Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implementation of EIP-4844: Shard Blob Transactions #1440

Merged
merged 15 commits into from
Jun 24, 2023
Merged
Prev Previous commit
Next Next commit
EIP-4844: make sure tx produce correct txHash
  • Loading branch information
jangko committed Jun 8, 2023
commit 4d1852ad111a3f39105a45a5f8f5bb909e390cf4
3 changes: 0 additions & 3 deletions nimbus/core/executor/process_transaction.nim
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,6 @@ proc asyncProcessTransactionImpl(
## Modelled after `https://eips.ethereum.org/EIPS/eip-1559#specification`_
## which provides a backward compatible framwork for EIP1559.

#trace "Sender", sender
#trace "txHash", rlpHash = ty.rlpHash

let
roDB = vmState.readOnlyStateDB
baseFee256 = header.eip1559BaseFee(fork)
Expand Down
2 changes: 1 addition & 1 deletion nimbus/core/sealer.nim
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ template unsafeQuantityToInt64(q: web3types.Quantity): int64 =
int64 q

proc toTypedTransaction(tx: Transaction): TypedTransaction =
web3types.TypedTransaction(rlp.encode(tx))
web3types.TypedTransaction(rlp.encode(tx.removeNetworkPayload))

func toWithdrawal(x: WithdrawalV1): Withdrawal =
result.index = x.index.uint64
Expand Down
2 changes: 1 addition & 1 deletion nimbus/core/tx_pool/tx_tasks/tx_packer.nim
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ proc runTxCommit(pst: TxPackerStateRef; item: TxItemRef; gasBurned: GasInt)
pst.dataGasUsed += item.tx.getTotalDataGas

# Update txRoot
pst.tr.put(rlp.encode(inx), rlp.encode(item.tx))
pst.tr.put(rlp.encode(inx), rlp.encode(item.tx.removeNetworkPayload))

# Add the item to the `packed` bucket. This implicitely increases the
# receipts index `inx` at the next visit of this function.
Expand Down
7 changes: 4 additions & 3 deletions nimbus/db/db_chain.nim
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,8 @@ proc persistTransactions*(db: ChainDBRef, blockNumber:
var trie = initHexaryTrie(db.db)
for idx, tx in transactions:
let
encodedTx = rlp.encode(tx)
txHash = keccakHash(encodedTx)
encodedTx = rlp.encode(tx.removeNetworkPayload)
txHash = rlpHash(tx) # beware EIP-4844
txKey: TransactionKey = (blockNumber, idx)
trie.put(rlp.encode(idx), encodedTx)
db.db.put(transactionHashToBlockKey(txHash).toOpenArray, rlp.encode(txKey))
Expand Down Expand Up @@ -219,7 +219,8 @@ iterator getBlockTransactionHashes*(db: ChainDBRef, blockHeader: BlockHeader): H
## Returns an iterable of the transaction hashes from th block specified
## by the given block header.
for encodedTx in db.getBlockTransactionData(blockHeader.txRoot):
yield keccakHash(encodedTx)
let tx = rlp.decode(encodedTx, Transaction)
yield rlpHash(tx) # beware EIP-4844

proc getTransactionCount*(chain: ChainDBRef, txRoot: Hash256): int =
var trie = initHexaryTrie(chain.db, txRoot)
Expand Down
7 changes: 3 additions & 4 deletions nimbus/graphql/ethapi.nim
Original file line number Diff line number Diff line change
Expand Up @@ -569,8 +569,7 @@ const logProcs = {
proc txHash(ud: RootRef, params: Args, parent: Node): RespResult {.apiPragma.} =
let
tx = TxNode(parent)
encodedTx = rlp.encode(tx.tx)
txHash = keccakHash(encodedTx)
txHash = rlpHash(tx.tx) # beware EIP-4844
resp(txHash)

proc txNonce(ud: RootRef, params: Args, parent: Node): RespResult {.apiPragma.} =
Expand Down Expand Up @@ -1249,8 +1248,8 @@ proc sendRawTransaction(ud: RootRef, params: Args, parent: Node): RespResult {.a
let ctx = GraphqlContextRef(ud)
try:
let data = hexToSeqByte(params[0].val.stringVal)
let _ = decodeTx(data) # we want to know if it is a valid tx blob
let txHash = keccakHash(data)
let tx = decodeTx(data) # we want to know if it is a valid tx blob
let txHash = rlpHash(tx) # beware EIP-4844
resp(txHash)
except CatchableError as em:
return err("failed to process raw transaction: " & em.msg)
Expand Down
5 changes: 2 additions & 3 deletions nimbus/rpc/p2p.nim
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,9 @@ proc setupEthRpc*(
tx = unsignedTx(data, chainDB, accDB.getNonce(address) + 1)
eip155 = com.isEIP155(com.syncCurrent)
signedTx = signTransaction(tx, acc.privateKey, com.chainId, eip155)
rlpTx = rlp.encode(signedTx)

txPool.add(signedTx)
result = keccakHash(rlpTx).ethHashStr
result = rlpHash(signedTx).ethHashStr

server.rpc("eth_sendRawTransaction") do(data: HexDataStr) -> EthHashStr:
## Creates new message call transaction or a contract creation for signed transactions.
Expand All @@ -274,7 +273,7 @@ proc setupEthRpc*(
signedTx = decodeTx(txBytes)

txPool.add(signedTx)
result = keccakHash(txBytes).ethHashStr
result = rlpHash(signedTx).ethHashStr

server.rpc("eth_call") do(call: EthCall, quantityTag: string) -> HexDataStr:
## Executes a new message call immediately without creating a transaction on the block chain.
Expand Down
5 changes: 1 addition & 4 deletions nimbus/sync/protocol/les_protocol.nim
Original file line number Diff line number Diff line change
Expand Up @@ -458,10 +458,7 @@ p2pProtocol les(version = lesVersion,

var results: seq[TransactionStatusMsg]
for t in transactions:
let hash = t.rlpHash # TODO: this is not optimal, we can compute
# the hash from the request bytes.
# The RLP module can offer a helper Hashed[T]
# to make this easy.
let hash = t.rlpHash
var s = ctx.getTransactionStatus(hash)
if s.status == TransactionStatus.Unknown:
ctx.addTransactions([t])
Expand Down
9 changes: 6 additions & 3 deletions nimbus/transaction.nim
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ proc validateTxLegacy(tx: Transaction, fork: EVMFork) =
isValid = isValid and tx.S < SECPK1_N div 2

if not isValid:
raise newException(ValidationError, "Invalid transaction")
raise newException(ValidationError, "Invalid legacy transaction")

proc validateTxEip2930(tx: Transaction) =
var isValid = tx.V in {0'i64, 1'i64}
Expand All @@ -126,7 +126,7 @@ proc validateTxEip2930(tx: Transaction) =
isValid = isValid and tx.R < SECPK1_N

if not isValid:
raise newException(ValidationError, "Invalid transaction")
raise newException(ValidationError, "Invalid typed transaction")

proc validateTxEip4844(tx: Transaction) =
validateTxEip2930(tx)
Expand All @@ -145,6 +145,9 @@ proc validateTxEip4844(tx: Transaction) =
isValid = isValid and
bv.data[0] == BLOB_COMMITMENT_VERSION_KZG

if not isValid:
raise newException(ValidationError, "Invalid EIP-4844 transaction")

proc validate*(tx: Transaction, fork: EVMFork) =
# parameters pass validation rules
if tx.intrinsicGas(fork) > tx.gasLimit:
Expand All @@ -163,7 +166,7 @@ proc validate*(tx: Transaction, fork: EVMFork) =
validateTxLegacy(tx, fork)
of TxEip4844:
validateTxEip4844(tx)
else:
of TxEip2930, TxEip1559:
validateTxEip2930(tx)

proc signTransaction*(tx: Transaction, privateKey: PrivateKey, chainId: ChainId, eip155: bool): Transaction =
Expand Down