Skip to content

Commit

Permalink
Refactoring for sc_cert_getblocktemplate.py
Browse files Browse the repository at this point in the history
Python script performs optional check based on overall execution time
Pyhton script optimization
RPC command getblocktemplate optimization
  • Loading branch information
JackPiri committed Jul 27, 2023
1 parent 84fa80a commit a4a89ee
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 23 deletions.
73 changes: 51 additions & 22 deletions qa/rpc-tests/sc_cert_getblocktemplate.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,22 @@
FT_SC_FEE = Decimal('0')
MBTR_SC_FEE = Decimal('0')
CERT_FEE = Decimal('0.00015')

GET_BLOCK_TEMPLATE_DELAY = 5 + 1 # Seconds ("+1" due to the fact the getblocktemplate trigger condition is ">5")
GET_BLOCK_TEMPLATE_DELAY_SEVERE = GET_BLOCK_TEMPLATE_DELAY - 1 # Seconds ("-1" due to the fact that getblocktemplate uses rounding to seconds)
#
# time1: 100.2 ---> time1_s: 100
# time2: 106.1 ---> time2_s: 106
# time2 - time1 = 5.9, time2_s - time1_s = 6
#
# script with "time2 - time1 > GET_BLOCK_TEMPLATE_DELAY" would not detect threshold crossing
# while checking with "time2 - time1 > GET_BLOCK_TEMPLATE_DELAY_SEVERE" would detect it


class sc_cert_base(BitcoinTestFramework):

unexpected_too_long_op = 0

def setup_chain(self, split=False):
print("Initializing test directory " + self.options.tmpdir)
initialize_chain_clean(self.options.tmpdir, NUMB_OF_NODES)
Expand Down Expand Up @@ -138,25 +149,30 @@ def run_test_with_scversion(self, scversion, ceasable = True):

### 1: Creating a transaction
node2_address = self.nodes[2].getnewaddress()
mark_logs("\nCall GetBlockTemplate on each node to create a cached (empty) version; check it is empty", self.nodes, DEBUG_MODE)
mark_logs("\nCall GetBlockTemplate on each node to create a new cached version; check it is empty", self.nodes, DEBUG_MODE)
for i in range(0, NUMB_OF_NODES):
cacheTime[i] = time.time()
blocktemplate = self.nodes[i].getblocktemplate()
assert_equal(len(blocktemplate['certificates']), 0)
assert_equal(len(blocktemplate['transactions']), 0)
mark_logs(f"Node{i} ok", self.nodes, DEBUG_MODE)
print(f"Node{i} ok") # print instead of mark_logs for being quicker

mark_logs("Node 0 sends a transaction", self.nodes, DEBUG_MODE)
print("Node 0 sends a transaction") # print instead of mark_logs for being quicker
self.nodes[0].sendtoaddress(node2_address, 0.1)
sync_mempools(self.nodes, 0.1) # syncing mempools only, because there is no need to check for blocks sync and here it's important to be as quick as possible

mark_logs("Check that the transaction is not immediately included into the block template", self.nodes, DEBUG_MODE)
print("Check that the transaction is not immediately included into the block template") # print instead of mark_logs for being quicker
for i in range(0, NUMB_OF_NODES):
blocktemplate = self.nodes[i].getblocktemplate()
mark_logs(f"Elapsed seconds from last cached result: {time.time() - cacheTime[i]}", self.nodes, DEBUG_MODE)
assert_equal(len(blocktemplate['certificates']), 0)
assert_equal(len(blocktemplate['transactions']), 0)
mark_logs(f"Node{i} ok", self.nodes, DEBUG_MODE)
deltaTime = time.time() - cacheTime[i]
print(f"Elapsed seconds from last cached result: {deltaTime}") # print instead of mark_logs for being quicker
if (deltaTime <= GET_BLOCK_TEMPLATE_DELAY_SEVERE):
assert_equal(len(blocktemplate['certificates']), 0)
assert_equal(len(blocktemplate['transactions']), 0)
print(f"Node{i} ok") # print instead of mark_logs for being quicker
else:
self.unexpected_too_long_op += 1
print("Skipping check due to too long operations") # print instead of mark_logs for being quicker

mark_logs(f"Wait {GET_BLOCK_TEMPLATE_DELAY} seconds and check that the transaction is now included into the block template", self.nodes, DEBUG_MODE)
time.sleep(GET_BLOCK_TEMPLATE_DELAY)
Expand All @@ -177,9 +193,9 @@ def run_test_with_scversion(self, scversion, ceasable = True):
blocktemplate = self.nodes[i].getblocktemplate()
assert_equal(len(blocktemplate['certificates']), 0)
assert_equal(len(blocktemplate['transactions']), 0)
mark_logs(f"Node{i} ok", self.nodes, DEBUG_MODE)
print(f"Node{i} ok") # print instead of mark_logs for being quicker

mark_logs("Node 0 sends a certificate", self.nodes, DEBUG_MODE)
print("Node 0 sends a certificate") # print instead of mark_logs for being quicker
try:
cert_epoch_0 = self.nodes[0].sc_send_certificate(scid, epoch_number, quality,
epoch_cum_tree_hash, proof, amount_cert_1, FT_SC_FEE, MBTR_SC_FEE, CERT_FEE)
Expand All @@ -190,13 +206,18 @@ def run_test_with_scversion(self, scversion, ceasable = True):
assert(False)
sync_mempools(self.nodes, 0.1) # syncing mempools only, because there is no need to check for blocks sync and here it's important to be as quick as possible

mark_logs("Check that the certificate is not immediately included into the block template", self.nodes, DEBUG_MODE)
print("Check that the certificate is not immediately included into the block template") # print instead of mark_logs for being quicker
for i in range(0, NUMB_OF_NODES):
blocktemplate = self.nodes[i].getblocktemplate()
mark_logs(f"Elapsed seconds from last cached result: {time.time() - cacheTime[i]}", self.nodes, DEBUG_MODE)
assert_equal(len(blocktemplate['certificates']), 0)
assert_equal(len(blocktemplate['transactions']), 0)
mark_logs(f"Node{i} ok", self.nodes, DEBUG_MODE)
deltaTime = time.time() - cacheTime[i]
print(f"Elapsed seconds from last cached result: {deltaTime}") # print instead of mark_logs for being quicker
if (deltaTime <= GET_BLOCK_TEMPLATE_DELAY_SEVERE):
assert_equal(len(blocktemplate['certificates']), 0)
assert_equal(len(blocktemplate['transactions']), 0)
print(f"Node{i} ok") # print instead of mark_logs for being quicker
else:
self.unexpected_too_long_op += 1
print("Skipping check due to too long operations") # print instead of mark_logs for being quicker

mark_logs(f"Wait {GET_BLOCK_TEMPLATE_DELAY} seconds and check that the certificate is now included into the block template", self.nodes, DEBUG_MODE)
time.sleep(GET_BLOCK_TEMPLATE_DELAY)
Expand Down Expand Up @@ -226,9 +247,9 @@ def run_test_with_scversion(self, scversion, ceasable = True):
blocktemplate = self.nodes[i].getblocktemplate()
assert_equal(len(blocktemplate['certificates']), 0)
assert_equal(len(blocktemplate['transactions']), 0)
mark_logs(f"Node{i} ok", self.nodes, DEBUG_MODE)
print(f"Node{i} ok") # print instead of mark_logs for being quicker

mark_logs("Node 0 sends a transaction and a certificate", self.nodes, DEBUG_MODE)
print("Node 0 sends a transaction and a certificate") # print instead of mark_logs for being quicker
self.nodes[0].sendtoaddress(node2_address, 0.1, "", "", True)

try:
Expand All @@ -241,13 +262,18 @@ def run_test_with_scversion(self, scversion, ceasable = True):
assert(False)
sync_mempools(self.nodes, 0.1) # syncing mempools only, because there is no need to check for blocks sync and here it's important to be as quick as possible

mark_logs("Check that the transaction and the certificate are not immediately included into the block template", self.nodes, DEBUG_MODE)
print("Check that the transaction and the certificate are not immediately included into the block template") # print instead of mark_logs for being quicker
for i in range(0, NUMB_OF_NODES):
blocktemplate = self.nodes[i].getblocktemplate()
mark_logs(f"Elapsed seconds from last cached result: {time.time() - cacheTime[i]}", self.nodes, DEBUG_MODE)
assert_equal(len(blocktemplate['certificates']), 0)
assert_equal(len(blocktemplate['transactions']), 0)
mark_logs(f"Node{i} ok", self.nodes, DEBUG_MODE)
deltaTime = time.time() - cacheTime[i]
print(f"Elapsed seconds from last cached result: {deltaTime}") # print instead of mark_logs for being quicker
if (deltaTime <= GET_BLOCK_TEMPLATE_DELAY_SEVERE):
assert_equal(len(blocktemplate['certificates']), 0)
assert_equal(len(blocktemplate['transactions']), 0)
print(f"Node{i} ok") # print instead of mark_logs for being quicker
else:
self.unexpected_too_long_op += 1
print("Skipping check due to too long operations") # print instead of mark_logs for being quicker

mark_logs(f"Wait {GET_BLOCK_TEMPLATE_DELAY} seconds and check that the transaction and the certificate are now included into the block template", self.nodes, DEBUG_MODE)
time.sleep(GET_BLOCK_TEMPLATE_DELAY)
Expand Down Expand Up @@ -354,6 +380,9 @@ def run_test(self):
mark_logs("\n**SC version 2 - non-ceasable SC", self.nodes, DEBUG_MODE)
self.run_test_with_scversion(2, False)

# allow too long operations only once
assert_greater_than(2, self.unexpected_too_long_op)


if __name__ == '__main__':
sc_cert_base().main()
3 changes: 2 additions & 1 deletion src/rpc/mining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,6 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)
// Store the pindexBest used before CreateNewBlockWithKey, to avoid races
nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
CBlockIndex* pindexPrevNew = chainActive.Tip();
nStart = GetTime();

// Create new block
if(pblocktemplate)
Expand All @@ -648,6 +647,8 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp)

// Need to update only after we know CreateNewBlockWithKey succeeded
pindexPrev = pindexPrevNew;

nStart = GetTime(); // update last execution time as final step
}
CBlock* pblock = &pblocktemplate->block; // pointer for convenience

Expand Down

0 comments on commit a4a89ee

Please sign in to comment.