def init_senders(self, num_accounts): accounts = [] client = RpcClient(self.nodes[0]) init_balance = int(client.GENESIS_ORIGIN_COIN * 0.9 / num_accounts) assert_greater_than_or_equal( client.GENESIS_ORIGIN_COIN, num_accounts * (init_balance + client.DEFAULT_TX_FEE)) for _ in range(num_accounts): to, priv_key = client.rand_account() tx = client.new_tx(receiver=to, value=init_balance) client.send_tx(tx, True) accounts.append(Account(to, priv_key, init_balance)) # Ensure accounts have stable start nonce client.generate_blocks(10) wait_for_account_stable() for account in accounts: account.nonce = wait_for_initial_nonce_for_privkey( self.nodes[0], account.priv_key) return accounts
def run_test(self): start_p2p_connection(self.nodes) block_gen_thread = BlockGenThread(self.nodes, self.log, interval_base=0.2) block_gen_thread.start() genesis_key = default_config["GENESIS_PRI_KEY"] tx_n = 100 gas_price = 1 shard_balance = [] for s in range(self.n_shard): ''' Send random transactions to this shard s ''' shard_nodes = self.nodes[s * self.shard_size:(s + 1) * self.shard_size] # We can not use genesis accounts in two shards, because they may generate transactions # that are valid in another shard and breaks our assertion about the final shard state. start_sk, _ = ec_random_keys() value = default_config["TOTAL_COIN"] - 21000 tx = create_transaction(pri_key=genesis_key, receiver=priv_to_addr(start_sk), value=value, nonce=0, gas_price=gas_price) shard_nodes[0].p2p.send_protocol_msg( Transactions(transactions=[tx])) balance_map = {start_sk: value} nonce_map = { start_sk: wait_for_initial_nonce_for_privkey(shard_nodes[0], start_sk) } account_n = 10 # Initialize new accounts new_keys = set() for _ in range(account_n): value = max(int(balance_map[start_sk] * random.random()), 21000 * tx_n) receiver_sk, _ = ec_random_keys() new_keys.add(receiver_sk) tx = create_transaction(pri_key=start_sk, receiver=priv_to_addr(receiver_sk), value=value, nonce=nonce_map[start_sk], gas_price=gas_price) shard_nodes[0].p2p.send_protocol_msg( Transactions(transactions=[tx])) balance_map[receiver_sk] = value nonce_map[start_sk] += 1 balance_map[start_sk] -= value + gas_price * 21000 wait_for_account_stable() for key in new_keys: nonce_map[key] = wait_for_initial_nonce_for_privkey( shard_nodes[0], key) for i in range(tx_n): sender_key = random.choice(list(balance_map)) nonce = nonce_map[sender_key] value = 0 receiver_sk = random.choice(list(balance_map)) balance_map[receiver_sk] += value tx = create_transaction(pri_key=sender_key, receiver=priv_to_addr(receiver_sk), value=value, nonce=nonce, gas_price=gas_price) r = random.randint(0, self.shard_size - 1) shard_nodes[r].p2p.send_protocol_msg( Transactions(transactions=[tx])) nonce_map[sender_key] = nonce + 1 balance_map[sender_key] -= value + gas_price * 21000 self.log.info( "New tx %s: %s send value %d to %s, sender balance:%d, receiver balance:%d", encode_hex(tx.hash), eth_utils.encode_hex(priv_to_addr(sender_key))[-4:], value, eth_utils.encode_hex(priv_to_addr(receiver_sk))[-4:], balance_map[sender_key], balance_map[receiver_sk]) self.log.debug("Send Transaction %s to node %d", encode_hex(tx.hash), r) time.sleep(random.random() / 10) for k in balance_map: self.log.info("Check account sk:%s addr:%s", bytes_to_int(k), eth_utils.encode_hex(priv_to_addr(k))) wait_until( lambda: self.check_account(k, balance_map, shard_nodes[0])) shard_balance.append(balance_map) def epochCheck(node): r = node.cfx_epochNumber() return int(r, 0) > 110 wait_until(lambda: epochCheck(self.nodes[0])) wait_until( lambda: epochCheck(self.nodes[int(self.num_nodes / self.n_shard)])) for s in range(self.n_shard): for idx in range(self.shard_size): connect_nodes(self.nodes, s * self.shard_size - 1 + idx, s * self.shard_size + idx) block_gen_thread.stop() block_gen_thread.join() sync_blocks(self.nodes) ''' Check if the balance state of every node matches ''' success_shard = -1 # use the state of node 0 to find the winning shard for s in range(self.n_shard): balance_map = shard_balance[s] unmatch = False for k in balance_map: if not self.check_account(k, balance_map, self.nodes[0]): unmatch = True self.log.info( "Final balance does not match shard %s, check next", s) break if unmatch: continue success_shard = s break assert success_shard != -1, "The final state of node 0 matches no shard state" self.log.info("Shard %s succeeds", success_shard) for i in range(1, self.num_nodes): balance_map = shard_balance[success_shard] for k in balance_map: if not self.check_account(k, balance_map, self.nodes[i]): raise AssertionError( "Final balance of node {} does not match node 0, sender={}" .format(i, k)) self.log.info("Pass")
def run_test(self): genesis_key = default_config["GENESIS_PRI_KEY"] balance_map = {genesis_key: default_config["TOTAL_COIN"]} self.log.info("Initial State: (sk:%d, addr:%s, balance:%d)", bytes_to_int(genesis_key), eth_utils.encode_hex(priv_to_addr(genesis_key)), balance_map[genesis_key]) nonce_map = {genesis_key: 0} # '''Check if transaction from uncommitted new address can be accepted''' # tx_n = 5 # receiver_sk = genesis_key gas_price = 1 # for i in range(tx_n): # sender_key = receiver_sk # value = int((balance_map[sender_key] - ((tx_n - i) * 21000 * gas_price)) * random.random()) # nonce = nonce_map[sender_key] # receiver_sk, _ = ec_random_keys() # nonce_map[receiver_sk] = 0 # balance_map[receiver_sk] = value # tx = create_transaction(pri_key=sender_key, receiver=privtoaddr(receiver_sk), value=value, nonce=nonce, # gas_price=gas_price) # r = random.randint(0, self.num_nodes - 1) # self.nodes[r].p2p.send_protocol_msg(Transactions(transactions=[tx])) # nonce_map[sender_key] = nonce + 1 # balance_map[sender_key] -= value + gas_price * 21000 # self.log.debug("New tx %s: %s send value %d to %s, sender balance:%d, receiver balance:%d", encode_hex(tx.hash), eth_utils.encode_hex(privtoaddr(sender_key))[-4:], # value, eth_utils.encode_hex(privtoaddr(receiver_sk))[-4:], balance_map[sender_key], balance_map[receiver_sk]) # self.log.debug("Send Transaction %s to node %d", encode_hex(tx.hash), r) # time.sleep(random.random() / 10 * self.delay_factor) block_gen_thread = BlockGenThread(self.nodes, self.log, interval_base=self.delay_factor) block_gen_thread.start() # for k in balance_map: # self.log.info("Check account sk:%s addr:%s", bytes_to_int(k), eth_utils.encode_hex(privtoaddr(k))) # wait_until(lambda: self.check_account(k, balance_map), timeout=60*self.delay_factor) # self.log.info("Pass 1") # self.register_test("general_1.json") '''Test Random Transactions''' all_txs = [] tx_n = 1000 account_n = 10 # Initialize new accounts new_keys = set() for _ in range(account_n): value = int(balance_map[genesis_key] * 0.5) receiver_sk, _ = ec_random_keys() new_keys.add(receiver_sk) tx = create_transaction(pri_key=genesis_key, receiver=priv_to_addr(receiver_sk), value=value, nonce=nonce_map[genesis_key], gas_price=gas_price) self.nodes[0].p2p.send_protocol_msg( Transactions(transactions=[tx])) balance_map[receiver_sk] = value nonce_map[genesis_key] += 1 balance_map[genesis_key] -= value + gas_price * 21000 wait_for_account_stable() for key in new_keys: nonce_map[key] = wait_for_initial_nonce_for_privkey( self.nodes[0], key) self.log.info( "start to generate %d transactions with about %d seconds", tx_n, tx_n / 10 / 2 * self.delay_factor) for i in range(tx_n): sender_key = random.choice(list(balance_map)) nonce = nonce_map[sender_key] value = 1 receiver_sk = random.choice(list(balance_map)) balance_map[receiver_sk] += value # not enough transaction fee (gas_price * gas_limit) should not happen for now assert balance_map[sender_key] >= value + gas_price * 21000 tx = create_transaction(pri_key=sender_key, receiver=priv_to_addr(receiver_sk), value=value, nonce=nonce, gas_price=gas_price) r = random.randint(0, self.num_nodes - 1) self.nodes[r].p2p.send_protocol_msg( Transactions(transactions=[tx])) all_txs.append(tx) nonce_map[sender_key] = nonce + 1 balance_map[sender_key] -= value + gas_price * 21000 self.log.debug( "New tx %s: %s send value %d to %s, sender balance:%d, receiver balance:%d nonce:%d", encode_hex(tx.hash), eth_utils.encode_hex(priv_to_addr(sender_key))[-4:], value, eth_utils.encode_hex(priv_to_addr(receiver_sk))[-4:], balance_map[sender_key], balance_map[receiver_sk], nonce) self.log.debug("Send Transaction %s to node %d", encode_hex(tx.hash), r) time.sleep(random.random() / 10 * self.delay_factor) for k in balance_map: self.log.info("Account %s with balance:%s", bytes_to_int(k), balance_map[k]) for tx in all_txs: self.log.debug("Wait for tx to confirm %s", tx.hash_hex()) for i in range(3): try: retry = True while retry: try: wait_until( lambda: checktx(self.nodes[0], tx.hash_hex()), timeout=60 * self.delay_factor) retry = False except CannotSendRequest: time.sleep(0.01) break except AssertionError as _: self.nodes[0].p2p.send_protocol_msg( Transactions(transactions=[tx])) if i == 2: raise AssertionError( "Tx {} not confirmed after 30 seconds".format( tx.hash_hex())) for k in balance_map: self.log.info("Check account sk:%s addr:%s", bytes_to_int(k), eth_utils.encode_hex(priv_to_addr(k))) wait_until(lambda: self.check_account(k, balance_map), timeout=60 * self.delay_factor) block_gen_thread.stop() block_gen_thread.join() sync_blocks(self.nodes, timeout=60 * self.delay_factor) self.log.info("Pass") self.register_test("general_2.json")
def run_test(self): genesis_key = default_config["GENESIS_PRI_KEY"] balance_map = {genesis_key: default_config["TOTAL_COIN"]} self.log.info("Initial State: (sk:%d, addr:%s, balance:%d)", bytes_to_int(genesis_key), eth_utils.encode_hex(priv_to_addr(genesis_key)), balance_map[genesis_key]) nonce_map = {genesis_key: 0} block_gen_thread = BlockGenThread(self.nodes, self.log, interval_base=0.2) block_gen_thread.start() '''Check if transaction from uncommitted new address can be accepted''' tx_n = 5 new_keys = set() gas_price = 1 for i in range(tx_n): sender_key = genesis_key receiver_sk, _ = ec_random_keys() new_keys.add(receiver_sk) value = int((balance_map[sender_key] - ((tx_n - i) * 21000 * gas_price)) * random.random()) balance_map[receiver_sk] = value nonce = nonce_map[sender_key] receiver_addr = priv_to_addr(receiver_sk) tx = create_transaction(pri_key=sender_key, receiver=receiver_addr, value=value, nonce=nonce, gas_price=gas_price) r = random.randint(0, self.num_nodes - 1) r = 0 self.nodes[r].p2p.send_protocol_msg(Transactions(transactions=[tx])) nonce_map[sender_key] = nonce + 1 balance_map[sender_key] -= value + gas_price * 21000 self.log.debug("New tx %s: %s send value %d to %s, sender balance:%d, receiver balance:%d", encode_hex(tx.hash), eth_utils.encode_hex(priv_to_addr(sender_key))[-4:], value, eth_utils.encode_hex(priv_to_addr(receiver_sk))[-4:], balance_map[sender_key], balance_map[receiver_sk]) self.log.debug("Send Transaction %s to node %d", encode_hex(tx.hash), r) for k in balance_map: self.log.info("Check account sk:%s addr:%s", bytes_to_int(k), eth_utils.encode_hex(priv_to_addr(k))) wait_until(lambda: self.check_account(k, balance_map)) self.log.info("Pass 1") '''Test Random Transactions''' wait_for_account_stable() for key in new_keys: nonce_map[key] = wait_for_initial_nonce_for_privkey(self.nodes[0], key) all_txs = [] tx_n = 1000 self.log.info("start to generate %d transactions with about %d seconds", tx_n, tx_n/100/2) for i in range(tx_n): sender_key = random.choice(list(balance_map)) nonce = nonce_map[sender_key] data = b'' rand_n = random.random() gas = 21000 storage_limit = 0 if rand_n > 0.9 and balance_map[sender_key] > 21000 * 4 * tx_n: value = 0 receiver = b'' data = bytes([96, 128, 96, 64, 82, 52, 128, 21, 97, 0, 16, 87, 96, 0, 128, 253, 91, 80, 96, 5, 96, 0, 129, 144, 85, 80, 96, 230, 128, 97, 0, 39, 96, 0, 57, 96, 0, 243, 254, 96, 128, 96, 64, 82, 96, 4, 54, 16, 96, 67, 87, 96, 0, 53, 124, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 4, 128, 99, 96, 254, 71, 177, 20, 96, 72, 87, 128, 99, 109, 76, 230, 60, 20, 96, 127, 87, 91, 96, 0, 128, 253, 91, 52, 128, 21, 96, 83, 87, 96, 0, 128, 253, 91, 80, 96, 125, 96, 4, 128, 54, 3, 96, 32, 129, 16, 21, 96, 104, 87, 96, 0, 128, 253, 91, 129, 1, 144, 128, 128, 53, 144, 96, 32, 1, 144, 146, 145, 144, 80, 80, 80, 96, 167, 86, 91, 0, 91, 52, 128, 21, 96, 138, 87, 96, 0, 128, 253, 91, 80, 96, 145, 96, 177, 86, 91, 96, 64, 81, 128, 130, 129, 82, 96, 32, 1, 145, 80, 80, 96, 64, 81, 128, 145, 3, 144, 243, 91, 128, 96, 0, 129, 144, 85, 80, 80, 86, 91, 96, 0, 128, 84, 144, 80, 144, 86, 254, 161, 101, 98, 122, 122, 114, 48, 88, 32, 181, 24, 13, 149, 253, 195, 129, 48, 40, 237, 71, 246, 44, 124, 223, 112, 139, 118, 192, 219, 9, 64, 67, 245, 51, 180, 42, 67, 13, 49, 62, 21, 0, 41]) gas = CONTRACT_DEFAULT_GAS is_payment = False storage_limit = 200000 else: value = 1 receiver_sk = random.choice(list(balance_map)) receiver = priv_to_addr(receiver_sk) balance_map[receiver_sk] += value is_payment = True # not enough transaction fee (gas_price * gas_limit) should not happen for now assert balance_map[sender_key] >= value + gas_price * 21000 tx = create_transaction(pri_key=sender_key, receiver=receiver, value=value, nonce=nonce, gas_price=gas_price, data=data, gas=gas, storage_limit=storage_limit) r = random.randint(0, self.num_nodes - 1) r = 0 self.nodes[r].p2p.send_protocol_msg(Transactions(transactions=[tx])) all_txs.append(tx) nonce_map[sender_key] = nonce + 1 if is_payment: balance_map[sender_key] -= value + gas_price * gas else: balance_map[sender_key] -= value + gas_price * charged_of_huge_gas(gas) self.log.debug("Send Transaction %s to node %d", encode_hex(tx.hash), r) time.sleep(random.random() / 100) for k in balance_map: self.log.info("Account %s with balance:%s", bytes_to_int(k), balance_map[k]) for tx in all_txs: self.log.debug("Wait for tx to confirm %s", tx.hash_hex()) for i in range(3): try: retry = True while retry: try: wait_until(lambda: checktx(self.nodes[0], tx.hash_hex()), timeout=120) retry = False except CannotSendRequest: time.sleep(0.01) break except AssertionError as _: self.nodes[0].p2p.send_protocol_msg(Transactions(transactions=[tx])) if i == 2: raise AssertionError("Tx {} not confirmed after 30 seconds".format(tx.hash_hex())) for k in balance_map: self.log.info("Check account sk:%s addr:%s", bytes_to_int(k), eth_utils.encode_hex(priv_to_addr(k))) wait_until(lambda: self.check_account(k, balance_map)) block_gen_thread.stop() block_gen_thread.join() sync_blocks(self.nodes) self.log.info("Pass")
def run_test(self): # Start mininode connection self.node = self.nodes[0] start_p2p_connection([self.node]) block_gen_thread = BlockGenThread([self.node], self.log, num_txs=10000, interval_fixed=0.2) block_gen_thread.start() tx_n = 100000 generate = False if generate: f = open("encoded_tx", "wb") '''Test Random Transactions''' genesis_key = default_config["GENESIS_PRI_KEY"] balance_map = {genesis_key: default_config["TOTAL_COIN"]} nonce_map = {genesis_key: 0} all_txs = [] gas_price = 1 account_n = 10 # Initialize new accounts new_keys = set() for _ in range(account_n): value = int(balance_map[genesis_key] * 0.5) receiver_sk, _ = ec_random_keys() new_keys.add(receiver_sk) tx = create_transaction(pri_key=genesis_key, receiver=priv_to_addr(receiver_sk), value=value, nonce=nonce_map[genesis_key], gas_price=gas_price) all_txs.append(tx) balance_map[receiver_sk] = value nonce_map[genesis_key] += 1 balance_map[genesis_key] -= value + gas_price * 21000 wait_for_account_stable() for key in new_keys: nonce_map[key] = wait_for_initial_nonce_for_privkey( self.nodes[0], key) self.log.info("start to generate %d transactions", tx_n) for i in range(tx_n): if i % 1000 == 0: self.log.debug("generated %d tx", i) sender_key = random.choice(list(balance_map)) if sender_key not in nonce_map: nonce_map[sender_key] = wait_for_initial_nonce_for_privkey( self.nodes[0], sender_key) nonce = nonce_map[sender_key] value = 1 receiver_sk = random.choice(list(balance_map)) balance_map[receiver_sk] += value # not enough transaction fee (gas_price * gas_limit) should not happen for now assert balance_map[sender_key] >= value + gas_price * 21000 tx = create_transaction(pri_key=sender_key, receiver=priv_to_addr(receiver_sk), value=value, nonce=nonce, gas_price=gas_price) self.log.debug( "%s send %d to %s nonce=%d balance: sender=%s, receiver=%s", encode_hex(priv_to_addr(sender_key)), value, encode_hex(priv_to_addr(receiver_sk)), nonce, balance_map[sender_key], balance_map[receiver_sk]) all_txs.append(tx) nonce_map[sender_key] = nonce + 1 balance_map[sender_key] -= value + gas_price * 21000 encoded_txs = [] batch_tx = [] i = 0 for tx in all_txs: batch_tx.append(tx) i += 1 if i % 1000 == 0: encoded = rlp.encode(Transactions(transactions=batch_tx)) encoded_txs.append(encoded) batch_tx = [] pickle.dump(encoded_txs, f) pickle.dump(balance_map, f) else: f = open("encoded_tx", "rb") encoded_txs = pickle.load(f) balance_map = pickle.load(f) f.close() start_time = datetime.datetime.now() for encoded in encoded_txs: self.node.p2p.send_protocol_packet( int_to_bytes(TRANSACTIONS) + encoded) for k in balance_map: wait_until(lambda: self.check_account(k, balance_map)) end_time = datetime.datetime.now() time_used = (end_time - start_time).total_seconds() block_gen_thread.stop() block_gen_thread.join() self.log.info("Time used: %f seconds", time_used) self.log.info("Tx per second: %f", tx_n / time_used)