diff --git a/fluffy/rpc/rpc_eth_api.nim b/fluffy/rpc/rpc_eth_api.nim index 3ee600376..f4b167253 100644 --- a/fluffy/rpc/rpc_eth_api.nim +++ b/fluffy/rpc/rpc_eth_api.nim @@ -14,14 +14,14 @@ import web3/conversions, # sigh, for FixedBytes marshalling web3/eth_api_types, web3/primitives as web3types, - eth/common/eth_types, + eth/common/[eth_types, transaction_utils], beacon_chain/spec/forks, ../network/history/[history_network, history_content], ../network/state/[state_network, state_content, state_endpoints], ../network/beacon/beacon_light_client, ../version -from ../../nimbus/transaction import getSender, ValidationError +from ../../nimbus/errors import ValidationError from ../../nimbus/rpc/filters import headerBloomFilter, deriveLogs, filterLogs from ../../nimbus/beacon/web3_eth_conv import w3Addr, w3Hash, ethHash @@ -42,10 +42,13 @@ func init*( header: eth_types.BlockHeader, txIndex: int, ): T {.raises: [ValidationError].} = + let sender = tx.recoverSender().valueOr: + raise (ref ValidationError)(msg: "Invalid tx signature") + TransactionObject( blockHash: Opt.some(w3Hash header.blockHash), blockNumber: Opt.some(eth_api_types.BlockNumber(header.number)), - `from`: w3Addr tx.getSender(), + `from`: sender, gas: Quantity(tx.gasLimit), gasPrice: Quantity(tx.gasPrice), hash: w3Hash tx.rlpHash, @@ -107,7 +110,6 @@ func init*( if fullTx: var i = 0 for tx in body.transactions: - # ValidationError from tx.getSender in TransactionObject.init blockObject.transactions.add txOrHash(TransactionObject.init(tx, header, i)) inc i else: diff --git a/hive_integration/nodocker/engine/tx_sender.nim b/hive_integration/nodocker/engine/tx_sender.nim index ff7376bcf..4d0a22cca 100644 --- a/hive_integration/nodocker/engine/tx_sender.nim +++ b/hive_integration/nodocker/engine/tx_sender.nim @@ -11,6 +11,7 @@ import std/[tables], eth/keys, + eth/common/transaction_utils, stew/endians2, nimcrypto/sha2, chronicles, @@ -150,7 +151,8 @@ proc makeTxOfType(params: MakeTxParams, tc: BaseTx): PooledTransaction = value : tc.amount, gasLimit: tc.gasLimit, gasPrice: gasPrice, - payload : tc.payload + payload : tc.payload, + chainId : params.chainId, ) ) of TxEip1559: @@ -207,7 +209,7 @@ proc makeTx(params: MakeTxParams, tc: BaseTx): PooledTransaction = # Build the transaction depending on the specified type let tx = makeTxOfType(params, tc) PooledTransaction( - tx: signTransaction(tx.tx, params.key, params.chainId, eip155 = true), + tx: signTransaction(tx.tx, params.key), networkPayload: tx.networkPayload) proc makeTx(params: MakeTxParams, tc: BigInitcodeTx): PooledTransaction = @@ -337,7 +339,7 @@ proc makeTx*(params: MakeTxParams, tc: BlobTx): PooledTransaction = ) PooledTransaction( - tx: signTransaction(unsignedTx, params.key, params.chainId, eip155 = true), + tx: signTransaction(unsignedTx, params.key), networkPayload: NetworkPayload( blobs : data.blobs.mapIt(it.bytes), commitments: data.commitments.mapIt(it.bytes), @@ -427,16 +429,10 @@ proc customizeTransaction*(sender: TxSender, if custTx.data.isSome: modTx.payload = custTx.data.get - if custTx.signature.isSome: - let signature = custTx.signature.get - modTx.V = signature.V - modTx.R = signature.R - modTx.S = signature.S + if custTx.chainId.isSome: + modTx.chainId = custTx.chainId.get if baseTx.txType in {TxEip1559, TxEip4844}: - if custTx.chainId.isSome: - modTx.chainId = custTx.chainId.get - if custTx.gasPriceOrGasFeeCap.isSome: modTx.maxFeePErGas = custTx.gasPriceOrGasFeeCap.get.GasInt @@ -448,7 +444,12 @@ proc customizeTransaction*(sender: TxSender, var address: EthAddress modTx.to = Opt.some(address) - if custTx.signature.isNone: - return signTransaction(modTx, acc.key, modTx.chainId, eip155 = true) + if custTx.signature.isSome: + let signature = custTx.signature.get + modTx.V = signature.V + modTx.R = signature.R + modTx.S = signature.S + else: + modTx.signature = modTx.sign(acc.key, eip155 = true) - return modTx + modTx diff --git a/hive_integration/nodocker/rpc/vault.nim b/hive_integration/nodocker/rpc/vault.nim index 9dce1b396..6fbb7966a 100644 --- a/hive_integration/nodocker/rpc/vault.nim +++ b/hive_integration/nodocker/rpc/vault.nim @@ -94,7 +94,7 @@ proc makeFundingTx*( ) PooledTransaction( - tx: signTransaction(unsignedTx, v.vaultKey, v.chainId, eip155 = true)) + tx: signTransaction(unsignedTx, v.vaultKey)) proc signTx*(v: Vault, sender: EthAddress, @@ -118,7 +118,7 @@ proc signTx*(v: Vault, let key = v.accounts[sender] PooledTransaction( - tx: signTransaction(unsignedTx, key, v.chainId, eip155 = true)) + tx: signTransaction(unsignedTx, key)) # createAccount creates a new account that is funded from the vault contract. # It will panic when the account could not be created and funded. diff --git a/nimbus/core/executor/process_block.nim b/nimbus/core/executor/process_block.nim index baa6a4320..326a51da0 100644 --- a/nimbus/core/executor/process_block.nim +++ b/nimbus/core/executor/process_block.nim @@ -21,6 +21,7 @@ import ./calculate_reward, ./executor_helpers, ./process_transaction, + eth/common/transaction_utils, chronicles, results @@ -40,8 +41,7 @@ proc processTransactions*( vmState.allLogs = @[] for txIndex, tx in transactions: - var sender: EthAddress - if not tx.getSender(sender): + let sender = tx.recoverSender().valueOr: return err("Could not get sender for tx with index " & $(txIndex)) let rc = vmState.processTransaction(tx, sender, header) if rc.isErr: diff --git a/nimbus/core/executor/process_transaction.nim b/nimbus/core/executor/process_transaction.nim index 5bd111da9..414b7c3ee 100644 --- a/nimbus/core/executor/process_transaction.nim +++ b/nimbus/core/executor/process_transaction.nim @@ -66,7 +66,7 @@ proc commitOrRollbackDependingOnGasUsed( proc processTransactionImpl( vmState: BaseVMState; ## Parent accounts environment for transaction tx: Transaction; ## Transaction to validate - sender: EthAddress; ## tx.getSender or tx.ecRecover + sender: EthAddress; ## tx.recoverSender header: BlockHeader; ## Header for the block containing the current tx ): Result[GasInt, string] = ## Modelled after `https://eips.ethereum.org/EIPS/eip-1559#specification`_ @@ -267,7 +267,7 @@ proc processDequeueConsolidationRequests*(vmState: BaseVMState): seq[Request] = proc processTransaction*( vmState: BaseVMState; ## Parent accounts environment for transaction tx: Transaction; ## Transaction to validate - sender: EthAddress; ## tx.getSender or tx.ecRecover + sender: EthAddress; ## tx.recoverSender header: BlockHeader; ## Header for the block containing the current tx ): Result[GasInt,string] = vmState.processTransactionImpl(tx, sender, header) diff --git a/nimbus/core/tx_pool/tx_item.nim b/nimbus/core/tx_pool/tx_item.nim index 9d6fda49d..dba3229d0 100644 --- a/nimbus/core/tx_pool/tx_item.nim +++ b/nimbus/core/tx_pool/tx_item.nim @@ -18,7 +18,7 @@ import ../../utils/utils, ../../transaction, ./tx_info, - eth/[common, keys], + eth/common/transaction_utils, results {.push raises: [].} @@ -62,7 +62,7 @@ proc init*(item: TxItemRef; status: TxItemStatus; info: string) = proc new*(T: type TxItemRef; tx: PooledTransaction; itemID: Hash256; status: TxItemStatus; info: string): Result[T,void] {.gcsafe,raises: [].} = ## Create item descriptor. - let rc = tx.tx.ecRecover + let rc = tx.tx.recoverSender() if rc.isErr: return err() ok(T(itemID: itemID, diff --git a/nimbus/core/validate.nim b/nimbus/core/validate.nim index fe4825321..9180b85ce 100644 --- a/nimbus/core/validate.nim +++ b/nimbus/core/validate.nim @@ -248,7 +248,7 @@ proc validateTxBasic*( proc validateTransaction*( roDB: ReadOnlyStateDB; ## Parent accounts environment for transaction tx: Transaction; ## tx to validate - sender: EthAddress; ## tx.getSender or tx.ecRecover + sender: EthAddress; ## tx.recoverSender maxLimit: GasInt; ## gasLimit from block header baseFee: UInt256; ## baseFee from block header excessBlobGas: uint64; ## excessBlobGas from parent block header diff --git a/nimbus/graphql/ethapi.nim b/nimbus/graphql/ethapi.nim index 24f831d2c..9eae86732 100644 --- a/nimbus/graphql/ethapi.nim +++ b/nimbus/graphql/ethapi.nim @@ -22,7 +22,8 @@ import ../common/common, ../transaction/call_evm, ../core/[tx_pool, tx_pool/tx_item], - ../utils/utils + ../utils/utils, + eth/common/transaction_utils from eth/p2p import EthereumNode export httpserver @@ -629,8 +630,7 @@ proc txFrom(ud: RootRef, params: Args, parent: Node): RespResult {.apiPragma.} = else: tx.blockNumber - var sender: EthAddress - if not getSender(tx.tx, sender): + let sender = tx.tx.recoverSender.valueOr: return ok(respNull()) let hres = ctx.getBlockByNumber(blockNumber) if hres.isErr: @@ -732,8 +732,7 @@ proc txCumulativeGasUsed(ud: RootRef, params: Args, parent: Node): RespResult {. proc txCreatedContract(ud: RootRef, params: Args, parent: Node): RespResult {.apiPragma.} = let ctx = GraphqlContextRef(ud) let tx = TxNode(parent) - var sender: EthAddress - if not getSender(tx.tx, sender): + let sender = tx.tx.recoverSender.valueOr: return err("can't calculate sender") if not tx.tx.contractCreation: diff --git a/nimbus/rpc/p2p.nim b/nimbus/rpc/p2p.nim index 05a26c438..d3eb783ba 100644 --- a/nimbus/rpc/p2p.nim +++ b/nimbus/rpc/p2p.nim @@ -234,9 +234,9 @@ proc setupEthRpc*( let accDB = stateDBFromTag(blockId("latest")) - tx = unsignedTx(data, chainDB, accDB.getNonce(address) + 1) + tx = unsignedTx(data, chainDB, accDB.getNonce(address) + 1, com.chainId) eip155 = com.isEIP155(com.syncCurrent) - signedTx = signTransaction(tx, acc.privateKey, com.chainId, eip155) + signedTx = signTransaction(tx, acc.privateKey, eip155) result = rlp.encode(signedTx) server.rpc("eth_sendTransaction") do(data: TransactionArgs) -> Web3Hash: @@ -254,9 +254,9 @@ proc setupEthRpc*( let accDB = stateDBFromTag(blockId("latest")) - tx = unsignedTx(data, chainDB, accDB.getNonce(address) + 1) + tx = unsignedTx(data, chainDB, accDB.getNonce(address) + 1, com.chainId) eip155 = com.isEIP155(com.syncCurrent) - signedTx = signTransaction(tx, acc.privateKey, com.chainId, eip155) + signedTx = signTransaction(tx, acc.privateKey, eip155) networkPayload = if signedTx.txType == TxEip4844: if data.blobs.isNone or data.commitments.isNone or data.proofs.isNone: diff --git a/nimbus/rpc/rpc_utils.nim b/nimbus/rpc/rpc_utils.nim index 5546a471a..c97fe1932 100644 --- a/nimbus/rpc/rpc_utils.nim +++ b/nimbus/rpc/rpc_utils.nim @@ -26,7 +26,8 @@ import ../evm/state, ../evm/precompiles, ../evm/tracer/access_list_tracer, - ../evm/evm_errors + ../evm/evm_errors, + eth/common/transaction_utils const @@ -91,7 +92,7 @@ proc calculateMedianGasPrice*(chain: CoreDbRef): GasInt const minGasPrice = 30_000_000_000.GasInt result = max(result, minGasPrice) -proc unsignedTx*(tx: TransactionArgs, chain: CoreDbRef, defaultNonce: AccountNonce): Transaction +proc unsignedTx*(tx: TransactionArgs, chain: CoreDbRef, defaultNonce: AccountNonce, chainId: ChainId): Transaction {.gcsafe, raises: [CatchableError].} = if tx.to.isSome: result.to = Opt.some(ethAddr(tx.to.get)) @@ -117,6 +118,7 @@ proc unsignedTx*(tx: TransactionArgs, chain: CoreDbRef, defaultNonce: AccountNon result.nonce = defaultNonce result.payload = tx.payload + result.chainId = chainId proc toWd(wd: Withdrawal): WithdrawalObject = WithdrawalObject( @@ -142,7 +144,8 @@ proc populateTransactionObject*(tx: Transaction, result.blockHash = Opt.some(w3Hash header.blockHash) result.blockNumber = Opt.some(w3BlockNumber(header.number)) - result.`from` = w3Addr tx.getSender() + if (let sender = tx.recoverSender(); sender.isOk): + result.`from` = sender[] result.gas = w3Qty(tx.gasLimit) result.gasPrice = w3Qty(tx.gasPrice) result.hash = w3Hash tx.rlpHash @@ -221,24 +224,22 @@ proc populateBlockObject*(header: BlockHeader, chain: CoreDbRef, fullTx: bool, i result.parentBeaconBlockRoot = Opt.some(w3Hash header.parentBeaconBlockRoot.get) proc populateReceipt*(receipt: Receipt, gasUsed: GasInt, tx: Transaction, - txIndex: uint64, header: BlockHeader): ReceiptObject - {.gcsafe, raises: [ValidationError].} = + txIndex: uint64, header: BlockHeader): ReceiptObject = + let sender = tx.recoverSender() result = ReceiptObject() result.transactionHash = w3Hash tx.rlpHash result.transactionIndex = w3Qty(txIndex) result.blockHash = w3Hash header.blockHash result.blockNumber = w3BlockNumber(header.number) - result.`from` = w3Addr tx.getSender() + if sender.isSome(): + result.`from` = sender.get() result.to = Opt.some(w3Addr tx.destination) result.cumulativeGasUsed = w3Qty(receipt.cumulativeGasUsed) result.gasUsed = w3Qty(gasUsed) result.`type` = Opt.some Quantity(receipt.receiptType) - if tx.contractCreation: - var sender: EthAddress - if tx.getSender(sender): - let contractAddress = generateAddress(sender, tx.nonce) - result.contractAddress = Opt.some(w3Addr contractAddress) + if tx.contractCreation and sender.isSome: + result.contractAddress = Opt.some(tx.creationAddress(sender[])) for log in receipt.logs: # TODO: Work everywhere with either `Hash256` as topic or `array[32, byte]` diff --git a/nimbus/rpc/server_api_helpers.nim b/nimbus/rpc/server_api_helpers.nim index 54354d7ef..ff6c32141 100644 --- a/nimbus/rpc/server_api_helpers.nim +++ b/nimbus/rpc/server_api_helpers.nim @@ -10,7 +10,7 @@ {.push raises: [].} import - eth/common/eth_types, + eth/common/[eth_types, transaction_utils], eth/common/eth_types_rlp, web3/eth_api_types, ../beacon/web3_eth_conv, @@ -44,9 +44,8 @@ proc populateTransactionObject*(tx: Transaction, result.blockHash = w3Hash optionalHash result.blockNumber = w3BlockNumber optionalNumber - var sender: EthAddress - if tx.getSender(sender): - result.`from` = w3Addr sender + if (let sender = tx.recoverSender(); sender.isOk): + result.`from` = sender[] result.gas = w3Qty(tx.gasLimit) result.gasPrice = w3Qty(tx.gasPrice) result.hash = w3Hash tx.rlpHash diff --git a/nimbus/tracer.nim b/nimbus/tracer.nim index 6019a3dbe..8215c7a37 100644 --- a/nimbus/tracer.nim +++ b/nimbus/tracer.nim @@ -15,6 +15,7 @@ import nimcrypto/utils as ncrutils, results, web3/conversions, + eth/common/transaction_utils, ./beacon/web3_eth_conv, ./common/common, ./constants, @@ -187,7 +188,7 @@ proc traceTransactionImpl( miner = vmState.coinbase() for idx, tx in transactions: - let sender = tx.getSender + let sender = tx.recoverSender().expect("valid signature") let recipient = tx.getRecipient(sender) if idx.uint64 == txIndex: @@ -263,7 +264,7 @@ proc dumpBlockStateImpl( stateBefore = LedgerRef.init(com.db, parent.stateRoot, storeSlotHash = true) for idx, tx in blk.transactions: - let sender = tx.getSender + let sender = tx.recoverSender().expect("valid signature") let recipient = tx.getRecipient(sender) before.captureAccount(stateBefore, sender, senderName & $idx) before.captureAccount(stateBefore, recipient, recipientName & $idx) @@ -278,7 +279,7 @@ proc dumpBlockStateImpl( var stateAfter = vmState.stateDB for idx, tx in blk.transactions: - let sender = tx.getSender + let sender = tx.recoverSender().expect("valid signature") let recipient = tx.getRecipient(sender) after.captureAccount(stateAfter, sender, senderName & $idx) after.captureAccount(stateAfter, recipient, recipientName & $idx) @@ -329,7 +330,7 @@ proc traceBlockImpl( for tx in blk.transactions: let - sender = tx.getSender + sender = tx.recoverSender().expect("valid signature") rc = vmState.processTransaction(tx, sender, header) if rc.isOk: gasUsed = gasUsed + rc.value diff --git a/nimbus/transaction.nim b/nimbus/transaction.nim index ba21b2f4c..4b4177bc4 100644 --- a/nimbus/transaction.nim +++ b/nimbus/transaction.nim @@ -6,11 +6,12 @@ # at your option. This file may not be copied, modified, or distributed except according to those terms. import - ./constants, ./errors, eth/[common, keys], ./utils/utils, - common/evmforks, ./evm/internals + ./[constants, errors], + ./common/evmforks, + ./evm/interpreter/gas_costs, + eth/common/[addresses, keys, transactions, transactions_rlp, transaction_utils] -import eth/common/transaction as common_transaction -export common_transaction, errors +export addresses, keys, transactions proc toWordSize(size: GasInt): GasInt = # Round input to the nearest bigger multiple of 32 @@ -48,54 +49,6 @@ proc intrinsicGas*(tx: Transaction, fork: EVMFork): GasInt = inc(numKeys, n.storageKeys.len) result += GasInt(numKeys) * ACCESS_LIST_STORAGE_KEY_COST -proc getSignature*(tx: Transaction, output: var Signature): bool = - var bytes: array[65, byte] - bytes[0..31] = tx.R.toBytesBE() - bytes[32..63] = tx.S.toBytesBE() - - if tx.txType == TxLegacy: - var v = tx.V - if v >= EIP155_CHAIN_ID_OFFSET: - v = 28 - (v and 0x01) - elif v == 27 or v == 28: - discard - else: - return false - bytes[64] = byte(v - 27) - else: - bytes[64] = tx.V.byte - - let sig = Signature.fromRaw(bytes) - if sig.isOk: - output = sig[] - return true - return false - -proc toSignature*(tx: Transaction): Signature = - if not getSignature(tx, result): - raise newException(Exception, "Invalid signature") - -proc getSender*(tx: Transaction, output: var EthAddress): bool = - ## Find the address the transaction was sent from. - var sig: Signature - if tx.getSignature(sig): - var txHash = tx.txHashNoSignature - let pubkey = recover(sig, SkMessage(txHash.data)) - if pubkey.isOk: - output = pubkey[].toCanonicalAddress() - result = true - -proc getSender*(tx: Transaction): EthAddress = - ## Raises error on failure to recover public key - if not tx.getSender(result): - raise newException(ValidationError, "Could not derive sender address from transaction") - -proc getRecipient*(tx: Transaction, sender: EthAddress): EthAddress = - if tx.contractCreation: - result = generateAddress(sender, tx.nonce) - else: - result = tx.to.get() - proc validateTxLegacy(tx: Transaction, fork: EVMFork) = var vMin = 27'u64 @@ -155,6 +108,8 @@ proc validateTxEip7702(tx: Transaction) = raise newException(ValidationError, "Invalid EIP-7702 transaction") proc validate*(tx: Transaction, fork: EVMFork) = + # TODO it doesn't seem like this function is called from anywhere except tests + # which feels like it might be a problem (?) # parameters pass validation rules if tx.intrinsicGas(fork) > tx.gasLimit: raise newException(ValidationError, "Insufficient gas") @@ -163,8 +118,10 @@ proc validate*(tx: Transaction, fork: EVMFork) = raise newException(ValidationError, "Initcode size exceeds max") # check signature validity - var sender: EthAddress - if not tx.getSender(sender): + # TODO a validation function like this should probably be returning the sender + # since recovering the public key accounts for ~10% of block processing + # time (at the time of writing) + let sender = tx.recoverSender().valueOr: raise newException(ValidationError, "Invalid signature or failed message verification") case tx.txType @@ -177,27 +134,9 @@ proc validate*(tx: Transaction, fork: EVMFork) = of TxEip7702: validateTxEip7702(tx) -proc signTransaction*(tx: Transaction, privateKey: PrivateKey, chainId: ChainId, eip155: bool): Transaction = +proc signTransaction*(tx: Transaction, privateKey: PrivateKey, eip155 = true): Transaction = result = tx - if eip155: - # trigger rlpEncodeEIP155 in nim-eth - result.V = chainId.uint64 * 2'u64 + 35'u64 - - let - rlpTx = rlpEncode(result) - sig = sign(privateKey, rlpTx).toRaw - - case tx.txType - of TxLegacy: - if eip155: - result.V = sig[64].uint64 + result.V - else: - result.V = sig[64].uint64 + 27'u64 - else: - result.V = sig[64].uint64 - - result.R = UInt256.fromBytesBE(sig[0..31]) - result.S = UInt256.fromBytesBE(sig[32..63]) + result.signature = result.sign(privateKey, eip155) # deriveChainId derives the chain id from the given v parameter func deriveChainId*(v: uint64, chainId: ChainId): ChainId = diff --git a/nimbus/utils/ec_recover.nim b/nimbus/utils/ec_recover.nim index 1bc57b08d..a2ffe662d 100644 --- a/nimbus/utils/ec_recover.nim +++ b/nimbus/utils/ec_recover.nim @@ -51,23 +51,6 @@ type # Private helpers # ------------------------------------------------------------------------------ -proc vrsSerialised(tx: Transaction): Result[array[65,byte],UtilsError] = - ## Parts copied from `transaction.getSignature`. - var data: array[65,byte] - data[0..31] = tx.R.toBytesBE - data[32..63] = tx.S.toBytesBE - - if tx.txType != TxLegacy: - data[64] = tx.V.byte - elif tx.V >= EIP155_CHAIN_ID_OFFSET: - data[64] = byte(1 - (tx.V and 1)) - elif tx.V == 27 or tx.V == 28: - data[64] = byte(tx.V - 27) - else: - return err((errSigPrefixError,"")) # legacy error - - ok(data) - proc encodePreSealed(header: BlockHeader): seq[byte] = ## Cut sigature off `extraData` header field. if header.extraData.len < EXTRA_SEAL: @@ -113,22 +96,6 @@ proc ecRecover*(header: BlockHeader): EcAddrResult = ## the argument header. header.extraData.recoverImpl(header.hashPreSealed) -proc ecRecover*(tx: var Transaction): EcAddrResult = - ## Extracts sender address from transaction. This function has similar - ## functionality as `transaction.getSender()`. - let txSig = tx.vrsSerialised - if txSig.isErr: - return err(txSig.error) - try: - result = txSig.value.recoverImpl(tx.txHashNoSignature) - except ValueError as ex: - return err((errTxEncError, ex.msg)) - -proc ecRecover*(tx: Transaction): EcAddrResult = - ## Variant of `ecRecover()` for call-by-value header. - var ty = tx - ty.ecRecover - # ------------------------------------------------------------------------------ # Public constructor for caching ecRecover version # ------------------------------------------------------------------------------ diff --git a/premix/parser.nim b/premix/parser.nim index 087b95469..3271ad0a4 100644 --- a/premix/parser.nim +++ b/premix/parser.nim @@ -9,7 +9,7 @@ # according to those terms. import - json, strutils, os, + json, strutils, os, eth/common/transaction_utils, eth/common, httputils, nimcrypto/utils, stint, stew/byteutils @@ -196,7 +196,7 @@ proc parseWithdrawal*(n: JsonNode): Withdrawal = n.fromJson "amount", result.amount proc validateTxSenderAndHash*(n: JsonNode, tx: Transaction) = - var sender = tx.getSender() + var sender = tx.recoverSender().expect("valid signature") var fromAddr: EthAddress n.fromJson "from", fromAddr doAssert sender.to0xHex == fromAddr.to0xHex diff --git a/premix/premixcore.nim b/premix/premixcore.nim index 1ac9b14e1..f8eff5607 100644 --- a/premix/premixcore.nim +++ b/premix/premixcore.nim @@ -10,7 +10,7 @@ import json, strutils, os, - chronicles, eth/common, + chronicles, eth/common, eth/common/transaction_utils, ../nimbus/transaction, ../nimbus/launcher, ./js_tracer, ./parser, ./downloader @@ -157,7 +157,8 @@ proc requestPostState*(premix, n: JsonNode, blockNumber: BlockNumber) = for t in txs: var txKind = TxKind.Regular let tx = parseTransaction(t) - let sender = tx.getSender + let sender = tx.recoverSender().valueOr: + raise (ref ValueError)(msg: "Invalid tx signature") if tx.contractCreation: txKind = TxKind.ContractCreation if hasInternalTx(tx, blockNumber, sender): let txTrace = requestInternalTx(t["hash"], tracer) diff --git a/tests/all_tests.nim b/tests/all_tests.nim index 21e4f4b92..d2060c922 100644 --- a/tests/all_tests.nim +++ b/tests/all_tests.nim @@ -37,7 +37,6 @@ cliBuilder: #./test_txpool, -- fails ./test_txpool2, ./test_engine_api, - ./test_eip4844, ./test_getproof_json, ./test_aristo, ./test_coredb diff --git a/tests/macro_assembler.nim b/tests/macro_assembler.nim index f20cdfcb7..10988d31c 100644 --- a/tests/macro_assembler.nim +++ b/tests/macro_assembler.nim @@ -10,7 +10,7 @@ import std/[macrocache, strutils], - eth/keys, + eth/common/[keys, transaction_utils], unittest2, chronicles, stew/byteutils, @@ -384,9 +384,10 @@ proc createSignedTx(payload: Blob, chainId: ChainId): Transaction = to: Opt.some codeAddress, value: 500.u256, payload: payload, + chainId: chainId, versionedHashes: @[VersionedHash(EMPTY_UNCLE_HASH), VersionedHash(EMPTY_SHA3)] ) - signTransaction(unsignedTx, privateKey, chainId, false) + signTransaction(unsignedTx, privateKey, false) proc runVM*(vmState: BaseVMState, boa: Assembler): bool = let @@ -395,7 +396,7 @@ proc runVM*(vmState: BaseVMState, boa: Assembler): bool = db.setCode(codeAddress, boa.code) db.setBalance(codeAddress, 1_000_000.u256) let tx = createSignedTx(boa.data, com.chainId) - let asmResult = testCallEvm(tx, tx.getSender, vmState) + let asmResult = testCallEvm(tx, tx.recoverSender().expect("valid signature"), vmState) verifyAsmResult(vmState, boa, asmResult) macro assembler*(list: untyped): untyped = diff --git a/tests/persistBlockTestGen.nim b/tests/persistBlockTestGen.nim index f18cbbdbf..9717f8bc3 100644 --- a/tests/persistBlockTestGen.nim +++ b/tests/persistBlockTestGen.nim @@ -106,7 +106,7 @@ proc main() {.used.} = #chainDB.dumpTest(2_283_416) # first DDOS spam attack block com.dumpTest(2_463_413) # tangerine call* gas cost bug com.dumpTest(2_675_000) # spurious dragon first block - com.dumpTest(2_675_002) # EIP155 tx.getSender + com.dumpTest(2_675_002) # EIP155 tx.recoverSender com.dumpTest(4_370_000) # Byzantium first block when isMainModule: diff --git a/tests/test_eip4844.nim b/tests/test_eip4844.nim deleted file mode 100644 index f6478c6f8..000000000 --- a/tests/test_eip4844.nim +++ /dev/null @@ -1,157 +0,0 @@ -# Nimbus -# Copyright (c) 2023-2024 Status Research & Development GmbH -# Licensed under either of -# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or -# http://www.apache.org/licenses/LICENSE-2.0) -# * MIT license ([LICENSE-MIT](LICENSE-MIT) or -# http://opensource.org/licenses/MIT) -# at your option. This file may not be copied, modified, or distributed except -# according to those terms. - -import - stew/byteutils, - unittest2, - eth/[common, keys], - ../nimbus/transaction - -const - recipient = address"095e7baea6a6c7c4c2dfeb977efac326af552d87" - source = address"0x0000000000000000000000000000000000000001" - storageKey= default(StorageKey) - accesses = @[AccessPair(address: source, storageKeys: @[storageKey])] - abcdef = hexToSeqByte("abcdef") - hexKey = "af1a9be9f1a54421cac82943820a0fe0f601bb5f4f6d0bccc81c613f0ce6ae22" - senderTop = address"73cf19657412508833f618a15e8251306b3e6ee5" - -proc tx0(i: int): Transaction = - Transaction( - txType: TxLegacy, - nonce: i.AccountNonce, - to: Opt.some recipient, - gasLimit: 1.GasInt, - gasPrice: 2.GasInt, - payload: abcdef) - -proc tx1(i: int): Transaction = - Transaction( - # Legacy tx contract creation. - txType: TxLegacy, - nonce: i.AccountNonce, - gasLimit: 1.GasInt, - gasPrice: 2.GasInt, - payload: abcdef) - -proc tx2(i: int): Transaction = - Transaction( - # Tx with non-zero access list. - txType: TxEip2930, - chainId: 1.ChainId, - nonce: i.AccountNonce, - to: Opt.some recipient, - gasLimit: 123457.GasInt, - gasPrice: 10.GasInt, - accessList: accesses, - payload: abcdef) - -proc tx3(i: int): Transaction = - Transaction( - # Tx with empty access list. - txType: TxEip2930, - chainId: 1.ChainId, - nonce: i.AccountNonce, - to: Opt.some recipient, - gasLimit: 123457.GasInt, - gasPrice: 10.GasInt, - payload: abcdef) - -proc tx4(i: int): Transaction = - Transaction( - # Contract creation with access list. - txType: TxEip2930, - chainId: 1.ChainId, - nonce: i.AccountNonce, - gasLimit: 123457.GasInt, - gasPrice: 10.GasInt, - accessList: accesses) - -proc tx5(i: int): Transaction = - Transaction( - txType: TxEip1559, - chainId: 1.ChainId, - nonce: i.AccountNonce, - gasLimit: 123457.GasInt, - maxPriorityFeePerGas: 42.GasInt, - maxFeePerGas: 10.GasInt, - accessList: accesses) - -proc tx6(i: int): Transaction = - const - digest = hash32"010657f37554c781402a22917dee2f75def7ab966d7b770905398eba3c444014" - - Transaction( - txType: TxEip4844, - chainId: 1.ChainId, - nonce: i.AccountNonce, - gasLimit: 123457.GasInt, - maxPriorityFeePerGas:42.GasInt, - maxFeePerGas: 10.GasInt, - accessList: accesses, - versionedHashes: @[digest] - ) - -proc tx7(i: int): Transaction = - const - digest = hash32"01624652859a6e98ffc1608e2af0147ca4e86e1ce27672d8d3f3c9d4ffd6ef7e" - - Transaction( - txType: TxEip4844, - chainID: 1.ChainId, - nonce: i.AccountNonce, - gasLimit: 123457.GasInt, - maxPriorityFeePerGas:42.GasInt, - maxFeePerGas: 10.GasInt, - accessList: accesses, - versionedHashes: @[digest], - maxFeePerBlobGas: 10000000.u256, - ) - -proc tx8(i: int): Transaction = - const - digest = hash32"01624652859a6e98ffc1608e2af0147ca4e86e1ce27672d8d3f3c9d4ffd6ef7e" - - Transaction( - txType: TxEip4844, - chainID: 1.ChainId, - nonce: i.AccountNonce, - to: Opt.some recipient, - gasLimit: 123457.GasInt, - maxPriorityFeePerGas:42.GasInt, - maxFeePerGas: 10.GasInt, - accessList: accesses, - versionedHashes: @[digest], - maxFeePerBlobGas: 10000000.u256, - ) - -proc privKey(keyHex: string): PrivateKey = - let kRes = PrivateKey.fromHex(keyHex) - if kRes.isErr: - echo kRes.error - quit(QuitFailure) - - kRes.get() - -proc eip4844Main*() = - var signerKey = privKey(hexKey) - - suite "EIP4844 sign transaction": - let txs = @[tx0(3), tx1(3), tx2(3), tx3(3), tx4(3), - tx5(3), tx6(3), tx7(3), tx8(3)] - - test "sign transaction": - for tx in txs: - let signedTx = signTransaction(tx, signerKey, 1.ChainId, true) - let sender = signedTx.getSender() - check sender == senderTop - -when isMainModule: - eip4844Main() diff --git a/tests/test_evm_support.nim b/tests/test_evm_support.nim index a590ee2ef..e4ada04f9 100644 --- a/tests/test_evm_support.nim +++ b/tests/test_evm_support.nim @@ -10,6 +10,7 @@ import unittest2, stew/byteutils, eth/keys, + eth/common/transaction_utils, ../nimbus/common, ../nimbus/transaction, ../nimbus/evm/types, @@ -358,8 +359,8 @@ proc runTestOverflow() = ) let privateKey = PrivateKey.fromHex("0000000000000000000000000000000000000000000000000000001000000000")[] - let tx = signTransaction(unsignedTx, privateKey, ChainId(1), false) - let res = testCallEvm(tx, tx.getSender, s) + let tx = signTransaction(unsignedTx, privateKey, false) + let res = testCallEvm(tx, tx.recoverSender().expect("valid signature"), s) when defined(evmc_enabled): check res.error == "EVMC_FAILURE" diff --git a/tests/test_generalstate_json.nim b/tests/test_generalstate_json.nim index 64502d187..484bf217f 100644 --- a/tests/test_generalstate_json.nim +++ b/tests/test_generalstate_json.nim @@ -20,6 +20,7 @@ import ../tools/evmstate/helpers, ../tools/common/state_clearing, eth/trie/trie_defs, + eth/common/transaction_utils, unittest2, stew/byteutils, results @@ -101,7 +102,7 @@ proc testFixtureIndexes(ctx: var TestCtx, testStatusIMPL: var TestStatus) = ) var gasUsed: GasInt - let sender = ctx.tx.getSender() + let sender = ctx.tx.recoverSender().expect("valid signature") vmState.mutateStateDB: setupStateDB(ctx.pre, db) diff --git a/tests/test_ledger.nim b/tests/test_ledger.nim index 574d04b18..2d78fc275 100644 --- a/tests/test_ledger.nim +++ b/tests/test_ledger.nim @@ -11,6 +11,7 @@ import std/[strformat, strutils, importutils], eth/keys, + eth/common/transaction_utils, stew/byteutils, stew/endians2, ../nimbus/config, @@ -53,13 +54,13 @@ proc pp*(a: EthAddress): string = proc pp*(tx: Transaction): string = # "(" & tx.ecRecover.value.pp & "," & $tx.nonce & ")" - "(" & tx.getSender.pp & "," & $tx.nonce & ")" + "(" & tx.recoverSender().value().pp & "," & $tx.nonce & ")" proc pp*(h: KeccakHash): string = h.data.toHex[52 .. 63].toLowerAscii proc pp*(tx: Transaction; ledger: LedgerRef): string = - let address = tx.getSender + let address = tx.recoverSender().value() "(" & address.pp & "," & $tx.nonce & ";" & $ledger.getNonce(address) & @@ -134,7 +135,7 @@ func makeTx( ) inc env.nonce - signTransaction(tx, env.vaultKey, env.chainId, eip155 = true) + signTransaction(tx, env.vaultKey, eip155 = true) func initAddr(z: int): EthAddress = const L = sizeof(result) diff --git a/tests/test_precompiles.nim b/tests/test_precompiles.nim index 07c679507..061baa152 100644 --- a/tests/test_precompiles.nim +++ b/tests/test_precompiles.nim @@ -9,6 +9,7 @@ import std/[strformat, strutils, json, os, tables, macros], unittest2, stew/byteutils, eth/[keys, trie], + eth/common/transaction_utils, ../nimbus/common/common, ../tools/common/helpers as chp, ../nimbus/[evm/computation, @@ -42,10 +43,11 @@ template doTest(fixture: JsonNode; vmState: BaseVMState; address: PrecompileAddr gasLimit: 1_000_000_000.GasInt, to: Opt.some initAddress(address.byte), value: 0.u256, + chainId: ChainId(1), payload: if dataStr.len > 0: dataStr.hexToSeqByte else: @[] ) - let tx = signTransaction(unsignedTx, privateKey, ChainId(1), false) - let fixtureResult = testCallEvm(tx, tx.getSender, vmState) + let tx = signTransaction(unsignedTx, privateKey, false) + let fixtureResult = testCallEvm(tx, tx.recoverSender().expect("valid signature"), vmState) if expectedErr: check fixtureResult.isError diff --git a/tests/test_rpc.nim b/tests/test_rpc.nim index b721fced0..3f16b28c1 100644 --- a/tests/test_rpc.nim +++ b/tests/test_rpc.nim @@ -12,6 +12,7 @@ import json_rpc/[rpcserver, rpcclient], nimcrypto/[keccak, hash], eth/[rlp, keys, trie/hexary_proof_verification], + eth/common/transaction_utils, ../nimbus/[constants, transaction, config, evm/state, evm/types, version], ../nimbus/db/[ledger, storage_types], ../nimbus/sync/protocol, @@ -139,7 +140,8 @@ proc setupEnv(com: CommonRef, signer, ks2: EthAddress, ctx: EthContext): TestEnv gasPrice: 30_000_000_000, gasLimit: 70_000, value : 1.u256, - to : some(zeroAddress) + to : some(zeroAddress), + chainId : com.chainId, ) unsignedTx2 = Transaction( txType : TxLegacy, @@ -147,11 +149,12 @@ proc setupEnv(com: CommonRef, signer, ks2: EthAddress, ctx: EthContext): TestEnv gasPrice: 30_000_000_100, gasLimit: 70_000, value : 2.u256, - to : some(zeroAddress) + to : some(zeroAddress), + chainId : com.chainId, ) eip155 = com.isEIP155(com.syncCurrent) - signedTx1 = signTransaction(unsignedTx1, acc.privateKey, com.chainId, eip155) - signedTx2 = signTransaction(unsignedTx2, acc.privateKey, com.chainId, eip155) + signedTx1 = signTransaction(unsignedTx1, acc.privateKey, eip155) + signedTx2 = signTransaction(unsignedTx2, acc.privateKey, eip155) txs = [signedTx1, signedTx2] let txRoot = calcTxRoot(txs) @@ -160,7 +163,7 @@ proc setupEnv(com: CommonRef, signer, ks2: EthAddress, ctx: EthContext): TestEnv vmState.receipts = newSeq[Receipt](txs.len) vmState.cumulativeGasUsed = 0 for txIndex, tx in txs: - let sender = tx.getSender() + let sender = tx.recoverSender().expect("valid signature") let rc = vmState.processTransaction(tx, sender, vmHeader) doAssert(rc.isOk, "Invalid transaction: " & rc.error) vmState.receipts[txIndex] = makeReceipt(vmState, tx.txType) @@ -400,7 +403,7 @@ proc rpcMain*() = let signedTxBytes = await client.eth_signTransaction(unsignedTx) let signedTx = rlp.decode(signedTxBytes, Transaction) - check signer == signedTx.getSender() # verified + check signer == signedTx.recoverSender().expect("valid signature") # verified let hashAhex = await client.eth_sendTransaction(unsignedTx) let hashBhex = await client.eth_sendRawTransaction(signedTxBytes) diff --git a/tests/test_transaction_json.nim b/tests/test_transaction_json.nim index e75d27507..8a8fc2ac6 100644 --- a/tests/test_transaction_json.nim +++ b/tests/test_transaction_json.nim @@ -13,6 +13,7 @@ import unittest2, eth/rlp, ./test_helpers, + eth/common/transaction_utils, ../nimbus/[errors, transaction], ../nimbus/utils/utils @@ -29,7 +30,7 @@ when isMainModule: transactionJsonMain() proc txHash(tx: Transaction): string = - toLowerAscii($keccakHash(rlp.encode(tx))) + rlpHash(tx).toHex() proc testTxByFork(tx: Transaction, forkData: JsonNode, forkName: string, testStatusIMPL: var TestStatus) = try: @@ -41,7 +42,7 @@ proc testTxByFork(tx: Transaction, forkData: JsonNode, forkName: string, testSta let sender = EthAddress.fromHex(forkData["sender"].getStr) check "hash" in forkData check tx.txHash == forkData["hash"].getStr - check tx.getSender == sender + check tx.recoverSender().expect("valid signature") == sender func noHash(fixture: JsonNode): bool = result = true diff --git a/tests/test_txpool/setup.nim b/tests/test_txpool/setup.nim index f3ea80820..d849c00cb 100644 --- a/tests/test_txpool/setup.nim +++ b/tests/test_txpool/setup.nim @@ -16,6 +16,7 @@ import ../../nimbus/utils/ec_recover, ../../nimbus/core/tx_pool/[tx_chain, tx_item], ../../nimbus/transaction, + eth/common/transaction_utils, ./helpers, eth/[keys, p2p], stew/[keyed_queue, byteutils] @@ -69,7 +70,7 @@ proc fillGenesis(env: var TxEnv, param: NetworkParams) = for z in n: let bytes = hexToSeqByte(z.getStr) let tx = rlp.decode(bytes, Transaction) - let sender = tx.getSender() + let sender = tx.recoverSender().expect("valid signature") let bal = map.getOrDefault(sender, 0.u256) if bal + tx.value > 0: map[sender] = bal + tx.value @@ -99,10 +100,10 @@ proc setupTxPool*(getStatus: proc(): TxItemStatus): (CommonRef, TxPoolRef, int) let txPool = TxPoolRef.new(com) for n, tx in txEnv.txs: - let s = txEnv.getSigner(tx.getSender()) + let s = txEnv.getSigner(tx.recoverSender().expect("valid signature")) let status = statusInfo[getStatus()] let info = &"{n}/{txEnv.txs.len} {status}" - let signedTx = signTransaction(tx, s.signer, txEnv.chainId, eip155 = true) + let signedTx = signTransaction(tx, s.signer, eip155 = true) txPool.add(PooledTransaction(tx: signedTx), info) (com, txPool, txEnv.txs.len) diff --git a/tests/test_txpool/sign_helper.nim b/tests/test_txpool/sign_helper.nim index 3b864c33a..61d60f614 100644 --- a/tests/test_txpool/sign_helper.nim +++ b/tests/test_txpool/sign_helper.nim @@ -9,7 +9,7 @@ # according to those terms. import - ../../nimbus/constants, + ../../nimbus/[constants, transaction], ../../nimbus/utils/ec_recover, ../../nimbus/core/tx_pool/tx_item, eth/[common, common/transaction, keys], @@ -20,35 +20,6 @@ const # example from clique, signer: 658bdf435d810c91414ec09147daa6db62406379 prvKey = "9c647b8b7c4e7c3490668fb6c11473619db80c93704c70893d3813af4090c39c" -proc signature(tx: Transaction; key: PrivateKey): (uint64,UInt256,UInt256) = - let - hashData = tx.txHashNoSignature.data - signature = key.sign(SkMessage(hashData)).toRaw - v = signature[64].uint64 - - result[1] = UInt256.fromBytesBE(signature[0..31]) - result[2] = UInt256.fromBytesBE(signature[32..63]) - - if tx.txType == TxLegacy: - if tx.V >= EIP155_CHAIN_ID_OFFSET: - # just a guess which does not always work .. see `txModPair()` - # see https://eips.ethereum.org/EIPS/eip-155 - result[0] = (tx.V and not 1'u64) or (not v and 1'u64) - else: - result[0] = 27 + v - else: - # currently unsupported, will skip this one .. see `txModPair()` - result[0] = 0'u64 - - -proc sign(tx: Transaction; key: PrivateKey): Transaction = - let (V,R,S) = tx.signature(key) - result = tx - result.V = V - result.R = R - result.S = S - - proc sign(header: BlockHeader; key: PrivateKey): BlockHeader = let hashData = header.blockHash.data @@ -73,14 +44,14 @@ proc txModPair*(item: TxItemRef; nonce: int; priceBump: int): tx1.gasPrice = (tx0.gasPrice * (100 + priceBump).GasInt + 99.GasInt) div 100 let - tx0Signed = tx0.sign(prvTestKey) - tx1Signed = tx1.sign(prvTestKey) + tx0Signed = tx0.signTransaction(prvTestKey) + tx1Signed = tx0.signTransaction(prvTestKey) block: - let rc = tx0Signed.ecRecover + let rc = tx0Signed.recoverSender() if rc.isErr or rc.value != testAddress: return block: - let rc = tx1Signed.ecRecover + let rc = tx1Signed.recoverSender() if rc.isErr or rc.value != testAddress: return (item,tx0Signed,tx1Signed) diff --git a/tests/test_txpool2.nim b/tests/test_txpool2.nim index 48c92b997..4a285910f 100644 --- a/tests/test_txpool2.nim +++ b/tests/test_txpool2.nim @@ -77,13 +77,13 @@ func makeTx( ) inc t.nonce - signTransaction(tx, t.vaultKey, t.chainId, eip155 = true) + signTransaction(tx, t.vaultKey, eip155 = true) func signTxWithNonce( t: TestEnv, tx: Transaction, nonce: AccountNonce): Transaction = var tx = tx tx.nonce = nonce - signTransaction(tx, t.vaultKey, t.chainId, eip155 = true) + signTransaction(tx, t.vaultKey, eip155 = true) proc initEnv(envFork: HardFork): TestEnv = var diff --git a/tools/evmstate/evmstate.nim b/tools/evmstate/evmstate.nim index 3428558bb..3b3ddef80 100644 --- a/tools/evmstate/evmstate.nim +++ b/tools/evmstate/evmstate.nim @@ -12,6 +12,7 @@ import std/[json, strutils, sets, tables, options, streams], chronicles, eth/keys, + eth/common/transaction_utils, stew/byteutils, results, stint, @@ -68,7 +69,7 @@ method getAncestorHash(vmState: TestVMState; blockNumber: BlockNumber): Hash256 keccakHash(toBytes($blockNumber)) proc verifyResult(ctx: var StateContext, vmState: BaseVMState, obtainedHash: Hash256) = - ctx.error = "" + ctx.error = "" if obtainedHash != ctx.expectedHash: ctx.error = "post state root mismatch: got $1, want $2" % [($obtainedHash).toLowerAscii, $ctx.expectedHash] @@ -129,7 +130,7 @@ proc runExecution(ctx: var StateContext, conf: StateConf, pre: JsonNode): StateR tracer = tracer) var gasUsed: GasInt - let sender = ctx.tx.getSender() + let sender = ctx.tx.recoverSender().expect("valid signature") vmState.mutateStateDB: setupStateDB(pre, db) diff --git a/tools/evmstate/helpers.nim b/tools/evmstate/helpers.nim index 92192fc2c..61d9da25e 100644 --- a/tools/evmstate/helpers.nim +++ b/tools/evmstate/helpers.nim @@ -147,7 +147,7 @@ proc parseTx*(n: JsonNode, dataIndex, gasIndex, valueIndex: int): Transaction = tx.to = Opt.some(EthAddress.fromHex(rawTo)) let secretKey = required(PrivateKey, "secretKey") - signTransaction(tx, secretKey, tx.chainId, false) + signTransaction(tx, secretKey, false) proc parseTx*(txData, index: JsonNode): Transaction = let diff --git a/tools/t8n/helpers.nim b/tools/t8n/helpers.nim index dd303f906..c70abb8b0 100644 --- a/tools/t8n/helpers.nim +++ b/tools/t8n/helpers.nim @@ -228,6 +228,7 @@ proc parseTx(n: JsonNode, chainId: ChainID): Transaction = if n.hasKey("to"): tx.to = Opt.some(EthAddress.fromJson(n, "to")) + tx.chainId = chainId case tx.txType of TxLegacy: @@ -262,7 +263,7 @@ proc parseTx(n: JsonNode, chainId: ChainID): Transaction = if n.hasKey("secretKey"): let data = Blob.fromJson(n, "secretKey") let secretKey = PrivateKey.fromRaw(data).tryGet - signTransaction(tx, secretKey, chainId, eip155) + signTransaction(tx, secretKey, eip155) else: required(tx, uint64, v) required(tx, UInt256, r) diff --git a/tools/t8n/transition.nim b/tools/t8n/transition.nim index c74ef6651..6d30d8dc4 100644 --- a/tools/t8n/transition.nim +++ b/tools/t8n/transition.nim @@ -11,6 +11,7 @@ import std/[json, strutils, tables, os, streams], eth/[rlp, trie, eip1559], + eth/common/transaction_utils, stint, results, "."/[config, types, helpers], ../common/state_clearing, @@ -256,8 +257,7 @@ proc exec(ctx: var TransContext, continue let tx = txRes.get - var sender: EthAddress - if not tx.getSender(sender): + let sender = tx.recoverSender().valueOr: rejected.add RejectedTx( index: txIndex, error: "Could not get sender" diff --git a/tools/txparse/txparse.nim b/tools/txparse/txparse.nim index a0780b65f..032554111 100644 --- a/tools/txparse/txparse.nim +++ b/tools/txparse/txparse.nim @@ -1,5 +1,5 @@ # Nimbus -# Copyright (c) 2022 Status Research & Development GmbH +# Copyright (c) 2022-2024 Status Research & Development GmbH # Licensed under either of # * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or # http://www.apache.org/licenses/LICENSE-2.0) @@ -11,6 +11,7 @@ import eth/[common, rlp], stew/byteutils, + eth/common/transaction_utils, ../../nimbus/transaction, ../../nimbus/common/evmforks @@ -19,7 +20,7 @@ proc parseTx(hexLine: string) = let bytes = hexToSeqByte(hexLine) tx = decodeTx(bytes) - address = tx.getSender() + address = tx.recoverSender().expect("valid signature") tx.validate(FkLondon) @@ -30,8 +31,6 @@ proc parseTx(hexLine: string) = echo "err: ", ex.msg except ValueError as ex: echo "err: ", ex.msg - except ValidationError as ex: - echo "err: ", ex.msg except Exception: # TODO: rlp.hasData assertion should be # changed into RlpError diff --git a/vendor/nim-eth b/vendor/nim-eth index 792b8b9bf..4ea11b9fb 160000 --- a/vendor/nim-eth +++ b/vendor/nim-eth @@ -1 +1 @@ -Subproject commit 792b8b9bff09a5ed7cc98bc12b0c3d991e019b6f +Subproject commit 4ea11b9fb9c6a0ab0886b5deca94a3d4f669386d diff --git a/vendor/nim-web3 b/vendor/nim-web3 index 62a0005b0..c38791832 160000 --- a/vendor/nim-web3 +++ b/vendor/nim-web3 @@ -1 +1 @@ -Subproject commit 62a0005b0907a64090827d4e5d691682587f5b2a +Subproject commit c38791832cac2d23eab57cdc32decdd8123e5d36