Changeset View
Changeset View
Standalone View
Standalone View
test/functional/test_framework/mininode.py
Show First 20 Lines • Show All 233 Lines • ▼ Show 20 Lines | |||||
def ToHex(obj): | def ToHex(obj): | ||||
return bytes_to_hex_str(obj.serialize()) | return bytes_to_hex_str(obj.serialize()) | ||||
# Objects that map to bitcoind objects, which can be serialized/deserialized | # Objects that map to bitcoind objects, which can be serialized/deserialized | ||||
class CAddress(object): | class CAddress(): | ||||
def __init__(self): | def __init__(self): | ||||
self.nServices = 1 | self.nServices = 1 | ||||
self.pchReserved = b"\x00" * 10 + b"\xff" * 2 | self.pchReserved = b"\x00" * 10 + b"\xff" * 2 | ||||
self.ip = "0.0.0.0" | self.ip = "0.0.0.0" | ||||
self.port = 0 | self.port = 0 | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
self.nServices = struct.unpack("<Q", f.read(8))[0] | self.nServices = struct.unpack("<Q", f.read(8))[0] | ||||
Show All 12 Lines | class CAddress(): | ||||
def __repr__(self): | def __repr__(self): | ||||
return "CAddress(nServices=%i ip=%s port=%i)" % (self.nServices, | return "CAddress(nServices=%i ip=%s port=%i)" % (self.nServices, | ||||
self.ip, self.port) | self.ip, self.port) | ||||
MSG_WITNESS_FLAG = 1 << 30 | MSG_WITNESS_FLAG = 1 << 30 | ||||
class CInv(object): | class CInv(): | ||||
typemap = { | typemap = { | ||||
0: "Error", | 0: "Error", | ||||
1: "TX", | 1: "TX", | ||||
2: "Block", | 2: "Block", | ||||
1 | MSG_WITNESS_FLAG: "WitnessTx", | 1 | MSG_WITNESS_FLAG: "WitnessTx", | ||||
2 | MSG_WITNESS_FLAG: "WitnessBlock", | 2 | MSG_WITNESS_FLAG: "WitnessBlock", | ||||
4: "CompactBlock" | 4: "CompactBlock" | ||||
} | } | ||||
Show All 12 Lines | def serialize(self): | ||||
r += ser_uint256(self.hash) | r += ser_uint256(self.hash) | ||||
return r | return r | ||||
def __repr__(self): | def __repr__(self): | ||||
return "CInv(type=%s hash=%064x)" \ | return "CInv(type=%s hash=%064x)" \ | ||||
% (self.typemap[self.type], self.hash) | % (self.typemap[self.type], self.hash) | ||||
class CBlockLocator(object): | class CBlockLocator(): | ||||
def __init__(self): | def __init__(self): | ||||
self.nVersion = MY_VERSION | self.nVersion = MY_VERSION | ||||
self.vHave = [] | self.vHave = [] | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
self.nVersion = struct.unpack("<i", f.read(4))[0] | self.nVersion = struct.unpack("<i", f.read(4))[0] | ||||
self.vHave = deser_uint256_vector(f) | self.vHave = deser_uint256_vector(f) | ||||
def serialize(self): | def serialize(self): | ||||
r = b"" | r = b"" | ||||
r += struct.pack("<i", self.nVersion) | r += struct.pack("<i", self.nVersion) | ||||
r += ser_uint256_vector(self.vHave) | r += ser_uint256_vector(self.vHave) | ||||
return r | return r | ||||
def __repr__(self): | def __repr__(self): | ||||
return "CBlockLocator(nVersion=%i vHave=%s)" \ | return "CBlockLocator(nVersion=%i vHave=%s)" \ | ||||
% (self.nVersion, repr(self.vHave)) | % (self.nVersion, repr(self.vHave)) | ||||
class COutPoint(object): | class COutPoint(): | ||||
def __init__(self, hash=0, n=0): | def __init__(self, hash=0, n=0): | ||||
self.hash = hash | self.hash = hash | ||||
self.n = n | self.n = n | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
self.hash = deser_uint256(f) | self.hash = deser_uint256(f) | ||||
self.n = struct.unpack("<I", f.read(4))[0] | self.n = struct.unpack("<I", f.read(4))[0] | ||||
def serialize(self): | def serialize(self): | ||||
r = b"" | r = b"" | ||||
r += ser_uint256(self.hash) | r += ser_uint256(self.hash) | ||||
r += struct.pack("<I", self.n) | r += struct.pack("<I", self.n) | ||||
return r | return r | ||||
def __repr__(self): | def __repr__(self): | ||||
return "COutPoint(hash=%064x n=%i)" % (self.hash, self.n) | return "COutPoint(hash=%064x n=%i)" % (self.hash, self.n) | ||||
class CTxIn(object): | class CTxIn(): | ||||
def __init__(self, outpoint=None, scriptSig=b"", nSequence=0): | def __init__(self, outpoint=None, scriptSig=b"", nSequence=0): | ||||
if outpoint is None: | if outpoint is None: | ||||
self.prevout = COutPoint() | self.prevout = COutPoint() | ||||
else: | else: | ||||
self.prevout = outpoint | self.prevout = outpoint | ||||
self.scriptSig = scriptSig | self.scriptSig = scriptSig | ||||
self.nSequence = nSequence | self.nSequence = nSequence | ||||
Show All 11 Lines | def serialize(self): | ||||
return r | return r | ||||
def __repr__(self): | def __repr__(self): | ||||
return "CTxIn(prevout=%s scriptSig=%s nSequence=%i)" \ | return "CTxIn(prevout=%s scriptSig=%s nSequence=%i)" \ | ||||
% (repr(self.prevout), bytes_to_hex_str(self.scriptSig), | % (repr(self.prevout), bytes_to_hex_str(self.scriptSig), | ||||
self.nSequence) | self.nSequence) | ||||
class CTxOut(object): | class CTxOut(): | ||||
def __init__(self, nValue=0, scriptPubKey=b""): | def __init__(self, nValue=0, scriptPubKey=b""): | ||||
self.nValue = nValue | self.nValue = nValue | ||||
self.scriptPubKey = scriptPubKey | self.scriptPubKey = scriptPubKey | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
self.nValue = struct.unpack("<q", f.read(8))[0] | self.nValue = struct.unpack("<q", f.read(8))[0] | ||||
self.scriptPubKey = deser_string(f) | self.scriptPubKey = deser_string(f) | ||||
def serialize(self): | def serialize(self): | ||||
r = b"" | r = b"" | ||||
r += struct.pack("<q", self.nValue) | r += struct.pack("<q", self.nValue) | ||||
r += ser_string(self.scriptPubKey) | r += ser_string(self.scriptPubKey) | ||||
return r | return r | ||||
def __repr__(self): | def __repr__(self): | ||||
return "CTxOut(nValue=%i.%08i scriptPubKey=%s)" \ | return "CTxOut(nValue=%i.%08i scriptPubKey=%s)" \ | ||||
% (self.nValue // COIN, self.nValue % COIN, | % (self.nValue // COIN, self.nValue % COIN, | ||||
bytes_to_hex_str(self.scriptPubKey)) | bytes_to_hex_str(self.scriptPubKey)) | ||||
class CScriptWitness(object): | class CScriptWitness(): | ||||
def __init__(self): | def __init__(self): | ||||
# stack is a vector of strings | # stack is a vector of strings | ||||
self.stack = [] | self.stack = [] | ||||
def __repr__(self): | def __repr__(self): | ||||
return "CScriptWitness(%s)" % \ | return "CScriptWitness(%s)" % \ | ||||
(",".join([bytes_to_hex_str(x) for x in self.stack])) | (",".join([bytes_to_hex_str(x) for x in self.stack])) | ||||
def is_null(self): | def is_null(self): | ||||
if self.stack: | if self.stack: | ||||
return False | return False | ||||
return True | return True | ||||
class CTxInWitness(object): | class CTxInWitness(): | ||||
def __init__(self): | def __init__(self): | ||||
self.scriptWitness = CScriptWitness() | self.scriptWitness = CScriptWitness() | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
self.scriptWitness.stack = deser_string_vector(f) | self.scriptWitness.stack = deser_string_vector(f) | ||||
def serialize(self): | def serialize(self): | ||||
return ser_string_vector(self.scriptWitness.stack) | return ser_string_vector(self.scriptWitness.stack) | ||||
def __repr__(self): | def __repr__(self): | ||||
return repr(self.scriptWitness) | return repr(self.scriptWitness) | ||||
def is_null(self): | def is_null(self): | ||||
return self.scriptWitness.is_null() | return self.scriptWitness.is_null() | ||||
class CTxWitness(object): | class CTxWitness(): | ||||
def __init__(self): | def __init__(self): | ||||
self.vtxinwit = [] | self.vtxinwit = [] | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
for i in range(len(self.vtxinwit)): | for i in range(len(self.vtxinwit)): | ||||
self.vtxinwit[i].deserialize(f) | self.vtxinwit[i].deserialize(f) | ||||
def serialize(self): | def serialize(self): | ||||
Show All 11 Lines | class CTxWitness(): | ||||
def is_null(self): | def is_null(self): | ||||
for x in self.vtxinwit: | for x in self.vtxinwit: | ||||
if not x.is_null(): | if not x.is_null(): | ||||
return False | return False | ||||
return True | return True | ||||
class CTransaction(object): | class CTransaction(): | ||||
def __init__(self, tx=None): | def __init__(self, tx=None): | ||||
if tx is None: | if tx is None: | ||||
self.nVersion = 1 | self.nVersion = 1 | ||||
self.vin = [] | self.vin = [] | ||||
self.vout = [] | self.vout = [] | ||||
self.wit = CTxWitness() | self.wit = CTxWitness() | ||||
self.nLockTime = 0 | self.nLockTime = 0 | ||||
self.sha256 = None | self.sha256 = None | ||||
▲ Show 20 Lines • Show All 88 Lines • ▼ Show 20 Lines | def is_valid(self): | ||||
return False | return False | ||||
return True | return True | ||||
def __repr__(self): | def __repr__(self): | ||||
return "CTransaction(nVersion=%i vin=%s vout=%s wit=%s nLockTime=%i)" \ | return "CTransaction(nVersion=%i vin=%s vout=%s wit=%s nLockTime=%i)" \ | ||||
% (self.nVersion, repr(self.vin), repr(self.vout), repr(self.wit), self.nLockTime) | % (self.nVersion, repr(self.vin), repr(self.vout), repr(self.wit), self.nLockTime) | ||||
class CBlockHeader(object): | class CBlockHeader(): | ||||
def __init__(self, header=None): | def __init__(self, header=None): | ||||
if header is None: | if header is None: | ||||
self.set_null() | self.set_null() | ||||
else: | else: | ||||
self.nVersion = header.nVersion | self.nVersion = header.nVersion | ||||
self.hashPrevBlock = header.hashPrevBlock | self.hashPrevBlock = header.hashPrevBlock | ||||
self.hashMerkleRoot = header.hashMerkleRoot | self.hashMerkleRoot = header.hashMerkleRoot | ||||
self.nTime = header.nTime | self.nTime = header.nTime | ||||
▲ Show 20 Lines • Show All 123 Lines • ▼ Show 20 Lines | def solve(self): | ||||
self.rehash() | self.rehash() | ||||
def __repr__(self): | 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 nBits=%08x nNonce=%08x vtx=%s)" \ | ||||
% (self.nVersion, self.hashPrevBlock, self.hashMerkleRoot, | % (self.nVersion, self.hashPrevBlock, self.hashMerkleRoot, | ||||
time.ctime(self.nTime), self.nBits, self.nNonce, repr(self.vtx)) | time.ctime(self.nTime), self.nBits, self.nNonce, repr(self.vtx)) | ||||
class CUnsignedAlert(object): | class CUnsignedAlert(): | ||||
def __init__(self): | def __init__(self): | ||||
self.nVersion = 1 | self.nVersion = 1 | ||||
self.nRelayUntil = 0 | self.nRelayUntil = 0 | ||||
self.nExpiration = 0 | self.nExpiration = 0 | ||||
self.nID = 0 | self.nID = 0 | ||||
self.nCancel = 0 | self.nCancel = 0 | ||||
self.setCancel = [] | self.setCancel = [] | ||||
self.nMinVer = 0 | self.nMinVer = 0 | ||||
Show All 38 Lines | class CUnsignedAlert(): | ||||
def __repr__(self): | def __repr__(self): | ||||
return "CUnsignedAlert(nVersion %d, nRelayUntil %d, nExpiration %d, nID %d, nCancel %d, nMinVer %d, nMaxVer %d, nPriority %d, strComment %s, strStatusBar %s, strReserved %s)" \ | return "CUnsignedAlert(nVersion %d, nRelayUntil %d, nExpiration %d, nID %d, nCancel %d, nMinVer %d, nMaxVer %d, nPriority %d, strComment %s, strStatusBar %s, strReserved %s)" \ | ||||
% (self.nVersion, self.nRelayUntil, self.nExpiration, self.nID, | % (self.nVersion, self.nRelayUntil, self.nExpiration, self.nID, | ||||
self.nCancel, self.nMinVer, self.nMaxVer, self.nPriority, | self.nCancel, self.nMinVer, self.nMaxVer, self.nPriority, | ||||
self.strComment, self.strStatusBar, self.strReserved) | self.strComment, self.strStatusBar, self.strReserved) | ||||
class CAlert(object): | class CAlert(): | ||||
def __init__(self): | def __init__(self): | ||||
self.vchMsg = b"" | self.vchMsg = b"" | ||||
self.vchSig = b"" | self.vchSig = b"" | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
self.vchMsg = deser_string(f) | self.vchMsg = deser_string(f) | ||||
self.vchSig = deser_string(f) | self.vchSig = deser_string(f) | ||||
def serialize(self): | def serialize(self): | ||||
r = b"" | r = b"" | ||||
r += ser_string(self.vchMsg) | r += ser_string(self.vchMsg) | ||||
r += ser_string(self.vchSig) | r += ser_string(self.vchSig) | ||||
return r | return r | ||||
def __repr__(self): | def __repr__(self): | ||||
return "CAlert(vchMsg.sz %d, vchSig.sz %d)" \ | return "CAlert(vchMsg.sz %d, vchSig.sz %d)" \ | ||||
% (len(self.vchMsg), len(self.vchSig)) | % (len(self.vchMsg), len(self.vchSig)) | ||||
class PrefilledTransaction(object): | class PrefilledTransaction(): | ||||
def __init__(self, index=0, tx=None): | def __init__(self, index=0, tx=None): | ||||
self.index = index | self.index = index | ||||
self.tx = tx | self.tx = tx | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
self.index = deser_compact_size(f) | self.index = deser_compact_size(f) | ||||
self.tx = CTransaction() | self.tx = CTransaction() | ||||
self.tx.deserialize(f) | self.tx.deserialize(f) | ||||
Show All 11 Lines | def serialize_with_witness(self): | ||||
return self.serialize(with_witness=True) | return self.serialize(with_witness=True) | ||||
def __repr__(self): | def __repr__(self): | ||||
return "PrefilledTransaction(index=%d, tx=%s)" % (self.index, repr(self.tx)) | return "PrefilledTransaction(index=%d, tx=%s)" % (self.index, repr(self.tx)) | ||||
# This is what we send on the wire, in a cmpctblock message. | # This is what we send on the wire, in a cmpctblock message. | ||||
class P2PHeaderAndShortIDs(object): | class P2PHeaderAndShortIDs(): | ||||
def __init__(self): | def __init__(self): | ||||
self.header = CBlockHeader() | self.header = CBlockHeader() | ||||
self.nonce = 0 | self.nonce = 0 | ||||
self.shortids_length = 0 | self.shortids_length = 0 | ||||
self.shortids = [] | self.shortids = [] | ||||
self.prefilled_txn_length = 0 | self.prefilled_txn_length = 0 | ||||
self.prefilled_txn = [] | self.prefilled_txn = [] | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | def calculate_shortid(k0, k1, tx_hash): | ||||
expected_shortid = siphash256(k0, k1, tx_hash) | expected_shortid = siphash256(k0, k1, tx_hash) | ||||
expected_shortid &= 0x0000ffffffffffff | expected_shortid &= 0x0000ffffffffffff | ||||
return expected_shortid | return expected_shortid | ||||
# This version gets rid of the array lengths, and reinterprets the differential | # This version gets rid of the array lengths, and reinterprets the differential | ||||
# encoding into indices that can be used for lookup. | # encoding into indices that can be used for lookup. | ||||
class HeaderAndShortIDs(object): | class HeaderAndShortIDs(): | ||||
def __init__(self, p2pheaders_and_shortids=None): | def __init__(self, p2pheaders_and_shortids=None): | ||||
self.header = CBlockHeader() | self.header = CBlockHeader() | ||||
self.nonce = 0 | self.nonce = 0 | ||||
self.shortids = [] | self.shortids = [] | ||||
self.prefilled_txn = [] | self.prefilled_txn = [] | ||||
self.use_witness = False | self.use_witness = False | ||||
if p2pheaders_and_shortids != None: | if p2pheaders_and_shortids != None: | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | def initialize_from_block(self, block, nonce=0, prefill_list=[0], use_witness=False): | ||||
if use_witness: | if use_witness: | ||||
tx_hash = block.vtx[i].calc_sha256(with_witness=True) | tx_hash = block.vtx[i].calc_sha256(with_witness=True) | ||||
self.shortids.append(calculate_shortid(k0, k1, tx_hash)) | self.shortids.append(calculate_shortid(k0, k1, tx_hash)) | ||||
def __repr__(self): | def __repr__(self): | ||||
return "HeaderAndShortIDs(header=%s, nonce=%d, shortids=%s, prefilledtxn=%s" % (repr(self.header), self.nonce, repr(self.shortids), repr(self.prefilled_txn)) | return "HeaderAndShortIDs(header=%s, nonce=%d, shortids=%s, prefilledtxn=%s" % (repr(self.header), self.nonce, repr(self.shortids), repr(self.prefilled_txn)) | ||||
class BlockTransactionsRequest(object): | class BlockTransactionsRequest(): | ||||
def __init__(self, blockhash=0, indexes=None): | def __init__(self, blockhash=0, indexes=None): | ||||
self.blockhash = blockhash | self.blockhash = blockhash | ||||
self.indexes = indexes if indexes != None else [] | self.indexes = indexes if indexes != None else [] | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
self.blockhash = deser_uint256(f) | self.blockhash = deser_uint256(f) | ||||
indexes_length = deser_compact_size(f) | indexes_length = deser_compact_size(f) | ||||
Show All 23 Lines | def to_absolute(self): | ||||
absolute_indexes.append(x + last_index + 1) | absolute_indexes.append(x + last_index + 1) | ||||
last_index = absolute_indexes[-1] | last_index = absolute_indexes[-1] | ||||
return absolute_indexes | return absolute_indexes | ||||
def __repr__(self): | def __repr__(self): | ||||
return "BlockTransactionsRequest(hash=%064x indexes=%s)" % (self.blockhash, repr(self.indexes)) | return "BlockTransactionsRequest(hash=%064x indexes=%s)" % (self.blockhash, repr(self.indexes)) | ||||
class BlockTransactions(object): | class BlockTransactions(): | ||||
def __init__(self, blockhash=0, transactions=None): | def __init__(self, blockhash=0, transactions=None): | ||||
self.blockhash = blockhash | self.blockhash = blockhash | ||||
self.transactions = transactions if transactions != None else [] | self.transactions = transactions if transactions != None else [] | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
self.blockhash = deser_uint256(f) | self.blockhash = deser_uint256(f) | ||||
self.transactions = deser_vector(f, CTransaction) | self.transactions = deser_vector(f, CTransaction) | ||||
def serialize(self, with_witness=False): | def serialize(self, with_witness=False): | ||||
r = b"" | r = b"" | ||||
r += ser_uint256(self.blockhash) | r += ser_uint256(self.blockhash) | ||||
if with_witness: | if with_witness: | ||||
r += ser_vector(self.transactions, "serialize_with_witness") | r += ser_vector(self.transactions, "serialize_with_witness") | ||||
else: | else: | ||||
r += ser_vector(self.transactions) | r += ser_vector(self.transactions) | ||||
return r | return r | ||||
def __repr__(self): | def __repr__(self): | ||||
return "BlockTransactions(hash=%064x transactions=%s)" % (self.blockhash, repr(self.transactions)) | return "BlockTransactions(hash=%064x transactions=%s)" % (self.blockhash, repr(self.transactions)) | ||||
# Objects that correspond to messages on the wire | # Objects that correspond to messages on the wire | ||||
class msg_version(object): | class msg_version(): | ||||
command = b"version" | command = b"version" | ||||
def __init__(self): | def __init__(self): | ||||
self.nVersion = MY_VERSION | self.nVersion = MY_VERSION | ||||
self.nServices = 1 | self.nServices = 1 | ||||
self.nTime = int(time.time()) | self.nTime = int(time.time()) | ||||
self.addrTo = CAddress() | self.addrTo = CAddress() | ||||
self.addrFrom = CAddress() | self.addrFrom = CAddress() | ||||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | class msg_version(): | ||||
def __repr__(self): | def __repr__(self): | ||||
return 'msg_version(nVersion=%i nServices=%i nTime=%s addrTo=%s addrFrom=%s nNonce=0x%016X strSubVer=%s nStartingHeight=%i nRelay=%i)' \ | return 'msg_version(nVersion=%i nServices=%i nTime=%s addrTo=%s addrFrom=%s nNonce=0x%016X strSubVer=%s nStartingHeight=%i nRelay=%i)' \ | ||||
% (self.nVersion, self.nServices, time.ctime(self.nTime), | % (self.nVersion, self.nServices, time.ctime(self.nTime), | ||||
repr(self.addrTo), repr(self.addrFrom), self.nNonce, | repr(self.addrTo), repr(self.addrFrom), self.nNonce, | ||||
self.strSubVer, self.nStartingHeight, self.nRelay) | self.strSubVer, self.nStartingHeight, self.nRelay) | ||||
class msg_verack(object): | class msg_verack(): | ||||
command = b"verack" | command = b"verack" | ||||
def __init__(self): | def __init__(self): | ||||
pass | pass | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
pass | pass | ||||
def serialize(self): | def serialize(self): | ||||
return b"" | return b"" | ||||
def __repr__(self): | def __repr__(self): | ||||
return "msg_verack()" | return "msg_verack()" | ||||
class msg_addr(object): | class msg_addr(): | ||||
command = b"addr" | command = b"addr" | ||||
def __init__(self): | def __init__(self): | ||||
self.addrs = [] | self.addrs = [] | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
self.addrs = deser_vector(f, CAddress) | self.addrs = deser_vector(f, CAddress) | ||||
def serialize(self): | def serialize(self): | ||||
return ser_vector(self.addrs) | return ser_vector(self.addrs) | ||||
def __repr__(self): | def __repr__(self): | ||||
return "msg_addr(addrs=%s)" % (repr(self.addrs)) | return "msg_addr(addrs=%s)" % (repr(self.addrs)) | ||||
class msg_alert(object): | class msg_alert(): | ||||
command = b"alert" | command = b"alert" | ||||
def __init__(self): | def __init__(self): | ||||
self.alert = CAlert() | self.alert = CAlert() | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
self.alert = CAlert() | self.alert = CAlert() | ||||
self.alert.deserialize(f) | self.alert.deserialize(f) | ||||
def serialize(self): | def serialize(self): | ||||
r = b"" | r = b"" | ||||
r += self.alert.serialize() | r += self.alert.serialize() | ||||
return r | return r | ||||
def __repr__(self): | def __repr__(self): | ||||
return "msg_alert(alert=%s)" % (repr(self.alert), ) | return "msg_alert(alert=%s)" % (repr(self.alert), ) | ||||
class msg_inv(object): | class msg_inv(): | ||||
command = b"inv" | command = b"inv" | ||||
def __init__(self, inv=None): | def __init__(self, inv=None): | ||||
if inv is None: | if inv is None: | ||||
self.inv = [] | self.inv = [] | ||||
else: | else: | ||||
self.inv = inv | self.inv = inv | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
self.inv = deser_vector(f, CInv) | self.inv = deser_vector(f, CInv) | ||||
def serialize(self): | def serialize(self): | ||||
return ser_vector(self.inv) | return ser_vector(self.inv) | ||||
def __repr__(self): | def __repr__(self): | ||||
return "msg_inv(inv=%s)" % (repr(self.inv)) | return "msg_inv(inv=%s)" % (repr(self.inv)) | ||||
class msg_getdata(object): | class msg_getdata(): | ||||
command = b"getdata" | command = b"getdata" | ||||
def __init__(self, inv=None): | def __init__(self, inv=None): | ||||
self.inv = inv if inv != None else [] | self.inv = inv if inv != None else [] | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
self.inv = deser_vector(f, CInv) | self.inv = deser_vector(f, CInv) | ||||
def serialize(self): | def serialize(self): | ||||
return ser_vector(self.inv) | return ser_vector(self.inv) | ||||
def __repr__(self): | def __repr__(self): | ||||
return "msg_getdata(inv=%s)" % (repr(self.inv)) | return "msg_getdata(inv=%s)" % (repr(self.inv)) | ||||
class msg_getblocks(object): | class msg_getblocks(): | ||||
command = b"getblocks" | command = b"getblocks" | ||||
def __init__(self): | def __init__(self): | ||||
self.locator = CBlockLocator() | self.locator = CBlockLocator() | ||||
self.hashstop = 0 | self.hashstop = 0 | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
self.locator = CBlockLocator() | self.locator = CBlockLocator() | ||||
self.locator.deserialize(f) | self.locator.deserialize(f) | ||||
self.hashstop = deser_uint256(f) | self.hashstop = deser_uint256(f) | ||||
def serialize(self): | def serialize(self): | ||||
r = b"" | r = b"" | ||||
r += self.locator.serialize() | r += self.locator.serialize() | ||||
r += ser_uint256(self.hashstop) | r += ser_uint256(self.hashstop) | ||||
return r | return r | ||||
def __repr__(self): | def __repr__(self): | ||||
return "msg_getblocks(locator=%s hashstop=%064x)" \ | return "msg_getblocks(locator=%s hashstop=%064x)" \ | ||||
% (repr(self.locator), self.hashstop) | % (repr(self.locator), self.hashstop) | ||||
class msg_tx(object): | class msg_tx(): | ||||
command = b"tx" | command = b"tx" | ||||
def __init__(self, tx=CTransaction()): | def __init__(self, tx=CTransaction()): | ||||
self.tx = tx | self.tx = tx | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
self.tx.deserialize(f) | self.tx.deserialize(f) | ||||
def serialize(self): | def serialize(self): | ||||
return self.tx.serialize_without_witness() | return self.tx.serialize_without_witness() | ||||
def __repr__(self): | def __repr__(self): | ||||
return "msg_tx(tx=%s)" % (repr(self.tx)) | return "msg_tx(tx=%s)" % (repr(self.tx)) | ||||
class msg_witness_tx(msg_tx): | class msg_witness_tx(msg_tx): | ||||
def serialize(self): | def serialize(self): | ||||
return self.tx.serialize_with_witness() | return self.tx.serialize_with_witness() | ||||
class msg_block(object): | class msg_block(): | ||||
command = b"block" | command = b"block" | ||||
def __init__(self, block=None): | def __init__(self, block=None): | ||||
if block is None: | if block is None: | ||||
self.block = CBlock() | self.block = CBlock() | ||||
else: | else: | ||||
self.block = block | self.block = block | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
self.block.deserialize(f) | self.block.deserialize(f) | ||||
def serialize(self): | def serialize(self): | ||||
return self.block.serialize() | return self.block.serialize() | ||||
def __repr__(self): | def __repr__(self): | ||||
return "msg_block(block=%s)" % (repr(self.block)) | return "msg_block(block=%s)" % (repr(self.block)) | ||||
# for cases where a user needs tighter control over what is sent over the wire | # for cases where a user needs tighter control over what is sent over the wire | ||||
# note that the user must supply the name of the command, and the data | # note that the user must supply the name of the command, and the data | ||||
class msg_generic(object): | class msg_generic(): | ||||
def __init__(self, command, data=None): | def __init__(self, command, data=None): | ||||
self.command = command | self.command = command | ||||
self.data = data | self.data = data | ||||
def serialize(self): | def serialize(self): | ||||
return self.data | return self.data | ||||
def __repr__(self): | def __repr__(self): | ||||
return "msg_generic()" | return "msg_generic()" | ||||
class msg_witness_block(msg_block): | class msg_witness_block(msg_block): | ||||
def serialize(self): | def serialize(self): | ||||
r = self.block.serialize(with_witness=True) | r = self.block.serialize(with_witness=True) | ||||
return r | return r | ||||
class msg_getaddr(object): | class msg_getaddr(): | ||||
command = b"getaddr" | command = b"getaddr" | ||||
def __init__(self): | def __init__(self): | ||||
pass | pass | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
pass | pass | ||||
def serialize(self): | def serialize(self): | ||||
return b"" | return b"" | ||||
def __repr__(self): | def __repr__(self): | ||||
return "msg_getaddr()" | return "msg_getaddr()" | ||||
class msg_ping_prebip31(object): | class msg_ping_prebip31(): | ||||
command = b"ping" | command = b"ping" | ||||
def __init__(self): | def __init__(self): | ||||
pass | pass | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
pass | pass | ||||
def serialize(self): | def serialize(self): | ||||
return b"" | return b"" | ||||
def __repr__(self): | def __repr__(self): | ||||
return "msg_ping() (pre-bip31)" | return "msg_ping() (pre-bip31)" | ||||
class msg_ping(object): | class msg_ping(): | ||||
command = b"ping" | command = b"ping" | ||||
def __init__(self, nonce=0): | def __init__(self, nonce=0): | ||||
self.nonce = nonce | self.nonce = nonce | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
self.nonce = struct.unpack("<Q", f.read(8))[0] | self.nonce = struct.unpack("<Q", f.read(8))[0] | ||||
def serialize(self): | def serialize(self): | ||||
r = b"" | r = b"" | ||||
r += struct.pack("<Q", self.nonce) | r += struct.pack("<Q", self.nonce) | ||||
return r | return r | ||||
def __repr__(self): | def __repr__(self): | ||||
return "msg_ping(nonce=%08x)" % self.nonce | return "msg_ping(nonce=%08x)" % self.nonce | ||||
class msg_pong(object): | class msg_pong(): | ||||
command = b"pong" | command = b"pong" | ||||
def __init__(self, nonce=0): | def __init__(self, nonce=0): | ||||
self.nonce = nonce | self.nonce = nonce | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
self.nonce = struct.unpack("<Q", f.read(8))[0] | self.nonce = struct.unpack("<Q", f.read(8))[0] | ||||
def serialize(self): | def serialize(self): | ||||
r = b"" | r = b"" | ||||
r += struct.pack("<Q", self.nonce) | r += struct.pack("<Q", self.nonce) | ||||
return r | return r | ||||
def __repr__(self): | def __repr__(self): | ||||
return "msg_pong(nonce=%08x)" % self.nonce | return "msg_pong(nonce=%08x)" % self.nonce | ||||
class msg_mempool(object): | class msg_mempool(): | ||||
command = b"mempool" | command = b"mempool" | ||||
def __init__(self): | def __init__(self): | ||||
pass | pass | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
pass | pass | ||||
def serialize(self): | def serialize(self): | ||||
return b"" | return b"" | ||||
def __repr__(self): | def __repr__(self): | ||||
return "msg_mempool()" | return "msg_mempool()" | ||||
class msg_sendheaders(object): | class msg_sendheaders(): | ||||
command = b"sendheaders" | command = b"sendheaders" | ||||
def __init__(self): | def __init__(self): | ||||
pass | pass | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
pass | pass | ||||
def serialize(self): | def serialize(self): | ||||
return b"" | return b"" | ||||
def __repr__(self): | def __repr__(self): | ||||
return "msg_sendheaders()" | return "msg_sendheaders()" | ||||
# getheaders message has | # getheaders message has | ||||
# number of entries | # number of entries | ||||
# vector of hashes | # vector of hashes | ||||
# hash_stop (hash of last desired block header, 0 to get as many as possible) | # hash_stop (hash of last desired block header, 0 to get as many as possible) | ||||
class msg_getheaders(object): | class msg_getheaders(): | ||||
command = b"getheaders" | command = b"getheaders" | ||||
def __init__(self): | def __init__(self): | ||||
self.locator = CBlockLocator() | self.locator = CBlockLocator() | ||||
self.hashstop = 0 | self.hashstop = 0 | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
self.locator = CBlockLocator() | self.locator = CBlockLocator() | ||||
self.locator.deserialize(f) | self.locator.deserialize(f) | ||||
self.hashstop = deser_uint256(f) | self.hashstop = deser_uint256(f) | ||||
def serialize(self): | def serialize(self): | ||||
r = b"" | r = b"" | ||||
r += self.locator.serialize() | r += self.locator.serialize() | ||||
r += ser_uint256(self.hashstop) | r += ser_uint256(self.hashstop) | ||||
return r | return r | ||||
def __repr__(self): | def __repr__(self): | ||||
return "msg_getheaders(locator=%s, stop=%064x)" \ | return "msg_getheaders(locator=%s, stop=%064x)" \ | ||||
% (repr(self.locator), self.hashstop) | % (repr(self.locator), self.hashstop) | ||||
# headers message has | # headers message has | ||||
# <count> <vector of block headers> | # <count> <vector of block headers> | ||||
class msg_headers(object): | class msg_headers(): | ||||
command = b"headers" | command = b"headers" | ||||
def __init__(self): | def __init__(self): | ||||
self.headers = [] | self.headers = [] | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
# comment in bitcoind indicates these should be deserialized as blocks | # comment in bitcoind indicates these should be deserialized as blocks | ||||
blocks = deser_vector(f, CBlock) | blocks = deser_vector(f, CBlock) | ||||
for x in blocks: | for x in blocks: | ||||
self.headers.append(CBlockHeader(x)) | self.headers.append(CBlockHeader(x)) | ||||
def serialize(self): | def serialize(self): | ||||
blocks = [CBlock(x) for x in self.headers] | blocks = [CBlock(x) for x in self.headers] | ||||
return ser_vector(blocks) | return ser_vector(blocks) | ||||
def __repr__(self): | def __repr__(self): | ||||
return "msg_headers(headers=%s)" % repr(self.headers) | return "msg_headers(headers=%s)" % repr(self.headers) | ||||
class msg_reject(object): | class msg_reject(): | ||||
command = b"reject" | command = b"reject" | ||||
REJECT_MALFORMED = 1 | REJECT_MALFORMED = 1 | ||||
def __init__(self): | def __init__(self): | ||||
self.message = b"" | self.message = b"" | ||||
self.code = 0 | self.code = 0 | ||||
self.reason = b"" | self.reason = b"" | ||||
self.data = 0 | self.data = 0 | ||||
Show All 14 Lines | def serialize(self): | ||||
(self.message == b"block" or self.message == b"tx")): | (self.message == b"block" or self.message == b"tx")): | ||||
r += ser_uint256(self.data) | r += ser_uint256(self.data) | ||||
return r | return r | ||||
def __repr__(self): | def __repr__(self): | ||||
return "msg_reject: %s %d %s [%064x]" \ | return "msg_reject: %s %d %s [%064x]" \ | ||||
% (self.message, self.code, self.reason, self.data) | % (self.message, self.code, self.reason, self.data) | ||||
# Helper function | |||||
def wait_until(predicate, *, attempts=float('inf'), timeout=float('inf')): | def wait_until(predicate, *, attempts=float('inf'), timeout=float('inf')): | ||||
''' | |||||
This function is subsequently remove in core's PR11712 | |||||
''' | |||||
attempt = 0 | attempt = 0 | ||||
elapsed = 0 | elapsed = 0 | ||||
while attempt < attempts and elapsed < timeout: | while attempt < attempts and elapsed < timeout: | ||||
with mininode_lock: | with mininode_lock: | ||||
if predicate(): | if predicate(): | ||||
return True | return True | ||||
attempt += 1 | attempt += 1 | ||||
elapsed += 0.05 | elapsed += 0.05 | ||||
time.sleep(0.05) | time.sleep(0.05) | ||||
return False | return False | ||||
class msg_feefilter(object): | class msg_feefilter(): | ||||
command = b"feefilter" | command = b"feefilter" | ||||
def __init__(self, feerate=0): | def __init__(self, feerate=0): | ||||
self.feerate = feerate | self.feerate = feerate | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
self.feerate = struct.unpack("<Q", f.read(8))[0] | self.feerate = struct.unpack("<Q", f.read(8))[0] | ||||
def serialize(self): | def serialize(self): | ||||
r = b"" | r = b"" | ||||
r += struct.pack("<Q", self.feerate) | r += struct.pack("<Q", self.feerate) | ||||
return r | return r | ||||
def __repr__(self): | def __repr__(self): | ||||
return "msg_feefilter(feerate=%08x)" % self.feerate | return "msg_feefilter(feerate=%08x)" % self.feerate | ||||
class msg_sendcmpct(object): | class msg_sendcmpct(): | ||||
command = b"sendcmpct" | command = b"sendcmpct" | ||||
def __init__(self): | def __init__(self): | ||||
self.announce = False | self.announce = False | ||||
self.version = 1 | self.version = 1 | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
self.announce = struct.unpack("<?", f.read(1))[0] | self.announce = struct.unpack("<?", f.read(1))[0] | ||||
self.version = struct.unpack("<Q", f.read(8))[0] | self.version = struct.unpack("<Q", f.read(8))[0] | ||||
def serialize(self): | def serialize(self): | ||||
r = b"" | r = b"" | ||||
r += struct.pack("<?", self.announce) | r += struct.pack("<?", self.announce) | ||||
r += struct.pack("<Q", self.version) | r += struct.pack("<Q", self.version) | ||||
return r | return r | ||||
def __repr__(self): | def __repr__(self): | ||||
return "msg_sendcmpct(announce=%s, version=%lu)" % (self.announce, self.version) | return "msg_sendcmpct(announce=%s, version=%lu)" % (self.announce, self.version) | ||||
class msg_cmpctblock(object): | class msg_cmpctblock(): | ||||
command = b"cmpctblock" | command = b"cmpctblock" | ||||
def __init__(self, header_and_shortids=None): | def __init__(self, header_and_shortids=None): | ||||
self.header_and_shortids = header_and_shortids | self.header_and_shortids = header_and_shortids | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
self.header_and_shortids = P2PHeaderAndShortIDs() | self.header_and_shortids = P2PHeaderAndShortIDs() | ||||
self.header_and_shortids.deserialize(f) | self.header_and_shortids.deserialize(f) | ||||
def serialize(self): | def serialize(self): | ||||
r = b"" | r = b"" | ||||
r += self.header_and_shortids.serialize() | r += self.header_and_shortids.serialize() | ||||
return r | return r | ||||
def __repr__(self): | def __repr__(self): | ||||
return "msg_cmpctblock(HeaderAndShortIDs=%s)" % repr(self.header_and_shortids) | return "msg_cmpctblock(HeaderAndShortIDs=%s)" % repr(self.header_and_shortids) | ||||
class msg_getblocktxn(object): | class msg_getblocktxn(): | ||||
command = b"getblocktxn" | command = b"getblocktxn" | ||||
def __init__(self): | def __init__(self): | ||||
self.block_txn_request = None | self.block_txn_request = None | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
self.block_txn_request = BlockTransactionsRequest() | self.block_txn_request = BlockTransactionsRequest() | ||||
self.block_txn_request.deserialize(f) | self.block_txn_request.deserialize(f) | ||||
def serialize(self): | def serialize(self): | ||||
r = b"" | r = b"" | ||||
r += self.block_txn_request.serialize() | r += self.block_txn_request.serialize() | ||||
return r | return r | ||||
def __repr__(self): | def __repr__(self): | ||||
return "msg_getblocktxn(block_txn_request=%s)" % (repr(self.block_txn_request)) | return "msg_getblocktxn(block_txn_request=%s)" % (repr(self.block_txn_request)) | ||||
class msg_blocktxn(object): | class msg_blocktxn(): | ||||
command = b"blocktxn" | command = b"blocktxn" | ||||
def __init__(self): | def __init__(self): | ||||
self.block_transactions = BlockTransactions() | self.block_transactions = BlockTransactions() | ||||
def deserialize(self, f): | def deserialize(self, f): | ||||
self.block_transactions.deserialize(f) | self.block_transactions.deserialize(f) | ||||
Show All 9 Lines | |||||
class msg_witness_blocktxn(msg_blocktxn): | class msg_witness_blocktxn(msg_blocktxn): | ||||
def serialize(self): | def serialize(self): | ||||
r = b"" | r = b"" | ||||
r += self.block_transactions.serialize(with_witness=True) | r += self.block_transactions.serialize(with_witness=True) | ||||
return r | return r | ||||
class NodeConnCB(object): | class NodeConnCB(): | ||||
"""Callback and helper functions for P2P connection to a bitcoind node. | """Callback and helper functions for P2P connection to a bitcoind node. | ||||
Individual testcases should subclass this and override the on_* methods | Individual testcases should subclass this and override the on_* methods | ||||
if they want to alter message handling behaviour. | if they want to alter message handling behaviour. | ||||
""" | """ | ||||
def __init__(self): | def __init__(self): | ||||
# Track whether we have a P2P connection open to the node | # Track whether we have a P2P connection open to the node | ||||
▲ Show 20 Lines • Show All 415 Lines • Show Last 20 Lines |