|
// RPCMarshalHeader converts the given header to the RPC output . |
|
func RPCMarshalHeader(head *types.Header) map[string]interface{} { |
|
result := map[string]interface{}{ |
|
"number": (*hexutil.Big)(head.Number), |
|
"hash": head.Hash(), |
|
"parentHash": head.ParentHash, |
|
"nonce": head.Nonce, |
|
"mixHash": head.MixDigest, |
|
"sha3Uncles": head.UncleHash, |
|
"logsBloom": head.Bloom, |
|
"stateRoot": head.Root, |
|
"miner": head.Coinbase, |
|
"difficulty": (*hexutil.Big)(head.Difficulty), |
|
"extraData": hexutil.Bytes(head.Extra), |
|
"gasLimit": hexutil.Uint64(head.GasLimit), |
|
"gasUsed": hexutil.Uint64(head.GasUsed), |
|
"timestamp": hexutil.Uint64(head.Time), |
|
"transactionsRoot": head.TxHash, |
|
"receiptsRoot": head.ReceiptHash, |
|
} |
|
if head.BaseFee != nil { |
|
result["baseFeePerGas"] = (*hexutil.Big)(head.BaseFee) |
|
} |
|
if head.WithdrawalsHash != nil { |
|
result["withdrawalsRoot"] = head.WithdrawalsHash |
|
} |
|
if head.BlobGasUsed != nil { |
|
result["blobGasUsed"] = hexutil.Uint64(*head.BlobGasUsed) |
|
} |
|
if head.ExcessBlobGas != nil { |
|
result["excessBlobGas"] = hexutil.Uint64(*head.ExcessBlobGas) |
|
} |
|
if head.ParentBeaconRoot != nil { |
|
result["parentBeaconBlockRoot"] = head.ParentBeaconRoot |
|
} |
|
if head.RequestsHash != nil { |
|
result["requestsHash"] = head.RequestsHash |
|
} |
|
if head.BlockAccessListHash != nil { |
|
result["blockAccessListHash"] = head.BlockAccessListHash |
|
} |
|
if head.SlotNumber != nil { |
|
result["slotNumber"] = hexutil.Uint64(*head.SlotNumber) |
|
} |
|
return result |
|
} |
1.
eth_createAccessList: The access-list orchestration excludes recipients or created contracts and EIP-7702 authorities in addition to the documented sender/precompile exceptionsinternal/ethapi/api.go:1328-1345—go-ethereum/internal/ethapi/api.go
Lines 1328 to 1345 in 81ab8b5
eth/tracers/logger/access_list_tracer.go:112-127—go-ethereum/eth/tracers/logger/access_list_tracer.go
Lines 112 to 127 in 81ab8b5
NewAccessListTraceris constructed with anaddressesToExcludeset, and itsAccessList()-building loop skips any address present in that set before adding it to the result;AccessList(the orchestration function backing the endpoint) populates that exclusion set with more than just the sender and precompiles — it also adds the transaction's recipient/created-contract address and any EIP-7702 authorization authorities. The exclusion mechanism therefore has a broader scope by design than the documented "sender account and precompiles" exception list.eth_createAccessList2.
eth_createAccessList:eth_createAccessListacceptsBlockNumberOrHashselector encodings beyond an Object-only parameter schemaeth_createAccessListacceptsBlockNumberOrHashselector encodings beyond an Object-only parameter schema.internal/ethapi/api.go:1328-1345—go-ethereum/internal/ethapi/api.go
Lines 1328 to 1345 in 81ab8b5
internal/ethapi/api.go:1244-1258—go-ethereum/internal/ethapi/api.go
Lines 1244 to 1258 in 81ab8b5
BlockChainAPI.CreateAccessListdeclares its optional third parameter as*rpc.BlockNumberOrHash, a union type whose JSON unmarshaler accepts either an object ({"blockNumber": ...}/{"blockHash": ...}) or a bare quantity/tag string, and defaults torpc.LatestBlockNumberwhen the parameter is omitted entirely. Because the decoder is the sharedBlockNumberOrHashtype used across the API rather than an object-only schema, string/tag encodings are accepted in addition to the documented object form.eth_createAccessList3.
eth_call:eth_callaccepts an omitted block selector and defaults it tolatestrather than requiring the parametereth_callaccepts an omitted block selector and defaults it tolatestrather than requiring the parameter.internal/ethapi/api.go:854-867—go-ethereum/internal/ethapi/api.go
Lines 854 to 867 in 81ab8b5
internal/ethapi/api.go:838-846—go-ethereum/internal/ethapi/api.go
Lines 838 to 846 in 81ab8b5
BlockChainAPI.Callexplicitly guardsif blockNrOrHash == nil { latest := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber); blockNrOrHash = &latest }before delegating toDoCall; the parameter is typed as a pointer specifically so the handler can detect an omitted argument and substitute the latest block, rather than the JSON-RPC dispatcher rejecting the call for a missing required parameter.eth_call4.
eth_getHeaderByNumber:eth_getHeaderByNumberusesrpc.BlockNumberand accepts named block tags in addition to a Quantity-only schemaeth_getHeaderByNumberusesrpc.BlockNumberand accepts named block tags in addition to a Quantity-only schema.internal/ethapi/api.go:494-507—go-ethereum/internal/ethapi/api.go
Lines 494 to 507 in 81ab8b5
rpc/types.go:80-97—go-ethereum/rpc/types.go
Lines 80 to 97 in 81ab8b5
BlockChainAPI.GetHeaderByNumber(ctx, number rpc.BlockNumber)decodes its parameter withBlockNumber.UnmarshalJSON, which explicitly recognizes the string tags"earliest","latest","pending", and"finalized"(in addition to numeric quantities) and maps each to a sentinel value before any lookup happens. The parameter's real schema is therefore the tag-or-quantity union used throughout the RPC layer, not the Quantity-only schema the endpoint documentation states.eth_getHeaderByNumber5.
eth_getHeaderByNumber:eth_getHeaderByNumberdocumentation includes asizefield thatRPCMarshalHeaderdoes not emiteth_getHeaderByNumberdocumentation includes asizefield thatRPCMarshalHeaderdoes not emit.internal/ethapi/api.go:494-507—go-ethereum/internal/ethapi/api.go
Lines 494 to 507 in 81ab8b5
internal/ethapi/api.go:984-1001—go-ethereum/internal/ethapi/api.go
Lines 984 to 1001 in 81ab8b5
GetHeaderByNumberreturns exactly the map built byRPCMarshalHeader, and that function's field list (number,hash,parentHash,nonce,mixHash,sha3Uncles,logsBloom,stateRoot,miner,difficulty,extraData,gasLimit,gasUsed,timestamp,transactionsRoot,receiptsRoot, …) never assigns asizekey — block/header size is a serialization-time property of a full RLP-encoded block, not of a header struct in isolation, so no code path computes it here. The documentedsizefield describes block-level output, not what this header-only marshaler produces.eth_getHeaderByNumber6.
eth_getLogs/eth_newFilter: For log ranges,earliestresolves to a historical/pruning-cutoff block rather than transactions not yet in a blockearliestresolves to a historical/pruning-cutoff block rather than transactions not yet in a block.eth/filters/filter_system.go:325-342—go-ethereum/eth/filters/filter_system.go
Lines 325 to 342 in 81ab8b5
eth/filters/api.go:480-497—go-ethereum/eth/filters/api.go
Lines 480 to 497 in 81ab8b5
EventSystem.SubscribeLogsandFilterAPI.GetLogstranslate afromselector equal torpc.EarliestBlockNumberintoes.backend.HistoryPruningCutoff()(the oldest block number the node still retains history for), then reject the query outright with aPrunedHistoryErrorif the resolved range still falls below that cutoff.earliestis thus wired to mean "the oldest historically available mined block," the opposite semantic from "transactions not yet included in a block," which the shared JSON-RPC spec'sfromBlock/toBlockwording assigns topending/earliestin some tag descriptions.eth_getLogs,eth_newFilter7.
eth_getLogs/eth_newFilter: Pending log-range endpoints are rejected rather than returning the documented unmined-transaction range semanticseth/filters/filter_system.go:301-318—go-ethereum/eth/filters/filter_system.go
Lines 301 to 318 in 81ab8b5
accounts/abi/bind/v2/base.go:485-502—go-ethereum/accounts/abi/bind/v2/base.go
Lines 485 to 502 in 81ab8b5
EventSystem.SubscribeLogsresolvesfromBlock/toBlockinto concreterpc.BlockNumbervalues and only proceeds along the "mined logs" subscription path (from == rpc.LatestBlockNumber && to == rpc.LatestBlockNumber, or an explicit non-negative range); apendingselector on either end of the range falls outside both accepted branches and returnserrPendingLogsUnsupportedbefore any log matching runs. No code path assembles a result set out of unmined/pending transactions for a range query, so the documented "pending range returns unmined-transaction logs" behavior has no implementation to back it.eth_getLogs,eth_newFilter8.
eth_newFilter:eth_newFilterdoes not support safe/finalized range sentinels despite the documented selector availability and semanticseth_newFilterdoes not support safe/finalized range sentinels despite the documented selector availability and semantics.eth/filters/api.go:465-482—go-ethereum/eth/filters/api.go
Lines 465 to 482 in 81ab8b5
accounts/abi/bind/v2/base.go:461-478—go-ethereum/accounts/abi/bind/v2/base.go
Lines 461 to 478 in 81ab8b5
FilterAPI.GetLogs's range-construction branch derivesbegin/endfromrpc.LatestBlockNumber.Int64()unless the caller supplied aFromBlock/ToBlock, and the only special-cased values checked afterward are negative sentinels tied tolatest/pending/earliest; there is no branch that resolves asafeorfinalizedtag to the chain's current safe/finalized head. The filter-construction code simply has no lookup for those two tags in the range path, so a request using them either falls through to an unintended interpretation or is rejected, contrary to the documented tag support.eth_newFilter9.
eth_newPendingTransactionFilter:eth_newPendingTransactionFilterhas an optionalfullTxparameter despite documentation saying it has noneeth_newPendingTransactionFilterhas an optionalfullTxparameter despite documentation saying it has none.eth/filters/api.go:149-166—go-ethereum/eth/filters/api.go
Lines 149 to 166 in 81ab8b5
eth/filters/filter_system.go:388-401—go-ethereum/eth/filters/filter_system.go
Lines 388 to 401 in 81ab8b5
FilterAPI.NewPendingTransactionFilter(fullTx *bool) rpc.IDaccepts an optional boolean pointer and storesfullTx: fullTx != nil && *fullTxon the created filter, which later controls whether subsequentgetFilterChangespolls return full transaction objects or bare hashes for that filter. The parameter is real and functional in the handler's signature; the documentation describing the method as taking no arguments does not reflect this optional flag.eth_newPendingTransactionFilter10.
eth_getBlockByHash/eth_getBlockByNumber/eth_getHeaderByNumber: Current RPC header/block marshaling omitstotalDifficulty, although the documented block/header schemas and examples still require ittotalDifficulty, although the documented block/header schemas and examples still require it.internal/ethapi/api.go:983-1028—go-ethereum/internal/ethapi/api.go
Lines 983 to 1028 in 81ab8b5
internal/ethapi/api.go:1030-1036—go-ethereum/internal/ethapi/api.go
Lines 1030 to 1036 in 81ab8b5
RPCMarshalHeader, the single function that builds the JSON map foreth_getHeaderByNumberand (viaRPCMarshalBlock, which calls it and layers on block-level fields likesize) foreth_getBlockByHash/eth_getBlockByNumber, populates a fixed field list —numberthroughreceiptsRoot, plus conditional post-merge/EIP fields such asbaseFeePerGas,withdrawalsRoot,blobGasUsed,excessBlobGas,parentBeaconBlockRoot,requestsHash,blockAccessListHash, andslotNumber— that never queries or attaches a chain-cumulative total-difficulty value, which would require an extra database lookup outside the header struct itself. Post-merge chains have a constant, uninformative total difficulty, so the field's computation and inclusion were dropped from both marshalers, leaving the documented schema and examples (written for the pre-merge, difficulty-bearing chain) stale across all three endpoints.eth_getBlockByHash,eth_getBlockByNumber,eth_getHeaderByNumber11.
eth_sendTransaction:eth_sendTransactionselects contract creation from a niltoaddress, not solely from data containing codeeth_sendTransactionselects contract creation from a niltoaddress, not solely from data containing code.core/state_transition.go:666-683—go-ethereum/core/state_transition.go
Lines 666 to 683 in 81ab8b5
internal/ethapi/api.go:1674-1691—go-ethereum/internal/ethapi/api.go
Lines 1674 to 1691 in 81ab8b5
stateTransition.executecomputescontractCreation = msg.To == nilas the sole condition that routes execution down the contract-creation path; the presence or shape ofmsg.Data/init code plays no role in that branch decision.TransactionAPI.SendTransactionpasses the caller'sargs.Tostraight through unchanged, so whether a submitted transaction is treated as a creation is determined entirely by omitting/nulling thetofield, not by inspecting whether the supplied data looks like contract bytecode.eth_sendTransaction12.
eth_sendTransaction:eth_sendTransactiondynamically estimates omitted gas rather than applying the documented fixed 90000 defaulteth_sendTransactiondynamically estimates omitted gas rather than applying the documented fixed 90000 default.internal/ethapi/transaction_args.go:103-120—go-ethereum/internal/ethapi/transaction_args.go
Lines 103 to 120 in 81ab8b5
internal/ethapi/api.go:1674-1691—go-ethereum/internal/ethapi/api.go
Lines 1674 to 1691 in 81ab8b5
TransactionArgs.setDefaults, invoked on the path fromSendTransaction, fills inValueandNoncewhen absent but leavesGasto a separate gas-estimation routine (DoEstimateGas-style simulation against current state) rather than assigning a hardcoded constant; no literal90000value appears anywhere in the default-filling code. The documented fixed default describes an old, static-default behavior that the current implementation replaced with a dynamic, per-call gas estimate.eth_sendTransaction13.
eth_sendTransaction:eth_sendTransactionreturns the submitted transaction hash on success and pairs a zero hash only with an error, not as a successful "unavailable" sentineleth_sendTransactionreturns the submitted transaction hash on success and pairs a zero hash only with an error, not as a successful "unavailable" sentinel.internal/ethapi/api.go:1640-1657—go-ethereum/internal/ethapi/api.go
Lines 1640 to 1657 in 81ab8b5
internal/ethapi/api.go:1674-1691—go-ethereum/internal/ethapi/api.go
Lines 1674 to 1691 in 81ab8b5
SubmitTransactionthat yieldscommon.Hash{}(the zero hash) is paired with a non-nilerrorvalue (e.g. fee-cap rejection, unprotected-transaction rejection,SendTxfailure), and the only path that reaches the final success return computes and returnstx.Hash(), the real submitted transaction's hash. There is no branch inSubmitTransactionorTransactionAPI.SendTransactionthat returns a zero hash together with a nil error, so a zero hash can never be read as a successful "hash unavailable" sentinel — it always accompanies a request failure.eth_sendTransaction14.
eth_signTransaction:eth_signTransactionrequiresgasand does not supply the documented 90000 defaulteth_signTransactionrequiresgasand does not supply the documented 90000 default.internal/ethapi/api.go:944-961—go-ethereum/internal/ethapi/api.go
Lines 944 to 961 in 81ab8b5
internal/ethapi/api.go:1890-1907—go-ethereum/internal/ethapi/api.go
Lines 1890 to 1907 in 81ab8b5
TransactionAPI.SignTransactionopens withif args.Gas == nil { return nil, errors.New("gas not specified") }, an unconditional early error rather than a default assignment; this is distinct fromDoEstimateGas's helper path (used by other endpoints), which does allocate a zero-valuedargs.Gasbefore estimating. BecauseSignTransactionnever reaches any gas-filling logic, a caller omittinggasis rejected outright instead of receiving the documented fixed 90000 fallback.eth_signTransaction15.
eth_signTransaction:eth_signTransactionrejects a missingnonce, contrary to documentation that marksnonceoptionaleth_signTransactionrejects a missingnonce, contrary to documentation that marksnonceoptional.internal/ethapi/api.go:1890-1907—go-ethereum/internal/ethapi/api.go
Lines 1890 to 1907 in 81ab8b5
internal/ethapi/transaction_args.go:132-149—go-ethereum/internal/ethapi/transaction_args.go
Lines 132 to 149 in 81ab8b5
TransactionAPI.SignTransactioncontains an explicitif args.Nonce == nil { return nil, errors.New("nonce not specified") }guard before any signing occurs; unlikeSendTransaction, which auto-fills a missing nonce from the pending pool state under a per-address lock,SignTransactionhas no equivalent nonce-defaulting branch. The endpoint therefore treatsnonceas a hard requirement rather than the optional, auto-assigned field the documentation describes.eth_signTransaction16.
eth_signTransaction:eth_signTransactionreturns a structuredSignTransactionResult; RLP bytes are only itsRawfield, not a top-level DATA/RLP resulteth_signTransactionreturns a structuredSignTransactionResult; RLP bytes are only itsRawfield, not a top-level DATA/RLP result.core/types/transaction.go:133-140—go-ethereum/core/types/transaction.go
Lines 133 to 140 in 81ab8b5
internal/ethapi/api.go:1918-1935—go-ethereum/internal/ethapi/api.go
Lines 1918 to 1935 in 81ab8b5
SignTransactionobtains the encoded bytes viasigned.MarshalBinary()(which RLP/typed-encodes the transaction) and then returns&SignTransactionResult{data, signed}, nil— a two-field struct pairing the raw bytes with the structured, signed transaction object — rather than returningdataalone. The JSON-RPC response is therefore always theSignTransactionResultobject, with the RLP bytes reachable only under itsraw/Rawkey, not as a bare top-level DATA value as some documentation phrasing implies.eth_signTransaction17.
eth_signTransaction:eth_signTransactiondoes not consume a transaction-type input field; transaction type is inferred from other fieldseth_signTransactiondoes not consume a transaction-type input field; transaction type is inferred from other fields.internal/ethapi/api.go:1890-1907—go-ethereum/internal/ethapi/api.go
Lines 1890 to 1907 in 81ab8b5
internal/ethapi/transaction_args.go:118-135—go-ethereum/internal/ethapi/transaction_args.go
Lines 118 to 135 in 81ab8b5
TransactionArgs.setDefaultsderives the effective transaction shape from which optional fields are populated (e.g. presence ofBlobHashesselects a blob transaction, presence of fee-market fields vs.GasPriceselects EIP-1559 vs. legacy, presence ofAuthorizationListselects EIP-7702), with no dedicatedtypeinput read or required anywhere in the path feedingTransactionAPI.SignTransaction. The resulting transaction's type is therefore computed from which combination of other fields is set, not decoded from a caller-supplied type parameter.eth_signTransaction18.
eth_simulateV1:eth_simulateV1advances an unspecified block time by a 12-second increment, not by oneeth_simulateV1advances an unspecified block time by a 12-second increment, not by one.internal/ethapi/simulate.go:559-576—go-ethereum/internal/ethapi/simulate.go
Lines 559 to 576 in 81ab8b5
internal/ethapi/simulate.go:96-112—go-ethereum/internal/ethapi/simulate.go
Lines 96 to 112 in 81ab8b5
simulator.makeHeadersbuilds each simulated block's header from the previous one viaoverrides.MakeHeader, and when no explicittimeoverride is supplied for a block, the timestamp step used is the chain's configured post-merge slot time (12 seconds on mainnet-shaped configs), matching real block spacing, rather than a literal one-second increment. The documentation's "incremented by one" wording describes an older or simplified default that does not match the 12-second slot-time step the simulator actually applies.eth_simulateV119.
eth_simulateV1:eth_simulateV1failure encoding does not always put return/error bytes in the documented fields: revert data moves toerror.dataand non-revert failures can omit dataeth_simulateV1failure encoding does not always put return/error bytes in the documented fields: revert data moves toerror.dataand non-revert failures can omit data.internal/ethapi/simulate.go:372-389—go-ethereum/internal/ethapi/simulate.go
Lines 372 to 389 in 81ab8b5
core/state_transition.go:64-69—go-ethereum/core/state_transition.go
Lines 64 to 69 in 81ab8b5
simulator.processBlockbranches onerrors.Is(result.Err, vm.ErrExecutionReverted): only in that case does it callresult.Revert()(which returns the raw return bytes solely when the error is exactlyErrExecutionReverted) and pack them intocallError.Dataalongside the decoded revert message; any other VM error sets onlycallError.Message/Codewith noDataat all, and the call's ownreturnData-style field is never populated for a failed call. Revert bytes therefore surface undererror.data, not the documented top-levelreturnData, and non-revert failures can legitimately carry no data field at all.eth_simulateV120.
eth_getBlockByNumber:GetBlockByNumber's pending special case nulls onlyhash,nonce, andminer, leaving the pending block'snumbernumeric although the delegatedeth_getBlockByHashschema declaresnumbernull for pending blocksGetBlockByNumber's pending special case nulls onlyhash,nonce, andminer, leaving the pending block'snumbernumeric although the delegatedeth_getBlockByHashschema declaresnumbernull for pending blocks.internal/ethapi/api.go:525-538—go-ethereum/internal/ethapi/api.go
Lines 525 to 538 in 81ab8b5
BlockChainAPI.GetBlockByNumberbuilds its response fromRPCMarshalBlock, and for the pending case only loops over the fixed list[]string{"hash", "nonce", "miner"}to force those three keys tonil;numberis never included in that nulling list, so it keeps whatever numeric valueRPCMarshalBlock/RPCMarshalHeaderassigned from the pending header.eth_getBlockByNumber's documentation defers entirely toeth_getBlockByHash's schema, which statesnumberisnullfor a pending block, but the implementation's hardcoded nulled-field set was never extended to covernumber, so the delegated contract is only partially honored.eth_getBlockByNumber