Fix issue with lastresultshash mismatch#2720
Merged
arajasek merged 5 commits intoasr/rpc-gigafrom Jan 20, 2026
Merged
Conversation
|
The latest Buf updates on your PR. Results from workflow Buf / buf (pull_request).
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## asr/rpc-giga #2720 +/- ##
================================================
+ Coverage 43.98% 43.99% +0.01%
================================================
Files 1980 1980
Lines 162757 162810 +53
================================================
+ Hits 71591 71634 +43
- Misses 84645 84659 +14
+ Partials 6521 6517 -4
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
arajasek
approved these changes
Jan 20, 2026
arajasek
pushed a commit
that referenced
this pull request
Jan 26, 2026
Fixed critical issues causing `LastResultsHash` mismatch between the
standard and giga executors, which was causing consensus failures when
running nodes with `GIGA_EXECUTOR` enabled.
The `LastResultsHash` is computed from only 4 deterministic fields of
each `ExecTxResult` (defined in `deterministicExecTxResult` in
`sei-tendermint/abci/types/types.go`):
- `Code`
- `Data`
- `GasWanted`
- `GasUsed`
The giga executor was producing different values for two of these
fields.
The giga executor was not setting `GasWanted` (defaulted to 0), while
the standard executor sets it to the transaction's gas limit.
```go
// Before: GasWanted not set (defaults to 0)
// After:
gasWanted := int64(ethTx.Gas())
```
The giga executor was putting raw receipt bytes in the `Data` field,
while the standard executor wraps `MsgEVMTransactionResponse` in
`TxMsgData`:
```go
// Before: Data = receiptBytes (raw marshaled receipt)
// After: Matches standard executor format
evmResponse := &evmtypes.MsgEVMTransactionResponse{
GasUsed: execResult.UsedGas,
VmError: vmError,
ReturnData: execResult.ReturnData,
Hash: ethTx.Hash().Hex(),
Logs: evmtypes.NewLogsFromEth(stateDB.GetAllLogs()),
}
txMsgData := &sdk.TxMsgData{Data: []*sdk.MsgData{{MsgType: msgTypeURL, Data: evmResponseBytes}}}
// Data = marshaled txMsgData
```
Added logging to aid future debugging of consensus issues:
| Level | Location | What's Logged |
|-------|----------|---------------|
| **Error** | `ValidateBlock` on mismatch | Expected vs got hash, block
height, numTxs, blockHash |
| **Info** | `ApplyBlock` after hash computation | Computed hash,
height, txCount |
| **Debug** | `ApplyBlock` per-tx | Code, GasWanted, GasUsed, dataLen
for each tx |
- `app/app.go` - Fixed giga executor `GasWanted` and `Data` field format
- `sei-tendermint/internal/state/execution.go` - Added LastResultsHash
debugging logs
Run a multi-node cluster with one node using `GIGA_EXECUTOR=true` and
verify blocks reach consensus without `LastResultsHash` mismatch errors.
arajasek
pushed a commit
that referenced
this pull request
Jan 26, 2026
Fixed critical issues causing `LastResultsHash` mismatch between the
standard and giga executors, which was causing consensus failures when
running nodes with `GIGA_EXECUTOR` enabled.
The `LastResultsHash` is computed from only 4 deterministic fields of
each `ExecTxResult` (defined in `deterministicExecTxResult` in
`sei-tendermint/abci/types/types.go`):
- `Code`
- `Data`
- `GasWanted`
- `GasUsed`
The giga executor was producing different values for two of these
fields.
The giga executor was not setting `GasWanted` (defaulted to 0), while
the standard executor sets it to the transaction's gas limit.
```go
// Before: GasWanted not set (defaults to 0)
// After:
gasWanted := int64(ethTx.Gas())
```
The giga executor was putting raw receipt bytes in the `Data` field,
while the standard executor wraps `MsgEVMTransactionResponse` in
`TxMsgData`:
```go
// Before: Data = receiptBytes (raw marshaled receipt)
// After: Matches standard executor format
evmResponse := &evmtypes.MsgEVMTransactionResponse{
GasUsed: execResult.UsedGas,
VmError: vmError,
ReturnData: execResult.ReturnData,
Hash: ethTx.Hash().Hex(),
Logs: evmtypes.NewLogsFromEth(stateDB.GetAllLogs()),
}
txMsgData := &sdk.TxMsgData{Data: []*sdk.MsgData{{MsgType: msgTypeURL, Data: evmResponseBytes}}}
// Data = marshaled txMsgData
```
Added logging to aid future debugging of consensus issues:
| Level | Location | What's Logged |
|-------|----------|---------------|
| **Error** | `ValidateBlock` on mismatch | Expected vs got hash, block
height, numTxs, blockHash |
| **Info** | `ApplyBlock` after hash computation | Computed hash,
height, txCount |
| **Debug** | `ApplyBlock` per-tx | Code, GasWanted, GasUsed, dataLen
for each tx |
- `app/app.go` - Fixed giga executor `GasWanted` and `Data` field format
- `sei-tendermint/internal/state/execution.go` - Added LastResultsHash
debugging logs
Run a multi-node cluster with one node using `GIGA_EXECUTOR=true` and
verify blocks reach consensus without `LastResultsHash` mismatch errors.
arajasek
pushed a commit
that referenced
this pull request
Jan 26, 2026
Fixed critical issues causing `LastResultsHash` mismatch between the
standard and giga executors, which was causing consensus failures when
running nodes with `GIGA_EXECUTOR` enabled.
The `LastResultsHash` is computed from only 4 deterministic fields of
each `ExecTxResult` (defined in `deterministicExecTxResult` in
`sei-tendermint/abci/types/types.go`):
- `Code`
- `Data`
- `GasWanted`
- `GasUsed`
The giga executor was producing different values for two of these
fields.
The giga executor was not setting `GasWanted` (defaulted to 0), while
the standard executor sets it to the transaction's gas limit.
```go
// Before: GasWanted not set (defaults to 0)
// After:
gasWanted := int64(ethTx.Gas())
```
The giga executor was putting raw receipt bytes in the `Data` field,
while the standard executor wraps `MsgEVMTransactionResponse` in
`TxMsgData`:
```go
// Before: Data = receiptBytes (raw marshaled receipt)
// After: Matches standard executor format
evmResponse := &evmtypes.MsgEVMTransactionResponse{
GasUsed: execResult.UsedGas,
VmError: vmError,
ReturnData: execResult.ReturnData,
Hash: ethTx.Hash().Hex(),
Logs: evmtypes.NewLogsFromEth(stateDB.GetAllLogs()),
}
txMsgData := &sdk.TxMsgData{Data: []*sdk.MsgData{{MsgType: msgTypeURL, Data: evmResponseBytes}}}
// Data = marshaled txMsgData
```
Added logging to aid future debugging of consensus issues:
| Level | Location | What's Logged |
|-------|----------|---------------|
| **Error** | `ValidateBlock` on mismatch | Expected vs got hash, block
height, numTxs, blockHash |
| **Info** | `ApplyBlock` after hash computation | Computed hash,
height, txCount |
| **Debug** | `ApplyBlock` per-tx | Code, GasWanted, GasUsed, dataLen
for each tx |
- `app/app.go` - Fixed giga executor `GasWanted` and `Data` field format
- `sei-tendermint/internal/state/execution.go` - Added LastResultsHash
debugging logs
Run a multi-node cluster with one node using `GIGA_EXECUTOR=true` and
verify blocks reach consensus without `LastResultsHash` mismatch errors.
arajasek
pushed a commit
that referenced
this pull request
Jan 27, 2026
Fixed critical issues causing `LastResultsHash` mismatch between the
standard and giga executors, which was causing consensus failures when
running nodes with `GIGA_EXECUTOR` enabled.
The `LastResultsHash` is computed from only 4 deterministic fields of
each `ExecTxResult` (defined in `deterministicExecTxResult` in
`sei-tendermint/abci/types/types.go`):
- `Code`
- `Data`
- `GasWanted`
- `GasUsed`
The giga executor was producing different values for two of these
fields.
The giga executor was not setting `GasWanted` (defaulted to 0), while
the standard executor sets it to the transaction's gas limit.
```go
// Before: GasWanted not set (defaults to 0)
// After:
gasWanted := int64(ethTx.Gas())
```
The giga executor was putting raw receipt bytes in the `Data` field,
while the standard executor wraps `MsgEVMTransactionResponse` in
`TxMsgData`:
```go
// Before: Data = receiptBytes (raw marshaled receipt)
// After: Matches standard executor format
evmResponse := &evmtypes.MsgEVMTransactionResponse{
GasUsed: execResult.UsedGas,
VmError: vmError,
ReturnData: execResult.ReturnData,
Hash: ethTx.Hash().Hex(),
Logs: evmtypes.NewLogsFromEth(stateDB.GetAllLogs()),
}
txMsgData := &sdk.TxMsgData{Data: []*sdk.MsgData{{MsgType: msgTypeURL, Data: evmResponseBytes}}}
// Data = marshaled txMsgData
```
Added logging to aid future debugging of consensus issues:
| Level | Location | What's Logged |
|-------|----------|---------------|
| **Error** | `ValidateBlock` on mismatch | Expected vs got hash, block
height, numTxs, blockHash |
| **Info** | `ApplyBlock` after hash computation | Computed hash,
height, txCount |
| **Debug** | `ApplyBlock` per-tx | Code, GasWanted, GasUsed, dataLen
for each tx |
- `app/app.go` - Fixed giga executor `GasWanted` and `Data` field format
- `sei-tendermint/internal/state/execution.go` - Added LastResultsHash
debugging logs
Run a multi-node cluster with one node using `GIGA_EXECUTOR=true` and
verify blocks reach consensus without `LastResultsHash` mismatch errors.
arajasek
pushed a commit
that referenced
this pull request
Jan 27, 2026
Fixed critical issues causing `LastResultsHash` mismatch between the
standard and giga executors, which was causing consensus failures when
running nodes with `GIGA_EXECUTOR` enabled.
The `LastResultsHash` is computed from only 4 deterministic fields of
each `ExecTxResult` (defined in `deterministicExecTxResult` in
`sei-tendermint/abci/types/types.go`):
- `Code`
- `Data`
- `GasWanted`
- `GasUsed`
The giga executor was producing different values for two of these
fields.
The giga executor was not setting `GasWanted` (defaulted to 0), while
the standard executor sets it to the transaction's gas limit.
```go
// Before: GasWanted not set (defaults to 0)
// After:
gasWanted := int64(ethTx.Gas())
```
The giga executor was putting raw receipt bytes in the `Data` field,
while the standard executor wraps `MsgEVMTransactionResponse` in
`TxMsgData`:
```go
// Before: Data = receiptBytes (raw marshaled receipt)
// After: Matches standard executor format
evmResponse := &evmtypes.MsgEVMTransactionResponse{
GasUsed: execResult.UsedGas,
VmError: vmError,
ReturnData: execResult.ReturnData,
Hash: ethTx.Hash().Hex(),
Logs: evmtypes.NewLogsFromEth(stateDB.GetAllLogs()),
}
txMsgData := &sdk.TxMsgData{Data: []*sdk.MsgData{{MsgType: msgTypeURL, Data: evmResponseBytes}}}
// Data = marshaled txMsgData
```
Added logging to aid future debugging of consensus issues:
| Level | Location | What's Logged |
|-------|----------|---------------|
| **Error** | `ValidateBlock` on mismatch | Expected vs got hash, block
height, numTxs, blockHash |
| **Info** | `ApplyBlock` after hash computation | Computed hash,
height, txCount |
| **Debug** | `ApplyBlock` per-tx | Code, GasWanted, GasUsed, dataLen
for each tx |
- `app/app.go` - Fixed giga executor `GasWanted` and `Data` field format
- `sei-tendermint/internal/state/execution.go` - Added LastResultsHash
debugging logs
Run a multi-node cluster with one node using `GIGA_EXECUTOR=true` and
verify blocks reach consensus without `LastResultsHash` mismatch errors.
arajasek
pushed a commit
that referenced
this pull request
Jan 27, 2026
Fixed critical issues causing `LastResultsHash` mismatch between the
standard and giga executors, which was causing consensus failures when
running nodes with `GIGA_EXECUTOR` enabled.
The `LastResultsHash` is computed from only 4 deterministic fields of
each `ExecTxResult` (defined in `deterministicExecTxResult` in
`sei-tendermint/abci/types/types.go`):
- `Code`
- `Data`
- `GasWanted`
- `GasUsed`
The giga executor was producing different values for two of these
fields.
The giga executor was not setting `GasWanted` (defaulted to 0), while
the standard executor sets it to the transaction's gas limit.
```go
// Before: GasWanted not set (defaults to 0)
// After:
gasWanted := int64(ethTx.Gas())
```
The giga executor was putting raw receipt bytes in the `Data` field,
while the standard executor wraps `MsgEVMTransactionResponse` in
`TxMsgData`:
```go
// Before: Data = receiptBytes (raw marshaled receipt)
// After: Matches standard executor format
evmResponse := &evmtypes.MsgEVMTransactionResponse{
GasUsed: execResult.UsedGas,
VmError: vmError,
ReturnData: execResult.ReturnData,
Hash: ethTx.Hash().Hex(),
Logs: evmtypes.NewLogsFromEth(stateDB.GetAllLogs()),
}
txMsgData := &sdk.TxMsgData{Data: []*sdk.MsgData{{MsgType: msgTypeURL, Data: evmResponseBytes}}}
// Data = marshaled txMsgData
```
Added logging to aid future debugging of consensus issues:
| Level | Location | What's Logged |
|-------|----------|---------------|
| **Error** | `ValidateBlock` on mismatch | Expected vs got hash, block
height, numTxs, blockHash |
| **Info** | `ApplyBlock` after hash computation | Computed hash,
height, txCount |
| **Debug** | `ApplyBlock` per-tx | Code, GasWanted, GasUsed, dataLen
for each tx |
- `app/app.go` - Fixed giga executor `GasWanted` and `Data` field format
- `sei-tendermint/internal/state/execution.go` - Added LastResultsHash
debugging logs
Run a multi-node cluster with one node using `GIGA_EXECUTOR=true` and
verify blocks reach consensus without `LastResultsHash` mismatch errors.
arajasek
pushed a commit
that referenced
this pull request
Jan 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix: Giga Executor LastResultsHash Mismatch
Summary
Fixed critical issues causing
LastResultsHashmismatch between the standard and giga executors, which was causing consensus failures when running nodes withGIGA_EXECUTORenabled.Root Cause
The
LastResultsHashis computed from only 4 deterministic fields of eachExecTxResult(defined indeterministicExecTxResultinsei-tendermint/abci/types/types.go):CodeDataGasWantedGasUsedThe giga executor was producing different values for two of these fields.
Fixes
1. Missing
GasWantedfield (app/app.go)The giga executor was not setting
GasWanted(defaulted to 0), while the standard executor sets it to the transaction's gas limit.2. Different
Datafield format (app/app.go)The giga executor was putting raw receipt bytes in the
Datafield, while the standard executor wrapsMsgEVMTransactionResponseinTxMsgData:Logging Improvements (
sei-tendermint/internal/state/execution.go)Added logging to aid future debugging of consensus issues:
ValidateBlockon mismatchApplyBlockafter hash computationApplyBlockper-txFiles Changed
app/app.go- Fixed giga executorGasWantedandDatafield formatsei-tendermint/internal/state/execution.go- Added LastResultsHash debugging logsTesting
Run a multi-node cluster with one node using
GIGA_EXECUTOR=trueand verify blocks reach consensus withoutLastResultsHashmismatch errors.