Пример #1
0
    def add_receivable_transaction(self, address, transaction_hash,
                                   sender_block_hash):
        validate_canonical_address(address, title="Storage Address")
        validate_is_bytes(transaction_hash, title="Transaction Hash")
        validate_is_bytes(sender_block_hash, title="Sender Block Hash")

        #this is the wallet address people send money to when slashed. It is a sink
        if address == SLASH_WALLET_ADDRESS:
            return

        #first lets make sure we don't already have the transaction
        if self.get_receivable_transaction(address,
                                           transaction_hash) is not False:
            raise ValueError(
                "Tried to save a receivable transaction that was already saved"
            )

        account = self._get_account(address)
        receivable_transactions = account.receivable_transactions

        new_receivable_transactions = receivable_transactions + (
            TransactionKey(transaction_hash, sender_block_hash), )

        self.logger.debug(
            "adding receivable transaction {}".format(transaction_hash))
        #self.logger.debug(new_receivable_transactions)

        self._set_account(
            address,
            account.copy(receivable_transactions=new_receivable_transactions))
Пример #2
0
    def delete_receivable_transaction(self, address, transaction_hash):
        validate_canonical_address(address, title="Storage Address")
        validate_is_bytes(transaction_hash, title="Transaction Hash")

        self.logger.debug("deleting receivable tx {}".format(transaction_hash))
        account = self._get_account(address)
        receivable_transactions = list(
            self.get_receivable_transactions(address))
        i = 0
        found = False
        for tx_key in receivable_transactions:
            if tx_key.transaction_hash == transaction_hash:
                found = True
                break
            i += 1

        if found == True:
            del receivable_transactions[i]
        else:
            raise ValueError(
                "transaction hash {0} not found in receivable_transactions database for wallet {1}"
                .format(transaction_hash, address))

        self._set_account(
            address,
            account.copy(
                receivable_transactions=tuple(receivable_transactions)))
Пример #3
0
    def add_receivable_transaction(self, address: Address, transaction_hash: Hash32, sender_block_hash: Hash32, is_contract_deploy:bool = False) -> None:
        validate_canonical_address(address, title="Wallet Address")
        validate_is_bytes(transaction_hash, title="Transaction Hash")
        validate_is_bytes(sender_block_hash, title="Sender Block Hash")
        
        #this is the wallet address people send money to when slashed. It is a sink
        if address == SLASH_WALLET_ADDRESS:
            return


        account = self._get_account(address)
        receivable_transactions = account.receivable_transactions

        # first lets make sure we don't already have the transaction
        for tx_key in receivable_transactions:
            if tx_key.transaction_hash == transaction_hash:
                raise ValueError("Tried to save a receivable transaction that was already saved. TX HASH = {}".format(encode_hex(transaction_hash)))

        
        new_receivable_transactions = receivable_transactions + (TransactionKey(transaction_hash, sender_block_hash), )
        
        
        #self.logger.debug(new_receivable_transactions)
        self.logger.debug("Adding receivable transaction {} to account {}".format(encode_hex(transaction_hash), encode_hex(address)))
        self._set_account(address, account.copy(receivable_transactions=new_receivable_transactions))

        #finally, if this is a smart contract, lets add it to the list of smart contracts with pending transactions
        if is_contract_deploy or self.get_code_hash(address) != EMPTY_SHA3:
            self.logger.debug("Adding address to list of smart contracts with pending transactions")
            #we only need to run this when adding the first one.
            self._add_address_to_smart_contracts_with_pending_transactions(address)
Пример #4
0
 def delete_chain(self,
                  address,
                  delete_from_historical_root_hashes: bool = True):
     validate_canonical_address(address, title="Wallet Address")
     self.delete_chain_head_hash(address)
     if delete_from_historical_root_hashes:
         self.add_block_hash_to_timestamp(address, BLANK_HASH, 0)
Пример #5
0
    def persist(self, save_account_hash=False, wallet_address=None) -> None:
        self._journaldb.persist()
        self._batchdb.commit(apply_deletes=True)

        if save_account_hash:
            validate_canonical_address(wallet_address, title="Address")
            self.save_current_account_with_hash_lookup(wallet_address)
Пример #6
0
    def delete_receivable_transaction(self, address: Address, transaction_hash: Hash32) -> None:
        validate_canonical_address(address, title="Storage Address")
        validate_is_bytes(transaction_hash, title="Transaction Hash")
        
        self.logger.debug("deleting receivable tx {} from account {}".format(encode_hex(transaction_hash), encode_hex(address)))
        account = self._get_account(address)
        receivable_transactions = list(self.get_receivable_transactions(address))
        i = 0
        found = False
        for tx_key in receivable_transactions:
            if tx_key.transaction_hash == transaction_hash:
                found = True
                break
            i +=1
            
        if found == True:
            del receivable_transactions[i]
        else:
            raise ReceivableTransactionNotFound("transaction hash {0} not found in receivable_transactions database for wallet {1}".format(transaction_hash, address))
        
        self._set_account(address, account.copy(receivable_transactions=tuple(receivable_transactions)))

        if self.get_code_hash(address) != EMPTY_SHA3:
            if len(receivable_transactions) == 0:
                self.logger.debug("Removing address from list of smart contracts with pending transactions")
                self._remove_address_from_smart_contracts_with_pending_transactions(address)
Пример #7
0
    def get_code(self, address):
        validate_canonical_address(address, title="Storage Address")

        try:
            return self._journaldb[self.get_code_hash(address)]
        except KeyError:
            return b""
Пример #8
0
 def get_chain_head_hash_at_timestamp(self, address, timestamp):
     validate_canonical_address(address, title="Wallet Address")
     validate_uint256(timestamp, title='timestamp')
     #make sure it isnt in the future
     if timestamp > int(time.time()):
         raise InvalidHeadRootTimestamp()
     
     #first make sure the timestamp is correct.
     if timestamp % TIME_BETWEEN_HEAD_HASH_SAVE != 0:
         raise InvalidHeadRootTimestamp()
         
     historical_roots = self.get_historical_root_hashes()
     if historical_roots is None:
         return None
     
     if timestamp < historical_roots[0][0]:
         return None
     
     historical_roots_dict = dict(historical_roots)
     
     try:
         historical_root = historical_roots_dict[timestamp]
     except KeyError:
         historical_root = historical_roots[-1][1]
     
     new_chain_head_db = ChainHeadDB(self.db, historical_root)
     head_hash = new_chain_head_db._trie_cache.get(address)
     return head_hash
Пример #9
0
 def add_log_entry(self, account: Address, topics: List[int], data: bytes) -> None:
     validate_canonical_address(account, title="Log entry address")
     for topic in topics:
         validate_uint256(topic, title="Log entry topic")
     validate_is_bytes(data, title="Log entry data")
     self._log_entries.append(
         (self.transaction_context.get_next_log_counter(), account, topics, data))
Пример #10
0
 def save_current_account_with_hash_lookup(self, wallet_address):
     validate_canonical_address(wallet_address, title="Address")
     account_hash = self.get_account_hash(wallet_address)
     account = self._get_account(wallet_address)
     rlp_account = rlp.encode(account, sedes=Account)
     
     lookup_key = SchemaV1.make_account_by_hash_lookup_key(account_hash)
     self.db[lookup_key] = rlp_account
Пример #11
0
 def persist(self, save_account_hash = False, wallet_address = None) -> None:
     self.logger.debug('Persisting account db. save_account_hash {} | wallet_address {}'.format(save_account_hash, wallet_address))
     self._journaldb.persist()
     self._batchdb.commit(apply_deletes=True)
     
     if save_account_hash:
         validate_canonical_address(wallet_address, title="Address")
         self.save_current_account_with_hash_lookup(wallet_address)
Пример #12
0
    def register_account_for_deletion(self, beneficiary: Address) -> None:
        validate_canonical_address(beneficiary, title="Self destruct beneficiary address")

        if self.msg.storage_address in self.accounts_to_delete:
            raise ValueError(
                "Invariant.  Should be impossible for an account to be "
                "registered for deletion multiple times"
            )
        self.accounts_to_delete[self.msg.storage_address] = beneficiary
Пример #13
0
    def set_code(self, address, code):
        validate_canonical_address(address, title="Storage Address")
        validate_is_bytes(code, title="Code")

        account = self._get_account(address)

        code_hash = keccak(code)
        self._journaldb[code_hash] = code
        self._set_account(address, account.copy(code_hash=code_hash))
Пример #14
0
 def revert_to_account_from_hash(self, account_hash, wallet_address):
     validate_canonical_address(wallet_address, title="Address")
     validate_is_bytes(account_hash, title="account_hash")
     lookup_key = SchemaV1.make_account_by_hash_lookup_key(account_hash)
     try:
         rlp_encoded = self.db[lookup_key]
         account = rlp.decode(rlp_encoded, sedes=Account)
         self._set_account(wallet_address, account)
     except KeyError:
         raise StateRootNotFound()
Пример #15
0
    def get_storage(self, address, slot):
        validate_canonical_address(address, title="Storage Address")
        validate_uint256(slot, title="Storage Slot")

        account = self._get_account(address)
        storage = HashTrie(HexaryTrie(self._journaldb, account.storage_root))

        slot_as_key = pad32(int_to_big_endian(slot))

        if slot_as_key in storage:
            encoded_value = storage[slot_as_key]
            return rlp.decode(encoded_value, sedes=rlp.sedes.big_endian_int)
        else:
            return 0
Пример #16
0
    def _get_peer_node_health(
            self, peer_wallet_address: Address,
            after_block_number: BlockNumber) -> PeerNodeHealth:
        validate_canonical_address(peer_wallet_address, title="Value")
        validate_uint64(after_block_number, 'block_number')

        key = SchemaV1.make_peer_node_health_lookup(peer_wallet_address,
                                                    after_block_number)
        try:
            rlp_peer_node_health = self.db[key]
            peer_node_health = rlp.decode(rlp_peer_node_health,
                                          sedes=PeerNodeHealth)
        except KeyError:
            peer_node_health = PeerNodeHealth()

        return peer_node_health
Пример #17
0
    def set_storage(self, address, slot, value):
        validate_uint256(value, title="Storage Value")
        validate_uint256(slot, title="Storage Slot")
        validate_canonical_address(address, title="Storage Address")

        account = self._get_account(address)
        storage = HashTrie(HexaryTrie(self._journaldb, account.storage_root))

        slot_as_key = pad32(int_to_big_endian(slot))

        if value:
            encoded_value = rlp.encode(value)
            storage[slot_as_key] = encoded_value
        else:
            del storage[slot_as_key]

        self._set_account(address, account.copy(storage_root=storage.root_hash))
Пример #18
0
    def __init__(self,
                 gas,
                 to,
                 sender,
                 value,
                 data,
                 code,
                 depth=0,
                 create_address=None,
                 code_address=None,
                 should_transfer_value=True,
                 is_static=False,
                 refund_amount=0):
        validate_uint256(gas, title="Message.gas")
        self.gas = gas  # type: int

        if to != CREATE_CONTRACT_ADDRESS:
            validate_canonical_address(to, title="Message.to")
        self.to = to

        validate_canonical_address(sender, title="Message.sender")
        self.sender = sender

        validate_uint256(value, title="Message.value")
        self.value = value

        validate_is_bytes(data, title="Message.data")
        self.data = data

        validate_is_integer(depth, title="Message.depth")
        validate_gte(depth, minimum=0, title="Message.depth")
        self.depth = depth

        validate_is_bytes(code, title="Message.code")
        self.code = code

        if create_address is not None:
            validate_canonical_address(create_address,
                                       title="Message.storage_address")
        self.storage_address = create_address

        if code_address is not None:
            validate_canonical_address(code_address,
                                       title="Message.code_address")
        self.code_address = code_address

        validate_is_boolean(should_transfer_value,
                            title="Message.should_transfer_value")
        self.should_transfer_value = should_transfer_value

        validate_is_integer(depth, title="Message.refund_amount")
        self.refund_amount = refund_amount

        validate_is_boolean(is_static, title="Message.is_static")
        self.is_static = is_static
    def __init__(self, origin: Address, send_tx_hash: Hash32, caller_chain_address:Address, gas_price: int = None, receive_tx_hash: Hash32 = None, is_receive: bool = False, is_refund: bool = False):
        if gas_price is not None:
            validate_uint256(gas_price, title="TransactionContext.gas_price")
        self._gas_price = gas_price
        validate_canonical_address(origin, title="TransactionContext.origin")
        self._origin = origin
        validate_canonical_address(caller_chain_address, title='caller_chain_address')
        self._caller_chain_address = caller_chain_address
        validate_is_boolean(is_receive, title="is_receive")
        self._is_receive = is_receive
        validate_is_boolean(is_refund, title="is_from_refund")
        self._is_refund = is_refund
        validate_word(send_tx_hash, title="send_tx_hash")
        self._send_tx_hash = send_tx_hash
        if receive_tx_hash is not None:
            validate_word(receive_tx_hash, title="receive_tx_hash")
        self._receive_tx_hash = receive_tx_hash

        self._log_counter = itertools.count()
Пример #20
0
    def calculate_final_reward_type_1_amount(
            self,
            wallet_address: Address,
            at_timestamp: Timestamp = None) -> int:
        '''
        :param wallet_address:
        :return:
        '''

        validate_canonical_address(wallet_address, 'wallet_address')

        if at_timestamp == None:
            at_timestamp = int(time.time())

        fractional_interest = self.reward_type_1_amount_factor

        amount = self.calculate_reward_based_on_fractional_interest(
            wallet_address, fractional_interest, at_timestamp)

        return amount
Пример #21
0
    def validate(self):

        validate_canonical_address(self.recipient_node_wallet_address, title="recipient_node_wallet_address")
        validate_uint256(self.score, title="score")
        validate_uint256(self.since_block_number, title="since_block_number")
        validate_uint256(self.timestamp, title="timestamp")

        validate_uint256(self.v, title="v")
        validate_uint256(self.r, title="r")
        validate_uint256(self.s, title="s")

        validate_lt_secpk1n(self.r, title="r")
        validate_gte(self.r, minimum=1, title="r")
        validate_lt_secpk1n(self.s, title="s")
        validate_gte(self.s, minimum=1, title="s")

        validate_gte(self.v, minimum=self.v_min, title="v")
        validate_lte(self.v, maximum=self.v_max, title="v")

        validate_lt_secpk1n2(self.s, title="s")
Пример #22
0
    def validate(self):
        validate_uint256(self.nonce, title="Transaction.nonce")
        validate_uint256(self.gas_price, title="Transaction.gas_price")
        validate_uint256(self.gas, title="Transaction.gas")
        if self.to != CREATE_CONTRACT_ADDRESS:
            validate_canonical_address(self.to, title="Transaction.to")
        validate_uint256(self.value, title="Transaction.value")
        validate_is_bytes(self.data, title="Transaction.data")

        validate_uint256(self.v, title="Transaction.v")
        validate_uint256(self.r, title="Transaction.r")
        validate_uint256(self.s, title="Transaction.s")

        validate_lt_secpk1n(self.r, title="Transaction.r")
        validate_gte(self.r, minimum=1, title="Transaction.r")
        validate_lt_secpk1n(self.s, title="Transaction.s")
        validate_gte(self.s, minimum=1, title="Transaction.s")

        validate_gte(self.v, minimum=self.v_min, title="Transaction.v")
        validate_lte(self.v, maximum=self.v_max, title="Transaction.v")

        super(FrontierTransaction, self).validate()
Пример #23
0
 def get_receivable_transactions(self, address: Address) -> List[TransactionKey]:
     validate_canonical_address(address, title="Storage Address")
     account = self._get_account(address)
     return account.receivable_transactions
Пример #24
0
    def get_code_hash(self, address):
        validate_canonical_address(address, title="Storage Address")

        account = self._get_account(address)
        return account.code_hash
Пример #25
0
 def add_receivable_transactions(self, address: Address, transaction_keys: TransactionKey) -> None:
     validate_canonical_address(address, title="Wallet Address")
     for tx_key in transaction_keys:
         self.add_receivable_transaction(address, tx_key.transaction_hash, tx_key.sender_block_hash)
Пример #26
0
    def touch_account(self, address):
        validate_canonical_address(address, title="Storage Address")

        account = self._get_account(address)
        self._set_account(address, account)
Пример #27
0
 def account_exists(self, address):
     validate_canonical_address(address, title="Storage Address")
     account_lookup_key = SchemaV1.make_account_lookup_key(address)
     
     return self._journaldb.get(account_lookup_key, b'') != b''
Пример #28
0
 def delete_account(self, address):
     validate_canonical_address(address, title="Storage Address")
     account_lookup_key = SchemaV1.make_account_lookup_key(address)
     #try:
     del self._journaldb[account_lookup_key]
Пример #29
0
 def has_pending_smart_contract_transactions(self, address: Address) -> bool:
     validate_canonical_address(address, title="Storage Address")
     address_set = set(self.get_smart_contracts_with_pending_transactions())
     return address in address_set
Пример #30
0
    def delete_code(self, address):
        validate_canonical_address(address, title="Storage Address")

        account = self._get_account(address)
        self._set_account(address, account.copy(code_hash=EMPTY_SHA3))