def add_transactions_to_blockchain_db(base_db, tx_list: List): # sort by time tx_list.sort(key=lambda x: x[3]) for tx_key in tx_list: sender_priv_key = tx_key[0] receive_priv_key = tx_key[1] amount = tx_key[2] tx_timestamp = int(tx_key[3]) if len(tx_key) > 4: gas_price = to_wei(tx_key[4], 'gwei') else: gas_price = to_wei(1, 'gwei') total_gas = gas_price sender_chain = MainnetChain(base_db, sender_priv_key.public_key.to_canonical_address(), sender_priv_key) dummy_sender_chain = MainnetChain(JournalDB(base_db), sender_priv_key.public_key.to_canonical_address(), sender_priv_key) dummy_sender_chain.create_and_sign_transaction_for_queue_block( gas_price=gas_price, gas=GAS_TX, to=receive_priv_key.public_key.to_canonical_address(), value=amount, data=b"", v=0, r=0, s=0 ) # import the block into the dummy chain to complete it and make sure it is valid imported_block = dummy_sender_chain.import_current_queue_block() # altering block timestamp and importing again timestamp_modified_imported_block = imported_block.copy( header=imported_block.header.copy(timestamp=tx_timestamp).get_signed(sender_priv_key, dummy_sender_chain.network_id)) sender_chain.import_block(timestamp_modified_imported_block, allow_unprocessed=False) # then receive the transactions dummy_receiver_chain = MainnetChain(JournalDB(base_db), receive_priv_key.public_key.to_canonical_address(), receive_priv_key) dummy_receiver_chain.populate_queue_block_with_receive_tx() imported_block = dummy_receiver_chain.import_current_queue_block() # altering block timestamp and importing again timestamp_modified_imported_block = imported_block.copy( header=imported_block.header.copy(timestamp=tx_timestamp).get_signed(receive_priv_key, dummy_receiver_chain.network_id)) # print('XXXXXXXXXX') # print(tx_timestamp) receiver_chain = MainnetChain(base_db, receive_priv_key.public_key.to_canonical_address(), receive_priv_key) receiver_chain.import_block(timestamp_modified_imported_block, allow_unprocessed=False)
def debug_test_1(): testdb = LevelDB("/home/tommy/.local/share/helios/mainnet/chain/full/") testdb = JournalDB(testdb) testdb = ReadOnlyDB(testdb) chain = MainnetChain(testdb, private_keys[0].public_key.to_canonical_address(), private_keys[0]) block = chain.get_block_by_hash( decode_hex( '0x6a8d49885e5f07ea66f722e4ec9ba9630a86f1189257317461196726bee7ea0c' )) new_chain = chain.get_blocks_on_chain( 0, 3, decode_hex('0x1d1a2266a15CcB2e70baeB4b75b2c59Da95498ac')) print('blocks on chain') for cur_block in new_chain: print(encode_hex(cur_block.header.hash)) print() newest_root_hash = chain.chain_head_db.get_historical_root_hashes()[-1][1] chain.chain_head_db.root_hash = newest_root_hash chain_head_hash = chain.chain_head_db.get_chain_head_hash( decode_hex('0x1d1a2266a15CcB2e70baeB4b75b2c59Da95498ac')) print("chain_head_hash {}".format(encode_hex(chain_head_hash))) # # now lets delete all but the first block # print("Deleting all blocks but first") chain = MainnetChain(testdb, private_keys[0].public_key.to_canonical_address(), private_keys[0]) chain.purge_block_and_all_children_and_set_parent_as_chain_head( block.header, save_block_head_hash_timestamp=True) newest_root_hash = chain.chain_head_db.get_historical_root_hashes()[-1][1] chain.chain_head_db.root_hash = newest_root_hash chain_head_hash = chain.chain_head_db.get_chain_head_hash( decode_hex('0x1d1a2266a15CcB2e70baeB4b75b2c59Da95498ac')) print("chain_head_hash {}".format(encode_hex(chain_head_hash))) # # Now lets import the second block again # print("Importing second block") chain.import_block( block, allow_replacement=False, ensure_block_unchanged=True, ) newest_root_hash = chain.chain_head_db.get_historical_root_hashes()[-1][1] chain.chain_head_db.root_hash = newest_root_hash chain_head_hash = chain.chain_head_db.get_chain_head_hash( decode_hex('0x1d1a2266a15CcB2e70baeB4b75b2c59Da95498ac')) print("chain_head_hash {}".format(encode_hex(chain_head_hash)))
def test_break_chronological_consistency_1(): testdb = create_reward_test_blockchain_database() chain = MainnetChain(testdb, private_keys[1].public_key.to_canonical_address(), private_keys[1]) tx_nonce = chain.get_current_queue_block_nonce() tx = chain.create_and_sign_transaction(nonce = tx_nonce, gas_price=to_wei(1, 'gwei'), gas=GAS_TX, to=private_keys[0].public_key.to_canonical_address(), value=1, data=b"", v=0, r=0, s=0 ) new_block_to_import = create_valid_block_at_timestamp(testdb, private_keys[1], transactions=[tx], receive_transactions=None, reward_bundle=None, timestamp=int(time.time()-1)) chain = MainnetChain(testdb, private_keys[0].public_key.to_canonical_address(), private_keys[0]) node_staking_scores = [] score = 100000 for i in range(1, 10): # Second score/proof is from instance 1 current_private_key = private_keys[i] node_staking_score = NodeStakingScore( recipient_node_wallet_address=private_keys[0].public_key.to_canonical_address(), score=int(score-i), since_block_number=0, timestamp=int(time.time()), head_hash_of_sender_chain=chain.chaindb.get_canonical_head_hash( current_private_key.public_key.to_canonical_address()), v=0, r=0, s=0, ) signed_node_staking_score = node_staking_score.get_signed(current_private_key, MAINNET_NETWORK_ID) node_staking_scores.append(signed_node_staking_score) # Now we try to import the reward block with instance 0 reward_chain = MainnetChain(testdb, private_keys[0].public_key.to_canonical_address(), private_keys[0]) reward_block = reward_chain.import_current_queue_block_with_reward(node_staking_scores) print("reward block timestamp {}".format(reward_block.header.timestamp)) for proof in reward_block.reward_bundle.reward_type_2.proof: print(encode_hex(proof.sender)) for i in range(1, 10): if proof.sender == private_keys[i].public_key.to_canonical_address(): print("proof from {}".format(i)) print("new_block_to_import timestamp {}".format(new_block_to_import.header.timestamp)) print("new_block_to_import chain address {}".format(encode_hex(new_block_to_import.header.chain_address))) # Now we import a block on private key 1 with a timestamp set to 10 seconds ago chain = MainnetChain(testdb, private_keys[1].public_key.to_canonical_address(), private_keys[1]) with pytest.raises(ReplacingBlocksNotAllowed): chain.import_block(new_block_to_import, allow_replacement=False) # test_break_chronological_consistency_1() # exit()
def create_dev_fixed_blockchain_database(base_db, key_balance_dict, use_real_genesis = False): logger.debug("generating test fixed blockchain db") earliest_timestamp = int(time.time()) required_total_supply = 0 for balance_timestamp in key_balance_dict.values(): required_total_supply += balance_timestamp[0] if balance_timestamp[1] < earliest_timestamp: earliest_timestamp = balance_timestamp[1] required_total_supply = required_total_supply*2 #initialize db if use_real_genesis: sender_chain = import_genesis_block(base_db) else: genesis_params, genesis_state = create_new_genesis_params_and_state(GENESIS_PRIVATE_KEY, required_total_supply, earliest_timestamp - 100000) sender_chain = MainnetChain.from_genesis(base_db, GENESIS_PRIVATE_KEY.public_key.to_canonical_address(), genesis_params, genesis_state) sender_chain.chaindb.initialize_historical_minimum_gas_price_at_genesis(min_gas_price=1, net_tpc_cap=5) prev_timestamp = 0 for priv_key, balance_timestamp in key_balance_dict.items(): sender_chain = MainnetChain(base_db, GENESIS_PRIVATE_KEY.public_key.to_canonical_address(), GENESIS_PRIVATE_KEY) dummy_sender_chain = MainnetChain(JournalDB(base_db), GENESIS_PRIVATE_KEY.public_key.to_canonical_address(), GENESIS_PRIVATE_KEY) balance = balance_timestamp[0] timestamp = balance_timestamp[1] if timestamp < prev_timestamp: raise ValueError("timestamps must be in ascending order") receiver_privkey = priv_key dummy_sender_chain.create_and_sign_transaction_for_queue_block( gas_price=0x01, gas=0x0c3500, to=receiver_privkey.public_key.to_canonical_address(), value=balance, data=b"", v=0, r=0, s=0 ) # import the block into the dummy chain to complete it and make sure it is valid imported_block = dummy_sender_chain.import_current_queue_block() # altering block timestamp and importing again timestamp_modified_imported_block = imported_block.copy(header = imported_block.header.copy(timestamp = timestamp).get_signed(GENESIS_PRIVATE_KEY,dummy_sender_chain.network_id)) sender_chain.import_block(timestamp_modified_imported_block, allow_unprocessed = False) #logger.debug("Receiving ") #then receive the transactions receiver_chain = MainnetChain(base_db, receiver_privkey.public_key.to_canonical_address(), receiver_privkey) dummy_receiver_chain = MainnetChain(JournalDB(base_db), receiver_privkey.public_key.to_canonical_address(), receiver_privkey) dummy_receiver_chain.populate_queue_block_with_receive_tx() imported_block = dummy_receiver_chain.import_current_queue_block() # altering block timestamp and importing again timestamp_modified_imported_block = imported_block.copy(header=imported_block.header.copy(timestamp=timestamp).get_signed(receiver_privkey, dummy_receiver_chain.network_id)) receiver_chain.import_block(timestamp_modified_imported_block, allow_unprocessed=False) logger.debug("finished creating fixed blockchain")
def create_dev_test_random_blockchain_db_with_reward_blocks(base_db = None, num_iterations = 5): # initialize db if base_db == None: base_db = MemoryDB() create_dev_test_random_blockchain_database(base_db, timestamp = 'genesis') node_1 = MainnetChain(base_db, GENESIS_PRIVATE_KEY.public_key.to_canonical_address(), GENESIS_PRIVATE_KEY) MIN_TIME_BETWEEN_BLOCKS = node_1.get_vm(timestamp = Timestamp(int(time.time()))).min_time_between_blocks chain_head_hashes = node_1.chain_head_db.get_head_block_hashes_list() last_block_timestamp = 0 for head_hash in chain_head_hashes: header = node_1.chaindb.get_block_header_by_hash(head_hash) if header.timestamp > last_block_timestamp: last_block_timestamp = header.timestamp private_keys_dict = {} for random_private_key in random_private_keys: priv_key = keys.PrivateKey(random_private_key) private_keys_dict[priv_key.public_key.to_address()] = priv_key private_keys_dict[GENESIS_PRIVATE_KEY.public_key.to_address()] = GENESIS_PRIVATE_KEY for i in range(num_iterations): # random_int = random.randint(0,len(private_keys_dict)-1) # numbers = [x in range(0, len(private_keys_dict)-1) if x != random_int] # random_int = random.choice(numbers) if i == 0: numbers = [x for x in range(0, len(private_keys_dict) - 1)] random_int = random.choice(numbers) privkey = GENESIS_PRIVATE_KEY receiver_privkey = private_keys_dict[list(private_keys_dict.keys())[random_int]] else: numbers = [x for x in range(0, len(private_keys_dict) - 1) if x != random_int] random_int = random.choice(numbers) privkey = receiver_privkey receiver_privkey = private_keys_dict[list(private_keys_dict.keys())[random_int]] tx_timestamp = last_block_timestamp + MIN_TIME_BETWEEN_BLOCKS+2 tx_list = [[privkey, receiver_privkey, 10000000*10**18-i*100000*10**18-random.randint(0,1000), tx_timestamp]] add_transactions_to_blockchain_db(base_db, tx_list) node_1 = MainnetChain(base_db, privkey.public_key.to_canonical_address(), privkey) chain_head_hashes = node_1.chain_head_db.get_head_block_hashes_list() reward_block_time = tx_timestamp + node_1.get_vm(timestamp = tx_timestamp).consensus_db.min_time_between_reward_blocks+ MIN_TIME_BETWEEN_BLOCKS+2+node_1.get_vm(timestamp = tx_timestamp).consensus_db.coin_mature_time_for_staking # print('BBBBBBB') # print(node_1.get_vm(timestamp=tx_timestamp).state.account_db.get_balance(receiver_privkey.public_key.to_canonical_address())) # print(node_1.chaindb.get_mature_stake(receiver_privkey.public_key.to_canonical_address(), node_1.get_consensus_db(timestamp=tx_timestamp).coin_mature_time_for_staking, reward_block_time)) node_staking_scores = [] for head_hash in chain_head_hashes: address = node_1.chaindb.get_chain_wallet_address_for_block_hash(head_hash) if not (address == privkey.public_key.to_canonical_address()): after_block_number = node_1.chaindb.get_latest_reward_block_number(privkey.public_key.to_canonical_address()) node_staking_score = NodeStakingScore(privkey.public_key.to_canonical_address(), 1, after_block_number, reward_block_time, head_hash, v=0, r=0, s=0) signed_node_staking_score = node_staking_score.get_signed(private_keys_dict[encode_hex(address)], node_1.network_id) node_staking_scores.append(signed_node_staking_score) if len(node_staking_scores) >= node_1.get_consensus_db(timestamp = tx_timestamp).required_number_of_proofs_for_reward_type_2_proof: # print('AAAAAAAAAAAA') # print(len(node_staking_scores)) # print(node_1.get_consensus_db(timestamp = tx_timestamp).required_number_of_proofs_for_reward_type_2_proof) reward_bundle = node_1.get_consensus_db(timestamp=tx_timestamp).create_reward_bundle_for_block(privkey.public_key.to_canonical_address(), node_staking_scores, reward_block_time) valid_block = create_valid_block_at_timestamp(base_db, privkey, reward_bundle = reward_bundle, timestamp = reward_block_time) assert(valid_block.header.timestamp == reward_block_time) node_1.import_block(valid_block) last_block_timestamp = reward_block_time return base_db