Browse Source

Merge #8141: Continuing port of java comparison tool

ff2dcf2 Tests: Edit bloated varint test and add option for 'barely expensive' tests (mrbandrews)
12c5a16 Catch exceptions from non-canonical encoding and print only to log (mrbandrews)
291f8aa Continuing port of java comptool (mrbandrews)
8c9e681 Tests: Rework blockstore to avoid re-serialization. (mrbandrews)
0.13
Wladimir J. van der Laan 9 years ago
parent
commit
44c1b1c9bb
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
  1. 1089
      qa/rpc-tests/p2p-fullblocktest.py
  2. 41
      qa/rpc-tests/test_framework/blockstore.py
  3. 23
      qa/rpc-tests/test_framework/blocktools.py
  4. 12
      qa/rpc-tests/test_framework/mininode.py
  5. 5
      src/main.cpp

1089
qa/rpc-tests/p2p-fullblocktest.py

File diff suppressed because it is too large Load Diff

41
qa/rpc-tests/test_framework/blockstore.py

@ -17,12 +17,23 @@ class BlockStore(object):
def close(self): def close(self):
self.blockDB.close() self.blockDB.close()
def erase(self, blockhash):
del self.blockDB[repr(blockhash)]
# lookup an entry and return the item as raw bytes
def get(self, blockhash): def get(self, blockhash):
serialized_block = None value = None
try: try:
serialized_block = self.blockDB[repr(blockhash)] value = self.blockDB[repr(blockhash)]
except KeyError: except KeyError:
return None return None
return value
# lookup an entry and return it as a CBlock
def get_block(self, blockhash):
ret = None
serialized_block = self.get(blockhash)
if serialized_block is not None:
f = BytesIO(serialized_block) f = BytesIO(serialized_block)
ret = CBlock() ret = CBlock()
ret.deserialize(f) ret.deserialize(f)
@ -75,13 +86,16 @@ class BlockStore(object):
def add_header(self, header): def add_header(self, header):
self.headers_map[header.sha256] = header self.headers_map[header.sha256] = header
# lookup the hashes in "inv", and return p2p messages for delivering
# blocks found.
def get_blocks(self, inv): def get_blocks(self, inv):
responses = [] responses = []
for i in inv: for i in inv:
if (i.type == 2): # MSG_BLOCK if (i.type == 2): # MSG_BLOCK
block = self.get(i.hash) data = self.get(i.hash)
if block is not None: if data is not None:
responses.append(msg_block(block)) # Use msg_generic to avoid re-serialization
responses.append(msg_generic(b"block", data))
return responses return responses
def get_locator(self, current_tip=None): def get_locator(self, current_tip=None):
@ -90,11 +104,11 @@ class BlockStore(object):
r = [] r = []
counter = 0 counter = 0
step = 1 step = 1
lastBlock = self.get(current_tip) lastBlock = self.get_block(current_tip)
while lastBlock is not None: while lastBlock is not None:
r.append(lastBlock.hashPrevBlock) r.append(lastBlock.hashPrevBlock)
for i in range(step): for i in range(step):
lastBlock = self.get(lastBlock.hashPrevBlock) lastBlock = self.get_block(lastBlock.hashPrevBlock)
if lastBlock is None: if lastBlock is None:
break break
counter += 1 counter += 1
@ -111,12 +125,19 @@ class TxStore(object):
def close(self): def close(self):
self.txDB.close() self.txDB.close()
# lookup an entry and return the item as raw bytes
def get(self, txhash): def get(self, txhash):
serialized_tx = None value = None
try: try:
serialized_tx = self.txDB[repr(txhash)] value = self.txDB[repr(txhash)]
except KeyError: except KeyError:
return None return None
return value
def get_transaction(self, txhash):
ret = None
serialized_tx = self.get(txhash)
if serialized_tx is not None:
f = BytesIO(serialized_tx) f = BytesIO(serialized_tx)
ret = CTransaction() ret = CTransaction()
ret.deserialize(f) ret.deserialize(f)
@ -136,5 +157,5 @@ class TxStore(object):
if (i.type == 1): # MSG_TX if (i.type == 1): # MSG_TX
tx = self.get(i.hash) tx = self.get(i.hash)
if tx is not None: if tx is not None:
responses.append(msg_tx(tx)) responses.append(msg_generic(b"tx", tx))
return responses return responses

23
qa/rpc-tests/test_framework/blocktools.py

@ -56,12 +56,27 @@ def create_coinbase(height, pubkey = None):
coinbase.calc_sha256() coinbase.calc_sha256()
return coinbase return coinbase
# Create a transaction with an anyone-can-spend output, that spends the # Create a transaction.
# nth output of prevtx. # If the scriptPubKey is not specified, make it anyone-can-spend.
def create_transaction(prevtx, n, sig, value): def create_transaction(prevtx, n, sig, value, scriptPubKey=CScript()):
tx = CTransaction() tx = CTransaction()
assert(n < len(prevtx.vout)) assert(n < len(prevtx.vout))
tx.vin.append(CTxIn(COutPoint(prevtx.sha256, n), sig, 0xffffffff)) tx.vin.append(CTxIn(COutPoint(prevtx.sha256, n), sig, 0xffffffff))
tx.vout.append(CTxOut(value, b"")) tx.vout.append(CTxOut(value, scriptPubKey))
tx.calc_sha256() tx.calc_sha256()
return tx return tx
def get_legacy_sigopcount_block(block, fAccurate=True):
count = 0
for tx in block.vtx:
count += get_legacy_sigopcount_tx(tx, fAccurate)
return count
def get_legacy_sigopcount_tx(tx, fAccurate=True):
count = 0
for i in tx.vout:
count += i.scriptPubKey.GetSigOpCount(fAccurate)
for j in tx.vin:
# scriptSig might be of type bytes, so convert to CScript for the moment
count += CScript(j.scriptSig).GetSigOpCount(fAccurate)
return count

12
qa/rpc-tests/test_framework/mininode.py

@ -836,6 +836,18 @@ class msg_block(object):
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
# note that the user must supply the name of the command, and the data
class msg_generic(object):
def __init__(self, command, data=None):
self.command = command
self.data = data
def serialize(self):
return self.data
def __repr__(self):
return "msg_generic()"
class msg_getaddr(object): class msg_getaddr(object):
command = b"getaddr" command = b"getaddr"

5
src/main.cpp

@ -5609,6 +5609,11 @@ bool ProcessMessages(CNode* pfrom)
// Allow exceptions from over-long size // Allow exceptions from over-long size
LogPrintf("%s(%s, %u bytes): Exception '%s' caught\n", __func__, SanitizeString(strCommand), nMessageSize, e.what()); LogPrintf("%s(%s, %u bytes): Exception '%s' caught\n", __func__, SanitizeString(strCommand), nMessageSize, e.what());
} }
else if (strstr(e.what(), "non-canonical ReadCompactSize()"))
{
// Allow exceptions from non-canonical encoding
LogPrintf("%s(%s, %u bytes): Exception '%s' caught\n", __func__, SanitizeString(strCommand), nMessageSize, e.what());
}
else else
{ {
PrintExceptionContinue(&e, "ProcessMessages()"); PrintExceptionContinue(&e, "ProcessMessages()");

Loading…
Cancel
Save