Skip to content

Commit 8c9e681

Browse files
committed
Tests: Rework blockstore to avoid re-serialization.
1 parent 425278d commit 8c9e681

File tree

2 files changed

+53
-19
lines changed

2 files changed

+53
-19
lines changed

qa/rpc-tests/test_framework/blockstore.py

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,31 @@ def __init__(self, datadir):
1313
self.blockDB = dbm.ndbm.open(datadir + "/blocks", 'c')
1414
self.currentBlock = 0
1515
self.headers_map = dict()
16-
16+
1717
def close(self):
1818
self.blockDB.close()
1919

20+
def erase(self, blockhash):
21+
del self.blockDB[repr(blockhash)]
22+
23+
# lookup an entry and return the item as raw bytes
2024
def get(self, blockhash):
21-
serialized_block = None
25+
value = None
2226
try:
23-
serialized_block = self.blockDB[repr(blockhash)]
27+
value = self.blockDB[repr(blockhash)]
2428
except KeyError:
2529
return None
26-
f = BytesIO(serialized_block)
27-
ret = CBlock()
28-
ret.deserialize(f)
29-
ret.calc_sha256()
30+
return value
31+
32+
# lookup an entry and return it as a CBlock
33+
def get_block(self, blockhash):
34+
ret = None
35+
serialized_block = self.get(blockhash)
36+
if serialized_block is not None:
37+
f = BytesIO(serialized_block)
38+
ret = CBlock()
39+
ret.deserialize(f)
40+
ret.calc_sha256()
3041
return ret
3142

3243
def get_header(self, blockhash):
@@ -75,13 +86,16 @@ def add_block(self, block):
7586
def add_header(self, header):
7687
self.headers_map[header.sha256] = header
7788

89+
# lookup the hashes in "inv", and return p2p messages for delivering
90+
# blocks found.
7891
def get_blocks(self, inv):
7992
responses = []
8093
for i in inv:
8194
if (i.type == 2): # MSG_BLOCK
82-
block = self.get(i.hash)
83-
if block is not None:
84-
responses.append(msg_block(block))
95+
data = self.get(i.hash)
96+
if data is not None:
97+
# Use msg_generic to avoid re-serialization
98+
responses.append(msg_generic(b"block", data))
8599
return responses
86100

87101
def get_locator(self, current_tip=None):
@@ -90,11 +104,11 @@ def get_locator(self, current_tip=None):
90104
r = []
91105
counter = 0
92106
step = 1
93-
lastBlock = self.get(current_tip)
107+
lastBlock = self.get_block(current_tip)
94108
while lastBlock is not None:
95109
r.append(lastBlock.hashPrevBlock)
96110
for i in range(step):
97-
lastBlock = self.get(lastBlock.hashPrevBlock)
111+
lastBlock = self.get_block(lastBlock.hashPrevBlock)
98112
if lastBlock is None:
99113
break
100114
counter += 1
@@ -111,16 +125,23 @@ def __init__(self, datadir):
111125
def close(self):
112126
self.txDB.close()
113127

128+
# lookup an entry and return the item as raw bytes
114129
def get(self, txhash):
115-
serialized_tx = None
130+
value = None
116131
try:
117-
serialized_tx = self.txDB[repr(txhash)]
132+
value = self.txDB[repr(txhash)]
118133
except KeyError:
119134
return None
120-
f = BytesIO(serialized_tx)
121-
ret = CTransaction()
122-
ret.deserialize(f)
123-
ret.calc_sha256()
135+
return value
136+
137+
def get_transaction(self, txhash):
138+
ret = None
139+
serialized_tx = self.get(txhash)
140+
if serialized_tx is not None:
141+
f = BytesIO(serialized_tx)
142+
ret = CTransaction()
143+
ret.deserialize(f)
144+
ret.calc_sha256()
124145
return ret
125146

126147
def add_transaction(self, tx):
@@ -136,5 +157,5 @@ def get_transactions(self, inv):
136157
if (i.type == 1): # MSG_TX
137158
tx = self.get(i.hash)
138159
if tx is not None:
139-
responses.append(msg_tx(tx))
160+
responses.append(msg_generic(b"tx", tx))
140161
return responses

qa/rpc-tests/test_framework/mininode.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,7 @@ def solve(self):
556556
self.nNonce += 1
557557
self.rehash()
558558

559+
559560
def __repr__(self):
560561
return "CBlock(nVersion=%i hashPrevBlock=%064x hashMerkleRoot=%064x nTime=%s nBits=%08x nNonce=%08x vtx=%s)" \
561562
% (self.nVersion, self.hashPrevBlock, self.hashMerkleRoot,
@@ -836,6 +837,18 @@ def serialize(self):
836837
def __repr__(self):
837838
return "msg_block(block=%s)" % (repr(self.block))
838839

840+
# for cases where a user needs tighter control over what is sent over the wire
841+
# note that the user must supply the name of the command, and the data
842+
class msg_generic(object):
843+
def __init__(self, command, data=None):
844+
self.command = command
845+
self.data = data
846+
847+
def serialize(self):
848+
return self.data
849+
850+
def __repr__(self):
851+
return "msg_generic()"
839852

840853
class msg_getaddr(object):
841854
command = b"getaddr"

0 commit comments

Comments
 (0)