rename data gas to blob gas (#1659)

* rename data gas to blob gas

* bump more submodules
* extend evmc tx_context with EIP-4844 blob_hashes
This commit is contained in:
andri lim 2023-08-04 19:43:30 +07:00 committed by GitHub
parent 221e6c9e2f
commit bdaeedb09f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
50 changed files with 215 additions and 198 deletions

View File

@ -240,25 +240,25 @@ func completeCmdArg*(T: type TrustedDigest, input: string): seq[string] =
return @[]
proc parseCmdArg*(T: type enr.Record, p: string): T
{.raises: [ConfigurationError].} =
{.raises: [ValueError].} =
if not fromURI(result, p):
raise newException(ConfigurationError, "Invalid ENR")
raise newException(ValueError, "Invalid ENR")
proc completeCmdArg*(T: type enr.Record, val: string): seq[string] =
return @[]
proc parseCmdArg*(T: type Node, p: string): T
{.raises: [ConfigurationError].} =
{.raises: [ValueError].} =
var record: enr.Record
if not fromURI(record, p):
raise newException(ConfigurationError, "Invalid ENR")
raise newException(ValueError, "Invalid ENR")
let n = newNode(record)
if n.isErr:
raise newException(ConfigurationError, $n.error)
raise newException(ValueError, $n.error)
if n[].address.isNone():
raise newException(ConfigurationError, "ENR without address")
raise newException(ValueError, "ENR without address")
n[]
@ -266,17 +266,17 @@ proc completeCmdArg*(T: type Node, val: string): seq[string] =
return @[]
proc parseCmdArg*(T: type PrivateKey, p: string): T
{.raises: [ConfigurationError].} =
{.raises: [ValueError].} =
try:
result = PrivateKey.fromHex(p).tryGet()
except CatchableError:
raise newException(ConfigurationError, "Invalid private key")
raise newException(ValueError, "Invalid private key")
proc completeCmdArg*(T: type PrivateKey, val: string): seq[string] =
return @[]
proc parseCmdArg*(T: type ClientConfig, p: string): T
{.raises: [ConfigurationError].} =
{.raises: [ValueError].} =
let uri = parseUri(p)
if (uri.scheme == "http" or uri.scheme == "https"):
getHttpClientConfig(p)
@ -284,7 +284,7 @@ proc parseCmdArg*(T: type ClientConfig, p: string): T
getWebSocketClientConfig(p)
else:
raise newException(
ConfigurationError, "Proxy uri should have defined scheme (http/https/ws/wss)"
ValueError, "Proxy uri should have defined scheme (http/https/ws/wss)"
)
proc completeCmdArg*(T: type ClientConfig, val: string): seq[string] =

View File

@ -209,7 +209,7 @@ func validateBlockHeaderBytes*(
let header = ? decodeRlp(bytes, BlockHeader)
if header.excessDataGas.isSome:
if header.excessBlobGas.isSome:
return err("EIP-4844 not yet implemented")
# TODO: Verify timestamp with Shanghai timestamp to if isSome()

View File

@ -54,7 +54,7 @@ proc init*(
)
proc parseCmdArg*(T: type RadiusConfig, p: string): T
{.raises: [ConfigurationError].} =
{.raises: [ValueError].} =
if p.startsWith("dynamic") and len(p) == 7:
RadiusConfig(kind: Dynamic)
elif p.startsWith("static:"):
@ -64,11 +64,11 @@ proc parseCmdArg*(T: type RadiusConfig, p: string): T
uint16.parseCmdArg(num)
except ValueError:
let msg = "Provided logRadius: " & num & " is not a valid number"
raise newException(ConfigurationError, msg)
raise newException(ValueError, msg)
if parsed > 256:
raise newException(
ConfigurationError, "Provided logRadius should be <= 256"
ValueError, "Provided logRadius should be <= 256"
)
RadiusConfig(kind: Static, logRadius: parsed)
@ -80,11 +80,11 @@ proc parseCmdArg*(T: type RadiusConfig, p: string): T
let msg =
"Not supported radius config option: " & p & " . " &
"Supported options: dynamic and static:logRadius"
raise newException(ConfigurationError, msg)
raise newException(ValueError, msg)
if parsed > 256:
raise newException(
ConfigurationError, "Provided logRadius should be <= 256")
ValueError, "Provided logRadius should be <= 256")
RadiusConfig(kind: Static, logRadius: parsed)

View File

@ -248,8 +248,8 @@ proc asPortalBlockData*(
nonce: default(BlockNonce),
fee: some(payload.baseFeePerGas),
withdrawalsRoot: withdrawalsRoot,
dataGasUsed: options.none(uint64),
excessDataGas: options.none(uint64)
blobGasUsed: options.none(uint64),
excessBlobGas: options.none(uint64)
)
headerWithProof = BlockHeaderWithProof(
@ -293,8 +293,8 @@ proc asPortalBlockData*(
nonce: default(BlockNonce),
fee: some(payload.baseFeePerGas),
withdrawalsRoot: withdrawalsRoot,
dataGasUsed: options.none(uint64),
excessDataGas: options.none(uint64) # TODO: adjust later according to deneb fork
blobGasUsed: options.none(uint64),
excessBlobGas: options.none(uint64) # TODO: adjust later according to deneb fork
)
headerWithProof = BlockHeaderWithProof(

View File

@ -170,7 +170,7 @@ type BeaconBridgeConf* = object
name: "direct-peer" .}: seq[string]
proc parseCmdArg*(
T: type Web3Url, p: string): T {.raises: [ConfigurationError].} =
T: type Web3Url, p: string): T {.raises: [ValueError].} =
let
url = parseUri(p)
normalizedScheme = url.scheme.toLowerAscii()
@ -181,7 +181,7 @@ proc parseCmdArg*(
Web3Url(kind: WsUrl, web3Url: p)
else:
raise newException(
ConfigurationError,
ValueError,
"The Web3 URL must specify one of following protocols: http/https/ws/wss"
)

View File

@ -40,12 +40,12 @@ type
name: "block-hash" .}: Hash256
proc parseCmdArg*(T: type Hash256, p: string): T
{.raises: [ConfigurationError].} =
{.raises: [ValueError].} =
var hash: Hash256
try:
hexToByteArray(p, hash.data)
except ValueError:
raise newException(ConfigurationError, "Invalid Hash256")
raise newException(ValueError, "Invalid Hash256")
return hash

View File

@ -184,7 +184,7 @@ type
discard
proc parseCmdArg*(
T: type Web3Url, p: string): T {.raises: [ConfigurationError].} =
T: type Web3Url, p: string): T {.raises: [ValueError].} =
let
url = parseUri(p)
normalizedScheme = url.scheme.toLowerAscii()
@ -195,7 +195,7 @@ proc parseCmdArg*(
Web3Url(kind: WsUrl, url: p)
else:
raise newException(
ConfigurationError,
ValueError,
"The Web3 URL must specify one of following protocols: http/https/ws/wss"
)
@ -203,14 +203,14 @@ proc completeCmdArg*(T: type Web3Url, val: string): seq[string] =
return @[]
proc parseCmdArg*(T: type StorageMode, p: string): T
{.raises: [ConfigurationError].} =
{.raises: [ValueError].} =
if p == "db":
return DbStorage
elif p == "json":
return JsonStorage
else:
let msg = "Provided mode: " & p & " is not a valid. Should be `json` or `db`"
raise newException(ConfigurationError, msg)
raise newException(ValueError, msg)
proc completeCmdArg*(T: type StorageMode, val: string): seq[string] =
return @[]

View File

@ -143,7 +143,7 @@ type
proc parseCmdArg*(T: type enr.Record, p: string): T =
if not fromURI(result, p):
raise newException(ConfigurationError, "Invalid ENR")
raise newException(ValueError, "Invalid ENR")
proc completeCmdArg*(T: type enr.Record, val: string): seq[string] =
return @[]
@ -151,14 +151,14 @@ proc completeCmdArg*(T: type enr.Record, val: string): seq[string] =
proc parseCmdArg*(T: type Node, p: string): T =
var record: enr.Record
if not fromURI(record, p):
raise newException(ConfigurationError, "Invalid ENR")
raise newException(ValueError, "Invalid ENR")
let n = newNode(record)
if n.isErr:
raise newException(ConfigurationError, $n.error)
raise newException(ValueError, $n.error)
if n[].address.isNone():
raise newException(ConfigurationError, "ENR without address")
raise newException(ValueError, "ENR without address")
n[]
@ -169,7 +169,7 @@ proc parseCmdArg*(T: type PrivateKey, p: string): T =
try:
result = PrivateKey.fromHex(p).tryGet()
except CatchableError:
raise newException(ConfigurationError, "Invalid private key")
raise newException(ValueError, "Invalid private key")
proc completeCmdArg*(T: type PrivateKey, val: string): seq[string] =
return @[]
@ -178,7 +178,7 @@ proc parseCmdArg*(T: type PortalProtocolId, p: string): T =
try:
result = byteutils.hexToByteArray(p, 2)
except ValueError:
raise newException(ConfigurationError,
raise newException(ValueError,
"Invalid protocol id, not a valid hex value")
proc completeCmdArg*(T: type PortalProtocolId, val: string): seq[string] =

View File

@ -45,8 +45,8 @@ proc parseGenesis(n: JsonNode): Genesis =
for x in genFields:
genesis[x] = gen[x]
optionalField("baseFeePerGas", genesis, gen)
optionalField("dataGasUsed", genesis, gen)
optionalField("excessDataGas", genesis, gen)
optionalField("blobGasUsed", genesis, gen)
optionalField("excessBlobGas", genesis, gen)
genesis["alloc"] = n["pre"]
parseGenesis($genesis)

View File

@ -35,8 +35,8 @@ type
gasUser* : GasInt
parentHash* : Hash256
baseFeePerGas*: Option[UInt256]
dataGasUsed* : Option[uint64] # EIP-4844
excessDataGas*: Option[uint64] # EIP-4844
blobGasUsed* : Option[uint64] # EIP-4844
excessBlobGas*: Option[uint64] # EIP-4844
GenesisAlloc* = Table[EthAddress, GenesisAccount]
GenesisAccount* = object
@ -67,8 +67,8 @@ type
gasUser* : GasInt
parentHash* : Hash256
baseFeePerGas*: Option[UInt256]
dataGasUsed* : Option[uint64] # EIP-4844
excessDataGas*: Option[uint64] # EIP-4844
blobGasUsed* : Option[uint64] # EIP-4844
excessBlobGas*: Option[uint64] # EIP-4844
const
CustomNet* = 0.NetworkId

View File

@ -81,8 +81,8 @@ proc toGenesisHeader*(
result.withdrawalsRoot = some(EMPTY_ROOT_HASH)
if fork >= Cancun:
result.dataGasUsed = g.dataGasUsed
result.excessDataGas = g.excessDataGas
result.blobGasUsed = g.blobGasUsed
result.excessBlobGas = g.excessBlobGas
proc toGenesisHeader*(
genesis: Genesis;

View File

@ -78,11 +78,11 @@ const
MAX_TX_WRAP_COMMITMENTS* = 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
GAS_PER_BLOB* = (1 shl 17).uint64 # 2^17
TARGET_BLOB_GAS_PER_BLOCK* = (1 shl 18).uint64 # 2^18
MIN_BLOB_GASPRICE* = 1'u64
BLOB_GASPRICE_UPDATE_FRACTION* = 2225652'u64
MAX_BLOB_GAS_PER_BLOCK* = (1 shl 19).uint64 # 2^19
MaxAllowedBlob* = MAX_BLOB_GAS_PER_BLOCK div GAS_PER_BLOB
# End

View File

@ -77,16 +77,16 @@ proc pointEvaluation*(input: openArray[byte]): Result[void, string] =
ok()
# calcExcessDataGas implements calc_excess_data_gas from EIP-4844
proc calcExcessDataGas*(parent: BlockHeader): uint64 =
# calcExcessBlobGas implements calc_excess_data_gas from EIP-4844
proc calcExcessBlobGas*(parent: BlockHeader): uint64 =
let
excessDataGas = parent.excessDataGas.get(0'u64)
dataGasUsed = parent.dataGasUsed.get(0'u64)
excessBlobGas = parent.excessBlobGas.get(0'u64)
blobGasUsed = parent.blobGasUsed.get(0'u64)
if excessDataGas + dataGasUsed < TARGET_DATA_GAS_PER_BLOCK:
if excessBlobGas + blobGasUsed < TARGET_BLOB_GAS_PER_BLOCK:
0'u64
else:
excessDataGas + dataGasUsed - TARGET_DATA_GAS_PER_BLOCK
excessBlobGas + blobGasUsed - TARGET_BLOB_GAS_PER_BLOCK
# fakeExponential approximates factor * e ** (num / denom) using a taylor expansion
# as described in the EIP-4844 spec.
@ -103,33 +103,33 @@ func fakeExponential*(factor, numerator, denominator: uint64): uint64 =
output div denominator
proc getTotalDataGas*(tx: Transaction): uint64 =
DATA_GAS_PER_BLOB * tx.versionedHashes.len.uint64
proc getTotalBlobGas*(tx: Transaction): uint64 =
GAS_PER_BLOB * tx.versionedHashes.len.uint64
proc getTotalDataGas*(versionedHashesLen: int): uint64 =
DATA_GAS_PER_BLOB * versionedHasheslen.uint64
proc getTotalBlobGas*(versionedHashesLen: int): uint64 =
GAS_PER_BLOB * versionedHasheslen.uint64
# getDataGasPrice implements get_data_gas_price from EIP-4844
func getDataGasprice*(parentExcessDataGas: uint64): uint64 =
# getBlobGasPrice implements get_data_gas_price from EIP-4844
func getBlobGasprice*(parentExcessBlobGas: uint64): uint64 =
fakeExponential(
MIN_DATA_GASPRICE,
parentExcessDataGas,
DATA_GASPRICE_UPDATE_FRACTION
MIN_BLOB_GASPRICE,
parentExcessBlobGas,
BLOB_GASPRICE_UPDATE_FRACTION
)
proc calcDataFee*(tx: Transaction,
parentExcessDataGas: Option[uint64]): uint64 =
tx.getTotalDataGas *
getDataGasprice(parentExcessDataGas.get(0'u64))
parentExcessBlobGas: Option[uint64]): uint64 =
tx.getTotalBlobGas *
getBlobGasprice(parentExcessBlobGas.get(0'u64))
proc calcDataFee*(versionedHashesLen: int,
parentExcessDataGas: Option[uint64]): uint64 =
getTotalDataGas(versionedHashesLen) *
getDataGasprice(parentExcessDataGas.get(0'u64))
parentExcessBlobGas: Option[uint64]): uint64 =
getTotalBlobGas(versionedHashesLen) *
getBlobGasprice(parentExcessBlobGas.get(0'u64))
func dataGasUsed(txs: openArray[Transaction]): uint64 =
func blobGasUsed(txs: openArray[Transaction]): uint64 =
for tx in txs:
result += tx.getTotalDataGas
result += tx.getTotalBlobGas
# https://eips.ethereum.org/EIPS/eip-4844
func validateEip4844Header*(
@ -137,34 +137,34 @@ func validateEip4844Header*(
txs: openArray[Transaction]): Result[void, string] {.raises: [].} =
if not com.forkGTE(Cancun):
if header.dataGasUsed.isSome:
return err("unexpected EIP-4844 dataGasUsed in block header")
if header.blobGasUsed.isSome:
return err("unexpected EIP-4844 blobGasUsed in block header")
if header.excessDataGas.isSome:
return err("unexpected EIP-4844 excessDataGas in block header")
if header.excessBlobGas.isSome:
return err("unexpected EIP-4844 excessBlobGas in block header")
return ok()
if header.dataGasUsed.isNone:
return err("expect EIP-4844 dataGasUsed in block header")
if header.blobGasUsed.isNone:
return err("expect EIP-4844 blobGasUsed in block header")
if header.excessDataGas.isNone:
return err("expect EIP-4844 excessDataGas in block header")
if header.excessBlobGas.isNone:
return err("expect EIP-4844 excessBlobGas in block header")
let
headerDataGasUsed = header.dataGasUsed.get()
dataGasUsed = dataGasUsed(txs)
headerExcessDataGas = header.excessDataGas.get
excessDataGas = calcExcessDataGas(parentHeader)
headerBlobGasUsed = header.blobGasUsed.get()
blobGasUsed = blobGasUsed(txs)
headerExcessBlobGas = header.excessBlobGas.get
excessBlobGas = calcExcessBlobGas(parentHeader)
if dataGasUsed > MAX_DATA_GAS_PER_BLOCK:
return err("dataGasUsed " & $dataGasUsed & " exceeds maximum allowance " & $MAX_DATA_GAS_PER_BLOCK)
if blobGasUsed > MAX_BLOB_GAS_PER_BLOCK:
return err("blobGasUsed " & $blobGasUsed & " exceeds maximum allowance " & $MAX_BLOB_GAS_PER_BLOCK)
if headerDataGasUsed != dataGasUsed:
return err("calculated dataGas not equal header.dataGasUsed")
if headerBlobGasUsed != blobGasUsed:
return err("calculated blobGas not equal header.blobGasUsed")
if headerExcessDataGas != excessDataGas:
return err("calculated excessDataGas not equal header.excessDataGas")
if headerExcessBlobGas != excessBlobGas:
return err("calculated excessBlobGas not equal header.excessBlobGas")
return ok()

View File

@ -78,7 +78,7 @@ proc asyncProcessTransactionImpl(
baseFee = baseFee256.truncate(GasInt)
tx = eip1559TxNormalization(tx, baseFee, fork)
priorityFee = min(tx.maxPriorityFee, tx.maxFee - baseFee)
excessDataGas = vmState.parent.excessDataGas.get(0'u64)
excessBlobGas = vmState.parent.excessBlobGas.get(0'u64)
# Return failure unless explicitely set `ok()`
var res: Result[GasInt, string] = err("")
@ -100,7 +100,7 @@ proc asyncProcessTransactionImpl(
# before leaving is crucial for some unit tests that us a direct/deep call
# of the `processTransaction()` function. So there is no `return err()`
# statement, here.
let txRes = roDB.validateTransaction(tx, sender, header.gasLimit, baseFee256, excessDataGas, fork)
let txRes = roDB.validateTransaction(tx, sender, header.gasLimit, baseFee256, excessBlobGas, fork)
if txRes.isOk:
# EIP-1153

View File

@ -52,10 +52,10 @@ type
profit: UInt256 ## Net reward (w/o PoW specific block rewards)
txRoot: Hash256 ## `rootHash` after packing
stateRoot: Hash256 ## `stateRoot` after packing
dataGasUsed:
Option[uint64] ## EIP-4844 block dataGasUsed
excessDataGas:
Option[uint64] ## EIP-4844 block excessDataGas
blobGasUsed:
Option[uint64] ## EIP-4844 block blobGasUsed
excessBlobGas:
Option[uint64] ## EIP-4844 block excessBlobGas
TxChainRef* = ref object ##\
## State cache of the transaction environment for creating a new\
@ -144,8 +144,8 @@ proc resetTxEnv(dh: TxChainRef; parent: BlockHeader; fee: Option[UInt256])
dh.txEnv.txRoot = EMPTY_ROOT_HASH
dh.txEnv.stateRoot = dh.txEnv.vmState.parent.stateRoot
dh.txEnv.dataGasUsed = none(uint64)
dh.txEnv.excessDataGas = none(uint64)
dh.txEnv.blobGasUsed = none(uint64)
dh.txEnv.excessBlobGas = none(uint64)
proc update(dh: TxChainRef; parent: BlockHeader)
{.gcsafe,raises: [CatchableError].} =
@ -224,8 +224,8 @@ proc getHeader*(dh: TxChainRef): BlockHeader
# mixDigest: Hash256 # mining hash for given difficulty
# nonce: BlockNonce # mining free vaiable
fee: dh.txEnv.vmState.fee,
dataGasUsed: dh.txEnv.dataGasUsed,
excessDataGas: dh.txEnv.excessDataGas)
blobGasUsed: dh.txEnv.blobGasUsed,
excessBlobGas: dh.txEnv.excessBlobGas)
if dh.com.forkGTE(Shanghai):
result.withdrawalsRoot = some(calcWithdrawalsRoot(dh.withdrawals))
@ -378,13 +378,13 @@ proc `txRoot=`*(dh: TxChainRef; val: Hash256) =
proc `withdrawals=`*(dh: TxChainRef, val: sink seq[Withdrawal]) =
dh.withdrawals = system.move(val)
proc `excessDataGas=`*(dh: TxChainRef; val: Option[uint64]) =
proc `excessBlobGas=`*(dh: TxChainRef; val: Option[uint64]) =
## Setter
dh.txEnv.excessDataGas = val
dh.txEnv.excessBlobGas = val
proc `dataGasUsed=`*(dh: TxChainRef; val: Option[uint64]) =
proc `blobGasUsed=`*(dh: TxChainRef; val: Option[uint64]) =
## Setter
dh.txEnv.dataGasUsed = val
dh.txEnv.blobGasUsed = val
# ------------------------------------------------------------------------------
# End

View File

@ -233,9 +233,9 @@ proc classifyValidatePacked*(xp: TxPoolRef;
else:
xp.chain.limits.trgLimit
tx = item.tx.eip1559TxNormalization(xp.chain.baseFee.GasInt, fork)
excessDataGas = vmState.parent.excessDataGas.get(0'u64)
excessBlobGas = vmState.parent.excessBlobGas.get(0'u64)
roDB.validateTransaction(tx, item.sender, gasLimit, baseFee, excessDataGas, fork).isOk
roDB.validateTransaction(tx, item.sender, gasLimit, baseFee, excessBlobGas, fork).isOk
proc classifyPacked*(xp: TxPoolRef; gasBurned, moreBurned: GasInt): bool =
## Classifier for *packing* (i.e. adding up `gasUsed` values after executing

View File

@ -37,7 +37,7 @@ type
tr: CoreDbMptRef
cleanState: bool
balance: UInt256
dataGasUsed: uint64
blobGasUsed: uint64
const
receiptsExtensionSize = ##\
@ -132,9 +132,9 @@ proc runTxCommit(pst: TxPackerStateRef; item: TxItemRef; gasBurned: GasInt)
vmState.cumulativeGasUsed += gasBurned
vmState.receipts[inx] = vmState.makeReceipt(item.tx.txType)
# EIP-4844, count dataGasUsed
# EIP-4844, count blobGasUsed
if item.tx.txType >= TxEip4844:
pst.dataGasUsed += item.tx.getTotalDataGas
pst.blobGasUsed += item.tx.getTotalBlobGas
# Update txRoot
pst.tr.put(rlp.encode(inx), rlp.encode(item.tx.removeNetworkPayload))
@ -245,9 +245,9 @@ proc vmExecCommit(pst: TxPackerStateRef)
if vmState.com.forkGTE(Cancun):
# EIP-4844
let excessDataGas = calcExcessDataGas(vmState.parent)
xp.chain.excessDataGas = some(excessDataGas)
xp.chain.dataGasUsed = some(pst.dataGasUsed)
let excessBlobGas = calcExcessBlobGas(vmState.parent)
xp.chain.excessBlobGas = some(excessBlobGas)
xp.chain.blobGasUsed = some(pst.blobGasUsed)
proc balanceDelta: UInt256 =
let postBalance = vmState.readOnlyStateDB.getBalance(xp.chain.feeRecipient)

View File

@ -234,7 +234,7 @@ proc validateUncles(com: CommonRef; header: BlockHeader;
func gasCost(tx: Transaction): UInt256 =
if tx.txType >= TxEip4844:
tx.gasLimit.u256 * tx.maxFee.u256 + tx.getTotalDataGas.u256 * tx.maxFeePerDataGas.u256
tx.gasLimit.u256 * tx.maxFee.u256 + tx.getTotalBlobGas.u256 * tx.maxFeePerBlobGas.u256
elif tx.txType >= TxEip1559:
tx.gasLimit.u256 * tx.maxFee.u256
else:
@ -246,7 +246,7 @@ proc validateTransaction*(
sender: EthAddress; ## tx.getSender or tx.ecRecover
maxLimit: GasInt; ## gasLimit from block header
baseFee: UInt256; ## baseFee from block header
excessDataGas: uint64; ## excessDataGas from parent block header
excessBlobGas: uint64; ## excessBlobGas from parent block header
fork: EVMFork): Result[void, string] =
let
@ -359,10 +359,10 @@ proc validateTransaction*(
"get=$1, expect=$2" % [$bv.data[0].int, $BLOB_COMMITMENT_VERSION_KZG.int])
# ensure that the user was willing to at least pay the current data gasprice
let dataGasPrice = getDataGasPrice(excessDataGas)
if tx.maxFeePerDataGas.uint64 < dataGasPrice:
return err("invalid tx: maxFeePerDataGas smaller than dataGasPrice. " &
"maxFeePerDataGas=$1, dataGasPrice=$2" % [$tx.maxFeePerDataGas, $dataGasPrice])
let blobGasPrice = getBlobGasPrice(excessBlobGas)
if tx.maxFeePerBlobGas.uint64 < blobGasPrice:
return err("invalid tx: maxFeePerBlobGas smaller than blobGasPrice. " &
"maxFeePerBlobGas=$1, blobGasPrice=$2" % [$tx.maxFeePerBlobGas, $blobGasPrice])
except CatchableError as ex:
return err(ex.msg)

View File

@ -78,7 +78,7 @@ proc makeAnRpcClient*(web3Url: string): Future[RpcClient] {.async.} =
uncles*: seq[Hash256] # list of uncle hashes.
baseFeePerGas*: Option[UInt256] # EIP-1559
withdrawalsRoot*: Option[Hash256] # EIP-4895
excessDataGas*: Option[UInt256] # EIP-4844
excessBlobGas*: Option[UInt256] # EIP-4844
]#
func fromQty(x: Option[Quantity]): Option[uint64] =
@ -107,8 +107,8 @@ func blockHeaderFromBlockObject(o: BlockObject): BlockHeader =
nonce: nonce,
fee: o.baseFeePerGas,
withdrawalsRoot: o.withdrawalsRoot.map(toHash),
dataGasUsed: fromQty(o.dataGasUsed),
excessDataGas: fromQty(o.excessDataGas)
blobGasUsed: fromQty(o.blobGasUsed),
excessBlobGas: fromQty(o.excessBlobGas)
)
proc fetchBlockHeaderWithHash*(rpcClient: RpcClient, h: Hash256): Future[BlockHeader] {.async.} =

View File

@ -35,13 +35,13 @@ when defined(evmc_enabled):
evmc/evmc,
evmc_helpers,
evmc_api,
stew/ranges/ptr_arith
stew/ptrops
export
evmc,
evmc_helpers,
evmc_api,
ptr_arith
ptrops
const
evmc_enabled* = defined(evmc_enabled)
@ -117,15 +117,13 @@ template getGasPrice*(c: Computation): GasInt =
template getVersionedHash*(c: Computation, index: int): VersionedHash =
when evmc_enabled:
# TODO: implement
Hash256()
cast[ptr UncheckedArray[VersionedHash]](c.host.getTxContext().blob_hashes)[index]
else:
c.vmState.txVersionedHashes[index]
template getVersionedHashesLen*(c: Computation): int =
when evmc_enabled:
# TODO: implement
0
c.host.getTxContext().blob_hashes_count.int
else:
c.vmState.txVersionedHashes.len

View File

@ -19,16 +19,18 @@ type
# directly if it's not involving stint computation
# and we can reduce unecessary conversion further
nimbus_tx_context* = object
tx_gas_price* : evmc_uint256be # The transaction gas price.
tx_origin* : EthAddress # The transaction origin account.
block_coinbase* : EthAddress # The miner of the block.
block_number* : int64 # The block number.
block_timestamp* : int64 # The block timestamp.
block_gas_limit* : int64 # The block gas limit.
block_prev_randao*: evmc_uint256be # The block difficulty.
chain_id* : evmc_uint256be # The blockchain's ChainID.
block_base_fee* : evmc_uint256be # The block base fee.
tx_gas_price* : evmc_uint256be # The transaction gas price.
tx_origin* : EthAddress # The transaction origin account.
block_coinbase* : EthAddress # The miner of the block.
block_number* : int64 # The block number.
block_timestamp* : int64 # The block timestamp.
block_gas_limit* : int64 # The block gas limit.
block_prev_randao*: evmc_uint256be # The block difficulty.
chain_id* : evmc_uint256be # The blockchain's ChainID.
block_base_fee* : evmc_uint256be # The block base fee.
blob_hashes* : ptr evmc_bytes32 # The array of blob hashes (EIP-4844).
blob_hashes_count*: csize_t # The number of blob hashes (EIP-4844).
nimbus_message* = object
kind* : evmc_call_kind
flags* : uint32

View File

@ -807,7 +807,7 @@ proc txMaxFeePerBlobGas(ud: RootRef, params: Args, parent: Node): RespResult {.a
if tx.tx.txType < TxEIP4844:
ok(respNull())
else:
longNode(tx.tx.maxFeePerDataGas)
longNode(tx.tx.maxFeePerBlobGas)
proc txVersionedHashes(ud: RootRef, params: Args, parent: Node): RespResult {.apiPragma.} =
let ctx = GraphqlContextRef(ud)
@ -1146,15 +1146,15 @@ proc blockWithdrawals(ud: RootRef, params: Args, parent: Node): RespResult {.api
proc blockBlobGasUsed(ud: RootRef, params: Args, parent: Node): RespResult {.apiPragma.} =
let h = HeaderNode(parent)
if h.header.dataGasUsed.isSome:
longNode(h.header.dataGasUsed.get)
if h.header.blobGasUsed.isSome:
longNode(h.header.blobGasUsed.get)
else:
ok(respNull())
proc blockexcessBlobGas(ud: RootRef, params: Args, parent: Node): RespResult {.apiPragma.} =
let h = HeaderNode(parent)
if h.header.excessDataGas.isSome:
longNode(h.header.excessDataGas.get)
if h.header.excessBlobGas.isSome:
longNode(h.header.excessBlobGas.get)
else:
ok(respNull())

View File

@ -246,7 +246,7 @@ proc prepareToRunComputation(host: TransactionHost, call: CallParams) =
# EIP-4844
if fork >= FkCancun:
let blobFee = calcDataFee(call.versionedHashes.len,
vmState.parent.excessDataGas).GasInt
vmState.parent.excessBlobGas).GasInt
db.subBalance(call.sender, blobFee.u256)
proc calculateAndPossiblyRefundGas(host: TransactionHost, call: CallParams): GasInt =

View File

@ -10,7 +10,7 @@
import
eth/common/eth_types,
stew/ranges/ptr_arith,
stew/ptrops,
stint,
".."/[vm_types, vm_computation],
../utils/utils,

View File

@ -65,6 +65,15 @@ proc setupTxContext(host: TransactionHost) =
host.txContext.chain_id = vmState.com.chainId.uint.u256.toEvmc
host.txContext.block_base_fee = vmState.baseFee.toEvmc
if vmState.txVersionedHashes.len > 0:
type
BlobHashPtr = typeof host.txContext.blob_hashes
host.txContext.blob_hashes = cast[BlobHashPtr](vmState.txVersionedHashes[0].addr)
else:
host.txContext.blob_hashes = nil
host.txContext.blob_hashes_count= vmState.txVersionedHashes.len.csize_t
# Most host functions do `flip256` in `evmc_host_glue`, but due to this
# result being cached, it's better to do `flip256` when filling the cache.
host.txContext.tx_gas_price = flip256(host.txContext.tx_gas_price)

View File

@ -10,7 +10,7 @@
import
macros, strformat, strutils, stint, chronicles,
stew/byteutils, stew/ranges/ptr_arith,
stew/byteutils, stew/ptrops,
./host_types
# Set `true` or `false` to control host call tracing.

View File

@ -51,10 +51,10 @@ proc debug*(h: BlockHeader): string =
result.add "fee : " & $h.fee.get() & "\n"
if h.withdrawalsRoot.isSome:
result.add "withdrawalsRoot: " & $h.withdrawalsRoot.get() & "\n"
if h.dataGasUsed.isSome:
result.add "dataGasUsed : " & $h.dataGasUsed.get() & "\n"
if h.excessDataGas.isSome:
result.add "excessDataGas : " & $h.excessDataGas.get() & "\n"
if h.blobGasUsed.isSome:
result.add "blobGasUsed : " & $h.blobGasUsed.get() & "\n"
if h.excessBlobGas.isSome:
result.add "excessBlobGas : " & $h.excessBlobGas.get() & "\n"
result.add "blockHash : " & $blockHash(h) & "\n"
proc dumpAccount(stateDB: AccountsCache, address: EthAddress): JsonNode =

View File

@ -167,7 +167,7 @@ type VerifiedProxyConf* = object
proc parseCmdArg*(
T: type Web3Url, p: string): T {.raises: [ConfigurationError].} =
T: type Web3Url, p: string): T {.raises: [ValueError].} =
let
url = parseUri(p)
normalizedScheme = url.scheme.toLowerAscii()
@ -178,7 +178,7 @@ proc parseCmdArg*(
Web3Url(kind: WsUrl, web3Url: p)
else:
raise newException(
ConfigurationError, "Web3 url should have defined scheme (http/https/ws/wss)"
ValueError, "Web3 url should have defined scheme (http/https/ws/wss)"
)
proc completeCmdArg*(T: type Web3Url, val: string): seq[string] =

View File

@ -56,8 +56,8 @@ proc pp*(h: BlockHeader; sep = " "): string =
&"stateRoot={h.stateRoot.pp}{sep}" &
&"baseFee={h.baseFee}{sep}" &
&"withdrawalsRoot={h.withdrawalsRoot.get(EMPTY_ROOT_HASH)}{sep}" &
&"dataGasUsed={h.dataGasUsed.get(0'u64)}" &
&"excessDataGas={h.excessDataGas.get(0'u64)}"
&"blobGasUsed={h.blobGasUsed.get(0'u64)}" &
&"excessBlobGas={h.excessBlobGas.get(0'u64)}"
proc pp*(g: Genesis; sep = " "): string =
"" &

View File

@ -119,7 +119,7 @@ proc tx7(i: int): Transaction =
maxFee: 10.GasInt,
accessList: accesses,
versionedHashes: @[digest],
maxFeePerDataGas: 10000000.GasInt,
maxFeePerBlobGas: 10000000.GasInt,
)
proc tx8(i: int): Transaction =
@ -136,7 +136,7 @@ proc tx8(i: int): Transaction =
maxFee: 10.GasInt,
accessList: accesses,
versionedHashes: @[digest],
maxFeePerDataGas: 10000000.GasInt,
maxFeePerBlobGas: 10000000.GasInt,
)
proc privKey(keyHex: string): PrivateKey =

View File

@ -113,7 +113,9 @@ proc parseHeader*(n: JsonNode): BlockHeader =
timestamp : required(EthTime, "currentTimestamp"),
stateRoot : emptyRlpHash,
mixDigest : omitZero(Hash256, "currentRandom"),
fee : optional(UInt256, "currentBaseFee")
fee : optional(UInt256, "currentBaseFee"),
excessBlobGas: optional(uint64, "excessBlobGas"),
blobGasUsed: optional(uint64, "blobGasUsed")
)
proc parseTx*(n: JsonNode, dataIndex, gasIndex, valueIndex: int): Transaction =
@ -128,7 +130,7 @@ proc parseTx*(n: JsonNode, dataIndex, gasIndex, valueIndex: int): Transaction =
maxFee : omitZero(GasInt, "maxFeePerGas"),
accessList: omitZero(AccessList, "accessLists", dataIndex),
maxPriorityFee: omitZero(GasInt, "maxPriorityFeePerGas"),
maxFeePerDataGas: omitZero(GasInt, "maxFeePerDataGas"),
maxFeePerBlobGas: omitZero(GasInt, "maxFeePerBlobGas"),
versionedHashes: omitZero(VersionedHashes, "blobVersionedHashes")
)

View File

@ -179,8 +179,10 @@ proc parseEnv*(ctx: var TransContext, n: JsonNode) =
optional(ctx.env, UInt256, parentBaseFee)
optional(ctx.env, GasInt, parentGasUsed)
optional(ctx.env, GasInt, parentGasLimit)
optional(ctx.env, uint64, parentDataGasUsed)
optional(ctx.env, uint64, parentExcessDataGas)
optional(ctx.env, uint64, currentBlobGasUsed)
optional(ctx.env, uint64, currentExcessBlobGas)
optional(ctx.env, uint64, parentBlobGasUsed)
optional(ctx.env, uint64, parentExcessBlobGas)
if n.hasKey("blockHashes"):
let w = n["blockHashes"]
@ -234,7 +236,7 @@ proc parseTx(n: JsonNode, chainId: ChainID): Transaction =
required(tx, GasInt, maxPriorityFeePerGas)
required(tx, GasInt, maxFeePerGas)
omitZero(tx, AccessList, accessList)
required(tx, GasInt, maxFeePerDataGas)
required(tx, GasInt, maxFeePerBlobGas)
required(tx, VersionedHashes, blobVersionedHashes)
var eip155 = true
@ -440,7 +442,7 @@ proc `@@`*(x: ExecutionResult): JsonNode =
result["currentBaseFee"] = @@(x.currentBaseFee)
if x.withdrawalsRoot.isSome:
result["withdrawalsRoot"] = @@(x.withdrawalsRoot)
if x.dataGasUsed.isSome:
result["dataGasUsed"] = @@(x.dataGasUsed)
if x.excessDataGas.isSome:
result["excessDataGas"] = @@(x.excessDataGas)
if x.blobGasUsed.isSome:
result["blobGasUsed"] = @@(x.blobGasUsed)
if x.excessBlobGas.isSome:
result["excessBlobGas"] = @@(x.excessBlobGas)

View File

@ -14,6 +14,6 @@
"amount": "0x2a"
}
],
"parentDataGasUsed": "0x100",
"parentExcessDataGas": "0x100"
"parentBlobGasUsed": "0x100",
"parentExcessBlobGas": "0x100"
}

View File

@ -16,7 +16,7 @@
"gasUsed": "0x0",
"currentBaseFee": "0x500",
"withdrawalsRoot": "0x4921c0162c359755b2ae714a0978a1dad2eb8edce7ff9b38b9b6fc4cbc547eb5",
"dataGasUsed": "0x0",
"excessDataGas": "0x0"
"blobGasUsed": "0x0",
"excessBlobGas": "0x0"
}
}

View File

@ -6,8 +6,8 @@
"currentNumber" : "0x01",
"currentRandom" : "0x0000000000000000000000000000000000000000000000000000000000020000",
"currentTimestamp" : "0x03e8",
"parentDataGasUsed" : "0x2000",
"parentExcessDataGas" : "0x1000",
"parentBlobGasUsed" : "0x2000",
"parentExcessBlobGas" : "0x1000",
"previousHash" : "0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"withdrawals": []
}

View File

@ -25,7 +25,7 @@
],
"currentBaseFee": "0x7",
"withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
"dataGasUsed": "0x0",
"excessDataGas": "0x0"
"blobGasUsed": "0x0",
"excessBlobGas": "0x0"
}
}

View File

@ -99,7 +99,9 @@ proc envToHeader(env: EnvStruct): BlockHeader =
timestamp : env.currentTimestamp,
stateRoot : emptyRlpHash,
fee : env.currentBaseFee,
withdrawalsRoot: env.withdrawals.calcWithdrawalsRoot()
withdrawalsRoot: env.withdrawals.calcWithdrawalsRoot(),
blobGasUsed: env.currentBlobGasUsed,
excessBlobGas: env.currentExcessBlobGas
)
proc postState(db: AccountsCache, alloc: var GenesisAlloc) =
@ -213,7 +215,7 @@ proc exec(ctx: var TransContext,
vmState.receipts = newSeqOfCap[Receipt](txList.len)
vmState.cumulativeGasUsed = 0
var dataGasUsed = 0'u64
var blobGasUsed = 0'u64
for txIndex, txRes in txList:
if txRes.isErr:
rejected.add RejectedTx(
@ -253,7 +255,7 @@ proc exec(ctx: var TransContext,
rec, tx, sender, txIndex, gasUsed
)
includedTx.add tx
dataGasUsed += tx.getTotalDataGas
blobGasUsed += tx.getTotalBlobGas
# Add mining reward? (-1 means rewards are disabled)
if stateReward.isSome and stateReward.get >= 0:
@ -302,8 +304,8 @@ proc exec(ctx: var TransContext,
)
if fork >= FkCancun:
result.result.dataGasUsed = some dataGasUsed
result.result.excessDataGas = some calcExcessDataGas(vmState.parent)
result.result.blobGasUsed = some blobGasUsed
result.result.excessBlobGas = some calcExcessBlobGas(vmState.parent)
template wrapException(body: untyped) =
when wrapExceptionEnabled:
@ -408,8 +410,8 @@ proc transitionAction*(ctx: var TransContext, conf: T8NConf) =
difficulty: ctx.env.parentDifficulty.get(0.u256),
ommersHash: uncleHash,
blockNumber: ctx.env.currentNumber - 1.toBlockNumber,
dataGasUsed: ctx.env.parentDataGasUsed,
excessDataGas: ctx.env.parentExcessDataGas
blobGasUsed: ctx.env.parentBlobGasUsed,
excessBlobGas: ctx.env.parentExcessBlobGas
)
# Sanity check, to not `panic` in state_transition
@ -426,11 +428,11 @@ proc transitionAction*(ctx: var TransContext, conf: T8NConf) =
raise newError(ErrorConfig, "Shanghai config but missing 'withdrawals' in env section")
if com.isCancunOrLater(ctx.env.currentTimestamp):
if ctx.env.parentDataGasUsed.isNone:
raise newError(ErrorConfig, "Cancun config but missing 'parentDataGasUsed' in env section")
if ctx.env.parentBlobGasUsed.isNone:
raise newError(ErrorConfig, "Cancun config but missing 'parentBlobGasUsed' in env section")
if ctx.env.parentExcessDataGas.isNone:
raise newError(ErrorConfig, "Cancun config but missing 'parentExcessDataGas' in env section")
if ctx.env.parentExcessBlobGas.isNone:
raise newError(ErrorConfig, "Cancun config but missing 'parentExcessBlobGas' in env section")
let res = loadKzgTrustedSetup()
if res.isErr:

View File

@ -44,8 +44,10 @@ type
parentGasUsed*: Option[GasInt]
parentGasLimit*: Option[GasInt]
withdrawals*: Option[seq[Withdrawal]]
parentDataGasUsed*: Option[uint64]
parentExcessDataGas*: Option[uint64]
currentBlobGasUsed*: Option[uint64]
currentExcessBlobGas*: Option[uint64]
parentBlobGasUsed*: Option[uint64]
parentExcessBlobGas*: Option[uint64]
TxsType* = enum
TxsNone
@ -94,8 +96,8 @@ type
gasUsed*: GasInt
currentBaseFee*: Option[UInt256]
withdrawalsRoot*: Option[Hash256]
dataGasUsed*: Option[uint64]
excessDataGas*: Option[uint64]
blobGasUsed*: Option[uint64]
excessBlobGas*: Option[uint64]
const
ErrorEVM* = 2.T8NExitCode

2
vendor/nim-blscurve vendored

@ -1 +1 @@
Subproject commit d3920425c5c02b0a7766045c064c888cd5b83e72
Subproject commit 81ed3ff376e6549aead42e506861b3a6ef63b7fa

2
vendor/nim-chronos vendored

@ -1 +1 @@
Subproject commit 0035f4fa6692e85756aa192b4df84c21d3cacacb
Subproject commit c4b066a2c4faeedd564e8467a9416920bfb4b9a9

@ -1 +1 @@
Subproject commit 1f3acaf6e968ea8e4ec3eec177aebd50eef1040c
Subproject commit dbe8d61f7fbb1cb9d74b38f9012406c8071aa9e9

2
vendor/nim-eth vendored

@ -1 +1 @@
Subproject commit 26ae539598e31efbaa016f6694b9a60ea08fc4b6
Subproject commit 2ed8e991b543156dbf3faf0d000e1cfc168498d2

2
vendor/nim-evmc vendored

@ -1 +1 @@
Subproject commit 144b13e0ccef229bc9118311e1735d0a23ac4dd5
Subproject commit 78fb00187f19dd0306acab82a52f91ab40217f94

@ -1 +1 @@
Subproject commit 583974782f1d5487e16cc72289cd97e8897bc894
Subproject commit 720fc5e5c8e428d9d0af618e1e27c44b42350309

2
vendor/nim-json-rpc vendored

@ -1 +1 @@
Subproject commit 0bf2bcbe74a18a3c7a709d57108bb7b51e748a92
Subproject commit 32200345f80a3b5f72e15d1b4e9363363d95a1cd

2
vendor/nim-snappy vendored

@ -1 +1 @@
Subproject commit 7cb2e57a58619a6ca2be94db94591467a41d8476
Subproject commit ecbcee1d100140db6cb9c13d753d739fb5102fa3

@ -1 +1 @@
Subproject commit 17e8479a7495ac96480485782c09b6d4f4bcfa12
Subproject commit ffba69121689e14c0aa286c885d00b90889571e6

2
vendor/nim-web3 vendored

@ -1 +1 @@
Subproject commit 1f9fa11d0e63c16aa4ec30e1f7328ae61254d7d0
Subproject commit 04f56c593a035af1b7bebdc726543a2a73826412

2
vendor/nimbus-eth2 vendored

@ -1 +1 @@
Subproject commit 970f5dfc4e2df53d12ed71fc591e23ecc2bafb60
Subproject commit 8f184911311d5b891fc2e83420f21206463d422b

2
vendor/nimcrypto vendored

@ -1 +1 @@
Subproject commit 24e006df85927f64916e60511620583b11403178
Subproject commit f62df96cfc43f1e1c0acaf12807cfe99b3b45a9d