def test_invalid_proofs_all_from_same_wallet():

    testdb = create_reward_test_blockchain_database()

    chain = MainnetChain(testdb, private_keys[0].public_key.to_canonical_address(), private_keys[0])

    required_number_of_proofs_for_reward_type_2_proof = chain.get_consensus_db(timestamp=Timestamp(int(time.time()))).required_number_of_proofs_for_reward_type_2_proof

    node_staking_scores = []

    score = 1000000
    for i in range(1, 10):
        # Second score/proof is from instance 1
        current_private_key = private_keys[1]
        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])

    with pytest.raises(ValidationError):
        reward_chain.import_current_queue_block_with_reward(node_staking_scores)
Beispiel #2
0
    def get_signed_peer_score(
        self,
        private_key: PrivateKey,
        network_id: int,
        peer_wallet_address: Address,
        after_block_number: BlockNumber = None,
    ) -> NodeStakingScore:

        this_node_wallet_address = private_key.public_key.to_canonical_address(
        )

        if after_block_number is None:
            after_block_number = self.chaindb.get_latest_reward_block_number(
                peer_wallet_address)

        peer_node_health = self._get_peer_node_health(peer_wallet_address,
                                                      after_block_number)

        # fields = [
        #     ('recipient_node_wallet_address', address),
        #     ('score', f_big_endian_int),
        #     ('since_block_number', f_big_endian_int),
        #     ('timestamp', f_big_endian_int),
        #     ('v', f_big_endian_int),
        #     ('r', f_big_endian_int),
        #     ('s', f_big_endian_int),
        # ]

        #need to get the time since the block.
        try:
            header = self.chaindb.get_canonical_block_header_by_number(
                after_block_number, peer_wallet_address)
        except HeaderNotFound:
            raise ValueError(
                "Cannot find previous block that is supposed to contain a stake reward"
            )

        since_timestamp = header.timestamp
        time_since_last_specified_block = int(time.time()) - since_timestamp

        score = self.calculate_node_staking_score(
            peer_node_health.requests_sent, peer_node_health.failed_requests,
            peer_node_health.average_response_time,
            time_since_last_specified_block)

        head_hash_of_local_chain = self.chaindb.get_canonical_head_hash(
            this_node_wallet_address)
        node_staking_score = NodeStakingScore(peer_wallet_address,
                                              score,
                                              after_block_number,
                                              int(time.time()),
                                              head_hash_of_local_chain,
                                              v=0,
                                              r=0,
                                              s=0)

        signed_node_staking_score = node_staking_score.get_signed(
            private_key, network_id)

        return signed_node_staking_score
Beispiel #3
0
def test_invalid_proofs_not_enough_proofs():

    testdb = create_reward_test_blockchain_database()

    chain = TestnetChain(testdb,
                         private_keys[0].public_key.to_canonical_address(),
                         private_keys[0])
    min_time_between_blocks = chain.get_vm(
        timestamp=Timestamp(int(time.time()))).min_time_between_blocks
    tx_list = [[
        private_keys[1], private_keys[0],
        to_wei(1, 'ether'),
        int(int(time.time()) - min_time_between_blocks * 10)
    ]]

    add_transactions_to_blockchain_db(testdb, tx_list)

    chain = TestnetChain(testdb,
                         private_keys[0].public_key.to_canonical_address(),
                         private_keys[0])

    required_number_of_proofs_for_reward_type_2_proof = chain.get_consensus_db(
        timestamp=Timestamp(int(
            time.time()))).required_number_of_proofs_for_reward_type_2_proof

    node_staking_scores = []

    # First score/proof with timestamp far in future
    current_private_key = private_keys[1]
    node_staking_score = NodeStakingScore(
        recipient_node_wallet_address=private_keys[0].public_key.
        to_canonical_address(),
        score=int(1000000),
        since_block_number=0,
        timestamp=int(time.time()) - 60 * 10,
        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, TESTNET_NETWORK_ID)
    node_staking_scores.append(signed_node_staking_score)

    # Now we try to import the reward block with instance 0
    reward_chain = TestnetChain(
        testdb, private_keys[0].public_key.to_canonical_address(),
        private_keys[0])

    with pytest.raises(NotEnoughProofsOrStakeForRewardType2Proof):
        reward_chain.import_current_queue_block_with_reward(
            node_staking_scores)
Beispiel #4
0
    def validate_node_staking_score(self, node_staking_score: NodeStakingScore,
                                    since_block_number: BlockNumber) -> None:
        node_staking_score.validate()

        # make sure all proof's have valid signatures
        node_staking_score.check_signature_validity()

        # need to make sure we have the up-to-date peer chain so that our stake calculation is correct.
        # RewardProofSenderBlockMissing
        if not self.chaindb.is_in_canonical_chain(
                node_staking_score.head_hash_of_sender_chain):
            raise RewardProofSenderBlockMissing(
                "Our chain for chain_address {} appears to be out of date. We need the block with hash {}"
                .format(
                    encode_hex(node_staking_score.sender),
                    encode_hex(node_staking_score.head_hash_of_sender_chain)))

        # The node staking score proof cannot know about a block in the future.
        claimed_header = self.chaindb.get_block_header_by_hash(
            node_staking_score.head_hash_of_sender_chain)
        if claimed_header.timestamp > node_staking_score.timestamp:
            raise ValidationError(
                "Reward proof has a timestamp that is less than the claimed head hash of sender chain. This is impossible because it cannot know about the future, and not allowed."
            )

        # we have to make sure the head_hash_of_sender_chain is the newest block before the given timestamp
        next_block_number = claimed_header.block_number + 1
        try:
            next_header = self.chaindb.get_canonical_block_header_by_number(
                next_block_number, node_staking_score.sender)
            if next_header.timestamp < node_staking_score.timestamp:
                # it found a block that is earlier than the proof timestamp, but is newer than the claimed header. This means they claimed the wrong header
                raise ValidationError(
                    "Reward proof has incorrect header hash for the sender chain, at the timestamp the proof was made. "
                    "The timestamp of the node staking score is {}. The timestamp of the next block is {}. "
                    "The block number of the next block is {}. The hash of the next block is {}"
                    .format(node_staking_score.timestamp,
                            next_header.timestamp, next_header.block_number,
                            encode_hex(next_header.hash)))
        except HeaderNotFound:
            pass

        # We need to validate that the previous reward block in proof equals the latest reward block
        if node_staking_score.since_block_number != since_block_number:
            raise ValidationError(
                "Reward proof has incorrect since_block_number. Got {}, but should be {}"
                .format(node_staking_score.since_block_number,
                        since_block_number))

        if node_staking_score.score < 0 or node_staking_score.score > 1000000:
            raise ValidationError(
                'Node staking score is out of allowed range of 0 to 1,000,000. Got {}'
                .format(node_staking_score.score))
def test_invalid_proofs_previous_reward_block_incorrect():

    testdb = create_reward_test_blockchain_database()

    chain = MainnetChain(testdb, private_keys[0].public_key.to_canonical_address(), private_keys[0])
    min_time_between_blocks = chain.get_vm(timestamp=Timestamp(int(time.time()))).min_time_between_blocks
    tx_list = [[private_keys[1], private_keys[0], to_wei(1, 'ether'), int(int(time.time())-min_time_between_blocks*10)]]

    add_transactions_to_blockchain_db(testdb, tx_list)

    chain = MainnetChain(testdb, private_keys[0].public_key.to_canonical_address(), private_keys[0])

    required_number_of_proofs_for_reward_type_2_proof = chain.get_consensus_db(timestamp=Timestamp(int(time.time()))).required_number_of_proofs_for_reward_type_2_proof

    node_staking_scores = []

    # First score/proof with the incorrect head hash
    current_private_key = private_keys[1]
    node_staking_score = NodeStakingScore(
        recipient_node_wallet_address=private_keys[0].public_key.to_canonical_address(),
        score=int(1000000),
        since_block_number=1,
        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)

    score = 100000
    for i in range(2, 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=1,
            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])

    with pytest.raises(ValidationError):
        reward_chain.import_current_queue_block_with_reward(node_staking_scores)
Beispiel #6
0
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 = TestnetChain(base_db, TESTNET_GENESIS_PRIVATE_KEY.public_key.to_canonical_address(), TESTNET_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[TESTNET_GENESIS_PRIVATE_KEY.public_key.to_address()] = TESTNET_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 = TESTNET_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 = TestnetChain(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
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 test_invalid_proofs_not_enough_stake():
    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
    min_time_between_blocks = chain.get_vm(timestamp=Timestamp(int(time.time()))).min_time_between_blocks
    now = int(time.time())
    start = now - max((coin_mature_time * 2), (min_time_between_blocks * 20))
    key_balance_dict = {
        private_keys[0]: (to_wei(1, 'ether'), start),
        private_keys[1]: (to_wei(1, 'ether'), start + min_time_between_blocks * 1),
        private_keys[2]: (to_wei(1, 'ether'), start + min_time_between_blocks * 2),
        private_keys[3]: (to_wei(1, 'ether'), start + min_time_between_blocks * 3),
        private_keys[4]: (to_wei(1, 'ether'), start + min_time_between_blocks * 4),
        private_keys[5]: (to_wei(1, 'ether'), start + min_time_between_blocks * 5),
        private_keys[6]: (to_wei(1, 'ether'), start + min_time_between_blocks * 6),
        private_keys[7]: (to_wei(1, 'ether'), start + min_time_between_blocks * 7),
        private_keys[8]: (to_wei(1, 'ether'), start + min_time_between_blocks * 8),
        private_keys[9]: (to_wei(1, 'ether'), now - coin_mature_time + 1),  # immature
    }
    create_dev_fixed_blockchain_database(testdb, key_balance_dict)

    chain = MainnetChain(testdb, private_keys[0].public_key.to_canonical_address(), private_keys[0])

    node_staking_scores = []

    # First score/proof with timestamp far in future
    current_private_key = private_keys[1]
    node_staking_score = NodeStakingScore(
        recipient_node_wallet_address=private_keys[0].public_key.to_canonical_address(),
        score=int(1000000),
        since_block_number=0,
        timestamp=int(time.time())-60*10,
        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)

    score = 100000
    for i in range(2, 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=1,
            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])

    with pytest.raises(NotEnoughProofsOrStakeForRewardType2Proof):
        reward_chain.import_current_queue_block_with_reward(node_staking_scores)
def _test_block_rewards_system():
    #The genesis chain will be adding a reward block. We need to generate fake NodeStakingScores from a bunch of other
    #nodes

    # testdb = LevelDB('/home/tommy/.local/share/helios/instance_test/mainnet/chain/full/')
    # testdb = JournalDB(testdb)
    testdb = create_reward_test_blockchain_database()

    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
    min_time_between_blocks = chain.get_vm(timestamp=Timestamp(int(time.time()))).min_time_between_blocks
    # now = int(time.time())
    # start = now - max((coin_mature_time * 2), (min_time_between_blocks*20))
    # key_balance_dict = {
    #     private_keys[0]: (to_wei(10, 'ether'), start),
    #     private_keys[1]: (to_wei(200, 'ether'), start + min_time_between_blocks * 1),
    #     private_keys[2]: (to_wei(340, 'ether'), start + min_time_between_blocks * 2),
    #     private_keys[3]: (to_wei(1000, 'ether'), start + min_time_between_blocks * 3),
    #     private_keys[4]: (to_wei(1400, 'ether'), start + min_time_between_blocks * 4),
    #     private_keys[5]: (to_wei(2400, 'ether'), start + min_time_between_blocks * 5),
    #     private_keys[6]: (to_wei(3000, 'ether'), start + min_time_between_blocks * 6),
    #     private_keys[7]: (to_wei(4000, 'ether'), start + min_time_between_blocks * 7),
    #     private_keys[8]: (to_wei(1000, 'ether'), start + min_time_between_blocks * 8),
    #     private_keys[9]: (to_wei(10000, 'ether'), now-coin_mature_time+1),# immature
    # }
    # create_dev_fixed_blockchain_database(testdb, key_balance_dict)

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

    # class NodeStakingScore(rlp.Serializable, metaclass=ABCMeta):
    #     fields = [
    #         ('recipient_node_wallet_address', address),
    #         ('score', f_big_endian_int),
    #         ('since_block_number', f_big_endian_int),
    #         ('timestamp', f_big_endian_int),
    #         ('v', big_endian_int),
    #         ('r', big_endian_int),
    #         ('s', big_endian_int),
    #     ]

    node_staking_scores = []

    score = 1000000
    for private_key in private_keys:
        node_staking_score = NodeStakingScore(recipient_node_wallet_address = GENESIS_PRIVATE_KEY.public_key.to_canonical_address(),
                                              score = int(score),
                                              since_block_number = 0,
                                              timestamp = int(time.time()),
                                              head_hash_of_sender_chain = chain.chaindb.get_canonical_head_hash(private_key.public_key.to_canonical_address()),
                                              v = 0,
                                              r = 0,
                                              s = 0,
                                              )
        signed_node_staking_score = node_staking_score.get_signed(private_key,MAINNET_NETWORK_ID)
        node_staking_scores.append(signed_node_staking_score)
        score = score/5

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

    node_staking_scores.sort(key=lambda x: -1* x.score)
    for node_staking_score in node_staking_scores:
        node_staking_score.validate()
        print(node_staking_score.is_signature_valid)
        print(node_staking_score.sender)
        print(node_staking_score.score, chain.get_mature_stake(node_staking_score.sender, node_staking_score.timestamp))


    reward_bundle = chain.get_consensus_db().create_reward_bundle_for_block(GENESIS_PRIVATE_KEY.public_key.to_canonical_address(), node_staking_scores, at_timestamp = int(time.time()))


    chain.get_consensus_db().validate_reward_bundle(reward_bundle, GENESIS_PRIVATE_KEY.public_key.to_canonical_address(), int(time.time()))

    print('AAAAAAAAAAA')
    print(reward_bundle.reward_type_1.amount)
    print(reward_bundle.reward_type_2.amount)
    print(reward_bundle.reward_type_2.proof[0].score)


    initial_balance = chain.get_vm().state.account_db.get_balance(GENESIS_PRIVATE_KEY.public_key.to_canonical_address())
    print("balance before reward = ", initial_balance)

    chain.import_current_queue_block_with_reward(reward_bundle.reward_type_2.proof)

    final_balance = chain.get_vm().state.account_db.get_balance(GENESIS_PRIVATE_KEY.public_key.to_canonical_address())
    print("balance after reward = ",final_balance)
    assert((reward_bundle.reward_type_1.amount + reward_bundle.reward_type_2.amount) == (final_balance- initial_balance))

    print("waiting {} seconds before importing the next block".format(min_time_between_blocks))
    time.sleep(min_time_between_blocks)

    proof_chain = MainnetChain(testdb, private_keys[1].public_key.to_canonical_address(), private_keys[1])
    mature_stake = proof_chain.get_mature_stake()
    print("proof chain mature stake")
    print(mature_stake)

    staking_score = proof_chain.get_signed_peer_score_string_private_key(private_keys[1].to_bytes(), private_keys[0].public_key.to_canonical_address())
    staking_score = staking_score.copy(score=1532)
    staking_score = staking_score.get_signed(private_keys[1], proof_chain.network_id)
    print('staking score')
    print(staking_score.score)

    # fields = [
    #     ('recipient_node_wallet_address', address),
    #     ('score', f_big_endian_int),  # a score out of 1,000,000
    #     ('since_block_number', f_big_endian_int),
    #     ('timestamp', f_big_endian_int),
    #     ('head_hash_of_sender_chain', hash32),
    #     ('v', big_endian_int),
    #     ('r', big_endian_int),
    #     ('s', big_endian_int),
    # ]
    #
    reward_chain = MainnetChain(testdb, private_keys[0].public_key.to_canonical_address(), private_keys[0])
    reward_bundle = reward_chain.get_consensus_db().create_reward_bundle_for_block(private_keys[0].public_key.to_canonical_address(), [staking_score],at_timestamp=Timestamp(int(time.time())))
    print("reward type 2 amount")
    print(reward_bundle.reward_type_2.amount)
    print("reward type 2 proof")
    print(reward_bundle.reward_type_2.proof)
    reward_chain.import_current_queue_block_with_reward([staking_score])

    # todo: this will fail if the reward block time is too long. Need to manually set it to a small number for the test... or manually make the blocks older?
    print("waiting {} seconds before importing the next block".format(min_time_between_blocks))
    time.sleep(min_time_between_blocks)

    proof_chain = MainnetChain(testdb, private_keys[1].public_key.to_canonical_address(), private_keys[1])
    mature_stake = proof_chain.get_mature_stake()
    print("proof chain mature stake")
    print(mature_stake)

    staking_score = proof_chain.get_signed_peer_score_string_private_key(private_keys[1].to_bytes(), private_keys[
        0].public_key.to_canonical_address())
    staking_score = staking_score.copy(score=1000000)
    staking_score = staking_score.get_signed(private_keys[1], proof_chain.network_id)
    print('staking score')
    print(staking_score.score)

    # fields = [
    #     ('recipient_node_wallet_address', address),
    #     ('score', f_big_endian_int),  # a score out of 1,000,000
    #     ('since_block_number', f_big_endian_int),
    #     ('timestamp', f_big_endian_int),
    #     ('head_hash_of_sender_chain', hash32),
    #     ('v', big_endian_int),
    #     ('r', big_endian_int),
    #     ('s', big_endian_int),
    # ]
    #
    reward_chain = MainnetChain(testdb, private_keys[0].public_key.to_canonical_address(), private_keys[0])
    reward_bundle = reward_chain.get_consensus_db().create_reward_bundle_for_block(
        private_keys[0].public_key.to_canonical_address(), [staking_score], at_timestamp=Timestamp(int(time.time())))
    print("reward type 2 amount")
    print(reward_bundle.reward_type_2.amount)
    print("reward type 2 proof")
    print(reward_bundle.reward_type_2.proof)
    reward_chain.import_current_queue_block_with_reward([staking_score])