mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-17 13:07:54 +02:00
work towards bringing mininode.py up to date with the main node and towards re-enabling rpc tests
This commit is contained in:
parent
1e1a2e580e
commit
3c21411c67
5 changed files with 205 additions and 129 deletions
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import *
|
||||
from test_framework.mininode import CTransaction, setCTxOutValue, CTxOutValue, COIN
|
||||
from test_framework.mininode import CTransaction, COIN
|
||||
from io import BytesIO
|
||||
import binascii
|
||||
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ class CompactBlocksTest(BitcoinTestFramework):
|
|||
height = node.getblockcount()
|
||||
tip = node.getbestblockhash()
|
||||
mtp = node.getblockheader(tip)['mediantime']
|
||||
block = create_block(int(tip, 16), create_coinbase(height + 1), mtp + 1)
|
||||
block = create_block(int(tip, 16), create_coinbase(height + 1), mtp + 1, height + 1)
|
||||
block.nVersion = 4
|
||||
if segwit:
|
||||
add_witness_commitment(block)
|
||||
|
|
@ -146,12 +146,12 @@ class CompactBlocksTest(BitcoinTestFramework):
|
|||
assert(int(self.nodes[0].getbestblockhash(), 16) == block.sha256)
|
||||
self.nodes[0].generate(100)
|
||||
|
||||
total_value = block.vtx[0].vout[0].nValue
|
||||
out_value = total_value // 10
|
||||
total_value = block.vtx[0].vout[0].nValue.getAmount()
|
||||
out_value = total_value
|
||||
tx = CTransaction()
|
||||
tx.vin.append(CTxIn(COutPoint(block.vtx[0].sha256, 0), b''))
|
||||
for i in range(10):
|
||||
tx.vout.append(CTxOut(out_value, CScript([OP_TRUE])))
|
||||
tx.vout.append(CTxOut(CTxOutValue(out_value), CScript([OP_TRUE])))
|
||||
tx.rehash()
|
||||
|
||||
block2 = self.build_block_on_tip(self.nodes[0])
|
||||
|
|
@ -458,7 +458,7 @@ class CompactBlocksTest(BitcoinTestFramework):
|
|||
for i in range(num_transactions):
|
||||
tx = CTransaction()
|
||||
tx.vin.append(CTxIn(COutPoint(utxo[0], utxo[1]), b''))
|
||||
tx.vout.append(CTxOut(utxo[2] - 1000, CScript([OP_TRUE])))
|
||||
tx.vout.append(CTxOut(CTxOutValue(utxo[2].getAmount() - 1000), CScript([OP_TRUE])))
|
||||
tx.rehash()
|
||||
utxo = [tx.sha256, 0, tx.vout[0].nValue]
|
||||
block.vtx.append(tx)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ from .mininode import *
|
|||
from .script import CScript, OP_TRUE, OP_CHECKSIG, OP_RETURN
|
||||
|
||||
# Create a block (with regtest difficulty)
|
||||
def create_block(hashprev, coinbase, nTime=None):
|
||||
def create_block(hashprev, coinbase, nTime=None, height=0):
|
||||
block = CBlock()
|
||||
if nTime is None:
|
||||
import time
|
||||
|
|
@ -16,9 +16,11 @@ def create_block(hashprev, coinbase, nTime=None):
|
|||
else:
|
||||
block.nTime = nTime
|
||||
block.hashPrevBlock = hashprev
|
||||
block.nBits = 0x207fffff # Will break after a difficulty adjustment...
|
||||
block.vtx.append(coinbase)
|
||||
block.hashMerkleRoot = block.calc_merkle_root()
|
||||
block.nHeight = height
|
||||
block.proof.challenge = CScript([OP_TRUE])
|
||||
block.proof.solution = b''
|
||||
block.calc_sha256()
|
||||
return block
|
||||
|
||||
|
|
@ -39,39 +41,28 @@ def add_witness_commitment(block, nonce=0):
|
|||
|
||||
# witness commitment is the last OP_RETURN output in coinbase
|
||||
output_data = WITNESS_COMMITMENT_HEADER + ser_uint256(witness_commitment)
|
||||
block.vtx[0].vout.append(CTxOut(0, CScript([OP_RETURN, output_data])))
|
||||
block.vtx[0].vout.append(CTxOut(CTxOutValue(0), CScript([OP_RETURN, output_data])))
|
||||
block.vtx[0].rehash()
|
||||
block.hashMerkleRoot = block.calc_merkle_root()
|
||||
block.rehash()
|
||||
|
||||
|
||||
def serialize_script_num(value):
|
||||
r = bytearray(0)
|
||||
if value == 0:
|
||||
return r
|
||||
neg = value < 0
|
||||
absvalue = -value if neg else value
|
||||
while (absvalue):
|
||||
r.append(int(absvalue & 0xff))
|
||||
absvalue >>= 8
|
||||
if r[-1] & 0x80:
|
||||
r.append(0x80 if neg else 0)
|
||||
elif neg:
|
||||
r[-1] |= 0x80
|
||||
return r
|
||||
|
||||
# Create a coinbase transaction, assuming no miner fees.
|
||||
# If pubkey is passed in, the coinbase output will be a P2PK output;
|
||||
# otherwise an anyone-can-spend output.
|
||||
def create_coinbase(height, pubkey = None):
|
||||
def create_coinbase(height, pubkey = None, amount = 0):
|
||||
coinbase = CTransaction()
|
||||
coinbase.vin.append(CTxIn(COutPoint(0, 0xffffffff),
|
||||
ser_string(serialize_script_num(height)), 0xffffffff))
|
||||
# coinbase transaction scriptsigs must be at least 2 bytes
|
||||
coinbase.vin.append(CTxIn(COutPoint(0, 0xffffffff),
|
||||
CScript([height, OP_TRUE]), 0xffffffff))
|
||||
coinbaseoutput = CTxOut()
|
||||
coinbaseoutput.nValue = 50 * COIN
|
||||
halvings = int(height/150) # regtest
|
||||
coinbaseoutput.nValue >>= halvings
|
||||
if (pubkey != None):
|
||||
|
||||
coinbaseoutput.nValue.setToAmount(amount)
|
||||
coinbaseoutput.nAsset.setToAsset(b'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
|
||||
|
||||
if amount == 0:
|
||||
# zero utxo's must be made unspendable
|
||||
coinbaseoutput.scriptPubKey = CScript([OP_RETURN])
|
||||
elif pubkey != None:
|
||||
coinbaseoutput.scriptPubKey = CScript([pubkey, OP_CHECKSIG])
|
||||
else:
|
||||
coinbaseoutput.scriptPubKey = CScript([OP_TRUE])
|
||||
|
|
@ -85,7 +76,7 @@ def create_transaction(prevtx, n, sig, value, scriptPubKey=CScript()):
|
|||
tx = CTransaction()
|
||||
assert(n < len(prevtx.vout))
|
||||
tx.vin.append(CTxIn(COutPoint(prevtx.sha256, n), sig, 0xffffffff))
|
||||
tx.vout.append(CTxOut(value, scriptPubKey))
|
||||
tx.vout.append(CTxOut(CTxOutValue(value), scriptPubKey))
|
||||
tx.calc_sha256()
|
||||
return tx
|
||||
|
||||
|
|
|
|||
|
|
@ -359,57 +359,119 @@ class CTxIn(object):
|
|||
% (repr(self.prevout), bytes_to_hex_str(self.scriptSig),
|
||||
self.nSequence)
|
||||
|
||||
def setCTxOutValue(amount):
|
||||
vchCommitment = [0]*33
|
||||
for i in range(8): #8 bytes
|
||||
vchCommitment[33-1-i] = ((amount >> (i*8)) & 0xff)
|
||||
return ''.join(map(chr, vchCommitment))
|
||||
|
||||
#Serialization only does value commitment
|
||||
class CTxOutValue(object):
|
||||
def __init__(self, vchCommitment=[], vchRangeProof="", vchNonceCommitment=""):
|
||||
class CTxOutAsset(object):
|
||||
def __init__(self, vchCommitment=b"\x00"):
|
||||
self.vchCommitment = vchCommitment
|
||||
self.vchRangeProof = vchRangeProof
|
||||
self.vchNonceCommitment = vchNonceCommitment
|
||||
|
||||
def deserialize(self, f):
|
||||
self.vchCommitment = f.read(33)
|
||||
#self.vchRangeProof = deser_string(f)
|
||||
#self.vchNonceCommitment = deser_string(f)
|
||||
version = ord(f.read(1))
|
||||
if version == 0: self.vchCommitment = b'\x00'
|
||||
elif version == 1: self.vchCommitment = b'\x01' + f.read(32)
|
||||
elif version == 0xff: self.vchCommitment = b'\xff' + f.read(32)
|
||||
elif version == 10 or version == 11: self.vchCommitment = bytes([version]) + f.read(32)
|
||||
else: raise 'invalid CTxOutAsset in deserialize'
|
||||
|
||||
def serialize(self):
|
||||
r = b""
|
||||
r += self.vchCommitment
|
||||
return r
|
||||
|
||||
def setToAsset(self, val):
|
||||
if len(val) != 32:
|
||||
raise 'invalid asset hash (expected 32 bytes got %d)' % len(val)
|
||||
self.vchCommitment = b'\x01' + val
|
||||
|
||||
def __repr__(self):
|
||||
return "CTxOutAsset(vchCommitment=%s)" % self.vchCommitment
|
||||
|
||||
class CTxOutValue(object):
|
||||
|
||||
def __init__(self, value=None):
|
||||
self.setNull()
|
||||
if value != None: self.setToAmount(value)
|
||||
|
||||
def setNull(self):
|
||||
self.vchCommitment = b'\x00'
|
||||
|
||||
def deserialize(self, f):
|
||||
version = ord(f.read(1))
|
||||
if version == 0: self.vchCommitment = b'\x00'
|
||||
elif version == 1: self.vchCommitment = b'\x01' + f.read(8)
|
||||
elif version == 0xff: self.vchCommitment = b'\xff' + f.read(8)
|
||||
elif version == 8 or version == 9: self.vchCommitment = bytes([version]) + f.read(32)
|
||||
else: raise Exception('invalid CTxOutValue in deserialize. version %d' % version)
|
||||
|
||||
def serialize(self):
|
||||
r = b""
|
||||
if len(self.vchCommitment) < 1: raise ValueError('invalid commitment')
|
||||
r += self.vchCommitment
|
||||
return r
|
||||
|
||||
def setToAmount(self, amount):
|
||||
commit = [1]*9
|
||||
for i in range(8): #8 bytes
|
||||
commit[8-i] = ((amount >> (i*8)) & 0xff)
|
||||
self.vchCommitment = bytes(commit)
|
||||
|
||||
def getAmount(self):
|
||||
if self.vchCommitment[0] != 1:
|
||||
raise ValueError('getAmount() called on non-explicit CTxOutValue')
|
||||
ret = 0
|
||||
for i in range(8): #8 bytes
|
||||
ret <<= 8
|
||||
ret |= self.vchCommitment[i+1]
|
||||
return ret
|
||||
|
||||
def __repr__(self):
|
||||
return "CTxOutValue(vchCommitment=%s)" % self.vchCommitment
|
||||
|
||||
class CTxOutNonce(object):
|
||||
def __init__(self, vchCommitment=b"\x00"):
|
||||
self.vchCommitment = vchCommitment
|
||||
|
||||
def deserialize(self, f):
|
||||
version = ord(f.read(1))
|
||||
if version == 0: self.vchCommitment = b'\x00'
|
||||
elif version == 1: self.vchCommitment = b'\x01' + f.read(32)
|
||||
elif version == 0xff: self.vchCommitment = b'\xff' + f.read(32)
|
||||
elif version == 2 or version == 3: self.vchCommitment = bytes([version]) + f.read(32)
|
||||
else: raise ValueError('invalid CTxOutNonce in deserialize')
|
||||
|
||||
def serialize(self):
|
||||
r = b""
|
||||
r += self.vchCommitment
|
||||
#r += ''.join(map(chr, self.vchCommitment))
|
||||
#r += ser_string(self.vchRangeProof)
|
||||
#r += ser_string(self.vchNonceCommitment)
|
||||
return r
|
||||
|
||||
def __repr__(self):
|
||||
return "CTxOutValue(vchCommitment=%s vchRangeProof=%s, vchnonceCommitment=%s)" \
|
||||
% ("COMMITMENT", "RANGE", "NONCE")#(self.vchCommitment, self.vchRangeProof,
|
||||
#self.vchNonceCommitment)
|
||||
return "CTxOutNonce(vchCommitment=%s)" % self.vchCommitment
|
||||
|
||||
class CTxOut(object):
|
||||
def __init__(self, nValue=CTxOutValue(), scriptPubKey=""):
|
||||
def __init__(self, nValue=CTxOutValue(), scriptPubKey=b'', nAsset=CTxOutAsset(), nNonce=CTxOutNonce()):
|
||||
self.nAsset = nAsset
|
||||
self.nValue = nValue
|
||||
self.nNonce = nNonce
|
||||
self.scriptPubKey = scriptPubKey
|
||||
|
||||
def deserialize(self, f):
|
||||
self.nAsset = CTxOutAsset()
|
||||
self.nAsset.deserialize(f)
|
||||
self.nValue = CTxOutValue()
|
||||
self.nValue.deserialize(f)
|
||||
self.nNonce = CTxOutNonce()
|
||||
self.nNonce.deserialize(f)
|
||||
self.scriptPubKey = deser_string(f)
|
||||
|
||||
def serialize(self):
|
||||
r = b""
|
||||
r += self.nAsset.serialize()
|
||||
r += self.nValue.serialize()
|
||||
r += self.nNonce.serialize()
|
||||
r += ser_string(self.scriptPubKey)
|
||||
return r
|
||||
|
||||
def __repr__(self):
|
||||
return "CTxOut(nValue=%s scriptPubKey=%s)" \
|
||||
% (self.nValue // COIN, self.nValue % COIN,
|
||||
bytes_to_hex_str(self.scriptPubKey))
|
||||
return "CTxOut(nAsset=%s nValue=%s nNonce=%s scriptPubKey=%s)" \
|
||||
% (self.nAsset, self.nValue, self.nNonce, bytes_to_hex_str(self.scriptPubKey))
|
||||
|
||||
|
||||
class CScriptWitness(object):
|
||||
|
|
@ -429,28 +491,63 @@ class CScriptWitness(object):
|
|||
|
||||
class CTxInWitness(object):
|
||||
def __init__(self):
|
||||
self.vchIssuanceAmountRangeproof = b'';
|
||||
self.vchInflationKeysRangeproof = b'';
|
||||
self.scriptWitness = CScriptWitness()
|
||||
|
||||
def deserialize(self, f):
|
||||
self.vchIssuanceAmountRangeproof = deser_string(f)
|
||||
self.vchInflationKeysRangeproof = deser_string(f)
|
||||
self.scriptWitness.stack = deser_string_vector(f)
|
||||
|
||||
def serialize(self):
|
||||
return ser_string_vector(self.scriptWitness.stack)
|
||||
r = b''
|
||||
r += ser_string(self.vchIssuanceAmountRangeproof)
|
||||
r += ser_string(self.vchInflationKeysRangeproof)
|
||||
r += ser_string_vector(self.scriptWitness.stack)
|
||||
return r
|
||||
|
||||
def __repr__(self):
|
||||
return repr(self.scriptWitness)
|
||||
return "CTxInWitness (%s, %s, %s)" % (self.vchIssuanceAmountRangeproof,
|
||||
self.vchInflationKeysRangeproof, self.scriptWitness)
|
||||
|
||||
def is_null(self):
|
||||
return self.scriptWitness.is_null()
|
||||
return len(self.vchIssuanceAmountRangeproof) == 0 \
|
||||
and len(self.vchInflationKeysRangeproof) == 0 \
|
||||
and self.scriptWitness.is_null()
|
||||
|
||||
class CTxOutWitness(object):
|
||||
def __init__(self):
|
||||
self.vchSurjectionproof = b'';
|
||||
self.vchRangeproof = b'';
|
||||
|
||||
def deserialize(self, f):
|
||||
self.vchSurjectionproof = deser_string(f)
|
||||
self.vchRangeproof = deser_string(f)
|
||||
|
||||
def serialize(self):
|
||||
r = b''
|
||||
r += ser_string(self.vchSurjectionproof)
|
||||
r += ser_string(self.vchRangeproof)
|
||||
return r
|
||||
|
||||
def __repr__(self):
|
||||
return "CTxOutWitness (%s, %s)" % (self.vchSurjectionproof, self.vchRangeproof)
|
||||
|
||||
def is_null(self):
|
||||
return len(self.vchSurjectionproof) == 0 \
|
||||
and len(self.vchRangeproof) == 0
|
||||
|
||||
class CTxWitness(object):
|
||||
def __init__(self):
|
||||
self.vtxinwit = []
|
||||
self.vtxoutwit = []
|
||||
|
||||
def deserialize(self, f):
|
||||
for i in range(len(self.vtxinwit)):
|
||||
self.vtxinwit[i].deserialize(f)
|
||||
for i in range(len(self.vtxoutwit)):
|
||||
self.vtxoutwit[i].deserialize(f)
|
||||
|
||||
def serialize(self):
|
||||
r = b""
|
||||
|
|
@ -462,13 +559,17 @@ class CTxWitness(object):
|
|||
return r
|
||||
|
||||
def __repr__(self):
|
||||
return "CTxWitness(%s)" % \
|
||||
(';'.join([repr(x) for x in self.vtxinwit]))
|
||||
return "CTxWitness([%s], [%s])" % \
|
||||
(';'.join([repr(x) for x in self.vtxinwit]),
|
||||
';'.join([repr(x) for x in self.vtxoutwit]))
|
||||
|
||||
def is_null(self):
|
||||
for x in self.vtxinwit:
|
||||
if not x.is_null():
|
||||
return False
|
||||
for x in self.vtxoutwit:
|
||||
if not x.is_null():
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
|
|
@ -492,14 +593,6 @@ class CTransaction(object):
|
|||
self.wit = copy.deepcopy(tx.wit)
|
||||
|
||||
def deserialize(self, f):
|
||||
self.nVersion = struct.unpack("<i", f.read(4))[0]
|
||||
self.vin = deser_vector(f, CTxIn)
|
||||
self.vout = deser_vector(f, CTxOut)
|
||||
self.nLockTime = struct.unpack("<I", f.read(4))[0]
|
||||
self.sha256 = None
|
||||
self.hash = None
|
||||
|
||||
def deserialize_with_witness(self, f):
|
||||
self.nVersion = struct.unpack("<i", f.read(4))[0]
|
||||
self.vin = deser_vector(f, CTxIn)
|
||||
flags = 0
|
||||
|
|
@ -514,13 +607,10 @@ class CTransaction(object):
|
|||
self.vout = deser_vector(f, CTxOut)
|
||||
if flags & 1 > 0:
|
||||
self.wit.vtxinwit = [CTxInWitness() for i in range(len(self.vin))]
|
||||
self.wit.vtxoutwit = [CTxOutWitness() for i in range(len(self.vout))]
|
||||
self.wit.deserialize(f)
|
||||
|
||||
if flags & 2 > 0:
|
||||
for i in range(len(self.vout)):
|
||||
self.vout[i].nValue.vchRangeProof = deser_string(f)
|
||||
self.vout[i].nValue.vchNonceCommitment = deser_string(f)
|
||||
if flags > 3:
|
||||
if flags > 1:
|
||||
raise TypeError('Extra witness flags:' + str(flags))
|
||||
self.nLockTime = struct.unpack("<I", f.read(4))[0]
|
||||
self.sha256 = None
|
||||
|
|
@ -554,42 +644,13 @@ class CTransaction(object):
|
|||
self.wit.vtxinwit = self.wit.vtxinwit[:len(self.vin)]
|
||||
for i in range(len(self.wit.vtxinwit), len(self.vin)):
|
||||
self.wit.vtxinwit.append(CTxInWitness())
|
||||
self.wit.vtxoutwit = self.wit.vtxoutwit[:len(self.vout)]
|
||||
for i in range(len(self.wit.vtxoutwit), len(self.vout)):
|
||||
self.wit.vtxoutwit.append(CTxInWitness())
|
||||
r += self.wit.serialize()
|
||||
r += struct.pack("<I", self.nLockTime)
|
||||
return r
|
||||
|
||||
# Only serialize with witness when explicitly called for
|
||||
def serialize_with_witness(self):
|
||||
flags = 0
|
||||
if not self.wit.is_null():
|
||||
flags |= 1
|
||||
for i in range(len(self.vout)):
|
||||
if self.vout[i].nValue.vchRangeProof != None or self.vout[i].nValue.vchNonceCommitment != None:
|
||||
flags |= 2
|
||||
r = b""
|
||||
r += struct.pack("<i", self.nVersion)
|
||||
if flags:
|
||||
dummy = []
|
||||
r += ser_vector(dummy)
|
||||
r += struct.pack("<B", flags)
|
||||
r += ser_vector(self.vin)
|
||||
r += ser_vector(self.vout)
|
||||
if flags & 1:
|
||||
if (len(self.wit.vtxinwit) != len(self.vin)):
|
||||
# vtxinwit must have the same length as vin
|
||||
self.wit.vtxinwit = self.wit.vtxinwit[:len(self.vin)]
|
||||
for i in range(len(self.wit.vtxinwit), len(self.vin)):
|
||||
self.wit.vtxinwit.append(CTxInWitness())
|
||||
r += self.wit.serialize()
|
||||
if flags & 2 > 0:
|
||||
for i in range(len(self.vout)):
|
||||
r += ser_string(self.vout[i].nValue.vchRangeProof)
|
||||
r += ser_string(self.vout[i].nValue.vchNonceCommitment)
|
||||
r += struct.pack("<I", self.nLockTime)
|
||||
return r
|
||||
|
||||
# Regular serialization is without witness -- must explicitly
|
||||
# call serialize_with_witness to include witness data.
|
||||
def serialize(self):
|
||||
return self.serialize_with_witness()
|
||||
|
||||
|
|
@ -620,6 +681,34 @@ class CTransaction(object):
|
|||
% (self.nVersion, repr(self.vin), repr(self.vout), repr(self.wit), self.nLockTime)
|
||||
|
||||
|
||||
class CProof(object):
|
||||
def __init__(self, challenge=b"", solution=b""):
|
||||
self.challenge = challenge
|
||||
self.solution = solution
|
||||
|
||||
def set_null(self):
|
||||
self.challenge = b""
|
||||
self.solution = b""
|
||||
|
||||
def deserialize(self, f):
|
||||
self.challenge = deser_string(f)
|
||||
self.solution = deser_string(f)
|
||||
|
||||
def serialize(self):
|
||||
r = b""
|
||||
r += ser_string(self.challenge)
|
||||
r += ser_string(self.solution)
|
||||
return r
|
||||
|
||||
def serialize_for_hash(self):
|
||||
r = b""
|
||||
r += ser_string(self.challenge)
|
||||
return r
|
||||
|
||||
def __repr__(self):
|
||||
return "CProof(challenge=%s solution=%s)" \
|
||||
% (self.challenge, self.solution)
|
||||
|
||||
class CBlockHeader(object):
|
||||
def __init__(self, header=None):
|
||||
if header is None:
|
||||
|
|
@ -630,8 +719,7 @@ class CBlockHeader(object):
|
|||
self.hashMerkleRoot = header.hashMerkleRoot
|
||||
self.nTime = header.nTime
|
||||
self.nHeight = header.nHeight
|
||||
self.nBits = header.nBits
|
||||
self.nNonce = header.nNonce
|
||||
self.proof = header.proof
|
||||
self.sha256 = header.sha256
|
||||
self.hash = header.hash
|
||||
self.calc_sha256()
|
||||
|
|
@ -642,8 +730,7 @@ class CBlockHeader(object):
|
|||
self.hashMerkleRoot = 0
|
||||
self.nTime = 0
|
||||
self.nHeight = 0
|
||||
self.nBits = 0
|
||||
self.nNonce = 0
|
||||
self.proof = CProof()
|
||||
self.sha256 = None
|
||||
self.hash = None
|
||||
|
||||
|
|
@ -653,8 +740,7 @@ class CBlockHeader(object):
|
|||
self.hashMerkleRoot = deser_uint256(f)
|
||||
self.nTime = struct.unpack("<I", f.read(4))[0]
|
||||
self.nHeight = struct.unpack("<I", f.read(4))[0]
|
||||
self.nBits = struct.unpack("<I", f.read(4))[0]
|
||||
self.nNonce = struct.unpack("<I", f.read(4))[0]
|
||||
self.proof.deserialize(f)
|
||||
self.sha256 = None
|
||||
self.hash = None
|
||||
|
||||
|
|
@ -665,8 +751,7 @@ class CBlockHeader(object):
|
|||
r += ser_uint256(self.hashMerkleRoot)
|
||||
r += struct.pack("<I", self.nTime)
|
||||
r += struct.pack("<I", self.nHeight)
|
||||
r += struct.pack("<I", self.nBits)
|
||||
r += struct.pack("<I", self.nNonce)
|
||||
r += self.proof.serialize()
|
||||
return r
|
||||
|
||||
def calc_sha256(self):
|
||||
|
|
@ -677,8 +762,7 @@ class CBlockHeader(object):
|
|||
r += ser_uint256(self.hashMerkleRoot)
|
||||
r += struct.pack("<I", self.nTime)
|
||||
r += struct.pack("<I", self.nHeight)
|
||||
r += struct.pack("<I", self.nBits)
|
||||
r += struct.pack("<I", self.nNonce)
|
||||
r += self.proof.serialize_for_hash()
|
||||
self.sha256 = uint256_from_str(hash256(r))
|
||||
self.hash = encode(hash256(r)[::-1], 'hex_codec').decode('ascii')
|
||||
|
||||
|
|
@ -688,9 +772,9 @@ class CBlockHeader(object):
|
|||
return self.sha256
|
||||
|
||||
def __repr__(self):
|
||||
return "CBlockHeader(nVersion=%i hashPrevBlock=%064x hashMerkleRoot=%064x nTime=%s nBits=%08x nNonce=%08x nHeight=%s)" \
|
||||
return "CBlockHeader(nVersion=%i hashPrevBlock=%064x hashMerkleRoot=%064x nTime=%s nHeight=%d)" \
|
||||
% (self.nVersion, self.hashPrevBlock, self.hashMerkleRoot,
|
||||
time.ctime(self.nTime), self.nBits, self.nNonce, self.nHeight)
|
||||
time.ctime(self.nTime), self.nHeight)
|
||||
|
||||
|
||||
class CBlock(CBlockHeader):
|
||||
|
|
@ -741,9 +825,10 @@ class CBlock(CBlockHeader):
|
|||
|
||||
def is_valid(self):
|
||||
self.calc_sha256()
|
||||
target = uint256_from_compact(self.nBits)
|
||||
if self.sha256 > target:
|
||||
return False
|
||||
# TODO: check signatures
|
||||
# target = uint256_from_compact(self.nBits)
|
||||
# if self.sha256 > target:
|
||||
# return False
|
||||
for tx in self.vtx:
|
||||
if not tx.is_valid():
|
||||
return False
|
||||
|
|
@ -753,15 +838,15 @@ class CBlock(CBlockHeader):
|
|||
|
||||
def solve(self):
|
||||
self.rehash()
|
||||
target = uint256_from_compact(self.nBits)
|
||||
while self.sha256 > target:
|
||||
self.nNonce += 1
|
||||
self.rehash()
|
||||
# target = uint256_from_compact(self.nBits)
|
||||
# while self.sha256 > target:
|
||||
# self.nNonce += 1
|
||||
# self.rehash()
|
||||
|
||||
def __repr__(self):
|
||||
return "CBlock(nVersion=%i hashPrevBlock=%064x hashMerkleRoot=%064x nTime=%s nBits=%08x nNonce=%08x vtx=%s)" \
|
||||
return "CBlock(nVersion=%i hashPrevBlock=%064x hashMerkleRoot=%064x nTime=%s vtx=%s)" \
|
||||
% (self.nVersion, self.hashPrevBlock, self.hashMerkleRoot,
|
||||
time.ctime(self.nTime), self.nBits, self.nNonce, repr(self.vtx))
|
||||
time.ctime(self.nTime), repr(self.vtx))
|
||||
|
||||
|
||||
class CUnsignedAlert(object):
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ public:
|
|||
};
|
||||
|
||||
/**
|
||||
* An 33-byte data field that typically is used to convey to the
|
||||
* A 33-byte data field that typically is used to convey to the
|
||||
* recipient the ECDH ephemeral key (an EC point) for deriving the
|
||||
* transaction output blinding factor. */
|
||||
class CConfidentialNonce : public CConfidentialCommitment<33, 2, 3>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue