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

Fix EIP-4844 bugs #1650

Merged
merged 2 commits into from
Jul 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions nimbus/common/chain_config.nim
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ type
gasUser* : GasInt
parentHash* : Hash256
baseFeePerGas*: Option[UInt256]
dataGasUsed* : Option[uint64] # EIP-4844
excessDataGas*: Option[uint64] # EIP-4844

GenesisAlloc* = Table[EthAddress, GenesisAccount]
GenesisAccount* = object
Expand Down Expand Up @@ -65,6 +67,8 @@ type
gasUser* : GasInt
parentHash* : Hash256
baseFeePerGas*: Option[UInt256]
dataGasUsed* : Option[uint64] # EIP-4844
excessDataGas*: Option[uint64] # EIP-4844

const
CustomNet* = 0.NetworkId
Expand Down
4 changes: 4 additions & 0 deletions nimbus/common/genesis.nim
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ proc toGenesisHeader*(
if fork >= Shanghai:
result.withdrawalsRoot = some(EMPTY_ROOT_HASH)

if fork >= Cancun:
result.dataGasUsed = g.dataGasUsed
result.excessDataGas = g.excessDataGas

proc toGenesisHeader*(
genesis: Genesis;
fork: HardFork;
Expand Down
3 changes: 1 addition & 2 deletions nimbus/constants.nim
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,14 @@ const
MAX_CALLDATA_SIZE* = 1 shl 24 # 2^24
MAX_ACCESS_LIST_SIZE* = 1 shl 24 # 2^24
MAX_ACCESS_LIST_STORAGE_KEYS* = 1 shl 24 # 2^24
MAX_VERSIONED_HASHES_LIST_SIZE* = 1 shl 24 # 2^24
MAX_TX_WRAP_COMMITMENTS* = 1 shl 12 # 2^12
LIMIT_BLOBS_PER_TX* = 1 shl 12 # 2^12
BLOB_COMMITMENT_VERSION_KZG* = 0x01.byte
FIELD_ELEMENTS_PER_BLOB* = 4096
DATA_GAS_PER_BLOB* = (1 shl 17).uint64 # 2^17
TARGET_DATA_GAS_PER_BLOCK* = (1 shl 18).uint64 # 2^18
MIN_DATA_GASPRICE* = 1'u64
DATA_GASPRICE_UPDATE_FRACTION* = 2225652'u64
MAX_DATA_GAS_PER_BLOCK* = (1 shl 19).uint64 # 2^19
MaxAllowedBlob* = MAX_DATA_GAS_PER_BLOCK div DATA_GAS_PER_BLOB

# End
4 changes: 2 additions & 2 deletions nimbus/core/eip4844.nim
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,8 @@ func validateEip4844Header*(
headerExcessDataGas = header.excessDataGas.get
excessDataGas = calcExcessDataGas(parentHeader)

if dataGasUsed <= MAX_DATA_GAS_PER_BLOCK:
return err("dataGasUsed should greater than MAX_DATA_GAS_PER_BLOCK: " & $dataGasUsed)
if dataGasUsed > MAX_DATA_GAS_PER_BLOCK:
return err("dataGasUsed " & $dataGasUsed & " exceeds maximum allowance " & $MAX_DATA_GAS_PER_BLOCK)

if headerDataGasUsed != dataGasUsed:
return err("calculated dataGas not equal header.dataGasUsed")
Expand Down
6 changes: 3 additions & 3 deletions nimbus/core/validate.nim
Original file line number Diff line number Diff line change
Expand Up @@ -349,9 +349,9 @@ proc validateTransaction*(
if tx.versionedHashes.len == 0:
return err("invalid tx: there must be at least one blob")

if tx.versionedHashes.len > MAX_VERSIONED_HASHES_LIST_SIZE:
return err("invalid tx: access list len exceeds MAX_VERSIONED_HASHES_LIST_SIZE. len=" &
$tx.versionedHashes.len)
if tx.versionedHashes.len > MaxAllowedBlob.int:
return err("invalid tx: versioned hashes len exceeds MaxAllowedBlob=" & $MaxAllowedBlob &
". get=" & $tx.versionedHashes.len)

for i, bv in tx.versionedHashes:
if bv.data[0] != BLOB_COMMITMENT_VERSION_KZG:
Expand Down
2 changes: 1 addition & 1 deletion nimbus/transaction.nim
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ proc validateTxEip4844(tx: Transaction) =
(acl.storageKeys.len <= MAX_ACCESS_LIST_STORAGE_KEYS)

isValid = isValid and
tx.versionedHashes.len <= MAX_VERSIONED_HASHES_LIST_SIZE
tx.versionedHashes.len <= MaxAllowedBlob.int

for bv in tx.versionedHashes:
isValid = isValid and
Expand Down
17 changes: 11 additions & 6 deletions nimbus/transaction/call_common.nim
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,6 @@ func intrinsicGas*(call: CallParams, vmState: BaseVMState): GasInt {.inline.} =
gas += ACCESS_LIST_ADDRESS_COST
gas += account.storageKeys.len * ACCESS_LIST_STORAGE_KEY_COST

# EIP-4844
if fork >= FkCancun:
gas += calcDataFee(call.versionedHashes.len,
vmState.parent.excessDataGas).GasInt

return gas

proc initialAccessListEIP2929(call: CallParams) =
Expand Down Expand Up @@ -237,9 +232,19 @@ proc prepareToRunComputation(host: TransactionHost, call: CallParams) =

# Charge for gas.
if not call.noGasCharge:
host.vmState.mutateStateDB:
let
vmState = host.vmState
fork = vmState.fork

vmState.mutateStateDB:
db.subBalance(call.sender, call.gasLimit.u256 * call.gasPrice.u256)

# EIP-4844
if fork >= FkCancun:
let blobFee = calcDataFee(call.versionedHashes.len,
vmState.parent.excessDataGas).GasInt
db.subBalance(call.sender, blobFee.u256)

proc calculateAndPossiblyRefundGas(host: TransactionHost, call: CallParams): GasInt =
let c = host.computation

Expand Down
10 changes: 9 additions & 1 deletion tools/evmstate/helpers.nim
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ proc fromJson(T: type AccessList, n: JsonNode): AccessList =
ap.storageKeys.add hexToByteArray(sk.getStr, 32)
result.add ap

proc fromJson(T: type VersionedHashes, list: JsonNode): VersionedHashes =
for x in list:
result.add Hash256.fromJson(x)

template required(T: type, nField: string): auto =
fromJson(T, n[nField])

Expand All @@ -92,6 +96,8 @@ template optional(T: type, nField: string): auto =
none(T)

proc txType(n: JsonNode): TxType =
if "blobVersionedHashes" in n:
return TxEip4844
if "gasPrice" notin n:
return TxEip1559
if "accessLists" in n:
Expand Down Expand Up @@ -121,7 +127,9 @@ proc parseTx*(n: JsonNode, dataIndex, gasIndex, valueIndex: int): Transaction =
gasPrice: omitZero(GasInt, "gasPrice"),
maxFee : omitZero(GasInt, "maxFeePerGas"),
accessList: omitZero(AccessList, "accessLists", dataIndex),
maxPriorityFee: omitZero(GasInt, "maxPriorityFeePerGas")
maxPriorityFee: omitZero(GasInt, "maxPriorityFeePerGas"),
maxFeePerDataGas: omitZero(GasInt, "maxFeePerDataGas"),
versionedHashes: omitZero(VersionedHashes, "blobVersionedHashes")
)

let rawTo = n["to"].getStr
Expand Down
9 changes: 9 additions & 0 deletions tools/t8n/t8n_test.nim
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,15 @@ const
output: T8nOutput(alloc: true, result: true),
expOut: "exp.json",
),
TestSpec(
name : "Blobhash list bounds",
base : "testdata/00-518",
input : t8nInput(
"alloc.json", "txs.json", "env.json", "Cancun", "",
),
output: T8nOutput(alloc: true, result: true),
expOut: "exp.json",
),
]

proc main() =
Expand Down
14 changes: 14 additions & 0 deletions tools/t8n/testdata/00-518/alloc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"0x095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "0x0de0b6b3a7640000",
"code" : "0x600a4960005500",
"nonce" : "0x00",
"storage" : {}
},
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "0x0de0b6b3a7640000",
"code" : "0x",
"nonce" : "0x00",
"storage" : {}
}
}
13 changes: 13 additions & 0 deletions tools/t8n/testdata/00-518/env.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"currentBaseFee" : "0x07",
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : null,
"currentGasLimit" : "0x1000000000",
"currentNumber" : "0x01",
"currentRandom" : "0x0000000000000000000000000000000000000000000000000000000000020000",
"currentTimestamp" : "0x03e8",
"parentDataGasUsed" : "0x2000",
"parentExcessDataGas" : "0x1000",
"previousHash" : "0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"withdrawals": []
}
31 changes: 31 additions & 0 deletions tools/t8n/testdata/00-518/exp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"alloc": {
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
"balance": "0xde0b6b3a7640000"
},
"0x095e7baea6a6c7c4c2dfeb977efac326af552d87": {
"code": "0x600a4960005500",
"balance": "0xde0b6b3a7640000"
}
},
"result": {
"stateRoot": "0x538353a3893bdc8daa9eb125f6680804fc6f63e07ba1a1b65329614325528a54",
"txRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"receipts": [],
"currentDifficulty": null,
"gasUsed": "0x0",
"rejected": [
{
"index": 0,
"error": "invalid tx: versioned hashes len exceeds MaxAllowedBlob=4. get=20"
}
],
"currentBaseFee": "0x7",
"withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"dataGasUsed": "0x0",
"excessDataGas": "0x0"
}
}
49 changes: 49 additions & 0 deletions tools/t8n/testdata/00-518/txs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
[
{
"accessList" : [
{
"address" : "0x095e7baea6a6c7c4c2dfeb977efac326af552d87",
"storageKeys" : [
"0x0000000000000000000000000000000000000000000000000000000000000000",
"0x0000000000000000000000000000000000000000000000000000000000000001"
]
}
],
"blobVersionedHashes" : [
"0x01a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065f0001",
"0x01a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065f0002",
"0x01a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065f0003",
"0x01a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065f0004",
"0x01a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065f0005",
"0x01a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065f0006",
"0x01a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065f0007",
"0x01a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065f0008",
"0x01a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065f0009",
"0x01a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065f0010",
"0x01a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065f0011",
"0x01a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065f0012",
"0x01a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065f0013",
"0x01a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065f0014",
"0x01a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065f0015",
"0x01a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065f0016",
"0x01a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065f0017",
"0x01a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065f0018",
"0x01a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065f0019",
"0x01a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065f0020"
],
"chainId" : "0x01",
"input" : "0x00",
"gas" : "0x3d0900",
"maxFeePerDataGas" : "0x0a",
"maxFeePerGas" : "0x012a05f200",
"maxPriorityFeePerGas" : "0x02",
"nonce" : "0x00",
"r" : "0x7b67348718a49b5e7c6f882030873feb198315051ae4b257fbd99bcc14777f53",
"s" : "0x375219ba48b2694622d8aab97d44fc7eb2902678e51369bcc74fae65c4bab628",
"sender" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"to" : "0x095e7baea6a6c7c4c2dfeb977efac326af552d87",
"type" : "0x03",
"v" : "0x00",
"value" : "0x0186a0"
}
]