def initialize_database(chain_config: ChainConfig,
                        chaindb: AsyncChainDB) -> None:
    try:
        chaindb.get_canonical_head(chain_address=GENESIS_WALLET_ADDRESS)
    except CanonicalHeadNotFound:
        if chain_config.network_id == MAINNET_NETWORK_ID:
            MainnetChain.from_genesis(chaindb.db,
                                      chain_config.node_wallet_address,
                                      MAINNET_GENESIS_PARAMS,
                                      MAINNET_GENESIS_STATE)
        else:
            # TODO: add genesis data to ChainConfig and if it's present, use it
            # here to initialize the chain.
            raise NotImplementedError(
                "Only the mainnet and ropsten chains are currently supported")
Beispiel #2
0
def create_block_params():
    from hvm.chains.mainnet import (
        MAINNET_TPC_CAP_TEST_GENESIS_PARAMS,
        MAINNET_TPC_CAP_TEST_GENESIS_STATE,
        TPC_CAP_TEST_GENESIS_PRIVATE_KEY,
    )

    db = MemoryDB()
    chain = MainnetChain.from_genesis(
        db,
        TPC_CAP_TEST_GENESIS_PRIVATE_KEY.public_key.to_canonical_address(),
        MAINNET_TPC_CAP_TEST_GENESIS_PARAMS,
        MAINNET_TPC_CAP_TEST_GENESIS_STATE,
        private_key=TPC_CAP_TEST_GENESIS_PRIVATE_KEY)

    receiver_privkey = keys.PrivateKey(random_private_keys[0])

    chain.create_and_sign_transaction_for_queue_block(
        gas_price=0x01,
        gas=0x0c3500,
        to=receiver_privkey.public_key.to_canonical_address(),
        value=1000,
        data=b"",
        v=0,
        r=0,
        s=0)

    imported_block = chain.import_current_queue_block()

    block_dict = imported_block.to_dict()
    print(block_dict)


# create_block_params()
# sys.exit()
def create_dev_test_blockchain_database_with_given_transactions(base_db, tx_list: List, use_real_genesis = False):

    # sort by time
    tx_list.sort(key=lambda x: x[3])

    genesis_chain_stake = 100000000000000000

    total_required_gas = sum([(to_wei(tx_key[4], 'gwei') if len(tx_key) > 4 else to_wei(1, 'gwei'))*GAS_TX for tx_key in tx_list])

    earliest_timestamp = tx_list[0][3]
    required_total_supply = sum([x[2] for x in tx_list if x[0] == GENESIS_PRIVATE_KEY])+genesis_chain_stake+total_required_gas

    if use_real_genesis:
        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)

        # import genesis block
        MainnetChain.from_genesis(base_db, GENESIS_PRIVATE_KEY.public_key.to_canonical_address(), genesis_params, genesis_state)

    add_transactions_to_blockchain_db(base_db, tx_list)
def test_boson_vm_calculate_node_staking_score():
    from hvm.vm.forks.boson.consensus import TIME_BETWEEN_PEER_NODE_HEALTH_CHECK

    testdb = MemoryDB()
    sender_chain = MainnetChain.from_genesis(
        testdb, SENDER.public_key.to_canonical_address(),
        MAINNET_GENESIS_PARAMS, MAINNET_GENESIS_STATE)

    boson_fork_timestamp = 0
    for timestamp_vm_config in MainnetChain.vm_configuration:
        if timestamp_vm_config[1].fork == 'boson':
            boson_fork_timestamp = timestamp_vm_config[0]

    boson_vm = sender_chain.get_vm(timestamp=boson_fork_timestamp)

    consensus_db = boson_vm.consensus_db

    #
    # score vs latency
    #
    latency = []
    staking_score = []
    for current_latency in range(1000, 1000000, 100000):
        current_staking_score = consensus_db.calculate_node_staking_score(
            average_response_time=current_latency,
            failed_requests=0,
            requests_sent=100,
            time_since_last_reward=TIME_BETWEEN_PEER_NODE_HEALTH_CHECK * 100)
        latency.append(current_latency / 1000)
        staking_score.append(current_staking_score / 10000)

    print(staking_score)
    print(latency)

    plt.plot(latency, staking_score)
    plt.xlabel('Latency (ms)')
    plt.ylabel('Percentage of max stake')

    plt.savefig('plots/staking_score_vs_latency.png', bbox_inches='tight')
    plt.clf()

    #
    # score vs failed requests
    #
    failed_requests = []
    staking_score = []
    for current_failed_requests in range(0, 100, 5):
        current_staking_score = consensus_db.calculate_node_staking_score(
            average_response_time=100000,
            failed_requests=current_failed_requests,
            requests_sent=100,
            time_since_last_reward=TIME_BETWEEN_PEER_NODE_HEALTH_CHECK * 100)
        failed_requests.append(current_failed_requests)
        staking_score.append(current_staking_score / 10000)

    print(failed_requests)
    print(staking_score)

    plt.plot(failed_requests, staking_score)
    plt.xlabel('Failed requests (% of requests sent)')
    plt.ylabel('Percentage of max stake')

    plt.savefig('plots/staking_score_vs_failed_requests.png',
                bbox_inches='tight')
    plt.clf()

    #
    # score vs percentage of uptime
    #
    percentage_of_uptime = []
    staking_score = []
    start = TIME_BETWEEN_PEER_NODE_HEALTH_CHECK * 10
    for current_time_since_last_reward in range(start, start + start * 100,
                                                start):
        current_staking_score = consensus_db.calculate_node_staking_score(
            average_response_time=100000,
            failed_requests=0,
            requests_sent=10,
            time_since_last_reward=current_time_since_last_reward)
        percentage_of_uptime.append(start / current_time_since_last_reward)
        staking_score.append(current_staking_score / 10000)

    print(percentage_of_uptime)
    print(staking_score)

    plt.plot(percentage_of_uptime, staking_score)
    plt.xlabel('Percentage of uptime')
    plt.ylabel('Percentage of max stake')

    plt.savefig('plots/staking_score_vs_time_since_last_reward.png',
                bbox_inches='tight')
    plt.clf()
def test_boson_vm_calculate_reward_based_on_fractional_interest():
    testdb = MemoryDB()

    masternode_level_3_required_balance = MASTERNODE_LEVEL_3_REQUIRED_BALANCE
    masternode_level_3_multiplier = MASTERNODE_LEVEL_3_REWARD_TYPE_2_MULTIPLIER
    masternode_level_2_required_balance = MASTERNODE_LEVEL_2_REQUIRED_BALANCE
    masternode_level_2_multiplier = MASTERNODE_LEVEL_2_REWARD_TYPE_2_MULTIPLIER
    masternode_level_1_required_balance = MASTERNODE_LEVEL_1_REQUIRED_BALANCE
    masternode_level_1_multiplier = MASTERNODE_LEVEL_1_REWARD_TYPE_2_MULTIPLIER

    genesis_block_time = int(time.time()) - 10000000
    genesis_params, genesis_state = create_new_genesis_params_and_state(
        GENESIS_PRIVATE_KEY, masternode_level_3_required_balance * 2,
        genesis_block_time)

    time_between_blocks = max(MIN_TIME_BETWEEN_BLOCKS, 1)
    # import genesis block
    MainnetChain.from_genesis(
        testdb, GENESIS_PRIVATE_KEY.public_key.to_canonical_address(),
        genesis_params, genesis_state)

    stake_start = genesis_block_time + time_between_blocks
    tx_list = [[
        GENESIS_PRIVATE_KEY, RECEIVER, masternode_level_3_required_balance,
        stake_start
    ],
               [
                   RECEIVER, RECEIVER2,
                   (masternode_level_3_required_balance -
                    masternode_level_2_required_balance - GAS_TX),
                   stake_start + 100000
               ],
               [
                   RECEIVER, RECEIVER2,
                   (masternode_level_2_required_balance -
                    masternode_level_1_required_balance - GAS_TX),
                   stake_start + 200000
               ],
               [
                   RECEIVER, RECEIVER2,
                   (masternode_level_1_required_balance - 1000000 - GAS_TX),
                   stake_start + 300000
               ]]

    add_transactions_to_blockchain_db(testdb, tx_list)

    receiver_chain = MainnetChain(testdb,
                                  RECEIVER.public_key.to_canonical_address(),
                                  RECEIVER)

    fractional_interest = REWARD_TYPE_2_AMOUNT_FACTOR

    boson_fork_timestamp = 0
    for timestamp_vm_config in MainnetChain.vm_configuration:
        if timestamp_vm_config[1].fork == 'boson':
            boson_fork_timestamp = timestamp_vm_config[0]

    boson_vm = receiver_chain.get_vm(timestamp=boson_fork_timestamp)

    consensus_db = boson_vm.consensus_db

    calculate_at_timestamp = int(time.time())
    reward = consensus_db.calculate_reward_based_on_fractional_interest(
        RECEIVER.public_key.to_canonical_address(), fractional_interest,
        calculate_at_timestamp)

    if calculate_at_timestamp < EARLY_BIRD_BONUS_CUTOFF_TIMESTAMP:
        early_bird_bonus = EARLY_BIRD_BONUS_FACTOR
    else:
        early_bird_bonus = 1
    expected_reward_part_1 = fractional_interest * early_bird_bonus * (
        masternode_level_3_required_balance * 100000 *
        masternode_level_3_multiplier)
    expected_reward_part_2 = fractional_interest * early_bird_bonus * (
        masternode_level_2_required_balance * 100000 *
        masternode_level_2_multiplier)
    expected_reward_part_3 = fractional_interest * early_bird_bonus * (
        masternode_level_1_required_balance * 100000 *
        masternode_level_1_multiplier)
    expected_reward_part_4 = fractional_interest * early_bird_bonus * (
        1000000) * (calculate_at_timestamp - (stake_start + 300000) -
                    consensus_db.coin_mature_time_for_staking)

    # print("Expected calculation = {} * {} * {} * {}".format((calculate_at_timestamp-(stake_start+300000)-COIN_MATURE_TIME_FOR_STAKING), 1000000, fractional_interest, 1))
    # print("Expected calculation = {} * {} * {} * {}".format(100000, masternode_level_1_required_balance, fractional_interest, masternode_level_1_multiplier))
    # print("Expected calculation = {} * {} * {} * {}".format(100000, masternode_level_2_required_balance, fractional_interest, masternode_level_2_multiplier))
    # print("Expected calculation = {} * {} * {} * {}".format(100000, masternode_level_3_required_balance, fractional_interest, masternode_level_3_multiplier))
    #
    # print("Expected reward {}".format(int(expected_reward_part_4)))
    # print("Expected reward {}".format(int(expected_reward_part_4)+int(expected_reward_part_3)))
    # print("Expected reward {}".format(int(expected_reward_part_4)+int(expected_reward_part_3)+int(expected_reward_part_2)))
    # print("Expected reward {}".format(int(expected_reward_part_4)+int(expected_reward_part_3)+int(expected_reward_part_2)+int(expected_reward_part_1)))

    expected_reward = int(expected_reward_part_1) + int(
        expected_reward_part_2) + int(expected_reward_part_3) + int(
            expected_reward_part_4)
    assert (reward == expected_reward)
def import_genesis_block(base_db):
   
    logger.debug("importing genesis block")
        
    #initialize db
    return MainnetChain.from_genesis(base_db, GENESIS_PRIVATE_KEY.public_key.to_canonical_address(), MAINNET_GENESIS_PARAMS, MAINNET_GENESIS_STATE)
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")
async def _build_test_consensus(
        request,
        event_loop,
        genesis_block_timestamp=int(time.time() / 1000) * 1000 - 1000 * 1000 +
    1000,
        gap_between_genesis_block_and_first_transaction=1000,
        diverging_transactions_timestamp=None):
    '''
    This one creates a swarm of 4 nodes with one database, and 4 nodes with another database, then asks
    consensus which ones to choose. It checks to make sure they choose the correct one.
    The bootnode, and the first half of the peers have the same blockchain database
    The second half of the peers have a conflicting database
    Then finally, the client has only the genesis block and is asked to choose which database is in consensus.
    The first half of the peers have much more stake then the second half, so the client should choose the blockchain
    database from the first half of the nodes, which is also the one the bootnode has.
    :param request:
    :param event_loop:
    :return:
    '''

    num_peers_in_swarm = 8

    # If this is less than TIME_BETWEEN_HEAD_HASH_SAVE, it will result in FAST SYNC MODE because even the first
    # chronological block hash will be different.
    #gap_between_genesis_block_and_first_transaction = 1000

    base_db = MemoryDB()

    #genesis_block_timestamp = int(time.time()/1000)*1000 - 1000*1000 + 1000
    #genesis_block_timestamp = 1547288000

    private_keys = []
    for i in range(len(random_private_keys)):
        private_keys.append(keys.PrivateKey(random_private_keys[i]))

    if gap_between_genesis_block_and_first_transaction < MIN_TIME_BETWEEN_BLOCKS:
        gap_between_genesis_block_and_first_transaction = MIN_TIME_BETWEEN_BLOCKS

    tx_list = [
        *[[
            GENESIS_PRIVATE_KEY, private_keys[i],
            ((1000000 - 1000 * i) * 10**18), genesis_block_timestamp +
            gap_between_genesis_block_and_first_transaction +
            MIN_TIME_BETWEEN_BLOCKS * i
        ] for i in range(len(random_private_keys))]
    ]

    total_required_gas = sum([
        (to_wei(tx_key[4], 'gwei') if len(tx_key) > 4 else to_wei(1, 'gwei')) *
        GAS_TX for tx_key in tx_list
    ])

    genesis_chain_stake = 100

    required_total_supply = sum([
        x[2] for x in tx_list if x[0] == GENESIS_PRIVATE_KEY
    ]) + genesis_chain_stake + total_required_gas

    genesis_params, genesis_state = create_new_genesis_params_and_state(
        GENESIS_PRIVATE_KEY, required_total_supply, genesis_block_timestamp)

    # import genesis block
    MainnetChain.from_genesis(
        base_db, GENESIS_PRIVATE_KEY.public_key.to_canonical_address(),
        genesis_params, genesis_state)

    # Client db has only the genesis block
    client_db = MemoryDB(base_db.kv_store.copy())

    add_transactions_to_blockchain_db(base_db, tx_list)

    # chain = MainnetChain(base_db, GENESIS_PRIVATE_KEY.public_key.to_canonical_address(), GENESIS_PRIVATE_KEY)
    # print('AAAAAAAAAAA')
    # print('genesis')
    # print(chain.get_vm().state.account_db.get_balance(GENESIS_PRIVATE_KEY.public_key.to_canonical_address()))
    # for i in range(len(random_private_keys)):
    #     print(i)
    #     print(chain.get_vm().state.account_db.get_balance(private_keys[i].public_key.to_canonical_address()))
    # exit()
    # stake for the first half of chains should be from node 1 to node n:
    # 100
    # 1000000
    # 999000
    # 998000
    # 997000
    # 996000
    # 995000
    # 994000
    # 993000
    # 992000

    peer_dbs = []
    for i in range(int(num_peers_in_swarm / 2)):
        peer_dbs.append(MemoryDB(base_db.kv_store.copy()))

    #last_block_timestamp = tx_list[-1][-1]
    # additional_tx_list_for_competing_db = [
    #     [private_keys[4], private_keys[1], 100, last_block_timestamp + TIME_BETWEEN_HEAD_HASH_SAVE + MIN_TIME_BETWEEN_BLOCKS * 1],
    #     [private_keys[4], private_keys[2], 100, last_block_timestamp + TIME_BETWEEN_HEAD_HASH_SAVE + MIN_TIME_BETWEEN_BLOCKS * 2],
    #     [private_keys[4], private_keys[3], 100, last_block_timestamp + TIME_BETWEEN_HEAD_HASH_SAVE + MIN_TIME_BETWEEN_BLOCKS * 3],
    # ]

    if diverging_transactions_timestamp is None:
        diverging_transactions_timestamp = tx_list[-1][
            -1] + TIME_BETWEEN_HEAD_HASH_SAVE

    additional_tx_list_for_competing_db = [
        [
            private_keys[4], private_keys[1], 100,
            diverging_transactions_timestamp + MIN_TIME_BETWEEN_BLOCKS * 0
        ],
        [
            private_keys[4], private_keys[2], 100,
            diverging_transactions_timestamp + MIN_TIME_BETWEEN_BLOCKS * 1
        ],
        [
            private_keys[4], private_keys[3], 100,
            diverging_transactions_timestamp + MIN_TIME_BETWEEN_BLOCKS * 2
        ],
    ]
    competing_base_db = MemoryDB(base_db.kv_store.copy())
    add_transactions_to_blockchain_db(competing_base_db,
                                      additional_tx_list_for_competing_db)

    # stake for the second half of chains should be from node 1 to node n:
    # 100
    # 1000000
    # 999100
    # 998100
    # 997100
    # 932700
    # 995000
    # 994000
    # 993000
    # 992000

    # for peer node 7 for root hash 1
    # 100 + 997100 + 996100 + 995100 + 930700

    for i in range(int(num_peers_in_swarm / 2), num_peers_in_swarm):
        peer_dbs.append(MemoryDB(competing_base_db.kv_store.copy()))

    bootstrap_node = MainnetChain(
        base_db, GENESIS_PRIVATE_KEY.public_key.to_canonical_address())
    bootstrap_node.chaindb.initialize_historical_minimum_gas_price_at_genesis(
        min_gas_price=1, net_tpc_cap=100, tpc=1)
    consensus_root_hash_timestamps = bootstrap_node.chain_head_db.get_historical_root_hashes(
    )

    async def validation(consensus_services):
        for i in range(len(consensus_services)):
            client_consensus = consensus_services[i]
            for timestamp, root_hash in consensus_root_hash_timestamps:
                client_consensus_choice = await client_consensus.coro_get_root_hash_consensus(
                    timestamp)
                assert (client_consensus_choice == root_hash)

            #consensus_service 0 is bootnode, it is in consensus
            #consensus_service 1 is the client. It only has genesis block and is not in consensus
            #consensus_services 2 to 2+int(num_peers_in_swarm/2) are in consensus
            #the rest of the peers are not in consensus
            await client_consensus.get_blockchain_sync_parameters()
            if i in [0, *[j + 2 for j in range(int(num_peers_in_swarm / 2))]]:
                sync_parameters = await client_consensus.get_blockchain_sync_parameters(
                )
                assert sync_parameters == None
            if i == 1:
                sync_parameters = await client_consensus.get_blockchain_sync_parameters(
                    debug=True)
                if (
                        genesis_block_timestamp +
                        gap_between_genesis_block_and_first_transaction
                ) < int(
                        time.time() / 1000
                ) * 1000 - 1000 * 1000 + 4 * 1000 or gap_between_genesis_block_and_first_transaction < TIME_BETWEEN_HEAD_HASH_SAVE:
                    assert sync_parameters.timestamp_for_root_hash == int(
                        (time.time() - TIME_OFFSET_TO_FAST_SYNC_TO) /
                        1000) * 1000
                else:
                    assert sync_parameters.timestamp_for_root_hash == int(
                        (genesis_block_timestamp +
                         gap_between_genesis_block_and_first_transaction) /
                        1000) * 1000 + 1000
            if i in [
                    j + 2 for j in range(int(num_peers_in_swarm /
                                             2), num_peers_in_swarm)
            ]:
                timestamp = int(
                    diverging_transactions_timestamp / 1000) * 1000 + 1000
                sync_parameters = await client_consensus.get_blockchain_sync_parameters(
                    debug=True)
                if timestamp > int(time.time()) - 1000 * 1000 + 1000 * 4:
                    assert sync_parameters.timestamp_for_root_hash == timestamp
                else:
                    assert sync_parameters.timestamp_for_root_hash == int(
                        (time.time() - TIME_OFFSET_TO_FAST_SYNC_TO) /
                        1000) * 1000

    await _test_consensus_swarm(request, event_loop, base_db, client_db,
                                peer_dbs, validation)
def test_get_receipts():
    testdb2 = MemoryDB()

    MainnetChain.from_genesis(
        testdb2, GENESIS_PRIVATE_KEY.public_key.to_canonical_address(),
        MAINNET_GENESIS_PARAMS, MAINNET_GENESIS_STATE)
    """
    Create some receive transactions for RECEIVER
    """
    sender_chain = MainnetChain(testdb2,
                                SENDER.public_key.to_canonical_address(),
                                SENDER)

    min_time_between_blocks = sender_chain.get_vm(
        timestamp=Timestamp(int(time.time()))).min_time_between_blocks
    for i in range(6):
        sender_chain.create_and_sign_transaction_for_queue_block(
            gas_price=i + 1,
            gas=0x0c3500,
            to=RECEIVER.public_key.to_canonical_address(),
            value=i + 100000000000,
            data=b"",
            v=0,
            r=0,
            s=0)

    sender_chain.import_current_queue_block()
    receiver_chain = MainnetChain(testdb2,
                                  RECEIVER.public_key.to_canonical_address(),
                                  RECEIVER)
    receiver_chain.populate_queue_block_with_receive_tx()
    imported_block_1 = receiver_chain.import_current_queue_block()
    """
    Create some send transactions for RECEIVER
    """
    receiver_chain = MainnetChain(testdb2,
                                  RECEIVER.public_key.to_canonical_address(),
                                  RECEIVER)
    for i in range(6):
        receiver_chain.create_and_sign_transaction_for_queue_block(
            gas_price=i + 1,
            gas=0x0c3500,
            to=SENDER.public_key.to_canonical_address(),
            value=i,
            data=b"",
            v=0,
            r=0,
            s=0)
    """
    Create a transaction with data in it.
    """
    compiled_sol = load_compiled_sol_dict('contract_data/erc20_compiled.pkl')

    contract_interface = compiled_sol['contract_data/erc20.sol:SimpleToken']

    w3 = Web3()

    SimpleToken = w3.eth.contract(abi=contract_interface['abi'],
                                  bytecode=contract_interface['bin'])

    # Build transaction to deploy the contract
    w3_tx1 = SimpleToken.constructor().buildTransaction(W3_TX_DEFAULTS)

    from hvm.constants import CREATE_CONTRACT_ADDRESS

    receiver_chain.create_and_sign_transaction_for_queue_block(
        gas_price=0x01,
        gas=1375666,
        to=CREATE_CONTRACT_ADDRESS,
        value=0,
        data=decode_hex(w3_tx1['data']),
        v=0,
        r=0,
        s=0)

    receiver_chain.populate_queue_block_with_receive_tx()

    print("waiting {} seconds before importing next block".format(
        min_time_between_blocks))
    time.sleep(min_time_between_blocks)
    imported_block = receiver_chain.import_current_queue_block()

    for i in range(7):
        if i < 6:
            receipt = sender_chain.chaindb.get_transaction_receipt(
                imported_block.transactions[i].hash)
            assert (receipt.status_code == b'\x01')
            assert (receipt.gas_used == GAS_TX)
            assert (receipt.bloom == 0)
            assert (receipt.logs == ())
        if i == 6:
            receipt = sender_chain.chaindb.get_transaction_receipt(
                imported_block.transactions[i].hash)
            assert (receipt.status_code == b'\x01')
            assert (receipt.gas_used == 1375666)
            assert (
                receipt.bloom ==
                243379359099696592952569079439667912256345493617967967903663341910531480774353059570732838085077727505416158987674861080353852392619637689071728561054211502067278701792094127192831079015338935810676425927305370163403783027301927515372719270157454901551766020292792184739669125690737609931485501648741152187826071626833444578979111366057983284511641401113379885201162016756050289195516614302086913696386892161910800529278878068496138240
            )
            assert (len(receipt.logs) == 1)

    for i in range(6):
        receipt = sender_chain.chaindb.get_transaction_receipt(
            imported_block_1.receive_transactions[i].hash)
        assert (receipt.status_code == b'\x01')
        assert (receipt.gas_used == 0)
        assert (receipt.bloom == 0)
        assert (receipt.logs == ())


# test_get_receipts()
Beispiel #10
0
def _test_airdrop_calling_erc_20():

    # testdb = LevelDB('/home/tommy/.local/share/helios/instance_test/mainnet/chain/full/')
    # testdb = JournalDB(testdb)
    testdb = MemoryDB()
    chain = MainnetChain(testdb,
                         GENESIS_PRIVATE_KEY.public_key.to_canonical_address(),
                         GENESIS_PRIVATE_KEY)
    coin_mature_time = chain.get_vm(timestamp=Timestamp(int(
        time.time()))).consensus_db.coin_mature_time_for_staking

    genesis_params, genesis_state = create_new_genesis_params_and_state(
        GENESIS_PRIVATE_KEY, 1000000 * 10**18,
        int(time.time()) - coin_mature_time * 10000)

    # import genesis block
    chain = MainnetChain.from_genesis(
        testdb, GENESIS_PRIVATE_KEY.public_key.to_canonical_address(),
        genesis_params, genesis_state, GENESIS_PRIVATE_KEY)

    #
    # erc20 contract deploy
    #

    compiled_erc20_sol = load_compiled_sol_dict(
        'contract_data/erc20_compiled.pkl')

    EXPECTED_TOTAL_SUPPLY = 10000000000000000000000

    erc20_contract_interface = compiled_erc20_sol[
        'contract_data/erc20.sol:SimpleToken']

    w3 = Web3()

    SimpleToken = w3.eth.contract(abi=erc20_contract_interface['abi'],
                                  bytecode=erc20_contract_interface['bin'])

    # Build transaction to deploy the contract
    w3_erc20_tx = SimpleToken.constructor().buildTransaction(W3_TX_DEFAULTS)

    max_gas = 20000000

    chain.create_and_sign_transaction_for_queue_block(
        gas_price=0x01,
        gas=max_gas,
        to=CREATE_CONTRACT_ADDRESS,
        value=0,
        data=decode_hex(w3_erc20_tx['data']),
        v=0,
        r=0,
        s=0)

    #time.sleep(1)
    print("deploying erc20 smart contract")
    imported_block = chain.import_current_queue_block()

    #now we need to add the block to the smart contract
    list_of_smart_contracts = chain.get_vm(
    ).state.account_db.get_smart_contracts_with_pending_transactions()
    erc20_contract_address = list_of_smart_contracts[0]

    chain = MainnetChain(testdb, erc20_contract_address, private_keys[0])

    chain.populate_queue_block_with_receive_tx()
    imported_block = chain.import_current_queue_block()

    #
    # airdrop contract deploy
    #
    compiled_airdrop_sol = load_compiled_sol_dict(
        'contract_data/airdrop_compiled.pkl')

    EXPECTED_TOTAL_SUPPLY = 10000000000000000000000

    airdrop_contract_interface = compiled_airdrop_sol[
        'contract_data/airdrop.sol:Airdrop']

    Airdrop = w3.eth.contract(abi=airdrop_contract_interface['abi'],
                              bytecode=airdrop_contract_interface['bin'])

    # Build transaction to deploy the contract
    w3_airdrop_tx = Airdrop.constructor().buildTransaction(W3_TX_DEFAULTS)

    chain = MainnetChain(testdb,
                         GENESIS_PRIVATE_KEY.public_key.to_canonical_address(),
                         GENESIS_PRIVATE_KEY)

    chain.create_and_sign_transaction_for_queue_block(
        gas_price=0x01,
        gas=max_gas,
        to=CREATE_CONTRACT_ADDRESS,
        value=0,
        data=decode_hex(w3_airdrop_tx['data']),
        v=0,
        r=0,
        s=0)

    print("deploying airdrop smart contract")
    imported_block = chain.import_current_queue_block()

    # now we need to add the block to the smart contract
    list_of_smart_contracts = chain.get_vm(
    ).state.account_db.get_smart_contracts_with_pending_transactions()
    airdrop_contract_address = list_of_smart_contracts[0]

    chain = MainnetChain(testdb, airdrop_contract_address, private_keys[0])

    chain.populate_queue_block_with_receive_tx()
    imported_block = chain.import_current_queue_block()

    #
    # Interacting with deployed smart contract step 1) add send transaction
    #
    chain = MainnetChain(testdb,
                         GENESIS_PRIVATE_KEY.public_key.to_canonical_address(),
                         GENESIS_PRIVATE_KEY)

    print(erc20_contract_interface['abi'])
    simple_token = w3.eth.contract(
        address=Web3.toChecksumAddress(erc20_contract_address),
        abi=erc20_contract_interface['abi'],
    )

    airdrop_token_balance = 1000

    w3_erc20_send = simple_token.functions.transfer(
        Web3.toChecksumAddress(airdrop_contract_address),
        airdrop_token_balance).buildTransaction(W3_TX_DEFAULTS)

    chain.create_and_sign_transaction_for_queue_block(
        gas_price=0x01,
        gas=max_gas,
        to=erc20_contract_address,
        value=0,
        data=decode_hex(w3_erc20_send['data']),
        v=0,
        r=0,
        s=0)
    imported_block = chain.import_current_queue_block()

    chain = MainnetChain(testdb, erc20_contract_address, private_keys[0])
    chain.populate_queue_block_with_receive_tx()
    imported_block = chain.import_current_queue_block()

    from pprint import pprint
    receipt = chain.chaindb.get_receipts(imported_block.header, Receipt)[0]

    receipt_dict = format_receipt_for_web3_to_extract_events(
        receipt, imported_block.receive_transactions[0].hash, chain)

    rich_logs = simple_token.events.Transfer().processReceipt(receipt_dict)
    print(rich_logs)
    print(rich_logs[0]['args'])
    print('a')

    assert (to_int(
        chain.chaindb.get_receipts(
            imported_block.header,
            Receipt)[0].logs[0].data) == airdrop_token_balance)

    chain = MainnetChain(testdb,
                         GENESIS_PRIVATE_KEY.public_key.to_canonical_address(),
                         GENESIS_PRIVATE_KEY)

    w3_erc20_balance = simple_token.functions.balanceOf(
        Web3.toChecksumAddress(airdrop_contract_address)).buildTransaction(
            W3_TX_DEFAULTS)

    chain.create_and_sign_transaction_for_queue_block(
        gas_price=0x01,
        gas=max_gas,
        to=erc20_contract_address,
        value=0,
        data=decode_hex(w3_erc20_balance['data']),
        v=0,
        r=0,
        s=0)
    imported_block = chain.import_current_queue_block()

    chain = MainnetChain(testdb, erc20_contract_address, private_keys[0])
    chain.populate_queue_block_with_receive_tx()
    imported_block = chain.import_current_queue_block()

    print(chain.chaindb.get_receipts(imported_block.header, Receipt)[0].logs)

    exit()
    #now lets look at the reciept to see the result
    assert (to_int(
        chain.chaindb.get_receipts(
            imported_block.header,
            Receipt)[0].logs[0].data) == EXPECTED_TOTAL_SUPPLY)
    print("Total supply call gave expected result!")
    gas_used = to_int(
        chain.chaindb.get_receipts(imported_block.header, Receipt)[0].gas_used)

    #
    # Interacting with deployed smart contract step 3) Receiving refund of extra gas that wasn't used in the computation
    #
    initial_balance = chain.get_vm().state.account_db.get_balance(
        GENESIS_PRIVATE_KEY.public_key.to_canonical_address())
    chain = MainnetChain(testdb,
                         GENESIS_PRIVATE_KEY.public_key.to_canonical_address(),
                         GENESIS_PRIVATE_KEY)
    chain.populate_queue_block_with_receive_tx()
    imported_block = chain.import_current_queue_block()
    final_balance = chain.get_vm().state.account_db.get_balance(
        GENESIS_PRIVATE_KEY.public_key.to_canonical_address())
    assert ((final_balance - initial_balance) == (max_gas - gas_used))
    print("Refunded gas is the expected amount.")
def get_fresh_db():
    testdb1 = MemoryDB()
    MainnetChain.from_genesis(
        testdb1, GENESIS_PRIVATE_KEY.public_key.to_canonical_address(),
        MAINNET_GENESIS_PARAMS, MAINNET_GENESIS_STATE)
    return testdb1