Skip to content

Commit

Permalink
Merge pull request #1911 from codablock/pr_backports_from_cmptblk
Browse files Browse the repository at this point in the history
Backports from compact block related Bitcoin PRs
  • Loading branch information
UdjinM6 authored Feb 9, 2018
2 parents 120893c + 4ac4e96 commit 6825b34
Show file tree
Hide file tree
Showing 15 changed files with 200 additions and 182 deletions.
4 changes: 2 additions & 2 deletions qa/rpc-tests/p2p-fullblocktest.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ def update_block(block_number, new_transactions):

# Extend the b26 chain to make sure bitcoind isn't accepting b26
b27 = block(27, spend=out[7])
yield rejected(RejectResult(16, b'bad-prevblk'))
yield rejected(RejectResult(0, b'bad-prevblk'))

# Now try a too-large-coinbase script
tip(15)
Expand All @@ -411,7 +411,7 @@ def update_block(block_number, new_transactions):

# Extend the b28 chain to make sure bitcoind isn't accepting b28
b29 = block(29, spend=out[7])
yield rejected(RejectResult(16, b'bad-prevblk'))
yield rejected(RejectResult(0, b'bad-prevblk'))

# b30 has a max-sized coinbase scriptSig.
tip(23)
Expand Down
2 changes: 1 addition & 1 deletion qa/rpc-tests/preciousblock.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def run_test(self):
assert_equal(self.nodes[2].getblockcount(), 6)
hashL = self.nodes[2].getbestblockhash()
print("Connect nodes and check no reorg occurs")
node_sync_via_rpc(self.nodes[0:3])
node_sync_via_rpc(self.nodes[1:3])
connect_nodes_bi(self.nodes,1,2)
connect_nodes_bi(self.nodes,0,2)
assert_equal(self.nodes[0].getbestblockhash(), hashH)
Expand Down
68 changes: 26 additions & 42 deletions qa/rpc-tests/sendheaders.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,30 +80,26 @@
Expect: disconnect.
'''

class BaseNode(NodeConnCB):
direct_fetch_response_time = 0.05

class BaseNode(SingleNodeConnCB):
def __init__(self):
NodeConnCB.__init__(self)
self.connection = None
SingleNodeConnCB.__init__(self)
self.last_inv = None
self.last_headers = None
self.last_block = None
self.ping_counter = 1
self.last_pong = msg_pong(0)
self.last_getdata = None
self.sleep_time = 0.05
self.block_announced = False
self.last_getheaders = None
self.disconnected = False
self.last_blockhash_announced = None

def clear_last_announcement(self):
with mininode_lock:
self.block_announced = False
self.last_inv = None
self.last_headers = None

def add_connection(self, conn):
self.connection = conn

# Request data for a list of block hashes
def get_data(self, block_hashes):
msg = msg_getdata()
Expand All @@ -122,17 +118,17 @@ def send_block_inv(self, blockhash):
msg.inv = [CInv(2, blockhash)]
self.connection.send_message(msg)

# Wrapper for the NodeConn's send_message function
def send_message(self, message):
self.connection.send_message(message)

def on_inv(self, conn, message):
self.last_inv = message
self.block_announced = True
self.last_blockhash_announced = message.inv[-1].hash

def on_headers(self, conn, message):
self.last_headers = message
self.block_announced = True
if len(message.headers):
self.block_announced = True
message.headers[-1].calc_sha256()
self.last_blockhash_announced = message.headers[-1].sha256

def on_block(self, conn, message):
self.last_block = message.block
Expand All @@ -141,9 +137,6 @@ def on_block(self, conn, message):
def on_getdata(self, conn, message):
self.last_getdata = message

def on_pong(self, conn, message):
self.last_pong = message

def on_getheaders(self, conn, message):
self.last_getheaders = message

Expand All @@ -157,7 +150,7 @@ def check_last_announcement(self, headers=None, inv=None):
expect_headers = headers if headers != None else []
expect_inv = inv if inv != None else []
test_function = lambda: self.block_announced
self.sync(test_function)
assert(wait_until(test_function, timeout=60))
with mininode_lock:
self.block_announced = False

Expand All @@ -180,43 +173,32 @@ def check_last_announcement(self, headers=None, inv=None):
return success

# Syncing helpers
def sync(self, test_function, timeout=60):
while timeout > 0:
with mininode_lock:
if test_function():
return
time.sleep(self.sleep_time)
timeout -= self.sleep_time
raise AssertionError("Sync failed to complete")

def sync_with_ping(self, timeout=60):
self.send_message(msg_ping(nonce=self.ping_counter))
test_function = lambda: self.last_pong.nonce == self.ping_counter
self.sync(test_function, timeout)
self.ping_counter += 1
return

def wait_for_block(self, blockhash, timeout=60):
test_function = lambda: self.last_block != None and self.last_block.sha256 == blockhash
self.sync(test_function, timeout)
assert(wait_until(test_function, timeout=timeout))
return

def wait_for_getheaders(self, timeout=60):
test_function = lambda: self.last_getheaders != None
self.sync(test_function, timeout)
assert(wait_until(test_function, timeout=timeout))
return

def wait_for_getdata(self, hash_list, timeout=60):
if hash_list == []:
return

test_function = lambda: self.last_getdata != None and [x.hash for x in self.last_getdata.inv] == hash_list
self.sync(test_function, timeout)
assert(wait_until(test_function, timeout=timeout))
return

def wait_for_disconnect(self, timeout=60):
test_function = lambda: self.disconnected
self.sync(test_function, timeout)
assert(wait_until(test_function, timeout=timeout))
return

def wait_for_block_announcement(self, block_hash, timeout=60):
test_function = lambda: self.last_blockhash_announced == block_hash
assert(wait_until(test_function, timeout=timeout))
return

def send_header_for_blocks(self, new_blocks):
Expand Down Expand Up @@ -266,7 +248,9 @@ def mine_blocks(self, count):
def mine_reorg(self, length):
self.nodes[0].generate(length) # make sure all invalidated blocks are node0's
sync_blocks(self.nodes, wait=0.1)
[x.clear_last_announcement() for x in self.p2p_connections]
for x in self.p2p_connections:
x.wait_for_block_announcement(int(self.nodes[0].getbestblockhash(), 16))
x.clear_last_announcement()

tip_height = self.nodes[1].getblockcount()
hash_to_invalidate = self.nodes[1].getblockhash(tip_height-(length-1))
Expand Down Expand Up @@ -494,7 +478,7 @@ def run_test(self):

test_node.send_header_for_blocks(blocks)
test_node.sync_with_ping()
test_node.wait_for_getdata([x.sha256 for x in blocks], timeout=test_node.sleep_time)
test_node.wait_for_getdata([x.sha256 for x in blocks], timeout=direct_fetch_response_time)

[ test_node.send_message(msg_block(x)) for x in blocks ]

Expand Down Expand Up @@ -525,13 +509,13 @@ def run_test(self):
# both blocks (same work as tip)
test_node.send_header_for_blocks(blocks[1:2])
test_node.sync_with_ping()
test_node.wait_for_getdata([x.sha256 for x in blocks[0:2]], timeout=test_node.sleep_time)
test_node.wait_for_getdata([x.sha256 for x in blocks[0:2]], timeout=direct_fetch_response_time)

# Announcing 16 more headers should trigger direct fetch for 14 more
# blocks
test_node.send_header_for_blocks(blocks[2:18])
test_node.sync_with_ping()
test_node.wait_for_getdata([x.sha256 for x in blocks[2:16]], timeout=test_node.sleep_time)
test_node.wait_for_getdata([x.sha256 for x in blocks[2:16]], timeout=direct_fetch_response_time)

# Announcing 1 more header should not trigger any response
test_node.last_getdata = None
Expand Down
100 changes: 27 additions & 73 deletions qa/rpc-tests/test_framework/mininode.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,24 +77,34 @@ def hash256(s):
def dashhash(s):
return dash_hash.getPoWHash(s)

def deser_string(f):
def ser_compact_size(l):
r = b""
if l < 253:
r = struct.pack("B", l)
elif l < 0x10000:
r = struct.pack("<BH", 253, l)
elif l < 0x100000000:
r = struct.pack("<BI", 254, l)
else:
r = struct.pack("<BQ", 255, l)
return r

def deser_compact_size(f):
nit = struct.unpack("<B", f.read(1))[0]
if nit == 253:
nit = struct.unpack("<H", f.read(2))[0]
elif nit == 254:
nit = struct.unpack("<I", f.read(4))[0]
elif nit == 255:
nit = struct.unpack("<Q", f.read(8))[0]
return nit

def deser_string(f):
nit = deser_compact_size(f)
return f.read(nit)

def ser_string(s):
if len(s) < 253:
return struct.pack("B", len(s)) + s
elif len(s) < 0x10000:
return struct.pack("<BH", 253, len(s)) + s
elif len(s) < 0x100000000:
return struct.pack("<BI", 254, len(s)) + s
return struct.pack("<BQ", 255, len(s)) + s
return ser_compact_size(len(s)) + s

def deser_uint256(f):
r = 0
Expand Down Expand Up @@ -127,13 +137,7 @@ def uint256_from_compact(c):


def deser_vector(f, c):
nit = struct.unpack("<B", f.read(1))[0]
if nit == 253:
nit = struct.unpack("<H", f.read(2))[0]
elif nit == 254:
nit = struct.unpack("<I", f.read(4))[0]
elif nit == 255:
nit = struct.unpack("<Q", f.read(8))[0]
nit = deser_compact_size(f)
r = []
for i in range(nit):
t = c()
Expand All @@ -143,28 +147,14 @@ def deser_vector(f, c):


def ser_vector(l):
r = b""
if len(l) < 253:
r = struct.pack("B", len(l))
elif len(l) < 0x10000:
r = struct.pack("<BH", 253, len(l))
elif len(l) < 0x100000000:
r = struct.pack("<BI", 254, len(l))
else:
r = struct.pack("<BQ", 255, len(l))
r = ser_compact_size(len(l))
for i in l:
r += i.serialize()
return r


def deser_uint256_vector(f):
nit = struct.unpack("<B", f.read(1))[0]
if nit == 253:
nit = struct.unpack("<H", f.read(2))[0]
elif nit == 254:
nit = struct.unpack("<I", f.read(4))[0]
elif nit == 255:
nit = struct.unpack("<Q", f.read(8))[0]
nit = deser_compact_size(f)
r = []
for i in range(nit):
t = deser_uint256(f)
Expand All @@ -173,28 +163,14 @@ def deser_uint256_vector(f):


def ser_uint256_vector(l):
r = b""
if len(l) < 253:
r = struct.pack("B", len(l))
elif len(l) < 0x10000:
r = struct.pack("<BH", 253, len(l))
elif len(l) < 0x100000000:
r = struct.pack("<BI", 254, len(l))
else:
r = struct.pack("<BQ", 255, len(l))
r = ser_compact_size(len(l))
for i in l:
r += ser_uint256(i)
return r


def deser_string_vector(f):
nit = struct.unpack("<B", f.read(1))[0]
if nit == 253:
nit = struct.unpack("<H", f.read(2))[0]
elif nit == 254:
nit = struct.unpack("<I", f.read(4))[0]
elif nit == 255:
nit = struct.unpack("<Q", f.read(8))[0]
nit = deser_compact_size(f)
r = []
for i in range(nit):
t = deser_string(f)
Expand All @@ -203,28 +179,14 @@ def deser_string_vector(f):


def ser_string_vector(l):
r = b""
if len(l) < 253:
r = struct.pack("B", len(l))
elif len(l) < 0x10000:
r = struct.pack("<BH", 253, len(l))
elif len(l) < 0x100000000:
r = struct.pack("<BI", 254, len(l))
else:
r = struct.pack("<BQ", 255, len(l))
r = ser_compact_size(len(l))
for sv in l:
r += ser_string(sv)
return r


def deser_int_vector(f):
nit = struct.unpack("<B", f.read(1))[0]
if nit == 253:
nit = struct.unpack("<H", f.read(2))[0]
elif nit == 254:
nit = struct.unpack("<I", f.read(4))[0]
elif nit == 255:
nit = struct.unpack("<Q", f.read(8))[0]
nit = deser_compact_size(f)
r = []
for i in range(nit):
t = struct.unpack("<i", f.read(4))[0]
Expand All @@ -233,15 +195,7 @@ def deser_int_vector(f):


def ser_int_vector(l):
r = b""
if len(l) < 253:
r = struct.pack("B", len(l))
elif len(l) < 0x10000:
r = struct.pack("<BH", 253, len(l))
elif len(l) < 0x100000000:
r = struct.pack("<BI", 254, len(l))
else:
r = struct.pack("<BQ", 255, len(l))
r = ser_compact_size(len(l))
for i in l:
r += struct.pack("<i", i)
return r
Expand Down Expand Up @@ -1191,7 +1145,7 @@ def sync_with_ping(self, timeout=30):
def received_pong():
return (self.last_pong.nonce == self.ping_counter)
self.send_message(msg_ping(nonce=self.ping_counter))
success = wait_until(received_pong, timeout)
success = wait_until(received_pong, timeout=timeout)
self.ping_counter += 1
return success

Expand Down
11 changes: 11 additions & 0 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,12 @@ class CRegTestParams : public CChainParams {
// Regtest Dash BIP44 coin type is '1' (All coin's testnet default)
nExtCoinType = 1;
}

void UpdateBIP9Parameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout)
{
consensus.vDeployments[d].nStartTime = nStartTime;
consensus.vDeployments[d].nTimeout = nTimeout;
}
};
static CRegTestParams regTestParams;

Expand Down Expand Up @@ -658,3 +664,8 @@ void SelectParams(const std::string& network)
SelectBaseParams(network);
pCurrentParams = &Params(network);
}

void UpdateRegtestBIP9Parameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout)
{
regTestParams.UpdateBIP9Parameters(d, nStartTime, nTimeout);
}
Loading

0 comments on commit 6825b34

Please sign in to comment.