Skip to content

fix/geth submit txn bug#53

Merged
i-naman merged 10 commits into
mainfrom
fix/geth_submitTXNBug
Jun 30, 2026
Merged

fix/geth submit txn bug#53
i-naman merged 10 commits into
mainfrom
fix/geth_submitTXNBug

Conversation

@saishibunb

@saishibunb saishibunb commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

What

Fix EIP-1559 (type 2) transaction support end-to-end — parsing, sender recovery, fee history, and response formatting. Also fixes nil-panic crashes on contract deployments.

Why

MetaMask switched from type 0 to type 2 transactions after commit 965f86d added a non-null baseFeePerGas to eth_getBlockByNumber. JMDN never supported typed transactions, causing eth_sendRawTransaction to fail with "typed transaction too short" on every MetaMask submission. Additionally, several nil-pointer panics existed that would crash the node on contract deployments and any type 2 tx debug path.

How

Core tx parsing (Service.go)

  • rlp.DecodeBytesethTx.UnmarshalBinary: handles legacy, EIP-2930 (0x01), and EIP-1559 (0x02) prefixed transactions
  • NewEIP155SignerLatestSignerForChainID: correct from address recovery for all tx types
  • Nil-guarded all debug prints in convertEthTxToConfigTx (To, GasPrice, MaxFee, MaxPriorityFee, V, R, S)

Fee history (handlers.go + Service.go)

  • Uncommented eth_feeHistory handler (was fully commented out — MetaMask calls this before submitting type 2 txns)
  • Implementation returns flat 35 gwei for all baseFeePerGas entries — no DB reads; consistent with the constant used in eth_getBlockByNumber

Receipt (Service.go)

  • effectiveGasPrice now computed as min(maxFeePerGas, baseFee + maxPriorityFeePerGas) per EIP-1559 spec
  • effectiveGasPrice always emitted — fallback to 35 gwei constant when both fee fields are nil

Transaction response (handlers.go)

  • to: emits JSON null for contract deployments instead of "0x"
  • maxFeePerGas / maxPriorityFeePerGas: emitted for type 2 transactions
  • gasPrice: for type 2, returns effectiveGasPrice instead of "0x0"
  • chainId: always emitted; falls back to global chain ID for transactions stored before this field was tracked. Propagated through Types.Tx, ConvertTrabsactionToTx, marshalTx, marshalBlock, and forwardBlocks (WS)

eth_estimateGas (handlers.go)

  • toCallMsg now parses maxFeePerGas and maxPriorityFeePerGas from call object; added fields to Types.CallMsg

Service interface

  • Added GetChainIDValue() *big.Int — no-context accessor for the chain ID constant, used to populate chainId in tx/block responses without a DB round-trip

Testing

  • Submit a type 2 transaction via MetaMask (JMDT transfer) — previously failed with "typed transaction too short", should now succeed
  • Call eth_feeHistory via MetaMask or curl — previously returned method-not-found, now returns 35 gwei history
  • Verify eth_getTransactionByHash for a type 2 tx returns maxFeePerGas, maxPriorityFeePerGas, chainId, and correct gasPrice
  • Verify receipt effectiveGasPrice is min(maxFeePerGas, baseFee + tip) not just maxFeePerGas

Checklist

  • make build passes
  • make lint passes
  • make fmt-check passes
  • Commit messages follow conventional commits
  • No secrets or credentials in the diff

saishibunb and others added 9 commits June 30, 2026 20:12
- Replaced RLP decoding with UnmarshalBinary for transaction parsing to support all transaction types (legacy, EIP-2930, EIP-1559).
- Simplified fee history calculation by using a constant base fee instead of fetching from blocks, improving performance and reliability.
- Enhanced error handling and logging for better traceability during transaction processing and fee history retrieval.
- Added GetChainIDValue method to the Service interface for retrieving the chain ID value directly.
- Implemented GetChainIDValue in ServiceImpl to return the chain ID as a big.Int.
- Updated transaction logging to handle nil values for To, Value, ChainID, GasPrice, MaxFee, MaxPriorityFee, and signature fields, improving robustness and clarity in transaction data.
- Enhanced marshalBlock and marshalTx functions to include chain ID and effective gas price calculations, ensuring accurate transaction representation in RPC responses.
- Improved error handling and logging for better traceability during transaction processing.
…ions

- Enhanced the CheckSignature function to support EIP-2930 and EIP-1559 typed transactions by using LatestSignerForChainID for recovery.
- Adjusted handling of legacy transactions (V=27/28) to ensure compatibility with MetaMask's signing methods.
- Improved logging for better traceability during signature verification processes, including success and failure scenarios.
- Refactored fallback logic to ensure robust handling of different transaction types and chain IDs.
… binary encoding

- Removed unnecessary binary encoding logic for chain ID conversion in SetExpectedChainIDBig function.
- Updated transaction construction in checkTransactionHash to utilize tx.Type directly, enhancing clarity and maintainability.
- Simplified case handling for transaction types (EIP-1559, EIP-2930, Legacy) to improve readability and reduce complexity.
…saction

- Updated the convertToPbTransaction function to directly set the transaction type from config.Transaction.Type, improving clarity.
- Streamlined logic for legacy transactions to use GasPrice as MaxFee when MaxFee is unset, enhancing maintainability and readability.
- Updated the CheckBalanceWithCache function to use effective gas pricing for transaction cost calculations, accommodating both legacy and EIP-1559 transaction types.
- Introduced logic to determine the effective gas price based on GasPrice and MaxFee fields, improving accuracy in balance checks and transaction processing.
- Adjusted the formatting of cached signers in Security.go for improved readability and consistency.
- Ensured alignment of variable declarations to enhance code clarity.
- CheckAddressExistWithCache: remove nil-To rejection; skip receiver
  check only for contract deployments (tx.To == nil)
- allChecksWithConn: guard tx.To.Hex() span attr against nil (panic)
- Add signerMu RWMutex around expectedChainID + cached signers
- chainIDStr: default to 'legacy/none' instead of empty string
- TODO: nonce gap acceptance (>= vs == expectedNonce)
i-naman
i-naman previously approved these changes Jun 30, 2026
@i-naman i-naman merged commit 8ec46b0 into main Jun 30, 2026
3 checks passed
i-naman added a commit that referenced this pull request Jun 30, 2026
* fix(service): update transaction parsing and fee history logic

- Replaced RLP decoding with UnmarshalBinary for transaction parsing to support all transaction types (legacy, EIP-2930, EIP-1559).
- Simplified fee history calculation by using a constant base fee instead of fetching from blocks, improving performance and reliability.
- Enhanced error handling and logging for better traceability during transaction processing and fee history retrieval.

* feat(service): enhance service interface and transaction handling

- Added GetChainIDValue method to the Service interface for retrieving the chain ID value directly.
- Implemented GetChainIDValue in ServiceImpl to return the chain ID as a big.Int.
- Updated transaction logging to handle nil values for To, Value, ChainID, GasPrice, MaxFee, MaxPriorityFee, and signature fields, improving robustness and clarity in transaction data.
- Enhanced marshalBlock and marshalTx functions to include chain ID and effective gas price calculations, ensuring accurate transaction representation in RPC responses.
- Improved error handling and logging for better traceability during transaction processing.

* fix(security): update signature verification logic for typed transactions

- Enhanced the CheckSignature function to support EIP-2930 and EIP-1559 typed transactions by using LatestSignerForChainID for recovery.
- Adjusted handling of legacy transactions (V=27/28) to ensure compatibility with MetaMask's signing methods.
- Improved logging for better traceability during signature verification processes, including success and failure scenarios.
- Refactored fallback logic to ensure robust handling of different transaction types and chain IDs.

* refactor(security): streamline transaction handling and remove unused binary encoding

- Removed unnecessary binary encoding logic for chain ID conversion in SetExpectedChainIDBig function.
- Updated transaction construction in checkTransactionHash to utilize tx.Type directly, enhancing clarity and maintainability.
- Simplified case handling for transaction types (EIP-1559, EIP-2930, Legacy) to improve readability and reduce complexity.

* refactor(gRPC): simplify transaction type handling in convertToPbTransaction

- Updated the convertToPbTransaction function to directly set the transaction type from config.Transaction.Type, improving clarity.
- Streamlined logic for legacy transactions to use GasPrice as MaxFee when MaxFee is unset, enhancing maintainability and readability.

* refactor(security): enhance gas cost calculation for transactions

- Updated the CheckBalanceWithCache function to use effective gas pricing for transaction cost calculations, accommodating both legacy and EIP-1559 transaction types.
- Introduced logic to determine the effective gas price based on GasPrice and MaxFee fields, improving accuracy in balance checks and transaction processing.

* refactor(security): standardize variable formatting in Security.go

- Adjusted the formatting of cached signers in Security.go for improved readability and consistency.
- Ensured alignment of variable declarations to enhance code clarity.

* fix(security): contract deploy support + race guard on signer globals

- CheckAddressExistWithCache: remove nil-To rejection; skip receiver
  check only for contract deployments (tx.To == nil)
- allChecksWithConn: guard tx.To.Hex() span attr against nil (panic)
- Add signerMu RWMutex around expectedChainID + cached signers
- chainIDStr: default to 'legacy/none' instead of empty string
- TODO: nonce gap acceptance (>= vs == expectedNonce)

* style: fix whitespace alignment for signerMu declaration

---------

Co-authored-by: Naman Agrawal <35531672+i-naman@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants