Skip to content
Open
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
6 changes: 6 additions & 0 deletions .github/workflows/integration-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,12 @@ jobs:
"./integration_test/evm_module/scripts/evm_giga_tests.sh"
]
},
{
name: "EVM GIGA Mixed (Determinism)",
scripts: [
"./integration_test/evm_module/scripts/evm_giga_mixed_tests.sh"
]
},
]
steps:
- uses: actions/checkout@v3
Expand Down
51 changes: 51 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,57 @@ giga-integration-test:
@echo "=== GIGA Integration Tests Complete ==="
.PHONY: giga-integration-test

# Run a mixed-mode cluster: node 0 uses GIGA_EXECUTOR, nodes 1-3 use standard V2.
# Any determinism divergence between giga and V2 will cause the giga node to halt.
# Use this with hardhat tests to find failing transaction patterns.
docker-cluster-start-giga-mixed: docker-cluster-stop build-docker-node
@rm -rf $(PROJECT_HOME)/build/generated
@mkdir -p $(shell go env GOPATH)/pkg/mod
@mkdir -p $(shell go env GOCACHE)
@cd docker && \
if [ "$${DOCKER_DETACH:-}" = "true" ]; then \
DETACH_FLAG="-d"; \
else \
DETACH_FLAG=""; \
fi; \
DOCKER_PLATFORM=$(DOCKER_PLATFORM) USERID=$(shell id -u) GROUPID=$(shell id -g) GOCACHE=$(shell go env GOCACHE) NUM_ACCOUNTS=10 INVARIANT_CHECK_INTERVAL=${INVARIANT_CHECK_INTERVAL} UPGRADE_VERSION_LIST=${UPGRADE_VERSION_LIST} MOCK_BALANCES=${MOCK_BALANCES} \
docker compose -f docker-compose.yml -f docker-compose.giga-mixed.yml up $$DETACH_FLAG
.PHONY: docker-cluster-start-giga-mixed

# Run the giga mixed-mode integration test.
# Starts a cluster where only node 0 runs giga (sequential), nodes 1-3 run standard V2.
# Then runs hardhat tests. If giga produces different results, node 0 will halt.
giga-mixed-integration-test:
@echo "=== Starting GIGA Mixed-Mode Integration Tests ==="
@echo "=== Node 0: GIGA_EXECUTOR=true, Nodes 1-3: standard V2 ==="
@$(MAKE) docker-cluster-stop || true
@rm -rf $(PROJECT_HOME)/build/generated
@DOCKER_DETACH=true $(MAKE) docker-cluster-start-giga-mixed
@echo "Waiting for cluster to be ready..."
@timeout=300; elapsed=0; \
while [ $$elapsed -lt $$timeout ]; do \
if [ -f "build/generated/launch.complete" ] && [ $$(cat build/generated/launch.complete | wc -l) -ge 4 ]; then \
echo "All 4 nodes are ready (took $${elapsed}s)"; \
break; \
fi; \
sleep 5; \
elapsed=$$((elapsed + 5)); \
echo " Waiting... ($${elapsed}s elapsed)"; \
done; \
if [ $$elapsed -ge $$timeout ]; then \
echo "ERROR: Cluster failed to start within $${timeout}s"; \
$(MAKE) docker-cluster-stop; \
exit 1; \
fi
@echo "Waiting 10s for nodes to stabilize..."
@sleep 10
@echo "=== Running GIGA EVM Tests (mixed mode) ==="
@./integration_test/evm_module/scripts/evm_giga_tests.sh || (echo "TEST FAILURE - check if node 0 (giga) halted due to consensus mismatch" && $(MAKE) docker-cluster-stop && exit 1)
@echo "=== Stopping cluster ==="
@$(MAKE) docker-cluster-stop
@echo "=== GIGA Mixed-Mode Integration Tests Complete ==="
.PHONY: giga-mixed-integration-test

# Implements test splitting and running. This is pulled directly from
# the github action workflows for better local reproducibility.

Expand Down
67 changes: 2 additions & 65 deletions app/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"crypto/sha256"
"time"

"github.com/cosmos/cosmos-sdk/tasks"
"github.com/cosmos/cosmos-sdk/telemetry"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
Expand Down Expand Up @@ -117,52 +116,7 @@ func (app *App) DeliverTx(ctx sdk.Context, req abci.RequestDeliverTxV2, tx sdk.T
defer span.End()
// update context with trace span new context
ctx = ctx.WithTraceSpanContext(spanCtx)
defer telemetry.MeasureSince(time.Now(), "abci", "deliver_tx")

gInfo := sdk.GasInfo{}
resultStr := "successful"

defer func() {
telemetry.IncrCounter(1, "tx", "count")
telemetry.IncrCounter(1, "tx", resultStr)
telemetry.SetGauge(float32(gInfo.GasUsed), "tx", "gas", "used")
telemetry.SetGauge(float32(gInfo.GasWanted), "tx", "gas", "wanted")
}()
gInfo, result, anteEvents, resCtx, err := legacyabci.DeliverTx(ctx.WithTxBytes(req.Tx).WithTxSum(checksum).WithVoteInfos(app.UnsafeGetVoteInfos()), tx, app.GetTxConfig(), &app.DeliverTxKeepers, checksum, func(ctx sdk.Context) (sdk.Context, sdk.CacheMultiStore) {
return app.CacheTxContext(ctx, checksum)
}, app.RunMsgs, app.TracingInfo, app.AddCosmosEventsToEVMReceiptIfApplicable)
if err != nil {
resultStr = "failed"
// if we have a result, use those events instead of just the anteEvents
if result != nil {
return sdkerrors.ResponseDeliverTxWithEvents(err, gInfo.GasWanted, gInfo.GasUsed, sdk.MarkEventsToIndex(result.Events, app.IndexEvents), false)
}
return sdkerrors.ResponseDeliverTxWithEvents(err, gInfo.GasWanted, gInfo.GasUsed, sdk.MarkEventsToIndex(anteEvents, app.IndexEvents), false)
}

res := abci.ResponseDeliverTx{
GasWanted: int64(gInfo.GasWanted), //nolint:gosec
GasUsed: int64(gInfo.GasUsed), //nolint:gosec
Log: result.Log,
Data: result.Data,
Events: sdk.MarkEventsToIndex(result.Events, app.IndexEvents),
}
if resCtx.IsEVM() {
res.EvmTxInfo = &abci.EvmTxInfo{
SenderAddress: resCtx.EVMSenderAddress(),
Nonce: resCtx.EVMNonce(),
TxHash: resCtx.EVMTxHash(),
VmError: result.EvmError,
}
// TODO: populate error data for EVM err
if result.EvmError != "" {
evmErr := sdkerrors.Wrap(sdkerrors.ErrEVMVMError, result.EvmError)
res.Codespace, res.Code, res.Log = sdkerrors.ABCIInfo(evmErr, false)
resultStr = "failed"
return res
}
}
return res
return app.BaseApp.DeliverTx(ctx, req, tx, checksum)
}

// DeliverTxBatch is not part of the ABCI specification, but this is here for code convention
Expand All @@ -172,24 +126,7 @@ func (app *App) DeliverTxBatch(ctx sdk.Context, req sdk.DeliverTxBatchRequest) (
defer span.End()
// update context with trace span new context
ctx = ctx.WithTraceSpanContext(spanCtx)
responses := make([]*sdk.DeliverTxResult, 0, len(req.TxEntries))

if len(req.TxEntries) == 0 {
return sdk.DeliverTxBatchResponse{Results: responses}
}

// avoid overhead for empty batches
scheduler := tasks.NewScheduler(app.ConcurrencyWorkers(), app.TracingInfo, app.DeliverTx)
txRes, err := scheduler.ProcessAll(ctx, req.TxEntries)
if err != nil {
ctx.Logger().Error("error while processing scheduler", "err", err)
panic(err)
}
for _, tx := range txRes {
responses = append(responses, &sdk.DeliverTxResult{Response: tx})
}

return sdk.DeliverTxBatchResponse{Results: responses}
return app.BaseApp.DeliverTxBatch(ctx, req)
}

func (app *App) Commit(ctx context.Context) (res *abci.ResponseCommit, err error) {
Expand Down
Loading
Loading