From 47690db6766c2776af4303a1ecb3e3e66fe0aeb5 Mon Sep 17 00:00:00 2001 From: canepat <16927169+canepat@users.noreply.github.com> Date: Thu, 5 Oct 2023 04:27:37 +0200 Subject: [PATCH 01/14] Block execution using embedded Silkworm (#8353) This introduces _experimental_ block execution run by embedded Silkworm API library: - new command-line option `silkworm.path` to enable the feature by specifying the path to the Silkworm library - the Silkworm API shared library is dynamically loaded on-demand - currently requires to build Silkworm library on the target machine - available only on Linux at the moment: macOS has issue with [stack size](https://github.com/golang/go/issues/28024) and Windows would require [TDM-GCC-64](https://jmeubank.github.io/tdm-gcc/), both need dedicated effort for an assessment --- cmd/integration/commands/stages.go | 4 +- cmd/integration/commands/state_stages.go | 4 +- cmd/utils/flags.go | 14 + erigon-lib/compress/decompress.go | 5 + erigon-lib/kv/kv_interface.go | 4 + erigon-lib/kv/mdbx/kv_mdbx.go | 5 + erigon-lib/kv/memdb/memory_mutation.go | 5 + erigon-lib/kv/remotedb/kv_remote.go | 5 + erigon-lib/recsplit/index.go | 4 + eth/backend.go | 21 +- eth/ethconfig/config.go | 6 + eth/stagedsync/stage_execute.go | 30 +- eth/stagedsync/stage_snapshots.go | 20 +- turbo/cli/default_flags.go | 2 + turbo/silkworm/load.go | 19 ++ turbo/silkworm/load_linux.go | 35 ++ turbo/silkworm/silkworm.go | 314 ++++++++++++++++++ turbo/silkworm/types.go | 65 ++++ .../freezeblocks/block_snapshots.go | 81 +++++ turbo/stages/mock/mock_sentry.go | 7 +- turbo/stages/stageloop.go | 12 +- 21 files changed, 644 insertions(+), 18 deletions(-) create mode 100644 turbo/silkworm/load.go create mode 100644 turbo/silkworm/load_linux.go create mode 100644 turbo/silkworm/silkworm.go create mode 100644 turbo/silkworm/types.go diff --git a/cmd/integration/commands/stages.go b/cmd/integration/commands/stages.go index ed656b3867d..70855cb1f93 100644 --- a/cmd/integration/commands/stages.go +++ b/cmd/integration/commands/stages.go @@ -894,7 +894,7 @@ func stageExec(db kv.RwDB, ctx context.Context, logger log.Logger) error { br, _ := blocksIO(db, logger) cfg := stagedsync.StageExecuteBlocksCfg(db, pm, batchSize, nil, chainConfig, engine, vmConfig, nil, /*stateStream=*/ false, - /*badBlockHalt=*/ false, historyV3, dirs, br, nil, genesis, syncCfg, agg) + /*badBlockHalt=*/ false, historyV3, dirs, br, nil, genesis, syncCfg, agg, nil) var tx kv.RwTx //nil - means lower-level code (each stage) will manage transactions if noCommit { @@ -1531,7 +1531,7 @@ func newSync(ctx context.Context, db kv.RwDB, miningConfig *params.MiningConfig, notifications := &shards.Notifications{} blockRetire := freezeblocks.NewBlockRetire(1, dirs, blockReader, blockWriter, db, notifications.Events, logger) - stages := stages2.NewDefaultStages(context.Background(), db, p2p.Config{}, &cfg, sentryControlServer, notifications, nil, blockReader, blockRetire, agg, nil, heimdallClient, logger) + stages := stages2.NewDefaultStages(context.Background(), db, p2p.Config{}, &cfg, sentryControlServer, notifications, nil, blockReader, blockRetire, agg, nil, nil, heimdallClient, logger) sync := stagedsync.New(stages, stagedsync.DefaultUnwindOrder, stagedsync.DefaultPruneOrder, logger) miner := stagedsync.NewMiningState(&cfg.Miner) diff --git a/cmd/integration/commands/state_stages.go b/cmd/integration/commands/state_stages.go index b9d761f8022..650b5985d0f 100644 --- a/cmd/integration/commands/state_stages.go +++ b/cmd/integration/commands/state_stages.go @@ -218,7 +218,7 @@ func syncBySmallSteps(db kv.RwDB, miningConfig params.MiningConfig, ctx context. br, _ := blocksIO(db, logger1) execCfg := stagedsync.StageExecuteBlocksCfg(db, pm, batchSize, changeSetHook, chainConfig, engine, vmConfig, changesAcc, false, false, historyV3, dirs, - br, nil, genesis, syncCfg, agg) + br, nil, genesis, syncCfg, agg, nil) execUntilFunc := func(execToBlock uint64) func(firstCycle bool, badBlockUnwind bool, stageState *stagedsync.StageState, unwinder stagedsync.Unwinder, tx kv.RwTx, logger log.Logger) error { return func(firstCycle bool, badBlockUnwind bool, s *stagedsync.StageState, unwinder stagedsync.Unwinder, tx kv.RwTx, logger log.Logger) error { @@ -556,7 +556,7 @@ func loopExec(db kv.RwDB, ctx context.Context, unwind uint64, logger log.Logger) br, _ := blocksIO(db, logger) cfg := stagedsync.StageExecuteBlocksCfg(db, pm, batchSize, nil, chainConfig, engine, vmConfig, nil, /*stateStream=*/ false, - /*badBlockHalt=*/ false, historyV3, dirs, br, nil, genesis, syncCfg, agg) + /*badBlockHalt=*/ false, historyV3, dirs, br, nil, genesis, syncCfg, agg, nil) // set block limit of execute stage sync.MockExecFunc(stages.Execution, func(firstCycle bool, badBlockUnwind bool, stageState *stagedsync.StageState, unwinder stagedsync.Unwinder, tx kv.RwTx, logger log.Logger) error { diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 6cabb978fbe..89c937957fc 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -828,6 +828,12 @@ var ( Name: "diagnostics.ids", Usage: "Comma separated list of support session ids to connect to", } + + SilkwormPathFlag = cli.StringFlag{ + Name: "silkworm.path", + Usage: "Path to the silkworm_api library (enables embedded Silkworm execution)", + Value: "", + } ) var MetricFlags = []cli.Flag{&MetricsEnabledFlag, &MetricsHTTPFlag, &MetricsPortFlag} @@ -1450,6 +1456,13 @@ func setWhitelist(ctx *cli.Context, cfg *ethconfig.Config) { } } +func setSilkworm(ctx *cli.Context, cfg *ethconfig.Config) { + cfg.SilkwormEnabled = ctx.IsSet(SilkwormPathFlag.Name) + if cfg.SilkwormEnabled { + cfg.SilkwormPath = ctx.String(SilkwormPathFlag.Name) + } +} + // CheckExclusive verifies that only a single instance of the provided flags was // set by the user. Each flag might optionally be followed by a string type to // specialize it further. @@ -1552,6 +1565,7 @@ func SetEthConfig(ctx *cli.Context, nodeConfig *nodecfg.Config, cfg *ethconfig.C setMiner(ctx, &cfg.Miner) setWhitelist(ctx, cfg) setBorConfig(ctx, cfg) + setSilkworm(ctx, cfg) cfg.Ethstats = ctx.String(EthStatsURLFlag.Name) cfg.P2PEnabled = len(nodeConfig.P2P.SentryAddr) == 0 diff --git a/erigon-lib/compress/decompress.go b/erigon-lib/compress/decompress.go index 3fbd9603e35..4f354733c32 100644 --- a/erigon-lib/compress/decompress.go +++ b/erigon-lib/compress/decompress.go @@ -24,6 +24,7 @@ import ( "path/filepath" "strconv" "time" + "unsafe" "github.com/ledgerwatch/erigon-lib/common/dbg" "github.com/ledgerwatch/erigon-lib/mmap" @@ -333,6 +334,10 @@ func buildPosTable(depths []uint64, poss []uint64, table *posTable, code uint16, return b0 + buildPosTable(depths[b0:], poss[b0:], table, (uint16(1)< cfg.prune.History.PruneTo(to) writeReceipts := nextStagesExpectData || blockNum > cfg.prune.Receipts.PruneTo(to) writeCallTraces := nextStagesExpectData || blockNum > cfg.prune.CallTraces.PruneTo(to) - if err = executeBlock(block, tx, batch, cfg, *cfg.vmConfig, writeChangeSets, writeReceipts, writeCallTraces, initialCycle, stateStream, logger); err != nil { + + if cfg.silkworm != nil { + blockNum, err = cfg.silkworm.ExecuteBlocks(tx, cfg.chainConfig.ChainID, blockNum, to, uint64(cfg.batchSize), writeChangeSets, writeReceipts, writeCallTraces) + } else { + err = executeBlock(block, tx, batch, cfg, *cfg.vmConfig, writeChangeSets, writeReceipts, writeCallTraces, initialCycle, stateStream, logger) + } + + if err != nil { + if errors.Is(err, silkworm.ErrInterrupted) { + logger.Warn(fmt.Sprintf("[%s] Execution interrupted", logPrefix), "block", blockNum, "err", err) + // Remount the termination signal + p, err := os.FindProcess(os.Getpid()) + if err != nil { + return err + } + p.Signal(os.Interrupt) + return nil + } if !errors.Is(err, context.Canceled) { - logger.Warn(fmt.Sprintf("[%s] Execution failed", logPrefix), "block", blockNum, "hash", blockHash.String(), "err", err) + if cfg.silkworm != nil { + logger.Warn(fmt.Sprintf("[%s] Execution failed", logPrefix), "block", blockNum, "err", err) + } else { + logger.Warn(fmt.Sprintf("[%s] Execution failed", logPrefix), "block", blockNum, "hash", blockHash.String(), "err", err) + } if cfg.hd != nil && errors.Is(err, consensus.ErrInvalidBlock) { cfg.hd.ReportBadHeaderPoS(blockHash, block.ParentHash() /* lastValidAncestor */) } diff --git a/eth/stagedsync/stage_snapshots.go b/eth/stagedsync/stage_snapshots.go index 0886737e4c4..0ea782fba3f 100644 --- a/eth/stagedsync/stage_snapshots.go +++ b/eth/stagedsync/stage_snapshots.go @@ -24,7 +24,9 @@ import ( "github.com/ledgerwatch/erigon/eth/ethconfig/estimate" "github.com/ledgerwatch/erigon/eth/stagedsync/stages" "github.com/ledgerwatch/erigon/turbo/services" + "github.com/ledgerwatch/erigon/turbo/silkworm" "github.com/ledgerwatch/erigon/turbo/snapshotsync" + "github.com/ledgerwatch/erigon/turbo/snapshotsync/freezeblocks" ) type SnapshotsCfg struct { @@ -39,14 +41,19 @@ type SnapshotsCfg struct { historyV3 bool agg *state.AggregatorV3 + silkworm *silkworm.Silkworm } func StageSnapshotsCfg(db kv.RwDB, - chainConfig chain.Config, dirs datadir.Dirs, + chainConfig chain.Config, + dirs datadir.Dirs, blockRetire services.BlockRetire, snapshotDownloader proto_downloader.DownloaderClient, - blockReader services.FullBlockReader, dbEventNotifier services.DBEventNotifier, - historyV3 bool, agg *state.AggregatorV3, + blockReader services.FullBlockReader, + dbEventNotifier services.DBEventNotifier, + historyV3 bool, + agg *state.AggregatorV3, + silkworm *silkworm.Silkworm, ) SnapshotsCfg { return SnapshotsCfg{ db: db, @@ -58,6 +65,7 @@ func StageSnapshotsCfg(db kv.RwDB, dbEventNotifier: dbEventNotifier, historyV3: historyV3, agg: agg, + silkworm: silkworm, } } @@ -125,6 +133,12 @@ func DownloadAndIndexSnapshotsIfNeed(s *StageState, ctx context.Context, tx kv.R return err } + if cfg.silkworm != nil { + if err := cfg.blockReader.Snapshots().(*freezeblocks.RoSnapshots).AddSnapshotsToSilkworm(cfg.silkworm); err != nil { + return err + } + } + if cfg.historyV3 { cfg.agg.CleanDir() diff --git a/turbo/cli/default_flags.go b/turbo/cli/default_flags.go index a9820094dd3..a6daf1cbf2b 100644 --- a/turbo/cli/default_flags.go +++ b/turbo/cli/default_flags.go @@ -162,5 +162,7 @@ var DefaultFlags = []cli.Flag{ &utils.OtsSearchMaxCapFlag, + &utils.SilkwormPathFlag, + &utils.TrustedSetupFile, } diff --git a/turbo/silkworm/load.go b/turbo/silkworm/load.go new file mode 100644 index 00000000000..4ae890436f4 --- /dev/null +++ b/turbo/silkworm/load.go @@ -0,0 +1,19 @@ +//go:build !linux +// +build !linux + +package silkworm + +import ( + "errors" + "unsafe" +) + +func OpenLibrary(dllPath string) (unsafe.Pointer, error) { + // See https://github.com/golang/go/issues/28024 + return nil, errors.New("Silkworm is only supported on Linux") +} + +func LoadFunction(dllHandle unsafe.Pointer, funcName string) (unsafe.Pointer, error) { + // See https://github.com/golang/go/issues/28024 + return nil, errors.New("Silkworm is only supported on Linux") +} diff --git a/turbo/silkworm/load_linux.go b/turbo/silkworm/load_linux.go new file mode 100644 index 00000000000..5f3113103da --- /dev/null +++ b/turbo/silkworm/load_linux.go @@ -0,0 +1,35 @@ +package silkworm + +/* +#cgo LDFLAGS: -ldl +#include +#include +*/ +import "C" + +import ( + "fmt" + "unsafe" +) + +func OpenLibrary(dllPath string) (unsafe.Pointer, error) { + cPath := C.CString(dllPath) + defer C.free(unsafe.Pointer(cPath)) + dllHandle := C.dlopen(cPath, C.RTLD_LAZY) + if dllHandle == nil { + err := C.GoString(C.dlerror()) + return nil, fmt.Errorf("failed to load dynamic library %s: %s", dllPath, err) + } + return dllHandle, nil +} + +func LoadFunction(dllHandle unsafe.Pointer, funcName string) (unsafe.Pointer, error) { + cName := C.CString(funcName) + defer C.free(unsafe.Pointer(cName)) + funcPtr := C.dlsym(dllHandle, cName) + if funcPtr == nil { + err := C.GoString(C.dlerror()) + return nil, fmt.Errorf("failed to find the %s function: %s", funcName, err) + } + return funcPtr, nil +} diff --git a/turbo/silkworm/silkworm.go b/turbo/silkworm/silkworm.go new file mode 100644 index 00000000000..51fec7888d3 --- /dev/null +++ b/turbo/silkworm/silkworm.go @@ -0,0 +1,314 @@ +package silkworm + +/* +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// START silkworm_api.h: C API exported by Silkworm to be used in Erigon. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +#ifndef SILKWORM_API_H_ +#define SILKWORM_API_H_ + +#include +#include +#include +#include + +#if defined _MSC_VER +#define SILKWORM_EXPORT __declspec(dllexport) +#else +#define SILKWORM_EXPORT __attribute__((visibility("default"))) +#endif + +#if __cplusplus +#define SILKWORM_NOEXCEPT noexcept +#else +#define SILKWORM_NOEXCEPT +#endif + +#if __cplusplus +extern "C" { +#endif + +typedef struct MDBX_txn MDBX_txn; + +#define SILKWORM_OK 0 +#define SILKWORM_INTERNAL_ERROR 1 +#define SILKWORM_UNKNOWN_ERROR 2 +#define SILKWORM_INVALID_HANDLE 3 +#define SILKWORM_INVALID_PATH 4 +#define SILKWORM_INVALID_SNAPSHOT 5 +#define SILKWORM_INVALID_MDBX_TXN 6 +#define SILKWORM_INVALID_BLOCK_RANGE 7 +#define SILKWORM_BLOCK_NOT_FOUND 8 +#define SILKWORM_UNKNOWN_CHAIN_ID 9 +#define SILKWORM_MDBX_ERROR 10 +#define SILKWORM_INVALID_BLOCK 11 +#define SILKWORM_DECODING_ERROR 12 +#define SILKWORM_TOO_MANY_INSTANCES 13 +#define SILKWORM_INSTANCE_NOT_FOUND 14 +#define SILKWORM_TERMINATION_SIGNAL 15 + +typedef struct SilkwormHandle SilkwormHandle; + +SILKWORM_EXPORT int silkworm_init(SilkwormHandle** handle) SILKWORM_NOEXCEPT; + +struct SilkwormMemoryMappedFile { + const char* file_path; + uint8_t* memory_address; + uint64_t memory_length; +}; + +struct SilkwormHeadersSnapshot { + struct SilkwormMemoryMappedFile segment; + struct SilkwormMemoryMappedFile header_hash_index; +}; + +struct SilkwormBodiesSnapshot { + struct SilkwormMemoryMappedFile segment; + struct SilkwormMemoryMappedFile block_num_index; +}; + +struct SilkwormTransactionsSnapshot { + struct SilkwormMemoryMappedFile segment; + struct SilkwormMemoryMappedFile tx_hash_index; + struct SilkwormMemoryMappedFile tx_hash_2_block_index; +}; + +struct SilkwormChainSnapshot { + struct SilkwormHeadersSnapshot headers; + struct SilkwormBodiesSnapshot bodies; + struct SilkwormTransactionsSnapshot transactions; +}; + +SILKWORM_EXPORT int silkworm_add_snapshot(SilkwormHandle* handle, struct SilkwormChainSnapshot* snapshot) SILKWORM_NOEXCEPT; + +SILKWORM_EXPORT int silkworm_execute_blocks( + SilkwormHandle* handle, MDBX_txn* txn, uint64_t chain_id, uint64_t start_block, uint64_t max_block, + uint64_t batch_size, bool write_change_sets, bool write_receipts, bool write_call_traces, + uint64_t* last_executed_block, int* mdbx_error_code) SILKWORM_NOEXCEPT; + +SILKWORM_EXPORT int silkworm_fini(SilkwormHandle* handle) SILKWORM_NOEXCEPT; + +#if __cplusplus +} +#endif + +#endif // SILKWORM_API_H_ + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// END silkworm_api.h: C API exported by Silkworm to be used in Erigon. +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +typedef int (*silkworm_init_func)(SilkwormHandle** handle); + +int call_silkworm_init_func(void* func_ptr, SilkwormHandle** handle) { + return ((silkworm_init_func)func_ptr)(handle); +} + +typedef int (*silkworm_add_snapshot_func)(SilkwormHandle* handle, struct SilkwormChainSnapshot* snapshot); + +int call_silkworm_add_snapshot_func(void* func_ptr, SilkwormHandle* handle, struct SilkwormChainSnapshot* snapshot) { + return ((silkworm_add_snapshot_func)func_ptr)(handle, snapshot); +} + +typedef int (*silkworm_execute_blocks_func)(SilkwormHandle* handle, MDBX_txn* txn, uint64_t chain_id, uint64_t start_block, + uint64_t max_block, uint64_t batch_size, bool write_change_sets, bool write_receipts, bool write_call_traces, + uint64_t* last_executed_block, int* mdbx_error_code); + +int call_silkworm_execute_blocks_func(void* func_ptr, SilkwormHandle* handle, MDBX_txn* txn, uint64_t chain_id, uint64_t start_block, + uint64_t max_block, uint64_t batch_size, bool write_change_sets, bool write_receipts, bool write_call_traces, + uint64_t* last_executed_block, int* mdbx_error_code) { + return ((silkworm_execute_blocks_func)func_ptr)(handle, txn, chain_id, start_block, max_block, batch_size, write_change_sets, + write_receipts, write_call_traces, last_executed_block, mdbx_error_code); +} + +typedef int (*silkworm_fini_func)(SilkwormHandle* handle); + +int call_silkworm_fini_func(void* func_ptr, SilkwormHandle* handle) { + return ((silkworm_fini_func)func_ptr)(handle); +} + +*/ +import "C" +import ( + "errors" + "fmt" + "math/big" + "unsafe" + + "github.com/ledgerwatch/erigon-lib/kv" + "github.com/ledgerwatch/erigon/consensus" +) + +const ( + SILKWORM_OK = iota + SILKWORM_INTERNAL_ERROR + SILKWORM_UNKNOWN_ERROR + SILKWORM_INVALID_HANDLE + SILKWORM_INVALID_PATH + SILKWORM_INVALID_SNAPSHOT + SILKWORM_INVALID_MDBX_TXN + SILKWORM_INVALID_BLOCK_RANGE + SILKWORM_BLOCK_NOT_FOUND + SILKWORM_UNKNOWN_CHAIN_ID + SILKWORM_MDBX_ERROR + SILKWORM_INVALID_BLOCK + SILKWORM_DECODING_ERROR + SILKWORM_TOO_MANY_INSTANCES + SILKWORM_INSTANCE_NOT_FOUND + SILKWORM_TERMINATION_SIGNAL +) + +// ErrInterrupted is the error returned by Silkworm APIs when stopped by any termination signal. +var ErrInterrupted = errors.New("interrupted") + +type Silkworm struct { + dllHandle unsafe.Pointer + instance *C.SilkwormHandle + initFunc unsafe.Pointer + finiFunc unsafe.Pointer + addSnapshot unsafe.Pointer + executeBlocks unsafe.Pointer +} + +func New(dllPath string) (*Silkworm, error) { + dllHandle, err := OpenLibrary(dllPath) + if err != nil { + return nil, fmt.Errorf("failed to load silkworm library from path %s: %w", dllPath, err) + } + + initFunc, err := LoadFunction(dllHandle, "silkworm_init") + if err != nil { + return nil, fmt.Errorf("failed to load silkworm function silkworm_init: %w", err) + } + finiFunc, err := LoadFunction(dllHandle, "silkworm_fini") + if err != nil { + return nil, fmt.Errorf("failed to load silkworm function silkworm_fini: %w", err) + } + addSnapshot, err := LoadFunction(dllHandle, "silkworm_add_snapshot") + if err != nil { + return nil, fmt.Errorf("failed to load silkworm function silkworm_add_snapshot: %w", err) + } + executeBlocks, err := LoadFunction(dllHandle, "silkworm_execute_blocks") + if err != nil { + return nil, fmt.Errorf("failed to load silkworm function silkworm_execute_blocks: %w", err) + } + + silkworm := &Silkworm{ + dllHandle: dllHandle, + initFunc: initFunc, + finiFunc: finiFunc, + addSnapshot: addSnapshot, + executeBlocks: executeBlocks, + } + status := C.call_silkworm_init_func(silkworm.initFunc, &silkworm.instance) //nolint:gocritic + if status == SILKWORM_OK { + return silkworm, nil + } + return nil, fmt.Errorf("silkworm_init error %d", status) +} + +func (s *Silkworm) Close() { + C.call_silkworm_fini_func(s.finiFunc, s.instance) + s.instance = nil +} + +func (s *Silkworm) AddSnapshot(snapshot *MappedChainSnapshot) error { + cHeadersSegmentFilePath := C.CString(snapshot.Headers.Segment.FilePath) + defer C.free(unsafe.Pointer(cHeadersSegmentFilePath)) + cHeadersIdxHeaderHashFilePath := C.CString(snapshot.Headers.IdxHeaderHash.FilePath) + defer C.free(unsafe.Pointer(cHeadersIdxHeaderHashFilePath)) + cHeadersSnapshot := C.struct_SilkwormHeadersSnapshot{ + segment: C.struct_SilkwormMemoryMappedFile{ + file_path: cHeadersSegmentFilePath, + memory_address: (*C.uchar)(snapshot.Headers.Segment.DataHandle), + memory_length: C.uint64_t(snapshot.Headers.Segment.Size), + }, + header_hash_index: C.struct_SilkwormMemoryMappedFile{ + file_path: cHeadersIdxHeaderHashFilePath, + memory_address: (*C.uchar)(snapshot.Headers.IdxHeaderHash.DataHandle), + memory_length: C.uint64_t(snapshot.Headers.IdxHeaderHash.Size), + }, + } + + cBodiesSegmentFilePath := C.CString(snapshot.Bodies.Segment.FilePath) + defer C.free(unsafe.Pointer(cBodiesSegmentFilePath)) + cBodiesIdxBodyNumberFilePath := C.CString(snapshot.Bodies.IdxBodyNumber.FilePath) + defer C.free(unsafe.Pointer(cBodiesIdxBodyNumberFilePath)) + cBodiesSnapshot := C.struct_SilkwormBodiesSnapshot{ + segment: C.struct_SilkwormMemoryMappedFile{ + file_path: cBodiesSegmentFilePath, + memory_address: (*C.uchar)(snapshot.Bodies.Segment.DataHandle), + memory_length: C.uint64_t(snapshot.Bodies.Segment.Size), + }, + block_num_index: C.struct_SilkwormMemoryMappedFile{ + file_path: cBodiesIdxBodyNumberFilePath, + memory_address: (*C.uchar)(snapshot.Bodies.IdxBodyNumber.DataHandle), + memory_length: C.uint64_t(snapshot.Bodies.IdxBodyNumber.Size), + }, + } + + cTxsSegmentFilePath := C.CString(snapshot.Txs.Segment.FilePath) + defer C.free(unsafe.Pointer(cTxsSegmentFilePath)) + cTxsIdxTxnHashFilePath := C.CString(snapshot.Txs.IdxTxnHash.FilePath) + defer C.free(unsafe.Pointer(cTxsIdxTxnHashFilePath)) + cTxsIdxTxnHash2BlockFilePath := C.CString(snapshot.Txs.IdxTxnHash2BlockNum.FilePath) + defer C.free(unsafe.Pointer(cTxsIdxTxnHash2BlockFilePath)) + cTxsSnapshot := C.struct_SilkwormTransactionsSnapshot{ + segment: C.struct_SilkwormMemoryMappedFile{ + file_path: cTxsSegmentFilePath, + memory_address: (*C.uchar)(snapshot.Txs.Segment.DataHandle), + memory_length: C.uint64_t(snapshot.Txs.Segment.Size), + }, + tx_hash_index: C.struct_SilkwormMemoryMappedFile{ + file_path: cTxsIdxTxnHashFilePath, + memory_address: (*C.uchar)(snapshot.Txs.IdxTxnHash.DataHandle), + memory_length: C.uint64_t(snapshot.Txs.IdxTxnHash.Size), + }, + tx_hash_2_block_index: C.struct_SilkwormMemoryMappedFile{ + file_path: cTxsIdxTxnHash2BlockFilePath, + memory_address: (*C.uchar)(snapshot.Txs.IdxTxnHash2BlockNum.DataHandle), + memory_length: C.uint64_t(snapshot.Txs.IdxTxnHash2BlockNum.Size), + }, + } + + cChainSnapshot := C.struct_SilkwormChainSnapshot{ + headers: cHeadersSnapshot, + bodies: cBodiesSnapshot, + transactions: cTxsSnapshot, + } + + status := C.call_silkworm_add_snapshot_func(s.addSnapshot, s.instance, &cChainSnapshot) //nolint:gocritic + if status == SILKWORM_OK { + return nil + } + return fmt.Errorf("silkworm_add_snapshot error %d", status) +} + +func (s *Silkworm) ExecuteBlocks(txn kv.Tx, chainID *big.Int, startBlock uint64, maxBlock uint64, batchSize uint64, writeChangeSets, writeReceipts, writeCallTraces bool) (lastExecutedBlock uint64, err error) { + cTxn := (*C.MDBX_txn)(txn.CHandle()) + cChainId := C.uint64_t(chainID.Uint64()) + cStartBlock := C.uint64_t(startBlock) + cMaxBlock := C.uint64_t(maxBlock) + cBatchSize := C.uint64_t(batchSize) + cWriteChangeSets := C._Bool(writeChangeSets) + cWriteReceipts := C._Bool(writeReceipts) + cWriteCallTraces := C._Bool(writeCallTraces) + cLastExecutedBlock := C.uint64_t(startBlock - 1) + cMdbxErrorCode := C.int(0) + status := C.call_silkworm_execute_blocks_func(s.executeBlocks, s.instance, cTxn, cChainId, cStartBlock, + cMaxBlock, cBatchSize, cWriteChangeSets, cWriteReceipts, cWriteCallTraces, &cLastExecutedBlock, &cMdbxErrorCode) + lastExecutedBlock = uint64(cLastExecutedBlock) + // Handle successful execution + if status == SILKWORM_OK { + return lastExecutedBlock, nil + } + // Handle special erros + if status == SILKWORM_INVALID_BLOCK { + return lastExecutedBlock, consensus.ErrInvalidBlock + } + if status == SILKWORM_TERMINATION_SIGNAL { + return lastExecutedBlock, ErrInterrupted + } + return lastExecutedBlock, fmt.Errorf("silkworm_execute_blocks error %d, MDBX error %d", status, cMdbxErrorCode) +} diff --git a/turbo/silkworm/types.go b/turbo/silkworm/types.go new file mode 100644 index 00000000000..0dea939761a --- /dev/null +++ b/turbo/silkworm/types.go @@ -0,0 +1,65 @@ +package silkworm + +import "unsafe" + +type MemoryMappedRegion struct { + FilePath string + DataHandle unsafe.Pointer + Size int64 +} + +type MappedHeaderSnapshot struct { + Segment *MemoryMappedRegion + IdxHeaderHash *MemoryMappedRegion +} + +type MappedBodySnapshot struct { + Segment *MemoryMappedRegion + IdxBodyNumber *MemoryMappedRegion +} + +type MappedTxnSnapshot struct { + Segment *MemoryMappedRegion + IdxTxnHash *MemoryMappedRegion + IdxTxnHash2BlockNum *MemoryMappedRegion +} + +type MappedChainSnapshot struct { + Headers *MappedHeaderSnapshot + Bodies *MappedBodySnapshot + Txs *MappedTxnSnapshot +} + +func NewMemoryMappedRegion(filePath string, dataHandle unsafe.Pointer, size int64) *MemoryMappedRegion { + region := &MemoryMappedRegion{ + FilePath: filePath, + DataHandle: dataHandle, + Size: size, + } + return region +} + +func NewMappedHeaderSnapshot(segment, idxHeaderHash *MemoryMappedRegion) *MappedHeaderSnapshot { + snapshot := &MappedHeaderSnapshot{ + Segment: segment, + IdxHeaderHash: idxHeaderHash, + } + return snapshot +} + +func NewMappedBodySnapshot(segment, idxBodyNumber *MemoryMappedRegion) *MappedBodySnapshot { + snapshot := &MappedBodySnapshot{ + Segment: segment, + IdxBodyNumber: idxBodyNumber, + } + return snapshot +} + +func NewMappedTxnSnapshot(segment, idxTxnHash, idxTxnHash2BlockNum *MemoryMappedRegion) *MappedTxnSnapshot { + snapshot := &MappedTxnSnapshot{ + Segment: segment, + IdxTxnHash: idxTxnHash, + IdxTxnHash2BlockNum: idxTxnHash2BlockNum, + } + return snapshot +} diff --git a/turbo/snapshotsync/freezeblocks/block_snapshots.go b/turbo/snapshotsync/freezeblocks/block_snapshots.go index e1060bfc7d5..96e222d54ee 100644 --- a/turbo/snapshotsync/freezeblocks/block_snapshots.go +++ b/turbo/snapshotsync/freezeblocks/block_snapshots.go @@ -44,6 +44,7 @@ import ( "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/rlp" "github.com/ledgerwatch/erigon/turbo/services" + "github.com/ledgerwatch/erigon/turbo/silkworm" "github.com/ledgerwatch/erigon/turbo/snapshotsync/snapcfg" "github.com/ledgerwatch/log/v3" "golang.org/x/exp/slices" @@ -840,6 +841,59 @@ func (s *RoSnapshots) PrintDebug() { } } +func (s *RoSnapshots) AddSnapshotsToSilkworm(silkwormInstance *silkworm.Silkworm) error { + mappedHeaderSnapshots := make([]*silkworm.MappedHeaderSnapshot, 0) + err := s.Headers.View(func(segments []*HeaderSegment) error { + for _, headerSegment := range segments { + mappedHeaderSnapshots = append(mappedHeaderSnapshots, headerSegment.mappedSnapshot()) + } + return nil + }) + if err != nil { + return err + } + + mappedBodySnapshots := make([]*silkworm.MappedBodySnapshot, 0) + err = s.Bodies.View(func(segments []*BodySegment) error { + for _, bodySegment := range segments { + mappedBodySnapshots = append(mappedBodySnapshots, bodySegment.mappedSnapshot()) + } + return nil + }) + if err != nil { + return err + } + + mappedTxnSnapshots := make([]*silkworm.MappedTxnSnapshot, 0) + err = s.Txs.View(func(segments []*TxnSegment) error { + for _, txnSegment := range segments { + mappedTxnSnapshots = append(mappedTxnSnapshots, txnSegment.mappedSnapshot()) + } + return nil + }) + if err != nil { + return err + } + + if len(mappedHeaderSnapshots) != len(mappedBodySnapshots) || len(mappedBodySnapshots) != len(mappedTxnSnapshots) { + return fmt.Errorf("addSnapshots: the number of headers/bodies/txs snapshots must be the same") + } + + for i := 0; i < len(mappedHeaderSnapshots); i++ { + mappedSnapshot := &silkworm.MappedChainSnapshot{ + Headers: mappedHeaderSnapshots[i], + Bodies: mappedBodySnapshots[i], + Txs: mappedTxnSnapshots[i], + } + err := silkwormInstance.AddSnapshot(mappedSnapshot) + if err != nil { + return err + } + } + + return nil +} + func buildIdx(ctx context.Context, sn snaptype.FileInfo, chainConfig *chain.Config, tmpDir string, p *background.Progress, lvl log.Lvl, logger log.Logger) error { //_, fName := filepath.Split(sn.Path) //log.Info("[snapshots] build idx", "file", fName) @@ -1137,10 +1191,13 @@ type BlockRetire struct { func NewBlockRetire(workers int, dirs datadir.Dirs, blockReader services.FullBlockReader, blockWriter *blockio.BlockWriter, db kv.RoDB, notifier services.DBEventNotifier, logger log.Logger) *BlockRetire { return &BlockRetire{workers: workers, tmpDir: dirs.Tmp, dirs: dirs, blockReader: blockReader, blockWriter: blockWriter, db: db, notifier: notifier, logger: logger} } + func (br *BlockRetire) snapshots() *RoSnapshots { return br.blockReader.Snapshots().(*RoSnapshots) } + func (br *BlockRetire) borSnapshots() *BorRoSnapshots { return br.blockReader.BorSnapshots().(*BorRoSnapshots) } + func (br *BlockRetire) HasNewFrozenFiles() bool { return br.needSaveFilesListInDB.CompareAndSwap(true, false) } @@ -1152,6 +1209,7 @@ func CanRetire(curBlockNum uint64, blocksInSnapshots uint64) (blockFrom, blockTo blockFrom = blocksInSnapshots + 1 return canRetire(blockFrom, curBlockNum-params.FullImmutabilityThreshold) } + func canRetire(from, to uint64) (blockFrom, blockTo uint64, can bool) { if to <= from { return @@ -1182,6 +1240,7 @@ func canRetire(from, to uint64) (blockFrom, blockTo uint64, can bool) { } return blockFrom, blockTo, blockTo-blockFrom >= 1_000 } + func CanDeleteTo(curBlockNum uint64, blocksInSnapshots uint64) (blockTo uint64) { if curBlockNum+999 < params.FullImmutabilityThreshold { // To prevent overflow of uint64 below @@ -1190,6 +1249,7 @@ func CanDeleteTo(curBlockNum uint64, blocksInSnapshots uint64) (blockTo uint64) hardLimit := (curBlockNum/1_000)*1_000 - params.FullImmutabilityThreshold return cmp.Min(hardLimit, blocksInSnapshots+1) } + func (br *BlockRetire) RetireBlocks(ctx context.Context, blockFrom, blockTo uint64, lvl log.Lvl, seedNewSnapshots func(downloadRequest []services.DownloadRequest) error) error { chainConfig := fromdb.ChainConfig(br.db) notifier, logger, blockReader, tmpDir, db, workers := br.notifier, br.logger, br.blockReader, br.tmpDir, br.db, br.workers @@ -1238,6 +1298,7 @@ func (br *BlockRetire) RetireBlocks(ctx context.Context, blockFrom, blockTo uint } return nil } + func (br *BlockRetire) PruneAncientBlocks(tx kv.RwTx, limit int, includeBor bool) error { if br.blockReader.FreezingCfg().KeepBlocks { return nil @@ -1285,6 +1346,7 @@ func (br *BlockRetire) RetireBlocksInBackground(ctx context.Context, forwardProg } }() } + func (br *BlockRetire) BuildMissedIndicesIfNeed(ctx context.Context, logPrefix string, notifier services.DBEventNotifier, cc *chain.Config) error { snapshots := br.snapshots() snapshots.LogStat() @@ -2336,3 +2398,22 @@ func (m *Merger) removeOldFiles(toDel []string, snapDir string) { _ = os.Remove(f) } } + +func (sn *HeaderSegment) mappedSnapshot() *silkworm.MappedHeaderSnapshot { + segmentRegion := silkworm.NewMemoryMappedRegion(sn.seg.FilePath(), sn.seg.DataHandle(), sn.seg.Size()) + idxRegion := silkworm.NewMemoryMappedRegion(sn.idxHeaderHash.FilePath(), sn.idxHeaderHash.DataHandle(), sn.idxHeaderHash.Size()) + return silkworm.NewMappedHeaderSnapshot(segmentRegion, idxRegion) +} + +func (sn *BodySegment) mappedSnapshot() *silkworm.MappedBodySnapshot { + segmentRegion := silkworm.NewMemoryMappedRegion(sn.seg.FilePath(), sn.seg.DataHandle(), sn.seg.Size()) + idxRegion := silkworm.NewMemoryMappedRegion(sn.idxBodyNumber.FilePath(), sn.idxBodyNumber.DataHandle(), sn.idxBodyNumber.Size()) + return silkworm.NewMappedBodySnapshot(segmentRegion, idxRegion) +} + +func (sn *TxnSegment) mappedSnapshot() *silkworm.MappedTxnSnapshot { + segmentRegion := silkworm.NewMemoryMappedRegion(sn.Seg.FilePath(), sn.Seg.DataHandle(), sn.Seg.Size()) + idxTxnHashRegion := silkworm.NewMemoryMappedRegion(sn.IdxTxnHash.FilePath(), sn.IdxTxnHash.DataHandle(), sn.IdxTxnHash.Size()) + idxTxnHash2BlockRegion := silkworm.NewMemoryMappedRegion(sn.IdxTxnHash2BlockNum.FilePath(), sn.IdxTxnHash2BlockNum.DataHandle(), sn.IdxTxnHash2BlockNum.Size()) + return silkworm.NewMappedTxnSnapshot(segmentRegion, idxTxnHashRegion, idxTxnHash2BlockRegion) +} diff --git a/turbo/stages/mock/mock_sentry.go b/turbo/stages/mock/mock_sentry.go index c10cbbe4858..6f93903177f 100644 --- a/turbo/stages/mock/mock_sentry.go +++ b/turbo/stages/mock/mock_sentry.go @@ -340,7 +340,7 @@ func MockWithEverything(tb testing.TB, gspec *types.Genesis, key *ecdsa.PrivateK inMemoryExecution := func(batch kv.RwTx, header *types.Header, body *types.RawBody, unwindPoint uint64, headersChain []*types.Header, bodiesChain []*types.RawBody, notifications *shards.Notifications) error { // Needs its own notifications to not update RPC daemon and txpool about pending blocks - stateSync := stages2.NewInMemoryExecution(ctx, mock.DB, ðconfig.Defaults, mock.sentriesClient, dirs, notifications, mock.BlockReader, blockWriter, agg, log.New() /* logging will be discarded */) + stateSync := stages2.NewInMemoryExecution(ctx, mock.DB, ðconfig.Defaults, mock.sentriesClient, dirs, notifications, mock.BlockReader, blockWriter, agg, nil, log.New() /* logging will be discarded */) // We start the mining step if err := stages2.StateStep(ctx, nil, engine, batch, blockWriter, stateSync, mock.sentriesClient.Bd, header, body, unwindPoint, headersChain, bodiesChain); err != nil { logger.Warn("Could not validate block", "err", err) @@ -390,7 +390,7 @@ func MockWithEverything(tb testing.TB, gspec *types.Genesis, key *ecdsa.PrivateK blockRetire := freezeblocks.NewBlockRetire(1, dirs, mock.BlockReader, blockWriter, mock.DB, mock.Notifications.Events, logger) mock.Sync = stagedsync.New( stagedsync.DefaultStages(mock.Ctx, - stagedsync.StageSnapshotsCfg(mock.DB, *mock.ChainConfig, dirs, blockRetire, snapshotsDownloader, mock.BlockReader, mock.Notifications.Events, mock.HistoryV3, mock.agg), + stagedsync.StageSnapshotsCfg(mock.DB, *mock.ChainConfig, dirs, blockRetire, snapshotsDownloader, mock.BlockReader, mock.Notifications.Events, mock.HistoryV3, mock.agg, nil), stagedsync.StageHeadersCfg(mock.DB, mock.sentriesClient.Hd, mock.sentriesClient.Bd, *mock.ChainConfig, sendHeaderRequest, propagateNewBlockHashes, penalize, cfg.BatchSize, false, mock.BlockReader, blockWriter, dirs.Tmp, mock.Notifications, engine_helpers.NewForkValidatorMock(1), nil), stagedsync.StageBorHeimdallCfg(mock.DB, stagedsync.MiningState{}, *mock.ChainConfig, nil /* heimdallClient */, mock.BlockReader, nil, nil), stagedsync.StageBlockHashesCfg(mock.DB, mock.Dirs.Tmp, mock.ChainConfig, blockWriter), @@ -414,6 +414,7 @@ func MockWithEverything(tb testing.TB, gspec *types.Genesis, key *ecdsa.PrivateK mock.gspec, ethconfig.Defaults.Sync, mock.agg, + nil, ), stagedsync.StageHashStateCfg(mock.DB, mock.Dirs, cfg.HistoryV3), stagedsync.StageTrieCfg(mock.DB, checkStateRoot, true, false, dirs.Tmp, mock.BlockReader, mock.sentriesClient.Hd, cfg.HistoryV3, mock.agg), @@ -460,7 +461,7 @@ func MockWithEverything(tb testing.TB, gspec *types.Genesis, key *ecdsa.PrivateK cfg.Genesis = gspec pipelineStages := stages2.NewPipelineStages(ctx, db, &cfg, mock.sentriesClient, mock.Notifications, - snapshotsDownloader, mock.BlockReader, blockRetire, mock.agg, forkValidator, logger, checkStateRoot) + snapshotsDownloader, mock.BlockReader, blockRetire, mock.agg, nil, forkValidator, logger, checkStateRoot) mock.posStagedSync = stagedsync.New(pipelineStages, stagedsync.PipelineUnwindOrder, stagedsync.PipelinePruneOrder, logger) mock.StreamWg.Add(1) diff --git a/turbo/stages/stageloop.go b/turbo/stages/stageloop.go index 021d23a04c7..2bd93144d5b 100644 --- a/turbo/stages/stageloop.go +++ b/turbo/stages/stageloop.go @@ -22,6 +22,7 @@ import ( "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/turbo/engineapi/engine_helpers" "github.com/ledgerwatch/erigon/turbo/services" + "github.com/ledgerwatch/erigon/turbo/silkworm" "github.com/ledgerwatch/erigon/cmd/sentry/sentry" "github.com/ledgerwatch/erigon/consensus/bor/heimdall" @@ -455,6 +456,7 @@ func NewDefaultStages(ctx context.Context, blockReader services.FullBlockReader, blockRetire services.BlockRetire, agg *state.AggregatorV3, + silkworm *silkworm.Silkworm, forkValidator *engine_helpers.ForkValidator, heimdallClient heimdall.IHeimdallClient, logger log.Logger, @@ -473,7 +475,7 @@ func NewDefaultStages(ctx context.Context, } return stagedsync.DefaultStages(ctx, - stagedsync.StageSnapshotsCfg(db, *controlServer.ChainConfig, dirs, blockRetire, snapDownloader, blockReader, notifications.Events, cfg.HistoryV3, agg), + stagedsync.StageSnapshotsCfg(db, *controlServer.ChainConfig, dirs, blockRetire, snapDownloader, blockReader, notifications.Events, cfg.HistoryV3, agg, silkworm), stagedsync.StageHeadersCfg(db, controlServer.Hd, controlServer.Bd, *controlServer.ChainConfig, controlServer.SendHeaderRequest, controlServer.PropagateNewBlockHashes, controlServer.Penalize, cfg.BatchSize, p2pCfg.NoDiscovery, blockReader, blockWriter, dirs.Tmp, notifications, forkValidator, loopBreakCheck), stagedsync.StageBorHeimdallCfg(db, stagedsync.MiningState{}, *controlServer.ChainConfig, heimdallClient, blockReader, controlServer.Hd, controlServer.Penalize), stagedsync.StageBlockHashesCfg(db, dirs.Tmp, controlServer.ChainConfig, blockWriter), @@ -497,6 +499,7 @@ func NewDefaultStages(ctx context.Context, cfg.Genesis, cfg.Sync, agg, + silkworm, ), stagedsync.StageHashStateCfg(db, dirs, cfg.HistoryV3), stagedsync.StageTrieCfg(db, true, true, false, dirs.Tmp, blockReader, controlServer.Hd, cfg.HistoryV3, agg), @@ -517,6 +520,7 @@ func NewPipelineStages(ctx context.Context, blockReader services.FullBlockReader, blockRetire services.BlockRetire, agg *state.AggregatorV3, + silkworm *silkworm.Silkworm, forkValidator *engine_helpers.ForkValidator, logger log.Logger, checkStateRoot bool, @@ -529,7 +533,7 @@ func NewPipelineStages(ctx context.Context, runInTestMode := cfg.ImportMode return stagedsync.PipelineStages(ctx, - stagedsync.StageSnapshotsCfg(db, *controlServer.ChainConfig, dirs, blockRetire, snapDownloader, blockReader, notifications.Events, cfg.HistoryV3, agg), + stagedsync.StageSnapshotsCfg(db, *controlServer.ChainConfig, dirs, blockRetire, snapDownloader, blockReader, notifications.Events, cfg.HistoryV3, agg, silkworm), stagedsync.StageBlockHashesCfg(db, dirs.Tmp, controlServer.ChainConfig, blockWriter), stagedsync.StageSendersCfg(db, controlServer.ChainConfig, false, dirs.Tmp, cfg.Prune, blockReader, controlServer.Hd), stagedsync.StageExecuteBlocksCfg( @@ -550,6 +554,7 @@ func NewPipelineStages(ctx context.Context, cfg.Genesis, cfg.Sync, agg, + silkworm, ), stagedsync.StageHashStateCfg(db, dirs, cfg.HistoryV3), stagedsync.StageTrieCfg(db, checkStateRoot, true, false, dirs.Tmp, blockReader, controlServer.Hd, cfg.HistoryV3, agg), @@ -563,7 +568,7 @@ func NewPipelineStages(ctx context.Context, func NewInMemoryExecution(ctx context.Context, db kv.RwDB, cfg *ethconfig.Config, controlServer *sentry.MultiClient, dirs datadir.Dirs, notifications *shards.Notifications, blockReader services.FullBlockReader, blockWriter *blockio.BlockWriter, agg *state.AggregatorV3, - logger log.Logger) *stagedsync.Sync { + silkworm *silkworm.Silkworm, logger log.Logger) *stagedsync.Sync { return stagedsync.New( stagedsync.StateStages(ctx, stagedsync.StageHeadersCfg(db, controlServer.Hd, controlServer.Bd, *controlServer.ChainConfig, controlServer.SendHeaderRequest, controlServer.PropagateNewBlockHashes, controlServer.Penalize, cfg.BatchSize, false, blockReader, blockWriter, dirs.Tmp, nil, nil, nil), @@ -588,6 +593,7 @@ func NewInMemoryExecution(ctx context.Context, db kv.RwDB, cfg *ethconfig.Config cfg.Genesis, cfg.Sync, agg, + silkworm, ), stagedsync.StageHashStateCfg(db, dirs, cfg.HistoryV3), stagedsync.StageTrieCfg(db, true, true, true, dirs.Tmp, blockReader, controlServer.Hd, cfg.HistoryV3, agg)), From b107a97e49c5c1fe486356afd5fbb93e0d94509f Mon Sep 17 00:00:00 2001 From: Manav Darji Date: Thu, 5 Oct 2023 09:15:40 +0530 Subject: [PATCH 02/14] eth/borfinality: handle errors to prevent access logging (#8372) This PR adds a few checks on top of https://github.com/ledgerwatch/erigon/pull/8364 to prevent access logging. Moreover, fixes a bug which sent wrong error to parent function. --- eth/borfinality/whitelist.go | 27 +++++++++++++++++---------- eth/borfinality/whitelist_helpers.go | 4 ++-- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/eth/borfinality/whitelist.go b/eth/borfinality/whitelist.go index 23f64cecf04..f523db5db77 100644 --- a/eth/borfinality/whitelist.go +++ b/eth/borfinality/whitelist.go @@ -94,7 +94,7 @@ func startNoAckMilestoneByIDService(config *config) { RetryHeimdallHandler(handleNoAckMilestoneByID, config, tickerDuration, noAckMilestoneTimeout, fnName) } -type heimdallHandler func(ctx context.Context, heimdall heimdall.IHeimdallClient, config *config) error +type heimdallHandler func(ctx context.Context, heimdallClient heimdall.IHeimdallClient, config *config) error func RetryHeimdallHandler(fn heimdallHandler, config *config, tickerDuration time.Duration, timeout time.Duration, fnName string) { retryHeimdallHandler(fn, config, tickerDuration, timeout, fnName) @@ -144,12 +144,12 @@ func retryHeimdallHandler(fn heimdallHandler, config *config, tickerDuration tim } // handleWhitelistCheckpoint handles the checkpoint whitelist mechanism. -func handleWhitelistCheckpoint(ctx context.Context, heimdall heimdall.IHeimdallClient, config *config) error { +func handleWhitelistCheckpoint(ctx context.Context, heimdallClient heimdall.IHeimdallClient, config *config) error { service := whitelist.GetWhitelistingService() // Create a new bor verifier, which will be used to verify checkpoints and milestones verifier := newBorVerifier() - blockNum, blockHash, err := fetchWhitelistCheckpoint(ctx, heimdall, verifier, config) + blockNum, blockHash, err := fetchWhitelistCheckpoint(ctx, heimdallClient, verifier, config) // If the array is empty, we're bound to receive an error. Non-nill error and non-empty array // means that array has partial elements and it failed for some block. We'll add those partial @@ -164,12 +164,12 @@ func handleWhitelistCheckpoint(ctx context.Context, heimdall heimdall.IHeimdallC } // handleMilestone handles the milestone mechanism. -func handleMilestone(ctx context.Context, heimdall heimdall.IHeimdallClient, config *config) error { +func handleMilestone(ctx context.Context, heimdallClient heimdall.IHeimdallClient, config *config) error { service := whitelist.GetWhitelistingService() // Create a new bor verifier, which will be used to verify checkpoints and milestones verifier := newBorVerifier() - num, hash, err := fetchWhitelistMilestone(ctx, heimdall, verifier, config) + num, hash, err := fetchWhitelistMilestone(ctx, heimdallClient, verifier, config) // If the current chain head is behind the received milestone, add it to the future milestone // list. Also, the hash mismatch (end block hash) error will lead to rewind so also @@ -178,6 +178,10 @@ func handleMilestone(ctx context.Context, heimdall heimdall.IHeimdallClient, con service.ProcessFutureMilestone(num, hash) } + if errors.Is(err, heimdall.ErrServiceUnavailable) { + return nil + } + if err != nil { return err } @@ -187,11 +191,14 @@ func handleMilestone(ctx context.Context, heimdall heimdall.IHeimdallClient, con return nil } -func handleNoAckMilestone(ctx context.Context, heimdall heimdall.IHeimdallClient, config *config) error { +func handleNoAckMilestone(ctx context.Context, heimdallClient heimdall.IHeimdallClient, config *config) error { service := whitelist.GetWhitelistingService() - milestoneID, err := fetchNoAckMilestone(ctx, heimdall, config.logger) + milestoneID, err := fetchNoAckMilestone(ctx, heimdallClient, config.logger) + + if errors.Is(err, heimdall.ErrServiceUnavailable) { + return nil + } - //If failed to fetch the no-ack milestone then it give the error. if err != nil { return err } @@ -201,12 +208,12 @@ func handleNoAckMilestone(ctx context.Context, heimdall heimdall.IHeimdallClient return nil } -func handleNoAckMilestoneByID(ctx context.Context, heimdall heimdall.IHeimdallClient, config *config) error { +func handleNoAckMilestoneByID(ctx context.Context, heimdallClient heimdall.IHeimdallClient, config *config) error { service := whitelist.GetWhitelistingService() milestoneIDs := service.GetMilestoneIDsList() for _, milestoneID := range milestoneIDs { - err := fetchNoAckMilestoneByID(ctx, heimdall, milestoneID, config.logger) + err := fetchNoAckMilestoneByID(ctx, heimdallClient, milestoneID, config.logger) if err == nil { service.RemoveMilestoneID(milestoneID) } diff --git a/eth/borfinality/whitelist_helpers.go b/eth/borfinality/whitelist_helpers.go index 4b8ef92cb91..586ec8cac3d 100644 --- a/eth/borfinality/whitelist_helpers.go +++ b/eth/borfinality/whitelist_helpers.go @@ -66,7 +66,7 @@ func fetchWhitelistMilestone(ctx context.Context, heimdallClient heimdall.IHeimd milestone, err := heimdallClient.FetchMilestone(ctx) if errors.Is(err, heimdall.ErrServiceUnavailable) { config.logger.Debug("Failed to fetch latest milestone for whitelisting", "err", err) - return num, hash, errMilestone + return num, hash, err } if err != nil { @@ -99,7 +99,7 @@ func fetchNoAckMilestone(ctx context.Context, heimdallClient heimdall.IHeimdallC milestoneID, err := heimdallClient.FetchLastNoAckMilestone(ctx) if errors.Is(err, heimdall.ErrServiceUnavailable) { logger.Debug("Failed to fetch latest no-ack milestone", "err", err) - return milestoneID, errMilestone + return milestoneID, err } if err != nil { From c293883ec039ebcc9bb7bbe85807cabee828b4bc Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Thu, 5 Oct 2023 12:23:08 +0700 Subject: [PATCH 03/14] evm: no interface (#8376) after removal of tevm experiment - we left interfaces everywhere removing it for performance and for geth compatibility --- cmd/state/commands/opcode_tracer.go | 4 +- cmd/state/exec3/calltracer_v3.go | 2 +- core/state_processor.go | 2 +- core/state_transition.go | 6 +-- core/vm/gas_table.go | 32 +++++++-------- core/vm/interpreter.go | 4 +- core/vm/jump_table.go | 2 +- core/vm/logger.go | 2 +- core/vm/operations_acl.go | 16 ++++---- core/vm/stack/stack.go | 39 ------------------- eth/calltracer/calltracer.go | 2 +- eth/tracers/js/goja.go | 4 +- eth/tracers/logger/access_list_tracer.go | 2 +- eth/tracers/logger/json_stream.go | 4 +- eth/tracers/logger/logger.go | 8 ++-- eth/tracers/logger/logger_json.go | 4 +- eth/tracers/native/4byte.go | 2 +- eth/tracers/native/call.go | 2 +- eth/tracers/native/mux.go | 2 +- eth/tracers/native/noop.go | 2 +- eth/tracers/native/prestate.go | 4 +- turbo/jsonrpc/otterscan_default_tracer.go | 2 +- .../otterscan_trace_contract_creator.go | 2 +- turbo/jsonrpc/otterscan_trace_touch.go | 2 +- turbo/jsonrpc/otterscan_trace_transaction.go | 2 +- turbo/jsonrpc/trace_adhoc.go | 2 +- 26 files changed, 58 insertions(+), 97 deletions(-) diff --git a/cmd/state/commands/opcode_tracer.go b/cmd/state/commands/opcode_tracer.go index 50672c4dfc8..0ac9f9d0771 100644 --- a/cmd/state/commands/opcode_tracer.go +++ b/cmd/state/commands/opcode_tracer.go @@ -114,7 +114,7 @@ type opcodeTracer struct { saveBblocks bool blockNumber uint64 depth int - env vm.VMInterface + env *vm.EVM } func NewOpcodeTracer(blockNum uint64, saveOpcodes bool, saveBblocks bool) *opcodeTracer { @@ -195,7 +195,7 @@ func (ot *opcodeTracer) captureStartOrEnter(from, to libcommon.Address, create b ot.stack = append(ot.stack, &newTx) } -func (ot *opcodeTracer) CaptureStart(env vm.VMInterface, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { +func (ot *opcodeTracer) CaptureStart(env *vm.EVM, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { ot.env = env ot.depth = 0 ot.captureStartOrEnter(from, to, create, input) diff --git a/cmd/state/exec3/calltracer_v3.go b/cmd/state/exec3/calltracer_v3.go index 31e25fa0007..951e114dfa8 100644 --- a/cmd/state/exec3/calltracer_v3.go +++ b/cmd/state/exec3/calltracer_v3.go @@ -22,7 +22,7 @@ func (ct *CallTracer) Tos() map[libcommon.Address]struct{} { return ct.tos } func (ct *CallTracer) CaptureTxStart(gasLimit uint64) {} func (ct *CallTracer) CaptureTxEnd(restGas uint64) {} -func (ct *CallTracer) CaptureStart(env vm.VMInterface, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { +func (ct *CallTracer) CaptureStart(env *vm.EVM, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { if ct.froms == nil { ct.froms = map[libcommon.Address]struct{}{} ct.tos = map[libcommon.Address]struct{}{} diff --git a/core/state_processor.go b/core/state_processor.go index 672385fa7f2..be097186fa6 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -34,7 +34,7 @@ import ( // indicating the block was invalid. func applyTransaction(config *chain.Config, engine consensus.EngineReader, gp *GasPool, ibs *state.IntraBlockState, stateWriter state.StateWriter, header *types.Header, tx types.Transaction, usedGas, usedBlobGas *uint64, - evm vm.VMInterface, cfg vm.Config) (*types.Receipt, []byte, error) { + evm *vm.EVM, cfg vm.Config) (*types.Receipt, []byte, error) { rules := evm.ChainRules() msg, err := tx.AsMessage(*types.MakeSigner(config, header.Number.Uint64(), header.Time), header.BaseFee, rules) if err != nil { diff --git a/core/state_transition.go b/core/state_transition.go index 5ab9d196db0..8b3f4aaa63e 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -66,7 +66,7 @@ type StateTransition struct { value *uint256.Int data []byte state evmtypes.IntraBlockState - evm vm.VMInterface + evm *vm.EVM //some pre-allocated intermediate variables sharedBuyGas *uint256.Int @@ -151,7 +151,7 @@ func IntrinsicGas(data []byte, accessList types2.AccessList, isContractCreation } // NewStateTransition initialises and returns a new state transition object. -func NewStateTransition(evm vm.VMInterface, msg Message, gp *GasPool) *StateTransition { +func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition { isBor := evm.ChainConfig().Bor != nil return &StateTransition{ gp: gp, @@ -181,7 +181,7 @@ func NewStateTransition(evm vm.VMInterface, msg Message, gp *GasPool) *StateTran // `refunds` is false when it is not required to apply gas refunds // `gasBailout` is true when it is not required to fail transaction if the balance is not enough to pay gas. // for trace_call to replicate OE/Pariry behaviour -func ApplyMessage(evm vm.VMInterface, msg Message, gp *GasPool, refunds bool, gasBailout bool) (*ExecutionResult, error) { +func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool, refunds bool, gasBailout bool) (*ExecutionResult, error) { return NewStateTransition(evm, msg, gp).TransitionDb(refunds, gasBailout) } diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go index f4495765f4c..90b39100c3e 100644 --- a/core/vm/gas_table.go +++ b/core/vm/gas_table.go @@ -68,7 +68,7 @@ func memoryGasCost(mem *Memory, newMemSize uint64) (uint64, error) { // EXTCODECOPY (stack position 3) // RETURNDATACOPY (stack position 2) func memoryCopierGas(stackpos int) gasFunc { - return func(_ VMInterpreter, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { + return func(_ *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { // Gas for expanding the memory gas, err := memoryGasCost(mem, memorySize) if err != nil { @@ -99,7 +99,7 @@ var ( gasReturnDataCopy = memoryCopierGas(2) ) -func gasSStore(evm VMInterpreter, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { +func gasSStore(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { value, x := stack.Back(1), stack.Back(0) key := libcommon.Hash(x.Bytes32()) var current uint256.Int @@ -182,7 +182,7 @@ func gasSStore(evm VMInterpreter, contract *Contract, stack *stack.Stack, mem *M // 2.2.2. If original value equals new value (this storage slot is reset): // 2.2.2.1. If original value is 0, add SSTORE_SET_GAS - SLOAD_GAS to refund counter. // 2.2.2.2. Otherwise, add SSTORE_RESET_GAS - SLOAD_GAS gas to refund counter. -func gasSStoreEIP2200(evm VMInterpreter, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { +func gasSStoreEIP2200(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { // If we fail the minimum gas availability invariant, fail (0) if contract.Gas <= params.SstoreSentryGasEIP2200 { return 0, errors.New("not enough gas for reentrancy sentry") @@ -226,7 +226,7 @@ func gasSStoreEIP2200(evm VMInterpreter, contract *Contract, stack *stack.Stack, } func makeGasLog(n uint64) gasFunc { - return func(_ VMInterpreter, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { + return func(_ *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { requestedSize, overflow := stack.Back(1).Uint64WithOverflow() if overflow { return 0, ErrGasUintOverflow @@ -255,7 +255,7 @@ func makeGasLog(n uint64) gasFunc { } } -func gasKeccak256(_ VMInterpreter, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { +func gasKeccak256(_ *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { gas, err := memoryGasCost(mem, memorySize) if err != nil { return 0, err @@ -276,7 +276,7 @@ func gasKeccak256(_ VMInterpreter, contract *Contract, stack *stack.Stack, mem * // pureMemoryGascost is used by several operations, which aside from their // static cost have a dynamic cost which is solely based on the memory // expansion -func pureMemoryGascost(_ VMInterpreter, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { +func pureMemoryGascost(_ *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { return memoryGasCost(mem, memorySize) } @@ -289,7 +289,7 @@ var ( gasCreate = pureMemoryGascost ) -func gasCreate2(_ VMInterpreter, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { +func gasCreate2(_ *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { gas, err := memoryGasCost(mem, memorySize) if err != nil { return 0, err @@ -310,7 +310,7 @@ func gasCreate2(_ VMInterpreter, contract *Contract, stack *stack.Stack, mem *Me return gas, nil } -func gasCreateEip3860(_ VMInterpreter, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { +func gasCreateEip3860(_ *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { gas, err := memoryGasCost(mem, memorySize) if err != nil { return 0, err @@ -329,7 +329,7 @@ func gasCreateEip3860(_ VMInterpreter, contract *Contract, stack *stack.Stack, m return gas, nil } -func gasCreate2Eip3860(_ VMInterpreter, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { +func gasCreate2Eip3860(_ *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { gas, err := memoryGasCost(mem, memorySize) if err != nil { return 0, err @@ -348,7 +348,7 @@ func gasCreate2Eip3860(_ VMInterpreter, contract *Contract, stack *stack.Stack, return gas, nil } -func gasExpFrontier(_ VMInterpreter, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { +func gasExpFrontier(_ *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { expByteLen := uint64(libcommon.BitLenToByteLen(stack.Data[stack.Len()-2].BitLen())) var ( @@ -361,7 +361,7 @@ func gasExpFrontier(_ VMInterpreter, contract *Contract, stack *stack.Stack, mem return gas, nil } -func gasExpEIP160(_ VMInterpreter, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { +func gasExpEIP160(_ *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { expByteLen := uint64(libcommon.BitLenToByteLen(stack.Data[stack.Len()-2].BitLen())) var ( @@ -374,7 +374,7 @@ func gasExpEIP160(_ VMInterpreter, contract *Contract, stack *stack.Stack, mem * return gas, nil } -func gasCall(evm VMInterpreter, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { +func gasCall(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { var ( gas uint64 transfersValue = !stack.Back(2).IsZero() @@ -412,7 +412,7 @@ func gasCall(evm VMInterpreter, contract *Contract, stack *stack.Stack, mem *Mem return gas, nil } -func gasCallCode(evm VMInterpreter, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { +func gasCallCode(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { memoryGas, err := memoryGasCost(mem, memorySize) if err != nil { return 0, err @@ -440,7 +440,7 @@ func gasCallCode(evm VMInterpreter, contract *Contract, stack *stack.Stack, mem return gas, nil } -func gasDelegateCall(evm VMInterpreter, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { +func gasDelegateCall(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { gas, err := memoryGasCost(mem, memorySize) if err != nil { return 0, err @@ -460,7 +460,7 @@ func gasDelegateCall(evm VMInterpreter, contract *Contract, stack *stack.Stack, return gas, nil } -func gasStaticCall(evm VMInterpreter, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { +func gasStaticCall(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { gas, err := memoryGasCost(mem, memorySize) if err != nil { return 0, err @@ -480,7 +480,7 @@ func gasStaticCall(evm VMInterpreter, contract *Contract, stack *stack.Stack, me return gas, nil } -func gasSelfdestruct(evm VMInterpreter, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { +func gasSelfdestruct(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { var gas uint64 // TangerineWhistle (EIP150) gas reprice fork: if evm.ChainRules().IsTangerineWhistle { diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index a6ca2efbe4a..79dbf1161e4 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -99,7 +99,7 @@ type EVMInterpreter struct { // //nolint:structcheck type VM struct { - evm VMInterpreter + evm *EVM cfg Config hasher keccakState // Keccak256 hasher instance shared across opcodes @@ -121,7 +121,7 @@ func copyJumpTable(jt *JumpTable) *JumpTable { } // NewEVMInterpreter returns a new instance of the Interpreter. -func NewEVMInterpreter(evm VMInterpreter, cfg Config) *EVMInterpreter { +func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter { var jt *JumpTable switch { case evm.ChainRules().IsPrague: diff --git a/core/vm/jump_table.go b/core/vm/jump_table.go index 6e6d146c4c7..047c9f53845 100644 --- a/core/vm/jump_table.go +++ b/core/vm/jump_table.go @@ -25,7 +25,7 @@ import ( type ( executionFunc func(pc *uint64, interpreter *EVMInterpreter, callContext *ScopeContext) ([]byte, error) - gasFunc func(VMInterpreter, *Contract, *stack.Stack, *Memory, uint64) (uint64, error) // last parameter is the requested memory size as a uint64 + gasFunc func(*EVM, *Contract, *stack.Stack, *Memory, uint64) (uint64, error) // last parameter is the requested memory size as a uint64 // memorySizeFunc returns the required size, and whether the operation overflowed a uint64 memorySizeFunc func(*stack.Stack) (size uint64, overflow bool) ) diff --git a/core/vm/logger.go b/core/vm/logger.go index ff76ae71efb..5677233f97a 100644 --- a/core/vm/logger.go +++ b/core/vm/logger.go @@ -33,7 +33,7 @@ type EVMLogger interface { CaptureTxStart(gasLimit uint64) CaptureTxEnd(restGas uint64) // Top call frame - CaptureStart(env VMInterface, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) + CaptureStart(env *EVM, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) CaptureEnd(output []byte, usedGas uint64, err error) // Rest of the frames CaptureEnter(typ OpCode, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) diff --git a/core/vm/operations_acl.go b/core/vm/operations_acl.go index 177be61b478..6256ae5740b 100644 --- a/core/vm/operations_acl.go +++ b/core/vm/operations_acl.go @@ -28,7 +28,7 @@ import ( ) func makeGasSStoreFunc(clearingRefund uint64) gasFunc { - return func(evm VMInterpreter, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { + return func(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { // If we fail the minimum gas availability invariant, fail (0) if contract.Gas <= params.SstoreSentryGasEIP2200 { return 0, errors.New("not enough gas for reentrancy sentry") @@ -40,6 +40,7 @@ func makeGasSStoreFunc(clearingRefund uint64) gasFunc { current uint256.Int cost = uint64(0) ) + evm.IntraBlockState().GetState(contract.Address(), &slot, ¤t) // If the caller cannot afford the cost, this change will be rolled back if _, slotMod := evm.IntraBlockState().AddSlotToAccessList(contract.Address(), slot); slotMod { @@ -99,12 +100,11 @@ func makeGasSStoreFunc(clearingRefund uint64) gasFunc { // whose storage is being read) is not yet in accessed_storage_keys, // charge 2100 gas and add the pair to accessed_storage_keys. // If the pair is already in accessed_storage_keys, charge 100 gas. -func gasSLoadEIP2929(evm VMInterpreter, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { +func gasSLoadEIP2929(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { loc := stack.Peek() - slot := libcommon.Hash(loc.Bytes32()) // If the caller cannot afford the cost, this change will be rolled back // If he does afford it, we can skip checking the same thing later on, during execution - if _, slotMod := evm.IntraBlockState().AddSlotToAccessList(contract.Address(), slot); slotMod { + if _, slotMod := evm.IntraBlockState().AddSlotToAccessList(contract.Address(), loc.Bytes32()); slotMod { return params.ColdSloadCostEIP2929, nil } return params.WarmStorageReadCostEIP2929, nil @@ -115,7 +115,7 @@ func gasSLoadEIP2929(evm VMInterpreter, contract *Contract, stack *stack.Stack, // > If the target is not in accessed_addresses, // > charge COLD_ACCOUNT_ACCESS_COST gas, and add the address to accessed_addresses. // > Otherwise, charge WARM_STORAGE_READ_COST gas. -func gasExtCodeCopyEIP2929(evm VMInterpreter, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { +func gasExtCodeCopyEIP2929(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { // memory expansion first (dynamic part of pre-2929 implementation) gas, err := gasExtCodeCopy(evm, contract, stack, mem, memorySize) if err != nil { @@ -141,7 +141,7 @@ func gasExtCodeCopyEIP2929(evm VMInterpreter, contract *Contract, stack *stack.S // - extcodehash, // - extcodesize, // - (ext) balance -func gasEip2929AccountCheck(evm VMInterpreter, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { +func gasEip2929AccountCheck(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { addr := libcommon.Address(stack.Peek().Bytes20()) // If the caller cannot afford the cost, this change will be rolled back if evm.IntraBlockState().AddAddressToAccessList(addr) { @@ -152,7 +152,7 @@ func gasEip2929AccountCheck(evm VMInterpreter, contract *Contract, stack *stack. } func makeCallVariantGasCallEIP2929(oldCalculator gasFunc) gasFunc { - return func(evm VMInterpreter, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { + return func(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { addr := libcommon.Address(stack.Back(1).Bytes20()) // The WarmStorageReadCostEIP2929 (100) is already deducted in the form of a constant cost, so // the cost to charge for cold access, if any, is Cold - Warm @@ -215,7 +215,7 @@ var ( // makeSelfdestructGasFn can create the selfdestruct dynamic gas function for EIP-2929 and EIP-2539 func makeSelfdestructGasFn(refundsEnabled bool) gasFunc { - gasFunc := func(evm VMInterpreter, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { + gasFunc := func(evm *EVM, contract *Contract, stack *stack.Stack, mem *Memory, memorySize uint64) (uint64, error) { var ( gas uint64 address = libcommon.Address(stack.Peek().Bytes20()) diff --git a/core/vm/stack/stack.go b/core/vm/stack/stack.go index e92888a21e1..119d8b61f16 100644 --- a/core/vm/stack/stack.go +++ b/core/vm/stack/stack.go @@ -107,42 +107,3 @@ func ReturnNormalStack(s *Stack) { s.Data = s.Data[:0] stackPool.Put(s) } - -var rStackPool = sync.Pool{ - New: func() interface{} { - return &ReturnStack{data: make([]uint32, 0, 10)} - }, -} - -func ReturnRStack(rs *ReturnStack) { - rs.data = rs.data[:0] - rStackPool.Put(rs) -} - -// ReturnStack is an object for basic return stack operations. -type ReturnStack struct { - data []uint32 -} - -func NewReturnStack() *ReturnStack { - rStack, ok := rStackPool.Get().(*ReturnStack) - if !ok { - log.Error("Type assertion failure", "err", "cannot get ReturnStack pointer from rStackPool") - } - return rStack -} - -func (st *ReturnStack) Push(d uint32) { - st.data = append(st.data, d) -} - -// A uint32 is sufficient as for code below 4.2G -func (st *ReturnStack) Pop() (ret uint32) { - ret = st.data[len(st.data)-1] - st.data = st.data[:len(st.data)-1] - return -} - -func (st *ReturnStack) Data() []uint32 { - return st.data -} diff --git a/eth/calltracer/calltracer.go b/eth/calltracer/calltracer.go index 7271a088f29..c4ca57e06c1 100644 --- a/eth/calltracer/calltracer.go +++ b/eth/calltracer/calltracer.go @@ -45,7 +45,7 @@ func (ct *CallTracer) captureStartOrEnter(from, to libcommon.Address, create boo } } -func (ct *CallTracer) CaptureStart(env vm.VMInterface, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { +func (ct *CallTracer) CaptureStart(env *vm.EVM, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { ct.captureStartOrEnter(from, to, create, code) } func (ct *CallTracer) CaptureEnter(typ vm.OpCode, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { diff --git a/eth/tracers/js/goja.go b/eth/tracers/js/goja.go index cd057c9f5d1..7ca6ec73a14 100644 --- a/eth/tracers/js/goja.go +++ b/eth/tracers/js/goja.go @@ -95,7 +95,7 @@ func fromBuf(vm *goja.Runtime, bufType goja.Value, buf goja.Value, allowString b // JS functions on the relevant EVM hooks. It uses Goja as its JS engine. type jsTracer struct { vm *goja.Runtime - env vm.VMInterface + env *vm.EVM toBig toBigFn // Converts a hex string into a JS bigint toBuf toBufFn // Converts a []byte into a JS buffer fromBuf fromBufFn // Converts an array, hex string or Uint8Array to a []byte @@ -224,7 +224,7 @@ func (t *jsTracer) CaptureTxEnd(restGas uint64) { } // CaptureStart implements the Tracer interface to initialize the tracing operation. -func (t *jsTracer) CaptureStart(env vm.VMInterface, from libcommon.Address, to libcommon.Address, precompile, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { +func (t *jsTracer) CaptureStart(env *vm.EVM, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { t.env = env db := &dbObj{ibs: env.IntraBlockState(), vm: t.vm, toBig: t.toBig, toBuf: t.toBuf, fromBuf: t.fromBuf} t.dbValue = db.setupObject() diff --git a/eth/tracers/logger/access_list_tracer.go b/eth/tracers/logger/access_list_tracer.go index 328634e0bd9..f9f9f981c00 100644 --- a/eth/tracers/logger/access_list_tracer.go +++ b/eth/tracers/logger/access_list_tracer.go @@ -149,7 +149,7 @@ func (a *AccessListTracer) CaptureTxStart(gasLimit uint64) {} func (a *AccessListTracer) CaptureTxEnd(restGas uint64) {} -func (a *AccessListTracer) CaptureStart(env vm.VMInterface, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { +func (a *AccessListTracer) CaptureStart(env *vm.EVM, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { } func (a *AccessListTracer) CaptureEnter(typ vm.OpCode, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { diff --git a/eth/tracers/logger/json_stream.go b/eth/tracers/logger/json_stream.go index 3f272ed6196..5b616e81e7f 100644 --- a/eth/tracers/logger/json_stream.go +++ b/eth/tracers/logger/json_stream.go @@ -30,7 +30,7 @@ type JsonStreamLogger struct { logs []StructLog output []byte //nolint err error //nolint - env vm.VMInterface + env *vm.EVM } // NewStructLogger returns a new logger @@ -52,7 +52,7 @@ func (l *JsonStreamLogger) CaptureTxStart(gasLimit uint64) {} func (l *JsonStreamLogger) CaptureTxEnd(restGas uint64) {} // CaptureStart implements the Tracer interface to initialize the tracing operation. -func (l *JsonStreamLogger) CaptureStart(env vm.VMInterface, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { +func (l *JsonStreamLogger) CaptureStart(env *vm.EVM, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { l.env = env } diff --git a/eth/tracers/logger/logger.go b/eth/tracers/logger/logger.go index 3beb7e7d96c..9e5ddb0889d 100644 --- a/eth/tracers/logger/logger.go +++ b/eth/tracers/logger/logger.go @@ -116,7 +116,7 @@ type StructLogger struct { logs []StructLog output []byte err error - env vm.VMInterface + env *vm.EVM } // NewStructLogger returns a new logger @@ -135,7 +135,7 @@ func (l *StructLogger) CaptureTxStart(gasLimit uint64) {} func (l *StructLogger) CaptureTxEnd(restGas uint64) {} // CaptureStart implements the Tracer interface to initialize the tracing operation. -func (l *StructLogger) CaptureStart(env vm.VMInterface, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { +func (l *StructLogger) CaptureStart(env *vm.EVM, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { l.env = env } @@ -339,7 +339,7 @@ func WriteLogs(writer io.Writer, logs []*types.Log) { type mdLogger struct { out io.Writer cfg *LogConfig - env vm.VMInterface + env *vm.EVM } // NewMarkdownLogger creates a logger which outputs information in a format adapted @@ -373,7 +373,7 @@ func (t *mdLogger) captureStartOrEnter(from, to libcommon.Address, create bool, `) } -func (t *mdLogger) CaptureStart(env vm.VMInterface, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { //nolint:interfacer +func (t *mdLogger) CaptureStart(env *vm.EVM, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { //nolint:interfacer t.env = env t.captureStartOrEnter(from, to, create, input, gas, value) } diff --git a/eth/tracers/logger/logger_json.go b/eth/tracers/logger/logger_json.go index b2c90f3509e..c06b4769226 100644 --- a/eth/tracers/logger/logger_json.go +++ b/eth/tracers/logger/logger_json.go @@ -32,7 +32,7 @@ import ( type JSONLogger struct { encoder *json.Encoder cfg *LogConfig - env vm.VMInterface + env *vm.EVM } // NewJSONLogger creates a new EVM tracer that prints execution steps as JSON objects @@ -49,7 +49,7 @@ func (l *JSONLogger) CaptureTxStart(gasLimit uint64) {} func (l *JSONLogger) CaptureTxEnd(restGas uint64) {} -func (l *JSONLogger) CaptureStart(env vm.VMInterface, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { +func (l *JSONLogger) CaptureStart(env *vm.EVM, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { l.env = env } diff --git a/eth/tracers/native/4byte.go b/eth/tracers/native/4byte.go index 41900f17b16..608f4990b4e 100644 --- a/eth/tracers/native/4byte.go +++ b/eth/tracers/native/4byte.go @@ -81,7 +81,7 @@ func (t *fourByteTracer) store(id []byte, size int) { } // CaptureStart implements the EVMLogger interface to initialize the tracing operation. -func (t *fourByteTracer) CaptureStart(env vm.VMInterface, from libcommon.Address, to libcommon.Address, precompile, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { +func (t *fourByteTracer) CaptureStart(env *vm.EVM, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { // Update list of precompiles based on current block rules := env.ChainConfig().Rules(env.Context().BlockNumber, env.Context().Time) t.activePrecompiles = vm.ActivePrecompiles(rules) diff --git a/eth/tracers/native/call.go b/eth/tracers/native/call.go index 520e953b9bd..0b7c60845bb 100644 --- a/eth/tracers/native/call.go +++ b/eth/tracers/native/call.go @@ -132,7 +132,7 @@ func newCallTracer(ctx *tracers.Context, cfg json.RawMessage) (tracers.Tracer, e } // CaptureStart implements the EVMLogger interface to initialize the tracing operation. -func (t *callTracer) CaptureStart(env vm.VMInterface, from libcommon.Address, to libcommon.Address, precompile, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { +func (t *callTracer) CaptureStart(env *vm.EVM, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { t.callstack[0] = callFrame{ Type: vm.CALL, From: from, diff --git a/eth/tracers/native/mux.go b/eth/tracers/native/mux.go index 77809c64fa7..e8a14bb4ad2 100644 --- a/eth/tracers/native/mux.go +++ b/eth/tracers/native/mux.go @@ -60,7 +60,7 @@ func newMuxTracer(ctx *tracers.Context, cfg json.RawMessage) (tracers.Tracer, er } // CaptureStart implements the EVMLogger interface to initialize the tracing operation. -func (t *muxTracer) CaptureStart(env vm.VMInterface, from libcommon.Address, to libcommon.Address, precompile, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { +func (t *muxTracer) CaptureStart(env *vm.EVM, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { for _, t := range t.tracers { t.CaptureStart(env, from, to, precompile, create, input, gas, value, code) } diff --git a/eth/tracers/native/noop.go b/eth/tracers/native/noop.go index ff04a23a000..29365d00d86 100644 --- a/eth/tracers/native/noop.go +++ b/eth/tracers/native/noop.go @@ -40,7 +40,7 @@ func newNoopTracer(ctx *tracers.Context, _ json.RawMessage) (tracers.Tracer, err } // CaptureStart implements the EVMLogger interface to initialize the tracing operation. -func (t *noopTracer) CaptureStart(env vm.VMInterface, from libcommon.Address, to libcommon.Address, precompile, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { +func (t *noopTracer) CaptureStart(env *vm.EVM, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { } // CaptureEnd is called after the call finishes to finalize the tracing. diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go index 8398af06c9a..1494fb479d0 100644 --- a/eth/tracers/native/prestate.go +++ b/eth/tracers/native/prestate.go @@ -59,7 +59,7 @@ type accountMarshaling struct { type prestateTracer struct { noopTracer - env vm.VMInterface + env *vm.EVM pre state post state create bool @@ -93,7 +93,7 @@ func newPrestateTracer(ctx *tracers.Context, cfg json.RawMessage) (tracers.Trace } // CaptureStart implements the EVMLogger interface to initialize the tracing operation. -func (t *prestateTracer) CaptureStart(env vm.VMInterface, from libcommon.Address, to libcommon.Address, precomplile, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { +func (t *prestateTracer) CaptureStart(env *vm.EVM, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { t.env = env t.create = create t.to = to diff --git a/turbo/jsonrpc/otterscan_default_tracer.go b/turbo/jsonrpc/otterscan_default_tracer.go index 1b312e59b0b..4c8807eb3f5 100644 --- a/turbo/jsonrpc/otterscan_default_tracer.go +++ b/turbo/jsonrpc/otterscan_default_tracer.go @@ -17,7 +17,7 @@ func (t *DefaultTracer) CaptureTxStart(gasLimit uint64) {} func (t *DefaultTracer) CaptureTxEnd(restGas uint64) {} -func (t *DefaultTracer) CaptureStart(env vm.VMInterface, from common.Address, to common.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { +func (t *DefaultTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { } func (t *DefaultTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { diff --git a/turbo/jsonrpc/otterscan_trace_contract_creator.go b/turbo/jsonrpc/otterscan_trace_contract_creator.go index 8d55e3305a2..3f0bb4b6a36 100644 --- a/turbo/jsonrpc/otterscan_trace_contract_creator.go +++ b/turbo/jsonrpc/otterscan_trace_contract_creator.go @@ -50,7 +50,7 @@ func (t *CreateTracer) captureStartOrEnter(from, to common.Address, create bool) t.Creator = from } -func (t *CreateTracer) CaptureStart(env vm.VMInterface, from common.Address, to common.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { +func (t *CreateTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { t.captureStartOrEnter(from, to, create) } diff --git a/turbo/jsonrpc/otterscan_trace_touch.go b/turbo/jsonrpc/otterscan_trace_touch.go index 06c3c2960c4..17fddfdd9ef 100644 --- a/turbo/jsonrpc/otterscan_trace_touch.go +++ b/turbo/jsonrpc/otterscan_trace_touch.go @@ -27,7 +27,7 @@ func (t *TouchTracer) captureStartOrEnter(from, to common.Address) { } } -func (t *TouchTracer) CaptureStart(env vm.VMInterface, from common.Address, to common.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { +func (t *TouchTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { t.captureStartOrEnter(from, to) } diff --git a/turbo/jsonrpc/otterscan_trace_transaction.go b/turbo/jsonrpc/otterscan_trace_transaction.go index 7959871aa22..5c252f05373 100644 --- a/turbo/jsonrpc/otterscan_trace_transaction.go +++ b/turbo/jsonrpc/otterscan_trace_transaction.go @@ -93,7 +93,7 @@ func (t *TransactionTracer) captureStartOrEnter(typ vm.OpCode, from, to common.A } } -func (t *TransactionTracer) CaptureStart(env vm.VMInterface, from common.Address, to common.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { +func (t *TransactionTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { t.depth = 0 t.captureStartOrEnter(vm.CALL, from, to, precompile, input, value) } diff --git a/turbo/jsonrpc/trace_adhoc.go b/turbo/jsonrpc/trace_adhoc.go index b47da577b36..d87097dc6a6 100644 --- a/turbo/jsonrpc/trace_adhoc.go +++ b/turbo/jsonrpc/trace_adhoc.go @@ -353,7 +353,7 @@ func (ot *OeTracer) captureStartOrEnter(deep bool, typ vm.OpCode, from libcommon ot.traceStack = append(ot.traceStack, trace) } -func (ot *OeTracer) CaptureStart(env vm.VMInterface, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { +func (ot *OeTracer) CaptureStart(env *vm.EVM, from libcommon.Address, to libcommon.Address, precompile bool, create bool, input []byte, gas uint64, value *uint256.Int, code []byte) { ot.captureStartOrEnter(false /* deep */, vm.CALL, from, to, precompile, create, input, gas, value, code) } From c4399da0f1ca45a451a563598b993b28011cabb8 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Thu, 5 Oct 2023 13:42:20 +0700 Subject: [PATCH 04/14] evm: no interface on contract creation (#8378) --- core/vm/analysis_test.go | 2 +- core/vm/contract.go | 8 ++++---- core/vm/evm.go | 8 ++++---- core/vm/evm_test.go | 7 ++++--- core/vm/instructions_test.go | 2 +- core/vm/mock_vm.go | 2 +- eth/tracers/js/tracer_test.go | 6 +++--- eth/tracers/logger/logger_test.go | 2 +- 8 files changed, 19 insertions(+), 18 deletions(-) diff --git a/core/vm/analysis_test.go b/core/vm/analysis_test.go index c2265de4659..fba400b69d4 100644 --- a/core/vm/analysis_test.go +++ b/core/vm/analysis_test.go @@ -90,7 +90,7 @@ func BenchmarkJumpDest(b *testing.B) { b.ResetTimer() for n := 0; n < b.N; n++ { - contract := NewContract(contractRef, contractRef, nil, 0, false /* skipAnalysis */) + contract := NewContract(contractRef, libcommon.Address{}, nil, 0, false /* skipAnalysis */) contract.Code = code contract.CodeHash = hash diff --git a/core/vm/contract.go b/core/vm/contract.go index a3225f1517d..7d6d7daa6ba 100644 --- a/core/vm/contract.go +++ b/core/vm/contract.go @@ -46,7 +46,7 @@ type Contract struct { // needs to be initialised to that of the caller's caller. CallerAddress libcommon.Address caller ContractRef - self ContractRef + self libcommon.Address jumpdests map[libcommon.Hash][]uint64 // Aggregated result of JUMPDEST analysis. analysis []uint64 // Locally cached result of JUMPDEST analysis skipAnalysis bool @@ -61,8 +61,8 @@ type Contract struct { } // NewContract returns a new contract environment for the execution of EVM. -func NewContract(caller ContractRef, object ContractRef, value *uint256.Int, gas uint64, skipAnalysis bool) *Contract { - c := &Contract{CallerAddress: caller.Address(), caller: caller, self: object} +func NewContract(caller ContractRef, addr libcommon.Address, value *uint256.Int, gas uint64, skipAnalysis bool) *Contract { + c := &Contract{CallerAddress: caller.Address(), caller: caller, self: addr} if parent, ok := caller.(*Contract); ok { // Reuse JUMPDEST analysis from parent context if available. @@ -176,7 +176,7 @@ func (c *Contract) UseGas(gas uint64) (ok bool) { // Address returns the contracts address func (c *Contract) Address() libcommon.Address { - return c.self.Address() + return c.self } // Value returns the contract's value (sent to it from it's caller) diff --git a/core/vm/evm.go b/core/vm/evm.go index 1c9d18481a6..e48a1b80f30 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -248,11 +248,11 @@ func (evm *EVM) call(typ OpCode, caller ContractRef, addr libcommon.Address, inp codeHash := evm.intraBlockState.GetCodeHash(addrCopy) var contract *Contract if typ == CALLCODE { - contract = NewContract(caller, AccountRef(caller.Address()), value, gas, evm.config.SkipAnalysis) + contract = NewContract(caller, caller.Address(), value, gas, evm.config.SkipAnalysis) } else if typ == DELEGATECALL { - contract = NewContract(caller, AccountRef(caller.Address()), value, gas, evm.config.SkipAnalysis).AsDelegate() + contract = NewContract(caller, caller.Address(), value, gas, evm.config.SkipAnalysis).AsDelegate() } else { - contract = NewContract(caller, AccountRef(addrCopy), value, gas, evm.config.SkipAnalysis) + contract = NewContract(caller, addrCopy, value, gas, evm.config.SkipAnalysis) } contract.SetCallCode(&addrCopy, codeHash, code) readOnly := false @@ -385,7 +385,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, // Initialise a new contract and set the code that is to be used by the EVM. // The contract is a scoped environment for this execution context only. - contract := NewContract(caller, AccountRef(address), value, gas, evm.config.SkipAnalysis) + contract := NewContract(caller, address, value, gas, evm.config.SkipAnalysis) contract.SetCodeOptionalHash(&address, codeAndHash) if evm.config.NoRecursion && depth > 0 { diff --git a/core/vm/evm_test.go b/core/vm/evm_test.go index 286fb9664e8..431be620ed1 100644 --- a/core/vm/evm_test.go +++ b/core/vm/evm_test.go @@ -4,6 +4,7 @@ import ( "fmt" "testing" + libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon/core/vm/evmtypes" "github.com/ledgerwatch/erigon/params" @@ -39,7 +40,7 @@ func TestInterpreterReadonly(t *testing.T) { dummyContract := NewContract( &dummyContractRef{}, - &dummyContractRef{}, + libcommon.Address{}, new(uint256.Int), 0, false, @@ -292,7 +293,7 @@ func TestReadonlyBasicCases(t *testing.T) { dummyContract := NewContract( &dummyContractRef{}, - &dummyContractRef{}, + libcommon.Address{}, new(uint256.Int), 0, false, @@ -384,7 +385,7 @@ func (st *testSequential) Run(_ *Contract, _ []byte, _ bool) ([]byte, error) { nextContract := NewContract( &dummyContractRef{}, - &dummyContractRef{}, + libcommon.Address{}, new(uint256.Int), 0, false, diff --git a/core/vm/instructions_test.go b/core/vm/instructions_test.go index c64b0f34697..cccd8a60031 100644 --- a/core/vm/instructions_test.go +++ b/core/vm/instructions_test.go @@ -583,7 +583,7 @@ func TestOpTstore(t *testing.T) { caller = libcommon.Address{} to = libcommon.Address{1} contractRef = contractRef{caller} - contract = NewContract(contractRef, AccountRef(to), u256.Num0, 0, false) + contract = NewContract(contractRef, to, u256.Num0, 0, false) scopeContext = ScopeContext{mem, stack, contract} value = common.Hex2Bytes("abcdef00000000000000abba000000000deaf000000c0de00100000000133700") ) diff --git a/core/vm/mock_vm.go b/core/vm/mock_vm.go index f2a99b66f0a..de0a632f454 100644 --- a/core/vm/mock_vm.go +++ b/core/vm/mock_vm.go @@ -51,7 +51,7 @@ func (evm *testVM) Run(_ *Contract, _ []byte, readOnly bool) (ret []byte, err er if *evm.currentIdx < len(evm.readOnlySliceTest) { res, err := run(evm.env, NewContract( &dummyContractRef{}, - &dummyContractRef{}, + libcommon.Address{}, new(uint256.Int), 0, false, diff --git a/eth/tracers/js/tracer_test.go b/eth/tracers/js/tracer_test.go index 32251acc700..080230f7cc0 100644 --- a/eth/tracers/js/tracer_test.go +++ b/eth/tracers/js/tracer_test.go @@ -70,7 +70,7 @@ func runTrace(tracer tracers.Tracer, vmctx *vmContext, chaincfg *chain.Config, c gasLimit uint64 = 31000 startGas uint64 = 10000 value = uint256.NewInt(0) - contract = vm.NewContract(account{}, account{}, value, startGas, false /* skipAnalysis */) + contract = vm.NewContract(account{}, libcommon.Address{}, value, startGas, false /* skipAnalysis */) ) contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x1, 0x0} if contractCode != nil { @@ -186,7 +186,7 @@ func TestHaltBetweenSteps(t *testing.T) { } env := vm.NewEVM(evmtypes.BlockContext{BlockNumber: 1}, evmtypes.TxContext{GasPrice: uint256.NewInt(1)}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Debug: true, Tracer: tracer}) scope := &vm.ScopeContext{ - Contract: vm.NewContract(&account{}, &account{}, uint256.NewInt(0), 0, false /* skipAnalysis */), + Contract: vm.NewContract(&account{}, libcommon.Address{}, uint256.NewInt(0), 0, false /* skipAnalysis */), } tracer.CaptureStart(env, libcommon.Address{}, libcommon.Address{}, false /* precompile */, false /* create */, []byte{}, 0, uint256.NewInt(0), []byte{} /* code */) tracer.CaptureState(0, 0, 0, 0, scope, nil, 0, nil) @@ -277,7 +277,7 @@ func TestEnterExit(t *testing.T) { t.Fatal(err) } scope := &vm.ScopeContext{ - Contract: vm.NewContract(&account{}, &account{}, uint256.NewInt(0), 0, false /* skipAnalysis */), + Contract: vm.NewContract(&account{}, libcommon.Address{}, uint256.NewInt(0), 0, false /* skipAnalysis */), } tracer.CaptureEnter(vm.CALL, scope.Contract.Caller(), scope.Contract.Address(), false, false, []byte{}, 1000, new(uint256.Int), []byte{}) tracer.CaptureExit([]byte{}, 400, nil) diff --git a/eth/tracers/logger/logger_test.go b/eth/tracers/logger/logger_test.go index 730b5fbca57..b4b41213754 100644 --- a/eth/tracers/logger/logger_test.go +++ b/eth/tracers/logger/logger_test.go @@ -60,7 +60,7 @@ func TestStoreCapture(t *testing.T) { logger = NewStructLogger(nil) mem = vm.NewMemory() stack = stack.New() - contract = vm.NewContract(&dummyContractRef{}, &dummyContractRef{}, new(uint256.Int), 0, false /* skipAnalysis */) + contract = vm.NewContract(&dummyContractRef{}, libcommon.Address{}, new(uint256.Int), 0, false /* skipAnalysis */) ) stack.Push(uint256.NewInt(1)) stack.Push(uint256.NewInt(0)) From 8850f3a76d50f7d1b1e088a8f106116e49a2c460 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Thu, 5 Oct 2023 13:42:30 +0700 Subject: [PATCH 05/14] memstat: to use helper func (#8377) --- turbo/app/snapshots_cmd.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/turbo/app/snapshots_cmd.go b/turbo/app/snapshots_cmd.go index 7c7f557cc66..968ece0c4fc 100644 --- a/turbo/app/snapshots_cmd.go +++ b/turbo/app/snapshots_cmd.go @@ -13,6 +13,7 @@ import ( "time" "github.com/c2h5oh/datasize" + "github.com/ledgerwatch/erigon-lib/common/dbg" "github.com/ledgerwatch/log/v3" "github.com/urfave/cli/v2" @@ -220,8 +221,7 @@ func doRam(cliCtx *cli.Context) error { } f := args.First() var m runtime.MemStats - runtime.ReadMemStats(&m) - runtime.ReadMemStats(&m) + dbg.ReadMemStats(&m) before := m.Alloc logger.Info("RAM before open", "alloc", common.ByteCount(m.Alloc), "sys", common.ByteCount(m.Sys)) decompressor, err := compress.NewDecompressor(f) @@ -229,7 +229,7 @@ func doRam(cliCtx *cli.Context) error { return err } defer decompressor.Close() - runtime.ReadMemStats(&m) + dbg.ReadMemStats(&m) logger.Info("RAM after open", "alloc", common.ByteCount(m.Alloc), "sys", common.ByteCount(m.Sys), "diff", common.ByteCount(m.Alloc-before)) return nil } From 7dd678896ae68fcadb996f07b6146cae6fab8a85 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Thu, 5 Oct 2023 14:25:00 +0700 Subject: [PATCH 06/14] downloader: move from `snapshots/db` to `snapshots/downloader` (#8375) --- cmd/downloader/main.go | 28 +++++++++---- cmd/erigon/main.go | 5 +++ cmd/integration/commands/stages.go | 9 ++++ cmd/integration/commands/state_stages.go | 4 ++ erigon-lib/common/datadir/dirs.go | 52 ++++++++++-------------- erigon-lib/downloader/downloader.go | 2 + node/node.go | 5 ++- 7 files changed, 63 insertions(+), 42 deletions(-) diff --git a/cmd/downloader/main.go b/cmd/downloader/main.go index a437b53c65e..4e88f436c13 100644 --- a/cmd/downloader/main.go +++ b/cmd/downloader/main.go @@ -11,23 +11,21 @@ import ( "strings" "time" - "github.com/ledgerwatch/erigon-lib/common/dir" - "github.com/ledgerwatch/erigon-lib/downloader/snaptype" - "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/erigon-lib/kv/mdbx" - "github.com/ledgerwatch/erigon/cmd/hack/tool" - "github.com/ledgerwatch/erigon/turbo/snapshotsync/snapcfg" - "github.com/pelletier/go-toml/v2" - "github.com/c2h5oh/datasize" + mdbx2 "github.com/erigontech/mdbx-go/mdbx" grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" grpc_recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery" "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/datadir" + "github.com/ledgerwatch/erigon-lib/common/dir" "github.com/ledgerwatch/erigon-lib/downloader" downloadercfg2 "github.com/ledgerwatch/erigon-lib/downloader/downloadercfg" + "github.com/ledgerwatch/erigon-lib/downloader/snaptype" proto_downloader "github.com/ledgerwatch/erigon-lib/gointerfaces/downloader" + "github.com/ledgerwatch/erigon-lib/kv" + "github.com/ledgerwatch/erigon-lib/kv/mdbx" "github.com/ledgerwatch/log/v3" + "github.com/pelletier/go-toml/v2" "github.com/spf13/cobra" "google.golang.org/grpc" "google.golang.org/grpc/credentials" @@ -37,12 +35,14 @@ import ( "google.golang.org/grpc/reflection" "github.com/ledgerwatch/erigon/cmd/downloader/downloadernat" + "github.com/ledgerwatch/erigon/cmd/hack/tool" "github.com/ledgerwatch/erigon/cmd/utils" "github.com/ledgerwatch/erigon/common/paths" "github.com/ledgerwatch/erigon/p2p/nat" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/turbo/debug" "github.com/ledgerwatch/erigon/turbo/logging" + "github.com/ledgerwatch/erigon/turbo/snapshotsync/snapcfg" ) func main() { @@ -146,6 +146,9 @@ var rootCmd = &cobra.Command{ func Downloader(ctx context.Context, logger log.Logger) error { dirs := datadir.New(datadirCli) + if err := datadir.ApplyMigrations(dirs); err != nil { + return err + } if err := checkChainName(dirs, chain); err != nil { return err } @@ -243,6 +246,10 @@ var printTorrentHashes = &cobra.Command{ func doPrintTorrentHashes(ctx context.Context, logger log.Logger) error { dirs := datadir.New(datadirCli) + if err := datadir.ApplyMigrations(dirs); err != nil { + return err + } + if forceRebuild { // remove and create .torrent files (will re-read all snapshots) //removePieceCompletionStorage(snapDir) files, err := downloader.AllTorrentPaths(dirs) @@ -371,7 +378,10 @@ func checkChainName(dirs datadir.Dirs, chainName string) error { if !dir.FileExist(filepath.Join(dirs.Chaindata, "mdbx.dat")) { return nil } - db := mdbx.NewMDBX(log.New()).Path(dirs.Chaindata).Label(kv.ChainDB).MustOpen() + db := mdbx.NewMDBX(log.New()). + Path(dirs.Chaindata).Label(kv.ChainDB). + Flags(func(flags uint) uint { return flags | mdbx2.Accede }). + MustOpen() defer db.Close() if err := db.View(context.Background(), func(tx kv.Tx) error { cc := tool.ChainConfig(tx) diff --git a/cmd/erigon/main.go b/cmd/erigon/main.go index 135d72c766e..24022e8d652 100644 --- a/cmd/erigon/main.go +++ b/cmd/erigon/main.go @@ -9,6 +9,7 @@ import ( "reflect" "strings" + "github.com/ledgerwatch/erigon-lib/common/datadir" "github.com/ledgerwatch/erigon-lib/common/dbg" "github.com/ledgerwatch/erigon/diagnostics" "github.com/ledgerwatch/erigon/metrics" @@ -70,6 +71,10 @@ func runErigon(cliCtx *cli.Context) error { erigonInfoGauge.Set(1) nodeCfg := node.NewNodConfigUrfave(cliCtx, logger) + if err := datadir.ApplyMigrations(nodeCfg.Dirs); err != nil { + return err + } + ethCfg := node.NewEthConfigUrfave(cliCtx, nodeCfg, logger) ethNode, err := node.New(cliCtx.Context, nodeCfg, ethCfg, logger) diff --git a/cmd/integration/commands/stages.go b/cmd/integration/commands/stages.go index 70855cb1f93..218e3ce4910 100644 --- a/cmd/integration/commands/stages.go +++ b/cmd/integration/commands/stages.go @@ -634,6 +634,11 @@ func stageSnapshots(db kv.RwDB, ctx context.Context, logger log.Logger) error { } func stageHeaders(db kv.RwDB, ctx context.Context, logger log.Logger) error { + dirs := datadir.New(datadirCli) + if err := datadir.ApplyMigrations(dirs); err != nil { + return err + } + sn, borSn, agg := allSnapshots(ctx, db, logger) defer sn.Close() defer borSn.Close() @@ -852,6 +857,10 @@ func stageSenders(db kv.RwDB, ctx context.Context, logger log.Logger) error { func stageExec(db kv.RwDB, ctx context.Context, logger log.Logger) error { dirs := datadir.New(datadirCli) + if err := datadir.ApplyMigrations(dirs); err != nil { + return err + } + engine, vmConfig, sync, _, _ := newSync(ctx, db, nil /* miningConfig */, logger) must(sync.SetCurrentStage(stages.Execution)) sn, borSn, agg := allSnapshots(ctx, db, logger) diff --git a/cmd/integration/commands/state_stages.go b/cmd/integration/commands/state_stages.go index 650b5985d0f..26683685081 100644 --- a/cmd/integration/commands/state_stages.go +++ b/cmd/integration/commands/state_stages.go @@ -169,6 +169,10 @@ func init() { func syncBySmallSteps(db kv.RwDB, miningConfig params.MiningConfig, ctx context.Context, logger1 log.Logger) error { dirs := datadir.New(datadirCli) + if err := datadir.ApplyMigrations(dirs); err != nil { + return err + } + sn, borSn, agg := allSnapshots(ctx, db, logger1) defer sn.Close() defer borSn.Close() diff --git a/erigon-lib/common/datadir/dirs.go b/erigon-lib/common/datadir/dirs.go index 736dea55910..85c10b063ed 100644 --- a/erigon-lib/common/datadir/dirs.go +++ b/erigon-lib/common/datadir/dirs.go @@ -67,7 +67,7 @@ func New(datadir string) Dirs { SnapHistory: filepath.Join(datadir, "snapshots", "history"), SnapDomain: filepath.Join(datadir, "snapshots", "domain"), SnapAccessors: filepath.Join(datadir, "snapshots", "accessor"), - Downloader: filepath.Join(datadir, "snapshots", "db"), + Downloader: filepath.Join(datadir, "downloader"), TxPool: filepath.Join(datadir, "txpool"), Nodes: filepath.Join(datadir, "nodes"), } @@ -91,7 +91,7 @@ func convertFileLockError(err error) error { return err } -func Flock(dirs Dirs) (*flock.Flock, bool, error) { +func TryFlock(dirs Dirs) (*flock.Flock, bool, error) { // Lock the instance directory to prevent concurrent use by another instance as well as // accidental use of the instance directory as a database. l := flock.New(filepath.Join(dirs.DataDir, "LOCK")) @@ -104,7 +104,12 @@ func Flock(dirs Dirs) (*flock.Flock, bool, error) { // ApplyMigrations - if can get flock. func ApplyMigrations(dirs Dirs) error { - lock, locked, err := Flock(dirs) + need := downloaderV2MigrationNeeded(dirs) + if !need { + return nil + } + + lock, locked, err := TryFlock(dirs) if err != nil { return err } @@ -113,43 +118,28 @@ func ApplyMigrations(dirs Dirs) error { } defer lock.Unlock() + // add your migration here + if err := downloaderV2Migration(dirs); err != nil { return err } - //if err := erigonV3foldersV31Migration(dirs); err != nil { - // return err - //} return nil } +func downloaderV2MigrationNeeded(dirs Dirs) bool { + return dir.FileExist(filepath.Join(dirs.Snap, "db", "mdbx.dat")) +} func downloaderV2Migration(dirs Dirs) error { // move db from `datadir/snapshot/db` to `datadir/downloader` - if dir.Exist(filepath.Join(dirs.Snap, "db", "mdbx.dat")) { // migration from prev versions - from, to := filepath.Join(dirs.Snap, "db", "mdbx.dat"), filepath.Join(dirs.Downloader, "mdbx.dat") - if err := os.Rename(from, to); err != nil { - //fall back to copy-file if folders are on different disks - if err := copyFile(from, to); err != nil { - return err - } - } + if !downloaderV2MigrationNeeded(dirs) { + return nil } - return nil -} - -// nolint -func erigonV3foldersV31Migration(dirs Dirs) error { - // migrate files db from `datadir/snapshot/warm` to `datadir/snapshots/domain` - if dir.Exist(filepath.Join(dirs.Snap, "warm")) { - warmDir := filepath.Join(dirs.Snap, "warm") - moveFiles(warmDir, dirs.SnapDomain, ".kv") - os.Rename(filepath.Join(dirs.SnapHistory, "salt.txt"), filepath.Join(dirs.Snap, "salt.txt")) - moveFiles(warmDir, dirs.SnapDomain, ".kv") - moveFiles(warmDir, dirs.SnapDomain, ".kvei") - moveFiles(warmDir, dirs.SnapDomain, ".bt") - moveFiles(dirs.SnapHistory, dirs.SnapAccessors, ".vi") - moveFiles(dirs.SnapHistory, dirs.SnapAccessors, ".efi") - moveFiles(dirs.SnapHistory, dirs.SnapAccessors, ".efei") - moveFiles(dirs.SnapHistory, dirs.SnapIdx, ".ef") + from, to := filepath.Join(dirs.Snap, "db", "mdbx.dat"), filepath.Join(dirs.Downloader, "mdbx.dat") + if err := os.Rename(from, to); err != nil { + //fall back to copy-file if folders are on different disks + if err := copyFile(from, to); err != nil { + return err + } } return nil } diff --git a/erigon-lib/downloader/downloader.go b/erigon-lib/downloader/downloader.go index e9989a961eb..0d0828f5cc9 100644 --- a/erigon-lib/downloader/downloader.go +++ b/erigon-lib/downloader/downloader.go @@ -29,6 +29,7 @@ import ( "github.com/anacrolix/torrent" "github.com/anacrolix/torrent/metainfo" "github.com/anacrolix/torrent/storage" + "github.com/c2h5oh/datasize" "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/datadir" "github.com/ledgerwatch/erigon-lib/common/dbg" @@ -634,6 +635,7 @@ func openClient(dbDir, snapDir string, cfg *torrent.ClientConfig) (db kv.RwDB, c Label(kv.DownloaderDB). WithTableCfg(func(defaultBuckets kv.TableCfg) kv.TableCfg { return kv.DownloaderTablesCfg }). SyncPeriod(15 * time.Second). + GrowthStep(16 * datasize.MB). Path(dbDir). Open() if err != nil { diff --git a/node/node.go b/node/node.go index 04a5dbbb7ce..2b313f2e31c 100644 --- a/node/node.go +++ b/node/node.go @@ -234,7 +234,7 @@ func (n *Node) openDataDir(ctx context.Context) error { return err } for retry := 0; ; retry++ { - l, locked, err := datadir.Flock(n.config.Dirs) + l, locked, err := datadir.TryFlock(n.config.Dirs) if err != nil { return err } @@ -324,8 +324,9 @@ func OpenDatabase(config *nodecfg.Config, label kv.Label, name string, readonly roTxLimit = int64(config.Http.DBReadConcurrency) } roTxsLimiter := semaphore.NewWeighted(roTxLimit) // 1 less than max to allow unlocking to happen - opts := mdbx.NewMDBX(log.Root()). + opts := mdbx.NewMDBX(logger). Path(dbPath).Label(label). + GrowthStep(16 * datasize.MB). DBVerbosity(config.DatabaseVerbosity).RoTxsLimiter(roTxsLimiter) if readonly { From c6f532d68e0158dbea736085d66ab210b1bcfcaf Mon Sep 17 00:00:00 2001 From: Anshal Shukla <53994948+anshalshukla@users.noreply.github.com> Date: Thu, 5 Oct 2023 14:42:47 +0530 Subject: [PATCH 07/14] Rewind fixes (#8380) --- eth/stagedsync/stage_bor_heimdall.go | 35 +++++++++++++++------------- turbo/rpchelper/helper.go | 3 ++- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/eth/stagedsync/stage_bor_heimdall.go b/eth/stagedsync/stage_bor_heimdall.go index e04ba9204f2..c0d4c57c1a3 100644 --- a/eth/stagedsync/stage_bor_heimdall.go +++ b/eth/stagedsync/stage_bor_heimdall.go @@ -103,24 +103,25 @@ func BorHeimdallForward( if generics.BorMilestoneRewind.Load() != nil && *generics.BorMilestoneRewind.Load() != 0 { // TODO set the hash and the headNumber to the milestone fork point - s.state.UnwindTo(*generics.BorMilestoneRewind.Load(), hash) + unwindPoint := *generics.BorMilestoneRewind.Load() + var reset uint64 = 0 + generics.BorMilestoneRewind.Store(&reset) + s.state.UnwindTo(unwindPoint, hash) - if s.BlockNumber > headNumber { - for blockNum := headNumber; blockNum > s.BlockNumber; blockNum++ { + if unwindPoint < headNumber { + for blockNum := unwindPoint + 1; blockNum <= headNumber; blockNum++ { if header, err = cfg.blockReader.HeaderByNumber(ctx, tx, blockNum); err == nil { logger.Debug("[BorHeimdall] Verification failed for header", "hash", header.Hash(), "height", blockNum) cfg.penalize(ctx, []headerdownload.PenaltyItem{ {Penalty: headerdownload.BadBlockPenalty, PeerID: cfg.hd.SourcePeerId(header.Hash())}}) - dataflow.HeaderDownloadStates.AddChange(blockNum, dataflow.HeaderEvicted) + dataflow.HeaderDownloadStates.AddChange(blockNum, dataflow.HeaderInvalidated) } } + return fmt.Errorf("milestone block mismatch at %d", headNumber) + } else { + return } - var reset uint64 = 0 - generics.BorMilestoneRewind.Store(&reset) - - return fmt.Errorf("milestone block mismatch at %d", headNumber) - /* This is the code from the original PR - it has been removed in favour of having the outer stage loop perform the unwind which is the standard erigon operating model @@ -142,14 +143,16 @@ func BorHeimdallForward( } if mine { - header = cfg.miningState.MiningBlock.Header + minedHeader := cfg.miningState.MiningBlock.Header - if minedHeadNumber := header.Number.Uint64(); minedHeadNumber > headNumber { + if minedHeadNumber := minedHeader.Number.Uint64(); minedHeadNumber > headNumber { // Whitelist service is called to check if the bor chain is // on the cannonical chain according to milestones - if !service.IsValidChain(headNumber, []*types.Header{header}) { - logger.Debug("[BorHeimdall] Verification failed for mined header", "hash", header.Hash(), "height", minedHeadNumber, "err", err) + if !service.IsValidChain(minedHeadNumber, []*types.Header{minedHeader}) { + logger.Debug("[BorHeimdall] Verification failed for mined header", "hash", minedHeader.Hash(), "height", minedHeadNumber, "err", err) + dataflow.HeaderDownloadStates.AddChange(minedHeadNumber, dataflow.HeaderInvalidated) + s.state.UnwindTo(minedHeadNumber-1, minedHeader.Hash()) return err } } else { @@ -202,18 +205,18 @@ func BorHeimdallForward( // Whitelist service is called to check if the bor chain is // on the cannonical chain according to milestones if service != nil { - if !service.IsValidChain(headNumber, []*types.Header{header}) { + if !service.IsValidChain(blockNum, []*types.Header{header}) { logger.Debug("[BorHeimdall] Verification failed for header", "height", blockNum, "hash", header.Hash()) cfg.penalize(ctx, []headerdownload.PenaltyItem{ {Penalty: headerdownload.BadBlockPenalty, PeerID: cfg.hd.SourcePeerId(header.Hash())}}) - dataflow.HeaderDownloadStates.AddChange(blockNum, dataflow.HeaderEvicted) + dataflow.HeaderDownloadStates.AddChange(blockNum, dataflow.HeaderInvalidated) + s.state.UnwindTo(blockNum-1, header.Hash()) return fmt.Errorf("verification failed for header %d: %x", blockNum, header.Hash()) } } } if blockNum%cfg.chainConfig.Bor.CalculateSprint(blockNum) == 0 { - if lastEventId, err = fetchAndWriteBorEvents(ctx, cfg.blockReader, cfg.chainConfig.Bor, header, lastEventId, cfg.chainConfig.ChainID.String(), tx, cfg.heimdallClient, cfg.stateReceiverABI, s.LogPrefix(), logger); err != nil { return err } diff --git a/turbo/rpchelper/helper.go b/turbo/rpchelper/helper.go index b5cc1e62a34..1b97a6ea16d 100644 --- a/turbo/rpchelper/helper.go +++ b/turbo/rpchelper/helper.go @@ -58,7 +58,8 @@ func _GetBlockNumber(requireCanonical bool, blockNrOrHash rpc.BlockNumberOrHash, if whitelist.GetWhitelistingService() != nil { num := borfinality.GetFinalizedBlockNumber(tx) if num == 0 { - return 0, libcommon.Hash{}, false, errors.New("no finalized block") + // nolint + return 0, libcommon.Hash{}, false, errors.New("No finalized block") } blockNum := borfinality.CurrentFinalizedBlock(tx, num).NumberU64() From c27825d47b82801e37fcb43089692df4e12a6321 Mon Sep 17 00:00:00 2001 From: Somnath Date: Thu, 5 Oct 2023 15:29:16 +0530 Subject: [PATCH 08/14] Remove protocolBaseFee checks (#8367) As per [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) , there is only initial base fee after which it adjusts automatically. There are no current references to a minimum protocol base fee on Ethereum, Gnosis or Polygon. The existing code would put a 7 wei minimum limit on transactions to be included in the pool. This PR removes this check within txPool. Any transaction can now be added to the `queued` sub-pool after which it could get promoted to `pending` or `baseFee` subpools. The`pricelimit` flag still exists and acts on non-local transactions as a minimum feeCap for inclusion. --- erigon-lib/txpool/pool.go | 65 +++++++++-------------------- erigon-lib/txpool/pool_fuzz_test.go | 9 ---- 2 files changed, 19 insertions(+), 55 deletions(-) diff --git a/erigon-lib/txpool/pool.go b/erigon-lib/txpool/pool.go index bbb3758bd5a..e71267525f9 100644 --- a/erigon-lib/txpool/pool.go +++ b/erigon-lib/txpool/pool.go @@ -96,25 +96,22 @@ type Pool interface { var _ Pool = (*TxPool)(nil) // compile-time interface check -// SubPoolMarker is an ordered bitset of six bits that's used to sort transactions into sub-pools. Bits meaning: -// 1. Minimum fee requirement. Set to 1 if feeCap of the transaction is no less than in-protocol parameter of minimal base fee. Set to 0 if feeCap is less than minimum base fee, which means this transaction will never be included into this particular chain. -// 2. Absence of nonce gaps. Set to 1 for transactions whose nonce is N, state nonce for the sender is M, and there are transactions for all nonces between M and N from the same sender. Set to 0 is the transaction's nonce is divided from the state nonce by one or more nonce gaps. -// 3. Sufficient balance for gas. Set to 1 if the balance of sender's account in the state is B, nonce of the sender in the state is M, nonce of the transaction is N, and the sum of feeCap x gasLimit + transferred_value of all transactions from this sender with nonces N+1 ... M is no more than B. Set to 0 otherwise. In other words, this bit is set if there is currently a guarantee that the transaction and all its required prior transactions will be able to pay for gas. -// 4. Not too much gas: Set to 1 if the transaction doesn't use too much gas -// 5. Dynamic fee requirement. Set to 1 if feeCap of the transaction is no less than baseFee of the currently pending block. Set to 0 otherwise. -// 6. Local transaction. Set to 1 if transaction is local. +// SubPoolMarker is an ordered bitset of five bits that's used to sort transactions into sub-pools. Bits meaning: +// 1. Absence of nonce gaps. Set to 1 for transactions whose nonce is N, state nonce for the sender is M, and there are transactions for all nonces between M and N from the same sender. Set to 0 is the transaction's nonce is divided from the state nonce by one or more nonce gaps. +// 2. Sufficient balance for gas. Set to 1 if the balance of sender's account in the state is B, nonce of the sender in the state is M, nonce of the transaction is N, and the sum of feeCap x gasLimit + transferred_value of all transactions from this sender with nonces N+1 ... M is no more than B. Set to 0 otherwise. In other words, this bit is set if there is currently a guarantee that the transaction and all its required prior transactions will be able to pay for gas. +// 3. Not too much gas: Set to 1 if the transaction doesn't use too much gas +// 4. Dynamic fee requirement. Set to 1 if feeCap of the transaction is no less than baseFee of the currently pending block. Set to 0 otherwise. +// 5. Local transaction. Set to 1 if transaction is local. type SubPoolMarker uint8 const ( - EnoughFeeCapProtocol = 0b100000 - NoNonceGaps = 0b010000 - EnoughBalance = 0b001000 - NotTooMuchGas = 0b000100 - EnoughFeeCapBlock = 0b000010 - IsLocal = 0b000001 - - BaseFeePoolBits = EnoughFeeCapProtocol + NoNonceGaps + EnoughBalance + NotTooMuchGas - QueuedPoolBits = EnoughFeeCapProtocol + NoNonceGaps = 0b010000 + EnoughBalance = 0b001000 + NotTooMuchGas = 0b000100 + EnoughFeeCapBlock = 0b000010 + IsLocal = 0b000001 + + BaseFeePoolBits = NoNonceGaps + EnoughBalance + NotTooMuchGas ) // metaTx holds transaction and some metadata @@ -178,10 +175,6 @@ func SortByNonceLess(a, b *metaTx) bool { return a.Tx.Nonce < b.Tx.Nonce } -func calcProtocolBaseFee(baseFee uint64) uint64 { - return 7 -} - // TxPool - holds all pool-related data structures and lock-based tiny methods // most of logic implemented by pure tests-friendly functions // @@ -1087,7 +1080,6 @@ func addTxs(blockNum uint64, cacheView kvcache.CacheView, senders *sendersBatch, pending *PendingPool, baseFee, queued *SubPool, byNonce *BySenderAndNonce, byHash map[string]*metaTx, add func(*metaTx, *types.Announcements) txpoolcfg.DiscardReason, discard func(*metaTx, txpoolcfg.DiscardReason), collect bool, logger log.Logger) (types.Announcements, []txpoolcfg.DiscardReason, error) { - protocolBaseFee := calcProtocolBaseFee(pendingBaseFee) if assert.Enable { for _, txn := range newTxs.Txs { if txn.SenderID == 0 { @@ -1134,7 +1126,7 @@ func addTxs(blockNum uint64, cacheView kvcache.CacheView, senders *sendersBatch, return announcements, discardReasons, err } onSenderStateChange(senderID, nonce, balance, byNonce, - protocolBaseFee, blockGasLimit, pending, baseFee, queued, discard, logger) + blockGasLimit, pending, baseFee, queued, discard, logger) } promote(pending, baseFee, queued, pendingBaseFee, pendingBlobFee, discard, &announcements, logger) @@ -1149,7 +1141,6 @@ func addTxsOnNewBlock(blockNum uint64, cacheView kvcache.CacheView, stateChanges pending *PendingPool, baseFee, queued *SubPool, byNonce *BySenderAndNonce, byHash map[string]*metaTx, add func(*metaTx, *types.Announcements) txpoolcfg.DiscardReason, discard func(*metaTx, txpoolcfg.DiscardReason), logger log.Logger) (types.Announcements, error) { - protocolBaseFee := calcProtocolBaseFee(pendingBaseFee) if assert.Enable { for _, txn := range newTxs.Txs { if txn.SenderID == 0 { @@ -1203,7 +1194,7 @@ func addTxsOnNewBlock(blockNum uint64, cacheView kvcache.CacheView, stateChanges return announcements, err } onSenderStateChange(senderID, nonce, balance, byNonce, - protocolBaseFee, blockGasLimit, pending, baseFee, queued, discard, logger) + blockGasLimit, pending, baseFee, queued, discard, logger) } return announcements, nil @@ -1427,7 +1418,7 @@ func removeMined(byNonce *BySenderAndNonce, minedTxs []*types.TxSlot, pending *P // nonces, and also affect other transactions from the same sender with higher nonce, it loops through all transactions // for a given senderID func onSenderStateChange(senderID uint64, senderNonce uint64, senderBalance uint256.Int, byNonce *BySenderAndNonce, - protocolBaseFee, blockGasLimit uint64, pending *PendingPool, baseFee, queued *SubPool, discard func(*metaTx, txpoolcfg.DiscardReason), logger log.Logger) { + blockGasLimit uint64, pending *PendingPool, baseFee, queued *SubPool, discard func(*metaTx, txpoolcfg.DiscardReason), logger log.Logger) { noGapsNonce := senderNonce cumulativeRequiredBalance := uint256.NewInt(0) minFeeCap := uint256.NewInt(0).SetAllOne() @@ -1477,16 +1468,6 @@ func onSenderStateChange(senderID uint64, senderNonce uint64, senderBalance uint } needBalance := requiredBalance(mt.Tx) - // 1. Minimum fee requirement. Set to 1 if feeCap of the transaction is no less than in-protocol - // parameter of minimal base fee. Set to 0 if feeCap is less than minimum base fee, which means - // this transaction will never be included into this particular chain. - mt.subPool &^= EnoughFeeCapProtocol - if mt.minFeeCap.Cmp(uint256.NewInt(protocolBaseFee)) >= 0 { - mt.subPool |= EnoughFeeCapProtocol - } else { - mt.subPool = 0 // TODO: we immediately drop all transactions if they have no first bit - then maybe we don't need this bit at all? And don't add such transactions to queue? - return true - } // 2. Absence of nonce gaps. Set to 1 for transactions whose nonce is N, state nonce for // the sender is M, and there are transactions for all nonces between M and N from the same @@ -1551,10 +1532,8 @@ func promote(pending *PendingPool, baseFee, queued *SubPool, pendingBaseFee uint tx := pending.PopWorst() announcements.Append(tx.Tx.Type, tx.Tx.Size, tx.Tx.IDHash[:]) baseFee.Add(tx, logger) - } else if worst.subPool >= QueuedPoolBits { - queued.Add(pending.PopWorst(), logger) } else { - discard(pending.PopWorst(), txpoolcfg.FeeTooLow) + queued.Add(pending.PopWorst(), logger) } } @@ -1567,11 +1546,7 @@ func promote(pending *PendingPool, baseFee, queued *SubPool, pendingBaseFee uint // Demote worst transactions that do not qualify for base fee pool anymore, to queued sub pool, or discard for worst := baseFee.Worst(); baseFee.Len() > 0 && worst.subPool < BaseFeePoolBits; worst = baseFee.Worst() { - if worst.subPool >= QueuedPoolBits { - queued.Add(baseFee.PopWorst(), logger) - } else { - discard(baseFee.PopWorst(), txpoolcfg.FeeTooLow) - } + queued.Add(baseFee.PopWorst(), logger) } // Promote best transactions from the queued pool to either pending or base fee pool, while they qualify @@ -1586,9 +1561,7 @@ func promote(pending *PendingPool, baseFee, queued *SubPool, pendingBaseFee uint } // Discard worst transactions from the queued sub pool if they do not qualify - for worst := queued.Worst(); queued.Len() > 0 && worst.subPool < QueuedPoolBits; worst = queued.Worst() { - discard(queued.PopWorst(), txpoolcfg.FeeTooLow) - } + // // Discard worst transactions from pending pool until it is within capacity limit for pending.Len() > pending.limit { diff --git a/erigon-lib/txpool/pool_fuzz_test.go b/erigon-lib/txpool/pool_fuzz_test.go index 967afbadcd5..5c5c7021f55 100644 --- a/erigon-lib/txpool/pool_fuzz_test.go +++ b/erigon-lib/txpool/pool_fuzz_test.go @@ -334,9 +334,6 @@ func FuzzOnNewBlocks(f *testing.F) { if tx.subPool&NoNonceGaps > 0 { assert.GreaterOrEqual(i.Nonce, senders[i.SenderID].nonce, msg, i.SenderID) } - if tx.subPool&EnoughFeeCapProtocol > 0 { - assert.LessOrEqual(calcProtocolBaseFee(pendingBaseFee), tx.Tx.FeeCap, msg) - } if tx.subPool&EnoughFeeCapBlock > 0 { assert.LessOrEqual(pendingBaseFee, tx.Tx.FeeCap, msg) } @@ -370,9 +367,6 @@ func FuzzOnNewBlocks(f *testing.F) { if tx.subPool&NoNonceGaps > 0 { assert.GreaterOrEqual(i.Nonce, senders[i.SenderID].nonce, msg) } - if tx.subPool&EnoughFeeCapProtocol > 0 { - assert.LessOrEqual(calcProtocolBaseFee(pendingBaseFee), tx.Tx.FeeCap, msg) - } if tx.subPool&EnoughFeeCapBlock > 0 { assert.LessOrEqual(pendingBaseFee, tx.Tx.FeeCap, msg) } @@ -391,9 +385,6 @@ func FuzzOnNewBlocks(f *testing.F) { if tx.subPool&NoNonceGaps > 0 { assert.GreaterOrEqual(i.Nonce, senders[i.SenderID].nonce, msg, i.SenderID, senders[i.SenderID].nonce) } - if tx.subPool&EnoughFeeCapProtocol > 0 { - assert.LessOrEqual(calcProtocolBaseFee(pendingBaseFee), tx.Tx.FeeCap, msg) - } if tx.subPool&EnoughFeeCapBlock > 0 { assert.LessOrEqual(pendingBaseFee, tx.Tx.FeeCap, msg) } From 417e316ed5ce5851f90678fa8ef283b9cf1ccd2e Mon Sep 17 00:00:00 2001 From: Somnath Date: Thu, 5 Oct 2023 18:02:43 +0530 Subject: [PATCH 09/14] Small log fix (#8382) --- turbo/engineapi/engine_block_downloader/core.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/turbo/engineapi/engine_block_downloader/core.go b/turbo/engineapi/engine_block_downloader/core.go index f0965787d0b..b2b1d5e0143 100644 --- a/turbo/engineapi/engine_block_downloader/core.go +++ b/turbo/engineapi/engine_block_downloader/core.go @@ -32,7 +32,7 @@ func (e *EngineBlockDownloader) download(hashToDownload libcommon.Hash, download tx, err := e.db.BeginRo(e.ctx) if err != nil { - e.logger.Warn("[EngineBlockDownloader] Could not begin tx: %s", err) + e.logger.Warn("[EngineBlockDownloader] Could not begin tx", "err", err) e.status.Store(headerdownload.Idle) return } From 0bd6d77acd3c527079586f6ff3c6c235a7f2ef23 Mon Sep 17 00:00:00 2001 From: Andrew Ashikhmin <34320705+yperbasis@users.noreply.github.com> Date: Thu, 5 Oct 2023 15:39:57 +0200 Subject: [PATCH 10/14] Remove CalcuttaBlock in favour of BlockAlloc (#8371) System contract upgrades for Polygon are already handled by the `BlockAlloc` logic and there's no need to duplicate it with the `CalcuttaBlock` logic (there's no Calcutta in https://github.com/maticnetwork/bor). --- consensus/bor/bor.go | 22 +----- core/system_contract_lookup.go | 60 +++++++-------- core/systemcontracts/const.go | 21 ------ core/systemcontracts/upgrade.go | 113 ----------------------------- core/types/genesis.go | 22 ++++-- erigon-lib/chain/chain_config.go | 15 +--- params/chainspecs/bor-devnet.json | 5 +- params/chainspecs/bor-mainnet.json | 1 - params/chainspecs/mumbai.json | 1 - 9 files changed, 49 insertions(+), 211 deletions(-) delete mode 100644 core/systemcontracts/const.go diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 1dc372f2954..c01c3c12158 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -4,7 +4,6 @@ import ( "bytes" "context" "encoding/hex" - "encoding/json" "errors" "fmt" "io" @@ -36,7 +35,6 @@ import ( "github.com/ledgerwatch/erigon/consensus/misc" "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/state" - "github.com/ledgerwatch/erigon/core/systemcontracts" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/types/accounts" "github.com/ledgerwatch/erigon/crypto" @@ -415,7 +413,7 @@ func New( // make sure we can decode all the GenesisAlloc in the BorConfig. for key, genesisAlloc := range c.config.BlockAlloc { - if _, err := decodeGenesisAlloc(genesisAlloc); err != nil { + if _, err := types.DecodeGenesisAlloc(genesisAlloc); err != nil { panic(fmt.Sprintf("BUG: Block alloc '%s' in genesis is not correct: %v", key, err)) } } @@ -1041,25 +1039,10 @@ func (c *Bor) Finalize(config *chain.Config, header *types.Header, state *state. return nil, types.Receipts{}, nil } -func decodeGenesisAlloc(i interface{}) (types.GenesisAlloc, error) { - var alloc types.GenesisAlloc - - b, err := json.Marshal(i) - if err != nil { - return nil, err - } - - if err := json.Unmarshal(b, &alloc); err != nil { - return nil, err - } - - return alloc, nil -} - func (c *Bor) changeContractCodeIfNeeded(headerNumber uint64, state *state.IntraBlockState) error { for blockNumber, genesisAlloc := range c.config.BlockAlloc { if blockNumber == strconv.FormatUint(headerNumber, 10) { - allocs, err := decodeGenesisAlloc(genesisAlloc) + allocs, err := types.DecodeGenesisAlloc(genesisAlloc) if err != nil { return fmt.Errorf("failed to decode genesis alloc: %v", err) } @@ -1128,7 +1111,6 @@ func (c *Bor) GenerateSeal(chain consensus.ChainHeaderReader, currnt, parent *ty func (c *Bor) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, header *types.Header, state *state.IntraBlockState, syscall consensus.SysCallCustom, logger log.Logger) { - systemcontracts.UpgradeBuildInSystemContract(config, header.Number, state, logger) } // Authorize injects a private key into the consensus engine to mint new blocks diff --git a/core/system_contract_lookup.go b/core/system_contract_lookup.go index 0e26363ba5d..dfcecb38d8c 100644 --- a/core/system_contract_lookup.go +++ b/core/system_contract_lookup.go @@ -1,49 +1,59 @@ package core import ( - "encoding/hex" "fmt" + "strconv" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/core/systemcontracts" + "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/params/networkname" ) func init() { - // Initialise systemContractCodeLookup + // Initialise SystemContractCodeLookup for _, chainName := range []string{networkname.BorMainnetChainName, networkname.MumbaiChainName, networkname.BorDevnetChainName} { byChain := map[libcommon.Address][]libcommon.CodeRecord{} systemcontracts.SystemContractCodeLookup[chainName] = byChain // Apply genesis with the block number 0 genesisBlock := GenesisBlockByChainName(chainName) - for addr, alloc := range genesisBlock.Alloc { - if len(alloc.Code) > 0 { - list := byChain[addr] - codeHash, err := common.HashData(alloc.Code) - if err != nil { - panic(fmt.Errorf("failed to hash system contract code: %s", err.Error())) - } - list = append(list, libcommon.CodeRecord{BlockNumber: 0, CodeHash: codeHash}) - byChain[addr] = list - } - } + allocToCodeRecords(genesisBlock.Alloc, byChain, 0) // Process upgrades chainConfig := params.ChainConfigByChainName(chainName) - if chainConfig.Bor != nil && chainConfig.Bor.CalcuttaBlock != nil { - blockNum := chainConfig.Bor.CalcuttaBlock.Uint64() - if blockNum != 0 { - addCodeRecords(systemcontracts.CalcuttaUpgrade[chainName], blockNum, byChain) + for blockNumStr, genesisAlloc := range chainConfig.Bor.BlockAlloc { + blockNum, err := strconv.ParseUint(blockNumStr, 10, 64) + if err != nil { + panic(fmt.Errorf("failed to parse block number in BlockAlloc: %s", err.Error())) } + alloc, err := types.DecodeGenesisAlloc(genesisAlloc) + if err != nil { + panic(fmt.Errorf("failed to decode block alloc: %v", err)) + } + allocToCodeRecords(alloc, byChain, blockNum) } } addGnosisSpecialCase() } +func allocToCodeRecords(alloc types.GenesisAlloc, byChain map[libcommon.Address][]libcommon.CodeRecord, blockNum uint64) { + for addr, account := range alloc { + if len(account.Code) > 0 { + list := byChain[addr] + codeHash, err := common.HashData(account.Code) + if err != nil { + panic(fmt.Errorf("failed to hash system contract code: %s", err.Error())) + } + list = append(list, libcommon.CodeRecord{BlockNumber: blockNum, CodeHash: codeHash}) + byChain[addr] = list + } + } +} + // some hard coding for gnosis chain here to solve a historical problem with the token contract being re-written // and losing the history for it in the DB. Temporary hack until erigon 3 arrives func addGnosisSpecialCase() { @@ -75,19 +85,3 @@ func addGnosisSpecialCase() { byChain[address] = list } - -func addCodeRecords(upgrade *systemcontracts.Upgrade, blockNum uint64, byChain map[libcommon.Address][]libcommon.CodeRecord) { - for _, config := range upgrade.Configs { - list := byChain[config.ContractAddr] - code, err := hex.DecodeString(config.Code) - if err != nil { - panic(fmt.Errorf("failed to decode system contract code: %s", err.Error())) - } - codeHash, err := common.HashData(code) - if err != nil { - panic(fmt.Errorf("failed to hash system contract code: %s", err.Error())) - } - list = append(list, libcommon.CodeRecord{BlockNumber: blockNum, CodeHash: codeHash}) - byChain[config.ContractAddr] = list - } -} diff --git a/core/systemcontracts/const.go b/core/systemcontracts/const.go deleted file mode 100644 index ab3315e726f..00000000000 --- a/core/systemcontracts/const.go +++ /dev/null @@ -1,21 +0,0 @@ -package systemcontracts - -import ( - libcommon "github.com/ledgerwatch/erigon-lib/common" -) - -var ( - // genesis contracts - ValidatorContract = libcommon.HexToAddress("0x0000000000000000000000000000000000001000") - SlashContract = libcommon.HexToAddress("0x0000000000000000000000000000000000001001") - SystemRewardContract = libcommon.HexToAddress("0x0000000000000000000000000000000000001002") - LightClientContract = libcommon.HexToAddress("0x0000000000000000000000000000000000001003") - TokenHubContract = libcommon.HexToAddress("0x0000000000000000000000000000000000001004") - RelayerIncentivizeContract = libcommon.HexToAddress("0x0000000000000000000000000000000000001005") - RelayerHubContract = libcommon.HexToAddress("0x0000000000000000000000000000000000001006") - GovHubContract = libcommon.HexToAddress("0x0000000000000000000000000000000000001007") - TokenManagerContract = libcommon.HexToAddress("0x0000000000000000000000000000000000001008") - MaticTokenContract = libcommon.HexToAddress("0x0000000000000000000000000000000000001010") - CrossChainContract = libcommon.HexToAddress("0x0000000000000000000000000000000000002000") - StakingContract = libcommon.HexToAddress("0x0000000000000000000000000000000000002001") -) diff --git a/core/systemcontracts/upgrade.go b/core/systemcontracts/upgrade.go index 677aea242fe..e9d6d005539 100644 --- a/core/systemcontracts/upgrade.go +++ b/core/systemcontracts/upgrade.go @@ -1,38 +1,10 @@ package systemcontracts import ( - "encoding/hex" - "fmt" - "math/big" - - "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" - "github.com/ledgerwatch/erigon/core/vm/evmtypes" - "github.com/ledgerwatch/log/v3" - - "github.com/ledgerwatch/erigon/params/networkname" ) -type UpgradeConfig struct { - BeforeUpgrade upgradeHook - AfterUpgrade upgradeHook - ContractAddr libcommon.Address - CommitUrl string - Code string -} - -type Upgrade struct { - UpgradeName string - Configs []*UpgradeConfig -} - -type upgradeHook func(blockNumber *big.Int, contractAddr libcommon.Address, statedb evmtypes.IntraBlockState) error - var ( - //upgrade config - - CalcuttaUpgrade = make(map[string]*Upgrade) - // SystemContractCodeLookup is used to address a flaw in the upgrade logic of the system contracts. Since they are updated directly, without first being self-destructed // and then re-created, the usual incarnation logic does not get activated, and all historical records of the code of these contracts are retrieved as the most // recent version. This problem will not exist in erigon3, but until then, a workaround will be used to access code of such contracts through this structure @@ -40,88 +12,3 @@ var ( // to be used in binary search to determine correct historical code SystemContractCodeLookup = map[string]map[libcommon.Address][]libcommon.CodeRecord{} ) - -func init() { - CalcuttaUpgrade[networkname.BorMainnetChainName] = &Upgrade{ - UpgradeName: "calcutta", - Configs: []*UpgradeConfig{ - { - ContractAddr: MaticTokenContract, - Code: "60806040526004361061019c5760003560e01c806377d32e94116100ec578063acd06cb31161008a578063e306f77911610064578063e306f77914610a7b578063e614d0d614610aa6578063f2fde38b14610ad1578063fc0c546a14610b225761019c565b8063acd06cb31461097a578063b789543c146109cd578063cc79f97b14610a505761019c565b80639025e64c116100c65780639025e64c146107c957806395d89b4114610859578063a9059cbb146108e9578063abceeba21461094f5761019c565b806377d32e94146106315780638da5cb5b146107435780638f32d59b1461079a5761019c565b806347e7ef24116101595780637019d41a116101335780637019d41a1461053357806370a082311461058a578063715018a6146105ef578063771282f6146106065761019c565b806347e7ef2414610410578063485cc9551461046b57806360f96a8f146104dc5761019c565b806306fdde03146101a15780631499c5921461023157806318160ddd1461028257806319d27d9c146102ad5780632e1a7d4d146103b1578063313ce567146103df575b600080fd5b3480156101ad57600080fd5b506101b6610b79565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101f65780820151818401526020810190506101db565b50505050905090810190601f1680156102235780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561023d57600080fd5b506102806004803603602081101561025457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610bb6565b005b34801561028e57600080fd5b50610297610c24565b6040518082815260200191505060405180910390f35b3480156102b957600080fd5b5061036f600480360360a08110156102d057600080fd5b81019080803590602001906401000000008111156102ed57600080fd5b8201836020820111156102ff57600080fd5b8035906020019184600183028401116401000000008311171561032157600080fd5b9091929391929390803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610c3a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103dd600480360360208110156103c757600080fd5b8101908080359060200190929190505050610caa565b005b3480156103eb57600080fd5b506103f4610dfc565b604051808260ff1660ff16815260200191505060405180910390f35b34801561041c57600080fd5b506104696004803603604081101561043357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610e05565b005b34801561047757600080fd5b506104da6004803603604081101561048e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610fc1565b005b3480156104e857600080fd5b506104f1611090565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561053f57600080fd5b506105486110b6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561059657600080fd5b506105d9600480360360208110156105ad57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506110dc565b6040518082815260200191505060405180910390f35b3480156105fb57600080fd5b506106046110fd565b005b34801561061257600080fd5b5061061b6111cd565b6040518082815260200191505060405180910390f35b34801561063d57600080fd5b506107016004803603604081101561065457600080fd5b81019080803590602001909291908035906020019064010000000081111561067b57600080fd5b82018360208201111561068d57600080fd5b803590602001918460018302840111640100000000831117156106af57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506111d3565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561074f57600080fd5b50610758611358565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156107a657600080fd5b506107af611381565b604051808215151515815260200191505060405180910390f35b3480156107d557600080fd5b506107de6113d8565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561081e578082015181840152602081019050610803565b50505050905090810190601f16801561084b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561086557600080fd5b5061086e611411565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156108ae578082015181840152602081019050610893565b50505050905090810190601f1680156108db5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610935600480360360408110156108ff57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061144e565b604051808215151515815260200191505060405180910390f35b34801561095b57600080fd5b50610964611474565b6040518082815260200191505060405180910390f35b34801561098657600080fd5b506109b36004803603602081101561099d57600080fd5b8101908080359060200190929190505050611501565b604051808215151515815260200191505060405180910390f35b3480156109d957600080fd5b50610a3a600480360360808110156109f057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019092919080359060200190929190505050611521565b6040518082815260200191505060405180910390f35b348015610a5c57600080fd5b50610a65611541565b6040518082815260200191505060405180910390f35b348015610a8757600080fd5b50610a90611546565b6040518082815260200191505060405180910390f35b348015610ab257600080fd5b50610abb61154c565b6040518082815260200191505060405180910390f35b348015610add57600080fd5b50610b2060048036036020811015610af457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506115d9565b005b348015610b2e57600080fd5b50610b376115f6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60606040518060400160405280600b81526020017f4d6174696320546f6b656e000000000000000000000000000000000000000000815250905090565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f44697361626c656420666561747572650000000000000000000000000000000081525060200191505060405180910390fd5b6000601260ff16600a0a6402540be40002905090565b60006040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f44697361626c656420666561747572650000000000000000000000000000000081525060200191505060405180910390fd5b60003390506000610cba826110dc565b9050610cd18360065461161c90919063ffffffff16565b600681905550600083118015610ce657508234145b610d58576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f496e73756666696369656e7420616d6f756e740000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167febff2602b3f468259e1e99f613fed6691f3a6526effe6ef3e768ba7ae7a36c4f8584610dd4876110dc565b60405180848152602001838152602001828152602001935050505060405180910390a3505050565b60006012905090565b610e0d611381565b610e1657600080fd5b600081118015610e535750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b610ea8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611da76023913960400191505060405180910390fd5b6000610eb3836110dc565b905060008390508073ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f19350505050158015610f00573d6000803e3d6000fd5b50610f168360065461163c90919063ffffffff16565b6006819055508373ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f4e2ca0515ed1aef1395f66b5303bb5d6f1bf9d61a353fa53f73f8ac9973fa9f68585610f98896110dc565b60405180848152602001838152602001828152602001935050505060405180910390a350505050565b600760009054906101000a900460ff1615611027576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611d846023913960400191505060405180910390fd5b6001600760006101000a81548160ff02191690831515021790555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061108c8261165b565b5050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b611105611381565b61110e57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60065481565b60008060008060418551146111ee5760009350505050611352565b602085015192506040850151915060ff6041860151169050601b8160ff16101561121957601b810190505b601b8160ff16141580156112315750601c8160ff1614155b156112425760009350505050611352565b60018682858560405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa15801561129f573d6000803e3d6000fd5b505050602060405103519350600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141561134e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4572726f7220696e2065637265636f766572000000000000000000000000000081525060200191505060405180910390fd5b5050505b92915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b6040518060400160405280600181526020017f890000000000000000000000000000000000000000000000000000000000000081525081565b60606040518060400160405280600581526020017f4d41544943000000000000000000000000000000000000000000000000000000815250905090565b6000813414611460576000905061146e565b61146b338484611753565b90505b92915050565b6040518060800160405280605b8152602001611e1c605b91396040516020018082805190602001908083835b602083106114c357805182526020820191506020810190506020830392506114a0565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b60056020528060005260406000206000915054906101000a900460ff1681565b600061153761153286868686611b10565b611be6565b9050949350505050565b608981565b60015481565b604051806080016040528060528152602001611dca605291396040516020018082805190602001908083835b6020831061159b5780518252602082019150602081019050602083039250611578565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b6115e1611381565b6115ea57600080fd5b6115f38161165b565b50565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008282111561162b57600080fd5b600082840390508091505092915050565b60008082840190508381101561165157600080fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561169557600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000803073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156117d357600080fd5b505afa1580156117e7573d6000803e3d6000fd5b505050506040513d60208110156117fd57600080fd5b8101908080519060200190929190505050905060003073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561188f57600080fd5b505afa1580156118a3573d6000803e3d6000fd5b505050506040513d60208110156118b957600080fd5b810190808051906020019092919050505090506118d7868686611c30565b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fe6497e3ee548a3372136af2fcb0696db31fc6cf20260707645068bd3fe97f3c48786863073ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156119df57600080fd5b505afa1580156119f3573d6000803e3d6000fd5b505050506040513d6020811015611a0957600080fd5b81019080805190602001909291905050503073ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611a9757600080fd5b505afa158015611aab573d6000803e3d6000fd5b505050506040513d6020811015611ac157600080fd5b8101908080519060200190929190505050604051808681526020018581526020018481526020018381526020018281526020019550505050505060405180910390a46001925050509392505050565b6000806040518060800160405280605b8152602001611e1c605b91396040516020018082805190602001908083835b60208310611b625780518252602082019150602081019050602083039250611b3f565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120905060405181815273ffffffffffffffffffffffffffffffffffffffff8716602082015285604082015284606082015283608082015260a0812092505081915050949350505050565b60008060015490506040517f190100000000000000000000000000000000000000000000000000000000000081528160028201528360228201526042812092505081915050919050565b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611cd2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f63616e27742073656e6420746f204d524332300000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611d18573d6000803e3d6000fd5b508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a350505056fe54686520636f6e747261637420697320616c726561647920696e697469616c697a6564496e73756666696369656e7420616d6f756e74206f7220696e76616c69642075736572454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429546f6b656e5472616e736665724f726465722861646472657373207370656e6465722c75696e7432353620746f6b656e49644f72416d6f756e742c6279746573333220646174612c75696e743235362065787069726174696f6e29a265627a7a72315820a4a6f71a98ac3fc613c3a8f1e2e11b9eb9b6b39f125f7d9508916c2b8fb02c7164736f6c63430005100032", - }, - }, - } - - CalcuttaUpgrade[networkname.MumbaiChainName] = &Upgrade{ - UpgradeName: "calcutta", - Configs: []*UpgradeConfig{ - { - ContractAddr: MaticTokenContract, - Code: "60806040526004361061019c5760003560e01c806377d32e94116100ec578063acd06cb31161008a578063e306f77911610064578063e306f77914610a7b578063e614d0d614610aa6578063f2fde38b14610ad1578063fc0c546a14610b225761019c565b8063acd06cb31461097a578063b789543c146109cd578063cc79f97b14610a505761019c565b80639025e64c116100c65780639025e64c146107c957806395d89b4114610859578063a9059cbb146108e9578063abceeba21461094f5761019c565b806377d32e94146106315780638da5cb5b146107435780638f32d59b1461079a5761019c565b806347e7ef24116101595780637019d41a116101335780637019d41a1461053357806370a082311461058a578063715018a6146105ef578063771282f6146106065761019c565b806347e7ef2414610410578063485cc9551461046b57806360f96a8f146104dc5761019c565b806306fdde03146101a15780631499c5921461023157806318160ddd1461028257806319d27d9c146102ad5780632e1a7d4d146103b1578063313ce567146103df575b600080fd5b3480156101ad57600080fd5b506101b6610b79565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101f65780820151818401526020810190506101db565b50505050905090810190601f1680156102235780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561023d57600080fd5b506102806004803603602081101561025457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610bb6565b005b34801561028e57600080fd5b50610297610c24565b6040518082815260200191505060405180910390f35b3480156102b957600080fd5b5061036f600480360360a08110156102d057600080fd5b81019080803590602001906401000000008111156102ed57600080fd5b8201836020820111156102ff57600080fd5b8035906020019184600183028401116401000000008311171561032157600080fd5b9091929391929390803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610c3a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103dd600480360360208110156103c757600080fd5b8101908080359060200190929190505050610caa565b005b3480156103eb57600080fd5b506103f4610dfc565b604051808260ff1660ff16815260200191505060405180910390f35b34801561041c57600080fd5b506104696004803603604081101561043357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610e05565b005b34801561047757600080fd5b506104da6004803603604081101561048e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610fc1565b005b3480156104e857600080fd5b506104f1611090565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561053f57600080fd5b506105486110b6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561059657600080fd5b506105d9600480360360208110156105ad57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506110dc565b6040518082815260200191505060405180910390f35b3480156105fb57600080fd5b506106046110fd565b005b34801561061257600080fd5b5061061b6111cd565b6040518082815260200191505060405180910390f35b34801561063d57600080fd5b506107016004803603604081101561065457600080fd5b81019080803590602001909291908035906020019064010000000081111561067b57600080fd5b82018360208201111561068d57600080fd5b803590602001918460018302840111640100000000831117156106af57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506111d3565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561074f57600080fd5b50610758611358565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156107a657600080fd5b506107af611381565b604051808215151515815260200191505060405180910390f35b3480156107d557600080fd5b506107de6113d8565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561081e578082015181840152602081019050610803565b50505050905090810190601f16801561084b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561086557600080fd5b5061086e611411565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156108ae578082015181840152602081019050610893565b50505050905090810190601f1680156108db5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610935600480360360408110156108ff57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061144e565b604051808215151515815260200191505060405180910390f35b34801561095b57600080fd5b50610964611474565b6040518082815260200191505060405180910390f35b34801561098657600080fd5b506109b36004803603602081101561099d57600080fd5b8101908080359060200190929190505050611501565b604051808215151515815260200191505060405180910390f35b3480156109d957600080fd5b50610a3a600480360360808110156109f057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019092919080359060200190929190505050611521565b6040518082815260200191505060405180910390f35b348015610a5c57600080fd5b50610a65611541565b6040518082815260200191505060405180910390f35b348015610a8757600080fd5b50610a90611548565b6040518082815260200191505060405180910390f35b348015610ab257600080fd5b50610abb61154e565b6040518082815260200191505060405180910390f35b348015610add57600080fd5b50610b2060048036036020811015610af457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506115db565b005b348015610b2e57600080fd5b50610b376115f8565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60606040518060400160405280600b81526020017f4d6174696320546f6b656e000000000000000000000000000000000000000000815250905090565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f44697361626c656420666561747572650000000000000000000000000000000081525060200191505060405180910390fd5b6000601260ff16600a0a6402540be40002905090565b60006040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f44697361626c656420666561747572650000000000000000000000000000000081525060200191505060405180910390fd5b60003390506000610cba826110dc565b9050610cd18360065461161e90919063ffffffff16565b600681905550600083118015610ce657508234145b610d58576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f496e73756666696369656e7420616d6f756e740000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167febff2602b3f468259e1e99f613fed6691f3a6526effe6ef3e768ba7ae7a36c4f8584610dd4876110dc565b60405180848152602001838152602001828152602001935050505060405180910390a3505050565b60006012905090565b610e0d611381565b610e1657600080fd5b600081118015610e535750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b610ea8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611da96023913960400191505060405180910390fd5b6000610eb3836110dc565b905060008390508073ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f19350505050158015610f00573d6000803e3d6000fd5b50610f168360065461163e90919063ffffffff16565b6006819055508373ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f4e2ca0515ed1aef1395f66b5303bb5d6f1bf9d61a353fa53f73f8ac9973fa9f68585610f98896110dc565b60405180848152602001838152602001828152602001935050505060405180910390a350505050565b600760009054906101000a900460ff1615611027576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611d866023913960400191505060405180910390fd5b6001600760006101000a81548160ff02191690831515021790555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061108c8261165d565b5050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b611105611381565b61110e57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60065481565b60008060008060418551146111ee5760009350505050611352565b602085015192506040850151915060ff6041860151169050601b8160ff16101561121957601b810190505b601b8160ff16141580156112315750601c8160ff1614155b156112425760009350505050611352565b60018682858560405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa15801561129f573d6000803e3d6000fd5b505050602060405103519350600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141561134e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4572726f7220696e2065637265636f766572000000000000000000000000000081525060200191505060405180910390fd5b5050505b92915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b6040518060400160405280600381526020017f013881000000000000000000000000000000000000000000000000000000000081525081565b60606040518060400160405280600581526020017f4d41544943000000000000000000000000000000000000000000000000000000815250905090565b6000813414611460576000905061146e565b61146b338484611755565b90505b92915050565b6040518060800160405280605b8152602001611e1e605b91396040516020018082805190602001908083835b602083106114c357805182526020820191506020810190506020830392506114a0565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b60056020528060005260406000206000915054906101000a900460ff1681565b600061153761153286868686611b12565b611be8565b9050949350505050565b6201388181565b60015481565b604051806080016040528060528152602001611dcc605291396040516020018082805190602001908083835b6020831061159d578051825260208201915060208101905060208303925061157a565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b6115e3611381565b6115ec57600080fd5b6115f58161165d565b50565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008282111561162d57600080fd5b600082840390508091505092915050565b60008082840190508381101561165357600080fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561169757600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000803073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156117d557600080fd5b505afa1580156117e9573d6000803e3d6000fd5b505050506040513d60208110156117ff57600080fd5b8101908080519060200190929190505050905060003073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561189157600080fd5b505afa1580156118a5573d6000803e3d6000fd5b505050506040513d60208110156118bb57600080fd5b810190808051906020019092919050505090506118d9868686611c32565b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fe6497e3ee548a3372136af2fcb0696db31fc6cf20260707645068bd3fe97f3c48786863073ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156119e157600080fd5b505afa1580156119f5573d6000803e3d6000fd5b505050506040513d6020811015611a0b57600080fd5b81019080805190602001909291905050503073ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611a9957600080fd5b505afa158015611aad573d6000803e3d6000fd5b505050506040513d6020811015611ac357600080fd5b8101908080519060200190929190505050604051808681526020018581526020018481526020018381526020018281526020019550505050505060405180910390a46001925050509392505050565b6000806040518060800160405280605b8152602001611e1e605b91396040516020018082805190602001908083835b60208310611b645780518252602082019150602081019050602083039250611b41565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120905060405181815273ffffffffffffffffffffffffffffffffffffffff8716602082015285604082015284606082015283608082015260a0812092505081915050949350505050565b60008060015490506040517f190100000000000000000000000000000000000000000000000000000000000081528160028201528360228201526042812092505081915050919050565b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611cd4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f63616e27742073656e6420746f204d524332300000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611d1a573d6000803e3d6000fd5b508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a350505056fe54686520636f6e747261637420697320616c726561647920696e697469616c697a6564496e73756666696369656e7420616d6f756e74206f7220696e76616c69642075736572454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429546f6b656e5472616e736665724f726465722861646472657373207370656e6465722c75696e7432353620746f6b656e49644f72416d6f756e742c6279746573333220646174612c75696e743235362065787069726174696f6e29a265627a7a72315820ccd6c2a9c259832bbb367986ee06cd87af23022681b0cb22311a864b701d939564736f6c63430005100032", - }, - }, - } - - CalcuttaUpgrade[networkname.BorDevnetChainName] = &Upgrade{ - UpgradeName: "calcutta", - Configs: []*UpgradeConfig{ - { - ContractAddr: MaticTokenContract, - Code: "60806040526004361061019c5760003560e01c806377d32e94116100ec578063acd06cb31161008a578063e306f77911610064578063e306f77914610a7b578063e614d0d614610aa6578063f2fde38b14610ad1578063fc0c546a14610b225761019c565b8063acd06cb31461097a578063b789543c146109cd578063cc79f97b14610a505761019c565b80639025e64c116100c65780639025e64c146107c957806395d89b4114610859578063a9059cbb146108e9578063abceeba21461094f5761019c565b806377d32e94146106315780638da5cb5b146107435780638f32d59b1461079a5761019c565b806347e7ef24116101595780637019d41a116101335780637019d41a1461053357806370a082311461058a578063715018a6146105ef578063771282f6146106065761019c565b806347e7ef2414610410578063485cc9551461046b57806360f96a8f146104dc5761019c565b806306fdde03146101a15780631499c5921461023157806318160ddd1461028257806319d27d9c146102ad5780632e1a7d4d146103b1578063313ce567146103df575b600080fd5b3480156101ad57600080fd5b506101b6610b79565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101f65780820151818401526020810190506101db565b50505050905090810190601f1680156102235780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561023d57600080fd5b506102806004803603602081101561025457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610bb6565b005b34801561028e57600080fd5b50610297610c24565b6040518082815260200191505060405180910390f35b3480156102b957600080fd5b5061036f600480360360a08110156102d057600080fd5b81019080803590602001906401000000008111156102ed57600080fd5b8201836020820111156102ff57600080fd5b8035906020019184600183028401116401000000008311171561032157600080fd5b9091929391929390803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610c3a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103dd600480360360208110156103c757600080fd5b8101908080359060200190929190505050610caa565b005b3480156103eb57600080fd5b506103f4610dfc565b604051808260ff1660ff16815260200191505060405180910390f35b34801561041c57600080fd5b506104696004803603604081101561043357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610e05565b005b34801561047757600080fd5b506104da6004803603604081101561048e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610fc1565b005b3480156104e857600080fd5b506104f1611090565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561053f57600080fd5b506105486110b6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561059657600080fd5b506105d9600480360360208110156105ad57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506110dc565b6040518082815260200191505060405180910390f35b3480156105fb57600080fd5b506106046110fd565b005b34801561061257600080fd5b5061061b6111cd565b6040518082815260200191505060405180910390f35b34801561063d57600080fd5b506107016004803603604081101561065457600080fd5b81019080803590602001909291908035906020019064010000000081111561067b57600080fd5b82018360208201111561068d57600080fd5b803590602001918460018302840111640100000000831117156106af57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506111d3565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561074f57600080fd5b50610758611358565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156107a657600080fd5b506107af611381565b604051808215151515815260200191505060405180910390f35b3480156107d557600080fd5b506107de6113d8565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561081e578082015181840152602081019050610803565b50505050905090810190601f16801561084b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561086557600080fd5b5061086e611411565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156108ae578082015181840152602081019050610893565b50505050905090810190601f1680156108db5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610935600480360360408110156108ff57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061144e565b604051808215151515815260200191505060405180910390f35b34801561095b57600080fd5b50610964611474565b6040518082815260200191505060405180910390f35b34801561098657600080fd5b506109b36004803603602081101561099d57600080fd5b8101908080359060200190929190505050611501565b604051808215151515815260200191505060405180910390f35b3480156109d957600080fd5b50610a3a600480360360808110156109f057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019092919080359060200190929190505050611521565b6040518082815260200191505060405180910390f35b348015610a5c57600080fd5b50610a65611541565b6040518082815260200191505060405180910390f35b348015610a8757600080fd5b50610a90611546565b6040518082815260200191505060405180910390f35b348015610ab257600080fd5b50610abb61154c565b6040518082815260200191505060405180910390f35b348015610add57600080fd5b50610b2060048036036020811015610af457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506115d9565b005b348015610b2e57600080fd5b50610b376115f6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60606040518060400160405280600b81526020017f4d6174696320546f6b656e000000000000000000000000000000000000000000815250905090565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f44697361626c656420666561747572650000000000000000000000000000000081525060200191505060405180910390fd5b6000601260ff16600a0a6402540be40002905090565b60006040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f44697361626c656420666561747572650000000000000000000000000000000081525060200191505060405180910390fd5b60003390506000610cba826110dc565b9050610cd18360065461161c90919063ffffffff16565b600681905550600083118015610ce657508234145b610d58576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f496e73756666696369656e7420616d6f756e740000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167febff2602b3f468259e1e99f613fed6691f3a6526effe6ef3e768ba7ae7a36c4f8584610dd4876110dc565b60405180848152602001838152602001828152602001935050505060405180910390a3505050565b60006012905090565b610e0d611381565b610e1657600080fd5b600081118015610e535750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b610ea8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611da76023913960400191505060405180910390fd5b6000610eb3836110dc565b905060008390508073ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f19350505050158015610f00573d6000803e3d6000fd5b50610f168360065461163c90919063ffffffff16565b6006819055508373ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f4e2ca0515ed1aef1395f66b5303bb5d6f1bf9d61a353fa53f73f8ac9973fa9f68585610f98896110dc565b60405180848152602001838152602001828152602001935050505060405180910390a350505050565b600760009054906101000a900460ff1615611027576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611d846023913960400191505060405180910390fd5b6001600760006101000a81548160ff02191690831515021790555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061108c8261165b565b5050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b611105611381565b61110e57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60065481565b60008060008060418551146111ee5760009350505050611352565b602085015192506040850151915060ff6041860151169050601b8160ff16101561121957601b810190505b601b8160ff16141580156112315750601c8160ff1614155b156112425760009350505050611352565b60018682858560405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa15801561129f573d6000803e3d6000fd5b505050602060405103519350600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141561134e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4572726f7220696e2065637265636f766572000000000000000000000000000081525060200191505060405180910390fd5b5050505b92915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b6040518060400160405280600181526020017f890000000000000000000000000000000000000000000000000000000000000081525081565b60606040518060400160405280600581526020017f4d41544943000000000000000000000000000000000000000000000000000000815250905090565b6000813414611460576000905061146e565b61146b338484611753565b90505b92915050565b6040518060800160405280605b8152602001611e1c605b91396040516020018082805190602001908083835b602083106114c357805182526020820191506020810190506020830392506114a0565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b60056020528060005260406000206000915054906101000a900460ff1681565b600061153761153286868686611b10565b611be6565b9050949350505050565b608981565b60015481565b604051806080016040528060528152602001611dca605291396040516020018082805190602001908083835b6020831061159b5780518252602082019150602081019050602083039250611578565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b6115e1611381565b6115ea57600080fd5b6115f38161165b565b50565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008282111561162b57600080fd5b600082840390508091505092915050565b60008082840190508381101561165157600080fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561169557600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000803073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156117d357600080fd5b505afa1580156117e7573d6000803e3d6000fd5b505050506040513d60208110156117fd57600080fd5b8101908080519060200190929190505050905060003073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561188f57600080fd5b505afa1580156118a3573d6000803e3d6000fd5b505050506040513d60208110156118b957600080fd5b810190808051906020019092919050505090506118d7868686611c30565b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fe6497e3ee548a3372136af2fcb0696db31fc6cf20260707645068bd3fe97f3c48786863073ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156119df57600080fd5b505afa1580156119f3573d6000803e3d6000fd5b505050506040513d6020811015611a0957600080fd5b81019080805190602001909291905050503073ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611a9757600080fd5b505afa158015611aab573d6000803e3d6000fd5b505050506040513d6020811015611ac157600080fd5b8101908080519060200190929190505050604051808681526020018581526020018481526020018381526020018281526020019550505050505060405180910390a46001925050509392505050565b6000806040518060800160405280605b8152602001611e1c605b91396040516020018082805190602001908083835b60208310611b625780518252602082019150602081019050602083039250611b3f565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120905060405181815273ffffffffffffffffffffffffffffffffffffffff8716602082015285604082015284606082015283608082015260a0812092505081915050949350505050565b60008060015490506040517f190100000000000000000000000000000000000000000000000000000000000081528160028201528360228201526042812092505081915050919050565b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611cd2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f63616e27742073656e6420746f204d524332300000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611d18573d6000803e3d6000fd5b508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a350505056fe54686520636f6e747261637420697320616c726561647920696e697469616c697a6564496e73756666696369656e7420616d6f756e74206f7220696e76616c69642075736572454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429546f6b656e5472616e736665724f726465722861646472657373207370656e6465722c75696e7432353620746f6b656e49644f72416d6f756e742c6279746573333220646174612c75696e743235362065787069726174696f6e29a265627a7a72315820a4a6f71a98ac3fc613c3a8f1e2e11b9eb9b6b39f125f7d9508916c2b8fb02c7164736f6c63430005100032", - }, - }, - } -} - -func UpgradeBuildInSystemContract(config *chain.Config, blockNumber *big.Int, statedb evmtypes.IntraBlockState, logger log.Logger) { - if config == nil || blockNumber == nil || statedb == nil { - return - } - - if config.Bor != nil && config.Bor.IsOnCalcutta(blockNumber) { - applySystemContractUpgrade(CalcuttaUpgrade[config.ChainName], blockNumber, statedb, logger) - } - - /* - apply other upgrades - */ -} - -func applySystemContractUpgrade(upgrade *Upgrade, blockNumber *big.Int, statedb evmtypes.IntraBlockState, logger log.Logger) { - if upgrade == nil { - logger.Info("Empty upgrade config", "height", blockNumber.String()) - return - } - - logger.Info(fmt.Sprintf("Apply upgrade %s at height %d", upgrade.UpgradeName, blockNumber.Int64())) - for _, cfg := range upgrade.Configs { - logger.Info(fmt.Sprintf("Upgrade contract %s to commit %s", cfg.ContractAddr.String(), cfg.CommitUrl)) - - if cfg.BeforeUpgrade != nil { - err := cfg.BeforeUpgrade(blockNumber, cfg.ContractAddr, statedb) - if err != nil { - panic(fmt.Errorf("contract address: %s, execute beforeUpgrade error: %s", cfg.ContractAddr.String(), err.Error())) - } - } - - newContractCode, err := hex.DecodeString(cfg.Code) - if err != nil { - panic(fmt.Errorf("failed to decode new contract code: %s", err.Error())) - } - - prevContractCode := statedb.GetCode(cfg.ContractAddr) - if len(prevContractCode) == 0 && len(newContractCode) > 0 { - // system contracts defined after genesis need to be explicitly created - statedb.CreateAccount(cfg.ContractAddr, true) - } - - statedb.SetCode(cfg.ContractAddr, newContractCode) - - if cfg.AfterUpgrade != nil { - err := cfg.AfterUpgrade(blockNumber, cfg.ContractAddr, statedb) - if err != nil { - panic(fmt.Errorf("contract address: %s, execute afterUpgrade error: %s", cfg.ContractAddr.String(), err.Error())) - } - } - } -} diff --git a/core/types/genesis.go b/core/types/genesis.go index 9a696a0bd25..d6f0e8cbc21 100644 --- a/core/types/genesis.go +++ b/core/types/genesis.go @@ -70,13 +70,6 @@ type Genesis struct { // GenesisAlloc specifies the initial state that is part of the genesis block. type GenesisAlloc map[common.Address]GenesisAccount -type AuthorityRoundSeal struct { - /// Seal step. - Step uint64 `json:"step"` - /// Seal signature. - Signature common.Hash `json:"signature"` -} - func (ga *GenesisAlloc) UnmarshalJSON(data []byte) error { m := make(map[common2.UnprefixedAddress]GenesisAccount) if err := json.Unmarshal(data, &m); err != nil { @@ -89,6 +82,21 @@ func (ga *GenesisAlloc) UnmarshalJSON(data []byte) error { return nil } +func DecodeGenesisAlloc(i interface{}) (GenesisAlloc, error) { + var alloc GenesisAlloc + + b, err := json.Marshal(i) + if err != nil { + return nil, err + } + + if err := json.Unmarshal(b, &alloc); err != nil { + return nil, err + } + + return alloc, nil +} + // GenesisAccount is an account in the state of the genesis block. // Either use "constructor" for deployment code or "code" directly for the final code. type GenesisAccount struct { diff --git a/erigon-lib/chain/chain_config.go b/erigon-lib/chain/chain_config.go index a82481115b7..09d8fe7d6e5 100644 --- a/erigon-lib/chain/chain_config.go +++ b/erigon-lib/chain/chain_config.go @@ -410,11 +410,10 @@ type BorConfig struct { OverrideStateSyncRecords map[string]int `json:"overrideStateSyncRecords"` // override state records count BlockAlloc map[string]interface{} `json:"blockAlloc"` - CalcuttaBlock *big.Int `json:"calcuttaBlock"` // Calcutta switch block (nil = no fork, 0 = already on calcutta) - JaipurBlock *big.Int `json:"jaipurBlock"` // Jaipur switch block (nil = no fork, 0 = already on jaipur) - DelhiBlock *big.Int `json:"delhiBlock"` // Delhi switch block (nil = no fork, 0 = already on delhi) + JaipurBlock *big.Int `json:"jaipurBlock"` // Jaipur switch block (nil = no fork, 0 = already on jaipur) + DelhiBlock *big.Int `json:"delhiBlock"` // Delhi switch block (nil = no fork, 0 = already on delhi) + IndoreBlock *big.Int `json:"indoreBlock"` // Indore switch block (nil = no fork, 0 = already on indore) - IndoreBlock *big.Int `json:"indoreBlock"` // Indore switch block (nil = no fork, 0 = already on indore) StateSyncConfirmationDelay map[string]uint64 `json:"stateSyncConfirmationDelay"` // StateSync Confirmation Delay, in seconds, to calculate `to` sprints sprints @@ -504,14 +503,6 @@ func (c *BorConfig) IsDelhi(number uint64) bool { return isForked(c.DelhiBlock, number) } -func (c *BorConfig) IsCalcutta(number uint64) bool { - return isForked(c.CalcuttaBlock, number) -} - -func (c *BorConfig) IsOnCalcutta(number *big.Int) bool { - return numEqual(c.CalcuttaBlock, number) -} - func (c *BorConfig) IsIndore(number uint64) bool { return isForked(c.IndoreBlock, number) } diff --git a/params/chainspecs/bor-devnet.json b/params/chainspecs/bor-devnet.json index 3f4c306f690..376663aa360 100644 --- a/params/chainspecs/bor-devnet.json +++ b/params/chainspecs/bor-devnet.json @@ -22,7 +22,7 @@ "0": 4 }, "sprint": { - "0":16 + "0": 16 }, "backupMultiplier": { "0": 5 @@ -41,8 +41,7 @@ } }, "jaipurBlock": 0, - "delhiBlock":0, - "calcuttaBlock": 30, + "delhiBlock": 0, "indoreBlock": 0 } } diff --git a/params/chainspecs/bor-mainnet.json b/params/chainspecs/bor-mainnet.json index baf0dc4b9aa..87a22d389b3 100644 --- a/params/chainspecs/bor-mainnet.json +++ b/params/chainspecs/bor-mainnet.json @@ -53,7 +53,6 @@ } } }, - "calcuttaBlock": 22156660, "jaipurBlock": 23850000, "delhiBlock": 38189056, "indoreBlock": 44934656 diff --git a/params/chainspecs/mumbai.json b/params/chainspecs/mumbai.json index 7ac40ef9bf7..3bd9d8ba6c7 100644 --- a/params/chainspecs/mumbai.json +++ b/params/chainspecs/mumbai.json @@ -47,7 +47,6 @@ } } }, - "calcuttaBlock": 22244000, "jaipurBlock": 22770000, "delhiBlock": 29638656, "indoreBlock": 37075456 From 2294c8c66c5539782297e25e488265559e2c3557 Mon Sep 17 00:00:00 2001 From: Giulio rebuffo Date: Thu, 5 Oct 2023 18:30:19 +0200 Subject: [PATCH 11/14] EthereumExecutionService in MockSentry (#8373) Now we use the ethereum execution service directly: * Changed sig of InsertChain * Use of the service in case of PoS --- accounts/abi/bind/backends/simulated.go | 2 +- cl/beacon/handler/blocks.go | 1 - cmd/pics/state.go | 4 +- cmd/rpcdaemon/rpcdaemontest/test_util.go | 8 +- consensus/aura/aura_test.go | 2 +- consensus/clique/clique_test.go | 4 +- consensus/clique/snapshot_test.go | 4 +- core/block_validator_test.go | 4 +- core/state/database_test.go | 54 ++--- eth/gasprice/gasprice_test.go | 2 +- eth/protocols/eth/handler_test.go | 2 +- tests/block_test_util.go | 17 +- tests/statedb_chain_test.go | 10 +- .../statedb_insert_chain_transaction_test.go | 59 +++-- turbo/execution/eth1/inserters.go | 1 + turbo/jsonrpc/call_traces_test.go | 12 +- turbo/jsonrpc/erigon_receipts_test.go | 2 +- turbo/jsonrpc/eth_call_test.go | 2 +- turbo/jsonrpc/eth_system_test.go | 2 +- turbo/jsonrpc/txpool_api_test.go | 2 +- turbo/snapshotsync/freezeblocks/dump_test.go | 2 +- turbo/stages/blockchain_test.go | 111 +++++----- turbo/stages/chain_makers_test.go | 11 +- turbo/stages/genesis_test.go | 2 +- turbo/stages/mock/mock_sentry.go | 204 +++++++++--------- 25 files changed, 273 insertions(+), 251 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 9ec89a6fb63..9b46a7d6f77 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -148,7 +148,7 @@ func (b *SimulatedBackend) Commit() { Headers: []*types.Header{b.pendingHeader}, Blocks: []*types.Block{b.pendingBlock}, TopBlock: b.pendingBlock, - }, nil); err != nil { + }); err != nil { panic(err) } //nolint:prealloc diff --git a/cl/beacon/handler/blocks.go b/cl/beacon/handler/blocks.go index a6d4d2e75d6..806baf66e00 100644 --- a/cl/beacon/handler/blocks.go +++ b/cl/beacon/handler/blocks.go @@ -82,7 +82,6 @@ func (a *ApiHandler) getBlock(r *http.Request) (data any, finalized *bool, versi blockId, err = blockIdFromRequest(r) if err != nil { - fmt.Println("A") httpStatus = http.StatusBadRequest return } diff --git a/cmd/pics/state.go b/cmd/pics/state.go index 7c999e4f878..1c387162d61 100644 --- a/cmd/pics/state.go +++ b/cmd/pics/state.go @@ -430,13 +430,13 @@ func initialState1() error { // BLOCKS for i := 0; i < chain.Length(); i++ { - if err = m2.InsertChain(chain.Slice(i, i+1), nil); err != nil { + if err = m2.InsertChain(chain.Slice(i, i+1)); err != nil { return err } if err = stateDatabaseComparison(m.DB, m2.DB, i+1); err != nil { return err } - if err = m.InsertChain(chain.Slice(i, i+1), nil); err != nil { + if err = m.InsertChain(chain.Slice(i, i+1)); err != nil { return err } } diff --git a/cmd/rpcdaemon/rpcdaemontest/test_util.go b/cmd/rpcdaemon/rpcdaemontest/test_util.go index 8dfe4af3f94..ecff7012c16 100644 --- a/cmd/rpcdaemon/rpcdaemontest/test_util.go +++ b/cmd/rpcdaemon/rpcdaemontest/test_util.go @@ -102,10 +102,10 @@ func CreateTestSentry(t *testing.T) (*mock.MockSentry, *core.ChainPack, []*core. t.Fatal(err) } - if err = m.InsertChain(orphanedChain, nil); err != nil { + if err = m.InsertChain(orphanedChain); err != nil { t.Fatal(err) } - if err = m.InsertChain(chain, nil); err != nil { + if err = m.InsertChain(chain); err != nil { t.Fatal(err) } @@ -428,7 +428,7 @@ func CreateTestSentryForTraces(t *testing.T) *mock.MockSentry { t.Fatalf("generate blocks: %v", err) } - if err := m.InsertChain(chain, nil); err != nil { + if err := m.InsertChain(chain); err != nil { t.Fatalf("failed to insert into chain: %v", err) } return m @@ -534,7 +534,7 @@ func CreateTestSentryForTracesCollision(t *testing.T) *mock.MockSentry { t.Fatalf("generate blocks: %v", err) } // Import the canonical chain - if err := m.InsertChain(chain, nil); err != nil { + if err := m.InsertChain(chain); err != nil { t.Fatalf("failed to insert into chain: %v", err) } diff --git a/consensus/aura/aura_test.go b/consensus/aura/aura_test.go index 401cae8a92d..1772905f68a 100644 --- a/consensus/aura/aura_test.go +++ b/consensus/aura/aura_test.go @@ -58,7 +58,7 @@ func TestEmptyBlock(t *testing.T) { blocks[0] = block chain := &core.ChainPack{Headers: headers, Blocks: blocks, Receipts: receipts, TopBlock: block} - err = m.InsertChain(chain, nil) + err = m.InsertChain(chain) require.NoError(err) } diff --git a/consensus/clique/clique_test.go b/consensus/clique/clique_test.go index c69bbf349af..87167c13428 100644 --- a/consensus/clique/clique_test.go +++ b/consensus/clique/clique_test.go @@ -106,7 +106,7 @@ func TestReimportMirroredState(t *testing.T) { } // Insert the first two blocks and make sure the chain is valid - if err := m.InsertChain(chain.Slice(0, 2), nil); err != nil { + if err := m.InsertChain(chain.Slice(0, 2)); err != nil { t.Fatalf("failed to insert initial blocks: %v", err) } if err := m.DB.View(m.Ctx, func(tx kv.Tx) error { @@ -123,7 +123,7 @@ func TestReimportMirroredState(t *testing.T) { // Simulate a crash by creating a new chain on top of the database, without // flushing the dirty states out. Insert the last block, triggering a sidechain // reimport. - if err := m.InsertChain(chain.Slice(2, chain.Length()), nil); err != nil { + if err := m.InsertChain(chain.Slice(2, chain.Length())); err != nil { t.Fatalf("failed to insert final block: %v", err) } if err := m.DB.View(m.Ctx, func(tx kv.Tx) error { diff --git a/consensus/clique/snapshot_test.go b/consensus/clique/snapshot_test.go index bfdaa4e1d09..0f487177bfc 100644 --- a/consensus/clique/snapshot_test.go +++ b/consensus/clique/snapshot_test.go @@ -477,7 +477,7 @@ func TestClique(t *testing.T) { chainX.Headers[k] = b.Header() } chainX.TopBlock = batches[j][len(batches[j])-1] - if err = m.InsertChain(chainX, nil); err != nil { + if err = m.InsertChain(chainX); err != nil { t.Errorf("test %d: failed to import batch %d, %v", i, j, err) failed = true break @@ -493,7 +493,7 @@ func TestClique(t *testing.T) { chainX.Headers[k] = b.Header() } chainX.TopBlock = batches[len(batches)-1][len(batches[len(batches)-1])-1] - err = m.InsertChain(chainX, nil) + err = m.InsertChain(chainX) if tt.failure != nil && err == nil { t.Errorf("test %d: expected failure", i) } diff --git a/core/block_validator_test.go b/core/block_validator_test.go index 0548eda0c89..2a666d1f927 100644 --- a/core/block_validator_test.go +++ b/core/block_validator_test.go @@ -62,7 +62,7 @@ func TestHeaderVerification(t *testing.T) { }); err != nil { panic(err) } - if err = m.InsertChain(chain.Slice(i, i+1), nil); err != nil { + if err = m.InsertChain(chain.Slice(i, i+1)); err != nil { t.Fatalf("test %d: error inserting the block: %v", i, err) } @@ -104,7 +104,7 @@ func TestHeaderWithSealVerification(t *testing.T) { }); err != nil { panic(err) } - if err = m.InsertChain(chain.Slice(i, i+1), nil); err != nil { + if err = m.InsertChain(chain.Slice(i, i+1)); err != nil { t.Fatalf("test %d: error inserting the block: %v", i, err) } diff --git a/core/state/database_test.go b/core/state/database_test.go index ce50eb03bcd..0211cf9bb13 100644 --- a/core/state/database_test.go +++ b/core/state/database_test.go @@ -143,7 +143,7 @@ func TestCreate2Revive(t *testing.T) { require.NoError(t, err) // BLOCK 1 - if err = m.InsertChain(chain.Slice(0, 1), nil); err != nil { + if err = m.InsertChain(chain.Slice(0, 1)); err != nil { t.Fatal(err) } @@ -157,7 +157,7 @@ func TestCreate2Revive(t *testing.T) { require.NoError(t, err) // BLOCK 2 - if err = m.InsertChain(chain.Slice(1, 2), nil); err != nil { + if err = m.InsertChain(chain.Slice(1, 2)); err != nil { t.Fatal(err) } @@ -179,7 +179,7 @@ func TestCreate2Revive(t *testing.T) { require.NoError(t, err) // BLOCK 3 - if err = m.InsertChain(chain.Slice(2, 3), nil); err != nil { + if err = m.InsertChain(chain.Slice(2, 3)); err != nil { t.Fatal(err) } err = m.DB.View(context.Background(), func(tx kv.Tx) error { @@ -192,7 +192,7 @@ func TestCreate2Revive(t *testing.T) { require.NoError(t, err) // BLOCK 4 - if err = m.InsertChain(chain.Slice(3, 4), nil); err != nil { + if err = m.InsertChain(chain.Slice(3, 4)); err != nil { t.Fatal(err) } err = m.DB.View(context.Background(), func(tx kv.Tx) error { @@ -349,7 +349,7 @@ func TestCreate2Polymorth(t *testing.T) { require.NoError(t, err) // BLOCK 1 - if err = m.InsertChain(chain.Slice(0, 1), nil); err != nil { + if err = m.InsertChain(chain.Slice(0, 1)); err != nil { t.Fatal(err) } @@ -364,7 +364,7 @@ func TestCreate2Polymorth(t *testing.T) { require.NoError(t, err) // BLOCK 2 - if err = m.InsertChain(chain.Slice(1, 2), nil); err != nil { + if err = m.InsertChain(chain.Slice(1, 2)); err != nil { t.Fatal(err) } @@ -384,7 +384,7 @@ func TestCreate2Polymorth(t *testing.T) { require.NoError(t, err) // BLOCK 3 - if err = m.InsertChain(chain.Slice(2, 3), nil); err != nil { + if err = m.InsertChain(chain.Slice(2, 3)); err != nil { t.Fatal(err) } err = m.DB.View(context.Background(), func(tx kv.Tx) error { @@ -397,7 +397,7 @@ func TestCreate2Polymorth(t *testing.T) { require.NoError(t, err) // BLOCK 4 - if err = m.InsertChain(chain.Slice(3, 4), nil); err != nil { + if err = m.InsertChain(chain.Slice(3, 4)); err != nil { t.Fatal(err) } err = m.DB.View(context.Background(), func(tx kv.Tx) error { @@ -417,7 +417,7 @@ func TestCreate2Polymorth(t *testing.T) { require.NoError(t, err) // BLOCK 5 - if err = m.InsertChain(chain.Slice(4, 5), nil); err != nil { + if err = m.InsertChain(chain.Slice(4, 5)); err != nil { t.Fatal(err) } err = m.DB.View(context.Background(), func(tx kv.Tx) error { @@ -534,7 +534,7 @@ func TestReorgOverSelfDestruct(t *testing.T) { }) require.NoError(t, err) // BLOCK 1 - if err = m.InsertChain(chain.Slice(0, 1), nil); err != nil { + if err = m.InsertChain(chain.Slice(0, 1)); err != nil { t.Fatal(err) } @@ -553,7 +553,7 @@ func TestReorgOverSelfDestruct(t *testing.T) { require.NoError(t, err) // BLOCKS 2 + 3 - if err = m.InsertChain(chain.Slice(1, chain.Length()), nil); err != nil { + if err = m.InsertChain(chain.Slice(1, chain.Length())); err != nil { t.Fatal(err) } @@ -567,7 +567,7 @@ func TestReorgOverSelfDestruct(t *testing.T) { require.NoError(t, err) // REORG of block 2 and 3, and insert new (empty) BLOCK 2, 3, and 4 - if err = m.InsertChain(longerChain.Slice(1, 4), nil); err != nil { + if err = m.InsertChain(longerChain.Slice(1, 4)); err != nil { t.Fatal(err) } err = m.DB.View(context.Background(), func(tx kv.Tx) error { @@ -675,7 +675,7 @@ func TestReorgOverStateChange(t *testing.T) { require.NoError(t, err) // BLOCK 1 - if err = m.InsertChain(chain.Slice(0, 1), nil); err != nil { + if err = m.InsertChain(chain.Slice(0, 1)); err != nil { t.Fatal(err) } @@ -694,12 +694,12 @@ func TestReorgOverStateChange(t *testing.T) { require.NoError(t, err) // BLOCK 2 - if err = m.InsertChain(chain.Slice(1, chain.Length()), nil); err != nil { + if err = m.InsertChain(chain.Slice(1, chain.Length())); err != nil { t.Fatal(err) } // REORG of block 2 and 3, and insert new (empty) BLOCK 2, 3, and 4 - if err = m.InsertChain(longerChain.Slice(1, 3), nil); err != nil { + if err = m.InsertChain(longerChain.Slice(1, 3)); err != nil { t.Fatal(err) } err = m.DB.View(context.Background(), func(tx kv.Tx) error { @@ -802,7 +802,7 @@ func TestCreateOnExistingStorage(t *testing.T) { require.NoError(t, err) // BLOCK 1 - if err = m.InsertChain(chain.Slice(0, 1), nil); err != nil { + if err = m.InsertChain(chain.Slice(0, 1)); err != nil { t.Fatal(err) } @@ -938,7 +938,7 @@ func TestEip2200Gas(t *testing.T) { require.NoError(t, err) // BLOCK 1 - if err = m.InsertChain(chain.Slice(0, 1), nil); err != nil { + if err = m.InsertChain(chain.Slice(0, 1)); err != nil { t.Fatal(err) } @@ -1024,7 +1024,7 @@ func TestWrongIncarnation(t *testing.T) { require.NoError(t, err) // BLOCK 1 - if err = m.InsertChain(chain.Slice(0, 1), nil); err != nil { + if err = m.InsertChain(chain.Slice(0, 1)); err != nil { t.Fatal(err) } @@ -1051,7 +1051,7 @@ func TestWrongIncarnation(t *testing.T) { require.NoError(t, err) // BLOCKS 2 - if err = m.InsertChain(chain.Slice(1, 2), nil); err != nil { + if err = m.InsertChain(chain.Slice(1, 2)); err != nil { t.Fatal(err) } err = m.DB.View(context.Background(), func(tx kv.Tx) error { @@ -1169,12 +1169,12 @@ func TestWrongIncarnation2(t *testing.T) { require.NoError(t, err) // BLOCK 1 - if err = m.InsertChain(chain.Slice(0, 1), nil); err != nil { + if err = m.InsertChain(chain.Slice(0, 1)); err != nil { t.Fatal(err) } // BLOCKS 2 - if err = m.InsertChain(chain.Slice(1, chain.Length()), nil); err != nil { + if err = m.InsertChain(chain.Slice(1, chain.Length())); err != nil { t.Fatal(err) } @@ -1199,7 +1199,7 @@ func TestWrongIncarnation2(t *testing.T) { }) require.NoError(t, err) // REORG of block 2 and 3, and insert new (empty) BLOCK 2, 3, and 4 - if err = m.InsertChain(longerChain.Slice(1, longerChain.Length()), nil); err != nil { + if err = m.InsertChain(longerChain.Slice(1, longerChain.Length())); err != nil { t.Fatal(err) } @@ -1472,7 +1472,7 @@ func TestRecreateAndRewind(t *testing.T) { } // BLOCKS 1 and 2 - if err = m.InsertChain(chain.Slice(0, 2), nil); err != nil { + if err = m.InsertChain(chain.Slice(0, 2)); err != nil { t.Fatal(err) } @@ -1493,7 +1493,7 @@ func TestRecreateAndRewind(t *testing.T) { require.NoError(t, err) // Block 3 and 4 - if err = m.InsertChain(chain.Slice(2, chain.Length()), nil); err != nil { + if err = m.InsertChain(chain.Slice(2, chain.Length())); err != nil { t.Fatal(err) } err = m.DB.View(context.Background(), func(tx kv.Tx) error { @@ -1512,7 +1512,7 @@ func TestRecreateAndRewind(t *testing.T) { require.NoError(t, err) // Reorg - if err = m.InsertChain(longerChain, nil); err != nil { + if err = m.InsertChain(longerChain); err != nil { t.Fatal(err) } err = m.DB.View(context.Background(), func(tx kv.Tx) error { @@ -1572,10 +1572,10 @@ func TestTxLookupUnwind(t *testing.T) { if err != nil { t.Fatal(err) } - if err = m.InsertChain(chain1, nil); err != nil { + if err = m.InsertChain(chain1); err != nil { t.Fatal(err) } - if err = m.InsertChain(chain2, nil); err != nil { + if err = m.InsertChain(chain2); err != nil { t.Fatal(err) } var count uint64 diff --git a/eth/gasprice/gasprice_test.go b/eth/gasprice/gasprice_test.go index 501c2bc3264..96184ffc296 100644 --- a/eth/gasprice/gasprice_test.go +++ b/eth/gasprice/gasprice_test.go @@ -118,7 +118,7 @@ func newTestBackend(t *testing.T) *testBackend { t.Error(err) } // Construct testing chain - if err = m.InsertChain(chain, nil); err != nil { + if err = m.InsertChain(chain); err != nil { t.Error(err) } return &testBackend{db: m.DB, cfg: params.TestChainConfig, blockReader: m.BlockReader} diff --git a/eth/protocols/eth/handler_test.go b/eth/protocols/eth/handler_test.go index a3cb2c50dcb..a373858c043 100644 --- a/eth/protocols/eth/handler_test.go +++ b/eth/protocols/eth/handler_test.go @@ -137,7 +137,7 @@ func mockWithGenerator(t *testing.T, blocks int, generator func(int, *core.Block }, testKey, false) if blocks > 0 { chain, _ := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, blocks, generator) - err := m.InsertChain(chain, nil) + err := m.InsertChain(chain) require.NoError(t, err) } return m diff --git a/tests/block_test_util.go b/tests/block_test_util.go index 11c6856aab0..4b54b816393 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -132,16 +132,16 @@ func (bt *BlockTest) Run(t *testing.T, checkStateRoot bool) error { return fmt.Errorf("genesis block state root does not match test: computed=%x, test=%x", m.Genesis.Root().Bytes()[:6], bt.json.Genesis.StateRoot[:6]) } - tx, err := m.DB.BeginRw(m.Ctx) + validBlocks, err := bt.insertBlocks(m) if err != nil { return err } - defer tx.Rollback() - validBlocks, err := bt.insertBlocks(m, tx) + tx, err := m.DB.BeginRw(m.Ctx) if err != nil { return err } + defer tx.Rollback() cmlast := rawdb.ReadHeadBlockHash(tx) if libcommon.Hash(bt.json.BestBlock) != cmlast { @@ -187,7 +187,7 @@ See https://github.com/ethereum/tests/wiki/Blockchain-Tests-II expected we are expected to ignore it and continue processing and then validate the post state. */ -func (bt *BlockTest) insertBlocks(m *mock.MockSentry, tx kv.RwTx) ([]btBlock, error) { +func (bt *BlockTest) insertBlocks(m *mock.MockSentry) ([]btBlock, error) { validBlocks := make([]btBlock, 0) // insert the test blocks, which will execute all transaction for bi, b := range bt.json.Blocks { @@ -202,7 +202,7 @@ func (bt *BlockTest) insertBlocks(m *mock.MockSentry, tx kv.RwTx) ([]btBlock, er // RLP decoding worked, try to insert into chain: chain := &core.ChainPack{Blocks: []*types.Block{cb}, Headers: []*types.Header{cb.Header()}, TopBlock: cb} - err1 := m.InsertChain(chain, tx) + err1 := m.InsertChain(chain) if err1 != nil { if b.BlockHeader == nil { continue // OK - block is supposed to be invalid, continue with next block @@ -210,7 +210,12 @@ func (bt *BlockTest) insertBlocks(m *mock.MockSentry, tx kv.RwTx) ([]btBlock, er return nil, fmt.Errorf("block #%v insertion into chain failed: %w", cb.Number(), err1) } } else if b.BlockHeader == nil { - canonical, cErr := bt.br.CanonicalHash(context.Background(), tx, cb.NumberU64()) + roTx, err := m.DB.BeginRo(m.Ctx) + if err != nil { + return nil, err + } + defer roTx.Rollback() + canonical, cErr := bt.br.CanonicalHash(context.Background(), roTx, cb.NumberU64()) if cErr != nil { return nil, cErr } diff --git a/tests/statedb_chain_test.go b/tests/statedb_chain_test.go index 1334199e299..ba400daba03 100644 --- a/tests/statedb_chain_test.go +++ b/tests/statedb_chain_test.go @@ -111,16 +111,22 @@ func TestSelfDestructReceive(t *testing.T) { if st.Exist(contractAddress) { t.Error("expected contractAddress to not exist before block 0", contractAddress.String()) } + tx.Rollback() // BLOCK 1 - if err = m.InsertChain(chain.Slice(0, 1), tx); err != nil { + if err = m.InsertChain(chain.Slice(0, 1)); err != nil { t.Fatal(err) } // BLOCK 2 - if err = m.InsertChain(chain.Slice(1, 2), tx); err != nil { + if err = m.InsertChain(chain.Slice(1, 2)); err != nil { t.Fatal(err) } + tx, err = m.DB.BeginRw(context.Background()) + if err != nil { + panic(err) + } + defer tx.Rollback() // If we got this far, the newly created blockchain (with empty trie cache) loaded trie from the database // and that means that the state of the accounts written in the first block was correct. // This test checks that the storage root of the account is properly set to the root of the empty tree diff --git a/tests/statedb_insert_chain_transaction_test.go b/tests/statedb_insert_chain_transaction_test.go index 1f8bc4ff7ac..c0f00ad2fa6 100644 --- a/tests/statedb_insert_chain_transaction_test.go +++ b/tests/statedb_insert_chain_transaction_test.go @@ -54,7 +54,7 @@ func TestInsertIncorrectStateRootDifferentAccounts(t *testing.T) { incorrectBlock := types.NewBlock(&incorrectHeader, chain.Blocks[0].Transactions(), chain.Blocks[0].Uncles(), chain.Receipts[0], nil) incorrectChain := &core.ChainPack{Blocks: []*types.Block{incorrectBlock}, Headers: []*types.Header{&incorrectHeader}, TopBlock: incorrectBlock} - if err = m.InsertChain(incorrectChain, nil); err == nil { + if err = m.InsertChain(incorrectChain); err == nil { t.Fatal("should fail") } @@ -69,14 +69,13 @@ func TestInsertIncorrectStateRootDifferentAccounts(t *testing.T) { t.Fatal(err) } + if err = m.InsertChain(chain); err != nil { + t.Fatal(err) + } tx, err := m.DB.BeginRw(context.Background()) require.NoError(t, err) defer tx.Rollback() - if err = m.InsertChain(chain, tx); err != nil { - t.Fatal(err) - } - st := state.New(m.NewStateReader(tx)) if !st.Exist(to) { t.Error("expected account to exist") @@ -122,7 +121,7 @@ func TestInsertIncorrectStateRootSameAccount(t *testing.T) { incorrectBlock := types.NewBlock(&incorrectHeader, chain.Blocks[0].Transactions(), chain.Blocks[0].Uncles(), chain.Receipts[0], nil) incorrectChain := &core.ChainPack{Blocks: []*types.Block{incorrectBlock}, Headers: []*types.Header{&incorrectHeader}, TopBlock: incorrectBlock} - if err = m.InsertChain(incorrectChain, nil); err == nil { + if err = m.InsertChain(incorrectChain); err == nil { t.Fatal("should fail") } @@ -137,7 +136,7 @@ func TestInsertIncorrectStateRootSameAccount(t *testing.T) { t.Fatal(err) } - if err = m.InsertChain(chain, nil); err != nil { + if err = m.InsertChain(chain); err != nil { t.Fatal(err) } @@ -184,7 +183,7 @@ func TestInsertIncorrectStateRootSameAccountSameAmount(t *testing.T) { incorrectBlock := types.NewBlock(&incorrectHeader, chain.Blocks[0].Transactions(), chain.Blocks[0].Uncles(), chain.Receipts[0], nil) incorrectChain := &core.ChainPack{Blocks: []*types.Block{incorrectBlock}, Headers: []*types.Header{&incorrectHeader}, TopBlock: incorrectBlock} - if err = m.InsertChain(incorrectChain, nil); err == nil { + if err = m.InsertChain(incorrectChain); err == nil { t.Fatal("should fail") } @@ -199,7 +198,7 @@ func TestInsertIncorrectStateRootSameAccountSameAmount(t *testing.T) { t.Fatal(err) } - if err = m.InsertChain(chain, nil); err != nil { + if err = m.InsertChain(chain); err != nil { t.Fatal(err) } @@ -246,7 +245,7 @@ func TestInsertIncorrectStateRootAllFundsRoot(t *testing.T) { incorrectBlock := types.NewBlock(&incorrectHeader, chain.Blocks[0].Transactions(), chain.Blocks[0].Uncles(), chain.Receipts[0], nil) incorrectChain := &core.ChainPack{Blocks: []*types.Block{incorrectBlock}, Headers: []*types.Header{&incorrectHeader}, TopBlock: incorrectBlock} - if err = m.InsertChain(incorrectChain, nil); err == nil { + if err = m.InsertChain(incorrectChain); err == nil { t.Fatal("should fail") } @@ -261,7 +260,7 @@ func TestInsertIncorrectStateRootAllFundsRoot(t *testing.T) { t.Fatal(err) } - if err = m.InsertChain(chain, nil); err != nil { + if err = m.InsertChain(chain); err != nil { t.Fatal(err) } @@ -308,7 +307,7 @@ func TestInsertIncorrectStateRootAllFunds(t *testing.T) { incorrectBlock := types.NewBlock(&incorrectHeader, chain.Blocks[0].Transactions(), chain.Blocks[0].Uncles(), chain.Receipts[0], nil) incorrectChain := &core.ChainPack{Blocks: []*types.Block{incorrectBlock}, Headers: []*types.Header{&incorrectHeader}, TopBlock: incorrectBlock} - if err = m.InsertChain(incorrectChain, nil); err == nil { + if err = m.InsertChain(incorrectChain); err == nil { t.Fatal("should fail") } @@ -323,7 +322,7 @@ func TestInsertIncorrectStateRootAllFunds(t *testing.T) { t.Fatal(err) } - if err = m.InsertChain(chain, nil); err != nil { + if err = m.InsertChain(chain); err != nil { t.Fatal(err) } @@ -368,7 +367,7 @@ func TestAccountDeployIncorrectRoot(t *testing.T) { } // BLOCK 1 - if err = m.InsertChain(chain.Slice(0, 1), nil); err != nil { + if err = m.InsertChain(chain.Slice(0, 1)); err != nil { t.Fatal(err) } err = m.DB.View(context.Background(), func(tx kv.Tx) error { @@ -390,7 +389,7 @@ func TestAccountDeployIncorrectRoot(t *testing.T) { incorrectChain := &core.ChainPack{Blocks: []*types.Block{incorrectBlock}, Headers: []*types.Header{&incorrectHeader}, TopBlock: incorrectBlock} // BLOCK 2 - INCORRECT - if err = m.InsertChain(incorrectChain, nil); err == nil { + if err = m.InsertChain(incorrectChain); err == nil { t.Fatal("should fail") } @@ -408,7 +407,7 @@ func TestAccountDeployIncorrectRoot(t *testing.T) { require.NoError(t, err) // BLOCK 2 - CORRECT - if err = m.InsertChain(chain.Slice(1, 2), nil); err != nil { + if err = m.InsertChain(chain.Slice(1, 2)); err != nil { t.Fatal(err) } @@ -454,7 +453,7 @@ func TestAccountCreateIncorrectRoot(t *testing.T) { } // BLOCK 1 - if err = m.InsertChain(chain.Slice(0, 1), nil); err != nil { + if err = m.InsertChain(chain.Slice(0, 1)); err != nil { t.Fatal(err) } @@ -473,7 +472,7 @@ func TestAccountCreateIncorrectRoot(t *testing.T) { require.NoError(t, err) // BLOCK 2 - if err = m.InsertChain(chain.Slice(1, 2), nil); err != nil { + if err = m.InsertChain(chain.Slice(1, 2)); err != nil { t.Fatal(err) } err = m.DB.View(context.Background(), func(tx kv.Tx) error { @@ -496,12 +495,12 @@ func TestAccountCreateIncorrectRoot(t *testing.T) { incorrectBlock := types.NewBlock(&incorrectHeader, chain.Blocks[2].Transactions(), chain.Blocks[2].Uncles(), chain.Receipts[2], nil) incorrectChain := &core.ChainPack{Blocks: []*types.Block{incorrectBlock}, Headers: []*types.Header{&incorrectHeader}, TopBlock: incorrectBlock} - if err = m.InsertChain(incorrectChain, nil); err == nil { + if err = m.InsertChain(incorrectChain); err == nil { t.Fatal("should fail") } // BLOCK 3 - if err = m.InsertChain(chain.Slice(2, 3), nil); err != nil { + if err = m.InsertChain(chain.Slice(2, 3)); err != nil { t.Fatal(err) } } @@ -538,7 +537,7 @@ func TestAccountUpdateIncorrectRoot(t *testing.T) { } // BLOCK 1 - if err = m.InsertChain(chain.Slice(0, 1), nil); err != nil { + if err = m.InsertChain(chain.Slice(0, 1)); err != nil { t.Fatal(err) } @@ -557,7 +556,7 @@ func TestAccountUpdateIncorrectRoot(t *testing.T) { require.NoError(t, err) // BLOCK 2 - if err = m.InsertChain(chain.Slice(1, 2), nil); err != nil { + if err = m.InsertChain(chain.Slice(1, 2)); err != nil { t.Fatal(err) } @@ -575,7 +574,7 @@ func TestAccountUpdateIncorrectRoot(t *testing.T) { require.NoError(t, err) // BLOCK 3 - if err = m.InsertChain(chain.Slice(2, 3), nil); err != nil { + if err = m.InsertChain(chain.Slice(2, 3)); err != nil { t.Fatal(err) } @@ -585,12 +584,12 @@ func TestAccountUpdateIncorrectRoot(t *testing.T) { incorrectBlock := types.NewBlock(&incorrectHeader, chain.Blocks[3].Transactions(), chain.Blocks[3].Uncles(), chain.Receipts[3], nil) incorrectChain := &core.ChainPack{Blocks: []*types.Block{incorrectBlock}, Headers: []*types.Header{&incorrectHeader}, TopBlock: incorrectBlock} - if err = m.InsertChain(incorrectChain, nil); err == nil { + if err = m.InsertChain(incorrectChain); err == nil { t.Fatal("should fail") } // BLOCK 4 - if err = m.InsertChain(chain.Slice(3, 4), nil); err != nil { + if err = m.InsertChain(chain.Slice(3, 4)); err != nil { t.Fatal(err) } } @@ -627,7 +626,7 @@ func TestAccountDeleteIncorrectRoot(t *testing.T) { } // BLOCK 1 - if err = m.InsertChain(chain.Slice(0, 1), nil); err != nil { + if err = m.InsertChain(chain.Slice(0, 1)); err != nil { t.Fatal(err) } @@ -645,7 +644,7 @@ func TestAccountDeleteIncorrectRoot(t *testing.T) { require.NoError(t, err) // BLOCK 2 - if err = m.InsertChain(chain.Slice(1, 2), nil); err != nil { + if err = m.InsertChain(chain.Slice(1, 2)); err != nil { t.Fatal(err) } @@ -663,7 +662,7 @@ func TestAccountDeleteIncorrectRoot(t *testing.T) { require.NoError(t, err) // BLOCK 3 - if err = m.InsertChain(chain.Slice(2, 3), nil); err != nil { + if err = m.InsertChain(chain.Slice(2, 3)); err != nil { t.Fatal(err) } @@ -672,12 +671,12 @@ func TestAccountDeleteIncorrectRoot(t *testing.T) { incorrectHeader.Root = chain.Headers[1].Root incorrectBlock := types.NewBlock(&incorrectHeader, chain.Blocks[3].Transactions(), chain.Blocks[3].Uncles(), chain.Receipts[3], nil) incorrectChain := &core.ChainPack{Blocks: []*types.Block{incorrectBlock}, Headers: []*types.Header{&incorrectHeader}, TopBlock: incorrectBlock} - if err = m.InsertChain(incorrectChain, nil); err == nil { + if err = m.InsertChain(incorrectChain); err == nil { t.Fatal("should fail") } // BLOCK 4 - if err = m.InsertChain(chain.Slice(3, 4), nil); err != nil { + if err = m.InsertChain(chain.Slice(3, 4)); err != nil { t.Fatal(err) } } diff --git a/turbo/execution/eth1/inserters.go b/turbo/execution/eth1/inserters.go index efb18065803..368a75a3f07 100644 --- a/turbo/execution/eth1/inserters.go +++ b/turbo/execution/eth1/inserters.go @@ -34,6 +34,7 @@ func (e *EthereumExecutionModule) InsertBlocks(ctx context.Context, req *executi if err != nil || parentTd == nil { return nil, fmt.Errorf("parent's total difficulty not found with hash %x and height %d: %v", header.ParentHash, header.Number.Uint64()-1, err) } + // Sum TDs. td := parentTd.Add(parentTd, header.Difficulty) if err := rawdb.WriteHeader(tx, header); err != nil { diff --git a/turbo/jsonrpc/call_traces_test.go b/turbo/jsonrpc/call_traces_test.go index fe831a8188c..d78714682dd 100644 --- a/turbo/jsonrpc/call_traces_test.go +++ b/turbo/jsonrpc/call_traces_test.go @@ -52,7 +52,7 @@ func TestCallTraceOneByOne(t *testing.T) { api := NewTraceAPI(newBaseApiForTest(m), m.DB, &httpcfg.HttpCfg{}) // Insert blocks 1 by 1, to tirgget possible "off by one" errors for i := 0; i < chain.Length(); i++ { - if err = m.InsertChain(chain.Slice(i, i+1), nil); err != nil { + if err = m.InsertChain(chain.Slice(i, i+1)); err != nil { t.Fatalf("inserting chain: %v", err) } } @@ -96,7 +96,7 @@ func TestCallTraceUnwind(t *testing.T) { api := NewTraceAPI(newBaseApiForTest(m), m.DB, &httpcfg.HttpCfg{}) - if err = m.InsertChain(chainA, nil); err != nil { + if err = m.InsertChain(chainA); err != nil { t.Fatalf("inserting chainA: %v", err) } stream := jsoniter.ConfigDefault.BorrowStream(nil) @@ -115,7 +115,7 @@ func TestCallTraceUnwind(t *testing.T) { } assert.Equal(t, []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, blockNumbersFromTraces(t, stream.Buffer())) - if err = m.InsertChain(chainB.Slice(0, 12), nil); err != nil { + if err = m.InsertChain(chainB.Slice(0, 12)); err != nil { t.Fatalf("inserting chainB: %v", err) } stream.Reset(nil) @@ -130,7 +130,7 @@ func TestCallTraceUnwind(t *testing.T) { } assert.Equal(t, []int{1, 2, 3, 4, 5, 11, 12}, blockNumbersFromTraces(t, stream.Buffer())) - if err = m.InsertChain(chainB.Slice(12, 20), nil); err != nil { + if err = m.InsertChain(chainB.Slice(12, 20)); err != nil { t.Fatalf("inserting chainB: %v", err) } stream.Reset(nil) @@ -158,7 +158,7 @@ func TestFilterNoAddresses(t *testing.T) { api := NewTraceAPI(newBaseApiForTest(m), m.DB, &httpcfg.HttpCfg{}) // Insert blocks 1 by 1, to tirgget possible "off by one" errors for i := 0; i < chain.Length(); i++ { - if err = m.InsertChain(chain.Slice(i, i+1), nil); err != nil { + if err = m.InsertChain(chain.Slice(i, i+1)); err != nil { t.Fatalf("inserting chain: %v", err) } } @@ -205,7 +205,7 @@ func TestFilterAddressIntersection(t *testing.T) { }) require.NoError(t, err, "generate chain") - err = m.InsertChain(chain, nil) + err = m.InsertChain(chain) require.NoError(t, err, "inserting chain") fromBlock, toBlock := uint64(1), uint64(15) diff --git a/turbo/jsonrpc/erigon_receipts_test.go b/turbo/jsonrpc/erigon_receipts_test.go index 71e15c1e958..aa82a42234d 100644 --- a/turbo/jsonrpc/erigon_receipts_test.go +++ b/turbo/jsonrpc/erigon_receipts_test.go @@ -214,7 +214,7 @@ func mockWithGenerator(t *testing.T, blocks int, generator func(int, *core.Block }, testKey, false) if blocks > 0 { chain, _ := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, blocks, generator) - err := m.InsertChain(chain, nil) + err := m.InsertChain(chain) require.NoError(t, err) } return m diff --git a/turbo/jsonrpc/eth_call_test.go b/turbo/jsonrpc/eth_call_test.go index e1c4a6f3383..ae6b3edb4a9 100644 --- a/turbo/jsonrpc/eth_call_test.go +++ b/turbo/jsonrpc/eth_call_test.go @@ -524,7 +524,7 @@ func chainWithDeployedContract(t *testing.T) (*mock.MockSentry, libcommon.Addres t.Fatalf("generate blocks: %v", err) } - err = m.InsertChain(chain, nil) + err = m.InsertChain(chain) assert.NoError(t, err) tx, err := db.BeginRo(context.Background()) diff --git a/turbo/jsonrpc/eth_system_test.go b/turbo/jsonrpc/eth_system_test.go index f29dbc7b15b..5d261812dab 100644 --- a/turbo/jsonrpc/eth_system_test.go +++ b/turbo/jsonrpc/eth_system_test.go @@ -81,7 +81,7 @@ func createGasPriceTestKV(t *testing.T, chainSize int) *mock.MockSentry { t.Error(err) } // Construct testing chain - if err = m.InsertChain(chain, nil); err != nil { + if err = m.InsertChain(chain); err != nil { t.Error(err) } diff --git a/turbo/jsonrpc/txpool_api_test.go b/turbo/jsonrpc/txpool_api_test.go index e08ac9339e5..a21d30a3231 100644 --- a/turbo/jsonrpc/txpool_api_test.go +++ b/turbo/jsonrpc/txpool_api_test.go @@ -28,7 +28,7 @@ func TestTxPoolContent(t *testing.T) { b.SetCoinbase(libcommon.Address{1}) }) require.NoError(err) - err = m.InsertChain(chain, nil) + err = m.InsertChain(chain) require.NoError(err) ctx, conn := rpcdaemontest.CreateTestGrpcConn(t, m) diff --git a/turbo/snapshotsync/freezeblocks/dump_test.go b/turbo/snapshotsync/freezeblocks/dump_test.go index 62eb4a6cdb4..a7c3b95a8d1 100644 --- a/turbo/snapshotsync/freezeblocks/dump_test.go +++ b/turbo/snapshotsync/freezeblocks/dump_test.go @@ -271,7 +271,7 @@ func createDumpTestKV(t *testing.T, chainConfig *chain.Config, chainSize int) *m t.Fatal(err) } // Construct testing chain - if err = m.InsertChain(chain, nil); err != nil { + if err = m.InsertChain(chain); err != nil { t.Fatal(err) } diff --git a/turbo/stages/blockchain_test.go b/turbo/stages/blockchain_test.go index 183a457a880..4f639b56483 100644 --- a/turbo/stages/blockchain_test.go +++ b/turbo/stages/blockchain_test.go @@ -80,7 +80,7 @@ func newCanonical(t *testing.T, n int) *mock.MockSentry { // Full block-chain requested chain := makeBlockChain(m.Genesis, n, m, canonicalSeed) - if err := m.InsertChain(chain, nil); err != nil { + if err := m.InsertChain(chain); err != nil { t.Fatal(err) } return m @@ -146,7 +146,7 @@ func testFork(t *testing.T, m *mock.MockSentry, i, n int, comparator func(td1, t }) require.NoError(t, err) - if err = m.InsertChain(blockChainB, nil); err != nil { + if err = m.InsertChain(blockChainB); err != nil { t.Fatalf("failed to insert forking chain: %v", err) } currentBlockHash := blockChainB.TopBlock.Hash() @@ -162,7 +162,7 @@ func testFork(t *testing.T, m *mock.MockSentry, i, n int, comparator func(td1, t require.NoError(t, err) // Sanity check that the forked chain can be imported into the original - if err := canonicalMock.InsertChain(blockChainB, nil); err != nil { + if err := canonicalMock.InsertChain(blockChainB); err != nil { t.Fatalf("failed to import forked block chain: %v", err) } // Compare the total difficulties of the chains @@ -174,7 +174,7 @@ func TestLastBlock(t *testing.T) { var err error chain := makeBlockChain(current(m, nil), 1, m, 0) - if err = m.InsertChain(chain, nil); err != nil { + if err = m.InsertChain(chain); err != nil { t.Fatalf("Failed to insert block: %v", err) } @@ -275,7 +275,7 @@ func testBrokenChain(t *testing.T) { chain := makeBlockChain(current(m, nil), 5, m, forkSeed) brokenChain := chain.Slice(1, chain.Length()) - if err := m.InsertChain(brokenChain, nil); err == nil { + if err := m.InsertChain(brokenChain); err == nil { t.Errorf("broken block chain not reported") } } @@ -325,20 +325,18 @@ func testReorg(t *testing.T, first, second []int64, td int64) { t.Fatalf("generate chain: %v", err) } + if err = m.InsertChain(easyChain); err != nil { + t.Fatalf("failed to insert easy chain: %v", err) + } + if err = m.InsertChain(diffChain); err != nil { + t.Fatalf("failed to insert difficult chain: %v", err) + } tx, err := m.DB.BeginRw(m.Ctx) if err != nil { fmt.Printf("beginro error: %v\n", err) return } defer tx.Rollback() - - if err = m.InsertChain(easyChain, tx); err != nil { - t.Fatalf("failed to insert easy chain: %v", err) - } - if err = m.InsertChain(diffChain, tx); err != nil { - t.Fatalf("failed to insert difficult chain: %v", err) - } - // Check that the chain is valid number and link wise prev, err := m.BlockReader.CurrentBlock(tx) require.NoError(err) @@ -380,7 +378,7 @@ func testBadHashes(t *testing.T) { core.BadHashes[chain.Headers[2].Hash()] = true defer func() { delete(core.BadHashes, chain.Headers[2].Hash()) }() - err = m.InsertChain(chain, nil) + err = m.InsertChain(chain) if !errors.Is(err, core.ErrBlacklistedHash) { t.Errorf("error mismatch: have: %v, want: %v", err, core.ErrBlacklistedHash) } @@ -449,7 +447,7 @@ func TestChainTxReorgs(t *testing.T) { t.Fatalf("generate chain: %v", err) } // Import the chain. This runs all block validation rules. - if err1 := m.InsertChain(chain, nil); err1 != nil { + if err1 := m.InsertChain(chain); err1 != nil { t.Fatalf("failed to insert original chain: %v", err1) } @@ -476,7 +474,7 @@ func TestChainTxReorgs(t *testing.T) { t.Fatalf("generate chain: %v", err) } - if err := m.InsertChain(chain, nil); err != nil { + if err := m.InsertChain(chain); err != nil { t.Fatalf("failed to insert forked chain: %v", err) } tx, err := m.DB.BeginRo(context.Background()) @@ -564,7 +562,7 @@ func TestCanonicalBlockRetrieval(t *testing.T) { if err2 != nil { t.Fatalf("generate chain: %v", err2) } - err := m.InsertChain(chain, nil) + err := m.InsertChain(chain) require.NoError(t, err) tx, err := m.DB.BeginRo(m.Ctx) @@ -657,7 +655,7 @@ func TestEIP155Transition(t *testing.T) { t.Fatalf("generate chain: %v", chainErr) } - if chainErr = m.InsertChain(chain, nil); chainErr != nil { + if chainErr = m.InsertChain(chain); chainErr != nil { t.Fatal(chainErr) } if err := m.DB.View(context.Background(), func(tx kv.Tx) error { @@ -697,7 +695,7 @@ func TestEIP155Transition(t *testing.T) { if chainErr != nil { t.Fatalf("generate blocks: %v", chainErr) } - if err := m.InsertChain(chain, nil); err == nil { + if err := m.InsertChain(chain); err == nil { t.Errorf("expected error") } } @@ -781,7 +779,7 @@ func doModesTest(t *testing.T, pm prune.Mode) error { return fmt.Errorf("generate blocks: %w", err) } - if err = m.InsertChain(chain, nil); err != nil { + if err = m.InsertChain(chain); err != nil { return err } @@ -979,33 +977,47 @@ func TestEIP161AccountRemoval(t *testing.T) { if err != nil { t.Fatalf("generate blocks: %v", err) } + + // account must exist pre eip 161 + if err = m.InsertChain(chain.Slice(0, 1)); err != nil { + t.Fatal(err) + } tx, err := m.DB.BeginRw(m.Ctx) if err != nil { fmt.Printf("beginro error: %v\n", err) return } defer tx.Rollback() - - // account must exist pre eip 161 - if err = m.InsertChain(chain.Slice(0, 1), tx); err != nil { - t.Fatal(err) - } if st := state.New(m.NewStateReader(tx)); !st.Exist(theAddr) { t.Error("expected account to exist") } + tx.Rollback() // account needs to be deleted post eip 161 - if err = m.InsertChain(chain.Slice(1, 2), tx); err != nil { + if err = m.InsertChain(chain.Slice(1, 2)); err != nil { t.Fatal(err) } + tx, err = m.DB.BeginRw(m.Ctx) + if err != nil { + fmt.Printf("beginro error: %v\n", err) + return + } + defer tx.Rollback() if st := state.New(m.NewStateReader(tx)); st.Exist(theAddr) { t.Error("account should not exist") } + tx.Rollback() // account mustn't be created post eip 161 - if err = m.InsertChain(chain.Slice(2, 3), tx); err != nil { + if err = m.InsertChain(chain.Slice(2, 3)); err != nil { t.Fatal(err) } + tx, err = m.DB.BeginRw(m.Ctx) + if err != nil { + fmt.Printf("beginro error: %v\n", err) + return + } + defer tx.Rollback() if st := state.New(m.NewStateReader(tx)); st.Exist(theAddr) { t.Error("account should not exist") } @@ -1057,14 +1069,14 @@ func TestDoubleAccountRemoval(t *testing.T) { t.Fatalf("generate blocks: %v", err) } + err = m.InsertChain(chain) + assert.NoError(t, err) tx, err := m.DB.BeginRw(m.Ctx) if err != nil { fmt.Printf("beginro error: %v\n", err) return } defer tx.Rollback() - err = m.InsertChain(chain, tx) - assert.NoError(t, err) st := state.New(m.NewStateReader(tx)) assert.NoError(t, err) @@ -1117,7 +1129,7 @@ func TestBlockchainHeaderchainReorgConsistency(t *testing.T) { // Import the canonical and fork chain side by side, verifying the current block // and current header consistency for i := 0; i < chain.Length(); i++ { - if err := m2.InsertChain(chain.Slice(i, i+1), nil); err != nil { + if err := m2.InsertChain(chain.Slice(i, i+1)); err != nil { t.Fatalf("block %d: failed to insert into chain: %v", i, err) } @@ -1130,7 +1142,7 @@ func TestBlockchainHeaderchainReorgConsistency(t *testing.T) { if b.Hash() != h.Hash() { t.Errorf("block %d: current block/header mismatch: block #%d [%x…], header #%d [%x…]", i, b.Number(), b.Hash().Bytes()[:4], h.Number, h.Hash().Bytes()[:4]) } - if err := m2.InsertChain(forks[i], nil); err != nil { + if err := m2.InsertChain(forks[i]); err != nil { t.Fatalf(" fork %d: failed to insert into chain: %v", i, err) } b, err = m.BlockReader.CurrentBlock(tx) @@ -1184,20 +1196,20 @@ func TestLargeReorgTrieGC(t *testing.T) { } // Import the shared chain and the original canonical one - if err := m2.InsertChain(shared, nil); err != nil { + if err := m2.InsertChain(shared); err != nil { t.Fatalf("failed to insert shared chain: %v", err) } - if err := m2.InsertChain(original, nil); err != nil { + if err := m2.InsertChain(original); err != nil { t.Fatalf("failed to insert original chain: %v", err) } // Import the competitor chain without exceeding the canonical's TD and ensure // we have not processed any of the blocks (protection against malicious blocks) - if err := m2.InsertChain(competitor.Slice(0, competitor.Length()-2), nil); err != nil { + if err := m2.InsertChain(competitor.Slice(0, competitor.Length()-2)); err != nil { t.Fatalf("failed to insert competitor chain: %v", err) } // Import the head of the competitor chain, triggering the reorg and ensure we // successfully reprocess all the stashed away blocks. - if err := m2.InsertChain(competitor.Slice(competitor.Length()-2, competitor.Length()), nil); err != nil { + if err := m2.InsertChain(competitor.Slice(competitor.Length()-2, competitor.Length())); err != nil { t.Fatalf("failed to finalize competitor chain: %v", err) } } @@ -1238,12 +1250,12 @@ func TestLowDiffLongChain(t *testing.T) { // Import the canonical chain m2 := mock.Mock(t) - if err := m2.InsertChain(chain, nil); err != nil { + if err := m2.InsertChain(chain); err != nil { t.Fatalf("failed to insert into chain: %v", err) } // And now import the fork - if err := m2.InsertChain(fork, nil); err != nil { + if err := m2.InsertChain(fork); err != nil { t.Fatalf("failed to insert into chain: %v", err) } @@ -1336,7 +1348,7 @@ func TestDeleteCreateRevert(t *testing.T) { t.Fatalf("generate blocks: %v", err) } - if err := m.InsertChain(chain, nil); err != nil { + if err := m.InsertChain(chain); err != nil { t.Fatalf("failed to insert into chain: %v", err) } } @@ -1441,7 +1453,7 @@ func TestDeleteRecreateSlots(t *testing.T) { t.Fatalf("generate blocks: %v", err) } // Import the canonical chain - if err := m.InsertChain(chain, nil); err != nil { + if err := m.InsertChain(chain); err != nil { t.Fatalf("failed to insert into chain: %v", err) } err = m.DB.View(m.Ctx, func(tx kv.Tx) error { @@ -1559,7 +1571,7 @@ func TestCVE2020_26265(t *testing.T) { t.Fatalf("generate blocks: %v", err) } // Import the canonical chain - if err := m.InsertChain(chain, nil); err != nil { + if err := m.InsertChain(chain); err != nil { t.Fatalf("failed to insert into chain: %v", err) } err = m.DB.View(m.Ctx, func(tx kv.Tx) error { @@ -1626,7 +1638,7 @@ func TestDeleteRecreateAccount(t *testing.T) { t.Fatalf("generate blocks: %v", err) } // Import the canonical chain - if err := m.InsertChain(chain, nil); err != nil { + if err := m.InsertChain(chain); err != nil { t.Fatalf("failed to insert into chain: %v", err) } err = m.DB.View(m.Ctx, func(tx kv.Tx) error { @@ -1806,7 +1818,7 @@ func TestDeleteRecreateSlotsAcrossManyBlocks(t *testing.T) { } for i := range chain.Blocks { blockNum := i + 1 - if err := m.InsertChain(chain.Slice(i, i+1), nil); err != nil { + if err := m.InsertChain(chain.Slice(i, i+1)); err != nil { t.Fatalf("block %d: failed to insert into chain: %v", i, err) } err = m.DB.View(m.Ctx, func(tx kv.Tx) error { @@ -1949,7 +1961,7 @@ func TestInitThenFailCreateContract(t *testing.T) { // First block tries to create, but fails { block := chain.Blocks[0] - if err := m.InsertChain(chain.Slice(0, 1), nil); err != nil { + if err := m.InsertChain(chain.Slice(0, 1)); err != nil { t.Fatalf("block %d: failed to insert into chain: %v", block.NumberU64(), err) } statedb = state.New(m.NewHistoryStateReader(1, tx)) @@ -1959,7 +1971,7 @@ func TestInitThenFailCreateContract(t *testing.T) { } // Import the rest of the blocks for i, block := range chain.Blocks[1:] { - if err := m.InsertChain(chain.Slice(1+i, 2+i), nil); err != nil { + if err := m.InsertChain(chain.Slice(1+i, 2+i)); err != nil { t.Fatalf("block %d: failed to insert into chain: %v", block.NumberU64(), err) } } @@ -2033,7 +2045,7 @@ func TestEIP2718Transition(t *testing.T) { // Import the canonical chain - if err = m.InsertChain(chain, nil); err != nil { + if err = m.InsertChain(chain); err != nil { t.Fatalf("failed to insert into chain: %v", err) } @@ -2135,12 +2147,7 @@ func TestEIP1559Transition(t *testing.T) { } // Import the canonical chain - if err := m.DB.Update(m.Ctx, func(tx kv.RwTx) error { - if err = m.InsertChain(chain, tx); err != nil { - t.Fatalf("failed to insert into chain: %v", err) - } - return nil - }); err != nil { + if err = m.InsertChain(chain); err != nil { t.Fatalf("failed to insert into chain: %v", err) } @@ -2188,7 +2195,7 @@ func TestEIP1559Transition(t *testing.T) { t.Fatalf("generate chain: %v", err) } - if err = m.InsertChain(chain, nil); err != nil { + if err = m.InsertChain(chain); err != nil { t.Fatalf("failed to insert into chain: %v", err) } diff --git a/turbo/stages/chain_makers_test.go b/turbo/stages/chain_makers_test.go index 49e10c12fb8..f16c0efb373 100644 --- a/turbo/stages/chain_makers_test.go +++ b/turbo/stages/chain_makers_test.go @@ -92,6 +92,11 @@ func TestGenerateChain(t *testing.T) { fmt.Printf("generate chain: %v\n", err) } + // Import the chain. This runs all block validation rules. + if err := m.InsertChain(chain); err != nil { + fmt.Printf("insert error%v\n", err) + return + } tx, err := m.DB.BeginRw(m.Ctx) if err != nil { fmt.Printf("beginro error: %v\n", err) @@ -99,12 +104,6 @@ func TestGenerateChain(t *testing.T) { } defer tx.Rollback() - // Import the chain. This runs all block validation rules. - if err := m.InsertChain(chain, tx); err != nil { - fmt.Printf("insert error%v\n", err) - return - } - st := state.New(m.NewStateReader(tx)) if big.NewInt(5).Cmp(current(m, tx).Number()) != 0 { t.Errorf("wrong block number: %d", current(m, tx).Number()) diff --git a/turbo/stages/genesis_test.go b/turbo/stages/genesis_test.go index 4cc5a63075f..3cec00a1b03 100644 --- a/turbo/stages/genesis_test.go +++ b/turbo/stages/genesis_test.go @@ -123,7 +123,7 @@ func TestSetupGenesis(t *testing.T) { if err != nil { return nil, nil, err } - if err = m.InsertChain(chain, nil); err != nil { + if err = m.InsertChain(chain); err != nil { return nil, nil, err } // This should return a compatibility error. diff --git a/turbo/stages/mock/mock_sentry.go b/turbo/stages/mock/mock_sentry.go index 6f93903177f..17950913179 100644 --- a/turbo/stages/mock/mock_sentry.go +++ b/turbo/stages/mock/mock_sentry.go @@ -8,7 +8,10 @@ import ( "os" "sync" "testing" + "time" + "github.com/ledgerwatch/erigon/turbo/execution/eth1" + "github.com/ledgerwatch/erigon/turbo/execution/eth1/eth1_utils" stages2 "github.com/ledgerwatch/erigon/turbo/stages" "github.com/c2h5oh/datasize" @@ -22,6 +25,7 @@ import ( "github.com/ledgerwatch/erigon-lib/direct" "github.com/ledgerwatch/erigon-lib/gointerfaces" proto_downloader "github.com/ledgerwatch/erigon-lib/gointerfaces/downloader" + "github.com/ledgerwatch/erigon-lib/gointerfaces/execution" proto_sentry "github.com/ledgerwatch/erigon-lib/gointerfaces/sentry" ptypes "github.com/ledgerwatch/erigon-lib/gointerfaces/types" "github.com/ledgerwatch/erigon-lib/kv" @@ -68,30 +72,31 @@ const MockInsertAsInitialCycle = false type MockSentry struct { proto_sentry.UnimplementedSentryServer - Ctx context.Context - Log log.Logger - tb testing.TB - cancel context.CancelFunc - DB kv.RwDB - Dirs datadir.Dirs - Engine consensus.Engine - gspec *types.Genesis - ChainConfig *chain.Config - Sync *stagedsync.Sync - MiningSync *stagedsync.Sync - PendingBlocks chan *types.Block - MinedBlocks chan *types.Block - sentriesClient *sentry.MultiClient - Key *ecdsa.PrivateKey - Genesis *types.Block - SentryClient direct.SentryClient - PeerId *ptypes.H512 - UpdateHead func(Ctx context.Context, headHeight, headTime uint64, hash libcommon.Hash, td *uint256.Int) - streams map[proto_sentry.MessageId][]proto_sentry.Sentry_MessagesServer - sentMessages []*proto_sentry.OutboundMessageData - StreamWg sync.WaitGroup - ReceiveWg sync.WaitGroup - Address libcommon.Address + Ctx context.Context + Log log.Logger + tb testing.TB + cancel context.CancelFunc + DB kv.RwDB + Dirs datadir.Dirs + Engine consensus.Engine + gspec *types.Genesis + ChainConfig *chain.Config + Sync *stagedsync.Sync + MiningSync *stagedsync.Sync + PendingBlocks chan *types.Block + MinedBlocks chan *types.Block + sentriesClient *sentry.MultiClient + Key *ecdsa.PrivateKey + Genesis *types.Block + SentryClient direct.SentryClient + PeerId *ptypes.H512 + UpdateHead func(Ctx context.Context, headHeight, headTime uint64, hash libcommon.Hash, td *uint256.Int) + streams map[proto_sentry.MessageId][]proto_sentry.Sentry_MessagesServer + sentMessages []*proto_sentry.OutboundMessageData + StreamWg sync.WaitGroup + ReceiveWg sync.WaitGroup + Address libcommon.Address + Eth1ExecutionService *eth1.EthereumExecutionModule Notifications *shards.Notifications @@ -293,7 +298,6 @@ func MockWithEverything(tb testing.TB, gspec *types.Genesis, key *ecdsa.PrivateK sendBodyRequest := func(context.Context, *bodydownload.BodyRequest) ([64]byte, bool) { return [64]byte{}, false } blockPropagator := func(Ctx context.Context, header *types.Header, body *types.RawBody, td *big.Int) {} - if !cfg.DeprecatedTxPool.Disable { poolCfg := txpoolcfg.DefaultConfig newTxs := make(chan types2.Announcements, 1024) @@ -339,10 +343,14 @@ func MockWithEverything(tb testing.TB, gspec *types.Genesis, key *ecdsa.PrivateK inMemoryExecution := func(batch kv.RwTx, header *types.Header, body *types.RawBody, unwindPoint uint64, headersChain []*types.Header, bodiesChain []*types.RawBody, notifications *shards.Notifications) error { + terseLogger := log.New() + terseLogger.SetHandler(log.LvlFilterHandler(log.LvlWarn, log.StderrHandler)) // Needs its own notifications to not update RPC daemon and txpool about pending blocks - stateSync := stages2.NewInMemoryExecution(ctx, mock.DB, ðconfig.Defaults, mock.sentriesClient, dirs, notifications, mock.BlockReader, blockWriter, agg, nil, log.New() /* logging will be discarded */) + stateSync := stages2.NewInMemoryExecution(mock.Ctx, mock.DB, &cfg, mock.sentriesClient, + dirs, notifications, mock.BlockReader, blockWriter, mock.agg, nil, terseLogger) + chainReader := stagedsync.NewChainReaderImpl(mock.ChainConfig, batch, mock.BlockReader, logger) // We start the mining step - if err := stages2.StateStep(ctx, nil, engine, batch, blockWriter, stateSync, mock.sentriesClient.Bd, header, body, unwindPoint, headersChain, bodiesChain); err != nil { + if err := stages2.StateStep(ctx, chainReader, mock.Engine, batch, blockWriter, stateSync, mock.sentriesClient.Bd, header, body, unwindPoint, headersChain, bodiesChain); err != nil { logger.Warn("Could not validate block", "err", err) return err } @@ -387,6 +395,28 @@ func MockWithEverything(tb testing.TB, gspec *types.Genesis, key *ecdsa.PrivateK var snapshotsDownloader proto_downloader.DownloaderClient + // proof-of-stake mining + assembleBlockPOS := func(param *core.BlockBuilderParameters, interrupt *int32) (*types.BlockWithReceipts, error) { + miningStatePos := stagedsync.NewProposingState(&cfg.Miner) + miningStatePos.MiningConfig.Etherbase = param.SuggestedFeeRecipient + proposingSync := stagedsync.New( + stagedsync.MiningStages(mock.Ctx, + stagedsync.StageMiningCreateBlockCfg(mock.DB, miningStatePos, *mock.ChainConfig, mock.Engine, mock.txPoolDB, param, tmpdir, mock.BlockReader), + stagedsync.StageBorHeimdallCfg(mock.DB, miningStatePos, *mock.ChainConfig, nil, mock.BlockReader, nil, nil), + stagedsync.StageMiningExecCfg(mock.DB, miningStatePos, mock.Notifications.Events, *mock.ChainConfig, mock.Engine, &vm.Config{}, tmpdir, interrupt, param.PayloadId, mock.TxPool, mock.txPoolDB, mock.BlockReader), + stagedsync.StageHashStateCfg(mock.DB, dirs, cfg.HistoryV3), + stagedsync.StageTrieCfg(mock.DB, false, true, true, tmpdir, mock.BlockReader, nil, histV3, mock.agg), + stagedsync.StageMiningFinishCfg(mock.DB, *mock.ChainConfig, mock.Engine, miningStatePos, nil, mock.BlockReader, latestBlockBuiltStore), + ), stagedsync.MiningUnwindOrder, stagedsync.MiningPruneOrder, + logger) + // We start the mining step + if err := stages2.MiningStep(ctx, mock.DB, proposingSync, tmpdir); err != nil { + return nil, err + } + block := <-miningStatePos.MiningResultPOSCh + return block, nil + } + blockRetire := freezeblocks.NewBlockRetire(1, dirs, mock.BlockReader, blockWriter, mock.DB, mock.Notifications.Events, logger) mock.Sync = stagedsync.New( stagedsync.DefaultStages(mock.Ctx, @@ -429,6 +459,13 @@ func MockWithEverything(tb testing.TB, gspec *types.Genesis, key *ecdsa.PrivateK logger, ) + cfg.Genesis = gspec + pipelineStages := stages2.NewPipelineStages(mock.Ctx, db, &cfg, mock.sentriesClient, mock.Notifications, + snapshotsDownloader, mock.BlockReader, blockRetire, mock.agg, nil, forkValidator, logger, checkStateRoot) + mock.posStagedSync = stagedsync.New(pipelineStages, stagedsync.PipelineUnwindOrder, stagedsync.PipelinePruneOrder, logger) + + mock.Eth1ExecutionService = eth1.NewEthereumExecutionModule(mock.BlockReader, mock.DB, mock.posStagedSync, forkValidator, mock.ChainConfig, assembleBlockPOS, nil, mock.Notifications.Accumulator, mock.Notifications.StateChangesConsumer, logger, histV3) + mock.sentriesClient.Hd.StartPoSDownloader(mock.Ctx, sendHeaderRequest, penalize) miningConfig := cfg.Miner @@ -460,9 +497,6 @@ func MockWithEverything(tb testing.TB, gspec *types.Genesis, key *ecdsa.PrivateK ) cfg.Genesis = gspec - pipelineStages := stages2.NewPipelineStages(ctx, db, &cfg, mock.sentriesClient, mock.Notifications, - snapshotsDownloader, mock.BlockReader, blockRetire, mock.agg, nil, forkValidator, logger, checkStateRoot) - mock.posStagedSync = stagedsync.New(pipelineStages, stagedsync.PipelineUnwindOrder, stagedsync.PipelinePruneOrder, logger) mock.StreamWg.Add(1) go mock.sentriesClient.RecvMessageLoop(mock.Ctx, mock.SentryClient, &mock.ReceiveWg) @@ -623,105 +657,82 @@ func (ms *MockSentry) insertPoWBlocks(chain *core.ChainPack, tx kv.RwTx) error { return nil } -func (ms *MockSentry) insertPoSBlocks(chain *core.ChainPack, tx kv.RwTx) error { +func (ms *MockSentry) insertPoSBlocks(chain *core.ChainPack) error { n := ms.numberOfPoWBlocks(chain) if n >= chain.Length() { return nil } - var bottomBlock *types.Block - for i := n; i < chain.Length(); i++ { if err := chain.Blocks[i].HashCheck(); err != nil { return err } - if bottomBlock == nil { - bottomBlock = chain.Blocks[i] - } - cr := stagedsync.ChainReader{Cfg: *ms.ChainConfig, Db: tx, BlockReader: ms.BlockReader} - if err := ms.Engine.VerifyHeader(cr, chain.Blocks[i].Header(), true); err != nil { - return err - } - if err := ms.Engine.VerifyUncles(cr, chain.Blocks[i].Header(), chain.Blocks[i].Uncles()); err != nil { - return err - } - rawdb.WriteHeader(tx, chain.Blocks[i].Header()) - if _, err := rawdb.WriteRawBodyIfNotExists(tx, chain.Blocks[i].Hash(), chain.Blocks[i].NumberU64(), chain.Blocks[i].RawBody()); err != nil { + res, err := ms.Eth1ExecutionService.InsertBlocks(ms.Ctx, &execution.InsertBlocksRequest{ + Blocks: []*execution.Block{eth1_utils.ConvertBlockToRPC(chain.Blocks[i])}, + }) + if err != nil { return err } - - parentTd, err := rawdb.ReadTd(tx, chain.Blocks[i].ParentHash(), chain.Blocks[i].NumberU64()-1) - if err != nil || parentTd == nil { - return fmt.Errorf("no td %s", err) + if res.Result != execution.ExecutionStatus_Success { + return fmt.Errorf("insertion failed for block %d, code: %s", chain.Blocks[i].NumberU64(), res.Result.String()) } - td := new(big.Int).Add(parentTd, chain.Blocks[i].Difficulty()) - if err = rawdb.WriteTd(tx, chain.Blocks[i].Hash(), chain.Blocks[i].NumberU64(), td); err != nil { - return err - } - rawdb.WriteCanonicalHash(tx, chain.Blocks[i].Hash(), chain.Blocks[i].NumberU64()) - } - if bottomBlock == nil { - return nil - } - currentHash := bottomBlock.ParentHash() - currentNumber := bottomBlock.NumberU64() - 1 - for canonical, err := rawdb.IsCanonicalHash(tx, currentHash, currentNumber); !canonical; canonical, err = rawdb.IsCanonicalHash(tx, currentHash, currentNumber) { + vRes, err := ms.Eth1ExecutionService.ValidateChain(ms.Ctx, &execution.ValidationRequest{ + Hash: gointerfaces.ConvertHashToH256(chain.Blocks[i].Hash()), + Number: chain.Blocks[i].NumberU64(), + }) if err != nil { return err } - currentHeader := rawdb.ReadHeader(tx, currentHash, currentNumber) - if currentHeader == nil { - return fmt.Errorf("missing header") + if vRes.ValidationStatus != execution.ExecutionStatus_Success { + return fmt.Errorf("insertion failed for block %d, code: %s", chain.Blocks[i].NumberU64(), vRes.ValidationStatus.String()) } - if err := rawdb.WriteCanonicalHash(tx, currentHash, currentNumber); err != nil { + + receipt, err := ms.Eth1ExecutionService.UpdateForkChoice(ms.Ctx, &execution.ForkChoice{ + HeadBlockHash: gointerfaces.ConvertHashToH256(chain.Blocks[i].Hash()), + SafeBlockHash: gointerfaces.ConvertHashToH256(chain.Blocks[i].Hash()), + FinalizedBlockHash: gointerfaces.ConvertHashToH256(chain.Blocks[i].Hash()), + Timeout: uint64(1 * time.Hour), + }) + if err != nil { return err } - - currentHash = currentHeader.ParentHash - currentNumber-- + if receipt.Status != execution.ExecutionStatus_Success { + return fmt.Errorf("forkchoice failed for block %d, code: %s", chain.Blocks[i].NumberU64(), receipt.Status.String()) + } } + return nil +} - ms.posStagedSync.UnwindTo(currentNumber, libcommon.Hash{}) - ms.posStagedSync.RunUnwind(ms.DB, tx) - hook := stages2.NewHook(ms.Ctx, ms.DB, ms.Notifications, ms.Sync, ms.BlockReader, ms.ChainConfig, ms.Log, ms.UpdateHead) +func (ms *MockSentry) InsertChain(chain *core.ChainPack) error { - if err := stages.SaveStageProgress(tx, stages.Headers, chain.TopBlock.NumberU64()); err != nil { - return err - } - if err := stages.SaveStageProgress(tx, stages.Bodies, chain.TopBlock.NumberU64()); err != nil { + tx, err := ms.DB.BeginRw(ms.Ctx) + if err != nil { return err } - rawdb.WriteHeadHeaderHash(tx, chain.TopBlock.Hash()) - - return stages2.StageLoopIteration(ms.Ctx, ms.DB, tx, ms.posStagedSync, MockInsertAsInitialCycle, ms.Log, ms.BlockReader, hook, false) - -} - -func (ms *MockSentry) InsertChain(chain *core.ChainPack, tx kv.RwTx) error { - externalTx := tx != nil - if !externalTx { - var err error - tx, err = ms.DB.BeginRw(ms.Ctx) - if err != nil { - return err - } - defer tx.Rollback() - } + defer tx.Rollback() if err := ms.insertPoWBlocks(chain, tx); err != nil { return err } - if err := ms.insertPoSBlocks(chain, tx); err != nil { + if err := tx.Commit(); err != nil { + return err + } + if err := ms.insertPoSBlocks(chain); err != nil { return err } + roTx, err := ms.DB.BeginRo(ms.Ctx) + if err != nil { + return err + } + defer roTx.Rollback() // Check if the latest header was imported or rolled back - if rawdb.ReadHeader(tx, chain.TopBlock.Hash(), chain.TopBlock.NumberU64()) == nil { + if rawdb.ReadHeader(roTx, chain.TopBlock.Hash(), chain.TopBlock.NumberU64()) == nil { return fmt.Errorf("did not import block %d %x", chain.TopBlock.NumberU64(), chain.TopBlock.Hash()) } - execAt, err := stages.GetStageProgress(tx, stages.Execution) + execAt, err := stages.GetStageProgress(roTx, stages.Execution) if err != nil { return err } @@ -747,11 +758,6 @@ func (ms *MockSentry) InsertChain(chain *core.ChainPack, tx kv.RwTx) error { //} //} - if !externalTx { - if err := tx.Commit(); err != nil { - return err - } - } return nil } From da4e1c1ba4f495b5c58f37d405e6560bfbead5b5 Mon Sep 17 00:00:00 2001 From: Anshal Shukla <53994948+anshalshukla@users.noreply.github.com> Date: Thu, 5 Oct 2023 22:25:32 +0530 Subject: [PATCH 12/14] fix bor.milestone flag (#8384) - Made milestones enabled by default, since it has now been tested on devnets - Small bug fix which fixes nil panic while minning --- cmd/utils/flags.go | 2 +- eth/stagedsync/stage_bor_heimdall.go | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 89c937957fc..3eb39541a9c 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -767,7 +767,7 @@ var ( WithHeimdallMilestones = cli.BoolFlag{ Name: "bor.milestone", Usage: "Enabling bor milestone processing", - Value: false, + Value: true, } // HeimdallgRPCAddressFlag flag for heimdall gRPC address diff --git a/eth/stagedsync/stage_bor_heimdall.go b/eth/stagedsync/stage_bor_heimdall.go index c0d4c57c1a3..6ce3347a650 100644 --- a/eth/stagedsync/stage_bor_heimdall.go +++ b/eth/stagedsync/stage_bor_heimdall.go @@ -148,12 +148,13 @@ func BorHeimdallForward( if minedHeadNumber := minedHeader.Number.Uint64(); minedHeadNumber > headNumber { // Whitelist service is called to check if the bor chain is // on the cannonical chain according to milestones - - if !service.IsValidChain(minedHeadNumber, []*types.Header{minedHeader}) { - logger.Debug("[BorHeimdall] Verification failed for mined header", "hash", minedHeader.Hash(), "height", minedHeadNumber, "err", err) - dataflow.HeaderDownloadStates.AddChange(minedHeadNumber, dataflow.HeaderInvalidated) - s.state.UnwindTo(minedHeadNumber-1, minedHeader.Hash()) - return err + if service != nil { + if !service.IsValidChain(minedHeadNumber, []*types.Header{minedHeader}) { + logger.Debug("[BorHeimdall] Verification failed for mined header", "hash", minedHeader.Hash(), "height", minedHeadNumber, "err", err) + dataflow.HeaderDownloadStates.AddChange(minedHeadNumber, dataflow.HeaderInvalidated) + s.state.UnwindTo(minedHeadNumber-1, minedHeader.Hash()) + return err + } } } else { return fmt.Errorf("attempting to mine %d, which is behind current head: %d", minedHeadNumber, headNumber) From 12566dda736a07ba7474c6ef239f6bf3d8dc3b5f Mon Sep 17 00:00:00 2001 From: Anshal Shukla <53994948+anshalshukla@users.noreply.github.com> Date: Thu, 5 Oct 2023 22:26:02 +0530 Subject: [PATCH 13/14] make rpc consistent with bor (#8385) --- turbo/jsonrpc/bor_api.go | 3 +- turbo/jsonrpc/bor_snapshot.go | 68 +++++++++++++++++++++++++++++++---- 2 files changed, 64 insertions(+), 7 deletions(-) diff --git a/turbo/jsonrpc/bor_api.go b/turbo/jsonrpc/bor_api.go index 2ee4a461e86..d80da52bd48 100644 --- a/turbo/jsonrpc/bor_api.go +++ b/turbo/jsonrpc/bor_api.go @@ -13,12 +13,13 @@ import ( type BorAPI interface { // Bor snapshot related (see ./bor_snapshot.go) GetSnapshot(number *rpc.BlockNumber) (*Snapshot, error) - GetAuthor(number *rpc.BlockNumber) (*common.Address, error) + GetAuthor(blockNrOrHash *rpc.BlockNumberOrHash) (*common.Address, error) GetSnapshotAtHash(hash common.Hash) (*Snapshot, error) GetSigners(number *rpc.BlockNumber) ([]common.Address, error) GetSignersAtHash(hash common.Hash) ([]common.Address, error) GetCurrentProposer() (common.Address, error) GetCurrentValidators() ([]*valset.Validator, error) + GetSnapshotProposer(blockNrOrHash *rpc.BlockNumberOrHash) (common.Address, error) GetSnapshotProposerSequence(blockNrOrHash *rpc.BlockNumberOrHash) (BlockSigners, error) GetRootHash(start uint64, end uint64) (string, error) } diff --git a/turbo/jsonrpc/bor_snapshot.go b/turbo/jsonrpc/bor_snapshot.go index 91bdf642afb..9063e12c148 100644 --- a/turbo/jsonrpc/bor_snapshot.go +++ b/turbo/jsonrpc/bor_snapshot.go @@ -61,7 +61,7 @@ func (api *BorImpl) GetSnapshot(number *rpc.BlockNumber) (*Snapshot, error) { } // GetAuthor retrieves the author a block. -func (api *BorImpl) GetAuthor(number *rpc.BlockNumber) (*common.Address, error) { +func (api *BorImpl) GetAuthor(blockNrOrHash *rpc.BlockNumberOrHash) (*common.Address, error) { ctx := context.Background() tx, err := api.db.BeginRo(ctx) if err != nil { @@ -71,16 +71,30 @@ func (api *BorImpl) GetAuthor(number *rpc.BlockNumber) (*common.Address, error) // Retrieve the requested block number (or current if none requested) var header *types.Header - if number == nil || *number == rpc.LatestBlockNumber { + + //nolint:nestif + if blockNrOrHash == nil { header = rawdb.ReadCurrentHeader(tx) } else { - header, _ = getHeaderByNumber(ctx, *number, api, tx) + if blockNr, ok := blockNrOrHash.Number(); ok { + header = rawdb.ReadHeaderByNumber(tx, uint64(blockNr)) + if blockNr == rpc.LatestBlockNumber { + header = rawdb.ReadCurrentHeader(tx) + } + } else { + if blockHash, ok := blockNrOrHash.Hash(); ok { + header, err = rawdb.ReadHeaderByHash(tx, blockHash) + } + } } - // Ensure we have an actually valid block - if header == nil { + + // Ensure we have an actually valid block and return its snapshot + if header == nil || err != nil { return nil, errUnknownBlock } - author, err := author(api, tx, header) + + author, err := api.bor.Author(header) + return &author, err } @@ -261,6 +275,48 @@ type difficultiesKV struct { Difficulty uint64 } +// GetSnapshotProposer retrieves the in-turn signer at a given block. +func (api *BorImpl) GetSnapshotProposer(blockNrOrHash *rpc.BlockNumberOrHash) (common.Address, error) { + // init chain db + ctx := context.Background() + tx, err := api.db.BeginRo(ctx) + if err != nil { + return common.Address{}, err + } + defer tx.Rollback() + + var header *types.Header + //nolint:nestif + if blockNrOrHash == nil { + header = rawdb.ReadCurrentHeader(tx) + } else { + if blockNr, ok := blockNrOrHash.Number(); ok { + if blockNr == rpc.LatestBlockNumber { + header = rawdb.ReadCurrentHeader(tx) + } else { + header = rawdb.ReadHeaderByNumber(tx, uint64(blockNr)) + } + } else { + if blockHash, ok := blockNrOrHash.Hash(); ok { + header, err = rawdb.ReadHeaderByHash(tx, blockHash) + } + } + } + + if header == nil || err != nil { + return common.Address{}, errUnknownBlock + } + + snapNumber := rpc.BlockNumber(header.Number.Int64() - 1) + snap, err := api.GetSnapshot(&snapNumber) + + if err != nil { + return common.Address{}, err + } + + return snap.ValidatorSet.GetProposer().Address, nil +} + func (api *BorImpl) GetSnapshotProposerSequence(blockNrOrHash *rpc.BlockNumberOrHash) (BlockSigners, error) { // init chain db ctx := context.Background() From 0eed8e35dd13cdfcc0494373b913c6fa18ea5b29 Mon Sep 17 00:00:00 2001 From: Giulio rebuffo Date: Thu, 5 Oct 2023 22:48:06 +0200 Subject: [PATCH 14/14] fixed --internalcl flag for gnosis (#8387) little thing i forgot to fix up. --- cmd/utils/flags.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 3eb39541a9c..db5964d7566 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -1640,7 +1640,7 @@ func SetEthConfig(ctx *cli.Context, nodeConfig *nodecfg.Config, cfg *ethconfig.C cfg.TxPool.OverrideCancunTime = cfg.OverrideCancunTime } - if ctx.IsSet(InternalConsensusFlag.Name) && clparams.EmbeddedEnabledByDefault(cfg.NetworkID) { + if ctx.IsSet(InternalConsensusFlag.Name) && clparams.EmbeddedSupported(cfg.NetworkID) { cfg.InternalCL = ctx.Bool(InternalConsensusFlag.Name) }