def run_test(self): block_number = 8000 client = RpcClient(self.nodes[0]) start = time.time() genesis = client.best_block_hash() parent = genesis # generate main chain for i in range(block_number): parent = client.generate_block_with_parent(parent, referee=[]) if i % 100 == 0: self.log.info("generate %d blocks", i) prev_end = parent now = time.time() self.log.info("Time to process main chain of %d blocks: %f", block_number, now - start) start = now # process fork parent = genesis for i in range(block_number + 1): parent = client.generate_block_with_parent(parent, referee=[]) self.log.debug("block hash: %s", parent) if i % 100 == 0: self.log.info("generate %d blocks", i) now = time.time() self.log.info("Time to process fork of %d blocks: %f", block_number + 1, now - start) # switch back to main chain parent = prev_end start = time.time() for i in range(2): parent = client.generate_block_with_parent(parent, referee=[]) now = time.time() self.log.info("Time to switch back %f", now - start)
def run_test(self): n_generate_batch = 1000 n_initial_chain = 50000 self.log.info( f"Prepare the initial chain of node 0 with {n_initial_chain} blocks" ) n_batches = int(n_initial_chain / n_generate_batch) for i in range(n_batches): batch_generate(self.nodes[0], n_generate_batch, self.log) n_fork_height = 1000 n_star_count = 15000 for i in range(self.num_nodes): self.log.info( f"Prepare node {i} with a chain of the length {n_fork_height} and then a star of {n_star_count} blocks." ) client = RpcClient(self.nodes[i]) fork_point = client.generate_empty_blocks(n_fork_height)[-1] for _ in range(n_star_count): client.generate_block_with_parent(fork_point) for i in range(self.num_nodes - 1): connect_nodes(self.nodes, i, i + 1) self.log.info( "Nodes connected, normal mining start at the interval of 0.5") block_gen_thread = BlockGenThread(self.nodes, self.log, interval_base=0.5) block_gen_thread.start() start_time = time.time() original_cnt = self.nodes[0].getblockcount() for _ in range(100): time.sleep(1) cnt = self.nodes[0].getblockcount() try: cnt1 = self.nodes[1].getblockcount() except Exception as e: self.log.info( "Unable to get Node1 block count. Maybe it is busy.") cnt1 = -1 try: cnt2 = self.nodes[2].getblockcount() except Exception as e: self.log.info( "Unable to get Node2 block count. Maybe it is busy.") cnt2 = -1 elapsed = time.time() - start_time avg_block_processing = (cnt - original_cnt) / elapsed self.log.info( f"Nodes block count {cnt};{cnt1};{cnt2}, elapsed {elapsed}, {avg_block_processing} blocks/s" ) self.log.info( f"Merge bench average block processing speed: {avg_block_processing} blocks/s" )
def run_test(self): attacker = RpcClient(self.nodes[0]) victim = RpcClient(self.nodes[1]) n_generate_batch = 1000 n_attack_blocks = 15000 self.log.info(f"Attacker start to prepare {n_attack_blocks} blocks") fork_point = attacker.generate_empty_blocks(1000)[-1] for _ in range(n_attack_blocks): attacker.generate_block_with_parent(fork_point) self.log.info("Honest node generate") for _ in range(int(20000 / n_generate_batch)): batch_generate(victim, n_generate_batch, self.log) connect_nodes(self.nodes, 0, 1) self.log.info("Nodes connected") for _ in range(1000): batch_generate(victim, n_generate_batch, self.log)
class Issue1303Test(ConfluxTestFramework): def set_test_params(self): self.num_nodes = 1 def setup_network(self): self.add_nodes(self.num_nodes) self.start_node(FULLNODE0, ["--archive"]) # set up RPC client self.rpc = RpcClient(self.nodes[FULLNODE0]) # wait for phase changes to complete self.nodes[FULLNODE0].wait_for_phase(["NormalSyncPhase"]) def run_test(self): # send tx0 to a random account (addr, _) = self.rpc.rand_account() tx0 = self.rpc.new_tx(value=5 * 10 ** 18, receiver=addr, nonce=0) assert_equal(self.rpc.send_tx(tx0, wait_for_receipt=True), tx0.hash_hex()) fork_hash = self.nodes[FULLNODE0].best_block_hash() # send tx1 to a random account (addr, _) = self.rpc.rand_account() tx1 = self.rpc.new_tx(value=5 * 10 ** 18, receiver=addr, nonce=1) assert_equal(self.rpc.send_tx(tx1, wait_for_receipt=True), tx1.hash_hex()) tip0 = self.nodes[FULLNODE0].best_block_hash() # current ledger: # x -- x -- x -- tx0 -- x -- x -- x -- tx1 -- tip0 # check receipts before fork r0 = self.rpc.get_transaction_receipt(tx0.hash_hex()) assert(r0 != None) r1 = self.rpc.get_transaction_receipt(tx1.hash_hex()) assert(r1 != None) r1_original_epoch = int(r1["epochNumber"], 16) # create fork tip1 = self.generate_chain(fork_hash, FORK_LENGTH)[-1] # current ledger: # x -- x -- x -- tx0 -- x -- x -- x -- tx1 -- tip0 # \ # \-- x -- x -- x -- x -- x -- tip1 # check receipts after fork r0 = self.rpc.get_transaction_receipt(tx0.hash_hex()) assert(r0 != None) r1 = self.rpc.get_transaction_receipt(tx1.hash_hex()) assert(r1 == None) # fails before #1303 # connect forks, tx should be re-executed tip = self.rpc.generate_block_with_parent(tip1, referee = [tip0]) # this time, tx1 will be in the epoch of `tip` # we need at least DEFERRED more blocks before it is re-executed tip = self.generate_chain(tip, 5)[-1] # current ledger: # x -- x -- x -- tx0 -- x -- x -- x -- tx1 -- tip0 .................. # \ : # \-- x -- x -- x -- x -- x -- tip1 -- x -- x -- x -- x -- x -- tip # check if updated receipt exists r1 = self.rpc.get_transaction_receipt(tx1.hash_hex()) assert(r1 != None) assert(int(r1["epochNumber"], 16) > r1_original_epoch) self.log.info(f"Pass") def generate_chain(self, parent, len): hashes = [parent] for _ in range(len): hash = self.rpc.generate_block_with_parent(hashes[-1]) hashes.append(hash) return hashes[1:]