diff --git a/cmd/aida-vm-sdb/run_substate.go b/cmd/aida-vm-sdb/run_substate.go index 71daa250a..686240423 100644 --- a/cmd/aida-vm-sdb/run_substate.go +++ b/cmd/aida-vm-sdb/run_substate.go @@ -113,9 +113,9 @@ func runSubstates(cfg *utils.Config, provider executor.Provider[txcontext.TxCont validator.MakeStateHashValidator[txcontext.TxContext](cfg), statedb.MakeBlockEventEmitter[txcontext.TxContext](), statedb.MakeTransactionEventEmitter[txcontext.TxContext](), - validator.MakeEthereumDbPreTransactionUpdator(cfg), + validator.MakeEthereumDbPreTransactionUpdater(cfg), validator.MakeLiveDbValidator(cfg, validator.ValidateTxTarget{WorldState: true, Receipt: true}), - validator.MakeEthereumDbPostTransactionUpdator(cfg), + validator.MakeEthereumDbPostTransactionUpdater(cfg), profiler.MakeOperationProfiler[txcontext.TxContext](cfg), // block profile extension should be always last because: diff --git a/executor/extension/validator/ethereum_post_transaction_updator.go b/executor/extension/validator/ethereum_post_transaction_updater.go similarity index 81% rename from executor/extension/validator/ethereum_post_transaction_updator.go rename to executor/extension/validator/ethereum_post_transaction_updater.go index 7dfade496..b5706cda9 100644 --- a/executor/extension/validator/ethereum_post_transaction_updator.go +++ b/executor/extension/validator/ethereum_post_transaction_updater.go @@ -24,18 +24,18 @@ import ( "github.com/Fantom-foundation/Aida/utils" ) -// MakeEthereumDbPostTransactionUpdator creates an extension which fixes Ethereum exceptions in LiveDB -func MakeEthereumDbPostTransactionUpdator(cfg *utils.Config) executor.Extension[txcontext.TxContext] { +// MakeEthereumDbPostTransactionUpdater creates an extension which fixes Ethereum exceptions in LiveDB +func MakeEthereumDbPostTransactionUpdater(cfg *utils.Config) executor.Extension[txcontext.TxContext] { if cfg.ChainID != utils.EthereumChainID { return extension.NilExtension[txcontext.TxContext]{} } - log := logger.NewLogger(cfg.LogLevel, "Ethereum-Exception-Updator") + log := logger.NewLogger(cfg.LogLevel, "Ethereum-Exception-Updater") - return makeEthereumDbPostTransactionUpdator(cfg, log) + return makeEthereumDbPostTransactionUpdater(cfg, log) } -func makeEthereumDbPostTransactionUpdator(cfg *utils.Config, log logger.Logger) executor.Extension[txcontext.TxContext] { +func makeEthereumDbPostTransactionUpdater(cfg *utils.Config, log logger.Logger) executor.Extension[txcontext.TxContext] { return ðereumDbPostTransactionUpdater{ cfg: cfg, log: log, @@ -44,7 +44,7 @@ func makeEthereumDbPostTransactionUpdator(cfg *utils.Config, log logger.Logger) // PostTransaction fixes OutputAlloc ethereum exceptions in given substate func (v *ethereumDbPostTransactionUpdater) PostTransaction(state executor.State[txcontext.TxContext], ctx *executor.Context) error { - return updateEthereumDb(state, ctx.State, false) + return updateEthereumDb(state, ctx, false) } type ethereumDbPostTransactionUpdater struct { @@ -53,9 +53,9 @@ type ethereumDbPostTransactionUpdater struct { log logger.Logger } -// PreRun informs the user that ethereumExceptionUpdator is enabled. +// PreRun informs the user that ethereumDbPostTransactionUpdater is enabled. func (v *ethereumDbPostTransactionUpdater) PreRun(executor.State[txcontext.TxContext], *executor.Context) error { - v.log.Warning("Ethereum exception post transaction updator is enabled.") + v.log.Warning("Ethereum exception post transaction updater is enabled.") return nil } diff --git a/executor/extension/validator/ethereum_pre_transaction_updator.go b/executor/extension/validator/ethereum_pre_transaction_updater.go similarity index 72% rename from executor/extension/validator/ethereum_pre_transaction_updator.go rename to executor/extension/validator/ethereum_pre_transaction_updater.go index d45c84b6f..c2a492d87 100644 --- a/executor/extension/validator/ethereum_pre_transaction_updator.go +++ b/executor/extension/validator/ethereum_pre_transaction_updater.go @@ -24,38 +24,38 @@ import ( "github.com/Fantom-foundation/Aida/utils" ) -// MakeEthereumDbPreTransactionUpdator creates an extension which fixes Ethereum exceptions in pre transaction in LiveDB -func MakeEthereumDbPreTransactionUpdator(cfg *utils.Config) executor.Extension[txcontext.TxContext] { +// MakeEthereumDbPreTransactionUpdater creates an extension which fixes Ethereum exceptions in pre transaction in LiveDB +func MakeEthereumDbPreTransactionUpdater(cfg *utils.Config) executor.Extension[txcontext.TxContext] { if cfg.ChainID != utils.EthereumChainID { return extension.NilExtension[txcontext.TxContext]{} } - log := logger.NewLogger(cfg.LogLevel, "Ethereum-Exception-Updator") + log := logger.NewLogger(cfg.LogLevel, "Ethereum-Exception-Updater") - return makeEthereumDbPreTransactionUpdator(cfg, log) + return makeEthereumDbPreTransactionUpdater(cfg, log) } -func makeEthereumDbPreTransactionUpdator(cfg *utils.Config, log logger.Logger) executor.Extension[txcontext.TxContext] { - return ðereumDbPreTransactionUpdator{ +func makeEthereumDbPreTransactionUpdater(cfg *utils.Config, log logger.Logger) executor.Extension[txcontext.TxContext] { + return ðereumDbPreTransactionUpdater{ cfg: cfg, log: log, } } // PreTransaction validates fixes InputSubstate ethereum exceptions in given substate -func (v *ethereumDbPreTransactionUpdator) PreTransaction(state executor.State[txcontext.TxContext], ctx *executor.Context) error { - return updateEthereumDb(state, ctx.State, true) +func (v *ethereumDbPreTransactionUpdater) PreTransaction(state executor.State[txcontext.TxContext], ctx *executor.Context) error { + return updateEthereumDb(state, ctx, true) } -type ethereumDbPreTransactionUpdator struct { +type ethereumDbPreTransactionUpdater struct { extension.NilExtension[txcontext.TxContext] cfg *utils.Config log logger.Logger } -// PreRun informs the user that ethereumExceptionUpdator is enabled. -func (v *ethereumDbPreTransactionUpdator) PreRun(executor.State[txcontext.TxContext], *executor.Context) error { - v.log.Warning("Ethereum exception pre transaction updator is enabled.") +// PreRun informs the user that ethereumDbPreTransactionUpdater is enabled. +func (v *ethereumDbPreTransactionUpdater) PreRun(executor.State[txcontext.TxContext], *executor.Context) error { + v.log.Warning("Ethereum exception pre transaction updater is enabled.") return nil } diff --git a/executor/extension/validator/transaction_validator.go b/executor/extension/validator/transaction_validator.go index 29451e3e6..be4b3cced 100644 --- a/executor/extension/validator/transaction_validator.go +++ b/executor/extension/validator/transaction_validator.go @@ -18,7 +18,6 @@ package validator import ( "fmt" - "strings" "sync/atomic" "github.com/Fantom-foundation/Aida/executor" @@ -135,7 +134,7 @@ func (v *stateDbValidator) runPreTxValidation(tool string, db state.VmStateDB, s } var err error - if strings.ToLower(v.cfg.UpdateOnFailure) == "all" || strings.ToLower(v.cfg.UpdateOnFailure) == "pre" { + if v.cfg.UpdateOnFailure == "all" || v.cfg.UpdateOnFailure == "pre" { return updateWorldState(v.cfg, db, state.Data.GetInputState()) } else { if err = validateWorldState(v.cfg, db, state.Data.GetInputState(), v.log); err == nil { @@ -154,7 +153,7 @@ func (v *stateDbValidator) runPreTxValidation(tool string, db state.VmStateDB, s func (v *stateDbValidator) runPostTxValidation(tool string, db state.VmStateDB, state executor.State[txcontext.TxContext], res txcontext.Result, errOutput chan error) error { if v.target.WorldState { - if strings.ToLower(v.cfg.UpdateOnFailure) == "all" || strings.ToLower(v.cfg.UpdateOnFailure) == "post" { + if v.cfg.UpdateOnFailure == "all" || v.cfg.UpdateOnFailure == "post" { return updateWorldState(v.cfg, db, state.Data.GetOutputState()) } else if err := validateWorldState(v.cfg, db, state.Data.GetOutputState(), v.log); err != nil { err = fmt.Errorf("%v err:\nworld-state output error at block %v tx %v; %v", tool, state.Block, state.Transaction, err) diff --git a/executor/extension/validator/utils.go b/executor/extension/validator/utils.go index 82c1dbe04..09c593997 100644 --- a/executor/extension/validator/utils.go +++ b/executor/extension/validator/utils.go @@ -25,7 +25,10 @@ import ( "github.com/Fantom-foundation/Aida/logger" "github.com/Fantom-foundation/Aida/state" "github.com/Fantom-foundation/Aida/txcontext" + substatecontext "github.com/Fantom-foundation/Aida/txcontext/substate" "github.com/Fantom-foundation/Aida/utils" + "github.com/Fantom-foundation/Substate/substate" + substatetypes "github.com/Fantom-foundation/Substate/types" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" @@ -238,9 +241,10 @@ func updateWorldState(cfg *utils.Config, db state.VmStateDB, alloc txcontext.Wor } // updateEthereumDb is used to fix exceptions in ethereum dataset inconsistencies -func updateEthereumDb(s executor.State[txcontext.TxContext], db state.VmStateDB, isPreTransaction bool) error { +func updateEthereumDb(s executor.State[txcontext.TxContext], ctx *executor.Context, isPreTransaction bool) error { var overwriteEverything = false var alloc txcontext.WorldState + var db = ctx.State if isPreTransaction { alloc = s.Data.GetInputState() } else { @@ -249,6 +253,7 @@ func updateEthereumDb(s executor.State[txcontext.TxContext], db state.VmStateDB, // only post alloc is diverging for these ethereum block exceptions if slices.Contains(ethereumLfvmBlockExceptions, s.Block) { overwriteEverything = true + overwriteReceipt(s, ctx) } } @@ -291,3 +296,37 @@ func updateEthereumDb(s executor.State[txcontext.TxContext], db state.VmStateDB, return nil } + +// overwriteReceipt is used to fix receipts of exceptions in ethereum dataset +func overwriteReceipt(s executor.State[txcontext.TxContext], ctx *executor.Context) { + //// alternative to skip transaction receipt validation all together + //s.Transaction = s.Transaction + 100000 + + logs := make([]*substatetypes.Log, 0) + + for _, l := range s.Data.GetResult().GetReceipt().GetLogs() { + topics := make([]substatetypes.Hash, 0) + for _, t := range l.Topics { + topics = append(topics, substatetypes.BytesToHash(t.Bytes())) + } + logs = append(logs, &substatetypes.Log{ + Address: substatetypes.HexToAddress(l.Address.Hex()), + Topics: topics, + Data: l.Data, + BlockNumber: l.BlockNumber, + TxHash: substatetypes.BytesToHash(l.TxHash.Bytes()), + TxIndex: l.TxIndex, + BlockHash: substatetypes.BytesToHash(l.BlockHash.Bytes()), + Index: l.Index, + Removed: l.Removed, + }) + } + + receipt := substate.NewResult(s.Data.GetResult().GetReceipt().GetStatus(), + substatetypes.BytesToBloom(s.Data.GetResult().GetReceipt().GetBloom().Bytes()), + logs, + substatetypes.HexToAddress(s.Data.GetResult().GetReceipt().GetContractAddress().Hex()), + s.Data.GetResult().GetReceipt().GetGasUsed()) + + ctx.ExecutionResult = substatecontext.NewReceipt(receipt) +} diff --git a/utils/default_config.go b/utils/default_config.go index 6fbae17ec..811e817b0 100644 --- a/utils/default_config.go +++ b/utils/default_config.go @@ -17,6 +17,8 @@ package utils import ( + "strings" + "github.com/Fantom-foundation/Aida/cmd/util-db/flags" "github.com/Fantom-foundation/Aida/logger" "github.com/urfave/cli/v2" @@ -118,7 +120,7 @@ func createConfigFromFlags(ctx *cli.Context) *Config { TransactionLength: getFlagValue(ctx, TransactionLengthFlag).(uint64), UpdateBufferSize: getFlagValue(ctx, UpdateBufferSizeFlag).(uint64), UpdateDb: getFlagValue(ctx, UpdateDbFlag).(string), - UpdateOnFailure: getFlagValue(ctx, UpdateOnFailure).(string), + UpdateOnFailure: strings.ToLower(getFlagValue(ctx, UpdateOnFailure).(string)), UpdateType: getFlagValue(ctx, UpdateTypeFlag).(string), Validate: getFlagValue(ctx, ValidateFlag).(bool), ValidateStateHashes: getFlagValue(ctx, ValidateStateHashesFlag).(bool),