def apply_create_message(
            cls, state: StateAPI, message: MessageAPI,
            transaction_context: TransactionContextAPI) -> ComputationAPI:

        computation = cls.apply_message(state, message, transaction_context)

        if computation.is_error:
            return computation
        else:
            contract_code = computation.output

            if contract_code:
                contract_code_gas_fee = len(contract_code) * GAS_CODEDEPOSIT
                try:
                    computation.consume_gas(
                        contract_code_gas_fee,
                        reason="Write contract code for CREATE",
                    )
                except OutOfGas:
                    computation.output = b''
                else:
                    cls.logger.debug2(
                        "SETTING CODE: %s -> length: %s | hash: %s",
                        encode_hex(message.storage_address),
                        len(contract_code), encode_hex(keccak(contract_code)))
                    state.set_code(message.storage_address, contract_code)
            return computation
Exemple #2
0
def validate_daejun_transaction(state : StateAPI,
                                transaction: SignedTransactionAPI) -> None:

    ## homesated logic ##
    
    if transaction.s > SECPK1_N // 2 or transaction.s == 0:
        raise ValidationError("Invalid signature S value")

    ## frontier logic ##

    # gas_cost = transaction.gas * transaction.gas_price
    sender_balance = state.get_balance(transaction.sender)

    # if sender_balance < gas_cost:
    #     raise ValidationError(
    #         f"Sender {transaction.sender!r} cannot afford txn gas "
    #         f"{gas_cost} with account balance {sender_balance}"
    #     )

    # total_cost = transaction.value + gas_cost
    total_cost = transaction.value

    if sender_balance < total_cost:
        raise ValidationError("Sender account balance cannot afford txn")

    sender_nonce = state.get_nonce(transaction.sender)
    if sender_nonce != transaction.nonce:
        raise ValidationError(
            f"Invalid transaction nonce: Expected {sender_nonce}, but got {transaction.nonce}"
        )
Exemple #3
0
def setup_state(desired_state: AccountState, state: StateAPI) -> None:
    for account, account_data in desired_state.items():
        for slot, value in account_data['storage'].items():
            state.set_storage(account, slot, value)

        nonce = account_data['nonce']
        code = account_data['code']
        balance = account_data['balance']

        state.set_nonce(account, nonce)
        state.set_code(account, code)
        state.set_balance(account, balance)
    state.persist()
Exemple #4
0
def _get_computation_error(state: StateAPI, transaction: SignedTransactionAPI) -> Optional[VMError]:

    snapshot = state.snapshot()

    try:
        computation = state.apply_transaction(transaction)
        if computation.is_error:
            return computation.error
        else:
            return None

    finally:
        state.revert(snapshot)
Exemple #5
0
def apply_state_dict(state: StateAPI, state_dict: AccountState) -> None:
    for account, account_data in state_dict.items():
        state.set_balance(account, account_data["balance"])
        state.set_nonce(account, account_data["nonce"])
        state.set_code(account, account_data["code"])

        for slot, value in account_data["storage"].items():
            state.set_storage(account, slot, value)
Exemple #6
0
    def make_receipt(base_header: BlockHeaderAPI,
                     transaction: SignedTransactionAPI,
                     computation: ComputationAPI,
                     state: StateAPI) -> ReceiptAPI:

        receipt_without_state_root = make_frontier_receipt(
            base_header, transaction, computation)

        return receipt_without_state_root.copy(
            state_root=state.make_state_root())
Exemple #7
0
def validate_frontier_transaction(state: StateAPI,
                                  transaction: SignedTransactionAPI) -> None:
    gas_cost = transaction.gas * transaction.gas_price
    sender_balance = state.get_balance(transaction.sender)

    if sender_balance < gas_cost:
        raise ValidationError(
            f"Sender {transaction.sender!r} cannot afford txn gas "
            f"{gas_cost} with account balance {sender_balance}"
        )

    total_cost = transaction.value + gas_cost

    if sender_balance < total_cost:
        raise ValidationError("Sender account balance cannot afford txn")

    sender_nonce = state.get_nonce(transaction.sender)
    if sender_nonce != transaction.nonce:
        raise ValidationError(
            f"Invalid transaction nonce: Expected {sender_nonce}, but got {transaction.nonce}"
        )
Exemple #8
0
def validate_frontier_transaction(state: StateAPI,
                                  transaction: SignedTransactionAPI) -> None:
    gas_cost = transaction.gas * transaction.gas_price
    sender_balance = state.get_balance(transaction.sender)

    if sender_balance < gas_cost:
        raise ValidationError(
            "Sender {} cannot afford txn gas {} with account balance {}".
            format(
                transaction.sender,
                gas_cost,
                sender_balance,
            ))

    total_cost = transaction.value + gas_cost

    if sender_balance < total_cost:
        raise ValidationError("Sender account balance cannot afford txn")

    if state.get_nonce(transaction.sender) != transaction.nonce:
        raise ValidationError("Invalid transaction nonce")
Exemple #9
0
    def make_receipt(cls, base_header: BlockHeaderAPI,
                     transaction: SignedTransactionAPI,
                     computation: ComputationAPI,
                     state: StateAPI) -> ReceiptAPI:

        gas_used = base_header.gas_used + cls.finalize_gas_used(
            transaction, computation)

        receipt_without_state_root = make_frontier_receipt(
            computation, gas_used)

        return receipt_without_state_root.copy(
            state_root=state.make_state_root())
Exemple #10
0
def validate_frontier_transaction(state: StateAPI,
                                  transaction: SignedTransactionAPI) -> None:
    max_gas_cost = transaction.gas * state.get_gas_price(transaction)
    sender_balance = state.get_balance(transaction.sender)

    if sender_balance < max_gas_cost:
        raise ValidationError(
            f"Sender {transaction.sender!r} cannot afford txn gas "
            f"{max_gas_cost} with account balance {sender_balance}")

    total_cost = transaction.value + max_gas_cost

    if sender_balance < total_cost:
        raise ValidationError(
            f"Sender does not have enough balance to cover transaction value and gas "
            f" (has {sender_balance}, needs {total_cost})")

    sender_nonce = state.get_nonce(transaction.sender)
    if sender_nonce != transaction.nonce:
        raise ValidationError(
            f"Invalid transaction nonce: Expected {sender_nonce}, but got {transaction.nonce}"
        )
Exemple #11
0
    def apply_create_message(
            cls, state: StateAPI, message: MessageAPI,
            transaction_context: TransactionContextAPI) -> ComputationAPI:
        snapshot = state.snapshot()

        computation = cls.apply_message(state, message, transaction_context)

        if computation.is_error:
            state.revert(snapshot)
            return computation
        else:
            contract_code = computation.output

            if contract_code:
                contract_code_gas_cost = len(
                    contract_code) * constants.GAS_CODEDEPOSIT
                try:
                    computation.consume_gas(
                        contract_code_gas_cost,
                        reason="Write contract code for CREATE",
                    )
                except OutOfGas as err:
                    # Different from Frontier: reverts state on gas failure while
                    # writing contract code.
                    computation.error = err
                    state.revert(snapshot)
                else:
                    if cls.logger:
                        cls.logger.debug2(
                            "SETTING CODE: %s -> length: %s | hash: %s",
                            encode_hex(message.storage_address),
                            len(contract_code),
                            encode_hex(keccak(contract_code)))

                    state.set_code(message.storage_address, contract_code)
                    state.commit(snapshot)
            else:
                state.commit(snapshot)
            return computation
    def apply_message(
            cls, state: StateAPI, message: MessageAPI,
            transaction_context: TransactionContextAPI) -> ComputationAPI:

        snapshot = state.snapshot()

        if message.depth > STACK_DEPTH_LIMIT:
            raise StackDepthLimit("Stack depth limit reached")

        if message.should_transfer_value and message.value:
            sender_balance = state.get_balance(message.sender)

            if sender_balance < message.value:
                raise InsufficientFunds(
                    f"Insufficient funds: {sender_balance} < {message.value}")

            state.delta_balance(message.sender, -1 * message.value)
            state.delta_balance(message.storage_address, message.value)

            cls.logger.debug2(
                "TRANSFERRED: %s from %s -> %s",
                message.value,
                encode_hex(message.sender),
                encode_hex(message.storage_address),
            )

        state.touch_account(message.storage_address)

        computation = cls.apply_computation(
            state,
            message,
            transaction_context,
        )

        if computation.is_error:
            state.revert(snapshot)
        else:
            state.commit(snapshot)

        return computation