From d8f8ff492f74216cb2c4b50fe826d70db2d1c738 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Mon, 2 Aug 2021 03:36:31 -0300 Subject: [PATCH 001/261] Squash all previous rebases up to v2021.07.05-otterscan --- README.md | 12 + cmd/rpcdaemon/commands/daemon.go | 8 + cmd/rpcdaemon/commands/otterscan_api.go | 522 +++++++++++++++++++++ otterscan/transactions/trace_operations.go | 83 ++++ otterscan/transactions/trace_touch.go | 52 ++ 5 files changed, 677 insertions(+) create mode 100644 cmd/rpcdaemon/commands/otterscan_api.go create mode 100644 otterscan/transactions/trace_operations.go create mode 100644 otterscan/transactions/trace_touch.go diff --git a/README.md b/README.md index 8cd165518de..8846be53a83 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,15 @@ +# Otterscan's Erigon Extensions + +This is a fork of Erigon containing jsonrpc method extensions used by [Otterscan](https://github.com/wmitsuda/otterscan). + +**Please be sure you have a working Erigon installation before trying this fork.** + +All instructions about which branch to use, how to run it, etc., are in the [Otterscan repository](https://github.com/wmitsuda/otterscan). + +The rest of this document contains the original Erigon README content. + +--- + # Erigon Erigon is an implementation of Ethereum (aka "Ethereum client"), on the efficiency frontier, written in Go. diff --git a/cmd/rpcdaemon/commands/daemon.go b/cmd/rpcdaemon/commands/daemon.go index 8678712eebd..f250cb2b953 100644 --- a/cmd/rpcdaemon/commands/daemon.go +++ b/cmd/rpcdaemon/commands/daemon.go @@ -25,6 +25,7 @@ func APIList(ctx context.Context, db kv.RoDB, eth services.ApiBackend, txPool tx web3Impl := NewWeb3APIImpl(eth) dbImpl := NewDBAPIImpl() /* deprecated */ shhImpl := NewSHHAPIImpl() /* deprecated */ + otsImpl := NewOtterscanAPI(base, db) for _, enabledAPI := range cfg.API { switch enabledAPI { @@ -91,6 +92,13 @@ func APIList(ctx context.Context, db kv.RoDB, eth services.ApiBackend, txPool tx Service: ErigonAPI(erigonImpl), Version: "1.0", }) + case "ots": + defaultAPIList = append(defaultAPIList, rpc.API{ + Namespace: "ots", + Public: true, + Service: OtterscanAPI(otsImpl), + Version: "1.0", + }) } } diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go new file mode 100644 index 00000000000..9b7620cc262 --- /dev/null +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -0,0 +1,522 @@ +package commands + +import ( + "bytes" + "context" + "encoding/binary" + "errors" + "fmt" + "github.com/RoaringBitmap/roaring/roaring64" + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/consensus/ethash" + "github.com/ledgerwatch/erigon/core" + "github.com/ledgerwatch/erigon/core/rawdb" + "github.com/ledgerwatch/erigon/core/state" + "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/core/vm" + "github.com/ledgerwatch/erigon/ethdb" + "github.com/ledgerwatch/erigon/ethdb/kv" + "github.com/ledgerwatch/erigon/log" + otterscan "github.com/ledgerwatch/erigon/otterscan/transactions" + "github.com/ledgerwatch/erigon/params" + "github.com/ledgerwatch/erigon/turbo/shards" + "github.com/ledgerwatch/erigon/turbo/transactions" + "sync" +) + +// API_LEVEL Must be incremented every time new additions are made +const API_LEVEL = 2 + +type SearchResult struct { + BlockNumber uint64 +} + +type BlockSearchResult struct { + hash common.Hash +} + +type TransactionsWithReceipts struct { + Txs []*RPCTransaction `json:"txs"` + Receipts []map[string]interface{} `json:"receipts"` + FirstPage bool `json:"firstPage"` + LastPage bool `json:"lastPage"` +} + +type OtterscanAPI interface { + GetApiLevel() uint8 + GetInternalOperations(ctx context.Context, hash common.Hash) ([]*otterscan.InternalOperation, error) + SearchTransactionsBefore(ctx context.Context, addr common.Address, blockNum uint64, minPageSize uint16) (*TransactionsWithReceipts, error) + SearchTransactionsAfter(ctx context.Context, addr common.Address, blockNum uint64, minPageSize uint16) (*TransactionsWithReceipts, error) +} + +type OtterscanAPIImpl struct { + *BaseAPI + db kv.RoDB +} + +func NewOtterscanAPI(base *BaseAPI, db kv.RoDB) *OtterscanAPIImpl { + return &OtterscanAPIImpl{ + BaseAPI: base, + db: db, + } +} + +func (api *OtterscanAPIImpl) GetApiLevel() uint8 { + return API_LEVEL +} + +func (api *OtterscanAPIImpl) GetInternalOperations(ctx context.Context, hash common.Hash) ([]*otterscan.InternalOperation, error) { + tx, err := api.db.BeginRo(ctx) + if err != nil { + return nil, err + } + defer tx.Rollback() + + txn, blockHash, _, txIndex, err := rawdb.ReadTransaction(tx, hash) + if err != nil { + return nil, err + } + if txn == nil { + return nil, fmt.Errorf("transaction %#x not found", hash) + } + block, err := rawdb.ReadBlockByHash(tx, blockHash) + if err != nil { + return nil, err + } + + chainConfig, err := api.chainConfig(tx) + if err != nil { + return nil, err + } + + getHeader := func(hash common.Hash, number uint64) *types.Header { + return rawdb.ReadHeader(tx, hash, number) + } + checkTEVM := ethdb.GetCheckTEVM(tx) + msg, blockCtx, txCtx, ibs, _, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, checkTEVM, ethash.NewFaker(), tx, blockHash, txIndex) + if err != nil { + return nil, err + } + + tracer := otterscan.NewOperationsTracer(ctx) + vmenv := vm.NewEVM(blockCtx, txCtx, ibs, chainConfig, vm.Config{Debug: true, Tracer: tracer}) + + if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), true, false /* gasBailout */); err != nil { + return nil, fmt.Errorf("tracing failed: %v", err) + } + + return tracer.Results, nil +} + +func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr common.Address, blockNum uint64, minPageSize uint16) (*TransactionsWithReceipts, error) { + dbtx, err := api.db.BeginRo(ctx) + if err != nil { + return nil, err + } + defer dbtx.Rollback() + + fromCursor, err := dbtx.Cursor(kv.CallFromIndex) + if err != nil { + return nil, err + } + defer fromCursor.Close() + toCursor, err := dbtx.Cursor(kv.CallToIndex) + if err != nil { + return nil, err + } + defer toCursor.Close() + + chainConfig, err := api.chainConfig(dbtx) + if err != nil { + return nil, err + } + + // Initialize search cursors at the first shard >= desired block number + resultCount := uint16(0) + fromIter := newSearchBackIterator(fromCursor, addr, blockNum) + toIter := newSearchBackIterator(toCursor, addr, blockNum) + + txs := make([]*RPCTransaction, 0) + receipts := make([]map[string]interface{}, 0) + + multiIter, err := newMultiIterator(false, fromIter, toIter) + if err != nil { + return nil, err + } + eof := false + for { + if resultCount >= minPageSize || eof { + break + } + + var wg sync.WaitGroup + results := make([]*TransactionsWithReceipts, 100, 100) + tot := 0 + for i := 0; i < int(minPageSize-resultCount); i++ { + var blockNum uint64 + blockNum, eof, err = multiIter() + if err != nil { + return nil, err + } + if eof { + break + } + + wg.Add(1) + tot++ + go api.traceOneBlock(ctx, &wg, addr, chainConfig, i, blockNum, results) + } + wg.Wait() + + for i := 0; i < tot; i++ { + r := results[i] + if r == nil { + return nil, errors.New("XXXX") + } + + resultCount += uint16(len(r.Txs)) + for i := len(r.Txs) - 1; i >= 0; i-- { + txs = append(txs, r.Txs[i]) + } + for i := len(r.Receipts) - 1; i >= 0; i-- { + receipts = append(receipts, r.Receipts[i]) + } + + if resultCount >= minPageSize { + break + } + } + } + + return &TransactionsWithReceipts{txs, receipts, blockNum == 0, eof}, nil +} + +func newSearchBackIterator(cursor kv.Cursor, addr common.Address, maxBlock uint64) func() (uint64, bool, error) { + search := make([]byte, common.AddressLength+8) + copy(search[:common.AddressLength], addr.Bytes()) + if maxBlock == 0 { + binary.BigEndian.PutUint64(search[common.AddressLength:], ^uint64(0)) + } else { + binary.BigEndian.PutUint64(search[common.AddressLength:], maxBlock) + } + + first := true + var iter roaring64.IntIterable64 + + return func() (uint64, bool, error) { + if first { + first = false + k, v, err := cursor.Seek(search) + if err != nil { + return 0, true, err + } + if !bytes.Equal(k[:common.AddressLength], addr.Bytes()) { + return 0, true, nil + } + + bitmap := roaring64.New() + if _, err := bitmap.ReadFrom(bytes.NewReader(v)); err != nil { + return 0, true, err + } + iter = bitmap.ReverseIterator() + } + + var blockNum uint64 + for { + if !iter.HasNext() { + // Try and check previous shard + k, v, err := cursor.Prev() + if err != nil { + return 0, true, err + } + if !bytes.Equal(k[:common.AddressLength], addr.Bytes()) { + return 0, true, nil + } + + bitmap := roaring64.New() + if _, err := bitmap.ReadFrom(bytes.NewReader(v)); err != nil { + return 0, true, err + } + iter = bitmap.ReverseIterator() + } + blockNum = iter.Next() + + if maxBlock == 0 || blockNum < maxBlock { + break + } + } + return blockNum, false, nil + } +} + +func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr common.Address, blockNum uint64, minPageSize uint16) (*TransactionsWithReceipts, error) { + dbtx, err := api.db.BeginRo(ctx) + if err != nil { + return nil, err + } + defer dbtx.Rollback() + + fromCursor, err := dbtx.Cursor(kv.CallFromIndex) + if err != nil { + return nil, err + } + defer fromCursor.Close() + toCursor, err := dbtx.Cursor(kv.CallToIndex) + if err != nil { + return nil, err + } + defer toCursor.Close() + + chainConfig, err := api.chainConfig(dbtx) + if err != nil { + return nil, err + } + + // Initialize search cursors at the first shard >= desired block number + resultCount := uint16(0) + fromIter := newSearchForwardIterator(fromCursor, addr, blockNum) + toIter := newSearchForwardIterator(toCursor, addr, blockNum) + + txs := make([]*RPCTransaction, 0) + receipts := make([]map[string]interface{}, 0) + + multiIter, err := newMultiIterator(true, fromIter, toIter) + if err != nil { + return nil, err + } + eof := false + for { + if resultCount >= minPageSize || eof { + break + } + + var wg sync.WaitGroup + results := make([]*TransactionsWithReceipts, 100, 100) + tot := 0 + for i := 0; i < int(minPageSize-resultCount); i++ { + var blockNum uint64 + blockNum, eof, err = multiIter() + if err != nil { + return nil, err + } + if eof { + break + } + + wg.Add(1) + tot++ + go api.traceOneBlock(ctx, &wg, addr, chainConfig, i, blockNum, results) + } + wg.Wait() + + for i := 0; i < tot; i++ { + r := results[i] + if r == nil { + return nil, errors.New("XXXX") + } + + resultCount += uint16(len(r.Txs)) + for _, v := range r.Txs { + txs = append([]*RPCTransaction{v}, txs...) + } + for _, v := range r.Receipts { + receipts = append([]map[string]interface{}{v}, receipts...) + } + + if resultCount > minPageSize { + break + } + } + } + + return &TransactionsWithReceipts{txs, receipts, eof, blockNum == 0}, nil +} + +func newSearchForwardIterator(cursor kv.Cursor, addr common.Address, minBlock uint64) func() (uint64, bool, error) { + search := make([]byte, common.AddressLength+8) + copy(search[:common.AddressLength], addr.Bytes()) + if minBlock == 0 { + binary.BigEndian.PutUint64(search[common.AddressLength:], uint64(0)) + } else { + binary.BigEndian.PutUint64(search[common.AddressLength:], minBlock) + } + + first := true + var iter roaring64.IntIterable64 + + return func() (uint64, bool, error) { + if first { + first = false + k, v, err := cursor.Seek(search) + if err != nil { + return 0, true, err + } + if !bytes.Equal(k[:common.AddressLength], addr.Bytes()) { + return 0, true, nil + } + + bitmap := roaring64.New() + if _, err := bitmap.ReadFrom(bytes.NewReader(v)); err != nil { + return 0, true, err + } + iter = bitmap.Iterator() + } + + var blockNum uint64 + for { + if !iter.HasNext() { + // Try and check next shard + k, v, err := cursor.Next() + if err != nil { + return 0, true, err + } + if !bytes.Equal(k[:common.AddressLength], addr.Bytes()) { + return 0, true, nil + } + + bitmap := roaring64.New() + if _, err := bitmap.ReadFrom(bytes.NewReader(v)); err != nil { + return 0, true, err + } + iter = bitmap.Iterator() + } + blockNum = iter.Next() + + if minBlock == 0 || blockNum > minBlock { + break + } + } + return blockNum, false, nil + } +} + +func newMultiIterator(smaller bool, fromIter func() (uint64, bool, error), toIter func() (uint64, bool, error)) (func() (uint64, bool, error), error) { + nextFrom, fromEnd, err := fromIter() + if err != nil { + return nil, err + } + nextTo, toEnd, err := toIter() + if err != nil { + return nil, err + } + + return func() (uint64, bool, error) { + if fromEnd && toEnd { + return 0, true, nil + } + + var blockNum uint64 + if !fromEnd { + blockNum = nextFrom + } + if !toEnd { + if smaller { + if nextTo < blockNum { + blockNum = nextTo + } + } else { + if nextTo > blockNum { + blockNum = nextTo + } + } + } + + // Pull next; it may be that from AND to contains the same blockNum + if !fromEnd && blockNum == nextFrom { + nextFrom, fromEnd, err = fromIter() + if err != nil { + return 0, false, err + } + } + if !toEnd && blockNum == nextTo { + nextTo, toEnd, err = toIter() + if err != nil { + return 0, false, err + } + } + return blockNum, false, nil + }, nil +} + +func (api *OtterscanAPIImpl) traceOneBlock(ctx context.Context, wg *sync.WaitGroup, addr common.Address, chainConfig *params.ChainConfig, idx int, bNum uint64, results []*TransactionsWithReceipts) { + defer wg.Done() + + // Trace block for Txs + newdbtx, err := api.db.BeginRo(ctx) + if err != nil { + log.Error("ERR", "err", err) + // TODO: signal error + results[idx] = nil + } + defer newdbtx.Rollback() + + _, result, err := api.traceBlock(newdbtx, ctx, bNum, addr, chainConfig) + if err != nil { + // TODO: signal error + log.Error("ERR", "err", err) + results[idx] = nil + //return nil, err + } + results[idx] = result +} + +func (api *OtterscanAPIImpl) traceBlock(dbtx kv.Tx, ctx context.Context, blockNum uint64, searchAddr common.Address, chainConfig *params.ChainConfig) (bool, *TransactionsWithReceipts, error) { + rpcTxs := make([]*RPCTransaction, 0) + receipts := make([]map[string]interface{}, 0) + + // Retrieve the transaction and assemble its EVM context + blockHash, err := rawdb.ReadCanonicalHash(dbtx, blockNum) + if err != nil { + return false, nil, err + } + + block, senders, err := rawdb.ReadBlockWithSenders(dbtx, blockHash, blockNum) + if err != nil { + return false, nil, err + } + + reader := state.NewPlainState(dbtx, blockNum-1) + stateCache := shards.NewStateCache(32, 0 /* no limit */) + cachedReader := state.NewCachedReader(reader, stateCache) + noop := state.NewNoopWriter() + cachedWriter := state.NewCachedWriter(noop, stateCache) + + ibs := state.New(cachedReader) + signer := types.MakeSigner(chainConfig, blockNum) + + getHeader := func(hash common.Hash, number uint64) *types.Header { + return rawdb.ReadHeader(dbtx, hash, number) + } + engine := ethash.NewFaker() + checkTEVM := ethdb.GetCheckTEVM(dbtx) + + blockReceipts := rawdb.ReadReceipts(dbtx, block, senders) + header := block.Header() + found := false + for idx, tx := range block.Transactions() { + ibs.Prepare(tx.Hash(), block.Hash(), idx) + + msg, _ := tx.AsMessage(*signer, header.BaseFee) + + tracer := otterscan.NewTouchTracer(searchAddr) + BlockContext := core.NewEVMBlockContext(header, getHeader, engine, nil, checkTEVM) + TxContext := core.NewEVMTxContext(msg) + + vmenv := vm.NewEVM(BlockContext, TxContext, ibs, chainConfig, vm.Config{Debug: true, Tracer: tracer}) + if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.GetGas()), true /* refunds */, false /* gasBailout */); err != nil { + return false, nil, err + } + _ = ibs.FinalizeTx(vmenv.ChainConfig().Rules(block.NumberU64()), cachedWriter) + + if tracer.Found { + rpcTx := newRPCTransaction(tx, block.Hash(), blockNum, uint64(idx), block.BaseFee()) + mReceipt := marshalReceipt(blockReceipts[idx], tx, chainConfig, block) + mReceipt["timestamp"] = block.Time() + rpcTxs = append(rpcTxs, rpcTx) + receipts = append(receipts, mReceipt) + found = true + } + } + + return found, &TransactionsWithReceipts{rpcTxs, receipts, false, false}, nil +} diff --git a/otterscan/transactions/trace_operations.go b/otterscan/transactions/trace_operations.go new file mode 100644 index 00000000000..5d26669b6f4 --- /dev/null +++ b/otterscan/transactions/trace_operations.go @@ -0,0 +1,83 @@ +package otterscan + +import ( + "context" + "github.com/ledgerwatch/erigon/common/hexutil" + "math/big" + "time" + + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/core/vm" + "github.com/ledgerwatch/erigon/core/vm/stack" +) + +type OperationType int + +const ( + TRANSFER OperationType = 0 + SELF_DESTRUCT OperationType = 1 + CREATE OperationType = 2 + CREATE2 OperationType = 3 +) + +type InternalOperation struct { + Type OperationType `json:"type"` + From common.Address `json:"from"` + To common.Address `json:"to"` + Value *hexutil.Big `json:"value"` +} + +type OperationsTracer struct { + ctx context.Context + Results []*InternalOperation +} + +func NewOperationsTracer(ctx context.Context) *OperationsTracer { + return &OperationsTracer{ + ctx: ctx, + Results: make([]*InternalOperation, 0), + } +} + +func (l *OperationsTracer) CaptureStart(depth int, from common.Address, to common.Address, precompile bool, create bool, calltype vm.CallType, input []byte, gas uint64, value *big.Int, codeHash common.Hash) error { + if depth == 0 { + return nil + } + + if calltype == vm.CALLT && value.Uint64() != 0 { + l.Results = append(l.Results, &InternalOperation{TRANSFER, from, to, (*hexutil.Big)(value)}) + return nil + } + if calltype == vm.CREATET { + l.Results = append(l.Results, &InternalOperation{CREATE, from, to, (*hexutil.Big)(value)}) + } + if calltype == vm.CREATE2T { + l.Results = append(l.Results, &InternalOperation{CREATE2, from, to, (*hexutil.Big)(value)}) + } + + return nil +} + +func (l *OperationsTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, rData []byte, contract *vm.Contract, depth int, err error) error { + return nil +} + +func (l *OperationsTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, contract *vm.Contract, depth int, err error) error { + return nil +} + +func (l *OperationsTracer) CaptureEnd(depth int, output []byte, gasUsed uint64, t time.Duration, err error) error { + return nil +} + +func (l *OperationsTracer) CaptureSelfDestruct(from common.Address, to common.Address, value *big.Int) { + l.Results = append(l.Results, &InternalOperation{SELF_DESTRUCT, from, to, (*hexutil.Big)(value)}) +} + +func (l *OperationsTracer) CaptureAccountRead(account common.Address) error { + return nil +} + +func (l *OperationsTracer) CaptureAccountWrite(account common.Address) error { + return nil +} diff --git a/otterscan/transactions/trace_touch.go b/otterscan/transactions/trace_touch.go new file mode 100644 index 00000000000..e6732eaecd3 --- /dev/null +++ b/otterscan/transactions/trace_touch.go @@ -0,0 +1,52 @@ +package otterscan + +import ( + "bytes" + "math/big" + "time" + + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/core/vm" + "github.com/ledgerwatch/erigon/core/vm/stack" +) + +type TouchTracer struct { + searchAddr common.Address + Found bool +} + +func NewTouchTracer(searchAddr common.Address) *TouchTracer { + return &TouchTracer{ + searchAddr: searchAddr, + } +} + +func (l *TouchTracer) CaptureStart(depth int, from common.Address, to common.Address, precompile bool, create bool, calltype vm.CallType, input []byte, gas uint64, value *big.Int, codeHash common.Hash) error { + if !l.Found && (bytes.Equal(l.searchAddr.Bytes(), from.Bytes()) || bytes.Equal(l.searchAddr.Bytes(), to.Bytes())) { + l.Found = true + } + return nil +} + +func (l *TouchTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, rData []byte, contract *vm.Contract, depth int, err error) error { + return nil +} + +func (l *TouchTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, contract *vm.Contract, depth int, err error) error { + return nil +} + +func (l *TouchTracer) CaptureEnd(depth int, output []byte, gasUsed uint64, t time.Duration, err error) error { + return nil +} + +func (l *TouchTracer) CaptureSelfDestruct(from common.Address, to common.Address, value *big.Int) { +} + +func (l *TouchTracer) CaptureAccountRead(account common.Address) error { + return nil +} + +func (l *TouchTracer) CaptureAccountWrite(account common.Address) error { + return nil +} From d47a44f28592810f872d6d1b4eb5399c7a605525 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Mon, 2 Aug 2021 14:54:55 -0300 Subject: [PATCH 002/261] First working prototype for ots_getBlockDetails API; non-optimized --- cmd/rpcdaemon/commands/otterscan_api.go | 135 ++++++++++++++++++++++++ 1 file changed, 135 insertions(+) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 9b7620cc262..c4fa335521d 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -7,7 +7,9 @@ import ( "errors" "fmt" "github.com/RoaringBitmap/roaring/roaring64" + "github.com/holiman/uint256" "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/consensus/ethash" "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/core/rawdb" @@ -19,8 +21,11 @@ import ( "github.com/ledgerwatch/erigon/log" otterscan "github.com/ledgerwatch/erigon/otterscan/transactions" "github.com/ledgerwatch/erigon/params" + "github.com/ledgerwatch/erigon/rpc" + "github.com/ledgerwatch/erigon/turbo/adapter/ethapi" "github.com/ledgerwatch/erigon/turbo/shards" "github.com/ledgerwatch/erigon/turbo/transactions" + "math/big" "sync" ) @@ -47,6 +52,7 @@ type OtterscanAPI interface { GetInternalOperations(ctx context.Context, hash common.Hash) ([]*otterscan.InternalOperation, error) SearchTransactionsBefore(ctx context.Context, addr common.Address, blockNum uint64, minPageSize uint16) (*TransactionsWithReceipts, error) SearchTransactionsAfter(ctx context.Context, addr common.Address, blockNum uint64, minPageSize uint16) (*TransactionsWithReceipts, error) + GetBlockDetails(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) } type OtterscanAPIImpl struct { @@ -520,3 +526,132 @@ func (api *OtterscanAPIImpl) traceBlock(dbtx kv.Tx, ctx context.Context, blockNu return found, &TransactionsWithReceipts{rpcTxs, receipts, false, false}, nil } + +func (api *OtterscanAPIImpl) delegateGetBlockByNumber(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) { + tx, err := api.db.BeginRo(ctx) + if err != nil { + return nil, err + } + defer tx.Rollback() + b, err := api.getBlockByNumber(number, tx) + if err != nil { + return nil, err + } + if b == nil { + return nil, nil + } + additionalFields := make(map[string]interface{}) + + td, err := rawdb.ReadTd(tx, b.Hash(), b.NumberU64()) + if err != nil { + return nil, err + } + additionalFields["totalDifficulty"] = (*hexutil.Big)(td) + additionalFields["transactionCount"] = b.Transactions().Len() + response, err := ethapi.RPCMarshalBlock(b, false, false, additionalFields) + + if err == nil && number == rpc.PendingBlockNumber { + // Pending blocks need to nil out a few fields + for _, field := range []string{"hash", "nonce", "miner"} { + response[field] = nil + } + } + return response, err +} + +func (api *OtterscanAPIImpl) delegateIssuance(ctx context.Context, number rpc.BlockNumber) (Issuance, error) { + tx, err := api.db.BeginRo(ctx) + if err != nil { + return Issuance{}, err + } + defer tx.Rollback() + + chainConfig, err := api.chainConfig(tx) + if err != nil { + return Issuance{}, err + } + if chainConfig.Ethash == nil { + // Clique for example has no issuance + return Issuance{}, nil + } + + block, err := api.getBlockByNumber(number, tx) + if err != nil { + return Issuance{}, err + } + minerReward, uncleRewards := ethash.AccumulateRewards(chainConfig, block.Header(), block.Uncles()) + issuance := minerReward + for _, r := range uncleRewards { + p := r // avoids warning? + issuance.Add(&issuance, &p) + } + + var ret Issuance + ret.BlockReward = hexutil.EncodeBig(minerReward.ToBig()) + ret.Issuance = hexutil.EncodeBig(issuance.ToBig()) + issuance.Sub(&issuance, &minerReward) + ret.UncleReward = hexutil.EncodeBig(issuance.ToBig()) + return ret, nil +} + +func (api *OtterscanAPIImpl) delegateBlockFees(ctx context.Context, number rpc.BlockNumber) (uint64, error) { + tx, err := api.db.BeginRo(ctx) + if err != nil { + return 0, err + } + defer tx.Rollback() + + blockNum, err := getBlockNumber(number, tx) + if err != nil { + return 0, err + } + block, senders, err := rawdb.ReadBlockByNumberWithSenders(tx, blockNum) + if err != nil { + return 0, err + } + if block == nil { + return 0, nil + } + chainConfig, err := api.chainConfig(tx) + if err != nil { + return 0, err + } + receipts, err := getReceipts(ctx, tx, chainConfig, block, senders) + if err != nil { + return 0, fmt.Errorf("getReceipts error: %v", err) + } + fees := uint64(0) + for _, receipt := range receipts { + txn := block.Transactions()[receipt.TransactionIndex] + effectiveGasPrice := uint64(0) + if !chainConfig.IsLondon(block.NumberU64()) { + effectiveGasPrice = txn.GetPrice().Uint64() + } else { + baseFee, _ := uint256.FromBig(block.BaseFee()) + gasPrice := new(big.Int).Add(block.BaseFee(), txn.GetEffectiveGasTip(baseFee).ToBig()) + effectiveGasPrice = gasPrice.Uint64() + } + fees += effectiveGasPrice * receipt.GasUsed + } + + return fees, nil + +} + +func (api *OtterscanAPIImpl) GetBlockDetails(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) { + getBlockRes, err := api.delegateGetBlockByNumber(ctx, number) + if err != nil { + return nil, err + } + getIssuanceRes, err := api.delegateIssuance(ctx, number) + if err != nil { + return nil, err + } + feesRes, err := api.delegateBlockFees(ctx, number) + + response := map[string]interface{}{} + response["block"] = getBlockRes + response["issuance"] = getIssuanceRes + response["totalFees"] = hexutil.Uint64(feesRes) + return response, nil +} From 091a249feeea91db8346f29be15fed05edc536d7 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Mon, 2 Aug 2021 15:18:32 -0300 Subject: [PATCH 003/261] Remove duplicated code --- cmd/rpcdaemon/commands/otterscan_api.go | 82 ++++++++----------------- 1 file changed, 27 insertions(+), 55 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index c4fa335521d..e5b7240dded 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -527,19 +527,7 @@ func (api *OtterscanAPIImpl) traceBlock(dbtx kv.Tx, ctx context.Context, blockNu return found, &TransactionsWithReceipts{rpcTxs, receipts, false, false}, nil } -func (api *OtterscanAPIImpl) delegateGetBlockByNumber(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) { - tx, err := api.db.BeginRo(ctx) - if err != nil { - return nil, err - } - defer tx.Rollback() - b, err := api.getBlockByNumber(number, tx) - if err != nil { - return nil, err - } - if b == nil { - return nil, nil - } +func (api *OtterscanAPIImpl) delegateGetBlockByNumber(tx kv.Tx, b *types.Block, number rpc.BlockNumber) (map[string]interface{}, error) { additionalFields := make(map[string]interface{}) td, err := rawdb.ReadTd(tx, b.Hash(), b.NumberU64()) @@ -559,26 +547,12 @@ func (api *OtterscanAPIImpl) delegateGetBlockByNumber(ctx context.Context, numbe return response, err } -func (api *OtterscanAPIImpl) delegateIssuance(ctx context.Context, number rpc.BlockNumber) (Issuance, error) { - tx, err := api.db.BeginRo(ctx) - if err != nil { - return Issuance{}, err - } - defer tx.Rollback() - - chainConfig, err := api.chainConfig(tx) - if err != nil { - return Issuance{}, err - } +func (api *OtterscanAPIImpl) delegateIssuance(tx kv.Tx, block *types.Block, chainConfig *params.ChainConfig) (Issuance, error) { if chainConfig.Ethash == nil { // Clique for example has no issuance return Issuance{}, nil } - block, err := api.getBlockByNumber(number, tx) - if err != nil { - return Issuance{}, err - } minerReward, uncleRewards := ethash.AccumulateRewards(chainConfig, block.Header(), block.Uncles()) issuance := minerReward for _, r := range uncleRewards { @@ -594,32 +568,12 @@ func (api *OtterscanAPIImpl) delegateIssuance(ctx context.Context, number rpc.Bl return ret, nil } -func (api *OtterscanAPIImpl) delegateBlockFees(ctx context.Context, number rpc.BlockNumber) (uint64, error) { - tx, err := api.db.BeginRo(ctx) - if err != nil { - return 0, err - } - defer tx.Rollback() - - blockNum, err := getBlockNumber(number, tx) - if err != nil { - return 0, err - } - block, senders, err := rawdb.ReadBlockByNumberWithSenders(tx, blockNum) - if err != nil { - return 0, err - } - if block == nil { - return 0, nil - } - chainConfig, err := api.chainConfig(tx) - if err != nil { - return 0, err - } - receipts, err := getReceipts(ctx, tx, chainConfig, block, senders) +func (api *OtterscanAPIImpl) delegateBlockFees(ctx context.Context, tx kv.Tx, block *types.Block, chainConfig *params.ChainConfig) (uint64, error) { + receipts, err := getReceipts(ctx, tx, chainConfig, block, nil) if err != nil { return 0, fmt.Errorf("getReceipts error: %v", err) } + fees := uint64(0) for _, receipt := range receipts { txn := block.Transactions()[receipt.TransactionIndex] @@ -635,19 +589,37 @@ func (api *OtterscanAPIImpl) delegateBlockFees(ctx context.Context, number rpc.B } return fees, nil - } func (api *OtterscanAPIImpl) GetBlockDetails(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) { - getBlockRes, err := api.delegateGetBlockByNumber(ctx, number) + tx, err := api.db.BeginRo(ctx) + if err != nil { + return nil, err + } + defer tx.Rollback() + + b, err := api.getBlockByNumber(number, tx) + if err != nil { + return nil, err + } + if b == nil { + return nil, nil + } + + chainConfig, err := api.chainConfig(tx) + if err != nil { + return nil, err + } + + getBlockRes, err := api.delegateGetBlockByNumber(tx, b, number) if err != nil { return nil, err } - getIssuanceRes, err := api.delegateIssuance(ctx, number) + getIssuanceRes, err := api.delegateIssuance(tx, b, chainConfig) if err != nil { return nil, err } - feesRes, err := api.delegateBlockFees(ctx, number) + feesRes, err := api.delegateBlockFees(ctx, tx, b, chainConfig) response := map[string]interface{}{} response["block"] = getBlockRes From 677bfe489dea1ddbeb84fdc7cf48ee43c826a0f4 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Mon, 2 Aug 2021 15:23:42 -0300 Subject: [PATCH 004/261] Remove logsBloom; big and unused --- cmd/rpcdaemon/commands/otterscan_api.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index e5b7240dded..8be3a5b31bb 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -544,6 +544,9 @@ func (api *OtterscanAPIImpl) delegateGetBlockByNumber(tx kv.Tx, b *types.Block, response[field] = nil } } + + // Explicitly drop unwanted fields + response["logsBloom"] = nil return response, err } From 79c5ee30691fab537f333e8fdee8eeac11e8ca62 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Mon, 2 Aug 2021 15:31:35 -0300 Subject: [PATCH 005/261] Fix senders error --- cmd/rpcdaemon/commands/otterscan_api.go | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 8be3a5b31bb..10404c8fd91 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -571,8 +571,8 @@ func (api *OtterscanAPIImpl) delegateIssuance(tx kv.Tx, block *types.Block, chai return ret, nil } -func (api *OtterscanAPIImpl) delegateBlockFees(ctx context.Context, tx kv.Tx, block *types.Block, chainConfig *params.ChainConfig) (uint64, error) { - receipts, err := getReceipts(ctx, tx, chainConfig, block, nil) +func (api *OtterscanAPIImpl) delegateBlockFees(ctx context.Context, tx kv.Tx, block *types.Block, senders []common.Address, chainConfig *params.ChainConfig) (uint64, error) { + receipts, err := getReceipts(ctx, tx, chainConfig, block, senders) if err != nil { return 0, fmt.Errorf("getReceipts error: %v", err) } @@ -594,6 +594,20 @@ func (api *OtterscanAPIImpl) delegateBlockFees(ctx context.Context, tx kv.Tx, bl return fees, nil } +func (api *OtterscanAPIImpl) getBlockWithSenders(number rpc.BlockNumber, tx kv.Tx) (*types.Block, []common.Address, error) { + if number == rpc.PendingBlockNumber { + return api.pendingBlock(), nil, nil + } + + n, err := getBlockNumber(number, tx) + if err != nil { + return nil, nil, err + } + + block, senders, err := rawdb.ReadBlockByNumberWithSenders(tx, n) + return block, senders, err +} + func (api *OtterscanAPIImpl) GetBlockDetails(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) { tx, err := api.db.BeginRo(ctx) if err != nil { @@ -601,7 +615,7 @@ func (api *OtterscanAPIImpl) GetBlockDetails(ctx context.Context, number rpc.Blo } defer tx.Rollback() - b, err := api.getBlockByNumber(number, tx) + b, senders, err := api.getBlockWithSenders(number, tx) if err != nil { return nil, err } @@ -622,7 +636,7 @@ func (api *OtterscanAPIImpl) GetBlockDetails(ctx context.Context, number rpc.Blo if err != nil { return nil, err } - feesRes, err := api.delegateBlockFees(ctx, tx, b, chainConfig) + feesRes, err := api.delegateBlockFees(ctx, tx, b, senders, chainConfig) response := map[string]interface{}{} response["block"] = getBlockRes From 2ee4b9e733f3c022410a33351e1d633974e7f083 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Mon, 2 Aug 2021 23:12:25 -0300 Subject: [PATCH 006/261] First iteration at ots_getBlockTransactions --- cmd/rpcdaemon/commands/otterscan_api.go | 78 ++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 8 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 10404c8fd91..88a079799a1 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -18,11 +18,11 @@ import ( "github.com/ledgerwatch/erigon/core/vm" "github.com/ledgerwatch/erigon/ethdb" "github.com/ledgerwatch/erigon/ethdb/kv" + "github.com/ledgerwatch/erigon/internal/ethapi" "github.com/ledgerwatch/erigon/log" otterscan "github.com/ledgerwatch/erigon/otterscan/transactions" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/rpc" - "github.com/ledgerwatch/erigon/turbo/adapter/ethapi" "github.com/ledgerwatch/erigon/turbo/shards" "github.com/ledgerwatch/erigon/turbo/transactions" "math/big" @@ -53,6 +53,7 @@ type OtterscanAPI interface { SearchTransactionsBefore(ctx context.Context, addr common.Address, blockNum uint64, minPageSize uint16) (*TransactionsWithReceipts, error) SearchTransactionsAfter(ctx context.Context, addr common.Address, blockNum uint64, minPageSize uint16) (*TransactionsWithReceipts, error) GetBlockDetails(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) + GetBlockTransactions(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) } type OtterscanAPIImpl struct { @@ -527,16 +528,14 @@ func (api *OtterscanAPIImpl) traceBlock(dbtx kv.Tx, ctx context.Context, blockNu return found, &TransactionsWithReceipts{rpcTxs, receipts, false, false}, nil } -func (api *OtterscanAPIImpl) delegateGetBlockByNumber(tx kv.Tx, b *types.Block, number rpc.BlockNumber) (map[string]interface{}, error) { - additionalFields := make(map[string]interface{}) - +func (api *OtterscanAPIImpl) delegateGetBlockByNumber(tx kv.Tx, b *types.Block, number rpc.BlockNumber, inclTx bool) (map[string]interface{}, error) { td, err := rawdb.ReadTd(tx, b.Hash(), b.NumberU64()) if err != nil { return nil, err } - additionalFields["totalDifficulty"] = (*hexutil.Big)(td) - additionalFields["transactionCount"] = b.Transactions().Len() - response, err := ethapi.RPCMarshalBlock(b, false, false, additionalFields) + response, err := ethapi.RPCMarshalBlock(b, inclTx, inclTx) + response["totalDifficulty"] = (*hexutil.Big)(td) + response["transactionCount"] = b.Transactions().Len() if err == nil && number == rpc.PendingBlockNumber { // Pending blocks need to nil out a few fields @@ -628,7 +627,7 @@ func (api *OtterscanAPIImpl) GetBlockDetails(ctx context.Context, number rpc.Blo return nil, err } - getBlockRes, err := api.delegateGetBlockByNumber(tx, b, number) + getBlockRes, err := api.delegateGetBlockByNumber(tx, b, number, false) if err != nil { return nil, err } @@ -637,6 +636,9 @@ func (api *OtterscanAPIImpl) GetBlockDetails(ctx context.Context, number rpc.Blo return nil, err } feesRes, err := api.delegateBlockFees(ctx, tx, b, senders, chainConfig) + if err != nil { + return nil, err + } response := map[string]interface{}{} response["block"] = getBlockRes @@ -644,3 +646,63 @@ func (api *OtterscanAPIImpl) GetBlockDetails(ctx context.Context, number rpc.Blo response["totalFees"] = hexutil.Uint64(feesRes) return response, nil } + +func (api *OtterscanAPIImpl) GetBlockTransactions(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) { + tx, err := api.db.BeginRo(ctx) + if err != nil { + return nil, err + } + defer tx.Rollback() + + b, senders, err := api.getBlockWithSenders(number, tx) + if err != nil { + return nil, err + } + if b == nil { + return nil, nil + } + + chainConfig, err := api.chainConfig(tx) + if err != nil { + return nil, err + } + + getBlockRes, err := api.delegateGetBlockByNumber(tx, b, number, true) + if err != nil { + return nil, err + } + + // Receipts + receipts, err := getReceipts(ctx, tx, chainConfig, b, senders) + if err != nil { + return nil, fmt.Errorf("getReceipts error: %v", err) + } + result := make([]map[string]interface{}, 0, len(receipts)) + for _, receipt := range receipts { + txn := b.Transactions()[receipt.TransactionIndex] + marshalledRcpt := marshalReceipt(receipt, txn, chainConfig, b) + marshalledRcpt["logs"] = nil + marshalledRcpt["logsBloom"] = nil + result = append(result, marshalledRcpt) + } + + // Pruned block attrs + prunedBlock := map[string]interface{}{} + for _, k := range []string{"timestamp", "miner", "baseFeePerGas"} { + prunedBlock[k] = getBlockRes[k] + } + + // Crop tx input to 4bytes + var txs = getBlockRes["transactions"].([]interface{}) + for _, rawTx := range txs { + rpcTx := rawTx.(*ethapi.RPCTransaction) + if len(rpcTx.Input) >= 4 { + rpcTx.Input = rpcTx.Input[:4] + } + } + + response := map[string]interface{}{} + response["fullblock"] = getBlockRes + response["receipts"] = result + return response, nil +} From 94b6bff766a1b5c9eff2a5a86e159d0cfba17a94 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Tue, 3 Aug 2021 01:33:44 -0300 Subject: [PATCH 007/261] Add pagination --- cmd/rpcdaemon/commands/otterscan_api.go | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 88a079799a1..e544fd363a4 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -53,7 +53,7 @@ type OtterscanAPI interface { SearchTransactionsBefore(ctx context.Context, addr common.Address, blockNum uint64, minPageSize uint16) (*TransactionsWithReceipts, error) SearchTransactionsAfter(ctx context.Context, addr common.Address, blockNum uint64, minPageSize uint16) (*TransactionsWithReceipts, error) GetBlockDetails(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) - GetBlockTransactions(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) + GetBlockTransactions(ctx context.Context, number rpc.BlockNumber, pageNumber uint8, pageSize uint8) (map[string]interface{}, error) } type OtterscanAPIImpl struct { @@ -647,7 +647,7 @@ func (api *OtterscanAPIImpl) GetBlockDetails(ctx context.Context, number rpc.Blo return response, nil } -func (api *OtterscanAPIImpl) GetBlockTransactions(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) { +func (api *OtterscanAPIImpl) GetBlockTransactions(ctx context.Context, number rpc.BlockNumber, pageNumber uint8, pageSize uint8) (map[string]interface{}, error) { tx, err := api.db.BeginRo(ctx) if err != nil { return nil, err @@ -701,8 +701,19 @@ func (api *OtterscanAPIImpl) GetBlockTransactions(ctx context.Context, number rp } } + // Crop page + pageEnd := b.Transactions().Len() - int(pageNumber)*int(pageSize) + pageStart := pageEnd - int(pageSize) + if pageEnd < 0 { + pageEnd = 0 + } + if pageStart < 0 { + pageStart = 0 + } + response := map[string]interface{}{} + getBlockRes["transactions"] = getBlockRes["transactions"].([]interface{})[pageStart:pageEnd] response["fullblock"] = getBlockRes - response["receipts"] = result + response["receipts"] = result[pageStart:pageEnd] return response, nil } From 4e591385f7378a410312455a117a3f106b6d7ef3 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Fri, 6 Aug 2021 20:00:15 -0300 Subject: [PATCH 008/261] Changes to make otterscan patches work with tag v2021.08.01 --- cmd/rpcdaemon/commands/otterscan_api.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index e544fd363a4..f5af93a17df 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -8,6 +8,7 @@ import ( "fmt" "github.com/RoaringBitmap/roaring/roaring64" "github.com/holiman/uint256" + "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/consensus/ethash" @@ -17,14 +18,13 @@ import ( "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/vm" "github.com/ledgerwatch/erigon/ethdb" - "github.com/ledgerwatch/erigon/ethdb/kv" "github.com/ledgerwatch/erigon/internal/ethapi" - "github.com/ledgerwatch/erigon/log" otterscan "github.com/ledgerwatch/erigon/otterscan/transactions" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/shards" "github.com/ledgerwatch/erigon/turbo/transactions" + "github.com/ledgerwatch/log/v3" "math/big" "sync" ) From 496a25c53a4956d4ff7b9013dd6098adbb6ae002 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Fri, 13 Aug 2021 00:11:28 -0300 Subject: [PATCH 009/261] Changes on otterscan patches to make it work with v2021.08.02 tag --- cmd/rpcdaemon/commands/otterscan_api.go | 4 ++-- otterscan/transactions/trace_operations.go | 4 ++-- otterscan/transactions/trace_touch.go | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index f5af93a17df..9eaae043122 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -99,7 +99,7 @@ func (api *OtterscanAPIImpl) GetInternalOperations(ctx context.Context, hash com getHeader := func(hash common.Hash, number uint64) *types.Header { return rawdb.ReadHeader(tx, hash, number) } - checkTEVM := ethdb.GetCheckTEVM(tx) + checkTEVM := ethdb.GetHasTEVM(tx) msg, blockCtx, txCtx, ibs, _, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, checkTEVM, ethash.NewFaker(), tx, blockHash, txIndex) if err != nil { return nil, err @@ -495,7 +495,7 @@ func (api *OtterscanAPIImpl) traceBlock(dbtx kv.Tx, ctx context.Context, blockNu return rawdb.ReadHeader(dbtx, hash, number) } engine := ethash.NewFaker() - checkTEVM := ethdb.GetCheckTEVM(dbtx) + checkTEVM := ethdb.GetHasTEVM(dbtx) blockReceipts := rawdb.ReadReceipts(dbtx, block, senders) header := block.Header() diff --git a/otterscan/transactions/trace_operations.go b/otterscan/transactions/trace_operations.go index 5d26669b6f4..ce3d03f95c1 100644 --- a/otterscan/transactions/trace_operations.go +++ b/otterscan/transactions/trace_operations.go @@ -39,7 +39,7 @@ func NewOperationsTracer(ctx context.Context) *OperationsTracer { } } -func (l *OperationsTracer) CaptureStart(depth int, from common.Address, to common.Address, precompile bool, create bool, calltype vm.CallType, input []byte, gas uint64, value *big.Int, codeHash common.Hash) error { +func (l *OperationsTracer) CaptureStart(depth int, from common.Address, to common.Address, precompile bool, create bool, calltype vm.CallType, input []byte, gas uint64, value *big.Int, code []byte) error { if depth == 0 { return nil } @@ -66,7 +66,7 @@ func (l *OperationsTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, ga return nil } -func (l *OperationsTracer) CaptureEnd(depth int, output []byte, gasUsed uint64, t time.Duration, err error) error { +func (l *OperationsTracer) CaptureEnd(depth int, output []byte, startGas, endGas uint64, t time.Duration, err error) error { return nil } diff --git a/otterscan/transactions/trace_touch.go b/otterscan/transactions/trace_touch.go index e6732eaecd3..f2a6704dfd6 100644 --- a/otterscan/transactions/trace_touch.go +++ b/otterscan/transactions/trace_touch.go @@ -21,7 +21,7 @@ func NewTouchTracer(searchAddr common.Address) *TouchTracer { } } -func (l *TouchTracer) CaptureStart(depth int, from common.Address, to common.Address, precompile bool, create bool, calltype vm.CallType, input []byte, gas uint64, value *big.Int, codeHash common.Hash) error { +func (l *TouchTracer) CaptureStart(depth int, from common.Address, to common.Address, precompile bool, create bool, calltype vm.CallType, input []byte, gas uint64, value *big.Int, code []byte) error { if !l.Found && (bytes.Equal(l.searchAddr.Bytes(), from.Bytes()) || bytes.Equal(l.searchAddr.Bytes(), to.Bytes())) { l.Found = true } @@ -36,7 +36,7 @@ func (l *TouchTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, co return nil } -func (l *TouchTracer) CaptureEnd(depth int, output []byte, gasUsed uint64, t time.Duration, err error) error { +func (l *TouchTracer) CaptureEnd(depth int, output []byte, startGas, endGas uint64, t time.Duration, err error) error { return nil } From 0ff078f8c015ca0d0e28dbd953e37f8b852875cc Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Fri, 3 Sep 2021 05:28:40 -0300 Subject: [PATCH 010/261] Automate build/push pre-built docker images of patched Erigon Otterscan --- .github/workflows/ci.yml | 75 ------------------------- .github/workflows/docker-publish.yaml | 80 +++++++++++++++++++++++++++ Dockerfile | 10 ++-- 3 files changed, 85 insertions(+), 80 deletions(-) delete mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/docker-publish.yaml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index e2aaa7d77c5..00000000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,75 +0,0 @@ -name: Continuous integration -on: - push: - branches: - - devel - pull_request: - branches: - - devel -jobs: - tests: - strategy: - matrix: - os: [ ubuntu-16.04, ubuntu-20.04, macos-10.15 ] # list of os: https://github.com/actions/virtual-environments - runs-on: ${{ matrix.os }} - - steps: - - uses: actions/checkout@v2 - - run: git submodule update --init --recursive --force - - uses: actions/setup-go@v2 - with: - go-version: 1.17.x - - name: Install dependencies - run: | - if [ "$RUNNER_OS" == "Linux" ]; then - sudo apt update && sudo apt install build-essential - fi - shell: bash - - uses: actions/cache@v2 - with: - path: ~/go/pkg/mod - key: ${{ matrix.os }}-go-${{ hashFiles('**/go.sum') }} - - run: make all - - name: Reproducible build test - run: | - shasum -a256 ./build/bin/erigon > erigon1.sha256 - make erigon - shasum -a256 ./build/bin/erigon > erigon2.sha256 - if ! cmp -s erigon1.sha256 erigon2.sha256; then - echo >&2 "Reproducible build broken"; exit 1 - fi - - name: Lint - if: matrix.os == 'ubuntu-20.04' - uses: golangci/golangci-lint-action@v2 - with: - version: v1.41 - skip-go-installation: true - skip-pkg-cache: true - skip-build-cache: true - - run: make test - - win: - strategy: - matrix: - os: [ windows-2019 ] - runs-on: ${{ matrix.os }} - - steps: - - uses: actions/checkout@v2 - - run: git submodule update --init --recursive --force - - uses: actions/setup-go@v2 - with: - go-version: 1.17.x - - run: choco upgrade mingw cmake -y --no-progress - - name: Build - run: | - .\wmake.ps1 - make test - shell: powershell - - docker: - runs-on: ubuntu-18.04 - steps: - - uses: actions/checkout@v2 - - run: git submodule update --init --recursive --force - - run: docker build . diff --git a/.github/workflows/docker-publish.yaml b/.github/workflows/docker-publish.yaml new file mode 100644 index 00000000000..1118ddcd558 --- /dev/null +++ b/.github/workflows/docker-publish.yaml @@ -0,0 +1,80 @@ +name: Publish Docker image + +on: + push: + branches: + - "otterscan-develop" + - "setup-docker" + tags: + - "*-otterscan" + +env: + IMAGE_NAME: ${{ github.repository }} + +jobs: + push_to_registry: + name: Push Docker image to Docker Hub + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout + uses: actions/checkout@v2.3.4 + with: + submodules: recursive + + - name: Cache Docker layers + uses: actions/cache@v2 + with: + path: /tmp/.buildx-cache + key: ${{ runner.os }}-buildx-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-buildx- + + - name: Docker Setup Buildx + uses: docker/setup-buildx-action@v1.5.1 + with: + driver: docker-container + driver-opts: | + image=moby/buildkit:master + + - name: Docker Login + uses: docker/login-action@v1.10.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Docker Login + uses: docker/login-action@v1.10.0 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Docker Metadata action + id: meta + uses: docker/metadata-action@v3.4.1 + with: + images: | + otterscan/erigon + ghcr.io/${{ env.IMAGE_NAME }} + + - name: Build and push Docker images + uses: docker/build-push-action@v2.6.1 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=local,src=/tmp/.buildx-cache + cache-to: type=local,dest=/tmp/.buildx-cache-new + + # Temp fix + # https://github.com/docker/build-push-action/issues/252 + # https://github.com/moby/buildkit/issues/1896 + - name: Move cache + run: | + rm -rf /tmp/.buildx-cache + mv /tmp/.buildx-cache-new /tmp/.buildx-cache diff --git a/Dockerfile b/Dockerfile index 29acc9e2dc5..04bcd025672 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,11 +27,11 @@ EXPOSE 8545 8546 30303 30303/udp 30304 30304/udp 8080 9090 6060 ARG BUILD_DATE ARG VCS_REF LABEL org.label-schema.build-date=$BUILD_DATE \ - org.label-schema.name="Erigon" \ - org.label-schema.description="Erigon Ethereum Client" \ - org.label-schema.url="https://torquem.ch" \ + org.label-schema.name="Otterscan/Erigon" \ + org.label-schema.description="Otterscan patched version of Erigon Ethereum Client" \ + org.label-schema.url="https://otterscan.io" \ org.label-schema.vcs-ref=$VCS_REF \ - org.label-schema.vcs-url="https://github.com/ledgerwatch/erigon.git" \ - org.label-schema.vendor="Torquem" \ + org.label-schema.vcs-url="https://github.com/wmitsuda/erigon.git" \ + org.label-schema.vendor="Otterscan" \ org.label-schema.version=$VERSION \ org.label-schema.schema-version="1.0" From 3dbdfeabb612feaa7bf6604c2c06efdf86509f3d Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Tue, 26 Oct 2021 22:11:04 -0300 Subject: [PATCH 011/261] First working prototype --- cmd/rpcdaemon/commands/otterscan_api.go | 46 +++++++++++- otterscan/transactions/trace_transaction.go | 78 +++++++++++++++++++++ 2 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 otterscan/transactions/trace_transaction.go diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 9eaae043122..3ba6cdc4315 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -30,7 +30,7 @@ import ( ) // API_LEVEL Must be incremented every time new additions are made -const API_LEVEL = 2 +const API_LEVEL = 3 type SearchResult struct { BlockNumber uint64 @@ -54,6 +54,7 @@ type OtterscanAPI interface { SearchTransactionsAfter(ctx context.Context, addr common.Address, blockNum uint64, minPageSize uint16) (*TransactionsWithReceipts, error) GetBlockDetails(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) GetBlockTransactions(ctx context.Context, number rpc.BlockNumber, pageNumber uint8, pageSize uint8) (map[string]interface{}, error) + TraceTransaction(ctx context.Context, hash common.Hash) ([]*otterscan.TraceEntry, error) } type OtterscanAPIImpl struct { @@ -717,3 +718,46 @@ func (api *OtterscanAPIImpl) GetBlockTransactions(ctx context.Context, number rp response["receipts"] = result[pageStart:pageEnd] return response, nil } + +func (api *OtterscanAPIImpl) TraceTransaction(ctx context.Context, hash common.Hash) ([]*otterscan.TraceEntry, error) { + tx, err := api.db.BeginRo(ctx) + if err != nil { + return nil, err + } + defer tx.Rollback() + + txn, blockHash, _, txIndex, err := rawdb.ReadTransaction(tx, hash) + if err != nil { + return nil, err + } + if txn == nil { + return nil, fmt.Errorf("transaction %#x not found", hash) + } + block, err := rawdb.ReadBlockByHash(tx, blockHash) + if err != nil { + return nil, err + } + + chainConfig, err := api.chainConfig(tx) + if err != nil { + return nil, err + } + + getHeader := func(hash common.Hash, number uint64) *types.Header { + return rawdb.ReadHeader(tx, hash, number) + } + checkTEVM := ethdb.GetHasTEVM(tx) + msg, blockCtx, txCtx, ibs, _, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, checkTEVM, ethash.NewFaker(), tx, blockHash, txIndex) + if err != nil { + return nil, err + } + + tracer := otterscan.NewTransactionTracer(ctx) + vmenv := vm.NewEVM(blockCtx, txCtx, ibs, chainConfig, vm.Config{Debug: true, Tracer: tracer}) + + if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), true, false /* gasBailout */); err != nil { + return nil, fmt.Errorf("tracing failed: %v", err) + } + + return tracer.Results, nil +} diff --git a/otterscan/transactions/trace_transaction.go b/otterscan/transactions/trace_transaction.go new file mode 100644 index 00000000000..102fed2d72a --- /dev/null +++ b/otterscan/transactions/trace_transaction.go @@ -0,0 +1,78 @@ +package otterscan + +import ( + "context" + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/common/hexutil" + "github.com/ledgerwatch/erigon/core/vm" + "github.com/ledgerwatch/erigon/core/vm/stack" + "math/big" + "time" +) + +type TraceEntry struct { + Type string `json:"type"` + Depth int `json:"depth"` + From common.Address `json:"from"` + To common.Address `json:"to"` + Value *hexutil.Big `json:"value"` + Input hexutil.Bytes `json:"input"` +} + +type TransactionTracer struct { + ctx context.Context + Results []*TraceEntry +} + +func NewTransactionTracer(ctx context.Context) *TransactionTracer { + return &TransactionTracer{ + ctx: ctx, + Results: make([]*TraceEntry, 0), + } +} + +func (l *TransactionTracer) CaptureStart(depth int, from common.Address, to common.Address, precompile bool, create bool, callType vm.CallType, input []byte, gas uint64, value *big.Int, code []byte) error { + inputCopy := make([]byte, len(input)) + copy(inputCopy, input) + if callType == vm.CALLT { + l.Results = append(l.Results, &TraceEntry{"CALL", depth, from, to, (*hexutil.Big)(value), inputCopy}) + return nil + } + if callType == vm.STATICCALLT { + l.Results = append(l.Results, &TraceEntry{"STATICCALL", depth, from, to, (*hexutil.Big)(value), inputCopy}) + return nil + } + if callType == vm.CREATET { + l.Results = append(l.Results, &TraceEntry{"CREATE", depth, from, to, (*hexutil.Big)(value), inputCopy}) + return nil + } + if callType == vm.CREATE2T { + l.Results = append(l.Results, &TraceEntry{"CREATE2", depth, from, to, (*hexutil.Big)(value), inputCopy}) + return nil + } + + return nil +} + +func (l *TransactionTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, rData []byte, contract *vm.Contract, depth int, err error) error { + return nil +} + +func (l *TransactionTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, contract *vm.Contract, depth int, err error) error { + return nil +} + +func (l *TransactionTracer) CaptureEnd(depth int, output []byte, startGas, endGas uint64, t time.Duration, err error) error { + return nil +} + +func (l *TransactionTracer) CaptureSelfDestruct(from common.Address, to common.Address, value *big.Int) { +} + +func (l *TransactionTracer) CaptureAccountRead(account common.Address) error { + return nil +} + +func (*TransactionTracer) CaptureAccountWrite(account common.Address) error { + return nil +} From a7cf698210ba3c39254cfadeb357a3995674d269 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Wed, 27 Oct 2021 01:24:02 -0300 Subject: [PATCH 012/261] Ignore precompiles --- otterscan/transactions/trace_transaction.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/otterscan/transactions/trace_transaction.go b/otterscan/transactions/trace_transaction.go index 102fed2d72a..ccba17d4719 100644 --- a/otterscan/transactions/trace_transaction.go +++ b/otterscan/transactions/trace_transaction.go @@ -32,6 +32,10 @@ func NewTransactionTracer(ctx context.Context) *TransactionTracer { } func (l *TransactionTracer) CaptureStart(depth int, from common.Address, to common.Address, precompile bool, create bool, callType vm.CallType, input []byte, gas uint64, value *big.Int, code []byte) error { + if precompile { + return nil + } + inputCopy := make([]byte, len(input)) copy(inputCopy, input) if callType == vm.CALLT { From 1fc47ed86b6d73607345a44010c03b34087eed19 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Wed, 27 Oct 2021 01:32:47 -0300 Subject: [PATCH 013/261] Enable DELEGATECALL tracing --- otterscan/transactions/trace_transaction.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/otterscan/transactions/trace_transaction.go b/otterscan/transactions/trace_transaction.go index ccba17d4719..74fd965dd1e 100644 --- a/otterscan/transactions/trace_transaction.go +++ b/otterscan/transactions/trace_transaction.go @@ -46,6 +46,14 @@ func (l *TransactionTracer) CaptureStart(depth int, from common.Address, to comm l.Results = append(l.Results, &TraceEntry{"STATICCALL", depth, from, to, (*hexutil.Big)(value), inputCopy}) return nil } + if callType == vm.DELEGATECALLT { + l.Results = append(l.Results, &TraceEntry{"DELEGATECALL", depth, from, to, (*hexutil.Big)(value), inputCopy}) + return nil + } + if callType == vm.CALLCODET { + l.Results = append(l.Results, &TraceEntry{"CALLCODE", depth, from, to, (*hexutil.Big)(value), inputCopy}) + return nil + } if callType == vm.CREATET { l.Results = append(l.Results, &TraceEntry{"CREATE", depth, from, to, (*hexutil.Big)(value), inputCopy}) return nil From 0d61552521686ba45f6b4eea90568ab446eb9e6e Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Wed, 27 Oct 2021 14:56:38 -0300 Subject: [PATCH 014/261] Fix value parsing --- otterscan/transactions/trace_transaction.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/otterscan/transactions/trace_transaction.go b/otterscan/transactions/trace_transaction.go index 74fd965dd1e..362f5c85bcc 100644 --- a/otterscan/transactions/trace_transaction.go +++ b/otterscan/transactions/trace_transaction.go @@ -38,20 +38,22 @@ func (l *TransactionTracer) CaptureStart(depth int, from common.Address, to comm inputCopy := make([]byte, len(input)) copy(inputCopy, input) + _value := new(big.Int) + _value.Set(value) if callType == vm.CALLT { - l.Results = append(l.Results, &TraceEntry{"CALL", depth, from, to, (*hexutil.Big)(value), inputCopy}) + l.Results = append(l.Results, &TraceEntry{"CALL", depth, from, to, (*hexutil.Big)(_value), inputCopy}) return nil } if callType == vm.STATICCALLT { - l.Results = append(l.Results, &TraceEntry{"STATICCALL", depth, from, to, (*hexutil.Big)(value), inputCopy}) + l.Results = append(l.Results, &TraceEntry{"STATICCALL", depth, from, to, nil, inputCopy}) return nil } if callType == vm.DELEGATECALLT { - l.Results = append(l.Results, &TraceEntry{"DELEGATECALL", depth, from, to, (*hexutil.Big)(value), inputCopy}) + l.Results = append(l.Results, &TraceEntry{"DELEGATECALL", depth, from, to, nil, inputCopy}) return nil } if callType == vm.CALLCODET { - l.Results = append(l.Results, &TraceEntry{"CALLCODE", depth, from, to, (*hexutil.Big)(value), inputCopy}) + l.Results = append(l.Results, &TraceEntry{"CALLCODE", depth, from, to, (*hexutil.Big)(_value), inputCopy}) return nil } if callType == vm.CREATET { From 611db5642a068c9a31bd07b2ab1373d05ef0b12c Mon Sep 17 00:00:00 2001 From: Igor Mandrigin Date: Thu, 28 Oct 2021 12:51:52 +0200 Subject: [PATCH 015/261] Revert "begin 2021.11.01 release cycle" This reverts commit 237592581b9d53ff0f2699c551e3de8530a05515. --- params/version.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/params/version.go b/params/version.go index 3b7b910e2c4..355507bbf27 100644 --- a/params/version.go +++ b/params/version.go @@ -32,8 +32,8 @@ var ( // see https://calver.org const ( VersionMajor = 2021 // Major version component of the current release - VersionMinor = 11 // Minor version component of the current release - VersionMicro = 1 // Patch version component of the current release + VersionMinor = 10 // Minor version component of the current release + VersionMicro = 4 // Patch version component of the current release VersionModifier = "alpha" // Patch version component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" From cdc8d2d4fc0205d714bbd8d7c517a6650186d905 Mon Sep 17 00:00:00 2001 From: "alex.sharov" Date: Fri, 29 Oct 2021 15:32:10 +0700 Subject: [PATCH 016/261] save --- go.mod | 4 ++-- go.sum | 8 ++++---- libmdbx | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index 18c39c49a9e..fba28c9cf19 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20211028031035-dce775626001 + github.com/ledgerwatch/erigon-lib v0.0.0-20211029082447-495dae1dce0f github.com/ledgerwatch/log/v3 v3.3.1 github.com/ledgerwatch/secp256k1 v0.0.0-20210626115225-cd5cd00ed72d github.com/logrusorgru/aurora/v3 v3.0.0 @@ -48,7 +48,7 @@ require ( github.com/spf13/cobra v1.2.1 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.7.0 - github.com/torquem-ch/mdbx-go v0.22.0 + github.com/torquem-ch/mdbx-go v0.19.2 github.com/ugorji/go/codec v1.1.13 github.com/ugorji/go/codec/codecgen v1.1.13 github.com/urfave/cli v1.22.5 diff --git a/go.sum b/go.sum index ac93cf2586a..6e9bde7bbec 100644 --- a/go.sum +++ b/go.sum @@ -497,8 +497,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20211028031035-dce775626001 h1:JeAqzPXZvLj+fARrpvvSB4ZAxYcyTDF+J8l6+ErLM1M= -github.com/ledgerwatch/erigon-lib v0.0.0-20211028031035-dce775626001/go.mod h1:+Dgxlx2A74QQAp1boH34onSy3k/qDftDiWvGXGC+5FA= +github.com/ledgerwatch/erigon-lib v0.0.0-20211029082447-495dae1dce0f h1:7sU2HG2aMDszq3nCNVby2xzfoc8a8ouP2eYzBc+tzfw= +github.com/ledgerwatch/erigon-lib v0.0.0-20211029082447-495dae1dce0f/go.mod h1:crehiHCLJeH5oeF10xjPg4uRN5D8cXtY3w9JCMk1D7o= github.com/ledgerwatch/log/v3 v3.3.1 h1:HmvLeTEvtCtqSvtu4t/a5MAdcLfeBcbIeowXbLYuzLc= github.com/ledgerwatch/log/v3 v3.3.1/go.mod h1:S3VJqhhVX32rbp1JyyvhJou12twtFwNEPESBgpbNkRk= github.com/ledgerwatch/secp256k1 v0.0.0-20210626115225-cd5cd00ed72d h1:/IKMrJdfRsoYNc36PXqP4xMH3vhW/8IQyBKGQbKZUno= @@ -752,8 +752,8 @@ github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs= github.com/tklauser/numcpus v0.3.0 h1:ILuRUQBtssgnxw0XXIjKUC56fgnOrFoQQ/4+DeU2biQ= github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8= -github.com/torquem-ch/mdbx-go v0.22.0 h1:d0YMSLQ+Wy4gidxV0SZUgPALRG1lhpEA87Y9m02G/tE= -github.com/torquem-ch/mdbx-go v0.22.0/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= +github.com/torquem-ch/mdbx-go v0.19.2 h1:NpIye75umYlr1oGvBFTIZtOJKdKg44sQVc6t8oGbm4Y= +github.com/torquem-ch/mdbx-go v0.19.2/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= diff --git a/libmdbx b/libmdbx index 710fc95d9a3..70933d81a86 160000 --- a/libmdbx +++ b/libmdbx @@ -1 +1 @@ -Subproject commit 710fc95d9a3fd58e37449f3f7237195546542a75 +Subproject commit 70933d81a86128d6a6f14d7102a9544e4f1807b2 From 805e281ebb848fa69aa9bfa6a9ea75c251459d1f Mon Sep 17 00:00:00 2001 From: Igor Mandrigin Date: Fri, 29 Oct 2021 14:37:13 +0200 Subject: [PATCH 017/261] update version to 10.05 --- params/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/params/version.go b/params/version.go index 355507bbf27..eaab42abd4a 100644 --- a/params/version.go +++ b/params/version.go @@ -33,7 +33,7 @@ var ( const ( VersionMajor = 2021 // Major version component of the current release VersionMinor = 10 // Minor version component of the current release - VersionMicro = 4 // Patch version component of the current release + VersionMicro = 5 // Patch version component of the current release VersionModifier = "alpha" // Patch version component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" From bc43e97d0cc7a3bc15ea9a3406d0026dd521755a Mon Sep 17 00:00:00 2001 From: Igor Mandrigin Date: Thu, 11 Nov 2021 14:18:36 +0100 Subject: [PATCH 018/261] Update version.go --- params/version.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/params/version.go b/params/version.go index 3b7b910e2c4..6c6934bf943 100644 --- a/params/version.go +++ b/params/version.go @@ -33,8 +33,8 @@ var ( const ( VersionMajor = 2021 // Major version component of the current release VersionMinor = 11 // Minor version component of the current release - VersionMicro = 1 // Patch version component of the current release - VersionModifier = "alpha" // Patch version component of the current release + VersionMicro = 2 // Patch version component of the current release + VersionModifier = "beta" // Patch version component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" ) From d217742ace01bfd691af5bf9629558b31ce9f3a2 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Sat, 13 Nov 2021 19:12:48 +0700 Subject: [PATCH 019/261] RPC: don't save nil's to blocksLRU (#2937) (#2948) --- cmd/rpcdaemon/commands/eth_api.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cmd/rpcdaemon/commands/eth_api.go b/cmd/rpcdaemon/commands/eth_api.go index 07ecbb82465..6647b05e86e 100644 --- a/cmd/rpcdaemon/commands/eth_api.go +++ b/cmd/rpcdaemon/commands/eth_api.go @@ -163,7 +163,9 @@ func (api *BaseAPI) blockWithSenders(tx kv.Tx, hash common.Hash, number uint64) if err != nil { return nil, err } - + if block == nil { // don't save nil's to cache + return nil, nil + } if api.blocksLRU != nil { api.blocksLRU.Add(hash, block) } From 30eea012a5ce0e7f8a58947fda403bd360faadfd Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Sat, 13 Nov 2021 19:13:00 +0700 Subject: [PATCH 020/261] Check existence before write - because WriteRawBody isn't idempotent (it allocates new sequence range for transactions on every call) (#2941) (#2949) --- eth/stagedsync/stage_bodies.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/eth/stagedsync/stage_bodies.go b/eth/stagedsync/stage_bodies.go index b2fdc1cfdf0..362d475e659 100644 --- a/eth/stagedsync/stage_bodies.go +++ b/eth/stagedsync/stage_bodies.go @@ -10,6 +10,7 @@ import ( libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/common/dbutils" "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/eth/stagedsync/stages" "github.com/ledgerwatch/erigon/params" @@ -158,12 +159,20 @@ Loop: u.UnwindTo(blockHeight-1, header.Hash()) break Loop } - if err = rawdb.WriteRawBody(tx, header.Hash(), blockHeight, rawBody); err != nil { - return fmt.Errorf("writing block body: %w", err) + + // Check existence before write - because WriteRawBody isn't idempotent (it allocates new sequence range for transactions on every call) + exists, err := tx.Has(kv.BlockBody, dbutils.BlockBodyKey(blockHeight, header.Hash())) + if err != nil { + return err + } + if !exists { + if err = rawdb.WriteRawBody(tx, header.Hash(), blockHeight, rawBody); err != nil { + return fmt.Errorf("writing block body: %w", err) + } } if blockHeight > bodyProgress { bodyProgress = blockHeight - if err = stages.SaveStageProgress(tx, stages.Bodies, blockHeight); err != nil { + if err = s.Update(tx, blockHeight); err != nil { return fmt.Errorf("saving Bodies progress: %w", err) } } From 29790cab3c1913f2a09b12ebc3c5b6a13b181cb8 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Mon, 15 Nov 2021 16:05:18 +0700 Subject: [PATCH 021/261] save (#2956) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 232ff24da94..91b299afd76 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20211104110507-597d0fbb01ab + github.com/ledgerwatch/erigon-lib v0.0.0-20211114052536-25ed30e2432d github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 diff --git a/go.sum b/go.sum index fca5587059d..475309b9ecb 100644 --- a/go.sum +++ b/go.sum @@ -497,8 +497,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20211104110507-597d0fbb01ab h1:CNIgX4Sw1uybwmLgLmWpAaNrm4ADo33BLpz4Zo3FnqI= -github.com/ledgerwatch/erigon-lib v0.0.0-20211104110507-597d0fbb01ab/go.mod h1:CuEZROm43MykZT5CjCj02jw0FOwaDl8Nh+PZkTEGopg= +github.com/ledgerwatch/erigon-lib v0.0.0-20211114052536-25ed30e2432d h1:4LM2ZUpWvweL9laRHi67VKBQa6XGmEQVk8e2AEs/R70= +github.com/ledgerwatch/erigon-lib v0.0.0-20211114052536-25ed30e2432d/go.mod h1:CuEZROm43MykZT5CjCj02jw0FOwaDl8Nh+PZkTEGopg= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= From 84399f845f42183e0c076923a8fc114b614c5d0d Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Mon, 15 Nov 2021 16:05:40 +0700 Subject: [PATCH 022/261] Increase default txpool size (#2963) --- core/tx_pool.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/tx_pool.go b/core/tx_pool.go index b46ac1143dc..809c9fe1472 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -167,9 +167,9 @@ var DefaultTxPoolConfig = TxPoolConfig{ AccountSlots: 16, GlobalSlots: 10_000, - GlobalBaseFeeQueue: 10_000, + GlobalBaseFeeQueue: 30_000, AccountQueue: 64, - GlobalQueue: 10_000, + GlobalQueue: 30_000, Lifetime: 3 * time.Hour, } From d7502fb9ba2c644352172d1256e032013cfbdf73 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Tue, 16 Nov 2021 16:26:09 +0700 Subject: [PATCH 023/261] P2p pooled tx rlp stable (#2967) * save * Update link to erigon-lib stable Co-authored-by: Alexey Sharp --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 91b299afd76..5f03efdfc40 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20211114052536-25ed30e2432d + github.com/ledgerwatch/erigon-lib v0.0.0-20211116070327-c9204777d306 github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 diff --git a/go.sum b/go.sum index 475309b9ecb..465eee228e4 100644 --- a/go.sum +++ b/go.sum @@ -497,8 +497,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20211114052536-25ed30e2432d h1:4LM2ZUpWvweL9laRHi67VKBQa6XGmEQVk8e2AEs/R70= -github.com/ledgerwatch/erigon-lib v0.0.0-20211114052536-25ed30e2432d/go.mod h1:CuEZROm43MykZT5CjCj02jw0FOwaDl8Nh+PZkTEGopg= +github.com/ledgerwatch/erigon-lib v0.0.0-20211116070327-c9204777d306 h1:bMUfndWm3u7oGxkIaP6QgdAke2nJFfj/qDhowZcJjJ8= +github.com/ledgerwatch/erigon-lib v0.0.0-20211116070327-c9204777d306/go.mod h1:CuEZROm43MykZT5CjCj02jw0FOwaDl8Nh+PZkTEGopg= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= From 270438b10ca5883d78670072eda97770e265e866 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Tue, 16 Nov 2021 14:54:56 +0000 Subject: [PATCH 024/261] Run CI actions on PRs and pushes for stable branch (#2970) * Run CI actions on PRs and pushes for stable branch (#2968) * Fix lint Co-authored-by: Alexey Sharp --- .github/workflows/ci.yml | 2 ++ params/version.go | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 21af75bcccb..955251508b0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,9 +3,11 @@ on: push: branches: - devel + - stable pull_request: branches: - devel + - stable jobs: tests: strategy: diff --git a/params/version.go b/params/version.go index 6c6934bf943..9bc5a5d46d1 100644 --- a/params/version.go +++ b/params/version.go @@ -31,9 +31,9 @@ var ( // see https://calver.org const ( - VersionMajor = 2021 // Major version component of the current release - VersionMinor = 11 // Minor version component of the current release - VersionMicro = 2 // Patch version component of the current release + VersionMajor = 2021 // Major version component of the current release + VersionMinor = 11 // Minor version component of the current release + VersionMicro = 2 // Patch version component of the current release VersionModifier = "beta" // Patch version component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" From 928345f0b0bbddbeb48eaf0640a219dbe3ef2c05 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Tue, 16 Nov 2021 16:13:12 +0000 Subject: [PATCH 025/261] [stable] `eth_getTransactionCount` to work with `pending` from txpool (#2971) * pending nonce (#2953) * pending nonce * Increment nonce of last tx to get tx count * Upgrade erigon-lib Co-authored-by: Alex Sharp Co-authored-by: Alexey Sharp * Point to latest stable in erigon-lib Co-authored-by: Alex Sharp Co-authored-by: Alexey Sharp --- cmd/rpcdaemon/commands/eth_accounts.go | 15 +++++++++++++++ go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/cmd/rpcdaemon/commands/eth_accounts.go b/cmd/rpcdaemon/commands/eth_accounts.go index d0089389e05..69533415b94 100644 --- a/cmd/rpcdaemon/commands/eth_accounts.go +++ b/cmd/rpcdaemon/commands/eth_accounts.go @@ -5,9 +5,12 @@ import ( "fmt" "math/big" + "github.com/ledgerwatch/erigon-lib/gointerfaces" "github.com/ledgerwatch/erigon/turbo/adapter" "github.com/ledgerwatch/erigon/turbo/rpchelper" + "google.golang.org/grpc" + txpool_proto "github.com/ledgerwatch/erigon-lib/gointerfaces/txpool" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/rpc" @@ -39,6 +42,18 @@ func (api *APIImpl) GetBalance(ctx context.Context, address common.Address, bloc // GetTransactionCount implements eth_getTransactionCount. Returns the number of transactions sent from an address (the nonce). func (api *APIImpl) GetTransactionCount(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Uint64, error) { + if blockNrOrHash.BlockNumber != nil && *blockNrOrHash.BlockNumber == rpc.PendingBlockNumber { + reply, err := api.txPool.Nonce(ctx, &txpool_proto.NonceRequest{ + Address: gointerfaces.ConvertAddressToH160(address), + }, &grpc.EmptyCallOption{}) + if err != nil { + return nil, err + } + if reply.Found { + reply.Nonce++ + return (*hexutil.Uint64)(&reply.Nonce), nil + } + } tx, err1 := api.db.BeginRo(ctx) if err1 != nil { return nil, fmt.Errorf("getTransactionCount cannot open tx: %w", err1) diff --git a/go.mod b/go.mod index 5f03efdfc40..3d1e59c1720 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20211116070327-c9204777d306 + github.com/ledgerwatch/erigon-lib v0.0.0-20211116105337-347396fb51eb github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 diff --git a/go.sum b/go.sum index 465eee228e4..72d28186a57 100644 --- a/go.sum +++ b/go.sum @@ -497,8 +497,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20211116070327-c9204777d306 h1:bMUfndWm3u7oGxkIaP6QgdAke2nJFfj/qDhowZcJjJ8= -github.com/ledgerwatch/erigon-lib v0.0.0-20211116070327-c9204777d306/go.mod h1:CuEZROm43MykZT5CjCj02jw0FOwaDl8Nh+PZkTEGopg= +github.com/ledgerwatch/erigon-lib v0.0.0-20211116105337-347396fb51eb h1:Y4PO0v++1SaT3DoD+dRhgn+ggYq7m7Gk7NYN67nDQdI= +github.com/ledgerwatch/erigon-lib v0.0.0-20211116105337-347396fb51eb/go.mod h1:CuEZROm43MykZT5CjCj02jw0FOwaDl8Nh+PZkTEGopg= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= From 2d05bd504847591e4573558f8b4529e34958cd87 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Tue, 16 Nov 2021 20:14:15 +0000 Subject: [PATCH 026/261] [beta] Fixes to sentry and downloader (#2972) * Fix header skeleton (#2945) * Fix underflow only * Rename queryRange to maxHeight * Fix additional cases * Fix SendHeaderRequest peer minBlock (#2946) * Add trusted peers flag (#2958) * Refactor and consolidate enode-list config parsing * Add trustedpeers flag * Refactor sentry peers (#2961) * Avoid a redundant rlpHash() in FeedHeader() (#2959) Co-authored-by: TBC Dev <48684072+tbcd@users.noreply.github.com> --- cmd/sentry/commands/sentry.go | 4 +- cmd/sentry/download/sentry.go | 148 ++++++++---------- cmd/sentry/download/sentry_api.go | 2 +- cmd/utils/flags.go | 90 ++++++----- turbo/cli/default_flags.go | 1 + .../stages/headerdownload/header_algo_test.go | 23 +-- turbo/stages/headerdownload/header_algos.go | 30 ++-- 7 files changed, 148 insertions(+), 150 deletions(-) diff --git a/cmd/sentry/commands/sentry.go b/cmd/sentry/commands/sentry.go index 6668efececa..acc0b9a45ac 100644 --- a/cmd/sentry/commands/sentry.go +++ b/cmd/sentry/commands/sentry.go @@ -23,6 +23,7 @@ var ( natSetting string // NAT setting port int // Listening port staticPeers []string // static peers + trustedPeers []string // trusted peers discoveryDNS []string nodiscover bool // disable sentry's discovery mechanism protocol string @@ -44,6 +45,7 @@ func init() { rootCmd.Flags().StringVar(&sentryAddr, "sentry.api.addr", "localhost:9091", "grpc addresses") rootCmd.Flags().StringVar(&protocol, "p2p.protocol", "eth66", "eth65|eth66") rootCmd.Flags().StringSliceVar(&staticPeers, "staticpeers", []string{}, "static peer list [enode]") + rootCmd.Flags().StringSliceVar(&trustedPeers, "trustedpeers", []string{}, "trusted peer list [enode]") rootCmd.Flags().StringSliceVar(&discoveryDNS, utils.DNSDiscoveryFlag.Name, []string{}, utils.DNSDiscoveryFlag.Usage) rootCmd.Flags().BoolVar(&nodiscover, utils.NoDiscoverFlag.Name, false, utils.NoDiscoverFlag.Usage) rootCmd.Flags().StringVar(&netRestrict, "netrestrict", "", "CIDR range to accept peers from ") @@ -76,7 +78,7 @@ var rootCmd = &cobra.Command{ } nodeConfig := node2.NewNodeConfig() - p2pConfig, err := utils.NewP2PConfig(nodiscover, datadir, netRestrict, natSetting, nodeConfig.NodeName(), staticPeers, uint(port), uint(p)) + p2pConfig, err := utils.NewP2PConfig(nodiscover, datadir, netRestrict, natSetting, nodeConfig.NodeName(), staticPeers, trustedPeers, uint(port), uint(p)) if err != nil { return err } diff --git a/cmd/sentry/download/sentry.go b/cmd/sentry/download/sentry.go index e2c077eef2c..ec52974534b 100644 --- a/cmd/sentry/download/sentry.go +++ b/cmd/sentry/download/sentry.go @@ -22,6 +22,7 @@ import ( "github.com/ledgerwatch/erigon-lib/gointerfaces/grpcutil" proto_sentry "github.com/ledgerwatch/erigon-lib/gointerfaces/sentry" proto_types "github.com/ledgerwatch/erigon-lib/gointerfaces/types" + "github.com/ledgerwatch/erigon/cmd/utils" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/debug" "github.com/ledgerwatch/erigon/core/forkid" @@ -123,17 +124,7 @@ func makeP2PServer( case params.FermionGenesisHash: urls = params.FermionBootnodes } - p2pConfig.BootstrapNodes = make([]*enode.Node, 0, len(urls)) - for _, url := range urls { - if url != "" { - node, err := enode.Parse(enode.ValidSchemes, url) - if err != nil { - log.Crit("Bootstrap URL invalid", "enode", url, "err", err) - continue - } - p2pConfig.BootstrapNodes = append(p2pConfig.BootstrapNodes, node) - } - } + p2pConfig.BootstrapNodes, _ = utils.GetUrlListNodes(urls, utils.BootnodesFlag.Name, log.Crit) p2pConfig.BootstrapNodesV5 = p2pConfig.BootstrapNodes p2pConfig.Protocols = []p2p.Protocol{protocol} return &p2p.Server{Config: p2pConfig}, nil @@ -461,7 +452,7 @@ func NewSentryServer(ctx context.Context, dialCandidates enode.Iterator, readNod DialCandidates: dialCandidates, Run: func(peer *p2p.Peer, rw p2p.MsgReadWriter) error { peerID := peer.ID().String() - if _, ok := ss.GoodPeers.Load(peerID); ok { + if ss.getPeer(peerID) != nil { log.Trace(fmt.Sprintf("[%s] Peer already has connection", peerID)) return nil } @@ -500,11 +491,11 @@ func NewSentryServer(ctx context.Context, dialCandidates enode.Iterator, readNod return readNodeInfo() }, PeerInfo: func(id enode.ID) interface{} { - p, ok := ss.GoodPeers.Load(id.String()) - if !ok { - return nil + peerID := id.String() + if peerInfo := ss.getPeer(peerID); peerInfo != nil { + return peerInfo.peer.Info() } - return p.(*PeerInfo).peer.Info() + return nil }, //Attributes: []enr.Entry{eth.CurrentENREntry(chainConfig, genesisHash, headHeight)}, } @@ -549,6 +540,46 @@ type SentryServerImpl struct { p2p *p2p.Config } +func (ss *SentryServerImpl) rangePeers(f func(peerID string, peerInfo *PeerInfo) bool) { + ss.GoodPeers.Range(func(key, value interface{}) bool { + peerInfo, _ := value.(*PeerInfo) + if peerInfo == nil { + return true + } + peerID := key.(string) + return f(peerID, peerInfo) + }) +} + +func (ss *SentryServerImpl) getPeer(peerID string) (peerInfo *PeerInfo) { + if value, ok := ss.GoodPeers.Load(peerID); ok { + peerInfo := value.(*PeerInfo) + if peerInfo != nil { + return peerInfo + } + ss.GoodPeers.Delete(peerID) + } + return nil +} + +func (ss *SentryServerImpl) removePeer(peerID string) { + if value, ok := ss.GoodPeers.LoadAndDelete(peerID); ok { + peerInfo := value.(*PeerInfo) + if peerInfo != nil { + peerInfo.Remove() + } + } +} + +func (ss *SentryServerImpl) writePeer(peerID string, peerInfo *PeerInfo, msgcode uint64, data []byte) error { + err := peerInfo.rw.WriteMsg(p2p.Msg{Code: msgcode, Size: uint32(len(data)), Payload: bytes.NewReader(data)}) + if err != nil { + peerInfo.Remove() + ss.GoodPeers.Delete(peerID) + } + return err +} + func (ss *SentryServerImpl) startSync(ctx context.Context, bestHash common.Hash, peerID string) error { switch ss.Protocol.Version { case eth.ETH65: @@ -600,26 +631,17 @@ func (ss *SentryServerImpl) startSync(ctx context.Context, bestHash common.Hash, func (ss *SentryServerImpl) PenalizePeer(_ context.Context, req *proto_sentry.PenalizePeerRequest) (*emptypb.Empty, error) { //log.Warn("Received penalty", "kind", req.GetPenalty().Descriptor().FullName, "from", fmt.Sprintf("%s", req.GetPeerId())) - strId := string(gointerfaces.ConvertH512ToBytes(req.PeerId)) - if x, ok := ss.GoodPeers.Load(strId); ok { - peerInfo := x.(*PeerInfo) - if peerInfo != nil { - peerInfo.Remove() - } - } - ss.GoodPeers.Delete(strId) + peerID := string(gointerfaces.ConvertH512ToBytes(req.PeerId)) + ss.removePeer(peerID) return &emptypb.Empty{}, nil } func (ss *SentryServerImpl) PeerMinBlock(_ context.Context, req *proto_sentry.PeerMinBlockRequest) (*emptypb.Empty, error) { peerID := string(gointerfaces.ConvertH512ToBytes(req.PeerId)) - x, _ := ss.GoodPeers.Load(peerID) - peerInfo, _ := x.(*PeerInfo) - if peerInfo == nil { - return &emptypb.Empty{}, nil - } - if req.MinBlock > peerInfo.Height() { - peerInfo.SetHeight(req.MinBlock) + if peerInfo := ss.getPeer(peerID); peerInfo != nil { + if req.MinBlock > peerInfo.Height() { + peerInfo.SetHeight(req.MinBlock) + } } return &emptypb.Empty{}, nil } @@ -630,13 +652,7 @@ func (ss *SentryServerImpl) findPeer(minBlock uint64) (string, *PeerInfo, bool) var foundPeerInfo *PeerInfo var maxPermits int now := time.Now() - ss.GoodPeers.Range(func(key, value interface{}) bool { - peerID := key.(string) - x, _ := ss.GoodPeers.Load(peerID) - peerInfo, _ := x.(*PeerInfo) - if peerInfo == nil { - return true - } + ss.rangePeers(func(peerID string, peerInfo *PeerInfo) bool { if peerInfo.Height() >= minBlock { deadlines := peerInfo.ClearDeadlines(now, false /* givePermit */) //fmt.Printf("%d deadlines for peer %s\n", deadlines, peerID) @@ -665,14 +681,7 @@ func (ss *SentryServerImpl) SendMessageByMinBlock(_ context.Context, inreq *prot msgcode != eth.GetPooledTransactionsMsg { return &proto_sentry.SentPeers{}, fmt.Errorf("sendMessageByMinBlock not implemented for message Id: %s", inreq.Data.Id) } - if err := peerInfo.rw.WriteMsg(p2p.Msg{Code: msgcode, Size: uint32(len(inreq.Data.Data)), Payload: bytes.NewReader(inreq.Data.Data)}); err != nil { - if x, ok := ss.GoodPeers.Load(peerID); ok { - peerInfo := x.(*PeerInfo) - if peerInfo != nil { - peerInfo.Remove() - } - } - ss.GoodPeers.Delete(peerID) + if err := ss.writePeer(peerID, peerInfo, msgcode, inreq.Data.Data); err != nil { return &proto_sentry.SentPeers{}, fmt.Errorf("sendMessageByMinBlock to peer %s: %w", peerID, err) } peerInfo.AddDeadline(time.Now().Add(30 * time.Second)) @@ -681,13 +690,12 @@ func (ss *SentryServerImpl) SendMessageByMinBlock(_ context.Context, inreq *prot func (ss *SentryServerImpl) SendMessageById(_ context.Context, inreq *proto_sentry.SendMessageByIdRequest) (*proto_sentry.SentPeers, error) { peerID := string(gointerfaces.ConvertH512ToBytes(inreq.PeerId)) - x, ok := ss.GoodPeers.Load(peerID) - if !ok { + peerInfo := ss.getPeer(peerID) + if peerInfo == nil { //TODO: enable after support peer to sentry mapping //return &proto_sentry.SentPeers{}, fmt.Errorf("peer not found: %s", peerID) return &proto_sentry.SentPeers{}, nil } - peerInfo := x.(*PeerInfo) msgcode := eth.FromProto[ss.Protocol.Version][inreq.Data.Id] if msgcode != eth.GetBlockHeadersMsg && msgcode != eth.BlockHeadersMsg && @@ -700,14 +708,7 @@ func (ss *SentryServerImpl) SendMessageById(_ context.Context, inreq *proto_sent return &proto_sentry.SentPeers{}, fmt.Errorf("sendMessageById not implemented for message Id: %s", inreq.Data.Id) } - if err := peerInfo.rw.WriteMsg(p2p.Msg{Code: msgcode, Size: uint32(len(inreq.Data.Data)), Payload: bytes.NewReader(inreq.Data.Data)}); err != nil { - if x, ok := ss.GoodPeers.Load(peerID); ok { - peerInfo := x.(*PeerInfo) - if peerInfo != nil { - peerInfo.Remove() - } - } - ss.GoodPeers.Delete(peerID) + if err := ss.writePeer(peerID, peerInfo, msgcode, inreq.Data.Data); err != nil { return &proto_sentry.SentPeers{}, fmt.Errorf("sendMessageById to peer %s: %w", peerID, err) } return &proto_sentry.SentPeers{Peers: []*proto_types.H512{inreq.PeerId}}, nil @@ -722,7 +723,7 @@ func (ss *SentryServerImpl) SendMessageToRandomPeers(ctx context.Context, req *p } amount := uint64(0) - ss.GoodPeers.Range(func(key, value interface{}) bool { + ss.rangePeers(func(peerID string, peerInfo *PeerInfo) bool { amount++ return true }) @@ -735,15 +736,8 @@ func (ss *SentryServerImpl) SendMessageToRandomPeers(ctx context.Context, req *p i := 0 var innerErr error reply := &proto_sentry.SentPeers{Peers: []*proto_types.H512{}} - ss.GoodPeers.Range(func(key, value interface{}) bool { - peerID := key.(string) - peerInfo, _ := value.(*PeerInfo) - if peerInfo == nil { - return true - } - if err := peerInfo.rw.WriteMsg(p2p.Msg{Code: msgcode, Size: uint32(len(req.Data.Data)), Payload: bytes.NewReader(req.Data.Data)}); err != nil { - peerInfo.Remove() - ss.GoodPeers.Delete(peerID) + ss.rangePeers(func(peerID string, peerInfo *PeerInfo) bool { + if err := ss.writePeer(peerID, peerInfo, msgcode, req.Data.Data); err != nil { innerErr = err return true } @@ -767,16 +761,8 @@ func (ss *SentryServerImpl) SendMessageToAll(ctx context.Context, req *proto_sen var innerErr error reply := &proto_sentry.SentPeers{Peers: []*proto_types.H512{}} - ss.GoodPeers.Range(func(key, value interface{}) bool { - peerID := key.(string) - peerInfo, _ := value.(*PeerInfo) - if peerInfo == nil { - return true - } - - if err := peerInfo.rw.WriteMsg(p2p.Msg{Code: msgcode, Size: uint32(len(req.Data)), Payload: bytes.NewReader(req.Data)}); err != nil { - peerInfo.Remove() - ss.GoodPeers.Delete(peerID) + ss.rangePeers(func(peerID string, peerInfo *PeerInfo) bool { + if err := ss.writePeer(peerID, peerInfo, msgcode, req.Data); err != nil { innerErr = err return true } @@ -838,13 +824,7 @@ func (ss *SentryServerImpl) SetStatus(_ context.Context, statusData *proto_sentr } func (ss *SentryServerImpl) SimplePeerCount() (pc int) { - ss.GoodPeers.Range(func(key, value interface{}) bool { - peerID := key.(string) - x, _ := ss.GoodPeers.Load(peerID) - peerInfo, _ := x.(*PeerInfo) - if peerInfo == nil { - return true - } + ss.rangePeers(func(peerID string, peerInfo *PeerInfo) bool { pc++ return true }) diff --git a/cmd/sentry/download/sentry_api.go b/cmd/sentry/download/sentry_api.go index a45bb5ba3ef..5f7c1d9c0cf 100644 --- a/cmd/sentry/download/sentry_api.go +++ b/cmd/sentry/download/sentry_api.go @@ -132,7 +132,7 @@ func (cs *ControlServerImpl) SendHeaderRequest(ctx context.Context, req *headerd } minBlock := req.Number if !req.Reverse { - minBlock = req.Number + req.Length*req.Skip + minBlock = req.Number + (req.Length-1)*(req.Skip+1) } outreq := proto_sentry.SendMessageByMinBlockRequest{ diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index bc3534924c0..6dfef4b1eba 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -426,6 +426,11 @@ var ( Usage: "Comma separated enode URLs to connect to", Value: "", } + TrustedPeersFlag = cli.StringFlag{ + Name: "trustedpeers", + Usage: "Comma separated enode URLs which are always allowed to connect, even above the peer limit", + Value: "", + } NodeKeyFileFlag = cli.StringFlag{ Name: "nodekey", Usage: "P2P node key file", @@ -611,17 +616,7 @@ func setBootstrapNodes(ctx *cli.Context, cfg *p2p.Config) { } } - cfg.BootstrapNodes = make([]*enode.Node, 0, len(urls)) - for _, url := range urls { - if url != "" { - node, err := enode.Parse(enode.ValidSchemes, url) - if err != nil { - log.Crit("Bootstrap URL invalid", "enode", url, "err", err) - continue - } - cfg.BootstrapNodes = append(cfg.BootstrapNodes, node) - } - } + cfg.BootstrapNodes, _ = GetUrlListNodes(urls, BootnodesFlag.Name, log.Crit) } // setBootstrapNodesV5 creates a list of bootstrap nodes from the command line @@ -655,47 +650,52 @@ func setBootstrapNodesV5(ctx *cli.Context, cfg *p2p.Config) { } } - cfg.BootstrapNodesV5 = make([]*enode.Node, 0, len(urls)) - for _, url := range urls { - if url != "" { - node, err := enode.Parse(enode.ValidSchemes, url) - if err != nil { - log.Error("Bootstrap URL invalid", "enode", url, "err", err) - continue - } - cfg.BootstrapNodesV5 = append(cfg.BootstrapNodesV5, node) - } - } + cfg.BootstrapNodesV5, _ = GetUrlListNodes(urls, BootnodesFlag.Name, log.Error) } func setStaticPeers(ctx *cli.Context, cfg *p2p.Config) { - if !ctx.GlobalIsSet(StaticPeersFlag.Name) { - return - } - urls := SplitAndTrim(ctx.GlobalString(StaticPeersFlag.Name)) - err := SetStaticPeers(cfg, urls) - if err != nil { - log.Error("setStaticPeers", "err", err) + cfg.StaticNodes, _ = appendCfgUrlListNodes(cfg.StaticNodes, ctx, StaticPeersFlag.Name, log.Error) +} + +func setTrustedPeers(ctx *cli.Context, cfg *p2p.Config) { + cfg.TrustedNodes, _ = appendCfgUrlListNodes(cfg.TrustedNodes, ctx, TrustedPeersFlag.Name, log.Error) +} + +func appendCfgUrlListNodes(nodes []*enode.Node, ctx *cli.Context, flagName string, logFn func(msg string, ctx ...interface{})) ([]*enode.Node, error) { + if ctx.GlobalIsSet(flagName) { + urls := SplitAndTrim(ctx.GlobalString(flagName)) + return appendUrlListNodes(nodes, urls, flagName, logFn) } + return nodes, nil +} + +func GetUrlListNodes(urls []string, nodeType string, logFn func(msg string, ctx ...interface{})) (_ []*enode.Node, retErr error) { + return appendUrlListNodes(nil, urls, nodeType, logFn) } -func SetStaticPeers(cfg *p2p.Config, urls []string) error { +func appendUrlListNodes(nodes []*enode.Node, urls []string, nodeType string, logFn func(msg string, ctx ...interface{})) (_ []*enode.Node, retErr error) { + if nodes == nil { + nodes = make([]*enode.Node, 0, len(urls)) + } for _, url := range urls { - if url == "" { - continue - } - node, err := enode.Parse(enode.ValidSchemes, url) - if err != nil { - return fmt.Errorf("static peer URL invalid: %s, %w", url, err) + if url != "" { + node, err := enode.Parse(enode.ValidSchemes, url) + if err != nil { + retErr = err + if logFn != nil { + logFn(fmt.Sprintf("%s URL invalid", nodeType), "url", url, "err", err) + } + } else { + nodes = append(nodes, node) + } } - cfg.StaticNodes = append(cfg.StaticNodes, node) } - return nil + return nodes, retErr } // NewP2PConfig // - doesn't setup bootnodes - they will set when genesisHash will know -func NewP2PConfig(nodiscover bool, datadir, netRestrict, natSetting, nodeName string, staticPeers []string, port, protocol uint) (*p2p.Config, error) { +func NewP2PConfig(nodiscover bool, datadir, netRestrict, natSetting, nodeName string, staticPeers []string, trustedPeers []string, port, protocol uint) (*p2p.Config, error) { var enodeDBPath string switch protocol { case eth.ETH65: @@ -722,9 +722,18 @@ func NewP2PConfig(nodiscover bool, datadir, netRestrict, natSetting, nodeName st cfg.NetRestrict.Add(netRestrict) } if staticPeers != nil { - if err := SetStaticPeers(cfg, staticPeers); err != nil { + staticNodes, err := GetUrlListNodes(staticPeers, StaticPeersFlag.Name, log.Error) + if err != nil { + return nil, err + } + cfg.StaticNodes = staticNodes + } + if trustedPeers != nil { + trustedNodes, err := GetUrlListNodes(trustedPeers, TrustedPeersFlag.Name, log.Error) + if err != nil { return nil, err } + cfg.TrustedNodes = trustedNodes } natif, err := nat.Parse(natSetting) if err != nil { @@ -837,6 +846,7 @@ func SetP2PConfig(ctx *cli.Context, cfg *p2p.Config, nodeName, dataDir string) { setBootstrapNodes(ctx, cfg) setBootstrapNodesV5(ctx, cfg) setStaticPeers(ctx, cfg) + setTrustedPeers(ctx, cfg) if ctx.GlobalIsSet(MaxPeersFlag.Name) { cfg.MaxPeers = ctx.GlobalInt(MaxPeersFlag.Name) diff --git a/turbo/cli/default_flags.go b/turbo/cli/default_flags.go index 15bd8bbcb29..98d60e604fd 100644 --- a/turbo/cli/default_flags.go +++ b/turbo/cli/default_flags.go @@ -56,6 +56,7 @@ var DefaultFlags = []cli.Flag{ utils.NodeKeyHexFlag, utils.DNSDiscoveryFlag, utils.StaticPeersFlag, + utils.TrustedPeersFlag, utils.MaxPeersFlag, utils.ChainFlag, utils.DeveloperPeriodFlag, diff --git a/turbo/stages/headerdownload/header_algo_test.go b/turbo/stages/headerdownload/header_algo_test.go index d4e86804417..0f97b0e4d3f 100644 --- a/turbo/stages/headerdownload/header_algo_test.go +++ b/turbo/stages/headerdownload/header_algo_test.go @@ -36,17 +36,22 @@ func TestInserter1(t *testing.T) { } defer tx.Rollback() hi := NewHeaderInserter("headers", big.NewInt(0), 0) - var h1, h2 types.Header - h1.Number = big.NewInt(1) - h1.Difficulty = big.NewInt(10) - h1.ParentHash = genesis.Hash() - h2.Number = big.NewInt(2) - h2.Difficulty = big.NewInt(1010) - h2.ParentHash = h1.Hash() - if err = hi.FeedHeader(tx, &h1, 1); err != nil { + h1 := types.Header{ + Number: big.NewInt(1), + Difficulty: big.NewInt(10), + ParentHash: genesis.Hash(), + } + h1Hash := h1.Hash() + h2 := types.Header{ + Number: big.NewInt(2), + Difficulty: big.NewInt(1010), + ParentHash: h1Hash, + } + h2Hash := h2.Hash() + if err = hi.FeedHeader(tx, &h1, h1Hash, 1); err != nil { t.Errorf("feed empty header 1: %v", err) } - if err = hi.FeedHeader(tx, &h2, 2); err != nil { + if err = hi.FeedHeader(tx, &h2, h2Hash, 2); err != nil { t.Errorf("feed empty header 2: %v", err) } } diff --git a/turbo/stages/headerdownload/header_algos.go b/turbo/stages/headerdownload/header_algos.go index 09ab708459e..f65a2a1f945 100644 --- a/turbo/stages/headerdownload/header_algos.go +++ b/turbo/stages/headerdownload/header_algos.go @@ -571,26 +571,27 @@ func (hd *HeaderDownload) RequestSkeleton() *HeaderRequest { defer hd.lock.RUnlock() log.Trace("Request skeleton", "anchors", len(hd.anchors), "top seen height", hd.topSeenHeight, "highestInDb", hd.highestInDb) stride := uint64(8 * 192) - queryRange := hd.topSeenHeight + nextHeight := hd.highestInDb + stride + maxHeight := hd.topSeenHeight + 1 // Inclusive upper bound + if maxHeight <= nextHeight { + return nil + } // Determine the query range as the height of lowest anchor for _, anchor := range hd.anchors { - if anchor.blockHeight > hd.highestInDb && anchor.blockHeight < queryRange { - queryRange = anchor.blockHeight + if anchor.blockHeight > nextHeight && anchor.blockHeight < maxHeight { + maxHeight = anchor.blockHeight // Exclusive upper bound } } - length := (queryRange - hd.highestInDb) / stride + length := (maxHeight - nextHeight) / stride if length > 192 { length = 192 } - if length == 0 { - return nil - } - return &HeaderRequest{Number: hd.highestInDb + stride, Length: length, Skip: stride, Reverse: false} + return &HeaderRequest{Number: nextHeight, Length: length, Skip: stride - 1, Reverse: false} } // InsertHeaders attempts to insert headers into the database, verifying them first // It returns true in the first return value if the system is "in sync" -func (hd *HeaderDownload) InsertHeaders(hf func(header *types.Header, blockHeight uint64) error, logPrefix string, logChannel <-chan time.Time) (bool, error) { +func (hd *HeaderDownload) InsertHeaders(hf func(header *types.Header, hash common.Hash, blockHeight uint64) error, logPrefix string, logChannel <-chan time.Time) (bool, error) { hd.lock.Lock() defer hd.lock.Unlock() var linksInFuture []*Link // Here we accumulate links that fail validation as "in the future" @@ -634,7 +635,7 @@ func (hd *HeaderDownload) InsertHeaders(hf func(header *types.Header, blockHeigh delete(hd.links, link.hash) continue } - if err := hf(link.header, link.blockHeight); err != nil { + if err := hf(link.header, link.hash, link.blockHeight); err != nil { return false, err } if link.blockHeight > hd.highestInDb { @@ -716,15 +717,14 @@ func (hd *HeaderDownload) addHeaderAsLink(header *types.Header, persisted bool) return link } -func (hi *HeaderInserter) FeedHeaderFunc(db kv.StatelessRwTx) func(header *types.Header, blockHeight uint64) error { - return func(header *types.Header, blockHeight uint64) error { - return hi.FeedHeader(db, header, blockHeight) +func (hi *HeaderInserter) FeedHeaderFunc(db kv.StatelessRwTx) func(header *types.Header, hash common.Hash, blockHeight uint64) error { + return func(header *types.Header, hash common.Hash, blockHeight uint64) error { + return hi.FeedHeader(db, header, hash, blockHeight) } } -func (hi *HeaderInserter) FeedHeader(db kv.StatelessRwTx, header *types.Header, blockHeight uint64) error { - hash := header.Hash() +func (hi *HeaderInserter) FeedHeader(db kv.StatelessRwTx, header *types.Header, hash common.Hash, blockHeight uint64) error { if hash == hi.prevHash { // Skip duplicates return nil From 58b4596410850035505e8649d39a398b1b0748b4 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Wed, 17 Nov 2021 08:19:21 +0000 Subject: [PATCH 027/261] Ropsten and main net preverified hashes, skip analysis (#2973) (#2974) * Ropsten preverified hashes * Pre-verified hashes for mainnet, skip analysis Co-authored-by: Alexey Sharp Co-authored-by: Alexey Sharp --- core/skip_analysis.go | 2 +- .../preverified_hashes_mainnet.go | 667 ++++++++++++++++- .../preverified_hashes_ropsten.go | 669 +++++++++++++++++- 3 files changed, 1335 insertions(+), 3 deletions(-) diff --git a/core/skip_analysis.go b/core/skip_analysis.go index 0fd6a8f7f8e..fc7382ec0d4 100644 --- a/core/skip_analysis.go +++ b/core/skip_analysis.go @@ -21,7 +21,7 @@ import ( ) // MainnetNotCheckedFrom is the first block number not yet checked for invalid jumps -const MainnetNotCheckedFrom uint64 = 13549000 +const MainnetNotCheckedFrom uint64 = 13627700 // SkipAnalysis function tells us whether we can skip performing jumpdest analysis // for the historical blocks (on mainnet now but perhaps on the testsnets diff --git a/turbo/stages/headerdownload/preverified_hashes_mainnet.go b/turbo/stages/headerdownload/preverified_hashes_mainnet.go index 1bffe5ed585..0f00cac8512 100644 --- a/turbo/stages/headerdownload/preverified_hashes_mainnet.go +++ b/turbo/stages/headerdownload/preverified_hashes_mainnet.go @@ -70314,6 +70314,671 @@ var mainnetPreverifiedHashes = []string{ "46af2c4ae0478eecb0b5f1343559f922b6a62321c38346d903364c1b65ee8395", "7c75355993301e54767cf1d8db82a319be8b73e5d0058e7ffdd5c26a751b2b9e", "dae4a2c85d07dc28297eb7032456b7680c2b4439089ce033f63a3296eb80b69a", + "4966a312477074796a94558412dc3afb0730e3e0216bf8aff88877dbd777e9fe", + "9214d851f8bc66472f8d6b2d93ea7034ddaacf2e77c7fbb206f50ea0c64455ea", + "ac044ae0508ff1c23d7f0c7136dbd15a9c2a50bd4d0745daee5f2d7da3eedcb9", + "f4556b041bee3db5e9bcbe6d1c290771d557f76d7a6e46524cf0caf57151116f", + "74fbb9dfc8fcedb3a3c6d9572a045eac5edcc6e83dcfbaf0ea3245d30ba1bb0a", + "3eb70bcf3c6d11b6cc309004918f852008bc122ce5263fe6e06172bdbe0e85be", + "9af47856db236c72e5be1ac6c6e39b196d8e792df17948db8cea3998fff0f1fd", + "b0997b4de593f937fae3e0eebf920bbdbb254e5e14c44bbac302c3610dea5d0a", + "b3ab57af43e523a0f4e453beca1e66ffba993c057f84a8c99c44a575ca8082da", + "f1a61527f279c5c5530fe028b4ef712b08475ee57ab654524295757f4b97a16d", + "3b8a87147fc3907a6d250162e132264ff302a9dd6744874730d3b32d91ff402c", + "014c1bcb5754bd56deb4f4e13cd7eb018a94bef917b48ec22ac863630ab4b318", + "d07c70fe6756cde78fa502ac99bb1f42dc7cee36ff6958f2b6cccf380df540ac", + "8d46d5e8cb3702510a221d3480e3446ec9eb3d8f812ce7b55df57661b2decfba", + "865eaa59403f3cff97521b57b9e1d171687700a915928a64b7c357b7c135d8a2", + "9db492b25c8abf22da62d234c68b54569f239ac68421df515f008f395ace27cc", + "51edc19041839d639065e44b508e5bfd48337df8165bf743bc1f7fc44af896d9", + "4d1dedab916897b65006caecde4dc46244793580e31c54e005a3e20f55bc4c4e", + "af2493bc08f76b515d74fcd89271cdfedd56e1bb0d4c52519c92c8f5e38333d9", + "5419910dbad462c989925dec343c0535f7c434b112698331a2786d4d3bfce53d", + "f09b8fa24aa4d07d4dd550cefa74ca40dd902c84e20b8089027707f3c1bfa56e", + "f61f4467c720e0c365c0dab9d4c8f5d733e8a976137c5673b1e98e3aa411fbf8", + "02ed3ab1f6e930baffd7eab34c8c932497df084cc75c5e5eefd23ad00f3cf671", + "55b70ce381b930e061479ae74c6d452f96aa887bccdaff02119fa2ed75688f31", + "ca34adf6bae2d380b014bb424f039b1f618995b5611d4b0ff874fe5b248c2d28", + "34c8aa73e373652b6ac36b6f819e3dd7df5651b75627db34aa09fdbbf0b83c20", + "6c45b3a0a6de151816401360590f792dceb756d350969211447680898941553b", + "2c3e5d3742eb547ca3d74f062b1c8959b8f71617994fac162216d355b7107fe6", + "10cf4e2d2484afdab0acefb7a09fb2f81e8933f38a4eaad6746427278f6f86d1", + "60d95adf4e8f2b3e730aca5d57cd13b64402fe2509ef9beabf5acb38fadb426e", + "a73d1646975cefed6aa0b30205a9dcc3ccecbfddcf498cfb75a5e09b1f5b20ba", + "dc1060f4af732d49c0b5b1ff323d417b56926d59f8e937817a67b868114fd7e5", + "4bd10a29d5abf74ba8dd4ab2e86ee93af4b2f554539eb08239b7f2f5a625a1ce", + "86b51c439f5fe8378d4fac64e4f9d9533be924797adcb2ab6dbe839f1f70bad4", + "9cc106a560f0d18e7d6bbc0a15cf8c35980660220b42dfecc538110bf2e1af15", + "d3a8c1c9cd80e495d77b0eb67a84d697a3280f4afd015f6b51b45cabe8ce71d2", + "dca81e9ea47e9c5a42c7bc10e5ab102751b58133d2e1ba0e081389af2c20cd38", + "6364d864817708794423acd96b64d698c25971366e0611d35c393b9ead2fdc96", + "290614862a7d8c8525e6ae1a5c3b9b556769ee7c5d4514c9faf1a3a880987378", + "8f6513b4bd1eed0d46a38e594a26b3f0e25b5e580ca9e350ab702075daefbb9a", + "f4246ee9b4d60d2ffd3c4adaf777f3f58a7b116422862da47c793aa8efef7f26", + "3a9d22e7c6738ab17b673770b79f15110fb2a19c18af23dcbfdae656050014f8", + "bbc549f68ca2c75088695fe1a8f726b9e8595c0aeb9a6e6b8d2e757008a2576a", + "82c5438f6e90639e4e9e9971338a9081072080c12322e54f5b0db8f69c8cd464", + "86450e8a7ae6723176730e057516a17e1ce2f66d9404cefd34c843f4662a224f", + "0ca0925b11075a0111142170cd10ebe4d8b5a9e03ded29f216135f6900d9c186", + "811f436dcc820290d690c692ca79830bb59d57bf46df85eb13649b99f2ec959f", + "ebf34047e075dc565e5373dc6cdc48eba99510d7950fd401d46db5ce27149b7f", + "ae74ebaa374a627017ad6bf12e09d4b99a0ff3a7f1be056cbbe7812c7800493e", + "4610c4a05fce9a273a043899db76e599800e5d641e891d107a271655091a5de0", + "6fd31fde0d2541d0b4ecdb679ebbdf97e709895d80af445611edfa93363b2112", + "bd3e3d838d59ea87e8219a66d00fe414d0897b974b7e8e0f50d73a229c0c6035", + "9952f55deac09483d1aba6daa301b380d2c30a4b08afefcfdc243e93f4adb769", + "22ba5a61358b1316f318c309ca57958a3bc383887838441e225d3cf5f42b81e1", + "4b0f170aed82350c413600d5ebe2107e9f50e850fe546f7ad89a781d10681359", + "eadc81fe8fe069db0a97621596ecb0c572515130f5b675f36a3b0eb30fabd747", + "45cd5b657f74bd6f0de0e727af54cf12670658b5a5b3358f8f06f8549cb1c2ee", + "ea748feeb72b9b887b132d3c95adf02d58618f37dcaf76f81718b1e69b703a79", + "519fc7821aebc34abc170dd68ea0f035f7f693f4296a46c9d49b07fc45b3b2c1", + "959739953b0407274d8dd983a2feed370794a8d4916eca1aad90ed84ad2f880c", + "c5d525a3a408740621af0618843bc6a5a9e62f8012099095e8e80ef625bbfe7d", + "8115532ef47f4d8ed668486842c86e9d848056f750adba5f6d204c3a0e944e62", + "ee1a3ee90921240ca9c6e5ce00840d2671125973aa003be4d4a3efa01f872cf5", + "b026006b12c4f70818a7f269cafc5530e80849d317cf77e3243eea18f9e2ba33", + "79a123b81e269d7fb81a4f8b6767f7f04d372a10293f921339c7fc7aa973c722", + "32bf51569436f230f34fd9284fc29b015df4579d6c30ba69974468dbf2d05206", + "bc1ffa5719ceff82749ad5baf58342c0ac1a89260c4a6d87a1c26d9dbc6fbdaa", + "e836dbf56400a1c525df39494ecb7cfa20c516b4bdf91f21985ca58b511c88b1", + "b1fe7f5de9bf086709129b7f999e339977acdb76017789413ed8fbd06c94a0e0", + "5623e2428e0b55f1c6a7c3b6d4fdbf100e4cea64550e202ffea2423b27ddf527", + "c19ce708f6d51016296a0054a4bfd0fd3ba90a6b39f451dc827e68b9d84115f2", + "9fb7e4596cf411c5f23262bb39b8b9ac1e7d787b31fe19b26d861002f4cb9465", + "052126bbef22dacc57a3b461f29cf12847eac908a62442f7a8f9723efe672189", + "32fc6854039debb608e79112ae138c6f451fa2aeb4909a0a96ad1ea19edd3a48", + "a8a9bfd1cef351d561f6418e6a6acba556c9ce02067c8ad53a1e5c7713b1bb36", + "4bd5e9d869a4886f79d9909d5fc7f1d351a9e91bd68123affe5c96264220bd9b", + "42e7fe43e591a10ad8ccbd7415f0ad13dd75327a9f965cdbf0cbad13e1cde688", + "88761d7358e1ff5e701238c6fc662473332dc27fd9f577e23e4914768d7e1fa1", + "fb19e9a51a46546b7691df8eb490f081ef0e027274f6c816e7867eee6fc387ab", + "9660ad21e6bb9ba39150b696018d10c5fc17d4adbff462e6658a0c3631ab9b70", + "287262533973a7b4f410131cfb181b19477b2c60869fabe48a0456a1462774b2", + "9c8e8b79542bc53fce82ae1fcf332960df0e4fa277fb2ed467e94d28082fb763", + "34d97c191c6d2f7a4e4ff332b6fa38c6ecdacd5dcff07dae90dc42d8b287f14d", + "a0c2ed60938822d3e02b8a8122590f303aa7df20fb5259ea829979c443dd74a1", + "17450c0c7231ec59b2f17273631b13106ebd3acd2442209ff2de88c50dcc75ed", + "99c8e44554fe38f72835d2c7c7f5419ab376faa38833bab8823bbeab2b91be2d", + "03341e691fb72be10cad17276ab02717aaa3d70462b3b20d970977a7afb32c77", + "3bc732af221b45309ae8a8705bc2527ed7e67b264c3e97489954a9e0dcdb839f", + "dfceb62a948d527657ee13e70cb57293b5dce23745884479da82924b160bc21c", + "049552526079516f6e4eb16bca59a1bfc59eb9ba05cf49a8526eefb39d76c6da", + "26dfd519b943745c8015f8bbf26b1233b02cb154800d9f41f3ed66e4773f942e", + "1c18904a18dbe1b7a1232f555abf7429c79e77dbe17305800eae8e92737b78c8", + "6a384dfa3a810ed56ace82049f4e47e13d5d611a09e9893e478270ace7a99398", + "9866774a257dc9b6a45528e53fd6d0a248a97c47250f8a3709d03d3cb8517482", + "934e93592ff04f63c700aff97aa226e1590f49e9b66926519f12abfe7469fa43", + "952275384201a607f9280850acb2cd26b7fd48f11bc4ca205585f5cdbfbc2e26", + "eb4ed47d930c5281f89ab51ea80618193c9072bfc00abd760d941664261f9d6e", + "44cbec330db696abe76e9bd61550355f5279f934902b02d99ac75be99469a329", + "d3a51bf52d749c72f6ae07c9fcc98c027a20149f2bd877e2fd699317f29d87ea", + "8f8d19f8f866d83c5b6b5d768cc0fec501a82f86b09e98d4eccaf568638a770f", + "fe711c97cbdd96149445675f99418c91db41044bdc2c86130c7a44466c2bbc47", + "a81bea5f8b9538399e2cf9743e174a21ede2be662fd7633c75e13dae1b90816a", + "d3028c5ad8f50fdea32f73a8681fa8dc13919b4daf2b2e628019648e1d040da0", + "fff5920295ec94527408fbfc723ccf4e1ca2ca9edae51d0384463e40cc28af9e", + "e7744a66137745bd4512f1d1c8a0f2a0fd1ed59e26cb71798c288e5af2a21247", + "986bf860b676a48047d553817999e437791964522aa7ee8eea05c8f38f831de5", + "7f44fd026cb87ce93e6b29734a27bc98af80dea5990b7250fc87816b6fbc5a9c", + "38f50477c4c148528b223b149cee7449131b9a007f9e28e94edfd935dfa50df8", + "f88880ab425259d46ec533fd55bb642b0332f22ed49cdb3585f34646d612e631", + "51a1ee5f2d973f35e8c252e843f1f6b61174aa035b000463f2c382bf4e32315b", + "5d482a94c4ada33daf1bf612eb7d2ecb788b33d7cf4fc82240fed66abadfbcf8", + "07e49551cbcab1568144967eca78f42285e49de4b0402d7c5d71e4a3a3e68117", + "63bd379113a90272a014fade80eab1f3be62f9bb6ead7631fc159bfb6662f1f7", + "d3dc298f42179d00a28791c1f3622adfd06568580fbef01075998d9697645f56", + "7f7e8008538bbdf2539cde8142310cf48b91e51935ec1e3de58b107fdca4cac8", + "a0716820a361c087fab9a26b142a8d1fc7889d97199a81887f661cf5719aa43a", + "b381f5ab26e6a70153ac4478ffb777e78cf3a365d07a5f3634a7552f1bcac863", + "2156fce8cb0b180762b47d12636ee466e86d4edb66c8473e5736b40d6a7ec9d9", + "50b30ad37ae81cfc26bce5fcce7afbf941666b394f0f75a301aa2583c4e73134", + "c664cc5830f5a8e1ad69e45cdfe78b91c1bb03e4f93b11605bd29bf06714f5e2", + "5454c78f95eaec5cb1e93dbf2be5e8a16efe4386c3a24c75782d33122c850d99", + "20bc8c3108ce9f14ba69340153cd2f4f49acda6617985aac73f047741d20df80", + "e667ef9d7edd05f8ed1e3271190c8cd66b7d55688ea9da290390bd73ffb11bd9", + "f72dfd419b6623d94d62a60647039b90269f42f45fbc2abf0fab9aafa9fb58f8", + "01ab9fc1ec906544de7b35e9510d53c29ef132e8051a7b918a7af64cc401761f", + "2ced06fd6f7092d02d17b445b7ad933224e50bf9181f9681bbd635b625d14db7", + "7d67d0bf3af01dd66a42ab24d09632648625c7d96de102e7b9982e51e8e3c7c9", + "25628d42a2de929e1c58490d0b18de54ba37aaf6d87fc3f745338ccb3f5fa4a5", + "350799395e51d9618fe5d19b51c75a52cec4d04cca877891aa63db3f1e56d020", + "bc4955946aa57c0d07b118bb69ea001cc52b8b42869324e4232b4138887e01db", + "f30ff9a9dedd5916e26300ca99e1790693b1579956b156128388ec51860c2975", + "6f422f7053bdceae8a74d63768f8142d109625d4ecbcb1a78f25ea6c01fc8285", + "e887eb70b498aaaca59fb28b6b0d0ca75c0fe1ea3ca51f32b82af8c104abfb53", + "175f1c2780fed9f488dc784c6d0e6a60eab73ad05f4c42664fb9b384db4307ac", + "c41d4852c0f50ba691ef570595fad31d6ff8a58c2e70c903e74a61746da56f36", + "459bfaa5b6ab89008632d499fc84ead116bf87f6bfded02add24be231c78eb86", + "5d368d8e37da06646e5d3b6fecb8f7e8772401410a0e460cb19ded1d94ddca79", + "f00e05eb19c966b1ebff2a55ff4e705a3ead62922bf07062372e3f7b531a88aa", + "df6567e8a8e561ba0ee212b84023fb8d4b26cc073f3818107db53ccb94c66b45", + "db520ae88cb79f7e089e89b28599764493828f6dc24fd997dd23f5a3d04f3b2d", + "214dbbbcc02d58ee68ea9afeeb8e70b47dbe934135dc50a0bac60aeb686646cb", + "21b049f2510f5905f8783ed1c9b5831c3614c68e028fd2d09967cce57c554fdd", + "6b3fccaae9337ca86a0ff2136754d3b79fc6d0be4c496507b9756baab36d6248", + "2ae78cebbc7ae70c90b71c3a6d72bebce37c034a8c0f1398345bec3b1d5f74c4", + "eeeb656b9c8eca10aee322cebd6c2a1cdac011ad7b70bded1e54af74bc590895", + "c5c302efe6c1a0bfb79513a70c6846d62c802d2256af8d6a464d62082c50d3ed", + "9bf4832f77dad07c7039494920c074746873c69ab3b48f72df18870cc4f56d06", + "60c5376b57d72c40e94b750e1381fcc6b1315cb2cce8ece589a541a667a02e42", + "cfe115d5b27f30b1d564ba13886e2a2a9ca2829bd1b1ef8688aa5650083a23e3", + "cce85085d4fe9a009324d7c4afd1b7d0404721ec8de3295bf8801d6c2c4ac65f", + "509cbf321e9b46f8e48464dbdd1ede8161f5a8d0141aa10cb3d9178937aa5b18", + "eb3d2674d5eb01512f76e2eb39a64e5a4361d8afec9f52204367355d40d37600", + "5f42f217b7f81c351d9d4678196c00177b8683b9d5873e880e4e8eb4007d5ba3", + "96280143689f98235d9c38b5a5f1dbabff0c501f637a97740a45cb8de5eafa31", + "2c3be3242c89db25af8668ddfab3ee79af8bd1cd852026e0d55bbb0f5eb2c3f0", + "8291611c166eeebbaaaf2885609b5fca21147be45113e667e46e18fd21b86e74", + "37184a841ea380b3c99ca953f9024a57e8f07b3b9d36d22255e4529778caa7f5", + "b9075143316c56650f8c5ad355bb1630867c62e11cd63056cdc1721864a8ca66", + "fcff20e95c6c22c7345622d215ff84d09cbcaf6be02bafa828a6eb455ebe6d9e", + "a1c7bbca40d38c764436aaeeadeff99d7738201dbe1707465673b6cb4851b7bb", + "b44563d5a46e62dac1a8fc1f6afdaaf783b4f5049ec2a414d1488fe5d01a202b", + "2607862dbdb0687427315ffb9e29419814c9e439ef8bc8d017f7ffc0e3e5dac9", + "d35f2b4b64ac3bda87c9a9dde7430e858c045518b99093baea6d7bead020e5cc", + "9b7c9899aec87a8817d73c37d867c2da84f5ec931577767d507f6c23000f54fa", + "25ffdd1beddf876adc86dbd4daa8e6759a9d4d65815d76b277fca584c7870a95", + "6b17702ef2869cea3ffe06148f4ca2a82835e7943d6add55194b9ff4ffaca66d", + "7367031aa56d1160c04b41a02c45c76a587e817ea30495a637b12e112fd71e95", + "a9fdafc61d6e343fd585dfc82af1cbf583e0ddb8818320b257204a540cd35f67", + "d0d68724062bfbbbbf7d1ca66acd10bd27f0f3cfef0d1270eeb39f4592b21d3f", + "40b6cddb6fb249e788c84572c38dd90e1f6bca95c4698a70d8b4509f69c03c3a", + "052873a4b2e2f948d8322930d9da33da4630769a92b9cb0ff5c95ca67f3d655a", + "a3a897c4dca18d381aca119dee87d1549d95bdd2c5ebcee0c7d57a05442e8de8", + "e0f7c94638a18e4483034f17f6d061a3d21bfa2b9cf7937f8cb5e1bcc074b6bc", + "7ea31383501fc113e33ce92a0870b60fe1438b69020f636deaf6e73c5d9d37b9", + "d26f04383c146648d8ef7eda9855a1036066e1549f1f7ffa8410c777d80b6e14", + "adf1cf260ccb6dc90c403ccd2448cc83ac8f827475ef6fd1b8419a51b042da46", + "30266815538ed2dfbd144cf8871035c141cb5f408fdeb0b672eadae5932ec70a", + "aba08ce23255170c39d1d09d49655f3c13b01a5bc8c08bd688f5ffd21e2e9a68", + "91903e9bf7684264d11230c25717c8b1c90ec1b395ea785fca9153baf192424e", + "daa8e15f9d82890c1ed27661ac3c5f6f1c37878b176316f9f76d6e77af40cde5", + "1bf918ceea4478280797efd7e39881ef95eaae285c4e8aa97309442d4910f3f6", + "2b203a60cb0fe59e6e22addf8b773d3c9d586bf3cb71100e7c4c6c386d49b71e", + "b97759edccf93c5d57379f3999267db922a8846b16348a530b9d2d4c3675e925", + "455080210290a00bf8d66b3f3d2541597580f1a0ab8f27c3b9e6730bef7e9212", + "1ca07586bca31bc03d992b54b45f784e1d2eb8eefa4ab16c1565f9d67de843d6", + "5bf62f5e6d5f5060c8eff9209ec7677d77f6d285dc67a86a7a4c281e53240b80", + "002097ae9bbad436d50fb0f13b7cec4b4e8800874eb7d51ab910e8e01d567ec8", + "30161b7343009848446e1eb3f2d7df276c980ee4e2ba5530564952e352ad899b", + "05448f493a6130eb2c5f01ffc1fbe328e60ddec0b81d089fc7bff1ae747dbb20", + "701fdf5b82fecbba2bfe8eea363f7055713a0f3e747f68d897e90e1065023b64", + "f36ebb3ff9ea9378194f3eaece2ce6d18cf05925e409c5f6f2bb807dba2981ac", + "ee5dd870d3653c3716de5c521031eaa8fb6d61e8480e375ad9c33184fe37f34e", + "eb24811bb177f63aae9a3e4d9c3e7d0051765e1dc31601b504faae8ee803c86b", + "b6356b7e501f96d17747c8ca1e33367761c23f9f18a6c39d222637f2c22c09b8", + "2016f8cf4d377c566f86b6a75b1a725cc159fc6a941d9fa41d58ea1c44d14dfd", + "b5823ff5f829c23819276ef72567810a912d9277cfc45cae49c4043cc845947b", + "1a160977d44ed0c9c7b0207a49dc55a9cec616afe382e0ae72a6dd7d9891d733", + "58cfa6cd7d36980083c6f715557b9071ebe3cda9f64efc0a3587b3c5773266d8", + "671ce42dc9d3b376635ba865c089509578667c40523c260f559787afafc035ca", + "064bc11fdeea9eb8369898a2c25c271a5c6d9a72a90f8dd738cc140175bfab3b", + "b71604a8fc935e1e1fd51b0243b8705d5d4f1efca5faebfdd76b1605b3dfa24d", + "d91cf08ee6264a36ab5a07c015671f4102de5c7fe17850511010154c0a0be9f3", + "3ba94a276f5fc12f4e61abfeeab9542a59560099fd19de86fc468a2f6db5c7ca", + "011f9099a8350b40a81b32bd1fc7c1af80bffde3150364028eb1f5d5e3939b30", + "65f1da67bd620e09fa2c8de1bee1aadfee643e5ba26aa8794012db68142b5e96", + "5eddb76d6c12f665450b0323eed5c045e353a8064e5f0313557d5a9a614b0e55", + "286043768062be3384008856c98b405330bc95a06809605ba4e654326b4ca61c", + "9c280d1752528fe5db4b67d24156a56e31d17c462da7ba3f576e6cf39171cb92", + "8d8e6ad6f8a43e2b7418c78e9535c740d9a907116e2bbc073176c1e03ff1d78b", + "73d1087cc059f4d129872a63d3ce2e53a69e9d5fb1b71d801cc27259961600d1", + "0f9682fdb4f076e67355b222c24c79ca59bc26ab24a73dce2f57b69c58904587", + "9bf3c3fb7b4f9ca0661b9cba95cd1678004a7603a2de5acf0a022e9672803d01", + "f75ca23030fde80b7764a2e3f221caa33a2b4e55df382fb4981d58f867f1fb86", + "ca632ea203a47ec21617d729b6c1f60066ec7f0b0f24a01622d262832fcee820", + "c10482c7ff8ec46368ea7a93b284053c0dad67be650aeff594f52663f6cdf3e4", + "b5393c6d19b69ea86715cbda04aff854663acdf6098bd51bff2d65333fbfec1a", + "4cf7ae022e873af425613c883f295e770db39ee2d79df6dac2df1f2545763e51", + "9e4139f51bb144a59527556888d23df975cf0da8213efca659daecf9196e9b7b", + "643def47e5bf0fcd84cd0d8780e81dd53d2329d1e78e41cd74220de728031273", + "fd652f3b84b14c1cff3e2a9b2c22c564726692e4d7629582064f1fc2954c5ea9", + "48fea4d47f673e61f17291835f6207abf86aeb370eaafe1572d9585496b752dd", + "25af91e036f9be2284eac8d9e0ad0ea712e6919d95e4ec2382fc934926f84e99", + "34f9777a631d022cad7536121a69a11d8ed141ba0e6bd6fbefbad817259426b8", + "5858557ccaf74b7b1df170e07170d522a654d4d48011284e94e69f8bdf762844", + "6719fc7b8fc55794c7f23ff9e157c814cdbd6e131538417633b73dff021e06f5", + "48cf67455ea143f0c17faf541e9e819c239dc353ab2c6bac30e2dab5d35f933c", + "7019cca8a49ea622def42d96c2bd37a07b363d00833963a53a132e7698d02fe5", + "34f856cec6533e9cbbd0b2050269790c03900e878bd9c1c1b8512605c6b6d27d", + "daa4f1f85d6ccb8093e0c7d5a8a0541b58cd5ca068aeadcb459ac6cbb9efbe0c", + "427d5442dce95351fd3cdf3bb2cade4b58ecbfb98ad5144bf2713e5b438b3e92", + "a9e19932a66eb795ae5747d4def224574bde9b2868e81d9f1a88a9cfa77910cb", + "04908d45584d7452f61064781ba9bf3ecaf6bcdb38d2421aa368bdcb66c269ae", + "961e0aeebd494bdd966d5334f5b4b94062394b376cbcd3406a72a3626308412c", + "0587fe9556fece66f7bded236ec19916bc54532d70be1b0aba11bd0d29250e58", + "998c745a3be3706702a5d7d2994d160661976394cae52fe18b3419b9b88da8a4", + "372e2fecdc9520f17a9b8ef8d5e019584d76aab15998c3f06fa7f1a6f6e8fc61", + "59cc5064eca3cb690a01558df80e7bf499ffe68bded61a9eecc63c410b53c55e", + "d995eac9e28dc46ee1d277741926801934a6dfb9039581e357f828a4d078b9b7", + "65b3c41ea1a7f1f10fd05541395813b75cc69a9c6f068e4db598968462d94ca1", + "7c29689e11132eb9dc9aaaa67905ebdeff17ea180e30a6e00474d969e309ba6c", + "db636ea6c56794827f5439fe4e1c9f1a732fa28c798173e470cc8ce7b7bd4c7f", + "a5d3df5c38493824469888f4a8fadce8860a509369dcc61b01746cfc6552516f", + "e523a2c70b4e04c06be94a1b15ea186d0588a42e0904953bda63221d4959d907", + "e2d531dfdfa37ca41048d1f12b822a394453539669dbd82671b107ca1cfdb16c", + "ecc48f1a1c3ad459fc12939793737fe3210dc8f28150d07f324041593d85f294", + "3aa105974e5cc5a3cc80c212b2d79a468e1425668a7ba9703cce0e2a7d3cd4ee", + "08ae88804f40322b57134d76f71e5f5f1b681ecd38f04421d4e618456692026b", + "b2989ad051c823408c9181179dd35a5adf0219e000f0ddd57dde1a4427e8ed29", + "a1cc76df13ca7d56cac6d8f8163abcf835a52252678c9c616d6111ce461f0df2", + "4a1ba361b850f603cc8b002e493c3fd8399620514529f02bfbf89ba5b250077d", + "54e3199ea18b61904d16fdab31c2925ded4c1b376de0c08351b755ae3fadbb4b", + "181a49324bf409bbb1e49e265400029fa8c184b7f143e52c0306a1200a871b75", + "705ef1a7c3cb9b7486b1db1cbe0c25b75644ba2499318a9358583a5bd7fb5adf", + "fdf83b117b67f725c402ffccc4bc7cc7f344860c84c3dd01d6977ca74d71ead7", + "f19560904ec348f9b1eb215ff3b24b1d9b09c71b041c411b992c41fea10fa78f", + "2c575fe595c33a2652272bd0a80265e4669ec29b21dbed9bf6dc28d3d110b03e", + "2537b935e7ee42b54720464d6174849539ee7f7afc54eddb9b7fc9f12813aa55", + "11c7b36bbdea2d1ae3e58eef936454dfaffeea038e3b2d3243e45aaed646d4e8", + "bc00794158c72c1f520470078f54cd14048ad71a7ea9013c353c1345df5b08b9", + "f582b732d8dd4d8f416b12d34441ed031f2b3dbe9da6160a2cd5e5adb3b2d28b", + "f3ee91e20f48a2924a3a43dddc0866a7837d027c32ad5c0812776732f54b324d", + "24f9c6fc4452d2d4368e9958eb2aa6610429ee1b1fecf0997bfbeb3bce874cc1", + "dce40a87e21ffeb58ae01c864683fd602dbb6291a15625678c5d78d90d60f0e1", + "13cdfbce54b6aa7ae147e2421633be3dd0b43faa88435e164d355092c31da7f6", + "10b5d8dd0ea3092e5c249882bbc25686a5b4062a373fbce5a4e141feff7c9026", + "b0ff0370a2c1259ca3c048c562dcccea6f3ab8ef1f3ec9bba18eb6b4f1dbd830", + "8cd4a52c23c025733502c5ad2e39129a464685322bf9114136099018da73f458", + "aba01cc0d7c503df3e3035db9ff95543ed58dce5d76fe05c277a1e259a797a90", + "e370ed075cb15f6f03c5aa543077956b1c6f8be31c2750f22725af3ed36602cc", + "acc3d3addbda5a1fc6949ecdc500617529b5789e05e18fbf7370e9349865a22a", + "877ff866ef50c8056a0e0c85bfc907aed1d319075b2dcdf0a001269d562abcfd", + "414a180bfcf80388e07b300898c2891ee39b17b33d961af9fb14a4186589b706", + "852887971aa090eac8996e479baa899abf4f02effa3a039487c5553046e90ccc", + "cb317829fcb617baf327ea27fcfacd3b89407591cc4a4bbe7d81b78ff696b426", + "b3ce53f5b869b11f4929f6f80264a90d840d12efacf8c693cbf18afb1468fbad", + "be6bd94e5090411136a846f65d540e4eeca70e5a18ff3013eb8456b7d08ebf4b", + "f43923d451a82956e294f81dfa2ba7ace5fb6e45466bd2af3b0dc4c494e3a527", + "28de6165c3c77c29a55f0b6ee3f7fa8c8f3259e71e161de921e6c25d73466f4c", + "a20a080e8bd6c0e4e0f9ff0d2b4131e8eb3b865290119f00dbdbea13d5263a91", + "8532aea7eaa91167f5a5dbe06051a296d28b057ef106621fe570f7036426755c", + "d38091e7b784c17ff4df817cfa58e7df71c0b0e82a3c75f5fc4d772f32eb7f9a", + "a5674097d74bf2e7db32884ae9958f60ff174777a16b5d1c5eddbbc152241641", + "4163201c6d22235e2d55d2fbec3ba3a0f59c2e1d5d19a33976198aae79b7c34c", + "b36bebe4e5fab2e1f676604c3e5ba4cb772f4898433e7d90915b7c8e9fe45e29", + "6b959f4276f1e77e98c8c072e2bd020d60a77d6a74341b146030189da2204f0f", + "52b2991bac7b8b314717825a8b09c076467f10616c79bc9d18654d2f8e0d4302", + "d0225899bca57e6e701c9b7ae35c89048cda3fccb7ce029a4d21cb407c1535c5", + "83591fd0435261847f699f143456998515b260f395b1fc29662abfcdf92de5e8", + "22f2b6e4bb244e7cdd8f37e5ecbde2ddc50b8e3f501cbeef0d8da063b977ba36", + "58da5ea185f5d1e3017dd51765d928ce32cd545d48faeb09ed9756a85e45cd0b", + "4f9b0b5cde12be49f93d7df28d7dee8964b022cafc301d532a37af045749e275", + "be22bc0dd4ca07e328c68ce31c4f30a4eba484841287778c1ec3f57a3334516d", + "7e0b3a394b01d2847fc123fd51b4edacf6a009fb27458a64273581ff22029e79", + "7429eee33d52c8849078038bb132ce3a244b729f23e640e4712a335018b5167d", + "34808bfc12a308700fdc47dc36d3f049f3006bc505cc95c90c6a6d39a7fbb59d", + "238cd59e6476d86a70465f9e8e3a03f83589b4d5b8b060b6cc80bd89f05b4437", + "248a5ee81aff0d66c7170b6a5bcfd161da6fc499dd7923bb5caf98f57f6db652", + "7d455ee84817507bd11883ec7de7d04d90a2a03fc5fc5c8232df3dd6dcc644d7", + "a188cbbbb62836883248732232c9c1548de1159103053afc5b268984b2dde573", + "9d527bff7136eb2d897b460bc5d61283002ca9be7b84be2a37a6bce2f251622c", + "384854ca6959c6124701a16c73cf1c05f3b998a71ae8b33b08048b1481fa4f9e", + "3a93cce9ae6133d0decb36abffb7b0b0481b8ae31bd53b180f1aea1d875b30ca", + "a8c3eb0c633d6a4880e832291a633ae0cdca3892aefc862a8f6bcc0e7ffd86cb", + "fe71b276d6dcc45d119002f63110ac78fe5fc4107c8840f12c0be7fe0d6ebe18", + "49275b4fcb9d23a1d52e4b843875d74c85349656bd4adb96efc805fe10bdcff4", + "10bb65176e1bdfb956c3fa58b5e2dc1cf01481f4c5ee2350eefbb2de25f8be46", + "f7cd34ea66ec7998b0a6b5043910e0c168295795d833243f615747fbf192c0da", + "01579b23b25f19147c4b3f93f83cc5d9b194008ba553bc7d4b06301015683b63", + "44139b3ecd6941409244b73788cdbd9aa5db58b60450c6bebaa9b936b1e2ed82", + "0828374a59d93b080c3538ef7f45252f2b27a155b84f32ec7dd0bfb196303371", + "81fa487236816b64587e419adb71e74e92479df0e8e4808947015acf3e14d10d", + "0d3879120ebdc0e5b77dbd2e20649acab3caeb98056a40013a20e94b7d489855", + "cd445e571c82d97dd4c17382200591c4618eee477a7693c05942dd9497e11053", + "4f43b45e2434295a4dba11f051394d28eb5d3224020401de03358d4119c20e79", + "b4d4e9f90e53e7bdf01678a7c44ac1a36fff3ef587881e967e485e0358e87707", + "4f23d9c4dc628db514cd215a583e5b9fbd22439531fcea3d6513a3eb6461a7ad", + "5b9655bdab58db402102aa89716a20b48760fd8d37a4975fe9c0ec050005944e", + "a3229caf6a219472ae27e30e2201a052260697f2dd4fba1eb2068be5865d3817", + "e1ce3dc27b5c5880121c214003231eefdc89f791eb5752779ed40cdbc8ec9c65", + "85d54c336c4e89814b39786ab39f17a67007955efb130ada5da50d0be44e57da", + "9d9ff393990571c1d7bf5a06d0eb719c66ee59bd22b3795ce3166330ae189faa", + "040a2d80bb83cd539e67b3bd11e23f02d3d2d259f6291b6ef3e7654e56f54149", + "a11fb1a99d5d5515489b33c5e137b6ba5b42b9675119a0b7fe3c63116e016682", + "9f2cf0f378b36119d5b0bc7a43024dfc5b62586e975ba776d01e1173d6244a85", + "7430ac377933375ea4b6a09836870d2344f4022762225b489469806cf5ca250a", + "9b247cacf8488fe6a3ab61c662bf8ad3aa40b04c176e6dc2701f820e27377bf8", + "0ff8a17cbe21e918d369ae5ab6a4556279788847a06594f1f4cfc5dfa15c3ced", + "31e06fa650863a1cf1b0fd8373ed934a3b77b6447b7540977ce52d163d213cc4", + "65940347835f8cf70f0336d66ab3871efe676e283e4bed5cefe2bd334486e4c5", + "f7ac8105f75f1334fd084111fe463b3962860084ae4f7560f8032d4a8dda2a72", + "13e7183a734dea9dbbcef8ba5546c2da600657ff471dabe4f697e578ce7c9163", + "9f43d8f8063dfb8dbf9c1e899be2a78dbb8f7ecf8ca38d315383eeca859f682d", + "471c3d44f84f398346896ff16378100361583de3ab4e33a0a0c9c95b82a5345b", + "d5fde04821d4492bb35f9cd75e8365889f5fc859ea8929de3af9d228b953cc69", + "f9afd8e8fae1fa075a400a663d5d06a454ca6f5ef20d78cdf6534dc023e1db44", + "ffef809c68412d1ce1a9f322ed86c58fb29c3c0f3e97414184d60981b8c34395", + "0f12c674601badf324fa37a7dae78ada3bec0ce20a50b8c7766638a154c4ce16", + "f12182bdfb44478f90183a942078cb66f6bfbf67de0f3696d05d031fc4f4d1a8", + "95944d1c8415d6281e61ae039e1882c28b01a9d47a8d0333e42c76c072059f70", + "b174721b47372ad88cca9aafdc9b429d65a40bb6a0aeaa2ff74a354079b0e5f8", + "f287bf641cba0497f0920a542e99679f77f533875c2448a08ea35f35eae5caff", + "d7bb2f220c6800de16ce4e8134eea623ad2040bf30096418b8ca77f1a52ceccc", + "703717e34d1862bb6c085c2b62c0422fdc7ab5ddd15a6efe0c67ff20acfbfbbd", + "3531f9e6a2db02cc9815df7e84f72895ab523091cbd109727dee561a2940c92e", + "a117abb34f9c89b7d7370a3501d383da987bde73abe6f5c52f4c30c4ebffa1ca", + "2282bb0b32e629901b5aab4d924d729b2f40ba967d7b434873aa32a36b9c7bbb", + "2871e42489189af1faa70ecf55e5f8feb888e0ed027e4ef7afa9d6926c65995b", + "11d512fae02191d537012bd58894d763ff60f131c66c53936f7ee2d5b2b71f1b", + "249e18b18027fd9b70e009a3d01041ede5b50364d5a69eccee3b6e56235b2ff8", + "62a34a7e8cf596436e29b31c117ee995d973c5658a14f7147d391f4d7fb3af15", + "30582c3b2b27be08cd8e6d2ea0c5e34e419936152249ca2838b56239ec1c901f", + "90f4e4f6f3a4aebc0092a59303a9b970f925e86b82654142bdb4a4b26126c24b", + "1323cdf43611e47e157e7765df50b2ededa311a7bb10ed5c23bf5cd4fb1206c9", + "8be0eff0bbd827fadf7f65342b69470a38b281aeb2f840d68513ef7dda7b1303", + "25cd93f9da2ba1d025a7ab3b002b7ec8c1a404f5ca447d62d43bf8cb77e2c6d5", + "ffd2d0d8f9dd0de14b2c9737c3b709e28972f10e9dc960625185ae47e1133d3e", + "3cca5d653730e0a6aa73cb4a48ad28742a13a70dd6b874dfd10ab7269fbcbd52", + "862a81f82fb5ae9c281356927bcc492fb35fd6183fbd20deab3415be405e0992", + "09a98418a12fc3651cfa18096bc0ed1a01c5a5e2dd5e02435d1ec59605ffb2c6", + "8cbf91ce23d32c8af9b381e8622a0418a905caa8efb258c98d7a67265e458d7c", + "064aa6cbd64e5896d7b7e47ec4e9fd2415cca04cac927752d5fa57fac6843c95", + "7c9a9595fbb7d9c27a747a9f67eabfe7b37d6a255d496d82090751e6236b4b21", + "17c98b1b3865a894d75b8b0efc157d0ce5a1b2aac554222884bca0e95198756f", + "3d0aec061c6f205b3fe7764ab1830d3332ded80bed0667638ae5139d7652f0eb", + "1b0001e4a95ed32db38e671140ab9ed0193c0847f200c2c027f0d236373bab75", + "65475cab00af6925511cd3f133d85eb06d05802ee45039b4fed31a7bf315a2dc", + "5d792c456270235ce9d1bebcc5aaf159560a0ab1aaab05b2eabbe04bcdae51c8", + "b6830dceceb1e109f3803a2ae026b39d7e6f78924cb4f6c556942fb1b1e85840", + "bbb601993171ae1a9247583e704a4b47ed4164f4fffe3b5dbf1baaeff8a17667", + "8245d84b0b23454c21ba3039dd5849d1f31b0830c742873913cae520e26f6882", + "78e93116d900002476bc1f3cd754b1c0609ceabb792dc885320b217411c33f78", + "590b2d8a368e9a681503b1278d5be1f4dadf7a92720c4a2fb445d91ea982f6a6", + "2e52eec69999b7ae696f5a2777969f1fbcdd08fa1d10a5c740314ee678a72204", + "296cba677313544243553e573f78cc1b23352dd75964706f3e0d7a7d33234ab2", + "cbe3bb9a1d55051a70aea47824cc89380857ad09372b4ff8ebd982e00586b640", + "aac374380dd02c4ae7783d92d6ec383aa73aafd1765830fc075b6f353898d85a", + "f691a79d13d6ed9c425a76c5d72678fd686f36087a7f46692a6363d14660d8c9", + "9b33085c9848185299c76fcc4a184c1818a18f8caf7174f835e0df54a26a7733", + "2fa38d15a4e1b9283e1e54a920d3f2ace75b4f2a4ff5cafe3a1d5ff60d0c540f", + "d60eabf82ddf752714e0e5899e0da07edf353b0aa0b775fad3dc3878ce3ee307", + "a48b21ef6211c7ad46ddb156584a0bfc8cc9cb1a2b4dacddcd74b1e2a4f00c58", + "18118ecc398d9e8d0cefac7d513e754cc0593cff18552ea060fa68050c339a62", + "402bf1f37ab68a240af961061fcd51d5b74457211f45550988efbbed0d16159a", + "5f76fced0dd9e163a0b449df51187dcb0a39b2fb7d4cf02a3bf8c94eb618aa01", + "eceed6c350093b8dbaf65490be5b9f8254ce5f47a1cdb346a369ff928e0c86eb", + "30f3c928c22d26734fbe83a8cf051d8aa97b2729356b99c9ca7ad94936a0da68", + "2ac1a5812383a3016d0acab32e2d9b9156222f438975e0735b79810ae31485e6", + "ce4fabaa392f3084d78aa1fb7dd85a65d5cf282c26ca04077afc9e244a0cdaa6", + "abb4132770c138fe06fb501229fefd0be342680511f2d8f901eebae6ad116bbe", + "b47deadc8cf86054bf4511f3aad4ba19ad7be5c355b4d8ac1f2aefd6b3a367bd", + "b9a27271c4f76329e69fa7c358665b6ffe5b6d83d3a9b65fe243e0249fb179c0", + "789d925cdd5a9eb9e78db39249a4d41b62c6c9d69abb54f19d211065cd554066", + "cf67a8b09b0f224ec6bf4bee6db8d118fb42a15adfd6da12bed895a51bd2c361", + "1fbb2222010f26e88025998e7e8224507b1f8e767bcbbd47e30a84b5fed84578", + "a3bb52b373bacc8f1e1ecb16a6d10a205f8f0224c56a6c8f50af7e21abab16a8", + "98b80232f028e990bb50c60f658b12e397df84a92f0720ecae8db5e6d69d446d", + "36529265fbe4a23da90e8120c4b22cd4deabde67e3d8451ca267cfeaad8d2d9d", + "47da27c45a53b4b7e19167c721588d4b1be5dfc882633742e3a425e2243bc458", + "dc52fde002f6cddf19ae382c42073d9fbaf890c819fb60884f55187b51fa4006", + "b7ed3fac1f412fdf674b2521f46dd35af5e38c8d75cc642d715b519599f3371c", + "1593296c5458bab8bd2192796c0a643ced5755e817c063479bf34ee8b26b2980", + "823a00415855f541ad3cae50ce7efc138d38e30a2e70386e8be28bf6eeee3551", + "ad45f55979590bad3b69807fcfe47748ed54a829563e6f08d1c59defac1aaf7e", + "6f99d2753ce44d87d722a51c26fd5905080b8fd7db66f1f59a094bc90d541426", + "90fc774599a6a3c4068d887b317c95a2017db7acbdf77b287c84f6922a797267", + "e099ff600cc1035ec8f87be126dd08721e7b75d4f5e00b6a06114b56df1b865f", + "e260a43571671df337725d172d31a61a1682452b972368de863984f2142c3546", + "9e7b496734c26740c4552ec46b7a83d8b2d6f8d18feb42bb7625cda0f3152fe8", + "0650ac223d3192e4663b3699656dbd1829ed8bcfbfcc2b02e12c9169c486bdc4", + "af3c83e4f703fbc1c591f452ed5a379248cfc941ff5cffe6b5559973c12da65a", + "97dc76b30ee90b85426d6dcae9b9a445d86ba97c4ced824b6aa11cda63c7de5b", + "3bbcb205b6b4bbb16ddaf69b25c9d1dba2bd620734b3ee7eaef1b80c8c7477c7", + "408c660dc68cd13a71009bfcfeca8c89115fb0e3ba6832e2a7e139f602b0fbf3", + "e285d6ab3fa322a2a2478d726187c09b844ccffb9ac387d1398f1919de442d45", + "de2e04a8a48ef46609a89b54666b529fee21fba2415465a865794b3cef11c650", + "1d4c6c86154e3515f3322e0341e8e5e87d50434fc0eb3fa42b6377dadab766a0", + "d96844a105f55338929903df744ede5a089ec2c09219b2ee042f013d91c0239d", + "7d78b296db5627327c7f6c8cb5e72d4b891a4e83b823040eb3af85b08852245b", + "c7a1a613d153e6d09332e02cd90d8a9d1d41c9617da2160a1d4c5debde815a98", + "dd46289572c4cd13313e38b2d121d5ac5e83aedf22db6b1dd4ff0774362f57b2", + "804a4e6873fca822b8b63ab77f7065c1d704996b8b9633755f04afd1143ca6fe", + "afa31d0f5dae49e7117673963cb6cb2a0f6b83efa4c6f70314ec5d56d6aae40e", + "8a6c788cb3b30bf5c93a03c16c29323111ef9030da0fe4ef3d71135ab5af45a2", + "4e0040c7a58da489c77649979ee16edfe6811624f32ad5211fa4d0d1afc6b9bb", + "e1c883b78680d6b7bbe92bc2c4b5036ddf479e065007b1000a6faad511c7405a", + "3f87b7cbfa33d80469f21dedd4f0de5e2936e680bfc7b1c0ffac328abfb321a4", + "99a01839be6759d49e776f7aab597dc1cfdf07c202b7f9ae5d34e67e7110e201", + "676c0c5ad01cd143aebabcb7d2774279b8dc6b06e6a0828cb09387898e06ee81", + "df186881919bedf81b0aa070623f0670831362f2e65a3fe807b89fa4e155bf97", + "192f414633bfce67ae182b2bbafa3e96156467416591c66fce66e311d50ddf38", + "985bfd9f069d4c27b530e2f4bc17942768e0fb1c0ad0c31ff9d900a88c125c68", + "2c14b3bc34702cb6fcc1146fe8ab4b5767496e1fb592b4ba77c27bf501efea95", + "e3aa9205d5335bda00d8ef3a20bb693a1b4d8dda1e52ec7830b792aa4310815b", + "b5474274cc831b1d863d4adfc6aec1faeb6441af8d7f17f6282b8fc73b201230", + "cca96120a0067f8cc8c61de18ea2263376209bd19a7d65d8d134dd26efac3c08", + "727b9c7f184e86e3c90c154c370881693d256bb64508faa4e434868afc3587d1", + "c62ac4dd5fa591fd367ecbe29f331f5ad101b32155290bb81958d8f3679a6b0d", + "979bae8416280622cb227df1263355f6ecccaa92cf5df448c3c59c7aa4d8fcc6", + "67486120820b343da1f355c098ed5a5d1c455da5dbf3e542dbd95965c514411b", + "54aa4c988fc4880a814e31bdc335ecfc0aa1e4a67b841ca36f518a36647cb622", + "172d2b2d7bdc2d743293168880da441de4242cc2b9ed8ebc0b8371578e4dac89", + "416278e9adb30be5137d8d5e1cfad856e07ac19e3b72f76bf91d24fd34739764", + "7b7fce07b737dbe0d6961f8e17740b5ee58ca152cad96176888e041b1c642b47", + "9e21ca373c7f44cc8c3e8f0cd198f89927352497b115e54efe8cf587777edc73", + "7ddb1bed2db2be053136f9509192e52b91e5e8712ab1dd2cbb2d272fd7bfc0c4", + "4e16af4abe96481002af611e132bde29220e0fedb3f0f6ee720646556dedaab0", + "900beb29ecc45d9d2d0a1ba6da2049d46505750715fd1433c8d2bdf7b9b9b3d2", + "c8260b7472b472a0af504e0aba0084deac77af600c26cacbe8c40202b6915d55", + "03ba49e6a28a704c7973527100454ecbd8e7a3903c4eb4bc62c45e553de4e818", + "679230919bc3f9739abd038de71dc8f8fa156e6440a8eaea2afc4c187e7cce13", + "84fbe4d1f279cd114f922edffbf421c47f82930fac2ed021633018caf26235ee", + "1235e0d4761c8db481b17fd5b7d74388d45ce4e9704d2bfeac4b9bbef78540fe", + "e70387d446c94014333fe5216a5d95a807a470ffab98b167b649d49e4df36eef", + "67af78e799b20bbc9e783aaa29059df24bff4d38517214656cf129fdbf8c19d9", + "491d9c82b5cbeebf23f2dedd90b71b800a83015ea74fb60a8a98c5f85759c39b", + "f839d0d351f38e72596a64451e5f15dc1c60fc3aef8bc928a0f91eca20c5180c", + "5c48a457de622ac00b0229921fe90b33be280b9ba2f66e31a1591f037b748678", + "a9535e1913fb99f476ecc31cd817c129dfd584a973b0da73328a758e0a735d50", + "d2e192b883f9e69c77abd23f6e5d1f74864bd4e6f0c0b70106056249fbfb4e30", + "5be7dd5f2558fa9a6ecb21b259b8964445aab977a8486ef5ce06037fa54a5667", + "9d78859c587b054f7d9bfc333d38c83b022e22bf2340539fe2e5de669bde9c05", + "dc70ef5892bc6db9eff0097199139c42a8ef9be260234e34bbc267967dddd059", + "53f71241c337a095fd4d948702f0af79c1936cc600d1e808b5c2ee5a8bc74554", + "b2f3d120efa2b4fbcc508e5b72df8390b39eec3a6169831793ec1f3d350df5ec", + "d85dad27c5f78d6a4726e9648640e32039aa86b6c819615de552ec239f5e32b2", + "78086b11cc42784279f80a0f2977b41aa38585829485b98aeb38b74c25af6813", + "20b81b8dd0965d97a0f1300d77bd0bfdbe3eab03789906fc1c1227772a84850c", + "ec14680b0fe0d3cce50a57fa78a56761e7094d2e17d8bcc8a78f259c3955ed72", + "df68adfeaf252568c2023772569d3102418aa64d657202b3720a047151f578d9", + "c483a3469ab362104bae8fe8b8d145779a007dbba3d42f41f62379452032cc5a", + "8249084d17dcdc29386225a0d20f9970b6cbb11229dcf437097f1e59061fb409", + "7d1828fa930b68e4fff0a685361cff8d05d5d6bf4af52b311f48450e01f6d01c", + "01ff8626846e3f2ded05634a72b6a15a9b584fbc54b4f966766b98e74b4d9a9e", + "2f98237eba696113ae228f9327ba02f4ce6cd545c2f65e2ce490e456bd3b158a", + "f7e2a5a9d4020d580f74f8e4a44d8d66fd903fe990a21df770ed0032fe4e82d3", + "e3d878e70a907a5d292121d729be2c0ae515c8a325572a721b62dfc4d2768ac2", + "429299eb7fffb51193ac0302de72b8e8ac58de79695d48033cab597143ba3370", + "a2daaf9d74f3ccf0a451cac3a3c1225b475bbdb0c29a348b0a12f15a41a46c34", + "75cee66c92f805d51174e68401d5203e0d1e8f922c9ea832d1fd3c97170e149f", + "53b51280668f37e0512fad9dd9814d7510c8f0be95d28d653dc3e4ac06a04da2", + "d7185a8ce9e16d762e64e4241fd70cb31f0fcd0ef2ae485c2be5e762124b3714", + "8f8d4333035bbd9960e271244e134fd4e93f2d33a6be0baef1cdc5b72400b4fb", + "473f689315fc357503d4ff5b1ea9f148eec1e3f922403ec14ccab77ca4e5583f", + "4cd7511670717f5bb8e412f802baccef485eec6344678cefcdc38640c10beb24", + "55e327a6bbd22dc2eac9f7e84e352455536f147763f4f88c7f32451e292df7cf", + "00ca01c1853d3088e26d3c6ee6c8aa59585f59b84c1615fbe713d398901533c5", + "d4f5f2ce417e0e1ed5272301ef7e6c141dfecd5f159eeeadeab97821f87da31a", + "487486ff1089817ce21f1ae83d58256561b8c4bdcca24bbc7ee26d562d32c066", + "88942af2dc67f9cec73d60233ffc21998515694e020a6282435d7fe9bb491c1d", + "30bd01585dc954b8c58e4035877085567876dbb11d5376c8e920df7745d26cde", + "6671dcb6678f6cd2f4fe44d641f173397f70685500030163cb17b8ca8f6ab927", + "4df9d8a1f3db8e68ed742da7ccf119ef0859bcf487dc107aa48e47eef6fc7c0a", + "1dfcbbe502f93b5fd7dff68a314e203f11353a878e3ebcb0084ed3929b020ca7", + "ab2c1770232594384f064b7f724f5c17d0c52da64450b9d27972d078a7cde68b", + "6e1424da46a82e7e8a3c292dbbe3861ca3929204095e4daf2b4c166096532d46", + "5ff14643b38f68c64f840799af7c8a0f875f912f20f84d5b641051616c5b3f57", + "1120f3368f602b2185acb857b0464ce92a46991ead32c4167cdbfd973a75cda5", + "ac23dc4c12f921e011ec35828eb55a051adc7e3538f27d3d6df117a9afa89f75", + "9260ec44392fa4e4cfcbcb2fb8ef449ddc4cbacd1f493f55f8962dd823809f69", + "068d160fb2a7224bcb7f06aff02f646b2acbb8065c6eb32446c141de1ee854df", + "0ecc24f1ebbb43e89bd5a9008ec4e8f5e1ae1f85b574065557c0a3d6c0babc91", + "419028e19a398e98f89330b724b623f1a2a83ad196af9a2a7e1db13b60ceaef2", + "c8cb50f6e61331977c474f52c63feee2e5ebda1b80fe0cb1ebd79e9d6d622399", + "6ddfdafd3330759c2366f4b6fc7963038bccc33d3360bf6f0427a7710c08eae7", + "a66e389d3271d43b145e210474993515d2dea613b5652035124331d0a3c51bfb", + "5b00bf4342c326c4fe5195f66b086c939bc848d4c8717c10a117fe2bef0bc169", + "cd3f232ff90302fb263480ed7836d57f75a8579a391b4d0e9033c42e20d88c5b", + "6906970092c63a5571e5345ea7443010874e467f3a460cb59df41a516ebfe877", + "7674cf3322ba0f1b13099f8c93d266d55cb9275a0926f96cdc21b3b72dfcc1fc", + "d893bcf3655fdb89811ededd6297dad4b790b4e907456d8c1695a27221fd660a", + "db4e11389d3a757ccd26bacaee681e01af0dd62cf4cb6bc1504fd24b2a633c06", + "6a88556343ca25dca5c21f8c9d29194f7dc057c8be54ff62311dbc1a0e7e0bd5", + "3eda76779241a872cf1258bbef26987a3db81b029f9e8f2ebd503a9ab462a5dc", + "78fa34bd7f67443cb6f0ff2d87499851f20826db1a96db63c7886b7744c73d1c", + "2290eb28ed967b458503c5cd50d11ece99b8902f61ca4a0959de488c08535b47", + "6b28d3fdc01c6cdf28390cb5067e6a318e199608d62ff18df32dc1808ec2a350", + "0e3dd46437dce4923525a65fec1e54726550c34ea9c477e57a9be4b476ce5fce", + "15123fbba012cc96d9004f93d4ae50534079eb1c97361bfe05d136ae61ece41f", + "2694e248601d5db85d3340abd5d0da5aeddcef9052840338ccb4439bf8586947", + "38c1c1ddbe9e4b1aa436baa1f90440e32223499217870439981a7d9990ef974a", + "fe342ab217d6f5fbccb6a811fe7f40d5c9a2454418988b9be999c597a8c0d6ed", + "92a783fd449a157a278ff1ecb6386888d85e240365296273d9e5f5d6d3f0346a", + "5e078fdb64386e309897153b5dad19fb41fa8ecf3a1f1c9607d446a029f31731", + "16f4936153808ccf905577783caae04bd61c56f32aac2a027284c97c1c1c0243", + "3c85046ae96002fb674d9a6c99a782b94bb82bf83ae6f7f33bab91eadddc247a", + "a69dcfb352e801d0ed470fb5f37dc3112212f4702f7b6089354e3debf66090df", + "8498d88f1372ea9ac8e35dae23eb6090cda19140dcef8f4caa6ed4977182b932", + "e7bb06a5c374999993011f1f6bfad5dd07efd308bc48b58b267019cf5ac92de3", + "7ff8a09b6f8fbbd7105e39dfa518030f62b29da375de1973706360a428c10ea0", + "e5b69d840b0cdff0b26128c264b9b8ff814097f564805bb124e8d637d06eaedc", + "688fd4b8c65c468a8837666b446deb74e8695e063978203da247c2073d100125", + "8d15ebb2363ff124cacf840eb58b19babe2cc70e2d6f1ec2bfd82160846f8e33", + "242d60c4aa077a5f3046a8c46743ac3c3ad0033ac68dc9dd88a92fd745aef07c", + "4847fe10768b6c49c7122851967dfbdb49320e3938789674f21309955e5b7110", + "2a9800b6db8c27cfeb519dc1fe8286ee11e646ba857f0a96e0eb433b4c4e1a65", + "70d26e3abc4d3748c6d883b32aa892d46f1b0ae818c77f525558d48d818e5c1f", + "4c8a7fdaca7ddf49017eab6067957eb5a9744c629bec64a981c8c9adce2c2776", + "48a3f768722ea868c482bdf20635d7ef83bc301036ae453cdb8b1a63e5bb9256", + "b65f7cd3a7033a44cfaf94e02f93064294c26ea978bb3cf51bab86cddb0aae9a", + "9e80957de4d60638d176c8090f7c465f77b133a28cae66ae96158c16f32002cd", + "f7a4f40a8c4ce75500e99a7f0b1bddb2179069bdd6ad3c0d2fbe36f17f36273d", + "d389e159584a92137c4b721192ff369b7ccc36ed2f63653ccd6cb2d7299bb42e", + "63657d77fc890b32388a75c0676c2a161e75cc2dad5c5fae27c0a16354975996", + "fe7fb46eced4ae3206b24a03ce6159ac66befeeb9954e53a4003b95c50693848", + "a91e3b935346c07bedaf95a00ec60ecb563a699e215fa0f9c71b1df40d9a6d54", + "758a09c7b993a1e40547a0c83135f7686efefeba6a55ed655350e1eee08fd9e9", + "b0efdc74e965590277424b12d13e613d53ab501dd08308e4a5b64543c50979a2", + "37865966a3fe11089651790b293cd4f2473656b7c9912897909726d68b1d6929", + "37a27347ee759d3d0041a8cae94ec5a9c18283e9f792a5fd08ed4e9f10f6c986", + "df02789cbb4a41924c3140b3c29b1184ff1cfb32243bbfd4a591ffd2ca9de64d", + "1504713b76b213363beeff6917c12c9c233d04f79230aa3aa806d8e059163dd2", + "b945980ed22d9339cb19687dec18182640321be8c7b42229d9e6a07ff22f2938", + "0ad34fe6731a09087db27f404f338e0a8dd1507cbe52952369eb680afba9e3b8", + "ef89ed7f233e1d18637bb115dcd6f5610c52b4f4344cd99dc9f0ccf7f32eb74b", + "a4a8c338640891f43d1e838143998fb8e6c4bb2fc986bedb44d13441c07aaabb", + "f2462abd9f4d574da7585d853155489cd5be52bc3773c0b59519ad9f0a2584c4", + "525c0fbe367731b89ec3e219e03418ef603f054836ee541d97bf4a12de89294d", + "ef0fb71bc75ce29fae935d04acca5a85fb5a6567ec9a6b1374360dcefab806cb", + "825f0804622ab1e0644d38d6fba9f7b6738d5e04d8be13cbdf4d00e436211a11", + "4337d4cf35f0bdf3e9fc70350c6bf79464c3aa3a4addba1aec8b1a3f396dab93", + "a8e5cbbefa16a04367d470479b27e7c396192b24c2a83541c4388b1ac6968abe", + "dbaa05426c2ed18bd1db747e8f28241e3817f8847022268b648189ee1bd3df28", + "e2320a48f1371ed8102d3870502d4c0857f6cb973163a128204a4db31fc5d258", + "31f56abc8999b503341740c002774c5dcd04e2369454ee482c0815db0c02439f", + "a499892e1c65df78a1de63cf116ffd0e41152d2a207bd6cfbb0a210f814449bd", + "368014ce6e48a7f2afa25213d7f99de40b728b3de000ebf13e44545ed598a553", + "ab1f4f8fac3d9091bfc49f744291cd9bdd9512548ea21f7a5c9f038db41b4304", + "10d4cb690da576fe8a5f4b79863dac198d6d6812dc61d80245cfea672f14316e", + "bff259029ea3662d7b0a1180f90fe486e801819ad2ac4d92441e9d5e24cd614e", + "fc3ac807eb121f849b9ed2cf048e6f5f4a2fcf47862de282a70a3ffea6f241e7", + "c16594a1926d44172e9a8811f921abed706a5ad6eb6c027dcf7237bcd33b3f1a", + "33ed8fb5f1a807118f9202d948f0e460c69ee76a5db1302e51f21382070a793f", + "1934df8dd9a4d570783e481acf52d2a7dfa3b32e50e0e51e95dac784d1d1af25", + "a859e9e11146199e701ee419ef969ad972dd3d5563aae75f79af8f260d360246", + "84a76dd2fc3c65b5e1d58b58fa8dc8bd1471e8bad26beff1412a546e2f77067b", + "e6edb44613196049fd1de1a5dfac44e415e9edc6ebfc41a27b9313000b8af626", + "13a637d4f20f7d97c4b1fb63136bffcff5715e25cfb6d7674dd5d3faabd79c68", + "9043e8d86884701998a05d2bcfcfaaeacd9ec615f49cf3595698d9922f824cc5", + "66f730511c8dc45425b42acb834a93dcd0e58ba5e4feae84f265c1b77ec62afa", + "61c1a577baef79df09993d035c931a5becc7f4912562c4da441a1699cf585539", + "c88bb33d1322ce5abbb308b475ac9e043d3bbc47972683e927f5a5e7dafe7a11", + "eaff236210b466024c85593896a5111c67b998feb7491285d31a23cb6b4486f5", + "ac4beaaa4c95c98de795b1753b4520a1028a479fc955d102a308a7819525ea76", + "c635b3d99c6a409981ed11075513a86b5df5529bc85de5a1266606cf490895c8", + "1fa34cc71684d84a15ed8914be7dbe6d61e28990d5499cc6d4a5bf96c6337c16", + "9412cfd784d43e6cd11ac0d200832226715edd81a0d78ea7caccd1a01c169236", + "83079818488ddbf6bca28d6aab3df4e5b9e3004bb5761a9466b9282f3a96ee92", + "78b18b21ab8d83299dc963320e77f738ae017cf853354ad7e9c1af4a3a47cca6", + "af28ad299f23a28c674fabd6434f4051a1d067122512f61d05bc435c1c103e0d", + "c03b4f94324a94c30302003948676f03f0d373a4501be65d337eaab7fd38fbf2", + "3019b1e03e7c085f45ee82285348924997de6e5392fdbd8095013950379c2203", + "3f58570c2584a5c12a97c69cb66481660d24a4c281e9d557b78ecefc1a1fb902", + "89baeb422424e337a654529269d8f4608f3abc45e5417ccfc7a9e9fa1a51341f", + "2ba5456e5e383353d35b11431e245fe48a56a93c996bf3ea021821508b22b130", + "e17028dd502daab2c4dc98afb647557e5db9d38a0b4329d0fcf9ba91655cfd99", + "86df3e7b56b37a0acc23b6a9e8c05fe6588844951af8edae2d1681c8255e1051", + "654bf52db88ded736f19bce43f1d2d9c292f3f7418ca47ba75c95945cc794d7d", + "b210210078dc447b952601cc03b50281cc2585f994e1d25878ef42c0c67510df", + "5e5d02bc10da9cced6907e77072f4c2c8587e7d94f914a5a822a68c2c2cd57de", + "96c599e0e7f2c48a947020dc77f315d1e025c16f45ea647d9b1945c53c3a6298", + "2b665a9baa847b557fc3b82a4b1b7e3d92a7c93d21fbac945a86fb4214232ebc", + "f53f5406b0d4e702c0e917e435d1f36dc720f09ea7670830329f2d94e8d12f2b", + "c0830fc760fa8dd0afdd16656dc757460180d53fde9dc27cfa69aa9451037dd5", + "37731fb70cbe234dc42d22f815bce1a714952eb1255a7eef181a7bfb96037123", + "f08af7214ef6d490314fc69bd4aea3b0dc0bcef41462df5e29c47c95c26711a1", + "58beebb09bfa2cf045d013e06b0fadd6fb95a5b4cc928c28c0eaf4bc0fb18087", + "44e232e048ee02b74e69d0ed25c48faee4b3b60e7819a52b17acfe747eeb1c78", + "d13f44946a2827f3ae646fe65da57641a3cef33092c4b7be44eebf0c1d018832", + "0842f208829347eb862d0bb7220e77a5e39061fc1a913b8e3211246aad34e6e1", + "abfdd5acae7676b26840b0026b482b39a0dd4148f69f022f83bcb4830cb60433", + "bef2cbddf59549cbadb0f457d2a445f2a2add4adc19e362b9cfb1c4e49ac0d96", + "243464c539ff2e4ddd24034f982d42f72720a0cec19fcc2956f7fdeaccbc7bc5", + "d9c66d7a584f4ed174d55230802a5e381a3453f39c3eae94df0377483ec49723", + "31500ff5c644be7f303fd5b12210c1fd40331c2a5fb52536bc36cee79939c02d", + "c8379c9115adf9559e4d254ad596e394d5b13ca69584590f7ee19e4b843fdab9", + "2399afa26f4b3b5d6ac65a08025038cb247863445a2f714b9f6e118602320a2b", + "c25fb5c996dc898b771e2ce52f20dad31f379df018300123dd655b0d26f82be4", + "de240be917566cabcfb99cccf419e06cf3604769b6c35f39c6c34bc47e5a4ac6", + "fccaa08ce2ebd0c8dd2ec7003999a1de0d456727bbfb15b5247ec04789248097", + "53319a7fb7699550db78c1cc4cc6c45375dcfbe2e27d022f6927a66e8220c500", + "a6b39f10bbd681e73ca5201db90b058952a566a52d3ac5379715b5a3529d47bf", + "9d5cba381883c0a7539e26f43a3be4412459fa8d215c653e005e60338c903ce5", + "358ab2db25afafaf119e9e8e39d187713928c94ba5ce881ba0be11a4116364c1", + "f8fcde7be7258e90711f9a8d7ee1b5397184c648d6e464ab7980437b18bc5624", + "0515ff9150a055de24c4b857a4761356a38c114cf5ea45c0945457fb2b4a97e3", + "f685e8bcb2757cdf98dd3a7f8c0ed8e2e257ceba0926e9cc48b48eedf4310df9", + "70fa7170a860d66d1e1a0d87a0eef00f4827cf9fab5cc99438da127f352697e3", + "df1f132923b30116c0cabd6f8b480e9069a9efda79d579e6d5ade11ff459c45d", + "959bd4858087213f3067ed8e211134297ccac2180d41f6d3f589a4729ce1298a", + "36c41c6689b5d14751036d3d2044ef8a9cdc16d19de2a37254ab38c5b5693953", + "95c07d6903df72ed21625b7d98815117b859d4b4b34f1d19b6ebf28c7d21c292", + "0dd9bc65978e0e631b61abedea7dbccc20937231c6b958feee82ab30ef2c4d3b", + "fd6539e2125071405ed81df31a9e09b09d29a23170c046197c1bbf694edf9a3a", + "ad967cb53cff4b0b4a46d9fc13b333c0442218d1ab922dca2ce709d4e4f3fcb8", + "b5abe17a05739aab59007487355d72790452c8f24ec4d5da3e30c2e7b9129adc", + "fc991c6c61514867208ca1d73e4487b37dd99b408a51bd4f7c25afacc136c424", + "7cb5c9ce8516ed8edbdc21ccce5b315241066e842286ff8b6e83606bceb0e649", + "a8966a353653c4332603e5d53f5f41e5921b9031200624a0899850d67dab9d15", + "4bb2f192e0c733c3b688dacdb8d8ba8ebfb8b25c4c695305a45cfc1db63e6ac9", + "71d89b486202b3f9922463ec89bc7eb65848e428d067de91a791440c5a2e87fe", + "6f95537142b888ecf55b825bccff9396fc0ed788e72be48ec7bf765a32d43716", + "472e5575d66f3c76cecdea13bd6dd42c5b2d94b97438530dde2f6d6602cb2d3a", + "8845338a71c9d1cc313a601c51d24754679ee7ae5d2d75c43d859852b6ab996f", + "013d821d2a86cf6b691b8632d045b86e8b075c7ba5a65c27cf1044e3aa38e438", + "2d30803a304f56d332dbdd71a5a0ac39973c43aa058f4f0fce8e4b924d8a93cd", + "0652b108d9fd2f11555ade34588d538180bbdc39f487e082ef3f7f712646fdfe", + "7e0eee3db277fd18e99d9f7e31cb09ae0fd563667a5491c0ac7e72ed4f2d5d8f", + "9435b8cca12293fdd69327ca61519f38f51a28da2be4fed90de0d8917c3264c8", + "981cbe8549a5400be86ab3add3be3bd79e1c5d31986364313070a11709efe952", + "3f7a0a4c94c3adb24641445cab2dc3c68a38272aadbd5c14e6bf8b2630c2366d", + "4acd1823b9df54e3c20c9dfc04940a9ff16ec8ef83605ab2c6031b6aaa7e90d2", + "a248c5f3407c9c73171ffa5299dbcc79f086904faf2ada3d79e58bca73f8d1af", + "d9ad00dc9dacf84a54c9e02ee308f5733bb50e63cab72364b3397a5c9838a848", + "165dabfb27a72f70585a1de7da517eda5646d1612e96d6d64183702ccf975b59", + "be2ae63d529e84829c88866cfeb09a1ec6599c7b1d82e6965fa5e053b207548f", + "8711a23bb87f6e9d3cf47c38c8735e2eb8b4b582bac3caa049ceed27856310c5", + "e4542229140d4d8e2ea77e4893ca73f1b799b0764c3c290e65c50a8293e395c8", + "6b0b389bf968f4a1fd8a9d5d13a0cffb8191654455d059e2cb13d12c77f6208f", + "dc65f00f7e380715dc265549ba42afe379ca4933492005499e5478b13b91bb02", + "2fe1d8ea840a63cb1ed5427d122d6b3b36ab2067c680dcf3ad04b678ea1a4fb4", + "a71f08ed34c0069129ee894092c84858f6f6832c90912915c901b11d8e521290", + "11cccfeb1c04ba92ea91797c3640f4dc7f39e321f4da1681313938f0293b93a4", + "0ae9ed2e0781592b40eee05636c0aca75574ed08dc9c5932725e846b6d2ab2cc", + "a313623ca6a4bb5d79b8be6bd46f10a8a303afa0323abbcd41f2233f00c3212a", + "f7f61c84b09c8c86f8876b6a5fdb98e52df41345f407ce484e594908ac7dbb9b", } -const mainnetPreverifiedHeight uint64 = 13499904 +const mainnetPreverifiedHeight uint64 = 13627584 diff --git a/turbo/stages/headerdownload/preverified_hashes_ropsten.go b/turbo/stages/headerdownload/preverified_hashes_ropsten.go index 1236381aa7f..3cde623dace 100644 --- a/turbo/stages/headerdownload/preverified_hashes_ropsten.go +++ b/turbo/stages/headerdownload/preverified_hashes_ropsten.go @@ -58907,6 +58907,673 @@ var ropstenPreverifiedHashes = []string{ "2f9f7f7431cc0f450660a488fd4438a00dcf000da528ea7e30a28731691448e0", "1d1bd5aed02cf1daa82f7e81946154ac4677286830acc8ea557e54aec7e38058", "65e1adc410dfebe9d3a7ef0743335c9e5f195703f7ea8b585eae2a8b619269c3", + "a894bed09317841d1bc0d74687896903965e4c24264153084a9e2af79e74b2ce", + "63aaeddc3afa2f7f384df08084e52d6aa3ef2e401d71a605523743648d489fcf", + "7b8c88a4e34da810b1ab7fc9071ceff74e60ff45f8e628438016630014bcb9fb", + "1ac6238ae2ef43647073a8b0427891075208462b153b01e2f84857d5d052e912", + "f1de65a886e312bf73037eb7c8399dacb35c3d33adb1b2dd7e57836892a6f7b1", + "5d12d6df2ec8fa33ee7dae6958d673242db2a0efa33701e1cd33105afecf8dba", + "84463c05bed3df6bd43062cea6073025168ab0815078b36991c6895af49b7af2", + "6f0c745c4937b6fdf3894d3b2125bc7e3152fc2867f6fb59544e3b8397ab0536", + "1efa0b465f8093d71fc6566e4f1906fcb9fbc7935a2312ed600edc876c7b29c6", + "821777cbc9598a8e410aa2093469ae90fb95dec854c3a7be8dfbd0024b364150", + "5ebf56d9db6d4832e8a0073220e13cec576fea6839d15cbc89b82305d6f03eff", + "ef37e48529e24048d1f613d96507a954d3456d18c2e603ad532ba6938ad72218", + "98b3b77caeced2814a985092e985e4af11a9d03838ed65dbff4089e05ce1b671", + "0dc3181796bf0c2a0adea5b75af51b99e44acfc88f32efc4c17ca94a795fd440", + "3316d7d5901cb67d0f8389056a3f5011693c4815d49cb464fc712f17d4577099", + "e6f8ce719a84026c4778154458f1bf91e3632c85f22ebf391ae16036160ee25f", + "10a2d084b68f3882206e4a2c2ecba5dbd5ec2479dc3c8b971c49ab139d77b5e7", + "5ee116fc14cd34e78ccba3229e81244936c890621d8c7a4c78a010ebe6b75046", + "dfd2722ceb7d08de056b513a7c47e3cfc87f965ee17c6db1c12cab4228ad777d", + "5ee5c88876489bd983601b70a307397249f95000bde5fabc358b19e0b6922151", + "7ff69740ecb0cc6e726b00dcec1bb771e09a56911ef93fc9cbdedf0bd2dd6009", + "694a11599566404b4718eea5145e88c443f021a771dac61ee799f5c2e4b6bc57", + "e6532956ced2b17b3953b152b44b82ad56ad0c026f2b6c11651efc1304f8d776", + "ae3dd61f1e2b8b6428ca5ceda9500950a41fe10abd515e5044271417ba9b9c29", + "21cdbf6f75bdd12f704abc9ee935cac55f065f946b2ccb13ee7f6959cbd605d7", + "da0ffc4afccb915a520e5d314ff92974bb5d67c4352161285cfdb862e08eb9a2", + "2ca9c8a37e04339b857f3069afb4c27258461db1149aa9ee1fa0daef2a0c59d6", + "b567e801026ff17cedb6f946aec0ea3ad43329a9d73cd30dac3f2d0b4ba4c753", + "5caca40541ce53f841946bcfa020af52de1e61e8808b975a57dfbe16719141ce", + "c51f455bde3edeb7453fb21cc27ef840ca4fbe35f21f8a3cc98c55dd2c35309f", + "59cfd93396d734d227046459e026ba6fc1a51a167ecee3f42b3d8bc171bb5de0", + "da54d6516acf66c047d6f1a790dd021627bc83c0f7e87c1d73d5e79beb2a2326", + "50520546c7887ffa330871bfdaca11170f4a288b66a25c35e214655e6ab8d18d", + "a5be07f2fcccc583beeca9cc42fb80d4ea6da816ce25156879533a23bc1806a4", + "43b015173dfc30ec9f3c6b2380b4034371d4ee338ed0fe0f64d0b2bb7c9a50b9", + "5ee026d42bcb34a7d0105d6c094e715d79582a59d96a2a9bdf15468d58fadb33", + "d52086c4f48045258e95d02cb4f292afe82b7d205f666675f2c43097663ac7aa", + "86c256faa6393e5466d1f7680564b03c8f019166cdd2fe7d4be596770f44953c", + "97f238f6ff1da768f97df525818be51740646eee7fd024e74dc23650225176c9", + "78f212c84a9f9384f3b8920fc190b254ac93a9e1d4a588d5d6d414d334e53c3a", + "e3b3dcd3cb27a298e553f0f71d8bd5d94d74a3129e9679b918f07b1fa1fa8bf3", + "7dd18f59183ab668e48c75e3879368fb4921800e57fdda827bd7170d9243bb3a", + "a20c7f0cd3b49a0d40d4067e4c97d4ef02ac88f38419856241fbc958f1481670", + "9a307dbbbe1958679854b7449e63b731ce68c181407ca1f73ad7aaac61d74290", + "1363778ee3ca3f63fba3436e7addb11b46abe8afe1484871f7ec2483d409244e", + "2af093bceec929997bd4c28557893f4334a6f2b5156a0ba1f1435f4e0a27f5c8", + "867400ffac2db1397b358faeb9c7c55dfb9b867024c96b94234393d56b443d3a", + "34db2e56d73aa2b3cf8e79c3ad6c024a4aca5d39b79ff4ccc4a8f80034698cb1", + "3ac5c8f2c62dd9e0e0984c4790d4a14c4bca4de2bfe5881115ad48f7b96b4637", + "daa7928e8cd91bd577bc4bc7bbd497b9a0e12ea9762fc467e3c9fc793861af6e", + "1e91278e821f9b2b12522eac80c02a033e2532efe3d693f4b5efcb810994f382", + "5e3de69e7d83f6e35ac0dd1dadc0f45456f199db64944488587ee44c292234d4", + "8cf995905d2779a4b942d0626788890c1c4684ad10fa5571cc506643ca84a9db", + "9f57b56e6ae30ec731c4b8710021d9f975f308265bacdc347f8bdc721dd288f4", + "d02720113c5306ff24d047db094e0f4a585a13143cee4e4caf4ee72f447c6e6a", + "d2d17a40bdc97e7a22fe114c5e3fca32eeced9863366c418fdd4c4fd10da11ad", + "0aa8f87cef4d4c3902b66b1d6e5baf00791fb35dccef7d351c46e8bbb7542aca", + "f3813c722592b19de4b8f6d336263ac52db595d15e7287586ee6087c353ca29e", + "6ba5379f4a9a0bb59921262a37f93b046b48df8e895455b4af956f7578c8fa5c", + "7614dadab862251ff372a72ee684505d7077b3a30946ba8605d51f6b9d60055d", + "4727957dcedaac11e3cff8bb39e85a8ecd7d8480a357eb955f1c1eb57171d29b", + "7c22bdd223e89da3e4798c8d27400688375aded6b84f543b9abd4dfa111ee391", + "62a3dfb0db9b385764c7dfd6f4ae8446340a45c27e12b6449acebd83d987a6f5", + "af994f64b302d6fc0ce622a1e9d5580c5e01d2fdd1fd21f7b073ef623a75b82b", + "81d270ed5390dd9aa90a74786c822b3897d53686a62f9c7f2d27ad1f9a8865f0", + "cc6ea3804374e08cc8a22e9a8cbe9ec61e530be93e33c4816cbaf7b8d642c11f", + "5f27cf2b84feba46035c55c369b02390c31b8fd8151ca68c1432cb1ec382be32", + "28b37ba884a9d9e64385a6e766b65ed37830d4332ed1555ef79dd3eabcba01b9", + "b3de0d3bd75c446d6aeea3c611f522ae9384dd6debdf9a2398b23852186b4294", + "377a7f740aec220af7799ff1d4c57b6c9d8dfa3f6724ad360ac1da0f9f7f2880", + "4b2a543ed3ac36589ebfab53ffb2417e6e72129b86d9b39414bcd34679ab63e7", + "4d72d825b6dd78de5293d91bd96a838b4547374ff246195536036e9c28a0e835", + "4c09fd918eb8316ff5bedfc6c5069502ab45e740fd09d75cadb97068b85add75", + "15a587e53762886e7fdad11ed8cfbc478062f8dcb83f4ce7e3bbbad5cf545131", + "efee389ed2fa81fbe18ccdd03175678b8904521366e7b925e8707ab2c6bf67fa", + "0faef96302f950b3ec5f21f5a2ae411926ab40538c2eb5a5f312447c8f6ac38e", + "a099a94cd4a57c3773620d37b1f83ad361481ed563bca65cd7ad1fd01e1be1eb", + "d3f24f365e8c20c7ece99f7b328c0d16f016f7b10580a81f8a06eab7885f876d", + "139d7c47562995c7f8a912de2deed19dc579442b6648b6ad76dff2eeeb872c4f", + "69bc9a268b6805ed1ad791040e625a18a0a521022227f31dd02a74c4f6c4054f", + "abb40806e96f11b42f3448aef4a354da1074c50581117c853a64794f0ddbf1bf", + "ba62e3d536d8bc46875da2f74fd85f80a60be85dcec11da820fff08dc4ac470b", + "66ab70c2370990adb176d853d143b8e1116f22af6623c64e8ac8db83b03e3075", + "60ec98175cb79b731a4dee48fcd6e6b38924ee28d8e0d57faa68d83d8c186aaf", + "aecf3e3b17b3bc67f87f25b61517fae9a787108183aa4ea4a673a35042517ded", + "36bc2fa1a7e5bb7fe59566d39d70ffe4b2643a77ecea5decbb7fa115f5d4162d", + "cc44a7feecfe8169fa957ce4407c2aefe771057947bf6dc1908eed4a6c3f5579", + "3b1c8a3eec70cec664339578862223943d7cf155181b4a544b752b614d07ca86", + "fcea10b22dbd615a67a3ec9bb9b8d5eca1ea0d7eb6938ffdf6a54819f31627af", + "60d0b365398273bb1d7d3868a50e663ecb788e8b65f107dfc697f79c6797d903", + "c6578471d0be1437f553d3ac5c83274453d7d46888c0f321924f5a928937881f", + "f22808977fa5097ce2aef5bbb8bdb6fcdef029ac9ba745e9f3eeceabff1d1881", + "3138dd4f840dc80209b1c714839cefbf51c845cb2db5fc693f7c0546c7eb59ce", + "9674a3fddcf3bdc9dc6a75b434014fe69633ecbf27059e9ef4ae02ffa0bce01b", + "af6f208d32f84dd070add30738279437b24157609d4d6a87a6f4a4b4910b6c1d", + "5bdc707dac8b7f9185f35539c196dc3ef3779c99a6ee8fa0f450a5c006acb01a", + "d00dd2b6aa7b8f763ae4e5e66ad930b394c5df15f0296db48a71eb307614fd6e", + "ea99e9163bd5eed1e3e398e3c7ff1774c55c0c7d41719806222d0d30ead98c3e", + "a04849a82dc29069eb31adc10fb300065395ba901ce4c900dc11afab1e97fd29", + "c1344f2df551b54f2dddfaa4b0d1d0fa710d727b464966c85160074753be25fe", + "3d7f1597c479b19d2098a0b3d384d234704eb21d62781c26e1603487bd732d76", + "568aecd5b08f7989dd370dfa997905e704313ce4e2bbe12a756851e549cc195b", + "4afd1dab7d10f340ae8369a90714658ffbb362459c65d071d4a42955c0c06109", + "e015a2ff0031c99cc8bb0e23266e11200e1551739374a8ece78c51a4ed402d5c", + "2f43416f56dd4d1e644242a03dec87b768f2e341f8f0bd96f29eac75153ee975", + "d1b9be9a6845d125d664d17fb1cd09d09b40cdbcbf28f829f26e68c594dacac4", + "52ebba2e8bd5ad7bbdbd3b4c02501369d3d96d7328069323d92704e57561a8f0", + "314a26bc7f60657960d0f1815ba32fcdf3d791a6447a6f6c970f0c3427735c15", + "633c1a3d2e34a8b0c9aade42dc178c2b393a118bd5c4ffdeeca0957aede4a7fb", + "cd273a8ac92e4b35fbbb3ec665d93851cf5e8081133318fabe68ef9525ee949b", + "85aecbfe586afae5596dd34b1676dfac4a02d03d9de03c4c1f3a3724bc3e8f13", + "8cefeb895228483f85cc7b18f6550ddd780021202c6e44496d87798f13793ddc", + "b3a760b8d9a908410db45f9b3ba34acf66ce42ce157940dfd5e67afc5bc77ecd", + "9f74dae4b2367eb915a2a8157eb1b12b70a6ccc10cbeadab8c2656e7d7df44bd", + "547c523e010ce3cf66a8468ee318a427d0f133655403a8710f9c7bdf9f2cfe57", + "f9ddf21015cfd3ff5e19c78a86088c25e2461c262c74ee6bbb5f43daa93eb87f", + "078f47566f158e15feee80b3b14aab074700ee351ea011c159b25f516678ba58", + "196c9bc0736daff3662eca1c242e372729176e08214514587e619a384b002bfe", + "79c5f4616c31eb9a75e3b8c50cbd6ac84f4a41554d4c515474d96f135789633a", + "99af2a5d22499d3eaa863a632c706185973ba6cea97656ad81412f49eea24e92", + "3666f7bdee0683ff7077e61c9e149f16eb6edef639c409f1f7caaae88f72327f", + "03b6d0633d9e40ebeb7e9ae9e7649866b8a6c71c6b942a269682420a50290814", + "ffa6b3268ef11bae58f7ff80b094e23619b7cb96082541a9f6cfcbf5ab06c555", + "8bdbb3fc3e9e8315352d086d18fcf60deac1001ecfc6c52d32d70c2ed1ee11d5", + "070bb700c951bd6dc6ad23a0ef10df0062986fd5eb6e319af61e3e0794cda6af", + "f37eca4b153a9c6a0f3ae2d64b777d6a561f1d5fcef919de05bf33be3b8272eb", + "c275d87c6fef3172e4d7260c2be2909c2b06facd1ad1aea96f80227c4456a19e", + "ffd41dfb280121d02bc9fe360900f39065e413bc31438feae4857d1a102fd389", + "d565eb1299e9a818bbd6ca4047e3ac436009d87f05f7c389a53d03c7fe082d8f", + "763ce64bf7de31cd3becbe414f33c74d3e0ee913c3a1fee34b482151e0225959", + "a77c749d725e6e91199665ff8132bccbbb500453e57505f0b9f25106a071f2a9", + "cfb471108d764cbd3e3323eaf201020532cccdef86fea1d0127a0e437599e605", + "a9487421fe8a9cdb6cb56e5d2686bd6e198104a2abf823ca0782384657f4b42b", + "6922238c49908bc449e01822cecfa05d613b3989c377f05e08337f2f5bd4e843", + "e180c81b3982a31ba8c55765b3f66fa7be985f3bb35bdaed966c809883cff665", + "87badd764b833df13ca20e20b987be3259f0343454d2e5527f9fa6043074e61b", + "c8f8206f782d5e7de27975878bffe1accadc1eb53306293c41614755aae97be7", + "461f2d2f9dc3d3cd9db77f0349b655cd4ad463000a3f2295532638536ba22c03", + "4a18ff30a466ddf7113a5deae6b0317900d646dc28547dfaa81e665a263797e7", + "3ab3a78f39c1014d44dfc2edebec74e21b8a72af23cab9acd91bb8b4dc439904", + "92fd0d6ab533cb15bd1a05f194fb70899cf1b1fb66d454ce2d2cdbdf04a4001f", + "94af2d9be413c0fd37b9e6cf74771b22d189c41a5dfec736666899e06c094c35", + "3561de2eb66f569fdf50a1268bd88c16eb7f964bc98572ba4fea08c1b505bad0", + "69bb88bacc552fda94b65344535805df6520e7bb54f464d7b081cdea11acc656", + "6b49829dfb9fec1a532fb1b8a17d1baeb31ede0657ea738d0ef75be7c3cc2933", + "f115a30d8b17aaf9bebbf9410c52b788123e6e829058a0c4dd0a0e9dd0598e36", + "cd04f693b580dff8c1966c3337963f97a0f274598564f5a8dfa239f64a271bff", + "3416ff93a383993781f0b4d4bd746832eca246177ab6acc07732d6c9b8ca529d", + "e4b29c99a38c7ca4e683710f34e3dc5d37a09f84a31bf17f8c1162364a4ce613", + "c29b30b98246ec8c023045fa3157a2e688557ce39ae96a36e2d410b2bf25a64e", + "a318903b05edba6ecb7f07048dea21700e05f5a450eb5d08d1b22bda7596acec", + "6f20a8b280e42c54353069da7a5f50f163acadbbdaa0780de445c39d772d76b4", + "0e62ca5bafc149b0f0b7ccee3db8794b92c202b5b3b3f1e9df21fdaac08a7de5", + "3c0f203f26cd1ca3ecf070be06e404d42aa5daacbb8a29af0ed0c7963e13b9cd", + "629ded4888debc79d292622431cee86f82a77194b7154b50833c784e6bf57590", + "7a78d1fdeb3bfe39f6ed7d1b1c539f9158bac5c7a8794bda33ff9d43fafc1f8c", + "19052593fda1210bca42fc124dec1301b950833c16cb13da429d4f0b34e7853b", + "b7dbb9512dfe0cc5480328105f3bd669a936b5c1e06c6fc4852e48a2b4b2b56f", + "ad350f7c071197ef8478678354ef99bd6503eeafed5ec22dc3582d60da88378c", + "72f0e0ee37ee9e70d16fa2cb062a5cae1405b25f5734cc7cf3a692f940d9620f", + "843a7b698b0bae36fc4c80625eb40064ab80aef5d781b89ff74714a491f5236a", + "bca19a6c45ce3e5fbc06c91f68903381b640f89f2dcd76102d071c65780c0496", + "a84827c2fd86d285403eca26cc1c0ff65bb92be63cdf5c5cfdb27eb3aa3f182f", + "4ace3e17e6e0264e68e2e58aab02929e6ee4c54c4c2418bbcd55c753ade7e47c", + "e4637809712d5c18784010dc4dbf1f2700cd245e252c427eede26d87f1e67751", + "abb2e88eceb685d05809b6f5155f548e68d2d728226f9a46933fe914fc842f3e", + "99d7d3be6b94f86c27e208208f7f029eb5106636596f2b276dbc19bd725455cc", + "672e3cd5919dab84522fef66679e1c207a111ee0ebf85d72079020141b8ab3df", + "f8563d588e075da94b774e1a7ee3aec9ad70cfbc152805359bd4d32a922cf40f", + "4e8b299f8e4be1b760a8bf80058f5e60345a1a142c96247e7df6a9df42fbeb0e", + "144ef851c1a762bb2abc8260f89751e057bd4dee40865ac0f8433776c09f1501", + "10211508ca63ceeb42c38c4c5c29c975aeba30cc873b36505758c34ed98b5940", + "68e7759b40ea8bc71f3ca3b365ded5c9259defc62a9b5d26abd591967aea0a2d", + "c41c958039c1e46d859fee728d3e43d85498f32b786de0a7028e7d3f872e599b", + "ec07167ba87b1f3fc47aacbcfc8e56a08f6dd7ae4bb76d3c12410f6a6459dd69", + "272922d02692babaceb5748f5aad86c3df7ac8f6328aae91c99d240b6d16cc33", + "0367c7a232c1d9f9c0cb3ffb5ec34abe766f5805584e23c8de045ac92422fe42", + "e0ff572fe3654f4ad27041cb9c75bb1beae7d8ec27b3ae2ad92281dd103b0fab", + "005b8ab06923fe1ec5c43df298a570a4a3849bdedd2e00949d91b437f56768e4", + "d1dbc66b4477a54fe867ad6ae4464fc3b6f6f9926a938821bc30f729c483dea6", + "5dc284df96d2b38cddb01c95c24180167cec4ce32e3d78d93ad37ef09b746eb9", + "ecf5f0be3f83f55deb391a608bd6e156ba473763a7cbf962a7786ed9284a8f6a", + "3b94bebf0f3b762f5e13d9a2705b36bceac0692ee84d2238acde235b7ce63797", + "17d872dd310f69b9104ae608ae4af89c3c77eb9904fd7496c840b7b2a81a2f21", + "7902b2c36f026d2736e9ceb4d38f9473da2bc94ac3b8efbbfba6f48c68ade457", + "6f0f6a08b011c828af3f1239283b654fe0bd24f72a36fd1c9485939e7c7c9a62", + "4c156ca38cd06595fd7024498b36e3010a6eeacd7fdfa6f31d7434361fe65076", + "1c6d8e51287425dad9be4079c1c79d29da0b5ba177b7b988b4a4fde8ca6a51f9", + "5885a33c79762ce33f5eec2fc1da991fdd8480fdf8d5a929411588aa4f88fe04", + "6bc8a491152a0b9ff7c99db59ea1b95e8a2a1e7195cddc2a1f1a1983378c7292", + "7cef2ed42150429792bbe3841b065b4d3757eb07aa94970762c552d9c929d518", + "523735b50a9c32a9e8483c3b21bcbc935cbdf10699422a6e8245159d9075bfad", + "700ad16a8c5cebb4e51f9d4f1e342ab4277e74bb63f44c8f9ea826ef0b99a566", + "1a71c6ef51e3a6a1e6a380d0bb7b763f6914c8e5b7786b1a00b5939ba87afc83", + "d089f7c2ca67957364adf611ed35f355b6773c18d8ee60e3c5ecda771dc8dcc1", + "1970824f84c2dc4bf3e3b543077c03b065c3d16948f15d55a84608b876f036d4", + "5c13bc5d8e07658b590e522a28d30ca891ca9bfde25eb402bd4fa0d39d898c11", + "217fc1a965392ad909e701ca4d99b6fbc5c1a97acde59b383e713c72b5364e23", + "528528393a2633b4959144bef6f7c01bb0b8d4dd1c916503554069668a20c6cf", + "997cab3fa67a73aa4aa99660e1b720e1efb59fb3adda46ff0182d7c736008680", + "fbcb981ac6de7ee404ffaff362ccc0cfb13a19d1e2c5a990dae88b4d78d8a29c", + "6aa70aa54004dd462d2684c9853bcf51c7fcad604609e672584bc9c194befa5a", + "95ff6df51a3850ec568dcfacdfd34ddc409ee076ffb6c4a97bc0f79533d5e2f2", + "0faedfbec2b6fd0e73dbd2742a2308a05e6a2d340d9aa0456653ed65a62d2142", + "b78c536ab17f8110e6d469d03b3e469968901a86241d8e7e4e1bfe30d033c503", + "a4c13f111646974aca48ac7493e2c0a6ee204c2158f72527eb82617fc20e1419", + "0a901cb558b66aef16e47e0e2b927531f97ba01855d989b747be0d256c0e44f5", + "169817626a9d5fff8d25576cd048275060c330efbb71105e3df957e60d18c537", + "98fd69afdf93b2fda001ffe9c9e6a36819e8895189cb6eef200ef45b9809d7c4", + "d76f21e06e346fc5a8b0b487845bf057921cccb9d1c35e4cbdc0d7b2dcbdafab", + "ff6dc5c21336cb513725effd267de996e83f84261be90020efdc1614ee1b43c2", + "67329c25509b0037732bbec157ff26a9fe3be5d36ac86138371b3ca790f86547", + "0432fac2c2f24811c56a5823b29fbb53e99e226dd1118fca4831ab12b4aaf63a", + "acd5b2016544be26cdeb62f320861c12839a76aacfa55006f9d4b95ea9e11bda", + "a5203a0b9fd9d13c182b640f4cf9bb4eef522de82141fa52d2eecd5bef888ee7", + "7252ba3a1ea3906bad5262c70d5e97babbfc6ad0d52d07de6bb17b43f371a2bc", + "885f532cf4de2f01885699bee1456da4859be0a2505e515ef03ec75d7b3ba5e2", + "49fec994b1cddfb3038cf41681e6b2bd4b3fed76f2d486b6205629264b78bd37", + "6353beaacbef3d9343b663f45a591e69ab0273182213062dbe424f745e919439", + "d84e531bc507d0d88ad6c9461a26dfd2b996d2404806830474161d4351457acd", + "8f74f3b7ea598106c2dc199989b2917545ee306b36ae9d659e8b2828209ef488", + "b8c8fd7ffdd6e79dea74056ffb3898d38f9adcec2bcf789faed4b57f1755d955", + "8e2f3e29a7c7364d128a44584bf3473e72ac21200958931a3bb8e87cfa2e826f", + "55154f045aae7cf256de3c51fdb8ac9cbd59da5ef7349f52fd98286dfbd4d5a3", + "95a820fc35d942f3cd4e5540b5717622047a3ec887d2bd79be0c706c165b5204", + "62ab872f7b9c2c140d413886ff0ba3d97d208cb6ce563c4a98a38001c9dc55f8", + "05e47e76b2c21aa550caae4f9407f24ed4a867ffc660df90b413ffa7db598813", + "850aa1bba3ffc7cac5994afd5fe5ce5c8899ded3867a5a382449494abeb4bde8", + "7ae76cef112e9718732538411e8aed9d7449043145ccc253d5a6008e36346f7f", + "8c8815853b1b38f48fb6c775212f7d92e3ff82a1bc0dc3252b1c571a0836bf3f", + "d325c0efd63b7471797ee341b3c24a01645bf19a41b15c47a7f62f17106c966e", + "c3cceb78be94d0b8e8a73170985feb9ebc6897112cf7d0d049d92afc893174c9", + "4f81cbca9e7c5704519442a9bfea65e3866361b02b751707fd7b14e872f48a6f", + "a30471f11a255c41e79a6f1d8562071322dd1a8c87d0230fc5c44af30de11dd1", + "07c5b1e6c00c9467ae228a60737cf930d0ba8435c75213c36a656167a0c1d4a8", + "0228b9334cbcbaba692a558f5c92e14868eba9ac600c50c006d2957910876098", + "f8ae63b5de841636eccc043fa65ca6c02323ad83b5f94d0de7a9e7eeee6d63ce", + "a026fdcca1af372131e86a117f4e86f88fb032e044ede0be0bc3e0a3f505b8bb", + "682df645ae7c1daf56ced952d9c57fd6c2ea60e9989a841295d505907913b897", + "ba82f8bf9dfb681013aff6200f25115cb5ffc3f8d97065e0df9f8ba9c982f51e", + "d3fb58aa2cc9bbdc982fcbad57f2f93000dae844eec20a35385bd029a894526d", + "8e97a17fabc9c62b0f9847e646bec9c830a34ce256cf2c99548f1e22663c6556", + "a40fb2945dc2242dad9e24d2aadf1a2beaeb4eae699912b644da3c4df4bf7a98", + "c419559847ab86b5c8430361a294d221ca32ba1f9d22863bd8bcf6b24b57ec7d", + "b92a0be68aa5e573fc558e7c0876de30d64518dbc838f36b421bec30b11773cb", + "cdb2b3075d7be1dc97263188310ad721ccbb886ffe58968e8711e3ef5d76ce1a", + "5f124a4cdf3fcf8b85c66c7dd2ab2febafe74be99c197835cacba9df03f5eb95", + "ddfd9c3d87d0ae0dea8fb2034171ffd404dba30cba643f4ad93859a2ec7332e8", + "4a4aacb097d1041b65829e48e8434fab4cab4750989b28eb392604425b9544c8", + "d8407f9e12cd04197e9f2b66ac1b21e086cb334e1b437d60709a8a2e03eda8e2", + "3f7d5d14fd271bf8778da8248f525be3d72639c0a84e38119c3f27bf6a08b2da", + "7dd0eaaa7709147e7daa0b77f0ce04aca918133f38d02974e6a01d7a52a7193c", + "8b1b78bbeaa686d66943f5ed82709d5babd8d8c7981768956e9d74880b669db7", + "0ef56a9c1d0be7af25a31f9114108a9dd41416fd02d079f5d7a1238b04e0baf1", + "7eff8ad6302b788860ad7c99d91fafcf1928f5024066f000c493b365e3e222d8", + "ff64e6402a378d7d77362b082ddf41af581c0d273274436833ea393b6b3a8465", + "af179f2720b0ede6ea467480c34c4b749408d7695da04d505854e6f5df9fc29a", + "5b60cab4e3a5d9c08e2b5fb3a9664e634154959753337b2af73502d703ddae89", + "e5cf9f6fb03943d3f920eab08ea73a9c3f194e619fbaf90cf7ec987219e3e208", + "c02ea2da68f68f2bb5f8753458841bbe884e2c2138ef062475ee13fb08861473", + "ec620e9e56c475459ca9c54e8e2cea74e7ddaa4734950c16ff064f589f3715dd", + "bebdae0f3625ced97a13c18913794e7e3f3eb7f98173470896d4783346b4b572", + "1b06396678108c5b70e359fba7934439d68f3bc949c110c75e6d34973e2c6428", + "bcf7d9ef020e578eee2a3612b92ffb5f2b25f3eb7b519c285a08b5a0e75ec66b", + "15c0fd396c4d05fc76a34ed71937a97071be05ba915776e9eb8c61b48aaa3b13", + "50361c2cf916d54ac095be60ca67a3f33bcf18af56e58cebcbc6a34da7f1ce16", + "fb5ccf5c65eafc3531f282b757fb6cd82d38d47c54d0e016ead52ffe0100353f", + "1ca9ff4052e5184356b2826f01a5febdc48ce8c28a56e63cae2c2a25419a452a", + "8af6ab22fa457132ef5d3240a688732380c99e2bbf01dc384cb3c2d364ac703c", + "eb9d2c6c3e3c8735e07df16f0f46158b8e1d4055ff9a32641fe3d69a9b583585", + "26d9fb4e340c778d2a3cac4178ae4990c606e70087de441fa91e1f924c627426", + "3ab12a65616513b9193c48c1b9a3c971430931d5b1100f5bd3ef169b9e4bff39", + "6be7b00648404af0d6fd159f24fb26e41abd543180eef3b8e3d4cf2b3b07465f", + "8e935109fb5bb12386b9bcbe134485317ee1bec5317a08a460008a552083ba5f", + "e2de3e191903dbfa8e97d19554cf1f1324013b3b78507b1a85a477785d4fa288", + "deeeb647409c069791a5175f3cdbf6855bac6e527fdadd0c8bf7fc8ec1b20d18", + "d64fe4431877b8b64e14f92134ac8820317269b82d03210592a8e16d71d2a567", + "f88d0853a700cd1e8d0d8a89e8c56789cd74d5bcc4d95b3ef2b6052bb0008eac", + "b7f2230df719e32419c1aa1177d82b146b7f46e4b9a200e37a0a7716dc2060e0", + "55bd0e406f4cfaccbfd47b79f81eeaead53cbf5b5245bae9ef6d74797890648d", + "efd932dc411cb9448b099ca36c3182fedd1b1014e6364b308cc0ffffb9e3ffc4", + "0d98cb047eb03a4ad07ea929f796f72315ca50e2483348c5a7ec6c8b36104fe0", + "db4ebd696b22a73dcabeb53ed9373eaba941fb30ceeaf35c74e69ea13e70dfe5", + "ac8c85477c4f1fe701597f29b4d0405b92ceb2534888da50bdc2de96f367296b", + "84be2ea77928e53cc632353ccafa853cd68d1cd650ddf1464ec16986de627f31", + "4b1680bb03ecc09057060d8ff3dae03acd6492bc770de379ce28ba2bdf21151b", + "3e620f939ed23c9bf856a4b7233f363efe77e7ec1bcaa557f646c2373ce76bdf", + "e9681c49149f42fa0686b8483adb926725ba5ac80ac6e7a2e6b5fa36b95196df", + "1bfad941f81421892d377a74c8eecf93c68d9adcb0dee06bb0fc105961f8104a", + "43076a56c167c939f0b9ea0c7f882f71c115dc0633bb7f66b8d1f0e5778472f3", + "9e6034b44cd8ef0e27b0e173858ea1b97d2410ec905af233fdce3dfc27adf361", + "dac455275049288a02ddd01b36205a543907e3154a5d42d039f16ff811a41661", + "6d5d6aebf9dd78ada1dff0e613850a4a8c27e717ddd53fb0ade603ed2d6f3195", + "76675dbcbaf5e462a0c41e0fe95bc1d31044da0ad8a25d6d470d7fb4388afe1a", + "2f8dbf40c9aae963e86ad3701ca13be3d65320daacb800d102090e7b31ca2ecd", + "4d892e50e4340280236b827e7842fda4f1e48f4067e3e99fd17866b3777431e5", + "85041bd3faa7875a81a288a3692eef178b9c6de0672a87569101b0f226aae64e", + "0df57da8366e33783f546a476feabe5dd4ab151db31ec2639c6578f3a2a749f5", + "5a9339c40746639efe3d26515ed0fbfcaaf0657ce9a2ade29816fb258e9cc777", + "affff876a017aeb6ebe5420a979b54ebd62b1231f83a1a3246f64b645997f1fc", + "865c5a55bf026d6ed12a8aeb86de6e12f323776fe76456ed49bf8f8b75470832", + "d44a3018df8a6d70c03fff0f8b2a12c0f6c25a86591d42e212cb12b0d888162e", + "e38e7e7be443c5bc7138b66f3887fe00232c530661be14fd26606ffddb80217b", + "d93496c7f102875fb75106d2faecf60270457469e0c9605edf26530089a3136d", + "fdd3f4bf6420e0098ed25183e4700b144749f3d51e1b9d94ff604839af2b7550", + "8ec55243ff9e40501271c087a88fd61f3201f864207dc36ac11bef44d06074af", + "3e1cf049c7d3d05401ba3dc33b8e782ba3841690a19dd813773eaa3d2e8a760b", + "2d1fc45ea94220fa731b4a8292f8e666cb4bd9234ac83c7d174112e79bf540e6", + "3ec063c0fdbfe601a6add34215cd8f1ea81d2328f934561fa9bcd71ffca6a4e0", + "0eb7efaf1d224433e0876c32b987a22e0304043494349e738e69e330c89e54a4", + "2d562f877246482a78272112a1ab718a0424c9aeb69fc899c81129120e19a62d", + "9ed25773847ebca2909a4d26c71b590e29b0d4af7b6dbcabb9a9effcf2089373", + "81117d497c3fece839919639ba25032418223e8200eee384c6a3c476a97407fe", + "461cd3aaaf86fed61719a8cb3f1418cfb51d1f11b0a8e7631e0cb0994e448221", + "94981c93c3eb1e5fb5c93b897bb409ed4d22719bcdb011d6e8191d389ed59e67", + "535a15df62214f850616f64c5845d29b4e6f3938b23d0845392531727034fd55", + "dff7f4d99f2e2cf7092fbca505589054f9c7b43c43aab042965d6451e6fcb930", + "4b5179aceb6ccbdec05d92e0fa416755085ed234680804a011f3206c7e84c919", + "96a6138d8d665043e18401fcd05e8e353b731d5efec387c4049e5ab38f0db0bf", + "c6004aa61ff6c0effb7ecfddb973161feb7e4ac8a9ce895870f337bc9869ea79", + "a4cd57cb3088833777164b85283f62452de80023bd310521fa3cecb7a0b12508", + "8318e981808e1386cdf21083962612303aa77abec726221728e23523fd572383", + "b1611c4f7b1ad50dccddf36be8a10a075abd3b1223acb1de975fb59c4c1f0b24", + "087994d295dc0f953878a678fe0563e0f6bf6a8af856c9e95704486be2403d0b", + "42ec59402782ba7968fa7486427cf17d0e4333ba31c8149b4e25807991f2bde3", + "ffc1096f8ce73ad48119402174ea5d50c0fcb4e853698a5ccf811967ae8cbb83", + "f7e4ef85fe402589f6b1bacd74cdb7001b77aee37410a131c57e982902267de9", + "93d92595565464079c209f4f4d4904dd19140d18804f6fcaf9f568e84a94b928", + "ca1e42702e1efb0f9e2d43257c1a492acf1adc538080bf89dbcf521ea020e492", + "adaafe1500c081b0a117afb13290fe9a69b6da86eee1a9172c23415e84fcfd86", + "5269ca0d77dd83039270e26bb43ea99b15a7420c5b0647bf9296254590520aea", + "647fafef2e2e3a6b043b95889fbce89f539da94599c49384634e9fb9246e60bf", + "b9df26bf94fbc65360337796a07dfd3a590aa0ec6ef6b7fcc186d1287fa7020d", + "3fefe2c2a0420fd663f47500cba4167a54331d136633a4fd69e17446f0dcf2a6", + "773ad5a37448bc5997dc3eeb472b4455cffa1532785baa5782607e7c2d2509ad", + "a02b3b935767e00cc892fdcb9b0952c8e4e70e2f2c228651bdfc6a09dd2c01cd", + "61e97358842b4509260ffabaa14a03a02a88ab222010919041bfcb1949a29a8d", + "4c8f98ea372fd9628fdb5e182093c880bc202d77b17378b267c04918fb9cf5a8", + "307b4953ac2c0f87c3728637b3bf5b3af194af9d3fc5d9adda504591af5be46c", + "add62f3f9d516ab6720ebea6847adf3025a3d44e8d1f966b1dff0d35461c8f6d", + "00b09b2f33fd276dbf8bae51e4f6485f0f297764e4c6083a074281604f65feac", + "d2b33858d91c2c71fe4c5588deecb4983a7d519d82d5f27a74ecd817fc210220", + "dd91dcfc9e3637eb3361e0aac8329fc5d0dfac07c6d275b9cf4d67141bbdf603", + "24a0ab77f92e40235fd3b838919ee4c9ad804a34e85c1183471043bbc2ed96f1", + "cce99e577c052544f2c5b8a9d8378b875ec9a08c64b3798414e709eb81eb3d8f", + "935b495cffe5fd43fd779b9f412d522865bc1bc656e246f87628cee7c4949b91", + "e40f438f50cf0e47766faae7ed04b62490e8898a19e5384c1c5ef41c8a8ecbc0", + "8b827b172ac086e324254c148bcf3f58796856c3da361fb067f7da7f5fe75cb3", + "dbdb1adf7f86eae7b516fbecf4c8b7ea4f066d7379d07217bcd937fc5a90ca39", + "9602ad307554d1336bee328916cda417d42eb67a24f49737578e35325876e48d", + "c793384aab22a032907e9831fca3a66c9697241857b0cfcd860bd49a2e0241ec", + "d4cd303c1bed2ff1b0cb04a673d5e040750a3cc1627438f206807da09845bfe6", + "cf322de35bcd5338bec688c4544a817447ce0a1ca9179cc504246f719b6f3ed2", + "a4c37e4a548b546f9c82d4fdd9a93f9085e8a3be36400a3f56c1aa65692d4db1", + "37adb12794dce5d05b38233398e4848b07acfd3a899572e42b037484a6a7e43b", + "e5c734d1e2c6b68e39c075d69557f89acb7918bbf10d193316c54072df898689", + "f960625ba69deefa976054b13b91e92dccea72943d3acf88d02a0cd9e720059e", + "9b2f9d2fc7e0fee5ee241cf0c7c81ec500ff7e5d5f1196389bc67ab5163d1b30", + "471128a8ba74fe7b63dc84142f75b8b84cc01296d75d06780d936647df72ecf7", + "3a7a96406da9b75ba99433579be4fe9f86e6347bdf48f02e64f064dcb6a98d5d", + "3289a0f64802be715330936ec27eb65461cd7b08235d603393ff569c0b9486c3", + "818f53a8280b707350f2e55ad8e80d3e23092c0fd40ecba7ec95b311afa7e618", + "03a5454aa88edc671eb3bd460bfc9e314c7e983792bb1ac0e11ba69e318b7bf0", + "38ed78a0c335e7f0ee8458ae8dddb894ebb2102c3ee4992809c84a2a1580b3b6", + "4065009ac70a8ac1681752ee2b17efae79d4550f356cd27069625fbc02a199aa", + "d2f525587608b6d3b8cdecfaa005f77c7f81af82da545df467faa2206d6996cc", + "45411beb2de4dd73bd6a0214ea0bdc0fba82f0fe89f5fbca8789863562f76020", + "6a134a69ff386f6a5fb12dea53de56984a2837eb67a041743a2563e09220d841", + "e734d025e0d78551af57e6d936d0b345823315f7e8f0140eb3908a04fc2dfddf", + "b45a8c6923cd6535f7dca3fe94ef59c9a810259f8a3afa95cf5950d247d2f7ac", + "9e0905af0001b87e83b2f3761fa31bad5e301616ed8236f7eaff9566b182b487", + "0ccf7e507e5bb588fc867e6641b114d2a36a720bea12829800d1464ab83466cf", + "97414573f282fab7f6e7deb2e55c997cbff60f7f0cab3c9dc8e607b86e080933", + "9cc433d714350a766151e29c790184b86f440efd0afec897182b7b330f464f97", + "25efa6c6c415ceef091b91c285ab37fd0de03fb8f3e5e66a78fa0c45cc688465", + "ce2c40ea3c2bf65d5ca032505681aaff210bf293d245796259ba4907f36559e8", + "0a927d0f484b9c13675616c935329b15d1d01544c540f50d7ea9263dd020b1ef", + "c1f46a49ff147427d7353064f53a45c1c7d922b907b225f6886a7227eeb619c1", + "a919df8ffa895c6c5c2a110d8f6f282b7ef98f9f776d043bfef6f2abfff912f9", + "678d58687541b8d46521c9c706fe6d4fb761a91e29c848695abc93ab2ef9ce91", + "c2e2650c61b0a9157d6d76e37a91eca6d8d2e20706e7c770d5634d8bddfae54f", + "94978322b5c33678e416b01aabbb0a0746dfd051586f3596d44cc9b7420fac42", + "41fa1bd648f7bbb47cf87bad0f708a65965bb76e295472eb20699005d810636b", + "d3c232eb86e03f86290066e86c94a234307583ed4d0eccdfe5039415308cbafc", + "f132349c781536c95d7b9ac4c39b7a65c04b590f946193c9b24b318e3dde50f3", + "8db5f6f7719352ea947c42da59b4e5158f3f3f4feefefeab292225ea68153ea5", + "5b9f280d33b1d2d03fa589ced276436044791c414a12bd930b5eb9af45a26ad2", + "bb82daf9cc0fb42372b0c847dffb33baee6ad6be45e53ccc2c212b25ab82d389", + "43ef268b8836fc4d5929d3cb129127973bcdd62197f03ffffe8bcf586dec9134", + "d0712d807b864f6d89ecc669818abfd87d297303282d6caed61c965091efad2b", + "7d0d18ae19785aeb7dcb705c51dded96a753b802a0bc27dcef9dcf4593fbdfb5", + "0e441972e0088347b444893990a786d8dbbbabdcce7bc944be90bdf2a2724e34", + "3bb0f78072a4508ef8b527130a3bf57b134d6ef2e45b1f96edb35200ea03b028", + "9aad7e0399171b8b42d3d2b8e8187e1da05e1d01b55e118ed6396eadb3b4bc4e", + "68a73ba75f5b44500e9f76d653101b1331bb0abb31f43935e0611a36aed45610", + "ba885c97a59b15f1c7103d3442e063f4239310a51cf380549618067c2ffb85cb", + "e915ab39b275789a03b9efe81fef46d1ee0f77a89e0b1e06574e39a290d9038a", + "3330e721cac068d465ef822e2ca916d0c5bc46ee20451150c1658ad5471e06d9", + "218454841a523d67d3b0904f6d0484f5101ce23298af31ab3d9a9ece83e23e77", + "4fdb30dda1d5e83a97b99b96e20a6c9ab19337ba522b688957ba9b32b41f9489", + "2d4b6886c9f1b8d3d44c7dfd97f4487fac8f7a912d9201bfad0ee8d4faa0d7a0", + "233bd8945e74877fcd3ef7d04d0032f52820a782d231784d8648d7b997d19e05", + "38b8093f4827c188dce98501ffc1a73e81a990ca8bec472cf3f2a25c5d1e505d", + "5fcd70514db4c36bec998a23c0118abef0ae5fc9eb437d399282d7168056c7c8", + "9b39bfe4d5f3e751a73563a1939370220085c19c20aa5b86339537b0396400e4", + "0d93a67e9287fed5c87874bc6b85eee144aa2b3654057267a90bfd647448c82a", + "b9cbfdab135c300bc8fd661c9f266798956dc8726aa33cd200e6c8788bb62928", + "5660a048857f75877615f0f5ab157441fac14eb5c15c976fb2494e5dd824d80b", + "60ea48f790fe2fa86e5f219449787a1bf47a6453ed98bdb6e2347e019add21ba", + "41a152d085b41f3a2d5c8d0e31e0f61c0d5d88d7e670b784fb65ab43105b44cd", + "5e9f1c1539d57d38bc2c4b9252bf28b48e67c8c56108533591f76849ccb3c104", + "8fa1c678ab4038bd666195efbe454f359e0131bc53b420969ec0cbf4a0a0144a", + "44801c81c222f60a54f6aec7f1f0faacbdadff6ff8ec23f3d676ae1adf48ee76", + "15c7e0c531f8574698ec5c220bd334abad452bd343acb04a6506e2572dfcf869", + "6a2a516b5c9615d3e3fc66f8b022e25ef3bbfa2eb4f75b3cc266580a65045025", + "3dc1100f684708a519817f2ef9c692b2915fd8d505f3a65fddf26917a2c841b2", + "2c46b8bbfd9769183c8c0571338dc6f3cbb6a425092de82fbf3b15789c73349f", + "db31b154914ad97a6f2574965bf49f449e05fd67f3fca2ada9bc9857ac291d7a", + "735b77d3cea315d9d992db9a7bd3adcf27850aa6d2e581acd7feb087c41ff64e", + "ee31a30594e0030462e44eb4d268b477ba46a42e3165ce795f6a27161eeba9df", + "9df844d32ef2fa4f4fd35d23deeaec9096643a3cf1907645b36eabbd4f5c9ac3", + "91da87a4cd917993dab5f6ef73102c0bb2bff008a635ed69c4747337d5646344", + "17edfb8518bc26c4251c2e56a10dbbf9971787e392e10a85c10e7afda7cf84e0", + "b7b750e218229696cf8c6b1c50beba6dd430a276f89b190c992eb269d6a36834", + "9b44393989604db358d748fad4024b248b51f043ff64dcff5f3ae31e23dc8dc7", + "dbc35e7c6b49351777936a7876ad9e00a27494f3fb6792975ec3799e204f1eb4", + "7ed0fc2192fdf05f40a05d568fac1c4cdd7ed82779185ef970d10b1a2e112c3c", + "1abeb6eb4ddc5854118b0573a3e1f77a7555ae54b165983b2dae14ceb2ff7697", + "cb73f199a333059ff2de8351aa2ba85bbcf8966bbb05b31bc0002c6f7682f0dc", + "2f9edaa7aab91eee7315cd4511f0e3c8892c62ff4612f4412e5473df559fbcc9", + "b4217f4ed6e0a9e6ec68d226aa951f99b6ed5255b0ee73101ee3e67023c8837f", + "d62f58c6272ca833c602dbe07c57a87466ea8c87f20f40e6189a4f4d140d2ab3", + "d533f612678a098343ecfcf1f031b5ee2981abe6e272259f9d973d8b6e0bc645", + "72440814713ec42b4616ad132fae259afca7fc027d588cf8193b987217768a44", + "8a89dfa334a59a27b4c3275d0c8d9183b50a31e2017455e63632eb6cb19d9a85", + "6a2a3462cfed333ca0cf9e7943bf6b52e5cd72959d228ced38571395fcc0ee97", + "73974434524b7ae02f13df797e65e81ed2739a0cb593f0a0e6241be8875d7f10", + "ea2cec482a70618e3f6ce2bba3e7a4024462cd23e187b6b9fc00e336911e1b1f", + "bbdb67be61dfea50c2f34323d3f42f64e507cfdb4076a3f6e49b390bb3ec7d37", + "02d611380c1a23782c6c44d82f59885d83f326b4179f064f81a818c21f4c0e1b", + "58a2b1788f766735c45319d99dc3b9d0f0940d2e621ea799c2b335fe4bb789c2", + "8c6dc3d9a3b1837c0041ed689de1297cc2f194fee0ec5e1b8aafb4ae066e53d5", + "5e3dbb8ece678f8dbf7b39aea3c2158c764c1cb865ca18b944c82a3d0fd3c40f", + "443e7d834c63c5f6651b465401adf2e3abb4565658a839d97c05fc3fa7013cd5", + "488323c7fa23f925cd6afd884795d5c17975830776e27248da72b60d579cd32f", + "d232f625c9e7d6e113fba8a95126c3855e1d3103ae29b9a20be9053e03f9bde4", + "cbe7e2da8c820584618c7d24e61780b9dced84aa3a9e699c1159f65e78e2e5ec", + "3b213e231275758a6f819ed5106bef5e7bf7e7bb426e8f5fafd580f198cc5730", + "235aebbbf5746865dd22ce8c856276d768324cb6779aa752d73dd049bcf46bae", + "0bf5b2df9cea7c85ae5d472de913bd9231389d0be5caf0e355fcb68a12d2e365", + "243aae2ed98ff2792753c89f6e3c5877ecf8412f8dcb3c64a6247aadb9920f4d", + "039b5138173211015df375c59417c56dcfbc3f5ee6bf15876444009441d5b078", + "aa949a6792364eb32138e270710d1c9104c299975ac2f7f38857dcaceac57118", + "43e7ea779717fff7b2fb52c59f404779e9844903dbebc08aa833460d236f9d6c", + "d0b00a9eea1b8149cd36f3160c7baf1b0d75f5ba2ae72a98b73c9751f5aef8ff", + "65e47fe603c6faeb3e1928e75cbe35572d33b567f2f4401859fabe82651c2032", + "44126fd1820fbe9132520aceb54ce347e3ded7c65ad01bd7f9fd0d3340c8df78", + "4bc384911c70c62d65241f50ceb11947b0144197f7914830adc707a23b283c51", + "c6ccaee733af0ea0873fc2043406b04e7686921fd60a1b76b0fa1b0f93a223fc", + "579ba58e259b68274036ea3309e4e9f6208df0d3f578a83a9d3d48d921c403f3", + "681cc7453d8414a6940c57ea256920f6f82742666b67906f794af5d9c1ec5b4b", + "04ba8e1721acfa60658833fe4567b91a20301d4fa62b181adca0effedc55fe94", + "9c63688d90dc1374d7b3e87f940ba4b815f0951fcf0b6d282b226b1609f84438", + "7eae3398b76ce91a09675138f63fd65352a38da60c97bf2858d87682603aab6e", + "f50b5766e3d6d1eba27c39bc0e9402ec08456669b9efad77b8028b1cd203fbc1", + "b0c55e506ecb404f78de91a00f4834675e0ed6b3c257da461549eef823ab86fe", + "b8b76d4d44a33c2892d828ce3c6d3733c789f5971a0e0dfba11b485789c043e7", + "8306cb26986e7c39cb92827f7086f50dac21e50a17c5869cd6a58acb204998cd", + "ab778b8f6c048100f4acbc284b107d248b226e20ed9945956fc213005daca54e", + "41b7fa996960522112da6ea663919c3e85b94bb51381c0caff399ca4cdca20da", + "a63dfe3326adc40eac5c6202a73fe92fdd120c7df94b7ab3bb58b50d2e86d280", + "8c8a55f51daa8aff5cfd5a3a517d6de49d4240df79f5c7ce7661dc8d7d08fec9", + "abab3b99d4a34d0149167afde8c7ad2459f545728d66e0be0972c37741a1a68b", + "6d88b50490e84b9750423ca2cfa193d58d4b626347676fe2a236d6d7a0084f74", + "b8136d85ae42fd5172b3dbaa7369bb5e60ee011e8080efe766e2c9b5b484bca2", + "6db4c19513da21bc4183dae9d16c48047e10a89828cace0b33eb2c4491c934d0", + "055d21e96036befc1016284936712b0bcf289b17637de6ebdab35cfc7a6aa63f", + "be69338ed091963bd5469f38e06416764be12a396d9d94d7c7dd09e3fb53e63f", + "208e9313dbaa7c5a71a9eb21405ea730cf3bd77e8a6ab06fecccd624f30d4e27", + "ec7c9911426d7a0884fc57510941b23da25fe513a09599cf2b4c67b93f994acd", + "8972c99fcf5097e74c075637c87a69f733aced4d79d7e08a2b76afdc352833bf", + "844cf3da7a0def3c215f0f9387032fb720e287751daf43a87888828b2dc92336", + "8acfc98384a5f0ab0a7abc89ab82763ccf592ded4d9980ac89f3f983f81961ae", + "6c046f38c2c809a65e2d90147e7f095ec4f6565b3b002f44d9bf404a03efed70", + "6f89e732907168ece12afb6f01c5915b408ae801d14cdea5018d9e7ef6f2e620", + "0efe63dc15207e131c3990734a73a48edd866d4b212df596fc8519c73b9a1018", + "d4811b9f75adf8c39aca96225e5a9881a45bcb3b6b73b450cd143f6e00e3a34b", + "1865785a0b5c7739a4c6ba238414180c223d5d4ab31b3f87dea5cbfdcc44e86b", + "33a96c4cf6ae989bd1d85933e3a0b9914d934d481b162243d6d87cdd74265fe3", + "407b299539a9c9b215ae3f3b5d4ca5572a2f9825b5e7157bc36d9084470a5ef7", + "0fbf3a73505b390dfb6a7fa6cd721447ed0d7bdabc1525a66a7605eb45851b45", + "6f92a523422987cf5cbd88fe0a0a7867f5704062970b8211c5326297019cb6d1", + "5bb8a710618e5e9432148c7eaec1e650c03540d32427ebac1073ae9f8482c65f", + "59b18c9582cbb91e1f132e1328471659e5492265f0c44cc23d3b5573cde9fa93", + "10c9d92e0c37d9b5901b0f4ba0fe1fbc4a0e62ea3b49405c2bdb9ec7e2d79634", + "7e299985fd2837bdb80ce01f5ba4c52f8a560da411ab9365bf8bb045d2a74d9c", + "4d992b70d596eb2b9d8309870f963cfffbba63a6f280aa0d4547aa027b273f06", + "00619378e5374e68d496c27ecc6e15d79d7a4dce92491a1d02917053b6721a46", + "ed69d2519429f85afcedf5424838f3fffa731b8298b6fec633bf9f4cfc0e0541", + "40b0dbacb50aa30589a96cda8d07f55e9f5122f1ab46a6d994b58a055dfdde3c", + "10b21eeb9897f4efdcbe6b6240216beefd73268af2b809b6c663c9fd314cf8d2", + "8a7050bda8745e77710e42db62cfc6dec0303382de063a6dfc1084b388d73927", + "928c19f9bd4cc378a45aafdc56b4e33b8c96cce5723635ef1cd098dce56563f2", + "9547026ce0d8a14f628888ea694a5042d64250ab95c9fb3ff9d88b06dcff8a35", + "6a06ef8d4d4fb98eb13a7a724eea15c667fed2a783ebdc8c7a1fbde3107aef32", + "34326c95b5e9aa67392a322fa11a4df81c7a5cc14397bb71f55d05cfc66e2fa4", + "db23bf92a8aee034cd66d61c96bbbc14afb3ba04db5883f7a5b35d40a6230135", + "a0c9cc6b11532d0640e33125ab08784c40b6721ccc0ed75542bdad448a0d8963", + "49f3cfdd53872f8304ce3ee748417ac4534118ffa7cda095fb6079f5ae7f4abc", + "3361574713d46a740d0fa8bb08c9a19311eba5d3c4f5b6845cfb471b661b4e90", + "72754674c701f7a0885a115e6f6fb81dcd0aa23b453a07a8d2e3d595aeceac03", + "c176050e98e39dbf220af713256a278eb9c4655dd213632d1587a76707da224c", + "659e0543ac4e67d4192d9bb0272c3d8a6398bff10ee7552aa818770a5cbc020a", + "07185ce62859967c873fb8eb1c90af4c4301853dac77c2cbdcb2bd8286ec2bb2", + "7c8f801163b9d8306ae3054020052d7930eab76ca061a365b537a439a4849e4f", + "3b80c7322a4105f123a95197f846f78a76e748fd05f30e691c7697fcd2390507", + "a18d331329618295a7468e39923eb3e4d3785e416acbfd3cd63a2bbabb8f1d1b", + "c54e6bc314dfd2fe99ba54fef4f5d7ac1b14dfa9f99a53d815fff822df9dab42", + "c1524508b54f67850972a0e7038817fe73f11fb52bc7eb6155404aec076ac373", + "4bd06eddc684916e9ebc0f8a60691738f35e261c91b69dfdd1144c66bb7a5d27", + "1bcd4a06e3d79d7e2ff3fd368c0d4daf8001f4d13ac559bffc2b618355d6f561", + "0f516b0b7d13aa8abb5b9f2967a66f437f5277634b2805a552d588446167c053", + "d313ee0b7c92f36b099e92d11052b13fc332a7687ec263a9ee1a7ea9db58f0eb", + "86c6ef26e77141407c2d2e72e98848702ad56deb33aad59f65d96e1ccbc1d7ee", + "c51325c9f699cbe12d8b1d3256010f28468f4d16e0d2a5c9d5b0f3d421fc328a", + "3fdedcf1fc99949569fe642d9aefe0ea9db45909696ee6e5cdb13da9bc7dcd52", + "ba6e3310767bdbec0cbcf2e3ea3b7128e72d8d57943493be8239ad6c0e7bb79d", + "b8fe52fc5ce5bb361c1b52a61fa2735b2ae55a53dbf2a2d235085ac49c840f06", + "1ec3ea39276dfbec140e51ad40de27635372453717fb11d8b4e53ad8615478c9", + "faaf2431bb0e526c607d79877003da744ffefcff30f7e3cbcb0ee9ded53ef8cc", + "70ae24a5dee404b485ca07b3f65299c5c6ee6f5644ce3031561ec650e544c0b1", + "daeb45b2662b807ad37574ea9e6e1ca616700fa624264d97a87b5af4636856a9", + "015d99384e8875a7bb65fe07f7baabdd985e06ed2db014cf0b3e6d0606f79308", + "e26ec9a1f0f6218e97bbe0ca7e2821c9fe55af34b3ab8d4f8a5749ccf2a6173c", + "0d1ebf5eafd0641076dcc38132f9af5acba30c5ebb02c5139da91583fbcfbc79", + "adfc95df6f05ca45f09d48f44673e5d42845745c049e0ea4d0a219ab61034c37", + "75839b0c0f2fb20d4ff7e3b51271471676c991ffa58e3a4167c4d530b78e0a13", + "d61659689189c494f521dd97fbd37685633fc8b3b87930407266eba759314142", + "fa2c34b9fe021d7670dc01954471ee9ec9ac3d6eec947805d979cd430bbe094a", + "a0f4ec7b3fd1eddb9c12446760220693f42ac855cdcee5cc5f597ca55fa45f47", + "58b4782b6fd4510a93d4e3ed6f4e5041c34be9c5781846822ede0293107c068e", + "fd07a1a597b953dde4b695a22e9e96d83954c4bb62f348ce483894d75e6736b3", + "783a9a78f17fe938d849ee289a89d7f0b07604497d9b6109bee1da6b17a6a8e1", + "ec19aeda29e828b39d871752fc4ad5eabbbddfca876e814f2e2fb715a3a355a2", + "f4a4cbbfb0b0b2c27d319bc4c645c80bd3665f8d295c6f27158c572992ea9b17", + "faa6ce3550ac3327a6041d0b4b5e27c6f68746865dff7fd29a7d9bdf4b60b44a", + "8b8b428be0a8c4153b49353a4166d0fdfbec8afe3ae83cf506698d981c9e0baa", + "33af30aa92de59e6cc46162d6292aba4197ed96ef26b59d6e62b0e0ccb7f1606", + "6beef2b4302f64c40a63df4880dc796bba12ad33b6193e88eb851a4ee641c0d1", + "ffcf6d9b1d2d5a4be99fc84525484ec8d939ac14cbee96421fe6cdffde8e64ef", + "e8c387af188d54187a21c574ac0eb16407bb0d0031fbcec7c3b81f55be4f8c6a", + "026e4e7d88086fae01a0482d923787f1eadf18edb7673591a05423e54ec0fc91", + "fd88bb0546680efc88bbbe75020f43a877652cc1b428cec3ba398c031ffcda99", + "4a82458458c25779206cf5a97e22e0994d7df5bde42ad37ca7b7e468806e10cf", + "1989485111f696ae66a54cb7363fb655cd87084fa15a083fc3c42a29612961e0", + "2e9ba91660f3cb7d2522c7bd12db15dda5bb73cd2213665324e2dcd773cda7b4", + "5029900de9dbc36665876247fb5fa4c8724e40bc2a04e84925834408781fc87b", + "7a0ca5cb0e3fadaa3d4f244caba197d552aa7c12006505f7111febe81b60972a", + "ac98e83e785dfc296646830403769f9f64b6e0076c8e4a174109d02576b8d066", + "ebf241b3137166d8a551a5ea9901422e2eb91687525025fd0ae7030e313f0e58", + "648b7fc28b0d497a9a7087a80f1f0017d568e07f791f1702c391686bb6f46aa3", + "267203b8c52f32fc2bd6440bd846cd445c220a4e7b41182b8d8d5f80a8f7dce8", + "b9c87d90397e4327cecbde1bc26f2b77ac467d8cd9511ea055fbb3fe11f965a1", + "f091020cc9841d210600f5a6e79085a6f11410990e991a7115b5d9d687e776db", + "d2fc89772d21b7d2f7993efc63db0a9e2fe474f1c90a8a96d65fbcd906e7061f", + "2039271a99c18dec5a494f0b65f60db7744130c9f44ef468490f52d0819f2b01", + "763fe29f4228adb293a7cf23552f066d65a80383e410136637b69e9a1fa11312", + "b16913071389540b9a4e0a94557fcd2ecfeca8f85831c636f08eeade7a8bc5ff", + "0953fa09f5b218a02c1a961a2e29379af7da8cf70867870d48b3d0f7fad34664", + "068ec35f35cd99f63811db99ccd6c1f33ce2e73e2e1c060bd3ad633edc4ce2a2", + "1218aa61cbbba9a0a4acbb557752562c9da0c7de3f30e8f7b11123b4f08b6495", + "c4cbc4bb82d0cd40ba46aee279e7de9462a3ee5cb265616e878e7b0b327971bc", + "09b9e55a8b300a40a928ca087089d587f39079efb904e3d7dd91410381f305aa", + "fa26d859983dd1f08bc181766ebcd8b04bb317a2be15b712b2b0eebede5de52e", + "99af176f439fdd0423b980d143f264cfc0c29ec65c25afc8bfdfb5598f500dde", + "3fcf6a02519b256e8d69bd576206583db38a0f716dfe042864d748efe1ab9fd2", + "b7f18438c512369aa77c3ee373cd7c907d616c97e93113b7cf7e63831138bce4", + "becbd2da5a15a8d56538ed8f0766a4a30a72b7bd68aad2fca59a5ff243860674", + "9307a5e88af2a7f354e949e00ac83822ce3cad00326bd967a4c17fbe99cbb6a9", + "35e4d221298fc9f95f2dcd8ff8e129d88ebe72afa9882966c53dec7f5de2b045", + "476d716fe4af7f4c8be5060ee7ff24caa8f15e993824ab4bf49a9060054fef56", + "ea5c9ad82c2fd62b018f528a239eacac269ecfe52995acad03ef30963b9179e5", + "19a81a400fc8d92631469522924256cd2acc2f0ed686d01299a27b006f29ad8b", + "8d65abb1ad896ae8ace3486d1cc135ecc285ae7a2ff8cc6286d12d11781f8e3c", + "b25600bf929f9911102dd1887874fbde96ee3fb5dd8ee552e2d97a2c216110b0", + "c89b5bc16870624f48917bc56d46bb991c5c721e8dc6162a5e5c553cdfe8e1e3", + "08680e0b4b9c9d814e0757d11425d5969325be6e477e00595d37fab0e5275eb6", + "591f2870d01c1a5beb031aa394801734eedab96f95a9bde4beea43bb1ba0311f", + "ecc94cf4ad2af549e301741b3ad74b1ade78b6ba6bc12dc41a70fb9c40a7cb32", + "a57b42a08e5a00be029e6f709e40d3bee2b9a545e42fc27e4c2d2c0529d95ef9", + "93641cf68c20734f79b7ff3535f7b1cf4e0d45b62c8520299affefbb8e18b92b", + "c0a5a736afebc25dc5ae7bd8932f49ba097ec575120713dbe2f1e833bacb4594", + "73de3c28c6ff10da1104412b1cf6403d8f115c7dc9b334afa0c2ac3edaba7273", + "6c1985a81d0894673d67e2f2e5fe380591707f8f9f732e25d5582866c380b5f2", + "ceb0cd6ddd217b432403b59d2a02a4d46391f029a168c17059ae85ec0d9d1adf", + "fb1c78cdd02ba8a483d5c374e1be2a08dcf1e8b28baa1b5b96b38e8397cdfc09", + "7792642a1da8afb7f71b77ac5f88ff86d79582d8f8f6096d30c5d8611cc42637", + "14b8f1f73fb68867ccc403ff6cf3bf0803b896d1503e32ff70d1705a015355ee", + "cdfb42d93925dc65353e3150f8ee140aa563d52e90e61de8ba1a01808f3ff83c", + "7082fdb76fc3cb91442f99e87bcdb4c3c722e47e10e4758b2f7995551fdb5494", + "b2f3bd4a0acbae69252942e61c24e637e4083d49104c694173d0f0a8c9ce56ed", + "b7bc6a82541e9c3e0462a8db62ab13ff7a8ebf91e865208f2b2bc5a32df6dce6", + "44630b046f4307041664d1b0f34ac0c46653273c38adc84b479be8ed16dc5c88", + "807bdd9630a8d34fd6b4ed5e111ba00592557e724e29316bbc70ac0889f7db03", + "8ca8c8856df01c56bbf3a85867a2e824c666938bdd932b1798cd6072e2590aef", + "6e8e00f992c42d1ab1635a7d579b45590b2fec5c3bc7abc75b2726754ed5027e", + "c6c9d68c215b4669b4ac51bb3615eb27ba444c90bca17e82755eac0a99682828", + "3920386b0ae09d30d7aaeb00e03d418b3ed0b7785e577cb5310b3c1859657a78", + "18940f5c848e802a12c0ad3e55e277be22a5b52b40ad85ce9e9c948266ccb3a7", + "47b49c4b176732a0a7db896b87595e7d8e5a7f871c08aba89c4b2d980e7a6c64", + "721ef80b0541e2c85e1355e6686e1a1a5c693ef7296de34207b7bec9994aaac0", + "cec534fac913201563f82ff6b95cdc3a1dd6db5fddba4097b937b747e313e0a9", + "2d9da6f74456a0e1d763e6c246d6392ba17001b7c2b190e54a36d117f6b4e57a", + "8a359bd4ef9cc56a0529b5e1d3e42939a65826c3fee57715bc62f8fd1cdc46dc", + "2650bb5325ec323080ac9b1c87b3af1f746a97798281bb682b9dfe1489bbc47b", + "5c52f69abeeb424b22a53f24758693228de97fe0bcbffb888a0faa40d4741043", + "eede4311a7e9a63f2905ffd2cb4cedc12654b28561072d240a88577666b924d1", + "a9365d267a96421df82a29bd15b0a2f5f51326a722438fc60284fafccbd7b05c", + "3c1d64809705c4dfc5250fe77bdb9fbfce8a33a96ba2464ee9950bb669396d0c", + "3378a3a8ecad11a599b1ae7a27646ac196de219db301c89c61dd9d56bacc6e97", + "5f36100d570aeaf94b872bb30a9e659f2287db4ca4867ca4f71d78d70be7b75f", + "b0d36c27ec429710130aac77846328c69f4215e061260b5017e37aa29a75466c", + "15f7dcf5cfcfd239c7235e52a18c163ece85e53dbf638fb4d762afa23eb72a69", + "b6ef83e372622bfd738f4215a919c1c64a2147658de0e866b7424ca2d23f9186", + "ebcc6343861b5674c4adc3699f02f688d4357bbb1fed191ce675b581eff9fb90", + "60be37b4ae2bc46c2a669f2b08b4023b44f5e650cc346c6f11f7404c96478747", + "2ca9c973fe595c990b265ea6b9bb7b00b2c7c69606b5fb93cb1971b5594c7d53", + "d19b7cfdec0f8422ef35c41737c01c15e3dc89f7d072801e2e0971e93dcd146a", + "b71f1323cc493746de2d2c781f3e1784d62c661c173afe842fb618b946b5d7b7", + "d429fa70d04ff68b94e533848d8cabfd89a1062d3b6a889a4456f06710a0a998", + "77ad60a8a16ac45e724a233c568e4f5a9ffed36009cd78887357ba61e1c59cef", + "2e2be6639a10a8e683553d7e4010bc93689dd06523949f62f51826ce75025b0c", + "04859547dfce019e952dcbe67d7fb3b3ce869b7c1a12f6c22f5855c444639c8f", + "2d71572c722b75c1e8961ca3bed9dd15d5b1ba9dbc76824da5fd602294d7d4fe", + "4a4028b2ae250c9a8cd5ae731738503bc63d5e5bf0bf8306553c17de0862af18", + "71c8f6fa1fddd205651318ecd8b6acae1cd6a51bd11786c9877438ebb79a840e", + "fd425058286255345d2abccb37ad94f073978b2842b1437f0a43af79f731b418", + "d195957d39f7a43f7f51d72782b2255df97e6f220e6983578f1abd47af1a3486", + "29dcd9a158e55a33079bb2939d1d6214c11866d95da252967f587805257e55a8", + "e4cf49e98aaaff6027f744900ae4161d1aa1a07337b0dbce824a0c9240d0d614", + "8f1d6eecd9aaf2126ac6127079adecc3d7777cf2cf75e5344ec5eddd850505f7", + "7ccd9d6c8e97938c1d74c5b792872a8f1c9543ca268b5fde85f0e0283af2f362", + "52e578e08925d1052c6198e28ee6d60d57096628e8f2a09f08fad604cf427752", + "ffdec8c2a794e3df19a37c3701f53f19cebf9757143568af2b99781fbbb1ff62", + "46a0a90562e65c064d1feac12b019c81e8036a80f8eeecb9990de63554e81bc6", + "885ccb9bc774a25417a24248f04d1f1ab08247be2e8dc7b80a69c845606fa625", + "56de0327d36ff9618007b00503db49dc3a74520e729391a8c040b1f2bc4c5a60", + "ffdceb9495db763ad75ba49d03e2cd58559fec390b3813a09d15fd16858df436", + "057a98e18982d65533926a677f70c1751e0ce6a6ce3e890a5a4d0ea4c7cbfab8", + "522dbe92d28b2865597eba6043418658e82a419bf6bdbef35bcceefebbfeff97", + "3a5042f4ff158fe0118c7654619ef5c11b54291b64f228280d318e08ce139add", + "105d1081d682ad419b2adb5f61ee7feb93cd4205b1eded470315e248216f40cf", + "954c6f71744fb20e6a11f0e83485287c1de1e5b3c86527b949da0e256f4b10cc", + "d5f9739b2c6a47c0113b0f5cc4bc9865ccc45664dfff9fc397a8ea7016d87148", + "1b8dc8cda669752e928ba10b37cb4035295ab0e46b3c2193d25928ae942f9b7c", + "18ed0b958bcfd9eb420925a3ff7a8bac221ff7263bfe2925026d0df72cd8aa5f", + "2b75f888b2dc58bf66d3f456792e6d5ca32cb2828c0af8bdee157c879a4abb0d", + "11f30e91cc2cf8819cf2055f40504f37dea463c9eb1cce306d8a46afc1c6d816", + "efe418f184ddd3d70de20df6dcb62eaa655aae457bad3e498726828886480c13", + "997ca5204bcef4f06ae16bdca07589a390a33d9f8cbd62861d79199085febdae", + "a2ca52ef1d7df662d1c7c23ac2a2015fdaa8b9bc1db2938f7c8fac5336e6390d", + "0ad0e4a426943944faad9b9c453d140f6959576b5b3cacb0d6e323db2ab8022d", + "69888fbd8413df470feda6cde125cccfd674bf64fb600501d34e1ba90cfaf53a", + "454604016e25708e0869247b6868b5f0d301830b68c91e0f7850a1aaf66502a3", + "ebe612fcd306d69aeda11c9cfa8a2a91c3ca3644bd78f2d90d8142e63b405f48", + "2b98d13d4ac651401e1bc2d55a5bf1b638b3d7291b49eeafc8411e75a34a9dad", + "a1a146ede99ae073811ccd94e32b2b91fdde6ad1033cbba64bf1411916438e9b", } -const ropstenPreverifiedHeight uint64 = 11309760 +const ropstenPreverifiedHeight uint64 = 11437824 From a37afc5b1546c1ee4c3056fec1315060d03442bd Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Wed, 17 Nov 2021 09:41:29 +0000 Subject: [PATCH 028/261] Bump release version to 2021.11.03-beta (#2975) --- params/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/params/version.go b/params/version.go index 9bc5a5d46d1..1ff07e5dfb4 100644 --- a/params/version.go +++ b/params/version.go @@ -33,7 +33,7 @@ var ( const ( VersionMajor = 2021 // Major version component of the current release VersionMinor = 11 // Minor version component of the current release - VersionMicro = 2 // Patch version component of the current release + VersionMicro = 3 // Patch version component of the current release VersionModifier = "beta" // Patch version component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" From 9c572516d9e0a87d3edd6eba664efd2088f5f8df Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Thu, 18 Nov 2021 14:58:22 +0000 Subject: [PATCH 029/261] Fix for eth_getLogs with zero fromBlock and toBlock (#2989) (#2990) --- cmd/rpcdaemon/commands/eth_receipts.go | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/cmd/rpcdaemon/commands/eth_receipts.go b/cmd/rpcdaemon/commands/eth_receipts.go index 504adbae186..e246cc01ae6 100644 --- a/cmd/rpcdaemon/commands/eth_receipts.go +++ b/cmd/rpcdaemon/commands/eth_receipts.go @@ -91,14 +91,25 @@ func (api *APIImpl) GetLogs(ctx context.Context, crit filters.FilterCriteria) ([ } begin = 0 - if crit.FromBlock != nil && crit.FromBlock.Sign() > 0 { - begin = crit.FromBlock.Uint64() + if crit.FromBlock != nil { + if crit.FromBlock.Sign() >= 0 { + begin = crit.FromBlock.Uint64() + } else { + return nil, fmt.Errorf("negative value for FromBlock: %v", crit.FromBlock) + } } end = latest - if crit.ToBlock != nil && crit.ToBlock.Sign() > 0 { - end = crit.ToBlock.Uint64() + if crit.ToBlock != nil { + if crit.ToBlock.Sign() >= 0 { + end = crit.ToBlock.Uint64() + } else { + return nil, fmt.Errorf("negative value for ToBlock: %v", crit.ToBlock) + } } } + if end < begin { + return nil, fmt.Errorf("end (%d) < begin (%d)", end, begin) + } blockNumbers := roaring.New() blockNumbers.AddRange(begin, end+1) // [min,max) From bb350dd121177cbe3167c430df3de29a69e03aa7 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Sun, 21 Nov 2021 10:08:01 +0000 Subject: [PATCH 030/261] eth_getTransactionReceipt not to return unrelated txs (#2998) (#3001) * Cleanup * Restore * Fix for existing tx * Cleanup Co-authored-by: Alex Sharp Co-authored-by: Alex Sharp --- cmd/rpcdaemon/commands/eth_receipts.go | 5 ++ core/state/database_test.go | 67 ++++++++++++++++++++++++++ eth/stagedsync/stage_txlookup.go | 4 +- 3 files changed, 75 insertions(+), 1 deletion(-) diff --git a/cmd/rpcdaemon/commands/eth_receipts.go b/cmd/rpcdaemon/commands/eth_receipts.go index e246cc01ae6..535d821b39a 100644 --- a/cmd/rpcdaemon/commands/eth_receipts.go +++ b/cmd/rpcdaemon/commands/eth_receipts.go @@ -265,12 +265,17 @@ func (api *APIImpl) GetTransactionReceipt(ctx context.Context, hash common.Hash) return nil, fmt.Errorf("could not find block %d", *blockNumber) } var txIndex uint64 + var found bool for idx, txn := range block.Transactions() { if txn.Hash() == hash { txIndex = uint64(idx) + found = true break } } + if !found { + return nil, nil + } cc, err := api.chainConfig(tx) if err != nil { diff --git a/core/state/database_test.go b/core/state/database_test.go index 0a1068f8cca..4f71ab25575 100644 --- a/core/state/database_test.go +++ b/core/state/database_test.go @@ -1593,3 +1593,70 @@ func TestRecreateAndRewind(t *testing.T) { require.NoError(t, err) } +func TestTxLookupUnwind(t *testing.T) { + var ( + key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + address = crypto.PubkeyToAddress(key.PublicKey) + funds = big.NewInt(1000000000) + gspec = &core.Genesis{ + Config: ¶ms.ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: new(big.Int), + EIP150Block: new(big.Int), + EIP155Block: new(big.Int), + EIP158Block: big.NewInt(1), + ByzantiumBlock: big.NewInt(1), + ConstantinopleBlock: big.NewInt(1), + }, + Alloc: core.GenesisAlloc{ + address: {Balance: funds}, + }, + } + signer = types.LatestSignerForChainID(nil) + ) + + m := stages.MockWithGenesis(t, gspec, key) + chain1, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 2, func(i int, block *core.BlockGen) { + var tx types.Transaction + var e error + switch i { + case 1: + tx, e = types.SignTx(types.NewTransaction(block.TxNonce(address), address, uint256.NewInt(0), 1000000, new(uint256.Int), nil), *signer, key) + if e != nil { + t.Fatal(e) + } + block.AddTx(tx) + } + }, false) + if err != nil { + t.Fatal(err) + } + chain2, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 3, func(i int, block *core.BlockGen) { + }, false) + if err != nil { + t.Fatal(err) + } + if err = m.InsertChain(chain1); err != nil { + t.Fatal(err) + } + if err = m.InsertChain(chain2); err != nil { + t.Fatal(err) + } + var count uint64 + if err = m.DB.View(context.Background(), func(tx kv.Tx) error { + c, e := tx.Cursor(kv.TxLookup) + if e != nil { + return e + } + defer c.Close() + if count, e = c.Count(); e != nil { + return e + } + return nil + }); err != nil { + t.Fatal(err) + } + if count != 0 { + t.Errorf("txlookup record expected to be deleted, got %d", count) + } +} diff --git a/eth/stagedsync/stage_txlookup.go b/eth/stagedsync/stage_txlookup.go index 597973b4a28..dc2f0a1b63b 100644 --- a/eth/stagedsync/stage_txlookup.go +++ b/eth/stagedsync/stage_txlookup.go @@ -152,7 +152,9 @@ func unwindTxLookup(u *UnwindState, s *StageState, tx kv.RwTx, cfg TxLookupCfg, }, etl.IdentityLoadFunc, etl.TransformArgs{ Quit: quitCh, ExtractStartKey: dbutils.EncodeBlockNumber(u.UnwindPoint + 1), - ExtractEndKey: dbutils.EncodeBlockNumber(s.BlockNumber), + // end key needs to be s.BlockNumber + 1 and not s.BlockNumber, because + // the keys in BlockBody table always have hash after the block number + ExtractEndKey: dbutils.EncodeBlockNumber(s.BlockNumber + 1), LogDetailsExtract: func(k, v []byte) (additionalLogArguments []interface{}) { return []interface{}{"block", binary.BigEndian.Uint64(k)} }, From 4dfce9b9745da2b196a03a9dc7beefbc6af29eb7 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Sun, 21 Nov 2021 10:08:32 +0000 Subject: [PATCH 031/261] trace_block to return empty result for genesis (#3002) (#3003) Co-authored-by: Alexey Sharp Co-authored-by: Alexey Sharp --- cmd/rpcdaemon/commands/trace_filtering.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmd/rpcdaemon/commands/trace_filtering.go b/cmd/rpcdaemon/commands/trace_filtering.go index 05a24c5791c..4825e74daa3 100644 --- a/cmd/rpcdaemon/commands/trace_filtering.go +++ b/cmd/rpcdaemon/commands/trace_filtering.go @@ -118,6 +118,9 @@ func (api *TraceAPIImpl) Block(ctx context.Context, blockNr rpc.BlockNumber) (Pa if err != nil { return nil, err } + if blockNum == 0 { + return []ParityTrace{}, nil + } bn := hexutil.Uint64(blockNum) // Extract transactions from block From fa2bf0e600cecebedde28bace86aaed3fce78d0d Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Sun, 21 Nov 2021 10:32:32 +0000 Subject: [PATCH 032/261] Update version.go (#3004) --- params/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/params/version.go b/params/version.go index 1ff07e5dfb4..99a4811486a 100644 --- a/params/version.go +++ b/params/version.go @@ -33,7 +33,7 @@ var ( const ( VersionMajor = 2021 // Major version component of the current release VersionMinor = 11 // Minor version component of the current release - VersionMicro = 3 // Patch version component of the current release + VersionMicro = 4 // Patch version component of the current release VersionModifier = "beta" // Patch version component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" From 21be8f775f6eb9e9c75a8e584d4c35d3775a2108 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sun, 21 Nov 2021 08:51:32 -0300 Subject: [PATCH 033/261] Add selfdestruct trace support --- otterscan/transactions/trace_transaction.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/otterscan/transactions/trace_transaction.go b/otterscan/transactions/trace_transaction.go index 362f5c85bcc..f61ab35f807 100644 --- a/otterscan/transactions/trace_transaction.go +++ b/otterscan/transactions/trace_transaction.go @@ -81,6 +81,8 @@ func (l *TransactionTracer) CaptureEnd(depth int, output []byte, startGas, endGa } func (l *TransactionTracer) CaptureSelfDestruct(from common.Address, to common.Address, value *big.Int) { + last := l.Results[len(l.Results)-1] + l.Results = append(l.Results, &TraceEntry{"SELFDESTRUCT", last.Depth + 1, from, to, (*hexutil.Big)(value), nil}) } func (l *TransactionTracer) CaptureAccountRead(account common.Address) error { From 79e309d68baae9008d28cbcb1de6e337b6adfc48 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Mon, 22 Nov 2021 11:36:19 +0000 Subject: [PATCH 034/261] Fix Sentry server initialization (#3008) (#3012) Co-authored-by: Dmitry Savelev <12631916+dsavelev@users.noreply.github.com> --- cmd/sentry/download/sentry.go | 9 +++++++-- cmd/sentry/download/sentry_test.go | 29 +++++++++++++++++++++++++++++ p2p/server.go | 11 ++++++----- 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/cmd/sentry/download/sentry.go b/cmd/sentry/download/sentry.go index ec52974534b..a5096d6c7dd 100644 --- a/cmd/sentry/download/sentry.go +++ b/cmd/sentry/download/sentry.go @@ -785,6 +785,7 @@ func (ss *SentryServerImpl) HandShake(context.Context, *emptypb.Empty) (*proto_s } return reply, nil } + func (ss *SentryServerImpl) SetStatus(_ context.Context, statusData *proto_sentry.StatusData) (*proto_sentry.SetStatusReply, error) { genesisHash := gointerfaces.ConvertH256ToHash(statusData.ForkData.Genesis) @@ -806,15 +807,19 @@ func (ss *SentryServerImpl) SetStatus(_ context.Context, statusData *proto_sentr } } - ss.P2pServer, err = makeP2PServer(*ss.p2p, genesisHash, ss.Protocol) + srv, err := makeP2PServer(*ss.p2p, genesisHash, ss.Protocol) if err != nil { return reply, err } + // Add protocol - if err := ss.P2pServer.Start(); err != nil { + if err = srv.Start(); err != nil { return reply, fmt.Errorf("could not start server: %w", err) } + + ss.P2pServer = srv } + ss.P2pServer.LocalNode().Set(eth.CurrentENREntryFromForks(statusData.ForkData.Forks, genesisHash, statusData.MaxBlock)) if ss.statusData == nil || statusData.MaxBlock != 0 { // Not overwrite statusData if the message contains zero MaxBlock (comes from standalone transaction pool) diff --git a/cmd/sentry/download/sentry_test.go b/cmd/sentry/download/sentry_test.go index d9852573ee8..1df63b8bcfa 100644 --- a/cmd/sentry/download/sentry_test.go +++ b/cmd/sentry/download/sentry_test.go @@ -148,3 +148,32 @@ func testForkIDSplit(t *testing.T, protocol uint) { } } } + +func TestSentryServerImpl_SetStatusInitPanic(t *testing.T) { + defer func() { + if r := recover(); r != nil { + t.Fatalf("panic during server initialization") + } + }() + + configNoFork := ¶ms.ChainConfig{HomesteadBlock: big.NewInt(1), ChainID: big.NewInt(1)} + dbNoFork := memdb.NewTestDB(t) + gspecNoFork := &core.Genesis{Config: configNoFork} + genesisNoFork := gspecNoFork.MustCommit(dbNoFork) + ss := &SentryServerImpl{p2p: &p2p.Config{}} + + _, err := ss.SetStatus(context.Background(), &proto_sentry.StatusData{ + ForkData: &proto_sentry.Forks{Genesis: gointerfaces.ConvertHashToH256(genesisNoFork.Hash())}, + }) + if err == nil { + t.Fatalf("error expected") + } + + // Should not panic here. + _, err = ss.SetStatus(context.Background(), &proto_sentry.StatusData{ + ForkData: &proto_sentry.Forks{Genesis: gointerfaces.ConvertHashToH256(genesisNoFork.Hash())}, + }) + if err == nil { + t.Fatalf("error expected") + } +} diff --git a/p2p/server.go b/p2p/server.go index 0b2461115c0..3ab28b2c67b 100644 --- a/p2p/server.go +++ b/p2p/server.go @@ -245,8 +245,8 @@ type transport interface { // handshake has completed. The code uses conn.id to track this // by setting it to a non-nil value after the encryption handshake. MsgReadWriter - // transports must provide Close because we use MsgPipe in some of - // the tests. Closing the actual network connection doesn't do + // transports must provide Close because we use MsgPipe in some + // tests. Closing the actual network connection doesn't do // anything in those tests because MsgPipe doesn't use it. close(err error) } @@ -383,7 +383,7 @@ func (srv *Server) RemoveTrustedPeer(node *enode.Node) { } } -// SubscribePeers subscribes the given channel to peer events +// SubscribeEvents subscribes the given channel to peer events. func (srv *Server) SubscribeEvents(ch chan *PeerEvent) event.Subscription { return srv.peerFeed.Subscribe(ch) } @@ -451,13 +451,13 @@ func (srv *Server) Running() bool { // Start starts running the server. // Servers can not be re-used after stopping. -func (srv *Server) Start() (err error) { +func (srv *Server) Start() error { srv.lock.Lock() defer srv.lock.Unlock() if srv.running { return errors.New("server already running") } - srv.running = true + srv.log = srv.Config.Logger if srv.log == nil { srv.log = log.Root() @@ -501,6 +501,7 @@ func (srv *Server) Start() (err error) { } srv.setupDialScheduler() + srv.running = true srv.loopWG.Add(1) go srv.run() return nil From 2943bc37afcefe93f2bc5aa3b5d9ce0dc839f171 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Mon, 22 Nov 2021 11:36:31 +0000 Subject: [PATCH 035/261] eth_estimateGas to correctly recap to balance for London txs (#3006) (#3007) Co-authored-by: Alexey Sharp Co-authored-by: Alexey Sharp --- cmd/rpcdaemon/commands/eth_call.go | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/cmd/rpcdaemon/commands/eth_call.go b/cmd/rpcdaemon/commands/eth_call.go index 28dba7ed53b..e643703c5f5 100644 --- a/cmd/rpcdaemon/commands/eth_call.go +++ b/cmd/rpcdaemon/commands/eth_call.go @@ -142,8 +142,18 @@ func (api *APIImpl) EstimateGas(ctx context.Context, args ethapi.CallArgs, block hi = h.GasLimit } + var feeCap *big.Int + if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) { + return 0, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified") + } else if args.GasPrice != nil { + feeCap = args.GasPrice.ToInt() + } else if args.MaxFeePerGas != nil { + feeCap = args.MaxFeePerGas.ToInt() + } else { + feeCap = common.Big0 + } // Recap the highest gas limit with account's available balance. - if args.GasPrice != nil && args.GasPrice.ToInt().Uint64() != 0 { + if feeCap.BitLen() != 0 { cacheView, err := api.stateCache.View(ctx, dbtx) if err != nil { return 0, err @@ -162,17 +172,20 @@ func (api *APIImpl) EstimateGas(ctx context.Context, args ethapi.CallArgs, block } available.Sub(available, args.Value.ToInt()) } - allowance := new(big.Int).Div(available, args.GasPrice.ToInt()) - if hi > allowance.Uint64() { + allowance := new(big.Int).Div(available, feeCap) + + // If the allowance is larger than maximum uint64, skip checking + if allowance.IsUint64() && hi > allowance.Uint64() { transfer := args.Value if transfer == nil { transfer = new(hexutil.Big) } log.Warn("Gas estimation capped by limited funds", "original", hi, "balance", balance, - "sent", transfer.ToInt(), "gasprice", args.GasPrice.ToInt(), "fundable", allowance) + "sent", transfer.ToInt(), "maxFeePerGas", feeCap, "fundable", allowance) hi = allowance.Uint64() } } + // Recap the highest gas allowance with specified gascap. if hi > api.GasCap { log.Warn("Caller gas above allowance, capping", "requested", hi, "cap", api.GasCap) From 6823662fe9351c3433fd56139759e0f9ef32f4d9 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Mon, 22 Nov 2021 11:36:42 +0000 Subject: [PATCH 036/261] [beta] Update skip_analysis and preverified hashes (#3011) * Update preverified hashes for mainnet and ropsten (#3010) Co-authored-by: Alexey Sharp * Update skip_analysis.go (#3009) Co-authored-by: Alexey Sharp --- core/skip_analysis.go | 2 +- .../preverified_hashes_mainnet.go | 165 +++++++++++++++++- .../preverified_hashes_ropsten.go | 164 ++++++++++++++++- 3 files changed, 328 insertions(+), 3 deletions(-) diff --git a/core/skip_analysis.go b/core/skip_analysis.go index fc7382ec0d4..9d46120cc8b 100644 --- a/core/skip_analysis.go +++ b/core/skip_analysis.go @@ -21,7 +21,7 @@ import ( ) // MainnetNotCheckedFrom is the first block number not yet checked for invalid jumps -const MainnetNotCheckedFrom uint64 = 13627700 +const MainnetNotCheckedFrom uint64 = 13658800 // SkipAnalysis function tells us whether we can skip performing jumpdest analysis // for the historical blocks (on mainnet now but perhaps on the testsnets diff --git a/turbo/stages/headerdownload/preverified_hashes_mainnet.go b/turbo/stages/headerdownload/preverified_hashes_mainnet.go index 0f00cac8512..a7d3057307a 100644 --- a/turbo/stages/headerdownload/preverified_hashes_mainnet.go +++ b/turbo/stages/headerdownload/preverified_hashes_mainnet.go @@ -70979,6 +70979,169 @@ var mainnetPreverifiedHashes = []string{ "0ae9ed2e0781592b40eee05636c0aca75574ed08dc9c5932725e846b6d2ab2cc", "a313623ca6a4bb5d79b8be6bd46f10a8a303afa0323abbcd41f2233f00c3212a", "f7f61c84b09c8c86f8876b6a5fdb98e52df41345f407ce484e594908ac7dbb9b", + "d6601e053162a490d5a2842cef20e5af4125203c3184a206a7913bc1307f4e5e", + "8156fa5eb3373669eab32a3471e37936d36d5e239c61ec08d43ff831fed3f76f", + "b33d6a357f9586fe4d93ee6b7d2c572223b9c63aac646aa35ce140ac03bc3797", + "4cca647aaad12847ff6a151aa2fa5e6c025b5dbd774dce6f66f66bb2676deb9b", + "a3768f2f7710227ed7e775cd63e6cafa50de3a15f2d139c3cd97877a0c5dc669", + "7101cfeacc6b092492c0f7c172711878e0399799606efa5528263fec0e8434aa", + "91f7976dcbe93bb8b8f83b413f761613be1b7cd5ef34b746fcd7ee44b57218cf", + "83afc2ce71c9b28626a864ad9c8f3420945c979d2197904232ed8c26c3bafb32", + "2629d5fa882071979b0c7d602f80da85fc76464d2f9c32e6cf2992e742db6632", + "d7686f7188795cc67a91ff17bf2c1c3d38010e9e3a7537fcae8c9fc2de8ff931", + "10c66f139568f8196feeff22e924a07d304e2477908955f56c68a99ca41b9188", + "0fb4c7a57cfe5dfbd348a5440fbc9b636e5bc3cae50fbd14516e944c03fd9fdc", + "fcfd5cefc9b49c3a696c5b53228f657341a8383bc031c3cdd02425c0c78ecf82", + "e7ca0d364a2abf87de4d0aa5c22a45d44333b920cf418c76316ab36ff51b78f8", + "7747fb1780f2925ce37ac158106b1cf942361fef07bc8e2337e56e770c678ed1", + "09283bf9d161058c47d569b9123b225b497cda52cbeb062835a01978c5f088b4", + "d7d4fea3d6e5eaad30823341dad795fe94dced4f11d0fffebc4ccdad15e209d2", + "3cc6d1fea8e0ac83770132b4263756e51c1e0152e62c29c13364ea4b92cc086d", + "d33d2e986895f3adb96d05cf10758d27b601b8e96b8e79db45f14afc193b4ffe", + "ae727dee8891102cfec44af8417570fc14c3e72eac35f063292aeabdcc3c5a4d", + "7d91b0533fa070f0deb6e9a40668c8bdc255fa73c0b4bff4c9725d5438492289", + "2fd1ec5c40b64e779d6883c3ecf15690682e12d0820e15f29a44a06d4f9abfe9", + "702089016c1530f9a6f92f1a5783b7da3031a1c1952ceef00156b51e22c8185d", + "b71199c852621a7a4d1a04fe7468845e4ea6ebb06e21c70663fbe07899f45c74", + "aea4c123ed14e9e497f3ca881264a21619303759deb82c9e3e51f28782d1e548", + "8bd7eb3098f38d989d53a3207f54e222c792c5fcb95ce6812bf1fd31f08bf726", + "f799c45ad92cb0bb2d870045bd54303062059aeac250f212f8278d0e3fb20219", + "d81ba47ec2cd03031f7977a599827a8089ad6c8be6fd8f28474109efecaf7ff9", + "6760e420ba04388a2fca94f322766916bb9b8cdbc2bb83c30418950a032468a1", + "e27676af6629e2db3d84c46f0ff62ce65f44e1b0e258e96f6b28e3adcea41e8e", + "dca57d4c3aab047562e4500b30ffc43fc9270f42490689d92eb72ca4215fbdfb", + "edcb379943fbdc1a5caf0d9cdc3a4908bf84151b701e3682734a470afbf25319", + "1a7f60ccf0ddc41e9bd30f0fb09bf5382e31249cc3d30cb8db85d4ed70d7b2dd", + "d894a245f13cd302354e1c214b979e5e34adc33660eb83d25749275c43320946", + "4049301bdaaabf519d30edf77c8ea43ee7cbc68ba5f793bcfe1d717937c21257", + "0f373c0d51a35a7f9f04dfb76e7e0e6591c0187a416e1025cb148c882e7601bc", + "d19a42be3d111a99190b1f3e9a72344a7b6b507f895d4b655e365ba7a397c72f", + "deb209aa6d88be9de53f4e7779bccfc34668ffeb2cebbb2ef5ec66eee1365e18", + "3ab86dd726af656ccaa98909c0a590b9122899e736ab3a46d9cd0669bbda110d", + "9225cba591e0b7d48e5f174f12bda836c52447894bf78d115ccb780ff605f646", + "f2909118411c241a766dcefaa27e56326fe5a690c60105098cbf52950ec0833b", + "82a740d36d2289ec5eb88719b06e2025b7268fe3a84fad8c313677c935787e29", + "acc1748e54359316cd5e52b66399376d862c75caf58e8feceb5d361696873752", + "540736baf47f3533cbcc2a680a664bd29715e3dbb80273c7a4d65b4928430594", + "55b65098dff706a0dfa568f823a97f90a287a33747b8d931daef827bd4593712", + "da61a071c43ba7d08656a878afa5ce60b03fabdfb1776f4cf6d0b03ab30b50a2", + "213fcac0b6d1f446ec35bee1e36dba4ca0e8485852c6ebdc0483f219d40e2be3", + "916d18a2da43291eb8bbf91959bdbc531a9f9904574312cb204e9e696789d6a5", + "ba3e730e93c4a94f5625afacc04ebe3344b58768d329c05bafa87cf542d88f93", + "2c9c6ad3178d569559faf09f5fa00f3f448f2308af19a2a090703258d3ad226b", + "9b8ef8b0a554dfffa4f8f79f8528182a9c0854569d4397f7f39a949aa7ec2ea4", + "24bf65fbc186cd5e13d56d5872266e6adb63ee15bb1d8e37aaab4935be1c78ae", + "3133ab1ca5ee60812332acda8c099bc927f26f6282502e0286a9954bae920a3b", + "a028c17d6ba26791f43bc0379f7b82c46071aa081263b6d50f406659b1f687dc", + "73294ed99c1680e94da0c2a45e0f433c9ea847e5610bae34e67dd6e9780fd003", + "e2e3da28fc8b137d21ddbe931eb376873a609322bfff348d21a4958ae0ba4201", + "4d2965aab74da36b8886f0a90f338a1ad63e7167643bd7868a7051b1675745e6", + "95217974e5f29037f7ff1defe3ca8a60a512d1f30f1f6cb60ac21d2459c2aea6", + "860209889484094fb151288e621d07b5bc4349af6b711ee0fbe5dd3c26c0da5f", + "c7bfa63815d56874cef402c1dd1eed8c873181738e0f20ab9d26066b45f933ed", + "6df55e919f3eb3dad940a14841229c991f4769df7b20a769d65f3e2a03a13d0a", + "4895efabc963dca6a22b473f63bf22e9c299cd56d0151b8790d3a4591766ab4b", + "ef7a1a1743333a369738c02ad7929e61c69273bc548cf6842cf9df79baed8869", + "43f83841e37f6352c025209660a9858837014f40c92938f9c61566b21c9e45fe", + "f718761447e18461614b6ffab6d1cf34720fc7e259e8243eed8e8b873b806bda", + "72be1bc2df6c919d0714ffddc7090ac1a3417438d218c0f3932040f1d230ecf7", + "d3e500250f26943a4133a5824732428c42aec6175d8a817ae5988f4d3ca762dd", + "72a8491184bde087fcbb08f90d0136a3598816270095a077068f953dc7f67b4c", + "183af8f9e084ff9d208586807bacdd0c61d23643ad02739cdb0536b6f67994ad", + "ccd96bffe2cd1b280cba1530786e2c5e5b3983235d81959a269bee7cee47acf0", + "6a6963e0eb2fba368d535d6c81ad8a9c0c1fe2baf2a00b80b6fa3c953435b233", + "cbfd43e1fedf56e75957848bd2ae17e15b5f66369e45e481991eb5e62aa3b633", + "644f01c241ee11ca65047b3cea81f6f3bb639b268bc8faedabd98a14cf381ee2", + "528ad9ff9b5f4dc4ce1696272db7b2b628fe66aa663d1a36e85e43782ede7b01", + "5b14a36fc44e8a59b1384a3a2264521e799a61b7416c0acee19df8a7197e5129", + "dd4c66714c04c41551c3f33cddf7b4e230f2121d0da89942d5d0872790128a66", + "f8710d239196bdc74a5b829c066983bf50ee939e89ba703effe9c9baed8ad73c", + "165f865621a5e9296270e20b827b79491423fa49c4d71cad952bcc0466d2e193", + "7ba205842037b8336c89c42b778ce97f08f4f9d7c8fd2055aa36da96baef8b92", + "9c5bf4111e6f0488d995f128e9499a9f404d2a6739d79fb2cc93b1c240d592cb", + "09df2938434648e4d89a5b3cba5f4dbeef2ae1ad2eded0dbe38d7c24db580039", + "3f9df9aee35d6af11d52052a30539502658f080f9a8d42edb95b015690a6c3c2", + "659f78e2b0ba220251b1d1b89362aac2be34c136696c87f86c021c1e58fac1f1", + "2c950079f4e9c51d3204580e14199178f88113b77b07e49aea73f32dbccbec09", + "0d3f98293aff28ca2061a687dfadcbd8f651d3f2b15eead5638028264a833cd6", + "c653f0825f82a47b47df58cd95148ec4f6b6b96a1ded912d197bef5c0494dd42", + "94b44ba907e1d18ecfe6476ad2eb7ef5c770fe4f3bbc6a0a7098110342b18f5d", + "6c36a81701c37274497340a7238fd7833ab8b264fc9fcf95a8ba23ca6b1dd5ee", + "ef752f57e10df7024c6f76bc4a7aee378e6b5c9bd7d533c72ba68b70688f9b7a", + "e9c321c136211c8794a734ae4081460317fe169b73b12c5f0b12ad2fb1f10e43", + "48808ff21ceed6db9a41712c9c7a2e9ec9dfc9f7c699d594903e269b5b846393", + "c7c9e7c2a85a5467530afd961f762a72e976a12110968267899084f1cfe8ee33", + "c4e36931fe8a17f1d6603b73a9de05a19d5c3851d52860d7ad7ccb36bc9bd651", + "53b3fe1dc07f5a4fec0a35b3c8ceb2e17f0b6e23d6a67b11895b0fcbebcd3499", + "2344069d1115eec895c2a0cc557ebf5905c9905e1e9ae09aff48d4cbe3e72d17", + "7354a7d082afaaf12d07f0108939520a147e506550481b64a575c6293ec8b575", + "b83de7a48df6260273c38c3d94f22ab0eb7d6f07f3b70a21425013373216236b", + "7f9bc01f6096cfcb299ca816bf8abc5a93f38d3bc443e8b47bf82d64f128a7d7", + "b5b2eb878beb2874c4b18df5ef26767352fb9ac7763c956f59c66303b6eeab82", + "898cfe9220916e63c0069f07fdf0fbecbbbf4aafcd5d5ea4062c50efb02e44a6", + "8ea5f46174d1989fb2f2a6fa2c481cf530f3ff7de6ea40afb0691f4d85134e13", + "e5a6fd8ceb9e4ec5c3fd45c153049ca5d2fa5065281dd79b29f8f8bea9899507", + "03ee56c82b7f20aca9c7958954533349977daed028ba102b19f05eace1b639cf", + "2fe614f4d33f25e2fb009b7e60a6813bf5e8f95369390ed0585b61029d547683", + "df1b2a84374c7d3dec96e85f30a9d3f5454cbc503f2ae07c199869be4f4acf3c", + "c2ff181329d2c33e2950d7803053ba298d15549e3161108de014576c8411a5ce", + "deb6a4b67251059d743008ee5b213f091d27c3d798063f92ce574cc0a8e74409", + "d0781056735eb81fb79e5d9a8ea94ab26eb42bc2772239c463f2daf077b63007", + "27b072896a5adedd7c0038713915693ad8341e5a44a0190181f1203438a9593d", + "828b20231c6d6eb9b909973ac1403a6199f90816c7131187b764cc0155069910", + "37876c5e5ba03b3e83c0189fc899f2a99ffd571ac67e428c42edda2788270445", + "ecc01095bb05ca7c2c425ef80b91c24068857a76424242be436750edcf10cb33", + "6ba9640daa49f862bea03e95e731c258a7473c49209d53fe688a2e083a80b105", + "22f32bc7dc46f3695e85d5cd17183f97826c1d95d1104944edc5f897cf08c7ad", + "093b3542c89786c2048fee01e0d28fa369197c760fd0d468846731ffa192852e", + "8b0c4a77fe5cbb96b5b5cba2a847afdccd9010cc3f3dbf4c09c656daedf9e422", + "6dfcb9a0e1e8a95d5c5ea643724c3bc2ab54dcec074a779389414187020feb7b", + "5d35c6de66d33f77d6e1a5de2a9131a41730b1c75928124e266cbe427dc28496", + "545fe13e34331563884b23b193f00879ff97de51685094e5954a9849d083c2d4", + "f2740c66487e2c66b9969c061bdb3c23d445eb68751ecfd392d4e5652ff7790b", + "b07d5a933eb562f2388154d08b50be21665d92437b89ddea9a939307fb947e78", + "5275577ad172b4b41d60e22ce24a1f1e9e375697a3ea2918e952c8d388277d14", + "7c63fa7c842b7d52ada543167542163a3e856ef2393633d4b51365c39a83e742", + "0b58a75692645387bd1b43762b6b95a2936bcafd07cab0756ac7d12b2a55bc8c", + "51970013b2080db0aa41ca9406e4f2b9ea79e7e3d96d1295e20b68e97c3ab0e1", + "cbedbde80cc4bb4e16372424760488ff6cd72ec4df4d83143452a63a7a3dbd7f", + "7d80f514417864065c64bfc72803cb0a6427438da56b5b927c6515b31e372a79", + "fa91d2746dc258e9b9b9db904817e7b7549d8611cd2f0b8e78e240f608847999", + "fa7dd8a61e3199cb992268c46ced60183dedbcd5805c47ff75f927f97a705b3e", + "3dd3724886f1179b7dd2bd4047b0aa56f55cca5b589df4f3eb7d53633bf6f14c", + "bcaafab3577eb1b1f9c0cc741655a39fb508dd248dad586aadd961dcccfad6eb", + "3a555285597bd4f7d49681118d260a13b89aa3ed8f840626e58840afcb96d7c3", + "e3867b23d77cda2e7e811db20c647664dbc097b5143f9e846c2f8e32ce673651", + "c9d01835be77d34ab62d74f1b5f114e9967a8b9d3edc9888ee139c4c6be3c6a1", + "15b32605dd4f3016f61ef111a0213530a770d2d443af975cfe03b5513935556a", + "e91c2303858007cb550291191ceea21540dfaa2cf2d04eedfbb40a9e0de4593f", + "54d834d99aef7515be8624a4f0ea899a27a50f32b52c60333f088fae2e594879", + "84b36cd257561c146b73140506efd5fe76c25c7e024834a781058695058fa420", + "394363d90d7dddcdb20af7b3a3d6442edf12185dccd66eb701811c8042ccd5f6", + "ed4728592d2b17570910b2edc9a56fd583b28abce921bbe0ac69dcae4d1eb033", + "c5819be67d4f5c66ef0855fddd34ccd900271b5ad0a972ffd30c1affc535211c", + "815caffde34fe2be918322364df17445a6856d3c0d3912ae196cae741996410e", + "52203fe1e0f97c1ba335c3a6b71a78379e930a9544a87ad232d0862a385ce426", + "5fc83061a3e6c28d87186e13b678b05c65a1400660089883e9311f4855815390", + "aceb81ccaa57455b8757445ec3cd04916188f519861407811cb717f88651ff9d", + "8c6f1c0342280ae27f07f9c063970d44974efbb60c8e082c862f1e61179a90c5", + "1a1e825e07fffc730f23703cd1279f9b4a4703ec520adafa9856ad7cd3a0f4b6", + "4f3029433daabdd1370cf6cb5b91de77f395435a296c5a079641b2af0645c196", + "f517ee24c3b42fd0aff2c62fd662c3da814c2b60da31f102763f967c2e3c0342", + "5730ee465a8beb691486d4e1253ef3f334d2c1db8651b48b991f61557e1f2cef", + "031a5c6710b454cc39fb6dcdbd7dc38e7fd01ccbd3717dd861b0f78049e52b15", + "428aee7aa96b3d166b2d18a2d99be825a49bc67abed0c9f86a5b5355716e369a", + "965b9e3bee170e831eeb6384533e1a11b116666728031c5e8d94c5a12dd422a7", + "1dcc283c1a9123bb318afabf63068abc1fd6eeacb709a003068547f349c7f745", + "0c842cb1a3343f0ea6962b4e1b0469ed0e4370d3d2c0f6c2da37c308a4b4f7cc", + "565b34a6a132858a1648439090f856147a1bbae989ee0a4e0ad94668b494d3b7", + "53b9cc4869a57e74ae217d6c76fc5a12560849a9406d68907ed0d51b7ad3e35a", + "80c69a852d88e580585356b7ae21c15463a6161ef2b48ad6631194e9cb8d8b97", + "82b58b52eefa2fc409cee21c882bd3a0435f2065cd252df7e09f5f7a70117dff", + "a391c2ec36a6bd5c5b337e80f64a295dfa3bb907991aaef7c3f1f19eec7c6e5c", + "95539489ece7e5e364fb48fe88f64f72c5598570ebcf6cb4974858cb773585bc", + "017ededd30cbd8a92bf1d41c243a7e01bce8f68d1682083aa9a1e82fb7ab4630", + "7ad7f720fad803769fdfe7c18db89e5ef7e9bd202415c4ea391a2933bf41194e", } -const mainnetPreverifiedHeight uint64 = 13627584 +const mainnetPreverifiedHeight uint64 = 13658880 diff --git a/turbo/stages/headerdownload/preverified_hashes_ropsten.go b/turbo/stages/headerdownload/preverified_hashes_ropsten.go index 3cde623dace..1ba10840672 100644 --- a/turbo/stages/headerdownload/preverified_hashes_ropsten.go +++ b/turbo/stages/headerdownload/preverified_hashes_ropsten.go @@ -59574,6 +59574,168 @@ var ropstenPreverifiedHashes = []string{ "ebe612fcd306d69aeda11c9cfa8a2a91c3ca3644bd78f2d90d8142e63b405f48", "2b98d13d4ac651401e1bc2d55a5bf1b638b3d7291b49eeafc8411e75a34a9dad", "a1a146ede99ae073811ccd94e32b2b91fdde6ad1033cbba64bf1411916438e9b", + "e1a6f8f52f0de3b46843e548a6acb928e6bd8646612123fc299ff7f5eec2cc7f", + "aca895a21033afaf6e4dcfa1ba566b01d1afa5e819e897ce410de42678366a2e", + "50694f7355bcdebf2b012addc73cac4439a5d0c77bdb197ba98560ac3a4396e0", + "465f4bdb5f9c02d4b9a016fe90a5d1eaa89566fb1ff76bcd6286e2ac3d64b9a4", + "ccbe7d4ea2da17de36ce573675f10d1ed38528016c481aac56ab628d3da24847", + "e20dbebd54f967e9c8f4595218f46f4aa2d56377578597bc21ee131aa7cb7690", + "81c1741ed9d77f850771a25e2c3c19cf1181135e09bc846144777fab07401d24", + "a21e85b837cf53e22e4456b56a89c60e400ef86193cb740054ae398df036a8f6", + "9899b86c0f529f26520a0dae226a14cbfecfcafd3b3a9c878a5a6755e2352b8e", + "53c484a99142d5360c3ea1b479b22d07d127364c1e3a22bb5416d6c284249adc", + "7792d578dbd234f40f27c31586f80837ee0972a92d3ec6a0166fa6daafe8bee3", + "88c834eebe3e5f206397c1c01a904b77d591834560e58910d455ab4f6e949144", + "cd1d02ef4a6cd6490d6ae810010f4c14da2b461dee7eae3f7be7749ea2c6913e", + "3fed1d643834018dd8657f4e9243ee72f6134ec12408644b3bbd245d1873d849", + "abda4c28b363fbd8e604458ad5bccab6e563c7e0fc115e8b486b42278402e61c", + "58cbd7af3edd7106fb4588e4b7682054e780d9389a894699392a85fda816d457", + "5f4919652cffec1e05a0bb49565eb084c160f61989c63bb25b4c973bc83cfb99", + "2212a1cff9d0d4146ade0b28d1d96ee365f9e208767823e2a5c2e536f20166bb", + "0899882d7ba2d2a669c1b5607f88b3c9718f0ee0860cac7f1f1bc352ba16eea1", + "9ff439f9f8c0da339638fc193c3bbae86e5e2b30b27321f2d0fc358ebe857bb8", + "984819a787488e20fd8df456c4dde9f242f817bfd457bbe1b291e6df795952aa", + "e2f603f81e16dddc34b333874c5f4f079db054f87ef2160f97247d96b37c29ba", + "a0ee2a81b6a244a8e6186f950e7467d6702dcb3f5e123a22709d6e687eb0d515", + "44967424a2e2799493984357e4aa29b0f52c1d443f4ada776b5fbe73112895f7", + "ea9d2f66869c25e80e01f149316af420380be6ad8af494cafb977ef028855322", + "72f4caeefc7ff2a92dff6e98d0dbacd1b702cc9df2ce361403ab43c274902807", + "fd1862df8f23b11837b0788696f680d794dc0b2fbdbc4add2d72f4d15692767f", + "1c96a366ccd132f18c05f6c1030006742b6eaae96458abb35d1b13f3228f65dd", + "baaeab0b4c296e03d7c7c3228622211a774d8ec2cabddfa3bee261a6d06008ed", + "15df2e1049d05fda4400867bfb419748526a9f305675104a22cda8f7f9b3f5d5", + "3072d15451f1e308eda0afd3fd0ccff4e817237af5e7a678eaa6e3216b407209", + "653a0b012d6ba78d93c18519e42a4ece004aacad8e9dfdbe5793219ec874580d", + "eb948da5f1b9a40eaed65795ea4fbe103eafda32b7f055f5aa51eb74efc5c8c1", + "1e9eb311955ac33c8943894407c05d97e5a910bb9c53aab2eb2d0ef04302244f", + "4054168860e3a1ee708afd530b201c74fdcd47afa40e310e49013804cc7ed378", + "d0546bafe7eb29bbdfd5863ff4c964f368c763ba4f3578656df2396fb062e061", + "81672c9b5b826f251537c621be810bb2fa1f6ae790684c1d44039d19ed6c92ee", + "d39a9d40cebe055baebb88db13e9b8072298d2511d45c06284bf9749f0a7f74c", + "66f0b9112c8698a9593ab5d068cec1516d181396174a9c7a1630192d4bb42396", + "c775a114ee6b1263f41712725d1ba381d5c319dd2493cd90c19fe06296ed21f0", + "275c61b296f42cd729540bce72d5104ea2d072779afe4d1d98253e40b1abf7cd", + "300bf5552274cb967736b36c612ecca2a94fbc72a372efede83c3805d0929805", + "0ec7ea943b54b6e30d38794ae0e64d522c5985613465ad8a93a1cd60ef848649", + "982d3c4167763ddaf41bdd1cd7b9b0cba96242768ed1865fa3ec7deadd5e467f", + "2cf2871331ba9741173dc4bc70b3adcc0bb2558707f880eb530b57d618ee8b69", + "8cdfcf5179d9cd9046d9729dc273d9b810d83ee5648bbe1a121e81e7f73d10d8", + "20274d9f36106a153c03f62f1b4f3f538446654732ccf47b238d154bdf41c1b1", + "7704c02efd3c8bf81564090c244cbad85eba1205910d94fac642d850194f21d3", + "bf645d953d919807329159e39313638dd7bea8ae7872cfdd57cd27185ca93289", + "6f16da31cb92e87d19f2bac50cd42088d49078a6f5478e15e68c4ab80d1deb6e", + "a875ebe805db1ba6311b1d19976b0486790ece19bf4b8097b8b985e407c63ec3", + "cd689de8f9471441e1b9aaa67517ff5db1999195ef47381cebac882342268e4f", + "92fceab9229be9cc0177881c5034e54cf9003cc5481493f2ca5ca06e6041fbc8", + "90b4b37867e203f77218e4d333dab1e7b937033195b024845ea683c5ad3a6434", + "eef0f862b7d5b34a4b3bc952eb80cf6a0d3820f9ef35d50d121aebe1829017bd", + "e24605f80f1130791a82489d5efce96de34b7aecef0715dec7aa636963f32cfd", + "64a6f1da53cc9a15326555723f69f07ed3be160c08b437830559635ffd7d0027", + "069fc1a3f2a7207d69b02235ccb4b3aba32047d9483150c91fc3f3f921aa5a5f", + "fef895419632e541a445b6c1916195945f59a745598cfd418b5d0800d114aa42", + "ecf25d72dfd017a5256fd48987f2bdcf58d7fd1e93bfd4433b59ca5ea00ff1ae", + "b9cd6386d7a1f8f19317d5649220357e50c1cab3c0e2a7bb4f056f7d038acd82", + "2e0711b3cbb773febd376d06129eb13e9e7650a4fd499f2ae60d604a0f25f20b", + "48492d8ef68b28c0659ee8a5b69f22dfb423d1b6aac1af4accbe04421557c376", + "ea41a80a11e597a4e8bdc62c9575550c17ae672b73aa23b107eb227bbb8311f7", + "c57ff04e6f5b5861fc4cc3d10fccff2296ad4ded5009d6ad356740242e813ac0", + "330b299690f0e29f6b9fd97b0a0b4b9b3a53224f463b72fa1e125217ccc841d0", + "437b55f1bc94e69881abd69d7003a54d2202cbb9aa0f17da3a11002156b4b05d", + "32e111ae66b19232513a35de575fdd19922790e15b402ee5553ff6794607aeca", + "afc4d41795c0b7288a54f31c8684e9754f1a7f8e7548fc9caeeee3616b5c5011", + "04c1b0043a2b8e49005efb497d40a9584977b77d75768ed64a27a23487c26bc9", + "f93b7f639f3f5ebf39d427d19c79aaf7af60f23fc6d1972f207e81f011094ce7", + "2bb55f8f3a9fff3bb32e1551f17f936a75130e895e5881a9ed7e30eb1bcc990b", + "90371004f101d2d484c382a7db2eb8185a04c8ee8f2ff19c4fd364a3b1b072b1", + "cae78f2c07c3a2e97a8d05a2dcc70b672bbd763bad23ae7f74afc1e70f811e81", + "02e909ee08387c301a18b5d820ed29492046361d5b413bf096b764759bb4212d", + "9f124e857b56d87d64ee2a8c2fc8a2dba3a824a1b60ca8617a656316db130d06", + "d838d74291716287f837c9afe0767a6f107e540b81218d7b735b8e522a8f0651", + "25d809e5987d6de0c23237119a24cc8819489b8378e2f5fec3318dc146a0d86d", + "f385f47f5c267655a9bbcbb39a37c639ff90686ca32861a2c136dd3507300ede", + "3c6cf19d77376c89dd9be4cb596dc4a6f27183f549fd9dd2a542643f47642e13", + "234b8d436a9216f99155e21daf5ac32c42d0434e711c5027c9bce93ccc9bca43", + "867f86d11aa9d3aefed22f3ff51183828ce0cdb319a0742842b8648b30569b7c", + "abc063317bd830f5851d0de7be4ae2ef160ed38b1f4ce860d5fd0198803372ca", + "3293270ff3763446fa4007ee2ea5769a4dbf1d36a5c264d1c0be1d3ccb83a24f", + "29d63ef792622d7df1bc0aa2d168a77e42c43a57f6f54cc2cf94b7a3beeacb0a", + "d9e7f4ccf7726f59bac7a09e4306b2c8464de8d13025d0a0dc4b3cf9161e400c", + "bfbe4c3cb75fb4682115211439e1806561d3a0e51dfb9270b9f2075c9bd9b366", + "ce9f649c74a7906e45c8fb4b2cfb8148cf03df7d00fbeb8a63b62634ebe9d6c5", + "a059ce69a4e325b3fadc5d170a0db8fece684a35924b2b7520051ed3cb0d044f", + "3d083be0d6703b1e054b804ae10432a6ae3e887af197bdad17d15d45db7b67bf", + "dadd21082998788d4c7bba9d6f900a7490c1b634e83db1f0435be910ec9d962c", + "e87cdc1bb79c5eb32c3d86ec26eb5b7b24f9a2dbac351ea8f0c28aed68f6174d", + "b9b45a12be2f80ec28b34e720405183f7175d4a24fd4fc2e93b88ba2a983554e", + "0d374e0a4bedeca6cbb11b1d6d46b94a8a0cc197b6ee007c9c0efed730ecf8cc", + "2997b89eff376474fa8e9ef60918a3b054e9247db6bfcadb420875df311e088a", + "138866dbc397fcf71e9fc4cecb0cf9684594e4d466183ba8334dfb740b7176de", + "f7badfeabe2a5ed7885d960c64af216f14cd77abcf63292a08329c6631c6413b", + "0dfac219c7bb1faebe56dbfe2584e5eecf5c96ac5073ea7f846f9a6cd3cdcb70", + "e4848b53eef5971588715be6ae7c468fe87b7485f7d7fdfadeec2c312ce1652e", + "d5411d7700d59f00f41c45f1508d5d31c63e019c590cb24f0c4b742b115f966d", + "015764d4c7bfd5396daf7e40b2a93e630610c6ac17e5906b9c3128712df77d85", + "e6b07d2a843b2fcfda8f058b927520cc0a98ae69c7ab8137dc0cc5cc5e9634f8", + "75769103c03a692f02e4a07579ad3e41249bf1e3b37c6c14e9b847bbf1c935dc", + "245040b864f5777adf0214642e7101d00fd90c0ff307231e4e32bc9f3ba8c558", + "3dc2c7b640add73265428552cea7254db5134bb437b5e42a3428b639618e82fc", + "01db4b7f7b576f1d83ce37d39df2bc992eb36942b7f502182274c1028bd890f1", + "137203fcc01396bf5b78715fee887f148e08025418c3cab8c4292a4b9586164a", + "f1cedd9eeb8293c613d8782dfeec80583dd5abdda1e5193af8219e87bd87c81c", + "f78ab9a31d0bb94e24d69e85f4a5ea0072b76af3ac808b2ac512b8ad5c6d2ae5", + "62674cfb29a5a899774508f05629a83f67a57919072914def2e9a61e9f286bf9", + "d02c2cad0d31c0528bf6b594be79efdae4343c1a4c92743a679140beed47d972", + "295e716da3b8a0dfe711ebf1c89313e09da4c3b5ec739d49af9b62114123363f", + "5a1240b10fa28bb7bf6ff1b78cab7eccfa699e1c17068b93b3102c20bb06202f", + "4534641f1328d21b864230624c1c514104ac5afb7d2436be1a4f8e1968754608", + "98cb1a2a3157f679be4e2e0847b9f0379556b13413046f954c8a0c23595a0174", + "99fa44177288555cb219a8a4f93f0d602e48dd4216df114b5dc35bd2de64269e", + "05501df6c13513b190c8f5fcd10ae40436f347b6a9278b9df28dd25ecbb20330", + "446c46f2738f63c5bb9957e1ca0f8326bd02f9779b0b8829179bd6ea0065bd8e", + "d6bfc0cb61cdcdab1717493e7d4fb1266d2af2cbb6fe9c59ffb0f0ed05d1f201", + "8de7121a93d1f71c7ec182578768562c4db42de981a31c7736c94e2f457b2cbe", + "3b67ac1134585867e0ff46aaa2dc76bd7eb8adc3a957c845115b6c4e44660605", + "96249f8074c4a36b5fbc2a378206649acb0225ddb2e2533ea165c709c92f90be", + "3aee956381f9dad6d1834fb051eeea50709a1e1f6d3b5a6e3c1198d466d8fb93", + "a34885111bdf398f5ad36b1fb1d20a7f426428d457d69999ece04131be8be613", + "eafe46941163b2c2c71e07fd49d5d5377b12e2a4498087ed7fc8165451d52478", + "ae2c5f65eda30edd8ce1da0ce8d80d5930dd5c61ab72ff094d72cd6999ec830b", + "16451ffee3cd3f2b910a0c84a25488f3f1d210b8ca3fd75574d2f02dcd75a51c", + "d27fb97a16af28203008b483128be9091dca3da8a5e6142d6536b6d9efe096ec", + "f9b3db4e8005b751a73b87f6efceea71190c5f246eabc66d88b1a639fe57badc", + "453c3e2212a420101b7aceb9ce74e69378618c2a5df55d5d14d65d258f57fa67", + "2e11e43dbada7fad2ddfa76ac4a117ebb1267aaba1fe374fec44bec34c5dab29", + "ccda6c7f29f0f85168f97300654a6dca4b2e68471a499b36e8c9d038eb181dda", + "b012f3812f2c5a9947deadb0ee4f23907a59810428fa84120ee700c542b60a34", + "8af63755ced5db7601b911f1ea8f34861697199761723c87df9882f8ecb4f60f", + "8d1463edb018d0fc35e35ffd6c5e9870166dff8d35b68d2c0b8f733a735fcd61", + "69053c30939d244f1c223b751b3d79f747697a7b3f35d0e65b6e10cbb2de8a5f", + "8c69bcf1a176647909fa5b371ad989ef130773eb6238f9ccba629cbed586ea53", + "d31018e63300d9410ffed639209cc15c891ae171ad65150467b3039829f19a6a", + "d2fea8f9154b789b979751a3ee7a87f368996853507b151bee92e29c09e14d95", + "5f8e18f19d2b9d4cb45ec188773b225c660b11939505c1b38a2109fbe9a71a93", + "b9f7eb84a7dd077d3eb9412ce93848c0b0d33512094d8327b699305b7263ac06", + "8eee7104fdf5781b70fa2b2ad175f5bf117ff59cd1c63f874bff641d21fb575a", + "bb3fc8bfd326706d8a340402d82e4fb0657637ecca53894cc9aa61eb2d48de4a", + "0868ed5f7f47813e2e5b836614bdfd1481f30442dc6fb1062ca03a2712bb5d87", + "c5e013e16bb53a049f7bdbede268caa3a354c698f4c3ca21843f7bbdd53fed04", + "9679503732b982699dc5f6ceb528d4425edc8837c7ec5b3d65ed74f90afe8e9d", + "5e5c0d518eed5d7cba6f329385ab94d442c621f74bc582151c99f27c716bd952", + "fd52cb171520d22eb011a57926c28607e2162efcbd395cfb4d1fe97cc0c235c8", + "ce6425e6c5f73821356801525eb3ad89f2b301045bcbc513fcc356f951021670", + "193fd31f561e2f3963a44a395ef46be1e8f28208a7a70bbabc04a60bc78005e7", + "c78d4e6bfac088e33c3bf32697e568808464a9011d601044d93945a543d6f7d3", + "47807a3345a137d6de964b45080d39aac9795483f643d45ac5310973d24bdeee", + "d2159ee7cf8289bdf94e30924712e1d72e351e43c3b688888e6cda6df5852940", + "21a52c93279aa62dbc2dd4c9b237f58d751d224f4fcf53ddd6d1abb006ea94fd", + "8a056fa6651b296b4430ba649a725f50f367877b77a309e7bbb9a62754e68883", + "bdeed6f1168d749fa360a119f81eaf3c6ca2a7ee106717b3c894d6e0d07f8727", + "314877cb55bdc7c07ac543bd0e47ea8077268072be76bbab389653a7d7041a0e", + "99eb5165b486b9b5a2c8850c927b6ce0b7cb71670d9c0bfeb66b1e2485b1f8b3", + "566fa61ba01030b7ac5ffa425e7e5e9ab0b8ec2486d89b70d35c452fda13941f", + "d93fa8c956c993e837f150eaf47c2f339e47e9b23e203699a16c51a2fc50c332", + "5f328eb4e674b2911c679fe3ef21bf744c2df28a461aab701b2edcc7e24dea2f", + "6554dc9841656eebb412b36440f8e5ed544cc773d130909a73c24e97b00cc3dc", } -const ropstenPreverifiedHeight uint64 = 11437824 +const ropstenPreverifiedHeight uint64 = 11468928 From 9f23c1e063f64bcca54cb976b058c1e48cdf1525 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Mon, 22 Nov 2021 18:36:57 +0700 Subject: [PATCH 037/261] save (#3016) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 3d1e59c1720..a2df3c7e0d7 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20211116105337-347396fb51eb + github.com/ledgerwatch/erigon-lib v0.0.0-20211122022334-d32c0b933041 github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 diff --git a/go.sum b/go.sum index 72d28186a57..190d82ae223 100644 --- a/go.sum +++ b/go.sum @@ -497,8 +497,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20211116105337-347396fb51eb h1:Y4PO0v++1SaT3DoD+dRhgn+ggYq7m7Gk7NYN67nDQdI= -github.com/ledgerwatch/erigon-lib v0.0.0-20211116105337-347396fb51eb/go.mod h1:CuEZROm43MykZT5CjCj02jw0FOwaDl8Nh+PZkTEGopg= +github.com/ledgerwatch/erigon-lib v0.0.0-20211122022334-d32c0b933041 h1:RW9F5MGxG0tYclcy8Rgp++RkiiiuDifD07kcjZfbUkg= +github.com/ledgerwatch/erigon-lib v0.0.0-20211122022334-d32c0b933041/go.mod h1:CuEZROm43MykZT5CjCj02jw0FOwaDl8Nh+PZkTEGopg= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= From 74b6fab54489eeeb51ebe1b3c4fb934b002b2d81 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Mon, 22 Nov 2021 20:07:31 +0700 Subject: [PATCH 038/261] save (#3015) Co-authored-by: Alex Sharp --- go.mod | 4 ++-- go.sum | 8 ++++---- libmdbx | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index a2df3c7e0d7..1e57d0bc47d 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20211122022334-d32c0b933041 + github.com/ledgerwatch/erigon-lib v0.0.0-20211122115051-9ad8e21b43fa github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 @@ -47,7 +47,7 @@ require ( github.com/spf13/cobra v1.2.1 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.7.0 - github.com/torquem-ch/mdbx-go v0.22.1 + github.com/torquem-ch/mdbx-go v0.22.2 github.com/ugorji/go/codec v1.1.13 github.com/ugorji/go/codec/codecgen v1.1.13 github.com/urfave/cli v1.22.5 diff --git a/go.sum b/go.sum index 190d82ae223..232e824969a 100644 --- a/go.sum +++ b/go.sum @@ -497,8 +497,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20211122022334-d32c0b933041 h1:RW9F5MGxG0tYclcy8Rgp++RkiiiuDifD07kcjZfbUkg= -github.com/ledgerwatch/erigon-lib v0.0.0-20211122022334-d32c0b933041/go.mod h1:CuEZROm43MykZT5CjCj02jw0FOwaDl8Nh+PZkTEGopg= +github.com/ledgerwatch/erigon-lib v0.0.0-20211122115051-9ad8e21b43fa h1:Pa/OycJVeTo5UhUQMaIwXnX6j5rZ2Y6JzN7t26dhMfI= +github.com/ledgerwatch/erigon-lib v0.0.0-20211122115051-9ad8e21b43fa/go.mod h1:lyGP3i0x4CeabdKZ4beycD5xZfHWZwJsAX+70OfGj4Y= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= @@ -750,8 +750,8 @@ github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs= github.com/tklauser/numcpus v0.3.0 h1:ILuRUQBtssgnxw0XXIjKUC56fgnOrFoQQ/4+DeU2biQ= github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8= -github.com/torquem-ch/mdbx-go v0.22.1 h1:2KN/5f5O8a6xJRmBVqXJzTUuZ+3nmqqCAkKhVnpBILs= -github.com/torquem-ch/mdbx-go v0.22.1/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= +github.com/torquem-ch/mdbx-go v0.22.2 h1:wl/eJaZeKqsqObfzXAurYuPozr4hkopJ1hELHXH+N8w= +github.com/torquem-ch/mdbx-go v0.22.2/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= diff --git a/libmdbx b/libmdbx index 113162b6511..e93d53ed923 160000 --- a/libmdbx +++ b/libmdbx @@ -1 +1 @@ -Subproject commit 113162b6511e1de791599ac87914930a1f6b02ee +Subproject commit e93d53ed923670b87acae9b40c2f3176f2756e2b From 0ff160c7382fd37880d4b1b2336e7b24087d67ee Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Tue, 23 Nov 2021 08:12:15 +0000 Subject: [PATCH 039/261] Fix atomic peer height update (#3019) (#3023) Co-authored-by: TBC Dev <48684072+tbcd@users.noreply.github.com> --- cmd/sentry/download/sentry.go | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/cmd/sentry/download/sentry.go b/cmd/sentry/download/sentry.go index a5096d6c7dd..0030d6308d3 100644 --- a/cmd/sentry/download/sentry.go +++ b/cmd/sentry/download/sentry.go @@ -67,8 +67,15 @@ func (pi *PeerInfo) AddDeadline(deadline time.Time) { func (pi *PeerInfo) Height() uint64 { return atomic.LoadUint64(&pi.height) } -func (pi *PeerInfo) SetHeight(h uint64) { - atomic.StoreUint64(&pi.height, h) + +// SetIncreasedHeight atomically updates PeerInfo.height only if newHeight is higher +func (pi *PeerInfo) SetIncreasedHeight(newHeight uint64) { + for { + oldHeight := atomic.LoadUint64(&pi.height) + if oldHeight >= newHeight || atomic.CompareAndSwapUint64(&pi.height, oldHeight, newHeight) { + break + } + } } // ClearDeadlines goes through the deadlines of @@ -639,9 +646,7 @@ func (ss *SentryServerImpl) PenalizePeer(_ context.Context, req *proto_sentry.Pe func (ss *SentryServerImpl) PeerMinBlock(_ context.Context, req *proto_sentry.PeerMinBlockRequest) (*emptypb.Empty, error) { peerID := string(gointerfaces.ConvertH512ToBytes(req.PeerId)) if peerInfo := ss.getPeer(peerID); peerInfo != nil { - if req.MinBlock > peerInfo.Height() { - peerInfo.SetHeight(req.MinBlock) - } + peerInfo.SetIncreasedHeight(req.MinBlock) } return &emptypb.Empty{}, nil } From 1ad08aa261603ac048d3603df363e643f54b13fd Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Tue, 23 Nov 2021 16:23:35 +0700 Subject: [PATCH 040/261] Pool: fix validate order (#3025) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 1e57d0bc47d..47185bce1c7 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20211122115051-9ad8e21b43fa + github.com/ledgerwatch/erigon-lib v0.0.0-20211123092026-7d9918deb304 github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 diff --git a/go.sum b/go.sum index 232e824969a..0d9dcc2218b 100644 --- a/go.sum +++ b/go.sum @@ -497,8 +497,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20211122115051-9ad8e21b43fa h1:Pa/OycJVeTo5UhUQMaIwXnX6j5rZ2Y6JzN7t26dhMfI= -github.com/ledgerwatch/erigon-lib v0.0.0-20211122115051-9ad8e21b43fa/go.mod h1:lyGP3i0x4CeabdKZ4beycD5xZfHWZwJsAX+70OfGj4Y= +github.com/ledgerwatch/erigon-lib v0.0.0-20211123092026-7d9918deb304 h1:0HC+NMIJ6YZTAryzt/xXGVnLN7JY47l+5IUX60E68E8= +github.com/ledgerwatch/erigon-lib v0.0.0-20211123092026-7d9918deb304/go.mod h1:lyGP3i0x4CeabdKZ4beycD5xZfHWZwJsAX+70OfGj4Y= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= From ec4eb2632d7342593734dbfbb08fa4cad3ff231e Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Thu, 25 Nov 2021 05:51:11 +0000 Subject: [PATCH 041/261] save (#3031) (#3032) Co-authored-by: Alex Sharov --- cmd/sentry/download/sentry.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/cmd/sentry/download/sentry.go b/cmd/sentry/download/sentry.go index 0030d6308d3..01bb43b7ac3 100644 --- a/cmd/sentry/download/sentry.go +++ b/cmd/sentry/download/sentry.go @@ -328,10 +328,34 @@ func runPeer( } send(eth.ToProto[protocol][msg.Code], peerID, b) case eth.GetNodeDataMsg: + if !hasSubscribers(eth.ToProto[protocol][msg.Code]) { + continue + } + b := make([]byte, msg.Size) + if _, err := io.ReadFull(msg.Payload, b); err != nil { + log.Error(fmt.Sprintf("%s: reading msg into bytes: %v", peerID, err)) + } + send(eth.ToProto[protocol][msg.Code], peerID, b) //log.Info(fmt.Sprintf("[%s] GetNodeData", peerID)) case eth.GetReceiptsMsg: + if !hasSubscribers(eth.ToProto[protocol][msg.Code]) { + continue + } + b := make([]byte, msg.Size) + if _, err := io.ReadFull(msg.Payload, b); err != nil { + log.Error(fmt.Sprintf("%s: reading msg into bytes: %v", peerID, err)) + } + send(eth.ToProto[protocol][msg.Code], peerID, b) //log.Info(fmt.Sprintf("[%s] GetReceiptsMsg", peerID)) case eth.ReceiptsMsg: + if !hasSubscribers(eth.ToProto[protocol][msg.Code]) { + continue + } + b := make([]byte, msg.Size) + if _, err := io.ReadFull(msg.Payload, b); err != nil { + log.Error(fmt.Sprintf("%s: reading msg into bytes: %v", peerID, err)) + } + send(eth.ToProto[protocol][msg.Code], peerID, b) //log.Info(fmt.Sprintf("[%s] ReceiptsMsg", peerID)) case eth.NewBlockHashesMsg: if !hasSubscribers(eth.ToProto[protocol][msg.Code]) { From 1521b079aded713ac70d7e9419de1734e0253b88 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Fri, 26 Nov 2021 10:56:56 +0000 Subject: [PATCH 042/261] Bump stable version to 2021.12.01-beta (#3036) --- params/version.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/params/version.go b/params/version.go index 99a4811486a..e0126036dad 100644 --- a/params/version.go +++ b/params/version.go @@ -32,8 +32,8 @@ var ( // see https://calver.org const ( VersionMajor = 2021 // Major version component of the current release - VersionMinor = 11 // Minor version component of the current release - VersionMicro = 4 // Patch version component of the current release + VersionMinor = 12 // Minor version component of the current release + VersionMicro = 1 // Patch version component of the current release VersionModifier = "beta" // Patch version component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" From 9307f0d8c176a4ea3f705e6cad2348e0417f257f Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Fri, 26 Nov 2021 14:32:21 +0000 Subject: [PATCH 043/261] Not try to create temporary file with enode (#3035) (#3037) * Update server.go * Update server.go --- p2p/server.go | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/p2p/server.go b/p2p/server.go index 3ab28b2c67b..a8c07527391 100644 --- a/p2p/server.go +++ b/p2p/server.go @@ -23,10 +23,7 @@ import ( "encoding/hex" "errors" "fmt" - "io/ioutil" "net" - "os" - "path" "sort" "sync" "sync/atomic" @@ -68,8 +65,6 @@ const ( frameWriteTimeout = 20 * time.Second ) -var EnodeAddressFileName = path.Join(os.TempDir(), "enode_address.tmp") - var errServerStopped = errors.New("server stopped") // Config holds Server options. @@ -718,12 +713,6 @@ func (srv *Server) doPeerOp(fn peerOpFunc) { // run is the main loop of the server. func (srv *Server) run() { defer debug.LogPanic() - if srv.localnode.Node().TCP() > 0 { - err := ioutil.WriteFile(EnodeAddressFileName, []byte(srv.localnode.Node().URLv4()), 0600) - if err != nil { - srv.log.Error("Write enode to file failed", "self", srv.localnode.Node().URLv4()) - } - } if len(srv.Config.Protocols) > 0 { srv.log.Info("Started P2P networking", "version", srv.Config.Protocols[0].Version, "self", srv.localnode.Node().URLv4(), "name", srv.Name) } From 9edf695a471705e6ef0e238e4bae90ffed331656 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Sat, 27 Nov 2021 15:53:55 +0000 Subject: [PATCH 044/261] [txpool] Introduce PriceBump, change tx replacement logic, add test (#3039) (#3040) Co-authored-by: Alexey Sharp Co-authored-by: Alexey Sharp --- cmd/txpool/main.go | 3 +++ cmd/utils/flags.go | 3 ++- eth/backend.go | 1 + go.mod | 2 +- go.sum | 4 ++-- 5 files changed, 9 insertions(+), 4 deletions(-) diff --git a/cmd/txpool/main.go b/cmd/txpool/main.go index cf71f9d903b..d06d7e13e48 100644 --- a/cmd/txpool/main.go +++ b/cmd/txpool/main.go @@ -40,6 +40,7 @@ var ( queuedPoolLimit int priceLimit uint64 + priceBump uint64 ) func init() { @@ -60,6 +61,7 @@ func init() { rootCmd.PersistentFlags().IntVar(&queuedPoolLimit, "txpool.globalqueue", txpool.DefaultConfig.QueuedSubPoolLimit, "Maximum number of non-executable transaction slots for all accounts") rootCmd.PersistentFlags().Uint64Var(&priceLimit, "txpool.pricelimit", txpool.DefaultConfig.MinFeeCap, "Minimum gas price (fee cap) limit to enforce for acceptance into the pool") rootCmd.PersistentFlags().Uint64Var(&priceLimit, "txpool.accountslots", txpool.DefaultConfig.AccountSlots, "Minimum number of executable transaction slots guaranteed per account") + rootCmd.PersistentFlags().Uint64Var(&priceBump, "txpool.pricebump", txpool.DefaultConfig.PriceBump, "Price bump percentage to replace an already existing transaction") } var rootCmd = &cobra.Command{ @@ -112,6 +114,7 @@ var rootCmd = &cobra.Command{ cfg.BaseFeeSubPoolLimit = baseFeePoolLimit cfg.QueuedSubPoolLimit = queuedPoolLimit cfg.MinFeeCap = priceLimit + cfg.PriceBump = priceBump cacheConfig := kvcache.DefaultCoherentConfig cacheConfig.MetricsLabel = "txpool" diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 6dfef4b1eba..ba76ea39a7c 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -31,6 +31,7 @@ import ( "text/template" "github.com/ledgerwatch/erigon-lib/kv" + "github.com/ledgerwatch/erigon-lib/txpool" "github.com/ledgerwatch/erigon/eth/protocols/eth" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -181,7 +182,7 @@ var ( TxPoolPriceBumpFlag = cli.Uint64Flag{ Name: "txpool.pricebump", Usage: "Price bump percentage to replace an already existing transaction", - Value: ethconfig.Defaults.TxPool.PriceBump, + Value: txpool.DefaultConfig.PriceBump, } TxPoolAccountSlotsFlag = cli.Uint64Flag{ Name: "txpool.accountslots", diff --git a/eth/backend.go b/eth/backend.go index 93a546ec6dd..ec8a762447d 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -326,6 +326,7 @@ func New(stack *node.Node, config *ethconfig.Config, logger log.Logger) (*Ethere cfg.PendingSubPoolLimit = int(config.TxPool.GlobalSlots) cfg.BaseFeeSubPoolLimit = int(config.TxPool.GlobalBaseFeeQueue) cfg.QueuedSubPoolLimit = int(config.TxPool.GlobalQueue) + cfg.PriceBump = config.TxPool.PriceBump cfg.MinFeeCap = config.TxPool.PriceLimit cfg.AccountSlots = config.TxPool.AccountSlots cfg.LogEvery = 1 * time.Minute diff --git a/go.mod b/go.mod index 47185bce1c7..6217b67d86c 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20211123092026-7d9918deb304 + github.com/ledgerwatch/erigon-lib v0.0.0-20211126140914-20cf6326808f github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 diff --git a/go.sum b/go.sum index 0d9dcc2218b..8e9b26034f0 100644 --- a/go.sum +++ b/go.sum @@ -497,8 +497,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20211123092026-7d9918deb304 h1:0HC+NMIJ6YZTAryzt/xXGVnLN7JY47l+5IUX60E68E8= -github.com/ledgerwatch/erigon-lib v0.0.0-20211123092026-7d9918deb304/go.mod h1:lyGP3i0x4CeabdKZ4beycD5xZfHWZwJsAX+70OfGj4Y= +github.com/ledgerwatch/erigon-lib v0.0.0-20211126140914-20cf6326808f h1:+UndlhFtwMGAtjcOHbftwTcRh8SErgJ4eN+7efsxogw= +github.com/ledgerwatch/erigon-lib v0.0.0-20211126140914-20cf6326808f/go.mod h1:lyGP3i0x4CeabdKZ4beycD5xZfHWZwJsAX+70OfGj4Y= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= From 5bf7664f644f3e690eeda74d0f310314dedddae8 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Mon, 29 Nov 2021 08:54:31 +0000 Subject: [PATCH 045/261] Update skip analysis and preverified (#3045) (#3049) Co-authored-by: Alexey Sharp Co-authored-by: Alexey Sharp --- core/skip_analysis.go | 2 +- .../preverified_hashes_mainnet.go | 226 +++++++++++++++++- .../preverified_hashes_ropsten.go | 225 ++++++++++++++++- 3 files changed, 450 insertions(+), 3 deletions(-) diff --git a/core/skip_analysis.go b/core/skip_analysis.go index 9d46120cc8b..57e1ffb5921 100644 --- a/core/skip_analysis.go +++ b/core/skip_analysis.go @@ -21,7 +21,7 @@ import ( ) // MainnetNotCheckedFrom is the first block number not yet checked for invalid jumps -const MainnetNotCheckedFrom uint64 = 13658800 +const MainnetNotCheckedFrom uint64 = 13701900 // SkipAnalysis function tells us whether we can skip performing jumpdest analysis // for the historical blocks (on mainnet now but perhaps on the testsnets diff --git a/turbo/stages/headerdownload/preverified_hashes_mainnet.go b/turbo/stages/headerdownload/preverified_hashes_mainnet.go index a7d3057307a..ada76c45fb5 100644 --- a/turbo/stages/headerdownload/preverified_hashes_mainnet.go +++ b/turbo/stages/headerdownload/preverified_hashes_mainnet.go @@ -71142,6 +71142,230 @@ var mainnetPreverifiedHashes = []string{ "95539489ece7e5e364fb48fe88f64f72c5598570ebcf6cb4974858cb773585bc", "017ededd30cbd8a92bf1d41c243a7e01bce8f68d1682083aa9a1e82fb7ab4630", "7ad7f720fad803769fdfe7c18db89e5ef7e9bd202415c4ea391a2933bf41194e", + "97286d78fbde4d263e330d46e727f02adab976bdc2780631a6f7bb56917ac45f", + "ef88dff56cf5a8819b1decd72e9f26b03c3bda4d02d3eebb4a46b748ea62f64a", + "07ab5cf582d93443a4a2bfc08d5ac1d923bdb6ec8fca0d90555a868e1cd00654", + "81e13561335c3d828c7b4a205da2c558fc91662eff5f2371f97b818dcaf4b60a", + "4ada96aadbdcee8a7296da93106cbf54740fc256838df626167910d5685865b1", + "a9cf53dc4343ea6624e9a069537aebfc80ef657cc3f0e4b46d7446a0903824d3", + "87a536d4b84b5dc9301dc9e98c3a7ab1fc6c82b53a8889b0b3d89350cc64c6de", + "45d5ab0228c6cebd181ed9b093167895be7a44dbf0cb7bd5919b3067376455aa", + "39abffc8d9afe6241c62d9548746936c936c1014097baf00cb5e3b2f0b4eeabd", + "1d45fef6f3ca7101b8f68c2aa3963f299520fe59af42c067e8fda9146e6d2170", + "3f4c09314164edf5c346dcd3747e01895524f2349107b73404257c85aaca9770", + "1f230347c29145d60cb9143cdcd491c7bc4b39b7923d400dd2b865a7834d8123", + "f2db33336287bdfe730eafae5e6e4657c64a04e41bcb1403197406837d3c8763", + "933a26363ead9c4905f7f3ab87fcde151e72273d75d87b73520b270b507afe9d", + "4234fb00adcf20a87f28f6cc7e298efbed15b455186c467202882997e618b5b6", + "09e3524890f8fb5e092c6f3f163f6a2fabe885458dbaef399e924bc956a2680c", + "50cf093e1411f990de574611b330104358600277c30c01b840597acea8334e68", + "c36e111de39d17978c1a603b1b1524692ebc6dd12046251f4f415d3832743338", + "732726864cab7f9e568f566d938478631544b79c6117b5c273cb0cb468690451", + "9fb2fc5f793d42df87e38a2b1c6ae0903a32804785a8777cfab9280dd28e9a88", + "84098f47c47ffdd4ec49c1ccad56e36391a350f1b005adffe13580c1fe164c63", + "9b4db9e2a0b6803f631185b23a6899f8a6b5ce0dbfba105388cc6929deb11247", + "f3b46d91cd53021052a12d6f4d52770b337e0a3af0e8e8667101faf70b373490", + "316b12d00210f14d1a317ca15b1b8dcc6996d103ed772886ba92885958db30ed", + "1a2f16612895e5efb90f5615e11799306b8e1369a8cdf188a5c26f8e8c2d1bad", + "3d074677329f00b2c812bc374aae6345721e2944239c454e6adc27be7a27ab18", + "9fbc006df5d110a02cb215fdf7d64f485034afa48bf61309d5284c49cb289dd5", + "cdeed10b352638a2202399a89763639e3dabd66ec0d61d30cc77130a6e22a231", + "82a51ba0c1e2cd8f75f51c3213733da84426a5da057672611b3707e1fde0b547", + "6c14d6d8d0fde29265e1c69c7fd33c4392eb89756f32b96b1b3de76459e1cfb9", + "01733a2c0196100ea8b465d2b5c05bf3ca158713d327cc78a9d7f07af7441acc", + "4709dd31be25a9ec2f13dc2009e5b3099fab542286e4118b9e12f8bc14848129", + "8ffc7c3e796a297328328981ba7255e694717037701083144cf62515c0f1c285", + "b370f3c1dec0a53a0ad133ce56676a91de800312e651716a464802561a3d5e9a", + "6bb90d192a6c0bf7647eba2cc58a2768b910b3dbf1fe51e89d6d5f111632f5b8", + "23911655cd07149bd19cdab4a2ca2a198316de3c2f2a10af8724e316ec8d547a", + "c2eefd8f9722a8a61fe890b13ceb44d88f91a09906c3f71b874b543a8d1ea90b", + "7ab964f5ed2977e6d687315460a4fa88b33b1f4cb44c35c704e1fd67a648a3a3", + "936a522279f723b2823e6dbd680ed4d23e6b73bf4a4ecb9c79ddb33bbfd6da5f", + "443534c69a5a037a210d64f6e7bcd389d3703ec0d4f4ada398ceec6150c061e8", + "d40ad368229696abb3bee3cc112c0f1758219c7c6eb716930d8129b600b50ec7", + "22535a8413cafd44acdf2c6ce64e2285974af29adf21620db2b4fd9920411c09", + "e8c8582f1a5b08ee6e4b5445ca6bc85361c0cd1d52c26ed873d178abe4268118", + "1b5bbd8c60d68aed9d9946e16ca1e6b09094524b821477f8094a078a09cea7a1", + "f404cd2e9338322d00bc1c3d2013a9961c95435b99f434cd2368864c35f6aa03", + "55426a8e45d48445f41890669184d256521bc8f3ea4abf5a687db0b92cf5c687", + "4800b0e9a1bc72d1778c2d1b20e927952c06081130a439adf868b6afaffa0162", + "94197a8f073bd4636631654ab9fbcdc97187add1a4105293b25b623634a1f7b5", + "451cb84610d79dd49738b2a95658818328b67f6032e8ee982e1458fe2e431961", + "580ba5b305759b41a0ddc13db339c7fcc38fff89fe64506e9fd6c06ede9f7be8", + "02f952a4e9b0dd4986e5c120d88c3818001c710bf7f1bbd17732cd96d107e2de", + "1e52a1511bdd61f3c3d2af165f7a608342bd9cbb6d4a77e240f9da25e3e8ddd0", + "98ba8e0ff180910a8675a89c71f0b914ba29c142d245f820d285b07c40d8faa8", + "f2e90114f445190120a20461d892ce0f9a24737bb4557fd9bab6594a10f7c7b1", + "c5992f079f757a05117f9e6fd2d1bb7d9eb02e594de73192aba6f935a91120bd", + "32a6588ab12ac74b2298c4122e66ba45e5af9f65b7b9c0b0dc5818001a5f290b", + "86ee1cde6b8a51d247ad5cd825f3cd12703121df160578a3aa119b907644e9c0", + "0a93b34629377f36dbb014f2bfcce100d476d00f9eb261508525d5bbd65c0e30", + "2cb53f41c8a3d57078f94a22c5472c736956a83da8dcfdebcab4111da80785f3", + "e3924c556589b54f5878949d7c4a58e3e6374d75d5334301b2606e47a4b5dde3", + "4c5f7796612e0a9beb96cb2a442c4309462b28e06d2058d16b3075f4ead6052b", + "5a292ed732389e6465d1efdecffac8667a1851b5f2c8ef55363734f4550eaa53", + "cab20867cb83377b6ab323ad6f959217ae38550503b0df2a1e4efe4152251fa2", + "959634873237107dfd320d50efe134feb42a1cde96b3dcbb1034ad3dd8aad4a9", + "2067485353e6f1f448515e427db40f5da69dd42a244cfa20b4ea6e53a9452c40", + "3d0a5f6a21d33f3f5d98f72f15fdeadd73ef607f50b96f647584cd4aafafee48", + "1494f03c0e8b2f0b40d9a693b298143e1605e91b1798c8d3d692f47ecab3d42e", + "b9dbbb191bccc65e15a1f1e969cc3a2ea50d8adf7c1b0f7b573fd8027b2a7da7", + "aa70780d549ada79123a9d5555d2c427a0f5e82eb8b5d96835e6e6a239ee3e00", + "209676a0e93938a38fcf7b871da5d559e5693e71c166a5eeaa09bb6b795ff2c7", + "aa80568f93175509016eb7d516e907c07d10f305b9909f2fa1abeb8d70dd1747", + "8f169d45e30246335599f83c3e9bff0038152d7000812f80d16ba938d71efb3d", + "7c64c54b61aab08e301631591e5e6a80673a316412912663c2c4aa34ae1db14e", + "b5f7df444132d70ff45cad5d4e390cccde6a854a0386abe907b2e135b248dd02", + "421f1801ea7aa3204c46c1df9b401f1ea88f109655371bd3cb9d761f92129109", + "e3addbdcea9bb9bde6bd97df546bd8383630e6f95ca6642256a8f95c1e0d7509", + "05bf7aa67a2903e933981c54ffb0036e39f67ba49c41292d60e9b1ca23f55469", + "402bd4df233777ac1fa261fd00cc734a36f8ad1219238a2d474ce06cdfe57576", + "801f6d2bc1bec1f19cec9741cddb2685dfcb7044890fcf8f1ecc8dfda71a3411", + "2d1ef449c699d40baf83c5d23ba3cc35fc667d932bc54d81e2e699e91963950f", + "d12d5adddc680e5ceef6740fc2459c4735f82ec2ca5d2e5d2d9d96d9c1c37387", + "5c8072d197eda9fd443f0729369c20ace1bee908978a72a0220b153506fb4c26", + "7d4e989c5a722b604b24dede860f8c4251754d28e8b57edfb3769e648fa40b11", + "62567435e085d035145a781cb3bb7dcca6fb9856749e1b29d2ef840ec2ad5ebe", + "b7c304a8632dac5a30c61666d432c86fdcd4aa80b38de315e48452495cbbf417", + "c59c8d0a07132a45dde1f6322ffdbb782e56fab9d0d5a083b0a052e5dc379445", + "c04ab1e8be794c6ec3ece4208fa9160014c82d6fb00abfec83d6d6109edf751d", + "43b98f8cc0378ad75cc00a2988eb956829c7a7800001138ecbf2cebb240ddce6", + "4bf903378136365d687d41cc2b1368ec28bc516d41d28aa1aa2774109dd1028e", + "6ea7dbcb6ef2c2b151ebf09eb6f7456c04788917bec89fe214f7be73ce555a4b", + "6efc519dc9a60c28d49eff8577654d834dc0ff46494452dac2fcc3d8008620d7", + "51e98a96d78007b354294d2cad4a72fe0aba459912f58c57f3adec53fddac34c", + "cd794b638935f17f8b44773a5aa9b4bf79c90558f4e5113eed328a1bb36ad3c5", + "146de79cef55cec13e3d0e0ad73dbe2d4ba3fea5bb1fb1a29049a4e46b0a6486", + "38744fc6914932534d187c4c3991bf1376674715c5c07b35e2874edc1618b9f0", + "88a53ce2b5417a6caa7db69ac03273d22f446907c4d362c002f4a4f03ff891b7", + "f1c015c36441f71a02d3f5a88c3789676a888945387a9b7674a22568c6638ed9", + "9ba013ecdd1f8cc10261364434b6a99f7c8fdbb15e7d41022a1431aa83dca372", + "235c0cee98a22379dad74872d04dec9fd912e24695d82695e5adbd8cc599719a", + "eec9574e8b775a5a49e0e37123bd0532931eb3c379193305155ad4d333702c08", + "a8dc50179d4a44a33457f60b7b28706726236de455236f0ac29a7c082d956ddb", + "541bbfaee6ddf23f3c071995e2f6b05cd9768f623c177121cb3a8393dfe2c758", + "0a5764e61e414217117ff9fb676e1129ff727c4b1771000b1c607864f7a143f6", + "a16930da77ff9b6910a10cc44278b8a78fefdf6c5b2cacc7a7f9312c4848767f", + "8af999e516844a3feb09af2ee376f4465fbdee43d1f1ec77b40c99647344ccee", + "77eb9ac23f479bec1dd15875e71e60eb49515c178f48238ac688bd6577f4d4d2", + "9894ea7ec65af6f92ea81bf95db181d450c1152d929652d8e0cfffd1b12209ed", + "f937780e551f61072482430bf8a3261e339f7ad927b9c690d3fcfb585feaf268", + "b57073b87d5c89327208373ad3c08e9621cdaf4656bb3df7ec7cee7e9e2a0f58", + "941cfc3df90ad5e4a68becb123943c69b5d67812132b67ee2c9473ef6fcc96ea", + "989c6fb6e86b9979a124695769acc844a5836104c098bc808175ac08ed9a658c", + "445e8bd84c3b40b264ecf9a93936bed56b32c0113e9f903af84968b26fa17c81", + "cc28836e8869a4f24ca67733d67663fcb3e66cce43bdbd19fd895db80b0768e2", + "d7b86015b48cdcfa6800b8c1b84a68bd94b2e117531857fe4b0a46f5aa8223d0", + "aa7342599473f1ec5ca7463c7ebd2cf13593c36f41a321de2c257a97fac30781", + "d90cb803a6e427662417db67593f319b4a4c91a149c055c35e3b672625ae8c6e", + "44bfc7934f15e28f8ef9fd1ad8b046a2e5e440f266399757e2ecb89d9701c62f", + "d65347431d6d5d79ec296cfd86354c61aa489e434d1c0d45fefb60d00357bf3c", + "71c90c33c3cc6b94f54252ebdbc57eb0fc6e27d636465aa9001f29c2b03a937d", + "474c5bbd269f0a84c7aa1f64394b4336cbf0c8320a748e81717ba355c1b20df7", + "e611b912abeb2630283c00144d999703429c9e38f46ddc0cf26bdb4562bfbbf8", + "a324a91bedea14527bd374d48036d948c3d2c3b07995651a9434364632e15005", + "efd2d548d1fe565e0bab1a53a375b0baacdc827de8268da3a92e2cc07913ee67", + "5717fd3d2fdf945e69231ed02e5803313019b532ff5de5c5aa3169e63a0977e2", + "a1c49f43a8089ab8ad4d629dd811a0023a9c45cc0073253acb58146b125191cc", + "9cd0ca2ee85560e9bbf9c4af99acf57d6e91f912eeff777ec6c2be9dfa0265b8", + "bc3a9be0fd49efb5e6f4307925a8fc468e5a3dbbffe9698e29fbfb7a6705f805", + "52508a2e2abb5f741076787838a440d45ebe93f414049ac8400e2f3c6dab49ce", + "27942190e82fd134ce916a15b299740cb1d1f3adb206aad306aeddef4b055704", + "be7c58a7a0ed4dc349340b6a77401307f7a0bde2e38f5dbe757e981e8fa6cf39", + "a7ef15fa81745d29518adc4d5bb83b65fcb99c646aede1cf8a18ccaf9d70fd1b", + "89d689b3b338f08936f0001bc92cc3a2cca47c83f861b292bf884b384a2b3191", + "9dd8b882e97b4a7f9b28f99ef383f230202cf7f8788257c98c5fa498071a7090", + "68ca774f7375c917e5441c532bb4692f4d091b62cd3629cb4079c71dffb9a29a", + "e04a5c5ab1549713376547660397f37b3d3247315cc2ef48197a6488e44aeca2", + "60446d3f7faf26e8ad430da027a454d1ef4d76e4db915d29b534e20d10734d8c", + "56a7394c56d2db24400acfe3f16a64531912778dbeee5980333c6059c17cedb9", + "2a1afc080782813cbbb150952a031e34f819e19a1a2b2f4ae785b65aad211dfd", + "85a71cb0a2d4ea261bcd5d460ecff083476414c30c15eca37fade9aac9d54d79", + "aebbf4d279a53a005f3fcbc05cacefa6cce78877125caa5020229e55542699b8", + "e530a171317cc9553377eac394a981ec1556cb46156d23967b27f44850bdefbf", + "f5d1c6dce98417fe0713b849024ab568ebb5fd7a865355480c0c15bab4574a6b", + "e5405a0eebbd88d86d962a40191ae3298eb84d4938e745d0a6b47b897e60f87d", + "96d5d2d4a69f656091d58705ffd8c3cae42ac331fe7d39886dd4e5a22239a72f", + "6c34e72837d5325fd3114f487b943818cd6b532264a677e34600a9502f3c528e", + "fe39fb874a567955df4df21faadf6965e4862bb9d73afc9c106988f949093543", + "6aad254266c5dbd6007f7f59f9cb92ddcdced377163ffa1b22cef3ac23bc44f1", + "7a6a6764240670cf31d415e868e25f23f9cad9f3e2ce6839b5473e61febafaf5", + "46ff5abc19dd2cd2ec18aa64a63ccacba453beb6f784f39fc281d9d91d5b21d7", + "cc835903aa29f66d321993c349511ba87272361f090ea4df1ff182ea1b1e0989", + "58528c5cdd00175721e679a5338f20af7ed77742d1573006a5fa6cfebd22758f", + "9d49fda6dfe6622e1a104a8fab5066d42e55e4569c9cf8e611f04395c7fd7023", + "5a7e3c5c41583440f5d270966c2ba34f7d9ad7a0e267648115d95bb6384f1cbf", + "e682afa09aa010e37bfe9b3de607e6e181a4885b569a9c611675b947bfeeaea3", + "60411b5d5a488aeccbceba2eab1f386cb2e7601e3d261e03272f62e3b9413186", + "57ca138d34c44f01787aaa4e0daeffeac9c8a3625979333c152118ab603b047f", + "2dd7fbbdbeb7e854cd900bf3ca1e4718675e3bf07b647a8e30aab83d719ad79d", + "bb9cde9fcb27ac3fc11934d4328ec0345b9db9c5d400ba3f144a1fd617cdc040", + "9a3e76fd2ff3e4bfefd392c496f60b1d56d6b0ee9f123b5c694d0a027d0f114a", + "94dd562579781e843611c994ba7b56e12ffa4547799d43e3a1412618950eb17c", + "dcf4dfa12c0192e3534e04ea03f61afefde0dfdae022918150abbe63460e70f8", + "b932add8938f42e55b51886ebab272152546bc6c29e8a6cb72e5537c8d742604", + "b4798691298bb547fba0fc7303b4d5cbd8974f5445269495bcdae627e4022b8d", + "c46ad051af4429920f47073eb99e6843430638f9803d1d171344806e10923824", + "b863603f1d2c5113383e33f79a6585f46f2f768c3448ff4dac16f7285deea20b", + "ad03e6e113b55fed7a161c866464611e42f266baefade71ed118b012affb1100", + "4b5b30a0d9bed676eb9b42fd5220ad4e37797c5a52f7d7885ae6e0848315436e", + "1645a34a653db29c83a353f9de4ed414378c0abf2705beec93b07c926668f4f3", + "f8e789f08959756cfbc85bf53cb06567cd5934b94357f1a01a7a12eee4b5a59a", + "faaa6bda50c8a9fe08d99eb86641d3d57aa4efd7bfc4af13f82030d379b0400f", + "db1450cb6aace2abd7e341e5788d2e44c926951511bf8b7a8ad39d684b11438a", + "47a67594fe0bbce9545fa7b6dab6fb2b84ecb798fec8eeedf61c81fa859c328d", + "dd93df2edfed369d17d62e832ba0f670a5edfe456340a815aa68e61ae3aefef2", + "7407e54c695bb8a3e67ea181f53ac24fbaa179a1c0d356f03ce5e5e28d4cb5a0", + "fc486bab2070732694c0f2acfcc4c8b66e55c6ce54929c5431b90937623e5f70", + "86fc7773ef6b4bf93682e8b6fc9339aca89b3f7aa31f4e308d2643c693a7607b", + "cece227d13746ae90f8ac6f93fca67120daba874ea73b530f4b35a0c5923566e", + "c8b44a0b5fd36a6c5001690badb8633b2f0733cabcb6d017cce902ab29ca84a9", + "381e27f9ddbbe1175616d015ecf4f3201113b6681105755dcb03ae362d610322", + "f5b82240ebd228d28a60f447a46d6320697549af42b74a3059ef6b9a804117c5", + "bcc0322611a326cce5880442de3c1d56bd4e2a1d02cafa86433fb23315fd242b", + "d25151be87d02cd4f242dc68107f723ff84a04b8700ae82fd0d1778f76992f83", + "071fc6d9318448be014a56c589bc960d86252b9e757c6154330d616220833d0d", + "2f2c8d32618ef0224f2cce5a30c9d75e3592698c19515c7ea74a4848fea24b38", + "cc3d1c64df1e4121088d8d35c0d394add4bab82fb12f6cc83248b00abad49d51", + "33ff6c86b547b3b0d412ad6bfdbaf5703bfd83f78c77cd32c6a90dda643c4eac", + "ec7b858814bcb71dd37232af231b45bb2e6c88b618db32fd9edbb7cb2a47add2", + "50740d7046e345aa0db821331213ab8c9adb6bbf0b40c990af8245b332f2aa8c", + "69243f35008a3e622dddff3e3c0ad1a8ab3574d32cc7633f90fcfa78f8a4f54c", + "bc7b25bac394903fe15b7b82938249a564bf5303d92643ef238030b5f867a953", + "048b28701a2d0dc1a490606e976c1b43db3893eb353c1c87826accfa09426438", + "ea3c90fb83dd145905cd82d7256488683da416a004db442a3b29cd30eec1ec48", + "d66e8816508bf5cd1b4abd05832a465085d31769e39362b51770ae6892d7bbd6", + "6130ee364df2d9e303c305c9f2bbdf0f30073413ebd4560cfc2a5dd275de495d", + "192529bf21add01f1e54f630d8d6eadb0f099c39002559ac2255cd5a4b4323d4", + "16c9206dfe79e52686301d7760167b3a1e0eac74693d406c72c365cb9df5bf8c", + "6f0572523c62d3d4cbfff43cabdf78395d9789b5c76ae6a7c1e16fa53d646f45", + "1fed9d1a2506b6ab30d3542ffafd6fe1f241885c00fbd435c24ed206475446ff", + "51fdbeddc4c1b9cbc99e2e81346599d5e34f537a65833d8bfaa3554a7080cacf", + "2160dc27c5246ae38e83fb10b4ce3bb283509733dac6601c3c1f6b2fcc411381", + "0c06fc7b6a4f174bd0dbafb37a5756bffe9211c576b8a4b2cb2e1c2f7006283d", + "9956563346be77562aaeac7b63354a25642164a3a3522b13933ef1661569db49", + "b03be203cca9c20ca760b886d24195271c7f6b03df3cd7e51b766b54a010373f", + "8094fa89b11d68dd039f21c10b350d6d29b40cbd1f225fd5bb098a2d77173910", + "63e035f4cfb5a89a691cd194255b53650652bdc6e644ecc903940fac46e0ea25", + "c77ae2e372224fbe38f4bde42a326a074429e9e4af81fd96d8ac69a14d65b014", + "200f6e0b30b99ec17a087c649369a51be3789dcc201640986571584e2284c346", + "9c8f788a0c0b840d76baf1f8fce3cd70ea90c81eea4e2d9296bf43075d7c4578", + "40de0270a9a9b0849bd34d69c65f229b56267063dbe164e6eb55ecd42a79e50e", + "685fb1be56d5c1c8aad99499aec4e755101746375d6ffe48a33b4cc896e1c64f", + "e81adfdd62633b51e5aa9faa47d1b1b808e3aa21783c8827fbd9d590460f0681", + "9578d86274eb6dd51fffbed563782cd925895516c4f7336857862d63b0a6efe8", + "9933c42f75d94b244a4d43869ad0e389c01d09c78cc2c2923a4b12b281db534d", + "d64fc295aa5f8e3045c5c33b9e2f64449fe41bf2f031afb5e93adc1f5f41a8b8", + "489f8509a80ef6d2c2ab5de86caa61f8ad598c221dd6d0e8a5d3394e647843f6", + "ef3012be17b164e9b42d00b6c48d020bda5cecf79b1da3fab58cc3486292b95a", + "82823f4dc602de854e522a0e07138869deab04a952f46fa7741ca15ebb567475", + "03f6f61ecc6f3d451b69d883f0c0d909b92fb20cf2b9983afc15bb61f4a74479", + "8e338e4d1b578bad65dcea97710de46d4b35ba62828a4ac7773beadb177a52dc", + "8f1473882b85eaa540a255cb63a01511b6439c41db0da770bcbc46bc27e7b4c3", + "3bf982cdccf40ee3efd22113c299ca7b7fdd55e3443a6491193a0ae4cf0d28cc", + "054ae50b17de1fa908f838a3b0e25e7e45a4e852a4e278b51b374997e2fb5e4d", + "a2f394117fd99cb2a91dfe82811f4c32303caa38a5496078c1d3c5c06bdb05b0", + "019e27d88a5466fbb927c9ec01fc012132c33b3a13a83081c144d02954460045", } -const mainnetPreverifiedHeight uint64 = 13658880 +const mainnetPreverifiedHeight uint64 = 13701888 diff --git a/turbo/stages/headerdownload/preverified_hashes_ropsten.go b/turbo/stages/headerdownload/preverified_hashes_ropsten.go index 1ba10840672..5a983b24572 100644 --- a/turbo/stages/headerdownload/preverified_hashes_ropsten.go +++ b/turbo/stages/headerdownload/preverified_hashes_ropsten.go @@ -59736,6 +59736,229 @@ var ropstenPreverifiedHashes = []string{ "d93fa8c956c993e837f150eaf47c2f339e47e9b23e203699a16c51a2fc50c332", "5f328eb4e674b2911c679fe3ef21bf744c2df28a461aab701b2edcc7e24dea2f", "6554dc9841656eebb412b36440f8e5ed544cc773d130909a73c24e97b00cc3dc", + "b7b482e0e39d1a8e942c5bf462d3904c1e4c6d154fdbb52f7154f2528401ba3f", + "e80715f008d14bb53bccb6598b8bd57afed22ef1c3e40cdb0ae2eede98854df3", + "cd837546e55ba2339119ccf328148b2dd813126777e6263e0b03d2e089cbeeec", + "084f0556670a6d659100f67a5b678b4067bea1356c30d7d36953f80bad51aca2", + "9827c1b49420405f158ce17aa343fc0d39c377392a91fe18071f6c9f4e69387a", + "813d6729dc549439eb945ea9eb241147c22dbedd8e3fa37a1b7d228a26b06bbb", + "b6521cb7f7d3df87aecef8aec8bd747b9498e8f132ae79603cf4834190dd970c", + "c034598c93cd9d1ec81d8d4b535c273ee48ca21ed6919eb101403f2865ec0ff3", + "c90cc933a81de70876b00c8202a4c2a2cbb184f9434322abb030ce427753f3aa", + "774588e9e64a01f4b71e55cf7e8b3cb03e09fc5b9a4cb3d39a47c4229ae1b984", + "02bd753fd829421f09df406eaf1e00defaa34f2af3409b94cfc9344bb1e39f0f", + "64dfa521982883c9d149d2bea1fd7b47c745c985ed7c63b51a7bacc462497ed0", + "46c5abe5aa5f143b11bb12ee292555d5ec8f726ff4c0ddbb68f6d37d04549e0c", + "091e329397d063071f17e603f1b049bc67d9ca8fa0bac0375245f1f13032bc8a", + "f15798244e89a01419c1392d98b3c3101d881facd4b60ae81a6f82e87d93bc5b", + "8d61efbc9d9dd1c758ab7577693fa8745928d5b347030cc5af79d311f712594b", + "6c6ff0415c7ad62d39fa0fff18df6c5c455e5cb5c888e05fa23a555463071df1", + "b36ee69f279a4ee051c48318433b689fbad2b40da6f40a8ab3b6d6c0bdc54202", + "fc615f6ad75cdefcdedd22fc32ab34ad0445cc726588c0509221fa5964d4bf88", + "0697c06a9bc5c7b0911dfe9f1eef5aade89bc6b2b1fda1579a04271fa95f2b4e", + "5eb8bb1bd9f0a5a430b33247d1e2f8abb9b4e66ecdedd797f1051e8ef93759b4", + "6f1f45ed1cd5565ce9e194225644184461ab36210d9f58f4ea98e0110aef34fa", + "16420ca4fc8237edec740e5eedb1a1fbf9f7fd3001ba34eb1de69252bca02367", + "ecae6fd8213debfce09d183a8394de4483fcef7afb3aad5d0c9768ab46bd6224", + "b661b5b2cad06925dc922ca0c516616b439c5763ef4310c5e963b63b3c8a383f", + "779c4eec51dc2a65a102ef049f9988adf8c208f04f23d0f6745d334477eeac08", + "831253a28f80ba011232cafd61f36ba8543b990462c3635308a6421f33e32c08", + "c68385ea2ba2004fa3af6cf9a1061c3ef85ed1f54ae3d03de9140067b93486a7", + "918a1e0b28a22b355e4715b9a1940190ecb40814f5772ba334227fc7278df349", + "65b17bde59915c1d567f00f35c88478e901346938b17d485a3458122848fc40e", + "24796735973ea04834bc859f4e761d4dc635ea0ed9c158f69ea970ae1738a023", + "317adc7bf9ecc6bff778118928d7e57b492b9814b44bae4c44684277da70af0f", + "d221f166c035dcac1e4c950560b4bce5fe1a75434b7f8615c1ca0479f77f9293", + "73355f8eac3fdfda6b7a604d1e1d996e5441c15fc759b78a4f35dd344c125bb9", + "dfc0ec9f748992308053c4f2b5bbfef374bf5ebd04c96ff3907143df50055b3f", + "250cb557244424e8a666899adff6fac3d300e1f0899d11a7753d8a852daa778a", + "37909bb27cd4ebcc28783097e9504e81112f992a596cb00f2d961b1fc7dc45ab", + "104c28e21d76219ce86e97669cc1853b8f89e47a0a1869dd1c9e4f732a799c9c", + "f225fc33c1f68c144b767f90733f09f6b3305740de2f1155193ad12a5e299ceb", + "29d46369c88a1cd06f31f865fb68132cf6e1b5604ad11360bbdbd9feb6c69a95", + "8f2f636a70040e40e205a5c9ae0ccf6ba4e43e3a8ab0bced710f3f87f940bba2", + "92f1b1e6146fd0322a55a06ee0509547c04b7738981ea280aac840a1a60e3daa", + "e4212cff906ed4e33c3bf030bcd47e8e8e3c6d916e9202bc78562971fd4fd69a", + "de0e62da91387f04d65094c2eb79c10dab3504d0791976b9f087e4ba6b5df590", + "af3e9c807adf07d6a2560e099351660ca029a4ab32b0e939c096a1933dc11401", + "590f81fff9bc9bbb6a5c6676f67fc5a84cbd95c6af3277baa08e1b251052fac6", + "ce75909f8bfa887b7227448313b470a371962be4cf972a4dbc5ef19d4688a0fd", + "9ba27eb1f5013e1c9d998cdf52077ea9147f692293b7b13b9564741e6ef9ea43", + "aad3fe4d8b1e57206355949321753d5c712bc17d3f2889705897fdb3cc758e2b", + "6ece356c4c58802ebf5ab4136ff769295fc7db9b5f3ed13294b0301f479e12a9", + "6d60a355587c0a06b1558f1233eabd98ecec2bb23190b1738f0fa4974f4b801a", + "e5cedcf0db82341594257fa7183ea5b47e352883214bd8ba9bfb1efbfdb4eb6d", + "54bb0347453102fbfc95ffa2cd250bd47b4ad5db726070ad031ab887f70b09c3", + "ce81374180a3d8b03cdb8bdc1ffae318649c400d2205dabfaed64fd708d7af49", + "1a29f85314f96720efc7d0c62a925db3e68d77c5e3bb3272115e9e1933ea1f90", + "e28878ab5d13859f544abb9cccaa1fd371117e9612656def6e52a813614456aa", + "27f57c0451ee86122271108872b9a24639c59e6e769a9bf6783570a5bea9fc8e", + "974772a856f8134fc7450eb25f3fe567ca27e0cad540e95f7376bbaf69220c8e", + "c85ad64f96f64cd999561ca0fbd9de71b6c8fb3366dfc226e3bc803459bf1df2", + "145c39479339940c2e714e200277cc746de8634d007100f9eb09a6ac894c1191", + "533aae0905cbc7883441eabf29921144811074cf6b471a7e1e1bca39eb410bff", + "293a4278fb936e2fb694ff0f0cf79dbf5f4a034680b1c512082c68b729f3f529", + "e306238df730965d6027263638f37cd00bca0cfc9c32e4b076a7016e96c9e51b", + "f2b9472588d3b5decd343cda9d59f272bfdc43d6fc8c715b0b2e4eef614f5576", + "afa0beeee4e27e3f6765d8d4ba80e6f03b017a48751c66cef72a411f780f8038", + "0451705e954da1c89d94d2a64dcf93f78ddbf5328d5a8cbe214240f76f33c079", + "dd06b1bad11cbad7a8d227c751eb2a26402f4429dfe1a563f600c60cbc407af8", + "b8b39cf367caca75b123d9cf4b886de479793ee90ea45a0baf66d3971a3318cf", + "7489eebb06d247a628ffa2818a76a904e3081c3f4bc2957171b236defa2fe57c", + "52fde02656b4028d3d5b9f08a30706dcb104dcd3adb98506b43bd0d5b0a60330", + "79e98edc492f22df58c1df2ef4d9400923c55388af7927d2ce133e76e5b50ea6", + "e216c12a8ffe08a3e17cf1b9846290ddba096138dde2b4be674981685a1c3149", + "19266fd3a7fb10c3978a79e1384353db8fc584d318b8254f09635ebb81aa0640", + "57df483b72566c6e86b20f89e40267d3026ee5efd7ca70f1cb8a7e12fb1d92f0", + "ee01f7188965355111f5ec41a11a9ad83c12caa8aaa782392b76d6280d568b9a", + "3161eee5c6c17ffa9edf0355839788f3d9e5478ffcdb288e03ccce7490d3ed40", + "8daa34763354c2a9add15ad69fde9e36d5452920377ac245f51563340ce6b39f", + "58f286730fa643c34d6994c1bd8a15bc2ebd9a85c2266c2d774e404fdc10dfc9", + "8c0620426a6860b150a0a89c60e382dd40ce371fe6d3be3da86c4db2ad04ce9c", + "1d488d3c1decbf0c8cdcd1e7fdc45411456e58b22cbcb1db4ee9dce07c99cd38", + "b630fdadb67d7920e1408b25c3c75e6b053e2bbcd5c1f92c33d1aa0915ed41b4", + "c878dea80e6ef2e12fac7ee91de4ab5c74f83cdf41d87ac3709539b676da6163", + "329fb870e091b7c464ffb7abc5846af1f5e7d8b2fa6d6c52a5e299768ec2bd95", + "8e003dbe998b10648d3461ba32f560416830597654923423eece6f8f5c07b1af", + "32d1e145316e98ddd2cb9828adcdeb5644bdb0acb71827a949ffd22b2a8e342b", + "7a3ce43197763e5b6719e9b6f464603e178d1301c2de87dd9a1b88ceba173d72", + "a3f1ed923760437d8eddea88174af72c0f151f8e99d22bd909c6d6d601084770", + "ddcb4ba7711fe7d9702be3632c5c622b3a36e8235d11a49d837a1c2c70814f1d", + "254da0aa6fccad864adf4886b0a686bc4ac5debf3e0ae873ace1d2041ce74178", + "065f375ad8ffc3ba930b4ef4cd302bb822cb0417f7d11ac400b1f3d4296430ea", + "100968f3d5a799262a0dbed14c56bc65b5f675034c73d7017713f589da09a87c", + "cb1848a33ad317776b6500993ea78bd94d8d28ebcd4c11c2eac15ff381f73a9c", + "492e1c0f02d04afe1f8f007c24820b20a2a59eb9a97a2d4e3b6915eb88f01f03", + "6f6a3a5738d839708cd6af34120946fa65de5095fd23e785032869399dab8ffd", + "9f9a1f87fb3f9e86c3489c40ba9b016949ebc522275315a8b5cea1a1753ee4c9", + "9639dca767affb43a782ad85ad58481ebbd341150c833aab7c635394a1c8724f", + "589e99ba10849759ed0058bf891badf3543d072a5ac3a3ab53c68c82a3662197", + "33f05be70a1fe51cb4d2a4416a29e8893195bbf4c437d513c387280f9dd4eb50", + "33ba32fa99884f50ce344003eacbbf09414d72f98d10e4c98c3378a39dce2781", + "c6b11f5eec275090c6cf7ff7f78efc281bfbc81cfc0d0e6c7397e81b45b3536d", + "cc52ee262cd850fe5c7fc68e3dffdbf5cedf64fe1861cdd31ac34d82c67e495b", + "012d06f1d58e0dd20dc98156898c2d2bc25375dee9c73a810a8b58881f242887", + "2532d9b9a62c230e3797407c1e605e223b01455861532be9bc7605cc8c9c2879", + "98bf2d21168c0fb04c3e642e231e04da62fb75bddc272427cf52925263b11104", + "06b7146fff36b4acba5730f7e2c62a30f2a0ef9cab872f9adc2911089a6e9373", + "53051c40749e8f643dd21c113f8e7f8c588bea13fd8845e2536fbbd6ce754b5c", + "42dadf7816b4e4a554122180284f957d921784c46e14944cc00b441a0bd7a8a0", + "b3c512925a4c3f926d53a8be9afe32a73c6806848858a0888aab449b8d4cb6ca", + "4029f49e6799b6bfb2e6ee1a4743285801a061dbe6dbc77b69fff1eb84527cb4", + "8d788e52b11001a99d5c40a810c9ac27175454925c4c2c5a1ca4e114b5b845a4", + "fa222b2c14522e4c09c54440045f5131b0b691e76f0c07692f894358578601ab", + "15dd5e26ffaa5f027fbc1678ad252e193a429af0517d1c38ad14fc100db53d0d", + "d399d8a2e51bac6336c641738aa2d59124de9a9e52f6272bf44c78f2f74ee204", + "d08046b3882c168567ebaa321485255c26ca9b1cb6f70711530ceb5c8807361f", + "9eff4e7b266f883f67716f4e86dee672411b4137c6a1c8798b42910c6c957d21", + "46b1317f1fc6104d0ec7beb5662dfbfb0a84a569b4e3ab4202c49d434620bd7e", + "5c08cc71982b0d417b5e507125640aa966bf4679853a8a31d2c73a38b3faacce", + "b17a5630c5687d73a357c132fdfdbcce9b5a8d5e495fb8a5fa5ebcfcb7461486", + "b5bc5c78eb68010de33f8c2aee611e9fa3e1e88fab4ea9ac42d600b35595d57a", + "dc47e431c433852f7d12841abfceecee442aa85c5b7443c812457ca2d3227bb1", + "17a8efd385a854f89c50f0283d538cdeb3e2518a2aa84d5222a1851139d4596e", + "7ddf45d1182c6a70cb2a361aeb4380de9e2636b2cd63ee6d26b9691ee050656e", + "d47282d574ecdc0e228d1c9ee6c2d2d17d649c33662436c9b1f95a10637a946f", + "07b2e01d32fcb1a65a0d13158b6a3d1c73687ae20d9459ac89504d13c54f0ab6", + "52bb293177e672a08ea886af53e2cd23fdeb5cb6b6b9c93cc9c938608e1942e7", + "dea42ec21c738ffeb7c9408aa64e55f9db76bd8c245f6e8697be7383c9ba5fd2", + "4a28678d1b477e810392cead7686f6b6faa3dd9fb19c5c8b0326c52560149027", + "e7a8d4b7c40d7be8155427d6a990bdd1848127b41b5a9235e5720952464ca2eb", + "a6fbb9bcacb72df6a2a9acec35203586cfa22dadf7e250a544884c73376964d2", + "bd8ce578f0d45bc2b13f5cce179cbe396a02e58602fe317dc8d0daeae08290c0", + "4cb662bd4244516c1fafea7fbb5d60fb52f699156e812c79ecd5002bea7b1e74", + "cec87f813b77b7a6be0379e2ed8f663bff756c2d867c1fa2d98174e581eea5f2", + "35d51cf7c643bd0baca104595ee26145bb0090d342fca6f024c5c32417041370", + "3bb9abcd069992bfd2a573babe3d3869e24aae8493660141e1e531c5d892dec5", + "bc17ccec441b353e0116103363b10690f62c2f5d6c3b479da12c1b8c703d5040", + "02e1b9e2f947a67fbfabfcb794aacb3cdec17ffd2588cfedc72cadbbd06d7be9", + "c5c39b72c345b135af7cc17e76d0c2acb265b77b9e950214276b8377e636c0b5", + "fa7c641438daa6edb665ba38605c01c360b2b02554f30980758a9d62b523d175", + "f95b720f94fd7eb9f8f5503b762a2cce14105c51b1b19839e99260fe5865331d", + "f2da125b53e66dff3f485bd0e5d84e16a42138cc9b8d5f356a2cfa36323c9748", + "a4b70213d054c9dfeaa324e03486eef156fe29a126971312aa4fb3bd15a1651b", + "4093d677422c933875588bb87748930f8c924487d27154c789f194a08208a8f1", + "ada18958d832e360143821dfe6911c00bd2cc8023874ce170cf13929bd7652c2", + "b7b9e33f9978e3765383cc554bebd902ca955e8f7ba263183310e118eef2a053", + "d356e681e01c1fed60e4eb5b9456d9d00ee9651db864101c8da8fd24ba076587", + "39feb035429fcce08d0dceef01888d2dde53199c33305686d87979f5a5be21d3", + "c8bd7ca39cb9b5adc2755ac98cc33398f96a46fdccc72d008dd3c97a4ec52a3d", + "445ae4a20fbede9a29274d09e932ce7547e18ba04a6eee98e0d06aaab7081ff5", + "4e26a7804fde9b3a98a9b0db40580ac4894f6435271b3bf3da0cdbb2c187b2b5", + "dd2860c5a93a09b96198c25673d1c0842cafcc5227b80b20d7099582c480e185", + "3ab3cc68cda07eb4ff388a8d0c2cc121f3ec0fa4257c971ae8303dce9824e9bd", + "c5abed85a6ec463097ff9185b7e4535b7a3ac6a1d45ed4d9bc002763bdad6228", + "5dc9f14f9ecca2ac4a0312fcfd8224e69d6a63eafcbb9b977e2a13c3d29977a6", + "4c9c55ceb20c1a8a10647d85710b8a141c6ef4036340999102e334e582daab94", + "d1291e99efb997b64a1e4bb0384d42626b2f27896b99785a8e9fc0a2e08b4e24", + "b42333e87074eb2256d9770f32ffcaca72628348e9b8459a4114b88bfeb9ec81", + "c5b137bbc40a3ec034801fcc0c9c99298986166e96968bde7c8b68031ebe343b", + "a746e78a887f9d79d3d282498cee16d4ee5ef83823cd9231dec633f7f9e36d11", + "4693c153517c71948fb18c57ebdbcb06c838e9b03f8bb0650360e8319ae54803", + "9cc83f9d1f03714c18f657fe3537393f6bac28d6e505e46d39e672557ee9e776", + "850b204d356c3d599c264e59a69b4b1c4c9ca7439ffb6b69a32ab072b50d30e3", + "93c3cb71efcd4ef8b3913e4c7e7ff91ef727a04d5de3f15bd4ea7cf69dc6d2a7", + "0bbac8692f2312d90cf4a81750ce66c5131096e459db90bb68926e929a98ebc2", + "c37fbc7b7df078b0fea3750c68dd487ac142ffca39a9bba7ed6b75fd53eec642", + "c75112e9ca9ae57beb455c46cdcfec01ada900bf40a9c724f2189940c735184a", + "7addef6d8f606b46c4f27f08f3ea2483ddb3c1a13e9c0548edcbc31f61dea2d0", + "14f3c8fc37319f546a651d1954bea77651e85eda2e94e9089946af43a6922aab", + "5f31c88196b53db30bd23bcd9ed44118e4dbb792b9506f34e626191f50477e07", + "8a90d7d9f7ac6de1cb3f1fb09f3b201072f980b9ba4381bdb8cbffe3edb6cca1", + "3f64791f394ed2880a3b300fa3d21ab9990f854350293f8e8e5e8ad6d39424b1", + "d3170b954223324b7b1e913d2b3998c60cc759854076d306f05b840867b7c7ee", + "c706fc81e99974b152ab2eb7a225c247d75c192884c6dd1b653b126690ed0abf", + "d48acec88ef44ad1468acb0dde1aaef098d12368d9742a249713c44f7aae3081", + "d8fbf8340b13c4d50b9dd7af90a1ccf533a17c1037e405b7663b80da0bd29ca1", + "ee0496a5c6b905b22d02a62c2404113688a1ed3519acb708a466148c6e93de53", + "1cbc0f7aa5af800823547bf52080bcebc325bd8bddfa558b5af1d5904325c903", + "7f2829e8d1a5e5ae1f93c7bafba37adc4769b57853b79ab660eabdd845c54738", + "0603decdd17dad9026a2a83fcd7d6a1ae078a5048b0de14a2573c4add8611c29", + "ed2149ff3d27cc7149eb042df2b23de4b642ec7496b6db79a3ccc94029195fe8", + "b00f049c4365a910758024b34eb5d6f7543737b6e8bca8ba66beee93d4370cdb", + "8c6032303f80932be8aed54bb413e0321e126cfe4f496558ec50e38ee1348a9e", + "0d2e56e83001200f172c3c4864f6a4d4f3322c7f0ef41d8f288aeb62fc231eed", + "8600112b382c2595f1eff88cd3d9e46a2da1b20e9ba057e6c4c5180730209649", + "90f43188e0a70aae39d4559412b63ef94e4e5b84eda05cbf01981dd857788cc7", + "e090c66fb75386270c4628432cac32fef993fb70a2172ce1b9381bfaad48f09d", + "81f98afc1079de85e5af5600821567e5359d71c6f1b558341be26684059467f1", + "25cc055bd5868661830ac7bda786355bc4bc135fe8b72b8efa29050eb65a041c", + "ff9816e3cd5821b2b475ca732194e1e8486c0fd89f85c8703862e820cf9a1cbd", + "c788f4badb8a3b323dda9bbfa92744a91e945b8b2fde36954b5ddaf82accd016", + "b46aedab55f899ad4aae3bbb49b2035f48a70fd81007f7e5266c2ff2f194b402", + "410bcacc51fab3a07f35a4cae26e2cb706ab486c241f046244ee64f6d61c4606", + "00e78c2d591a71868e6a2cca1e1112fdfcaa39c2f9d4d50cea297d1eab487c8e", + "78d5f878c3f1c898ecf28a7b30e9da4207238239aded3c8f7d3932c9f647ddba", + "905e320a5f716ebb92505cbf4f309e59b6a12dc860249a7c9c8b18c36e401664", + "88985876ae3ac923e2c034143d855f9dd9c20bff49e6b8c931160b06c659de33", + "38ea091731d22ad67dd2a013fae5f2f857924e5ec94e974f06fab9b03a31bcfd", + "e7275e7e41c21febbbce15c8c3ce9fa9037eda4404b4f16e2a1d03ddee0fc41e", + "fd3ef21f688792a9e55944e5bd99c802a3da98d12154c6bd2b6012cd0299dd67", + "63da2b74bf05c2bb067d60e51f26ec7ff42ebb0fea39467cd7cab2bae317975e", + "8e5e014fcd13efd4d893834ab47dbc1a6ac6f513625de3647b6b5eab9f4b5fff", + "ba1d76d03e894455bc3b70426d8b8edabe3b517efdb41c871553576f5d876010", + "48913353b3336758fcce3d1760c59d86acf35dc867eab03e4abbaeb72e887263", + "e9fdc26a2be613aaf88ccde205919400d04d2196e7f9f5d6965bfc6f42b6241f", + "29f47ac0fd8a031a0d49cb83cb70c3b8d4e19b02fb0cf3dd8cd65b16cf009160", + "1eb5ba3460ed477d43f0f58c192b34e42e4fba377de6f2dfb2737620efb83bc9", + "ecdf7d0bb6c5df6d8f4c3b3dfc927cd487c709461134dd96a19e7e780b0a071f", + "0ea407c6f31a69f725645a181002c4b3396e663f0a7514c59485629ffba1348e", + "87a2db49f1d52c81a96c578a05c5e413eff487568355ba7d95fd9084d58ad5a5", + "7bb32ecb5ac3f17e638c0a98ab413cee9a88830bba7fb544b8b0a42334424a98", + "fcf55cf0ac151d0c3fdb518d30fd31a8a6731cdcdc5a3f79bd29ada6dde343a2", + "2eb1dc4f28b86fa92722f607da259ffd6d03a6f87b96c9f8f81b7740d9742bae", + "645571aba4469656b3e43e9361f7a56ed46cbc484b323251270a152494e13847", + "09bfd488df2d7b4cf84847048b708bb3c3b2101d35a0751db4ee3156c3380802", + "ed0c82a8c78f95733542fb75ef3ec93610a8bb9b300a17fa9af3365464f1926b", + "f43b3096c23fa0aa33bfb2cb503c2da69780046f36163843ed74568195cff119", + "e3bec7c7ec75429e45750e5a480144c4a80327f51a2cb07a6ca31eab1da93b2a", + "8c67244c4e29cf91209738606f74e774e1813e6c19b4eb31fbb2bf2b113cedff", + "308d88b18ee8d2a279ccd3a4a0c3364173b8265a4c2a06900041aa143d31d4c0", + "b6fb957a1429f4d99f6a367547ab0b2174b7e06767c8e124d6161264b81b617d", + "e8f60078e9b41609eabc007ab532ad6668db1a4590bba087be10ab79f4e7e746", + "4e4156ef42cad98b2980ef1d4cf8d266015c7375e1b7c70c660fc3fa617431ee", + "154b8f020266a216ea46fdac5c1ac7b19dc1a2d8d60ceb1eec789fd854d38d5c", + "5266b2193223c15de0a8f04d2d1f286fd9a961148a40cdc4cfb45b2d965f6b63", } -const ropstenPreverifiedHeight uint64 = 11468928 +const ropstenPreverifiedHeight uint64 = 11511744 From 5c6c03cb7a2ed06109adac7d8acdfc19448bed43 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Mon, 29 Nov 2021 15:37:17 +0000 Subject: [PATCH 046/261] Create access list (#3048) (#3052) * Create access list * CreateAccessList compiles * fixes Co-authored-by: Alexey Sharp Co-authored-by: Alexey Sharp --- cmd/rpcdaemon/commands/eth_api.go | 1 + cmd/rpcdaemon/commands/eth_call.go | 130 +++++++ eth/tracers/logger/access_list_tracer.go | 192 ++++++++++ internal/ethapi/api.go | 432 +---------------------- 4 files changed, 324 insertions(+), 431 deletions(-) create mode 100644 eth/tracers/logger/access_list_tracer.go diff --git a/cmd/rpcdaemon/commands/eth_api.go b/cmd/rpcdaemon/commands/eth_api.go index 6647b05e86e..184e0310bfb 100644 --- a/cmd/rpcdaemon/commands/eth_api.go +++ b/cmd/rpcdaemon/commands/eth_api.go @@ -81,6 +81,7 @@ type EthAPI interface { Sign(ctx context.Context, _ common.Address, _ hexutil.Bytes) (hexutil.Bytes, error) SignTransaction(_ context.Context, txObject interface{}) (common.Hash, error) GetProof(ctx context.Context, address common.Address, storageKeys []string, blockNr rpc.BlockNumber) (*interface{}, error) + CreateAccessList(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash, args ethapi.CallArgs) (*accessListResult, error) // Mining related (see ./eth_mining.go) Coinbase(ctx context.Context) (common.Address, error) diff --git a/cmd/rpcdaemon/commands/eth_call.go b/cmd/rpcdaemon/commands/eth_call.go index e643703c5f5..ebb9b4e3132 100644 --- a/cmd/rpcdaemon/commands/eth_call.go +++ b/cmd/rpcdaemon/commands/eth_call.go @@ -6,6 +6,9 @@ import ( "fmt" "math/big" + "github.com/holiman/uint256" + "github.com/ledgerwatch/erigon-lib/gointerfaces" + txpool_proto "github.com/ledgerwatch/erigon-lib/gointerfaces/txpool" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/hexutil" @@ -14,6 +17,8 @@ import ( "github.com/ledgerwatch/erigon/core/state" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/vm" + "github.com/ledgerwatch/erigon/crypto" + "github.com/ledgerwatch/erigon/eth/tracers/logger" "github.com/ledgerwatch/erigon/ethdb" "github.com/ledgerwatch/erigon/internal/ethapi" "github.com/ledgerwatch/erigon/params" @@ -21,6 +26,7 @@ import ( "github.com/ledgerwatch/erigon/turbo/rpchelper" "github.com/ledgerwatch/erigon/turbo/transactions" "github.com/ledgerwatch/log/v3" + "google.golang.org/grpc" ) // Call implements eth_call. Executes a new message call immediately without creating a transaction on the block chain. @@ -276,3 +282,127 @@ func (api *APIImpl) GetProof(ctx context.Context, address common.Address, storag var stub interface{} return &stub, fmt.Errorf(NotImplemented, "eth_getProof") } + +// accessListResult returns an optional accesslist +// Its the result of the `debug_createAccessList` RPC call. +// It contains an error if the transaction itself failed. +type accessListResult struct { + Accesslist *types.AccessList `json:"accessList"` + Error string `json:"error,omitempty"` + GasUsed hexutil.Uint64 `json:"gasUsed"` +} + +// CreateAccessList implements eth_createAccessList. It creates an access list for the given transaction. +// If the accesslist creation fails an error is returned. +// If the transaction itself fails, an vmErr is returned. +func (api *APIImpl) CreateAccessList(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash, args ethapi.CallArgs) (*accessListResult, error) { + tx, err := api.db.BeginRo(ctx) + if err != nil { + return nil, err + } + defer tx.Rollback() + + chainConfig, err := api.chainConfig(tx) + if err != nil { + return nil, err + } + contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } + if api.TevmEnabled { + contractHasTEVM = ethdb.GetHasTEVM(tx) + } + blockNumber, hash, err := rpchelper.GetCanonicalBlockNumber(blockNrOrHash, tx, api.filters) // DoCall cannot be executed on non-canonical blocks + if err != nil { + return nil, err + } + block, err := api.BaseAPI.blockWithSenders(tx, hash, blockNumber) + if err != nil { + return nil, err + } + if block == nil { + return nil, nil + } + var stateReader state.StateReader + if num, ok := blockNrOrHash.Number(); ok && num == rpc.LatestBlockNumber { + cacheView, err := api.stateCache.View(ctx, tx) + if err != nil { + return nil, err + } + stateReader = state.NewCachedReader2(cacheView, tx) + } else { + stateReader = state.NewPlainState(tx, blockNumber) + } + state := state.New(stateReader) + + header := block.Header() + // If the gas amount is not set, extract this as it will depend on access + // lists and we'll need to reestimate every time + nogas := args.Gas == nil + + var to common.Address + if args.To != nil { + to = *args.To + } else { + // Require nonce to calculate address of created contract + if args.Nonce == nil { + var nonce uint64 + reply, err := api.txPool.Nonce(ctx, &txpool_proto.NonceRequest{ + Address: gointerfaces.ConvertAddressToH160(*args.From), + }, &grpc.EmptyCallOption{}) + if err != nil { + return nil, err + } + if reply.Found { + nonce = reply.Nonce + 1 + } + args.Nonce = (*hexutil.Uint64)(&nonce) + } + to = crypto.CreateAddress(*args.From, uint64(*args.Nonce)) + } + // Retrieve the precompiles since they don't need to be added to the access list + precompiles := vm.ActivePrecompiles(chainConfig.Rules(blockNumber)) + + // Create an initial tracer + prevTracer := logger.NewAccessListTracer(nil, *args.From, to, precompiles) + if args.AccessList != nil { + prevTracer = logger.NewAccessListTracer(*args.AccessList, *args.From, to, precompiles) + } + for { + // Retrieve the current access list to expand + accessList := prevTracer.AccessList() + log.Trace("Creating access list", "input", accessList) + + // If no gas amount was specified, each unique access list needs it's own + // gas calculation. This is quite expensive, but we need to be accurate + // and it's convered by the sender only anyway. + if nogas { + args.Gas = nil + } + // Set the accesslist to the last al + args.AccessList = &accessList + baseFee, _ := uint256.FromBig(header.BaseFee) + msg, err := args.ToMessage(api.GasCap, baseFee) + if err != nil { + return nil, err + } + + // Apply the transaction with the access list tracer + tracer := logger.NewAccessListTracer(accessList, *args.From, to, precompiles) + config := vm.Config{Tracer: tracer, Debug: true, NoBaseFee: true} + blockCtx, txCtx := transactions.GetEvmContext(msg, header, blockNrOrHash.RequireCanonical, tx, contractHasTEVM) + + evm := vm.NewEVM(blockCtx, txCtx, state, chainConfig, config) + gp := new(core.GasPool).AddGas(msg.Gas()) + res, err := core.ApplyMessage(evm, msg, gp, true /* refunds */, false /* gasBailout */) + if err != nil { + return nil, err + } + if tracer.Equal(prevTracer) { + var errString string + if res.Err != nil { + errString = res.Err.Error() + } + return &accessListResult{Accesslist: &accessList, Error: errString, GasUsed: (hexutil.Uint64)(res.UsedGas)}, nil + } + prevTracer = tracer + } +} diff --git a/eth/tracers/logger/access_list_tracer.go b/eth/tracers/logger/access_list_tracer.go new file mode 100644 index 00000000000..42cefa66280 --- /dev/null +++ b/eth/tracers/logger/access_list_tracer.go @@ -0,0 +1,192 @@ +// Copyright 2021 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package logger + +import ( + "math/big" + "time" + + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/core/vm" + "github.com/ledgerwatch/erigon/core/vm/stack" +) + +// accessList is an accumulator for the set of accounts and storage slots an EVM +// contract execution touches. +type accessList map[common.Address]accessListSlots + +// accessListSlots is an accumulator for the set of storage slots within a single +// contract that an EVM contract execution touches. +type accessListSlots map[common.Hash]struct{} + +// newAccessList creates a new accessList. +func newAccessList() accessList { + return make(map[common.Address]accessListSlots) +} + +// addAddress adds an address to the accesslist. +func (al accessList) addAddress(address common.Address) { + // Set address if not previously present + if _, present := al[address]; !present { + al[address] = make(map[common.Hash]struct{}) + } +} + +// addSlot adds a storage slot to the accesslist. +func (al accessList) addSlot(address common.Address, slot common.Hash) { + // Set address if not previously present + al.addAddress(address) + + // Set the slot on the surely existent storage set + al[address][slot] = struct{}{} +} + +// equal checks if the content of the current access list is the same as the +// content of the other one. +func (al accessList) equal(other accessList) bool { + // Cross reference the accounts first + if len(al) != len(other) { + return false + } + for addr := range al { + if _, ok := other[addr]; !ok { + return false + } + } + for addr := range other { + if _, ok := al[addr]; !ok { + return false + } + } + // Accounts match, cross reference the storage slots too + for addr, slots := range al { + otherslots := other[addr] + + if len(slots) != len(otherslots) { + return false + } + for hash := range slots { + if _, ok := otherslots[hash]; !ok { + return false + } + } + for hash := range otherslots { + if _, ok := slots[hash]; !ok { + return false + } + } + } + return true +} + +// accesslist converts the accesslist to a types.AccessList. +func (al accessList) accessList() types.AccessList { + acl := make(types.AccessList, 0, len(al)) + for addr, slots := range al { + tuple := types.AccessTuple{Address: addr, StorageKeys: []common.Hash{}} + for slot := range slots { + tuple.StorageKeys = append(tuple.StorageKeys, slot) + } + acl = append(acl, tuple) + } + return acl +} + +// AccessListTracer is a tracer that accumulates touched accounts and storage +// slots into an internal set. +type AccessListTracer struct { + excl map[common.Address]struct{} // Set of account to exclude from the list + list accessList // Set of accounts and storage slots touched +} + +// NewAccessListTracer creates a new tracer that can generate AccessLists. +// An optional AccessList can be specified to occupy slots and addresses in +// the resulting accesslist. +func NewAccessListTracer(acl types.AccessList, from, to common.Address, precompiles []common.Address) *AccessListTracer { + excl := map[common.Address]struct{}{ + from: {}, to: {}, + } + for _, addr := range precompiles { + excl[addr] = struct{}{} + } + list := newAccessList() + for _, al := range acl { + if _, ok := excl[al.Address]; !ok { + list.addAddress(al.Address) + } + for _, slot := range al.StorageKeys { + list.addSlot(al.Address, slot) + } + } + return &AccessListTracer{ + excl: excl, + list: list, + } +} + +func (a *AccessListTracer) CaptureStart(depth int, from common.Address, to common.Address, precompile bool, create bool, callType vm.CallType, input []byte, gas uint64, value *big.Int, code []byte) error { + return nil +} + +// CaptureState captures all opcodes that touch storage or addresses and adds them to the accesslist. +func (a *AccessListTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, rData []byte, contract *vm.Contract, depth int, err error) error { + stackData := stack.Data + stackLen := len(stackData) + if (op == vm.SLOAD || op == vm.SSTORE) && stackLen >= 1 { + slot := common.Hash(stackData[stackLen-1].Bytes32()) + a.list.addSlot(contract.Address(), slot) + } + if (op == vm.EXTCODECOPY || op == vm.EXTCODEHASH || op == vm.EXTCODESIZE || op == vm.BALANCE || op == vm.SELFDESTRUCT) && stackLen >= 1 { + addr := common.Address(stackData[stackLen-1].Bytes20()) + if _, ok := a.excl[addr]; !ok { + a.list.addAddress(addr) + } + } + if (op == vm.DELEGATECALL || op == vm.CALL || op == vm.STATICCALL || op == vm.CALLCODE) && stackLen >= 5 { + addr := common.Address(stackData[stackLen-2].Bytes20()) + if _, ok := a.excl[addr]; !ok { + a.list.addAddress(addr) + } + } + return nil +} + +func (*AccessListTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, contract *vm.Contract, depth int, err error) error { + return nil +} +func (*AccessListTracer) CaptureEnd(depth int, output []byte, startGas, endGas uint64, t time.Duration, err error) error { + return nil +} +func (*AccessListTracer) CaptureSelfDestruct(from common.Address, to common.Address, value *big.Int) { +} +func (*AccessListTracer) CaptureAccountRead(account common.Address) error { + return nil +} +func (*AccessListTracer) CaptureAccountWrite(account common.Address) error { + return nil +} + +// AccessList returns the current accesslist maintained by the tracer. +func (a *AccessListTracer) AccessList() types.AccessList { + return a.list.accessList() +} + +// Equal returns if the content of two access list traces are equal. +func (a *AccessListTracer) Equal(other *AccessListTracer) bool { + return a.list.equal(other.list) +} diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 8ee4192e528..bb640c73ff1 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -32,294 +32,6 @@ import ( "github.com/ledgerwatch/log/v3" ) -/* -// PublicEthereumAPI provides an API to access Ethereum related information. -// It offers only methods that operate on public data that is freely available to anyone. -type PublicEthereumAPI struct { - b Backend -} - -// NewPublicEthereumAPI creates a new Ethereum protocol API. -func NewPublicEthereumAPI(b Backend) *PublicEthereumAPI { - return &PublicEthereumAPI{b} -} - -// GasPrice returns a suggestion for a gas price. -func (s *PublicEthereumAPI) GasPrice(ctx context.Context) (*hexutil.Big, error) { - price, err := s.b.SuggestPrice(ctx) - return (*hexutil.Big)(price), err -} - -// Syncing returns false in case the node is currently not syncing with the network. It can be up to date or has not -// yet received the latest block headers from its pears. In case it is synchronizing: -// - startingBlock: block number this node started to synchronise from -// - currentBlock: block number this node is currently importing -// - highestBlock: block number of the highest block header this node has received from peers -// - pulledStates: number of state entries processed until now -// - knownStates: number of known state entries that still need to be pulled -//func (s *PublicEthereumAPI) Syncing() (interface{}, error) { -// progress := s.b.Downloader().Progress() -// -// // Return not syncing if the synchronisation already completed -// if progress.CurrentBlock >= progress.HighestBlock { -// return false, nil -// } -// // Otherwise gather the block sync stats -// return map[string]hexutil.Uint64{ -// "startingBlock": hexutil.Uint64(progress.StartingBlock), -// "currentBlock": hexutil.Uint64(progress.CurrentBlock), -// "highestBlock": hexutil.Uint64(progress.HighestBlock), -// "pulledStates": hexutil.Uint64(progress.PulledStates), -// "knownStates": hexutil.Uint64(progress.KnownStates), -// }, nil -//} - -// PublicTxPoolAPI offers and API for the transaction pool. It only operates on data that is non confidential. -type PublicTxPoolAPI struct { - b Backend -} - -// NewPublicTxPoolAPI creates a new tx pool service that gives information about the transaction pool. -func NewPublicTxPoolAPI(b Backend) *PublicTxPoolAPI { - return &PublicTxPoolAPI{b} -} - -// Content returns the transactions contained within the transaction pool. -func (s *PublicTxPoolAPI) Content() map[string]map[string]map[string]*RPCTransaction { - content := map[string]map[string]map[string]*RPCTransaction{ - "pending": make(map[string]map[string]*RPCTransaction), - "queued": make(map[string]map[string]*RPCTransaction), - } - pending, queue := s.b.TxPoolContent() - - // Flatten the pending transactions - for account, txs := range pending { - dump := make(map[string]*RPCTransaction) - for _, tx := range txs { - dump[fmt.Sprintf("%d", tx.GetNonce())] = newRPCPendingTransaction(tx) - } - content["pending"][account.Hex()] = dump - } - // Flatten the queued transactions - for account, txs := range queue { - dump := make(map[string]*RPCTransaction) - for _, tx := range txs { - dump[fmt.Sprintf("%d", tx.GetNonce())] = newRPCPendingTransaction(tx) - } - content["queued"][account.Hex()] = dump - } - return content -} - -// Status returns the number of pending and queued transaction in the pool. -func (s *PublicTxPoolAPI) Status() map[string]hexutil.Uint { - pending, queue := s.b.Stats() - return map[string]hexutil.Uint{ - "pending": hexutil.Uint(pending), - "queued": hexutil.Uint(queue), - } -} - -// Inspect retrieves the content of the transaction pool and flattens it into an -// easily inspectable list. -func (s *PublicTxPoolAPI) Inspect() map[string]map[string]map[string]string { - content := map[string]map[string]map[string]string{ - "pending": make(map[string]map[string]string), - "queued": make(map[string]map[string]string), - } - pending, queue := s.b.TxPoolContent() - - // Define a formatter to flatten a transaction into a string - var format = func(tx types.Transaction) string { - if to := tx.GetTo(); to != nil { - return fmt.Sprintf("%s: %v wei + %v gas × %v wei", tx.GetTo().Hex(), tx.GetValue(), tx.GetGas(), tx.GetPrice()) - } - return fmt.Sprintf("contract creation: %v wei + %v gas × %v wei", tx.GetValue(), tx.GetGas(), tx.GetPrice()) - } - // Flatten the pending transactions - for account, txs := range pending { - dump := make(map[string]string) - for _, tx := range txs { - dump[fmt.Sprintf("%d", tx.GetNonce())] = format(tx) - } - content["pending"][account.Hex()] = dump - } - // Flatten the queued transactions - for account, txs := range queue { - dump := make(map[string]string) - for _, tx := range txs { - dump[fmt.Sprintf("%d", tx.GetNonce())] = format(tx) - } - content["queued"][account.Hex()] = dump - } - return content -} - -// PublicBlockChainAPI provides an API to access the Ethereum blockchain. -// It offers only methods that operate on public data that is freely available to anyone. -type PublicBlockChainAPI struct { - b Backend -} - -// NewPublicBlockChainAPI creates a new Ethereum blockchain API. -func NewPublicBlockChainAPI(b Backend) *PublicBlockChainAPI { - return &PublicBlockChainAPI{b} -} - -// ChainId returns the chainID value for transaction replay protection. -func (s *PublicBlockChainAPI) ChainId() *hexutil.Big { - return (*hexutil.Big)(s.b.ChainConfig().ChainID) -} - -// BlockNumber returns the block number of the chain head. -func (s *PublicBlockChainAPI) BlockNumber() hexutil.Uint64 { - header, _ := s.b.HeaderByNumber(context.Background(), rpc.LatestBlockNumber) // latest header should always be available - return hexutil.Uint64(header.Number.Uint64()) -} - -// GetBalance returns the amount of wei for the given address in the state of the -// given block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta -// block numbers are also allowed. -func (s *PublicBlockChainAPI) GetBalance(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Big, error) { - state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) - if state == nil || err != nil { - return nil, err - } - return (*hexutil.Big)(state.GetBalance(address).ToBig()), state.Error() -} - -// GetHeaderByNumber returns the requested canonical block header. -// * When blockNr is -1 the chain head is returned. -// * When blockNr is -2 the pending chain head is returned. -func (s *PublicBlockChainAPI) GetHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) { - header, err := s.b.HeaderByNumber(ctx, number) - if header != nil && err == nil { - response := s.rpcMarshalHeader(ctx, header) - if number == rpc.PendingBlockNumber { - // Pending header need to nil out a few fields - for _, field := range []string{"hash", "nonce", "miner"} { - response[field] = nil - } - } - return response, err - } - return nil, err -} - -// GetHeaderByHash returns the requested header by hash. -func (s *PublicBlockChainAPI) GetHeaderByHash(ctx context.Context, hash common.Hash) map[string]interface{} { - header, _ := s.b.HeaderByHash(ctx, hash) - if header != nil { - return s.rpcMarshalHeader(ctx, header) - } - return nil -} - -// GetBlockByNumber returns the requested canonical block. -// * When blockNr is -1 the chain head is returned. -// * When blockNr is -2 the pending chain head is returned. -// * When fullTx is true all transactions in the block are returned, otherwise -// only the transaction hash is returned. -func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) { - block, err := s.b.BlockByNumber(ctx, number) - if block != nil && err == nil { - response, err1 := s.rpcMarshalBlock(ctx, block, true, fullTx) - if err1 == nil && number == rpc.PendingBlockNumber { - // Pending blocks need to nil out a few fields - for _, field := range []string{"hash", "nonce", "miner"} { - response[field] = nil - } - } - return response, err1 - } - return nil, err -} - -// GetBlockByHash returns the requested block. When fullTx is true all transactions in the block are returned in full -// detail, otherwise only the transaction hash is returned. -func (s *PublicBlockChainAPI) GetBlockByHash(ctx context.Context, hash common.Hash, fullTx bool) (map[string]interface{}, error) { - block, err := s.b.BlockByHash(ctx, hash) - if block != nil { - return s.rpcMarshalBlock(ctx, block, true, fullTx) - } - return nil, err -} - -// GetUncleByBlockNumberAndIndex returns the uncle block for the given block hash and index. When fullTx is true -// all transactions in the block are returned in full detail, otherwise only the transaction hash is returned. -func (s *PublicBlockChainAPI) GetUncleByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) (map[string]interface{}, error) { - block, err := s.b.BlockByNumber(ctx, blockNr) - if block != nil { - uncles := block.Uncles() - if index >= hexutil.Uint(len(uncles)) { - log.Trace("Requested uncle not found", "number", blockNr, "hash", block.Hash(), "index", index) - return nil, nil - } - block = types.NewBlockWithHeader(uncles[index]) - return s.rpcMarshalBlock(ctx, block, false, false) - } - return nil, err -} - -// GetUncleByBlockHashAndIndex returns the uncle block for the given block hash and index. When fullTx is true -// all transactions in the block are returned in full detail, otherwise only the transaction hash is returned. -func (s *PublicBlockChainAPI) GetUncleByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) (map[string]interface{}, error) { - block, err := s.b.BlockByHash(ctx, blockHash) - if block != nil { - uncles := block.Uncles() - if index >= hexutil.Uint(len(uncles)) { - log.Trace("Requested uncle not found", "number", block.Number(), "hash", blockHash, "index", index) - return nil, nil - } - block = types.NewBlockWithHeader(uncles[index]) - return s.rpcMarshalBlock(ctx, block, false, false) - } - return nil, err -} - -// GetUncleCountByBlockNumber returns number of uncles in the block for the given block number -func (s *PublicBlockChainAPI) GetUncleCountByBlockNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint { - if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { - n := hexutil.Uint(len(block.Uncles())) - return &n - } - return nil -} - -// GetUncleCountByBlockHash returns number of uncles in the block for the given block hash -func (s *PublicBlockChainAPI) GetUncleCountByBlockHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint { - if block, _ := s.b.BlockByHash(ctx, blockHash); block != nil { - n := hexutil.Uint(len(block.Uncles())) - return &n - } - return nil -} - -// GetCode returns the code stored at the given address in the state for the given block number. -func (s *PublicBlockChainAPI) GetCode(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) { - state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) - if state == nil || err != nil { - return nil, err - } - code := state.GetCode(address) - return code, state.Error() -} - -// GetStorageAt returns the storage from the state at the given address, key and -// block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta block -// numbers are also allowed. -func (s *PublicBlockChainAPI) GetStorageAt(ctx context.Context, address common.Address, key string, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) { - state, _, err := s.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) - if state == nil || err != nil { - return nil, err - } - keyHash := common.HexToHash(key) - var res uint256.Int - state.GetState(address, &keyHash, &res) - return res.Bytes(), state.Error() -} -*/ - // CallArgs represents the arguments for a call. type CallArgs struct { From *common.Address `json:"from"` @@ -329,6 +41,7 @@ type CallArgs struct { MaxPriorityFeePerGas *hexutil.Big `json:"maxPriorityFeePerGas"` MaxFeePerGas *hexutil.Big `json:"maxFeePerGas"` Value *hexutil.Big `json:"value"` + Nonce *hexutil.Uint64 `json:"nonce"` Data *hexutil.Bytes `json:"data"` AccessList *types.AccessList `json:"accessList"` ChainID *hexutil.Big `json:"chainId,omitempty"` @@ -477,149 +190,6 @@ func (e *RevertError) ErrorData() interface{} { return e.reason } -/* -// Call executes the given transaction on the state for the given block number. -// -// Additionally, the caller can specify a batch of contract for fields overriding. -// -// Note, this function doesn't make and changes in the state/blockchain and is -// useful to execute and retrieve values. -func (s *PublicBlockChainAPI) Call(ctx context.Context, args CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *map[common.Address]Account) (hexutil.Bytes, error) { - var accounts map[common.Address]Account - if overrides != nil { - accounts = *overrides - } - result, err := DoCall(ctx, s.b, args, blockNrOrHash, accounts, vm.Config{}, 5*time.Second, s.b.RPCGasCap()) - if err != nil { - return nil, err - } - // If the result contains a revert reason, try to unpack and return it. - if len(result.Revert()) > 0 { - return nil, NewRevertError(result) - } - return result.Return(), result.Err -} - -func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNrOrHash rpc.BlockNumberOrHash, gasCap uint64) (hexutil.Uint64, error) { - // Binary search the gas requirement, as it may be higher than the amount used - var ( - lo uint64 = params.TxGas - 1 - hi uint64 - cap uint64 - ) - // Use zero address if sender unspecified. - if args.From == nil { - args.From = new(common.Address) - } - // Determine the highest gas limit can be used during the estimation. - if args.Gas != nil && uint64(*args.Gas) >= params.TxGas { - hi = uint64(*args.Gas) - } else { - // Retrieve the block to act as the gas ceiling - block, err := b.BlockByNumberOrHash(ctx, blockNrOrHash) - if err != nil { - return 0, err - } - if block == nil { - return 0, errors.New("block not found") - } - hi = block.GasLimit() - } - // Recap the highest gas limit with account's available balance. - if args.GasPrice != nil && args.GasPrice.ToInt().BitLen() != 0 { - state, _, err := b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) - if err != nil { - return 0, err - } - balance := state.GetBalance(*args.From) // from can't be nil - available := balance.ToBig() - if args.Value != nil { - if args.Value.ToInt().Cmp(available) >= 0 { - return 0, errors.New("insufficient funds for transfer") - } - available.Sub(available, args.Value.ToInt()) - } - allowance := new(big.Int).Div(available, args.GasPrice.ToInt()) - - // If the allowance is larger than maximum uint64, skip checking - if allowance.IsUint64() && hi > allowance.Uint64() { - transfer := args.Value - if transfer == nil { - transfer = new(hexutil.Big) - } - log.Warn("Gas estimation capped by limited funds", "original", hi, "balance", balance, - "sent", transfer.ToInt(), "gasprice", args.GasPrice.ToInt(), "fundable", allowance) - hi = allowance.Uint64() - } - } - // Recap the highest gas allowance with specified gascap. - if gasCap != 0 && hi > gasCap { - log.Warn("Caller gas above allowance, capping", "requested", hi, "cap", gasCap) - hi = gasCap - } - cap = hi - - // Create a helper to check if a gas allowance results in an executable transaction - executable := func(gas uint64) (bool, *core.ExecutionResult, error) { - args.Gas = (*hexutil.Uint64)(&gas) - - result, err := DoCall(ctx, b, args, blockNrOrHash, nil, vm.Config{}, 0, gasCap) - if err != nil { - if errors.Is(err, core.ErrIntrinsicGas) { - return true, nil, nil // Special case, raise gas limit - } - return true, nil, err // Bail out - } - return result.Failed(), result, nil - } - // Execute the binary search and hone in on an executable gas limit - for lo+1 < hi { - mid := (hi + lo) / 2 - failed, _, err := executable(mid) - - // If the error is not nil(consensus error), it means the provided message - // call or transaction will never be accepted no matter how much gas it is - // assigned. Return the error directly, don't struggle any more. - if err != nil { - return 0, err - } - if failed { - lo = mid - } else { - hi = mid - } - } - // Reject the transaction as invalid if it still fails at the highest allowance - if hi == cap { - failed, result, err := executable(hi) - if err != nil { - return 0, err - } - if failed { - if result != nil && result.Err != vm.ErrOutOfGas { - if len(result.Revert()) > 0 { - return 0, NewRevertError(result) - } - return 0, result.Err - } - // Otherwise, the specified gas cap is too low - return 0, fmt.Errorf("gas required exceeds allowance (%d)", cap) - } - } - return hexutil.Uint64(hi), nil -} - -// EstimateGas returns an estimate of the amount of gas needed to execute the -// given transaction against the current pending block. -func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs, blockNrOrHash *rpc.BlockNumberOrHash) (hexutil.Uint64, error) { - bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber) - if blockNrOrHash != nil { - bNrOrHash = *blockNrOrHash - } - return DoEstimateGas(ctx, s.b, args, bNrOrHash, s.b.RPCGasCap()) -} -*/ - // ExecutionResult groups all structured logs emitted by the EVM // while replaying a transaction in debug mode as well as transaction // execution status, the amount of gas used and the return value From 46ea50241f6fa67a56b829d3bebb77793467675e Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Mon, 29 Nov 2021 17:05:41 +0000 Subject: [PATCH 047/261] Upgrade GitHub Actions to macOS 11 (#3054) (#3055) --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 955251508b0..7b62a698c7a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ jobs: tests: strategy: matrix: - os: [ ubuntu-20.04, macos-10.15 ] # list of os: https://github.com/actions/virtual-environments + os: [ ubuntu-20.04, macos-11 ] # list of os: https://github.com/actions/virtual-environments runs-on: ${{ matrix.os }} steps: From 5fecd9738036c6a15a6226715dcc3eccd9ebc6e0 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Tue, 30 Nov 2021 14:09:39 +0700 Subject: [PATCH 048/261] save (#3058) --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 6217b67d86c..770de1069d8 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20211126140914-20cf6326808f + github.com/ledgerwatch/erigon-lib v0.0.0-20211130023852-d5c8a5b8d0d9 github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 diff --git a/go.sum b/go.sum index 8e9b26034f0..cbd798f263a 100644 --- a/go.sum +++ b/go.sum @@ -499,6 +499,8 @@ github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7 github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/ledgerwatch/erigon-lib v0.0.0-20211126140914-20cf6326808f h1:+UndlhFtwMGAtjcOHbftwTcRh8SErgJ4eN+7efsxogw= github.com/ledgerwatch/erigon-lib v0.0.0-20211126140914-20cf6326808f/go.mod h1:lyGP3i0x4CeabdKZ4beycD5xZfHWZwJsAX+70OfGj4Y= +github.com/ledgerwatch/erigon-lib v0.0.0-20211130023852-d5c8a5b8d0d9 h1:b3zPqvi3xlyQGyJFRqoHk6yrMgFjfYAscC4DB4z2xog= +github.com/ledgerwatch/erigon-lib v0.0.0-20211130023852-d5c8a5b8d0d9/go.mod h1:lyGP3i0x4CeabdKZ4beycD5xZfHWZwJsAX+70OfGj4Y= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= From 410bb0d8c29ba708e3267e3dfadadeb414d053dd Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Tue, 30 Nov 2021 17:01:43 +0700 Subject: [PATCH 049/261] save (#3059) --- cmd/integration/commands/reset_state.go | 3 +-- core/genesis.go | 16 ---------------- 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/cmd/integration/commands/reset_state.go b/cmd/integration/commands/reset_state.go index 4308e4860d9..ca091bc76de 100644 --- a/cmd/integration/commands/reset_state.go +++ b/cmd/integration/commands/reset_state.go @@ -148,8 +148,7 @@ func resetExec(tx kv.RwTx, g *core.Genesis) error { return err } - _, _, err := core.OverrideGenesisBlock(tx, g) - if err != nil { + if _, _, err := g.WriteGenesisState(tx); err != nil { return err } return nil diff --git a/core/genesis.go b/core/genesis.go index 1b72d29970a..b252187befd 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -194,22 +194,6 @@ func MustCommitGenesisBlock(db kv.RwDB, genesis *Genesis) (*params.ChainConfig, return c, b } -func OverrideGenesisBlock(db kv.RwTx, genesis *Genesis) (*params.ChainConfig, *types.Block, error) { - stored, err := rawdb.ReadCanonicalHash(db, 0) - if err != nil { - return nil, nil, err - } - err = rawdb.DeleteCanonicalHash(db, 0) - if err != nil { - return nil, nil, err - } - err = rawdb.DeleteChainConfig(db, stored) - if err != nil { - return nil, nil, err - } - return WriteGenesisBlock(db, genesis) -} - func WriteGenesisBlock(db kv.RwTx, genesis *Genesis) (*params.ChainConfig, *types.Block, error) { if genesis != nil && genesis.Config == nil { return params.AllEthashProtocolChanges, nil, ErrGenesisNoConfig From dad09ab94e5ba39926586b84c9b7fa1d452ac548 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Wed, 1 Dec 2021 08:28:50 +0000 Subject: [PATCH 050/261] [beta] Reverse order of arguments in eth_createAccessList (#3067) * Reverse order of arguments in eth_createAccessList (#3066) Co-authored-by: Alex Sharp * More info about remote RPC Daemon state cache + eth_createAccessList (#3068) Co-authored-by: Alex Sharp --- cmd/rpcdaemon/README.md | 7 +++++++ cmd/rpcdaemon/commands/eth_api.go | 2 +- cmd/rpcdaemon/commands/eth_call.go | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/cmd/rpcdaemon/README.md b/cmd/rpcdaemon/README.md index f137877c8c1..cc27e6fcec5 100644 --- a/cmd/rpcdaemon/README.md +++ b/cmd/rpcdaemon/README.md @@ -64,6 +64,12 @@ The daemon should respond with something like: INFO [date-time] HTTP endpoint opened url=localhost:8545... ``` +When RPC daemon runs remotely, by default it maintains a state cache, which is updated every time when Erigon +imports a new block. When state cache is reasonably warm, it allows such remote RPC daemon to execute queries +related to `latest` block (i.e. to current state) with comparable performance to a local RPC daemon +(around 2x slower vs 10x slower without state cache). Since there can be multiple such RPC daemons per one +Erigon node, it may scale well for some workloads that are heavy on the current state queries. + ### Healthcheck Running the daemon also opens an endpoint `/health` that provides a basic health check. @@ -191,6 +197,7 @@ The following table shows the current implementation status of Erigon's RPC daem | eth_getStorageAt | Yes | | | eth_call | Yes | | | eth_callBundle | Yes | | +| eth_createAccessList | Yes | | | | | | eth_newFilter | - | not yet implemented | | eth_newBlockFilter | - | not yet implemented | diff --git a/cmd/rpcdaemon/commands/eth_api.go b/cmd/rpcdaemon/commands/eth_api.go index 184e0310bfb..da2dba01385 100644 --- a/cmd/rpcdaemon/commands/eth_api.go +++ b/cmd/rpcdaemon/commands/eth_api.go @@ -81,7 +81,7 @@ type EthAPI interface { Sign(ctx context.Context, _ common.Address, _ hexutil.Bytes) (hexutil.Bytes, error) SignTransaction(_ context.Context, txObject interface{}) (common.Hash, error) GetProof(ctx context.Context, address common.Address, storageKeys []string, blockNr rpc.BlockNumber) (*interface{}, error) - CreateAccessList(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash, args ethapi.CallArgs) (*accessListResult, error) + CreateAccessList(ctx context.Context, args ethapi.CallArgs, blockNrOrHash rpc.BlockNumberOrHash) (*accessListResult, error) // Mining related (see ./eth_mining.go) Coinbase(ctx context.Context) (common.Address, error) diff --git a/cmd/rpcdaemon/commands/eth_call.go b/cmd/rpcdaemon/commands/eth_call.go index ebb9b4e3132..23b24d102b7 100644 --- a/cmd/rpcdaemon/commands/eth_call.go +++ b/cmd/rpcdaemon/commands/eth_call.go @@ -295,7 +295,7 @@ type accessListResult struct { // CreateAccessList implements eth_createAccessList. It creates an access list for the given transaction. // If the accesslist creation fails an error is returned. // If the transaction itself fails, an vmErr is returned. -func (api *APIImpl) CreateAccessList(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash, args ethapi.CallArgs) (*accessListResult, error) { +func (api *APIImpl) CreateAccessList(ctx context.Context, args ethapi.CallArgs, blockNrOrHash rpc.BlockNumberOrHash) (*accessListResult, error) { tx, err := api.db.BeginRo(ctx) if err != nil { return nil, err From cce47a061748279e27ab314048d7c8710862733c Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Thu, 2 Dec 2021 13:40:20 +0000 Subject: [PATCH 051/261] [beta] admin_nodeInfo implementation (#3073) * Add NodeInfo implementation (#3046) * Add NodeInfo implementation * replace magic value with a constant. * update dependencies * bump minor version * add nodes deduplication logic. * shuffle values in test cases a little. * Remove deduplication in NodeInfo response (#3070) * Remove deduplication in NodeInfo response * remove unused dependencies * Adjust erigon-lib dependency * Bump ethBackend interface version Co-authored-by: Dmitry Savelev <12631916+dsavelev@users.noreply.github.com> Co-authored-by: Alexey Sharp --- cmd/rpcdaemon/commands/admin_api.go | 41 +++++++++++++++++++++++ cmd/rpcdaemon/commands/daemon.go | 10 +++++- cmd/rpcdaemon/commands/erigon_api.go | 15 ++++++--- cmd/rpcdaemon/commands/erigon_nodeInfo.go | 16 +++++++++ cmd/rpcdaemon/services/eth_backend.go | 41 +++++++++++++++++++++++ cmd/sentry/download/sentry.go | 29 ++++++++++++++++ eth/backend.go | 26 ++++++++++++++ ethdb/privateapi/ethbackend.go | 12 ++++++- go.mod | 2 +- go.sum | 6 ++-- 10 files changed, 187 insertions(+), 11 deletions(-) create mode 100644 cmd/rpcdaemon/commands/admin_api.go create mode 100644 cmd/rpcdaemon/commands/erigon_nodeInfo.go diff --git a/cmd/rpcdaemon/commands/admin_api.go b/cmd/rpcdaemon/commands/admin_api.go new file mode 100644 index 00000000000..abf8518a105 --- /dev/null +++ b/cmd/rpcdaemon/commands/admin_api.go @@ -0,0 +1,41 @@ +package commands + +import ( + "context" + "errors" + "fmt" + + "github.com/ledgerwatch/erigon/cmd/rpcdaemon/services" + "github.com/ledgerwatch/erigon/p2p" +) + +// AdminAPI the interface for the admin_* RPC commands. +type AdminAPI interface { + // NodeInfo returns a collection of metadata known about the host. + NodeInfo(ctx context.Context) (*p2p.NodeInfo, error) +} + +// AdminAPIImpl data structure to store things needed for admin_* commands. +type AdminAPIImpl struct { + ethBackend services.ApiBackend +} + +// NewAdminAPI returns AdminAPIImpl instance. +func NewAdminAPI(eth services.ApiBackend) *AdminAPIImpl { + return &AdminAPIImpl{ + ethBackend: eth, + } +} + +func (api *AdminAPIImpl) NodeInfo(ctx context.Context) (*p2p.NodeInfo, error) { + nodes, err := api.ethBackend.NodeInfo(ctx, 1) + if err != nil { + return nil, fmt.Errorf("node info request error: %w", err) + } + + if len(nodes) == 0 { + return nil, errors.New("empty nodesInfo response") + } + + return &nodes[0], nil +} diff --git a/cmd/rpcdaemon/commands/daemon.go b/cmd/rpcdaemon/commands/daemon.go index 67ae90a4c34..9d59b825522 100644 --- a/cmd/rpcdaemon/commands/daemon.go +++ b/cmd/rpcdaemon/commands/daemon.go @@ -24,13 +24,14 @@ func APIList(ctx context.Context, db kv.RoDB, base.EnableTevmExperiment() } ethImpl := NewEthAPI(base, db, eth, txPool, mining, cfg.Gascap) - erigonImpl := NewErigonAPI(base, db) + erigonImpl := NewErigonAPI(base, db, eth) txpoolImpl := NewTxPoolAPI(base, db, txPool) netImpl := NewNetAPIImpl(eth) debugImpl := NewPrivateDebugAPI(base, db, cfg.Gascap) traceImpl := NewTraceAPI(base, db, &cfg) web3Impl := NewWeb3APIImpl(eth) dbImpl := NewDBAPIImpl() /* deprecated */ + adminImpl := NewAdminAPI(eth) for _, enabledAPI := range cfg.API { switch enabledAPI { @@ -90,6 +91,13 @@ func APIList(ctx context.Context, db kv.RoDB, Service: ErigonAPI(erigonImpl), Version: "1.0", }) + case "admin": + defaultAPIList = append(defaultAPIList, rpc.API{ + Namespace: "admin", + Public: false, + Service: AdminAPI(adminImpl), + Version: "1.0", + }) } } diff --git a/cmd/rpcdaemon/commands/erigon_api.go b/cmd/rpcdaemon/commands/erigon_api.go index 9870b6b683e..c95d96312b0 100644 --- a/cmd/rpcdaemon/commands/erigon_api.go +++ b/cmd/rpcdaemon/commands/erigon_api.go @@ -4,8 +4,10 @@ import ( "context" "github.com/ledgerwatch/erigon-lib/kv" + "github.com/ledgerwatch/erigon/cmd/rpcdaemon/services" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/p2p" "github.com/ledgerwatch/erigon/rpc" ) @@ -26,18 +28,23 @@ type ErigonAPI interface { // BlockReward(ctx context.Context, blockNr rpc.BlockNumber) (Issuance, error) // UncleReward(ctx context.Context, blockNr rpc.BlockNumber) (Issuance, error) Issuance(ctx context.Context, blockNr rpc.BlockNumber) (Issuance, error) + + // NodeInfo returns a collection of metadata known about the host. + NodeInfo(ctx context.Context) ([]p2p.NodeInfo, error) } // ErigonImpl is implementation of the ErigonAPI interface type ErigonImpl struct { *BaseAPI - db kv.RoDB + db kv.RoDB + ethBackend services.ApiBackend } // NewErigonAPI returns ErigonImpl instance -func NewErigonAPI(base *BaseAPI, db kv.RoDB) *ErigonImpl { +func NewErigonAPI(base *BaseAPI, db kv.RoDB, eth services.ApiBackend) *ErigonImpl { return &ErigonImpl{ - BaseAPI: base, - db: db, + BaseAPI: base, + db: db, + ethBackend: eth, } } diff --git a/cmd/rpcdaemon/commands/erigon_nodeInfo.go b/cmd/rpcdaemon/commands/erigon_nodeInfo.go new file mode 100644 index 00000000000..68ef98d9299 --- /dev/null +++ b/cmd/rpcdaemon/commands/erigon_nodeInfo.go @@ -0,0 +1,16 @@ +package commands + +import ( + "context" + + "github.com/ledgerwatch/erigon/p2p" +) + +const ( + // allNodesInfo used in NodeInfo request to receive meta data from all running sentries. + allNodesInfo = 0 +) + +func (api *ErigonImpl) NodeInfo(ctx context.Context) ([]p2p.NodeInfo, error) { + return api.ethBackend.NodeInfo(ctx, allNodesInfo) +} diff --git a/cmd/rpcdaemon/services/eth_backend.go b/cmd/rpcdaemon/services/eth_backend.go index 6b3a45430bc..a1bdc23cdfe 100644 --- a/cmd/rpcdaemon/services/eth_backend.go +++ b/cmd/rpcdaemon/services/eth_backend.go @@ -2,6 +2,7 @@ package services import ( "context" + "encoding/json" "errors" "fmt" "io" @@ -10,6 +11,7 @@ import ( "github.com/ledgerwatch/erigon-lib/gointerfaces/remote" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/ethdb/privateapi" + "github.com/ledgerwatch/erigon/p2p" "github.com/ledgerwatch/log/v3" "google.golang.org/grpc" "google.golang.org/grpc/status" @@ -26,6 +28,7 @@ type ApiBackend interface { ProtocolVersion(ctx context.Context) (uint64, error) ClientVersion(ctx context.Context) (string, error) Subscribe(ctx context.Context, cb func(*remote.SubscribeReply)) error + NodeInfo(ctx context.Context, limit uint32) ([]p2p.NodeInfo, error) } type RemoteBackend struct { @@ -141,3 +144,41 @@ func (back *RemoteBackend) Subscribe(ctx context.Context, onNewEvent func(*remot } return nil } + +func (back *RemoteBackend) NodeInfo(ctx context.Context, limit uint32) ([]p2p.NodeInfo, error) { + nodes, err := back.remoteEthBackend.NodeInfo(ctx, &remote.NodesInfoRequest{Limit: limit}) + if err != nil { + return nil, fmt.Errorf("nodes info request error: %w", err) + } + + if nodes == nil || len(nodes.NodesInfo) == 0 { + return nil, errors.New("empty nodesInfo response") + } + + ret := make([]p2p.NodeInfo, 0, len(nodes.NodesInfo)) + for _, node := range nodes.NodesInfo { + var protocols map[string]interface{} + if err = json.Unmarshal(node.Protocols, &protocols); err != nil { + return nil, fmt.Errorf("cannot decode protocols metadata: %w", err) + } + + ret = append(ret, p2p.NodeInfo{ + Enode: node.Enode, + ID: node.Id, + IP: node.Enode, + ENR: node.Enr, + ListenAddr: node.ListenerAddr, + Name: node.Name, + Ports: struct { + Discovery int `json:"discovery"` + Listener int `json:"listener"` + }{ + Discovery: int(node.Ports.Discovery), + Listener: int(node.Ports.Listener), + }, + Protocols: protocols, + }) + } + + return ret, nil +} diff --git a/cmd/sentry/download/sentry.go b/cmd/sentry/download/sentry.go index 01bb43b7ac3..c1e81639c92 100644 --- a/cmd/sentry/download/sentry.go +++ b/cmd/sentry/download/sentry.go @@ -3,6 +3,8 @@ package download import ( "bytes" "context" + "encoding/json" + "errors" "fmt" "io" "math" @@ -990,6 +992,33 @@ func (ss *SentryServerImpl) Peers(req *proto_sentry.PeersRequest, server proto_s } } +func (ss *SentryServerImpl) NodeInfo(_ context.Context, _ *emptypb.Empty) (*proto_types.NodeInfoReply, error) { + if ss.P2pServer == nil { + return nil, errors.New("p2p server was not started") + } + + info := ss.P2pServer.NodeInfo() + ret := &proto_types.NodeInfoReply{ + Id: info.ID, + Name: info.Name, + Enode: info.Enode, + Enr: info.ENR, + Ports: &proto_types.NodeInfoPorts{ + Discovery: uint32(info.Ports.Discovery), + Listener: uint32(info.Ports.Listener), + }, + ListenerAddr: info.ListenAddr, + } + + protos, err := json.Marshal(info.Protocols) + if err != nil { + return nil, fmt.Errorf("cannot encode protocols map: %w", err) + } + + ret.Protocols = protos + return ret, nil +} + // PeersStreams - it's safe to use this class as non-pointer type PeersStreams struct { mu sync.RWMutex diff --git a/eth/backend.go b/eth/backend.go index ec8a762447d..9ba4fd6b27c 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -25,6 +25,7 @@ import ( "os" "path" "reflect" + "sort" "strconv" "sync" "time" @@ -34,8 +35,10 @@ import ( "github.com/ledgerwatch/erigon-lib/direct" "github.com/ledgerwatch/erigon-lib/etl" "github.com/ledgerwatch/erigon-lib/gointerfaces/grpcutil" + "github.com/ledgerwatch/erigon-lib/gointerfaces/remote" "github.com/ledgerwatch/erigon-lib/gointerfaces/sentry" txpool_proto "github.com/ledgerwatch/erigon-lib/gointerfaces/txpool" + prototypes "github.com/ledgerwatch/erigon-lib/gointerfaces/types" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv/kvcache" "github.com/ledgerwatch/erigon-lib/kv/remotedbserver" @@ -662,6 +665,29 @@ func (s *Ethereum) NetPeerCount() (uint64, error) { return sentryPc, nil } +func (s *Ethereum) NodesInfo(limit int) (*remote.NodesInfoReply, error) { + if limit == 0 || limit > len(s.sentries) { + limit = len(s.sentries) + } + + nodes := make([]*prototypes.NodeInfoReply, 0, limit) + for i := 0; i < limit; i++ { + sc := s.sentries[i] + + nodeInfo, err := sc.NodeInfo(context.Background(), nil) + if err != nil { + log.Error("sentry nodeInfo", "err", err) + } + + nodes = append(nodes, nodeInfo) + } + + nodesInfo := &remote.NodesInfoReply{NodesInfo: nodes} + sort.Sort(nodesInfo) + + return nodesInfo, nil +} + // Protocols returns all the currently configured // network protocols to start. func (s *Ethereum) Protocols() []p2p.Protocol { diff --git a/ethdb/privateapi/ethbackend.go b/ethdb/privateapi/ethbackend.go index c9967323fa9..80730ff960c 100644 --- a/ethdb/privateapi/ethbackend.go +++ b/ethdb/privateapi/ethbackend.go @@ -18,7 +18,8 @@ import ( // EthBackendAPIVersion // 2.0.0 - move all mining-related methods to 'txpool/mining' server // 2.1.0 - add NetPeerCount function -var EthBackendAPIVersion = &types2.VersionReply{Major: 2, Minor: 1, Patch: 0} +// 2.2.0 - add NodesInfo function +var EthBackendAPIVersion = &types2.VersionReply{Major: 2, Minor: 2, Patch: 0} type EthBackendServer struct { remote.UnimplementedETHBACKENDServer // must be embedded to have forward compatible implementations. @@ -32,6 +33,7 @@ type EthBackend interface { Etherbase() (common.Address, error) NetVersion() (uint64, error) NetPeerCount() (uint64, error) + NodesInfo(limit int) (*remote.NodesInfoReply, error) } func NewEthBackendServer(ctx context.Context, eth EthBackend, events *Events) *EthBackendServer { @@ -121,3 +123,11 @@ func (s *EthBackendServer) ProtocolVersion(_ context.Context, _ *remote.Protocol func (s *EthBackendServer) ClientVersion(_ context.Context, _ *remote.ClientVersionRequest) (*remote.ClientVersionReply, error) { return &remote.ClientVersionReply{NodeName: common.MakeName("erigon", params.Version)}, nil } + +func (s *EthBackendServer) NodeInfo(_ context.Context, r *remote.NodesInfoRequest) (*remote.NodesInfoReply, error) { + nodesInfo, err := s.eth.NodesInfo(int(r.Limit)) + if err != nil { + return nil, err + } + return nodesInfo, nil +} diff --git a/go.mod b/go.mod index 770de1069d8..335bda49199 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20211130023852-d5c8a5b8d0d9 + github.com/ledgerwatch/erigon-lib v0.0.0-20211201135019-85b4119c0f58 github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 diff --git a/go.sum b/go.sum index cbd798f263a..70bb1e089ae 100644 --- a/go.sum +++ b/go.sum @@ -497,10 +497,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20211126140914-20cf6326808f h1:+UndlhFtwMGAtjcOHbftwTcRh8SErgJ4eN+7efsxogw= -github.com/ledgerwatch/erigon-lib v0.0.0-20211126140914-20cf6326808f/go.mod h1:lyGP3i0x4CeabdKZ4beycD5xZfHWZwJsAX+70OfGj4Y= -github.com/ledgerwatch/erigon-lib v0.0.0-20211130023852-d5c8a5b8d0d9 h1:b3zPqvi3xlyQGyJFRqoHk6yrMgFjfYAscC4DB4z2xog= -github.com/ledgerwatch/erigon-lib v0.0.0-20211130023852-d5c8a5b8d0d9/go.mod h1:lyGP3i0x4CeabdKZ4beycD5xZfHWZwJsAX+70OfGj4Y= +github.com/ledgerwatch/erigon-lib v0.0.0-20211201135019-85b4119c0f58 h1:VXWRbNnhTaCkKMSQY9z7zjnhOQiFesFzWRLINJI12n4= +github.com/ledgerwatch/erigon-lib v0.0.0-20211201135019-85b4119c0f58/go.mod h1:lyGP3i0x4CeabdKZ4beycD5xZfHWZwJsAX+70OfGj4Y= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= From 29387e8ceba2a7ae841a297d733860dd1558d38d Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Thu, 2 Dec 2021 15:26:53 -0300 Subject: [PATCH 052/261] Add ots_hasCode rpc method; increment API level --- cmd/rpcdaemon/commands/otterscan_api.go | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 3ba6cdc4315..1d2ca7daac1 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -22,6 +22,8 @@ import ( otterscan "github.com/ledgerwatch/erigon/otterscan/transactions" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/rpc" + "github.com/ledgerwatch/erigon/turbo/adapter" + "github.com/ledgerwatch/erigon/turbo/rpchelper" "github.com/ledgerwatch/erigon/turbo/shards" "github.com/ledgerwatch/erigon/turbo/transactions" "github.com/ledgerwatch/log/v3" @@ -30,7 +32,7 @@ import ( ) // API_LEVEL Must be incremented every time new additions are made -const API_LEVEL = 3 +const API_LEVEL = 4 type SearchResult struct { BlockNumber uint64 @@ -54,6 +56,7 @@ type OtterscanAPI interface { SearchTransactionsAfter(ctx context.Context, addr common.Address, blockNum uint64, minPageSize uint16) (*TransactionsWithReceipts, error) GetBlockDetails(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) GetBlockTransactions(ctx context.Context, number rpc.BlockNumber, pageNumber uint8, pageSize uint8) (map[string]interface{}, error) + HasCode(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (bool, error) TraceTransaction(ctx context.Context, hash common.Hash) ([]*otterscan.TraceEntry, error) } @@ -719,6 +722,26 @@ func (api *OtterscanAPIImpl) GetBlockTransactions(ctx context.Context, number rp return response, nil } +func (api *OtterscanAPIImpl) HasCode(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (bool, error) { + tx, err := api.db.BeginRo(ctx) + if err != nil { + return false, fmt.Errorf("hasCode cannot open tx: %w", err) + } + defer tx.Rollback() + + blockNumber, _, err := rpchelper.GetBlockNumber(blockNrOrHash, tx, api.filters) + if err != nil { + return false, err + } + + reader := adapter.NewStateReader(tx, blockNumber) + acc, err := reader.ReadAccountData(address) + if err != nil { + return false, err + } + return !acc.IsEmptyCodeHash(), nil +} + func (api *OtterscanAPIImpl) TraceTransaction(ctx context.Context, hash common.Hash) ([]*otterscan.TraceEntry, error) { tx, err := api.db.BeginRo(ctx) if err != nil { From 614acad51dd4472c299a9ec008dac58101242b6d Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Fri, 3 Dec 2021 15:39:26 +0000 Subject: [PATCH 053/261] Fix NodeInfo protocols decoding (#3081) (#3082) Co-authored-by: Dmitry Savelev <12631916+dsavelev@users.noreply.github.com> --- cmd/rpcdaemon/services/eth_backend.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cmd/rpcdaemon/services/eth_backend.go b/cmd/rpcdaemon/services/eth_backend.go index a1bdc23cdfe..e4088b72961 100644 --- a/cmd/rpcdaemon/services/eth_backend.go +++ b/cmd/rpcdaemon/services/eth_backend.go @@ -157,11 +157,16 @@ func (back *RemoteBackend) NodeInfo(ctx context.Context, limit uint32) ([]p2p.No ret := make([]p2p.NodeInfo, 0, len(nodes.NodesInfo)) for _, node := range nodes.NodesInfo { - var protocols map[string]interface{} - if err = json.Unmarshal(node.Protocols, &protocols); err != nil { + var rawProtocols map[string]json.RawMessage + if err = json.Unmarshal(node.Protocols, &rawProtocols); err != nil { return nil, fmt.Errorf("cannot decode protocols metadata: %w", err) } + protocols := make(map[string]interface{}, len(rawProtocols)) + for k, v := range rawProtocols { + protocols[k] = v + } + ret = append(ret, p2p.NodeInfo{ Enode: node.Enode, ID: node.Id, From c9108ae271ccae408ce3d4445e943a2c2b47ac94 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Fri, 3 Dec 2021 15:39:39 +0000 Subject: [PATCH 054/261] eth_getLogs to start from latest by default (#3079) (#3084) * eth_getLogs to start from latest by default * Update eth_receipts.go * Update eth_receipts.go * Update eth_receipts.go --- cmd/rpcdaemon/commands/eth_receipts.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/rpcdaemon/commands/eth_receipts.go b/cmd/rpcdaemon/commands/eth_receipts.go index 535d821b39a..d749e6df77b 100644 --- a/cmd/rpcdaemon/commands/eth_receipts.go +++ b/cmd/rpcdaemon/commands/eth_receipts.go @@ -90,11 +90,11 @@ func (api *APIImpl) GetLogs(ctx context.Context, crit filters.FilterCriteria) ([ return nil, err } - begin = 0 + begin = latest if crit.FromBlock != nil { if crit.FromBlock.Sign() >= 0 { begin = crit.FromBlock.Uint64() - } else { + } else if !crit.FromBlock.IsInt64() || crit.FromBlock.Int64() != int64(rpc.LatestBlockNumber) { return nil, fmt.Errorf("negative value for FromBlock: %v", crit.FromBlock) } } @@ -102,7 +102,7 @@ func (api *APIImpl) GetLogs(ctx context.Context, crit filters.FilterCriteria) ([ if crit.ToBlock != nil { if crit.ToBlock.Sign() >= 0 { end = crit.ToBlock.Uint64() - } else { + } else if !crit.ToBlock.IsInt64() || crit.ToBlock.Int64() != int64(rpc.LatestBlockNumber) { return nil, fmt.Errorf("negative value for ToBlock: %v", crit.ToBlock) } } From 276b6c085178f4c0e04262247853796b44fc2f2d Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Mon, 6 Dec 2021 08:46:50 +0000 Subject: [PATCH 055/261] [beta] Bump version to 2021.12.02 (#3085) --- params/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/params/version.go b/params/version.go index e0126036dad..7107e305f22 100644 --- a/params/version.go +++ b/params/version.go @@ -33,7 +33,7 @@ var ( const ( VersionMajor = 2021 // Major version component of the current release VersionMinor = 12 // Minor version component of the current release - VersionMicro = 1 // Patch version component of the current release + VersionMicro = 2 // Patch version component of the current release VersionModifier = "beta" // Patch version component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" From 0e4fab289d147821dbcd6694fe9593b4b0fea027 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Mon, 6 Dec 2021 09:40:38 +0000 Subject: [PATCH 056/261] [beta] Stricter uint256 RLP decoding. Update consensus tests to 10.1 (#3089) (#3095) * Clean up test runners. Don't run legacy tests * Cherry pick https://github.com/ethereum/go-ethereum/pull/22927 * Tests update 10.1: Transaction Tests * Port decodeBigInt changes to decodeUint256 * Introduce (*Stream) Uint256Bytes * Temporarily disable stTransactionTest/HighGasPrice * linter * ttWrongRLP transaction tests pass now * Fix stTransactionTest/HighGasPrice Co-authored-by: Felix Lange Co-authored-by: Andrew Ashikhmin <34320705+yperbasis@users.noreply.github.com> Co-authored-by: Felix Lange --- core/state_transition.go | 15 ++++-- core/types/access_list_tx.go | 30 +++-------- core/types/block.go | 15 ++---- core/types/dynamic_fee_tx.go | 35 +++---------- core/types/legacy_tx.go | 25 ++------- eth/protocols/eth/protocol.go | 5 +- rlp/decode.go | 96 +++++++++++++++++++++++++--------- rlp/decode_test.go | 22 ++++++-- rlp/encode_test.go | 8 +++ tests/block_test.go | 33 +----------- tests/init_test.go | 2 - tests/state_test.go | 74 +++++++++----------------- tests/state_test_util.go | 7 --- tests/testdata | 2 +- tests/transaction_test.go | 11 +--- tests/transaction_test_util.go | 49 ++++++++++------- tests/vm_test.go | 47 ----------------- 17 files changed, 191 insertions(+), 285 deletions(-) delete mode 100644 tests/vm_test.go diff --git a/core/state_transition.go b/core/state_transition.go index 307e70d6db1..b54de8d769a 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -203,12 +203,21 @@ func (st *StateTransition) to() common.Address { func (st *StateTransition) buyGas(gasBailout bool) error { mgval := st.sharedBuyGas mgval.SetUint64(st.msg.Gas()) - mgval = mgval.Mul(mgval, st.gasPrice) + mgval, overflow := mgval.MulOverflow(mgval, st.gasPrice) + if overflow { + return fmt.Errorf("%w: address %v", ErrInsufficientFunds, st.msg.From().Hex()) + } balanceCheck := mgval if st.gasFeeCap != nil { balanceCheck = st.sharedBuyGasBalance.SetUint64(st.msg.Gas()) - balanceCheck = balanceCheck.Mul(balanceCheck, st.gasFeeCap) - balanceCheck.Add(balanceCheck, st.value) + balanceCheck, overflow = balanceCheck.MulOverflow(balanceCheck, st.gasFeeCap) + if overflow { + return fmt.Errorf("%w: address %v", ErrInsufficientFunds, st.msg.From().Hex()) + } + balanceCheck, overflow = balanceCheck.AddOverflow(balanceCheck, st.value) + if overflow { + return fmt.Errorf("%w: address %v", ErrInsufficientFunds, st.msg.From().Hex()) + } } if have, want := st.state.GetBalance(st.msg.From()), balanceCheck; have.Cmp(want) < 0 { if !gasBailout { diff --git a/core/types/access_list_tx.go b/core/types/access_list_tx.go index 0dd41185445..d46031efdb0 100644 --- a/core/types/access_list_tx.go +++ b/core/types/access_list_tx.go @@ -465,22 +465,16 @@ func (tx *AccessListTx) DecodeRLP(s *rlp.Stream) error { return err } var b []byte - if b, err = s.Bytes(); err != nil { + if b, err = s.Uint256Bytes(); err != nil { return fmt.Errorf("read ChainID: %w", err) } - if len(b) > 32 { - return fmt.Errorf("wrong size for ChainID: %d", len(b)) - } tx.ChainID = new(uint256.Int).SetBytes(b) if tx.Nonce, err = s.Uint(); err != nil { return fmt.Errorf("read Nonce: %w", err) } - if b, err = s.Bytes(); err != nil { + if b, err = s.Uint256Bytes(); err != nil { return fmt.Errorf("read GasPrice: %w", err) } - if len(b) > 32 { - return fmt.Errorf("wrong size for GasPrice: %d", len(b)) - } tx.GasPrice = new(uint256.Int).SetBytes(b) if tx.Gas, err = s.Uint(); err != nil { return fmt.Errorf("read Gas: %w", err) @@ -495,12 +489,9 @@ func (tx *AccessListTx) DecodeRLP(s *rlp.Stream) error { tx.To = &common.Address{} copy((*tx.To)[:], b) } - if b, err = s.Bytes(); err != nil { + if b, err = s.Uint256Bytes(); err != nil { return fmt.Errorf("read Value: %w", err) } - if len(b) > 32 { - return fmt.Errorf("wrong size for Value: %d", len(b)) - } tx.Value = new(uint256.Int).SetBytes(b) if tx.Data, err = s.Bytes(); err != nil { return fmt.Errorf("read Data: %w", err) @@ -511,26 +502,17 @@ func (tx *AccessListTx) DecodeRLP(s *rlp.Stream) error { return fmt.Errorf("read AccessList: %w", err) } // decode V - if b, err = s.Bytes(); err != nil { + if b, err = s.Uint256Bytes(); err != nil { return fmt.Errorf("read V: %w", err) } - if len(b) > 32 { - return fmt.Errorf("wrong size for V: %d", len(b)) - } tx.V.SetBytes(b) - if b, err = s.Bytes(); err != nil { + if b, err = s.Uint256Bytes(); err != nil { return fmt.Errorf("read R: %w", err) } - if len(b) > 32 { - return fmt.Errorf("wrong size for R: %d", len(b)) - } tx.R.SetBytes(b) - if b, err = s.Bytes(); err != nil { + if b, err = s.Uint256Bytes(); err != nil { return fmt.Errorf("read S: %w", err) } - if len(b) > 32 { - return fmt.Errorf("wrong size for S: %d", len(b)) - } tx.S.SetBytes(b) if err := s.ListEnd(); err != nil { return fmt.Errorf("close AccessListTx: %w", err) diff --git a/core/types/block.go b/core/types/block.go index 6a16ab4b600..d48c3cd168a 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -463,19 +463,13 @@ func (h *Header) DecodeRLP(s *rlp.Stream) error { return fmt.Errorf("wrong size for Bloom: %d", len(b)) } copy(h.Bloom[:], b) - if b, err = s.Bytes(); err != nil { + if b, err = s.Uint256Bytes(); err != nil { return fmt.Errorf("read Difficulty: %w", err) } - if len(b) > 32 { - return fmt.Errorf("wrong size for Difficulty: %d", len(b)) - } h.Difficulty = new(big.Int).SetBytes(b) - if b, err = s.Bytes(); err != nil { + if b, err = s.Uint256Bytes(); err != nil { return fmt.Errorf("read Number: %w", err) } - if len(b) > 32 { - return fmt.Errorf("wrong size for Number: %d", len(b)) - } h.Number = new(big.Int).SetBytes(b) if h.GasLimit, err = s.Uint(); err != nil { return fmt.Errorf("read GasLimit: %w", err) @@ -513,7 +507,7 @@ func (h *Header) DecodeRLP(s *rlp.Stream) error { return fmt.Errorf("wrong size for Nonce: %d", len(b)) } copy(h.Nonce[:], b) - if b, err = s.Bytes(); err != nil { + if b, err = s.Uint256Bytes(); err != nil { if errors.Is(err, rlp.EOL) { h.BaseFee = nil h.Eip1559 = false @@ -524,9 +518,6 @@ func (h *Header) DecodeRLP(s *rlp.Stream) error { } return fmt.Errorf("read BaseFee: %w", err) } - if len(b) > 32 { - return fmt.Errorf("wrong size for BaseFee: %d", len(b)) - } h.Eip1559 = true h.BaseFee = new(big.Int).SetBytes(b) } diff --git a/core/types/dynamic_fee_tx.go b/core/types/dynamic_fee_tx.go index fce6d6197d1..ed8b99d446f 100644 --- a/core/types/dynamic_fee_tx.go +++ b/core/types/dynamic_fee_tx.go @@ -378,29 +378,20 @@ func (tx *DynamicFeeTransaction) DecodeRLP(s *rlp.Stream) error { return err } var b []byte - if b, err = s.Bytes(); err != nil { + if b, err = s.Uint256Bytes(); err != nil { return err } - if len(b) > 32 { - return fmt.Errorf("wrong size for ChainID: %d", len(b)) - } tx.ChainID = new(uint256.Int).SetBytes(b) if tx.Nonce, err = s.Uint(); err != nil { return err } - if b, err = s.Bytes(); err != nil { + if b, err = s.Uint256Bytes(); err != nil { return err } - if len(b) > 32 { - return fmt.Errorf("wrong size for MaxPriorityFeePerGas: %d", len(b)) - } tx.Tip = new(uint256.Int).SetBytes(b) - if b, err = s.Bytes(); err != nil { + if b, err = s.Uint256Bytes(); err != nil { return err } - if len(b) > 32 { - return fmt.Errorf("wrong size for MaxFeePerGas: %d", len(b)) - } tx.FeeCap = new(uint256.Int).SetBytes(b) if tx.Gas, err = s.Uint(); err != nil { return err @@ -415,12 +406,9 @@ func (tx *DynamicFeeTransaction) DecodeRLP(s *rlp.Stream) error { tx.To = &common.Address{} copy((*tx.To)[:], b) } - if b, err = s.Bytes(); err != nil { + if b, err = s.Uint256Bytes(); err != nil { return err } - if len(b) > 32 { - return fmt.Errorf("wrong size for Value: %d", len(b)) - } tx.Value = new(uint256.Int).SetBytes(b) if tx.Data, err = s.Bytes(); err != nil { return err @@ -431,26 +419,17 @@ func (tx *DynamicFeeTransaction) DecodeRLP(s *rlp.Stream) error { return err } // decode V - if b, err = s.Bytes(); err != nil { + if b, err = s.Uint256Bytes(); err != nil { return err } - if len(b) > 32 { - return fmt.Errorf("wrong size for V: %d", len(b)) - } tx.V.SetBytes(b) - if b, err = s.Bytes(); err != nil { + if b, err = s.Uint256Bytes(); err != nil { return err } - if len(b) > 32 { - return fmt.Errorf("wrong size for R: %d", len(b)) - } tx.R.SetBytes(b) - if b, err = s.Bytes(); err != nil { + if b, err = s.Uint256Bytes(); err != nil { return err } - if len(b) > 32 { - return fmt.Errorf("wrong size for S: %d", len(b)) - } tx.S.SetBytes(b) return s.ListEnd() diff --git a/core/types/legacy_tx.go b/core/types/legacy_tx.go index 36f8566d815..24a4db88b6b 100644 --- a/core/types/legacy_tx.go +++ b/core/types/legacy_tx.go @@ -369,12 +369,9 @@ func (tx *LegacyTx) DecodeRLP(s *rlp.Stream, encodingSize uint64) error { return fmt.Errorf("read Nonce: %w", err) } var b []byte - if b, err = s.Bytes(); err != nil { + if b, err = s.Uint256Bytes(); err != nil { return fmt.Errorf("read GasPrice: %w", err) } - if len(b) > 32 { - return fmt.Errorf("wrong size for GasPrice: %d", len(b)) - } tx.GasPrice = new(uint256.Int).SetBytes(b) if tx.Gas, err = s.Uint(); err != nil { return fmt.Errorf("read Gas: %w", err) @@ -389,36 +386,24 @@ func (tx *LegacyTx) DecodeRLP(s *rlp.Stream, encodingSize uint64) error { tx.To = &common.Address{} copy((*tx.To)[:], b) } - if b, err = s.Bytes(); err != nil { + if b, err = s.Uint256Bytes(); err != nil { return fmt.Errorf("read Value: %w", err) } - if len(b) > 32 { - return fmt.Errorf("wrong size for Value: %d", len(b)) - } tx.Value = new(uint256.Int).SetBytes(b) if tx.Data, err = s.Bytes(); err != nil { return fmt.Errorf("read Data: %w", err) } - if b, err = s.Bytes(); err != nil { + if b, err = s.Uint256Bytes(); err != nil { return fmt.Errorf("read V: %w", err) } - if len(b) > 32 { - return fmt.Errorf("wrong size for V: %d", len(b)) - } tx.V.SetBytes(b) - if b, err = s.Bytes(); err != nil { + if b, err = s.Uint256Bytes(); err != nil { return fmt.Errorf("read R: %w", err) } - if len(b) > 32 { - return fmt.Errorf("wrong size for R: %d", len(b)) - } tx.R.SetBytes(b) - if b, err = s.Bytes(); err != nil { + if b, err = s.Uint256Bytes(); err != nil { return fmt.Errorf("read S: %w", err) } - if len(b) > 32 { - return fmt.Errorf("wrong size for S: %d", len(b)) - } tx.S.SetBytes(b) if err = s.ListEnd(); err != nil { return fmt.Errorf("close tx struct: %w", err) diff --git a/eth/protocols/eth/protocol.go b/eth/protocols/eth/protocol.go index 5392f2cac4e..78c39ba08ab 100644 --- a/eth/protocols/eth/protocol.go +++ b/eth/protocols/eth/protocol.go @@ -402,12 +402,9 @@ func (nbp *NewBlockPacket) DecodeRLP(s *rlp.Stream) error { } // decode TD var b []byte - if b, err = s.Bytes(); err != nil { + if b, err = s.Uint256Bytes(); err != nil { return fmt.Errorf("read TD: %w", err) } - if len(b) > 32 { - return fmt.Errorf("wrong size for TD: %d", len(b)) - } nbp.TD = new(big.Int).SetBytes(b) if err = s.ListEnd(); err != nil { return err diff --git a/rlp/decode.go b/rlp/decode.go index fefca41ff3c..1568bb60e1d 100644 --- a/rlp/decode.go +++ b/rlp/decode.go @@ -242,19 +242,17 @@ func decodeBigIntNoPtr(s *Stream, val reflect.Value) error { } func decodeBigInt(s *Stream, val reflect.Value) error { - b, err := s.Bytes() + b, err := s.bigIntBytes() if err != nil { return wrapStreamError(err, val.Type()) } + + // Set the integer bytes. i := val.Interface().(*big.Int) if i == nil { i = new(big.Int) val.Set(reflect.ValueOf(i)) } - // Reject leading zero bytes - if len(b) > 0 && b[0] == 0 { - return wrapStreamError(ErrCanonInt, val.Type()) - } i.SetBytes(b) return nil } @@ -264,22 +262,17 @@ func decodeUint256NoPtr(s *Stream, val reflect.Value) error { } func decodeUint256(s *Stream, val reflect.Value) error { - b, err := s.Bytes() + b, err := s.Uint256Bytes() if err != nil { return wrapStreamError(err, val.Type()) } - if len(b) > 32 { - return wrapStreamError(errUintOverflow, val.Type()) - } + + // Set the integer bytes. i := val.Interface().(*uint256.Int) if i == nil { i = new(uint256.Int) val.Set(reflect.ValueOf(i)) } - // Reject leading zero bytes - if len(b) > 0 && b[0] == 0 { - return wrapStreamError(ErrCanonInt, val.Type()) - } i.SetBytes(b) return nil } @@ -599,7 +592,7 @@ type Stream struct { limited bool // auxiliary buffer for integer decoding - uintbuf []byte + uintbuf [32]byte kind Kind // kind of value ahead size uint64 // size of value ahead @@ -734,6 +727,59 @@ func (s *Stream) uint(maxbits int) (uint64, error) { } } +func (s *Stream) Uint256Bytes() ([]byte, error) { + b, err := s.bigIntBytes() + if err != nil { + return nil, err + } + if len(b) > 32 { + return nil, errUintOverflow + } + return b, nil +} + +func (s *Stream) bigIntBytes() ([]byte, error) { + var buffer []byte + kind, size, err := s.Kind() + switch { + case err != nil: + return nil, err + case kind == List: + return nil, ErrExpectedString + case kind == Byte: + buffer = s.uintbuf[:1] + buffer[0] = s.byteval + s.kind = -1 // re-arm Kind + case size == 0: + // Avoid zero-length read. + s.kind = -1 + case size <= uint64(len(s.uintbuf)): + // For integers smaller than s.uintbuf, allocating a buffer + // can be avoided. + buffer = s.uintbuf[:size] + if err := s.readFull(buffer); err != nil { + return nil, err + } + // Reject inputs where single byte encoding should have been used. + if size == 1 && buffer[0] < 128 { + return nil, ErrCanonSize + } + default: + // For large integers, a temporary buffer is needed. + buffer = make([]byte, size) + if err := s.readFull(buffer); err != nil { + return nil, err + } + } + + // Reject leading zero bytes. + if len(buffer) > 0 && buffer[0] == 0 { + return nil, ErrCanonInt + } + + return buffer, nil +} + // Bool reads an RLP string of up to 1 byte and returns its contents // as a boolean. If the input does not contain an RLP string, the // returned error will be ErrExpectedString. @@ -856,9 +902,7 @@ func (s *Stream) Reset(r io.Reader, inputLimit uint64) { s.size = 0 s.kind = -1 s.kinderr = nil - if s.uintbuf == nil { - s.uintbuf = make([]byte, 8) - } + s.uintbuf = [32]byte{} s.byteval = 0 } @@ -977,20 +1021,20 @@ func (s *Stream) readUint(size byte) (uint64, error) { b, err := s.readByte() return uint64(b), err default: - start := int(8 - size) - for i := 0; i < start; i++ { - s.uintbuf[i] = 0 + buffer := s.uintbuf[:8] + for i := range buffer { + buffer[i] = 0 } - if err := s.readFull(s.uintbuf[start:]); err != nil { + start := int(8 - size) + if err := s.readFull(buffer[start:]); err != nil { return 0, err } - if s.uintbuf[start] == 0 { - // Note: readUint is also used to decode integer - // values. The error needs to be adjusted to become - // ErrCanonInt in this case. + if buffer[start] == 0 { + // Note: readUint is also used to decode integer values. + // The error needs to be adjusted to become ErrCanonInt in this case. return 0, ErrCanonSize } - return binary.BigEndian.Uint64(s.uintbuf), nil + return binary.BigEndian.Uint64(buffer), nil } } diff --git a/rlp/decode_test.go b/rlp/decode_test.go index 4e308324426..c91e4865d5d 100644 --- a/rlp/decode_test.go +++ b/rlp/decode_test.go @@ -327,6 +327,11 @@ type recstruct struct { Child *recstruct `rlp:"nil"` } +type bigIntStruct struct { + I *big.Int + B string +} + type invalidNilTag struct { X []byte `rlp:"nil"` } @@ -374,7 +379,8 @@ var ( uint256.NewInt(0).Lsh(uint256.NewInt(0xFFFFFFFFFFFFFF), 16), uint256.NewInt(0xFFFF), ) - realBigInt = big.NewInt(0).SetBytes(unhex("010000000000000000000000000000000000000000000000000000000000000000")) + realBigInt = big.NewInt(0).SetBytes(unhex("010000000000000000000000000000000000000000000000000000000000000000")) + veryVeryBigInt = new(big.Int).Exp(veryBigInt.ToBig(), big.NewInt(8), nil) ) type hasIgnoredField struct { @@ -451,13 +457,16 @@ var decodeTests = []decodeTest{ {input: "C0", ptr: new(string), error: "rlp: expected input string or byte for string"}, // big ints + {input: "80", ptr: new(*big.Int), value: big.NewInt(0)}, {input: "01", ptr: new(*big.Int), value: big.NewInt(1)}, {input: "89FFFFFFFFFFFFFFFFFF", ptr: new(*big.Int), value: veryBigInt.ToBig()}, {input: "A1010000000000000000000000000000000000000000000000000000000000000000", ptr: new(*big.Int), value: realBigInt}, + {input: "B848FFFFFFFFFFFFFFFFF800000000000000001BFFFFFFFFFFFFFFFFC8000000000000000045FFFFFFFFFFFFFFFFC800000000000000001BFFFFFFFFFFFFFFFFF8000000000000000001", ptr: new(*big.Int), value: veryVeryBigInt}, {input: "10", ptr: new(big.Int), value: *big.NewInt(16)}, // non-pointer also works {input: "C0", ptr: new(*big.Int), error: "rlp: expected input string or byte for *big.Int"}, - {input: "820001", ptr: new(big.Int), error: "rlp: non-canonical integer (leading zero bytes) for *big.Int"}, - {input: "8105", ptr: new(big.Int), error: "rlp: non-canonical size information for *big.Int"}, + {input: "00", ptr: new(*big.Int), error: "rlp: non-canonical integer (leading zero bytes) for *big.Int"}, + {input: "820001", ptr: new(*big.Int), error: "rlp: non-canonical integer (leading zero bytes) for *big.Int"}, + {input: "8105", ptr: new(*big.Int), error: "rlp: non-canonical size information for *big.Int"}, // uint256 {input: "01", ptr: new(*uint256.Int), value: uint256.NewInt(1)}, @@ -479,6 +488,13 @@ var decodeTests = []decodeTest{ ptr: new(recstruct), value: recstruct{1, &recstruct{2, &recstruct{3, nil}}}, }, + { + // This checks that empty big.Int works correctly in struct context. It's easy to + // miss the update of s.kind for this case, so it needs its own test. + input: "C58083343434", + ptr: new(bigIntStruct), + value: bigIntStruct{new(big.Int), "444"}, + }, // struct errors { diff --git a/rlp/encode_test.go b/rlp/encode_test.go index f3bd5e02887..722d8b6d827 100644 --- a/rlp/encode_test.go +++ b/rlp/encode_test.go @@ -134,6 +134,14 @@ var encTests = []encTest{ val: big.NewInt(0).SetBytes(unhex("010000000000000000000000000000000000000000000000000000000000000000")), output: "A1010000000000000000000000000000000000000000000000000000000000000000", }, + { + val: veryBigInt, + output: "89FFFFFFFFFFFFFFFFFF", + }, + { + val: veryVeryBigInt, + output: "B848FFFFFFFFFFFFFFFFF800000000000000001BFFFFFFFFFFFFFFFFC8000000000000000045FFFFFFFFFFFFFFFFC800000000000000001BFFFFFFFFFFFFFFFFF8000000000000000001", + }, // non-pointer big.Int {val: *big.NewInt(0), output: "80"}, diff --git a/tests/block_test.go b/tests/block_test.go index c04a4088a10..ecc5c653c31 100644 --- a/tests/block_test.go +++ b/tests/block_test.go @@ -32,33 +32,8 @@ func TestBlockchain(t *testing.T) { bt := new(testMatcher) // General state tests are 'exported' as blockchain tests, but we can run them natively. - // For speedier CI-runs, the line below can be uncommented, so those are skipped. - // For now, in hardfork-times (Berlin), we run the tests both as StateTests and - // as blockchain tests, since the latter also covers things like receipt root - //bt.skipLoad(`^GeneralStateTests/`) - - // Skip random failures due to selfish mining test - bt.skipLoad(`.*bcForgedTest/bcForkUncle\.json`) - - // Slow tests - bt.slow(`.*bcExploitTest/DelegateCallSpam.json`) - bt.slow(`.*bcExploitTest/ShanghaiLove.json`) - bt.slow(`.*bcExploitTest/SuicideIssue.json`) - bt.slow(`.*/bcForkStressTest/`) - bt.slow(`.*/bcGasPricerTest/RPC_API_Test.json`) - bt.slow(`.*/bcWalletTest/`) - - // Very slow test - bt.skipLoad(`.*/stTimeConsuming/.*`) - - // test takes a lot for time and goes easily OOM because of sha3 calculation on a huge range, - // using 4.6 TGas - bt.skipLoad(`.*randomStatetest94.json.*`) - - bt.fails(`(?m)^TestBlockchain/InvalidBlocks/bcInvalidHeaderTest/wrongReceiptTrie.json/wrongReceiptTrie_EIP150`, "No receipt validation before Byzantium") - bt.fails(`(?m)^TestBlockchain/InvalidBlocks/bcInvalidHeaderTest/wrongReceiptTrie.json/wrongReceiptTrie_EIP158`, "No receipt validation before Byzantium") - bt.fails(`(?m)^TestBlockchain/InvalidBlocks/bcInvalidHeaderTest/wrongReceiptTrie.json/wrongReceiptTrie_Frontier`, "No receipt validation before Byzantium") - bt.fails(`(?m)^TestBlockchain/InvalidBlocks/bcInvalidHeaderTest/wrongReceiptTrie.json/wrongReceiptTrie_Homestead`, "No receipt validation before Byzantium") + // For speedier CI-runs those are skipped. + bt.skipLoad(`^GeneralStateTests/`) bt.walk(t, blockTestDir, func(t *testing.T, name string, test *BlockTest) { // import pre accounts & construct test genesis block & state root @@ -66,8 +41,4 @@ func TestBlockchain(t *testing.T) { t.Error(err) } }) - - // There is also a LegacyTests folder, containing blockchain tests generated - // prior to Istanbul. However, they are all derived from GeneralStateTests, - // which run natively, so there's no reason to run them here. } diff --git a/tests/init_test.go b/tests/init_test.go index 547720a06fc..fdc478add74 100644 --- a/tests/init_test.go +++ b/tests/init_test.go @@ -37,8 +37,6 @@ var ( baseDir = filepath.Join(".", "testdata") blockTestDir = filepath.Join(baseDir, "BlockchainTests") stateTestDir = filepath.Join(baseDir, "GeneralStateTests") - legacyStateTestDir = filepath.Join(baseDir, "LegacyTests", "Constantinople", "GeneralStateTests") - vmTestDir = filepath.Join(baseDir, "LegacyTests", "Constantinople", "VMTests") transactionTestDir = filepath.Join(baseDir, "TransactionTests") rlpTestDir = filepath.Join(baseDir, "RLPTests") difficultyTestDir = filepath.Join(baseDir, "BasicTests") diff --git a/tests/state_test.go b/tests/state_test.go index 78aec0e3a68..73a64eb05bd 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -38,21 +38,10 @@ func TestState(t *testing.T) { t.Parallel() st := new(testMatcher) - // Long tests: - st.slow(`^stAttackTest/ContractCreationSpam`) - st.slow(`^stBadOpcode/badOpcodes`) - st.slow(`^stPreCompiledContracts/modexp`) - st.slow(`^stQuadraticComplexityTest/`) - st.slow(`^stStaticCall/static_Call50000`) - st.slow(`^stStaticCall/static_Return50000`) - st.slow(`^stSystemOperationsTest/CallRecursiveBomb`) - st.slow(`^stTransactionTest/Opcodes_TransactionInit`) // Very time consuming st.skipLoad(`^stTimeConsuming/`) - - // Uses 1GB RAM per tested fork - st.skipLoad(`^stStaticCall/static_Call1MB`) + st.skipLoad(`.*vmPerformance/loop.*`) // Broken tests: st.skipLoad(`^stCreate2/create2collisionStorage.json`) @@ -60,44 +49,33 @@ func TestState(t *testing.T) { st.skipLoad(`^stSStoreTest/InitCollision.json`) st.skipLoad(`^stEIP1559/typeTwoBerlin.json`) - // Expected failures: - //st.fails(`^stRevertTest/RevertPrecompiledTouch(_storage)?\.json/Byzantium/0`, "bug in test") - //st.fails(`^stRevertTest/RevertPrecompiledTouch(_storage)?\.json/Byzantium/3`, "bug in test") - //st.fails(`^stRevertTest/RevertPrecompiledTouch(_storage)?\.json/Constantinople/0`, "bug in test") - //st.fails(`^stRevertTest/RevertPrecompiledTouch(_storage)?\.json/Constantinople/3`, "bug in test") - //st.fails(`^stRevertTest/RevertPrecompiledTouch(_storage)?\.json/ConstantinopleFix/0`, "bug in test") - //st.fails(`^stRevertTest/RevertPrecompiledTouch(_storage)?\.json/ConstantinopleFix/3`, "bug in test") + // https://github.com/ethereum/tests/issues/1001 + st.skipLoad(`^stTransactionTest/ValueOverflow.json`) - // For Istanbul, older tests were moved into LegacyTests - for _, dir := range []string{ - stateTestDir, - legacyStateTestDir, - } { - st.walk(t, dir, func(t *testing.T, name string, test *StateTest) { - db := memdb.NewTestDB(t) - for _, subtest := range test.Subtests() { - subtest := subtest - key := fmt.Sprintf("%s/%d", subtest.Fork, subtest.Index) - t.Run(key, func(t *testing.T) { - withTrace(t, test.gasLimit(subtest), func(vmconfig vm.Config) error { - config, ok := Forks[subtest.Fork] - if !ok { - return UnsupportedForkError{subtest.Fork} - } - rules := config.Rules(1) - tx, err := db.BeginRw(context.Background()) - if err != nil { - t.Fatal(err) - } - defer tx.Rollback() - _, err = test.Run(rules, tx, subtest, vmconfig) - tx.Rollback() - return st.checkFailure(t, err) - }) + st.walk(t, stateTestDir, func(t *testing.T, name string, test *StateTest) { + db := memdb.NewTestDB(t) + for _, subtest := range test.Subtests() { + subtest := subtest + key := fmt.Sprintf("%s/%d", subtest.Fork, subtest.Index) + t.Run(key, func(t *testing.T) { + withTrace(t, test.gasLimit(subtest), func(vmconfig vm.Config) error { + config, ok := Forks[subtest.Fork] + if !ok { + return UnsupportedForkError{subtest.Fork} + } + rules := config.Rules(1) + tx, err := db.BeginRw(context.Background()) + if err != nil { + t.Fatal(err) + } + defer tx.Rollback() + _, err = test.Run(rules, tx, subtest, vmconfig) + tx.Rollback() + return st.checkFailure(t, err) }) - } - }) - } + }) + } + }) } // Transactions with gasLimit above this value will not get a VM trace on failure. diff --git a/tests/state_test_util.go b/tests/state_test_util.go index cc1cbca8897..f95dd48f58a 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -230,13 +230,6 @@ func (t *StateTest) RunNoVerify(rules params.Rules, tx kv.RwTx, subtest StateSub statedb.RevertToSnapshot(snapshot) } - // And _now_ get the state root - // Add 0-value mining reward. This only makes a difference in the cases - // where - // - the coinbase suicided, or - // - there are only 'bad' transactions, which aren't executed. In those cases, - // the coinbase gets no txfee, so isn't created, and thus needs to be touched - statedb.AddBalance(block.Coinbase(), new(uint256.Int)) if err = statedb.FinalizeTx(evm.ChainRules, w); err != nil { return nil, common.Hash{}, err } diff --git a/tests/testdata b/tests/testdata index 52cb3b3e724..fbff6fee061 160000 --- a/tests/testdata +++ b/tests/testdata @@ -1 +1 @@ -Subproject commit 52cb3b3e724d13943bd8a457ed70929f98b9b8bf +Subproject commit fbff6fee061ade2358280a8d6f98f67b4ae2b60e diff --git a/tests/transaction_test.go b/tests/transaction_test.go index f4a2d295008..2d528b720e4 100644 --- a/tests/transaction_test.go +++ b/tests/transaction_test.go @@ -26,25 +26,16 @@ func TestTransaction(t *testing.T) { t.Parallel() txt := new(testMatcher) - // These can't be parsed, invalid hex in RLP - txt.skipLoad("^ttWrongRLP/.*") + // We don't allow more than uint64 in gas amount // This is a pseudo-consensus vulnerability, but not in practice // because of the gas limit txt.skipLoad("^ttGasLimit/TransactionWithGasLimitxPriceOverflow.json") - // We _do_ allow more than uint64 in gas price, as opposed to the tests - // This is also not a concern, as long as tx.Cost() uses big.Int for - // calculating the final cozt - txt.skipLoad(".*TransactionWithGasPriceOverflow.*") // The nonce is too large for uint64. Not a concern, it means geth won't // accept transactions at a certain point in the distant future txt.skipLoad("^ttNonce/TransactionWithHighNonce256.json") - // The value is larger than uint64, which according to the test is invalid. - // Geth accepts it, which is not a consensus issue since we use big.Int's - // internally to calculate the cost - txt.skipLoad("^ttValue/TransactionWithHighValueOverflow.json") txt.walk(t, transactionTestDir, func(t *testing.T, name string, test *TransactionTest) { cfg := params.MainnetChainConfig if err := txt.checkFailure(t, test.Run(cfg)); err != nil { diff --git a/tests/transaction_test_util.go b/tests/transaction_test_util.go index 9c70b008cd6..60e79cc5a0c 100644 --- a/tests/transaction_test_util.go +++ b/tests/transaction_test_util.go @@ -30,19 +30,27 @@ import ( // TransactionTest checks RLP decoding and sender derivation of transactions. type TransactionTest struct { - RLP hexutil.Bytes `json:"rlp"` - Byzantium ttFork - Constantinople ttFork - Istanbul ttFork - EIP150 ttFork - EIP158 ttFork - Frontier ttFork - Homestead ttFork + RLP hexutil.Bytes `json:"txbytes"` + Forks ttForks `json:"result"` +} + +type ttForks struct { + Berlin ttFork + Byzantium ttFork + Constantinople ttFork + ConstantinopleFix ttFork + EIP150 ttFork + EIP158 ttFork + Frontier ttFork + Homestead ttFork + Istanbul ttFork + London ttFork } type ttFork struct { - Sender common.UnprefixedAddress `json:"sender"` - Hash common.UnprefixedHash `json:"hash"` + Exception string `json:"exception"` + Sender common.Address `json:"sender"` + Hash common.Hash `json:"hash"` } func (tt *TransactionTest) Run(config *params.ChainConfig) error { @@ -74,19 +82,22 @@ func (tt *TransactionTest) Run(config *params.ChainConfig) error { isHomestead bool isIstanbul bool }{ - {"Frontier", types.MakeFrontierSigner(), tt.Frontier, false, false}, - {"Homestead", types.LatestSignerForChainID(nil), tt.Homestead, true, false}, - {"EIP150", types.LatestSignerForChainID(nil), tt.EIP150, true, false}, - {"EIP158", types.LatestSignerForChainID(config.ChainID), tt.EIP158, true, false}, - {"Byzantium", types.LatestSignerForChainID(config.ChainID), tt.Byzantium, true, false}, - {"Constantinople", types.LatestSignerForChainID(config.ChainID), tt.Constantinople, true, false}, - {"Istanbul", types.LatestSignerForChainID(config.ChainID), tt.Istanbul, true, true}, + {"Frontier", types.MakeFrontierSigner(), tt.Forks.Frontier, false, false}, + {"Homestead", types.LatestSignerForChainID(nil), tt.Forks.Homestead, true, false}, + {"EIP150", types.LatestSignerForChainID(nil), tt.Forks.EIP150, true, false}, + {"EIP158", types.LatestSignerForChainID(config.ChainID), tt.Forks.EIP158, true, false}, + {"Byzantium", types.LatestSignerForChainID(config.ChainID), tt.Forks.Byzantium, true, false}, + {"Constantinople", types.LatestSignerForChainID(config.ChainID), tt.Forks.Constantinople, true, false}, + {"ConstantinopleFix", types.LatestSignerForChainID(config.ChainID), tt.Forks.ConstantinopleFix, true, false}, + {"Istanbul", types.LatestSignerForChainID(config.ChainID), tt.Forks.Istanbul, true, true}, + {"Berlin", types.LatestSignerForChainID(config.ChainID), tt.Forks.Berlin, true, true}, + {"London", types.LatestSignerForChainID(config.ChainID), tt.Forks.London, true, true}, } { sender, txhash, err := validateTx(tt.RLP, *testcase.signer, testcase.isHomestead, testcase.isIstanbul) - if testcase.fork.Sender == (common.UnprefixedAddress{}) { + if testcase.fork.Exception != "" { if err == nil { - return fmt.Errorf("expected error, got none (address %v)[%v]", sender.String(), testcase.name) + return fmt.Errorf("expected error %v, got none [%v]", testcase.fork.Exception, testcase.name) } continue } diff --git a/tests/vm_test.go b/tests/vm_test.go deleted file mode 100644 index 688c081b34b..00000000000 --- a/tests/vm_test.go +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package tests - -import ( - "context" - "testing" - - "github.com/ledgerwatch/erigon-lib/kv/memdb" - "github.com/ledgerwatch/erigon/core/vm" - "github.com/ledgerwatch/log/v3" -) - -func TestVM(t *testing.T) { - log.Root().SetHandler(log.LvlFilterHandler(log.LvlInfo, log.StderrHandler)) - t.Parallel() - vmt := new(testMatcher) - vmt.slow("^vmPerformance") - vmt.fails("^vmSystemOperationsTest.json/createNameRegistrator$", "fails without parallel execution") - - db := memdb.NewTestDB(t) - - vmt.walk(t, vmTestDir, func(t *testing.T, name string, test *VMTest) { - withTrace(t, test.json.Exec.GasLimit, func(vmconfig vm.Config) error { - tx, err := db.BeginRw(context.Background()) - if err != nil { - t.Fatal(err) - } - defer tx.Rollback() - return vmt.checkFailure(t, test.Run(tx, vmconfig, 0)) - }) - }) -} From 5210767ca4ab44d0a64739fd292bbd0e58c18a1a Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Mon, 6 Dec 2021 16:45:45 +0000 Subject: [PATCH 057/261] trace_ include subtraces to precompiles with value > 0 (#3096) (#3098) Co-authored-by: Alexey Sharp Co-authored-by: Alexey Sharp --- cmd/rpcdaemon/commands/trace_adhoc.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/rpcdaemon/commands/trace_adhoc.go b/cmd/rpcdaemon/commands/trace_adhoc.go index 8207edafa43..63843b62551 100644 --- a/cmd/rpcdaemon/commands/trace_adhoc.go +++ b/cmd/rpcdaemon/commands/trace_adhoc.go @@ -241,6 +241,7 @@ type OeTracer struct { } func (ot *OeTracer) CaptureStart(depth int, from common.Address, to common.Address, precompile bool, create bool, calltype vm.CallType, input []byte, gas uint64, value *big.Int, code []byte) error { + //fmt.Printf("CaptureStart depth %d, from %x, to %x, create %t, input %x, gas %d, value %d, precompile %t\n", depth, from, to, create, input, gas, value, precompile) if ot.r.VmTrace != nil { var vmTrace *VmTrace if depth > 0 { @@ -270,14 +271,13 @@ func (ot *OeTracer) CaptureStart(depth int, from common.Address, to common.Addre vmTrace.Code = code } } - if precompile && depth > 0 { + if precompile && depth > 0 && value.Sign() <= 0 { ot.precompile = true return nil } if gas > 500000000 { gas = 500000001 - (0x8000000000000000 - gas) } - //fmt.Printf("CaptureStart depth %d, from %x, to %x, create %t, input %x, gas %d, value %d\n", depth, from, to, create, input, gas, value) trace := &ParityTrace{} if create { trResult := &CreateTraceResult{} From 563df5f5aa5ac0337d6316d2afa2b1a072f1cdb5 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Mon, 6 Dec 2021 16:45:54 +0000 Subject: [PATCH 058/261] Update skip analysis and preverified hashes (#3097) (#3099) Co-authored-by: Alexey Sharp Co-authored-by: Alexey Sharp --- core/skip_analysis.go | 2 +- .../preverified_hashes_mainnet.go | 260 ++++++++++++++++- .../preverified_hashes_ropsten.go | 275 +++++++++++++++++- 3 files changed, 534 insertions(+), 3 deletions(-) diff --git a/core/skip_analysis.go b/core/skip_analysis.go index 57e1ffb5921..cc16d4bc08e 100644 --- a/core/skip_analysis.go +++ b/core/skip_analysis.go @@ -21,7 +21,7 @@ import ( ) // MainnetNotCheckedFrom is the first block number not yet checked for invalid jumps -const MainnetNotCheckedFrom uint64 = 13701900 +const MainnetNotCheckedFrom uint64 = 13751500 // SkipAnalysis function tells us whether we can skip performing jumpdest analysis // for the historical blocks (on mainnet now but perhaps on the testsnets diff --git a/turbo/stages/headerdownload/preverified_hashes_mainnet.go b/turbo/stages/headerdownload/preverified_hashes_mainnet.go index ada76c45fb5..0411b64d042 100644 --- a/turbo/stages/headerdownload/preverified_hashes_mainnet.go +++ b/turbo/stages/headerdownload/preverified_hashes_mainnet.go @@ -71366,6 +71366,264 @@ var mainnetPreverifiedHashes = []string{ "054ae50b17de1fa908f838a3b0e25e7e45a4e852a4e278b51b374997e2fb5e4d", "a2f394117fd99cb2a91dfe82811f4c32303caa38a5496078c1d3c5c06bdb05b0", "019e27d88a5466fbb927c9ec01fc012132c33b3a13a83081c144d02954460045", + "e8bcf46167bd9e4e917f7d97bd5229b86707e5a65e5a0984827dc9685fd6e4fa", + "b33c4956e06611a8d3c7982e27de014f155c8c162c4481997e682fcf40fb3cc5", + "3637dbc442cc21f7e2c1f8e12802d425c73877b708f8d28324c55b94c08d06c1", + "db6a5de6b7359eee39fd57f394116ff4839165e044098312d8d9f8887b932683", + "0e94d16c9de848dcbc89e0c2b7ef07609092fd8801d4803fd2fad3855c6c6bcc", + "953810a95dcb0459eb94ff6a145f61173cce02da196dabbf0aea002d2a09dff7", + "bf17cda9d3e3eb18244652110d01faf3ba053b042b5b841f1db38fb9ad31c92f", + "ecd956b537cfb6a34360e32670992d96f6ae7f9f13aceef92a7401269ef30d82", + "ea10b36c9bdb44445267c90a98d94aadf117696eaa22d722852619954db5c99a", + "55a57d52b1d2038bc49e50b9d46ba93917b8304fa5740834c18444b3b4d122ae", + "6b9248677f621042b479cc1e5b3526004c87fdcb9d277e7e0742ee49743f9fa4", + "e6874827faca6c48b71bf05cc0ddc2fcdef0fea334c268577350394ee9615198", + "c54a4109c726eef2aff022291a1364e48a45418c6a6d7325fc486cc04f83e7f7", + "1f49872b43e845f2d1f128e8b5f4d15d36a5d94056a7521b36dca52380e6b84e", + "2c1278918ac440a3a1c2e25b0db3979ad84cca79182b7e99161db64e549805e5", + "931508b1d9d9154f183521569aa01df83561801f50dc628135c5c1a63116e2f5", + "96e9c8bf724b24658cdf9b66a94b7050e6f4cf22b604f1febe0f95d91084285a", + "f12021a1bc3e9b206a686be6326f6de1c32c15478bac729d8b2614970c9fab89", + "ab78726f9e67448f78a10e99ce2f31de83418466435b56eccef2e88d937c4588", + "47aa7cfa147b2f4a3bd6af6c75a367109d606b8386cfa815849609c2ce18662d", + "b226ea9b216ea16cc925c36169589460a709b68c379bbab51ad622cc160f70e9", + "e6d48e599b35f4c7a0b85bf1ae8f5a4d646f7ab2a84ae5537cfdaf0a0838a94d", + "ea13405bd0f445e58e2607df6b4ec13d3bb723c7d104bc5c3d9bd243cc86b136", + "db984b010dfca3c581bab87254d6ec16f95ee17d96c9906e815b567791c7e85e", + "1db6204cbb4aa10d1257b3c44ca880b9584e4cead15eedbcd2437f02b67cb3c4", + "af250c477cce2c2cdd80fc6777effa46de689f093d5da852def33033d3dfd23b", + "67989ac0a445a38061b6994b0e3359bd1aaff59c0da2230ece4f0b1a155e71b8", + "51f23d653beab417cb08cb1090e49a4d2d85b5d016ac3dff7913702e688ecefb", + "81eab12731d4a73bab5db0f795b79ee07ca7b072696b9550e1c0aa631810dbe7", + "b519c4a6c018cea76dcd4408cbf2bed0be3536a05f5d9a579fbb703102796dc7", + "18a4d346a1a938e75b7f1883b9d0743238062f5c5ffdca154e71058bba646c31", + "b5757c5a8b4c2cce767cb03fc205657de7b597a909df3ff2ca6a5aa4236fa615", + "9ff96720691b2ad4e638c2a94f71ed14969eda832ff36a0c966b4f26ea7e0017", + "c2502f701dc2049f1a5ffab339e81020b98a87cffcd57f9e6cdfe5d05d5453d7", + "875200371b11dfc4ea4cd27346916dc62847a0f524532b4b7ade82e4ac151e36", + "45ba40407abc1a06a020a562012ab028f410f9b64b5046db13da61e30076ffd1", + "93b73fe0246abf884afc3861f7618809f637377c02f036f483c0cb522134d932", + "9a42d0610b59d0d519167eda51cf91186aa2272826a87b3f866c5cee7f665bc8", + "2f5a7dc042fafd4a7e146540aad9f5a14962c97c04a754e299056a4032053d72", + "628a6fd4c6e2ac0b557b2af3b8a6f415bf0288a6aeab59dcf666cc9d578914a9", + "f34f3ccc6d0292dfbdc8533dd239162effaff68c95eecfdfad9f6f36cf99a153", + "0163c224c801c5c73db540b24972290dc1d7d2776c9073f00b556205d8899417", + "0a547b39a10c771a25df7e01b1ef88e0325de10a05aa804b0bdddacc2f2ddaa0", + "da640a5bbd31d41f5e64cf75b294c60e78f9cf318f0f2846a5a48091782ce698", + "595b25c5d250ecd1c8a686150696b9a5d110437cfa3f11131c12ef775dd9101b", + "d6eed1d509148bf991ca7f2c02a20fa14307b6817090d685a1643a496323ac22", + "e179f30c4029a092d46cb678f168164fee92716e1a737a8f4b3cae04a034e13b", + "f5980608329f9efc001c3426c2b6bb9b5705a4d9b1dc15965007993959a8db1d", + "8f46ef0a63e8b633798add74c2ef29150b832b43e077956bfdf15b2991727b76", + "7ee87220e87c633cb4e39cef59a754df0175da68f15ddd16dffae68f5221e77d", + "e8f663c3a6111d0f2e09ad2022f94d3bde76a71a7f136868fcd62b6bc1c2556f", + "83847b27bd136c0530a7e4cc90f120d703e5bcde4ccb97bdf4e34d95f6176918", + "2d54dbc95bf14f8517b89fe6fa755d156184a9afaa2ea1c275244122000dd1db", + "f537e2f6d862d4bd05b64dcc3f7ae8cbb0eedcbd7d74390ecbb689ddb4c74645", + "2619131c7765ed3d8d51a2b14ffb746a87846089ecef74503264599edae191f1", + "4728fa7f5903b0f8f2bc837dafebab1ee7a417de8e8123d3b10acde34982ea74", + "a80a774979b70002fa64ce2395d8a6d3114be6518d1c7c8fe2b27b90a42d8cb9", + "b338f8f931738a50bff900d501a98a4f716e4b43ca9f4c2b0cf93f34509acd34", + "b15bf8bdf9a74914f1f4e5a92c92318be2f2b12c9bea3bf890cff656b3cde407", + "ca581767d035dc0b78a27bdcac7ffeff2297b9e3867923d24ebc8eff89ae94d8", + "bc24560a3150b519ceefe5942aae0342c8d74d8e27a922f46bba67754c2ac01c", + "da2596f361af1617db8ac3a679f90ecdf791d2b706e32db4b3b324f90aa425e5", + "fb3380c2bd914e2ef0efa093477a29808487d39aa152f83ffec9065f16f2765d", + "8bf62742da907c08a2011302c2357ae6267565243743f41dcd1f4f7f976554ff", + "c952f6e3c89537906f5d1fb4af88cd301657b4be7fd006ce1160b3d7afb6c51c", + "ae2afc16e6cd33f783c9388aafaf602f50025e7fcf7713134c839a72cfbc4ddb", + "707304cd4ff73329001ddc46e9faa74258ad1e4ddf48992cf4c14951f6d57a42", + "ca31581627cdb7c4f3f99b1c0033b62a5dc4a0ce8a08ca33f006bd0efc6b6519", + "66c0ab2f78110f37addbc5ae5fb03c810cebb3ec0ce8269c6197b7f704afe10b", + "ed5a35491cf75fb16a71f652954742e3e8506a7cd731263d89d6449635110e3f", + "437392fb01b8bef859c3c307e16c48078d52cbde4631e5dbd2c4defa09083a09", + "3145a08ea7d47a9ad7303c20143f265063407aa0537792ef5cbdf1eb0f123bb8", + "190b6b9020e980522d97834c3167b8298567b4af70465cab5dc2363b259629f4", + "58aa482b78d49f5f7fee5793093c6613dcafaa9fb3874ec0f5ec5a3d4db8517a", + "1be35f21ee181a7a39fbcf84804df29d88264e9f1bd9cb914a282dbe86e95e9c", + "274c2e65c416bd782a5e1b34f76b277e80cb39a8f30b9a2143e80b09c2bc9f6a", + "2970e16e4c3fd37ecbed003560a5bddbe11fdbea60bae6de95d1fb98d38e6dbd", + "fe146c92dc0de877082f2a8718ffafa70c04c1f69ebb52745f063f170e7d62be", + "5f07af82b2ab0c623ec5ddad1ee8af2a1550400ed9f3f4cddea3228fb0a50f23", + "df90672cf8eabc990df51ed77a77a93ecfd7cc68ef24c03297821a79d4ddcebf", + "58226e26babe808807a22694d6f351101f8fe97a1c0835f9f7fd23b586eeac4a", + "96f636fe1435d5dc61a7dbddb82453a837983262b951285dbca2b318b3659d83", + "14816915e20d7c0f9062dadf7c2bbe5f0fc3089faa41059169163be9804a5910", + "393b772c486cfd32ba5c510cb393827d1021d7115520d5d8343d2eb916227021", + "b2b12fd79cc2a92717af19982ce8a092da5c12171366c3cfaeb652d751591a3f", + "8d712e2e948fbbb7c94b58bf51554df4395f274036f8bb3fce82d8a2c7f6a5c6", + "1bac7d8f043a060501ba795438b76e9072fab8b476e68c58146b13429bc0aaa1", + "6b11744dbfd78b6e11b9ee782f8b55bc706ab1dc10e6dedeecf1318a4d53e9eb", + "8773765575b3d0681524faae0880a10953366db66140e942f8aed796763b43e9", + "4069f467f10db2d98c26e1fbfccdf1d36b8085c17d3ce6226df8d061d5f59b5c", + "417dae8d0a573fd38c6ad47d386d51eeb008a7ddf5e4a58417696ae67e739588", + "ab4ed28b7eb648825c1e305531d620db87de67620f14c0d7a318af0c081925d5", + "a3b75d72fe816704399d55b20880dfdca87a1b43ac440862082a09504fb74ba7", + "4e2cfa0a7f5014ba13f83210a22660bf49c0590f947cf35782ffa4e56a88bdba", + "7bc7f91f59311b852714cc817e3698387ffbcf9947a7b5a16c7e492a978fb963", + "44cfe68c1947d331653ad4817b04f0efd7f4bc3009e78f55c8af874746d41264", + "e5e12fd5b9998e1e219a815ea9e828eca984b7439030b11cd6256bedf5cf91dd", + "35ef7693634f1ae16cfecd37d2a7b8f442d0e8b70f76473a676d309160e033a1", + "df1e973563a790b7cdf17cc2cf5399911b6a39a3d77737456137491b396e75b7", + "26a328f3952377d21b0ab80891d9ecebcf846afa9c6c3a5a546cbe27d4a51af1", + "02583de1ecd1db319a86ceb61fcead6771770cad1240c6b149be5a054b075bf1", + "23231c0967b4a92686441d3174de16c59b5487ae7ae20e7f7c6f93f71d8382da", + "2ec80602cbc11fad92c2c171be5db6b1aa3ee3e8d40b5575f9a5252ebddf9946", + "ca0ebacc5c0abe13fd37d4bba40852055d42dfa6742509b1a398826c23839a97", + "3b3097a66aed04341168524583a2e2c09b21f6255af467e28e4299bea1041dfc", + "dd050dcebac3322a7e2bed05c7c1e9efb3f14175cb5fba953df20f19ebb43d1c", + "99e65687fd805eab5e340bed637056ce0bd42310d9b5406c6140f7b421b5bb59", + "5ffc89b71efbfa5134b5c5349192b7500b9c98122fe81fb2ec1a5ee1efa32f8f", + "94c0b029d05c17ea49cbb0c28a40c3e39b643fb3131b2e3c830f5fcd30595630", + "8ea1c7fa9a3b7a47af69fc6b8cf9a6152b3240d80e92b2a3c8c995fdcff6f9dc", + "4bcfe5e905f7f48ab927ceaeef96f80d9065a466fbf27a7c1f6d8e02e822cd22", + "6c354daac8e3828ba1346aa5aa67aaaf5fb55b47030623a4cccb266aee4507a6", + "873a2c297d95c4e27353bc52b4944893ffefb8b998a5ab3f8f466cea04015f1c", + "8ee47f851bd79ef569b6524fea55706e9ebfb90a1081a1d28eec643485d36faf", + "c04b17b8f4bd98d5095c9a4084851286256b91a79009d90d677f2aaf62995926", + "a59aecec951481df1c87bf3823da0571f768f5b916b5e58a580f585d585ec71d", + "d4477bf4e17d000a26a372f4f71a106f02b47c1b039335e9a37739ebfca18e74", + "170aa8205cdf5502afbcf2ffbb2af510a1ddfc251ca1233faf30fd9a7d0a9a9d", + "c68a320410cf65325ddd74b6a83c8688d1ea4e4ced2973a4cf64274c254a5ebf", + "2d0865542dab66d89838582b7735e79a6648b1346624bdf68d9fd37f664cf7d7", + "fd93adc207ba918f1ef5c8a6d4d18857d7d5ac3f9e27272e1ddc0a942a1e4ebf", + "eedf35e06aedfdaaf2c7d3f299886927bf5a5db18992b1d4d948834eb3217a43", + "a39d7086318c5d8ece82ef0a8c3c47cbe6ee788885ce1bb09211fb100e7da7db", + "150e3b4bcd902d0c972c9de0643ec4e775c8da03860714b2cd7fb15cb14f3edb", + "dc5c0cb7c2036a8d22687de80441e96b9d55ce19a2737da20418b66b4dc79c0d", + "68854145583d3103ce62cfd02b3690b61e32f7c9113f2530fa214ca6eb0bc8b8", + "3dc218f08921dafe7e427148a378df73f0e074d6a04a316e8b2a56c739f0171a", + "837ca16d9b3f2338a5521208a814e40b84f0b25316de0beef536145bfccceaf3", + "547a8b0640f89d92401660aa2bf1dda3ddc970f323c9d26302b32c44cbb96360", + "ca4930728f6ce1fe616689f3a9efaaedde8f6a4eb8c3eae727f68a4cbdac03e4", + "ed7ddcaad20a1f7e43c357f8948426383415f29f2b481a4c5ad333a3fbbf965d", + "6fc618f58dc4a0712043edea0c387358f28fb15fe75b528981aef1928cb7b36d", + "fd032a6d38cca6cc3f6844a78683be0d41ed68662c197cab022ab52bfdcfab7f", + "a40c1d104cb1b3f10f0edfcf70fc4c97c774c06536aa80fe04b05652f3271e30", + "c0a2adfa9b00d063b13c8682bc0ed14d1c62502291fe2d71c1767419c4743205", + "c19560c8bb95350a6684d7f9cdf2d467603f50202419b94f5aee3d3a9b21f90f", + "805c03e44581aaee193abc370d325cd9832feaf76446b788ebdf055acc3e198f", + "9e547e41af010f47a96c5cfea7dedbad586094ab8d45a02ccc43c3668940d2fe", + "0058f1b1c1b523d907afe5c74435d00efb0cf9e7d6d93f8fea79eb9281368a20", + "9893e60b15a3bdbd73c292c4642da119265fee1d4198e9916755e429d0e1c6ff", + "0b06aa1addd10fc064c577275f2856a88ce31c4d6c51faa39b4004aa30f24789", + "5d782f4210239ac9b4f854d3e6936d74a2da7304b97543a786662a0d25d10fa0", + "9bba847f9846f398721093b0f24281592b63c05760b3baed8f32a4a19fe985bd", + "07716b9ba726bdfaa649709ccfee1ec8f2f1e8f60cc619b2efef19a383674c75", + "6b96f8239c4f88b0d6e79d707cbc3b3116c52b33638848c26f1160f2c287d867", + "817773055dd855bfd579769d9cf73615206e6d3e90729e8202b6dcb0656f8426", + "9fd2e0688952aac0379b93650996d26ca0c05fc6281e8fd6c6db422517e563a8", + "0b4e5e251168eab0b97e9082e343dee8db37a4f62669917ad7f369418d7fcccb", + "5e2648a489b795efcec0a197acd214e10ceb0d47965a4a9c81e025451cb2905d", + "336836443e58b84aff8b223b9d1dc3b6a882510cc79f6f45e07db1c0a04582ff", + "cca9ae4bd629f09356054642635489f0119a50a44d563b63c2124dfdaa6bef73", + "103e4a3a78102c1ee3f51bff5d084640e178094f1f90416bfd1eae2fea9a275b", + "9f6f01a427fa08034f2164737d4964bacf9bf73aa924441172cb33fdeca6aa9a", + "3285d621b0c8c9ae43e8e9526d63cabd6f7162175e1a2f6f42246f62fdec490b", + "7a784981cc1e0d93c763a34ebf20f3e182539302dedd16167ff161fcf4b06260", + "123bd3c1df5c75c0414696a9a04103dbf3398b1351dc808ba08ccf80d0e1c5f6", + "4a1087784ceeb616bd29445abfd3b40fe4db58de63d66c9eb038bb4ac518c6b4", + "d538eb6f4807a110bd00f53df7d56363ec06122d997428f012af4b192e730f56", + "b09fac3292b4c983fa4b047d4630363d735b8160b8d90aef113b322710f85748", + "bd7f7cc8e47072cebf7b07cd78ecf095c0990115e9e5823a529c3630bfb4128f", + "c0cd16884df17db0bae150ec95e7651d35a0aea40abd08b6f3759cc82a3853ff", + "b5e6be6e603c2b7342241ef33b1d08eeb8dd961c8d145f45d7f48ad16cb78f8a", + "9fade82e72a773fd5b96ca60504e7bfb158b6914f9a93739fcbf5aa6891c7522", + "df95d466ac5ab408ee95375ecfaa4650fc6aedb0ed5691b0c1416e6b493f9cb0", + "cd99823c3bf1cc1ff518f61de52c595345930ff76ad1aa52ee255d60b873348c", + "080c794074a5d8fe33099534fd029974b4c63378db05b78bbcd9d0942df885ea", + "54a8468c5e76825c21392ecec3517c46fcc96f3a68d9cc378a9194ec2d4e484c", + "d111107dc9586ae2921aab02a079d1342712f8c72b76b6cd10212a9c7732f4b1", + "aab5b6a9526de6956b7e4fb9e09cf9631bc3aa3a727069a380a67b20ce139ae6", + "97a45ff41b713c78201c49a290e5b0e32260e1c73bacb50d809fe0bac18c4329", + "50d3f1185c9ea62d7fe08a44ed15a08eb1c0e414e133a64064703d61ad548e32", + "bcd83a91fc5b561d03c539b444570d06c43a6ceb6c953d69824b6c4032f3d45e", + "56fb4376676ff0eea017d8abc305f6b21ed4c39071bfc4c592ee3fd43e6848f7", + "14101d1f53fc8c6d3fd67a35d45d345a3f0646879ece43f1cad033e52d647687", + "4475392fdadfd6ff0562920b82b780609379d22a5a440e1947f89ce18e1da3bc", + "5fd03dd49c68e5aba9381acf8b5dce3779dd9ab14bee55a1a0d68c7634c478f3", + "9d3295941388c1a071ae903d8bc1b44c6fa9c20d40319024bad7c076f6067829", + "bcc3c1b661e8e0dc8cae5dfb89e9128285f2ee3a012dbf952b78f09d22ebcbfa", + "3a3c6fcd5a7e86c779e2267f50330fa68010b9d722c75567e0458a829f35e59d", + "1b5a8f623813233e80186970cf3cb9a18bb0cf41c0ef0814440cd813c5ef2cf0", + "de0853ce3300400ace542a0ba5373076db65665ff070a5c3035f2f32b4fe0481", + "c0af0849a17cdc2c27a711ec756dfcc57baa903715857d55da2e56e12896de94", + "7d94ba2c71dc10b6eff848e6923cdba601b8180752c0efd1a3b5f5ffa50830c8", + "6c91c0705eb4556d02352462d5b07a180ffe63a1ceaa8aabd29ec05b99f30ce6", + "cb303950e82899f93351efb07092bdb0de4ba35d8cadd355e4654b31ab0c0408", + "a8d86a8d39625ae38b159a21f2cf271929e8152cd3b7575521e128f1eec1db21", + "2970ac669c8ab3cb51b1d4ff62573cb0c7f155bd53a855e01b03ebe8f17d1b14", + "82e9c3e28af48ee62d48beca86b75849ccbca5e18aa6ea6849a92bc989f47758", + "3f1a59dda1934c0463963fbd3b747c7224f339c20b55b1039a0fc3cb41cc4054", + "1164ccc52dbecf4cf8280ef22542273cbd43abdf649e3a83d809700880e4dfd3", + "4044d02c8702d1712a029c30a63696b651225bec0ddfcf178adfa15a60c809f9", + "b50b44fca135bfe0e5044696b0e95405f425536264e6b94172fd525a5196b7c1", + "1da0ee84ed27fb9014bc34ab31e870df56b3eed4a998c43ff78b001efd1756f5", + "f120e341858054f1741d933c69ec50220b9513456a03cc3d049c268d0735febb", + "19461cc973b258262c974429f4800f76c79b61ee65d8f4d674edb79367739735", + "063a418570e65540ff5b7427a908b0e36baf6480b9aaf6c5ba209b8c7c38df0d", + "51d9a1616a328888b7aaffa4270bdd1ada6057c1cf2d766fb009bb8772b878b3", + "c0d3db587efc3d1f7145fd442064317e8351291e374f9331ddf802166d500822", + "518e71071ffcbc95dd3ac157c4d09d7d17276caf1f2e5b009120ae08e40d65e2", + "5c5ad88ded285bf1a17476515e637b1785713f4b757ff2a7a4d64361c00ce61d", + "4440a5693bc17ac7f04693db36e2f866559e8baad05b35b20b8a07efcc23d4f9", + "89be54b0fdea5ca0e7508e58f1ee168496fbb5550eb08426fda3ec69c3c4621a", + "e2d43660f24700c439911fee41c1c97ba5976c98a5b60144bf243a0d11fd15c3", + "83494f0e5e804214f314c49ef5312286ce57b80c2be9c75795a03f45333209f3", + "81af980cd090aecb0435cf5012c43f287da5d074fb41fa42dc5f3354a660c71c", + "4e50d71f96739e243874b7f7ef9c70098c05c4cd1cfea63561f60087b2c9bd04", + "b5989524e028162754b07be7c27be96bf7b12bb00e0778084b24162e39322691", + "b520ffecceab5bf79a275ef4d7e6448c3bf8d9464197da07068aff033537124d", + "d654925e07f8c20dc319a8cdec71a1437fe6ce742b3d4e0d2a725871b9575157", + "4e90aea9012ef7907e458cf3891d625d26d5057d10e0f088803f18a83d615bca", + "2b6fb712ec3c046568aea2a76c2eedfe9ba4666e97a25e37de0198b33da2c258", + "a2a18f4bd47dc08a468e12c1742a40a99929b8f3657afe1842d31ea765e5b354", + "e24c758ca91a5d21bc6ebd76ae106fb2db20ca0d298563c6b6defe85e868a565", + "8c23fe2968dd4d277f19962ca0e8c42db9e8e502dc7a291518683b1297dba42a", + "12eb8ad3d82efa1e943873d06f8aa1cea33bfde85039c60c6e607e0b871a00a6", + "cc47d10bde0d2f8485b6e97cefb12a00242a8f77e0412b12ee7944bb9e50ddd5", + "a7d90cdcbc20e06bde725b26673cc75cd7012f5e9435d97507b76449f0c5e905", + "fa023491bdce794dc996e19cc6e68cb3bd56d8aae3384ea0f437a569b11df55d", + "6bf40738051cc74a3da30a18a12c3a3780937992d2ba6dc45f9e497e4499fca4", + "6ed8f62f6b26108698a9a03d6ee140f27665025bc5aae9a7c61be4b31b1b4356", + "ddabeef058fcae58a90a6451b67955ebe132a501e71a1b784e10c71159efc94f", + "ffa84305fd56dc97137219d4f71e27acf36bbc7604243966d87a541fd703231c", + "c99fcf73b84764702d35e849013030ec883c119baaa30ef7d38431135081ce85", + "78dfcba7a2a5f406f8ffcacf93d45d78f11d880e2009ea74ccb4a3b27bf816aa", + "d54abba06611be7f37257809d45401725548e7f0ce336e772d48cd28dd215b39", + "348633c8aa3e8c3dee421d082cb4e1bf790a0c65ae0b472815d4bb34c58c13d0", + "effce7768afe5db9f2d7b415152aeb3f4a88e209df856d7ac99d8d35290216f0", + "2e217e2caff0fe277f5c031244223548a563ca7a469621899a84fcf11732a1f4", + "a93d24b826ec86637ce73a7e7a93117a8d67469fcd8e023e9a1f19fd0d4316d6", + "1cf518d73a53506f892cc2af73e19bafe8eec2b1c46ebf023ab10b48bda53068", + "9ed08506f3bed6d10af3217d2950f5ab22102d171a32efb1c56fe57a49b57d88", + "5f4321fa95dba7dd72070c81baf5f939b696f6b9ed7d87a1f920faab546aecf2", + "2bd6aefcae756420277186dbefdb5fc15e7353edd95ead2046c350a80a38240d", + "47eaf6bbb89cbb3ba9529cf5dba55ff942225f6b9302e20a2456a841f69c2ef1", + "e0f03a98da824116d4634e8e7bcb702b1b9d1c1437133cc8c0a7e4df46a61fb6", + "0ee6335c1d39fe474aa6587e34b3ecf89eab75edab2f3a690d78cd815f53d050", + "39f95328be72cf7be66292825f9fa9755b8a34b945d947700c8de98dee732241", + "8d1bdb060e858d59d3b86db666c3d5a56dbd6e5665ae6c060c2098a56a67d0bf", + "68944c5e75c528dc2be74f37cc94df8df7cb5b38c43134cdf1820e0a4830759b", + "40e8a76fe6be92a4c09cf1379293b095c66fe4f434d0b1023830e09611d0b21a", + "69fad741cf0e76ec477349574371e742cefd1696d307761493d5e4474fdf62d2", + "a17d67731a1571dd1e29190693cbbaaf6f9057efe0c3896f39d525cdc1fe46f3", + "f31132f2246da0b6e0af7011f64970e507d2510f2368a77eeb2f85963b77b6d1", + "67ae2e52e07fdbf449cef926199c1e52298e216b8f86df4ce6f11dec4d39e9bc", + "eaa238a2a1ad92c06e196a19e98a6628b2e78ff690f08fe31f108cf868d0577d", + "233c8f1981194a0f0c5d28f1f7cc9e487abea87c9be7c51543c37356c712a5be", + "d827789d99274c3846b7b2c4fc05f2a13e1abd2c79b508d42043e1bc7a7b0f05", + "62d94752473f9a5e0b90afe7cbb97bb124a61b3105579e2b238fb662e3e33c96", + "36f9359018f217d57f712b5c695a3fc27ab442d643b58939407d8901db19dff1", + "aaf791f756204935bf3506453453ffd955527143897563b15f23c51bf80c95bb", + "e5b196bdee1fdbca2a5a8343e83470b0be1cf9c861c5c772e883822e47113316", + "1395969a21712b8e87f413cbe3301ba85aa18011b742a3fc91c95ab805b94076", + "0190828792725544737c83a4372aeabfad62cec26f9a6882e5a39ae4282adb63", + "1d7a37cc325cd1782be0aadd108222fbc0b6677e92969d0ba602f2370e98c77f", + "1758373d2af5193263d17515b11af723cbd0152aea5e1313b812d8f1443e1958", + "acb808cdc6bf7a5999c7d0a27d732d9b55d71d4db3a8639c10073465223e7e9c", + "c75c78757c9fd389e54afc1f5d13199cebe6371c4d632bcba4c10cfe6114669c", + "5af35c9d402461dec054c9b9cbb97591224f1c23b4557186f065fc84ee70968f", } -const mainnetPreverifiedHeight uint64 = 13701888 +const mainnetPreverifiedHeight uint64 = 13751424 diff --git a/turbo/stages/headerdownload/preverified_hashes_ropsten.go b/turbo/stages/headerdownload/preverified_hashes_ropsten.go index 5a983b24572..b5469ea1ff9 100644 --- a/turbo/stages/headerdownload/preverified_hashes_ropsten.go +++ b/turbo/stages/headerdownload/preverified_hashes_ropsten.go @@ -59959,6 +59959,279 @@ var ropstenPreverifiedHashes = []string{ "4e4156ef42cad98b2980ef1d4cf8d266015c7375e1b7c70c660fc3fa617431ee", "154b8f020266a216ea46fdac5c1ac7b19dc1a2d8d60ceb1eec789fd854d38d5c", "5266b2193223c15de0a8f04d2d1f286fd9a961148a40cdc4cfb45b2d965f6b63", + "b0cb642c22f7721d1cd14961372e0c3010aab09ca817aeae8745534f62fa7faf", + "f9ab7ef049fcd8de5f8023162bf258d3cbc4a3bc2ca3523711edd34ccacf3c90", + "8e971ee78201fb5958ad3a62669411d2edb9421a5c8c3d9c61a1fd67538d8506", + "5d035ca81cb3b8a539f54004804b5e6664f7a97147e1b574e07e6ff00ff3a4ae", + "1176b9bff7f7889cb7c137112fc52fdcc2a7f37b4b20dcca3ffb9060cd2048c7", + "cb37ca482fc89cf4792e5ecc747c498ede210d6f630bb6b75bd7ebb1f0fcddb3", + "2ee4dc7a1a38f85d02be58d103d1b871eac4b471c0a810b6730b854d60e0e54b", + "51dcab90ad805cfb0bb59a82fa1bc80a003d167279ce00ef106fe9e6122a76b2", + "3d91d886009a3a8df623e0e86534c3a60768f75b46581dc453486ad5e4d035a7", + "d52f6925030de0454b6bb624d2e1df594a60d201bdde2b6de934727a4e28b815", + "81738639269f04c25d76f30ba6cc8546b00c11f733df640734dcf4efd8bb5ea2", + "3fd2ac7dbfda6ab0869274b15d17a7f5ec7da7d3462158c58b1114fbdf28d7cc", + "79c4dc99579dfc2dfcab2849fe589b5c4a215c17948b2dd5a2f86a65be868292", + "8f19442d1f0383941d93030b24bdd03681bba02ebe7ee48ab74aa012cf33203a", + "c7755fda40a0248d71d5ed7377ab70eadd5d4b71bd2a42c76718b05320dff8f8", + "fd1fe49413b07c88d183a530a75303259448f113ee014578a747515bb1bb5550", + "428916cfd72c64fbb26723434eeb1f493d9e010ab02fa1ef052c6555df34ebd0", + "7efb5900ab860cc95f6926c03abeff96b27e7351aaa2dbc2c514bdad49b910e9", + "9c656c501aae6d19632d577241a6686f88f904a6d9036b4402eba719fac14b96", + "2bab2aebb07e566d1950ffdb8d3f2cef72f0d57aeb574f82cb9aa11fa84954d4", + "e9761ce0bcea339061bce9c1afb888f747a110993c441f944e483e403139870c", + "a7d9ec158c4867573df8e4166298cdf35c6ba2128ce8a08acb6f8d3ccdd4d145", + "584e4c437b180b4b8e153dd3dd54acf42815b8638b379fba4de1e72d9e959212", + "c1d964e38d66e7b87ec8aa782c7c4d64cb025facad817e5a440985309da329c2", + "2601499fda5385bdfc77973e7d7043fdb5bbfcc1f76ec838d34e63f313e3c652", + "01a2203afbe8c5f85cfb58a0a72324f4a7ce939610f6ba18a5cb082fc81eaf5b", + "44a570d1be997e9a6bcda81d973fcf14eac3311810f1b677f0d0f3e2e7542aae", + "04fb697cfb1524f909592313859c14bd779272523e21f4a70a3b1f4dcfd98043", + "b0a2b0a0fb637a0ff8810d8b0c038a8e42f6c5aa8d22df4b07921ad48bda8f78", + "05717a0ccd09f76fc17e5f299522cc027b368ed6b494426fe1503a63e2619b5d", + "d183becc6978c4c806406964573502977c9b5b8f24d769d272bd9c42c22765bd", + "6ff78ef3203d2380f030c25db3b0b39e32e909e97e4da086911a009bb37f261a", + "4d20df03b15265f579b5f7794acfde7356330de0424f7c11cf44cc25bc75a9ba", + "cd8a4113e93d1713d2dbac16a26db932c970e34a3e5d74e22843c37db40f7161", + "b6b1a8ad25c9e490d76f8cfa42776cbc434c94134e9a8656b2ac963c2d3951c9", + "63074569b04368e2d1fadc335f4cad1526e6d19e4a45816cea594b50b6f855e2", + "5fbed01e7e302f8c728e5c055676d80fb2847238c81962739d2e2618b0acd66f", + "ab6a45d977bd4bf76a504ea54bc0cd7ba6cf6a4404ec4ae125aa7ffa81a97150", + "c7ccf40ef8ee0dde4a8cf4c5a976ae43f1661adb298e67d59a6b4ba564c6b74e", + "62272869c6a6e131a461e49290d44ac2ca5a2a660327cfc886cb1bec62018897", + "f8ab82faffc9ee70ebff1eda41bc32a5274c9a5c5d6c99c2400097561ce5d25f", + "2043f6c9ebfee6510048d0a410418e29b7046b0d4f02bd1c2f7a64421cd2b488", + "5c32ff823f133a51b123710659eb618f962a21893fee6b049baa88095e6f8057", + "5e0df3ae288705c4c742d421e34315911e4fa352cbaf9970f9728fe6df3f8d87", + "0b409225d37ffbda4321b3a9cc8732291eaa47711c9b2f6026708a01f57d905d", + "ad8ee19e44bcd5433d333fe5ddfbb24b9bb392ca2d60a2ce8fa003b1505e4724", + "97f54b49bfab7e7d9381f4697c847135b93392f2ddd8f53dca2698a268968745", + "3288091c7839cd0c7d5a29e4035ea83f99f8055ce08f112ca62194bca7a4fce1", + "16d6378c9a125e3c9ff1509837f18a0dc9aac19b8632b321c3eec3538138e746", + "cf19a46a0efec275b5c917e6fbebc4ee95e3caddbb0b6cb54370e55be0254af2", + "d21c66210e191bff9c090b4c2a3b1b65e07ef803c09438399405dc0f1869196a", + "798575c5bbd07a60f32934c1f3cbbcf47a2f82e3186dae2710654727f8df5bc2", + "11e6a76d2b1ac345df7bc68d3de9ba34ff46cfa318c58642d8defb385725c3f4", + "db08ac0356359a29b598a9ba5644399c5403130a3638b93f101f61f1dbd435e3", + "9ccc033bdcdc42d3ebc7b4c1d62d43c5c9a08231ac3a7a255d3dae520a90a0b5", + "1820a01f6dd3d2749ec5271e182f9f4b4d56d9af3e2c0a7a03314cd97be5c473", + "c5f5baf7115a5707b51175e898518123ac61544a933a551fa0123f0f0cd56c7c", + "73f93e12e18d67f7cad3e87e963daef9fd2212330595fa022ceb07e6fca04be8", + "562b0ae75273014ae62fd6b496150ab3d8e9368118b6c137a4f1a4d6503dc232", + "5d134a029f1f82c2ae8a70cabc9145b52e57ffb16b42f5901ef2acaa1f5cf508", + "bd41432fcbceadc546ceb3ad9fa09e403802e1decee3dd7372fb2a84a6a6d37f", + "46ce3f363fba838cc742448ec4879b3be1fa74506583a4149f917ee379fcccf5", + "049e93a9f2fb3e5fbe63a9919c223bf7347be2a64955cdedca8ca4e25005b0ba", + "f4b233c4990af84aee22783e246eb2a75c1cbf1ddc2d645ae6961428bab36ca5", + "3901ba0f19250ecbd4839648e3509ac91351e1f0791a98fc95a802750c8eb7e6", + "52497b6032ce3ae0ea892414bab1e028f3c96611bcee7c283f682529c587c1d7", + "cf0be78caeff3de709301fde9f122f2a347871721b63acd8ee7f9e23de0d54ba", + "ef9ef76710a0d314a9f9982c80511ca95cdf80fc45a49a61e803f0c7f611670d", + "1b19af6891103658ee1f63689fc08773af359479bfc00e3168b596f826d9fc18", + "c7400dfa2c2482d5e5f737aa9c41c713631736add5438de307333de3e5691083", + "5aa165ad39207171e8b9664e43ba5843622fc00c2da7b660e9144ac3e5986258", + "d772535778f719b526e1fba706e7a2f1d22fbdff28590bb6cae843802c9f4360", + "b36cf4a9545f01657083bc7998fe41437669d0141bd89e853120e3afadc07b07", + "d42761532df021f5378b47c6247f6775282b5838496d574b1019524fb3590b68", + "af1a56c42582d1b8b4e289b584f4e7003da538e1ecf44d196cbce87f3719bbd9", + "9f74407cc321dd1072837573b1ce3a0167617bfa4b0cd6d7ebde53b2384f53e9", + "7025d7b9a3e65f42da6e0c6bb07a8f39c439e509f36fe611ae2ba7fac48bb699", + "04d38a2c1473c4f19ea3c444e64d152a682b4980ad8d444f67e5c0582cd55cf3", + "2bd39f99654b7fc7f632c05d8010c243ef74237ed0c96b22f1ffd13a9937dd16", + "5c367e20d69ab7d6be71c375364d6734f4e0b4de82fd8628cbfefc29bf599eb8", + "01b065cba06a0ecf46d4e0dd9b26b063959f6c14d1b413fc2b1ccec786200f24", + "4b1927dabebe2fa64595990dcd5895e890693c8210b549077b7e799baed8c0b5", + "67ec718867a43b587a794f9d1aa54f558ec858062937b801d8dd5e81ae4bbea9", + "1a9841a6c4fdf65dec1457639557da1d37aee2bf22e358a2d2897a78c1e05da3", + "501593ae7654975065f82e034e0fbae56aea4377d8360fb2f61b8dac2ed2f32a", + "42b38836da5db119ced931d8df23135ca9711b09f37c16258b95c977f5733994", + "054341bf75d236068aca8cb4bdec707ad0dcb1b6779c02f2cdda63cc30c88979", + "4e52ce77d156cf5a5114d30639ae430f077cec5ad8f5e1b828c605e60d788dca", + "94c0f630591a085c81e9ac0e525f8bca95659c86e6994994b155cc8f0283e6f2", + "3413ec7356d62057b276206294d9e29953936be440ca219562d2535968641d50", + "bd3812836bf4f69b6852daf2ebce02a5668d17e50a064d9f3862af638a530f13", + "3bc8b36d7d30d1f3953b409f3f3a5a994f205cf7713d38e6cc14b8b4dedbf9a3", + "f4f051015f83a0ce521407ce85f4fb8ba5a5d57674486ebfaaf18c07762a0fc0", + "d7bfd1e03ba7c9cae1806a753bcb91fc44041ff20f45c8d659ccc8bfe85bab3f", + "e4b26f5a36819fa698d686734fce37b1ec337c47b1a6af6958caa28abd38df49", + "47d49b44521128c0d81ce3f79b88f58f76d768e745fb6174946e2410865eadcf", + "8ee46e1fb917bb43abfea574dbbfa3268a13616dccab013fc7b21e8da1da2fe1", + "3b2c897915faf5faf2253ca203dfcda58c54722cd09b874acf8c26c65bab81d0", + "c675b76b35e92a0ead1366f1a59fc215bbfbf65594134750b10290c91c619162", + "cbab1385eade75dc7642a60e5d30494414dad6f47f101162e092cb94a86d6512", + "ff3f3b01ad3249ad735cf78b583fa40f011fbe0945ab6577ee0a0704c26c306a", + "cc35fba7dfc86fc90f5cb754d908b5dbc365dbfc53458b7ee7ae58c359dea716", + "cd8d5a4345d628f5163561291178b3e03360cc6cbacb9d26062ab8ec8e5b3180", + "881b6ea1594a2715e40162db0fc0ea82615742d6716da4017ec3504c7e8e0e7d", + "681671a5befcfdee8720eb61ee29fa7aad00b82c0742b749667039da4e99d287", + "8ece2e41b971e593751c8bb9736a37486afcf766d2fc695bc5edc36aa0526df7", + "2e39b1940e38216c86dd7aa99aaad9c305a9d8cc4d40f5327241f3b417b7c994", + "4b069ce79d4f6ad03714e9782b9edab2ce1c30109b0103c1af0a512ee16939da", + "cb13a3449a4eaf1dc97111b0f2276e9f6d3d1cdd490d5b2b5170d3dfdeb8153b", + "66d23be062f432fe0cd2a354e5fecae251c9b327c0340ff1310aeec4048b4f2a", + "0a7246497d7fb1c2d44d08d8e2afa745a8dcbe7ed6eae60ec1d13a00b5d5a412", + "b369c5cd8a2db8b295a120f9ce4378bf15fc5b1c343a7c8138225d13a91d0b90", + "d2bbd80f5493e97800b80849c32aab78e9573f0a18ac8af7c45bd26872f5a9d3", + "4006816cddda29684d3a7c91814dbe276c9f3d07b4ceef498cd7b8bd791d3f2b", + "2e3b0c3ed7c8f79f9db85d7c2dae7cb81c5a8d941537c261532128e84a96d7a0", + "4e5305010fe7292af27caa1f6f90fd700438c4f2a3343dcdc6ec890207eb86c0", + "3cba3cd605a7bd11b7884413514c971b572a0cc732131da8df3f70d41b711866", + "a565e367b1f87f3f2d5ba7d62c1e87b21e5fdb949ce4ce1a978e314f782b5542", + "65b1879541471e36d8c0fc3a882de5509dbae8ff7858bca23f52bdf90f6da088", + "377efaeaa59cb894eb2c71820a06d05bbd3ef684c4f6dd98c8b9b1850788b594", + "90c5ea6c8a61644f46448ba8643b83bb6520ae8d05d7e33e96fc3846ed89344d", + "83cd4363131b20465ff2ba1add73b863ff59aaafd384e44f209154741a1f8a7d", + "838d1d4e588b7a6788db10890c10bf668a6239226289dba47a28991e42e132bc", + "137b250cfe377cafa5445c7adfa040eca47243052257b80ead211120047e8758", + "84eb9c48e9616016d285ea1fbc504816ded1f9bc5ab1a72be09dc16accc13fbd", + "248c7207e379ca4353ffe84dedf54539388f19e359dd4ee3dc3a3b950a8287fe", + "bdbdc77cd631d626dd083a60e91da901baa10f225e59e736efea7f056dd2ada4", + "2cf048f3ac69d8abaa385124c1132e2e08256d4109790982ace3fc990b10ae59", + "1dd506fe19baa44d86223c2830c2ab3951594ceb62b1f75d03637997a8b01902", + "d721f928f00755ecb65b4a355b87309d020406f97d1d6c87abb58ea2c16867e1", + "0e89769ae6a1be22761fb4be8779277f3fb98f476bbe7c9fc0982f7d780910fc", + "e21a5448179e801fa41dcb4177bb1a0bf227b018a0f2b6f79bd6e61e4d21d08d", + "39d3a4be0139632950ba737e917b89ea9f27734ec0a6fb7d172d5ab95d7f9424", + "babfe0097af57e7bdbcca6718a06858bbc160fd9d1b772cf80aa5a13f8b54908", + "854245e2b108cd1380f5f40eb6aa38255e169ab9ab1e53414445487ebf6c8562", + "49b0819acb9278b95af9490cf9b9aefac3d1341e9279e3712e57cd416de2a623", + "e9e33443e8c31779a2ab6bae2978df7e325391fff2c4e45b65bfb76314c58ee9", + "0116b9b59ed816067a45371a4bc7b33b2e8af428e2b379a56764d6b040820fae", + "7a6b415a215896d3d3b32dac017373ed9e23570754af9120baee5476d80fea74", + "aa15b7e0551365d31c318a7e451ee22342c80f4eae2363c5c20131b21d032e30", + "f3f5e44587adac5477685933bd23f4bfad89802a5d03c5d541cbc59d871c5b66", + "7a3f358ca7598111722d85375b33e19b0defe270829ed4ab3e4931a484999505", + "f9d3e61ffb1fd4a893c1441b1daed9c0af44ce2d5791404b1f5e269af4ac30b7", + "c062a9c76f74430ca531ae8ef18642eff247092d07676ef17aebde8634955542", + "f2649484ba7cc60f0d070447a8f5ae3d3920ed4e42c0b5781f0f2fd48d394235", + "cb7238839020f3eae0ffed61dc1fa836e72bba904ab9158f254126aec10046ad", + "914916be5c7bdadcb172621bfe24105b5cc4cc6dad91f7ccf48a6f6a0de2fb54", + "2976cb15a500f37413ab9af639dbb4a56af8fa1f0581ced8b84f2bbfb804331b", + "22a602aa00f069ff26d069ee5a256ac78f52ed82b009a976cd6ee7785665785d", + "85eabe73c66e716ce398248a10e13d672cb0a4c761cb4df1d6bac25457e5de7f", + "0ffcb3d6206bba239487960a7823c8915819a46f8a3c4dcc8f02eb54fd32f7af", + "39b157aa03252bc203350a1e9a8cdc9b7cce256be6cb86d1ebbbc46cc11b9cef", + "76a6e64b0750d5ed7211324407f82dd05f35636fb266de428f3e6da2f1e5604e", + "b2d671aa1226c84ec362e15c42e7fe41bd8744f3347d796dc854311ed0da8af8", + "73ba12675e1c4b8896419dd580a2ec037060c75fe933a3487d1dee76b5641d9f", + "ebdb44bae215a97acd24fb72b959e6f4adbd01d24b08ddb56ea7dd498cb9cb1e", + "2b4bf377a22c5c7e593fa76813c5899dffd373630f2694f5912dd85a5a4d6767", + "0d81f88bec5ab315971e863a45bae4fdb7f500a2f15e1450cd34484f19557aa3", + "3d86824a65c2e5ea06d70ea091c58fd0fce10e0a1e8bdff1b1f7513a5ad54a1b", + "57197e1102e45e7d9ae2b455adc5a5d2ae99477ef23e0c6713993d0394f9c8d1", + "5644169162ce657878a10c9303296c095b677ff3ff0f8c07042d45aeae13314f", + "0aa51c8491f422a197616fa297dbd448d95f3d0bdaeaf1a4e1524d986d3a0e71", + "9fe9772e550142acadf71d06fea6ce2c1a5dca0812f5c2a659936a0a4c05808f", + "e8faf8ad612d08edde4f70d4865dc60aa290682e61598c97bb4d9afb8d409e6a", + "7348b7c318c644b917e99025511ee0ea28b0b00ff503047dc6783458b0b9d5eb", + "442fa5339d5b05657b511063e99b6bf85e068693f8b4875d2789fbe0126f7f0f", + "e18ce1131242ec53e1ba43acf11faf88b1b7e3119a4fce946d7c655535d147d6", + "86e2eb93d778650858971a695dcb95c5dd93644256fd588fc1a121f92c52a309", + "a2590bb79390e88122812e4bc1f222311141931240e3a85f36a4fe2231f1c322", + "00bac8b367028e70ce32248668955eb1633d515036c0c29f06704752d1d2b6fc", + "7252575859b6573151146ef8d7122b7c43a7bcd70d3c719304751b6cfdf46640", + "efa705449f25b9bc2c319765371dd2c9bb85cf7b1eb81030c434e8a7b08d1ccc", + "b257df4698a02035a7f39dd5ff064e7d3b95c028b0addb1d48123d2a1d92f836", + "dd73f403f3ba8fb3352eaa63a24b03634a5c2d9f7f40befd77b303f65df2f7f0", + "18a9066dc78cfae3ddcf11f1ab55b112015a5777de10fd2d789ab2f38b17edfb", + "0ad2bf21420cecaceb1b66978b7cb1d6398ccb85d2a5fc286bc34fe01810f042", + "e116bbd0b07ceaad30d43b0b9313c25fcd06a30ce23dc97612dae3e9a199bb85", + "4d95d4de8d45de72bee0a9393c1b073aeb7efe03d4d8fa5871cc1cf4e6375fea", + "5f1a770efaab14478c242217f419b1120d4bfcaa6a0d25185c1ae57f22dfe1e4", + "98808c78692b2f92666fe26d6a202910607541bf403aa0a44a330fcf74f99dd5", + "f7d14b5eaecf52abd647a6a87355594aa7750bdf5e603bfb25703ed4160061c0", + "74bd88fe5da9538e13a8aafcf606aa6c9450313bb233c938e5a5091b0e3e3acd", + "57e8c30a9e77326c4dc853d6226d6205c5dd90c294d068199d6f0890eba15381", + "8fa49fa326b7bb030aa2e759af853b557f954ab0ed2a67cb43871af4b78b4cb0", + "7defcd6faa9b581ef0b0c3413aecf44a16329aed53c5c9b7e918f6b23ede31e4", + "05dad3a8880d24bb2b0fb2108f91a337bd2d981d3933feb73a44fafdc3c6db1d", + "e3a493018e3f4312b554ec02e4884e930659123c38256e6ab205580709b7daae", + "2ad22380feb3aea3b71573e747a8668e40d5c32857c9e7b7fe06ab9041ecbab3", + "eaa070de9a8625949281feeabb944526e88e94affc5fd8f4a36e18bd3fc60611", + "2b67750e5bc723cdca4c34e5c8bfb3a70a097b95f5a24471b6971481f8d1f357", + "d8da4b3ee76ae4bf72cf5b2520730fd1bcdae3301b8f7f97f3f1279b94cb63df", + "453931bcf9c733c74441f2d03d66d0e75661c6c38437fc6ac871b7195a9b5933", + "bbe4788a9c1f28f43080172e865682d29c44215550b70ed45be917ed1a9e23a3", + "c9c7febfe8a76246728c75456510d4a498fbde571a77a74f412aab3fc625a8a2", + "038bc0a4b28fde1dd011009b3f30ab8d7ea0e5438fc48974c65839b7b267db65", + "76b0b8921c2bb1fc3b1c6cd01d0e3b6b06a795677f284f843970e7d51ffc7a07", + "b780b2be6aadc8369fe6791bf3604aa58082c889be0e0aef06a057e6e23749da", + "0526fc9dcc46a40e7fd6de833bc9847f8fb127f5bc57b311d2ea322b7701e8c1", + "9d847df96fd2698becb987aa63eddb4e8fef63921279657b0c6d85dc8e6a9c3f", + "8feb03c682079a201f0872925238e087d12c029ca5780ba4aa4db76c517344ed", + "ba97f7ebf4228f95e7b8ae8c3be355f0046d4467fadbfc13c79188850a5e637e", + "e9a8749fea044dd7750aded678550819b6e9949f301ff84756d35d80d5b9fecc", + "d317643345723bc9a0944d5c8ae79ac77378237f4b390b807b65b07b98f89527", + "3cae3653c05b40b5eea57f5024c97b998436298f0810acf77bfe1ede6e24472c", + "98dc2e99ad150321eadd9fb0a52dec99a0798d467f32a543b3e4acbbc3aae30e", + "49220e155618814576f7dda0a34d752eb76c32c22f9e00dd3551c02284929e76", + "8885b3bb50a1c0b9229c821f2d2208e3217f9098cb4f0024e93d53e0cc43cfb6", + "b291b884875ab66eef943ec15efc447866785f55efc9b3e5dc3f56caed8f013b", + "ace7ff001fef2b0959830328a42cd1a3b20fdff50c11d242e1a439efaf822140", + "7d6d710037f69db03f94f0dd689645043eae6095e9dc9ee0b21757f35bc8eddd", + "6fe998b6758197bb13e319436ae405b753d15d05ba2e9ab5ed88e91f11759ce1", + "26215ef84a9e85f479ac95cb3ef5f8a998eb0d5d5326ecac67227f5bf32466cc", + "c26afb6c5092f81d27b84767cc4584178dd8aeb9c62a740846279de5d438f29e", + "1bd464a748a6b17b26c2102b146c71cc024d8b01b95aa9d1236982a2c8d8bf21", + "19856b056f048d62e6d0d55503ce455173a65a4cd8a011dc1a55371ab5ce38d2", + "3969725fc468e500c621ae341ab5512433dcb65ae723123662de8c6722b74f43", + "e7190dc3af13fa3a40781268adc672e96802af27db82b37c56989b7e43c2f549", + "75a07ae4cefb028a88dc2bcf7493acce416edb1fde18764b3e3057a0ccc43286", + "c405573c480258acd20f5bb7a717b82b5585a2801afc782bc040c6db4010a253", + "b890127629d2c63428c759c51c59397111ccdcafc872c42c492e9f6a94b45590", + "36d92b04f646457cedba7f247457c8e46235dfb3f26fc5ec49b257dcec28f067", + "c564de37a18e36a610f1dedbe71b6f6b8c210c6d1a85385b0066bef49e809ec3", + "05fad4ed4dd285972b4278fbc5dad15f96ae14e8182d8ccbcc2c2087ed1755dd", + "a3af95fc41272893b558f490f8768f2ef050adf7d334a5e1c3b2d1b0f99b447c", + "dafad919fcf2e87798c6ceeeb63ae4516d23a2e50889ae239a1442cc9b670d93", + "4a5666e5ba86dcfaccfea21ae865e35684c9240819f82c3b0f1cda257b44b272", + "f7c605868b86a876741922d7824bee75fd85013b135f3bcbfaa3f408554ccd02", + "f9678dc2dbf483b29905a8b5fb37f8d787cb9a0812ab9147519746ecccfc5569", + "b72f33cbe981f3985a96bf22486646eaf44fd81c5bb15424d3571037f75ed6e2", + "71c0efbdeaf183cfd670b50df55ff212679ec6855d8464025369175d7224bad9", + "c329d753fc7966ad3c4ab8da89c2e813fd78b6d502c34e9bef00522491ee426b", + "1165b94b70e80d0fc52aa5ff1db76b04eb9f84084294550e720e9cf293729376", + "df06ec509ec9271e9f316ba6b7a59f27fd244e41aec96afbd051e731f5266944", + "011956826c6818855812ae32618ef8ab22a7a9ab9f837b864df399f8b5ed15b7", + "a630ce1f48fa8d50a655a3e4dc3b7e91bcb081de11f21a93a1c32573b2d4ba57", + "9be46d984864108587c8959f228dee2a1a071af742614886cdff188ce8dc9ee8", + "8471c9ee1a3b46cf30277e582e6341a91acd4af4d7ff21a7efb887fa502de677", + "49f5625422606448ead7efbc0483f36623456dfa9fc9649b0dcc1b5d0f8abec0", + "fee84743cf1538bc182a000911fe29c568a7a98297c173a394042d3247327cf0", + "6044abe5782e8ce2541957ad7edb21b10c36bb8f2e0390070347f302287ac5a3", + "ff9321d33b57f4b12fad8bff3236ad774e9f9ba7edcb82455bcf285988adbcd5", + "894cbbcf75320f107546d23f76f14c15350078a2aca7983920d3b2db23c025ea", + "d1fde0be8448d0c198b637a90070ac5c97a861b43f5d27b14510b8257adbad9d", + "5dffd633267a47277c33476c04c71102a8098f5c30c6a2646753a6d299a34347", + "776134fdd511bbc982975baa7762dccc66d64d39211606ee45286d2cb72689ce", + "29da2edc3f36311287cf19f64423ab53e5b54b805c2a23b32208facac0d8e17e", + "08c98b954da324f958f5a4930cdb3630ef27dbb806dbccdc0fb1f723f8c7e94b", + "98c8d1391ded475b1ef0031169685cf205764661fc99e75046563aa42b9f17f7", + "d137eeadbef827ae0fdfa0cf060e362c701b8cf06f23e9a6dd33e1c723f57ec7", + "7647a24f8e4fa7ad5f3233746aa7b1423506c70ac8dd0c10ae409fa211266a09", + "60ac5cd35fb7079484282cfcd3c8e01c7b020615bb0192c09ce6771fd0558afe", + "d515b4e50efe7b23f6db98d861999fa1ce6d8284215abc4ed8951427dbc8312b", + "a8fd5ab10b593767ee4e20a6986daad74094c19bfcca12478f58fb091fea75fa", + "2742ea0e6be2a43ae769639b09c564631d23a5e1b53256b6fa5c2e1dbacd3540", + "548113ceee52a2d6def447293a94bef0f770550727b1206f64ae6dfed4843c44", + "ffdfa353b8601031c85f131cb19bab5b8813a136270bc0b5b7130458eed1396e", + "4a22e2009bc11b34ea273201fc62276931f4bcc2b76420b099de84335b8d2730", + "7283f9a9abdb08fff715c01e54e5acd7fc4a5273a9d6ff9cab162b44d22720f7", + "71cade9c8f2623b9fae617ed63bb1e1fd84f00b13040de955601cb5e7f16be46", + "ccfc047650e8fc835ad90a1868b4dc054c7c0914ad4f4da3222ee9e3a78b4553", + "c8d394ad146585a4faa5ba3a838bfaa2d4c040689e03e7cbb89d619dffd7164a", + "e353a7dc8f2ea1c7ea6e2313dbf3c5aaa66c7c6b142bf8bd6ed69e9fb8b346c3", + "573a68a28e32ab713369f6ff06f1608e67f50f96f34b4304029a2ebaf478fd55", + "90edd96bbf08e9ce49fedb4c2fcad370e1b767fae9c9660be8dc8ec9874b0b06", + "1a3f940e28b5af263d13e1bd478498f40bbc9734779237d04af19b27f160ef35", + "b0fb529e054f0d32dd97a66dcfaed46d28179b290d87988b0c5906bca487a080", + "6808f873ab5913ec97e867647b39ab18023ff131713e9e89455f34053e3d7a86", + "cba24cea4d951f8e9318eefbb105fb24f30577d6cb655ad53ec8ed5023a08965", + "8e869a0f9dc3b335753c7e3c9ba02c08ced1ea243f48b1259685827f5951694c", + "d744c2a1d500d62f98d0bbedb524347d10df7d182274a73e3d408bce6b66c871", + "9040fbff02b136b48da79df689bb5afb19cf163b499d00cd01eaae089f1fd96a", + "86d5f9bab608d5523bf53644a3b140d96e10a36d84997cc5514a14d1afeaedd2", + "10795cda8415b84a8ef1b5fd0c79a4f2c7176e642e62a6f22417426702738fd6", } -const ropstenPreverifiedHeight uint64 = 11511744 +const ropstenPreverifiedHeight uint64 = 11564160 From 1781181b7d970609c55b3243a7b7d620de3eaa2e Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Mon, 6 Dec 2021 16:46:02 +0000 Subject: [PATCH 059/261] Fix rlp from erigon-lib (#3101) Co-authored-by: Alexey Sharp --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 335bda49199..b481e120d3b 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20211201135019-85b4119c0f58 + github.com/ledgerwatch/erigon-lib v0.0.0-20211206151611-8f75c77e6cea github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 diff --git a/go.sum b/go.sum index 70bb1e089ae..2f604bd5e26 100644 --- a/go.sum +++ b/go.sum @@ -497,8 +497,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20211201135019-85b4119c0f58 h1:VXWRbNnhTaCkKMSQY9z7zjnhOQiFesFzWRLINJI12n4= -github.com/ledgerwatch/erigon-lib v0.0.0-20211201135019-85b4119c0f58/go.mod h1:lyGP3i0x4CeabdKZ4beycD5xZfHWZwJsAX+70OfGj4Y= +github.com/ledgerwatch/erigon-lib v0.0.0-20211206151611-8f75c77e6cea h1:4Eqqqq1tm3PVWb8frJ2fIPESaQ08PPyPgbUZg3w2uF8= +github.com/ledgerwatch/erigon-lib v0.0.0-20211206151611-8f75c77e6cea/go.mod h1:lyGP3i0x4CeabdKZ4beycD5xZfHWZwJsAX+70OfGj4Y= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= From 89169359b28398916671a123b5a19a075ec356c9 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Sun, 12 Dec 2021 16:10:24 +0700 Subject: [PATCH 060/261] save (#3115) --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index bd22ff462b1..0474c9480ef 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -40,7 +40,7 @@ services: rpcdaemon: image: thorax/erigon:latest - command: rpcdaemon --datadir=/home/erigon/.local/share/erigon --private.api.addr=erigon:9090 --http.addr=0.0.0.0 --http.vhosts=* --http.corsdomain=* --http.api=eth,debug,net --ws + command: rpcdaemon --datadir=/home/erigon/.local/share/erigon --private.api.addr=erigon:9090 --txpool.api.addr=erigon:9090 --http.addr=0.0.0.0 --http.vhosts=* --http.corsdomain=* --http.api=eth,debug,net --ws pid: service:erigon # Use erigon's PID namespace. It's required to open Erigon's DB from another process (RPCDaemon local-mode) volumes: - ${XDG_DATA_HOME:-~/.local/share}/erigon:/home/erigon/.local/share/erigon From 5fa6889acf2acefd2f06317992c896ec26b9ed35 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Sun, 12 Dec 2021 11:23:57 +0000 Subject: [PATCH 061/261] Bump beta version to 2021.12.03 (#3110) --- params/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/params/version.go b/params/version.go index 7107e305f22..f57a62c4f27 100644 --- a/params/version.go +++ b/params/version.go @@ -33,7 +33,7 @@ var ( const ( VersionMajor = 2021 // Major version component of the current release VersionMinor = 12 // Minor version component of the current release - VersionMicro = 2 // Patch version component of the current release + VersionMicro = 3 // Patch version component of the current release VersionModifier = "beta" // Patch version component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" From 35fba5533a687080b7efe23ac3eb671c4ce7c22a Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Sun, 12 Dec 2021 11:24:06 +0000 Subject: [PATCH 062/261] [beta] Grpc healtcheck (#3109) * Issue/2710 add grpc health check (#3091) * ISSUE-2710: Add standard grpc health check to services with grpc server * Go import changed files * Add flags for healthcheck * Add grpc healthcheck option to rpcdaemon * Remove grpc port info if grpc is not enabled * Resolve merge issues * Fixup * go mod tidy Co-authored-by: primal_concrete_sledge Co-authored-by: Alexey Sharp --- cmd/cons/commands/clique.go | 1 + cmd/integration/commands/testing.go | 1 + cmd/rpcdaemon/cli/config.go | 91 +++++++++++++++++++++-------- cmd/sentry/commands/sentry.go | 4 +- cmd/sentry/download/sentry.go | 20 +++++-- cmd/utils/flags.go | 5 ++ eth/backend.go | 3 +- ethdb/privateapi/all.go | 16 ++++- go.mod | 4 +- go.sum | 12 +++- node/config.go | 3 + node/defaults.go | 2 + turbo/cli/default_flags.go | 1 + turbo/cli/flags.go | 6 ++ 14 files changed, 130 insertions(+), 39 deletions(-) diff --git a/cmd/cons/commands/clique.go b/cmd/cons/commands/clique.go index 4cecd887df1..e03a7025bce 100644 --- a/cmd/cons/commands/clique.go +++ b/cmd/cons/commands/clique.go @@ -15,6 +15,7 @@ import ( grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" grpc_recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery" + //grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "github.com/holiman/uint256" "github.com/ledgerwatch/erigon-lib/gointerfaces" diff --git a/cmd/integration/commands/testing.go b/cmd/integration/commands/testing.go index d4e3f077a33..10a5f71456f 100644 --- a/cmd/integration/commands/testing.go +++ b/cmd/integration/commands/testing.go @@ -10,6 +10,7 @@ import ( grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" grpc_recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery" + //grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" proto_sentry "github.com/ledgerwatch/erigon-lib/gointerfaces/sentry" proto_testing "github.com/ledgerwatch/erigon-lib/gointerfaces/testing" diff --git a/cmd/rpcdaemon/cli/config.go b/cmd/rpcdaemon/cli/config.go index a540519cd3e..db61f636715 100644 --- a/cmd/rpcdaemon/cli/config.go +++ b/cmd/rpcdaemon/cli/config.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "io" + "net" "net/http" "path" "time" @@ -29,34 +30,40 @@ import ( "github.com/spf13/cobra" "google.golang.org/grpc" "google.golang.org/grpc/codes" + grpcHealth "google.golang.org/grpc/health" + "google.golang.org/grpc/health/grpc_health_v1" "google.golang.org/grpc/status" ) type Flags struct { - PrivateApiAddr string - SingleNodeMode bool // Erigon's database can be read by separated processes on same machine - in read-only mode - with full support of transactions. It will share same "OS PageCache" with Erigon process. - Datadir string - Chaindata string - HttpListenAddress string - TLSCertfile string - TLSCACert string - TLSKeyFile string - HttpPort int - HttpCORSDomain []string - HttpVirtualHost []string - HttpCompression bool - API []string - Gascap uint64 - MaxTraces uint64 - WebsocketEnabled bool - WebsocketCompression bool - RpcAllowListFilePath string - RpcBatchConcurrency uint - TraceCompatibility bool // Bug for bug compatibility for trace_ routines with OpenEthereum - TxPoolV2 bool - TxPoolApiAddr string - TevmEnabled bool - StateCache kvcache.CoherentConfig + PrivateApiAddr string + SingleNodeMode bool // Erigon's database can be read by separated processes on same machine - in read-only mode - with full support of transactions. It will share same "OS PageCache" with Erigon process. + Datadir string + Chaindata string + HttpListenAddress string + TLSCertfile string + TLSCACert string + TLSKeyFile string + HttpPort int + HttpCORSDomain []string + HttpVirtualHost []string + HttpCompression bool + API []string + Gascap uint64 + MaxTraces uint64 + WebsocketEnabled bool + WebsocketCompression bool + RpcAllowListFilePath string + RpcBatchConcurrency uint + TraceCompatibility bool // Bug for bug compatibility for trace_ routines with OpenEthereum + TxPoolV2 bool + TxPoolApiAddr string + TevmEnabled bool + StateCache kvcache.CoherentConfig + GRPCServerEnabled bool + GRPCListenAddress string + GRPCPort int + GRPCHealthCheckEnabled bool } var rootCmd = &cobra.Command{ @@ -90,6 +97,10 @@ func RootCommand() (*cobra.Command, *Flags) { rootCmd.PersistentFlags().StringVar(&cfg.TxPoolApiAddr, "txpool.api.addr", "127.0.0.1:9090", "txpool api network address, for example: 127.0.0.1:9090") rootCmd.PersistentFlags().BoolVar(&cfg.TevmEnabled, "tevm", false, "Enables Transpiled EVM experiment") rootCmd.PersistentFlags().IntVar(&cfg.StateCache.KeysLimit, "state.cache", kvcache.DefaultCoherentConfig.KeysLimit, "Amount of keys to store in StateCache (enabled if no --datadir set). Set 0 to disable StateCache. 1_000_000 keys ~ equal to 2Gb RAM (maybe we will add RAM accounting in future versions).") + rootCmd.PersistentFlags().BoolVar(&cfg.GRPCServerEnabled, "grpc", false, "Enable GRPC server") + rootCmd.PersistentFlags().StringVar(&cfg.GRPCListenAddress, "grpc.addr", node.DefaultGRPCHost, "GRPC server listening interface") + rootCmd.PersistentFlags().IntVar(&cfg.GRPCPort, "grpc.port", node.DefaultGRPCPort, "GRPC server listening port") + rootCmd.PersistentFlags().BoolVar(&cfg.GRPCHealthCheckEnabled, "grpc.healthcheck", false, "Enable GRPC health check") if err := rootCmd.MarkPersistentFlagFilename("rpc.accessList", "json"); err != nil { panic(err) @@ -329,8 +340,29 @@ func StartRpcServer(ctx context.Context, cfg Flags, rpcAPI []rpc.API) error { if err != nil { return fmt.Errorf("could not start RPC api: %w", err) } + info := []interface{}{"url", httpEndpoint, "ws", cfg.WebsocketEnabled, + "ws.compression", cfg.WebsocketCompression, "grpc", cfg.GRPCServerEnabled} + var ( + healthServer *grpcHealth.Server + grpcServer *grpc.Server + grpcListener net.Listener + grpcEndpoint string + ) + if cfg.GRPCServerEnabled { + grpcEndpoint = fmt.Sprintf("%s:%d", cfg.GRPCListenAddress, cfg.GRPCPort) + if grpcListener, err = net.Listen("tcp", grpcEndpoint); err != nil { + return fmt.Errorf("could not start GRPC listener: %w", err) + } + grpcServer = grpc.NewServer() + if cfg.GRPCHealthCheckEnabled { + healthServer = grpcHealth.NewServer() + grpc_health_v1.RegisterHealthServer(grpcServer, healthServer) + } + go grpcServer.Serve(grpcListener) + info = append(info, "grpc.port", cfg.GRPCPort) + } - log.Info("HTTP endpoint opened", "url", httpEndpoint, "ws", cfg.WebsocketEnabled, "ws.compression", cfg.WebsocketCompression) + log.Info("HTTP endpoint opened", info...) defer func() { srv.Stop() @@ -338,6 +370,15 @@ func StartRpcServer(ctx context.Context, cfg Flags, rpcAPI []rpc.API) error { defer cancel() _ = listener.Shutdown(shutdownCtx) log.Info("HTTP endpoint closed", "url", httpEndpoint) + + if cfg.GRPCServerEnabled { + if cfg.GRPCHealthCheckEnabled { + healthServer.Shutdown() + } + grpcServer.GracefulStop() + _ = grpcListener.Close() + log.Info("GRPC endpoint closed", "url", grpcEndpoint) + } }() <-ctx.Done() log.Info("Exiting...") diff --git a/cmd/sentry/commands/sentry.go b/cmd/sentry/commands/sentry.go index acc0b9a45ac..ec4c276590e 100644 --- a/cmd/sentry/commands/sentry.go +++ b/cmd/sentry/commands/sentry.go @@ -28,6 +28,7 @@ var ( nodiscover bool // disable sentry's discovery mechanism protocol string netRestrict string // CIDR to restrict peering to + healthCheck bool ) func init() { @@ -50,6 +51,7 @@ func init() { rootCmd.Flags().BoolVar(&nodiscover, utils.NoDiscoverFlag.Name, false, utils.NoDiscoverFlag.Usage) rootCmd.Flags().StringVar(&netRestrict, "netrestrict", "", "CIDR range to accept peers from ") rootCmd.Flags().StringVar(&datadir, utils.DataDirFlag.Name, paths.DefaultDataDir(), utils.DataDirFlag.Usage) + rootCmd.Flags().BoolVar(&healthCheck, utils.HealthCheckFlag.Name, false, utils.HealthCheckFlag.Usage) if err := rootCmd.MarkFlagDirname(utils.DataDirFlag.Name); err != nil { panic(err) } @@ -82,7 +84,7 @@ var rootCmd = &cobra.Command{ if err != nil { return err } - return download.Sentry(datadir, sentryAddr, discoveryDNS, p2pConfig, uint(p)) + return download.Sentry(datadir, sentryAddr, discoveryDNS, p2pConfig, uint(p), healthCheck) }, } diff --git a/cmd/sentry/download/sentry.go b/cmd/sentry/download/sentry.go index c1e81639c92..75a9684e266 100644 --- a/cmd/sentry/download/sentry.go +++ b/cmd/sentry/download/sentry.go @@ -12,7 +12,6 @@ import ( "net" "os" "os/signal" - "path" "sort" "sync" "sync/atomic" @@ -36,6 +35,8 @@ import ( "github.com/ledgerwatch/erigon/rlp" "github.com/ledgerwatch/log/v3" "google.golang.org/grpc" + "google.golang.org/grpc/health" + "google.golang.org/grpc/health/grpc_health_v1" "google.golang.org/protobuf/types/known/emptypb" ) @@ -444,7 +445,7 @@ func rootContext() context.Context { return ctx } -func grpcSentryServer(ctx context.Context, sentryAddr string, ss *SentryServerImpl) (*grpc.Server, error) { +func grpcSentryServer(ctx context.Context, sentryAddr string, ss *SentryServerImpl, healthCheck bool) (*grpc.Server, error) { // STARTING GRPC SERVER log.Info("Starting Sentry gRPC server", "on", sentryAddr) listenConfig := net.ListenConfig{ @@ -459,7 +460,16 @@ func grpcSentryServer(ctx context.Context, sentryAddr string, ss *SentryServerIm } grpcServer := grpcutil.NewServer(100, nil) proto_sentry.RegisterSentryServer(grpcServer, ss) + var healthServer *health.Server + if healthCheck { + healthServer = health.NewServer() + grpc_health_v1.RegisterHealthServer(grpcServer, healthServer) + } + go func() { + if healthCheck { + defer healthServer.Shutdown() + } if err1 := grpcServer.Serve(lis); err1 != nil { log.Error("Sentry gRPC server fail", "err", err1) } @@ -537,15 +547,15 @@ func NewSentryServer(ctx context.Context, dialCandidates enode.Iterator, readNod } // Sentry creates and runs standalone sentry -func Sentry(datadir string, sentryAddr string, discoveryDNS []string, cfg *p2p.Config, protocolVersion uint) error { - if err := os.MkdirAll(path.Join(datadir, "erigon"), 0744); err != nil { +func Sentry(datadir string, sentryAddr string, discoveryDNS []string, cfg *p2p.Config, protocolVersion uint, healthCheck bool) error { + if err := os.MkdirAll(datadir, 0744); err != nil { return fmt.Errorf("could not create dir: %s, %w", datadir, err) } ctx := rootContext() sentryServer := NewSentryServer(ctx, nil, func() *eth.NodeInfo { return nil }, cfg, protocolVersion) sentryServer.discoveryDNS = discoveryDNS - grpcServer, err := grpcSentryServer(ctx, sentryAddr, sentryServer) + grpcServer, err := grpcSentryServer(ctx, sentryAddr, sentryServer, healthCheck) if err != nil { return err } diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index ba76ea39a7c..8a020e226ea 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -538,6 +538,11 @@ var ( Usage: "a path to clique db folder", Value: "", } + + HealthCheckFlag = cli.BoolFlag{ + Name: "healthcheck", + Usage: "Enabling grpc health check", + } ) var MetricFlags = []cli.Flag{MetricsEnabledFlag, MetricsEnabledExpensiveFlag, MetricsHTTPFlag, MetricsPortFlag} diff --git a/eth/backend.go b/eth/backend.go index 9ba4fd6b27c..8bdc6370cff 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -404,7 +404,8 @@ func New(stack *node.Node, config *ethconfig.Config, logger log.Logger) (*Ethere miningRPC, stack.Config().PrivateApiAddr, stack.Config().PrivateApiRateLimit, - creds) + creds, + stack.Config().HealthCheck) if err != nil { return nil, err } diff --git a/ethdb/privateapi/all.go b/ethdb/privateapi/all.go index 93e231faf31..fe7ce6479e2 100644 --- a/ethdb/privateapi/all.go +++ b/ethdb/privateapi/all.go @@ -6,15 +6,20 @@ import ( "github.com/ledgerwatch/erigon-lib/gointerfaces/grpcutil" "github.com/ledgerwatch/erigon-lib/kv/remotedbserver" + //grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "github.com/ledgerwatch/erigon-lib/gointerfaces/remote" txpool_proto "github.com/ledgerwatch/erigon-lib/gointerfaces/txpool" "github.com/ledgerwatch/log/v3" "google.golang.org/grpc" "google.golang.org/grpc/credentials" + "google.golang.org/grpc/health" + "google.golang.org/grpc/health/grpc_health_v1" ) -func StartGrpc(kv *remotedbserver.KvServer, ethBackendSrv *EthBackendServer, txPoolServer txpool_proto.TxpoolServer, miningServer txpool_proto.MiningServer, addr string, rateLimit uint32, creds credentials.TransportCredentials) (*grpc.Server, error) { +func StartGrpc(kv *remotedbserver.KvServer, ethBackendSrv *EthBackendServer, txPoolServer txpool_proto.TxpoolServer, + miningServer txpool_proto.MiningServer, addr string, rateLimit uint32, creds credentials.TransportCredentials, + healthCheck bool) (*grpc.Server, error) { log.Info("Starting private RPC server", "on", addr) lis, err := net.Listen("tcp", addr) if err != nil { @@ -30,8 +35,15 @@ func StartGrpc(kv *remotedbserver.KvServer, ethBackendSrv *EthBackendServer, txP txpool_proto.RegisterMiningServer(grpcServer, miningServer) } remote.RegisterKVServer(grpcServer, kv) - + var healthServer *health.Server + if healthCheck { + healthServer = health.NewServer() + grpc_health_v1.RegisterHealthServer(grpcServer, healthServer) + } go func() { + if healthCheck { + defer healthServer.Shutdown() + } if err := grpcServer.Serve(lis); err != nil { log.Error("private RPC server fail", "err", err) } diff --git a/go.mod b/go.mod index b481e120d3b..e9125976b50 100644 --- a/go.mod +++ b/go.mod @@ -54,12 +54,12 @@ require ( github.com/valyala/fastjson v1.6.3 github.com/wcharczuk/go-chart/v2 v2.1.0 go.uber.org/atomic v1.9.0 - golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 + golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/sys v0.0.0-20211030160813-b3129d9d1021 golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac golang.org/x/tools v0.1.7 - google.golang.org/grpc v1.41.0 + google.golang.org/grpc v1.42.0 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 google.golang.org/protobuf v1.27.1 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 diff --git a/go.sum b/go.sum index 2f604bd5e26..1fea22fbc8d 100644 --- a/go.sum +++ b/go.sum @@ -212,7 +212,10 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/consensys/bavard v0.1.8-0.20210329205436-c3e862ba4e5f/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= github.com/consensys/gnark-crypto v0.4.0 h1:KHf7Ta876Ys6L8+i0DLRRKOAa3PfJ8oobAX1CEeIa4A= github.com/consensys/gnark-crypto v0.4.0/go.mod h1:wK/gpXP9B06qTzTVML71GhKD1ygP9xOzukbI68NJqsQ= @@ -836,8 +839,9 @@ golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 h1:/pEO3GD/ABYAjuakUS6xSEmmlyVS4kxBNkeA9tLJiTI= +golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -928,8 +932,9 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d h1:20cMwl2fHAzkJMEA+8J4JgqBQcQGzbisXo31MIeenXI= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1221,8 +1226,9 @@ google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.41.0 h1:f+PlOh7QV4iIJkPrx5NQ7qaNGFQ3OTse67yaDHfju4E= google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= +google.golang.org/grpc v1.42.0 h1:XT2/MFpuPFsEX2fWh3YQtHkZ+WYZFQRfaUgLZYj/p6A= +google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= diff --git a/node/config.go b/node/config.go index 576d3029301..d1dd53d37e3 100644 --- a/node/config.go +++ b/node/config.go @@ -160,6 +160,9 @@ type Config struct { TLSCACert string MdbxAugumentLimit uint64 + + // HealthCheck enables standard grpc health check + HealthCheck bool } // IPCEndpoint resolves an IPC endpoint based on a configured value, taking into diff --git a/node/defaults.go b/node/defaults.go index f465de20fa8..f105872cdad 100644 --- a/node/defaults.go +++ b/node/defaults.go @@ -28,6 +28,8 @@ const ( DefaultHTTPPort = 8545 // Default TCP port for the HTTP RPC server DefaultWSHost = "localhost" // Default host interface for the websocket RPC server DefaultWSPort = 8546 // Default TCP port for the websocket RPC server + DefaultGRPCHost = "localhost" // Default host interface for the GRPC server + DefaultGRPCPort = 8547 // Default TCP port for the GRPC server ) // DefaultConfig contains reasonable default settings. diff --git a/turbo/cli/default_flags.go b/turbo/cli/default_flags.go index 98d60e604fd..a8047de3286 100644 --- a/turbo/cli/default_flags.go +++ b/turbo/cli/default_flags.go @@ -84,4 +84,5 @@ var DefaultFlags = []cli.Flag{ utils.MinerNoVerfiyFlag, utils.MinerSigningKeyFileFlag, utils.SentryAddrFlag, + HealthCheckFlag, } diff --git a/turbo/cli/flags.go b/turbo/cli/flags.go index 44c0cc6514c..41a4f98b20c 100644 --- a/turbo/cli/flags.go +++ b/turbo/cli/flags.go @@ -149,6 +149,11 @@ var ( Usage: "Marks block with given hex string as bad and forces initial reorg before normal staged sync", Value: "", } + + HealthCheckFlag = cli.BoolFlag{ + Name: "healthcheck", + Usage: "Enable grpc health check", + } ) func ApplyFlagsForEthConfig(ctx *cli.Context, cfg *ethconfig.Config) { @@ -299,4 +304,5 @@ func setPrivateApi(ctx *cli.Context, cfg *node.Config) { cfg.TLSKeyFile = keyFile cfg.TLSCACert = ctx.GlobalString(TLSCACertFlag.Name) } + cfg.HealthCheck = ctx.GlobalBool(HealthCheckFlag.Name) } From 3279f9499299dacbcc852d65a9f3be28b313d24d Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sun, 12 Dec 2021 20:51:11 -0300 Subject: [PATCH 063/261] Add ots_getTransactionError API --- cmd/rpcdaemon/commands/otterscan_api.go | 46 ++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 1d2ca7daac1..e30e364c66a 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -32,7 +32,7 @@ import ( ) // API_LEVEL Must be incremented every time new additions are made -const API_LEVEL = 4 +const API_LEVEL = 5 type SearchResult struct { BlockNumber uint64 @@ -58,6 +58,7 @@ type OtterscanAPI interface { GetBlockTransactions(ctx context.Context, number rpc.BlockNumber, pageNumber uint8, pageSize uint8) (map[string]interface{}, error) HasCode(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (bool, error) TraceTransaction(ctx context.Context, hash common.Hash) ([]*otterscan.TraceEntry, error) + GetTransactionError(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) } type OtterscanAPIImpl struct { @@ -784,3 +785,46 @@ func (api *OtterscanAPIImpl) TraceTransaction(ctx context.Context, hash common.H return tracer.Results, nil } + +func (api *OtterscanAPIImpl) GetTransactionError(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) { + tx, err := api.db.BeginRo(ctx) + if err != nil { + return nil, err + } + defer tx.Rollback() + + txn, blockHash, _, txIndex, err := rawdb.ReadTransaction(tx, hash) + if err != nil { + return nil, err + } + if txn == nil { + return nil, fmt.Errorf("transaction %#x not found", hash) + } + block, err := rawdb.ReadBlockByHash(tx, blockHash) + if err != nil { + return nil, err + } + + chainConfig, err := api.chainConfig(tx) + if err != nil { + return nil, err + } + + getHeader := func(hash common.Hash, number uint64) *types.Header { + return rawdb.ReadHeader(tx, hash, number) + } + checkTEVM := ethdb.GetHasTEVM(tx) + msg, blockCtx, txCtx, ibs, _, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, checkTEVM, ethash.NewFaker(), tx, blockHash, txIndex) + if err != nil { + return nil, err + } + + vmenv := vm.NewEVM(blockCtx, txCtx, ibs, chainConfig, vm.Config{}) + + result, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), true, false /* gasBailout */) + if err != nil { + return nil, fmt.Errorf("tracing failed: %v", err) + } + + return result.Revert(), nil +} From 1fdbe22a1e1bdf5b7cbe0e04b4a51751015c0770 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Tue, 14 Dec 2021 13:31:29 +0000 Subject: [PATCH 064/261] [beta] Remove eth/65 support (#3123) * Remove eth/65 support * Clean up Co-authored-by: Alexey Sharp --- cmd/sentry/download/downloader.go | 272 +----------------------------- cmd/sentry/download/sentry.go | 25 +-- cmd/utils/flags.go | 10 -- eth/backend.go | 10 -- turbo/cli/default_flags.go | 1 - 5 files changed, 2 insertions(+), 316 deletions(-) diff --git a/cmd/sentry/download/downloader.go b/cmd/sentry/download/downloader.go index 2095d511e1c..f5dab4d50f9 100644 --- a/cmd/sentry/download/downloader.go +++ b/cmd/sentry/download/downloader.go @@ -99,9 +99,6 @@ func RecvUploadMessage(ctx context.Context, defer cancel() stream, err := sentry.Messages(streamCtx, &proto_sentry.MessagesRequest{Ids: []proto_sentry.MessageId{ - eth.ToProto[eth.ETH65][eth.GetBlockBodiesMsg], - eth.ToProto[eth.ETH65][eth.GetReceiptsMsg], - eth.ToProto[eth.ETH66][eth.GetBlockBodiesMsg], eth.ToProto[eth.ETH66][eth.GetReceiptsMsg], }}, grpc.WaitForReady(true)) @@ -194,8 +191,6 @@ func RecvUploadHeadersMessage(ctx context.Context, defer cancel() stream, err := sentry.Messages(streamCtx, &proto_sentry.MessagesRequest{Ids: []proto_sentry.MessageId{ - eth.ToProto[eth.ETH65][eth.GetBlockHeadersMsg], - eth.ToProto[eth.ETH66][eth.GetBlockHeadersMsg], }}, grpc.WaitForReady(true)) if err != nil { @@ -292,11 +287,6 @@ func RecvMessage( defer sentry.MarkDisconnected() stream, err := sentry.Messages(streamCtx, &proto_sentry.MessagesRequest{Ids: []proto_sentry.MessageId{ - eth.ToProto[eth.ETH65][eth.BlockHeadersMsg], - eth.ToProto[eth.ETH65][eth.BlockBodiesMsg], - eth.ToProto[eth.ETH65][eth.NewBlockHashesMsg], - eth.ToProto[eth.ETH65][eth.NewBlockMsg], - eth.ToProto[eth.ETH66][eth.BlockHeadersMsg], eth.ToProto[eth.ETH66][eth.BlockBodiesMsg], eth.ToProto[eth.ETH66][eth.NewBlockHashesMsg], @@ -435,48 +425,6 @@ func (cs *ControlServerImpl) newBlockHashes66(ctx context.Context, req *proto_se return nil } -func (cs *ControlServerImpl) newBlockHashes65(ctx context.Context, req *proto_sentry.InboundMessage, sentry direct.SentryClient) error { - if !cs.Hd.RequestChaining() && !cs.Hd.Fetching() { - return nil - } - //log.Info(fmt.Sprintf("NewBlockHashes from [%s]", gointerfaces.ConvertH512ToBytes(req.PeerId))) - var request eth.NewBlockHashesPacket - if err := rlp.DecodeBytes(req.Data, &request); err != nil { - return fmt.Errorf("decode newBlockHashes65: %w", err) - } - for _, announce := range request { - cs.Hd.SaveExternalAnnounce(announce.Hash) - if cs.Hd.HasLink(announce.Hash) { - continue - } - //log.Info(fmt.Sprintf("Sending header request {hash: %x, height: %d, length: %d}", announce.Hash, announce.Number, 1)) - b, err := rlp.EncodeToBytes(ð.GetBlockHeadersPacket{ - Amount: 1, - Reverse: false, - Skip: 0, - Origin: eth.HashOrNumber{Hash: announce.Hash}, - }) - if err != nil { - return fmt.Errorf("encode header request: %w", err) - } - outreq := proto_sentry.SendMessageByIdRequest{ - PeerId: req.PeerId, - Data: &proto_sentry.OutboundMessageData{ - Id: proto_sentry.MessageId_GET_BLOCK_HEADERS_65, - Data: b, - }, - } - - if _, err = sentry.SendMessageById(ctx, &outreq, &grpc.EmptyCallOption{}); err != nil { - if isPeerNotFoundErr(err) { - continue - } - return fmt.Errorf("send header request: %w", err) - } - } - return nil -} - func (cs *ControlServerImpl) blockHeaders66(ctx context.Context, in *proto_sentry.InboundMessage, sentry direct.SentryClient) error { // Extract header from the block rlpStream := rlp.NewStream(bytes.NewReader(in.Data), uint64(len(in.Data))) @@ -558,86 +506,7 @@ func (cs *ControlServerImpl) blockHeaders66(ctx context.Context, in *proto_sentr return nil } -func (cs *ControlServerImpl) blockHeaders65(ctx context.Context, in *proto_sentry.InboundMessage, sentry direct.SentryClient) error { - // Extract header from the block - rlpStream := rlp.NewStream(bytes.NewReader(in.Data), uint64(len(in.Data))) - if _, err := rlpStream.List(); err != nil { // Now stream is at the BlockHeadersPacket, which is list of headers - return fmt.Errorf("decode 3 BlockHeadersPacket66: %w", err) - } - var headersRaw [][]byte - for headerRaw, err := rlpStream.Raw(); ; headerRaw, err = rlpStream.Raw() { - if err != nil { - if !errors.Is(err, rlp.EOL) { - return fmt.Errorf("decode 4 BlockHeadersPacket66: %w", err) - } - break - } - - headersRaw = append(headersRaw, headerRaw) - } - - // Parse the entire request from scratch - var request eth.BlockHeadersPacket - if err := rlp.DecodeBytes(in.Data, &request); err != nil { - return fmt.Errorf("decode 5 BlockHeadersPacket66: %w", err) - } - headers := request - var heighestBlock uint64 - for _, h := range headers { - if h.Number.Uint64() > heighestBlock { - heighestBlock = h.Number.Uint64() - } - } - - if segments, penalty, err := cs.Hd.SplitIntoSegments(headersRaw, headers); err == nil { - if penalty == headerdownload.NoPenalty { - var canRequestMore bool - for _, segment := range segments { - requestMore, penalties := cs.Hd.ProcessSegment(segment, false /* newBlock */, string(gointerfaces.ConvertH512ToBytes(in.PeerId))) - canRequestMore = canRequestMore || requestMore - if len(penalties) > 0 { - cs.Penalize(ctx, penalties) - } - } - - if canRequestMore { - currentTime := uint64(time.Now().Unix()) - req, penalties := cs.Hd.RequestMoreHeaders(currentTime) - if req != nil { - if peer := cs.SendHeaderRequest(ctx, req); peer != nil { - cs.Hd.SentRequest(req, currentTime, 5 /* timeout */) - log.Trace("Sent request", "height", req.Number) - } - } - cs.Penalize(ctx, penalties) - } - } else { - outreq := proto_sentry.PenalizePeerRequest{ - PeerId: in.PeerId, - Penalty: proto_sentry.PenaltyKind_Kick, // TODO: Extend penalty kinds - } - if _, err1 := sentry.PenalizePeer(ctx, &outreq, &grpc.EmptyCallOption{}); err1 != nil { - log.Error("Could not send penalty", "err", err1) - } - } - } else { - return fmt.Errorf("singleHeaderAsSegment failed: %w", err) - } - outreq := proto_sentry.PeerMinBlockRequest{ - PeerId: in.PeerId, - MinBlock: heighestBlock, - } - if _, err1 := sentry.PeerMinBlock(ctx, &outreq, &grpc.EmptyCallOption{}); err1 != nil { - log.Error("Could not send min block for peer", "err", err1) - } - return nil -} - func (cs *ControlServerImpl) newBlock66(ctx context.Context, inreq *proto_sentry.InboundMessage, sentry direct.SentryClient) error { - return cs.newBlock65(ctx, inreq, sentry) -} - -func (cs *ControlServerImpl) newBlock65(ctx context.Context, inreq *proto_sentry.InboundMessage, sentry direct.SentryClient) error { // Extract header from the block rlpStream := rlp.NewStream(bytes.NewReader(inreq.Data), uint64(len(inreq.Data))) _, err := rlpStream.List() // Now stream is at the beginning of the block record @@ -699,22 +568,9 @@ func (cs *ControlServerImpl) blockBodies66(inreq *proto_sentry.InboundMessage, s return nil } -func (cs *ControlServerImpl) blockBodies65(inreq *proto_sentry.InboundMessage, sentry direct.SentryClient) error { - var request eth.BlockRawBodiesPacket - if err := rlp.DecodeBytes(inreq.Data, &request); err != nil { - return fmt.Errorf("decode blockBodies65: %w", err) - } - txs, uncles := request.Unpack() - cs.Bd.DeliverBodies(txs, uncles, uint64(len(inreq.Data)), string(gointerfaces.ConvertH512ToBytes(inreq.PeerId))) - return nil -} - func (cs *ControlServerImpl) receipts66(ctx context.Context, inreq *proto_sentry.InboundMessage, sentry direct.SentryClient) error { return nil } -func (cs *ControlServerImpl) receipts65(ctx context.Context, inreq *proto_sentry.InboundMessage, sentry direct.SentryClient) error { - return nil -} func (cs *ControlServerImpl) getBlockHeaders66(ctx context.Context, inreq *proto_sentry.InboundMessage, sentry direct.SentryClient) error { var query eth.GetBlockHeadersPacket66 @@ -749,7 +605,7 @@ func (cs *ControlServerImpl) getBlockHeaders66(ctx context.Context, inreq *proto _, err = sentry.SendMessageById(ctx, &outreq, &grpc.EmptyCallOption{}) if err != nil { if !isPeerNotFoundErr(err) { - return fmt.Errorf("send header response 65: %w", err) + return fmt.Errorf("send header response 66: %w", err) } return fmt.Errorf("send header response 66: %w", err) } @@ -757,43 +613,6 @@ func (cs *ControlServerImpl) getBlockHeaders66(ctx context.Context, inreq *proto return nil } -func (cs *ControlServerImpl) getBlockHeaders65(ctx context.Context, inreq *proto_sentry.InboundMessage, sentry direct.SentryClient) error { - var query eth.GetBlockHeadersPacket - if err := rlp.DecodeBytes(inreq.Data, &query); err != nil { - return fmt.Errorf("decoding getBlockHeaders65: %w, data: %x", err, inreq.Data) - } - - var headers []*types.Header - if err := cs.db.View(ctx, func(tx kv.Tx) (err error) { - headers, err = eth.AnswerGetBlockHeadersQuery(tx, &query) - if err != nil { - return err - } - return nil - }); err != nil { - return fmt.Errorf("querying BlockHeaders: %w", err) - } - b, err := rlp.EncodeToBytes(eth.BlockHeadersPacket(headers)) - if err != nil { - return fmt.Errorf("encode header response: %w", err) - } - outreq := proto_sentry.SendMessageByIdRequest{ - PeerId: inreq.PeerId, - Data: &proto_sentry.OutboundMessageData{ - Id: proto_sentry.MessageId_BLOCK_HEADERS_65, - Data: b, - }, - } - _, err = sentry.SendMessageById(ctx, &outreq, &grpc.EmptyCallOption{}) - if err != nil { - if !isPeerNotFoundErr(err) { - return fmt.Errorf("send header response 65: %w", err) - } - } - //log.Info(fmt.Sprintf("[%s] GetBlockHeaderMsg{hash=%x, number=%d, amount=%d, skip=%d, reverse=%t, responseLen=%d}", string(gointerfaces.ConvertH512ToBytes(inreq.PeerId)), query.Origin.Hash, query.Origin.Number, query.Amount, query.Skip, query.Reverse, len(b))) - return nil -} - func (cs *ControlServerImpl) getBlockBodies66(ctx context.Context, inreq *proto_sentry.InboundMessage, sentry direct.SentryClient) error { var query eth.GetBlockBodiesPacket66 if err := rlp.DecodeBytes(inreq.Data, &query); err != nil { @@ -831,40 +650,6 @@ func (cs *ControlServerImpl) getBlockBodies66(ctx context.Context, inreq *proto_ return nil } -func (cs *ControlServerImpl) getBlockBodies65(ctx context.Context, inreq *proto_sentry.InboundMessage, sentry direct.SentryClient) error { - var query eth.GetBlockBodiesPacket - if err := rlp.DecodeBytes(inreq.Data, &query); err != nil { - return fmt.Errorf("decoding getBlockBodies65: %w, data: %x", err, inreq.Data) - } - tx, err := cs.db.BeginRo(ctx) - if err != nil { - return err - } - defer tx.Rollback() - response := eth.AnswerGetBlockBodiesQuery(tx, query) - tx.Rollback() - b, err := rlp.EncodeToBytes(eth.BlockBodiesRLPPacket(response)) - if err != nil { - return fmt.Errorf("encode header response: %w", err) - } - outreq := proto_sentry.SendMessageByIdRequest{ - PeerId: inreq.PeerId, - Data: &proto_sentry.OutboundMessageData{ - Id: proto_sentry.MessageId_BLOCK_BODIES_65, - Data: b, - }, - } - _, err = sentry.SendMessageById(ctx, &outreq, &grpc.EmptyCallOption{}) - if err != nil { - if isPeerNotFoundErr(err) { - return nil - } - return fmt.Errorf("send bodies response: %w", err) - } - //log.Info(fmt.Sprintf("[%s] GetBlockBodiesMsg responseLen %d", string(gointerfaces.ConvertH512ToBytes(inreq.PeerId)), len(b))) - return nil -} - func (cs *ControlServerImpl) getReceipts66(ctx context.Context, inreq *proto_sentry.InboundMessage, sentry direct.SentryClient) error { var query eth.GetReceiptsPacket66 if err := rlp.DecodeBytes(inreq.Data, &query); err != nil { @@ -905,63 +690,8 @@ func (cs *ControlServerImpl) getReceipts66(ctx context.Context, inreq *proto_sen return nil } -func (cs *ControlServerImpl) getReceipts65(ctx context.Context, inreq *proto_sentry.InboundMessage, sentry direct.SentryClient) error { - var query eth.GetReceiptsPacket - if err := rlp.DecodeBytes(inreq.Data, &query); err != nil { - return fmt.Errorf("decoding getReceipts65: %w, data: %x", err, inreq.Data) - } - tx, err := cs.db.BeginRo(ctx) - if err != nil { - return err - } - defer tx.Rollback() - receipts, err := eth.AnswerGetReceiptsQuery(tx, query) - if err != nil { - return err - } - tx.Rollback() - b, err := rlp.EncodeToBytes(eth.ReceiptsRLPPacket(receipts)) - if err != nil { - return fmt.Errorf("encode header response: %w", err) - } - outreq := proto_sentry.SendMessageByIdRequest{ - PeerId: inreq.PeerId, - Data: &proto_sentry.OutboundMessageData{ - Id: proto_sentry.MessageId_RECEIPTS_66, - Data: b, - }, - } - _, err = sentry.SendMessageById(ctx, &outreq, &grpc.EmptyCallOption{}) - if err != nil { - if isPeerNotFoundErr(err) { - return nil - } - return fmt.Errorf("send bodies response: %w", err) - } - //log.Info(fmt.Sprintf("[%s] GetReceipts responseLen %d", string(gointerfaces.ConvertH512ToBytes(inreq.PeerId)), len(b))) - return nil -} - func (cs *ControlServerImpl) HandleInboundMessage(ctx context.Context, inreq *proto_sentry.InboundMessage, sentry direct.SentryClient) error { switch inreq.Id { - // ========= eth 65 ========== - case proto_sentry.MessageId_GET_BLOCK_HEADERS_65: - return cs.getBlockHeaders65(ctx, inreq, sentry) - case proto_sentry.MessageId_BLOCK_HEADERS_65: - return cs.blockHeaders65(ctx, inreq, sentry) - case proto_sentry.MessageId_NEW_BLOCK_65: - return cs.newBlock65(ctx, inreq, sentry) - case proto_sentry.MessageId_GET_BLOCK_BODIES_65: - return cs.getBlockBodies65(ctx, inreq, sentry) - case proto_sentry.MessageId_BLOCK_BODIES_65: - return cs.blockBodies65(inreq, sentry) - case proto_sentry.MessageId_GET_RECEIPTS_65: - return cs.getReceipts65(ctx, inreq, sentry) - case proto_sentry.MessageId_RECEIPTS_65: - return cs.receipts65(ctx, inreq, sentry) - case proto_sentry.MessageId_NEW_BLOCK_HASHES_65: - return cs.newBlockHashes65(ctx, inreq, sentry) - // transactions-related methods are in tx-pool server // ========= eth 66 ========== diff --git a/cmd/sentry/download/sentry.go b/cmd/sentry/download/sentry.go index 75a9684e266..6e93c1d4592 100644 --- a/cmd/sentry/download/sentry.go +++ b/cmd/sentry/download/sentry.go @@ -484,7 +484,7 @@ func NewSentryServer(ctx context.Context, dialCandidates enode.Iterator, readNod peersStreams: NewPeersStreams(), } - if protocol != eth.ETH65 && protocol != eth.ETH66 { + if protocol != eth.ETH66 { panic(fmt.Errorf("unexpected p2p protocol: %d", protocol)) } @@ -625,27 +625,6 @@ func (ss *SentryServerImpl) writePeer(peerID string, peerInfo *PeerInfo, msgcode func (ss *SentryServerImpl) startSync(ctx context.Context, bestHash common.Hash, peerID string) error { switch ss.Protocol.Version { - case eth.ETH65: - b, err := rlp.EncodeToBytes(ð.GetBlockHeadersPacket{ - Amount: 1, - Reverse: false, - Skip: 0, - Origin: eth.HashOrNumber{Hash: bestHash}, - }) - if err != nil { - return fmt.Errorf("startSync encode packet failed: %w", err) - } - - if _, err := ss.SendMessageById(ctx, &proto_sentry.SendMessageByIdRequest{ - PeerId: gointerfaces.ConvertBytesToH512([]byte(peerID)), - Data: &proto_sentry.OutboundMessageData{ - Id: proto_sentry.MessageId_GET_BLOCK_HEADERS_65, - Data: b, - }, - }); err != nil { - return err - } - case eth.ETH66: b, err := rlp.EncodeToBytes(ð.GetBlockHeadersPacket66{ RequestId: rand.Uint64(), @@ -821,8 +800,6 @@ func (ss *SentryServerImpl) HandShake(context.Context, *emptypb.Empty) (*proto_s switch ss.Protocol.Version { case eth.ETH66: reply.Protocol = proto_sentry.Protocol_ETH66 - case eth.ETH65: - reply.Protocol = proto_sentry.Protocol_ETH65 } return reply, nil } diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 8a020e226ea..1dc41ef948d 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -408,11 +408,6 @@ var ( Usage: "Network listening port", Value: 30303, } - ListenPort65Flag = cli.IntFlag{ - Name: "p2p.eth65.port", - Usage: "ETH65 Network listening port", - Value: 30304, - } SentryAddrFlag = cli.StringFlag{ Name: "sentry.api.addr", Usage: "comma separated sentry addresses ':,:'", @@ -704,8 +699,6 @@ func appendUrlListNodes(nodes []*enode.Node, urls []string, nodeType string, log func NewP2PConfig(nodiscover bool, datadir, netRestrict, natSetting, nodeName string, staticPeers []string, trustedPeers []string, port, protocol uint) (*p2p.Config, error) { var enodeDBPath string switch protocol { - case eth.ETH65: - enodeDBPath = path.Join(datadir, "nodes", "eth65") case eth.ETH66: enodeDBPath = path.Join(datadir, "nodes", "eth66") default: @@ -773,9 +766,6 @@ func setListenAddress(ctx *cli.Context, cfg *p2p.Config) { if ctx.GlobalIsSet(ListenPortFlag.Name) { cfg.ListenAddr = fmt.Sprintf(":%d", ctx.GlobalInt(ListenPortFlag.Name)) } - if ctx.GlobalIsSet(ListenPort65Flag.Name) { - cfg.ListenAddr65 = fmt.Sprintf(":%d", ctx.GlobalInt(ListenPort65Flag.Name)) - } if ctx.GlobalIsSet(SentryAddrFlag.Name) { cfg.SentryAddr = SplitAndTrim(ctx.GlobalString(SentryAddrFlag.Name)) } diff --git a/eth/backend.go b/eth/backend.go index 8bdc6370cff..fcdaca48bc4 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -285,16 +285,6 @@ func New(stack *node.Node, config *ethconfig.Config, logger log.Logger) (*Ethere server66 := download.NewSentryServer(backend.downloadCtx, d66, readNodeInfo, &cfg66, eth.ETH66) backend.sentryServers = append(backend.sentryServers, server66) backend.sentries = []direct.SentryClient{direct.NewSentryClientDirect(eth.ETH66, server66)} - cfg65 := stack.Config().P2P - cfg65.NodeDatabase = path.Join(stack.Config().DataDir, "nodes", "eth65") - d65, err := setupDiscovery(backend.config.EthDiscoveryURLs) - if err != nil { - return nil, err - } - cfg65.ListenAddr = cfg65.ListenAddr65 - server65 := download.NewSentryServer(backend.downloadCtx, d65, readNodeInfo, &cfg65, eth.ETH65) - backend.sentryServers = append(backend.sentryServers, server65) - backend.sentries = append(backend.sentries, direct.NewSentryClientDirect(eth.ETH65, server65)) go func() { logEvery := time.NewTicker(120 * time.Second) defer logEvery.Stop() diff --git a/turbo/cli/default_flags.go b/turbo/cli/default_flags.go index a8047de3286..1f49c371595 100644 --- a/turbo/cli/default_flags.go +++ b/turbo/cli/default_flags.go @@ -47,7 +47,6 @@ var DefaultFlags = []cli.Flag{ SyncLoopThrottleFlag, BadBlockFlag, utils.ListenPortFlag, - utils.ListenPort65Flag, utils.NATFlag, utils.NoDiscoverFlag, utils.DiscoveryV5Flag, From a926bc0239322307f6b328e0fc64a549352c772a Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Tue, 14 Dec 2021 15:16:39 -0300 Subject: [PATCH 065/261] Fix calling ots_hasCode for uninitialized accounts --- cmd/rpcdaemon/commands/otterscan_api.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index e30e364c66a..454490b0bb8 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -737,7 +737,7 @@ func (api *OtterscanAPIImpl) HasCode(ctx context.Context, address common.Address reader := adapter.NewStateReader(tx, blockNumber) acc, err := reader.ReadAccountData(address) - if err != nil { + if acc == nil || err != nil { return false, err } return !acc.IsEmptyCodeHash(), nil From 73c5090497b3b8b7c9cdfbc8f0bc1d5daff73d75 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Wed, 15 Dec 2021 08:18:43 +0000 Subject: [PATCH 066/261] [beta] Txpool tracing by sender addresses (#3127) * Txpool tracing by sender addresses (#3113) * Txpool tracing by sender addresses * Update to latest erigon-lib Co-authored-by: Alexey Sharp * Switch to correct erigon-lib * Repoint erigon-lib Co-authored-by: Alexey Sharp --- cmd/utils/flags.go | 14 ++++++++++++++ core/tx_pool.go | 5 +++-- eth/backend.go | 1 + go.mod | 2 +- go.sum | 4 ++-- turbo/cli/default_flags.go | 1 + 6 files changed, 22 insertions(+), 5 deletions(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 1dc41ef948d..6096a502215 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -214,6 +214,11 @@ var ( Usage: "Maximum amount of time non-executable transaction are queued", Value: ethconfig.Defaults.TxPool.Lifetime, } + TxPoolTraceSendersFlag = cli.StringFlag{ + Name: "txpool.trace.senders", + Usage: "Comma separared list of addresses, whoes transactions will traced in transaction pool with debug printing", + Value: "", + } // Miner settings MiningEnabledFlag = cli.BoolFlag{ Name: "mine", @@ -1020,6 +1025,15 @@ func setTxPool(ctx *cli.Context, cfg *core.TxPoolConfig) { if ctx.GlobalIsSet(TxPoolLifetimeFlag.Name) { cfg.Lifetime = ctx.GlobalDuration(TxPoolLifetimeFlag.Name) } + if ctx.GlobalIsSet(TxPoolTraceSendersFlag.Name) { + // Parse the command separated flag + senderHexes := SplitAndTrim(ctx.GlobalString(TxPoolTraceSendersFlag.Name)) + cfg.TracedSenders = make([]string, len(senderHexes)) + for i, senderHex := range senderHexes { + sender := common.HexToAddress(senderHex) + cfg.TracedSenders[i] = string(sender[:]) + } + } } func setEthash(ctx *cli.Context, datadir string, cfg *ethconfig.Config) { diff --git a/core/tx_pool.go b/core/tx_pool.go index 809c9fe1472..4517cf0c5a4 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -152,8 +152,9 @@ type TxPoolConfig struct { GlobalBaseFeeQueue uint64 // Maximum number of non-executable transaction slots for all accounts - Lifetime time.Duration // Maximum amount of time non-executable transaction are queued - StartOnInit bool + Lifetime time.Duration // Maximum amount of time non-executable transaction are queued + StartOnInit bool + TracedSenders []string // List of senders for which tx pool should print out debugging info } // DefaultTxPoolConfig contains the default configurations for the transaction diff --git a/eth/backend.go b/eth/backend.go index fcdaca48bc4..f5ce41ea819 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -324,6 +324,7 @@ func New(stack *node.Node, config *ethconfig.Config, logger log.Logger) (*Ethere cfg.AccountSlots = config.TxPool.AccountSlots cfg.LogEvery = 1 * time.Minute cfg.CommitEvery = 5 * time.Minute + cfg.TracedSenders = config.TxPool.TracedSenders //cacheConfig := kvcache.DefaultCoherentCacheConfig //cacheConfig.MetricsLabel = "txpool" diff --git a/go.mod b/go.mod index e9125976b50..98018e092b4 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20211206151611-8f75c77e6cea + github.com/ledgerwatch/erigon-lib v0.0.0-20211214172614-e03a1f6fe9ce github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 diff --git a/go.sum b/go.sum index 1fea22fbc8d..d2e47a59532 100644 --- a/go.sum +++ b/go.sum @@ -500,8 +500,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20211206151611-8f75c77e6cea h1:4Eqqqq1tm3PVWb8frJ2fIPESaQ08PPyPgbUZg3w2uF8= -github.com/ledgerwatch/erigon-lib v0.0.0-20211206151611-8f75c77e6cea/go.mod h1:lyGP3i0x4CeabdKZ4beycD5xZfHWZwJsAX+70OfGj4Y= +github.com/ledgerwatch/erigon-lib v0.0.0-20211214172614-e03a1f6fe9ce h1:l90jhkwhNKl6FhSLrlDeODt1LL+DZzujX7Oy3Gs/1sw= +github.com/ledgerwatch/erigon-lib v0.0.0-20211214172614-e03a1f6fe9ce/go.mod h1:lyGP3i0x4CeabdKZ4beycD5xZfHWZwJsAX+70OfGj4Y= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= diff --git a/turbo/cli/default_flags.go b/turbo/cli/default_flags.go index 1f49c371595..0923d41f58a 100644 --- a/turbo/cli/default_flags.go +++ b/turbo/cli/default_flags.go @@ -24,6 +24,7 @@ var DefaultFlags = []cli.Flag{ utils.TxPoolAccountQueueFlag, utils.TxPoolGlobalQueueFlag, utils.TxPoolLifetimeFlag, + utils.TxPoolTraceSendersFlag, PruneFlag, PruneHistoryFlag, PruneReceiptFlag, From 73a290a7a89933024db17b4f0c3680f2660056a9 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Wed, 15 Dec 2021 08:18:53 +0000 Subject: [PATCH 067/261] [beta] Skip analysis and preverified hashes (#3129) Co-authored-by: Alexey Sharp --- core/skip_analysis.go | 2 +- .../preverified_hashes_mainnet.go | 279 ++++++++++++++++- .../preverified_hashes_ropsten.go | 296 +++++++++++++++++- 3 files changed, 574 insertions(+), 3 deletions(-) diff --git a/core/skip_analysis.go b/core/skip_analysis.go index cc16d4bc08e..2b77b95eeec 100644 --- a/core/skip_analysis.go +++ b/core/skip_analysis.go @@ -21,7 +21,7 @@ import ( ) // MainnetNotCheckedFrom is the first block number not yet checked for invalid jumps -const MainnetNotCheckedFrom uint64 = 13751500 +const MainnetNotCheckedFrom uint64 = 13804600 // SkipAnalysis function tells us whether we can skip performing jumpdest analysis // for the historical blocks (on mainnet now but perhaps on the testsnets diff --git a/turbo/stages/headerdownload/preverified_hashes_mainnet.go b/turbo/stages/headerdownload/preverified_hashes_mainnet.go index 0411b64d042..a978ceea467 100644 --- a/turbo/stages/headerdownload/preverified_hashes_mainnet.go +++ b/turbo/stages/headerdownload/preverified_hashes_mainnet.go @@ -71624,6 +71624,283 @@ var mainnetPreverifiedHashes = []string{ "acb808cdc6bf7a5999c7d0a27d732d9b55d71d4db3a8639c10073465223e7e9c", "c75c78757c9fd389e54afc1f5d13199cebe6371c4d632bcba4c10cfe6114669c", "5af35c9d402461dec054c9b9cbb97591224f1c23b4557186f065fc84ee70968f", + "29d289abbdbf86e2518051dda610e0a4af6c817106900004c93d25efbd193def", + "35d5ba7a467a71ca5ca0d54d953027cddd04546601d7c69452c8b81785acfff5", + "3a18cb84913339e5aeff177bd70c7a7cbb8f67751bc08ac5fcdd91301cbf0ad0", + "9bd01f44e2cb4c23990fc08b4bf0c2c34ac42feb30d018a597d85cdd71d5d9a0", + "492881f4323809b0ddf303b03a258e4a9793a22f58bfd5d674efa0ed4c505c09", + "6c8f1aae92271c5f87eb50bfe1a5d75d408d4b0550bb30d0b1368bf586830b75", + "6d3d394ef2b8f6b5159d88972902aaa671995495b9714a98f93313de0a4d91ba", + "e01ca653a62daf7168ed438536e37ff458d378a4d5fd7887e1e62370e98311b6", + "e58465cf6923a864cff1538d951a8575413c0d9b4cfd17cbbe0d5993b784df01", + "c82aedfc4bf42aca07dbe522b0b9ed79e5f3f9c08bcb746d2d671443a545b96d", + "040b665bef7336a238c7a5931e9d2b2434a1b4a758e7d626954d53f05adb2c23", + "5ee46fb45cbf07c5af6ad68cb0e5bbf219759e8b9fdc10820902421e5e29ed94", + "2a15ae966fc7e73a0ef27d8ca7b791a630689d2b4fed3bdb81eec631bcf58531", + "ab0b4ce5d95f1c2f74087ccda63f9a9054dbcb6d1ccdb7eefa1f1c938de11db3", + "c94a3c1aaf95751ae41053d0716083ef646b9f4a533981b4673aca6aa641bf70", + "fbc1c559a20c6ec2b5744edbf87ec062d805d6b5d3b3a606fa749d0d90a283be", + "0f68d099187177c9e9f10bfb3a99e010cc4faa385310777f6e0fc40e4757e8d1", + "8e25fbcc83cbbc326426bb014c9d160e3c9013dffbbcf4629a1bcfe13f0b93a4", + "2343469634d4f62e3ca8df6b2d92ab18cfe9b89cb009349723bee7413d29780f", + "ec1fd2ef8df95c89af05d069b6e62fc4b9147414c2df3b999edce2d316504de5", + "f05cd0aa53a1798ececea961da72f6e29cae5d48e1bf6c1dcad15cbe3c46047e", + "ec273fd77a6e7ef5bbb2879a2ce05f89286dfea3180a9d543c80be524d3891c8", + "92978a8a27b170ab9e172f2dc6a5f20ea24f0400f39931ba593be6b11ab860a6", + "a1b88b50aedd07622acdfb47f07bea547ae169bc9f6db493d733bebb380a08c1", + "75c30569dcb6ed87b2c796fea516f0b8be536fc964c4c96eb00df4a393408c6f", + "762e880c9583b3a82e5d5ca0b3236b9a6b7dbbefeb6cb48c4bb4f35d0bad1cbf", + "94b1593e3bec738ed9fb86cfcd0e66e9cecf773e333a244a97eb7aa151e2f221", + "466cd50d4a477b40d145d814c07e6f70bdc24f9c815757434b14357cf406e4c6", + "da79545e91284cd42d9f43f2d65f4c8a2ebf09c150d217eae2a673127d1430f3", + "789316820c35c5738fd58ec5818cf6ee0546fc90cd2810162fb719bb08851c28", + "6183c2a47b7c18add29d32ebff51bb661196d96747e9cc6f49bd0f130cccc933", + "5e900c50dc4f1cba35c26cc1928ea7a226ca52d46a7b8b97bacdc55cf995ee0a", + "1fca78f8a6c5ab693fb80aeb5bfa3386a9b14cebb5f7862f07e680e94e04aa1b", + "863e3a81da5618be6795e09cd50ce53a03394c0ae735bb49f92f3c2f789cf81e", + "087e8190353ad5a9a79cded27ac67c5e744df54de4b32e23bc27d0bc56df9519", + "6ead97dc1695be80b352c41afa879e89947f6d6f35efdcf39b31b275abb97d6b", + "b2da59a27c3e21a0142ab27f2b5b17bed1a43a370f840728113dc2b46bd3728a", + "5775a8ee8048ed247a7894978f44a24ddb2651288fa4abb99fcd1dd57f7f5061", + "c0d9f4cb849f2f17b8950247421e39f93e8addea7da2c72628499f7245147868", + "43be0ec1f4a41b1a63afbb0def2bdafb0bc8b2a2a022008f6bd6e3ce8623f807", + "5f63947f596222e3f246d5029298cc2b84b8ea7ef7862c89c1dd58ab0fc22558", + "6d09b6a591c1d6161b01ca55a5b93322bcc409a6a28e7b10d9fa08daa733ac8c", + "01fd61ab86e3e988794f7339d68e9ff3712e9e532101ed5191ed042203a48822", + "1a50fc71a616e001e8c1d37f8bf434abfa6700ca63dd63214c81e5e2b77d9cfc", + "288a1b19fea12c0f5e265bc4f252e73ca6197722262163ac506ca98a6c1ef5ae", + "8a7ff2d303884169927994ad1842dd96c5286f67aa169d1d8cae95b7cb3c6c77", + "7b33dbc458001b4f67026ac942f5f88bf749e2fc192ffc7e266109ef9d3af9f8", + "a7e36f83bcf2d254fbeb85f6d1092d6b53af8495a3fa15c101404d9f5c7a32ea", + "3ed9f6acf60ae162c6946af2e0508a3d4fbdfae96fa2aa1edbf5ed526d644eef", + "2ae49275e13e780f1d29aea8507b2a708ff7bfe977efac93e050273b8b3a8164", + "bc0ebc3514ec0223d213072048a3e8bcfdd3a7afbe19f334b8b9f03e7bdf747a", + "ea921e9f4638fa89930a75f78be68f3d9ef87378138980c5ebe7b4e473e04809", + "cf5039f70c2ffb46b0c9439e3ff63bbd03e51cde95d8df2fecaad6a0890cc2ba", + "e1fb7d4412b686cbc7711ec96dc4e8135e279bc017d505c56ddfa4d501e7e262", + "49aac04da80295142a3e32a340186377dc3248f0ddd28caba54bbe488ff4b807", + "0ed7aa3c234915f7ff0847a41cde55445e3bc3e25b3f7a1b9e9e4d0b1529116d", + "04bd76133221193b9c48e4f35faa3a135752bf5cd15a492301e875f6bf700ddd", + "0b7bcfb37d502f8fe1eb1e2810e7ff7a38e986f14171dfb1999658f61bd91640", + "cda9eeb30670e63ebb608a318616b738df888726058f723ecfc01cb8554252c3", + "8fc9617c0fbfde772860ed73e4921df544a0e9eadb228032ee09ef64098cee4c", + "d9e0974d8eed9c73d05a6f5bbe1f767f91a8d6f5f3dfb2ca28ae430a39bdd499", + "a9f3f21c6d335789dd1662665dc2ac7656f1d590081aaea205ae44f0d9b1f132", + "996bfd35caf53d35fc6b69ee46e705040b2044668955155d9390a3fca47dafdb", + "72cab7dd27e417af58e2ee6d3e233b33f8cc0e25ef007d8004edeecda9014614", + "388c7a9d70098aa1707765e1b0856fc5467a4953d90a2a9b06fbd73fc077b578", + "415dc512e7a703477a22adb841b2b636aa078ef6dcd7cd7281c25996e5f0298f", + "37b7230bb0ad5a025e2adec7ca25dfe64026e2d3f7d22d0d86205588cfa3bdd2", + "007296c717158b9d079dc711332256324bb80ba6338dbd70686a67ab0aa1dc0d", + "7151f054968b2806c28a32a98033c4abaea34d29c1c74c8723fa94b84b1d7ac4", + "e4a116856980ee83c4628c3515a4c6e8ab28d98e90f7ad05bfe5203d888361fc", + "e899901865547facbd3cadffa8e66b55d8279440520417f4e948970404d6a101", + "77a6c0b27e726b957d8542ae503956e43d9069f6233998661fbc2893095b7450", + "9fec5f6dcd1e8ad64ef4a7b49e7e6e26efdd79c234b9ab48a9d302dc284f4006", + "fa95a7c1b11236a3c2a906624678a4ec6d51f1a527b9c51f40e35646208f8008", + "1eb6e86f5a611fafc1e5c12a65ac796f603f1e064caf73443ffcf07ff9104d0c", + "dd1a1629a1d6dc955f52ca9d9e3ab4b95a5652afbbf71d40eb9cc1bb0e04ebac", + "2b56d3ed2af428abe4ade1c183d88156abf34f65c5314a00f59a99e2b77d2028", + "1777c62ea5b86e3c4435723219e0a1635526fbcc2d88d3ce3fa0af4f1132798c", + "a452307fe67a3b6beb3130035bf9a0774349b9400355e119350f7847059c6d6b", + "a1dced705891c5a08eb957c289613e964a98a10c5db887f0b092af548e28f120", + "307fc98745cb0af49fa3cd43582927228cfde5efcedf36113054d91f1e663e0c", + "0945868dd11a00ef2e13b2bd62197fef23f784b2456eb5a7086c27dabd0acfda", + "eb24b9242d2a543fa963bf6664f7cf0587de9bb2698230b9c3dc79c7d6fe30c7", + "aebb7c6330c2ad5a0a676cec970ae754fa53941f72b5a54961171944fd1e5e5e", + "bc493caca682217bad0801c952aea37ddcf7a7890eddba427060cbda12dee5a6", + "3b1658844979a4e535b9a3a5e03a17187fa6e97997251f58e6d7520ff71f16aa", + "5e946cb108ad41fab2dcab607ca9e7c8566f2e599c32f02bda88113d6d45e1ce", + "ac3aa3b8de8e0c559308a0e5a869b4db2b97b16cecd102a18da09db091559324", + "64871d1f4ffae6f3d72150893ea707f560d8fecf006d0ad8e7b39eccedf63558", + "2365d0def47b15c58f36e8ae82a059bd1429cafe8074943f30ba685a738b24fe", + "b028a0f19166d18f4e9f804090f5c1a2de452c18778f2b90f6c9656ef2696894", + "bc76ee40ac2fd8e439f4da486203d4d31069996e851cf7dba8f89cfb0fc9c34e", + "d1473d3530f467422b890e099fc9500891d0662553ee5fdcb872cccdc5e0a12f", + "024739ac2a777921e46a269d12388be0ef9dafa531df8154f8a267930de86f07", + "dbd4212a0f904699389df642cda006eafdbfc2a234d259fcf7aa80b8b2eb07eb", + "07b5db07b47e6b6e4d7e523cd7d072e273b604f5ef5cb95a2b343c5f4780e5a0", + "b82dbcab50072bc4b53a11ae76f52113ef02059b70aa8c30c241328a9ab4a0cd", + "2a30cba7ff61c6f3eec2ef3e5191399a0d29381f22ffe0ab68a9976097293a88", + "1e796e864c1cacdb8f53925941b1b1d0cfcadc46576749cf9eea44ffa4f5c432", + "0e214ae0260e240e3952034c64cd303f4084122de25bd078dc8f9ba8f0be6dd8", + "def9bced5afeace6b2003889f3be039d54d3188ce500ade2f7700fd799b698b1", + "26504662d607e8db9423c2863b6bf8ede9051ae84fb9244a8b790091c13bfbd8", + "3a3d73db1dae52e0d931d9c3943234ead4593a68b47d8a25d9989e3426d3f345", + "146c3d99c2f65c5133899246a7df1d9e53e706779715407ad3acf7ceace8f34c", + "fbde90de8fd65374d5ba78ce6b789095de9e8a0ead0bc867bfec7472475edb81", + "c9db4f960c5ce90e35e67e71b092112e6b5c3e0ee49f9100d3b28e387ef74964", + "a6c2aebf40cf8442930dcff333cad5d52d1a048f7ea1d70f5160c1bf644f2d7d", + "074010ad3ca501ca2d1d19bf4c783583290c6bccc7402e61c306c171c564b7f8", + "a60d0215cf254e4e29722c18c9ccb7bfe726f6c230965b31659763bfbbc9ab92", + "6beb079abb5fde1a731e8ffef687d942f4730071dc312db17caa76c5d7ce1e07", + "fd1e01c7ac10af630d03eef342d6a6ffbf8e3a7766383bec6cda2fc03760c425", + "cbc7fb8c08c8521ba1e19bdfa2d0c58b7180fa50832fccd67bca10668762466d", + "eb804ac0cfa49881dabe0c4ee8cbf143b1201e76f0aff00cbb0fb2d415b75661", + "76afbc36996da269deb3aebd6a0c126a35c48b15a589c7831bc7a0b6e3c3a25a", + "5f99db38e7a53acdcbe9500dacb56d43512a3b82719db6f432999f0fe8e6568e", + "b8204017634cdee4305624e6127606b94d557a4632dc1264882af13caa16334f", + "ce1429ea6520fbd8d97ccd471791ceb374f1d35bfa9e8120a6c054fb3af2714e", + "e0c608378d39c11fb84ef935c61b3e5dddda90ea6b58358e74991b5be302d0c8", + "78cae32e31706d25731405b32b0ba0c61b7ee7690bbf9a375f15103c4e539b02", + "53718a3e2eb7825cd2d8554fd5cb83215bdad3f421f7749d121275e40fa179a8", + "12c15d573c5a7132734cf137ebeb2ffd7f88c994f484d78d73632572d0d3ac91", + "26d760f19be3480792e99962c277c5b9fc11348f56e05e18b63f3d3665d4b339", + "8f6c31a3747ee4eaffd7cdb5e444ffe8074deec6719b18c86e1041621ea48c15", + "c93c5392f366a35765990f5aa473ff2413a4ce42bf9aac7b7c526182647daab5", + "e359c58628895b61a3bf637af07b5139d361b3a326bf65d1c386e9a3f5a95129", + "95b053544cf74bbcfe185c0de43be72dfb7e02be1e83497fd56a348793d31134", + "c5dfdb05db1b80650542488f13c3c5d7df63f8d70156873f831a07babf7bd7eb", + "30b955f31d7f55b62f9d4598428241cdfbbc5cdf3a3aa6ce18d57ae806b2d420", + "badfb95d8a0ae5482ab4fb20069ae1c85d17834fe5d4a181b804c21be17c62d9", + "a6bc81212ed8359ad0df2485b5cbd08036b30e7ec824fb698de105ca47ae46a8", + "b62774d18478a00583020fe612b12eddbee36c110b7b02ed359010dc354d0141", + "6ce2d2f172e015b81002d8678df58687aae975d0ba58ebb5a1fbd35ba941a193", + "33206dc49c0e1b7667eafcaabb76901923fe4f794667aadb4724b6a1cf065610", + "01a2d34b733883a92009f23c3fcf13021fff058b8e62e4847be0a474b815ec65", + "071b3ff098754d645d7213ec830469e95c5456256aee07d510c2a1a62ff27f63", + "8eb14d67e14fb63e14ea55abbab54302550f987f036f5014dd446672cc1c764f", + "f5583a49a0ec399172508bcef764867fa2d4301b681876c94e2f84055188c7e0", + "debd3be222d0b1c2ac3ce6f5531915956abc732b826e537708f6094759a578c7", + "8498c81db9a34b019c588a14548935487ab09089234b569ab2a798af94c3d087", + "60693c18b25aa73f71dd5e67a1d4af536b0585728513e55336a617196a063295", + "a4e4c034d1f4d5fcd3cd8eb5c5c4dd0f71f1f7ac04bc887ced86582f207eeb7c", + "8665aa1eb7b988afef6d96fca36e9eb4a4ced78ad73c270f9e7ea39b3f66e4b2", + "cea9b587f556acc52449b36aba6f9753a745bbd863d2976d2af06bda1da430d3", + "fb630626358bfc0ad751dd7ff32a1cd49b880f4c147da2856b0593f5a8331e3f", + "cb696edaed9b75b4683f5e10d41517e5d8899e543b22a54b74fccd12a7d3b843", + "5fa2ba94fa28498630f78320ef2f7fda313b44d4de681b74826e5e1e8930dcb5", + "e942c282db9ce03b13a4b6a1499a431f7c84803976276e9717efc85dbcdae62c", + "a68c25492e1f52fde7c8921262d9fa6ab3776de3d9f5301778bf1b1ec51e174f", + "3e63533eae82de6b3659a857eba8d53e3842d6eeae8f1edf8b90a97a219631c7", + "91814cc8ac784ce5f8e69a79883f88d02c48c35309caa00d97d7c39b0a21ff31", + "590181ce1f34f7ad94b5346eeff86229b8f6f182b8eb363aba85cf8325a4e828", + "ac982c2e4d439fff255a938ca496a8953416bd4eed085de2cb067890b21cd7ef", + "001ddbfd086320ef7ffac8098e73c2ef78625f1334a108b3f9b6a8ad2d2ed9da", + "1fbfc933ce6ac1b9ed9ddde77b0d0b355c2cedbbe04e2b6c79eaa63cc366c6c4", + "accf26cd78319d2b1fcf74c97475728a519d0ddcde45f29f886162d16fce72ff", + "d1525714b867274a32801e9110cf9a785775c7cab812e2d6726a5308fa48a41d", + "c8329bba2918a6348b64d4761c2daf7545d5deb35a586b32125d6b2f423f4ffd", + "1728111eb4e9f8f444764908ea8c127d3351be2b2e29fa7fe2e1176449e45b21", + "2a847f224f438f55b8aac61b716b0d24183f6cc5f4ef92577603677479d59636", + "dc004c9e206f3c0776ee5de88b49b1256ebec02b6e0a37c38d0e0a0732b0fca9", + "b0093013820c3bfc82fa45d560adbe17359faebf4dc9699f01c13418a7c78882", + "6c6d5e11b06249d56e1eaecf81472da3e1cbb8ba43f4c593db37310b46022444", + "ea78faad1b58ea6b105038e3d25b9983c76487c94587430da9b65a3de725a3de", + "cdaee2012198d5478459dabe4a05d9928f3adbb7a99037e9fed1de86678d6d3a", + "69ff9567aa361563f5013f8f7ff910b5a3480d9c564d27111acef087faa2f5a8", + "8d97d2d06a8f85b719b6ba0c6139cf9c398a8e54a37e58e36892408c57b32183", + "0ec05a93c84c467ee4432b816dfcfe6cb67972171e83b2a29267d6f7d2076f87", + "7e6e0cf7c71cddb93962f9c59765ee0cf7c32c6a03ef2bb885a0c5fd3a2b11b9", + "03e31523340b171d304094b825b48d270aa1c3f26ee912b31ad62707d4063b41", + "1254c72759f0873063a3850fc1933df700df72d1b5592659922c1f088cd076da", + "cc851c143f8889a83dcbdcd68ac58dde2cba09dc66385f803699525a8c08cd8d", + "d0fd3edfdfb2613193cc40fa04e3820b0fc75f52c4e8de24f48603324f247bc4", + "652b055237ef45776db4e48ff249e4a562d8dd903d14fe024cb13700553a9d71", + "0d304b12a91110f9eb7466a991e5a283f6580acaa7dd2d6a1ba7f24f3bce154e", + "33a9b6e6262dd7604c4d77f576d4cffb80f8ba9e44b83326a151fd240f816cca", + "1d979c4984fac5fd60a4039f64e91ea418416f07fb160afa2c0643651e7d2078", + "72a09499166492f38890ae7cc481b5b44c7c64e5e0cc0357f35c0512d2551e7a", + "3c893d17f2370bfd85198f7e6e69516334189467bef82f6c76ced5fe4f5a980e", + "884d4b47ae26f3e2a3b70947dce5225ae2eacf022f447171954142ad5ee6dea6", + "fdd80d77e24464e7c93a5b1f25f1afba61d75f3f293e3f09a4d2bf4500239d06", + "9d214c7de0575d296d6b192bd49ad9cc7ffc0a4d8eb7b07ea3d573989508f9ef", + "ecbb0b636c8ebdc1a5f85243c7bbbbda47f60c0cc525abbf16e34b53b1fd2e1c", + "ce966f0a3bcc10bc80908218ce76e83a3deda7e1d4712fc7cbff2d7313c26465", + "20f781fd98212a1e2b4c87de777c90a6798d1c01ad8fda72e18eea65f92a8960", + "c98e86ede655400bb57ae0a0644a48c816754e7392d712275611c0a0d3f429ce", + "6058e00d648f9780c7acefb36a9491d43d69f218aa894b00c0ef0c1ebe3bbcec", + "fb15fecbb9d78e024ce9e8cb3c49097bfb13e85a56e46defd5e16f0014be2181", + "006c94a618f3d35d338743d3005a6930bb56779940ecb631871bfa0a85e8a519", + "53539fae7507abaa3bd83c74f5204d93787e6a57ea2db25df4f9a50880999186", + "1d9e4868df154607ec2518869ad737f37e48f66b4253312aa2ff4bb4889b4fda", + "621b3b54754f83539829d84bade29c7e5b1a6c6c28824e22eedfc8910d891cb2", + "a80cabeeea7387ab164e524a24b9efc26e5da61f1bded6d3536e7c3f3a61eb14", + "fafccd966311b6689399c5befcf37412530d79ef9f93ad9ecf13400b18446e82", + "08ba87cf95a9121402401e8399772cfef4202eac9f446a3a864d1aeed74fba0d", + "38992b72a520004cf118059ef342a2eb800767351a0073f8dfac7c359fe38330", + "6bc5ea816f6a9c1bf329512979734133caa8c18232bbbcad4974e0dcc4098a70", + "7ce250e39d8e946d7c65adeb79545c25dea6faf15cc2c56969368b313117aa50", + "b3e674c9e50990ce19ecab8af5cb800cf3f9c1ae7fa040e6f5c5d2d7fd523467", + "5d8de7a2990b3c255be98095fc42e1df30f88ee278b992347931b582f9b1ba93", + "6b09184b976dcdbc6c8258766b1900ffcf7a2c26af12c87722c562bd372273e3", + "d49ae771224d8287b9e829c5e45bdbc2d8adb068d7fad2f3928bd84910baddee", + "603513cbef8be042339093e34f81032e7e332fc94c3b9ac74e603e10f0d4623f", + "c520b15172f40f5fe26fec9ef5865c00a84e79b0024c46c9295e25f9ccdc5057", + "7689f2f8230444c691169f1b5bedca35c61a2e6b1f1ab11ad629c96219cdf0d3", + "d76a4d4a771aa5636fcd382b15f424be600018196666dd6f4683c5e60dcaae7b", + "5c4c9a276791890af93f5da1e087e8c622f19e72b91b1137b77db796de5e8c97", + "29c883f87326604318517711ff555e7890e913de81a7247d5910889a78960b0c", + "5a26648bbc8f11b639bb76ec0fadcbc0abcf471fc3a6f094b8401add5a240a46", + "4609717d22514a61a920dc25124e3d08ad884fd9829aecbaa9aabd947ab50851", + "af0082ecd7741a5f70d8ce885b850e293be9114008e4a0def8e9e834aee97db7", + "de111ca4832fc9c921d4eca7724402a8f492f1ab1839108dda3040f181cd0ce3", + "11e41b4148198539eb1da9acc71637dc07d8b65e101a7ca84e0c09ff97831c03", + "b1b148228581496193c8c9b848924d3b46b4b7e6cdd095fe5833bcb2e3fd689d", + "637a5eb06a39da77882d88c40039373c63e3638ff4785dfa48c2405491f3882b", + "93f70fa442684052b92c8a6bd64044f5ae4e99b2dce49519bb1fa8270409cc22", + "b650902fe22dc91ff5734cb310662586ad2ef7252d2f92678a39a5f36a3e4379", + "fa64df468084af94249f83a29f869852263f2fcb1cb12b82478e58ad78615442", + "07637f4568f4c8dd19d92717b1b4a076320c409e60ea5fd411d141430768f11e", + "65c4705d8c5571df8cf286275c320592f2fdd2ee7dfb1add360e8f6de9d07240", + "8494c9b7c7c356ccff2d227a50f2b312704143a3b2d3efcac437d0aaf7ba023d", + "90640a78c8b15a2ad94006f01935cc2a8e905c639aaa11225fef35dca94d7353", + "92d9a62f147d970b00a3094899bf67d8bb28e5484408afb118424fb6c25183f0", + "44e0dd6511de408206a766386131c3a1cc48167707399477746be11f527d1097", + "a7714920d05c590ad50cb893e21449ac52691081aa9751175231960c8c927af5", + "c6201982369577efbc60a6c69719dade0ce536990068d66bddea15fc73e9d515", + "da2b04ea23e6e469e5b81a69cd3bc73f1f31e1c95cf63abaa1f6ef951307e56c", + "e0c8320688038089f9f2cb6a377b9a27ba14a8ee3c80331ffa7e71c95aa08c18", + "e155ef3d165edd54b9ab61f159fbebab1a051d48caeb6bc74faff4bcf943945f", + "466d347f71a70dc57ede17372c7d93475551d86ecd5e6e498c5762fae6752e81", + "dd4033446da14f10783df76403e217ff78f8be9b977ed65cf8ebccdb29839126", + "dc0280313e39103c205ec05653c30fd60ea9da243394518b90de1b6843ffde79", + "596c3093feef564f6c6315d4f1a2e784707349da40b2e636c586eedad563a567", + "dd1d0f6f4545751a5b3f74e2f5d68481c931992e3f3becb8a846caad61e420d5", + "6796bde05727b898cb6b5b16708ca2e9d589e4a87384bc7360ec29b7e2eb8439", + "f66c8e7bb1bcf864bbf261f3932d25c94238123d7d0da0af887866554a167bd7", + "0577d024277134b0f0c56a8764bb220d5d5e3461dfcdfe71c5637fa8d254fe2a", + "b50b9be887b2d7156915dc189752ada0129599abd24e671f91e3b56aab0c0755", + "f64ef57aecb91a652c099445276ef5b9ad2fb48581c51141073b50a2400a5038", + "7c105a3877ebdb7db2ab6c1ac3a626f86d960d9aeda2824552ef9165dfa05e80", + "0bc36ffdf89117b4ba08e782386562aa0732e4201512c372baad3f5aa6720253", + "8a78987437d7473258e7e7cddc1576acfe4ad292f39828ecc7b573c9dfe063d3", + "773265f9968724e0bf58674920c980a5f842a57915668e6d1c39effed5776eb8", + "962c599f893341b32f4394c812747a3d33d466c03070f05b81e98b898f59ced5", + "9725de2b4d9c0f77076f7f0a47f2d20d85f931e179e5812b4ddff102e3360260", + "db82361e47d82fd88acd77237be8fed05952451c681fbe78271dc8231edb265d", + "55ffcb92c2d38a47b8fda9456cafa9536e190db39265723002032091c32471d1", + "48ae507745b180759f56009e1a52fff7f0c1b96eb59b77c35a47174804e76999", + "3a95a8fd3788fe1a45be30869c62cbfa5e12608316e960822733f3b102eef79f", + "effaa5591d69d5e4b049df936e12d214fda01ddc53c15834df37b7c008a26dfb", + "ec53eb56bed2ccf52c5237080ba9d3ed9aedc21a2a813ba1b35175f3914ec1b2", + "8392dc9629e4131f5f9e17a5c254654659a79cb0fe4d567640f42e69c0ba1d50", + "2c2d44bd76be75f5d37cf82ba7399e836a35f861fb5cd0e8477253e6c5b97638", + "91722a78636f55fea0e27186e293a2b29e2088fd29e1dad6dc1315ae5029528b", + "1024ebd0e4322e78f44086c66230988860537237d80d6bfa8c7133f66def32bc", + "e05b5a1f2644c4e578f77ecb0db6da04a90c15db714547d55133703df2b67222", + "30d05f8d5f41c8f7d58429f168d788a5684906f5d02c9a59316d122cb3804507", + "e831aec6ccabe0dbda352763d17f32571ac5c1805cd6633a47b1d4ae1182b7b5", + "10e35c9af21bae50b3a73363039c63bcf6af57a1b92f77cb5c11685e1c732708", + "091600e3a8943f7df8f80c929f2bbbd2dd7a5d480872c9ae2eef022aa2c27928", + "33552a1e0ee86d0cb8b4ea0c5c73cad16f9c2879e43a42e8e51ac4a8e3953177", + "7f2be157860ec71b5e8489eb9bc5614c74ad3c99270f5695758bb14a9f2762e7", + "56fc536fac1c477a8a2470210364c7adc6d4897327ff01f766d727a4699ccd90", + "c82b603d305035cbec9be61b2d298ec937cd8f024d5913d633bd27a0eea6a89e", + "8a0b0f61fa36b7c4c691f0442307646438153bc52698bed3f0ac2747b42ed322", + "3c3c9aa3fe78e5a10150ed99066b40e43a8bbb80791b4347dad8bf45875c6af1", + "6b0592a7fa7ed6114781fe2e28a9021681d87ba269388c09d41f0475441ab043", + "6a86f3082f8f4b75b698315131396777db7e6a6f2ded96976ae4def3bf34f051", + "f719e6fcecadb19262c738e2bbb5a9992514b776eef69189c9c57de26cae9f69", + "9d274011fc0cd2a573f7fb9935851ba1b0342224177559584e356307449f317e", + "3b3e8d821c7edf0a963127b12b422b83b666fe5a0a3c84a6b5e9676aeae2e6b9", + "cd1b8875c2f3d6951446f56b2bc0d48e8b881865b9b89b4c1d2c068ba9dc4cce", + "2ea602ef765904ff6791e660a9b52c8c40fc68a28a81cff099b8ba8f299adbb9", + "f8b7f139cd041f2bce4d811200deb674a8ee20adc3d887fe3acf07c306aa7df6", + "5c1340eb7b2534cfdc1ef9380945453b1b4f474224b96ba93530b9e98b204f28", + "2ffbb626dd8d99fd96924058dc2b3eb587ea074d00dbb0983f0e220f38a96d0a", + "45f52f06b3b221aca1bd26b1fc146f469b58f6319845fdda5433baac7ef8063e", + "68510f8bc28d916ac36f7ae0fdbcbc790094ff2f1233f46f2214a609526a38de", } -const mainnetPreverifiedHeight uint64 = 13751424 +const mainnetPreverifiedHeight uint64 = 13804608 diff --git a/turbo/stages/headerdownload/preverified_hashes_ropsten.go b/turbo/stages/headerdownload/preverified_hashes_ropsten.go index b5469ea1ff9..6bac82676e7 100644 --- a/turbo/stages/headerdownload/preverified_hashes_ropsten.go +++ b/turbo/stages/headerdownload/preverified_hashes_ropsten.go @@ -60232,6 +60232,300 @@ var ropstenPreverifiedHashes = []string{ "9040fbff02b136b48da79df689bb5afb19cf163b499d00cd01eaae089f1fd96a", "86d5f9bab608d5523bf53644a3b140d96e10a36d84997cc5514a14d1afeaedd2", "10795cda8415b84a8ef1b5fd0c79a4f2c7176e642e62a6f22417426702738fd6", + "64d45161c7ccc3892e3a017c7cbc3ff12a0e3156b2d7cc07b4c332a9958e8f55", + "c9a5029e3e1121169f80f3cc8e0a780e26127dad89a39dae6827de158d67bf4f", + "be5dfe20dd7eb3828eb9c67f74fa2b5d83ab964190d39175d763275118057ff5", + "16a0b309ba804b8c914b16f1060d0e5925377033926a390c164d99b72449bd70", + "e38db6a384ed95ee94e6a834128073b7ba9d92993039b1838ccdf0567b72f4c5", + "60510c1844fbdbf71d2709d19b75c0b8a293937f8cce72ac250184398c0b15f8", + "a9a8deb93753d13225d1a2883ce3e5c410649e4743359d70803592243fab1df9", + "0a196a8a6a1226b28c1a814e74ab0c14ce963c8153d19c888b9cbe46dc57baa6", + "24143f4ff4fd6c9009962a727aa5d1312b105ffc0fde68466e871d713e3a5c05", + "7f980e20dbda592eca967ce58ec9792b9a8cd948023270257ae1f6f9b19b7abf", + "4ae3cab7263e5a8286ad655f6ac8a26f85c715feec33e4c4595fd5253c8ae0e2", + "ed3011987e8b6d02dc0bcc28520d2d2230e4ec386b881cbf5ded30a9df91b209", + "d6370289c74e76355f852aed6269f9d536c275fd418fd3bac086866d0be64e03", + "01bd81e3a68a8d8ebbec193d5f0766ba70ddeafb723ee0ddc0e057fb647d5574", + "f70181e8fa6c72d7418c2fa133804d12341ff56ebcde4dadf6b65299a5b2df3b", + "cbbba1df6119ec41cbe03aa75a045d8c696ceedd06b4044e98b9b8e5d3dbd55b", + "8ef285c6d9adc886303703da10708a9f6ad6acfb35fd4cbf6d5796ff82635980", + "7f3b40450a1e84287894a494c3c455de6740123d0846643cc04c6a3427d48de3", + "65be003a809a586a373560a01f7e244cd12b56d9f6c0088133db7f801ec3385a", + "fa6a038eba4d4de3b9ccb6864c3427c75e84419c5504d8c70af919a99ca70c94", + "ad29a132f45d1fc6cdf5b0c3b3d2332289391f3ca8da9765c330f3ab33ebaa0a", + "41d51aa23fc6c7be9b1e40f8ef3a94230bfa7e2dfef60ae5fe86cb3c26cd9dd9", + "3fede38a465b41bec8e29cc6eb89203040de34b6a55a01225b37ea065ea38298", + "5c990c4a009c6a66ee1b2ee3720e2cb786e508f0bd362dfc40559fe8fa9e39ad", + "a4086cab6f33d237663631abdea048010f8ffad6a350a9361d0f1bdff4cb3b6d", + "4c7ae90e4d0de9ca5cbcdba44c75c7db421a18acbd80d27a1925a028b34d9a5b", + "5b0aa3e1804026197b9a04281327795f3c861d8e6051ca92653e0a9109195650", + "fe3e31980cf208a54a5c75f2d4d822e3ffc47b94aebe5aae2f7e8b01f897bcc5", + "d380e34cc2b6a02d44054c281c23b20b437ea8a6ecb332aae7362e1a04d44767", + "90aa16b56c35e2916a6b2e1cef586843c8bc5fb1f2e5e0dd78d088dbafc71346", + "9f8ba9d3f7dc4e897f04ca392d5a6a96b1bf9aafda4df557df3d12807930acb1", + "ba5e4e9b1d4f787532cae5ca824d26d6626a86ade7b0cfadf57a1037d77f122c", + "abc30477eeb417b8eecf1e0131cc46eda40babde709ac02161943761aefe5ae9", + "cab3103e2ae4e59d697d9fee1fb0c0cd8eef3a14085150f3f1a340f8192f247f", + "37c63eb2a157335ee4a4a623b3b529fa724978823b26c4bacef0134d2739890a", + "616635b627debbe1189749dd33a9720b3c1b9ced5ee2c81d5d19a26391018bfb", + "e0de7e5d869f7ad65771da88e0c0f77dc868407566b315d7d99041ae5733c34a", + "7f1c5b3fbbc3d3a47d442fee98040d122a2cb5658d0a989272cdb50c9dce28c1", + "dbbd70ce5450ce010e6e870903d9feed5f67a96bef9f60566d666c68d03efa7c", + "d653555513fbe34fac4b8ec28d8a6e484351ff11862ac3bd4ecfe085465b1e2d", + "6cde4cd710e5813dda14781805526ba2c652ca634595343d4dd0c8006cbc9b29", + "a24a18f3d93950a58729e9b714d4cea8645238d82a1fab7f64dac2881378a673", + "a86a502098672aaf667a908c94b177bccaf8d2f7548c32e18190b858d8b866cd", + "50114f14c420f241bb5ce30f891fd1b1bb59a3d3c93c62ca1f19f999116b38a1", + "964926d9d78420c630be1aac56eb007f4f051a649c1f0a408248c611be6066f4", + "8d6d686e474e57f05f1bd3926f3918aee1197c6b7a125a727d2ab5fe079fe114", + "29d0b1933718f9a764422399c68ef1e42ef79963c3891d8a03d8df4885d983c0", + "ab8efede87bf8826c97d82d31ece943788c3f0853506e61a4c17e8b399e2674e", + "59ea862845e7ba127a58c2273bc208b7987f0212112aa7c4b1a6473018d98589", + "2bf1d7165252713b72060f70842571369ae4a37cce86444bafda57e2f17696d3", + "db215be00e56e3dcc1ec1fe2f14f642082a554506a903d25dcb3b2621cb1087d", + "e987df4118fa5c1bc440d0f3ab3cf8b732c2f377f0cf767026e6499cc106bfa9", + "b53f852eb33f5c375a24f1d1412759b294a561aab3c3903ef2910ecc4db0d007", + "bc6b992f473a94b6e434edbcbc416485e1e69764adef0c698b93ff152175d301", + "2f43a5663f9221b5229f1678a3b54192c1996ed0086392588469c1474bb3ef8e", + "ed32959a5b252aa475d838ca8308808f4d13cf4f56d6d9998b157ba460eb6476", + "e3e92ccd1dca7c0de51f3a030458f0708aebeb1ad27d317f46101f0eef2de6f2", + "ad4f3dcec119e12db25e1b2e7298a1cb236eb28b46322ae38ccbe05d57938684", + "cd737f75b71033de8a043ea300b06168ae1bad5ce53f25275c2cc771292cfb70", + "5cd3fb57908029b75c616ddb880a4bfeb552e4487bb9d2b07acfb5d9715592d5", + "f965950ef9f573bf72ba2d5cb185cf172f8c9d6b76e54089fef76411678fd410", + "e97a636697967082581faee7864065367e7345c6d71ca46f4addbe9577642f40", + "52734c5c3cdbe2d46251f29766dec843b25055189a0526c72f88a3f7c6850adb", + "208b0388efdc04a6434bcbab3662857cd57dd214abd2378e12380b0639aaa710", + "895ca4b4299247c87c9d331edb65eca80ebe375c830a5d407375784c466bfcc1", + "86d24026a191acff5d3e0456ec8000f140b8f0cc2e0a0b5b95b76632c448a90e", + "d10eb425e9ba08856c32da15101c30f7b2905330913214cde5e09efb305a28ba", + "9f49df508ef864d72496820cc11d344a05cc8ebc9dbaa02167dec308a64acd86", + "c02ee1d54b1cfd9d376ecb4676b0ef5553bd795f2b7be47e72a2afba4095f17b", + "24405419a7e980b117d32b1da4149bfeea379d144ec5e425c1201026933bfc43", + "c3d7ffb970070faaf695d5fe2910c5397b528c60695cf3f326b7fc4e1440daa4", + "5d420b2e5d8289057551b3d89b9fc030a72d0b09d9e7c91ad885e7d03f42ccc9", + "441d7d73cd235a1c993fb479b341d99496db23d84eb0c72a22877c04095a23b6", + "c1e26140cad5637edb6736ef32ac99b669ad8c400165672f27a557619bfa56dd", + "28edd97095bde07602b2225e8d1cd857ad397b7a951f3b5d7c6e141e00a541e0", + "ab42274a70a51c59460d16153e539d713be7d02169294a54fc33307c0bb67a64", + "eaac96d90a0f66917a23e53f37b9c1dadcd9188ec743a1814b08ff8366789bef", + "8bfa4f99580903d147a12175afcd8f4c6d14a0ee39ed18b5bbce9d6383a1ba7f", + "7642b67f96e484ae69d550de0d33cf25c2bf0184ee2410b4afdd6a5725da5c12", + "3c5a857a669a07ac17f6ff95a77921858b67ccbb2b7f49cb6461ef6bf6210f13", + "83c89a8c92dea414258962ac08623e3fd75319b1162436caa224dc30b486ea8f", + "4293de5b9bd6c5b6ab812fdf2b04198f3140ac3459b62001d08ec478a56cfffd", + "ee553ae6d533d1dea84cf61bfea0d64b290a601893f48ebb1d1ad74fd37756b5", + "03154ff7192f9b1f210ddf90bd85c0f6c95bdeda070316f58c5b484501b9e32a", + "dd07760ea39d91ec1822dd2673ea35e308452e039f79a8cd03f0fe4e8e76cd29", + "2f93a04854c4b7a9e2d4f22dd30daf4ea51adac869eed792863a2ad57f0097e1", + "46496368603cd4218edbd11b609fd14cc955b9b66d94f3652e9441b0deab6527", + "84afef07f2be817ea76121c9b03f231030237a88836b59091050ea2085da2dc6", + "058dc4015f6a4756eed839bc296b6d13a06f5632ac879c1cdd4448f74ed19951", + "0d06f76dd957338b27d7665fde8d8ed83e94af7578d80ae474528cceb5f7cd8a", + "e02d01c892e900cce82d6eb59d5f7bbb775d5d877d83197f4a95b2fe0867b8bb", + "ae25b8e1b2cc03da39f06986a4e7d47262dafb07f1e4d99bc4a41dc5e1100d5b", + "0ce6a2dca166a2a14ca1584e4c84b58d2c14e88e5731b1332f2840f5a9857767", + "ead63b2f64a0acc2a9be9d86badae8740f29e9ab9a19de805cad5d73655a0ab3", + "4f85fed3f4e47db54458f852d3666112d6c7a321681231ac60cf6d93d1c17d2b", + "d8459715ee17ff4c50041ad494d5089405737b47c4d79f778f9949e1621676cd", + "697b474deb7049050a5f51b353547e1556b8598bba5c22867f20f523a17b286a", + "fbf406e14323aabee1a46132ab2f56ea1811da31057e5e0ba47aaa6817800d88", + "356e48460c131580f0d19efd24b9816c1466443a4efe2d555bf59c5cd98f4835", + "364fbec817579ef71fb008034a8bab680f4b2c7fbd8d9ccd6f4ce349130618ab", + "b45e4bf32a142f4f6d99a4496ddf89eb0fbafa9e41668b657368473e9bac372e", + "a8ee6fe672d24935763e8d9d06e8faded973898701e3626a05a9c8e8b1d2ee93", + "1c7a49339173056edf045010511eab9e36d6161cdc22a278d667f9888d512a35", + "7d5d7953197c5c7819d90ef5b970020a4cc8f23c4b249252b700b5caa741631b", + "6fdfb6b51e243a517fe05fef43f8026766a6c5cac6b3ea3a78289182f0de12a4", + "401046fb26de322ec0cb6195ff65fb3b1a8b870208304ff2a4443848af65ca27", + "d9a62576c15e54d6734115a44d2f3506203d4b9df835a4f3fc4c9228ad2bc61b", + "e1d3772ea59974fe255f29c576acc56b559f1e46393a42c5b1604ec1372edd7d", + "8704315c24a9de1f7bc95b452f5dea7613da3abc1e0c58378beb490db5d0e52d", + "16cf5837882a96221614fcd2e27d492146a4d9ba8622db6691770812ea73da6b", + "941de968cc8d7f905382db696d58bbe5eebe00f1fc1cd50b53b9e4cb963046a5", + "749254f6ec4759182f20c8ea7397054181e6155bda690dd10fd181e2616321d9", + "66c3170a951ac7b75fab513d01eb921274f1354160c70b0fc6b544e2d0ff4f3a", + "ad780f13a34e44bbe1dae0eba45ad3655492121cc94d061808015535cf698802", + "ab15c9ece34185b5edf7146f63944d0fabed0992f35368278f7fcae300802d0e", + "abf1873611ab5565cdd93a26fb4f7d348e205429f0f394b5666ac80d333463d4", + "aa4cbdfc6c5094c387c3367dd6f03a0891a1209cceab237471dd79dfad107863", + "1f3934fcfa22e797299a7d4dd9c69e51b8a71ebb455ffc94b9dfcb0840e35b80", + "1c36abc4bd227a844f05689911057c3530a2bfbeeb228404513be3f58ef53069", + "c24fccf0b7727862a824378ccb98d1b7948a27dd15e23139bcce1a6febb2ea10", + "93d81b625bb298c1295253a7614465a6197a913ad4e9f938f585e6934071714c", + "f7570fd106f6bafa5fd149a26c808a68430c6bd61c9d4861821cf361aec1919c", + "3661c26afc7f7d0aab736bd2a98870b90bfc55450d7f9b9f8ae77c18748ad4ab", + "6ee29587cd779e21ce44b6857a5594ea35a37bddeabdfbe1b135314e74dbac67", + "b84759744276dea04683373333a6137e4f2ddf8ab15fc48ddc7ea33a3a185671", + "53ada061b0d1c2d146f9c53794b791c053cbbe81ac626cc9272d3c55d618270f", + "8415d724c6a922a1b941a34cecc6e0b436132f10fded6c4a6b139008ebdb1cd0", + "e83688817c20f36569ef387f757f201da7ef24362818167467f15f8c75a8903b", + "fccfb8d0a371c21c23cfa7a628517d439cc61dbc8d07946861c49877ff7ff240", + "2d89c1e9228ef7af990821ee06f437066fdc0aa8434b8f11c39ba6e0fa7c2478", + "d9cdcf050d8078bcbdc3d5ad77d81537dae81addcad0b7f0f9a127e2ce76c968", + "7f8555bb400fdc738436829b1a3fa38e791f31f39682d028b82ed99530238908", + "14e5732cdad99728001f5adaab51047a0bbbe651cad231b468a182b1f842797b", + "a757010f2172b8eb083ecdf5b189bc948bfb4c3803a574844bd144e9537961e6", + "0d66a651c84cbd4c9da7eee5b794c0f919e5ee34e6ee99771a23fc2bb003f77f", + "860277436a18eee6ecedb1918bf6abfb712e6bd955bf047c11031d3b000259f5", + "e7a4b2451d401ece4e21ff2b2f4798eba9f5722fb46f892826979f2d47053df2", + "685c0f17c99d0402af9e7f72285c90c85288e86298a692bdbb8f2477ec51a2cf", + "3285076d5583611f0ea3ad9499fbfd87b3588ad454f6fc0f6ec76d3bb37567bf", + "716d0c453f11b111966df0c3b743c9cab033f78bfd1528c9b172ab6266baf364", + "60d1ee990e6bf0cc2c008bea6da9706a97e252b8c3ff5f1aa7902af4879cfeab", + "208f6be632e89f3414f1cd90e5c97b8004060d2898051bc843929f8dcbcc618a", + "59c61d9c308ea0c0664abfdee960fe1e2b8e69ce8c8a85492ac8083a7b458e08", + "b279255d3197ead3aaeefaffd08c16d09766e2c3b4e5b042c9ca73a81595ae05", + "012b036921d35028e09550a5c355a7668ab1079e64824e78935d9b9d7b93b02d", + "adf0471639e891d9b27fbb154adc0ad67bfedf1a06f9a368b30f10cfe7bcf372", + "eeecc5c582e15d384c0bf34f807e34c34a3f75aa54d9dc1f051d10c2ef8f5a0a", + "6138ec5819662c68e418cdcea034ca9fb467edfba494e6b78b0ac2a3397366d2", + "abf701308a2fe1b90af1272cb0f51bb047647126db4368fa0608246624748bd9", + "4836cd94366149e051f0889e94810315ae881cfaf8b47bc66758bf21c209a71b", + "2f4b2a085333aece2e87cceecb8fba324577ef1df17da46c94512574a3c5356f", + "9d93c34fab9ca67bb7e1748f2f242a48dbe85b99ea56d68a96157d162e57b3c0", + "eb2586956bdcdd5d0b28c7bd08840eaacfeabdca1d54ab70f36af3f8f116448e", + "9ed73cc97509a583ac59915bd192e52b67c212e227fec66f8b8aa01c30666639", + "1c2b9927455585f65a52864e4218eb582f3b8b8131268d2564717899852c25ac", + "404058cefc5376fb582788b6dd9e6aec044d4d8a255b42e06d2bef9f95be4e88", + "b12239f529d78cca74e93a93b3d6c9ebe78f5916f010a656fdba138ced05f822", + "405954c3bb24c5a4904d20424c5ee77f81d860569801e99b48c14e633c1c45f4", + "e3c87164f9c9a329a62fb0c3adc3f9bd4b32a7096576abad06330a6c2ab8f35a", + "1ba8f61ec213213c32bf76e12904f79fb10d20a82f0e87bcd2b0a22672810225", + "d0a8533172385794a450e58344cb1576141fc3248530b9ac3dd71e20ecbb1359", + "34fcb31bc1be5113afae4f04d34dc6d93c5e67504c0951eb36212743e6830f32", + "c11f3c032c8dacb272d7367c1c3dbf7f09ffff10a4cf46034d28952035743352", + "f505363b304276cd6cd8cb780bf101ba5a7247dadfa49985ed8c4c6136411144", + "eee7769313ff18097d60e369e0910029b18dbb6c0223d7c9ee0d1c10003d6010", + "2d577e051d585a6261c3e569375f30247a2dfbb8754b0bc69bbb0ec266f7cef4", + "87d6f9bdf94e7c3c1733be32fa63ae7adcdde6d6c3f2f77de43261fc9a264bc1", + "9a9191a80e9fa22ea0f749d0de8b604b95c6df23b701a31ed3708360d2d7fddb", + "151175b699a266ffc73bfe2715c62c76f29a3072bfe546cf123f4d95e940ddc4", + "d46437ece8b3f0646fe341cde26014bd6282f6c2b2509226b2a03db90676a4d0", + "60610cb12210e93433ff67285741195756c971eb6b81f30a636959aea591bf95", + "1ddc6221fe9d48f726c581017ad3bacbd4b12a1ce27856b6f9269b4f591ec786", + "ddd7d133764d33eb9a5b6623287cb5e2faa91d2228f52006a22380b1780387bd", + "d2854dbaff74cb7d73a492b7e0ae08da48cb182ee6e31fbcd4d437d89552647e", + "894d5945ebc0045a000a0cd1f88643324bccfe41ba2b6a653b8a5fbc29496eff", + "5adcf552324e02dce57a73c116929e8eee33f574627709b8f487e66dae3955bc", + "521fa94de522227eea47086d6c19f42561f14dbd436e8b310ee1dd4c5ec27f5b", + "ca0c2d6e0f57612a5da5dda2bab79b4ea8bb29da5d70be2b81bfd45693cb4338", + "029e6a6d533547326809f5f5c50258d14e4c5d158e5b6ede10b668398b3ea2e6", + "363c5c4fe36d94cf05bc47565042111d857c6b82ceb35ec11526f8726595e093", + "beaa9e63b227f4545ad7991e30f080bf16e8c28f72f5287c5265ee2324719ee6", + "eae09d0023a895e889ae2814df97fd09f16bb8d0f05aa9fd21d25feae57317dc", + "74fa3b242c06e966286e705b8d3de8ab0d923402bd3a26920f18688b4f13a28c", + "71bd7cd85e2e6320afa94fe310e317587b858843395919ad8c5462deabbba4f1", + "21d64104c1ba0780939836ac26760cab3c0206fd249179b9182d7e97a8b8bf77", + "63b451be8c69b27f8131c3c38a7f6a3369a7051b4eac41f807d14c991e9513e5", + "be8c24b9da099fe161c47c5b01733f8300d828c0154467d78ad206386cb6c346", + "f1c000e13528befb0ade60a55d04cf89650b80d0285e78c74154e63821faf6e3", + "c2626e96aa6b72d051fe7c90532e9aacca60cb2e48c48e6000e78867a7a624f9", + "6ea61d337f9d532abe9b88b04011745b31951101a6af90206c03263ca10c63cc", + "b8534042ec13774bbdd310f336247936c8cc2730bab983f4770f2ae336eb68d6", + "8a49d29a91c1deb5e430a3d1547e5837fc1eab9da0297dde2780ee09bbe4b220", + "d517049c57846a0750ddbb59318465b462ff60fa2f61a0ba17da630985be3640", + "8749580457a770c5c37e5909e268ff38bb86767624bea7384fa3e5ac7d00a34b", + "23f29adc1d0c8b6cb0a10808810963a305ea43f82654636be629662bcfb1a6c6", + "2ed9d5005f88ec4113bac0629c0f366fce76d879ad66016960a5a31c9a59cea0", + "6f1c7740640a6e16a4d8d72ee38b4776b06761861b1dcd5d5b2e4475e9254f26", + "1dbadb5645ddaf6194cd3b43e0e78bdc4a239e7f40221755a1842db0a1cd41cb", + "2f3b569a83403410deea36bc0a7a4787b8d45f19a68bf7f48cc2ad9687fe372e", + "647cbd8fc22dcf89113528b50f0e8ba596b6de99a935b884b4a8ba45a3ce3511", + "e14132aad6b9efddfbd799a03fdb80e503cc411dc54611f5abb3aa31be92b0d6", + "fab3f54b56d0d22f55058fa8b97b98bc9a82291d95e9b4c1e743ee6e624edb77", + "2cb6b3ff8aa01f66a866758592db29ffa9f33c32372b701df44c4af0d5640611", + "4cce17399df4b3a2919b3fd84fd96f726a904a9ee1d97154d63dbba1bd9fd6f8", + "df13cd95cb124322a71439a3626a6ebbf575b6b67f48971c3d4209ef19c3e6c4", + "b9e34794bd234de301e1b7285bc82b71d321556e1c34cd2c50cfa4195350584d", + "2b066cdabc75e3b3bb39e0f3223d42f51ada53410930282d31fa950dc3f02a7b", + "943aeebf4f8eb88c19eb2a9fa136f090b565846e57f6c9d37aee2855d9e40910", + "817005f82d3c22fb2f8f2a53904670593b48fbd2881b2e7a4aeb1abb050e556a", + "be62fbf8945f3f6af5f9c49d3efacc56a936b84d57881ef491a00fad61b52982", + "acb745c34f4ef963c27cc4cb571a83501ef98c48171280bc344fbda738312a71", + "a551fc2cbf891acbadd5384634611277052ab24cfb3e43e14e85c50d63a27c5e", + "5ed6b07062002c32c8004f81e9a232a9584f48fb840b67a668416ccea423dee6", + "c10d7491904cdf7d1c4b7cadd0621df53b7180d45d54169c408cceaae275b670", + "6fe99b88f9d942260826f543d05b098bc9481787de8c8cad17aa1b54e193f8d1", + "03381958385164dd06735e7d11f1a7a0aa24db4c915ec99e50e1c0d06b96a9b6", + "2caf84586505f14790d9a05bfb913b202647c44a9339fa76b0bedb614a73fcb1", + "3647591067037997d25a6d2155edfc7835ec7fedbb61c99c8509859208d2ad99", + "8add2be6f919defdda1fe9eec6f10178db617a7047d8f97dda5f81b9c1bbc3c7", + "6e9a65aff0495b35d3e8423c90be47932b4d2c6ea11a2bd821b6d38034629094", + "43d42dc2b93571468b93160cf74b4956e93ed9edb5109e52cab2fdbff1e0570c", + "410299f10fec96e81f96762102b713fc854877fe87de81b8812f27aa776a2d03", + "4583a182b241e62df787fb345c55aa7deab12e398c889d64771dc41fa1785d2c", + "efb98dd89cd1523f7b6a3db2259b6240b4d49e5851583b1c55990b5b8bea252c", + "0115a6a7ed33d451c00bdf46e761e419c423b4427611da8f8d4238aff14139b0", + "47e0803552e6282b0cbac4e8946c11be768f6f7e5c4926067f71e9151c619246", + "71f61bb31cf0187983b28b758c00ecb15bf2dcb1f151433187a7cac7ff005863", + "abc29e1ee941a02a509d820bbc87c1d6f325a1b820da4e6b0db8b6619bfdc74f", + "32c8a57c8ba9d37024d77c0a25a6fbc97341537b9bc52260feb40db950c48497", + "916f9057579e1970545528c341a73cb144bd9c5afed89d128b76ba97137f304a", + "6536f0b22f1332a3045bf33004a867d13cacd63bbf97cc80c0cb74fde7124b42", + "a06428d6233613d30f342f97418ca824450aac824089b98d556d558928f06023", + "da6728495ae9bcb6007a1a89499a63c2dd6bcac4735f7e3a4f3667344b6f11d0", + "918ac8ef1d70b159590f3e02fcf95abff094713ffda97666c963bf4492824147", + "e927294a9d64299b0b239525ab8728f8227db1536e10992932325054cf4e0728", + "75afd0ef4a96f1731c1ab18634d8fe78eba15c128a8dc93244a473184e08ea69", + "3e05eba76c1b15871067179da463f7a6dab8b85a9f8d9147c14299bc282b653a", + "287a02bed5f0fef1310f77ffb89152457ebf4448679aadfe1ff6c498ea1391b1", + "bf4eba0a8abcacf6a54514ce7c33ab5b5b2fff7b4de15fbaaea6f5e1336d6f5b", + "1af056f92c22bb34963067202673c9a093521260c8c7c348ea4405ea6c32d6f2", + "b7202061d082891dfd387f37fc224e5e49a2291b44fa6ca892936c6812b57362", + "4290f9fc2db8b24de4ac96ad8ad4ffebdca2dbd0248e7563c035403c4bce59d1", + "0eb3cfc47addc1df5a2242298ee44882c8978b91ea8887e022e31a97bd148379", + "e8c9b84fbb13ca6031e9ba45f070c6c667816f7679fc5b762c361c9532ebbf17", + "488feea0d631839d74abb8059bea6f2d23d98f9ca01a6d0ff9537486de2f9931", + "5d8050dad736bd34b07f35a56d49b20e0b18ec5b39141539157521c0641a9fdf", + "26589e771e1a10dc8e55bff687190e35d9713205403ee6cfbefeb18051873ffc", + "e6829efc3004d8b98dff64077ce88ef1c4293b410cd16d5f6e3617718a878468", + "20bc50d839c5cd4dcc294a9973748df0086168a253a009155f5c6857e4978d9f", + "3c23d031cc01a51e77818c1fdca288b4dd7878e3ad333332cdea99bc27b36f0a", + "7592d31efbb5c42d110beb9065e6132c18c8339a713598d2f5b5fde1321c9181", + "770f37d4468b115cc0a8a27e9b7c583fcb12e1a185785681adbb7828d60e9177", + "e4959ec71f512118e7b383b69c8c694006a99dfec4fe8ef0b40bdce32cc6db22", + "d2be840d4d921ff60d94b9394f0e4bd212a2436aa9f02c9f92a87215ede2a552", + "0b6ad6733d03e9605b53ef9b31b4d5d841fde0f126c1c90b5a5da1ff00617e16", + "8e2708ce33f863bf12c41800ed87e7b69bda26d61764115c4acc97ab63225589", + "f42be30de0cf4c82303f03d335f944dd961c5429d6f08e76170810f20073690d", + "26ad9899f63cb8c5a46af8b49728ae3dc0b54a5daacaa578f1b89f352db9d687", + "43c1daa57b4520cff6db35ed2ddd6b22576474936a6f9e006fa86f64fbaff26a", + "4cb09945d24c011f01d7465c08e211a2c9c214116e19a4c8d70d9e60d88c7709", + "9e0a42b4b7227d681349ad81bc9d38501f857419517e64b5e1dafb1fd9413242", + "09ce5cb5ae1120b639f441de931d58a65b998650172212107e00cf9b14834d65", + "26b2582000a334e8d502bf891136d4b0eaf6534e0d9d9df24cc9c9cf176147fc", + "817a7e9ce07e45eb26fb02985c5f730be2638878f1a6aa54a73ec95b2cea1681", + "8f4443c15e08eb809ff81968942d177d60bdf9b218cd8dbad429589b929f897b", + "341c37869d9bdb6d317365a3345d4a4b6b7d00dd6f94386643be62a4dc44a4e7", + "7922ec1ceb6682a775ac6eb29cdcbcb4b4d03f21cc65234f83ca4f835008301d", + "ede7d155a5c90f799dd734ac5657ddd4e0c2b29dda3220f3884e6c76a1d2cd1b", + "c211585c799c7487a2c5d9e87e5ce0f1c59e094678f3074f5ebfc9ce193a98b1", + "ce6cda88f12cbd8c8f80463a0faed781d48dbef1c57a827efcc0098295981837", + "f9da0ca90e833e583b669f26ad58b91e29f69b1ce4768d8f977216996ae7ee88", + "aef4d891c2c135bde4833033ca185e4cb94caae1cf3e6f09a6223e6365061ad7", + "1a8ac1763898b28462220795463632db2b6285b422749a327db26c94e3b83aa8", + "d7d523553c945dbea7f4aa5317a3a54ce166611fa4b667cf106f3f3262288ffa", + "b4a2e2630c00dfff08c92db5fc9d10bcb342d598eee439c88d6cf67812d34c36", + "c1a3b7c5cc495eea987ac468cea3a28747b38cdb58e8a25d9106dc8daca8fc9e", + "dbb3b1d62bbaa4bc7ee534d55c758320794bd5d103fde83d2845f57db4c90dd9", + "f4caf6ab55da3c3857b3c8d1691e318490b0a1201412312bdeb7ac2b86441c8f", + "4c9101f55aea6d983718890ab78ae2b6e6178316f6264f4fed804c3d57e20080", + "4175fee1bfdbc38054a3fdd35eb77c5be50de705e6b05d9a3894ca369725f0f0", + "60f9bbec40fe78a93a6cd823951efe0c36d3b007b02ea0f7e39278542b0a2983", + "b339632498f0cf1074b44132277d689984ac63d64573d2674a4bee76a7377d04", + "7bc2ed89423d5c2b35fbc839b66ec43bbfd4aa9af265ce4a1c11396b1af4cc0b", + "36e51808dc7ad583145604537e0541ea1aea15134184052a4fe995c5b683de01", + "2dbea298e7023f871ee308b794c3525578b6b0c06055cdc33c4a2eb411e9b524", + "1110cb8d87924d4818a1c17981ca120fc050ab695567be2a88f0da7809407cf4", + "362d65a26ecadcf9050c300140cc2e252af1c2d4301c52cba803cc40c7e31f0d", + "863cf875b7535ba16c6aa1903ffc1b09e571ced08b4bce1978a36911c24fe623", + "c0dff770704ee27a56cc1044e13b180d4ac5843e6ac13ae066b497786333e3a2", + "830ce8932feaef4f61f13316a28122e72e3ce7ac065a21a3bccded5476373683", + "221ef4ae991beabdae08a798a49eae3b7220336bbb09c7dd08fb7e114f2b7531", + "23eb835544e07ed558ee4d61cd44458f3e44c2b470ca8227fea9601b5d9b2879", + "61508b2bd3d629164d536c55abd6ff169f82145c002fd72e02b6433f2905c92d", + "58b5177a1e7622820b6b04134144c69f340934d56af25dd5b224d4dcb89be2e0", } -const ropstenPreverifiedHeight uint64 = 11564160 +const ropstenPreverifiedHeight uint64 = 11620608 From 3884f22e2e8f01580ac2ea8e75071bfef0c2a5e9 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Wed, 15 Dec 2021 22:19:10 +0000 Subject: [PATCH 068/261] Check upgrade/downgrade of database schema version to prevent accidental upgrade, remove migrations (#3133) (#3134) * Check upgrade/downgrade * Remove old migrations * Fix compilation * Fix lint Co-authored-by: Alexey Sharp Co-authored-by: Alex Sharp Co-authored-by: Alexey Sharp Co-authored-by: Alex Sharp --- cmd/hack/hack.go | 140 ----------- migrations/fix_sequences.go | 41 ---- migrations/header_prefix.go | 177 ------------- migrations/header_prefix_test.go | 116 --------- migrations/migrations.go | 34 ++- migrations/prune.go | 89 ------- migrations/receipt_cbor.go | 409 ------------------------------- migrations/receipt_repair.go | 183 -------------- migrations/remove_clique.go | 36 --- migrations/set_prune_type.go | 41 ---- 10 files changed, 28 insertions(+), 1238 deletions(-) delete mode 100644 migrations/fix_sequences.go delete mode 100644 migrations/header_prefix.go delete mode 100644 migrations/header_prefix_test.go delete mode 100644 migrations/prune.go delete mode 100644 migrations/receipt_cbor.go delete mode 100644 migrations/receipt_repair.go delete mode 100644 migrations/remove_clique.go delete mode 100644 migrations/set_prune_type.go diff --git a/cmd/hack/hack.go b/cmd/hack/hack.go index 3579cd2e1e6..0f73fa5d896 100644 --- a/cmd/hack/hack.go +++ b/cmd/hack/hack.go @@ -55,7 +55,6 @@ import ( "github.com/ledgerwatch/erigon/eth/stagedsync/stages" "github.com/ledgerwatch/erigon/ethdb" "github.com/ledgerwatch/erigon/ethdb/cbor" - "github.com/ledgerwatch/erigon/migrations" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/rlp" "github.com/ledgerwatch/erigon/turbo/trie" @@ -3883,142 +3882,6 @@ func scanReceipts2(chaindata string) error { return nil } -func scanReceipts(chaindata string, block uint64) error { - f, err := os.Create("fixed.txt") - if err != nil { - return err - } - defer f.Close() - w := bufio.NewWriter(f) - defer w.Flush() - db := mdbx.MustOpen(chaindata) - defer db.Close() - tx, err := db.BeginRw(context.Background()) - if err != nil { - return err - } - defer tx.Rollback() - blockNum, err := changeset.AvailableFrom(tx) - if err != nil { - return err - } - if block > blockNum { - blockNum = block - } - - chainConfig := tool.ChainConfig(tx) - vmConfig := vm.Config{} - noOpWriter := state.NewNoopWriter() - var buf bytes.Buffer - fixedCount := 0 - logInterval := 30 * time.Second - logEvery := time.NewTicker(logInterval) - var key [8]byte - var v []byte - for ; true; blockNum++ { - select { - default: - case <-logEvery.C: - log.Info("Commit", "block", blockNum, "fixed", fixedCount) - tx.Commit() - if tx, err = db.BeginRw(context.Background()); err != nil { - return err - } - } - var hash common.Hash - if hash, err = rawdb.ReadCanonicalHash(tx, blockNum); err != nil { - return err - } - if hash == (common.Hash{}) { - break - } - binary.BigEndian.PutUint64(key[:], blockNum) - if v, err = tx.GetOne(kv.Receipts, key[:]); err != nil { - return err - } - var receipts types.Receipts - if err = cbor.Unmarshal(&receipts, bytes.NewReader(v)); err == nil { - broken := false - for _, receipt := range receipts { - if receipt.CumulativeGasUsed < 10000 { - broken = true - break - } - } - if !broken { - continue - } - } else { - // Receipt is using old CBOR encoding - var oldReceipts migrations.OldReceipts - if err = cbor.Unmarshal(&oldReceipts, bytes.NewReader(v)); err != nil { - return err - } - var body *types.Body - if chainConfig.IsBerlin(blockNum) { - body = rawdb.ReadBodyWithTransactions(tx, hash, blockNum) - } - receipts = make(types.Receipts, len(oldReceipts)) - for i, oldReceipt := range oldReceipts { - receipts[i] = new(types.Receipt) - receipts[i].PostState = oldReceipt.PostState - receipts[i].Status = oldReceipt.Status - receipts[i].CumulativeGasUsed = oldReceipt.CumulativeGasUsed - if body != nil { - receipts[i].Type = body.Transactions[i].Type() - } - } - buf.Reset() - if err = cbor.Marshal(&buf, receipts); err != nil { - return err - } - if err = tx.Put(kv.Receipts, common.CopyBytes(key[:]), common.CopyBytes(buf.Bytes())); err != nil { - return err - } - fixedCount++ - continue - } - var block *types.Block - if block, _, err = rawdb.ReadBlockWithSenders(tx, hash, blockNum); err != nil { - return err - } - - dbstate := state.NewPlainState(tx, block.NumberU64()-1) - intraBlockState := state.New(dbstate) - - getHeader := func(hash common.Hash, number uint64) *types.Header { return rawdb.ReadHeader(tx, hash, number) } - contractHasTEVM := ethdb.GetHasTEVM(tx) - receipts1, err1 := runBlock(intraBlockState, noOpWriter, noOpWriter, chainConfig, getHeader, contractHasTEVM, block, vmConfig) - if err1 != nil { - return err1 - } - fix := true - if chainConfig.IsByzantium(blockNum) { - receiptSha := types.DeriveSha(receipts1) - if receiptSha != block.Header().ReceiptHash { - fmt.Printf("(retrace) mismatched receipt headers for block %d: %x, %x\n", block.NumberU64(), receiptSha, block.Header().ReceiptHash) - fix = false - } - } - if fix { - // All good, we can fix receipt record - buf.Reset() - err := cbor.Marshal(&buf, receipts1) - if err != nil { - return fmt.Errorf("encode block receipts for block %d: %w", blockNum, err) - } - if err = tx.Put(kv.Receipts, key[:], buf.Bytes()); err != nil { - return fmt.Errorf("writing receipts for block %d: %w", blockNum, err) - } - if _, err = w.Write([]byte(fmt.Sprintf("%d\n", blockNum))); err != nil { - return err - } - fixedCount++ - } - } - return tx.Commit() -} - func runBlock(ibs *state.IntraBlockState, txnWriter state.StateWriter, blockWriter state.StateWriter, chainConfig *params.ChainConfig, getHeader func(hash common.Hash, number uint64) *types.Header, contractHasTEVM func(common.Hash) (bool, error), block *types.Block, vmConfig vm.Config) (types.Receipts, error) { header := block.Header() @@ -4227,9 +4090,6 @@ func main() { case "scanTxs": err = scanTxs(*chaindata) - case "scanReceipts": - err = scanReceipts(*chaindata, uint64(*block)) - case "scanReceipts2": err = scanReceipts2(*chaindata) diff --git a/migrations/fix_sequences.go b/migrations/fix_sequences.go deleted file mode 100644 index a890c045b60..00000000000 --- a/migrations/fix_sequences.go +++ /dev/null @@ -1,41 +0,0 @@ -package migrations - -import ( - "context" - - "github.com/ledgerwatch/erigon-lib/kv" -) - -var oldSequences = map[string]string{ - kv.EthTx: "eth_tx", -} - -var fixSequences = Migration{ - Name: "fix_sequences", - Up: func(db kv.RwDB, tmpdir string, progress []byte, BeforeCommit Callback) (err error) { - tx, err := db.BeginRw(context.Background()) - if err != nil { - return err - } - defer tx.Rollback() - - for bkt, oldbkt := range oldSequences { - seq, getErr := tx.GetOne(kv.Sequence, []byte(oldbkt)) - if getErr != nil { - return getErr - } - - if seq != nil { - putErr := tx.Put(kv.Sequence, []byte(bkt), seq) - if putErr != nil { - return putErr - } - } - } - - if err := BeforeCommit(tx, nil, true); err != nil { - return err - } - return tx.Commit() - }, -} diff --git a/migrations/header_prefix.go b/migrations/header_prefix.go deleted file mode 100644 index fc9a809ae89..00000000000 --- a/migrations/header_prefix.go +++ /dev/null @@ -1,177 +0,0 @@ -package migrations - -import ( - "bytes" - "context" - "fmt" - - "github.com/ledgerwatch/erigon-lib/etl" - "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/common/dbutils" -) - -var headerPrefixToSeparateBuckets = Migration{ - Name: "header_prefix_to_separate_buckets", - Up: func(db kv.RwDB, tmpdir string, progress []byte, BeforeCommit Callback) (err error) { - tx, err := db.BeginRw(context.Background()) - if err != nil { - return err - } - defer tx.Rollback() - - exists, err := tx.ExistsBucket(kv.HeaderPrefixOld) - if err != nil { - return err - } - if !exists { - if err := BeforeCommit(tx, nil, true); err != nil { - return err - } - return tx.Commit() - } - - if err = tx.ClearBucket(kv.HeaderCanonical); err != nil { - return err - } - if err = tx.ClearBucket(kv.HeaderTD); err != nil { - return err - } - logPrefix := "split_header_prefix_bucket" - const loadStep = "load" - - canonicalCollector, err := etl.NewCollectorFromFiles(logPrefix, tmpdir+"canonical") - if err != nil { - return err - } - tdCollector, err := etl.NewCollectorFromFiles(logPrefix, tmpdir+"td") - if err != nil { - return err - } - headersCollector, err := etl.NewCollectorFromFiles(logPrefix, tmpdir+"headers") - if err != nil { - return err - } - - switch string(progress) { - case "": - // can't use files if progress field not set, clear them - if canonicalCollector != nil { - canonicalCollector.Close() - canonicalCollector = nil - } - - if tdCollector != nil { - tdCollector.Close() - tdCollector = nil - } - if headersCollector != nil { - headersCollector.Close() - headersCollector = nil - } - case loadStep: - if headersCollector == nil || canonicalCollector == nil || tdCollector == nil { - return ErrMigrationETLFilesDeleted - } - defer func() { - // don't clean if error or panic happened - if err != nil { - return - } - if rec := recover(); rec != nil { - panic(rec) - } - canonicalCollector.Close() - tdCollector.Close() - headersCollector.Close() - }() - goto LoadStep - } - - canonicalCollector = etl.NewCriticalCollector(logPrefix, tmpdir+"canonical", etl.NewSortableBuffer(etl.BufferOptimalSize*4)) - tdCollector = etl.NewCriticalCollector(logPrefix, tmpdir+"td", etl.NewSortableBuffer(etl.BufferOptimalSize*4)) - headersCollector = etl.NewCriticalCollector(logPrefix, tmpdir+"headers", etl.NewSortableBuffer(etl.BufferOptimalSize*4)) - defer func() { - // don't clean if error or panic happened - if err != nil { - return - } - if rec := recover(); rec != nil { - panic(rec) - } - canonicalCollector.Close() - tdCollector.Close() - headersCollector.Close() - }() - - err = tx.ForEach(kv.HeaderPrefixOld, []byte{}, func(k, v []byte) error { - var innerErr error - switch { - case IsHeaderKey(k): - innerErr = headersCollector.Collect(k, v) - case IsHeaderTDKey(k): - innerErr = tdCollector.Collect(bytes.TrimSuffix(k, HeaderTDSuffix), v) - case IsHeaderHashKey(k): - innerErr = canonicalCollector.Collect(bytes.TrimSuffix(k, HeaderHashSuffix), v) - default: - return fmt.Errorf("incorrect header prefix key: %v", common.Bytes2Hex(k)) - } - if innerErr != nil { - return innerErr - } - return nil - }) - if err = tx.DropBucket(kv.HeaderPrefixOld); err != nil { - return err - } - - LoadStep: - // Now transaction would have been re-opened, and we should be re-using the space - if err = canonicalCollector.Load(tx, kv.HeaderCanonical, etl.IdentityLoadFunc, etl.TransformArgs{}); err != nil { - return fmt.Errorf("loading the transformed data back into the storage table: %w", err) - } - if err = tdCollector.Load(tx, kv.HeaderTD, etl.IdentityLoadFunc, etl.TransformArgs{}); err != nil { - return fmt.Errorf("loading the transformed data back into the acc table: %w", err) - } - if err = headersCollector.Load(tx, kv.Headers, etl.IdentityLoadFunc, etl.TransformArgs{}); err != nil { - return fmt.Errorf("loading the transformed data back into the acc table: %w", err) - } - if err := BeforeCommit(tx, nil, true); err != nil { - return err - } - return tx.Commit() - }, -} - -func IsHeaderKey(k []byte) bool { - l := common.BlockNumberLength + common.HashLength - if len(k) != l { - return false - } - - return !IsHeaderHashKey(k) && !IsHeaderTDKey(k) -} - -func IsHeaderTDKey(k []byte) bool { - l := common.BlockNumberLength + common.HashLength + 1 - return len(k) == l && bytes.Equal(k[l-1:], HeaderTDSuffix) -} - -// headerHashKey = headerPrefix + num (uint64 big endian) + headerHashSuffix -func HeaderHashKey(number uint64) []byte { - return append(dbutils.EncodeBlockNumber(number), HeaderHashSuffix...) -} - -func CheckCanonicalKey(k []byte) bool { - return len(k) == 8+len(HeaderHashSuffix) && bytes.Equal(k[8:], HeaderHashSuffix) -} - -func IsHeaderHashKey(k []byte) bool { - l := common.BlockNumberLength + 1 - return len(k) == l && bytes.Equal(k[l-1:], HeaderHashSuffix) -} - -var ( - HeaderTDSuffix = []byte("t") // block_num_u64 + hash + headerTDSuffix -> td - HeaderHashSuffix = []byte("n") // block_num_u64 + headerHashSuffix -> hash -) diff --git a/migrations/header_prefix_test.go b/migrations/header_prefix_test.go deleted file mode 100644 index c9c06b5af9d..00000000000 --- a/migrations/header_prefix_test.go +++ /dev/null @@ -1,116 +0,0 @@ -package migrations - -import ( - "bytes" - "context" - "encoding/binary" - "strconv" - "testing" - - "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/erigon-lib/kv/memdb" - "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/common/dbutils" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestHeaderPrefix(t *testing.T) { - require := require.New(t) - db := memdb.NewTestDB(t) - - err := db.Update(context.Background(), func(tx kv.RwTx) error { - err := tx.CreateBucket(kv.HeaderPrefixOld) - if err != nil { - return err - } - for i := uint64(0); i < 10; i++ { - //header - err = tx.Put(kv.HeaderPrefixOld, dbutils.HeaderKey(i, common.Hash{uint8(i)}), []byte("header "+strconv.Itoa(int(i)))) - require.NoError(err) - //canonical - err = tx.Put(kv.HeaderPrefixOld, HeaderHashKey(i), common.Hash{uint8(i)}.Bytes()) - require.NoError(err) - err = tx.Put(kv.HeaderPrefixOld, append(dbutils.HeaderKey(i, common.Hash{uint8(i)}), HeaderTDSuffix...), []byte{uint8(i)}) - require.NoError(err) - } - return nil - }) - require.NoError(err) - - migrator := NewMigrator(kv.ChainDB) - migrator.Migrations = []Migration{headerPrefixToSeparateBuckets} - err = migrator.Apply(db, t.TempDir()) - require.NoError(err) - - num := 0 - err = db.View(context.Background(), func(tx kv.Tx) error { - return tx.ForEach(kv.HeaderCanonical, []byte{}, func(k, v []byte) error { - require.Len(k, 8) - bytes.Equal(v, common.Hash{uint8(binary.BigEndian.Uint64(k))}.Bytes()) - num++ - return nil - }) - }) - require.NoError(err) - require.Equal(num, 10) - - num = 0 - err = db.View(context.Background(), func(tx kv.Tx) error { - return tx.ForEach(kv.HeaderTD, []byte{}, func(k, v []byte) error { - require.Len(k, 40) - bytes.Equal(v, []byte{uint8(binary.BigEndian.Uint64(k))}) - num++ - return nil - }) - }) - require.NoError(err) - require.Equal(num, 10) - - num = 0 - err = db.View(context.Background(), func(tx kv.Tx) error { - return tx.ForEach(kv.Headers, []byte{}, func(k, v []byte) error { - require.Len(k, 40) - bytes.Equal(v, []byte("header "+strconv.Itoa(int(binary.BigEndian.Uint64(k))))) - num++ - return nil - }) - }) - require.NoError(err) - require.Equal(num, 10) - -} - -func TestHeaderTypeDetection(t *testing.T) { - // good input - headerHashKey := common.Hex2Bytes("00000000000000006e") - assert.False(t, IsHeaderKey(headerHashKey)) - assert.False(t, IsHeaderTDKey(headerHashKey)) - assert.True(t, IsHeaderHashKey(headerHashKey)) - - headerKey := common.Hex2Bytes("0000000000004321ed7240d411782ae438adfd85f7edad373cea722318c6e7f5f5b30f9abc9b36fd") - assert.True(t, IsHeaderKey(headerKey)) - assert.False(t, IsHeaderTDKey(headerKey)) - assert.False(t, IsHeaderHashKey(headerKey)) - - headerTdKey := common.Hex2Bytes("0000000000004321ed7240d411782ae438adfd85f7edad373cea722318c6e7f5f5b30f9abc9b36fd74") - assert.False(t, IsHeaderKey(headerTdKey)) - assert.True(t, IsHeaderTDKey(headerTdKey)) - assert.False(t, IsHeaderHashKey(headerTdKey)) - - // bad input - emptyKey := common.Hex2Bytes("") - assert.False(t, IsHeaderKey(emptyKey)) - assert.False(t, IsHeaderTDKey(emptyKey)) - assert.False(t, IsHeaderHashKey(emptyKey)) - - tooLongKey := common.Hex2Bytes("0000000000004321ed7240d411782ae438adfd85f7edad373cea722318c6e7f5f5b30f9abc9b36fd0000000000004321ed7240d411782ae438adfd85f7edad373cea722318c6e7f5f5b30f9abc9b36fd0000000000004321ed7240d411782ae438adfd85f7edad373cea722318c6e7f5f5b30f9abc9b36fd0000000000004321ed7240d411782ae438adfd85f7edad373cea722318c6e7f5f5b30f9abc9b36fd") - assert.False(t, IsHeaderKey(tooLongKey)) - assert.False(t, IsHeaderTDKey(tooLongKey)) - assert.False(t, IsHeaderHashKey(tooLongKey)) - - notRelatedInput := common.Hex2Bytes("alex") - assert.False(t, IsHeaderKey(notRelatedInput)) - assert.False(t, IsHeaderTDKey(notRelatedInput)) - assert.False(t, IsHeaderHashKey(notRelatedInput)) -} diff --git a/migrations/migrations.go b/migrations/migrations.go index cec0d5a412c..1983d26b603 100644 --- a/migrations/migrations.go +++ b/migrations/migrations.go @@ -31,12 +31,7 @@ import ( // - write test - and check that it's safe to apply same migration twice var migrations = map[kv.Label][]Migration{ kv.ChainDB: { - headerPrefixToSeparateBuckets, - removeCliqueBucket, dbSchemaVersion, - fixSequences, - storageMode, - setPruneType, }, kv.TxPoolDB: {}, kv.SentryDB: {}, @@ -127,10 +122,37 @@ func (m *Migrator) Apply(db kv.RwDB, datadir string) error { } var applied map[string][]byte + var existingVersion []byte if err := db.View(context.Background(), func(tx kv.Tx) error { var err error applied, err = AppliedMigrations(tx, false) - return err + if err != nil { + return fmt.Errorf("reading applied migrations: %w", err) + } + existingVersion, err = tx.GetOne(kv.DatabaseInfo, kv.DBSchemaVersionKey) + if err != nil { + return fmt.Errorf("reading DB schema version: %w", err) + } + if len(existingVersion) != 0 && len(existingVersion) != 12 { + return fmt.Errorf("incorrect length of DB schema version: %d", len(existingVersion)) + } + if len(existingVersion) == 12 { + major := binary.BigEndian.Uint32(existingVersion) + minor := binary.BigEndian.Uint32(existingVersion[4:]) + if major > kv.DBSchemaVersion.Major { + return fmt.Errorf("cannot downgrade major DB version from %d to %d", major, kv.DBSchemaVersion.Major) + } else if major == kv.DBSchemaVersion.Major { + if minor > kv.DBSchemaVersion.Minor { + return fmt.Errorf("cannot downgrade minor DB version from %d.%d to %d.%d", major, minor, kv.DBSchemaVersion.Major, kv.DBSchemaVersion.Major) + } + } else { + // major < kv.DBSchemaVersion.Major + if kv.DBSchemaVersion.Major-major > 1 { + return fmt.Errorf("cannot upgrade major DB version for more than 1 version from %d to %d, use integration tool if you know what you are doing", major, kv.DBSchemaVersion.Major) + } + } + } + return nil }); err != nil { return err } diff --git a/migrations/prune.go b/migrations/prune.go deleted file mode 100644 index 72e31889be5..00000000000 --- a/migrations/prune.go +++ /dev/null @@ -1,89 +0,0 @@ -package migrations - -import ( - "context" - - "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/erigon/common/math" - "github.com/ledgerwatch/erigon/ethdb/prune" - "github.com/ledgerwatch/erigon/params" -) - -var storageMode = Migration{ - Name: "storage_mode", - Up: func(db kv.RwDB, tmpdir string, progress []byte, BeforeCommit Callback) (err error) { - tx, err := db.BeginRw(context.Background()) - if err != nil { - return err - } - defer tx.Rollback() - var ( // old db keys - //StorageModeHistory - does node save history. - StorageModeHistory = []byte("smHistory") - //StorageModeReceipts - does node save receipts. - StorageModeReceipts = []byte("smReceipts") - //StorageModeTxIndex - does node save transactions index. - StorageModeTxIndex = []byte("smTxIndex") - //StorageModeCallTraces - does not build index of call traces - StorageModeCallTraces = []byte("smCallTraces") - ) - pm := prune.Mode{Initialised: true} - castToPruneDistance := func(v []byte) prune.Distance { - if len(v) == 1 && v[0] == 2 { - return params.FullImmutabilityThreshold // means, prune enabled - } - return math.MaxUint64 // means, prune disabled - } - { - v, err := tx.GetOne(kv.DatabaseInfo, StorageModeHistory) - if err != nil { - return err - } - if v == nil { // if no records in db - means Erigon just started first time and nothing to migrate. Noop. - if err := BeforeCommit(tx, nil, true); err != nil { - return err - } - return tx.Commit() - } - pm.History = castToPruneDistance(v) - } - { - v, err := tx.GetOne(kv.DatabaseInfo, StorageModeReceipts) - if err != nil { - return err - } - pm.Receipts = castToPruneDistance(v) - } - { - v, err := tx.GetOne(kv.DatabaseInfo, StorageModeTxIndex) - if err != nil { - return err - } - pm.TxIndex = castToPruneDistance(v) - } - { - v, err := tx.GetOne(kv.DatabaseInfo, StorageModeCallTraces) - if err != nil { - return err - } - pm.CallTraces = castToPruneDistance(v) - } - { - v, err := tx.GetOne(kv.DatabaseInfo, kv.StorageModeTEVM) - if err != nil { - return err - } - pm.Experiments.TEVM = len(v) == 1 && v[0] == 1 - } - - err = prune.SetIfNotExist(tx, pm) - if err != nil { - return err - } - - if err := BeforeCommit(tx, nil, true); err != nil { - return err - } - return tx.Commit() - }, -} diff --git a/migrations/receipt_cbor.go b/migrations/receipt_cbor.go deleted file mode 100644 index e57bba6dfb5..00000000000 --- a/migrations/receipt_cbor.go +++ /dev/null @@ -1,409 +0,0 @@ -package migrations - -import ( - "bytes" - "context" - "encoding/binary" - "errors" - pkg2_big "math/big" - "runtime" - "strconv" - "time" - - "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/core/rawdb" - "github.com/ledgerwatch/erigon/core/types" - "github.com/ledgerwatch/erigon/eth/stagedsync/stages" - "github.com/ledgerwatch/erigon/ethdb/cbor" - "github.com/ledgerwatch/log/v3" - - pkg1_common "github.com/ledgerwatch/erigon/common" - codec1978 "github.com/ugorji/go/codec" -) - -// OldReceipt is receipt structure before introduction of Type field -// to be able to read old records -type OldReceipt struct { - // Consensus fields: These fields are defined by the Yellow Paper - PostState []byte `json:"root" codec:"1"` - Status uint64 `json:"status" codec:"2"` - CumulativeGasUsed uint64 `json:"cumulativeGasUsed" gencodec:"required" codec:"3"` -} - -type OldReceipts []*OldReceipt - -var ReceiptCbor = Migration{ - Name: "receipt_cbor", - Up: func(db kv.RwDB, tmpdir string, progress []byte, BeforeCommit Callback) (err error) { - tx, err := db.BeginRw(context.Background()) - if err != nil { - return err - } - defer tx.Rollback() - - genesisBlock, err := rawdb.ReadBlockByNumber(tx, 0) - if err != nil { - return err - } - if genesisBlock == nil { - // Empty database check - if err := BeforeCommit(tx, nil, true); err != nil { - return err - } - return tx.Commit() - } - chainConfig, cerr := rawdb.ReadChainConfig(tx, genesisBlock.Hash()) - if cerr != nil { - return cerr - } - logInterval := 30 * time.Second - logEvery := time.NewTicker(logInterval) - defer logEvery.Stop() - var buf bytes.Buffer - var key [8]byte - var v []byte - var to uint64 - if to, err = stages.GetStageProgress(tx, stages.Execution); err != nil { - return err - } - for blockNum := uint64(1); blockNum <= to; blockNum++ { - binary.BigEndian.PutUint64(key[:], blockNum) - if v, err = tx.GetOne(kv.Receipts, key[:]); err != nil { - return err - } - if v == nil { - continue - } - select { - default: - case <-logEvery.C: - log.Info("Scanned receipts up to", "block", blockNum) - } - var receipts types.Receipts - var oldReceipts OldReceipts - if err = cbor.Unmarshal(&oldReceipts, bytes.NewReader(v)); err != nil { - continue - } - - var blockHash common.Hash - if blockHash, err = rawdb.ReadCanonicalHash(tx, blockNum); err != nil { - return err - } - var body *types.Body - if chainConfig.IsBerlin(blockNum) { - body = rawdb.ReadBodyWithTransactions(tx, blockHash, blockNum) - } - receipts = make(types.Receipts, len(oldReceipts)) - for i, oldReceipt := range oldReceipts { - receipts[i] = new(types.Receipt) - receipts[i].PostState = oldReceipt.PostState - receipts[i].Status = oldReceipt.Status - receipts[i].CumulativeGasUsed = oldReceipt.CumulativeGasUsed - if body != nil { - receipts[i].Type = body.Transactions[i].Type() - } - } - buf.Reset() - if err = cbor.Marshal(&buf, receipts); err != nil { - return err - } - if err = tx.Put(kv.Receipts, common.CopyBytes(key[:]), common.CopyBytes(buf.Bytes())); err != nil { - return err - } - } - if err := BeforeCommit(tx, nil, true); err != nil { - return err - } - return tx.Commit() - }, -} - -const ( - // ----- value types used ---- - codecSelferValueTypeArray2 = 10 - codecSelferValueTypeMap2 = 9 - codecSelferValueTypeNil2 = 1 -) - -var ( - errCodecSelferOnlyMapOrArrayEncodeToStruct2 = errors.New(`only encoded map or array can be decoded into a struct`) -) - -type codecSelfer2 struct{} - -func init() { - if codec1978.GenVersion != 19 { - _, file, _, _ := runtime.Caller(0) - ver := strconv.FormatInt(int64(codec1978.GenVersion), 10) - panic(errors.New("codecgen version mismatch: current: 19, need " + ver + ". Re-generate file: " + file)) - } - if false { // reference the types, but skip this branch at build/run time - var _ pkg1_common.Address - var _ pkg2_big.Int - } -} - -func (x *OldReceipt) CodecEncodeSelf(e *codec1978.Encoder) { - var h codecSelfer2 - z, r := codec1978.GenHelperEncoder(e) - _, _, _ = h, z, r - if x == nil { - r.EncodeNil() - } else { - yy2arr2 := z.EncBasicHandle().StructToArray - _ = yy2arr2 - z.EncWriteArrayStart(3) - z.EncWriteArrayElem() - if x.PostState == nil { - r.EncodeNil() - } else { - r.EncodeStringBytesRaw([]byte(x.PostState)) - } // end block: if x.PostState slice == nil - z.EncWriteArrayElem() - r.EncodeUint(uint64(x.Status)) - z.EncWriteArrayElem() - r.EncodeUint(uint64(x.CumulativeGasUsed)) - z.EncWriteArrayEnd() - } -} - -func (x *OldReceipt) CodecDecodeSelf(d *codec1978.Decoder) { - var h codecSelfer2 - z, r := codec1978.GenHelperDecoder(d) - _, _, _ = h, z, r - yyct2 := r.ContainerType() - if yyct2 == codecSelferValueTypeNil2 { - *(x) = OldReceipt{} - } else if yyct2 == codecSelferValueTypeMap2 { - yyl2 := z.DecReadMapStart() - if yyl2 == 0 { - } else { - x.codecDecodeSelfFromMap(yyl2, d) - } - z.DecReadMapEnd() - } else if yyct2 == codecSelferValueTypeArray2 { - yyl2 := z.DecReadArrayStart() - if yyl2 != 0 { - x.codecDecodeSelfFromArray(yyl2, d) - } - z.DecReadArrayEnd() - } else { - panic(errCodecSelferOnlyMapOrArrayEncodeToStruct2) - } -} - -func (x *OldReceipt) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { - var h codecSelfer2 - z, r := codec1978.GenHelperDecoder(d) - _, _, _ = h, z, r - var yyhl3 bool = l >= 0 - for yyj3 := 0; ; yyj3++ { - if yyhl3 { - if yyj3 >= l { - break - } - } else { - if z.DecCheckBreak() { - break - } - } - z.DecReadMapElemKey() - yys3 := z.StringView(r.DecodeStringAsBytes()) - z.DecReadMapElemValue() - switch yys3 { - case "1": - x.PostState = r.DecodeBytes(([]byte)(x.PostState), false) - case "2": - x.Status = (uint64)(r.DecodeUint64()) - case "3": - x.CumulativeGasUsed = (uint64)(r.DecodeUint64()) - default: - z.DecStructFieldNotFound(-1, yys3) - } // end switch yys3 - } // end for yyj3 -} - -func (x *OldReceipt) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { - var h codecSelfer2 - z, r := codec1978.GenHelperDecoder(d) - _, _, _ = h, z, r - var yyj8 int - var yyb8 bool - var yyhl8 bool = l >= 0 - yyj8++ - if yyhl8 { - yyb8 = yyj8 > l - } else { - yyb8 = z.DecCheckBreak() - } - if yyb8 { - z.DecReadArrayEnd() - return - } - z.DecReadArrayElem() - x.PostState = r.DecodeBytes(([]byte)(x.PostState), false) - yyj8++ - if yyhl8 { - yyb8 = yyj8 > l - } else { - yyb8 = z.DecCheckBreak() - } - if yyb8 { - z.DecReadArrayEnd() - return - } - z.DecReadArrayElem() - x.Status = (uint64)(r.DecodeUint64()) - yyj8++ - if yyhl8 { - yyb8 = yyj8 > l - } else { - yyb8 = z.DecCheckBreak() - } - if yyb8 { - z.DecReadArrayEnd() - return - } - z.DecReadArrayElem() - x.CumulativeGasUsed = (uint64)(r.DecodeUint64()) - for { - yyj8++ - if yyhl8 { - yyb8 = yyj8 > l - } else { - yyb8 = z.DecCheckBreak() - } - if yyb8 { - break - } - z.DecReadArrayElem() - z.DecStructFieldNotFound(yyj8-1, "") - } -} - -func (x *OldReceipt) IsCodecEmpty() bool { - return !(len(x.PostState) != 0 && x.Status != 0 && x.CumulativeGasUsed != 0 && true) -} - -func (x OldReceipts) CodecEncodeSelf(e *codec1978.Encoder) { - var h codecSelfer2 - z, r := codec1978.GenHelperEncoder(e) - _, _, _ = h, z, r - if x == nil { - r.EncodeNil() - } else { - h.encReceipts((OldReceipts)(x), e) - } // end block: if x slice == nil -} - -func (x *OldReceipts) CodecDecodeSelf(d *codec1978.Decoder) { - var h codecSelfer2 - z, r := codec1978.GenHelperDecoder(d) - _, _, _ = h, z, r - h.decReceipts((*OldReceipts)(x), d) -} - -func (x codecSelfer2) encReceipts(v OldReceipts, e *codec1978.Encoder) { - var h codecSelfer2 - z, r := codec1978.GenHelperEncoder(e) - _, _, _ = h, z, r - if v == nil { - r.EncodeNil() - return - } - z.EncWriteArrayStart(len(v)) - for _, yyv1 := range v { - z.EncWriteArrayElem() - if yyv1 == nil { - r.EncodeNil() - } else { - yyv1.CodecEncodeSelf(e) - } - } - z.EncWriteArrayEnd() -} - -func (x codecSelfer2) decReceipts(v *OldReceipts, d *codec1978.Decoder) { - var h codecSelfer2 - z, r := codec1978.GenHelperDecoder(d) - _, _, _ = h, z, r - - yyv1 := *v - yyh1, yyl1 := z.DecSliceHelperStart() - var yyc1 bool - _ = yyc1 - if yyh1.IsNil { - if yyv1 != nil { - yyv1 = nil - yyc1 = true - } - } else if yyl1 == 0 { - if yyv1 == nil { - yyv1 = []*OldReceipt{} - yyc1 = true - } else if len(yyv1) != 0 { - yyv1 = yyv1[:0] - yyc1 = true - } - } else { - yyhl1 := yyl1 > 0 - var yyrl1 int - _ = yyrl1 - if yyhl1 { - if yyl1 > cap(yyv1) { - yyrl1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 8) - if yyrl1 <= cap(yyv1) { - yyv1 = yyv1[:yyrl1] - } else { - yyv1 = make([]*OldReceipt, yyrl1) - } - yyc1 = true - } else if yyl1 != len(yyv1) { - yyv1 = yyv1[:yyl1] - yyc1 = true - } - } - var yyj1 int - for yyj1 = 0; (yyhl1 && yyj1 < yyl1) || !(yyhl1 || z.DecCheckBreak()); yyj1++ { // bounds-check-elimination - if yyj1 == 0 && yyv1 == nil { - if yyhl1 { - yyrl1 = z.DecInferLen(yyl1, z.DecBasicHandle().MaxInitLen, 8) - } else { - yyrl1 = 8 - } - yyv1 = make([]*OldReceipt, yyrl1) - yyc1 = true - } - yyh1.ElemContainerState(yyj1) - var yydb1 bool - if yyj1 >= len(yyv1) { - yyv1 = append(yyv1, nil) - yyc1 = true - } - if yydb1 { - z.DecSwallow() - } else { - if r.TryNil() { - yyv1[yyj1] = nil - } else { - if yyv1[yyj1] == nil { - yyv1[yyj1] = new(OldReceipt) - } - yyv1[yyj1].CodecDecodeSelf(d) - } - } - } - if yyj1 < len(yyv1) { - yyv1 = yyv1[:yyj1] - yyc1 = true - } else if yyj1 == 0 && yyv1 == nil { - yyv1 = make([]*OldReceipt, 0) - yyc1 = true - } - } - yyh1.End() - if yyc1 { - *v = yyv1 - } -} diff --git a/migrations/receipt_repair.go b/migrations/receipt_repair.go deleted file mode 100644 index d1ee62d594d..00000000000 --- a/migrations/receipt_repair.go +++ /dev/null @@ -1,183 +0,0 @@ -package migrations - -import ( - "bytes" - "context" - "encoding/binary" - "fmt" - "time" - - "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/common/changeset" - "github.com/ledgerwatch/erigon/consensus/ethash" - "github.com/ledgerwatch/erigon/consensus/misc" - "github.com/ledgerwatch/erigon/core" - "github.com/ledgerwatch/erigon/core/rawdb" - "github.com/ledgerwatch/erigon/core/state" - "github.com/ledgerwatch/erigon/core/types" - "github.com/ledgerwatch/erigon/core/vm" - "github.com/ledgerwatch/erigon/ethdb" - "github.com/ledgerwatch/erigon/ethdb/cbor" - "github.com/ledgerwatch/erigon/params" - "github.com/ledgerwatch/log/v3" -) - -func availableReceiptFrom(tx kv.Tx) (uint64, error) { - c, err := tx.Cursor(kv.Receipts) - if err != nil { - return 0, err - } - defer c.Close() - k, _, err := c.First() - if err != nil { - return 0, err - } - if len(k) == 0 { - return 0, nil - } - return binary.BigEndian.Uint64(k), nil -} - -var ReceiptRepair = Migration{ - Name: "receipt_repair", - Up: func(db kv.RwDB, tmpdir string, progress []byte, BeforeCommit Callback) (err error) { - tx, err := db.BeginRw(context.Background()) - if err != nil { - return err - } - defer tx.Rollback() - - blockNum, err := changeset.AvailableFrom(tx) - if err != nil { - return err - } - receiptsFrom, err := availableReceiptFrom(tx) - if err != nil { - return err - } - if receiptsFrom > blockNum { - blockNum = receiptsFrom - } - - genesisBlock, err := rawdb.ReadBlockByNumber(tx, 0) - if err != nil { - return err - } - chainConfig, cerr := rawdb.ReadChainConfig(tx, genesisBlock.Hash()) - if cerr != nil { - return cerr - } - vmConfig := vm.Config{} - noOpWriter := state.NewNoopWriter() - var buf bytes.Buffer - fixedCount := 0 - logInterval := 30 * time.Second - logEvery := time.NewTicker(logInterval) - var key [8]byte - var v []byte - for ; true; blockNum++ { - select { - default: - case <-logEvery.C: - log.Info("Progress", "block", blockNum, "fixed", fixedCount) - } - var hash common.Hash - if hash, err = rawdb.ReadCanonicalHash(tx, blockNum); err != nil { - return err - } - if hash == (common.Hash{}) { - break - } - binary.BigEndian.PutUint64(key[:], blockNum) - if v, err = tx.GetOne(kv.Receipts, key[:]); err != nil { - return err - } - var receipts types.Receipts - if err = cbor.Unmarshal(&receipts, bytes.NewReader(v)); err == nil { - broken := false - for _, receipt := range receipts { - if receipt.CumulativeGasUsed < 10000 { - broken = true - break - } - } - if !broken { - continue - } - } - var block *types.Block - if block, _, err = rawdb.ReadBlockWithSenders(tx, hash, blockNum); err != nil { - return err - } - - dbstate := state.NewPlainState(tx, block.NumberU64()-1) - intraBlockState := state.New(dbstate) - - getHeader := func(hash common.Hash, number uint64) *types.Header { return rawdb.ReadHeader(tx, hash, number) } - contractHasTEVM := ethdb.GetHasTEVM(tx) - receipts1, err1 := runBlock(intraBlockState, noOpWriter, noOpWriter, chainConfig, getHeader, contractHasTEVM, block, vmConfig) - if err1 != nil { - return err1 - } - fix := true - if chainConfig.IsByzantium(block.Number().Uint64()) { - receiptSha := types.DeriveSha(receipts1) - if receiptSha != block.Header().ReceiptHash { - fmt.Printf("(retrace) mismatched receipt headers for block %d: %x, %x\n", block.NumberU64(), receiptSha, block.Header().ReceiptHash) - fix = false - } - } - if fix { - // All good, we can fix receipt record - buf.Reset() - err := cbor.Marshal(&buf, receipts1) - if err != nil { - return fmt.Errorf("encode block receipts for block %d: %w", blockNum, err) - } - if err = tx.Put(kv.Receipts, key[:], buf.Bytes()); err != nil { - return fmt.Errorf("writing receipts for block %d: %w", blockNum, err) - } - fixedCount++ - } - } - if err := BeforeCommit(tx, nil, true); err != nil { - return err - } - return tx.Commit() - }, -} - -func runBlock(ibs *state.IntraBlockState, txnWriter state.StateWriter, blockWriter state.StateWriter, - chainConfig *params.ChainConfig, getHeader func(hash common.Hash, number uint64) *types.Header, contractHasTEVM func(common.Hash) (bool, error), block *types.Block, vmConfig vm.Config) (types.Receipts, error) { - header := block.Header() - vmConfig.TraceJumpDest = true - engine := ethash.NewFullFaker() - gp := new(core.GasPool).AddGas(block.GasLimit()) - usedGas := new(uint64) - var receipts types.Receipts - if chainConfig.DAOForkSupport && chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(block.Number()) == 0 { - misc.ApplyDAOHardFork(ibs) - } - for i, tx := range block.Transactions() { - ibs.Prepare(tx.Hash(), block.Hash(), i) - receipt, _, err := core.ApplyTransaction(chainConfig, getHeader, engine, nil, gp, ibs, txnWriter, header, tx, usedGas, vmConfig, contractHasTEVM) - if err != nil { - return nil, fmt.Errorf("could not apply tx %d [%x] failed: %w", i, tx.Hash(), err) - } - receipts = append(receipts, receipt) - } - - if !vmConfig.ReadOnly { - // Finalize the block, applying any consensus engine specific extras (e.g. block rewards) - if _, err := engine.FinalizeAndAssemble(chainConfig, header, ibs, block.Transactions(), block.Uncles(), receipts, nil, nil, nil, nil); err != nil { - return nil, fmt.Errorf("finalize of block %d failed: %w", block.NumberU64(), err) - } - - if err := ibs.CommitBlock(chainConfig.Rules(header.Number.Uint64()), blockWriter); err != nil { - return nil, fmt.Errorf("committing block %d failed: %w", block.NumberU64(), err) - } - } - - return receipts, nil -} diff --git a/migrations/remove_clique.go b/migrations/remove_clique.go deleted file mode 100644 index 2675c112cf9..00000000000 --- a/migrations/remove_clique.go +++ /dev/null @@ -1,36 +0,0 @@ -package migrations - -import ( - "context" - - "github.com/ledgerwatch/erigon-lib/kv" -) - -var removeCliqueBucket = Migration{ - Name: "remove_clique_bucket", - Up: func(db kv.RwDB, tmpdir string, progress []byte, BeforeCommit Callback) (err error) { - tx, err := db.BeginRw(context.Background()) - if err != nil { - return err - } - defer tx.Rollback() - - if exists, err := tx.ExistsBucket(kv.Clique); err != nil { - return err - } else if !exists { - if err := BeforeCommit(tx, nil, true); err != nil { - return err - } - return tx.Commit() - } - - if err := tx.DropBucket(kv.Clique); err != nil { - return err - } - - if err := BeforeCommit(tx, nil, true); err != nil { - return err - } - return tx.Commit() - }, -} diff --git a/migrations/set_prune_type.go b/migrations/set_prune_type.go deleted file mode 100644 index fac208775c4..00000000000 --- a/migrations/set_prune_type.go +++ /dev/null @@ -1,41 +0,0 @@ -package migrations - -import ( - "context" - - "github.com/ledgerwatch/erigon-lib/kv" -) - -var setPruneType = Migration{ - Name: "set_prune_type", - Up: func(db kv.RwDB, tmpdir string, progress []byte, BeforeCommit Callback) (err error) { - tx, err := db.BeginRw(context.Background()) - if err != nil { - return err - } - defer tx.Rollback() - - var pruneTypeKeys = [4][]byte{kv.PruneHistoryType, kv.PruneReceiptsType, kv.PruneTxIndexType, kv.PruneCallTracesType} - - for _, key := range pruneTypeKeys { - pruneType, getErr := tx.GetOne(kv.DatabaseInfo, key) - if getErr != nil { - return getErr - } - - if pruneType != nil { - continue - } - - putErr := tx.Put(kv.DatabaseInfo, key, kv.PruneTypeOlder) - if putErr != nil { - return putErr - } - } - - if err := BeforeCommit(tx, nil, true); err != nil { - return err - } - return tx.Commit() - }, -} From 12b46c5a1b0a1e544dd8167ad6bb67b9d91fc0f4 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Fri, 17 Dec 2021 00:26:57 +0000 Subject: [PATCH 069/261] [beta] TxPool broadcast fixes (#3138) * Point to erigon-lib stable * Txpool: broadcast transaction along with announcements (#3135) * Txpool: broadcast transaction along with announcements * Fix panic * Add TransactionMsg * Change terminology in the logs * Fixes from erigon-lib * Rebroadcast txs promoted to pending subpool * Deduplicate promoted hashes, fix basefee promotion * Make sending more resilient, fix promoted * Split Broadcast and Announce * Downgrade to Debug messages * Limit number of retries in SendMessageByMinBlock Co-authored-by: Alexey Sharp * Downgrade messages to Debug Co-authored-by: Alexey Sharp --- cmd/sentry/download/downloader.go | 15 +++-------- cmd/sentry/download/sentry.go | 43 ++++++++++++++++--------------- go.mod | 2 +- go.sum | 4 +-- 4 files changed, 29 insertions(+), 35 deletions(-) diff --git a/cmd/sentry/download/downloader.go b/cmd/sentry/download/downloader.go index f5dab4d50f9..b1ee6abd305 100644 --- a/cmd/sentry/download/downloader.go +++ b/cmd/sentry/download/downloader.go @@ -79,7 +79,7 @@ func RecvUploadMessageLoop(ctx context.Context, time.Sleep(time.Second) continue } - log.Warn("[RecvUploadMessage]", "err", err) + log.Debug("[RecvUploadMessage]", "err", err) continue } } @@ -119,11 +119,8 @@ func RecvUploadMessage(ctx context.Context, return } if err = handleInboundMessage(ctx, req, sentry); err != nil { - if rlp.IsDecodeError(err) { - log.Debug("[RecvUploadMessage]: Handling incoming message", "error", err) - } else { - log.Warn("[RecvUploadMessage]: Handling incoming message", "error", err) - } + log.Debug("[RecvUploadMessage]: Handling incoming message", "error", err) + } if wg != nil { wg.Done() @@ -210,11 +207,7 @@ func RecvUploadHeadersMessage(ctx context.Context, return } if err = handleInboundMessage(ctx, req, sentry); err != nil { - if rlp.IsDecodeError(err) { - log.Debug("[RecvUploadHeadersMessage] Handling incoming message", "error", err) - } else { - log.Warn("[RecvUploadHeadersMessage] Handling incoming message", "error", err) - } + log.Debug("[RecvUploadHeadersMessage] Handling incoming message", "error", err) } if wg != nil { wg.Done() diff --git a/cmd/sentry/download/sentry.go b/cmd/sentry/download/sentry.go index 6e93c1d4592..e9bb703560f 100644 --- a/cmd/sentry/download/sentry.go +++ b/cmd/sentry/download/sentry.go @@ -691,21 +691,27 @@ func (ss *SentryServerImpl) findPeer(minBlock uint64) (string, *PeerInfo, bool) } func (ss *SentryServerImpl) SendMessageByMinBlock(_ context.Context, inreq *proto_sentry.SendMessageByMinBlockRequest) (*proto_sentry.SentPeers, error) { - peerID, peerInfo, found := ss.findPeer(inreq.MinBlock) - if !found { - return &proto_sentry.SentPeers{}, nil - } + reply := &proto_sentry.SentPeers{} msgcode := eth.FromProto[ss.Protocol.Version][inreq.Data.Id] if msgcode != eth.GetBlockHeadersMsg && msgcode != eth.GetBlockBodiesMsg && msgcode != eth.GetPooledTransactionsMsg { return &proto_sentry.SentPeers{}, fmt.Errorf("sendMessageByMinBlock not implemented for message Id: %s", inreq.Data.Id) } - if err := ss.writePeer(peerID, peerInfo, msgcode, inreq.Data.Data); err != nil { - return &proto_sentry.SentPeers{}, fmt.Errorf("sendMessageByMinBlock to peer %s: %w", peerID, err) + var lastErr error + for retry := 0; retry < 16 && len(reply.Peers) == 0; retry++ { // limit number of retries + peerID, peerInfo, found := ss.findPeer(inreq.MinBlock) + if !found { + break + } + if err := ss.writePeer(peerID, peerInfo, msgcode, inreq.Data.Data); err != nil { + lastErr = fmt.Errorf("sendMessageByMinBlock to peer %s: %w", peerID, err) + } else { + peerInfo.AddDeadline(time.Now().Add(30 * time.Second)) + reply.Peers = []*proto_types.H512{gointerfaces.ConvertBytesToH512([]byte(peerID))} + } } - peerInfo.AddDeadline(time.Now().Add(30 * time.Second)) - return &proto_sentry.SentPeers{Peers: []*proto_types.H512{gointerfaces.ConvertBytesToH512([]byte(peerID))}}, nil + return reply, lastErr } func (ss *SentryServerImpl) SendMessageById(_ context.Context, inreq *proto_sentry.SendMessageByIdRequest) (*proto_sentry.SentPeers, error) { @@ -738,7 +744,8 @@ func (ss *SentryServerImpl) SendMessageToRandomPeers(ctx context.Context, req *p msgcode := eth.FromProto[ss.Protocol.Version][req.Data.Id] if msgcode != eth.NewBlockMsg && msgcode != eth.NewBlockHashesMsg && - msgcode != eth.NewPooledTransactionHashesMsg { + msgcode != eth.NewPooledTransactionHashesMsg && + msgcode != eth.TransactionsMsg { return &proto_sentry.SentPeers{}, fmt.Errorf("sendMessageToRandomPeers not implemented for message Id: %s", req.Data.Id) } @@ -754,21 +761,18 @@ func (ss *SentryServerImpl) SendMessageToRandomPeers(ctx context.Context, req *p // Send the block to a subset of our peers sendToAmount := int(math.Sqrt(float64(amount))) i := 0 - var innerErr error + var lastErr error reply := &proto_sentry.SentPeers{Peers: []*proto_types.H512{}} ss.rangePeers(func(peerID string, peerInfo *PeerInfo) bool { if err := ss.writePeer(peerID, peerInfo, msgcode, req.Data.Data); err != nil { - innerErr = err + lastErr = fmt.Errorf("sendMessageToRandomPeers to peer %s: %w", peerID, err) return true } reply.Peers = append(reply.Peers, gointerfaces.ConvertBytesToH512([]byte(peerID))) i++ return i < sendToAmount }) - if innerErr != nil { - return reply, fmt.Errorf("sendMessageToRandomPeers to peer %w", innerErr) - } - return reply, nil + return reply, lastErr } func (ss *SentryServerImpl) SendMessageToAll(ctx context.Context, req *proto_sentry.OutboundMessageData) (*proto_sentry.SentPeers, error) { @@ -779,20 +783,17 @@ func (ss *SentryServerImpl) SendMessageToAll(ctx context.Context, req *proto_sen return &proto_sentry.SentPeers{}, fmt.Errorf("sendMessageToAll not implemented for message Id: %s", req.Id) } - var innerErr error + var lastErr error reply := &proto_sentry.SentPeers{Peers: []*proto_types.H512{}} ss.rangePeers(func(peerID string, peerInfo *PeerInfo) bool { if err := ss.writePeer(peerID, peerInfo, msgcode, req.Data); err != nil { - innerErr = err + lastErr = fmt.Errorf("SendMessageToAll to peer %s: %w", peerID, err) return true } reply.Peers = append(reply.Peers, gointerfaces.ConvertBytesToH512([]byte(peerID))) return true }) - if innerErr != nil { - return reply, fmt.Errorf("sendMessageToRandomPeers to peer %w", innerErr) - } - return reply, nil + return reply, lastErr } func (ss *SentryServerImpl) HandShake(context.Context, *emptypb.Empty) (*proto_sentry.HandShakeReply, error) { diff --git a/go.mod b/go.mod index 98018e092b4..bdb5a1fa0c1 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20211214172614-e03a1f6fe9ce + github.com/ledgerwatch/erigon-lib v0.0.0-20211216220419-44c18ee5f94a github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 diff --git a/go.sum b/go.sum index d2e47a59532..0cb050f7366 100644 --- a/go.sum +++ b/go.sum @@ -500,8 +500,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20211214172614-e03a1f6fe9ce h1:l90jhkwhNKl6FhSLrlDeODt1LL+DZzujX7Oy3Gs/1sw= -github.com/ledgerwatch/erigon-lib v0.0.0-20211214172614-e03a1f6fe9ce/go.mod h1:lyGP3i0x4CeabdKZ4beycD5xZfHWZwJsAX+70OfGj4Y= +github.com/ledgerwatch/erigon-lib v0.0.0-20211216220419-44c18ee5f94a h1:saAP2TrAu8ifG6CJ30GAs5ydlaUtuVSmp0xe7clejIE= +github.com/ledgerwatch/erigon-lib v0.0.0-20211216220419-44c18ee5f94a/go.mod h1:lyGP3i0x4CeabdKZ4beycD5xZfHWZwJsAX+70OfGj4Y= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= From 47c3b9df31ce6f53b4d6067bbc52d1518966f90e Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Fri, 17 Dec 2021 10:07:09 +0000 Subject: [PATCH 070/261] Fix for RPC filters, remove mined transactions (#3142) Co-authored-by: Alexey Sharp --- cmd/rpcdaemon/commands/eth_filters.go | 8 +++++--- cmd/rpcdaemon/filters/filters.go | 16 ++++++++++++++-- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/cmd/rpcdaemon/commands/eth_filters.go b/cmd/rpcdaemon/commands/eth_filters.go index fcf17175aa2..ef2a8399ef3 100644 --- a/cmd/rpcdaemon/commands/eth_filters.go +++ b/cmd/rpcdaemon/commands/eth_filters.go @@ -95,9 +95,11 @@ func (api *APIImpl) NewPendingTransactions(ctx context.Context) (*rpc.Subscripti select { case txs := <-txsCh: for _, t := range txs { - err := notifier.Notify(rpcSub.ID, t.Hash()) - if err != nil { - log.Warn("error while notifying subscription", "err", err) + if t != nil { + err := notifier.Notify(rpcSub.ID, t.Hash()) + if err != nil { + log.Warn("error while notifying subscription", "err", err) + } } } case <-rpcSub.Err(): diff --git a/cmd/rpcdaemon/filters/filters.go b/cmd/rpcdaemon/filters/filters.go index 13c4f73b0a5..2a26f6769c5 100644 --- a/cmd/rpcdaemon/filters/filters.go +++ b/cmd/rpcdaemon/filters/filters.go @@ -222,9 +222,12 @@ func (ff *Filters) subscribeToPendingBlocks(ctx context.Context, mining txpool.M } func (ff *Filters) HandlePendingBlock(reply *txpool.OnPendingBlockReply) { + if len(reply.RplBlock) == 0 { + return + } b := &types.Block{} if err := rlp.Decode(bytes.NewReader(reply.RplBlock), b); err != nil { - log.Warn("OnNewTx rpc filters, unprocessable payload", "err", err) + log.Warn("HandlePendingBlock rpc filters, unprocessable payload", "err", err) } ff.mu.Lock() @@ -263,9 +266,12 @@ func (ff *Filters) subscribeToPendingLogs(ctx context.Context, mining txpool.Min } func (ff *Filters) HandlePendingLogs(reply *txpool.OnPendingLogsReply) { + if len(reply.RplLogs) == 0 { + return + } l := []*types.Log{} if err := rlp.Decode(bytes.NewReader(reply.RplLogs), &l); err != nil { - log.Warn("OnNewTx rpc filters, unprocessable payload", "err", err) + log.Warn("HandlePendingLogs rpc filters, unprocessable payload", "err", err) } ff.mu.RLock() @@ -338,6 +344,9 @@ func (ff *Filters) OnNewEvent(event *remote.SubscribeReply) { switch event.Type { case remote.Event_HEADER: payload := event.Data + if len(payload) == 0 { + return + } var header types.Header err := rlp.Decode(bytes.NewReader(payload), &header) @@ -385,6 +394,9 @@ func (ff *Filters) OnNewTx(reply *txpool.OnAddReply) { txs := make([]types.Transaction, len(reply.RplTxs)) for i, rlpTx := range reply.RplTxs { + if len(rlpTx) == 0 { + continue + } var decodeErr error s := rlp.NewStream(bytes.NewReader(rlpTx), uint64(len(rlpTx))) txs[i], decodeErr = types.DecodeTransaction(s) diff --git a/go.mod b/go.mod index bdb5a1fa0c1..13b8789e119 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20211216220419-44c18ee5f94a + github.com/ledgerwatch/erigon-lib v0.0.0-20211217093552-7d82c6ac76e6 github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 diff --git a/go.sum b/go.sum index 0cb050f7366..7f17730af42 100644 --- a/go.sum +++ b/go.sum @@ -500,8 +500,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20211216220419-44c18ee5f94a h1:saAP2TrAu8ifG6CJ30GAs5ydlaUtuVSmp0xe7clejIE= -github.com/ledgerwatch/erigon-lib v0.0.0-20211216220419-44c18ee5f94a/go.mod h1:lyGP3i0x4CeabdKZ4beycD5xZfHWZwJsAX+70OfGj4Y= +github.com/ledgerwatch/erigon-lib v0.0.0-20211217093552-7d82c6ac76e6 h1:xXbeZ6gQLwPSNE8o6W99hZqjDGwN95fF7Q2p3zmRfAE= +github.com/ledgerwatch/erigon-lib v0.0.0-20211217093552-7d82c6ac76e6/go.mod h1:lyGP3i0x4CeabdKZ4beycD5xZfHWZwJsAX+70OfGj4Y= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= From 6bf2ca5585e385d11fe647d925b12e2340885a60 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Sat, 25 Dec 2021 12:29:49 +0700 Subject: [PATCH 071/261] RLP: base error - allows skip them if need (#3156) --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 13b8789e119..c1e4055c19b 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20211217093552-7d82c6ac76e6 + github.com/ledgerwatch/erigon-lib v0.0.0-20211222073534-b4b2e2f27002 github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 diff --git a/go.sum b/go.sum index 7f17730af42..e789d6bc3e3 100644 --- a/go.sum +++ b/go.sum @@ -502,6 +502,8 @@ github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7 github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/ledgerwatch/erigon-lib v0.0.0-20211217093552-7d82c6ac76e6 h1:xXbeZ6gQLwPSNE8o6W99hZqjDGwN95fF7Q2p3zmRfAE= github.com/ledgerwatch/erigon-lib v0.0.0-20211217093552-7d82c6ac76e6/go.mod h1:lyGP3i0x4CeabdKZ4beycD5xZfHWZwJsAX+70OfGj4Y= +github.com/ledgerwatch/erigon-lib v0.0.0-20211222073534-b4b2e2f27002 h1:uvAKqbCEaCVG0D401Bc6pRXp1MAcN5uNoC7G7fl4Xuo= +github.com/ledgerwatch/erigon-lib v0.0.0-20211222073534-b4b2e2f27002/go.mod h1:lyGP3i0x4CeabdKZ4beycD5xZfHWZwJsAX+70OfGj4Y= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= From 56766f0a1274c5ca27e985394d8b4670550c141a Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Mon, 27 Dec 2021 14:11:03 +0700 Subject: [PATCH 072/261] Fix sender nil pointer stable (#3171) * add go.work to .gitignore * fix nil pointer in senders stage --- .gitignore | 4 +++- eth/stagedsync/stage_senders.go | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 850526e6479..231614a4dce 100644 --- a/.gitignore +++ b/.gitignore @@ -69,4 +69,6 @@ docker-compose.dev.yml /ethdb/*.fail libmdbx/build/* -tests/testdata/* \ No newline at end of file +tests/testdata/* + +go.work \ No newline at end of file diff --git a/eth/stagedsync/stage_senders.go b/eth/stagedsync/stage_senders.go index 2b0c72cd401..2cd4b6ec59e 100644 --- a/eth/stagedsync/stage_senders.go +++ b/eth/stagedsync/stage_senders.go @@ -148,7 +148,11 @@ func SpawnRecoverSendersStage(cfg SendersCfg, s *StageState, u Unwinder, tx kv.R case <-quitCh: return case <-logEvery.C: - log.Info(fmt.Sprintf("[%s] Recovery", logPrefix), "block_number", s.BlockNumber+uint64(j.index)) + n := s.BlockNumber + if j != nil { + n += uint64(j.index) + } + log.Info(fmt.Sprintf("[%s] Recovery", logPrefix), "block_number", n) case j, ok = <-out: if !ok { return From b1ca8f767308c30fc13b2e7b455b47c5ef949f2f Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Mon, 27 Dec 2021 14:11:18 +0700 Subject: [PATCH 073/261] RLP base error, part2 (#3176) * add go.work to .gitignore * rlp base error --- go.mod | 2 +- go.sum | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index c1e4055c19b..5d56d791ecf 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20211222073534-b4b2e2f27002 + github.com/ledgerwatch/erigon-lib v0.0.0-20211227023931-1ee73a7ee43f github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 diff --git a/go.sum b/go.sum index e789d6bc3e3..af8271a335e 100644 --- a/go.sum +++ b/go.sum @@ -500,10 +500,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20211217093552-7d82c6ac76e6 h1:xXbeZ6gQLwPSNE8o6W99hZqjDGwN95fF7Q2p3zmRfAE= -github.com/ledgerwatch/erigon-lib v0.0.0-20211217093552-7d82c6ac76e6/go.mod h1:lyGP3i0x4CeabdKZ4beycD5xZfHWZwJsAX+70OfGj4Y= -github.com/ledgerwatch/erigon-lib v0.0.0-20211222073534-b4b2e2f27002 h1:uvAKqbCEaCVG0D401Bc6pRXp1MAcN5uNoC7G7fl4Xuo= -github.com/ledgerwatch/erigon-lib v0.0.0-20211222073534-b4b2e2f27002/go.mod h1:lyGP3i0x4CeabdKZ4beycD5xZfHWZwJsAX+70OfGj4Y= +github.com/ledgerwatch/erigon-lib v0.0.0-20211227023931-1ee73a7ee43f h1:pQtRH0qqk3PVBHGi/I0aul0QSBxuZYD7alwnHQn92Vw= +github.com/ledgerwatch/erigon-lib v0.0.0-20211227023931-1ee73a7ee43f/go.mod h1:lyGP3i0x4CeabdKZ4beycD5xZfHWZwJsAX+70OfGj4Y= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= From 92f8490fc943a0f629c28d6d0400111f2d7deac7 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Mon, 27 Dec 2021 14:11:32 +0700 Subject: [PATCH 074/261] enable ruleguard linter (#3169) --- .golangci.yml | 16 +++++++++++----- eth/stagedsync/stage_call_traces.go | 4 ++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 713c6660b5d..c776341cb12 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -23,16 +23,17 @@ linters-settings: gocritic: # Which checks should be enabled; can't be combined with 'disabled-checks'; # See https://go-critic.github.io/overview#checks-overview - # To check which checks are enabled run `GL_DEBUG=gocritic golangci-lint run` + # To check which checks are enabled run `GL_DEBUG=gocritic ./build/bin/golangci-lint run` # By default list of stable checks is used. enabled-checks: - ruleguard - truncateCmp - # - defaultCaseOrder + # - defaultCaseOrder # Which checks should be disabled; can't be combined with 'enabled-checks'; default is empty disabled-checks: - regexpMust + - appendAssign # - hugeParam - rangeValCopy - exitAfterDefer @@ -44,17 +45,22 @@ linters-settings: - captLocal - commentFormatting - ifElseChain - - appendAssign + - importShadow + - paramTypeCombine + - builtinShadow + - typeUnparen # Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks. # Empty list by default. See https://github.com/go-critic/go-critic#usage -> section "Tags". enabled-tags: - performance + - diagnostic + - opinionated disabled-tags: - experimental - ruleguard: - rules: "rules.go" settings: + ruleguard: + rules: "rules.go" hugeParam: # size in bytes that makes the warning trigger (default 80) sizeThreshold: 1000 diff --git a/eth/stagedsync/stage_call_traces.go b/eth/stagedsync/stage_call_traces.go index d0a4699a7c2..1042b11efa9 100644 --- a/eth/stagedsync/stage_call_traces.go +++ b/eth/stagedsync/stage_call_traces.go @@ -263,7 +263,9 @@ func UnwindCallTraces(u *UnwindState, s *StageState, tx kv.RwTx, cfg CallTracesC func DoUnwindCallTraces(logPrefix string, db kv.RwTx, from, to uint64, ctx context.Context, tmpdir string) error { froms := etl.NewCollector(logPrefix, tmpdir, etl.NewOldestEntryBuffer(etl.BufferOptimalSize)) + defer froms.Close() tos := etl.NewCollector(logPrefix, tmpdir, etl.NewOldestEntryBuffer(etl.BufferOptimalSize)) + defer tos.Close() logEvery := time.NewTicker(30 * time.Second) defer logEvery.Stop() @@ -419,7 +421,9 @@ func pruneCallTraces(tx kv.RwTx, logPrefix string, pruneTo uint64, ctx context.C defer logEvery.Stop() froms := etl.NewCollector(logPrefix, tmpdir, etl.NewOldestEntryBuffer(etl.BufferOptimalSize)) + defer froms.Close() tos := etl.NewCollector(logPrefix, tmpdir, etl.NewOldestEntryBuffer(etl.BufferOptimalSize)) + defer tos.Close() { traceCursor, err := tx.CursorDupSort(kv.CallTraceSet) From fa869bf7a1bd1ae00cc5c98fab51705217bdba8d Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Sun, 2 Jan 2022 15:08:06 +0700 Subject: [PATCH 075/261] fix debug_storageRangeAt (#3182) * add go.work to .gitignore * save Co-authored-by: bgelb --- turbo/transactions/tracing.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/turbo/transactions/tracing.go b/turbo/transactions/tracing.go index 66ea3420f6c..5ef034dd90e 100644 --- a/turbo/transactions/tracing.go +++ b/turbo/transactions/tracing.go @@ -67,6 +67,11 @@ func ComputeTxEnv(ctx context.Context, block *types.Block, cfg *params.ChainConf // Ensure any modifications are committed to the state // Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect _ = statedb.FinalizeTx(vmenv.ChainRules, state.NewNoopWriter()) + + if idx+1 == len(block.Transactions()) { + // Return the state from evaluating all txs in the block, note no msg or TxContext in this case + return nil, BlockContext, vm.TxContext{}, statedb, reader, nil + } } return nil, vm.BlockContext{}, vm.TxContext{}, nil, nil, fmt.Errorf("transaction index %d out of range for block %x", txIndex, blockHash) } From 00f2b79d2ad1fe37110f1d7879e8de559911abe7 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sun, 2 Jan 2022 19:05:50 -0300 Subject: [PATCH 076/261] Add ots_getTransactionBySenderAndNonce API --- cmd/rpcdaemon/commands/otterscan_api.go | 160 +++++++++++++++++++++++- 1 file changed, 157 insertions(+), 3 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 454490b0bb8..d0f86fd36b5 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -6,16 +6,22 @@ import ( "encoding/binary" "errors" "fmt" + "math/big" + "sort" + "sync" + "github.com/RoaringBitmap/roaring/roaring64" "github.com/holiman/uint256" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/common/changeset" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/consensus/ethash" "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/state" "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/core/types/accounts" "github.com/ledgerwatch/erigon/core/vm" "github.com/ledgerwatch/erigon/ethdb" "github.com/ledgerwatch/erigon/internal/ethapi" @@ -27,12 +33,10 @@ import ( "github.com/ledgerwatch/erigon/turbo/shards" "github.com/ledgerwatch/erigon/turbo/transactions" "github.com/ledgerwatch/log/v3" - "math/big" - "sync" ) // API_LEVEL Must be incremented every time new additions are made -const API_LEVEL = 5 +const API_LEVEL = 6 type SearchResult struct { BlockNumber uint64 @@ -59,6 +63,7 @@ type OtterscanAPI interface { HasCode(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (bool, error) TraceTransaction(ctx context.Context, hash common.Hash) ([]*otterscan.TraceEntry, error) GetTransactionError(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) + GetTransactionBySenderAndNonce(ctx context.Context, addr common.Address, nonce uint64) (*common.Hash, error) } type OtterscanAPIImpl struct { @@ -828,3 +833,152 @@ func (api *OtterscanAPIImpl) GetTransactionError(ctx context.Context, hash commo return result.Revert(), nil } + +func (api *OtterscanAPIImpl) GetTransactionBySenderAndNonce(ctx context.Context, addr common.Address, nonce uint64) (*common.Hash, error) { + tx, err := api.db.BeginRo(ctx) + if err != nil { + return nil, err + } + defer tx.Rollback() + + accHistoryC, err := tx.Cursor(kv.AccountsHistory) + if err != nil { + return nil, err + } + defer accHistoryC.Close() + + accChangesC, err := tx.CursorDupSort(kv.AccountChangeSet) + if err != nil { + return nil, err + } + defer accChangesC.Close() + + // Locate the chunk where the nonce happens + acs := changeset.Mapper[kv.AccountChangeSet] + k, v, err := accHistoryC.Seek(acs.IndexChunkKey(addr.Bytes(), 0)) + if err != nil { + return nil, err + } + + bitmap := roaring64.New() + maxBlPrevChunk := uint64(0) + var acc accounts.Account + + for { + if k == nil || !bytes.HasPrefix(k, addr.Bytes()) { + // Check plain state + data, err := tx.GetOne(kv.PlainState, addr.Bytes()) + if err != nil { + return nil, err + } + if err := acc.DecodeForStorage(data); err != nil { + return nil, err + } + + // Nonce changed in plain state, so it means the last block of last chunk + // contains the actual nonce change + if acc.Nonce > nonce { + break + } + + // Not found; asked for nonce still not used + return nil, nil + } + + // Inspect block changeset + if _, err := bitmap.ReadFrom(bytes.NewReader(v)); err != nil { + return nil, err + } + maxBl := bitmap.Maximum() + data, err := acs.Find(accChangesC, maxBl, addr.Bytes()) + if err != nil { + return nil, err + } + if err := acc.DecodeForStorage(data); err != nil { + return nil, err + } + + // Desired nonce was found in this chunk + if acc.Nonce > nonce { + break + } + + maxBlPrevChunk = maxBl + k, v, err = accHistoryC.Next() + if err != nil { + return nil, err + } + } + + // Locate the exact block inside chunk when the nonce changed + blocks := bitmap.ToArray() + var errSearch error = nil + idx := sort.Search(len(blocks), func(i int) bool { + if errSearch != nil { + return false + } + + // Locate the block changeset + data, err := acs.Find(accChangesC, blocks[i], addr.Bytes()) + if err != nil { + errSearch = err + return false + } + + if err := acc.DecodeForStorage(data); err != nil { + errSearch = err + return false + } + + // Since the state contains the nonce BEFORE the block changes, we look for + // the block when the nonce changed to be > the desired once, which means the + // previous history block contains the actual change; it may contain multiple + // nonce changes. + return acc.Nonce > nonce + }) + if errSearch != nil { + return nil, errSearch + } + + // Since the changeset contains the state BEFORE the change, we inspect + // the block before the one we found; if it is the first block inside the chunk, + // we use the last block from prev chunk + nonceBlock := maxBlPrevChunk + if idx > 0 { + nonceBlock = blocks[idx-1] + } + found, txHash, err := findNonce(tx, addr, nonce, nonceBlock) + if err != nil { + return nil, err + } + if !found { + return nil, nil + } + + return &txHash, nil +} + +func findNonce(tx kv.Tx, addr common.Address, nonce uint64, blockNum uint64) (bool, common.Hash, error) { + hash, err := rawdb.ReadCanonicalHash(tx, blockNum) + if err != nil { + return false, common.Hash{}, err + } + senders, err := rawdb.ReadSenders(tx, hash, blockNum) + if err != nil { + return false, common.Hash{}, err + } + body := rawdb.ReadBodyWithTransactions(tx, hash, blockNum) + + for i, s := range senders { + if s != addr { + continue + } + + t := body.Transactions[i] + if t.GetNonce() == nonce { + return true, t.Hash(), nil + } + } + + return false, common.Hash{}, nil +} From 0e266e3cfd3c9f9d9fcf78957b051145e68aff9b Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Mon, 3 Jan 2022 02:26:49 -0300 Subject: [PATCH 077/261] Remove unnecessary capacity --- cmd/rpcdaemon/commands/otterscan_api.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index d0f86fd36b5..e7a4f8df927 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -167,7 +167,7 @@ func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr } var wg sync.WaitGroup - results := make([]*TransactionsWithReceipts, 100, 100) + results := make([]*TransactionsWithReceipts, 100) tot := 0 for i := 0; i < int(minPageSize-resultCount); i++ { var blockNum uint64 @@ -308,7 +308,7 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c } var wg sync.WaitGroup - results := make([]*TransactionsWithReceipts, 100, 100) + results := make([]*TransactionsWithReceipts, 100) tot := 0 for i := 0; i < int(minPageSize-resultCount); i++ { var blockNum uint64 From bf63558b58fa7d943f5211ad99f88fe2ce120b61 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Mon, 3 Jan 2022 02:28:55 -0300 Subject: [PATCH 078/261] Code cleanup, remove unused structs --- cmd/rpcdaemon/commands/otterscan_api.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index e7a4f8df927..62f4b7af43f 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -38,14 +38,6 @@ import ( // API_LEVEL Must be incremented every time new additions are made const API_LEVEL = 6 -type SearchResult struct { - BlockNumber uint64 -} - -type BlockSearchResult struct { - hash common.Hash -} - type TransactionsWithReceipts struct { Txs []*RPCTransaction `json:"txs"` Receipts []map[string]interface{} `json:"receipts"` From 4b9120f8d992b52793315931ea8c529a23444f36 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Mon, 3 Jan 2022 21:38:49 +0700 Subject: [PATCH 079/261] Use same linter version with devel branch (#3199) --- .github/workflows/ci.yml | 2 +- common/fdlimit/fdlimit_unix.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7b62a698c7a..4b4dd3dda02 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,7 +44,7 @@ jobs: if: matrix.os == 'ubuntu-20.04' uses: golangci/golangci-lint-action@v2 with: - version: v1.41 + version: v1.42 skip-go-installation: true skip-pkg-cache: true skip-build-cache: true diff --git a/common/fdlimit/fdlimit_unix.go b/common/fdlimit/fdlimit_unix.go index e5a575f7a79..a1f388ebb78 100644 --- a/common/fdlimit/fdlimit_unix.go +++ b/common/fdlimit/fdlimit_unix.go @@ -14,6 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . +//go:build linux || netbsd || openbsd || solaris // +build linux netbsd openbsd solaris package fdlimit From 8a5401aa26a77439791c4c550746c69ff6213ff6 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Wed, 5 Jan 2022 18:14:10 +0700 Subject: [PATCH 080/261] Sanity check p2p block (#3196) --- cmd/sentry/download/downloader.go | 7 +++++-- eth/protocols/eth/handlers.go | 2 +- eth/protocols/eth/protocol.go | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/cmd/sentry/download/downloader.go b/cmd/sentry/download/downloader.go index b1ee6abd305..827549c0b8e 100644 --- a/cmd/sentry/download/downloader.go +++ b/cmd/sentry/download/downloader.go @@ -515,10 +515,13 @@ func (cs *ControlServerImpl) newBlock66(ctx context.Context, inreq *proto_sentry return fmt.Errorf("decode 3 NewBlockMsg: %w", err) } // Parse the entire request from scratch - var request eth.NewBlockPacket - if err := rlp.DecodeBytes(inreq.Data, &request); err != nil { + request := ð.NewBlockPacket{} + if err := rlp.DecodeBytes(inreq.Data, request); err != nil { return fmt.Errorf("decode 4 NewBlockMsg: %w", err) } + if err := request.SanityCheck(); err != nil { + return fmt.Errorf("newBlock66: %w", err) + } if segments, penalty, err := cs.Hd.SingleHeaderAsSegment(headerRaw, request.Block.Header()); err == nil { if penalty == headerdownload.NoPenalty { cs.Hd.ProcessSegment(segments[0], true /* newBlock */, string(gointerfaces.ConvertH512ToBytes(inreq.PeerId))) // There is only one segment in this case diff --git a/eth/protocols/eth/handlers.go b/eth/protocols/eth/handlers.go index 7ebee75e23c..72a7ebf1f2b 100644 --- a/eth/protocols/eth/handlers.go +++ b/eth/protocols/eth/handlers.go @@ -342,7 +342,7 @@ func handleNewBlock(backend Backend, msg Decoder, peer *Peer) error { log.Warn("Propagated block has invalid body", "have", hash, "exp", ann.Block.TxHash()) return nil // TODO(karalabe): return error eventually, but wait a few releases } - if err := ann.sanityCheck(); err != nil { + if err := ann.SanityCheck(); err != nil { return err } ann.Block.ReceivedAt = msg.Time() diff --git a/eth/protocols/eth/protocol.go b/eth/protocols/eth/protocol.go index 78c39ba08ab..8a0b56b5ffd 100644 --- a/eth/protocols/eth/protocol.go +++ b/eth/protocols/eth/protocol.go @@ -412,8 +412,8 @@ func (nbp *NewBlockPacket) DecodeRLP(s *rlp.Stream) error { return nil } -// sanityCheck verifies that the values are reasonable, as a DoS protection -func (request *NewBlockPacket) sanityCheck() error { +// SanityCheck verifies that the values are reasonable, as a DoS protection +func (request *NewBlockPacket) SanityCheck() error { if err := request.Block.SanityCheck(); err != nil { return err } From 440acba6d33e3025ec10679de5ffdd3640cfa8ff Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Wed, 5 Jan 2022 18:14:33 +0700 Subject: [PATCH 081/261] RLP: suspend parse errors from logs (#3207) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 5d56d791ecf..ccda751ee0b 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20211227023931-1ee73a7ee43f + github.com/ledgerwatch/erigon-lib v0.0.0-20220105105930-7e83346def11 github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 diff --git a/go.sum b/go.sum index af8271a335e..87c12cf743a 100644 --- a/go.sum +++ b/go.sum @@ -500,8 +500,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20211227023931-1ee73a7ee43f h1:pQtRH0qqk3PVBHGi/I0aul0QSBxuZYD7alwnHQn92Vw= -github.com/ledgerwatch/erigon-lib v0.0.0-20211227023931-1ee73a7ee43f/go.mod h1:lyGP3i0x4CeabdKZ4beycD5xZfHWZwJsAX+70OfGj4Y= +github.com/ledgerwatch/erigon-lib v0.0.0-20220105105930-7e83346def11 h1:tT+CWEBGFJ0l+uAusa7Qb4OKLqxBowlAQLi8m+yVgUQ= +github.com/ledgerwatch/erigon-lib v0.0.0-20220105105930-7e83346def11/go.mod h1:lyGP3i0x4CeabdKZ4beycD5xZfHWZwJsAX+70OfGj4Y= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= From f8600861fc6bc194ee261758d6a8691c1df4ce42 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Thu, 6 Jan 2022 19:17:33 -0300 Subject: [PATCH 082/261] Remove unnecessary check --- cmd/rpcdaemon/commands/otterscan_api.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 62f4b7af43f..a625b230dbe 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -344,11 +344,7 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c func newSearchForwardIterator(cursor kv.Cursor, addr common.Address, minBlock uint64) func() (uint64, bool, error) { search := make([]byte, common.AddressLength+8) copy(search[:common.AddressLength], addr.Bytes()) - if minBlock == 0 { - binary.BigEndian.PutUint64(search[common.AddressLength:], uint64(0)) - } else { - binary.BigEndian.PutUint64(search[common.AddressLength:], minBlock) - } + binary.BigEndian.PutUint64(search[common.AddressLength:], minBlock) first := true var iter roaring64.IntIterable64 From cdb28266a23d4d6f47550233cc6eadfaf8f95fcc Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Tue, 11 Jan 2022 15:15:56 +0700 Subject: [PATCH 083/261] mdbx: fix gc "retry" issue (slowness of gc during commit) (#3230) * mdbx: fix gc "retry" issue (slowness of gc during commit) * mdbx: fix gc "retry" issue (slowness of gc during commit) --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index ccda751ee0b..3dbd5c96fe6 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20220105105930-7e83346def11 + github.com/ledgerwatch/erigon-lib v0.0.0-20220110123802-994b74cd54de github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 @@ -47,7 +47,7 @@ require ( github.com/spf13/cobra v1.2.1 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.7.0 - github.com/torquem-ch/mdbx-go v0.22.2 + github.com/torquem-ch/mdbx-go v0.22.3 github.com/ugorji/go/codec v1.1.13 github.com/ugorji/go/codec/codecgen v1.1.13 github.com/urfave/cli v1.22.5 diff --git a/go.sum b/go.sum index 87c12cf743a..8fb088951e4 100644 --- a/go.sum +++ b/go.sum @@ -500,8 +500,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20220105105930-7e83346def11 h1:tT+CWEBGFJ0l+uAusa7Qb4OKLqxBowlAQLi8m+yVgUQ= -github.com/ledgerwatch/erigon-lib v0.0.0-20220105105930-7e83346def11/go.mod h1:lyGP3i0x4CeabdKZ4beycD5xZfHWZwJsAX+70OfGj4Y= +github.com/ledgerwatch/erigon-lib v0.0.0-20220110123802-994b74cd54de h1:57dTOByuRZCodDGCgo0cQjuG3JsoVBcJftDBt0etgIY= +github.com/ledgerwatch/erigon-lib v0.0.0-20220110123802-994b74cd54de/go.mod h1:RtMyitRZlGyq0k8YVbMIwN/w3iby0zhPfM3tpCoqSUU= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= @@ -753,8 +753,8 @@ github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs= github.com/tklauser/numcpus v0.3.0 h1:ILuRUQBtssgnxw0XXIjKUC56fgnOrFoQQ/4+DeU2biQ= github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8= -github.com/torquem-ch/mdbx-go v0.22.2 h1:wl/eJaZeKqsqObfzXAurYuPozr4hkopJ1hELHXH+N8w= -github.com/torquem-ch/mdbx-go v0.22.2/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= +github.com/torquem-ch/mdbx-go v0.22.3 h1:C6cj5BMZ74Mbkn/FjOKvz2lVDSJLm7pqYwQBsIT9T4Y= +github.com/torquem-ch/mdbx-go v0.22.3/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= From 4aca7e85e8e6fad353d5070218b96b1d76b78df2 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Tue, 11 Jan 2022 22:51:33 +0700 Subject: [PATCH 084/261] increase body download timeout (#3217) (#3237) --- eth/backend.go | 2 +- eth/ethconfig/config.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/eth/backend.go b/eth/backend.go index f5ce41ea819..ca985716541 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -309,7 +309,7 @@ func New(stack *node.Node, config *ethconfig.Config, logger log.Logger) (*Ethere if err != nil { return nil, err } - config.BodyDownloadTimeoutSeconds = 30 + config.BodyDownloadTimeoutSeconds = 60 var txPoolRPC txpool_proto.TxpoolServer var miningRPC txpool_proto.MiningServer diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index c3186024cba..ccd2ea565b6 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -86,7 +86,7 @@ var Defaults = Config{ GPO: FullNodeGPO, RPCTxFeeCap: 1, // 1 ether - BodyDownloadTimeoutSeconds: 30, + BodyDownloadTimeoutSeconds: 60, } func init() { From 3ab065667cd3f80e09db951c25a805cf19874de8 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Tue, 11 Jan 2022 15:53:26 +0000 Subject: [PATCH 085/261] Update stable version to 2022.01.1 (#3238) --- params/version.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/params/version.go b/params/version.go index f57a62c4f27..24bae2b9280 100644 --- a/params/version.go +++ b/params/version.go @@ -31,9 +31,9 @@ var ( // see https://calver.org const ( - VersionMajor = 2021 // Major version component of the current release - VersionMinor = 12 // Minor version component of the current release - VersionMicro = 3 // Patch version component of the current release + VersionMajor = 2022 // Major version component of the current release + VersionMinor = 1 // Minor version component of the current release + VersionMicro = 1 // Patch version component of the current release VersionModifier = "beta" // Patch version component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" From 39f25fc2dbf044cbd522fcc649b0ad96cc1c29f5 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Wed, 12 Jan 2022 12:40:46 +0000 Subject: [PATCH 086/261] Skip analysis and preverified hashe update (#3244) (#3245) Co-authored-by: Alexey Sharp Co-authored-by: Alexey Sharp --- core/skip_analysis.go | 2 +- .../preverified_hashes_mainnet.go | 948 +++++++++++++++++- .../preverified_hashes_ropsten.go | 937 ++++++++++++++++- 3 files changed, 1884 insertions(+), 3 deletions(-) diff --git a/core/skip_analysis.go b/core/skip_analysis.go index 2b77b95eeec..cae582b80b4 100644 --- a/core/skip_analysis.go +++ b/core/skip_analysis.go @@ -21,7 +21,7 @@ import ( ) // MainnetNotCheckedFrom is the first block number not yet checked for invalid jumps -const MainnetNotCheckedFrom uint64 = 13804600 +const MainnetNotCheckedFrom uint64 = 13986250 // SkipAnalysis function tells us whether we can skip performing jumpdest analysis // for the historical blocks (on mainnet now but perhaps on the testsnets diff --git a/turbo/stages/headerdownload/preverified_hashes_mainnet.go b/turbo/stages/headerdownload/preverified_hashes_mainnet.go index a978ceea467..8c435211320 100644 --- a/turbo/stages/headerdownload/preverified_hashes_mainnet.go +++ b/turbo/stages/headerdownload/preverified_hashes_mainnet.go @@ -71901,6 +71901,952 @@ var mainnetPreverifiedHashes = []string{ "2ffbb626dd8d99fd96924058dc2b3eb587ea074d00dbb0983f0e220f38a96d0a", "45f52f06b3b221aca1bd26b1fc146f469b58f6319845fdda5433baac7ef8063e", "68510f8bc28d916ac36f7ae0fdbcbc790094ff2f1233f46f2214a609526a38de", + "94b9a6240ba1c47c404b142e102d215a7f8bbb9503ff4ce8398b9605ac45b769", + "befc779a6f09fb9afa3d041b90faf1ab89aedde150019c9fe27983eefaf14a35", + "8ed5ded70e65d2211607ae1e7cd3eafbd4938b9a2e63b5feed2526db723d4cbb", + "010bfadf516f2dad270845b1def41ee31bf6d629e051e1fdc45d34fecde8de78", + "a0f903eab94c09e1307e5315d3a20e0d63c2afc32a017990ba8e1e81d3f8ac3d", + "2851d807df6912ec5dee0cb758c0400f2f3309131bae2d3c78bce66f590e944f", + "f20cf622782e467a4cfa74279bf98305ca0386b3b01a6bd3657eb2941340d91f", + "fd94c18b66970822b3c6cf6785ea8b66ab1da9e1c11efb7fa712da51cc2ad645", + "fe92c81d5fb2045d8e2295b066143849c7ffc54913b03ff54b5521827b923dc6", + "885b6d89f4220a0fc84444c9f9f818795349e9915fb3f5ab9c45db9d84a40c8a", + "69af5174578f0325a21459f35f02b1f8972a6aecbc0d50c9c3a418e987999eb0", + "cedd40dae5329d9d0c3734f1ccc797e0670ec0ce7d3f395191d68730e346beb4", + "8c9a6afbb18e9402426fd5f2800e3142fccb086279d8233302929b3789668e01", + "27f83dc9e55e0d03aeba7bb58e269f0aa5a1082305e5d74a45d0f05927941d11", + "2dde1e770141aeb6486ec61eeaabc47d9800e9cce89b9108fb178ea7ef373de2", + "70383b3bded0305a7f6d93601eb36318b485202bc6636df2d5f4731e9a5f31eb", + "2f039d5e54c102ca6ef9a65424defb52f3aeac306b01b6c3f16b28cf38cee3d2", + "d9c03e4f65b8205e60489899d158c3191f22bf633ca5bb17f33a2d2ce4f05600", + "033af031c21627dd3fd617febf5e322cb24ac9cf23c67c2d3fe0e4b93c37f321", + "d0388f6ac3bbc7f08cda74179fabc2d2c92297eba9264faa1627c5f0921e0862", + "466bfd95fe151ca418968da7868b194fd6b7afe29605cdb3117adabe3e0ea423", + "a032149036ca07a69e63a72a34c3ae945d56b1a70d4406aad53a3850c1e6ee9e", + "2e51001c12e1b6b5377544d8f188ef8ccf241b05847aaea852e6400e117e439a", + "d38f6aa05282812bd26304b63032bc015faa84570fa66593cf5c78dca4e9bdcb", + "a83f61d5e713759c3b77250401701e3cea3a788f5e2e2271c21f99874948d7da", + "361af1553c30ecf188f4d55966a99454bd154926de8a46f9fd9b736fe76a445b", + "303490543136e57a082fa04610416badb7bcb5e913697c6a9516cdc0c8f88dc5", + "d3aee2f20b9622e1595c5dd35c2974bbbd8a9032f33239a0501cd509ac992be0", + "7de27244e045b54a5d4f289b6baff773adfd28e026a21f4b977d16f0400204b1", + "4ba459f2cb897f57bc5b67248eb1427ac53066c68d15e6d07757e235b163dc45", + "0677058a1cb8cbd30c85016694cccf7b51af855a56003744f0caee08d88836e1", + "c8438e4c3e48743f8557244b6a0bfbdf13548cd33695c0db55ce29a220338f2e", + "9944eb3e31e6941460053a902ef343f42a1f281d9c7cbf2a5c3c9d6a6b696753", + "cef9160c2f3bd00c6740055f9400adf0938801bf2378d6070e0445e2c77f75cc", + "c968137c5e1fef01dd90139d4c790380bfa53b424f48fab667408f538c4e504c", + "631909da174fc15ca7d3c68b0712adbdd79d8240b183ec1c46136c2e64825fc6", + "1c1bbbe6ffaa63c49af7e54802798664381e91b2106e529f6920275d0519e3f6", + "4df6c9e14732057c62c5446f421c7c9f4f2a76b246513f036fb2a1812eb7d9b9", + "f8f78be32dd35aa478de2190542243c71071bbfc0d9da6e3edbaade18631d4cd", + "ee3e515b43ad5a3714d1059e5eac3658b23884fef07a15dba844b4188a05cb7b", + "853f8915d795fa2ec41008b6255b5091d03050be0a6f8a36c31504440d2677da", + "a7a72228e11a98f593e24acf6b86f39e38a965482a7942908faf9bff02887125", + "ada8ffd22ebd30096763a4faf63b57fa316a7a314d7c587e122241f26a93be7c", + "3d2f009f7ecc150e7316246ff4d0a387f13b7d68811390d7e0db1c5f9888b283", + "a378404154980274e105d5685d6120a3eb25bbb82852a6336777f203a1b226b8", + "d49ac541bdb5f4b4564d6cbe3d89b4d935dd03a01fddc67da8a8f105ba146478", + "61f67c6634b392b5260bf145dac53d00f12330c4b9db63e8f0ae041f9a3930ae", + "25833144cc4124ff96fbf527aea36607aa4c7fdbac1f5f8595c0b936abc220e7", + "f6df0b46451642a17f7f6be759df8c027e388f1c7bdd1b0b8101fd6df11e46b9", + "51caa65a3382542e30c4a08897defb31ceac4e7185b6733f1ae0a43f3ad3cd69", + "b4d7ffda3046f991ae70312635bc8beea3eee95205dfbfe9920d77698a427962", + "7ebc0e0aa6d82572d665ec5d06c92f4466051192dc6dc04cc0fd39e1c82d211c", + "9f831ebf81bc1a11d255b9b768206ea5cb3dc6f8d618c684be5b394790763dd8", + "c58109805aebd558f074d759785116d9288a6696dfd42bfdad148ad06a347d8d", + "69fcec60ab39166c802a52b5ad8201487fea7cdf70747253abeb90490cdd8ee7", + "b5c6f35ec1eac54d09f4051bfef109d3d7a0d319f34d1d7d98a3528cf477f0d8", + "9c5b001db72a272ae0e3840175ccf46cb58ecc7fd668e549dabc70d7ade6b7fc", + "bc770cff1e00ffe4a6e4f60d09c0d2c4996b6b6e3168544d89bca6a2e4f24dee", + "c433e4817cddf36feb0dae241f2900d3fb763a45fd58b879623882b96ec32311", + "f0b0439e1032bb1416c46979ded04e7655bac907cadf729bc6622c31ae3eb1e7", + "4f575ecddc63cbc1f1c581463ce8b3c93fbeae3ae5c88c001294c7787d1ed7c8", + "51f6d42fe83f20a45c8ef9ccc196970106a1d186f7534c587442e34e89aac990", + "3b1e1d773e0ddac29ab584aad70c6d6999637ae2d941f3420b7ebe7e8ab00235", + "68135b132dd629f9f4e34b8a50c72c525e7ba3d1da79453328b90236831d280c", + "f52341b4a43b47a35db353fa644f0f753ca4aaf685092d448b8179af680f409c", + "c59456c061da69160a0e17dab8b42544fd8c4dbd46318bf1f645e671e1bb2924", + "001dda20200f2de01d33b666ba218f3851e6b84ad6e56e5eba44262b4f5455e8", + "507893a4732bd3236d49529de172f3435403ef9d17a74afb752cbe3f8e33a966", + "f392de45c7d659672a6cbf2ed58e335bd627cbf4a664c106d58f25e9c452983a", + "e1d314cd6b76f7b0a9f2b26772875e614b6d63a1f8f43a0d0eba282a6df86f14", + "87cac3b72e5b3624994fea269977043cd21ef386e9fb387a9f6651915e24e91d", + "dfeeb449f96b74dcd5fb488fa99004a406f573ef94527c2940fa47bccc7cbf0e", + "ea3c1924e80eeada7fb2bd6c96a07ad5692fdc6157b2a00bfb6e91a40f682771", + "a61b535820c95339aeb4c946d2f9d88e5a81465d83f058324423ae7fbe5af8ee", + "1ca1daff4f9b7a7e6c643dad9e2102dd08a342f105aa29809c6cc64470427d03", + "eba60761fcdc434ee921a4d686dedf8382ae0e63eb4770e6af83e3be8321244d", + "dedb7330bf45d3ab905863aabbf11510208e1a312e570d9ced90895beba53823", + "ba28f47fbfdad26e5fee1dc6ffb2bb5ed91332eaeff3c8c0ef0c50fc2105aa8b", + "458e4795d68e0882f9a969b4f79480244acec36a1f97b6de2b66bf0d11a89c53", + "e129d694a5fae91b61b5c2d0ef40ed6fed5d0b9a5d319ab115ce47fbc9dbf729", + "a0011fa77e6a6132566d47556b8c549e335007bf0ac0791877fedd9272a48219", + "bb81f504e077a58f572b6d3be1fa78e867b314296f4420129a6554ba0ec015ef", + "5afe8c1b0f19ffeacca855a122ac830372c466ffa663f0a2c3dbe111645e46b4", + "006bdbb33a98b7f9154763a6aecb40654bb2a5ce4c8f6d3a718c3e43acbf27e8", + "462dbefbdbfd19bb93027a43d8725fca5edf237a60fdede926b00cb97b24649e", + "6b3c5caf6c287461a81650ac75abd734f8b2c31808a33d301f4bc8b2c2ed7411", + "0f0b2b8b4b716ffd0938f39f63cb505c5cbc3175c42a0b6e071ef5d0a176faf2", + "2a45be927b68d950391cceb3bae616cea0f63a7da204fb80c0445565de35acbd", + "c6b2c3043bc47fb49a68d6934de9eb402311b5bdd8921842156cbd362ab3d89f", + "5ed88780d16aa763f34fca885fc3bd618b31747b92c57aac7ab0a5f8fb0ef9ee", + "e0403b2a30ee7ea24359b51fea398bd55ac29bd2be4bf5cbe7472448a4ba22da", + "211d81da7a2ce6d9c2ca875f886bff512e6cdce53baec9f15b897ffec5a0e2dd", + "fbd5fa02fd37569dbc17984dc4ddbe58f47ca1119c3f57a04039f4911261f1dd", + "4d387b4c8ab5bbb1626a8da476669de8ba99346fa1114f2dc7b7235512e8f249", + "2b8d53db57a8474da1b46b4375fac25e32681bf292c9ff949a1a324905cf661f", + "8027df4d93e57157c81197111be63e29b5d7b64005790613ab7e528a8687e747", + "44e0d694b5bc7e5956ba4431bbb80cd4d02a8013d50c1ddbf84cb3bce95fe87e", + "41d332abf7b03a0e5a9cab72758977339d526c4286c910d0a57e03a1367c4e94", + "fd9908d597d8884b60c8403d328330fdc03fd7a9c18eb12ee9912d70e393fc43", + "79c2978178a547594423637405c5fdaf0d63c3adb815cf6275686de7b01b980b", + "0768de57d9883c5e0131ecfd4adcfa5af6818a41f584245b5f2b2f9761ac3775", + "788a2f9041d11791df0ba27aec9dfae41338b20251cf4b33ffdc4c2df1ff6900", + "27fb4314d3863b50f695f5dad09befda0d6e6d327a502027eaf68f4bc4dc713d", + "fff7431fd46365adcf8c02ec26cb8e635bbd2c45172ee2678c27b48eea377aa6", + "070f700bbb61e98b48528798fb7b3bd1c565eb1bce28146f6dc19b4ad27cf839", + "2eea0e25954ae621fcd6bc52a69a6511bf5204ca72c92eddc8ccefd5ae065760", + "5cd2b8b3aee250594e7c01df73ceac8538433ba7be80cc11eaca28d9724f0f8a", + "c745a2b71946a4f9204fe90a969944da39bc4a157ab0ed4518bf1d4e303b61e5", + "a65bc428d37ca2198771da78606494cb9b1da1e0addd1848b03aff4bae728dd8", + "101e8eb4361b77c8b2c629dd0a20c87c21a7bc990978c40123ef6458a44d0c7d", + "82f955993829639ca01c312f8adf23aea5b46f4f1829a2096cd10cdfe9532f28", + "83a7ebaecbe5c8f4e21178124b38e0435df9cec99e70a9db68d4df9605cf6053", + "79db467343a470b59a653f5262c28ab25ed0491aaaac0959b1f9c59ad5f652d3", + "ee9668730bf25e4524db955085d3e730dc3efa22270c1696f547453a4f0c9cd5", + "66f3d14b6c5cfef73a269bd6fa2d2a3b7e3bc37d091a5d7e8ebc7472bcacb655", + "b0e18ccc22dd9e1986d59ba676d6953b3a16e31564208d0929c8c582ba7940a2", + "3b659ab3e47b31d9f1edb7231cb629cd17126d365fe3e2fb451c5da319f8015f", + "fa5a1fe96ff16845cba7833a9d6c9c7a05e3db0090cfe60ad2d887a83ea8a740", + "e0f24b9fe14fa67366354d168ab322842b6d38186cb16e9d1f1264a4e9e8d49e", + "ef493226254de636b67f9b7a92b9a3ecd6b9183a65a28e8800f1a6008c191b2f", + "0d6563616eb52cdb186d1af9b29ffca3390570abc82400e1f6f3a90eba2c7083", + "438ac0e1f96ba11204b105693ff85f264c032df20cc6f0c0bdab09b2e956b699", + "1ed52ce8d386a2ccc1ca5e4802ba1201ecf94cc90ab9a26324a2ef335e6d9bb4", + "97ce137b97a940de57e68df013317dd9a44151c0c9d574b1f8cf488309bfc497", + "51433252bca2afc00687afb79b32aa43bcfb4c7dfd1117e9eda0de4bb3dfe35e", + "0b8985a4400c9f53d8b9dd929e0473063dff0d35bc3d3da83f8db87375f79099", + "d3e52b5895a81648180c6c1c8099006a78f551e844267278f2d0724eae125a9b", + "a45456256cf3a3fe7630d7d063ff8e513a38dc8b6e84190d34a9d5bd8ec4ce22", + "e7f7a229ae25b30426fe9658145be88223bcad223f057b369b9b062d2f2e2b53", + "51776bacec2e164b00d6a07ed20dd11a1f138245c959d4e46a1d3ec40e5dc739", + "ec390a591f1ac3eacc362ee2b917b69376fd5550af9cd511348bcb21c759b7d6", + "07f8397ef95ef4e17d2d4b5aea33499afc3300deed4dc4a24e8c4a51124cd68f", + "ab26c1f3c6e35cf80867f8ff1789bc18cb1422305d808a2a7931e72443dfa65a", + "c1f63232d20b80a45023243b6e98d23be69a38aeca7b68d90688d70897c889e5", + "dd0d3170c5150819ee54485be543a3ba73d8a0f90b572f45c47de3d562c8a0fb", + "035b8106993b28e02ec88be337c69f3c14a8b4f5add44347542e670bb172deb5", + "0c445d77610e223ece4f2a5c5ae97d0a50dc0dd0e7e889b88ba2dc6541a5d233", + "74d360a1a1e6ed3d0fabde2df7b1fa033b2b1e48554e4af8f7b98054068c8b60", + "f05e3e100a6b4b4f48b772a7e40c011d8f6bb12a404fdf5d5d929187b1930b5c", + "722530d9970febb0c22a1030179177b828dd489040b823c25688834dde02f08f", + "b2fa9959f9b01f92e1fd633190891be353ae8ae34faf8463f3fcbf629b7b9e25", + "a5f21605076f8b07fac292147c216c874a30130bc5a7af15d89b14e9d88fa396", + "4d99351bb4d1711ce7ae93e90b818b187d1865865eaf082d8893b0449fdb978a", + "ff67c637168b82a2df8201dd29afa94d5ac55fd72532588b7a9f6eb8a4025604", + "02c09ac0a843627146a4521a6c8894d6ba9af7f473c1f5c0b959a22ec7a58d36", + "7f6d8e524bef9b4c6d89668a75a699930acc378f7a53a8b1adffb8306f7c8029", + "e37c6da97885db93df4bb1f688878557b44a40429b64389facc65fb93c08afc8", + "76f08897cfe7a932416d5fc52d2d6b4e482753a6bff651a282d44d3d77830849", + "349dd68353a279f5a1150c7ebc84bdd778cbb8fd6a9f1b652686db9ae5bda7fb", + "afee67fe04ea21cbd65bbfda68a86ba99558544ad6557e226445ccf2bc755b6e", + "b5af8c9e5e4253761132d385996557b2be594775dda41d0bd13a18eb3b0686ac", + "c84680ea369e96431ab14f229aa9f21eacafd05bac4ac8698a23870403b29ede", + "41ba1e3ff86532580cd88cbb75d105da1c2e35761ca16c1552a0d572830d2171", + "795959c242303cd1bee55bc95e923aacdc12c6de2c49dfde437622ec7f9c7133", + "cc9ecc7e59a6922b3d87c25b96e08632d231bd5cce6b2ed94399832137542243", + "9ce237b1218c2e95422f3e40f575461c40f58ce7fb2ddbfed3908d1cdeeaed75", + "567d787429f8edec0b0076cc61db7c1a88e8f68842af9a0b85396cbb45aa2a24", + "3dfec8dad24f8b38a0ad67bf9ab3e2b2e3487bb48959954f74f14d095a45f37a", + "8417c1cc57950dbbe08bcaf84b55072a922244bfa7d48e04db43141ffdbca913", + "f78af7c818901aa01f6a6ccb7b5778e18f9c9d8c6e6a20cae6d3dc3814d03b4e", + "43028fcdbb8db105bb76b5a0f5e76399cf903329360f2bd029d9c5d3c5c9cd17", + "d02e2200561057913638e93d4804617a6adf91e27fc28dcd4c474b9072f1d8b1", + "97f8aeb026bfe666511b1d2110ffdf78b140175ba012ecb45ffc8814a6982281", + "4abc59e18137728e02406b417e0565bb0e20c0e4b0b2fc762d8d73c71da8b579", + "8f45dd28ac1e4a759011ee7da15b5f9d5bc46191a33c88b12005ea954c86236f", + "47830fde00321b6f4723e128b075228a81a4206109bc9a8815238b3862ed001a", + "a205dc98467a01a10e1485bbf41be721208dc0c5021f8d32878dc337da03562e", + "79dfa718b3f1697c9fd79a6cc3558dd0c19048e05f858da85523bf91618f00e4", + "6b0de0fc05de0448aa4a01af00f288345344ac4823529896a8479c7c4284c900", + "1c2da03d56503800304e548e4e4d7ac61601a08e69b72ddcee2acf699b247e23", + "a48254517584813e18d3474c4b08ec5a156ec10c1c23b74109762ae66854542b", + "a05e8dbba7f3f9b22b2901de9de6e4e7bb7814166909e62d0cfa7f5ba6f40f5e", + "6905a5057660990fd4d49ad3b2e715cfa3317bf47b5903e31d1ff1b115284b13", + "5d8b9a84f79f87ac253b2fec4833c3bddd642b2bfe38d7f739c3bbd3acd6ba25", + "7e73ba9c4f9bc3d155b204aa3597368a13ec743d6b00c89a03b4a3a8d2faf84a", + "df089e02a7c802a1657e18210a76146925168b5cabebc5d2e937cef5321f36e2", + "e93945b9933d67d0646bd480b2e4b39c4e647e81c7220a520fe34f6fb7a27264", + "6e26474f78be6ee8098e69ed7e2b554f07a917b94c839ff378503671337977cb", + "0dc9fc38451f0e4b52686029d37c903aa20b0bda32035cea4adfc2005fb480e5", + "fb4157b88006f018e023fe1d44c6f3412272763a6f773d3bf1ef2afff676d7a9", + "3d5af380b886dee22dea10460c5e5027eaf190c91bb611f67cbbf4dcaacd5373", + "21fa1a35ffbb65aa825de5cf67a270c7b226b84310c3b7a6f6a668f255fc2276", + "b87cc96c7421b470f7ac525cea1478ce9f8cece6d0c12d264f8842ec7b128b4a", + "c913194d73d6a164edeb6b2a1f78ad484140e6abd60a9706b3c33a115430d00b", + "4f8de7b71b8a5756872b920c1aa71b1ce4347f12c8f0fa5490e08e434bd1441e", + "706da9f5d8a6c34b9767e7d356eaf052c96320ff4f80db216e89646e2755e1f6", + "2d76e32e663651bef59377985e9437b816690a7ae894b91cfd53248773085dd7", + "304302c78e12ad929b51de8ecb32ebfe603e1f23302546a3ba0dd968296e2ae9", + "958c0433febd802316f48d5641988ac02c6ceb1226021681de5629938a91c07f", + "7691912f84ed1b947b1304af382055b57dc650525de9c40f59eaa696913d6c57", + "56e146d38d80d09b378eee09e2e78260210b04d1e2a9ae0e3a7ea0e5537d3cab", + "27b82f30007331db981a87bc6b62412953cf20f799ceb96d66e4c6539dd16e3e", + "affe09931bb7719b518afd8615d96cf0ff6b029a5adbc0ca817474a5afde6843", + "93606f92c4bd6cd996dce2b7e69fca1beb0bb237248e12329afaaa8a3c5fc9a2", + "5570a81415c352120bd66450a6f66cce22c26d709a0be3a4720a8f1bf831aa83", + "92d498937e2f28864bd4b7b94db476d4510a6bf6f1e25407b047a8a061bf2d0e", + "7a94b8aa879cbbf4175aceec708d712c0e7486f2208429df132066364e22e7e7", + "b629ea6b630e33e4f7602c782c5daca4a40b2e6d06edbd6c7203e9c03093f955", + "ef37e6a9e728472c5832fdb69376d4b771025850a4b8d122501b016475ca10af", + "207113d83c4255824f701ae6141bc6b2b3edde1e30e7c6eacf94d8f6b94fd1d7", + "f4b85b3e98afb3447ff3070a1482b2ee62284a758282427e2eacb15c263d36f0", + "956c0d26f44d6da5b4ae0fafc45bc0fddfc1ea8db89cda0a9cf6e4141eeafa93", + "2b1b8d0e58c58d03b778fcc4b1bad4858782e29c26ab2b80471ea49bba2ca218", + "ed68549d1995086c30fd2934c942fb1fdd38c5c3094170760c50d37bb766cc95", + "83d6076a3d58d17ecf0ed21ada56757c592c6a40e6d873c72e386c4ee8cb5669", + "44f1fae8f01dcc3491c02effa7aefae76ffd038cc1428c2a78ecf71f82fea795", + "a8ea5504fdad4b116f87f70ed9075a0369845ab5949b0bb493e8350e10bf9906", + "ef8d0fe2d51d3a140f9729e05208a7444f89f705c670710f1b1fa3c78a04a12f", + "594f2591e70ec0759e5316138aaf80bd35d94c7bb26f098afc5d8eb0a5a04bd5", + "f10521bab6ad4f3606b36c09f20e5f5622fcdbce21b9fac5d1caf424029e8dc9", + "3b9072646da7bed0c9c0b61719c03151efece01843d7257c9a14db12d62289a0", + "34bb7a1c93f77ac8b8938cc01bb40ef6230d6d0bd6a982651a14f243e48fa5c0", + "7463d5b29a496d507ebab02a88fcd7bed8fc65af9e604f79c014c8c80862fe7a", + "17fdd9d950ea69ce5a76335b899f3b74ce4840862bbe09c4ad582b51f4dca07a", + "9953f4afb8ee17d75e65d9aa0f35201c22b012ccdd97c06c4ae4f11869a7037e", + "4c5fb7e50edf81a2e39df3f283d1dd1e6ec48d968a8830e4548def0063902c17", + "e2c90f645759da5f78b2dc0b06e1658a8fc355622fcb9351d7a1acdf5875d217", + "0c8307c274ee9f89c682def6b11d0ac87f0a58120bb31d936d1bd8dc1f168881", + "1a8e5be35c40245cbaa7ff2df2889e21bdf1a3c445fb46473e8b1e28eaeef487", + "eead2ebfa7fd861cb53265dc4ab71da145f366e488adc5c515b679b3c4b5d35d", + "01ab7e82f775ae597474271ce072745e97348774bcd4be93a71309351f3fddc3", + "1b1cc74a2143562b2e37caccbc91bbf4bd74ea25f5472a197e48e0576b59e423", + "d806ffd6cf4cdabb9b8876257874fde26dc5d49c39fab41acfd743b2372fbce9", + "a0aec0a8b72b848c5822797c1beeac18ff267fdf60c4f42d1648ae430a036fed", + "622baf2b3653fb2bef2b6416dd9d42ae6c297636a61bd8adc5fe9994627712f9", + "0fb116c025a21c891a64c08c6ba3f48b38a8bdc5578f73d66cbd3c7ab0a60171", + "5ff98fbb713b13ecd8170ac216d972cbb8ecc97a1d7cf4bb40b806f7ab90fdae", + "e91bc13bc8eecd1a98438782f56f6abec5bc2e1c841de72a68b489d39e8187b7", + "65b05606cfbb9bf9da3e49a063ceb4f11fc025e0a990768ae7984b72a8210302", + "f9c341c03c6b0934ffb9a135c5143f209bb7a1dda98070eb5e8760401b17eb40", + "78d185364e0f8668f4fea59e27daf1e3b24a4e155a44bfec02a9ec05f33e9920", + "b36cf96603dc1e88f99938905bdc1624afc249d8550ef2e74ac90114b82156cd", + "77bfb71245ed9e36d127bf353a8126f41b6e768e326e332e26c834349903cdf5", + "32ee5754e8e8074665de6b288644d54da07dc9e93e2cdaf54a1160111614d6fb", + "3ace2617c0106fbbccbe39018ca9fba31a47ad01201f89f725c34cd232be23d1", + "aa10b58a3e2c35f7e6c729794bd87e2f2d53418b6a936a7cffda48eee4878a8f", + "cab06e5431046aec0af29074b9ff4e82ee88b4a8750d970307830d76a44e012b", + "85d391c145ebed8a66d1a22d1041ef033bd26b86c7912ddce86fd7526a741e23", + "b6d04d1076a4fa78b6d22c153c02080c5b08758db6aab60962b58e40dd8dc7f9", + "5adb54df9dd30b68fc997916027fe675d58ef8db9bbd216c49f63ab8dc59580f", + "6362ea0f0eee5a85d35c27e2382044eef74270fd6463df9634365e223605988a", + "c437164165addafaae608cd259a909b2a5591601fe22706cf6b7bd1317b1c01e", + "8d4201687132f55c55cea77342b924a9d1ad673d6b8dc7889b7f4ea38dbbfdfa", + "00422b82fc8e019f27f2eb1aee7f7b460e2e974e9c6527b69b80bf1ac1da98e9", + "fda11cdfee6648223f23f25733dae51990fcdac8e0969a23c06ba3e04fd93d4b", + "6196c28468b5c85bf0981c04f4424f212097bfd8cfe90f9b80beaf3967ee201f", + "9768995ddd3bcf8f57e6e5f8a030b4fd99e6d368e180558ca2a6108f45fe5320", + "c836810ac299374eee30991bee54f901cf21273c4b9bef90368afcba8536d751", + "2a8cfd6c33d534dbbc5b9f0c64ae5ab103114c0e610d347ee1a52578815b8dcd", + "a5e27fd32c09af1a4abddcd8300070f6368e3b6ce89b3014aff037f795346a2f", + "be6738dd0ae80f7c287c3e1165d47d31c8e3d8d6d8bf1c4f1a2d32df05c5a61b", + "0f4e088f5b4951ee140d6ebd1ca8635cb1f8958040e4f16d5b42901e9c902a72", + "1bcfe81df494916206cbd9df1bee3ae78e595ff573b4ded17380de4e00ecd70e", + "eda711c2d53b7de0bba8b61de88f46cb834cb61d65deb8bd5f4ed237313f5930", + "a45bb86c36b05eab668588171db901476f37293c30d2a52f24d8af1235678bfd", + "71ca91bab5f37c0c89429df85fdd0ea8fdd3f758c19f5762ffe43021deb03feb", + "9c218c1216c537ef11aeffef0e983c50d19631131bf5e98c5408bbd66de29135", + "edb23cb474ac14aacbd4782acfa7e6f9de2e7112c242cd8e51aef793739651f5", + "411d88ff504c14d95ddf6aeb4b9b34b9721481879d25b1b92b4d8631e57f5238", + "d6558bb33b99341b9ff4c33dc3b035bd4d71c78f338c8dbbf3f5719cf550844b", + "bf49338931f1aecae88075ced9335f29c8ab487b5a284aa6ca477f7336b431b0", + "03d809abe4785ee63af49b2ee9ee8433c2487e50749524f7011c729390814830", + "dc58d7323eb4c80b9742d3edf7841ccbf9e453fd02f9ac881c2a8f381d603042", + "5b0a577b0fe3f01fc4797666f6744c77cdc2613f5aa7bfe37523d2802edd35d0", + "2d9f224210551abbc9a13d2c225c74176313d39552e531853e161c57bb65b41a", + "38c6fda298e2a2b87cd545da152b4c310578237f1610b6ae86c4412160f647ff", + "087372ffa6ab4eb776fb3c10bbedc0892c9872b4176068abc6130eef0aa4b055", + "23523b0d1ace4239668ebc10264623413e37bc8e1dc9e7402e3c3dbfc5db05b2", + "32fa6819f27101acc8458ab1803b7ea316c6ed3490639e67136644138e8500ee", + "b25849a7b6a3f8370aee419e711ff8b8d972a3ef6880345fd66c5b5fea1683c2", + "19b425357ac0ad4da1d197ce902e8b802fc5b2c426a6abd0d6b926407c551a2a", + "c0567e124cf74b903a2596997959038a322ea3e41fcc62c1dfc6a65266272bc6", + "84218e217488cb25c9c1eb9955558bccf3d92fc69ea60b0aa50db4f2b3015685", + "d8f7d714bd40418600e04cd4fbd65d81fd3d2b6f19c966f96c0c50823a5373e3", + "92aeb049ff58763c2be28dd58c58d141c942db057ac88952bc58268800513826", + "20d7214b07674c82ee04c70be5c4a1b398262a0f8225ee8ced2ac05c6a80171e", + "c1c6b0cb3b7ca71adb0175ed690f29c676b668046bb5475d1da913cadd38c6ac", + "4f130ab48b5230bedc54235ce3daaef35d839038bcd11134045ae943a7aa4d46", + "22f505aba86678ce6f552c3ccd874cb7dd0aeacc3d4912c843b0af8f195ef376", + "1a60a29be685121b30cae2a5818fd62920dde58372999f4d8761ec74aee1f626", + "ea235c65f1413f910a61be78c038d6875c1fcd59aea0a226b6568529d0a2f4f5", + "7d0603ec3652c59b81a1f02984066a6b80970c2b834a0b53232ca245a338803d", + "0e78d85666ca93181ce2a5d4a6f052606d8e665e677d80e915636496bf5f84ab", + "9e2e143b7d45afe361d06553e30b3409fa66b8f5c07e12ca6397783dfb2325eb", + "88188521836323027838566ab20dbbbe8df1d461b3c92bf3497faa19a1bda81e", + "49776f2f74cec823befb80f9bdb24eca88c2748c6d9326c8fe4ae8d9f97e641b", + "2559edd2bb7e854037961e34749177ce662e6b9a756790c1bbf55bd06dc62395", + "911dffb2310e2f95963eaa85d37cb867ee9ebb54125a8e619bee42d4c4f652a6", + "48495c9bbbc4d7c8862780872a2a4e52d2cf78d27d70f975581fbab0f8cdcc69", + "90998b5b86fd2d16b6c5f0b8fe419470779fb113cf057be25c02da1fc2ba4b5a", + "4578c524bbb56191bd43eaefab1039980a17573bd4b65ffdb324f68fc966dbe5", + "8103690f780dc0b15f9888f5ffda8d7cf6c90929af5dded5dc8a58f0830829fb", + "e0c395edd0066622a82d9ca28959c633ef5772efc46d6ceafc2d33953339ff8d", + "b8d0ce688d1d9768ea6352a5c41e286e5a42c2a01c111d17a26aaad8a41a6f6d", + "9fd262a87922906ca382f249a798f9685b24fcec55166b6be561e7b2a8a27fe7", + "9a660f6608b0dcccc72a1ff54aee9c9a7b6e3d0a63bff509ea2806d39eb25b31", + "989926978fc4cc31599973f3df334ca3763b240f11d28de1c306c28c6f72b09d", + "a7f3c72197018524e9e6c41fb79cfd436763c04bf763023e3446ba128e38d368", + "275d25d29f82ba5bf166f7ab65994da7e7e588fa9e6ef4bc163dfc5e9e77e33e", + "907aeffd428cbd980202d287b1b0a4b9c50dbab67184d4f2499510d9aeb713f5", + "3aaff9b827f18a48799e0802498594aa81502c0acae9279c68eeff4fce78b3f1", + "576f19bcc22a92b8733d11557ae17c7cf52f06c9e24fb55f152d0146666ca6a4", + "3cd7afee77216808fef69833c2fca880ffb19f64656a8b0595b7c7d88fc6faea", + "11b31fd491b7fa2061228dd558d59b26f464edc2699d87777601fa830d9990b4", + "9418387140cc22a0f18531f6c7c549ce8e7ad74d63052c3cb118b7325ccaf1e1", + "081f1adeff477d6af2de7b493251cbe0dc2b79bfaef796a3c1d9b54a32807566", + "c9b711d0b8a227edd9c27051ba579a85501cd36b5cb149b3b09f0327a1c22d07", + "847b2b975bc12185d72b40fca2997b9784ab112f050df69f9784a99386cfd092", + "9101788b00331d32ffe842f088fbc5f3ff25d6b18771c75b2c447c6bc47a9440", + "dbc2291e4da8a372547bbc864b1b1087bb61e91070770c515d0548a07f9e021d", + "e8b89199591e71bcc6a239f301425e8245de366b1872aae40f57a49dbd0d69a8", + "a014322ed4e9db72eaf6421b6a18c4adaed5afa737ad9faa9065e809b7594e5f", + "609574c31c7fe51072531fce862e5bebdeacd2c14234b8aa21450d6a8ba94ef8", + "afd2f77cb6df1c3b6d2b7750ebb51faeba3ca0a46e384515d57dbc5bdffee30a", + "c996b5611cffe2ece896c5d6eb56d344fe36cea9392ac6f4cca0330017eb5967", + "1fa9e24bc6230d550470aa6a9a31f8f82a7b319cfd2892b27bfcd62143f0d6b2", + "7ce780dc39bf661b997e120aeaef59dffcf44692476ccd14b941a95b0bb3dede", + "5bed4dc93384d07d1604fd49e937c90ed72bf94001bb714f29b1fb3c0a743486", + "66a012e6036f366286270b65b2961e9fbcdc8355071443d5cb5e5903a08f2d1c", + "ca24756fe050c51e6132257fafa09c4f9b7ef30ff62098ac98950bfeb7567d2f", + "353cf39055b746358be323e5f98f844b2ba733c70ad39963a18fd043b99f1454", + "35cb3fee07d2c873654b9b6c7491695bda7b4bfe232f1a65976498120666143e", + "cb867360ea608f6fa18c9e8e5e264028f868b2eae3848536e92bf53b8f43a678", + "aee43ac728ff01d46e22e611cd2a535d45fc63b27a11911765c80868d14dc1f2", + "36fd1b2ef2c6b9a4e9758cf17775561fdce038febb2879f521ca7e585f692cb2", + "a84bdf1374e2775d65bc9311b36f106b211c25dbf730fb835d3ec112cc353cc6", + "1dfa5a930a986b10f736e858629e4679297041a8d21f8f76908c885630c7884c", + "04b4d3a3109afaee60741cde7b7d25a899dd4f0a51682bea87691a171cb1ccdd", + "e1bb403d8366e257a30f2f6789c2c0066f2fc4bc86f6bc8acbae228e17bd24dc", + "2f0f8a673c20dabd7339eea83782646a0059eae826efc02583ceb3a422448c2c", + "167f97b4e6fc5762b21bf8cea42f0265ae99d3236f8c443ba1eab59bc1164b4d", + "a12de4929b4751cb5d25a2280854b7c12104ea91c317d3aa1e3f749c9363256f", + "8b998b160f485122037942da5825169b928f313f09f93de7909d2bbb8e3a7b3e", + "8d92e91c4faba54a71433cf3f9385a652b7471bfe4f465954e416ad821741df8", + "7249c4159e44595311add690e84349c7d501417b038a9dc77b81c98df40b8ffe", + "f57d67e1e419d400ff5c8344c2803a02a753462124ef3e57ac0973caa863cca2", + "e2348f736f3d142699ea8400b7e00ec6e4f8620e83876fb220ca7831e2692a95", + "1ef58ce2362cd2cf6715933ac785b5b97ecbece1a8fd15d858de6a900f2f1855", + "6b797b79205959605468239e929a88077c1c661d74f41e3eb7a959266964b0f7", + "34148ffe4ee1a190109274ef79c6608c20378054136b05849b658faa456b2728", + "a2d0b1dc675c4b9728f64848227c6d16d154e8dcdf71251f6d577400d0580867", + "926f07e8d83500f9eee77df69ad211cbf39b4a34f39ab8f65795d621912d9982", + "a299711201f31c6918fb0f507f6e2357ce7177fb84d4a972cdb3196aaa61b4fd", + "a6ac8ec04e9358969fb3ccf88db6d168138e255497dd71573272f50c63e77e1f", + "ef90da16ac95069e9c9e778ea3495608ab4f036a0c7ca4c279ff5df01125da0f", + "16b44ab677c9498a0f0746f963286cac24bf65c1d421656a8f29d5eabd5a6a75", + "a4be1fa8e49a6f6316cf8f5f94eb4cd228eb6974026efb68fdc19199f3462c39", + "69f6b5046dbb861abda4c8231cb7eacde7a45497e2e53d48e0e2b0d530dfb2cb", + "e979d5852d7bfadb276c39288ed35eae752bd5e3647e3d090653af996474e1d0", + "4e88cb388fea5d16f2d26e60ed466faadfa12040e45cb99ab9c3f7697ce1e167", + "d194b5a5a28fa6b300505c3ffb7a7d5abaa2c9ce4c1d1701368daca8a1e483b7", + "985e4e7498cb03e97e91756f2c398bcf8c78fbb3effcb60895a85bf2ef356139", + "00ac5842a84ad967c4e1cf551356b023007590c9e902bb07dbeb54baf60ccf2c", + "74735013f0110ba6c247eb9b42a138d3749c59d1872822ab2dc6e6e349c7ef31", + "c37472f8c81bd67c8dbc5748aee78f342963adf1f69b4cf95fe80f9a8e00a8ae", + "204e084c7ef616a7cf9bf55a92a282194dd87edf9d9fa2632095f53fba2851a6", + "4e38974a6e1c3890575354d80ef97c38c586ad4b41be22e2c02be83d55f08fe2", + "70436f197cb2d347d7e96678df02d27a0642b18dce242555cbd32d5bac302d49", + "348fe724d86090892547432fd57ad38226049197eec52301d48e61217269fd13", + "74a9a59dbbe49eefaaf965a927c7d472f6c428f7a52405707d0d0ea9a7874f9c", + "379b852d467adbb0945f1d4fd634c61dbf162e8f24916698b36971f575847c58", + "0b990141d49dbe1128b73402484e4ef678be8a740bddf19f9b7dc2ef5ea8ae94", + "e253239a4b8d8333c71b52550b411176ffc6457bda7b4710bbcee9829f34efca", + "48e5bda1a95acb664d8c9b8b0f066868b1d29e9f041e7fb655c08642a8d16930", + "d20ae15b94866ea48f9060d2595d3d5aaa63d877ff2f13ff9fe2d082df1f5255", + "b90be009d56c8701771216412ef0bc064e4445ab984b26ecce717aef0f62873f", + "53715835b595554d0f1b8cdeced924312c177ec68fe6500f7b32ad5c6d33ca4b", + "6c2fc759a429324c361d474f4035b3ae04475192126f0c6e88276ba709a7e01b", + "8d1d47e3155cfcbefa888e9f20d7e9bea8a6d17028d5455dfc6e44be7710e4df", + "ce607f5c2a6d39530dee820ac4a52748fbea56fa95a4d9e527e6cf2c902f6e61", + "d87db06d4620b7c21526327b1717928995a5f084ed37452f9eed9759f5e9eca8", + "f2d390e7f4ca329619c4973b45b3b0c1ee573c011522a780bbeda647a538933b", + "cef71a407f91c06ac3aa94104a549b450e0951ba2a731ba9c3ffc014c3870586", + "a9df4b16e0feaaf427f48874284242015df752e365e36a6f40f2bcca306bc2bd", + "0e2bd248e80af711c7d49c6a284ebec54ee3310790190ac774984218df39b398", + "dc80ca57aa4a5d176976b18edb776a64a15ea54a4b9145949fbf703242f9890e", + "7e51e93ce5037e3524ac68986fbd68df6bb2843b5baa1cd65ad74ff4b1e3f127", + "0b63415738df95bf6d5422a55fe604d629a29c6639a2d46784a26f50a3a547d5", + "127475d18be9a748dbaa51bcb602e6921eee731593e0a89a90edb0bcebd749c2", + "5170f13d0a606edc72ddab49d973dd3f62b92800bc474eff52daa702f6592036", + "e63aa0dd87017b91bb057508cb85e6dc70d41f90d588a2f759f63430cc99c8d2", + "6132715ed4ef8b47266372be1fd662734ac0173868dde81cf7bddac33e02ce5f", + "2c6e76950a8014af8c51512ab15626061673b28dcb53af7a8c989bd3a1f26b60", + "ad049c11c5c0a382af49c324903fc2eebb3d53b8b9d02400a1d9189c12277ab0", + "83eb0293b51f2da4f0db15635a8398cd73bf81a1d4a192234edd8ce5b0904114", + "5e67f1d09b305a4fe57cefcf3ad02a6c75956b56bc0944042b21f6ddd87ebf2a", + "3bc06234d8228529ecb975ee6daa89bf937dd341de8c9b56e6b5d22ca09f50f3", + "2459a25f16a2f7a006d779e74ac9e052e65dde65e8c7d722e0333bde21cb7433", + "248b97b6f948ff91ff7bd714932ba80811c15e6ec3b27b08766a82fe8a54b4d9", + "2fc3efd241beb99a14ab740632eaf14146ecaec2a373cd9c0a8d8029fc9658bc", + "32a624df3699137c6af2b3e7555211f09cb6f3709d148526116536a5323101f1", + "0996fe1298dea1910e11378688779f745f63fa45f23e2718dee91af9050bf7cb", + "3ac16a3c6130ce4fdb7abf001c2b23ffaa0f7ddd14fc98121c29b86e7d056c35", + "fbf045e4b91251821888527589691f4948a77c39a3a64bba84ecd68fe63964db", + "756f65ebc9e484df3d977579862b557ed8ef80ebd8a2c71ff982dcab33fad9ec", + "d4a38c3e8819b1e5e5720978a1c130abeb8a01177ab72f56de23b89f97b7312d", + "4988a7e8708f8b0e09c433d625a80cef5db13f3e7f6afae2a4964bdd8f68806d", + "02dc8e9d25967c96372b8d0676896496c1a001ef5198b20bebfedc8186888731", + "db1101e91c74a02d5261467665f7a6752cbb73446a7417ef5a93a97dbeb74e85", + "bd1bb5991f0532a82a9be81e99afa4e95669097dadd7615b9cf4f2d4ebced32b", + "39488a374fb5c45b6662ab2a92761016a344bb48ef35927834e881beb36cdbff", + "67e76b6af24e30ea9c3bed0d34fb3d0af19d4eca1c0cf2f621c856e4155fccbd", + "7e49ad0de89694492301b5f8a09d77b65474087adb5d48892ed0a18e7bf5aa12", + "5aa36832c5227946e3fe1003c98a5e1e8e722a0ae3eda6aa4524177aec58a693", + "411d50d070a3d52cafaf7582fff0a24b0322e5c839d9473c812c57c188828fbb", + "1d074114c640eca20cb879f00578e03142658131bba483dacac16314cfd1985a", + "2264d7abf1d8e1ae2b5df3c13b2cc7da26851f47f3296b9614c17d58cf09d7ea", + "2e273f3ccd1c1bfdca3ef3ba24dc836d3a874a5fa49d69db7b1b6702ad9ab152", + "45ec225c05d5b10a07fb0ed577978a91716edb2f9de8f260071b8659cc936f9e", + "68b7be633319505736828636d96abb7d8f7e67b44c39468186e6e91c15f1a3bd", + "51db70a4f13efe9b7cc0eb9bccd8f98468f7cfc0516a523ae22700f36f7afd34", + "1a18481a26a0c9d691a151dc16c41df8f9f42422828a2e1eb70aad3fa8fc31c9", + "bae59ccea4538ea37b484227066846e12e12898b95ae1382e33e136b898c6846", + "3978ebe22df1324d72b65205fa1774d057b824a6646296e282a7ebaa15272d1f", + "427f549f103e7f0693ae1c575426abaf222cfdd875264b13eef6f11f6a2228a0", + "6df8c25c6f07946180dcb423dc3ac91b20c25a5ce9e70c9f2cae5f4e467e7c68", + "3d3a810e86f5a9d9f686c0a7ef49f874bf6b91bde85666d1e7bdf48fee51e1eb", + "d6b56a885f08fdb55c2f928746c1709054f25f4e79222b12bd925755c5eeff8e", + "0907efc37fbae8d14467ce98795063f05e2c319cd828298d0c2d57bb60e55938", + "3b9a034599f49710e41fe31e24384947aa6535b92e77bff633229f2545ec687b", + "9bcdb045dc4d257a6030d0f9718a01b0f35e897a2adf3537459fd9bbe9df993b", + "7c32f5bfe1b6597d983ed7eb2c15e25c46a2135b70276952f07849d5dbf628b3", + "b469f7d361403e14b5e2da6d1dd5f55c986a7819ddfd2c449250fa5055fd9c31", + "fa0396e35e3aca9afa4445732e134bf43db86197faf625ef3c882b872f450ec2", + "7e3cbf769c2ad82c8e25e3e1a70d4b1bd6925f53842a5c9c806e7aa960835745", + "fa81779aeb3fe08f7e3cb2e361e5da3bdf6d11f28831fb00cfc4fd091d772abc", + "c5c56643384c89e3d49627794560353ae9e88d21ad2b06a0d1cdbc6f17ed5af9", + "dce936ca5df17c711f291a939a1c8014817ab07821961ffe2aeb51e94cf483c0", + "b482927771036d5133d19f2ca99c0a55a1a627c0d235372aa53ce78ddcef4122", + "2b268fabda7d834a8da51f66dab7a0b3adb3e5811cfc9f2ab08aeef4adbd0198", + "113bd3a36b3235ba6b5c8dc2f656c3e1da38b0d5a2fc683ddb578cde9acf051d", + "1828ba8c9f02a450eefaba6d436d40b6f9a10a81dd94ed49cb2ed93a13288a91", + "9cc321503981a440835bbc1bd0949c9b815277beeba60fe82e9493a219ead3a1", + "95b46cff115b83d85e4f6c41865f25582cf66c75f335852d23277153805e3557", + "406acdfec59a179b1348e1a36e27d18aa6d78ad434b08218206fb35b06924dcc", + "af802d48cbf418fa972f8b7251634a337c8e3001d6910f5cb5f1c6caa10a0524", + "8b3ba6b5a33d056c737f6345c64bcb2202744da74a9cdd42c022348006b27356", + "723ba2ed129ee254b8a755b63309446c127515d00e55dae5c4ac82b47fa1ee82", + "5584bb5ec3d03c530653d3efe5a6423c01cfdbb9b3d2bdddcfb59795b7ccabc7", + "637cd98ffcf98a31c0f8cc7f85e6cedef1f326bd140d43c691722988b3972f7d", + "57166bd4fa3d2106742d4113958a54c91e8b02c3745cf8941985f228f12f7bd1", + "276b9c777b2b3905d042c8761f7ed9ec918775caaf41f58b52317aaf7964fd7a", + "05cc452ab0dacfffd4afb77e53c122aed9d6b0fc6584e71cc7517796ed530dd1", + "cb07ae00f4b8f699116f8981c4ee65d2ca12f2e54fbbd39d4b78a3491dd84a8c", + "c477884eade5e2a90460a8e0443faec5ad146a5ee943ad2d486fe87d739cef53", + "16965293c8164af2f617a54b0016eacaed58a144e2f27589933b5064a745435f", + "86cf4403642457aa12a24a93c289e5fa5b278c675dcdd47d2b376c25b65666cc", + "143b42db48558c389bd3dffe8f3eb4b195d85f9d4e73b7c1be3d048822e28e0e", + "1639d7ad10883fccd2cd0222d296b180c4fdb27143fd5cf2d7cb6dbfff98423f", + "9676275abd2e114cf46b18fdaa362220cf249d072a6eb52dcf24993b0f1bc786", + "8bd01299e999b2c8e687d84cb073bece42cb247b4313b456bcae67f3d49df313", + "b94912f7a25a756ba9f4b63261876c8c15c979975d078b5fae9b6d18057addf1", + "fb1525ac5a3a066f316232cf0e5663cb8f9be7e9578ebe02b51e582c0d06f278", + "09e45bee7cddc62bd2646cecd3cd03e5b7353efb1cb382a04483fcccaa370c76", + "5f42fa6e8333fd9afb67c08af91c21adabd7c3aa52000783859b429ea8f070f4", + "cfff78b0f29e85ea1a7a6753ae950b92608190926a18ed1e32369f9392b5068c", + "31dc95a20291480775c08effed39e45ec645a55d1d97c8ef9661a8d57ceca93b", + "64021b9be202ab6eb07700ad580e7b7edc4233be15503631e4511b1b8598d5d2", + "59d7d33533f173a585328f93b0bf7239ff5e9cc30e2b355827cb18c092e04661", + "661f4edb2b1f5a98a8449cb8f477a837703c855baf898e158ae48db7a8c82591", + "7502286f1e592e386bd62407438dfe84fc07c9ad3474d9cb64c7153efe4a2a51", + "7a7584d1ac728278a88d25625cc5af006c2ce526dae53ff74b614161c0ecaf8b", + "7a968b51e117657cade09973a8f888fd8786ce4c34ad50903635682fab523710", + "f72f62ce80ced3c63f2bdccee3e3bbbbefd42473c4767e9311b92b444952ef77", + "2db04bcd3f7cda7877e4ed5fd14a397164057db9195dbc28755ea74ba117932b", + "8494839281ba91bbd54c6b6487b16bc074d1a3d197edac77141361924f16a91b", + "3aff33b328759963ba7f80e9860aa119a40b60a67d5d37b49a45174b854871cd", + "79cdd99d33b439d19add28b0b9d7201e10ad5dd72aab522474a497f420b969c0", + "9f504785f7486f535da39706a14de8f18e650393cc65424c9043ffb9671adb4d", + "5beecb6490d7a4245565b54bd4def0a79bbb4e80e761cda0c63c381ae475f469", + "22f1ed17bd9e12ebdb8004ed12bc64a7ee59f1a31c024ad288c67068f122a9c8", + "fedf9cb03a36b74c199f71fcbfafdaad3acc7e66dc5190b54f99e7742aef7637", + "2f415d5d85b9b7231d48e7f80239c4a8a9c83a33a10b9350f927328f58285e8d", + "3b832bf9cea100ec77c60fc71d40a640ba8099527a6756f12df435ca6b1e1c9b", + "41e7869c17a0bee0aa3e03809c4bc700ae28e2a3fbf1f5ced8f5e7a3444279b3", + "d13710c8a884fc104ae0aa10ea9e75c0c7c36eca972b9136c626a893131de229", + "40fc2479a813f2c33b448213369c62fdc40657f1f0950d0e1d426d028c96120c", + "0177f8d25c597b3800e08da9cdae9f2de965c22c021cc5e99cfbc15a8a7da6d7", + "3e4d401c941515f18e9f826200a07b4f71964032fc6292a1421706aa8e71dcdf", + "e895ae39264b9f757e99b83c1e868cab2c5ae337dce15abeb4da89318ea51109", + "9f35b0daa1d7431d9851379cb36f86d55c165035190eae6dc5f7e9159aeb8256", + "aa56b391a6107d611dfef63e611e31be640ee2ec3a4ff8b6afceceb59fb6d596", + "0b3eff9e0e197554ad189c6f0bb88519d8e70658c62e65e420b6ccb80183f7ef", + "67b6e2d4b90502737acaf70bc2bf0d7437e117d317975ac35b6d08c8bfaa9cf4", + "b3768b4e5579adaf51b27364c96ae80b71f77b8923ae85c299c036cdad63c700", + "1a864ac4e2cec7291a7bcc2568738808b7a987a64d50535a0a205a82c154bec7", + "f034895721da78d38ce3a6cb310a3cf142b85025ac8a4ca2115860f29e6e5b0d", + "7c595ede9c842089d5adde5b4b73938581d93b14c2c05ee7bf0b68d439cc67b1", + "8fbcf66b02f5c19641c900f4dea707e665b8e703c2082121d4e25fb6adb652b2", + "e4acbefca8944d0d08e1524e0ff3b6dfe58a42e28f1ddf374c592e46fa16a6d7", + "b4e246b328ac77171309d49d0c22e2888322bff18354713cfc49ff7031a30bf5", + "ad517cd25e25e28b105676f002df17d25aef56ece2652471cca45fcb42e6a494", + "bc2256fda8a664fe801b0b2d24f742c3d68a63474c61ec979c7b8a3f3a4afae0", + "d008fbcf56f76f79c0cbae6836db06d5f9dd041bd7467bce2f4c7f5d0e2d6e7e", + "87ec3499fbafe3fefa1e7a54a87be3f5d140fc06a996e28ee92b0a5aba8e85d4", + "12b6da079c2b08ba920c13eaa0e3ce6095d1ead94fcf79bb458cfb9fc67625dc", + "88cb8208b91ce555d2854a652d051c9e3acf40a1a7f73b11fa6f8ca15754776f", + "a8550a8e10ad70a30a8ad7e8f6258e5042885c36e1f750bd415278e34f92820a", + "376a4e0adb15aee251fba98d21fd9e0a5a5fda2992e724d9c09e056d2ac91f07", + "405a7e48ce1f53437d3e8e27ce7fd840629a57b5987f2f4123f17223ff0adae3", + "147ea8b679f785e4b6d6c6e8132809f49323bc651c41babb187186b1cc440a7d", + "a6c9a9bfaf485bf28a6fbb382d84962da28b293604b412fd341cb41e4a1a67da", + "4485632864e89dbc1e97e9f69203b22c8fe3f6f0b650198743d1c96d39f06c84", + "152d35fd529c452ba3ccfadba481385459ee383bcf17d938bef7933839938af5", + "92624fe41bc65ab9894f621f620d59576416f94ab56fe9f1123a7a5f17284e83", + "ebc5cee81ee12e101f09721e43353321e5b748c8fc4449cc0736b9eed1980d4e", + "45b9e881f3541b60e8a37d805a7cd2a976e20a2377a6f61c2273be09d8469bb9", + "97419794c69c952728191f7134ffcf6fd1801ae4962a05061dc73aa3684f23d1", + "b5b1528732b32af835f150af424ce38227ed13787f3aa0aae41a2b4f46400c87", + "c02dee81490f5a1a169b7c7de4297171547aaa20ef80c5b2b757a7a69916468b", + "e233b76746a6cd8305298840fe7caaf4209846ba68fb3294721afc49fb208db3", + "fa5f2cbe8090a8918ffc414f40ad311105afdb75c3e17824f7ab9605113ad8c3", + "d46b9c8edf3b2f2019ed187825d1b904bd8b7a73662f43b9e2faf590db714a24", + "7be47f17a768e0c01e0f9381aa35e095535bb1e14017df81102acf0fe2b61491", + "e5d48df4570584d57b39ca39e2f94a5dd0611b0d712df29cfe05a8c8752f4e0f", + "9e888d8aee65815be9dc371f6def84e9bc5bb7db5b00ad0abd82381de9738d7e", + "350801dc687faa5c331a1460ec570940d4c95882b7a5f3c29a6de7a7d031bf6e", + "9879fca36a55838a03b1f1686c274527ebee211ab5441f3b51fc1417ad2e8e8b", + "416db8820f6278ca760daa5a0713e69358b0c81a8615e48b58fa6b7aed62f630", + "836433440155c9598cf0cb3ff4681e70c6cbb7b1862830b659040e7d343f1a44", + "ae9f0a3b0f2bbfbed096cbf1567a7b49b5eeedc2e88c21b7f6cb72230e21a35f", + "c118d8c0993d37d415b2179a974174513a6f30e09f4f77950eae87de8e374f8b", + "59fdc9d52c02a29af8518466a6d5c2aebae1c19f8953143d6fc4d484ceb5e1c4", + "309e3622e87a422533b0155ee3cbceff89129de0b0f2c52a7f0576b5dc8cb620", + "ce8b9ebcaae8d79f6c3eaaeb6d3e0f9440c5ee6d72443bd35ee2d2c5ddf23811", + "168ae3768c368ac44fa4291b18d0ce03517b97d1e1d098abe34027bf22b902f6", + "308759d8853b8c0b3080dda429df268b4cf7d66537405d664072e595f48d1203", + "fbf6f67266989d9704b9514d420eaf6b2e58df9eb90835912404aaafddb2565a", + "899ed62e396438aecb4c8b7ffe53391b5782262f408318808eab7cb4847e0bb1", + "4defd6c062ab03bdab3edd1ff278fb73eff8bf901cf91d317ea11916cf89ab7a", + "8d0c3a559c0311f87e464599b1ba88e95ffc590feeab5e305884b933cc45a234", + "0b5bb7633d2ff0ab3e3161e0faea6ff037d185b6b24844faa17ff00c46502be1", + "e8c3a14e5a2fc1af2d78eb5d8436f410286d031d7229ae73de784edc37ce7a92", + "665d85058490155e366b8a145f6ea06f72e55e3151521d0750b896d8011c57db", + "8a0eb2c7030b8eec9171ece1ce83b20436ea30030d1987e0b024d4d6a2e32da5", + "2b1e25cfdbcd25c0d3ad74c141fa4b48522fb904f62951558c084b7a9fc88e63", + "893917041051046c64645c193d4f166e0fea79dd8cea06b4b06d713bd370c510", + "90eeb48c43d97a8eb7337e5e4a5fcfaf121eb84fbf3847b16f6a184f895d5395", + "676c25466d2ecb7d27d1a7bcfbb5b9ea0db8fb046e1b5cdeb78547f01c089f83", + "04f6439cdb67b7ecbddacec304c8b78819c82998b2ec067439e67e8b7bb15409", + "5c269022abc903eea64c58e277532278680d58c19114fc7670de370ceac1d5da", + "172603dc7e7a3dff1d688907b00cc4c47edea15fa763dd5667d70a8643bab385", + "1df0cc9f20b00caf864b06582ebb7cd3136b815720af143ee0672a44ed9fee78", + "297686dc33473b22fafb47baa96dc4a4a22f4cb8160816db6676a9d89032bce6", + "781dcf7514c3bc8b5ecda915f8d2a94f0085322a1c5b0137d509730c44a94e6d", + "c1794815b7ba8ee76523f04f2d50ea8aeda1d6885116e5e6d67e84cc6f273cc0", + "0b384f8870e640f615d2125d47fc0ff3ca25dbd166c7e4c3ba920446ae44b393", + "8b60957cf0f7e71f437c4e386482a34a32dcc2c2b1068e81d5638ab7fe381003", + "315b2eefeb4dc0d3dab33f7fdda0b73576172e8accaee5c9034a927bd98df25c", + "b6b6075983d100b5f6e00d01bf9fe6114237188305e145083137e032000fbceb", + "479d411d2afe82a68f4b781bedb9f71682bf25f94f313a9a044b62b6ea7114a3", + "196f9460bfdccfe9622ea0020563884b274ba8c9ec02c4a9f35d2b8116305224", + "92787b4d75f0cd905a12a73b4c78e7573440074fbfe92f9dc9cc6e2cad55d5fd", + "83ef320e67769260827fa3d053f43d736b1ed89f15aba9b502539bf1d874fdb4", + "3d99a0f1f47a85fd18cefc5305657b6657226b2a675190424eb1bebde18c8775", + "7034c3770fac08ac69dfe64025738e7175e3e573a3cf5612d1e5c29210612a58", + "3371e1683ca3aa25dfa35d6f50cb91739fb4414ac7ca7c216592034b9f9ead87", + "024b56f8ba9e8ff83403c2d1cd7a6d86939a8045f68a670db1fb400db7c91908", + "6f90a2b7c6c667748cb73b2c3c5bf9a1dcc220122c2f83709de106d24d5bfca2", + "b24d282ba6db87f85de3a0bedc9cad119dbb603dad1a499c677b19676bc2662a", + "ce4d6e93bd614f67815d736c0aacf542ee264b5584d56e127fab6287a99500a4", + "f2481d38efe7498a3185a97a309bddf9c6c450fe608c0c76318700a821775a8f", + "9c64a7ffc6683bd83509c491cc687955d38bc1d08a274cc29a54f101bbd1ac6e", + "bf8207e37666d4ee53f8a3818b7684b49497be89c4ff42e94b9f3d781bcb9dee", + "5c86aaa822fbb77475ff60f58bcb509e70d8da5691ee6f1a74c64bd94945afda", + "a546adbb5be7b2b45d3869ae16af67240605821f2a13129924b761d162ba21ec", + "e501f981605c826c27ef9994336d5ad1083d581d708ca30cac7b2fd23dd4de0d", + "25079b538382c491f2754f2b529415e5f21345ffefd09aa08ef755945c1c2e7a", + "befe34e5742262cfc6452b8efd19eb41351337684f4f9720c5d2f2a61f8b5298", + "9722f4e43dc42b0c135d8e74ab8ba97386d83a1c16cfcaa69981ae567effa9f4", + "2a60be109ce014ca187179f4cd65f4d81b85a23c8a1bb2d4bd446c39dd43bf13", + "68f54944bf6e1796ec9b28e21d27c1752b50e877696a1c43065a766ec17edf5b", + "245488851ef4beb2996636750827d3fedb053d7c348106be75b7719df80d78fb", + "e604946a8707680ad0ee466747769d3dc12c77db9b003b3d3b23fff8aa924a3f", + "7b081d60a179b9605c69f6fa434fd03305edc4eff6881350a01c5641025bb2c9", + "af80f5ce2e9afe00a7c9ad7449ef5ad18b7979b478fa88341ea15f69df963788", + "b8f3d2c6aff2d5bdbba4a7c948450bfde5b4c551b95216e91ee562c2310885c5", + "39355d84c5aeb3664732ceb6da3afdd53b61a6621ce2c016f09d773780634da8", + "0fc9bb0d273629b0e69d53709e637c597556e0bb2ccf511a221eb34f5fe1c66d", + "b4207674839256da79f552e4cce473ed4dede9d1dbbc846ae3fb3a2014677d7b", + "1232c6ba950016e3c26022c4dd178371b946ccf71c43e65f1a8f139d73c938eb", + "f4a6750b978b903921a7ec2edf01e37e4c1c1cf65a8023da92964361287e3b25", + "1a7390fa93c22b18929f7c6034fbbd285a65bf6aaed8b21a6a3008d6a102c43e", + "4da804c1ff1983e6d47f1cc963eae9666161bc9e67f7bea058ef2f5d46bf967f", + "e99530e4ff4e7f8b2be45be0d5fc90b3eea3ea49c389d01863869f961bc2ba06", + "edbd394742bf883928e10272a8e463dc19b20b8c32a4e1d6dbccb5149cd716b9", + "d549c72e5c2976a67598dc2e548d44ec0e34465af83c3e4e79d505fa5966ca60", + "e875d95b049dd2082ca1cdee7c0a5bfb05d981642f70954300c476c1bf8ac802", + "27c70fc2b1e9dfb3f492c25f8f43172e5acac1a8f8fd07e2d6fc81da3126fb62", + "ee5d8d83cd6794150a0dceafad8ee0841bc461dac0c7746c98530e76db0c1f0d", + "58175514b5c0720d56fef7bd661bdf4a408f7981f76e2a52d03de43608421b23", + "acfd133792afa0b3dbb8f453f074d6fa926b46b9e28e504bc9eb88a3cbe9aecf", + "dcc4c4a01d5164d4c4045613e0cada170064e70d535d77c8a9324b168c64f6a5", + "abc523a2c408515cfd1b2790b914e79125de848dd21c86ff42f64d3066e2386c", + "a0a8943db98bc98197736002a47fe80bf960293ff4f26e44dfe0439bf4ab3854", + "2a06072961e562d5039b7c17293d7f582a5fe736d0fe633875e5e5838ac4297f", + "78d6e10698db61c7c183b8df26bd14a8f45372353125de5923b6b523928e6455", + "1e2306a3aeb1feccb8795931c057281e16fe7d2a2cf7a566c565b0cf2553dfd8", + "1f9809b643d8966ce4b1a6c22a2ad382b400541510f97c0ea1be2d67d3d9c123", + "d763bf572ff38e2183c0d5c69ed19aafda2ce27d8aa2541e15f72473dc7e27fe", + "a1dc4c126ed1212db5005a9b520a1ffd688785b9d54622a63d9f67a124bbe36c", + "a94ce1262c243632ddbcbe0e5a2c2b73129a9b99004186b5e7036846f25384cb", + "587f46b3d3dfd12053060947f4461bff1d1aee32de41aa12126b28e72cd17f00", + "fcace308203823ed5e56f8c75155a8f89fab1900bd244fa8f6d7b00af701a434", + "2168336090f010c5fcb18328f9bca5dda2869114c53f9efd4c8766d6239cf52d", + "a32e88bad6490703b9b998f707b1af64abefe29e9481e0f3c17f149323cad4a2", + "c6a6b4acd3bde260955e3f9785c9aa1c541f0b5357aad9d8e5ec7e57568b248f", + "a86a4d117deddefaa701bfea1fe0c911479cf2b47dbc8759c23329ac5b3121c0", + "1dd6c45e04386184dd0bf91b65c5c4ac237685cc949637e74eabc9fad3726ac4", + "c1dbcc628a0384bf7a205dd105b7f98c7a82e329d05d2761658043e52804d4f2", + "24a907707e671838f0703fffdf05f053e55f4bc089faba2f3890473d013d2cc9", + "59d3e6d2cb32f5eae760cf40650d0be1ed1eee2b437fac4e7829030df72a73bb", + "d1876d4d74e7889f5adb2a6f485cc8a38c615e87a5840675f54d53f4b18b4bd3", + "37afce2f4aec206a06574617e18d9ea6e99254e16bed898a1c7c8fb54d068697", + "fb2e1aba55fa805253d200c94c3dcb6162fd42f9c5941bdc4b9f6592fe2e58db", + "d0910a4773fb46d2afd75f5f26c3afd75ebe0e8915f475b5e8876c292b420481", + "6c8a76d36a88a359230766bff4412f104d5ff0b351a241b961bd51f18956b285", + "a27945dbe20226836702cb53216db9497c38c02a165b591ede2ed6ddf7bac407", + "c753ea471123c16ff475ebe01d3575224a3be9eb1603d1e41d0b17d30f36837f", + "57e4225812bb0d3fbe55ee68a62d9abbf0165d431d5531b6d95697fe75f577d5", + "96b0c1a7ba73002f8b197cb57ca14c9f3cc92445f13c575ea4de3a8a677c34f6", + "2054a04bcc6d108f763314e768a62bd317226bc4eca71ad0438883281487d8c8", + "01c8d9bc4220d6f56a249e99057bf1307dcc89420f7ce04ece0e2454efaa249a", + "cc8dc4f368eacc08631f3cb65d9c93b1214f65087ef6cb033ceda1b86ef3e660", + "d1d5f960834cae80791e75059827f6fa4b5d8117a7747b54a3061a01542e00d4", + "c25d2936a5303816c414a9f76b883f98584042806e90c0f6d6cea5628294ae7d", + "5de397669976a72dcc61d309057063015ae3e995b97ca48185c50da0ef598e67", + "15e123a475843599d8c46c6e259e7a0c19ce535fa30c3657dc54d7d7e025b2a8", + "1470c745f5520ee24468ed2ad74216fec68b31d2e14b654cb2175542a3c80202", + "76bd3adaf8c7dae36f14ba44d2dc86479592c15e6b08984c7ce7fe8838e18d02", + "40d28bf7311b8dab97affce12a315fd786c094ccf1d0a21738023bd245dcfa5f", + "c18a5f16452c9e6de348a1183fc3fccfebe8fb36eca3ac73c6b03b671fd4f8ef", + "56cb1863159290b01cd6efe06c4124e98d3c7e23f45cdcb54a9defb7031a838c", + "50928142c5314e8cc97cbf24d33bf2f99f1dc3a4679d3d60a5104d0c64816391", + "88f5ded616699c1d95059b1392229ded1b0917c19b7e0d74bd08c0266c689019", + "3bf298019f84e40ad955c2fd0b956b3d60077890b55c4899b13ebd5cd3ecdad2", + "18b31291238ca853661b96495f2e1acb0190ce16128c98a656a9d7932917b457", + "510840e4e1b9d01184b4ba790412a8cbe3e90dfb63a648784d57612c08798a7d", + "a8b3e3bd16efdb8d83ea9f5da078ef68d41a69127e639b112989814d4526df88", + "cdc8dd064d825b2a6504245681d0c3bce45aa6eabf16d3e839edaa41948644f5", + "05b9948f3c7e51b6583a25156e715e2fdc3d92469c5a5596c710441cf344a874", + "292f4d0dfdf984a54885b8bc0d7b2ccb1155f0a5dce6d15095414925cd7ef0e6", + "50758ba432b39a6b7535f4a4a599346424d6e73b71b954dd3ba1f6e761294d82", + "f961b24bcda20d1a57f57690ea767c617de98bd46efe9f007c6869b73c52f324", + "e22322f81d6bd26131b1859f3d1646d362d0abdf8fd74a41fae2bdaabd42a1a9", + "c3b440251cb27a923b7c1129696901d440b0320246aad2c044e83a8f7a5532eb", + "b177ba19e699ec487d2c4a4d59e3d854df3ae4f134347f41264217e49ebd1d71", + "9ac1ea1f0a80fcacfc21cded5caf28bc06241b90324569caf7468c30e18f94c1", + "2010ff54ce842b4823cb54c5393b0afed99a864279352256023439e0b974968c", + "3e42325a80f57ef2bf385817aa579aa479656fc8f63f69ff454062907f1a608b", + "67453f728cb2ec974fa4b7fb2be7ce1121c7a4a3b11a6500861420360f80534c", + "9ace51c6f38e010a40f974dcb12cc26057a2dab7329526ee495db597ad212a79", + "c30fe1fcec81cfc6e43411fb301b4f403e7f5584719952c551d200e9e4ab7a9d", + "9ed420b0fc24de3c89385735e4afbf5cf15a80b18b6d2772455dc4f909f103a8", + "4e27e0340e32b5d0da3d38dca1a5c7d9d38b83c7f20251a2f5ade4daa728a501", + "0418638604ade7fec112eedab0155e908e8ff8a32dc26e865ed4b2ce96071c99", + "8c68ab2bf16b9312f340c7cd83a464fc0796f4bdd8607d002dd336787cc0738c", + "7f126490d7ea37c9e2934fdc0864c089d9580a9489b0f8e851b8dc599c42e396", + "02473d5aecceb51da6b94b706ab2ea543a511953ed832176d5a7b28dcd0d283d", + "bcc31b0ee737e272748062460d5962648a160ffb81ce6f051c84dc0e0ff9f429", + "df2773d16cda932b4c1aad889e7d7be121cf8f3854e251aac78a775c6fa281c7", + "fc718d5ceb317ee11255a2a0199fd4d3200e527391570d85c68bda8dc39f7197", + "3e2e1416ceb588ab07ae593cba6d668983f2d2b3aeffc199f3f6f274acf65d1b", + "2de1c7197e8d479f55cc91cd64576d513fd6bae8ff6faf791794c0dacf880a5e", + "b9ae3f60863b86c2f87bb788e1f0173e0dc19f4077fac73e908648ee011f411c", + "be810a5b28df5c8add513fba11f24451263b1e5b99bd8b08fccdd61f330b5839", + "6796232a632c1295139239553bf781446344ac7265d672b8c5737260337bc011", + "ecda851ba03c108e8e29e4f74ae3bd51b6884c2eaf9f309591ecebc44f32bd2b", + "9df14bec3c3e8dc1a637151f13525f12a45c640bf9ea4319b5dd1b0537107605", + "655d973c49e25b4843a6e76491d9b9eb351b8c3ed7da4aae78a1156e88b49121", + "4a2dd4f8f3574291c141ef4fe9229ffb85751f8cccca48f847a5b7944f356e39", + "26f2c54c77471bf876eca56636bf7fa02eba833265a9e085237e7df26ba2ac5e", + "0c95e5eeb6d97c9221b7736bf01e4ff1e5f4250a32efa655bdf7e1eaf8756571", + "cf414180dde875f296ff8dab4203fd93d02d80a920f1fa92914c0c54ca6639e0", + "71bc5404d68a2686f4871aa788ade4c4ab44e28565a858edc6d7861288755176", + "52a47d290ad8cd449ad0f6a580eb8e644c2924a10114aa0c59fafea6b386a471", + "8f9a5f0a1fe863efb313c3492a646c8deaf78227637c14b75119c80463ace676", + "03757f44bd3c73b23317d7b78378b9a0e1cdc2c4942d264f1308645348f53129", + "64aa78367edd23dbceb9fcc4b385c7c35b6278ba53a255f888c97a59fd50221a", + "993450b0b990b8088772340a6f0f679eac8f6895ec03c9b5ff92252db2ba15b0", + "3bd727266617f4240e61ee8717ac14d0462983a08fff6f08060a126d65e0c109", + "f92c1b309d5e0e7d46e6e3aca6decae081058bfb4118777c5b45e88cdf1f05a4", + "5efa082e6de6aebadfe7588bf9e4b55a3469992327d47bd754fc5604db3c8929", + "2d5df9545f43ef26b800d534ca05eb1cc3f9430a4063cddfb673dd40416dfc30", + "de21fc9ead8cfef0476e8f0c9e9d663e6b85766ac6aee052793f33dbbdece4fe", + "a79b9891a84db60befbe59cdaecb72045fca66318b07fa75d184fb3a27bf4b75", + "dc040a95c2cdb1a23b997f8fdf954bfdacbc296df2a5876527cc2a87cbef4251", + "f48b857580fe5b95ef604623d72b758951d71922ec15c13a446a27ca2b4eb0be", + "10efe2ba72aa4f2ada03e57d2789d6e23de6ca657ab40bec875083bb62985f7b", + "6a0ce5e71f246f9428d0ebc036167685fcfe80e7c88200d503edf18d51d88b1f", + "9991b9bcf9c0c518b7cd6c905d91fedf05380645a99c3570592a017fd3fe9335", + "226ae79b663f3b2331536930d563481f017912fbb8c68c69b79c92599a7b2f7c", + "e9b2ba0b659732a1972af8fb1f609c5b5362269d1011779f47dbab07b21e353b", + "3a7b2adad736da9d074ce054956f64f35c84d6a1ef813e91d29c200f5220f87a", + "05c1862dbabdad278971a33039f7226334fc134ba59757ef54569d7360bedb74", + "a99443f32bd57c897b10a4c3bd0bf97cf320c3a32c0521cd0ac4f496f47930c5", + "9e2085adc8986d11805479eca74afbebc899398a5e1f9367f54b439ee33b139a", + "3df49b8732a260e706723c9c29408226eb1a8815cca5edd03a73ebf856705e98", + "d4aa9cbd543694d3b458ba82ab6b866c962ab744ea822d344641162ee04942a8", + "c91952df62c0106adb4cf5ca6630a0e750d540784be5266c0046776f8b7d2e75", + "92aa1094411b8698caca8c22e0e841ba95103efa2df45901919e839b2de19af7", + "9092734a3df9baf7f6578f8e2430405682d2def348c82e3f173d1e6f6b0d0bc2", + "b498899dbbb4dd3bd39734a19b5447833545c530d926eb4e4b675cccff089d51", + "848960ba0f504b3eec388dc82b521268d2418ff367f196f0a44d9466a496d571", + "b7c35e1dd973cec598ad274de43444c0a330f5a7c008546d11bb6bc7752e0232", + "e6af102c0f007bb6cf707ac3fc3752219320057f7cd3216f647ae85fad7cd0ce", + "d44a48334d0651059dafeead3644bbaf885cd95cd44e41a4397d0d521e3b64a0", + "95157b8fcb52193e78dea2c2a1258f0f681a1883e4e1105665d2d77e98c34ac3", + "99dbdc6495b06ab25040e7e79f05c00c143f1238d36aeaf7c59d68658e4ed5c8", + "0ba58630d73ac9633377ea105840cf25856467f4a98e2c1f5c48d29d0326fdeb", + "fbfa87864ec228bcad3f6887fb2ee52a5d9376f2c3aeb5a7dbfddebb55d48527", + "43bb52896e98421a991f5531e55435736881de8b2e0793737954484be4ddbef4", + "ab4a4a4e7cebf019dd81c8cde1f2817333b28bddae40f0953f75502d5b9df890", + "5ebc695156827467ede2f8a59486f29dacff21c2b515b216f6cacffac658147a", + "fe76e16583b722ae1c41d080fec882d72c08d2f091dcac334716300800915510", + "2535941fab3a497f9daf02b628aab308cfa7c24d32c3bcf54fa83c6d3ad3c6dc", + "2274688723260a593aa8df9a1a59ef753f472186d39efcaa63baa0904d352113", + "d79dbf092246b619b0c37ba0aa8adbff74fc358b8901bb000d723553d3eee713", + "19e85d19ee7c2d449bba4ac8b5af1cb2d17d713bdd007f90ede78e2dfe2866d7", + "303b7b4ea04e60891d6ec948d8a0f132695e998cc79e6b26983bc3d7b166f6d3", + "e906d3eac8d45c0e85d568317c3e58682a347850ba53012dd1278ef17ed9431a", + "73d6c009e40dbe2d2113441fc640e3dd5a9a1ff4c036c0c2f73cab62556f3285", + "76fd02e400aabc04b367341d8385e0ff53087244dc21d9e57d6d42d836cf9ba4", + "a35f1f53ea8c6b6d5babcac597b75f91e8249498da4a99b1e6643863910f7bf3", + "7a1e3a0958abd2a1068e289467b49a40313c4594181eb5e9138456108747dcdc", + "ddae8cec3fa65d67c6a428624e38dc95fb1ec93fb89835fc9b65e9906cfce567", + "36623ee3005b0914c5462aa904b1c0c33c223f006f74a796508560507648375f", + "a75c0bab2bc84fca28d6ec37a7279bf43df166b785aa2747f205ac00da4085ea", + "28b46b1b82fb9df0b19c6da251991ce4df02ee63a8f3642b0ab53f19a2d9a7fc", + "af66e4012d60f81917a67e6a3f205849d782c82eef69f2da0fcfaa345eb33363", + "e8b659513a019399585845a7b408b59223819e5cd4626838d7f8ecdfa435062b", + "40212f5c3fd1b4f6b0c8b6436ff4c05f9682bbff5ff14275516440efb37cc76b", + "3090d07b7ec8fccf8e171370c5ed77f448f0a3b307e186611136981578ef727c", + "eda2321bd5c7a124aa47f26904a0d8e8fc30a8879970928ac2eb641dba8145d1", + "2fc434b58687d183be8a478fa3db779392c73d843f345a952b1d988acdf68473", + "7b2e4a580b20cee7a7338e7fe515a5e7bd5f033c302e70f264bf5e975cf3abad", + "82f2331285fa24fad3bc473b8be47e9fa4fc8b8cc524115a4f38f54c7d9495b6", + "f4303e17919edd9d9d15c5e3ceeb18e9add1f5cd590a16b210af1708d7c2d9f6", + "faa9096c4f7357e03d8a6c923d4dd3c89cf3e7b7df93d6e3550d2097afbb41bf", + "430597e61915003b62887051e2ff6bac76db5345c2bac14650fb69038e5b5b44", + "fd6741141a55801dd30572c4b8a3226e969970ffebc873ae786ef4c5aea7271a", + "40598e846c7f106597edcd6dda0095d1cd2388fb77870fbecef4bebf1648f035", + "1014de80f68dbef688cf440a7ed4a55a3e9c3dab5b481495271e5356e5b3a426", + "50155ca43c403e94069c8457086021bd75a91ee4aa9cebd19c503aa7b5ef4071", + "1a69fbae34376567b5904c9bbde6febef32ab3595c49aa25b885013aed982bd8", + "c0dd4cb5fbbfb2a942bc272a2473661e0801c1834f3776b830cdb4426a1a19d2", + "93a43d9ad7361b0da6f631939c854b4d074a64065eec9492ba32b037db8cd9e0", + "428f89ed58207d7e40452936998284473d2bff1faa6e8df53876a15c37068e4b", + "c35f0c9b820d0cf03fbb3579b61b317de6b25c39ec7659a943f577f1b2d041a7", + "429d7ed49bc12a7550025f395003fd133e867fdb9cb167dbab947bcd7ce535df", + "7768329e78a5e62f89240056389321c077ac1f2c5a55a6fb449ec1e33101fd75", + "5303cbd2ec92eff94c73b54cfd6a700c18a14ef5ac727c7e32d58b91dfafb05c", + "65f72a63f5081c70d286761a03592b2fe5a08c44a196677773b25aa07dc79dbc", + "2a381c0f77d255d0010c2c93d68887acff0963c18837227b63f6fa39236c6976", + "857d57e42e827cb1b5ee8a786ae6fdf63d4b797b3402246e75ed405a02efbb15", + "e5fa393c7bd5f39dfac876d717f60203f33ceceb45c39625035e84744178b327", + "bd722819c226c228085b005ff10e1242baa85aaba3b6fa25e7e0b41f08fe13f4", + "90fabe39b40aedc94b85397cc5d97ce8801dfce928b3a9bc8f37e1ec39a4401d", + "b402e874692915e6dca16ec47e961af7760312792cb764d0c8316924fc112b1c", + "9e940fd230642734dd72bcd887a22f008e4a87ccbd505eae65aff06152a38fe1", + "cec2b6dfb58ae3750eddc2352db513aeac289f65178e60346b3280d7f095876e", + "febd6ff0792d5118a0b42582f5d3b9507e5edd09b792c094214f9a781f1bf204", + "a12781979db891fb082f99836f9d52cc665a29ef42ba535504797acac6fecc04", + "85198d635610e7203a800592029d9509aa834b4657fde78ce2534e45f66d9989", + "97e04879325cc7fa906cf9be456087a3b15ec1e7a1c9f6e9c57fc4c9df67e1a7", + "8636bd4af07445149fcd5ba5db4aca3c76ad33916cce18bf9da5848d92ad2e15", + "a7940a553f3dd182a27a886ea7744defc5d46e1ce58379b0330807276c71b576", + "47e2984c2aac5c77653413fc70c7a8bd0e3b6be570c3043d7c07982fa64fe8bb", + "451f81a173c140734f486531815aebac6c5936a1bbf6aed60d08fbedc33493f7", + "ea11fb762f582d4dd309d2ee1a14ae3f1e16a700b6937446085d4fc95456e893", + "37780d59111d634f178c7be55177f6f2cbcfdd39bb29839f12217c8bceb6d798", + "67dbd7776aa16cfecc349bfcb33700150a908bcd3483a79addf17015f6c66272", + "7e5ca05ccb214c3d0d25304d745aebca58833a4210e2832179433bc1847a9202", + "e1efb53ac8e385c8f2ed01943ef068b127527bdea2269ffd5cb6f99272ab48ce", + "6b35de6e5869c28893064d53511fef3f60de00f2f3c078ecbb9ec614fe15aa59", + "7c3ef08b2614a9a1002728920e2b916c7b8809ca56b6138a86f744260f05833a", + "166cf41e4c2d95814be729e7e38db1249be0bf3f81846a80d148d0706877b4de", + "944c7194e08292aa790cf3333c0a20b41de591439ecca985be44ee90c184801b", + "99eea96b8ad28de460c36d504ab73a5cdfc6cf6023e3b4f22659c8f3cb9b950d", + "b663cc47528a27d7590095abf743054229f462edb1f8aabd1ad8307a0248f488", + "f7fda963ca5121112f604bbbe0095b5983a88a78d6598d54e4a26ea193e96584", + "14e7d432ab6aa8235cc74544a11857705fb6d7b912156e9f71388919307cde71", + "0b78b74106af4ab56184f71312642b8b95eb05ea220b89addd466fe6529e8699", + "5d4a5c2c9386c9d8a7c2851ac1adef3c496ea27f6ef71307ded2abe21ffa75f6", + "28ea23c9305330d7b53df44a1e5dc8c7a1d06085ad4848399bb7b1ff4137b631", + "c20ff359a239034d495a8e800db6b5be4df5b6c14a145587ec9da8992fcf727c", + "6e88a75f45b49c5e3f40bb3fcf885bb93822b6caa22aeca4031cf64bb3aa770a", + "184b58c5f5f342cd7b26f5ea650859bafc684e6b6b3cf844d1ed4ee14eb4279c", + "d33e033c2088decae18cc8583d62f7aef1a27b4c9bce3218bad2156cc74890a7", + "2e88694642707b4a0af81e6358bb478f7d6e80339ae598cbf2274f34031ca5e0", + "347860992ffc275c61dd19bf3f0aa4228ef273c2b04578f1fb62bf3a827d8d88", + "b58f4e3f843309aa3cde8684ddab220af15e4014ffd85ea67b257645c8b02227", + "efe786361f346c274ce015eac7337cca1096473e548366df8e97a357978ae962", + "a5594e7f79db8272f276a392c010ecb6ba093e7cf1e4753552390b85b443c44b", + "5d4cbbd7b5ff9475c925d42d0423d160443c2c48fad09289e895ac916e13495a", + "786e4fb2c18dc70543a74d2ee93a8b1b0e6efffb89d5e0ead6c808f6e0ff81ad", + "df16d5d637f7464ae60cd3bde0c2a253f9ecad246fb9222632ae8ac17412cfe6", + "6cf0dcc646f8cf375041812f5cdfa05c98b13689ce53f5fa6f57671418590c70", + "189710bf3afcde61f18903ad8169a84531a175aea7c9763d841a66b7f42275c5", + "8f636e553270640b8a7d496ed095d1e37c1e6e65d7a6bfaf9544b81227ec11c6", + "00ed702f895288f7f7e90831f88e3f3f3a35701876e92719b8f16d9903ea69f7", + "cc6fd888ab122719b0f74454b7ade615a0c0b0dd684d308b2f3041c095ec4972", + "1c5c52531bbc27ee148bb796ed42e195fe266f085c050fca01059884c490d33e", + "aec3d0dc92e91fa62f6e7326754293c8b7cca9a06e3a2d51c3001ac1b59f4272", + "3ac2730a16f9db4db96280ef9a9b34f3e061c0d4f23e8f1ec96618aa660e246e", + "1d30de904ad9e9260f5ba9ce004af902e6bb52d98fb79dc714052b4436d5a2fb", + "831953127ae04758e703685902708c43d7969cd52783827043b649609fd063f6", + "791d669993dff2c4d843837a4467d4f09be104fa9dfeb39ca1df105a7cedb10a", + "7e22231babca359809cf897f80bf35029915b73b636fd2fc797d9e7081004faa", + "c53a9353c137a113df1e0960370c218b53039b55874fce98688cbd452c8b8b1a", + "768e78c0b9dd00542b7d356720903a7d51b8cf2d8088d1c9c05816e800c0783f", + "12de9b125b0230e4fee4896259ad3fb53240a2c99510b095f51740a31df35fe8", + "440312e33626e2211dc6234ae8562cd96c03acdc1939ddafc6df5bfd1e806328", + "425f8a3194912b563b0388e57411e8200f052344638edebec71d41c287ae7caf", + "50902e5bb28a3968b03be74e8fb8ca19efea6f78424c42f5a47dd2809ee89c5a", + "fd9523798a747f03de2abca46c867f320dd335ad4c0342af2fb69414ab65aead", + "8c14ad5f50ef713b0962ceed2bf337202c0290c3c3484a5396a242809f17d030", + "2b2b1d32e82a1bc263d02cbed4f377831285a759c85c2ec1226ceeb3407b3b4b", + "c914dbe5334a7a1a17e499c890cf58825e099ecb26a8c98d7c3b9fd652f46a32", + "bdddf07dd06541939f67c5610b6350fc4345df445683ae1046c14bc3743d823a", + "93ab7711182ddfae7ef85fe35b0657d9b1d6a09c0301615ca4f02aa2b2f50203", + "29b1153daaec8c39f0246356283e27ad47df31a4b4151b1e51bd8066cb22a1b6", + "6792b39dfd16bb3de433c38e1252197e1aed3a00bfe3e89d44efa0b7ddc776e1", + "17aa82a28e443a5c0ba42e565b6aaa786cfcd02cebfdca828c854041cc1e5196", + "da855fa12afb6afae0b3750b8aa4a228fda0795e33b568e744c1fdd680d9499f", + "9e06d6fe3e42faac4770d256d86750b147ba95447d8a3cfeb6e4f79918729e66", + "14ca549527c3ed4b383c4a3b33828a0c6eaf6490ce7b5302deb932be8fd70865", + "7e65d98a5935b9c70e757fc1e7bdc85d94a7671054480747102040ba36300ffd", + "15139225a81c662da26b7f457dabcdce40f53f2e5252e03e76f6fcd3b3b177e6", + "332d6d995bb771792d49420261eaaf12e2c1c21ee15db5448d6792f340f275f1", + "562f7676d3e8913fc877c6824b3dc96c9be52a2c222fd02bb3b49c2206d9bc89", + "4f8fc0eac4ddc7bb888158c455ff0eb85ff416c69e21b5ad64fb147269689995", + "19fe67f55fb226c4a43b59ddd1693f8bb084bdb076690991411a30f1b1dfe231", + "fadeacc4459d6e7c123b43a0d2bd7661b7a294fe3ef8b5f2025fae4519c97954", + "2bc060dc5eb3d30bee51ab5f6eb2d6fa8a37e9e679719c65479c61b41edf379c", + "2b16bdaac9faacb53ad20dad99f82391fd3119ad19df1f44ef7817feb969e944", + "3f56fd87aaffa5c6094909f036b49e44cfe4822546e21e6a3723dfa350675604", + "c3de3de77c02cbe7af5c70aef2d8511ed6b0c08e08e6f146c440df707ce8427b", + "d7256178e1fc9c976329d1673c509d5e157c3f6aa73d6101330c7f6f9842c2d9", + "0dd617c9d93a68ec5ccdc2cef8652f6a22c853dc3ba3b595342c863ecfc5f93e", + "2e72505539c116ceb2d4c5005c006a3955e552b6426171c99e0eb0b098b7fa24", + "e2bd0a3b190a00273fb4ff90721d969d0ce803e696b2db413fdc45bdf7b4a7d7", + "13278204aa249947c285e83b02cb80cf01ab16c065cb12acfeb07e874d6066b1", + "030606d1fe53e5835834843a83ed7db1ae133ddb39ef23b4b426a2cdcc0e42b8", + "6c293e63f50a0a9728e5d00ef88210f1801a2b4b3efb17f03e40dd5226c8e322", + "4f3e7bdcee123a89fbc86fa5614263ee25faa91054aa34eb033d342c740e7150", + "309dd0c50d1e93a84e2429b3236f409f6692df31ff11b77e916f381d5adde839", + "adc3199b2b854ea38033b0c2c465f20ab874ab222c60cc59fa769f4488044b0e", + "f5180eeae94989a0d392a597593572eab0605d45026d72ee3cd2d50cd619ef4f", + "515798bc1a6de6789a1a04f82d4bf9114ed1d649febdfd5b0082dd5d26080f58", + "83da2846b49b76105240d46b8be65d923f33aec2d89c4c6d622134ad5dce257d", + "bfadc71a9ab0eaa9bdd5734e1b0371a2e3bddba22cb5e500b92ac6b14260b3d3", + "a3babf2051c8f0ed9c1789d7c9b69537f41a5c2f1e0708c433355a93378c1584", + "2db54e8a901ce41a59bcf3a3c3524d22a183208ab0f5e1861956a4146bf66942", + "c83bcfe1898ea74ac32dc6240feb93de36e7ac561fd2a0e38b2e87d78004bca3", + "6d01614890d352069c83d86d293bfc083b8d9b2e5223e824b4f3b0dc1a71cf80", + "b401c3e43541892981ea40e43f75d91fd244cfe158ecc66070168a9bd9d8d5ea", + "deba8936bff7b7abd6654fb0a3108c61a00f94f4b57a8d44917c216189d00dde", + "d92939873020815f2f2ab5b98d7170037ecb6d0db53b109ab2c8738e677e2d99", + "81747d9aa279ce2f83dda19c3612bc51cd39da8822de43635cb5b7ba0662a839", + "de8c185cf73ef1e0402b571d9f41a168c9289a1ee6ed16d346ec9c617756e554", + "ffea494dd34684cb6c16f0d80ca0bac517bb6c89b771210507cb6fbad55dd83b", + "63e426baf41b0e2a1955601ed1ed28eed76a61a45d87b9290888d14021780912", + "8b6d3a34d040fe0ed55193884b3a2113d9e23adabf93b8d1b62d0ebab36c2996", + "e6d9593d7c3c6838aa21db84d894c0e1cf6ab5efb758d97019a663716c100e09", + "3016d1b4585b88d2c8ea0d10139edc2ed8c960a00a9cc2bd7182dcf93c5148f3", + "0624ea9ffaf0959520c107982253f79062cb9fd329b914021cc6148fcfacbf67", + "bbda34ed3fbbae35c06e64068cf3a750bc9db54b0fa96ea015efb15f6bcb398f", + "5fb0dc27300814db3e5f5326a866258aee993358cc9cc7c2dd20b2096584483b", + "53af922d2099718876aca6d8112a609b93044f57c071fd01eb1f3432ba3b666d", + "d00ce144166591338b2d30e7e71c1084af606715ea942834d877d2858d8c5f8a", + "e1ab7c387cdedd947f5c8fd7e56115ce879b504f1c58d35851e6415513924ed6", + "23fbef938823474f4ff1d03d586847ff72fade8bcafaae36124abd9efb2f7882", + "04b3866d5b6420cdda60c35ceaea4c83c138c10324ec629c7e63694d087b33f1", + "4695eedc5f998efb47b67ce312ce75086e22d23721aa5ccdf4aa6f194ec9516f", + "461c6ce05451d0932a1ba6745b059382191325249949509c70e2839507e5ddf2", + "e88439b3f78bd8d7f93e4cc7fc93309207d88ca8d2c55af449cf2a4a55ab9e19", + "f8e30ff3c24ae180dcbaed2e36c0db5a2a456c9c063d206142e5f7f810a1949b", + "ac3e0fd5ad170717d6e19fe5ac500ea14e4554149d4588d18fce191fc3b701fa", + "600a93ae15522bac4dd808fbeeb3678e5c534369fc9ee76462865191fa07fa5f", + "36e6e51bdb50483863662d9491fdf87b2cc2b4db01393a6f57ba13ce6d88da51", + "8ef91df0ad023a7fa5e3cf2079bce64a0e2221fff4582e8c938b1f890a46e3ff", + "ee891585f569690fa3c14c555e42c59540af8641568e025c4c6942209c9dc7c7", + "9d7d1ae283bedcf6d1ade45401e9b28097b8d92e7ea34bdd082c4c5b21d3ba28", + "599d19a48e02e7d3be940c3f507d5d21f229559bb9bd00d9432b3c6e5e4aa8f4", + "7fb1e267870d2c82de06341a5b6291985379e53e82ad00298b92c9efe168c7b0", + "09e7b44a0c8e8ea466523a011a74286f1eb5b4ed216f02bdd6b3395250219d67", + "ed1f538a759c53e7068a484be25fa341bbea7fa4f12c6c73add3036fcd5d1066", + "4846ded7a45d637cae55ae0a760a7f119a9899307fceaea882999b86f8d84980", + "fa021060f1b038e8ba619e9e3d6abaf1c0fec917b6e06e207d583f3647eddb1b", + "d47241613e7c37597df7f743f83dea75916a9917abb88538680be1384a0a61e5", + "e70779307c56ea55cbccc124347c9544c8e86643d97dc0674e89f3d91f61b932", + "6008545b549fd0cc26d1d86c821ea23e06ba7199513d45507e76d6cd8123a812", + "c860b10b8b9701bc3b91a8fef2c0cc418e5186d46c8ec224ab0348a5aa54fac2", + "4bd3608a165c3909b42d3d55f53e810d35ca7b6498cf823dddaf46b97f837cc9", + "025920d76db997b110388cf6904d6b38b4a88050029a22229478f4290a692fb8", + "441e164d7e6abcdc89ade7cfc5a1761f8b04175f80d7e0bbe844f73dffe3c87d", + "52b761cf6c0e128b7ac8e19a0c36da02d01b9ea7445a4f8fc3b105f75fb052aa", + "6bac07c97883885c74d9d04a370e82833cee213f44502fbd25a427b88c5d5587", + "548578c0288e3b0a9665a97a360fa73e1e6ae43d9034542b8c639ded35e7d5b8", + "22336d6c79ba4a107bb1ea684b75fd5f753b796ebb7d21b6d146857b96b8526c", + "1fb682b5e4671f551e5076b8ed81c8165488b811672b22fcf97cac8090bb556a", + "ad7d9d7c46824a208c8f0a604e161ab0699700d1975fb4a093a28654879dc258", + "848137ccb895e12399142366f90965825c39a06542f3965a6977cc3e198eb7da", + "252751885c7fd9af6aebc1d4b4e59c50e7a29a2fa13ef0d44622607e318660c2", + "d90c0ef7456e8170b171f278744f8109ebe9ac59f6eccffcd42c0967a70c1d7b", + "8b7f59101918ea632f5ef94196c6a4caacd07c2baa23b077986b96797ce5d3d0", + "62b0b2096499fee6c5308046cd47c484088e632aa7d4dbdc9e7e2c97894fb8bb", + "0edbc474f3be15a0dcfdbd5d34c326197422e2553c89305277c2fde6bec70b6a", + "d5fc317a4587bc2bf31b3356e5efd893da87c6b3fe364ff19fb424e89b78c9bf", + "f6dc05093a228a9e73bb0a050c240a80c802109124e31f6f0a27609638702a42", + "d1dd27090ad14001a99cae31908c8f4985619935021ca872db39d9a6a908a137", + "e4749b0ee13d8caa07a65bd9f8056b94caa747a496aa03f33d12e43c0c45f078", + "537ea8ec2e6e0e41284001967639f96945c06b2fd153e8056e5f544a586afed7", + "fc1a41da8eded393027eb18ea66db2a2829b7b055498572a083573e2313bc0d5", + "4cf719033b137569e8b819dc0422cc4cc93610d6808dd0a956b0dbb0cef97887", + "5057b6c53638dbb171e652d1dfb65f96ec66f83c0a5fdb778aaa47007dc9e34f", + "b85d03ddcf3243769d0e3d4d562364d192c65859bf7b548a2e6ebbd0a7db0f23", + "335cd2f5de840281f8e89fe78af2d243495c65585b6ae5c9ab9ffe8af23d964e", + "5cb571d47a1bc0236abdff2ccdc4a1a3f1805efa58066c8488d7c4c9fd421bf6", + "ae48e6e11125b045726e0975ee049ee3f83257bba7b1b4c98d3270bbfe4bf26c", + "d3c04219f7844c57349f367c79e566f31cbe998ab1d46e0758d7f9a616880ca7", + "2d93b70c846c1c0b7f65f5dc14650788470f6901ab6c21470538bc179a6c2df7", + "8eb7c39a0bb9c9c27c3a6db120c5497c8d6c0aa08d98d24c0e1678cd59490d50", + "7cb68f79c6972d2df393bdfe5ee45c35141b28b4f1de2a3668ee6f58590e3381", + "9af1a1d9e9e313b250f65e4302a221e7d012ece77c059f1ea3efa14c783349f4", + "446a71d3855a434db093c35e1812e145a35c9478dd3fe14865378ed10de2f563", + "e2bd6bc37fad97bd196116c64270751e2977b5ae2251d2cc3dfc840ec612e033", + "fc4392c2abb547727d420a24da417a00408282a6e2b76a72e8a255fd7ec9da9d", + "ee012b3ec271abd64c0bb7b0bfe3439fc27671c916c2dd9a97d77057459700fb", + "cc299116470ba9675d6110addf925a9fbc2fbcfaeac9020a06344bb4c8a29f13", + "70dbaf72040538159dff66b81df11420369af632bb530c2e648adfe2eb339cb0", + "c0f3f5795da6358fc0fb8de057fe2fbfe2aae1b4e949d9fa58ceb67f35876055", + "ab6c68fa93dc6bbc7ebd97318316c8994468be20f02a5a455d9c5e24d26e6f6e", + "85135c8e85aaed9f62ed3dc9fe284d5a158b5c3434e86edf049b752ca0185e59", + "ee31dfb0360dec36a1e74784849053952695357bec1aec67fe98421c9c112b3b", + "86c6dccfc1c74ba03f66b76be6fcca50067801a7dc8f4489e91cc56a39be1c71", + "80acd02f9afd1109af3dae6c9aa34488d574c8797c57a7359d3c2b4c83d91622", + "73b2f06ecf6286d073161264deeb36a2fdbcf21185a458f6ba37eaff5a27734f", + "5fa649b465736e5a567a79e67f0f05e19c1ed70aaa95dd20375f1b893e6ceb23", + "7a7b9b3f38d3d4bff8305369a22939a673c99eb8ab425be2b5d7ab95e5ac5363", + "bf284dac1b347d0e731204f45ebbf88b4facf8841bdefb5688e0b75ead672518", + "55165268e2d0a695a51fe47f5ea69ba91a96eb967b50069864a58ecc35a90dc1", + "86faa28babf62ef87c04d8655f79897f5ce98aa63862e616fba6ed2c42fc82ef", + "6267da068e9f2987592c99be922384e22edad80ea9dcf288a71692a7b84e50a4", + "d8abcb315464eb9070c896e3824f58bc20799056e7294c9ef8539c61514eecd5", } -const mainnetPreverifiedHeight uint64 = 13804608 +const mainnetPreverifiedHeight uint64 = 13986240 diff --git a/turbo/stages/headerdownload/preverified_hashes_ropsten.go b/turbo/stages/headerdownload/preverified_hashes_ropsten.go index 6bac82676e7..56f0df1bc69 100644 --- a/turbo/stages/headerdownload/preverified_hashes_ropsten.go +++ b/turbo/stages/headerdownload/preverified_hashes_ropsten.go @@ -60526,6 +60526,941 @@ var ropstenPreverifiedHashes = []string{ "23eb835544e07ed558ee4d61cd44458f3e44c2b470ca8227fea9601b5d9b2879", "61508b2bd3d629164d536c55abd6ff169f82145c002fd72e02b6433f2905c92d", "58b5177a1e7622820b6b04134144c69f340934d56af25dd5b224d4dcb89be2e0", + "45421fb7432485bd611ac805982603c759c83b27655ae1093a27e52dc09880f5", + "3b61b38cdb5882729ade265c6bd25e3f1331a73f1c835e2c8a22f0a3f6f18e1a", + "cb63d1c7d34a06a4d6f623ca23691d15c782b7344f65e67d4542358ab2f4790c", + "59b7b2a408f58f50451d15ce2ce0b0c4de87c08e4d23d4c77ea1ce23d1c809a1", + "d196500ffd0eb1340c7f8edf1d18b795c15b531090bd3b47792e7486f99d5a4b", + "b02b73d74b314a9f5f042a36c675b0ce7798c0d739ef68350aec0bad9f3e0ad0", + "45915753e743d54d961c57b63c32867a16cce6f01471dabcaee174043c5d1e15", + "5c62be4e10c59bfab787bdcea13913919f29490abf9259ec78320d57592acc9b", + "f2641036a0ed4de130c08234066cb870611eb92a19b155e5b77024d51debc2c5", + "9f144e21f0ea5181549f8307928aab93eea47a311ae322faf246ed1002363f43", + "8ec3375abe876737728e3f3c2f967b6d6ee05d8c8b99165a1c335d943795bb11", + "d76d9dee9591664f43401fc08a666a21090d0f902d6dbc3fe7ec38d60e0c7a0b", + "786e087eec6770fb3034db88abb21598b711ec74b3249cb06e3c6c679334b672", + "a2220946194c6f066be15df59c105f6c7d1bf76e4b61b6a1170c96cdc32ff5cf", + "9eb931d4158a6c3afe4e2798cb21a7005d3f753f95ea6fcebab4ee3c49d86442", + "f03f8bc54a19553bc0d47a201808e2082e7c068800b261ba0e40019ce8f7c542", + "295478593bc7311a3fab0945a8329901f3eadd521f2de211cc711cc0eda96019", + "17328c101fafcb04802cf63a37eed5787ddc20f6f692d56cca306d741203c26b", + "c58942b758c32abefaf2a1e6f1738439cfe1fe1b25b75e7b6e7effa11c7ba9d0", + "7da5268137d6df305e7435e0d0e3f53e77aea548f2cde7b25a49d6b3317281c1", + "09bf7cb0d7e1d6d9c05560f9da18805019bb63da40b4d918192c3992867b04df", + "93f3a6b944126b11ee4794b068ae72327058f71cc2b9eba926fdf3eee3f2ee51", + "d0c355b8bd9dc698031af78ece56209c93b761a5b0749d0aae9bbfb3494acff3", + "22e7b869374b39e49d11df01883717abd62688b1fefd8de60b5edb0edc74fdbf", + "227547270952063238ba912804b7f8a68397bd05dfb4f5a16f3ae0324848f733", + "0524dfcabae1f25976893e73fd175ed95527005b8a51e7887724ef4816e69fb6", + "558deeeadf7a9264bcb01c2114f8b7e902a0e553ae4487034ce51de7857b6b1a", + "1ef9b9bb2f321a00a930041b7a6f72883fcc177446ddc59947f4be800a3ff5ed", + "7eba39acf910da04bc3f99915c3e93f9e9038e5b853fe60d65864bb3d1ccb3c4", + "2c67acbb66e9c7e426bcd82fa091db25174387e9e11f3ed5bc4d4b85d27c3ac6", + "3a7c54b2d15b1ba0ca8e510737048f9f8d650304e3a443407abc3436f9e583f5", + "56d8b7c3adddc66ed1808ebd991a879f0e2368571b6987681a85edccc4692ce0", + "eb148392ad73eefbd2bc69330fdb94c0ced8b2fbc535cd7c5f8b97a2d072e851", + "3649626798df027409b7133355c169ef8ce87cb9bf8bcbd53e5a60c8a30eda10", + "e6561143985e0283234d34451132ea603bc1c95ae238e9bdaf6aa9ecc5d9a2e1", + "a33abce68b8fb150a21d14bcd241c5985654494b4da83f21ee73e16b9f6f6fb2", + "d4370c4af1be0f3db3c0b84f80c9c3a827c120dc2999fce52aa99b4c5cfe0078", + "ec39ae1e22fd5f97505b85f4fd1ce3969aa5354a5e1ac5bdff4350d77d8d8699", + "9124e20f9d19ec163a1e7dd391d211d687688e7f06119f9d368dc78b7fbadaf9", + "39b9738c23ece102a9df4cb37897e02f90290e85f89595bdcbdf918197acccd6", + "5fb363dd7a1ac24ec80a1258421e4c7c69778554646dd00f0dee897ca236780d", + "b6dc859b76d75cec474eddbfb70cc7a20f72fe55c5cd9e500ab15da2c9a58c66", + "334937569518cc663e350c7f492bdc663c523499d48ea51e708c3d9a519e1d88", + "3d91274fb2c0d854722c526d04ebf5078aee8dcf506158524556adec7a46d208", + "52aa3881783a5f01d510c88c434b866702ed6e4fa7586217009736b7f8f208b1", + "2d265b38179836e71de51b83a1526889b8934768f40eca88d0d62a77ddff6e42", + "517037ba0bbf96b704590e132f485cd872ec8e94284704b962789a62313d72ff", + "2ba34954f3d5721c287e5ea87e463f4c67831c191cf0d7ba391f5f686aff75f0", + "3692dbd6bcc34514b2d65dbe0c3b2f7f9aa2f2a8c3f630c675ff3251caeea499", + "3d4305b4b82e5e985c7fcdd0b955d745425dd2a2855eba5d329b47ed9770a85c", + "2720ee49d49baa8267a732ef393a2525b68ec2a3cbf52ae0309fb86cb288eac2", + "ec952072771b1ef96cc3863f33a518aafc389c281633fce5a3373a52555d741c", + "60bff14a57f815b1e013c707ec0d0ac44600f84f423d1209af24a50a334438af", + "4dced87121089a9e05bf4ecc5c194e5da546758e60d255ce63705e8f583ae0ea", + "b20b798bb00903cf611e913d706b1f1a241213c8ef39f30f161bcf6adadabb32", + "94ef03f93b89c1eec3f97ced4b770efc34133f02842e47098e91e54f94732983", + "fa4bfdec68242f07fbcf882dbb226967f39c290a2bea030fd836caa9d3f6e9c3", + "84dc51e66ca34c055a612315d8621da8f34953dcc7d4265cc38d87283bf3bf69", + "72b965523b597e2f66f7b9cc3166e79c1ed0f46b34324fe4430cf5b25b98ecaa", + "d1bc7b4d63f25f9aabfae2fe42804eeea7892debdcaa9ce16707af0e5adf80e0", + "144975e00c83b2708a709faaee3133d305216512816595e8c1a47c8e0ca21ed1", + "9a927f568df6c97078a03ee6a183d6430c38f98c106459af80e5452fb90ecfd9", + "9f9f84e1fcfc941e0ba78e7e5ac94498ea62424ea3e127d777c03e06a290e289", + "53240a3b9a674b50c4e29372cf8a1bf2cc5c746949324b10217ca5c1720e6a9d", + "6b2cf3f377806768e749d1ea9603569b5acef063e0ece19fe0dc337d746dea98", + "83932f627e2e5268171d386dc5c63da6d90fbb9fc9fe08a0bfeff8ee6e03ed4e", + "8565070141c433870a13fd2ed091e74311cddcaee2e8378a05883395ffbbcda7", + "1f4a49738da56fd4e8d9829ecfb0689e9247d81493061067fc08da61f57df6e1", + "84b6df4689da62b3b1a4f7da87f0d5723f1a5f658f31e877845a78bf12e3314c", + "0aaddd98094add01ac089584814e86253e93598d055d785d51242a6b81cbe082", + "54adcc3667b7d713bd82cae0068502aeae1edb602df6f54965562e8b747206a1", + "d0c67e1d9faec46606bc76128e94ea8dea93504392408ae5459b6e65e5cb4a02", + "d411328ca82e1f152866289d72433bdd61698185ac1fb8fa7a3b43dafedb1d7f", + "bbb9e2d778ffb985025179b3b4be80e6d6bac38da371bd34fccfa876aeb9d7c1", + "72afcf0ddc50d1def9af50ac33d73aa2be7c2ab9c46c95fd3aaa9777780f958a", + "d1aca7ae88da0a30a5a2de70d5fe9452e18e6ae27796690df212a24e633940fa", + "9a4eab2afef6543789b0d38c6cb132fbadd54d4d08e594f6360a67147aab598e", + "ce62a48b4d0f69e817433bbddd1fefab578af6baa401383f3d8fda82658b5c2a", + "11cccf7670aca4c6a6190eefadebf6a06953a07f68c983dbeec6077cbc3cdcd7", + "5b985f235cee05cb58e34f239338537e9cb49797610b597ce9621c30cc9bbcee", + "edbc675eee0d101c32aa8559f2d3e8adf662ba5f6c35a92830b7acc08bf11f9b", + "7be1665014aafb2c00ac91c4f18523cb6cfee59f43255d7c81385acaaf716f31", + "7490abdd5c02f8a4fdd617a9591197b14727b8a15d28a46266b1648ea7aefc4e", + "8533b5bdab2e69d7ab8cf030ddaa52893fce83116a5bf81a35aaf7ce0b8e8a0f", + "b284343d3a13c210cb563456675f4c654028e53c5fd566c04727ce120fd3ed0f", + "11b27b011aa8e774177adbf05966d5695ae4c24c7eb7a2b636e9e757a8385d89", + "35c5b2ac951208e56e0c8209277eb95234f1ebd2f66802677d9d767f49d0ad17", + "49a254aae714f00993b4d2fb9f0701da9ddb92d360d4f0305d7846b5170c1666", + "1834225fb552ea0e6e18f98f6915609941c3455c243f8ff4cc25cb73e21c377a", + "14f882c66d9e583ec6d6bf16118d7999b53baabf88e5e7d547d842dd49f394ec", + "531535b45a1495afd2b798482e9b5f6b0bc57bf9520e534c1d91129d594e5eed", + "622ef65cb8edfa1c1a669f728254ed3ec6a7d05dff13402e62f41b74f5830bdc", + "4b629cb59ab94e10d3e61fa385267326053b59b4f86f4e694a1766882f0cad71", + "287c18a10afeb2046ff793b88d282945f37fbd2addb4db9c9af580dd984ba6e5", + "d137c6cd08a6169e0dd09df93d88a15068b70f93a66be5a374de3b0a0c3acb75", + "2f4b92063431ac7bc43a671e919dfdf727efcff93b5c253c786a7adf8baefbf6", + "47a690b33c01620032e15b530a22dfe46b5d81f13e275fa3c014bd727bf96901", + "66a57c49333173fb53fd5961bc71d16a7615cab78e367faf93ae54305c26da03", + "3f6c2877721fc33a01a44db9d3875d05ca2a1ecd253cd821864827b56a5b9d76", + "affcff3c761554eb52a6c3d4fcc5f367a8abeb40142af2153dce4701168cc3ce", + "526af0fd04f97bd8affecb9d4434620c88e621c276115d9c101c5450324125c4", + "8d3ce25a052f566a075d0268a13244647f5fb1bf8e0218bed7b9b1e0d0f4ac7b", + "4cbd8f91225a1d69b0936d2871f7efe13e72badc8b7d1b819b356c29391ff35b", + "e09c4f5df2d09e8b5c18aa2d5f616280798df9ecc5b34eb4ba4b6ace4256f62d", + "539c80e0fc2847e324f23521dd6511b2ce808dcc71361054b7781cefdc368dae", + "f45363068d1014395acebdb9162331c857aec4785a9a74c11b8505c95ad8b1ac", + "93a7fc1bea1a010b0e328c1318c2acda4530b15d9f948b5864ad7ffa15bc1d66", + "8d84d1ef4e2bf7cfeabde4637f2b30a35ec2d28662fd00a35438cee8c54f8f59", + "4305c1a8b7fb842a5caa4960366f39e7fcbd68980fe3c5a1845ea680c6c9527d", + "765c46aab4931f419f87949fb50e20dde0e5c45004903ab55b8c896661a6b22d", + "854b49b666cb170a7a4c947382a860fbd3a683d1505161acdb7dad79ba7809c1", + "6ae9106102f21ab833d9b0fd5c530403efbd49aa53cd5ba4ffc0f3824d896036", + "db200dcb25d8ca13ab436c916c2ea63034a494a757206927a51585c8a457b070", + "44a8492b17db62b8bd0bd08d8a5832787439e291691f0cfb439190250dbb82a8", + "bb7b1ce330fc188b7662252cbb96a252d52a0db9f85fd6d6d17a1a302261fe15", + "0dd4a085ad5867a46d85e9c45643b5a7b0f9451c7dc7a0bf9b81761a9cbd0f17", + "384033e95cc4208cb4dc488a1eb203b351b14d269917a8c06b553b74ce5d02c0", + "f58ff799f6964084ed0897d4161b83d37b46d756dfd3c7e667f98cec675dc460", + "6014bc56bdff0a26c3f619606e12adedd5d5c079f7251e799dd9f25d29513292", + "e1cdc8c04335cb62ced33aaac21bba143378b970846ef7c7dc31bb29367da890", + "30757968ad410dd9adf4b984a47119548c949feef98bbfc98530f30786cc8ceb", + "cc01c6285d21aa63e00b1541cd988e5518b497e4694fdf20e3af757108ed1760", + "ee4c6dcf80be02b47a4096c8e16c7cc2d7832a8e9c2cc2565a278710a18a2801", + "2ba8e063fe7fbd10787f6365e96524c9aaf2b30025d83246a4ce22e07ad01cdf", + "f2d94ec47336d0bf3e3470feae04376bcc91864d0b3b6bdceeb2bac6aed44d00", + "1fa9e50fa8c25deaf8471c419a6d9c812b7d6a94e92da1b4b02ec34bdd2b4b56", + "47ee77474876a8fef1287b9e30f809f7af2b960c88c15225597d5a37a4a876d9", + "a88a18fe2d1f3d957cd7d779766eaba8f40a3eea65a6f5f4e0c83907816ea8b0", + "197ee51224e79a771d33397f184672b9ef23c257469cdf94a61d695bf2978403", + "8259bc2f24c0f32cd78490c9779cd0529d3a194042b79089d1b9bf36ddbc8743", + "93860cb356cf36bfab002ffacd4e242791e121c61a347729e0d035b30af75000", + "8b907424634d5cca28a9049c231a2bc715a6e54e9edc5dac8a081ac9db3eb8bc", + "b186d98ba0610580d5c6d7ba65989c4f95876691286284886ece6f137ec7e18b", + "95c777c85e6b3a3dd708ed12775ccbb3719f27f84a5c1d97c9d7b205cd3b467e", + "f8d9de86eaf81fc522d0d116ba616c79c8d736a91aa864cf1bd7f66c3a42a89a", + "47d4a33444672d33bd8a3c6e68e99c2f80a4c8fd8f516a6241bf020d4ad1c3cb", + "433687efe1d97c3cfd610216225a34cc82467ab482d2bf1953c9510bbb1255c6", + "9cc2003eed6d4fe1fbdcd126f8dc0275fa413cc27c4d8204cd7ef5f977274b4c", + "8c5dccff612cdd3e040dfd4b8a70e2205b62134c964fb775da566896f1c50599", + "3a229a5aa728a8b66b0879de59587aaaad05c661ff90e60c5e6a189ae466cfc9", + "354a341574bc9424df94f5f3993cf3c700c0bc5a396525c4901665dd9ed41ac9", + "84278fda71abfa61508e49e91bb4762983d56f1dfa2da54335d99b2a8ef88e6f", + "1d235349d1ea8fed3de806989cfd790e6da5a9d21f206c9c5003cc076e86dd8a", + "e5c135367c8075bed42ccacf03f18ccfd8922a98f5c1b063bb73bb4e3c074946", + "8390500874ace018b51300410eb102f212e6c4982d2ed9fd0068d8c4d003c20d", + "dff734551aa1ecad98cf8374b6b2b98540faf099676f5fa9b5c8b4795379b96d", + "f91f8c971cbfe6ce1da9b8fcb41954ac7c3229607064d075f166f8900d58e06c", + "d4daa759c9fc1e364df7ccafa83e9848e0c25164fdf262d7b99d0ddff901e115", + "743d0b13ddf57ab2b5ef66c45f48fe7548eb3c4d7642ae56a6233d21c2c157b7", + "80f6c9b83fbc167d0a219b0bc4ffb63c9ee72ea7b64e115745583c6ba3ed991e", + "76ff1402486ec39f2230b23c273340218115483f21f5a77417c69c514ef2aad4", + "463be82c647339a9821a5ebf5bbd219be8e9d1e34ed1480600035f2586e00045", + "e28b2e13af890ee8b4b4ded9ba6017e0143843573b82785cabd41534c83f930c", + "4e3366e6e61fbb1ecb6317b0e39007ee1c807d4dd2234cc41808e0efb8dcd8e7", + "f94f963ce75ff3c9a6061576fa5260458ad98954ca12a3f3538651808222ca02", + "8e5701923790c61790c0b1b4fad9d1a2860c55f8ad35a4dec10751e851987d9d", + "a2dc227bebf923f97d747a2f6571549af4c8fb8283eb1b56e83c7709a0775600", + "28da82f40f0d7ccff9da8f9fdaa56d8182ee6da7a8633d2c74557941839f6fb7", + "e0fcbf6173d56ddda24dc7fd39b40aa3dfbb0f4935fd14fef1a27f04b9065994", + "9933e117cf3b97e678988cf810862ec360d0fa9633639a0f07b6f8d394ce8634", + "a35336ab73abe8de9d1f5d91376030bf36f09adf67535e6a707dd41c802ff37b", + "664ca5c578e0c7b00a0784643281c0ea981d6b8fb17e9b9a7ef48888488e0b4d", + "74ca11e9c8ffe6b9f13986efa787aaaf12a4512fe347e9b86e6999e99cc5e087", + "38637a830fa3961c32753eca311a1473e00e774e6ea360661c6a00cf21a8264a", + "984194196ba3be9e83c6eda447da3f490c61a3c6d4a66a9b700e94f5226707fd", + "72fd66cb4fe6c27f7680418f92e5809157988c0d7612b7265bdf125cb682dc0c", + "aaa38ef7fa6f2120ae094078ca9f00a08395f04921fe8b9f98f8aba4df155390", + "3dfb6de220a6873e64a9a2d8e9ec6f1e545426b4f704427455e37e5ba2928143", + "6a0b3302f92ba3f4fee91700979bc8206459cd83a7f1f3dc3cd022de8c32eb47", + "ce556f571224963459e43d7afff61b67ee21935cdd5bd7cba5998a5932e6c71d", + "018252dc32406c8d1ae70e5885ff3193c7ddd2ec750cf63763e94d4ab4c6aaf7", + "77959c9f00bb9285d2ba9dab80c9b403bf208a6ee5dd494941c449a7a114121b", + "c82418fa346a7a96d153b2ec6a0f861a252db156b36699d1f1dd22782ae4f21f", + "c26d3f6d11bb739f6e05f40a4c6045e1b40f75ce2329c664e60990af175ccc93", + "cd9818c98be3bc80eb27d334ffec886e2b5a0f693abfce279cbe551f88743a96", + "83e75953195fdaf540f8bd1b5a33a310cb83b9fcf6ae5ebf0c69b1e94cfd1f5b", + "0e2b17999965962e14a6142e1197ea37b4322fc01560786ab59b1d52f675e8ee", + "66098d5b9ace44ffb6a05b4054141f967577fa3a4ad5b0e19259ce26a3fc9b12", + "aa836db13d5d7fc1b6dcd32bd800caa328f9ba4fbdc27c2e371913e5330c8a41", + "a8c6ee36623fde263934cdd05c4aacd78caca998fdd5bae81fdcda96c748e7e2", + "898e277eb96c57b6cad4401f74d6052a194a3c9a911f1bd629a4a6f47ecc4e70", + "3e3869f52ebcf99ca4e589bc585cb59253b95b5182cc11bb517072c8050226df", + "1e76666e109dfed96c928cb5d33951f8bcac7c9f61960bad5898d7152ad6638c", + "813e9599ec61c53541e489b316a334c00891023a43845ca5148b0860874f56cd", + "11ab2d7d7670704efcba7e5492a8d6681872910299505f534277b28831e15e1a", + "e2463e6bc004e5bde29baf9ddc544d705517f435de7cbb6ef9de3875613b48a5", + "7e2fa43a30151e098e22d73e15041f82d4694b77d1e42e886d6158003a7540f2", + "e0000cc7c47d133526ba8fa6ac1884385a2dd66e0f0cc00aa236cc149039ceab", + "5b40d2cbb4f1a046a0f308dc23286961cc061dcbc5f7051b92d2fab4781bb24b", + "5ab66e8774c7351e59de6a9c894ba2a2736b9dcc0e22b2b50816766ba9e2daad", + "6d0427cd685a4f81b83025d2aaaad8122d40c99712d7f9c429d17562d1637c36", + "df9b215a8cb6a1f78e99839e58e53df5da107a4b3bc0d6cd1e75df96287cf816", + "d775ef445b9cb7b99a238b0217d625d5511819829f1b95d63b58eeb99c7cc43c", + "81f1981d4b92f549b616f097d3a0dc04976e6c9f7b78fe78945d45cdf324a28e", + "95de3c9cc6821f0c0ccd9cd2f970051307c5dee49392a50d65ddf5857e1bcc10", + "cc591f56690e37467ed1d3560fd6efd3ccba78b5ad781b6a6a977c4f6da45bb8", + "2e9b9393cdacca6f3732f1e4cd0c734b2fc17a81549f140d3de860b219182ee2", + "c8ac33417133b3326dab9715daeffb3ebfc6612ddc546870373eb8c8d3226f8f", + "6124b51dc5449412d75d06c7eaa01d49dd3050b55b058bc9e2a9d8b81ec7dcab", + "7f2530d3e94280c57ac922a9387174460a9d77561f915a64e2063463120d7159", + "e16abfd1242931d4b1784cdd185ae4e0cab43447be21b8293af00440ff706f19", + "6e1b90a72de0af942d3b349cae6bd0b01b0e02bdeac34d9bfa7caa165d92bb52", + "dc0a7b7321b06f3b9c5986fe3866177d7263e7ea74a98a6bc39262b792c29bb5", + "bd6bdc358343d80a2967421dd4f0eaf25642ae683e095572a759a2f0e49ea257", + "a6eb7b4fcda36f0a20c23851f3be78be9b0d5b0b112c2df687472eb642cc8a58", + "63ea2b8c20d4a6a48c7c83d5db406b0aab292a1ed9add45a5e7ee14ad012ebc0", + "70e73fdd69ea67c5cb89124ea75ed3b476f61663b8f1cf99641d7fa3fc62ac35", + "45ec2316fd2ba5ed28dd5240bd820ec381fbc21b26f4ca3a17b365250bca2c62", + "19d2bfcf63ed53c6dcbe314ab6f4240699c84dbbe43bb93acc46b0bfc1384049", + "1ee36c153883072af807ad6dab395e6db8a323862fb66b41bd586524c25e0f39", + "9ea56c8c8b4fe800829614b9cd3e47ca8c96f39b79424fbbebca8f26ced23b6d", + "ceb5b29a0ec1fb6324abbb1610ce016bc48599a91f57ef89bd01b5a6a59c6229", + "2ad3ada09a411c921c10e5f477b3f8e607ee994083742697bd691c00f20b8b39", + "3679ef5c853a61b4622fe66c41df59098c1b6b7ea3b62d683c375043550aea52", + "8516e9ab9d2229e8dcf57def54b131271bd0152919ed95525fc21c43754ec519", + "6e1e0b01bdb9e99a244eb85dd2deb3392ad51f9a3b7274ed69b97d788ce365d6", + "552c9b21a3ba5e345b5b33b028e8375570973adb70a3f45d83898aa87390a5c1", + "93c6608087b6a4907486fed5ad59672cead7237f3f98c059a28ae5eecb8ea4ff", + "abb8118d2612180f0a2e177e5947363bc28c848470dcea5651d322841cc813f3", + "da221ada467593f840ef187ffee77937f04d3bb9aad27bcca1b46a1a09751306", + "68cf5641d0d15894f7e212d048b28d83b1bafffc962913b84ff6916fc3bfec61", + "fc2745b56d1152517de7b62b05dbc8db08d979860d83927567c1d3c04d7184a5", + "d8e4b216bb535ffaed838ae35dfbe8211dfff12b631a078998b771730930b69e", + "eb8c0a20f3131ce9300a52f0f8dbe68e2321236b5942e3c8f684118bd6b1cb0a", + "9b951cab32ea9ba7544e085b87571e645ae38cbdf9e8be32202044ee80e34cf2", + "87aa995c1eea28250ac4bd13f329b0578a7bada0e0494df8e940b6d38effd034", + "d4885d2277d11cda6ea427937f316709c29af28127073af28d561b899a48ef57", + "790b3c2ca38eec2117ecfc0d3f110ebc7b3b3c60040b47811f34213ab7a502ef", + "63c98f8780bf611eaa7de165bff11030b06bfae4d694ab9e12dd6cc7f7820c6f", + "d6ea7a1d884dedb4ec042f03fe2e0c6c79ebd40ac08288270dc76ca7c7655ed8", + "27145eb4bfd09f637ba6ccd9965aca8b64f0ff5a02cc8dfaaee11e1ee1696a45", + "d7cf58c4e2b083c4a363f9c8865b8db2cfe8a4f610e9ab4e969e09d919c204f2", + "5e350cc032c0afdb9538970c16290060e9823f3f68913b856591adf4c1b36f5b", + "0cda381ed83f54a43b589eaa56d9ea819392f4fbaa09d662f85f2e203720f54c", + "3e362c212a307952df3006f92e96eca459c219853d24cf7614fd791a6d00f0a1", + "5e0a3a39b82b42aaf02780335435ffa68b41175e0e55e357b4b73fcd62000f20", + "ea7b085fb7432161a84c2e272f196e572ff1789b765947d0e995c6aedc1302de", + "1d21fb58ca2761dadc5060e28ac9274919df66a68b68e61ed64745fb808cd0a4", + "42c5077b8e8044ec817f501483b72c180a8bfd906214ab648ee0e32a3679df97", + "b6e84f62a004317cce25b7a02b5be32081cd567140bf98a0f25d3e6603b90fed", + "19b532961787f225deea5299806d4eb2793212c66aa413f0b87a2a3f861cbdad", + "04f6ca33cf8ca2aeaa66774a736b6b2eb41f70ec93359e3f49f7baf2ccdbd15a", + "44a45eab04abb2b07ab493fbd1a2b872aa8f8ffa906f7042592e9233f3d33798", + "a17f5dfcb59aa88f2a86db4f7e656b9ff59371d458e5533b47a0f079298f6ca1", + "87264cb6f804380ad89879641643cb473ee605e1a7d36233d9ffb477a279db74", + "4caa4d2e90559edc972286abf51af5b4d4f40434522a2909804123bd494e0cba", + "58fef3b880709bdf39eddd533942bc2163af3d7b9e0711ee8b5bb013749884dc", + "653958caafa4118ea02567941015d0d2cd59cc724b1f8c0b942d2f4b76df624e", + "bde5aeef7a9b850ddba98ad13e141fbf33d20d964e663fd23627465eb5fff1af", + "7a8e2c696c25d6b742d6ac1d8503d5347883ba7cf773c7236d56ff9a2292b38f", + "9c5bfb619e8d6f2e62d8549c789495669366efdd16624c355b415735d9543349", + "44873653c064d91f934f409555fc603d5518e0ac032a1fea77d8990b34b9ca6a", + "a66171638b1f4feef6a63062c1daa7531a08a8736c101e427548602040ba3668", + "b2d6369aee142edfa326a9ab352ca2d0caea02cac1efa694a67a7c3563f188da", + "288b5cd212496f7110ed62740fa66becee0405a1c8f9be7bb417869de25b3fff", + "3218925121ff3fcc8680ed0d5f13b9965779261f3d1cd06c0f3aae690dc5248d", + "1d56abc28349e5c50e2ce0ad0fd5023fa9e0e64fb0c886e46d5528d921513995", + "f8db29938ae6d1d5563e46239a59952e60c508c9632399e4164eb48e96553287", + "3e565a3103e7149a58d0373efa0fe6827a8d46376574e2d2058cf6124defe879", + "f5506fad09d8900fd2c0a3e4cb54a94fc6fd6ccb2f94b6de5e471154fd3282e5", + "78652a4c72ba8c7385c7bb4afb43c331f940769b53715e33edbceab81ad2bbba", + "f8fd41418f58fa9dd52f88ed240be4e12a64e0259ffcd616a2d006647d541145", + "5665bb9ef6a8b2185bf35108074031c584f152c0a7892bacecd97adced78e971", + "a23f182a301630e914a7a99bcb3412c24acd0b1a4d3ffc6b12e34e34d0d1e90a", + "9963531429344212174de0e6c629a0386bc65e7f42e430e7a2ef0cc58ff498de", + "40555ac83eae341176cd8579ad6f991f75a86c507a66572a957c2348c9c66084", + "1bb27c195319e1efe762d470ab195d35172539ded0199eeaf5e442b0a3d9d0a3", + "bf2e6ec9d28b003d68234c4b0fa4f2e5db85aeb72657e613d6b23f3a50fecf77", + "fba4fe7517fcc1bd1f2e6b21898c8676999b6debf635f01acf510a2c39f0ee47", + "1738fb52d2d1401dfb4ff3e6bdb32fcafb63be77950d2a59fbbeaf4507145962", + "2aee810fc8d7be725e185d1b98e24ae80bfff449e0650feb3424be27b6f86c73", + "cc22ce1677b846a830b3536d3f1de9bb915e4b2cc0f8afc6bb9d99c827b43bd2", + "3464da53afdbe6badfe38291445312487dad28d1a00a4690a74829dab36cbc45", + "5b8efd5260b84f6b3ed7d815ba96938a61db4b66247f646dbf84d9d62bac3ab1", + "6fa953db03c4451f8559cffae328e32fceded428ef186281035259855d3fed27", + "b84d73b2cc1485f31db9fef7941b27a0999e5c8ddaa81b7e8d9b0c8f3fcabd65", + "89397c142cbb33ff0189e1bb3dc6ee95180aa36ab5d303a4270da83b97bd4ad6", + "be270f4b1e0853e5434f24510ab7bc33139ed00f14103ddd7132f64d93069727", + "233cad1dac0b537cf32ccee09b27c7b97b79fa8821cd2f2922c5ccc11bad3572", + "0b214f63e1f42ffe946ae5fb8f163be833d3e077499561fd8f45e92138d4d0f6", + "0bdf9a0491926f273b73777ae78bf0e3fb1e8ecfc55f9c83a3c3c7f2da7152d7", + "480a39f70e9aed687d79e10faa6eb4c4dbfd9d8daabfb709d1a586485777efe3", + "fa21d14227316159fddacfbf46001b55ca6801311e302d68bf71005d0304da3d", + "488c41f465d2620a7284114855ccf55230df826ad5071e8a4f90fdb946258c17", + "d8ffc6f9f1250879d0235060da23f1bc15de34580ddeedb4c4e58fd9158b39e5", + "59c68506217f63adf2916b9c987d24db09c1dc05a4fac5e5c6342fed785c15d7", + "26618b0be1a5036856cf74f735569afe72b29d6143bf8753a2dbf35bccaab26e", + "833a626ae884b43743be12978f6ca6d234fe442ed46128ad77863675eb2835c7", + "c1fd55e0923c716e26497721526350f9630f82761c49fe5b909679c742d14c22", + "f2e921df684544a8d2844d93740632da6dfbf737b533bb2b96aed491462f58f7", + "100185014e08b3aa621cdfbee2a905cab66ab396337e80fa9d64f40d17478b01", + "3cbd2fdf68b02aab0a125534d6855608419cda51bd1e1fdcddd3e187dffdaef8", + "a4d3a1bb74a336daefc2db786975370311c179302b5d7595218be8df1a53c690", + "4103b9d2fa433f98b13ef2176083bbd55d864fa3085aa5240a5474514e71c320", + "ccc9a563465f1f4ba0d24d0b8abb866a2e2787f6453aea449dc4058053a8a050", + "c844c09b1454c3421435ad7ab8d9b5496b89cb39346c895c37f3f0735be32491", + "e159196355e199d49a62b8bd6d80885c20ef9dd392999f02c6f9d513cb572ce1", + "d000f8306978fc77f32f8fa11d32ccde70e48456a31cff38b838e4a8a893cb10", + "053c26ce1b3fa89d390ca497b4e4cacbf0633e7c4c5e89ff255149a94faba136", + "4c7f9e0d82e0034656d6c785cad431fc450496e14cc3b87a8e754bdfac1577e7", + "116752d56c1b520de72683a2db4929e0cde38450861e405733b234c30a6df91f", + "2d25c059215c296ac66a30b5b46893f633f149374fa1f3beb41f5b566f9698fd", + "82281bcd2bb4e32e98797e24c651805a4d79164690f9929f53c5c8b530129b08", + "258ffb3026f069b76d5639e4865b74f8765e2665264c21183a4ddb8edb9c5619", + "09390055314065f7d50167845bc05cac963600aca7c64c589b237a16cf0e935c", + "e49c13d8f11a44351a07ea3b8dc54e8a443d176950a1f63cc511844d50d3249b", + "fc694924cc8aa8e26721cf755f9b64a42ebb20427fd23e875d1989f175a98563", + "a1819448074de8bb29c60d09c40b6e042a480c6862c95d2ab65c516ec6ee4fd6", + "02a876592044dd80ba2a6d1ba37c241f048d10760a1b8b68c9d3b971b612f297", + "2a0e04d25c3cae54682588490d051a29fd7fb38108246dd5de1ef532ac79e742", + "69a54929c838312d2014fb09fe55c1d63e735a3043f08b02960edb552e13de38", + "85f6b845c26f8c9519664c71c61463111abbb7dc2cd006412e9aa556b93517a2", + "9e4704901b4282c96895fadb287d7a9338f2fb26a5df3308b564f117a91c1680", + "62ab19394a7485880bca4a3c7971598f1a91be0a432e90651142f2c364ac621a", + "9408070d78f355700e0f43c1093c9c2ab8f36b2d5d784e11f57e8cb8a5ce3695", + "beb6d69a0ecc04486847f795eb03e1e3ec3c6fb8e8f62e787e136446edb3dfd4", + "ace9b55da7669192015eda8ab77df7381c9ccef86c59c84c79b38ad8b1881779", + "64b2d66305e8ec1cf58a5591da705c2102aedd51a46ed7d6a88b7135c3a88c78", + "502a7afa1466dec13d9dd0584eadbee4d476b44afa3a6762b19123db2a8037a3", + "ef9869260b4e9bcbdff3b665d3c895412ff25d4edc3183d2efda832df5f66491", + "172c587fa1fc6c47f349cb9ce38d7ad7acf2d61d3f1c9281de4e3a508cd615ae", + "3a7693b35245b97402e13598722f66256e9a307a3e7a0442b0142a5d06d0d6dc", + "390dcbe3d8904aa44e925d4c9bdffb1f09b5267f807e4f0ca584576b867c340f", + "c089c04f2d269bb5c572d1a1e2000aa400dfc137727eb7c6684a6044582007de", + "ce52558cc6376c77df1481359dae507d9e53d3a3f1c01aaedf31f0e4f265d0c9", + "e04d473651e9d033a011e35217ead31e1e947c13387cad8f473b75c35678280f", + "903e909e6f6e32a29c6722ef5598765572d17da3bed090fccc2e36997f471c24", + "b38e0ac4d93cddb3b66d70a5134474e7afa8c46b52cb5275d965336bad6c3f07", + "3e748f4983548caeaa435b06f1913183d856e88bce0bdb5a9a8b7e1bf5321d3b", + "6ad30944664f7f873d7d1203d4ad102bb771531d82db0ffc0d6f28fa8a4f1138", + "581cab2fc100307f56791ace48423be5df6dde2c28fc429dee13dcb25446c78c", + "c2a8f13be9ca1842f5a33a2e9dbf197df70064aa5cffb026443de9bd4560beb0", + "0d26ba676dba5794745ae59367d9a7a15c2f1d9f51a13bd1ca105d8ee79e9840", + "cf5249e830fc98faf867642dddcec0592a0e8fee6460087c8dbe2a08961a2b8a", + "fc7818741d87abc2e973c34497132e813e7d83dd7fd43b10f14c1f17b7afbda3", + "556eac1c170346d0b6299cbc0447d1d856a0d34d919c30e4fe38001aad5cb546", + "8238292718efdb7e451ddb5c1b4a72dbc72f4c601b39d2dc787653744ad34033", + "8caffea2663e3eb5e10308c1d632c906c3faf74e4a77b0521cfccc0b39945b41", + "c7d04b1cae836d66da46d57ef5404db7fa5b4b99fe140663e448b97452dee1b1", + "4c724eec3a300700023167f4cb391cd21db2346d5bdf57ffab280c0059614850", + "a6cc4a8df10dc9c82c27e34b212964d5b966d99369ccdb6325610c784aad2a6b", + "43ba7b458d2169ffcc8b7d06d231e49f15702a2a7168edada9b12121ae624adc", + "f3ea04af8cca0746c0da956717385cfe1c0807b8941f0eb33629f4048efc38c9", + "41215412d56063d36993224582563e3a1dcc4e834b90aa81df32ecfd8180c91a", + "40ee79414236fb44e96ab58727a19b8f0e746f51f4bec033fbfa54732bf064ad", + "f7be3d0444fae359ffc24d736f919944ab57e5eb4e24b9f17081aa4d0ae0472e", + "11f21bb7df93df081f5e0207280a11b674800bf45e900bc1b705a99d91b6fe53", + "8075343fa0b6797ce6181fe342631908567765655128b6a249f7ad7e61a3d557", + "61d0b33a17982b235cf193a73bfab6d8388f09cedaaa31687575cd88f4b179e5", + "fd9e34fd3644ba3499f8a6f0414ff306fa48d9bcf27cc31fde3f706dde9a0d49", + "6e5caa37cf48aaf95671ce5d613a706b0ce61418ebc744a5ef478d244d6e2d44", + "f9a57281f314768b7c611ce332563f669429109008306bbbdcddf0d991689ef3", + "76ceeea46a50f98d6097c3cefae6e3d18c8f618a95b5405df81c995fc4641c74", + "be9b46bbef3de2c6aeb082b2f40b9b18dbd995984fe71cb422d104c198503c84", + "da2da26f56c495940ad0a158702ec04bc29ed3e0b4263a35a7eec3e7e2616024", + "0200cab24d07ac58641c291d3bd86192189254397d976da8dd8c5bbdb6e8afdf", + "59f65080e6c2766179b56cf919ba1ca4dae829a61a270f66ff622e4409f848dd", + "d14d81f1330c524b643f7ac13b5f132b3b220688daeb52d8363fb39bc5ce4d72", + "ea5510823910843d667762a321c8581c0647e22515f08ccf81cb3ad3da67a62c", + "2963e7c3b349c8248aa3bba9601df877d8ee01910167a9add87685d58b5d9ff7", + "77352e34576646c652efce8cfac0c88d3ec6ab1f937bbb0de2bd4742d65790c5", + "8aa98d20b9537fb8b97dcc645e0ba0c497f35bc57bff5cb2fdb173de25d61ee3", + "79b544916fae301cc68ab3e52cb23d97fbfe76209cc940b6699eda2df0a02039", + "5f2f71c5deabd962d4718de04a49868d1c2ae2110b1ec2b2aad190ba4c13c380", + "aefbdbb6a14e9db8bdc1eec24fa0042dd21ea4e2909c47cadf2da6d80536c99b", + "1eee518f879112bf7248c0b6ccdb82f806a41c8200df9baa3ab81b3925f35a75", + "6622e3d26610bd49d720a500ab293a693575f3506f82f61ffb09fdcee09409bd", + "9de7727d1cea26c19ad8c3dfd207dc5b31ae30b76d08d7009cb681e9a6907acf", + "93cf13d68560372f2ad5df2f97e092c5583abafb3230b33fa3195a316ea49343", + "008944e3ebcb49a19719bd68e4f40b026dea46037fd0115617789d0814499d1f", + "c9cdf34fe29a09b4201bbb35ffc3a0c14fc1783662ce19e5946c022256188d87", + "61c8681ccd057f5bea15b324b60c765955b3781825661e7f9a014014dc6c6ea3", + "0f5624711f584843f5721da806e3e1b73ad521fd6d5b78e5863c7fcabdda99af", + "9e49d0e8ac9b6ef84a6453d30b00aa634a57876e21f5b3e14584c9034472a58a", + "21c71bc88a40838855352a23a7685a110b04f6184553c2ebe2cb0f8d129009c9", + "7da5c8d5d4439a681a9f28582f4fe61ac38be620a368f89f6475ac1ba3e36d0e", + "8f99d9d4b076724c1ae8051e533ab762a597113e113f0ba01ebf1bee922ba92c", + "67e8a57074a7f006217c288e24c7cff93cc296c83a809e5b081f0bf0284c5876", + "9e1212a696cfd133866681998c0c3b334171ffeee114e2d62c8ec94f80c8bd04", + "3d22bef5be25aa18f8f86f161fcd0b86aa9bf957b6648e4850884dfa817a5db1", + "edf03c243da9659e71e5af6a9fc4ef28562a9e6eafd26900f0901c287a012282", + "295b03c2783a000350f986922f7f98c0f00a2ffba8f39fb8981bac11cae3aaa7", + "2bd1c6701dc685456f2ff02b9c9c6fb4d90c2b5217e579b6494df2e7d4b9bda4", + "c7a743f8b033785f99ecd0085eac42e9f6da6c965e461cbb7267799d7cbb8d7e", + "5a9e28a619053d7470d1fb81f018df6bcf34b93b758b0c4b690adf6430c59c69", + "f52c489570a9a80c7b7eb5047c5ac9f864163cf539e519eee513ad05a7fb9f7d", + "f1fc1eca6db639105b55dcfa15ef71b9c68ce3648d7ba8300b871c20983e8324", + "20b497203b57354813ce011168e00c7af52e9f1b33dca3b196ef0ef759d07f37", + "b59fe2cd98414355aa855852b69f033172215467e4644713908d262e8c28b67d", + "9af01e3cf4eddae1fd2956485c3c8238c3df7684413257aebf85cd38594630f6", + "b1f233fd6f5509fdfa8c58f8f6f9218598d1096611ddfa9065257aaf6905d765", + "089117c4849dd581c1a117dd8e65b9837e0853684a52389a213a2723a5e4c512", + "b08ca0c2fbb28caeddf4d3244cf166e1891137d8defc3e69a079e2bed7dfd5ec", + "a1cd8ebce182096248dcaa47ed25c6c07090fff5ebc563c734df5fbb4201af55", + "774c744f7da872f8b334c31e565759c0d258446fac47116be17c392b3e85d81f", + "48eeb348c1ba2035fb4efb9cc2d06704b51af565c9957bb1328f7ba960b1909e", + "9aa7e6caec7aef3b7d588ea42bf44da0282925f5b07ec467c380a2176f5ab700", + "241439867c14c3158719b463fdb5832a29476a0a8eec6e2bb06329dc3669db10", + "07ac0c04f8142d4ff5cc9651f44a3a953690df6cdc0db41e8a31d449d99a1277", + "14d45f67a730ce928a0d83d964b5f9b809b91b85601acc8e4fe6f8e1561a6f9b", + "3b72713b71d00681890a20a5df1415872a6d21fbb816d4605c71df80a33b18aa", + "3e1845a9c290be31ae03183b6a0fa849447870b221e1a5f435c6f6f9ebb338fa", + "610b27d868e833e1fece6d87e17e6c595e972519bfc087312c3f98d810f1e69f", + "2d93b31a05b9a453944ed3f4b80046fd90132a841a03b9bd079ce56d88629bf0", + "28fd908f997d764f3e0a0bdf7148c5aa047e1b6f681f148f561f891b10bc2910", + "7acee0e6b910e2c1c81578aad28ca2e2ce571141218f962d0250d4f7eecc2c91", + "975b2058ea8048a1e5b2a8cd662d40315ef43a1c9ebb95806c4ae99814349e92", + "29cf7553a32a34d09a7e4413f014e5e70afe7523d7c06456b7621fbf1e765702", + "22fed3bd16c0629767159b718682d2ea103cc2a53ac43070c98590fe4460d258", + "6ccd1dd63c39a5d5b01b3b12bfc10a9799f7a97f292ace6c780c5d9394298038", + "da014808d17b9e71e856fe65e388c8ee4fc767b329c0846653f52d622487ce17", + "31a1a56de3609b835838aeb25f4a46e637648385e292f87795c4374483712bb3", + "816888b06e8d9c70405aa9507f35269bb692bc54c0678c0f8044ec9d77b69759", + "ac699c187441fc5425972f75d19f18c4797e46c94d1a2a6adca6ac6d71f51013", + "da9174a8820c8e4e3df463dad8f42c0f5bd364656a2ae0b9871792a6ee35afde", + "a15890989a56e611d9e76dfd3adefc88522b9d6c12b00eb8488d6ade664cc43f", + "caf41b1d4dfb4f6073f8fd2aaef0348c728e6879fef66a6fdcf7a1467961285b", + "7cd0c3c129a050646d6c8c6b9d2a8618793f7844693104b657e355a023cd2c15", + "72c5319694b1c9d3e33cfcc21dbc2519331718bbd14b80b9abe94466a49afc68", + "99c7593818378b88bf975c6f4156a324aeb7b0c780ba6e85871a04438c13c040", + "d8388a5a35f5dcb52be7fce81bca22e8a5328bce58bc711c4403bd27bda4963c", + "11010425029415741225b57df2d5a013b579ae3cbf65367cbdd53b3c1cf43e95", + "198308b0f4a19254e024bb095c7013592c7ed371f052a7d902998f53b25505e6", + "5bc848665930cd9b96aa8d45fd1c3f9a5126267b4570310a1c3122f67b09b8eb", + "5cf54c9bd52be3221dc0f851716ef93998eadca5e8d9c0062a3326df030691e5", + "d21b17ad28737a911e8c4ae017da286b8bf4af54bc32722ea043aefd907c1564", + "6b8c7a89dcdbeb6557dd499e73aa7d2c386de87c2fc6bc65ea2d76a4e35956fb", + "3a91d622c4eb96399b551314e317c3afdf1831d61bd8cfa4288904437581966e", + "f4e759b3f79dd95907b8a95e2c55137b1789f02419f1a4d4af32cd5f1598900c", + "cdfaa8a160c87b4d57eb163cbb9e185c1d04929427e974c04cb774f499aaac8b", + "f52e77ae77f953d0887d6777f602e747ef351e5b7f06e18d4a7e49fbfa46cb5f", + "c0106b35c264b1399f2f1b778e4ba89c792b8008b3159dff95f937d06b94abf5", + "eeb5a79c31d7422c49a54a5cfd133aee92c012ad9c135c05751cf04f1a119dab", + "47ca7851f7bd437d0e39ec16395f339306ce0d5093ae54ffc59b3d57765cf232", + "a6855caf0d769d5ef0c7806ca4dfd14403d708e5a8e78cd6b650c6a62dfdba69", + "dad86208642d81be4d9c3dd76dd01e892d56f375f69ff982edc08b3286164a0d", + "2a9a39a8bff736a9fbd9e0f4ffefd4935015e1ac1123d6e7d56f5c0a3ac4c907", + "509b2443ce9104b6aa20dd57b46d4374f5c02fcc3f28edec54c769bd01df4b64", + "dd19da4d58ec02a4296c0756b9974c6bcbdf172f82f0ea841034b60094fab2bc", + "178630c472a5e62202f67b2aa453c2375b026c9b0a607ca2ff1d7e719d6d1a0d", + "98801c1f106350331d48cf6cb3ad9b5701028333bd23b5df1424ce2d05d09385", + "3bb50aa1865ac64bf866d03155b4a46e51c5daa25c637dcca5874ddadda52594", + "f14e058dcef183f09b7207d600be2e7b9ec9a34cf8f50d28fc462f91efcb1ee2", + "501593f75b771c6b3523f2fcfc46741572ee96afaae5e91fe0439ce04d98b51a", + "f61e5fb53303bc998c7e05987ba3ab0f4b4b76d34895470d429f4420782120e0", + "e433b8966eee4d5ebf0071536d9b55c13c85a30a3d003202fcb7da0d9268dc07", + "ea40d93df502b638ec4657dde632bd826b96e730d3bb5ed267ac4db0ce671c49", + "5f04c9cc7e15194decdf7dc6159694c9f87e52d38b5dd4a7a06b52fc25734adb", + "43a282caa24c8fed619886c8686ce505cb1cc41e9e69d9b6fa6d2f6ba9f391a4", + "e5d9b8b9283af6869f172ada3d3ba5b25f41a8b42d672cdc5bc6e647f013e2b7", + "835ffe3e217ce2ea9c48634f01dd1dfbbe81c8ccd2acbb0ebacf16175c914c5f", + "e5f446f9a196e2213351a2900b319bc7f2bcaf07f1eda556e981ce5c45d10d3d", + "54243d2039e1dbacc65c0031cf9fa7201432d856f3377e2eba2dfb4abab76055", + "e9606fd625aa44842056e6346dbf2b9962feda41a5b76a82f8403c04e5efd41a", + "60ef49863458054d3c22d1ba2e9edce7bea5540c862a1558e3a8579afd798344", + "b4c914520a640a4b9024018afa66c3e1b65ba25893cb42f356a79ba9db5f4286", + "fea7a9c21ab4eebff6d39faaf48ae810e346e6acf92db14a89121c420ed76f3a", + "b9914faa93b20c6f1bfbee6703936482d141528e40a3b7a5cb13a97a5072cc94", + "0d74dd5ebea132d0bc626a207f2a52c558e474b70512581d94387086c97cf5f8", + "bf384d84488cb489145f4934bfca6be111fb98476b8723b1cb27e5e157282312", + "732a289f4acfc599d7493a552baf3bdcbd825c574daeecfae29ddd28fad3e6bd", + "0250f48209e15d17504d87001f60dc31a931142e29ab207f75e12e903414841d", + "a3600c24f9dfbd3e5d58393b6c39559a82143f5454da367aaa624d07a5b2f146", + "ae17f4fd4da30e0e1479daa324b79c7dd0e2b39f5e789d7cec8ba55a109d4145", + "8b11726bd48fbb6aabbc23dffefb44ee873d9420aad21b484233f82d74c8725f", + "505d90e9a659be736eb51fd961f2f15247298544a7623114e44f9f61251df8b8", + "a8eaa1b347f6b57ffa7e938fca8d2e2c6c58bdb5eb775b5954652c9f54e1ed80", + "bd9af53cdec7b085a12dc38e1781c62684c6b9920d370c8de84ea1ee2aa10224", + "a83f697d3e60a93250599f191031536f9cf9b6d8eca5aa244e56ce7267ca5ab6", + "9a06221714196df17de5bf3901bbc44fdebb264645efa5ab49017499febc8b5b", + "fc29e46847fc26d210d4d378d9cdfeffd8010162d2946998a15c86970aa432db", + "a201f61de3a81e8727a738d02c62b5498bd01a50cfd5b3b669ce37b43e0de9b1", + "2e9ab3f4e1b89672beb86bb243852b31dafddd3fb5f247750aa2c12183040420", + "f997e603400cceaee51ae1d37fc157daabb00814f45963100ed41a49d5734b69", + "6a35662bd4ec8d0a1ecbee1d80e1d82fafe24fb4e50115e337fef498cbb0462a", + "10b6ada6a6e0c6ffc56946767e8a503450c52547097c2f96b34595d6d0ce5171", + "196c5c237942d0d3eb600ee349bb24bed99ac4a6e1d8fbd3364adb950b95d4d6", + "f7b0167729c580667efcd8e8f56b8ba61d1d2f0bdbeb3e09013c1f2f02f9c761", + "86a5ed585dba5f1c73b49d97f913e325615694f6ba6f80560c160fe7ea73e5b3", + "ea61081d1d0dfb71add6e33119ad162ff00a9d72766df260e537645534e39900", + "d0084f8874f648bef04f49f705d4afafa7d07e4fa9851a8d19d0b4cb83bd9874", + "f41aba54ae50cef55f29253d5595c3b84c3c5c2149ff9412db2e6d1e4a3bf300", + "c208d16625be5c7d99087485f696d4f86e7792141f697132050ff69c685ba13c", + "c5e8eef90b4bed7da4f0d23ba66dd4d5f78a47be09a5429d43cbb0c048b02f78", + "de17c0fdd01ae76f50b18262e11513ebedfdadc28733d649cf5996311f0d6856", + "fdc0b9987fb5553b480a312592b5c86d9ba0ebf17f83a9a8bccffd995b15adfb", + "496077fb2f8e1817844865edfffde8d78449fddcf51a1f6f64bd6207e856f7d2", + "c7df7b9a9cce7ab490dbe9ee0ed7e9e503a7bcb54e64a74f4db99848c0d8169f", + "403036cd3e84cb600a9a0bba18934a06204233755b9bb3e8671628647dd8905c", + "7e5e3c0e4f0af18bfc2468a536cecb338991ebc04d20010417acf32797a333ab", + "20d93a010fe2f7306918a85facccb74a0402ce24284c00297537fe44bb48bf42", + "affce621a8138a741d0d2dbd75ac3347232f19e4558af9d75c4b5a18c5981715", + "cc3e16e79bdeb9e3d88e5a901a17f74ac6bfe8d15012bac36da9bed36c0d2eb3", + "29465054e8fb55144d621661a214a2627abe96a11c59bebda459fdc7a9a5ea24", + "a72767fbe1c45b285617b808cd6283c99946fb12ce4adc63a9b7db730a09718d", + "7705e7b5d98ee4b4d7a164a22f9a22521f313586422eaa64eaa63df98dcdadb1", + "cf33eeb1e8af72409022c93cf8c8dffd668ac67fffe56c1c73de335ba0ae47be", + "c0651712aa0567a7367f4535e0698981012ad21e3c430786fca064895c5578ee", + "66cac141dcfd1e98516ab87bf3880d36d849f0c0c2287d65e68374b8f890da53", + "a0d77548e1067a0ccfc80ffc79efb5b2ec19f6ef8ebe2b39767118ff303ab4bf", + "fb06fc722cf6422a826dd850ff47fe0456ca1dea69c00c06b47845dd0495a536", + "cab7d0484ee77a718948fced5ad8eafa6bb50c3259a4685c28e1bcc9ac8d452e", + "bdcf8f1936bf6a205dc4b6138e9ca36ca257941e5ec2412b78a0d238b8cdb8c8", + "7f3114a52aa77e945f3d2746303b89a9f141272f5f4a5cdb9d5037bd26aa9578", + "55ee933bdaacf20c3dcf0c53ea4916e306bd5327c0daeab68db997d41e815cf7", + "455085fa89dcfd19f517678707c6bece9a0832285d0f347bf9e2e6051ef2951c", + "f3fcec854558ce644eb904e7b524d2bb06213dc284316d86441b0bca583b36af", + "e28a0978a3abb8e4d41658108200ba20994ccee20dd7784b5e493fbf4be59e83", + "0e8f0d7253a5b13d8fc2881f1c6cb40bc4e7da1195d079f37bc56b54db14d366", + "340797d67ce8587c72d5cd29188a1d01242d03c0be545869dcf1c6b8a35cb90e", + "08946528d81a904583ae79a9b587fd5b7b361ddcfa8fd8d29880d8c4d2789ab2", + "af921dea6e6e9adeb8f503dae8b3bc4abfeb1236b6629656669d9cd45f1215eb", + "2d9d40566659578235ad085f36d01c17d7a5444decd8c5dd7640a6f2dfea3c5f", + "1718030a12a9ab40c21c877ee9cafabbf1861678d16fc12fc5b2e8b947413e3c", + "93e177d4f1ec50fdfe92a3d9a1dae03aab13b3fe14acaaf189062e55ec649d5a", + "6f8b7d2c968f5bfa466898bbe96a014e042877dc0dfcd97ba8b44f940da1999b", + "9aaa361237b92c030bc07796d37676627b3c3de9001903ec4ddcd56c03e90aad", + "9945ab912a4b5cf9d6617ce413735cc5bfbd8ad341cce24f35fb6c9f205f4687", + "804a870441dc38da0394150a3f4eabf24038cfd0bfa2a05ea42fd2292d8be373", + "c8117eb6fe4f86df00a82a47ecf5dafb8ebdf4e9af4fcfc1a949c6587ba8aaf8", + "dc26779ff99f458f1b35382ac8e9ed3609c1920b766cebab5f20af8f10c96000", + "9d72cea42db14e1c80716c0de5f988d011a5feb68c0ee71779cae5d8282e0267", + "ebe6b26b9752dab3946fa18f6129fd7c5eb889fff1579ab85c6dd0797520e6bb", + "9a604d4c2599876cfd9890d524f7f9a6f982794b83c15520a45ccb0b74b8c90d", + "a1b5faf48b17098da38d35568eef8cfdc723fa75c74331060dcbc339e9c837e9", + "1df01f0a1994282480fad290034fc91a202658924d923f34c2d82fe0ed6fb7ca", + "be670f1d1d26fe185cd74d8a13f47cfe2f3b374052cee89afc51e5a900113cf4", + "4d34f5bb7bc5ee36652b9f2275eafa4d371ccfe8d6bdb61f719c51b6ec3e2ebf", + "49a149d8237517c2d54dee9cd4e03fa308665841558f217dfb762b42c365c01f", + "fb4b20da66b6fdf4fa77d41aae7e4a2d86da0b84412c3e1bbb8bdf0c924838cd", + "8039c477106edff9e66dcd444c06175a9bf50b5b3fe70ce478296fc24e0c51ba", + "8341c7b6d1685afa425feee40ef207e6ccda7edc6b43604312339e73c5d3ca3f", + "4cb9e8237964de9c937275132e92e4f714c3fe75897cf6cc464aaa98f306e0a7", + "93d699010295f3c0e70b06f871cfe0b6bd9e9ed5f27ba4ef193fe2380fa1e814", + "e8359d7908c3b8d3c3ae846bd33998ca21252005abb5bcde25432c520f8ea7eb", + "5493e993da4ca4d4570c790f0040e3592b51403bc021b30e9c65acc2f1fca86b", + "f63ceceb07e4b47735cfcff9a79d812494ee1368384e323df39d09ec0574f397", + "7bfd7f17b5e3e89f9d6714ff3f005654d21f3e76732b11f6062c9c496340ad53", + "a6e962d7360574f8aa09178f7441803e0ff711690d6a928cc34bc3bd9c8d10ca", + "28d790494b879708d54947172e4362aadc50603e04b60515f929cf19bfdd453b", + "c790f3725e2468b839ea3017072b6ec9ee9de5d108ec13ebeeae2fc8b4892835", + "fd14d7e018bc3796a957afdf8b8d38fa71690a4f647fd0830b6b902df2bd0e3f", + "526a308def41e387b5ca8e8e4689d23ef1b1d55ce89184896a1f066a0df7060f", + "e431dde147b52f073c1c71821dd30754e1eca09c22c349da1aa97236c115a0e8", + "c8aaffabede35dbb5e43369c16cb5b9ed8f716fa94a537b26e036c2251c52888", + "77453cf5b5fc33de6035e7727044add82cdd2f87536a37ad96ef09777bd0f0d8", + "55feadd2c0329c7f0b5d502a702b4f804aa87f943d31e473aa252fa0a4da3d90", + "8cdbf0b4b2c2d2961488b28ebf7bc843b5a86f60b7fb874150992a1e0ff02016", + "1b3a3c739b128b8d399ee8f202e1ae2ec87eaa39942b123bde3c6a63dd4b607a", + "9cfc924d1a1f0807047da363c08417105717d1b5186df4ad77e11f4eafd9736c", + "de13ef6db0c2d1640895a3aa513efebe801e81ad39cb2b4206e592d59e25142f", + "bdedcf2fa924c1ad3d4fb87b3cb0e7e087940f95ec2496ea4bb973b6e006bc03", + "c707f179df1c917f74e5176de0ecd8211960af01802e990c086b179861e720d8", + "057a31fa99c4c7ea3159a9d2d2e2f789e4a5a89ac96ebf866736621d1e617746", + "c123b2a99b07d0cdd01c266dc30581fb380b483828ac7fc94150b687fb21a023", + "1529965c0fe863634eae3c2bc7ba92387db45322cbcfc9fb2a0d8ce092a5fad2", + "97378e9f752b2064f8b354df2152e5651ff36d89f2979cd7e4d0d5b2160c6bcb", + "d777923fed3095b16d21b2bf1ccca84ec5ae935759e52facaaff09a03606ed7a", + "2c30a1d99c9f77274d7e0ea0d2ea525a09222ce826f27be889e005a1dd8c39e9", + "c352c8e002623a6f4f4819abce22998d48a73474fdc3f6b3cedfbe750782555e", + "bb6d3f9f098b5ebca9f11b002c0ecec2be7aee9e150e1ff1f149688e93c2ea35", + "4bcb807e8c630c66c7f5fa0ad1da539ca9b7dec1d1be1ee306784d251aea5259", + "137b393f5fcb7b9768bf7a0a7fb15afe2c8eaa48dcf426f0fc9b4227f82036f2", + "2db65bb131ef30ddcbdfd266ec2fc029f0731c0ca2c1283358eaf30ac77c9081", + "4f6cc84dc5f9260e8220defb450874b89383232bf2bf2a72664cd2c493f7449a", + "39b02c589a96547afa75f8e2ad083ff1e4b9bd6756d1331826aaea3b4462c796", + "7971d0720c7b0250304cbd6aae527e4d769d1a15371acd2730ef519fc270bc60", + "dc3e0ca9bb10ae9138094be6ae18db8652d61c3c8975b9ba75e458f9b6f34ed4", + "4a2c5fb4b3ff858972885b1d869bdd980b90b6a230e060c569eec0dadf3fe603", + "d155f77aad5ff3295493d3b27cf10da4a6722e8ff94027e0e54ffb432b1c7147", + "86f3a21fb380736e6b5cab705e8acfce0271129c293ed235df41e1fd7bd32c0d", + "e6684c6cf0c4b9ed2b87f048447e8206e51340b413d14357f0c95d2bd2d86c5e", + "111163c5d2334cabcc3aa4b107d1fe57475a0a122b948d791785b729d8cb4cf6", + "952bf309d74b8a8b7e0bad2184704ea6cfca0a0b0a1fbcce124f2e2fd7658e69", + "ad221d0b862886f322ea592d014a2d4535a25c9a38c3ad063941d9562eb09dea", + "b33934302170faaa4e730629343dca179c34ff56cb74cfe88288d3a3fea6fce6", + "d5389cdc37b63ccdc8053896884fbb3ef48aeaef4114a741e89de0e6ea041fe6", + "d71fc6d617db6e05e084b1003038144177ba78448bd0cbc2ff5b5d9ccd9e24d1", + "fda2574398f254bcc0e2187b732b2db92ee8a7498fc61c412ca73278052cf6d2", + "dff0ea5c5a8dd347003bcc18f1bd848213436d3ed6f194a898e40e78690549c8", + "942a2297460e70a9d4981f7ade819be0da4508cee4c24f944afe4fc68aa68e95", + "a6560bed871e5207a2b59d1f141da27ef5e09ce27089356863624e431f953b8c", + "0ad2aa5375d40aa69389bda5a07941ed1aff40801e326ed43fa3a77aea42d14b", + "481dae555070fe70a985f4b96c36a58164bd374f06d46f692df4cffabb682f04", + "fdddb2061fde4b2831923941af3ce71a5bfcaca65851c6b1acb5814ed5d470da", + "38bf7c429e6a5ced73e9e80e67575a10eb12284ad8eda6c5831a227b839fc107", + "a085b81f9ece1d37c4dfeaf4ac2373ef833521ef5b1c0143c13cbbae6c80b959", + "fe9960a4d18339061d3a420b5b49796293250a752474a802b74ab538ff914289", + "4e4bcbbcaf283aee6833e2712f5ca8c63b161b91707e94d3dcc1c6966d11bab8", + "4990031fd24d6f8e80d919fef7b2282401e5c534864f2bd3e4dbe5cdcab085b3", + "513fc99d9fd43ab44919d7df9669c07229ca6d0434d0298bf02612c5064d1d41", + "f48690ba476c89550f26d2368c57043504f3d819963619735d82470dffcfdba8", + "3a1fbed4118bd8f5febef8b70bb29b6996048299fe4a0ee6ac52030b3d6ab58a", + "1bd267cc70d6e01163e743a2f5edabd2360407ae896ba003e2ab8a89d1c472a7", + "d1d025054232f13ff1414b3dc8eff554fe547006f8be0505f5abfa9f52c2571d", + "ab3b878a8ac85dc2d0ba186dae2355a1e156389afff5cbb8b1fa1b9a8755a5fd", + "b51d4e7c4d532b5b9c4e417f6906bae96daea055b32912c1dbb25d8b5d93a576", + "5c5010a94856ec67fdf7d8baa1c46912b8726bc9bf840d20aba7f772a3f6fba6", + "6d68c9c4ed46e11437c13b72a8efd6ee5ec932bcffd56084e335986435b65424", + "781ccd9d90c33431b02364fe8f2c42f9036a2f2158e6b8b1b8e2601c12b6e795", + "ec3df1f59f2bc8fef1cea329bee6bd39fb955a54186c4f3f5ca99db4e3188da4", + "99ab9b9bd056b2f4b68f822f6fe86575c2d8dfffbfa664780570d2957863ffb2", + "6068d6db598e98ee9c76b5d4cbda70beccb5b4d21fd6f5fafae6572ac943aa55", + "22993d3292b14b202cf11b049e7ea6cf4d5fb402147ba3d3330c4a29d82c3dc0", + "de7f74fec2d3efd2bbcaf89a63d098d5236dd7f58e2a6a0d53693d1bf133caea", + "61503f1dbff906047ed5fd1916fc76df6d748686fdcb8a2eff5bdafd6f66200d", + "7242787810c3942777a72d7f43cfe294828a3b5b4b3684ad25b62789beeecdbf", + "5a21c5f6a038be8f930fbd6a1a8d0aab20d72ffb266ee3039035decfb22e44cf", + "e49a45e8ef65391825776d0a2b4b658b832a9d82eedfdc5aa300afb2ad4327bc", + "38e520a2d1ab6068e806cc3b4fc2d33ba72116ef98f86b55d9c5edb255895195", + "319d609ece50afcb5015c14276090cbcf8a3d37e34ffe50c8c57f808d9ec2aec", + "0612d51980657ed99882d24911682336223bde844b01dde39795e176c2a2cbb1", + "7cba66d7f10d82a446dd0e9e805c23fcf5b89cf0ae347bfc46553ea59b1090f0", + "16fa350d2c40658246635228db7be3c4bd702dd631cdaab665077406d9a0cd19", + "1b8f40e25aacc42ef55597f43255c26836d54045c8573c4ae603bb07ba72c328", + "5b9a38b8e2446958cabfc445fe5e84d18866b03ce48254fe39e25b797e7ee20a", + "35d4ae951c2d269c7f7d8a82b3011162bfef7d9c765261f0d36d26f4b4c2d5f2", + "9781e9b4b8e3ad3c72a81b476c8082cd20c61e669ffecc583f6a230d3a58370b", + "fff3b578d1e2470635d99a7daea87a93e90941a916f0f00e2faf0bee5f6b9723", + "0fc6cf8008a5ed08d502a387e6ac1ab380c4534fb7df7c4964159adfd3e08d31", + "f9cbe00505e775102d49434d740ca25a69036683143b38642f0f9de4bb8c74b6", + "6d03eb05af2fb73bf024cd3656c1c8befb5628f3866077951009711c51891a02", + "4175059109f7cfef3d3008187645a73268720cf44bd560f1cc1c8685a604d91f", + "7d001e20a1eb296ed58c03ebd1a20afb54b397a6b865b644e4dd70cafa128ac2", + "26c51c741639a7e775c48ec35d1b2dbd08b035bf1349d3d76acae7cdc1b7e993", + "de6617002c1f0018042cc7d552feb5c7ee5739463adfd53ca9e29d039a01542b", + "b3fc11101c71c89f0615438acf74b011eac190d709d8f25877b3f39528ecd0bf", + "4b5bd2eae612260a910e862564d2d60952568c33e01ce82b3711d779cb82e508", + "7345584f0e4e3b90ecfb18a35a98cd1131ec65a08b5a6aa8a64f60550e744ecb", + "2145852069b6f29e8c4163f23a6976863f25a709a76603367cc9bd364c6484fd", + "082d4a4b0c943fe0ba4196909e4dbb66fa32576c55c6c2209bbfbc87746687c0", + "20bc4f6bc3205b06abe63a84a990da25c3704129149ef4be614ea2a649dd78d6", + "0bf156065302fdb4ad886a945029a04c75a441bd406feb8a4b94f209f75b3b9e", + "537fc5faeeb4f41dcb8784ff46a898a720c841b22d64d6a833137f0f2aecc620", + "c501491ae7dea3e902837c6e283141b625685f3b48c924576eeb15d829a49a55", + "6f9648d2068a16dca0b8f0b983d2272041fedc192ecc41114016c49d623953da", + "5f64c62ead2ad9fb82ba730632a831beba0040424d6a45e6f9534bf81e0a5c35", + "ad451c35cb555a21243c54fe186c0fd068207c9c3e65d9899c7ee3d154d5b3c8", + "60e7f1df7f5c3b95b11413f9707296485382d6c8f43f7b44e385179431a05081", + "63a60f9670c71a8894b3b74e50b6a2bb80e824415fb2941242ead8045170ddf5", + "51f2ac878a92aa69e7eadc078f9a6e6173dafa24b9f113f63d977e4b6e479a6a", + "ae107b28a82d1a37691d5aa07ae1678a3fa2be93ef7799bd16df6519eacc2985", + "9914101086c4a5905f02a75f924575429b6f49c2693927c86fdb609dc5643a68", + "450e72f61878417b2e40aad2c78ebc7bd5bc070174b06cc5009636d38ede3c92", + "a495c8825b967742d9568a10bb6645e9144dd8d3ff2f1a1f72113053507aad7a", + "977813d9e498e52e058e2005ad78214597de0c2c059cff6262ae8bbc9912abdc", + "5de687a20cb36080fc7fbb962f50cd5df584b6dcae7fa22aac69a4dc2b143fc5", + "1a020663c8164f3e5f92e31a74aa69dc8a316a5840aa9af6193bf95f83c98d3a", + "646dd6426cabdbe0654a1188571cc52ae0aa81f6e0f0df69cdbb776bdfc5fbcf", + "4b770aacd9ab92272eb749a684d038d6dab057fb68e7a3d1e15fe379cceb6855", + "19b9c6a77219fd5b8853cb47cd5d2717ba8c8ecfe2d782023a2033b9ff08227c", + "812951e8d5767bf14aa3cade5f7d6b37a0c74b04b0c0a32b598cfc90530ad98b", + "caeb46e77a4bbf72cab7f6d0d00c5af4512055e6a4813f15a5830e9e4df58a94", + "ec7cb6d33d371acaffa13a616149b916775aec7dd24435a2f60f878576207918", + "927446e6e808e8883a37183dc8c7616c2e18bf0c7d4d429a8af30fdc841b899b", + "c2a667d94836efceea05036580627f798b8003f8a1ca6ccde8b8594d2bdfca61", + "68a1c91b5a4eab5b5a588f3bcf77b6093ad50817e2fb2db3c37320c38452a3c7", + "6ec2a5dcf4c5f7fa6a15f74bb8f1bcc08531ea54ddddcd8bb44f6bc55ce5ec81", + "049969b02fcd761119c7ec0fa65e7c73153742a9013470a093b524c631cb247b", + "b7a39e6368a4d542dc4a1e7ee5437d0c8d4ca74126f8116cb7c0734ece9de4d8", + "70c100986492094dfcdb22cecd4d8be82b54afc7da0812ce86f6f7d3274b8340", + "4760996f8a6758eb8a79129511c37fda5cfe5a93c363f3389cc6cca2711187fd", + "f87310fced92660ec5d7efac59e1382341cdc9925f855fbc9683510b405cffcb", + "1bd3fe417c21ad4ce5c368a28bda3a82a060a57a701bd8154f50cee50eb46076", + "f0c21667512222786f0bc3b60c6b5fb3d40431cd9d86e956b78f016c8500a1af", + "91364b09f7f321588e284e0e14385975aad15e0afbf8995cdea29caaac0d33de", + "7d43a7f8ee80d0de7ca835efaa35127c5153fec762d68990eb70aab541ee674c", + "d7f27a95c05c072f5f45fcd6cedfb0e1da0b792503baa882ba2f095acad71b0f", + "b809aa63375df9790cc56060538f09eca01605c85d1f39e7ab7578c09a92b0e0", + "1d0ca237570d6339d0cc227fc2611a36345c2484fa48d58f142db05675879bcb", + "7e314a9b48a43bba89f5dd454b1c88407be5fb440015d49f20bc82f108faed93", + "010f11ddef752d8baf425ae88ca6925fa512be000d2e5151d795098cc222f489", + "d830f2ccc0646e3c93be52d0009fe2831e4e1b176ab8aa0429f90e31385c7452", + "4a993fedbbfcb3d8db1f3181de36999101a8d9b3b3f157033f02951fb319b44c", + "5a8cae40ed35146fbf057d12d569cc13455523907e9ee273314d8c22d7aeaff3", + "ac66cd85dc52421699d5f882d7bdfac665ae37e9d138bd88fc18e827d2fe6dd4", + "d8f999d4c9a434a2b04aa4c0a31c4294c6e155e795cf1d8daefd562c49914500", + "0ddd0d851ef0283f393ded8373a9b9ccf786f154413f809bcee631710899ad46", + "24d94c92d9ff2a87cce68f036fe30808db00610af6151af27906de9aca68e258", + "9844f2c3157a2336bd481493b4b5794808cffd4de8b3ae9b7d8e95a6732f8ddf", + "8b95d03abac8189c178eac4d2a264fd66de003b023b27cd3b796654a9d2199a0", + "6be1336410e21d65e061b314512477ae5de712e8903365f530850aeabae0026e", + "2a114a94ca174d85a971fc502fac1b2a0ed5f9387a3181a9f7f4e77cdd083355", + "ddb29106af4b593c4fa3324238b737e6aa93a939ee4606c592d7d41c53f6990d", + "8973419a46e0ffcd9d99c5dff5d925cd3229eea8d2bdd3a472d72fbc5a7ede2f", + "3dcd4876e74819ff1b3b96f75d0e833f0aafe36f1fc8240b33beabc75cdc0511", + "36a3aac89b3fff1bd09f8fd0c1ddf62a8eecdf84bf661906c1e8e6b80637eb17", + "309b339b1b8aa4c36f0ca6097096ace1e99f32434674ac3f0db549e7188ff047", + "d1084ab7ecaca00fd5881ad66922d56125ac5fdf0bb5c42db48b340fd4925660", + "8ab2b3bd5767accd68eb46b751f5b89ec1fa4a713feed2f0ce79e1f90b9d985d", + "a9ad8efbeb1fab060630894ec61945cd7ffac07779b977da47dd4444cc89cad2", + "032a6778f35b307c5b43ccaee8b611794af16b16e28d6f596ea6937daa4591ca", + "5b0f8396730294f8604e379b871265409e03c2d512f95ec95486131ce2b09ef2", + "5e977969c54821de275dfc190fee5f20b9380654cc58f761cdb728fab02d7ef5", + "763d4eadad8c42f5022e40889b7adc0fcf7dc5d46142fb693267f8ccc4764ce0", + "2eb9e58c37ef50c9921b03acc65064528f9858b6bbe4315cb53b2ac4772c03e0", + "bda5382ba790f5f48290a2107a4cbaf72ac948c0d9bbbd037a55d1d3227ac47e", + "03143cc5ba6c6a2efa12205343c38528e754b598a8d9eba47e34e3f0755014e6", + "19e16aeff7ee22f3d38ee8f2bf9aafe3991eeab1ed1dd8b96cd60044bc7232c1", + "18917fb554744a601ed3ab29fc103482aa792784d26e531239da2abac14b6253", + "96c4eb5e0bd0c9fbfc18fd94ae7dc8a12c48cabd9551c3250f572d11c538702b", + "6d5a7de87ba25c91a9ce98d1976dd156a101c5b5c9eceb258d2575cf568ab83a", + "5b1894b5b7884f6a758b3573f691abafe8cf0db63d2b7821f9465de578f7a4c0", + "f00bbf525ce16ff0420b04d690a394aa07993b744f2d076837804888d2b651b2", + "a2dcac834d8e7f048d259cc38501414657080631fd8b2f8941921a6619a063d2", + "a0ca7e6b333dab253bb95bd89e9e48e5e8b6b4a928895f04ee301d92a5485f20", + "3214a20610419a4bcd9bf4dbacf76e9f1c5d613f11edfb822ae995f9623241e9", + "a53d6d62e590282a9c56ea90276040defa826b5e5ff048ddb67f863a8094b98f", + "e5e6dc9fcdf89edf8096c1fe84c0adfd8b88de4c2aa87dd6b366b04f38de957d", + "38a84dab2642988034ce8fe45988b745b6052000678b4494d9a405d20d3ed076", + "7c6adaddbeacd69976f39b742955f840f80c4e82249082ef09d1368ab26f7a55", + "9b8645858ad92de6695312b03233bf684930b3399d5263bab8e6a947035ce9bd", + "a859675109979501a458200d3035356db899f14d0f3127cbb978806e029bd933", + "b0e9d2c5d98b9626f7d15fbfbad94f95fbb796a776856bc71cb1b0e2ca859072", + "77b40b3a0332ad1c033bad8e87943979afde3ef828d203d21728ad72dae1da02", + "7a89817499ff901441168ec8364e1afa90391e32e12fbf99c71d1b2506f69355", + "b9b90f11d841049ccd1eeca05b6e353a80c2f469b8d2aaa8e0e227262c57d50d", + "ac3bf5682afdd4f41c67db6346b5ea6178d2d620612d7b84e98684083bbc7bb1", + "aa0867d01c143632fa7c419c4af695d8f48813f0064f9265fb07562690a229db", + "fe9e40d1183390e180307905e0775214e3998c1a4dc5dcbab0ca748175cc79c3", + "ebac966ad4bd04ced802f65d7ae7356c77ff3af161cadf8dece9746b4417bbbc", + "3ae49cb3719cfa39fc3a5104f7787b2251eb15199c6cd139941b1a27a02c0bea", + "4a2d58b49b8f779a115b792a238b566be0c6feb3421a125bfcd37cd78ee7ef54", + "e46cb97715e7e6c6a4721d0cef4288480a56143e14a59454adb517968c0d477a", + "bc4caafde97f9a00da3420d5160eef2b3bca93d6f87e4be2d32a3dcdef07be46", + "8ada2e9763d939d675e9bad7fefb40120bdfdbc84bf9e8f343de98cafa852377", + "eaabcab0dfe42dd287a47b228e1f04221e4d1f680d69c22ab64282cb213976dc", + "fa22301db09db30b863bbab3784e0be510f1804538dc0aa2f875bccdc440f214", + "3127b87fe7a39bf2f1df6fd6575d7fed04ae7184f8885fb22ba6665a7fced9ed", + "ca4a08c98d921dc637376adae0254fc9230947a4876224e482e850a3d8f71b0c", + "0fa89cc33a4b502ee79da6623860cdd2acfeb2ccd4d021767af47596df2e160c", + "cb2c3d04206db6a0772a2aa59573961fac8c039d4f91c6175d208e97a7580b9b", + "4a9ef2f9b42422d6ad99d1708f2d3678424a1d0e0cae8fb318f3e816e2303a64", + "c6f6cd488df6760ea50f85786a023e50777fdefd2f1a6ec148a4c0322deb41a4", + "b799a838d2cc9b062ba1703a0f8587b0ab50e0697f0ab51304944e9f39288d4e", + "1352379268101688d34775efa759b6c9098e88bb9f9857ee3217679569443c40", + "565030d3d4d861dd2d39d0588ad35f79acad9bb02c057ba4a3b42fbf04469ce0", + "60386ef7636fdd41ed1720931a513ef98f4b7554fad5f51dcce788d3625bcb75", + "a14c070d94a82aded274ffac6d207249b5a616d36f88ac59d25472cd82c7237c", + "cf35599912bcb4cdda1a25c7c6a9a243c41d7cfb19e47ca3d75e760a323d4603", + "e1b11c7a11916a2c245882a9a752e3f9a6f0b0f74f38bb9ef4d7935c9284fd0a", + "a00e82d63f617c326919019a32ebf1561f72eb9b63ac3b09ac3b571fb7ec0115", + "b3e95aac1b135f98a1ab8a61f9cb03c4ee1d35f4e6071543e40d1a7b86655226", + "f8181d3530ed61c3eaed1b77030219c5f6a33885c5ec214adee96c09435825db", + "91f372dae1b9651b5cf61c46396526a7046135506307b1b5759f02b3f6032027", + "731bf4be7f053a918159ea915ec5ec5ef75ddeaec30154ceb829714d29e0bc11", + "118c92f8a95dd143de8b044ef6d9955385a078fc87c8d3083e7f8821196855a3", + "c1601404291c706c937e5a1cb2a5282433e5467285ba160d2f260dd38fff33ee", + "ef77f22a3b7ef69d9cbe6a4ed8590053181fb7902d26427e7f46e8aeb37a84e2", + "3711e98025d22c848330715406a1d90802b082650690813bbaff540f5909ce4b", + "a49111993dea1f2f9735501a2efef612edeb574afdd97640345547fc037c966b", + "ad00a466f20ab3cbb211d9c6ad241c1f8e1edfc694830de991940a959c340efc", + "e16ccaaadab5d1233e2be89247e2e771e2788da42e576d6b79d6d3dea2f90606", + "9fc015542051954e7c5e1dd618f6d2a92cf609a51f0b58ab6eb78c6fcec46776", + "792d7875cfa6f4d7058001088758580dfeac8385eabbad57be59d581d726d29b", + "48f357c87b17ff82bfe55ae16fc0eba2ddbb476a836b03ce3e7c06bf3351ba63", + "a64d97fbff057c9753618924169731be3927c2ada029bf9656f1d4b7dbf4a2d2", + "3cbd7f8d63735eab28c22fbf4c9e6e22729e6984b801802bdf48f1d945ab43d3", + "687aa5762c4147382b7dd8ec3f6966dac6b89a64dbc5d64a1a0d84c8129fe11d", + "52c31efb6401b09ec2acb0c153d7816e853867145b805132e75c1858c6ce53b5", + "676a70a31ae518d934dec24a9f4d6d0a2a36705126c9e0bcc7419c60e98cb7c0", + "f9190c645ba215030c41a98b11beee9c283050832817b749e8ab54d75aefc14c", + "a3cff8a864405ab388fb6dd40b589ec5e2dd6144c001b6f18160c455c4173c86", + "e7188991ad6e59fec51e8788e6761220de16c5f889e3680b31fbc2ef16c3c9d8", + "18c4ef9944da12343cfbb1667336d69ed5b48d9a9d7d5c8fab6f518868b76d65", + "d3b3c9c88e6a15b216aaa826b3c17c21b6baab83183a27b98dafc5937a146bf0", + "6fd5f678f0438ba4fb76fa2ea8179199c6e038ea8c8a8053522b7975d7570d53", + "f53330f4cb4ba6b34e8279ba8699152d783de2fb578edef2c7c890407d6f3628", + "d14c4db00d58d7d7c2800afd66ec9b20d1b157362e0a4e54a14c52b795332016", + "add04b3103713c20a4711fe0374f06452f90386721cb587b385e01a988af0502", + "883066edf85466beee07c05c29fe131ce90815af1624c23c01aa3695c1086c0f", + "3b8d02d36c3810531d9cc891d8b6b39160ef355c75aa3bf484b38324308386c3", + "6e95123ef25d6c655dc98da96b9f97691f228aecd0372ef63a2c318f97c107ea", + "57b61b4ddaf06ac32f74c4381670cc507bb74ce43d238f5a114418ba8881a8fc", + "5b63f717ea400ad75c02512553f564a904292f9abdb6ac8d3ef357988e290954", + "557e32768440b2a9acc159db4ae767bd54c80359fbd48ec16212da33dea0b428", + "f7f25bf9e5f3dde31c7477ec250de55adb7d3d066ecb552da73fa5ad590e20ed", + "03e30519b22a129b7953b46647d08383f8f1159c9a835af119da715f5fffa9ad", + "2a5f118300c531c51dfadded9b136ab89239d61b4965439b85803c88d745256c", + "7e2b54879733bce3337aa9cd4b3039b5383ab97d6187f733ca8479185e16a1de", + "2783f02fb6cc2491b763c99ff20176f470580a14dc860faf56993edb2e2536b8", + "4f35c777e1bde8e544c01fdabda9249e01c0b28dc306ebe5ba1612b64e46f9d0", + "54a4d0ea2784b6e646fddaab1e63e9a9587dff91fb4889587e596d91b0651259", + "3ae450442b2c0a221dc549e4c58b2c296d2baf6f9fd067b2ce236a3c5f2afe13", + "9976de48b89e58629dd94a0ab388851372393ffaaf5cdd06d79d30c9f43a6727", + "7b033bb83c63b614b47039a8cf25e99fe46c1d233da49cdb3bdb1c7aecbb44f5", + "a53f05685c1dcb68a6276c831ad0825410ea16e1075985b8bf2b90dfc7c6e853", + "d305bd6ca6b55879e14d1eeeab1156bee51f9ca0f84405f3f61f3b7ecf907236", + "54bdceb5c9e8779c0ca1eca2c5afa1c2182ab4699d23f38278bca4c5667df77c", + "93ce64278b7aaa5f127d892659d066d82bc6029628cb0c1a055dc5b13fe3dcfb", + "720b1af67f0eaa14f5f5eefda28bfec86f1d716960d88c7e5e204725fa38d0b2", + "8f4f7541ec833a40781a1ccee8d531a4c44b383da4de74ee9b98f153ed2d50f3", + "0b649b3d9811b808f637603d8513a6b36af98ed2f8f17a3dd2a4efcccdee598e", + "5f02c695853ee74f1fd90dc548e5304bf38ea48c13e4b47978ccb69548c94244", + "659e51ee8235b80a35f48e977667552accd30d20b55ea80fbd56764a9b2767ca", + "77a37ed7e94660ada94e901953e911571b8103fec269db145385352408db966e", + "b90a378d5c49c155509c05ba3b6022b21caa2d29709c9ef20df80673d69d0509", + "cdc155e227554b7530fa2f765d6ff252ce59d9a14be0ed38dd803805e0ebe6f8", + "e354d0daef8bbdad461494bf56234e4bbe311f88db676ce8a334ef03fea8513b", + "1f6b931c21d67de6ec12e823d3d5ccb6aace3d92075815c7706a4db1de6c6e7d", + "ea757559e56d8c8d85997313e7e4afb37737079aef79e9cbaeba3cf239fcbe3b", + "31d7c38311f5086352e3236f3a057e22b6322e8ae97786b3e8a190984305a187", + "31cb6bee40657a9a2757d2cf6d8928a82d67ba207ccf9d3c2155e6e147dda8ec", + "dc61cf2048dd58ba54361fa9bcf0dc4e7036c6ba5e0861a6c216d4f7afb85768", + "43b4f2780dc570c8e266b35d055b02607ce9b458df5845bb7f84822f7ecf4366", + "0e43baeef997a5d8e4cd0e8630f4f5038781e0b76c1141874ce0f91fd0d4ee3a", + "682c1971e8f4e1e5ef733e9f9501100de3d6a2f334d7ed4022580a7de7b7f930", + "b28b00671c60a65149b0a176b3284510ea8c53e957019db2b10d2322a508f3a7", + "457ab9d6bb6eb2937b97c1776ab41ac4d37fa6fbb4f85cc1d477e28bab5ef7f6", + "2723b0751796103cf029013f876146822f5c6d4fa49747efae275346ece03a2b", + "0055209bb15a0121c2e788720bdfcaecc6d61e8ea8614d82af265c993c0bd5bd", + "3fdaf8f50a0c8630fe51042730472c90c4275df99dc735c11148a85e95335595", + "929dcca8d2a29bb515b0093e878d2d217c83e117eebface1a695607722db7341", + "0ec42ccd41a66774a141e5dabf05284e3e30117ec1090af8a90162d6299c232d", + "29bdd3ac0cdb53b72fcd2dbcca73ebb311a253f51fea7f284749918cc2332fdd", + "cd5f325dd9714e680bde9aee12b83d12945807c94a1e44db7a733cd363d347dd", + "6d7608029ac861a1e40ad731934b48c84af5347a49e7f6d3ecbd45ab8045366c", + "d6f08e4aa65893b42ea0ecd19fdb6f13980dd05fc73ab1ca2b3b7937f15f0869", + "3ff6cd668748440c9dc693a328167e11649bd0f6b09c38634078042cbb5f1b6b", + "d8c7d6f31e385c8bf57ee6ac72070de8b5ae65eaee8f6d14c999f7f43775f167", + "25142e26db2bc122809aed9e89c940ae002840ba1f6692a750b2f198b76e2445", + "075d51a41a9adbf4112f760a0e4cb1dfea4e08ba4889a79ad287ac8771ca494e", + "8b1aee9ce1c613e4ee5e126592550d935c2e77803a19881bf1877f00e28295ee", + "db861488febf7b32daadc03fb38a1bd2d06bfaa728174b9ed96328166101757b", + "f38fbb64e44cae371a2bc31ccb25dcd0d5d77225ccb43748f903cd65395bd12c", + "09ed53c611faa7920a732502e894f6c8fafbdaf20d9aff5edad16402b479a341", + "5389e9c1e61021013428688be3ec3c8b250246bc5adf81cb1e3dae454d86adf4", + "4c0703df89b6bccca2f0bbdd95231caa75b8e0b0a69c5eba3da83eca23fc9c70", + "72bec27462576085e72b2832737349f85645d6cab0dff408ab7cae51a2947533", + "815af31d525776e7bc77b95b67dbcbc64521eb52123d2580479674f840e8bd8d", + "76e1ea63365da58f10af6ff81c8ede63c81f45e70a66bb38e3510179215fcef4", + "ebe2a2bd1dfc3621cdac827b959a63be737c75c3e0eea447c234e62fb67b2263", + "51cb528593fe3ecc8c9731a252e011a2021a2d7fe32188462395ae3ba802da46", + "b7a98f142289e20ca7f9741f1d0091ac4c270ecc0ba424556a7c6e6285a4975b", + "8a4b0c19e6ea0d17902ced14481a1ca9688dde978a72f3ccc537fd490595c720", + "ee26af625ad5daffd76b44bd97984607173b310235709aff90844b2af1de2bbc", + "40f300700aae394d104430169d6f66a7798f428ce23d8d271ae239f151e8ce90", + "a73deb81cc67a1a56167fc125f6d1c6eb25a7c7f873ca8e2710d5792969b79f0", + "9634bb766c3345e934edcb0b4a2a9ab0246d040c845b48e538aa0bef47f34217", + "fcc6fcfb5c6430033cec158eba7d54f75504aa08cbe377a46ed2bdf64896b851", + "b5553c9ebca0e9d452a045d3e467cd05bbea51602e6bf13b02cc4662b11915b7", + "61a42723cf08c610e49e0eb896dc93c26d990e520ce5bf845565548d2079c7af", + "61cadc7f0919943e11112bc422313ba46c5c44d04e16d41e608180c11d725d0a", + "b96b3c0f03f03ff19a55ff8fd4c6179ec9a08c2392da2da11abe5e82bcfd2372", + "84418c465264331031d08480fa9aabae549089e8fc1f87b80b5cec58d02f2ed3", + "314dc2ce130b6e0db5ea022afee3af2740f503391c63810bf695eebaaac95478", + "737abc04eadbb27b924e66f1cdf4e6274dd740a1c16bf0b4b478b01377c7f9e8", + "fb48f07eb032fe1e5af19d784b39b41527207458619263fc97c39e80e2b9b065", + "88099907c3a8235a43fa2cc48d957d7bed7e89c2e2e2ee4b2c167b231753742b", + "cab950d339ec4206ae64a7153987313009446a200a3fdf67d56ed9cdd52a203c", + "409bbafb3e5b43066478fd3dbac2d77ee9ab7793a7a887d17b1e01f3d5f1dce4", + "12efab84f748d610131898a99f70bc06e239acfc44c055f38743cd2991cef099", + "81eeaaac15d99b1c9c1ebca200190ff8c97eec339ee847a46de71038526c1846", + "656f08e1b6bdef9d60b9ba6feb10a2f29723977b6e6c376cef41319d0a24d47b", + "f1d134865dab04d392f6b9f79bb6f607c148d27b3f81428b13cb95931ccbc8cb", + "5c42f4367c879e7d10b43d17f96cd5af9a8bf75bb81e05857deca42f2c8b5dfa", + "57047ae277ce9619203d2148bbe632d98970166ebbf957a35cdb7b0303f10488", + "b503ac392833495b8d974bbb4b8275ca64ae23f9a5de6798d34501b4815fe0e4", + "31b9d09d15b40650fbfc18d1206cd8a2c5bdac9df8889409267b7ac1d43c1155", + "3ad8bd520b18d6aaabe9dda8c435f7ea4833a5f3c6149ce2dcff3403ceb44684", + "6255065a64296f636e2c39c1d54f5291bb001245bffb74d5d9737433e3f35f40", + "c1951622e2af624eeeac1fcfdc515f4bf356e10a0e42e180439d286a45dd9a52", + "b42ca8a277e9343eb0a164bbcda004b5e500d18e3e9fad39d90670fbd8532c74", + "868fd14107a66801c2588155659750920ecc5a61babdacb6af8109e3bf7098bb", + "dc69d4e7663e0b9a3cf2811a1dae84d0b71be36423e048ea7d219a15099944cd", + "d13a66983dd80af3fbe5fd7704c5813c48852316a799e9919e9508a2c89845cf", + "d244ffa9688203517514b45292b37636495595b6cca5f8c44e47672d6799fc48", + "b76767596bc6e7bbe2416d1fc42ce8f5977c84611d5bfdb4daff243e21de16e9", + "f04190ea11859fb3c59007c64cb56a4c9c1a8c10ae2e89248ac61c774b5cf4fc", + "8cf15c8d7c51089025e8751719228fcad1e543f14d2da767da99067d571facd4", + "35102089f1ef49a2dafb4007993ea6719101f0bc3f54bfbbdda3b812d52ca088", + "1afcb5e2b1e57397c75f3ed0fea7659decabf3c14fb84b71f6ef68892b58dc55", + "afdaba66d7877d1078d2f283fc6704aa9c5518ebad7365c68e867abd8af44616", + "a26645e99561979926f0aab9c98e0ee7a44651e58a0ba067d746260384c31782", + "5fb5630f94afe1facdfe5eddc7b28091312ac29078e89a69aaee824284db9ec5", + "24196107a2e687e1039361b4b9ffc962073e29a9db24795cf02fbc6cc5297c73", + "0316bd6b96155997af0040cfc17b92472dd2402d4d89ce7d7fff98b84d686f77", + "eb25a81c259b92b0c3eba069c4171cb4bff69e4a01213557c9b137095725fcc6", + "4d78fd18a7f73b4949c51de20f0502003f446e89b87bdcebe1459d32c676e997", + "cd1f56728c7db3247ce27e98fa2b9d3fb6eed387a6251f45bed1253e92b10ab7", + "45890cf9d2c73a3872be17a01454003c3dce9264700a5c86d38c5e0cd27eebaa", + "19ea0fa2fce38d5396e5f1cc626d5a5f4154837be5f318d83e7115551fb79468", + "091370d535871702a1953fa110c78bfbc5c1e7f8a0188b17515c38d40a4808b9", + "77a4d11bc1258c0a424f4a92ec8291232182a9abb80b3a66017341d5ea88434d", + "78cfffb9b79cb59c36e2993d9da569b4ac24690d576d311e929083eba65b6860", + "6b65ef1fa870084042283dd2a10fdd5a178857a62420ce2312e6cc86123373ea", + "0e32029e963bc099e0de4f97f6238ca26a3a8c597fef7dacec5a5433fd6c1f89", + "40a3ce142466d096f05ff065981b1899b937fd40fef3c97adb003b4b3171bc8f", + "f3a79087082d680474c20b51c9bf9c5fab9c25a268046b840a1782af2e930966", + "e9f431352523bb806c93a85c3bf0a405a77264bf8288f97c27fbf4e9e78eec90", + "ddb624861b293cde7343e4bbb98b03659c96372cf600b7c0f610e2ca2f975d8e", + "133dd57c6dd52f8fc349604de25d363c87ef949be172b80dd0ccf0783d63821f", + "553ad6e8da8a18e7cc6fc3195c441a264f70df81aabbe47a2ed564dd034d8f8d", + "00647c5d3f1f6c1f2640fc6d0d8ae1fa17654c469ef5c680b8d7426830b13a9a", + "9cac3715a92e9009fcae73f7fdbf75f76908c0719ba0426c5b1709dacf35921f", + "be10fd011a5dd8c3114c9b02514caa03b4c28dcad42e0941e5fecc9d43bf5bcb", + "c6e3585468a898401df0feee8eabee2a30f13b06680a80300f357726d275cfe6", + "d44b6ff000a00ad547666d7beb3a2629488fcedf95dfea83f5334f90c20377d9", + "47bab84efa1121380c27949c9451fc640ab2e6e70ff635f31b330e3e05c7b6ca", + "353807fe1fa0d9e92798e16178115412b6ed40ec1f8a33b4e71ff67b9ea2a0cf", + "ece728212bde1fa396a947a8640275b39788ac677a5ce70e861b705d361e0e29", + "664c3ba27de326df0e841649cd0e61acaf8a3a7ac59e66e2e5ec1ae0080901b6", + "46af5389368223c2c64b00f0303a4f4e27ea6323e1354c687c37b3d31dc5cdc5", + "d6149549963de49b7dab720d5ced147a9fa1fc07230faf871da2d1c5771da7a9", + "76d433948972f78c96c653ed1983bdbacdf80e64a66dbcbed01337540f27c95a", + "4a04fdf27ab93c52ff5f841f34ec47188925955291a91c9f33aa526a0bfd7815", + "a782624628efb3818c36e5eb1ab8b2f0cd635f6e14cb14e844f39a0419dc1972", + "f240914dd903dae5bf6b1d54c44fc58f4f0ddc9a55d0ae04f8ba890531fd1924", + "af72feaa1fed808ec1ec30466a401c296d42f33b53c2ac882f334b48ca85cd63", + "b499c056b8541a7dd9583f7662d0a0a9d4d00779ed667cfe30a2d14b27b53788", + "9ca7916495637ad909cf9947b8bf84b6d1f8b371dd7b15710032ed602455e60d", + "c1bcddf22118ec1477bcd6d3b715e6b5a43156c2d6b27e0f415d89fc234cae1a", + "a35570cc2502a8c51a15c9b5415bd68a9560e2645f9790356692cab14b54c7d1", + "85d72020c67c69d37f26462662d898a6b15e01b19b1767b2ca9c2cb3fc00e6bd", + "2be38b2056d06a7a58dc24f2bd9345b23f3a611d6c14f7767bdf6f817de7b678", + "10f9ef5991e5222b24748f4f90bdafe7796edbce57b46d07501971eb7d13c273", + "59587e1502c50e0694fd57fa61a63d72e3666f60c3a08035f804874651c4fdb3", + "549aa4c620a2d91295c4492ffa1b4a1a626ae3db5b10fd094d1827417a982e25", + "c0ac138266133cfa2f12f2237bf651ee968cb7cbb7ad70ae4dbf33f57d67c671", + "70cca80e3635321146bf4e0ec3eaf9679bdb795afcbfcefc9d36578dc526aad1", + "cdcf20f675690f41fa20811fc17ea895ba3204d9f0ec12af729c75b994067e6c", + "f19de7da55d2e79cf0e3e82dead9b133a7ffe6439af641e220a94fa291499da5", + "6795635f6dde7f94bfc24da2c34a0b674ac27f2cde44470f09932700053312b9", + "f1659e318ea91415c9fb4ad1ccd1a29fc3a7be051abadfa7e228dabdedd5a1f6", + "0e9a4e91947c90b1d5d2ee67188091d29223e450852951b9522dd0084ba65ae4", + "f0409e8fbe86af10fd2bd927e812920eaeaa831db8209b9f8c6dccadc7bd4aab", + "f8fb24e91042f45a86cc5169168fdce7c2f8219b2bff29ff7ce3865dc2da79da", + "fabe978cfa9b7d73b5eab55c01975edf970114792eb2a41617930c910a4e64ca", + "8342ff34897774baf2cc5bc96d28cdffa5d0e583e5df02b50248f8987c4355bc", + "ddded849311583832d96767c9d4f043bb4818dae33e4d675f9c019d8033becb6", + "ce11c5b017a8523e962ce71883d42af458a973608c161ce84404e8aae27fc9c1", + "8584c8dd22fb873b665443eed6375bf6999156637e8af102636370881d456d4a", + "c13ce50cdd3d5fc15aa32586a12eb5861124ea118c09ca9f8a70199575c2ea60", + "1e0e685627b7d4f8f65844a0a54df94d77773e3c62c2cc3ddab38dee209d1928", + "93e7251a72bc1525fe71ecc47aee0245c7d05a374b9901251477d8d133e0cde6", } -const ropstenPreverifiedHeight uint64 = 11620608 +const ropstenPreverifiedHeight uint64 = 11800128 From 5364532947eebc3896e1acc52678451eade206b5 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Wed, 12 Jan 2022 13:17:11 +0000 Subject: [PATCH 087/261] Switch to erigon-lib stable (#3246) Co-authored-by: Alexey Sharp --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 3dbd5c96fe6..dd8dbf5eb44 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20220110123802-994b74cd54de + github.com/ledgerwatch/erigon-lib v0.0.0-20220111081227-d6108f0d081f github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 diff --git a/go.sum b/go.sum index 8fb088951e4..467fa3caa6b 100644 --- a/go.sum +++ b/go.sum @@ -500,8 +500,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20220110123802-994b74cd54de h1:57dTOByuRZCodDGCgo0cQjuG3JsoVBcJftDBt0etgIY= -github.com/ledgerwatch/erigon-lib v0.0.0-20220110123802-994b74cd54de/go.mod h1:RtMyitRZlGyq0k8YVbMIwN/w3iby0zhPfM3tpCoqSUU= +github.com/ledgerwatch/erigon-lib v0.0.0-20220111081227-d6108f0d081f h1:j4cRW+chzRRCW5Uyvf238Ct5ej+gnGBSfj07JcQ9Ixc= +github.com/ledgerwatch/erigon-lib v0.0.0-20220111081227-d6108f0d081f/go.mod h1:RtMyitRZlGyq0k8YVbMIwN/w3iby0zhPfM3tpCoqSUU= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= From 81011f83fb0a786956b5edf6d2de141801471805 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Wed, 12 Jan 2022 19:36:32 -0300 Subject: [PATCH 088/261] Rewrite of the search forward/multi iterator code; fixed many small bugs --- cmd/rpcdaemon/commands/otterscan_api.go | 104 ++++------- cmd/rpcdaemon/commands/otterscan_types.go | 161 ++++++++++++++++++ .../commands/otterscan_types_test.go | 151 ++++++++++++++++ 3 files changed, 342 insertions(+), 74 deletions(-) create mode 100644 cmd/rpcdaemon/commands/otterscan_types.go create mode 100644 cmd/rpcdaemon/commands/otterscan_types_test.go diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index a625b230dbe..af4b24aea31 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -200,7 +200,7 @@ func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr return &TransactionsWithReceipts{txs, receipts, blockNum == 0, eof}, nil } -func newSearchBackIterator(cursor kv.Cursor, addr common.Address, maxBlock uint64) func() (uint64, bool, error) { +func newSearchBackIterator(cursor kv.Cursor, addr common.Address, maxBlock uint64) func() (nextBlock uint64, eof bool, err error) { search := make([]byte, common.AddressLength+8) copy(search[:common.AddressLength], addr.Bytes()) if maxBlock == 0 { @@ -258,6 +258,9 @@ func newSearchBackIterator(cursor kv.Cursor, addr common.Address, maxBlock uint6 } } +// Search transactions that touch a certain address. +// +// It searches forward a certain block (including); the results are sorted descending. func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr common.Address, blockNum uint64, minPageSize uint16) (*TransactionsWithReceipts, error) { dbtx, err := api.db.BeginRo(ctx) if err != nil { @@ -293,9 +296,9 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c if err != nil { return nil, err } - eof := false + hasMore := true for { - if resultCount >= minPageSize || eof { + if resultCount >= minPageSize || !hasMore { break } @@ -304,11 +307,11 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c tot := 0 for i := 0; i < int(minPageSize-resultCount); i++ { var blockNum uint64 - blockNum, eof, err = multiIter() + blockNum, hasMore, err = multiIter() if err != nil { return nil, err } - if eof { + if !hasMore { break } @@ -338,108 +341,61 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c } } - return &TransactionsWithReceipts{txs, receipts, eof, blockNum == 0}, nil + return &TransactionsWithReceipts{txs, receipts, !hasMore, blockNum == 0}, nil } -func newSearchForwardIterator(cursor kv.Cursor, addr common.Address, minBlock uint64) func() (uint64, bool, error) { - search := make([]byte, common.AddressLength+8) - copy(search[:common.AddressLength], addr.Bytes()) - binary.BigEndian.PutUint64(search[common.AddressLength:], minBlock) - - first := true - var iter roaring64.IntIterable64 - - return func() (uint64, bool, error) { - if first { - first = false - k, v, err := cursor.Seek(search) - if err != nil { - return 0, true, err - } - if !bytes.Equal(k[:common.AddressLength], addr.Bytes()) { - return 0, true, nil - } - - bitmap := roaring64.New() - if _, err := bitmap.ReadFrom(bytes.NewReader(v)); err != nil { - return 0, true, err - } - iter = bitmap.Iterator() - } - - var blockNum uint64 - for { - if !iter.HasNext() { - // Try and check next shard - k, v, err := cursor.Next() - if err != nil { - return 0, true, err - } - if !bytes.Equal(k[:common.AddressLength], addr.Bytes()) { - return 0, true, nil - } - - bitmap := roaring64.New() - if _, err := bitmap.ReadFrom(bytes.NewReader(v)); err != nil { - return 0, true, err - } - iter = bitmap.Iterator() - } - blockNum = iter.Next() - - if minBlock == 0 || blockNum > minBlock { - break - } - } - return blockNum, false, nil - } +func newSearchForwardIterator(cursor kv.Cursor, addr common.Address, minBlock uint64) BlockProvider { + chunkLocator := NewForwardChunkLocator(cursor, addr, minBlock) + return NewForwardBlockProvider(chunkLocator, minBlock) } -func newMultiIterator(smaller bool, fromIter func() (uint64, bool, error), toIter func() (uint64, bool, error)) (func() (uint64, bool, error), error) { - nextFrom, fromEnd, err := fromIter() +func newMultiIterator(smaller bool, fromIter, toIter BlockProvider) (BlockProvider, error) { + nextFrom, hasMoreFrom, err := fromIter() if err != nil { return nil, err } - nextTo, toEnd, err := toIter() + nextTo, hasMoreTo, err := toIter() if err != nil { return nil, err } return func() (uint64, bool, error) { - if fromEnd && toEnd { + if !hasMoreFrom && !hasMoreTo { return 0, true, nil } var blockNum uint64 - if !fromEnd { + if !hasMoreFrom { + blockNum = nextTo + } else if !hasMoreTo { + blockNum = nextFrom + } else { blockNum = nextFrom - } - if !toEnd { if smaller { - if nextTo < blockNum { + if nextTo < nextFrom { blockNum = nextTo } } else { - if nextTo > blockNum { + if nextTo > nextFrom { blockNum = nextTo } } } // Pull next; it may be that from AND to contains the same blockNum - if !fromEnd && blockNum == nextFrom { - nextFrom, fromEnd, err = fromIter() + if hasMoreFrom && blockNum == nextFrom { + nextFrom, hasMoreFrom, err = fromIter() if err != nil { - return 0, false, err + return 0, true, err } } - if !toEnd && blockNum == nextTo { - nextTo, toEnd, err = toIter() + if hasMoreTo && blockNum == nextTo { + nextTo, hasMoreTo, err = toIter() if err != nil { - return 0, false, err + return 0, true, err } } - return blockNum, false, nil + return blockNum, hasMoreFrom || hasMoreTo, nil }, nil } diff --git a/cmd/rpcdaemon/commands/otterscan_types.go b/cmd/rpcdaemon/commands/otterscan_types.go new file mode 100644 index 00000000000..374b390df82 --- /dev/null +++ b/cmd/rpcdaemon/commands/otterscan_types.go @@ -0,0 +1,161 @@ +package commands + +import ( + "bytes" + "encoding/binary" + + "github.com/RoaringBitmap/roaring/roaring64" + "github.com/ledgerwatch/erigon-lib/kv" + "github.com/ledgerwatch/erigon/common" +) + +// Bootstrap a function able to locate a series of byte chunks containing +// related block numbers, starting from a specific block number (greater or equal than). +type ChunkLocator func(block uint64) (chunkProvider ChunkProvider, ok bool, err error) + +// Allows to iterate over a set of byte chunks. +// +// If err is not nil, it indicates an error and the other returned values should be +// ignored. +// +// If err is nil and ok is true, the returned chunk should contain the raw chunk data. +// +// If err is nil and ok is false, it indicates that there is no more data. Subsequent calls +// to the same function should return (nil, false, nil). +type ChunkProvider func() (chunk []byte, ok bool, err error) + +type BlockProvider func() (nextBlock uint64, hasMore bool, err error) + +func NewForwardChunkLocator(cursor kv.Cursor, addr common.Address, minBlock uint64) ChunkLocator { + return func(block uint64) (ChunkProvider, bool, error) { + search := make([]byte, common.AddressLength+8) + copy(search[:common.AddressLength], addr.Bytes()) + binary.BigEndian.PutUint64(search[common.AddressLength:], minBlock) + + k, _, err := cursor.Seek(search) + if err != nil { + return nil, false, err + } + + // Exact match? + if bytes.Equal(k, search) { + return NewForwardChunkProvider(cursor, addr, minBlock), true, nil + } + + // It maybe the previous chunk + kp, _, err := cursor.Prev() + if err != nil { + return nil, false, err + } + if !bytes.Equal(kp[:common.AddressLength], addr.Bytes()) { + // It is in the current chunk + _, _, err = cursor.Next() + if err != nil { + return nil, false, err + } + return NewForwardChunkProvider(cursor, addr, minBlock), true, nil + } + + // It is in the previous chunk + return NewForwardChunkProvider(cursor, addr, minBlock), true, nil + } +} + +func NewForwardChunkProvider(cursor kv.Cursor, addr common.Address, minBlock uint64) ChunkProvider { + first := true + var err error + eof := false + return func() ([]byte, bool, error) { + if err != nil { + return nil, false, err + } + if eof { + return nil, false, nil + } + + var k, v []byte + if first { + first = false + k, v, err = cursor.Current() + } else { + k, v, err = cursor.Next() + } + + if err != nil { + eof = true + return nil, false, err + } + if !bytes.Equal(k[:common.AddressLength], addr.Bytes()) { + eof = true + return nil, false, nil + } + return v, true, nil + } +} + +func NewForwardBlockProvider(chunkLocator ChunkLocator, block uint64) BlockProvider { + var iter roaring64.IntPeekable64 + var chunkProvider ChunkProvider + + return func() (uint64, bool, error) { + if chunkProvider == nil { + var ok bool + var err error + chunkProvider, ok, err = chunkLocator(block) + if err != nil { + return 0, false, err + } + if !ok { + return 0, false, nil + } + if chunkProvider == nil { + return 0, false, nil + } + } + + if iter == nil { + chunk, ok, err := chunkProvider() + if err != nil { + return 0, false, err + } + if !ok { + return 0, false, nil + } + + bm := roaring64.NewBitmap() + if _, err := bm.ReadFrom(bytes.NewReader(chunk)); err != nil { + return 0, false, err + } + iter = bm.Iterator() + } + + nextBlock := iter.Next() + hasNext := iter.HasNext() + for { + if nextBlock >= block || !hasNext { + break + } + nextBlock = iter.Next() + hasNext = iter.HasNext() + } + + if !hasNext { + // Check if there is another chunk to get blocks from + chunk, ok, err := chunkProvider() + if err != nil { + return 0, false, err + } + if ok { + hasNext = true + + bm := roaring64.NewBitmap() + if _, err := bm.ReadFrom(bytes.NewReader(chunk)); err != nil { + return 0, false, err + } + iter = bm.Iterator() + } + } + + return nextBlock, hasNext, nil + } +} diff --git a/cmd/rpcdaemon/commands/otterscan_types_test.go b/cmd/rpcdaemon/commands/otterscan_types_test.go new file mode 100644 index 00000000000..eed70309b41 --- /dev/null +++ b/cmd/rpcdaemon/commands/otterscan_types_test.go @@ -0,0 +1,151 @@ +package commands + +import ( + "bytes" + "testing" + + "github.com/RoaringBitmap/roaring/roaring64" +) + +func newMockChunkLocator(chunks [][]byte) ChunkLocator { + return func(block uint64) (ChunkProvider, bool, error) { + for i, v := range chunks { + bm := roaring64.NewBitmap() + if _, err := bm.ReadFrom(bytes.NewReader(v)); err != nil { + return nil, false, err + } + if block > bm.Maximum() { + continue + } + + return newMockChunkProvider(chunks[i:]), true, nil + } + + // Not found + return nil, true, nil + } +} + +func newMockChunkProvider(chunks [][]byte) ChunkProvider { + i := 0 + return func() ([]byte, bool, error) { + if i >= len(chunks) { + return nil, false, nil + } + + chunk := chunks[i] + i++ + return chunk, true, nil + } +} + +func createBitmap(t *testing.T, blocks []uint64) []byte { + bm := roaring64.NewBitmap() + bm.AddMany(blocks) + + chunk, err := bm.ToBytes() + if err != nil { + t.Fatal(err) + } + return chunk +} + +func checkNext(t *testing.T, blockProvider BlockProvider, expectedBlock uint64, expectedHasNext bool) { + bl, hasNext, err := blockProvider() + if err != nil { + t.Fatal(err) + } + if expectedHasNext != hasNext { + t.Fatalf("Expected hasNext=%t, received=%t", expectedHasNext, hasNext) + } + if bl != expectedBlock { + t.Fatalf("Expected block %d, received %d", expectedBlock, bl) + } +} + +func TestForwardBlockProviderWith1Chunk(t *testing.T) { + // Mocks 1 chunk + chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) + + chunkLocator := newMockChunkLocator([][]byte{chunk1}) + blockProvider := NewForwardBlockProvider(chunkLocator, 0) + + checkNext(t, blockProvider, 1000, true) + checkNext(t, blockProvider, 1005, true) + checkNext(t, blockProvider, 1010, false) +} + +func TestForwardBlockProviderWith1ChunkMiddleBlock(t *testing.T) { + // Mocks 1 chunk + chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) + + chunkLocator := newMockChunkLocator([][]byte{chunk1}) + blockProvider := NewForwardBlockProvider(chunkLocator, 1005) + + checkNext(t, blockProvider, 1005, true) + checkNext(t, blockProvider, 1010, false) +} + +func TestForwardBlockProviderWith1ChunkNotExactBlock(t *testing.T) { + // Mocks 1 chunk + chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) + + chunkLocator := newMockChunkLocator([][]byte{chunk1}) + blockProvider := NewForwardBlockProvider(chunkLocator, 1007) + + checkNext(t, blockProvider, 1010, false) +} + +func TestForwardBlockProviderWith1ChunkLastBlock(t *testing.T) { + // Mocks 1 chunk + chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) + + chunkLocator := newMockChunkLocator([][]byte{chunk1}) + blockProvider := NewForwardBlockProvider(chunkLocator, 1010) + + checkNext(t, blockProvider, 1010, false) +} + +func TestForwardBlockProviderWith1ChunkBlockNotFound(t *testing.T) { + // Mocks 1 chunk + chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) + + chunkLocator := newMockChunkLocator([][]byte{chunk1}) + blockProvider := NewForwardBlockProvider(chunkLocator, 1100) + + checkNext(t, blockProvider, 0, false) +} + +func TestForwardBlockProviderWithNoChunks(t *testing.T) { + chunkLocator := newMockChunkLocator([][]byte{}) + blockProvider := NewForwardBlockProvider(chunkLocator, 0) + + checkNext(t, blockProvider, 0, false) +} + +func TestForwardBlockProviderWithMultipleChunks(t *testing.T) { + // Mocks 2 chunks + chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) + chunk2 := createBitmap(t, []uint64{1501, 1600}) + + chunkLocator := newMockChunkLocator([][]byte{chunk1, chunk2}) + blockProvider := NewForwardBlockProvider(chunkLocator, 0) + + checkNext(t, blockProvider, 1000, true) + checkNext(t, blockProvider, 1005, true) + checkNext(t, blockProvider, 1010, true) + checkNext(t, blockProvider, 1501, true) + checkNext(t, blockProvider, 1600, false) +} + +func TestForwardBlockProviderWithMultipleChunksBlockBetweenChunks(t *testing.T) { + // Mocks 2 chunks + chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) + chunk2 := createBitmap(t, []uint64{1501, 1600}) + + chunkLocator := newMockChunkLocator([][]byte{chunk1, chunk2}) + blockProvider := NewForwardBlockProvider(chunkLocator, 1300) + + checkNext(t, blockProvider, 1501, true) + checkNext(t, blockProvider, 1600, false) +} From db56c3341e83c9089c355502f36b6c48cfe3a265 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Wed, 12 Jan 2022 19:42:05 -0300 Subject: [PATCH 089/261] Small code cleanup --- cmd/rpcdaemon/commands/otterscan_types.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_types.go b/cmd/rpcdaemon/commands/otterscan_types.go index 374b390df82..d0d30954106 100644 --- a/cmd/rpcdaemon/commands/otterscan_types.go +++ b/cmd/rpcdaemon/commands/otterscan_types.go @@ -47,7 +47,7 @@ func NewForwardChunkLocator(cursor kv.Cursor, addr common.Address, minBlock uint if err != nil { return nil, false, err } - if !bytes.Equal(kp[:common.AddressLength], addr.Bytes()) { + if !bytes.HasPrefix(kp, addr.Bytes()) { // It is in the current chunk _, _, err = cursor.Next() if err != nil { @@ -85,7 +85,7 @@ func NewForwardChunkProvider(cursor kv.Cursor, addr common.Address, minBlock uin eof = true return nil, false, err } - if !bytes.Equal(k[:common.AddressLength], addr.Bytes()) { + if !bytes.HasPrefix(k, addr.Bytes()) { eof = true return nil, false, nil } From 635402e14342b1bf88bda307704d190253dbc72c Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Wed, 12 Jan 2022 19:48:04 -0300 Subject: [PATCH 090/261] Renames --- cmd/rpcdaemon/commands/otterscan_api.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index af4b24aea31..e445920ea82 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -268,16 +268,17 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c } defer dbtx.Rollback() - fromCursor, err := dbtx.Cursor(kv.CallFromIndex) + callFromCursor, err := dbtx.Cursor(kv.CallFromIndex) if err != nil { return nil, err } - defer fromCursor.Close() - toCursor, err := dbtx.Cursor(kv.CallToIndex) + defer callFromCursor.Close() + + callToCursor, err := dbtx.Cursor(kv.CallToIndex) if err != nil { return nil, err } - defer toCursor.Close() + defer callToCursor.Close() chainConfig, err := api.chainConfig(dbtx) if err != nil { @@ -286,8 +287,8 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c // Initialize search cursors at the first shard >= desired block number resultCount := uint16(0) - fromIter := newSearchForwardIterator(fromCursor, addr, blockNum) - toIter := newSearchForwardIterator(toCursor, addr, blockNum) + fromIter := newSearchForwardIterator(callFromCursor, addr, blockNum) + toIter := newSearchForwardIterator(callToCursor, addr, blockNum) txs := make([]*RPCTransaction, 0) receipts := make([]map[string]interface{}, 0) @@ -350,6 +351,7 @@ func newSearchForwardIterator(cursor kv.Cursor, addr common.Address, minBlock ui } func newMultiIterator(smaller bool, fromIter, toIter BlockProvider) (BlockProvider, error) { + // TODO: move this inside the closure; remove error from sig nextFrom, hasMoreFrom, err := fromIter() if err != nil { return nil, err From adcf01af4010eb95c251a661e5c4af7910617aea Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Wed, 12 Jan 2022 20:15:09 -0300 Subject: [PATCH 091/261] Add docs, make function private, optimize first chunk call --- cmd/rpcdaemon/commands/otterscan_types.go | 29 +++++++++++++---------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_types.go b/cmd/rpcdaemon/commands/otterscan_types.go index d0d30954106..23f91335220 100644 --- a/cmd/rpcdaemon/commands/otterscan_types.go +++ b/cmd/rpcdaemon/commands/otterscan_types.go @@ -26,6 +26,10 @@ type ChunkProvider func() (chunk []byte, ok bool, err error) type BlockProvider func() (nextBlock uint64, hasMore bool, err error) +// This ChunkLocator searches over a cursor with a key format of [common.Address, block uint64], +// where block is the first block number contained in the chunk value. +// +// It positions the cursor on the chunk that contains the first block >= minBlock. func NewForwardChunkLocator(cursor kv.Cursor, addr common.Address, minBlock uint64) ChunkLocator { return func(block uint64) (ChunkProvider, bool, error) { search := make([]byte, common.AddressLength+8) @@ -39,7 +43,7 @@ func NewForwardChunkLocator(cursor kv.Cursor, addr common.Address, minBlock uint // Exact match? if bytes.Equal(k, search) { - return NewForwardChunkProvider(cursor, addr, minBlock), true, nil + return newForwardChunkProvider(cursor, addr, minBlock), true, nil } // It maybe the previous chunk @@ -53,15 +57,17 @@ func NewForwardChunkLocator(cursor kv.Cursor, addr common.Address, minBlock uint if err != nil { return nil, false, err } - return NewForwardChunkProvider(cursor, addr, minBlock), true, nil + return newForwardChunkProvider(cursor, addr, minBlock), true, nil } // It is in the previous chunk - return NewForwardChunkProvider(cursor, addr, minBlock), true, nil + return newForwardChunkProvider(cursor, addr, minBlock), true, nil } } -func NewForwardChunkProvider(cursor kv.Cursor, addr common.Address, minBlock uint64) ChunkProvider { +// This ChunkProvider is built by NewForwardChunkLocator and advances the cursor forward until +// there is no more chunks for the desired addr. +func newForwardChunkProvider(cursor kv.Cursor, addr common.Address, minBlock uint64) ChunkProvider { first := true var err error eof := false @@ -93,6 +99,8 @@ func NewForwardChunkProvider(cursor kv.Cursor, addr common.Address, minBlock uin } } +// Given a ChunkLocator, moves forward over the chunks and inside each chunk, moves +// forward over the block numbers. func NewForwardBlockProvider(chunkLocator ChunkLocator, block uint64) BlockProvider { var iter roaring64.IntPeekable64 var chunkProvider ChunkProvider @@ -127,18 +135,15 @@ func NewForwardBlockProvider(chunkLocator ChunkLocator, block uint64) BlockProvi return 0, false, err } iter = bm.Iterator() + + // It can happen that on the first chunk we'll get a chunk that contains + // the first block >= minBlock in the middle of the chunk/bitmap, so we + // skip all previous blocks before it. + iter.AdvanceIfNeeded(block) } nextBlock := iter.Next() hasNext := iter.HasNext() - for { - if nextBlock >= block || !hasNext { - break - } - nextBlock = iter.Next() - hasNext = iter.HasNext() - } - if !hasNext { // Check if there is another chunk to get blocks from chunk, ok, err := chunkProvider() From abffe406cd304d398487d2235437b26d383ce582 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Thu, 13 Jan 2022 00:56:48 -0300 Subject: [PATCH 092/261] Backwards chunk/block iterator --- cmd/rpcdaemon/commands/otterscan_api.go | 6 +- .../otterscan_search_backward_test.go | 127 ++++++++++++++++++ cmd/rpcdaemon/commands/otterscan_types.go | 73 ++++++++++ .../commands/otterscan_types_test.go | 22 +-- 4 files changed, 216 insertions(+), 12 deletions(-) create mode 100644 cmd/rpcdaemon/commands/otterscan_search_backward_test.go diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index e445920ea82..b95d9c45383 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -117,6 +117,9 @@ func (api *OtterscanAPIImpl) GetInternalOperations(ctx context.Context, hash com return tracer.Results, nil } +// Search transactions that touch a certain address. +// +// It searches back a certain block (including); the results are sorted descending. func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr common.Address, blockNum uint64, minPageSize uint16) (*TransactionsWithReceipts, error) { dbtx, err := api.db.BeginRo(ctx) if err != nil { @@ -200,7 +203,7 @@ func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr return &TransactionsWithReceipts{txs, receipts, blockNum == 0, eof}, nil } -func newSearchBackIterator(cursor kv.Cursor, addr common.Address, maxBlock uint64) func() (nextBlock uint64, eof bool, err error) { +func newSearchBackIterator(cursor kv.Cursor, addr common.Address, maxBlock uint64) BlockProvider { search := make([]byte, common.AddressLength+8) copy(search[:common.AddressLength], addr.Bytes()) if maxBlock == 0 { @@ -227,6 +230,7 @@ func newSearchBackIterator(cursor kv.Cursor, addr common.Address, maxBlock uint6 if _, err := bitmap.ReadFrom(bytes.NewReader(v)); err != nil { return 0, true, err } + bitmap.RemoveRange(maxBlock+1, ^uint64(0)) iter = bitmap.ReverseIterator() } diff --git a/cmd/rpcdaemon/commands/otterscan_search_backward_test.go b/cmd/rpcdaemon/commands/otterscan_search_backward_test.go new file mode 100644 index 00000000000..9f1f456eb79 --- /dev/null +++ b/cmd/rpcdaemon/commands/otterscan_search_backward_test.go @@ -0,0 +1,127 @@ +package commands + +import ( + "bytes" + "testing" + + "github.com/RoaringBitmap/roaring/roaring64" +) + +func newMockBackwardChunkLocator(chunks [][]byte) ChunkLocator { + return func(block uint64) (ChunkProvider, bool, error) { + for i := len(chunks) - 1; i >= 0; i-- { + bm := roaring64.NewBitmap() + if _, err := bm.ReadFrom(bytes.NewReader(chunks[i])); err != nil { + return nil, false, err + } + if block < bm.Minimum() { + continue + } + + return newMockBackwardChunkProvider(chunks[:i+1]), true, nil + } + + // Not found + return nil, true, nil + } +} + +func newMockBackwardChunkProvider(chunks [][]byte) ChunkProvider { + i := len(chunks) - 1 + return func() ([]byte, bool, error) { + if i < 0 { + return nil, false, nil + } + + chunk := chunks[i] + i-- + return chunk, true, nil + } +} +func TestBackwardBlockProviderWith1Chunk(t *testing.T) { + // Mocks 1 chunk + chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) + + chunkLocator := newMockBackwardChunkLocator([][]byte{chunk1}) + blockProvider := NewBackwardBlockProvider(chunkLocator, 0) + + checkNext(t, blockProvider, 1010, true) + checkNext(t, blockProvider, 1005, true) + checkNext(t, blockProvider, 1000, false) +} + +func TestBackwardBlockProviderWith1ChunkMiddleBlock(t *testing.T) { + // Mocks 1 chunk + chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) + + chunkLocator := newMockBackwardChunkLocator([][]byte{chunk1}) + blockProvider := NewBackwardBlockProvider(chunkLocator, 1005) + + checkNext(t, blockProvider, 1005, true) + checkNext(t, blockProvider, 1000, false) +} + +func TestBackwardBlockProviderWith1ChunkNotExactBlock(t *testing.T) { + // Mocks 1 chunk + chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) + + chunkLocator := newMockBackwardChunkLocator([][]byte{chunk1}) + blockProvider := NewBackwardBlockProvider(chunkLocator, 1003) + + checkNext(t, blockProvider, 1000, false) +} + +func TestBackwardBlockProviderWith1ChunkLastBlock(t *testing.T) { + // Mocks 1 chunk + chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) + + chunkLocator := newMockBackwardChunkLocator([][]byte{chunk1}) + blockProvider := NewBackwardBlockProvider(chunkLocator, 1000) + + checkNext(t, blockProvider, 1000, false) +} + +func TestBackwardBlockProviderWith1ChunkBlockNotFound(t *testing.T) { + // Mocks 1 chunk + chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) + + chunkLocator := newMockBackwardChunkLocator([][]byte{chunk1}) + blockProvider := NewBackwardBlockProvider(chunkLocator, 900) + + checkNext(t, blockProvider, 0, false) +} + +func TestBackwardBlockProviderWithNoChunks(t *testing.T) { + chunkLocator := newMockBackwardChunkLocator([][]byte{}) + blockProvider := NewBackwardBlockProvider(chunkLocator, 0) + + checkNext(t, blockProvider, 0, false) +} + +func TestBackwardBlockProviderWithMultipleChunks(t *testing.T) { + // Mocks 2 chunks + chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) + chunk2 := createBitmap(t, []uint64{1501, 1600}) + + chunkLocator := newMockBackwardChunkLocator([][]byte{chunk1, chunk2}) + blockProvider := NewBackwardBlockProvider(chunkLocator, 0) + + checkNext(t, blockProvider, 1600, true) + checkNext(t, blockProvider, 1501, true) + checkNext(t, blockProvider, 1010, true) + checkNext(t, blockProvider, 1005, true) + checkNext(t, blockProvider, 1000, false) +} + +func TestBackwardBlockProviderWithMultipleChunksBlockBetweenChunks(t *testing.T) { + // Mocks 2 chunks + chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) + chunk2 := createBitmap(t, []uint64{1501, 1600}) + + chunkLocator := newMockBackwardChunkLocator([][]byte{chunk1, chunk2}) + blockProvider := NewBackwardBlockProvider(chunkLocator, 1500) + + checkNext(t, blockProvider, 1010, true) + checkNext(t, blockProvider, 1005, true) + checkNext(t, blockProvider, 1000, false) +} diff --git a/cmd/rpcdaemon/commands/otterscan_types.go b/cmd/rpcdaemon/commands/otterscan_types.go index 23f91335220..dd693327fd5 100644 --- a/cmd/rpcdaemon/commands/otterscan_types.go +++ b/cmd/rpcdaemon/commands/otterscan_types.go @@ -164,3 +164,76 @@ func NewForwardBlockProvider(chunkLocator ChunkLocator, block uint64) BlockProvi return nextBlock, hasNext, nil } } + +// Given a ChunkLocator, moves back over the chunks and inside each chunk, moves +// backwards over the block numbers. +func NewBackwardBlockProvider(chunkLocator ChunkLocator, block uint64) BlockProvider { + // block == 0 means no max + if block == 0 { + block = ^uint64(0) + } + var iter roaring64.IntIterable64 + var chunkProvider ChunkProvider + + return func() (uint64, bool, error) { + if chunkProvider == nil { + var ok bool + var err error + chunkProvider, ok, err = chunkLocator(block) + if err != nil { + return 0, false, err + } + if !ok { + return 0, false, nil + } + if chunkProvider == nil { + return 0, false, nil + } + } + + if iter == nil { + chunk, ok, err := chunkProvider() + if err != nil { + return 0, false, err + } + if !ok { + return 0, false, nil + } + + bm := roaring64.NewBitmap() + if _, err := bm.ReadFrom(bytes.NewReader(chunk)); err != nil { + return 0, false, err + } + + // It can happen that on the first chunk we'll get a chunk that contains + // the last block <= maxBlock in the middle of the chunk/bitmap, so we + // remove all blocks after it (since there is no AdvanceIfNeeded() in + // IntIterable64) + if block != ^uint64(0) { + bm.RemoveRange(block+1, ^uint64(0)) + } + iter = bm.ReverseIterator() + } + + nextBlock := iter.Next() + hasNext := iter.HasNext() + if !hasNext { + // Check if there is another chunk to get blocks from + chunk, ok, err := chunkProvider() + if err != nil { + return 0, false, err + } + if ok { + hasNext = true + + bm := roaring64.NewBitmap() + if _, err := bm.ReadFrom(bytes.NewReader(chunk)); err != nil { + return 0, false, err + } + iter = bm.ReverseIterator() + } + } + + return nextBlock, hasNext, nil + } +} diff --git a/cmd/rpcdaemon/commands/otterscan_types_test.go b/cmd/rpcdaemon/commands/otterscan_types_test.go index eed70309b41..3eb10e60a65 100644 --- a/cmd/rpcdaemon/commands/otterscan_types_test.go +++ b/cmd/rpcdaemon/commands/otterscan_types_test.go @@ -7,7 +7,7 @@ import ( "github.com/RoaringBitmap/roaring/roaring64" ) -func newMockChunkLocator(chunks [][]byte) ChunkLocator { +func newMockForwardChunkLocator(chunks [][]byte) ChunkLocator { return func(block uint64) (ChunkProvider, bool, error) { for i, v := range chunks { bm := roaring64.NewBitmap() @@ -18,7 +18,7 @@ func newMockChunkLocator(chunks [][]byte) ChunkLocator { continue } - return newMockChunkProvider(chunks[i:]), true, nil + return newMockForwardChunkProvider(chunks[i:]), true, nil } // Not found @@ -26,7 +26,7 @@ func newMockChunkLocator(chunks [][]byte) ChunkLocator { } } -func newMockChunkProvider(chunks [][]byte) ChunkProvider { +func newMockForwardChunkProvider(chunks [][]byte) ChunkProvider { i := 0 return func() ([]byte, bool, error) { if i >= len(chunks) { @@ -67,7 +67,7 @@ func TestForwardBlockProviderWith1Chunk(t *testing.T) { // Mocks 1 chunk chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) - chunkLocator := newMockChunkLocator([][]byte{chunk1}) + chunkLocator := newMockForwardChunkLocator([][]byte{chunk1}) blockProvider := NewForwardBlockProvider(chunkLocator, 0) checkNext(t, blockProvider, 1000, true) @@ -79,7 +79,7 @@ func TestForwardBlockProviderWith1ChunkMiddleBlock(t *testing.T) { // Mocks 1 chunk chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) - chunkLocator := newMockChunkLocator([][]byte{chunk1}) + chunkLocator := newMockForwardChunkLocator([][]byte{chunk1}) blockProvider := NewForwardBlockProvider(chunkLocator, 1005) checkNext(t, blockProvider, 1005, true) @@ -90,7 +90,7 @@ func TestForwardBlockProviderWith1ChunkNotExactBlock(t *testing.T) { // Mocks 1 chunk chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) - chunkLocator := newMockChunkLocator([][]byte{chunk1}) + chunkLocator := newMockForwardChunkLocator([][]byte{chunk1}) blockProvider := NewForwardBlockProvider(chunkLocator, 1007) checkNext(t, blockProvider, 1010, false) @@ -100,7 +100,7 @@ func TestForwardBlockProviderWith1ChunkLastBlock(t *testing.T) { // Mocks 1 chunk chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) - chunkLocator := newMockChunkLocator([][]byte{chunk1}) + chunkLocator := newMockForwardChunkLocator([][]byte{chunk1}) blockProvider := NewForwardBlockProvider(chunkLocator, 1010) checkNext(t, blockProvider, 1010, false) @@ -110,14 +110,14 @@ func TestForwardBlockProviderWith1ChunkBlockNotFound(t *testing.T) { // Mocks 1 chunk chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) - chunkLocator := newMockChunkLocator([][]byte{chunk1}) + chunkLocator := newMockForwardChunkLocator([][]byte{chunk1}) blockProvider := NewForwardBlockProvider(chunkLocator, 1100) checkNext(t, blockProvider, 0, false) } func TestForwardBlockProviderWithNoChunks(t *testing.T) { - chunkLocator := newMockChunkLocator([][]byte{}) + chunkLocator := newMockForwardChunkLocator([][]byte{}) blockProvider := NewForwardBlockProvider(chunkLocator, 0) checkNext(t, blockProvider, 0, false) @@ -128,7 +128,7 @@ func TestForwardBlockProviderWithMultipleChunks(t *testing.T) { chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) chunk2 := createBitmap(t, []uint64{1501, 1600}) - chunkLocator := newMockChunkLocator([][]byte{chunk1, chunk2}) + chunkLocator := newMockForwardChunkLocator([][]byte{chunk1, chunk2}) blockProvider := NewForwardBlockProvider(chunkLocator, 0) checkNext(t, blockProvider, 1000, true) @@ -143,7 +143,7 @@ func TestForwardBlockProviderWithMultipleChunksBlockBetweenChunks(t *testing.T) chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) chunk2 := createBitmap(t, []uint64{1501, 1600}) - chunkLocator := newMockChunkLocator([][]byte{chunk1, chunk2}) + chunkLocator := newMockForwardChunkLocator([][]byte{chunk1, chunk2}) blockProvider := NewForwardBlockProvider(chunkLocator, 1300) checkNext(t, blockProvider, 1501, true) From a1fae566c5ad99666e98c93b960df130108fac98 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Thu, 13 Jan 2022 00:57:54 -0300 Subject: [PATCH 093/261] Rename --- .../{otterscan_types_test.go => otterscan_search_forward_test.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename cmd/rpcdaemon/commands/{otterscan_types_test.go => otterscan_search_forward_test.go} (100%) diff --git a/cmd/rpcdaemon/commands/otterscan_types_test.go b/cmd/rpcdaemon/commands/otterscan_search_forward_test.go similarity index 100% rename from cmd/rpcdaemon/commands/otterscan_types_test.go rename to cmd/rpcdaemon/commands/otterscan_search_forward_test.go From 0dacd6e4e819336dc973920d6a76a98e00da2ef9 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Thu, 13 Jan 2022 21:43:25 +0700 Subject: [PATCH 094/261] Penalize for invalid rlp (#3242) * save * log * save --- cmd/sentry/download/downloader.go | 11 +++++++++-- rlp/decode.go | 7 +++++-- turbo/txpool/p2p.go | 2 +- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/cmd/sentry/download/downloader.go b/cmd/sentry/download/downloader.go index 827549c0b8e..b534169fd5e 100644 --- a/cmd/sentry/download/downloader.go +++ b/cmd/sentry/download/downloader.go @@ -304,8 +304,15 @@ func RecvMessage( } if err = handleInboundMessage(ctx, req, sentry); err != nil { - if rlp.IsDecodeError(err) { - log.Debug("[RecvMessage] Handling incoming message", "error", err) + if rlp.IsInvalidRLPError(err) { + log.Debug("[RecvMessage] Kick peer for invalid RLP", "error", err) + outreq := proto_sentry.PenalizePeerRequest{ + PeerId: req.PeerId, + Penalty: proto_sentry.PenaltyKind_Kick, // TODO: Extend penalty kinds + } + if _, err1 := sentry.PenalizePeer(ctx, &outreq, &grpc.EmptyCallOption{}); err1 != nil { + log.Error("Could not send penalty", "err", err1) + } } else { log.Warn("[RecvMessage] Handling incoming message", "error", err) } diff --git a/rlp/decode.go b/rlp/decode.go index 1568bb60e1d..df4d3f5a427 100644 --- a/rlp/decode.go +++ b/rlp/decode.go @@ -60,7 +60,7 @@ var ( } ) -func IsDecodeError(err error) bool { +func IsInvalidRLPError(err error) bool { return errors.Is(err, ErrExpectedString) || errors.Is(err, ErrExpectedList) || errors.Is(err, ErrCanonInt) || @@ -70,7 +70,10 @@ func IsDecodeError(err error) bool { errors.Is(err, ErrValueTooLarge) || errors.Is(err, ErrMoreThanOneValue) || errors.Is(err, ErrWrongTxTypePrefix) || - errors.Is(err, ErrUnknownTxTypePrefix) + errors.Is(err, ErrUnknownTxTypePrefix) || + errors.Is(err, errNotInList) || + errors.Is(err, errNotAtEOL) || + errors.Is(err, errUintOverflow) } // Decoder is implemented by types that require custom RLP decoding rules or need to decode diff --git a/turbo/txpool/p2p.go b/turbo/txpool/p2p.go index 4df920bb6d0..c80c07c6850 100644 --- a/turbo/txpool/p2p.go +++ b/turbo/txpool/p2p.go @@ -332,7 +332,7 @@ func RecvTxMessage(ctx context.Context, s, ok := status.FromError(err) doLog := !((ok && s.Code() == codes.Canceled) || errors.Is(err, io.EOF) || errors.Is(err, context.Canceled)) if doLog { - if rlp.IsDecodeError(err) { + if rlp.IsInvalidRLPError(err) { log.Debug("[RecvTxMessage] Handling incoming message", "error", err) } else { log.Warn("[RecvTxMessage] Handling incoming message", "error", err) From 2cc72de4f81eb28ec4e75b156fcf03bdcad1f277 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Thu, 13 Jan 2022 23:46:04 +0700 Subject: [PATCH 095/261] don't interrup stage bodies on first cycle (#3252) --- eth/stagedsync/default_stages.go | 2 +- eth/stagedsync/stage_bodies.go | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/eth/stagedsync/default_stages.go b/eth/stagedsync/default_stages.go index 7f1816c0dbf..ce78c266285 100644 --- a/eth/stagedsync/default_stages.go +++ b/eth/stagedsync/default_stages.go @@ -60,7 +60,7 @@ func DefaultStages(ctx context.Context, ID: stages.Bodies, Description: "Download block bodies", Forward: func(firstCycle bool, badBlockUnwind bool, s *StageState, u Unwinder, tx kv.RwTx) error { - return BodiesForward(s, u, ctx, tx, bodies, test) + return BodiesForward(s, u, ctx, tx, bodies, test, firstCycle) }, Unwind: func(firstCycle bool, u *UnwindState, s *StageState, tx kv.RwTx) error { return UnwindBodiesStage(u, tx, bodies, ctx) diff --git a/eth/stagedsync/stage_bodies.go b/eth/stagedsync/stage_bodies.go index 362d475e659..808d924ebf5 100644 --- a/eth/stagedsync/stage_bodies.go +++ b/eth/stagedsync/stage_bodies.go @@ -52,6 +52,7 @@ func BodiesForward( tx kv.RwTx, cfg BodiesCfg, test bool, // Set to true in tests, allows the stage to fail rather than wait indefinitely + firstCycle bool, ) error { var d1, d2, d3, d4, d5, d6 time.Duration @@ -186,7 +187,7 @@ Loop: stopped = true break } - if s.BlockNumber > 0 && noProgressCount >= 5 { + if !firstCycle && s.BlockNumber > 0 && noProgressCount >= 5 { break } timer.Stop() From d77b68306c21c93d515f821155a2239ef2e21f87 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Thu, 13 Jan 2022 15:56:04 -0300 Subject: [PATCH 096/261] Reimplement search backwards properly --- cmd/rpcdaemon/commands/otterscan_api.go | 88 +++++------------------ cmd/rpcdaemon/commands/otterscan_types.go | 83 +++++++++++++++++++++ 2 files changed, 100 insertions(+), 71 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index b95d9c45383..f1d1fbc1160 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -3,7 +3,6 @@ package commands import ( "bytes" "context" - "encoding/binary" "errors" "fmt" "math/big" @@ -127,16 +126,17 @@ func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr } defer dbtx.Rollback() - fromCursor, err := dbtx.Cursor(kv.CallFromIndex) + callFromCursor, err := dbtx.Cursor(kv.CallFromIndex) if err != nil { return nil, err } - defer fromCursor.Close() - toCursor, err := dbtx.Cursor(kv.CallToIndex) + defer callFromCursor.Close() + + callToCursor, err := dbtx.Cursor(kv.CallToIndex) if err != nil { return nil, err } - defer toCursor.Close() + defer callToCursor.Close() chainConfig, err := api.chainConfig(dbtx) if err != nil { @@ -145,8 +145,8 @@ func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr // Initialize search cursors at the first shard >= desired block number resultCount := uint16(0) - fromIter := newSearchBackIterator(fromCursor, addr, blockNum) - toIter := newSearchBackIterator(toCursor, addr, blockNum) + fromIter := newSearchBackIterator(callFromCursor, addr, blockNum) + toIter := newSearchBackIterator(callToCursor, addr, blockNum) txs := make([]*RPCTransaction, 0) receipts := make([]map[string]interface{}, 0) @@ -155,9 +155,9 @@ func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr if err != nil { return nil, err } - eof := false + hasMore := true for { - if resultCount >= minPageSize || eof { + if resultCount >= minPageSize || !hasMore { break } @@ -166,11 +166,11 @@ func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr tot := 0 for i := 0; i < int(minPageSize-resultCount); i++ { var blockNum uint64 - blockNum, eof, err = multiIter() + blockNum, hasMore, err = multiIter() if err != nil { return nil, err } - if eof { + if !hasMore { break } @@ -200,66 +200,12 @@ func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr } } - return &TransactionsWithReceipts{txs, receipts, blockNum == 0, eof}, nil + return &TransactionsWithReceipts{txs, receipts, blockNum == 0, hasMore}, nil } func newSearchBackIterator(cursor kv.Cursor, addr common.Address, maxBlock uint64) BlockProvider { - search := make([]byte, common.AddressLength+8) - copy(search[:common.AddressLength], addr.Bytes()) - if maxBlock == 0 { - binary.BigEndian.PutUint64(search[common.AddressLength:], ^uint64(0)) - } else { - binary.BigEndian.PutUint64(search[common.AddressLength:], maxBlock) - } - - first := true - var iter roaring64.IntIterable64 - - return func() (uint64, bool, error) { - if first { - first = false - k, v, err := cursor.Seek(search) - if err != nil { - return 0, true, err - } - if !bytes.Equal(k[:common.AddressLength], addr.Bytes()) { - return 0, true, nil - } - - bitmap := roaring64.New() - if _, err := bitmap.ReadFrom(bytes.NewReader(v)); err != nil { - return 0, true, err - } - bitmap.RemoveRange(maxBlock+1, ^uint64(0)) - iter = bitmap.ReverseIterator() - } - - var blockNum uint64 - for { - if !iter.HasNext() { - // Try and check previous shard - k, v, err := cursor.Prev() - if err != nil { - return 0, true, err - } - if !bytes.Equal(k[:common.AddressLength], addr.Bytes()) { - return 0, true, nil - } - - bitmap := roaring64.New() - if _, err := bitmap.ReadFrom(bytes.NewReader(v)); err != nil { - return 0, true, err - } - iter = bitmap.ReverseIterator() - } - blockNum = iter.Next() - - if maxBlock == 0 || blockNum < maxBlock { - break - } - } - return blockNum, false, nil - } + chunkLocator := NewBackwardChunkLocator(cursor, addr, maxBlock) + return NewBackwardBlockProvider(chunkLocator, maxBlock) } // Search transactions that touch a certain address. @@ -367,7 +313,7 @@ func newMultiIterator(smaller bool, fromIter, toIter BlockProvider) (BlockProvid return func() (uint64, bool, error) { if !hasMoreFrom && !hasMoreTo { - return 0, true, nil + return 0, false, nil } var blockNum uint64 @@ -392,13 +338,13 @@ func newMultiIterator(smaller bool, fromIter, toIter BlockProvider) (BlockProvid if hasMoreFrom && blockNum == nextFrom { nextFrom, hasMoreFrom, err = fromIter() if err != nil { - return 0, true, err + return 0, false, err } } if hasMoreTo && blockNum == nextTo { nextTo, hasMoreTo, err = toIter() if err != nil { - return 0, true, err + return 0, false, err } } return blockNum, hasMoreFrom || hasMoreTo, nil diff --git a/cmd/rpcdaemon/commands/otterscan_types.go b/cmd/rpcdaemon/commands/otterscan_types.go index dd693327fd5..891a1f6bd1d 100644 --- a/cmd/rpcdaemon/commands/otterscan_types.go +++ b/cmd/rpcdaemon/commands/otterscan_types.go @@ -31,6 +31,7 @@ type BlockProvider func() (nextBlock uint64, hasMore bool, err error) // // It positions the cursor on the chunk that contains the first block >= minBlock. func NewForwardChunkLocator(cursor kv.Cursor, addr common.Address, minBlock uint64) ChunkLocator { + // TODO: remove minBlock param and replace by block from closure? return func(block uint64) (ChunkProvider, bool, error) { search := make([]byte, common.AddressLength+8) copy(search[:common.AddressLength], addr.Bytes()) @@ -165,6 +166,88 @@ func NewForwardBlockProvider(chunkLocator ChunkLocator, block uint64) BlockProvi } } +// This ChunkLocator searches over a cursor with a key format of [common.Address, block uint64], +// where block is the first block number contained in the chunk value. +// +// It positions the cursor on the chunk that contains the last block <= maxBlock. +func NewBackwardChunkLocator(cursor kv.Cursor, addr common.Address, maxBlock uint64) ChunkLocator { + // block == 0 means no max, search for last address chunk (0xffff...) + if maxBlock == 0 { + maxBlock = ^uint64(0) + } + + // TODO: remove maxBlock param and replace by block from closure? + return func(block uint64) (ChunkProvider, bool, error) { + search := make([]byte, common.AddressLength+8) + copy(search[:common.AddressLength], addr.Bytes()) + binary.BigEndian.PutUint64(search[common.AddressLength:], maxBlock) + + k, _, err := cursor.Seek(search) + if err != nil { + return nil, false, err + } + + // If the addr prefix is different it means there is not even the last + // chunk (0xffff...), so this address has no call index + if !bytes.HasPrefix(k, addr.Bytes()) { + return nil, false, nil + } + + // Exact match? + if bytes.Equal(k, search) { + return newBackwardChunkProvider(cursor, addr, maxBlock), true, nil + } + + // If we reached the last addr's chunk (0xffff...), it may contain desired blocks + binary.BigEndian.PutUint64(search[common.AddressLength:], ^uint64(0)) + if bytes.Equal(k, search) { + return newBackwardChunkProvider(cursor, addr, maxBlock), true, nil + } + + // It maybe the previous chunk; position it over the previous, but let the prefix to be + // checked in the ChunkProvider (peek + prefix check) + _, _, err = cursor.Prev() + if err != nil { + return nil, false, err + } + return newBackwardChunkProvider(cursor, addr, maxBlock), true, nil + } +} + +// This ChunkProvider is built by NewBackwardChunkLocator and advances the cursor backwards until +// there is no more chunks for the desired addr. +func newBackwardChunkProvider(cursor kv.Cursor, addr common.Address, minBlock uint64) ChunkProvider { + first := true + var err error + eof := false + return func() ([]byte, bool, error) { + if err != nil { + return nil, false, err + } + if eof { + return nil, false, nil + } + + var k, v []byte + if first { + first = false + k, v, err = cursor.Current() + } else { + k, v, err = cursor.Prev() + } + + if err != nil { + eof = true + return nil, false, err + } + if !bytes.HasPrefix(k, addr.Bytes()) { + eof = true + return nil, false, nil + } + return v, true, nil + } +} + // Given a ChunkLocator, moves back over the chunks and inside each chunk, moves // backwards over the block numbers. func NewBackwardBlockProvider(chunkLocator ChunkLocator, block uint64) BlockProvider { From eece4676d9f08679bec8c5b67c2f0d8bbea0746a Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Thu, 13 Jan 2022 17:10:36 -0300 Subject: [PATCH 097/261] Fix last page detection --- cmd/rpcdaemon/commands/otterscan_api.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index f1d1fbc1160..7e369f35544 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -200,7 +200,7 @@ func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr } } - return &TransactionsWithReceipts{txs, receipts, blockNum == 0, hasMore}, nil + return &TransactionsWithReceipts{txs, receipts, blockNum == 0, !hasMore}, nil } func newSearchBackIterator(cursor kv.Cursor, addr common.Address, maxBlock uint64) BlockProvider { From 447bbc85238f2a97f59dfd86f6aa4a167e6f0f56 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Thu, 13 Jan 2022 17:29:12 -0300 Subject: [PATCH 098/261] Code split --- cmd/rpcdaemon/commands/otterscan_api.go | 69 +--- .../commands/otterscan_search_backward.go | 170 ++++++++++ .../commands/otterscan_search_forward.go | 155 +++++++++ .../commands/otterscan_search_multi.go | 52 +++ cmd/rpcdaemon/commands/otterscan_types.go | 304 ------------------ 5 files changed, 381 insertions(+), 369 deletions(-) create mode 100644 cmd/rpcdaemon/commands/otterscan_search_backward.go create mode 100644 cmd/rpcdaemon/commands/otterscan_search_forward.go create mode 100644 cmd/rpcdaemon/commands/otterscan_search_multi.go diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 7e369f35544..c4298a64516 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -145,8 +145,8 @@ func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr // Initialize search cursors at the first shard >= desired block number resultCount := uint16(0) - fromIter := newSearchBackIterator(callFromCursor, addr, blockNum) - toIter := newSearchBackIterator(callToCursor, addr, blockNum) + fromIter := NewSearchBackIterator(callFromCursor, addr, blockNum) + toIter := NewSearchBackIterator(callToCursor, addr, blockNum) txs := make([]*RPCTransaction, 0) receipts := make([]map[string]interface{}, 0) @@ -203,11 +203,6 @@ func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr return &TransactionsWithReceipts{txs, receipts, blockNum == 0, !hasMore}, nil } -func newSearchBackIterator(cursor kv.Cursor, addr common.Address, maxBlock uint64) BlockProvider { - chunkLocator := NewBackwardChunkLocator(cursor, addr, maxBlock) - return NewBackwardBlockProvider(chunkLocator, maxBlock) -} - // Search transactions that touch a certain address. // // It searches forward a certain block (including); the results are sorted descending. @@ -237,8 +232,8 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c // Initialize search cursors at the first shard >= desired block number resultCount := uint16(0) - fromIter := newSearchForwardIterator(callFromCursor, addr, blockNum) - toIter := newSearchForwardIterator(callToCursor, addr, blockNum) + fromIter := NewSearchForwardIterator(callFromCursor, addr, blockNum) + toIter := NewSearchForwardIterator(callToCursor, addr, blockNum) txs := make([]*RPCTransaction, 0) receipts := make([]map[string]interface{}, 0) @@ -295,62 +290,6 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c return &TransactionsWithReceipts{txs, receipts, !hasMore, blockNum == 0}, nil } -func newSearchForwardIterator(cursor kv.Cursor, addr common.Address, minBlock uint64) BlockProvider { - chunkLocator := NewForwardChunkLocator(cursor, addr, minBlock) - return NewForwardBlockProvider(chunkLocator, minBlock) -} - -func newMultiIterator(smaller bool, fromIter, toIter BlockProvider) (BlockProvider, error) { - // TODO: move this inside the closure; remove error from sig - nextFrom, hasMoreFrom, err := fromIter() - if err != nil { - return nil, err - } - nextTo, hasMoreTo, err := toIter() - if err != nil { - return nil, err - } - - return func() (uint64, bool, error) { - if !hasMoreFrom && !hasMoreTo { - return 0, false, nil - } - - var blockNum uint64 - if !hasMoreFrom { - blockNum = nextTo - } else if !hasMoreTo { - blockNum = nextFrom - } else { - blockNum = nextFrom - if smaller { - if nextTo < nextFrom { - blockNum = nextTo - } - } else { - if nextTo > nextFrom { - blockNum = nextTo - } - } - } - - // Pull next; it may be that from AND to contains the same blockNum - if hasMoreFrom && blockNum == nextFrom { - nextFrom, hasMoreFrom, err = fromIter() - if err != nil { - return 0, false, err - } - } - if hasMoreTo && blockNum == nextTo { - nextTo, hasMoreTo, err = toIter() - if err != nil { - return 0, false, err - } - } - return blockNum, hasMoreFrom || hasMoreTo, nil - }, nil -} - func (api *OtterscanAPIImpl) traceOneBlock(ctx context.Context, wg *sync.WaitGroup, addr common.Address, chainConfig *params.ChainConfig, idx int, bNum uint64, results []*TransactionsWithReceipts) { defer wg.Done() diff --git a/cmd/rpcdaemon/commands/otterscan_search_backward.go b/cmd/rpcdaemon/commands/otterscan_search_backward.go new file mode 100644 index 00000000000..affa683c506 --- /dev/null +++ b/cmd/rpcdaemon/commands/otterscan_search_backward.go @@ -0,0 +1,170 @@ +package commands + +import ( + "bytes" + "encoding/binary" + + "github.com/RoaringBitmap/roaring/roaring64" + "github.com/ledgerwatch/erigon-lib/kv" + "github.com/ledgerwatch/erigon/common" +) + +// This ChunkLocator searches over a cursor with a key format of [common.Address, block uint64], +// where block is the first block number contained in the chunk value. +// +// It positions the cursor on the chunk that contains the last block <= maxBlock. +func newBackwardChunkLocator(cursor kv.Cursor, addr common.Address, maxBlock uint64) ChunkLocator { + // block == 0 means no max, search for last address chunk (0xffff...) + if maxBlock == 0 { + maxBlock = ^uint64(0) + } + + // TODO: remove maxBlock param and replace by block from closure? + return func(block uint64) (ChunkProvider, bool, error) { + search := make([]byte, common.AddressLength+8) + copy(search[:common.AddressLength], addr.Bytes()) + binary.BigEndian.PutUint64(search[common.AddressLength:], maxBlock) + + k, _, err := cursor.Seek(search) + if err != nil { + return nil, false, err + } + + // If the addr prefix is different it means there is not even the last + // chunk (0xffff...), so this address has no call index + if !bytes.HasPrefix(k, addr.Bytes()) { + return nil, false, nil + } + + // Exact match? + if bytes.Equal(k, search) { + return newBackwardChunkProvider(cursor, addr, maxBlock), true, nil + } + + // If we reached the last addr's chunk (0xffff...), it may contain desired blocks + binary.BigEndian.PutUint64(search[common.AddressLength:], ^uint64(0)) + if bytes.Equal(k, search) { + return newBackwardChunkProvider(cursor, addr, maxBlock), true, nil + } + + // It maybe the previous chunk; position it over the previous, but let the prefix to be + // checked in the ChunkProvider (peek + prefix check) + _, _, err = cursor.Prev() + if err != nil { + return nil, false, err + } + return newBackwardChunkProvider(cursor, addr, maxBlock), true, nil + } +} + +// This ChunkProvider is built by NewBackwardChunkLocator and advances the cursor backwards until +// there is no more chunks for the desired addr. +func newBackwardChunkProvider(cursor kv.Cursor, addr common.Address, minBlock uint64) ChunkProvider { + first := true + var err error + eof := false + return func() ([]byte, bool, error) { + if err != nil { + return nil, false, err + } + if eof { + return nil, false, nil + } + + var k, v []byte + if first { + first = false + k, v, err = cursor.Current() + } else { + k, v, err = cursor.Prev() + } + + if err != nil { + eof = true + return nil, false, err + } + if !bytes.HasPrefix(k, addr.Bytes()) { + eof = true + return nil, false, nil + } + return v, true, nil + } +} + +// Given a ChunkLocator, moves back over the chunks and inside each chunk, moves +// backwards over the block numbers. +func NewBackwardBlockProvider(chunkLocator ChunkLocator, block uint64) BlockProvider { + // block == 0 means no max + if block == 0 { + block = ^uint64(0) + } + var iter roaring64.IntIterable64 + var chunkProvider ChunkProvider + + return func() (uint64, bool, error) { + if chunkProvider == nil { + var ok bool + var err error + chunkProvider, ok, err = chunkLocator(block) + if err != nil { + return 0, false, err + } + if !ok { + return 0, false, nil + } + if chunkProvider == nil { + return 0, false, nil + } + } + + if iter == nil { + chunk, ok, err := chunkProvider() + if err != nil { + return 0, false, err + } + if !ok { + return 0, false, nil + } + + bm := roaring64.NewBitmap() + if _, err := bm.ReadFrom(bytes.NewReader(chunk)); err != nil { + return 0, false, err + } + + // It can happen that on the first chunk we'll get a chunk that contains + // the last block <= maxBlock in the middle of the chunk/bitmap, so we + // remove all blocks after it (since there is no AdvanceIfNeeded() in + // IntIterable64) + if block != ^uint64(0) { + bm.RemoveRange(block+1, ^uint64(0)) + } + iter = bm.ReverseIterator() + } + + nextBlock := iter.Next() + hasNext := iter.HasNext() + if !hasNext { + // Check if there is another chunk to get blocks from + chunk, ok, err := chunkProvider() + if err != nil { + return 0, false, err + } + if ok { + hasNext = true + + bm := roaring64.NewBitmap() + if _, err := bm.ReadFrom(bytes.NewReader(chunk)); err != nil { + return 0, false, err + } + iter = bm.ReverseIterator() + } + } + + return nextBlock, hasNext, nil + } +} + +func NewSearchBackIterator(cursor kv.Cursor, addr common.Address, maxBlock uint64) BlockProvider { + chunkLocator := newBackwardChunkLocator(cursor, addr, maxBlock) + return NewBackwardBlockProvider(chunkLocator, maxBlock) +} diff --git a/cmd/rpcdaemon/commands/otterscan_search_forward.go b/cmd/rpcdaemon/commands/otterscan_search_forward.go new file mode 100644 index 00000000000..ed291dc32d8 --- /dev/null +++ b/cmd/rpcdaemon/commands/otterscan_search_forward.go @@ -0,0 +1,155 @@ +package commands + +import ( + "bytes" + "encoding/binary" + + "github.com/RoaringBitmap/roaring/roaring64" + "github.com/ledgerwatch/erigon-lib/kv" + "github.com/ledgerwatch/erigon/common" +) + +// This ChunkLocator searches over a cursor with a key format of [common.Address, block uint64], +// where block is the first block number contained in the chunk value. +// +// It positions the cursor on the chunk that contains the first block >= minBlock. +func newForwardChunkLocator(cursor kv.Cursor, addr common.Address, minBlock uint64) ChunkLocator { + // TODO: remove minBlock param and replace by block from closure? + return func(block uint64) (ChunkProvider, bool, error) { + search := make([]byte, common.AddressLength+8) + copy(search[:common.AddressLength], addr.Bytes()) + binary.BigEndian.PutUint64(search[common.AddressLength:], minBlock) + + k, _, err := cursor.Seek(search) + if err != nil { + return nil, false, err + } + + // Exact match? + if bytes.Equal(k, search) { + return newForwardChunkProvider(cursor, addr, minBlock), true, nil + } + + // It maybe the previous chunk + kp, _, err := cursor.Prev() + if err != nil { + return nil, false, err + } + if !bytes.HasPrefix(kp, addr.Bytes()) { + // It is in the current chunk + _, _, err = cursor.Next() + if err != nil { + return nil, false, err + } + return newForwardChunkProvider(cursor, addr, minBlock), true, nil + } + + // It is in the previous chunk + return newForwardChunkProvider(cursor, addr, minBlock), true, nil + } +} + +// This ChunkProvider is built by NewForwardChunkLocator and advances the cursor forward until +// there is no more chunks for the desired addr. +func newForwardChunkProvider(cursor kv.Cursor, addr common.Address, minBlock uint64) ChunkProvider { + first := true + var err error + eof := false + return func() ([]byte, bool, error) { + if err != nil { + return nil, false, err + } + if eof { + return nil, false, nil + } + + var k, v []byte + if first { + first = false + k, v, err = cursor.Current() + } else { + k, v, err = cursor.Next() + } + + if err != nil { + eof = true + return nil, false, err + } + if !bytes.HasPrefix(k, addr.Bytes()) { + eof = true + return nil, false, nil + } + return v, true, nil + } +} + +// Given a ChunkLocator, moves forward over the chunks and inside each chunk, moves +// forward over the block numbers. +func NewForwardBlockProvider(chunkLocator ChunkLocator, block uint64) BlockProvider { + var iter roaring64.IntPeekable64 + var chunkProvider ChunkProvider + + return func() (uint64, bool, error) { + if chunkProvider == nil { + var ok bool + var err error + chunkProvider, ok, err = chunkLocator(block) + if err != nil { + return 0, false, err + } + if !ok { + return 0, false, nil + } + if chunkProvider == nil { + return 0, false, nil + } + } + + if iter == nil { + chunk, ok, err := chunkProvider() + if err != nil { + return 0, false, err + } + if !ok { + return 0, false, nil + } + + bm := roaring64.NewBitmap() + if _, err := bm.ReadFrom(bytes.NewReader(chunk)); err != nil { + return 0, false, err + } + iter = bm.Iterator() + + // It can happen that on the first chunk we'll get a chunk that contains + // the first block >= minBlock in the middle of the chunk/bitmap, so we + // skip all previous blocks before it. + iter.AdvanceIfNeeded(block) + } + + nextBlock := iter.Next() + hasNext := iter.HasNext() + if !hasNext { + // Check if there is another chunk to get blocks from + chunk, ok, err := chunkProvider() + if err != nil { + return 0, false, err + } + if ok { + hasNext = true + + bm := roaring64.NewBitmap() + if _, err := bm.ReadFrom(bytes.NewReader(chunk)); err != nil { + return 0, false, err + } + iter = bm.Iterator() + } + } + + return nextBlock, hasNext, nil + } +} + +func NewSearchForwardIterator(cursor kv.Cursor, addr common.Address, minBlock uint64) BlockProvider { + chunkLocator := newForwardChunkLocator(cursor, addr, minBlock) + return NewForwardBlockProvider(chunkLocator, minBlock) +} diff --git a/cmd/rpcdaemon/commands/otterscan_search_multi.go b/cmd/rpcdaemon/commands/otterscan_search_multi.go new file mode 100644 index 00000000000..b2eab3dda34 --- /dev/null +++ b/cmd/rpcdaemon/commands/otterscan_search_multi.go @@ -0,0 +1,52 @@ +package commands + +func newMultiIterator(smaller bool, fromIter, toIter BlockProvider) (BlockProvider, error) { + // TODO: move this inside the closure; remove error from sig + nextFrom, hasMoreFrom, err := fromIter() + if err != nil { + return nil, err + } + nextTo, hasMoreTo, err := toIter() + if err != nil { + return nil, err + } + + return func() (uint64, bool, error) { + if !hasMoreFrom && !hasMoreTo { + return 0, false, nil + } + + var blockNum uint64 + if !hasMoreFrom { + blockNum = nextTo + } else if !hasMoreTo { + blockNum = nextFrom + } else { + blockNum = nextFrom + if smaller { + if nextTo < nextFrom { + blockNum = nextTo + } + } else { + if nextTo > nextFrom { + blockNum = nextTo + } + } + } + + // Pull next; it may be that from AND to contains the same blockNum + if hasMoreFrom && blockNum == nextFrom { + nextFrom, hasMoreFrom, err = fromIter() + if err != nil { + return 0, false, err + } + } + if hasMoreTo && blockNum == nextTo { + nextTo, hasMoreTo, err = toIter() + if err != nil { + return 0, false, err + } + } + return blockNum, hasMoreFrom || hasMoreTo, nil + }, nil +} diff --git a/cmd/rpcdaemon/commands/otterscan_types.go b/cmd/rpcdaemon/commands/otterscan_types.go index 891a1f6bd1d..2a61a2f2342 100644 --- a/cmd/rpcdaemon/commands/otterscan_types.go +++ b/cmd/rpcdaemon/commands/otterscan_types.go @@ -1,14 +1,5 @@ package commands -import ( - "bytes" - "encoding/binary" - - "github.com/RoaringBitmap/roaring/roaring64" - "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/erigon/common" -) - // Bootstrap a function able to locate a series of byte chunks containing // related block numbers, starting from a specific block number (greater or equal than). type ChunkLocator func(block uint64) (chunkProvider ChunkProvider, ok bool, err error) @@ -25,298 +16,3 @@ type ChunkLocator func(block uint64) (chunkProvider ChunkProvider, ok bool, err type ChunkProvider func() (chunk []byte, ok bool, err error) type BlockProvider func() (nextBlock uint64, hasMore bool, err error) - -// This ChunkLocator searches over a cursor with a key format of [common.Address, block uint64], -// where block is the first block number contained in the chunk value. -// -// It positions the cursor on the chunk that contains the first block >= minBlock. -func NewForwardChunkLocator(cursor kv.Cursor, addr common.Address, minBlock uint64) ChunkLocator { - // TODO: remove minBlock param and replace by block from closure? - return func(block uint64) (ChunkProvider, bool, error) { - search := make([]byte, common.AddressLength+8) - copy(search[:common.AddressLength], addr.Bytes()) - binary.BigEndian.PutUint64(search[common.AddressLength:], minBlock) - - k, _, err := cursor.Seek(search) - if err != nil { - return nil, false, err - } - - // Exact match? - if bytes.Equal(k, search) { - return newForwardChunkProvider(cursor, addr, minBlock), true, nil - } - - // It maybe the previous chunk - kp, _, err := cursor.Prev() - if err != nil { - return nil, false, err - } - if !bytes.HasPrefix(kp, addr.Bytes()) { - // It is in the current chunk - _, _, err = cursor.Next() - if err != nil { - return nil, false, err - } - return newForwardChunkProvider(cursor, addr, minBlock), true, nil - } - - // It is in the previous chunk - return newForwardChunkProvider(cursor, addr, minBlock), true, nil - } -} - -// This ChunkProvider is built by NewForwardChunkLocator and advances the cursor forward until -// there is no more chunks for the desired addr. -func newForwardChunkProvider(cursor kv.Cursor, addr common.Address, minBlock uint64) ChunkProvider { - first := true - var err error - eof := false - return func() ([]byte, bool, error) { - if err != nil { - return nil, false, err - } - if eof { - return nil, false, nil - } - - var k, v []byte - if first { - first = false - k, v, err = cursor.Current() - } else { - k, v, err = cursor.Next() - } - - if err != nil { - eof = true - return nil, false, err - } - if !bytes.HasPrefix(k, addr.Bytes()) { - eof = true - return nil, false, nil - } - return v, true, nil - } -} - -// Given a ChunkLocator, moves forward over the chunks and inside each chunk, moves -// forward over the block numbers. -func NewForwardBlockProvider(chunkLocator ChunkLocator, block uint64) BlockProvider { - var iter roaring64.IntPeekable64 - var chunkProvider ChunkProvider - - return func() (uint64, bool, error) { - if chunkProvider == nil { - var ok bool - var err error - chunkProvider, ok, err = chunkLocator(block) - if err != nil { - return 0, false, err - } - if !ok { - return 0, false, nil - } - if chunkProvider == nil { - return 0, false, nil - } - } - - if iter == nil { - chunk, ok, err := chunkProvider() - if err != nil { - return 0, false, err - } - if !ok { - return 0, false, nil - } - - bm := roaring64.NewBitmap() - if _, err := bm.ReadFrom(bytes.NewReader(chunk)); err != nil { - return 0, false, err - } - iter = bm.Iterator() - - // It can happen that on the first chunk we'll get a chunk that contains - // the first block >= minBlock in the middle of the chunk/bitmap, so we - // skip all previous blocks before it. - iter.AdvanceIfNeeded(block) - } - - nextBlock := iter.Next() - hasNext := iter.HasNext() - if !hasNext { - // Check if there is another chunk to get blocks from - chunk, ok, err := chunkProvider() - if err != nil { - return 0, false, err - } - if ok { - hasNext = true - - bm := roaring64.NewBitmap() - if _, err := bm.ReadFrom(bytes.NewReader(chunk)); err != nil { - return 0, false, err - } - iter = bm.Iterator() - } - } - - return nextBlock, hasNext, nil - } -} - -// This ChunkLocator searches over a cursor with a key format of [common.Address, block uint64], -// where block is the first block number contained in the chunk value. -// -// It positions the cursor on the chunk that contains the last block <= maxBlock. -func NewBackwardChunkLocator(cursor kv.Cursor, addr common.Address, maxBlock uint64) ChunkLocator { - // block == 0 means no max, search for last address chunk (0xffff...) - if maxBlock == 0 { - maxBlock = ^uint64(0) - } - - // TODO: remove maxBlock param and replace by block from closure? - return func(block uint64) (ChunkProvider, bool, error) { - search := make([]byte, common.AddressLength+8) - copy(search[:common.AddressLength], addr.Bytes()) - binary.BigEndian.PutUint64(search[common.AddressLength:], maxBlock) - - k, _, err := cursor.Seek(search) - if err != nil { - return nil, false, err - } - - // If the addr prefix is different it means there is not even the last - // chunk (0xffff...), so this address has no call index - if !bytes.HasPrefix(k, addr.Bytes()) { - return nil, false, nil - } - - // Exact match? - if bytes.Equal(k, search) { - return newBackwardChunkProvider(cursor, addr, maxBlock), true, nil - } - - // If we reached the last addr's chunk (0xffff...), it may contain desired blocks - binary.BigEndian.PutUint64(search[common.AddressLength:], ^uint64(0)) - if bytes.Equal(k, search) { - return newBackwardChunkProvider(cursor, addr, maxBlock), true, nil - } - - // It maybe the previous chunk; position it over the previous, but let the prefix to be - // checked in the ChunkProvider (peek + prefix check) - _, _, err = cursor.Prev() - if err != nil { - return nil, false, err - } - return newBackwardChunkProvider(cursor, addr, maxBlock), true, nil - } -} - -// This ChunkProvider is built by NewBackwardChunkLocator and advances the cursor backwards until -// there is no more chunks for the desired addr. -func newBackwardChunkProvider(cursor kv.Cursor, addr common.Address, minBlock uint64) ChunkProvider { - first := true - var err error - eof := false - return func() ([]byte, bool, error) { - if err != nil { - return nil, false, err - } - if eof { - return nil, false, nil - } - - var k, v []byte - if first { - first = false - k, v, err = cursor.Current() - } else { - k, v, err = cursor.Prev() - } - - if err != nil { - eof = true - return nil, false, err - } - if !bytes.HasPrefix(k, addr.Bytes()) { - eof = true - return nil, false, nil - } - return v, true, nil - } -} - -// Given a ChunkLocator, moves back over the chunks and inside each chunk, moves -// backwards over the block numbers. -func NewBackwardBlockProvider(chunkLocator ChunkLocator, block uint64) BlockProvider { - // block == 0 means no max - if block == 0 { - block = ^uint64(0) - } - var iter roaring64.IntIterable64 - var chunkProvider ChunkProvider - - return func() (uint64, bool, error) { - if chunkProvider == nil { - var ok bool - var err error - chunkProvider, ok, err = chunkLocator(block) - if err != nil { - return 0, false, err - } - if !ok { - return 0, false, nil - } - if chunkProvider == nil { - return 0, false, nil - } - } - - if iter == nil { - chunk, ok, err := chunkProvider() - if err != nil { - return 0, false, err - } - if !ok { - return 0, false, nil - } - - bm := roaring64.NewBitmap() - if _, err := bm.ReadFrom(bytes.NewReader(chunk)); err != nil { - return 0, false, err - } - - // It can happen that on the first chunk we'll get a chunk that contains - // the last block <= maxBlock in the middle of the chunk/bitmap, so we - // remove all blocks after it (since there is no AdvanceIfNeeded() in - // IntIterable64) - if block != ^uint64(0) { - bm.RemoveRange(block+1, ^uint64(0)) - } - iter = bm.ReverseIterator() - } - - nextBlock := iter.Next() - hasNext := iter.HasNext() - if !hasNext { - // Check if there is another chunk to get blocks from - chunk, ok, err := chunkProvider() - if err != nil { - return 0, false, err - } - if ok { - hasNext = true - - bm := roaring64.NewBitmap() - if _, err := bm.ReadFrom(bytes.NewReader(chunk)); err != nil { - return 0, false, err - } - iter = bm.ReverseIterator() - } - } - - return nextBlock, hasNext, nil - } -} From 1447ec1a375291a60d96ee78262f26f4423a4b67 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Thu, 13 Jan 2022 17:44:13 -0300 Subject: [PATCH 099/261] Code simplification --- .../commands/otterscan_search_backward.go | 18 ++++++------------ .../commands/otterscan_search_forward.go | 13 ++++++------- 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_search_backward.go b/cmd/rpcdaemon/commands/otterscan_search_backward.go index affa683c506..3e371654d9d 100644 --- a/cmd/rpcdaemon/commands/otterscan_search_backward.go +++ b/cmd/rpcdaemon/commands/otterscan_search_backward.go @@ -13,17 +13,11 @@ import ( // where block is the first block number contained in the chunk value. // // It positions the cursor on the chunk that contains the last block <= maxBlock. -func newBackwardChunkLocator(cursor kv.Cursor, addr common.Address, maxBlock uint64) ChunkLocator { - // block == 0 means no max, search for last address chunk (0xffff...) - if maxBlock == 0 { - maxBlock = ^uint64(0) - } - - // TODO: remove maxBlock param and replace by block from closure? +func newBackwardChunkLocator(cursor kv.Cursor, addr common.Address) ChunkLocator { return func(block uint64) (ChunkProvider, bool, error) { search := make([]byte, common.AddressLength+8) copy(search[:common.AddressLength], addr.Bytes()) - binary.BigEndian.PutUint64(search[common.AddressLength:], maxBlock) + binary.BigEndian.PutUint64(search[common.AddressLength:], block) k, _, err := cursor.Seek(search) if err != nil { @@ -38,13 +32,13 @@ func newBackwardChunkLocator(cursor kv.Cursor, addr common.Address, maxBlock uin // Exact match? if bytes.Equal(k, search) { - return newBackwardChunkProvider(cursor, addr, maxBlock), true, nil + return newBackwardChunkProvider(cursor, addr, block), true, nil } // If we reached the last addr's chunk (0xffff...), it may contain desired blocks binary.BigEndian.PutUint64(search[common.AddressLength:], ^uint64(0)) if bytes.Equal(k, search) { - return newBackwardChunkProvider(cursor, addr, maxBlock), true, nil + return newBackwardChunkProvider(cursor, addr, block), true, nil } // It maybe the previous chunk; position it over the previous, but let the prefix to be @@ -53,7 +47,7 @@ func newBackwardChunkLocator(cursor kv.Cursor, addr common.Address, maxBlock uin if err != nil { return nil, false, err } - return newBackwardChunkProvider(cursor, addr, maxBlock), true, nil + return newBackwardChunkProvider(cursor, addr, block), true, nil } } @@ -165,6 +159,6 @@ func NewBackwardBlockProvider(chunkLocator ChunkLocator, block uint64) BlockProv } func NewSearchBackIterator(cursor kv.Cursor, addr common.Address, maxBlock uint64) BlockProvider { - chunkLocator := newBackwardChunkLocator(cursor, addr, maxBlock) + chunkLocator := newBackwardChunkLocator(cursor, addr) return NewBackwardBlockProvider(chunkLocator, maxBlock) } diff --git a/cmd/rpcdaemon/commands/otterscan_search_forward.go b/cmd/rpcdaemon/commands/otterscan_search_forward.go index ed291dc32d8..b724006c41a 100644 --- a/cmd/rpcdaemon/commands/otterscan_search_forward.go +++ b/cmd/rpcdaemon/commands/otterscan_search_forward.go @@ -13,12 +13,11 @@ import ( // where block is the first block number contained in the chunk value. // // It positions the cursor on the chunk that contains the first block >= minBlock. -func newForwardChunkLocator(cursor kv.Cursor, addr common.Address, minBlock uint64) ChunkLocator { - // TODO: remove minBlock param and replace by block from closure? +func newForwardChunkLocator(cursor kv.Cursor, addr common.Address) ChunkLocator { return func(block uint64) (ChunkProvider, bool, error) { search := make([]byte, common.AddressLength+8) copy(search[:common.AddressLength], addr.Bytes()) - binary.BigEndian.PutUint64(search[common.AddressLength:], minBlock) + binary.BigEndian.PutUint64(search[common.AddressLength:], block) k, _, err := cursor.Seek(search) if err != nil { @@ -27,7 +26,7 @@ func newForwardChunkLocator(cursor kv.Cursor, addr common.Address, minBlock uint // Exact match? if bytes.Equal(k, search) { - return newForwardChunkProvider(cursor, addr, minBlock), true, nil + return newForwardChunkProvider(cursor, addr, block), true, nil } // It maybe the previous chunk @@ -41,11 +40,11 @@ func newForwardChunkLocator(cursor kv.Cursor, addr common.Address, minBlock uint if err != nil { return nil, false, err } - return newForwardChunkProvider(cursor, addr, minBlock), true, nil + return newForwardChunkProvider(cursor, addr, block), true, nil } // It is in the previous chunk - return newForwardChunkProvider(cursor, addr, minBlock), true, nil + return newForwardChunkProvider(cursor, addr, block), true, nil } } @@ -150,6 +149,6 @@ func NewForwardBlockProvider(chunkLocator ChunkLocator, block uint64) BlockProvi } func NewSearchForwardIterator(cursor kv.Cursor, addr common.Address, minBlock uint64) BlockProvider { - chunkLocator := newForwardChunkLocator(cursor, addr, minBlock) + chunkLocator := newForwardChunkLocator(cursor, addr) return NewForwardBlockProvider(chunkLocator, minBlock) } From 3315171a22fe6235aa515549a3944d76e2df1b7b Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Thu, 13 Jan 2022 18:04:43 -0300 Subject: [PATCH 100/261] Extract key maker; magic number --- .../commands/otterscan_search_backward.go | 21 ++++++++----------- .../commands/otterscan_search_forward.go | 10 +++------ cmd/rpcdaemon/commands/otterscan_types.go | 15 +++++++++++++ 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_search_backward.go b/cmd/rpcdaemon/commands/otterscan_search_backward.go index 3e371654d9d..4f22c401179 100644 --- a/cmd/rpcdaemon/commands/otterscan_search_backward.go +++ b/cmd/rpcdaemon/commands/otterscan_search_backward.go @@ -2,7 +2,6 @@ package commands import ( "bytes" - "encoding/binary" "github.com/RoaringBitmap/roaring/roaring64" "github.com/ledgerwatch/erigon-lib/kv" @@ -15,11 +14,8 @@ import ( // It positions the cursor on the chunk that contains the last block <= maxBlock. func newBackwardChunkLocator(cursor kv.Cursor, addr common.Address) ChunkLocator { return func(block uint64) (ChunkProvider, bool, error) { - search := make([]byte, common.AddressLength+8) - copy(search[:common.AddressLength], addr.Bytes()) - binary.BigEndian.PutUint64(search[common.AddressLength:], block) - - k, _, err := cursor.Seek(search) + searchKey := callIndexKey(addr, block) + k, _, err := cursor.Seek(searchKey) if err != nil { return nil, false, err } @@ -31,13 +27,13 @@ func newBackwardChunkLocator(cursor kv.Cursor, addr common.Address) ChunkLocator } // Exact match? - if bytes.Equal(k, search) { + if bytes.Equal(k, searchKey) { return newBackwardChunkProvider(cursor, addr, block), true, nil } // If we reached the last addr's chunk (0xffff...), it may contain desired blocks - binary.BigEndian.PutUint64(search[common.AddressLength:], ^uint64(0)) - if bytes.Equal(k, search) { + lastAddrKey := callIndexKey(addr, MaxBlockNum) + if bytes.Equal(k, lastAddrKey) { return newBackwardChunkProvider(cursor, addr, block), true, nil } @@ -90,7 +86,7 @@ func newBackwardChunkProvider(cursor kv.Cursor, addr common.Address, minBlock ui func NewBackwardBlockProvider(chunkLocator ChunkLocator, block uint64) BlockProvider { // block == 0 means no max if block == 0 { - block = ^uint64(0) + block = MaxBlockNum } var iter roaring64.IntIterable64 var chunkProvider ChunkProvider @@ -129,8 +125,9 @@ func NewBackwardBlockProvider(chunkLocator ChunkLocator, block uint64) BlockProv // the last block <= maxBlock in the middle of the chunk/bitmap, so we // remove all blocks after it (since there is no AdvanceIfNeeded() in // IntIterable64) - if block != ^uint64(0) { - bm.RemoveRange(block+1, ^uint64(0)) + if block != MaxBlockNum { + bm.RemoveRange(block+1, MaxBlockNum) + bm.Remove(MaxBlockNum) // because RemoveRange is [start, end) } iter = bm.ReverseIterator() } diff --git a/cmd/rpcdaemon/commands/otterscan_search_forward.go b/cmd/rpcdaemon/commands/otterscan_search_forward.go index b724006c41a..bde6604ce07 100644 --- a/cmd/rpcdaemon/commands/otterscan_search_forward.go +++ b/cmd/rpcdaemon/commands/otterscan_search_forward.go @@ -2,7 +2,6 @@ package commands import ( "bytes" - "encoding/binary" "github.com/RoaringBitmap/roaring/roaring64" "github.com/ledgerwatch/erigon-lib/kv" @@ -15,17 +14,14 @@ import ( // It positions the cursor on the chunk that contains the first block >= minBlock. func newForwardChunkLocator(cursor kv.Cursor, addr common.Address) ChunkLocator { return func(block uint64) (ChunkProvider, bool, error) { - search := make([]byte, common.AddressLength+8) - copy(search[:common.AddressLength], addr.Bytes()) - binary.BigEndian.PutUint64(search[common.AddressLength:], block) - - k, _, err := cursor.Seek(search) + searchKey := callIndexKey(addr, block) + k, _, err := cursor.Seek(searchKey) if err != nil { return nil, false, err } // Exact match? - if bytes.Equal(k, search) { + if bytes.Equal(k, searchKey) { return newForwardChunkProvider(cursor, addr, block), true, nil } diff --git a/cmd/rpcdaemon/commands/otterscan_types.go b/cmd/rpcdaemon/commands/otterscan_types.go index 2a61a2f2342..88a3b10d754 100644 --- a/cmd/rpcdaemon/commands/otterscan_types.go +++ b/cmd/rpcdaemon/commands/otterscan_types.go @@ -1,5 +1,11 @@ package commands +import ( + "encoding/binary" + + "github.com/ledgerwatch/erigon/common" +) + // Bootstrap a function able to locate a series of byte chunks containing // related block numbers, starting from a specific block number (greater or equal than). type ChunkLocator func(block uint64) (chunkProvider ChunkProvider, ok bool, err error) @@ -16,3 +22,12 @@ type ChunkLocator func(block uint64) (chunkProvider ChunkProvider, ok bool, err type ChunkProvider func() (chunk []byte, ok bool, err error) type BlockProvider func() (nextBlock uint64, hasMore bool, err error) + +func callIndexKey(addr common.Address, block uint64) []byte { + key := make([]byte, common.AddressLength+8) + copy(key[:common.AddressLength], addr.Bytes()) + binary.BigEndian.PutUint64(key[common.AddressLength:], block) + return key +} + +const MaxBlockNum = ^uint64(0) From 7459ac7e44785ca0f2e8713aea8714aa9a1ae006 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Thu, 13 Jan 2022 18:06:40 -0300 Subject: [PATCH 101/261] Undo wrong check --- cmd/rpcdaemon/commands/otterscan_search_backward.go | 1 - 1 file changed, 1 deletion(-) diff --git a/cmd/rpcdaemon/commands/otterscan_search_backward.go b/cmd/rpcdaemon/commands/otterscan_search_backward.go index 4f22c401179..b81b3d79f32 100644 --- a/cmd/rpcdaemon/commands/otterscan_search_backward.go +++ b/cmd/rpcdaemon/commands/otterscan_search_backward.go @@ -127,7 +127,6 @@ func NewBackwardBlockProvider(chunkLocator ChunkLocator, block uint64) BlockProv // IntIterable64) if block != MaxBlockNum { bm.RemoveRange(block+1, MaxBlockNum) - bm.Remove(MaxBlockNum) // because RemoveRange is [start, end) } iter = bm.ReverseIterator() } From 86ec56c20efd8b42f4f3199b5491e3547bd34c9e Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Thu, 13 Jan 2022 18:27:54 -0300 Subject: [PATCH 102/261] Split files --- cmd/rpcdaemon/commands/otterscan_api.go | 90 +-------------- .../commands/otterscan_search_trace.go | 103 ++++++++++++++++++ 2 files changed, 105 insertions(+), 88 deletions(-) create mode 100644 cmd/rpcdaemon/commands/otterscan_search_trace.go diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index c4298a64516..5b9880a2747 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -18,7 +18,6 @@ import ( "github.com/ledgerwatch/erigon/consensus/ethash" "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/core/rawdb" - "github.com/ledgerwatch/erigon/core/state" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/types/accounts" "github.com/ledgerwatch/erigon/core/vm" @@ -29,9 +28,7 @@ import ( "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/adapter" "github.com/ledgerwatch/erigon/turbo/rpchelper" - "github.com/ledgerwatch/erigon/turbo/shards" "github.com/ledgerwatch/erigon/turbo/transactions" - "github.com/ledgerwatch/log/v3" ) // API_LEVEL Must be incremented every time new additions are made @@ -176,7 +173,7 @@ func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr wg.Add(1) tot++ - go api.traceOneBlock(ctx, &wg, addr, chainConfig, i, blockNum, results) + go api.searchTraceBlock(ctx, &wg, addr, chainConfig, i, blockNum, results) } wg.Wait() @@ -263,7 +260,7 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c wg.Add(1) tot++ - go api.traceOneBlock(ctx, &wg, addr, chainConfig, i, blockNum, results) + go api.searchTraceBlock(ctx, &wg, addr, chainConfig, i, blockNum, results) } wg.Wait() @@ -290,89 +287,6 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c return &TransactionsWithReceipts{txs, receipts, !hasMore, blockNum == 0}, nil } -func (api *OtterscanAPIImpl) traceOneBlock(ctx context.Context, wg *sync.WaitGroup, addr common.Address, chainConfig *params.ChainConfig, idx int, bNum uint64, results []*TransactionsWithReceipts) { - defer wg.Done() - - // Trace block for Txs - newdbtx, err := api.db.BeginRo(ctx) - if err != nil { - log.Error("ERR", "err", err) - // TODO: signal error - results[idx] = nil - } - defer newdbtx.Rollback() - - _, result, err := api.traceBlock(newdbtx, ctx, bNum, addr, chainConfig) - if err != nil { - // TODO: signal error - log.Error("ERR", "err", err) - results[idx] = nil - //return nil, err - } - results[idx] = result -} - -func (api *OtterscanAPIImpl) traceBlock(dbtx kv.Tx, ctx context.Context, blockNum uint64, searchAddr common.Address, chainConfig *params.ChainConfig) (bool, *TransactionsWithReceipts, error) { - rpcTxs := make([]*RPCTransaction, 0) - receipts := make([]map[string]interface{}, 0) - - // Retrieve the transaction and assemble its EVM context - blockHash, err := rawdb.ReadCanonicalHash(dbtx, blockNum) - if err != nil { - return false, nil, err - } - - block, senders, err := rawdb.ReadBlockWithSenders(dbtx, blockHash, blockNum) - if err != nil { - return false, nil, err - } - - reader := state.NewPlainState(dbtx, blockNum-1) - stateCache := shards.NewStateCache(32, 0 /* no limit */) - cachedReader := state.NewCachedReader(reader, stateCache) - noop := state.NewNoopWriter() - cachedWriter := state.NewCachedWriter(noop, stateCache) - - ibs := state.New(cachedReader) - signer := types.MakeSigner(chainConfig, blockNum) - - getHeader := func(hash common.Hash, number uint64) *types.Header { - return rawdb.ReadHeader(dbtx, hash, number) - } - engine := ethash.NewFaker() - checkTEVM := ethdb.GetHasTEVM(dbtx) - - blockReceipts := rawdb.ReadReceipts(dbtx, block, senders) - header := block.Header() - found := false - for idx, tx := range block.Transactions() { - ibs.Prepare(tx.Hash(), block.Hash(), idx) - - msg, _ := tx.AsMessage(*signer, header.BaseFee) - - tracer := otterscan.NewTouchTracer(searchAddr) - BlockContext := core.NewEVMBlockContext(header, getHeader, engine, nil, checkTEVM) - TxContext := core.NewEVMTxContext(msg) - - vmenv := vm.NewEVM(BlockContext, TxContext, ibs, chainConfig, vm.Config{Debug: true, Tracer: tracer}) - if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.GetGas()), true /* refunds */, false /* gasBailout */); err != nil { - return false, nil, err - } - _ = ibs.FinalizeTx(vmenv.ChainConfig().Rules(block.NumberU64()), cachedWriter) - - if tracer.Found { - rpcTx := newRPCTransaction(tx, block.Hash(), blockNum, uint64(idx), block.BaseFee()) - mReceipt := marshalReceipt(blockReceipts[idx], tx, chainConfig, block) - mReceipt["timestamp"] = block.Time() - rpcTxs = append(rpcTxs, rpcTx) - receipts = append(receipts, mReceipt) - found = true - } - } - - return found, &TransactionsWithReceipts{rpcTxs, receipts, false, false}, nil -} - func (api *OtterscanAPIImpl) delegateGetBlockByNumber(tx kv.Tx, b *types.Block, number rpc.BlockNumber, inclTx bool) (map[string]interface{}, error) { td, err := rawdb.ReadTd(tx, b.Hash(), b.NumberU64()) if err != nil { diff --git a/cmd/rpcdaemon/commands/otterscan_search_trace.go b/cmd/rpcdaemon/commands/otterscan_search_trace.go new file mode 100644 index 00000000000..bdc3b43b63e --- /dev/null +++ b/cmd/rpcdaemon/commands/otterscan_search_trace.go @@ -0,0 +1,103 @@ +package commands + +import ( + "context" + "sync" + + "github.com/ledgerwatch/erigon-lib/kv" + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/consensus/ethash" + "github.com/ledgerwatch/erigon/core" + "github.com/ledgerwatch/erigon/core/rawdb" + "github.com/ledgerwatch/erigon/core/state" + "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/core/vm" + "github.com/ledgerwatch/erigon/ethdb" + otterscan "github.com/ledgerwatch/erigon/otterscan/transactions" + "github.com/ledgerwatch/erigon/params" + "github.com/ledgerwatch/erigon/turbo/shards" + "github.com/ledgerwatch/log/v3" +) + +func (api *OtterscanAPIImpl) searchTraceBlock(ctx context.Context, wg *sync.WaitGroup, addr common.Address, chainConfig *params.ChainConfig, idx int, bNum uint64, results []*TransactionsWithReceipts) { + defer wg.Done() + + // Trace block for Txs + newdbtx, err := api.db.BeginRo(ctx) + if err != nil { + log.Error("ERR", "err", err) + // TODO: signal error + results[idx] = nil + } + defer newdbtx.Rollback() + + _, result, err := api.traceBlock(newdbtx, ctx, bNum, addr, chainConfig) + if err != nil { + // TODO: signal error + log.Error("ERR", "err", err) + results[idx] = nil + //return nil, err + } + results[idx] = result +} + +func (api *OtterscanAPIImpl) traceBlock(dbtx kv.Tx, ctx context.Context, blockNum uint64, searchAddr common.Address, chainConfig *params.ChainConfig) (bool, *TransactionsWithReceipts, error) { + rpcTxs := make([]*RPCTransaction, 0) + receipts := make([]map[string]interface{}, 0) + + // Retrieve the transaction and assemble its EVM context + blockHash, err := rawdb.ReadCanonicalHash(dbtx, blockNum) + if err != nil { + return false, nil, err + } + + block, senders, err := rawdb.ReadBlockWithSenders(dbtx, blockHash, blockNum) + if err != nil { + return false, nil, err + } + + reader := state.NewPlainState(dbtx, blockNum-1) + stateCache := shards.NewStateCache(32, 0 /* no limit */) + cachedReader := state.NewCachedReader(reader, stateCache) + noop := state.NewNoopWriter() + cachedWriter := state.NewCachedWriter(noop, stateCache) + + ibs := state.New(cachedReader) + signer := types.MakeSigner(chainConfig, blockNum) + + getHeader := func(hash common.Hash, number uint64) *types.Header { + return rawdb.ReadHeader(dbtx, hash, number) + } + engine := ethash.NewFaker() + checkTEVM := ethdb.GetHasTEVM(dbtx) + + blockReceipts := rawdb.ReadReceipts(dbtx, block, senders) + header := block.Header() + found := false + for idx, tx := range block.Transactions() { + ibs.Prepare(tx.Hash(), block.Hash(), idx) + + msg, _ := tx.AsMessage(*signer, header.BaseFee) + + tracer := otterscan.NewTouchTracer(searchAddr) + BlockContext := core.NewEVMBlockContext(header, getHeader, engine, nil, checkTEVM) + TxContext := core.NewEVMTxContext(msg) + + vmenv := vm.NewEVM(BlockContext, TxContext, ibs, chainConfig, vm.Config{Debug: true, Tracer: tracer}) + if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.GetGas()), true /* refunds */, false /* gasBailout */); err != nil { + return false, nil, err + } + _ = ibs.FinalizeTx(vmenv.ChainConfig().Rules(block.NumberU64()), cachedWriter) + + if tracer.Found { + rpcTx := newRPCTransaction(tx, block.Hash(), blockNum, uint64(idx), block.BaseFee()) + mReceipt := marshalReceipt(blockReceipts[idx], tx, chainConfig, block) + mReceipt["timestamp"] = block.Time() + rpcTxs = append(rpcTxs, rpcTx) + receipts = append(receipts, mReceipt) + found = true + } + } + + return found, &TransactionsWithReceipts{rpcTxs, receipts, false, false}, nil +} From 674057fc95ec6efd826aef73db8c8f07c2db1626 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Thu, 13 Jan 2022 19:02:41 -0300 Subject: [PATCH 103/261] Small refactorings --- cmd/rpcdaemon/commands/otterscan_api.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 5b9880a2747..3ff598317ce 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -141,17 +141,17 @@ func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr } // Initialize search cursors at the first shard >= desired block number - resultCount := uint16(0) fromIter := NewSearchBackIterator(callFromCursor, addr, blockNum) toIter := NewSearchBackIterator(callToCursor, addr, blockNum) - - txs := make([]*RPCTransaction, 0) - receipts := make([]map[string]interface{}, 0) - multiIter, err := newMultiIterator(false, fromIter, toIter) if err != nil { return nil, err } + + txs := make([]*RPCTransaction, 0) + receipts := make([]map[string]interface{}, 0) + + resultCount := uint16(0) hasMore := true for { if resultCount >= minPageSize || !hasMore { @@ -159,11 +159,11 @@ func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr } var wg sync.WaitGroup - results := make([]*TransactionsWithReceipts, 100) tot := 0 - for i := 0; i < int(minPageSize-resultCount); i++ { - var blockNum uint64 - blockNum, hasMore, err = multiIter() + blocks2Trace := minPageSize - resultCount + results := make([]*TransactionsWithReceipts, blocks2Trace) + for i := 0; i < int(blocks2Trace); i++ { + nextBlock, hasMore, err := multiIter() if err != nil { return nil, err } @@ -173,7 +173,7 @@ func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr wg.Add(1) tot++ - go api.searchTraceBlock(ctx, &wg, addr, chainConfig, i, blockNum, results) + go api.searchTraceBlock(ctx, &wg, addr, chainConfig, i, nextBlock, results) } wg.Wait() From 93adec48edd64608e3c6c7b88895cd8854d79cc8 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Fri, 14 Jan 2022 19:55:38 +0700 Subject: [PATCH 104/261] Revert "increase body download timeout (#3217) (#3237)" (#3260) This reverts commit 4aca7e85e8e6fad353d5070218b96b1d76b78df2. --- eth/backend.go | 2 +- eth/ethconfig/config.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/eth/backend.go b/eth/backend.go index ca985716541..f5ce41ea819 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -309,7 +309,7 @@ func New(stack *node.Node, config *ethconfig.Config, logger log.Logger) (*Ethere if err != nil { return nil, err } - config.BodyDownloadTimeoutSeconds = 60 + config.BodyDownloadTimeoutSeconds = 30 var txPoolRPC txpool_proto.TxpoolServer var miningRPC txpool_proto.MiningServer diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index ccd2ea565b6..c3186024cba 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -86,7 +86,7 @@ var Defaults = Config{ GPO: FullNodeGPO, RPCTxFeeCap: 1, // 1 ether - BodyDownloadTimeoutSeconds: 60, + BodyDownloadTimeoutSeconds: 30, } func init() { From 0481849a00c750daee5ee6a364b7f81b4bb44428 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Fri, 14 Jan 2022 21:23:52 -0300 Subject: [PATCH 105/261] Fix variable hidinh/infinite loop --- cmd/rpcdaemon/commands/otterscan_api.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 3ff598317ce..e780ce59516 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -163,7 +163,8 @@ func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr blocks2Trace := minPageSize - resultCount results := make([]*TransactionsWithReceipts, blocks2Trace) for i := 0; i < int(blocks2Trace); i++ { - nextBlock, hasMore, err := multiIter() + var nextBlock uint64 + nextBlock, hasMore, err = multiIter() if err != nil { return nil, err } @@ -249,8 +250,8 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c results := make([]*TransactionsWithReceipts, 100) tot := 0 for i := 0; i < int(minPageSize-resultCount); i++ { - var blockNum uint64 - blockNum, hasMore, err = multiIter() + var nextBlock uint64 + nextBlock, hasMore, err = multiIter() if err != nil { return nil, err } @@ -260,7 +261,7 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c wg.Add(1) tot++ - go api.searchTraceBlock(ctx, &wg, addr, chainConfig, i, blockNum, results) + go api.searchTraceBlock(ctx, &wg, addr, chainConfig, i, nextBlock, results) } wg.Wait() From 384e47d76a221d50f8794f8d3ffb8a183edb6100 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Fri, 14 Jan 2022 21:49:11 -0300 Subject: [PATCH 106/261] Extract common logic; simplify --- cmd/rpcdaemon/commands/otterscan_api.go | 75 ++++++++++++------------- 1 file changed, 36 insertions(+), 39 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index e780ce59516..e4abbc0907e 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -158,28 +158,13 @@ func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr break } - var wg sync.WaitGroup - tot := 0 - blocks2Trace := minPageSize - resultCount - results := make([]*TransactionsWithReceipts, blocks2Trace) - for i := 0; i < int(blocks2Trace); i++ { - var nextBlock uint64 - nextBlock, hasMore, err = multiIter() - if err != nil { - return nil, err - } - if !hasMore { - break - } - - wg.Add(1) - tot++ - go api.searchTraceBlock(ctx, &wg, addr, chainConfig, i, nextBlock, results) + var results []*TransactionsWithReceipts + results, hasMore, err = api.traceBlocks(ctx, addr, chainConfig, minPageSize, resultCount, hasMore, multiIter) + if err != nil { + return nil, err } - wg.Wait() - for i := 0; i < tot; i++ { - r := results[i] + for _, r := range results { if r == nil { return nil, errors.New("XXXX") } @@ -246,27 +231,13 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c break } - var wg sync.WaitGroup - results := make([]*TransactionsWithReceipts, 100) - tot := 0 - for i := 0; i < int(minPageSize-resultCount); i++ { - var nextBlock uint64 - nextBlock, hasMore, err = multiIter() - if err != nil { - return nil, err - } - if !hasMore { - break - } - - wg.Add(1) - tot++ - go api.searchTraceBlock(ctx, &wg, addr, chainConfig, i, nextBlock, results) + var results []*TransactionsWithReceipts + results, hasMore, err = api.traceBlocks(ctx, addr, chainConfig, minPageSize, resultCount, hasMore, multiIter) + if err != nil { + return nil, err } - wg.Wait() - for i := 0; i < tot; i++ { - r := results[i] + for _, r := range results { if r == nil { return nil, errors.New("XXXX") } @@ -288,6 +259,32 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c return &TransactionsWithReceipts{txs, receipts, !hasMore, blockNum == 0}, nil } +func (api *OtterscanAPIImpl) traceBlocks(ctx context.Context, addr common.Address, chainConfig *params.ChainConfig, minPageSize, resultCount uint16, hasMore bool, multiIter BlockProvider) ([]*TransactionsWithReceipts, bool, error) { + var wg sync.WaitGroup + + tot := 0 + blocks2Trace := minPageSize - resultCount + results := make([]*TransactionsWithReceipts, blocks2Trace) + for i := 0; i < int(blocks2Trace); i++ { + var nextBlock uint64 + var err error + nextBlock, hasMore, err = multiIter() + if err != nil { + return nil, false, err + } + if !hasMore { + break + } + + wg.Add(1) + tot++ + go api.searchTraceBlock(ctx, &wg, addr, chainConfig, i, nextBlock, results) + } + wg.Wait() + + return results[:tot], hasMore, nil +} + func (api *OtterscanAPIImpl) delegateGetBlockByNumber(tx kv.Tx, b *types.Block, number rpc.BlockNumber, inclTx bool) (map[string]interface{}, error) { td, err := rawdb.ReadTd(tx, b.Hash(), b.NumberU64()) if err != nil { From 0f6ad7086617fab17bdec8c618d01b1085986317 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Fri, 14 Jan 2022 21:56:24 -0300 Subject: [PATCH 107/261] Renames, remove unnecessary params/returns --- cmd/rpcdaemon/commands/otterscan_api.go | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index e4abbc0907e..0ab3147d0e0 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -159,7 +159,7 @@ func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr } var results []*TransactionsWithReceipts - results, hasMore, err = api.traceBlocks(ctx, addr, chainConfig, minPageSize, resultCount, hasMore, multiIter) + results, hasMore, err = api.traceBlocks(ctx, addr, chainConfig, minPageSize, resultCount, multiIter) if err != nil { return nil, err } @@ -232,7 +232,7 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c } var results []*TransactionsWithReceipts - results, hasMore, err = api.traceBlocks(ctx, addr, chainConfig, minPageSize, resultCount, hasMore, multiIter) + results, hasMore, err = api.traceBlocks(ctx, addr, chainConfig, minPageSize, resultCount, multiIter) if err != nil { return nil, err } @@ -250,7 +250,7 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c receipts = append([]map[string]interface{}{v}, receipts...) } - if resultCount > minPageSize { + if resultCount >= minPageSize { break } } @@ -259,13 +259,15 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c return &TransactionsWithReceipts{txs, receipts, !hasMore, blockNum == 0}, nil } -func (api *OtterscanAPIImpl) traceBlocks(ctx context.Context, addr common.Address, chainConfig *params.ChainConfig, minPageSize, resultCount uint16, hasMore bool, multiIter BlockProvider) ([]*TransactionsWithReceipts, bool, error) { +func (api *OtterscanAPIImpl) traceBlocks(ctx context.Context, addr common.Address, chainConfig *params.ChainConfig, minPageSize, resultCount uint16, multiIter BlockProvider) ([]*TransactionsWithReceipts, bool, error) { var wg sync.WaitGroup - tot := 0 - blocks2Trace := minPageSize - resultCount - results := make([]*TransactionsWithReceipts, blocks2Trace) - for i := 0; i < int(blocks2Trace); i++ { + maxBlocksToTrace := minPageSize - resultCount + results := make([]*TransactionsWithReceipts, maxBlocksToTrace) + totalBlocksTraced := 0 + hasMore := true + + for i := 0; i < int(maxBlocksToTrace); i++ { var nextBlock uint64 var err error nextBlock, hasMore, err = multiIter() @@ -277,12 +279,12 @@ func (api *OtterscanAPIImpl) traceBlocks(ctx context.Context, addr common.Addres } wg.Add(1) - tot++ + totalBlocksTraced++ go api.searchTraceBlock(ctx, &wg, addr, chainConfig, i, nextBlock, results) } wg.Wait() - return results[:tot], hasMore, nil + return results[:totalBlocksTraced], hasMore, nil } func (api *OtterscanAPIImpl) delegateGetBlockByNumber(tx kv.Tx, b *types.Block, number rpc.BlockNumber, inclTx bool) (map[string]interface{}, error) { From 74374e74e754a721571e7df7df0b9b4c36c6530f Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Fri, 14 Jan 2022 22:25:59 -0300 Subject: [PATCH 108/261] Using default expected capacity for page; code simplification --- cmd/rpcdaemon/commands/otterscan_api.go | 26 +++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 0ab3147d0e0..38b80869cfd 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -148,8 +148,8 @@ func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr return nil, err } - txs := make([]*RPCTransaction, 0) - receipts := make([]map[string]interface{}, 0) + txs := make([]*RPCTransaction, 0, minPageSize) + receipts := make([]map[string]interface{}, 0, minPageSize) resultCount := uint16(0) hasMore := true @@ -169,7 +169,6 @@ func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr return nil, errors.New("XXXX") } - resultCount += uint16(len(r.Txs)) for i := len(r.Txs) - 1; i >= 0; i-- { txs = append(txs, r.Txs[i]) } @@ -177,6 +176,7 @@ func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr receipts = append(receipts, r.Receipts[i]) } + resultCount += uint16(len(r.Txs)) if resultCount >= minPageSize { break } @@ -218,8 +218,8 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c fromIter := NewSearchForwardIterator(callFromCursor, addr, blockNum) toIter := NewSearchForwardIterator(callToCursor, addr, blockNum) - txs := make([]*RPCTransaction, 0) - receipts := make([]map[string]interface{}, 0) + txs := make([]*RPCTransaction, 0, minPageSize) + receipts := make([]map[string]interface{}, 0, minPageSize) multiIter, err := newMultiIterator(true, fromIter, toIter) if err != nil { @@ -242,20 +242,22 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c return nil, errors.New("XXXX") } - resultCount += uint16(len(r.Txs)) - for _, v := range r.Txs { - txs = append([]*RPCTransaction{v}, txs...) - } - for _, v := range r.Receipts { - receipts = append([]map[string]interface{}{v}, receipts...) - } + txs = append(txs, r.Txs...) + receipts = append(receipts, r.Receipts...) + resultCount += uint16(len(r.Txs)) if resultCount >= minPageSize { break } } } + // Reverse results + lentxs := len(txs) + for i := 0; i < lentxs/2; i++ { + txs[i], txs[lentxs-1-i] = txs[lentxs-1-i], txs[i] + receipts[i], receipts[lentxs-1-i] = receipts[lentxs-1-i], receipts[i] + } return &TransactionsWithReceipts{txs, receipts, !hasMore, blockNum == 0}, nil } From e55bfa9d3b828bb05593056f54fd27d955641bc1 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Fri, 14 Jan 2022 22:44:14 -0300 Subject: [PATCH 109/261] More code simplification --- cmd/rpcdaemon/commands/otterscan_api.go | 12 ++----- .../commands/otterscan_search_multi.go | 36 +++++++++++-------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 38b80869cfd..a5f03ebce65 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -143,10 +143,7 @@ func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr // Initialize search cursors at the first shard >= desired block number fromIter := NewSearchBackIterator(callFromCursor, addr, blockNum) toIter := NewSearchBackIterator(callToCursor, addr, blockNum) - multiIter, err := newMultiIterator(false, fromIter, toIter) - if err != nil { - return nil, err - } + multiIter := newMultiIterator(false, fromIter, toIter) txs := make([]*RPCTransaction, 0, minPageSize) receipts := make([]map[string]interface{}, 0, minPageSize) @@ -214,17 +211,14 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c } // Initialize search cursors at the first shard >= desired block number - resultCount := uint16(0) fromIter := NewSearchForwardIterator(callFromCursor, addr, blockNum) toIter := NewSearchForwardIterator(callToCursor, addr, blockNum) + multiIter := newMultiIterator(true, fromIter, toIter) txs := make([]*RPCTransaction, 0, minPageSize) receipts := make([]map[string]interface{}, 0, minPageSize) - multiIter, err := newMultiIterator(true, fromIter, toIter) - if err != nil { - return nil, err - } + resultCount := uint16(0) hasMore := true for { if resultCount >= minPageSize || !hasMore { diff --git a/cmd/rpcdaemon/commands/otterscan_search_multi.go b/cmd/rpcdaemon/commands/otterscan_search_multi.go index b2eab3dda34..90161d2f3b7 100644 --- a/cmd/rpcdaemon/commands/otterscan_search_multi.go +++ b/cmd/rpcdaemon/commands/otterscan_search_multi.go @@ -1,17 +1,23 @@ package commands -func newMultiIterator(smaller bool, fromIter, toIter BlockProvider) (BlockProvider, error) { - // TODO: move this inside the closure; remove error from sig - nextFrom, hasMoreFrom, err := fromIter() - if err != nil { - return nil, err - } - nextTo, hasMoreTo, err := toIter() - if err != nil { - return nil, err - } +func newMultiIterator(smaller bool, fromIter, toIter BlockProvider) BlockProvider { + var nextFrom, nextTo uint64 + var hasMoreFrom, hasMoreTo bool + initialized := false return func() (uint64, bool, error) { + if !initialized { + initialized = true + + var err error + if nextFrom, hasMoreFrom, err = fromIter(); err != nil { + return 0, false, err + } + if nextTo, hasMoreTo, err = toIter(); err != nil { + return 0, false, err + } + } + if !hasMoreFrom && !hasMoreTo { return 0, false, nil } @@ -36,17 +42,17 @@ func newMultiIterator(smaller bool, fromIter, toIter BlockProvider) (BlockProvid // Pull next; it may be that from AND to contains the same blockNum if hasMoreFrom && blockNum == nextFrom { - nextFrom, hasMoreFrom, err = fromIter() - if err != nil { + var err error + if nextFrom, hasMoreFrom, err = fromIter(); err != nil { return 0, false, err } } if hasMoreTo && blockNum == nextTo { - nextTo, hasMoreTo, err = toIter() - if err != nil { + var err error + if nextTo, hasMoreTo, err = toIter(); err != nil { return 0, false, err } } return blockNum, hasMoreFrom || hasMoreTo, nil - }, nil + } } From 18d1ef555a6a4e5dfaeb5306602dd12d0b1a3e89 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Sat, 15 Jan 2022 15:19:06 +0000 Subject: [PATCH 110/261] [stable] No empty RLPs in TxPacket messages, consistent parsing of TxPackets (#3268) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index dd8dbf5eb44..85a5a5998d4 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20220111081227-d6108f0d081f + github.com/ledgerwatch/erigon-lib v0.0.0-20220115122611-403e025ead66 github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 diff --git a/go.sum b/go.sum index 467fa3caa6b..e38420bc19d 100644 --- a/go.sum +++ b/go.sum @@ -500,8 +500,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20220111081227-d6108f0d081f h1:j4cRW+chzRRCW5Uyvf238Ct5ej+gnGBSfj07JcQ9Ixc= -github.com/ledgerwatch/erigon-lib v0.0.0-20220111081227-d6108f0d081f/go.mod h1:RtMyitRZlGyq0k8YVbMIwN/w3iby0zhPfM3tpCoqSUU= +github.com/ledgerwatch/erigon-lib v0.0.0-20220115122611-403e025ead66 h1:03ZFFrMFMS7cpXvRq/tI/lIvRIr7o2HX69HkO3cRP1c= +github.com/ledgerwatch/erigon-lib v0.0.0-20220115122611-403e025ead66/go.mod h1:RtMyitRZlGyq0k8YVbMIwN/w3iby0zhPfM3tpCoqSUU= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= From 704be221e5bb175acec917cd18083c33d23a4028 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sat, 15 Jan 2022 19:34:44 -0300 Subject: [PATCH 111/261] Renames --- cmd/rpcdaemon/commands/otterscan_api.go | 16 ++++++++-------- .../commands/otterscan_search_backward.go | 2 +- .../commands/otterscan_search_forward.go | 2 +- cmd/rpcdaemon/commands/otterscan_search_multi.go | 12 ++++++------ 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index a5f03ebce65..9659b05a137 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -141,9 +141,9 @@ func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr } // Initialize search cursors at the first shard >= desired block number - fromIter := NewSearchBackIterator(callFromCursor, addr, blockNum) - toIter := NewSearchBackIterator(callToCursor, addr, blockNum) - multiIter := newMultiIterator(false, fromIter, toIter) + callFromProvider := NewCallCursorBackwardBlockProvider(callFromCursor, addr, blockNum) + callToProvider := NewCallCursorBackwardBlockProvider(callToCursor, addr, blockNum) + callFromToProvider := newCallFromToBlockProvider(false, callFromProvider, callToProvider) txs := make([]*RPCTransaction, 0, minPageSize) receipts := make([]map[string]interface{}, 0, minPageSize) @@ -156,7 +156,7 @@ func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr } var results []*TransactionsWithReceipts - results, hasMore, err = api.traceBlocks(ctx, addr, chainConfig, minPageSize, resultCount, multiIter) + results, hasMore, err = api.traceBlocks(ctx, addr, chainConfig, minPageSize, resultCount, callFromToProvider) if err != nil { return nil, err } @@ -211,9 +211,9 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c } // Initialize search cursors at the first shard >= desired block number - fromIter := NewSearchForwardIterator(callFromCursor, addr, blockNum) - toIter := NewSearchForwardIterator(callToCursor, addr, blockNum) - multiIter := newMultiIterator(true, fromIter, toIter) + callFromProvider := NewCallCursorForwardBlockProvider(callFromCursor, addr, blockNum) + callToProvider := NewCallCursorForwardBlockProvider(callToCursor, addr, blockNum) + callFromToProvider := newCallFromToBlockProvider(true, callFromProvider, callToProvider) txs := make([]*RPCTransaction, 0, minPageSize) receipts := make([]map[string]interface{}, 0, minPageSize) @@ -226,7 +226,7 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c } var results []*TransactionsWithReceipts - results, hasMore, err = api.traceBlocks(ctx, addr, chainConfig, minPageSize, resultCount, multiIter) + results, hasMore, err = api.traceBlocks(ctx, addr, chainConfig, minPageSize, resultCount, callFromToProvider) if err != nil { return nil, err } diff --git a/cmd/rpcdaemon/commands/otterscan_search_backward.go b/cmd/rpcdaemon/commands/otterscan_search_backward.go index b81b3d79f32..bbe59cbfb7e 100644 --- a/cmd/rpcdaemon/commands/otterscan_search_backward.go +++ b/cmd/rpcdaemon/commands/otterscan_search_backward.go @@ -154,7 +154,7 @@ func NewBackwardBlockProvider(chunkLocator ChunkLocator, block uint64) BlockProv } } -func NewSearchBackIterator(cursor kv.Cursor, addr common.Address, maxBlock uint64) BlockProvider { +func NewCallCursorBackwardBlockProvider(cursor kv.Cursor, addr common.Address, maxBlock uint64) BlockProvider { chunkLocator := newBackwardChunkLocator(cursor, addr) return NewBackwardBlockProvider(chunkLocator, maxBlock) } diff --git a/cmd/rpcdaemon/commands/otterscan_search_forward.go b/cmd/rpcdaemon/commands/otterscan_search_forward.go index bde6604ce07..4217cc3f127 100644 --- a/cmd/rpcdaemon/commands/otterscan_search_forward.go +++ b/cmd/rpcdaemon/commands/otterscan_search_forward.go @@ -144,7 +144,7 @@ func NewForwardBlockProvider(chunkLocator ChunkLocator, block uint64) BlockProvi } } -func NewSearchForwardIterator(cursor kv.Cursor, addr common.Address, minBlock uint64) BlockProvider { +func NewCallCursorForwardBlockProvider(cursor kv.Cursor, addr common.Address, minBlock uint64) BlockProvider { chunkLocator := newForwardChunkLocator(cursor, addr) return NewForwardBlockProvider(chunkLocator, minBlock) } diff --git a/cmd/rpcdaemon/commands/otterscan_search_multi.go b/cmd/rpcdaemon/commands/otterscan_search_multi.go index 90161d2f3b7..e754338a9c9 100644 --- a/cmd/rpcdaemon/commands/otterscan_search_multi.go +++ b/cmd/rpcdaemon/commands/otterscan_search_multi.go @@ -1,6 +1,6 @@ package commands -func newMultiIterator(smaller bool, fromIter, toIter BlockProvider) BlockProvider { +func newCallFromToBlockProvider(isBackwards bool, callFromProvider, callToProvider BlockProvider) BlockProvider { var nextFrom, nextTo uint64 var hasMoreFrom, hasMoreTo bool initialized := false @@ -10,10 +10,10 @@ func newMultiIterator(smaller bool, fromIter, toIter BlockProvider) BlockProvide initialized = true var err error - if nextFrom, hasMoreFrom, err = fromIter(); err != nil { + if nextFrom, hasMoreFrom, err = callFromProvider(); err != nil { return 0, false, err } - if nextTo, hasMoreTo, err = toIter(); err != nil { + if nextTo, hasMoreTo, err = callToProvider(); err != nil { return 0, false, err } } @@ -29,7 +29,7 @@ func newMultiIterator(smaller bool, fromIter, toIter BlockProvider) BlockProvide blockNum = nextFrom } else { blockNum = nextFrom - if smaller { + if isBackwards { if nextTo < nextFrom { blockNum = nextTo } @@ -43,13 +43,13 @@ func newMultiIterator(smaller bool, fromIter, toIter BlockProvider) BlockProvide // Pull next; it may be that from AND to contains the same blockNum if hasMoreFrom && blockNum == nextFrom { var err error - if nextFrom, hasMoreFrom, err = fromIter(); err != nil { + if nextFrom, hasMoreFrom, err = callFromProvider(); err != nil { return 0, false, err } } if hasMoreTo && blockNum == nextTo { var err error - if nextTo, hasMoreTo, err = toIter(); err != nil { + if nextTo, hasMoreTo, err = callToProvider(); err != nil { return 0, false, err } } From ebcb352d682454b016a52870b38b0566ce5cff40 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sat, 15 Jan 2022 22:36:09 -0300 Subject: [PATCH 112/261] Better pageSize docs/naming --- cmd/rpcdaemon/commands/otterscan_api.go | 49 ++++++++++++++++--------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 9659b05a137..76e4cf442da 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -44,8 +44,8 @@ type TransactionsWithReceipts struct { type OtterscanAPI interface { GetApiLevel() uint8 GetInternalOperations(ctx context.Context, hash common.Hash) ([]*otterscan.InternalOperation, error) - SearchTransactionsBefore(ctx context.Context, addr common.Address, blockNum uint64, minPageSize uint16) (*TransactionsWithReceipts, error) - SearchTransactionsAfter(ctx context.Context, addr common.Address, blockNum uint64, minPageSize uint16) (*TransactionsWithReceipts, error) + SearchTransactionsBefore(ctx context.Context, addr common.Address, blockNum uint64, pageSize uint16) (*TransactionsWithReceipts, error) + SearchTransactionsAfter(ctx context.Context, addr common.Address, blockNum uint64, pageSize uint16) (*TransactionsWithReceipts, error) GetBlockDetails(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) GetBlockTransactions(ctx context.Context, number rpc.BlockNumber, pageNumber uint8, pageSize uint8) (map[string]interface{}, error) HasCode(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (bool, error) @@ -116,7 +116,12 @@ func (api *OtterscanAPIImpl) GetInternalOperations(ctx context.Context, hash com // Search transactions that touch a certain address. // // It searches back a certain block (including); the results are sorted descending. -func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr common.Address, blockNum uint64, minPageSize uint16) (*TransactionsWithReceipts, error) { +// +// The pageSize indicates how many txs may be returned. If there are less txs than pageSize, +// they are just returned. But it may return a little more than pageSize if there are more txs +// than the necessary to fill pageSize in the last found block, i.e., let's say you want pageSize == 25, +// you already found 24 txs, the next block contains 4 matches, then this function will return 28 txs. +func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr common.Address, blockNum uint64, pageSize uint16) (*TransactionsWithReceipts, error) { dbtx, err := api.db.BeginRo(ctx) if err != nil { return nil, err @@ -145,18 +150,18 @@ func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr callToProvider := NewCallCursorBackwardBlockProvider(callToCursor, addr, blockNum) callFromToProvider := newCallFromToBlockProvider(false, callFromProvider, callToProvider) - txs := make([]*RPCTransaction, 0, minPageSize) - receipts := make([]map[string]interface{}, 0, minPageSize) + txs := make([]*RPCTransaction, 0, pageSize) + receipts := make([]map[string]interface{}, 0, pageSize) resultCount := uint16(0) hasMore := true for { - if resultCount >= minPageSize || !hasMore { + if resultCount >= pageSize || !hasMore { break } var results []*TransactionsWithReceipts - results, hasMore, err = api.traceBlocks(ctx, addr, chainConfig, minPageSize, resultCount, callFromToProvider) + results, hasMore, err = api.traceBlocks(ctx, addr, chainConfig, pageSize, resultCount, callFromToProvider) if err != nil { return nil, err } @@ -174,7 +179,7 @@ func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr } resultCount += uint16(len(r.Txs)) - if resultCount >= minPageSize { + if resultCount >= pageSize { break } } @@ -186,7 +191,12 @@ func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr // Search transactions that touch a certain address. // // It searches forward a certain block (including); the results are sorted descending. -func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr common.Address, blockNum uint64, minPageSize uint16) (*TransactionsWithReceipts, error) { +// +// The pageSize indicates how many txs may be returned. If there are less txs than pageSize, +// they are just returned. But it may return a little more than pageSize if there are more txs +// than the necessary to fill pageSize in the last found block, i.e., let's say you want pageSize == 25, +// you already found 24 txs, the next block contains 4 matches, then this function will return 28 txs. +func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr common.Address, blockNum uint64, pageSize uint16) (*TransactionsWithReceipts, error) { dbtx, err := api.db.BeginRo(ctx) if err != nil { return nil, err @@ -215,18 +225,18 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c callToProvider := NewCallCursorForwardBlockProvider(callToCursor, addr, blockNum) callFromToProvider := newCallFromToBlockProvider(true, callFromProvider, callToProvider) - txs := make([]*RPCTransaction, 0, minPageSize) - receipts := make([]map[string]interface{}, 0, minPageSize) + txs := make([]*RPCTransaction, 0, pageSize) + receipts := make([]map[string]interface{}, 0, pageSize) resultCount := uint16(0) hasMore := true for { - if resultCount >= minPageSize || !hasMore { + if resultCount >= pageSize || !hasMore { break } var results []*TransactionsWithReceipts - results, hasMore, err = api.traceBlocks(ctx, addr, chainConfig, minPageSize, resultCount, callFromToProvider) + results, hasMore, err = api.traceBlocks(ctx, addr, chainConfig, pageSize, resultCount, callFromToProvider) if err != nil { return nil, err } @@ -240,7 +250,7 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c receipts = append(receipts, r.Receipts...) resultCount += uint16(len(r.Txs)) - if resultCount >= minPageSize { + if resultCount >= pageSize { break } } @@ -255,15 +265,18 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c return &TransactionsWithReceipts{txs, receipts, !hasMore, blockNum == 0}, nil } -func (api *OtterscanAPIImpl) traceBlocks(ctx context.Context, addr common.Address, chainConfig *params.ChainConfig, minPageSize, resultCount uint16, multiIter BlockProvider) ([]*TransactionsWithReceipts, bool, error) { +func (api *OtterscanAPIImpl) traceBlocks(ctx context.Context, addr common.Address, chainConfig *params.ChainConfig, pageSize, resultCount uint16, multiIter BlockProvider) ([]*TransactionsWithReceipts, bool, error) { var wg sync.WaitGroup - maxBlocksToTrace := minPageSize - resultCount - results := make([]*TransactionsWithReceipts, maxBlocksToTrace) + // Estimate the common case of user address having at most 1 interaction/block and + // trace N := remaining page matches as number of blocks to trace concurrently. + // TODO: this is not optimimal for big contract addresses; implement some better heuristics. + estBlocksToTrace := pageSize - resultCount + results := make([]*TransactionsWithReceipts, estBlocksToTrace) totalBlocksTraced := 0 hasMore := true - for i := 0; i < int(maxBlocksToTrace); i++ { + for i := 0; i < int(estBlocksToTrace); i++ { var nextBlock uint64 var err error nextBlock, hasMore, err = multiIter() From 15ba21542d8c6fc08d54956225c091d019851dc6 Mon Sep 17 00:00:00 2001 From: bgelb Date: Sun, 16 Jan 2022 10:46:46 -0800 Subject: [PATCH 113/261] re-add line that was dropped from PR 3148 (#3270) --- turbo/transactions/tracing.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/turbo/transactions/tracing.go b/turbo/transactions/tracing.go index 5ef034dd90e..40dd5999ddb 100644 --- a/turbo/transactions/tracing.go +++ b/turbo/transactions/tracing.go @@ -66,7 +66,7 @@ func ComputeTxEnv(ctx context.Context, block *types.Block, cfg *params.ChainConf } // Ensure any modifications are committed to the state // Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect - _ = statedb.FinalizeTx(vmenv.ChainRules, state.NewNoopWriter()) + _ = statedb.FinalizeTx(vmenv.ChainRules, reader) if idx+1 == len(block.Transactions()) { // Return the state from evaluating all txs in the block, note no msg or TxContext in this case From 3630c264644b0ef2479ee9797902043a9133f046 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Mon, 17 Jan 2022 07:23:34 +0000 Subject: [PATCH 114/261] issue/2028-support_parity_listStorageKeys (#3235) (#3271) Co-authored-by: primal_concrete_sledge --- cmd/rpcdaemon/commands/daemon.go | 8 ++ cmd/rpcdaemon/commands/parity_api.go | 72 +++++++++++++++ cmd/rpcdaemon/commands/parity_api_test.go | 102 ++++++++++++++++++++++ 3 files changed, 182 insertions(+) create mode 100644 cmd/rpcdaemon/commands/parity_api.go create mode 100644 cmd/rpcdaemon/commands/parity_api_test.go diff --git a/cmd/rpcdaemon/commands/daemon.go b/cmd/rpcdaemon/commands/daemon.go index 9d59b825522..ef7e898bf62 100644 --- a/cmd/rpcdaemon/commands/daemon.go +++ b/cmd/rpcdaemon/commands/daemon.go @@ -32,6 +32,7 @@ func APIList(ctx context.Context, db kv.RoDB, web3Impl := NewWeb3APIImpl(eth) dbImpl := NewDBAPIImpl() /* deprecated */ adminImpl := NewAdminAPI(eth) + parityImpl := NewParityAPIImpl(db) for _, enabledAPI := range cfg.API { switch enabledAPI { @@ -98,6 +99,13 @@ func APIList(ctx context.Context, db kv.RoDB, Service: AdminAPI(adminImpl), Version: "1.0", }) + case "parity": + defaultAPIList = append(defaultAPIList, rpc.API{ + Namespace: "parity", + Public: false, + Service: ParityAPI(parityImpl), + Version: "1.0", + }) } } diff --git a/cmd/rpcdaemon/commands/parity_api.go b/cmd/rpcdaemon/commands/parity_api.go new file mode 100644 index 00000000000..443593acbf2 --- /dev/null +++ b/cmd/rpcdaemon/commands/parity_api.go @@ -0,0 +1,72 @@ +package commands + +import ( + "context" + "encoding/binary" + "fmt" + + "github.com/ledgerwatch/erigon-lib/kv" + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/common/hexutil" + "github.com/ledgerwatch/erigon/core/state" +) + +// ParityAPI the interface for the parity_ RPC commands +type ParityAPI interface { + ListStorageKeys(ctx context.Context, account common.Address, quantity int, offset *hexutil.Bytes) ([]hexutil.Bytes, error) +} + +// ParityAPIImpl data structure to store things needed for parity_ commands +type ParityAPIImpl struct { + db kv.RoDB +} + +// NewParityAPIImpl returns ParityAPIImpl instance +func NewParityAPIImpl(db kv.RoDB) *ParityAPIImpl { + return &ParityAPIImpl{ + db: db, + } +} + +// ListStorageKeys implements parity_listStorageKeys. Returns all storage keys of the given address +func (api *ParityAPIImpl) ListStorageKeys(ctx context.Context, account common.Address, quantity int, offset *hexutil.Bytes) ([]hexutil.Bytes, error) { + tx, err := api.db.BeginRo(ctx) + if err != nil { + return nil, fmt.Errorf("listStorageKeys cannot open tx: %w", err) + } + defer tx.Rollback() + a, err := state.NewPlainStateReader(tx).ReadAccountData(account) + if err != nil { + return nil, err + } else if a == nil { + return nil, fmt.Errorf("acc not found") + } + + b := make([]byte, 8) + binary.BigEndian.PutUint64(b, a.GetIncarnation()) + seekBytes := append(account.Bytes(), b...) + + c, err := tx.CursorDupSort(kv.PlainState) + if err != nil { + return nil, err + } + defer c.Close() + keys := make([]hexutil.Bytes, 0) + var v []byte + var seekVal []byte + if offset != nil { + seekVal = *offset + } + + for v, err = c.SeekBothRange(seekBytes, seekVal); v != nil && len(keys) != quantity && err == nil; _, v, err = c.NextDup() { + if len(v) > common.HashLength { + keys = append(keys, v[:common.HashLength]) + } else { + keys = append(keys, v) + } + } + if err != nil { + return nil, err + } + return keys, nil +} diff --git a/cmd/rpcdaemon/commands/parity_api_test.go b/cmd/rpcdaemon/commands/parity_api_test.go new file mode 100644 index 00000000000..ed4cc29c24c --- /dev/null +++ b/cmd/rpcdaemon/commands/parity_api_test.go @@ -0,0 +1,102 @@ +package commands + +import ( + "context" + "fmt" + "testing" + + "github.com/ledgerwatch/erigon/cmd/rpcdaemon/rpcdaemontest" + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/common/hexutil" + "github.com/stretchr/testify/assert" +) + +func TestParityAPIImpl_ListStorageKeys_NoOffset(t *testing.T) { + assert := assert.New(t) + db := rpcdaemontest.CreateTestKV(t) + api := NewParityAPIImpl(db) + answers := []string{ + "0000000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000002", + "0a2127994676ca91e4eb3d2a1e46ec9dcee074dc2643bb5ebd4e9ac6541a3148", + "0fe673b4bc06161f39bc26f4e8831c810a72ffe69e5c8cb26f7f54752618e696", + "120e23dcb7e4437386073613853db77b10011a2404eefc716b97c7767e37f8eb", + } + addr := common.HexToAddress("0x920fd5070602feaea2e251e9e7238b6c376bcae5") + result, err := api.ListStorageKeys(context.Background(), addr, 5, nil) + if err != nil { + t.Errorf("calling ListStorageKeys: %v", err) + } + assert.Equal(len(answers), len(result)) + for k, v := range result { + assert.Equal(answers[k], common.Bytes2Hex(v)) + } +} + +func TestParityAPIImpl_ListStorageKeys_WithOffset_ExistingPrefix(t *testing.T) { + assert := assert.New(t) + db := rpcdaemontest.CreateTestKV(t) + api := NewParityAPIImpl(db) + answers := []string{ + "29d05770ca9ee7088a64e18c8e5160fc62c3c2179dc8ef9b4dbc970c9e51b4d8", + "29edc84535d98b29835079d685b97b41ee8e831e343cc80793057e462353a26d", + "2c05ac60f9aa2df5e64ef977f271e4b9a2d13951f123a2cb5f5d4ad5eb344f1a", + "4644be453c81744b6842ddf615d7fca0e14a23b09734be63d44c23452de95631", + "4974416255391052161ba8184fe652f3bf8c915592c65f7de127af8e637dce5d", + } + addr := common.HexToAddress("0x920fd5070602feaea2e251e9e7238b6c376bcae5") + offset := common.Hex2Bytes("29") + b := hexutil.Bytes(offset) + result, err := api.ListStorageKeys(context.Background(), addr, 5, &b) + if err != nil { + t.Errorf("calling ListStorageKeys: %v", err) + } + assert.Equal(len(answers), len(result)) + for k, v := range result { + assert.Equal(answers[k], common.Bytes2Hex(v)) + } +} + +func TestParityAPIImpl_ListStorageKeys_WithOffset_NonExistingPrefix(t *testing.T) { + assert := assert.New(t) + db := rpcdaemontest.CreateTestKV(t) + api := NewParityAPIImpl(db) + answers := []string{ + "4644be453c81744b6842ddf615d7fca0e14a23b09734be63d44c23452de95631", + "4974416255391052161ba8184fe652f3bf8c915592c65f7de127af8e637dce5d", + } + addr := common.HexToAddress("0x920fd5070602feaea2e251e9e7238b6c376bcae5") + offset := common.Hex2Bytes("30") + b := hexutil.Bytes(offset) + result, err := api.ListStorageKeys(context.Background(), addr, 2, &b) + if err != nil { + t.Errorf("calling ListStorageKeys: %v", err) + } + assert.Equal(len(answers), len(result)) + for k, v := range result { + assert.Equal(answers[k], common.Bytes2Hex(v)) + } +} + +func TestParityAPIImpl_ListStorageKeys_WithOffset_EmptyResponse(t *testing.T) { + assert := assert.New(t) + db := rpcdaemontest.CreateTestKV(t) + api := NewParityAPIImpl(db) + addr := common.HexToAddress("0x920fd5070602feaea2e251e9e7238b6c376bcae5") + offset := common.Hex2Bytes("ff") + b := hexutil.Bytes(offset) + result, err := api.ListStorageKeys(context.Background(), addr, 2, &b) + if err != nil { + t.Errorf("calling ListStorageKeys: %v", err) + } + assert.Equal(0, len(result)) +} + +func TestParityAPIImpl_ListStorageKeys_AccNotFound(t *testing.T) { + assert := assert.New(t) + db := rpcdaemontest.CreateTestKV(t) + api := NewParityAPIImpl(db) + addr := common.HexToAddress("0x920fd5070602feaea2e251e9e7238b6c376bcaef") + _, err := api.ListStorageKeys(context.Background(), addr, 2, nil) + assert.Error(err, fmt.Errorf("acc not found")) +} From d61fce83216dfbf89c690a5ad42abbb17993d1e1 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Mon, 17 Jan 2022 08:55:40 +0000 Subject: [PATCH 115/261] Simplify miner gas limit post EIP-1559. Default to 30M (#3205) (#3274) Co-authored-by: Andrew Ashikhmin <34320705+yperbasis@users.noreply.github.com> --- cmd/integration/commands/flags.go | 3 +- cmd/utils/flags.go | 20 ++------- core/block_validator.go | 45 ++++++++------------- core/chain_makers.go | 6 ++- eth/ethconfig/config.go | 3 +- eth/stagedsync/stage_mining_create_block.go | 4 +- params/mining.go | 3 +- turbo/cli/default_flags.go | 1 - 8 files changed, 31 insertions(+), 54 deletions(-) diff --git a/cmd/integration/commands/flags.go b/cmd/integration/commands/flags.go index 5e9a676bfc9..9b523e69159 100644 --- a/cmd/integration/commands/flags.go +++ b/cmd/integration/commands/flags.go @@ -39,8 +39,7 @@ func must(err error) { func withMining(cmd *cobra.Command) { cmd.Flags().Bool("mine", false, "Enable mining") cmd.Flags().StringArray("miner.notify", nil, "Comma separated HTTP URL list to notify of new work packages") - cmd.Flags().Uint64("miner.gastarget", ethconfig.Defaults.Miner.GasFloor, "Target gas floor for mined blocks") - cmd.Flags().Uint64("miner.gaslimit", ethconfig.Defaults.Miner.GasCeil, "Target gas ceiling for mined blocks") + cmd.Flags().Uint64("miner.gaslimit", ethconfig.Defaults.Miner.GasLimit, "Target gas limit for mined blocks") cmd.Flags().Int64("miner.gasprice", ethconfig.Defaults.Miner.GasPrice.Int64(), "Target gas price for mined blocks") cmd.Flags().String("miner.etherbase", "0", "Public address for block mining rewards (default = first account") cmd.Flags().String("miner.extradata", "", "Block extra data set by the miner (default = client version)") diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 6096a502215..4964bbe88b8 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -228,15 +228,10 @@ var ( Name: "miner.notify", Usage: "Comma separated HTTP URL list to notify of new work packages", } - MinerGasTargetFlag = cli.Uint64Flag{ - Name: "miner.gastarget", - Usage: "Target gas floor for mined blocks", - Value: ethconfig.Defaults.Miner.GasFloor, - } MinerGasLimitFlag = cli.Uint64Flag{ Name: "miner.gaslimit", - Usage: "Target gas ceiling for mined blocks", - Value: ethconfig.Defaults.Miner.GasCeil, + Usage: "Target gas limit for mined blocks", + Value: ethconfig.Defaults.Miner.GasLimit, } MinerGasPriceFlag = BigFlag{ Name: "miner.gasprice", @@ -1075,11 +1070,7 @@ func SetupMinerCobra(cmd *cobra.Command, cfg *params.MiningConfig) { panic(err) } cfg.ExtraData = []byte(extraDataStr) - cfg.GasFloor, err = flags.GetUint64(MinerGasTargetFlag.Name) - if err != nil { - panic(err) - } - cfg.GasCeil, err = flags.GetUint64(MinerGasLimitFlag.Name) + cfg.GasLimit, err = flags.GetUint64(MinerGasLimitFlag.Name) if err != nil { panic(err) } @@ -1139,11 +1130,8 @@ func setMiner(ctx *cli.Context, cfg *params.MiningConfig) { if ctx.GlobalIsSet(MinerExtraDataFlag.Name) { cfg.ExtraData = []byte(ctx.GlobalString(MinerExtraDataFlag.Name)) } - if ctx.GlobalIsSet(MinerGasTargetFlag.Name) { - cfg.GasFloor = ctx.GlobalUint64(MinerGasTargetFlag.Name) - } if ctx.GlobalIsSet(MinerGasLimitFlag.Name) { - cfg.GasCeil = ctx.GlobalUint64(MinerGasLimitFlag.Name) + cfg.GasLimit = ctx.GlobalUint64(MinerGasLimitFlag.Name) } if ctx.GlobalIsSet(MinerGasPriceFlag.Name) { cfg.GasPrice = GlobalBig(ctx, MinerGasPriceFlag.Name) diff --git a/core/block_validator.go b/core/block_validator.go index a88b7d8f54c..57dd9bbb3e7 100644 --- a/core/block_validator.go +++ b/core/block_validator.go @@ -21,37 +21,26 @@ import ( ) // CalcGasLimit computes the gas limit of the next block after parent. It aims -// to keep the baseline gas above the provided floor, and increase it towards the -// ceil if the blocks are full. If the ceil is exceeded, it will always decrease -// the gas allowance. -func CalcGasLimit(parentGasUsed, parentGasLimit, gasFloor, gasCeil uint64) uint64 { - // contrib = (parentGasUsed * 3 / 2) / 1024 - contrib := (parentGasUsed + parentGasUsed/2) / params.GasLimitBoundDivisor - - // decay = parentGasLimit / 1024 -1 - decay := parentGasLimit/params.GasLimitBoundDivisor - 1 - - /* - strategy: gasLimit of block-to-mine is set based on parent's - gasUsed value. if parentGasUsed > parentGasLimit * (2/3) then we - increase it, otherwise lower it (or leave it unchanged if it's right - at that usage) the amount increased/decreased depends on how far away - from parentGasLimit * (2/3) parentGasUsed is. - */ - limit := parentGasLimit - decay + contrib - if limit < params.MinGasLimit { - limit = params.MinGasLimit +// to keep the baseline gas close to the provided target, and increase it towards +// the target if the baseline gas is lower. +func CalcGasLimit(parentGasLimit, desiredLimit uint64) uint64 { + delta := parentGasLimit/params.GasLimitBoundDivisor - 1 + limit := parentGasLimit + if desiredLimit < params.MinGasLimit { + desiredLimit = params.MinGasLimit } // If we're outside our allowed gas range, we try to hone towards them - if limit < gasFloor { - limit = parentGasLimit + decay - if limit > gasFloor { - limit = gasFloor + if limit < desiredLimit { + limit = parentGasLimit + delta + if limit > desiredLimit { + limit = desiredLimit } - } else if limit > gasCeil { - limit = parentGasLimit - decay - if limit < gasCeil { - limit = gasCeil + return limit + } + if limit > desiredLimit { + limit = parentGasLimit - delta + if limit < desiredLimit { + limit = desiredLimit } } return limit diff --git a/core/chain_makers.go b/core/chain_makers.go index b2f7da73ad6..52a28988ad1 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -404,7 +404,7 @@ func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.I parent.UncleHash(), parent.Header().Seal, ), - GasLimit: CalcGasLimit(parent.GasUsed(), parent.GasLimit(), parent.GasLimit(), parent.GasLimit()), + GasLimit: CalcGasLimit(parent.GasLimit(), parent.GasLimit()), Number: new(big.Int).Add(parent.Number(), common.Big1), Time: time, } @@ -413,6 +413,10 @@ func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.I if chain.Config().IsLondon(header.Number.Uint64()) { header.BaseFee = misc.CalcBaseFee(chain.Config(), parent.Header()) header.Eip1559 = true + if !chain.Config().IsLondon(parent.NumberU64()) { + parentGasLimit := parent.GasLimit() * params.ElasticityMultiplier + header.GasLimit = CalcGasLimit(parentGasLimit, parentGasLimit) + } } header.WithSeal = chain.Config().IsHeaderWithSeal() diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index c3186024cba..661c7ac5903 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -76,8 +76,7 @@ var Defaults = Config{ NetworkID: 1, Prune: prune.DefaultMode, Miner: params.MiningConfig{ - GasFloor: 8000000, - GasCeil: 8000000, + GasLimit: 30_000_000, GasPrice: big.NewInt(params.GWei), Recommit: 3 * time.Second, }, diff --git a/eth/stagedsync/stage_mining_create_block.go b/eth/stagedsync/stage_mining_create_block.go index 95d9017523f..2a5c562afb9 100644 --- a/eth/stagedsync/stage_mining_create_block.go +++ b/eth/stagedsync/stage_mining_create_block.go @@ -213,7 +213,7 @@ func SpawnMiningCreateBlockStage(s *StageState, tx kv.RwTx, cfg MiningCreateBloc header := &types.Header{ ParentHash: parent.Hash(), Number: num.Add(num, common.Big1), - GasLimit: core.CalcGasLimit(parent.GasUsed, parent.GasLimit, cfg.miner.MiningConfig.GasFloor, cfg.miner.MiningConfig.GasCeil), + GasLimit: core.CalcGasLimit(parent.GasLimit, cfg.miner.MiningConfig.GasLimit), Extra: cfg.miner.MiningConfig.ExtraData, Time: uint64(timestamp), } @@ -224,7 +224,7 @@ func SpawnMiningCreateBlockStage(s *StageState, tx kv.RwTx, cfg MiningCreateBloc header.BaseFee = misc.CalcBaseFee(&cfg.chainConfig, parent) if !cfg.chainConfig.IsLondon(parent.Number.Uint64()) { parentGasLimit := parent.GasLimit * params.ElasticityMultiplier - header.GasLimit = core.CalcGasLimit(parent.GasUsed, parentGasLimit, cfg.miner.MiningConfig.GasFloor, cfg.miner.MiningConfig.GasCeil) + header.GasLimit = core.CalcGasLimit(parentGasLimit, cfg.miner.MiningConfig.GasLimit) } } log.Info(fmt.Sprintf("[%s] Start mine", logPrefix), "block", executionAt+1, "baseFee", header.BaseFee, "gasLimit", header.GasLimit) diff --git a/params/mining.go b/params/mining.go index d3878199f89..4215ec0523f 100644 --- a/params/mining.go +++ b/params/mining.go @@ -17,8 +17,7 @@ type MiningConfig struct { SigKey *ecdsa.PrivateKey // ECDSA private key for signing blocks Notify []string `toml:",omitempty"` // HTTP URL list to be notified of new work packages(only useful in ethash). ExtraData hexutil.Bytes `toml:",omitempty"` // Block extra data set by the miner - GasFloor uint64 // Target gas floor for mined blocks. - GasCeil uint64 // Target gas ceiling for mined blocks. + GasLimit uint64 // Target gas limit for mined blocks. GasPrice *big.Int // Minimum gas price for mining a transaction Recommit time.Duration // The time interval for miner to re-create mining work. } diff --git a/turbo/cli/default_flags.go b/turbo/cli/default_flags.go index 0923d41f58a..e1240ea3016 100644 --- a/turbo/cli/default_flags.go +++ b/turbo/cli/default_flags.go @@ -77,7 +77,6 @@ var DefaultFlags = []cli.Flag{ utils.CliqueDataDirFlag, utils.MiningEnabledFlag, utils.MinerNotifyFlag, - utils.MinerGasTargetFlag, utils.MinerGasLimitFlag, utils.MinerEtherbaseFlag, utils.MinerExtraDataFlag, From 765d46cab6ae2adb3d4967465746390f30ea85b7 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Mon, 17 Jan 2022 08:55:52 +0000 Subject: [PATCH 116/261] [stable] Update PriceBump, change tx replacement logic, update test (#3276) Co-authored-by: Alexey Sharp --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 85a5a5998d4..26253d62795 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20220115122611-403e025ead66 + github.com/ledgerwatch/erigon-lib v0.0.0-20220117080915-8327de3c4e64 github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 diff --git a/go.sum b/go.sum index e38420bc19d..9fec7e6e243 100644 --- a/go.sum +++ b/go.sum @@ -500,8 +500,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20220115122611-403e025ead66 h1:03ZFFrMFMS7cpXvRq/tI/lIvRIr7o2HX69HkO3cRP1c= -github.com/ledgerwatch/erigon-lib v0.0.0-20220115122611-403e025ead66/go.mod h1:RtMyitRZlGyq0k8YVbMIwN/w3iby0zhPfM3tpCoqSUU= +github.com/ledgerwatch/erigon-lib v0.0.0-20220117080915-8327de3c4e64 h1:Q3kUXgFiE2K/JscqqjCROg4Y4sjaz7Vzhuhg7xOSHNk= +github.com/ledgerwatch/erigon-lib v0.0.0-20220117080915-8327de3c4e64/go.mod h1:RtMyitRZlGyq0k8YVbMIwN/w3iby0zhPfM3tpCoqSUU= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= From a9a201e94a75304a45830b2f528748290d8a96ec Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Mon, 17 Jan 2022 14:07:56 -0300 Subject: [PATCH 117/261] Add more debug info --- cmd/rpcdaemon/commands/otterscan_search_forward_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_search_forward_test.go b/cmd/rpcdaemon/commands/otterscan_search_forward_test.go index 3eb10e60a65..f52bb9bc9f8 100644 --- a/cmd/rpcdaemon/commands/otterscan_search_forward_test.go +++ b/cmd/rpcdaemon/commands/otterscan_search_forward_test.go @@ -55,12 +55,12 @@ func checkNext(t *testing.T, blockProvider BlockProvider, expectedBlock uint64, if err != nil { t.Fatal(err) } - if expectedHasNext != hasNext { - t.Fatalf("Expected hasNext=%t, received=%t", expectedHasNext, hasNext) - } if bl != expectedBlock { t.Fatalf("Expected block %d, received %d", expectedBlock, bl) } + if expectedHasNext != hasNext { + t.Fatalf("Expected hasNext=%t, received=%t; at block=%d", expectedHasNext, hasNext, expectedBlock) + } } func TestForwardBlockProviderWith1Chunk(t *testing.T) { From 690e795421bd15f47ed772dad8696300b024b72d Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Mon, 17 Jan 2022 14:08:23 -0300 Subject: [PATCH 118/261] Add docs --- cmd/rpcdaemon/commands/otterscan_types.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/rpcdaemon/commands/otterscan_types.go b/cmd/rpcdaemon/commands/otterscan_types.go index 88a3b10d754..6f62bdda5a7 100644 --- a/cmd/rpcdaemon/commands/otterscan_types.go +++ b/cmd/rpcdaemon/commands/otterscan_types.go @@ -23,6 +23,7 @@ type ChunkProvider func() (chunk []byte, ok bool, err error) type BlockProvider func() (nextBlock uint64, hasMore bool, err error) +// Standard key format for call from/to indexes [address + block] func callIndexKey(addr common.Address, block uint64) []byte { key := make([]byte, common.AddressLength+8) copy(key[:common.AddressLength], addr.Bytes()) From 5af66db5021a011e58e6e03d48727bb19aefd72c Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Mon, 17 Jan 2022 14:11:52 -0300 Subject: [PATCH 119/261] Extract common test utils --- .../commands/otterscan_search_forward_test.go | 24 -------------- .../commands/otterscan_search_test.go | 31 +++++++++++++++++++ 2 files changed, 31 insertions(+), 24 deletions(-) create mode 100644 cmd/rpcdaemon/commands/otterscan_search_test.go diff --git a/cmd/rpcdaemon/commands/otterscan_search_forward_test.go b/cmd/rpcdaemon/commands/otterscan_search_forward_test.go index f52bb9bc9f8..216dfaef6a1 100644 --- a/cmd/rpcdaemon/commands/otterscan_search_forward_test.go +++ b/cmd/rpcdaemon/commands/otterscan_search_forward_test.go @@ -39,30 +39,6 @@ func newMockForwardChunkProvider(chunks [][]byte) ChunkProvider { } } -func createBitmap(t *testing.T, blocks []uint64) []byte { - bm := roaring64.NewBitmap() - bm.AddMany(blocks) - - chunk, err := bm.ToBytes() - if err != nil { - t.Fatal(err) - } - return chunk -} - -func checkNext(t *testing.T, blockProvider BlockProvider, expectedBlock uint64, expectedHasNext bool) { - bl, hasNext, err := blockProvider() - if err != nil { - t.Fatal(err) - } - if bl != expectedBlock { - t.Fatalf("Expected block %d, received %d", expectedBlock, bl) - } - if expectedHasNext != hasNext { - t.Fatalf("Expected hasNext=%t, received=%t; at block=%d", expectedHasNext, hasNext, expectedBlock) - } -} - func TestForwardBlockProviderWith1Chunk(t *testing.T) { // Mocks 1 chunk chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) diff --git a/cmd/rpcdaemon/commands/otterscan_search_test.go b/cmd/rpcdaemon/commands/otterscan_search_test.go new file mode 100644 index 00000000000..e4a7c3b68d4 --- /dev/null +++ b/cmd/rpcdaemon/commands/otterscan_search_test.go @@ -0,0 +1,31 @@ +package commands + +import ( + "testing" + + "github.com/RoaringBitmap/roaring/roaring64" +) + +func createBitmap(t *testing.T, blocks []uint64) []byte { + bm := roaring64.NewBitmap() + bm.AddMany(blocks) + + chunk, err := bm.ToBytes() + if err != nil { + t.Fatal(err) + } + return chunk +} + +func checkNext(t *testing.T, blockProvider BlockProvider, expectedBlock uint64, expectedHasNext bool) { + bl, hasNext, err := blockProvider() + if err != nil { + t.Fatal(err) + } + if bl != expectedBlock { + t.Fatalf("Expected block %d, received %d", expectedBlock, bl) + } + if expectedHasNext != hasNext { + t.Fatalf("Expected hasNext=%t, received=%t; at block=%d", expectedHasNext, hasNext, expectedBlock) + } +} From 4083b1c05720202e19b28595c0a0fdd5caa91d46 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Mon, 17 Jan 2022 22:21:21 -0300 Subject: [PATCH 120/261] Extract common code; fix bugs; add more tests --- cmd/rpcdaemon/commands/otterscan_api.go | 3 +- .../commands/otterscan_search_backward.go | 148 +++++++----------- .../otterscan_search_backward_multi_test.go | 109 +++++++++++++ .../otterscan_search_backward_test.go | 24 ++- .../commands/otterscan_search_forward.go | 127 +++++---------- .../otterscan_search_forward_multi_test.go | 108 +++++++++++++ .../commands/otterscan_search_forward_test.go | 18 ++- .../commands/otterscan_search_multi.go | 5 + cmd/rpcdaemon/commands/otterscan_types.go | 56 +++++++ 9 files changed, 417 insertions(+), 181 deletions(-) create mode 100644 cmd/rpcdaemon/commands/otterscan_search_backward_multi_test.go create mode 100644 cmd/rpcdaemon/commands/otterscan_search_forward_multi_test.go diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 76e4cf442da..9e53d4dda15 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -283,7 +283,8 @@ func (api *OtterscanAPIImpl) traceBlocks(ctx context.Context, addr common.Addres if err != nil { return nil, false, err } - if !hasMore { + // TODO: nextBlock == 0 seems redundant with hasMore == false + if !hasMore && nextBlock == 0 { break } diff --git a/cmd/rpcdaemon/commands/otterscan_search_backward.go b/cmd/rpcdaemon/commands/otterscan_search_backward.go index bbe59cbfb7e..4d8193e0119 100644 --- a/cmd/rpcdaemon/commands/otterscan_search_backward.go +++ b/cmd/rpcdaemon/commands/otterscan_search_backward.go @@ -8,116 +8,57 @@ import ( "github.com/ledgerwatch/erigon/common" ) -// This ChunkLocator searches over a cursor with a key format of [common.Address, block uint64], -// where block is the first block number contained in the chunk value. -// -// It positions the cursor on the chunk that contains the last block <= maxBlock. -func newBackwardChunkLocator(cursor kv.Cursor, addr common.Address) ChunkLocator { - return func(block uint64) (ChunkProvider, bool, error) { - searchKey := callIndexKey(addr, block) - k, _, err := cursor.Seek(searchKey) - if err != nil { - return nil, false, err - } - - // If the addr prefix is different it means there is not even the last - // chunk (0xffff...), so this address has no call index - if !bytes.HasPrefix(k, addr.Bytes()) { - return nil, false, nil - } - - // Exact match? - if bytes.Equal(k, searchKey) { - return newBackwardChunkProvider(cursor, addr, block), true, nil - } - - // If we reached the last addr's chunk (0xffff...), it may contain desired blocks - lastAddrKey := callIndexKey(addr, MaxBlockNum) - if bytes.Equal(k, lastAddrKey) { - return newBackwardChunkProvider(cursor, addr, block), true, nil - } - - // It maybe the previous chunk; position it over the previous, but let the prefix to be - // checked in the ChunkProvider (peek + prefix check) - _, _, err = cursor.Prev() - if err != nil { - return nil, false, err - } - return newBackwardChunkProvider(cursor, addr, block), true, nil - } -} - -// This ChunkProvider is built by NewBackwardChunkLocator and advances the cursor backwards until -// there is no more chunks for the desired addr. -func newBackwardChunkProvider(cursor kv.Cursor, addr common.Address, minBlock uint64) ChunkProvider { - first := true - var err error - eof := false - return func() ([]byte, bool, error) { - if err != nil { - return nil, false, err - } - if eof { - return nil, false, nil - } - - var k, v []byte - if first { - first = false - k, v, err = cursor.Current() - } else { - k, v, err = cursor.Prev() - } - - if err != nil { - eof = true - return nil, false, err - } - if !bytes.HasPrefix(k, addr.Bytes()) { - eof = true - return nil, false, nil - } - return v, true, nil - } -} - // Given a ChunkLocator, moves back over the chunks and inside each chunk, moves // backwards over the block numbers. -func NewBackwardBlockProvider(chunkLocator ChunkLocator, block uint64) BlockProvider { +func NewBackwardBlockProvider(chunkLocator ChunkLocator, maxBlock uint64) BlockProvider { // block == 0 means no max - if block == 0 { - block = MaxBlockNum + if maxBlock == 0 { + maxBlock = MaxBlockNum } var iter roaring64.IntIterable64 var chunkProvider ChunkProvider + isFirst := true + finished := false return func() (uint64, bool, error) { - if chunkProvider == nil { + if finished { + return 0, false, nil + } + + if isFirst { + isFirst = false + + // Try to get first chunk var ok bool var err error - chunkProvider, ok, err = chunkLocator(block) + chunkProvider, ok, err = chunkLocator(maxBlock) if err != nil { + finished = true return 0, false, err } if !ok { + finished = true return 0, false, nil } if chunkProvider == nil { + finished = true return 0, false, nil } - } - if iter == nil { + // Has at least the first chunk; initialize the iterator chunk, ok, err := chunkProvider() if err != nil { + finished = true return 0, false, err } if !ok { + finished = true return 0, false, nil } bm := roaring64.NewBitmap() if _, err := bm.ReadFrom(bytes.NewReader(chunk)); err != nil { + finished = true return 0, false, err } @@ -125,29 +66,56 @@ func NewBackwardBlockProvider(chunkLocator ChunkLocator, block uint64) BlockProv // the last block <= maxBlock in the middle of the chunk/bitmap, so we // remove all blocks after it (since there is no AdvanceIfNeeded() in // IntIterable64) - if block != MaxBlockNum { - bm.RemoveRange(block+1, MaxBlockNum) + if maxBlock != MaxBlockNum { + bm.RemoveRange(maxBlock+1, MaxBlockNum) } iter = bm.ReverseIterator() + + // This means it is the last chunk and the min block is > the last one + if !iter.HasNext() { + chunk, ok, err := chunkProvider() + if err != nil { + finished = true + return 0, false, err + } + if !ok { + finished = true + return 0, false, nil + } + + bm := roaring64.NewBitmap() + if _, err := bm.ReadFrom(bytes.NewReader(chunk)); err != nil { + finished = true + return 0, false, err + } + + iter = bm.ReverseIterator() + } } nextBlock := iter.Next() hasNext := iter.HasNext() if !hasNext { + iter = nil + // Check if there is another chunk to get blocks from chunk, ok, err := chunkProvider() if err != nil { return 0, false, err } - if ok { - hasNext = true + if !ok { + finished = true + return nextBlock, false, nil + } - bm := roaring64.NewBitmap() - if _, err := bm.ReadFrom(bytes.NewReader(chunk)); err != nil { - return 0, false, err - } - iter = bm.ReverseIterator() + hasNext = true + + bm := roaring64.NewBitmap() + if _, err := bm.ReadFrom(bytes.NewReader(chunk)); err != nil { + finished = true + return 0, false, err } + iter = bm.ReverseIterator() } return nextBlock, hasNext, nil @@ -155,6 +123,6 @@ func NewBackwardBlockProvider(chunkLocator ChunkLocator, block uint64) BlockProv } func NewCallCursorBackwardBlockProvider(cursor kv.Cursor, addr common.Address, maxBlock uint64) BlockProvider { - chunkLocator := newBackwardChunkLocator(cursor, addr) + chunkLocator := newCallChunkLocator(cursor, addr, false) return NewBackwardBlockProvider(chunkLocator, maxBlock) } diff --git a/cmd/rpcdaemon/commands/otterscan_search_backward_multi_test.go b/cmd/rpcdaemon/commands/otterscan_search_backward_multi_test.go new file mode 100644 index 00000000000..4aabcda0aa6 --- /dev/null +++ b/cmd/rpcdaemon/commands/otterscan_search_backward_multi_test.go @@ -0,0 +1,109 @@ +package commands + +import ( + "testing" +) + +func TestFromToBackwardBlockProviderWith1Chunk(t *testing.T) { + // Mocks 1 chunk + chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) + + chunkLocator := newMockBackwardChunkLocator([][]byte{chunk1}) + fromBlockProvider := NewBackwardBlockProvider(chunkLocator, 0) + toBlockProvider := NewBackwardBlockProvider(newMockBackwardChunkLocator([][]byte{}), 0) + blockProvider := newCallFromToBlockProvider(true, fromBlockProvider, toBlockProvider) + + checkNext(t, blockProvider, 1010, true) + checkNext(t, blockProvider, 1005, true) + checkNext(t, blockProvider, 1000, false) +} + +func TestFromToBackwardBlockProviderWith1ChunkMiddleBlock(t *testing.T) { + // Mocks 1 chunk + chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) + + chunkLocator := newMockBackwardChunkLocator([][]byte{chunk1}) + fromBlockProvider := NewBackwardBlockProvider(chunkLocator, 1005) + toBlockProvider := NewBackwardBlockProvider(newMockBackwardChunkLocator([][]byte{}), 0) + blockProvider := newCallFromToBlockProvider(true, fromBlockProvider, toBlockProvider) + + checkNext(t, blockProvider, 1005, true) + checkNext(t, blockProvider, 1000, false) +} + +func TestFromToBackwardBlockProviderWith1ChunkNotExactBlock(t *testing.T) { + // Mocks 1 chunk + chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) + + chunkLocator := newMockBackwardChunkLocator([][]byte{chunk1}) + fromBlockProvider := NewBackwardBlockProvider(chunkLocator, 1003) + toBlockProvider := NewBackwardBlockProvider(newMockBackwardChunkLocator([][]byte{}), 0) + blockProvider := newCallFromToBlockProvider(true, fromBlockProvider, toBlockProvider) + + checkNext(t, blockProvider, 1000, false) +} + +func TestFromToBackwardBlockProviderWith1ChunkLastBlock(t *testing.T) { + // Mocks 1 chunk + chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) + + chunkLocator := newMockBackwardChunkLocator([][]byte{chunk1}) + fromBlockProvider := NewBackwardBlockProvider(chunkLocator, 1000) + toBlockProvider := NewBackwardBlockProvider(newMockBackwardChunkLocator([][]byte{}), 0) + blockProvider := newCallFromToBlockProvider(true, fromBlockProvider, toBlockProvider) + + checkNext(t, blockProvider, 1000, false) +} + +func TestFromToBackwardBlockProviderWith1ChunkBlockNotFound(t *testing.T) { + // Mocks 1 chunk + chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) + + chunkLocator := newMockBackwardChunkLocator([][]byte{chunk1}) + fromBlockProvider := NewBackwardBlockProvider(chunkLocator, 900) + toBlockProvider := NewBackwardBlockProvider(newMockBackwardChunkLocator([][]byte{}), 0) + blockProvider := newCallFromToBlockProvider(true, fromBlockProvider, toBlockProvider) + + checkNext(t, blockProvider, 0, false) +} + +func TestFromToBackwardBlockProviderWithNoChunks(t *testing.T) { + chunkLocator := newMockBackwardChunkLocator([][]byte{}) + fromBlockProvider := NewBackwardBlockProvider(chunkLocator, 0) + toBlockProvider := NewBackwardBlockProvider(newMockBackwardChunkLocator([][]byte{}), 0) + blockProvider := newCallFromToBlockProvider(true, fromBlockProvider, toBlockProvider) + + checkNext(t, blockProvider, 0, false) +} + +func TestFromToBackwardBlockProviderWithMultipleChunks(t *testing.T) { + // Mocks 2 chunks + chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) + chunk2 := createBitmap(t, []uint64{1501, 1600}) + + chunkLocator := newMockBackwardChunkLocator([][]byte{chunk1, chunk2}) + fromBlockProvider := NewBackwardBlockProvider(chunkLocator, 0) + toBlockProvider := NewBackwardBlockProvider(newMockBackwardChunkLocator([][]byte{}), 0) + blockProvider := newCallFromToBlockProvider(true, fromBlockProvider, toBlockProvider) + + checkNext(t, blockProvider, 1600, true) + checkNext(t, blockProvider, 1501, true) + checkNext(t, blockProvider, 1010, true) + checkNext(t, blockProvider, 1005, true) + checkNext(t, blockProvider, 1000, false) +} + +func TestFromToBackwardBlockProviderWithMultipleChunksBlockBetweenChunks(t *testing.T) { + // Mocks 2 chunks + chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) + chunk2 := createBitmap(t, []uint64{1501, 1600}) + + chunkLocator := newMockBackwardChunkLocator([][]byte{chunk1, chunk2}) + fromBlockProvider := NewBackwardBlockProvider(chunkLocator, 1500) + toBlockProvider := NewBackwardBlockProvider(newMockBackwardChunkLocator([][]byte{}), 0) + blockProvider := newCallFromToBlockProvider(true, fromBlockProvider, toBlockProvider) + + checkNext(t, blockProvider, 1010, true) + checkNext(t, blockProvider, 1005, true) + checkNext(t, blockProvider, 1000, false) +} diff --git a/cmd/rpcdaemon/commands/otterscan_search_backward_test.go b/cmd/rpcdaemon/commands/otterscan_search_backward_test.go index 9f1f456eb79..9f85b7e00f4 100644 --- a/cmd/rpcdaemon/commands/otterscan_search_backward_test.go +++ b/cmd/rpcdaemon/commands/otterscan_search_backward_test.go @@ -9,19 +9,24 @@ import ( func newMockBackwardChunkLocator(chunks [][]byte) ChunkLocator { return func(block uint64) (ChunkProvider, bool, error) { - for i := len(chunks) - 1; i >= 0; i-- { + for i, v := range chunks { bm := roaring64.NewBitmap() - if _, err := bm.ReadFrom(bytes.NewReader(chunks[i])); err != nil { + if _, err := bm.ReadFrom(bytes.NewReader(v)); err != nil { return nil, false, err } - if block < bm.Minimum() { + if block > bm.Maximum() { continue } return newMockBackwardChunkProvider(chunks[:i+1]), true, nil } - // Not found + // Not found; return the last to simulate the behavior of returning + // everything up to the 0xffff... chunk + if len(chunks) > 0 { + return newMockBackwardChunkProvider(chunks), true, nil + } + return nil, true, nil } } @@ -125,3 +130,14 @@ func TestBackwardBlockProviderWithMultipleChunksBlockBetweenChunks(t *testing.T) checkNext(t, blockProvider, 1005, true) checkNext(t, blockProvider, 1000, false) } + +func TestBackwardBlockProviderWithMultipleChunksBlockNotFound(t *testing.T) { + // Mocks 2 chunks + chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) + chunk2 := createBitmap(t, []uint64{1501, 1600}) + + chunkLocator := newMockBackwardChunkLocator([][]byte{chunk1, chunk2}) + blockProvider := NewBackwardBlockProvider(chunkLocator, 900) + + checkNext(t, blockProvider, 0, false) +} diff --git a/cmd/rpcdaemon/commands/otterscan_search_forward.go b/cmd/rpcdaemon/commands/otterscan_search_forward.go index 4217cc3f127..f9774c6385c 100644 --- a/cmd/rpcdaemon/commands/otterscan_search_forward.go +++ b/cmd/rpcdaemon/commands/otterscan_search_forward.go @@ -8,109 +8,53 @@ import ( "github.com/ledgerwatch/erigon/common" ) -// This ChunkLocator searches over a cursor with a key format of [common.Address, block uint64], -// where block is the first block number contained in the chunk value. -// -// It positions the cursor on the chunk that contains the first block >= minBlock. -func newForwardChunkLocator(cursor kv.Cursor, addr common.Address) ChunkLocator { - return func(block uint64) (ChunkProvider, bool, error) { - searchKey := callIndexKey(addr, block) - k, _, err := cursor.Seek(searchKey) - if err != nil { - return nil, false, err - } - - // Exact match? - if bytes.Equal(k, searchKey) { - return newForwardChunkProvider(cursor, addr, block), true, nil - } - - // It maybe the previous chunk - kp, _, err := cursor.Prev() - if err != nil { - return nil, false, err - } - if !bytes.HasPrefix(kp, addr.Bytes()) { - // It is in the current chunk - _, _, err = cursor.Next() - if err != nil { - return nil, false, err - } - return newForwardChunkProvider(cursor, addr, block), true, nil - } - - // It is in the previous chunk - return newForwardChunkProvider(cursor, addr, block), true, nil - } -} - -// This ChunkProvider is built by NewForwardChunkLocator and advances the cursor forward until -// there is no more chunks for the desired addr. -func newForwardChunkProvider(cursor kv.Cursor, addr common.Address, minBlock uint64) ChunkProvider { - first := true - var err error - eof := false - return func() ([]byte, bool, error) { - if err != nil { - return nil, false, err - } - if eof { - return nil, false, nil - } - - var k, v []byte - if first { - first = false - k, v, err = cursor.Current() - } else { - k, v, err = cursor.Next() - } - - if err != nil { - eof = true - return nil, false, err - } - if !bytes.HasPrefix(k, addr.Bytes()) { - eof = true - return nil, false, nil - } - return v, true, nil - } -} - // Given a ChunkLocator, moves forward over the chunks and inside each chunk, moves // forward over the block numbers. -func NewForwardBlockProvider(chunkLocator ChunkLocator, block uint64) BlockProvider { +func NewForwardBlockProvider(chunkLocator ChunkLocator, minBlock uint64) BlockProvider { var iter roaring64.IntPeekable64 var chunkProvider ChunkProvider + isFirst := true + finished := false return func() (uint64, bool, error) { - if chunkProvider == nil { + if finished { + return 0, false, nil + } + + if isFirst { + isFirst = false + + // Try to get first chunk var ok bool var err error - chunkProvider, ok, err = chunkLocator(block) + chunkProvider, ok, err = chunkLocator(minBlock) if err != nil { + finished = true return 0, false, err } if !ok { + finished = true return 0, false, nil } if chunkProvider == nil { + finished = true return 0, false, nil } - } - if iter == nil { + // Has at least the first chunk; initialize the iterator chunk, ok, err := chunkProvider() if err != nil { + finished = true return 0, false, err } if !ok { + finished = true return 0, false, nil } bm := roaring64.NewBitmap() if _, err := bm.ReadFrom(bytes.NewReader(chunk)); err != nil { + finished = true return 0, false, err } iter = bm.Iterator() @@ -118,26 +62,39 @@ func NewForwardBlockProvider(chunkLocator ChunkLocator, block uint64) BlockProvi // It can happen that on the first chunk we'll get a chunk that contains // the first block >= minBlock in the middle of the chunk/bitmap, so we // skip all previous blocks before it. - iter.AdvanceIfNeeded(block) + iter.AdvanceIfNeeded(minBlock) + + // This means it is the last chunk and the min block is > the last one + if !iter.HasNext() { + finished = true + return 0, false, nil + } } nextBlock := iter.Next() hasNext := iter.HasNext() if !hasNext { + iter = nil + // Check if there is another chunk to get blocks from chunk, ok, err := chunkProvider() if err != nil { + finished = true return 0, false, err } - if ok { - hasNext = true - - bm := roaring64.NewBitmap() - if _, err := bm.ReadFrom(bytes.NewReader(chunk)); err != nil { - return 0, false, err - } - iter = bm.Iterator() + if !ok { + finished = true + return nextBlock, false, nil } + + hasNext = true + + bm := roaring64.NewBitmap() + if _, err := bm.ReadFrom(bytes.NewReader(chunk)); err != nil { + finished = true + return 0, false, err + } + iter = bm.Iterator() } return nextBlock, hasNext, nil @@ -145,6 +102,6 @@ func NewForwardBlockProvider(chunkLocator ChunkLocator, block uint64) BlockProvi } func NewCallCursorForwardBlockProvider(cursor kv.Cursor, addr common.Address, minBlock uint64) BlockProvider { - chunkLocator := newForwardChunkLocator(cursor, addr) + chunkLocator := newCallChunkLocator(cursor, addr, true) return NewForwardBlockProvider(chunkLocator, minBlock) } diff --git a/cmd/rpcdaemon/commands/otterscan_search_forward_multi_test.go b/cmd/rpcdaemon/commands/otterscan_search_forward_multi_test.go new file mode 100644 index 00000000000..cc1112ecec6 --- /dev/null +++ b/cmd/rpcdaemon/commands/otterscan_search_forward_multi_test.go @@ -0,0 +1,108 @@ +package commands + +import ( + "testing" +) + +func TestFromToForwardBlockProviderWith1Chunk(t *testing.T) { + // Mocks 1 chunk + chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) + + chunkLocator := newMockForwardChunkLocator([][]byte{chunk1}) + fromBlockProvider := NewForwardBlockProvider(chunkLocator, 0) + toBlockProvider := NewForwardBlockProvider(newMockForwardChunkLocator([][]byte{}), 0) + blockProvider := newCallFromToBlockProvider(false, fromBlockProvider, toBlockProvider) + + checkNext(t, blockProvider, 1000, true) + checkNext(t, blockProvider, 1005, true) + checkNext(t, blockProvider, 1010, false) +} + +func TestFromToForwardBlockProviderWith1ChunkMiddleBlock(t *testing.T) { + // Mocks 1 chunk + chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) + + chunkLocator := newMockForwardChunkLocator([][]byte{chunk1}) + fromBlockProvider := NewForwardBlockProvider(chunkLocator, 1005) + toBlockProvider := NewForwardBlockProvider(newMockForwardChunkLocator([][]byte{}), 0) + blockProvider := newCallFromToBlockProvider(false, fromBlockProvider, toBlockProvider) + + checkNext(t, blockProvider, 1005, true) + checkNext(t, blockProvider, 1010, false) +} + +func TestFromToForwardBlockProviderWith1ChunkNotExactBlock(t *testing.T) { + // Mocks 1 chunk + chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) + + chunkLocator := newMockForwardChunkLocator([][]byte{chunk1}) + fromBlockProvider := NewForwardBlockProvider(chunkLocator, 1007) + toBlockProvider := NewForwardBlockProvider(newMockForwardChunkLocator([][]byte{}), 0) + blockProvider := newCallFromToBlockProvider(false, fromBlockProvider, toBlockProvider) + + checkNext(t, blockProvider, 1010, false) +} + +func TestFromToForwardBlockProviderWith1ChunkLastBlock(t *testing.T) { + // Mocks 1 chunk + chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) + + chunkLocator := newMockForwardChunkLocator([][]byte{chunk1}) + fromBlockProvider := NewForwardBlockProvider(chunkLocator, 1010) + toBlockProvider := NewForwardBlockProvider(newMockForwardChunkLocator([][]byte{}), 0) + blockProvider := newCallFromToBlockProvider(false, fromBlockProvider, toBlockProvider) + + checkNext(t, blockProvider, 1010, false) +} + +func TestFromToForwardBlockProviderWith1ChunkBlockNotFound(t *testing.T) { + // Mocks 1 chunk + chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) + + chunkLocator := newMockForwardChunkLocator([][]byte{chunk1}) + fromBlockProvider := NewForwardBlockProvider(chunkLocator, 1100) + toBlockProvider := NewForwardBlockProvider(newMockForwardChunkLocator([][]byte{}), 0) + blockProvider := newCallFromToBlockProvider(false, fromBlockProvider, toBlockProvider) + + checkNext(t, blockProvider, 0, false) +} + +func TestFromToForwardBlockProviderWithNoChunks(t *testing.T) { + chunkLocator := newMockForwardChunkLocator([][]byte{}) + fromBlockProvider := NewForwardBlockProvider(chunkLocator, 0) + toBlockProvider := NewForwardBlockProvider(newMockForwardChunkLocator([][]byte{}), 0) + blockProvider := newCallFromToBlockProvider(false, fromBlockProvider, toBlockProvider) + + checkNext(t, blockProvider, 0, false) +} + +func TestFromToForwardBlockProviderWithMultipleChunks(t *testing.T) { + // Mocks 2 chunks + chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) + chunk2 := createBitmap(t, []uint64{1501, 1600}) + + chunkLocator := newMockForwardChunkLocator([][]byte{chunk1, chunk2}) + fromBlockProvider := NewForwardBlockProvider(chunkLocator, 0) + toBlockProvider := NewForwardBlockProvider(newMockForwardChunkLocator([][]byte{}), 0) + blockProvider := newCallFromToBlockProvider(false, fromBlockProvider, toBlockProvider) + + checkNext(t, blockProvider, 1000, true) + checkNext(t, blockProvider, 1005, true) + checkNext(t, blockProvider, 1010, true) + checkNext(t, blockProvider, 1501, true) + checkNext(t, blockProvider, 1600, false) +} + +func TestFromToForwardBlockProviderWithMultipleChunksBlockBetweenChunks(t *testing.T) { + // Mocks 2 chunks + chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) + chunk2 := createBitmap(t, []uint64{1501, 1600}) + + chunkLocator := newMockForwardChunkLocator([][]byte{chunk1, chunk2}) + fromBlockProvider := NewForwardBlockProvider(chunkLocator, 1300) + toBlockProvider := NewForwardBlockProvider(newMockForwardChunkLocator([][]byte{}), 0) + blockProvider := newCallFromToBlockProvider(false, fromBlockProvider, toBlockProvider) + + checkNext(t, blockProvider, 1501, true) + checkNext(t, blockProvider, 1600, false) +} diff --git a/cmd/rpcdaemon/commands/otterscan_search_forward_test.go b/cmd/rpcdaemon/commands/otterscan_search_forward_test.go index 216dfaef6a1..8be27092b0b 100644 --- a/cmd/rpcdaemon/commands/otterscan_search_forward_test.go +++ b/cmd/rpcdaemon/commands/otterscan_search_forward_test.go @@ -21,7 +21,12 @@ func newMockForwardChunkLocator(chunks [][]byte) ChunkLocator { return newMockForwardChunkProvider(chunks[i:]), true, nil } - // Not found + // Not found; return the last to simulate the behavior of returning + // the 0xffff... chunk + if len(chunks) > 0 { + return newMockForwardChunkProvider(chunks[len(chunks)-1:]), true, nil + } + return nil, true, nil } } @@ -125,3 +130,14 @@ func TestForwardBlockProviderWithMultipleChunksBlockBetweenChunks(t *testing.T) checkNext(t, blockProvider, 1501, true) checkNext(t, blockProvider, 1600, false) } + +func TestForwardBlockProviderWithMultipleChunksBlockNotFound(t *testing.T) { + // Mocks 2 chunks + chunk1 := createBitmap(t, []uint64{1000, 1005, 1010}) + chunk2 := createBitmap(t, []uint64{1501, 1600}) + + chunkLocator := newMockForwardChunkLocator([][]byte{chunk1, chunk2}) + blockProvider := NewForwardBlockProvider(chunkLocator, 1700) + + checkNext(t, blockProvider, 0, false) +} diff --git a/cmd/rpcdaemon/commands/otterscan_search_multi.go b/cmd/rpcdaemon/commands/otterscan_search_multi.go index e754338a9c9..c5bdba0391f 100644 --- a/cmd/rpcdaemon/commands/otterscan_search_multi.go +++ b/cmd/rpcdaemon/commands/otterscan_search_multi.go @@ -13,9 +13,12 @@ func newCallFromToBlockProvider(isBackwards bool, callFromProvider, callToProvid if nextFrom, hasMoreFrom, err = callFromProvider(); err != nil { return 0, false, err } + hasMoreFrom = hasMoreFrom || nextFrom != 0 + if nextTo, hasMoreTo, err = callToProvider(); err != nil { return 0, false, err } + hasMoreTo = hasMoreTo || nextTo != 0 } if !hasMoreFrom && !hasMoreTo { @@ -46,12 +49,14 @@ func newCallFromToBlockProvider(isBackwards bool, callFromProvider, callToProvid if nextFrom, hasMoreFrom, err = callFromProvider(); err != nil { return 0, false, err } + hasMoreFrom = hasMoreFrom || nextFrom != 0 } if hasMoreTo && blockNum == nextTo { var err error if nextTo, hasMoreTo, err = callToProvider(); err != nil { return 0, false, err } + hasMoreTo = hasMoreTo || nextTo != 0 } return blockNum, hasMoreFrom || hasMoreTo, nil } diff --git a/cmd/rpcdaemon/commands/otterscan_types.go b/cmd/rpcdaemon/commands/otterscan_types.go index 6f62bdda5a7..502e3fdee3e 100644 --- a/cmd/rpcdaemon/commands/otterscan_types.go +++ b/cmd/rpcdaemon/commands/otterscan_types.go @@ -1,8 +1,10 @@ package commands import ( + "bytes" "encoding/binary" + "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon/common" ) @@ -32,3 +34,57 @@ func callIndexKey(addr common.Address, block uint64) []byte { } const MaxBlockNum = ^uint64(0) + +// This ChunkLocator searches over a cursor with a key format of [common.Address, block uint64], +// where block is the first block number contained in the chunk value. +// +// It positions the cursor on the chunk that contains the first block >= minBlock. +func newCallChunkLocator(cursor kv.Cursor, addr common.Address, navigateForward bool) ChunkLocator { + return func(minBlock uint64) (ChunkProvider, bool, error) { + searchKey := callIndexKey(addr, minBlock) + _, _, err := cursor.Seek(searchKey) + if err != nil { + return nil, false, err + } + + return newCallChunkProvider(cursor, addr, navigateForward), true, nil + } +} + +// This ChunkProvider is built by NewForwardChunkLocator and advances the cursor forward until +// there is no more chunks for the desired addr. +func newCallChunkProvider(cursor kv.Cursor, addr common.Address, navigateForward bool) ChunkProvider { + first := true + var err error + eof := false + return func() ([]byte, bool, error) { + if err != nil { + return nil, false, err + } + if eof { + return nil, false, nil + } + + var k, v []byte + if first { + first = false + k, v, err = cursor.Current() + } else { + if navigateForward { + k, v, err = cursor.Next() + } else { + k, v, err = cursor.Prev() + } + } + + if err != nil { + eof = true + return nil, false, err + } + if !bytes.HasPrefix(k, addr.Bytes()) { + eof = true + return nil, false, nil + } + return v, true, nil + } +} From 90170c278c51e3aca5fe557fcd282f7c4c2f5ef0 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Tue, 18 Jan 2022 00:47:26 -0300 Subject: [PATCH 121/261] Renames --- cmd/rpcdaemon/commands/otterscan_api.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 9e53d4dda15..9f90823a9a1 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -265,7 +265,7 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c return &TransactionsWithReceipts{txs, receipts, !hasMore, blockNum == 0}, nil } -func (api *OtterscanAPIImpl) traceBlocks(ctx context.Context, addr common.Address, chainConfig *params.ChainConfig, pageSize, resultCount uint16, multiIter BlockProvider) ([]*TransactionsWithReceipts, bool, error) { +func (api *OtterscanAPIImpl) traceBlocks(ctx context.Context, addr common.Address, chainConfig *params.ChainConfig, pageSize, resultCount uint16, callFromToProvider BlockProvider) ([]*TransactionsWithReceipts, bool, error) { var wg sync.WaitGroup // Estimate the common case of user address having at most 1 interaction/block and @@ -279,7 +279,7 @@ func (api *OtterscanAPIImpl) traceBlocks(ctx context.Context, addr common.Addres for i := 0; i < int(estBlocksToTrace); i++ { var nextBlock uint64 var err error - nextBlock, hasMore, err = multiIter() + nextBlock, hasMore, err = callFromToProvider() if err != nil { return nil, false, err } From ab3f69b342e572df8b01d74d6f35deab9701eb2b Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Wed, 19 Jan 2022 18:03:01 +0000 Subject: [PATCH 122/261] Inverted lowestNum and highestNum in header downloader (#3301) (#3303) Co-authored-by: Alexey Sharp Co-authored-by: Alexey Sharp --- turbo/stages/headerdownload/header_algos.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/turbo/stages/headerdownload/header_algos.go b/turbo/stages/headerdownload/header_algos.go index f65a2a1f945..d096cd9bbff 100644 --- a/turbo/stages/headerdownload/header_algos.go +++ b/turbo/stages/headerdownload/header_algos.go @@ -851,7 +851,7 @@ func (hi *HeaderInserter) BestHeaderChanged() bool { // speeds up visibility of new blocks // It remember peerID - then later - if anchors created from segments will abandoned - this peerID gonna get Penalty func (hd *HeaderDownload) ProcessSegment(segment *ChainSegment, newBlock bool, peerID string) (requestMore bool, penalties []PenaltyItem) { - log.Trace("processSegment", "from", segment.Headers[0].Number.Uint64(), "to", segment.Headers[len(segment.Headers)-1].Number.Uint64()) + log.Trace("processSegment", "from", segment.Headers[len(segment.Headers)-1].Number.Uint64(), segment.Headers[0].Number.Uint64(), "to") hd.lock.Lock() defer hd.lock.Unlock() foundAnchor, start := hd.findAnchors(segment) @@ -867,8 +867,8 @@ func (hd *HeaderDownload) ProcessSegment(segment *ChainSegment, newBlock bool, p } return } - height := segment.Headers[len(segment.Headers)-1].Number.Uint64() - hash := segment.Headers[len(segment.Headers)-1].Hash() + height := segment.Headers[0].Number.Uint64() + hash := segment.Headers[0].Hash() if newBlock || hd.seenAnnounces.Seen(hash) { if height > hd.topSeenHeight { hd.topSeenHeight = height From 31735b3d673d04898ef9e15dad47cfa4ded01d4b Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Wed, 19 Jan 2022 18:03:12 +0000 Subject: [PATCH 123/261] skip analysis and preverified hashes update (#3300) (#3302) Co-authored-by: Alexey Sharp Co-authored-by: Alexey Sharp --- core/skip_analysis.go | 2 +- .../preverified_hashes_mainnet.go | 262 +++++++++++++++++- .../preverified_hashes_ropsten.go | 218 ++++++++++++++- 3 files changed, 479 insertions(+), 3 deletions(-) diff --git a/core/skip_analysis.go b/core/skip_analysis.go index cae582b80b4..3fe05d8d81a 100644 --- a/core/skip_analysis.go +++ b/core/skip_analysis.go @@ -21,7 +21,7 @@ import ( ) // MainnetNotCheckedFrom is the first block number not yet checked for invalid jumps -const MainnetNotCheckedFrom uint64 = 13986250 +const MainnetNotCheckedFrom uint64 = 14036300 // SkipAnalysis function tells us whether we can skip performing jumpdest analysis // for the historical blocks (on mainnet now but perhaps on the testsnets diff --git a/turbo/stages/headerdownload/preverified_hashes_mainnet.go b/turbo/stages/headerdownload/preverified_hashes_mainnet.go index 8c435211320..9afc2e3e03b 100644 --- a/turbo/stages/headerdownload/preverified_hashes_mainnet.go +++ b/turbo/stages/headerdownload/preverified_hashes_mainnet.go @@ -72847,6 +72847,266 @@ var mainnetPreverifiedHashes = []string{ "86faa28babf62ef87c04d8655f79897f5ce98aa63862e616fba6ed2c42fc82ef", "6267da068e9f2987592c99be922384e22edad80ea9dcf288a71692a7b84e50a4", "d8abcb315464eb9070c896e3824f58bc20799056e7294c9ef8539c61514eecd5", + "21b7d5a43e2a10db04d0300c51241f61860dc1246f2505c9c2902792313061da", + "569235d4b5df8744752304445a05907d12463deb6afe5415921a71f3d5944031", + "5fb99b2013616a75656e9b6984f415a87bca6c4f1f1377f1b42e6fce15a8d047", + "5b569b46ae256d67399fe20aed64fe93f15e87335af9e7a2a5dac593fc9d8dcb", + "00a57797af7289c0337ed79da11a2a982d57bd4d8dc2c49683c71c8e1cc0040b", + "ffda075779f0aae75dedfbc50a3a65d001f4c0fdbb90e01f255ec9ea17c8c676", + "2d4b8222717002a8e10d6e5cf36b559a05777122c90bce76e02cc06d3242471c", + "d77a458fd53c58600c7edf7277eab863e292b2fa8b96163391e145811000587f", + "15ca38f9d22821cebc39e197c5d1071d92bf1d1b4d7286a11f07785b97b3c751", + "07fd7607d3de47aa477a44262b981ae94d7cf52d51e8c8fea8e2fd3e312abcc3", + "1102d9b39a88542c6171a314e79bebffba30257da4c050f7533c9ad395925bec", + "280a993a2f57c2d236f4ad560da660ca86cc6f69f563dd4134731b8b13da92df", + "7f78ec279afa8d475a0c079ca2a3c5d05bb48f05892faf7c64b9512aa8b9db22", + "f82550b23b11c576161e37f9e688794aa9288df31eb68a36101dbe2560989fcb", + "a3cd4213a76da4558f39a09aa38cc1a5134adb171e81db2aa4422fd696e9235f", + "1e372621950a43881e96f46fca949c8e648c4827a6f4f23cd95616c11a3a6bc1", + "7a5714c22c21e7c0814ef5b7ffe389601b7028a71d343689fa521d2459b55d2f", + "71032aaa1e0500d7848c9f824c2751feba0abc52bcec0f2723c476bb0cb5a709", + "c9ca4d594b69bc9b1f4dbf40123f790f0a9bcd7c47226ad016871f99775fb9ff", + "105c66396bc65d316ceacff988a36e42c629f55e854a6f5a5a86033fabb20e74", + "dec6030cf472437b276186882d0cc467a8939fb55f92dab0301cb547a862416f", + "eaf1d392d070b2576f58d341b9372f229ae1724009457e033048dcb009c8c5d2", + "0c1739ef182bf30b943bc9821e77753ef3f59bdc0835b3987013fcdbd71bdeb9", + "8da9cf2124a17cd23b05c104f07f835d343e27dddc4c6128486a1ef55a63872f", + "c5e26175f5c010dba1e8b60f35b4c31875d04a9a25f1f34bce9b64bd490f5f71", + "0d5d8350c827c4cb4f58976cc21d46b41431a0d5e350a7a0ded29c50cca4e8b5", + "450a5b7542d0fe33e42c602441808196f1b9b99da04c73bf575e2f14c9e4498b", + "2a2d73439cc33747aae724b4b823a97c8f145b1a1f8b4c158b5bb590adb5f149", + "98fcef317fbcb385ca00dc20d807999f23e15208bbcc35f816a97664b881661c", + "99238ed19117a3b48bc12f02d0279b0733367d655658a8866efeb55f7821fdc8", + "7692e9f5ef3b99653d6e36cf0958b11fddc753727b580112910531f3ef3d9fa5", + "b5258caeb37cacf84b924f6a795dc0a14a2b7871f6a574892e0c5b9650b54ab7", + "fa883d7f632f2623df7c398cbf58063ea652f93d6aaf187caa2f9204b4fa3e79", + "4bad5c3535e22f66d735f7035939ce3e1704fa816684d59c92868767077f6e92", + "7d729c7b847578d070f3cfacb93f7afb68cb4b9501c589e284bc2f290d933585", + "fab19f6f0e51a42d9f06e75aebd58f227f8ca0a15f7855cfe6471a19386ab2d3", + "292c3f4ea7c742af4379ae9412d53380a822ace13b8e899e7e689bc8962245bf", + "36291568d8ea2f069885ebfd05c39d215c3b03833c3bb1f4242e12d5d2ce9edc", + "ed77715f3d337db7485f0f9f247993c7e5b3cf0752ead502966df94c960b1c04", + "3ecd0b02cf4cbdace897911a5f4c6c8a894c1f361cedc7bb47ae23eb3e342b0a", + "e32430c1ad305b700374cec4bc3da3a426b299dda0cb3aa33f61a4945e734397", + "5ec0f8866d12559560a36c1ad06c97329869905e6448cc7f244ad115a7b91a3d", + "38b354d7682c4e1b21d0a5a000b2537146515011f6d283fc6eb5d57854d4f1f3", + "c6d235ae8e3ff07123e8e782e3ce050efa24b309c8b8d402db5d05337f0fe2c8", + "7642bc249d7fb6d804688d5daf5636eee56c6415c6fe6a45d18d10f86ca713c7", + "aa0118eddc41f312f4d5d16239be7e211efe5ceb1754f7e102ae495410a4f305", + "598b17593ad434fe91eddb12babf3bad58c1ccc49f0b8e27cb9ba534783d13dd", + "5762f6960f575d7ab0acd21aad8e3b04f9dfa36c92a51d1bd61dac4e12c3e851", + "3e68eb2df63122109ea27759f1a1ef78115ffa3c3740c2c305b8b34ddc6b734f", + "45a0eaeb68922f1605c53b6fbf540116e31fb92ec46a0cfa7b87a5dd6cde5fc6", + "1488e88eb1cef5481297b45d92e85d07da97fe4483a343bdf84f62ed99df1872", + "362df2446be5eecd4f5ea6356b4ffbdca62d92b396fe786822493c352990fa0f", + "1b4b737247470485a5f8850afb1df4c0ce28cf832bca78f024726dca1ad388ee", + "1b6dcc21b4d6cbfdfe1df520021ede41ab81f6ee92d21ea11e3883cc6936d58b", + "a11cb5e62d4ac5ae56a9ff1fe9a07791d963815e487562eda8ecf9d8a85bff1f", + "0d0df7294cfd8a6aaab363205ee38a4e8312440969b3c50db5b1452912c474ba", + "b82b8ef6b7723f30b01d55e80826cfc5f83f4f0b734e4f78c399e94d1a5e0f37", + "c0e52c426f108b7c54d0e8cad344398e38522c5c22f3922d71be40c7d807702a", + "f86b6f0e183b5bfba5d65f789996bedb7b1c9600dd8517d618aa9e193b39aa24", + "5b1dccecb79d87aa90006fc4752f736648d1d83192f52f40cb7c91dfee140ecf", + "ad8d7b874ee10229257ed098b57407c7a6d1673d38a51acfec128cce04c2a41f", + "cead4be5cae5eab7217dbcc47493182ded8a5ba274dd4c13f8c65417c0f6df38", + "2e174aa0177fb345f50933599e2f06ff9f0644bc1c9eff7c37b37cf7051261ad", + "79c35c55f4dcf63e4371e7886a1a1dbd9dfd8bcd64dad1161e6f499b5a7f5354", + "29a9db07690197599a358b206c84777f9e34d094c8ab19f9d6611360f6166230", + "8aa5fa6263cbae724cc2ff292066808dcf03a73d602b2f09e12c427ae6868f6b", + "cd44b333a627abedc3201a630ae6679cc21b45fbed2679e5e7e2232243a6d161", + "1f843a774dedfa1def50c6d51bc82cdc18fa8b187480704f92ed39ae60af5269", + "a781d60976b5f08389d8100861750a7ca0acffe5c2bc37d6c128b531efff067f", + "0516bf8cf1520bf1d1e08067571f7495526274fd1b8b8a3236524b95a9de5d2d", + "c7eb42d764f69f10a19d2152704b92fa4f9e9778fc21f3015e4237dd681df0b9", + "ac03ff5ffc1771e4c7447d6747298e168ce2a47c9908313a636f6acc9446647a", + "5d5db1531abbb51ad0d2452f6ff0358a417ab6f568244a2ea8438d9e2de528ff", + "bbc51ec99111c8059f5e54077683bb6027a4a684c7dc32bbad619866d977b12c", + "e540b07d7e46721a62ad89d56b89adc2e48b83cf99aed6742aac0a5070d5197a", + "a3c94cb5f71f090e25d43af695a13c2ed3708120b65db59696a9d4b942de9df3", + "329b4feb205b5e34ce809083c5efa1ad334469247b94a79824d024cd11761f7d", + "d154d61665ec2f919218d6beced42d07f263ab5e829d039ab3a769bb80c5e8dc", + "d23531f7f619747834fb813b988922d804ad46625faecf7167cff91ee060caca", + "dc867e8add69165f66826a1c65aabf87b66e27d5f4224b9465452979976d1d68", + "c01c56e837bfa623c02e9af8ba765d5c461912da74ca640b5d735608f8e97c18", + "a34f9027b89cfd83312e094da4b31d8804a4b5d6bd2810379eecf670144396c0", + "6cc78e36f63713c663983d9dd60a65f3b17f001798a157e5822b3e58314e01ec", + "91ca02178bdea33333fd056c21c34c065ba4904a0f35d31e765d8eee6f0ef748", + "b069f88a3df194ea5ac51ba1858565350960e635252b43ad4f8078cfb149798f", + "0cc287fcfd0d8859cd5040ab52509d749f281a2a54fb90c8c00140a461b4d188", + "e7d91eb920a97770bee21b2994939304cbe6502fb905eafc5b7470e69dcc0c95", + "2b2f166d8706d451acb7971a15755e8b4db7dc268386c6087441d4e7c17a5e40", + "656bf6dd7cd8f807a71a881f295dc72895ab60eba1564974d6a01213c1a26cf5", + "8a9916792dae6785694b8364edbb1c040391ba1eeb8d45b3a75e8c66a6c27cea", + "137d400b86beed8808c05f31347e491080728565f7023db0a7745d1ab1002356", + "3acdbab2908b5caa9ca9e65004d7d9d5ff11e0fc26383e41f9f263907d773cec", + "b09f10acecdbd1a235cfab0944aee9c75f3dc3c2d08481594a345aea7ef5997d", + "91ba7f2535c758a64c029277426534f5d24b99b19746b9cc676f075ab20e5f8b", + "9f87c63aea5ba973a9c8038f1f2bde9911184abf3cd39fcfa01a78a4a381a890", + "1c4204bc14b14ab552ef29a407dd5f59c6e1a4a20ee8442d3fcaf2667af547a5", + "4cb98bf7ca06496998040bd12efb5f4c23b6920423658329cf37cbe7250f9283", + "3f711e5b1be4dded4d3b3a11b2ceabcbc15c9a33c50d4fc1fd25da66d1c64693", + "fccc90d9aff7d14fa9ba2ce6788845b7dc008554a4131a4e75c0ab46dc7adead", + "8337cbf048d329b64494a78cabef7e64aa6cba8895318dc97909dfb142a7fd92", + "a1588e72a0e73c0ad344db7a7af30b02c433f5b312d8358852e8b96c2f38bb37", + "eb4b62f3f195482d675b027b4f1d398a8e55eb881ec1070ca232ae3af21956a2", + "b71fecb183b13e4708c2d4eb4a1741b0e663de4808551402930fb1dde3a8cfa9", + "2d443df5e7da3cc2f4452565b0f3fb1b904903103b308ed1464798c3eb24f25a", + "ea589db1cb902aa9d9d95257ca0901e8d3b500d3182c625aea1de91c29114f61", + "37441899283e454ee220b95f755b3ec5e7c12025be5f2b6612edca46e7e8e182", + "51eac432197a6c51c7c932a969b08c8d4e922baabd1b57df9332309f96208bbf", + "edeac977b5e8d92165dbc3c84bee4ef441401424b2c31087ca6521f49e6a43cd", + "8c1f491cf14e2a5e5ce31531147bf5dbec93a92ab920170cb599d0d981c058a6", + "f537a8fb8f65a0577d85aecbea5d1fd9b44207268bb8cfa97152462c243bbba8", + "e0919eb49ee667bb0d1c03ada4ef74f6cefc8d7e53e5ed2904da3c00d0225358", + "27fc670e057a4a39c0892feb0fc18780282c8ff8db19b48e4000b208c94fce51", + "a8e8047616f8e07673352987c00100bf9e73bf0df93af7cf938d50ca5f808a61", + "db33cab02e3fa0fab9e6be24afd921969a4a31f6e8ad020eeb94c52844c36511", + "9d494e046ee7a22601a0ac99d362dd541b9b4060091cb95516069373be30d047", + "5ad41fa3deb36704c79a1840ba3a716d088f54048a97a2ac8547c54c349bc62c", + "c474258a1e13f655f6d9247417f734b5f27d6321280b50d9a0001871045f421e", + "e02cfc13e6c54e8a967f70c08bef2a10977b3ebb4af193424a3e3d6f5132cbb8", + "6c76b407f470d9eef01785f689a101159a20b1f6c1ca8e80cea156e0a44b7969", + "3e63457ac330d9806725a92a9ba7d9a9412f223729b546fa4614d6db15a683a7", + "866580849bc19045e8141ff45f5239cd96245c1a0a8cb6192de78a9253672536", + "2efee52999228ae8267aba7cdd2af740e3746b0a5b6902cc8f599182aa2bc9c5", + "948797e50fb2cc8407ebc00239a1960194f0f970e19624f205aab13222cd74ce", + "363f67224ea752160c221658063b78d272e17d979f17556aa8bac456fe4262fb", + "2dcb65ddabe063a93c0b8bc0fce9e384e9a9acf61b70fae287d9581977830df3", + "d27cf6e02d82e5401d165635082e909f0d50b3d1fa0a16b113ccc79bf7afdca8", + "be060d25605f1b8022c153af32ebc0e7af03620dc18a11ec3150033923a6b084", + "800485682f6053252699c683f507e06d9c572fc18dc458aff0722254661173ff", + "b61e92f48f1dea7e6fbda10edb74bb3070566d48e9822bed6c46c5794b38fb3f", + "7f5162cc12c88c2dd810f33cdb5f32e04c37c2d6ce73a817a593c2d81439a771", + "98d0ea98b1e7252517bd27244a2b5fed729ab210bda4e2142668f2ac7f9373b9", + "e373029d55eda14b86b2eb2d9fd10e7dc339323ac8d01b25d64a265daa040782", + "ad5eb023a5864347ef1dbedba76d8776810caf9ea0c054d65271c04612a2eaea", + "89cbe7604aeaf5542230102e29228bcb788e4eee1aa864503ca3b23cbb1efaa4", + "2eeaf8bb37ed6bda47299581c35c30fc38eb62585052ad4cbb95aa221015247f", + "cd5adbb38b27a82be727231a43bdb23102db602eaacc62933f9840f5b39a66ac", + "b0005a91c86462e6f58790102ef9ab0118cb58392e4dc7115ec5bc61afc04195", + "c90833ea125216757038e6c139ed1bfc34f3d8f6eea31fa5ecc331c52276c4fa", + "8f4fee3b5b6a9f9e95fec4988fb03ce0c0332a94c3adaf67931d045151de45cc", + "fcf1441b7b14891f24391ec978e601396b3ca30bc6f7b9cd871a7a67ead47522", + "dcf4e22748275963f4e2492ec71f8b05e490eccd70ef9268ffba90d8bfcb899d", + "00045abb577d6559c39d3c7b344fd73ab23de4bcec986564eb29e8678de4e250", + "aef722389e52d127ee386583e6b81b2d8cc6ba64667251eda618aa689f69f6eb", + "57da3609a3bb23c1a3a19997c3e8efff07a080020c151909d76c79483c9a900e", + "52b5734803faec0ba16403710549c5c21c739e7cf61d5c265f477c20247aa11a", + "8a7f85e458b06877ca6fb65dcad7e2cc98e335ca592218359619979ef02ed172", + "16f1664988472471830d82e7131781e785644fe0a11c6461badf3ee4f4d75d42", + "ae0f849a505bfc5e2d8bb602dc4af5052e10989160e34f08cd920a26a41e8c46", + "edeb976ac051c8f1a394f424d7b86d088d95f22e9890d3c2fe82f41cd21c22a8", + "a6a7efa1cf6316d4154a83a52ecde5bf5702a4cd7092c0a45611db7743ca06e4", + "9a64f80962ffde53ed55d9841d249ce2fb253585e2b5da30fb4152c222c1c3e2", + "9f9f99b283db83fbbc706959b48a1ccff22d8ed2c57be0c38627d764ccc35980", + "6e02c478b14bba6168b46aad565e445423e1f8c22ce9878dde2bbfadae628bdf", + "3c89ec2080a619c03a7dd4f2ff655c4d79789ef72fec2ec0772f8b27da020ba3", + "db06cddfcebf8cdca5683087b9b6f6b2c1f0e5558e182559ad8f1992ff25d2c1", + "3f53438048d60c73af5c546b36a27e291bf18c1b3bdc574815dc6b7a68b59534", + "789a25dfbc46df2463717500f53a9405c89c632ed128468d53bd98fed4b716ad", + "7f22c299f279fca70314711ce607619455b2cd10525bbaf94e94586e445b58b9", + "1242b43c5a38e7bab6ec6d0859ae81deb59d33abba11dc8f0bcbc525b0312969", + "65c97a4b45ddfeb4480659c4b44a3c5c79d0cfa1ade09169fd231351a001f43b", + "f7d8babacb3b6c3c64264e5f3f2a42c8fc1b578f311658085a62b8a32bdced8c", + "4c54b57ffd8e812e3fe3fcbd230c841b5bdfecfe70e54bfbfd226c7928e06c64", + "2b86e99292d49107642e04023c05dcd9477259785ca623cd020982926e8689a9", + "66fea6e0904e7f90721b2cca7fe7670022726961c4293c476f2e0d37c1bb133e", + "40f83bd0694adf3f1e6ed31f3a2b99b57ddb89b0e90d18f30509d3f296dc2133", + "aae243a522170701759cfb317df0a613d4c1636db980a59cd89a2454fc51348b", + "b6b66a20575caa442381c92b32851b9cc08a9d9534148cdb89733a6145a865ab", + "41df246515087332fd4f92fd662863576880b7078aa8b2db1904cdb54035ca9e", + "790c20edd67486c26691daa2302e5ab5d9af4d83ac01a6abb24f50b158d08962", + "b13e0a9406a2f397d48507e6265142c137140383c9c8bf08851a8d6a0599f715", + "4fd808b3db696da083bc25359eba73450fac30104df949daa45fe4b774594c9f", + "40268470e22b967e069cd0fffc87bb9ac164d8c0f1bc467ad632de356ead1265", + "7aab94d96d351917012e723e5bba25f2c987e204d6c934f08edfb72dca73db6a", + "b6979e51e542f3c5f4a3e2a5f8faf2431ef4f27b77b1039671ec5cd8b56ba6a1", + "7bc1f2b75af34ff4077ba4d73ed16e73d0c2850993ca8a84f94915198edcfecf", + "337dce2e210040a1d3ee6f8f064702582af501b9cbf4c4318b2a0f144d839710", + "f6f33b15d8c9ff32ad817481c604150d6e095eaaecec68a8e141d225956851f3", + "a2697aa71d79fae1780ed07e14819f27474fa812ec1a728557a6f2c8b0c26596", + "6261c1b4393d9b385f914a320de8bf3bc942af4cec44048a55a76d4487a49d5f", + "3771e0e43360600d9fde0896bef3502e93f659db92ce510d9662219fbf704a15", + "53ff3d8213792fa21949fcdbd7fc809e7ebae600c8f4b16ddfe64c126d80c40f", + "1cfcfc31e8c0477bc97db872ead5e420b5bb6f537091f2f6800a1021b895f0e5", + "cecec9bad9b920e064443edf6ad8e107bc3d630de1f3d3834b5690636282640c", + "2f3988eea6c87a0e9d056e52947335605d41ab70908e4fb81572d6d8c69a3de5", + "65434408ecf08808265f8df5fec8afc7bcaf46027c48d8b0ce4eccef46fd0256", + "4c9d288681fec9c0ffee725506992fe02bdd8223ba3c409f5b752a90240d3b97", + "a7be57a51e404631259db70425cd9bed5296896e42807f714326f88dce648783", + "f4c0c57254a5a00b1f8aa1346b0e6c4064af9d70429d6bedc87f59a667538071", + "0c93ccfef04f7796bafbe89ed75b4e21f97396de36a44de6ae5d343293b3937b", + "5092459b361485c7bd473c926aaae59518cd55a96d0adcb3bfe07f9169218076", + "5f1438f793853db51a0de71a17e0d2382da0e6f7859616b0fb55c7d4275c75ab", + "ee9051044a6c3583b1a75c23fa37b4a480df34717e380c9071a73410afde8229", + "eb901022177ecf6d3f449494e71d600bf1082f8deb3624d071e4a8e0f0a0da76", + "e3c5af2132d24d958aa9e6ad61d557988136e0f4b62159d675fe6dc7bfbbd57f", + "8a21cfe54771a401f3344a175edd6187f4a7bb99f0d8fb66dfd35bd9421aa56f", + "3a668ab8e118315f65ee83e06b162cab7b5dfad013052f5643b9a797bd33bcb7", + "49d0c5fb6722c0fa09a8a84729a7346657671645079d882f856900107900064e", + "b11a569704daef363614f1619c6c33df4bc62c8e49a863d87d9cc65ef085c9c5", + "7af55f7c8fb414521af761ba2deda67c00d1312fc88e805c909803891c5c61d2", + "e727cf7819da8e03c72254227692222daf0ae2243bb29dc8f7c9f12f86e5753a", + "d5dde32e6b1e2d2ed809b0fe754a8de2c00df8b30e2a11a153fd52e1e7439f4a", + "beb8a1f7fc443dc230e12b41c8076c31b0aaee4a1ff90565dbf2632545c497c9", + "c3b918b9f52fb25e8346e6ed710bfaee0a932c1ac72e7167ef492ef409aaab0a", + "cae14c724524520c33ff3ab58fdf89762efb2376ce73080e4ada40588b3c1e2e", + "739c0353ac72bac3152015e9f86c9a1596d98777dda22c27aa427a6b94721f94", + "78f62518bdee561971aa0e86213d2fbbaba0735521304a3f7e05654316218281", + "eb7ea287b1f6e88aab1291bd14c093d26dadc016646d3c2baa4166f619604408", + "2d76cc1580b0c9a64d601d2970de33297a59826762dd75005d44bbc5ed342132", + "f3304b4e36bc7c3cb46e9679edc940023824a78c576737a2ba632846f2ddde86", + "813702f0e9361f2765330fd4f88badba46bb6e206813e7fd6afde5db10087fee", + "54a4d748ab2098024f62f710137d2d74b16c63016dee445fcc691df936685bd2", + "06cfe80269e4c19e44e7d72a3c7be26ea69e9fdfc3fb650064ea083b17e123d5", + "a78de226d51a2cb12b4b48bbc99fd4cbd99f4820e4043960adb8f3bd2b107803", + "277281e140670890d8ccfdec044c8b3fc282c0493575e8ec252d38c4c599d65f", + "e8dac93f7b610b1e4a26581b99c5010515784186dff0235b650a71bb0a31146c", + "bbda75db82476f95784e78d9d464031211a65f00ac2f3de333f78601ce59f4b7", + "51e489eb538d7aa9eea1890d03620cbc0937620ce20df1da8b0978b93a21ed8e", + "c3e97148442f2895b1a0d89dad6c9b7ac46069226479afc283f7a13608962f93", + "cb37d24be4adb4e878d7eddbebe783a18d4c23e1a1cf9bbcb2129b1ac259211a", + "c854d5dccf575efcef8c07d56190a9afc3cf3115582680095acc44d5575f2505", + "b618f552cb2729e64f4a54cc43068c8f09efffd7314aeba69c780a86cb66f4f1", + "df720834fd643fa0c52f7d0b4d42bbe0a385944bd42bace39d4c756ecd334c14", + "935920655af05a76debe56d3fc9eca31410ae84f987ab89d196e93330e1901bf", + "0aa2461fb92634de5157554884333aaa57f85a0b240b6f6b88068ad99ffef9eb", + "7966d15f314979ae702324b4bf700527357509c4e48b97d13fc18c2a8263b94f", + "9780da4fad5a54256efc362fb372b18771ca811a03b93da2a1f01b789da41850", + "50eb62667943281001ab8de47817d174fef2cdee018971c014930b80f9c5803d", + "184188678473eee36b88369c6f3f7d7b49c70f1997f8269b10a71933aadd0b7d", + "a02e49ad394bd9716f4fe9673083125b3ed46a0000c9f2609079e82ec1c1e996", + "8962f9de9020e41e3d2e58bf0c8a011628d5b40eadcd4c6270ef081ccd6621f1", + "8838f2764091372bbfc94e51a3f3347a75876058aea8564ab60f7422faaf235c", + "3022a1552039d70c713d62993fcb5e960e2db5347c94da52779bde3c48c98247", + "911f7fc7bf4438e850ac16a8ab75e2afb9a22607752b8a3f3b75821468a8bf4f", + "c1b9f2b4415b1d19308b364dc2596ac6b0532c3a8350555acfc0cdcf4572fbe4", + "1fe15763ec7a8238513bb51d19d0165ff484d22cce48491e25e156938404538b", + "a6c093de9359f5e010f1e4d2bdc348e92a5ebc418f5f4fe797091ae4d4ff4f88", + "05c1253fb5dc16b1c3e42b06225fa02fce8b30717104f0ba43e5609668b22f3c", + "056682748c313e50c15ea85bfd94c347575045cb7e590c8e19e358f1c0e233d6", + "7c560cedd6be366f4fc0870fdc74e29d575450183898d6725926d6381adebf45", + "4afc82da0911b148e5811573d5a85eb6e5ecd623ceac349a36009f52a83c9390", + "5a43f8590ca87c8cb37f85e141ff66f9880810c726ca6f286c8f28ee765eb231", + "f59a825f8ee723f685b7eb182850f08d2bd862482fd603942336d715e595b834", + "27b242cab9ae3b2e5b37a57d4ed0f75134b6f66d3bdd5ff5fe32b7af0e75c269", + "77a23bb458b8f11a3b0ececc5b7f8c37616580bc996e058f0afafb8a5b5f2aa6", + "222168dab3e45360789ffc417c45727d311dd57021f850602af208db441fad1d", + "5f94c78c6f3ba0000b6d042f6d3c89ef3da34a6d57d8b4973796518d33403e3f", + "544df25ce242934bb9b208b3421f72b426e28e2e6d007c35a1bebf8f78e5b7fe", + "7dcb9927d6de2c2f014529faa14e467136bbd714aa0270ddf6ffb1df2970c299", + "28bc5a89cd44c90fbd23548823ab6c0cc9de0850819294f7dbf321aadb613aab", + "1d0ee714fced8ab63db9ae1ea12d0d9802dd318660c7684e74e4dda82b31aabc", + "59e31d857fb663fd147224f021757cff1eb3047017d7091a878bb72dceb470cb", + "53f659fcee6b252b1196c6e109afbdfa8be48aa5626fae73a99838227f8a059b", + "fb365f2c7385571727c3ecd803732b9ec9dd29e95e744e89d4eb9cdb59a88bab", + "cf57865aa23993b41c4b0704c77473e451f5024d728e40ac14b1702d1ce456ef", + "1b0c460144d02ef0819c425adf28bdabcbec6b504afdcf8cb10f85f01ba6c632", + "e2e98bbe408df76a768a7969d3916ee670a66b98a2b9f6717722eda0f7ad28a0", + "d322bd0b4a99f7bd7ab85e70f8e7c6523299a9b1c25e4d356638ba8d084ce79e", + "aff83db12544220efbf6214a36a87712c12054c178ad4fa88f9e5e2a648c2d04", + "1766202ead4987c16752798f80a55b49f5b48ff7754393388d7dc04366526c2a", + "51f2bf9dca17a5b8d27bda10e8e59983324feeb703497cf171c9ad0dc6b13ec6", } -const mainnetPreverifiedHeight uint64 = 13986240 +const mainnetPreverifiedHeight uint64 = 14036160 diff --git a/turbo/stages/headerdownload/preverified_hashes_ropsten.go b/turbo/stages/headerdownload/preverified_hashes_ropsten.go index 56f0df1bc69..bf87fdad6c0 100644 --- a/turbo/stages/headerdownload/preverified_hashes_ropsten.go +++ b/turbo/stages/headerdownload/preverified_hashes_ropsten.go @@ -61461,6 +61461,222 @@ var ropstenPreverifiedHashes = []string{ "c13ce50cdd3d5fc15aa32586a12eb5861124ea118c09ca9f8a70199575c2ea60", "1e0e685627b7d4f8f65844a0a54df94d77773e3c62c2cc3ddab38dee209d1928", "93e7251a72bc1525fe71ecc47aee0245c7d05a374b9901251477d8d133e0cde6", + "dedae1e554e8dcce24a8029e962a9d0c72cda26e617f2a4e8779ffb255b812fe", + "b79e47331998785f510b9e02fc48a4efd9591205798a20728f67e510ca11301c", + "48fad2813b2f1fbe8f6f69a696a78245340cae0944bca1c8ece6559898b0d1b9", + "c7d4e9b55cca88eec3e979c6a2e610bd413593f5fea2efbb7e5d37994569a688", + "04513c424294cffcca46242fdac6c1516f154ec9b7629ab0614293017ec961ee", + "4f42f2f4d3a2567c7a67e202c5aaea39c2adeb47229ed79acb6135ac1a15cca7", + "48f97732df775f8839ce61b261de0445c41e73c6757605c2558aa1bcffd045b7", + "7b091f5674c98f38735ce0ac09a28487317c49ab36a5df84f5762cf40346fb47", + "055abde6e401d0424cac9b16892b46b7f2741b5729537e74a7e73a8150c1538d", + "f32f5ecd12f288c25e9d4ae7d0c3816e888fc27b92323a40eece39fb1c5d71e6", + "4b0fe039a7fc95a7cc53aa80d608b3339ea0f33d7f59b9e7c6e50c5934f681a1", + "d2ceeb89fb3ca026c58709fb28af8a1a35d06fa9167b23137445d32d1c7b105f", + "5571b80260fdca7f6539f378c5b025e707c8b55e5ba73e6043f55a494411bcb0", + "cad6f9c05e9e365cae8ed1ed3af14afe5aafdcbc110a405de7174d8127cc5a66", + "05cec69adaa1691f9626a98a2984215270e9b44d8035951245273fbe411191e6", + "4fdd807c142af508d41918b28fad25f6cddf07bffb41534c65f04ee9ee364966", + "b0e0ec0d78d6d30469a7eafb05402518e8310214f134e6e004439d469929581d", + "64aa5e1a00bd9b4040fd28580a7a4c45c37c7d7ebc37b3e17797c6f64415a239", + "f71653ecd15d6f78d541c36c9c2ed9b9c2c745eaef389902c4ac4edb3e706525", + "122edd35e51417bc1a0400428c5f52ee8da620d1d560a9c47d7dc6c32e5222e9", + "aa4a90503ca1817869712b9e5ce0c55d136bd8e9f0040927ec7275deb2e45715", + "a387de4a930be22a08c20b726facaa04d05105838a3a6ff619556f986ba5026a", + "121788a22b204dd7dbb5c804f145324543531a27c7c49cde2cddc7d8c051e3f7", + "32b411431c4fb48d25c78e8a0837250bef20c74094a1ba7e39764f7d6c5ec4e3", + "8677d74c5f7de63b9646808808fd11b7489df084b3f484722896ae9ca17e3bd8", + "b62a688a1bef3844f168832880b983bb0240d39d2ccb04c219540daf6b558fad", + "bd39361749204f8e526ed60f0a8cc9b16cfe15e657d295187e36a34695a79a54", + "2de2e6c31cf03783f16042f83c6bf3fafa49e55709729c9b3fc6fcb87412fac5", + "fca784ea10f2746b0697b5aee730ed6b91f8b29645cae9d3f275d9265199392a", + "bdb66bb82d08e63f79ac9232f666f901a146d097c44f2ddae064e64f430bebe1", + "066829e69e3e38b6e3b87b6995d0a8f98b0f25ed3144c0dbdc1358067dc2ee66", + "5656eddc88b320552075fd93362211b159107be6f7f425757cce696c82486964", + "9cd64c10ecc361797b2adb775aa51894e0900fd5f5f128a5af40a9cc8f0707c4", + "a4067b9883116519a4cc1bef9a55b241fa508b3df485399cfa29c09ae83a3df5", + "6410c287a118dca846841cec1e4408d197f1263373f9197748e9026b0224ca86", + "0673fc6b2945d62bb1961006df0828a6598e72d8889c75a39b70bbe65d799e53", + "8ae0f5f172e58b6f7c05841269474cc675bc2ac54dd2631fc9d5d5b9dcbc53f9", + "315d1df9b7b885ddc6774651857941b443d3c0be5eb8231e187cdcea67420cf1", + "e031034235e939ce74d59aec7fd36e74fcabadde5183d3ee736933cb9b84261d", + "f79a89114dab86663f6b47b56d709f763cd72ca45cd7ca69dac3a5ae6853c99a", + "96bcdac1c5b703344c0809a42103a335a805b73fa5937023be927dacc063bd45", + "b90e54586c164bbbfb7f3c52d60bc3080a4edffc6ae509ceaeebffcfe71e485d", + "43224592f083aed6f460268cd093323633afffd77cc28ad2f999601bf62750a4", + "697df3d77b18d6f2a73fcac7a7b9bbee679cd535e546c8fdaf109dbda09f4609", + "9c2a41a473a726b95d3be7c7a7ee0eccb0f986d85409203a4c0af611a310aa5a", + "bbd026d1108453206285f37c21687bd1f78d63fae42911fba6f738819906f584", + "2697a4b7e90b88919f8c2f5594a6d423f70e039c79a33baa122809ae0797eb6c", + "410b50bc6ec7d883d4da03c53d4a4d9e2a2bbe4d8d36f6faefff82de2b738b00", + "e8524491a09a02e97640ef766ee2707cceb41a0df40349fc68d530133b2b1cc8", + "12091d81e8e264dcf034801adb4416278638f5ca8d6930e5c365fb25cf21d42f", + "8cbe79c655c42d220838f4e906990f57a15ebb623ae92d10e3d6de1f80843b57", + "d1264ec629c7c3a8b0a7f545726b2e1450c2545695edf0189672568d33261cb5", + "348ce169abd852fe984b5e8eb61924aaaff0958ef5800d83c1c413424b68eaca", + "3cec54b5689b99e5b8db4562ad7b1f79d0a47ee4c33cd90c2a2186eb171979fb", + "70fe86666e027a0d4cd9c051967779bf0b8b9fd14c554e01a730443761b91918", + "68f7c1f977e81eaf98f03eccce02ec68f560d1d365d4321c273d217180b1d62d", + "b222a4b9f8801e08d186ba04dd44b4c376f3247121130b77c12f4e3d132535ec", + "ad5ed9fdf029fd29f59f68d1022dd9b3cfe49af0a3ad797f876b5e41c62d5c63", + "d6bd59cc29d11ac6034b318a9f3d2e8682789648f76cabd079e61eb65bdc4fe8", + "0ead1e29fcf4b92f384b7436650ef41b842640e2125dc85270ebf573db875a92", + "b33ddc145adf6671bbcad6266e1bdd86774e66ee457413194aba7488a4563b1e", + "acd290d204b228bddff8dcb55f2f3accfd7777705618c2e157fe82926c9f1a35", + "88373d18b46117d2e6a32c17215630fbee7c9b6150123f7dfc98f93cabf07053", + "f67ca14c9e751414377e920a563a0091cac47dca65c01aaa7188af025db293c7", + "d7eb41b31d194b6e7a7ac2ec229edd60c3889e7249c384ed6a7bb68ddfe3844b", + "707f767ac524a7b2ab2ff002d36c90b7baaf83712186d3da03d8812be0d29763", + "c9583a11031d9a6a4876e46100314a7ce9caa547d19fbba20865e4717582a8d1", + "7873894b4c9a6c73beb5afab164266fd7bb9e1b9c41257796873417ce1d584d5", + "89578e2fd1702fd50b57d6271085dc58745a239022e5a3557a2d440c2823ccb9", + "70030b583b5dac542c03e2eacfe2eb71d3501b16d8fac95ce310cb5cd07a59b3", + "e62032b9579ae005f49120c7e8216abdd623fa53bf8370585f961f8b91fdb1be", + "aa0d23b6151f3ad4f766043a92e96cfeeb290a5a2e24b532485d8e9a8a9b4435", + "682897eb080497ac5aec984cbe6da5a2ecee79ca1fe6aa2173e2e9c17a6c2f18", + "ce9cfad4c26f1125cc67c371a4aa811f2d3ff5bd78d32643babb27f74b431ee6", + "01e09d4ba1932ef7e6d247262c081b57cf23bb6686e46d16a5b9955a82af0080", + "fc855944a7014ae664618cbd800d62b62d4e0e8de985d9f0feae10fdd4b56de9", + "f3d7ed5f3ecfd1220be22ea513b60d956ffd59276ab498ba8959b368ef44229d", + "1ab879bd30df0a6fb32b7eb65d7e9292fce27d135612320006b2c3c3f6244835", + "0c17fe51396c586577f5d9621e724b14195450a653016b01d541632315868603", + "fbbe98fb3b27abbc9d3b983bf9221173a8c0177292d0f6a31f854b59309b4c7c", + "2853ce8004ad3511458873b7f781a98d34c56c3c5e732f85ffb054bc5b7219d7", + "c615c5a9ae5ba86dc2415230df417db0bedb22b55da47a5ece4a4cda19e92d5c", + "c58d2487db21edd622defc67d532958b70ef00777152e4c341e28572b31cd82f", + "ae667516e0ccf4da1f1c0920fe59386587a79f6052c4439ad53dcf4b9fd2eaee", + "7d2c8851607ce4883c2d6ffea7b18fdd755bb5ef400047cc549dbcb7683cd7a9", + "80e6278e6f6cfa85d6c097ee9d103a300e908e137e72a88dc47f201eff3821bd", + "5544c77ef0b2721782943fd4e0346441f1812a4c94b315e76568d6bd4560ac2c", + "0c6e9f1ba31899f33b42b111a7d1f2337a4d8a01f08723ca999e6ba1a69add75", + "bc9415c6d80cec1e987d1c2fcf25551a9cb023ca3f30fde51c7a613706154006", + "5748354f49a73953ec4c3e589d8276e7390a93160b43c6d859c383f8a3625da2", + "7c35198403f72cd4db9ef6c84196fc523c353fe4e9a4c76aea8dff3139e07091", + "00f45aad57aad6233405d4d1a0b9cb4401661fed89837fc7203a2eb88314645b", + "8e32544dc23ea39a501b116006088009fead7fcf6703311e930f873a3ddc2ae4", + "26e04ec719f826db08f03c03547e33be8a3c82f2cbca6ca4697d01af63d53b63", + "7e24667c27913574bbc0b8f8aeeb0f8edbacc605329d48c8b11d87290a522308", + "6aefaf3f06789ba6ed0993c1f14c59d1c07f014f19bae70233c6ef663696a41f", + "f800083966b9f818e03a11fe28ec3222a365af816b6111de61925ce973255c33", + "593f978e2b28ba8fcd6985818751c63e7edf9fd52319071ad36a0a894edf89ec", + "fd0d04f2a9b5077005f08dd83c7558d1fc9cfd7b5ab4cc908ab52735b366b4f5", + "98977e30c27351126512be94263e605ca83a179a9ddd19194be5fa6bec2a4f59", + "7f883519cbbe77d3102488268af354fd5810ef79e01074c6ce7db3dfa389ae5b", + "8680bf5f75bfff64171b528c6b4b11ee62539ae8a07dcc5c10a1c5a6da36b149", + "10ed010615a0abcc99445c8dae4d23cc462594630e9e989157f3485d2ad3d146", + "490c8fd0142ab9098b18b2ffd30fb526b1fc74a01f89fb1efb492f8d2b1aad2d", + "f79f87c5f698aa7c7d34624d03a4f70ed3ec6613a48228012b4a14c22a694485", + "451e6135521255ceade3b2007801d2ad0f52b332e424ff84f824e468c41e4f90", + "0e281fded68c0d786d267a65527972ea1c372c62c29d988af5ceb2e5c66d6dbd", + "2fb1499ba6625b2a32c6617631bd2719a8867ad03f01bdb9c4ae1f3acb0606a7", + "b23d3f16a02d66d120a14b25d30e5a75124fef213277b9389e445f2089f11e74", + "d8444e79b17353a1f4febb976e929cdc265af98c8869e34241b7ce95e36190cf", + "8d50722aae4189182e1ab1b273a2b1c04b722e01c95ee48c3d9472e75afafaec", + "5be8f4b40b07ad0b602e89f0f6c780a62ce36b1b5097b71840471c6216d66098", + "c9c88b5ab85397447597590e4962061eb44b6e227a89a126e6ebe2596bb7e3e8", + "aa994eec4ee1be330627222cff0a758ac6efe04c200141e4b3a77f29501b7ea3", + "b932dfaad020f3e0c6f4e4fb24fd921c4254a3d52108d6985ee1f8161b146aa5", + "540d3e8952972aafc36bd23e47d3292aea8e3da4cd48cd577eb3114365df57aa", + "1d433673a224fc9ea21b7cb8766d4fe260d440f7620df27e5c6e2e0401280c7e", + "17bd904f5c62dcfdb1c295b512acf0c3bfc9b59d570549a0525c24adb0d6b642", + "a978543fb959bcbe0a49f0d0a7e0dd9bd5b4717e6ae69fdf22c5748a2d2ae996", + "d35367481d8b9039ba391b11f7c42a3bf06f050d3a0b88dde2550f8b600ee026", + "5559572ab65dfba17fd61bf431dc55346f1d39b5332a360645294967fbd0ef4b", + "14437566651f55d5cb49cebf0135815b6229dec5bf0bc323dd16d8998abab86b", + "783b8fe5bf114282dd4de844b76b9d5c2cb331ff1e058a09d353d157699156c8", + "22d771d606808a2d869fb34ea529816871991e366f632cc8bf99c2b92827b737", + "6f57ca393169f956ff778977ddbf3cfcb03e571aa5705fd1eb4120c55b4a4374", + "719b022db165b88e167421d3a2251539c37f9fcf13c3afd66f721b2bb03c3edc", + "87e14757be92a6033ecdb881a12968663b4705dd8100199ac995f67b7df7ac5a", + "afdeaadbf650f87f5eea08d0ad370484d403fbc646a02f3ebff1188d5e59a10b", + "93e141c225b18791938b6e99e5840c1edbc3781287462e8c166302c30394bd9a", + "fe085883d800c692b735db036604e44509e485d3296ac95c93b82c76b74aea30", + "a6b48f7538a2ba549fd56cdff43cadf71e820512b5a9fb66874dc37e27e78446", + "392bbc745478b0e672bd3b20e888a3b40b94bf1e3aad7613c61b50deb864b771", + "c52d89c98774a43f3efbd59947ccb38895b4671ae2391a072432c9d644452f09", + "3729b25f371fcc3c12e42e208acc79127afcfd2131ec2916020ea133f1c02c6f", + "e1fda3b8ba65ebc0b20543b717725223469c63283badae240b5fa38d3d142bdc", + "2f70f66ad2fbeb08d316dc5a11bc9fbc48593306516c2d883709e0c0f12f9cbc", + "b3471f84b304919715765d8a1f8ab684ed3722ebcb004c4957e40af28da1c6f5", + "0e99db1ece0f82a026ab062b9aed781bade322bca79fc1686a4cb5beddb9d338", + "ace3454cfe5351a97f4ec699d4743765e3d1a2152fb53e0724dea459e24ea490", + "5ecc2f35ed562b99e95afe2079dac1a73b227c34804e4dcd9a50c8c6cdf437f0", + "a15066c5a49ac9eb970329bae8ccc21e9469604d15903cbc456fb22e7ee123bb", + "7dbf7c5f81a564a9ecc4988b1c72dfdb1a88896472b7cafd2238665fd9073999", + "341e5d7014183f7eb0c6e8d892b09fbd4f168090037a2509f6ed7143f387f6c0", + "4c41346c7bdb6e36b749f6c16a71d2166d91dfbcab7361ec66372d5c9f3a91dc", + "9b9a082639e6555137ce4bbd7c3454e1b9c3cc7a3559ba3cda1b81848681f8d3", + "47369c48a7a347bbe1bea24ecdd3287c96e252dbdcf39dd040213edf2723a7e0", + "68f237a23f3cc92bda516bd8e1d62f7e95a6300889fd7b9b0cd237375e137c8f", + "c32d1b6d575813cfa1ce3637a0104d1c14d88c48dc7fcf270ce4b145b8689cbc", + "590a5e9ed75e9b5ded7e57de6aaa018e9ffe30f7d8cc37a3a11214bdeed6a9f9", + "8c8b6190f8b930cc2dbf6664635067b3143337b5a72d40556647fbc4394748c1", + "6ec350d648165259cd2d8da8a48774f54367a7a86aaafed6abf2a47a4d711f3c", + "f3fb726f604c5b31cf166206b6de64325a1a1e9bc4a3b5d4895da1f5ebbe76a0", + "6284881d6be0e0ea221d8706c66eae229735aeb0b865fe9ab05f1869e76531b8", + "8dff89dda7ffcaddeed906ba9dcb304daa2ac522ff88e986084806807ad17ce0", + "3a167b4ce253fa1b48559b6b0244820ad9564f1e7388baf741874cede44d7de6", + "6e31ff841573e7672cfd5111371ef9f58af907bc7b830c307fa966659ac158cc", + "1d96483a406f3e24323c4a0c88fc378ba397ee3da7b414a577d369f73238a404", + "949ed7a0acf855ff22f6a45a1755d10f9f681b5a6f62593074221193a21cf5e5", + "4ed70823fc6eee5f4b8b226e1530930e4fed09b5461fe99b9dc1382b28bf5762", + "35c751df62a7a6ddfa69c883c253fdcb347e6332d2ec1dd572e98cf27e4ee9d3", + "87845234f85725b0fc0cbff6ddcae826e28b81ed3eb8b4922d166ee739471982", + "2b92d0436dd89d399ac3d5fea995ae2a4f44cce5ebb8297df1b43d3ebeb8d632", + "608c65c6454b276856b17f189b05cb2c5717e5a2424ea4dbe3358b25484863a8", + "f1c01fbbd566f73b160f8377bddefb0ad298bebc8150b5637b0eac03a14a5a43", + "c7659eeebb2e25cba94ca5db5ffc7fe057feb6397b28ed7a17b69fd96a67a0d1", + "5d7337318e3a686eb085984a671204cd0496bc2943bbd4c7c799efc029f259f8", + "93cce15b27f245b7c675930ee2094dddff563aa9bfb8e1b5a6532d10474071b1", + "c816b6675716cc770ecee78bdc1184076077ff0e70ffc00758f8e6587f76c2b7", + "9901db2acaf3087814a35a9b226d0354d4f606b9c99cf745080aee3c0c6d2b58", + "8c719ab300735f9ac41e7934949968ac2ca5b549fdbaf45409e18dc93c2f32dd", + "7d7acd8888daeeb61e9a290d3c0639e81f05b61967b031c28e0986809c91c7e9", + "9d20deb4122e874e3da32d95af0331436c4111b988933399c4e8be256b61fb46", + "2c579006a5b3833995aa5ad91ee8c1cb00d10e0c3c9eb52514dd68fd62463e08", + "369e582ec7cdc1a557370a2574b0b0b4d2b4991604dabce27116c3243602ca86", + "8e6b571b0c5af2a67718bf0c14566a486020662e3a03105ade32026373d1aa1d", + "45639d6a5bb7943678a11d30cd4f02a1fa4c373abd9d3579eef543afa49dc8a3", + "b3fd64c6e580d722f4877e6ad0a81116f5867276972647402be74a771780d275", + "16ea28643425d8937d3fc36c368e3f55edcefd124c1c3947b6fa4dbccc42042b", + "11fa041de184d64fe3d1799b565859a6b38175e0e5e10444f462f3e443eeea94", + "dcb046b87a08e1e349fa81c57ec4d76f1d2f535c73dffe364a07d7d36dca4a19", + "2c1b0ac7ebe7c624983da4d2c6e1d96fbc74b10287083c4dd31ddd86c023d07d", + "04c1f33fc1c108b92f7630331863d4a2c7f12b519bebc0bb7f1d0c7d61f51b9b", + "2d7547df90faa3519fa06f7c76ed6d77d32359832ae4c6a3fa803021a25f556e", + "18b54bed1c7407856346c8641b83eeac78888b2083f6b83e35185a16cc23670d", + "637f5675b777c7f55e1081192194f4fbf7408a7e763e69c2ff0615871cabd838", + "898e4fb9ae7de672dc008fef60ab1580b40a8db27942f050e62f41a043593bc4", + "5b67b70b9c3fe06bacadc25f60a27b58460a71ddd047530febccdf35c93e2f5a", + "f588c0379f2a325f03cce411e5c57ec3586dd1b6e7ac04d5c03cd91e0d14f69f", + "d6b85cc3c36fa0d75bc819a38be169fb8e9d1c7d096128de718b139f915e138e", + "a0d0774f9640581aec36d07e25a652e6c83eb9e6c6c7b1c9be5802d2146d6998", + "8bf83c01f95a94d845cecfee5f5f81e89f9808c42d44f9832fb27de22e3a5b54", + "4e41d70abee27aed4393b60eea16116db0c74561acf20d195a416f2681095bb2", + "c467aca2d5c465832d793dbef90eab556400296a17aeed1018faf7fb99e658bb", + "21f5b2e0d58495e7d23ec5ca0735265e6d9916eb059af8811b075ed237d6a4cb", + "f2b0f77793600461c0fb2957c2fed1d951c22f17b2034269a5bfc2bb6ea862f8", + "8aed4838506d94337e4832d0002965c84588679e9c0e17867de6e85fdb02c13a", + "2ce56f8e06a895effb99ceda03bec09d133682b2756c6053b29429921de41f1a", + "3040cdb762777bfbaf1db9e2c49e62ae3536842e2ce079c9bafdb53b57f2d156", + "64469d32795fd303f59ebb9b2cc12fb74e3fbec57d911b4b1a81acc8a698c39d", + "0bb57cc98badffb1468c92dae37afb538dc28fe0d4a39ac4d7eaeade861cf732", + "a358f598567bfeba415e312f9e04a47ac9e005bcc467e4d7e314c9f62fc528ee", + "d965671ac04af7e30442505abf520ee59dd1d95d3daeae206387033f2c56dc4c", + "5e908e631360aa06ca65cf581dee11114fc391decb293780cea30060e3296b9c", + "ebf54bab7fa588f8dca51e21a691f4c89a93e1758bbf048368aeac312144c2b2", + "c585430b9202a30a95f201568b96f040e9627e6ddfa0da702e2bdcda565ebbf3", + "86ff111d0f47624ca6688f5fdf01d2543db9d7ac26d8d68fabb2b5f515b8e09c", + "6bcf906ee559e6c01e2674914414de646db70e6fe4c078163ae94f94a89262ed", + "214d547353927a7b323f7f96b3ddb12f90f25618299a7f582de989829dc764c8", + "6f81720f5a51fbb09fd77380d1a1336c15a430e18ec52492df64b9369e3eab6e", + "d46b921280d0bd310e74ec6ef2226e0937bb1817b1f1500692ed911b7c98d530", + "7edea109b1c160e5f89447acb15582f4f2ede4eb7b465229628b642ca7b22dde", + "0d88c5cc83a618533cb09ac01883d411b5ee0beb0b4088b7cb451f78e1e6ce9f", + "9fbc9a39eefe9ef919deed0c8bd6344cce129ca514633f8f69e4fc7f499e5606", + "329f938f5c9284c781c593393c8aaf41dcb0d4cf321aca6fdac6acc03890fe07", + "cbbc630e0f207a5ca288928df887adf265b4a890180dceb3a9acc3a98fe61281", + "789f8e43527204b92b20abb81c266dc89299f760393bffb52ab41930d10d5e80", } -const ropstenPreverifiedHeight uint64 = 11800128 +const ropstenPreverifiedHeight uint64 = 11841600 From 65dede38f866b2ed85f9561a5a64288773d0664e Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Wed, 19 Jan 2022 15:09:31 -0300 Subject: [PATCH 124/261] Fix including/excluding criteriaa to match original method signature --- cmd/rpcdaemon/commands/otterscan_api.go | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 9f90823a9a1..cdc8540be1b 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -115,7 +115,7 @@ func (api *OtterscanAPIImpl) GetInternalOperations(ctx context.Context, hash com // Search transactions that touch a certain address. // -// It searches back a certain block (including); the results are sorted descending. +// It searches back a certain block (excluding); the results are sorted descending. // // The pageSize indicates how many txs may be returned. If there are less txs than pageSize, // they are just returned. But it may return a little more than pageSize if there are more txs @@ -145,6 +145,14 @@ func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr return nil, err } + isFirstPage := false + if blockNum == 0 { + isFirstPage = true + } else { + // Internal search code considers blockNum [including], so adjust the value + blockNum-- + } + // Initialize search cursors at the first shard >= desired block number callFromProvider := NewCallCursorBackwardBlockProvider(callFromCursor, addr, blockNum) callToProvider := NewCallCursorBackwardBlockProvider(callToCursor, addr, blockNum) @@ -185,12 +193,12 @@ func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr } } - return &TransactionsWithReceipts{txs, receipts, blockNum == 0, !hasMore}, nil + return &TransactionsWithReceipts{txs, receipts, isFirstPage, !hasMore}, nil } // Search transactions that touch a certain address. // -// It searches forward a certain block (including); the results are sorted descending. +// It searches forward a certain block (excluding); the results are sorted descending. // // The pageSize indicates how many txs may be returned. If there are less txs than pageSize, // they are just returned. But it may return a little more than pageSize if there are more txs @@ -220,6 +228,14 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c return nil, err } + isLastPage := false + if blockNum == 0 { + isLastPage = true + } else { + // Internal search code considers blockNum [including], so adjust the value + blockNum++ + } + // Initialize search cursors at the first shard >= desired block number callFromProvider := NewCallCursorForwardBlockProvider(callFromCursor, addr, blockNum) callToProvider := NewCallCursorForwardBlockProvider(callToCursor, addr, blockNum) @@ -262,7 +278,7 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c txs[i], txs[lentxs-1-i] = txs[lentxs-1-i], txs[i] receipts[i], receipts[lentxs-1-i] = receipts[lentxs-1-i], receipts[i] } - return &TransactionsWithReceipts{txs, receipts, !hasMore, blockNum == 0}, nil + return &TransactionsWithReceipts{txs, receipts, !hasMore, isLastPage}, nil } func (api *OtterscanAPIImpl) traceBlocks(ctx context.Context, addr common.Address, chainConfig *params.ChainConfig, pageSize, resultCount uint16, callFromToProvider BlockProvider) ([]*TransactionsWithReceipts, bool, error) { From 40bb58d9878aac3c23477248510bc8014918cbd2 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Wed, 19 Jan 2022 15:31:36 -0300 Subject: [PATCH 125/261] Proper error handling --- cmd/rpcdaemon/commands/otterscan_api.go | 4 ++-- cmd/rpcdaemon/commands/otterscan_search_trace.go | 9 ++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index cdc8540be1b..735013ef5ad 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -176,7 +176,7 @@ func (api *OtterscanAPIImpl) SearchTransactionsBefore(ctx context.Context, addr for _, r := range results { if r == nil { - return nil, errors.New("XXXX") + return nil, errors.New("internal error during search tracing") } for i := len(r.Txs) - 1; i >= 0; i-- { @@ -259,7 +259,7 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c for _, r := range results { if r == nil { - return nil, errors.New("XXXX") + return nil, errors.New("internal error during search tracing") } txs = append(txs, r.Txs...) diff --git a/cmd/rpcdaemon/commands/otterscan_search_trace.go b/cmd/rpcdaemon/commands/otterscan_search_trace.go index bdc3b43b63e..a5bcc21050a 100644 --- a/cmd/rpcdaemon/commands/otterscan_search_trace.go +++ b/cmd/rpcdaemon/commands/otterscan_search_trace.go @@ -25,18 +25,17 @@ func (api *OtterscanAPIImpl) searchTraceBlock(ctx context.Context, wg *sync.Wait // Trace block for Txs newdbtx, err := api.db.BeginRo(ctx) if err != nil { - log.Error("ERR", "err", err) - // TODO: signal error + log.Error("Search trace error", "err", err) results[idx] = nil + return } defer newdbtx.Rollback() _, result, err := api.traceBlock(newdbtx, ctx, bNum, addr, chainConfig) if err != nil { - // TODO: signal error - log.Error("ERR", "err", err) + log.Error("Search trace error", "err", err) results[idx] = nil - //return nil, err + return } results[idx] = result } From 96f837315332f86719aeb52d3fc799e7754a6e81 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Thu, 20 Jan 2022 07:26:50 +0000 Subject: [PATCH 126/261] [stable] Intersection mode for trace_filter (#3305) * * contracts: implemented trace_filter intersection mode for Trace API (#2119) * fixed formatting * revisited error check during tx tracing * commands: follow-up update of (#2119): realigned TraceFilterModeIntersection behaviour (#3304) Co-authored-by: Artem Tsebrovskiy --- cmd/rpcdaemon/commands/call_traces_test.go | 89 ++++++++++++++++++++++ cmd/rpcdaemon/commands/trace_filtering.go | 38 ++++++++- 2 files changed, 125 insertions(+), 2 deletions(-) diff --git a/cmd/rpcdaemon/commands/call_traces_test.go b/cmd/rpcdaemon/commands/call_traces_test.go index f96f7e65b6c..a02859372db 100644 --- a/cmd/rpcdaemon/commands/call_traces_test.go +++ b/cmd/rpcdaemon/commands/call_traces_test.go @@ -3,14 +3,19 @@ package commands import ( "bytes" "context" + "sync" "testing" + "github.com/holiman/uint256" jsoniter "github.com/json-iterator/go" "github.com/ledgerwatch/erigon-lib/kv/kvcache" + "github.com/stretchr/testify/require" + "github.com/ledgerwatch/erigon/cmd/rpcdaemon/cli" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/core" + "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/turbo/stages" "github.com/ledgerwatch/log/v3" "github.com/stretchr/testify/assert" @@ -176,3 +181,87 @@ func TestFilterNoAddresses(t *testing.T) { } assert.Equal(t, []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, blockNumbersFromTraces(t, buf.Bytes())) } + +func TestFilterAddressIntersection(t *testing.T) { + m := stages.Mock(t) + defer m.DB.Close() + + api := NewTraceAPI(NewBaseApi(nil, kvcache.New(kvcache.DefaultCoherentConfig), false), m.DB, &cli.Flags{}) + + toAddress1, toAddress2, other := common.Address{1}, common.Address{2}, common.Address{3} + + once := new(sync.Once) + chain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 15, func(i int, block *core.BlockGen) { + once.Do(func() { block.SetCoinbase(common.Address{4}) }) + + var rcv common.Address + if i < 5 { + rcv = toAddress1 + } else if i < 10 { + rcv = toAddress2 + } else { + rcv = other + } + + signer := types.LatestSigner(m.ChainConfig) + txn, err := types.SignTx(types.NewTransaction(block.TxNonce(m.Address), rcv, new(uint256.Int), 21000, new(uint256.Int), nil), *signer, m.Key) + if err != nil { + t.Fatal(err) + } + block.AddTx(txn) + }, false /* intemediateHashes */) + require.NoError(t, err, "generate chain") + + err = m.InsertChain(chain) + require.NoError(t, err, "inserting chain") + + fromBlock, toBlock := uint64(1), uint64(15) + t.Run("second", func(t *testing.T) { + stream := jsoniter.ConfigDefault.BorrowStream(nil) + defer jsoniter.ConfigDefault.ReturnStream(stream) + + traceReq1 := TraceFilterRequest{ + FromBlock: (*hexutil.Uint64)(&fromBlock), + ToBlock: (*hexutil.Uint64)(&toBlock), + FromAddress: []*common.Address{&m.Address, &other}, + ToAddress: []*common.Address{&m.Address, &toAddress2}, + Mode: TraceFilterModeIntersection, + } + if err = api.Filter(context.Background(), traceReq1, stream); err != nil { + t.Fatalf("trace_filter failed: %v", err) + } + assert.Equal(t, []int{6, 7, 8, 9, 10}, blockNumbersFromTraces(t, stream.Buffer())) + }) + t.Run("first", func(t *testing.T) { + stream := jsoniter.ConfigDefault.BorrowStream(nil) + defer jsoniter.ConfigDefault.ReturnStream(stream) + + traceReq1 := TraceFilterRequest{ + FromBlock: (*hexutil.Uint64)(&fromBlock), + ToBlock: (*hexutil.Uint64)(&toBlock), + FromAddress: []*common.Address{&m.Address, &other}, + ToAddress: []*common.Address{&toAddress1, &m.Address}, + Mode: TraceFilterModeIntersection, + } + if err = api.Filter(context.Background(), traceReq1, stream); err != nil { + t.Fatalf("trace_filter failed: %v", err) + } + assert.Equal(t, []int{1, 2, 3, 4, 5}, blockNumbersFromTraces(t, stream.Buffer())) + }) + t.Run("empty", func(t *testing.T) { + stream := jsoniter.ConfigDefault.BorrowStream(nil) + defer jsoniter.ConfigDefault.ReturnStream(stream) + + traceReq1 := TraceFilterRequest{ + FromBlock: (*hexutil.Uint64)(&fromBlock), + ToBlock: (*hexutil.Uint64)(&toBlock), + ToAddress: []*common.Address{&other}, + FromAddress: []*common.Address{&toAddress2, &toAddress1, &other}, + Mode: TraceFilterModeIntersection, + } + if err = api.Filter(context.Background(), traceReq1, stream); err != nil { + t.Fatalf("trace_filter failed: %v", err) + } + require.Empty(t, blockNumbersFromTraces(t, stream.Buffer())) + }) +} diff --git a/cmd/rpcdaemon/commands/trace_filtering.go b/cmd/rpcdaemon/commands/trace_filtering.go index 4825e74daa3..c82436fe664 100644 --- a/cmd/rpcdaemon/commands/trace_filtering.go +++ b/cmd/rpcdaemon/commands/trace_filtering.go @@ -2,16 +2,19 @@ package commands import ( "context" + "errors" "fmt" "github.com/RoaringBitmap/roaring/roaring64" jsoniter "github.com/json-iterator/go" "github.com/ledgerwatch/erigon-lib/kv" + "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/consensus/ethash" "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/ethdb" "github.com/ledgerwatch/erigon/ethdb/bitmapdb" "github.com/ledgerwatch/erigon/rpc" ) @@ -229,11 +232,18 @@ func (api *TraceAPIImpl) Filter(ctx context.Context, req TraceFilterRequest, str fromAddresses := make(map[common.Address]struct{}, len(req.FromAddress)) toAddresses := make(map[common.Address]struct{}, len(req.ToAddress)) - var allBlocks roaring64.Bitmap + var ( + allBlocks roaring64.Bitmap + blocksTo roaring64.Bitmap + ) + for _, addr := range req.FromAddress { if addr != nil { b, err := bitmapdb.Get64(dbtx, kv.CallFromIndex, addr.Bytes(), fromBlock, toBlock) if err != nil { + if errors.Is(err, ethdb.ErrKeyNotFound) { + continue + } stream.WriteNil() return err } @@ -241,17 +251,31 @@ func (api *TraceAPIImpl) Filter(ctx context.Context, req TraceFilterRequest, str fromAddresses[*addr] = struct{}{} } } + for _, addr := range req.ToAddress { if addr != nil { b, err := bitmapdb.Get64(dbtx, kv.CallToIndex, addr.Bytes(), fromBlock, toBlock) if err != nil { + if errors.Is(err, ethdb.ErrKeyNotFound) { + continue + } stream.WriteNil() return err } - allBlocks.Or(b) + blocksTo.Or(b) toAddresses[*addr] = struct{}{} } } + + switch req.Mode { + case TraceFilterModeIntersection: + allBlocks.And(&blocksTo) + case TraceFilterModeUnion: + fallthrough + default: + allBlocks.Or(&blocksTo) + } + // Special case - if no addresses specified, take all traces if len(req.FromAddress) == 0 && len(req.ToAddress) == 0 { allBlocks.AddRange(fromBlock, toBlock+1) @@ -473,6 +497,16 @@ type TraceFilterRequest struct { ToBlock *hexutil.Uint64 `json:"toBlock"` FromAddress []*common.Address `json:"fromAddress"` ToAddress []*common.Address `json:"toAddress"` + Mode TraceFilterMode `json:"mode"` After *uint64 `json:"after"` Count *uint64 `json:"count"` } + +type TraceFilterMode string + +const ( + // Default mode for TraceFilter. Unions results referred to addresses from FromAddress or ToAddress + TraceFilterModeUnion = "union" + // IntersectionMode retrives results referred to addresses provided both in FromAddress and ToAddress + TraceFilterModeIntersection = "intersection" +) From 5d3c7761c5f1fc7ffe7f528e7907431b3a749c32 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Thu, 20 Jan 2022 07:27:00 +0000 Subject: [PATCH 127/261] Update version.go (#3306) --- params/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/params/version.go b/params/version.go index 24bae2b9280..c79616d8346 100644 --- a/params/version.go +++ b/params/version.go @@ -33,7 +33,7 @@ var ( const ( VersionMajor = 2022 // Major version component of the current release VersionMinor = 1 // Minor version component of the current release - VersionMicro = 1 // Patch version component of the current release + VersionMicro = 2 // Patch version component of the current release VersionModifier = "beta" // Patch version component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" From cb44decc9136d92d9ea524145c4b6d1ae6c7564c Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Thu, 20 Jan 2022 15:09:22 -0300 Subject: [PATCH 128/261] Add versioning explanation, reference to custom API docs --- README.md | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 07255700cc9..b64aceb0e2b 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,30 @@ -# Otterscan's Erigon Extensions +# Otterscan JSON-RPC API Extensions for Erigon -This is a fork of Erigon containing jsonrpc method extensions used by [Otterscan](https://github.com/wmitsuda/otterscan). +This is a fork of Erigon containing JSON-RPC API method extensions used by [Otterscan](https://github.com/wmitsuda/otterscan). -**Please be sure you have a working Erigon installation before trying this fork.** +> **Please be sure you have a working Erigon installation before trying this fork.** -All instructions about which branch to use, how to run it, etc., are in the [Otterscan repository](https://github.com/wmitsuda/otterscan). +## Running + +Erigon versioning schema follows this format: `YYYY.MM.nn`, where: + +- `YYYY` is the year +- `MM` is the month +- `nn` is an incremental number starting with 1 representing the nn-th release of the month + +For example `v2021.12.03` means it is the 3rd release of December, 2021. + +They do weekly stable releases. This repository only builds on top of stable tags. We usually follow their releases 1:1 a few days after, so you might expect a corresponding patched release for every Erigon stable release, but it is not guaranteed, please check if the corresponding tag actually exists in our repository. + +Our tag format is `-otterscan`, so for Erigon `v2021.12.03` there should be a `v2021.12.03-otterscan` tagged release. + +You can checkout the desired tag from the git repository and follow the same build instructions from the upstream Erigon or download the automated built images from [Docker Hub](https://hub.docker.com/r/otterscan/erigon/tags). + +## Other docs + +The Otterscan's JSON-RPC API extensions are documented [here](https://github.com/wmitsuda/otterscan/blob/develop/docs/custom-jsonrpc.md). + +All instructions about how to run Otterscan are in the [Otterscan repository](https://github.com/wmitsuda/otterscan). The rest of this document contains the original Erigon README content. From 265f783088c8adee033189d1d8a220e5c071d038 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Thu, 20 Jan 2022 15:56:06 -0300 Subject: [PATCH 129/261] Add fix explanation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b64aceb0e2b..4350b2992cc 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ For example `v2021.12.03` means it is the 3rd release of December, 2021. They do weekly stable releases. This repository only builds on top of stable tags. We usually follow their releases 1:1 a few days after, so you might expect a corresponding patched release for every Erigon stable release, but it is not guaranteed, please check if the corresponding tag actually exists in our repository. -Our tag format is `-otterscan`, so for Erigon `v2021.12.03` there should be a `v2021.12.03-otterscan` tagged release. +Our tag format is `[-fix]-otterscan`, so for Erigon `v2021.12.03` there should be a `v2021.12.03-otterscan` tagged release. If there is some fix from our side on top of our own tag, we would add an additional suffix before `-otterscan`, like `v2021.12.03-1-otterscan`. You can checkout the desired tag from the git repository and follow the same build instructions from the upstream Erigon or download the automated built images from [Docker Hub](https://hub.docker.com/r/otterscan/erigon/tags). From 7f1646fe8162686d4fbcafee23179a3bb2550046 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Fri, 21 Jan 2022 17:47:51 +0700 Subject: [PATCH 130/261] Penalize for invalid rlp (#3315) * save * log * save From b4b8df998363298dfc4e36c25da60c5142534594 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Fri, 21 Jan 2022 17:42:42 +0000 Subject: [PATCH 131/261] [stable] Enable Sentry to send "peer disconnected" event (#3317) (#3320) * Enable Sentry to send "peer disconnected" event (#3317) * Fix up Co-authored-by: Michelangelo Riccobene Co-authored-by: Alex Sharp --- cmd/sentry/download/sentry.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cmd/sentry/download/sentry.go b/cmd/sentry/download/sentry.go index e9bb703560f..6ac451f3397 100644 --- a/cmd/sentry/download/sentry.go +++ b/cmd/sentry/download/sentry.go @@ -528,6 +528,7 @@ func NewSentryServer(ctx context.Context, dialCandidates enode.Iterator, readNod ); err != nil { log.Trace(fmt.Sprintf("[%s] Error while running peer: %v", peerID, err)) } + ss.sendGonePeerToClients(gointerfaces.ConvertBytesToH512([]byte(peerID))) return nil }, NodeInfo: func() interface{} { @@ -969,6 +970,12 @@ func (ss *SentryServerImpl) sendNewPeerToClients(peerID *proto_types.H512) { } } +func (ss *SentryServerImpl) sendGonePeerToClients(peerID *proto_types.H512) { + if err := ss.peersStreams.Broadcast(&proto_sentry.PeersReply{PeerId: peerID, Event: proto_sentry.PeersReply_Disconnect}); err != nil { + log.Warn("Sending gone peer notice to core P2P failed", "error", err) + } +} + func (ss *SentryServerImpl) Peers(req *proto_sentry.PeersRequest, server proto_sentry.Sentry_PeersServer) error { clean := ss.peersStreams.Add(server) defer clean() From ea9ad474467af7a924063a50a6c9f9c82ad5d1d9 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Sun, 23 Jan 2022 17:31:55 +0700 Subject: [PATCH 132/261] mdbx 0.11.4 (fixes for 4tb asserts logic) (#3327) * mdbx 0.11.4 * mdbx 0.11.4 * mdbx 0.11.4 * don't loose default CGO_CFLAGS * Update to erigon-lib@stable Co-authored-by: Alex Sharp --- Makefile | 10 ++++++++-- go.mod | 4 ++-- go.sum | 8 ++++---- libmdbx | 2 +- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index f49d1930f5d..95cca41fd36 100644 --- a/Makefile +++ b/Makefile @@ -5,8 +5,14 @@ GOTEST = GODEBUG=cgocheck=0 $(GO) test ./... -p 2 GIT_COMMIT ?= $(shell git rev-list -1 HEAD) GIT_BRANCH ?= $(shell git rev-parse --abbrev-ref HEAD) GIT_TAG ?= $(shell git describe --tags `git rev-list --tags="v*" --max-count=1`) -GOBUILD = env GO111MODULE=on $(GO) build -trimpath -ldflags "-X github.com/ledgerwatch/erigon/params.GitCommit=${GIT_COMMIT} -X github.com/ledgerwatch/erigon/params.GitBranch=${GIT_BRANCH} -X github.com/ledgerwatch/erigon/params.GitTag=${GIT_TAG}" -GO_DBG_BUILD = $(GO) build -trimpath -tags=debug -ldflags "-X github.com/ledgerwatch/erigon/params.GitCommit=${GIT_COMMIT} -X github.com/ledgerwatch/erigon/params.GitBranch=${GIT_BRANCH} -X github.com/ledgerwatch/erigon/params.GitTag=${GIT_TAG}" -gcflags=all="-N -l" # see delve docs + +CGO_CFLAGS := $(shell $(GO) env CGO_CFLAGS) # don't loose default +CGO_CFLAGS += -DMDBX_FORCE_ASSERTIONS=0 # Enable MDBX's asserts by default in 'devel' branch and disable in 'stable' +CGO_CFLAGS := CGO_CFLAGS="$(CGO_CFLAGS)" +DBG_CGO_CFLAGS += -DMDBX_DEBUG=1 + +GOBUILD = $(CGO_CFLAGS) $(GO) build -trimpath -ldflags "-X github.com/ledgerwatch/erigon/params.GitCommit=${GIT_COMMIT} -X github.com/ledgerwatch/erigon/params.GitBranch=${GIT_BRANCH} -X github.com/ledgerwatch/erigon/params.GitTag=${GIT_TAG}" +GO_DBG_BUILD = $(DBG_CGO_CFLAGS) $(GO) build -trimpath -tags=debug -ldflags "-X github.com/ledgerwatch/erigon/params.GitCommit=${GIT_COMMIT} -X github.com/ledgerwatch/erigon/params.GitBranch=${GIT_BRANCH} -X github.com/ledgerwatch/erigon/params.GitTag=${GIT_TAG}" -gcflags=all="-N -l" # see delve docs GO_MAJOR_VERSION = $(shell $(GO) version | cut -c 14- | cut -d' ' -f1 | cut -d'.' -f1) GO_MINOR_VERSION = $(shell $(GO) version | cut -c 14- | cut -d' ' -f1 | cut -d'.' -f2) diff --git a/go.mod b/go.mod index 26253d62795..b59276c9c58 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20220117080915-8327de3c4e64 + github.com/ledgerwatch/erigon-lib v0.0.0-20220123081303-02a3d31baa21 github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 @@ -47,7 +47,7 @@ require ( github.com/spf13/cobra v1.2.1 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.7.0 - github.com/torquem-ch/mdbx-go v0.22.3 + github.com/torquem-ch/mdbx-go v0.22.6 github.com/ugorji/go/codec v1.1.13 github.com/ugorji/go/codec/codecgen v1.1.13 github.com/urfave/cli v1.22.5 diff --git a/go.sum b/go.sum index 9fec7e6e243..aac38e25b35 100644 --- a/go.sum +++ b/go.sum @@ -500,8 +500,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20220117080915-8327de3c4e64 h1:Q3kUXgFiE2K/JscqqjCROg4Y4sjaz7Vzhuhg7xOSHNk= -github.com/ledgerwatch/erigon-lib v0.0.0-20220117080915-8327de3c4e64/go.mod h1:RtMyitRZlGyq0k8YVbMIwN/w3iby0zhPfM3tpCoqSUU= +github.com/ledgerwatch/erigon-lib v0.0.0-20220123081303-02a3d31baa21 h1:H3zBUTL5ULVLNjogDzXQeDLTrhUx8eNh8DpGljhaeog= +github.com/ledgerwatch/erigon-lib v0.0.0-20220123081303-02a3d31baa21/go.mod h1:U3uvygbCLT1SodSM8/p7Am1VFIEKkGzSYeE8PtjEWq0= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= @@ -753,8 +753,8 @@ github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs= github.com/tklauser/numcpus v0.3.0 h1:ILuRUQBtssgnxw0XXIjKUC56fgnOrFoQQ/4+DeU2biQ= github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8= -github.com/torquem-ch/mdbx-go v0.22.3 h1:C6cj5BMZ74Mbkn/FjOKvz2lVDSJLm7pqYwQBsIT9T4Y= -github.com/torquem-ch/mdbx-go v0.22.3/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= +github.com/torquem-ch/mdbx-go v0.22.6 h1:xtPd4xfB8HdU1pJCZEkLNwnrqwAoLe2/luMsVRuMhGQ= +github.com/torquem-ch/mdbx-go v0.22.6/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= diff --git a/libmdbx b/libmdbx index e93d53ed923..03d828834bd 160000 --- a/libmdbx +++ b/libmdbx @@ -1 +1 @@ -Subproject commit e93d53ed923670b87acae9b40c2f3176f2756e2b +Subproject commit 03d828834bdb57a8e0ff34a311b6b835bfe4a479 From 30281f4c36e0be034f9699afac1e26e625be11ea Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Tue, 25 Jan 2022 05:26:50 +0700 Subject: [PATCH 133/261] MDBX: Add recommendations to corruption error message (#3338) * corruption recommendations * Point to latest commit in stable erigon-lib Co-authored-by: Alexey Sharp --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index b59276c9c58..a768a4de798 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20220123081303-02a3d31baa21 + github.com/ledgerwatch/erigon-lib v0.0.0-20220124070814-0c942eea2758 github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 @@ -47,7 +47,7 @@ require ( github.com/spf13/cobra v1.2.1 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.7.0 - github.com/torquem-ch/mdbx-go v0.22.6 + github.com/torquem-ch/mdbx-go v0.22.7 github.com/ugorji/go/codec v1.1.13 github.com/ugorji/go/codec/codecgen v1.1.13 github.com/urfave/cli v1.22.5 diff --git a/go.sum b/go.sum index aac38e25b35..6e0055031b6 100644 --- a/go.sum +++ b/go.sum @@ -500,8 +500,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20220123081303-02a3d31baa21 h1:H3zBUTL5ULVLNjogDzXQeDLTrhUx8eNh8DpGljhaeog= -github.com/ledgerwatch/erigon-lib v0.0.0-20220123081303-02a3d31baa21/go.mod h1:U3uvygbCLT1SodSM8/p7Am1VFIEKkGzSYeE8PtjEWq0= +github.com/ledgerwatch/erigon-lib v0.0.0-20220124070814-0c942eea2758 h1:3UNSbrWhQa8jthePN14OPeu8IGjrKzMGhCpcKbVhag4= +github.com/ledgerwatch/erigon-lib v0.0.0-20220124070814-0c942eea2758/go.mod h1:kKssw3jA21RUsCq+abwZgHpaXOXU6wMzwkfKJRFgHn4= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= @@ -753,8 +753,8 @@ github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs= github.com/tklauser/numcpus v0.3.0 h1:ILuRUQBtssgnxw0XXIjKUC56fgnOrFoQQ/4+DeU2biQ= github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8= -github.com/torquem-ch/mdbx-go v0.22.6 h1:xtPd4xfB8HdU1pJCZEkLNwnrqwAoLe2/luMsVRuMhGQ= -github.com/torquem-ch/mdbx-go v0.22.6/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= +github.com/torquem-ch/mdbx-go v0.22.7 h1:m3fy1xmtlVnXEcbcTPuw5KJ3TpX4lPswdKCxLGny8oI= +github.com/torquem-ch/mdbx-go v0.22.7/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= From df43bef85a3df92653e2b9bd24390c32318ef589 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Tue, 25 Jan 2022 15:52:14 +0700 Subject: [PATCH 134/261] save (#3343) --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index a768a4de798..001c474c164 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20220124070814-0c942eea2758 + github.com/ledgerwatch/erigon-lib v0.0.0-20220125082654-f370c7f664d2 github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 @@ -47,7 +47,7 @@ require ( github.com/spf13/cobra v1.2.1 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.7.0 - github.com/torquem-ch/mdbx-go v0.22.7 + github.com/torquem-ch/mdbx-go v0.22.10 github.com/ugorji/go/codec v1.1.13 github.com/ugorji/go/codec/codecgen v1.1.13 github.com/urfave/cli v1.22.5 diff --git a/go.sum b/go.sum index 6e0055031b6..3f20cec1835 100644 --- a/go.sum +++ b/go.sum @@ -500,8 +500,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20220124070814-0c942eea2758 h1:3UNSbrWhQa8jthePN14OPeu8IGjrKzMGhCpcKbVhag4= -github.com/ledgerwatch/erigon-lib v0.0.0-20220124070814-0c942eea2758/go.mod h1:kKssw3jA21RUsCq+abwZgHpaXOXU6wMzwkfKJRFgHn4= +github.com/ledgerwatch/erigon-lib v0.0.0-20220125082654-f370c7f664d2 h1:grEMJ87dawpzHG+tAHuh7b2HGqUO5SwnL+4NsXJaVsQ= +github.com/ledgerwatch/erigon-lib v0.0.0-20220125082654-f370c7f664d2/go.mod h1:BQNYmN6i8RdHqedsztAj3XDnswYebacmFAnsznlisTc= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= @@ -753,8 +753,8 @@ github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs= github.com/tklauser/numcpus v0.3.0 h1:ILuRUQBtssgnxw0XXIjKUC56fgnOrFoQQ/4+DeU2biQ= github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8= -github.com/torquem-ch/mdbx-go v0.22.7 h1:m3fy1xmtlVnXEcbcTPuw5KJ3TpX4lPswdKCxLGny8oI= -github.com/torquem-ch/mdbx-go v0.22.7/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= +github.com/torquem-ch/mdbx-go v0.22.10 h1:reevtNP74E9SN7ESnogJr8Q8CI/0JcSMJ9tghfaLAEQ= +github.com/torquem-ch/mdbx-go v0.22.10/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= From a101cde4ac28868bb8582f404175edbdc49239a9 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Wed, 26 Jan 2022 17:00:15 +0700 Subject: [PATCH 135/261] better docs (#3347) --- cmd/txpool/main.go | 13 +++++++++++-- cmd/txpool/readme.md | 42 +++++++++++++++++++++--------------------- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/cmd/txpool/main.go b/cmd/txpool/main.go index d06d7e13e48..ebe7b753446 100644 --- a/cmd/txpool/main.go +++ b/cmd/txpool/main.go @@ -18,6 +18,7 @@ import ( "github.com/ledgerwatch/erigon-lib/txpool/txpooluitl" "github.com/ledgerwatch/erigon/cmd/rpcdaemon/rpcdaemontest" "github.com/ledgerwatch/erigon/cmd/utils" + common2 "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/paths" "github.com/ledgerwatch/erigon/ethdb/privateapi" "github.com/ledgerwatch/erigon/internal/debug" @@ -27,6 +28,7 @@ import ( var ( sentryAddr []string // Address of the sentry : + traceSenders []string privateApiAddr string txpoolApiAddr string datadir string // Path to td working dir @@ -62,11 +64,12 @@ func init() { rootCmd.PersistentFlags().Uint64Var(&priceLimit, "txpool.pricelimit", txpool.DefaultConfig.MinFeeCap, "Minimum gas price (fee cap) limit to enforce for acceptance into the pool") rootCmd.PersistentFlags().Uint64Var(&priceLimit, "txpool.accountslots", txpool.DefaultConfig.AccountSlots, "Minimum number of executable transaction slots guaranteed per account") rootCmd.PersistentFlags().Uint64Var(&priceBump, "txpool.pricebump", txpool.DefaultConfig.PriceBump, "Price bump percentage to replace an already existing transaction") + rootCmd.Flags().StringSliceVar(&traceSenders, utils.TxPoolTraceSendersFlag.Name, []string{}, utils.TxPoolTraceSendersFlag.Usage) } var rootCmd = &cobra.Command{ - Use: "sentry", - Short: "Run p2p sentry", + Use: "txpool", + Short: "Launch externa Transaction Pool instance - same as built-into Erigon, but as independent Service", PersistentPreRunE: func(cmd *cobra.Command, args []string) error { return debug.SetupCobra(cmd) }, @@ -119,6 +122,12 @@ var rootCmd = &cobra.Command{ cacheConfig := kvcache.DefaultCoherentConfig cacheConfig.MetricsLabel = "txpool" + cfg.TracedSenders = make([]string, len(traceSenders)) + for i, senderHex := range traceSenders { + sender := common2.HexToAddress(senderHex) + cfg.TracedSenders[i] = string(sender[:]) + } + newTxs := make(chan txpool.Hashes, 1024) defer close(newTxs) txPoolDB, txPool, fetch, send, txpoolGrpcServer, err := txpooluitl.AllComponents(ctx, cfg, diff --git a/cmd/txpool/readme.md b/cmd/txpool/readme.md index 92b6b22a8e4..a3077ea7b8d 100644 --- a/cmd/txpool/readme.md +++ b/cmd/txpool/readme.md @@ -1,40 +1,38 @@ # TxPool v2 -Design docs: https://github.com/ledgerwatch/erigon/wiki/Transaction-Pool-Design +Transaction Pool - place where living "not-included-to-block-yet transactions". +Erigon's TxPool can work inside Erigon (default) and as separated process. -Has 2 modes: internal and external +Erigon's pool implementation is not fork of Geth’s, has Apache license - Design +docs: https://github.com/ledgerwatch/erigon/wiki/Transaction-Pool-Design +95% of pool-related code (from p2p message parsing, to sorting logic) is inside this +folder: https://github.com/ledgerwatch/erigon-lib/tree/main/txpool ## Internal mode -It's default. No special flags required. But if in RPCDaemon you using custom `--private.api.addr` flag, then set same -value to `--txpool.api.addr` flag. +It's default. No special flags required - just start Erigon. +RPCDaemon - flags `--private.api.addr` and `--txpool.api.addr` must have same value in this case. ## External mode -Add `--txpool.disable` to erigon. External TxPool works in separated process and **require** external Sentry. TxPool -connect to Erigon and Sentry. RPCDaemon connect to TxPool. Build by: - ``` make txpool -``` -Start by: +# Add `--txpool.disable` flag to Erigon -``` -# Add `--txpool.disable` flags to Erigon. -./build/bin/sentry -./build/bin/txpool -``` +# External TxPool require(!) external Sentry +./build/bin/sentry --sentry.api.addr=localhost:9091 --datadir= -To change address/port of Erigon or Sentry: +# Start TxPool service (it connects to Erigon and Sentry): +# --private.api.addr - connect to Erigon's grpc api +# --sentry.api.addr - connect to Sentry's grpc api +# --txpool.api.addr - other services to connect TxPool's grpc api +# Increase limits flags: --txpool.globalslots, --txpool.globalbasefeeeslots, --txpool.globalqueue +# --txpool.trace.senders - print more logs about Txs with senders in this list +./build/bin/txpool --private.api.addr=localhost:9090 --sentry.api.addr=localhost:9091 --txpool.api.addr=localhost:9094 --datadir= +# Add flag `--txpool.api.addr` to RPCDaemon ``` -./build/bin/txpool --private.api.addr localhost:9090 --sentry.api.addr localhost:9091 --txpool.api.addr localhost:9094 -``` - -## Increase pool limits - -In `./build/bin/txpool --help` see flags: `--txpool.globalslots`, `--txpool.globalbasefeeeslots`, `--txpool.globalqueue` ## ToDo list @@ -42,3 +40,5 @@ In `./build/bin/txpool --help` see flags: `--txpool.globalslots`, `--txpool.glob [] Add pool to docker-compose [] Add pool (db table) - where store recently mined txs - for faster unwind/reorg. [] Save history of local transactions - with 1 day expiration +[] move tx.rlp field to separated map, to make tx immutable + From 6c8926a192b7bf0676e8537dee0963efb5473967 Mon Sep 17 00:00:00 2001 From: Giulio rebuffo Date: Wed, 26 Jan 2022 13:51:07 +0100 Subject: [PATCH 136/261] Added WatchTheBurn Stage and RPC Call to beta (#3345) * added test and stage * added flags * rpc --- README.md | 6 + cmd/rpcdaemon/commands/erigon_api.go | 6 +- cmd/rpcdaemon/commands/erigon_issuance.go | 86 ++++++--- cmd/utils/flags.go | 6 +- core/rawdb/accessors_chain.go | 26 +++ eth/ethconfig/config.go | 3 + eth/stagedsync/default_stages.go | 14 ++ eth/stagedsync/stage_issuance.go | 209 ++++++++++++++++++++++ eth/stagedsync/stage_issuance_test.go | 69 +++++++ eth/stagedsync/stages/stages.go | 1 + turbo/cli/default_flags.go | 1 + turbo/stages/mock_sentry.go | 2 +- turbo/stages/stageloop.go | 2 +- 13 files changed, 404 insertions(+), 27 deletions(-) create mode 100644 eth/stagedsync/stage_issuance.go create mode 100644 eth/stagedsync/stage_issuance_test.go diff --git a/README.md b/README.md index abee214bd13..5900be9d3b0 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,12 @@ make erigon ./build/bin/erigon ``` +### Optional stages + +There is an optional stage that can be enabled through flags: + +* `--watch-the-burn`, Enable WatchTheBurn stage which keeps track of ETH issuance and is required to use `erigon_watchTheBurn`. + ### Testnets If you would like to give Erigon a try, but do not have spare 2Tb on your driver, a good option is to start syncing one diff --git a/cmd/rpcdaemon/commands/erigon_api.go b/cmd/rpcdaemon/commands/erigon_api.go index c95d96312b0..e75dd66f799 100644 --- a/cmd/rpcdaemon/commands/erigon_api.go +++ b/cmd/rpcdaemon/commands/erigon_api.go @@ -24,10 +24,8 @@ type ErigonAPI interface { GetLogsByHash(ctx context.Context, hash common.Hash) ([][]*types.Log, error) //GetLogsByNumber(ctx context.Context, number rpc.BlockNumber) ([][]*types.Log, error) - // Issuance / reward related (see ./erigon_issuance.go) - // BlockReward(ctx context.Context, blockNr rpc.BlockNumber) (Issuance, error) - // UncleReward(ctx context.Context, blockNr rpc.BlockNumber) (Issuance, error) - Issuance(ctx context.Context, blockNr rpc.BlockNumber) (Issuance, error) + // WatchTheBurn / reward related (see ./erigon_issuance.go) + WatchTheBurn(ctx context.Context, blockNr rpc.BlockNumber) (Issuance, error) // NodeInfo returns a collection of metadata known about the host. NodeInfo(ctx context.Context) ([]p2p.NodeInfo, error) diff --git a/cmd/rpcdaemon/commands/erigon_issuance.go b/cmd/rpcdaemon/commands/erigon_issuance.go index 82b5a09e93a..5ba8c77bb8a 100644 --- a/cmd/rpcdaemon/commands/erigon_issuance.go +++ b/cmd/rpcdaemon/commands/erigon_issuance.go @@ -2,11 +2,13 @@ package commands import ( "context" + "fmt" + "math/big" - "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/erigon/common/hexutil" + "github.com/holiman/uint256" + "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/consensus/ethash" - "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/rpc" ) @@ -33,7 +35,7 @@ import ( //} // Issuance implements erigon_issuance. Returns the total issuance (block reward plus uncle reward) for the given block. -func (api *ErigonImpl) Issuance(ctx context.Context, blockNr rpc.BlockNumber) (Issuance, error) { +func (api *ErigonImpl) WatchTheBurn(ctx context.Context, blockNr rpc.BlockNumber) (Issuance, error) { tx, err := api.db.BeginRo(ctx) if err != nil { return Issuance{}, err @@ -48,12 +50,22 @@ func (api *ErigonImpl) Issuance(ctx context.Context, blockNr rpc.BlockNumber) (I // Clique for example has no issuance return Issuance{}, nil } - - block, err := api.getBlockByRPCNumber(tx, blockNr) + hash, err := rawdb.ReadCanonicalHash(tx, uint64(blockNr)) if err != nil { return Issuance{}, err } - minerReward, uncleRewards := ethash.AccumulateRewards(chainConfig, block.Header(), block.Uncles()) + header := rawdb.ReadHeader(tx, hash, uint64(blockNr)) + if header == nil { + return Issuance{}, fmt.Errorf("could not find block header") + } + + body := rawdb.ReadBodyWithTransactions(tx, hash, uint64(blockNr)) + + if body == nil { + return Issuance{}, fmt.Errorf("could not find block body") + } + + minerReward, uncleRewards := ethash.AccumulateRewards(chainConfig, header, body.Uncles) issuance := minerReward for _, r := range uncleRewards { p := r // avoids warning? @@ -61,24 +73,58 @@ func (api *ErigonImpl) Issuance(ctx context.Context, blockNr rpc.BlockNumber) (I } var ret Issuance - ret.BlockReward = hexutil.EncodeBig(minerReward.ToBig()) - ret.Issuance = hexutil.EncodeBig(issuance.ToBig()) + ret.BlockReward = minerReward.ToBig() + ret.Issuance = issuance.ToBig() issuance.Sub(&issuance, &minerReward) - ret.UncleReward = hexutil.EncodeBig(issuance.ToBig()) - return ret, nil -} - -func (api *ErigonImpl) getBlockByRPCNumber(tx kv.Tx, blockNr rpc.BlockNumber) (*types.Block, error) { - blockNum, err := getBlockNumber(blockNr, tx) + ret.UncleReward = issuance.ToBig() + // Compute how much was burnt + if header.BaseFee != nil { + ret.Burnt = header.BaseFee + ret.Burnt.Mul(ret.Burnt, big.NewInt(int64(header.GasUsed))) + } else { + ret.Burnt = common.Big0 + } + // Compute totalIssued, totalBurnt and the supply of eth + ret.TotalIssued, err = rawdb.ReadTotalIssued(tx, uint64(blockNr)) if err != nil { - return nil, err + return Issuance{}, err + } + ret.TotalBurnt, err = rawdb.ReadTotalBurnt(tx, uint64(blockNr)) + if err != nil { + return Issuance{}, err + } + if uint64(blockNr) == 0 { + ret.Issuance.Set(ret.TotalIssued) } - return api.blockByNumberWithSenders(tx, blockNum) + // Compute tips + ret.Tips = big.NewInt(0) + + if header.BaseFee != nil { + receipts, err := rawdb.ReadReceiptsByHash(tx, hash) + if err != nil { + return Issuance{}, err + } + + baseFee, overflow := uint256.FromBig(header.BaseFee) + if overflow { + return Issuance{}, fmt.Errorf("baseFee overflow") + } + + for i, transaction := range body.Transactions { + tip := transaction.GetEffectiveGasTip(baseFee).ToBig() + ret.Tips.Add(ret.Tips, tip.Mul(tip, big.NewInt(int64(receipts[i].GasUsed)))) + } + } + return ret, nil } // Issuance structure to return information about issuance type Issuance struct { - BlockReward string `json:"blockReward,omitempty"` - UncleReward string `json:"uncleReward,omitempty"` - Issuance string `json:"issuance,omitempty"` + BlockReward *big.Int `json:"blockReward"` // Block reward for given block + UncleReward *big.Int `json:"uncleReward"` // Uncle reward for gived block + Issuance *big.Int `json:"issuance"` // Total amount of wei created in the block + Burnt *big.Int `json:"burnt"` // Total amount of wei burned in the block + TotalIssued *big.Int `json:"totalIssued"` // Total amount of wei created in total so far + TotalBurnt *big.Int `json:"totalBurnt"` // Total amount of wei burnt so far + Tips *big.Int `json:"tips"` // Total Tips generated by the block } diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 4964bbe88b8..3a462e8cf24 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -219,6 +219,10 @@ var ( Usage: "Comma separared list of addresses, whoes transactions will traced in transaction pool with debug printing", Value: "", } + EnabledIssuance = cli.BoolFlag{ + Name: "watch-the-burn", + Usage: "Enable WatchTheBurn stage to keep track of ETH issuance", + } // Miner settings MiningEnabledFlag = cli.BoolFlag{ Name: "mine", @@ -1221,7 +1225,7 @@ func SetEthConfig(ctx *cli.Context, nodeConfig *node.Config, cfg *ethconfig.Conf setWhitelist(ctx, cfg) cfg.P2PEnabled = len(nodeConfig.P2P.SentryAddr) == 0 - + cfg.EnabledIssuance = ctx.GlobalIsSet(EnabledIssuance.Name) if ctx.GlobalIsSet(NetworkIdFlag.Name) { cfg.NetworkID = ctx.GlobalUint64(NetworkIdFlag.Name) } diff --git a/core/rawdb/accessors_chain.go b/core/rawdb/accessors_chain.go index 66da8212bf2..11ade0678cf 100644 --- a/core/rawdb/accessors_chain.go +++ b/core/rawdb/accessors_chain.go @@ -847,6 +847,32 @@ func ReadBlockByHashWithSenders(db kv.Tx, hash common.Hash) (*types.Block, []com return ReadBlockWithSenders(db, hash, *number) } +func ReadTotalIssued(db kv.Getter, number uint64) (*big.Int, error) { + data, err := db.GetOne(kv.Issuance, dbutils.EncodeBlockNumber(number)) + if err != nil { + return nil, err + } + + return new(big.Int).SetBytes(data), nil +} + +func WriteTotalIssued(db kv.Putter, number uint64, totalIssued *big.Int) error { + return db.Put(kv.Issuance, dbutils.EncodeBlockNumber(number), totalIssued.Bytes()) +} + +func ReadTotalBurnt(db kv.Getter, number uint64) (*big.Int, error) { + data, err := db.GetOne(kv.Issuance, append([]byte("burnt"), dbutils.EncodeBlockNumber(number)...)) + if err != nil { + return nil, err + } + + return new(big.Int).SetBytes(data), nil +} + +func WriteTotalBurnt(db kv.Putter, number uint64, totalBurnt *big.Int) error { + return db.Put(kv.Issuance, append([]byte("burnt"), dbutils.EncodeBlockNumber(number)...), totalBurnt.Bytes()) +} + func ReadHeaderByNumber(db kv.Getter, number uint64) *types.Header { hash, err := ReadCanonicalHash(db, number) if err != nil { diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index 661c7ac5903..a62ea70d4ca 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -178,6 +178,9 @@ type Config struct { // SyncLoopThrottle sets a minimum time between staged loop iterations SyncLoopThrottle time.Duration + + // Enable WatchTheBurn stage + EnabledIssuance bool } func CreateConsensusEngine(chainConfig *params.ChainConfig, logger log.Logger, config interface{}, notify []string, noverify bool) consensus.Engine { diff --git a/eth/stagedsync/default_stages.go b/eth/stagedsync/default_stages.go index ce78c266285..8ffe7c5d853 100644 --- a/eth/stagedsync/default_stages.go +++ b/eth/stagedsync/default_stages.go @@ -23,6 +23,7 @@ func DefaultStages(ctx context.Context, callTraces CallTracesCfg, txLookup TxLookupCfg, txPool TxPoolCfg, + issuance IssuanceCfg, finish FinishCfg, test bool, ) []*Stage { @@ -217,6 +218,19 @@ func DefaultStages(ctx context.Context, return PruneTxPool(p, tx, txPool, ctx) }, }, + { + ID: stages.Issuance, + Description: "Issuance computation", + Forward: func(firstCycle bool, badBlockUnwind bool, s *StageState, u Unwinder, tx kv.RwTx) error { + return SpawnStageIssuance(issuance, s, tx, ctx) + }, + Unwind: func(firstCycle bool, u *UnwindState, s *StageState, tx kv.RwTx) error { + return UnwindIssuanceStage(u, issuance, tx, ctx) + }, + Prune: func(firstCycle bool, p *PruneState, tx kv.RwTx) error { + return PruneIssuanceStage(p, issuance, tx, ctx) + }, + }, { ID: stages.Finish, Description: "Final: update current block for the RPC API", diff --git a/eth/stagedsync/stage_issuance.go b/eth/stagedsync/stage_issuance.go new file mode 100644 index 00000000000..961e97066bf --- /dev/null +++ b/eth/stagedsync/stage_issuance.go @@ -0,0 +1,209 @@ +package stagedsync + +import ( + "bytes" + "context" + "fmt" + "math/big" + "time" + + "github.com/holiman/uint256" + "github.com/ledgerwatch/erigon-lib/kv" + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/common/dbutils" + "github.com/ledgerwatch/erigon/consensus/ethash" + "github.com/ledgerwatch/erigon/core/rawdb" + "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/eth/stagedsync/stages" + "github.com/ledgerwatch/erigon/params" + "github.com/ledgerwatch/erigon/rlp" + "github.com/ledgerwatch/log/v3" +) + +type IssuanceCfg struct { + db kv.RwDB + chainConfig *params.ChainConfig + enabledIssuance bool +} + +func StageIssuanceCfg(db kv.RwDB, chainConfig *params.ChainConfig, enabledIssuance bool) IssuanceCfg { + return IssuanceCfg{ + db: db, + chainConfig: chainConfig, + enabledIssuance: enabledIssuance, + } +} + +func SpawnStageIssuance(cfg IssuanceCfg, s *StageState, tx kv.RwTx, ctx context.Context) error { + useExternalTx := tx != nil + + if !useExternalTx { + var err error + tx, err = cfg.db.BeginRw(context.Background()) + if err != nil { + return err + } + defer tx.Rollback() + } + + headNumber, err := stages.GetStageProgress(tx, stages.Bodies) + if err != nil { + return fmt.Errorf("getting headers progress: %w", err) + } + + if cfg.chainConfig.Consensus != params.EtHashConsensus || !cfg.enabledIssuance || headNumber == s.BlockNumber { + if !useExternalTx { + if err = tx.Commit(); err != nil { + return err + } + } + return nil + } + + // Log timer + logEvery := time.NewTicker(logInterval) + defer logEvery.Stop() + // Read previous issuance + totalIssued, err := rawdb.ReadTotalIssued(tx, s.BlockNumber) + if err != nil { + return err + } + + totalBurnt, err := rawdb.ReadTotalBurnt(tx, s.BlockNumber) + if err != nil { + return err + } + + stopped := false + prevProgress := s.BlockNumber + currentBlockNumber := s.BlockNumber + 1 + headerC, err := tx.Cursor(kv.Headers) + if err != nil { + return err + } + for k, v, err := headerC.Seek(dbutils.EncodeBlockNumber(currentBlockNumber)); k != nil && !stopped; k, v, err = headerC.Next() { + if err != nil { + return err + } + + if len(k) != 40 { + continue + } + + currentBlockNumber, err = dbutils.DecodeBlockNumber(k[:8]) + if err != nil { + return err + } + if currentBlockNumber > headNumber { + currentBlockNumber = headNumber + break + } + // read body without transactions + hash, err := rawdb.ReadCanonicalHash(tx, currentBlockNumber) + if err != nil { + return err + } + + if hash != common.BytesToHash(k[8:]) { + continue + } + var header types.Header + if err := rlp.Decode(bytes.NewReader(v), &header); err != nil { + log.Error("Invalid block header RLP", "hash", hash, "err", err) + return nil + } + + burnt := big.NewInt(0) + // burnt: len(Transactions) * baseFee * gasUsed + if header.BaseFee != nil { + burnt.Set(header.BaseFee) + burnt.Mul(burnt, big.NewInt(int64(header.GasUsed))) + } + + var blockReward uint256.Int + var uncleRewards []uint256.Int + if header.UncleHash == types.EmptyUncleHash { + blockReward, uncleRewards = ethash.AccumulateRewards(cfg.chainConfig, &header, nil) + } else { + body, _, _ := rawdb.ReadBody(tx, hash, currentBlockNumber) + if body == nil { + return fmt.Errorf("block body not found for block number %d", currentBlockNumber) + } + + blockReward, uncleRewards = ethash.AccumulateRewards(cfg.chainConfig, &header, body.Uncles) + } + // Set BlockReward + totalIssued.Add(totalIssued, blockReward.ToBig()) + // Compute uncleRewards + for _, uncleReward := range uncleRewards { + totalIssued.Add(totalIssued, uncleReward.ToBig()) + } + totalBurnt.Add(totalBurnt, burnt) + // Write to database + if err := rawdb.WriteTotalIssued(tx, currentBlockNumber, totalIssued); err != nil { + return err + } + if err := rawdb.WriteTotalBurnt(tx, currentBlockNumber, totalBurnt); err != nil { + return err + } + // Sleep and check for logs + select { + case <-ctx.Done(): + stopped = true + case <-logEvery.C: + log.Info(fmt.Sprintf("[%s] Wrote Block Issuance", s.LogPrefix()), + "now", currentBlockNumber, "blk/sec", float64(currentBlockNumber-prevProgress)/float64(logInterval/time.Second)) + prevProgress = currentBlockNumber + default: + log.Trace("RequestQueueTime (header) ticked") + } + } + if err = s.Update(tx, currentBlockNumber); err != nil { + return err + } + if !useExternalTx { + if err = tx.Commit(); err != nil { + return err + } + } + return nil +} + +func UnwindIssuanceStage(u *UnwindState, cfg IssuanceCfg, tx kv.RwTx, ctx context.Context) (err error) { + useExternalTx := tx != nil + if !useExternalTx { + tx, err = cfg.db.BeginRw(ctx) + if err != nil { + return err + } + defer tx.Rollback() + } + + if err = u.Done(tx); err != nil { + return fmt.Errorf(" reset: %w", err) + } + if !useExternalTx { + if err = tx.Commit(); err != nil { + return fmt.Errorf("failed to write db commit: %w", err) + } + } + return nil +} + +func PruneIssuanceStage(p *PruneState, cfg IssuanceCfg, tx kv.RwTx, ctx context.Context) (err error) { + useExternalTx := tx != nil + if !useExternalTx { + tx, err = cfg.db.BeginRw(ctx) + if err != nil { + return err + } + defer tx.Rollback() + } + + if !useExternalTx { + if err = tx.Commit(); err != nil { + return err + } + } + return nil +} diff --git a/eth/stagedsync/stage_issuance_test.go b/eth/stagedsync/stage_issuance_test.go new file mode 100644 index 00000000000..396d2a7e044 --- /dev/null +++ b/eth/stagedsync/stage_issuance_test.go @@ -0,0 +1,69 @@ +package stagedsync + +import ( + "context" + "math/big" + "testing" + + "github.com/ledgerwatch/erigon-lib/kv/memdb" + "github.com/ledgerwatch/erigon/core/rawdb" + "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/eth/stagedsync/stages" + "github.com/ledgerwatch/erigon/params" + "github.com/stretchr/testify/assert" +) + +func TestIssuanceStage(t *testing.T) { + ctx, assert := context.Background(), assert.New(t) + db, tx := memdb.NewTestTx(t) + + header1 := &types.Header{ + BaseFee: big.NewInt(10), + GasUsed: 1000, + Number: big.NewInt(1), + UncleHash: types.EmptyUncleHash, + Eip1559: true, + } + + header2 := &types.Header{ + BaseFee: big.NewInt(30), + GasUsed: 1000, + Number: big.NewInt(2), + UncleHash: types.EmptyUncleHash, + Eip1559: true, + } + + header3 := &types.Header{ + BaseFee: big.NewInt(100), + GasUsed: 1000, + Number: big.NewInt(3), + UncleHash: types.EmptyUncleHash, + Eip1559: true, + } + // Write Headers + rawdb.WriteHeader(tx, header1) + rawdb.WriteHeader(tx, header2) + rawdb.WriteHeader(tx, header3) + + stages.SaveStageProgress(tx, stages.Bodies, 3) + // Canonicals + rawdb.WriteCanonicalHash(tx, header1.Hash(), header1.Number.Uint64()) + rawdb.WriteCanonicalHash(tx, header2.Hash(), header2.Number.Uint64()) + rawdb.WriteCanonicalHash(tx, header3.Hash(), header3.Number.Uint64()) + // Execute stage issuance + err := SpawnStageIssuance(StageIssuanceCfg(db, ¶ms.ChainConfig{ + Consensus: params.EtHashConsensus, + }, true), &StageState{ + ID: stages.Issuance, + }, tx, ctx) + assert.NoError(err) + + tb, err := rawdb.ReadTotalBurnt(tx, 3) + assert.NoError(err) + assert.Equal(tb, big.NewInt(140000)) + + ti, err := rawdb.ReadTotalIssued(tx, 3) + assert.NoError(err) + issued, _ := new(big.Int).SetString("15000000000000000000", 10) + assert.Equal(ti, issued) +} diff --git a/eth/stagedsync/stages/stages.go b/eth/stagedsync/stages/stages.go index 0e4616c8841..c822376c26f 100644 --- a/eth/stagedsync/stages/stages.go +++ b/eth/stagedsync/stages/stages.go @@ -43,6 +43,7 @@ var ( CallTraces SyncStage = "CallTraces" // Generating call traces index TxLookup SyncStage = "TxLookup" // Generating transactions lookup index TxPool SyncStage = "TxPool" // Starts Backend + Issuance SyncStage = "WatchTheBurn" // Compute ether issuance for each block Finish SyncStage = "Finish" // Nominal stage after all other stages MiningCreateBlock SyncStage = "MiningCreateBlock" diff --git a/turbo/cli/default_flags.go b/turbo/cli/default_flags.go index e1240ea3016..000d2ee132f 100644 --- a/turbo/cli/default_flags.go +++ b/turbo/cli/default_flags.go @@ -75,6 +75,7 @@ var DefaultFlags = []cli.Flag{ utils.CliqueSnapshotInmemorySnapshotsFlag, utils.CliqueSnapshotInmemorySignaturesFlag, utils.CliqueDataDirFlag, + utils.EnabledIssuance, utils.MiningEnabledFlag, utils.MinerNotifyFlag, utils.MinerGasLimitFlag, diff --git a/turbo/stages/mock_sentry.go b/turbo/stages/mock_sentry.go index fb6ec0f9125..0812b019363 100644 --- a/turbo/stages/mock_sentry.go +++ b/turbo/stages/mock_sentry.go @@ -301,7 +301,7 @@ func MockWithEverything(t *testing.T, gspec *core.Genesis, key *ecdsa.PrivateKey mock.DB, cfg.BatchSize, mock.ChainConfig, - ), stagedsync.StageHashStateCfg(mock.DB, mock.tmpdir), stagedsync.StageTrieCfg(mock.DB, true, true, mock.tmpdir), stagedsync.StageHistoryCfg(mock.DB, prune, mock.tmpdir), stagedsync.StageLogIndexCfg(mock.DB, prune, mock.tmpdir), stagedsync.StageCallTracesCfg(mock.DB, prune, 0, mock.tmpdir), stagedsync.StageTxLookupCfg(mock.DB, prune, mock.tmpdir), stagedsync.StageTxPoolCfg(mock.DB, nil, cfg.TxPool, func() {}), stagedsync.StageFinishCfg(mock.DB, mock.tmpdir, mock.Log), true), + ), stagedsync.StageHashStateCfg(mock.DB, mock.tmpdir), stagedsync.StageTrieCfg(mock.DB, true, true, mock.tmpdir), stagedsync.StageHistoryCfg(mock.DB, prune, mock.tmpdir), stagedsync.StageLogIndexCfg(mock.DB, prune, mock.tmpdir), stagedsync.StageCallTracesCfg(mock.DB, prune, 0, mock.tmpdir), stagedsync.StageTxLookupCfg(mock.DB, prune, mock.tmpdir), stagedsync.StageTxPoolCfg(mock.DB, nil, cfg.TxPool, func() {}), stagedsync.StageIssuanceCfg(mock.DB, mock.ChainConfig, true), stagedsync.StageFinishCfg(mock.DB, mock.tmpdir, mock.Log), true), stagedsync.DefaultUnwindOrder, stagedsync.DefaultPruneOrder, ) diff --git a/turbo/stages/stageloop.go b/turbo/stages/stageloop.go index 84a340cdcdf..3218a63a8df 100644 --- a/turbo/stages/stageloop.go +++ b/turbo/stages/stageloop.go @@ -273,7 +273,7 @@ func NewStagedSync( } txPoolServer.TxFetcher.Start() } - }), stagedsync.StageFinishCfg(db, tmpdir, logger), false), + }), stagedsync.StageIssuanceCfg(db, controlServer.ChainConfig, cfg.EnabledIssuance), stagedsync.StageFinishCfg(db, tmpdir, logger), false), stagedsync.DefaultUnwindOrder, stagedsync.DefaultPruneOrder, ), nil From 8b7f1ddf770168fc2fc737bb13cd13cb1ac582d6 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Thu, 27 Jan 2022 10:03:03 +0000 Subject: [PATCH 137/261] Update version.go (#3363) --- params/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/params/version.go b/params/version.go index c79616d8346..23d080ccfaa 100644 --- a/params/version.go +++ b/params/version.go @@ -33,7 +33,7 @@ var ( const ( VersionMajor = 2022 // Major version component of the current release VersionMinor = 1 // Minor version component of the current release - VersionMicro = 2 // Patch version component of the current release + VersionMicro = 3 // Patch version component of the current release VersionModifier = "beta" // Patch version component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" From bd30504a43db3c3a795a408dc2148184fe986b5e Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Thu, 27 Jan 2022 10:03:17 +0000 Subject: [PATCH 138/261] [stable] Transaction pool fixes and improvements (#3352) * [stable] Transaction pool fixes and improvements * Fix test * Save * Add blockGasLimit to the state stream (#3321) * Add blockGasLimit to the state stream * Send block gas limit * Switch to new erigon-lib * Update * Update txpool - safe operations * Update erigon-lib * Txpool working * Update * Update * Update * Fix lint * fix lint Co-authored-by: Alex Sharp Co-authored-by: Alexey Sharp * Restore test * Switch to new erigon-lib * Update to erigon-lib stable Co-authored-by: Alexey Sharp Co-authored-by: Alex Sharp --- cmd/hack/hack.go | 1603 ---------------------- go.mod | 3 +- go.sum | 5 +- turbo/shards/state_change_accumulator.go | 4 +- turbo/stages/stageloop.go | 2 +- 5 files changed, 6 insertions(+), 1611 deletions(-) diff --git a/cmd/hack/hack.go b/cmd/hack/hack.go index 0f73fa5d896..b0d743272da 100644 --- a/cmd/hack/hack.go +++ b/cmd/hack/hack.go @@ -3,10 +3,8 @@ package main import ( "bufio" "bytes" - "container/heap" "context" "encoding/binary" - "encoding/hex" "errors" "flag" "fmt" @@ -19,23 +17,16 @@ import ( "runtime" "runtime/pprof" "sort" - "strconv" "strings" - "sync" - "sync/atomic" "syscall" "time" "github.com/RoaringBitmap/roaring/roaring64" - "github.com/flanglet/kanzi-go/transform" "github.com/holiman/uint256" - "github.com/ledgerwatch/erigon-lib/compress" "github.com/ledgerwatch/erigon-lib/etl" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv/mdbx" - "github.com/ledgerwatch/erigon-lib/patricia" "github.com/ledgerwatch/erigon-lib/recsplit" - "github.com/ledgerwatch/erigon-lib/txpool" hackdb "github.com/ledgerwatch/erigon/cmd/hack/db" "github.com/ledgerwatch/erigon/cmd/hack/flow" "github.com/ledgerwatch/erigon/cmd/hack/tool" @@ -1425,1509 +1416,6 @@ func genstate() error { return nil } -// processSuperstring is the worker that processes one superstring and puts results -// into the collector, using lock to mutual exclusion. At the end (when the input channel is closed), -// it notifies the waitgroup before exiting, so that the caller known when all work is done -// No error channels for now -func processSuperstring(superstringCh chan []byte, dictCollector *etl.Collector, completion *sync.WaitGroup) { - for superstring := range superstringCh { - //log.Info("Superstring", "len", len(superstring)) - sa := make([]int32, len(superstring)) - divsufsort, err := transform.NewDivSufSort() - if err != nil { - log.Error("processSuperstring", "create divsufsoet", err) - } - //start := time.Now() - divsufsort.ComputeSuffixArray(superstring, sa) - //log.Info("Suffix array built", "in", time.Since(start)) - // filter out suffixes that start with odd positions - n := len(sa) / 2 - filtered := make([]int, n) - var j int - for i := 0; i < len(sa); i++ { - if sa[i]&1 == 0 { - filtered[j] = int(sa[i] >> 1) - j++ - } - } - //log.Info("Suffix array filtered") - // invert suffixes - inv := make([]int, n) - for i := 0; i < n; i++ { - inv[filtered[i]] = i - } - //log.Info("Inverted array done") - lcp := make([]byte, n) - var k int - // Process all suffixes one by one starting from - // first suffix in txt[] - for i := 0; i < n; i++ { - /* If the current suffix is at n-1, then we don’t - have next substring to consider. So lcp is not - defined for this substring, we put zero. */ - if inv[i] == n-1 { - k = 0 - continue - } - - /* j contains index of the next substring to - be considered to compare with the present - substring, i.e., next string in suffix array */ - j := int(filtered[inv[i]+1]) - - // Directly start matching from k'th index as - // at-least k-1 characters will match - for i+k < n && j+k < n && superstring[(i+k)*2] != 0 && superstring[(j+k)*2] != 0 && superstring[(i+k)*2+1] == superstring[(j+k)*2+1] { - k++ - } - - lcp[inv[i]] = byte(k) // lcp for the present suffix. - - // Deleting the starting character from the string. - if k > 0 { - k-- - } - } - //log.Info("Kasai algorithm finished") - // Checking LCP array - /* - for i := 0; i < n-1; i++ { - var prefixLen int - p1 := int(filtered[i]) - p2 := int(filtered[i+1]) - for p1+prefixLen < n && p2+prefixLen < n && superstring[(p1+prefixLen)*2] != 0 && superstring[(p2+prefixLen)*2] != 0 && superstring[(p1+prefixLen)*2+1] == superstring[(p2+prefixLen)*2+1] { - prefixLen++ - } - if prefixLen != int(lcp[i]) { - log.Error("Mismatch", "prefixLen", prefixLen, "lcp[i]", lcp[i]) - } - l := int(lcp[i]) // Length of potential dictionary word - if l < 2 { - continue - } - dictKey := make([]byte, l) - for s := 0; s < l; s++ { - dictKey[s] = superstring[(filtered[i]+s)*2+1] - } - fmt.Printf("%d %d %s\n", filtered[i], lcp[i], dictKey) - } - */ - //log.Info("LCP array checked") - // Walk over LCP array and compute the scores of the strings - b := inv - j = 0 - for i := 0; i < n-1; i++ { - // Only when there is a drop in LCP value - if lcp[i+1] >= lcp[i] { - j = i - continue - } - for l := int(lcp[i]); l > int(lcp[i+1]); l-- { - if l < minPatternLen { - continue - } - // Go back - var new bool - for j > 0 && int(lcp[j-1]) >= l { - j-- - new = true - } - if !new { - break - } - window := i - j + 2 - copy(b, filtered[j:i+2]) - sort.Ints(b[:window]) - repeats := 1 - lastK := 0 - for k := 1; k < window; k++ { - if b[k] >= b[lastK]+l { - repeats++ - lastK = k - } - } - score := uint64(repeats * int(l-4)) - if score > minPatternScore { - // Dictionary key is the concatenation of the score and the dictionary word (to later aggregate the scores from multiple chunks) - dictKey := make([]byte, l) - for s := 0; s < l; s++ { - dictKey[s] = superstring[(filtered[i]+s)*2+1] - } - var dictVal [8]byte - binary.BigEndian.PutUint64(dictVal[:], score) - if err = dictCollector.Collect(dictKey, dictVal[:]); err != nil { - log.Error("processSuperstring", "collect", err) - } - } - } - } - } - completion.Done() -} - -type DictionaryItem struct { - word []byte - score uint64 -} - -type DictionaryBuilder struct { - limit int - lastWord []byte - lastWordScore uint64 - items []DictionaryItem -} - -func (db DictionaryBuilder) Len() int { - return len(db.items) -} - -func (db DictionaryBuilder) Less(i, j int) bool { - if db.items[i].score == db.items[j].score { - return bytes.Compare(db.items[i].word, db.items[j].word) < 0 - } - return db.items[i].score < db.items[j].score -} - -func (db *DictionaryBuilder) Swap(i, j int) { - db.items[i], db.items[j] = db.items[j], db.items[i] -} - -func (db *DictionaryBuilder) Push(x interface{}) { - db.items = append(db.items, x.(DictionaryItem)) -} - -func (db *DictionaryBuilder) Pop() interface{} { - old := db.items - n := len(old) - x := old[n-1] - db.items = old[0 : n-1] - return x -} - -func (db *DictionaryBuilder) processWord(word []byte, score uint64) { - heap.Push(db, DictionaryItem{word: word, score: score}) - if db.Len() > db.limit { - // Remove the element with smallest score - heap.Pop(db) - } -} - -func (db *DictionaryBuilder) compressLoadFunc(k, v []byte, table etl.CurrentTableReader, next etl.LoadNextFunc) error { - score := binary.BigEndian.Uint64(v) - if bytes.Equal(k, db.lastWord) { - db.lastWordScore += score - } else { - if db.lastWord != nil { - db.processWord(db.lastWord, db.lastWordScore) - } - db.lastWord = common.CopyBytes(k) - db.lastWordScore = score - } - return nil -} - -func (db *DictionaryBuilder) finish() { - if db.lastWord != nil { - db.processWord(db.lastWord, db.lastWordScore) - } -} - -type DictAggregator struct { - lastWord []byte - lastWordScore uint64 - collector *etl.Collector -} - -func (da *DictAggregator) processWord(word []byte, score uint64) error { - var scoreBuf [8]byte - binary.BigEndian.PutUint64(scoreBuf[:], score) - return da.collector.Collect(word, scoreBuf[:]) -} - -func (da *DictAggregator) aggLoadFunc(k, v []byte, table etl.CurrentTableReader, next etl.LoadNextFunc) error { - score := binary.BigEndian.Uint64(v) - if bytes.Equal(k, da.lastWord) { - da.lastWordScore += score - } else { - if da.lastWord != nil { - if err := da.processWord(da.lastWord, da.lastWordScore); err != nil { - return err - } - } - da.lastWord = common.CopyBytes(k) - da.lastWordScore = score - } - return nil -} - -func (da *DictAggregator) finish() error { - if da.lastWord != nil { - return da.processWord(da.lastWord, da.lastWordScore) - } - return nil -} - -const CompressLogPrefix = "compress" - -// superstringLimit limits how large can one "superstring" get before it is processed -// Compressor allocates 7 bytes for each uint of superstringLimit. For example, -// superstingLimit 16m will result in 112Mb being allocated for various arrays -const superstringLimit = 16 * 1024 * 1024 - -// minPatternLen is minimum length of pattern we consider to be included into the dictionary -const minPatternLen = 5 - -// minPatternScore is minimum score (per superstring) required to consider including pattern into the dictionary -const minPatternScore = 1024 - -// maxDictPatterns is the maximum number of patterns allowed in the initial (not reduced dictionary) -// Large values increase memory consumption of dictionary reduction phase -const maxDictPatterns = 1024 * 1024 - -func compress1(chaindata string, name string) error { - database := mdbx.MustOpen(chaindata) - defer database.Close() - chainConfig := tool.ChainConfigFromDB(database) - chainID, _ := uint256.FromBig(chainConfig.ChainID) - logEvery := time.NewTicker(20 * time.Second) - defer logEvery.Stop() - - var superstring []byte - // Read keys from the file and generate superstring (with extra byte 0x1 prepended to each character, and with 0x0 0x0 pair inserted between keys and values) - // We only consider values with length > 2, because smaller values are not compressible without going into bits - f, err := os.Open(name + ".dat") - if err != nil { - return err - } - r := bufio.NewReaderSize(f, etl.BufIOSize) - // Collector for dictionary words (sorted by their score) - tmpDir := "" - ch := make(chan []byte, runtime.NumCPU()) - var wg sync.WaitGroup - wg.Add(runtime.NumCPU()) - collectors := make([]*etl.Collector, runtime.NumCPU()) - for i := 0; i < runtime.NumCPU(); i++ { - collector := etl.NewCollector(CompressLogPrefix, tmpDir, etl.NewSortableBuffer(etl.BufferOptimalSize)) - collectors[i] = collector - go processSuperstring(ch, collector, &wg) - } - var buf []byte - l, e := binary.ReadUvarint(r) - i := 0 - for ; e == nil; l, e = binary.ReadUvarint(r) { - if len(buf) < int(l) { - buf = make([]byte, l) - } - if _, e = io.ReadFull(r, buf[:l]); e != nil { - return e - } - if len(superstring)+2*int(l)+2 > superstringLimit { - ch <- superstring - superstring = nil - } - for _, a := range buf[:l] { - superstring = append(superstring, 1, a) - } - superstring = append(superstring, 0, 0) - i++ - select { - default: - case <-logEvery.C: - log.Info("Dictionary preprocessing", "millions", i/1_000_000) - } - - } - itemsCount := i - if e != nil && !errors.Is(e, io.EOF) { - return e - } - if err = f.Close(); err != nil { - return err - } - if len(superstring) > 0 { - ch <- superstring - } - close(ch) - wg.Wait() - dictCollector := etl.NewCollector(CompressLogPrefix, tmpDir, etl.NewSortableBuffer(etl.BufferOptimalSize)) - dictAggregator := &DictAggregator{collector: dictCollector} - for _, collector := range collectors { - if err = collector.Load(nil, "", dictAggregator.aggLoadFunc, etl.TransformArgs{}); err != nil { - return err - } - collector.Close() - } - if err = dictAggregator.finish(); err != nil { - return err - } - db := &DictionaryBuilder{limit: maxDictPatterns} // Only collect 1m words with highest scores - if err = dictCollector.Load(nil, "", db.compressLoadFunc, etl.TransformArgs{}); err != nil { - return err - } - db.finish() - dictCollector.Close() - var df *os.File - df, err = os.Create(name + ".dictionary.txt") - if err != nil { - return err - } - w := bufio.NewWriterSize(df, etl.BufIOSize) - // Sort dictionary builder - sort.Sort(db) - - for i := len(db.items); i > 0; i-- { - fmt.Fprintf(w, "%d %x\n", db.items[i-1].score, db.items[i-1].word) - } - if err = w.Flush(); err != nil { - return err - } - df.Close() - - if err := reducedict(name); err != nil { - return err - } - if err := _createIdx(*chainID, name, itemsCount); err != nil { - return err - } - return nil -} - -// DynamicCell represents result of dynamic programming for certain starting position -type DynamicCell struct { - optimStart int - coverStart int - compression int - score uint64 - patternIdx int // offset of the last element in the pattern slice -} - -type Ring struct { - cells []DynamicCell - head, tail, count int -} - -func NewRing() *Ring { - return &Ring{ - cells: make([]DynamicCell, 16), - head: 0, - tail: 0, - count: 0, - } -} - -func (r *Ring) Reset() { - r.count = 0 - r.head = 0 - r.tail = 0 -} - -func (r *Ring) ensureSize() { - if r.count < len(r.cells) { - return - } - newcells := make([]DynamicCell, r.count*2) - if r.tail > r.head { - copy(newcells, r.cells[r.head:r.tail]) - } else { - n := copy(newcells, r.cells[r.head:]) - copy(newcells[n:], r.cells[:r.tail]) - } - r.head = 0 - r.tail = r.count - r.cells = newcells -} - -func (r *Ring) PushFront() *DynamicCell { - r.ensureSize() - if r.head == 0 { - r.head = len(r.cells) - } - r.head-- - r.count++ - return &r.cells[r.head] -} - -func (r *Ring) PushBack() *DynamicCell { - r.ensureSize() - if r.tail == len(r.cells) { - r.tail = 0 - } - result := &r.cells[r.tail] - r.tail++ - r.count++ - return result -} - -func (r Ring) Len() int { - return r.count -} - -func (r *Ring) Get(i int) *DynamicCell { - if i < 0 || i >= r.count { - return nil - } - return &r.cells[(r.head+i)&(len(r.cells)-1)] -} - -// Truncate removes all items starting from i -func (r *Ring) Truncate(i int) { - r.count = i - r.tail = (r.head + i) & (len(r.cells) - 1) -} - -func optimiseCluster(trace bool, numBuf []byte, input []byte, trie *patricia.PatriciaTree, mf *patricia.MatchFinder, output []byte, uncovered []int, patterns []int, cellRing *Ring, posMap map[uint64]uint64) ([]byte, []int, []int) { - matches := mf.FindLongestMatches(trie, input) - if len(matches) == 0 { - n := binary.PutUvarint(numBuf, 0) - output = append(output, numBuf[:n]...) - output = append(output, input...) - return output, patterns, uncovered - } - if trace { - fmt.Printf("Cluster | input = %x\n", input) - for _, match := range matches { - fmt.Printf(" [%x %d-%d]", input[match.Start:match.End], match.Start, match.End) - } - } - cellRing.Reset() - patterns = append(patterns[:0], 0, 0) // Sentinel entry - no meaning - lastF := matches[len(matches)-1] - for j := lastF.Start; j < lastF.End; j++ { - d := cellRing.PushBack() - d.optimStart = j + 1 - d.coverStart = len(input) - d.compression = 0 - d.patternIdx = 0 - d.score = 0 - } - // Starting from the last match - for i := len(matches); i > 0; i-- { - f := matches[i-1] - p := f.Val.(*Pattern) - firstCell := cellRing.Get(0) - if firstCell == nil { - fmt.Printf("cellRing.Len() = %d\n", cellRing.Len()) - } - maxCompression := firstCell.compression - maxScore := firstCell.score - maxCell := firstCell - var maxInclude bool - for e := 0; e < cellRing.Len(); e++ { - cell := cellRing.Get(e) - comp := cell.compression - 4 - if cell.coverStart >= f.End { - comp += f.End - f.Start - } else { - comp += cell.coverStart - f.Start - } - score := cell.score + p.score - if comp > maxCompression || (comp == maxCompression && score > maxScore) { - maxCompression = comp - maxScore = score - maxInclude = true - maxCell = cell - } - if cell.optimStart > f.End { - cellRing.Truncate(e) - break - } - } - d := cellRing.PushFront() - d.optimStart = f.Start - d.score = maxScore - d.compression = maxCompression - if maxInclude { - if trace { - fmt.Printf("[include] cell for %d: with patterns", f.Start) - fmt.Printf(" [%x %d-%d]", input[f.Start:f.End], f.Start, f.End) - patternIdx := maxCell.patternIdx - for patternIdx != 0 { - pattern := patterns[patternIdx] - fmt.Printf(" [%x %d-%d]", input[matches[pattern].Start:matches[pattern].End], matches[pattern].Start, matches[pattern].End) - patternIdx = patterns[patternIdx+1] - } - fmt.Printf("\n\n") - } - d.coverStart = f.Start - d.patternIdx = len(patterns) - patterns = append(patterns, i-1, maxCell.patternIdx) - } else { - if trace { - fmt.Printf("cell for %d: with patterns", f.Start) - patternIdx := maxCell.patternIdx - for patternIdx != 0 { - pattern := patterns[patternIdx] - fmt.Printf(" [%x %d-%d]", input[matches[pattern].Start:matches[pattern].End], matches[pattern].Start, matches[pattern].End) - patternIdx = patterns[patternIdx+1] - } - fmt.Printf("\n\n") - } - d.coverStart = maxCell.coverStart - d.patternIdx = maxCell.patternIdx - } - } - optimCell := cellRing.Get(0) - if trace { - fmt.Printf("optimal =") - } - // Count number of patterns - var patternCount uint64 - patternIdx := optimCell.patternIdx - for patternIdx != 0 { - patternCount++ - patternIdx = patterns[patternIdx+1] - } - p := binary.PutUvarint(numBuf, patternCount) - output = append(output, numBuf[:p]...) - patternIdx = optimCell.patternIdx - lastStart := 0 - var lastUncovered int - uncovered = uncovered[:0] - for patternIdx != 0 { - pattern := patterns[patternIdx] - p := matches[pattern].Val.(*Pattern) - if trace { - fmt.Printf(" [%x %d-%d]", input[matches[pattern].Start:matches[pattern].End], matches[pattern].Start, matches[pattern].End) - } - if matches[pattern].Start > lastUncovered { - uncovered = append(uncovered, lastUncovered, matches[pattern].Start) - } - lastUncovered = matches[pattern].End - // Starting position - posMap[uint64(matches[pattern].Start-lastStart+1)]++ - lastStart = matches[pattern].Start - n := binary.PutUvarint(numBuf, uint64(matches[pattern].Start)) - output = append(output, numBuf[:n]...) - // Code - n = binary.PutUvarint(numBuf, p.code) - output = append(output, numBuf[:n]...) - atomic.AddUint64(&p.uses, 1) - patternIdx = patterns[patternIdx+1] - } - if len(input) > lastUncovered { - uncovered = append(uncovered, lastUncovered, len(input)) - } - if trace { - fmt.Printf("\n\n") - } - // Add uncoded input - for i := 0; i < len(uncovered); i += 2 { - output = append(output, input[uncovered[i]:uncovered[i+1]]...) - } - return output, patterns, uncovered -} - -func reduceDictWorker(inputCh chan []byte, completion *sync.WaitGroup, trie *patricia.PatriciaTree, collector *etl.Collector, inputSize *uint64, outputSize *uint64, posMap map[uint64]uint64) { - defer completion.Done() - var output = make([]byte, 0, 256) - var uncovered = make([]int, 256) - var patterns = make([]int, 0, 256) - cellRing := NewRing() - var mf patricia.MatchFinder - numBuf := make([]byte, binary.MaxVarintLen64) - for input := range inputCh { - // First 8 bytes are idx - n := binary.PutUvarint(numBuf, uint64(len(input)-8)) - output = append(output[:0], numBuf[:n]...) - if len(input) > 8 { - output, patterns, uncovered = optimiseCluster(false, numBuf, input[8:], trie, &mf, output, uncovered, patterns, cellRing, posMap) - if err := collector.Collect(input[:8], output); err != nil { - log.Error("Could not collect", "error", err) - return - } - } - atomic.AddUint64(inputSize, 1+uint64(len(input)-8)) - atomic.AddUint64(outputSize, uint64(len(output))) - posMap[uint64(len(input)-8+1)]++ - posMap[0]++ - } -} - -type Pattern struct { - score uint64 - uses uint64 - code uint64 // Allocated numerical code - codeBits int // Number of bits in the code - w []byte - offset uint64 // Offset of this patten in the dictionary representation -} - -// PatternList is a sorted list of pattern for the purpose of -// building Huffman tree to determine efficient coding. -// Patterns with least usage come first, we use numerical code -// as a tie breaker to make sure the resulting Huffman code is canonical -type PatternList []*Pattern - -func (pl PatternList) Len() int { - return len(pl) -} - -func (pl PatternList) Less(i, j int) bool { - if pl[i].uses == pl[j].uses { - return pl[i].code < pl[j].code - } - return pl[i].uses < pl[j].uses -} - -func (pl *PatternList) Swap(i, j int) { - (*pl)[i], (*pl)[j] = (*pl)[j], (*pl)[i] -} - -type PatternHuff struct { - uses uint64 - tieBreaker uint64 - p0, p1 *Pattern - h0, h1 *PatternHuff - offset uint64 // Offset of this huffman tree node in the dictionary representation -} - -func (h *PatternHuff) AddZero() { - if h.p0 != nil { - h.p0.code <<= 1 - h.p0.codeBits++ - } else { - h.h0.AddZero() - } - if h.p1 != nil { - h.p1.code <<= 1 - h.p1.codeBits++ - } else { - h.h1.AddZero() - } -} - -func (h *PatternHuff) AddOne() { - if h.p0 != nil { - h.p0.code <<= 1 - h.p0.code++ - h.p0.codeBits++ - } else { - h.h0.AddOne() - } - if h.p1 != nil { - h.p1.code <<= 1 - h.p1.code++ - h.p1.codeBits++ - } else { - h.h1.AddOne() - } -} - -// PatternHeap is priority queue of pattern for the purpose of building -// Huffman tree to determine efficient coding. Patterns with least usage -// have highest priority. We use a tie-breaker to make sure -// the resulting Huffman code is canonical -type PatternHeap []*PatternHuff - -func (ph PatternHeap) Len() int { - return len(ph) -} - -func (ph PatternHeap) Less(i, j int) bool { - if ph[i].uses == ph[j].uses { - return ph[i].tieBreaker < ph[j].tieBreaker - } - return ph[i].uses < ph[j].uses -} - -func (ph *PatternHeap) Swap(i, j int) { - (*ph)[i], (*ph)[j] = (*ph)[j], (*ph)[i] -} - -func (ph *PatternHeap) Push(x interface{}) { - *ph = append(*ph, x.(*PatternHuff)) -} - -func (ph *PatternHeap) Pop() interface{} { - old := *ph - n := len(old) - x := old[n-1] - *ph = old[0 : n-1] - return x -} - -type Position struct { - pos uint64 - uses uint64 - code uint64 - codeBits int - offset uint64 -} - -type PositionHuff struct { - uses uint64 - tieBreaker uint64 - p0, p1 *Position - h0, h1 *PositionHuff - offset uint64 -} - -func (h *PositionHuff) AddZero() { - if h.p0 != nil { - h.p0.code <<= 1 - h.p0.codeBits++ - } else { - h.h0.AddZero() - } - if h.p1 != nil { - h.p1.code <<= 1 - h.p1.codeBits++ - } else { - h.h1.AddZero() - } -} - -func (h *PositionHuff) AddOne() { - if h.p0 != nil { - h.p0.code <<= 1 - h.p0.code++ - h.p0.codeBits++ - } else { - h.h0.AddOne() - } - if h.p1 != nil { - h.p1.code <<= 1 - h.p1.code++ - h.p1.codeBits++ - } else { - h.h1.AddOne() - } -} - -type PositionList []*Position - -func (pl PositionList) Len() int { - return len(pl) -} - -func (pl PositionList) Less(i, j int) bool { - if pl[i].uses == pl[j].uses { - return pl[i].pos < pl[j].pos - } - return pl[i].uses < pl[j].uses -} - -func (pl *PositionList) Swap(i, j int) { - (*pl)[i], (*pl)[j] = (*pl)[j], (*pl)[i] -} - -type PositionHeap []*PositionHuff - -func (ph PositionHeap) Len() int { - return len(ph) -} - -func (ph PositionHeap) Less(i, j int) bool { - if ph[i].uses == ph[j].uses { - return ph[i].tieBreaker < ph[j].tieBreaker - } - return ph[i].uses < ph[j].uses -} - -func (ph *PositionHeap) Swap(i, j int) { - (*ph)[i], (*ph)[j] = (*ph)[j], (*ph)[i] -} - -func (ph *PositionHeap) Push(x interface{}) { - *ph = append(*ph, x.(*PositionHuff)) -} - -func (ph *PositionHeap) Pop() interface{} { - old := *ph - n := len(old) - x := old[n-1] - *ph = old[0 : n-1] - return x -} - -type HuffmanCoder struct { - w *bufio.Writer - outputBits int - outputByte byte -} - -func (hf *HuffmanCoder) encode(code uint64, codeBits int) error { - for codeBits > 0 { - var bitsUsed int - if hf.outputBits+codeBits > 8 { - bitsUsed = 8 - hf.outputBits - } else { - bitsUsed = codeBits - } - mask := (uint64(1) << bitsUsed) - 1 - hf.outputByte |= byte((code & mask) << hf.outputBits) - code >>= bitsUsed - codeBits -= bitsUsed - hf.outputBits += bitsUsed - if hf.outputBits == 8 { - if e := hf.w.WriteByte(hf.outputByte); e != nil { - return e - } - hf.outputBits = 0 - hf.outputByte = 0 - } - } - return nil -} - -func (hf *HuffmanCoder) flush() error { - if hf.outputBits > 0 { - if e := hf.w.WriteByte(hf.outputByte); e != nil { - return e - } - hf.outputBits = 0 - hf.outputByte = 0 - } - return nil -} - -// reduceDict reduces the dictionary by trying the substitutions and counting frequency for each word -func reducedict(name string) error { - logEvery := time.NewTicker(20 * time.Second) - defer logEvery.Stop() - // Read up the dictionary - df, err := os.Open(name + ".dictionary.txt") - if err != nil { - return err - } - // DictonaryBuilder is for sorting words by their freuency (to assign codes) - var pt patricia.PatriciaTree - code2pattern := make([]*Pattern, 0, 256) - ds := bufio.NewScanner(df) - for ds.Scan() { - tokens := strings.Split(ds.Text(), " ") - var score int64 - if score, err = strconv.ParseInt(tokens[0], 10, 64); err != nil { - return err - } - var word []byte - if word, err = hex.DecodeString(tokens[1]); err != nil { - return err - } - p := &Pattern{ - score: uint64(score), - uses: 0, - code: uint64(len(code2pattern)), - codeBits: 0, - w: word, - } - pt.Insert(word, p) - code2pattern = append(code2pattern, p) - } - if err = df.Close(); err != nil { - return err - } - log.Info("dictionary file parsed", "entries", len(code2pattern)) - statefile := name + ".dat" - f, err := os.Open(statefile) - if err != nil { - return err - } - r := bufio.NewReader(f) - var buf []byte - tmpDir := "" - ch := make(chan []byte, 10000) - var inputSize, outputSize uint64 - var wg sync.WaitGroup - var collectors []*etl.Collector - var posMaps []map[uint64]uint64 - for i := 0; i < runtime.NumCPU(); i++ { - collector := etl.NewCollector(CompressLogPrefix, tmpDir, etl.NewSortableBuffer(etl.BufferOptimalSize)) - collectors = append(collectors, collector) - posMap := make(map[uint64]uint64) - posMaps = append(posMaps, posMap) - wg.Add(1) - go reduceDictWorker(ch, &wg, &pt, collector, &inputSize, &outputSize, posMap) - } - l, e := binary.ReadUvarint(r) - i := 0 - for ; e == nil; l, e = binary.ReadUvarint(r) { - if len(buf) < int(l) { - buf = make([]byte, l) - } - if _, e = io.ReadFull(r, buf[:l]); e != nil { - return e - } - input := make([]byte, 8+int(l)) - binary.BigEndian.PutUint64(input, uint64(i)) - copy(input[8:], buf[:l]) - ch <- input - i++ - select { - default: - case <-logEvery.C: - var m runtime.MemStats - runtime.ReadMemStats(&m) - log.Info("Replacement preprocessing", "millions", i/1_000_000, "input", common.StorageSize(atomic.LoadUint64(&inputSize)), "output", common.StorageSize(atomic.LoadUint64(&outputSize)), "alloc", common.StorageSize(m.Alloc), "sys", common.StorageSize(m.Sys)) - } - } - if e != nil && !errors.Is(e, io.EOF) { - return e - } - if err = f.Close(); err != nil { - return err - } - close(ch) - wg.Wait() - var m runtime.MemStats - runtime.ReadMemStats(&m) - log.Info("Done", "input", common.StorageSize(atomic.LoadUint64(&inputSize)), "output", common.StorageSize(atomic.LoadUint64(&outputSize)), "alloc", common.StorageSize(m.Alloc), "sys", common.StorageSize(m.Sys)) - posMap := make(map[uint64]uint64) - for _, m := range posMaps { - for l, c := range m { - posMap[l] += c - } - } - fmt.Printf("posMap = %v\n", posMap) - var patternList PatternList - for _, p := range code2pattern { - if p.uses > 0 { - patternList = append(patternList, p) - } - } - sort.Sort(&patternList) - // Calculate offsets of the dictionary patterns and total size - var offset uint64 - numBuf := make([]byte, binary.MaxVarintLen64) - for _, p := range patternList { - p.offset = offset - n := binary.PutUvarint(numBuf, uint64(len(p.w))) - offset += uint64(n + len(p.w)) - } - patternCutoff := offset // All offsets below this will be considered patterns - i = 0 - log.Info("Effective dictionary", "size", patternList.Len()) - // Build Huffman tree for codes - var codeHeap PatternHeap - heap.Init(&codeHeap) - tieBreaker := uint64(0) - var huffs []*PatternHuff // To be used to output dictionary - for codeHeap.Len()+(patternList.Len()-i) > 1 { - // New node - h := &PatternHuff{ - tieBreaker: tieBreaker, - offset: offset, - } - if codeHeap.Len() > 0 && (i >= patternList.Len() || codeHeap[0].uses < patternList[i].uses) { - // Take h0 from the heap - h.h0 = heap.Pop(&codeHeap).(*PatternHuff) - h.h0.AddZero() - h.uses += h.h0.uses - n := binary.PutUvarint(numBuf, h.h0.offset) - offset += uint64(n) - } else { - // Take p0 from the list - h.p0 = patternList[i] - h.p0.code = 0 - h.p0.codeBits = 1 - h.uses += h.p0.uses - n := binary.PutUvarint(numBuf, h.p0.offset) - offset += uint64(n) - i++ - } - if codeHeap.Len() > 0 && (i >= patternList.Len() || codeHeap[0].uses < patternList[i].uses) { - // Take h1 from the heap - h.h1 = heap.Pop(&codeHeap).(*PatternHuff) - h.h1.AddOne() - h.uses += h.h1.uses - n := binary.PutUvarint(numBuf, h.h1.offset) - offset += uint64(n) - } else { - // Take p1 from the list - h.p1 = patternList[i] - h.p1.code = 1 - h.p1.codeBits = 1 - h.uses += h.p1.uses - n := binary.PutUvarint(numBuf, h.p1.offset) - offset += uint64(n) - i++ - } - tieBreaker++ - heap.Push(&codeHeap, h) - huffs = append(huffs, h) - } - root := heap.Pop(&codeHeap).(*PatternHuff) - var cf *os.File - if cf, err = os.Create(name + ".compressed.dat"); err != nil { - return err - } - cw := bufio.NewWriterSize(cf, etl.BufIOSize) - // First, output dictionary - binary.BigEndian.PutUint64(numBuf, offset) // Dictionary size - if _, err = cw.Write(numBuf[:8]); err != nil { - return err - } - // Secondly, output directory root - binary.BigEndian.PutUint64(numBuf, root.offset) - if _, err = cw.Write(numBuf[:8]); err != nil { - return err - } - // Thirdly, output pattern cutoff offset - binary.BigEndian.PutUint64(numBuf, patternCutoff) - if _, err = cw.Write(numBuf[:8]); err != nil { - return err - } - // Write all the pattens - for _, p := range patternList { - n := binary.PutUvarint(numBuf, uint64(len(p.w))) - if _, err = cw.Write(numBuf[:n]); err != nil { - return err - } - if _, err = cw.Write(p.w); err != nil { - return err - } - } - // Write all the huffman nodes - for _, h := range huffs { - var n int - if h.h0 != nil { - n = binary.PutUvarint(numBuf, h.h0.offset) - } else { - n = binary.PutUvarint(numBuf, h.p0.offset) - } - if _, err = cw.Write(numBuf[:n]); err != nil { - return err - } - if h.h1 != nil { - n = binary.PutUvarint(numBuf, h.h1.offset) - } else { - n = binary.PutUvarint(numBuf, h.p1.offset) - } - if _, err = cw.Write(numBuf[:n]); err != nil { - return err - } - } - log.Info("Dictionary", "size", offset, "pattern cutoff", patternCutoff) - - var positionList PositionList - pos2code := make(map[uint64]*Position) - for pos, uses := range posMap { - p := &Position{pos: pos, uses: uses, code: 0, codeBits: 0, offset: 0} - positionList = append(positionList, p) - pos2code[pos] = p - } - sort.Sort(&positionList) - // Calculate offsets of the dictionary positions and total size - offset = 0 - for _, p := range positionList { - p.offset = offset - n := binary.PutUvarint(numBuf, p.pos) - offset += uint64(n) - } - positionCutoff := offset // All offsets below this will be considered positions - i = 0 - log.Info("Positional dictionary", "size", positionList.Len()) - // Build Huffman tree for codes - var posHeap PositionHeap - heap.Init(&posHeap) - tieBreaker = uint64(0) - var posHuffs []*PositionHuff // To be used to output dictionary - for posHeap.Len()+(positionList.Len()-i) > 1 { - // New node - h := &PositionHuff{ - tieBreaker: tieBreaker, - offset: offset, - } - if posHeap.Len() > 0 && (i >= positionList.Len() || posHeap[0].uses < positionList[i].uses) { - // Take h0 from the heap - h.h0 = heap.Pop(&posHeap).(*PositionHuff) - h.h0.AddZero() - h.uses += h.h0.uses - n := binary.PutUvarint(numBuf, h.h0.offset) - offset += uint64(n) - } else { - // Take p0 from the list - h.p0 = positionList[i] - h.p0.code = 0 - h.p0.codeBits = 1 - h.uses += h.p0.uses - n := binary.PutUvarint(numBuf, h.p0.offset) - offset += uint64(n) - i++ - } - if posHeap.Len() > 0 && (i >= positionList.Len() || posHeap[0].uses < positionList[i].uses) { - // Take h1 from the heap - h.h1 = heap.Pop(&posHeap).(*PositionHuff) - h.h1.AddOne() - h.uses += h.h1.uses - n := binary.PutUvarint(numBuf, h.h1.offset) - offset += uint64(n) - } else { - // Take p1 from the list - h.p1 = positionList[i] - h.p1.code = 1 - h.p1.codeBits = 1 - h.uses += h.p1.uses - n := binary.PutUvarint(numBuf, h.p1.offset) - offset += uint64(n) - i++ - } - tieBreaker++ - heap.Push(&posHeap, h) - posHuffs = append(posHuffs, h) - } - posRoot := heap.Pop(&posHeap).(*PositionHuff) - // First, output dictionary - binary.BigEndian.PutUint64(numBuf, offset) // Dictionary size - if _, err = cw.Write(numBuf[:8]); err != nil { - return err - } - // Secondly, output directory root - binary.BigEndian.PutUint64(numBuf, posRoot.offset) - if _, err = cw.Write(numBuf[:8]); err != nil { - return err - } - // Thirdly, output pattern cutoff offset - binary.BigEndian.PutUint64(numBuf, positionCutoff) - if _, err = cw.Write(numBuf[:8]); err != nil { - return err - } - // Write all the positions - for _, p := range positionList { - n := binary.PutUvarint(numBuf, p.pos) - if _, err = cw.Write(numBuf[:n]); err != nil { - return err - } - } - // Write all the huffman nodes - for _, h := range posHuffs { - var n int - if h.h0 != nil { - n = binary.PutUvarint(numBuf, h.h0.offset) - } else { - n = binary.PutUvarint(numBuf, h.p0.offset) - } - if _, err = cw.Write(numBuf[:n]); err != nil { - return err - } - if h.h1 != nil { - n = binary.PutUvarint(numBuf, h.h1.offset) - } else { - n = binary.PutUvarint(numBuf, h.p1.offset) - } - if _, err = cw.Write(numBuf[:n]); err != nil { - return err - } - } - log.Info("Positional dictionary", "size", offset, "position cutoff", positionCutoff) - df, err = os.Create("huffman_codes.txt") - if err != nil { - return err - } - w := bufio.NewWriterSize(df, etl.BufIOSize) - for _, p := range positionList { - fmt.Fprintf(w, "%d %x %d uses %d\n", p.codeBits, p.code, p.pos, p.uses) - } - if err = w.Flush(); err != nil { - return err - } - df.Close() - - aggregator := etl.NewCollector(CompressLogPrefix, tmpDir, etl.NewSortableBuffer(etl.BufferOptimalSize)) - for _, collector := range collectors { - if err = collector.Load(nil, "", func(k, v []byte, table etl.CurrentTableReader, next etl.LoadNextFunc) error { - return aggregator.Collect(k, v) - }, etl.TransformArgs{}); err != nil { - return err - } - collector.Close() - } - - wc := 0 - var hc HuffmanCoder - hc.w = cw - if err = aggregator.Load(nil, "", func(k, v []byte, table etl.CurrentTableReader, next etl.LoadNextFunc) error { - // Re-encode it - r := bytes.NewReader(v) - var l uint64 - var e error - if l, err = binary.ReadUvarint(r); e != nil { - return e - } - posCode := pos2code[l+1] - if e = hc.encode(posCode.code, posCode.codeBits); e != nil { - return e - } - if l > 0 { - var pNum uint64 // Number of patterns - if pNum, e = binary.ReadUvarint(r); e != nil { - return e - } - // Now reading patterns one by one - var lastPos uint64 - var lastUncovered int - var uncoveredCount int - for i := 0; i < int(pNum); i++ { - var pos uint64 // Starting position for pattern - if pos, e = binary.ReadUvarint(r); e != nil { - return e - } - posCode = pos2code[pos-lastPos+1] - lastPos = pos - if e = hc.encode(posCode.code, posCode.codeBits); e != nil { - return e - } - var code uint64 // Code of the pattern - if code, e = binary.ReadUvarint(r); e != nil { - return e - } - patternCode := code2pattern[code] - if int(pos) > lastUncovered { - uncoveredCount += int(pos) - lastUncovered - } - lastUncovered = int(pos) + len(patternCode.w) - if e = hc.encode(patternCode.code, patternCode.codeBits); e != nil { - return e - } - } - if int(l) > lastUncovered { - uncoveredCount += int(l) - lastUncovered - } - // Terminating position and flush - posCode = pos2code[0] - if e = hc.encode(posCode.code, posCode.codeBits); e != nil { - return e - } - if e = hc.flush(); e != nil { - return e - } - // Copy uncovered characters - if uncoveredCount > 0 { - if _, e = io.CopyN(cw, r, int64(uncoveredCount)); e != nil { - return e - } - } - } - wc++ - if wc%10_000_000 == 0 { - log.Info("Compressed", "millions", wc/1_000_000) - } - return nil - }, etl.TransformArgs{}); err != nil { - return err - } - aggregator.Close() - if err = cw.Flush(); err != nil { - return err - } - if err = cf.Close(); err != nil { - return err - } - return nil -} -func recsplitLookup(chaindata, name string) error { - database := mdbx.MustOpen(chaindata) - defer database.Close() - chainConfig := tool.ChainConfigFromDB(database) - chainID, _ := uint256.FromBig(chainConfig.ChainID) - logEvery := time.NewTicker(20 * time.Second) - defer logEvery.Stop() - - d, err := compress.NewDecompressor(name + ".compressed.dat") - if err != nil { - return err - } - defer d.Close() - - idx := recsplit.MustOpen(name + ".idx") - defer idx.Close() - - var word, word2 = make([]byte, 0, 4096), make([]byte, 0, 4096) - wc := 0 - g := d.MakeGetter() - dataGetter := d.MakeGetter() - - parseCtx := txpool.NewTxParseContext(*chainID) - parseCtx.WithSender(false) - slot := txpool.TxSlot{} - var sender [20]byte - var l1, l2, total time.Duration - start := time.Now() - var prev []byte - var prevOffset uint64 - for g.HasNext() { - word, _ = g.Next(word[:0]) - if _, err := parseCtx.ParseTransaction(word[1:], 0, &slot, sender[:]); err != nil { - return err - } - wc++ - - t := time.Now() - recID := idx.Lookup(slot.IdHash[:]) - l1 += time.Since(t) - t = time.Now() - offset := idx.Lookup2(recID) - l2 += time.Since(t) - if ASSERT { - var dataP uint64 - if prev != nil { - dataGetter.Reset(prevOffset) - word2, dataP = dataGetter.Next(word2[:0]) - if !bytes.Equal(word, word2) { - fmt.Printf("wc=%d, %d,%d\n", wc, offset, dataP-uint64(len(word2))) - fmt.Printf("word: %x,%x\n\n", word, word2) - panic(fmt.Errorf("getter returned wrong data. IdHash=%x, offset=%x", slot.IdHash[:], offset)) - } - } - prev = common.CopyBytes(word) - prevOffset = offset - } - - select { - default: - case <-logEvery.C: - var m runtime.MemStats - runtime.ReadMemStats(&m) - log.Info("Checked", "millions", float64(wc)/1_000_000, - "lookup", time.Duration(int64(l1)/int64(wc)), "lookup2", time.Duration(int64(l2)/int64(wc)), - "alloc", common.StorageSize(m.Alloc), "sys", common.StorageSize(m.Sys), - ) - } - } - - total = time.Since(start) - log.Info("Average decoding time", "lookup", time.Duration(int64(l1)/int64(wc)), "lookup + lookup2", time.Duration(int64(l2)/int64(wc)), "items", wc, "total", total) - return nil -} - -func createIdx(chaindata string, name string) error { - database := mdbx.MustOpen(chaindata) - defer database.Close() - chainConfig := tool.ChainConfigFromDB(database) - chainID, _ := uint256.FromBig(chainConfig.ChainID) - d, err := compress.NewDecompressor(name + ".compressed.dat") - if err != nil { - return err - } - defer d.Close() - logEvery := time.NewTicker(20 * time.Second) - defer logEvery.Stop() - g := d.MakeGetter() - var word = make([]byte, 0, 4*1024) - wc := 0 - for g.HasNext() { - word, _ = g.Next(word[:0]) - wc++ - select { - default: - case <-logEvery.C: - log.Info("[Filling recsplit] Processed", "millions", wc/1_000_000) - } - } - return _createIdx(*chainID, name, wc) -} -func _createIdx(chainID uint256.Int, name string, count int) error { - d, err := compress.NewDecompressor(name + ".compressed.dat") - if err != nil { - return err - } - defer d.Close() - logEvery := time.NewTicker(20 * time.Second) - defer logEvery.Stop() - rs, err := recsplit.NewRecSplit(recsplit.RecSplitArgs{ - KeyCount: int(count), - Enums: true, - BucketSize: 2000, - Salt: 0, - LeafSize: 8, - TmpDir: "", - StartSeed: []uint64{0x106393c187cae21a, 0x6453cec3f7376937, 0x643e521ddbd2be98, 0x3740c6412f6572cb, 0x717d47562f1ce470, 0x4cd6eb4c63befb7c, 0x9bfd8c5e18c8da73, - 0x082f20e10092a9a3, 0x2ada2ce68d21defc, 0xe33cb4f3e7c6466b, 0x3980be458c509c59, 0xc466fd9584828e8c, 0x45f0aabe1a61ede6, 0xf6e7b8b33ad9b98d, - 0x4ef95e25f4b4983d, 0x81175195173b92d3, 0x4e50927d8dd15978, 0x1ea2099d1fafae7f, 0x425c8a06fbaaa815, 0xcd4216006c74052a}, - IndexFile: name + ".idx", - }) - if err != nil { - return err - } - -RETRY: - - var word = make([]byte, 0, 256) - g := d.MakeGetter() - wc := 0 - var pos uint64 - parseCtx := txpool.NewTxParseContext(chainID) - parseCtx.WithSender(false) - slot := txpool.TxSlot{} - var sender [20]byte - - for g.HasNext() { - word, pos = g.Next(word[:0]) - if _, err := parseCtx.ParseTransaction(word[1:], 0, &slot, sender[:]); err != nil { - return err - } - if err := rs.AddKey(slot.IdHash[:], pos); err != nil { - return err - } - wc++ - select { - default: - case <-logEvery.C: - log.Info("[Filling recsplit] Processed", "millions", wc/1_000_000) - } - } - log.Info("Building recsplit...") - - if err = rs.Build(); err != nil { - return err - } - - if rs.Collision() { - log.Info("Building recsplit. Collision happened. It's ok. Restarting...") - rs.ResetNextSalt() - goto RETRY - } - return nil -} -func decompress(name string) error { - d, err := compress.NewDecompressor(name + ".compressed.dat") - if err != nil { - return err - } - defer d.Close() - logEvery := time.NewTicker(20 * time.Second) - defer logEvery.Stop() - var df *os.File - if df, err = os.Create(name + ".decompressed.dat"); err != nil { - return err - } - dw := bufio.NewWriterSize(df, etl.BufIOSize) - var word = make([]byte, 0, 256) - numBuf := make([]byte, binary.MaxVarintLen64) - var decodeTime time.Duration - g := d.MakeGetter() - start := time.Now() - wc := 0 - for g.HasNext() { - word, _ = g.Next(word[:0]) - decodeTime += time.Since(start) - n := binary.PutUvarint(numBuf, uint64(len(word))) - if _, e := dw.Write(numBuf[:n]); e != nil { - return e - } - if len(word) > 0 { - if _, e := dw.Write(word); e != nil { - return e - } - } - wc++ - select { - default: - case <-logEvery.C: - log.Info("Decompressed", "millions", wc/1_000_000) - } - start = time.Now() - } - log.Info("Average decoding time", "per word", time.Duration(int64(decodeTime)/int64(wc))) - if err = dw.Flush(); err != nil { - return err - } - if err = df.Close(); err != nil { - return err - } - return nil -} - func changeSetStats(chaindata string, block1, block2 uint64) error { db := mdbx.MustOpen(chaindata) defer db.Close() @@ -3587,87 +2075,6 @@ func fixState(chaindata string) error { return tx.Commit() } -func dumpTxs(chaindata string, block uint64, totalBlocks int, name string) error { - db := mdbx.MustOpen(chaindata) - defer db.Close() - chainConfig := tool.ChainConfigFromDB(db) - chainID, _ := uint256.FromBig(chainConfig.ChainID) - - tx, err := db.BeginRo(context.Background()) - if err != nil { - return err - } - defer tx.Rollback() - var txs kv.Cursor - if txs, err = tx.Cursor(kv.EthTx); err != nil { - return err - } - defer txs.Close() - var bodies kv.Cursor - if bodies, err = tx.Cursor(kv.BlockBody); err != nil { - return err - } - defer bodies.Close() - f, err := os.Create(name + ".dat") - if err != nil { - return err - } - defer f.Close() - w := bufio.NewWriterSize(f, etl.BufIOSize) - defer w.Flush() - i := 0 - numBuf := make([]byte, binary.MaxVarintLen64) - blockEncoded := dbutils.EncodeBlockNumber(block) - parseCtx := txpool.NewTxParseContext(*chainID) - parseCtx.WithSender(false) - slot := txpool.TxSlot{} - k, v, e := bodies.Seek(blockEncoded) - for ; k != nil && e == nil; k, v, e = bodies.Next() { - bodyNum := binary.BigEndian.Uint64(k) - if bodyNum >= block+uint64(*blockTotal) { - break - } - var body types.BodyForStorage - if e = rlp.DecodeBytes(v, &body); err != nil { - return e - } - if body.TxAmount > 0 { - binary.BigEndian.PutUint64(numBuf, body.BaseTxId) - tk, tv, te := txs.Seek(numBuf[:8]) - for ; tk != nil && te == nil; tk, tv, te = txs.Next() { - txId := binary.BigEndian.Uint64(tk) - if txId >= body.BaseTxId+uint64(body.TxAmount) { - break - } - if _, err := parseCtx.ParseTransaction(tv, 0, &slot, nil); err != nil { - panic(err) - } - tv = append(append([]byte{}, slot.IdHash[:1]...), tv...) - n := binary.PutUvarint(numBuf, uint64(len(tv))) - if _, e = w.Write(numBuf[:n]); e != nil { - return err - } - if len(tv) > 0 { - if _, e = w.Write(tv); e != nil { - return e - } - } - i++ - if i%1_000_000 == 0 { - log.Info("Wrote into file", "million txs", i/1_000_000, "block num", bodyNum) - } - } - if te != nil && !errors.Is(te, io.EOF) { - return te - } - } - } - if e != nil && !errors.Is(e, io.EOF) { - return e - } - return nil -} - func trimTxs(chaindata string) error { db := mdbx.MustOpen(chaindata) defer db.Close() @@ -4100,18 +2507,8 @@ func main() { err = devTx(*chaindata) case "dumpState": err = dumpState(*chaindata, int(*block), *name) - case "compress": - err = compress1(*chaindata, *name) - case "createIdx": - err = createIdx(*chaindata, *name) - case "recsplitLookup": - err = recsplitLookup(*chaindata, *name) - case "decompress": - err = decompress(*name) case "genstate": err = genstate() - case "dumpTxs": - err = dumpTxs(*chaindata, uint64(*block), int(*blockTotal), *name) } if err != nil { diff --git a/go.mod b/go.mod index 001c474c164..33e1b4fa7f5 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,6 @@ require ( github.com/emicklei/dot v0.16.0 github.com/fatih/color v1.12.0 github.com/fjl/gencodec v0.0.0-20191126094850-e283372f291f - github.com/flanglet/kanzi-go v1.9.0 github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect github.com/goccy/go-json v0.7.4 github.com/gofrs/flock v0.8.1 @@ -36,7 +35,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20220125082654-f370c7f664d2 + github.com/ledgerwatch/erigon-lib v0.0.0-20220127090331-cd0b2e660794 github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 diff --git a/go.sum b/go.sum index 3f20cec1835..c49b78584a4 100644 --- a/go.sum +++ b/go.sum @@ -267,7 +267,6 @@ github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc= github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fjl/gencodec v0.0.0-20191126094850-e283372f291f h1:Y/gg/utVetS+WS6htAKCTDralkm/8hLIIUAtLFdbdQ8= github.com/fjl/gencodec v0.0.0-20191126094850-e283372f291f/go.mod h1:q+7Z5oyy8cvKF3TakcuihvQvBHFTnXjB+7UP1e2Q+1o= -github.com/flanglet/kanzi-go v1.9.0 h1:bhpFJaGIKGio575OO6mWFec658OKKt7DKS9kMRSl6/U= github.com/flanglet/kanzi-go v1.9.0/go.mod h1:/sUSVgDcbjsisuW42GPDgaMqvJ0McZERNICnD7b1nRA= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= @@ -500,8 +499,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20220125082654-f370c7f664d2 h1:grEMJ87dawpzHG+tAHuh7b2HGqUO5SwnL+4NsXJaVsQ= -github.com/ledgerwatch/erigon-lib v0.0.0-20220125082654-f370c7f664d2/go.mod h1:BQNYmN6i8RdHqedsztAj3XDnswYebacmFAnsznlisTc= +github.com/ledgerwatch/erigon-lib v0.0.0-20220127090331-cd0b2e660794 h1:wnlxEKAgMxSvYtqgWluYCYjxl/ePrV+u0MY6RxFFIl4= +github.com/ledgerwatch/erigon-lib v0.0.0-20220127090331-cd0b2e660794/go.mod h1:BQNYmN6i8RdHqedsztAj3XDnswYebacmFAnsznlisTc= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= diff --git a/turbo/shards/state_change_accumulator.go b/turbo/shards/state_change_accumulator.go index dab38689560..9fdf9f0b8dc 100644 --- a/turbo/shards/state_change_accumulator.go +++ b/turbo/shards/state_change_accumulator.go @@ -36,11 +36,11 @@ func (a *Accumulator) Reset(viewID uint64) { a.viewID = viewID } func (a *Accumulator) ChainConfig() *params.ChainConfig { return a.chainConfig } -func (a *Accumulator) SendAndReset(ctx context.Context, c StateChangeConsumer, pendingBaseFee uint64) { +func (a *Accumulator) SendAndReset(ctx context.Context, c StateChangeConsumer, pendingBaseFee uint64, blockGasLimit uint64) { if a == nil || c == nil || len(a.changes) == 0 { return } - sc := &remote.StateChangeBatch{DatabaseViewID: a.viewID, ChangeBatch: a.changes, PendingBlockBaseFee: pendingBaseFee} + sc := &remote.StateChangeBatch{DatabaseViewID: a.viewID, ChangeBatch: a.changes, PendingBlockBaseFee: pendingBaseFee, BlockGasLimit: blockGasLimit} c.SendStateChanges(ctx, sc) a.Reset(0) // reset here for GC, but there will be another Reset with correct viewID } diff --git a/turbo/stages/stageloop.go b/turbo/stages/stageloop.go index 3218a63a8df..a962c2f9a1e 100644 --- a/turbo/stages/stageloop.go +++ b/turbo/stages/stageloop.go @@ -183,7 +183,7 @@ func StageLoopStep( if header.Number.Uint64() == 0 { notifications.Accumulator.StartChange(0, header.Hash(), nil, false) } - notifications.Accumulator.SendAndReset(ctx, notifications.StateChangesConsumer, pendingBaseFee.Uint64()) + notifications.Accumulator.SendAndReset(ctx, notifications.StateChangesConsumer, pendingBaseFee.Uint64(), header.GasLimit) return stagedsync.NotifyNewHeaders(ctx, finishProgressBefore, head, sync.PrevUnwindPoint(), notifications.Events, tx) From d8b0992a01881101818a9bf316850fef1891bb5f Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Thu, 27 Jan 2022 12:19:13 +0000 Subject: [PATCH 139/261] [stable] Update skip_analysis and preverified hashes for mainnet (#3364) * Update skip_analysis and preverified hashes for mainnet * Add ropsten preverified hashes Co-authored-by: Alexey Sharp --- core/skip_analysis.go | 2 +- .../preverified_hashes_mainnet.go | 265 +++++++++++++++++- .../preverified_hashes_ropsten.go | 206 +++++++++++++- 3 files changed, 470 insertions(+), 3 deletions(-) diff --git a/core/skip_analysis.go b/core/skip_analysis.go index 3fe05d8d81a..a4dd8505abf 100644 --- a/core/skip_analysis.go +++ b/core/skip_analysis.go @@ -21,7 +21,7 @@ import ( ) // MainnetNotCheckedFrom is the first block number not yet checked for invalid jumps -const MainnetNotCheckedFrom uint64 = 14036300 +const MainnetNotCheckedFrom uint64 = 14086800 // SkipAnalysis function tells us whether we can skip performing jumpdest analysis // for the historical blocks (on mainnet now but perhaps on the testsnets diff --git a/turbo/stages/headerdownload/preverified_hashes_mainnet.go b/turbo/stages/headerdownload/preverified_hashes_mainnet.go index 9afc2e3e03b..d722b6ac5c0 100644 --- a/turbo/stages/headerdownload/preverified_hashes_mainnet.go +++ b/turbo/stages/headerdownload/preverified_hashes_mainnet.go @@ -73107,6 +73107,269 @@ var mainnetPreverifiedHashes = []string{ "aff83db12544220efbf6214a36a87712c12054c178ad4fa88f9e5e2a648c2d04", "1766202ead4987c16752798f80a55b49f5b48ff7754393388d7dc04366526c2a", "51f2bf9dca17a5b8d27bda10e8e59983324feeb703497cf171c9ad0dc6b13ec6", + "799e1a3ca481512b38965842c6d4748ef561e119f7cee9e707e3c4bcc2afbc2a", + "c8894db326195103913e7e0c36d1d2070dde8d6f8ac578162ccc9c2410634d39", + "d87e18eeb5f4214a3e19799b6613b70eda9a3fa93bef9bdf0ff41da1f786acf1", + "0abd1998deb05b74932f70670451ca5b9b64f63bebd922896506eae836a33154", + "259d1449d1d1eb81c5b247f6ed2bb5a34312051d9d77064f82dde362baca7b26", + "74bf70ec329c229f10aadc42c0e59d8f94d47062070055d66821c036e8746d6a", + "66c2406c5816d2d6ebeb2d6d7321f586a5be947f897fa3d64064fa4d267c4a05", + "d83871ff0152de6be6299744bd2dc3a52be777eb2eccdb3174ed7cde53fc5cbe", + "81603bd0e1fa42ecad48dc87f3fe88c99fef329586a83f2ebb9d612123d1d362", + "763b2aab6430e3f9f402ec387eea705ab3b43c7046237bf45f449a7d3ca03557", + "ba510b4b5454ae5fd5fca03c9d64150a81677284d4f6399458723839dffc3076", + "a03daca96cc889a3f5bfef38aa6a01f74ba8cb8aead03647968fde2bf0231784", + "aa5e8b62046dc236923c3b65a0cbfdfcdef6c4c875dbc2890d244a259019ee16", + "0d80fa67dc47b5ed2ebf03bddea1358c6af44b8852cb18aeed70a728368fa3e1", + "58556f660dec985dfdebf2747e31bd8137229eb8a2c0ff09fa271c07a31d773b", + "56291e6cbe3fec07786107c8a1ef86a1edd6ea785f17e16dc042930f0bbce96d", + "3dc9fd5caef037e6f946b22aef6a1785e7ab546d91ecd45f80cc1f73130546ca", + "9453529ee04e4f45f2be31901dc4531f63c6f7b5af7e3349dcfe3f3c7b9fb942", + "d15b75ef1290a7800b2fa300524831423e2ef485d2e93fdb5cc53a091d32d3fa", + "cfb03147c575a72206c4697e8c8199f65caa06a95ba76c5ed39d39af02b81a1c", + "9b86ce41bcbea954dedd3eacc2a73b223325e4f4a5093283a2aa97b0b8b42ddd", + "2e44cc7169ea567b0d96f6f6e934c72baffa255ae1693090edf1343e71035ff5", + "8d547409e0638d7a7b8f3d32b48cd9e8b1dbe946d0ffea10c59a2fb3f25558f5", + "0f44abfa2787507a68aea53ed9d801df9966fdd37775ec191cf1827ed6e4984e", + "0645da8bd7d415179d82f01628af2749866c5792466d86b0f35ce90e94a8b0e2", + "4e8f3a1931dead13ea6d01fcd5317ce467e2a637b581244e5a71dc9867fdf57e", + "4f4e237d2d7b25e90720da72ae29e162eb04c604dc48c8de3ccee93fd29743b8", + "addc4310bf51ee65da201b2e3c0e722f3a3501348c9e05b8dd21efae205664c8", + "fa68899842fd3ff24513ed81b979e81e172f6f21d739cd817d56958e122eb6d1", + "84d0540935f47c19b5ae94e914c4a3201e796d1f63b1261a100b10bef80d301a", + "990e2ea372e216f028b2ad0ff045c03a1575e5852bf942601e35aa23a2dd9313", + "fa1a0b03b8291c6f5411167cf5ccebf2b42f71c7181964d98ec43872c75ef5c7", + "67bba3136ad68e0196184badc025b5bc61fd454e25e87252098a2073cad853f9", + "b5823d40385a996607ecbf182316dfa0d00ed987a173a0c497936c6f9687a776", + "a98c89f17fb79c6cd7fc29f4f1fa5e0c4502f5ed363d9dd02c79ff853cfb256b", + "f94e1503923b74be85ba3eb5a21e853b939cdae6176ea23ff06f640bf8470f18", + "8aaff435e3b7738eb65f944ddfecf893ef2b1c922940ebb4dd9f1f75be57b655", + "dbb97c29e95f71bd509fd4418c06d322decd743168f5c2620b21fa3309312b50", + "3cd9cf06e9b413f18f3c6624172e627fde6c6ee51d62d55c9d4812b032667eaa", + "78206a16253e63f72ba29e984d512d0bb1e43b246627cf55726b1095a6c8be65", + "9c120eb0dc8a9686213d46b60c94fa0bdfe833c9ce60b6f3a152e59de0062d6a", + "4eaecaa8a3e579966675721b571b7103594c4dc98e0a08c6881b97af4f864637", + "332757562ff67770d2aae422cd24d553fee3927169bb0598bf64cbbe4360a3fd", + "7375a11144c89f9f217da040e4f51b4c8a11b3aeb842e7f2cd607df7e8a95128", + "12ecaaa7ce62da02e367e6833d6064040a3299922facb72d298fc0df730f3b80", + "25e98c3afa5bcbd7bfadc13f4b181e18cd07c4e8eec14d979244cd83d30ca6eb", + "a6ee50b2413071974be43d43355740c7524350eff7ef1b0a342efe2a882230b7", + "3c4d9b14514da56757149daf5f8985748f31bfe61ae9d2c956c019ef9323fc79", + "e89559124f4a8689f46ecbae1c1127830b6ccb0f9d70ea398301bc09b7b7c294", + "8e33e36b3b7bb7021a548aeccb496edf1917d010c3a49542dbabf3c3b26d99d7", + "ceace6a6d0163a2e3d922d9b5719c2930639191dea4edf460a335474025f6fc3", + "6ba13bae43199a150278f852df7a317b41760026662b249baf3ee8918bbf7e3d", + "a8d477126b940b4982fb213401a302c8c6d1917409a974e096b049c7aea8816c", + "e3f2d06750783cadf1cdd7c566407a6f03da0fcd2fbaa643abeb6eb9c44e0884", + "59505dd9a22dd13f26dfc9fa91bc3ca9db3cd3f13850feaca34fea996a2b425a", + "315a3719989d6cfb6d7c0504ddf7dbb1fff01dd16732dc2bd7369b42711c7b87", + "ee0672f91b0c914792d5485700df779da8b0eba3a71552bd5584097718fbfc30", + "3018c479c1e0ceb71c08fe1ea306827e0af04b18fb0b9cdfd9fdda7fb745bdac", + "91102469150523bb22e6f74032bed62a4178ba239f5f1f1b8e8cda8e3602f424", + "8e55213a8dd3583d79fbee8328f298618bafe012e31159cba54b59cc1faf120c", + "978b79d4a1987d854cd8cc0d2dfc15b3d84512f380fbe618ffce95efb7dd8fd2", + "7020cd2d27d1652138efea108adb3ff52a0dc5859b490317dc9f9b7526060f16", + "b3faebebd3d8dd4b1c9a8b0b7961a2784cedc05b09bb7cfcda27463f28b50166", + "baf4edd08540f0df0a8db00ae5a5eb212253d8fef3ac541a6c961546e36a1d76", + "4d9ee1d1435ba7c4adbbd38f2bac1ba2a4fbf12afbf341da3a88e6fbb0e901e4", + "a7429307213dc1ba2f156eabd4ab762f69a330fe4df916a9466a4491f14c9cd6", + "50b1885a2e5c045ea27ae615622b7acc275fee87ceadd1e9728d12d4004eb5da", + "305abc6d2dd35a51f9fc052b955eecaa5a96beed6dbd15635b6027b3f1ee429a", + "1ccfc4f2bb21485e463ca3a624ada1476a63b215863e93b942d6e08bb73a63b6", + "e95f417fc61bc61358125405fbad811115434da8739d9be9ceace7e4ffc3fdf5", + "630adc6f74641fd5e68866de680d67b94ff4d32133cd9519f0ee38f56e8477e4", + "34386fad46978f8a2ba2278e946545ffebf44e3695a95d017007e4db6f189e00", + "c70df1a9abea0d6421d77efa180796b6aeefa065f7635e54edea20eff1dffc54", + "3ebec017dd0e01131ffe9a1fd816eddba760e0db05913ca9fe2a2bebbb903c76", + "34bcde728c51301cb0289d81a4318a338dddb1a638f750fde30411bff48fb75b", + "8bdbf5daf090010ac98a279326414c44685446922997040a9fb940aebf14faa0", + "b6bdfa6973e3aaf5c8ceb11be9fb134071302beba18ec4304eadd8f8a8504a8a", + "45e5989bb7528ae1ce5f2c1893f0d3af2d054a5b7535fe1cee49897e27ba5172", + "3f00626d7e5f5aa82ef28e42eff76358830e53b9766296e5034f1f3aa387c78d", + "7fa18035f66b2bc595df0664d855c2bada4963c8fb2cbc36c93d481ddfe3d393", + "478e94c899af430f612fd183b000fc825f829d3117f2601163e4d7a49adffc8b", + "db97f9cc7b9bb534fb89ff79aa5d89d91d059b0c62238952af9b145fcfb48a9d", + "58025dec97f842988514610b09d3c19dee697f3cf44a6a1e5fcedbca5834bba0", + "d9cf9b0c1471733c0ae00894b554db8f6f934b350dfe771bd1e13908dd1eced3", + "186c96ace6106907931f65d559351a99159ecdf33f5959025f44156d30df98d9", + "e73bbf08cc0cb8b5f51ac77a99c4a66dbb933345e47108751a26c6bf136cc0e7", + "e7b44abdb0258d5280e2a28c81831389d897374b4644c2683e937299d7bfa855", + "98402c7f5b82d9b65c6289f4d446a2a411a1ce3ae5488c67ab6ced8f35786782", + "e9436de8838955f15cc1f64da078b83b391afcbdbf7939256531614d7949e6b2", + "0e8a1856a79a25fe151417b5673674b3274a310fe6656f69643bec6c7d45155f", + "1a9053481b8c61524faaf57a93900a6d09cd8e4e6922f431e52b3de99ad430f5", + "d5e60724156697f7d79847d24adcb6f1084a947ade6d138b852fed8e2c7640f7", + "3bb277479d15a5aeb22984a3b2c2f61826acec8b2ee28c0f491fb4327ed46127", + "0024f59cd845a7c808cdde4abeed146697b7a0ae1ea9fd472750e87091e75cb6", + "adfe70ae33cbb9643b8f3547f63e968b7015e3c9b0d2cd2ffebb7793c403b1d2", + "f758febfb47f718570a7e0006d604bbc7add5b1a83d3ed2bd25b3f8ac7cf3548", + "eb58fb65e1cc8de33d2ad9bae7fc391d4ee481317162b8ab2ac3da4e409ccb26", + "cb61b14443c4b474a970a70c02030752d53ebfd41cc29a4e990221506623c1b1", + "9e321dc1a47bb56bf76ba00d9147e44c2a3f9d21cc6055a4aa9090c7659c912c", + "e84d25ae2ac89cda224651802bc917221df76d5c7ff61a471f5ba4e026da12db", + "e1188a8746f37010bedc818fdf9bb196abfcab7a3ed8274b9bcdf77a831ba1dd", + "aa1158b8be71058fc7f10f80481825c89302ad87c279e285bd88ee2d801c5da5", + "71c7ca9a0ac2458aa642474135de5fe7bab0a5e641c02be2332fd4dbc55144e1", + "daafcdff7ec08da50636fe863b2d0c42c4e4af3d2bc943a45f252a462de3d888", + "db6bc3cd4a6600608342d4235d81b2768bc887c446fb310a29cd18dc3d98da88", + "1d5d6e1ad288403d508b9555e4a451790704dff7b6785defbb0f7107e9fbe84a", + "38899b899337ffeb4944fc214e4cd837f5a7c7da75f18ca4e7e9a40f84806d16", + "f32fb5b8f03d824c230274b8411cc435e3465d962aa64b57509818af40791361", + "5c2847e64d85a6620e86ecd2b8bd4869dd6518a4233bdab9fdb4dfca76af0843", + "5944109c570ddec853fdc1f4a43577f874dd222a13388abf221701d29daaa50f", + "cf7c60f80283d55d64cb4f570eda012f88c11ae184721d30bc1f191064ee8db7", + "0ca7972a6e0a2cbd16506aeeaf9a7400f284e87330b9d10f53e46e43fbee5b08", + "d48a88a5395cc9f76b43936c1741a1d9d0fa00b09b9d128e6e157cf01fbba697", + "5189e07d14171843f19f3d6d4caf0377c27562dd298e17ae3fa32215cc2d568e", + "a3672120a41e29394d38e9d82d97b2297147e4363457fde81f4a8cf9704d4352", + "1ba40fdde66f5a64792408025e318c4886a25ac772ffea4e1b6517f7fcdb41b5", + "59bd1a14c2bc02742ff67b1684a21347ab371e7a837107e5d69a51a3f4aa3c31", + "2c2e671c50ab9a234beff2128fd454c19f20f79ee611f1510941a41c2679890a", + "923844238655476fb618aeb3b401921a60a8029160ef26f78d813991d4596e6e", + "464df114e5485a180403daf8af8fd30fde05214d9668c7b17fc8a8665ec50758", + "81fa1f8aa45144750915ad343785c6225018891b389f77d4704f186f11dc0694", + "5d8370f507c27ea65a431c1131694717877555a4777896ca43666ce46d35a77d", + "9494b93a4f20598034b2bfae8833c88271662c27999f910c8630d73f96ade6c9", + "c19308dc1e6383e23dbedca173872fc51f94fc4a17698b29e0566da57c154e75", + "e3f9ab592f50bf7d0093e04580871de76dd73cb20ec307097f6446834e4ab400", + "6d25a9b344125c9b53d5b42c5bcd0d86080edb47f99df4b1ba5bb6262808b565", + "8e79551171883f276df9425ba1bb4c3fc652ca0c0b36a773a3ca90fe07782e59", + "1d91b72b8db38909130f6b2fe4a31c725952c3f79276ff62b3a67263df7db4f2", + "420a8b871291d747031439492399121ca45868b9e429b77bd4cefa0d9f123c11", + "757f8302e23caef475c43a38c6c27a4ee2a1d0f1d3957b51d2bc782bc407c88b", + "f8b1eb9c4dbc65c65f6409085bed36a6f044856993899a071de022f8c1316c64", + "2194c4acb2def6897707de96af872fd308303f9d29dcea32d1a13920e22294b1", + "2886a30484bccaf7f93ff411e3dbfd5d5174820dfa2cbd0469b7925c68e1bd6b", + "f4685a81a56a784d49a691602b37536bba023a37930fb3f0ca2524e862d5690f", + "55267bfbb225c7ce49c0f0a13633cfba4d29e5594e62bec164c47d9bd4d48614", + "bb252519883f461bb5330dc928bc745e94b8b4c6dcf5de015c8a87289ba3912b", + "991ea787a47f16132f93d74cc17b0f750b11f6e141dfde7350430a1324d6f3a4", + "a6ed9b31542ae0b2c764f7a57361de483a376e66258024c3bcf50aef134e4fab", + "032ce676f852f1e3325a2397951b2d6954f64d5d2efca29f1daac29ea00d34c3", + "96872431b6773dee15207159464f6a5237f99c606a98f0edc559984b9050b163", + "a530b7d093f42d4be73342adcd56361dba4e1a40fcdd565f404cdae25496f371", + "657f5b5435bac289078b3cd00a199dbe54d6cc772460005099034f4441e10e30", + "9643c3c1a811810ecd3b32283f7c3fa150ff8714fd5f7ddc23cfe4fb56e1d50d", + "68b65b1417f14146afc15a04cc8414a505a0f4516f25b0f3893847ecd280e111", + "d0a50191e9e141578201f4c209e3fbbe6cc245cc1ad3edb85e7348ea545a8377", + "36d73b53ec99b83d339801856d12e8f8935a9861b6bf561f39b3377b8a92aeb1", + "8126c5ac6da3f6e08bed787dece7b37493c1233292c916af0b38411af27e737b", + "35e1afbc5df0999e21a42c2d84bc18d6dec2eb9ba3a8171b4b51181ce691a15a", + "801a0f4ab7ec1f4722ab9e6ed40b7e585f08abf16a578c8309c431b572c1d7f2", + "01b81fbd9129931e9e8db969bc80119b72af2f5f15ef23f119f242b813ffc25a", + "6db45ffb7160651383366c1f8a415d3ca94763d027ac6f6ec606aa7028af8826", + "3b89f071e0f7f13cb3ed31bf00a3f2e5580b0288c741633e81e5598cf5dd2290", + "6d69c05d74afdae92552487ee616a949edaeae659054930f36da40c4953a2120", + "4c441f325aaacb1d7859194995f4e45a3a18b9aea03ee40411ca48a5fd4e0f03", + "2204380be8ac0a3d367f5e81a82cc161d8a247dbe171707e49997b063af9dbac", + "df7374114037ee600342faf5df12f6f3807d2e7781c7ce50952603a98f7e99ce", + "05e70d9e776308b2fee9ae2be315146281c62708c6ea409080bead5442076751", + "84c1b478186cd46d0c1b21751eed016a65df7d70b6f0144a2a19cf2d21fd5756", + "7f8812c5673f8b52d232f36f9945f79c7a85c022d787e55999dc9d558505de15", + "641673db02b9cc5a922d90454d525e2a390f231d2a94ebe6aed326038e02135e", + "3a55ba3dd9f2896d9f877c97e5d8f5ddeefcba62e8b06c97923d3b8995f39ad6", + "0ec7d7010b652e4cb4a143d08f1e9dca8c6c9dd7e4b2702f66a2b4a236829d97", + "6ee7e7d04124f3f2de0d010439481af6ca365ce265c537d6cd3de61868f85707", + "f7ff0e447fc7db840d0ae36e48e31d3c0ed258bbc1306a284bf193a8b5ac9276", + "ed55ba76b04e4f8989ebcb1c62be79b47fb2968d9389b2887fc74365915e68f6", + "130be00f3855b39c35558ca9d9b682058c80f1e872f89d283878eedbfe65db2c", + "38c4431f4a6e9ab00aa3c631a110870bf8bc1baf264e73f526de918f826cf016", + "603207e4ecc48493d43339c66408133b2c39836e4eb86f88c2daddd865c03697", + "26f6d4d265991cd4c9daa326ee3db38d2c1baf9795c09079188a7059cdd6767d", + "59a8f8dd50fb9abda06512e7e403b0a155778b560082324bd25771a6829d6cbf", + "9b4d2a373f7456dc0df6957043e367e7ffa612b941c291cb74519bd1c55e7c6f", + "121148c242e1c731389fea743c53281226885bd18ca8dc67e0755160ce9a61bf", + "7d066b50ec714eb2a8f82d4ed22e256a6ce5c3284c2424edd7f20612cd5c8f50", + "234ef5784d692edee2685830e99c7085f0a4b7611002ed39ea965c95aab34ea5", + "0b3f2f66266493142771d06f4f3bb8c08680a079d0ae59ee8811b478148e7675", + "924f57a2d764f3b7217dd8f5931ccaff6f7aeae8aedcf8cb951e6c63ee2743d0", + "65495328d170c4b3a2e0380cd18eb838324914a6e5401c032eb0b8d873d526b4", + "f90ffd4b6dc1e729defe1c67841b024b1c2893260865734b8cacb4bf9acea3b2", + "2725488ae0b1b6ec3117f7a9a88e4ccec956f478e76ad4262b0c803ed62b7841", + "6ce663e13274fdb5a3796974dcebaa0d58a9debc24ee7a9433c3c80c827af70b", + "b33dccad0750b8f690f38f9f5aeb1ad026059464e92e4d5a7ebb2b2b124bc1eb", + "c98cb2b04b5fbaccb0d064c3c6c321a83fb27226c61423a0a07948bbe2477081", + "75befb1181fb0f1d7a5c6aefce31394ca832a9dcf8ca51a7ade2bbedb83b94ef", + "d7fb7c605d5660117339e0d04f596623067a59728a0f8324eda06508bc47d1ed", + "35d44552ef1267488c0eb594c44a9193712d9e00ddbd0961d8623ffa340631e7", + "60f67d12454fd110cae2100141b946bd920362fca54a2ef50f4c49215331a12a", + "c11eb21b35c45a13228e616eea8868cca536431b7be7a12eef80465551bce5e5", + "5cc8befd0b62c8bf15bb98ca5a3de61c781ef4236c525999fe3f2942e5223104", + "966a69a35657509fac8a6c4e82802f0bf0332e36bf6d2593b687801e2bda16cc", + "82b783485022e531117387d318d6a5e19bf474c7244076a4c68b04ce369438b3", + "b8e0b5a88a34bfb04529b988e36d5aba94577fd81d17c6a849d4d7f13e1078ea", + "11d27e1f44908a2f8207ed60bd227287163e683eacba11845f80c40cfd218b46", + "28124390f20b200742605fa2ef360d87cc0bf14cb28bdbc3c387f604f4481a5c", + "1971be74a2c2155e7355bb436b493008694bc02b6ae58e9954c546d5faa0f0e7", + "37de4233eaad14525f3c5e5405b52cc5970da22a6a848519dd2b1f4f555b82f6", + "7cc348be902c110503b73aadbe323055b69133c6de555c561e8584c00c68faff", + "a4bf4265eb07befa59bb8b1ecc1ace11d5d8a32da8b93484dd685e3fc1b1122e", + "a131bc7230e61f3c3d5980e3f7534db105b5dc89a6d53fccc242de747e78f2f3", + "a9ac8f06da748754644b7d44ab89fc89da9cefb08eac57de192e7befee2d400c", + "3c2ab88e0c6f9c0526b5ebff803ffbf5818ed3bfb524f7032799671858a5e205", + "f9de7314523cf87c6bab3b51faf7dc32763d2832c4e5c29a791488b5324d6266", + "0aa9968a1660b119801415de0695984adaf5353eaa2992bf90bbc07413982d7a", + "ce93249cdb057057dcd47e68db456e208f1fccd8210e6aee93ba9796a743cd62", + "0b7e6affd2845dab534280ed60166f3f1b6e2d80c0f03ad102a4639e82e19991", + "99d4e66e9a63eb704c5333f1223d676c7228bf5ca3c183c62b25bd292badb4e5", + "3eee33fbd384a5d2e0f0af5bff6c472556032452bf2702e8613058922ab70428", + "347f8c63be159da9eb1e7462a6383ddd6b5d97f6cf0204de2ed3bec1e464124f", + "1566758d2405f83fe7883d743ed1ab417bbc3e86a1519502a0f1facabf0cf12c", + "33723c73346f29012942fb096836bb2a0032fe24b4362203f0cadb038fc64b21", + "c96aa9dbc90ff59f1d1acb18f19bb094d5c677ce053f6e388425d89cfb8ff06d", + "045bb32980dd7dba651f0d5d8f6d835b8a8e6cc3b4af003eaa671f825212e5b3", + "00b7aca793bd21f3b81bd7095e284706690b0ba4b35283f31fea1908eb45d050", + "c763e210899a31787c2410d1bf458af4820e916a431a9147ef28996a398822e8", + "78ecf8f251fafed9250202bcfa8c9064d42cf014e64952e7db0c6d15d324f896", + "9d5b490116544567b4ae485ba2d05d98b186aaa6a1efad9c54c595dd071bd8c2", + "1ffe8adc9e51372c38d15bbd273b4b07a6bc465f0ec4537a14873e19790cd698", + "82312cb93a947557fe90e88e96e296cb55a4bd9d8f4890e2cc7b9a413f72b49c", + "0ecfa2242560676bdff314a34d3497524fa3b63b86fb4241f512847f4e1dded1", + "ec7e61e5d3ca007eebe3b09f3445ce9c1ddcb8c40c8fa9222529134d50455910", + "4d53a47ecd21c66aa4affe9da9ad1df7671354f0e6e9dbae8a1f44c15f2f71f9", + "5adef51a80051f149d4e972116c974d297d58b56976dcfcc6714aadf238b24f4", + "915e8991854f6cf27e9f4ee9953c45744b12cb13b91e208d5ddecbb20dda8f6c", + "c0b29e9d38a302c433b38a3579b4b5c88ea20cbbe6b9c979d3a434488583d1b2", + "923b4e58c0ea628b2c12abfa82703debdc8d4b7ba78929a40b81b21cedaebeec", + "8c4c203ce976f3deb88287d7b6e8db02b57b7208c271f0a3457969f3770b25dc", + "a24a538722775f9f003d78760619bed45b1d89351f233454b3d6690dc677df04", + "c42e897bac00900f90df5af19586e60b85898d9ab07fe18e52391c7abd0854be", + "a6caeb2ec8efb9911ae9d58068f2f2706bd6b26743da360cebfc957116ed694a", + "44263440512b9b4be266de42bba2048f25126785b79452eb1325a68fe9d88239", + "070aee53bdec031838ff1e91e967ba1f623853e72a04de73e798a06ee5fb077b", + "307b7050ab2b3efc29e618d7037e9f929e9de59a301273a5c2955b5428b2c613", + "77e9b92a3e3d4085d85090271ad08039b963e500fa5a80dd3111849c87fb8142", + "00e9a70e277b42f6d2b308e15cfa0fa44ab42ff4ddfcd1e2dd71e13b4c18151b", + "e26761f2030c8d8043098a8ae06b14c4ee1c9606c4b44c4d7bf8c7af1bd18d9c", + "58913a8c58753b863f4d082114b426b32404501d62f145d1e706cafd166e7617", + "44efedf82365246d64de3a24c1254d3bf5400a7fb09fcc6f62a22eb018df66e5", + "5089e5e1733cd0602db1bed657da83e5e196f70f56f3ef491b338836b01c5aba", + "1d68b43bf70c4b252a4ddabbcc5f10128bb7666ba6695e6b9a885741636bbf6b", + "1286781a36feeadf90e5ed53be92da07608770842cb1840997abde2981165dd6", + "32001aff20eef9406be6bd5736d936e19fa49618ae4ceed554703a5fd1d46aa0", + "e3535eb8e8e10e4938c2d1e0416e836a025fae616ac589978a66176a32b73ea5", + "4b4e01baa0c31f1e0ba58cc443b71c144d74504f06ece159168098b9151f9655", + "4197f6899c2903894b975a883425fd08c9cde88b78fcd2013117f641e799f0d3", + "94e28f63f2dacc2b4e9c187026d28581c78c8eeb4596e61fe80155fe06e72fe1", + "0a8da524764fd2f23999d5768aad6ce29b5b033435bccd0fdd618ce5c310a071", + "5936de5e660dbddfb7088da5c28d7ad3b09beb11013b8d1f2d0d7c2ccaeb5b2d", + "b3103e74b8b17b53acc166475c433d1db7a36df171ca35c42a6a9dd5106994d9", + "5ffc1c090085688f6450a9a015b7210aab7cf1db3e81323b850d10ae8e9964bc", + "3a8928e6a558f580733e2b622620c60ad6c43dfe8cd882bcd71bb629c6c052ae", + "e5005e694c566331d6d070bffdaf93ae510d94dfee68f7a4333eb99972845fbd", + "50789e073ccb6213e64ca1a73a588a8da34588026ed24bb3b407d498411da028", + "3ccc05153a9557e2f9bf3ff7bd93df3849c2e60e8be59e3984197ccd4dc859f4", + "058fa70bfe6e94ede6b20c20d354211f77ee33d80c3fa48c656e1e1881f0332b", + "e359733f6da8578c59421e537a3b98a6ffc3fa107678f2addecade75707dae5e", + "486630abee70aeb0de424f82513e873c3efdad85382dc64c66e5a73d1b41c068", + "3fc74251a9e457a7c31303371b3fc5bc509aaa35988f1187d0c4aea2d03eae8c", + "b1d368571ca0137dd15faf999d13ebffa4715fe0b25fda5f00b7f09819279e0a", + "66c646d6846870d4d9212028820699f39b66e379790a72d203570722e67ce2e1", + "f6fe4ad6202b82035801eddd1644b23e46379d9b5ec69af8aed13abc06bfad27", + "f25d31f9b00cd17185b36e54eeb6da8635986aa2c139c480524ba7920d891ffd", + "65065cad644bacf668a832f68642e7f00bfce89c98fac48b47a21db379d45f03", + "bb55bfd8cd00243c837dc06d937f2d4f83d498135507a02d7885de5c754e4655", + "3ad9912f842aaea3fe9bcdb8bfb42c7e1f189510eaa68fd3358d0daa0f97382e", } -const mainnetPreverifiedHeight uint64 = 14036160 +const mainnetPreverifiedHeight uint64 = 14086656 diff --git a/turbo/stages/headerdownload/preverified_hashes_ropsten.go b/turbo/stages/headerdownload/preverified_hashes_ropsten.go index bf87fdad6c0..6e00a80d5ad 100644 --- a/turbo/stages/headerdownload/preverified_hashes_ropsten.go +++ b/turbo/stages/headerdownload/preverified_hashes_ropsten.go @@ -61677,6 +61677,210 @@ var ropstenPreverifiedHashes = []string{ "329f938f5c9284c781c593393c8aaf41dcb0d4cf321aca6fdac6acc03890fe07", "cbbc630e0f207a5ca288928df887adf265b4a890180dceb3a9acc3a98fe61281", "789f8e43527204b92b20abb81c266dc89299f760393bffb52ab41930d10d5e80", + "cb2de31544cb98b915666c69a47d84da21a73a0993d20ad6e98ee31260032ab4", + "1db81818be2de18ea202d990ee76d7920a086590a16d6e56ce839e34a634abe7", + "9a2a5c121408f5b8e9e6699c77398016f65769832b67f51a9564e2fe3980eedb", + "59a089d196dce8254b98e15de57efb42489a4690ceacb77713b18c80ce5a4d6a", + "40fdd8bf236e6c853480f49ea65ac7b9e45c8519f0e2acb8e11f7661326e093f", + "7d539ccdf66e4fbe23a178aa7b0b71528161c8118da51a86a3a43cf67f829f68", + "dbb223fd973246e7c8ef6432721f4fc0c8671149cd9ae70b6aeaef41c3e5f652", + "27c9a8ba994a529c4e77f9a33cf7d3a4ddf11018f4308c4fc1a3db6a6ca92f72", + "ae864fb2036d3f39176ecaddc19913df1271a10bb220c7089652a5a1fe0543ec", + "54cc5b477946341dff611c50762896ebee3b9f7fe4887f26bb07b99a4fd937f5", + "b5efe1a68b671935a51bacb3aae09d6e9bb7c7e9d0834f706482aa9df3447173", + "a13c244debf02a50e58b81249f5349c8c2ccdab7af53bc4e2fc0d7d747235c81", + "1308a92fec524d142280b41771279aedf57d4db5f8ae50794994c944406473ea", + "797a6b69a06754a8602aa5508ab96838c3d8924008a11d2ac5f67cb70a370394", + "606663711276d96d92744164dbf3b27240091e176822446666aecbff804f1b75", + "9a1bdc364ffb37278efc15b59b80766b4333d2aaf9249fb20c0f19dfcbc6558b", + "d52f0d38dad4d25bc905f797de27e09e42506b5f8e04f0571c622074e2b093a1", + "f4fc5ef71eb6a688852610a1d36a8442224a35f7a10a1bd6702adb5f0db02277", + "f54165ac2419d8805fae1bc5dfb35e64e9d31372abfd60a374f3261a6eaf4a9e", + "46dacd0f81b63ae66785d5ff241aa884276914a76faa860eaae6a256689575b5", + "2b24c86762859cbed20ea8f59ebd4c9051d58fe8fcebc00ed2a445f33ec50d76", + "7488fe4211057ccf84d5576e6de587b1c350d1a373c6b8bb37dcc6e9fb7c3d1b", + "a8dc70962088851f53322c726b8c86ffcac6b4a60f0cafc0fc7aa20f90247b58", + "05d850664e90ad38da13fe2c314dc611f9888db627b8fe8eb2bd3c018f4d9433", + "e6fff10b8e3b9130ef3b8be6f06a43c8534d594a26d99580a51b030d9d942c91", + "62a34e4dcee8ab911aa36db1ccfa4e833cbc6b6dd1807e448866e7a9e6913b42", + "4c5a53333741f4765aace95434e3ccc6838a233ba0d1cf92611a520c0edf63c8", + "97c83daf67e116ca1a497ae6c787025dffb6e4aaf957a9f852748575e13c9f0d", + "74997c5cb6797437ac1cd16be046c5c4166376909ced669c9a1a5c1047837873", + "2732ba7909763eb185d8b9a5a9e4093aed6e3237842b4ef6c1ef5caa1e03830b", + "ecfd2652cb2f7c41b434fc8fdf3630a0080e850d98f20765d9d44bfe38b429b8", + "88e54cb03061b57b3eccc60ae60bbf27c0663dcb178b6746e75e78ae85bc7c43", + "afd2676c8ed36386292946d9edb68f51728cf3c97c7ef3d0f6aca0a765b2ce4b", + "d2592c605a3bda4b7c01c288b24dbf06391489ab837ef8624a060426e37961ab", + "516c0100f1928ae56dd801ef062953d7db9f4c5bbff7e0e25a1ae44a16f6be68", + "52375b07c5852dfc3189e4b571f713855784e3606af21f12c6128ee579a6b7e4", + "cab5d71bec743ef37e9c8564d010467da02481d0ea9aff6f7a0caf1e5a5930cc", + "5d24c46ca761cbc4a3f0b0510fc92a4a4750e264cbf7c7f1923181d43f9fdbe5", + "4a1a6d63c11fb5a5cf05a7b800632606dc227ff33f5c8aadd1750bc0f29f30a0", + "dcc6a709e89b6dfca1d697fccfb74d1d7e1aff6a9a69a3852cee437b2fd73512", + "9b8f5da4c6539740bfa4432747ab97c0bf8b889a8872df4fcf9c88413882328b", + "b248415cfaa898d0d302268b386415d772d9d00b898e7795352ab32fa4e18fd4", + "5c03501b12b570b54a60dee4881aa43086c6c3c64861c8e735fd6199374099d2", + "8bbb6ef66bf64b9f36bda6682cbcd29df6c367adf3b67e2f136b374ce029a76f", + "32b8e2384cfdfc959376236ac84fa309ca780da579bc90b622e1aac3a54c8f4b", + "1e73191a4dca7349f9baac9bba440b37245c1a90ba674833f35d6d9f04ea413c", + "e526fe5e771e561786f47e2e8093cbbd6037f02ae4a1d5d8e25b603b106aabb7", + "69d5340ae788bf05341ac14c876ad60433c5ad10c70f4e0d55f43d0bf235421a", + "858153476aa3ff4448a5f38544ff02e0d64907c6576c16bc09b1b16d96313d3d", + "beec677991b9a8c4027c05195eeec26231c86b3af7193e869791b725741a2d09", + "8b1dbec5d084e81b8d47843b3de228cda588a052226e11c20ef6eeb5df81981d", + "bbcf92b36ca1bf6c9dcb8ff00787449ec26fd649dd880a2167f647aa037afad5", + "06ffbcfaeb96640fbdcea9ce3903cc63b56e0b4c44aed24b2b4f221dbc950d13", + "c8d2f2e5270a09bdfe0e50d4174bfda56de6a3bd5119d5171acd029d1dcab251", + "d0c30386439fd7d271224ca72d942dafcffbbf83951c4dbb39a553513c35266b", + "7dc235a60debc11631493640215ecbf60f275df2444c31335982bf68f598733e", + "3238399810670a6623b13b0e8322fab8d752af07836bc2afa4e1f460e11a0249", + "5302d5fab7180b51b0ec6bbb6dae872aafbcc6b4618159ffafbe770d207a2961", + "ca67cb348ffd0337bc0d6fbedaccc55dfd9ae77108dcc8e0b597a4e580b5f072", + "d72c9d368a6d08f451decc196a4af16cb9c639a8b5ff38fa919afa027e6c9940", + "75bcef139277302abcdeb9a8dfdae73f3bfb6ac8bec6ee5fd4f3e6bffc9817a0", + "8ef15b46cb6b4be3a7015ae543599ed64958a23a26fb18cc96dd263cbeba8e1e", + "00c070f09f2148233ea4fa82a7e6026b61ee601509c24c9f36905d394a3a551b", + "82739a6a3abe3d911b00bde19eea00cfe70954ccb6c548c57ec534f25294752d", + "a9fbfb4d088b8aad169495bb0a15b844cf3074c435920daf68321ab4b87ef29b", + "95b0bcf97a7f52aa4a5c1ebf3691578b7c32d453ed0ebfb29cb4ac3913c84c53", + "e795f538606b09eac96444c5f4d862258a7528508d749b931ba295879ae9e8f8", + "b3fe111e94e7173743e6889b7f22be513b65884194905e23b4e08fc31c9877ca", + "7e2dbd0d78c33301dd5c74bc7b9051a83a1d5a40707af9681d0cd2e623e35a11", + "1827c9b7bb88bf298b10a98b55c016d21b50a961b61224bfc2a3c68d7ae2a0f3", + "cf8622cfd0f3487e1468540b34d798cf272d5e7b30b9f91223b2c313748d7673", + "9fbc551112b301a62eb547a42e67e6016977024134cfe3d3ae86d4e0277b871d", + "99f5ce2cb5477937e5d7b66e4ee9e89dda4021b858263c2bb888858f59133d49", + "ad8d8b597136c71cf0efa76eb127e27b386da9bf799da362f4dccb1f542783fc", + "3fd7e568259049cedcc18530889f2d3037f9eeacf53b70550ebec119c33a1c2f", + "22d280c19bff12c5159523e7ed16c7a02cf6e7eb5945fa3b921f56958aadfc5d", + "001209093c93a9ccfbe3e71a0b6fc4d1af4216b91a37720840237cfcbd6ba35f", + "50d3abdb0e889b20be05ab4d627935caaa009fca6af635d8f3ecd194fb72a8db", + "5257746cf905ae56e20ce966f4c4ab3998825afe15bdb4d530e32b57210e69f5", + "5311d3a9843909fffe1dfe107a1598965d9daee745d2e82286cc1893c3afe863", + "31cbdac3dac64868e3ab8e02d899a10b11f76e42ba54b987ca3877ebfa7812ea", + "152a0ff32a13a9a727c978868af3695a6e6c0ff5ab06dd2dfdd8c54cad09b95a", + "7bf59b68ad63b5f462b8f287cf9fe5d5f6afffe4c6e78c963f97dae2de3af3a8", + "4ea760cbfb9e2497d61e03b22a29f320a20e61bfa3024b246dab58fb5b32850f", + "2d3072be6a54490fea47378552acff115163c7e375e6c68900543e8ac512f5b7", + "a99f22ba0eb811672f13d71d739529359f6cd973bc851363eef3a386d8b7d31d", + "faba5bd9258f7ad4baa306ba7a7fad6d5812077849b857c5b776e231fe1e10a8", + "80c7722eb8e3c56b6646e1143bbec93ad2f19f5bee1afd1d534f1252edb6da00", + "bcd588c1db3950cf4d5c5e48c73a372f02e1126added0862b7cff7a86d123c67", + "23df30ef73d0afaaec009a49b90314269b3f43b4e80254aef91eb21837d5fe3c", + "cd1095daa6d66fbb61a815ed107fb187d4f58e418898fee5a19c5873e8ea907a", + "c6b1e5415b76d19744afacc7157a4aa6768c7f78c3f789bcb75f31c87cf5f4f2", + "e6bec9a2970b21dee60284fc0e9b00230bf40a8c4b610c9032a48d36b607004d", + "b7e88a7fd21a3fba5a6c13ac443bf3c97484aba8f9c42756dff87fa149e30bfa", + "ab2fb1f3ac35501eb3ad5846c43471c94c027a81e937195b538a2fce7e719378", + "bfd34c9b6a72d7acd4df1dd7a4747a9f588e0d61e80c8bbd05c7fa09c094cc07", + "c079a8d558ef8cd64b09afefad2b88fcf277b8ce87d9abe31c0fc59512d57437", + "d181dadcdc780f17ab1a89edd3fc3bf1352189900c3de8ae2eeaa503215b8d5b", + "19233c600060a2e1730361ec0a05ea5081e7cf1705cdd02d8c83e33f32fe1328", + "bcaaefc82757932ef3b683c033e2b04730a547d39e1fa50398585d26d6be344e", + "cefad9212305e56bedae24dc99fa50361a290ad1cad862247cdd1807002a95c1", + "17d98d7c314fce3dea816afb5d85ba1f1425b8f6906f8e7ca7a1acfdb7600cc9", + "c20b14dab574f8a4aa118b6384797dbaec8d4d8dd8c83f78768fb6d5e799036d", + "27d2ff5380c2553b1b2f40c3288c2d58392e8caa4f77c409b1304ba7fb3dfa84", + "2d0f0f8ed8baa172c768575dede8b92e6c5f16fff84540b0f35a36c87d16bb0e", + "23a4578cbc5927838af8f2b5f13bc229b68cea82d9133e58fd9479682dd52594", + "c8ddfe7b1f8d963b80b6f817572044f05b7952883281cc08f3eda82e3541e185", + "9ce9c46c0fd703375c2c6c8e8d1993f25a5f5cfcb4363dca504bdf9b8b779c74", + "d13047ba5f0e50a8ed395e02a177b5016c01b937c3c6d8ffbbc9f174d3ac1bb5", + "60ae7bb5c94d0f14c3e9bc4ee68fd90d66a656742d1c25b2c3a280dafbf3f72f", + "f24d675e9cd301e6a93b5a3b428168966a045dc161f56768b1b20c993d2271df", + "37677807c7614d0a8e4946a4b9626d887503cdc12128376fc62356492d80a99f", + "508c38c710fc1ed0d226dba58c5b44755a16c5f89c0752eaf9b1f26c2b1537c5", + "c3d8f3b25fb01e1daf6c663ef189c3ff04b41b2bb1663ca0ec7607b224ee592f", + "441cd1bab7158b4db772ff684360f94996550e3e8ff0c04261e9f119efb41628", + "605d98f75dd54a2d1d514ce07bd8e74756901c40125af1afd404a8a0ab70776d", + "63565113bba9f78d6cd51c9a047431a49192af7f586f7bee3caa2aa611b15f38", + "e97c54ebeea362fe175df1655e0b5420fdcb62f2bb2aa44f42df99e48afb0d0f", + "c44a17304d9e777ac8e200b49a10a97b8c2a3879e4e464e9e4f7c27e9ec3113d", + "8ee9f36c71c7e6e2b427595ab488b247e43ae48f5447649b8c04ae14f9f0dedb", + "3bedc7e8b73c7851eb9b30e48e310dc14fde742edee34734a49b2494c2447b62", + "18c104d6c23c19b57245d53933720b369627fa0ed2e6cfea1f0934f20331fd16", + "0ec030ca639c2a8f3a9dda99806110665ba5130caaf3d5a4a379ec5c46d364c6", + "d61720fe8601e7bd51efc64e6a9fe16216ae273dc6907ad7042c275935a5460a", + "4f682cf7dfe79e4003150a092cbad1f77878a7a4bd27156106805c546ccc33be", + "f1e5899db353c5453aa58e05411f17fa0cdf6f0d7e8e1f5380123bf454134479", + "3a18afdf9d6743882e0f7573bf2e8e2f1968cd3d948569df748a7e49cabd4a01", + "e365afc05935a7f782284dd2f63aff24472e363de800788b0058a0efac04f725", + "2db7fc1ecff527a6ccb5028122eb63194d02d5d57cd8116916f421d2efd3e2c7", + "7e00332fc7f03b1e7d8f70118f0eabb2a02ed9bb79cf3124570e2646f2c83109", + "20517feb8659aa197ed59045d3482363ec05ca53fcca9956bc890a1160d53469", + "889a08c1227b3c62cf95c713a7860348f8156b7392a142afff3a5b3f7d0c05c7", + "36778937de70bbebdf6950415424564a8add1d81333f6f28bab3741132a04a99", + "293df1a7592c434fe2e8f4be232aea79530d26bcd20197e0721688dbc9a42a12", + "6e0a2d8d0d87a87747291596f7ed563c320c463119654d685e5b1cbc7c893be3", + "96be978aab4bb71a0f986b4fb9304f5805f0e5c411edc0fd05921faf67b7776d", + "ada8632f1af7f5358cb180b466c904e8dc3365fc99df33dc62e2d7c1881bedb2", + "ce23c3e65c19c26d28a6e1a038bd25b720f1cd086301ca3df86a4e2b1dd46901", + "202701ca309d16f985cd9408b3cd2ba6942ae921fc7d356c56dec25faedf30dd", + "e78e987533df9d8911106e3cf4e14b3258643bfbf66438e40e0c5fad70c84530", + "6dbfb8107884b6e58c38ff2305ba96731f1c976110ffe63396a3452cf5443767", + "e5c841ff71ac47b0fe2251de101a0eead2bc24a636807f6ffd135b36ce69f7e0", + "cc3dc78d615f5278f468b6157ff697bb568fe985cc33eaf73a110edab9a47942", + "c6bac5cce75ba032cf66ad9037061ac799521b73988a0e434c414ff5757b03b0", + "77b68e2b9cb5256a32078a0128fc695a866a7a81eed5f0595a79b168cb5cfb59", + "308d28cd5bdc22301d1585f91ef9ca2d558dcd0a5f7604a3acefabcca159247f", + "09961a1bf9418dbd75a2bd6a139ed9fc0716a8c8182518eb920e1b92d220ee3d", + "13bedef6820771f6580f15a23ad8aa316bf4bf21bfb7278b8f74edeb924810b3", + "bb248e980e531c5781f810525c5b51ba995ed383483c73474832ce63793aeaea", + "16ca9e753176f1c07707a34a5895a21dc325bc9b7e46cf3d8c30ec5051bcf496", + "3cf6be3a0e7f2b8cda4912d0f39c10f049f282bad7f23c45b64f369fb7eb447b", + "e84288e54554825be99199a54fd79c0f79b27e927de9d2005ffc3806ad94f9dd", + "fa111a069e657c274d9586762f200828e4d84c6e19fef149ef6f433b4a8683c2", + "817d7767b8816c993f6376594913ffa93ed3154bc9e71cabe738869833dd9494", + "e3980fc6657bdc801ae8d50582ed17090671ce5d695a79600289c8797bcb079c", + "59f8f8795472969b3e847a78eb6f99285d661da9276b44f43218b708186bf4f1", + "249c11532c6fc4b486e3bfa837d08b96cd46cf03d05fced80205e49399dff7dc", + "8c2685ce89dda92dd5811bc3e765834e94745df5dd390b15c83f9062d8db3c84", + "4ea601ff8171ad93fd28930c73b73c2e4992933bb7855f0159d013267319104b", + "b7eb1d26b85e82b062a9b42b42b585e8ab71da00d7e04524e87eae689364ffcf", + "abb75904a47506ec0ee93ced2fde1c81215bb73ae933316e6f2f989ca721e0a2", + "adbd8489304b74ca778004f2131259269ff46dd49523be10ba43aa8c1f7c6772", + "40356b7d94ffeb7c9a5aa982828846a656ef96d909c442c4c50df6aa62c55e3b", + "95efc381bb862384e7cd9997619058eaff3654c1c67a56eb555d408955034e32", + "399e9faff5513b0a58214c258532389a9dc797606be019ccb25f09c29b7c6d50", + "82151e036749c16f7a88b3fcc0f4a360ed76f24358513c0fe1f01a87fe5ca364", + "237a2d488b6713b50a941d2679c83946896d4ec76f4907de55e829d5d6cb988c", + "82b84e7ae89c3c62e8f979947e5b4ffe785e91bef6a5ccd3dfa1e62f44d62f7e", + "1b97f59d49290354785945d679cfbb11eed9b290eabacf88ed2b4b0d57e20688", + "f533879e8936347f963d590133e047f4e28563d4ab6a704552382ffba2c5f85a", + "a0d4e0e42093caf8b188e8f67d73d22c20db0b48c7ade0be917b583d5743d829", + "dc435b25024adb472815f7548f22988eea59d2e7cd1bd2682f4a3e04c52916e5", + "63df7c6978ebccf7038a434678cb19e1cd846497c2dd8c1c3e30501810547bd1", + "a9c50f4c3680879ce3ca108c0b34b984500b3f45e5b6c8d1588e1fd40a331ddf", + "233c2f5ea76724033f88f2d3940ce84e40e2a7afb7fb77d9f617dfc802b920e3", + "90b24e82ed5806a4a85f68f62a7f4279d5cd7eb1a29c7b4031e224bab3a78eaf", + "a5ba92cecadce2cec0863f3ac44edea0d922c5baf905a015b24d6bda820e3c8a", + "7edd50669725e6267ea58be2129d60c513f6731eb2549b8fc77a5bb4d9446765", + "3be7575b7625aa074d4cb89f45254c5ba1177e4ceedf4350aa3ab3eff9b4d5dd", + "8de87eef5aab7684fcffca2ea6bf5d42dfbb6a9598bfc12ad137e5d00961acca", + "46755dc66d4e8c642fa733afbc48bc316362dc39efded39e14007777159ad768", + "b03592f6947ca3008b84ccfff14f7458456e00acdfb24f568115a26aa7f47e17", + "8fd2a3837ef1122f531c3b1385741908177916dfe138e32cc0253b4ae3990d62", + "56653a2518401ea46c116f3bea11cf86135d5031a8b56537ecada93059d3ac3a", + "0a85a43ea320f46c1f89bbf768686a86f8a6c80b0edec4d25abe572c3bcc68c3", + "35ba0e9af27cce4f5c265a5084aeaf789d6d5b8e6499e4c9c694e16fc16cbe4a", + "afc2fe913ba941e6489cf5e134a1bb492d09829feeb625c1db779682cc5b9d3e", + "0dd3e119054de5b15215556d81ee729fb7eb7c159d864233324606e31e811d96", + "052b979609e89a70c069106bb86e783c20c860f70d7338bb263f57d1be2459c0", + "ac50fd006679672fd5c66ef17c0529124da992cc2f7dfacd7082c2a46af2f4b0", + "3e4e14dbcf1e9f0144d86500d510065caa0d9ca664666396703cc96c583b02cb", + "f4085cfdd929f1267321be702b33290b2a612687a047dcab9e041660aacbb166", + "f44e36916d74bd9a70031762d77066b42ae0931ce5f6cd30cd8a1e8aef178e13", + "3fdd89cba970db35495a9d83b5dc59668d861b573587012a7d18431f4c656a29", + "d6a0c631547e88465725880db5f69ebccaf8801e0812b69ab77fa5cf8460c55f", + "ea9c11e3cf85ae148359198f23983886695026a746f1d65e5821295880c0e009", + "bff06293a11ad0f3fe933c1fea8d19e9d25105ed4bc301b3c243a21fa443581d", + "9b9a85b333afb977d9e2693496ec33cd8ff4c09aea27c8a7322c223abb5f46a1", + "50d544df9c8e11d58a9cb8faf7c05850363e520db43e92956e770b16edc66899", + "030b874900545b381248237f1035606ae995e5f34c671e79f1e1c29566ce2870", + "675de9a222aadd9ee7a4692d9981a623a90dfb7769ee1dde6aca7088b0838cc1", + "92c5078cf1b0d78b8ff5954ea2277ffe710b8c2ac3a1b58e3085721d404094d8", + "99bc1c7e6de7d95950e21971ad44c9b641b5f88d669b1a735ae9a904b741c15b", + "b80f53cbff9d9fc39fa9593dcc830b6abefaa2940d7e9050ba79a781e378ede5", } -const ropstenPreverifiedHeight uint64 = 11841600 +const ropstenPreverifiedHeight uint64 = 11880768 From 33b1aa153382d12633dc7a9e9b576e24a306bfcd Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Fri, 28 Jan 2022 21:11:57 -0300 Subject: [PATCH 140/261] Fix internal API breakage with a temp workaround --- cmd/rpcdaemon/commands/otterscan_api.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 735013ef5ad..e1e2f2197bd 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -334,10 +334,17 @@ func (api *OtterscanAPIImpl) delegateGetBlockByNumber(tx kv.Tx, b *types.Block, return response, err } -func (api *OtterscanAPIImpl) delegateIssuance(tx kv.Tx, block *types.Block, chainConfig *params.ChainConfig) (Issuance, error) { +// TODO: temporary workaround due to API breakage from watch_the_burn +type internalIssuance struct { + BlockReward string `json:"blockReward,omitempty"` + UncleReward string `json:"uncleReward,omitempty"` + Issuance string `json:"issuance,omitempty"` +} + +func (api *OtterscanAPIImpl) delegateIssuance(tx kv.Tx, block *types.Block, chainConfig *params.ChainConfig) (internalIssuance, error) { if chainConfig.Ethash == nil { // Clique for example has no issuance - return Issuance{}, nil + return internalIssuance{}, nil } minerReward, uncleRewards := ethash.AccumulateRewards(chainConfig, block.Header(), block.Uncles()) @@ -347,7 +354,7 @@ func (api *OtterscanAPIImpl) delegateIssuance(tx kv.Tx, block *types.Block, chai issuance.Add(&issuance, &p) } - var ret Issuance + var ret internalIssuance ret.BlockReward = hexutil.EncodeBig(minerReward.ToBig()) ret.Issuance = hexutil.EncodeBig(issuance.ToBig()) issuance.Sub(&issuance, &minerReward) From d207251e7dc7f4e7d9db5182816e387f2d001f12 Mon Sep 17 00:00:00 2001 From: Giulio rebuffo Date: Sun, 30 Jan 2022 07:42:52 +0100 Subject: [PATCH 141/261] fixed watchTheBurn output format (#3370) * fixed watchTheBurn output format * ops --- cmd/rpcdaemon/commands/erigon_issuance.go | 44 ++++++++++++----------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/cmd/rpcdaemon/commands/erigon_issuance.go b/cmd/rpcdaemon/commands/erigon_issuance.go index 5ba8c77bb8a..359b133fd5b 100644 --- a/cmd/rpcdaemon/commands/erigon_issuance.go +++ b/cmd/rpcdaemon/commands/erigon_issuance.go @@ -7,6 +7,7 @@ import ( "github.com/holiman/uint256" "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/consensus/ethash" "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/rpc" @@ -73,31 +74,32 @@ func (api *ErigonImpl) WatchTheBurn(ctx context.Context, blockNr rpc.BlockNumber } var ret Issuance - ret.BlockReward = minerReward.ToBig() - ret.Issuance = issuance.ToBig() + ret.BlockReward = (*hexutil.Big)(minerReward.ToBig()) + ret.Issuance = (*hexutil.Big)(issuance.ToBig()) issuance.Sub(&issuance, &minerReward) - ret.UncleReward = issuance.ToBig() + ret.UncleReward = (*hexutil.Big)(issuance.ToBig()) // Compute how much was burnt if header.BaseFee != nil { - ret.Burnt = header.BaseFee - ret.Burnt.Mul(ret.Burnt, big.NewInt(int64(header.GasUsed))) + burnt := header.BaseFee + burnt.Mul(burnt, big.NewInt(int64(header.GasUsed))) + ret.Burnt = (*hexutil.Big)(header.BaseFee) } else { - ret.Burnt = common.Big0 + ret.Burnt = (*hexutil.Big)(common.Big0) } // Compute totalIssued, totalBurnt and the supply of eth - ret.TotalIssued, err = rawdb.ReadTotalIssued(tx, uint64(blockNr)) + totalIssued, err := rawdb.ReadTotalIssued(tx, uint64(blockNr)) if err != nil { return Issuance{}, err } - ret.TotalBurnt, err = rawdb.ReadTotalBurnt(tx, uint64(blockNr)) + totalBurnt, err := rawdb.ReadTotalBurnt(tx, uint64(blockNr)) if err != nil { return Issuance{}, err } - if uint64(blockNr) == 0 { - ret.Issuance.Set(ret.TotalIssued) - } + + ret.TotalIssued = (*hexutil.Big)(totalIssued) + ret.TotalBurnt = (*hexutil.Big)(totalBurnt) // Compute tips - ret.Tips = big.NewInt(0) + tips := big.NewInt(0) if header.BaseFee != nil { receipts, err := rawdb.ReadReceiptsByHash(tx, hash) @@ -112,19 +114,21 @@ func (api *ErigonImpl) WatchTheBurn(ctx context.Context, blockNr rpc.BlockNumber for i, transaction := range body.Transactions { tip := transaction.GetEffectiveGasTip(baseFee).ToBig() - ret.Tips.Add(ret.Tips, tip.Mul(tip, big.NewInt(int64(receipts[i].GasUsed)))) + tips.Add(tips, tip.Mul(tip, big.NewInt(int64(receipts[i].GasUsed)))) } } + + ret.Tips = (*hexutil.Big)(tips) return ret, nil } // Issuance structure to return information about issuance type Issuance struct { - BlockReward *big.Int `json:"blockReward"` // Block reward for given block - UncleReward *big.Int `json:"uncleReward"` // Uncle reward for gived block - Issuance *big.Int `json:"issuance"` // Total amount of wei created in the block - Burnt *big.Int `json:"burnt"` // Total amount of wei burned in the block - TotalIssued *big.Int `json:"totalIssued"` // Total amount of wei created in total so far - TotalBurnt *big.Int `json:"totalBurnt"` // Total amount of wei burnt so far - Tips *big.Int `json:"tips"` // Total Tips generated by the block + BlockReward *hexutil.Big `json:"blockReward"` // Block reward for given block + UncleReward *hexutil.Big `json:"uncleReward"` // Uncle reward for gived block + Issuance *hexutil.Big `json:"issuance"` // Total amount of wei created in the block + Burnt *hexutil.Big `json:"burnt"` // Total amount of wei burned in the block + TotalIssued *hexutil.Big `json:"totalIssued"` // Total amount of wei created in total so far + TotalBurnt *hexutil.Big `json:"totalBurnt"` // Total amount of wei burnt so far + Tips *hexutil.Big `json:"tips"` // Total Tips generated by the block } From 4cb14f01f8a2b0237e469486473bf2cbe8e8f2ef Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Tue, 1 Feb 2022 19:55:01 +0700 Subject: [PATCH 142/261] penalize peer for invalid rlp (#3396) --- rlp/decode.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/rlp/decode.go b/rlp/decode.go index df4d3f5a427..54ddf1579ba 100644 --- a/rlp/decode.go +++ b/rlp/decode.go @@ -71,9 +71,16 @@ func IsInvalidRLPError(err error) bool { errors.Is(err, ErrMoreThanOneValue) || errors.Is(err, ErrWrongTxTypePrefix) || errors.Is(err, ErrUnknownTxTypePrefix) || + // internal errors errors.Is(err, errNotInList) || errors.Is(err, errNotAtEOL) || - errors.Is(err, errUintOverflow) + errors.Is(err, errUintOverflow) || + // stream errors + strings.Contains(err.Error(), "rlp: input list has too many elements") || + strings.Contains(err.Error(), "rlp: expected input string or byte") || + strings.Contains(err.Error(), "rlp: expected input list") || + strings.Contains(err.Error(), "rlp: non-canonical size information") || + strings.Contains(err.Error(), "rlp: non-canonical integer (leading zero bytes)") } // Decoder is implemented by types that require custom RLP decoding rules or need to decode From d52c213ead52ce6e53b170d3ab35e5da02ff3b2f Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Tue, 1 Feb 2022 23:08:54 +0700 Subject: [PATCH 143/261] Pool: hotfix for slow "new txs notifications" (#3399) * hotfix for slow "new txs notifications" * Update to erigon-lib stable Co-authored-by: Alexey Sharp --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 33e1b4fa7f5..bc86d75b8ab 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20220127090331-cd0b2e660794 + github.com/ledgerwatch/erigon-lib v0.0.0-20220201121653-231506e33939 github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 diff --git a/go.sum b/go.sum index c49b78584a4..40812e94d75 100644 --- a/go.sum +++ b/go.sum @@ -499,8 +499,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20220127090331-cd0b2e660794 h1:wnlxEKAgMxSvYtqgWluYCYjxl/ePrV+u0MY6RxFFIl4= -github.com/ledgerwatch/erigon-lib v0.0.0-20220127090331-cd0b2e660794/go.mod h1:BQNYmN6i8RdHqedsztAj3XDnswYebacmFAnsznlisTc= +github.com/ledgerwatch/erigon-lib v0.0.0-20220201121653-231506e33939 h1:gDB89cmKon/6waTGYBJFaPz1P6SogHxIQgZoGSk2iwk= +github.com/ledgerwatch/erigon-lib v0.0.0-20220201121653-231506e33939/go.mod h1:BQNYmN6i8RdHqedsztAj3XDnswYebacmFAnsznlisTc= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= From 4f0fa99c244ad20541b0902bde03ed7e6652bfcd Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Wed, 2 Feb 2022 17:24:47 +0700 Subject: [PATCH 144/261] pool: fix race in async broadcast (#3404) * pool: fix race in broadcast * Udate to stable erigon-lib Co-authored-by: Alexey Sharp --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index bc86d75b8ab..4ccff3827ee 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20220201121653-231506e33939 + github.com/ledgerwatch/erigon-lib v0.0.0-20220202093315-e3f672e28f76 github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 diff --git a/go.sum b/go.sum index 40812e94d75..a64c18fa51a 100644 --- a/go.sum +++ b/go.sum @@ -499,8 +499,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20220201121653-231506e33939 h1:gDB89cmKon/6waTGYBJFaPz1P6SogHxIQgZoGSk2iwk= -github.com/ledgerwatch/erigon-lib v0.0.0-20220201121653-231506e33939/go.mod h1:BQNYmN6i8RdHqedsztAj3XDnswYebacmFAnsznlisTc= +github.com/ledgerwatch/erigon-lib v0.0.0-20220202093315-e3f672e28f76 h1:3wt4XnLRkQmfiKrxV9pvKcy72eDwEcCblyKkbo2eryQ= +github.com/ledgerwatch/erigon-lib v0.0.0-20220202093315-e3f672e28f76/go.mod h1:BQNYmN6i8RdHqedsztAj3XDnswYebacmFAnsznlisTc= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= From 8401197cf009993de5e4f2de001ab58cec412827 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Wed, 2 Feb 2022 21:06:10 +0700 Subject: [PATCH 145/261] sentry: 1 goroutine per peer (for outbound traffic) (#3407) * 1 goroutine per peer (for outbound traffic) * 1 goroutine per peer (for outbound traffic) * 1 goroutine per peer (for outbound traffic) --- cmd/sentry/download/sentry.go | 101 ++++++++++++++++++++++------------ 1 file changed, 66 insertions(+), 35 deletions(-) diff --git a/cmd/sentry/download/sentry.go b/cmd/sentry/download/sentry.go index 6ac451f3397..fca513d3212 100644 --- a/cmd/sentry/download/sentry.go +++ b/cmd/sentry/download/sentry.go @@ -55,7 +55,27 @@ type PeerInfo struct { deadlines []time.Time // Request deadlines height uint64 rw p2p.MsgReadWriter - removed bool + + removed chan struct{} // close this channel on remove + removeOnce sync.Once + // each peer has own worker (goroutine) - all funcs from this queue will execute on this worker + // if this queue is full (means peer is slow) - old messages will be dropped + // channel closed on peer remove + tasks chan func() +} + +func NewPeerInfo(peer *p2p.Peer, rw p2p.MsgReadWriter) *PeerInfo { + p := &PeerInfo{peer: peer, rw: rw, removed: make(chan struct{}), tasks: make(chan func(), 16)} + go func() { // each peer has own worker, then slow + for f := range p.tasks { + f() + } + }() + return p +} + +func (pi *PeerInfo) ID() enode.ID { + return pi.peer.ID() } // AddDeadline adds given deadline to the list of deadlines @@ -101,15 +121,35 @@ func (pi *PeerInfo) ClearDeadlines(now time.Time, givePermit bool) int { } func (pi *PeerInfo) Remove() { - pi.lock.Lock() - defer pi.lock.Unlock() - pi.removed = true + pi.removeOnce.Do(func() { + close(pi.removed) + close(pi.tasks) + }) +} + +func (pi *PeerInfo) Async(f func()) { + select { + case <-pi.removed: // noop if peer removed + case pi.tasks <- f: + if len(pi.tasks) == cap(pi.tasks) { // if channel full - loose old messages + for i := 0; i < cap(pi.tasks)/2; i++ { + select { + case <-pi.tasks: + default: + } + } + log.Debug("slow peer or too many requests, dropping its old requests", "name", pi.peer.Name()) + } + } } func (pi *PeerInfo) Removed() bool { - pi.lock.RLock() - defer pi.lock.RUnlock() - return pi.removed + select { + case <-pi.removed: + return true + default: + return false + } } func makeP2PServer( @@ -501,10 +541,7 @@ func NewSentryServer(ctx context.Context, dialCandidates enode.Iterator, readNod } log.Trace(fmt.Sprintf("[%s] Start with peer", peerID)) - peerInfo := &PeerInfo{ - peer: peer, - rw: rw, - } + peerInfo := NewPeerInfo(peer, rw) defer ss.GoodPeers.Delete(peerID) err := handShake(ctx, ss.GetStatus(), peerID, rw, protocol, protocol, func(bestHash common.Hash) error { @@ -615,13 +652,19 @@ func (ss *SentryServerImpl) removePeer(peerID string) { } } -func (ss *SentryServerImpl) writePeer(peerID string, peerInfo *PeerInfo, msgcode uint64, data []byte) error { - err := peerInfo.rw.WriteMsg(p2p.Msg{Code: msgcode, Size: uint32(len(data)), Payload: bytes.NewReader(data)}) - if err != nil { - peerInfo.Remove() - ss.GoodPeers.Delete(peerID) - } - return err +func (ss *SentryServerImpl) writePeer(logPrefix string, peerInfo *PeerInfo, msgcode uint64, data []byte, ttl time.Duration) { + peerInfo.Async(func() { + err := peerInfo.rw.WriteMsg(p2p.Msg{Code: msgcode, Size: uint32(len(data)), Payload: bytes.NewReader(data)}) + if err != nil { + peerInfo.Remove() + ss.GoodPeers.Delete(peerInfo.ID()) + log.Debug(logPrefix, "msgcode", msgcode, "err", err) + } else { + if ttl > 0 { + peerInfo.AddDeadline(time.Now().Add(ttl)) + } + } + }) } func (ss *SentryServerImpl) startSync(ctx context.Context, bestHash common.Hash, peerID string) error { @@ -705,12 +748,8 @@ func (ss *SentryServerImpl) SendMessageByMinBlock(_ context.Context, inreq *prot if !found { break } - if err := ss.writePeer(peerID, peerInfo, msgcode, inreq.Data.Data); err != nil { - lastErr = fmt.Errorf("sendMessageByMinBlock to peer %s: %w", peerID, err) - } else { - peerInfo.AddDeadline(time.Now().Add(30 * time.Second)) - reply.Peers = []*proto_types.H512{gointerfaces.ConvertBytesToH512([]byte(peerID))} - } + ss.writePeer("sendMessageByMinBlock", peerInfo, msgcode, inreq.Data.Data, 30*time.Second) + reply.Peers = []*proto_types.H512{gointerfaces.ConvertBytesToH512([]byte(peerID))} } return reply, lastErr } @@ -735,9 +774,7 @@ func (ss *SentryServerImpl) SendMessageById(_ context.Context, inreq *proto_sent return &proto_sentry.SentPeers{}, fmt.Errorf("sendMessageById not implemented for message Id: %s", inreq.Data.Id) } - if err := ss.writePeer(peerID, peerInfo, msgcode, inreq.Data.Data); err != nil { - return &proto_sentry.SentPeers{}, fmt.Errorf("sendMessageById to peer %s: %w", peerID, err) - } + ss.writePeer("sendMessageById", peerInfo, msgcode, inreq.Data.Data, 0) return &proto_sentry.SentPeers{Peers: []*proto_types.H512{inreq.PeerId}}, nil } @@ -765,10 +802,7 @@ func (ss *SentryServerImpl) SendMessageToRandomPeers(ctx context.Context, req *p var lastErr error reply := &proto_sentry.SentPeers{Peers: []*proto_types.H512{}} ss.rangePeers(func(peerID string, peerInfo *PeerInfo) bool { - if err := ss.writePeer(peerID, peerInfo, msgcode, req.Data.Data); err != nil { - lastErr = fmt.Errorf("sendMessageToRandomPeers to peer %s: %w", peerID, err) - return true - } + ss.writePeer("sendMessageToRandomPeers", peerInfo, msgcode, req.Data.Data, 0) reply.Peers = append(reply.Peers, gointerfaces.ConvertBytesToH512([]byte(peerID))) i++ return i < sendToAmount @@ -787,10 +821,7 @@ func (ss *SentryServerImpl) SendMessageToAll(ctx context.Context, req *proto_sen var lastErr error reply := &proto_sentry.SentPeers{Peers: []*proto_types.H512{}} ss.rangePeers(func(peerID string, peerInfo *PeerInfo) bool { - if err := ss.writePeer(peerID, peerInfo, msgcode, req.Data); err != nil { - lastErr = fmt.Errorf("SendMessageToAll to peer %s: %w", peerID, err) - return true - } + ss.writePeer("SendMessageToAll", peerInfo, msgcode, req.Data, 0) reply.Peers = append(reply.Peers, gointerfaces.ConvertBytesToH512([]byte(peerID))) return true }) From d58bfe6333bc52ae306f47661c710157b6e44500 Mon Sep 17 00:00:00 2001 From: Igor Mandrigin Date: Wed, 2 Feb 2022 15:25:32 +0100 Subject: [PATCH 146/261] [stable] fix compatibility of getting tx by number (#3410) * fix compatibility of getting tx by number `eth_getTransactionByBlockHashAndIndex` and `eth_getTransactionByBlockNumberAndIndex` should return `null` if the index provided is out of bound (checked with Infura and Cloudflare ETH gateway). * small fixup (formatting) --- cmd/rpcdaemon/commands/eth_txs.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cmd/rpcdaemon/commands/eth_txs.go b/cmd/rpcdaemon/commands/eth_txs.go index b0683c3b506..79fb8685923 100644 --- a/cmd/rpcdaemon/commands/eth_txs.go +++ b/cmd/rpcdaemon/commands/eth_txs.go @@ -3,7 +3,6 @@ package commands import ( "bytes" "context" - "fmt" "math/big" "github.com/ledgerwatch/erigon-lib/gointerfaces" @@ -121,7 +120,7 @@ func (api *APIImpl) GetTransactionByBlockHashAndIndex(ctx context.Context, block txs := block.Transactions() if uint64(txIndex) >= uint64(len(txs)) { - return nil, fmt.Errorf("txIndex (%d) out of range (nTxs: %d)", uint64(txIndex), uint64(len(txs))) + return nil, nil // not error } return newRPCTransaction(txs[txIndex], block.Hash(), block.NumberU64(), uint64(txIndex), block.BaseFee()), nil @@ -171,7 +170,7 @@ func (api *APIImpl) GetTransactionByBlockNumberAndIndex(ctx context.Context, blo txs := block.Transactions() if uint64(txIndex) >= uint64(len(txs)) { - return nil, fmt.Errorf("txIndex (%d) out of range (nTxs: %d)", uint64(txIndex), uint64(len(txs))) + return nil, nil // not error } return newRPCTransaction(txs[txIndex], block.Hash(), block.NumberU64(), uint64(txIndex), block.BaseFee()), nil From 2faf546b0c3547d42f87d74580b1a654232a7b1d Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Thu, 3 Feb 2022 12:38:13 +0000 Subject: [PATCH 147/261] [stable] Update skip analysis and preverified hashes for main net and Ropsten (#3416) * Update skip_analysis.go (#3408) * Update preverified hashes for mainnet and ropsten (#3415) Co-authored-by: Alexey Sharp Co-authored-by: Alexey Sharp --- core/skip_analysis.go | 2 +- .../preverified_hashes_mainnet.go | 183 +++++++++++++++++- .../preverified_hashes_ropsten.go | 148 +++++++++++++- 3 files changed, 330 insertions(+), 3 deletions(-) diff --git a/core/skip_analysis.go b/core/skip_analysis.go index a4dd8505abf..55c6c658c06 100644 --- a/core/skip_analysis.go +++ b/core/skip_analysis.go @@ -21,7 +21,7 @@ import ( ) // MainnetNotCheckedFrom is the first block number not yet checked for invalid jumps -const MainnetNotCheckedFrom uint64 = 14086800 +const MainnetNotCheckedFrom uint64 = 14121400 // SkipAnalysis function tells us whether we can skip performing jumpdest analysis // for the historical blocks (on mainnet now but perhaps on the testsnets diff --git a/turbo/stages/headerdownload/preverified_hashes_mainnet.go b/turbo/stages/headerdownload/preverified_hashes_mainnet.go index d722b6ac5c0..c4d6585ac82 100644 --- a/turbo/stages/headerdownload/preverified_hashes_mainnet.go +++ b/turbo/stages/headerdownload/preverified_hashes_mainnet.go @@ -73370,6 +73370,187 @@ var mainnetPreverifiedHashes = []string{ "65065cad644bacf668a832f68642e7f00bfce89c98fac48b47a21db379d45f03", "bb55bfd8cd00243c837dc06d937f2d4f83d498135507a02d7885de5c754e4655", "3ad9912f842aaea3fe9bcdb8bfb42c7e1f189510eaa68fd3358d0daa0f97382e", + "180c0eefe213114587300a2aea421d4ec858a0faa5ccc0eb1c29ffa1a9b2977a", + "ac920f30062d72403c0120361822400f386d36250770391990ada9a6fb70d973", + "e07878968fbd3bbf611946a17d4cfa0f52bf71be4c978cc59a618b0e699f3df1", + "2ab9a22db10291d5f13dc65eaed919df561c39bfb7c204e77945e8da5d1198e3", + "1dda666cf914ab559649e71d162b450d70838786eb29d4a964a5299d152f2981", + "60d6221a3b048ddc168e360ee935f9b9405a918cda3dbdf82690ef4454f87ef1", + "733f2def47e6cbaeca015284d54d8d72a6227c287ba828d66c7c381d497140e1", + "489372fdca1c7546583f055de219d7f2d02633a3b94237e123d6badaa8c502f7", + "24b6f8a09b800554d2edc5772ceaf5873b5b71d8ba6547c4ed38745bf6d4a230", + "0c520e03666f5a79353498c1289eac8e8db6988cd2dd7062053df3cc6605a326", + "b54c5d297068cae15a9d964a1c5993d715c6ef18e28bc71240c12afa53c497aa", + "c054e92361648a84f4486b6055fd833908b0ea6b878c0d2fd41450abd7ac14ba", + "c07bf50637a39f8da78ae4e37ae10e51f382171a9c133886920d87bd8b1bd183", + "c95f67aca9e8878e619e004f8f70914cc161175fc96366f0a36cc894cf7e6495", + "b03ab717e6eb6902490ff40839e10102c01071ec7a035580e4fc8785ff204990", + "b7da34f6bd47adb9024ca4944eb434ac217c07d942dbc9432d1c028e92759beb", + "2e3035b11663ca3656a8f11795dfe16b8fd676c6bb95a96009778d6b70003142", + "5796cdcd49f49d675c118670577431ce5533d8a43c6647ac7da92520ff164f02", + "8b5b72e1af6ef5dfc74d24f2bce6ba8ed1ad2eb8e50d14b16eafb2cd98eb6d16", + "a5c5b53f6b45ffa1f327134f56565ddf8e90d89f9d112e89d25ddccf643ae412", + "5569359f0e4f1ad9391f50a578020f7c1f15aa00785440f46fdef1f5c5b5c941", + "6704d5bc915d22aa2ac6f43918671444afd801f17d4514af211ada425c2f4fcf", + "328ee67fc917dcd7a4cb122b5886d6cea7cedfd443a9dc7a9d6e306488080bdd", + "efbfe9e5396fa851e0520e6e3fd4b7c489335e8497539cae5ead53593667af46", + "b03c8232fbc11656a2a9168d51723cfbe23b980260b098448e576e33c5e2416a", + "b7972ed0c17f8f2d89e185440e3e94553051134e82bc5ffe05c939bdb9cffa79", + "73d412d14bd992b70403464ddf6f51b0daafde2d9ab4d66996e26abfd4f6a6c7", + "3522fafbddbb11e214e3526a11991aca85361372359260a79cec38256120d4b3", + "1006f7a968df49e3372f89317a47fc03a68b0c20b796038014b8fdce47f94123", + "604d25647373abd2389a457b6c1a7aab1dda5f2933a65895af90c5c39702b1be", + "7aa5ee7b4938f23f317ee22997ce332bc9366eb7c110ac0babf8aca6dea7b8de", + "aa40ceef1edaa8a76fa4ba9af49b9d257bf2dae9c2efcb44a1608d0edf8fcc69", + "19548b354104c9205cc0e35c58475253713c0393b828c3cd7c92c6f5fdaf4867", + "51e77e833d7f89329ec11016ae934309801558db13f09998293bbc2015e2d387", + "122adfff2f936a7cde746318042766d5c304f2b4e972d2b8bc3a2152f4b84671", + "7677836955a16411cba6264df60a15eb9a4b4d997d7436ea7e57ff1779abd5ed", + "70c7b3bb8e721ae66dc596ff439bc6357af0029f8dc0017f8fd62da0218ba545", + "757460fabbb04120236db629f3102e889489f1cf54d21b704a0d847f6b181699", + "3c8cb2229e8e091f4fa5c3a53e42214118f61945c4bff1c189a312e8989784c9", + "b7f95abd77dffdf4180391e9c94e80e844ffd9f174af54bd74608a46c58700d0", + "e2bcda4927a92078e8481b2694298a38ce1b9f635ec388a5453dc4e1cd49f2ad", + "4f98dffed2b9200456015312d5053aa369959f1c9f289faf02093783853d465f", + "d9cfdb9223285a8b87e7b6d7eaa1a0e53336cb8758bca08ce603f99666a603de", + "e20b910746d3a56d454ac739f9fd1caf0182f201f1b81d76540a168e4dc35960", + "3369b9131bfc9221602617a8ce91831a4d012d2ad463fc699077067ea0f3a204", + "6d63b5a2112f8eb7877867f698cf4f05e491a8a907ca5723359878cefc083392", + "8aca271e07330a81135b6bddf15da8eae759307fa9bdfa18811a547acf31163d", + "1312df9fc21850247956f5b8b86b46c444ddd58d37369f2e89fc253aa460fcdc", + "87ff0cea71c10f9fe17aee73eaae74b81b7fbbf0851934a16b95bdda418d6da3", + "490a8040a6a6db201a303ca9e4050d5a7d324482156a7cf24326540cc5e85b91", + "24d4ed0b77475837c5be21cdd3c049ff592f028d590e67d90994b894f4156fc8", + "fb039514189206e60c828380e4324a02d743b71a7f664b71807570f48bb15e2a", + "a744274ec72de88e958a5ab1cc23a20af2726351b095cfe1abdfd957ef2745e3", + "436ca721433c4bb9abe8ff429c36079a3483ed0ce30318fd5ddad75414579996", + "9df06be24f55605b3367b2de879076503cc09dc68ecf59d76fbc436ee5118817", + "709e11b664a8cd23194dbe38d9b014b48a6a8b09bc6487545b600ce3fe3f0c6c", + "683ff33c48a9d8296981944581e2944143aaefa86c2a7425629f4ef4b2bcc776", + "b078e06491bbb5e8a8e71c18d4e0a6579bfc52c2c61586ab0d2e1c4a3bd2e682", + "ba9c287b84792d4f56d25237ce9555298bfa106def2401c0553d2a7df046dd7c", + "2247e832cd7c6ce7f6a8e9b9ddc2130d7b1bb350429eac157b4fb8cb9fec40bf", + "f2c734c8793c38ece3492ec1ac0d55f8b3fa86ef26e4fc7758bf32b9b7fe4ea8", + "e302559a4c6e509a05a3708ed8f05ab39af8719dc3de3edab0cc2eba32ef0225", + "70338ba2a3aa095e779e42f7527720254696105e79e943d8b773041530ca9530", + "d58b7022d356b41bc7c867236807181bef1ec6f2e9f25102b3e91132b49d9b94", + "af87b7ac80d59bfff786bd02035e26c4daf6a48231dc609877e2e0b4ff75cbdc", + "ba3d26b477823bdc88f4a89d04b79f3b9668608583a529e66e488ae373395239", + "33f16815d78c5288d70011baf3d5fed03fb6d8b52099c429b5a05d4e8f5e0b3e", + "b54568aec067b280348e90a55a2ae6d7bdceb3681c07fd7e4ba01c8a4b574757", + "ce54e9d7197f84819159aedf3928f515c40c6b54d182b229166214da11c1733c", + "2df4923f379c297a81c30b43a0c5e6ebe12aeaa5b1220008026ee27d5e7a306f", + "691b868cfed913c35fc74af762cd1e0a4f58e716c1a46bead1b30859edb7e69b", + "2de262ec90759f26ef6afc20bf6aaa8bdfb422c7641fc65cb342a56119a18603", + "1488240eeba1fbc39bc990408118517c933d38e5f48397b598b74c073068b909", + "340ece33bac9f5a2121c1da2c06ac1c05cff61ea600743e7bf2a112efeb8072a", + "e9efbc3648050695da30372ee73f8160ba308acaab36c6fd787da25334103c96", + "de2a42d86d6a3ca0ccba978c44de60c106e74c475e95c209b826269409bb6dba", + "4300cb183f401951a64e1ccac464af2e2d4ef7ede7f07fb4357fc6cdd00142fb", + "18308825212a0f5c84fe07c6c164eb8e31b8fd70709421cc7326ba1bbb3d3109", + "1a3dfce48708d664c4d0f6c1b5216cb4e077dcdd317426cd5d9bc135289ad5aa", + "8c1ef822d753a4721e0b88e856d62fc68672a46fab4601be21ee7c99dd5280aa", + "600cab7edba45f100abd2bcf44d8ad688d7f6c20613334c9aaf8ca11869f9b86", + "cfba686f05bbd75180d5a3704be3fefe905c1d8a2331c1b3a2c3a232774ae073", + "c68072e3c0c21101b2e270c6e2ae848af4aa927785ac027880e914d494530c94", + "075caa87fcc346ce27e642194f24795cebd2fe472575536b10e9de170e5e2627", + "d5df4535fb85f271b3461e433b7dd186c693279137cc16e514e8c309ca5fa061", + "da0090a939035610babd20c1d158025919915c6ccb732846b92235109c8be8f8", + "5ac01ff823d5b667c8546e5bf3879d53960621f00456e77d0ac96ea5c9ebf33c", + "ee56d55d8c420f23a6056baf6af8471838d7b6f9be3ba71a2182af175a2aa267", + "9eafe04bca4e170eba20481810e3d1954313f69ac83cf98700862f8768b20b52", + "eb6c4ba2220c85f5bd882b28d8d7f71dc3a6da07cf547048e85dbb8e89b46d7e", + "f77836f9b5cc4151593d7b112d94357d2c1ac6d4d5407537635d6688edb5b724", + "4811183ec6f76aac4ec373cda98426b89996af4810e01eea28b5339672687dca", + "82e0ca46d4ae0d287e4ee2f1d3234506dbece4278e7b23d96f177c393461d13b", + "5cc86e2a86be33af14603a86b4a66e287f570441b9ddddbd7a90d4432375de89", + "c7e0482747ac2fe8418226a8acec0481226f47cea9189a17ca8b74abd5ec6aab", + "fb80d543ecb00fca6fb88a458fb3750225da8cdf06f3b2a44003659475c0d04f", + "5d0412e030228089500d593b6cdcc485245261e4b366ce61b769541ccd9e74c3", + "8930fab5f9d939b39b65a059387b6e99ce92173387f5951555ffaf41e8a13fb1", + "1e8fc91d4231b0c074c42229522b427d987dbefe30b1e2046225ed5960a384ac", + "55aac7179172ac73933373a86b821c5165d3400e8a20e210f804e33c16790adb", + "fa02d7ee1738abb354a962c4601aee0df2c2fb91699f2cdc0d0c93df6625180c", + "bd6228470beb1d4fda8b1cad3bcea93a691a935066e038a4f30f62f73993fbbc", + "f41b3781317e6ba9748ac5d10c59e40de48b34f92f7978ee93aa1cf41b4d0821", + "da2417f8ff683e5b147b1fc7f3fc6263c35433b76866de50b4b52759361e8634", + "567f3000661e5cbbb3788bba6584dafd44fd9166c97d3ea4da032d421770b913", + "069649339896853b047e4101153a63e83c173a13ccd656cde3ceeca5990a459a", + "e6a151a5a61998cfc8f6c3b64b08e1f465ee143d110206cb702108a062a44bc9", + "c352a6fce0a2caa76a0ee0af802f3e2a6d717977e41fa86483ce36234512e897", + "53f8e530603cc51960f95ea8aa474a2478afaea5f18dc205821d5645e9ed94d7", + "a2d2716db8d7caf47164a4a431fc765f248fa063ceaf979ab9587a868b1933b0", + "0538fac11aaf39e879a901207179391ac144f63eca7a983b6ff64e991974b0e0", + "93d53b882a781a6401714d97410bb5b0919d4d15f9072edbe5513ad6be1713d8", + "1fdc296d280b5c73490627357f262fd5177898698fca149b2ab1dca55bca3f2c", + "e18dcc8ea671ff7fc6ab7769398af4c8bdf2aeb7aa7a3c33025cf3d22a0f3d1d", + "5a5ace108bca66adaecf20e24a39405259d6b0fa9a41a999bb86956817fffadf", + "1c485f7d99fb350e646d06d178d0f63ba1dffb64c3062bf0deb8f81c3964f44c", + "a5dcd81948040fcfeeb2e00fbe46bd2aea81c0e37d26dda5054957606e46c6a9", + "d6c95b363e747dcb314c31036abbdfab1cd291d48cd1c8f6e12466d7e351ada8", + "ac5c42e15f5fdfd59ee7f4aa9da45f1f4e0052df434069035535390695920bd7", + "f469b7599f0cc5ee50c9d23388809ce3edb30f0fd892522f72fb3d6369214f32", + "04f0a6f838dad603bc86eb3cc12c51e8aafb1b726b5983d96754d00110692367", + "8f2a7611fb92c846c60912939c66ab8b4a6f79f70d648cb03260392d602007c5", + "c291feb010b12df7960ddb3b2ca95298a7dcf7274278f5c8a88088e17fcdc30d", + "f0882fac7e0004dd8067afbe848c11b8201798f5f43a810cce90fdff53761675", + "76af0ad0dd5f98b04d55c860b015fcabb804a497c0c8cdccd85c98c2fdc73591", + "145f23a7368c9f28ddf39ec96dea674d41bc4d61f7f546be82f8102b932bcbb8", + "ed5c637e5662f47281f89b074a8c222c4b9c6346423f73ff6f529d6b30a39e62", + "85e65fd47bdcbdd4778c727609c8ea50a46bca2ae33a53780db794fa864f0055", + "96946f6d13efb4b553817658720bbde657ac415ac65a342a80b06ffbc772ce89", + "ba7808ad25b4112403f9e6847121c27c396bb807edac7d5175d0449eff88b502", + "8f2aac2b80637023be57e64d8f23311df1e5e6c26d557bb239c48c2736963d04", + "911cd412aaed6ea28cc2f58db99538f46b760820eb98acfc834b90c84d0d7dd7", + "da2c1e326904a92f6ac5203a298a480ded7c1d6c2783387b51ebf9c92699e6e8", + "bfe48abf84c2a3fcbfcb9296de30b7b4821e00bea2ae560c5bea3ea3dbeaa2a9", + "0e29cbc7b8b1a28cdd93e72f51729d86800e94146f1203145fa98dfa83ce5d69", + "e8a92b2bb16e6218312b4b3105ee581bfeeb99ccc45e9dfedef1aad3263d7a67", + "46dba2b9541a78ec4064b756683526a1c9f1ea8e8b6a8cb84ac721c11a04970d", + "a43c78511648faaeaa913cb3902639e41255d23a68b871c3cbd526b90ee2f79b", + "2ba27826ff89d4171ec0c7b3f5b690881b2ea4758685e83c6d7f582837cd8127", + "e46879029d868a0acaa12b9f6ca244418cc735b363bd082f695957693e07a415", + "5be16e8631f9dc73127a398653057765be3278a2f867370e1c3ed028b19381d7", + "82400f19d4e97a6bfe3ff1bdb6e16e42a2f9b2b14a216fb50b0e55d4be0a592d", + "8f7421520a6c9fc46304e4f34d9dd1a30db42e3fad7f999028c1a353ca3d48ff", + "220c40ec0e444c27bb4c2ce6ab048977ac4c50f6066fe494b0c8a04f83ac699d", + "bc3fafd7feb5121d35508a94403c1604008d94eb9655cb52e9e810c0496b2824", + "abb48cbb755490e639944d9544ebc48fd8a960cdf5e5e57e99804f67ee0a7105", + "f017b9ecde8e7a159b46b6054b4ba622f59c5f7ede0d635cdf77a9ac8552a146", + "2521cc512eee2c3cfe41ad85a43c4501f98e04fe47843ca04e18139a8be1622e", + "a41ffa191d0d47925be170b2d1cf3d19b8cc20bf447b059db7c5776a34051519", + "2ee5bdfe80875e17c24bead70c02d519f55d611490b3f87d095e8d292e3b79ae", + "61aafc9ec7767c83674198ed8f4fd6e4d8a873abc2c7d771e0046a36d4342b02", + "7e8db37439335b0a11b908b81bd1f521e6ad1e467cb80b844afa99b2e1b71071", + "ab94d4a9b65663c10a9a405ff1587bdc9d29e6293ebe66ef5b8e1c8b9d1e4696", + "ca580780d0e423983e0eab74ed03f001d48090d9e9aae9689d7cdd8443e93896", + "5f75f240c185d12d59c6e67033d0e6d8eadc0213b7ab4887251a1d1a1fb98157", + "6df89784f4be419badebf35448d918755d836b12f138a402057079e68c8108cb", + "c023411b6a69a51e079458ad49b40f034ada3f3fccc66cbd08f9a24ddd950f21", + "f78d3b2eea20da883a733c2c5938f743a8a4191ab42795f627aed3698ded5071", + "98317a5b4ecdedb1a71350f011d525bface87fe0fca3ec0ff5c362da8543cb05", + "05a1b7ee437c76194a7b557aecab7d688aab3b890b9dc3970ae4419bfb06fc76", + "6a8b096b99268125ec34f52a9e67b8ac46fdfc0521227c3ccab927ac40875860", + "62f1f085c30c59f3da8e6aec2fcf1a5047c93a60beaa0f1748ecb3d11692f30e", + "da92967dc6bbf282e0eb9353a63ae899ca3649e386d4b5af4d69d2cb17f36ac8", + "af4363185903f7729a02b5be1ab545b1b1c6c5b6fac0f3ee122edb3ee6c4e870", + "b42dce5d7515dbdf2a7c49b4c0737663304c979082fa6e199ce27e92fa7bd5e7", + "08c281eeef46d924006b74f1543cffd66be1eea2aaf5ddc5748a6cccefbb63a6", + "da71db727a4388e8b34901fbc6b65d547eb697c79a7c52e371cb6477791803bb", + "e670923770636e624f9fa94bf553da2f1b27bf24d1e8bb02634e209add2948d3", + "b782befcdab263e0cb641b3914f8666191200306eff3d993bd3459718f60b4a7", + "dfe65edb40ee5168bffdd9747f1c7afcd844b1db7044c678c681d4c40d3a8b4d", + "ae5ae323a0eb3098ebc873338146363c3333fdefa8c789691eed62aa2cca6f61", + "3426a12fbe425d0e5ea603f0fa8ffb11eeda41e56e0ef9ec53cb296caf21d6b5", + "79899a3e8ff6d19656d82530ff79c13620ba49edf8cfbb7116409188ba09c107", + "b07e82e66fe4e1b7e34b0ea9f2f3f78955e6a9a54d0b1bf33e762e9224b85586", + "ac40eec1e7c0132c77a8961e7e0c8e57678ecce34deb60dd2342b16a08ae8c95", + "14131a5e4ceb1ecb6a38f73656808c8da0882a29d291e9d04ec8a1ad75cca7d9", + "629513123654c242c7f0df713d7d96ba23a6059c201c19e35f8e21ac5b94ca3e", + "1cbd412690a61276bd1eda381339f4744841cb1e7f3340354865e9f989e46bd3", + "c66fba67205d7cc482ac946d4deb42c5d5aa7c8824fb4fe53d204f438e4addb2", + "2efde96fb63b15cbdb02f92e9c2e3865e2b3fe89049707debe7174eb786bb7f2", + "ba155688bb8c82e3b214c983c51db5488c255c326be4852c1c972c7eb5b48cc3", } -const mainnetPreverifiedHeight uint64 = 14086656 +const mainnetPreverifiedHeight uint64 = 14121408 diff --git a/turbo/stages/headerdownload/preverified_hashes_ropsten.go b/turbo/stages/headerdownload/preverified_hashes_ropsten.go index 6e00a80d5ad..16f5df1ba5c 100644 --- a/turbo/stages/headerdownload/preverified_hashes_ropsten.go +++ b/turbo/stages/headerdownload/preverified_hashes_ropsten.go @@ -61881,6 +61881,152 @@ var ropstenPreverifiedHashes = []string{ "92c5078cf1b0d78b8ff5954ea2277ffe710b8c2ac3a1b58e3085721d404094d8", "99bc1c7e6de7d95950e21971ad44c9b641b5f88d669b1a735ae9a904b741c15b", "b80f53cbff9d9fc39fa9593dcc830b6abefaa2940d7e9050ba79a781e378ede5", + "309d6fee8343157ea28a7b11826f29d5d58675b65d645e2519f7da2e147dbd71", + "d0a3ec6f4dea09808c63c776d0c34b8ea3ecd2a41c785352148feb3665242c0b", + "6374403410ac1c1e5ea4a232ebee707b732365d2b4281803bf6394b02cfbd2fd", + "1ce9e8d34450156ff33bf0816cc162d4c35c7c7ad53e2787549dac637845aa13", + "e357b1d20116b7ba1df6c8e6a8b89a15673a8f1e2e90199563a3b8123c1fd239", + "5d1a260947a37f5a8decce0b640611f160f41c0faf728d9ebf888b95604a39f4", + "fc0f73404bfb21fea14e5c3d96a55b7977d6837b4eaef24d659d5ab7e0a327a8", + "6630a54576cee52696e0e76e0fa364d84ab2443415b13703ba7cca15e421cf05", + "0ad31e092f0cc17e23a9b36c5f00e2054bf1e9060a1899d871342b63b3ac4bb0", + "1f6cac9bd1de213bf3f4838dda2d80b56d94c68f9a81b12011780171bc77383b", + "5cae496ab6084222fa4581f8fb15d616e0bca7f0a22699b580d58a7bf5d88830", + "354a7320cea5654f1d9269b22291bf540e8f29d9cee81ec8a776d6a67d26511a", + "7eee776311db7c72c03c027ce0a37fc335e9261670d1c7cd2eaa8bd107bd6608", + "efb1579df19f73851a571b26e72bf6a539c690130645ad8ca8dd64719f6c58ea", + "c45dc6d3bcd4e0add00bfe375af05175098e494a9b7168a79582e85944be36e0", + "107c5e49997af34bb3a6341d961f7af3b072a053a4ed6719b2c9ffd9d09374f0", + "52974e0da1ccf57d0977a5d5c8a34c2c0065546e4b33bacdf77fa1a250a87678", + "28e76304bf49520cfb3b7b3ab0deb66dd389900eb81f6b3d22419e42d05e991d", + "146fbafcf5a14e29e36c3a694287120422747cc9a00d70c2357100f3dd770f72", + "ca231c52a3e404055df870554f978c655cdf6b314c8653a5e85224d5f87f7e3d", + "c7d555493d7237a5943c09168b9087bdc4e0ddf77006bb862921214fc24b3ffe", + "727099ba7ad6e2c26b0a113dfd5196f0996bc88a716708fac3f481759fbaffa2", + "6e335f837a60b4bfd31305a363beb04624937d4987ebf76916d82fd3d96d6b7a", + "7517f9c37605c3ee8a909b12a40fdf06ce3af94b0e61e8d48436ca170959a836", + "d1a81a00a5edcd694968e8636c41b056a966a2f8cf1748592a88ba48ad32f7c2", + "65e4f212471d99b22accc6ac61b3ada340e004513418e5780303e8685d4bda17", + "4e41a6934047f8bba8bbe1d3974695b5571e239d1cd4c63ae1a8a4cb773c4e89", + "1a20648f73e4e5694f06880fa6cc328b69a3c856dc1ce3bb5e5a4732dbb90a7b", + "df3534252db316eb81eefd4b94c39e143dc580679fd1a31a3c89f4ea045dcc83", + "814f544a4e819b803de84cf0cc9bf56c49a9185aa166dfffd5b40e7ec980615f", + "0c6f68316c2a49813a4606182e2a018ffdc1e8ade3f70f5f4ae16cf519ef01f5", + "2731cb55d58fd2ca1884c16530654b09d8dacf3e7e27bea1b338b761de1a2d92", + "f8a194a92d2602ea287f9ca9aab6a49c40527295973467e9b1fe4bc3c9df4090", + "37eb1040a0777538eea389320620e610450b5c2cff0041bd467a81270a23ab31", + "9f3e7e8b21092d81fb0cd0164e6743afde5ffe8a937833aa8fd8debd01a3822b", + "a43586387a8fd76c126639e23ea87645f6ff4f31b8f0e361be934b79dba93092", + "38cdc514ad5d1484fb2c8bda5f9e7b8fba7174d89b93147de4164bb7d6fe79b0", + "ace1202baa79c373637cbc372de5833a7bf4a14d84e2fe9367bbc687cc523d80", + "a708b4e78244446cb57f3e71b61d843d98ae8b384cdcfa4bf80078951bef046d", + "ab5bc0c26a3550089792357860d7f510a330ffc00d8eba327bcb3f305d92cd25", + "683acd61be317cede9a7a122a921f79362db3eddf73db72d35a9b31274d96cbe", + "8bc2432339449ea6c8a3743f3eea2ca115896e9f7b10dab016586959550e1b48", + "ebd4876dc332ef045cd305e6e935315f0a11c88dedc52f70a856ed08d99868f0", + "deb3180dd15fd9277f530faa48ebc121d52d4d754213124a4821dd4e915ba1b2", + "904f3c620b43ca54c8e1dab4ab4328305878299f214700e7902ca255522f97b2", + "b79589d8c1e8cca551d30a8fc5b387b98a51b96549b563e7ab872c3eab812e99", + "9093192a76d21518b456ea9dd48ed8321c5315c0d3c582e6bb6fc29b32da2694", + "4230a89bd141a306559ccde1a675aaf2d0300d4e89d047a829a92d2d1e60c6ea", + "a6a3a32a9b4ca9a189a22b1c14d25a4e33aef6dd562cea9daacf36614341e607", + "7747eb8949514a5c1ef27c3cfa7af6cce15e0a36ff07fe0f3dd560b8cb4c9403", + "3db22aee10130256b8e5685cde0ec230e2dc1e516968343987c48b856eca849b", + "5d2035ac57e2627ef035547eecd8094fbcd5885d71c70bf82172f2ec99e635de", + "11d02ad7dc1063c2fa6883c0c798c43867be5af6757f9681942977d9cbe56b52", + "6cdf85d4b2b3660d39e07f17c6a5a47d4fb4b2cdb9c909d7e38ea52df41173d0", + "7dd12374a638f8444dbfbf726242dc8bd546a40a731e9773b4ddbdaa5e059509", + "b02a7ea348d0b06296d274d8199a32ac8b9dd436b92d9fbbb9563821ac7056f3", + "d2e9c0c2616830dec1a52078ea9a093760565536ce51517de7a03ea4c05ee2c2", + "93c1c707cef116303a6697c1ff9fe3c357d4ee24a86f622e915713853624cd47", + "e89b6f2e0facdd3d03d44c79b54d41998b2fa00bad3d1d75b46b650a784c9b2d", + "31e2b80df0cb250df716e50376ec0e4c4fff8a076906ef3891c6dfe054909dd8", + "44790c2c63a4b4472b031e098523e2cbf41602e55e9303121d8043079124c0da", + "8250d0aaa52caab332f001239e84bfd4c0200bbbad07f2a0c5a4fbfc306dfa9e", + "efa2fe2e4d311bae74c8dbe10f8da1d301984bcace14757f6713ec299d2a6eb4", + "1e6333861fbdf74bdd03ccf154972fc526e9b934a4c935d36dc70b97c26270b6", + "6e2d86f6870c3cd285570964504c315d1d01c4b6f5d6de8b942a20758cb824cc", + "98e458d221e5f5823e1e08ae8dee3e91126ee9f311eff0a779a095bbfabd7d2f", + "ad28cd6db15e81e81ac0a36d6a48b386580b356f98f9d0fdef9de5524409804c", + "0ed848227c916249b0baafb1589976922b287266a1bccaf8dc76b3548db02119", + "fdcf864ad6103525735a830682f393b96f3d63a2871ed10930ce9bf7f4176754", + "78331d664ac587bebadc23f6f0aeda8ce055b6750de36b98e5e7eee543c64999", + "5ddb0654fe454d12fa471c9c79c9398a77335210639d54b256142810b0e850ee", + "2269aae13efe5d788c7f35d58acc0164f8fa90d57978de19f063200bb2bc8d6f", + "2354a46e2cea77d3eeaeaeeb52607bce110ab21f0ed661e8f0fbd0fe71364baa", + "05f8d7fb768495972be56780a986d43ff0c2bde29e4612f2ab05704e839cbf95", + "79ddf22346d66f6ed18caf0f0296b8e6dfbcad5d0ba3bcbfb7d55fb873d67975", + "1664979111ec81092ac72175e799fe0a452c481e6cd09d91785639eb030771c6", + "a0fa136650517e38dc25bdca6b8acc3322d5befe731bdad56d5bf57bbe278dd9", + "92ab2ca557870791498267d4d8b4cda2b683e3adb5c7693f5ef4069bb5675618", + "a5cc1a2c482279690e6da556486fb79089186d3107d94d933194c6228398a1fd", + "ca161c142f2248459352417a69acca26fb814bd09b5282d9cb12d706619cb899", + "65ddaa2b7de4a9f50b1134dfe0e744b378fe49779f0539e24bda86735e14df32", + "97b13d7b144f22936d799a4e9c698879ba0fe5394b0a58de157354a320b9b521", + "5d8d9ae27913631e230c49245478c3a8deb0e1b03a47605994131c49fb595533", + "ef746d1ac55c5e9b7fe458e5141748c4dd556e20f62b5c32e0435d85d74baea1", + "50cf0fd79dc46c0ffaf2609b66051036c1bd0e599d5e5951fd181e27000b456f", + "7da7d60c09fdf86d53f34a3bea561ef3b1367fd87019445dfb42b15a01120cdf", + "667ab7c22364bcbf50c00f0537c40c5b65bea54ba93af438e449324a9db0ab0e", + "9434f9cfd83261dabb51e054ae5b27a817ff1ea5d6f44e63c82f4138d5f8d058", + "1043801490317d841755f98005bebdd914f52732721b4519f9db8a2f8b3e5186", + "edc2894dee8c5750161a54068f88c6968a22e7bce51eee17de9e0b70715c7ab2", + "bbe971624c3d4bbbcec3390dc04cfe64793ba189d45dca21ffb78a129259d3c6", + "e0db1031953e78d4b1d5f0552f2e5e1530f57fbea94aa0c71b13365bc6e30ace", + "b0689228ff36a4d855476b915f0ea2cf21f3ed83c902ec2255bbe531531659d0", + "5152580943a30b945999446352a8f23ba015accb1357d4112cf981bfc0b6a9d1", + "a0163c3f15eebde24edaf2b78c394145444636b3b260e346f0ceb55f75786612", + "cf8442ad3f9972a99d6ad1326ca6e95a567088cde46c18c2f963ec70e6ef44e8", + "7813093a0ac633dc0a991955bf647b2868e674ea38ea88e95719072c31e08e78", + "420ce43f5fa4a23d6e432eb226158f972491e8d418e46de1706a64e61b0ff246", + "88d869aa62716683d5163770bf1ade608e3edc02a95b0dc1b047e53cda2950f6", + "12f637f48df38b19e0450a348e022b66405fe2ec5e6d6a0aae5a47453decf866", + "57f511a6da9ed973815ad402584ae3f3de14a790bbc59dcdd0d3e24d2d27258f", + "ccb99254e889c9d94ac50cce320a7746ad1ca9dda9acb8616c601ecae7a78b02", + "b5bd7fecbb1d006bbb18a32a5945939c63bf8f5e405178f2b82d721637ba0752", + "daa2411aec55a4d653c41a1d8d9605f91c9d76dd648ade9cba98cbd967abfd36", + "3069cc2eabe421a8dd21157d419fd439c4f5a87561fc5081220e42509279fd05", + "57cdb302e589c5950c6c2333998ce92f1e3d1482be22a68b962f742d87eef59d", + "dc035a7feffb43f7a3a17220f203851e77cec963b09cdf65c5f9204d56f2755e", + "19a5792d05d9088e8e32c89c1b9424f54ff948252f88960bb540ad2a78f9c1e1", + "8859b4ce52fb687cf101c75f586d9951a184452353df8b8af5804267cbc6116f", + "9f11f793bf51d66d0b8d5a2b733b17fc9fa64a7e4dab4cbc09a7fefaddce9c41", + "61cb64aee5e2afb4289ff08ea5391769d0139da805d792e393c78ac23cd0d7cb", + "3bc5a6843955487707ee14c1db5e98ebd519e9e9e9754e541c9996aff9f2675c", + "4bf103e9061666b11d926e82b7020d3768d58aa939efd381b20f2528d106e5bd", + "9615202aa136b86ff3330d3317882691123912503773d964d9ba5935a7c1482d", + "8351dc3efbea94176be9b4d868a49b897bd4a5927a3840d64ac8bcc2a88ddbe1", + "956c1680f47c856ed2cc73705f0832b36433dde6db00d119d6506b9f089098fe", + "7e1b6b77edace4c4d6dbae8111a0bede9404932797c8d862246ffcba1b513457", + "78290ae7c2215751b0549565730d9c7b20cfdda95665b70704c818a8dcc7ee13", + "2fdaac59d9e38c025481ffb850b01304fdd50b5187cc673c45cd7169f65c26fd", + "545804a11f9384c8307d545e6d138de763741bb2d580ca4768b2293bd27617d6", + "e0bdbd8e5c26fa04ccb8e5525981af6a4056b72b18a2740d4a2d06b6699df8e9", + "74e9fd0ebfce5a32e27e4955dfb4d6daa3aa856be320d0e01b8b14fb5c33db0d", + "1900153f6ccb5dc8125838d7afd5ab81a8d1095fb475819ee77af435cbb2b62c", + "a1e21310c242a28fd901d02a5c80ae609f7426cd20e12bbaa3d4b92e7c2d40c6", + "7d7f886e106d73ae46cd9ad7a2619fc3ab183dcfaf07df6ffa352fc8f6a78de2", + "8998370156cd33ddc405e0c20c6804dd2d3c3efaad3995dc9e126aba58a7b248", + "5754639b298a325cca30400da827289bd052023641ca1c1523115449b05ed455", + "f206a77ac80146e5cce97ee19653ba97eb8fcee9a09a4112b6e1432ad7119193", + "0a628a54edf538c336e19e6b3bd5d6066855d8d8bf4005b6511bdd3798d6b1e2", + "f5f34b4b8488f7518dbb8a377d5b3c34c945e0fa02f182df38da913e41fc56f3", + "ce4880373b03df304985ac4a3d352539bbe6f42c68984fef9c1c3453e1b328aa", + "1e9d3e132a700411487ae83639f741bfd0980f9e315606f8a585edab7dd26617", + "dc2e514516e957cfc39d3e01bc3c0b57de4184d0c92d738f76b477dee0577c55", + "2d537b2b10ab7105312a1d1d61731d5cb0c986416447a835190c9c2765d52b43", + "f5e3ac6101d2d51820aafef9f1a45d938d53ae09f60df3c6b26df277860c90a4", + "ff1d01e6cb0d01aaedb873fa5fd3af20af424fdc9a442f68bb72cc7b96e149ea", + "d3fb4890d3eee8e115122628b7ec3c815ffd8ac3dad0ef1b9110d12cdc9e69da", + "0304cf1502acb945f075b44068d3424222d18b75a99ab14d0916cb22a8aea706", + "1181bcb084876a0250f920ed598cd7305720bdca5e9ca32f72c377d529205779", + "506bfbae8d9496e3cb438a7428e4455fb87ef34d126008f0763371d301370a86", + "e5b5c4ef4b4764cae7b6746764f91ba4923635d345d53cb2328b8cde60e045f4", + "49e23100f67654423813059a69a8d9a2fdfab037d1005305d8b6e4600c9eaab7", + "4d0ebb2f80f37870dfc7a817a9cb23cb962878c1ceff3653d34b2f617e854269", + "389f32e0e5a0a9b46a37da99be4576436d6dd4f23fde196f44119ee15e79b49b", + "c5ae9f7e0aa75727161e3c06542631796e13c8f59ec4cf19814031c05ce30c2e", + "3cc61d22b6cee76b063bb7562b1d4536a17b88e50e750f59a26bad5d6d287dec", } -const ropstenPreverifiedHeight uint64 = 11880768 +const ropstenPreverifiedHeight uint64 = 11908800 From 6a141ec43bd8b53325c50952b60199954457d893 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Thu, 3 Feb 2022 12:38:20 +0000 Subject: [PATCH 148/261] Update version.go (#3414) --- params/version.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/params/version.go b/params/version.go index 23d080ccfaa..e760cabc8a7 100644 --- a/params/version.go +++ b/params/version.go @@ -32,8 +32,8 @@ var ( // see https://calver.org const ( VersionMajor = 2022 // Major version component of the current release - VersionMinor = 1 // Minor version component of the current release - VersionMicro = 3 // Patch version component of the current release + VersionMinor = 2 // Minor version component of the current release + VersionMicro = 1 // Patch version component of the current release VersionModifier = "beta" // Patch version component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" From 9a46788de0d565c6ff7eabde14c64d386ec98998 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Thu, 3 Feb 2022 18:55:59 +0000 Subject: [PATCH 149/261] [stable] Fix txpool memory leak (#3419) Co-authored-by: Alexey Sharp --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 4ccff3827ee..c2486eb5cfc 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20220202093315-e3f672e28f76 + github.com/ledgerwatch/erigon-lib v0.0.0-20220203181034-d49d18ddaf17 github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 diff --git a/go.sum b/go.sum index a64c18fa51a..5e569290826 100644 --- a/go.sum +++ b/go.sum @@ -499,8 +499,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20220202093315-e3f672e28f76 h1:3wt4XnLRkQmfiKrxV9pvKcy72eDwEcCblyKkbo2eryQ= -github.com/ledgerwatch/erigon-lib v0.0.0-20220202093315-e3f672e28f76/go.mod h1:BQNYmN6i8RdHqedsztAj3XDnswYebacmFAnsznlisTc= +github.com/ledgerwatch/erigon-lib v0.0.0-20220203181034-d49d18ddaf17 h1:1WOGytdl1036LxxMLcQp53I+coKrSH0oFkE0NJqamGA= +github.com/ledgerwatch/erigon-lib v0.0.0-20220203181034-d49d18ddaf17/go.mod h1:BQNYmN6i8RdHqedsztAj3XDnswYebacmFAnsznlisTc= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= From 3824fdf26a63e738a76e8c3fa342cf45f3aafe4e Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Fri, 4 Feb 2022 21:57:28 +0700 Subject: [PATCH 150/261] close nodes db on server start error (#3424) (#3425) --- cmd/sentry/download/downloader.go | 2 ++ cmd/sentry/download/sentry.go | 1 + p2p/enode/nodedb.go | 3 +-- p2p/server.go | 6 ++++++ 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/cmd/sentry/download/downloader.go b/cmd/sentry/download/downloader.go index b534169fd5e..dbc318c2c35 100644 --- a/cmd/sentry/download/downloader.go +++ b/cmd/sentry/download/downloader.go @@ -235,6 +235,7 @@ func RecvMessageLoop(ctx context.Context, continue } log.Warn("[RecvMessage] sentry not ready yet", "err", err) + time.Sleep(time.Second) continue } if err := SentrySetStatus(ctx, sentry, cs); err != nil { @@ -243,6 +244,7 @@ func RecvMessageLoop(ctx context.Context, time.Sleep(time.Second) continue } + time.Sleep(time.Second) log.Warn("[RecvMessage] sentry not ready yet", "err", err) continue } diff --git a/cmd/sentry/download/sentry.go b/cmd/sentry/download/sentry.go index fca513d3212..eb091be6615 100644 --- a/cmd/sentry/download/sentry.go +++ b/cmd/sentry/download/sentry.go @@ -865,6 +865,7 @@ func (ss *SentryServerImpl) SetStatus(_ context.Context, statusData *proto_sentr // Add protocol if err = srv.Start(); err != nil { + srv.Stop() return reply, fmt.Errorf("could not start server: %w", err) } diff --git a/p2p/enode/nodedb.go b/p2p/enode/nodedb.go index 01bd7bc5497..fb4c088f0fb 100644 --- a/p2p/enode/nodedb.go +++ b/p2p/enode/nodedb.go @@ -28,9 +28,8 @@ import ( "sync" "time" - "github.com/google/btree" - "github.com/c2h5oh/datasize" + "github.com/google/btree" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv/mdbx" diff --git a/p2p/server.go b/p2p/server.go index a8c07527391..face5e4d73c 100644 --- a/p2p/server.go +++ b/p2p/server.go @@ -400,6 +400,9 @@ func (srv *Server) Self() *enode.Node { func (srv *Server) Stop() { srv.lock.Lock() if !srv.running { + if srv.nodedb != nil { + srv.nodedb.Close() + } srv.lock.Unlock() return } @@ -409,6 +412,9 @@ func (srv *Server) Stop() { // this unblocks listener Accept srv.listener.Close() } + if srv.nodedb != nil { + srv.nodedb.Close() + } srv.lock.Unlock() srv.loopWG.Wait() } From 42eee1740eb3c8bddf62546a1104c3a3605730f1 Mon Sep 17 00:00:00 2001 From: primal_concrete_sledge Date: Tue, 8 Feb 2022 19:25:03 +0300 Subject: [PATCH 151/261] Cherrypick/parity list (#3447) * Cherry pick devnettest * fix/add_4th_parameter_to_parity_list (#3443) * fix/add_4th_parameter_to_parity_list * Change blocknum type from interface{} to rpc.BlockNumberOrHash * Change latest block check --- DEV_CHAIN.md | 144 +++++++++++++++++++ cmd/devnettest/commands/account.go | 46 ++++++ cmd/devnettest/commands/block.go | 55 +++++++ cmd/devnettest/commands/parity.go | 38 +++++ cmd/devnettest/commands/root.go | 36 +++++ cmd/devnettest/commands/tx.go | 21 +++ cmd/devnettest/main.go | 7 + cmd/devnettest/requests/request_generator.go | 79 ++++++++++ cmd/devnettest/requests/requests.go | 80 +++++++++++ cmd/devnettest/requests/utils.go | 29 ++++ cmd/rpcdaemon/commands/parity_api.go | 21 ++- cmd/rpcdaemon/commands/parity_api_test.go | 13 +- cmd/rpctest/rpctest/type.go | 16 +++ 13 files changed, 578 insertions(+), 7 deletions(-) create mode 100644 DEV_CHAIN.md create mode 100644 cmd/devnettest/commands/account.go create mode 100644 cmd/devnettest/commands/block.go create mode 100644 cmd/devnettest/commands/parity.go create mode 100644 cmd/devnettest/commands/root.go create mode 100644 cmd/devnettest/commands/tx.go create mode 100644 cmd/devnettest/main.go create mode 100644 cmd/devnettest/requests/request_generator.go create mode 100644 cmd/devnettest/requests/requests.go create mode 100644 cmd/devnettest/requests/utils.go diff --git a/DEV_CHAIN.md b/DEV_CHAIN.md new file mode 100644 index 00000000000..d3510aea3df --- /dev/null +++ b/DEV_CHAIN.md @@ -0,0 +1,144 @@ +Steps to setup and run Erigon dev chain. This tutorial is made for macOS. + + +## 1. Clone and Build Erigon +Open terminal 1 and type the following command + +```bash +git clone --recurse-submodules -j8 https://github.com/ledgerwatch/erigon.git +cd erigon +make erigon +``` + + +## 2. Build RPCdeamon +On the same terminal folder you can build the RPC daemon. + +```bash +make rpcdaemon +``` + +## 3. Start Node 1 +If evereything is fine, by changing directory to erigon/build/bin you will see the two exec for erigon and rpc daemon. +On the terminal you can type the following command to start node1. + +```bash +./erigon --datadir=dev --chain dev --private.api.addr=localhost:9090 --mine +``` + + Argument notes: + * datadir : Tells where the data is stored, default level is dev folder. + * chain : Tells that we want to run Erigon in the dev chain. + * private.api.addr=localhost:9090 : Tells where Eigon is going to listen for connections. + * mine : Add this if you want the node to mine. + * dev.period : Add this to specify the timing interval amongst blocks. Number of seconds MUST be > 0 (if you want empty blocks) otherwise the default value 0 does not allow mining of empty blocks. + +The result will be somenthing like this: + +Node 1 start + + +Now save the enode information generated in the logs, we will use this in a minute. Here there is an example. +``` +enode://d30d079163d7b69fcb261c0538c0c3faba4fb4429652970e60fa25deb02a789b4811e98b468726ba0be63b9dc925a019f433177eb6b45c23bb78892f786d8f7a@127.0.0.1:53171 +``` + +## 4. Start RPC deamon + +Open terminal 2 and navigate to erigon/build/bin folder. Here type the following command + +```bash +./rpcdaemon --datadir=dev --private.api.addr=localhost:9090 --http.api=eth,erigon,web3,net,debug,trace,txpool,parity +``` +The result will look like this: +rpc daemon start + + + +## 5. Start Node 2 + +Node 2 has to connect to Node 1 in order to sync. As such, we will use the argument --staticpeers. +To tell Node 2 where Node 1 is we will use the Enode info of Node 1 we saved before. + +Open terminal 3 and navigate to erigon/build/bin folder. Paste in the following command the Enode info and run it, be careful to remove the last part ?discport=0. + +```bash +./erigon --datadir=dev2 --chain dev --private.api.addr=localhost:9091 \ + --staticpeers "enode://d30d079163d7b69fcb261c0538c0c3faba4fb4429652970e60fa25deb02a789b4811e98b468726ba0be63b9dc925a019f433177eb6b45c23bb78892f786d8f7a@127.0.0.1:53171" \ + --nodiscover +``` + +To check if the nodes are connected, you can go to the log of both the nodes and look for the line + + ``` [p2p] GoodPeers eth66=1 ``` + +Note: this might take a while it is not istantaneus, also if you see a 1 on either one of the two the node is fine. + + + + + +## 6. Interact with the node using RPC + + Open a terminal 4 and type + +```bash + curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc": "2.0", "method": "eth_chainId", "params": [], "id":1}' localhost:8545 + +``` + The result should look like this: + +```json +{"jsonrpc":"2.0","id":1,"result":"0x539"} +``` + +Other commands you can try: + + ```bash + curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc": "2.0", "method": "eth_gasPrice", "params": [], "id":1}' localhost:8545 + ``` + ```bash + curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc": "2.0", "method": "eth_mining", "params": [], "id":1}' localhost:8545 + ``` + ```bash + curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc": "2.0", "method": "eth_syncing", "params": [], "id":1}' localhost:8545 + ``` + ```bash + curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc": "2.0", "method": "net_peerCount", "params": [], "id":74}' localhost:8545 + ``` + ```bash + curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc": "2.0", "method": "eth_blockNumber", "params": [], "id":83}' localhost:8545 + ``` + +## 7. Send a transaction with metamask + + Finally, we want to try sending a transaction between two accounts. + For this example we will use dev accounts retrived from Erigon code: + + * Account with balance (Dev 1) + * address = ``` 0x67b1d87101671b127f5f8714789C7192f7ad340e ``` + * privateKey = ``` 26e86e45f6fc45ec6e2ecd128cec80fa1d1505e5507dcd2ae58c3130a7a97b48 ``` + + * Empty account (Dev 2) + * address = ``` 0xa94f5374Fce5edBC8E2a8697C15331677e6EbF0B ``` + * privateKey = ``` 45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8 ``` + + + +Now from metamask, you can import Dev 1 , and then send a transaction to pass some ethers from Dev 1 to Dev 2. +From the RPC daemon terminal, you will see something like this + +Transaction example + + Finally you will see the ethers in the Dev 2 account balance. + + + + ## 7. Check a mined block + + Now we want to check the creation of a new block and that all the nodes sync. + +Below we can see that block 1 is created (blocn_num=1) and that the next block to be proposed increments from 1 to 2 ( block=2). The other nodes will see the same update. + +Block + diff --git a/cmd/devnettest/commands/account.go b/cmd/devnettest/commands/account.go new file mode 100644 index 00000000000..932bc7b9a6d --- /dev/null +++ b/cmd/devnettest/commands/account.go @@ -0,0 +1,46 @@ +package commands + +import ( + "fmt" + + "github.com/ledgerwatch/erigon/cmd/devnettest/requests" + "github.com/ledgerwatch/erigon/common" + "github.com/spf13/cobra" +) + +var ( + addr string + blockNum string +) + +func init() { + getBalanceCmd.Flags().StringVar(&addr, "addr", "", "String address to check") + getBalanceCmd.MarkFlagRequired("addr") + getBalanceCmd.Flags().StringVar(&blockNum, "block-num", "latest", "String denoting block number") + + rootCmd.AddCommand(getBalanceCmd) +} + +var getBalanceCmd = &cobra.Command{ + Use: "get-balance", + Short: "Checks balance by address", + Args: func(cmd *cobra.Command, args []string) error { + var err error + switch blockNum { + case "pending", "latest", "earliest": + default: + err = fmt.Errorf("block number must be 'pending', 'latest' or 'earliest'") + } + if err != nil { + return err + } + return nil + }, + Run: func(cmd *cobra.Command, args []string) { + if clearDev { + defer clearDevDB() + } + toAddress := common.HexToAddress(addr) + requests.GetBalance(reqId, toAddress, blockNum) + }, +} diff --git a/cmd/devnettest/commands/block.go b/cmd/devnettest/commands/block.go new file mode 100644 index 00000000000..31382ecf80d --- /dev/null +++ b/cmd/devnettest/commands/block.go @@ -0,0 +1,55 @@ +package commands + +import ( + "fmt" + + "github.com/holiman/uint256" + "github.com/ledgerwatch/erigon/cmd/devnettest/requests" + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/crypto" + "github.com/ledgerwatch/erigon/params" + "github.com/spf13/cobra" +) + +var devnetSignPrivateKey, _ = crypto.HexToECDSA("26e86e45f6fc45ec6e2ecd128cec80fa1d1505e5507dcd2ae58c3130a7a97b48") + +var ( + sendAddr string + sendValue uint64 + nonce uint64 +) + +const ( + gasPrice = 50000 +) + +func init() { + sendTxCmd.Flags().StringVar(&sendAddr, "addr", "", "String address to send to") + sendTxCmd.MarkFlagRequired("addr") + sendTxCmd.Flags().Uint64Var(&sendValue, "value", 0, "Uint64 Value to send") + sendTxCmd.Flags().Uint64Var(&nonce, "nonce", 0, "Uint64 nonce") + + rootCmd.AddCommand(sendTxCmd) +} + +var sendTxCmd = &cobra.Command{ + Use: "send-tx", + Short: "Sends a transaction", + Args: func(cmd *cobra.Command, args []string) error { + if sendValue == 0 { + return fmt.Errorf("value must be > 0") + } + return nil + }, + Run: func(cmd *cobra.Command, args []string) { + if clearDev { + defer clearDevDB() + } + toAddress := common.HexToAddress(sendAddr) + signer := types.LatestSigner(params.AllCliqueProtocolChanges) + signedTx, _ := types.SignTx(types.NewTransaction(nonce, toAddress, uint256.NewInt(sendValue), + params.TxGas, uint256.NewInt(gasPrice), nil), *signer, devnetSignPrivateKey) + requests.SendTx(reqId, &signedTx) + }, +} diff --git a/cmd/devnettest/commands/parity.go b/cmd/devnettest/commands/parity.go new file mode 100644 index 00000000000..ef7b61b20ca --- /dev/null +++ b/cmd/devnettest/commands/parity.go @@ -0,0 +1,38 @@ +package commands + +import ( + "strings" + + "github.com/ledgerwatch/erigon/cmd/devnettest/requests" + "github.com/ledgerwatch/erigon/common" + "github.com/spf13/cobra" +) + +var ( + offsetAddr string + quantity int +) + +func init() { + listStorageKeysCmd.Flags().StringVar(&addr, "addr", "", "String address to list keys") + listStorageKeysCmd.MarkFlagRequired("addr") + listStorageKeysCmd.Flags().StringVar(&offsetAddr, "offset", "", "Offset storage key from which the batch should start") + listStorageKeysCmd.Flags().IntVar(&quantity, "quantity", 10, "Integer number of addresses to display in a batch") + listStorageKeysCmd.Flags().StringVar(&blockNum, "block", "latest", "Integer block number, or the string 'latest', 'earliest' or 'pending'; now only 'latest' is available") + + rootCmd.AddCommand(listStorageKeysCmd) +} + +var listStorageKeysCmd = &cobra.Command{ + Use: "parity-list", + Short: "Returns all storage keys of the given address", + RunE: func(cmd *cobra.Command, args []string) error { + if clearDev { + defer clearDevDB() + } + toAddress := common.HexToAddress(addr) + offset := common.Hex2Bytes(strings.TrimSuffix(offsetAddr, "0x")) + requests.ParityList(reqId, toAddress, quantity, offset, blockNum) + return nil + }, +} diff --git a/cmd/devnettest/commands/root.go b/cmd/devnettest/commands/root.go new file mode 100644 index 00000000000..d0113d906af --- /dev/null +++ b/cmd/devnettest/commands/root.go @@ -0,0 +1,36 @@ +package commands + +import ( + "fmt" + + "github.com/spf13/cobra" +) + +var ( + clearDev bool + reqId int +) + +func init() { + rootCmd.PersistentFlags().BoolVar(&clearDev, "clear-dev", false, "Determines if service should clear /dev after this call") + rootCmd.PersistentFlags().IntVar(&reqId, "req-id", 0, "Defines number of request id") +} + +var rootCmd = &cobra.Command{ + Use: "devnettest", + Short: "Devnettest root command", +} + +// Execute executes the root command. +func Execute() error { + return rootCmd.Execute() +} + +func clearDevDB() { + fmt.Printf("Clearing ~/dev\n") + // + //_, err := exec.Command("rm", "-rf", "~/dev", "~/dev2").Output() + //if err != nil { + // fmt.Println(err) + //} +} diff --git a/cmd/devnettest/commands/tx.go b/cmd/devnettest/commands/tx.go new file mode 100644 index 00000000000..bd27b6dfe92 --- /dev/null +++ b/cmd/devnettest/commands/tx.go @@ -0,0 +1,21 @@ +package commands + +import ( + "github.com/ledgerwatch/erigon/cmd/devnettest/requests" + "github.com/spf13/cobra" +) + +func init() { + rootCmd.AddCommand(txPoolCmd) +} + +var txPoolCmd = &cobra.Command{ + Use: "txpool-content", + Short: "Gets content of txpool", + Run: func(cmd *cobra.Command, args []string) { + if clearDev { + defer clearDevDB() + } + requests.TxpoolContent(reqId) + }, +} diff --git a/cmd/devnettest/main.go b/cmd/devnettest/main.go new file mode 100644 index 00000000000..04ad7055674 --- /dev/null +++ b/cmd/devnettest/main.go @@ -0,0 +1,7 @@ +package main + +import "github.com/ledgerwatch/erigon/cmd/devnettest/commands" + +func main() { + commands.Execute() +} diff --git a/cmd/devnettest/requests/request_generator.go b/cmd/devnettest/requests/request_generator.go new file mode 100644 index 00000000000..7138c223dc7 --- /dev/null +++ b/cmd/devnettest/requests/request_generator.go @@ -0,0 +1,79 @@ +package requests + +import ( + "fmt" + "net/http" + "time" + + "github.com/ledgerwatch/erigon/cmd/rpctest/rpctest" + "github.com/ledgerwatch/erigon/common" +) + +var ( + erigonUrl = "http://localhost:8545" +) + +type RequestGenerator struct { + reqID int + client *http.Client +} + +func initialiseRequestGenerator(reqId int) *RequestGenerator { + var client = &http.Client{ + Timeout: time.Second * 600, + } + + reqGen := RequestGenerator{ + client: client, + reqID: reqId, + } + if reqGen.reqID == 0 { + reqGen.reqID++ + } + + return &reqGen +} + +func (req *RequestGenerator) Erigon(method, body string, response interface{}) rpctest.CallResult { + return req.call(erigonUrl, method, body, response) +} + +func (req *RequestGenerator) call(target string, method, body string, response interface{}) rpctest.CallResult { + start := time.Now() + err := post(req.client, erigonUrl, body, response) + return rpctest.CallResult{ + RequestBody: body, + Target: target, + Took: time.Since(start), + RequestID: req.reqID, + Method: method, + Err: err, + } +} + +func (req *RequestGenerator) getBalance(address common.Address, blockNum string) string { + const template = `{"jsonrpc":"2.0","method":"eth_getBalance","params":["0x%x","%v"],"id":%d}` + return fmt.Sprintf(template, address, blockNum, req.reqID) +} + +func (req *RequestGenerator) sendRawTransaction(signedTx []byte) string { + const template = `{"jsonrpc":"2.0","method":"eth_sendRawTransaction","params":["0x%x"],"id":%d}` + return fmt.Sprintf(template, signedTx, req.reqID) +} + +func (req *RequestGenerator) txpoolContent() string { + const template = `{"jsonrpc":"2.0","method":"txpool_content","params":[],"id":%d}` + return fmt.Sprintf(template, req.reqID) +} + +func (req *RequestGenerator) parityStorageKeyListContent(address common.Address, quantity int, offset []byte, blockNum string) string { + const template = `{"jsonrpc":"2.0","method":"parity_listStorageKeys","params":["0x%x", %d, %v, "%s"],"id":%d}` + var offsetString string + if len(offset) != 0 { + offsetString = fmt.Sprintf(`"0x%x"`, offset) + } else { + offsetString = "null" + } + + return fmt.Sprintf(template, address, quantity, offsetString, blockNum, req.reqID) +} diff --git a/cmd/devnettest/requests/requests.go b/cmd/devnettest/requests/requests.go new file mode 100644 index 00000000000..eb679505adc --- /dev/null +++ b/cmd/devnettest/requests/requests.go @@ -0,0 +1,80 @@ +package requests + +import ( + "bytes" + "encoding/json" + "fmt" + + "github.com/ledgerwatch/erigon/cmd/rpctest/rpctest" + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/core/types" +) + +func parseResponse(resp interface{}) string { + result, err := json.Marshal(resp) + if err != nil { + panic(err) + } + + return string(result) +} + +func GetBalance(reqId int, address common.Address, blockNum string) { + reqGen := initialiseRequestGenerator(reqId) + var b rpctest.EthBalance + + res := reqGen.Erigon("eth_getBalance", reqGen.getBalance(address, blockNum), &b) + if res.Err != nil { + fmt.Printf("Error getting balance: %v\n", res.Err) + return + } + + fmt.Printf("Balance retrieved: %v\n", parseResponse(b)) +} + +func SendTx(reqId int, signedTx *types.Transaction) { + reqGen := initialiseRequestGenerator(reqId) + var b rpctest.EthSendRawTransaction + + var buf bytes.Buffer + err := (*signedTx).MarshalBinary(&buf) + if err != nil { + fmt.Printf("Error trying to marshal binary: %v\n", err) + return + } + + res := reqGen.Erigon("eth_sendRawTransaction", reqGen.sendRawTransaction(buf.Bytes()), &b) + if res.Err != nil { + fmt.Printf("Error sending transaction: %v\n", res.Err) + return + } + + fmt.Printf("Submitted transaction successfully: %v\n", parseResponse(b)) +} + +func TxpoolContent(reqId int) { + reqGen := initialiseRequestGenerator(reqId) + var b rpctest.EthTxPool + + res := reqGen.Erigon("txpool_content", reqGen.txpoolContent(), &b) + if res.Err != nil { + fmt.Printf("Error fetching txpool: %v\n", res.Err) + return + } + + fmt.Printf("Txpool content: %v\n", parseResponse(b)) +} + +func ParityList(reqId int, account common.Address, quantity int, offset []byte, blockNum string) { + reqGen := initialiseRequestGenerator(reqId) + var b rpctest.ParityListStorageKeysResult + + res := reqGen.Erigon("parity_listStorageKeys", reqGen.parityStorageKeyListContent(account, quantity, offset, blockNum), &b) + if res.Err != nil { + fmt.Printf("Error fetching storage keys: %v\n", res.Err) + return + } + + fmt.Printf("Storage keys: %v\n", parseResponse(b)) + +} diff --git a/cmd/devnettest/requests/utils.go b/cmd/devnettest/requests/utils.go new file mode 100644 index 00000000000..46c50545789 --- /dev/null +++ b/cmd/devnettest/requests/utils.go @@ -0,0 +1,29 @@ +package requests + +import ( + "encoding/json" + "fmt" + "net/http" + "strings" + "time" + + "github.com/ledgerwatch/log/v3" +) + +func post(client *http.Client, url, request string, response interface{}) error { + fmt.Printf("Request=%s\n", request) + log.Info("Getting", "url", url, "request", request) + start := time.Now() + r, err := client.Post(url, "application/json", strings.NewReader(request)) + if err != nil { + return err + } + defer r.Body.Close() + if r.StatusCode != 200 { + return fmt.Errorf("status %s", r.Status) + } + decoder := json.NewDecoder(r.Body) + err = decoder.Decode(response) + log.Info("Got in", "time", time.Since(start).Seconds()) + return err +} diff --git a/cmd/rpcdaemon/commands/parity_api.go b/cmd/rpcdaemon/commands/parity_api.go index 443593acbf2..5e6d7bac23b 100644 --- a/cmd/rpcdaemon/commands/parity_api.go +++ b/cmd/rpcdaemon/commands/parity_api.go @@ -9,11 +9,16 @@ import ( "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/core/state" + "github.com/ledgerwatch/erigon/rpc" ) +var latestTag = common.BytesToHash([]byte("latest")) + +var ErrWrongTag = fmt.Errorf("listStorageKeys wrong block tag or number: must be '%s' ('latest')", latestTag) + // ParityAPI the interface for the parity_ RPC commands type ParityAPI interface { - ListStorageKeys(ctx context.Context, account common.Address, quantity int, offset *hexutil.Bytes) ([]hexutil.Bytes, error) + ListStorageKeys(ctx context.Context, account common.Address, quantity int, offset *hexutil.Bytes, blockNumber rpc.BlockNumberOrHash) ([]hexutil.Bytes, error) } // ParityAPIImpl data structure to store things needed for parity_ commands @@ -29,7 +34,11 @@ func NewParityAPIImpl(db kv.RoDB) *ParityAPIImpl { } // ListStorageKeys implements parity_listStorageKeys. Returns all storage keys of the given address -func (api *ParityAPIImpl) ListStorageKeys(ctx context.Context, account common.Address, quantity int, offset *hexutil.Bytes) ([]hexutil.Bytes, error) { +func (api *ParityAPIImpl) ListStorageKeys(ctx context.Context, account common.Address, quantity int, offset *hexutil.Bytes, blockNumberOrTag rpc.BlockNumberOrHash) ([]hexutil.Bytes, error) { + if err := api.checkBlockNumber(blockNumberOrTag); err != nil { + return nil, err + } + tx, err := api.db.BeginRo(ctx) if err != nil { return nil, fmt.Errorf("listStorageKeys cannot open tx: %w", err) @@ -70,3 +79,11 @@ func (api *ParityAPIImpl) ListStorageKeys(ctx context.Context, account common.Ad } return keys, nil } + +func (api *ParityAPIImpl) checkBlockNumber(blockNumber rpc.BlockNumberOrHash) error { + num, isNum := blockNumber.Number() + if isNum && rpc.LatestBlockNumber == num { + return nil + } + return ErrWrongTag +} diff --git a/cmd/rpcdaemon/commands/parity_api_test.go b/cmd/rpcdaemon/commands/parity_api_test.go index ed4cc29c24c..70a607a8f4b 100644 --- a/cmd/rpcdaemon/commands/parity_api_test.go +++ b/cmd/rpcdaemon/commands/parity_api_test.go @@ -8,9 +8,12 @@ import ( "github.com/ledgerwatch/erigon/cmd/rpcdaemon/rpcdaemontest" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/hexutil" + "github.com/ledgerwatch/erigon/rpc" "github.com/stretchr/testify/assert" ) +var latestBlock = rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) + func TestParityAPIImpl_ListStorageKeys_NoOffset(t *testing.T) { assert := assert.New(t) db := rpcdaemontest.CreateTestKV(t) @@ -23,7 +26,7 @@ func TestParityAPIImpl_ListStorageKeys_NoOffset(t *testing.T) { "120e23dcb7e4437386073613853db77b10011a2404eefc716b97c7767e37f8eb", } addr := common.HexToAddress("0x920fd5070602feaea2e251e9e7238b6c376bcae5") - result, err := api.ListStorageKeys(context.Background(), addr, 5, nil) + result, err := api.ListStorageKeys(context.Background(), addr, 5, nil, latestBlock) if err != nil { t.Errorf("calling ListStorageKeys: %v", err) } @@ -47,7 +50,7 @@ func TestParityAPIImpl_ListStorageKeys_WithOffset_ExistingPrefix(t *testing.T) { addr := common.HexToAddress("0x920fd5070602feaea2e251e9e7238b6c376bcae5") offset := common.Hex2Bytes("29") b := hexutil.Bytes(offset) - result, err := api.ListStorageKeys(context.Background(), addr, 5, &b) + result, err := api.ListStorageKeys(context.Background(), addr, 5, &b, latestBlock) if err != nil { t.Errorf("calling ListStorageKeys: %v", err) } @@ -68,7 +71,7 @@ func TestParityAPIImpl_ListStorageKeys_WithOffset_NonExistingPrefix(t *testing.T addr := common.HexToAddress("0x920fd5070602feaea2e251e9e7238b6c376bcae5") offset := common.Hex2Bytes("30") b := hexutil.Bytes(offset) - result, err := api.ListStorageKeys(context.Background(), addr, 2, &b) + result, err := api.ListStorageKeys(context.Background(), addr, 2, &b, latestBlock) if err != nil { t.Errorf("calling ListStorageKeys: %v", err) } @@ -85,7 +88,7 @@ func TestParityAPIImpl_ListStorageKeys_WithOffset_EmptyResponse(t *testing.T) { addr := common.HexToAddress("0x920fd5070602feaea2e251e9e7238b6c376bcae5") offset := common.Hex2Bytes("ff") b := hexutil.Bytes(offset) - result, err := api.ListStorageKeys(context.Background(), addr, 2, &b) + result, err := api.ListStorageKeys(context.Background(), addr, 2, &b, latestBlock) if err != nil { t.Errorf("calling ListStorageKeys: %v", err) } @@ -97,6 +100,6 @@ func TestParityAPIImpl_ListStorageKeys_AccNotFound(t *testing.T) { db := rpcdaemontest.CreateTestKV(t) api := NewParityAPIImpl(db) addr := common.HexToAddress("0x920fd5070602feaea2e251e9e7238b6c376bcaef") - _, err := api.ListStorageKeys(context.Background(), addr, 2, nil) + _, err := api.ListStorageKeys(context.Background(), addr, 2, nil, latestBlock) assert.Error(err, fmt.Errorf("acc not found")) } diff --git a/cmd/rpctest/rpctest/type.go b/cmd/rpctest/rpctest/type.go index 06f9740643f..6cedced2913 100644 --- a/cmd/rpctest/rpctest/type.go +++ b/cmd/rpctest/rpctest/type.go @@ -42,6 +42,16 @@ type EthTransaction struct { Value hexutil.Big `json:"value"` } +type EthSendRawTransaction struct { + CommonResponse + TxnHash common.Hash `json:"result"` +} + +type EthTxPool struct { + CommonResponse + Result interface{} `json:"result"` +} + type EthBlockByNumberResult struct { Difficulty hexutil.Big `json:"difficulty"` Miner common.Address `json:"miner"` @@ -239,8 +249,14 @@ type AccountResult struct { StorageHash common.Hash `json:"storageHash"` StorageProof []StorageResult `json:"storageProof"` } + type StorageResult struct { Key string `json:"key"` Value *hexutil.Big `json:"value"` Proof []string `json:"proof"` } + +type ParityListStorageKeysResult struct { + CommonResponse + Result []hexutil.Bytes `json:"result"` +} From bb571a1961b90a251c0a384ce85e060fae0a3a60 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Thu, 10 Feb 2022 15:35:50 +0700 Subject: [PATCH 152/261] GetTransactionByHash: return nil if no pending tx (#3464) --- cmd/rpcdaemon/commands/eth_txs.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cmd/rpcdaemon/commands/eth_txs.go b/cmd/rpcdaemon/commands/eth_txs.go index 79fb8685923..4b0690439a4 100644 --- a/cmd/rpcdaemon/commands/eth_txs.go +++ b/cmd/rpcdaemon/commands/eth_txs.go @@ -64,6 +64,12 @@ func (api *APIImpl) GetTransactionByHash(ctx context.Context, hash common.Hash) if err != nil { return nil, err } + + // if no transactiion was found in the txpool then we return nil and an error warning that we didn't find the transaction by the hash + if txn == nil { + return nil, nil + } + return newRPCPendingTransaction(txn, curHeader, chainConfig), nil } From 7c35cd2b3337c89ac9ca82d9fe86a344d2f03d76 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Thu, 10 Feb 2022 16:15:45 +0700 Subject: [PATCH 153/261] state and newHead: 1 goroutine per subscriber (#3466) * save * save * save * Update to latest erigon-lib Co-authored-by: Alex Sharp --- cmd/rpcdaemon/commands/eth_subscribe_test.go | 2 +- eth/protocols/eth/discovery.go | 20 - eth/protocols/eth/handler.go | 33 -- eth/protocols/eth/protocol.go | 2 +- eth/stagedsync/stage_finish.go | 25 +- eth/stagedsync/stagebuilder.go | 2 +- ethdb/privateapi/ethbackend.go | 61 +-- ethdb/privateapi/events.go | 34 +- ethdb/snapshotdb/kv_snapshot_property_test.go | 466 ------------------ go.mod | 10 +- go.sum | 48 +- turbo/stages/stageloop.go | 1 - 12 files changed, 86 insertions(+), 618 deletions(-) delete mode 100644 ethdb/snapshotdb/kv_snapshot_property_test.go diff --git a/cmd/rpcdaemon/commands/eth_subscribe_test.go b/cmd/rpcdaemon/commands/eth_subscribe_test.go index 85bd8dd9774..03af730c5b8 100644 --- a/cmd/rpcdaemon/commands/eth_subscribe_test.go +++ b/cmd/rpcdaemon/commands/eth_subscribe_test.go @@ -52,6 +52,6 @@ func TestEthSubscribe(t *testing.T) { for i := uint64(1); i <= highestSeenHeader; i++ { header := <-newHeads - require.Equal(header.Number.Uint64(), i) + require.Equal(i, header.Number.Uint64()) } } diff --git a/eth/protocols/eth/discovery.go b/eth/protocols/eth/discovery.go index d88f2c5199b..a6cf92b88dc 100644 --- a/eth/protocols/eth/discovery.go +++ b/eth/protocols/eth/discovery.go @@ -19,10 +19,6 @@ package eth import ( "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/core/forkid" - "github.com/ledgerwatch/erigon/core/types" - "github.com/ledgerwatch/erigon/ethdb/privateapi" - "github.com/ledgerwatch/erigon/p2p/enode" - "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/rlp" ) @@ -39,22 +35,6 @@ func (e enrEntry) ENRKey() string { return "eth" } -// StartENRUpdater starts the `eth` ENR updater loop, which listens for chain -// head events and updates the requested node record whenever a fork is passed. -func StartENRUpdater(chainConfig *params.ChainConfig, genesisHash common.Hash, events *privateapi.Events, ln *enode.LocalNode) { - events.AddHeaderSubscription(func(h *types.Header) error { - ln.Set(CurrentENREntry(chainConfig, genesisHash, h.Number.Uint64())) - return nil - }) -} - -// CurrentENREntry constructs an `eth` ENR entry based on the current state of the chain. -func CurrentENREntry(chainConfig *params.ChainConfig, genesisHash common.Hash, headHeight uint64) *enrEntry { - return &enrEntry{ - ForkID: forkid.NewID(chainConfig, genesisHash, headHeight), - } -} - // CurrentENREntryFromForks constructs an `eth` ENR entry based on the current state of the chain. func CurrentENREntryFromForks(forks []uint64, genesisHash common.Hash, headHeight uint64) *enrEntry { return &enrEntry{ diff --git a/eth/protocols/eth/handler.go b/eth/protocols/eth/handler.go index 8466099c038..3032a5b45f5 100644 --- a/eth/protocols/eth/handler.go +++ b/eth/protocols/eth/handler.go @@ -25,9 +25,7 @@ import ( "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/types" - "github.com/ledgerwatch/erigon/p2p" "github.com/ledgerwatch/erigon/p2p/enode" - "github.com/ledgerwatch/erigon/p2p/enr" "github.com/ledgerwatch/erigon/params" ) @@ -91,37 +89,6 @@ type TxPool interface { Get(hash common.Hash) types.Transaction } -// MakeProtocols constructs the P2P protocol definitions for `eth`. -func MakeProtocols(backend Backend, readNodeInfo func() *NodeInfo, dnsdisc enode.Iterator, chainConfig *params.ChainConfig, genesisHash common.Hash, headHeight uint64) []p2p.Protocol { - protocols := make([]p2p.Protocol, len(ProtocolVersions)) - for i, version := range ProtocolVersions { - version := version // Closure - - protocols[i] = p2p.Protocol{ - Name: ProtocolName, - Version: version, - Length: protocolLengths[version], - Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error { - peer := NewPeer(version, p, rw, backend.TxPool()) - defer peer.Close() - - return backend.RunPeer(peer, func(peer *Peer) error { - return Handle(backend, peer) - }) - }, - NodeInfo: func() interface{} { - return readNodeInfo() - }, - PeerInfo: func(id enode.ID) interface{} { - return backend.PeerInfo(id) - }, - Attributes: []enr.Entry{CurrentENREntry(chainConfig, genesisHash, headHeight)}, - DialCandidates: dnsdisc, - } - } - return protocols -} - // NodeInfo represents a short summary of the `eth` sub-protocol metadata // known about the host peer. type NodeInfo struct { diff --git a/eth/protocols/eth/protocol.go b/eth/protocols/eth/protocol.go index 8a0b56b5ffd..a200125331f 100644 --- a/eth/protocols/eth/protocol.go +++ b/eth/protocols/eth/protocol.go @@ -52,7 +52,7 @@ var ProtocolVersions = []uint{ETH66, ETH65} // protocolLengths are the number of implemented message corresponding to // different protocol versions. -var protocolLengths = map[uint]uint64{ETH66: 17, ETH65: 17} +// var protocolLengths = map[uint]uint64{ETH66: 17, ETH65: 17} // maxMessageSize is the maximum cap on the size of a protocol message. const maxMessageSize = 10 * 1024 * 1024 diff --git a/eth/stagedsync/stage_finish.go b/eth/stagedsync/stage_finish.go index d825cd20e8f..9982528d4d1 100644 --- a/eth/stagedsync/stage_finish.go +++ b/eth/stagedsync/stage_finish.go @@ -1,18 +1,15 @@ package stagedsync import ( - "bytes" "context" "encoding/binary" - "reflect" - - "github.com/ledgerwatch/erigon/params" - "github.com/ledgerwatch/erigon/rlp" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/kv" + common2 "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/common/dbutils" "github.com/ledgerwatch/erigon/core/rawdb" - "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/log/v3" ) @@ -115,7 +112,6 @@ func NotifyNewHeaders(ctx context.Context, finishStageBeforeSync uint64, finishS log.Trace("RPC Daemon notification channel not set. No headers notifications will be sent") return nil } - // Notify all headers we have (either canonical or not) in a maximum range span of 1024 var notifyFrom uint64 if unwindTo != nil && *unwindTo != 0 && (*unwindTo) < finishStageBeforeSync { @@ -129,25 +125,20 @@ func NotifyNewHeaders(ctx context.Context, finishStageBeforeSync uint64, finishS } notifyFrom++ - startKey := make([]byte, reflect.TypeOf(notifyFrom).Size()+32) var notifyTo uint64 - binary.BigEndian.PutUint64(startKey, notifyFrom) - if err := tx.ForEach(kv.Headers, startKey, func(k, headerRLP []byte) error { + var headersRlp [][]byte + if err := tx.ForEach(kv.Headers, dbutils.EncodeBlockNumber(notifyFrom), func(k, headerRLP []byte) error { if len(headerRLP) == 0 { return nil } - header := new(types.Header) - if err := rlp.Decode(bytes.NewReader(headerRLP), header); err != nil { - log.Error("Invalid block header RLP", "err", err) - return err - } - notifyTo = header.Number.Uint64() - notifier.OnNewHeader(header) + notifyTo = binary.BigEndian.Uint64(k) + headersRlp = append(headersRlp, common2.CopyBytes(headerRLP)) return libcommon.Stopped(ctx.Done()) }); err != nil { log.Error("RPC Daemon notification failed", "error", err) return err } + notifier.OnNewHeader(headersRlp) log.Info("RPC Daemon notified of new headers", "from", notifyFrom-1, "to", notifyTo) return nil diff --git a/eth/stagedsync/stagebuilder.go b/eth/stagedsync/stagebuilder.go index 3a2155ffcf8..14141a6922e 100644 --- a/eth/stagedsync/stagebuilder.go +++ b/eth/stagedsync/stagebuilder.go @@ -11,7 +11,7 @@ import ( ) type ChainEventNotifier interface { - OnNewHeader(*types.Header) + OnNewHeader(newHeadersRlp [][]byte) OnNewPendingLogs(types.Logs) } diff --git a/ethdb/privateapi/ethbackend.go b/ethdb/privateapi/ethbackend.go index 80730ff960c..c5f3f65f38d 100644 --- a/ethdb/privateapi/ethbackend.go +++ b/ethdb/privateapi/ethbackend.go @@ -1,16 +1,13 @@ package privateapi import ( - "bytes" "context" "github.com/ledgerwatch/erigon-lib/gointerfaces" "github.com/ledgerwatch/erigon-lib/gointerfaces/remote" types2 "github.com/ledgerwatch/erigon-lib/gointerfaces/types" "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/params" - "github.com/ledgerwatch/erigon/rlp" "github.com/ledgerwatch/log/v3" "google.golang.org/protobuf/types/known/emptypb" ) @@ -72,47 +69,35 @@ func (s *EthBackendServer) NetPeerCount(_ context.Context, _ *remote.NetPeerCoun return &remote.NetPeerCountReply{Count: id}, nil } -func (s *EthBackendServer) Subscribe(r *remote.SubscribeRequest, subscribeServer remote.ETHBACKEND_SubscribeServer) error { +func (s *EthBackendServer) Subscribe(r *remote.SubscribeRequest, subscribeServer remote.ETHBACKEND_SubscribeServer) (err error) { log.Trace("Establishing event subscription channel with the RPC daemon ...") - s.events.AddHeaderSubscription(func(h *types.Header) error { + ch, clean := s.events.AddHeaderSubscription() + defer clean() + log.Info("new subscription to newHeaders established") + defer func() { + if err != nil { + log.Warn("subscription to newHeaders closed", "reason", err) + } else { + log.Warn("subscription to newHeaders closed") + } + }() + for { select { case <-s.ctx.Done(): - return nil + return s.ctx.Err() case <-subscribeServer.Context().Done(): - return nil - default: - } - - var buf bytes.Buffer - if err := rlp.Encode(&buf, h); err != nil { - log.Warn("error while marshaling a header", "err", err) - return err + return subscribeServer.Context().Err() + case headersRlp := <-ch: + for _, headerRlp := range headersRlp { + if err = subscribeServer.Send(&remote.SubscribeReply{ + Type: remote.Event_HEADER, + Data: headerRlp, + }); err != nil { + return err + } + } } - payload := buf.Bytes() - - err := subscribeServer.Send(&remote.SubscribeReply{ - Type: remote.Event_HEADER, - Data: payload, - }) - - // we only close the wg on error because if we successfully sent an event, - // that means that the channel wasn't closed and is ready to - // receive more events. - // if rpcdaemon disconnects, we will receive an error here - // next time we try to send an event - if err != nil { - log.Info("event subscription channel was closed", "reason", err) - } - return err - }) - - log.Info("event subscription channel established with the RPC daemon") - select { - case <-subscribeServer.Context().Done(): - case <-s.ctx.Done(): } - log.Info("event subscription channel closed with the RPC daemon") - return nil } func (s *EthBackendServer) ProtocolVersion(_ context.Context, _ *remote.ProtocolVersionRequest) (*remote.ProtocolVersionReply, error) { diff --git a/ethdb/privateapi/events.go b/ethdb/privateapi/events.go index 8d6cdaec7f7..ed42c880df0 100644 --- a/ethdb/privateapi/events.go +++ b/ethdb/privateapi/events.go @@ -8,14 +8,15 @@ import ( type RpcEventType uint64 -type HeaderSubscription func(*types.Header) error +type HeaderSubscription func(headerRLP []byte) error type PendingLogsSubscription func(types.Logs) error type PendingBlockSubscription func(*types.Block) error type PendingTxsSubscription func([]types.Transaction) error // Events manages event subscriptions and dissimination. Thread-safe type Events struct { - headerSubscriptions map[int]HeaderSubscription + id int + headerSubscriptions map[int]chan [][]byte pendingLogsSubscriptions map[int]PendingLogsSubscription pendingBlockSubscriptions map[int]PendingBlockSubscription pendingTxsSubscriptions map[int]PendingTxsSubscription @@ -24,17 +25,24 @@ type Events struct { func NewEvents() *Events { return &Events{ - headerSubscriptions: map[int]HeaderSubscription{}, + headerSubscriptions: map[int]chan [][]byte{}, pendingLogsSubscriptions: map[int]PendingLogsSubscription{}, pendingBlockSubscriptions: map[int]PendingBlockSubscription{}, pendingTxsSubscriptions: map[int]PendingTxsSubscription{}, } } -func (e *Events) AddHeaderSubscription(s HeaderSubscription) { +func (e *Events) AddHeaderSubscription() (chan [][]byte, func()) { e.lock.Lock() defer e.lock.Unlock() - e.headerSubscriptions[len(e.headerSubscriptions)] = s + ch := make(chan [][]byte, 8) + e.id++ + id := e.id + e.headerSubscriptions[id] = ch + return ch, func() { + delete(e.headerSubscriptions, id) + close(ch) + } } func (e *Events) AddPendingLogsSubscription(s PendingLogsSubscription) { @@ -49,12 +57,20 @@ func (e *Events) AddPendingBlockSubscription(s PendingBlockSubscription) { e.pendingBlockSubscriptions[len(e.pendingBlockSubscriptions)] = s } -func (e *Events) OnNewHeader(newHeader *types.Header) { +func (e *Events) OnNewHeader(newHeadersRlp [][]byte) { e.lock.Lock() defer e.lock.Unlock() - for i, sub := range e.headerSubscriptions { - if err := sub(newHeader); err != nil { - delete(e.headerSubscriptions, i) + for _, ch := range e.headerSubscriptions { + select { + case ch <- newHeadersRlp: + default: //if channel is full (slow consumer), drop old messages + for i := 0; i < cap(ch)/2; i++ { + select { + case <-ch: + default: + } + } + ch <- newHeadersRlp } } } diff --git a/ethdb/snapshotdb/kv_snapshot_property_test.go b/ethdb/snapshotdb/kv_snapshot_property_test.go deleted file mode 100644 index 6a0723377b6..00000000000 --- a/ethdb/snapshotdb/kv_snapshot_property_test.go +++ /dev/null @@ -1,466 +0,0 @@ -package snapshotdb - -import ( - "context" - "testing" - - "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/erigon-lib/kv/memdb" - "github.com/ledgerwatch/erigon/common" - "github.com/stretchr/testify/require" - "pgregory.net/rapid" -) - -func TestGetAndPut(t *testing.T) { - t.Skip("remove when it become stable for 200 rounds") - rapid.Check(t, rapid.Run(&getPutkvMachine{})) -} - -type getPutkvMachine struct { - bucket string - snKV kv.RwDB - modelKV kv.RwDB - snapshotKeys [][20]byte - newKeys [][20]byte - allKeys [][20]byte - - snTX kv.RwTx - modelTX kv.RwTx -} - -func (m *getPutkvMachine) Init(t *rapid.T) { - m.bucket = kv.PlainState - m.snKV = memdb.New() - m.modelKV = memdb.New() - m.snapshotKeys = rapid.SliceOf(rapid.ArrayOf(20, rapid.Byte())).Filter(func(_v [][20]byte) bool { - return len(_v) > 0 - }).Draw(t, "generate keys").([][20]byte) - m.newKeys = rapid.SliceOf(rapid.ArrayOf(20, rapid.Byte())).Filter(func(_v [][20]byte) bool { - return len(_v) > 0 - }).Draw(t, "generate new keys").([][20]byte) - notExistingKeys := rapid.SliceOf(rapid.ArrayOf(20, rapid.Byte())).Filter(func(_v [][20]byte) bool { - return len(_v) > 0 - }).Draw(t, "generate not excisting keys").([][20]byte) - m.allKeys = append(m.snapshotKeys, notExistingKeys...) - - txSn, err := m.snKV.BeginRw(context.Background()) - require.NoError(t, err) - defer txSn.Rollback() - - txModel, err := m.modelKV.BeginRw(context.Background()) - require.NoError(t, err) - defer txModel.Rollback() - for _, key := range m.snapshotKeys { - innerErr := txSn.Put(m.bucket, key[:], []byte("sn_"+common.Bytes2Hex(key[:]))) - require.NoError(t, innerErr) - innerErr = txModel.Put(m.bucket, key[:], []byte("sn_"+common.Bytes2Hex(key[:]))) - require.NoError(t, innerErr) - } - - //save snapshot and wrap new write db - err = txSn.Commit() - require.NoError(t, err) - err = txModel.Commit() - require.NoError(t, err) - m.snKV = NewSnapshotKV().StateSnapshot(m.snKV).DB(memdb.New()).Open() -} - -func (m *getPutkvMachine) Cleanup() { - if m.snTX != nil { - m.snTX.Rollback() - } - if m.modelTX != nil { - m.modelTX.Rollback() - } - m.snKV.Close() - m.modelKV.Close() -} - -func (m *getPutkvMachine) Check(t *rapid.T) { -} - -func (m *getPutkvMachine) Get(t *rapid.T) { - if m.snTX == nil && m.modelTX == nil { - return - } - key := rapid.SampledFrom(m.allKeys).Draw(t, "get a key").([20]byte) - var ( - v1, v2 []byte - err1, err2 error - ) - - v1, err1 = m.snTX.GetOne(m.bucket, key[:]) - v2, err2 = m.modelTX.GetOne(m.bucket, key[:]) - - require.Equal(t, err1, err2) - require.Equal(t, v1, v2) -} - -func (m *getPutkvMachine) Put(t *rapid.T) { - if len(m.newKeys) == 0 { - return - } - if m.snTX == nil && m.modelTX == nil { - return - } - key := rapid.SampledFrom(m.newKeys).Draw(t, "put a key").([20]byte) - m.allKeys = append(m.allKeys, key) - for i, v := range m.newKeys { - if v == key { - m.newKeys = append(m.newKeys[:i], m.newKeys[i+1:]...) - } - } - err := m.snTX.Put(m.bucket, key[:], []byte("put"+common.Bytes2Hex(key[:]))) - require.NoError(t, err) - - err = m.modelTX.Put(m.bucket, key[:], []byte("put"+common.Bytes2Hex(key[:]))) - require.NoError(t, err) -} - -func (m *getPutkvMachine) Delete(t *rapid.T) { - if m.snTX == nil && m.modelTX == nil { - return - } - key := rapid.SampledFrom(m.allKeys).Draw(t, "delete a key").([20]byte) - - err := m.snTX.Delete(m.bucket, key[:], nil) - require.NoError(t, err) - - err = m.modelTX.Put(m.bucket, key[:], nil) - require.NoError(t, err) -} - -func (m *getPutkvMachine) Begin(t *rapid.T) { - if m.modelTX != nil && m.snTX != nil { - return - } - mtx, err := m.modelKV.BeginRw(context.Background()) //nolint - require.NoError(t, err) - sntx, err := m.snKV.BeginRw(context.Background()) //nolint - require.NoError(t, err) - m.modelTX = mtx - m.snTX = sntx -} - -func (m *getPutkvMachine) Rollback(t *rapid.T) { - if m.modelTX == nil && m.snTX == nil { - return - } - m.snTX.Rollback() - m.modelTX.Rollback() - m.snTX = nil - m.modelTX = nil -} - -func (m *getPutkvMachine) Commit(t *rapid.T) { - if m.modelTX == nil && m.snTX == nil { - return - } - err := m.modelTX.Commit() - require.NoError(t, err) - err = m.snTX.Commit() - require.NoError(t, err) - m.snTX = nil - m.modelTX = nil -} - -type getKVMachine struct { - bucket string - snKV kv.RwDB - modelKV kv.RwDB - overWriteKeys [][20]byte - snKeys [][20]byte - newKeys [][20]byte - allKeys [][20]byte -} - -func (m *getKVMachine) Init(t *rapid.T) { - m.bucket = kv.PlainState - m.snKV = memdb.New() - m.modelKV = memdb.New() - m.snKeys = rapid.SliceOf(rapid.ArrayOf(20, rapid.Byte())).Filter(func(_v [][20]byte) bool { - return len(_v) > 0 - }).Draw(t, "generate keys").([][20]byte) - m.overWriteKeys = rapid.SliceOf(rapid.SampledFrom(m.snKeys)).Draw(t, "get snKeys").([][20]byte) - m.newKeys = rapid.SliceOf(rapid.ArrayOf(20, rapid.Byte())).Draw(t, "generate new keys").([][20]byte) - m.allKeys = append(m.snKeys, m.overWriteKeys...) - m.allKeys = append(m.allKeys, m.newKeys...) - notExistingKeys := rapid.SliceOf(rapid.ArrayOf(20, rapid.Byte())).Draw(t, "generate not excisting keys").([][20]byte) - m.allKeys = append(m.allKeys, notExistingKeys...) - - txSn, err := m.snKV.BeginRw(context.Background()) - require.NoError(t, err) - defer txSn.Rollback() - - txModel, err := m.modelKV.BeginRw(context.Background()) - require.NoError(t, err) - defer txModel.Rollback() - for _, key := range m.snKeys { - innerErr := txSn.Put(m.bucket, key[:], []byte("sn_"+common.Bytes2Hex(key[:]))) - require.NoError(t, innerErr) - innerErr = txModel.Put(m.bucket, key[:], []byte("sn_"+common.Bytes2Hex(key[:]))) - require.NoError(t, innerErr) - } - - //save snapshot and wrap new write db - err = txSn.Commit() - require.NoError(t, err) - m.snKV = NewSnapshotKV().StateSnapshot(m.snKV).DB(memdb.New()).Open() - txSn, err = m.snKV.BeginRw(context.Background()) - require.NoError(t, err) - defer txSn.Rollback() - - for _, key := range m.overWriteKeys { - innerErr := txSn.Put(m.bucket, key[:], []byte("overwrite_"+common.Bytes2Hex(key[:]))) - require.NoError(t, innerErr) - innerErr = txModel.Put(m.bucket, key[:], []byte("overwrite_"+common.Bytes2Hex(key[:]))) - require.NoError(t, innerErr) - } - for _, key := range m.newKeys { - innerErr := txSn.Put(m.bucket, key[:], []byte("new_"+common.Bytes2Hex(key[:]))) - require.NoError(t, innerErr) - innerErr = txModel.Put(m.bucket, key[:], []byte("new_"+common.Bytes2Hex(key[:]))) - require.NoError(t, innerErr) - } - err = txSn.Commit() - require.NoError(t, err) - err = txModel.Commit() - require.NoError(t, err) -} - -func (m *getKVMachine) Cleanup() { - m.snKV.Close() - m.modelKV.Close() -} - -func (m *getKVMachine) Check(t *rapid.T) { -} - -func (m *getKVMachine) Get(t *rapid.T) { - key := rapid.SampledFrom(m.allKeys).Draw(t, "get a key").([20]byte) - var ( - v1, v2 []byte - err1, err2 error - ) - err := m.snKV.View(context.Background(), func(tx kv.Tx) error { - v1, err1 = tx.GetOne(m.bucket, key[:]) - return nil - }) - require.NoError(t, err) - err = m.modelKV.View(context.Background(), func(tx kv.Tx) error { - v2, err2 = tx.GetOne(m.bucket, key[:]) - return nil - }) - require.NoError(t, err) - require.Equal(t, err1, err2) - require.Equal(t, v1, v2) -} - -func TestGet(t *testing.T) { - t.Skip("remove when it become stable for 200 rounds") - rapid.Check(t, rapid.Run(&getKVMachine{})) -} - -func TestCursorWithTX(t *testing.T) { - t.Skip("remove when it become stable for 200 rounds") - rapid.Check(t, rapid.Run(&cursorKVMachine{})) -} - -type cursorKVMachine struct { - bucket string - snKV kv.RwDB - modelKV kv.RwDB - - snTX kv.RwTx - modelTX kv.RwTx - - snCursor kv.RwCursor - modelCursor kv.RwCursor - - snapshotKeys [][20]byte - newKeys [][20]byte - allKeys [][20]byte -} - -func (m *cursorKVMachine) Init(t *rapid.T) { - m.bucket = kv.PlainState - m.snKV = memdb.New() - m.modelKV = memdb.New() - m.snapshotKeys = rapid.SliceOf(rapid.ArrayOf(20, rapid.Byte())).Filter(func(_v [][20]byte) bool { - return len(_v) > 0 - }).Draw(t, "generate keys").([][20]byte) - m.newKeys = rapid.SliceOf(rapid.ArrayOf(20, rapid.Byte())).Filter(func(_v [][20]byte) bool { - return len(_v) > 0 - }).Draw(t, "generate new keys").([][20]byte) - notExistingKeys := rapid.SliceOf(rapid.ArrayOf(20, rapid.Byte())).Filter(func(_v [][20]byte) bool { - return len(_v) > 0 - }).Draw(t, "generate not excisting keys").([][20]byte) - m.allKeys = append(m.snapshotKeys, notExistingKeys...) - - defer func() { - m.snTX = nil - m.modelTX = nil - }() - txSn, err := m.snKV.BeginRw(context.Background()) - require.NoError(t, err) - defer txSn.Rollback() - - txModel, err := m.modelKV.BeginRw(context.Background()) - require.NoError(t, err) - defer txModel.Rollback() - for _, key := range m.snapshotKeys { - innerErr := txSn.Put(m.bucket, key[:], []byte("sn_"+common.Bytes2Hex(key[:]))) - require.NoError(t, innerErr) - innerErr = txModel.Put(m.bucket, key[:], []byte("sn_"+common.Bytes2Hex(key[:]))) - require.NoError(t, innerErr) - } - - //save snapshot and wrap new write db - err = txSn.Commit() - require.NoError(t, err) - err = txModel.Commit() - require.NoError(t, err) - m.snKV = NewSnapshotKV().StateSnapshot(m.snKV).DB(memdb.New()).Open() -} - -func (m *cursorKVMachine) Check(t *rapid.T) { -} - -func (m *cursorKVMachine) Cleanup() { - if m.snTX != nil { - m.snTX.Rollback() - } - if m.modelTX != nil { - m.modelTX.Rollback() - } - - m.snKV.Close() - m.snKV = nil - m.modelKV.Close() - m.modelKV = nil -} - -func (m *cursorKVMachine) Begin(t *rapid.T) { - if m.modelTX != nil && m.snTX != nil { - return - } - - mtx, err := m.modelKV.BeginRw(context.Background()) //nolint - require.NoError(t, err) - sntx, err := m.snKV.BeginRw(context.Background()) //nolint - require.NoError(t, err) - m.modelTX = mtx - m.snTX = sntx -} - -func (m *cursorKVMachine) Rollback(t *rapid.T) { - if m.modelTX == nil && m.snTX == nil { - return - } - m.snTX.Rollback() - m.modelTX.Rollback() - m.snTX = nil - m.modelTX = nil - m.snCursor = nil - m.modelCursor = nil -} - -func (m *cursorKVMachine) Commit(t *rapid.T) { - if m.modelTX == nil && m.snTX == nil { - return - } - err := m.modelTX.Commit() - require.NoError(t, err) - err = m.snTX.Commit() - require.NoError(t, err) - m.snTX = nil - m.modelTX = nil - m.snCursor = nil - m.modelCursor = nil -} - -func (m *cursorKVMachine) Cursor(t *rapid.T) { - if m.modelTX == nil && m.snTX == nil { - return - } - if m.modelCursor != nil && m.snCursor != nil { - return - } - var err error - m.modelCursor, err = m.modelTX.RwCursor(m.bucket) - require.NoError(t, err) - m.snCursor, err = m.snTX.RwCursor(m.bucket) - require.NoError(t, err) -} - -func (m *cursorKVMachine) CloseCursor(t *rapid.T) { - if m.modelTX == nil && m.snTX == nil { - return - } - if m.modelCursor == nil && m.snCursor == nil { - return - } - m.modelCursor.Close() - m.snCursor.Close() - m.modelCursor = nil - m.snCursor = nil -} - -func (m *cursorKVMachine) First(t *rapid.T) { - if m.modelCursor == nil && m.snCursor == nil { - return - } - k1, v1, err1 := m.modelCursor.First() - k2, v2, err2 := m.snCursor.First() - require.Equal(t, k1, k2) - require.Equal(t, v1, v2) - require.Equal(t, err1, err2) -} - -func (m *cursorKVMachine) Last(t *rapid.T) { - if m.modelCursor == nil && m.snCursor == nil { - return - } - k1, v1, err1 := m.modelCursor.Last() - k2, v2, err2 := m.snCursor.Last() - require.Equal(t, k1, k2) - require.Equal(t, v1, v2) - require.Equal(t, err1, err2) -} - -func (m *cursorKVMachine) Seek(t *rapid.T) { - if m.modelCursor == nil && m.snCursor == nil { - return - } - key := rapid.SampledFrom(m.allKeys).Draw(t, "get random key").([20]byte) - k1, v1, err1 := m.modelCursor.Seek(key[:]) - k2, v2, err2 := m.snCursor.Seek(key[:]) - require.Equal(t, k1, k2) - require.Equal(t, v1, v2) - require.Equal(t, err1, err2) -} - -func (m *cursorKVMachine) SeekExact(t *rapid.T) { - if m.modelCursor == nil && m.snCursor == nil { - return - } - - key := rapid.SampledFrom(m.allKeys).Draw(t, "get random key").([20]byte) - k1, v1, err1 := m.modelCursor.SeekExact(key[:]) - k2, v2, err2 := m.snCursor.SeekExact(key[:]) - require.Equal(t, k1, k2) - require.Equal(t, v1, v2) - require.Equal(t, err1, err2) -} - -func (m *cursorKVMachine) Next(t *rapid.T) { - if m.modelCursor == nil && m.snCursor == nil { - return - } - k1, v1, err1 := m.modelCursor.Next() - k2, v2, err2 := m.snCursor.Next() - - require.Equal(t, k1, k2) - require.Equal(t, v1, v2) - require.Equal(t, err1, err2) -} diff --git a/go.mod b/go.mod index c2486eb5cfc..1cfb49343e4 100644 --- a/go.mod +++ b/go.mod @@ -35,17 +35,17 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20220203181034-d49d18ddaf17 + github.com/ledgerwatch/erigon-lib v0.0.0-20220210083718-1599f6eed792 github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 github.com/pelletier/go-toml v1.9.4 - github.com/quasilyte/go-ruleguard/dsl v0.3.6 - github.com/rs/cors v1.8.0 - github.com/shirou/gopsutil/v3 v3.21.9 + github.com/quasilyte/go-ruleguard/dsl v0.3.15 + github.com/rs/cors v1.8.2 + github.com/shirou/gopsutil/v3 v3.21.12 github.com/spf13/cobra v1.2.1 github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.7.1-0.20210427113832-6241f9ab9942 github.com/torquem-ch/mdbx-go v0.22.10 github.com/ugorji/go/codec v1.1.13 github.com/ugorji/go/codec/codecgen v1.1.13 diff --git a/go.sum b/go.sum index 5e569290826..4b6ee5654bc 100644 --- a/go.sum +++ b/go.sum @@ -63,8 +63,6 @@ github.com/RoaringBitmap/roaring v0.9.4 h1:ckvZSX5gwCRaJYBNe7syNawCU5oruY9gQmjXl github.com/RoaringBitmap/roaring v0.9.4/go.mod h1:icnadbWcNyfEHlYdr+tDlOTih1Bf/h+rzPpv4sbomAA= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= -github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= github.com/VictoriaMetrics/fastcache v1.7.0 h1:E6GibaGI685TafrI7E/QqZPkMsOzRw+3gpICQx08ISg= github.com/VictoriaMetrics/fastcache v1.7.0/go.mod h1:n7Sl+ioh/HlWeYHLSIBIE8TcZFHg/+xgvomWSS5xuEE= github.com/VictoriaMetrics/metrics v1.18.1 h1:OZ0+kTTto8oPfHnVAnTOoyl0XlRhRkoQrD2n2cOuRw0= @@ -279,8 +277,6 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4 github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61 h1:IZqZOB2fydHte3kUgxrzK5E1fW7RQGeDwE8F/ZZnUYc= github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61/go.mod h1:Q0X6pkwTILDlzrGEckF6HKjXe48EgsY/l7K7vhY4MW8= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= @@ -299,10 +295,8 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2 github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY= -github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM= -github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -371,8 +365,9 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -466,7 +461,6 @@ github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -499,19 +493,20 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20220203181034-d49d18ddaf17 h1:1WOGytdl1036LxxMLcQp53I+coKrSH0oFkE0NJqamGA= -github.com/ledgerwatch/erigon-lib v0.0.0-20220203181034-d49d18ddaf17/go.mod h1:BQNYmN6i8RdHqedsztAj3XDnswYebacmFAnsznlisTc= +github.com/ledgerwatch/erigon-lib v0.0.0-20220210083718-1599f6eed792 h1:JWkGY3AME4Su+1xtjGvtYfJnaO6dAScf/Jx4J9mb6Vw= +github.com/ledgerwatch/erigon-lib v0.0.0-20220210083718-1599f6eed792/go.mod h1:BQNYmN6i8RdHqedsztAj3XDnswYebacmFAnsznlisTc= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= github.com/ledgerwatch/secp256k1 v1.0.0/go.mod h1:SPmqJFciiF/Q0mPt2jVs2dTr/1TZBTIA+kPMmKgBAak= -github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= github.com/logrusorgru/aurora/v3 v3.0.0 h1:R6zcoZZbvVcGMvDCKo45A9U/lzYyzl5NfYIvznmDfE4= github.com/logrusorgru/aurora/v3 v3.0.0/go.mod h1:vsR12bk5grlLvLXAYrBsb5Oc/N+LxAlxggSjiwMnCUc= github.com/lucas-clemente/quic-go v0.7.1-0.20190401152353-907071221cf9/go.mod h1:PpMmPfPKO9nKJ/psF49ESTAGQSdfXxlg1otPbEB2nOw= github.com/lucas-clemente/quic-go v0.18.0/go.mod h1:yXttHsSNxQi8AWijC/vLP+OJczXqzHSOcJrM5ITUlCg= github.com/lucas-clemente/quic-go v0.19.3 h1:eCDQqvGBB+kCTkA0XrAFtNe81FMa0/fn4QSoeAbmiF4= github.com/lucas-clemente/quic-go v0.19.3/go.mod h1:ADXpNbTQjq1hIzCpB+y/k5iz4n4z4IwqoLb94Kh5Hu8= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/lukechampine/stm v0.0.0-20191022212748-05486c32d236/go.mod h1:wTLsd5FC9rts7GkMpsPGk64CIuea+03yaLAp19Jmlg8= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= @@ -531,7 +526,6 @@ github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHR github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= @@ -644,6 +638,8 @@ github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= @@ -664,13 +660,13 @@ github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/quasilyte/go-ruleguard/dsl v0.3.6 h1:W2wnISJifyda0x/RXq15Qjrsu9iOhX2gy4+Ku+owylw= -github.com/quasilyte/go-ruleguard/dsl v0.3.6/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= +github.com/quasilyte/go-ruleguard/dsl v0.3.15 h1:rClYn6lk8wUV5kXnQG4JVsRQjZhSetaNtwml5wkFp5g= +github.com/quasilyte/go-ruleguard/dsl v0.3.15/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rs/cors v1.8.0 h1:P2KMzcFwrPoSjkF1WLRPsp3UMLyql8L4v9hQpVeK5so= -github.com/rs/cors v1.8.0/go.mod h1:EBwu+T5AvHOcXwvZIkQFjUN6s8Czyqw12GL/Y0tUyRM= +github.com/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U= +github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/dnscache v0.0.0-20190621150935-06bb5526f76b/go.mod h1:qe5TWALJ8/a1Lqznoc5BDHpYX/8HU60Hm2AwRmqzxqA= github.com/rs/dnscache v0.0.0-20210201191234-295bba877686 h1:IJ6Df0uxPDtNoByV0KkzVKNseWvZFCNM/S9UoyOMCSI= github.com/rs/dnscache v0.0.0-20210201191234-295bba877686/go.mod h1:qe5TWALJ8/a1Lqznoc5BDHpYX/8HU60Hm2AwRmqzxqA= @@ -684,8 +680,8 @@ github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46/go.mod h1:uAQ5P github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/shirou/gopsutil/v3 v3.21.9 h1:Vn4MUz2uXhqLSiCbGFRc0DILbMVLAY92DSkT8bsYrHg= -github.com/shirou/gopsutil/v3 v3.21.9/go.mod h1:YWp/H8Qs5fVmf17v7JNZzA0mPJ+mS2e9JdiUF9LlKzQ= +github.com/shirou/gopsutil/v3 v3.21.12 h1:VoGxEW2hpmz0Vt3wUvHIl9fquzYLNpVpgNNB7pGJimA= +github.com/shirou/gopsutil/v3 v3.21.12/go.mod h1:BToYZVTlSVlfazpDDYFnsVZLaoRG+g8ufT6fPQLdJzA= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= @@ -738,8 +734,9 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1-0.20210427113832-6241f9ab9942 h1:t0lM6y/M5IiUZyvbBTcngso8SZEZICH7is9B6g/obVU= +github.com/stretchr/testify v1.7.1-0.20210427113832-6241f9ab9942/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syncthing/syncthing v0.14.48-rc.4/go.mod h1:nw3siZwHPA6M8iSfjDCWQ402eqvEIasMQOE8nFOxy7M= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= @@ -756,10 +753,8 @@ github.com/torquem-ch/mdbx-go v0.22.10 h1:reevtNP74E9SN7ESnogJr8Q8CI/0JcSMJ9tghf github.com/torquem-ch/mdbx-go v0.22.10/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go v1.1.13 h1:nB3O5kBSQGjEQAcfe1aLUYuxmXdFKmYgBZhY32rQb6Q= github.com/ugorji/go v1.1.13/go.mod h1:jxau1n+/wyTGLQoCkjok9r5zFa/FxT6eI5HiHKQszjc= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.1.13 h1:013LbFhocBoIqgHeIHKlV4JWYhqogATYWZhIcH0WHn4= github.com/ugorji/go/codec v1.1.13/go.mod h1:oNVt3Dq+FO91WNQ/9JnHKQP2QJxTzoN7wCBFCq1OeuU= github.com/ugorji/go/codec/codecgen v1.1.13 h1:rGpZ4Q63VcWA3DMBbIHvg+SQweUkfXBBa/f9X0W+tFg= @@ -790,6 +785,8 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= +github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0= @@ -982,7 +979,6 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190910064555-bbd175535a8b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1018,6 +1014,7 @@ golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1036,6 +1033,7 @@ golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211030160813-b3129d9d1021 h1:giLT+HuUP/gXYrG2Plg9WTjj4qhfgaW424ZIFog3rlk= golang.org/x/sys v0.0.0-20211030160813-b3129d9d1021/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -1251,8 +1249,6 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogR gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= -gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 h1:a6cXbcDDUkSBlpnkWV1bJ+vv3mOgQEltEJ2rPxroVu0= diff --git a/turbo/stages/stageloop.go b/turbo/stages/stageloop.go index a962c2f9a1e..badca01bf96 100644 --- a/turbo/stages/stageloop.go +++ b/turbo/stages/stageloop.go @@ -186,7 +186,6 @@ func StageLoopStep( notifications.Accumulator.SendAndReset(ctx, notifications.StateChangesConsumer, pendingBaseFee.Uint64(), header.GasLimit) return stagedsync.NotifyNewHeaders(ctx, finishProgressBefore, head, sync.PrevUnwindPoint(), notifications.Events, tx) - }); err != nil { return err } From 82c80c942c64c2ad5e9cb869871fa4856af96295 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Thu, 10 Feb 2022 13:18:40 +0000 Subject: [PATCH 154/261] Revert "Inverted lowestNum and highestNum in header downloader (#3301) (#3303)" (#3469) This reverts commit ab3f69b342e572df8b01d74d6f35deab9701eb2b. Co-authored-by: Alexey Sharp --- turbo/stages/headerdownload/header_algos.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/turbo/stages/headerdownload/header_algos.go b/turbo/stages/headerdownload/header_algos.go index d096cd9bbff..f65a2a1f945 100644 --- a/turbo/stages/headerdownload/header_algos.go +++ b/turbo/stages/headerdownload/header_algos.go @@ -851,7 +851,7 @@ func (hi *HeaderInserter) BestHeaderChanged() bool { // speeds up visibility of new blocks // It remember peerID - then later - if anchors created from segments will abandoned - this peerID gonna get Penalty func (hd *HeaderDownload) ProcessSegment(segment *ChainSegment, newBlock bool, peerID string) (requestMore bool, penalties []PenaltyItem) { - log.Trace("processSegment", "from", segment.Headers[len(segment.Headers)-1].Number.Uint64(), segment.Headers[0].Number.Uint64(), "to") + log.Trace("processSegment", "from", segment.Headers[0].Number.Uint64(), "to", segment.Headers[len(segment.Headers)-1].Number.Uint64()) hd.lock.Lock() defer hd.lock.Unlock() foundAnchor, start := hd.findAnchors(segment) @@ -867,8 +867,8 @@ func (hd *HeaderDownload) ProcessSegment(segment *ChainSegment, newBlock bool, p } return } - height := segment.Headers[0].Number.Uint64() - hash := segment.Headers[0].Hash() + height := segment.Headers[len(segment.Headers)-1].Number.Uint64() + hash := segment.Headers[len(segment.Headers)-1].Hash() if newBlock || hd.seenAnnounces.Seen(hash) { if height > hd.topSeenHeight { hd.topSeenHeight = height From be13f9d3da0a05608142244014cb48982c3ff463 Mon Sep 17 00:00:00 2001 From: Andrew Ashikhmin <34320705+yperbasis@users.noreply.github.com> Date: Thu, 10 Feb 2022 14:19:07 +0100 Subject: [PATCH 155/261] Update instead of SaveStageProgress for stages.Header (#3458) * Update instead of SaveStageProgress for stages.Header * Call WriteHeadHeaderHash/stage.Update after the loop --- eth/stagedsync/stage_headers.go | 16 +++++++++++++--- turbo/stages/headerdownload/header_algos.go | 6 ------ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/eth/stagedsync/stage_headers.go b/eth/stagedsync/stage_headers.go index 447eb74ba61..93bf6e0f6ae 100644 --- a/eth/stagedsync/stage_headers.go +++ b/eth/stagedsync/stage_headers.go @@ -158,6 +158,7 @@ Loop: if inSync, err = cfg.hd.InsertHeaders(headerInserter.FeedHeaderFunc(tx), logPrefix, logEvery.C); err != nil { return err } + announces := cfg.hd.GrabAnnounces() if len(announces) > 0 { cfg.announceNewHashes(ctx, announces) @@ -194,9 +195,18 @@ Loop: } if headerInserter.Unwind() { u.UnwindTo(headerInserter.UnwindPoint(), common.Hash{}) - } else if headerInserter.GetHighest() != 0 { - if err := fixCanonicalChain(logPrefix, logEvery, headerInserter.GetHighest(), headerInserter.GetHighestHash(), tx); err != nil { - return fmt.Errorf("fix canonical chain: %w", err) + } + if headerInserter.GetHighest() != 0 { + if !headerInserter.Unwind() { + if err := fixCanonicalChain(logPrefix, logEvery, headerInserter.GetHighest(), headerInserter.GetHighestHash(), tx); err != nil { + return fmt.Errorf("fix canonical chain: %w", err) + } + } + if err = rawdb.WriteHeadHeaderHash(tx, headerInserter.GetHighestHash()); err != nil { + return fmt.Errorf("[%s] marking head header hash as %x: %w", logPrefix, headerInserter.GetHighestHash(), err) + } + if err = s.Update(tx, headerInserter.GetHighest()); err != nil { + return fmt.Errorf("[%s] saving Headers progress: %w", logPrefix, err) } } if !useExternalTx { diff --git a/turbo/stages/headerdownload/header_algos.go b/turbo/stages/headerdownload/header_algos.go index f65a2a1f945..1e0380b1483 100644 --- a/turbo/stages/headerdownload/header_algos.go +++ b/turbo/stages/headerdownload/header_algos.go @@ -789,12 +789,6 @@ func (hi *HeaderInserter) FeedHeader(db kv.StatelessRwTx, header *types.Header, // Loop above terminates when either err != nil (handled already) or ch == ancestorHash, therefore ancestorHeight is our forking point forkingPoint = ancestorHeight } - if err = rawdb.WriteHeadHeaderHash(db, hash); err != nil { - return fmt.Errorf("[%s] marking head header hash as %x: %w", hi.logPrefix, hash, err) - } - if err = stages.SaveStageProgress(db, stages.Headers, blockHeight); err != nil { - return fmt.Errorf("[%s] saving Headers progress: %w", hi.logPrefix, err) - } hi.highest = blockHeight hi.highestHash = hash hi.highestTimestamp = header.Time From 0397007f2d1af390037db2a8f8422f7eee29a7b4 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Thu, 10 Feb 2022 14:01:05 +0000 Subject: [PATCH 156/261] Update version.go (#3470) --- params/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/params/version.go b/params/version.go index e760cabc8a7..b663d95f2ef 100644 --- a/params/version.go +++ b/params/version.go @@ -33,7 +33,7 @@ var ( const ( VersionMajor = 2022 // Major version component of the current release VersionMinor = 2 // Minor version component of the current release - VersionMicro = 1 // Patch version component of the current release + VersionMicro = 2 // Patch version component of the current release VersionModifier = "beta" // Patch version component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" From 412464c843be9cea85c7deb1406bb740e07ec07a Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Thu, 10 Feb 2022 14:11:33 +0000 Subject: [PATCH 157/261] Update skip analysis and preverified hashes (#3472) Co-authored-by: Alexey Sharp --- core/skip_analysis.go | 2 +- .../preverified_hashes_mainnet.go | 298 +++++++++++++++++- .../preverified_hashes_ropsten.go | 189 ++++++++++- 3 files changed, 486 insertions(+), 3 deletions(-) diff --git a/core/skip_analysis.go b/core/skip_analysis.go index 55c6c658c06..376c6b75f5f 100644 --- a/core/skip_analysis.go +++ b/core/skip_analysis.go @@ -21,7 +21,7 @@ import ( ) // MainnetNotCheckedFrom is the first block number not yet checked for invalid jumps -const MainnetNotCheckedFrom uint64 = 14121400 +const MainnetNotCheckedFrom uint64 = 14178300 // SkipAnalysis function tells us whether we can skip performing jumpdest analysis // for the historical blocks (on mainnet now but perhaps on the testsnets diff --git a/turbo/stages/headerdownload/preverified_hashes_mainnet.go b/turbo/stages/headerdownload/preverified_hashes_mainnet.go index c4d6585ac82..89137463d0f 100644 --- a/turbo/stages/headerdownload/preverified_hashes_mainnet.go +++ b/turbo/stages/headerdownload/preverified_hashes_mainnet.go @@ -73551,6 +73551,302 @@ var mainnetPreverifiedHashes = []string{ "c66fba67205d7cc482ac946d4deb42c5d5aa7c8824fb4fe53d204f438e4addb2", "2efde96fb63b15cbdb02f92e9c2e3865e2b3fe89049707debe7174eb786bb7f2", "ba155688bb8c82e3b214c983c51db5488c255c326be4852c1c972c7eb5b48cc3", + "8117c1d2c46212ed4669a9c9dbfa4926861a72483b11af1ddf15cfe2b8796c56", + "b90a9ae470482022c9239244fbc34f5a066b2317916aa1fd4ca80e75e582f32a", + "fe571e3178097b61e9a4d5294217474b903dd0473c236a1678013323fc935fd9", + "aa7d3310c6bee5dac98ee32ad4523518d799c82a49a7a1a2a9e3855b1226ff4c", + "f6111124a5e97d04e99373e5288c4f867bf7e69a171cad24fa8b60a2253eb8da", + "6ea310b30be08a93afc6ecf1149bc512ba4fd5e9321be252aa0ff8da60ee8901", + "172e1bc033950a10d26e47843d007ffb96083b9abbe1dd500681c28a03d9eef8", + "f1162e48987220a0f684cbe620aee283d13355a0b80e4f357dedd5d0262716b7", + "5cc24c2b965b7c282d81dbd96a334e8b21b7ae6002640149cd381f816cdd6182", + "9d449442b9f1f2c1aed5dbe36aa4fa9ce668246ec17ebc7b483f1caf2861351a", + "3099e32e484ed3eb48cf848467d756dbe1f7041cdd9c3dbaf4e7de0c548cdb21", + "d5a07c9c320fc9187aeeef33fb37aa4d54c7f6e14a36d72c2093f6bf00d5280c", + "fe86faafca367db459736677bbb854205585559aa87437ae3001140213e0b9f5", + "30ed5da9022e4940147443cf5724e34e7eb74128f1908c32791204e684eeb2a5", + "3f8414be4664ff35756dcad7c91c3402a59bc542e8bcccec32b168921b2564b1", + "7d8acb1f0b56cdc7afbad5b40a348171a59136bb58aa85343fdf83078f39c520", + "674f976e0c187a948da1eadbd1cfc48303002a74990e6cc3de1aecfcdcbc1d8a", + "868f550fb868bf84df4fed51b9b56c6f743bce19b6d02ffba1634b29f8c99680", + "9e015662e7cfb550c552c9dc66d13f1c3d34b851f5726d547baef122210eb249", + "a54090992f98179e7a0b3d8cb841053e389464218ea11ef953de40a2c8091cb3", + "a0ccb561023311c00d6dc4a7719fb114a6a107efc87cc326bcafe46fb1952f9a", + "872335a0bc941d7fcd4e66cc8561468f480174f3b6441bb47d4d109f00281c41", + "8588b64d376773b14c9c942779a40abc9fa00131d6fab3bca5f1e1ced5f99555", + "9118d2b56deaa72a93c1b9cf81b2b6026de6bc10393475e96a14e4354a7301fc", + "3575598478d1b724acf525f477d0e86f4ce5b0c3b312a298ad8c2430051304ff", + "351dba85af255af6d92a51747f3b14aacf5f85ac33c61af381a113d12bca1697", + "5132ca09e74d40f6ac0e60abcb5eb17bad11158f427ea1e7c84812b4a3c7f192", + "1c5c479bf2b057f1a516d9eb953fe314333b83ec517718e1361d8ed3db9876e9", + "945685ec2606a267c081b266e5694a6a5607f44e8af2f514b02d58bafc3ff1e3", + "9283ebc349de0f198588d74284e98425e940984716f1b5856193f0adde709cb0", + "0f87b8a2fffb2a653a887c082f11385b5f5c5ebb476dba03a851911b96b79e1d", + "567ebcb8ff426fa3aa7ac9932e90c182d5482ff038bb60f0945e043910dfeea3", + "ee9e0808926ba49f6ce920dfbe9dbf843a5b68a6137e435b88a103fbf56f482e", + "7867d925ad497b52eac052c93f57b911523995a02371005777b4107c714a9467", + "725a9b0506ee8fe734a3e4c2a80511ecf5a723cee1571c87ac996c218234bf2c", + "8db4cb3aa2025521f0f578bd8870c0bdaa51f8930a6923cf885bed7da7dc3f4d", + "084f3ce85787f65aac03b66b66bb73b5a258a482a742750ee556b147a2a12c1d", + "e835cb87a9cfe48df08401df1a2b6f2baaf4bf049fb423caeb570981f8d35da2", + "0db61ce8b90e8f233194015b82a9659216d5da63ec662d612adde51444e771f3", + "aff998385dcb7c35ac8763490b78fa09b3c939491c253a5698ba03caef1b247f", + "3df9cf46a2a53a1ff3761aa73fbf1f5579c76c8861949d632fb72598b185b304", + "910f0177a22124664f8703440a5dfe6e1efacfe71af702966d912d68a594547a", + "917abed07ad037ff3482c724052d41b30f833ebc2a3f2af3b275b015d12be7d5", + "260153634b056c122387e0f3de7f9167f8768e85fc896e25321584694a9a0638", + "ab6062055ce87d09819137073eea963fc9c34766f1298e42f9773c282bf6aca6", + "664b532c4ecac21b23466287549fd8eae06aa17d84d401ca29001d335cc4e504", + "145bafb3455719cc5c0bfc8cd53b2093dbdf670725ed2f03812d4f4c2a318567", + "8e19a8ac0a42d22a54367f946e26d936d6ab8de272eec513200646571889ea05", + "77e3463f4952729636547eff44b853387db01fdf168d4f135c74add6e1d81ee6", + "9514166eba92975ea79dd9203519b2d49bc44b9ffa4864b3c22fa177f9abc4db", + "8ab8833c71148cb9090477566e4bf3d6acd5242d3eb087750bb3b422843a0395", + "b609d9cbf477c2955a9cb2a13e60723f088b2ddb89ace3eb1a529ae6f90bf32a", + "bdc73e933ef69b6cdad63ea65ead2494d621eb72b2c764ad69d5c6e63ffc7ba4", + "0d2ec379ca3d888b43f4df9f80ca6be295d8825887a258dbca6b9ef54a1a80dd", + "16bd28139f58d48397c26ca3c0501ecca49043e5bf62e16e6ce4c60ad3436bf7", + "897f38b5b842d2603bee38d45911b1b483b115ce918c695833a72b5a90dafd28", + "ffea26c58cc1a96700f72138b4e1817e75d12fff116043ee28724da4242517ea", + "f5841ad44edb5c3e2c8bb7cde1a9e901b9ef6c20e61e16070f9113c000bbc95b", + "f5175ef51d9a12a46e2f7a59b5a5e60b70b011882f2d1dc039e9bafa18c58401", + "35555f27a1a3685e77c55deb96fc7b52cbb5b7b590b074498c496912132ffe36", + "510ea62961e72276dc67bec5ba106185aac6481296d47910040eec8990807036", + "e2ba24156471bfd63e386b2a7417e2fcb0ec6800f2f8d7c7cc889452961d7449", + "0077868aad85f35636b107bbbbf9886b23c7b7e82b31fe33565a7414c3e856da", + "33adf2d16fbc86e47cb5c283ab104af41e422b6f9a421ba0cd9835b26d04f7d0", + "5c47a1e94191e41748639eb6c69fe311184322cb192050e18114d06d7924c30d", + "c1ed09f315f8dd107ee8c17f5c58c3cfc3d519775f9487e8b22c5e8ce651cd5c", + "5809a3fb5416ade7e7b9d81d88111e4ae0daa160bef6493beb16a34dc0615978", + "ffb5a55262c1a2941a1cdad859ee22f98a438a4ab88451ab599e3edb6ace373b", + "23f9d257bbe481bd8c6a0e58027edc70650626d5f09185accc3cb5bb040cc80e", + "7790890e2fb25ab269fba76db0aa26a24e294d6929f07179c305685c2980f745", + "3187d0ae208dc01b52fd362cc001742cc5c558873511fca4102afdc54c1d94d9", + "a099878d84e8c10ce2e3d743f7a2811cea58b3fb217084eec6063032d8771349", + "2bc4a51956af8ff9821d20bcd7ada9a77664fb74479bef062b90fb88f92d6227", + "6b54ee065215620fc5549d4ca4e1993a9df2f0c28937d705426d699b7711b7f4", + "e65f894bb7c004c424c6922e8f0bca279ecd9cb34cea1cdad9a91b2625871d4e", + "904363fd27e60903a4d53efc916b5cca237a8c8bd08c1f7f4da1915048f0b652", + "49820c2dd562db4876552357d1f1ed6ed6f8e0000509d5399ca56b357fbb1a27", + "d524e37ddcbeb497929eec614c1a9f327f8452ab894d0959c9d8e2ac500ce14d", + "0952f89bafde696b4fe5c8a75f7c1553c225b52bcdef2cf7ab037c820858fce2", + "b113efd53d9b5d3e50c07d5fbccd167b5476a5ec23ac4f6578927feb5067a177", + "21d68a3cf4d7f634e1c144efbc3d29a77265a8187a6fdd8bf329f9d268481025", + "2dff7f1a29c81329005e9f9cf4b76166caf9c904a21d3dc4e47b5e4d7e08375d", + "28e4112c066d9388bdd9d0dfffe197da6e4591677f43b1314e1892c76122676f", + "30a72bd5601f21960d8d368fa17231b7689ea20dc94e3e293e68f9b14f12cfc3", + "8acb7817d1449ea0be3383a7702e8283d1c9eba4f264d71a7d27872e00858a8f", + "eccdbfbf3aafabf060cecc7057f5e258d62ed8eea9cf007d70329dc05a578ee1", + "088c1240ead46e737a1f082445c388304fdb4f0c1fda9058966085f79ba850ed", + "eb764b8c119af2770d0912e0c131f0d099c03494c0e079a04a7b882cfeb16860", + "efdbeacd0aab7cd12f93808f522a37e65729936cd4db572b7053a9b776b81173", + "044f0e99968439858f54481050ab7a8b363d71d081be49cff0c124b445a327c5", + "d5d9af22e750397c1c03f656ec70b3420af89df94955752687737ae44f8c9f0c", + "426bd0a139102a0f44cb256c33e77d921378d04942c8768409cfffad5518056e", + "102286212bef0dd6c5cae4dbf9815a826651f2b7bb59da17d67f483983cfd72a", + "01926fa99d93350a356a1dad4d4fe2bf077e3e6159e5f280ee35589ef170c510", + "70a03cc676aecce0c25c0ebabd57f12ef9471222c6f22d5d9ec506f8753c2ce0", + "a5de75d2991393aab613dd2262778ad842fb2cc932d9934bb6453c84cb1f379c", + "941c9eb92674ac3cf9cf42d7ba40af342b97637089f66f1e688f44ff260c2769", + "3ca1e28f48bed0f7cd38894cb23183ef5da794a2e69ff07656e46a0cba7b3a88", + "458f3bce2371c811915ecee6f27ce24863323de899e1173fa18a96a68dc4b260", + "95386e2a7eca44802062adc7d98fc763d4958a4d7e714051fa50739713ab7511", + "be1bb666c96ca62319edc77b5b5d5a555e10373e0947902715a49555ab005240", + "abad0b2eb34da8da808c110dcf6b6578f184295184f7a7bb353928b424450961", + "496d737d296d1574cdd5bc014a813b8b8af2b47a7db96dd23d72c84a203b0336", + "628dea81c58515de150808d70cff929c58906f4e774e0c49106a1ab29d2641a2", + "38d706f7c3afd2c9e0016e3f57001b62f1435a021c100142c68663c0dddf953b", + "571a4533134ec7fac0e1f9e833e6144b2e34150b56ae8da1dd19ab37fe779ace", + "8663d8484578ac33d757401b9eb23fbcaa08d5804fa36b385efe19518ad30f99", + "cc3a2f7991bcb844639b635966ca7cbfe8ad86d8b3b57aca398615c12edc9a26", + "a507756d1609a050cd2d142c264c4ba3dfc03c21dbf9e6a759263fa8c18557f6", + "7e6a1e44f51461ac55e92ec25ae5b0ff4caa6425d47ec632af0ab162be6b0554", + "444bf6b57010a3db6d803ebfba596ea5e0b2b1b786355ade9cd766600daed075", + "a4fa456581a3884b83c3cfa122fd73e55a97be8d0a6cca3566f4a44b0b96ad9e", + "cc56ef95977ec8f2dcf2600495d61ff874437a081ccbdc72e01b0ef99e9f4f6d", + "587bafdb431368468aa1b265786fb365e9e44b75602ef4f541842957e9bf2d9a", + "0fcf175c1adda09f70a216965e5342c160bdc524e70eaae155de57112f150adf", + "1e75da9b421302d412f3a91b0fd9fe008119404c80e3cf7729aac91570da378c", + "62ec5a91fe9c35b9c386d1b2b5adf7ad4d4339a5eebfd91b148e25888cd5448c", + "b8d884fec040e4f9570196af822da28b1d84f3daedd43d4a88e703bc294cdece", + "07b722ed54320a9f1a84d4b64b9d354417a72f21affd61536914a6e3b1e024aa", + "e96e5935c7cd28c7534e07bbabe8460ba36cf3120dc1cec006e0ed3e36430f80", + "04a66d05c7c39476b684738d7442ee028e38ef4c98516938b94773395525c152", + "f9a138d2e3e08f9c65e9c7b04b5a2f4ac44d1eb77096299e70c1dafedf6bdd2e", + "51116940d4c6396f4d1fadadaba9f7a8d996c27e6ffd4d757e026ebbc0a14ee9", + "87f177918fb8d89178ce82f5b9a9d1efb81ee3c2405c45953086b33939390b6a", + "3aacbdb5f169d3b8253a55d7bc8fd4a18bcab6f8b68bda86cfbb5bf09146e10d", + "af343805bc9484cb9063db0fe72657de84ceb05e3b4520442011b82208c032ed", + "266e3657d872923cea0e9540057f81fda3049b0685c14156cd2029ecc9649a11", + "1cb4e76192b76f6bcf51ca5e4d8de7a54148b6261f2e7e23c49b85e79b001657", + "4a54a1ecdb63a787abe10a1c40ad9e24f325e18aab2e790e4764f9bb31b80504", + "b07488631f9e8947eef31e70379e7322048026f0ab1ed11ba2fa1636980672f8", + "39236d6571bd29b0b739f89e26fb22691c3f5cf80f070016bd564d69c8909703", + "fac1eea310ec846017fcecc906d30a743c417bb94609afe87621dde5911bb5d1", + "5d73b0717807762d520725b9f9747859afa76c8b4fff9325cd4632d66e2e736f", + "02862a320812b118a55b8d172225678dd60a82d88f9d06957bac4b751d8b8583", + "4bbb781b63847bc03cae9ac73511a8d1d4360119194fc0772340f0981d7003e4", + "fcacd9c33999a29132d23f61fc24c26f96f453c541ad9b26972466d5516f18da", + "8fc93b10eb923bca9456d681152719f0b902a32ee98d7d0db8ab6f20738e3b8f", + "fea779dcccdc66bc05f372d134191992c7764a51ad1fe8de684f4c43dbe5a2f4", + "469950df474d45eeeb1fd0d9095529a8ce6650e01613c83c128ecee302a9b047", + "d765d9fd507b83886268914fe179869681a68a3e8e1657dad26187d8787254c6", + "bfea913faf9b55151fc631c5ea7df9e0b62be2751411309a7e04ea112e53a643", + "93d442d9b855ce0e2a3ac8f26365dbe57da33d40f0dfb19426d575f208fa4a31", + "2d074524c95ee5527c10de86668e19f156497d778e10f0e2e8a40cf0580da031", + "d933a350ae2e457a413da9c50db85ace1f80c43fdf2b66a79d8cf306c18588f4", + "b1af6fbef276b06dba7e995b98b4eb33184a56bc021f539b4106b3e1386bd3f1", + "95bfba760ec435a0cb9c4224d1e464c8dc9415071e9e46e6cf1cadb6b342738e", + "abdec2484f4633b80de608eda0fc06c395b6534850fdc966082ad0b3ec26f9f2", + "f041d29b059ff60f4c423fcb128172fd6ecd76648083ff5e9348d1367f94be15", + "0019c08b688301617e0411008b8bd8a6f80f5686c4d9d9770e0651bd7619805b", + "aabee513831147c20eb3ea93e37a171c41f54d89d24e8ea4ffe5355ebaec6275", + "474b724eb55b9f3b161a0ed7e7ed48aa64a527907f5368c32938d46b46191384", + "2dfea4b869d4c3532867635d869eb87984f919e9d22fc23cc91e206f65c17025", + "ef343847e1d7e4b7bbc42d8afc6ace7b111fe79bbdf910342db5cb62fab1e8f7", + "de8e2eaae3e0f915d7d294e93df0dac657779eb299d38a37ab6bf80cca146ad1", + "26238a6c3304a0b69c1201fc2ec75b318ee370570c2fcff24508bb2239f064d8", + "4e592748599e9be38f62455200986123a43a3d6ff726c133f83300852f0d87b1", + "58dcc13bc0d67e3625e293a45107993cb68f08ea4b0d660574fe0e0fd0890e30", + "f4ff6e8a27e1dda2547878a2f6a8b8ebffce027410dffa3eedfb96569138741e", + "3193623a6219b88ecd17ad4073c0c441734e201b799db757a99d0f09b2f4b1e9", + "8f59ee334c755843959a1426e776af8c93eb4bd4cc0e52cf0984511d914f60b1", + "488a6b1c1923af71f949cf201ce2b03d0d8728d0d6ce27d8d7278c95a94fce45", + "0460795a6c670ddf1fe5d41c1f9615cb0d4b55be88ea17f6d762c1820c725a12", + "68c7a508ef350df42355f4d4a08f2b627021045c48df935ebb39f64ff728f3fd", + "136f37a9047677447d7651f547936669ce0842cfaa0d8831ff26d9eb74a5cd2d", + "b325d5076fd2591781ff88694f0123320f64b5d6f6bfdcba2887732f24af8844", + "eacb2054bae8a238979893d59d553b3cb33f811c8fbd9dbd73d7454290655aa8", + "8fbed3403b4a1c9972fede99f770dbff2fd538a06493748a9bbfdfb7c32033bf", + "04d8716f25d076712b9643f86ec93d22fa435497750b284ef82a7a5d3c7ce0a9", + "0051380bc9323722534dd2d81a0e704b26e36082587f89e7df80b443f1a19625", + "9bce306b7723f4677694ca0dbc49027f0ba5f10f66bf96f13bebe3a6cf6e3323", + "7f2e8ee98c9366b4a59d46492687dd1fcb2e25bbd72cc86834702bd25eb89857", + "adf4da5f4006135c777ce83a22a31252cc7a4eaed7d5ccd2e348a16d1c5ebc84", + "c66c1a8ae2f555b2e870b99469bf4cf82dab5299b10b57dae63f479056ab1fc5", + "3d0b54d50cce29d02eb5cc85b403ded7043ea968a97b9283af5f04327bf05a30", + "10b63167a2a5270cddba784e246d777b6ac0b898de9572113541ac3e06d62b0a", + "9843403781a386178ec309692386ef8e1a368290facc2b3f313e2472431cf432", + "46b69214e90fbe1a5a692e218487c1160a3e2fab6cb26be61aa2060618e78752", + "2fa2b383608604705fe2b2a8a097b03b82d241fc177dfa3be0ad8a8b35f0b1e7", + "9c6ae4abd91293f10909b471e28bb82d993b3c3e811bae368c3ddffac04cb532", + "976213a1730b21529c730a4db5f450f26cfea307ae281e0cbbd2f481e9fcce29", + "6bf8ae58b8e53200ad0568bf7772897dcad72fd04e85adc95269b227e4a1eb7c", + "a8af0099a7cda7f3d30236f8da71743e5a465f047e29284d70fe578206f51f31", + "e9ab3baaceadafa00a73e0ee77b15125a696f722928a7b412d704d350dedb3d7", + "f0a56578da9b76abed8a54c1f56049e131b8f4e2173b4a1545349c61c9104a6a", + "849e5409fc8d794782d49d9aba7f85ccfd5f22fb4f247b88bbe96e08c2f4eff5", + "d8dda4c363f0ab435f2cf78a76ce5aef3968ae5f3b1c5d63e3b66e277041acc8", + "db029195e50a3eae8357273931523f096bdc89ddc710a6c847463d071435d29c", + "ef0d978904dc652ebccb02ff935573eec10aeac399d576fa0dbb9d04ec346cf7", + "7fee13e89e660028826d7dd02bd6cf43be14b32539d4422e7c77144e2f4849e8", + "706767fdea32a56459ac7a7a64c430faa5b87eaac214b1fecc9d1adfdf06e70b", + "4a3dc9d0ac8090183a164c52ff556f794d79dc47fd31cd37f650133f22d1c7e8", + "74fd8c6bf1e2555a23da814e08e8487fbbccce5ab91fee6f6b49155a5e4aca45", + "87595600f7b9ed134b7375a2ba6036faa0d159f69309be6c828a6354952522ca", + "c0f9a7036d807fed7c4d02d0a7f99369876822cfe0d75629aa03677aa88de77f", + "56a38c2edae3f6469ba76ada80e7df04bbb380abfd884e17b3837b7ea0949574", + "ecd8f0423e3e739426d12f5487e68fa4b8cd91b2592026cefd5635bea00d8fea", + "9e5177eefed3e65330387ed8c4c4f129ec66f61fe1b8b95bd8a03e66110be62e", + "5da66968fa4eb452ef4f329a8027ea5cd9e3aa50f682952ff23c815aa8ad31fe", + "4708388606fd00de412197691d08dd222237a28cab79ddb78eb0fb7f0984db55", + "2e6b528ba6c3b40897134cd233fda0adeecc6e413ed894e93bf36518e3a2797b", + "70937f417f6c42fd810a11d07d659059310c9cd111300729d76a137cd32cf88f", + "2620b753786dd288ccf3b85c55c3b1cfafbc03de8740e39e4da647480cc8f5e9", + "1728180628a51e5711cfeb8122b7cf81c20c0bb237a3921b446a730267fa50d0", + "b900765ff4008199397bc706b8c28341d3146ec183fce1d882087ce025a0f0ab", + "02f53ef00a39d66ddbe58a0f8a22c0917f9b7ad832d5b2f563985e3d5fb6b772", + "ba48d9a2107ecd0bdeafba4fb201c2e5c0af3886bb72a4455ec0ea4b01b7f5ee", + "0754bfdd2c73fcded1a1c929fe07b1f20c341cdc4ace7ca861962aee0b956068", + "8d86525349d42d8e50b93b1337bd8aa1a30730da00117c98ae710f1ef019b0fb", + "f0e5faf3f6f8a90dd91e1cce56269cd458486095384a07264a68ebbaa71d6ab0", + "2ea0196fb31f9887ee3802681f6daea6e9bc7fbb107ee9bebe1480df5f052efa", + "be0aa0571436e4306bb2ab8dc8b5cee996583cbd8a46308b270ed043798b4fc1", + "218619d8699181119025ad9516f2caae5bd0f828770746a98b983c8d74a0a8ad", + "f5c62ec22f3e268d0a797235a07bfba0be38de5a801605dec15644202ca1e4f0", + "0bae62c3adc06299377e670580f5d081661186321656595637d3b605978de71c", + "25887f6c19941b8461a475bc771483f87854d4b521d1dc400c0eff4ddcb16344", + "40413c01bfb8908ff4051b66a7da0dc1c7a87facde877c2ee9a8e7fde50efccd", + "dc38b7cd335f65985efe60aa4c28c9c2b390ab2f8903184ed6c2926736653907", + "5b8826f306d9a65a3a518f85edcc81a3f92ef05c059d93586f8380e2fb2ea71b", + "5874087c2fbe9678b49ed896ba5e715440a766169c9a5a1a0d59bfb8800a8fe5", + "a9538bd63a418b9e23ce3e585848e6f214e2f3ab7824e546bebcb8cd9154f2de", + "280e8f987f28b13d9bbdb9b26de90aaa18cbe0d8941a378f898d6111e70dbe6a", + "2fe408574faf37997c0788bd49091decfeb9d0ef47194e1ead5cbd5049217e1d", + "124e40a9aec82d245497c64b67d0a7d700cec860a4c25564a2dac5ae00c0c2ab", + "708014cdeae14cb812ee67e2ae1c87414dc713a830519fb4378e6ec74290106c", + "c94899bf8baf0f392568beb77b0f5c4feac7c99541341f5b9ccab66634c5658a", + "71b79b32955458a94f0db767e215e3a23e01fb1b32900643769edba273f2f8fc", + "b2247fff8a2d5abb37b10c2af23dc09f1876ef6490911b9fd2807eb45895cfb0", + "4ab051b734a2c1f51d6ee4d9371342111b4998027b113068d25ba60c5f6ec474", + "028d32b13b462789e3a1cf4821690240f68b3feb0ba713cd38e027843259600d", + "f5aa96b6345431924fe70f9c6cba0484c42c8ffdd9ccbe0bb7b1c1d09fc8c6a9", + "c3fb3c59878100e7ce23972090a8e3e0a7a5aff65ed179280b1c76e806af2798", + "594b18754b8c1096b1d9edc5dd096003a2dd230283b64e2fb6d66d0675977b56", + "377be58d955eb520d92b0a0c057b7d2f357bd4a612733ab6ac1d3018acd18bf3", + "0b0908316a58cf1cf5aca1c540aea1067d70c61fd3de00822ff8deadfb6d02ca", + "d71e9dbbfedda7c7441c9b9b1dbd77b39314e6a93765f5410075a4f478281b29", + "ef103a1af57f8cacd1a7fc69018a601b22589244ccebee4cf68dad2d728812e4", + "ead7e91d93c2053c4bb01206cfbbc190f051609fe0a6095eeeaaf44f705793d4", + "6ad99c2880adaf95807d38d29ad0e2c2b7dcc03f3c91aa160d204ad7582f7070", + "6fe2c2a44ed96f226097e3b8aeee0d231558e06f195167190f81bcbfa8058f78", + "495b092745509a1eda65f1fcdc8ed14b789c652a892740df4db0a31d1235d43d", + "45f2da83f06814d1e1613f87bf3d93ffbdb23ed74b8f9bb7669cb2903db96ed6", + "064a4edee98134061e2129a9e34e8efe5194edffe1ed06cbd901509da9b73fc9", + "93d7984c1a186dca7d0cae4775e7913b1e4462206b8246baafe2fbbfeccb256e", + "2430212116063044c1302b514d9860bccd6cf458e96bbd7d56cca6bc8abc2d25", + "43ea27ab5761897381a5c27c83694428cc12e05f5a7e00ee582bf61efeea452b", + "dd10020ff53c98b67322eded586bf2e71bda58181505c2e1d2944da420f7fe9d", + "25b136e862900545fa4587835c1cdad3370d811d9ce8edc2a1e08802011f70c1", + "3cf2cc141520eb6822620f4405bae45aaca966c6b715d0a40d6d31dcaa828e18", + "925417708d6b7beed3d95dbaa11e9950314978704380fbb269873ba0f1ecf474", + "c3f3227ce1e50756cd39aa9a7e1f75a497deb4ac20bc0f07acc830340f1a7e1c", + "2f653b7bfa488709aed7473d4008625532181bf408f2504a034befb211c12662", + "6480109e6b86d33a8795b653b0b0e71150b22177d2a2c558bfcbd6f7a25388e2", + "af2dcd97d56c3d57963d8294f11f715b75ceb3876036236b3cedd43c9a60bb86", + "46a2b74bbc59a68697b2574e0d4f50d6678dc7bee3b49fc09b43e1cb24e467ca", + "deb1e81ed62ca851ee36eb977713f7aac476f710874830a1e9ff0f8f80c04b68", + "8f6af38bcd117f5585d23e46acad695c857b5596a2068b076b528687c5048ab0", + "b7f39fd2d730972a4970695bac43c9721f0dbe1cb14eba288724c8d5287140d6", + "da208ec56e99fc65fe50189ac86104f2476f3f58fd944c8d3a8bebf23ff1eabe", + "19326b12cad83b2fe23e999a936556d91b5cdb20afec5d42535519722f642aa5", + "e110606d4e84ea6a32481b8ed8dd5aaf8509091dc5be79ebe9eb0b5af9b7d089", + "c89c39e7787d9ee48f7314b71318861b6d33c404b277f41558678a3cf90473aa", + "d60d0b4769b3d897ed0a47df26e213a9b33757965009458152448eda5ca5e5e8", + "f1ac59c16d039182cbb01471feb7cf7e39535591eb107c6f3fa968c584336de9", + "a6ec1167e8ee0bd6ef9e815b99e615c8ada3d8220ef7f8f1a71480003d0aba04", + "912017a9ed2d8c58b75019d4a952c14412426a3007de3c1d36a113c2668d802d", + "432ca8ba80f4a24e29d6df9081e7a0f9d34123e8e90052e9a85b518439ed0f84", + "cae9de334fac383de86aa0cd021606abd2947f6194f0ce83a09b9c636883565d", + "76e442c5c4de4a5a0fb314c34d58a20d5d08a8407c2fccfddedeec2d303b7a0c", + "8949df38e8b46050242f4e3da510c4116a3db1f72a7097ef9496fe7f18d53eac", + "7df80949f939a5464718f7971d40b030cd0049249d80178d58c6629bd77ea614", + "f60e0cb3a40c800ca9f49f4a4d8cb84e8b277652589b9c06340830fcba97dd58", + "0f70b4cc79edab5348adeaf9337125340139c8ba8e4c0d60d877ab04b16232c3", + "553fdbac781133723ebf1509ebfadc32de490416383aef2091b1555aeaeda33b", + "2035a11c0a621c83f28dece1250f9e38a4175750108511752f42fdc102bce983", + "8fcdff28c6c339c24c02210fc1ffd0f066bd51ab7801597ae7c3dee57ad96a78", + "bbb2e73f498ccc69e48dd2aa0113620210f96e489ba4d6008d72dbaacac81c92", + "d27d2ca03324a4c3477a7d99e16a21c890338504bc8177eda8aaffb38b989a2f", + "4a1d88e924e9e94214a625e0a215f98c3a2481c655c6228dd477a82969be410e", + "422ce906845130c4e68b971611c5fc1c233a6f655b827b4daade25c1bd5b32bb", + "d741d48fbfc818da632df204d092be8a7f9f53c31e5b54f7f5755f6a47f2f87b", + "5be7b0c5bf2609c99e353579bf230a2935aaa6be68af939eab9d729848c8dc09", + "a41e6aa256aba8f9bcfaa02eab7f50cc59196ca6ac180765550c1dca5b5b69c0", + "577d5f9d9587105a1588a4f0158dfaf73bd98a60aef579169b3242048bd48386", + "6c961f4790ed6b3868a63c9bae6ea5a13ee99b90d137499d009a06ff80d7eb1d", + "d218af10ad7afd6dc734dcf576444303ca36db114a64c59448a3208143bfc17f", + "f113ea7121daea200ed3fb9ac55b819a6202cc35b7e2fea3c952daa571c6fef6", + "71d046d5449109f135cc5485bb713dc27df6028de3d6622b171fec6514493cc4", + "e34ca1ac3d155a4b419a43bb9083ffc07faf8ca9c7f3483268beafb88f710dbb", + "392b633b573c7f428d8a2399e4c7c06366f5eee328a680b0e8faa44cd43de8a6", + "fd565f8348218b7aa1b1b758ad206d64d2158a7aeb234ad2a9e34ac18cf65ec6", + "97c8088398e1e322586e23751d4d73198c2c21078f0234d043de3f12156e8e97", + "33d9b5bcf811f4e72c3a6ad2f33c8f8c27ab0f57595faa3730c8c2ef975758b2", + "cb24ddc1a092be92aa3cba55dba6041df48720001e4198659ee82ee4357d7c0b", + "cbd6810bf626e70db5f41fb0bb9bb987e44ed8fb33c863dba4169bb9255fd5bc", + "7485e599b713eec84f06e13960b6210417097c03727fd917f4a1acde7c70d735", + "535e5ce8f534c72d199e14806caa3215be3853518cad7232c3043f99222b370b", } -const mainnetPreverifiedHeight uint64 = 14121408 +const mainnetPreverifiedHeight uint64 = 14178240 diff --git a/turbo/stages/headerdownload/preverified_hashes_ropsten.go b/turbo/stages/headerdownload/preverified_hashes_ropsten.go index 16f5df1ba5c..9920dd33435 100644 --- a/turbo/stages/headerdownload/preverified_hashes_ropsten.go +++ b/turbo/stages/headerdownload/preverified_hashes_ropsten.go @@ -62027,6 +62027,193 @@ var ropstenPreverifiedHashes = []string{ "389f32e0e5a0a9b46a37da99be4576436d6dd4f23fde196f44119ee15e79b49b", "c5ae9f7e0aa75727161e3c06542631796e13c8f59ec4cf19814031c05ce30c2e", "3cc61d22b6cee76b063bb7562b1d4536a17b88e50e750f59a26bad5d6d287dec", + "52e46038cfb54783174556908ce3a95fff859d105f004a593cfefd6419056427", + "44e76f2be25549ee8769cd98c633ccebad9a81dcecf6458c6f370510ae6c731b", + "55bca3acecc987e3ef0a5548480579d3a06f7e683088c08b8cf35e392deef94c", + "9d0b5069bc751d64ba4fdafbe8f5918b1298022d79a924c5acde2af7192cab73", + "b10c0a36ee6da5836dde029ddbd8f94cb90f27285a2f67bf1cd706fdbbc201d3", + "0f876f0265a37f0ca786f9766c6716f2c30923f7e23abd99ca6a0c78a9ca5f60", + "9330fd5be5b831c79d1464564693bb77328e86233a4fe4b5a3fdbbd4e21dc638", + "1e6a19e54bd6f5483dcd10939749a56a44e2c30810fecad29f7b4397ecf0f41b", + "2e17ed325f724c70671592cb88436af9a7eff9444c46338d08c5e1f850c21279", + "1be2f58f42ff2c420a1b4a5996b9f0c5099c1af21801f0dacf456d5a77c47b10", + "5c1c202f3849ab46d10c8604bdd3ed90ce60a947f3602b085194c74ff22a9d25", + "e9710be49e78299064665dc38fadabcf40c36e6575589fcda9f100fd88c8e170", + "eedf2d00cfd452b21e6ec491a3c5ed8cbc65a801ca67938601be475fe4ed6086", + "8e38c5959ba781bc7a04fff79261f83739cf51f4250f1d4fac17ca946b5fdfdf", + "697eef19f94489648e1aeacdda70b345398782cd0ca74a7b8f2b1134a95c3edb", + "58dca304d6fec23de9a72c0bbc504c78df28722e7d13ec43ed771291b398d948", + "ab2809a3ba689436d404869515873085a286e13e9f7f05026fc4bdac35d5850f", + "4b8c423d6f5e178dbd9f62fda03d4db773a2bcb01d0794c46ea7bb7f06b14bcc", + "3b1fe0e727869ac6b74a957443cb860a74d728bb2b0a20359859b57abd3d86d8", + "cb40248d24fce20cf152d30a5d24773dfd8e50ab92752f00aa7dd35fd855201a", + "55844cf20dd61b05f592597f54120d81b84d3e121936fb9a084a89e1be3f6639", + "b393f7b6129d33533b3667be11aa2bc0bd0451c14afa1309a36c793eb207a847", + "f501741d002d91d567bf0d1ab6c41c8a6b919c1d07104c326597f57222b45745", + "a6d07f4e78ca550470d83a99349707f19026ef1e04f1de1a532818bce5f7b3e2", + "8b8c184164468bec407a39e6c2e3e492ae5e95827c94813ad4b57be57b760571", + "350d424ffb7cb1dceb1ae9b2264354b100a02a2f53e6dd08bdd68e9d248c0826", + "cf5434cbbe30f954f482d93cda9bf7d22eb93ff13a4c9acf271dd66868683e06", + "0cd31f5ec53be2692149da3a31abe495af46b2c41cb05840cc564d50fb3db8be", + "a2401e2b168dbfe6014e0ae285d6b28a018442c080ed37f4dac4560dd2b3e951", + "128a1e2f03209e3e466d00791b20cc6c6ac447c8a1faeb9dde48da3b55247f7b", + "96e31cc50735cfab27b7d11ed8dc0364be47a9d06d5c28f0855443e90e0a092e", + "57d91101eb706178272048642c10f2cf1fbf4ca7989ee1810c8ea656b9ffb4a2", + "ee09f27c429e81e95303b09110de628752a09c3e8f465c5f882ca1f8c7667138", + "630ec07fddf62aad110f1a9355465310277a0a0f1a2f8aba8435030bd74db86f", + "dbd26589531d963c0c5802928537a2c8846f413552bbf4f40a0b2f3d45711b9d", + "0ff777b6f73b00c0af54b4e39985339d43aa7367100c4434c1cec8e844de481c", + "c2058270f0a5ab9e1771299c098db1c5db9132a045e3625622742a9932cda5e3", + "1fedc8272ae9fae0faabafdf441866941ffc8f5585e6ec2eb618a57a93132076", + "bf6f567331089e02f5b0848895757dbfda999d3678484afce610fb76b3737a7a", + "c97f18fd475f01692a3b945400671383ed8bc484f0adf32dde1e07896a5e5240", + "ebb2ff3946190e230fbc103e78e77b7b347c1b54b7381f81f9f01430d0b6c73f", + "5a5ff63f3e78c4779f47f0b273b798de692cf37239cd6fc73bf0e0df10947789", + "76fefc4f66d0bbf343a62f0a01c000b3d241372ba32924dad7221a1bb5959cd1", + "ec5e4cc26b98c4deef983b8dc41fd0bc124500efbe9c5ebeb1d592c899e52407", + "793b63682f71a01ba6a119d908c516a56fbd6d9a57dca5343f49a7b44a133245", + "fcf4a84885310f92aad5ad6a427d9d679530fe6bb69065136d372a57e06a1831", + "6eb9e3a10fc8136178afc4203d8bbe6f3d59e46fa344ef0987c6c1b42271c6ef", + "0d189287e138b357a3d4b0c59f4c99d791e018ab609a51af4615343d63d04757", + "2a5fb5bf2261172b84871e04871d5fead598aca249fc92871d08a936eddc88c3", + "bc31f83b1dd3d0d64960758920a4ca61f15fbd41033dcf39821d8aaba8799732", + "ed80b34977c4c4b54beece49ae6604b05d2c9e47a359fe903ec3d1f8b4c59e0f", + "54b10adfeb958c4a67a3145474220ea2dff0091c7bc8f1d90faa9cd865e4c1a9", + "db563f1b06ad2de40b0bdd184204a4039fe4b6cd5a96fa914c8d165de7a5eadc", + "8a971796dc5212d9b621aede9c8266fe814253b8289a25ddf3621e63121749aa", + "21d040cce8af1fb1b69ff8cea4ed95ef04aa0f3ce74b04d54f4c7b7bd2563858", + "12775160864c3abeb2c1ff93e155bdfcc3fc3cf3f51608ed6a078dc192d083af", + "87299c06fb3f5169b88d0b9ec7a0e826c6821de357229216fa523de2f1f5063c", + "f1e7656a9dbf55154392bfeca3dbb10982525acc568f5f05ad5d7ba0f8848a0a", + "6a874de8badecf77a735f93b391ca18462e7f5f52ddef6cacd174b8bba8f77be", + "b61315a14978043a1a43170c0609b73068c3d73b114be19b1ead2ab1a4728a96", + "47547165e1fb7c66bb5be40dc3067fbd0a9eb3884f03bb6e639e1b1eaf1c1fb7", + "3bc2ffc75dccc0338c393a8d215d505099ac8a319355cc570ea006bcd7c3418b", + "3e0829b1370881861e2e3662900b87b4c029d100b8da4bd0d712f8e3923c78dc", + "798eeb8347fc53273c929c0f87d1158c7484b8696e2a036364cdfc4b52305d3d", + "c8348076e525e9d008ac7740c209da549400bfd354db3d0a3e85558e23f88b10", + "ff4b31dcc0891e21ca54fd222563deebc98365bd704d8e9900dc8cf8e1f03c33", + "e68765ddc792b5c1e4f6355114c4a2b1cafa0fc638fd13052ec21bb671ede66e", + "2d6d1b5c7bb3a991d590ee2aab0cd435cc77023376c6eb87a511413d082ab293", + "6a199bb02340f776e2c1ffb00e5bae08bf939858d85c6ee53a0ed73f8e65229f", + "dfbbc39fd8d79f669850399451c438f5665e01ce2b5e0b261b29d3b5b49fbd2d", + "5de8be883ba15ad2f2f7d7b3564911c8cc237e38adca35d6a898b4645d5a1103", + "3dc9643b1cc4e8cdb1426899f36c0747e4238911306c8b197d89d58e1698279e", + "1450196f6935445ebf95dfd4965c9340eb082ab722306c3cf308f73a48a4388f", + "d62a0962d48321117c22b997a1414105f4f6994a641301f48f2a240c89ddb990", + "510f844b82d633edb8bbc36342de90712dacf1b6f0f1ccbec6be7e13ca6b8c58", + "e628acd33722a1c302e5ad83c62fa6b607cd0f86f9a795bf09bb1efee76a2d95", + "eea497c1e8d3f04e62c1c531cb308041263ad27f18794aea6fc77714a2babf5d", + "2e429b4461177ceaa65ead91ffc78f6ce4755b36835867a33c036562a4f80b6f", + "d85bc8e44a54c24a38bd03dbb6ef7d178cfc0958f6e96faf3f1c88539391f2fd", + "b33b481c72ece138a1fa268a00466add4ea5d92734fc2155f7bd07dc5bc8885f", + "594da66a223d2991815c66891a1962dfeeb74f9d74c0a604f98c77529c093db3", + "675c87322409215659543ea976c006b62909927fcf5c8865372807a44b3c7ae7", + "18e8e2f793c3fbc2b59dc3d50c6b6b0ef849e62070957af148f328bd3fe863b2", + "4049dbf12477fea148c1aaea97985a73c55689abc413e2a8cb8d395abba6dfcb", + "0dc4bd12ea25cd0e1369b610c3099e979e7538a1875e1a4710d785aa4be89888", + "8f79c26a27e3c3427a889bda3407e28d4be0e10be0420c7af9180ee5c741442e", + "0085608c987b1795c14ce9ee1814487816c5a5b6f630b11018b3decb96dc2877", + "6775f8f3fd1b1efa08d32c9da1e2274dcd6bd0f78a2554cac6ed69a0d75f65b6", + "a2d51939a7608943a11d17c9f6280e0401dc4e3b1dced1631506250d24fb76de", + "b2a5ab7bed80d3b454cae217053d97270d797027c73ade786c0e607de4521517", + "c37127f2c0db2e851905463b8cdc1f8579ef4d3aad592dec610ebc8e305cf59b", + "b08e41dbcfdc0fc6031cf25e190846ee69e8d71b8f6de8ab18096f461335e25a", + "73202a95acb1aa789ac82072b047fc29c21d8dd2b7233f99865b3ea3d033bd75", + "e2ec4b58d288dfdeb54e2e405e9f6230f75f9b9713acea7a92710b81499ba7cb", + "037a895faeba6e6e6188389cb82041d232dcf05adddbf1654724bbe63249a442", + "da3d18d71fce31e7d2f57c8284733a5645dee6a96c30109026a86c98917ab1eb", + "795e17a1ffb467c68433a0ce488e5752fb0859e864a43bf8a7fe6fe9aa534a3d", + "fa77c480c96f48776139df5bc4cfac604a683770a12a6294dfdae76eb18ca16f", + "87ed3f4e409be75032023260ddb80bfcdfc68bb500b2f3f03e6d33328749d01c", + "18e075bd0a452fc1520bc2813b3fcbb02647feaf5a39f2c9a9e103fa0fbfabf4", + "e9e71a5f43bbaaff671c5cca9de47e6a79d954ffc59e011b990c1af3303c0af1", + "4d697eb3a91879e3d110b84003f694f2f52d39c041ec1ca44331e631b060e7bc", + "56a4a78739b1687101429222f0f1f9dd97eb44b0fd72f4dd6b02bac356a7fbf6", + "99801f755b9869eda72ecc80d0893210035746c1ae1932cff8ff958d976e9150", + "26884b376cb098572eeca77f93dcb56cd0124cfee102598494028eed3ce82e3b", + "fbc2c2ccf28a305d47fb9fbf92e1a48fbeb15a4670de9dcbb47fa42ac20e18a0", + "6776198f3c002140e70ce6f8456de3ff39e74c0c277fe41cbbe075ec77579443", + "a287f55b65a5ed01c86178200f0455fef22a749d2841d70ea9f864dd079d3732", + "8d3cc1fee7570a13c4af9a2e764b2884a1c469d4f6816f4481a6dce1cddff380", + "274107897c1c10253faa717f546a2ea045a54233ccae2ba4e6cf3ce0e21b3014", + "a8084b727e02add1f551ed2e19a935ea632d00224dd33c9fd354ab2b33912d7a", + "f0a7165360faedc0b96837363faafd4ced3f2971d5495626d23130af7fccde0a", + "7b7f4ed498a8065ae3359d4150c13ccf36cc1b7f2f8bf0d399564bf3c97a4d18", + "243a66716a9e1a04283fb2775cd7f4a2343df2585f4a87bd01606c2dc8003962", + "04cba4e1caa5a101a7b263be3ea7ec198cdd5e812e9ef97cb63bb017369b9bd0", + "50d1babca8571546f344737d435b2c646254330a2067be8db4b20c627bb5b527", + "3e36e2ff4a710a59b8437d10f48e41ecc3f936e16837ac3688af7214604a4bf7", + "7e6d4146259a1b4d2c45796fca29dbb98d25d4889771fb09b2d751e59e6bcfe9", + "81a69ec28ce4dd657fb2ae4416223d769144f3d50f2c18df84514590d3d66eb2", + "7a3c0b09d635c99cda654ae9f9556206c79cdf03843b892481c5660f89129898", + "f0ef376837e25d54b7690c2ea00063163907a0524753abf46d03c971eea9570e", + "77ce101d7745243a4b9fab12a7739ea61adc3c4e906f1e6e1082d55e7ac14b27", + "8d668aa90f2d66855a61fbc2cc5bba428bb5e1927997bc4e84d0006a5f0110ec", + "92b28adfab8114da36c338ac3ba24298dccddc2e07248e4375e1e9286577557b", + "e9fba1e541bba3b5d0e8a9be2130a8cc49d1b4717a9cea5443dd771f31ff1637", + "8bece4d34003cf7db0d5b59dfdd09cb8ba2dd1f35cba1b684725b8bdec413db3", + "7af09d04ac7ade4da5b73550ed9891d0d65b1c018314d7803b3b250241e28781", + "21004747f5672c35c249437a893e3c36f19f0ef95dcbe60fa8637ede7d0beeb5", + "c571174ee6d9583f249827c9e206757e58a0c8ce26f45bd048b25925a8bf4554", + "714be48c5ab22c700dd67ffbee42ac74899e76c0b2a0663f2af28258b867e60c", + "ea78d8dd7102c72dc81aa2db6224cd0ac36783e704f9a74259d95cb50a4265a5", + "343c2346bf5a257516631236c7551c14a6b2871ff3e416732abfb5b41f13f4d8", + "7042ab48dc4b2fbc1d98443409c9325754b5d7e1464617ccd39291ee758da448", + "732c67dc88155e813729dccfcf41485842e67ec438be2c6a2a379034ccbcd826", + "3feb01ad39694db6c5a51f3e7db10f82ce548d6f1989feb076a6a60280157b2e", + "7cfb29fb06d39d1c9844399ffd3b27e2b0672b206a0f870e1715469728908840", + "b4ba0acc841b9bbd00555f9d3b2c4f1a4ea73886307e0f64b0ae6ebebda4a0eb", + "c25c4526bff46494347c65a87f9a526c44bbf985175a3c836da8cb8db614deb0", + "cc7699d7b54819f91ba763120e6d9a225aeff6796dc4f8e5d98c2c4eb06b0e5b", + "0d928b0fff7cc331a8628b28f1a2f279de13f6896c64907aacd2b2abef6b98a2", + "8211ad73b07796fb7e4577bf94bacd2b657c9bfaa0bd8651eefe126445b49bd4", + "084590bc568746d61dc0d7f019fbb01540b4d1cd1b0243fe14670de01c4f0b77", + "57d63cdee38572fb4953df6c0d2f15f502b6feadafe8ecab146e64d3dee3ba79", + "2640e61bd21ceafab06b0623c318d8e17450cb8ac906d690093a59623f97b029", + "f4fd6552f5c5214475299496d72cc313b399c7675b664a4ab3d251de9030e1f4", + "9264e960d1924415b55a439ca1d1e6cf95eb91a68a241a93067d64f940c01159", + "f126d69a96d472ba29578ac07f0f07604d4b2b72ae8418a32d579b95eb7dd03d", + "d66414104b9d84f872fbe1a8a20b6977efa21273a2a407a5da345bf726c8ce2f", + "69ffb3e0b257957fcc9e04f2986af240aa47ef6d9dbdc5373775d40da79f47ae", + "465665eaecac0a02de9d470dc46c6e1dcc0bae737af9620772c6d9b8b218e6e5", + "1faadfa93a94fd8eaee1718c2ef23d85996f3ab46a8523e65ba7b10bea759f9f", + "a346053767e34e118d45e8374970f91d488129341a39ed9ce9c9f02bddbcca96", + "9c8dc0c7146fd44f3082f509c83594eb70cd4fff4549b75fef571d97e80d4f15", + "97b6cde5f25c8c993637452b360e62da9db60cf7a74a0b3eb8c108564e1f6f89", + "d50362a94a7ca5ffb9288bd220c381b6fcc98a99bf5b25d01131209ea48b491a", + "587cb796890f176324de06d5d756e453c0cdcbdc666d6cefdefe56c985a32a65", + "2cec781ca4cb7004e17e579d509c17b627ceda9937f045505abb9a774d3d8de1", + "13a683cf8253bfac26e3c6315bf2a58cde32185a615821cf8f731cb3f271ebfd", + "3c0d1a6c77e350ffa0a8c6521d6e84ade87bc7488f7064259cad3c753c1d47a2", + "81080c01ae1cb0f95c7241079f64abd50083ac930c64af18ad7912150eb92a17", + "285d6a15d79c9e078bf213fce0cc1852ebdb8394b5a74b134744190eb481be22", + "27cb849f8bdcacc2d8061699b5edbb49c9fd1441c86cec8cb8cf00c9d5501f3d", + "36b085e0231cfb1b976d13aab35f0f8ccd9c94f3c5eb39ada49fff95f3194917", + "0f923bbc6c8d2965ce4dbe17691ad1f7a083731f4475002ca68ce6bb740e45fd", + "856542ee2c3cfef5ffa270dd1877606f84362b3512f6b7ecf5af2a47575a957f", + "00a04e86eaef5f713e939a9073cecb9f19ce727db2a0ad4f6da3580baff2a252", + "b344d4b4f48fdd3375c0b871e7a15afc738e009f48407eafac2e0795c8a4b1e6", + "d17a831f7dd29660f937623e316021d039b3ad488f9f27440d096a0ec091577e", + "ed81e6079fadd320eedfe11f32871a0f9aa969409ded8d785b07128b64076eab", + "24021a581da258bc8c617e6dfc68e17e6c9a33eded31ce3425a12ae1448e4b90", + "743fdf3054fdbbe9152cd35b4f21918b2c55f6cb5d5f52387797a777c767e095", + "58569de56bb59314357f8bb4b9be1815f1b48de84160cd7dd1ca292808352e11", + "8090a424a97380200309c998316f0b8faefa27dce416efdda2d2dd64a8d528b8", + "626f46fe3b876bfa64c2f2989683222964a7d94ca8cb83249d49e14c4b419d08", + "c11c6f6b34b288ffd40b51f91b662fd5a76e064317dc222cd051ba35fec5d538", + "913b8a528cee3c62787f0867f6baae014f8f595bc110df4762fdacb037671366", + "411807b405a2466f98e1f584c3edbe5a8793e8c7a5c684019cb9bb54ca4b647e", + "24beb7acecb0a3003909115c94ee7fbfef74260123c1fbc2792dbd1e563a9652", + "643b167b97a8c3516b93a455ea5ff12bb6f12c5684067767ef3ab17ccff9e55d", + "61d3ba67f0f260a8ef8ec37bff9c8fb7e8f0f89a975da029545afaca688feadc", + "463347418fd8f94e3d73b5c0df87a98a3195a08d2b85c5b7ca1610866647db56", + "dae6b38c31dc8d0f66b32f9f601e60024c43ad894f82ea5c57bd8dd1d774b356", + "4bf979d128417367df1782f0da39d36acc4e3bc22c9a486d8f6ab59519d31aad", + "21154da8cc7623f1466b8c209e3e33c5da711be33144e40f2a3314b66deacc55", + "dafe61b81f4b505ace111a0d7c194ddf0db09fa5655124842a14d31d3a94b313", + "9e1b6147f22653de017e726b1206da2bfa6dd8f44d64e35df08b853c140c3009", + "5ad2411e83feda15df68a503d9e27de3518cd5e1a74d56add8d9da6de4bd74be", } -const ropstenPreverifiedHeight uint64 = 11908800 +const ropstenPreverifiedHeight uint64 = 11944704 From 6658b64c04eed05ec25af89a16a1b39bc6f481a5 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Thu, 10 Feb 2022 17:00:51 +0000 Subject: [PATCH 158/261] [WIP] Adding Support for Sepolia (#3462) (#3473) * [WIP] Adding Sepolia * Fix formatting * Added Timestamp to Sepolia genesis * update config * fixed formating Co-authored-by: Jared Doro <56698307+DockBoss@users.noreply.github.com> --- cmd/integration/commands/stages.go | 3 ++ cmd/sentry/download/sentry.go | 2 ++ cmd/utils/flags.go | 15 +++++++++- core/allocs/sepolia.json | 47 ++++++++++++++++++++++++++++++ core/genesis.go | 15 ++++++++++ params/bootnodes.go | 9 ++++++ params/config.go | 23 +++++++++++++++ turbo/node/node.go | 3 ++ 8 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 core/allocs/sepolia.json diff --git a/cmd/integration/commands/stages.go b/cmd/integration/commands/stages.go index 8027683579a..8f06bb4680d 100644 --- a/cmd/integration/commands/stages.go +++ b/cmd/integration/commands/stages.go @@ -995,6 +995,9 @@ func byChain() (*core.Genesis, *params.ChainConfig) { case "", params.MainnetChainName: chainConfig = params.MainnetChainConfig genesis = core.DefaultGenesisBlock() + case params.SepoliaChainName: + chainConfig = params.SepoliaChainConfig + genesis = core.DefaultSepoliaGenesisBlock() case params.RopstenChainName: chainConfig = params.RopstenChainConfig genesis = core.DefaultRopstenGenesisBlock() diff --git a/cmd/sentry/download/sentry.go b/cmd/sentry/download/sentry.go index eb091be6615..1ce4e546bbd 100644 --- a/cmd/sentry/download/sentry.go +++ b/cmd/sentry/download/sentry.go @@ -161,6 +161,8 @@ func makeP2PServer( switch genesisHash { case params.MainnetGenesisHash: urls = params.MainnetBootnodes + case params.SepoliaGenesisHash: + urls = params.SepoliaBootnodes case params.RopstenGenesisHash: urls = params.RopstenBootnodes case params.GoerliGenesisHash: diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 3a462e8cf24..e58ec46ae0c 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -600,6 +600,8 @@ func setBootstrapNodes(ctx *cli.Context, cfg *p2p.Config) { } else { chain := ctx.GlobalString(ChainFlag.Name) switch chain { + case params.SepoliaChainName: + urls = params.SepoliaBootnodes case params.RopstenChainName: urls = params.RopstenBootnodes case params.RinkebyChainName: @@ -631,9 +633,10 @@ func setBootstrapNodesV5(ctx *cli.Context, cfg *p2p.Config) { if ctx.GlobalIsSet(BootnodesFlag.Name) { urls = SplitAndTrim(ctx.GlobalString(BootnodesFlag.Name)) } else { - chain := ctx.GlobalString(ChainFlag.Name) switch chain { + case params.SepoliaChainName: + urls = params.SepoliaBootnodes case params.RopstenChainName: urls = params.RopstenBootnodes case params.RinkebyChainName: @@ -916,6 +919,8 @@ func DataDirForNetwork(datadir string, network string) string { return filepath.Join(datadir, "kovan") case params.FermionChainName: return filepath.Join(datadir, "fermion") + case params.SepoliaChainName: + return filepath.Join(datadir, "sepolia") default: return datadir } @@ -1264,6 +1269,12 @@ func SetEthConfig(ctx *cli.Context, nodeConfig *node.Config, cfg *ethconfig.Conf } cfg.Genesis = core.DefaultGenesisBlock() SetDNSDiscoveryDefaults(cfg, params.MainnetGenesisHash) + case params.SepoliaChainName: + if !ctx.GlobalIsSet(NetworkIdFlag.Name) { + cfg.NetworkID = 11155111 + } + cfg.Genesis = core.DefaultSepoliaGenesisBlock() + SetDNSDiscoveryDefaults(cfg, params.SepoliaGenesisHash) case params.RopstenChainName: if !ctx.GlobalIsSet(NetworkIdFlag.Name) { cfg.NetworkID = 3 @@ -1366,6 +1377,8 @@ func MakeGenesis(ctx *cli.Context) *core.Genesis { var genesis *core.Genesis chain := ctx.GlobalString(ChainFlag.Name) switch chain { + case params.SepoliaChainName: + genesis = core.DefaultSepoliaGenesisBlock() case params.RopstenChainName: genesis = core.DefaultRopstenGenesisBlock() case params.RinkebyChainName: diff --git a/core/allocs/sepolia.json b/core/allocs/sepolia.json new file mode 100644 index 00000000000..e3d1af45ce9 --- /dev/null +++ b/core/allocs/sepolia.json @@ -0,0 +1,47 @@ +{ + "0xa2A6d93439144FFE4D27c9E088dCD8b783946263": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0xBc11295936Aa79d594139de1B2e12629414F3BDB": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x7cF5b79bfe291A67AB02b393E456cCc4c266F753": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0xaaec86394441f915bce3e6ab399977e9906f3b69": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0xF47CaE1CF79ca6758Bfc787dbD21E6bdBe7112B8": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0xd7eDDB78ED295B3C9629240E8924fb8D8874ddD8": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x8b7F0977Bb4f0fBE7076FA22bC24acA043583F5e": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0xe2e2659028143784d557bcec6ff3a0721048880a": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0xd9a5179f091d85051d3c982785efd1455cec8699": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0xbeef32ca5b9a198d27B4e02F4c70439fE60356Cf": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x0000006916a87b82333f4245046623b23794c65c": { + "balance": "0x84595161401484A000000" + }, + "0xb21c33de1fab3fa15499c62b59fe0cc3250020d1": { + "balance": "0x52B7D2DCC80CD2E4000000" + }, + "0x10F5d45854e038071485AC9e402308cF80D2d2fE": { + "balance": "0x52B7D2DCC80CD2E4000000" + }, + "0xd7d76c58b3a519e9fA6Cc4D22dC017259BC49F1E": { + "balance": "0x52B7D2DCC80CD2E4000000" + }, + "0x799D329e5f583419167cD722962485926E338F4a": { + "balance": "0xDE0B6B3A7640000" + } +} \ No newline at end of file diff --git a/core/genesis.go b/core/genesis.go index b252187befd..a01d2414f58 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -281,6 +281,8 @@ func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig { return g.Config case ghash == params.MainnetGenesisHash: return params.MainnetChainConfig + case ghash == params.SepoliaGenesisHash: + return params.SepoliaChainConfig case ghash == params.RopstenGenesisHash: return params.RopstenChainConfig case ghash == params.RinkebyGenesisHash: @@ -521,6 +523,19 @@ func DefaultGenesisBlock() *Genesis { } } +//DefaultSepoliaGenesisBlock returns the Sepolia network genesis block. +func DefaultSepoliaGenesisBlock() *Genesis { + return &Genesis{ + Config: params.SepoliaChainConfig, + Nonce: 0, + ExtraData: []byte("Sepolia, Athens, Attica, Greece!"), + GasLimit: 30000000, + Difficulty: big.NewInt(131072), + Timestamp: 1633267481, + Alloc: readPrealloc("allocs/sepolia.json"), + } +} + // DefaultRopstenGenesisBlock returns the Ropsten network genesis block. func DefaultRopstenGenesisBlock() *Genesis { return &Genesis{ diff --git a/params/bootnodes.go b/params/bootnodes.go index d7d0925a758..4518a695833 100644 --- a/params/bootnodes.go +++ b/params/bootnodes.go @@ -32,6 +32,13 @@ var MainnetBootnodes = []string{ "enode://5d6d7cd20d6da4bb83a1d28cadb5d409b64edf314c0335df658c1a54e32c7c4a7ab7823d57c39b6a757556e68ff1df17c748b698544a55cb488b52479a92b60f@104.42.217.25:30303", // bootnode-azure-westus-001 } +// SepoliaBootnodes are the enode URLs of the P2P bootstrap nodes running on the +// Sepolia test network. +var SepoliaBootnodes = []string{ + "enode://7c9740e4d64674801fe62b76798d46778a038c49caebb15843d8c0f2b2f80d7ceba2585b4be366e6161988f81ddcfcd6fca98b5da52ae9a6f22c1b2a84b24a04@18.130.169.73:30303", + "enode://ec66ddcf1a974950bd4c782789a7e04f8aa7110a72569b6e65fcd51e937e74eed303b1ea734e4d19cfaec9fbff9b6ee65bf31dcb50ba79acce9dd63a6aca61c7@52.14.151.177:30303", +} + // RopstenBootnodes are the enode URLs of the P2P bootstrap nodes running on the // Ropsten test network. var RopstenBootnodes = []string{ @@ -113,6 +120,8 @@ func KnownDNSNetwork(genesis common.Hash, protocol string) string { switch genesis { case MainnetGenesisHash: net = "mainnet" + case SepoliaGenesisHash: + net = "sepolia" case RopstenGenesisHash: net = "ropsten" case RinkebyGenesisHash: diff --git a/params/config.go b/params/config.go index 5631f7868f1..70832126df1 100644 --- a/params/config.go +++ b/params/config.go @@ -27,6 +27,7 @@ import ( const ( MainnetChainName = "mainnet" + SepoliaChainName = "sepolia" RopstenChainName = "ropsten" RinkebyChainName = "rinkeby" GoerliChainName = "goerli" @@ -48,6 +49,7 @@ const ( // Genesis hashes to enforce below configs on. var ( MainnetGenesisHash = common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3") + SepoliaGenesisHash = common.HexToHash("0x25a5cc106eea7138acab33231d7160d69cb777ee0c2c553fcddf5138993e6dd9") RopstenGenesisHash = common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d") RinkebyGenesisHash = common.HexToHash("0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177") GoerliGenesisHash = common.HexToHash("0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a") @@ -91,6 +93,27 @@ var ( Ethash: new(EthashConfig), } + // SepoliaChainConfig contains the chain parameters to run a node on the Sepolia test network. + SepoliaChainConfig = &ChainConfig{ + ChainName: SepoliaChainName, + ChainID: big.NewInt(11155111), + Consensus: EtHashConsensus, + HomesteadBlock: big.NewInt(0), + DAOForkBlock: nil, + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + Ethash: new(EthashConfig), + } + // RopstenChainConfig contains the chain parameters to run a node on the Ropsten test network. RopstenChainConfig = &ChainConfig{ ChainName: RopstenChainName, diff --git a/turbo/node/node.go b/turbo/node/node.go index 58ea3eefe95..a129fafe1bd 100644 --- a/turbo/node/node.go +++ b/turbo/node/node.go @@ -52,6 +52,9 @@ func NewNodConfigUrfave(ctx *cli.Context) *node.Config { // If we're running a known preset, log it for convenience. chain := ctx.GlobalString(utils.ChainFlag.Name) switch chain { + case params.SepoliaChainName: + log.Info("Starting Erigon on Sepolia testnet...") + case params.RopstenChainName: log.Info("Starting Erigon on Ropsten testnet...") From c7e063ebdd62ebb726609cfeb8498e059cbe42fe Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Thu, 10 Feb 2022 17:00:51 +0000 Subject: [PATCH 159/261] [WIP] Adding Support for Sepolia (#3462) (#3473) * [WIP] Adding Sepolia * Fix formatting * Added Timestamp to Sepolia genesis * update config * fixed formating Co-authored-by: Jared Doro <56698307+DockBoss@users.noreply.github.com> --- cmd/integration/commands/stages.go | 3 ++ cmd/sentry/download/sentry.go | 2 ++ cmd/utils/flags.go | 15 +++++++++- core/allocs/sepolia.json | 47 ++++++++++++++++++++++++++++++ core/genesis.go | 15 ++++++++++ params/bootnodes.go | 9 ++++++ params/config.go | 23 +++++++++++++++ turbo/node/node.go | 3 ++ 8 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 core/allocs/sepolia.json diff --git a/cmd/integration/commands/stages.go b/cmd/integration/commands/stages.go index 8027683579a..8f06bb4680d 100644 --- a/cmd/integration/commands/stages.go +++ b/cmd/integration/commands/stages.go @@ -995,6 +995,9 @@ func byChain() (*core.Genesis, *params.ChainConfig) { case "", params.MainnetChainName: chainConfig = params.MainnetChainConfig genesis = core.DefaultGenesisBlock() + case params.SepoliaChainName: + chainConfig = params.SepoliaChainConfig + genesis = core.DefaultSepoliaGenesisBlock() case params.RopstenChainName: chainConfig = params.RopstenChainConfig genesis = core.DefaultRopstenGenesisBlock() diff --git a/cmd/sentry/download/sentry.go b/cmd/sentry/download/sentry.go index eb091be6615..1ce4e546bbd 100644 --- a/cmd/sentry/download/sentry.go +++ b/cmd/sentry/download/sentry.go @@ -161,6 +161,8 @@ func makeP2PServer( switch genesisHash { case params.MainnetGenesisHash: urls = params.MainnetBootnodes + case params.SepoliaGenesisHash: + urls = params.SepoliaBootnodes case params.RopstenGenesisHash: urls = params.RopstenBootnodes case params.GoerliGenesisHash: diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 3a462e8cf24..e58ec46ae0c 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -600,6 +600,8 @@ func setBootstrapNodes(ctx *cli.Context, cfg *p2p.Config) { } else { chain := ctx.GlobalString(ChainFlag.Name) switch chain { + case params.SepoliaChainName: + urls = params.SepoliaBootnodes case params.RopstenChainName: urls = params.RopstenBootnodes case params.RinkebyChainName: @@ -631,9 +633,10 @@ func setBootstrapNodesV5(ctx *cli.Context, cfg *p2p.Config) { if ctx.GlobalIsSet(BootnodesFlag.Name) { urls = SplitAndTrim(ctx.GlobalString(BootnodesFlag.Name)) } else { - chain := ctx.GlobalString(ChainFlag.Name) switch chain { + case params.SepoliaChainName: + urls = params.SepoliaBootnodes case params.RopstenChainName: urls = params.RopstenBootnodes case params.RinkebyChainName: @@ -916,6 +919,8 @@ func DataDirForNetwork(datadir string, network string) string { return filepath.Join(datadir, "kovan") case params.FermionChainName: return filepath.Join(datadir, "fermion") + case params.SepoliaChainName: + return filepath.Join(datadir, "sepolia") default: return datadir } @@ -1264,6 +1269,12 @@ func SetEthConfig(ctx *cli.Context, nodeConfig *node.Config, cfg *ethconfig.Conf } cfg.Genesis = core.DefaultGenesisBlock() SetDNSDiscoveryDefaults(cfg, params.MainnetGenesisHash) + case params.SepoliaChainName: + if !ctx.GlobalIsSet(NetworkIdFlag.Name) { + cfg.NetworkID = 11155111 + } + cfg.Genesis = core.DefaultSepoliaGenesisBlock() + SetDNSDiscoveryDefaults(cfg, params.SepoliaGenesisHash) case params.RopstenChainName: if !ctx.GlobalIsSet(NetworkIdFlag.Name) { cfg.NetworkID = 3 @@ -1366,6 +1377,8 @@ func MakeGenesis(ctx *cli.Context) *core.Genesis { var genesis *core.Genesis chain := ctx.GlobalString(ChainFlag.Name) switch chain { + case params.SepoliaChainName: + genesis = core.DefaultSepoliaGenesisBlock() case params.RopstenChainName: genesis = core.DefaultRopstenGenesisBlock() case params.RinkebyChainName: diff --git a/core/allocs/sepolia.json b/core/allocs/sepolia.json new file mode 100644 index 00000000000..e3d1af45ce9 --- /dev/null +++ b/core/allocs/sepolia.json @@ -0,0 +1,47 @@ +{ + "0xa2A6d93439144FFE4D27c9E088dCD8b783946263": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0xBc11295936Aa79d594139de1B2e12629414F3BDB": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x7cF5b79bfe291A67AB02b393E456cCc4c266F753": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0xaaec86394441f915bce3e6ab399977e9906f3b69": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0xF47CaE1CF79ca6758Bfc787dbD21E6bdBe7112B8": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0xd7eDDB78ED295B3C9629240E8924fb8D8874ddD8": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x8b7F0977Bb4f0fBE7076FA22bC24acA043583F5e": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0xe2e2659028143784d557bcec6ff3a0721048880a": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0xd9a5179f091d85051d3c982785efd1455cec8699": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0xbeef32ca5b9a198d27B4e02F4c70439fE60356Cf": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x0000006916a87b82333f4245046623b23794c65c": { + "balance": "0x84595161401484A000000" + }, + "0xb21c33de1fab3fa15499c62b59fe0cc3250020d1": { + "balance": "0x52B7D2DCC80CD2E4000000" + }, + "0x10F5d45854e038071485AC9e402308cF80D2d2fE": { + "balance": "0x52B7D2DCC80CD2E4000000" + }, + "0xd7d76c58b3a519e9fA6Cc4D22dC017259BC49F1E": { + "balance": "0x52B7D2DCC80CD2E4000000" + }, + "0x799D329e5f583419167cD722962485926E338F4a": { + "balance": "0xDE0B6B3A7640000" + } +} \ No newline at end of file diff --git a/core/genesis.go b/core/genesis.go index b252187befd..a01d2414f58 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -281,6 +281,8 @@ func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig { return g.Config case ghash == params.MainnetGenesisHash: return params.MainnetChainConfig + case ghash == params.SepoliaGenesisHash: + return params.SepoliaChainConfig case ghash == params.RopstenGenesisHash: return params.RopstenChainConfig case ghash == params.RinkebyGenesisHash: @@ -521,6 +523,19 @@ func DefaultGenesisBlock() *Genesis { } } +//DefaultSepoliaGenesisBlock returns the Sepolia network genesis block. +func DefaultSepoliaGenesisBlock() *Genesis { + return &Genesis{ + Config: params.SepoliaChainConfig, + Nonce: 0, + ExtraData: []byte("Sepolia, Athens, Attica, Greece!"), + GasLimit: 30000000, + Difficulty: big.NewInt(131072), + Timestamp: 1633267481, + Alloc: readPrealloc("allocs/sepolia.json"), + } +} + // DefaultRopstenGenesisBlock returns the Ropsten network genesis block. func DefaultRopstenGenesisBlock() *Genesis { return &Genesis{ diff --git a/params/bootnodes.go b/params/bootnodes.go index d7d0925a758..4518a695833 100644 --- a/params/bootnodes.go +++ b/params/bootnodes.go @@ -32,6 +32,13 @@ var MainnetBootnodes = []string{ "enode://5d6d7cd20d6da4bb83a1d28cadb5d409b64edf314c0335df658c1a54e32c7c4a7ab7823d57c39b6a757556e68ff1df17c748b698544a55cb488b52479a92b60f@104.42.217.25:30303", // bootnode-azure-westus-001 } +// SepoliaBootnodes are the enode URLs of the P2P bootstrap nodes running on the +// Sepolia test network. +var SepoliaBootnodes = []string{ + "enode://7c9740e4d64674801fe62b76798d46778a038c49caebb15843d8c0f2b2f80d7ceba2585b4be366e6161988f81ddcfcd6fca98b5da52ae9a6f22c1b2a84b24a04@18.130.169.73:30303", + "enode://ec66ddcf1a974950bd4c782789a7e04f8aa7110a72569b6e65fcd51e937e74eed303b1ea734e4d19cfaec9fbff9b6ee65bf31dcb50ba79acce9dd63a6aca61c7@52.14.151.177:30303", +} + // RopstenBootnodes are the enode URLs of the P2P bootstrap nodes running on the // Ropsten test network. var RopstenBootnodes = []string{ @@ -113,6 +120,8 @@ func KnownDNSNetwork(genesis common.Hash, protocol string) string { switch genesis { case MainnetGenesisHash: net = "mainnet" + case SepoliaGenesisHash: + net = "sepolia" case RopstenGenesisHash: net = "ropsten" case RinkebyGenesisHash: diff --git a/params/config.go b/params/config.go index 5631f7868f1..70832126df1 100644 --- a/params/config.go +++ b/params/config.go @@ -27,6 +27,7 @@ import ( const ( MainnetChainName = "mainnet" + SepoliaChainName = "sepolia" RopstenChainName = "ropsten" RinkebyChainName = "rinkeby" GoerliChainName = "goerli" @@ -48,6 +49,7 @@ const ( // Genesis hashes to enforce below configs on. var ( MainnetGenesisHash = common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3") + SepoliaGenesisHash = common.HexToHash("0x25a5cc106eea7138acab33231d7160d69cb777ee0c2c553fcddf5138993e6dd9") RopstenGenesisHash = common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d") RinkebyGenesisHash = common.HexToHash("0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177") GoerliGenesisHash = common.HexToHash("0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a") @@ -91,6 +93,27 @@ var ( Ethash: new(EthashConfig), } + // SepoliaChainConfig contains the chain parameters to run a node on the Sepolia test network. + SepoliaChainConfig = &ChainConfig{ + ChainName: SepoliaChainName, + ChainID: big.NewInt(11155111), + Consensus: EtHashConsensus, + HomesteadBlock: big.NewInt(0), + DAOForkBlock: nil, + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + Ethash: new(EthashConfig), + } + // RopstenChainConfig contains the chain parameters to run a node on the Ropsten test network. RopstenChainConfig = &ChainConfig{ ChainName: RopstenChainName, diff --git a/turbo/node/node.go b/turbo/node/node.go index 58ea3eefe95..a129fafe1bd 100644 --- a/turbo/node/node.go +++ b/turbo/node/node.go @@ -52,6 +52,9 @@ func NewNodConfigUrfave(ctx *cli.Context) *node.Config { // If we're running a known preset, log it for convenience. chain := ctx.GlobalString(utils.ChainFlag.Name) switch chain { + case params.SepoliaChainName: + log.Info("Starting Erigon on Sepolia testnet...") + case params.RopstenChainName: log.Info("Starting Erigon on Ropsten testnet...") From 18582db329ef8e7190a106ef98b035ad02a8a6df Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Sat, 12 Feb 2022 17:45:31 +0700 Subject: [PATCH 160/261] RPCDaemon: can start when txpool disabled (#3486) * grpc disabled server txpool * grpc disabled server txpool * grpc disabled server txpool * Update to stable erigon-lib Co-authored-by: Alex Sharp --- eth/backend.go | 61 +++++++++++++++++++++++++++++--------------------- go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/eth/backend.go b/eth/backend.go index f5ce41ea819..55e5218b34f 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -126,7 +126,7 @@ type Ethereum struct { newTxs2 chan txpool2.Hashes txPool2Fetch *txpool2.Fetch txPool2Send *txpool2.Send - txPool2GrpcServer *txpool2.GrpcServer + txPool2GrpcServer txpool_proto.TxpoolServer notifyMiningAboutNewTxs chan struct{} } @@ -314,31 +314,36 @@ func New(stack *node.Node, config *ethconfig.Config, logger log.Logger) (*Ethere var txPoolRPC txpool_proto.TxpoolServer var miningRPC txpool_proto.MiningServer if config.TxPool.V2 { - cfg := txpool2.DefaultConfig - cfg.DBDir = path.Join(stack.Config().DataDir, "txpool") - cfg.PendingSubPoolLimit = int(config.TxPool.GlobalSlots) - cfg.BaseFeeSubPoolLimit = int(config.TxPool.GlobalBaseFeeQueue) - cfg.QueuedSubPoolLimit = int(config.TxPool.GlobalQueue) - cfg.PriceBump = config.TxPool.PriceBump - cfg.MinFeeCap = config.TxPool.PriceLimit - cfg.AccountSlots = config.TxPool.AccountSlots - cfg.LogEvery = 1 * time.Minute - cfg.CommitEvery = 5 * time.Minute - cfg.TracedSenders = config.TxPool.TracedSenders - - //cacheConfig := kvcache.DefaultCoherentCacheConfig - //cacheConfig.MetricsLabel = "txpool" - - stateDiffClient := direct.NewStateDiffClientDirect(kvRPC) - backend.newTxs2 = make(chan txpool2.Hashes, 1024) - //defer close(newTxs) - backend.txPool2DB, backend.txPool2, backend.txPool2Fetch, backend.txPool2Send, backend.txPool2GrpcServer, err = txpooluitl.AllComponents( - ctx, cfg, kvcache.NewDummy(), backend.newTxs2, backend.chainDB, backend.sentries, stateDiffClient, - ) - if err != nil { - return nil, err + if config.TxPool.Disable { + backend.txPool2GrpcServer = &txpool2.GrpcDisabled{} + txPoolRPC = backend.txPool2GrpcServer + } else { + cfg := txpool2.DefaultConfig + cfg.DBDir = path.Join(stack.Config().DataDir, "txpool") + cfg.PendingSubPoolLimit = int(config.TxPool.GlobalSlots) + cfg.BaseFeeSubPoolLimit = int(config.TxPool.GlobalBaseFeeQueue) + cfg.QueuedSubPoolLimit = int(config.TxPool.GlobalQueue) + cfg.PriceBump = config.TxPool.PriceBump + cfg.MinFeeCap = config.TxPool.PriceLimit + cfg.AccountSlots = config.TxPool.AccountSlots + cfg.LogEvery = 1 * time.Minute + cfg.CommitEvery = 5 * time.Minute + cfg.TracedSenders = config.TxPool.TracedSenders + + //cacheConfig := kvcache.DefaultCoherentCacheConfig + //cacheConfig.MetricsLabel = "txpool" + + stateDiffClient := direct.NewStateDiffClientDirect(kvRPC) + backend.newTxs2 = make(chan txpool2.Hashes, 1024) + //defer close(newTxs) + backend.txPool2DB, backend.txPool2, backend.txPool2Fetch, backend.txPool2Send, backend.txPool2GrpcServer, err = txpooluitl.AllComponents( + ctx, cfg, kvcache.NewDummy(), backend.newTxs2, backend.chainDB, backend.sentries, stateDiffClient, + ) + if err != nil { + return nil, err + } + txPoolRPC = backend.txPool2GrpcServer } - txPoolRPC = backend.txPool2GrpcServer } else { backend.txPoolP2PServer, err = txpool.NewP2PServer(backend.downloadCtx, backend.sentries, backend.txPool) if err != nil { @@ -406,9 +411,13 @@ func New(stack *node.Node, config *ethconfig.Config, logger log.Logger) (*Ethere if config.TxPool.V2 { backend.txPool2Fetch.ConnectCore() backend.txPool2Fetch.ConnectSentries() + var newTxsBroadcaster *txpool2.NewSlotsStreams + if casted, ok := backend.txPool2GrpcServer.(*txpool2.GrpcServer); ok { + newTxsBroadcaster = casted.NewSlotsStreams + } go txpool2.MainLoop(backend.downloadCtx, backend.txPool2DB, backend.chainDB, - backend.txPool2, backend.newTxs2, backend.txPool2Send, backend.txPool2GrpcServer.NewSlotsStreams, + backend.txPool2, backend.newTxs2, backend.txPool2Send, newTxsBroadcaster, func() { select { case backend.notifyMiningAboutNewTxs <- struct{}{}: diff --git a/go.mod b/go.mod index 1cfb49343e4..6fe70f5e8b7 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20220210083718-1599f6eed792 + github.com/ledgerwatch/erigon-lib v0.0.0-20220212095410-fa2dc4720eb0 github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 diff --git a/go.sum b/go.sum index 4b6ee5654bc..b0f119a596b 100644 --- a/go.sum +++ b/go.sum @@ -493,8 +493,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20220210083718-1599f6eed792 h1:JWkGY3AME4Su+1xtjGvtYfJnaO6dAScf/Jx4J9mb6Vw= -github.com/ledgerwatch/erigon-lib v0.0.0-20220210083718-1599f6eed792/go.mod h1:BQNYmN6i8RdHqedsztAj3XDnswYebacmFAnsznlisTc= +github.com/ledgerwatch/erigon-lib v0.0.0-20220212095410-fa2dc4720eb0 h1:dXFUMIIlbO9QtcULfvx2akZSt6zab/z+Oaw6ykpBtbE= +github.com/ledgerwatch/erigon-lib v0.0.0-20220212095410-fa2dc4720eb0/go.mod h1:BQNYmN6i8RdHqedsztAj3XDnswYebacmFAnsznlisTc= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= From 3edf17d1473f88b364088ac205bd631804a463e3 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Sun, 13 Feb 2022 02:21:06 +0700 Subject: [PATCH 161/261] atomic close 2 channels (#3497) --- cmd/sentry/download/sentry.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmd/sentry/download/sentry.go b/cmd/sentry/download/sentry.go index 1ce4e546bbd..fe0e3fb7fde 100644 --- a/cmd/sentry/download/sentry.go +++ b/cmd/sentry/download/sentry.go @@ -121,6 +121,8 @@ func (pi *PeerInfo) ClearDeadlines(now time.Time, givePermit bool) int { } func (pi *PeerInfo) Remove() { + pi.lock.Lock() + defer pi.lock.Unlock() pi.removeOnce.Do(func() { close(pi.removed) close(pi.tasks) @@ -128,6 +130,8 @@ func (pi *PeerInfo) Remove() { } func (pi *PeerInfo) Async(f func()) { + pi.lock.Lock() + defer pi.lock.Unlock() select { case <-pi.removed: // noop if peer removed case pi.tasks <- f: From 34209f9bacd360d1e4e446e34dfc998b204960e4 Mon Sep 17 00:00:00 2001 From: leonardchinonso <36096513+leonardchinonso@users.noreply.github.com> Date: Sat, 12 Feb 2022 23:42:51 +0100 Subject: [PATCH 162/261] Fix/wsfix stable (#3502) * Added devnettest tool code * Added the mock_requests.go file for testing GET \ requests * Fixing git submodules * Added the devnet launch tool to the Makefile --- Makefile | 4 + cmd/devnettest/commands/block.go | 103 ++++++++++++++++++- cmd/devnettest/commands/requests.go | 18 ++++ cmd/devnettest/requests/mock_requests.go | 16 +++ cmd/devnettest/requests/request_generator.go | 35 +++++++ cmd/devnettest/requests/requests.go | 9 +- cmd/rpcdaemon/cli/config.go | 3 +- 7 files changed, 177 insertions(+), 11 deletions(-) create mode 100644 cmd/devnettest/commands/requests.go create mode 100644 cmd/devnettest/requests/mock_requests.go diff --git a/Makefile b/Makefile index 95cca41fd36..580436eaf88 100644 --- a/Makefile +++ b/Makefile @@ -106,6 +106,10 @@ seeder: @echo "Done building." @echo "Run \"$(GOBIN)/seeder\" to seed snapshots." +devnettest: + $(GOBUILD) -o $(GOBIN)/devnettest ./cmd/devnettest + @echo "Run \"$(GOBIN)/devnettest\" to launch devnettest." + sndownloader: $(GOBUILD) -o $(GOBIN)/sndownloader ./cmd/snapshots/downloader @echo "Done building." diff --git a/cmd/devnettest/commands/block.go b/cmd/devnettest/commands/block.go index 31382ecf80d..4b62c8f13af 100644 --- a/cmd/devnettest/commands/block.go +++ b/cmd/devnettest/commands/block.go @@ -1,7 +1,13 @@ package commands import ( + "context" "fmt" + "github.com/ledgerwatch/erigon/common/hexutil" + "strings" + "time" + + "github.com/ledgerwatch/erigon/rpc" "github.com/holiman/uint256" "github.com/ledgerwatch/erigon/cmd/devnettest/requests" @@ -15,13 +21,14 @@ import ( var devnetSignPrivateKey, _ = crypto.HexToECDSA("26e86e45f6fc45ec6e2ecd128cec80fa1d1505e5507dcd2ae58c3130a7a97b48") var ( - sendAddr string - sendValue uint64 - nonce uint64 + sendAddr string + sendValue uint64 + nonce uint64 + searchBlock bool ) const ( - gasPrice = 50000 + gasPrice = 912345678 ) func init() { @@ -29,6 +36,7 @@ func init() { sendTxCmd.MarkFlagRequired("addr") sendTxCmd.Flags().Uint64Var(&sendValue, "value", 0, "Uint64 Value to send") sendTxCmd.Flags().Uint64Var(&nonce, "nonce", 0, "Uint64 nonce") + sendTxCmd.Flags().BoolVar(&searchBlock, "search-block", false, "Boolean look for tx in mined blocks") rootCmd.AddCommand(sendTxCmd) } @@ -50,6 +58,91 @@ var sendTxCmd = &cobra.Command{ signer := types.LatestSigner(params.AllCliqueProtocolChanges) signedTx, _ := types.SignTx(types.NewTransaction(nonce, toAddress, uint256.NewInt(sendValue), params.TxGas, uint256.NewInt(gasPrice), nil), *signer, devnetSignPrivateKey) - requests.SendTx(reqId, &signedTx) + hash, err := requests.SendTx(reqId, &signedTx) + if err != nil { + fmt.Printf("Error trying to send transaction: %v\n", err) + } + + if searchBlock { + searchBlockForTx(*hash) + } }, } + +func searchBlockForTx(txnHash common.Hash) { + url := "ws://127.0.0.1:8545" + client, clientErr := rpc.DialWebsocket(context.Background(), url, "") + if clientErr != nil { + fmt.Println("error connecting to socket", clientErr) + panic(clientErr) + } + fmt.Println("Connected to web socket successfully") + + if err := subscribe(client, "eth_newHeads", txnHash); err != nil { + fmt.Println("error occurred while subscribing", err) + panic(err) + } +} + +func subscribe(client *rpc.Client, method string, hash common.Hash) error { + parts := strings.SplitN(method, "_", 2) + namespace := parts[0] + method = parts[1] + ch := make(chan interface{}) + sub, err := client.Subscribe(context.Background(), namespace, ch, []interface{}{method}...) + if err != nil { + return err + } + defer sub.Unsubscribe() + + blockCount := 0 +ForLoop: + for { + select { + case v := <-ch: + blockCount++ + blockNumber := v.(map[string]interface{})["number"] + fmt.Printf("Searching for the transaction in block with number: %+v\n", blockNumber) + foundTx, err := blockHasHash(client, hash, blockNumber.(string)) + if err != nil { + return err + } + if foundTx || blockCount == 128 { + break ForLoop + } + case err := <-sub.Err(): + return err + } + } + + return nil + +} + +type Block struct { + Number *hexutil.Big + Transactions []common.Hash +} + +func blockHasHash(client *rpc.Client, hash common.Hash, blockNumber string) (bool, error) { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + var currentBlock Block + err := client.CallContext(ctx, ¤tBlock, "eth_getBlockByNumber", blockNumber, false) + if err != nil { + fmt.Println("can't get latest block:", err) + return false, err + } + + for _, txnHash := range currentBlock.Transactions { + if txnHash == hash { + fmt.Println() + fmt.Printf("Block with number: %v was mined and included transaction with hash: %v ==> %+v\n", blockNumber, hash, currentBlock) + fmt.Println() + return true, nil + } + } + + return false, nil +} diff --git a/cmd/devnettest/commands/requests.go b/cmd/devnettest/commands/requests.go new file mode 100644 index 00000000000..a8d3a7f9aaf --- /dev/null +++ b/cmd/devnettest/commands/requests.go @@ -0,0 +1,18 @@ +package commands + +import ( + "github.com/ledgerwatch/erigon/cmd/devnettest/requests" + "github.com/spf13/cobra" +) + +func init() { + rootCmd.AddCommand(mockRequestCmd) +} + +var mockRequestCmd = &cobra.Command{ + Use: "mock", + Short: "Mocks a request on the devnet", + Run: func(cmd *cobra.Command, args []string) { + requests.MockGetRequest(reqId) + }, +} diff --git a/cmd/devnettest/requests/mock_requests.go b/cmd/devnettest/requests/mock_requests.go new file mode 100644 index 00000000000..834d6ab247d --- /dev/null +++ b/cmd/devnettest/requests/mock_requests.go @@ -0,0 +1,16 @@ +package requests + +import "fmt" + +func MockGetRequest(reqId int) { + reqGen := initialiseRequestGenerator(reqId) + + res := reqGen.Get() + + if res.Err != nil { + fmt.Printf("error: %v\n", res.Err) + return + } + + fmt.Printf("OK\n") +} diff --git a/cmd/devnettest/requests/request_generator.go b/cmd/devnettest/requests/request_generator.go index 7138c223dc7..9075eff2b0e 100644 --- a/cmd/devnettest/requests/request_generator.go +++ b/cmd/devnettest/requests/request_generator.go @@ -1,7 +1,9 @@ package requests import ( + "errors" "fmt" + "io/ioutil" "net/http" "time" @@ -34,6 +36,39 @@ func initialiseRequestGenerator(reqId int) *RequestGenerator { return &reqGen } +func (req *RequestGenerator) Get() rpctest.CallResult { + start := time.Now() + res := rpctest.CallResult{ + RequestID: req.reqID, + } + + resp, err := http.Get(erigonUrl) + if err != nil { + res.Took = time.Since(start) + res.Err = err + return res + } + defer resp.Body.Close() + + if resp.StatusCode != 200 { + res.Took = time.Since(start) + res.Err = errors.New("bad request") + return res + } + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + res.Took = time.Since(start) + res.Err = err + return res + } + + res.Response = body + res.Took = time.Since(start) + res.Err = err + return res +} + func (req *RequestGenerator) Erigon(method, body string, response interface{}) rpctest.CallResult { return req.call(erigonUrl, method, body, response) } diff --git a/cmd/devnettest/requests/requests.go b/cmd/devnettest/requests/requests.go index eb679505adc..ba46234841d 100644 --- a/cmd/devnettest/requests/requests.go +++ b/cmd/devnettest/requests/requests.go @@ -32,24 +32,23 @@ func GetBalance(reqId int, address common.Address, blockNum string) { fmt.Printf("Balance retrieved: %v\n", parseResponse(b)) } -func SendTx(reqId int, signedTx *types.Transaction) { +func SendTx(reqId int, signedTx *types.Transaction) (*common.Hash, error) { reqGen := initialiseRequestGenerator(reqId) var b rpctest.EthSendRawTransaction var buf bytes.Buffer err := (*signedTx).MarshalBinary(&buf) if err != nil { - fmt.Printf("Error trying to marshal binary: %v\n", err) - return + return nil, err } res := reqGen.Erigon("eth_sendRawTransaction", reqGen.sendRawTransaction(buf.Bytes()), &b) if res.Err != nil { - fmt.Printf("Error sending transaction: %v\n", res.Err) - return + return nil, err } fmt.Printf("Submitted transaction successfully: %v\n", parseResponse(b)) + return &b.TxnHash, nil } func TxpoolContent(reqId int) { diff --git a/cmd/rpcdaemon/cli/config.go b/cmd/rpcdaemon/cli/config.go index db61f636715..7b55049765b 100644 --- a/cmd/rpcdaemon/cli/config.go +++ b/cmd/rpcdaemon/cli/config.go @@ -11,6 +11,7 @@ import ( "path" "time" + "github.com/gorilla/websocket" "github.com/ledgerwatch/erigon-lib/gointerfaces" "github.com/ledgerwatch/erigon-lib/gointerfaces/grpcutil" "github.com/ledgerwatch/erigon-lib/gointerfaces/remote" @@ -329,7 +330,7 @@ func StartRpcServer(ctx context.Context, cfg Flags, rpcAPI []rpc.API) error { if health.ProcessHealthcheckIfNeeded(w, r, rpcAPI) { return } - if cfg.WebsocketEnabled && r.Method == "GET" { + if cfg.WebsocketEnabled && websocket.IsWebSocketUpgrade(r) { wsHandler.ServeHTTP(w, r) return } From 02c4e44ba5575e249c2dd1bebad3ffaafddca43c Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Sun, 13 Feb 2022 20:09:57 +0700 Subject: [PATCH 163/261] save (#3508) --- libmdbx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmdbx b/libmdbx index 03d828834bd..daa7f04f617 160000 --- a/libmdbx +++ b/libmdbx @@ -1 +1 @@ -Subproject commit 03d828834bdb57a8e0ff34a311b6b835bfe4a479 +Subproject commit daa7f04f6173504b5acc74140ed36f617d3a62bf From b37476344ef8fa54e23395bd1c2a57025d6905bc Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Wed, 16 Feb 2022 18:58:19 +0000 Subject: [PATCH 164/261] Update version.go (#3526) --- params/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/params/version.go b/params/version.go index b663d95f2ef..a05ef00eaf7 100644 --- a/params/version.go +++ b/params/version.go @@ -33,7 +33,7 @@ var ( const ( VersionMajor = 2022 // Major version component of the current release VersionMinor = 2 // Minor version component of the current release - VersionMicro = 2 // Patch version component of the current release + VersionMicro = 3 // Patch version component of the current release VersionModifier = "beta" // Patch version component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" From 4e79393a0432009e90a1adfb5bc8dadddab86eb9 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Wed, 16 Feb 2022 18:58:28 +0000 Subject: [PATCH 165/261] Optimized eth_createAccessList (#3453) (#3524) * Make blockNrOrHash optional in CreateAccessList (in line with geth) * OptimizedAccessList * cosmetics * optimizeGas param instead of separate method * Inline toAddress Co-authored-by: Andrew Ashikhmin <34320705+yperbasis@users.noreply.github.com> --- cmd/rpcdaemon/commands/eth_api.go | 2 +- cmd/rpcdaemon/commands/eth_call.go | 51 ++++++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/cmd/rpcdaemon/commands/eth_api.go b/cmd/rpcdaemon/commands/eth_api.go index da2dba01385..169b86a79ca 100644 --- a/cmd/rpcdaemon/commands/eth_api.go +++ b/cmd/rpcdaemon/commands/eth_api.go @@ -81,7 +81,7 @@ type EthAPI interface { Sign(ctx context.Context, _ common.Address, _ hexutil.Bytes) (hexutil.Bytes, error) SignTransaction(_ context.Context, txObject interface{}) (common.Hash, error) GetProof(ctx context.Context, address common.Address, storageKeys []string, blockNr rpc.BlockNumber) (*interface{}, error) - CreateAccessList(ctx context.Context, args ethapi.CallArgs, blockNrOrHash rpc.BlockNumberOrHash) (*accessListResult, error) + CreateAccessList(ctx context.Context, args ethapi.CallArgs, blockNrOrHash *rpc.BlockNumberOrHash, optimizeGas *bool) (*accessListResult, error) // Mining related (see ./eth_mining.go) Coinbase(ctx context.Context) (common.Address, error) diff --git a/cmd/rpcdaemon/commands/eth_call.go b/cmd/rpcdaemon/commands/eth_call.go index 23b24d102b7..97321e8453c 100644 --- a/cmd/rpcdaemon/commands/eth_call.go +++ b/cmd/rpcdaemon/commands/eth_call.go @@ -284,7 +284,7 @@ func (api *APIImpl) GetProof(ctx context.Context, address common.Address, storag } // accessListResult returns an optional accesslist -// Its the result of the `debug_createAccessList` RPC call. +// Its the result of the `eth_createAccessList` RPC call. // It contains an error if the transaction itself failed. type accessListResult struct { Accesslist *types.AccessList `json:"accessList"` @@ -295,7 +295,12 @@ type accessListResult struct { // CreateAccessList implements eth_createAccessList. It creates an access list for the given transaction. // If the accesslist creation fails an error is returned. // If the transaction itself fails, an vmErr is returned. -func (api *APIImpl) CreateAccessList(ctx context.Context, args ethapi.CallArgs, blockNrOrHash rpc.BlockNumberOrHash) (*accessListResult, error) { +func (api *APIImpl) CreateAccessList(ctx context.Context, args ethapi.CallArgs, blockNrOrHash *rpc.BlockNumberOrHash, optimizeGas *bool) (*accessListResult, error) { + bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber) + if blockNrOrHash != nil { + bNrOrHash = *blockNrOrHash + } + tx, err := api.db.BeginRo(ctx) if err != nil { return nil, err @@ -310,7 +315,7 @@ func (api *APIImpl) CreateAccessList(ctx context.Context, args ethapi.CallArgs, if api.TevmEnabled { contractHasTEVM = ethdb.GetHasTEVM(tx) } - blockNumber, hash, err := rpchelper.GetCanonicalBlockNumber(blockNrOrHash, tx, api.filters) // DoCall cannot be executed on non-canonical blocks + blockNumber, hash, err := rpchelper.GetCanonicalBlockNumber(bNrOrHash, tx, api.filters) // DoCall cannot be executed on non-canonical blocks if err != nil { return nil, err } @@ -322,7 +327,7 @@ func (api *APIImpl) CreateAccessList(ctx context.Context, args ethapi.CallArgs, return nil, nil } var stateReader state.StateReader - if num, ok := blockNrOrHash.Number(); ok && num == rpc.LatestBlockNumber { + if num, ok := bNrOrHash.Number(); ok && num == rpc.LatestBlockNumber { cacheView, err := api.stateCache.View(ctx, tx) if err != nil { return nil, err @@ -358,6 +363,7 @@ func (api *APIImpl) CreateAccessList(ctx context.Context, args ethapi.CallArgs, } to = crypto.CreateAddress(*args.From, uint64(*args.Nonce)) } + // Retrieve the precompiles since they don't need to be added to the access list precompiles := vm.ActivePrecompiles(chainConfig.Rules(blockNumber)) @@ -388,7 +394,7 @@ func (api *APIImpl) CreateAccessList(ctx context.Context, args ethapi.CallArgs, // Apply the transaction with the access list tracer tracer := logger.NewAccessListTracer(accessList, *args.From, to, precompiles) config := vm.Config{Tracer: tracer, Debug: true, NoBaseFee: true} - blockCtx, txCtx := transactions.GetEvmContext(msg, header, blockNrOrHash.RequireCanonical, tx, contractHasTEVM) + blockCtx, txCtx := transactions.GetEvmContext(msg, header, bNrOrHash.RequireCanonical, tx, contractHasTEVM) evm := vm.NewEVM(blockCtx, txCtx, state, chainConfig, config) gp := new(core.GasPool).AddGas(msg.Gas()) @@ -401,8 +407,41 @@ func (api *APIImpl) CreateAccessList(ctx context.Context, args ethapi.CallArgs, if res.Err != nil { errString = res.Err.Error() } - return &accessListResult{Accesslist: &accessList, Error: errString, GasUsed: (hexutil.Uint64)(res.UsedGas)}, nil + accessList := &accessListResult{Accesslist: &accessList, Error: errString, GasUsed: hexutil.Uint64(res.UsedGas)} + if optimizeGas != nil && *optimizeGas { + optimizeToInAccessList(accessList, to) + } + return accessList, nil } prevTracer = tracer } } + +// to address is warm already, so we can save by adding it to the access list +// only if we are adding a lot of its storage slots as well +func optimizeToInAccessList(accessList *accessListResult, to common.Address) { + indexToRemove := -1 + + for i := 0; i < len(*accessList.Accesslist); i++ { + entry := (*accessList.Accesslist)[i] + if entry.Address != to { + continue + } + + // https://eips.ethereum.org/EIPS/eip-2930#charging-less-for-accesses-in-the-access-list + accessListSavingPerSlot := params.ColdSloadCostEIP2929 - params.WarmStorageReadCostEIP2929 - params.TxAccessListStorageKeyGas + + numSlots := uint64(len(entry.StorageKeys)) + if numSlots*accessListSavingPerSlot <= params.TxAccessListAddressGas { + indexToRemove = i + } + } + + if indexToRemove >= 0 { + *accessList.Accesslist = removeIndex(*accessList.Accesslist, indexToRemove) + } +} + +func removeIndex(s types.AccessList, index int) types.AccessList { + return append(s[:index], s[index+1:]...) +} From 159373c2c8cc455d8f4cc6212b68eb9a1860aa8b Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Wed, 16 Feb 2022 18:58:38 +0000 Subject: [PATCH 166/261] [header downloader] introduce queues instead of insertList (#3489) (#3525) * [header downloader] introduce queues instead of insertList (#3489) * First change for header queues * Fix * Fix import * trigger verification when highestInDb changes * Print hash, fix MarkAllPreverified * Fix test * Cleanup * More cleanup Co-authored-by: Alexey Sharp Co-authored-by: Alex Sharp * Add extra check Co-authored-by: Alexey Sharp Co-authored-by: Alex Sharp --- turbo/stages/headerdownload/header_algos.go | 235 +++++++++++++----- .../headerdownload/header_data_struct.go | 100 +++++++- turbo/stages/mock_sentry.go | 2 +- 3 files changed, 257 insertions(+), 80 deletions(-) diff --git a/turbo/stages/headerdownload/header_algos.go b/turbo/stages/headerdownload/header_algos.go index 1e0380b1483..e4dd3f11568 100644 --- a/turbo/stages/headerdownload/header_algos.go +++ b/turbo/stages/headerdownload/header_algos.go @@ -111,6 +111,16 @@ func (hd *HeaderDownload) ReportBadHeader(headerHash common.Hash) { hd.lock.Lock() defer hd.lock.Unlock() hd.badHeaders[headerHash] = struct{}{} + // Find the link, remove it and all its descendands from all the queues + if link, ok := hd.links[headerHash]; ok { + removeList := []*Link{link} + for len(removeList) > 0 { + removal := removeList[len(removeList)-1] + hd.moveLinkToQueue(removal, NoQueue) + delete(hd.links, removal.hash) + removeList = append(removeList[:len(removeList)-1], removal.next...) + } + } } func (hd *HeaderDownload) IsBadHeader(headerHash common.Hash) bool { @@ -151,8 +161,8 @@ func (hd *HeaderDownload) removeUpwards(toRemove []*Link) { for len(toRemove) > 0 { removal := toRemove[len(toRemove)-1] toRemove = toRemove[:len(toRemove)-1] - delete(hd.links, removal.header.Hash()) - heap.Remove(hd.linkQueue, removal.idx) + delete(hd.links, removal.hash) + hd.moveLinkToQueue(removal, NoQueue) toRemove = append(toRemove, removal.next...) } } @@ -160,11 +170,37 @@ func (hd *HeaderDownload) removeUpwards(toRemove []*Link) { func (hd *HeaderDownload) markPreverified(link *Link) { // Go through all parent links that are not preveried and mark them too for link != nil && !link.persisted { - link.preverified = true + if !link.verified { + link.verified = true + hd.moveLinkToQueue(link, InsertQueueID) + } link = hd.links[link.header.ParentHash] } } +func (hd *HeaderDownload) MarkAllPreverified() { + hd.lock.Lock() + defer hd.lock.Unlock() + for hd.verifyQueue.Len() > 0 { + link := hd.verifyQueue[0] + if !link.verified { + link.verified = true + hd.moveLinkToQueue(link, InsertQueueID) + } else { + panic("verified link in verifyQueue") + } + } + for hd.linkQueue.Len() > 0 { + link := hd.linkQueue[0] + if !link.verified { + link.verified = true + hd.moveLinkToQueue(link, InsertQueueID) + } else { + panic("verified link in linkQueue") + } + } +} + // ExtendUp extends a working tree up from the link, using given chain segment func (hd *HeaderDownload) extendUp(segment *ChainSegment, start, end int) error { // Find attachment link again @@ -173,13 +209,21 @@ func (hd *HeaderDownload) extendUp(segment *ChainSegment, start, end int) error if !attaching { return fmt.Errorf("extendUp attachment link not found for %x", linkHeader.ParentHash) } - if attachmentLink.preverified && len(attachmentLink.next) > 0 { + if attachmentLink.verified && len(attachmentLink.next) > 0 { return fmt.Errorf("cannot extendUp from preverified link %d with children", attachmentLink.blockHeight) } // Iterate over headers backwards (from parents towards children) prevLink := attachmentLink for i := end - 1; i >= start; i-- { link := hd.addHeaderAsLink(segment.Headers[i], false /* persisted */) + if prevLink.persisted { + // If we are attching to already persisted link, schedule for insertion (persistence) + if link.verified { + hd.moveLinkToQueue(link, InsertQueueID) + } else { + hd.moveLinkToQueue(link, VerifyQueueID) + } + } prevLink.next = append(prevLink.next, link) prevLink = link if _, ok := hd.preverifiedHashes[link.hash]; ok { @@ -189,7 +233,11 @@ func (hd *HeaderDownload) extendUp(segment *ChainSegment, start, end int) error if _, bad := hd.badHeaders[attachmentLink.hash]; !bad && attachmentLink.persisted { link := hd.links[linkHeader.Hash()] - hd.insertList = append(hd.insertList, link) + if link.verified { + hd.moveLinkToQueue(link, InsertQueueID) + } else { + hd.moveLinkToQueue(link, VerifyQueueID) + } } return nil } @@ -202,7 +250,7 @@ func (hd *HeaderDownload) extendDown(segment *ChainSegment, start, end int) (boo if anchor, attaching := hd.anchors[anchorHeader.Hash()]; attaching { anchorPreverified := false for _, link := range anchor.links { - if link.preverified { + if link.verified { anchorPreverified = true break } @@ -262,7 +310,7 @@ func (hd *HeaderDownload) connect(segment *ChainSegment, start, end int) ([]Pena if !ok1 { return nil, fmt.Errorf("connect attachment link not found for %x", linkHeader.ParentHash) } - if attachmentLink.preverified && len(attachmentLink.next) > 0 { + if attachmentLink.verified && len(attachmentLink.next) > 0 { return nil, fmt.Errorf("cannot connect to preverified link %d with children", attachmentLink.blockHeight) } anchor, ok2 := hd.anchors[anchorHeader.Hash()] @@ -271,7 +319,7 @@ func (hd *HeaderDownload) connect(segment *ChainSegment, start, end int) ([]Pena } anchorPreverified := false for _, link := range anchor.links { - if link.preverified { + if link.verified { anchorPreverified = true break } @@ -284,6 +332,14 @@ func (hd *HeaderDownload) connect(segment *ChainSegment, start, end int) ([]Pena prevLink := attachmentLink for i := end - 1; i >= start; i-- { link := hd.addHeaderAsLink(segment.Headers[i], false /* persisted */) + // If we attach to already persisted link, mark this one for insertion + if prevLink.persisted { + if link.verified { + hd.moveLinkToQueue(link, InsertQueueID) + } else { + hd.moveLinkToQueue(link, VerifyQueueID) + } + } prevLink.next = append(prevLink.next, link) prevLink = link if _, ok := hd.preverifiedHashes[link.hash]; ok { @@ -302,7 +358,11 @@ func (hd *HeaderDownload) connect(segment *ChainSegment, start, end int) ([]Pena penalties = append(penalties, PenaltyItem{Penalty: AbandonedAnchorPenalty, PeerID: anchor.peerID}) } else if attachmentLink.persisted { link := hd.links[linkHeader.Hash()] - hd.insertList = append(hd.insertList, link) + if link.verified { + hd.moveLinkToQueue(link, InsertQueueID) + } else { + hd.moveLinkToQueue(link, VerifyQueueID) + } } return penalties, nil } @@ -469,7 +529,7 @@ func (hd *HeaderDownload) RecoverFromDb(db kv.RoDB) error { // Drain persistedLinksQueue and remove links for hd.persistedLinkQueue.Len() > 0 { - link := heap.Pop(hd.persistedLinkQueue).(*Link) + link := heap.Pop(&hd.persistedLinkQueue).(*Link) delete(hd.links, link.hash) } err := db.View(context.Background(), func(tx kv.Tx) error { @@ -594,68 +654,105 @@ func (hd *HeaderDownload) RequestSkeleton() *HeaderRequest { func (hd *HeaderDownload) InsertHeaders(hf func(header *types.Header, hash common.Hash, blockHeight uint64) error, logPrefix string, logChannel <-chan time.Time) (bool, error) { hd.lock.Lock() defer hd.lock.Unlock() - var linksInFuture []*Link // Here we accumulate links that fail validation as "in the future" - for len(hd.insertList) > 0 { - // Make sure long insertions do not appear as a stuck stage 1 - select { - case <-logChannel: - log.Info(fmt.Sprintf("[%s] Inserting headers", logPrefix), "progress", hd.highestInDb) - default: - } - link := hd.insertList[len(hd.insertList)-1] - if link.blockHeight <= hd.preverifiedHeight && !link.preverified { - // Header should be preverified, but not yet, try again later - break - } - hd.insertList = hd.insertList[:len(hd.insertList)-1] - skip := false - if !link.preverified { - if _, bad := hd.badHeaders[link.hash]; bad { - skip = true - } else if err := hd.engine.VerifyHeader(hd.headerReader, link.header, true /* seal */); err != nil { - log.Warn("Verification failed for header", "hash", link.header.Hash(), "height", link.blockHeight, "error", err) - if errors.Is(err, consensus.ErrFutureBlock) { - // This may become valid later - linksInFuture = append(linksInFuture, link) - log.Warn("Added future link", "hash", link.header.Hash(), "height", link.blockHeight, "timestamp", link.header.Time) - continue // prevent removal of the link from the hd.linkQueue - } else { - skip = true + + checkVerify := true + checkInsert := true + + for checkVerify || checkInsert { + if checkVerify { + checkVerify = false + // Perform verification if needed + for hd.verifyQueue.Len() > 0 { + link := hd.verifyQueue[0] + select { + case <-logChannel: + log.Info(fmt.Sprintf("[%s] Verifying headers", logPrefix), "progress", hd.highestInDb) + default: } - } else { - if hd.seenAnnounces.Pop(link.hash) { - hd.toAnnounce = append(hd.toAnnounce, Announce{Hash: link.hash, Number: link.blockHeight}) + skip := false + if link.blockHeight <= hd.preverifiedHeight { + if link.blockHeight <= hd.highestInDb { + // There was preverified alternative to this link, drop + skip = true + } else { + break // Wait to be mark as pre-verified or an alternative to be inserted + } + } + if !skip { + _, skip = hd.badHeaders[link.hash] + } + if !skip && !link.persisted { + _, skip = hd.badHeaders[link.header.ParentHash] + } + if !skip { + if err := hd.engine.VerifyHeader(hd.headerReader, link.header, true /* seal */); err != nil { + if errors.Is(err, consensus.ErrFutureBlock) { + // This may become valid later + log.Warn("Added future link", "hash", link.hash, "height", link.blockHeight, "timestamp", link.header.Time) + break // prevent removal of the link from the hd.linkQueue + } else { + log.Warn("Verification failed for header", "hash", link.hash, "height", link.blockHeight, "error", err) + skip = true + } + } + } + if skip { + hd.moveLinkToQueue(link, NoQueue) + delete(hd.links, link.hash) + continue } + hd.moveLinkToQueue(link, InsertQueueID) + checkInsert = true } } - if _, ok := hd.links[link.hash]; ok { - heap.Remove(hd.linkQueue, link.idx) - } - if skip { - delete(hd.links, link.hash) - continue - } - if err := hf(link.header, link.hash, link.blockHeight); err != nil { - return false, err - } - if link.blockHeight > hd.highestInDb { - hd.highestInDb = link.blockHeight - } - link.persisted = true - link.header = nil // Drop header reference to free memory, as we won't need it anymore - heap.Push(hd.persistedLinkQueue, link) - if len(link.next) > 0 { - hd.insertList = append(hd.insertList, link.next...) + if checkInsert { + checkInsert = false + // Check what we can insert without verification + for hd.insertQueue.Len() > 0 && hd.insertQueue[0].blockHeight <= hd.highestInDb+1 { + link := hd.insertQueue[0] + _, bad := hd.badHeaders[link.hash] + if !bad && !link.persisted { + _, bad = hd.badHeaders[link.header.ParentHash] + } + if bad { + // If the link or its parent is marked bad, throw it out + hd.moveLinkToQueue(link, NoQueue) + delete(hd.links, link.hash) + continue + } + // Make sure long insertions do not appear as a stuck stage 1 + select { + case <-logChannel: + log.Info(fmt.Sprintf("[%s] Inserting headers", logPrefix), "progress", hd.highestInDb) + default: + } + err := hf(link.header, link.hash, link.blockHeight) + if err != nil { + return false, err + } + + if link.blockHeight > hd.highestInDb { + hd.highestInDb = link.blockHeight + checkVerify = true // highestInDb changes, so that there might be more links in verifyQueue to process + } + link.persisted = true + link.header = nil // Drop header reference to free memory, as we won't need it anymore + hd.moveLinkToQueue(link, PersistedQueueID) + for _, nextLink := range link.next { + if nextLink.verified { + hd.moveLinkToQueue(nextLink, InsertQueueID) + } else { + hd.moveLinkToQueue(nextLink, VerifyQueueID) + checkVerify = true + } + } + } + for hd.persistedLinkQueue.Len() > hd.persistedLinkLimit { + link := heap.Pop(&hd.persistedLinkQueue).(*Link) + delete(hd.links, link.hash) + } } } - for hd.persistedLinkQueue.Len() > hd.persistedLinkLimit { - link := heap.Pop(hd.persistedLinkQueue).(*Link) - delete(hd.links, link.hash) - } - if len(linksInFuture) > 0 { - hd.insertList = append(hd.insertList, linksInFuture...) - linksInFuture = nil //nolint - } return hd.highestInDb >= hd.preverifiedHeight && hd.topSeenHeight > 0 && hd.highestInDb >= hd.topSeenHeight, nil } @@ -710,9 +807,9 @@ func (hd *HeaderDownload) addHeaderAsLink(header *types.Header, persisted bool) } hd.links[linkHash] = link if persisted { - heap.Push(hd.persistedLinkQueue, link) + hd.moveLinkToQueue(link, PersistedQueueID) } else { - heap.Push(hd.linkQueue, link) + hd.moveLinkToQueue(link, EntryQueueID) } return link } @@ -913,7 +1010,7 @@ func (hd *HeaderDownload) ProcessSegment(segment *ChainSegment, newBlock bool, p log.Trace("Too many links, cutting down", "count", hd.linkQueue.Len(), "tried to add", end-start, "limit", hd.linkLimit) } for hd.linkQueue.Len() > hd.linkLimit { - link := heap.Pop(hd.linkQueue).(*Link) + link := heap.Pop(&hd.linkQueue).(*Link) delete(hd.links, link.hash) if parentLink, ok := hd.links[link.header.ParentHash]; ok { for i, n := range parentLink.next { diff --git a/turbo/stages/headerdownload/header_data_struct.go b/turbo/stages/headerdownload/header_data_struct.go index bd22fc67966..b6fcfd8e173 100644 --- a/turbo/stages/headerdownload/header_data_struct.go +++ b/turbo/stages/headerdownload/header_data_struct.go @@ -12,6 +12,16 @@ import ( "github.com/ledgerwatch/erigon/core/types" ) +type QueueID uint8 + +const ( + NoQueue QueueID = iota + EntryQueueID + VerifyQueueID + InsertQueueID + PersistedQueueID +) + // Link is a chain link that can be connect to other chain links // For a given link, parent link can be found by hd.links[link.header.ParentHash], and child links by link.next (there may be more than one child in case of forks) // Links encapsule block headers @@ -22,9 +32,10 @@ type Link struct { next []*Link // Allows iteration over links in ascending block height order hash common.Hash // Hash of the header blockHeight uint64 - persisted bool // Whether this link comes from the database record - preverified bool // Ancestor of pre-verified header - idx int // Index in the heap + persisted bool // Whether this link comes from the database record + verified bool // Ancestor of pre-verified header or verified by consensus engine + idx int // Index in the heap + queueId QueueID // which queue this link belongs to } // LinkQueue is the priority queue of links. It is instantiated once for persistent links, and once for non-persistent links @@ -69,6 +80,8 @@ func (lq *LinkQueue) Pop() interface{} { old := *lq n := len(old) x := old[n-1] + x.idx = -1 + x.queueId = NoQueue *lq = old[0 : n-1] return x } @@ -168,6 +181,41 @@ type Announce struct { type VerifySealFunc func(header *types.Header) error type CalcDifficultyFunc func(childTimestamp uint64, parentTime uint64, parentDifficulty, parentNumber *big.Int, parentHash, parentUncleHash common.Hash) *big.Int +// InsertQueue keeps the links before they are inserted in the database +// It priorities them by block height (the lowest block height on the top), +// and if block heights are the same, by the verification status (verified/preverified on the top) +type InsertQueue []*Link + +func (iq InsertQueue) Len() int { + return len(iq) +} + +func (iq InsertQueue) Less(i, j int) bool { + return iq[i].blockHeight < iq[j].blockHeight +} + +func (iq InsertQueue) Swap(i, j int) { + iq[i], iq[j] = iq[j], iq[i] + iq[i].idx, iq[j].idx = i, j // Restore indices after the swap +} + +func (iq *InsertQueue) Push(x interface{}) { + // Push and Pop use pointer receivers because they modify the slice's length, + // not just its contents. + x.(*Link).idx = len(*iq) + *iq = append(*iq, x.(*Link)) +} + +func (iq *InsertQueue) Pop() interface{} { + old := *iq + n := len(old) + x := old[n-1] + *iq = old[0 : n-1] + x.idx = -1 + x.queueId = NoQueue + return x +} + type HeaderDownload struct { badHeaders map[common.Hash]struct{} anchors map[common.Hash]*Anchor // Mapping from parentHash to collection of anchors @@ -175,10 +223,11 @@ type HeaderDownload struct { links map[common.Hash]*Link // Links by header hash engine consensus.Engine headerReader consensus.ChainHeaderReader - insertList []*Link // List of non-persisted links that can be inserted (their parent is persisted) + verifyQueue InsertQueue // Priority queue of non-peristed links ready for verification + insertQueue InsertQueue // Priority queue of non-persisted links that are verified and can be inserted seenAnnounces *SeenAnnounces // External announcement hashes, after header verification if hash is in this set - will broadcast it further - persistedLinkQueue *LinkQueue // Priority queue of persisted links used to limit their number - linkQueue *LinkQueue // Priority queue of non-persisted links used to limit their number + persistedLinkQueue LinkQueue // Priority queue of persisted links used to limit their number + linkQueue LinkQueue // Priority queue of non-persisted links used to limit their number anchorQueue *AnchorQueue // Priority queue of anchors used to sequence the header requests DeliveryNotify chan struct{} SkipCycleHack chan struct{} // devenet will signal to this channel to skip sync cycle and release write db transaction. It's temporary solution - later we will do mining without write transaction. @@ -215,16 +264,16 @@ func NewHeaderDownload( engine: engine, preverifiedHashes: make(map[common.Hash]struct{}), links: make(map[common.Hash]*Link), - persistedLinkQueue: &LinkQueue{}, - linkQueue: &LinkQueue{}, anchorQueue: &AnchorQueue{}, seenAnnounces: NewSeenAnnounces(), DeliveryNotify: make(chan struct{}, 1), SkipCycleHack: make(chan struct{}), } - heap.Init(hd.persistedLinkQueue) - heap.Init(hd.linkQueue) + heap.Init(&hd.persistedLinkQueue) + heap.Init(&hd.linkQueue) heap.Init(hd.anchorQueue) + heap.Init(&hd.verifyQueue) + heap.Init(&hd.insertQueue) return hd } @@ -255,6 +304,37 @@ func (pp PeerPenalty) String() string { return fmt.Sprintf("peerPenalty{peer: %d, penalty: %s, err: %v}", pp.peerHandle, pp.penalty, pp.err) } +func (hd *HeaderDownload) moveLinkToQueue(link *Link, queueId QueueID) { + if link.queueId == queueId { + return + } + // Remove + switch link.queueId { + case NoQueue: + case EntryQueueID: + heap.Remove(&hd.linkQueue, link.idx) + case VerifyQueueID: + heap.Remove(&hd.verifyQueue, link.idx) + case InsertQueueID: + heap.Remove(&hd.insertQueue, link.idx) + case PersistedQueueID: + heap.Remove(&hd.persistedLinkQueue, link.idx) + } + // Push + switch queueId { + case NoQueue: + case EntryQueueID: + heap.Push(&hd.linkQueue, link) + case VerifyQueueID: + heap.Push(&hd.verifyQueue, link) + case InsertQueueID: + heap.Push(&hd.insertQueue, link) + case PersistedQueueID: + heap.Push(&hd.persistedLinkQueue, link) + } + link.queueId = queueId +} + // HeaderInserter encapsulates necessary variable for inserting header records to the database, abstracting away the source of these headers // The headers are "fed" by repeatedly calling the FeedHeader function. type HeaderInserter struct { diff --git a/turbo/stages/mock_sentry.go b/turbo/stages/mock_sentry.go index 0812b019363..319464473b7 100644 --- a/turbo/stages/mock_sentry.go +++ b/turbo/stages/mock_sentry.go @@ -431,7 +431,7 @@ func (ms *MockSentry) InsertChain(chain *core.ChainPack) error { if ms.TxPoolV2 != nil { ms.ReceiveWg.Add(1) } - if err := StageLoopStep(ms.Ctx, ms.DB, ms.Sync, highestSeenHeader, ms.Notifications, initialCycle, ms.UpdateHead, nil); err != nil { + if err = StageLoopStep(ms.Ctx, ms.DB, ms.Sync, highestSeenHeader, ms.Notifications, initialCycle, ms.UpdateHead, nil); err != nil { return err } if ms.TxPoolV2 != nil { From 6a3537dcdd6444250dee897ab7a067cc3cf57435 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Wed, 16 Feb 2022 19:17:26 +0000 Subject: [PATCH 167/261] [stable] Update skip analysis and preverified headers (#3530) * Update skip analysis and preverified headers (#3527) * Updated skip analysis for mainnet * Preverified hashes for mainnet * Add Sepolia and Ropsten Co-authored-by: Alexey Sharp * Fix up Co-authored-by: Alexey Sharp --- core/skip_analysis.go | 2 +- turbo/stages/headerdownload/header_algos.go | 3 + .../preverified_hashes_mainnet.go | 204 +- .../preverified_hashes_ropsten.go | 164 +- .../preverified_hashes_sepolia.go | 2699 +++++++++++++++++ 5 files changed, 3069 insertions(+), 3 deletions(-) create mode 100644 turbo/stages/headerdownload/preverified_hashes_sepolia.go diff --git a/core/skip_analysis.go b/core/skip_analysis.go index 376c6b75f5f..074269f0a65 100644 --- a/core/skip_analysis.go +++ b/core/skip_analysis.go @@ -21,7 +21,7 @@ import ( ) // MainnetNotCheckedFrom is the first block number not yet checked for invalid jumps -const MainnetNotCheckedFrom uint64 = 14178300 +const MainnetNotCheckedFrom uint64 = 14217100 // SkipAnalysis function tells us whether we can skip performing jumpdest analysis // for the historical blocks (on mainnet now but perhaps on the testsnets diff --git a/turbo/stages/headerdownload/header_algos.go b/turbo/stages/headerdownload/header_algos.go index e4dd3f11568..f6672b1c22b 100644 --- a/turbo/stages/headerdownload/header_algos.go +++ b/turbo/stages/headerdownload/header_algos.go @@ -496,6 +496,9 @@ func InitPreverifiedHashes(chain string) (map[common.Hash]struct{}, uint64) { case params.RopstenChainName: encodings = ropstenPreverifiedHashes height = ropstenPreverifiedHeight + case params.SepoliaChainName: + encodings = sepoliaPreverifiedHashes + height = sepoliaPreverifiedHeight default: log.Warn("Preverified hashes not found for", "chain", chain) return nil, 0 diff --git a/turbo/stages/headerdownload/preverified_hashes_mainnet.go b/turbo/stages/headerdownload/preverified_hashes_mainnet.go index 89137463d0f..f8dad0805c1 100644 --- a/turbo/stages/headerdownload/preverified_hashes_mainnet.go +++ b/turbo/stages/headerdownload/preverified_hashes_mainnet.go @@ -73847,6 +73847,208 @@ var mainnetPreverifiedHashes = []string{ "cbd6810bf626e70db5f41fb0bb9bb987e44ed8fb33c863dba4169bb9255fd5bc", "7485e599b713eec84f06e13960b6210417097c03727fd917f4a1acde7c70d735", "535e5ce8f534c72d199e14806caa3215be3853518cad7232c3043f99222b370b", + "4e7ffd7df1684115d3ad59e4e0c52854c81ffca59a8ff431249e2732b8c4d1bb", + "8091070f97e1efcb883efde19e799723dc5d7de55b23f20b030b61fc74b2c94f", + "a1d911c6262c07832a5045ebc56963bb038442b44499556550ee15384daad284", + "4d27c2f539aa8c2d14449ac8c54c9fcb412eb6fccc30307c773db0389007db55", + "08bc8a6d6c0ea39136505454948acb056d54b9394ea9bd02c226bd0282384f47", + "99e594ceae45f7398c662ffd02fc80107292d1b9c861de6fbda6d3d5d9bac48a", + "046b33d20b80db96cc1213bde9477519b1fd1ef2296b6c0f198cbe498141ccbd", + "1cd0365d81690ef6cff18c6ce5337c3409b0908770e89df7643af4e2fdaa17de", + "7ff9826e2d25961654317589db8b16cae857a22f49d9a7cc60139809d94c92da", + "cac86fbd97368e50f57814a394ae7280ced9067d1e197e7a519a829521f22a5a", + "3e8ab8769da77053cdef928d33a8bf019abffdecafb15da28339d3f50411903c", + "27cf8be96126a56f3c89deea2c00a42a517f0a6c67df2e868a52a6c08a4ce7f0", + "aef3fb9726ddef56b376fec2e485f14cab2cc6fa51ec34e9fa25686cc12130bb", + "44b0dfbc2460d89f6726dc179034c5cee22c32c612d5fe136222ec9c5c928093", + "554db327e77ee42377508db14ff7b6d3496532703a160aff7245bfb4997a19f1", + "18a15f5fc6d46623f39afb50eb53d8a0b4bcfe47c107113b8664745f5f3ecde1", + "37738c2f0056bd9a8f902e813428c2b82466b0bada06e65db361a492401a455c", + "fbc177b76a8749b16fbcc6e4d1b4aed6609653607b0f9e5d88fa1a2a8da0559c", + "22e75e2b10de6af0d7d50058a473053e3895219d34c014d72000264be6bb6ead", + "0033d0e50e57852836581c8b07c8160dd46da01fa89e5f40609ec0a94c061d28", + "552889ad9de481f260f9f4b8b893b9d0c96c1b58d57f609a1a1f671b42a33977", + "02d708f4bb9b9ac814e07257305860c603e79a1ec418f02e0b4209b7dfd09667", + "a8d17c45337c58ba132ca2a6a4f92979750e06f08f6d186e1d0f771799b4c580", + "0eacfc946b0ed0de8818105f1fdeaa855d2b9b9235c9008c22a40d1ee57ceba8", + "e5e940c9a8bf613bd809b0404dfada7ef9df8f21d6d3821969b6a9a6e574bdf9", + "46987011ef91c72526cb79203467a17743683b5ab4447fd5b5827960c2bc4d00", + "4bab7ce66fefd6b3be6cbe2aa8926fcaf14b732ea71165f8f631f632f237dc2b", + "634b9bcb4a7ddb1baccb9a6d1e2d517935aebd3a5f521c21d067c93e06ce2c4f", + "5758f671ef8b81df8a48b925fee607bf2dee58714916555585cd889db6dc3321", + "bdb817de83fbee628f7d9d297b5f15d3028dff5d1b26ea36867a9126b3ec55f2", + "bc2c00347a05a36a6f04ad601aa02210c5feab2285f447e9f8317b7730677a44", + "0424e3b89cf2980ee2dc97125aa44357b41aff39580c3943cde2092a424e7462", + "f26f5491546a044e0eb10771643cafe940d0c4fdaaa6b5a722d6f2e86f78397d", + "c81b1e9173f280563b947dd4013fa7e6380c1c44689ae9d32f8521fff4cff6de", + "1b3245175bf2622bd3737f8226500b0d85a8a8e1caf6f572eba472a741c4813d", + "7df24d0dcba4b1eaa13db5edeb8c41f99a16c6ecf7864b1110071fecc442359b", + "0806ded18eea35b8e954d540db89fc74a4e0533be05057298f98032f9ee2a794", + "78df5d586f8c8f9c9146b4c3e6a0c8a70d3cad0a2313297eb6697273c52b81ac", + "f5d3b135f27fd8d700f9a8c6c93b6998d17c1aad89b8a6f3a7fa19dfd5ee7600", + "b97d6772c3b7f17cc7d6a2a101938af2fcca43b1374f8f921458c6d477cf37eb", + "a2ba5e3e8b2ad81a95a2e1be73587715a3d9cb3d69555c8b19c658f5ac8960a4", + "aedacad2b613f8146836bf51c130daf729a158a1201fef0185a579f8be72a1e7", + "c23124d7e34727a87e302d8869bbfdb52ea2052c7752e10bd21ea22cd658dd92", + "3fafe010429e3d99beef0456c3a4c33c3c442c3d29f1287682d4048a630254fa", + "2ae48caf9234d3d4f6c0d782f50e123d68289aaedbbf7c1f9aaa6f48cd830b58", + "6c643628a5566edada8ea95b21e7e07371cc10a60c4d8e37d09a5513208387d5", + "08dc66d30a45eb7e8108777c69505974309590235744076d1991c85ecdd0aecc", + "df2398bcdf001629115c95a5237cb9c24ccbb9e30a91817caf366be629cfab30", + "29c8553a32337830e63f8bc9a969774615210b617f27d22afbb44d33b12c6b0c", + "f160f8b0c8cbf16d8041d2337739adf6d6c7dad3f4059b13e60a702f1a3b494f", + "5c51cf93091db4dc82d97a55c2cb86b03904ac643d619fd3419c662a181c2862", + "242afd8b0380b76cb3f582d1d6f02a179ee1aa2580346fe031f5fc00bbf95724", + "332b9158a44e1fb6ba971b9bf4d7da0251f4340a72a0e6804ccc5e78288f9da5", + "719beff6bde874dbcce4b73b5bca3e9a78f44ee98ffee94b818a60c85caa0ad1", + "e59bc5c6e8d89e465d0738c27f3aaf7216f44d7673d2e9019e10aaf6932ceaef", + "ea5505c90e0a85166c045b4fdd9c6a8c42e108282a0ad1bc93aa0b39ca3872f5", + "e1614770128bcf134a502ee6284f04f957bc3781f5563bd677902477edf14b67", + "772d346bd153182a8385fc8969691acf265571a1fc2df67642b84f87ca2b0178", + "2421caf3a601a1e89a6e851e8acdcf795a5b05bcf78d9c67e3c8c8d2da93dad0", + "6a36e4a6b06214c9047755af7c8db3f85f4524bf82955ff3fc256eff67f81649", + "876de9f8dfee13180fe35f9524737987e1a3b5ec1e2ed8a7e7e2205798833e43", + "510efaf4164e58b2b9e89ff46521b534df85702d984f9cd58d59d379fff03d8d", + "a1b414b6f372c4f0ecff8b60f94fd39188de9d2827553ffe4f8249e6197fa534", + "195a0b1d18f1cf4fb4ba4689fb3bbefbd00780af79fae22c2a6577d723489aa5", + "c9b2ddcde8e8cc6087381e91bf9d562277a05285cb3e7c367b0a7ccca5a8d1db", + "ae0e02786664117dfe308b155252b481a30d1302ee5cadbef3a4329fc012014c", + "4b7229eca000216887bf047a8c14950a746e4ef3333ef96aa3a312e062f84469", + "ef8dd7920d24ac3a4f09d5a9cca5edbc05aeb6c1491199b9cc25e3ff5598c61d", + "f8f12487ec681f9478c788f82fa7f51b9bd6db5bbbccd5faa6442ac0146742a2", + "a5254c81c7b06e87112f410976ed2d08d3030979e46087bbc6c2c755e777984e", + "015ca9eff0a4586c4e3c4aaf194aaf8596b17043aa1f4b8d2e3045667ea3bb21", + "66ac7ece155ee8f21d3b548b6412c6c7c33fe0f9ea08c727ff8d105fb5d8e9b8", + "b3c1579c1d97efc4bf793be2786c77bf2eb04e0e46bb86ff8996d61f0d9c029c", + "f8a48734136ec32e4ce388ed7ef0c7e07e3db29985fb2dfe97dd4420ce9186b4", + "fe4673b91765fe8bfd2a4e3640689757b95623b29c9859a56e08f8a2a9987f4c", + "98dd19a1cac7c69b45d29545f839cf83d7cc48b577e7e72226ce77db08e20af9", + "881f9a66f21d3735e681917bb2d69ec3bac55de514a7fb2ae052768251f7a25b", + "7712400671b4351fa650ff752b1735854a782c7245353573fefb1a7b5ba773c8", + "7e9148903d070da926319f4ab976fc44da846d40cf51f081fa710837dcf63248", + "bc8e5a8b9439ecf4d537ac4d2e6ecc095b4134fec2e293f1448f8c3e8f5249d7", + "8e3765e2713359215e340ddcab7f2bd653b921a0bd7bbe2724803a7eb7deed61", + "f0b90f8eebcca1332462cdbfdb33f8d0e392f3ececbe67c4464b90baf50ae729", + "03b0f8c3ce2d2aeb8bc44abc987f34f81cb36670dec932b5ee575f20a2364607", + "f10388702a9131b8aeccd641ed32bfe9e2e2c18d8c689e6bc741eb11b42ffa27", + "c800a7ef49f2e0bcc3ee2f8328d299c67fce73d97ff5b9f20f2ad9db129c5d67", + "2a2e6671686e48c7c128b9801fe650d1a644c46c2557e88e798488564873cc33", + "a54b758551c95d5e62c2e0ef3a94dadc6f3c897143cf15a2f7903981e0b6e7c5", + "879567d26c6d4914ba322b1ee51e09cf8e10dedaf6ee91fc6402380c7fac810b", + "fc107f53bf51d70682172a5818a8ed5ff0bf3cda99401d15b813cd67933b3e9e", + "ce18048bf046261ca0939c2098c720c574b67c13edcb21042504773cf5cde53b", + "24eb9b54a632abce5bb72eac3daa54b8f8b23372e8a214c86874289d1b57c87b", + "e7ccdd94efff28f1027653a8fe08ac86e62d706a873610c3169c28ead56705d7", + "b2d4379967f0eeb9197a3672f63fdd1219435478f5d79b5b96b5bdea281f0e6f", + "1d8d9554ba770cb17d305cfa7cb94ce0d3fb6171085880e6601b167450a36437", + "7423f627edc4922fb0daa3b10f1532471269b3a147326b8105ee2f1b36690e3f", + "80df06a25e1ef5825a8ce4b9e700855a10f21dba4ff5e6f0d136289960b41915", + "08e6263d0c268454c31a1df7ac82054551161142a860e4385e56df6530735442", + "4d86974a34a780b8dad8fb501b0c8d32cfcb301d5c2f3844a12e00d232d09bbf", + "00c5773c6216c30a97a806be4be2de4763de59640c5524f2b34bfbc895d85393", + "4046622356a61c2f34bdcbbb51437f69be2f7a031fa702a95fc5b28107989122", + "ca30d757736a5d13773e84a346cf5470c771964d4a200ced30c2af7aa38524ed", + "7ba580da345717c8bc26f996f647e5c524b068053b9f9cfc35621eef12156701", + "e37759ebc3f4861ab231ae4ed576ce2ba20ac80eda07c2c00d4369b885d798ea", + "abbf3d07f35fa785414244d0cbc7dbfb3e365ee1bbb3824509f529709f7fca92", + "1b7a26cc953959dc7555343126364c2df588974bf6c236c55ec4d870ea000647", + "7f42191a2de697df0d77c0e9941434c8aea57924d46879837dcd8b5cdf418c49", + "ca18861355f254df4f524b954a16f4707fe42d39d2fbda6ccabcea3d71e6b221", + "a1fff4be56a92935e5b76f55d03e3050622ed5b8db3be12e97d1dc8c86758ea6", + "7976a3d39df7dd080c81b75d78f341e97526aedc2e5565627075fc50282a9daa", + "2e5cf779041a7a14867b574339ae631fa919c892e984e7bb5c1b4329b0ceece3", + "53865a90c7eef774380441b6ad82302573da9946bdcfbb5f6e164b1a7b3ff80a", + "4043d1e7b2401762f58f2925e7d46a9caf2aa359fdeccd5873d3793adb49ab24", + "cdad08b4d3ae7fb33428b7578452d87ce7e9b94c76b087eb7e3036a2086ecec2", + "8f04a3242628dd789eb34d2b38e08e31b4da2d6e24da547c91e2adadbe6384c2", + "3d582b8953c58d65d1e0ec58b9766720585b834653edc11fc62fb019364ede04", + "78ca807eecf25175f624810d7ccc79685f285a89d9a5cd0267536a88ebad6f1a", + "f1546911fa55df8563bc7320d3593a441a8654afc49de18b79eb1f421aab5b56", + "28aa51014fb0ba36e310375583cdf290e171951dd453bde5d2882684543cb30d", + "afcd21eafc3b2bf87e124b85913ea830f8c5c529ec071494e2d8425e524d1361", + "e047e6808cc3e0e0fcc627a3d830c60db07fb220c73a6265d0dd5edcb645b2dc", + "5989b4ae126cb15fdd3a6b13cdd8b9eab22777a3a887e57eca6f042579055957", + "47442d4a4177649369f7aec445d4f8042b7f444c951d75ee5b123f28d94dd678", + "1e34eb021cdce5e8f1832c08e507572a403be4b1e69a3994c060ffece8613a29", + "267258b23419dc15085d86361e399d488b57e4fa0fba43bcc110936ec77f5bc1", + "729e3155d2a14d8582124d6e757c13194520d052fe35b9c0901c4d545341b293", + "52ab518b3c2563558fd39053844797868ff4a0acd0b169a9ddcf7adb5066b894", + "01e1ba756aa110b966c227098462e4227c4473a3fa5ef9f2c76dc5e01ee6957b", + "19432de17c506eb597d78a39e101443e01a64be73b0ccddd0414bb60e993f799", + "125f77633612679d088ee8d7eadbe8cec490edb60563f13f88fd724e5419cf64", + "e37a03636107043283067a482822ec0a8dc7b1afb569165696991e89bcc3ff04", + "2aa9924e93a7caf96cd39536a731e2cb323a24e2dfc592a784e989ed92171289", + "0ec35c5474abfb2303d676922e95464c13d073826f90e2363007aabe5fb65fde", + "2e1451730cc64f9bc4958ec92bdb8782718e54afc232330f62fc7221c8729220", + "38bfcc5deea36110e02b8c5f2f96cb41ceb1f64f3fb59107cbba920a19b1ad5d", + "2ae71954e31d00d851893271f5317b688c7c342bb340f85087cac8e4eefe3765", + "acfd985882020ed6c1eecc58061e70ce8f69467f6c66ddd2964b623dde0e5bcb", + "acfae2f0315c4477afa509f846adb945f3b797c46ee636d5b637d20d85c7bc6f", + "30b351e70245a30a32ac5ec3b2186856bff707feb47bf3d27d9eebbc9c1e4b57", + "d23a0c368e375ba898ed0020c57a0414ffcfa1e26b7cf603e4af7eeb95ef1723", + "f710e658153f083895c5b827c78a1312789cc4d8c208d234ca968a6738c758a1", + "cd4c4ae092d1467546e2e6ee77e58e5f46041e0a2eac3c68ed5714216616479c", + "6fa025f88af9146df39f48d37b2dcdf37b161a7453deabb1909d63a2c2873a98", + "b22b162e0bd3c4dd6d380331cb47a6dd6d5c050646aa82b04eeb9d90c67e9de8", + "8154934343b44540347e0087fbcf6177bd5665614fff1617c37092daab232fe9", + "ddf566105b54ccd83b064a888095979796e096d286bd938da0da02fb9c0f924f", + "499bf36b01a9a2c59e410e2c397a2d3a3e74740f30de96de620bd3c968d36b8e", + "3dfcfa3edb472d4fb1d80065b7ecb138a9ede71312472187b31376ee5855a712", + "1306ed4e05a29c7501ebf4aec68df85fb4c80f6625dd09a1ba471ae88104bb64", + "69b6799eeb2ab620620c202372ed82e9fa07d171677efd2140885df5c286e687", + "9a862aa9a41b0d7a73b3ffc276e149d5a17e49f4d46a77ca4a1fe10ba483bb74", + "f6669f2e728d059ce6a525aa2c66883a05562413692dbfd0e8241d357f34533e", + "7865429ed9da5a5ddc398b17731932d775f8db3c3c61222a04d8d248629cdd44", + "7ce5793d57ce2129dd353d9f2edc4948f4ef3f50bf79d3aeda90a76f4239fa19", + "1c6e122aafe95141c08341d1165ffd59a60b1df0fab8962f84537831410ea005", + "84678bd7b7f2c92598c099a0bdf5274eb7e9a27342abb7918dad03724ad06a7e", + "917ef67589a961bebeac70f1c78f7785f586414ccb01cb3456b156e59c3acf94", + "27cb805ef035246d72ceff17cbc0e3c305a304f500aad4e205ec3fb5fafebf96", + "4da16938167f7849660ff6a78d463ec102401585caf234a2c8b446427dd254d3", + "d7a476d343bb1d2c592b82821b1ddf98d3f1e1f28fd5f9b93667e85ae03b3346", + "d4cda5a2013242acfc3b336e0a9bf0ad17ab24e6df5d18af4c2330abe6b28346", + "b6ee739a3801179dd4d7b9d369719fd386a1e39c008c69fa62311c94b4095fbb", + "7fdec80d0c1b4a2ac7d01557d43f685518fc017424d13fdb92b21559f05636f6", + "55bc317b710d8940da83ee9e73bf9d754bccc31031f7a6a38e53cadfe6a000c8", + "2ad24eec253a961708ce3e801a3ed80046fec27fcf1da9694f72ebfb7627a6e0", + "a736a4171e6cce781fd8bad781766a83ea291ee42a7d0c30b22589a171049d6b", + "f6f9147f9bfc52be4056411bddf4297d7e57a4fdc23f5ad67089e61f9605b334", + "4a570c3e909cf9e104ae5087b187d08ced0ed21707a7f0220dc98a7010bf20d7", + "5e5b44f80903d9a901fde9b25ade9857de3659ae3b7503c249ae9b66f04fc5e5", + "b3dd4ba8a309df4c07f5f823b268f750ad69b3495943a1d0687ee0a9ea6c0d89", + "19f19633979deb57fc7768b5bcd47983a85a19d143feb2732c3a24d562aebbab", + "cd340c069484e02b304a5e4de4882dea11ebb59f6a759a1282f32a8f7cc5598f", + "94e5ea497928058ad856d2278f3ec95e876d3cab4166aced1e02f02cd1cf301f", + "3255f2d2cdaaba85b99437d9f9dc54e6a0ec9826bfd0605c9b306164d7c934eb", + "cf318a5eecb0b1f327033a329b0a8b1a25b805550a91e50d863cc392b0c18eb2", + "637f97ccae706ab65025ac2ac2ffc13012a8fed23d7e47ee650d299085ad63ec", + "c5665bb27e25e9847e6687deba845574aa81fe05b7a40f7d4516698e831b94e1", + "87ae9f0c14028cd1acd786c620f44fd591bd96141de390039aba8de0934decde", + "7cbb1e226323bf38a62e65857a99472773baa6981a460976e2a101048097327e", + "bef4423ea72122e37ec5d1792a86a44019156949bfa830dc99f07df5e81018b6", + "66898c862bc05dc214b6d2488d2ac0847fe69cf034b796a4918731a819d40e42", + "3d32540c39eddb378a68709f04bba80b5892cb8238bf1b6d86148c783befb5bf", + "2cf8c97d375e4b50d8b166cd3b2c9ed35cf1d487ead7f03de525104d6526731b", + "4a790eb004bef560e05c79e48ffe2ea3011abda24df1f2f6cfebd720ba616ca2", + "616b02cc5031a40975078e2ffe8c0dbc5bb76845cf0a2c5d963a730a68a97b0f", + "596ef2296a03845b2b8e69c7ba819f6b20c5047d80960e515841194429b6f2a3", + "03ef7635f4e1275b747cbb1ad1e643d011cce6dc1de47d957288feffb5d0eb8a", + "1250daf2b14135f6d02553cf17606f4bd20c67da778465f66bf9ce22dc41b450", + "32ecd47b833b5477d62d6b622ad7159d13c127d324ed082d39fe0a1132950444", + "09f4f1c55ca311aeeb507d505d568be58b9e11099c20080e9e164cf3f064db0d", + "0dfd156e6f22d40a682d9d94c38b19d62edf0d86def7d199c38d7fb9c0f5c2fc", + "2e05b7b29915bfe8a985f73f30a84addb3592759ef12131f1d2c59b925905d8a", + "d3c12b318c793c3a67b0f875cc435c46c2ba87d1943d31281638b2752807c992", + "d38c393daf6e21d008514f2cb40f034f27ad48fd0f1e238181816bdc4d7e7ab0", + "0700606f01bb9491d44a1403cfc0748794ef2068f3782565cc7d45f0b0a44455", + "f19bbd37641bed6c01e52278dfa0753deaad0e8e4e6d2847c2c0921286c6692b", + "684743dc6c1169c4eeea3c5d29c002992b2655483afa45f9b8c35bbace9e75c4", + "364951aa88b1ef09de48b9e1b7fba3e9f9e2e59316916b7921c90844ea3bfdd9", + "9a7d40bfc2537123b0af0e44a1550e9d597ae7fac3fa67b61bb18eabc707c039", + "39c5688e6fdeda198f3849588ec299a39663c7c119d5b239eb4811b49f4cd7e1", + "32fbada851e3eb67ba9254c7c578990dfc57ce00556f992f42985c3eefdd5313", + "9672917c2cc8ba35e65cd7ad5c355a16e98d525409b80fa4b7e2a2c30dd8fc5c", + "ab82de17282c5944afef9c72c0df68b24421d28d59f80090422c16ef376b299d", } -const mainnetPreverifiedHeight uint64 = 14178240 +const mainnetPreverifiedHeight uint64 = 14217024 diff --git a/turbo/stages/headerdownload/preverified_hashes_ropsten.go b/turbo/stages/headerdownload/preverified_hashes_ropsten.go index 9920dd33435..f9780abd7be 100644 --- a/turbo/stages/headerdownload/preverified_hashes_ropsten.go +++ b/turbo/stages/headerdownload/preverified_hashes_ropsten.go @@ -62214,6 +62214,168 @@ var ropstenPreverifiedHashes = []string{ "dafe61b81f4b505ace111a0d7c194ddf0db09fa5655124842a14d31d3a94b313", "9e1b6147f22653de017e726b1206da2bfa6dd8f44d64e35df08b853c140c3009", "5ad2411e83feda15df68a503d9e27de3518cd5e1a74d56add8d9da6de4bd74be", + "6cef057716774e8a1fede7c2ef2c9301ad2872cae92987a392c547d33295fac5", + "7d8508138ae69f0997f589fc637692e4f6bded074291b8437a7f03234aacaf8f", + "d99681535850053d2e3d9b0a9b909de7c9a635bae7ad55b68e0802872d62aae8", + "c7df6ce16047aa20efc20eb2856a9ac639146e7c20521289132ba3801ec39f60", + "a8346d76b311c396151975c6b7b6c57bc5ba77523e3b4b428b6544287c054a80", + "4e011c402803a03eaa54ee4582e21fa96f138f722392e97db23145f6c370a327", + "2cb9787df9bd2962b2b92297e16e605e29ace9bc1d4fdc6d827c40f44b6f31b5", + "6368fed8ab3c3119d0021856a475366f7d0546e7132a5efeaa3407459a6c6e3c", + "a0929d82e07c9968644e9522416137cf24b8e76835bb3eeadace1c625bdf3e32", + "c77a7932d38053fe04413b42417945f805afc4b256e1d9f21be678519d2cbfe3", + "476fd0d1fae3ac650534364b1702abcc1bcd30ae550ffb61bd14204a9303784a", + "8d3374db0bb84f1166ab0d668a5b1e61e6c295949d9241a92db339dbdeb2a911", + "72841439893a25621187d8d1f0ca2a069b15b9a8f7a56d8380615ea420674c80", + "c4a8984692da5db00685aa971915173ca5c8f115a6a7428e77c181a1b0b97f4b", + "8970ee65fc91cf5adb652b50a86c46dc2fad672b912c8a53a504c4acf52f44c9", + "901090d832093626fceed47eb4edc18d79b743309124ef9c6588a039062fe2ea", + "9f21b3e63a51564b8f369c1d34e5e0632db289f5809f5e87b4ad340b4a9d79e1", + "562247b277c28ee1c597df22bb63b99d99b7c335dd3a97ce373a3ed1a78f2078", + "6b06c8b7e470fbb9ac9b5ea7fadbe883e95c83fc7964f4f6f48b8abc7dc928f6", + "ff5dc114887dad6091624d74dba9d4248200186b81e188fe825205ee006b6ad6", + "4953d955dd35a0dc6a8f66ac8abfb06fda788b8d9b25bf1a66e642b926ba0ada", + "25eec5d485737c5387fcb1d98c21b2ae0e75583ff638895520a03036e0ff5cfb", + "0e40f73f278580acfbb4409c069c5c4d691fc95b327098f1d61b1ddd484fbc6d", + "adf6febf2554d72b43b77baa7480e0dfb59a570012bb800af23eed03f64e0ee0", + "355f98f79c0c473f7a191cf6bae84708ec6fa046b91bd01997b0a05a0610e200", + "d689cc41d8bbff324041cb906b5f0f7080f07d09c1bd24bd465112576f15ba56", + "a326f07f52252d0035f4997bc10597831404ea2e064c1f47ebba0065940a4de6", + "c5690e01758d8bdd014f3d00313cdfba96d20023090716c266e26cba939d4dad", + "4492e1a0d023fa229665a142d035e640e1896c216eca20360d76432d703263b4", + "585351683ec2e061d27ace29c20052dca9dc82d49282df66b14509e02aa3daad", + "bcfc261bf483f64f3dbb376fcf4831cd8ea014c97b807f9bd7d48932613cf790", + "6b7231e3f61d103e3656ee18be2bcefb62d85c4784c9b99c87ca29628d6ce259", + "1a025ce18a92551629018f3e49a77d0d88efe9b602acbe24367b37ee96fca082", + "a5fa1d1d563ed63c67c093bae8856838bc566e0ef7bc24790d38a4c198937257", + "278c7fb4a32d36c2f0db0c9cb7d6cd15f01ad04c4c9c4ec6768fea9671feaf6e", + "c04d3412c2f28c769e6504313046d71ffd7de8531e41f6385baf4a0db3760be6", + "6741187772de0b4299cbcb67e19d1ae61828c67f67665f30d856c8b23d78d63b", + "e0990fc913b00e429dabc7ab2e0cbe644e6a8ca954ea60eb24bed260c07cf8bb", + "453b90d24413a686c68116ad21144a36bb1cb9352cda1d029c8e0228157f4aef", + "8d705a079dd0ebc5165ed023448c4e4a7d0d240569244b33bf62b7715c03e6c0", + "a308daf17d2d8efa6458c2d0b662adaf40161eb41c82e6b2ee60d0e74dc06690", + "f7fb18b20e9491062776433655ab470b4417b7a944960075c7cfd35c153dc0d9", + "dd4317e5d537e0db5b821f93b06356f39d8e5daf107338201016a01a82ea5b9d", + "30411bad56e63ef0d8d60b2ded937d9b033585afd302614d96e125075574cc3f", + "f70ef4c6a8b8f68532958a8c315541821288e68f750b3d9802fc249c8caddcc9", + "559776816670c01f60ace351abade02a47dec251afd8bc99265584b2ce2ff080", + "95f2fd54eecb0a0dcb975adf803cf1989d7b09d170398c1ff814c82e1b2a01b3", + "653d7a2560f75a8344853cb28b9d8c6675a9a717861005681a7f5ba66c7ca29c", + "a02b5d296c6686a8ef1204e3249485c7b4fcf704e0afc12b89d17bb5e6be4bcb", + "b4dfe7cc97d1478149e15ab54a82f221f81e47035f57a0a0fe76d6a0a41230e3", + "80b37e0ae2efcc7a8d50e413c026aff1d8cf34bfd0fa7258be472e74d1e9a328", + "17a5cf12e817f0582de516d074aca3152da6114e17e94b36ee2210eb5a7a9f7c", + "647891d7f90fa42e3198b34d9272e32451b9c6a7d8d1cc5d0b969f2b75ba91d3", + "e11bd337b920963e05b56149e051cf461996f4b4dd0aedcf75a2ba2d0c9066e1", + "99942090cea8fdfe5a9d77c52436f84c1432f04c39b1f225acd1282b658a125f", + "83506a379b5fd2a4fcdcc390c3bcc3c38c2cd925b51d8f49db68208a2f6b973a", + "b70d6abcc7e5af56dabeb58d3eeebe06411d1292f1b1566f115737250e5e787c", + "0e155f5fa1e61a1f9a3dcde7bf1daeeff2efc6483b867ae2a7b9f1cc573b274a", + "1181c04a1238d8015a984925ba40cd886277532eeb6ffb4f03a3e914befc6f00", + "cc2bf805e8874da21afe6a7bed08794d684dcd08c881423525366dbee20e9ac2", + "78dc042a3782bbe8be05695282b1c9eb503ab3b093696db011b3703900850346", + "59c08a9d8ab671ec92bf4065883e9c6118c8367aa1ed76d0a1e72b4818b20013", + "84d5c0f13d1f1260a2179b305a21f6038168551243d43221b90a63ef85d59c5f", + "2c9b7b520db01624bb43e81f5117b9c743a3f9b48cfcc41c958bebf7003c305f", + "eb7ced8b22993c252875a9c7d25508470e0295295ba77c666bc69b27030060bc", + "44e0ee49acfdf084800ca25b9f976a21b1cd54add920a2aec1bfcc71afbfc7a8", + "bdacab5bca3ca61e5793aba15863d254151a710c98ec8c55666a590a1fea1b94", + "c2dbcbc147a1711b59e6df7898f09f170548ebda950d055eddb224e732f2d6f1", + "dafa15bf0cacce1a49d373b42a01d8b9ae7ec28d83a3ebc5849888674e25465b", + "53a533c2568de409d1f959963647be3acbb849e5cdb934597aeec8d944b5be1e", + "4ec191cb8679b19cf6002a4bd2c5bff92d7dc5952554ba7178fccf0949e55ddf", + "f9d61e333aa4d2335061f872ff2b02b3e80a1af22ccbca9e869609d09ade386e", + "e2ac690b9b3182c8d2ed54265d17d1581a2d7d9b475b151dd4a42132be5c30b3", + "3f99e438406c3926224d4134f84f6afd998e80bf9c16b65d38915ddd4b3177ae", + "170c581a62a3768843debaee33998e6780029592746e5234734ca84f8f4b8f37", + "cb3ab310e14a7850215436b2c74506cd3a03f2a178796589e39c95cd5acf550d", + "4e8dc5f306b773d724417bfb7fc981bd32a5256b1baade9bc97628031eea1f2f", + "8a32d0d6652924f4b176024ac0f6aa599dfa81c6cf30fa375327a0949de19f70", + "b76a6637b6af9477ca83299d0d6431445adbbe1dff69cae5a66eeaddb27c685c", + "587592261b68fea3c90abdaaa48adcc6582b3a929497fa42b7c0cebef3e570c1", + "acf79e727cb731794219e31090c99192a65070edd5a31cb9db8aa14a07262d11", + "ac7978364d816940d6e62c59e395b056e57b44b3d196ce437e6786606f297436", + "d1f926964154317f38caa771cfb1adf765538647c46e7c62e3d2a7b0a0f507de", + "a28b451c0393e888f1f9937eed4b1e6a5bc665b2b7e486dff820e9d2477213a8", + "4b7530006ad542715512c12bedbd650b421c9d0d7a23d05da246002aea73f21e", + "d4848c7486bf8c76d1710496498c8b7076d539304e702eb4de7ad1a0660c1f4d", + "25be6b3d90953954f82f52568839f3f29fa0d4c38eeede914d83600473be2112", + "228ca34739e36808d5460e638776a2b6f3ea292e2db172c397314e9736df6136", + "ba5cd264093e029d05d4e5aef19f984177cc5b36f0a469eedee72e3f9b82efef", + "9fe3b4fec16c2bd430a6a785f920d271bb2dc67f095965fe6850110215bf6830", + "4350904c6f28221efcecec487016977125d6b73b584d2c2b269190a082fc94e2", + "5d63b515eac1206b4f2e1f4cca436f614c56d33ef3f697e1310ff767a592dd9c", + "58ff5682fa9ee777b07c77602afec8098cbfae0df393cee100dcceca84a5fa29", + "d6d1ab71c4c34a6e68d85eb20d65cf1773aadc7790b5fd23b8fc05c2f0dfcdd3", + "4012057861420efcb4fc515fa217107954215b9be7b35c6e9f5b5e360a176a78", + "350b1f50fc0f2438cae2389b09d83a1541cafaa09903758dd259d5e7ed337188", + "89f2ead1e635b98f32e4b74585020e9b82c5cc60bf6d2519c6b5ad23ce3c7c65", + "7d836753f12ba13ecbbf884df48ea04275d1e1697d7e0bc87752e8153921390a", + "aacac5d0696d9789b36f0ba74a5e226c3861c28e85e8d5b4b5276be2cc602baf", + "15ea7f8b0d708ea0c835c2406d237ffb4a48607a47696725f635c68b5a573041", + "f6e59091e9bb52e36c8990aaeb994a5f276c95e8ec31fcac86b2834921c570e4", + "06f536dbb7c18410f47c2658385ae9ad8f4f282b9705cb9a7d09938f7f0b7812", + "0ce0c2f85758cbb6e674f45a0e64ee76872d1f7c4aa804e0891e9d1b43a4e857", + "d21216dc7a154b9edbe4a441746dc77daacd59dfbbc5265c3ee4d58e8a99c389", + "44e23751110e8133d0114a30a0d61757af217ca2d51ed9fd16a683d553013879", + "cfa5958c18fbec013bf6794b740bef82968dea364f3713205a1239d06e7d754e", + "8700a26da119065aaa7805b715dad5ccfef4be43fc773be15b991448f08bc18a", + "d8ffedafc780c11dd709a5b63ac1f2f547df4968d701995b837c9a3a06335a46", + "0d5a5226fc9f1c215cb0769aa82fb608fae66c34f6635993f2bdf86e3415d8fa", + "03c8646933ca39265f69cbc6def2436fd8b74087910de50c3f9503e39f79d66c", + "3031bc3d13991426348e45c7fb93ec4b994a3bfeade73f04f3975cda8cf33870", + "1a4df27a89a731c7cec6a82c65d65875c366c0fab0155baa76732226c21b2f6d", + "7d05c72a4f3ded9e87fd74678fd76039c20bd94a378e1736eb790edc99492720", + "85f5d90b0af001a4ee281e2c52b2a9f2f942a9457eb526eb0afa689cb833d296", + "b684ef997ad4273fa2313f05144a2d25e076f77ba2d1ed1f61f8ffa10eea8067", + "eee609785b527cb943e15341367c326fddf08adaa929a2b087281d3d0334e678", + "59916c02b51bf6dd373f727fac44f1072a2125bfd87bbce53a8a0664d63d052b", + "00eefce36e615c8fe843e4765886ecf799576de5365f87c75c6b768f6e31d65a", + "102bca9d1d51336afca4ec323b61b59e5279991c18a92a56eed0cf24ebeaaf3e", + "a69d78c55a79df3f649a00873dd5d3ecd765a23cac656af9d076ec8e0404ada5", + "33c2f3fc5165108ebf5a181c1dbb7a621d98e35dd060f02008e2187ad611778d", + "d3e5ad1fe4a2a63306ded66971b2422516e35039cd40405095ebbbe10d3eb75b", + "704f4314dbbda90866276d6dba00435adcc32c1f923012a23a26d3cb6995dc87", + "05cc2ebfda03682e08769e5cf313a3ad3dd106baf01cf369854bcdb94292264b", + "d5a0dd93a80833f9592f3e93e38f3c733026b1926857647979144f3dfcd94999", + "6fbdd25e462d398080c3be5466709aeece144999a3a6e9f9b19a6e5d25b0b9be", + "d002811ef276627fd0bd326b76a203462c8cc7f12d3c42c0a4a330d0a0812692", + "c12d5cd592cf6264c791a03413526fcabf11635313e5b795ab953fb9671bffb7", + "9ee615a9776079a05137adf9e729142340b08560a9a2baf0fbfec8ee60304788", + "2f010e2c103bdef4f034fa946739c6abc3f7b594921a285ab82b12c23e3ca85a", + "3a88d42956b5c1304cd6ed0b7438aa2014c6e98e2fd7783ef2e50a4349d2ca16", + "3d81858555634180d51acf97fc29bcd2ca6f20fc46cec43d26b977358a01a84f", + "77e75eecbd062a3805fd227ac5991241176ee313efd1c8533bbd658c4842b5f0", + "831f6198aa563ddf1fad162ebf1ef0dc62a0e702ef56c90e005790e89ab30e30", + "2aa7eaca017e20c48d354fb49b03c9c77281b795a696103444fe89a19f6ed5b6", + "2ac2dd7db9527f0fa5ed650a14a32a89cd9c2a331e452b73084711d6c7e0629f", + "efaa5c13b8f9a968cb34602b5f6f5d4d6a95a7b2992592aabd0668e73332c240", + "58c42461d5f43440a2a6e959ae90060532ac0adfc9306db4bdd447580616e5c5", + "d4f56f1eafba4b70c5a17c5fffdde64d7c4da698063809ecfdbc3c2d9a95fc61", + "853e3a99a840975823907849e541ac634d478d2c270a203202b2fa740eae5feb", + "e6e92ecf836d7008698d542be72634dee40084612139eb1d87251ec65610d0a2", + "17228545383662f25c60790eb96fd0bf802804980d3b7fddd972d6b957a25d0f", + "e0ce97f407e1210a52fec95915d3e26da9527ec84644a1f35031c1d10fa33099", + "4e804788d3fd3f7f0b7d637c6995db40ca640f87e3622e293ed5dac240b0e247", + "cc966d76a32492ac3fb1ece3bbc7c0aefa74bf94926a9624a671ad23ff7dd70a", + "54fb55ce32bcea62b92b6b0ba703ca5fa6fc562eae087dd98e97474248b00c58", + "75d546fd3b9a5d3892e24b762d944fa46c937934d2042d3cdd571cea9214ad09", + "6ef6637045716f720f3279adf6079acd695c1ac4aadbb4c7d8e2fbb93b733cf6", + "1bea827009e931c1cfc8b10301170e124a1f9416dd9dd4a5a0f6cf6833d2a200", + "6ba3373931ecc0a78a079b224ca9348ab319990e242fd3a181825081fc4596dc", + "63d435851bc3852254c8d398757195004483b16aa06a0420f5da19f4163cb332", + "ec384cd62e4424408b6e6585756e63b7965cc9963851cc9ed97f7a3cf66fd393", + "118f90563c6384077a1a8822d4a570f2a9ab89f992c71652e8d3a2fa0cdbc329", + "412c8777b3e4fbefb522af6ce3a3e9b97d4b8cfa74ba8972ba4cb5be33be7218", + "e74e38a9e40c6e52a21859a877ac67fd360de50d804f12309d68532d4669d36b", + "cc26d506030edd8a580b9f2112cb80a50322aa7d44dba1155dc429f10d3bfa66", + "c058f1729eee75ae5c55cb8c5980c161f23cd3d4252bfebb1a9bae9f7dde6992", + "15a8e388117b604e1c66a472b07ac38334d7cf75e8e3adb1f4c0ed370c6e9b81", + "58a44a5acf25b757482ca3d933db7dbf8f940a07303e02564f43afbe4696046c", + "d754cb92dc79fec57ac696c03cb1a54ca97a5e09be739af2b51967529739960e", + "d12cab13ed7b52f60b8aec29714d97795e941525b6fe66acf5a3c2d4c37ec1ae", + "c17e24970ec4f561614b8ea16eb8b63d32b1d2c7c5a6c540108dd53f03d4d534", } -const ropstenPreverifiedHeight uint64 = 11944704 +const ropstenPreverifiedHeight uint64 = 11975808 diff --git a/turbo/stages/headerdownload/preverified_hashes_sepolia.go b/turbo/stages/headerdownload/preverified_hashes_sepolia.go new file mode 100644 index 00000000000..bfd4d0b3b41 --- /dev/null +++ b/turbo/stages/headerdownload/preverified_hashes_sepolia.go @@ -0,0 +1,2699 @@ +package headerdownload + +var sepoliaPreverifiedHashes = []string{ + "25a5cc106eea7138acab33231d7160d69cb777ee0c2c553fcddf5138993e6dd9", + "29c22f63239b38b3f9c5d218b10c4c4408c82794aa5d98947931349d9866258a", + "123b38318aac3fd648ac3a0d614bfe94e27149301f899d78cb527e9f397ea1bf", + "060828518b29fc7c6a0833551b3fadedfdb8c2fb97e865372839e8a6726d4235", + "9f200128c16fbf030279ab004ca608b52cad1a48e92d0e3d94e1d98c8293abdd", + "7501661f6643ea85ed972aac961ef446643e399c4c228d18cc2c0593fcd4fe50", + "64c23bd0c35fd9e7a7deccc28d5a2cb14deae96582d8785f16e03e8ea1025613", + "25bfcc6399c8bca8c9a6b365913fa27e48b5ac995763861e06512b7c6dd33334", + "c63581320174097c8e4500a04e827c52bda3fa8b0edf78cd62b46c4c3281fbdd", + "447cf75f04e9ea7ba8a931e95c81926828b76186692771326fc4b63110d9fba8", + "deff58e46d3642d3eb835335817da69d7d300493f6b3564d4a0da1becd1d2881", + "7f656f840809d10fda8851a651f0fccfe8c76aab95c501bef75fe7a167514c84", + "8181a84f009b6b1bb79e14a9239863cbd547399dd969b7576a112fe20455da9e", + "05e1f0bfc853b94be5db9d4292002364669ea9c3dd84d08bcb3a686db96bbbb7", + "0da53985b0fec314bdf4cdfc51ab0a190152b1b9d47f4b1610b0192e0c755c0c", + "ddc344695a1fa9535e5c18606d03592833d806bc7eba304715686e668f2f033f", + "6ed9db1e6fd89c8f63768981de47ecaa7c2b2ffb0d3d65d98cc292b5e527873a", + "f80a595b57e574603b871bc384d494ac20169b7fb690dcab1c7b885a4318adc8", + "c53a71a75736a0f50f574730c571a1ae9747edb02bc86ad833a0971121fc2d0f", + "df4df5e928ec1007311a941b1a3c9e07cf52892fe0eb2c37c2f5b72ab84acef9", + "1a754d8da11211a96c7396ec682d712168a873d4bc97d6af85fc7bd3344c537f", + "0553bb3b76a902c72430f128b6081d3e827928b614d1e1b37f7d94b944862716", + "d290279c566bb088fc04cc6f41089c44356cff92e41c78287b6054099c7ceaf2", + "be1f0f8b5e1984b03089bf9d27d3cec88c7497f3a7699a2bf2e33c52dd7554a7", + "7370a73098bc83b7aa0b080e7ecb61764e72249027636e5ddaec767cc8449a79", + "9049bc504c8e744adf31aaaefef9a50603a9766039e50bff03b6dffd205f10e8", + "b3db5269172130652487075883a72cf6e5b11afa17a18a100dbf5714539607cb", + "8b47b7eabafbed2498ae2c36a0c7ab44ffec43a30a2df906b77c34f20d2b59c3", + "a557486aea35cb9701b68eb607d494e3577b9e5184b7dfd067e8558240465a3e", + "c5a06d22deca2ea3102921dd139d063337c172fa8656a0bf646c13dcef5ed15d", + "880247dfe48f365908557ac1caef167e18b70d88f1b21fe1ed69cdbcec134637", + "2489b1043399b29d5295c9becd78c27906e1b272f9f358ef114ec7e83b4371ce", + "be87ba05f516b02af12f2b5e100115cb0cdc27c932d7b285225259f3237a4a94", + "4ba4f9a47f2fd1eb7880c7b8ff6cdf7aceefb0306d0cc297bc1a0aa201722068", + "3f453b9f34e01981e48c477cd595078b2e2f3394b16833698fc1264972f35f79", + "15938bea9b175270f41dfbaf569d587e66f7249bce14c03e22246810df412482", + "d36f798ddfb563bfcb7c1ac183166187d5708aec33625ef8e9984531359d888e", + "4695f98a1dd8fcadd0cbb7c735d9be7a1b2cf14f9133b5822bd9c8355c9ad13e", + "dc251d45c0effe73494ae1e5787daa928254584b1ea907584070129c3bcb4b77", + "ee588494346a3fa15462024a40e06be1ff546f8ffcd9d80470f0c8cec618782b", + "d8ec08642048fdef8db382c9154d3c283a8dde6ce3260e0fbc7c14c0ffeaef7b", + "3195116d1e79c14f87b34ecec0e13c49e59de8f53169f325e5cde9a3eccb4c08", + "6fc60d3633189cddf854697d12128a2189cef8a17c829ee4c46d5f83d36f4d9c", + "43f2e6bcffa811b03ac804d7ebc7fb60aaa0da910d6d52e09d80b6f0ff24215a", + "012af15e1265f80976951113251cb29c4de54ef98b912f0cd6f34253e03701a5", + "5462644b620a0253147a7ea0e667e22c2f3013ccdcdf148eb16c51dd2512ed50", + "f0dcca015fb41fdc0e213059fbd71338325cf412aa7da68e39c48f93f2fbbb70", + "2618c8c95516cbe7a9d8dcb7abe036fcfb64a0e470a83ecfb51fb23b1179aa19", + "a75157c27393f0805ea927eb6bbc68804580e565ebfa58146933bc8b26f27ef2", + "3d08a998eb29cf775c64e60be5f46d7b70e92d7f3f238610aa719b54585ba025", + "01f715311c1121209dff67cfdf8f3ca88b170d5b792ff2d141d345a25cb39719", + "94c322f28e92bfb4db62171724de3b79b874d22a2cdccf8da3323cb9e44ee8f2", + "ea6531591e5873bebb5c641d46e6a8838980e52a964a923fd5e478b8ed2afea8", + "d1def4714c058a1220dc2c70644304b5947e6537392403a8dcd4d366fd77fd80", + "6a0bd08e6f4d98d2123f05e920765c038af9c0cb72fd276ebf8c1600b0de33c6", + "1a8c3a1cb71ebf8d54b0b39e9429ac25f39407ddea7b38556aa97c22f4be3fb1", + "417e003bf2014292432a96847f69a2479cc4c12005a042ab5ab82c001c824a00", + "6e7ed154a23863edf6029fe3bd1ad07dc27f6b453442e3966b0f90c0fdcde214", + "ba7507c74b98a2c2f664971308b9780b4b738fc959022fb2b5ad50709135338b", + "464cd884d750f89a5a26b2b39ef19010a3995d56fd1b7aa7d75e4aeecadd9fe1", + "e47cf6b4568250f59baf8d91a58e3a2f11b24cd1c3702407932dfdf02be47085", + "36ce5833744a29095d118823ab6e4acd9a1aea8228e78a91e7ba32ff5411f4e6", + "6fa9e382d2cf248acc4c0b20e100ef4efce7c170b4dba95319961c90bfbda5a7", + "54c4b65ec183319f357e93fb1e881f95f1efe7812788022561fea9b457535686", + "5f4fd51d27dada2fbe1e5dfa43d52e92405346c372d2dccfaba493565165e4c2", + "e74e0562311acc890b6a3918adac9b610c1a5673f378c7d5e320819c367c3938", + "3a808ecca21090d1a84cd60e96684861f1a02f452fa78e47f7f337f806faad61", + "58a43bcf586fbde9928cb378758ee77a7f41a8ed90be444a162417291fc018ff", + "8591f7cf30bbe1e3acbc9e9777aec8ab8821f76fd542c1c3aff368c680c862a7", + "f0658348461b723279c9e38ee7b5f6d6a1771de6f4b364e1430553addeb026bd", + "2c81003f78bbdeef200014fa4146fdc6183c35c347a60362df5c6e58ef620c39", + "7aa5ec0600bf0be0633f29f82048627fed50741481a00129de8fddc1557f30db", + "a695599201eedb6924f57fe4863bc95bf1a4d651c00cd5bc953420158b0d5d77", + "23784725dfc1f5270c3c49ed3154f5e2e5d30f714490d6b9d8a230a450ecd994", + "effaf8e7c052ad4ee8864298dea833144007f0861565d5d701a0f79efebfee93", + "38ad07dd066bab81d600fab9e9f024ab3816cd0365209ee065933dd17d8827bf", + "e5767be0a549e3013032f0bdc7c0eae105f97353658550c94d91ab1abc8d895e", + "be43512133d25abcaf73620c66d5f5debbf8c15d59fa157e48b37247a07c3a53", + "6842405a53be03e1fe83896f5b8599e303405f617a8b613b55bc0bb22eb06ed0", + "dbd7ff400df93c4f138cd7104d711e209e53d7ba42c74460788c0e6e134f25bd", + "c676421a0d8511a3d154a67808e3dd2043bb513765fa067f351cd2f8183a191a", + "b5dc7f0642056166f6efd52daf93656ad7479a0a759ab838887d8a76a29f3a03", + "523e88531cd37a2421bc43d079a782e73c1513c0439984af873185e214603eb1", + "e80cba8eb1e8a5eee06ebc79b3377e68be86c08792957785fa3ca36a617e8fe4", + "2ad332ec9d923de73882c2cb63c34947af94295b9d304659469be98fbf2054e4", + "e3f5e4b10c74226020f9e77549f8715cc7584c904c53221b9acf92c709d42c3b", + "b3bb2ad27231b0da2ecab808188b877a74787da2682f60448642461f7abb85ba", + "f00468cf435996f3d5c9f3a23b3bede5f5eb8bbe3a7d23728fa3568c2d680857", + "55fd1de80fcb8993b94f4a00991a70a9aa56decb2b0e0a4756d44b0b59d60215", + "fa083c6995a4a4b28cb91d6311680734128d5b040e2a587c4370bf98587b3a51", + "7d4d10188a6057b50aab4c2e882315cb810537bdab41f29790f10461d48ed5ea", + "e4ac334b3f55e53c336b2cf69302eae0120de75b200c93e7f10be82e1e5fde82", + "97f02a15e00d07ecdee5dfa690567127492e45413cd08ff0b01b72dc31b6ee69", + "4b38f357d218a8119f91c186488b9d88e421315323c93cb4858bc88c1538cb1b", + "c12288828c5aa02ca6391b6588a4e02a3965517eab908dcf2a15d7371876533e", + "3dc0e1267577378011de210330795375bf80d00acab5f7205ce520e1c848e575", + "69762097a24a4d9099dca0984ccc4683d0c7ffd0af6d9e534f85d302fd6d6548", + "46db97e9ff9838e6fb6173608cc6e83eec7bfe265a650a9865fc2b5461de6d53", + "a55b756cce4fc867f51e7ec07181e23087c0decce4755495391f16cbd44b8c22", + "d372bcc5f1e39208233dafbcf054b0d3644a59e4280bb4c7321a2d6343d8b103", + "ca1515c4362887095c376bb026457fa55c398bd255920f97b62358a8db31fa4f", + "db7ce081b96aac866a491eb94736e43d97167d8d3a4e215b343c89caabacabc9", + "fbcbebc183747a64ed8b555ca3c555d2020740c63fdf867f1d4b878c8e09e344", + "c9df3fb04c9f563b08ef2637832a227774add5153c02806d02a91a7718da24d6", + "27eb6ba23e2863bb63bf07ff3c3076e730fa6fd74205634a50189f2f1a93f6c0", + "bb23ee2041d12434d8e62ec7cccbc4ac31217e89a981b7aab1a9fe51c740b228", + "3565e05340e3cf17b0e23b5cdfa2f79626f630c9a7bee4df6dd4cd5a9a92f10d", + "3ad85553b44867cfe6c25afd7f97c669670d0b58349d456a00dbeba546dc906e", + "4e6d2ceb139eec7867fbcb113b53afa9a193c3087b465c2bc10c4bd6ddac8236", + "bcad04feb3c30c41459fbea0e90e3409abb4b718f558e4f0726fda598592ee41", + "11e64b4762b2cecee4fb09e288fae544ad5602b9321bd5c1f16b5644c71df617", + "03aaab7cc6e6b06bf2914a7937c0d654a28b48635edc789327c2d57d0a7337e7", + "e22729ededc614907ce1d7e8a86126c639043db39f148961481226fbbbc03278", + "a91ba39d60383a50806be9d9b331f960ba0b8bef97b8b386a19855d56ff064b7", + "020862bf50ca10a12652ccaabc43fdc603e450901e556517bf286fd01d4ce6ab", + "76cfcf5c195b7f5231f422f61212027c79e81bcc694875db72f4f143439660a4", + "d866db0b7b9b832db8a890448e580f7d9b885a61ef0435b4cbff3324e59a6308", + "e43e73df43b589f910ef3899f3c7be6724fe9462982550571156e4270ca4ccf8", + "9ad1541474cd3c38b1b58837589e1987757db5d4bd702821e5001332a1410e48", + "6aa8b4ec9bcc8269f873ad79cc2918b6ebff092951e598f48142a7501c03cac3", + "2ff88c4ddd2ba69a17be4347f2780085632c197ef554c71c7e343754f45761d4", + "2b8fe72c5711ae5669d3a366cd44b3ac0d9e5bace4d170114c253d8036d03c2d", + "d7c7416a041b58b40004cf8032e7aad016cb8e4d750c1b083fc11b5c3dce6200", + "a634876d7ae5f7d495e9b6c1921c0624a4260f6d3b19636d8cfe17de5ec493d9", + "6cb5a5096fc820f54bb03809a75ba8a1c8bfd9b282c7a43f62cf7bd9cdd590c8", + "2e37d6b573230ea777a558762f1817fe3c82f0d1844dea7df92536503dfffaad", + "c955c548cf79bbe6699f31de381638a7dd3d828860e534f8556c359fad748274", + "1649e558423f3eecaf7775328d64f3276e1234fe8762a1be98323882ff67fd04", + "cc173efcfda2b9e006bc3b93c421bbe8f197b3ddc033930bb42a346595ff7f68", + "a9ff159246076e9b34ccabf737b6cac6f094ce5cd5812d4fcee70741f04a0a05", + "7da4ab892eb0bde9451f20b5d7c7142f02940536104ff499b06f400565340511", + "12e74d82ee28effb9dc57c1785fe12341dd7c4cceab9f4b47a0ddf5d464ed51a", + "d8b638d73d0ad916736d7d54ded43629663d61db309a2e55fca239838bd66fc4", + "a32b9a30ed4e13a8d3febe2f0ae90235e59241338f3002a59d4a3c9b2d690c14", + "c460db5dbd007b70eb3a39bb0c81dd928b1a461d74afd1ea01a2f93e472309db", + "31253173ca39f4883f92dd50feaa812249383816a946e6365eaf491acea3b330", + "1806c344f5d55402134b380da54578a3083eb36ba542ffa94c6a585c8dff1eb2", + "ea48e18053721b59a353b9936641b479456f9166c17d927085c9809416a65375", + "113a4b4e2e984923dce44cf9f295e0b04961a50a0e51b9b842e151a7ded4686a", + "4c534167a25a14dad98fc68a30d97737ad9033265db3025841d2f12734471dea", + "9a7ad677de291550c8c5fe95790d5c594ce20544fa78677ced4fa27e31cf9d93", + "a4ae20d76dfd983ae537a54fdd20eecea52773ab5f1028824e094bae0e8914fc", + "4f35a603cd4990e715279d2bbc32748114885e039427a631b190539cf0c72518", + "6812e3f31e3db23deea7b3753fd2b285813252b1bdcbc5178d8271b4d8adb47b", + "a0eaf7dfb0ca002ecc1b9aeb1b8e0a02e2e8a457ff4f932640e1562b1ac09b58", + "49f4bb067ae8c0e3e568c14a8a6bca45b55f1f178219a161859d73392d2c512e", + "deebc826bb592ddb3cd62ce53907d8fc95711001eef587c0eb439ab3e0af1811", + "4fda0a67bc2da88c8b76fa65d7f6597eb94dbcc9cb5f2952c1f2c142cf8112f0", + "227d9faf2853cd77fc3514c68b0c8af22cad886771eb8c7d980f365e4a163440", + "c854a6886eed847311f1e5ede2fc7f2658c75ca3aef77d22a88b4dfc19af52c8", + "cf6c8efa45e93e7ae2a4f0d1dc3166055948a21331c49dc051eef4296d8e4775", + "6799c53303eb2a2889ea749a54d0081cc6f1f625c8557999c20d1e2dd0478cdb", + "2a1e36e2de40f1a651de0d4f2a943ec77800661eab2cdf69a0a80730e1806f22", + "81988fbbbb07c9420492c290705a5a7c484310052596a9dc2cbf33004a9a48e8", + "a6b701f7628b28b9a2fc25b1c0d0f8d252d4f58efa59f05f9996fad97a2ee058", + "da4cf98a61e7c1a8674295fcee019104ff8296451c207572b573aa0ae6c98b8f", + "5c214dac8721c5b179eb5bf888f17aaa269056e55517dcbd54db485e62f9c521", + "64e0400aa71e7edbf8a82af8fd6c541236c65bae27c0a78a1b30013f49e83259", + "8c31709369d5bba209defb545935c41d5a83fed39be08808ff15b0929c68efeb", + "bcd2519b938b2a7e4b22f8c412529ad903918ed0e862030e916dc088a3569138", + "be5f1ad6bae920ba2597092e10f3c8d67d5af272026acf552167808e741e7cd8", + "6757d7d49e95e5dc822a3430413eb5343fed9233b7cf56881de61e65ae939cf3", + "686fd8056cc6b8215764ed020ba1a2c846ddd24314a6bc1b1a9b6a874fcdb0fa", + "a182681441674cc1d632cf62d4f1783959b905650c303d9da052697910ddfba1", + "041a64e2c8abad8e3be9fc0c0d48bc685f69b3c63887447cb3d9730f3f836444", + "71cafad800dbb99eab801cf2ea3a8c651ae55c40307b58f02b29e8fa5475db57", + "0eacb4ad3ec9856d16734d325f831df829618940d76465e53755aa946d886c43", + "b1346432c32e41db607260d474aa6db8a204a4538ce9419ea4172d55904a3ff5", + "2553d04bd04df80157dcb7d90b3c11cf4925d397bf38b9f576b3f0d1382379f5", + "da4c9bb204c548bb62e62aededcf53ee4e3d19cec3723a498cc7f7afee21c687", + "b8d7780b7783dcdf37d55551f5e1a454ad1e652d153b1c8c5baf617086a4b02a", + "125c99ae77fb035e4124f6cb57a003578aed1f4ecf66a9f3cedf3397b026642a", + "92dd3281d4ef48cf792f2ea367108ec4e450a852c24f64489d03ba9227d7fb3e", + "59eee8ed1dede392ac2c765cb08c29809f994f6f900c8ce3f45606ac5f589238", + "fa83fa26f26d6b791f6f885714d6047c5ab91be50a8a5079e114b5927034fa4f", + "6976ed2351e8cab20f27893cf0db3eaa1d4cb2eafc554cd785beb7765b2c0555", + "e78e6993a857939ebc70f2eb8b91292dcf035125905c32ac440012727031193b", + "26de5d0430ca4c372f4624dcc5ad133f725632ce80f59bda61320245ef33b125", + "1a1a05df72709fdadf78803d0d0f63a0456b6d1916e9a1726d4adc50dfd66f49", + "7a4c54cb145ec4704209860c46f4d88a0d710813fc9d1d2d457688aa81c666c6", + "748820160c1f78e32e2e4538121a57efd1c744da56c1d24e07d266daefa0a90a", + "a470107f3b803a351096ffcbc54fc95a2ebc1b82ee804f58f48109357288672e", + "1fe5802a251057f539d13100b5971c944125b7bd7a03d1cd9893ec66b7ee61c6", + "91b74e5a2fe50d4d9e33a3a9e473c5b6fbed84ff6e8bba169956f121703003b0", + "81a70a33855397cae3ed8c208eda3af7d02faad21516291933d08786b5017b02", + "61721cffe2c456d7cec5d55875b9c1fd0323f97c113fb72fc90cc1c8ddac86c1", + "5726fd0dbb6471c187c97c94bc1a2014b83092acf5b6297bfce1e5282f8c6a0b", + "8b531b1fad55d17ec16827f0554855ef6e40b7bd646e954a0a95c5732dc12eda", + "48e0d20223fd7d0af2a5520e44e9eb0e9559b49aec883a22cecb56a1e467b501", + "4a6719798741e242a83a1aee31a9bc2d4f84f821c9321cfe00031379053bd2f3", + "6ad7760eff8765988d27b4f6170d5adebe1a093e6223d655f3e27b502ef3aa55", + "778868cc7356b3d4859d64a3ae28d2384c8f9176477c9256a5618613b33b9b99", + "d3c7637ad6b963c61a04feb2557726c7528311c9225da1c39f9123b9900a699d", + "d502e580cc37da0a0e312e9df0963de6a20efa5452ed617ff90732e7e16f51da", + "b4d88eb403fd47b75ba69cdfda64a2bca3b5e46d84b45059efa1841bf912b6f3", + "98ba045ad3745bcf732fadeabb8d3fcd00435efeb0b5459c79de5f25c6e6e909", + "8ef544d8bf020e15fafa6725e1e57bf73965f4ff121e48ae94e30922e4e7bdb2", + "445b12ba8a22225db3444536df76e1e97aae5a5278075da750e291f034941a50", + "9b546de6ffd350695bb01ec31328f4ea3d21593b544fb446a88e68470c7b15b0", + "5eb4a84765617f5bd609877dc288a25a5bbcccaf6f116353a96a6f58ee743712", + "b767a25742828669c63d0af253e8762beed4dbe8a13362d11b5c92a65cde6a93", + "1d5f314879843e0366cd4a0acd2c4c70072022e556ee836b2b9a3cd815d71a08", + "a278610f1126f4ff7525d904c913e29974c5bd32944bd456afca76c64eb34127", + "6cade3cc80a4db978c55873fbfda9dcd78d06b04ea67ed713163bb15ff29b37e", + "d0b4e51a806d1ca9642cb93cec9456c21c70f73fa6304a19557a067464714a2f", + "ae2f8fcdfe756abd8384bc47440823e01b82388ecd4ec0de0d65d887748957ce", + "66aa1098a7aaa481ebc9f4fb8e028088936207c5281ad087741ee4c3badc323f", + "26dc3d7d73b9a56cc032bdfb7fda2d4e18fea10de409dea7fcda4c0ce5d5a847", + "22423d9cfa384f793b3d36a3604958875ce46174a3fcdee648483ec7144a3d09", + "b6f2d224578132481c3df0a13d5c5b3984990cc46aa6e5a040499e2130f9d5e6", + "2e20dfe3b56f0a27d83896ef3cc00a946f016d447128add067d15b63323bff5e", + "481b2c966640ba4441dc48857e3d876761f2f978d3a1c31983746506b4581da7", + "fd8d1b367afc6df582d2759b6ae9523aae4d55daeeed58aefebd22f25aaa1e15", + "dd1cfbe4e3b13b5595d8bc0cc1eed90e60bb593f92eeff9b4ee106d7d170eb99", + "742e8d5c5c270664fd611a29e93f21a9aaf104641a5bed09c75bbd9d29bd5c0d", + "14aee9a3198affb5cf149a786f43e8abd8e408eb66a8f2c2558c3c7688c43970", + "8dd67efcb8704caaca3ac43db842628307a14a18cae90ffdcf4a11d802c45f75", + "215ad34c137fcf5492692a48827fc6bd686e90d9c4cd0ce6909ff4de7bfdf377", + "a45bbf2075f1285a15a952336bc31acbe1b98daa852c27975866ce3252819cc1", + "86255d4ce8499d2335c942c71bae6e71dc03bdab10caefd2570b7fb81be0e71a", + "3320957999a72ab6d3ed3a5760a7e36649d1832f3f721eba90ea71ad0b7440bb", + "5b8ae230850a01f0762afd99d75210b2735cdafa911af8d65cde3002041f027d", + "c6a6ca52371567ac0cd3cb59f1e0283241de4089f5104644de3a37c2b34ed4b0", + "4e73981c10c40da53ded0ce837e09ee911f13b5bddd5ea7968296151fd5a51c6", + "4c9d9ed9fe6a0c0288bc12ccc81bea9fa2afa558cddc2b80758c6886fc8ad646", + "8b0244aefb68e5495f149e2f8612e2e26c65eb13d2dbced65d9b006501d08099", + "4d0bde74a243746dcf7770f5c0567827f4a778e7da1f38c20e6514e6695e37a0", + "6e00d8d7957a5739699a47addeceae019be162ca4062428bffddc19a5c8b005a", + "cde07d41382841e5ff91c18586afe2a293f34c9a956402c9be3a4de58fd82540", + "41b938f100e52a213c90f63f1dafbad6e3c028a09ada4516d16f619183f2d341", + "c1d031b7335a64e0f83b4e871afbbd7c5296bdccd77b4291bd94c1f393f36728", + "5c4f32ec75a0752b8efb2e5615649b5c283cf700a0538c31ef50ddc10cf98948", + "2eee5eea8b0154fc1620d694246b7c80fa9bd2d57097b2ab7c1575467d63faf9", + "a07333dffffc4c7564636ec367e94fa70a95f8f6ebbd02a3c025284ce6113dbd", + "8ba48735d324f083e847e08c5df058c72a271e87a5f5dccbf2f18d833ce91c06", + "961c6c72f57a3bb23629a8c92fa52b106124b49adf199c761f6994ab6a1d4601", + "358df010cf516e948076c4110b2fdccde98a98d5cb376adde528e535df9e7527", + "7b33a72911753a3616b190c42eb388078bf333f62aa391791d9c17a778c38ed5", + "169633eed6e41428b45b871a9981e244115e722580471c44ddcae1372561439b", + "ca7c9219bdc2b16da25561cb4a324da8cdac42c2c0ba68cd8f5dbbb8dc934e24", + "2e5f8446f776f8f60d56e07590eb0794a2c176dbab1fe9acfcd6ef3e64acd69b", + "94c71ee68740b5a5ca6666ecc666ccb1151d92bb0a6c6210837e0e18f0ae8384", + "7e39e3d03f19271bc705b6b27088d2fae61a47a9056a0ecd15bb1d8fa31a4c5e", + "b52b18f60af6f480e0f4b7a5ff28c582cd4e4ed61b6b542a4ec212cb587e6c93", + "6f13276261cd9496d8880ebaa15b89c09d71e6da679205e19efa16d85292bd63", + "996205d806894a9f5d0c1946629fb531711320e92d9949df3d1894c4db5caa0d", + "432830d6f008f06a01d50e8e85581b2867fb49572df275d3ca8d6a7fb59c252c", + "1e75a2c04f663dca71b34fd0368cd9be74f7efa3e329c114b61b9b315ae83bbb", + "f7fa38662463be2244a4adc558372f4d95abeb3de1be27ea04c317e48f729250", + "6d89e86afb008c797eb07343a85668cc06c2528f5d9546907d09b840d996b583", + "dec6db7c815b5f1672c0df376e1e58bb7249bff56a07ccf6a8281e426218c5eb", + "d728cf4958da7de2d15fbfec86095c2bf0c36be88ff57aebe89cfb18eeebdac5", + "a0759bdae739a26ffa17e65a9dfe7aae7ada2d41357673a373ef409a511360ee", + "17622389d3ad2e8f1bc0eb3e7e650054875045d3be38730d5b82256df7eed523", + "ce298f86e136396ba26cbf83b77c46fac473fd1e5504118ab03406fd8e1c4918", + "02959f660a8d23ea55a9d39173afd8b5b89005b8f8237dde902dd8e9df3526e4", + "b021ee1dfed73fbb29a07a4f5b283fbc64f59eefd5f51f414fbb29dce394b4e6", + "9113cd0b5a8d829f6078d6bf45f9d74c4bc389ecccf2c1607bebcc88e5e107bf", + "8010045daa3fd565f6a901c2f90a0fa5b72517518b76bd6be41035a3c8efd565", + "71c96c39018537ec8cd1a6f41b2b270f73237bb7bd3235e2cf2a2244b8c9e6a2", + "00f7dc2fe56c711e252efeb86ec2557e0d3a28c5f5064bcfd3dd448ff83cf89b", + "cc5dd1b02002d70f382ae9c8659b80d9114b5332de7d5fbf6eaf0601a154cace", + "6aa874c9f3c9436851b734e064c637b9a270869f1bbd6fa90521c5eed209835b", + "400e9bab6c2c340f6d3c4c8aa54244bddbf5a4db15b5e613fa5c2aac94eca08d", + "e39282bcde098a83aedb04bedd6aa5aa594a7008eb202441328d8f4d113c96b2", + "519f3e8454f61473967643ecaabe632ab505d0444f1f77d9ecf49d29f5249d90", + "38eaff54778c3e928d8fc2d664393cc62c36ba801a7e8f5082f3c52ae5a33160", + "70c3607b92777c0cada20e5fa958990930e8546b4e1699bc3f22565522c46bf7", + "1efa1ef88aab327fc2deee70df73f42a57d80c7768fb444863baf5d0b7c97dc5", + "8e3a9a723ed47e8c00f38742dc8ac7e125afe0616322c8c1f007cfe3c68acfb1", + "21d515680da0d40f0c65dc090ae612f66e535beda3f42d2cf82a3918966db66a", + "51351465039ddfae935a91341ddff20a1b84a27a5e6db4ee3eb960a33c7c060b", + "f1138cb1163e0525e4e9b5267e64b1b62e2248ae82d9417c063a281ab3c136cc", + "1c7bf750c04ba470218adc3b2280498ba8fdef9c115d0adc7530d15fef0aa722", + "5052be95a352fa74f38b29c17b68143cf4787a340d232ec820c325d6b797b09c", + "509187bc639e8bdf09bfea5f3309a71c91c8080ea37452160eaefda769def47e", + "a3d5658a7b99ef52816d9ccad83ce7820f75f245b963ea866463b5654c4e867b", + "1a2dd6a9afd7e101b5e35af7a9af992103560466fc9ab6d2155dadcfc8d892d4", + "88d594461fe06a37b3f55a70eb5ecbc0bd107fa15a21bdf37dc2a5acd65c16ba", + "19bab6c7f7860e8a735da55f2fe9ba83f8a7d65c691927a08b9baec0dce66eec", + "bd05793e1731b54a1b2da509f2c24dc8d5670d5531e935c4469fc6823545f6d4", + "0d94de7113a0dc09c8ea22e3d2ed12d7dfef94f403dad15144aa3cca7307b27f", + "46c4ce2720f113230fc8922d24cb1ff2ffd6ddbc2a46e1eb8155672db72742f4", + "1d32be616bbad1d92b176dc9b0ea5c1d4f5c17d688d57c914aea6ba1035e6c38", + "6baa7c5cf444cbab267bec26a8f307a1d0e1dcde9b18fa31c5ce1fe4208d39c8", + "c0da0dfed67d584ee55d11a24c03011eb877b6995aa8c646191ef184bed46332", + "daeeedff84910c5d35f32785bb0805303e03181ecb02813432bf750acee3d302", + "1d7a599b0afdb15fdeeecc38a483bf9de3625d425f1b4468c083e32264e39939", + "1d399074cbd605fa36b528c86c050c035cc8a2486bd0da423208a5e7702eca09", + "8150e6d654658af1250fe03ed4bdb3394b8a07d2355b60c86429dd1c22d18213", + "fc2cf580bc3784cfab4a4439d99ef4b8f867410d145040ccac038d5f0323baaa", + "c4067e6e1f667e4f139faf37f486c2bcf992a5c525efb2548a286ebe27314dab", + "b4d3dc001d9634ddba51da99d9820f74c0a49c2a4be043aed312068723fffea9", + "e1916c97fae0a47f2aebff0a129f15777a7f2f47d4a9cc94dfc5e4bc7c6940d2", + "560a6e02e69d8de6b6480f17643d90f6098bcd7a98e3a1014ea8d876c437e46e", + "cccf2e0cb02f8272d6e4e22f2ff8f1541ed51cd2eb12a84fb65d66b605a69f4e", + "25b3958836cc27f52eed379e13657e40ea074e0a4784bc476ac617eed710994e", + "f11eeffdcfe0f6c28f471c15e8f13dc5455e61d244c2dbb6a7121fee2f000b3e", + "39bd4ad38aca2797782cb12e60bf5b752fd47256f359328bf2fabd2f43bc2f31", + "5d8e12d0e741f6551128d1bb7ff02c69db31fe2bb92f68205d28d4d6af57ce16", + "43ed35201208da09fff4808375db597ebbb16646b874cddad494ce056597d48f", + "c26090d28db81847ca29efbc742f593aa5470e270f35e788c9a79b701121984b", + "d5eea033156e360d950a6140d3095a8c0634ce6a5f3d01f645e530cc8940a4d1", + "32b0d4ed5dec1e679193cfbf8c4b3d9365f2d779eb90ebb7acc69080be534ae4", + "2571089b5533ddbb538547c8b432ccb4d2ec5e0fdc4e26a32ef8a002b2149984", + "7c063376f03eba7e0a74eec6b64e24ed3676e9752eaae2c728bf6b6fefd7b233", + "33079fbe656ccb7e64aed3f313b621e6c5b8d8050d7d9101fd3174272242eddc", + "b2196ecd3b83a99007977b71a3d2eb9dceaf4030dc6623253a52b1e457846363", + "e81c098a9a59b0ab2cc3db0a89c8c142d7655216600558f74c7c523b4183990d", + "06cd063b84acc7a32326f53c1ccb20fce48f89be87026928df6030baff0d5316", + "10fa130ae96f9f59fe32f27a993265789707a0fa850c8351a7ceaa9fa09dda18", + "300d9f1bf40df8e92d9eee6ff4c295cfe3e102148e3f44661e52613f348c7ca1", + "1b0ee21c52c510a63debced8aeced17a4998974ef1a29cd4e352a65637a40628", + "e3173d2ac384f184996a99c97738d86ea804329a7ced68b88647b3c68ee7c64d", + "1651b5f6a5284701674be2f90e23cf35086103535484b52c194e82297e251562", + "6ce982d8ab5e2866cfb81041f8b4d3bde8d621c36bbe724f5acbc6119e0cf0d8", + "176e2748d0319a2e86a3faac81a57dceefc643109617a1c4255c9da2298a8b03", + "bf8947170fcec170499467aeb6411a9f8b2ef11138e93b6fba731e63e535315c", + "0db995389674de9d40f39e9e734bcf204879923f4e66e79388df614d1140888a", + "b92ed283e542e7d2f361267391d8c34ca3d843d8f2f25509940ec6476f949081", + "eac8a016697fc27c9a87023923c61a7ef6c8cf05ccfbec5e1695b8bc002d5bc3", + "230705ed3e7551510e7fc1365f5f2ffb24fdce0241383ccbb58b25bb34ae1da1", + "8fb87c55de0e150f18219b0f766d0ded90003b2e887c71660dc13f53bd305ff3", + "a1431c32cf6f91b7a89576d8abac5cab2ff073c3fba9d1077efd6af0eb324328", + "94cfbf90cd145ac3b6d7009f498c210b27a29d1be6296411661ff0538a22b3b8", + "c77d870e0d35856a9c5bdf11388acfe934b68a453d3a4a4f8f0c65fe7cf73131", + "8f279891b43ac42e8e6dc9240467b1cefba1718a856345378bc754a88c710d6d", + "cf4cb7588876d7cdb215c49f1bee1914c23fc19f2958bf029d5c7d9de46ecf52", + "2a6063b51c731c9217a810e0d1f72f6cbedd7b02be95f8bf963e526dbca0c442", + "e4e2df9d6f21f62a12e3d54879744b334edd621766aaa509657904973f34366e", + "a56bf28b834b926cf2db2a31064262f4466feccdf0f1a572d729f0cb662b7dcd", + "bbe8d99a4304addff67e58820109ffa9318bc994b65c9c7c59f6f7332b86fa78", + "d9565aba308f153405e14028609446f8c14a530a84af0054f3b11aa931db31ab", + "56772854007dfe765d03a819f0e41b7046eda8f96bf94a2d07be3a80d408845f", + "b7873387de070dcb59c929ec3aa2328bedd5728f4ca1e929818a47f2ebccf186", + "ef5131bc25f0f20d40c6a11972a2ec8da9e49648837c29bee5fdffd961a01341", + "7a8a448ac91b980a804bce7eca094f6b755822f28e8fac18d7d5274626c595b8", + "87debc64e633f7f0c34382eb7de8e5bd97f0b65b9081d3851ac31bdb0482325a", + "b1278668fdabd87cfdbcbb08e14a4bd624b89a07e12e279948e78bcc103001fd", + "e02dc411cb09927547d41890094e6554e3c9ccef956a70af92914494624416fc", + "ca8e2fc6204e0b3f609195aca54a81927a9061da09a672e185d904625d563479", + "86ecf42b43eff84b269acd0d6ee204ba2b86753be348b1063b5334176682acb0", + "18f8db0c3826fd0a99b36dfd48b27637ee1bc081df1da169fa36ba8d71a2b11d", + "bf244d8ebd154da08a3235db542a059ce968bf7fdfba2ca14ab43db290ddab8b", + "aa99d8f0862ab712f3a880f95aff1f5720411a90de561511aa72ebd3e8b45459", + "03c7dc86d1d74971d00727c6dc3b00899f48a813524d13f25dd2136a0ce70a09", + "5a7506846b0dad4657b67329a2f60329f12a5af0b3c7d718f7c205fad469c24f", + "925de3cca01790f712f1dccf39e65024b392b442fd1a37bb795bf05e1926fdf7", + "07514eb70282707056bb33cc40ba8469cd7203f56b29d18b1f16a7ee3d211bee", + "2d2386c7f8e3dd58135f4ee54b19480bb0eff9139c0caaef81bc857277364078", + "89de3e690a99cb77c663f9662482925e71db2c8ae14dba88758755f3cbf124d9", + "047624d18ac9e4b4146ef308aebfd56a5b4a739cd4118e7763590c77f080fc10", + "4196dd50b9ec8c13db22d6f07cb841647bf2f5e1479e73bc1520c92be2c65f8d", + "6f211e445da60bde6813dfddfd997c18ebae39dfe4b58f0beea74b850e5a9afe", + "e9cc46911b40d3a8fc85b2b09fc8b0708197961c1c88e49fccfcbc5b7d5dea1d", + "25f8517632c9d3e7340e95ae754ac9004bb9d321bf954e3657a68678183d545a", + "77dc327511ee79db550f95920518e9181a44237c210e89a39682087eb07c94ca", + "ceb4e754a4b720c604f4e509126d2756cb8d1504c4e5f46c6ec9c9e7fa78122e", + "29135327dbfcdc0539b568994c66825b64741a4ced936d013d9e19432cbbb6e8", + "d7e4f922cdacee97a3877070abb46b8c5bcefb43d8ad10176eeda1f53cc1a4fd", + "c2f3e2f8d51c88e1eac3a42a9a07a1b26105b897288999e00066f833e2c6dbad", + "e1bc6a25c96774116d7608131f030751769d4f1137eb4e998fe8b24dc5e2e82b", + "1c4a92cb570bcf8a9cae4b530fd89eebc8f8a23d25dbd2df39b3f8b2f3d93f5d", + "cc5d6e6e55ea926c885a9d4bc92a79b4a03b22f03ab5000366401b6dcc2cc64d", + "a5f3d8c5e47872b39b6dc61732841ef6dcb12dbd11d8441c3d1f434da96c80f8", + "c8768c59623728a21d198b180b63c8608f5e8ba8764596aaad348fc0716e8da5", + "b3cad06e299e716df5b0c9bf3fb0414ae8dbcdba2d279e0db0026909bec066b4", + "8d9651f3d0b98cbfa15f856850d3bebf526dab8fc9597db597c26ffb3176757c", + "267e736fac0d81ea8a208ca71cb1f41eae0f912626f922ddc2fab302a94cab24", + "cb01ee77b50661a028ef3da2ae52f3e51f84d8f4ad4f8060c9f0dcb297b1fe7e", + "669726c1ddb58bd835cc10b38e5d6c78a4a8921e3e002172cbfba45f80e3a650", + "1d43c8e91d12d022e849df6ab6161994a19800e42e465c7e38bc87700e335602", + "94419c8a99520edf0c2d6c8872cdc3e941cc99dab31e34a7beb5d068be377e7d", + "7b7d8d0608eb0446ee89aca624e7d2368729bc0ef0082dde8847ed15988b83fb", + "139092abfee569653fe1645d175e93de2ba8c5b382cb2e06819a483693e91ac5", + "2fe94a073514de00ad664424490d2c51f70e1e044197c011467016ed5e465d48", + "693f84585075e672b5e5c23c0a17d12444719e1ede93e133576bdcc5d04e4acb", + "36834503e6b111b54ceddc3ed03ea71abf685f160fa7c53637fb4ed2fc858a7e", + "df7e2197cad6ce373024a5979d565aec87716a25c2aadb0636966e2bf98a72f0", + "7c1cecbdc3bae223b3291ba6ec95e7d410736738c1f54ffd10318cdd646d7b2d", + "8f864d2f2ddec18477335c010c3d19dd8748a63dc6c06839cd9784c9e0d365d5", + "efa96d3b9c9635a29c621c26b3ece1857925c494b038c33311e7ca4ccaabe6d5", + "fbfedd747f16d95db6d7a41d0a4ee836fe5bba93f95faffcde4fff46a05e14be", + "6ca9f9b2543c46f1afe3a8735218bbfa530650a93b5e84547057bdeaa46f245a", + "925df07359417ce76ce5eb5c48ab748d8edc181271901e75108ab012be198568", + "72cb833a4ec5f7f95db76645bbf23fc09898f315baa054b144290a6c375a0872", + "e717686544882332aa392428faff88e326307feebb506f7b5a25444805bae5a1", + "94835664f99aa68401b456bd5f5847c37e477c2b1996ab90f5cc6974e70092c1", + "4a94faf1d0613d69f83b0c17d5fbce9cc6f09d39507563d692a366170660426f", + "f366d1a16a81d3372f5d15bd592ee0adc3befa3d32c3885c8e3a33df6637c781", + "71691065a59f1108e5fb1ae265be213de90e52c050592074951cac7d7e9dc1f8", + "2a03b7b9068d622ec73d94c9aa84e4ed7c5ce5217ed8c2e097b29a4b111a0d79", + "38090414a9e2528710ea41d00fbd618c6bd3a9af5f231d4ffcae1797931b47a9", + "c6fa80b9e0c74335852feca1505cbebf0c25df7f611fdcad7ca4cd38a5d47e83", + "fad4fd237fd3ba58dfdfb2e29ecfd7bad4941ed519408c07a797f328ea2d79da", + "91cfb382a717b5ba68229caca3370cadd2c966d47092f5ed556cb649f2f850b0", + "8e70a6d8d46b3e9f94d62d0302139f3b1df00248b230eabc7d0443419cb8033f", + "3963c31c29220a49e86ea76611a5c412aba3adf24e59bc66623d70a6e08783ce", + "1e6df4432b8427c5b282bd635994d16d1854e5eb024311ff518a1dc1595b112a", + "064e2c194f48b328034a5f3b5d661f4e594b8dbccd0bba843a6b67d7d792ac19", + "376533d8b5580042141c48032c0f70c94eb1e8176da708076fa5c3c25c0f8729", + "30497c1df1aec0e9adc64a6ef3b3935d014fa86a146d73f8b8f4f4b6b65993ef", + "d89c8e95c2d99aba885a6f48211d21e213ee4a5cad35e8bef0a5ae0b4001569c", + "b149aecf813be9fa619cc13cf9451e1170afc1f9fcdddb9d1775157e6aa2e737", + "8bd1df462c0d8c5e5085551151c8a33b469b7e791cbeb866f5ab12f7ebba147e", + "30c5bba8bcffe5c1a9775c03b47fa9b8fda87f8e32d1873b52dfbad1443f786d", + "2176dbb4ef8dd6edf8467ac61949a4940cf3b289ecd364fee01b66e84888195e", + "5a50e55d376d9b27e80900bf78f1a199c9cf1d5476cd84eaf1296de3ca679b00", + "16ae4df24c82baa572f2cab418148701c39fe070f6099fd6f7cdf384cf4e28b7", + "af9c99988dadd9d53344a560239b686e0eb800c05c7707cffec9525c6d3dda45", + "c3ef41fd5f9692e0e739d10a24e5e985693d01b84531b19bc9d740b48f8c903e", + "11ce47f456e7c7de8c01e6f094cb64562ddd5abb34aaed4883afdf8c2de4aeaa", + "f2002bc247ce31dd97718c6132e5eca5f6ed4640dfea8a63fc4bff1bd8e75b35", + "fcc972079a80ede21245f5126e27cfe8f13a668257b7426ca28d2946792c2228", + "20f21a4282894a3197e80d57877a29e9aff45927f601d8e226c530972f89ade0", + "332e9fe401e5df58efba58acc5e5234528fa8b7f7851a4b36e66627d20c1b2ed", + "0c904e2095d22cf46ede43a37b44a6bf58e6a9f80af77efc206acb81c4484dce", + "aa69d97fd80f0904acb8b0b90da90f9e99eced5b1021ec500c8fdae7c97510c4", + "42cadc85baac8e84430454fae279caad586e4088ffcc69769cf65acb72bc7d9a", + "71880390e2f14d569e18c6239aeaac88579d797e91083b2754cbd3fafb4d8208", + "b0ebdd62ff42c848cec038d8cd6a1e04b13f25becd9c01c62418d80c19cbb95a", + "c773a0c14d2633e9ea544972baefb7942ff87d1899748dfcff4d327c971f669a", + "b39922092501c26dafe5436e026ba805b7d380938b942b82cda886364cd65cc2", + "1e4b96ee4814dda64c90b18c7d1a35e894e5381188a66261ddfc1fc2446c7afc", + "d45f8375604be7cf10e9e53ac45c890007481c1abcd71647d0a8d2393746e128", + "8a48fd981bfcb0e1b6d734ad8b8654ba4c4a3ea3cf3d4f0867c5a101c763c20d", + "5accf2319fe7dd4480518327c5ba7af46786c748ea89beb168ef3e3c344bcdd8", + "e65a6835e9ea4d7ea9076bf69df77c078c16b42f1569d8816d17ef05f4d4c3c3", + "7c99be532dadb457da7c521b68f6919c39ca74312379895e450749d7d51b9910", + "c0b14bcb8506e2568299c43893d7656fc9afcab8aaa037d9b0be86c9e9cbebb3", + "f82ded95d77263611404e7bb88f41f663aa78c3a499d6ae4625fa5cf5f59ed7a", + "5d9ae0b27c7e5fbe9c7dfdd1f1e1dfceed4f1b364c76e122fe015e700538c2ac", + "7163da21bf0f1d7ed2be9b9a4a187cd0e8602cc3c02ed8d00d81e759c826a2ea", + "24fefd43be4fde1a12cb275ab3fac0b384b8609e8cb78f6f40fb09bba1780474", + "5538a2db3a6c7ce7fb8bff378588739f57020ef7ddbb28c7a7c4429e5f954ff7", + "9754d4087029e5b2edd256c9ccc74f3c34701e90fc75ffebee387907b567d502", + "2e663da4c6a356dea56b78a6339dbbf8fd4fc787765b3d4c0ac305611ba80e66", + "89a4e2246fffb728b4c42afc4c82b34b7e3f03eac0269c520a9c8a2d55aceaf1", + "97d07f88fd94a38460ef852b54bf72caa109f59467e19b9565b27872387dd568", + "78f782fbfda597d8f8cc1b003c7c26103df7d60903ad47a79a437e82d9642f4b", + "fdabc85d86c7376e7726396ef19a53eedce4ca0631894700a149f490412c5ccd", + "5630724b46360ad3e4f935b2cd1fca6665dbaa94c7316f58563b10854843b482", + "db6705d33ab763cb69b5c3984d889cc8c78fc031d52bd532459ff3b8828d330a", + "813227790af21fe5f1a8ea7cb670611569fbe63ed053ea4870a15d7b9058a996", + "a791d0f07a75bac8a5d24e38fb049e128eb313e4611569606a0869a8498436d7", + "bad95ec29f14c7445d5e8291a9cc8c063af9bfafe01436fb67c46a5447efda7d", + "e1dbd49345f7e903c2c0f3a479a9ffb5b226925e88013c7117f876ec56932939", + "61c3ba66b7b6660a01ec7095706e4d708c4bb43d3ba90a45e5a76187e1daa1dd", + "212edf28513e603878f3e440e3eac4881beacb09a39c3effc2298d00a3a78077", + "e0925788fb778f525d3fb15dab112deef6aa9698a655b380fe37e4c27f795a2b", + "c8e81a1b12498a0a2be355b26599b5b5cd7c2398dabbdf7583cd539b5bb56dac", + "f3d8b583240ed0ed9817b9470a384ad8e6c7fd4f076896e027c93791d72e40ba", + "a25d879c1fa98ef940e42a26ac157a9c6737b09434cd12e667f2c10640717700", + "d363ceb2dc9e20f5867e325633aaf16cfae10d8c6578d2fe3c8ac43178ab1b06", + "f4db733b9a7d545a97ed506c0d3bfe13778f3823d1485c155082c3decc8c1c39", + "9129d79b8c47f8c23c0a903f3f090bd32c8307c6fddaf4cb814115e80ed4edd2", + "ddbdbf2ff8be13257d9b293b22fb07919e4905f8975d27acb0478a5cc64a8471", + "abc20d1cc0053b575fd546d5deaaca7b7eca9f412815835e18909b0290c1f377", + "cb7475da903315f7fba0cdbddc7960559f67f6e461733a46d28d84cc542dc24d", + "c69c5152120fb898d4b4bdab6635f00f8cec18a1fce055fdefbcd73787e8cfe2", + "75b6df962b039555ad4009e9beba1b985a785e8c05939e2f7108665a329dd1fd", + "0786990331032cd9beb67f398cec0f3bf5b04da8d05c4b08f5cc2a4375e4a2c7", + "c9d200742f2b12b04bbb84f3a1dcda26a1c8d9cdb92d6a2270e352d3b1e19427", + "2d30937be93b263ba77b400c924ad7bddbd67ea9cd84db1ced041f11f69ad4df", + "2ceea7c1148d0cfabe528970294b4e36db7c2bfbe840e6b8d3eade74dc5f51b6", + "3e423eaf9067465cc00ee943335ae7995279b9ce1167dd8a5f0c2f22fa2d092f", + "86f50f0524ad909dcbda4c28eb79a78c6da1d5d15384e8b6e1c7f91d0142b8b9", + "0c2b51ed8502f146f29699695c1ffd4275d251d38611642fe39177d76671822a", + "456701335f348bd4d06ff4d012a5e6d622bf50e5f6453aed30097753d2b44576", + "4e91b1b52b67ed1d1d6c2ca3ac80dc17de98aba74cc87983135c44d4c138a9fa", + "49da2c8961e461374b691beee038b5a37810dede0da9a249672d894fe5f1b34e", + "2765dd9fdd27d9ecda4b42a834be7238fbb43432ac67cd858cdc3784cc404d2a", + "91f32aa0b8414946d629df119772a467015e42eb63d793cc75685dd45f8854ec", + "31e3c0e4182dda48fe01becf23298bbec9671492d1321ef2120d468d929e8991", + "54eafc2a2f327afe665d7012b39ecbeefea2c00ee9dea5354db653063c6cf90c", + "63deeaa03d64de174ea0ea282026a08489cca5304c801fe94118c901b9c08f19", + "50d593ce1b61024e1a140d5021582806c0ee292dc58ed5a825369f357b1e9d57", + "da27afcf6ee7287b57bb4f3e822b6bade64461630b21f8b9b5ef411dcac33b38", + "fbf2d9a05952eedd24dc71dfedc5bf70047de91eb862455477ebaaf530efe087", + "60f68dfd68f0237e236687da60b18f0f08843f78c8f7f0bdeb8609773e3f0988", + "1c6dc10164bbd5c934d29e5b730b669642decc8ad3cc52090ef87dd24b46f667", + "25133a1e44700cd1324ba81b9ff99e5f0307975c6a843cfbc7b08f5104458c8d", + "39461873880b4f800f005b36609643750a15dc294d86ee3c3eb41bbf11d57f19", + "5f81f53a9fe99950bc92e6c6124eced8f28247dbb60a0338a2126d835e4e4240", + "1248a17e26ead341e0849b36fe4563dedd6e28e0e97fddc482dd8d60ac2e0878", + "d25b4202abda7d279f3ebcd01df05ae802f1714ac4c376f0ef8849f58e2b5481", + "6b927168e0aa7317ce77804c5dd1819a4203cd0d9241111f24e627a091db3a43", + "f530ae50ad102f4f4ee8b6ceac7f68a4e3265391a14a73cae3795c92f762873b", + "04eedfc2807560623bc52f88129e71cf5b29b39b9d2e73e711c24e778b29c8f8", + "954e2afedcb4e6fafa15255d8313acc7ac1e176a82c400a84d2e35b0d1f6b72b", + "34dcb539589073f470dbffc33a2c7e80e7416022992c1fbb440620ce3dde026f", + "15d8dca1df96bbd93be570c96ad4565d9d8429e9819a79b34c9d4014f53907c9", + "9ce7219862609095ec060adb4aade2b386e3c408c99832f8f3560efb5b5181e1", + "2e447c3d6baff57791575902eac50b24c46161533095cd82d23993b0372abd07", + "63597ef1c220c228e0cf25b0b5738f239f7b585f28070c2af3211916bbaf4aa0", + "743c03d190a3c12e8dd871b229a31db9e9580156498086f9a70e94b886c68344", + "e9943e3282201793fa8e30494c5fea32bb58b5784121c0a291d09830f4c67dab", + "349ee5bca33a20474dccc3cf75f9717c8b9fd87218993054e3b18aaa22381dbe", + "dd857fcd383d49c8b569050a3df033f68b154424192927d063d0e7bacc0fd6c6", + "36faacaddc9556a6091e25bb30f339281ae0565c27620683b6c39b859547fad1", + "4fde20991fd792c0f18215ddbbf388754d30c69adcf9e5803700a28192cf61b7", + "688867aac1071c273f4bd98921db3877738286980c2f633dc44bc13d99c7c3f5", + "41aacd8aa595148da02b5ed29dbc8000ec03129d18394f4eacc31fdc19256570", + "bfe5ad97566f5272a366880b898fa4aeb06612f95d834e9ebb86e240f1bfe4d6", + "bc953ef1f85b6e69ffe9e566676de731348712d65fd5c9a0906250fc1069e2b0", + "3b4e20ca5a93abce1e017cdc772d192435777a0eda87c0b427e5be69d5121998", + "676561aefe687b73b136c5abbf35da52fc1d04fcb078167ee2894c311bac6d80", + "0281ba239ad7960f7b0dfa257ffa96fbcff71fe175f73acd7518b2daa866ed81", + "6440ab08abe99580f0c4feba7c077eee051a62313ceb9d1027b724e266846b2a", + "642616d4b0ee34246a08d6ecf6102573656806284748e7f4d74339d958a7a040", + "71c0094c5ab6029c3561cf9c5be034d714649b991b663f9b195d7e685ad20daf", + "132865cf8b684ba11b6f9b1da8932e800519efd0c0816e1ce47e875540cabb11", + "1eef16dac49305da35d7046a0aa78372f6b4c65442306fea135887eff959d690", + "74207d09de2e5d71784148df0fac599efa76df394b54e79138d3578dac3fda08", + "295a51c9609e9cc2410611e98cad2e6bb556d954eabfc83d7a04f5735e47f82b", + "0f9e15a398ad5a652dc381a1ea792cd6b8fb00c7297261e7e62eded69ee18a4c", + "80c1fe084596dae46596fed34839f43df8af8c4fd538dd7f8b1999877e284a95", + "3f6c4bca6a6075b66699d727eb75e2961c1d96fae39a0c6da90104525b90f04e", + "ebc18521ae7d8c64acac13a796c99efb443720bd7a8a1f2d5b7feeca372bba9a", + "34928609bbfdb916f6ff4962294fd6b8b2a0dfea30c4bb0771fe5136ec493ccd", + "6a0d1cbb9b70a6f322167e6321139a57e1fd59903a140216bad1c550ff0cb4aa", + "b31ce4a7f1c266782093824f3d3e9cc082bde06ef40519c1b54f71584db67206", + "44dd171cb4342dff881c408aec5c1310647d08bd2a9b0ca7d0d862ef606f84d8", + "d87acb60859b4c9642383c0f36691db86f67234b314253ae315df58f709d6bb8", + "05dcb898e347feb0b14f37fc5991358d311a65735fb301032ce1baffc659f2b1", + "ed241e51d958b51d447c5e38be64b22f289ee8b4aad69d13d8854fd0ef489746", + "f8020bded769c9af98d21f7c04ba39434459d963a8c75d441accf2052f75ef4e", + "64069e57bbbecf0c37a5a3505bbaf6c38618141cbae73622e343529369030e6b", + "da35795262e6e5275a7363d741c5f7088d92fd4f9a184074630bbbcc1700f11c", + "e71616a10025535cd1ba9542ce98276ff38b5efa9aec8a0a3415dde294b7377b", + "3d264fb6ead981b38c999e930c6a2b51f47814b44e78e30dd46196249cda4847", + "e7a8e3ce0c00ea661044b89cbb4f895ecc296b28c74c8ac80c0834eb011643bf", + "d1e97ee93d842b56196514b188349721ba4fc4f6ed0004c741fa507bce57ddb8", + "dea47cb638477f7dee9462f5e9f95c3b1a9e7c85bcce20b04d9ce0d7e898ed61", + "2f31a6b9a18caec29becf2a26e88db1c693747f4b5ed920781bc0205210677e2", + "67333e12e90e4516cd737add7084da22692adeab747e4536430200449986ed17", + "78f3725e6982bfb5b27477053299fa7298a1f06419c2786bc5c5df6fadbcff68", + "82ba3de14e34900eeb830e3e056986f6d860f3364c06da826726a6cad6913766", + "cfb6666f3fe9d9c80b355c1fc4c92e5216357c6fcebdfb89780bf8ac4e0d872c", + "52c27fd06b69dde2163a4bd840551720b912e6738531c2c8a20f1f4f1c445244", + "2ee78cd22f63eb032e9752acce83ed9468ebc465e36fa4219e3a4412671f1bac", + "856f3862aa1e786318f86d55e3145f221fdc0ea4dc16a8bffe5659ac4f68af79", + "369d4f168801c9f8bfcf2f5d11034f86587db2076b9c715ea57d90f1cd5d1dc1", + "82fbfc3725d3161def1df6115c9fd4e071e47b629929128c03f8a954372029bc", + "b959238d1fab84241b07742a0e8a53d91ed00c8955d77a431ec09df8ff26e0a5", + "c389a63f436276b87caf4267cbcfc4891c5f76ad55e897d6a8b243d7f9545f73", + "1c60ecef2affac22055e3c8d25ca6cf90166b7adb08d467ac0ec45b666da1a76", + "6dff7e5abc8c93473d9ee8fff351a94160c075196e776fde4d51f5535838a266", + "71b9052b9d4783f4f602b149b2752c6bbc93ce60a954da5dc99357023dc11009", + "1e2b7276a9e76ab4c793f3be2a88dc975b05ebe3b7e944ab3db012e0bd54aee9", + "c91772c6d7f404c97ee72d85012a223b023296139dc87d938a2187cf3e7e65d1", + "d514f08e7307dbe2208ade58ee656afa4187c976cbe7fc5512df362f4b651459", + "f47fdfa5323e2d82a0368ece79a813d6206562fbc558a3b1d0e277a7cf0e40f8", + "0e4377a0e48b94967621805fc983cbe2aed5d896ae325d6a0e835518954aabd5", + "68c3f050256db220f6fd44559891514b2290fe7d395f0d527f8b91adc6902e1b", + "d84e7bf175949378260cdaeb7b197dceffd90aa1aa8060cdce53ee7cdcb80e80", + "56811fca518c82f52d757dde3703eca21f806b5bd7092fc0d722f34905afaa50", + "e6b7ce79ece3a7221a061e2c7f7a0309f977ce6473bbca4d9546023d51cb467a", + "8473a09a4826efbc92710cdc4492c5059bf36414388f128a11af59dde6a244ff", + "4328d9d2f07588c3bf967a46dc56fa568c4fad4083fc7143ab6b4925b2d56a65", + "84a7add40ce0c98d6e12f07a951fdbcd565595d24a1c7ffef5a371b9a3ec9434", + "b7509ec13b018c977e17db8e8ceb4b4b725f1d00de184201ee919a7e9467653b", + "051e8f0a8cce7fc40c0ba30dc890678e2353dbeabc6dd803de00d2149f1870df", + "c9acab792bb743226a6e4444e2d4bd0c1031502e603cef24955f794ea0f33067", + "6b7311a998ea5f3a6c878dbaab3fa84b4a8b56609525b0761fc8658ff7a56c30", + "1951d243fbeaffdf64bdce48101ab2e65afff4deec9377e26f7600744333d489", + "1b35fc3e4a14ad04ce4aab5ec701c1dd5888c121cf12c5c6f148d67e58366752", + "2479b5e5d07c65d0ca13a8e7810fbe542b2fb017a4856d0347f290270b1b88a9", + "0e15566e3277b3a70d77d7893294315fb13647a82c5021c2d095e2b4290ab021", + "e2bb09d2da5c298450bff068fee154cbc4f1411f63f8aa3484d8caac616d19fc", + "c8edc09925192a48973acb8ba75c9bb7b8573ceae0d59112b759d6dbd15d1f0b", + "bed9913fedd2d5260092847260a1941afa98e549930eb9f8d3547efa8e1c8b66", + "98c3a9d81f48cd4a9af11f6b6dbeb107f76302382a6890bfedf0ed40857dc993", + "4d16e8feb2c858cb747c207ff0df6293938e1387240ef55cba0433f5b561a288", + "ba5ffdf7a719122274e8bc75c3fdbfa837bdb4c3af21ba77c05b8f7de1839779", + "fd75d6de59e7fd59a100dacce7cfeb75f752a47d26164cc2d0c6e62a7fb27462", + "d4a43e89f33c0e6097e9ee2b2efd7d893e27dce6a28002f06cf8c9932a0bc6ed", + "0e116f67d37e2c98f380b7bab2df73d99ea8fbb405d6fe8124ecfe4f44ac3a34", + "7c5e46916503c2c97c6ba4924635d01bd3107f2ed8d3f5a8f3667d5b562cb617", + "b68478485214890b0dfcf503ff8edec0dc0bbc354cb219c49547ead4a09e71ee", + "8aaba706605b8f01d2d9e3cb3dc161d5b6a247894deed34d568fc1aaaee62ca8", + "fad7c4e6a07d099b14b2881f4a137fe4c01a808dbbb7f9a0eb7ea2cc6487a8d2", + "0299962df9df651c46ecc54a6a2ce138c62a6dd0c4be7ffdae47e6363da682ae", + "1ebcb5b7d5f84c0378fca8f604f4798a2da9d3d17d50325e26445b351818ea43", + "e23662328b15b1aba204dcbe7097248a74201811ec12a81ff391085c1c0e1b30", + "741eefba410d765395f0ee887ee9f4a404c035ff1ddfd804a7c6e4ecc639dcfc", + "365efbf3d2d6396a9963cd099e44e4f1718bc612aedbfbeab95dc1af678c9bf3", + "97082f0582d146d86cddd8f53959f1a232ecfe193a41ad3917179f894e5b82a5", + "70eebb4f2687c8cac610ef90befceb7387ef0ea844be2e7dd079dc9662db30b5", + "a088f7ad529a54b2af99c20f1de36edbaa445818a80ea0990f4b5535c480c5c2", + "e36339d5739c43ae373687cef432b03c38afee1b5294fa8a4aee21b1b64850cc", + "c028445fe214ec23ad96ec7383eb9d9531c0096fd0856b5cc461642ad2af5837", + "6058d405fa3947c50d1bafc4123f7d7af4be8fa5564a7ac01f6b394953a548a4", + "b6828945c614b60b1b6425eb66731552a112f81a646eb65cf566d4c798771544", + "7aec0021220b415cf47b5f3f51f90701568bee75b113956d854ed13c627073d7", + "d0b58cd7fca49ae3a72fe14e1d7d91604f18fcef3a3aba059f9c7779aba0f418", + "d24aa99d02abbee831e6348a667de6cda62a0a82d9bf87f20f2bb2b2e1087a4c", + "b8075af8f0d977c453ade5fb499a14c4be6a06f985405b8d0112309afd4458d4", + "72e544026c657cce514d7feda3c315e48afa08c9f7ad21a7477e524e5868ac87", + "9cebcfcbe3e1c124b585da084765bb7823848e519f51c86689f1e4438d5f246d", + "a940e32a7ea78b1d4d33058e854218053e037b2b6b1c9e11c416cf1d2acd28a9", + "65f9c9dff71c534f4d68afffe52d1b2a5f679b6dbd9b175b4ca8005bfe6e3315", + "bebb883e489f583762dc1f216b981029922423f1355966f5766411676ef6382c", + "0c9da16f74be9d8624c247da6ebf085d5b5ff17ebbef83d526ef0ae07020cbc2", + "80958bf06bce58311bb8f14c6f940b823271f1659eb583e955949dad53e1f360", + "a007a6ec9b15d7c643973be0a93e5117dbd4c0c8a5124b3c2c30c343e43b6029", + "4b3c0b47c937f7b882e5d9683303f9813006b571517693782dcad922181696b9", + "2bbfa6e71dde626cee5ca236edfa2500a51bbfc5c741c0a52903a5ea90a3da5c", + "f3994063904381537e899489a49594313dbffb480c43f7a2cde2292e2f1789ba", + "ade1e9a8f0f6e94bfc7e342a4c9653a39bf820883006d00683c36ae60e6235df", + "bbff37de9bee8517c03f4bf95a7cb400cbba65d14d7809db9ce211381ad18e80", + "be405fbd7f168eb50d7fae6bff88aa0893e36e9a8edc8ebfd7dead60a1027a9a", + "bf250ed458f1cb7fab15ad43e8e93701bc027393a0751195e1804b168ca4276a", + "69b322015f8f5ad2cb2692e09df3e761224232314aa718cf5bb02586ddc04897", + "d247541698c06d080a9575c8247dddfdd189718856299559549f5830da742d3e", + "62473a57751ae484a89e9b719150f2b784c7851cc50a6db2f8275b6b925816d0", + "301754f23e97ae895c9a8a2bfacfe0e8d7fea3bd426f3e621fc9626133e53dfe", + "3f8478ab98e4d47edd2ee951eb67480e07cd8c614352b7916261cd59f8496ec3", + "04d61e888b86d814902dbe4533cede4d1f3d2fb1be0fdb3dc56246747d5e1786", + "d61c1f47a9f3caec13b5c2c1de644118fd1b67df3f6f51aa4109b20a537c7018", + "d0a151b92bb1ceb1eab439e3e1d43db608ddc3fd0b8e04f36b272c99cf2ca25a", + "c12b0f03de16dcc6c38fa5cd1ba8a06d6c39285700643cc78d0785ef88c24a5c", + "6878efb2fb539857af42821be66a316b6a771b766a9b398246debdf6f989bc2b", + "81e9337112ca65409841a405287d6c5ef4c2738581a77f5b90e7bd8493c8ed94", + "6afdfdb47930882ac0ca2beef557408ebd1f7f36db4fb0b492829d73d766ccd1", + "0003ef6c1107aae03afa37a118008a4d1aff2d845acccc79bb699cc028abce64", + "7f961c0eb82b64bbbefb0d9e8c3066da8bb9442710efae0ea0b8b5f010e19236", + "3bb0da93a8924e9fc22205e161cc34012a6ba17bd3dca899394a73ef19b0ddd2", + "951e2f86590cdbf455a301c1c83acdab0cdcc0d3ad659c7e96181557311517b8", + "a8f8473cd733d461b1d58d44025e9656be70f42bc318733f23446f0990e86bac", + "d8a7088d4ac36217945abd712d5d6c7dbe246427760dde95913ac4bcc83223a6", + "0ba79fa3aa829cce47e8d12c57a59d9f0df15a58e030d1025a67525d7807685e", + "11d325ea68fcc284969a7706ea6db28500d190aa935ba3b45fad4ce67891f827", + "4260174a9772074726a7b9a5e521ae08e924eb72f413ed6c34e73ab463384de3", + "e988ddf8508d88a876a725f98d9cd7dba93477ebff1811319f1675e05d97f659", + "84c4768a6e6a200f8df0d5644ade0b5595f71ac3b36ff8fedc985b99bdbf7a7b", + "475d5e0ad0f77e419852a0a5b0619143551961553db48a09c19f857408b00fc9", + "8354bdecaea6578edee2f0832104c56c5680123c4fb40b9369bbd804fb06c634", + "6f734b14a62c10465cf026ac77e13806bdb993b6b59d41eb9016bda313e41155", + "904f32350fcabf725d2a5bfc015540d7909e790dba02f6d5355d7a54347f6aba", + "27f84d869150dc4a23559c13137254ce9d84c48ac6ad8df8be7d48abbe74fb21", + "812d0b6816dccb07aabea23818978b379b81e322b99893e785bdfa0934e67b06", + "ab140151aecf119bd93a001e1f768f3342e2e3f7ced6f488b9ddf8ae4cf6b519", + "2056507046b07a5d7ed4f124a7febce2aec7295b464746523787b8c2acc627dc", + "a83594bb29c0722f9039a743ad2eaabc3286930acbcccf109360d443954bc050", + "7c63ce2c83771134dffc2b9809b6e0e29ead88569646aa710ec37f5cf25844da", + "9b4f77096539aeab5d5089fb197dc92460f51a395fc993733dfd19315a89db1d", + "edafc0cb2fec91cf36464018b86e0c4c5f9c58ac4353a111f29c8521eb3289b5", + "e213e2876956434639f2503f0cf4a11b370fb2e499de0ba5ac2026917602bbe7", + "9bc62a1d4f02cecc688737cd5b9ab2d8c30e5f58bcef1bf427f9cd9524c21419", + "628895221db014238eaa56fcc009c9d30e78f1368ab8c282a0df47f4b2bafb70", + "d91102052f37bbc76d44995c897c1218aac5ef5f4454eeca9074227f4dfdb986", + "5a3f9da6e416e347fbae9425c6118a896ea524bafd23618a0bcdd76ffa12182f", + "375589c49c35f3fb26c31e6e4ebe7e613c0247542faee848dc252d881154e224", + "7d3b894ad43a82536254fd14db72f7c9b575b6e0a5e56ec3df226b090b22520c", + "b08be1c882e9131d3a11bb243b21b1ded36019e06200c8e666412c6f60f0c414", + "e0217ad4b98ead3e0202704e98b92ba2c85fb67a645d91e7db549603d69fafa0", + "1e03198be29853a1276102de12fb7f03e4f609b3b56ebd4bc4314391e6919dd1", + "fdf6f6726b253b562abf9651b7e22df0f395c4c51c786ba012f21b581073e88c", + "4d93717fb4efd413a9484f0868382e06c672d0cd9f1074a9b85e7ad8f0f01775", + "93c90afac6ceaba20de2442810330910543263067c1e6296c8da1ffc85d1e32c", + "5c9a52bc5b82508295d2761a57c1a6661affd194770d661e126cfb2fef039405", + "98b68c81bf20c93f5d8384db317c0b4f85baad84f0a025037f3479f91e1c0c39", + "13cd6aaf707b10eabe10690477d95508d3c3f87df11adeeeb065f3d35492a092", + "a7069ec3ff69fa4deb00a5c6b0f3161cc015e3539035839b04af4bf89a103b64", + "2b978279a0a4abf014adcc6bac2bf61a914dfc1e06705c6b8189f09d658e08ca", + "67d7eace38f077a7a8946760ad1dc94beaba2abacdfef8805a30829d524c3f3b", + "a0b42d4c3e27b5e135129cd7e701cc7599ae3337bc6b04cae8a771b233ef06f6", + "4250292e33c2cd4f7307a032f526fdacde1fd8880ac1ed28195cafbc195c753f", + "8525eea1f25685e96f2356e2fc9bd38a4eaaeaa70fb5a923f90814a076a69ea7", + "9af4cf25b4c95c8d53d35c51f0f41d9d4ed9fc7bfe745c4a17a1b5ace497e5ef", + "35ece2716b5d8bd83b7c61ac9fd1049f5827149c6c4d99294acfb5421b167c27", + "22ec83f0b9427bee2b762e811ad2711a233e6fac192ceb179d1088e34bdf71d1", + "676d305e6fefe233f5c8ed654a69f72e30f679aa4075f37711ee852fc12f350b", + "64ef324ef6d6485bdf83374d7a9a67b080c08bd7ce0e19169cb63caf8a96b0c5", + "a44a96a6c7774eeefce8298f1dddb39736090c6eccf8e24c5815e14007c330cc", + "69e3e0c41ceff5878c5d0b7e89a8dbf19fe3f82f43f5e08881541f6dcbca8965", + "c724a394275d457b45829a804528c66bc1c8c59304a96309337067517bfaacd8", + "bca40b678ae91500a2614e8403f0350fb766576608c95af1b9147449bb16a320", + "d3261da293ad0dec4404425fbd904880b0d5dcf77be526f678097e2c239a2867", + "c4ac9a755141354f7abc8cf1a43767b4a2819f48938bab2566d3f8e8a82589b0", + "ac1a5a051e6ae3958d45d17cd9469cb515ce2fd602131ddf33600226b673cdca", + "5470a2e5fb981698d5584b68c0fa73cad530781840ce4fe6360d7e16c539c0a9", + "c2b81774d57c11decfd08d61f80aaca4f08abc040af316d912939daf8e6d8954", + "e499539c34edbdf5939fd614ec8ab864d70d06888cc9c529ea1424932694c2e7", + "f95eab0ee2d124bc6c90bc2713697ddad11e4d8d735e806a1460b1257812a7c1", + "541843b4b12242ca233472eb9347a14a88a73427dedd7d9f524c3e988b176304", + "ea94225ed92fff2535ce322bbc7b2c6abe1be9014f88fcf45432ba7b02c855be", + "190cb1d6b44ad38d1c071dff93713a1b48c5c279b7466e22e07e42c98b3d42a6", + "549e03377959f6bc1884adf3526c101e5c541f65d8e99965b0b599b3ec4016d3", + "9f913190db30a8ddb9399c8bdc9c12ee1fb1faea78d325a3b8284f0ce3d2b731", + "9b0632b893cfabeaad3612fb25dcde25171d8ff6b280257ce82f96342b467ae3", + "bfa958d66ff3aac1dfca3e8938c0a549878c282a5af84e530cb118bff145db86", + "0ddcf4264d2af326a3f63204600d8383179beed1a190083176c679a6eec4a89e", + "5c1092ca81aff09b5dafd36374af11e1260c89de487d31eef0821682a338a7f8", + "46fef6179ecb8c0edad9ac7228607f3be6aee4c9684a3ae55d1e18f02dffbd53", + "9e058f0c169be6b3367be2d470589119acc83b9da6611f59e9ccdff43c5af6f5", + "d3520b81554b5a04397ed86bae6312f71eaa2c4671f65b4132e85205a7f1c911", + "f541c42b850411f46584aba4e82dd7d64420c712f55c62f6b212147751c8ac89", + "54531f535352220db569eee6d327e359b9c44afed5f8d6bf0081989a11cee791", + "8c816a74979331584d06320c1c8eb9d79591a8ddd9e7121db5a21f4be8163640", + "340e03f4abbcb71395c26530bebe4b8846a758ce294803b03a6c3a257b5886fe", + "675782db956ed53548bbcf7689181cf3d394ce5ca8fd2b66fde315acfa21e623", + "78b589eea14b244738cf0062cfab2924892d32d6ee204f3e8e5d72ea869aaaaa", + "4cbf59d98eb5708c293aff04dc67259189233fba52d8557ace33ea419e5d769b", + "6a3214f5f90b2efe305a553317b10193c9ef5fd01cd18980ba7446378d5efe25", + "19bca9c1c3c580ded2cfd07932564b925eb1b0cf97cc165f96acbac4491634d1", + "591866bbcdf6bd1aa1fb298b8cf0acab3358615a9134efbfdb6407b3fa375592", + "3f64887ed06e0b627c5ef5ea49dc9f4601aa8fc52600149e8a9a9ed5acbe20c9", + "66f935ae66fbbea614d517d8586c55a68859814cbad5bf05eafe8e1d89ae4056", + "facb973e3c33e9c50b1e95c96667cc2c13fbb89f4b6b8edcec6767d9bfe09d9b", + "07e2887460ec425cec80b2e369efd7c3945435585830dbe0eadcd0854aba8e4c", + "e40e41bea174815ad088353b3a0d1830783b617149122c36d222b0fb9a21359a", + "12dabf1d4e054496bca8818e02cf9646fb74ed7a0be692a02a72e6e8bdc30b42", + "7c0bd1764d435ad8ec5dfcb6722907adbd3e918f93a563982be8a9b768e09f43", + "2a4baff7437f9a62ff3fcf87d85321e9978e464226e9b1642091a7a1887e362f", + "b536020dc93490c88bc7cad0fff8f3552e4a96d840151d3f9ac6cb99d0c265b2", + "1d35bccebbf0e935b95f3837f6844dd83133710094a5c743c83c620f14ec3183", + "556edcf540e9ff78a9e78f16053f5a53263e17fd5416e16be61c00b6c52b3903", + "7685fd12982e95cc1e4cc8114babef2ee33483422bf60f7bfd269a9f735d9200", + "4ebabeba70c32377344431d695c9f2d7b80303c0e90b3706c9489ce5a6353382", + "09adabf7bff706de5665c83ea19b018f5d3584e7cbc06de183ad0a2fe7b846fe", + "023a925555570b719729d6f483eb7428efd651f01623832fc4e1a787021e138a", + "f87c56d1848e7ab3691a55d0b5fa08c9f76eeb6bd802cd3cda26d9494bbc4c3a", + "4c63edcc751d54d6180fb8c569becd301c498cc6f01f1922ba085f2ad4b06fff", + "1d808e4848bf484f9082d8d72414067bdfeb75949d6e4d22e79f8de231068d5d", + "a77cc34d9f0cdd24adedb333b460a28d28240d078f4fb2582850f620b2ac489b", + "8e72267ec5d00aded24e6d0c44d3d57a214706cd0d28e4b37c3878879c31d3b5", + "02c92bd095f9fcf601e913d3ea51bc7589eb50891d2a59c24bdb69aa55165f33", + "de8070bd5e6a7365eaaa1a0dfa019269b9910e47b78af68b7789631d8d99bfa1", + "c1d2c7e9f3be9342dfecdc4d2f10ce14e7bf664dcbc71b547e43fe9f1dc7ae2c", + "f0048bd474b27ec5c7210e3af4ff8c5c53fa876ea8473e49226ed7f085420371", + "303cc63749cf3accbed38374d5ea77ac75b0333c218b700f1aebd234f2890c5e", + "b1cc0682c7636223c252749aca27c5d27029c3a76653e3b91f8018d04867a01d", + "65d7cd7d63e6122f37bd004eea1c9d46c0a13ccda42508200b986e40596314e2", + "912e86f5db48d8cd5e17efc5c5c4864525f61cf4aaaf4fe69a6c0049eb12bb9a", + "0fafebd003192cdbb01b5460543a2fbd9b045f7b606f6fcd7a1404b63bfa0bf0", + "0dc4640949c5bbf68f62fbadbfdafb314a1dc8b2a70968d0a8ea7c20f672e6cb", + "462360917a1808bef197173d766cc5dbd5a8de8418ad2facef87b21c280d8a19", + "5c264dd605b70b25d483a41ea2b6711668cf5587fc36f51e2be8951b844a4b0f", + "f55a4d628bd4d2acc852887beee2af0a80a190318c28f9f3a4920ab991cb78ef", + "28a90b8dc71fe46bc7b6e4d5cc0d75a586d34df0b9882f0ecd0b83d11697d989", + "d835e614a93e792a0bdbae5e8713bd8b23a02ea358206a2cfdb7251059f35b29", + "d981d088ee0b7070673f95bdcf189127454d796c85633c9e253320be41509d07", + "29638366b8917ddc44adea4c51b2d8876d5721ced5c32651e572de9d38620575", + "4be79a30920194e87a94abd8c6bec9b61b99b258e03a9c66e3328f840eedba06", + "addf611d93e32c6575a692f626d50c856912d5a232ffe0acdf6b283d4aabbf0c", + "43ef305195245df906758c62c7f49e1e576a7e1573a7f5760bf1ca5b29b8d672", + "42e1a012c67a553b8655a5e495925baebaa30e4eb526f11f2aa729d1889d9980", + "cbe138bb903d0e055f1a0114ec8b62e3a2b355f397a53a3863f95c9b7d574105", + "d4f4d096ec9112f9bbf4d7a62679ab0826e044166b905ef0ceeccdbeb91de5ed", + "c4b20e07fedbe731fa721984678b1e100bfa5cd75eb2de0b92b05dcdcf927dac", + "293f2b4be0b126ebb329293fd0f3072dc5f882bfbd5edc50d4b3538571adf575", + "5186516a889182a09a4d3014513e331a682b8f2c316fbfc0fd4339c7cd0a3f1e", + "396e51a63422da7f782f0c8051beec317a5638f6a2672fb0efeb6d406e6d5acd", + "47239cd994b798d468bb9b9a99e111dcdc92c24d7d3bd58e0de777d70450b261", + "1659c95d55f3d0f7283973b36db5d401f32f4d8d43bf971308bf208761e35865", + "c5fda84892aa4364afffbac7f20f5153a10a8d23c5895af4478417cb41ff09f2", + "fef06abe34740253a0ccf5734dc18df454ebd8d0ed411324e7e6df502c3be34c", + "13442482ac3d2327f4b5c70db47b657f97927876982521328826d6acb8708ab6", + "bab6f4393e29800ff1ca8f331eebb1a125960185ac32b890684d1a1b1769c96c", + "f355dfa30259797fe089c03995ffffa2260d683240ae2fa9a0abaf70d26ee981", + "eb2ee33d867c7d07dc75748c8988244bac834e5d299d7dae567ce5cf69a95ebf", + "b0bb358f384691dc6e319264b1370f4df668ed0b52d92ac8ab3019bedc6f3249", + "22b3a845c00ed5ede40a10cc49b5107c93ccde0e4630ee67b0630fe8778bf524", + "0045825a6230f10cdc43ccceb0c7b0a933ef2ad7a2f2805090f2f9bab30cd4b9", + "9039b507b4eeb35aad9bcbe407e4ccd3d6b8a86bc3f271027775ac9a67efd4dc", + "def63e228b53c29bec6a333156b8dc4d7cc31a6d2b613684bd190b31a5157059", + "d3b94e93d016959cf9e9495fc3716f7daed1b5278cd0224d79e3d2eef510c577", + "a3ffa01ac29c47a41a98eba21990a148a0cf8b2998ec26aeca73b546ef0b4c60", + "0415f7799dda5b0e9726a895a04857961e78e5949c7fd78189b4ab7b1dd0bca6", + "bd7f2ad523153b5e31a54e8412ca30b2431e0540805068b880c2ce6a74b5c0da", + "474cc4201a6cbb9fca246b4a630faa8b27555042a8c18cec62fbd3a6dc9cceda", + "160f02ad21100807feb9b676added7cd5b6705c95218af81069b08869be37b46", + "99842320b55cfdac62748eb1a700065ac68c71fa1a3220f171219045dcd2b394", + "bdc735594808436313aa319b6d8f8ca178af1fd7039fc054cdb2c3b0a6c67ea6", + "a3e7745423f81d5f5671d06bcd82d7b46ffb47558f8dfde252c75330e0043c0e", + "37a3351a978fd4a9aa8699f566fbb8a775aa8322dc3d09ec4b03143e78d909f7", + "a064e72dd0fd26b7734dafd0322255ea628aae8f34937836c7bdb96ea68896e6", + "0a9194dae90f68b6817665c66021f6daf21e00beec48e935b1981536692d5600", + "5ec388b607c27730287a84e8d881a5014d8c6822a73b270a827297bb0cb3e10f", + "34c29aa9884489923c5780bc34258fdc4674e376589579772a6e553875b79051", + "dc763546fe48fd4b23e48111de6184242cc9f8da8b16e8dc41b53de685eff32f", + "870da0555e9a7b052fb3b791c45c0612d6aa02523a08fcff7552224d47be29b7", + "8019547d617f80a2124b577eb44f06798670f58663ba37ca97cb73b58034fcc6", + "02b13430bb39b977a5d47f9061214193b4753afe9e790ae674973aaee0e49fd2", + "04bf668313ea852f9d5aa43891e59da9d08782c044cae53f046c40b299d49b2a", + "ff936649cc75041ec853f6912fd3c495b570d263e68e0bed63c740cb3f9f9e21", + "ef1e9a9ab213452984a093838a63bda6bd401e6ac9abe66d6360288b4371b208", + "285a06a2595098ddeeb9649411b837b0561d9282390f7011a571cd15d5febf23", + "85b1bbad5ca513b1dae0656baeafd641bf117f3bcd9bed5445774acdef65f690", + "27e5162e181ec14c8d5ecc018773469dbebf1e2dea979dd65488e3ee4a63e169", + "2180f445cae499a4a6878e7902dfac204e9c47e7014e53c8417d6b6a1c8a0fa1", + "298eae88eeebecf62198aa909cb31c444f0c881946db4074b455deb9a0e188c9", + "1e856421865518657f92da3fa0e65e3b275e61c6627b3a573e042e00ad9cc361", + "10aa3cd44787b4bb432b89a1aff0bcec16ab155b7be9ce192c7c8553313aab50", + "fd43eaa1418d7e172fdfd4afad05b64fd427bef0f014d8a0c5911e8ab08d26fa", + "7b987e83b32b5a33a6a3d1563f42a8021dbbaeecbe46919cb3b1fe9cb84c9ca2", + "f353f1f6c9c2b99837965def157927eef23f976412f8ae28688105e0d4c7e375", + "7c1f6659bb35c22b1deb717a4a5140b6ec4249ed5b48c006dd5576fa1b5b8e31", + "18c76dcf4626082d5903730e66a78b3e0adec35a21bd09c2758affe5cea8c83b", + "c205176b0194463cebb6bb7f62c30c006105178a0ff29caae7a8c904b2526388", + "7cebe33f9b7047bee8c822926a31a01288a61057ea92efaae7592cbde273a29e", + "b151eb08f3fa3d1cd0431ee76bc8053539bc5111a1117453330c08d14f22d88e", + "40ba7263e30a4877a3f8d16977a0608eb3b9d392d391c85c5fb67608df37997d", + "d60d3ee9bb41ccac6e9df1a39f8506f7479015125d841ed7c73032d900d21d59", + "8e9202f2025bb75e25f2189d6c35b6f88282249683edba043907f3e88fd1c530", + "f3542ad456c00a77f2261be675ea9805f7061b8fd94856cacfb3348d2fd504ab", + "cc54ef03710760d47f437563dc468a842d66a5616801c8d7b30df4f3851ebfda", + "2df0fde3f8900d848825893ec6f09cafb7b9e4836f859174ce5846055f3aa0c4", + "9c3faded7abff9400db6923cef242058470af968f47601f17701c707b2546d16", + "12dbf4c7a4964b3ecc56ad8ce234b02729fc32aa5d23e92a005e35ef88e5032a", + "9bab9eefa61a8aebd55bc4a5d885c8c192811fb6f0652533d550f7fa60d7559d", + "d81813dd21119b08db2c50ea97b80eb85f671a2e314b81543b101a788bb88c34", + "bc33678d9aa3da34ccd421cea99747c5b8eaac42442e1202912c40c6cd542cf9", + "e7f7bdc9526de105e978d201a73765d362cf97710d89f62dac4b9c898f16bd85", + "602fb87088b4c5cec7c75f2e3b50e56e3917d41eeaf7e0c597f12838e8c23eed", + "361a303b7f0380c8b83f0a5f0ba33e1b540bd347d970c2892e6e0989f7b08c5c", + "c4ff1c85cf9226fa48ff89a94f1ecb1928fc089448230b76dbb8d9e6bcc67fb1", + "0f1a0d267012a6df65587790bc367f8e9c379cb94a76f2efa1ccdaf33fd12aa2", + "59cdf79ab1e9405876119c153739b3f6811170cb43ed9728065397cd20fe2fb3", + "dd8555f560679abbbb12240e57ee99e883633ef350c452962b5701f07043497e", + "e0243e543c04548169efa3bd927f1932e240d249807ea1238692abc72cc04ae4", + "db8d50482f835df96d9a15875e763ccbb2b5a32b71888ee04ba3aa195bd14cf7", + "7400dcecc1ccbf043a0f85239c6573e64c1b3fb718d1f3547901b0cdeabe998a", + "526826aae4e76b8e923bd7e3ec732427c67ea2d835aa007bef9196813909042d", + "17355a646be0342ed7effb398b2e53dce2090ed16999abf63b4c451782a99498", + "0831cd95a74f4401e6b64062b968d2305b35ef75ff17826cd4d9600e16ca5c77", + "bd810ba0aa8d3013a45c7e858849285d016c33858609a7f15374f310ced537fd", + "26b8a8bbdd3550dfc626b473bc7af742170ef6bf3f56fe38c3c28553616188e3", + "d21cf19e43aeac74365d4eec16de4d74c83de00ebeb72d549f9715fe1f956849", + "d1447084ba6ccd0ec9b456812731d3af33d529d5891e5d616ee8da8ef963eb42", + "ad482b8228c8c563156cf92b834388cad230510e4d6c3a22ef0ae314f6c37e01", + "1d4cdebd17b7b3fd99e065055dede203b52e5c7b9d39351b73cff932435b2f41", + "fb29fa8e5784839ae3c7e970c3cfce3fabd6e852cd046874a54a7300f45df473", + "73ff69a6f7d22655eeb016212e942d9639a7521797e14b56647486bfcfa15bd4", + "009d0e086d6f6143374c3369b5f919644f99e08afbe8a5b50123ad9f9cdd37d9", + "19a1f176aabbcb5ee0a1b3c58426620d4ce2b0168a7c69b9a9e0aeb7e9de5789", + "35a4090364fa978db1304696e71d0b5e35d4840f5d7847062542ed9ebb7f3db7", + "f521a328fad4eb79f071beee854cdac1b0f8c7252b57e23ae391f2d46b0199f4", + "aa7127b161e820d0d75db6456226c77844eb10f5f4cab4a051f323b69419db5c", + "6d59355fbd1992a49b4b41dd2e7fcf6ed6047d4419005975d3bcda1793433559", + "08e8332d18d41a4886081ef6fda3d7734880a7587dd5e329db22e4b40716b5ed", + "f5547db72d293cee64a6bc49856899bac102696c87e15b5e850ea6bd7166f2d4", + "09069ec4805daf234cdd701691777b1106d123f964fbf4f179e8454f8ff68279", + "09db508f05a8468042eacc50effc0db419e7428bf43c440203f2ccc6a948d2e4", + "cdf3c30347d5979a02c29c9d0aeca56de0caac6719342e3705296381284adb57", + "a2cd9b66752e042fd0a66239af121777e9bb67a513e888277dd4ad357abf165d", + "edbb4c618794c816183ba13afe748a03191a31cccbd13b58716e7e3d04c7d3cf", + "b4b89862c553ca94a3e55dab9b8e043ffe40d4de9934493ef715292f4868dc7f", + "9af599e9afbe3febb984b15daed18a71a622bdce30cf71ec20ccbfad571cd1a1", + "746f648d83247650528257e029e2e78e93b6724c401ad2b69c40e5996ffc72ab", + "f16339dc0978dce4fd387b384b3b35794d4ca18ff9c7560ee9e25e8f080daad4", + "898a8ca6bb2fa85cc5e3036d0e91990c79340d09c2cec1ffff0ecd2b2464264d", + "70fd1bceedfb4b721e149ba565e268283238a36abfe2e36b28baaaa83b37f9b0", + "a5175bcbdf85dfe33b917bf65e94b1875608d4b59a98fb5fbe67bf6e17aab1ca", + "92077fafec6d417ee5cae719517853f89dcab393398918ccd69365bbdb650ecd", + "f8e44c86fed09dc0f6d88d9c5e78366a18632e121a0defc6edfaf843b6b6a0ef", + "a52314ba99db0dfd878a3472aad7fc58aa4726558fa6bffe8894392fb73ea7d4", + "5c064c7eba9eef0b867d5721267a1aef769d12f9021f662c43a16c5092803a4b", + "7155aa255a6eebab03b5a8e1aa573d8d0873f7e38ab4413ebc042e9b36b69098", + "49a613372cc8beef32b42d324321ecf277dde0c5275dd6c9a1b13f97809132f5", + "286e1189adea500c938a60d0ea1ebc7475069b0d785f92e002e1a7478eec9517", + "f065af89f4260172ea3e58cf4c29f871397edac3dff1ba2b79c969a11c0171c7", + "bc2035b1531bf30e038dbcaea3d2cd87db5a076a49243f6130e9836faa03381f", + "5f9d282dc69e6db1b5d27dc0ebb22a02c31fc4a48ffb21154fc755fbc7d0d37b", + "a711ec6c1323bd402b37c251126c8001bf32d69fc86e72e2b30ffc14601dbcd1", + "62fd4fd6e9fbff3bfda188dc0d8c3985cf75d357e7955462a6d27d45f25c2e13", + "2402378dc9c346e23f6f8f9400ffa2739bd45d17ed1de358457e5e4ad8c05bda", + "dcd5837c422b216d3ce61a77d8dc98e2735a4cadbae44ba032926639ba063358", + "adc4aebeb6f3df77e9c6dae5269bf9b0478193eca070486e53b62514e4d7bec6", + "7bbd4b8ce58bd018b88de1077ccab9d27ec41c22edf21396cbe6fefb44c973b8", + "40590a2217262639e825f8f9ef6a0b4652ea9c628e85737ebd7c5bc811578a0a", + "1a19097e64e9486c7be08bdea666c8d18d4fc8ebdfdb5f49c3c7ae22471c8c06", + "3ea90cb7ad87ac73c4245eac6333da57ec34e3a85ff0187f3260342a53270b9b", + "6c41a46a1bead526156847c43c92223f720a9941fbe0c3ba147523dca34fbbd1", + "e0143b4f728f84e710eb6b8f88f466f211c9fdcbd4e833a7680a9141b3d60c1f", + "8c51ba9fd62d8158a8daba2ffd833f6a9aa98a8e0e5c546b97d84ef505592433", + "ec9d96f0d3ec484354bb11c89a47f1a25c0ffc1123797e91d0e37f9bef360862", + "565ffb1c2a5cfefe7d0cc06b68cc8d450cefd73ab4b0a7234d6825a70160247d", + "0ce3c6d8dc04c16cf9c1d6bff98c1c9da9c679579a75c4aae0d8f9d38714ac9e", + "cd00061c5f95b992248a2e9b3afa8069776482d2bb9474735ecf580f8d0518bf", + "99bbc5fe1bfc47d3641080d08a4fbdf3631d6c7764ae1f9ddf49430718e29d8b", + "2dc5d5923ab937b10df18c10ae4218ef0e119fe3944f58d1427606af7ace4707", + "d06acad1f2e93c7fb4486783eb093929047140e0c4079de3301f9eb55f7fd301", + "2ef7babfe2c8b657fbe664c015d84aca60d9791ba95c670fd241f9839d81883f", + "8cb5210c0e92da6f0396d5cddf8498cfef26ae6ab3bbbe6fbba93b3db06fe6d8", + "8f30fb460b79ba3fbe9c53d29ebf262177361450ed658ac1c32c278c922f50f1", + "678debf285e22a431852a13af0f288b4a8c30c7d6c1b09d631c31841b7197278", + "fd53066a2b4e5ce61ccca4b0c2beffec7a1cface8150a4ea2b392f03daf7748d", + "1850fc0f0bc7353f5709d51445a71bae7c01d803232dec3627cc08f5ab7061a3", + "9cf160e227bcf3d72f85eabc52be1905c2b1497c7084b8965ead6e29c0737298", + "de9ddc18331e6d231fb76b4568050e161805df57345c38928d4ac0229606562c", + "3801cef8bdc428815f478f67858fd47821650d2b80a9137ac19094af65affcb1", + "88af56c49cffef7ffbf13b2e7aa65c6f7b55b8bbf1eff4d75a42242e965f2403", + "9c74865720c30918e4cd379e5509525ee64a6f07bfefdff9c23ed2523227f600", + "eb20db3e285c22f189aae88e1044aed08997b35675cfb5db3e60fe8a0daee218", + "e47b12d94f35e2173ac357e50c91ccaabefa5a548b6d765f1e7b1c6706992b58", + "f906e02d2d7632a16e13d09370f8c9fc51f70d08446b0f4ec41ed39379d579eb", + "9afaf87cd5454649de3575139abcbf27bf7bb5ce45a222459aca7f97bd2a7a3d", + "436451951890dccfbf25e35c79ce40b17ae3ddbf5188acfcb44d3193c778b615", + "cf1b0ed46bf4818c72a038e34458e64296e1108bf11f2992ff69f1348314c594", + "a61e6408d5ef145aabc2ef1c332b7ad87a0f2df965797cd6073668cf5d7884e6", + "1389350aedc1e42d94a1b91508d73cbd4e51ec8f4c4af9a7fe8b60b8981f18b6", + "5e16980c3b6b00ffdbd8f4686618f54c3407f0d98aff8f959c1633069ed876ec", + "c6d7c81f3ba862671c83e854bd923606ab1b9ac7d6bed036c65474149c0810e8", + "ffcc164dd59261920faa1c7fc44ed2b5db7b6b89a8143a2ef0f680852a5b240f", + "e0a249c6e0a396b4916e79756125f94b864185996523c0b1b51680f7755be02a", + "1577cdd3aa44f160981ed3d4ae28af1ed545812fa12540df54607c72428a604c", + "916d7fdafc545bed823abe3bfe26ebcff5ed0d622e43650bf0079d077c446ecb", + "bdde40c8a9a61386b5e7571dd4fc6ff851fff1f4033a190bafd2748c68c3c611", + "6913edefe5baf9a9db2076106db9955bba7c2e4242e447a52906f3fbf117bdd0", + "85f1af48be82737689f4bd25dffb97381b0a4710590cd8f06628a2d9fb1fc309", + "5b7f65df1601eb6dd6ffc7d0faa8ea5f1c47c24334a9d6c6cbdf4846e00a6e30", + "9f2e1afea652da867d9e1e0f5ba66a7c48333c66014377ad3f66c63fbf819ae7", + "ac97ab3d8b7416c05f18e6eadda033d4e61a8d50606d35c91398d15f0a577baf", + "7a7c48996ac0ba2a382c62ae6c94dcb66ea8a378675696a1736f3d7f8b0b6f7d", + "09ca460f6a39761a239cd818fd41f33dda4665a928853417cdccc95414f70a7a", + "763a12dbb2dccafa00cfacb50df47fd1d17d41710c7eb34926029986c775a31a", + "917a252e7fd689e5b9011e38148008df17e2acbd4585dc50368c5984575a03c0", + "a586d90d3d09d56f197bc54a2a55efbe000e38647987da1d3d8e19b4d6b37f0a", + "25f8cadea0258825ad650fe36e9206f7a56cf514f3be75a8e2c407d3ce7f1cac", + "f14faf64ace5d41c7ceca119a9fa9cfede18f3eab6db3739f3f00c4663bf64a1", + "1137d2aafcfd4da37463181dcc7f230248b80191db969c6239ed1f7edb9bdf19", + "e50b3e70350a0666b30c5ae73f07a2f628c02203987f7636d66227eee220a70a", + "4dabe7863355428725541564d1a2e61530d55f6f3bf2e6d1317f1517a307c381", + "3152d0fd6d79410dd9b2a78ec365ec0cd0fd566916321333d9b707b188198977", + "e59576f990dc22630bc4767da83318efa3cff50a8b0e4722175881cc913d9dae", + "cef21ef7864f95ab095792baccebc03edf5a38e6da5cac508a001c20af5a4f3b", + "a226404590f05c8dcbfa1c0dda30b1e92f941dc50d208384a9272f8c22268957", + "8a109b7cae99052aee79d7e1ff39223e001e7d5e4f845aa3c00555b8a1096433", + "b9c919ca8249d843b337afa829286ffed376e79c5ec5a5e3f3885027382c719f", + "1fd37a262fdcc0d17a1c6eaaca2b0d91d08a907c582f5f932e6694a93ae99356", + "4ee5956e29bc4a3bca1c6b3be1e6e1ee24a559b1310c26da62535fc4f69ae667", + "aa30a037f0eb9f5c028f86a579c299ad2c98f5962b56a737388d6959d811b4db", + "0ed1aa6815890698b59e4d6bf196294fb2cb0c805992c7cac04d751cfe1dc5e3", + "580330efce6a85c889f8b9a23c51c1ccdbf9e78b45b0d54e11ca5868bd6466df", + "bcbf54216e46d0d42d362613fc084e5ea885ecbf5d0b00c83ca5eaeecd8c04e2", + "4a919381dc56324bca293b704b815d9413f4545ccefd0e5cabdb7196be0d8214", + "dffe8427f8411d32584d5f7ea9355895e47a27b894f914fef382c87d1b3ddc7c", + "06438552c783477d78cf4350f2099efd9aa82c2289c6072b9ee58405894dbd33", + "c09bdb74774218fd79a01ab2436804f6336e8ada0f5a0594f1615c1b2f8d32ca", + "ec47626828f3cc9e43fe3fa9d97382908fe40e8b0afc893a9b53d5281f105fc9", + "6c8f1b10f211ff4f51a92542055266338702663fa3ea411bc6eb52d26a744855", + "7a75477e2e4836dc8e9a6e688afbe1cff1ab43299cd334f0def3e80db85ac16d", + "b652f3347db02f63c2eaf8ee7ab8c90a93739c7809a982fb5fc8d5038ef1ed3a", + "a054b5daa70b7eebbb4a798e10325d1b76da68f48260f3782af70dcfcf21add5", + "b2d07ef2c497ac2171931f2d4cf60ebf8bdee7f2c2ef28952324f10e943c69fc", + "21287993f6e14aa05cb2df96fdb81911685247373b1650b54e883d712fccbc6a", + "cb138d2a9c5fec4cb2449faaa7a1abbb5ade51e1f87e22e1ec044ae93a0bc5c4", + "5a832ba233f56546af982a9bf5fff6f6b428039d69174d89da9ea336563a788f", + "a56b76cc6210a85c6972ec80c7a413cdcee1a287f0b7a6acc311b5f3d49118b7", + "568d509f5bfd08eb1ca144d4ce077f662440a14a4197a1bb2a962984f95fd88b", + "e6dd9b84c95f9762a9ca837b6b938ae1f8ff08bbf0b7415e575ba91322c4d587", + "6408a9708a4198e8b74baa0877f4ce836a24073fa47595ed9902d0d4a6cd977b", + "2802cbbd9a27454f3ccaaac888fb91b15936d9da2e82c96fe934bca88769c61f", + "cbd9d7edf43203a838d1b6421fc1f31bf0c2d9b7e5dc0ee3cc757ccfcb352b29", + "128b8728ab355283ad14ef192e1d8dcbef1ef9197ac2df217c33097d3e07394c", + "ba9ec776995cf4b5eac7af88115bdf7d20a4709b2619bc2cb0dfe7bd55ff739d", + "8860fe9ede5d592864d700790cb72ee32bb80a6dca6fd5a35ffc7363bc1d06bd", + "c1cf1079d93629a3766089c871717dbf42813a8db90a04184479d1786f4481c8", + "2b8f96012e0f7e0703e8489199eec9077748bc0e92760244064a5da7e00eb03f", + "0b3c873f5861782e354bcc5d2b8182cde986e4808a66f80d8f42311d49cf3b98", + "f903530648472c4b4de3ebdf4f01b59daf7674e0602c3f822aa68b283a2ef4c2", + "0b5d6cd8b516c855020819de5ef96bcc8f9386c563ac9f080ed7b31c281277fe", + "558e2164fc1e2f8031c602fbd4d15132b6ce653dc2390cbe5108ffebbd8075e0", + "569b4a9497c06785f469eeefa4104ed64b877d988d93b0063ef514ebdf0bd9a8", + "25c46450fa5d6de20d6b0b73d9da75c4974896e1b4b8eda6d53b9e7efa09fd0c", + "cb8c6c3804f08dfc1cc1dcfe365f8241c2f9eca3ccdaef2452a841b621e7a3b0", + "1ca74bc1409708f94f91f1169fb40cdbb34c3cf2a1b92dfd2029163d64e0983b", + "3299cff8c9a8c9890af908d23beddb7d725e805d91483299f1a334fcf9c2be40", + "2066acd32b822da2e53670ef3e34dd54e258390e9a545fd51592ee7eccc4887a", + "27acc98f5213e05b5641d53d4042290b08b2de8cdb8ffa4c49b13f48a769e5ca", + "9b6d62f5a1646b95ea364dda6420e9f229318971b8ace8ccfbd3192ad8623f9e", + "342c81ebd9a0eb6a08fdc3ee18bc2ac6a68af95160ea3b0b29bc017131e74e25", + "5523cb6c360b6687883eb28979223268ad4471a18406f8f894fe53a44a5a1f68", + "c25848657a5070c5a67400f8203a90f0e844e846c02285b4b10637b3f49626b7", + "e30131111cb3aa9c073963eb19ff8c81048bf38ad73b021b89bea20c67828f79", + "07db6f3aa67d02abe1fd8d22538a32ccc2666449c02a90e1cf1c35f3af1892dd", + "6e97b651b335938aa2b62c31b6ea426c55fa16cc687d79ccb2312ad8d9bc32db", + "693cc7782c4cc8ecb09d776f10a80008199c2315ffe1b50c5fe86c39218c5b33", + "955e8a893cd41a0b0be93214a46a9d57d4ae66daf55600cf3ba1d77e73c8b968", + "a0edecd6aae7b3bc1acdf05011d49668b441cc088aef2a3087d85fe761e72150", + "e3e634f71fcee34f2dc5dc2efa50eff04a0dcf5a9f9c4c852165e443103949f1", + "17f63a66ae97ea7833075600b6bbfd1ddb340eef0e66e5130a28645f912dade7", + "e75ac9671d29c2d557137a4f435ed0262f8c169ac98c8a8b806f849943feeea3", + "f3517b538c1068f19bfd4b9282a69a36250fa8790bfba5c0b07b111db3f61847", + "ab2b45b73d70414782a9bb64f9637a118752498b408413deb79f2b12fdb04d86", + "4d863beb9fa4e173240ffc2ebce042209e773cac9593f4d956c9102dc0614b66", + "6495c59a0431e44ef48c3a3fe0392f83b31f29277fd546e330d1efcb71ca7f97", + "68d75f3386a382e5b266b617125ffccf7c7377800923ce1a3ef0973ef5840bba", + "e221d29b6da11d400ce7aebfb8ede89c36584b0509aed420dbea7a5993bacfca", + "5cc53d7c1779731cbbca8c291b784ac585aa15376e1b31093b9736ec90f05291", + "141fbd90c0da616a0e406312adc74d9acca8346f93bbbd82ad43efebadbd8856", + "d795007d263c12d4feecfabb51ac9d829f13030dd3de625776158b414458236d", + "a7d96407b7a47f7fca6f2b311013b3580158e84b60cd42c3eb3a21e7046bbe04", + "961416ad25e5b82a72704b671212e54e7e9c634ce6b3ff81d7694fa923832c27", + "6d38ebf32c7b5ff10f8c31372ee9810af1f3f189c03e2769c3633bc1466cacbc", + "fcd8b6e32983a92dfb53f6bb9e1accb1c03dfda48174086995c167017b9b3720", + "26813ef427ff04b36a55bb043e3ac8c9f0d298040b484371ac31d0bd5330ceff", + "38088b8dbeca8c2969f7801f8c37c616aec5626bd5121c9ef32aa528c7baecf3", + "e98207f7d7d6a1c7da419fb5f7b360b6e494fefe447c0bf3c940c94991936560", + "d8c23a15133ebe8c12199986b4274b9c85e08f5aea83f368ffc6b54e2092fa8d", + "5cae801d3c366060e7839de93801ffe2eb26b9d5e22df78f6bb581920098d878", + "4dace2c0698042deda558a2d06bca6b9c05e7bcd438167207dde22a532fd05b3", + "c6de1e4969f9f2bb5251ba080947ebab5eecf28890a249f9b4cb39115003083a", + "4d63b24dc4542d4eb0620ac82627ba9fd1de6cbd2ee0cb28e38999f9d9387695", + "fee7e55014fe3ec92598e00cae8b46ebf0eccabe1fb106175c97921963ade208", + "24a73a6c2bf698ef773bbd21b0c9163a217604034cdc89eb6d6e3397f2b86ce9", + "b09665d8fc877b3bc88653a86b039032ceb386840718b8192651fa511dc3135c", + "bc4174db07de34ce2bc62634e857d685b713ae264a076875c5d999e61ac58a95", + "fd6c91620edbc319a3dab6e81c465e98c4b7962cae79dbe69c0fc08bc703bf02", + "4e8c939a6e99ab48fef60dab51142c3d5b338dccca72227f0bf16ae22a085a13", + "cba8fb7c33a69b5a72be72937e2a9de399bfa47e9d754d0a1b780e9e96ce4d89", + "2af92039be86c8536954ba105fdda1b0c928687235a51aac5bd7043c8dac84c1", + "ae37c8dd2dcbba75f801c98c31dd03175f1e397d2a9efb9276fd11a5ede10c28", + "ee16a294031b927ddf1a8f49d27f79aa95a144d4747b559faf02fcc64ca3fede", + "e3602f468d41e6917690be6f5a62a6a547b5287a9a6ce0d21cf76a0b60d0d679", + "911d39abdd90a61dd7a597d31c4d5b75d08a191ac1e4260f7d8664e94300d2b2", + "e1728255ce3b3f7e812087f207a9e040a511fde2919e73fa9afbaee9a39157ae", + "5ba3e150c0a0fbb545360d9730526e14d1eebf31c21215feee300cda8fb5d7b8", + "4312797b45d7fa21bcf31b418a4882e0155bf779c5a1f1a8edb171f67c15e109", + "ea8ba97b371bff9b818981a5fce3df08dd9a5efa3964b9efab3548c1611b02d1", + "2987599ab448c14c55208839e7a56c29a41a032616ace1603d6d3db7e9f1763f", + "844d465f5971e0615fd07a1cf0fa15a916622e525d5270ae6580dcfa18bd7593", + "40e285dbea11d71eccbb9d07b0269d470e32120da6b7924435f5f6e85b1aa94a", + "91be8d872a7accd018175dad80eaba52d3ce7237683f35bb89c812f340c0b5a2", + "a90245f2126b36cf93075a5bf34b9bee42d53b410170ac26aa6ec134cfc2b40d", + "8ed07e947c3a3cef9dea082ef20871329d8797c80cb2ceb5054fed01a7e3f648", + "d9969b445d87ffca7c27bb82280f89ccf03ad02efd88f198e4d64a23bd021732", + "eb145d5cba82511380b7db9daf442d067fe8f1db254c91a86d266a88290a9bdc", + "648d96377343a9aa62ed4ce76b90f7f063a3e31c5ed3e4373f858b79029b9602", + "5f4f6db279579712ebfd8facc27bc8bfa48a39211393719f5ab4a0ae4ad49d16", + "1e26018f9f7ef1c5d4a96ad3db2e7107fd07dd49ebe5ffeec9be4f5e6973dabb", + "6a4447b0be4019d9f5219c1bd3faee2e0860488cf8b0aba3e5b87a0b6ad09245", + "339652b47bd127b3f6d709ed5a33b160e41394308212909364278533e2d9a0e6", + "3a85b1dec220be4acacc314fced966bc13274a242dd73d38e829d43592af153a", + "c9980abd5415ab386fad2670d798745c72bd98a52e3cd84dcc48f18a28f36a38", + "322882ec19b084743693b167dbe883c67f7cf2efb0c3617cad793131c21d02b1", + "85030b76c8329bd4640b7e38fef6368fd1b4ffbf1661d61934ee9a743805ff47", + "e660cfe78e350b75d0f5df5d2e23bfe66f2d03dcda98fa3b8ef81963db593576", + "d220e6d68131fca4dead9a9ad5d8b1163ff87692f5f4577ffce024fa00e938fc", + "bd6658504c071f7adfe09832fc18674d7c1ab5dc11706a1f2f1be58f8f2be3b7", + "ee1c126053db6eb16f4cdd5b4dba48c502bb74b0a6e81760adfa18e4d9e00f6d", + "29e7ac50a933359e0bfffbbff66b03b4d55c317d6840a155dbba12eb47f55ae3", + "7e61edb50edfc34f7e0bbf297806c3b7fb0faaa507e7debade49967af9376148", + "c405aac080405d9fec696e6dd0cfed9fb618d7bb1f95e5acf2f72219395d4e3c", + "d226cdaed7b86b531c0a53e451a0e2461ecfcfae77c1645457edd4a05a7280a4", + "bfd7b3f13bee15eecb44b70bd9c2fa745b6f2a6ddfb77cfe51a1838935b84164", + "b8ddb61e711dab0fee7ef55143b14a58111f403452b405a9d888c3608d1908df", + "ff11ecdb26e8ac6546f6ada97ae1c3b1e1e2e1aa72d3cb42839ffa2db745e171", + "1fe46b0a8b242560894434f264157f417cf9209ba109cb43e340d66faebd2bec", + "89ca23187b58cbe82923748f4c6c1245cd037d2de780e0d98ffe472b1aa7e22d", + "2c36185e1bb3a7775ac04406b7c4c427c94bbcda6d500cf97fada34d3ea52509", + "657836c401d6602da040243d35c1ad2bfd9d4d579f07fe68a514d2ecc4ea85a9", + "c92f54835701781ed19a56522f8ffa76ae57110483c82d74578dd143a584e29d", + "61670c92e541cdfe364312b6ed579dd74988aefbdd1e67e383d7c12f727a6e93", + "4abfaf22a2915fed67da1b80475763667adebfeb09e5d0f5e59eed3bf58a9eb7", + "6147a7300ab50ff93c0662f6d721b0defeb518cc6465b0661d4ef8bee97ea6dc", + "714af7ce2c9e965f9d994f5332b02fdc206a7a46afe68d4ba94156fc96b70fb8", + "1a3015eef93f8979ec9898805f4ff39e77eedaa8eaf2e9205ee944ae3fb80406", + "47050ad8a9259905ca257d01b0c761e7e5a9b8f49f2bc7aed92cf950669e9cdf", + "c88f9b2f23e970288680e1b70652699231a3afd8d96cb09589b25e160118bbc9", + "50793784dfea1f6df5710631a9c07f8f1254a4c57007b59d1a17b1c3ea851e0f", + "3d335a13945747938d1cc4d205f97e7e199ab74d0e347b19e4b5436c38d13b0a", + "813322b58fa47eb5c26f9b582f1c86bc637695d986951e7a840471df9b02213e", + "191735622ccae63faeb9ab9bb084c1b0d1eff8414f79c85962cc4fa19ccd9828", + "bb92f4f1a3da56d6c663f0bb183ea45552e67fcf6509f905231ececc5545a706", + "84476be3c2cc2e42acd1b568363696fdd09025e6d9a8f214b99eb248f378eef9", + "cde568ea05f290098176e6b1355a89349ad063a672be6eaf1f0855d4cb7beca9", + "7f5d627cb1ae4de1779223915ad9a45a0c4c343cbe5694e70d57a427c70721d1", + "e0cbd21b753be13accab01b6b74ebc31a5ea1ad042e36ae1df0be15345641a32", + "7488eba8e6c03ef3c40763477055055b6cfdbc2e0e0513521c6bb8569927d202", + "829c35e81c37839295cb42b83dbf8ecdc97a88c0a633fc1557904cd3e809cb73", + "057f541c4019deb92f9ab1aeafcdfd959e54b055e31e7f86128cca6a62b29fcb", + "00c676a4e3a2669e1259c8c3b90addf1856677ee79344c116010f62c8bfff0e7", + "b5f37ff3467686a2b0ec9bb18c40b38ef13f11e4f44a48bafd7d10690994b41d", + "7469a0b3fc2c21199c032f382a4d77530e687b607c4f5658111ac2a0f54a5aaf", + "0499b0c4de9c91b2dbda8c5cc1c2538fafbdf827f16e90ec19f2828509104a7c", + "455526ba097358aa458bf7452d497caeeafdcaf9c319acd474541911898719b7", + "6f88d5c5062b1e7cbd26939c7b95f7ed7cc6e342ebc90221ba73739b4af100b1", + "6785af0726b5a725ea566e9bf05326063a5af673321f1559dfe247b5e08f0d6c", + "19bb6298ab8395033d4728124655db4e52929f6a08285af9010e48940b1b13e7", + "9556e997f4873c5025a10bd175d7303c1867753c65e069996924b842c43a8702", + "bcd15811f478cba628571613a61f95a2a2f4f21202a5839c0dba45fd50b6358b", + "723e639c5dcde827abe16fd5897a4f961b91e7c6e07d3cbe8c12626cd973c416", + "9ec7a27f07754e257d234112b55688605549cb99dbaabfab84b45c5e53ba718b", + "5e55356bf76162e6fa601cd22d927a75b44ce66195322d0a7873418d67a9171c", + "f1a8ba1cb84755c880341bf0e978d7201b846b3ffac84c776ff73318d7d835b8", + "5fdb8f5eb8a679b6ddc2dad772c316b4db365031a7aefefe0cb39d182230265d", + "e0ca21ba8ba29f18a2a9f0eb2029f2d88205cfb6796ada580054b22c553757e3", + "6958404dc59a74baec4421c720bb6d70383e82aef9f1869f1827496582601ca8", + "9abadc9e68aeea80678c0395e1e6adb159fc2bcd84d5da215b015cf240129d9a", + "346f91c834b5591298e0dea532e02df225c690714335022c2bd5a76f547f9f71", + "7368d4d86fae8099fe9512618ebab92b9560954f6765f057ca75a612e4e8faf4", + "36c7cdaae0535a354851d5d64521e6e919448d6c9778f700fca0a4a5bab4b725", + "a51ef6da16ea0196051a1c9cd6aaecf56d72df77f5ec418357adab5f2ab6cd4f", + "f5dd9d96fab49a3c02d5abc913bb384ada01b7687e86a3569f305144958c0ec8", + "1c4e24252ae637d35e44a5520a04552e1927a5e1a8186a77bb41edcbeeaa7dbc", + "8f671c59a6de5432625990ff85af439634c0f150487122afd0166fc570a1a7e0", + "bdfff62a5cea3b4f852bf019604cfb5ec75669370191d6353e763abf9002c7e1", + "3dcc463983ed270730607d029ffc6d480043f0aca2c520733db992705237538d", + "000bec029f25124ac9667c005542a23178b392c48f6dcf45ead51d7753820126", + "0b00b497a3c4f8f47740cb0b03653fa8dcca1f6f3aa6916e2776c23caa6812c1", + "3b285683dcbeaf2fd7c0501566103ac68df9af527c73ae7877404ae3ccdfd04d", + "7fd1fa3da220414d5a369c6b112ed573605c1b5bbb84c42bde376741fc5d9687", + "920a61e697c5f0be71b3654fc9e8aace889343e4f5bd1cf91434e746ae199766", + "82c6ee7ec9a3c568861927075fede55e268c31b1e92e1c8699803a3c542d73c7", + "02fe963a74dcbb59dfd64cd52e33d9243e9edaf2cb9440e33c8f2f6d65081c36", + "229cb295196e1eabebced858e110ea9a7e7a1f695d694bc9c1e03d93c6c2b5bd", + "acb3c97a6cbe52056d15b9220f9d62a64c6a65bc54c68ae242d21aa6ad1acbea", + "86b0c50b22f3ce3af95ff6524d993a1078a3ce92090ebbc98f3ca53eef1fe123", + "f65396b3e256bb93d33de68866c5428d77d64e651b63691f9ff954ba7cd6f111", + "f3b7e3683f7c5ed4d26102065f46179e0462723cfb2305d508a090ac9384bdb9", + "c926d58a05a4eb7ac5ff773f233a614127d6bf4b12392d86a8dbbce4b86cd323", + "0cc09119a1b8a70067d15bd2ff810aa6837b0085001356e85c079e3092331508", + "fb1b8be3bdd364d64ccc62f85e22e0e29369fa51dd9044b57e1fea7134be711c", + "217ad5726c61e4edca2d437cd382c27ca9f6d69efcb890bafb6b6643c880f852", + "295ad5b79610a64af253268bbdeeedff91b2394d70907b6d68d53d3574b59da3", + "6f79912b4e7dd6f7b62396675c1d4a68371c81d272c8d97442c0c3ef9cd81ad1", + "f33652d37859ca6f0f5f24de7daf6071267afbae8f66f42cc2cb903ddeec77cf", + "39b69aa62274142c09bd720f7cbfba15fadd6be278f1f2818ea0bbea01a7884a", + "f9c90e10109ed682c94077779b6ae779696a893bc1e462b4cda4b5c011d027e8", + "b4b7018b2b15696288291bc29ba8c8f15229e701a677e839cc2632200e787131", + "e5d889d24eae4bb873ffb703a8fb0493b7fc86639a0af00bfb83abded33bcfb6", + "f1d40adbbe7badd0ea5c2aeee337452c0b6ff0bd62dd3db89e01ad456f0d48f0", + "25f8d54c2de66d8599714e3c2c08ba6e6d7fc105e0a03b0b604d8bd1394f288f", + "e489efc97e8613968aed61dc2df1e78fe7caf02a8ef41e2ebc16a7b573079ae6", + "71367723118f33d37495a0c3b72727b19a011e8c91491ed57872739e9abb6139", + "6760172c7e2831aa2bde4887948a37d1e92929c0244a4c56232ee8b27753479b", + "418c085d42fa7f80f21d48863d701f4aba8586ff37fb9194ddc34a5d59be5c67", + "71a4cf43a5bacf6e38373df52888644996cc3f4c06801354cf478c8d310b2107", + "dd978e916b6f99c5040d8ce741f1099a9f5f69353d446eae9b91156a271735a0", + "059b44e36b1ab8e23bb72ba9c1a966834b7d4d79b9dacf81d83839f03d83687e", + "23b2e6ceff4cf8e40f1919d9e052cd7f1c85c32cbb98c34a0ffa384be8860c45", + "d4f1fdafb59c32d4a35f21bf1fc3c6aee48c0f1e0690f09344612f34fd41f31d", + "acfabae890578fbe30ab8ce52c92f381f7bf0f16897a4bfb9244b1ac476b85ce", + "50b72f042176ce04538f3adbe379a7b3e84751b144bde9170a9a2104b093c852", + "850e4834ccc4f0aeabe80156b44dd4bb9fbacccac331b1278e24d133b3922c7a", + "cee6e10672e0d89a82a9ec97f1cab546f59f948cc844fcb20d3bc8eb1714e862", + "d81c8b3fa6d172ece03f3e67b80ddf2f5e3241f7afaccf9f1492e734efc12fe7", + "32a7693eedeff40e93eb1096916d6ffd0b9a24995a2e84d1cef02d12130bf5bb", + "514c0906e31dcd065197440b9428ed0ae24fbb85f96e880b385a1dd2a618241a", + "f4651df27a1ed294dce6c6104e765949e77846126e26088d27995ad557b2edbd", + "3854ae849d1f7abbce7827f533efff4084a593cbf264bab749bd4f3e9874dd46", + "b4cca5a74319764fff23098fe505564d6db29cbe1dd5d63df21388941b55598e", + "b477dbb69f03aa86e955c0e93692d29a05e0dbcf9b4a7f104ad8003509bdd243", + "f4e3442cc1d980bde2fc1a9bcbba1a211e0f1cf0cd9e2e45c334e2302b9586d8", + "00b407fcb8333e7c565b77b845f71d0c378a51383bf103cbd10724bf1cb49822", + "724e74fff4824331fe06a6cd4179c2babee69cdbb11f0df6cf6ae7a1ea717bed", + "25f3789fde8fc18a7efaf4b90e6c6ee2ed31a8ddaa28c83900b92d48cc543c04", + "f47487ece4a31a55c010faaa88c66f9f18eb64de4909ffb0989293890f47ad91", + "a72ecc09479921a3ebd4425b9dae640f59da929ae48517290e9d6c0d851544f4", + "189f8c5b2612b177067934faf35e2eb0dfb1ce50f8720b52b96bd087ef092d56", + "8d242d331ed2238af25e7a6f63b6e4ab9bf88995d9f3fb29750bfab45efed816", + "0c93b9d4f08341f1cd9b589139b0950245f6387460c2567ddde71c35d2213144", + "8d0c2ac11a0f2d7b36ee1bebce411c763da84520ba1a01979e2e97aee61d075a", + "cd92ec926b2b6c5bf52fb360c5fade196421fd59d06f0599f46350bd31946153", + "22086b05b32eaf0a3933c89d29f264a36b36f56ec84ed270f973e11574d355bc", + "e17cfa7b47d20c387313b734a6e6014b87b497d4dd242fadacd230411194c8e0", + "c0492fab147e6898bf833755ad1d76c50206d15102ba81cd5e9876ec5355a39c", + "67c6e797f1f0ae43e29334663a28f213fe5051fde78e1e9ed5e732b93613fa5c", + "0515e4fe5184ad15bfae6d1ba53a257968b1d851a4d509bcd99a5d957b07824b", + "b5983212e99f7ee88010fd3460d6c637c345d663d26f6a75be7b2c130e6b3734", + "41c7bb5467efbe664b8a0f07e49ee1ac62186ee9e9227a018192a50dc4ef9859", + "6af8ee9f9da4cc9b432475c174ba0ee19535c0e2fa3a32dfb09313809199dd95", + "bae2807b9a754887be0c987a0023bab5350b1bdedf1b15fd9d7206ad2f5e1679", + "dcafc512570eb7edc8d7f9b183a7f9f187fa836511bacbd924af2944e145abe1", + "13afeae5982fd2f0ce1484baafd76b2ca6e3c0976f06591b91f1090ae3fef879", + "c08c9027584dd4ee3e1f4459c9242ece3b648025482fe27bf64b45063e78b8eb", + "fff9ac7767a6c29646dc6ba81dfe7c5f38170d4a87f38717588e8708873f0380", + "bbb2e0d2fd407d5030f73dfe7903dfaa3337c9b264546ce3ee66da2d3862f837", + "735058bf0ffcc56453675fa9f521ebd4bbe1297bfcad37cdf5de44020599fa9c", + "ca5d94d311adaa29ba937ca392c0f34ee5a54008697ca7bb6d607ce7b0913336", + "c2d946cd37d41d513528d352c81b77b227e63cdb74c7cde3f8045135a0a514f2", + "c9d61ee759da8723987828a30be83a7e64c6200b9fadf98f14ac767446f3df39", + "84c7282df934be1f6fa7cf50049da8294bea2db0903cf528c5faccc6381d7cdf", + "264e813082b712781fd3749dbeb994e99292e2908818401184625b5a1d3bda0f", + "9a53c288ffa62508e8ab9fbc6b14a462d3a8218da324cfdced23c464bb07fd34", + "0b23353fd811dc89200cf839b3344c31b8bdf1c913410e721e24bf66aaa736a8", + "b377b7dcf5f0ba6fced13196dd56717b926276bab9e70680d909bafc107ab9bd", + "782810c57ff8e530e52101509e49594ecfa2ed44cf3b0cae798f62fef140ae16", + "a92abc285ba6971633c87b8f02cfb198697a7bdc174ff04746e954a7cbb5f852", + "69c5aa483a4d155cd16ba45b43e08401dfe8d05ba3d3195556a733e54e761685", + "5343cad0781415c7e1ef731f779da4df5c72599ce938b2b6d17f52f3a3ce7e08", + "a4c2acce5f3e5b46d64166ba2139a7e0f7a49b0ac5d3ade97152128bc8663bf7", + "dcdade4967a3cd833c7172e7eba6f1b4b1be97381797cbe5d8459b32a3258fd5", + "2b4cb90f228ff258a6a0c4d66172a2e2c650a431efebe8789af0a3ef88f31d4b", + "164bc3a86435b66ebdced6367b2a71bc81d16e4c244240a500703ed26c073710", + "b3028e5fc26695f60c1c51657cfe6863cd4743adbc0ec841b8a207f7e84eef40", + "3f82e6449fb7a313df4546a7b3965c12e32c5b31a6100b33e399c55ed88378f9", + "b9387373906a75be568a9dbf75c47c18df427ea72eb259b8420663a097321f47", + "a529c44ead81f6829b6e922eff24ffdb2827614336631607720451bf6dd7d979", + "0d7b661449677d097af2cebf2752a3d4c3274d4bfd99726682283ad6e3c949f0", + "810822e237c5164dd8aa4abd4fba46e5e50dd4f644b1cd80bcb27b637ca1315b", + "1bb210a3467df8d545c66ea01fbe3dba115168e097ff8183569e3041a788376e", + "67edf1713683f11bed85730697924874d9377a405375e29ba7ffdea6c881291f", + "0a5423f7d9ad9d04de4a5145da218ef1281edf2878b3f1c9bc347e3c406e5678", + "f10ff4f0275d36429468a2e3503a21d47eb2e0a22694bffad712c9cfafa0a9f2", + "73ebe0a535a692c20d28e4d28513896cf9c76667a8b5378f94fc7d44267c4189", + "ffd43220c9585f8712011e0650b590b0768ad2e09e1bc7d2b38a6eabc1c80cb8", + "9975849e5618590de783b421072323096688eee3c6490bba34d3b5de83db8bd9", + "130ae4e83d5d449f4312adf0af03590655d2ec294144802c9f5bccac50fe4f55", + "5d32edfc969027f10b85945754d97bcda963ce2ba713bc8f8fc87d7548fd72bc", + "34266a4404473bc1807a756bfd412dd92ebf282d2c22026256554e102a559218", + "5ccfd6849e316e184fc416782557b9164ced491b9ee29b8a1619a818a87d6d6a", + "e449abdad9fb4a4d370cc5fabb7374ea1182915bd0d8fc0468b8755459f5ed07", + "c7339bc2d2265dc9d5a8c0abecbb1f845b0f51b0af42bb6bb317aed25775c9a1", + "937906b94cb585ad45087e249e65c3fb1d4e87d2d8a53ec81efb60eb25e823b0", + "d4670fee6c2af0e7ad7bb6305ba2a09d1900bbe322a89ff6207ad7501c680641", + "a81a54a032edcc73aa780932b10099c954615bc1d33a4b3ff0c2e5fd032424fe", + "6e43bfaad19abb4b038e1840db4ff4611ac2cd93f8ac45b12885e8fa3c4d3b0c", + "ae9596437938a0d3eff707b73b6db05374dc92fb5b182ca536e9f86dbe6c0703", + "a01f51ad9c3898d8959bebe0b25daeea1751a23521d7ced242bbe2fa89fd3160", + "6446868528746fa7b61ff04925f664b9f8a39cf3e1fdeb8c1c27e5935f5ae5dc", + "4c6075ffcd89c216a4dbf9c0f2c1489f5dfa0e5705febf88201e76c049b27ed4", + "0552cf81edbd99b209bdac1dce719dd070896b06451dac84507d38b1e9f2d87b", + "bcf405a2e2f291e1e7e4ce3b920d652f44060879cb09ea3bf8031121a96f5fb0", + "59df51ed5a04f3686b8ab2cc28eafb6e0259ec680dd0d76d46d1cc4a2e6f78c3", + "4d28ddf86bef38599421446e9f564f14409d55674a0032e9378d8cf9b74bdcd4", + "ca980d2ed6c1600ac4868f287fd9a5f2bd235dd3e225c86979e1ecae0e83f45f", + "e563d80d7dcce656804e4fead9fd5cee8f77500f7e7ade4b69307e0d4d6fd03a", + "19bcb3e4d8e1aa93f1a4ebb71ec4dcd875c0f587a3f8d465100fcea749a58638", + "92d0cbc62bad14d5c7741804cb11ebb0b2d2cc500e2f3f79c5e3374931af98ce", + "0889802f46d74c3e2da61911fc64ee594e2af324597519ebf28e0d87fa0f923e", + "ad73e61ad34e33319d307d318e35d0f12479a04700faaa1fb28a6da8f7bcf823", + "5c797684e04543e817e21903f40fad9a7ffc6dbdf3d29fb9e5f75447895b08bc", + "a5bc03af0a25934e5482e465c5fc092b4ea23ccd0057a22ac12585ef78ccdb28", + "0310109ca48f842802dc44f0b3148f3f9f85156f7479a68a4d83975d6821449f", + "39ac7e34ed19650f4248f6904ebd9bad9dc4217e44a9addbc8edf066b236229c", + "d4f56d1386a69980f17096fc5662765156ae689ed39b1ec897148fea8265051c", + "cc7718238b92c78af16412cbf2f95e6a201fde48009f96b4014c504d2ec4c45f", + "238d0da7641abfd0cb5e5e3a7645e1eb36c39909f68b500c22a78154013809bb", + "9e5940065f27fc7c3c649286a7d0a68e8f9e386e0e763130e59b00e796b3aa74", + "f3d568aa05d686343a63bb9de6748245df465bcf33dcab5a1da869a1eeae8db4", + "fab6f82a3ac13518c382d49cf47d75f38296267b54d5d293e02429fadd82dfa5", + "3580182f441108d5ba68492545345f2e8c25742bfd8cb5ad9538cb35e2f57332", + "670d1a680a3da7557da8ab213140447972c0a1599c8ff3a9ac8fef1288c7f90c", + "a643a737cd6aac3a50c1a5de181cfb479aedfb54cbf050ee265656aa2aadbeb2", + "aba00291d8f5fb0b1e91e9ccc52187021aa3c80c3eeb4ccaa4c18ed551e17d39", + "2fe76d73667aa0df278a0d2aa9677fb5682cdd4b72e53a9e9771e2cce79b5262", + "7a4258742a18b23d502ebb48ae1b68ff05b125f639e1087bb2f9f0c2a7cffeb6", + "f5c07bb973e98714cb040ab1f36599170c5dfaeb9fb0e195ae83e3211e0152e8", + "63d050af597c3ed0079ff9cf927f4d162141ed2ff0cf3dd7c461b0a38ba87d50", + "3a46fbe62fbe5f37bd6da57820799e525b994b37dbc201dcb07e88fc285bb77f", + "f7c5c4143cb2c6edef3130274d98f7e8e7e3795624c8888aa1e5f3baeead3c56", + "cbc24f2a5b749ab7ea82eed2c1456318c0d4cf3825d32ca473c1379e09b214fd", + "9a219eeaad2535de13c96614375461b672976724ec6c161d766191a30aa78af8", + "3e00f7e93106f798028c42d6bcb3e32d1727e167ce84269b10f763a625c36b35", + "b9d92de6b6320d11bbaf7c26a8b7940825aaccfad0578826fad110a9b2c241b6", + "49cd5f38ea7b401ecd8ec3fc3568b94323dcf91125428987e2e52e26bad64469", + "e4a7eb7402ba06243f0631a019928b9efa557daa606ad398f0141559fbc66b51", + "8a3730b84535683ba36eea172f35f9ebee9ad190b054aac6d3736c8ac3383fdc", + "8d7acd7944eb03575f5bfc6d79f70603fedf198e6bfba8a7344c211dc60aa65d", + "2518dc6753b3032ed072ccef09fa2e90f70b9d39b4dfc7ba723ed846a6040bd2", + "07b380c16b475179efc4c9f22c79cd15ade85d70cfe62f2f8a3767868d16e93a", + "2174af835f405febf67c3abf1e3ae891552ca1d182ed45d9886a6d3105de7491", + "7d054f60a38020f5ca200d7c153762f6210f64d0a2afd5e75e4ba7cd838e9eb8", + "b7affe4499a8d9b5b724e46f06d49ef7d48f6fc4cb4fa42fe299a0ab6b5ea245", + "8ae52b13dc4847b87d04eef31ef309c544327a97abf77bb9d6f65ce254eda20f", + "b40bafb5898242bbfbb4459d5fca834d087fd6eda1e73000b6a70b939b4579e0", + "45b14cf7b55e0b279aa73f975bbc9410a0f7ce9e16403a26fcf43ecb32c8dba3", + "541aea033d4d466f16151ad4cd14e1ef5eafdfde6de5d90f81b982ce248c333d", + "0ea6a2404499f5c305cf867b120e51e2f0e059f62724a00e037bfc454640edb0", + "11555e84c566c763461366e82688b7f79069b6348384b94bac59384be8a13060", + "7c0ffdab5ae1411d737454a99731e03763c8b50db72f1fb2e95e98e77e2468d4", + "650870b8dc8bae225d2c9941cf50bd7170c4be972c0c7bdf1c231c423f01feab", + "b48e58d099f050b861fb89fb64e63328027ed537873a3c4d3ed2478db0fac0df", + "4adeb45eda87c2e7ca8fcca1c3e08a0c8790d8ea90ce0feb7bcb64d5897a5586", + "0f7d040f352b9dd1584a7c3f1b69662ffac2d1547c9f59e1cc8d3c0dee39730d", + "4dc8d32b227e9f6c237e365ec2a4dfffa3aaebc57eef16d9346c7db64ba49374", + "b10b657ccd264d681971f967d5028a8af4a9b1b1b8f9f2b71007be3e59be7d3c", + "5448d01fd79a523a4bdee2ec2dbbd7791f9fe6ca75f5c40401ef117461cec8ba", + "36de4cd104d86a95870973df8098594e2664dbb511fb5b88ea81177a81222f3b", + "5e236d0f2998c9b378dc7c700d1b78f09d2e976684d26c82e0c01d8258f4a194", + "fc61a91f8df17f071e12f870a9db9a3bfa5a5539059562d26ddc5dab740d36b3", + "a4c76b409ca8749d7872751d2fcca6edd1d31786838b401331d278e152f2359d", + "5052cdac3a71a04de5a08d1a68a65d7d430d3cc826dab8f251f8d563c0bd9ccb", + "ad02bb92a7671d1c6169b54b5a2aec164b365ead6d3f6ba8e7a6b9ae1a058a72", + "b160c3f6027aaceea2333d60bd73a5f272855160d86f534de62d1a3612123272", + "633caa8b96855f1f4670221fcc74e4c98ad11021aedc49836a266ee8b969a8e1", + "776e120dae4c7ea79976af13d50fbdddf9f505878b04507f7764064fe3e6ea6d", + "bbbf44819cdb326f8e2b384e1a7706a9d47d916ca7dfc17066cda06e832d5532", + "d5138dc9927d45efa6eba22b936839c6304a15c3d829bdf9ae72ac1c35c6abd3", + "07df79598d074eeeed6e015e358c27d0ef30bfb3f73d51b4947b90f11b55931d", + "83245156b9df39721c7e59ab02521a0a03636e4705d8366fb9e0b48a332158c6", + "e3a9c8ba834848391671954a7c834bdfeaf27e984954d80709b1999c646e6bfa", + "3177022845a8587acc8ef8520e4f6c2a5ffef505a1bd002d954d53948acb596d", + "c27d701d27ca4948bec81ed30beeffe45916ebabe741df064302b9f372993c97", + "579526f4e56296474b4cab4f4daf4b9a0330b093f60678c8aaa786539beb7c05", + "5b1c8fc73cfb06a7e6732688b1587225441f757428100d3519cc74c205aaa155", + "88dfcf9c1bec83243bd7a0e2ea79279e941a96bce9db5792df86ec9e4a893a86", + "9c8007037b711fc1154cc74e67f8ea3bc84ff9c06c4b155bf0e4fd600a29b9ca", + "dbf31032d555e8be1a9235bc98f770e7f0d844a9f69dce654d0e5771f72bb96a", + "d6539b6feecb279bcbf009f49c980e2567d1024af28322b82fe27d2ea8f666a0", + "a7c77925b8ec6604aff06f9f8f2b9d17ee698ff9c37ad9ffd51864ab0ae152f8", + "0979b560002cbfe8d266b286177f93d4c828a61eaeab5fc59a86ee7ad0bbec67", + "4bd935f1659d1a567232c5d57549ac46b2a906a236aadb440c5136883aa19f5c", + "c4898a787c2d876acdf3eed6e601a2efdf4f3e89725109bd1317f122ab4123d5", + "644eb040a0e13dc203add904544dbbdaa951a22ec9395267430518cb557740bc", + "80d327418da0d49aac4359061215c9e0c429c686d1b111b0d15f20a5250c9914", + "558db8ad5f0298e73ed101f80fc7120811acb7cb1b02d0a27b40b0439e94fc2a", + "27b06b61e4ab34deaaaeb0cf4a4ccec6da6dc339684f1c50a7e5597d2c39c8e0", + "aed1669fe139e8fdbea025b2bf5b0b0b10b935e620830a809d866c035296d181", + "8a639aed255b84e628986cb11d979b5774f1a4d47826e096874988dfd5580e11", + "2c8e06b2834233062fc2978681a37aceee95f98c805c7abbf0fb599810576642", + "5a5f43158e1929ed0f422d2e2d61090fc005c9cf7ce958a177f3199a5ee8ec0f", + "2f0f62b2d4a21cee962df856ad3a5ad8e3d96b4ec8473f5dcc1598cafcf79982", + "4e2194acdd1ed0442faf52d9044280c705970bc07d1401c19860112780f1f1c6", + "3624a56dc490d31ee78de92f29bfc0e5b69048329238062dfd451a5d86be78f6", + "362f790c42d03479e8393bb3f48244065942d23bd5d261d5ee54a02baeea9e3c", + "07aa6f35c49ec9ab0a2c19760b3cd606aef28d537425e77e93c78d2c1fc9d2ce", + "5ec61b85801d8f25dc6e1dda194adc577dd516e6a52ead33dd094fd7d039aefe", + "c55af6bf9d8a96e0835c44bf32e9d6e1aec808b43dee7b9ef5abec534147fc05", + "79e51fc1e50905c176de6c3091907c1d4a4aa935411ad98ab6c0532ba1794cb6", + "421359d5c39a8ab5df141c702849e678a664b90452b73e1132d5fe17a4d99953", + "6de6566b5f0c43ab3adcb0e2e25a4f2d0c2cce0d7022527d678482e6ee70454e", + "6a4208f0652097437445e722a475f73f27e1d35eaab58cef1150b73c79debda2", + "41dca060ad4d612f4d3a59e7b7e6e62f8c30fa534c03a56b1137058a5ed46690", + "66d5db41d7a2e35b7d9feb26a9c36d4313c98730259747701c8029742eeeb354", + "cf066b030b9f88fff4db198dfcc82c3d5c9b24ce5bd3c604a46fc7744a78c259", + "df9e4dba9d27aa27f564854b11b5c5585873b8d2c4e6bb568123d2a20079b6b7", + "674b8b74d09ddf144dc283e5b829c3abd6e12127e2ee9068cdf6703189baf4ca", + "23fdc5cea956071ee9ee8d93e28c78dda3aeb1a503b0bf56a79636088d9cd4bd", + "b5484d2a46e6e948407311c14eaa58fe91cfd9ea4ff19a0aaec135a6c48b1aaf", + "8d550a75a405594fc9bb283eee445caaa53ea6b6fa666b094c7fd52736b42da4", + "cbfe05b921ee2a01883a24e125f1a23b869b72a10f8954160a7bd62435f8d4f6", + "5a4c46a541fe292758e2bcd08ea435f7776da9046e755e2be5ab67fcf8721c41", + "86d93df85087e6bc7f045a2aabfba00bcee2c4acb2012f6489deed6dfb9cfa83", + "088cdaff9c9e85d97c0c8c8b27793a5609878820e2838b8609d02e5a0843545f", + "ccdd1bd698b5880ad814813c6c6d06edda06d51dc8504353127812e2108efcb0", + "409efcce9ba5887e3f53108ff7fe8836b861ada1917f542282e70a9e9d197f3c", + "a35118b456d97fd96944889f845710d316f423dc6efddc01caf8414490ffbef0", + "d3129f7bdfc6c50f08971bf310c07963d6e7fb223cbefbca19cdf2381bf4d9b7", + "a8780847418a03aea4fafb36dec616dd160c6c3a5e83117cc4e8450a9c244f3c", + "fa34a1d412ee326ac9bddb2990dd38433b24ac464e5a077ab6acbc8d9639e334", + "9a625d085279239480603d767af74987c7abdf091ffce11d0acdafc3a4a2e2c5", + "c5ed750262419aa8219727c22ca98ffba499500b908d2881ff5bbf75bfdd2925", + "bcd568b72347141b87b37bb615929d3e28955b6271e956109319cefc7e464bd7", + "4fe10919a6ca8d493ee9e7795a648144c2c68882ce09b4e3e82b5c48cffab8e5", + "d6e2296e2dd150fa79b5d07c45d0d3aea7bb952dcc9196bc19c4b094b59c2175", + "01b1e51334ab83ab30fe913838bd54dbbc499eb87cce0c818944380044f7e753", + "04d3e39554c54ff358af278045a3127f21911a70c541db14786401862547edbb", + "266309edde994c6ae7a999ed9b7b7f03295bfd78530eebe1aa644aa3632f6262", + "577cc2bf79c256e797473f113d5caea14d742cd9f2c00786e133e52571a81d1f", + "e692b07fb98743d2ae929d879cb70e9e0048c92ad0d251a16b5cf80ad4ed9fcc", + "936a01e989de9805d26d82df2b27f7802ab75717cacec8b9a493fcafdc973241", + "904d6986c44af49c9504a91226f8f3be48a3f362708e6eae05e5c37831e2948c", + "eca23d330369c934ef996c236dedeb7a76eb65900c96c072c39fae6b75fadd47", + "a5a9118e0c1877f5f4979ed41d025df5dce6c2c1be2ff485855590682fbc3cd6", + "debc80347afe4759066939546513421253e26d5e0ac8fc053fa6a9395292d4f7", + "e701775fa14c8a7648c9828749532c1f8b9326e544b093d8aaa4c6384facab53", + "2e4aa1d5188b1017bb82805266a98accd310ccda01b2726c56005edfa126d46d", + "81719afe226db230cb3056545c29b33e2a497f98d9e5b9b24ff743ba1aacae9f", + "88520ae4bf9c49cff8470c7057e679a6a26d086cf97bcc808f4bfbebe0acbdbb", + "ca4aa841769644bdc15b8a512de610c3d835cd9e0a56ff5043509cf5330b8722", + "1888f00054bf7f07244ffd49d581faf4910bff0b793455b72c2edbb0a7699459", + "4ab1a9200b367a74e1d892a770cb76254f11761ba4f3b725f0d24f65b9ea0041", + "cc0e3add1233a38db536418f4e26d02e870d23a3570288ab092cb7b9278e067c", + "135ef05b698b87f87d518d62c9578eeb3bd4af9f6df80a3425e60f39cbb6247b", + "d71183e1b80361823d7875298260a1fda3f13e56bc30ea40644a7050a5dea50b", + "8f8d7fa37fb357980cc4b1c6b98eff1d0622a2aa8b4f47bfbc5ee0d0e0a844cf", + "b18b662175533e20166b95d676b3e538405e46c5b542d9ae3301a98838f06d53", + "01327d1259292fe5942f0138074572014ff370863f400058ff11ba32b4d4ba32", + "1ac6a575686bd6a1851d343e7e7ca90819d97d448011f646ab2af991a30e7aac", + "749b21a4ec03597845598017e8119c52206f5cfdca2e76694e18b65da0a3ea43", + "01f5d02e1e2a6397b3b8e73271fbb79a626f3d44fda854060664412260b132c7", + "b08e5bf1b55c7d20b29fc2f76f17d82419d4b86ae277e5520cb5dd8484117c82", + "b9f7911f8171984aea0d39872882ebe34090120f27edde96db9992bd8a749079", + "6facbd52d3ad007c029069435335c3de7a3d89d52db18e099e5f3c093c499af4", + "77874ceab62a958624fcc45f91d81a139478f44e8014aed2aaedd50a76cc60a5", + "1be50ac83fa7d7c69ef11d3fb25c2164c4bd55bc11bfcf5990a4115ec0c5a35e", + "905d7cbe647742f95fbf2a69f8ce132a22e0e7379f5fdfd30c73b9cc7ccd2b0a", + "87a37c5093d100ee402dbbcfdff7d1418ddd0787892242465c07d8f1e7bd1e55", + "516b525e11f3fc7486f372bfd745cd91c7eb70e59ce4a1ada1c9b44479ebafb4", + "d004e7140334fc6414784387b3610c3638f9ee29a03707844b18102a6955bea0", + "b17dfbc75dbbf124ab6c47ced79655ba72422a7d1107f9ed7d75bc6dc2cdfb0d", + "bb8ab123456c59dd3acdb9a684ac075719fa5f939b9a1a447fe36f375e73b58f", + "382b49ac281c172fdec96d69c34f5b3a15b8805f4f07776080f2cd9ec6b14a09", + "4f2534f177123e701096fce7cdd2a8cb02caf60ca9c223d8da2dec29c2b29e59", + "7ccff4eb14f87a7b2d3bf77a7d4833a1e40f00ececf339da28c3ceb55780626d", + "bd165e9b94b145e6c2536fa4510dd1804bb96255bd67c17c68448686896a6980", + "a1c044bd6192a33e7152d6f37b21b3b907cd653890c637514ddeeca60c4ec915", + "356b2a38a09cf89c7828132251858d5f785151e15248c510a6be41f5dee36f68", + "0ab4842c324964b19b2b857ccb02474b03251b313aa3b3edac4420c1a6e260b8", + "70e72169c4680ec8727ccc85bad3f0feb6b5f066bc34a8a67ddf5fb3416b5e35", + "f53c5202d47f6c5189032af2e3a2acf4229c2bb77dd6162a85a23ed070ae4b6f", + "c0721eaf7ef1c846de75138237d6ce1b3f11265360f4e7af718828d1e4b8fc09", + "6f0ce58605ca833414b3580bc3074623b6fbc845a42439bdb454be22522eb3dc", + "4e563b61dfd40116b68e111b3169b9b9ac638457aae194d0f88317a136d4906f", + "b762f05fa27e153eb18032b335a5b9ccb243ab6dc1bfd3fe58a0c854b8b85f88", + "6b2cb76ae02fce4cc4df76ddea669aaee1bcc59bd1c78edf892fadcf3d01e6ad", + "ef9818b3b5817735e8435c71604b70823450114a30330257eba91ef1e43ff290", + "723db218ce48d4cc99d2423afc5714bf5703261a1e3e5362eca4f87abcee51de", + "28347b297cfd842d7e59ce23a671c9fbd843339e5805984f395cab946385b34a", + "b45224cd2e1b68f02cff4ae0045cc8ba8efd3ab2ffa563ced058154d1ff3aa1d", + "685c17e4dffa89b2cd0ad18274df4039fb9954363aa710b41381f1d63245c87f", + "3f21575e193388cd2a5526dd258d070669d813544d01c28a32b47c4a9ff05ee0", + "686358d157ba70b4fd96d4b0710f92f5633fa632bf7b9db7e415a1f14fdef8e7", + "d65205b4fe42b1f879d3531644d02b79275a1326afc60d088f9f69bb6e21a362", + "961d8f6a5ceb00d5a6557e74c0ed609fa0f492a1fe5e14f5a74ff7f150bb4b97", + "73ea0b1c9c4ae8cbe196648ba50971e6405aa329ac6ff8225f67a62589c869f4", + "86f4161248273e71293a84657ab79ffa1502b6572185b15fe926f827012d5c53", + "d681e9fb7121386a705fc7d411c9f20d68fb25f05ef977fdf99af591f6663e11", + "6b1e01932cc462a701fe677e9ef64dd7c0ec77b9fb8187e95d5ab049141e706e", + "da426dab9884d2b27b4e9aa13c891051d1350eb716790f5624c925c661a81350", + "b54fc03a49dc4ac9d37a96b427d44e4c62f1cb4ae244b1df07f010069937f3fa", + "3d4b4d0a375a0323d4ad4b27a864b0a41462a772e952d992d86c913cb075f498", + "2a3f7555b354a26b4e7b96aecf2e63a56e2f02693c256c39009b01cf599412b0", + "233c8830bb4d0577ea0e7470a3ca1b2dcb9c3bdf771e72e51f4ded06c936356e", + "f8eec164494233cadb72bda418d8e6dc187e9c21a948e438203f9c9bb9d0a5cf", + "ccd43069fbd31fcc4fbb0bb171da21c0088851c9254d2f5b007f9de53caa9959", + "80ae4a996ee4a732a6b617fba89cf79b9fbfd85d496736f24dde4f895c261caa", + "d68b15434f610de47c1985d7c962cf6557972b51cb294060691a7748576efc28", + "a463000b03bb09a2849cadafbc342ec87785eea605c54181bd21391cfb837de2", + "cbab7214afbfe30476e37eba7d33821509208fbc6d37e7e94a19c7e836646eb0", + "6f253c2a08f6dcd5ea0ed1bb3a99b0634c8241fe18fe430f24d67805e5ee83e6", + "540850c8c64fc68aa491fc19b24edabd09633471d64e6249dd9faf7a1440ca9b", + "a262a67ca576788430d4af2ec0770ceb6319384c86c7ee915a7b576ec2769b2f", + "190727bcd415adb879bf257363238eb4441cf440b6f72c477bbcfca1be22e8eb", + "5a9940bc586b36aa7b534f9af2460d36587dc0ba84f15bbca5386605d334dce4", + "b9b081140e51dd12df96700a691d604178082a2a63c3856767841545a8b9694e", + "560402c3717c7328f50c5dec1fce37917226423ed1cc1ef7b809eb4940f5bd45", + "b1e88caa0485eb4a18f5bc926c6c1efd7d59f794a03f319ba3c8060c60e8911e", + "a9319507ca1e94f94f02d283dff7967af1416a20957aa0b1ee299bc4403bbba4", + "c3a70bae9d438626d449239fd07a28cfde0b1b805e007aff8f4e05ce6327bbe5", + "f69e8fe639e4a5b335270996987e2f2ce07944949e7ac6c1dfe097bbb1371225", + "f914e65f8980592b178b58e2c8cd64b742ecef3868ac393fc3dcfc31a7f6bc9e", + "36ab44df65f34b166c36de2e662cb0a42a874d20f7f53d5aa0234dcc2d1923d2", + "05d926c35519e44e9d0e882f1e418efe498dd7135cdfd2106550fb2faf135843", + "66721cae365af689d99d304c91809afe6cb8a79c87e21e2fb23a6e4016132118", + "bed48b5a7df72951a7b42544bbe08f5ea9f37561baac756670a8fb6e5dfc6a0d", + "0214e2fc2b5f565e71b4f15b094fcfe8757a8f45616cb002160d0181c5c05fee", + "dc8a6cb3e9fd0368f10c3b14c07e9e36ce8c457433f64060cf02e1b8135cde26", + "a0417bc667ebba54e02466ce38e975c6d75f09ea637416bfb932978eddcf641e", + "e60bee5f0f493a98da57299045329a520504db4641064a3ae3d22b3ffe7e6ec3", + "3f3de7b1af0be482dfb95ccf5480250c14885bdcb27661d38907e571c25f30a0", + "29684278c0dfe081c9e0fe4d5a785b9dd86c6bc1e784b657f0dcd31c76570801", + "80848f501c1c444645fc1e4582cb33dae2fddfde4fa9e1ae20dfcb1c3da14c16", + "3f8c3105589195198c0047f8564aa3fd41590d4d79999d49d05a25b3ddee4b41", + "ea6d1f6d9b944eba6a1908c8bdc307fe7edffdf40321859cd16ca1453b1017ce", + "9100ada69402b717cb7168bf9ceb2b594e6d750bb13e28c03123fec09137802d", + "a2b37784c2573926affe5170a1ead5615f467d8c1d6ef251fdfe8f672cb4773c", + "843b6cfded5dc1dfca8a63e70d37a2ae8ac2206afe479ba334bd6a6ffdd175b4", + "dca82cded6e330ef44e5f422a61c133db6a142531330c7396fff955fe0eff0d2", + "91d98d1d751bd11345bfbe710f7704a7a2c00aec0c0d3ce03ad39f96f23624b1", + "578121829627a931f7ebaddb8b42b9597aa7a79ac0195a06fd10c87fc5286b62", + "bbe4a3b41c6d8763db2a444c38e6f144579a9164b7fe57f9692be2a083e6da72", + "071bc13ec06b7fbf0b0ba4ffd5d632eb2aa06e4d91a514ded967dc339636e010", + "4302112fd4ce9e22d17ee437144d9cf3d4cc27fb0593566b518a1533d12ba8cd", + "7775538ff206ef844e99b5a01485d9cf0b631fa78afbff05a40d1c665d8eb63b", + "b4eb049bd620f1145ec85729d6c7dd4d70b3e666ea76ce692ef61632a446a83a", + "81549ed6eca3cdc49468b004123258b0dd9281b97c02d161cc2a510e9c233397", + "c3162753c970a9e182cfc6e4556f6b7d105a7f2233a2b88c20cf1ede74e94963", + "4ec85978212e38a328e0431a7183f8019e10c428140732aa2f5563c577c41dc2", + "9605ec46a61a4412adee89b5ea24c368b0a38e91931bf93850087e8b08c4c089", + "5cc565993d6c6016dfae3415d19ddc2adecb1dcfc4b2fc2a1fbfd84f3f460b84", + "0f16388fb735154236f8faeda0fb99e162ffcf4dd2ebd2cc64b026fb3f7a8bcb", + "f55472c19c5de90948addcd9ea74d1aa2f1653e52dc291bd0d7fdb2b6a3c8651", + "fb8cf6c0375cddf1b2e993a182473a25f968f8e5cfcf6dd086e8e5f9907deb6f", + "96d1a6524a8c8fe31434e14e53e36e53ea7ab53d860f3a161835bb52eee7debd", + "ed90eef691e07956574920a82463aa89a9c858d4f9e4f04004c6f15b7a18d80e", + "568829fc6083d27780b4e86069b5243a1790d9247ad9a52746661c99b667a38c", + "03604b64553de57131502df844b50ee68c1f11eb267d2553e5bcc9292d3c9c25", + "a68a470e5b436223e524fc21d40020a947c2fa56748d79c8bf1e4c0f73b7d974", + "555e2a47c2d60ac6b542665561c4be39487b2a162c23fc4a6139dcb614a58f76", + "4fb14f17a3bfff41fb0ae8c55272c11bfad9b04b266130ad9cd6bf52012ee47f", + "de9563d578587552894069e6cb1fe63ebb33001bb80a504600b90141231807c7", + "5c215f3f4451f8c5ef98564d4793590207b2fa0f0af2e44965e4d68d7887124d", + "e52bcc8ce6c5a822ccaadf89489af0e63c84e8db65bd8912fc8678c99b467279", + "c59212c3a8fd4e68674b0f49cb05acd7acbb0fe7db7b4fc0196282c33c3d8fa1", + "a35187ad812b51720bb8d510244b6793829497ce1699f7b68e43e47f629eb898", + "1ac55bf08f20cbb5c167dd1d2b540698f4ef8e5fdb0a424055f60c107f2a07bc", + "7900c4602c43e70457e2784c1c6704ef691104996a22cc9ef5d794a6f182779c", + "8d178331c2821ccaa827ec65bc8cf17c1e2854fee689380803e32491a526d558", + "1abcfbf51c9a7bb6b6eb2fecd38761acaea9abb77e222182acfae956756409f7", + "22f95cdac7ebf0de08c28875b9b7d822a21a37acf2059cbd5508d1c2a3d2311b", + "6678c0b8bbd6520b1a279a741f021eb97260922284a055b804c5c565f1ce4139", + "d86e71f1a57459ef5d3602601dc545103fc40d113e4a49ab94d91c097077856e", + "a26039460af388c4b95e4f8f0ce1e56a8e6dbdce2e7c97ac4e1f40725865bf3e", + "b45eb7ae23573524d4dc89a7d7934ef494dafd8d4f46d38850852304362445b7", + "b4d2cef8c39eca723f01371c53915c28c4b97b200c8127c76e38d6a07dec6d51", + "e754d1f170048fdbdd2d86a6e79094498e26f1e62694332a1be9e9cd03bc584b", + "af47a3604eafee12ab9e856a8244fad2f83feec1db74b5814a8cb4ed6584202b", + "a80eacd66efd198431d4ff6bb916b46ed18d2d10fadd6cd69ffc9c7f6195ed56", + "b9fa284f0ab846d68a793124aa8c881bde8f2e4b4adc2dfa117d717e6d422a9f", + "3a991c4580b7d6d9bdb03f24f17b40a8987bf2ebf1849c931fb6edf70fa1cee8", + "2869e142b6ac3f2c331dbce6d50407a91096697aecd82917a9087111fa5a5c88", + "4a1af1f1f9cc3c23d6518e4cf20651412d50f9f567e3d4e3c0d070935403432a", + "df39d6fa80a6be7916f4cd8efa59af0a27b7a9a2c67e3f640ff9b8fd080a85ba", + "f98d7923881a9fe18a184e6e1eff636a287445273d416dd1f37cd50e9a07308c", + "8b55b2a6f7152e9520f8291ed37f60c7fe02cc2e68dab2a547f9e0b3a4639fac", + "51c5028719825b7ffddef51d6215a4c1379b617dad1facf1dc66693367a2e71d", + "23a7c7179db683b3b163cc11bb210a494529f058ebbf7c5471fef7bd20b3e240", + "3d98bb72b5a89994e52e0b1853426fc200b4c6ca6622520fbc98fd14b2041b55", + "495a3b9a4b3cc30ead754feae8385a2b28c4ee1ad47f345e786fbac73b6429d0", + "effcef0f12669c18bcad5ed365577cb6e9c93dd5af0008b6e1be4efcc7462af6", + "234a9c6a5d35bf3c412205aecc29fee6553204115e31eecaad2cc7ebefce87c4", + "35bb3f3424d5642ed4dbdf865f11b4e54807ff5430a8555df1e19fffd9cceafc", + "23c3c07024455c41928bb5c6ffbd27b82bfe339cbbf2880936d3ce8c694bc619", + "ce6572b0822dffe0e23c1e512a572a2f2dcf2b1ecea3cfbbf8160d801dd7266e", + "a02eabf77e39f57ad4b287ecfcf09b5ce63a773f7fb8e30aeca811805a73c92b", + "6675161070745bc89280688c2275f3080b4ce2637e6493cae0f79510909dc1cf", + "c6e660598757b2c4afc35283cdc0d565d43d4c10ccfc9165472388a676a9e0b9", + "db7dc2025dee9288f9f2b73abeafd66b6f266bde2918684797fc08caadfe1118", + "a0a8514fa0819a0e34057dec4df4b01d4090d5f95383ec96b0048a6434cf5afd", + "84c25364eb61c92c7a940156156a4b204a4bf003770f72896864cf8c892df043", + "a6f02aa27135744e8f01880d14ddcf0977f1e110d3c988320dcced6a59b3ac21", + "762e49ca7150ef1b4545ad91bca2462514d15fbc81d9d01ef9884e827836c35d", + "8ff537cb7430651c7417403a82f916c3652257987a099c75828c68542c031861", + "da369554023a42c56048c284e2aacae2e151cd4286fa69f905b502e57bb51647", + "31107b9bc7c84933b0d753e4a137ec397cb704d468ad8c52587a7838332692dd", + "d36da55f4db1dcf28acd118cdad59307115eccb895698a070b8524edcecbafc6", + "24ae1b9af9169d4f174f404dc59b4f9b4cbe2b5b44a841118306f53f6eac9e81", + "0cd631b2fc52b211c295dcfc0ff2a8a1e6b81eddf6eab5212ac12b455e808ac4", + "3820f61a043773ac5dbcdb511d95a4e8df776f5410dd294d668bb4117a4d57ea", + "c0b5f319b99e22bf710bac97a53daa07521c52090f1aa24bef255306dbc3cb65", + "bae7143df5b3d137aba86289c2b1c71ed22052a6d8090363421d4ea4f4c1f880", + "e8509509ab732ab30fcd1424d4c8bad78e6fd98dc86feb9dffa036bbd6250753", + "8c9719e989a57eec1629649d5bb9b847619b52be921bd78b677df9ce3e3a2901", + "63822b43a1ee24dac39965c7373fb1949107366597711aa192c91f53e944380f", + "641047aa25f2c5147d164551247b65d61d387cca604d7e605d32b0a6989db6a9", + "5ab7013b588b6bf85deade10e1ad19de160ebf4297e629e475ea0446572cbe32", + "f1646221b775364932156ed9b01414edaea74777bc9254ae2782012386b9405b", + "5af7ffba8cbcd20a2449f750e13cc7de9086ec4cc0cd532c3fecac40cda40961", + "b020eaf4c37e512e46aeb03c62a6893294b0cc8d22ad0a28f11b0ba80c7bd8f4", + "6d8fe38f536199455457e14daa7c32c9d1cdb986f730ea05217be27a716e97d1", + "73aa58fdd101d83c70100a7fdcfeada14173bb1e78eb020a4b72199f0215c99f", + "3579523b9ddfe99ad9440f7a24845fd6b8f0af70e872c3c76f4ad9da4e8a6d8d", + "3a3a2a938ecd3e6dc8a24f219cd79ab01e3dce8fdf1b9835cfa5a8882e80b693", + "34544a720fe343b3fc61834778f4c19d6cc480c106ca5b4820d34d7aa67efb81", + "6a452d5f85787446128a08cc85476bc1ab73b50f183c3b4e52469a81be54b068", + "eb43ed909a226dd06c2f0513f3cbc019ef520e32fbb3cf0b3a03d22cd5f7cc10", + "4af5d1e674a02f459fe5a54ee25810e0189f0138829e4a150d508370ee3d25b8", + "13b246ff3cb1f689613cf7b33ca0669503b810de9710e8dd1f3fd022449b384c", + "03defe9681a147061d4ab4e90417a11f313379b50f4e1af324c160b66abb8021", + "3aad552d62233eb0650953256d609fc50c6b45c3be088ebae4c6718fde39eefa", + "a48f23c163603f152e40147dce44a3bffba48ad2381bda0077f1e0128976f448", + "ff09dffb9fdb55adf26e291572ed802a15f9e0ee956c15e8ba4f459e6fe7714f", + "ed59c4157ac0b748cf16c762a1aa8dd2ef97aab23eff66777940c7e0acaf510f", + "00ae099a1b611b391edc0b14017e97210649119c532e5c11176407e08288cf6e", + "0c00a22f8bdde7aed041cd788e465f5e016b1974afa695eca6205c9261a4c2fe", + "c376cc155a638eb5c0a60f6b27b288a7c84ac5813921cfa6cdfc32649a99fa64", + "f51f9baaef862c5bbe62a82cef7f30ac980cbdceb06d0e95776b8888229bf903", + "5ff0dd6a81ba0a97c30ba2d4e9a857c9c2e023245c1af4398aed40b002923a01", + "0d341cb948eee09883d41a0a6250256d2b046a707c2505c81e3173f9b45a0d9a", + "b15482400ddeea2c7ea43eb738d21e4735deb9134396ea7b519776479c6e8d51", + "095035ae72db04906e05098669b45bb07aae74476917a6563718d892295a0192", + "ef638ba5040153d4cf4d3167847c150c3b50fdc54af72bb35a0a2c58ce0bd3b9", + "d9279b3c21f531b1106acaa10082a3e1a8b185214554263a443bad87daae3746", + "72e8ab32088d2fb8c408f9e4056e8811d3f090d3a2946744d5a73e07970f49e7", + "aefdf50ee206888763d72b531cdb70c8bb49aa59dd293c590326970cf36fb470", + "ce596189eabbb4007c13b89b78c3c65d5041ec415dd677bdf6ddf291cf9c9b7f", + "95de1f1084d7f16c08d1524bb1cc74390994a2da4e65d0afd7de67496123417a", + "f006d3d973832344ed26e8fdcc33d28e22a0496416632c923d3829d9367d1e4f", + "63542aacda81815d584d16422b9d72016e68b330bd9a4bfde2c0882598e81ab7", + "c73623eccd1912e88375716eb67f7d4064d35cd20988e23e76d3cb5ccd584a6b", + "2daea725dba11134471ffc3ec15f9be5e02a427c8c67d629f2a22a04f994080f", + "6014eff90271578d441100f321eef6ced10c7957a3478bdf2a99228550743809", + "9b80f67d98636a99a5328346f1596726a5df1908bb5664c8a10d891af9e72408", + "53615fdff0303f103b453395cfd03df21c2181f7136ff0ff0ef745daae330da5", + "08c5e2c6bae354bcb3ecd57028d7835be4a0816510897885e692a90774ff7bfe", + "3a282cbac56525c67e454c1f68298c5d02613deccb1dfb83c8c59adc6bf4177d", + "dd453ba7a4eddbc9723658f8b588b8e9677b57cbbc76ced52864dadb94014f19", + "480aef80ba5f140acfe1fd8b811445f56773fea2ab828217e32574c8bda6c724", + "8247c66eed210efc5cf40cfef5dca6dbfcb491decf1aa77684094c95e649bb4b", + "4bd28ef63895fa6ff4f9f8dd590673a058cde28e13aab9f3ffb3fc7b969172c7", + "881b370bff8fd5008dd7a7cde25dad0454617a8b0e0e372e8aa034970e2e9396", + "e0e56acbe73d952c7bcafb70a660d851cfaa2435fb8a87ff2d9261cd3ab859a2", + "89fadfcca11eee66d405f55efce0b97840f42043bbb81485b64aec6a426545fe", + "5f20de39d77e97e3cbec5f42b234a8a1ec05aa4eb2f1ea9496f20a0fddfc7f4b", + "dcf8d27df3cfe343f4a07dfedad2777f2c971aeebcbe5a788a06475d4e641690", + "aef8527b6bb92126f47ee822ca69f6e89c9dd316d0edaa229cc5b1fc070f4bdc", + "8554c70ccf39cb75ac4d40f39c9c34e5142e197d7203c2cfea5259f8acb05a22", + "4127c5031b835298e32a3689fb816ca16292ee2c4cbf456840442461cfe454b7", + "97f59e1512c2ae9d678595e251cc7f6d4bae4b68907dbf2569ece3e5a7edbd74", + "c23be19183c8e8a872328d22e52f7a514e2b7793990e58b1f9a9c835b0d145ed", + "93b9ee61b7ed02a89c3f744d275486cc810664ab5a150b3bd8b9a639d08f5d1e", + "b5b5afc1a430944058cc39d1c018281b04bdb4f660de1979389658db540a127b", + "dbf2a6a6e693798b165dd589c125726997bec7e02785c36e435f660197cce7bb", + "931b077146db9e383edd26f52e5724ef4cea0691a09a936458ab059163e30230", + "06abdddf0b34812f6aa8e10085ea332354fd3a2b36645bfe57de32f069e2be43", + "d47dd52be5bbaef60bb6b53a9000fd57b9c02f404413c2dc8db64cb9daf9cfa6", + "4d875107edb088d14b6cef1278bd43844e2d21bba8137d63e63fd3cc21a5cf0a", + "f1b9d3595f9e00487b6149005d95bc59c3f15421e9e04e0f6cddcfae201e4290", + "1fe7810c0a33f2b9b94975ad87f0d37e75ee34c6c0b6b54775c68372d467e185", + "457e4e7ba576e97c4d408a2d58bd864b0aafb2c11677f4f4d5308c3ba71951ca", + "74c24cae124fd3e3d0bcd434bf3f505922a86dd85dd9f232c42a4a4fd28f3f22", + "b7619fbf01b0e96f6f2866095438ccc6fda29448af76b937beab273ac01701e2", + "74cd5cae1d4b4ce708cdb0b0e9efed76274a213d746139b172e7d284bf9a1900", + "4ce98653bec957f5924d8781528d52f596c68904222fdc7f4732c8c207575a1e", + "a976462eee03fe5a060148d61cfe5f73af0f23617bd55b740a010db526fd56fa", + "ebb414ecab443aabf20c796b0f667280760db0c3f788979052285b7ca877afcf", + "dead676006c2d0a9951f66db1051f89fc97752f0ca6b8ba29decaf996be9d072", + "dfb84d7be92c68876a2c01783a011e8b14e9e3e8b10b884458592593bacdac17", + "593ecc41cb0977a52d809f66365ce7816078988ce05baead4f004c2cb906deb3", + "323d8ac0969f979e0d58387dead8f7f6119b328a8e6cabca02444964fd04d1d9", + "eca0862fcd630453768056b15c3ab0651ab00943f144851a026171a2a6b34a8f", + "97cae6df32c491719b7bbc6633abd1a97c8adb19b3777e40923c2b5ef8b8c8e4", + "25755f1d3c946bf5d6bcd9da7e6e8d8d85e5a3d810f3ca5bd9affc25dc3ef722", + "8be2aa59c6ed4d61ed366f72be2de656a451b94ac606d259c42481a3b25c435b", + "557486c6dea8d57803ff8b4cef4adc6de82f1b2eb165509248e5d6d84d7585a6", + "b273ec609c7a708848c96d02fa24b263450450cbb18c14f5d3fa8f11dc3baaa5", + "d4a1f146c5c8ba6e759fd65d6a753736ae2584548a788a274bc6f7e9eace4af0", + "651a4135a1ea9593b0f5705d8aee95e80fe9c837bca24fa4fdfca8c9f47015a0", + "3075de73eb1a7aaaf95db68fac79c52cc7ccc424918b2c628edc826165ce9d50", + "035808afb1521803aeb6ddc51270962bae3f6649323de25d356c58cc934949ef", + "0eb9cdcb07611ba3edd01f6cdf5b313821da97a3d0678ee43aee2a8a30162a39", + "42b5aa6e81f62e7442a8aa2f36ff30cbd21104c527e4058f7f8cd7730fd0a0d8", + "e72a02c997a715c445e10847ed240e4d43719aa3d6667300980d738dc195b57f", + "7ba1d3ed9cff47b5cc448a8ec8fb0d3c741929d942f132985bf14f86d2f742c6", + "ff0230cda73ff1981cd71e0bf04621982dfe43190e898f2c6c8d929c20a924ea", + "b2cd6099e6fe58f1ee0097ac7633c91896478458eeefa16015cec165649ce287", + "d9a386231672d4b8525c951b0d2a756c1a489311b8d8baf51b4088c3bdcab5ec", + "a9a47be39aca641f51a8a2a54604a67c9d94ec89e64996e0844952cb42543c3b", + "221b94d34b59d71cab9b52d766b58ec8ae2b33e375b75f154d736187ff2cf350", + "0a8347f61316c0f8eaa15abd0598d02396d4670d225438acd0e3cef30d6a0c05", + "9bb9b2ea3e1909d1241192f8dd1d1553e7f41466b20cc677950f3cf99425b6cd", + "126e21a283eced50d02ed3fbd1cb824c0e2f0b636f6135537054b5cc6c866500", + "4dd19af247dce2258d296fc8a00d226a7c51540170dcd951e3029a71f771de7f", + "d2eab32397511d0aa647a94657053902ea4b7ecb4e566075752363b1385904ac", + "dfc30cda83b228baa0fca9c5886ba734172a590f32568c278c30369cb5a5a63e", + "a1ff1b14eba6779016760e0496001f625201c3f810efc2844053933bc71941ab", + "ce79ffb780a9773e57d528ebca671d0132cf3dd6e313876d3e6043d420c7d78a", + "084da33ad1ae62f7ddb4fdc58ea36548732e4e4d3556f7fbb0f0d8ae89bf8d29", + "d515b8e7cc4a7eaf6a1cea2de78d1249ac4c1c8ea87d8af9fa850f5ee16bf0d0", + "eb69e0fa6544edb59286936e322b3897c022a835d716546816ecd4d07af48108", + "fafb00a81f85d196f93ae604ef28e10f25b81aea68df6b5162fac48327bd87f4", + "1a08c7e0fa095eac4454f25469c9aab755be55f3458ceb2643608ca3e4e83d39", + "9a0da8b8d8d79bc5460ace5f00d0726506bbd5e4899e07e7a64dddbc830a8c82", + "366ecd6d66ec9b3606871cd25c1ad8a87c05412c6f31c635680112cf6d9a6077", + "28111d38ca888563ba6f0313cc826125ef0d3c8ccb85ef57e5410fd390523b12", + "730d0c5f36956479ff99c2423411cc370048767e889f78dd26268630741753f6", + "18574a1c1df45ee388e40f3bd89283243d2b1beea8eafa800c89a4e36adfb8b9", + "2baa675141017c1a58c5c0a4cfbf6226c37f69176246c12e39c62c9219e9f973", + "61845224935499594bdbc38300b5b71859823ccd7c45500f48a01c868e794a89", + "61974dfc6db15793277fa358d2c06bd47124de36ef815d171b7df853a33df799", + "58310bc10b7ee2db01f5c43d21a9c9e79a86126c1cfc479ae18a1ffdb07caf9b", + "81207ea5f3c4295bfc0c79e528fb73b24f5653a2a62c87de7a4bbf9aa751f992", + "ff99b0c9af9d5fed82393860d95e7baeafd9a6440c4b162cb17a5afdc9d2e3ad", + "5f65aedc08a099be1c318edc8c25225fba0bb8f347b186b6d39d7665ab8faaac", + "97995bd50879b55aa7a512201f5bf4c48b2a9220bc8d1be6688e362604b8f3ee", + "301e8f558e345d7b96df93697e54c0f896583cfc8f1cf857f12bc19b4d4f8c97", + "501748549879132493148b68d12554141af20b4725f4b9601ec041b0f7cb32e6", + "584c1ba25dc561e3ac9c875dcbe64c3f206c39feb3aa990790b696d7e04c5f9c", + "0c091a45912be4c9c57f473af0e481a1d1ffbfbc8e1a75c9e69f7cf176b0fb89", + "f5aeb79e90803ff4cdf02e4cd9619002e92b3fb367bda4f3d4c125751a4142ff", + "aedc3978429e54516558435e2436b0478443185bc627f51e0bc93beac6bcc7b1", + "0dead44397855180d8985c107c1f7e638f4405aaad6c41a3e3bd8c71d1039c73", + "65040690343f6e4e79d8ce081b1faea8e080e0bf49a72586f790cbb14ed4b502", + "1ab7b272a90ca0ab753afc8f8e7ceb2aa69663718f376ca3553e990670dbebe1", + "66596d139d7f25dbd5ea95454fe52b0a1ae8798a0007cbb4bb1fee5bc7ce910f", + "b7ca0dc8ea94629e3ffeebd15e9791b1079e7118afd63c971f47fffe4caedee4", + "b1ee395a739071e316117a82f0cc496650be9cce269602898a721fb4434db0ad", + "7dd4d4e86f82d85ead2622342f37c70777c55e204c49a722a73e953a5fd06918", + "9c280ce532cba01a7930a9279351f8defa99ae04c98bc5de5131c4daec72f4aa", + "aa443be422ac9f5cc61162ec92b34b3971f1628875ccfa05458f71528e46ad02", + "7ae74dbd40025034f062be7bf8cef0909eaf8c7e3b26d26e6ba34c98e30a8b09", + "2741537d4989c9e137ac726a01309d52b7d97ad6f95cb3982f3373ef0247c017", + "88d3305ed43d7e05726814164a02d71221513679b2af4f2001c13cbd305ea7dc", + "3050c58a77d37598c68335838d33be8beaa9a087a298aadd664c6da10b1ba715", + "5fbb7fa1755e5da64ab255d5d8a43885bcaf15fc37d8f814a476f7b33d4c2d2d", + "1a6981f30a72db6b40b42a23aa1a796b8d21564f3785fb50b19a1f1f2572955f", + "4b7b340e4743b1fde332bebef15284873bc337fcd7bb872c8d872374c40a2336", + "aab498faff72a8e93357fb7f9b77c8e4d3fdbce52e112a2513f679ed746f435e", + "184208bfe6fc3494d30337d9353fe7fec08cb5a3266d673b1296e49e18ce559a", + "cad2519c2b5b6c1012e7ade0da0ecff70e0297769f62244ae2d9bf4fc8ffd477", + "35874da270a6df8f8de554edd03adbd8fc0fba715e0977cfcfc7814cc4b2177b", + "70f02b12a958780dd09684da493ff9f4a30a718d8f497dcf38a7fb22dc6245f5", + "e0a5a993e913601a1b6cd2c175227e15357af79aa088b52e0d472c10cbdea6e8", + "c76ee48ee2f21221498ef39449d2db5188c1a9551187f3ec0f2ea6245c8f5eb0", + "c90da09748ea364acb48b3e1d72fce63db09fb6ef4f6f9810acf2f2dbe2d82ec", + "5e9acf215cc6bec31c3dd3ba23b78a6f4dfa5d9fd37fd934d745192e2bb057ee", + "0fa2e9eb4f23a2fe798d5e1ff178ea376206eba08af14c70c946fdc00c28bf90", + "f03c45b6f6754aa015d33a93dc8537e75b5a307d2178b072f6f601c54f020052", + "10f1b6af0d71c526620030781aa2947f817d0694110d1981ec0bec2b083513d1", + "d556903579ec6981889ca3886896554391cecab5bf8e5eecf1e2a455809e6d97", + "2a2d6ce865defd46f78cff7b829a6f9f5064e1e5cf56dbadccd420ec2b9cc66c", + "c4ba030b8c709f1354b7b4cbb34036a51f766cf6f37b4d1154a8ddd955899807", + "21c1e5b5ccc821f354fbc14dd3eef2d20133143daabddd84d11c5bc8c013c033", + "ab480f875f251d437e00b0f6a3cfa2cab4c2ea04e5db2dfe86b2939a40d99284", + "811558af974950fe01a469ddd1c3a6fba719c351550039a1e94b940be6c7252a", + "4b982112e4dabb372dee1fd94cbb1ad269eb8da9c1a0b6a5caecfa0d87cbb53c", + "d0d2dfb7f7e839654ef7a8ab988d37067229bbf74d048c39aec1aea413ee71c4", + "a2fa4ea579f43123d857b595f21569ae5e861c6311d6826501bf34c76dd66c3a", + "1110fa6e4323ebe2f126d79f13efbc37f5575a1bda70e5b6bcf265d6669ce3e0", + "461e86c7deeff76362a0c67f638350d4ca3f58c7134ee08dedd9b48511b450eb", + "dc95e2c6e5919d4cbc99f252cd66fb496719af381c5d4389ce92d2607a29e054", + "9f01ecdb99e8d0be8f8a6d4633020757d4d0cfec47fcba0146eec3913e9f94a1", + "972b7d679014f300e7df729361fa73cf9d6392a2885fe1fd6a1c1cda779e0124", + "cf285bbac5d60a62d75779bf66bbe4ee9f70ef20f6ccc24721b290c9784cb12c", + "6f636cc686e695627218827b773707c29d4f34f0ee367f10f548e16737055dcf", + "5afd033de7c4808e8e66471e24a61b923812ed0169377521f63b18707d88e098", + "d677c8fcf31db36d204d5203d64c865575ea7fad18f811fc39ce08a0c4a1793d", + "7190108701913b5baf8d31210df48a3d0cff2dcabb8dc789cd952704587ee624", + "3ae3c6e1598187b3f3529cc3a4de7b8774d3d96ae0ebd2045fe1d5d8ad372978", + "86f933fa3ff10bbdbca57478f7104fa33c10bc813c1153bea0fa842f2be7d0e5", + "4163c057f23f5f41fb6f5e717e698e34af7dbc668677d5b5459c9ef9831dc421", + "c55b526bedb4e42c435b6b21b031fe47bf4f3f08cc84569d296463f621f4d6f0", + "b84727540afd332cde8de390acd7939e8428963eaa5ef3a19ca7c9c8a5a3cbff", + "0a9578e9a7835a05149757e836ffda0928fe3b7d9c23689d75577f8c731dda66", + "ae9b5f307c2bfc86247b3b49dae78b2f15e6d5a65319e4acb28a55bdddb688cb", + "c1926e6fab4f5fc3f982d25912e539f34c8cbc3af3fa66d4a17ba5e2098e727b", + "d22ee7d4ba5fa4f90d46cefd67c0799aab59fe7fcc349771586e8cb84b444a96", + "93459c764ec70a9132244c4a17c934fbbd3eac4fc69183891569f0b0b434edde", + "e1e4aa35f64a535762de73e554cfa68b53e9d994c9941b7f6089c6745c4815aa", + "7863f90380e3937f9e9a593f1e6e418e58d10cc4ae3024b4351280f5077dbbae", + "03ebf6ae6e434fba02113ab5543abe312de4d58c488cc67f8612c1a01d49add5", + "3a6795c2c3f6bbe37ff757a40622d571450453edfcf3086296aecbbb6eeebb1c", + "f7b0a7f4b4b44045efdc5c31eb877ef5659b71ad344bd05abd925ddc41f724ac", + "c486c26ac90236395572f97b3f908405f961c28e4971ad1410526e6d995f14d4", + "10cf1408c32a50e1a4156dad663613bb3deee3afad0d07482820045fa1711efa", + "d695911b016bf775798c0d4ffc72cc9049437c2348c807a55b17670291a645e3", + "aa614f766513a1fc5187d84a931ee26572e6bf18aaa64e67366b5421aa5171b1", + "e033428d6d3a4bedbb1bb55e01eff3ac470a1efdd53b5046ba6ddd1ba846cda1", + "597c0b71f618681b177e08e367a6cbff955b093ce2867b55fc3919911149e6e8", + "113d56221a14314684c27c1a9e6f0523758408223664d600e5ec4f06a754fb3d", + "ab832dcf19421a08ad7a865050b75711f0a0854f7991d245ea9a2163ff35502a", + "49715fbbc9c9dff47065f4542bbbfd36eaf5a7a68d3bb41f5189177cc907ba1b", + "4ac21782d2e016634ba64d16c255511bd2e9773d83769664ee7fa646a835b1b6", + "d548609d4bc4c5b73c293aee5d8a54b27b2b319a3235922e49beeb4d64511399", + "cc59db9641ef34e6986ccb217b491100746ce9d84de0d6b5fefccc05e0900128", + "741672373f9ed8c136fa1686264d60476177b57d2c5f0d18c9ceba15cb0fb669", + "7063900501c7e42dfeea0dac0b9620d18aca80cfb5b1fa1f929493ddff44a684", + "0527a750384f4b476bfbd0253d2280d148ddbd68974b80b89d18bc3c3d170ff5", + "5cadb8c145e16bbb16eafe010463fd210a4f99b4c8db58d080c0520c00453e9d", + "3ad7d1cef9dfd4bfc72f5bbaaa74a65f8e17a595ff5b79ca0005abb224cf45f0", + "542efe2f29d47df0003a91564921d9d4ce01b90ce7a0b782b3e34f94c3a20b9b", + "85cae98760bd8ca6444feeb70ededee1cc41d22afa5a47e818f7229db7f11f38", + "8f4641956e86019030846668e25d56df769a21b901956261fbf61079177ac4c1", + "f377edeba761a4bd7e6f1f05f9cfed60430ec177513496162e32dc2bdd88ed58", + "5010a2705bdb9bd0fa8f020cec66a3194ad7baabfab15e6be14171b27768019f", + "32757e7fb10bdf3c8c744d602a3b53d570aaca6b8164af320115de7c006f792a", + "a8b202fb6cb3f611b1e2682e6d2b417bede642d94f74d66e76e6c55b55aa9809", + "8ab441aaabcc55bb9bf35adbb1289cf27486cd7900d63996cf77cddc87be94f4", + "ed824d3b81d98048562a63a8b6fd85c5e2f23092190be993b36bba723d56ec0c", + "a5ac82dcdd63de6fdd9d7a11c5cbd8fcb639e7caf14596cba1fcbef03868be3f", + "12622b7769d6c7d5ef1ce58d952e9c049d17e0bebbe676ea807194710ff630b2", + "ce26aa2b0c30b8f0ab6574e63611061f2f8fc36bf5f54ef0b098911124398c6d", + "60ddfeae77e513ab8c584bd3d5efefcc653f9a4ef9a4f11e84434bc9ffe571bd", + "520b7b949bcde922245aa30fe1c10a5fdf2098dc52d8bda92302616e8732d1b1", + "f55ea6cc2432f15eb25db035446f1f2119f139354f8bf1cc5226e62109f50d7e", + "cd5e1b4255de61c92b7a24b59a083129bd6fa396c764f113381b8e212b0da8ae", + "2c1dad08f6360fa2575e5ed4bedcf833f4e1ede2cfb565dd65be13fe0750f57f", + "c4cdcb8833b7b6534956f335c0dae64cc90a07032e64779c2f58c5b5d28f63b9", + "960f6a2f8dc6ceac1b404bbcd54cfa82306134daf72db6985ee797e224d8e5e2", + "91e0714d95f31951e25961e62e234dd4b9210d737101abf349b1e2848bbab1c4", + "191b75716c96cbd3773b566b7f3561de9ac3d9df88893b450a090645d45de998", + "32300910a0df019f966f41c7fa0b28b8f044e5d34a71933c039b2277d4874063", + "fcac95d38bb87a46c9e80186bc22a35444cc61c6b5a82a47e767651d0a953a96", + "2020bebca9b51f6d84763584df5f5935b36be130fa051cfc922c8aaea3a42889", + "b316a7f9d07dbc479b19cef7b590114284aedf17c9988f8b2db2c21f7bfb7974", + "f7498503447cf07fcdcc788bf013d1fac88b3b3766ad241d31e3edb656f546e4", + "37250263a849d7a4bf688fb9521c4906097efa3124937ea39c2dcf0d0c9f3a38", + "3cde8c79a00f8c9f834fbd2bbab84b04fefcf276e751a04a4798347f38f5a78a", + "e70c00eaf6586e245b878fc6ad9977a4ff781977e498d52bb2c76d6a79744f37", + "7f1e22697fbec5bc939b6631efd24b9a68d8ddcdfe3e5e6dba15eab75770ec83", + "5f5a2586d251e4f907cdb01fb4024c6d71a7c3cb20421d64c5e122069ecae05c", + "4e9c132c5bfc2428e237e9b4861a993eeb264e8b53685c6457109314e45f3f2b", + "836ce2a2e70d84fbe311f78cb7eedf7553eec388b13860fa9dad837a67338b39", + "e8759f82d8b7d1ba81b4240dda5a227a72c69dbd9fa92a3f2095ebf1c0883aed", + "ded7b9bc33ca87a75f479bf19f8cc241cefd03d8a841b54c76e3ba07ffc63ee9", + "3f8786d10e67a408324860b22b148dfc40fe4878f12d066174d74b37a3b24906", + "b70a778f57947b50817c61385f00de2cb2fa34063843b759854e0d25f8460305", + "2d74a4a40aeabcc94e12d69f227561f06791fddda83f260bded00d7c64918081", + "73d7d5e024430af75999f2b7cf801a1198d1aefa25bb512a09291423600ccdfd", + "91e58f6eac5f8c04fb7e8ec2c4e700a987ade2d9007eb6482f18cfe2c8df875f", + "386b4fbe549031804aa06e3f98494d7a3aa5a2bd11fbc7c729b1f534e81ba33a", + "657810e6d31ca8387026be38225ee625835da3167a4c56767fab3a735b8f6b44", + "3091363d13dde290f7286f310111410bab6e2a0b507ede130b10b2d68ca3498f", + "149b050fb332e4c1efe47acebd253c4a738b8cb6986a7c0c51714b3effe1ec9f", + "a8165c5e0e71dcf7fff9ca4c31441931ba45eef3d12467f88c86c864e583f245", + "590375c79a285440f699e9eb11d6d706ee6ed68fa4de753631258cab33fccea1", + "4a66227736d083f8a183ba00d14457eb9ee1282078c493a4723765495be6fa29", + "b2571cbfdea18613687ccaa56a9660e222b1ba7bbe3c05741d2b3ae68f3a963c", + "5e1df119044856d6567f7e573f3b56ae6040d70805b56de25e004a2d894a0193", + "624c3a562ac8fc92850bd8301e61e270a97780b016351026731f8cc65e073948", + "b0497ea80dd85e4b937ad45f3e556b6f340557830b58f1bdbdfe40b91e6807a9", + "3496707fc73cea2da3ecaf9c64185ba6b1257e79908cf6efc07918c8299e83ae", + "b5b439ac73e347d64f6d3cb317d968aec58065874e0382df1ba5ff4064659edc", + "442c2b8ce340d01c22a036937e145b98e3024cbb87b6eda0554dbf6d8ef134a3", + "78ac7d07a2da4643cc6d3014177c8f061e0b97214b36a6f1db5f3dae3f04d28e", + "a998d27c8fa35ec56781248a9d46bb02ee190ea956448687ae2c0a4508664dc8", + "cc2eed5bb90c4a5080e11a4b1ce528595fb24bd3df12b123e29af4935de5245b", + "c2c37b4e06417e618729298db0caa056818c25d4a6db35810f3948d1ad67aa10", + "73efd0b1802fdd96f4c251c73d76ea5098223b1a382e43080dc277735422c2b4", + "f46f97bed2e7443019ff1dd32a315af730a5be16f83a775245ed350d7ea16b94", + "717b21510926b81e5bc6d1749a46ba3f5d11d2c59f4ff6ac8d35475a29ecbcfb", + "2ceaf28182abed2e71483a3fe7fa99088cdf106355430e224ee19ae65bb839bd", + "460f6be069d4df1201c807f3ac67c35baf4c0a8d440774811b393e925028f749", + "ccc606f47ef516e89e75d6f2cf3ec1d32996da8794516fc49247c99219581ef1", + "abc7beecb7224d428b0ed0d4b50a06782ef4172261b4b78525d2f79a1d93b8f3", + "dd887b37fe3f06dbe6a4a1a8edf04b12022c4318fa75766e490f1afd7f449aa5", + "6b30084f42a010a4af31715b052db7e15dfd793b71f7376fdf24b2816a0c789d", + "2551ad6f5622f0b225c19caf8a7890ad1e763d456267e6de08c6db7fb7d26b53", + "807e8a665a4a56aa8f8d01a4f6ad10d5aaab7d315a62bba1c9f8c7e55a5769d0", + "49be183806eb70560370993553e3d980557fff7f2248d4b357b427e7b0c3c9ed", + "f1cd0203abb09406f544cd994e70fb53cca2d00d8daaeb928fe97f92c33df49b", + "4eca416e11bd866878e763b2509e18ae1565b81beede53c5508462682a643f6d", + "6daaf0779acef1459d052ca06e9c9e7ea324bce9ec7362b9551dc371d29285b0", + "d9007a6ce98a988edd05d0b3febb94e28534e09b0f4446d278e00651d9f08470", + "3024683a90b64eff593180b01a068ae038b0436f1d1ee949f32eb13f81a3aa58", + "76a797cf5e19d3ae21148575ef1be8869fdfaaaf19964bdd4f4bb767e20f1268", + "617c0b8c9c94f2e3c2ec19836ff938d6d2d89fcda54c8261f6c6c9dad60de57a", + "9772084beb4b24583dc550dbc3aaddaf541c4f058f09f791e4531103f0421ff8", + "19d1838ba4f79c8f0dd31c4bd7d181f3d602397d100d1c0d2c944b036853d369", + "17bf63687c5e69aa3568813c060136aedcbfcbd57ff7a665f4e443a9a3b4dbd5", + "1d6d424eec816d7d6b11b1f39c896e937abbbeceb29eed22f311591708085f73", + "10b73c7c9114f7ea82576f6f46cc76f32204e26069cc6590ad312cebc83464df", + "7bfe6de3c2e1592b5b109ed918796590ca61fae55bdb741996bf7f9c9cc23302", + "cb1b3b352ad65ce346342a8af70aca0fcfe4ee23bdfd6f8afd3fe7783982dede", + "62cdb6d4db1c10e1cf7f451dfe04537416341ae580edc7a99dc0989a172e317f", + "02bcf2eb174508f1562128a43e8155ebc4e56ba988fc3d246691b258e85fbd4f", + "b85d876d34b8d821c5296f27758f7b879c69aa1304f04084426c399c41bbc7aa", + "27b45b043694184921eff99f92fa9bca1bbb5b8b0a9dc79a91011eb9185e4982", + "dc60a7b484b56f40334e6ac8ef3851d31c180eb73766341605e4f1f090374510", + "1681eafea059ad4f4746f02f29f8882add2d69ae7bb1b4eea8b89990653a03a9", + "902d76132d99bf2f303bd19f57d8fa9f8e3d21b6d69ecf128e3d1a7c57ef044c", + "3d33d02d703a51b70beaf3f18d03a80c35cd81d03a0e218eb141082d7ce7d4d0", + "5e718a364321710813768beb40d0ce1c6469ffb155a6895ef56cb2d9ad2ac9fc", + "a0d8b442fe91e69b935f711031fba1d374872d8414efcf96c84d5f46ab3d27a9", + "2268f8f4550b1a14c3ba78f555e95c77c351bb3ab4b696127c32e22954790505", + "3d4b11b3f092f1102f185ef09acc73bfa3fd57e9e1faa20e51c772526f098fa9", + "543ca8962383c78859ee081499532efe226072124d5a78e7cc038b76b1c846db", + "e5a2f76ab45b0fece8b93a5dd6dc920e31bca1499ff269bac6d08552eca334c0", + "ecc48602081b754942174b2b022956e8567e3241fac4709e73f8c8897b128c0a", + "3d96d28c29698d47d23b3e353ae5f1acb06c43eeb8da356550ab37355de3e4a2", + "eb4663f2c68f172499401daefeadaf78983a555f9d9b7bd9dedec3fab056ae0e", + "9b333013736746c0cf88866eab61abc33664cd0e4f884e3fbcafa895fa05788b", + "c9125773a58d2262f77a5584bc82e3ccafdc4b1da55b5f845c62a99674b5108b", + "06a509900891bf422999cfbad434ddf802ca9868e9e0b1403c305da7c4d879ab", + "1f6e0b1ae3f0a2303753ff3ba9f304a42dbbf5ead6c006bf4ee73c9cfef4d5c7", + "026605a56f7ac65bbe0c8aeeb918887351407ccc4a7ac08bcd63ee3da2910c84", + "8643f6cfe05c970f3c535dc501ebed7825ef7aa1d11672f01564169d0ac4139c", + "5fdfa29be4474123a388e5a79ea0455520b04ff31fbad9c16499b871710a4674", + "0e87ff109c92921e3a637c6883fc2f7ed7e7a3198d7ba0a7370d01ef6c91324c", + "49d5d7b28ec66a24f09fbb185decb0a279867c99946285cef81b728b84040d37", + "1cf9696c2471208e172104ce5c64e3d78e84f547c5dc0146037247cde02a7015", + "8afaceae75285c49e440ea87295fbe02e99d28949f4e1b6247e778ada9db5b7f", + "d48d8342a372c4ae5f81a339e3f9c58075c7d3ce178cfde223bf452e8a082707", + "80729c468dee0337544219989d1f4f74851c08e31474025cfe7c217ae03f588b", + "a25b56edaae3a0ab8fa6ddeb708ca31711ada9b7b8d615519f62d5737fa337fa", + "71818a59dd3510335241477bedf1e565bd13d19bc0382995703aa8de9e2c7ebb", + "38084b550ae963bba7356ff2ba41798dd5da698c02022e7a83ab5aadcf830c1e", + "9c89e5585c6cf9ea3236b0a2649cc5f66984ac9c9e5632b8b164a155108dbe71", + "bef8201d7a8b2423b60f9673fce5de9a6fcffa3ad63f105c6d7b893e961ae3c8", + "2fa31fabd2d9d4e4be9ca620674d9e16fa1be525866bf924076de42e9a0c2560", + "864b5ea6b259c59acfa7bf5f7490954ae8072739f78c549aee2ad6543db668cf", + "20a6f778674ec7401031d39120b6cfec157585a12ded12fd3a4d5218641d5c35", + "24f003e77e51abd3d3f524c98e98c882e0d1c3d0775af8bafea30d50a43c895a", + "fb3f7c35f007a0f62b419d953a40b8f216fae2240ad1c1c4a66b4c606efe3044", + "234134aecb9271f82a74f5ce8ee217da349dce9676aafcea29b0b188e343b40c", + "1207bfeec729a8cd0bb898d39dc22dbd16b175d101fbc1c0a17b5c968e41741e", + "267f04f102e2ed2957c047e04cb089b603a64c06e771ceb6e35ad93b9997351c", + "f198c248cf0ba9a44ce05b48264f274a4014a9b8ec94e4ac9ef61afe38d249da", + "3daca57101f4007af0b5be8a40cba7d0037b05a2b9ef9a34782ea4aa16a934a6", + "12d484fe4ce930c3cca2d050acfa5999a0c2ad9a4aa71ed433074d6a6922ef02", + "262438c275c9ad7268c57fda1c201e19353b35166e1a0221d9a54ae1aa6dade9", + "402a402f28e3dbb4462a5f7786441298d84283dfda85a6f853bbcd82ea06d268", + "af25021f1b9812c3e637ec6d08d6b993ca6ac93e36b33d6d7a49d07218fa146b", + "05a0eb61372b71dd75121ebe9d8e1a944841ebe4f007c438f321df314e9f2f98", + "0afbb8aab922939911737abe8d3fad8668f9492ef7b129567155c492ecc60c5b", + "17d7979181b83ccd15acc583af03968fa496321a080399121dd737c40b0303ad", + "bf45b451aed941407076198d1667327575d5152c3e93870704c84a67fbc9b65c", + "91ba219e9caca1402b2e582094535878e14dc48a6546bc68411adcab1bcdceed", + "42965233c49530f7e866709933252280aa930946c355afd4544d662d3cc86e1e", + "d70c433ec832059879f2a34726ae91f1cbd8ce9eed8ccf2716f92f98a88b6cc5", + "582b8e1837c9d95b764d0b385167b5bf63c64f4bb698934fcdcdce9b5284cd80", + "6bfa47c4f83e840f61cc0f54cdafcada9586cde26c8466abeb16f35bd4ee3706", + "8f16ddf44bf33a5b69a7e7d3cdd7e82f62f7cefb6dddc9ff93cf91fb1d35bf3c", + "ad085b5e9411a6f9bf2aad725b6f54cac2f612528aacb788863b1cc8d754e40e", + "84a4f014c9b372561b21ea324a10fba212ee08206e709b647034dd3a86a2aad9", + "e8ebb7292c02b11226edf2156f14fd312aa3d4778da3b3f3557402d22a3a6afb", + "609399ae61c35848493f1a96d991139c0261412973fba1b5d705c686d4ecf5b3", + "cc0281cdf0c05f58411da69389f76502b4ac857c80d88f3f4fae424289d13dc9", + "9c7a5239ac6f08029f50adda1a87319f89aceb927be4f8aba20b14c057fa5ab6", + "94acaf4b164811766c7c386f4346af9e81fc0024ae0a33652e581cf0c68121d5", + "2a4dec8b1c1ae71a030e288d50aac949a7819edd948349195066737c83cff364", + "bdfca0f268a1caf5735bcf892e4f3daceaec30d6dc520b49c5aa7a215e500fae", + "a81de97a9c532e86d02f68577a3f82134489198d94996880a0fbd8ccb34a158c", + "21b155f1734cde6917da897a233e8ee6f6a9e3a63c5760715c718fb4e5ab0762", + "87fe4c592839715adb2d8b9d9169d5c2f5b0497ba2be4642ba64e8ceafbb57b8", + "96d9c0acb73c29f33cfe4d64a931dbbbe3e618eb1c219cb5f50a90249b20cbf6", + "022c4805291fb5fca6ade4dfae4870dce2831cd3314670780efafd07d4769f20", + "d153a001dded91bf7ae40af6cda3d13e9db70200199353af62f0720ca94a961d", + "3948ae57630020be5feae9abc4bc07719b0f07cb63cc09f328da302c4d79e502", + "e0dccf975ccf3aac14311c9ec1966ea734c9722d9352a4c1864253983030f3e2", + "ca430fec8817c87da7963af097881e47f829f7037e7c14d15939f70dd58ee307", + "121506b09984b8e7f0fd5aae71cb51e22276d3ad391fb611279c9948c8c35564", + "9fd195c4220718504338cb16b82738fc58e903b34476e2430f089ab6e4b58f31", + "19692f3106b2d3c71cd07c78b13094434013189da113c9aa2808cd529b05af59", + "7d2b1741c561c71f42c77414ef8dd9908e2f05534c3e4ce9fd61a5d70aa71e80", + "43facf2b65192b52f45f6c97b915a5e7b3e8dcef0e9f28d5efdcfb77fe7a06fe", + "6ef24e139e4f8152f3fd0a4e728b8d556640d964b53210eaf14b41741a9a5d68", + "33b183426df9dbaae79488bc95352a0b720fc0ffdfe5c9502203b7b4f3db988d", + "04121520c8f8d62cfb2c5c6cfc5663a8d4187eb477fbdbf2b21cbee8b8ae49bf", + "49b3d540abc5f0223c2ec5eec00baab105a63905f3b500c680cd72131bfae39e", + "d9b82fccef531768bffdcc55f02da90e767636bb4deb94f24767e741c6bcccd2", + "6677b1195fe0d265450746107f1968490ea0c9c1d24546995b32ae6f12a3e1ff", + "6a8c630a128dcd1933f26cc443612c9b49cfd0b23a1d87495b0193ede0f74250", + "975cbaa917164dd099808b6dbb831fd339f69a23c7b9119280e3e8eaca39823e", + "5ed359824f504464c95c10ec89b241acd1cd4d2efcfc1b66464008fe6a513c66", + "02edc0acb4b2e6262fd83728a3337f8e6e947e9ec8aabf9e5910875e9e9386d2", + "2f2c2a2224c01b14cc9f8adfe1b6148330e954d9c975eb6314ec8a7e5ab839a0", + "cbfd78e2a2afd7464e8fb67cc2c65d4aa0fd3b055cbe9e93ed30234a219b13b0", + "34f9efbb4e30de1af8d755ed76dbbab9d97494d265f2f0e9aa10f8203312e06b", + "583af64a21463eb059fbae7f8611e85237c1923c0da13c2e5c8e7a89f6763436", + "cbdeb667599579aaca42686dff5f4d66eb2a63771d51d67bcae2edbd763d9829", + "5971e5eb13d9538f66f3684ccec493956b547eaf63fb24a3b06d39c2bd8f1e7a", + "6f00bbc9ca110cc4c0f75694964cb449585f467bd6d1638492dce95a69138c91", + "491152810a178f01559010aff9f79a0567b9799b332ac87906cb5bd6ed6df7a2", + "c058499cd555c60898fb39d8a3afca43d950c1984e868d9a24f255398ece3121", + "ae5ea1d96c94fb01d59bdbd64738a58ac15bc876ffa39bc3f996fd8f296d3d2f", + "d61a0497850d2e2c52072de500676bbff65cbdfa129809640d1b44cce5c375e8", + "408972c3ba0049c8030355621cd3ab93386347ee3c6dcbf0732f199a788b1b42", + "032255601ea67a657f3d0f4da4fc4f2353dccf3d5bbc817f8df29209096d22e3", + "e39ce7cc05a582baf5a91ecef9568c60f163b23e3a18d7d840ccdcacc3ca135d", + "4257a1a8df7b7922c78c89e67a7ad74f0b98c74489056f16ce2ca22c1030da38", + "c7a367d00f966fc8436da3de15d0d0c2a41945abc3047b9f014540cd1f11cc53", + "2eb8d1d092c1f38520d02ea3da0d522f82b437352e8f236f8ada8fd5f6085421", + "94c5cda31faec88dbed38d25bb624ad1774ac842187e6d2ff23116354cbf0b85", + "2bb83a7ca99a61d4adafb16487f4e659558d94059d47d96683cf69d6ef03db88", + "71414b8d951e98ec4451ea4311ab5a1e7df8f113c99465678cc7ea5369002c99", + "6d7bfb836c5cdc5596fe007358f4ec0ec3d3a767313a2fd305bad33a1387c228", + "f0c793adb98b912b9fc9b7b281fb245f99e75a1d74f521b9d9f1be643de8ff8f", + "0049de4dc695e4eed44a491fbb0f365af1f7172ffdff40f4e1774a33d01de170", + "4b8a8e2ffa036395767978ef4907079484c37264eb6f6edcbb78a33fd980ca9b", + "078f524ceac8760557cc8ce5c91cd486b390c4e7f75ae6218556282f0702a7f4", + "a8c1175e0f06cb9d38f3048166ba1c4a557f64465eb0dd277c0b70cbd4111ea2", + "71131dfb9ccadd90a45ee9d278408548132aaab426c9c34e61d1adc17cacbc44", + "0695b0de309a2e68745d1a026e77c8bca119d59f081f88ec66264483713d9be5", + "5e511d76eb856325ed379fa843f9bf8131a7f9f244062d3e0671fac69d6346e3", + "26cec41ff047e9548fd0af6b2334c5c916f9ad16f6a4d7851ad93ef7624e373a", + "bfc4af97abd5679d80c3e4dd4d647b0c7b3bb469e1de51d8eb31e6ada592cdec", + "bd93bf829750c81d31f46154293ae554dfb1d57e07ecb45bf77fd650588dd482", + "e57568910eea0c23f50ee84a088ff838e46386af987925a922ebedd1f6395a99", + "ec86b0fa55e390833a9ebcacb62997980cc16e0c2aa56bcc4abc7b537b09b1ab", + "f44e061db072dcfbbee7a1ff3746fca9bc5ddaf75a2ffea281bcfae9216b8970", + "38f6b19c67d475dd4879bbf355c74fee72f4669b69e56702572498012a8e3bc5", + "1615d438ce78aabe324d32644a51da8ff8150d955e63c098884d4f2fd4521c58", + "c60e12248d83884d1bbb27ffcea4f6fded702b2726d2aee314d821a18cb2b952", + "e50fa21a223b11f0462ad1105df4a5e80baf9539c8aa41154ef18812b4528899", + "c8ae4f843d23b88a4de0bf867b0c3a80d60aea76f53836dcb30ecf6b420581c3", + "1b6b3be7602881e0ae43162d094d1cbe2e1e6f0a07d0f69ff9dbbda1a4cbbd21", + "8b97d03bd1657f945d62a6564de882d1d25e918218a4b7039bcabe3e0f220ed1", + "f548b51d881c311a046bc1e8b83458701fa0074743d0c24bdcc898dd5e443363", + "550c18aaa70947a6e913e0058bbb39791c52ce7584c4475fcc1ea29397d6f72c", + "0fafebaea9e253e56ef696a244217a796c1270c1b16a79a50f3d15ac9ddabcc2", + "4c1f2cb29a0673847d07816829180af7769155e4575d77c2eee15c38c3661115", + "bec8f8934f9a8ea04c65f0bef4fe4a63f9725544652ebd29c91ad6edd0b6d944", + "cd61189f9901ea951d2d96dd38ad938cf79562ad002201747093b4d9fd0c9d64", + "d9999e1aee5756fe3f5f513cc3d6c8ee92462426507f311c61ebf20e6188e548", + "b3344d4cf2c2c8a550e7ace7052c97d76352b812f689fa48cedaf7ed6e88f9e2", + "e84f957c80bf4076468305faad2e3a7655ceb5b128498ed2206fbc8245afaa0f", + "e8ec76a7507a0055d62f2cec9cb87c34b6008c51c2a94a8daf1d2741923ce27d", + "6d6997045b532edb42f600ceb4332afa757b5ce0634601905c96140aed625e7a", + "b3dac5083fa989670055049d853f8f317e548394b79722b026346917739c784e", + "d928ad3bd54594b618692ee26f3eb9b6478cf05eaacff6c05f3dad9eddac9280", + "384915e4dbb3efd8a7cca15cff2ca127725cbf065433c16dd7bd5e6a92dff4e9", + "f213f593a65b91ebb86d8ff580271561c9e5f6d63f30830f8333b177c1015a08", + "7380190040969344b3124a14127480f4366bc15839240ebeb4ed9612bd40576b", + "e1aa67d2f57b37b58c0646c2a16cc9cf9605841c243d13ec2e7ca6bdcdad9322", + "95f9764c34ee45264a27e697184665aa2e9cfa6a70162a4f64916aa0d4af464a", + "fea911cf35de23d6934201ed7e7cfa5208bd46380bf525aa821ab6ebebed5fa3", + "69856a747150a16950b5d82510cfc1d14aa8a9a3056013935f698d17de36cc2d", + "4522f9b5e4e54694e4238f7628a06d06d8a114b1831d6b22cb2d771a3c604e50", + "3cd6d7c27a92e99d6fe24b6d12f8f5a40c69fe70b1d36e8c0f4a385b780f1c11", + "86d3c71506995c8995150ecd2a9d91c0cae49e94a25e6c3d86a1f3f1b885a0bf", + "9b0f07f9ae650435ad5d24daffe2fc0d22b33dd397c62c60d3cab049549d3f4f", + "3ff9a4c487c36f437ff674b8905c6ded21c24d49551dd6fb21b7db5dffcbef4d", + "e85ea2370e0cc53c9ab15ef14d66c44363492d3f607e3c188bf90d35f3e957e3", + "679a30beb269a80abf240c50c587e390b0f6190155fbed698bb726bf81ffa0e2", + "25706c54723c0f52faea573b43835fea7a6ffccf9bfbca511f823c9916c3e733", + "a33097cb24a5add8f423c31c6489a01f3bb5775481cb5ad32c97c6591aa9edaf", + "7833a1db1aa9d9e83b6fd121e15b12c31814c6368ee003653921568fe3683855", + "1385439d84ed7ba39bc97f323a5a6ffa135a3fd3a2b64c9be95f6a4cc05fa1fc", + "20ccf772a11c0fdf2ad59b4602446d87e43e82fb1f73e54cb2ee7ffd8e37fe1d", + "7c78ebe589f03c4bfd100937a7fe0a5adb5ada61f0a67c03ae633d10f7823846", + "3b4232e79184dccb5dd3f8180e269df0b2c9f9a18441f980c3e576570f591693", + "d89bc6ae5e02bda238103bacbaaee93c9327216ce9bb17db9236c1b84933c9b7", + "27c3350caf9728a7dd8df16755808b46f258a34f0e90b078542cea5f8e6a5b14", + "7fd95facf48bbe93b8a230d922db7646b146f15c437246f6b732ebbe66d0ad97", + "666e3bb9a029f73c43996a4edb810032b5176e4be6cc029e2613562c7e530dd5", + "a8f01608f1ddd393845a8d72609e2be62b0898a00e3c86f8ddb9d3b05c432269", + "212c56230882759bffa4245fa3fb188be89b1b486381fe6d83785bd3e1a72bc8", + "7d254091260185874f1b45a58a9c592b336388ad8a876d2b24b78ac0d046db93", + "747d684201c6634ed3b7f067b7da65eae1971601113ddcb594aaa1ef1e89a408", + "1276dd5adf86508030510f8e4bb4588b89883142cff5ff13383396d632404460", + "53dbf97a7831edfeb124f72938df3bd16838ee7b8e60fc21b33b7da915d03ea6", + "f3fac835308b085d77cb29ae94246a11b74c93438993e76b0901ad6ac75868e7", + "e93794e073f6644558d345a9fd975228e991f9c302418a508a38ceb543aa1f83", + "c87963a28a3f6968d16728ffed733a6e63f2678cecc98a8a74aaf08c186c4894", + "996600c4d1955ffec182e37980a79065a9f2a9ff0bec82f8b77a88c783abfafb", + "252afd2b8eaf8cb6e35cdc7beb934aa7baf709b124738d09f225e042eedb9497", + "674f8884d3085537972f92d360eafe27a0a5361576e769ca6d3d08ea9c086ffc", + "3efcb1b78d50e4e9bbc00e4bee70865c7e14eda0f2d8eaf1a6188bd78c598b98", + "cfe1853580ef9d021573e5e7dc9f498307b5d57b4f456a997dd7336788ace17c", + "269e992c95fe77ea634ee2e5dd227e063f54f1c4964d1e4728199c0741479585", + "c16a88ecdf1d2e2cdf4fbe4f55bc91fb4330290a3520a16951aeded70e6d4084", + "88ef86ca834693f3ff8807efd8f6c75b9d49620253f39648b801cea36fd40e7a", + "11c3314c35bb987ceee5186a6957737f69439158846bafe9ddafa1a5a5ef822c", + "4bee5ff612983d0815c5f3ef532c01e396a8ae27df69fd4b27588a2a2fabf0fd", + "e203341a0b679964410e66037bb22b3a8ccc3cb6c63f4c713640e0af737c562f", + "26d6b95872071d59089eb0989fcea6a157501dd813a988ae84b6f9b3ab967f74", + "e40017e9236d82736ea80a0e137fd13d5a3a1b3b054e62ccb9036bbc88060ef8", + "2df2985e235740fe04640c2fcdbc370baa0654086593d637de2638d6b114f521", + "5944701f5935ab7a58e2ec032e1c40204d7f190bf3d4b8aefc2c2c1694ba2d58", + "5834933d1df43c9a453b3d7db2bbb48c1e019daa197c20e4d4776d962ca003c2", + "0392a70a12b9b58ac243a9ed22f6367f358c72b24357981dbbb39b8b66f7a026", + "afc064700e6ee837a9a4cfea1a07f427fc33d2946858b1a22789db88d3df1c33", + "9db2feb14b7407d5725cfb7bd25646f8e424bd8a870f28d753a944dec7abe2f5", + "678b844b8849f0b9f5c2c712b9bf6e76b6bd27f9c8f3be19fed41df8d97406b6", + "ba85a94234461ecbf1f596a51fd24af2d1e4118735df6415de3623439e83ace2", + "6549878adecc0c459feef6de69ed4eaa8eaebd595d67f9a66026fb6faa503299", + "71ac8e5b60ae3dfc0d4590c0155a7257ddef22e5368d259ab7f0b24ae4c2392d", + "b2741d3cbf8b21a49f983402e52edd93ca78acdd905f61dee00cf569138cbe74", + "1b015898faefe1f3b42980e9c399158318e869db6023d9c4a9acf0fb9973c3d1", + "32feeef8a393f9d9a8fa314213eb811c01fe3d5271a330cc0c3368064a323564", + "ac30a1cedc17bbd0dc16c120bccd28587809cfb55026039e13921af335b0c180", + "b5503adde1065a9e9b3863b37830ee4e0c2110d047b9433e545cc1e70f14efc6", + "49ed2b5634bd6f315b0ebd284562f5fb723a7df04316bc9fde1a38645cade923", + "dabf4af0cc5d06597970128f6ef4710ea2c0a2df62588016a87fce5178915ba0", + "336554b72d47724b040130aec880ab6d94a0bdb8a07d5d1d3fac870119e5f5db", + "4fd3b08a08401e36268002481a78eabddd2731491f721b35d090c8c8a9d841e0", + "b6d7796007627158dffb02eb74ac05d6da83bce2f7501de065b0b9f64d50fbaa", + "a19d8683fbd94f08a0d8f7a8a90dbddcf04ed31007e7d558166cea9a44eda4ec", + "aee071913da04e4b2b0ab7a102399ac4596da13c4ef5cbea97856efa1a0b5b31", + "af4f722242fabb0a0b8b2c715426f8396032f111a9818eee3cb15b0377238df1", + "909a8984dd8901d6ea77b863982ebf873d4142d73ef48836c6ebd154630d9038", + "dcad5189070d2cdbfc249f4207767dcb8a9d29fe06c4ef24c33a6e2e4a0fef10", + "0b1ca8998bfd26bda4ef907806a4e3a70ef34fee17c435940862a6f9c94ff949", + "3fc00727dab5efc6b3d77cac462e875e62d79ea997474fbe7a4dd47ecd2b4e00", + "85916af9bd99b6feaed758b3044b3094dd49c2051ceffb95485ae1bb27857bbf", + "fcbb05d9a0ef181199e54beeaf86ad80d1fe0adfa7dcd0f8d0ca4f068a51fb63", + "04ac34b25916b13a236a8ce93e93a9db5d307adeede64eef964cf70dd94a56dd", + "359833170f75ce7fec074bda8759e484419e967daf1447bd4ced725537b514f0", + "39b34e92678fc91f41c219061d5d594b65501d5ae93c9bab3aa26abd45206152", + "539f4abed4636ebdbfd8f8d09dcb8f39c064eb294d6462e203d5400e02489bb8", + "2e07c87d345f313165ea82bbeb35f55215cdd3de60f1f1d3bfd69b11b20c02aa", + "52914a79c06f30ea3a5495be859121553a0bc68804d4f9f4b9a7a05f5e98b9e8", + "89ea793c84414150eab020e78950327767a5e0980129283efe086889c8c3a2ff", + "05c77250cae44821eccaf87e6daaec4fab39c2ec46ec5f6cf2eba7efb1874de2", + "16071bc10921d770d861f7058bbddb9ab28b5ad88a9f980dfc851ee3ddf20ce2", + "8f97f6bebc9f7824aeb6a8c4c8521f7aa2cfc330ddb6050f05e1dcaaaf22c369", + "2eaed0ec050803a1181c4e4a90955ac860eaef669ceb30765fdcfb7bbef8d479", + "8d91f0f55f2988e7ed3a3325cad51283f42a8d1763d0b993fb6251f5a3dca628", + "abc4dd650f334d35b5bd0f9b4738a872393b078a4002742b601a73c9e5caa7f8", + "cbab93c9bb162485b408e074c9af56e08a64f20a94a0d60e717bbd57271cefbe", + "8524ee227c4ebb77ba5495e44927779a05f2f83defa7618b4f779b9e0386ee93", + "845c7705c2b40b12bf77241386a74965805e9b682f15ac6bc7bd571b9214fdc1", + "b66c75af322eee06623d1c527bbd35097430bafe89424aabab0461ee1b8e2f59", + "4eda6860c68892562c08fc1d41fed27fd3e5c019bdf8889a7cab447505f30144", + "7f3c6584041c6cb2530f6f72cf2a306a34a55aa69318c0e9dceb10c3b89d3ff0", + "8c8110a4ac34deb23b1a14e49047b811273341db64287afcfec0b6bb81aa2fc7", + "b02ca570d6a0f78e48268c76a8133549f473014505c0beea902662890304525a", + "73a56a38098b54b664a7040e60ac79f7a2b1479323ef4be373c802229a512df7", + "33b1b1d000bdf086d852a7a4b74fe15c689aab394fd5ffd7e5d8de50fe63d9fa", + "976ad7147f181078d884801bd5c3db598aea41c7ff66962ede337019505dd021", + "eaedfc9e5703bf41e2f52e306ee28afe72a0e8a1fd5aba387bf91f57117f9d67", + "cdd9407bf4426a27a685a9704d86b23ee8c2d953165eddd69b0ee5f5696d3656", + "3f35da84b664fe0f087c52a0ddd18fed1eaa2f13738fb8c70fef6f80d26b10b6", + "36b58f36ddca46848ea7184c626c9b2e96036a5d2088a022b944bba60bed5d2e", + "05c15a5fbfce75a691e525a980f8a9d2a363836234e14ea7b7b3c5b2e7d20fdb", + "4a03363b46695492bfc92b308fbd97c5fca888a4cd716b9aef24024886717f36", + "525934d632a5bd63fdb18ec79e6bdd94d5be5c40b64ef87d3ce1ca11f256afa9", + "88b72ed2919f0296d5b47c2bb33f61f98c6b27f3aba58e93ac1bb35a5b4131fe", + "a24b9660fdb9ab45a539f5327f4f920775eb4beb00e59704ab287a8ca9a48967", + "1788b15d0f9adf50c79256d8cfb7bbfbc53e0b52650d7492fa820fab64f03e17", + "55bce5b67afb71e01ab76352e5d28cc10ef84c9e7f9b9b97927a6cadb2f09f67", + "f0e6ffa22ad770224886262f59df7f89d81f8d1828bd0703ecd6c34ebbd68abc", + "0db6790f7071e0eda2019e261d95a7b78d1ebf497b0a56cbb741b3cc63c21140", + "cc7802e985f4e716bfde15d721b1a99859b1565cf82323f5a08fef6a0dbfbc3d", + "cac9fb1c12aabf6f2e0630298ae8819449709b1245b3b2dbb1e057400cc23594", + "c635a756ea30d721ea11cf505d7a8212749d59eeb9677e818131d9ab4f496816", + "15d246301be8ae7c3d49b245d33ec5104be75d70152eff29c1f7c77af9b4dbb7", + "1cd68a13b04d741b9ecfc517b0bf075c37ff917a8976bab70a8fca0c020690b3", + "20088f02fbb360f6424112acc855928cc8e244a1377ca9c6bec5653c80f9cad7", + "40de5a6a65a939db277db89b89453a8b8e5627c879fbbc4930c7930790cbb67a", + "a4bbced709f196101514dc78d528306461db34bd52ef1d7e2c898019ff389373", + "c2129c162a9a12284fdc2cf9a0525d27e2f82ab99e1a0aeaa7f3cb093dd2a599", + "073d6ece792ee4ef1d32fbb6266f8bafbc3415a0b497d17ee1ca4b96716e8e26", + "9551111a7b68fb8d443f3c3b7efea272ee80058df3120c333b7679b5337791f4", + "93a8de073f13af04b371c1f3ad4913a67ef95fe5c7b32575b3fc14c1b24cce51", + "b89b8ebb9b221084bd94be6406664814d89acb53c89dad3fa4cbd8e536ffee8b", + "d3bdab4ac126d33a995436a4ae26a6e69a0759c6a90f177a09c00ea238cdf120", + "287b083f1e572eb8f6fd992229b5b547db10a0af4a8c15e98aea5d38686e6dce", + "668cf1b02ecf1497e3ed47c8ec63426ee37243bd0fb7aae24abe075c1f979ca2", + "94e27906fbc00ab291446e20aac3da084c6b84760dd00ef082deec9322e1661f", + "8f20aa2196b5aa7f3f34bfef5d0ee5863f3c0f5916f7300661ec4f05e8a2c1ee", + "1a0b1aff376ad3b01f785fae25e898780564e0c5be5f4d01cbd310e6c4177583", + "ef3d2bc45fb97e15de091126d9082d8920ee145c22ef561ef56b0028aae66a4c", + "f1a017bf74ff8df36dfe9c6a70f7f359622beb6924466606139eeffdad48b56a", + "51ef7b02f73097a0a12c787320b98967c79a2f740c570ba8357a306c13d53e1c", + "ab9130dad9d3cccfa95cf3a51fd9043aad9941b6a48ae15fe2b6e75125584669", + "6fd8444cab6ce550c4e477acacf5bad32bbe2d4a414fefe7e1a2faad2cc26d14", + "3ab528ae9f572564b3cb78b0a3967d06e35b912f03355167d9d4eaa3f54c1981", + "e3b12bbfc65f4da0ac39dc0c08f80d0f517e8dda70797278c5a9f0e6d058bf49", + "94bdc3ea9f74ed3429a8aeaa6d8ed48756c87f927cf79f4b21df9fc60b01e060", + "281e3398c91b4913856f8efbbacf44b4f028d73ad8fe19a16498cdcf3e141b89", + "9929f6018811f47e32d428675a6ff0fa0b29e18efce3e700b9eca9b701cd68f4", + "01f82d8322957a401fa4d62da97463305f8e896070136b02ea5bbfd43c65b3da", + "99022e5b2283733f7e796b04cbbfd5a4a2c2f857a22683db2dca8fd39cfa619b", + "4bdab0ea884cb0277797dd2ba0c7a9fb6a58a89bf09a29cadcc6131beabc8893", + "f7edbab4b6945357c37e8055dce88f9238a63d7a6c008f1b902aa8fe03d57c42", + "317b46659751915abca78fdbdc1ddd88714de74cfd775cbd5ae3476dda84bbaf", + "100451e73a76d7dca6081515d4af378a6f7e860b5489aa0193e31486200fd39c", + "ddc0ceff3b4098bf6d33779da8d8bad81daf1e11648c050222991794379c74e0", + "7e2441083751117c3d41741b5aa425ea93115ae474fa959db25bfd9ab73b31e1", + "6f9c321ed7e2083a547167a98840eb115fb85576a5bf0c1e2a2bb97fa3b89ffd", + "d86bbf40caee1821f5fad80ee3fb1adb207bb2cb6ca1be934cfca2e3783981ee", + "cb5375879dc038d8aee930c65f7c8f6f3f629b5edcf7b8e8e739544d5b2871f0", + "baa80236c427c7d1556cc35cc6ade94f7a85356c1f5325bb64d4542965389f0e", + "30b557196908034354cc52a595fabdc433e13affcd1978576e75b980948eed0c", + "6e475479a87fc8fe074c74cc25fc665f1bbc290d3d49247207b6869cac1453e8", + "13d954b5bc2bfea5eedce6359c066d9bb9289123c28a074d2e9da793af2d521b", + "6b6c90a7d3098c05d5a3dd774188dc50d2bbe1cb82776c6dcd597c13665eebb4", + "ee30adee14ab92f957c317ad8030ec9333dbfc4772cfd618ea9da334e682901f", + "420ec9203c57bbca7663e9b3ee0a1e9c681ce491cb1683c02d49483c0ac2ff11", + "202a6090a26d20780d0f63f12baeb7d68ec77c7a6448d3d59b483377e04776cb", + "ad20c60fec78efef9132b393a31f4ff6a48e393e0bcdbac2c28a150bd70666ed", + "f0e16f81acd2fe837894555c412db35051332634c48019aef5b69b2cad6cb9dd", + "b07acec562136fdac83c286447d8b8430f2e9adca204f34e1616b9cc09683147", + "17edbc60417940ece8b1bb393d07eff352414cb2e92b7e00b89b8d6a090ace5b", + "4a9f1c69999e475d2cb8a578234ef0014b02a8bb3e854fd7a57da04718ae61bf", + "e87d766db5d037dc57a488552d3a46fe66d43f16f5c20cc0ac9127e437999846", + "05ff855728943421a0f2fbce106848e93db6d7c2a62888caffa9c99ace9a8842", + "459da7821d97e6299478ac2e2d4c59996e242fc97a961c018db7768107eeb44b", + "3b26290e5cc88eb6ea663e57c8410db1da098714bb391ba675b4ca3369b6232e", + "781e1dfeec5775071f140d61221362ee35f5035286ec99b1f269b46c15ce7143", + "82516867d2f29db65b56c0827ed8c73d388216ee3a77496778936ff9516561ff", + "54235a7d09e59ac8e50ffce0379f9b98a51103cb872adfd3f1af338ef6fc13c4", + "08e6848af932de20f84a5a6fdf78b6e2e680f984b094759c0c296be9d5e5eb2e", + "ec15d85b5af3d641c9c5f95d9997556b82bbaded771a9e41d4c8041e2c5df45b", + "e49da3cfdb07cffad5707da7297d261b557101f45d9b9ea0c97311cfdf43a02d", + "886456bc4391c4294a754d6f4de5c340e1395558147ca5f32a71b82d6b9b331c", + "a050ea7cd582286f890365aa604742926e74462e0fa1a1b05f648bebcf74b795", + "3fb41f8804c9cb2d60ebd356bb51150c047b4fa4103c59f988215676177a1857", + "009aa2829b13937fd772fc0b5311d725509776409982916c972e859ffe8b8f8b", + "4dced228eeabcaa6a7e70916814ccdbe3c32d82617d20ecda4ec2d32a82df9a9", + "a9a08b1fba2c78ec1d8a1f452d7973790aa1c6cb84f6e08b51cad712aad67437", + "44572a9e3290c781587362b1ef5f5138f7aba112ce09c55c1bcaf38ba91b7ec1", + "08af0e292ee11544217f3a532af796dc8c94a875aa9ec6933b6459e37f2b4f5f", + "45933044cf8da0c75fdc19ed7f59289df10b47d659fb35b558205499ba6fee45", + "42751027304e14788a1aee8c616d911da8ba865fef5d9fe2d5206b40729ec142", + "892366b48464a9c11ae8edc31a82bb03a631b0980db8ced70ea73de223dad586", + "b1ebe35b6db580e47ffc2de5d36b4071cf4ccd6a050c9e14788968ff5d819f45", + "e509a693ffa9d966ae8a50453365069305f5505d96e81db43a7071990fbaa824", + "28c9a0d64f5e85c6eecb149451d228ca91072bdd2356664d026f0133776e2d01", + "8115e9aaf552a3c47ea4a0f2e254ee1d3418a59e4d4643f1ebe57c411d2da1eb", + "eb121b97e3cc72f5454dadd24aaf621f0169f2def79fee6fb0e8b92f3439273d", + "7b474ed629a406ca684f137e30a760f76c43585eb2194a18471454792d8bcb44", + "1cfb3cb8a2f1dcdf75865093709014d45394c07a8272e858bcf5c036422a9e1c", + "955d0f671b614dc80609c0e887751bc04d6ea532ac834ea2520108d4f0c3b7c9", + "35ef822996fefcbd78d626e3c0fc47db307ed37cca341e03433c31fb061f677e", + "cf6eae46ed36dec5dacdfd6865d2f366ef4674d3423d1419ddcc747e89919638", + "33fc1b431e3f08e124f41a91c0592718487cdae452fa7a875214c279e30a3fc9", + "f9ed91fa22351bc12165592179584d228e61d185603e4a493bfbea64d21dee36", + "373e60df039edd90ac704942af26aded1124bf442ee8e4c8962425b1d2939fcc", + "6679e461498d395427f714cb3df6fe3b668a367d8a201f7fa08cc0c0791a5105", + "73dd3616e92c32c3a280eb7fa315708a0152c8d3377a25e576813d16e942cb95", + "60bde2964badc7f23b8305681ad42b57b2a6a06261d934339666af8bdb216caa", + "786675a320f3c5daf6aa965686b5108580634244c7eef2b2468bef0bd8f03d9e", + "9a62a10f9e7c98a9603f5b57ce86c1f043c0560262d5bf33a94219a319381e2e", + "14de332c5502b1297bd823dc0aa4972d21205d07d4e7101fba96bbeebb076039", + "50dd4532c4473775dd0c6aa2606f1fc8b7fac5fa4a7b511ce0f4117f98f330b3", + "525a8c197e7b928c5608d4a098a6c229839129eba241daafdc1f96efc201a7fd", + "8dff8515ad3a3510eb2fe2884eab0d2b5558e3da895600946b0e1a6bfdca1f06", + "586daf74e0022b7c3332390fed260a77df116842787a86f95117035f708fe663", + "d2e6eeb1f0e83fb7e4b6f05a4c948625f0fb787e7fbab9d04e5aebb69437bfa1", + "12a298664eb5e5a44afb970d5d2401f65f623e7f44e3918c6cd45da4345f5716", + "aacfd06f2d5e71c8ebe989b07c333d86fb2f2b227c31e3359cb1be7a2b0c634a", + "9861189a90f241f8a08c924a77b537ddcaf89f42450f488848e1e1b32e4d21c1", + "3dcf12d31ac60dd0ec944d774f2fcaa3393a021c20bd247dbc6a98fa69d3beac", + "9d99d655ac35d95c200c070abd9bf2d26e3e9867c4fe152df0f93be5835d7c42", + "cb42dfaf45de0566ffbe387ffdb6f1634eea4441fdb69d6c3bd07e7c0ade1776", + "abcaa467c054779fcfc781fb6c0183a775f2c353d9e3939342f1788716da2667", + "55e1e3f24d90f070e03a3a2bc36dbd74768ac289f7e967a21c531e98067b6cc0", + "0e3e3e6d97e63a5d576539371ff9b576c7fdd75d540188a0429f4f497a8df6f6", + "c2aec67e5f103a768ed48aaca7419cfa9ba95c9945076e44c63181f390e6c875", + "a1ba8d332706c63ff99574f5815c3324139bb3b29fe9f26dd4a7e2f7c7d977b8", + "f928cd4e0827776956ac1c35e4b94cb735cb835307943e537f4322f531858cee", + "842158eff1fb41d9cd33dd2bbb90906fd5a9cf03a08c62edf8107b4533ddd4eb", + "87af4016b80f1fe6cfc108103bbdea3a0d121b0dff2b88957a709e102ea83cf0", + "c2ed8f23865b5cbcb846c98838dab4a88e48dfaff05c55e17a216716f9b12974", + "777581bb4305a39c71a8d7075e4ab5862a1190776a3010383d6009919a2456ad", + "94a0b36adbaf552071064a4ccbf6af0fa23df946188de4e25a93935bc6126e16", + "0f1de7f16de4419adcc386d6d03429267845e5ba438059e5b1a05d85e29b341e", + "6cf8dfad0654b34a5e83252af95b093cd96b0c0726e2abf339f66428123973e9", + "91aafc25f1dec1e74a30457cd4f77022157683b62b0563ad618f11f8335f818c", + "aedddca4bc083ed051021d7fe7cff7da717d8e1461a17c8fe0faf3b4931de585", + "95e352c5338bbbe05cc608563bea43e86c50fd08e1bd267f28be6f1eb98d022d", + "e516acd15351f7fe1f5b081ffab7c6912b0eca5e317cc7affc600c01cc770979", + "7ded1ea4c48d84239c05370c7592959960913cbca5e652a4f0aef226ce83f4bb", + "86e456bc5deaf08568be4c5826a77f43fb934b4d89da56b0e73944be5ec537bd", + "ebe6277d00da3d519405527d7e9b00bf91f058b33172da5993f04901353d59dc", + "6afe6521ab41750fc50d4bf56a050e24f780be9cfac61c3139793ab6e5c06a71", + "dfa65669806d18e6d0dec114836267fdab339c2283d716d601609d7e97d837bd", + "86a3fd200e1f6a4ac4750a239cfa9b378e5cd77abcac077330488e31716c5626", + "5921ba4f6457e2480d2c083122ab70126f7c37d9ee7a467f6bb49b0e25cef0c1", + "7cf83485749da0930a212d96e1825d1f5bc48d9ee645fabe34430906bfcd8921", + "d0653f958958eec9241f1e2135de4dee4aca80a6c8a66ac8a197911963808868", + "0c367ecae9e472b0e382e6cbab42607d1d777ff463b94523239568de297f2c4a", + "8d154c211eb2d3dbfeca17105f4c44b725c660c4a5ed1b2c4d3a3cc47f651501", + "1720b21dd8b481b152f9af3d5852a89055c43a5d077c42b839c9c1024133bde0", + "ce7b3837509c8ac6a636b4c5a51dbd62407af2270323fa3553f2111858313f48", + "3c37f5338cda397848deee259c30bf330ab3cc173e9f46075516797acc6fcf20", + "9a7372cd6f6af7264f121b3ac9e5169d70cde1be39bc2607dde3a8d0ac2461ce", + "debed7bfcf4858c5852819d2402550e03c516ecdc7e05332325a15e6e8494e7b", + "c78f05f7033142e3a308632cf9f78b02692e2b9352f16a9cabf10d3a025f72c0", + "885e12aed1ddfb4b37fc86e6dfed618a944268a54bc888df25e54f38c8cb481d", + "8e7d8c8f89021d61f634857df9393bf58e269bb66e2bd3e4a1332c8be739c2f3", + "20a103c14281b503642bbd899f32a7fc8f7b78faa32328307dc04cad5d6bb174", + "719c3e6e162bc442e00da019944640a424f9dc58cbc01096d2466487af4791b9", + "bc2497b39fee840e06e8138ffdac511d224aef70c79bdb2bfe20cb5efa3762d3", + "cf9925a0f8b6112bc8053e088adf27b28efc6b90d28b63c6656497d6bec82017", + "272406dea5fa70ad1f59a747a58e9a22fb35ff8804b534f4efb2d31c0fd1d0c5", + "c2d55c072553efe33901d82e09e3ea879ff0dbe763cf511c556574832fb35c27", + "fd2c5eea5b512a69626497148360f021e8444690cc7b98ab014b2e3e1bb42f19", + "599f7f1d5172449fac96489c5ed3a96ec0f2b6da7f16748418632f18ec94787e", + "69e99d4edf86984b53ad5ae29dd7aab84feb7cd53ee954d6f60d817c1fa7f453", + "c76ed1f3f1a47b5f7b19ab0cdd6921f1c6f762b70f5d40ed46e06ef703b86572", + "c55c73744be40a29942a3f250c2110a6e8745d3db0817bb17ebb5eb4fd73783a", + "0fa1beeddbf8045864c5ce410a8d626b01b806d784e54e9aeb17eec9f9515b98", + "7aaae1247ddaea49cf4937d634959c81a01366f22def111f1b65a69591b82fce", + "e043c75946dbc029ae00896109e3a4e273949f46d6098a39ff054a6b57f82d8b", + "f94b972a4e6cd2cd3c72eb899501359cef6ce9ab15a57b2eec7667ba6e962576", + "7ada90634752bdbc5c7eb696821a6e575553ef00c400c8499fa63da7ffe02044", + "ad2d433fd13d80d9862ddd5a2f454f586ace857319a433d9f04817ec4cd51b25", + "3c19fe9c4d7aaa2b6788768692658702544a593ee5581d4fdc88531397afb0ff", + "f90fa73185cd15b9b3a0fb681acb2ca6d4f1957738453f8dd87f9d3443896aaa", + "a2f6baef8d3c570be96db6515411b36e5a7535c892d4358b37ab479a1924075f", + "243a6c26b5923b463ac669fccba8530c2bb448eee54f882a798f89803e35bb96", + "1e43838382d43039561cd9accc275eab3614d33e93a3612b9239689c1a255eb8", + "31cde936f57cc302dfbede7a2a3e626d48c7837e6dc70b69a710d3342dfc9a39", + "a51aabc6c4585847e09fd4e0be1dac3a9b204b3e82de8818d821615ae452a0cb", + "8fbe37ee966b808e26034e916ceac3b982900289fdbb7d7baaa2cdb2433a13bd", + "b2c5c54f4fd6f06b5ee05a8257b8ee37df52f64ac15fcadb81cc3c63f725c8c0", + "61e3c087292baea8b6685a464d3db79e2f43458929a201b5ffc4fe523fd3b170", + "30adaf1ca7222d88ec8b9ef25c44bef728af693da5720f65bb80b14c4266474f", + "4d1ecac3596fb23d869fde9f6365abf344b8fb2705ac8fa112bf6f740c59e59f", + "1d8b635873b16144a274542fb0e379c0bc44b571782a4d73a452873f9713c19e", + "d8b11fec8ab3dae1f755bb2f955e591bc43c64772ad11dc6d0d9f18c52a5db08", + "c8c2f9843609c11c4c5fbaebccf0699cc4193cbb2dcb8e7bca037433b8f19615", + "36cd540184a2f3d762ea6c47296903121a0bcf17eea591ae17c2dca40ed33c73", + "ade0f576949bc7f34fc505ccbd61e5240fdff95905037701a228fba404d92616", + "c9c6fa4c31f7c4e2e3e805e24288becc3bcf0706ef96ff56188eb74b035df9ea", + "3c44f7f29c8ea11602364d41b00ca68f4e18f98b5227e50003985f5fb6ddda9e", + "cec9b6a321acbf533bf4805b19543ed49521d1d5135f061ae43088dec89e5ca7", + "3d7efbbf4b30eb0358bf6250f2162b25e1a0a7412e1f2e4590e1edd2ea305473", + "2cb66057e658aab7c6c7e8e7f413040178898a0b95cd1934ff1df543a41eb7a1", + "b355f7f2f4e6547f86e478cf75a2d4960b9b43d4cd18f496a4646f225eea001f", + "727bc330363c9b05fe388fcf26c4f9f7ef56e5d8aea9fa49204ea010b0a4ba35", + "79cd30110672fa9aeed526a1e60e5e2015820fc6c165f7f440c7e59d47e38692", + "74cb30eee7e93cc0ee2342c438919a4108a2f43050d95d176a2387f9fe66c37c", + "652169bc6e91df2e16f9aa43b77bc919708933308358aec1c9fa583940bab532", + "4d203e878f472a28d471ade26a25253651e86776cb8c57f6c021dfa5e8a3f145", + "7b22caa4c87db855b969974116f3c7aab2b2a44c06c577ab8960d3e5490d3546", + "2060a9a86ab2b75d7a93b394a8c14192e51cd61f91b0f95888e6604fe4b5ec41", + "3813d2446b336313c8360c10a56a485168bedc19364e22e7becb0ea3219b1e7d", + "8d2a4ea6f9f418155b5130e9bb6860cdff9e53668f9fb7a0192758427d82a06b", + "bac755331bee023938bd90df407f769b28ba35c334478001ad517c3076e93077", + "3476caed71e58a47dc128c0f13df6ae6891b23f0b8ab0fb61d23b6fbc39ab703", + "84292ec19dbe167c13680c5b729c3b89fa46ceb206cda43e75de24eb80bba93d", + "35ecb67272d373a05a2a2727f0f487c2256c072ab33621fa4fbca9b2101e94fc", + "964500588df963e8fc8ffdf062c8056b99ba39972704aa0f94621d5ef5ba7e93", + "343b3dada044bac7b5eda98d9c5b00847ca63e491fd2b8296ea102a6c3836d70", + "b5e906fce3f4dda8485eac8857fda3f6dfe4a1d0b01290e1bfcd061dfb7a2d7b", + "e4ef9d9684bbe52a6fa7d6317f11af4f090e299b718c153a430e60b87f76bb5f", + "8d9f5aa059421843e8a2a1292f5b85293365c0fac5400b098d278f252f6d00cf", + "7c0cb0b5883b5eda9979793670ba9e1796a23cf66bfbf49aa272dad06820180a", + "35c892b3d99bdb741fda6d264e5803a7fab002e3b1980ba687fb3e53e46dd8d3", + "67d945bcbd3435afa483f20d81eca901c4c290d251099811477e818b9a780c6e", + "cae8540472c465c7e055c918128c19b3c653fc8576b48c35f4e16e5fda93c617", + "a2ec240bcb1bd48fa87c5003299f18516ac657bfe02ec4ec996caf5b5286d55e", + "a00281ead5b791c547a15839190139b625fabc03813bb3a00e58738e450c0140", + "5447c8822ac3d75d697c2e35dffaeb7c96ca4821d3f6584e571e915ed6ad6457", + "4bf343ec71bdcb7415c9c9045d89ecd8004ff4fd3882e3767712114db9f4ca78", + "7709ac3310bf0605d6dd2bce5f17161bab1c3754cbc632b7297d973f84873741", + "9f40319a580e435846badc6201b5f0b8513362d52e6920145019da423c3b146a", + "0026efd47dbf94537f26c15ec64686b4eb2fb4e64770248486ad95c3196dd3b9", + "50fe985ae7139cfb6f0b694af26afaa9389e66c9ad2038c73fd7b0049f304135", + "d1bf94b0cbc27465d0e2579142796a9c5a84c9a2e92837407697c6ca6b959a58", + "671c38bab52df0530240766ba41759ef8f5d036976b470cf0930e0f453665eda", + "d5c1d213b49a67c5ae0145ee18863be3fab00d44e3a87aa5a5e5f30f1f187018", + "326b50078751b41105de2f81c283559a2495885f20147fe8065afc9e79e4e3e7", + "76574c6ba4c6010799fc4ae3f860750f3f8ac415b0176e838e516977f7abfbe8", + "8b7b1b3274dc45f4d3ad06b2a61b2216fbc2dabb1c1a0bb4ce0b7d4fb0f49c33", + "8d6f1208461a4e7f82baf7182e134703d71ca58e18b1e9b93397e3f2d0a2719f", + "282c9fe450fbb40bc3380495e06c78f4b299e7cd332516970498b48ff388bcac", + "07db82e13de8a4b3bf839f8bcb5abd4beed89437f45853300b255bdb58cf540e", + "fc79f26156fdb0b13dad85968d61722c56e6e95ceb1929610cc8e3ef84ae8928", + "d1e3dc21010fe14d8b8a0c627e2ad654a289ae4ce366021fdd950bdfe7d327f6", + "0ee7f5f991458612c34cbe1c9828ec4b84a2a09f086e583ed15694af712b55fb", + "045e9ef63b90816384be70f10de0b5c8d9c61a9e0cebb3f8d53ae070db7b74c8", + "00101472245be2301ee22f996f496f499b1d5b6fc0dfc6f3f6c6a3cee0907bac", + "d907bcf02450dcd41deecc78717aafd4e3672373162e11a706ad8c669fc634f3", + "f7da39fe95c7eb2efe04a5e9cd928adad07e9c3afedb46dbc9b60ef75a9dad20", + "169bf9d379980b543eb43d0276044e02e4d176503ab027f93a481eeb221d44f6", + "ff2f8fee484de799d0926ed5c8b78815c58a3c4cd0ec033e031af2b315b60f7e", + "1e1721d06a440d61c988086917c17ec94f010f5b200041594acbf927e13077dd", + "d9b989b742ada63edae99096fc47aceacb3bc95f1e6b471ccaf00336028079ea", + "5e6057fa1bb3db2acb11434c0747d350d832c0ab49b3305010859976a9cbfdb9", + "ecf17f337b5f1489de2a75dbf8b449a426bf65f2e50d68e34cc82786fdc26499", + "fab0a4992c2bc17bc6aeec1a44d646d4e1c88d2c84ec45f663eda90c80bc5257", + "8866dcac38479c7e60fc18fea51eeb366369a8fc74f589ecd9f18903aaba95ab", + "712cff7157aa4120d8417dc14b146df525096f79d229188b68c075e4e4808007", + "f013f1be08598a88533ae9b1f130139449866ae6a1d959f2ad34574b4f34dff6", + "fd8ed04b0d39962091847ede4787ab0e9aba188e20dbe97724e0086d62d1087a", + "a92cc908f9d5e0b653b05f5091572654b9fabdf1259a3ee14bddf9fe0e26b948", + "ab20af88654fa2df1056e91d29c98d32adf6ef8b96854490526e67d315ca663b", + "590ee81c9846e7c50b23e004d3cdb67620a20497dafe0bec3c2d42cd09e03e77", + "c6fd8b2297af42233e8d5902bd214bfaed4fd78169dbc538a37587893413e1ff", + "15d261585a98bc2b7ee6f24d7bceea252d48a0076d607c437a709c1d7cd2f193", + "9ae78e2f7d30906fca8da6418bbf519c4fe15681dc360a03830bd5844c71ba27", + "0c4cd3c6fee5feef1d37e2f6848a273f2b2dd4d1b2d19b50890666b8a340d1e4", + "d968cf7686e77af019c1a3384d00bf47d3d116dc637829802182912eef3df94c", + "905632cb21e9a272e31da96c4d602025bf6507f48487c035ff89f88d0610284d", + "9ca200053c7a4e642300f5f798fa4840a31d4cbbe4cd0b18900cf8a1a2d4cae1", + "8a990fd04e6e5fbb7377c8f937980dcdf65832ca5f8a781975d424e3014a6f1d", + "79b9b7ceef32c6fbe27b2397ee5712a4708a3332d2a9634b5a29b583d5ab725f", + "33cb6d6ee3a3f09c958fec42ca0da471b0660f1897d81ba2cc193894a4d38766", + "42f11468c1925669b01802159171b5bab5a9cf17c80608b46d0c4cd465a4cf66", + "9255c4f18732928bcee0d999efc0a7ffb52d7d3024dca9b598e409851ad73fb9", + "4e2bb82f5857257a68f0319dcba5b0dbc55a671ea6579500503431984ee37905", + "e3c6c7f9d6578ab1618854314b647621fb049b3ae4ed12d4134cb3a0759d9f50", + "082f1d2d75ef804f418fb654734f2af95de774a2f85886993f7faa7c4a60972d", + "d9b17e8597e39be34de9056ed0d92b95e0aedbbb1cbce178298981e51166bb20", + "5df4478f590cfbf8932c288cd6b37e6a99217be91da2d7f8de617011d2e93a22", + "9b6ef000ec2f6ebac9ce8b7ba0ecadf50021b22c357d6e0949967ec4f575a605", + "f437f1251940a13301c731cd383d25b85885f3b9758931ce608dd58f1c791442", + "c93dd325bdbe10015b80df5e969efc2fdea4fe1f66ed5d472425a14837b9e61b", + "9a2a4622079ca21a6a8b6400adc3e616bb4ec1a561483df3fb27d7b61084a3ca", + "7fad3d21afcc30e324176f8b56b67cf391b5f815f4018227924b0d6f528283c0", + "77b870e92eb11842c42075ac2f0ec1b69ab95da67d2167fc37719561d6775735", + "15f84393461d679bfc88038659a691c227851e97edb29d32d049263be2352d49", + "98b956c646e338094a3eb239b2b32743863c34dbc70ce1cdf822e97844ee2043", + "7439ed28377b91fb612474e3878d862df4ba517eeb2340089eee13615300e3a8", + "c7dfddc8e5da7bb9d3bbf75e7e28a38da042ebc243d5d448635977d046edddcd", + "887026f92433558d4ee00ab03ec7607799ad1391945aa4c7f7dc2feb8fd26cd8", + "2d8ed1233346a9637d29b41b11a3291fb2c8aee840975af37f640a979c82cf98", + "c8b64cfac0e01d30f3e8690d91451595199b2954cafa469c36d1fa9d77449109", + "f5dd105e51a3dd725d4a3e4f9cf9ab75e4267ba84e544e5b0e99e737824821b7", + "e3f838be89c6caecc1ada40589309ebbc5bf69760cb1ccd786a7d79134e04368", + "e0712c3f91c6f6aacb0e23cf31b615ee437f48dbc2f62169ebead05ef591fb88", + "9ae7f58ec581f3ec553792e5bc056f918efa8880c1580e195ef2c1345e302ac6", + "8638e7824e6d2523bf53d697e935741eff631f18ec2b1e803825418ba4c64844", + "b52766ff584756b9173e072de9cd96a1a6090fd7e25947dd35f3ef22d7c7d6ab", + "e48561db4650043bea23a6f9bfcf1f3c88d72ac362e73a606e906a6560c74daf", + "80929c3792470c498fe93085eac4f2d36be89aefe97338e3290ae7d19ec6ca37", + "7455d117302e45b8eb770b80e0be9d046d4d1a95cc26fb0574c1bce551f63a52", + "b0e5fb3a4c7ac3db9ce54a547abbd17e8ae1cf534edf432cbe92b15c74d548bd", + "d15d25e3cb5f673cdbe4844df1f36088a037ba0d1479f5e2f40ccb70ccc4ce3c", + "9e7208b23196c36416e42ec87fe252b33ca1560233108b010c8eab198b5f3417", + "7083a8f061dcc18f3018ddbceced8a015dbef1f9ae002ed032a53208fcce4546", + "cd0ea80d295add57e72c16e371fea0db28cd6aca0131a30d310f8f9635f4922a", + "ce5f12813b8d9508fac7e010844bb1f5c31d846885c2357d7f6d465a49dbe89b", + "fd2c3eb1e41cf761c92c306d7548b933d374619018d9b648a7dbb4f66edc7ba5", + "886511ec1eddcca5ac93a74808a80609073fe1a5362bb84e9786b31992b6dafe", + "7e0a8a627a927521e08a1b3c2149c58178e9bc7711c6583bdd7f12e35cb04ecc", + "6e49769d18c8746dd09e28abb303484f1fb4f8c6b5027d8c9b239df53af655d6", + "d5e226225ba7dbd0809b98dd99a7452fb2d7178b568451efdbbf353d01d4cf1c", + "98f4df60036b28ef6fef2952cbf5395a33c1d4c73dd6882b2791f6fab364b6b1", + "dc82a58115a2df310443bec83d51635a37da679ea66aef0bf2b99dbcccb8ca94", + "2aae616233b753b15849ca135edd1f0d9f500c633e10d090ed49f2d58ca5beb5", + "471e6b548668c536bcc8c20b6fbd9b14301ca5ce097f1b99c7a37d49e06d6db5", + "f70ff91b76d034464160f76878244a7b8816699fed54273407bf5f2d0e2bb756", + "9972f58d4a5a90f640daaeb53553deae3681c8dcafd53c4a1c2a1d09aff2d2ce", + "fb464f0034f04b7e0236d5f015be0f39759b7bf14eb7956a7a07249ef9ed37af", + "3a2c43c75b817bb186dc4a0cae081cf8fdf3db6816c012b3a5025d99cc1e9005", + "f061685828ff8ce2f97cc7d9e0779b74af628917fae824242a6f051c6decbf1f", + "b37f693bb8b2df70c7672d6fe984ea011c13982a8fcaac9b0e1724a20d0cce90", + "4fd0b8c6d547fa4a4ba9d675b578ba7f70feae4eac425f97875d1fe968e64282", + "6043fab5840eddd0570461f507346e429d627b2245099032062637321c8b3836", + "cd62a44a5cb1549c5853aa56def7e203c1bc9817f037085fff13386fc016fc5a", + "95a2e1f16af062d967c9647669c61dbb24aef16e265392441a4474ca61bd12c2", + "62151431c771c660086bf67fc725a56eccdc804d9db2793804b7b92a70f79a5d", + "a55ffc209ae05a00ca2d164efa971839b33a661ef1f077141920f8b2fa880fc9", + "522ac0f37eda8f8e8b3e9a7a736ee07229c81fc7588c338f2b7f0b6e1399189f", + "0a19651c7a7855b2e7da42983a821875a4187aaca1cfc34b5d4859a04c7993c5", + "94906ea2611e7d1fa52f61dec77e9af5a8eaadf142084065faea6c5c48711cb6", + "ab92cbc478194f5a3308834e8d9f6f7b3ccd2cb4da3ae3ef2a747165ed26255a", + "146fe3a8ea0cebc2a63498921dad6dda8a5c8282fc3da138f13bc34d68cd52a8", + "afc8f584d4bb369bb14fca869ffa5a150915f4d3d3d2348742832c609b61d416", + "89daa4a4ecd6b0fe9520f65eba2f69e6a3f3a25c9235d96b52c484ea79dba3ee", + "597805cdbacb80058837b052e4928921659930a6c97b46f5a6ffe64e8fbdcec6", + "5b5bdf3efb57172798a1323acf82586ef416fcebf6b4feeebcb1814cb1841291", + "d064f4b00ec57ede0ac3f0ed7263d6485f12b2968a65464349e2db594282fa44", + "3a1c90d34bba157d684811dc2d1282bf088177a7fbd7052b4cd4db45b946557a", + "4cae7ccbce4fc16a44441053f0df0b277fabf31d5589f55d33c756ea3bc57062", + "7cb1964bc2f0b8e039c2ca9242a709ed41ad19c77533bdd7392a1c024d392abb", + "b3167325bbaaf248ddddde5650bf2e85ff1e599ca3ef32ac5cf10ca044e94c75", + "ce4125d3d579c3c525ac71ccb1484856a5b5d4c753266f9e6a25518f247f2aae", + "bd72f43c4c9a2896f67b2925bda412ecc5c498563f8e84b85960dfa98b6dcfd4", + "2780a2adb4315f93d01d985bae6df8f432dc99ed2b700088be19cc84f4e6a9c6", + "1848b08b1cf82b78c12c48923361999b51125b3f0df4863067ecb908c37d2961", + "f2548eba5c800c45a4d15c466c13ead6f44a18607b6ac41477f737e2165a8442", + "4488437236021ac8acc2d083133440df17a41943f2e1c689e8adffb2768a8ee8", + "e57c89b6082063bb2af8a858a982b544b35930099d02768dc07f5953d704183a", + "7cf84b35696bf6f298d53ab5c6c1c4686260b6dc62b1574f3f56c8b134b85a1e", + "2cd4aa83bee0c37ea402e71b0fd74648457d669bd4ff1d127a44b7dcf970c866", + "aa357da6333fa3dc9a06ec51b1e3eb4a0b9073ded1e1b3295c413a5d528b8aa9", + "2f396e547ff7cc899b4db00151c0c6b6cc70a3c1eacc73eb75c37369e6bccd84", + "cea468d21e5563423bd4afc2778a1697987a994a7490bcdd963868e603a02697", + "3614b42b64af6623acf6158d3003b5965fa6045d704b2a9abb0849fc80755d82", + "d040ba307633f267f0ce931be31323268aa4424743c7119a0e0235db70a13d02", + "64909a9d18306dcdf3316335e03425c10112ba8ef228c098b6467c688ffa4509", + "888900933f2c29f0f843a47179eb2cc4c2de801c703c1145957a1c180205bea3", + "607e1a563da66807a67fece8943820185cfa00c11bc68c358e66a5c7f90c0153", + "87c3a4b737408fe23bd15076b2f7d1dca645f040a27b75ab13cb058716fc9dbf", + "f5cb860809263f0c9a1c0b50234ec6a0797029d7a012610e1c76861e5d9c6692", + "ad3f6aef6e169d16a9e72537d770266632f78cde4abddecdc68de7c9c385ad44", + "b473de491ca82c2fc1897543d9b1892706771ba54f2b84dce76622713724e3c7", + "3e727289e53c27c1a1e2adb722877382252519a7f7f2023bde741eb948251976", + "77a20a1445bf838c4520dc0e9e914b51a6dd5bb6048483a18f5fa7967cff4f4c", + "c00249e5998c531792dce3ff5716fb6ec4901a962e884114dc7bf33f3ce8179a", + "ef44432fa400969ac735c5e960dbfe5770820a2e73182248f1c06c0b6ac5b9bd", + "a5a0c26dcf1efa77480bf05e7a19dfc3294e8e7729026f7cbc2aa76c649f1c11", + "ee0a9f1c242a0bf5cd7d27e467db3282c24330da281d87395f414c1f79ebb21b", + "feb21c2bec420948d4fe6a463b26439f4e4ae7d7101349669186638bd0ffe9b8", + "53032cb07189f546927dc13f74bb8b4217ea8198d6414703174abb22e15624ac", + "17aa261e6b592a982b32282c3638521d2bb9860c90b18add60a290c25039d374", + "0415766e474cdfb025133bdff425d7666f82db13357f510c318ea43c0150aadd", + "cbc12abd6b2f052dc68ccb6f37b1aac65404e18e85005eeaf4f0037d8c3b8085", + "1d46f28487743ce8364f2b4003fd5800d60cedec443d8c14994b11bc37d9196e", + "e6fdb7cc00cc3e0261407d7bdc66643cc0e23d4cd73d2e9d533ef201ab65de87", + "65a3bbc168f15c5e85e969d474b5f389a15b9e736cf51da805690064f3907d0a", + "cc2f87c559a49c375a69f13a0ca234bf68165b92f69a002f61f46411e8683cdc", + "cc6e0ef82a28496a545acf9c1c8191d8a4e17aa61dcf016add01612d4fa3ee13", + "c18da70c2006c9d361ffdd2641975b44af6a3a5e9041ff01752c7d10122b988a", + "be8c5a2661aa6adf26e15d6b40339f22b75539cbc89235c55ac59c4634734afa", + "d7e59d295715a03cced959ef0f72a1775aeffe0087d8548caf3562577bb3dfb4", + "723a6ce22b842f00e48eddef9b47863d756b77d1f794c0b3b91651186c967150", + "6bb76740a7334227c47b6518a4d75efe98076f88cca0bf9e79cd56ccf202fa66", + "3ee578f2becf7a84097d60ee3dc913452c141eca14830ceccea68ee4433eb1a7", + "b7b4714233e4335a2a9992c8c6810fe1d5fe583d5342f8a7467da0d5db0bf997", + "2cb8a0c1fa854dd97fee3fecabed83c8ef3a987c978ab5cfdf5f0946806a2b98", + "bad25be9bd43d6164e00af8fdce7cc8fc73a9d555edd762aa6fd86c1ac03eef2", + "c79e0bd1473c9ed599a772866d83fabca1442dc0a02777fb4a4b4e259cffb525", + "79e8d8020f950664eb58129df5f361b8ca9ec36baceb8fe23256859b1dc0dbaf", + "405c63866a9acfaa14c57269d117357d3f47517046c7255c2f205655f3481eae", + "dfe45fe00d08f0eaa50d8063eb3fdf091aa1d5d3aeddda63ed96dfb45326bb9e", + "6f30e4cb2a79e8ffc49dc26145c0975e773ec4b5eb6b21dab5316ec31762de34", + "a491820073b9f43eae8747f0cb003bfac5a0b8465a8bc8d185d13cd35e644981", + "f50330a4b9e22bdcae7b667579a0643cdb3e245beb768eefa86a09f1136a06fb", + "6f161245e388f2b6ee9e7f6705bdbcfe02c6c25f8c626d8ec41c8b6c3fd3c68a", + "941e9ef11218a971bc88af445af7d466b05e98e85c681439fefe37ef2d2edb52", + "446ca70c3d37d609bb76977e68af5c26d45d482dd92f66312781717349de0cd7", + "87aee570938c1192f7a3bfc80c7fabcb15d387891f2a3dfde0f926085680c38d", + "d40af651b75e9043def87efcd36a7c64c264e18b62256b9dba7bb7c601508143", + "e9f67502b60cf3deebc462b0ce1dffa5272998b600ab502371f03f4069b7c3f0", + "a96eea77830de13286a6a9ef7f7639df0b00ded92bf067cabb3076c87c81271b", + "67e78bd3fe5aa8059aa68ecb9ae07422df389d5589d5d4db4e7ad418c40b05fc", + "3384a80356fe5ed4d3b943637219b318ce3f7ea4e76c81451d811402bfccf94b", + "6878f0d7dd5bb75d88f1ffb588ff5f752cf7bc1c007bbb90d8a60966e4128e6b", + "26f34e47a95ce1eb98b5838e1c8ff811ef70f7822f7cb60d12d75a85e39dd275", + "400d03091050cff7ddcb80f74176d4d67aa4c4db724a3dcecbe62db22132a314", + "6699e2a551d2cae080ace52afc3324861f65f18076d7448d8e2382ddb33d66b2", + "49a7ad0b8f1e7f046ae521a464ce37b2c52c221782d8546f6f230fb900c4f0ac", + "7ccc96eaab5b152617dc4d367fa587e99d167d5d8e2bfbb31932dbb6ba4fd258", + "7ccb2e5c1a99ae1ceeaddbcad27bcf1778acbd03676aa0415ff23d136f57a51e", + "09ae33eabaeb808b2b772351aff32e6999fe1541c76fcc1a5e42715f0faedd26", + "301ca1a8839fdfe315a4246d235c3c5e643ab759103f05ed102d0e51defd32b9", + "5348fba5a977259f24e6f680f3047b980eee6a60215110b8372862b58309e44b", + "ea4fe2cf38b6012685c5993fb4ccf4d63f3c59addded64ed318b2db3ebb8103a", + "ff3867e9dfcc8b374349f9358dd2a48e0929d5824c273a5102db010fd757c66e", + "bbd8dfedcb70c4fb1119c8cc1cf29309ec2a03f1d9e537c086047cd857b48548", + "8acf3e8223fc64a49108278031cc77b0ad6f0a1539bf51f6e8c27ba0820e8e9e", + "a8ea1485caed1fb38627f272744b320b702da3201739eb7dab824ffe92b5d72f", + "0adfe735397b28e49623766b7446361ffa9d1f76ac812016bd45b2e5614155ad", + "8afa8c0b9ec42cfe65cce7da3dd12e23d33071cba64bf0b77385d6ad919ff9b0", + "680f52d8e13c85a6b71cbc379a7f91d36841d14927a21120882daee5287dfdd0", + "364d746a7f31c7c11079a19db0d079d0e9901e428dcf54ec7591646ed0a9280f", + "82743ecd79d4e4d539b975b98e9044fe8b23a94c0e76800b0f2ded4d957cb829", + "7249ccf10487952e528f27df9ff6c9a6f882adf5f2d5e729265fff736450b36e", + "da91d7eba1c5c6dab500b9efc64ea4048a32dab4a88105b9c749f1f324ecb205", + "0cb936d8a758b317dfc9569a02b096a37567b15e6970bda585e23a4aeb7fb13c", + "a3438c9e279c2e3520429e442eb8baa49626fe37b390abc22ba79e6f47b39db0", + "af22ac26b4a00119cff6b4e0b1053d8d3f3cc3e00f147f4a3285afdd03f3255a", + "b5be19c56149f098f69f73e661327cd195fc872e21b49bd1175c329b70fe72df", + "580eda9bfbfdf5b3f77548b6ef540c143e8044c3402810ccd5b4068d6cf1def1", + "5542ecdc07a0117a6ca3395eb9dff27b353c9ec8a43da04aa9ee4dd5bb07f96c", + "4e79a4c74505c1c8539c970a56aed96b4923701b3b101f59c556b15be59a7477", + "27586a9ec623f0ef88539134a7cd27b9d56cc777d09226e5dfc3738ac2e983ea", + "76963cc36259a6ab48f091033b48451cf2bef8bfcbbf256ec4eba4810fa54399", + "35393af102cac753ed9df3bac93ca3c6750a0b519621adff82d725a799e409cf", + "fac6b40a2c2aaee06fa3df054dbb50257067d30c9094e8551349553e20ac9be2", + "63c91343f38e4278f046105166c88d4f768cb01c75587f99cf68a9070244e39c", + "28bc810428a3c90b96e13f2c7f6c8e15e1b40570000393f9bc4b70af5bd2482e", + "ebf0fdad90aa3d985ac3bd99e87c1be6a17c5f378531f0f673bad4c48d07e9d9", + "fb21ecec35aacd1e00b1bd8f81c131ecbcb1693be1d77d34b349dc3b6f94c105", + "8e2aa43a76762574c11d0cebb2d202c82e6a30f74048a63cfb08a6cb6ba16bb5", + "e8794dab14eda76afdbbe80441b913b1480c03b79e514ae727f312ccebe673ff", + "9e022bae0f564da1876840bc2e7636ffab2b7b0313d673d20115504b868866ea", + "d37610d88439ed2f2b6ddcf5b5dc92735829835406f1895b2368bd28bf47ab32", + "3f1dbd80c16c141839aa94da583ab8e839f4a81341f18819f499d396fe3d8f1d", + "e51a611a362f98dc186c08b60f922f145530c470fbc6e70032fe0d182850b5c6", + "c6df554985bcb676b72e9509d473658c7978aeb7a25ae5fa3b85d90172695737", + "1cc7450c556b5a2fc2ceac9235f20e22b13f1564fe60f7d5a765f2016964b0e5", + "d540a094dedd9a4707dcd89b1be007e30660c0b6119eec042c66e748b8fa54b9", + "1661a4e47a0b46b28dab8ddf6ba570c7f9f3dba0f7aa9d06f4b5a80017c0cf24", + "02a6276e9980e6f68c197aa67d7beef982276d5981d997f8ed4e7d0f77d67339", + "32b9a6048c52a59d42549a8f4c087507b73f61daeb4fbaa78cef169bc0f340b2", + "4eff26030834c13e84a01909867115cca4cbfc8321960f73208304000e2c49a2", + "c6c0e16d7055654e589053a5c274cd68ac0014067d72e006353e4656c8f3e3ac", + "2bd6280248debd462d3dc64ef9b885514c2ff811aec5fde81120d0b2dc361f03", + "d7e5dca9e6eee5bd3ee1719191a7bbded8b3bbf12c28585eb574b6873fcc347b", + "1cc2b32e8875af9d54e5d01f3eeb236afa4657c2cfb2156760da8eb644fb4de4", + "d5ec8b1cffc0ac5b06d6c12a24532786c7aac9e5dc26e06f80f2874e20329c12", + "d4e2b712b4f4fd74d095b8b856ed72045ce958824a842a02c2da5c0026219d1e", + "0cbb588d22fc14361a519a2c1cf16b67c8f68359140bacdc3a8ec38684ec5b02", + "01201668cce35489938b04c350286217277e471a46ab9f389192f837968664ac", + "0608774ab57c7f2df39ad7e2561f15b0913f97195f8be6267939ce1fa4600dd9", + "85c578d258e346af5ee6edca1f72989181e463180959406e63f377bb0006652b", + "80a5f1eb4129ee6b54b434b7b927e72d5604fa4628e23086102307067b8532cc", + "85456ba4d6a9d0b2de4f060806e8fa3108f38e8466ca78c31e468fcd3630969e", + "a4a2a769f7385faf61e366cad0d2c198a31d09289dfa56dcadac68bfaddf4f4b", + "c9263d8eb9b194be6db3e7e1b6457174c38560199c0fdbb2362de1f0cb5cc4b9", + "db5950d50c4275589baacc418fa37e36fca1175462cd2eb189366434bbb68b2b", + "a4c25ed6b2f897537c61b2df64a30f93f4e72da36ed86c1ef19e501eabdaebf6", + "389f83127218f3826885ca7287b19c585f495d8889388a396fd7fded56219497", + "44749831d977e300bfdccf4bfc085f37c5e86866e5e7e32fd60faef653abcd09", + "c5a3a8c7a68a919137178e1945e364c0b3a6c7ef7f97d9408465294dda17470f", + "c6c23e6200cb93302b8d006f51181cf9a8e081a704db9ed50f26dec006b2386e", + "7ff23d784dd90e6fd75abecb2279fed8d99de1f02d905a42fed7b63a8f2ff467", + "b9a79df0858438129aa240c293e681e5d68684de922499611f5b95d56e0bc060", + "fe88d4351a0c67d340b06f80c627f407665136449b5b39f0067432474d65584b", + "f0cb8ab83d2a42f4736c7bcefb0d20900d1a18565b00b04f41385ef7f442593a", + "710ed19d064e5be2cd1bb4aff5121fe33aa7060f34542d43fc7013ee3879880e", + "0baa88ac41047607304f64d7550026d66be38884c965c6e4a24cdeb3d4a28ff4", + "6dfbfbd1803823250a22f983c9fb22b815ee2d914325935fad7b8b6493d57757", + "3f4fc1d3495136960eb1f63b2013ca62fba3df1b3b32194b9c79da841d019c76", + "5d28dd71bb3189662a166460659e31180c23a9aa841b67f0032ddba699f7b6e4", + "069ceae298cf68de00857dabfae3b02942e80e54ecc15c7d6a2ebf4967107d25", + "b8d46f508eba032b3a9ddeae3ef8e5afba1ffa00bfeec4c8f01b07cd74c5605d", + "c0c7c06fa0c0342c10b64b08ff82ae595bceea9d994e06df76243858657f157f", + "a7d2ccd98ea0ff9656de7978f0332389a280d0933785eba798162faa6c8a5c99", + "0ddfa887328a9a1295ea0b085a9cadf6c9657042f99409a6123994ee17d70443", + "054532617ce06b0259ae8b9355c6078982380d18ef9f8d1ee3af35b34fa45443", + "075c061b44d61b0348830b333b2691c94791d9a799a1b7feb068a1c23909002b", + "481ab72874c94f5b31b7a53d5973a93247e6792da17afc5c3c1d21a365688edd", + "f494127d30817d04b634eae9f6139d8155ee4c78ba60a35bd7be187378e93d6e", + "1d45d4d57c8569edada1eb86ee94ed153255c3977cd0718166f793c2759e13cb", + "fc66f76c51a20e8831b8ac5e8932a36258dd7b50ba5864f59329fea6e6b55f63", + "8ac73773fa9d5aeb3bd23229495c06800257ff0dc0d0baa7b56221166dafdf64", + "85afe25c9fb67c8058b227daf606fb8532368e40b2c0b58e3817b19ef55e18e6", + "d9cc4df3809134221ca6d8b81b27bd943b9e539d6446418504792df60652cf6b", + "b338bf18de532de10b5de68bdd0850bd3cf07b93fe33d60ef6ce41d0712754fe", + "6abd87fa0625685216a22eab0d845817adcdcd7cb36f47ab4f4ac3900970bca3", + "ca5f338135a835372fb05f83c61555e23f1ba025088b1210a2f369822459a0e1", + "1828fb7d0ad9b6a3f17f67a1386ce4edb789d11ff0e525880c6a72c26a204e67", + "3778528e6df4a36c573bc95798e89e2c4cedda33ecb1e7bf55c42b05ab04e594", + "112ebd143201dd4581ffe737f5e1292598579d7847105be2b0dbd8f35c6df476", + "b7ddfd6f6a9e0f77621ce07b1a4c57645b3f938216a1671a081dd435b78d7d43", + "69f737b24363b5e87d57f0beda35f1dd6a10819fa14409c2c10ca34e65776e43", + "df5e2363244ce22970df64ca75d728378bf9558ea28f237f53593614e2aaaf09", + "b39745e5e773d9116d968eccde56fb6dc4e5bc23d03847e58db4e2c4635859c8", + "cad66a82f7915d513d5ecf1ef202e3bf78f028591241614fa73117e755901cb2", + "b2db89db006f91d48b2298bbacba83911c09642d1aafdb9854f7fd57091ae4dd", + "d3993e75c15c7e9b48b29bf5336a8a684728e37cc527be1e604df979f3301d68", + "064c3cb6b3db518361f1de0c2b84ef26b4d8c7a77dba930d1180847c3248dddf", + "5ca2661cc4afbbfa5f608b58edace1bc13b7f0761ad6a974e3d2a47b7ee058d9", + "743e4564907bbec87e6489f71ef5c8197bcb40c7fde7f0251be747efbd0df86f", + "44db1354a1269425c5d76c6fd6218b8e2a6a0d21f35a4120c878b2f0d186e11a", + "a8d3923b21a90bd657003f81a31bf95bf440d461eae842d3bd57276554337a34", + "57568acc9aee543f73f41847357f78a430075a902b2b90eeaa244eda79ee26d2", + "749719d7669780717ee4f8d9a64a37ace3894350b99f1ea101a290b4c2eba333", + "e5980472fda5c34ed1cfd94855813d15d0a97232b27eb4bfe6cd70f642050b3d", + "a31417e9ae8e3614a9a0116d03b03e13640b04e49177088801eb489dbb4aef76", + "bf2e81c166507d5710aab960d4ef3132150ab4a556f3a4a1318311ed47581d08", + "3bc77cf2af53a3e7f737f45b2b9fb2127a32ed4b178311783b263fd89742d184", + "5d47ee90bfbafe6de22f1493aa1849f9c6f2a257a42e3a6583b7788528aadd82", + "6a10fc3d33b797fed0e19c3a45e1d3309b3188416dc78aaebbe15eb004de81b1", + "2db66f1ba44a9ee00e0475d09d0e48ec4608a0a9086e3ce67bbd5df04a863798", + "cba37a1c5294106c52ea84f0168bd49d9cba246fd9e445f7fa84e7b174778295", + "2d0d39958a00f232ab0a10b8c952c57788fccff53708b53dadf6c84bde47f607", + "162a206f01b2719c6ee07d9cacb0302d6f6e60fa378a7e5c2e508c395b263e21", + "498f1e265105d0776d64b23da84bf36fe827fbfabad4b0789c6e6ca576311987", + "9fbf69f1c731aabfaa38f4c82f8fb642c4210f7d0246f20244c3f9ec482407d9", + "86d75262dc429c7b1a70b2477f959a7e27e7591ae725c8a47d875ccefeb36c18", + "82c62b72d3cf26916e9fd41df31c18ba4c1e0fc620a2f719a1418ebd3c6de580", + "0ab4110fa25fab74ab979f3e6c15e78646953c2f9c858e74febc069bdd257fb7", + "48089dcb506284d907b428e676f497f1e5913ac5c0c764fc4ddb25d60df42592", + "fc46fe189d7e9ee3ce27437c156d24887e8209ece327e26bb179e5c4daa93f5c", + "9861dfa2c4e34d622db57fc97fcbca843dc8a369bd4e20ad5bcbf232d62a4a95", + "c2b02e05449ab5405ec421c1868336c8aa2ba5cff88be2a0a235807e2465f2a1", + "4410c5e98eb8eee34ce832a1bc5a2f8f35b1c7e644ff9e520853639a138c9d66", + "f9c661608a909b9305678c6bb4095f9236aba2320439067def4aaa1f86fcd0ea", + "7681d1d18d441165db3ddfd078ca839a96ce8c568f40a3757ad16dcc8b0a0f9e", + "0c72ea868739f6b8e7442285d6ba2f11bd1247aca3f1adb0fd352ae3fc07e4c6", + "7e33964c115e29b35946a0bfae27379b74046fdcd4a458164617b4f2d964a999", + "c13d3a8ab7f0be6307664cf1adcb0fecb0b4a24ace38d8255db73143ddc6ee04", + "8a192c36a99bccd5bb6ea4f2845f7d4634afccd50207ad954d3261d5363a88e3", + "a17602c893e16edd376ba95578d5163b4f62e48fe7a88628cede02483b77cdae", + "61986320f25184fa32d4dac16b400b01043c41537d4d1d6f364493d565dd865e", + "40dc376bfd55dd54f19084d7e47b3c6123ec3a7b3e4ef9f85d0269c0474af630", + "a6f6dadddcdf7e2ab358bc076b06b31a39d4bcde2bce5434db6c3d8d710e5610", + "9646df212d0f422304e58431a648bab9763dac20d36a564c2093b60d29192727", + "bd0b10158e0c3c8dfd32befde09d0b81ef5fb64119b261663ec692e71ceece1a", + "fdc79d51f20417ecb4aaf88a287b6c6a254985c66f66def309eebe200d7e904d", + "c400d264d87d9f2eab481c0bdfa21a20bd6c2baa28b684566522600abe937a18", + "135c4391efe6fa8192f2677bb808f31a99405793d6c09a802e4c5f41ce649811", + "74faab0850b9043dd0e489c5586711820696f4081e5d5ccee75d1987bf894ddc", + "883ae15e7dcfb1202512cc93519d6399911a7089694a64c5aa63aa29e39f6db0", + "079f79095ba4bd18ec23539d1bac58364cc39aa90cb7b186b10deb3b467d96c0", + "164fc5cd555d7b072c33e81c4905bb0e9c5a9a9629e91ed5e62e77a22f0078be", + "7a274482c5b77ce03e5fb61ba2208ca25ad923900c3b30237e7c7d30e9329b1d", + "1fb12e32f27ee5f24b4c43d42e9a1e03eabc56ec36f22b5c7dac30808b61f0e1", + "47889b95632372b5925fd08ce60ed0d40320dfb97e6f4488a961f67c3d3aada2", + "eb63e8ed90386cd3a2a7df39732bc2ee1f30c193cc960c5f8a60dcad797a4187", + "1a0995f17248897a050e8e3bf7c1e409b4eb1adb821ff5202476e3ae17d2fe59", + "b04fa501fda38ca62e933914d47330d6761445d7213dcaaa253f8a652d444c73", + "3061c755229f1c78d44f604ea1122024b757aebb83f1e7bd15e4a0e5b3cdd729", + "72fa10ba908ac94d06ae1544d73d55e94a6e19773e9bae0d488bc80bb959a4d6", + "328070cbbea0bd9a744ead8bc5f0767ac1bc077b29e2d8b19706376399c1cc9a", + "34a99dfd374ec50835b7a54babef66679932ca74ca0d37dcfc56831b206462d4", + "90ba81d4b4256e3f5dd7958e06f4cd08960d5a0d20ed96bc1290600146fd4233", + "efe2f3be76ba708f775afd6513c998c47e60d0ffca44f3946145aaadd542bd04", + "3af3302e5e81a2d3577638c90db8b1df64c7fb64d1512b0b149ad9f3729428d8", + "a5b32771058216efd7d94cf16daf6d7c15b8a2e38fbc83fd4f842d3b4c5196b1", + "0519bc7817c5a0d4d34762bc66ac224ccc2601bfbc3d920f21c6e14d9640ddc0", + "dec550761f5f3583885485d895b9db314864f17c2edd76d22c229bf210aa0812", + "b95e6e8b1c10d814e304e46cd79d9d68861247567cd89a28fa473d48cff91ef0", + "97b46b319d84b8fcd386facefe30e940a2824ec49a1619a635c8ebd722a78339", + "fb1f8d31a920658fb57949796270a1ca1bbf6b0b41ab688fb46ab67682ff8984", + "54e896b3c54655353f8189522f6a179a05db2c3d5b15b387958cf8c5d8a584b8", + "02c105cf492ef2ba516d037915e8579b4a6cf106a0b0cfc55a6d25a4570e21d7", + "9fac46f88fc0d3ea3788e67c7cf2ffce2ad3c19dc947b00b03038465844418b0", + "1b1b8c590871656fd43b33c3e7ede43c656764af11ac75c303d96ad199284ab1", + "2b4c0bfad19749ac178c7fb9e2a2be0f0601c727cdbb57b24dad4d3d885a17f8", + "82ba5d0f0cf9d99c0635ab9ff7f888eac6b53ce21bc350410200d7d8f4fa353f", + "4742a9ae547b3af2889f3745e229543b4b2d2a0e7dab2d24ecdbcdc4b73727e8", + "e15ad5f2d9e229f9d489e09f0a9873fcdbb46d0aba3e9d471b37fdad54b82bd2", + "352275fb8c4f71e65e186062cc4fd2a111ba9111159f014f14c3f56c9f154729", + "cab33bc1fdc8a8cbeaa5c7c9a89cd6e3d5a04661d8090b0c6fe573e87705799d", + "f83bfb128d6b94ac0c303fed12c8be75a6cbc7a4545ae6439a99a573da6ab838", + "bff22e0b7fe9b588cd203972e8247c14912d2f323275974dfeaf1fad12c25e04", + "37e38665e261ea8c379e6c7afa39124489cf92a64363f1f7c6aa58a4567e22a1", + "b3c66e6a7e77ce9cb917b5d87ba21f4ab8f0b5ba5a41dc9eb1a1d5cfc7414215", + "b5aee43fc4c6cd7ebbf283da20d5a47285bd455618008839d9bf968deacab411", + "1c28ca1aeeb4420604647dfc4fd226e253722bdc2acae7fa0ca24a1eaf829abd", + "31fd830e9529ec121b493a137a12586fe92ef88f46cc59eef24783a87498ec74", + "067ab189cafa4f3c8d76ff805c76eff5220a8378aa60136d1a949a2c5dcc6eb8", + "12c1068323cd5e349d24a356575e04066ad4b7b96605bf64657037664664f4f5", + "8dc47d6c371efebedfcd0798e1c6e0ef00ffafc4d514c0b88cb345b52f3b4b57", + "7652fcf6a2e764b35ed163041ed183bef9343795d2c93607bff4ff95d3a69c7a", + "16753270f43e09e39d391b440487538004c6d89e9d7e9eae93bc605f0649cfef", + "ceb270fe62a6a5720fb6b9bcc829d04dccdcd9a27caf7e24b746b05a410aafeb", + "b8f513e5872631baf9bfc58dfc6cf2e2622c23d032443e22bae413dca92f5570", + "6e8b8f5525f4dd1829ba616481a0cbb8be2d71e4418f01fe21cbe2c691e54d01", + "bc96c44a8cbb03b71eae390bbbcc93f13657c6724203385a07b470f5a5272e03", + "1b4943ec89da10a571250e00a08c564516f68221dbd895d7e3787e26ce59a4ae", + "be806cb56d4f93ee33ee00c82f2bae5579646cc6fbb006cf0ec25c105b5433bf", + "71df5d4d9b2775ed04c81d60dfaf79ef04374bc66eaca0248363f91f29862c06", + "78db6f5ecbdf3c37f24f46045fb74fcccfd10a01d4d0575046381c4e715792f5", + "35e5425764073f28de6738acd006e19c3a2153596f327fa87472ec6949458432", + "3ba0c167caa775e3b6b8111e2f9d8926598d0643275f1957264360a8416ba0e8", + "cf4de1cc280a7b55a91d5eec1df0e9d0dc2527c9aaf557cfb3268d9ea34c49b8", + "1c9fc23c5454351bc820f4e1dd9296e5a169ca8b7316b7a1bb1f7c3571212418", + "59f334a1230565d6eccfd5e17f24d4be30a910979742ac6325bb330b28a167c5", + "32571e8cacc17e438bfb8f1e619760b4674074a89dd16cd42274faa52775f94f", + "fd962c1691d84bb6141b7bd2243ada3aecbada06c08c22a26638eb71e0c8bfea", + "a8429383c1c0f12c82bccc062496f2986e4d805f99f13d1588c8cb962a84ab53", + "474199305764091876f8453f7d56b64f37d607b2c09d915577b6512c8a038cc9", + "ce0f4ebbdaa10937725ec1aff385621f56314787665386b3402037d9f62be6cc", + "5d8c6d8564b823c967db5cf47d1c980faaa48e921c7d285447deb9b7564a5992", + "f8f15bd7866186412cbcbb10184d12f7d2e89dfe51179a1b5bdc445cbd3f1bc5", + "c7b98e7bfe664134ce27ade3de25a8fc5ed16c9f5a376e66ab0f5d83e56a1d0b", + "06b45f3a31ecc038ce0a98546208f9ef9daa4d9c7ec7bf09e1adfc6451fc162b", + "582b141e0a0b40204a664c68d8e06611d9eab94b93b2733d51f4eb43ea57b68f", + "7bb6e80c4b28d82feb644b0335643ac5b00d30ab99af1d1967f458a5e6c30f0f", + "1983fcc1290866cbad126d730a2331d968d16413f1757d85f41b37d661df8766", + "7c1187445c1bb53f7845d950f2783f70e8ef32b097c14051c03d67d899fdc876", + "6bd1cbc0c3108036ef4883ba47a572a0c0e288fc08805290df211d091f3f4c48", + "60bcae60aeb941a0bf6e5e3a04fed47c02ba3e4d2acaab35fd8632b68d971938", + "705f9f2a40fea5d3fb1a8e0bdd49797a082e4f3bd5da97330398668c975bd72b", + "e1e70df6082fb346b5d59670967b723b9b3d36f592f213e309f6d2e77c5e4f34", + "e4a0e2f949b023f9024724ef841088571dab106a5f29eea901b8cb5cca3637e5", + "be1a2a831e3ec3ae2d54c697499f1fb75756285abad7f188d19e1c5c6d565993", + "f718a89e1fee5aa421805a9018f0d6c830d1c6c221d9c85a9df154516747f4a3", + "c1d6a237a7e4acb7329cd480bf9087f61b362200ac93da46e8300d24ccb12b1d", + "a070e6800c5e9dc6a3f3cff153fac52c11afd7752769fac7bef8e9f37376da1f", + "a1f0835454a056197d5c91d6c33cf9e8b5afe6a4d46d6e929273dd7057f754cb", + "dd2eb71d6814259e0b4a68e8981a0c8a15fed2a7b97d4387473623f2012b5b1e", + "e467fbf9e56b41691ada3ea4076a2b7d76db4e688c429a657508738cb3be98a0", + "9147084b15f87dbdbceffb36c305b03162cbadcca65cdced9f70c8682a3e5a27", + "46da64798917b3842c7de18b5638282efc295078faf4a90f5ff1e0eb6270c2b6", + "5601c8c8256eb6c51da3e26aa7ec13121a09258d49ffdcd05e5d8a64a91ec4a4", + "086618b0a9980d6d662b3019dcec9afec63371cd702a914c32d58c3431896ff1", + "f6e07fbba1de3322827b31bfc0a5bee7bbcde4ed0fce2ec1cf89fffb70151b5c", + "bd83eb7e32270a5d67caca5261f4a5c4dc5c67dfbb3b4230e5f7fff51680cc44", + "5a430b72b2d0a5fcb31cd4e52ec8fd3346b81f0a04eac20d4f60c2a058fcc7c7", + "3a5cd674803091499af865e6714be801c2458fc54df1a5ebde8934b2367d846f", + "45b8ffeb50577c61d1bd98ba49969bc4095f84a84703fd8f4fda45ea13aa16d3", +} + +const sepoliaPreverifiedHeight uint64 = 516864 From 227bb7368937ba408da82fddcacc02d27153d4fe Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Thu, 17 Feb 2022 14:37:26 +0700 Subject: [PATCH 168/261] save (#3533) --- eth/backend.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eth/backend.go b/eth/backend.go index 55e5218b34f..0bd46d9dfe8 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -756,7 +756,7 @@ func (s *Ethereum) Stop() error { sentryServer.Close() } s.chainDB.Close() - if s.config.TxPool.V2 { + if s.config.TxPool.V2 && s.txPool2DB != nil { s.txPool2DB.Close() } return nil From 98b6603b0a4fe9491c414488dbb4a727cfe7d2f3 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Fri, 18 Feb 2022 02:05:44 -0300 Subject: [PATCH 169/261] Extract ots_getBlockDetails into its own file --- cmd/rpcdaemon/commands/otterscan_api.go | 40 ---------------- .../commands/otterscan_block_details.go | 48 +++++++++++++++++++ 2 files changed, 48 insertions(+), 40 deletions(-) create mode 100644 cmd/rpcdaemon/commands/otterscan_block_details.go diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index e1e2f2197bd..2647b1299d8 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -399,46 +399,6 @@ func (api *OtterscanAPIImpl) getBlockWithSenders(number rpc.BlockNumber, tx kv.T return block, senders, err } -func (api *OtterscanAPIImpl) GetBlockDetails(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) { - tx, err := api.db.BeginRo(ctx) - if err != nil { - return nil, err - } - defer tx.Rollback() - - b, senders, err := api.getBlockWithSenders(number, tx) - if err != nil { - return nil, err - } - if b == nil { - return nil, nil - } - - chainConfig, err := api.chainConfig(tx) - if err != nil { - return nil, err - } - - getBlockRes, err := api.delegateGetBlockByNumber(tx, b, number, false) - if err != nil { - return nil, err - } - getIssuanceRes, err := api.delegateIssuance(tx, b, chainConfig) - if err != nil { - return nil, err - } - feesRes, err := api.delegateBlockFees(ctx, tx, b, senders, chainConfig) - if err != nil { - return nil, err - } - - response := map[string]interface{}{} - response["block"] = getBlockRes - response["issuance"] = getIssuanceRes - response["totalFees"] = hexutil.Uint64(feesRes) - return response, nil -} - func (api *OtterscanAPIImpl) GetBlockTransactions(ctx context.Context, number rpc.BlockNumber, pageNumber uint8, pageSize uint8) (map[string]interface{}, error) { tx, err := api.db.BeginRo(ctx) if err != nil { diff --git a/cmd/rpcdaemon/commands/otterscan_block_details.go b/cmd/rpcdaemon/commands/otterscan_block_details.go new file mode 100644 index 00000000000..62135b73dfe --- /dev/null +++ b/cmd/rpcdaemon/commands/otterscan_block_details.go @@ -0,0 +1,48 @@ +package commands + +import ( + "context" + + "github.com/ledgerwatch/erigon/common/hexutil" + "github.com/ledgerwatch/erigon/rpc" +) + +func (api *OtterscanAPIImpl) GetBlockDetails(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) { + tx, err := api.db.BeginRo(ctx) + if err != nil { + return nil, err + } + defer tx.Rollback() + + b, senders, err := api.getBlockWithSenders(number, tx) + if err != nil { + return nil, err + } + if b == nil { + return nil, nil + } + + chainConfig, err := api.chainConfig(tx) + if err != nil { + return nil, err + } + + getBlockRes, err := api.delegateGetBlockByNumber(tx, b, number, false) + if err != nil { + return nil, err + } + getIssuanceRes, err := api.delegateIssuance(tx, b, chainConfig) + if err != nil { + return nil, err + } + feesRes, err := api.delegateBlockFees(ctx, tx, b, senders, chainConfig) + if err != nil { + return nil, err + } + + response := map[string]interface{}{} + response["block"] = getBlockRes + response["issuance"] = getIssuanceRes + response["totalFees"] = hexutil.Uint64(feesRes) + return response, nil +} From 78b3f06e4b9d4e5b33997bc06514b096848db6cf Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Fri, 18 Feb 2022 02:22:51 -0300 Subject: [PATCH 170/261] Add ots_getBlockDetailsByHash --- cmd/rpcdaemon/commands/otterscan_api.go | 3 +- .../commands/otterscan_block_details.go | 42 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 2647b1299d8..990fd7db1fb 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -32,7 +32,7 @@ import ( ) // API_LEVEL Must be incremented every time new additions are made -const API_LEVEL = 6 +const API_LEVEL = 7 type TransactionsWithReceipts struct { Txs []*RPCTransaction `json:"txs"` @@ -47,6 +47,7 @@ type OtterscanAPI interface { SearchTransactionsBefore(ctx context.Context, addr common.Address, blockNum uint64, pageSize uint16) (*TransactionsWithReceipts, error) SearchTransactionsAfter(ctx context.Context, addr common.Address, blockNum uint64, pageSize uint16) (*TransactionsWithReceipts, error) GetBlockDetails(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) + GetBlockDetailsByHash(ctx context.Context, hash common.Hash) (map[string]interface{}, error) GetBlockTransactions(ctx context.Context, number rpc.BlockNumber, pageNumber uint8, pageSize uint8) (map[string]interface{}, error) HasCode(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (bool, error) TraceTransaction(ctx context.Context, hash common.Hash) ([]*otterscan.TraceEntry, error) diff --git a/cmd/rpcdaemon/commands/otterscan_block_details.go b/cmd/rpcdaemon/commands/otterscan_block_details.go index 62135b73dfe..87355346aa5 100644 --- a/cmd/rpcdaemon/commands/otterscan_block_details.go +++ b/cmd/rpcdaemon/commands/otterscan_block_details.go @@ -3,7 +3,9 @@ package commands import ( "context" + "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/hexutil" + "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/rpc" ) @@ -46,3 +48,43 @@ func (api *OtterscanAPIImpl) GetBlockDetails(ctx context.Context, number rpc.Blo response["totalFees"] = hexutil.Uint64(feesRes) return response, nil } + +func (api *OtterscanAPIImpl) GetBlockDetailsByHash(ctx context.Context, hash common.Hash) (map[string]interface{}, error) { + tx, err := api.db.BeginRo(ctx) + if err != nil { + return nil, err + } + defer tx.Rollback() + + b, senders, err := rawdb.ReadBlockByHashWithSenders(tx, hash) + if err != nil { + return nil, err + } + if b == nil { + return nil, nil + } + + chainConfig, err := api.chainConfig(tx) + if err != nil { + return nil, err + } + + getBlockRes, err := api.delegateGetBlockByNumber(tx, b, rpc.BlockNumber(b.Number().Int64()), false) + if err != nil { + return nil, err + } + getIssuanceRes, err := api.delegateIssuance(tx, b, chainConfig) + if err != nil { + return nil, err + } + feesRes, err := api.delegateBlockFees(ctx, tx, b, senders, chainConfig) + if err != nil { + return nil, err + } + + response := map[string]interface{}{} + response["block"] = getBlockRes + response["issuance"] = getIssuanceRes + response["totalFees"] = hexutil.Uint64(feesRes) + return response, nil +} From 7273c0b65cbddd295b404e7583508e0f674d4a50 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Fri, 18 Feb 2022 02:24:00 -0300 Subject: [PATCH 171/261] Add TODO --- cmd/rpcdaemon/commands/otterscan_block_details.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/rpcdaemon/commands/otterscan_block_details.go b/cmd/rpcdaemon/commands/otterscan_block_details.go index 87355346aa5..86b324f0f70 100644 --- a/cmd/rpcdaemon/commands/otterscan_block_details.go +++ b/cmd/rpcdaemon/commands/otterscan_block_details.go @@ -49,6 +49,7 @@ func (api *OtterscanAPIImpl) GetBlockDetails(ctx context.Context, number rpc.Blo return response, nil } +// TODO: remove duplication with GetBlockDetails func (api *OtterscanAPIImpl) GetBlockDetailsByHash(ctx context.Context, hash common.Hash) (map[string]interface{}, error) { tx, err := api.db.BeginRo(ctx) if err != nil { From 215661392f052e91fb561e613fcc7560aacf2530 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Fri, 18 Feb 2022 22:08:56 +0700 Subject: [PATCH 172/261] Rpcdaemon start with disabled txpool (#3540) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 6fe70f5e8b7..93df3931d0f 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20220212095410-fa2dc4720eb0 + github.com/ledgerwatch/erigon-lib v0.0.0-20220218024433-4f4c1fcf22a9 github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 diff --git a/go.sum b/go.sum index b0f119a596b..3280fad9cef 100644 --- a/go.sum +++ b/go.sum @@ -493,8 +493,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20220212095410-fa2dc4720eb0 h1:dXFUMIIlbO9QtcULfvx2akZSt6zab/z+Oaw6ykpBtbE= -github.com/ledgerwatch/erigon-lib v0.0.0-20220212095410-fa2dc4720eb0/go.mod h1:BQNYmN6i8RdHqedsztAj3XDnswYebacmFAnsznlisTc= +github.com/ledgerwatch/erigon-lib v0.0.0-20220218024433-4f4c1fcf22a9 h1:gXVXqLZEHtk/M/ylqc9eDNmu1fLIxyGNRXplHOqNlc0= +github.com/ledgerwatch/erigon-lib v0.0.0-20220218024433-4f4c1fcf22a9/go.mod h1:BQNYmN6i8RdHqedsztAj3XDnswYebacmFAnsznlisTc= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= From 764230ffc8473869e8654e03686425b7163af1b2 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Tue, 22 Feb 2022 03:16:47 -0300 Subject: [PATCH 173/261] Add ots_getContractCreator method --- cmd/rpcdaemon/commands/otterscan_api.go | 3 +- .../commands/otterscan_contract_creator.go | 169 ++++++++++++++++++ .../otterscan_contract_creator_tracer.go | 75 ++++++++ .../commands/otterscan_generic_tracer.go | 75 ++++++++ 4 files changed, 321 insertions(+), 1 deletion(-) create mode 100644 cmd/rpcdaemon/commands/otterscan_contract_creator.go create mode 100644 cmd/rpcdaemon/commands/otterscan_contract_creator_tracer.go create mode 100644 cmd/rpcdaemon/commands/otterscan_generic_tracer.go diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 990fd7db1fb..1f1c5be6b31 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -32,7 +32,7 @@ import ( ) // API_LEVEL Must be incremented every time new additions are made -const API_LEVEL = 7 +const API_LEVEL = 8 type TransactionsWithReceipts struct { Txs []*RPCTransaction `json:"txs"` @@ -53,6 +53,7 @@ type OtterscanAPI interface { TraceTransaction(ctx context.Context, hash common.Hash) ([]*otterscan.TraceEntry, error) GetTransactionError(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) GetTransactionBySenderAndNonce(ctx context.Context, addr common.Address, nonce uint64) (*common.Hash, error) + GetContractCreator(ctx context.Context, addr common.Address) (*ContractCreatorData, error) } type OtterscanAPIImpl struct { diff --git a/cmd/rpcdaemon/commands/otterscan_contract_creator.go b/cmd/rpcdaemon/commands/otterscan_contract_creator.go new file mode 100644 index 00000000000..2bef2cc040d --- /dev/null +++ b/cmd/rpcdaemon/commands/otterscan_contract_creator.go @@ -0,0 +1,169 @@ +package commands + +import ( + "bytes" + "context" + "fmt" + "sort" + + "github.com/RoaringBitmap/roaring/roaring64" + "github.com/ledgerwatch/erigon-lib/kv" + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/common/changeset" + "github.com/ledgerwatch/erigon/core/state" + "github.com/ledgerwatch/erigon/core/types/accounts" + "github.com/ledgerwatch/log/v3" +) + +type ContractCreatorData struct { + Tx common.Hash `json:"hash"` + Creator common.Address `json:"creator"` +} + +func (api *OtterscanAPIImpl) GetContractCreator(ctx context.Context, addr common.Address) (*ContractCreatorData, error) { + tx, err := api.db.BeginRo(ctx) + if err != nil { + return nil, err + } + defer tx.Rollback() + + reader := state.NewPlainStateReader(tx) + plainStateAcc, err := reader.ReadAccountData(addr) + if err != nil { + return nil, err + } + + // No state == non existent + if plainStateAcc == nil { + return nil, nil + } + + // EOA? + if plainStateAcc.IsEmptyCodeHash() { + return nil, nil + } + + // Contract; search for creation tx; navigate forward on AccountsHistory/ChangeSets + // + // We search shards in forward order on purpose because popular contracts may have + // dozens of states changes due to ETH deposits/withdraw after contract creation, + // so it is optimal to search from the beginning even if the contract has multiple + // incarnations. + accHistory, err := tx.Cursor(kv.AccountsHistory) + if err != nil { + return nil, err + } + defer accHistory.Close() + + accCS, err := tx.CursorDupSort(kv.AccountChangeSet) + if err != nil { + return nil, err + } + defer accCS.Close() + + // Locate shard that contains the block where incarnation changed + acs := changeset.Mapper[kv.AccountChangeSet] + k, v, err := accHistory.Seek(acs.IndexChunkKey(addr.Bytes(), 0)) + if err != nil { + return nil, err + } + if !bytes.HasPrefix(k, addr.Bytes()) { + log.Error("Couldn't find any shard for account history", "addr", addr) + return nil, fmt.Errorf("could't find any shard for account history addr=%v", addr) + } + + var acc accounts.Account + bm := roaring64.NewBitmap() + prevShardMaxBl := uint64(0) + for { + _, err := bm.ReadFrom(bytes.NewReader(v)) + if err != nil { + return nil, err + } + + // Shortcut precheck + st, err := acs.Find(accCS, bm.Maximum(), addr.Bytes()) + if err != nil { + return nil, err + } + if st == nil { + log.Error("Unexpected error, couldn't find changeset", "block", bm.Maximum(), "addr", addr) + return nil, fmt.Errorf("unexpected error, couldn't find changeset block=%v addr=%v", bm.Maximum(), addr) + } + + // Found the shard where the incarnation change happens; ignore all + // next shards + if err := acc.DecodeForStorage(st); err != nil { + return nil, err + } + if acc.Incarnation >= plainStateAcc.Incarnation { + break + } + prevShardMaxBl = bm.Maximum() + + k, v, err = accHistory.Next() + if err != nil { + return nil, err + } + + // No more shards; it means the max bl from previous shard + // contains the incarnation change + if !bytes.HasPrefix(k, addr.Bytes()) { + break + } + } + + // Binary search block number inside shard; get first block where desired + // incarnation appears + blocks := bm.ToArray() + var searchErr error + r := sort.Search(len(blocks), func(i int) bool { + bl := blocks[i] + st, err := acs.Find(accCS, bl, addr.Bytes()) + if err != nil { + searchErr = err + return false + } + if st == nil { + log.Error("Unexpected error, couldn't find changeset", "block", bl, "addr", addr) + return false + } + + if err := acc.DecodeForStorage(st); err != nil { + searchErr = err + return false + } + if acc.Incarnation < plainStateAcc.Incarnation { + return false + } + return true + }) + + if searchErr != nil { + return nil, searchErr + } + + // The sort.Search function finds the first block where the incarnation has + // changed to the desired one, so we get the previous block from the bitmap; + // however if the found block is already the first one from the bitmap, it means + // the block we want is the max block from the previous shard. + blockFound := prevShardMaxBl + if r > 0 { + blockFound = blocks[r-1] + } + + // Trace block, find tx and contract creator + chainConfig, err := api.chainConfig(tx) + if err != nil { + return nil, err + } + tracer := NewCreateTracer(ctx, addr) + if err := api.genericTracer(tx, ctx, blockFound, chainConfig, tracer); err != nil { + return nil, err + } + + return &ContractCreatorData{ + Tx: tracer.Tx.Hash(), + Creator: tracer.Creator, + }, nil +} diff --git a/cmd/rpcdaemon/commands/otterscan_contract_creator_tracer.go b/cmd/rpcdaemon/commands/otterscan_contract_creator_tracer.go new file mode 100644 index 00000000000..ce6c52f4067 --- /dev/null +++ b/cmd/rpcdaemon/commands/otterscan_contract_creator_tracer.go @@ -0,0 +1,75 @@ +package commands + +import ( + "context" + "math/big" + "time" + + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/core/vm" + "github.com/ledgerwatch/erigon/core/vm/stack" +) + +type CreateTracer struct { + ctx context.Context + target common.Address + found bool + Creator common.Address + Tx types.Transaction +} + +func NewCreateTracer(ctx context.Context, target common.Address) *CreateTracer { + return &CreateTracer{ + ctx: ctx, + target: target, + found: false, + } +} + +func (t *CreateTracer) SetTransaction(tx types.Transaction) { + t.Tx = tx +} + +func (t *CreateTracer) Found() bool { + return t.found +} + +func (t *CreateTracer) CaptureStart(depth int, from common.Address, to common.Address, precompile bool, create bool, calltype vm.CallType, input []byte, gas uint64, value *big.Int, code []byte) error { + if t.found { + return nil + } + if !create { + return nil + } + if to != t.target { + return nil + } + + t.found = true + t.Creator = from + return nil +} + +func (t *CreateTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, rData []byte, contract *vm.Contract, depth int, err error) error { + return nil +} + +func (t *CreateTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *stack.Stack, contract *vm.Contract, depth int, err error) error { + return nil +} + +func (t *CreateTracer) CaptureEnd(depth int, output []byte, startGas, endGas uint64, d time.Duration, err error) error { + return nil +} + +func (t *CreateTracer) CaptureSelfDestruct(from common.Address, to common.Address, value *big.Int) { +} + +func (t *CreateTracer) CaptureAccountRead(account common.Address) error { + return nil +} + +func (t *CreateTracer) CaptureAccountWrite(account common.Address) error { + return nil +} diff --git a/cmd/rpcdaemon/commands/otterscan_generic_tracer.go b/cmd/rpcdaemon/commands/otterscan_generic_tracer.go new file mode 100644 index 00000000000..dde627e4de2 --- /dev/null +++ b/cmd/rpcdaemon/commands/otterscan_generic_tracer.go @@ -0,0 +1,75 @@ +package commands + +import ( + "context" + + "github.com/ledgerwatch/erigon-lib/kv" + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/consensus/ethash" + "github.com/ledgerwatch/erigon/core" + "github.com/ledgerwatch/erigon/core/rawdb" + "github.com/ledgerwatch/erigon/core/state" + "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/core/vm" + "github.com/ledgerwatch/erigon/ethdb" + "github.com/ledgerwatch/erigon/params" + "github.com/ledgerwatch/erigon/turbo/shards" +) + +type GenericTracer interface { + vm.Tracer + SetTransaction(tx types.Transaction) + Found() bool +} + +func (api *OtterscanAPIImpl) genericTracer(dbtx kv.Tx, ctx context.Context, blockNum uint64, chainConfig *params.ChainConfig, tracer GenericTracer) error { + // Retrieve the transaction and assemble its EVM context + blockHash, err := rawdb.ReadCanonicalHash(dbtx, blockNum) + if err != nil { + return err + } + + block, _, err := rawdb.ReadBlockWithSenders(dbtx, blockHash, blockNum) + if err != nil { + return err + } + + reader := state.NewPlainState(dbtx, blockNum-1) + stateCache := shards.NewStateCache(32, 0 /* no limit */) + cachedReader := state.NewCachedReader(reader, stateCache) + noop := state.NewNoopWriter() + cachedWriter := state.NewCachedWriter(noop, stateCache) + + ibs := state.New(cachedReader) + signer := types.MakeSigner(chainConfig, blockNum) + + getHeader := func(hash common.Hash, number uint64) *types.Header { + return rawdb.ReadHeader(dbtx, hash, number) + } + engine := ethash.NewFaker() + checkTEVM := ethdb.GetHasTEVM(dbtx) + + // blockReceipts := rawdb.ReadReceipts(dbtx, block, senders) + header := block.Header() + for idx, tx := range block.Transactions() { + ibs.Prepare(tx.Hash(), block.Hash(), idx) + + msg, _ := tx.AsMessage(*signer, header.BaseFee) + + BlockContext := core.NewEVMBlockContext(header, getHeader, engine, nil, checkTEVM) + TxContext := core.NewEVMTxContext(msg) + + vmenv := vm.NewEVM(BlockContext, TxContext, ibs, chainConfig, vm.Config{Debug: true, Tracer: tracer}) + if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(tx.GetGas()), true /* refunds */, false /* gasBailout */); err != nil { + return err + } + _ = ibs.FinalizeTx(vmenv.ChainConfig().Rules(block.NumberU64()), cachedWriter) + + if tracer.Found() { + tracer.SetTransaction(tx) + return nil + } + } + + return nil +} From 2bb50d4fe8d289dc8323ebab5461b713d98e1f2d Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Tue, 22 Feb 2022 17:28:55 +0700 Subject: [PATCH 174/261] save (#3568) --- cmd/sentry/download/sentry.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/cmd/sentry/download/sentry.go b/cmd/sentry/download/sentry.go index fe0e3fb7fde..ac964d965a3 100644 --- a/cmd/sentry/download/sentry.go +++ b/cmd/sentry/download/sentry.go @@ -57,6 +57,8 @@ type PeerInfo struct { rw p2p.MsgReadWriter removed chan struct{} // close this channel on remove + ctx context.Context + ctxCancel context.CancelFunc removeOnce sync.Once // each peer has own worker (goroutine) - all funcs from this queue will execute on this worker // if this queue is full (means peer is slow) - old messages will be dropped @@ -65,7 +67,9 @@ type PeerInfo struct { } func NewPeerInfo(peer *p2p.Peer, rw p2p.MsgReadWriter) *PeerInfo { - p := &PeerInfo{peer: peer, rw: rw, removed: make(chan struct{}), tasks: make(chan func(), 16)} + ctx, cancel := context.WithCancel(context.Background()) + + p := &PeerInfo{peer: peer, rw: rw, removed: make(chan struct{}), tasks: make(chan func(), 16), ctx: ctx, ctxCancel: cancel} go func() { // each peer has own worker, then slow for f := range p.tasks { f() @@ -125,7 +129,7 @@ func (pi *PeerInfo) Remove() { defer pi.lock.Unlock() pi.removeOnce.Do(func() { close(pi.removed) - close(pi.tasks) + pi.ctxCancel() }) } @@ -134,6 +138,11 @@ func (pi *PeerInfo) Async(f func()) { defer pi.lock.Unlock() select { case <-pi.removed: // noop if peer removed + case <-pi.ctx.Done(): + if pi.tasks != nil { + close(pi.tasks) + pi.tasks = nil + } case pi.tasks <- f: if len(pi.tasks) == cap(pi.tasks) { // if channel full - loose old messages for i := 0; i < cap(pi.tasks)/2; i++ { From 3d959a37d16d33ac033b7efe638407e8ac74abff Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Wed, 23 Feb 2022 14:01:22 +0000 Subject: [PATCH 175/261] Update version.go (#3588) --- params/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/params/version.go b/params/version.go index a05ef00eaf7..c2c8b13e106 100644 --- a/params/version.go +++ b/params/version.go @@ -33,7 +33,7 @@ var ( const ( VersionMajor = 2022 // Major version component of the current release VersionMinor = 2 // Minor version component of the current release - VersionMicro = 3 // Patch version component of the current release + VersionMicro = 4 // Patch version component of the current release VersionModifier = "beta" // Patch version component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" From e1a36394bdd08742037a04caa87a3c2d5071facf Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Wed, 23 Feb 2022 14:01:32 +0000 Subject: [PATCH 176/261] [stable][txpool] Remove unsafe parameter for onSenderStateChange (#3585) Co-authored-by: Alex Sharp --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 93df3931d0f..0cfeb605312 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20220218024433-4f4c1fcf22a9 + github.com/ledgerwatch/erigon-lib v0.0.0-20220222093403-f3e052f4dd1d github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 diff --git a/go.sum b/go.sum index 3280fad9cef..6c699acc05b 100644 --- a/go.sum +++ b/go.sum @@ -493,8 +493,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20220218024433-4f4c1fcf22a9 h1:gXVXqLZEHtk/M/ylqc9eDNmu1fLIxyGNRXplHOqNlc0= -github.com/ledgerwatch/erigon-lib v0.0.0-20220218024433-4f4c1fcf22a9/go.mod h1:BQNYmN6i8RdHqedsztAj3XDnswYebacmFAnsznlisTc= +github.com/ledgerwatch/erigon-lib v0.0.0-20220222093403-f3e052f4dd1d h1:y3RwITHJ5SE3W2WXAqVMsRvMsjnp2IPFsPHOWBhsHzk= +github.com/ledgerwatch/erigon-lib v0.0.0-20220222093403-f3e052f4dd1d/go.mod h1:BQNYmN6i8RdHqedsztAj3XDnswYebacmFAnsznlisTc= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= From 97a695e8372a6a35d0f0c7317222f52bde91da0c Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Wed, 23 Feb 2022 14:01:41 +0000 Subject: [PATCH 177/261] Fixes to access list and state overrides (#3570) (#3586) Co-authored-by: Alex Sharp Co-authored-by: Alex Sharp --- cmd/rpcdaemon/commands/eth_call.go | 2 +- core/state/state_object.go | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/cmd/rpcdaemon/commands/eth_call.go b/cmd/rpcdaemon/commands/eth_call.go index 97321e8453c..99ccbb97019 100644 --- a/cmd/rpcdaemon/commands/eth_call.go +++ b/cmd/rpcdaemon/commands/eth_call.go @@ -336,7 +336,6 @@ func (api *APIImpl) CreateAccessList(ctx context.Context, args ethapi.CallArgs, } else { stateReader = state.NewPlainState(tx, blockNumber) } - state := state.New(stateReader) header := block.Header() // If the gas amount is not set, extract this as it will depend on access @@ -373,6 +372,7 @@ func (api *APIImpl) CreateAccessList(ctx context.Context, args ethapi.CallArgs, prevTracer = logger.NewAccessListTracer(*args.AccessList, *args.From, to, precompiles) } for { + state := state.New(stateReader) // Retrieve the current access list to expand accessList := prevTracer.AccessList() log.Trace("Creating access list", "input", accessList) diff --git a/core/state/state_object.go b/core/state/state_object.go index 55d416d0a1a..8ac57cfcd51 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -156,6 +156,11 @@ func (so *stateObject) touch() { // GetState returns a value from account storage. func (so *stateObject) GetState(key *common.Hash, out *uint256.Int) { + // If the fake storage is set, only lookup the state here(in the debugging mode) + if so.fakeStorage != nil { + *out = so.fakeStorage[*key] + return + } value, dirty := so.dirtyStorage[*key] if dirty { *out = value @@ -167,6 +172,11 @@ func (so *stateObject) GetState(key *common.Hash, out *uint256.Int) { // GetCommittedState retrieves a value from the committed account storage trie. func (so *stateObject) GetCommittedState(key *common.Hash, out *uint256.Int) { + // If the fake storage is set, only lookup the state here(in the debugging mode) + if so.fakeStorage != nil { + *out = so.fakeStorage[*key] + return + } // If we have the original value cached, return that { value, cached := so.originStorage[*key] @@ -197,6 +207,11 @@ func (so *stateObject) GetCommittedState(key *common.Hash, out *uint256.Int) { // SetState updates a value in account storage. func (so *stateObject) SetState(key *common.Hash, value uint256.Int) { + // If the fake storage is set, put the temporary state update here. + if so.fakeStorage != nil { + so.fakeStorage[*key] = value + return + } // If the new value is the same as old, don't set var prev uint256.Int so.GetState(key, &prev) From acad6bdd253afc5c5be232a43556131d13d2f62c Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Wed, 23 Feb 2022 14:01:50 +0000 Subject: [PATCH 178/261] Optimise eth_getStorageAt for current state (#3580) (#3587) * Optimise eth_getStorageAt for current state * Fix Co-authored-by: Alex Sharp Co-authored-by: Alex Sharp --- cmd/rpcdaemon/commands/eth_accounts.go | 5 ++++- turbo/rpchelper/helper.go | 17 +++++++++++++++++ turbo/transactions/call.go | 13 ++++--------- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/cmd/rpcdaemon/commands/eth_accounts.go b/cmd/rpcdaemon/commands/eth_accounts.go index 69533415b94..22969e2636b 100644 --- a/cmd/rpcdaemon/commands/eth_accounts.go +++ b/cmd/rpcdaemon/commands/eth_accounts.go @@ -110,7 +110,10 @@ func (api *APIImpl) GetStorageAt(ctx context.Context, address common.Address, in if err != nil { return hexutil.Encode(common.LeftPadBytes(empty, 32)), err } - reader := adapter.NewStateReader(tx, blockNumber) + reader, err := rpchelper.CreateStateReader(ctx, tx, blockNrOrHash, blockNumber, api.stateCache) + if err != nil { + return hexutil.Encode(common.LeftPadBytes(empty, 32)), err + } acc, err := reader.ReadAccountData(address) if acc == nil || err != nil { return hexutil.Encode(common.LeftPadBytes(empty, 32)), err diff --git a/turbo/rpchelper/helper.go b/turbo/rpchelper/helper.go index a2b7cbeeca4..2ff70fafce3 100644 --- a/turbo/rpchelper/helper.go +++ b/turbo/rpchelper/helper.go @@ -1,12 +1,15 @@ package rpchelper import ( + "context" "fmt" "github.com/ledgerwatch/erigon-lib/kv" + "github.com/ledgerwatch/erigon-lib/kv/kvcache" "github.com/ledgerwatch/erigon/cmd/rpcdaemon/filters" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/core/rawdb" + "github.com/ledgerwatch/erigon/core/state" "github.com/ledgerwatch/erigon/core/types/accounts" "github.com/ledgerwatch/erigon/eth/stagedsync/stages" "github.com/ledgerwatch/erigon/rpc" @@ -82,3 +85,17 @@ func GetAccount(tx kv.Tx, blockNumber uint64, address common.Address) (*accounts reader := adapter.NewStateReader(tx, blockNumber) return reader.ReadAccountData(address) } + +func CreateStateReader(ctx context.Context, tx kv.Tx, blockNrOrHash rpc.BlockNumberOrHash, blockNumber uint64, stateCache kvcache.Cache) (state.StateReader, error) { + var stateReader state.StateReader + if num, ok := blockNrOrHash.Number(); ok && num == rpc.LatestBlockNumber { + cacheView, err := stateCache.View(ctx, tx) + if err != nil { + return nil, err + } + stateReader = state.NewCachedReader2(cacheView, tx) + } else { + stateReader = state.NewPlainState(tx, blockNumber) + } + return stateReader, nil +} diff --git a/turbo/transactions/call.go b/turbo/transactions/call.go index 41364db832d..798bdc4c92e 100644 --- a/turbo/transactions/call.go +++ b/turbo/transactions/call.go @@ -18,6 +18,7 @@ import ( "github.com/ledgerwatch/erigon/internal/ethapi" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/rpc" + "github.com/ledgerwatch/erigon/turbo/rpchelper" "github.com/ledgerwatch/log/v3" ) @@ -32,15 +33,9 @@ func DoCall(ctx context.Context, args ethapi.CallArgs, tx kv.Tx, blockNrOrHash r } */ blockNumber := block.NumberU64() - var stateReader state.StateReader - if num, ok := blockNrOrHash.Number(); ok && num == rpc.LatestBlockNumber { - cacheView, err := stateCache.View(ctx, tx) - if err != nil { - return nil, err - } - stateReader = state.NewCachedReader2(cacheView, tx) - } else { - stateReader = state.NewPlainState(tx, blockNumber) + stateReader, err := rpchelper.CreateStateReader(ctx, tx, blockNrOrHash, blockNumber, stateCache) + if err != nil { + return nil, err } state := state.New(stateReader) From 434d92144ffcee31ca4d6dce3174e0bf66343d53 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Thu, 24 Feb 2022 03:23:25 +0000 Subject: [PATCH 179/261] Auto detect latest block for optimal use of plain state and state cache (#3598) (#3601) * Auto detect latest block for optimal use of plain state and state cache * Fix lint * Fix test Co-authored-by: Alex Sharp Co-authored-by: Alex Sharp --- cmd/rpcdaemon/commands/eth_accounts.go | 19 ++++-------- cmd/rpcdaemon/commands/eth_api_test.go | 6 +++- cmd/rpcdaemon/commands/eth_block.go | 4 +-- cmd/rpcdaemon/commands/eth_call.go | 12 ++++---- cmd/rpcdaemon/commands/trace_adhoc.go | 13 ++++---- cmd/rpcdaemon/commands/tracing.go | 4 +-- turbo/rpchelper/helper.go | 42 ++++++++++++++------------ turbo/transactions/call.go | 16 ++++++++-- 8 files changed, 64 insertions(+), 52 deletions(-) diff --git a/cmd/rpcdaemon/commands/eth_accounts.go b/cmd/rpcdaemon/commands/eth_accounts.go index 22969e2636b..c55869d3999 100644 --- a/cmd/rpcdaemon/commands/eth_accounts.go +++ b/cmd/rpcdaemon/commands/eth_accounts.go @@ -6,7 +6,6 @@ import ( "math/big" "github.com/ledgerwatch/erigon-lib/gointerfaces" - "github.com/ledgerwatch/erigon/turbo/adapter" "github.com/ledgerwatch/erigon/turbo/rpchelper" "google.golang.org/grpc" @@ -23,14 +22,14 @@ func (api *APIImpl) GetBalance(ctx context.Context, address common.Address, bloc return nil, fmt.Errorf("getBalance cannot open tx: %w", err1) } defer tx.Rollback() - blockNumber, _, err := rpchelper.GetBlockNumber(blockNrOrHash, tx, api.filters) + reader, err := rpchelper.CreateStateReader(ctx, tx, blockNrOrHash, api.filters, api.stateCache) if err != nil { return nil, err } - acc, err := rpchelper.GetAccount(tx, blockNumber, address) + acc, err := reader.ReadAccountData(address) if err != nil { - return nil, fmt.Errorf("cant get a balance for account %q for block %v", address.String(), blockNumber) + return nil, fmt.Errorf("cant get a balance for account %x: %w", address.String(), err) } if acc == nil { // Special case - non-existent account is assumed to have zero balance @@ -59,12 +58,11 @@ func (api *APIImpl) GetTransactionCount(ctx context.Context, address common.Addr return nil, fmt.Errorf("getTransactionCount cannot open tx: %w", err1) } defer tx.Rollback() - blockNumber, _, err := rpchelper.GetBlockNumber(blockNrOrHash, tx, api.filters) + reader, err := rpchelper.CreateStateReader(ctx, tx, blockNrOrHash, api.filters, api.stateCache) if err != nil { return nil, err } nonce := hexutil.Uint64(0) - reader := adapter.NewStateReader(tx, blockNumber) acc, err := reader.ReadAccountData(address) if acc == nil || err != nil { return &nonce, err @@ -79,12 +77,11 @@ func (api *APIImpl) GetCode(ctx context.Context, address common.Address, blockNr return nil, fmt.Errorf("getCode cannot open tx: %w", err1) } defer tx.Rollback() - blockNumber, _, err := rpchelper.GetBlockNumber(blockNrOrHash, tx, api.filters) + reader, err := rpchelper.CreateStateReader(ctx, tx, blockNrOrHash, api.filters, api.stateCache) if err != nil { return nil, err } - reader := adapter.NewStateReader(tx, blockNumber) acc, err := reader.ReadAccountData(address) if acc == nil || err != nil { return hexutil.Bytes(""), nil @@ -106,11 +103,7 @@ func (api *APIImpl) GetStorageAt(ctx context.Context, address common.Address, in } defer tx.Rollback() - blockNumber, _, err := rpchelper.GetBlockNumber(blockNrOrHash, tx, api.filters) - if err != nil { - return hexutil.Encode(common.LeftPadBytes(empty, 32)), err - } - reader, err := rpchelper.CreateStateReader(ctx, tx, blockNrOrHash, blockNumber, api.stateCache) + reader, err := rpchelper.CreateStateReader(ctx, tx, blockNrOrHash, api.filters, api.stateCache) if err != nil { return hexutil.Encode(common.LeftPadBytes(empty, 32)), err } diff --git a/cmd/rpcdaemon/commands/eth_api_test.go b/cmd/rpcdaemon/commands/eth_api_test.go index 7b31dc7f8a9..6e965acbf1e 100644 --- a/cmd/rpcdaemon/commands/eth_api_test.go +++ b/cmd/rpcdaemon/commands/eth_api_test.go @@ -142,7 +142,11 @@ func TestGetStorageAt_ByBlockHash_WithRequireCanonicalDefault_NonCanonicalBlock( result, err := api.GetStorageAt(context.Background(), addr, "0x0", rpc.BlockNumberOrHashWithHash(orphanedBlock.Hash(), false)) if err != nil { - t.Errorf("calling GetStorageAt: %v", err) + if fmt.Sprintf("%v", err) != fmt.Sprintf("hash %s is not currently canonical", orphanedBlock.Hash().String()[2:]) { + t.Errorf("wrong error: %v", err) + } + } else { + t.Error("error expected") } assert.Equal(common.HexToHash("0x0").String(), result) diff --git a/cmd/rpcdaemon/commands/eth_block.go b/cmd/rpcdaemon/commands/eth_block.go index b48398ea56f..16a52c0e189 100644 --- a/cmd/rpcdaemon/commands/eth_block.go +++ b/cmd/rpcdaemon/commands/eth_block.go @@ -53,13 +53,13 @@ func (api *APIImpl) CallBundle(ctx context.Context, txHashes []common.Hash, stat } defer func(start time.Time) { log.Trace("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now()) - stateBlockNumber, hash, err := rpchelper.GetBlockNumber(stateBlockNumberOrHash, tx, api.filters) + stateBlockNumber, hash, latest, err := rpchelper.GetBlockNumber(stateBlockNumberOrHash, tx, api.filters) if err != nil { return nil, err } var stateReader state.StateReader - if num, ok := stateBlockNumberOrHash.Number(); ok && num == rpc.LatestBlockNumber { + if latest { cacheView, err := api.stateCache.View(ctx, tx) if err != nil { return nil, err diff --git a/cmd/rpcdaemon/commands/eth_call.go b/cmd/rpcdaemon/commands/eth_call.go index 99ccbb97019..843e4e361c3 100644 --- a/cmd/rpcdaemon/commands/eth_call.go +++ b/cmd/rpcdaemon/commands/eth_call.go @@ -51,7 +51,7 @@ func (api *APIImpl) Call(ctx context.Context, args ethapi.CallArgs, blockNrOrHas contractHasTEVM = ethdb.GetHasTEVM(tx) } - blockNumber, hash, err := rpchelper.GetCanonicalBlockNumber(blockNrOrHash, tx, api.filters) // DoCall cannot be executed on non-canonical blocks + blockNumber, hash, _, err := rpchelper.GetCanonicalBlockNumber(blockNrOrHash, tx, api.filters) // DoCall cannot be executed on non-canonical blocks if err != nil { return nil, err } @@ -63,7 +63,7 @@ func (api *APIImpl) Call(ctx context.Context, args ethapi.CallArgs, blockNrOrHas return nil, nil } - result, err := transactions.DoCall(ctx, args, tx, blockNrOrHash, block, overrides, api.GasCap, chainConfig, api.stateCache, contractHasTEVM) + result, err := transactions.DoCall(ctx, args, tx, blockNrOrHash, block, overrides, api.GasCap, chainConfig, api.filters, api.stateCache, contractHasTEVM) if err != nil { return nil, err } @@ -215,7 +215,7 @@ func (api *APIImpl) EstimateGas(ctx context.Context, args ethapi.CallArgs, block args.Gas = (*hexutil.Uint64)(&gas) numOrHash := rpc.BlockNumberOrHash{BlockNumber: &lastBlockNum} - blockNumber, hash, err := rpchelper.GetCanonicalBlockNumber(numOrHash, dbtx, api.filters) // DoCall cannot be executed on non-canonical blocks + blockNumber, hash, _, err := rpchelper.GetCanonicalBlockNumber(numOrHash, dbtx, api.filters) // DoCall cannot be executed on non-canonical blocks if err != nil { return false, nil, err } @@ -228,7 +228,7 @@ func (api *APIImpl) EstimateGas(ctx context.Context, args ethapi.CallArgs, block } result, err := transactions.DoCall(ctx, args, dbtx, numOrHash, block, nil, - api.GasCap, chainConfig, api.stateCache, contractHasTEVM) + api.GasCap, chainConfig, api.filters, api.stateCache, contractHasTEVM) if err != nil { if errors.Is(err, core.ErrIntrinsicGas) { // Special case, raise gas limit @@ -315,7 +315,7 @@ func (api *APIImpl) CreateAccessList(ctx context.Context, args ethapi.CallArgs, if api.TevmEnabled { contractHasTEVM = ethdb.GetHasTEVM(tx) } - blockNumber, hash, err := rpchelper.GetCanonicalBlockNumber(bNrOrHash, tx, api.filters) // DoCall cannot be executed on non-canonical blocks + blockNumber, hash, latest, err := rpchelper.GetCanonicalBlockNumber(bNrOrHash, tx, api.filters) // DoCall cannot be executed on non-canonical blocks if err != nil { return nil, err } @@ -327,7 +327,7 @@ func (api *APIImpl) CreateAccessList(ctx context.Context, args ethapi.CallArgs, return nil, nil } var stateReader state.StateReader - if num, ok := bNrOrHash.Number(); ok && num == rpc.LatestBlockNumber { + if latest { cacheView, err := api.stateCache.View(ctx, tx) if err != nil { return nil, err diff --git a/cmd/rpcdaemon/commands/trace_adhoc.go b/cmd/rpcdaemon/commands/trace_adhoc.go index 63843b62551..b47f0d540ed 100644 --- a/cmd/rpcdaemon/commands/trace_adhoc.go +++ b/cmd/rpcdaemon/commands/trace_adhoc.go @@ -781,7 +781,7 @@ func (api *TraceAPIImpl) ReplayBlockTransactions(ctx context.Context, blockNrOrH return nil, err } - blockNumber, _, err := rpchelper.GetBlockNumber(blockNrOrHash, tx, api.filters) + blockNumber, _, _, err := rpchelper.GetBlockNumber(blockNrOrHash, tx, api.filters) if err != nil { return nil, err } @@ -858,12 +858,13 @@ func (api *TraceAPIImpl) Call(ctx context.Context, args TraceCallParam, traceTyp var num = rpc.LatestBlockNumber blockNrOrHash = &rpc.BlockNumberOrHash{BlockNumber: &num} } - blockNumber, hash, err := rpchelper.GetBlockNumber(*blockNrOrHash, tx, api.filters) + + blockNumber, hash, latest, err := rpchelper.GetBlockNumber(*blockNrOrHash, tx, api.filters) if err != nil { return nil, err } var stateReader state.StateReader - if num, ok := blockNrOrHash.Number(); ok && num == rpc.LatestBlockNumber { + if latest { cacheView, err := api.stateCache.View(ctx, tx) if err != nil { return nil, err @@ -1028,7 +1029,7 @@ func (api *TraceAPIImpl) CallMany(ctx context.Context, calls json.RawMessage, pa var num = rpc.LatestBlockNumber parentNrOrHash = &rpc.BlockNumberOrHash{BlockNumber: &num} } - blockNumber, hash, err := rpchelper.GetBlockNumber(*parentNrOrHash, dbtx, api.filters) + blockNumber, hash, _, err := rpchelper.GetBlockNumber(*parentNrOrHash, dbtx, api.filters) if err != nil { return nil, err } @@ -1064,12 +1065,12 @@ func (api *TraceAPIImpl) doCallMany(ctx context.Context, dbtx kv.Tx, msgs []type var num = rpc.LatestBlockNumber parentNrOrHash = &rpc.BlockNumberOrHash{BlockNumber: &num} } - blockNumber, hash, err := rpchelper.GetBlockNumber(*parentNrOrHash, dbtx, api.filters) + blockNumber, hash, latest, err := rpchelper.GetBlockNumber(*parentNrOrHash, dbtx, api.filters) if err != nil { return nil, err } var stateReader state.StateReader - if num, ok := parentNrOrHash.Number(); ok && num == rpc.LatestBlockNumber { + if latest { cacheView, err := api.stateCache.View(ctx, dbtx) if err != nil { return nil, err diff --git a/cmd/rpcdaemon/commands/tracing.go b/cmd/rpcdaemon/commands/tracing.go index c2b5fdac65f..638a5aa91a2 100644 --- a/cmd/rpcdaemon/commands/tracing.go +++ b/cmd/rpcdaemon/commands/tracing.go @@ -81,13 +81,13 @@ func (api *PrivateDebugAPIImpl) TraceCall(ctx context.Context, args ethapi.CallA return err } - blockNumber, hash, err := rpchelper.GetBlockNumber(blockNrOrHash, dbtx, api.filters) + blockNumber, hash, latest, err := rpchelper.GetBlockNumber(blockNrOrHash, dbtx, api.filters) if err != nil { stream.WriteNil() return err } var stateReader state.StateReader - if num, ok := blockNrOrHash.Number(); ok && num == rpc.LatestBlockNumber { + if latest { cacheView, err := api.stateCache.View(ctx, dbtx) if err != nil { return err diff --git a/turbo/rpchelper/helper.go b/turbo/rpchelper/helper.go index 2ff70fafce3..94acc2e7be8 100644 --- a/turbo/rpchelper/helper.go +++ b/turbo/rpchelper/helper.go @@ -25,25 +25,25 @@ func (e nonCanonocalHashError) Error() string { return fmt.Sprintf("hash %x is not currently canonical", e.hash) } -func GetBlockNumber(blockNrOrHash rpc.BlockNumberOrHash, tx kv.Tx, filters *filters.Filters) (uint64, common.Hash, error) { +func GetBlockNumber(blockNrOrHash rpc.BlockNumberOrHash, tx kv.Tx, filters *filters.Filters) (uint64, common.Hash, bool, error) { return _GetBlockNumber(blockNrOrHash.RequireCanonical, blockNrOrHash, tx, filters) } -func GetCanonicalBlockNumber(blockNrOrHash rpc.BlockNumberOrHash, tx kv.Tx, filters *filters.Filters) (uint64, common.Hash, error) { +func GetCanonicalBlockNumber(blockNrOrHash rpc.BlockNumberOrHash, tx kv.Tx, filters *filters.Filters) (uint64, common.Hash, bool, error) { return _GetBlockNumber(true, blockNrOrHash, tx, filters) } -func _GetBlockNumber(requireCanonical bool, blockNrOrHash rpc.BlockNumberOrHash, tx kv.Tx, filters *filters.Filters) (uint64, common.Hash, error) { - var blockNumber uint64 - var err error - hash, ok := blockNrOrHash.Hash() +func _GetBlockNumber(requireCanonical bool, blockNrOrHash rpc.BlockNumberOrHash, tx kv.Tx, filters *filters.Filters) (blockNumber uint64, hash common.Hash, latest bool, err error) { + var latestBlockNumber uint64 + if latestBlockNumber, err = stages.GetStageProgress(tx, stages.Execution); err != nil { + return 0, common.Hash{}, false, fmt.Errorf("getting latest block number: %w", err) + } + var ok bool + hash, ok = blockNrOrHash.Hash() if !ok { number := *blockNrOrHash.BlockNumber if number == rpc.LatestBlockNumber { - blockNumber, err = stages.GetStageProgress(tx, stages.Execution) - if err != nil { - return 0, common.Hash{}, fmt.Errorf("getting latest block number: %w", err) - } + blockNumber = latestBlockNumber } else if number == rpc.EarliestBlockNumber { blockNumber = 0 } else if number == rpc.PendingBlockNumber { @@ -51,34 +51,34 @@ func _GetBlockNumber(requireCanonical bool, blockNrOrHash rpc.BlockNumberOrHash, if pendingBlock == nil { blockNumber, err = stages.GetStageProgress(tx, stages.Execution) if err != nil { - return 0, common.Hash{}, fmt.Errorf("getting latest block number: %w", err) + return 0, common.Hash{}, false, fmt.Errorf("getting latest block number: %w", err) } } else { - return pendingBlock.NumberU64(), pendingBlock.Hash(), nil + return pendingBlock.NumberU64(), pendingBlock.Hash(), false, nil } } else { blockNumber = uint64(number.Int64()) } hash, err = rawdb.ReadCanonicalHash(tx, blockNumber) if err != nil { - return 0, common.Hash{}, err + return 0, common.Hash{}, false, err } } else { number := rawdb.ReadHeaderNumber(tx, hash) if number == nil { - return 0, common.Hash{}, fmt.Errorf("block %x not found", hash) + return 0, common.Hash{}, false, fmt.Errorf("block %x not found", hash) } blockNumber = *number ch, err := rawdb.ReadCanonicalHash(tx, blockNumber) if err != nil { - return 0, common.Hash{}, err + return 0, common.Hash{}, false, err } if requireCanonical && ch != hash { - return 0, common.Hash{}, nonCanonocalHashError{hash} + return 0, common.Hash{}, false, nonCanonocalHashError{hash} } } - return blockNumber, hash, nil + return blockNumber, hash, blockNumber == latestBlockNumber, nil } func GetAccount(tx kv.Tx, blockNumber uint64, address common.Address) (*accounts.Account, error) { @@ -86,9 +86,13 @@ func GetAccount(tx kv.Tx, blockNumber uint64, address common.Address) (*accounts return reader.ReadAccountData(address) } -func CreateStateReader(ctx context.Context, tx kv.Tx, blockNrOrHash rpc.BlockNumberOrHash, blockNumber uint64, stateCache kvcache.Cache) (state.StateReader, error) { +func CreateStateReader(ctx context.Context, tx kv.Tx, blockNrOrHash rpc.BlockNumberOrHash, filters *filters.Filters, stateCache kvcache.Cache) (state.StateReader, error) { + blockNumber, _, latest, err := _GetBlockNumber(true, blockNrOrHash, tx, filters) + if err != nil { + return nil, err + } var stateReader state.StateReader - if num, ok := blockNrOrHash.Number(); ok && num == rpc.LatestBlockNumber { + if latest { cacheView, err := stateCache.View(ctx, tx) if err != nil { return nil, err diff --git a/turbo/transactions/call.go b/turbo/transactions/call.go index 798bdc4c92e..643802667c5 100644 --- a/turbo/transactions/call.go +++ b/turbo/transactions/call.go @@ -9,6 +9,7 @@ import ( "github.com/holiman/uint256" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv/kvcache" + "github.com/ledgerwatch/erigon/cmd/rpcdaemon/filters" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/core/rawdb" @@ -24,7 +25,17 @@ import ( const callTimeout = 5 * time.Minute -func DoCall(ctx context.Context, args ethapi.CallArgs, tx kv.Tx, blockNrOrHash rpc.BlockNumberOrHash, block *types.Block, overrides *map[common.Address]ethapi.Account, gasCap uint64, chainConfig *params.ChainConfig, stateCache kvcache.Cache, contractHasTEVM func(hash common.Hash) (bool, error)) (*core.ExecutionResult, error) { +func DoCall( + ctx context.Context, + args ethapi.CallArgs, + tx kv.Tx, blockNrOrHash rpc.BlockNumberOrHash, + block *types.Block, overrides *map[common.Address]ethapi.Account, + gasCap uint64, + chainConfig *params.ChainConfig, + filters *filters.Filters, + stateCache kvcache.Cache, + contractHasTEVM func(hash common.Hash) (bool, error), +) (*core.ExecutionResult, error) { // todo: Pending state is only known by the miner /* if blockNrOrHash.BlockNumber != nil && *blockNrOrHash.BlockNumber == rpc.PendingBlockNumber { @@ -32,8 +43,7 @@ func DoCall(ctx context.Context, args ethapi.CallArgs, tx kv.Tx, blockNrOrHash r return state, block.Header(), nil } */ - blockNumber := block.NumberU64() - stateReader, err := rpchelper.CreateStateReader(ctx, tx, blockNrOrHash, blockNumber, stateCache) + stateReader, err := rpchelper.CreateStateReader(ctx, tx, blockNrOrHash, filters, stateCache) if err != nil { return nil, err } From 25e6a4514a792fa3f2b894ea2d631c88e7db25fa Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Thu, 24 Feb 2022 03:23:35 +0000 Subject: [PATCH 180/261] rpcdaemon: added debug_traceBlockByNumber and debug_traceBlockByHash (#3548) (#3599) Co-authored-by: bernard-wagner --- cmd/rpcdaemon/README.md | 2 + cmd/rpcdaemon/commands/debug_api.go | 2 + cmd/rpcdaemon/commands/debug_api_test.go | 82 +++++++++++++++++++ cmd/rpcdaemon/commands/tracing.go | 77 ++++++++++++++++- cmd/rpctest/main.go | 10 +++ cmd/rpctest/rpctest/bench_tracetransaction.go | 57 +++++++++++++ cmd/rpctest/rpctest/request_generator.go | 5 ++ 7 files changed, 234 insertions(+), 1 deletion(-) diff --git a/cmd/rpcdaemon/README.md b/cmd/rpcdaemon/README.md index cc27e6fcec5..8ca9d6a94e2 100644 --- a/cmd/rpcdaemon/README.md +++ b/cmd/rpcdaemon/README.md @@ -231,6 +231,8 @@ The following table shows the current implementation status of Erigon's RPC daem | debug_getModifiedAccountsByNumber | Yes | | | debug_getModifiedAccountsByHash | Yes | | | debug_storageRangeAt | Yes | | +| debug_traceBlockByHash | Yes | Streaming (can handle huge results) | +| debug_traceBlockByNumber | Yes | Streaming (can handle huge results) | | debug_traceTransaction | Yes | Streaming (can handle huge results) | | debug_traceCall | Yes | Streaming (can handle huge results) | | | | | diff --git a/cmd/rpcdaemon/commands/debug_api.go b/cmd/rpcdaemon/commands/debug_api.go index eb3d4814dcf..c80fe48b4ef 100644 --- a/cmd/rpcdaemon/commands/debug_api.go +++ b/cmd/rpcdaemon/commands/debug_api.go @@ -26,6 +26,8 @@ import ( type PrivateDebugAPI interface { StorageRangeAt(ctx context.Context, blockHash common.Hash, txIndex uint64, contractAddress common.Address, keyStart hexutil.Bytes, maxResult int) (StorageRangeResult, error) TraceTransaction(ctx context.Context, hash common.Hash, config *tracers.TraceConfig, stream *jsoniter.Stream) error + TraceBlockByHash(ctx context.Context, hash common.Hash, config *tracers.TraceConfig, stream *jsoniter.Stream) error + TraceBlockByNumber(ctx context.Context, number rpc.BlockNumber, config *tracers.TraceConfig, stream *jsoniter.Stream) error AccountRange(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash, start []byte, maxResults int, nocode, nostorage bool) (state.IteratorDump, error) GetModifiedAccountsByNumber(ctx context.Context, startNum rpc.BlockNumber, endNum *rpc.BlockNumber) ([]common.Address, error) GetModifiedAccountsByHash(_ context.Context, startHash common.Hash, endHash *common.Hash) ([]common.Address, error) diff --git a/cmd/rpcdaemon/commands/debug_api_test.go b/cmd/rpcdaemon/commands/debug_api_test.go index a0eff1db458..62c7c1fdd7a 100644 --- a/cmd/rpcdaemon/commands/debug_api_test.go +++ b/cmd/rpcdaemon/commands/debug_api_test.go @@ -12,6 +12,7 @@ import ( "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/eth/tracers" "github.com/ledgerwatch/erigon/internal/ethapi" + "github.com/ledgerwatch/erigon/rpc" ) var debugTraceTransactionTests = []struct { @@ -36,6 +37,87 @@ var debugTraceTransactionNoRefundTests = []struct { {"b6449d8e167a8826d050afe4c9f07095236ff769a985f02649b1023c2ded2059", 62899, false, ""}, } +func TestTraceBlockByNumber(t *testing.T) { + db := rpcdaemontest.CreateTestKV(t) + stateCache := kvcache.New(kvcache.DefaultCoherentConfig) + baseApi := NewBaseApi(nil, stateCache, false) + ethApi := NewEthAPI(baseApi, db, nil, nil, nil, 5000000) + api := NewPrivateDebugAPI(baseApi, db, 0) + for _, tt := range debugTraceTransactionTests { + var buf bytes.Buffer + stream := jsoniter.NewStream(jsoniter.ConfigDefault, &buf, 4096) + tx, err := ethApi.GetTransactionByHash(context.Background(), common.HexToHash(tt.txHash)) + if err != nil { + t.Errorf("traceBlock %s: %v", tt.txHash, err) + } + txcount, err := ethApi.GetBlockTransactionCountByHash(context.Background(), *tx.BlockHash) + if err != nil { + t.Errorf("traceBlock %s: %v", tt.txHash, err) + } + err = api.TraceBlockByNumber(context.Background(), rpc.BlockNumber(tx.BlockNumber.ToInt().Uint64()), &tracers.TraceConfig{}, stream) + if err != nil { + t.Errorf("traceBlock %s: %v", tt.txHash, err) + } + if err = stream.Flush(); err != nil { + t.Fatalf("error flusing: %v", err) + } + var er []ethapi.ExecutionResult + if err = json.Unmarshal(buf.Bytes(), &er); err != nil { + t.Fatalf("parsing result: %v", err) + } + if len(er) != int(*txcount) { + t.Fatalf("incorrect length: %v", err) + } + } + var buf bytes.Buffer + stream := jsoniter.NewStream(jsoniter.ConfigDefault, &buf, 4096) + err := api.TraceBlockByNumber(context.Background(), rpc.BlockNumber(rpc.LatestBlockNumber), &tracers.TraceConfig{}, stream) + if err != nil { + t.Errorf("traceBlock %v: %v", rpc.LatestBlockNumber, err) + } + if err = stream.Flush(); err != nil { + t.Fatalf("error flusing: %v", err) + } + var er []ethapi.ExecutionResult + if err = json.Unmarshal(buf.Bytes(), &er); err != nil { + t.Fatalf("parsing result: %v", err) + } +} + +func TestTraceBlockByHash(t *testing.T) { + db := rpcdaemontest.CreateTestKV(t) + stateCache := kvcache.New(kvcache.DefaultCoherentConfig) + baseApi := NewBaseApi(nil, stateCache, false) + ethApi := NewEthAPI(baseApi, db, nil, nil, nil, 5000000) + api := NewPrivateDebugAPI(baseApi, db, 0) + for _, tt := range debugTraceTransactionTests { + var buf bytes.Buffer + stream := jsoniter.NewStream(jsoniter.ConfigDefault, &buf, 4096) + tx, err := ethApi.GetTransactionByHash(context.Background(), common.HexToHash(tt.txHash)) + if err != nil { + t.Errorf("traceBlock %s: %v", tt.txHash, err) + } + txcount, err := ethApi.GetBlockTransactionCountByHash(context.Background(), *tx.BlockHash) + if err != nil { + t.Errorf("traceBlock %s: %v", tt.txHash, err) + } + err = api.TraceBlockByHash(context.Background(), *tx.BlockHash, &tracers.TraceConfig{}, stream) + if err != nil { + t.Errorf("traceBlock %s: %v", tt.txHash, err) + } + if err = stream.Flush(); err != nil { + t.Fatalf("error flusing: %v", err) + } + var er []ethapi.ExecutionResult + if err = json.Unmarshal(buf.Bytes(), &er); err != nil { + t.Fatalf("parsing result: %v", err) + } + if len(er) != int(*txcount) { + t.Fatalf("incorrect length: %v", err) + } + } +} + func TestTraceTransaction(t *testing.T) { db := rpcdaemontest.CreateTestKV(t) stateCache := kvcache.New(kvcache.DefaultCoherentConfig) diff --git a/cmd/rpcdaemon/commands/tracing.go b/cmd/rpcdaemon/commands/tracing.go index 638a5aa91a2..b26b8e9f41c 100644 --- a/cmd/rpcdaemon/commands/tracing.go +++ b/cmd/rpcdaemon/commands/tracing.go @@ -19,6 +19,82 @@ import ( "github.com/ledgerwatch/erigon/turbo/transactions" ) +// TraceBlockByNumber implements debug_traceBlockByNumber. Returns Geth style block traces. +func (api *PrivateDebugAPIImpl) TraceBlockByNumber(ctx context.Context, blockNum rpc.BlockNumber, config *tracers.TraceConfig, stream *jsoniter.Stream) error { + return api.traceBlock(ctx, rpc.BlockNumberOrHashWithNumber(blockNum), config, stream) +} + +// TraceBlockByHash implements debug_traceBlockByHash. Returns Geth style block traces. +func (api *PrivateDebugAPIImpl) TraceBlockByHash(ctx context.Context, hash common.Hash, config *tracers.TraceConfig, stream *jsoniter.Stream) error { + return api.traceBlock(ctx, rpc.BlockNumberOrHashWithHash(hash, true), config, stream) +} + +func (api *PrivateDebugAPIImpl) traceBlock(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash, config *tracers.TraceConfig, stream *jsoniter.Stream) error { + tx, err := api.db.BeginRo(ctx) + if err != nil { + stream.WriteNil() + return err + } + defer tx.Rollback() + var block *types.Block + if number, ok := blockNrOrHash.Number(); ok { + block, err = api.blockByRPCNumber(number, tx) + } else if hash, ok := blockNrOrHash.Hash(); ok { + block, err = api.blockByHashWithSenders(tx, hash) + } else { + return fmt.Errorf("invalid arguments; neither block nor hash specified") + } + + if err != nil { + stream.WriteNil() + return err + } + + chainConfig, err := api.chainConfig(tx) + if err != nil { + stream.WriteNil() + return err + } + + contractHasTEVM := func(contractHash common.Hash) (bool, error) { return false, nil } + if api.TevmEnabled { + contractHasTEVM = ethdb.GetHasTEVM(tx) + } + + getHeader := func(hash common.Hash, number uint64) *types.Header { + return rawdb.ReadHeader(tx, hash, number) + } + + _, blockCtx, txCtx, ibs, reader, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, contractHasTEVM, ethash.NewFaker(), tx, block.Hash(), 0) + if err != nil { + stream.WriteNil() + return err + } + + signer := types.MakeSigner(chainConfig, block.NumberU64()) + stream.WriteArrayStart() + for idx, tx := range block.Transactions() { + select { + default: + case <-ctx.Done(): + stream.WriteNil() + return ctx.Err() + } + ibs.Prepare(tx.Hash(), block.Hash(), idx) + msg, _ := tx.AsMessage(*signer, block.BaseFee()) + + transactions.TraceTx(ctx, msg, blockCtx, txCtx, ibs, config, chainConfig, stream) + _ = ibs.FinalizeTx(chainConfig.Rules(blockCtx.BlockNumber), reader) + if idx != len(block.Transactions())-1 { + stream.WriteMore() + } + stream.Flush() + } + stream.WriteArrayEnd() + stream.Flush() + return nil +} + // TraceTransaction implements debug_traceTransaction. Returns Geth style transaction traces. func (api *PrivateDebugAPIImpl) TraceTransaction(ctx context.Context, hash common.Hash, config *tracers.TraceConfig, stream *jsoniter.Stream) error { tx, err := api.db.BeginRo(ctx) @@ -27,7 +103,6 @@ func (api *PrivateDebugAPIImpl) TraceTransaction(ctx context.Context, hash commo return err } defer tx.Rollback() - // Retrieve the transaction and assemble its EVM context txn, blockHash, _, txIndex, err := rawdb.ReadTransaction(tx, hash) if err != nil { diff --git a/cmd/rpctest/main.go b/cmd/rpctest/main.go index cb8a7d099c5..53a19fe0877 100644 --- a/cmd/rpctest/main.go +++ b/cmd/rpctest/main.go @@ -152,6 +152,16 @@ func main() { } with(bench9Cmd, withErigonUrl, withGethUrl, withNeedCompare) + var benchTraceBlockByHashCmd = &cobra.Command{ + Use: "benchTraceBlockByHash", + Short: "", + Long: ``, + Run: func(cmd *cobra.Command, args []string) { + rpctest.BenchTraceBlockByHash(erigonURL, gethURL, needCompare, blockFrom, blockTo, recordFile, errorFile) + }, + } + with(benchTraceBlockByHashCmd, withGethUrl, withErigonUrl, withNeedCompare, withBlockNum, withRecord, withErrorFile) + var benchTraceTransactionCmd = &cobra.Command{ Use: "benchTraceTransaction", Short: "", diff --git a/cmd/rpctest/rpctest/bench_tracetransaction.go b/cmd/rpctest/rpctest/bench_tracetransaction.go index 7158c2b07ab..403e1b99b17 100644 --- a/cmd/rpctest/rpctest/bench_tracetransaction.go +++ b/cmd/rpctest/rpctest/bench_tracetransaction.go @@ -8,6 +8,63 @@ import ( "time" ) +func BenchTraceBlockByHash(erigonUrl, gethUrl string, needCompare bool, blockFrom uint64, blockTo uint64, recordFile string, errorFile string) { + setRoutes(erigonUrl, gethUrl) + var client = &http.Client{ + Timeout: time.Second * 600, + } + + var rec *bufio.Writer + if recordFile != "" { + f, err := os.Create(recordFile) + if err != nil { + fmt.Printf("Cannot create file %s for recording: %v\n", recordFile, err) + return + } + defer f.Close() + rec = bufio.NewWriter(f) + defer rec.Flush() + } + var errs *bufio.Writer + if errorFile != "" { + ferr, err := os.Create(errorFile) + if err != nil { + fmt.Printf("Cannot create file %s for error output: %v\n", errorFile, err) + return + } + defer ferr.Close() + errs = bufio.NewWriter(ferr) + defer errs.Flush() + } + + var res CallResult + reqGen := &RequestGenerator{ + client: client, + } + + reqGen.reqID++ + + for bn := blockFrom; bn < blockTo; bn++ { + var b EthBlockByNumber + res = reqGen.Erigon("eth_getBlockByNumber", reqGen.getBlockByNumber(bn), &b) + if res.Err != nil { + fmt.Printf("retrieve block (Erigon) %d: %v", blockFrom, res.Err) + return + } + if b.Error != nil { + fmt.Printf("retrieving block (Erigon): %d %s", b.Error.Code, b.Error.Message) + return + } + reqGen.reqID++ + request := reqGen.traceBlockByHash(b.Result.Hash.Hex()) + errCtx := fmt.Sprintf("block %d, tx %s", bn, b.Result.Hash.Hex()) + if err := requestAndCompare(request, "debug_traceBlockByHash", errCtx, reqGen, needCompare, rec, errs, nil); err != nil { + fmt.Println(err) + return + } + } +} + func BenchTraceTransaction(erigonUrl, gethUrl string, needCompare bool, blockFrom uint64, blockTo uint64, recordFile string, errorFile string) { setRoutes(erigonUrl, gethUrl) var client = &http.Client{ diff --git a/cmd/rpctest/rpctest/request_generator.go b/cmd/rpctest/rpctest/request_generator.go index 4dcbe3c4da1..5e23c3f1a7c 100644 --- a/cmd/rpctest/rpctest/request_generator.go +++ b/cmd/rpctest/rpctest/request_generator.go @@ -41,6 +41,11 @@ func (g *RequestGenerator) storageRangeAt(hash common.Hash, i int, to *common.Ad return fmt.Sprintf(template, hash, i, to, nextKey, 1024, g.reqID) } +func (g *RequestGenerator) traceBlockByHash(hash string) string { + const template = `{"jsonrpc":"2.0","method":"debug_traceBlockByHash","params":["%s"],"id":%d}` + return fmt.Sprintf(template, hash, g.reqID) +} + func (g *RequestGenerator) traceTransaction(hash string) string { const template = `{"jsonrpc":"2.0","method":"debug_traceTransaction","params":["%s"],"id":%d}` return fmt.Sprintf(template, hash, g.reqID) From df89d08c06c4d4027c105bb14c8789ec3e2702d4 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Thu, 24 Feb 2022 07:00:59 +0000 Subject: [PATCH 181/261] storage override revert support (#3597) (#3600) * storage override revert support * Fix Co-authored-by: Alex Sharp Co-authored-by: Alex Sharp --- core/state/journal.go | 13 +++++++++++++ core/state/state_object.go | 5 +++++ 2 files changed, 18 insertions(+) diff --git a/core/state/journal.go b/core/state/journal.go index a1674af0648..7913e1029ce 100644 --- a/core/state/journal.go +++ b/core/state/journal.go @@ -124,6 +124,11 @@ type ( key common.Hash prevalue uint256.Int } + fakeStorageChange struct { + account *common.Address + key common.Hash + prevalue uint256.Int + } codeChange struct { account *common.Address prevcode []byte @@ -220,6 +225,14 @@ func (ch storageChange) dirtied() *common.Address { return ch.account } +func (ch fakeStorageChange) revert(s *IntraBlockState) { + s.getStateObject(*ch.account).fakeStorage[ch.key] = ch.prevalue +} + +func (ch fakeStorageChange) dirtied() *common.Address { + return ch.account +} + func (ch refundChange) revert(s *IntraBlockState) { s.refund = ch.prev } diff --git a/core/state/state_object.go b/core/state/state_object.go index 8ac57cfcd51..d826d764991 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -209,6 +209,11 @@ func (so *stateObject) GetCommittedState(key *common.Hash, out *uint256.Int) { func (so *stateObject) SetState(key *common.Hash, value uint256.Int) { // If the fake storage is set, put the temporary state update here. if so.fakeStorage != nil { + so.db.journal.append(fakeStorageChange{ + account: &so.address, + key: *key, + prevalue: so.fakeStorage[*key], + }) so.fakeStorage[*key] = value return } From 0e8d7b833126d8ce7d987132248e600acc61f543 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Thu, 24 Feb 2022 08:15:34 +0000 Subject: [PATCH 182/261] [stable][txpool] Poke transactions that cannot be replaced (#3604) Co-authored-by: Alex Sharp --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 0cfeb605312..9721438ac6c 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20220222093403-f3e052f4dd1d + github.com/ledgerwatch/erigon-lib v0.0.0-20220224065624-2b634b692f2b github.com/ledgerwatch/log/v3 v3.4.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 diff --git a/go.sum b/go.sum index 6c699acc05b..e809b214d4b 100644 --- a/go.sum +++ b/go.sum @@ -493,8 +493,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20220222093403-f3e052f4dd1d h1:y3RwITHJ5SE3W2WXAqVMsRvMsjnp2IPFsPHOWBhsHzk= -github.com/ledgerwatch/erigon-lib v0.0.0-20220222093403-f3e052f4dd1d/go.mod h1:BQNYmN6i8RdHqedsztAj3XDnswYebacmFAnsznlisTc= +github.com/ledgerwatch/erigon-lib v0.0.0-20220224065624-2b634b692f2b h1:vlh0dSuZRVUF3KXBMWI6acvusKxWCSjZldggtGcSleA= +github.com/ledgerwatch/erigon-lib v0.0.0-20220224065624-2b634b692f2b/go.mod h1:BQNYmN6i8RdHqedsztAj3XDnswYebacmFAnsznlisTc= github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= From c4e29e33707474cd7485f137310952a8ca14009f Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Thu, 24 Feb 2022 09:31:24 +0000 Subject: [PATCH 183/261] [stable] Update skip analysis and preverified hashes (#3610) * Skip analysis update (#3594) Co-authored-by: Alexey Sharp * Add preverified hashes for mainnet and ropsten (#3609) Co-authored-by: Alexey Sharp Co-authored-by: Alexey Sharp --- core/skip_analysis.go | 2 +- .../preverified_hashes_mainnet.go | 265 +++++++++++++++++- .../preverified_hashes_ropsten.go | 184 +++++++++++- 3 files changed, 448 insertions(+), 3 deletions(-) diff --git a/core/skip_analysis.go b/core/skip_analysis.go index 074269f0a65..37e0e63a1c6 100644 --- a/core/skip_analysis.go +++ b/core/skip_analysis.go @@ -21,7 +21,7 @@ import ( ) // MainnetNotCheckedFrom is the first block number not yet checked for invalid jumps -const MainnetNotCheckedFrom uint64 = 14217100 +const MainnetNotCheckedFrom uint64 = 14262700 // SkipAnalysis function tells us whether we can skip performing jumpdest analysis // for the historical blocks (on mainnet now but perhaps on the testsnets diff --git a/turbo/stages/headerdownload/preverified_hashes_mainnet.go b/turbo/stages/headerdownload/preverified_hashes_mainnet.go index f8dad0805c1..6750f8ce142 100644 --- a/turbo/stages/headerdownload/preverified_hashes_mainnet.go +++ b/turbo/stages/headerdownload/preverified_hashes_mainnet.go @@ -74049,6 +74049,269 @@ var mainnetPreverifiedHashes = []string{ "32fbada851e3eb67ba9254c7c578990dfc57ce00556f992f42985c3eefdd5313", "9672917c2cc8ba35e65cd7ad5c355a16e98d525409b80fa4b7e2a2c30dd8fc5c", "ab82de17282c5944afef9c72c0df68b24421d28d59f80090422c16ef376b299d", + "a3b2397d83a55e3d0164d2cb2a076c1df996988b0c84a711295fe94349e166c1", + "6d7c3f2a647ee517e7c9264d8158d89720fff1c45569700bb3646945ba4eae93", + "1a4aefcf9f3e19075c13b88223ed2a24f4b279355df219d87f0851c98838ad89", + "d6d619cfdac73a2a2dc400a86e352fc2c10618bdf6d36aff71a99fda786e6c03", + "3d45abecdb974afc88652adb94f2b52baa63b1726aeba0aca0979d0e72ac6e91", + "775154ddbb465e14da74cf4a996b3a07c8f463966e1c672112164d247433712d", + "d2329cf248d079e406d4c796f3257e83f6e70b3443b560416e378d86cce906ea", + "4baf7de394badd55c536a9bd30fcc3eab87e7acad1bf44d0feb60592cb20a3a9", + "905819c0d32cc47119df11ed0ef6ba3fdf7e29b28eb07e6657c560a241137aba", + "e730509aed31d5893cb541ede0a9737122176888d3da6fbf14e9df0acc862716", + "aced5d9128998d1ab5010f02f879f13566c28da4e79864f422441a8eb31a9f4a", + "344340280a8eca35c7c51acd6dc9d19d054a5342da32eed819ec0a7e8fbb2572", + "aa7a0154b65740f4c7f70c9962b6ff9e6c7447f6550efc66fe1f947224776718", + "c15b603fdde48817f3552192f943d14d00ad3dc640cefb9f8a772130cd55626b", + "6097948d57d2315dddf51c08adda70152ffcd461aba916ce2e76dc5b53d944b8", + "c30bd6148d73f9c3c4b3b43b89a2583a3c00f0224f40bbd8e6fbd8d54b606f6a", + "8987337900c2c91464b586e2e1098b17800b9bbbfc3fb2a680258827c853752d", + "ba9963804ea2b191fa3e33a41a093c4175177f29a32bdc4fd45ec58168587a2e", + "b6d10bebb7aa17fc37f9be8c2886b9487b9800bf4628cb80a1b3b0a12cd2f4bd", + "c3b04dd1b9bd92f6b4571db210b8561d6a2e023d23b06fcd259ba6baab5b6816", + "5b4a6d5891c405d5e5652b55559053cc9d3dea2e4eabda46649b11a6790f1b1c", + "61e7b9b59835e48b77d3b63d1485718c3369c32e9e6ee871382726499bf1c4f7", + "5775bb4bd68c82709092afc9419ac518a0639b38c077745dbce8e54b59eb7e28", + "88bc74947ccb8d839402ada0edc3254a9546f5d38d8cf1ea38f9bc15e9191489", + "014756b7093d46f59b6302b34758c9840e7fbcb7dea59fa490561edcd558e642", + "ee2e80f14c81e7b57dee8cf98d532c120933a2a3b3fc475d3ee0f6bf84d9349a", + "c0d0f912d8d48eb01e603b01f12e002b9a6bfce2165e162efc28fe7332f81290", + "a79cc6c01143cb256851a3a2d4374a36b1e78d629752b3e3b2da7c7fcf13e346", + "685e158b6280d281e20d556d346ac2a90b1c94cb93dc723337044fc834fd1963", + "8a93b8d8b9147bbb74dd439118f14f4b15cf09894adc28af6dc0e6c7af7e4786", + "b770b1db9d8f5b20dfdf389fbdf007414a21e98ac26c6e229baeb61e02c5c549", + "f7635535747fd0e4c6a5be26ceabaf7547f37a83b618efdeb76aff8f364b4162", + "5bbdf0b71104aaf09ba05da89821c1655cc7b601c9435fded546c47421d949f8", + "a50b7a775b3dc8a66e80f9888ad14d863b5fd4283f5c217d88a57f76c90494d0", + "1d6d5ecada70c4236f47bc39120fcb7a7ab94e1c5c848fa26b55476c037c5e13", + "6f83ed7ee4da322c9e10e64dbb7c5d9f1321634585a17ea5cf3e5d67b5045a84", + "55bd103923e328c8426838c79053649cca3673d182d1e4d13636159b0cca7252", + "a2f365b78943f5e167d488ffa3afd06558ef3f643d64739ed1f7aacc88975096", + "299e113926cee140acb5e85a53be0c23859bd316343327b1275072a740df7023", + "184a619916219733254008d826b5f30a27ee5b3f4e09d107e6c57876da310807", + "afd4b4810548fe4d32afcb941511377c266a5c878e2c9bdcd1d227f5008a88ca", + "70c7356432e0686694ab9c7376b378e91c4f5aff52e706d8dd06fa9c2e58cb48", + "210887945317f1c1abc65b44d00bf7fa86e212a44039105a48dc29ad756afdf7", + "5ba707553ad5731ead32c6c2521d2483aa2204f2b3cf0b44f21be43079836589", + "99f4a11d9ddad8970c5581736936a33f80cc8de6c6ccc48189ee889dee1273e0", + "1abb740ba1cf622a53504bd74e11b76eac1ed9e6273904545d7dc57bdb086722", + "c419cebda29c77211722231b7d4c2fbffcdafa6f3372315d7745fb9ffb769fa4", + "8163db09eaeb86fcc361b6796888dda5fe20b7dd4ab29e9ae718b24510b06b77", + "2ea97b9fe2280096e6d45e81846e80b09e068baafddd04b46a878b7fcdb13807", + "ccdcbb177f4cffaa0abc37ebd4e7ce630caff10e9dadc815bdc0849f9c2b435a", + "1da92543bc25240ce37cff2fba41b1513529a0c61dae689bdc7972c281b9867c", + "5660ef7a5b379db43ac79d6c0679699464952bd838b68fa4426febcb8ca7a99d", + "f37bc8f65eb8240e2ebb32684988a8fb28ea69b6556b702cb368fe6a147f1cd6", + "048b7b906cf3b84ea85e4f13ab875c4b40708bddee48c5d6a052167ff0e28601", + "4a0a8b141e356fbb4cad08e6b4cfb41298db6c351d1b1887b2383e2666183886", + "0f9d52fd8ad1ffe0d166df13a7890824294fb48f41263233c7494a0a3e0567c4", + "733a1fb0fb9ee88112417177cfe69e489cf74deef872a92f9e7d5cddeeb0b95e", + "eb8f14094c1e57647dc7b4915d0a135d1927dd771cdb7ebe33eaaaf921439a0d", + "f86d6de3a9067e552fe0231a83112e557a74047919fefdaaa70680f34d68da3b", + "89a27e6a44a923b8dbb247b381b3cd2c37f155a3fe20e7d1d1b034b7f398c28f", + "5ac0141758c894179d379297bb41ea61c99ab2db60cdff2d249d1c6572973d3e", + "86069f2fe109113e9c9f6c972eefe87aa8ba8192632d8556780ac6823b2bfc90", + "2bf30fc1aac1f16f1072717fe1446830bb15e2df1277c7ffae0a7ed7b7c20660", + "31ad19fac4f1349d97bf6e4a5f4bde1e86587d39400799b4e2b695d423438ffc", + "ed273b2a417ea9bc8de3fac1e13bf202db5ab7d7f60b2f8039fdecea73f5e497", + "a1e9b6eb905e73fbe0aa684715cea134588a6316a633d3ed76ba566a073d5dae", + "cca3980f5b6621d2017139ddb444516356b1f10e0354491d1da363ad989d54cf", + "4e706b523dbc5f74ffefb362e3f65b93f163410962039e1af60bfac0855870e2", + "b2733235ed180b4a64b669a386bb7053c5c385dbca16e86f99f6740a21269b52", + "ff6e0b1f2ad0dd84373c4f180773ae321d155f6dd15f4933d19745ac2990ce19", + "9842430f5949cfaa5ffc418a903cb2c96cb40df2c79dab8492e8ce65554a35f6", + "9468a301fed9a4bf3a9cb583db9be836502ea14dac7501b3b21e4b8f491c6487", + "dd1c58e7be43b6c56ab305bbbd6129801e64f713f9547f23ac5cc5463ba463ef", + "a9633b25e2807eb75853c245fb89605cd8cfb341946590a7210f24172d13a0c6", + "f1b65c5acd00c330bdf05b2581c4df51f7e00e0b74a6374e575ccacbcb11c12c", + "c0a4c009a70f66f722a457eb4326788d98ea8f7233e80999b235bf9a356b40cf", + "caf8f9c1833deb6cdf9240f023e1801d3f7cec30be1d9f68781111e14e598201", + "abce3888b4cd6484c70d3b480b096bdae4b2ccb22d90e94ff76dd80107e82507", + "31f847f4ae732f30eda2858a6b398362673a04e61dc18fddcbec7cf911bd2b3b", + "b801752ec500279d54b7f610478f3f07ae159aee1fe0fcd964934c601ea7f85d", + "71226de3522d598d86486df7984fd6afb4e54d8c9e46695acbd348229608c547", + "2c59e32e999ce08b737c7dbda14b7a9dbc79ad69f3d9d5c279275d5f83b9a160", + "57712d6ec4945c098a0263ef19371bc0cb8423e7c24ab2d0d289a770dd0a6243", + "0b99eb267d6647b9c3e032643451e1671049fd716427b2171b2e7f6fb5f6dca1", + "3f33c97d07a41ab740a485afc39b60bc32a5cd1b23bd5a4662f8b96fa0ef085c", + "a472dc2c66c4ab43541ac192000b74a68b86f7fff7e8fdc874efe7383d1724e2", + "66ae82fc350bbb1e151fe12b78566d3af4d801278a612f91b8aea224edc1d086", + "70e1f70bdf28d0623977b3b1252c93d5cda34a95305171f940acfb370c74ce50", + "3e92be127c091a2b16a3921359717e73ef9a3bedee11f96cb878246e3d9bfbc5", + "4eb1d3d18bff4ebc80940c2a7a8f5a5fbd9486c5de7298d56d263b7a26046be0", + "4094ae101a1a3f4a82249f5d843fac0f5f1f669708b0984dc4ff26270f69cbf3", + "f6ae25ce314bfa36cef4d9a645bdcf277dbc5c7a0d40897f3a3fcb2b1944561a", + "fe0485ea67d477306b2df1575496c6c980bf47b782e3b9aef21a2783ea81ac30", + "76ba864342f20c3b65e7c79cbc35f6341696ac2b262f5e3781b10c4e9e44fe45", + "56d23a20486827c883cae5f4103e564252cb62f2a8aa615e800ab6cc8afa4820", + "903dfb280810b2ab48cb6dbe1305202176559b8aeb73bf453d995f92839e9c0d", + "5751fe00e17ceaf8f4977617bbdeeb81cc4d7d4416d66daf17639188cc8dcccd", + "22323b2962ee602b3d1d67599e41b21c4f168b5a2b8b9ffc1f93f6adb3ec4ec2", + "9076bb8b1cee5d2f9a8bd6c03b3e7912f3657c4f3ca595c6dc79ca957eae1b6b", + "04ea4a97e426c0b1376895a482652de8415084d947508ce2d7a99143ef66671f", + "9156ff070f17d19c8ce87766bb53bf82edfb33ea220e2e1c6ca116ee81dfa3a9", + "b4eef621e46df1c85d3c13f297b9a6b70c39146648fde82d1c59fc0335ebf04c", + "b118d14d301925219b127d1173024e8bbedafbd3c052d7f1798bdc66d1e5f789", + "3b288c9d28468dfd7b3687a6f6c201a196132371ee3b159502806165b546d1e0", + "d34b8a2ac53263199895934b7cb3b53816b4ba43eb35917885d4644c53c2af04", + "ffc63670da4904497a3f2141b16dcd67cdc592b659343f073c6a103f85e8d2dc", + "990bc43fa30be25645a2e957639506f7b2407c1d57e1a59168509ed5ba84c758", + "3aa019368b829666d7253ac81e2b856f15e8fa39eddcbb79b0b7dcfdbb21a7f2", + "c93b4ec7756a2fd1873ddd63e7d406d1db4a16d79d05ebf5e0abd77eff675669", + "df34bd3aab034404c8fa404baf0eed4a6ec4568c2a83d44c1532f9aefea8cd7a", + "693060965e02fc2b531b2005afb286a5a0ac0f02ca1d5f74ab24409689209c45", + "bbdf7f3417c0fc63265ae70a17e0c9a8a0e4d02511b77a5b66b182a0dd6db048", + "17efb9b10c08b338c7647f95fecd34087fa251efe03016da72e3c96965a65bee", + "f4a263c06d2477b1113667677831dffc52667abc1d2bfe0349d19236944539bb", + "cc4cd7e2021d14cb59557a8d66e65122f54a2f2b847e33ef80b038ac5dbeac4a", + "47ffdb56cfff9e52e512bf67c3c7fb33f25b6e5b530d640f5861f4d43d28dc33", + "de52896ace89e1c4fc08ed24d1fb4a6b33eb671321c357e7aadae3109236faa0", + "9823aa620ee01922f786954d3cdd59945f1109e044965fcf81a77c7219b32e3e", + "b2dd3dddd5c5616f0b4ca7aa98c54bb9e9f42101629d273678671d08c9f62968", + "cf9b7204271683cae2ed2c7e29044facb16fb3daf51cd180f63d562460f19877", + "106773baa7b307f59a0c24968fc60afb6d6d92545bb82d3e1920d1155297eaf0", + "4c4a6ab21e789b79c1fff605697a0045ccce4a5c100b850cecb91bb4f09eceff", + "a9591a5486e930868fedca62c1e7ca66c8a69ed7cfc8653c6d9aa8b7f1853b9c", + "2a001d183a59712c532daab4ad7b6e8d31244a4e9db06f52d7ff8adbec38ac55", + "b7210c627b3c7eea607c56e74a334411949f317db4509884a3261b20ed41ae72", + "6f652fa82c04814b3c129dcb4e7680d0a1713aef3bc40241eadf3ec38becd5a0", + "657e14f59064a620e939e1dece4b0f02d1f0a3dcf2b9f1205f9c2bbea7a4ac62", + "892e01fb388d1070f4189d017edf30552b5f9761af90bdd9c8ac5098ddd1d4b2", + "dd5be1da91ff92e826a2d9603e49b3425d1b3831caa492207d2c68418573ec92", + "81e45bbb67527c52e5243f672a5fdf85341b3f82c776776b270a77a0f8875660", + "6d4823fa9e7f6ab342a656e5775be3c353fad4475fc47ec86e8e9f9b51f274fd", + "eb5ac469aafdf61c0c865745d0ff401f121fbade9bd27fca0068c56949160a84", + "8839a905628dbed6daee74646c3668f4fee2cd6eedeb3cd4c090912162bc82bb", + "d47fa9aea8de4c2f8c41a14fab68e3ae2ed1d3f26bd83104f98493116f908873", + "277fa9a84dfef5dbe70db0842e1ede7eaa50e5327d3fcc792b239b7a2a50ab8d", + "318c7a1e591197983fa8cc218eef8430e4928804a8f5ee24df5fca91cf3af540", + "ed68fc89f816059faf8eae91b4392ff38f1e1235314f4e81a3cc2ad8f2970e86", + "cf72ea393088185d0c25fe2d6017153a1f30511c0d12b2d0551afa2e00498b43", + "c8cb73c6e00e9a76cc1e1ee35c7eed1a70b4eeaea4391b14f2f1fac5ae52a4b5", + "57220b2ec34e8d541284b91a847903eb39df494c11229d30c0e8b6b7ee277848", + "ff2eb1c8fb87695f83422c19733aa394aa031ba3a2ba80aa5dba8cd5868da856", + "10da26f6dcb41ce3d0e58dbe82ac8a00ba0921ed420d68da5d3886c6c2e41c1c", + "e43bef811135fbde13b82006e06d11145c2ef3a5521b4d8fc585b32d486eae15", + "e013f42932414791cb5a45a41eb89ffc2b780a99d85be065b98d1b1f5e6fdd40", + "32b8b2e6b7bd66a331b6daa532d25824bea4511574c0f60df52a641518d75a8c", + "ee93f244bffd6ec83953fab1b11aeae585303d36424a84c8bdc4ec7972f05b4e", + "5242c4f5e0141790a0803eaa07064a41f55c0c5d079f6d4f27d7268a452e0550", + "b9e110a24836684169155a83b232ba5371dea3897f9b1d552ccffcc810fdab3c", + "1f34a9b2765f47bd3476a333591b779971f91151b0ae1971f3d54008b0343416", + "62f93a547ad3e910f3d5adc834bd7e4f0c2c6a23664afbe9d62a1672800b46de", + "ea5a75216e6d4ae4d0db470bb9defec1e140a4d4ca272df541db90d04bba0818", + "d07e595b5f8a3558b630ead82616d714692c7b026716e8c7b64a0dd0177a56a0", + "d0215876550da9daebca6d611027f3f2a5828d6ac32e233d9bf0c7b7c3e50d06", + "1fbfd27fb0625974d65b4c6f9432266028a58bef59f6234bf1dfbd955e46be6a", + "f889689e00ece570b358277d000fd8f945f502f691718b6a076171c675b65f62", + "a032ae514607f8e5bb1affe6a474d18ab27acbcc7ac52a6d390e5379867201d8", + "6e16ad565006d275019f5a2283ddd183f7cc3d9b0dc9e9b508849bc8add91dd1", + "ac5b9435251ddba16f351004be93e03f082d2efc5a66eb5060bfaa6554c42b83", + "5bca813de9e2e618fc4893f2f759b75ac612de93ac708d934780047c5593478a", + "81760456519763fa2427300f073ed7cb058734f400f40f996f342180c3254b87", + "e4090a0497fdd8ac13af7650979e678fde42ad6779c54af371af6dbb602c8dff", + "29b2019928b337b77b760e22bf115686ce0b3001ac5067e0d226f86583660f72", + "da5c58756b96e61a6a4bdff13da19f164329e59c203f7885c915f04833323c4c", + "64f1f02a4ce979ec65c03ef2e1d3161443d2e6696a1823493e97589214edf3ca", + "757689382d4c5fef3fe1ebb45af28fceca6084a59207bf6615779dd3d5965f23", + "939390fbac9a9d950dbd8949ce2576bf24e4a914e54d675f20ebdb1549c988b4", + "a2f702a536b31215ca45c99aa6dba352bbeafc5d3241f064ea78d99418e20514", + "946b010cf5a2e04a37cd41d39db98b59817c49aa95f8d565e50dbef97fbe4648", + "56587ac6ec814845b715fc073dc983fc12f0fda2550c3f96e1f7c7305c190dee", + "a084131385b1a56c9f969a2adb76510ad3cdc1decd1f6de2d30e8923ccaf99a1", + "6eb3610ba0c2d82fe59efb20f8332fa2118b39ad1fae1a793cf110ff02dab3d9", + "55168e60b6a3830425300364c6b87602ea8d7ef2ac110c27d3e34ad3cd02d253", + "da7f72c6e3ecc56e85085352240fa1e74695c1dbb5910795e2f416c4742bed8c", + "2796c81e9db8557ddfd8e75e7e6eb4c789c3b2d294d3cd1346ffc7b549b09b40", + "b4377290416c7534752f11d7d0ab3733b0dc743fef6789d29558e678c1e1d5cf", + "70c53aa8acae15c0c82e05115f1adec15d5981f1e985b34401ed65057e0f0b5e", + "7fcab66d00bf473ef067b132a978c3b69b35411ba0882de0216a4b78a0847cf0", + "fb02051c9c868cb70f46b68853a58c95469491a36c4f5bce87d0f6ac39e50d77", + "a2ffba6294994683b29987ff53333af8744d98b9d41644e26e67fdcd88846000", + "11804ae9eb324302ea689309851e82b6240ab5a0a50a70472a315779d9074c0b", + "f3e6b9c56c40e8db3dd71f563298eb0f5d13a686c6026f012ba8270d8bebd953", + "14a25851763667df6a99bdf5bba69e6b0c7eea8945a7a1cddb351de82df00ec8", + "712b7d9727b2c7f94e18bb0b35aa6d80b78bfca243aac371f9e815623537d42e", + "4b23521edede7ac0ae6b59808a514278ed3b615f0c13f7972fd5ac17dcacacac", + "aa41fb087e48e1cab38d7e2613d9fe97fb5ee5c1b603f0c384ab89c7072defbd", + "78dff59de26c13c030ba496e829f0f17827e8db80894e2868c08718ff4eb0a5c", + "f36c1bcd7869d881a4e0b96e087cc310a57ad6dc5faa305059950e609b547101", + "508410b8473ac0b3a2502314980ca81b3cb1d5025a053181e8982c394cf7ceee", + "70829f8c4d147f4c4d69c630173daa0fdb39b9893a9970698d30cab777fe024f", + "7c75ec2d3ac61fb35d025ec0e4d6da5909e66effe38ecd15190014b9a96572b2", + "597d1ed1785e8579615023bb44ac7db90f8866f5231b85ee9aa1c9af4fd17da8", + "fb09fe4f2491de3e6ac923bbef77c3ab9580d9b2a936fe80ab0e9377bba6c546", + "751e648aa98d45b028d4567bb32b1efd5468df1e89cc60fba14daf5a6ed5c63a", + "c6878b74c5bc366f54da370fdef38ab31287957d82a9dd9118df8e4cf5fcde89", + "9867d9af4ab55d3d52c9205f92866353f08ef9ff3bbd586a4d6990afe71d3e58", + "f3a49c560b2a766a31d8ab841453c2b582788ba984efdb4c47ffa7bf2e55c8f2", + "78ce2cce1be1100d7deb5f63f35743eb784371da68bb6ab8a31af22b60867c68", + "1e169dd9bc279985747573eab2717e1047455f8c702a8e0e91f9e528e6b19dd1", + "401ac0c7d8a675b6b45618da6bd9461d8047f5728734804639cd85c40afa0b27", + "5b549a6d2f3b082fff0ad72769fab6e5f2323888bff1704c04c2caa772f78c62", + "05beea54222341ac24440e39973d3bcda799015d315a9dfffcee1c899e7d77b7", + "46b4e4b8a7687a31ff4ec80fbab553d1eb90994e9ee00bedc81f6e3d4e57a9e4", + "626d8ae746f2d3f712e317eca23c92acdd0ceae86c903c56d6a29fc389e8752c", + "83850baa29e747f7e432e200b6f9e9007742991991084dc19c03eb3d085e357c", + "45edfb7df1f89ac8f4990918e60428d86ad74e4a3465f5b1e5c80fa8a3f22bcc", + "4ee73fa7319affa971163efef23227ae0e1dab7e92e2b5c778aaf13c475b25e5", + "8646de422708233aa4f697cdaa872dc852e517cc95854f4a25f53a2d13270e46", + "ccd5ee30fedaeacbb190379a3d93a1a92bfc52945f915ed74c5bc59aa63e36a8", + "435619047f2c3a4b629be58559dcbabb982d780490ed8aa50ea0e104ccfe83df", + "5e768bbfa6943d73993c3a1b2c5c2ad95f6ea7505fe74390839315df203d955e", + "d6633f43d5858675eb2db9717b4c4788e0ffd867fe1c52ea153e6019bf9337b4", + "1028387608077fb748e41d043270ef45a608ae8c468f0dfa85ee1ebf1fd24e6a", + "acd208862bd7feb14f0fe7bd6d931b9c44ec6577de96a8599f6a5ed55bf884d7", + "cf21861f3a85f62ef724db322d46bfce830e126e311e0335f7a445463c6f9308", + "a847166d5c639f39e89b203644f9355b15283391fe7fbb29f236fb74f8673d0b", + "7811da5f63ff1bf29acf4500a1b226f0b935d641afa72653da382b2de45aecee", + "b49e9e7502df968f312185b368168b0174fc772b98f5c266bd889c7ce7561136", + "8e22a011f3a3de2b755db3596a96725890f041c4415e994a0561e242bf40a2e0", + "d3cd619fadc0b69aebdf176e4f0bea71880899a6964e2b20db078bec3f9fc2cf", + "37af97c7d70e5a4a768d4a4588ad98ce2b6fa9f2d055fe9d9b724208ef38b4f1", + "9a648b59f653b1a12c55b06f5ca19ac8f6c8a4bad36538be861b582512997eed", + "4d175d0c4a6283bc276256000d32a4bb76a1d410844d4bcf2d30a76e99e24a31", + "8a93c399899dc44070d1bee5a6728263dd13c0c79f64a1df48d1c22a84552d26", + "ee2b6dfcf790e5be8e4e5a85d680ab4ff2c584ec34afbf60cd013bbb86fb6673", + "71ed23dc78ec3e252a4b556b691a0a45d9635c1f9e1e671dde628bee116e1a06", + "12f2fa926d50fb1a8576d6566d23e95d54f4bf8ab011a86e319a464001464755", + "e9999e21b4bdc0ded3fa71dfb68cb73fafcfdbdc64503676e0264b28e89b0cee", + "4e1f028152aacb1921d112f5c21d59f4be132ba817ac0a13fcc035c0c1f0fa91", + "fa0f866448755587b4f9d8549ed472a0889466ab3b9fe4d1444c01347a5e8c12", + "627e173a059f32dd3b923069979586cf32560d8bd516486018baf5509f1fe86c", + "ceda4a2e67abc1d980b1b192572a59b4e30e55987b911c4f6e9914ebc51d17ba", + "8c282b6d6bb76f387d0132ee187f092f1e0cc902d2e3e3983e614f14a71c8f0f", + "11e6dfd24b75332915faa9a5d8bd3e50fb079ea56f4300f0ec743480135a3e1e", + "88b28c94460dd1843493f3985faf87c668c9e5d4f2e51d988bd4fdf43aa24e6b", + "bee84da3a1444e3063891c9b4b6e475d4e32175276d2c2f739475f059392602f", + "2beaec834540c376edd4bd50eaebef049d3e2cdec911b309c680c0ce6efde29f", + "989d102b16bc7ce4338f8b3f288eff203100071938f8b8cfd99b81bee2f51c39", + "a36fd70eb34e717f2210d82bc9b5a8c02631172c6f1c71d011fdbd42bf9b59b5", + "2367b6dcf10b69520290e934cfc95cf293ed56ed9256f187f895969699d91c7e", + "82bd0f530b5f3b79854b55bc6acaf577fb6acb6e283b70e6dd86f587ab1698bc", + "e3375506c7668cc278a264789c24df6c6390f2e9636441da3efe61230b77595f", + "694fa3d886d945719aef5045b0b03b12586fdbc0c89da7864cd3699e36f3dfaa", + "02a21fab77ca555c945bcbe1c4f0d27c5fcfe34ac952e5b8b42f4d444b778d28", + "d371d7ee8b72ac5d32441e7550ac2304faf72fae6bbead09a527002dbcbb0ab8", + "0f867abcc1c98d8e58e3750f359c1ebf9ec78df6d241e8d8add7c405bcde4bf8", + "921d9da7ac3f6457d47056f936a780ca695fddef136198b24161538a040abd37", + "9a06118dcb78bd3a4a1c18775ffa8d6290885598b8befd3f2c07f0bd82a3c28f", + "1fbb041221d210ec4a786568222d0a6f6453d51eefba58a7a0db6eff45d280ec", + "cd94ca9df4cc03eecd5a005d2295e73b743e2a21e56557bfbe2e4c90b2f48fa6", + "1079c3fb2ba5844855862dc97040c874126eb411b001608c2753296a54390ac6", + "019f8d7a732ef586897d982cc077e8d772adfe74938f342f8dc0ab5647feb5c9", + "032c0fe81bdf06c2396ef6d0d2b27f82ed09bcfcc3999908504b708f24959d3b", + "438d909d6ae886971d5231816f4a449348c4780a569f3611231e4f7d5b314ee1", + "45b4cb829fe65d9b67736c5a03840c308fcac1139688221383593831373aacd6", + "ac87633e595f144f983fa8eeca79b2a593a898d7418b1bf1d9c7110471e67570", + "6c5c07c98b713440bbdbfc01f8e340d1e21ae0f7d12ad5d01b7b76e67457c763", + "f77de5a02d5d7e79f263fd9d5fe2502080a19c345b683871ee5df52760727e8d", + "8c177e464a71bab7d98bdf13b672f7a013ce7664d88ecd23a9de1582eeb1a951", + "4b440acddb9905e76979c6b17279cdfc629e87206698e8ec20fb8a7cd2925400", + "44d2341032994327d1bbbd50949ca05feb47828e866517f616790679dd9871d5", + "018af69f29875d4c9b65521c7dc06d95ef50f9f1af8141f01cf5c4d6ff26883a", + "9cb67f964ed81091c4a2dbdb8fabaa9028b0647ff9353c74706d88bbbe9c3448", + "6b0c7b72d9d206c246bdafbac829561ae2ec8a16d2e57f8da1f4037ebec11c73", } -const mainnetPreverifiedHeight uint64 = 14217024 +const mainnetPreverifiedHeight uint64 = 14267520 diff --git a/turbo/stages/headerdownload/preverified_hashes_ropsten.go b/turbo/stages/headerdownload/preverified_hashes_ropsten.go index f9780abd7be..ad348447cda 100644 --- a/turbo/stages/headerdownload/preverified_hashes_ropsten.go +++ b/turbo/stages/headerdownload/preverified_hashes_ropsten.go @@ -62376,6 +62376,188 @@ var ropstenPreverifiedHashes = []string{ "d754cb92dc79fec57ac696c03cb1a54ca97a5e09be739af2b51967529739960e", "d12cab13ed7b52f60b8aec29714d97795e941525b6fe66acf5a3c2d4c37ec1ae", "c17e24970ec4f561614b8ea16eb8b63d32b1d2c7c5a6c540108dd53f03d4d534", + "f29f068501b87df05761245d7a9acdf97df240046ca9bca0cffa93b69b47a7c6", + "8a5c363772787344d8feba93fa8f4e0b9a7d21e5a14954df4ea69c5bd848cef5", + "97ffa34f7fe27bd4dca31eb6580c99d53c9907901b33ed4a64886f71e3ba4e6c", + "4b4f576de2a529c0a65f26b2d3a9576d816ffe0eeda01efe3ac86219caaa95c2", + "bdcb0329df94e90ad6fa1e2bccc6a1b6264b55f7aec46ef18af8828e8203de22", + "a715c6540a0704b817e9e2dcf9f5076ec4aec4b19f45210c949bae17f69e3a30", + "73883ff3b29ea01411d20728b089fea46922f34345f964c52b0093c6d89f1552", + "8e19336d2cbef709336d8f3981c49473743e9918db970d36147cce83d8fe7604", + "52df8b15959b43e90b97a7efbaa3265c1c984c5edaa826599d1ee120970300cc", + "5e82dbb59097497bf5d1ee35799ede0f9a911b5466c2d52e65c7c5d73e776765", + "567cd51e4699c3149c87f5a5ff8a0e9bcf885c44af2443a3bda2a719d75623a5", + "53b16ee698c22ec9e46b03aa0ecaa1f65df196f6f4604c10065c866dce6aa888", + "c5279adec9a891932f737478ba2d0c7455229759f2ebfad7121eb4214b8f48e5", + "049e3c1050d53eb590c27c58ac9622a66f08657989070cd0cbf88c17b49bb229", + "6190cad8c0158c68930e34cd9297a78f02a66471877f274f21f7320d31359074", + "856777454dcc8f5fd8e0d2e432fc78ee143d8ef96eb4307cc75b0822899926e0", + "77845346d1fc5d19167941429e48d591d0f6173c0c8bfdb9a3face0bb8c2ae4c", + "9e440da5a90c85b2b5b15dcace33a5ac400bd196f4833da22a870c678f8c8fac", + "23567e906f9cca9c7a17337a4717897f260f5d18564f41b970273fc379383e9b", + "f913a8fb782f837c45b58f1b935c065dcce810c4cc7897d5be23b3b3c717b659", + "19e22218ddb9bd9beb4d35d97ddfd827599da299194dc598e275046e72255158", + "034e8589c1acd6e3268316998d67a3f66edc3f3b50fd2403882f6a98b3ae1119", + "0df60e896318c41d4011c5bda2d5ed81714bff8e1297b7a0fafc0ecc6344f8ff", + "3124721942f89a35e1968278ae946c9e1b72c84dea0c92373f987e11b55b537e", + "245097b795898c3cec2ab3167164ff211b17c7e373238b190cba26f68a4f8b7b", + "a9d1ab090baa53d1ddb1bc9a833c66c451d3f5666edfd2894de73dc5ed14e430", + "63236dd916db0285772b516ebaf6d9ecf41688ea331d8ab3edb1b1df632f289e", + "2a8e0e2e223b20e188cfd0b7d63dad286507c0c4a84e0a78201872545e712161", + "5e60124c83ab1a389bdf341caaa889bffc602c8f9df91727d484b14cee4ccd9c", + "b27a3978ac148f07e9b8bbef7af58e631c221a4f53aaab64af1cacee45c8f7e7", + "a1427adc2ddd42b5ec383e721cbbccff0ad5253a842c09a334f498878f5981e7", + "a4a1860b14a1fd0e1ae438f51a3660919d9b83d7455d60a317ac698f36e6a33b", + "0b4d9ec126056596fa0ec9e4fc7ec1a4d09d41d88f589199eb85bc66c14f515b", + "264c42eee4586cfbc0234443e9bcef1aaeae3097bf52aa46b3966f139c359980", + "596323dcd6dd994a74af947e6189fc3b7d296763473b3952fa681f5b218bd999", + "acefef2ac428d9060c093ea3197e39fdd21dcc9ea41fda6190328cf92b49c87c", + "fc6d84be49e4fc7c01fc1c26b4ed925ae8713e4e851daeb5e84cf1a6bedc0679", + "177ef634587458f77fc44093efc84045bde1443766a41ec41fe14129c82d3ef1", + "5c374e200a3725c3ebd78a1726894ec5e9c51f465b447a13a0522069f763dace", + "1cde884c8f04d1f444f5e57943463972c4af0b8622b424ebb2690bc93afa2e0f", + "156f3d3274cde537a9602adb3406b09579f050acb973ad62fd1ddd2a1a974bbb", + "4bc9e3713d96eec6b0d78114d3d964bdf0a65f686f711847818418e86723e285", + "7c33a592cb7aa97a08243653be121e76a2994bf989e809177b403e55f0878448", + "8d63c5aa6e7999ed04f14e668040d379abaa5e4cf5e4405dc9c0e4d669d6f549", + "b1d907fa1681b895172f418ee7c98336bfd2619aa948d137555bfc9d71693829", + "c25d0e40b178bf4694157aaf15b5c276cd1a485a090047df2bff837b1b726c1e", + "9f3f0bc293c4879147d4c1af93e889d44002a6f10a30998e17376ec200b5d3b8", + "0dc03a7da1e09ce579c55b1671a25b05c673b33d35c85ff4a17c685c112a0389", + "a621e2e1db12dd42ee1089ba4edee7886ef1abf0bfb14b55801783f8b7ac101f", + "c5f76db8bff41c70770e4b8e5976add7e1c2e2ec915d49b0bf19d4defb958614", + "dda4e8dd008a0a949a3c02317dd1d74f2ce423388d3d3536ccdea743c3316fcb", + "fe30a9ff187be6d9697166fd4e76891f1f5fd6a214cce4c36502d347a540e0ab", + "d6b088e99f69104dca79e06f4bb1adae5dc662bdce101e849901ec5a345dfa7a", + "d8f994ad3552d1d8be76b6d7c291b997fc016c463faf21d376388ce51928e59a", + "5527ee295adc6cb7a306de9941300372167401ef389bf29a95ecdd61c360728c", + "3c912639fede9e01660e26405776ae781afc16a110cf0608b614a9475e84a1ca", + "0660fbdcc8a7680618e98c066519ad6b4ff6e3de6972b86c57f8f0787966e575", + "1a0f4bb5d694a04c7ebecd6ddf176c9f657061c43405258f8a27bfcf2edba27e", + "460ca17680f38b06aaf0cdcdf3f677a0286a15b67002201e74075e9487ca85aa", + "3ab54a11ae48516eedde21271e76c56a3fd3291f0b74ec5a379a125dd23685e7", + "2f108ded9891c2ceb79228f50c5abf43d890b0ec44509eae32985bea088e1244", + "9f766cbb5f7e6076703e3a6f75bc69e3d10c93428498e27c8f3c1959ef57590d", + "e766b209189cda26688b001738094ae0b89a31b8d2b12699783f4f3962e2dd3f", + "7025b7aefec6e10d21ad5a2210c0f089cd49a71e920cf6fa0b670673572a2f9d", + "f34f91cf0a8883c599cb55dee2ee9b0e58a7817c48b4b2770953fbadb4682654", + "27670f5ba68adda65aeff3e697014bd2e30bfcd3f0133880c418da26e5984163", + "37b30c16af8f289bd84478b957dca99d81eaf0651da9eac70499c8c89993ee01", + "13f8fa85673c43a61a64fc0760637159e9395e34937b104a13d7eccb7feee5ac", + "0156fe2ab7b1d68791a4455336f9552f22d657f5766fd1bfdc39476defb6204b", + "736e34e807c232c303b7cc52192a957937bd270537892dcf7cc88854c1e888f6", + "a3bb86d97a96d8909bfeeea7302d5fac5c7d5e2acbd0c37d416a9e7e46ab1fa9", + "7f00ea39073be8b68fc2173c898fbcd3bef004b5c242996698f4e5b4eeb7ed21", + "8bf3142eaec531c55d7e26135cd471c1be5fadabee84f351e33f2b75fecd8eec", + "6835b703219ee9210c23247fd06dec18feeb20f90d1fac25f925a93775d8b27d", + "1ab5238703f33f42cae96d34809962699751a399fbb95271ace8a67e917b2b72", + "15d75291e2b40c15a5a94c6fcef465644eeb84178ed598f07bac374d11b17ef4", + "1349cb1455b60c4ec0d2b543bc0f46cd98d59ec9b22236fae9ec34bca0e20ecf", + "6b2883c46de9cc76623fae7aaefd50bed002f516bad3c9060a3eaa276653dde3", + "6fd46f1b7ef71c3b8c8f804c60b1bde35d5d5248e4499f03768afb5a66a82044", + "951950e2de77a55254eb174edd71f29ba6fa91b4cea26554d715846a2d4f5700", + "7a51c0043d5bf55994991bf1c1ae0244c110fdab269e99d49b0824620c13caa5", + "5c365322c8666af9d921af583b69ef89ef0fc7fb8435d5a983077935d43b2255", + "9dead20e9b20c5ea511a3ba68bab3ecfb8b44337b9e945e18a2e8937fa7f1760", + "2d500bcc13e88ddddfebf88bbf32b9c6cfe970e07470c0c3e48f7046018c5313", + "9d4d77cd2464d5a75fd17cecd4a90df85fe9789c6cc6b4a8cc3c86dce971b138", + "89d5547fc60830a141993c1c28a12e646b7afe80148d11731a9ce21b1e767f83", + "0807b01e48c814292c8e220af6107e3489560728b339978658bcf0cee6da1d01", + "4758123810b83f9cebcfcdec34fe482c11d6fdd88cc9fa3c9c1e620a82902e57", + "1ba139e5e91332b4bb9089821a057bd58d654b86f0bd4145ac265941b2d2d499", + "1856e30e7620b566eb3eadd59be5b442a5ea71d461cbc3340e1a2ec848392fc4", + "4d8c5be4e29677f5cc4f83e3f38beda5555a34438b2d13b3bd9106f8465e9170", + "f4f0c4268414a80e71fa91defd97ed4b8bfebc46fac19bbb8c5c9776e73caeaf", + "ab7317523023c78155f0479dd0b14ae4e4a0337af0d95ccaf91b4c27e55121fd", + "ca56879de3eccbe4050eaf0104eccb3dd3014601865c89f0a8b47b5c1dd09952", + "58e40017619296ed9fa7acb2b05fe93b68aa5089e6d880c156166086f948c312", + "5b99e4540494b4d819b4f34162e186cd4b97d4f84b006091ad66c8150789753c", + "1fa1f8fee12bd71dee03c593bdf0adc7b893c7bd48c85cc02b2427a9a4005b28", + "f56507b304ffde865df23f33fe36afe023a2ad80bebe7e7caa9bd8ffe4f0dcce", + "eaa6c91743e05080ec9a27e2bd390baa8f88763795f548ad9c91680975b02420", + "75add8073228efce6b90bf3db7d84d5bf3a86482a5e3c1fd819726b12bff36b1", + "fb43f9d28bfb087100cce0edbc7249d40ab1e905fd28b486bcb2654e6a13a46c", + "530fbd69f2206a6b10fe2634abbe13357ded76c0399e26e37f12debe48c64dfb", + "5b0d41322c4ec63a880b35216f7b1628538c2dcbda428f2bd0a279e4da69f476", + "c80eec90847a52ff2810307259fa073a22965672d13549f2c335be9396fe351d", + "5beda0c0e8ed5b8d9dd4c1b4de82d9b2e93efca468ae69c38d15674824fb7bb3", + "6dda5746d800c640ce487b309a794ef482451cb3f8024ffbde538e2f03e4de74", + "3c2b9dd3d58cb6bbc27ef509617716e4b2ebe891d77b8bec60ffbcb8c1e00907", + "485e1263847a584e8adf77d2b2f32501dce1bc00530cd5d7dd8e34a6f84fb319", + "9b6db6a5196f583a277ef8e60a133a2dfe2191976396084f4907867b9fc14c19", + "b7966cb02a5b45768944714d21878c3bbde371d86f19b56ee5cb6232c780d7fb", + "79177a9da071358596424d85f8c1e9520c3a3c0d2537a80e5e9963e789b83866", + "5433fd6e5bf2a3a7967a150b685ced01f2ad8ef70665dfeb684917fc44cf500c", + "1647f72613878c82183c2dfcbf98959d2754ea89827902ff8f23705cc3ee73b5", + "33aded6b70774831df2204e33b0852bf74a460b028f91afef0494591150e9ab5", + "1c6751d1c597a3e71f825cabcf81973f59ed829c83ea5ee7d312cc24946bf69b", + "6ef7762e4f47461b74ed6279cb9378ab770a2a6a74464580f3b97d3108377b81", + "6fd7250b57fef5c9e20d685905a2405b2b4801afeaf102d2add67878d68da794", + "f93ba8c25f06da39c231e6556330f3b954b6a8b1231d228cae19a5baccafe5fd", + "b56ff389c13594acba3dbe4209a76f5eb77cfb73f458dd0234e8c0e3694b21a8", + "35c745138df93949d71cabd079d5854b66be3df757332584a0d6b8954a377931", + "8bcf9d759fba76d7b1482a2e0ba5c854a8463ea82c6e82a1cba46153ab713423", + "faba65c0df257e51cd59598febeb5f50e67da6552adf4a7b06686b875d4eaacd", + "5b5f61d51d92950591a4c7ee0eeb410e48e038fcd43d4c6e4c18ceb823ec2917", + "9dec39ee6aced9dd88cb28438143547e2d3f53165ca674b11afdc77488aae668", + "8306f661522e21e566b526d777935a1b3da410466cf7fea4ce74682e6ac78fa3", + "22b44064887a37e489373e97e1321a6e98a12278cd5e83494afd45b3e1b26906", + "528038e808770861fa9fd14b1e2d11255c43b20d571cf45c042e77eff596e5dc", + "a2e2b37d87ef12214425c630b809ae461b45f38b5125fc50e9b8b429f81915e0", + "a7e7f8a2968e959b0e1909860e83afba9f0a093b19b0622b3ed2d2deb0423a15", + "0702f0c44f4b38e7ec0249e9badffc06912e52dd7aa81c5b77f58fbc642afc9b", + "9e26beacc6d118963a5bb8722c1f74f640ac5f2ac80f7ba63d46e9e7a3be7cc2", + "af34e4e082c268329a299896a0e1271673aad74a4b79795c86ded5b0355d6407", + "ae5aaea46647fff4b55b8ee4c9cb0a075c4674aec521d393d7b0faf988cd945b", + "efbab555340ab45d03288865b42d247176b9237db196c9ccd878a6e413858735", + "5a1bf06092ef446c1fb6d3cf5cccfff2c6c5c110d8d199541fc4f5e6b4225504", + "33385d55b60aed00b6aea6bc4680fdda5fe0c94bdd864b4aec9f9b5eb1fc9c91", + "998d442ddf417aa63522ee72f4614000d752def4c28e7a84f7b40e2ef917f737", + "ad83f3b6168dc87052f534f334c1953085b774cc3d588c668427efad1400960f", + "9c7025e2bc6539adeddbede4494d93127451981772cd35e2a6e2e999b71deb18", + "2abda52a772e901b85d0551ac0ee5ee377f855cf9b5e8befa7555eb0ad507a28", + "993d7167bf21a59c66588eef6bdff4d9745787d8b5ad58ff70a27e0f0ab6d0e1", + "ae519bfdb994f836cf8620020a4bc3cef3e0eba62dd177dbd62451d38dcb9106", + "adb37fc4438829e3106d7991105953bbeca75f430be70bddb26bdff882d4bf62", + "b5efeefcdda1ee5ea5a77551317539787273d0ede2e725e08d12b06b57bc5858", + "32fb2fac06136e2451ea09ce0b19c381e882fb24dba365234b8a6e854b21a782", + "92947f43f7eb04e4840e5b563be0dc76ebff9df9f469024defbce58b5d005bf1", + "1c0f6287e2aab401dea4dd9d2dd39926b19ea9eca636aa8fb4b7631c201be274", + "5d4459af354034746d20a9e2dacb25108b469076298705526621360200e967db", + "ed98890c25fc4c4fa627a779b3256e54c8b36c1ddfa899d5f92c5fe4792e64be", + "98580dbdc55afe7df2079710ca5c197d63fa31d13f14cc105e8a34e186c8ecbd", + "2c6ffe660b4272c61177497693efa5b545ec9ccd8a3da2ac1c5b7a149f5f3acd", + "d09686d3338f8aa42d14612a7031aa9291bf85824bf3490128a164d47f3a122f", + "00e76dc03ad17cd398d6af5359c18e866720615c88453bee3e8bc6117c27b00a", + "6384ef863c5be3ca2f6df2fe78b928ede25d365123748a6d39098221767787b2", + "12693ec0035ec641930d3a22a5d9fd1f115cb7ca8b6eb177c901de664d1cffb3", + "19f00abef57cf4ec17f4bf775dc1a51df02f54594ebfe4e23510a2f75e06772e", + "6541c0c135ecb36b61fe71ce05e6e568c5ad5735d97bbec67d5afedd63cf19f2", + "728ac237d49ff21c4ef2c748e078e3358e7811a9372ad8e9cbd43f96bc554776", + "83d4517d0ee740d26dbf9085df76b6d775372937ad0c765fa61942c55ac0647d", + "9e9857dd142f7ccf7957fe75b786a02e04ca73553ed15fcb67cba9aea87a3a01", + "486e53d6f1369e8582649f93b02f9d41847afde00f1dabc3789eed90c472a18a", + "30e87f658074c2b2818a2f875a271f221bb70adbef604b31fc4c6249f4273f71", + "9d725236710a00735c437dbf61ffe77bf1d99758078d2e3a8275018f105289de", + "e9962e829664f3c13dc228af4c6b1b7d14a7e10f520e1bad78344fab1207e51e", + "6feacba5077d8b03ba38cfcb2bad9f63f62d65e82621355f18b98022e159f7fe", + "ef2f33f06872758c03331117f1301b1293a281564acca9eba4ec8d66ce43ae1c", + "ee1d75230bf50515038727b6a216751a8fe6088b1d05f35df8873c33e1dead06", + "9dc7ff07fc73e963ac88753eaea890021184cedaf355cea54d74d0738acb3a2d", + "2ab0daddaffed28c832e99f517fe47c568192e7de589c45ab2f2795ffb09a4db", + "974b175c9394a64f006dbd8556712ba9d487f69763f2f7ad4901b803d2f160d1", + "b55af680c83d88800554a44c75cd5b7679b199283a79b0de6042b4d22c2eea5a", + "0b7efef49ea7c626f8fb2191779fe1939167d740aabf7a41054527e388ac6c77", + "7e6aa464b11583b9ad658febf8416db5e47bf038143436fd692219b0697cd444", + "2c2b4623d54510490c66df07a6aa131171fa9254b3d78abb63ab0ba2b94e33e3", + "6da853edc60bcaf9e2f9b0508587495a8be90df905be7fb58bc8ea822ecbeb75", + "ecfcf4e72b4b8825b7fc85c0051cc68ed2560cadc4be26b12cc45872ef5b7844", + "5df000ebc98190f27870bfe5f99e7710e48fb1d4cb3270778504c2d2fddbdcc9", + "f5c5408039b5f2bfd0fda3e78a6897cd337d3b6335c1835f877c88c54b7f32ee", + "e8f79251aeb4d3a05b946be0a18ba3047d24b8ae695f64a80232624851d7833c", + "860e5439dbc488103b1f9c40bb6835b0261f15936e7b6be010401aeb8a4f7c72", + "fe3443b5d4e65094ae4550ba1f6df926b2cbb9792cfa102a40a298f25d0d8638", + "21961331b176e969b8d0d5237870731dd952940e900b94ba8fc07389c655bd8a", } -const ropstenPreverifiedHeight uint64 = 11975808 +const ropstenPreverifiedHeight uint64 = 12010752 From 39804f3bbef15fec834000178ae4b4c0a48e161f Mon Sep 17 00:00:00 2001 From: Enrique Jose Avila Asapche Date: Fri, 25 Feb 2022 04:42:18 +0000 Subject: [PATCH 184/261] block by timestamp for stable (#3617) --- cmd/rpcdaemon/README.md | 12 ++ cmd/rpcdaemon/commands/erigon_api.go | 1 + cmd/rpcdaemon/commands/erigon_block.go | 82 ++++++++++ cmd/rpcdaemon/commands/eth_call_test.go | 207 ++++++++++++++++++++++++ rpc/types.go | 27 ++++ 5 files changed, 329 insertions(+) diff --git a/cmd/rpcdaemon/README.md b/cmd/rpcdaemon/README.md index 8ca9d6a94e2..e81740c8998 100644 --- a/cmd/rpcdaemon/README.md +++ b/cmd/rpcdaemon/README.md @@ -264,6 +264,18 @@ The following table shows the current implementation status of Erigon's RPC daem | erigon_getLogsByHash | Yes | Erigon only | | erigon_forks | Yes | Erigon only | | erigon_issuance | Yes | Erigon only | +| erigon_GetBlockByTimestamp | Yes | Erigon only | +| | | | +| starknet_call | Yes | Starknet only | +| | | | +| bor_getSnapshot | Yes | Bor only | +| bor_getAuthor | Yes | Bor only | +| bor_getSnapshotAtHash | Yes | Bor only | +| bor_getSigners | Yes | Bor only | +| bor_getSignersAtHash | Yes | Bor only | +| bor_getCurrentProposer | Yes | Bor only | +| bor_getCurrentValidators | Yes | Bor only | +| bor_getRootHash | Yes | Bor only | This table is constantly updated. Please visit again. diff --git a/cmd/rpcdaemon/commands/erigon_api.go b/cmd/rpcdaemon/commands/erigon_api.go index e75dd66f799..00be90ad536 100644 --- a/cmd/rpcdaemon/commands/erigon_api.go +++ b/cmd/rpcdaemon/commands/erigon_api.go @@ -19,6 +19,7 @@ type ErigonAPI interface { // Blocks related (see ./erigon_blocks.go) GetHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) GetHeaderByHash(_ context.Context, hash common.Hash) (*types.Header, error) + GetBlockByTimestamp(ctx context.Context, timeStamp rpc.Timestamp, fullTx bool) (map[string]interface{}, error) // Receipt related (see ./erigon_receipts.go) GetLogsByHash(ctx context.Context, hash common.Hash) ([][]*types.Log, error) diff --git a/cmd/rpcdaemon/commands/erigon_block.go b/cmd/rpcdaemon/commands/erigon_block.go index fe9f90e0c39..d32557024e4 100644 --- a/cmd/rpcdaemon/commands/erigon_block.go +++ b/cmd/rpcdaemon/commands/erigon_block.go @@ -3,10 +3,13 @@ package commands import ( "context" "fmt" + "sort" + "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/internal/ethapi" "github.com/ledgerwatch/erigon/rpc" ) @@ -58,3 +61,82 @@ func (api *ErigonImpl) GetHeaderByHash(ctx context.Context, hash common.Hash) (* return header, nil } + +func (api *ErigonImpl) GetBlockByTimestamp(ctx context.Context, timeStamp rpc.Timestamp, fullTx bool) (map[string]interface{}, error) { + tx, err := api.db.BeginRo(ctx) + if err != nil { + return nil, err + } + defer tx.Rollback() + + uintTimestamp := timeStamp.TurnIntoUint64() + + currentHeader := rawdb.ReadCurrentHeader(tx) + currenttHeaderTime := currentHeader.Time + highestNumber := currentHeader.Number.Uint64() + + firstHeader := rawdb.ReadHeaderByNumber(tx, 0) + firstHeaderTime := firstHeader.Time + + if currenttHeaderTime <= uintTimestamp { + blockResponse, err := buildBlockResponse(tx, highestNumber, fullTx) + if err != nil { + return nil, err + } + + return blockResponse, nil + } + + if firstHeaderTime >= uintTimestamp { + blockResponse, err := buildBlockResponse(tx, 0, fullTx) + if err != nil { + return nil, err + } + + return blockResponse, nil + } + + blockNum := sort.Search(int(currentHeader.Number.Uint64()), func(blockNum int) bool { + currentHeader := rawdb.ReadHeaderByNumber(tx, uint64(blockNum)) + + return currentHeader.Time >= uintTimestamp + }) + + resultingHeader := rawdb.ReadHeaderByNumber(tx, uint64(blockNum)) + + if resultingHeader.Time > uintTimestamp { + response, err := buildBlockResponse(tx, uint64(blockNum)-1, fullTx) + if err != nil { + return nil, err + } + return response, nil + } + + response, err := buildBlockResponse(tx, uint64(blockNum), fullTx) + if err != nil { + return nil, err + } + + return response, nil +} + +func buildBlockResponse(db kv.Tx, blockNum uint64, fullTx bool) (map[string]interface{}, error) { + block, err := rawdb.ReadBlockByNumber(db, blockNum) + if err != nil { + return nil, err + } + + if block == nil { + return nil, nil + } + + response, err := ethapi.RPCMarshalBlock(block, true, fullTx) + + if err == nil && rpc.BlockNumber(block.NumberU64()) == rpc.PendingBlockNumber { + // Pending blocks need to nil out a few fields + for _, field := range []string{"hash", "nonce", "miner"} { + response[field] = nil + } + } + return response, err +} diff --git a/cmd/rpcdaemon/commands/eth_call_test.go b/cmd/rpcdaemon/commands/eth_call_test.go index aee770f8682..f3b9d8d5f66 100644 --- a/cmd/rpcdaemon/commands/eth_call_test.go +++ b/cmd/rpcdaemon/commands/eth_call_test.go @@ -8,6 +8,7 @@ import ( "github.com/ledgerwatch/erigon-lib/kv/kvcache" "github.com/ledgerwatch/erigon/cmd/rpcdaemon/rpcdaemontest" "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/internal/ethapi" "github.com/ledgerwatch/erigon/rpc" ) @@ -41,3 +42,209 @@ func TestEthCallNonCanonical(t *testing.T) { } } } + +func TestGetBlockByTimestampLatestTime(t *testing.T) { + ctx := context.Background() + db := rpcdaemontest.CreateTestKV(t) + + tx, err := db.BeginRo(ctx) + if err != nil { + t.Errorf("fail at beginning tx") + } + defer tx.Rollback() + + stateCache := kvcache.New(kvcache.DefaultCoherentConfig) + api := NewErigonAPI(NewBaseApi(nil, stateCache, false), db, nil) + + latestBlock := rawdb.ReadCurrentBlock(tx) + response, err := ethapi.RPCMarshalBlock(latestBlock, true, false) + + if err != nil { + t.Error("couldn't get the rpc marshal block") + } + + if err == nil && rpc.BlockNumber(latestBlock.NumberU64()) == rpc.PendingBlockNumber { + // Pending blocks need to nil out a few fields + for _, field := range []string{"hash", "nonce", "miner"} { + response[field] = nil + } + } + + block, err := api.GetBlockByTimestamp(ctx, rpc.Timestamp(latestBlock.Header().Time), false) + if err != nil { + t.Errorf("couldn't retrieve block %v", err) + } + + if block["timestamp"] != response["timestamp"] || block["hash"] != response["hash"] { + t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected timestamp: %d\nblock hash retrieved: %s timestamp retrieved: %d", response["hash"], response["timestamp"], block["hash"], block["timestamp"]) + } +} + +func TestGetBlockByTimestampOldestTime(t *testing.T) { + ctx := context.Background() + db := rpcdaemontest.CreateTestKV(t) + + tx, err := db.BeginRo(ctx) + if err != nil { + t.Errorf("failed at beginning tx") + } + defer tx.Rollback() + + stateCache := kvcache.New(kvcache.DefaultCoherentConfig) + api := NewErigonAPI(NewBaseApi(nil, stateCache, false), db, nil) + + oldestBlock, err := rawdb.ReadBlockByNumber(tx, 0) + if err != nil { + t.Error("couldn't retrieve oldest block") + } + + response, err := ethapi.RPCMarshalBlock(oldestBlock, true, false) + + if err != nil { + t.Error("couldn't get the rpc marshal block") + } + + if err == nil && rpc.BlockNumber(oldestBlock.NumberU64()) == rpc.PendingBlockNumber { + // Pending blocks need to nil out a few fields + for _, field := range []string{"hash", "nonce", "miner"} { + response[field] = nil + } + } + + block, err := api.GetBlockByTimestamp(ctx, rpc.Timestamp(oldestBlock.Header().Time), false) + if err != nil { + t.Errorf("couldn't retrieve block %v", err) + } + + if block["timestamp"] != response["timestamp"] || block["hash"] != response["hash"] { + t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected timestamp: %d\nblock hash retrieved: %s timestamp retrieved: %d", response["hash"], response["timestamp"], block["hash"], block["timestamp"]) + } +} + +func TestGetBlockByTimeHigherThanLatestBlock(t *testing.T) { + ctx := context.Background() + db := rpcdaemontest.CreateTestKV(t) + + tx, err := db.BeginRo(ctx) + if err != nil { + t.Errorf("fail at beginning tx") + } + defer tx.Rollback() + + stateCache := kvcache.New(kvcache.DefaultCoherentConfig) + api := NewErigonAPI(NewBaseApi(nil, stateCache, false), db, nil) + + latestBlock := rawdb.ReadCurrentBlock(tx) + + response, err := ethapi.RPCMarshalBlock(latestBlock, true, false) + + if err != nil { + t.Error("couldn't get the rpc marshal block") + } + + if err == nil && rpc.BlockNumber(latestBlock.NumberU64()) == rpc.PendingBlockNumber { + // Pending blocks need to nil out a few fields + for _, field := range []string{"hash", "nonce", "miner"} { + response[field] = nil + } + } + + block, err := api.GetBlockByTimestamp(ctx, rpc.Timestamp(latestBlock.Header().Time+999999999999), false) + if err != nil { + t.Errorf("couldn't retrieve block %v", err) + } + + if block["timestamp"] != response["timestamp"] || block["hash"] != response["hash"] { + t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected timestamp: %d\nblock hash retrieved: %s timestamp retrieved: %d", response["hash"], response["timestamp"], block["hash"], block["timestamp"]) + } +} + +func TestGetBlockByTimeMiddle(t *testing.T) { + ctx := context.Background() + db := rpcdaemontest.CreateTestKV(t) + + tx, err := db.BeginRo(ctx) + if err != nil { + t.Errorf("fail at beginning tx") + } + defer tx.Rollback() + + stateCache := kvcache.New(kvcache.DefaultCoherentConfig) + api := NewErigonAPI(NewBaseApi(nil, stateCache, false), db, nil) + + currentHeader := rawdb.ReadCurrentHeader(tx) + oldestHeader := rawdb.ReadHeaderByNumber(tx, 0) + + middleNumber := (currentHeader.Number.Uint64() + oldestHeader.Number.Uint64()) / 2 + middleBlock, err := rawdb.ReadBlockByNumber(tx, middleNumber) + if err != nil { + t.Error("couldn't retrieve middle block") + } + + response, err := ethapi.RPCMarshalBlock(middleBlock, true, false) + + if err != nil { + t.Error("couldn't get the rpc marshal block") + } + + if err == nil && rpc.BlockNumber(middleBlock.NumberU64()) == rpc.PendingBlockNumber { + // Pending blocks need to nil out a few fields + for _, field := range []string{"hash", "nonce", "miner"} { + response[field] = nil + } + } + + block, err := api.GetBlockByTimestamp(ctx, rpc.Timestamp(middleBlock.Header().Time), false) + if err != nil { + t.Errorf("couldn't retrieve block %v", err) + } + + if block["timestamp"] != response["timestamp"] || block["hash"] != response["hash"] { + t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected timestamp: %d\nblock hash retrieved: %s timestamp retrieved: %d", response["hash"], response["timestamp"], block["hash"], block["timestamp"]) + } +} + +func TestGetBlockByTimestamp(t *testing.T) { + ctx := context.Background() + db := rpcdaemontest.CreateTestKV(t) + + tx, err := db.BeginRo(ctx) + if err != nil { + t.Errorf("fail at beginning tx") + } + defer tx.Rollback() + + stateCache := kvcache.New(kvcache.DefaultCoherentConfig) + api := NewErigonAPI(NewBaseApi(nil, stateCache, false), db, nil) + + highestBlockNumber := rawdb.ReadCurrentHeader(tx).Number + pickedBlock, err := rawdb.ReadBlockByNumber(tx, highestBlockNumber.Uint64()/3) + if err != nil { + t.Errorf("couldn't get block %v", pickedBlock.Number()) + } + + if pickedBlock == nil { + t.Error("couldn't retrieve picked block") + } + response, err := ethapi.RPCMarshalBlock(pickedBlock, true, false) + + if err != nil { + t.Error("couldn't get the rpc marshal block") + } + + if err == nil && rpc.BlockNumber(pickedBlock.NumberU64()) == rpc.PendingBlockNumber { + // Pending blocks need to nil out a few fields + for _, field := range []string{"hash", "nonce", "miner"} { + response[field] = nil + } + } + + block, err := api.GetBlockByTimestamp(ctx, rpc.Timestamp(pickedBlock.Header().Time), false) + if err != nil { + t.Errorf("couldn't retrieve block %v", err) + } + + if block["timestamp"] != response["timestamp"] || block["hash"] != response["hash"] { + t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected timestamp: %d\nblock hash retrieved: %s timestamp retrieved: %d", response["hash"], response["timestamp"], block["hash"], block["timestamp"]) + } +} diff --git a/rpc/types.go b/rpc/types.go index 19072e79358..03cbfbd42b6 100644 --- a/rpc/types.go +++ b/rpc/types.go @@ -68,6 +68,7 @@ type jsonWriter interface { } type BlockNumber int64 +type Timestamp uint64 const ( PendingBlockNumber = BlockNumber(-2) @@ -240,3 +241,29 @@ func (dh *DecimalOrHex) UnmarshalJSON(data []byte) error { *dh = DecimalOrHex(value) return nil } + +func (ts Timestamp) TurnIntoUint64() uint64 { + return uint64(ts) +} + +func (ts *Timestamp) UnmarshalJSON(data []byte) error { + input := strings.TrimSpace(string(data)) + if len(input) >= 2 && input[0] == '"' && input[len(input)-1] == '"' { + input = input[1 : len(input)-1] + } + + // parse string to uint64 + timestamp, err := strconv.ParseUint(input, 10, 64) + if err != nil { + + // try hex number + if timestamp, err = hexutil.DecodeUint64(input); err != nil { + return err + } + + } + + *ts = Timestamp(timestamp) + return nil + +} From 9b593bf54066523cff47ff4eb9270e402ea3063d Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Fri, 25 Feb 2022 14:44:35 +0700 Subject: [PATCH 185/261] Add timings of forward stages to logs (#3621) * save * save --- eth/stagedsync/sync.go | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/eth/stagedsync/sync.go b/eth/stagedsync/sync.go index 44b5c621172..dffcbf6f314 100644 --- a/eth/stagedsync/sync.go +++ b/eth/stagedsync/sync.go @@ -317,16 +317,17 @@ func (s *Sync) runStage(stage *Stage, db kv.RwDB, tx kv.RwTx, firstCycle bool, b return fmt.Errorf("[%s] %w", s.LogPrefix(), err) } - t := time.Since(start) - if t > 60*time.Second { + took := time.Since(start) + if took > 60*time.Second { logPrefix := s.LogPrefix() - log.Info(fmt.Sprintf("[%s] DONE", logPrefix), "in", t) + log.Info(fmt.Sprintf("[%s] DONE", logPrefix), "in", took) } + s.timings = append(s.timings, Timing{stage: stage.ID, took: took}) return nil } func (s *Sync) unwindStage(firstCycle bool, stage *Stage, db kv.RwDB, tx kv.RwTx) error { - t := time.Now() + start := time.Now() log.Trace("Unwind...", "stage", stage.ID) stageState, err := s.StageState(stage.ID, tx, db) if err != nil { @@ -349,17 +350,17 @@ func (s *Sync) unwindStage(firstCycle bool, stage *Stage, db kv.RwDB, tx kv.RwTx return fmt.Errorf("[%s] %w", s.LogPrefix(), err) } - took := time.Since(t) + took := time.Since(start) if took > 60*time.Second { logPrefix := s.LogPrefix() log.Info(fmt.Sprintf("[%s] Unwind done", logPrefix), "in", took) } - s.timings = append(s.timings, Timing{isUnwind: true, stage: stage.ID, took: time.Since(t)}) + s.timings = append(s.timings, Timing{isUnwind: true, stage: stage.ID, took: took}) return nil } func (s *Sync) pruneStage(firstCycle bool, stage *Stage, db kv.RwDB, tx kv.RwTx) error { - t := time.Now() + start := time.Now() log.Trace("Prune...", "stage", stage.ID) stageState, err := s.StageState(stage.ID, tx, db) @@ -380,12 +381,12 @@ func (s *Sync) pruneStage(firstCycle bool, stage *Stage, db kv.RwDB, tx kv.RwTx) return fmt.Errorf("[%s] %w", s.LogPrefix(), err) } - took := time.Since(t) + took := time.Since(start) if took > 60*time.Second { logPrefix := s.LogPrefix() - log.Info(fmt.Sprintf("[%s] Prune done", logPrefix), "in", t) + log.Info(fmt.Sprintf("[%s] Prune done", logPrefix), "in", took) } - s.timings = append(s.timings, Timing{isPrune: true, stage: stage.ID, took: time.Since(t)}) + s.timings = append(s.timings, Timing{isPrune: true, stage: stage.ID, took: took}) return nil } From 77d2779e1d64c58e046022a13c6fe351de85103c Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Fri, 25 Feb 2022 15:02:57 -0300 Subject: [PATCH 186/261] Fix due to change in rpchelper.GetBlockNumber return value signature; additional latest block flag which is ignored for our purposes --- cmd/rpcdaemon/commands/otterscan_api.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 1f1c5be6b31..1a85e2aedd9 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -479,7 +479,7 @@ func (api *OtterscanAPIImpl) HasCode(ctx context.Context, address common.Address } defer tx.Rollback() - blockNumber, _, err := rpchelper.GetBlockNumber(blockNrOrHash, tx, api.filters) + blockNumber, _, _, err := rpchelper.GetBlockNumber(blockNrOrHash, tx, api.filters) if err != nil { return false, err } From f35b9b255b02170ce9183385a2aede83c91a6ee4 Mon Sep 17 00:00:00 2001 From: Enrique Jose Avila Asapche Date: Sat, 26 Feb 2022 07:27:11 +0000 Subject: [PATCH 187/261] deleted bor and starknet from doc (#3627) --- cmd/rpcdaemon/README.md | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/cmd/rpcdaemon/README.md b/cmd/rpcdaemon/README.md index e81740c8998..4d6d6dc47c6 100644 --- a/cmd/rpcdaemon/README.md +++ b/cmd/rpcdaemon/README.md @@ -265,17 +265,8 @@ The following table shows the current implementation status of Erigon's RPC daem | erigon_forks | Yes | Erigon only | | erigon_issuance | Yes | Erigon only | | erigon_GetBlockByTimestamp | Yes | Erigon only | -| | | | -| starknet_call | Yes | Starknet only | -| | | | -| bor_getSnapshot | Yes | Bor only | -| bor_getAuthor | Yes | Bor only | -| bor_getSnapshotAtHash | Yes | Bor only | -| bor_getSigners | Yes | Bor only | -| bor_getSignersAtHash | Yes | Bor only | -| bor_getCurrentProposer | Yes | Bor only | -| bor_getCurrentValidators | Yes | Bor only | -| bor_getRootHash | Yes | Bor only | + + This table is constantly updated. Please visit again. From 5c0e683c97047f86b631837cbddaaaa282ee927b Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Mon, 7 Mar 2022 21:25:58 +0700 Subject: [PATCH 188/261] add nosqlite tag (#3653) * add nosqlite tag * save --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 580436eaf88..821fbf2989e 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ GO = go GOBIN = $(CURDIR)/build/bin -GOTEST = GODEBUG=cgocheck=0 $(GO) test ./... -p 2 +GOTEST = GODEBUG=cgocheck=0 $(GO) test -tags nosqlite -trimpath ./... -p 2 GIT_COMMIT ?= $(shell git rev-list -1 HEAD) GIT_BRANCH ?= $(shell git rev-parse --abbrev-ref HEAD) @@ -11,8 +11,8 @@ CGO_CFLAGS += -DMDBX_FORCE_ASSERTIONS=0 # Enable MDBX's asserts by default in 'd CGO_CFLAGS := CGO_CFLAGS="$(CGO_CFLAGS)" DBG_CGO_CFLAGS += -DMDBX_DEBUG=1 -GOBUILD = $(CGO_CFLAGS) $(GO) build -trimpath -ldflags "-X github.com/ledgerwatch/erigon/params.GitCommit=${GIT_COMMIT} -X github.com/ledgerwatch/erigon/params.GitBranch=${GIT_BRANCH} -X github.com/ledgerwatch/erigon/params.GitTag=${GIT_TAG}" -GO_DBG_BUILD = $(DBG_CGO_CFLAGS) $(GO) build -trimpath -tags=debug -ldflags "-X github.com/ledgerwatch/erigon/params.GitCommit=${GIT_COMMIT} -X github.com/ledgerwatch/erigon/params.GitBranch=${GIT_BRANCH} -X github.com/ledgerwatch/erigon/params.GitTag=${GIT_TAG}" -gcflags=all="-N -l" # see delve docs +GOBUILD = $(CGO_CFLAGS) $(GO) build -tags nosqlite -trimpath -ldflags "-X github.com/ledgerwatch/erigon/params.GitCommit=${GIT_COMMIT} -X github.com/ledgerwatch/erigon/params.GitBranch=${GIT_BRANCH} -X github.com/ledgerwatch/erigon/params.GitTag=${GIT_TAG}" +GO_DBG_BUILD = $(DBG_CGO_CFLAGS) $(GO) build -tags nosqlite -trimpath -tags=debug -ldflags "-X github.com/ledgerwatch/erigon/params.GitCommit=${GIT_COMMIT} -X github.com/ledgerwatch/erigon/params.GitBranch=${GIT_BRANCH} -X github.com/ledgerwatch/erigon/params.GitTag=${GIT_TAG}" -gcflags=all="-N -l" # see delve docs GO_MAJOR_VERSION = $(shell $(GO) version | cut -c 14- | cut -d' ' -f1 | cut -d'.' -f1) GO_MINOR_VERSION = $(shell $(GO) version | cut -c 14- | cut -d' ' -f1 | cut -d'.' -f2) From bde975fea01455a86baad0142ecaf8ccf7399800 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Thu, 10 Mar 2022 00:29:30 +0700 Subject: [PATCH 189/261] save (#3665) --- cmd/utils/flags.go | 1 - 1 file changed, 1 deletion(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index e58ec46ae0c..ecb063d6f5c 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -1219,7 +1219,6 @@ func CheckExclusive(ctx *cli.Context, args ...interface{}) { // SetEthConfig applies eth-related command line flags to the config. func SetEthConfig(ctx *cli.Context, nodeConfig *node.Config, cfg *ethconfig.Config) { - CheckExclusive(ctx, MinerSigningKeyFileFlag, MinerEtherbaseFlag) setEtherbase(ctx, cfg) setGPO(ctx, &cfg.GPO) setTxPool(ctx, &cfg.TxPool) From 86680c56d8eaf6168774aa1062264b5152667264 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Thu, 10 Mar 2022 01:41:15 +0700 Subject: [PATCH 190/261] save (#3663) --- internal/debug/flags.go | 1 + metrics/exp/exp.go | 1 + 2 files changed, 2 insertions(+) diff --git a/internal/debug/flags.go b/internal/debug/flags.go index 9c659b81baa..84ce9611fa2 100644 --- a/internal/debug/flags.go +++ b/internal/debug/flags.go @@ -274,6 +274,7 @@ func StartPProf(address string, withMetrics bool) { // from the registry into expvar, and execute regular expvar handler. if withMetrics { http.HandleFunc("/debug/metrics/prometheus", func(w http.ResponseWriter, req *http.Request) { + w.Header().Set("Access-Control-Allow-Origin", "*") metrics2.WritePrometheus(w, true) }) } diff --git a/metrics/exp/exp.go b/metrics/exp/exp.go index c894dd6ae05..f06905c1f61 100644 --- a/metrics/exp/exp.go +++ b/metrics/exp/exp.go @@ -46,6 +46,7 @@ func ExpHandler(r metrics.Registry) http.Handler { // This function enables metrics reporting separate from pprof. func Setup(address string) { http.HandleFunc("/debug/metrics/prometheus", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Access-Control-Allow-Origin", "*") metrics2.WritePrometheus(w, true) }) //m.Handle("/debug/metrics", ExpHandler(metrics.DefaultRegistry)) From 6fd8f98a09ccfc45f427d06fc3b3b2b8c8154ebc Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Thu, 10 Mar 2022 20:20:38 +0700 Subject: [PATCH 191/261] linter up (#3672) (#3673) * linter up (#3672) * save * save --- .github/workflows/ci.yml | 5 ++--- Makefile | 2 +- p2p/discover/v4_udp_test.go | 4 ++-- p2p/discover/v5_udp_test.go | 4 ++-- p2p/simulations/adapters/exec.go | 2 +- 5 files changed, 8 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4b4dd3dda02..f90a887fedd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,10 +42,9 @@ jobs: fi - name: Lint if: matrix.os == 'ubuntu-20.04' - uses: golangci/golangci-lint-action@v2 + uses: golangci/golangci-lint-action@v3 with: - version: v1.42 - skip-go-installation: true + version: v1.44 skip-pkg-cache: true skip-build-cache: true - run: make test diff --git a/Makefile b/Makefile index 821fbf2989e..b45d9324806 100644 --- a/Makefile +++ b/Makefile @@ -144,7 +144,7 @@ lintci: lintci-deps: rm -f ./build/bin/golangci-lint - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b ./build/bin v1.42.1 + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b ./build/bin v1.44.2 clean: env GO111MODULE=on go clean -cache diff --git a/p2p/discover/v4_udp_test.go b/p2p/discover/v4_udp_test.go index 834608e5e2b..fe98680bce2 100644 --- a/p2p/discover/v4_udp_test.go +++ b/p2p/discover/v4_udp_test.go @@ -102,7 +102,7 @@ func (test *udpTest) packetInFrom(wantError error, key *ecdsa.PrivateKey, addr * enc, _, err := v4wire.Encode(key, data) if err != nil { - test.t.Errorf("%s encode error: %w", data.Name(), err) + test.t.Errorf("%s encode error: %s", data.Name(), err) } test.sent = append(test.sent, enc) if err = test.udp.handlePacket(addr, enc); err != wantError { @@ -124,7 +124,7 @@ func (test *udpTest) waitPacketOut(validate interface{}) (closed bool) { } p, _, hash, err := v4wire.Decode(dgram.data) if err != nil { - test.t.Errorf("sent packet decode error: %w", err) + test.t.Errorf("sent packet decode error: %s", err) return false } fn := reflect.ValueOf(validate) diff --git a/p2p/discover/v5_udp_test.go b/p2p/discover/v5_udp_test.go index 5d132e6fe20..c9fd6ea37d1 100644 --- a/p2p/discover/v5_udp_test.go +++ b/p2p/discover/v5_udp_test.go @@ -755,7 +755,7 @@ func (test *udpV5Test) packetInFrom(key *ecdsa.PrivateKey, addr *net.UDPAddr, pa codec := &testCodec{test: test, id: ln.ID()} enc, _, err := codec.Encode(test.udp.Self().ID(), addr.String(), packet, nil) if err != nil { - test.t.Errorf("%s encode error: %w", packet.Name(), err) + test.t.Errorf("%s encode error: %s", packet.Name(), err) } if test.udp.dispatchReadPacket(addr, enc) { <-test.udp.readNextCh // unblock UDPv5.dispatch @@ -807,7 +807,7 @@ func (test *udpV5Test) waitPacketOut(validate interface{}) (closed bool) { codec := &testCodec{test: test, id: ln.ID()} frame, p, err := codec.decodeFrame(dgram.data) if err != nil { - test.t.Errorf("sent packet decode error: %w", err) + test.t.Errorf("sent packet decode error: %s", err) return false } if !reflect.TypeOf(p).AssignableTo(exptype) { diff --git a/p2p/simulations/adapters/exec.go b/p2p/simulations/adapters/exec.go index 5b09d2b446c..76753f97202 100644 --- a/p2p/simulations/adapters/exec.go +++ b/p2p/simulations/adapters/exec.go @@ -182,7 +182,7 @@ func (n *ExecNode) Start(snapshots map[string][]byte) error { for id, node := range n.adapter.nodes { confCopy.PeerAddrs[id.String()] = node.wsAddr } - confData, confDataErr := json.Marshal(confCopy) + confData, confDataErr := json.Marshal(confCopy) //nolint if confDataErr != nil { return fmt.Errorf("error generating node config: %s", confDataErr) } From a52e53a30f7ea4510fae6a0f2775a7bf421fb0a4 Mon Sep 17 00:00:00 2001 From: battlmonstr Date: Thu, 10 Mar 2022 15:03:15 +0100 Subject: [PATCH 192/261] Revert node DB cache (#3581) (#3674) (#3675) Revert "Prevent frequent commits to the node DB in sentries (#2505)". This reverts commit 65a9a265c2049b22f9fe78f0f93715ed00a33014. --- p2p/enode/nodedb.go | 256 +++++++------------------------------------- 1 file changed, 38 insertions(+), 218 deletions(-) diff --git a/p2p/enode/nodedb.go b/p2p/enode/nodedb.go index fb4c088f0fb..621159c6da1 100644 --- a/p2p/enode/nodedb.go +++ b/p2p/enode/nodedb.go @@ -29,7 +29,6 @@ import ( "time" "github.com/c2h5oh/datasize" - "github.com/google/btree" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv/mdbx" @@ -74,23 +73,9 @@ var zeroIP = make(net.IP, 16) // DB is the node database, storing previously seen nodes and any collected metadata about // them for QoS purposes. type DB struct { - kvCache *btree.BTree - kvCacheLock sync.RWMutex - path string // Remember path for log messages - kv kv.RwDB // Interface to the database itself - runner sync.Once // Ensures we can start at most one expirer - quit chan struct{} // Channel to signal the expiring thread to stop -} - -// DbItem is type of items stored in the kvCache's btrees -type DbItem struct { - key []byte - val []byte -} - -func (di *DbItem) Less(than btree.Item) bool { - i := than.(*DbItem) - return bytes.Compare(di.key, i.key) < 0 + kv kv.RwDB // Interface to the database itself + runner sync.Once // Ensures we can start at most one expirer + quit chan struct{} // Channel to signal the expiring thread to stop } // OpenDB opens a node database for storing and retrieving infos about known peers in the @@ -117,7 +102,6 @@ func newMemoryDB(logger log.Logger) (*DB, error) { if err != nil { return nil, err } - db.kvCache = btree.New(32) return db, nil } @@ -162,7 +146,7 @@ func newPersistentDB(logger log.Logger, path string) (*DB, error) { } return newPersistentDB(logger, path) } - return &DB{path: path, kvCache: btree.New(32), kv: db, quit: make(chan struct{})}, nil + return &DB{kv: db, quit: make(chan struct{})}, nil } // nodeKey returns the database key for a node record. @@ -229,54 +213,9 @@ func localItemKey(id ID, field string) []byte { return key } -func (db *DB) getFromCache(key []byte) []byte { - db.kvCacheLock.RLock() - defer db.kvCacheLock.RUnlock() - i := db.kvCache.Get(&DbItem{key: key}) - if i != nil { - di := i.(*DbItem) - return di.val - } - return nil -} - -func (db *DB) setToCache(key, val []byte) { - db.kvCacheLock.Lock() - defer db.kvCacheLock.Unlock() - db.kvCache.ReplaceOrInsert(&DbItem{key: key, val: val}) - if db.kvCache.Len() > 16*1024 { - db.commitCache(false /* logit */) - } -} - -func (db *DB) searchCache(key []byte) (foundKey, foundVal, nextKey []byte) { - if key == nil { - return nil, nil, nil - } - db.kvCacheLock.RLock() - defer db.kvCacheLock.RUnlock() - db.kvCache.AscendGreaterOrEqual(&DbItem{key: key}, func(i btree.Item) bool { - di := i.(*DbItem) - if foundKey == nil { - foundKey = di.key - foundVal = di.val - return true - } - nextKey = di.key - return false - }) - return -} - // fetchInt64 retrieves an integer associated with a particular key. func (db *DB) fetchInt64(key []byte) int64 { var val int64 - if blob := db.getFromCache(key); blob != nil { - if v, read := binary.Varint(blob); read > 0 { - return v - } - return 0 - } if err := db.kv.View(context.Background(), func(tx kv.Tx) error { blob, errGet := tx.GetOne(kv.Inodes, key) if errGet != nil { @@ -299,17 +238,14 @@ func (db *DB) fetchInt64(key []byte) int64 { func (db *DB) storeInt64(key []byte, n int64) error { blob := make([]byte, binary.MaxVarintLen64) blob = blob[:binary.PutVarint(blob, n)] - db.setToCache(common.CopyBytes(key), blob) - return nil + return db.kv.Update(context.Background(), func(tx kv.RwTx) error { + return tx.Put(kv.Inodes, common.CopyBytes(key), blob) + }) } // fetchUint64 retrieves an integer associated with a particular key. func (db *DB) fetchUint64(key []byte) uint64 { var val uint64 - if blob := db.getFromCache(key); blob != nil { - val, _ = binary.Uvarint(blob) - return val - } if err := db.kv.View(context.Background(), func(tx kv.Tx) error { blob, errGet := tx.GetOne(kv.Inodes, key) if errGet != nil { @@ -329,28 +265,26 @@ func (db *DB) fetchUint64(key []byte) uint64 { func (db *DB) storeUint64(key []byte, n uint64) error { blob := make([]byte, binary.MaxVarintLen64) blob = blob[:binary.PutUvarint(blob, n)] - db.setToCache(common.CopyBytes(key), blob) - return nil + return db.kv.Update(context.Background(), func(tx kv.RwTx) error { + return tx.Put(kv.Inodes, common.CopyBytes(key), blob) + }) } // Node retrieves a node with a given id from the database. func (db *DB) Node(id ID) *Node { var blob []byte - blob = db.getFromCache(nodeKey(id)) - if blob == nil { - if err := db.kv.View(context.Background(), func(tx kv.Tx) error { - v, errGet := tx.GetOne(kv.Inodes, nodeKey(id)) - if errGet != nil { - return errGet - } - if v != nil { - blob = make([]byte, len(v)) - copy(blob, v) - } - return nil - }); err != nil { - return nil + if err := db.kv.View(context.Background(), func(tx kv.Tx) error { + v, errGet := tx.GetOne(kv.Inodes, nodeKey(id)) + if errGet != nil { + return errGet } + if v != nil { + blob = make([]byte, len(v)) + copy(blob, v) + } + return nil + }); err != nil { + return nil } if blob == nil { return nil @@ -377,7 +311,11 @@ func (db *DB) UpdateNode(node *Node) error { if err != nil { return err } - db.setToCache(nodeKey(node.ID()), blob) + if err := db.kv.Update(context.Background(), func(tx kv.RwTx) error { + return tx.Put(kv.Inodes, nodeKey(node.ID()), blob) + }); err != nil { + return err + } return db.storeUint64(nodeItemKey(node.ID(), zeroIP, dbNodeSeq), node.Seq()) } @@ -397,24 +335,12 @@ func (db *DB) Resolve(n *Node) *Node { // DeleteNode deletes all information associated with a node. func (db *DB) DeleteNode(id ID) { - deleteRange(db, nodeKey(id)) + deleteRange(db.kv, nodeKey(id)) } -func deleteRange(db *DB, prefix []byte) { - db.kvCacheLock.Lock() - defer db.kvCacheLock.Unlock() - // First delete relevant entries from the cache - db.kvCache.AscendGreaterOrEqual(&DbItem{key: prefix}, func(i btree.Item) bool { - di := i.(*DbItem) - if !bytes.HasPrefix(di.key, prefix) { - return false - } - di.val = nil // Mark for deletion - return true - }) - // Now mark all other entries for deletion - if err := db.kv.View(context.Background(), func(tx kv.Tx) error { - c, err := tx.Cursor(kv.Inodes) +func deleteRange(db kv.RwDB, prefix []byte) { + if err := db.Update(context.Background(), func(tx kv.RwTx) error { + c, err := tx.RwCursor(kv.Inodes) if err != nil { return err } @@ -422,9 +348,8 @@ func deleteRange(db *DB, prefix []byte) { if err != nil { return err } - if f := db.kvCache.Get(&DbItem{key: k}); f == nil { - // Only copy key if item is missing in the cache - db.kvCache.ReplaceOrInsert(&DbItem{key: common.CopyBytes(k), val: nil}) + if err := c.Delete(k, nil); err != nil { + return nil } } return nil @@ -477,8 +402,7 @@ func (db *DB) expireNodes() { p := []byte(dbNodePrefix) var prevId ID var empty = true - ci := cachedIter{c: c, db: db} - for k, v, err := ci.Seek(p); bytes.HasPrefix(k, p); k, v, err = ci.Next() { + for k, v, err := c.Seek(p); bytes.HasPrefix(k, p); k, v, err = c.Next() { if err != nil { return err } @@ -513,7 +437,7 @@ func (db *DB) expireNodes() { log.Warn("nodeDB.expireNodes failed", "err", err) } for _, td := range toDelete { - deleteRange(db, td) + deleteRange(db.kv, td) } } @@ -594,72 +518,6 @@ func (db *DB) storeLocalSeq(id ID, n uint64) { db.storeUint64(localItemKey(id, dbLocalSeq), n) } -type cachedIter struct { - c kv.Cursor - db *DB - cKey, cVal []byte - cacheKey, cacheVal, cacheNextKey []byte -} - -func (ci *cachedIter) Seek(searchKey []byte) (k, v []byte, err error) { - ci.cKey, ci.cVal, err = ci.c.Seek(searchKey) - if err != nil { - return nil, nil, err - } - ci.cacheKey, ci.cacheVal, ci.cacheNextKey = ci.db.searchCache(searchKey) - return ci.Next() -} - -func (ci *cachedIter) Next() (k, v []byte, err error) { - for { - if ci.cKey == nil && ci.cacheKey == nil { - k = nil - v = nil - return - } - if ci.cKey == nil { - k = ci.cacheKey - v = ci.cacheVal - ci.cacheKey, ci.cacheVal, ci.cacheNextKey = ci.db.searchCache(ci.cacheNextKey) - if v != nil { - // if v == nil, it is deleted entry and we try the next record - return - } - continue - } - if ci.cacheKey == nil { - k = ci.cKey - v = ci.cVal - ci.cKey, ci.cVal, err = ci.c.Next() - return - } - switch bytes.Compare(ci.cKey, ci.cacheKey) { - case -1: - k = ci.cKey - v = ci.cVal - ci.cKey, ci.cVal, err = ci.c.Next() - return - case 0: - k = ci.cacheKey - v = ci.cacheVal - ci.cacheKey, ci.cacheVal, ci.cacheNextKey = ci.db.searchCache(ci.cacheNextKey) - ci.cKey, ci.cVal, err = ci.c.Next() - if v != nil { - // if v == nil, it is deleted entry and we try the next record - return - } - case 1: - k = ci.cacheKey - v = ci.cacheVal - ci.cacheKey, ci.cacheVal, ci.cacheNextKey = ci.db.searchCache(ci.cacheNextKey) - if v != nil { - // if v == nil, it is deleted entry and we try the next record - return - } - } - } -} - // QuerySeeds retrieves random nodes to be used as potential seed nodes // for bootstrapping. func (db *DB) QuerySeeds(n int, maxAge time.Duration) []*Node { @@ -674,7 +532,6 @@ func (db *DB) QuerySeeds(n int, maxAge time.Duration) []*Node { if err != nil { return err } - ci := &cachedIter{db: db, c: c} seek: for seeks := 0; len(nodes) < n && seeks < n*5; seeks++ { // Seek to a random entry. The first byte is incremented by a @@ -684,7 +541,7 @@ func (db *DB) QuerySeeds(n int, maxAge time.Duration) []*Node { rand.Read(id[:]) id[0] = ctr + id[0]%16 var n *Node - for k, v, err := ci.Seek(nodeKey(id)); k != nil && n == nil; k, v, err = ci.Next() { + for k, v, err := c.Seek(nodeKey(id)); k != nil && n == nil; k, v, err = c.Next() { if err != nil { return err } @@ -700,12 +557,9 @@ func (db *DB) QuerySeeds(n int, maxAge time.Duration) []*Node { db.ensureExpirer() pongKey := nodeItemKey(n.ID(), n.IP(), dbNodePong) var lastPongReceived int64 - blob := db.getFromCache(pongKey) - if blob == nil { - var errGet error - if blob, errGet = tx.GetOne(kv.Inodes, pongKey); errGet != nil { - return errGet - } + blob, errGet := tx.GetOne(kv.Inodes, pongKey) + if errGet != nil { + return errGet } if blob != nil { if v, read := binary.Varint(blob); read > 0 { @@ -729,37 +583,6 @@ func (db *DB) QuerySeeds(n int, maxAge time.Duration) []*Node { return nodes } -func (db *DB) commitCache(logit bool) { - entriesUpdated := 0 - entriesDeleted := 0 - if err := db.kv.Update(context.Background(), func(tx kv.RwTx) error { - var err error - db.kvCache.Ascend(func(i btree.Item) bool { - di := i.(*DbItem) - if di.val == nil { - if err = tx.Delete(kv.Inodes, di.key, nil); err != nil { - return false - } - entriesUpdated++ - } else { - if err = tx.Put(kv.Inodes, di.key, di.val); err != nil { - return false - } - entriesDeleted++ - } - return true - }) - return err - }); err != nil { - log.Warn("p2p node database update failed", "path", db.path, "err", err) - } else { - if logit { - log.Info("Successfully update p2p node database", "path", db.path, "updated", entriesUpdated, "deleted", entriesDeleted) - } - db.kvCache.Clear(true) - } -} - // close flushes and closes the database files. func (db *DB) Close() { select { @@ -771,8 +594,5 @@ func (db *DB) Close() { return } close(db.quit) - db.kvCacheLock.Lock() - defer db.kvCacheLock.Unlock() - db.commitCache(true /* logit */) db.kv.Close() } From 461ac47157825d91c01bde643674bbdb00972b53 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Mon, 14 Mar 2022 16:24:59 +0000 Subject: [PATCH 193/261] [stable] Fixes to discovery nodedb (#3691) * Update to erigon-lib stable * Discovery: throttle node DB commits (#3581) (#3656) UpdateFindFails/UpdateLastPingReceived/UpdateLastPongReceived events are causing bursty DB commits (100 per minute). This optimization throttles the disk writes to happen at most once in a few seconds, because this info doesn't need to be persisted immediately. This helps on HDD drives. * Update erigon-lib * Discovery: split node records to a sepatate DB table (#3581) (#3667) Problem: QuerySeeds will poke 150 random entries in the whole node DB and ignore hitting "field" entries. In a bootstrap scenario it might hit hundreds of :lastping :lastpong entries, and very few true "node record" entries. After running for 15 minutes I've got totalEntryCount=1508 nodeRecordCount=114 entries. There's a 1/16 chance of hitting a "node record" entry. It means finding just about 10 nodes of 114 total on average from 150 attempts. Solution: Split "node record" entries to a separate table such that QuerySeeds doesn't do idle cycle hits. * Discovery: add Context to Listen. (#3577) Add explicit Context to ListenV4 and ListenV5. This makes it possible to stop listening by an external signal. * Discovery: refactor public key to node ID conversions. (#3634) Encode and hash logic was duplicated in multiple places. * Move encoding to p2p/discover/v4wire * Move hashing to p2p/enode/idscheme * Change newRandomLookup to create a proper random key on a curve. * Discovery: speed up lookup tests (#3677) * Update erigon-lib Co-authored-by: Alexey Sharp Co-authored-by: battlmonstr --- cmd/bootnode/main.go | 9 ++- cmd/sentry/download/sentry.go | 4 +- go.mod | 6 +- go.sum | 11 ++-- p2p/discover/common.go | 5 +- p2p/discover/lookup.go | 14 +++++ p2p/discover/node.go | 33 ----------- p2p/discover/table.go | 1 + p2p/discover/table_util_test.go | 2 +- p2p/discover/v4_lookup_test.go | 18 +++--- p2p/discover/v4_udp.go | 30 +++++----- p2p/discover/v4_udp_test.go | 97 ++++++++++++++------------------- p2p/discover/v4wire/v4wire.go | 10 +--- p2p/discover/v5_udp.go | 8 +-- p2p/discover/v5_udp_test.go | 15 +++-- p2p/enode/idscheme.go | 20 +++++-- p2p/enode/nodedb.go | 51 +++++++++++------ p2p/enode/urlv4.go | 9 --- p2p/server.go | 13 +++-- p2p/server_test.go | 19 ++++--- 20 files changed, 188 insertions(+), 187 deletions(-) diff --git a/cmd/bootnode/main.go b/cmd/bootnode/main.go index 986b8939a12..c94a511bc76 100644 --- a/cmd/bootnode/main.go +++ b/cmd/bootnode/main.go @@ -21,6 +21,7 @@ import ( "crypto/ecdsa" "flag" "fmt" + "github.com/ledgerwatch/erigon-lib/common" "net" "os" @@ -129,12 +130,16 @@ func main() { PrivateKey: nodeKey, NetRestrict: restrictList, } + + ctx, cancel := common.RootContext() + defer cancel() + if *runv5 { - if _, err := discover.ListenV5(conn, ln, cfg); err != nil { + if _, err := discover.ListenV5(ctx, conn, ln, cfg); err != nil { utils.Fatalf("%v", err) } } else { - if _, err := discover.ListenUDP(conn, ln, cfg); err != nil { + if _, err := discover.ListenUDP(ctx, conn, ln, cfg); err != nil { utils.Fatalf("%v", err) } } diff --git a/cmd/sentry/download/sentry.go b/cmd/sentry/download/sentry.go index ac964d965a3..43a63f59204 100644 --- a/cmd/sentry/download/sentry.go +++ b/cmd/sentry/download/sentry.go @@ -852,7 +852,7 @@ func (ss *SentryServerImpl) HandShake(context.Context, *emptypb.Empty) (*proto_s return reply, nil } -func (ss *SentryServerImpl) SetStatus(_ context.Context, statusData *proto_sentry.StatusData) (*proto_sentry.SetStatusReply, error) { +func (ss *SentryServerImpl) SetStatus(ctx context.Context, statusData *proto_sentry.StatusData) (*proto_sentry.SetStatusReply, error) { genesisHash := gointerfaces.ConvertH256ToHash(statusData.ForkData.Genesis) ss.lock.Lock() @@ -879,7 +879,7 @@ func (ss *SentryServerImpl) SetStatus(_ context.Context, statusData *proto_sentr } // Add protocol - if err = srv.Start(); err != nil { + if err = srv.Start(ctx); err != nil { srv.Stop() return reply, fmt.Errorf("could not start server: %w", err) } diff --git a/go.mod b/go.mod index 9721438ac6c..236e5a917d0 100644 --- a/go.mod +++ b/go.mod @@ -35,8 +35,8 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20220224065624-2b634b692f2b - github.com/ledgerwatch/log/v3 v3.4.0 + github.com/ledgerwatch/erigon-lib v0.0.0-20220314143349-5c8ca0878ba4 + github.com/ledgerwatch/log/v3 v3.4.1 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 github.com/pelletier/go-toml v1.9.4 @@ -46,7 +46,7 @@ require ( github.com/spf13/cobra v1.2.1 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.7.1-0.20210427113832-6241f9ab9942 - github.com/torquem-ch/mdbx-go v0.22.10 + github.com/torquem-ch/mdbx-go v0.22.16 github.com/ugorji/go/codec v1.1.13 github.com/ugorji/go/codec/codecgen v1.1.13 github.com/urfave/cli v1.22.5 diff --git a/go.sum b/go.sum index e809b214d4b..7492b28ba09 100644 --- a/go.sum +++ b/go.sum @@ -493,10 +493,11 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20220224065624-2b634b692f2b h1:vlh0dSuZRVUF3KXBMWI6acvusKxWCSjZldggtGcSleA= -github.com/ledgerwatch/erigon-lib v0.0.0-20220224065624-2b634b692f2b/go.mod h1:BQNYmN6i8RdHqedsztAj3XDnswYebacmFAnsznlisTc= -github.com/ledgerwatch/log/v3 v3.4.0 h1:SEIOcv5a2zkG3PmoT5jeTU9m/0nEUv0BJS5bzsjwKCI= +github.com/ledgerwatch/erigon-lib v0.0.0-20220314143349-5c8ca0878ba4 h1:wivpdSUiMW/EZw8FoEC2lZTip7bg6MWOd3NCAqQPy6w= +github.com/ledgerwatch/erigon-lib v0.0.0-20220314143349-5c8ca0878ba4/go.mod h1:T1qFKmOyjrE1Uu2iImEsnQQDs7xBbQX/zwtrdfVOkWA= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= +github.com/ledgerwatch/log/v3 v3.4.1 h1:/xGwlVulXnsO9Uq+tzaExc8OWmXXHU0dnLalpbnY5Bc= +github.com/ledgerwatch/log/v3 v3.4.1/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= github.com/ledgerwatch/secp256k1 v1.0.0/go.mod h1:SPmqJFciiF/Q0mPt2jVs2dTr/1TZBTIA+kPMmKgBAak= github.com/logrusorgru/aurora/v3 v3.0.0 h1:R6zcoZZbvVcGMvDCKo45A9U/lzYyzl5NfYIvznmDfE4= @@ -749,8 +750,8 @@ github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs= github.com/tklauser/numcpus v0.3.0 h1:ILuRUQBtssgnxw0XXIjKUC56fgnOrFoQQ/4+DeU2biQ= github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8= -github.com/torquem-ch/mdbx-go v0.22.10 h1:reevtNP74E9SN7ESnogJr8Q8CI/0JcSMJ9tghfaLAEQ= -github.com/torquem-ch/mdbx-go v0.22.10/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= +github.com/torquem-ch/mdbx-go v0.22.16 h1:uSuQOAKSZC7TvV4N4km+6kyER2YxaOuL/0qybsQtlUY= +github.com/torquem-ch/mdbx-go v0.22.16/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ugorji/go v1.1.13 h1:nB3O5kBSQGjEQAcfe1aLUYuxmXdFKmYgBZhY32rQb6Q= diff --git a/p2p/discover/common.go b/p2p/discover/common.go index 642d79016ef..63cbcd091c0 100644 --- a/p2p/discover/common.go +++ b/p2p/discover/common.go @@ -17,6 +17,7 @@ package discover import ( + "context" "crypto/ecdsa" "net" @@ -63,8 +64,8 @@ func (cfg Config) withDefaults() Config { } // ListenUDP starts listening for discovery packets on the given UDP socket. -func ListenUDP(c UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv4, error) { - return ListenV4(c, ln, cfg) +func ListenUDP(ctx context.Context, c UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv4, error) { + return ListenV4(ctx, c, ln, cfg) } // ReadPacket is a packet that couldn't be handled. Those packets are sent to the unhandled diff --git a/p2p/discover/lookup.go b/p2p/discover/lookup.go index ec11aad89a2..0e03daa30f2 100644 --- a/p2p/discover/lookup.go +++ b/p2p/discover/lookup.go @@ -35,6 +35,7 @@ type lookup struct { result nodesByDistance replyBuffer []*node queries int + noSlowdown bool } type queryFunc func(*node) ([]*node, error) @@ -50,6 +51,8 @@ func newLookup(ctx context.Context, tab *Table, target enode.ID, q queryFunc) *l cancelCh: ctx.Done(), queries: -1, } + it.noSlowdown = isDisabledLookupSlowdown(ctx) + // Don't query further if we hit ourself. // Unlikely to happen often in practice. it.asked[tab.self().ID()] = true @@ -129,7 +132,18 @@ func (it *lookup) startQueries() bool { return it.queries > 0 } +func disableLookupSlowdown(ctx context.Context) context.Context { + return context.WithValue(ctx, "p2p.discover.lookup.noSlowdown", true) +} + +func isDisabledLookupSlowdown(ctx context.Context) bool { + return ctx.Value("p2p.discover.lookup.noSlowdown") != nil +} + func (it *lookup) slowdown() { + if it.noSlowdown { + return + } sleep := time.NewTimer(1 * time.Second) defer sleep.Stop() select { diff --git a/p2p/discover/node.go b/p2p/discover/node.go index f2dd30e136a..59c20b1bdb3 100644 --- a/p2p/discover/node.go +++ b/p2p/discover/node.go @@ -17,15 +17,9 @@ package discover import ( - "crypto/ecdsa" - "crypto/elliptic" - "errors" - "math/big" "net" "time" - "github.com/ledgerwatch/erigon/common/math" - "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/p2p/enode" ) @@ -37,33 +31,6 @@ type node struct { livenessChecks uint // how often liveness was checked } -type encPubkey [64]byte - -func encodePubkey(key *ecdsa.PublicKey) encPubkey { - var e encPubkey - math.ReadBits(key.X, e[:len(e)/2]) - math.ReadBits(key.Y, e[len(e)/2:]) - return e -} - -func decodePubkey(curve elliptic.Curve, e []byte) (*ecdsa.PublicKey, error) { - if len(e) != len(encPubkey{}) { - return nil, errors.New("wrong size public key data") - } - p := &ecdsa.PublicKey{Curve: curve, X: new(big.Int), Y: new(big.Int)} - half := len(e) / 2 - p.X.SetBytes(e[:half]) - p.Y.SetBytes(e[half:]) - if !p.Curve.IsOnCurve(p.X, p.Y) { - return nil, errors.New("invalid curve point") - } - return p, nil -} - -func (e encPubkey) id() enode.ID { - return enode.ID(crypto.Keccak256Hash(e[:])) -} - func wrapNode(n *enode.Node) *node { return &node{Node: *n} } diff --git a/p2p/discover/table.go b/p2p/discover/table.go index 4374f290970..e2e473a4f73 100644 --- a/p2p/discover/table.go +++ b/p2p/discover/table.go @@ -305,6 +305,7 @@ func (tab *Table) doRefresh(done chan struct{}) { func (tab *Table) loadSeedNodes() { seeds := wrapNodes(tab.db.QuerySeeds(seedCount, seedMaxAge)) + tab.log.Debug("QuerySeeds read nodes from the node DB", "count", len(seeds)) seeds = append(seeds, tab.nursery...) for i := range seeds { seed := seeds[i] diff --git a/p2p/discover/table_util_test.go b/p2p/discover/table_util_test.go index c6c9da20540..b61556df615 100644 --- a/p2p/discover/table_util_test.go +++ b/p2p/discover/table_util_test.go @@ -245,7 +245,7 @@ func hexEncPrivkey(h string) *ecdsa.PrivateKey { } // hexEncPubkey decodes h as a public key. -func hexEncPubkey(h string) (ret encPubkey) { +func hexEncPubkey(h string) (ret enode.PubkeyEncoded) { b, err := hex.DecodeString(h) if err != nil { panic(err) diff --git a/p2p/discover/v4_lookup_test.go b/p2p/discover/v4_lookup_test.go index a3905dc941e..1eb38de14aa 100644 --- a/p2p/discover/v4_lookup_test.go +++ b/p2p/discover/v4_lookup_test.go @@ -39,7 +39,7 @@ func TestUDPv4_Lookup(t *testing.T) { test := newUDPTest(t) // Lookup on empty table returns no nodes. - targetKey, _ := decodePubkey(crypto.S256(), lookupTestnet.target[:]) + targetKey, _ := v4wire.DecodePubkey(crypto.S256(), v4wire.Pubkey(lookupTestnet.target)) if results := test.udp.LookupPubkey(targetKey); len(results) > 0 { t.Fatalf("lookup on empty table returned %d results: %#v", len(results), results) } @@ -61,7 +61,7 @@ func TestUDPv4_Lookup(t *testing.T) { results := <-resultC t.Logf("results:") for _, e := range results { - t.Logf(" ld=%d, %x", enode.LogDist(lookupTestnet.target.id(), e.ID()), e.ID().Bytes()) + t.Logf(" ld=%d, %x", enode.LogDist(lookupTestnet.target.ID(), e.ID()), e.ID().Bytes()) } if len(results) != bucketSize { t.Errorf("wrong number of results: got %d, want %d", len(results), bucketSize) @@ -150,7 +150,7 @@ func serveTestnet(test *udpTest, testnet *preminedTestnet) { case *v4wire.Ping: test.packetInFrom(nil, key, to, &v4wire.Pong{Expiration: futureExp, ReplyTok: hash}) case *v4wire.Findnode: - dist := enode.LogDist(n.ID(), testnet.target.id()) + dist := enode.LogDist(n.ID(), testnet.target.ID()) nodes := testnet.nodesAtDistance(dist - 1) test.packetInFrom(nil, key, to, &v4wire.Neighbors{Expiration: futureExp, Nodes: nodes}) } @@ -164,12 +164,12 @@ func checkLookupResults(t *testing.T, tn *preminedTestnet, results []*enode.Node t.Helper() t.Logf("results:") for _, e := range results { - t.Logf(" ld=%d, %x", enode.LogDist(tn.target.id(), e.ID()), e.ID().Bytes()) + t.Logf(" ld=%d, %x", enode.LogDist(tn.target.ID(), e.ID()), e.ID().Bytes()) } if hasDuplicates(wrapNodes(results)) { t.Errorf("result set contains duplicate entries") } - if !sortedByDistanceTo(tn.target.id(), wrapNodes(results)) { + if !sortedByDistanceTo(tn.target.ID(), wrapNodes(results)) { t.Errorf("result set not sorted by distance to target") } wantNodes := tn.closest(len(results)) @@ -239,7 +239,7 @@ var lookupTestnet = &preminedTestnet{ } type preminedTestnet struct { - target encPubkey + target enode.PubkeyEncoded dists [hashBits + 1][]*ecdsa.PrivateKey } @@ -311,7 +311,7 @@ func (tn *preminedTestnet) closest(n int) (nodes []*enode.Node) { } } sort.Slice(nodes, func(i, j int) bool { - return enode.DistCmp(tn.target.id(), nodes[i].ID(), nodes[j].ID()) < 0 + return enode.DistCmp(tn.target.ID(), nodes[i].ID(), nodes[j].ID()) < 0 }) return nodes[:n] } @@ -326,11 +326,11 @@ func (tn *preminedTestnet) mine() { tn.dists[i] = nil } - targetSha := tn.target.id() + targetSha := tn.target.ID() found, need := 0, 40 for found < need { k := newkey() - ld := enode.LogDist(targetSha, encodePubkey(&k.PublicKey).id()) + ld := enode.LogDist(targetSha, enode.PubkeyToIDV4(&k.PublicKey)) if len(tn.dists[ld]) < 8 { tn.dists[ld] = append(tn.dists[ld], k) found++ diff --git a/p2p/discover/v4_udp.go b/p2p/discover/v4_udp.go index e5255ef223b..cdeec407d35 100644 --- a/p2p/discover/v4_udp.go +++ b/p2p/discover/v4_udp.go @@ -21,7 +21,6 @@ import ( "container/list" "context" "crypto/ecdsa" - crand "crypto/rand" "errors" "fmt" "io" @@ -128,9 +127,9 @@ type reply struct { matched chan<- bool } -func ListenV4(c UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv4, error) { +func ListenV4(ctx context.Context, c UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv4, error) { cfg = cfg.withDefaults() - closeCtx, cancel := context.WithCancel(context.Background()) + closeCtx, cancel := context.WithCancel(ctx) t := &UDPv4{ conn: c, priv: cfg.PrivateKey, @@ -266,7 +265,7 @@ func (t *UDPv4) LookupPubkey(key *ecdsa.PublicKey) []*enode.Node { // case and run the bootstrapping logic. <-t.tab.refresh() } - return t.newLookup(t.closeCtx, encodePubkey(key)).run() + return t.newLookup(t.closeCtx, key).run() } // RandomNodes is an iterator yielding nodes from a random walk of the DHT. @@ -281,20 +280,23 @@ func (t *UDPv4) lookupRandom() []*enode.Node { // lookupSelf implements transport. func (t *UDPv4) lookupSelf() []*enode.Node { - return t.newLookup(t.closeCtx, encodePubkey(&t.priv.PublicKey)).run() + return t.newLookup(t.closeCtx, &t.priv.PublicKey).run() } func (t *UDPv4) newRandomLookup(ctx context.Context) *lookup { - var target encPubkey - crand.Read(target[:]) - return t.newLookup(ctx, target) + key, err := crypto.GenerateKey() + if err != nil { + t.log.Warn("Failed to generate a random node key for newRandomLookup", "err", err) + key = t.priv + } + return t.newLookup(ctx, &key.PublicKey) } -func (t *UDPv4) newLookup(ctx context.Context, targetKey encPubkey) *lookup { - target := enode.ID(crypto.Keccak256Hash(targetKey[:])) - ekey := v4wire.Pubkey(targetKey) +func (t *UDPv4) newLookup(ctx context.Context, targetKey *ecdsa.PublicKey) *lookup { + targetKeyEnc := v4wire.EncodePubkey(targetKey) + target := enode.PubkeyEncoded(targetKeyEnc).ID() it := newLookup(ctx, t.tab, target, func(n *node) ([]*node, error) { - return t.findnode(n.ID(), n.addr(), ekey) + return t.findnode(n.ID(), n.addr(), targetKeyEnc) }) return it } @@ -565,7 +567,7 @@ func (t *UDPv4) handlePacket(from *net.UDPAddr, buf []byte) error { return err } packet := t.wrapPacket(rawpacket) - fromID := fromKey.ID() + fromID := enode.PubkeyEncoded(fromKey).ID() if packet.preverify != nil { err = packet.preverify(packet, from, fromID, fromKey) } @@ -741,7 +743,7 @@ func (t *UDPv4) handleFindnode(h *packetHandlerV4, from *net.UDPAddr, fromID eno req := h.Packet.(*v4wire.Findnode) // Determine closest nodes. - target := enode.ID(crypto.Keccak256Hash(req.Target[:])) + target := enode.PubkeyEncoded(req.Target).ID() closest := t.tab.findnodeByID(target, bucketSize, true).entries // Send neighbors in chunks with at most maxNeighbors per packet diff --git a/p2p/discover/v4_udp_test.go b/p2p/discover/v4_udp_test.go index fe98680bce2..7ccaec42f17 100644 --- a/p2p/discover/v4_udp_test.go +++ b/p2p/discover/v4_udp_test.go @@ -18,6 +18,7 @@ package discover import ( "bytes" + "context" "crypto/ecdsa" crand "crypto/rand" "encoding/binary" @@ -28,7 +29,6 @@ import ( "net" "reflect" "runtime" - "sync" "testing" "time" @@ -74,10 +74,15 @@ func newUDPTest(t *testing.T) *udpTest { panic(err) } ln := enode.NewLocalNode(test.db, test.localkey) - test.udp, _ = ListenV4(test.pipe, ln, Config{ + ctx := context.Background() + ctx = disableLookupSlowdown(ctx) + test.udp, err = ListenV4(ctx, test.pipe, ln, Config{ PrivateKey: test.localkey, Log: testlog.Logger(t, log.LvlInfo), }) + if err != nil { + panic(err) + } test.table = test.udp.tab // Wait for initial refresh so the table doesn't send unexpected findnode. <-test.table.initDone @@ -261,7 +266,8 @@ func TestUDPv4_findnode(t *testing.T) { // put a few nodes into the table. their exact // distribution shouldn't matter much, although we need to // take care not to overflow any bucket. - nodes := &nodesByDistance{target: testTarget.ID()} + testTargetID := enode.PubkeyEncoded(testTarget).ID() + nodes := &nodesByDistance{target: testTargetID} live := make(map[enode.ID]bool) numCandidates := 2 * bucketSize for i := 0; i < numCandidates; i++ { @@ -279,11 +285,11 @@ func TestUDPv4_findnode(t *testing.T) { // ensure there's a bond with the test node, // findnode won't be accepted otherwise. - remoteID := v4wire.EncodePubkey(&test.remotekey.PublicKey).ID() + remoteID := enode.PubkeyToIDV4(&test.remotekey.PublicKey) test.table.db.UpdateLastPongReceived(remoteID, test.remoteaddr.IP, time.Now()) // check that closest neighbors are returned. - expected := test.table.findnodeByID(testTarget.ID(), bucketSize, true) + expected := test.table.findnodeByID(testTargetID, bucketSize, true) test.packetIn(nil, &v4wire.Findnode{Target: testTarget, Expiration: futureExp}) waitNeighbors := func(want []*node) { test.waitPacketOut(func(p *v4wire.Neighbors, to *net.UDPAddr, hash []byte) { @@ -291,11 +297,12 @@ func TestUDPv4_findnode(t *testing.T) { t.Errorf("wrong number of results: got %d, want %d", len(p.Nodes), bucketSize) } for i, n := range p.Nodes { - if n.ID.ID() != want[i].ID() { + nodeID := enode.PubkeyEncoded(n.ID).ID() + if nodeID != want[i].ID() { t.Errorf("result mismatch at %d:\n got: %v\n want: %v", i, n, expected.entries[i]) } - if !live[n.ID.ID()] { - t.Errorf("result includes dead node %v", n.ID.ID()) + if !live[nodeID] { + t.Errorf("result includes dead node %v", nodeID) } } }) @@ -319,7 +326,7 @@ func TestUDPv4_findnodeMultiReply(t *testing.T) { // queue a pending findnode request resultc, errc := make(chan []*node), make(chan error) go func() { - rid := encodePubkey(&test.remotekey.PublicKey).id() + rid := enode.PubkeyToIDV4(&test.remotekey.PublicKey) ns, err := test.udp.findnode(rid, test.remoteaddr, testTarget) if err != nil && len(ns) == 0 { errc <- err @@ -443,7 +450,7 @@ func TestUDPv4_successfulPing(t *testing.T) { // pong packet. select { case n := <-added: - rid := encodePubkey(&test.remotekey.PublicKey).id() + rid := enode.PubkeyToIDV4(&test.remotekey.PublicKey) if n.ID() != rid { t.Errorf("node has wrong ID: got %v, want %v", n.ID(), rid) } @@ -583,7 +590,9 @@ func startLocalhostV4(t *testing.T, cfg Config) *UDPv4 { realaddr := socket.LocalAddr().(*net.UDPAddr) ln.SetStaticIP(realaddr.IP) ln.SetFallbackUDP(realaddr.Port) - udp, err := ListenV4(socket, ln, cfg) + ctx := context.Background() + ctx = disableLookupSlowdown(ctx) + udp, err := ListenV4(ctx, socket, ln, cfg) if err != nil { t.Fatal(err) } @@ -592,11 +601,8 @@ func startLocalhostV4(t *testing.T, cfg Config) *UDPv4 { // dgramPipe is a fake UDP socket. It queues all sent datagrams. type dgramPipe struct { - mu *sync.Mutex - cond *sync.Cond - closing chan struct{} - closed bool - queue []dgram + queue chan dgram + closed chan struct{} } type dgram struct { @@ -605,11 +611,9 @@ type dgram struct { } func newpipe() *dgramPipe { - mu := new(sync.Mutex) return &dgramPipe{ - closing: make(chan struct{}), - cond: &sync.Cond{L: mu}, - mu: mu, + make(chan dgram, 1000), + make(chan struct{}), } } @@ -617,30 +621,24 @@ func newpipe() *dgramPipe { func (c *dgramPipe) WriteToUDP(b []byte, to *net.UDPAddr) (n int, err error) { msg := make([]byte, len(b)) copy(msg, b) - c.mu.Lock() - defer c.mu.Unlock() - if c.closed { - return 0, errors.New("closed") - } - c.queue = append(c.queue, dgram{*to, b}) - c.cond.Signal() + + n = 0 + err = errors.New("closed") + defer recover() + + c.queue <- dgram{*to, b} return len(b), nil } // ReadFromUDP just hangs until the pipe is closed. func (c *dgramPipe) ReadFromUDP(b []byte) (n int, addr *net.UDPAddr, err error) { - <-c.closing + <-c.closed return 0, nil, io.EOF } func (c *dgramPipe) Close() error { - c.mu.Lock() - defer c.mu.Unlock() - if !c.closed { - close(c.closing) - c.closed = true - } - c.cond.Broadcast() + close(c.queue) + close(c.closed) return nil } @@ -649,29 +647,16 @@ func (c *dgramPipe) LocalAddr() net.Addr { } func (c *dgramPipe) receive() (dgram, error) { - c.mu.Lock() - defer c.mu.Unlock() - - var timedOut bool - timer := time.AfterFunc(3*time.Second, func() { - c.mu.Lock() - timedOut = true - c.mu.Unlock() - c.cond.Broadcast() - }) - defer timer.Stop() + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() - for len(c.queue) == 0 && !c.closed && !timedOut { - c.cond.Wait() - } - if c.closed { + select { + case p, isOpen := <-c.queue: + if isOpen { + return p, nil + } return dgram{}, errClosed - } - if timedOut { + case <-ctx.Done(): return dgram{}, errTimeout } - p := c.queue[0] - copy(c.queue, c.queue[1:]) - c.queue = c.queue[:len(c.queue)-1] - return p, nil } diff --git a/p2p/discover/v4wire/v4wire.go b/p2p/discover/v4wire/v4wire.go index 8b678964399..af2e29d86f4 100644 --- a/p2p/discover/v4wire/v4wire.go +++ b/p2p/discover/v4wire/v4wire.go @@ -29,7 +29,6 @@ import ( "github.com/ledgerwatch/erigon/common/math" "github.com/ledgerwatch/erigon/crypto" - "github.com/ledgerwatch/erigon/p2p/enode" "github.com/ledgerwatch/erigon/p2p/enr" "github.com/ledgerwatch/erigon/rlp" ) @@ -125,11 +124,6 @@ const MaxNeighbors = 12 // Pubkey represents an encoded 64-byte secp256k1 public key. type Pubkey [64]byte -// ID returns the node ID corresponding to the public key. -func (e Pubkey) ID() enode.ID { - return enode.ID(crypto.Keccak256Hash(e[:])) -} - // Node represents information about a node. type Node struct { IP net.IP // len 4 for IPv4 or 16 for IPv6 @@ -192,6 +186,7 @@ func seqFromTail(tail []rlp.RawValue) uint64 { return 0 } var seq uint64 + //goland:noinspection GoUnhandledErrorResult rlp.DecodeBytes(tail[0], &seq) //nolint:errcheck return seq } @@ -279,7 +274,8 @@ func recoverNodeKey(hash, sig []byte) (key Pubkey, err error) { return key, nil } -// EncodePubkey encodes a secp256k1 public key. +// EncodePubkey converts a public key into a binary format. +// The logic matches DecodePubkey. func EncodePubkey(key *ecdsa.PublicKey) Pubkey { var e Pubkey math.ReadBits(key.X, e[:len(e)/2]) diff --git a/p2p/discover/v5_udp.go b/p2p/discover/v5_udp.go index 711966a789e..d3b5806737b 100644 --- a/p2p/discover/v5_udp.go +++ b/p2p/discover/v5_udp.go @@ -123,8 +123,8 @@ type callTimeout struct { } // ListenV5 listens on the given connection. -func ListenV5(conn UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv5, error) { - t, err := newUDPv5(conn, ln, cfg) +func ListenV5(ctx context.Context, conn UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv5, error) { + t, err := newUDPv5(ctx, conn, ln, cfg) if err != nil { return nil, err } @@ -136,8 +136,8 @@ func ListenV5(conn UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv5, error) { } // newUDPv5 creates a UDPv5 transport, but doesn't start any goroutines. -func newUDPv5(conn UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv5, error) { - closeCtx, cancelCloseCtx := context.WithCancel(context.Background()) +func newUDPv5(ctx context.Context, conn UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv5, error) { + closeCtx, cancelCloseCtx := context.WithCancel(ctx) cfg = cfg.withDefaults() t := &UDPv5{ // static fields diff --git a/p2p/discover/v5_udp_test.go b/p2p/discover/v5_udp_test.go index c9fd6ea37d1..e357996d72d 100644 --- a/p2p/discover/v5_udp_test.go +++ b/p2p/discover/v5_udp_test.go @@ -18,6 +18,7 @@ package discover import ( "bytes" + "context" "crypto/ecdsa" "encoding/binary" "errors" @@ -101,7 +102,9 @@ func startLocalhostV5(t *testing.T, cfg Config) *UDPv5 { realaddr := socket.LocalAddr().(*net.UDPAddr) ln.SetStaticIP(realaddr.IP) ln.Set(enr.UDP(realaddr.Port)) - udp, err := ListenV5(socket, ln, cfg) + ctx := context.Background() + ctx = disableLookupSlowdown(ctx) + udp, err := ListenV5(ctx, socket, ln, cfg) if err != nil { t.Fatal(err) } @@ -562,7 +565,7 @@ func TestUDPv5_lookup(t *testing.T) { test := newUDPV5Test(t) // Lookup on empty table returns no nodes. - if results := test.udp.Lookup(lookupTestnet.target.id()); len(results) > 0 { + if results := test.udp.Lookup(lookupTestnet.target.ID()); len(results) > 0 { t.Fatalf("lookup on empty table returned %d results: %#v", len(results), results) } @@ -581,7 +584,7 @@ func TestUDPv5_lookup(t *testing.T) { // Start the lookup. resultC := make(chan []*enode.Node, 1) go func() { - resultC <- test.udp.Lookup(lookupTestnet.target.id()) + resultC <- test.udp.Lookup(lookupTestnet.target.ID()) test.close() }() @@ -725,7 +728,9 @@ func newUDPV5Test(t *testing.T) *udpV5Test { ln := enode.NewLocalNode(test.db, test.localkey) ln.SetStaticIP(net.IP{10, 0, 0, 1}) ln.Set(enr.UDP(30303)) - test.udp, err = ListenV5(test.pipe, ln, Config{ + ctx := context.Background() + ctx = disableLookupSlowdown(ctx) + test.udp, err = ListenV5(ctx, test.pipe, ln, Config{ PrivateKey: test.localkey, Log: testlog.Logger(t, log.LvlInfo), ValidSchemes: enode.ValidSchemesForTesting, @@ -764,7 +769,7 @@ func (test *udpV5Test) packetInFrom(key *ecdsa.PrivateKey, addr *net.UDPAddr, pa // getNode ensures the test knows about a node at the given endpoint. func (test *udpV5Test) getNode(key *ecdsa.PrivateKey, addr *net.UDPAddr) *enode.LocalNode { - id := encodePubkey(&key.PublicKey).id() + id := enode.PubkeyToIDV4(&key.PublicKey) ln := test.nodesByID[id] if ln == nil { db, err := enode.OpenDB(test.t.TempDir()) diff --git a/p2p/enode/idscheme.go b/p2p/enode/idscheme.go index 0d7bcf19221..d07ef769c3a 100644 --- a/p2p/enode/idscheme.go +++ b/p2p/enode/idscheme.go @@ -21,8 +21,8 @@ import ( "fmt" "io" - "github.com/ledgerwatch/erigon/common/math" "github.com/ledgerwatch/erigon/crypto" + "github.com/ledgerwatch/erigon/p2p/discover/v4wire" "github.com/ledgerwatch/erigon/p2p/enr" "github.com/ledgerwatch/erigon/rlp" "golang.org/x/crypto/sha3" @@ -83,10 +83,20 @@ func (V4ID) NodeAddr(r *enr.Record) []byte { if err != nil { return nil } - buf := make([]byte, 64) - math.ReadBits(pubkey.X, buf[:32]) - math.ReadBits(pubkey.Y, buf[32:]) - return crypto.Keccak256(buf) + id := PubkeyToIDV4((*ecdsa.PublicKey)(&pubkey)) + return id[:] +} + +// PubkeyToIDV4 derives the v4 node address from the given public key. +func PubkeyToIDV4(key *ecdsa.PublicKey) ID { + return PubkeyEncoded(v4wire.EncodePubkey(key)).ID() +} + +type PubkeyEncoded v4wire.Pubkey + +// ID returns the node ID corresponding to the public key. +func (e PubkeyEncoded) ID() ID { + return ID(crypto.Keccak256Hash(e[:])) } // Secp256k1 is the "secp256k1" key, which holds a public key. diff --git a/p2p/enode/nodedb.go b/p2p/enode/nodedb.go index 621159c6da1..61c3836e094 100644 --- a/p2p/enode/nodedb.go +++ b/p2p/enode/nodedb.go @@ -35,6 +35,8 @@ import ( "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/rlp" "github.com/ledgerwatch/log/v3" + + mdbx1 "github.com/torquem-ch/mdbx-go/mdbx" ) // Keys in the node database. @@ -61,7 +63,7 @@ const ( const ( dbNodeExpiration = 24 * time.Hour // Time after which an unseen node should be dropped. dbCleanupCycle = time.Hour // Time period for running the expiration task. - dbVersion = 9 + dbVersion = 10 ) var ( @@ -88,9 +90,10 @@ func OpenDB(path string) (*DB, error) { return newPersistentDB(logger, path) } -var bucketsConfig = func(defaultBuckets kv.TableCfg) kv.TableCfg { +func bucketsConfig(_ kv.TableCfg) kv.TableCfg { return kv.TableCfg{ - kv.Inodes: {}, + kv.Inodes: {}, + kv.NodeRecords: {}, } } @@ -110,7 +113,14 @@ func newMemoryDB(logger log.Logger) (*DB, error) { func newPersistentDB(logger log.Logger, path string) (*DB, error) { var db kv.RwDB var err error - db, err = mdbx.NewMDBX(logger).Path(path).Label(kv.SentryDB).MapSize(1024 * datasize.MB).WithTablessCfg(bucketsConfig).Open() + db, err = mdbx.NewMDBX(logger). + Path(path). + Label(kv.SentryDB). + WithTablessCfg(bucketsConfig). + MapSize(1024 * datasize.MB). + Flags(func(f uint) uint { return f ^ mdbx1.Durable | mdbx1.SafeNoSync }). + SyncPeriod(2 * time.Second). + Open() if err != nil { return nil, err } @@ -141,7 +151,7 @@ func newPersistentDB(logger log.Logger, path string) (*DB, error) { } if blob != nil && !bytes.Equal(blob, currentVer) { db.Close() - if err := os.Remove(path); err != nil { + if err := os.RemoveAll(path); err != nil { return nil, err } return newPersistentDB(logger, path) @@ -274,7 +284,7 @@ func (db *DB) storeUint64(key []byte, n uint64) error { func (db *DB) Node(id ID) *Node { var blob []byte if err := db.kv.View(context.Background(), func(tx kv.Tx) error { - v, errGet := tx.GetOne(kv.Inodes, nodeKey(id)) + v, errGet := tx.GetOne(kv.NodeRecords, nodeKey(id)) if errGet != nil { return errGet } @@ -312,7 +322,7 @@ func (db *DB) UpdateNode(node *Node) error { return err } if err := db.kv.Update(context.Background(), func(tx kv.RwTx) error { - return tx.Put(kv.Inodes, nodeKey(node.ID()), blob) + return tx.Put(kv.NodeRecords, nodeKey(node.ID()), blob) }); err != nil { return err } @@ -340,17 +350,10 @@ func (db *DB) DeleteNode(id ID) { func deleteRange(db kv.RwDB, prefix []byte) { if err := db.Update(context.Background(), func(tx kv.RwTx) error { - c, err := tx.RwCursor(kv.Inodes) - if err != nil { - return err - } - for k, _, err := c.Seek(prefix); bytes.HasPrefix(k, prefix); k, _, err = c.Next() { - if err != nil { + for bucket := range bucketsConfig(nil) { + if err := deleteRangeInBucket(tx, prefix, bucket); err != nil { return err } - if err := c.Delete(k, nil); err != nil { - return nil - } } return nil }); err != nil { @@ -358,6 +361,20 @@ func deleteRange(db kv.RwDB, prefix []byte) { } } +func deleteRangeInBucket(tx kv.RwTx, prefix []byte, bucket string) error { + c, err := tx.RwCursor(bucket) + if err != nil { + return err + } + var k []byte + for k, _, err = c.Seek(prefix); (err == nil) && (k != nil) && bytes.HasPrefix(k, prefix); k, _, err = c.Next() { + if err = c.DeleteCurrent(); err != nil { + break + } + } + return err +} + // ensureExpirer is a small helper method ensuring that the data expiration // mechanism is running. If the expiration goroutine is already running, this // method simply returns. @@ -528,7 +545,7 @@ func (db *DB) QuerySeeds(n int, maxAge time.Duration) []*Node { ) if err := db.kv.View(context.Background(), func(tx kv.Tx) error { - c, err := tx.Cursor(kv.Inodes) + c, err := tx.Cursor(kv.NodeRecords) if err != nil { return err } diff --git a/p2p/enode/urlv4.go b/p2p/enode/urlv4.go index 16208724e93..a566339a581 100644 --- a/p2p/enode/urlv4.go +++ b/p2p/enode/urlv4.go @@ -26,7 +26,6 @@ import ( "regexp" "strconv" - "github.com/ledgerwatch/erigon/common/math" "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/p2p/enr" ) @@ -193,11 +192,3 @@ func (n *Node) URLv4() string { } return u.String() } - -// PubkeyToIDV4 derives the v4 node address from the given public key. -func PubkeyToIDV4(key *ecdsa.PublicKey) ID { - e := make([]byte, 64) - math.ReadBits(key.X, e[:len(e)/2]) - math.ReadBits(key.Y, e[len(e)/2:]) - return ID(crypto.Keccak256Hash(e)) -} diff --git a/p2p/server.go b/p2p/server.go index face5e4d73c..7f6a6397d1d 100644 --- a/p2p/server.go +++ b/p2p/server.go @@ -19,6 +19,7 @@ package p2p import ( "bytes" + "context" "crypto/ecdsa" "encoding/hex" "errors" @@ -452,7 +453,7 @@ func (srv *Server) Running() bool { // Start starts running the server. // Servers can not be re-used after stopping. -func (srv *Server) Start() error { +func (srv *Server) Start(ctx context.Context) error { srv.lock.Lock() defer srv.lock.Unlock() if srv.running { @@ -497,7 +498,7 @@ func (srv *Server) Start() error { return err } } - if err := srv.setupDiscovery(); err != nil { + if err := srv.setupDiscovery(ctx); err != nil { return err } srv.setupDialScheduler() @@ -552,7 +553,7 @@ func (srv *Server) setupLocalNode() error { return nil } -func (srv *Server) setupDiscovery() error { +func (srv *Server) setupDiscovery(ctx context.Context) error { srv.discmix = enode.NewFairMix(discmixTimeout) // Add protocol-specific discovery sources. @@ -606,7 +607,7 @@ func (srv *Server) setupDiscovery() error { Unhandled: unhandled, Log: srv.log, } - ntab, err := discover.ListenV4(conn, srv.localnode, cfg) + ntab, err := discover.ListenV4(ctx, conn, srv.localnode, cfg) if err != nil { return err } @@ -624,9 +625,9 @@ func (srv *Server) setupDiscovery() error { } var err error if sconn != nil { - srv.DiscV5, err = discover.ListenV5(sconn, srv.localnode, cfg) + srv.DiscV5, err = discover.ListenV5(ctx, sconn, srv.localnode, cfg) } else { - srv.DiscV5, err = discover.ListenV5(conn, srv.localnode, cfg) + srv.DiscV5, err = discover.ListenV5(ctx, conn, srv.localnode, cfg) } if err != nil { return err diff --git a/p2p/server_test.go b/p2p/server_test.go index 01c856f63c7..c58eb6b8271 100644 --- a/p2p/server_test.go +++ b/p2p/server_test.go @@ -17,6 +17,7 @@ package p2p import ( + "context" "crypto/ecdsa" "crypto/sha256" "errors" @@ -82,12 +83,16 @@ func startTestServer(t *testing.T, remoteKey *ecdsa.PublicKey, pf func(*Peer)) * return newTestTransport(remoteKey, fd, dialDest) }, } - if err := server.Start(); err != nil { + if err := server.TestStart(); err != nil { t.Fatalf("Could not start server: %v", err) } return server } +func (srv *Server) TestStart() error { + return srv.Start(context.Background()) +} + func TestServerListen(t *testing.T) { // start the test server connected := make(chan *Peer) @@ -219,11 +224,11 @@ func TestServerRemovePeerDisconnect(t *testing.T) { ListenAddr: "127.0.0.1:0", Logger: testlog.Logger(t, log.LvlTrace).New("server", "2"), }} - if err := srv1.Start(); err != nil { + if err := srv1.TestStart(); err != nil { t.Fatal("cant start srv1") } defer srv1.Stop() - if err := srv2.Start(); err != nil { + if err := srv2.TestStart(); err != nil { t.Fatal("cant start srv2") } defer srv2.Stop() @@ -252,7 +257,7 @@ func TestServerAtCap(t *testing.T) { Logger: testlog.Logger(t, log.LvlTrace), }, } - if err := srv.Start(); err != nil { + if err := srv.TestStart(); err != nil { t.Fatalf("could not start: %v", err) } defer srv.Stop() @@ -329,7 +334,7 @@ func TestServerPeerLimits(t *testing.T) { }, newTransport: func(fd net.Conn, dialDest *ecdsa.PublicKey) transport { return tp }, } - if err := srv.Start(); err != nil { + if err := srv.TestStart(); err != nil { t.Fatalf("couldn't start server: %v", err) } defer srv.Stop() @@ -440,7 +445,7 @@ func TestServerSetupConn(t *testing.T) { log: cfg.Logger, } if !test.dontstart { - if err := srv.Start(); err != nil { + if err := srv.TestStart(); err != nil { t.Fatalf("couldn't start server: %v", err) } defer srv.Stop() @@ -530,7 +535,7 @@ func TestServerInboundThrottle(t *testing.T) { return listenFakeAddr(network, laddr, fakeAddr) }, } - if err := srv.Start(); err != nil { + if err := srv.TestStart(); err != nil { t.Fatal("can't start: ", err) } defer srv.Stop() From 0fe1dcc4b6e4a501599383d2f6e03b26c07457f4 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Tue, 15 Mar 2022 07:28:04 +0000 Subject: [PATCH 194/261] [stable] Fixes for state overrides in RPC (#3693) * State override support (#3628) * added stateOverride type * solved import cycle * refactoring * imported wrong package * fixed Call arguments * typo * override for traceCall * Fix eth call (#3618) * added isFake * using isFake instead of checkNonce * Revert "using isFake instead of checkNonce" This reverts commit 6a202bbcdda666677fc93744549046432fae18b6. * Revert "added isFake" This reverts commit 2c4802488afde25ac583c6af6e6778cfa90c4dcd. * only checking EOA if we are checking for Nonce Co-authored-by: Enrique Jose Avila Asapche --- cmd/rpcdaemon/commands/eth_api.go | 2 +- cmd/rpcdaemon/commands/eth_call.go | 2 +- cmd/rpcdaemon/commands/tracing.go | 6 ++++ core/state_transition.go | 16 +++++----- eth/tracers/api.go | 14 ++++++--- internal/ethapi/state_overrides.go | 50 ++++++++++++++++++++++++++++++ turbo/transactions/call.go | 36 +++------------------ 7 files changed, 79 insertions(+), 47 deletions(-) create mode 100644 internal/ethapi/state_overrides.go diff --git a/cmd/rpcdaemon/commands/eth_api.go b/cmd/rpcdaemon/commands/eth_api.go index 169b86a79ca..a6174518813 100644 --- a/cmd/rpcdaemon/commands/eth_api.go +++ b/cmd/rpcdaemon/commands/eth_api.go @@ -74,7 +74,7 @@ type EthAPI interface { GasPrice(_ context.Context) (*hexutil.Big, error) // Sending related (see ./eth_call.go) - Call(ctx context.Context, args ethapi.CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *map[common.Address]ethapi.Account) (hexutil.Bytes, error) + Call(ctx context.Context, args ethapi.CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *ethapi.StateOverrides) (hexutil.Bytes, error) EstimateGas(ctx context.Context, args ethapi.CallArgs, blockNrOrHash *rpc.BlockNumberOrHash) (hexutil.Uint64, error) SendRawTransaction(ctx context.Context, encodedTx hexutil.Bytes) (common.Hash, error) SendTransaction(_ context.Context, txObject interface{}) (common.Hash, error) diff --git a/cmd/rpcdaemon/commands/eth_call.go b/cmd/rpcdaemon/commands/eth_call.go index 843e4e361c3..4e94bc16e0e 100644 --- a/cmd/rpcdaemon/commands/eth_call.go +++ b/cmd/rpcdaemon/commands/eth_call.go @@ -30,7 +30,7 @@ import ( ) // Call implements eth_call. Executes a new message call immediately without creating a transaction on the block chain. -func (api *APIImpl) Call(ctx context.Context, args ethapi.CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *map[common.Address]ethapi.Account) (hexutil.Bytes, error) { +func (api *APIImpl) Call(ctx context.Context, args ethapi.CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *ethapi.StateOverrides) (hexutil.Bytes, error) { tx, err := api.db.BeginRo(ctx) if err != nil { return nil, err diff --git a/cmd/rpcdaemon/commands/tracing.go b/cmd/rpcdaemon/commands/tracing.go index b26b8e9f41c..05956c8f722 100644 --- a/cmd/rpcdaemon/commands/tracing.go +++ b/cmd/rpcdaemon/commands/tracing.go @@ -178,6 +178,12 @@ func (api *PrivateDebugAPIImpl) TraceCall(ctx context.Context, args ethapi.CallA } ibs := state.New(stateReader) + if config != nil && config.StateOverrides != nil { + if err := config.StateOverrides.Override(ibs); err != nil { + return err + } + } + var baseFee *uint256.Int if header != nil && header.BaseFee != nil { var overflow bool diff --git a/core/state_transition.go b/core/state_transition.go index b54de8d769a..cc681684471 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -249,15 +249,15 @@ func (st *StateTransition) preCheck(gasBailout bool) error { return fmt.Errorf("%w: address %v, tx: %d state: %d", ErrNonceTooLow, st.msg.From().Hex(), msgNonce, stNonce) } - } - // Make sure the sender is an EOA (EIP-3607) - if codeHash := st.state.GetCodeHash(st.msg.From()); codeHash != emptyCodeHash && codeHash != (common.Hash{}) { - // common.Hash{} means that the sender is not in the state. - // Historically there were transactions with 0 gas price and non-existing sender, - // so we have to allow that. - return fmt.Errorf("%w: address %v, codehash: %s", ErrSenderNoEOA, - st.msg.From().Hex(), codeHash) + // Make sure the sender is an EOA (EIP-3607) + if codeHash := st.state.GetCodeHash(st.msg.From()); codeHash != emptyCodeHash && codeHash != (common.Hash{}) { + // common.Hash{} means that the sender is not in the state. + // Historically there were transactions with 0 gas price and non-existing sender, + // so we have to allow that. + return fmt.Errorf("%w: address %v, codehash: %s", ErrSenderNoEOA, + st.msg.From().Hex(), codeHash) + } } // Make sure the transaction gasFeeCap is greater than the block's baseFee. diff --git a/eth/tracers/api.go b/eth/tracers/api.go index c006b7319be..6187022f30c 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -1,12 +1,16 @@ package tracers -import "github.com/ledgerwatch/erigon/core/vm" +import ( + "github.com/ledgerwatch/erigon/core/vm" + "github.com/ledgerwatch/erigon/internal/ethapi" +) // TraceConfig holds extra parameters to trace functions. type TraceConfig struct { *vm.LogConfig - Tracer *string - Timeout *string - Reexec *uint64 - NoRefunds *bool // Turns off gas refunds when tracing + Tracer *string + Timeout *string + Reexec *uint64 + NoRefunds *bool // Turns off gas refunds when tracing + StateOverrides *ethapi.StateOverrides } diff --git a/internal/ethapi/state_overrides.go b/internal/ethapi/state_overrides.go new file mode 100644 index 00000000000..d3159f351b5 --- /dev/null +++ b/internal/ethapi/state_overrides.go @@ -0,0 +1,50 @@ +package ethapi + +import ( + "fmt" + "math/big" + + "github.com/holiman/uint256" + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/core/state" +) + +type StateOverrides map[common.Address]Account + +func (overrides *StateOverrides) Override(state *state.IntraBlockState) error { + + for addr, account := range *overrides { + // Override account nonce. + if account.Nonce != nil { + state.SetNonce(addr, uint64(*account.Nonce)) + } + // Override account(contract) code. + if account.Code != nil { + state.SetCode(addr, *account.Code) + } + // Override account balance. + if account.Balance != nil { + balance, overflow := uint256.FromBig((*big.Int)(*account.Balance)) + if overflow { + return fmt.Errorf("account.Balance higher than 2^256-1") + } + state.SetBalance(addr, balance) + } + if account.State != nil && account.StateDiff != nil { + return fmt.Errorf("account %s has both 'state' and 'stateDiff'", addr.Hex()) + } + // Replace entire state if caller requires. + if account.State != nil { + state.SetStorage(addr, *account.State) + } + // Apply state diff into specified accounts. + if account.StateDiff != nil { + for key, value := range *account.StateDiff { + key := key + state.SetState(addr, &key, value) + } + } + } + + return nil +} diff --git a/turbo/transactions/call.go b/turbo/transactions/call.go index 643802667c5..312600a40b6 100644 --- a/turbo/transactions/call.go +++ b/turbo/transactions/call.go @@ -29,7 +29,7 @@ func DoCall( ctx context.Context, args ethapi.CallArgs, tx kv.Tx, blockNrOrHash rpc.BlockNumberOrHash, - block *types.Block, overrides *map[common.Address]ethapi.Account, + block *types.Block, overrides *ethapi.StateOverrides, gasCap uint64, chainConfig *params.ChainConfig, filters *filters.Filters, @@ -53,38 +53,10 @@ func DoCall( // Override the fields of specified contracts before execution. if overrides != nil { - for addr, account := range *overrides { - // Override account nonce. - if account.Nonce != nil { - state.SetNonce(addr, uint64(*account.Nonce)) - } - // Override account(contract) code. - if account.Code != nil { - state.SetCode(addr, *account.Code) - } - // Override account balance. - if account.Balance != nil { - balance, overflow := uint256.FromBig((*big.Int)(*account.Balance)) - if overflow { - return nil, fmt.Errorf("account.Balance higher than 2^256-1") - } - state.SetBalance(addr, balance) - } - if account.State != nil && account.StateDiff != nil { - return nil, fmt.Errorf("account %s has both 'state' and 'stateDiff'", addr.Hex()) - } - // Replace entire state if caller requires. - if account.State != nil { - state.SetStorage(addr, *account.State) - } - // Apply state diff into specified accounts. - if account.StateDiff != nil { - for key, value := range *account.StateDiff { - key := key - state.SetState(addr, &key, value) - } - } + if err := overrides.Override(state); err != nil { + return nil, err } + } // Setup context so it may be cancelled the call has completed From aca7d9b67eefd164b35963933e3c9e4e51ccd6cf Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Tue, 15 Mar 2022 09:13:12 +0000 Subject: [PATCH 195/261] new bootnodes (#3591) (#3695) Co-authored-by: Enrique Jose Avila Asapche --- params/bootnodes.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/params/bootnodes.go b/params/bootnodes.go index 4518a695833..c2457e481e9 100644 --- a/params/bootnodes.go +++ b/params/bootnodes.go @@ -24,12 +24,12 @@ var MainnetBootnodes = []string{ // Ethereum Foundation Go Bootnodes "enode://d860a01f9722d78051619d1e2351aba3f43f943f6f00718d1b9baa4101932a1f5011f16bb2b1bb35db20d6fe28fa0bf09636d26a87d31de9ec6203eeedb1f666@18.138.108.67:30303", // bootnode-aws-ap-southeast-1-001 "enode://22a8232c3abc76a16ae9d6c3b164f98775fe226f0917b0ca871128a74a8e9630b458460865bab457221f1d448dd9791d24c4e5d88786180ac185df813a68d4de@3.209.45.79:30303", // bootnode-aws-us-east-1-001 - "enode://ca6de62fce278f96aea6ec5a2daadb877e51651247cb96ee310a318def462913b653963c155a0ef6c7d50048bba6e6cea881130857413d9f50a621546b590758@34.255.23.113:30303", // bootnode-aws-eu-west-1-001 - "enode://279944d8dcd428dffaa7436f25ca0ca43ae19e7bcf94a8fb7d1641651f92d121e972ac2e8f381414b80cc8e5555811c2ec6e1a99bb009b3f53c4c69923e11bd8@35.158.244.151:30303", // bootnode-aws-eu-central-1-001 "enode://8499da03c47d637b20eee24eec3c356c9a2e6148d6fe25ca195c7949ab8ec2c03e3556126b0d7ed644675e78c4318b08691b7b57de10e5f0d40d05b09238fa0a@52.187.207.27:30303", // bootnode-azure-australiaeast-001 "enode://103858bdb88756c71f15e9b5e09b56dc1be52f0a5021d46301dbbfb7e130029cc9d0d6f73f693bc29b665770fff7da4d34f3c6379fe12721b5d7a0bcb5ca1fc1@191.234.162.198:30303", // bootnode-azure-brazilsouth-001 "enode://715171f50508aba88aecd1250af392a45a330af91d7b90701c436b618c86aaa1589c9184561907bebbb56439b8f8787bc01f49a7c77276c58c1b09822d75e8e8@52.231.165.108:30303", // bootnode-azure-koreasouth-001 "enode://5d6d7cd20d6da4bb83a1d28cadb5d409b64edf314c0335df658c1a54e32c7c4a7ab7823d57c39b6a757556e68ff1df17c748b698544a55cb488b52479a92b60f@104.42.217.25:30303", // bootnode-azure-westus-001 + "enode://2b252ab6a1d0f971d9722cb839a42cb81db019ba44c08754628ab4a823487071b5695317c8ccd085219c3a03af063495b2f1da8d18218da2d6a82981b45e6ffc@65.108.70.101:30303", // bootnode-hetzner-hel + "enode://4aeb4ab6c14b23e2c4cfdce879c04b0748a20d8e9b59e25ded2a08143e265c6c25936e74cbc8e641e3312ca288673d91f2f93f8e277de3cfa444ecdaaf982052@157.90.35.166:30303", // bootnode-hetzner-fsn } // SepoliaBootnodes are the enode URLs of the P2P bootstrap nodes running on the From 8d4f91b92004537ef04d6ea828e26e92194eb654 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Tue, 15 Mar 2022 17:16:44 +0000 Subject: [PATCH 196/261] Update skip analysis and preverified hashes (#3700) (#3704) Co-authored-by: Alexey Sharp Co-authored-by: Alexey Sharp --- core/skip_analysis.go | 2 +- .../preverified_hashes_mainnet.go | 640 +++++++++++++++++- .../preverified_hashes_ropsten.go | 407 ++++++++++- 3 files changed, 1046 insertions(+), 3 deletions(-) diff --git a/core/skip_analysis.go b/core/skip_analysis.go index 37e0e63a1c6..168285d1285 100644 --- a/core/skip_analysis.go +++ b/core/skip_analysis.go @@ -21,7 +21,7 @@ import ( ) // MainnetNotCheckedFrom is the first block number not yet checked for invalid jumps -const MainnetNotCheckedFrom uint64 = 14262700 +const MainnetNotCheckedFrom uint64 = 14390050 // SkipAnalysis function tells us whether we can skip performing jumpdest analysis // for the historical blocks (on mainnet now but perhaps on the testsnets diff --git a/turbo/stages/headerdownload/preverified_hashes_mainnet.go b/turbo/stages/headerdownload/preverified_hashes_mainnet.go index 6750f8ce142..0cff53b78c8 100644 --- a/turbo/stages/headerdownload/preverified_hashes_mainnet.go +++ b/turbo/stages/headerdownload/preverified_hashes_mainnet.go @@ -74312,6 +74312,644 @@ var mainnetPreverifiedHashes = []string{ "018af69f29875d4c9b65521c7dc06d95ef50f9f1af8141f01cf5c4d6ff26883a", "9cb67f964ed81091c4a2dbdb8fabaa9028b0647ff9353c74706d88bbbe9c3448", "6b0c7b72d9d206c246bdafbac829561ae2ec8a16d2e57f8da1f4037ebec11c73", + "be42737d0a71456ea2f558f4d5832c338d26d68089afb8cfab59094cbe30749f", + "be908cb35707abf4b88106beaa5e257853e38a5ad1fe26fce687c0f4018e3659", + "30ab4845f0180da45181a9175e0f219c48df38d2ab256cb045cdfdf0ab402460", + "dff98ad7e77d8bdfa974700df2f1dcce4c6fb034a3969a46357979422ea0d9fa", + "60701d3899e387b5936f738cb43a1fdc16e6e82d1d69f44692e17acbd624994c", + "f8f161ee8a7761ed9d79942135468ecb1b894859cbaedcb6d7271ed3f3ef188d", + "9aa2ce4a8fff3c0863bbb7d0ba9cbe602efc98caaaf9389fa0a2eb264fa60d99", + "a59592c7824ac417db9dfa8264d15c69f85fc6015bd764651c682e418a9d7e39", + "607b45d4e521b7896c564a400b8357bd246ddfc674241a2a15b2aee599f5f7b1", + "a840a689b158377ff64cfb1997352d2cb9be394cd82f92af9995a05a217d7d3a", + "9a73bd4fe23b4e0dab53c6d0b7a157b6dfadebcefa7cbae60ee2145a1a8bfd60", + "9de08828d6e6cfd1294592e2e08bd6f7cf63f582c9722dd160bca5b254a2db5a", + "674a9bfe33faabe0731a4e4f25b55091d305c1d8909692dcc841a7d9e0436f4e", + "72c9a881574afffd58112c5482388265a47806e9881df367347fc5723419b55a", + "d456cc8f84da1a0a5fe60e6b617992602de74d5a394a05c6ee6da9622a9fcae4", + "14caf0ef2a0ef57e793579f866fc215730d530542dcc98f8692e89fffc1ec814", + "ff2ce92f00a4c6159d641081f12d13a7e6c22dc7b5422da36287738ae93ee08c", + "961726d0cfc6d33cecc16e1f7ac76ed2292d94a907d238361beb44c26bcd10ac", + "5018eee19639eae73aa653e95998c89d28c68f877ff9a0b12be587ccb4a5d2d1", + "0d2743a991065e67ac27acf9f3c849749c117e9ed05cfa21c7a39ac43db80102", + "a069a2e4e1b7e65b13a5f3cff20c5f2817705f0b215d67078ccf859054e227d2", + "7b97f85827965387c48920d7560a7a61122fa95a53b7688d41339c7d7b809840", + "4c1e4221b6a6e661927fab5fd2e3a89a824b02686d7d09f75fb59d986f80084d", + "43520a2902999f45459359dda600d86d076d84cfdba5cdbe6ce2ed346a85917e", + "7943dda79d811f46c5bf610d942866b6738816b7860b71600a0d7aee2a10c8b8", + "d6e000c52175a9f71833721824e42788bbd25bc61207fd49e3b67e8457a082ac", + "85c39989dad50e3c8d85795bdadb88426970da78320a2a1d1534d4417f58c9dc", + "2aafd8a867dd34cd98dc30ddb4a3107dea7a2ea83ef78c99fc4378d82a4fb62e", + "52f97d9d8c25e083c90ce472a6ab33cb6f5fee3f60a1986079a787e4e0dad6cd", + "e758fc91f820c01e599d991dffb568b3e49bd3e8ca07a75dbef86e10c318ea29", + "076fd13d5199b8c732919887d99fe03646eb1dba306de67e8d990a20f4bd61d6", + "e92e1ac592134edb3234cd205631bc7b8e767227c1e99f80019086b627fcb425", + "d93dee82d741f25f0df49724296f67ef0f719bdce57481042d274a28cbb6be58", + "ef47fdc937cc85a9e4187977116b64f2c109e039fcb9e061189be5fb512baee1", + "7eb8b1f2ce86e094c565accd5cbb41518a8d0f864bc7de00bce289ebbf68f67e", + "45bd6d4a810747bf753866866ec7c5ddd56db4e6182610b82701ad0956e7a1bd", + "41207c0475464f1451ba3a6bb68cf991ab6a64e3cc7dc0a397de1e3c61a4bfe7", + "f41da842f2279c1f9f256083b5283d2592139e3d261eac76ffbc24b6b1be75fb", + "5603e4ae0a1e5d7d66db77312bb09925084c318d6ac85fd8e090576ffde83b2b", + "31c1a613188199e315d6b6fe32511f7eb8d30b83c1e01ec9bf05bb7094dba5a3", + "d8209d23084e3c21218c72234ac62cba3e39d2b74d451e4285822eabd66f2f89", + "b8e048c101eaf91593f4cfe55cc267f0c6eee73969ac8fd09b3a77e16ba00ce4", + "527c83ba42b1e86ced02c5d04ced71cd2aae9abb9ccb156642f4aac156109637", + "7748058f934e786f02760e21e2f9dad3a0104d5190ea9acd477b12df8babbe06", + "ecb800710c055b17e3d2121297b720007525d5454792fa1467446c04d10940a1", + "098709f4b66de2801557ac8879399f9fc0970844987d16febf81618038cc9047", + "6a5ae8b449a144d2b79a89bf306d808740df1e22c8612bd7d7d7b55d17ff51ea", + "3d78e4e8f616e647f9a9942725dcb52b44561f8f9c132b284312e01a411ffc87", + "812fec887b0cbe36caba2c877b2116d8c3ea44a2518ae9866c12997eaf7cd7e8", + "c49885ce287c327bd198272816111adfa0ff5d25403c58478ab5223f9c0b5ac1", + "5caef5cc64bcf8bc7c7ac8fc9e834c88ee78e071aac971d12067c157fd6bad83", + "583c40aea476cd16d871b18770c061f7e36a560a72ba914906fb6c05e26a1905", + "4ec09f3470799d207b8fae10b9c299f48bf22544ac544f92b1fe844a9fea0816", + "0a3487f6f7bea382d91babc15e88753ec29249f7d39a1ce21652f8c28949450b", + "7c7474e939e9f36c83596b016da5a0cb6616813e2cf41b30dac1d8b83afdf677", + "df0cc6db7e0b7c40c8c7d2233682df9fe2fcfa16f627e0fd9f5a51b2e863b408", + "33db502f754b26509a499b1017bfdbbdc965a0294292f225bc76dbec720f75e1", + "b9b77c8a91bef0fba0d24848e47222eda2d5969f6eaa4546331bd1b3d4c36250", + "300d541408bb1f44b3ef1a798468bef7e18a2a4123d8d146c27ecc3d56b9140e", + "0f3bd6ae54fcdd5bfcd1e745a68a4946e741d648633a8dc58ed005ac120d18ba", + "17c0e4c4c13becde6a90303b1b0b8989825af8969786ac7cc6255f84437b5953", + "feaa4d51b4efe2fbd26212c25bfda92cf4eab458b88d11bfe50f0e0de4974f10", + "e9a38ec4301fc3392ee179c2538bf1e6d4a14038d117dfe3e55ef76229a96eea", + "4d8a5c2a1a6fb14673f992654eed68fdbd8553c55f345949ee1e96daa2aee6a5", + "7cf7edc1ade44c93d7de0ceaeade6cf6670da04582eb8592863deb6324d51e38", + "0efd42528764eba2bd76788d9b7e863be84136e3474471a99108763cd4b3d4de", + "079a2e14532e887264313a16c05aa187ae07664ffa280f3230e0ac49403a725f", + "812aa60e37fe62b3d43a5dcb01c1ae01604c4cdcc5a318a09de619b9509d2687", + "fdbda298ce7001ba4de2f9cbcb1f383cfba0f79fc016c1d3a87a3df68d1e43bc", + "a28299b02de18c186e52c581c5376b8af47b1ecba2bdb7b95d937ff822ff615e", + "846c790e7961bd2facdeb361c872ac456b2c98169be89ee1ebfe5261501b1a48", + "4a6d9abd9b9f953b1d534b7ad971f88f4514113d39cd0584f6d2b0488cb4d84f", + "4e79f4529332ba144cd781e280d214b0c6bb2c746a336e0178bfcfce6af9ead8", + "025340fac2daa59f1e20921d0d9d8b28edca45753b9a9bb1dc207ce18c6860ac", + "8cc4d9727d1306f2466e816c766f69b9dd2d75b9691ad8814ae28f3b3f32720a", + "e8b3153357714de517f8c149058ef3ef858bf51c5f719658db74aca98b56d492", + "36b41706d3040c44f1bd6c1ccfc02b698c3d491dd48bd38bb70079e1fa94b7f4", + "f5c332cb64bcc099d7c25a7cc30800f42f7d5575d4d186463333ba78538239f0", + "9db7ed11cb9e3e71995a1f567601ccdef100596365d3ec1cf50a6b32a60c0339", + "b3efde446bb5b607198ecd1cbfa25449533cc743210e2e1ab3a6117779af7f6e", + "f1891c2bdf3e1f2781804e6d9619ab3e44c9016c89008540117c28aba7a52208", + "5f894d60654996da08af8650cb8c42510bf1f996ecfdac9bffc39132690f6177", + "7de821539e94d1a92285246e27bb991d974f25559138911b7c9332da87936cff", + "52537f34279274627117d74cbf51bb74d1476f0087f869ff1c1c2fff3972144d", + "f3d0e95ccbf45208dbce4234f77adca7d879d20477b7749b00b78ee8980aa828", + "ea14feaebe52e843196698f5a6a460f4fbc846f4c831790fbbbc075b4590ca8d", + "3b955fadea6047aee23ffc553d58f87607b2afe0f1f6b7f7549cd45591cdfbd3", + "0bfebe231a3c6e9d9c648f83d8bab2ab6b04c0a47a3e01fba9adb9a5dae058db", + "48918e31bffeb1d7f9eab12bc076eaa171906a8f90ab9ce1575cfaa046f9d293", + "d7c3870efec36ce5d2c469f83e8129e435f3769c8dac2e31ac400d0759b34c2e", + "a3131d7e25e2358db7ed5645975b3ac86229accd4450f7731c1aa63135f32dda", + "6e71921f7dfcfdee4da5b9c28285e1496396b49bf9a075132c10033d9c4f596d", + "4fe75d96437cbef8da05e27644fba77dd7aad351e2c2aa6ce98b3e0925779fb9", + "77c569b7457da157b93b5dc010bff54310d2cc64e389d4616d7afc8e57eb4a6d", + "05f9f0b5375335f665db8e0dac794cd5baf8abca18ed15d7be28032259dea12e", + "ad8488098b039f3dad1ae18b9eb962d1819f3507ba6d2be4949f38798dd240c0", + "27db7c066b041b40a7d5eb0b4c52570c21775bfcf4f88cde180f6164e9795b05", + "2c6da471559f6231ce255e5de7e326a22c534cdee5d5f260a628f7c861ab4bd1", + "c90ef9d7d5c1939202ceef218006ec6087d3caebc2a97c46f52d6eef2e4ef5e8", + "5c8ad1d0f60b1d54957024e58c1c20aa4991003eedd488bc5f49aaff896ca416", + "87ecf98145f667935346ef101b4b553773f6cb0f185e305276fbf754b48a3c7b", + "c7d3af29d1c0793bf3f60304ab88ef47ef98ee0e50cba7878b503f5e6cb0f5d7", + "36e333695434b243362980c04a84c392bdf43b67323c967c9499550c3e6daa99", + "b0ede67d2a03921fe783d1a274eadf8b6c26d383974e9d6d58fe2baa9130ecf3", + "b186baf7fb3002ce6956d6fd1b42ea27fee9779da5ea037bd7f50687dbeee676", + "3bbd567ec21e165f778b56c2f4be65864b45eece147df722c5e45e45da209d9f", + "4542e0cad67ac7de3d3ced2d5aa0677805f494ad36b3b6a184023507ee1ba25c", + "da97de01773698116272a79c3b4ea677e68aef7a9cb89a1041a4356c8dfeee5a", + "99ca381d8127c3b482c03f8e4e6e88328ef87d8a8509829cc3e5d5a04d8ec65b", + "21962f7478071f71c2990b6f2ce343062233ba1c5b505d44bdb53d065f35cb9c", + "75d6dfeba8c196fb1c4a973e45fca09b8f548abe14b0b7e732a75fb46a50518b", + "e2b13fba7e061af10e3c6f3f09bd464f769f72c9d3f4f044fc58cb4453096df3", + "029677a33a470ef9199cc7831f349cbac6fee2b300981f99a5844f16d53e065f", + "bda461d78bc8ba4cfeec6234007e552829e82f1e1ac07a679e0a9e7075e2c657", + "e33f1d434959548a0111e94ad07cecfb23e71134aba82b5155af56187aed5828", + "ac6afc3e02b5e7879e3b9e4d296d630df25ad2382066115b8e587fd91ed6318a", + "33208ee6dedd7f8cf326151972d96ae6a9d9469e905a61d2801d2a787f91a2a8", + "c342a0b420adb6363dd03d96330db2817acc89acb34c67acb9b3715cc09f7a9f", + "4c263a9f3103bf56ba12a03f8460d84deec7c29418dd16e96d7924af0fc239f8", + "755b62537df19473a86080327b13a8d715a84ef97e93c697196eef85a741727d", + "dc4c63c3cec13ccffcfbfcc90f3fad92b39ba7d4c00737fc9a81b6dd3215abb0", + "c110b79c2471b6e7a50adf73d91d88562a0191b79151aa390fe9e3dad2bb887f", + "ad6de4d10fa132dab6cf539f76a44d42d3b2487072a2c496861113bea3da7f8f", + "35d476192d6ecb166841039e2e09f6898f25d3ec0b8b68cdf60b458a489c01c1", + "6715dafd9f20fa068ff138fd43b8971696cfa36fc8e6792ec6361b0d9dcb073f", + "17f394536217b7c609d72c0664e93926fd0e303e3f39d695463a3ad0ef695bdf", + "0ebb3e930c940c330997e31b17215e8af2184303b3edb152ae94a222bf95134f", + "4596ac18ea2ff555c2b7fab885d89e9c527e60fa295ff60a1531d02557711cde", + "da1c5d54f93ff19ebb4929a7d6e76b6cf77ba78053a498eab2c0b3d15f48e200", + "6874e36cdce287893d1faedcf9c8a344bd54888139de2d8ac5f4b4cb7d02003f", + "9ef1fe01e63c98721c5ceb5241a714cb60663f0650f0a8ad12c05e3883f70869", + "2c0491550ac8ed0f166e437d28f64d1796697fa12b3f4f41f00464aeca332cbd", + "f172091e4dca784e6082822aa71800fef30e08b6973c9a38826ea6ca8fbcaba4", + "1c0d92c83d4296d0327053979900c883e114412be6684ef02f66557797f4d712", + "54ec3ea3d508e510238a278855039cc5207b79a1754008ace396605501f5c74f", + "fe1693a63d27fda9af674c302e98402e2b32aef2b891589185d5f936f173ec96", + "d2f67df3c3673747bf93943bec5c1960ebf0f955b1947ea028fc10edf210f61e", + "5bd4d6c2390570b8f85487022e9ad8c5b6a5db9f4e657ad0322ba92cd45a6d0e", + "097b3a36b96e415594540c240780eab19c9745c24d5781bfef5c4fdfb51a3458", + "357a899629370c37b929c42b6f01435d35e02c7997db37a2e78f3e663e6806e0", + "a1ab28c354e334fc9e1cf6d3344fc3724766979d5249b647d4755f923e5115d9", + "9e1611c29a4035c9533b16bc8c7dd1466e70abd5490266eba88fdb1859fbb33c", + "0103c1bb7f2472c15b84bda77e6a452b4d20a02edf416903be08eefd46f9b629", + "cf4a58e3c8f531b1d9aa1a5a69e710ccfe234adbf593c9797ea73468db7df0d5", + "a68e38ed0fb34059768cca1530763666be1c175827d2492e44d8b52c231ee125", + "81f85df5e8d1ba9cbb3e3d7f576393473a8c5959a5cc3dd3ed3ff543ddbbfc85", + "0dd539fae2aa8867f4a2a278de37e623a0b0a81e258a69bb7ce4926647b3cc09", + "4c0def023746bca13db5b7eab815f1eb27bafd3061071e956cc1470e23e9c389", + "6bd5ee11f74542f2b364e4229ef543eac7375e653b6b886e8036061a005c7276", + "b51649ca5c7b4c3ac45439b903da05a948a0b8b946735bbe7dcf9528ca7ad94f", + "7432fe14edbddc8735c0bca350b93f5f8cc505b651c336e0264a05a869794520", + "f336f5b3c2e5d320f1d84566ecbfc72f93d10b98bb2dd43ca52bd446279d6006", + "5758ddfb634f7ba726cd6fa1c937e6bc4dd66be066959e56783b3865c34fbca3", + "43e54ffbad79125a6427247d88f08c53fed34477de3efcdef38bf077f7b9fdb2", + "b0cae824f24205a8196cbc1324aa2d7279c8e414e58c5dd42f51eb7d18233055", + "fce778cc65b9d4a4143ba2c902d073013f925e968fa51bfd9fca352586d835b4", + "eaeda547a3d13023ffc1c987ea7677c257790545f14245e8495c5939b5bc128f", + "4105490ac81ea98dfc9973be73ec6eeba7fb941cdd723d633d39cabd293aa13a", + "e3ccd0fe7a0a3c1e529b366b384582d909b9241256dd2b5dce357a5fcc8d3a0e", + "6de41abf82646f67e1f6bf3cb8b4c577e3a09876d8f3b26b2d9daf49d0ab6e15", + "657535ac71a276cc4bb45c9dc17988dde59495d3e457591da1f5c57557a2183c", + "18be74e521a79ccf92d0b427675708297f8864727357033bd275765a4aea4f15", + "b694f813622e2e511c90dd4b8c9a2bc9606c47aab2cc9bf27162a93a72924a69", + "e01991fab48dcdfc43a8d4771a3c5dc851d624a3a8bd781f9e122b1acb94a948", + "326a858dbf0c723a3d2b300b8a9ca7433b80c749ea9353f97b90bfe009a7e5f1", + "902e3305efe9902112607585dbc09ce72de15eee1bbbafa5cc962819d2daba82", + "312e0a178bd034804a6ea0aacb054105943c27842770e8f5e8af5de03c974b73", + "99b8366a87a5b8da725c07f248eb227d3f8e0d3c311ca48f1eeb8c0eaeaf16b6", + "ad21d37f905eeb1c301cec7f821f1e1eaf35d01c786b2d9d24ba542e14cec886", + "fea5c88b9257f1773dea2534af812ad7c1ae85619de943ecfefae476b2199ae5", + "62e8b5902d907d70a4755c6339d9ff6db6b03393a3816b52e57dcf276942a2d6", + "ecf39ca7bd783659e0ecfd759792b192fdc9a4d5fce5690c0589920479d6ff24", + "a9fdc65a20f4be5c7fa9c3ece6c5876d0c82f14509c56206cd826d8e11db4590", + "b4eeea5ff67aab4a0e3d02020e13756e1e70fb520702bc629ce26bdfbf612335", + "1d500fb144b978080083ccb014f692a49e40c88195ae80dd6fe997a6e628c75d", + "d1656059d1781820a0261fe243faa92a159da1cfadf9e6660cf62f77da1749ad", + "1b44d3034f05d9a0e389610e6dec30a8cf93ff07d6d7fdf0a0421e227fd68402", + "7301cebcc282ee5f1b773bfe277702a4e3f9147c584c8e704222e0c3fa137af5", + "6f76f06721d5236f734fc3c19b22847b3464c523d408dcff123e08d116e7445a", + "3d446d7ad9d4b2d09ab0956d223c42fcc3709391c47629b15b0520ef861f2fb4", + "be822de5e4af81506480dbd5088db343fd883109fcb3100242b220ce20eb2651", + "f8bd44bcc8c9bdc299e4d41b6f305f3c8b267943afe7707673d926de0f4e03e7", + "5deeb90c1595abc6875ad5d778cbc62688d2ef7b12f842173d218971af569a8c", + "4b3e45a75bb3c6c9fb24d6f890b0a55a1591385bbe0c41dc98a124a0482ce097", + "fe850aef8b7d1d846f8ea195203eae028009297fec0ca67c6e5518d5bfcf2102", + "f2f79a7d480496a6c5258aed9ccab1dfc28a9477cfcbf784fbeea7b92d33b989", + "bd3817ab60cd3ebc1da670ed13c4291c9d6caf2feb3b18b3e0220b30dc35c57b", + "f0b4ac4d03e37535a141a7c3ae98681ecf414ebe28a73fd019b5a67e088ebc64", + "cfac1b9b19401fe53e96785c9af371a4ea7a1db9a09207e00280eed6b7f730fe", + "f7694fbe88b92810f251c5f2973c364c3f69b668465d78b9ff1d35ef1d4c8e18", + "c9b5380accb7f883ceebf3967fceaec39f721974692d7213d506b4937af914df", + "bff957d1313de12b88c412ceafca383654a10af87d8453f2d231152c827aa79c", + "fa39a4bdded62f2f0b84d0b4d5492b20a4b8f8ca8266b89477a91fc901c13214", + "37b9555c57006706ed550811c035d913d72a3d09e00293955c1bc485481e8026", + "e1525a20b49e557062fd432608c5ee735b84e9f3f5fd5ede71fbfc9e4824daf4", + "00e875dea8ece95007aed6a1bacfa27e1d2cba6ddf81e1e1568f306b908bd9ec", + "f51792e6c696855857f92bf7b940a5e7f596631400d6e6f11263bb0d7905995c", + "917f5e3e779bcfd19156b473d5275f68d48ada9cd9c630ff9480289da77a5ec0", + "fdcd754a7bcde87ca6c80aa89b2fb99164501b18b14ea315a8518383059f8a75", + "ac0c75d5673e0017e402ddd82a149ba757be035cc075421df462071ebb257ffe", + "e01ea970f5577f099155d5a19f20bf721153a286eabeb50ae1bc98c945f43503", + "680f73ac49511f0251b4e65819f03b20a77a0b41cefaca428cc0a6e32e8ed40e", + "be75347ba7576d1d7b3318c03c77fa80f53fa7370a7de423887292a29fba40ce", + "3af1b7c15cd65ebb602c8f865a23df37d7fb9d939a3296cafbbc363335bd9e12", + "cb63fb05d0a820de88475946c72830bec26dc29ceefdb68c6f9fbd83cdce6d31", + "24c44da10045f1d9ae2be46e90eb4fe1352f0b0da23685ced29436d0c72bd1d1", + "203fbf3def31be5abb2bc8c0dcd10394f09589b66a86eaa1d4119f99e2a975e8", + "028d6b3efacc606a5c9bf4fdca7a6b5fe1e28070ed3c453ac0e0c9ca703e8e3e", + "0c6fc6bead299a9d7bd6aba62190b9c78214afffba09f188baba4133e35d3cae", + "016a4e500bf25667c4e3055b5950f64e4b03f2f94f01a4a269bb733d0d6a81ca", + "b609b58174af8a740eabd4ce40d051170b0a2712c0695f9137d0280fcb859a11", + "16ba9d2e20cb16642186b24f7e161345336fd253958e61a3f82bba5c47a2f77e", + "348991797d5bca88e21ad10a6d6c277c929481e03acda50f317055a3e0c3ced9", + "dcbf3d2019fea08cc31f28995126991ac808afa48b1372f9eb624c0d3fc20477", + "7c198576c915f1f3d4b4850cbc8ae7d7f1b80fcd97aad1f9e06d6f0ee56c2146", + "eec926eeb822cbd4a8b691b39a44aa4fe634bdb1890a76de8a4cc0070ccf2626", + "838c7624dda6f4150fd2a21656d9e399ef83a13ac2bc6e78a80558e37a15ca44", + "8a3a7ccad5427f100cba64a4480de453b29390c7cbdba45d09576c9dfd9efe91", + "dc972c2bc110fcb770929a803513140db71e19297947fc9a0dd3e3d41d2defdd", + "7009b17c75781c7d4026de26286122b86f3d59b120ad1370ae80a07abc70ff84", + "61ee64518fe7f3642a12e2974e79a9139c36390eaa358089ad9a03c953879b08", + "20c5705dd770261470a7cd4b34e0651e2f125bb61c057362b9100d7d17828c56", + "c61e2480fe57d14441f37f7a2e1f41e0037d4b74ae7e038cf6e30fbadd1830c9", + "c5e4c1b35bef6e337ee5435699fa5c1a02523cc4a9bedf4248baf08a506da886", + "6563a884b68373d2eb5e7e7f05e82a21155adabc69da0426ade7ee33467a892e", + "9896af424aab6268cc071d14e0470b84a6b7c64e6b8bc981e51427b38d2cb44d", + "026c854abc2ef4d98de5071b33e6a0de23541a7217311fdb345b95cb0cab6d8e", + "8ac3c9065cdcd603fbb9e825056cd377ba52fd7b3c95e83ec9c44b17232ec3dc", + "370fd0f710d5274859c1f33b43049331ce6078a90bd7248bf88f12a0aaeee507", + "865cbb0aa9509c4903a1979976ac113908f901794a8fd2256a2a95930f454247", + "d52feac04cdc70bdd468726c684407f7f6af3d799323dec374fe627c55b76e81", + "a08520bc41edf5f8c03e2a1ac67418ce9ebfe23e86d56227c07aa9d72569eaab", + "0972f9b37387a15029101bfefd3072db28a8832251f750438aaa5aac08196771", + "16081634a36f92d9ca8e062820944ac514064b90eee4410530037b405ea0381a", + "d0c1ac4dedd71c4351146bcbcd31cfac29490217b65c9c2884f1b898e07f4c55", + "ae7e31a3f4542dc38f5751150f8435c6462cc3242034ca068229a4514f25c839", + "400b6a65f05a114a17383a5281c844abb5d7d7d2ddbb8db6e02032c46b598b3d", + "eb34634c3eb42fe587ebb7a0e183f62313ad78b845937694106284393ca11a8e", + "4db65d9afec192e519646bfd302dd786b0b4f4d48d154fcda17caedfe89d7810", + "48b8a1bdfe74eda83bf329ecfe6d54ff0b75b38e2ed30adf029d670e4fd5f0f2", + "64c42fbab54454739c68cd5c4358a14e578671caa2a1bbcf7f0a8e5d6d3fa622", + "4032a4451dd65eaaa95e94d9cefe887ffd8be07f24850fe9b4ec2c5a6a5e877f", + "a567a162499c97e305fa5f68413a028970f618bffe237f3e3e9bc0ae87591f2e", + "21f6e894133f5e5d4bf10d6f863c01c3614b7aa04a9d8ca0c4744cfd135b64c5", + "0e8de385b4bb9c530f939a3addc931cdc1be4f4994bb295b4e6c2e7d24adbe03", + "8a809bb5bb7c65c39d9b72a789d31430129f9766774814aa70a00a09d6626fd8", + "646d92f13a32d431d8589daac69989ba93c87b0b9b75241993280a33cee9135c", + "afb3f9bb84380bc0e5fe81a00493ccbda69a0584e11a5896bdc0a49e134a6b23", + "2865c062fd08305766c22126a1755ffd3d53399ecc9cdf1b1e979d56bdb7b3bd", + "9f14e230107dbb6458e23e05ac84ec392c8c6306e976feb5c810e4eadcb72a29", + "81bda7dfb457fd541ca09974de4a293d85ecb3aa6de015a2b61bfa110542836d", + "5191c62128367d20ed9b5e5c14dda16d4024f748fccdbf0b348cd79847b990dc", + "9cf80098c5e05004aaff126fe1a1640cc75bdb7b97b4cda9431bba73548ac030", + "fba1d20478f099b82ce3f142f47de53eff559b1ecf2171a19a0e1231dd33665d", + "100f4688e042f042e2826a74ed2884df4044845c0f2e43cbddb787c7e17f92b7", + "4444ff459b9d7b2672ffa722c11357120719053136061cfa6612eb8e3047b21f", + "5b3e32e3feb6cdd429fe2aac165449eca574afeff013f874b2493dcf669ec24c", + "0f73c3d47f788f15ce4fc60071cb56780aaa0498833b1643236a08b6e95bc721", + "edc2ef081d67cfdf1186ef85688f130f70af129db4c2a3b0e141fbc54a74fbd5", + "ec2deb93844080afe4081e899c3954f190db57e52aa7c91cf86082a1b5473d53", + "6e718973ade47325be669d3726dfaadd35300fff9dff553881cdcdc3ec0906e5", + "a1f10bfadb04f1013102e7e9ad38e6c96dcfda0add0b88d79e4f647fcafb067f", + "69af9eb7132ca5b501cd42ff2ed89f5f31b87d6e855f6bcdc1c34975eb7b2e10", + "1fd013299153c802d6ffb1d2e403d8ac67656dea6f46874ec3f94e983bae379c", + "87b879e69d0b93ebe450784af56e9cf357ef6c0cba17b4a682b5a3d7b791b3d3", + "fe808631cf83e0fcf8a172a9c1c9f489d78b1eb65173fd7881ce1be65ebeed6c", + "1ee65e513a0cc4716169745b50759407ea9ee093042f6218983d81b016940812", + "202597a5adb4451ffd7c3807f13093803535b3c6044b9fe9eb666f1e074b35fa", + "9b472da5a79e29c42553ec8b8433ad64e7d9ca1578bd16a390244c4687d2e5df", + "e4b58d5bbc873b38021d7c979bfac56e96aa4e3791f02468935ef85c0ca71aff", + "a0e38a726f7285293cfef3c77df20cc90f01c7d4a92c8531a023438961a5f71e", + "03420778e40a27a763da32db6599af641f0fca27bc1d6960151cda03853266b9", + "a4648d1f2d8dfec189e42019554117f6e9da3e298bcd74efb1cab11a415c0c8d", + "617f910b0355739d21084934eb2e3b8accef2feaf8e1088175324a03fdabbcd6", + "e32bf1f994fee54ec3ff1bd2ac550e5af2f46c5fc15f99803c5bb563046f9614", + "3a36a3a6986cf32ce192b6cb6d84afb9a8fb6093187379159edeeb6a891c7425", + "85ebe1763e44d1a30d05c37d1d1d4cd3c6ee1dc6a783aaa743e7aabf0762273a", + "b81c8d66cc236a44e2d9fe5e2eb142c773c64827990831f28c933b73968a0842", + "aa8e0a36b57577e0f9def8b14ee14198c5d41685c6de9f8998624163fbb20759", + "2559ea419d4241e063d75aa5f0244c81aa4c58e005913bc078c76dfe78e3d12f", + "46bd45fa72ddc3b4c3dc8925c1859b51232912ad34b49cc4c6b4258a0342923c", + "fe051768abaf94584e59cbd5773a2f01007a1cb80084fd45af5b31a691ce843b", + "6402d1a3744f114aa92c610d23f846a5227bf1c4ec2530dccbaaddbc2a508dfb", + "4e1ef5fd38943e06067f2a43bc10a38788e6c6d22148678f2375919995a0d91d", + "595ccafec4ec54b6ae2e7f7cec798ab109af18d0847d1c5247a832f6212c509e", + "4c143a5c34b7845536dd63a628a69a54858353ba06226fb27fc13a25468db574", + "6219dbb3e6bd0df99075c20211ff9aa0ef3cf85647f0b961063b086101da5950", + "e2b55721a536e540d5da3ada5585057808b7c5decc9b0b94973ef30b790c7c24", + "525f07e73576160576e8a95355defb828964f9cb9ce69c2916594bb41c3aeec9", + "d51da396a414c1424ded40788adc2238370ecc2e87a75f2c173253db340eb094", + "0870c1b40adad639f7a2d6d2e1ce4149dee0d60db3bdb4e0c1e11871a4306213", + "75a12665172ab7d8d55435f58fdecb39454ee02620f2e8955738506db4a70f24", + "db4c6de104536799aef5ff56635d1ebeea50cb143dd068c1844849a04f0acfe2", + "6d5e8c0497b81aa8dcc0549bc580e87099f8809a371e625befbd57c7f249ddc5", + "eaf99b9f9eb1be4ad4aa4c69164ba79f66d2b2746222b98abec406c4fe30b18d", + "264945a8a49f0b43a21cc64498a255b0eb74dfd92f37ee44c12f6f09d4e30bde", + "e7d7882248696096aab4c6b1152f2148e6c5e8315b2ce219544040958afea987", + "d098c46929f3c9247d7a0a3bb26d09735b5a8a340e13da05a7a8948727d5ec7d", + "1f0cdd19830e8ba862a67238d031d3c3d308c0c21ca3f6a1fb6e43ec444d5f12", + "17bc20567adc2824e22fd6273befaae85d9234b5edd94286eb1c71edf9269ebc", + "73b265eb444c46460f1ee1bf03536359c97cc21f36771b68f59ae1fb048b10e1", + "fa2ce4d59386bd66d350354aa1fed7940aed659a37afbefae8e989ae40e7031f", + "78e4aa45c5fd70139ae6434c2fee1b8a7a72f4ed1120991220ddfb2323240aef", + "16e00cd48e8b25e3de4e5d66de42b2c97ae8d6f519a4d48bd4e562c5e9969a5d", + "4717df6c29c085cea0e769003e6fffad78c72177269b45aa40f6af22974aa214", + "7336dbe4b20aeb50e1388ecc57f6e45f95d9fc55927bd9a77319b9e189ebb5da", + "5bfa656513abe2bb9d9927e73ced71ea883b2aa2c56a3c9ba600e46b1f98ff2c", + "130e8cdd0656cf9a828530bcfdd7e329668348de3ff96f100fbd561bbb91980e", + "ed3bcdee2aa579a74701beb0d9b2e163f979d3a5b75672becd32b3c94106587a", + "a4365c703892a66cdc0eae843d00e14cf4256eb16db9c4865dc97191ee55bfdf", + "c06ce22382c75adaa549c8ec55f5d20a74efbf65bee309f406caeaef74f01b57", + "0ef08b3effd4db105f3337e79bd8297d77ee0b76741ae5e0fa554326f5092c21", + "456a9a2a3c2f5da6150f732c466b0e4fe6604ae056ea8d92dbdc602140e1f6cc", + "2ec6ab72129bf04d429c5dab223d46919ce7f12bcfd29496cb48bd70f6fa04e7", + "ba53084abfafcaf8b70cb98874c890a51a56360eeb3d31b11eda60636a8f7436", + "cef6420680b1cd346950e6047557855034977e9a88653a35e5774d7a35b97a60", + "f7db7863a34129aca338e675a5581d84390df388da5cb0b521f2802ec45c35c6", + "c2a54652dc455e7ec1d98ed1679d1543c49a7a3f2e83e3f884c5f2ea20bb81cc", + "80650dff41731f33f93be9dbca3b6aa2a01c333ee3552ff13a34f0869b2bb0a5", + "e08061601065cbb782e9532110657d6677386643bf4b4058740c13ca96fb6d58", + "773c39c3abf1cde22c468e8224193979379970783c1c64e86de687f8d9d206b7", + "debc6d7db778ea3fabe5f7ac2319b6500a1cbc21766cbdc37a26204d919df272", + "298a1f679ccb65e4b024f8a9c5486108950a69d78bae58da87d5fa73f8663bec", + "bc0edc52c586a531c9e247e178e225f955567bae54e056a2fd7e856ae2c9f746", + "949d6c0e2c05b8dd0f5142d3e021ec620364472c5e5f1817cca4361c125bf39e", + "70e64e33b2d8e92157cf28663839cf08cc0923d7328e76e40b3ebe789697f448", + "7551f3b387439127aa74c46e1584d04bae5871cd3a49d0779dcf7dd8c65defe7", + "634abc83988e2668aea7a22008b575a7da115e2b6d393f4bb64fc45e37ea0cc3", + "5e4393b51956a5be8e125a1c5b73ecd45f7c93255ab57dd903b936e75ea88f94", + "81b58269af47c4907a9ffa39bb940e6d9c304587c80010bbaa6f8c48ce403756", + "5e37f1f9a21aebecf2b9c7131624422898e950b95b55716fc1baac0752abc5eb", + "9200f2f359db2e897ab7fa8684753ee152aed63f9778424ae413c757ebe99606", + "1921153db132db9a38c773a43e63a155feddcfe5b98ef066a9325360ef5637e5", + "70fd9728112a4a7de14cc7f7737001395505265f015c0a9119f3e9a5f0ca31a8", + "b40c0641a3c27a2a54958a8665a9b4ce197dca6e100720b8ed45eec2cebe58b9", + "14270590e10c067c12d8022ee7e3b9f282e91b723eb43bb6cd439119e896fd7f", + "1c12dcec14f6e9823c5044b1b2a20c57c04435f498619def54046f274f2a87cf", + "e73e63aff75633535affb7875c89bea43b846bbd52d98d76d52b330474a81bfa", + "646db1f40b436953610f6460682c3868b03ad915bf4a31e8ae3dc7ceecf3a8c1", + "91ba915543dff540d8ab8b0a8e6aa92b2ac9cc5b667e420e84505ce7c66bda3b", + "daca2741f721700fa0182b7b955b4abbb1f9e61fdcd4090bed2d11c0621be8a4", + "6d449026b533239bdd23b30adfebf192453dab3df4638ee7dc4945995d0a1175", + "77068a81807c8c0a2c17a58eda60777a9bdaa4038a08d81960efc81f83503334", + "d8d7a9a5dddb22e27a2446c13cf82fd8579d2c0834134ead52787ab125687f0a", + "23101ab79da7c3c30bf06a8f8f7516fbedb8446867364f4a478f118dd5ab5a75", + "a0d7ad67cb15ea0fe8404c272d305c056e14568592f47fdfa9c2a236372ef840", + "9b905148cf7b47b66317cd8f5438bbb8c41babc56c422db1af763d0462fe7127", + "6da0dec152682fa1d307df101c14df579f703532ffdb18e6706effa6da28a192", + "cd9c3d0f03605629fa131edfbf1b0b0b948a98225f61b786e85fa22c08e189bb", + "6f0f0b65c455fb05957c09a83b270c17c894c66fd235a6f1135790a429ebfd57", + "8b42838778ac9f0f78611c9b5608eb2588a9a4ef30163f0f61c024058fbc3607", + "9a195f6337d92f6c4ce62aa5b725b595e6d824220afa502f807fd9ea78911435", + "084d7daf62e15621016ffe128a8780a2295f309bb513c628337fece66a094532", + "b69cff5b16d53d4d1df7a3341f5afc3f93c966827f7a6695b92e7a31c9a99f0a", + "843a4541dfb9093815894cc1921f5f710bd627a562d46f3e6068e7c19a3baba7", + "5b9c670b284afff86f1aec76a9b225751e2587aef24c0641952b473d1b7ce78d", + "b2c8913145e84a8c8508550af03e89f9c117fd5b4f65ae7dba470675d733c2e4", + "743590009c80d1d7d0100fb15e254c51e672805c3a90dcd59521c5359c88f0fa", + "28ef882da6dbe4e2f7c38388143717d5232298c565247f25a767a0aea9d8a273", + "cbf20e76076747beb2ddda4bfab619c7427e6425c6318bf92c2ad05c8e0f6be5", + "16aa82c93cb42c81bd5e81cdf3a2f36554d9c9a63fb83620e0f6aeec4ef5f04d", + "8cd08db2f7adeb74250414b953e9210fc0936051701287de5e1447537c207745", + "7a61d370ebe193f6e7dbf7048e3c208dda48896172db636ae1d0b5debb97fa5c", + "f0792961e49e4ad389327138f1827936750b6551fd74339b9c607b967203b29a", + "68d8aa4c7c185c49014a361e95fc86243815e99e663dbfa2806b6b496d3b1fe9", + "37c0f81ac79470d2f74347fb0ceb0a91162c52ad7f329b5c9e46f368238a2133", + "3d67ca387752db8696476c93317c3884ac543559b1836dcd57e939aebc3fe340", + "0fc34fb3dcbdac9d1b47981751fc916d56a096a50f93782b049d812bb868edf0", + "370fabc2daaebd45de6ca831e1329ffdf8951dbf33957e7e6e40363f405406fb", + "af85b496829e656aaf4d5aa7ac3122749f3f80aab4ff08dcef4128d045ea6a9b", + "a7e35169190a5df408ac253af4704e81e31415cf3b6d1e041d00aecc5d1ee1e3", + "95e9192b43ad71c7cd9587ba3d16d4da415c2afab621da0161d5953fb3131d0c", + "d43a04536a5ff7c06891a224e55c8f4773d7eecfb257bd16af6a631c3234a76b", + "59c11563a59315899fce1145344207ea8485d0ab190bbfc8c43516641a31e92d", + "1990c87c7282998fc89ea6282acdc0db880c659904ecea24fb468cc7371a57cc", + "d3df92cba0b60619e47290ef27e36d0f3462128c6d167e6490a268434ceaeff0", + "4a2e4a3b9d68e8e152ebae9e907b143c573ee639cd15251604b3638a13b96930", + "cdea2611189dc5d1a1415287018effc945405c70fc71682dc4878f97e884d806", + "7652633ba8f5e7e3435d262c13b813b9575925c8dbcbd24165b577a1b9ab4cbc", + "06df027be9c0ba9017f6455aeb81cbab977a028ba68e06357df980b01f519fe3", + "e031c4447a6a03090d7d94d45554d37421ac02f9fbea8c58c4b06da3ac7e1f97", + "9cdacfc10814cfc9822f512940480f6bdf68672a9c60e7857bfc795a9b81d37a", + "8ed650521b882192deb40c456c97bda7f5539931db5f8dc209254cc447dc5e99", + "559d390b7baf997ba6891c8a2cc7ba5cbc806802bb49dc89095d91f16cdf89d2", + "c8fdea72d561458c089106af28ca6d44f18dd818bd0a6f745c689d0cabafea39", + "1c7b9ab5e5420546f2fc1ecd9be4e424547e3f5d491453f757a658a3622371ff", + "7138fbca9f16de281a4aca7b7ac036c02efed41968658c459472a19ebd8f6772", + "6d588565ba28d755070ce79078ecbd634b589114e106cadbb0e4cfc12d5d1bd0", + "26665bf8ffe36c49dd25ad16d681c869e305ffe26b2a55a26a3cac7236ffb001", + "e8e89d216c511ab2ca31c6e0e845681c2c6d47085bd27149a6e6c62a035091b2", + "f296903eaeefe437c389cd5dde6c969ed17608db4a4e4d2f97fcb3ad614ce6b9", + "9aed4b6447e56a562b7f1b4bdc5e0ac723f37a71ee3b3b1cf32cfd77afb5c27d", + "65ee3dbc11bd6d546a41d6c5c186343e26b6ddfead8d5a50ec19080039d6f606", + "420d5c07f4bf36cc6bbb0fbf763f76781dfda5d6f6cdb9e1c7d569ffa706c6ba", + "e83ddf0f1c1d535b42f1df3e8466c041a2ea2479a4b5ceb4966044d3b4be71ee", + "1e388ae580ed1b75f5b6aa909393fad157b0c9381f1fa07b7a131c0c0b04950a", + "da28056978522c9d8730bfad37a9098e3d8d81abb4505003494ef32e25afd7e4", + "15125c5235171886e9ac7e92f50553def6f1404d05e12250f7628782ac702640", + "e2c6cd21938271beb4d21e7973edc58b9eb389733a9f589b60441f1dee4e60c2", + "60d7dd25ec168127933751f4b3a852ce2c4f5c2372446bc2a38ef6fa530ecf48", + "b646b372c370383fb7ecca111eab5269c891bc70ce63adf8430cd3df3d3ed0ba", + "92b3fee9cad7fdf16cc513a25e6ffdd4d6de18c24e28672d53c1f1e9bc324514", + "53d2e29cc74f35b5dd2b81f6183c61727622c9b9f3b6bd07ea25b1822f1de2d6", + "41331314c7d9ca91de0cea153bbfbbff739fafecffd21ea771b2d23baef49d78", + "bf5b36e794d7447e4739a7d29328e5223037fcd9042aecdf00544ba6a6bd8d41", + "ad0148e2d16f46e5cb07a7e4266e5a2d3b25a7afb7d671b3dbedd080cfd2d01d", + "6ffb64ea6949bc1e4885a6ae5e74906cb925bf99c682195f2a2dfc75291af7ff", + "78b13732cc85cd6dbcd23791bee83e1e4568f6203a2fb26b5a6f11ba6f93d291", + "4b50a984a5727b615302ec21752020b2b933949574bd70b8dd14a1453acf65a1", + "41d3bd59b0e9f26f338ffaed1a6a8f8714563e7cc8cf5cebef2c64cc45c34e20", + "615f6329d5003bbbab71d578054d7a7a17bb28bd03bac66504c169685487b78f", + "ed8f9d1053a27e7980f2488949eb815225c269e71404b92ab69f268dc5a46b89", + "af25d95fec3df259920a7457a2c180379562fc9ed8a964522b98b697c03da6f0", + "cbcf3bc8360f32b189456fdf9a2d23def34c07d40500fcc365605487ea488c55", + "08bb0f2f4c2d03ebcda779e6fea1fcb1d9c0af260523290839ae5c2d687bc52e", + "aed2e0e6cbcd04859b68ae2276a9ee6f022259fd0098effb856f048e0b95b40d", + "752000001548c25a66034ac656134196902ee270998af35fc60cf46159a5ffac", + "e8bb3b551ca8a90733cadda38ed411f35ff38d26f9231caa4a5d821390370a96", + "b1f1ceff47a3ffb374212b21a5cabb734fd9f63360e9972b7f3e0292991114fc", + "e1c2a463a904376020a0d4324b434f130b9137257f06281e0a2f93391a5ac102", + "2df076ae2b98ba4f51aff877ef73bb5bb75d5dd2e0e6efafcb15ef4ae19941b8", + "6d8aae523a94b2f1963dd659e7e1b0700bc2ecf53ad1f676c2271984155c980e", + "0252e44f62340ff77c721acba64c0c6c6a5391fdebfc7c62bf5a83466da9331b", + "d68fc4feb86574cc35aff7475b6fec99fcc7fdd45cb5201b7c9cd4f3d6c26631", + "7a393e5903d02b766cc4663cc925048f12e5ec8622c0482e3c0aa9c8e781ea08", + "536cefa1867ae7e1b8f77d9f1ceceb75895d7cacbcbb48ff03696b3211f07fb0", + "f04ad48e711d2f82f2cf11e544187d5696f703180d3580a3e112785708407c1b", + "ef6c12c5b1007f58ce41a0f88593549293a3d43c155c7841318403fe399195a0", + "dece9bb99ca42a5f7767cbd0c0e955a5ca0fbd644c9c8ce44b5172282f79a2a3", + "0a65347b15cc4206dd5f34538488a45daeed82313969a3ce39c4595214376eed", + "65ba1f38859a81624b64c7865a8db802d4d098f755b9c5e482f8fb9d5fff410f", + "3c6e0891a0a9718273a5f60edbccecd213f1b61ba0003a5451339250994293ea", + "5e52610b0b033da04505335ab39bc8be7917f1c593d32141722a89976525fdb4", + "7ce2a3127519c1a3aa185c7b98cae675aab04b21c31c9fdc04ba2cce8fd72b12", + "27f7d91e3912f90992e1db6fff8529b2120f6e694550b9610f5d8958d72ea6bb", + "f2c787c0281974485a42ec47aa8e4c87245e9f92dbf8973752691363363715bb", + "44fd3f8b5c1acd5251a1b6bdc3e1c7bc1c88607ee6956c39f138c347f9a010dd", + "fa6ddb2aecfa6a2e5967a704ebf9acdf3d080d66c8b1f1af8dc8284185485719", + "d32e6503df1b6c905852adbddc2f3f90569e728fb3d93aea80264aead367f6d4", + "c2b1222d69e7651044b573250fa680606c366ef312c6267f693ccb1e77b9fcbc", + "32e6eb30cc8c936993575092e8fcdcf8609e12eb3ad027f7675a4b521b3e831d", + "ab0543cf0d052e130def2a692db0beff2bfe53a06f58933f48d70004f0e88591", + "2fca0e6f86aedce57a2c63ddb38f715da310722f6c427b3f12c0d74410193236", + "93cbbad91f7e4f1d4bdaed670e9a07ef8c18a3a553c55f4919ee8c5b4050861a", + "d5d06ea5eb4d4f975ef28e4868385fc95af3b1546543ae0b156dcfa2dae59cf2", + "72ab3f9f6fe35a43ef1313fb2594bbb4929d88c1a6a0bffad7e5ca069a8e852a", + "fee733e95eb34bb52688fa1e8ae9f00d0410e7d4515936f5f1cf98f23471fe59", + "8abb0532712dd4e6f754f9afe25e7860319cebe585840b03b4718b650d929a43", + "974b0b8e5f9984949502aef11312c5a6d387da33e9cd707894497d50f6505641", + "c00dc2431e9873449d39a16d3b166d45dae99761e0f68f7d1e739e8153c86f9f", + "cfbae62d7ba0a03ff4963b63e00dd66697402507bc483bf7a171ae62fb3f6428", + "ac9034571eed2fd4c33971a1264165502df2406f6de296cb69ec3095641eb41f", + "db6f4f97419a7542b08d62553e00a63342cab3902a947ea6316b6274d67f362d", + "706ab9ab74ef2bedfdf6ec6929c8d020b76ab361965500006fdbb9466c53bc66", + "489c1e0af6049db2afa872b9132552ac696ebd15d1c6dda73b1f3484829bb815", + "2149b36a19ad8f1db68977d6d7fa7a33a9dca3e760fd41140664b3e41bb725e5", + "de44b31e6290da1c8a2261732c376cc7bd1d821f4fda0296b7f8aa8742ee5a87", + "e3413896dc1919448cb1d0dcfa86765ecb82d6621776bb68201acbc8054f2a33", + "c8ab545ae278d283387763d78b9f5be691a23306081d51e8355e32516b6cfeca", + "142f9a29ff05036d6924730cde701ffb72279e77c561666407839e1115b21099", + "fa30008265264760f7274ea1d887d2505567b6fe5df61afd4dfdd22fa4921f2d", + "17915dbb35a08db14615893ffb091c6a2aed8c3f00daba409b41e93eeecfe11e", + "41e364406c32d18e7e4a1cde7ae78ea8e064bc827abebbe135594404ff98a801", + "8eb2f56deb0b59fa83b973122016af4f8d00627b8abfa21e4c8052fed1b47843", + "001b7544b401cc27f7bd4977544825cd874b8b6d92b567c395bb950c80636062", + "754cd48bc980bd5d843571d9a1cab6b0eac55308e558672c0561f29401bf5080", + "97d51669ef78ad18c76dc066be16d094c664d52a7b8a85138e707b111983c94c", + "5cf3624baab6b58da3d5444236e6256252fae9c2297e6523cfe43d09ee63ae48", + "8f961b304868dcfc3849845ca17f1b612d98cc7125f715baa9eb3795b6dd565c", + "55107fd7a0f408383d506b15aa77dc82d9f2a9b45070f263c5e2e1aa182d2bed", + "67670968cee8ef566a9ecea0f361f6526b05157f7657c3eb1cda472b76e921b2", + "cd0534098535227e74189390678af3aed71613f097d5ffb2bcd589ab6855acc6", + "c2efd857a0e2dd4285ab34342f59dfb459d61060ecfd9566bc2d508b0a96c080", + "fbb76ecb3cea4620f90d7aaaf8956ea80159c5c696c61dd593eca2e43652401b", + "d881423fb21cb9ccbff071aca07acf79ebdbed4db5aec55b68d35f18e0d9ddc8", + "c8777208ebc36338fda6b1d639ef0d01f2f9f6184e09f06499e879e87037cd7f", + "543b16509ad198ea5b58cabf56b67a5f2d27ef12ab51209039c919d10ea18b0a", + "a377b311bfa42bbe902c4ea43bfdfd65680b03bad1589a9a2c7538a84b6418cc", + "8c22db2ab0abf0a51cfebd9273b3e1d8304ef81b933a515721c1793593d5e431", + "6a5c64b37716f614c0438d77c4d9c85c0ca647224973d11987e7e4259b2a5486", + "2aa6775109aec5d8a4e3d2d231655e26c36fed8f08692691f203271cbb1c2c9f", + "8a5c93aed4329f316441da2b80e1f9b40386f37cae2edb6adcd243a7e0b0aa0c", + "71221c170822e104c81d71a6222a9ef463f265a305e2902406d1640604e11cff", + "e44c3116255351ddda3870735324f89dbe31a2b9b12fe7f7b5f708f068f2e051", + "cf9c616d916bcbf385342d376308d55bac236e624e7a67fb7d56f1e93699d9d9", + "ba8070e3f31e575d2c12b54cb33f6695d84f2ec5ee262bf7bb00b3d42fcbb32e", + "644a888ccea4f489de48d1361bacf893e435f257102792bdada5fa7d2829f8dc", + "5a2e1c65183e8a7f7d2aba74d0f7d9ca87bac57178f3e76db31a7c35a5f15df1", + "4d6e67c441a05b086dd52ca5a637c653c515b48e9a349a67d138bfab2b9d5a53", + "2cab9cfe1d836b577308f450f9508d5d1d14b0bf17574a76c63fdb5ddc036cdb", + "f5bfbb2ca42f683d1817808ca9c3f575055924184842c9532320557aba32dfeb", + "1613c1bbbdaef3a21392cc52de0e584ed44870cfa36a3c21f05e3cfa11b39c54", + "68cc76781c74037fb600efe9379a0268e5c9f5dda53219b3cd123357f03aa38f", + "8cb9d5b65b66532ab3a7f595279066ac749b796a5ec7017f3b329995bfef0546", + "28800eabdbf3912835913a7a5d292d5b4333df18bb8a67390780bcd183fbfae1", + "2ba4dbccc894865554a5033535194450a4dc7ece64210b7289d87045ba9a0794", + "175b4a1013b4acdc61e6700a57f521ffabe4631e7e476434feb80a68604660e6", + "74adfeb94365c8c2266afd369fb6c64b9f532156312b79f39a99a21f2afec7cc", + "51b53bd367264859ab5b0db32869ffa1d52aa22bbd0886e391abae236aa526aa", + "985be3f9b1e131b980b961e39646391becba83d9048a418ce3daa55c20b52fa5", + "37c517c74bf94093594afcce1c5ff4cf490866ccfe3ea156bb76f8a888cf3555", + "f863a2266c15742922894aa98d4dc9108a9f2bdca9931fc9f7241d80f202f0c3", + "8fd3ed9a17a4169b7b00b8c24afc1f0b175fd2f16a978c2c3554b1940ace890b", + "d8d19ba7eb9706fa81de244063b0d32ac72228b677abbdb8cd61ee14cf6918f4", + "28d34b30230744828ba8a17f6b11e5873ed87eb230092c03dd436a59af7ff809", + "755798d851d2f3534e543d93658e48231df185a6b98f542099f9c19ac8dfc2ac", + "cba5b051c6ea449e10344fc997b935c45040e4f3171a66f32424963a68a96154", + "3b7b1eab0353f6a1f0669cae1969b69282e8cc218520d6b9b30b6a828e9a1020", + "c15da8b794cf7313b6e82d299ebd0e812de6c9aa9213783de47c64820a34e8db", + "cb716eb37635628242ed2043e7a95f9ab627ac6e7f59e213ecd6ffd2786535fe", + "21bd25928d958796e22d3e255e09fecd25e9d8a771fd780e6b86b660c30f6b4d", + "a1067508625d48530e1b9a41ed4aeaf597350966e857dd49f8105dd11f2ffacd", + "963c70607b8c4b2cc64dec627d7c3dd26a066139be1b6c5f07c42601fb604f63", + "805723fae5afa661d3403d4cd4af15ca885363390a0e6f745c00a2b9b5e85bba", + "bae3632d659433d8e0c37dd6e1d415d615a6b2baf7881f4d9906166d5348ff9c", + "9f68e509597fe1536832713b5cb15d8d2d77dcab571dbc9d9c3f84d6ca13da9c", + "e57309c1dcd59363c9c815f0a5b2d0a0fe6b222fd22d32e09b68628ac190f073", + "776223f2c92c1b8f6a8bc602c0dc1bfc9bad132955cc75b4013b8d4d655f5227", + "8391ce3c8869dede93a92852e59537d39a71fa37a9343db6479837bd4eab9b57", + "66e4f688c9ad85578b07e148bc01f8beb7c8cee4d5e118d9dfd28f9aa41b1a56", + "430e025c65f14f2e32cc772d36b67ff6b73e58c378486ead85721bde44e924f3", + "306babe087e8f8050e9ba21d41c17a309179af2ed44fb92f6588f2e8dc2b7af8", + "ca64c6001d42fd8de6848f366645fe07032244f16e3fd0ea6bead5c5c6735326", + "def3bc5a6a48cd38fb77e0d431e0195b6b2e252b2f54d92c2bc2a5b5a3acd969", + "3c82bcaf5a256d3244cf400ec2f1c0c7d558f7f49a9d6979eb9c48736a201f94", + "18bdf6466d9afb8f3371b464562aab1a504b75bf8a3aee4aa32489b8d3d77df9", + "217990652dd1f40c5cda918ff0ac61905bbee982d5f834c49deba3b1f4505d14", + "48b63ee6996caeb0c0d15369be2eeb173a54422b959824d42f166da9957ead33", + "042d7b0661ff36ff96d6738c8a110e6d4cd31464862527df7983d86cf99a6a0d", + "7bf74f8a3df521e9957a7b4729f8b14d0b3df0f8305c6e590a95f639f35fc849", + "2bfdaff0ff733e4df7f5fef79ab61298725c7d7a067de0716705be81b423da97", + "c106a0512eebf13de88fe0d1fcaa9822d6a4c23a0e34e49252dec5f565412df6", + "5044abaa4cf17524653aafe1da18ef578e9ece6839ed2c61b6cb5fab5575ba13", + "6ff5f6e0594626e956d86cb41eb8746e8d7244df6784cb16dcbf597aac6a2691", + "305457e4c105c427af60a50dea913f22eb045daeace3c7555ed40b0e0028b015", + "d05c7b757773ee7f2b813fafcbc96e6cb4209de5dcb65f57d1ef2bb06fe5659b", + "9efeb54cf900578976c83ffdcad380fe368c57d10c06e1683db897a72bb06eb4", + "c5bde191c00dbb77bb802625826b58eebace1f4fb63e1f3c73cf92991915ad28", + "d738615f8328f651c7475209c63236c1870567ca2591b28bf89f4a9501e512fb", + "9f06b5f2d3826d3b9c4abefdab5793241f97bb5bf5bd3149ddf51a1474ceec9b", + "81312ef94e24dafe27c9a36979508056b39f917991eb4cf6462c793e8e2a78c7", + "797ef9a50adaf1afbc7d2a3ab4309df283a8cf5c8466c3a7b8997ed10ef119b6", + "e4c75068f07f04b4507dfccfecb1468f28da007df81d4c2f3e644d62622858d4", + "76a80834213a721b993c5cf35efd0fb1b50d5308102180452e7618f2f8c6742f", + "1087fd1f17fc874282938afbee0dd97b5648f1c45bb15f3fc9371efeee9cd632", + "43dbecd6b9a07d681c2ca08c62d61f8ff1a2ebe8f312953701d05d5f7c1a37dc", + "d3549f5262e19333919e8badd82fa0c6e80c841d10b0a4cb53361ad8189aab2d", + "bfc6f5c82e5af07480a3cff8e19945fffe32b414bab6fc5a416680167c7a00e5", + "620c973115086674c7c908b19baeda0f115e1b56f1110110eeac4f606fe2f790", + "e8d75558a3d1adb5cda73fd16069c169709050fbc5ad1168f20d330b2af3f4df", + "dbc33ad539d4cb663c724881e2fb8eaa86d9d941e7f00265269259ad0d49abb6", + "120f8e7c35d01fdd184627045b7e10712a1acf64ebe3f9d06b36bcba96e65bfa", + "c86fe481eb9d54c0913fffd633dbfe8e70482c4c529569e0c07b1ed2a8769502", + "19acff77f99874ac0cc472611cdae0cc0cb9cba771374064db6d3c9ebc36ded4", + "75391d1183c4d145b5797de449714caf05eadff99fbc852f8c74bc12c60916b9", + "8c49bd595a5391daa14f5abc4c7648fd82559f5bc4d8f74fa66659fc37fb2f66", + "87ff9545a38c60c67ed8c9e346ff777d85042e966ff626eb9167b66e5eb4d7d3", + "2a56338bc281f7b9e191d682502f5140504884faa133d3a1eef29ec62ac7606d", + "2e9246803365b0c32245147190360d62a81b9ee34e03a3f43d4647effc6d85b4", + "7abd2a1e53652d8659117ead20a60819743855e052c155b0761a7864b39cb13d", + "0f98e2fb267cebec7977d87f1256a525262c07cb8a5bb946c091741dcbf5608c", + "926b6b46d61cea22badcfaf5cf805dae95d91c7a37a095c19b1fd7cea2a0ac81", + "e3461b92efcf369e38cec04daa8dd2d2466cc310419ae1523ac4538902a43abb", + "fdbf03a971327971d30d59706a19beca1657cc0a7c2037dddf6801b70b18b92e", + "7440a59f6de6eee9f716c121b068567f37a820e70d0586f84191ecd9767c466c", + "c6eb4aba04fb137dac05aed834ff2c47c822bf873d36b96db31b89760a157dc4", + "2e790c21e904c0984fd8710b286973077077fc8bb47d131fe74e66ccab909d36", + "60afb157a8a135736efdeb7144e046f98f53cbe16089edf7706b8d59fa8176a2", + "df1f49b6f09da03de2205d43f61ea0e809cfba5089336a2a24c8b1976ac1acde", + "7f80a2d28201f6da6e4959ed5f2ff4bd605ed7ae6580d0bef3f8ad958cc3a4b2", + "efc47e69d5e8c9b7ad0d6373099996ee4edc1f990abc24d7f9fdcb6b6c585c11", + "2a7342c3d7c88a195d1f1bf741233a6b368ac0c5830af524a7873b76decfd1db", + "740586fe9f5bceb9234fec9542b7797c72c17e868b312c91bfee6499f1edcf3e", + "3ec412492ea6d7cb36a37f666c5a09260ce123d87b41ae73760fcbffe0ccb88f", + "6da1b1a5c3fe2284bdcc2a35261d7b47109825ddc54a03cad1b14a2f4ba90279", + "10c9b7f82883fbcb522396f3a96c2fb50f9f2f401ae40ca4016803f36e2a83aa", + "ad3f4f7b0554c9929a602688e8e562507cbd2047e660acc036c65da39799542e", + "47c33d36df19d2a0022c70526b987e1c032a7409814a157e7657d16989cacb50", + "03527a1eade1eaa9835383fc67fd2ae87db813dd3c748fb874df79641ea22ee2", + "1f39098708ec17df7ada0a777eec888fbfabb40cf760bce3ab68fc2d88e7f15d", + "7fc8e754a85462a8776a290f64e921f200d4ad2b549c845011a77e3ed6fa6a9f", + "2a205b145e12ce902a6a82ae5cb2d969546da41ce5dc399f681f459e1cc4c2bc", + "eff5af2034207aeb3c06723fbea520102ebb7ec61c4aefc297879c1d5e0b1e79", + "3eb544c95528b41b737161d8b969667d0a0885cac43426ee8e8c38a8e6e94aa9", + "f099d39b3fa89f46a18ca332bc8f93c94ca3505218e0b638cdac76fec1d37e0e", + "436fe56ad8bc65d5d6123846b386f7d54fa47930fafbdd1dc9651c5689e3decc", + "4653f8b6beeb5d43dbc04bff659a9a5279eb98b39802547ec6310f3b5c4c6dd9", + "f03d7524fe88fe6f162bfeb9d988d7ab19db13d737351d6246d7a48f94542339", + "433d53fe42f0540df888db658e1a662f647f7a13394bf186664758c91817fab8", + "d573f2e8519dc7c4409afc16696ada9549adb0330c73d8965cd2f9b3e8bf27b3", + "c95845a78c378a398d2b9802ef69c7aa48fe5c45856615bed2e5d98cb7a0e018", + "18ca7b4b8c4be58f810431be2ee726fa72be8a7f8fdd8e59da304cfae2cead55", + "1ad2caf173b9b659794807456a8d721c8b0bf546bf94c6a284e3b8a1435d45c9", + "236caf3282cccf1464ae9abc7fc945194caf4431febd80b504325f9a459f83d8", + "55660f19e7ed6f78c9cb2224fcb3ecea3f53c5ea876bdacbdc263948201877f6", + "7f772857696d5ebe5f491cce60943e294842dcc7de6792899471f23d34e4eba6", + "298fd42b1b02dcb9b90ed5eb8d68902fa93471773ca68a129e15178403d12d48", + "767045985b32ed4bca6196f19f421523f3d87b54e4e46493a8c0a739ac99313a", + "3fe16c35d4b84f682b50b904887d44d32a8f71061488d22ce2e1a5863a5c3354", + "a84aa5d02717f8eddf81e0a0b2bf89e64a8d9dba0a695e66a7e3c2bd9bf4d668", + "408fd7cf7402e6dca0395821cadee65df2829be94518d7f3a73ba10567f7d78f", + "c6a21ca21534baf90301c57ff9886cfe8b1f4ec2efcc48e0e54858ec486d986f", + "43741a2a66c0a324c39494e3307cad41186ea305c4d24a1bbd144dba0cddc9d6", + "9c28b3b644a284c52a41a4133e534c4e731d9a10d8bbbc40a021103666448203", + "9d0e1a1445a11d7c864322864b64f804bb15fd0ef3d69575c2fe17c57162ec4d", + "d6bbc6b2810710176eb85296cfd0a9b8dcce5f8968a6119608a26958c4926f33", + "c3cf02cf20f6c57808dd4e0abd3aa6c567c5dc9dcb0eb725a6fbd860500670f9", + "deb8ac90678bf673cac999a4f1d1251c3d01807820e1a2e1322748f15018bc90", + "7378c2697ad65105371bec1ee5f921a2f3d00c2101e37c1c9d429aff13e73cbf", + "bdb9870cce8addf4a05ba932e1c1a5dd5b10bb6e3055655cf3b62a918fc297fe", + "4896c56bd25953f67a3a442800517779ae138cff8815b413aa26ef7c91618f90", + "1a086e00b8818947f23a7043794155c8dfd94fed67032ca40bdbf8049ca8cddf", + "68cfe62dda2538a79393ae29dcef235cd941cb65f8419d8deeed71a40cec2b0a", + "357369190003cbb2cc6908bdec86c3b942cb5a23865dfaac6fc1cb53476c2cd1", + "70c5df7eac02e6a6cb1eda60f0a2f4c6b337c304e4a5de984dea1320a0811d5f", + "3237263a8cbe32ed07081dd7488c08f2826c6b30556bcfec8a86c34fa0c9987b", + "0f2e8d93ea5764dfc3837ce0593e61d0af7d2290a5fe66e43a3b3c1dfa233baf", + "fc62b1b5e57d0cc31cac1e75912f001401de94b359ab2a9982d188cd750ac768", + "03387028bdf50d1f3f4afef3a57e64c2ab16389364c540cc03b74d6176f348c9", + "7c76cea054a80023ebcf5b97eadb29755d1488149fd4397e224b06bd04c73fcf", + "b823dcc7a0510e0acc6fef25fb554219383072c9091bf7683c89954e28c9fec0", + "e573a094f0958e475bf9f5ce4e6642373df1bcee3680e3fbf27edb2881f0ffb6", + "99633699c0690266bbadbe7006dd0538bda84042c2f8c495d1f1e011c62f3205", + "34e9babfd3a0d22cba6da5f61a902f4acdf71e7bf43111d6da685eaf01f5f469", + "939b8bdd2dd6018748afaf3a2fddf8b5e3fa01aa7eaad46e894b15e323e330ca", + "83a2f0f72a06931ccf8ff29dcc2c720059193db0553f722935ea8e683f63f4a3", + "c3b25057058d2306fd92d5013f9fb9cee9ae84c0833c3801dc50dfd0df9ef15c", + "04de6c87089fd0b2f2cf83756b059a017c776482c4fe1c22f6f9cc12b945a1eb", + "aae0eb80fdb6ec37028bc557b2afb47b31732401405a33fc8a47cfbd774c06ea", + "3d68e325ffd61a4676133acbc649d13dc6468f6f98f8150d47238f344a4002e4", + "508815370c44420511c0a91b5047eacf43dff681c6d3ac3aac6d415b26bc57f8", + "00b034c2f799dc25a831799710d31035927f8440af376fc94edaaa425078b789", + "e7019d1dc9b9640aa0e481ba1f01b24a3ec40cea55cacf479b428f637d967719", + "03206e63c21dc51412a03aa7f6a7acbb8dbfdddff5405941c5adf82f371b30ea", + "30e835fb518cbf6f1c70750a3ec872572649ecd1796432d0fee6debc84cb584b", + "eff18470027c56569b73d2308fed1ae46fc3426859e3507c292e356629ea0da2", + "8e74d8281a076266018a45e431b130a59dec429d2d901eb320c9f4b8ffaaa67e", + "d511db93dfb3abb9984dd2d48ae77e1a12b72c9578f764bba9950683dd252640", } -const mainnetPreverifiedHeight uint64 = 14267520 +const mainnetPreverifiedHeight uint64 = 14390016 diff --git a/turbo/stages/headerdownload/preverified_hashes_ropsten.go b/turbo/stages/headerdownload/preverified_hashes_ropsten.go index ad348447cda..c79787da17e 100644 --- a/turbo/stages/headerdownload/preverified_hashes_ropsten.go +++ b/turbo/stages/headerdownload/preverified_hashes_ropsten.go @@ -62558,6 +62558,411 @@ var ropstenPreverifiedHashes = []string{ "860e5439dbc488103b1f9c40bb6835b0261f15936e7b6be010401aeb8a4f7c72", "fe3443b5d4e65094ae4550ba1f6df926b2cbb9792cfa102a40a298f25d0d8638", "21961331b176e969b8d0d5237870731dd952940e900b94ba8fc07389c655bd8a", + "fa5d920f1886f49404146d5563de833d2b48f48fd17a13879abd13ffdf8a8d85", + "9ed07ef3633a35f3dc3c3d0a6215f894a825567cfbd88c0561312ccac7b432f1", + "842c5427cd058078ff63fc70e9e61675b9319a960e554f0c80006ed64d253e81", + "83d27f2ea334bf9ef9a60fb4b3d1a0d4b8701293fdec9b8a17b15a9a945068a4", + "95694e10177ba6ed542eadec1cbfcc5a8c6548735ebf85daaf7439dd41556b59", + "f4323cbfd60ad25a1c64d46f63367564275c645f407dcdc8d2eb232b50033483", + "b9f7cabf27981271db2101dda6b8c7ac2f3b89f24a75cd5f3698ae016fe40b46", + "80e61e85b2f7752cb850cebabb095b73015060c18f165bf84a8b52959db1a93d", + "f39dd0839cdec07a6110544851c6cd4bc1593f1540a7b080cf3192b4f92d28de", + "c806ee7529d6292bbfd1a7fb03744476a3d71e14302c3439d993b1927739abca", + "42a8f5362e6a1971614e96f330e4c01ac3b8b50e57a47f7ef9a108c4872dd16e", + "8ae0b938347bab73598b8c166c567756f8a6877131cb5b579094b5c475f1dc89", + "74dfacb2404a0b00f9e4ca92d9dde54d27cb540c66fbd0fdde3af3fb933ac7c1", + "38b70eb55e0cceddc226ec49e86a24eb0283e229b399975f3a28b72f74afccae", + "3a7fab847070ba977d96ec839463910ddf0114a80bbd9196f6f3d13201f32f01", + "127c031453561b7f92eb8533e19afd46e45ee599095015b0448bfe2a632d9c0e", + "ea4c2c17e0215ae7ae088b06e36edee80c5ad68a1a77290257f489976ffc7c3a", + "8258c239f09d1edb6d09333ff39bd20604ced27864c93245575f1e8ca18cf196", + "d4d31753a63e6534a2b74b8b3e5a528a12b2579f9ca27e80f33fd15b7592956e", + "d2efdb37d9358e08d3a8e85de12de93fbb67a5e587860ec41fc43e4f19b3973a", + "092a7b9ea5597a9530e8d63db13b7a2b04f1d47f3c74592fe188b108585734a0", + "868eefdc59c00d3580aaab28ad32dc342f9a1cd99d73694080bcbce37b6e9919", + "aefa06c1ea3e22d2f7d3eb8aa96f5aa55d53478f1075b154c7646d97e848cae3", + "3efba93d90c36166f27793c2d1eef2ef4d83593a945d52780ccc4ec4c3e5b7d2", + "f520975a1e851e3c1e9677fc6059068b9c163ef66666cabb80e0a7b52b61cc70", + "345be0ccdb75535e0187b95d55a896bf22a2ac53535cd9a1b79c0c3a73805b2d", + "9b1bdc4a1d6e1d525c3b88c1b8599ce25b5e166bd08be7ed8ad6eaea3de67b60", + "da2ca3950943af52f3c7441c1d21be8ea49132ff9ecb53432c8aa1efbd9a0b43", + "cdfc717d05cdf3c74a6dfe2734b9a094fd0abb7cada882151d88f797277ab5f5", + "521cf2e8471ee283f10a2155eab5d4b5ea1becf02519fb357299d7ac6e5ccab5", + "bde5bb31048e663ee6f9417eb284ac0ee0f49441bf3bc7771683177ba883c2ba", + "9f78460d1f48766e61efc745f1467d98860443e6ec7f37c5c3cff7e84c80f6a8", + "65ce095bf666997df7902f5eb86a871c6598a990996dfcac3fd4afa68ba1df44", + "26c29e379736009d33b0138685a7e95aada9841d1e7991c4c7d9f23fac6dfb2b", + "91156166d3650c9da21898debd45bcf42965019faa1f209e3dc8bcaac6dbe0ef", + "5554c24e6b2632b42b8f1c64bfcbd5c6bc626a17766efacec77894892e8369a8", + "abadd94788ab2b5c97749585ccb854d6b5ef7cd49c3960d58086198fd165ffe3", + "b8d02e969f1ae57cbf91d2f67ec439880eee8b10cfa706989596f4867f1c4916", + "888c062c280d1f6a8266145ac2313c236841dbe52b2bb455f6688181ed3de1e0", + "595d47117a7ca8e35bbdb8e051c3c9b1c82f7112dad5761f1b9610df39415510", + "bfdd34b75aa6f5f1811a169549dcffe537707756dd77a764ff73bf08ee545d40", + "51b7cc1b545b76f3bd08466f61da1e976341b523907521b7251c9cc76bdf3004", + "94467c061cb6507e6e3d94287c72b29736676d0bfc2dbe3d1a2d02e85e8fa346", + "44cc4e9499581b032b30e33a2420df989ed00b2a967a10735f4e5949ca30384d", + "bffa64454eec7fa74365af35e8b6cfc28bb8f01331a78b9a6f2fdab041142d1b", + "31af0a6e26ef03301ff2cd2ce6b71d9876f17b7dbd5e55eb45445f15e85c27d7", + "684cb8e7a5bd1dbdae685cdffd23809565e8350ba3726ba3399f544f6d2db569", + "86b118df16e16fe2abce593dd4a73b9949043cfd3d956f1dfeeb4a1404a7fca9", + "ae36c774b5c3d8d7fafa37c8afe70e21fdf59a1c11600af39a8d559e15ac00b7", + "a16bef4b3e62a178972cf229fe0fc7f3af52d09f04f8296ef1bc5c0b0bba2b5e", + "4f722d93050b2e9dd1f9b331bde27a72843e3bc8f794b0fb74cf511e7633af40", + "dfbe7241fd90eb777fe12f8ccdd2d05349047d3e11f407bd448fe3b383326e7d", + "14815d305d87c930f3b2a1e13a6c409671210f3f47714194e33cb55ce9862474", + "ca9d5dfcad3c716cf130a7dcc7d113c90ec636c7b81946bd440cf2c819b49c3a", + "d4e7d23f156f5e00b394c99b128df82faf6c22fdd83223a987483e749b984948", + "b1b7c50b10725700cf77541abcf34c42c5b96c46f52ae6e62f2995ab45f3e856", + "9eefb62b015bffff7595357ef7b93f1d2b33edcef711ba46ac5ea71b22d088cc", + "950416c9acd5954c12a4482a7254b2fb9f7b9ff79d0aa153ca3915b10bcd8ed4", + "4769e9e80f75eff6144dee2da075a023d33af440cd1c8e31af8317ba73bc793e", + "cdfd7fbd71c6a5eb694862ff473026c78844ca8d551e7c31bedac828dd65ea3a", + "f153a8812c7f588edc9cb4c5158cf69981071a5d0e5d827deea6bb142ebd5ac0", + "c4528480ce324ab50979ab3f82863e93de67b2b8efabc14c03d0dbd4a4d27e19", + "0457537c9e5c59d548e5aee614876cb556fe6e0b22d8134b276cf8e3fdc0a830", + "3a4c9e62af94181e680a86d40f93f1f89dac52f4618596e40cc8147d2a6c7aad", + "3ecb84d874e5ec4f254a35f209ffadc4c23a2845bce487d6bf7390de53427a82", + "46df04528cfb198459c29832038be7fd4773ab5760abc91558de7b3a557d7430", + "c382df9b0c643e7b992bfd7adc5bd4a58a64f7d47d4724081dabf9e8284901f2", + "280273f1965d0ff0c989ff64859c225cf9b75d154ceaed635d88060074008e33", + "7c8731695579e9b24f3522b65c0d02fcc772c5f0eabd3d5471f9c762fa8b4467", + "bb359cf7c4b6750ba17fb7ca9edb4e90d6cdde32655293650b8c8f9aa0113a65", + "222de2ba435ec1c1337af815097fbcff5f456375e6a3d442cd453ccc08474437", + "96d0bbd3a22a52f5e410596e188d393d3995b3fd2348f06de4297e22c987f298", + "a13d32eb1a4e93317b9e5a6a1fd11a63a6b4028df275fdedc834d54264cc8c0d", + "d27ec55d707fc3ccb5a31e40f82128aa848c131603836906cd4562a3115ccca3", + "e25d434f4bae787cbb3e7922bc62c4a56f292d148f0a87329555cb4929321110", + "43f8b6b139c987e7c25c8204529cb2234456bc16185fbac6621e28342fef3f8a", + "086433aeea535d7263c8707a414b2e40c724b102db8d166c97a430691fff32d5", + "1e76ab3a6ce62ee2eeda3316f18dde957d5115c5bc0d5615f79e9c5e712cebfd", + "d05b38a7521a85e3980660b078f0603cce36daddc814f09171a6a1508ebe01fe", + "2bd2d2332ffd6ed787f99be1416021b4297cbca0d98bf93b7936d87db70c8c24", + "8bbefbf153eccd6f829fa3ad4e4f02a97e9fca75ba17edfdbd92c5ed551b51c6", + "f2842d19e708f9fefb1a7aede4375558eedeb3e5d817abdd1491306c797d7847", + "f445831874c4f28b1cf659e8e3912e9d0ee2965fe8024ec622d4d6c31cd51f6e", + "580788e3389d1a228901932fdb84254600367f9e30ccac4cec7ec12c655ba99d", + "f5e9e6cb7ebb76c24fbd837dac4aa308010f63baed4013b0d19603a4bb697c74", + "0aca227ffcbfa28051bc3912a62a159565512b74c891303059b3134f21179905", + "c0e0db779a27b94924450ea9df47b7f4cb38a081d020739802bd1185c5b10ccc", + "ae5439b2762e10507a244eef64c06f175a92e112c146bb60827ad065e5ad7271", + "54b02784bc8309bea6ecfb850952fbafeb4f9cbbc433ab748f16be753883531b", + "8830a04efe6033b38529a8bbb5cf4ca049597b732fed33472250c908a7cf6a49", + "0d92682d447ad3aaf151058338973e24e016a2cd049ab992cd80ce54d406fed2", + "85565b1775c39beaf14e828df1dbd584f2e5ef4daea6677e4df15057c631edb3", + "e5427d4283a213022f7ddc7148225b84379e58c0ced29949c3ca13c8fb2504a6", + "02384dcd1024585c16a521c4b3826158ccddd668558e5e9e43ded0e701ec530e", + "fa2a9fe91370ef4a55b12390d819271b7289dadc882212d5d00b031054671ccc", + "4edab6f905e4840f4901a903bf6409c6bb85adb6d77d469f16120b60cbbf4a44", + "b3d37d8e68678c07fbc6503cd335629d00441d15fe3dbfc32a679af8f4a8c272", + "a50d014f39b6c8fdd5e3985902f3569faa894abc6c4768281fddd27abb45c32c", + "f6a9222166ba50eadb5984ef1881d8bae6dfb4167da6dc3da8c49648e1272872", + "fa14b1fb21ab48a600417741fd47205d3c9c83400dbc13643f4858bdb0227a2e", + "44641f3d05817150587dfb6b5aa6fe3a147ffa67b5dcf218371da1765637a57f", + "9f4737dba106cdff038d3084545d99277b98cc267698c373088e4733c13e4de2", + "b35f18273543f0babffa0239d6a65ad214b416b60faf0a62d50af57a8c16befc", + "a54ced5e9cc363d6b51d7f971797a114b375c614dd1c8b33557f4fd39a4ae846", + "157d3089d6fd658ff768af28265d70c0327e17764d818683321645a92bfa69ea", + "13120fdd6633381e59979e07836727a88e200a6e89ea60950fd2bcece5299595", + "751ff6a634075d3340387f57b9d00fe8d78528f193c91264940e12251fa4fe1c", + "c5ac3cf9b2b469f4cb857aafd6b932d60bc5b5915556d5af08a34bee04bc434b", + "c04f9ae02b69d28806fb39468326b8a3fe6bdb2c98763117b71b4b9512704df9", + "c45d1245b6e96ccf9b73ae6332173cbf5056999d4b9cd549636e6fbffcc77941", + "bff9e0395b65980b1d26cb0678f65f0c383e383f3a6f83741f838cabb54857de", + "53dfc46c6ddf344a2312c69979069216521beb8209a4b4f32cf9ac08432969f9", + "900b6d1bfdc7cfe8a48637e741dd53e1f2d8676800ba03bacac1b61fad759aec", + "9ef8a50a77bbbb45b87962a32b476af8b39f3fba230b2ab8568c32e28f99e410", + "625a9ea6f4deddea4bd8806ea1e3c5b80cd13ceb93e1356476f4c593fc8afb9f", + "40b250a79d4dd8ba0cfb0a2ac5d2ed336e5ec3ff76506651d3fc5b47a6eb9bd2", + "cc4b1f919ad5e91a9a9418ca9a3599afcaf3547aa733a1dd84eda42230242d10", + "64885ded66208f4ec16c783da83df5746aeee9e3871d9ad6dc5bc25b0ace0845", + "61dd471667730de869568e509d865625fcbe9d7f0d825af8b4ce7eb4ee44b41c", + "43c51ffb33e909a7a4468c8b8402b3b372f35c8c0e80d8774a257b83d7529985", + "35ba8770e1bd019a49bd98dd9ef2bdff5ca3bac143ee252579f084f019245ad7", + "41d4b56608d98355b2556074e5d46f48299fd76d2e3fbb391fd5c405ddf77c1a", + "d34bac573036e6c992f627ff9b9273fddbc88a5b1f1acd5ea14ac3bf3857f035", + "beb59858bd8e673b74c3e15ffbbd79ace3eb7e60298acc822d962849e993077e", + "0fe051d880fcad3ca5a4929196a56d29eb5f3892ab0beae0e1dd742f62f8c113", + "6c332230cc1a543805dda995c963d663b7a8aea1231fa6f526605cc6a9419ac3", + "286d97d22ba6bd354728126d1769efff6563eee9137ec9a081b3b9d98ca03eb3", + "8037c4b34320de4866da341ee011b2107d313a579fcb8f886ed2353d981ca903", + "14efb17da6e4089380c494bfbc3d432a50687bfd775ba2a522b811bf17354cae", + "e6c96570ec0cdb460cab9ab1466aa08c4e4e5c259617ba9e3715d67abd20af4e", + "d393ea163983d7bd00655cd1e591b24f754baf44b84358ed41528a4600dc90a8", + "9fa92fbe050a57feb7167e2c4becd0a1c80336ec1664f016ced486b61131322e", + "e41806c9d973c76ca4e490965013425833fb0192f0b9b3e2d5f149c551faceda", + "fa68869ea439e032f3003ea58c5f18e4a743581dc9e8e7effc9053e7d00b6680", + "521a4b21601f8464f6f000e8f676a8a7cb9251786364fd1642cc389ca4e1fcec", + "175ce1922bda9e1176cba1b0120cf14a56965cca7246efdacc11cf5f43c3202d", + "b0a88497df0334f2f73471316d2462f437b5564c12287218abc85a458b0dea34", + "00ad65499615796e6b2ed5ffff1880a647801e7d596c40d959287595fc82a371", + "81d7634edc1864f93682cef7205385945e62775f464b2f31cc8644369b22c107", + "3e14809c1b4c08005a7588c8312ba285c97cad123967b1618903182ce3bcd5b1", + "cc554eaed9a0cccee347b0cca26f95a858c50e7b9d4b149c383929f167b4182e", + "c5edfe3c535274805106708d57419513e49f5ec5d1c27220072934783de694c4", + "5002447b5ba5e17237eee0bd3492f39d0236d7b7d3e7d48dd80c899371ab5f2c", + "e1e3e419ac8e2141c40ebf16533b85ad767c86ca5eb6bb76ebde063cfefff069", + "0808cf3a7b2adc8c7103cfbf176103b5143e08f6758dcf8dab4d289fe18c1178", + "6f3d986d8f2115c24608ffdb0ea460135e7099315c3286ddf77cd3509f0151bd", + "2e8c4f6df77bebd9dab3920c55c9ac7b3a6b0d907e3b973976287bf3935d5fe7", + "abbfb5695c50928153060c66232e39c5666ad0e4e1f6db3f46491df87a5b301c", + "0c1d90df8ef4388e417cbc5c9ab066eb969505cc1006d9fef06d679cf7d17426", + "144732ef1e35096354adfa5c84f2e52de372cfb9ce73ef56b4e7fd5984ec5002", + "128f13f6e135482310bfe8544ca61436c7ba92e171ff9b42ab9af53b94379b30", + "3c9792276d5fadfc6e1874a7fb865482962df0edf848ec12d28ed169a829eded", + "2e9ab9030bba6bcf4858c60859c596079c93387d8f2ce6a3f531a2faf87595a8", + "cff1e56acf2c27ffc1d244646cb9ad364d10d71e93ef3a6285ac69c2782d884d", + "d781c081417a6ce5d830e8cb0c44cd242348d5636d16b5fbea71bdd2e52aa718", + "8504a71519f313ec8d0b62aa83ed0b9ea8780e2ad5fef189037344067b372acd", + "ba43c7cc890a77949d27841f13190d1a00909915a2e8d22f41d91f8dd4925b7f", + "d9f112115b12fe910d43aa6323a83dbb9e12a970cd04e915d8f1b4a3e1f8d08e", + "8c630c6b61734bb14e91d0124241b95a75e2c3e723768a36cfea2c5cedfe6f8f", + "d6cb4c34866d53e0855ceaf6c84aca05f1102a79797ab9c88d0cb4dbcc6a8d88", + "cd906809dd3664191b8e8a2e007e2d845879e838120fe5dee8e405e6861a22a0", + "23c8eb9bf6cca28b370ffe56f4af9eb339801df7a8cccfda49be735be85e11cb", + "45318809d48695b1220e887238c7d3a459a511da3cb9f2e4e3bd1512c57f8df7", + "acdd85ee1a7cc4da93fd7d9c8e2a11cd9c2ecf957c956b8c549f039d71061aec", + "a42f00fa5b5cb6d49991b7600c0e653cf7cf11ca840053310137df3881c19cf6", + "dfd6994e193a434860cb90467b7a3be326228f19862ff38e951c0d8f1e2f4f67", + "7c4cab7981f24214f797f109c8621c11fae2825e800cb31a1a0dc1f32c74bcf5", + "928c9566ca19235fdf74975ea9ed05be9cf3b34d2c055092b27afc6ebbbf6808", + "e25a098330d9309d65363d5238e24d5bdd9714990705d2e9860fff3751a9512b", + "6cbeda20d10b8c5f83441d4a4c6e42d92986a826be5a8b4f04a3b8b872a6fb69", + "76683c79f04127bb774e86a8dfc7606dccc7f77c284627c80d6c23e82f67bd26", + "848bfd973acf5ec351a5d846151561ceaea881c27f961cd33867e5ee04ab2a44", + "556012fcb62423e078fdd490a57e62bc640d6023ef9528e9bebbe036e7dcc411", + "f32b2e3d4363867e589ee7bf86c71924ee072d59db1a9761fe5adbb242ce3cc2", + "8f4a2488fe40aea892cf20a93ddc4601ff26536dc33141275102a05259689164", + "04c2843564fc8210e414244b982d4e5aee853479d4ccf6a7ec525fece4b36768", + "f20090bf6093bb8b1c95ba6cbff673039b9f448065711b898710873d0416cf25", + "9b03a8e54b26c35685424dee2e1b67ac1915260dbdb6fc81a0c1d559264ce6ee", + "ae2f8f0a415bc3864381cd3063bb1af863cf322c40da1ed577b3bbacc46d9571", + "e70f80177e1038780cf0546706aa0514dc8244e4dc3ebf75a1d0914b09abe3d4", + "6e691224c7fe3a0115b9f379cc250dbbc0dfceb7873fa72b4edded705824b578", + "77ae60e42821fc6b8a4e8e69ad7ed78aa13d5a93e630a04b0ffe89ae462fe261", + "ee7f2d15873dee3483e88f2ebc88102923107e27cea7cb53c9c0b7f0f17b06bc", + "6c9986e8240b43aeea6aa2b6fb431115edfb09f8cb3cc3f9c70e3fecf59a231c", + "ead710aa0b69777d3a973a55db1355cbce5b67a9cc86548823eecb4cb31f8272", + "97c19541a45f119ec1994741a79b3fbffeaa1c7eeed53749f2865876f8bc9de4", + "11151d63fd48fa3d35530158e3d331c4581a111f9ad573f7737fb9c85f818b7f", + "8307a45afc14576423cba1075aee6257b097edca6855ff0d28fba055194fceb2", + "cb7fe8e0b418b55790e3a4580f9eb49461587edcab0f01f523704c660c5f799f", + "ed3d01cdcb5aacf91e015debb07adf5a5ec4d34d23128839d732f7ca10b8366a", + "e2bd97df55495712b533dcfff0e374bc641e4724758b29062e727498bb14b1ef", + "9112dfd272f686e77eba03ba6a7830cec005feaf8f46a188a1afe9adabfc5051", + "ed658d487d1b06f8de2e6b2891d465677d0a250d9333e93e69fe806b130d459b", + "814bdd2cbc63f7e94815e82d3876e9cd7080d7ee2e0132f6e55995684d74ffa8", + "6ba6e3c38299c567f17d5a5aeb34ace979bf1d41432163914f94535301914695", + "6640380b28ef69f7e2d21efffe3ec5258eaf37b774926bb2eccbfb932a512306", + "5bab57f4a44da414085f9b999f20d53d4f7d4f28b2158328d23ed0367636191a", + "614b2c8adc98d25fddb33a7be7800cd52e38aed9bbd2745f0791c9850e370d98", + "83f69088cf0571e33a079b38d430c220001f88dcc75bf857b5518c5b9666c7ef", + "1c52e27deff070d9c3397e32b5d726cf3fb3d508ff491a2af5e4af49a2c8b76e", + "0a0d477de881bde5ea2eb0e8d71a27d7e26fc1dbd0ac1bf5baf6588b100220ec", + "a825777c4357bd48e1954bed658f155df6d466b55708e4d0dc044c5c60849d9c", + "906cfd7c20f44a76847475f69b6785a1d595336deb2a5861af77a58f91061754", + "7d7db68b664f74adba0b3e3f9a08d33dfae1179120903c03a6c83e27502aaca2", + "121c2ca299724becdd00c0838804f3489465cda8a45b0eb570c684bde9cfa962", + "76b00788f674043570c50de449c59f45ae0ede4571cf3fba7d742333442fbed0", + "42b3099dc5b5bf96acfd860e9d5a99ecadb2d0e5540014805bda23bd2b174c2f", + "fce2cfaaf8e181f25dabecad80726585b6ac39c6ab41cbab780ba5e7ea3d173f", + "094516a4e8f0dfd802eb0d3da4a2c98fd8a5b4e4af65c48ce65bc0fac2ee99d3", + "a74fa22fbc91f8f4885a06790c5fade1b2e7b3f681ef9be6a82c5b8bce7e9e58", + "06ca2e663906cbc5aac4ae5666fdc21559b69bf755f21a0ba14b78e944004732", + "72a49376c56a8268fc1bd3b82a2ad13d8e025cf1368e0fe2fa30324b9defe4e2", + "1d88130253055740f1260f23c4d696fee43535d13c88cf9c8f85afa5a609bda3", + "3f86873c5bf7516e5ec3b15f6487ac54a127d7d4b09655be43db0f7ad63c25e6", + "2af6404ed34cf5d3d0e9e748fc46c8c9761b2a3b624dc2eab46f273d4bb8f4aa", + "0f20ff8b945471b8bcebec2eb4466b47b8a9a08b5b742f0da4443784311de94f", + "80a299a1dec0cea82dbb4807243abc2da2b8554ee68923559dc22225bfcfdb0f", + "26b63254c9676846dc06d75093a134df9afa9f1eb901a21852ff19e150da7bbb", + "c68b7c786f05dbcf0bde9184f90a88da22c22bacae4dc0c2c94c2154f9efca68", + "c2db651cbcec250fe77b6eeb4d3b61b154be1bcdfeec1e83d2b70a6491a5377d", + "e668d33701560594ea613e32ee9d4a754f8aecc85d69b9242e49429cdb7a4520", + "d4cd171ed3ac0f825f0b72a9228cdf18a5ed15fe70edd1b4b34764c23afc8e72", + "09c532451e8496f0e4e331cab44e072ce6c0b3e2dff3a57a1de98785d794c881", + "e688238cebed6c65c1530cb9d1c3b01076e2b1ec74097ff2ea79898335349ec5", + "65da2376b51c3fe8cd91cf04cac1d27a075b6247dbd04b65dec1ffac8ab6db60", + "43704b25007e82dcf7fdbcb44e3258f48e8a6a310d4dafd5b7c88605aed14402", + "f8375ec8f98cc452fdaf9c66465ba58ec38a8170038dcc12a95fe99630f49bd5", + "10f049189cf22b8c1693cfa7e7d012caef6f6fda7160bc0aa2fff23dd375fdf8", + "7f23539c5e246c22e90b96c2f1eb3e56a2156d2e735e114b331da05fe0485ae5", + "6c4534fbe7dda9dd133b2130b797a794da0219559841644664e725dcff250fdd", + "f9d6776a55c976778856cbfb293445332195c7d883cbbbda7c6243d8a518cdd2", + "d01de8ae86feb147ece906c495a8aca1f169b038011252da19e4464698878174", + "93aba29ce2804872b01d1150aeaece8487fd3aec3a8bc42f2c8b83293e5ddc09", + "260338f41047f28d373a0c5c05adf51db375db2b574888b0c7f3edd507acabd1", + "16ce15abd7cf2f4ed1bf17b5c77397c55018e0750c6751526e8d812eb1c63d64", + "4a6a7261cb47a8ac58afc2d72d59473f210d0d87e917561125e8554f08fcf8a5", + "1238400df045a4026f0b7b86590b91b5bc33d08c3ffe74bb7de0327c6f8836e3", + "2c7f7b33e03cbc36a5e281b94fd91620c00c4c8f771c3df74785f64a22958722", + "c8cb613f0f2a033e6bc5c12b5ebfceeb8aa1097b832b5b66a6e145bc93de49b8", + "2546c4c68b77e2e335ceb0236f7752604857b1e7594e6345b989293b43ca2e78", + "f685faae6d99c003e9aeec81ac6643877c21bef6c02903b6308202867a1c2230", + "1896d42d66cef3fadf4c91c1ce3dd58f035a67cef76ca0102d6596c9ccada9de", + "24e68496d9d019cc881a493337ef3544058af7deb0b9d881628a0e9885d423a6", + "dbc28a916080bafc4662b0a20867a5b26984560de9c2f4c9813230d9ab976596", + "0fc76e57b3ec5285f5f8999224db8f96937f37387fd3bd203f42dcfa59b89e32", + "708e5c7c830fdcfa47089bbba40b8870cf2015ae62c1a5ddaac491e49440f30d", + "dd280789e0dab9e70ea6d1174564ad323d1c7b1f48dab25e3f860411f2daf455", + "34cd5040995eca4902145c3a78115bd0e17b18c0f916abc84425d5fda2a64a06", + "ec3df298721d736c16afe4e38b0ffe7b5c01f5491ba5f98c9640ab3904ef7cbd", + "3527c06a858a89d1df7ff6f0182ddd7c191e5caff4cbaa07ea480fba47cf10ea", + "3d5bc5f1e5a5f8b27a3a17b1a82a4796fa0810907948875cb6915e5118026a61", + "e64799f890e487494be0b33591432ddb321c456ebed4ffb1dc5ac4f381ad6291", + "70ece1a235c5fc5925227d64ee779cd6d5a4c9bfb4b2702cce8e0d45ac82d5da", + "27b8621a9eeabc0490330e157f19d67843fed56797c6097575b33e542403fb45", + "b4f4ede7a4944c6caa430352dcf04f523b3526fa5670c7e9cc847820f12e7b3f", + "0df95f55cf4d5d9e45cf61616fe1faf8f6fa5ae6eb16ced164f409039e975eea", + "00cbd1dc6c399964a53da8135e03c10c4214771f61e518f87f2e8becfa6d893f", + "b44d700337072e3832b79a7c1aa38e0805ccf1482d1bc2482af5fdde067d7b33", + "2b18ddfd9118bee047610343916f43566278a5ac1361e11a9b25b8683c266345", + "118b5d522fd4bb2a5d69f8847c3afab13cb273d13042a4cde0812de72bf84d30", + "f2053cef7a0e5102e0759def52dcf2f4fc140ac81ce346342805db9f4ed3222c", + "eed72a7837262ebb9ddcfbbef482ddddeea424f8457e21fa3647531a2aeef63c", + "507a8e7b270ddab1516be01cbbc75af4f6d10fde90fdf2ecfa76b9cf88fce17a", + "d57f475a682c86b406bc8bdffb9e769f17ef03a5d8422d2900f6aece6f91cf49", + "0f80c18ee7eb9d26b7531abf070aef4b143d0ad6e8d1d48f2efbf99fb8ea9dd4", + "a05cbe748b8efe35d8042bc604b1c8effdbbd643c28ed6f3ff1a6b5e2e881200", + "ea8162326da097abd74c1d0ed407dd9aaa8db98e9ebc383a46d114bc150e2953", + "c6ed8d2a27486c6e10fa0d8f49af5f53a0bba39ae762214dd6f82ff848555134", + "3c8f6f1ade3222e10cd2b10657f97adf2c7309694abd51fe32795dae6494f080", + "6f7866270511c9db25660f9a2127e142da6d39e8d8e4d5a9832d030badc2b897", + "46258b0a32007def279cfcfad8e1b5ca6f13f2ac141490132b442d9d78e8f61c", + "71239c46e8fedab9e2f9028b608ad9e7f0c7478c799b6630a8d1e9b4459158fe", + "30d98b30fb2666e7fd01dbe341974e6132737dc2699eea53e2da50ed98845f15", + "bfc7919ee02934ab768ab26fc153717194d55e0ed5eb9f486915f00bfc8fe1d2", + "520616b8a96ebc403c253c8aed7ed141a8dbdd26d3f5400c41450570eaa372b4", + "ad9d3dfa83c41b3b666452c9f14dac942f3544143b2a782a0d1339c98cd6d91e", + "9ceb31caca21f72021097a2c0ea1b20e94cf827917f56f2a9495ec10b8d00740", + "c8530ec83e7284a8f81763a1323f39a8601a0afe38f8ace22e093b529afd5d40", + "96f1b36fc978e24757df80cb1c9da1786a511256dfa055845f534f33b704d5d1", + "ebcd1c6482910151f38e2252cdba595bee2a493dfbc4d12df21b9ad3da12e0ed", + "2693139fb3ff31e710e6b21694f3acde1ee55d64768d86d0a0b6b5b84ac2a6fb", + "ea91e842c3ebc4725dac29e63f9f2467c4feabd9c5d2723c7af236705e5a80bc", + "904bea038dc755ffd0938bf3acac00a906a477b2b37f63753d99c1e9b40be67d", + "8a18bb878f360395c436c86213445246d606cf5d96e6fe90cae733fbc4a1d082", + "56d29041019caa21a53845360cea15832cc9e10c5f619175eef5389766081503", + "41d9513dbed73a04d5555e5a27b4b21d6aacc818c0e1dc1765dd46134fc3e56e", + "eabe42158fb5036d517ae7f30e7f745a51216c02183fd7d4a5ba4518337da5cd", + "48f6201eb64d368eb180c8e7575a2a64bd65857ad4c6805e555a7ce2a2e117f0", + "db428261699e6b7c57f22a0ed28e2419faf19fc8e31a48993371fe98e857eb8e", + "4721d94e254a2fc33c12c5af0a8c219286ac1fd8da5a8b864125d3bb9c35d698", + "f4db014179fec258488592b756fa3330314a50f933f0e8742a4a073954e3625a", + "d65df63ef95238340f926acb5f0ee310068786851f940a968c0cbccae35e6256", + "387d6b17933df224b60e68a5813872ad7922cf6b19bc9fde5002fd9d7aab2491", + "797e9f493c41948d4e8db7ad146465ee19115190deb74ea1ef2b4b91bcd0f7b1", + "aa80c35e42b93e22f9c4ac5c32e7589ed4a2e134c062d3f430064aff632d74f2", + "8cfe8cfb318264dbb1614e1d288cab00c668b0f3f4cc9fd7e5c1bdbbc7b00b7b", + "e5b2c705211abc74e4c3d7c68f44d3426e9b5de92d6730c9a7cb010e6dbce102", + "29da761790f4298107f2d27879c19adc66f852ecefd859c4f9958a07e5a5f7ec", + "3ddd611e7e66c0212b9e5ae35cf8898af3dac6207f788bf42b64f95961d00fc5", + "62ddbe7f95c81bcebd7a6c9b29a651ede71fd1da94b772b13b78bee8d9570ea1", + "020b2dfe6ac726a5a819c5f20eb9e051f5b6f2b9c67aee0f3ef9da8114f0cae1", + "f9fd3f8fdd293a9208193d8d8c23eac4febc0e8f6309f5cbfb186e4968db367f", + "67153c5dc67904b932bc082422529fef73c79faacf27f15006f8b095a8097084", + "bf99fea5d01d53fa8f639ea7bbad2b9969b98ef9b6727f2ae5988c553f46b5fd", + "8e1e4be9cbef42c8e9a889937cf021b15f2af0b866ba01a4ad728e702660add8", + "3b69e03247594d30bd83d9489a8c6d1444c7287588b20fb1de4308b841b3134a", + "5e3940a9b8b8a3fe76792c22b3f2aaab30923690de49d81299a6610d83d92a47", + "89da318cef9a99e761cf9d0f489287a14c90f065c325647940d4a5134cf9e2ba", + "e27abb59d26b3c9a54f0155c905fc0815342e9686cd75fc96813ca50ab84893a", + "46c864c775cef2e8745f37a359d1b86c26b92dd482fa605850b145a1d802aa7f", + "53e18c1bbfce6d69721afebb271270d0d70ce54929531393efd4102792e0a643", + "bf3eb74b0717376f6214c838673d5603858b0539a3cd197cc3aeb38dc407aff3", + "0c459f37f26193432223cf6efec9cbf675287e86bd76c08d890fbee393534269", + "0599ebe31b4b69ab105d410849bd58b44a5c0291cb391d3dadd074e036e9dcf6", + "368adfec891612dd4d742b22ca6d0b4724675e5e4ae705a82ed2fe1a30a298b2", + "c7c96f384d8c8daa417bd4ef1657b21c5a458f4375119d7c4619f9aa85555f80", + "42120bdc7f2d01c4860bf8bc357930fe6b7d257587f1a9e69d70d1a0fe22de1d", + "8ce0f4c46f34a5fa24ed3277f11c972b99f72a5805ba656e030efdd7dbcf0147", + "4cb866fbff47706b1566d2e53dc262793e231f8930c31febfafbc21dcc3d6d0a", + "9fe2f749a21abccb2f6df833305a02ef3004f7465fcd588b1f842b6bc9c6f9bf", + "0d202eb12117ba6f9b76c714337d51142414aa9fb172c5846a2c9f9401f789fc", + "3dab8731592f011e529dcec19cb6fff9ff9c01714fd52556f3cb1d81456691c3", + "a925fd054883dd8ef709278e1514052fc9309857869027c212615929307a3091", + "1f19dd9e4c5643b6dc47aaa82b9763dc34be825b7db5f2194e958cf1202677c0", + "807375fc9b33dcd9c6f9bee5e55e0bc5ccb1642e492c4d6de309f197a9c05e3a", + "8938cdfbd8dbc89ff9d69e20bdd7e92783d4e18a33f696662bcf8a75c145e6a7", + "2e062ed85cc3c3ced49bf2af34462d14e259bb608c23ccf5ad525e8df493402a", + "a2e4e538cda171f84ae9b856e0aa0eb9fa33ab3926d0a251e6fdd4230147277f", + "239350c75bc23ce636c7a1ff39ed1809ae70e7d1c0677fc8f04bfe8472cb58bb", + "26f42e14168e2b0a728bfdcb6b8cffa7fdfbc9a51d3f3081cdcdff9b12b41a69", + "2ebbf404307ed5ff55df088d7c621bf672e780adc06b300e08f5dabae3057e65", + "77c90b3a6c83ebadc6d5c27c9eb12618f648ee30193aa2a54c4493ce134e2c0b", + "6367c9dce3ecddc19e3fa8bdc45da36721bb45cdfec050481121cc6eb18fd286", + "cf2dc54c5dd92aae95c1f454ef635a15a8db5d3e9f7f25dc0cbd50f653162a26", + "34d8be0990300b71e3704b70d8a11436fab24ceffa7fc9e9be8f6cdc0c199750", + "ad1cddf71d8365268dcddb58896129fc00ffbd042d77f423a8f13b0b6435732c", + "47e1051243bf8e996611b1d43da731e71005d5f86dfc876c16b45204fc8c296a", + "b540011dfb7f671d7ab70bf54014f29b51bdfb344e87bc110e4e65f195f0e189", + "96cefc45c451b027e98b9f0bb6959fe9a06857bd6511abb889557a397fb73f9a", + "ea780acb9686978c8d8917235f1ceab6303681be0d55988eebbbe3aa26e2d423", + "456b17ea46a7ca764075ce71c1ecde89d9adc646e223f8759b678656b5df7306", + "85b04d7eb6efec78c4843a7dc17ed193dd501263699de7cd12168e932e5c2584", + "6191a405b5c7f7ba82e8326471293925da325c9f43e2de89a0d49f43ddf344eb", + "348a83e2eb8a91729a5764efa5eab4d7de64118d7266b200e78d9c9528d043a2", + "c1b5e297472913a638f03fbac1903c299d6ba9a5a093f491f8d3476af54087db", + "13b6a88964a3acbcb7f13e584f403047f0aa01e17b77e7464a2d919333ee6ab5", + "75bf8e8ec14a649548b7910abd7fd3d5c90967deaa003487a7d292274b8b5eb0", + "fdb756d751c4a95144e540cf5b80441e1bc42e8e4811bcbb0d78a834a472ba59", + "f9bcec1a97496de391ccc96569e5f6cd9cc2f00be778391f44d2c4b63aea1e0d", + "26dc7fe97b2e203a6b1fe8eb1b571acaafcc05cb4fd87820260bed3e200c8c34", + "3df08bba0e57b244cf27b7500f245a8a89733f4f5bb013c0108aa7de9057c8b4", + "f70388bf55d3b66da2964b2077c6cf20daaaf3517f012349bb47ae1feb330c80", + "91b02dfcf0989649fdf230dec2fbf4905d2476a8b8449c18b0b9c5b2415e9df0", + "633d98fa119a00deb3ca6e429cc86a2b805115c7e70beb2fb522f01843b9a1f3", + "1ae65990ee1381d04c30de6ae7a10a074685535622b12efc84e252cace553680", + "0d821f0886463cb338712b6b529c896e8a9fa511812a886144d30e24879a27f1", + "6e17c1d5bc6cfdf7f27ef6f76194710abe877c13883488f6bf8a2e2e95f64890", + "61600bb14b990ee11de50d88ec5d1e90bb3e50ec267932b49b13ab6ddfb05e32", + "9722b7717d42ccf9a81fe56e4e8265c3748b9bd8d4cc0b9ccc6765fee5cb528e", + "ad7297d9936a33c6355c41c1ef1fee06634ceeba11048a490fa0313e76c2ecba", + "b50324e09bf0a9c10e4e03789c80bef655e6850e26153979ec02d3385e9321a5", + "f910de297bed51fa8382079fb5cf21e116f20d60dc8c508110a62c5a5aa8b225", + "ea4c332220579820f11d35bc1a7f02f7a8c70ad7121b8aeec3370bd0f949b4bf", + "6ada430b0cf80b84f50b29ee8748c9da135cc721459fd6a14d0f5c0eae6f613e", + "5ae62d7e018488c7b6624828940b6027c339c4b5a5ce37abb7f818d656f0b6d4", + "06358cef28410ff43fe504b4da24d319b04ce8799359a34f95cda8e97e56aa93", + "baa7b87895f8d753106b36a430e208e1457da6c65ba34d5897f3eb7e4c670460", + "80e6d67b02d28f2642ce3253a5788d105c5ff4606aecaf29d65e8271736c93dc", + "2727ce84952c69d6836cae806ca3022826a9dc4dd074730f5e0a2c16d19656cf", + "ce25aee0c22e201d748a278734575f91a83b2246984bd74cd831ccc6ec608ab8", + "12ad4b22279c85568f077f1307b4c647c006be45f8f71eb3ca51a93e9eb33af1", + "137443c7d9f558cf0ecdb010b39ed4eb877dee91b6f63c3e0f86c2c8d330305a", + "d128794cc426fffda7546210e023c3c973b156d24a5f0cce04dc16f933d62f1f", + "73debbb64834700420a75d4e7f0fa1ca768e0d611563fc9937444ef9ee2fd54c", + "48f64ab189aeccdd8a15df119c2a4f0cbb6d4dba048a86c83e990499e55ab396", + "c0a03183012a4d54fb793aed15392a5d6aaf8aa843972c96874457cfeacbae97", + "bd509ff86d978db2ac1ae1abe9cf0e4ab2e6351fbf78ea59a5137066d89a13c6", + "f92fc2f288f1951f73024981309034115263c39262a2c9599573fe4df192d904", + "0b518f6c9fcf4c516874d91718a2335c8051ace16f943f35561c6fb787d9fb20", + "cd8c3d424da15a6ac5f2213d4567c1a5b3851308481f10fa3fe1d46a609ef8b8", + "4ee57cdcb2ea46bcbe3561d0e23d69bf8a0552c77d8145a784e0e688f2593630", + "f9df6b426e92e52456eec0c2cb1894b1c16796edf580d71e1e093b3a00ef6470", + "8712279f6ef9fb406fc6d368e5ae5f37598977cb00890b83b0c5f370aa7f7c5a", + "39cb52eb63c983ac1137478c97ba179a2e1926ed4054e22b8245131e9a257f33", + "3b8223c8afd307600822d72eee2b97082e80058635056bf64774493b0603f2cc", + "c4be27d94d1718bb3da45b5253bb4a4e11cdd85ef60b07168be82ac1441936d6", + "bfa6e5463e02c0af1b9f632924258fab427e5ccb36750383fdfe871aab2b78ca", + "cefe8cb276df0f3224445026c13b80911fe28a5d498fc440d0b206c05bee4614", + "5abb8cc73d8d04d02c5331a4b05bb535fc778e93f2b7c377006bd04e98bdc438", + "b8a9dcb9253a47ee25abcd8f5b8d320162063e209fa2fc66ef1e7b6a4c25ea3d", + "857704f3ef8dda18cbd4e32a2e309baff39100658d4bc0a75ebd78c5637f82f2", + "aa6ad7bb28e48b47cf5b989d9cab478a1238c82f8836282f5cd489d15c83cfb7", + "a979f28eea43fafeb0b3f929eb16af086c9c8135e2d0cfc6466a0b9b3c0a0507", + "24562664e219cfe283d45483cea06b175e6dee079e3959a39e20e21f740f8242", + "eca464b0a1e7148f3c47f8b1299f7f58c3e08d86bdef9707c34577ec112ebbd1", + "a72f6c3a83dfd1be8585d91fcaf2b3cbe91986213000b12aad41ee77129ceb2f", + "525caa90a7566a6e981117a3f406c3560d612da5d874e10ed735ad1fd46ced1c", + "aa2550f49d8d72df3f899f7e2f638634168339639740f7dfde5b2c7cf4b2c5fb", + "75f99f9014d94ef5a114d6ddb35b489c0e96b8701402d770f34bb3d31039bc39", + "207a732b3f7d9cd290574977320b64745042ff3c7f8972685b329eed75366e60", + "a00e7e3efefa35b21d6d4a06c78e4098572413236b8eb0ce9bef6b0516ba58a2", + "756d13c86ccef3892230b8f0b50f3ef0a539c3537a3d66fbfc43b585cebbf2e4", + "a94db20edbbb718b81a2b1b179b5ee3cd8993835e9081a7b8b52121afd72615e", + "9147c61b90fe848c1c5ba0145493b7acb93fbfe17d815b72caefdde844ac54cc", + "30e2500c42a2867cdd96b620be6b7dc1a9c38ed009caac5f026cdade59f53850", } -const ropstenPreverifiedHeight uint64 = 12010752 +const ropstenPreverifiedHeight uint64 = 12088512 From 25a68e08a5287892022291f0c6ef98684be12838 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Tue, 15 Mar 2022 17:38:10 +0000 Subject: [PATCH 197/261] Update version.go (#3701) --- params/version.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/params/version.go b/params/version.go index c2c8b13e106..397f830801a 100644 --- a/params/version.go +++ b/params/version.go @@ -32,8 +32,8 @@ var ( // see https://calver.org const ( VersionMajor = 2022 // Major version component of the current release - VersionMinor = 2 // Minor version component of the current release - VersionMicro = 4 // Patch version component of the current release + VersionMinor = 3 // Minor version component of the current release + VersionMicro = 1 // Patch version component of the current release VersionModifier = "beta" // Patch version component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" From 7ce2134e21e1063d8f171ac5658bdb19499093f2 Mon Sep 17 00:00:00 2001 From: can Date: Wed, 16 Mar 2022 22:45:31 +0800 Subject: [PATCH 198/261] rpcdaemon: fix TxContext in traceBlock (#3716) Previously `txCtx` is not updated for every tx, which leads to wrong tracing results. --- cmd/rpcdaemon/commands/tracing.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cmd/rpcdaemon/commands/tracing.go b/cmd/rpcdaemon/commands/tracing.go index 05956c8f722..dab587c5843 100644 --- a/cmd/rpcdaemon/commands/tracing.go +++ b/cmd/rpcdaemon/commands/tracing.go @@ -11,6 +11,7 @@ import ( "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/state" "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/core/vm" "github.com/ledgerwatch/erigon/eth/tracers" "github.com/ledgerwatch/erigon/ethdb" "github.com/ledgerwatch/erigon/internal/ethapi" @@ -65,7 +66,7 @@ func (api *PrivateDebugAPIImpl) traceBlock(ctx context.Context, blockNrOrHash rp return rawdb.ReadHeader(tx, hash, number) } - _, blockCtx, txCtx, ibs, reader, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, contractHasTEVM, ethash.NewFaker(), tx, block.Hash(), 0) + _, blockCtx, _, ibs, reader, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, contractHasTEVM, ethash.NewFaker(), tx, block.Hash(), 0) if err != nil { stream.WriteNil() return err @@ -82,6 +83,11 @@ func (api *PrivateDebugAPIImpl) traceBlock(ctx context.Context, blockNrOrHash rp } ibs.Prepare(tx.Hash(), block.Hash(), idx) msg, _ := tx.AsMessage(*signer, block.BaseFee()) + txCtx := vm.TxContext{ + TxHash: tx.Hash(), + Origin: msg.From(), + GasPrice: msg.GasPrice().ToBig(), + } transactions.TraceTx(ctx, msg, blockCtx, txCtx, ibs, config, chainConfig, stream) _ = ibs.FinalizeTx(chainConfig.Rules(blockCtx.BlockNumber), reader) From 785539f9d629c9f34b5208bd1cdedb4fce64f0cb Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Thu, 17 Mar 2022 15:24:46 +0700 Subject: [PATCH 199/261] Mdbx: WriteMap fallback on error (#3714) * save * save --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 236e5a917d0..5220ec943f6 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20220314143349-5c8ca0878ba4 + github.com/ledgerwatch/erigon-lib v0.0.0-20220316084317-5eadbec16d2d github.com/ledgerwatch/log/v3 v3.4.1 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 diff --git a/go.sum b/go.sum index 7492b28ba09..fb98ee538a6 100644 --- a/go.sum +++ b/go.sum @@ -493,8 +493,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20220314143349-5c8ca0878ba4 h1:wivpdSUiMW/EZw8FoEC2lZTip7bg6MWOd3NCAqQPy6w= -github.com/ledgerwatch/erigon-lib v0.0.0-20220314143349-5c8ca0878ba4/go.mod h1:T1qFKmOyjrE1Uu2iImEsnQQDs7xBbQX/zwtrdfVOkWA= +github.com/ledgerwatch/erigon-lib v0.0.0-20220316084317-5eadbec16d2d h1:yMlC+zKkgveAiMdFl1FgajV5Pc7tP7TjRht9AV04iIQ= +github.com/ledgerwatch/erigon-lib v0.0.0-20220316084317-5eadbec16d2d/go.mod h1:T1qFKmOyjrE1Uu2iImEsnQQDs7xBbQX/zwtrdfVOkWA= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/log/v3 v3.4.1 h1:/xGwlVulXnsO9Uq+tzaExc8OWmXXHU0dnLalpbnY5Bc= github.com/ledgerwatch/log/v3 v3.4.1/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= From 2071fe9ad797c1401cb199117c678bbf09b31608 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Fri, 18 Mar 2022 04:32:54 +0700 Subject: [PATCH 200/261] Pool cost fix (#3725) * save * save * Update to erigon-lib stable Co-authored-by: Alex Sharp --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 5220ec943f6..adc26e306e2 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20220316084317-5eadbec16d2d + github.com/ledgerwatch/erigon-lib v0.0.0-20220317201720-60a8e311ca68 github.com/ledgerwatch/log/v3 v3.4.1 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 diff --git a/go.sum b/go.sum index fb98ee538a6..1de6a6fefa8 100644 --- a/go.sum +++ b/go.sum @@ -493,8 +493,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20220316084317-5eadbec16d2d h1:yMlC+zKkgveAiMdFl1FgajV5Pc7tP7TjRht9AV04iIQ= -github.com/ledgerwatch/erigon-lib v0.0.0-20220316084317-5eadbec16d2d/go.mod h1:T1qFKmOyjrE1Uu2iImEsnQQDs7xBbQX/zwtrdfVOkWA= +github.com/ledgerwatch/erigon-lib v0.0.0-20220317201720-60a8e311ca68 h1:wCF7O882369n/KG80rdbVYgNI+DCGDgfl2dJx+KIzFY= +github.com/ledgerwatch/erigon-lib v0.0.0-20220317201720-60a8e311ca68/go.mod h1:T1qFKmOyjrE1Uu2iImEsnQQDs7xBbQX/zwtrdfVOkWA= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/log/v3 v3.4.1 h1:/xGwlVulXnsO9Uq+tzaExc8OWmXXHU0dnLalpbnY5Bc= github.com/ledgerwatch/log/v3 v3.4.1/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= From c6c02fec537d02f757a0edf17971386552d5cbef Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Fri, 25 Mar 2022 20:24:39 +0700 Subject: [PATCH 201/261] mdbx v0.11.6 (#3771) --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index adc26e306e2..fa1f83b444d 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20220317201720-60a8e311ca68 + github.com/ledgerwatch/erigon-lib v0.0.0-20220325041222-d1fb60f9798f github.com/ledgerwatch/log/v3 v3.4.1 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 @@ -46,7 +46,7 @@ require ( github.com/spf13/cobra v1.2.1 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.7.1-0.20210427113832-6241f9ab9942 - github.com/torquem-ch/mdbx-go v0.22.16 + github.com/torquem-ch/mdbx-go v0.23.0 github.com/ugorji/go/codec v1.1.13 github.com/ugorji/go/codec/codecgen v1.1.13 github.com/urfave/cli v1.22.5 diff --git a/go.sum b/go.sum index 1de6a6fefa8..90ad517fdad 100644 --- a/go.sum +++ b/go.sum @@ -493,8 +493,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20220317201720-60a8e311ca68 h1:wCF7O882369n/KG80rdbVYgNI+DCGDgfl2dJx+KIzFY= -github.com/ledgerwatch/erigon-lib v0.0.0-20220317201720-60a8e311ca68/go.mod h1:T1qFKmOyjrE1Uu2iImEsnQQDs7xBbQX/zwtrdfVOkWA= +github.com/ledgerwatch/erigon-lib v0.0.0-20220325041222-d1fb60f9798f h1:H2FG+z7z9KBn/dHuC+i4gICtkEN82umLZvoeCoYaRDM= +github.com/ledgerwatch/erigon-lib v0.0.0-20220325041222-d1fb60f9798f/go.mod h1:ZJuSY/lTYzZnclDfGvxFfTGGJ4AWRmqkHe6E7dLiKYo= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/log/v3 v3.4.1 h1:/xGwlVulXnsO9Uq+tzaExc8OWmXXHU0dnLalpbnY5Bc= github.com/ledgerwatch/log/v3 v3.4.1/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= @@ -750,8 +750,8 @@ github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs= github.com/tklauser/numcpus v0.3.0 h1:ILuRUQBtssgnxw0XXIjKUC56fgnOrFoQQ/4+DeU2biQ= github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8= -github.com/torquem-ch/mdbx-go v0.22.16 h1:uSuQOAKSZC7TvV4N4km+6kyER2YxaOuL/0qybsQtlUY= -github.com/torquem-ch/mdbx-go v0.22.16/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= +github.com/torquem-ch/mdbx-go v0.23.0 h1:1rX04EXbbieaMa5sZ2uV6aQOE/uoj2q4UFJWLcFbpuo= +github.com/torquem-ch/mdbx-go v0.23.0/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ugorji/go v1.1.13 h1:nB3O5kBSQGjEQAcfe1aLUYuxmXdFKmYgBZhY32rQb6Q= From a9b09baa262b275fd99ffbb695811eab184de205 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Sun, 27 Mar 2022 14:00:45 +0700 Subject: [PATCH 202/261] mdbx fix after v0.11.6 (#3775) * save * save * save --- go.mod | 4 ++-- go.sum | 8 ++++---- libmdbx | 2 +- turbo/shards/state_change_accumulator.go | 8 ++++---- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index fa1f83b444d..dcd324d2c0e 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20220325041222-d1fb60f9798f + github.com/ledgerwatch/erigon-lib v0.0.0-20220327025752-a815df5b646d github.com/ledgerwatch/log/v3 v3.4.1 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 @@ -46,7 +46,7 @@ require ( github.com/spf13/cobra v1.2.1 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.7.1-0.20210427113832-6241f9ab9942 - github.com/torquem-ch/mdbx-go v0.23.0 + github.com/torquem-ch/mdbx-go v0.23.1 github.com/ugorji/go/codec v1.1.13 github.com/ugorji/go/codec/codecgen v1.1.13 github.com/urfave/cli v1.22.5 diff --git a/go.sum b/go.sum index 90ad517fdad..79db4189ae1 100644 --- a/go.sum +++ b/go.sum @@ -493,8 +493,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20220325041222-d1fb60f9798f h1:H2FG+z7z9KBn/dHuC+i4gICtkEN82umLZvoeCoYaRDM= -github.com/ledgerwatch/erigon-lib v0.0.0-20220325041222-d1fb60f9798f/go.mod h1:ZJuSY/lTYzZnclDfGvxFfTGGJ4AWRmqkHe6E7dLiKYo= +github.com/ledgerwatch/erigon-lib v0.0.0-20220327025752-a815df5b646d h1:mvNXkThZb0IrOqSsEZpAWSrClmeK95dM/ZWQGSIzxkQ= +github.com/ledgerwatch/erigon-lib v0.0.0-20220327025752-a815df5b646d/go.mod h1:DuTHf07xXPh3sf0ON0Fsab3bNnqS+XVeKTFUN9Pv36Q= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/log/v3 v3.4.1 h1:/xGwlVulXnsO9Uq+tzaExc8OWmXXHU0dnLalpbnY5Bc= github.com/ledgerwatch/log/v3 v3.4.1/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= @@ -750,8 +750,8 @@ github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs= github.com/tklauser/numcpus v0.3.0 h1:ILuRUQBtssgnxw0XXIjKUC56fgnOrFoQQ/4+DeU2biQ= github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8= -github.com/torquem-ch/mdbx-go v0.23.0 h1:1rX04EXbbieaMa5sZ2uV6aQOE/uoj2q4UFJWLcFbpuo= -github.com/torquem-ch/mdbx-go v0.23.0/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= +github.com/torquem-ch/mdbx-go v0.23.1 h1:lclZI7qZu844VjMn6onSWWcQYCIEwbClML7we9qxz7E= +github.com/torquem-ch/mdbx-go v0.23.1/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ugorji/go v1.1.13 h1:nB3O5kBSQGjEQAcfe1aLUYuxmXdFKmYgBZhY32rQb6Q= diff --git a/libmdbx b/libmdbx index daa7f04f617..a6b506be45d 160000 --- a/libmdbx +++ b/libmdbx @@ -1 +1 @@ -Subproject commit daa7f04f6173504b5acc74140ed36f617d3a62bf +Subproject commit a6b506be45dbfe1bb3ab88ce8ac6e351adbe9f40 diff --git a/turbo/shards/state_change_accumulator.go b/turbo/shards/state_change_accumulator.go index 9fdf9f0b8dc..dc7372c9537 100644 --- a/turbo/shards/state_change_accumulator.go +++ b/turbo/shards/state_change_accumulator.go @@ -81,7 +81,7 @@ func (a *Accumulator) ChangeAccount(address common.Address, incarnation uint64, accountChange.Action = remote.Action_UPSERT case remote.Action_CODE: accountChange.Action = remote.Action_UPSERT_CODE - case remote.Action_DELETE: + case remote.Action_REMOVE: panic("") } accountChange.Incarnation = incarnation @@ -104,7 +104,7 @@ func (a *Accumulator) DeleteAccount(address common.Address) { accountChange.Data = nil accountChange.Code = nil accountChange.StorageChanges = nil - accountChange.Action = remote.Action_DELETE + accountChange.Action = remote.Action_REMOVE } // ChangeCode adds code to the latest change @@ -122,7 +122,7 @@ func (a *Accumulator) ChangeCode(address common.Address, incarnation uint64, cod accountChange.Action = remote.Action_CODE case remote.Action_UPSERT: accountChange.Action = remote.Action_UPSERT_CODE - case remote.Action_DELETE: + case remote.Action_REMOVE: panic("") } accountChange.Incarnation = incarnation @@ -138,7 +138,7 @@ func (a *Accumulator) ChangeStorage(address common.Address, incarnation uint64, a.accountChangeIndex[address] = i } accountChange := a.latestChange.Changes[i] - if accountChange.Action == remote.Action_DELETE { + if accountChange.Action == remote.Action_REMOVE { panic("") } accountChange.Incarnation = incarnation From c12f8987fe95a91d4907acaf628b36bea7dd2466 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Sun, 27 Mar 2022 09:47:29 +0100 Subject: [PATCH 203/261] [stable] Event log subscription (#3773) * Logs sub (#3666) * save * Add onLogs * Fix lint * Add proper logs * Update go.mod * goimports * Add unwind * feat/rpcadaemon_logs_sub (#3751) * Fixes to subscribe logs (#3769) * Fixes to subscribe logs * Add criteria to logs subscription * Skeleton of RPC daemon event log distribution * Simplify * Send aggregated filter to Erigon * Change API * Print * Fixes * Fix topics filtering * Fill txHash and blockHash * Timing logs, fill tx index * Print * More print * Print * Asynchronous sending of log events to RPC daemon * Remove prints * Only extract logs if there are subscribers * Check empty when RPC daemon is removed Co-authored-by: Alex Sharp Co-authored-by: Alexey Sharp * Fix up * Update to erigon-lib stable * Update to erigon-lib stable Co-authored-by: primal_concrete_sledge Co-authored-by: Alex Sharp Co-authored-by: Alexey Sharp --- cmd/rpcdaemon/commands/eth_filters.go | 36 +++++ cmd/rpcdaemon/filters/filters.go | 121 ++++++++++++++++ cmd/rpcdaemon/filters/logsfilter.go | 160 +++++++++++++++++++++ cmd/rpcdaemon/services/eth_backend.go | 25 ++++ eth/stagedsync/stage_finish.go | 78 ++++++++++- eth/stagedsync/stagebuilder.go | 3 + ethdb/privateapi/ethbackend.go | 48 ++++++- ethdb/privateapi/events.go | 48 +++++++ ethdb/privateapi/logsfilter.go | 191 ++++++++++++++++++++++++++ go.mod | 2 +- go.sum | 4 +- interfaces.go | 1 - 12 files changed, 705 insertions(+), 12 deletions(-) create mode 100644 cmd/rpcdaemon/filters/logsfilter.go create mode 100644 ethdb/privateapi/logsfilter.go diff --git a/cmd/rpcdaemon/commands/eth_filters.go b/cmd/rpcdaemon/commands/eth_filters.go index ef2a8399ef3..85db9e123ec 100644 --- a/cmd/rpcdaemon/commands/eth_filters.go +++ b/cmd/rpcdaemon/commands/eth_filters.go @@ -7,6 +7,7 @@ import ( "github.com/ledgerwatch/erigon/common/debug" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/eth/filters" "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/log/v3" ) @@ -110,3 +111,38 @@ func (api *APIImpl) NewPendingTransactions(ctx context.Context) (*rpc.Subscripti return rpcSub, nil } + +// SubscribeLogs send a notification each time a new log appears. +func (api *APIImpl) Logs(ctx context.Context, crit filters.FilterCriteria) (*rpc.Subscription, error) { + if api.filters == nil { + return &rpc.Subscription{}, rpc.ErrNotificationsUnsupported + } + notifier, supported := rpc.NotifierFromContext(ctx) + if !supported { + return &rpc.Subscription{}, rpc.ErrNotificationsUnsupported + } + + rpcSub := notifier.CreateSubscription() + + go func() { + defer debug.LogPanic() + logs := make(chan *types.Log, 1) + defer close(logs) + id := api.filters.SubscribeLogs(logs, crit) + defer api.filters.UnsubscribeLogs(id) + + for { + select { + case h := <-logs: + err := notifier.Notify(rpcSub.ID, h) + if err != nil { + log.Warn("error while notifying subscription", "err", err) + } + case <-rpcSub.Err(): + return + } + } + }() + + return rpcSub, nil +} diff --git a/cmd/rpcdaemon/filters/filters.go b/cmd/rpcdaemon/filters/filters.go index 2a26f6769c5..4edde36ad66 100644 --- a/cmd/rpcdaemon/filters/filters.go +++ b/cmd/rpcdaemon/filters/filters.go @@ -9,8 +9,14 @@ import ( "io" "reflect" "sync" + "sync/atomic" "time" + "github.com/ledgerwatch/erigon-lib/gointerfaces" + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/eth/filters" + + "github.com/ledgerwatch/erigon-lib/gointerfaces/grpcutil" "github.com/ledgerwatch/erigon-lib/gointerfaces/remote" "github.com/ledgerwatch/erigon-lib/gointerfaces/txpool" "github.com/ledgerwatch/erigon/cmd/rpcdaemon/services" @@ -28,6 +34,7 @@ type ( PendingLogsSubID SubscriptionID PendingBlockSubID SubscriptionID PendingTxsSubID SubscriptionID + LogsSubID uint64 ) type Filters struct { @@ -39,6 +46,8 @@ type Filters struct { pendingLogsSubs map[PendingLogsSubID]chan types.Logs pendingBlockSubs map[PendingBlockSubID]chan *types.Block pendingTxsSubs map[PendingTxsSubID]chan []types.Transaction + logsSubs *LogsFilterAggregator + logsRequestor atomic.Value } func New(ctx context.Context, ethBackend services.ApiBackend, txPool txpool.TxpoolClient, mining txpool.MiningClient) *Filters { @@ -49,6 +58,7 @@ func New(ctx context.Context, ethBackend services.ApiBackend, txPool txpool.Txpo pendingTxsSubs: make(map[PendingTxsSubID]chan []types.Transaction), pendingLogsSubs: make(map[PendingLogsSubID]chan types.Logs), pendingBlockSubs: make(map[PendingBlockSubID]chan *types.Block), + logsSubs: NewLogsFilterAggregator(), } go func() { @@ -83,6 +93,31 @@ func New(ctx context.Context, ethBackend services.ApiBackend, txPool txpool.Txpo } }() + go func() { + if ethBackend == nil { + return + } + for { + select { + case <-ctx.Done(): + return + default: + } + if err := ethBackend.SubscribeLogs(ctx, ff.OnNewLogs, &ff.logsRequestor); err != nil { + select { + case <-ctx.Done(): + return + default: + } + if grpcutil.IsEndOfStream(err) || grpcutil.IsRetryLater(err) { + time.Sleep(3 * time.Second) + continue + } + log.Warn("rpc filters: error subscribing to logs", "err", err) + } + } + }() + if txPool != nil { go func() { for { @@ -337,6 +372,73 @@ func (ff *Filters) UnsubscribePendingTxs(id PendingTxsSubID) { delete(ff.pendingTxsSubs, id) } +func (ff *Filters) SubscribeLogs(out chan *types.Log, crit filters.FilterCriteria) LogsSubID { + id, f := ff.logsSubs.insertLogsFilter(out) + f.addrs = map[common.Address]int{} + if len(crit.Addresses) == 0 { + f.allAddrs = 1 + } else { + for _, addr := range crit.Addresses { + f.addrs[addr] = 1 + } + } + f.topics = map[common.Hash]int{} + if len(crit.Topics) == 0 { + f.allTopics = 1 + } else { + for _, topics := range crit.Topics { + for _, topic := range topics { + f.topics[topic] = 1 + } + } + } + f.topicsOriginal = crit.Topics + ff.logsSubs.addLogsFilters(f) + lfr := &remote.LogsFilterRequest{ + AllAddresses: ff.logsSubs.aggLogsFilter.allAddrs == 1, + AllTopics: ff.logsSubs.aggLogsFilter.allTopics == 1, + } + for addr := range ff.logsSubs.aggLogsFilter.addrs { + lfr.Addresses = append(lfr.Addresses, gointerfaces.ConvertAddressToH160(addr)) + } + for topic := range ff.logsSubs.aggLogsFilter.topics { + lfr.Topics = append(lfr.Topics, gointerfaces.ConvertHashToH256(topic)) + } + ff.mu.Lock() + defer ff.mu.Unlock() + loaded := ff.logsRequestor.Load() + if loaded != nil { + if err := loaded.(func(*remote.LogsFilterRequest) error)(lfr); err != nil { + log.Warn("Could not update remote logs filter", "err", err) + ff.logsSubs.removeLogsFilter(id) + } + } + return id +} + +func (ff *Filters) UnsubscribeLogs(id LogsSubID) { + ff.logsSubs.removeLogsFilter(id) + lfr := &remote.LogsFilterRequest{ + AllAddresses: ff.logsSubs.aggLogsFilter.allAddrs == 1, + AllTopics: ff.logsSubs.aggLogsFilter.allTopics == 1, + } + for addr := range ff.logsSubs.aggLogsFilter.addrs { + lfr.Addresses = append(lfr.Addresses, gointerfaces.ConvertAddressToH160(addr)) + } + for topic := range ff.logsSubs.aggLogsFilter.topics { + lfr.Topics = append(lfr.Topics, gointerfaces.ConvertHashToH256(topic)) + } + ff.mu.Lock() + defer ff.mu.Unlock() + loaded := ff.logsRequestor.Load() + if loaded != nil { + if err := loaded.(func(*remote.LogsFilterRequest) error)(lfr); err != nil { + log.Warn("Could not update remote logs filter", "err", err) + ff.logsSubs.removeLogsFilter(id) + } + } +} + func (ff *Filters) OnNewEvent(event *remote.SubscribeReply) { ff.mu.RLock() defer ff.mu.RUnlock() @@ -411,6 +513,25 @@ func (ff *Filters) OnNewTx(reply *txpool.OnAddReply) { } } +func (ff *Filters) OnNewLogs(reply *remote.SubscribeLogsReply) { + lg := &types.Log{ + Address: gointerfaces.ConvertH160toAddress(reply.Address), + Data: reply.Data, + BlockNumber: reply.BlockNumber, + TxHash: gointerfaces.ConvertH256ToHash(reply.TransactionHash), + TxIndex: uint(reply.TransactionIndex), + BlockHash: gointerfaces.ConvertH256ToHash(reply.BlockHash), + Index: uint(reply.LogIndex), + Removed: reply.Removed, + } + t := make([]common.Hash, 0) + for _, v := range reply.Topics { + t = append(t, gointerfaces.ConvertH256ToHash(v)) + } + lg.Topics = t + ff.logsSubs.distributeLog(reply) +} + func generateSubscriptionID() SubscriptionID { var id [32]byte diff --git a/cmd/rpcdaemon/filters/logsfilter.go b/cmd/rpcdaemon/filters/logsfilter.go new file mode 100644 index 00000000000..7d1cbb35991 --- /dev/null +++ b/cmd/rpcdaemon/filters/logsfilter.go @@ -0,0 +1,160 @@ +package filters + +import ( + "sync" + + "github.com/ledgerwatch/erigon-lib/gointerfaces" + "github.com/ledgerwatch/erigon-lib/gointerfaces/remote" + "github.com/ledgerwatch/erigon/common" + types2 "github.com/ledgerwatch/erigon/core/types" +) + +type LogsFilterAggregator struct { + aggLogsFilter LogsFilter // Aggregation of all current log filters + logsFilters map[LogsSubID]*LogsFilter // Filter for each subscriber, keyed by filterID + logsFilterLock sync.Mutex + nextFilterId LogsSubID +} + +// LogsFilter is used for both representing log filter for a specific subscriber (RPC daemon usually) +// and "aggregated" log filter representing a union of all subscribers. Therefore, the values in +// the mappings are counters (of type int) and they get deleted when counter goes back to 0 +// Also, addAddr and allTopic are int instead of bool because they are also counter, counting +// how many subscribers have this set on +type LogsFilter struct { + allAddrs int + addrs map[common.Address]int + allTopics int + topics map[common.Hash]int + topicsOriginal [][]common.Hash // Original topic filters to be applied before distributing to individual subscribers + sender chan *types2.Log // nil for aggregate subscriber, for appropriate stream server otherwise +} + +func NewLogsFilterAggregator() *LogsFilterAggregator { + return &LogsFilterAggregator{ + aggLogsFilter: LogsFilter{ + addrs: make(map[common.Address]int), + topics: make(map[common.Hash]int), + }, + logsFilters: make(map[LogsSubID]*LogsFilter), + nextFilterId: 0, + } +} + +func (a *LogsFilterAggregator) insertLogsFilter(sender chan *types2.Log) (LogsSubID, *LogsFilter) { + a.logsFilterLock.Lock() + defer a.logsFilterLock.Unlock() + filterId := a.nextFilterId + a.nextFilterId++ + filter := &LogsFilter{addrs: map[common.Address]int{}, topics: map[common.Hash]int{}, sender: sender} + a.logsFilters[filterId] = filter + return filterId, filter +} + +func (a *LogsFilterAggregator) removeLogsFilter(filterId LogsSubID) { + a.logsFilterLock.Lock() + defer a.logsFilterLock.Unlock() + if filter, ok := a.logsFilters[filterId]; ok { + a.subtractLogFilters(filter) + delete(a.logsFilters, filterId) + } +} + +func (a *LogsFilterAggregator) subtractLogFilters(f *LogsFilter) { + a.aggLogsFilter.allAddrs -= f.allAddrs + for addr, count := range f.addrs { + a.aggLogsFilter.addrs[addr] -= count + if a.aggLogsFilter.addrs[addr] == 0 { + delete(a.aggLogsFilter.addrs, addr) + } + } + a.aggLogsFilter.allTopics -= f.allTopics + for topic, count := range f.topics { + a.aggLogsFilter.topics[topic] -= count + if a.aggLogsFilter.topics[topic] == 0 { + delete(a.aggLogsFilter.topics, topic) + } + } +} + +func (a *LogsFilterAggregator) addLogsFilters(f *LogsFilter) { + a.aggLogsFilter.allAddrs += f.allAddrs + for addr, count := range f.addrs { + a.aggLogsFilter.addrs[addr] += count + } + a.aggLogsFilter.allTopics += f.allTopics + for topic, count := range f.topics { + a.aggLogsFilter.topics[topic] += count + } +} + +func (a *LogsFilterAggregator) distributeLog(eventLog *remote.SubscribeLogsReply) error { + a.logsFilterLock.Lock() + defer a.logsFilterLock.Unlock() + filtersToDelete := make(map[LogsSubID]*LogsFilter) + for _, filter := range a.logsFilters { + if filter.allAddrs == 0 { + _, addrOk := filter.addrs[gointerfaces.ConvertH160toAddress(eventLog.Address)] + if !addrOk { + continue + } + } + var topics []common.Hash + for _, topic := range eventLog.Topics { + topics = append(topics, gointerfaces.ConvertH256ToHash(topic)) + } + if filter.allTopics == 0 { + if !a.chooseTopics(filter, topics) { + continue + } + } + lg := &types2.Log{ + Address: gointerfaces.ConvertH160toAddress(eventLog.Address), + Topics: topics, + Data: eventLog.Data, + BlockNumber: eventLog.BlockNumber, + TxHash: gointerfaces.ConvertH256ToHash(eventLog.TransactionHash), + TxIndex: uint(eventLog.TransactionIndex), + BlockHash: gointerfaces.ConvertH256ToHash(eventLog.BlockHash), + Index: uint(eventLog.LogIndex), + Removed: eventLog.Removed, + } + filter.sender <- lg + } + // remove malfunctioned filters + for filterId, filter := range filtersToDelete { + a.subtractLogFilters(filter) + delete(a.logsFilters, filterId) + } + + return nil +} + +func (a *LogsFilterAggregator) chooseTopics(filter *LogsFilter, logTopics []common.Hash) bool { + var found bool + for _, logTopic := range logTopics { + if _, ok := filter.topics[logTopic]; ok { + found = true + break + } + } + if !found { + return false + } + if len(filter.topicsOriginal) > len(logTopics) { + return false + } + for i, sub := range filter.topicsOriginal { + match := len(sub) == 0 // empty rule set == wildcard + for _, topic := range sub { + if logTopics[i] == topic { + match = true + break + } + } + if !match { + return false + } + } + return true +} diff --git a/cmd/rpcdaemon/services/eth_backend.go b/cmd/rpcdaemon/services/eth_backend.go index e4088b72961..3182594a247 100644 --- a/cmd/rpcdaemon/services/eth_backend.go +++ b/cmd/rpcdaemon/services/eth_backend.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "io" + "sync/atomic" "github.com/ledgerwatch/erigon-lib/gointerfaces" "github.com/ledgerwatch/erigon-lib/gointerfaces/remote" @@ -28,6 +29,7 @@ type ApiBackend interface { ProtocolVersion(ctx context.Context) (uint64, error) ClientVersion(ctx context.Context) (string, error) Subscribe(ctx context.Context, cb func(*remote.SubscribeReply)) error + SubscribeLogs(ctx context.Context, cb func(*remote.SubscribeLogsReply), requestor *atomic.Value) error NodeInfo(ctx context.Context, limit uint32) ([]p2p.NodeInfo, error) } @@ -145,6 +147,29 @@ func (back *RemoteBackend) Subscribe(ctx context.Context, onNewEvent func(*remot return nil } +func (back *RemoteBackend) SubscribeLogs(ctx context.Context, onNewLogs func(reply *remote.SubscribeLogsReply), requestor *atomic.Value) error { + subscription, err := back.remoteEthBackend.SubscribeLogs(ctx, grpc.WaitForReady(true)) + if err != nil { + if s, ok := status.FromError(err); ok { + return errors.New(s.Message()) + } + return err + } + requestor.Store(subscription.Send) + for { + logs, err := subscription.Recv() + if errors.Is(err, io.EOF) { + log.Info("rpcdaemon: the logs subscription channel was closed") + break + } + if err != nil { + return err + } + onNewLogs(logs) + } + return nil +} + func (back *RemoteBackend) NodeInfo(ctx context.Context, limit uint32) ([]p2p.NodeInfo, error) { nodes, err := back.remoteEthBackend.NodeInfo(ctx, &remote.NodesInfoRequest{Limit: limit}) if err != nil { diff --git a/eth/stagedsync/stage_finish.go b/eth/stagedsync/stage_finish.go index 9982528d4d1..da2a038feaf 100644 --- a/eth/stagedsync/stage_finish.go +++ b/eth/stagedsync/stage_finish.go @@ -1,14 +1,22 @@ package stagedsync import ( + "bytes" "context" "encoding/binary" + "fmt" + "time" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/gointerfaces" + "github.com/ledgerwatch/erigon-lib/gointerfaces/remote" + types2 "github.com/ledgerwatch/erigon-lib/gointerfaces/types" "github.com/ledgerwatch/erigon-lib/kv" common2 "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/dbutils" "github.com/ledgerwatch/erigon/core/rawdb" + "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/ethdb/cbor" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/log/v3" ) @@ -108,14 +116,17 @@ func PruneFinish(u *PruneState, tx kv.RwTx, cfg FinishCfg, ctx context.Context) } func NotifyNewHeaders(ctx context.Context, finishStageBeforeSync uint64, finishStageAfterSync uint64, unwindTo *uint64, notifier ChainEventNotifier, tx kv.Tx) error { + t := time.Now() if notifier == nil { log.Trace("RPC Daemon notification channel not set. No headers notifications will be sent") return nil } // Notify all headers we have (either canonical or not) in a maximum range span of 1024 var notifyFrom uint64 + var isUnwind bool if unwindTo != nil && *unwindTo != 0 && (*unwindTo) < finishStageBeforeSync { notifyFrom = *unwindTo + isUnwind = true } else { heightSpan := finishStageAfterSync - finishStageBeforeSync if heightSpan > 1024 { @@ -139,7 +150,70 @@ func NotifyNewHeaders(ctx context.Context, finishStageBeforeSync uint64, finishS return err } notifier.OnNewHeader(headersRlp) - - log.Info("RPC Daemon notified of new headers", "from", notifyFrom-1, "to", notifyTo) + headerTiming := time.Since(t) + t = time.Now() + if notifier.HasLogSubsriptions() { + logs, err := ReadLogs(tx, notifyFrom, isUnwind) + if err != nil { + return err + } + notifier.OnLogs(logs) + } + logTiming := time.Since(t) + log.Info("RPC Daemon notified of new headers", "from", notifyFrom-1, "to", notifyTo, "header sending", headerTiming, "log sending", logTiming) return nil } + +func ReadLogs(tx kv.Tx, from uint64, isUnwind bool) ([]*remote.SubscribeLogsReply, error) { + logs, err := tx.Cursor(kv.Log) + if err != nil { + return nil, err + } + defer logs.Close() + reply := make([]*remote.SubscribeLogsReply, 0) + reader := bytes.NewReader(nil) + + var prevBlockNum uint64 + var block *types.Block + var logIndex uint64 + for k, v, err := logs.Seek(dbutils.LogKey(from, 0)); k != nil; k, v, err = logs.Next() { + if err != nil { + return nil, err + } + blockNum := binary.BigEndian.Uint64(k[:8]) + if block == nil || blockNum != prevBlockNum { + logIndex = 0 + prevBlockNum = blockNum + if block, err = rawdb.ReadBlockByNumber(tx, blockNum); err != nil { + return nil, err + } + } + txIndex := uint64(binary.BigEndian.Uint32(k[8:])) + txHash := block.Transactions()[txIndex].Hash() + var ll types.Logs + reader.Reset(v) + if err := cbor.Unmarshal(&ll, reader); err != nil { + return nil, fmt.Errorf("receipt unmarshal failed: %w, blocl=%d", err, blockNum) + } + for _, l := range ll { + r := &remote.SubscribeLogsReply{ + Address: gointerfaces.ConvertAddressToH160(l.Address), + BlockHash: gointerfaces.ConvertHashToH256(block.Hash()), + BlockNumber: blockNum, + Data: l.Data, + LogIndex: logIndex, + Topics: make([]*types2.H256, 0, len(l.Topics)), + TransactionHash: gointerfaces.ConvertHashToH256(txHash), + TransactionIndex: txIndex, + Removed: isUnwind, + } + logIndex++ + for _, topic := range l.Topics { + r.Topics = append(r.Topics, gointerfaces.ConvertHashToH256(topic)) + } + reply = append(reply, r) + } + } + + return reply, nil +} diff --git a/eth/stagedsync/stagebuilder.go b/eth/stagedsync/stagebuilder.go index 14141a6922e..408f1af8042 100644 --- a/eth/stagedsync/stagebuilder.go +++ b/eth/stagedsync/stagebuilder.go @@ -3,6 +3,7 @@ package stagedsync import ( "context" + "github.com/ledgerwatch/erigon-lib/gointerfaces/remote" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/eth/stagedsync/stages" @@ -13,6 +14,8 @@ import ( type ChainEventNotifier interface { OnNewHeader(newHeadersRlp [][]byte) OnNewPendingLogs(types.Logs) + OnLogs([]*remote.SubscribeLogsReply) + HasLogSubsriptions() bool } type Notifications struct { diff --git a/ethdb/privateapi/ethbackend.go b/ethdb/privateapi/ethbackend.go index c5f3f65f38d..972f1fa4c2a 100644 --- a/ethdb/privateapi/ethbackend.go +++ b/ethdb/privateapi/ethbackend.go @@ -2,6 +2,8 @@ package privateapi import ( "context" + "errors" + "fmt" "github.com/ledgerwatch/erigon-lib/gointerfaces" "github.com/ledgerwatch/erigon-lib/gointerfaces/remote" @@ -16,14 +18,15 @@ import ( // 2.0.0 - move all mining-related methods to 'txpool/mining' server // 2.1.0 - add NetPeerCount function // 2.2.0 - add NodesInfo function -var EthBackendAPIVersion = &types2.VersionReply{Major: 2, Minor: 2, Patch: 0} +// 2.3.0 - add Subscribe to logs +var EthBackendAPIVersion = &types2.VersionReply{Major: 2, Minor: 3, Patch: 0} type EthBackendServer struct { remote.UnimplementedETHBACKENDServer // must be embedded to have forward compatible implementations. - - ctx context.Context - eth EthBackend - events *Events + ctx context.Context + eth EthBackend + events *Events + logsFilter *LogsFilterAggregator } type EthBackend interface { @@ -34,7 +37,33 @@ type EthBackend interface { } func NewEthBackendServer(ctx context.Context, eth EthBackend, events *Events) *EthBackendServer { - return &EthBackendServer{ctx: ctx, eth: eth, events: events} + s := &EthBackendServer{ctx: ctx, eth: eth, events: events, logsFilter: NewLogsFilterAggregator(events)} + + ch, clean := s.events.AddLogsSubscription() + go func() { + var err error + defer clean() + log.Info("new subscription to logs established") + defer func() { + if err != nil { + if !errors.Is(err, context.Canceled) { + log.Warn("subscription to logs closed", "reason", err) + } + } else { + log.Warn("subscription to logs closed") + } + }() + for { + select { + case <-s.ctx.Done(): + err = s.ctx.Err() + return + case logs := <-ch: + s.logsFilter.distributeLogs(logs) + } + } + }() + return s } func (s *EthBackendServer) Version(context.Context, *emptypb.Empty) (*types2.VersionReply, error) { @@ -116,3 +145,10 @@ func (s *EthBackendServer) NodeInfo(_ context.Context, r *remote.NodesInfoReques } return nodesInfo, nil } + +func (s *EthBackendServer) SubscribeLogs(server remote.ETHBACKEND_SubscribeLogsServer) (err error) { + if s.logsFilter != nil { + return s.logsFilter.subscribeLogs(server) + } + return fmt.Errorf("no logs filter available") +} diff --git a/ethdb/privateapi/events.go b/ethdb/privateapi/events.go index ed42c880df0..babc1104847 100644 --- a/ethdb/privateapi/events.go +++ b/ethdb/privateapi/events.go @@ -3,6 +3,7 @@ package privateapi import ( "sync" + "github.com/ledgerwatch/erigon-lib/gointerfaces/remote" "github.com/ledgerwatch/erigon/core/types" ) @@ -12,6 +13,7 @@ type HeaderSubscription func(headerRLP []byte) error type PendingLogsSubscription func(types.Logs) error type PendingBlockSubscription func(*types.Block) error type PendingTxsSubscription func([]types.Transaction) error +type LogsSubscription func([]*remote.SubscribeLogsReply) error // Events manages event subscriptions and dissimination. Thread-safe type Events struct { @@ -20,6 +22,8 @@ type Events struct { pendingLogsSubscriptions map[int]PendingLogsSubscription pendingBlockSubscriptions map[int]PendingBlockSubscription pendingTxsSubscriptions map[int]PendingTxsSubscription + logsSubscriptions map[int]chan []*remote.SubscribeLogsReply + hasLogSubscriptions bool lock sync.RWMutex } @@ -29,6 +33,7 @@ func NewEvents() *Events { pendingLogsSubscriptions: map[int]PendingLogsSubscription{}, pendingBlockSubscriptions: map[int]PendingBlockSubscription{}, pendingTxsSubscriptions: map[int]PendingTxsSubscription{}, + logsSubscriptions: map[int]chan []*remote.SubscribeLogsReply{}, } } @@ -45,6 +50,31 @@ func (e *Events) AddHeaderSubscription() (chan [][]byte, func()) { } } +func (e *Events) AddLogsSubscription() (chan []*remote.SubscribeLogsReply, func()) { + e.lock.Lock() + defer e.lock.Unlock() + ch := make(chan []*remote.SubscribeLogsReply, 8) + e.id++ + id := e.id + e.logsSubscriptions[id] = ch + return ch, func() { + delete(e.logsSubscriptions, id) + close(ch) + } +} + +func (e *Events) EmptyLogSubsctiption(empty bool) { + e.lock.Lock() + defer e.lock.Unlock() + e.hasLogSubscriptions = !empty +} + +func (e *Events) HasLogSubsriptions() bool { + e.lock.RLock() + defer e.lock.RUnlock() + return e.hasLogSubscriptions +} + func (e *Events) AddPendingLogsSubscription(s PendingLogsSubscription) { e.lock.Lock() defer e.lock.Unlock() @@ -84,3 +114,21 @@ func (e *Events) OnNewPendingLogs(logs types.Logs) { } } } + +func (e *Events) OnLogs(logs []*remote.SubscribeLogsReply) { + e.lock.Lock() + defer e.lock.Unlock() + for _, ch := range e.logsSubscriptions { + select { + case ch <- logs: + default: //if channel is full (slow consumer), drop old messages + for i := 0; i < cap(ch)/2; i++ { + select { + case <-ch: + default: + } + } + ch <- logs + } + } +} diff --git a/ethdb/privateapi/logsfilter.go b/ethdb/privateapi/logsfilter.go new file mode 100644 index 00000000000..93b6a09a730 --- /dev/null +++ b/ethdb/privateapi/logsfilter.go @@ -0,0 +1,191 @@ +package privateapi + +import ( + "fmt" + "io" + "sync" + + "github.com/ledgerwatch/erigon-lib/gointerfaces" + "github.com/ledgerwatch/erigon-lib/gointerfaces/remote" + "github.com/ledgerwatch/erigon-lib/gointerfaces/types" + "github.com/ledgerwatch/erigon/common" +) + +type LogsFilterAggregator struct { + aggLogsFilter LogsFilter // Aggregation of all current log filters + logsFilters map[uint64]*LogsFilter // Filter for each subscriber, keyed by filterID + logsFilterLock sync.Mutex + nextFilterId uint64 + events *Events +} + +// LogsFilter is used for both representing log filter for a specific subscriber (RPC daemon usually) +// and "aggregated" log filter representing a union of all subscribers. Therefore, the values in +// the mappings are counters (of type int) and they get deleted when counter goes back to 0 +// Also, addAddr and allTopic are int instead of bool because they are also counter, counting +// how many subscribers have this set on +type LogsFilter struct { + allAddrs int + addrs map[common.Address]int + allTopics int + topics map[common.Hash]int + sender remote.ETHBACKEND_SubscribeLogsServer // nil for aggregate subscriber, for appropriate stream server otherwise +} + +func NewLogsFilterAggregator(events *Events) *LogsFilterAggregator { + return &LogsFilterAggregator{ + aggLogsFilter: LogsFilter{ + addrs: make(map[common.Address]int), + topics: make(map[common.Hash]int), + }, + logsFilters: make(map[uint64]*LogsFilter), + nextFilterId: 0, + events: events, + } +} + +func (a *LogsFilterAggregator) insertLogsFilter(sender remote.ETHBACKEND_SubscribeLogsServer) (uint64, *LogsFilter) { + a.logsFilterLock.Lock() + defer a.logsFilterLock.Unlock() + filterId := a.nextFilterId + a.nextFilterId++ + filter := &LogsFilter{addrs: make(map[common.Address]int), topics: make(map[common.Hash]int), sender: sender} + a.logsFilters[filterId] = filter + return filterId, filter +} + +func (a *LogsFilterAggregator) checkEmpty() { + a.events.EmptyLogSubsctiption(a.aggLogsFilter.allAddrs == 0 && len(a.aggLogsFilter.addrs) == 0 && a.aggLogsFilter.allTopics == 0 && len(a.aggLogsFilter.topics) == 0) +} + +func (a *LogsFilterAggregator) removeLogsFilter(filterId uint64, filter *LogsFilter) { + a.logsFilterLock.Lock() + defer a.logsFilterLock.Unlock() + a.subtractLogFilters(filter) + delete(a.logsFilters, filterId) + a.checkEmpty() +} + +func (a *LogsFilterAggregator) updateLogsFilter(filter *LogsFilter, filterReq *remote.LogsFilterRequest) { + a.logsFilterLock.Lock() + defer a.logsFilterLock.Unlock() + a.subtractLogFilters(filter) + filter.addrs = make(map[common.Address]int) + if filterReq.GetAllAddresses() { + filter.allAddrs = 1 + } else { + filter.allAddrs = 0 + for _, addr := range filterReq.GetAddresses() { + filter.addrs[gointerfaces.ConvertH160toAddress(addr)] = 1 + } + } + filter.topics = make(map[common.Hash]int) + if filterReq.GetAllTopics() { + filter.allTopics = 1 + } else { + filter.allTopics = 0 + for _, topic := range filterReq.GetTopics() { + filter.topics[gointerfaces.ConvertH256ToHash(topic)] = 1 + } + } + a.addLogsFilters(filter) + a.checkEmpty() +} + +func (a *LogsFilterAggregator) subtractLogFilters(f *LogsFilter) { + a.aggLogsFilter.allAddrs -= f.allAddrs + for addr, count := range f.addrs { + a.aggLogsFilter.addrs[addr] -= count + if a.aggLogsFilter.addrs[addr] == 0 { + delete(a.aggLogsFilter.addrs, addr) + } + } + a.aggLogsFilter.allTopics -= f.allTopics + for topic, count := range f.topics { + a.aggLogsFilter.topics[topic] -= count + if a.aggLogsFilter.topics[topic] == 0 { + delete(a.aggLogsFilter.topics, topic) + } + } +} + +func (a *LogsFilterAggregator) addLogsFilters(f *LogsFilter) { + a.aggLogsFilter.allAddrs += f.allAddrs + for addr, count := range f.addrs { + a.aggLogsFilter.addrs[addr] += count + } + a.aggLogsFilter.allTopics += f.allTopics + for topic, count := range f.topics { + a.aggLogsFilter.topics[topic] += count + } +} + +// SubscribeLogs +// Only one subscription is needed to serve all the users, LogsFilterRequest allows to dynamically modifying the subscription +func (a *LogsFilterAggregator) subscribeLogs(server remote.ETHBACKEND_SubscribeLogsServer) error { + filterId, filter := a.insertLogsFilter(server) + defer a.removeLogsFilter(filterId, filter) + // Listen to filter updates and modify the filters, until terminated + var filterReq *remote.LogsFilterRequest + var recvErr error + for filterReq, recvErr = server.Recv(); recvErr == nil; filterReq, recvErr = server.Recv() { + a.updateLogsFilter(filter, filterReq) + } + if recvErr != nil && recvErr != io.EOF { // termination + return fmt.Errorf("receiving log filter request: %w", recvErr) + } + return nil +} + +func (a *LogsFilterAggregator) distributeLogs(logs []*remote.SubscribeLogsReply) error { + a.logsFilterLock.Lock() + defer a.logsFilterLock.Unlock() + + filtersToDelete := make(map[uint64]*LogsFilter) +outerLoop: + for _, log := range logs { + // Use aggregate filter first + if a.aggLogsFilter.allAddrs == 0 { + if _, addrOk := a.aggLogsFilter.addrs[gointerfaces.ConvertH160toAddress(log.Address)]; !addrOk { + continue + } + } + if a.aggLogsFilter.allTopics == 0 { + if !a.chooseTopics(a.aggLogsFilter.topics, log.GetTopics()) { + continue + } + } + for filterId, filter := range a.logsFilters { + if filter.allAddrs == 0 { + if _, addrOk := filter.addrs[gointerfaces.ConvertH160toAddress(log.Address)]; !addrOk { + continue + } + } + if filter.allTopics == 0 { + if !a.chooseTopics(filter.topics, log.GetTopics()) { + continue + } + } + if err := filter.sender.Send(log); err != nil { + filtersToDelete[filterId] = filter + continue outerLoop + } + } + } + // remove malfunctioned filters + for filterId, filter := range filtersToDelete { + a.subtractLogFilters(filter) + delete(a.logsFilters, filterId) + } + + return nil +} + +func (a *LogsFilterAggregator) chooseTopics(filterTopics map[common.Hash]int, logTopics []*types.H256) bool { + for _, logTopic := range logTopics { + if _, ok := filterTopics[gointerfaces.ConvertH256ToHash(logTopic)]; ok { + return true + } + } + return false +} diff --git a/go.mod b/go.mod index dcd324d2c0e..9f653e59265 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20220327025752-a815df5b646d + github.com/ledgerwatch/erigon-lib v0.0.0-20220327062501-84f0d06450aa github.com/ledgerwatch/log/v3 v3.4.1 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 diff --git a/go.sum b/go.sum index 79db4189ae1..ff0bc01d920 100644 --- a/go.sum +++ b/go.sum @@ -493,8 +493,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20220327025752-a815df5b646d h1:mvNXkThZb0IrOqSsEZpAWSrClmeK95dM/ZWQGSIzxkQ= -github.com/ledgerwatch/erigon-lib v0.0.0-20220327025752-a815df5b646d/go.mod h1:DuTHf07xXPh3sf0ON0Fsab3bNnqS+XVeKTFUN9Pv36Q= +github.com/ledgerwatch/erigon-lib v0.0.0-20220327062501-84f0d06450aa h1:sogweFOU1SLPLZRL69cRRSRBLwDC+nNV9+EB0T72+ho= +github.com/ledgerwatch/erigon-lib v0.0.0-20220327062501-84f0d06450aa/go.mod h1:DuTHf07xXPh3sf0ON0Fsab3bNnqS+XVeKTFUN9Pv36Q= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/log/v3 v3.4.1 h1:/xGwlVulXnsO9Uq+tzaExc8OWmXXHU0dnLalpbnY5Bc= github.com/ledgerwatch/log/v3 v3.4.1/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= diff --git a/interfaces.go b/interfaces.go index fcc74c33404..4b96275bcd3 100644 --- a/interfaces.go +++ b/interfaces.go @@ -23,7 +23,6 @@ import ( "math/big" "github.com/holiman/uint256" - "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/core/types" ) From 58f23b81193b1dbd663c04f340d38b88d3693c91 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Sun, 27 Mar 2022 09:47:36 +0100 Subject: [PATCH 204/261] Update version.go (#3776) --- params/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/params/version.go b/params/version.go index 397f830801a..da6ea7afc09 100644 --- a/params/version.go +++ b/params/version.go @@ -33,7 +33,7 @@ var ( const ( VersionMajor = 2022 // Major version component of the current release VersionMinor = 3 // Minor version component of the current release - VersionMicro = 1 // Patch version component of the current release + VersionMicro = 2 // Patch version component of the current release VersionModifier = "beta" // Patch version component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" From 997846fc4fb3fc99856679aa7407cad644cbc34b Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Sun, 27 Mar 2022 10:40:05 +0100 Subject: [PATCH 205/261] Update Skip analysis and preverified hashes (#3777) (#3778) * Update skip analysis * Add preverified hashes for mainnet and ropsten * preverified hashes and bootnode for sepolia Co-authored-by: Alexey Sharp Co-authored-by: Alexey Sharp --- core/skip_analysis.go | 2 +- params/bootnodes.go | 2 +- .../preverified_hashes_mainnet.go | 389 ++++- .../preverified_hashes_ropsten.go | 263 +++- .../preverified_hashes_sepolia.go | 1356 ++++++++++++++++- 5 files changed, 2007 insertions(+), 5 deletions(-) diff --git a/core/skip_analysis.go b/core/skip_analysis.go index 168285d1285..82d4ca47148 100644 --- a/core/skip_analysis.go +++ b/core/skip_analysis.go @@ -21,7 +21,7 @@ import ( ) // MainnetNotCheckedFrom is the first block number not yet checked for invalid jumps -const MainnetNotCheckedFrom uint64 = 14390050 +const MainnetNotCheckedFrom uint64 = 14464300 // SkipAnalysis function tells us whether we can skip performing jumpdest analysis // for the historical blocks (on mainnet now but perhaps on the testsnets diff --git a/params/bootnodes.go b/params/bootnodes.go index c2457e481e9..b3825f606b1 100644 --- a/params/bootnodes.go +++ b/params/bootnodes.go @@ -35,7 +35,7 @@ var MainnetBootnodes = []string{ // SepoliaBootnodes are the enode URLs of the P2P bootstrap nodes running on the // Sepolia test network. var SepoliaBootnodes = []string{ - "enode://7c9740e4d64674801fe62b76798d46778a038c49caebb15843d8c0f2b2f80d7ceba2585b4be366e6161988f81ddcfcd6fca98b5da52ae9a6f22c1b2a84b24a04@18.130.169.73:30303", + "enode://9246d00bc8fd1742e5ad2428b80fc4dc45d786283e05ef6edbd9002cbc335d40998444732fbe921cb88e1d2c73d1b1de53bae6a2237996e9bfe14f871baf7066@18.168.182.86:30303", "enode://ec66ddcf1a974950bd4c782789a7e04f8aa7110a72569b6e65fcd51e937e74eed303b1ea734e4d19cfaec9fbff9b6ee65bf31dcb50ba79acce9dd63a6aca61c7@52.14.151.177:30303", } diff --git a/turbo/stages/headerdownload/preverified_hashes_mainnet.go b/turbo/stages/headerdownload/preverified_hashes_mainnet.go index 0cff53b78c8..492969f1143 100644 --- a/turbo/stages/headerdownload/preverified_hashes_mainnet.go +++ b/turbo/stages/headerdownload/preverified_hashes_mainnet.go @@ -74950,6 +74950,393 @@ var mainnetPreverifiedHashes = []string{ "eff18470027c56569b73d2308fed1ae46fc3426859e3507c292e356629ea0da2", "8e74d8281a076266018a45e431b130a59dec429d2d901eb320c9f4b8ffaaa67e", "d511db93dfb3abb9984dd2d48ae77e1a12b72c9578f764bba9950683dd252640", + "4fbb55c91218ddecee8fd4d2d5f532c479640e4fc7f61530a7bf9d0d3a2d8dd4", + "ed1cb2ad317c59a60934ca01f2124822a662f1a1dafccbf382ff73f10c34398b", + "bd0a21c68d90fa2cd8b09a12c047ef967273380e1801e45fee47fd5717f5b976", + "7bf1cb030bdbc5ec91d5396b0f41ea926cbd37622699c2f2515f7352948f8b0c", + "cf3950d33120bfb6d88d410edb1b55f085963bea618e2499ae8bd88233079591", + "ba347de9e9d4e4af9096e9b1c51c94435e039a5438be69ce56bbbeb76ce16e81", + "e587d1cf7c546a499d4d86c3b0e0d0540359dff430d14ef936d600d8f1046a4a", + "25b5d87e7fa5d569b9eb4f0a7a4ae7a6560a300145c731239c6629a8fb7f206c", + "a8052250b56d8411560fdb7b34a140590f5515a6fa672f105a8415187cab464a", + "a38d6ed108c5cb49f2e355a7d5cc7d536423a921a4b48e3638db480cae639bde", + "5498eb2907f7f8b25baaa4a5526c4481c536f9d137c18d90de67e589a27fb938", + "128f4480aa17186cd460e12bf7e6157711dbe290cc50cd03ff9bcbbd9d4ce795", + "df18d857c9d2a8221c48f751790c209b9d2880406817f012207ee9f85076881b", + "b61cb94a063c0a5aa80a8a2ab7aef60b4a2cef5fa5812c31b1f9defa9f86a813", + "354282f86a98fe14e2af959528d03b569b7303fe538be806d723fd42501d9e0b", + "537d5805dc6d3e3adfb569f264ab88714eceb202501d933a5e8a572bb3cf43fa", + "fcd743d201c562fb9736671d0dac3fa7df9833a8138913b3a53e2dd6eca38fba", + "733a692bb33f08b14fb5691ea15c0f3437f9565465c65611196c146b63e96722", + "c733de3bd253e1a37a74aa097593670e8801b4cbb6f509ffa9cb00eec4182b59", + "317a738ab0df7d4c5bf005b120703a6952296a4b86e66f83b728a640b4c11abd", + "f463e4443ee03ae9f030b37b5b23b59621719fc627ac411ebc0a16c110eb11e9", + "55ce7acf24ebac4f1fbfe6ae2de5d9abf5910586057278bf4d4e16ad9dd8f491", + "55265dc4dd4b1649fa9e20d555acbe097095750d80bd0ddb315c156e93412958", + "bf62e5200948724b36bd6103c708d1d1e13147b2bc809c5dfde03147e6bc6197", + "1afac72331dcaf1f223f2e866fff0ac82acd1feb9f9fb264db6cd6dc818f0248", + "2f689d01d004a6f4eb4a905cbcfe8e4d0e1eb434faaa439a46e3376c55767b12", + "9f4ccf4806ad9c1525af3f6d9146f8bada019f048260f8d6b485dc186b56dd25", + "e277daf3b70bfeb366ec4c614b76dec6d2ebd20ca514be63ba307463016f05b2", + "c0f8d39b80bd95db1ec462f747981f26c75aefa708e73b842d586699a948896e", + "314f8c29def26598bda6ef6ba45e44e1d0c8fd6f7de3eeb650bb0b0df949d996", + "837ad028eb8d360c9b768a9e5cac55033ad5afce5e129950928a8edde43e78db", + "feb8b5ab6fd58fe4b91624c5c07673663d091300f96149c6a3ab1ed466f6fc20", + "c2f71a0ab6eff03e9418ccbdca095d06c3146422f41b5aad7579a2c8ad4a8518", + "6e001b0cc162b00bc472a10207c742d0292371a4f7858be1e7c92f1591d47a7e", + "9115cd49d3245240086564b3240337d9dd525fe82d00302e35a10b39524baa0b", + "04b3bee4023f3b31ba362cff944dabb2b78a50a43120bc6568633b26e7d6c553", + "e8256f1fa7094bc25fb70f72220d64fe57de9ce550cbe0ee133fd2b928866b65", + "953ff24826647f41787bc60e20fc16544f30c41c1526765075fdee1cd38b0b25", + "a6e48b137e0b79dfc064e7b883471e99511fbb79ee448f3b10caf7c41f7f8669", + "07a7dc5f0eac58b94805f5f7c17348108b59618c3df2ad6cd4778cd85bd061fe", + "29c638a6936ccfc1f099d78b3ebcbaa0f0b3a7db9150e7eae937d969e5c9e8b8", + "96ecfd494b740eefe0fdbced0e411fe81a74e6b24535d90710c8eecb7aed78ff", + "568bab7e35255f2aeb91cec2661a529eedb58296edfadc9a25f879a70792a230", + "916f51dadf9417d023aec218bbd72bfffc7ada533210d3d4a3d83c25abf86797", + "e6c82b25a38e3c990cd89078c8d62f410ac78a412b5da2fd82c61b01f5ee488b", + "b12861d01d2c93bb460f8bdaab12ea03d3767e1709f9b3d4664e205501591202", + "51199bb5105d98a19462d92c23666fe3db2d7221e8e70f2ecd3c22047fa8359d", + "8d480b3f4ca0cc0fc8a328ec2d7fe291882c32ac4490c172056fc3a4ce257c55", + "9c393f81cab03a421734f5fd1b267efe64e5c70950dc9e0a3f43b0c83433bda2", + "3c73ba6dd523c5272f0f940ebd1ffb4a74b2babaca10adfa3b5a00148266ac23", + "abbff7106c801ef44a9716b67deb230f6613305f1355de2a198cf47c112326a5", + "d6fc5074e4f21a511f69b6258c40df8cb5f9ea5e3bf3cfd2c19326dd81eba2b8", + "0fe61ece07da0a855fd3f09086141f5cff7e64ef520589756ee00a89a57f42f8", + "0a46089e9d1706b084045444523225c2c91018a323acbc4de7195c47aee208ce", + "8f9e6f717964209cbbf48b8f3169cee953fb5d2fed03579cbd4c62f2c3729a00", + "554f6185592f2960f5a3092ccad5d4ceb47dd485043d02bdd064c9fcf38f010f", + "e61d8a00471409d9ac7787359f1add7505bed35f5591f3fb712a625cf65cb41e", + "e80e7a67547812266bad31a14b79729a734f5b8862d16addd6f482ed920d3982", + "c6f87fc88c109a55339ac31a34dcf6ec9786d602b1f18139a2d29e512a0f1839", + "aba7dc06c1f4effb0da772c1d0d0f5ce160a46ab323bfc9e6ba77a207bbf33c4", + "db1d455a2a47c7170be55acdc9244352d9cc2db47c32a00883a1893fb6bcd9da", + "2755ccdc61e60ea76cc2bed3642d0fa26f29126cbc1ac8e308827e597e0f54ce", + "10af286b94a7a216cc2db3dd344ff645bf2ebb9cf96c2a16b5d0ab08f23e52ce", + "5cc58d03caa734dbf8b61735d2f2ddd983d6d48e565b24e33e533d3158e1c8fc", + "3b235bb988931968393e191c467db9f926c3668fc2c514339f1d3df7f92bbdec", + "cc4bc3c2286c7099a99b81dd5cbbde2cc6b97b3f94965143595781b0179b3d73", + "3d33814b16a07b5e941204161fa1bd3b81058dce244c8c4a5db9cd2a43d7a76b", + "74726fcc37b74456f2d49daa1631ffd6b21da81411184d263552be3e0d1945f0", + "d9bf8001671061a645e0c1c91b31d81345038bde71a668d6ba0002f0c9e88914", + "507a52821cb2455a546b5b80297af170e0d293a241332721e7e5d1f37b8a883a", + "0621482bbc7c8e52912dae6b4ed0798467291f1ae529e9d780e8ccabfa81b9f7", + "5ddd2e8f16077df46c2b633f3fe6f1e08a5c570a8cbb61dd7ec24a0c4946cfef", + "89ceb9a2a1c14dd387989317d4f1d3bc2a0c08f76ba47489fa030864e70ecafb", + "240540801d6fe52c27712785f2d8af936e3d4a055364ec1b833ec2e1ff02c42e", + "7cd1bbfe6130453d6171b73328a5e5f22bf013e95a9e3da1c61d33a89481b28c", + "dbc1f9a909734957a91978fae6677c659f9372eafb6c692043d5615e04bbaa5a", + "39b4d3078c5ea698fb7f0faadccac1e4efd98bbadf35e0e5d6d31b12940cc41d", + "b196e4f81e0656aa60e0e62d74fa2d6cb5aec59025ef949919c1c86a07aaf744", + "ef03742b1eeafa27d7dc00c8c686773dde494ca7a8a8bc279323897388003b8c", + "2ad9d836f8109a4f68c0305f7571486e004ed078c49da1ef2db0f4d9eb8c2d99", + "f9326e2b1feb6a06826a6fb22321c994b8e46155cd48863913572721d982b1f2", + "89f7f35984a677c20c9f0dba09e5a2a756c6e2cbf895b1461c30443be83870e1", + "b9348e989319bb2ac709f3134f028d32e3a79d0e44d87b5cbae3c808cf10f27a", + "baf892bb8654ded31389c9b06ab9688fb54147475162c4c4879af57d197930d4", + "f8450b24ddad03986eaddf952cf653ffe6711bde359c47ce281d96f12b5388b8", + "6126a13327974f343875d4ae9db49980964c949f64f1e752601c501ae6f3c704", + "5b8b501978c5bbf12e568b80513c7d60952140114b23fa10fd867f8735f1d128", + "519e2d32423885f2c1310a0e8e433a9de0900a4797452ee90419c4cd5000575b", + "73cfacd7e2ea80108e59aa4cbcdf90d5357d39354e274a869cc7373c46bf38e4", + "bc6fb083e78226313d62c97736fb52725ae7bc55642e552d2ccfb2b746592f65", + "c6d86b0b1db7327be6aeef1a51bc46db7ff2a25cb69f113bfa9911eca16897a6", + "d9eceb677ba23da709e7a9e01585d53d44a4c68dd422f1b946f125de04fef852", + "1867b55c720bc398377eb41c97bdb0dbd2e80592249b508dfd2fdd7d6ce29002", + "a3c68545ce32481e8a8c0eafd42ef6cf89932e1765caea1404a7df87f46cbd6f", + "9cbf1b4d5cf2ba094c0ece4b13875b778e0292b3e976e643a575406aa12b6885", + "b49a9748df99e236559bf440f3336f34866baa9966a25cc68bd2a53114359fd5", + "565469066043e70279195060a635fda8c20013d2c0296934687fdbeb85f6e3db", + "493b7ceb61021f2624ac13173a3502dba8c656a82eb586afd911f0c710e36544", + "569ac73ed9376ffdf3e1ce987342c29c57f464fb52251c1814c98099499fe27f", + "a6d3f3a04377f7215aa1afc88965bad695c6d176be87c47cc31dfd0d003816ce", + "df7cfa35c419ae45b66c73f1ae9251c659d67a28d06dd459a2f880a7b7cf8bd5", + "80aed9b0221f94ea7119b11acca7017a58052ded28a4bb1f247a327aff426bba", + "3643ece7de2e158a8490713c896f1349231f3f92dbc828baa00a7d64c79f4efe", + "c125ba66f56b0d626061017350fcd7f4dc39be3fa6dbb38c01e0fe19e5d72d2f", + "563993ac512d889eadf4a4a11d6c46c5ae3ffab0b3f32cb3b7d0db17b0ca98c3", + "86b41a1b7d8aeee292dcaeef8f2b25a5f45c00d1586bbf256fe9b6f81dfaa817", + "5766aea51b4048b031542e6d4729d749d6f17593d88bf5b9603fe8118175bb30", + "aa8596eb2912903c71be335dae96bd8d9457c3b8311db3e3b1675e1327aa1c58", + "da11891b1cfe053dffc4f702af615ce83ba762a04f22e9a763672f2e7a8327f8", + "b06c0a9bd797d52d2d28cab2f805f81b0ba0e622035a321140141d8d1b47ca61", + "7a8264fcd62865d1a4a369b27d033ffb512b40944c07691a4577ff63d9a44327", + "22a9d76bd4101661a5dd18e6df8e7d31e8601007c6f77eb44c51ba1d907fd462", + "af3b0fdcf93af2fe5f494ddf9d12828cbfa301683634928192540a92e190cc57", + "940969877e069af88fb530b4c2122ed86070a20130e9decb065b9b9494433f8b", + "b248683956d3fb47c793aaa53b6101de6a5a6e41510f972e37bfa6836694a19a", + "d8a10892d431f191c45ef43adad69a26b0c39dd15ffba9d09de30d361458ef28", + "444970ac15589b695462d1748f993321e7f1e372e34018ebf4db92ea0c48ed2b", + "596a3663fe94fcf8dd640d51fab61bdbfc20685d93d96e7e6910a710601f1869", + "499a4d8e5e9b11d33416c08e5fd4c74919ac5f78a90cdcd494d477661645308c", + "25847952acc234c766087be61a36b300ff9a68d614713f1f09115cffc9882bb1", + "e980de1552fd3abf72f26c44dd553e8867667252e8dabd09065cf64de816480d", + "91a0a4e0e3043a3b65726b0b5de57082dfcc73af6f7e5e4b3886fabc43c5a620", + "a5fb91122c103af58732ece707e06574a08c4618a6a5a827e9d0faf2f88cfcc8", + "ca7492323f16a8ca9e5ce42d22a1f5a8b43142ccf8b70622ad8050c07d9faf42", + "182023e68d7c98229259b54216a496f748bca2623fac6c7651304a901ce8038d", + "bf9fdae8706403d2f83018c0f3cce2e005a24e3b4c154719977f2601936f019c", + "b3cd31870691900ebcfe532d4de627883fa16382aec46d7b646a3bd5a11fe298", + "40d11522f9dfab7e06ce55a3632628d30402f163856488c9f03cfb7dd2263cef", + "eb838851f8473b40d9b9f205c02507bf6173de55153dc9d82633db5e2b19fbd6", + "e093e30b1b71f3bcfef4ac6784834c3c448d617c071d29dd14ceb953139ee97d", + "a8ad6f33f54f7ff243a5dd6b34a34e1239d36f57e33080803365e4d6ca81e705", + "5e0d218e24114a7a0d54cf44cd60a9bcf3bf0289e5afe13de2e97b4bac91fffc", + "bd89525a10da23599257cc8787bcb0fe6e69ae512f677b4578e29cafc63b6b0f", + "32a35fb5e7457023c9fef36b5f5144d39c5f5e6566f91c7d4c64b2fe6d90c9bf", + "9e173008e7868e3540d04bec7673495bff83a971e0a8279bb7b07d5951e1245b", + "aa08967319465324b3106dc0064640067336d96aefcc7149189c534c0c0368d5", + "9dcbf14e2fa0937284be1f0515d37ee2f7847fb54efe7b5842c116fda2770042", + "e0133880e736593c4599a1a23aeed5892016bb57f46f4d4762d0f1745424e77e", + "b46c903457d29fa52929937572c2622ef9cf5d2bfc50ef7fe6b603368510b3ce", + "5b0b302b6e086fbd9e51371709ddc48c775d215adaf0a7078062eb706995303f", + "d129b3b197cddee41e7710ba0811c6d0dff7bb19bed0e000f0b4a06ae42f8f52", + "f1f03c4797c28c5fd8080675ba75461d6a4cc1d2f37b465b06d26a3f66b7c634", + "8fc355c8b4b6c8084822aa6ad2bf88107e55dfb0e26b3651b80568754f1a4419", + "810d1b718dec41463dd8527f1481c848df5d93c850925c3b38f270ac92393f25", + "ea80252da0827dcce9046d00ba8a050041a6f77e768780661d4a32e11da0ea09", + "d5bb60db8fa1f5167f4a46c1149f2f5da5d9bcd265b10e294ce49f65a1ec6359", + "e9ac874d58c0b62535c17412dcc164e46a348d7219dc493c7d9ff87462f8e21b", + "71ed1f547d66d3bc6026b7fc95cbc5778176b70755e56eb317c460165f08e50b", + "906839884742bfc9ebf4260084c3a886a956208de78dd8bd7eed744a0eab0193", + "5555091a8aeccdf85aa5dd7be879a41663ccf21628ce66964c51dc6151fa5229", + "741b3b3f11fdd24d37f1e7c490a9161da7359fbb23becd5863ee483441b72f92", + "c105f061438c98c8959acbc93dffa31d0be56d9b0158750dfde04c5c88f86c3e", + "3f5d9149c284f4483a67dce6b533982b3ded67ae9e92c32d082a6f1abac349f5", + "972833783119bd853403afdb823cc7e92b4f59634bc1621917eb414c14ddadce", + "fce4b29f7eff2712e435a679ab61a3970c97d7e19ccd682cd1a76e811866f1f7", + "ea60070e146748f7185c9353f4d43498a5d2dedc699852081da00228173aff23", + "7a1e672bf7662182427537452a277aa43fabfa2d5ede3490c304604bdf7b1583", + "edf3bf8cfeed7c8689b3bcad6a2760b2b81dd4cc61a153d9882e1cc39d233a67", + "8c176a856dc019f8315fa7b18e583608cf6577f46148c9407144d605810c86eb", + "4dcf2771646d41b3198f0c9112e673f53f4515529c65721d30358e221e7f2f9c", + "13b8f1d51766356554b07fb9fa2f83c6ff5502ced215e32d95e5be027415367c", + "97bab98fabdc3c2ffc12b9791afdbb9129282f2d8c4168f97ad6dab21252dcd5", + "1b6ed1154b59156021a6e55eb41d3ef163ad6691d73a1939549c3cc36780df88", + "5fef6f04ded479c92423d4252269529caab3ef4ba356b2d863a9f6a151ce8759", + "c8d017c5e87b9bf40996260bc304d8c863597bc6271b36ff86a0568ccfc96b80", + "68e7740580c0ea1ed1412570a2c6e4b069f33ed578e5af22778c81ade972bb6a", + "0676ba8bebd474710503c9b82e78597789fc1ad31042cb9d3ffe5c35b08f59ad", + "3f72e27a27d3e2d442c8429be069b253d7add59ab21adcd2665e5676e8a31c03", + "8d5bb28468beb1da86cb5f938ba83389f5dbdbd9ce2447ce6f0579f0872b91c8", + "d85d5cc472111c9aacb0522a5c2431d60e6ed1d867a8ea6b851b2077f8b22263", + "4866a80188930ab4cef4d4145f9a89f9124c7ba9de7c2ca9a45467c5bf98150f", + "efdc9b6a7e2f3895427bbe236f04e8a45df3e537eb3b4a92c8e18d5ebddabeb5", + "b856e3f7dd1289f41fa6eb88919c48269f0b3f1e3238435079219c767e132798", + "78702f32b55eb14f1ad9b79d7877e22cbd5ab12385b37ccaad6e96622b54c0ba", + "c9e36c541d33a660ee270342cd497183da61167ec3230c415a62a50a6f04a397", + "d681987a5db9d004fb8a732f2654ae0ad2fa2e9d1896634fee2384b441bbb890", + "2c202e984ce62c15de73309898b39c96dc02df5464c4a9698aed01bb4cc78073", + "2d637053b82e2bfb3a20f9311972807f588fd28ee2102bfb3fe623e4b4dfb360", + "020a0c831e60073cf5ee18baa03d6270c974f18266626e451c80dbd70af2b3d1", + "57cbf601333e4c813e3cf146c522c9f944f292abe99f85f64f2c64d0e4862dc0", + "7b185976a30e6ecb08afac4bf16e46bc304fd5eb0c668a3b14813d21e6a05a5a", + "6776adb3627df228cbf316cae4052bd6f2168aecb5ffa1b34f0f8fb267dda8b9", + "2a39485a4b14cf774aae8005f69c5ab7a5ea23422167a67ee5eaf76a33a0941a", + "1c9bb1f35290ed74f3785a106b2408e7efbb76d0d7597a1274f5b6fc58d0079c", + "931a270cfc655fe266d6e063c1801691f8d3e3cafbe38f7c7541ea155bb1d714", + "2bc57dfca7fcc811b7804b6a63a2d35ce473112e5b9170d072db81006539529a", + "64e33048fde91a3e71012b541f72f03dc9fe3cfb57abc1a16fbcae0ecf153cf6", + "14c6347cfa86ec8da44094d41008d941191930869dfac01d9a56b5b1e02c8ffa", + "3135b28893005de9402348f395fa79ec5d59fc263b1d5149e1a37b538b6bb06b", + "51f4b0c444c69c69397fee547d2639306ae7980fa3702ec4d6acffb55a54494d", + "01ecc5b503e1a8b02406abe3b1527eb2b41de38548801c84de46131aa1b50702", + "eefc9d145b6e389fa167060bb4f77580222ef29f907f1ab913e1d6063982c592", + "56f71a1ee9d2487d1d8eb9a1208fabbff12e522709b656c35ca94a7e328372c6", + "1586d10253cbc3464957b3e89c9f82ece3291789ea1ccb38b9a8029f9f940882", + "19e8ff28b6d17df27e3c0403292dce312a5beb13f2ab73230fc597bdc24298e3", + "91b5b3e6d66c8512da943e20d7bc699012e9ff7eeaa8b4cf2514e779ad2faaa2", + "ee79abdb942628f6f42c94b7592015f6817182f6fd4a7702b2ef13f2058d4518", + "d993e8db63001ba67c6ea3d6dea2015072dcc68ef1e7029561c32137f020fbaf", + "9140de1b4f7a9ef75bd857b4dcbe3953227bebbaa94fa1251e9aeca22d16d818", + "7cabbb9e4eb064f235cd503a46543e0dfbfca3f6b91e0636352b5d454bd3d54b", + "f302aa610a885d656781fd4d8f788d45b0e0a78ece04c1b2fdea2d586c6ca4ae", + "105bb6ea32b9874bfd05e8c285a57ecc327c488e382c4c4ee939e37fc9d63e7e", + "f9632fa2f4f50477c01567b04129308e782faa8effd0c4214b77d564d64344ab", + "6017dea9695123297143076f7fc53c63c85205e3ef284f4fc0787dea7a93c29f", + "a5d26ceca475dfd87f1686366d0d1594e6bd6af639fbc09a022344bf405b885a", + "ff288365c8f670dbad97a801b2c8a18389f8fd3d4c29264efe92509d9b812099", + "d43914bfd249a5e50e8fdb98f1cb3c86a1d9dce91f0f3486385cdb02dc5fbe81", + "ecb747dc3679c35c2d0f0357a192a80112cd9ad002e34827766b34be9aba164f", + "c31149cfe018b2aedd0391d60e6e33e99a14539e2e17bf57f67183d793f2a81e", + "4eec1601342ae62332b8c1f29c97b44491f338b4850b19c026ddc55aa5d5407e", + "5a92e7902c8f3998f2af4623189f3c29d9e7af756dbe966d6f8f45c8309f5073", + "4dcfcd450a2643c18a05b8548faeec352f15e929a6e13aadc187fa7c1e50508c", + "ce1dc936262f9f94a47cb9ca00ba695df630263a6f151cbb8f6d61a59996ffe0", + "530f3f5e24460871e6b504daf1455326b6c77a9a28e09ef3570a245ca3b9e9d9", + "f093858ab36cf23ca14a49430b79b864e07851430bffbf59a5437b7bc26e0613", + "1939a88b2da89f1512e134e6d17a08e71c7fcd352cff2ddee942c4d79140055f", + "027c288b830160a6547a79a733f810978b8358c86ade1540c356124cd5db14c6", + "37f3d33be96f7aacdafc75399ad1a7dee8b1a255335ae7c92dfacfe840d3513d", + "956640048af477d33efc64310612dd0c03bd177106096eb720f8e39f07c8c3cb", + "5c78718bbef3f4a46c75e7d51d0caff15d6841132e5c496437d629d019e969c2", + "ca9d16c942ec33898e286ef3ce27ce28129745c8f91151092498097be66dc737", + "255699f79a19925d7f47fd93f60ce051ac3fca98421427f858cabf5a069f37ba", + "78f13dee637de62e1f27b74b38869ed7ab4bea8bdc059af48a3a1c38364a48ee", + "076eefa59542392e07301c8355cf99bb97ace8b46ad487da453f50fc4c731e11", + "abf8f188bfc36b4cbb94eab9c561d0029146e74af2ecad389b8bead823217201", + "9c7825c61f055b1cc2f6c934d12389ce9449ef064af1c0790ba240e6f4af1c68", + "c9cc83f0c9f10594eb2bbe1458dcf19a035c1e763f12902cfeecd3ba45845b8a", + "c590fc11206be37beec5837bb4361674a163fdbb46cdbab3afdc78a5e5c99958", + "2683f8237aa22fc0554912b395aa2b9fffef2ec7735752a4c956713fadb37861", + "6f3d609fed0177291449ac9549231e4e9a636b7cd4cd462aa78dcf4e81e0b252", + "c44f8e9f7b9a1ba95b75533014ddb774b83e9538514e124ac50663d873975a2c", + "5374aa5bd9a0f5410e9d6b2fa2fccfd582ef67ae27eafb1e7647b3806f551c1e", + "45e32a7bcb8aa642e0c0190275cda98862174e0074f159f0b63716f8c1d7863c", + "f3dd185705db5a1a857b0bbda5059cc9d219abce66569ec40a327f9af7fd05aa", + "62d590442b6084d7f0b8e8c962d1f88c46b6ecee7831d2f48dbdf0e625123868", + "6486cd51af85f7548a76cb9f1ef4792d09a722c5b859e015d7dec5cb09a98afd", + "ff1826600af54eece5404a093fdab100de4374f46121313fe13215b501b683aa", + "e3acc68243927dee5484380182401bc2f9944cdcc6565364023b86e2d2fbd963", + "cd622dd936973a202a4de286f60d2ae84fd1f5457dd52ab9093315afbf6771f8", + "77aad7ff53323ac52488577542c30415364e2aeda2b99bcff23f9ee2942f764d", + "f5202481d3c06d4b8dc4763c1ee5df7656b083d21d06ff234e7bc3d8dfa949ba", + "9362efbad198641d7f30f874e9064c099c43bc3df170d07a0ef79609830a12c6", + "cdeeb92180c1fb2d8d481b20e727f6b84f7990ca506896450d7219f5c964fbda", + "25314dd0c83415de743fb7472a9c9df18fedb68cc01c1f2946d6de3f763c2c19", + "284c3b6da40166a075b7cbafc95711da7fcf46d71d817a0d3fcf0c0cbaefe913", + "bc99ba8ef32c6b46a6cdd8c24a81c219c858f06dfe3837eac2ba633163fa6d6b", + "8eddfe47bc5fddebe01142782b8733f52ce69f5c50b71206c0ef169aa4bed9b5", + "19d656e30e06bddd0fcc44b568ade5b1c73f1c1c3409084adf083927a4ebfef9", + "362c1d6fd6457fa8b06c4a35d0bec9320bd2638c595c3376d59f4eae23e369a8", + "41677a0f6e86ec012bc722e718b6de48cb2b5d0deaf9b91d081cec6bd101bcfe", + "5aaec52cff59b7c4b73f2f6a8ec8e3abb8322cd1969f0f2e0803bcaf13cee486", + "9c472cd4e64b14f78a7b31a65695d34dd24cc623130c92d454fe22fb4619d8e9", + "486066ff3685305dfaf58f068a628e68311d142e1c5cc66b8ee7eab1d3e9725b", + "f4d2fd1913acb9fddfb4cdc6dd19abc289940bb8f32a25419c5441fe37d482d7", + "fa6f3301ea56a5a61fc74f202daaed8e96a9cdca7dbd76b2d7816af4c5837bd9", + "ad0c33a449bcafba6879bd1adcd7e7b500aa5e74d79dcd06b36a8664218c6cf0", + "c5b9d5cf2f1339d39db7a1daccd8686624c0d45166e2fc3474694c7cc3eb411f", + "4d149d97234c4f79307a7a9ac48c62a54a7704929dbb6f941fd8adf727074ca4", + "8afd86ed74cc410056c717f67c1097a1dffc14dcdeb5a4d9e8b8f40447f0107c", + "07824a4cce2a7bf12e7c296d750b54359f141e574b2f89a083664395dd6cf7f9", + "15472c92bf3d3f121bd618d84c9db237953f6185a9b7ed4bac93328f59d802ac", + "99557f255211fb4b9532ccfda7a57a03782af8efa0e9d1105a07b93ea28e6c6f", + "e6439f640027b7991e49368cbce279cf6d5b2919c0dbc858991b051b183bf64b", + "dff4610fca9de116f79d14c61963b63704a93aedcaece32a634cb0a53e7f2ba7", + "8e9e61c09265a491aeb49a7acc6a10eaa8c1db6565cd57c6a41d3a662f55203b", + "42cede60994c04aa77c324d6062b18cf7a4d0f664948449eefb0baa0c056e5b2", + "f7da1dec9869f49536cbe99087e0ef273e2493a8c1e324219c50b03de7451dab", + "16490562aca6183ad8b3afb98e0b8fd83bb965e746da5629566488669e09d9af", + "17c1494eea09376d06f93e3f0f65d73686aa76fa2476a0b136148c45603c6ebc", + "71427e5afeb0a2a00776e1142ec112dbbc5f09973b7a363c44c58639980a8247", + "bc6ac31bd850a97437030a4888e5f54b7361523975b563440e7e069430f7a5bb", + "9defb91847416743e1ce582b419e2470c7f59d1f31606b8083b5fccb993e8b65", + "aa5eccdc0999c650c8736231660194f8a5543e0b2bd90593cc32683d4a55a378", + "bab39f3d2b9f49737bc846996ceaee5c2a540d4d11ab8155d378fd3aa7248b80", + "dd8b101d4502263deffcbcc8f164635801668fdaddaae8bdf1096ad849751598", + "cfd53a6577e3397cd9925b30a676ca4641f6792a1c11512ef2eebded500f257e", + "75df5219bcc3906b868ea748883cda63fee69642d9028274c8b31c776c9240df", + "99916fa21a601eeedc035d0e94ccdd56df7ac8e5892d48b95efd47d145cde935", + "d9f49bd548d18262d998cbbacce4fcecd8cea0a50e8303200e50d6245bde4609", + "836318b0a2e7334319662b4a6a6a8937aaaf5241020ebab7797984c71682512d", + "c2089d17a2ee316351207a0beb25873529e9a0d722556cead94beb3ea6807975", + "e3af63f3eafa347fb125a8cd6ec3c9fe76b528878569434abe1f047eb86165f0", + "5bc5d64e6b59f47a78ca2f1aea9f28e086db6ac1cde487bdfa03053fa07fd5ef", + "a27db6c92e5af1fe318d2c8ab266953166276b1490181c8c1e157bf698823dee", + "66f3c79d3db2ddb1f410c530efddf56049e9fdd3bc7f346e1e4d16d4a34d751e", + "fcb033fd9fa47e200ff4fccafa390b7f1211d1fe3dcca78147ab4ee7e12c76d7", + "b4a64e009349ec7c1056f10c65400bcb8af0c60e4ede5a7faa17a51886ef0130", + "2ce5c4a3b26e9af2647251bdeffbaeaa16c9bccfd2150a6585a9ca22d11e40d4", + "ff69edb4161f4c6c268ada5ce36a8123d60dd0ef0c5d142b2d0cde37dfb93435", + "62f75ad07c1b5309406e277c66eda87a8ab48f95c65d898ef2f6dfce40bc2155", + "550e8c0f6fae0d5d9f3898b185097cd186ece2920f34bfb151fbe82bee06cc91", + "37e88b7d77e026fb7e26110878d7b4cd046d9c8efbce3a3b462d7fd56b6f3cf5", + "f06a24fb5e2d51fd4059a23668061059e3f59e8eafe120ba6da53ebe622829bd", + "66798af5adb2ecf9c2035d478cc5a91bbbe9e0cf54379cb13c01093027af7853", + "445d7d742e247e05bcbed2a9260d7edf33b9e18f4d41bf7eae2d1e447483c293", + "1dd8f73beb6ddb9ed9e7bf368a094162cb23980041164b990daa804f49624bcf", + "f3ae85ba63bfa2508ce35a7044c7ba0b8ad1bac32ebfdc9fe6364cbf4c757071", + "8cd40c34105d90bc9a4bb0e294046f0c3e342f01bac951a7bf84f5e61b9713e6", + "3300a6440662dbb40207e06dd37a6439bc83379615e63216a1ab74e4644e6533", + "4ba00e797b240f047a1ade2edea9faf809c2fd2fede2f24d4961aa0014a4b882", + "535127757ccd8f69c75ca4e161d27ed85a1bda4f37405ce8e8f188e8de8d4552", + "b9a1b94d833168a6e8e16828163988ce29490ade328c48569563d4f4841e7737", + "da6eecc27816c3184b36717c3afe5dd4d1255e712ea02177c27e5c8df3bb1093", + "5bf85e035b39d244c6a48493c2ffd5629cd41b8790b8521bb78175051007ef1e", + "4c6e117391ecef39ed25ea7f5fe89d40b9f3a115e8c0a971f372f7e9d8c7b8fe", + "7e447978acd58452fc075dfa4874ac71bf3cbc836c8b89a9eb80ae78f4f4b628", + "04cb63589a0420251ae99e77a7a9bbdf7f742044eef010866a2059e73c7794bb", + "c28a8901dc7d395e122946cb87a5b1c181e82183f0968ee3fa8979688244591f", + "626fa267076194d279cdf661263b1647dfe7a04c863c61d6b74a59ade9b49870", + "4760dfe2ff93dbb401102461df322245be6bf6a17d4364a4a46c12bfadaae0a5", + "d15238b43d91236c1d4853a1c6e80795201430040a4c6a1a7ad585eba128c8a4", + "6d84acaa43f0bef2740d2a2ec3e2f2f19a09b1bf6bfd029847b4045218bd9d05", + "28584ea9cefd7d6826c655e5f1ad89b9d61cec02c1931c2cc0bbbd27ec860ef7", + "be255452c332245658632cce6de3dfbadee50fd596bdcb4d7f229a32b6b02099", + "e0806e6aea9d0d0c8e05870b74b2a7e53937905c038fbddeaa5973f81710fcd4", + "c04fb404d7f06c0e7987e954947656de7a08531b779d83ead2ffd07c97e6bb48", + "769bdfbfc1f472c4e7b25025ff1b2a53dbde6528e89e96f1d4e2555e9dafc936", + "e0e2dc590b4380d924a5ced81b7ab58d0145eebe2140162d0a2b3097c8bf109e", + "e10cdb043a16de36472a0a02680ee6714f813b20aefebc0ac6c0f27ee4e1d21e", + "0affc875c05b6b8fb3d2200552478c68ea690d96d9199698312f36767efd6adf", + "c07cfdb56eb2f2d9819d38c167362b281eaeef971be6dab819af143ddc116445", + "af026d5ce5efb0da4929f8052a0807b6d8d9272813d565f23f5a443bde3e91d8", + "400dd199229f0b157583e4a5facd7bd86aa433beb43816ac75421ac11882fb62", + "7aa7964ef5b0da101edd95062f787a0d64c34e4824cd08f46c9fc7dc9f194aeb", + "df6140516ed5aa8952ca1cec39aa67077584837094ee7d66582d39e7ec05907d", + "44e03470cebda8bb1ccfb2713f2e6bd6e7f8dd5fd219d0209c0caeab605aee12", + "73a7e57fbea32f61db2c1eb45a8b5f7b7bbefa4baf7aff331f66d80778fa1343", + "5559baf2dce6e02229e03972b318c942c43f26fac225149c2ead32b4b2323f53", + "117c941a10097e73a1e7db7e59fbbc3c4323b87d3eda4a70643ea9519da904cb", + "5c07f27dcbba5871aad25d3c4b962e8b5938ae2ee169cfc4868308067a686caf", + "9f60d9c560b45ce746c9250ecc7edc50e0010b6fb3c2c49dde3a01e8b4b2fa9d", + "050f660a7e776d30c07b2eb2256919cd9194d204bf9262f071877ab5f5148179", + "941d6673f913cf4ff888108043ec291f61f92108595229aa75d25bd2465c725a", + "34763e4ead0da6f20300a910c2ebaf6313bd9c0dbc2a76efab01449a56ab29c3", + "24fae880c912827d7b00d2695ea7e16aab063288b99e235b42197380660a52b7", + "52ed0df278b1b44aa935515d09a179efeea636fdda41ad0cce789abc56f2a8ca", + "73d4a6669e35540987f1b3437db3cfa3013f2ba073b01f7a4ffc3a34a6b94334", + "28f6a066ecdb94c2e8134c86e0c2acfcd97204879760bceac6c8cd2d6e21fecb", + "d096e76e6dfafacea61b4feab72872c624a210562023e1040246bf0c073328a8", + "28ef0da5801f4e7aca3bb09d3d708b4e3c4a9f6c5b95e5a3ea2a4c0ed8926b3c", + "3c1f788c97e4c3180537f00a18f308d90cb5690ac19d7cfe38d8290bfa12ac7f", + "6932b405e6453a537c512972134197e994c23af19f54d2325e60c570dc8fad27", + "318228ab2d8ff528ca99a8eb071ca892f40df291b9fdb1cd8b0a57e26c16e93a", + "09671789474f82a901f4420bd53351fdba17e687a08f97b38a2e1c92e1e4669c", + "e3e101e415e990d67466c88c6f9495d065b2cc988c0a795cbb6958e49db21f5e", + "013811d0236149b0afa28f890f8344ee98645cf534de1de5ce6d102a235efe2c", + "13e68c79188ba3c0d50c18618c30e85827a9d52b2e3eadf5a5a2da2b96df0376", + "e03ab88806c88a5334d9d7a543e3e9ddce2d9440bcea89cb748a02dba515a4e4", + "7c9e1dc04838ae0826d7946b5fcf8c42ea585dcf791d40c625de7522c6b0f697", + "d7d5df33c2ee7e3c94b2a9e33cedee3f3ca37331a1296a0748e587d94277413d", + "5de99bce60e5a0170a23465e8f648ab30544e641e227e5d04ccb6c4f14fed0bc", + "d1c156c7a73db25e040a6f6a711fa67843e7745f3b3a441018f73a02d9d7e6f0", + "76f2e738cc0032c6f83e200a376d70ace9643e100559b2892a403dbe80d5d8af", + "a93e7f251097d342d143794f73654b2784f8072020a04e418bf466c3aabd42e0", + "44fd490fbfb072d4dabe140a2776ce4471b01124c2b3270ff55c424485850d28", + "b58b0c28edd10abe3ff8d8b60af99adda5befd8888e891771b83962ea7a2dfc7", + "3310204a484817f367f74d2d5eafa2721315619d9aa2f373294f44e010b8314a", + "b614fd06178590f562ce4ae875eff34b26cf2726acdbb3608eac92d0fd1d23a5", + "5a8583bb5774cf8ca9383c78023cd0d33e2882ad438fd3e6e4d3848d158a944a", + "089162a9aab1335e29cb0bd70f24eb3e295caf037e6cc9718bf7d51a72d403e7", + "a1dfcaa1f902083fe465d7601258b642c9ef870bef1399c9939ceb379fbae748", + "1cba04054025c1e5fd0b86eae369f1311efb3f77caa87e72405e2c71788ab0ba", + "424efe32867ff7982800b15acd67c2eb338bcabb4372abd9bfcc3ba4456f821a", + "2a476f7dd9a8aa3549fc635385d1bd87ea8bb9276adddfdab59d534062b36b17", + "10e1d10f36f99afd4bc0be503c2e0ed24c12912866662092e1d00950a76f6dae", + "a6bc5a83582497065b63afca817d8390fe74e40b499fb701fdfdd028a107b295", + "3fbc8cf5a43124808250b565628e7da97e4852e4b95f3c0da921b4ac48bdbd74", + "e4b85472e24705cd21379871466fe0d4fd5e479ce5cf025da5af07948821fe5a", + "c40b718624e67ead0b36a1e4fb5d0d7270e806630ae879184c1b4e383ec94225", + "3fc90ea9e1624ade7ba2fd1af10ea5b39d20fc3f56201d5b8db11d72e82b3a00", + "68d834035e6df2d9a3829d132ed72efcc90c8c8b983aeb38fe5ffb9fd34a2c25", + "5373446f6482763fcdf6ebfb6638d790758e9373ffc7323356549a49c3edf843", + "97298a0a0f07311e655e2bc8f84aef95def5468af86cad5a581c7faf701a89e7", + "67da7d93c223215262d5580c3c64f0fef910ce14d2a70167efd7e78ec3927e33", + "42f97d950e3a6d42c3df002d9d59f674373ef15926e31dc17ee46d9bb81f7c9a", + "341f2876f4c5f9f6887e5c01be9142780356c07d341b3b9b1d1cb964ff5c7bbc", + "3c0ec859c2a56f76215a91fddfabd0b307fa78f578e4371d93f34dfc89a3caf9", + "1b1524a12cad394dddba797cb67d5902da582c528db96a08da09662068ec58bd", + "d61892086879d5386b159e8a5e015ab190100d17d5bcb2aca6f9ad0d9d81e232", + "a77f9b559d4da6eb842900733bd7c30f726e7b312deefd37ca3dd11de578caa1", + "fc93a41045e05776b26e3a28f53b56b7db67df51c854f74c74eaf1b6ae12b8ca", + "4b485131c1e37306ffbf8805af2878205589821e50289f08bd64416cbeb2a669", + "e0c651a05d43b00505a9bbfc6472b5d8e0a09b598ecd19937b4e0a711a0f7487", + "97ca6d1e684e46f780136c7b8b27a5e55d0095b88bf0a9d27f2473717045d132", + "62e9d15602492611948bdcf0878115f75f95195c8d364a0b2cf66fa527428487", + "bd1aad2f54609dfbf1390efb857b5bbc111face47c8061ed5d0b56f60e765b00", + "9398ab637011f5824407a0b17a6db5db1d3918517d3f291dc0c82eca496aff23", } -const mainnetPreverifiedHeight uint64 = 14390016 +const mainnetPreverifiedHeight uint64 = 14464320 diff --git a/turbo/stages/headerdownload/preverified_hashes_ropsten.go b/turbo/stages/headerdownload/preverified_hashes_ropsten.go index c79787da17e..ef7081fabbe 100644 --- a/turbo/stages/headerdownload/preverified_hashes_ropsten.go +++ b/turbo/stages/headerdownload/preverified_hashes_ropsten.go @@ -62963,6 +62963,267 @@ var ropstenPreverifiedHashes = []string{ "a94db20edbbb718b81a2b1b179b5ee3cd8993835e9081a7b8b52121afd72615e", "9147c61b90fe848c1c5ba0145493b7acb93fbfe17d815b72caefdde844ac54cc", "30e2500c42a2867cdd96b620be6b7dc1a9c38ed009caac5f026cdade59f53850", + "fa21408a77a64d28897dfc8a78637c5f1299c03ecb509a97213b919ab0187066", + "c59809acfbb449e545f53da4ffb97d602a7482e7463fd2513f7625a2687703b4", + "0c2ed85b0a9a09a975a0551e57fc16925de622f55bb31c748b6ab2232de1c6f0", + "5b919885273d4983701867c27630f265b8f61bad6d53278f4ef88ec4f555ea2c", + "0e2e9517954212fa8284ee3a8d68ac097bfc08d440d244d2ea62f467e05b7e45", + "6f042e820bea47772610a0b6ec8cbe79a28c830cfc83a4470bae608ed3cd1db0", + "1645ad72d4b045fc4554a82fb3cf5fa73604a1483aee8bffc852eb770b4836d0", + "42c248a784b68d00a3f89aeb1cbbf9ad933356c68652bd373fb78220eb5f98f7", + "dc60831244cd2c5b1061fd695c737e6f493c799db335112eb748a2e1b4ce403a", + "ca0e580d94390720121c1d16eafedae43d9bbe6287bb8dccb7abfa81b3901c0f", + "ab81bcd264fc84d64f4aefa923ed9256677b923e536926141374a7f2068225fe", + "93a3342ec5c6b14984c5f999bb89da129b9c997a886a30c4cc5c5e0f060add6a", + "28733b33750a0799a1741ab3780923a9aa695be8975433bc8769dec060c727b3", + "e249e2473d8422657c291dd0f7e4a156b6d76a6ff076da21e6541fd4aefa7678", + "7104a9b475d85abe9e565dc357381ea60b574828d4a692fc775dc9325206941c", + "4aeabbbd92fd82be8e2d01a3064bc05ceeb7ab43ef2986ff128b2d24c050bf03", + "28c3dd712a803f8df3fe739b02817453614bd414e39e141bacfe3293286235b2", + "158273369bb1503e49196262eb8b5c9a222dbe0fb25c2cae983c721431b6ae4c", + "8105ccd7b46f061250f7535c71110c4078f7b21fddbf8af89eb5a69e5f7117da", + "2dfba05d5fb7f1b9ba5e25843bfae369e3ea534b2fdb9044c5e4456c51ddb28f", + "271cea77557861ef124aad69695856bca60cb1f6217f5b25f2adca134c235e58", + "d2a308e2fc8a35cdd17478da6beac51e92f66a98f0ef9b00b3221df4bf33199d", + "d26ffaa3391c4fdcaf6045f66f457ae6fc5a9694eb7597f3bc78881872559f2c", + "e25564cef90af53e18e90e0a265887b58a26f1ddfee3928dd9de6274a594273b", + "921300461b76c76a1da9ac8ec35afde510abcaa5ca9ea6e125618bb7492b43da", + "4b4a526e8207a6c6e367d722d3ea15b169e12328b3a256c6d1935ef4fb5e197b", + "54edcef0760fefc27470297dda17a8c4a4e8f40873397d4b7c6fa58c57e7ff19", + "7a9042a19f4ae205473997c020a0b274156edb9392a2ae92a0c4f68c2d05fe52", + "866dee2874ef04755bda5e2632bad2ee966f01e58711efc25d1bae42bbaf09fb", + "11c67b1808f1af85b7198e827b0f2d95ee1b075d5d4899e61b15043bac23d990", + "8e80b2e9c04fb37342d40b8d0312904c90147ce6b8776fffe5c16cc93c9622b7", + "05a20e371084d89dde72ad5f867536eb38f0a8fd4f0550a90dc96e6c7fec5b21", + "b3b96f765f9eaf97179c313d86a31d651109811cc6b9cfba20de7390c97688ee", + "d4be7191c7e91ce6bd4515c81494b4ab5cbf7c3aefda7c530779fd74ef58a577", + "959c6d56e4082a4ce20cd8ff97b4392c490c4583a7adda4fd4fc1ea2b8f827d3", + "88119ab2965194f4e36a0b6be88552e2fba1d3b22aece3a496e38127e0452449", + "e3541bb29cde9143cff5fe76ab8ecfa8f4303d9a93bfcd706f74cae55c167236", + "391881798c04224345b9151e665e2212e34af35c45b0cbdb595573aa03e2c123", + "6819212f236a4797a7195a7b9e67d75fe4b201218a4e83eb4ef5bc77205723fa", + "b39ad1ba01bdec9497ffd80815a89cee3cc2d45a6660d05d99648e066a962f09", + "1327df869a0844296994084702989a28bdc0064c04e01ca80017b67584359e72", + "b3fd36519eaf8f6cfbeeeb4dead03f4263fc12f210baff34cf75adfcaa3405ea", + "00ba4d623c250a6bbab918856baaa30f69dde2427e30e5915d41af86d33ac43c", + "d00c32315050560f6bf04e91871ca443203bb64244fde32f7e739c4aa8604b8e", + "559136fd24fc5b3b56adac688ace276ca9c60843edfd27019cd8d6fb30728c32", + "8043c640d08375c7df48cfe8e6e9159ea369ff143980f0c3e59fa986b8b8032b", + "f1fa886b58f80210250f4398b0a90e3cd071201d858692d2454075220651f0cf", + "159b3c9229c4ccd1bf488ead3dffc93f26c1b5f874958a01d0b349d000e0f490", + "ad24093cc18387ed3b31727c31863adbe77836922e4bc28ac7c17e1163b3e266", + "7000f33c9b4503f6b5f868acf055585b4886e7f171414c72205cba4d2457e4bd", + "53653c51cb6c8c795eb66be8c8f64da59db5a3a4a31308929ab1fac1f7cf7218", + "3117c6c2cd00618c1df8017dd51fecda51f1faa51514df9cce5e61c1f9fcf700", + "6fc063e4115a8efff2ffe7026b2963b02b674d7ff30f8ab26292c76e86fdad96", + "7c7b429c9fc3f63f955df94c3ee40054a877eea5fda470d86386a92df2169791", + "b368f3a07d28ce8636b821225829e067944206e78f257181b123290b05c0cc43", + "3773f56f4a951b52d45c6b25f9d09b9bbb1fd3a8b8278c1f9bd26faeb18aaa53", + "1f17ac9374862afe7d21d78575b93471532459799442afd8f2f72fd5c4819c93", + "b9c6c2a440005aa57ae966533abe397e55ab636fb9e471682763eaad42f5a4eb", + "6a888c4373afff18a2962d389c85602a411c6bb7b86bc2f03432b3d51387ba4d", + "2f240fb1f2ccd4d4d03b20011ca57d4740757de063ad74ef6c72a28c5236fef4", + "a2d97b94eff571f511833ac32f54d7eb477058c68df31353a3a1875bc37d76c6", + "1342baa8e3afbf14cd26882e7061d806c2d14508518f60be920a97d2e3cbcec9", + "bdda1bb55a126259c3a485918fea99163a27e279c3e157869d138bd3712f059b", + "72344ff96b108ec7ee47b1306eb16637cba0bf8d9d7ae7a283c64c7c52337f79", + "b8ef983dc66ff4bde43a27a27b6d77f83b0f8cc14c784d83ab8644eeed86b295", + "06ec3d77f4e0c89049db075ca8b403e85c5f2742fec7b61dfdc0c1a9c1feccf4", + "34fe6bf387187fdf3004a3fba94463ff83eafdf6ddd9ec64c20cc3806ceb14dc", + "29e942461b5ab96fb01d7cbe358ec607b871222eb00f4ac3f0fcc802e583c53d", + "5fccc85d3bfdda81f64e996de25bce1e1ee73c9605d64badf35fc4a17de757d0", + "89d85c392aa1a455a734bcfa02d79f7c5d8e44f20ff5cc5599b2e834d6a39d11", + "15c75d3366cee836b5863de521d8870b3b48bc7675a975f29cd96d2a6558cf60", + "b5ece60fa50cf254fca5aea13a131c401e8d6fbfa7f8e9cd07f4169a333b2f78", + "8408b0519a6c31dfb8c75e1b4be2aee1c9d3825b8f71c8fd05d73a5ee652d1c2", + "aab73c7135d88b81989949a94d0bdb1013665b45820226d7c6c5228b3a513cb1", + "575abf42a69daa847c4cc53985dfa51454ac21c5c7d32f15be839b313a745b96", + "cb13c5a8a1398d9f9e6ffb95b57a6d8d6a34d8cf867be55bdf17a0047072c55f", + "0cb5807c34397875216bea68f2960b5772b97fc7d9fb3f669289390eec513853", + "80f5776de6a1c7bf31e831a91d79f28f90f04ea31a9f922bffb787a2abbb8d13", + "cc6882e2ccda49dfcc70cbb0dfe68fcc377aad49e4d8b6c07f0ae1e818171624", + "31c76677070ebb9fe6a63605b28f3212fed9f65d16cbefb0ea026cdba4a91c0f", + "2149ee219823375c0d67f11baaea9418344d2c6c785487dab1822eb6054e9caf", + "cd99bc7eb54adb1a9199825072b888744a7e26beae26d7bc26d1984498b02e8c", + "2427b3bc7adc47a4f1264bd397b884f9e02edb1d7997a6590e5d7c445b6e55f8", + "7fd3c608d6ef41a09b8f74c5d5f9d17a600cea0280cdf2c85eb341e950d19720", + "fa2f3f0df401713fde6da663b3fc8e6ab5f43d1b771bf2d4e290d9308702305c", + "4c7ba22b378dc9399055e187c84844862cede10aaba01bb4c1ee3b68910b6f75", + "123ccbe202c9ae93d067adac82db2c919ad13c6ddcf315ad7762ec477def359c", + "8988ba282ac5a3a0fa66642a03de3d7d94dcf7c46217b29d1b4b0be099b56ca4", + "aa15c9a7ca993f0f8574e55b05af6da74da5f8fdec5f42129a54cc80d5c5b6e3", + "b350cbf7617b8abb9332b8fa6d4ef59f6b5678202e93e5803e839324984e6cf0", + "ef24cbad317f5c6eb21e35d8bfec25fac629ea37c21f9d5c95aaeb77afaa9093", + "e6fed189d741acfb825479760e9405f29d83cf800392fee607b1516d640839fb", + "c8fe8922b0dee03c7b344b01911af7a0bb167cded9e5d3aaf42f86e851da0941", + "f2cc1c015982cb600d9f3b571c368c2a24f20f3402549e65ef020c8ca736d4d8", + "224422029f3784b52ccb6500ce7b6290ca402a379cd7844fb7c286b3cc7ca3f7", + "fe0b2b3566195fb307ae3aed3f323502ae581bc5ff83281b6c6e9ca7bfa040a5", + "e8aef77324051c25d04c2c99b6b776db9ceffc9a861b92efac3f06fc974d75aa", + "4ba19df9ac3de78c8863f61910bfc69124deebe7118ce1bd82c49eb361f1988d", + "b42d418d3e3302a296b7203b985730e1c2f9c7a6a123ae7ae0c0bbc4fca622db", + "4e6d7ed876825701ca76544107cca38435d3089b6fbd62bdf7916ba6e8bc4908", + "dc9ee29ae06240934d706efc4104b9860ca2c4b6c7e1783c3b43ba7fd9ddd353", + "f37866ba86120954d47782d782cb1db96b925e844876b0de7060609918d3398c", + "a37ecc82b7b69f1819521a31682a26e75c4ff233486dcc126ea31fc5cdb99eba", + "05cb4222516d09d6fd47be69e9828c91f6b8a0e60540941e2441f8dec0fbbc68", + "5e64a414f76ddca0f7ddfea53acd769f803e50eff9b4e8478d1baf22f790f6ee", + "e2dca73df7dd41273156032263bccab2e4e553fb7aec22ca96417917a7cd225d", + "4265e91f2e85cdeb726fab2535acf918683759023e76853f8d162c515fe09b1f", + "f72607d9943df6c720536841e4cdc1dceb746ac7b93ad595dc863f79fcc26159", + "e284c3852fd89f40b81d32359b2e3d8839af7145da9645a9d8685f68b84007d3", + "133a9c7e0d42bed1dc055366232f0c4fee4aeae58f2c7328c9d8ad2e50e1cb40", + "3fe00c161034c5cb4d9e3e61bebb5ceda809f1f9480599c3fbfd841b8793ae72", + "76af5cf6dcb9c335c3cc4465a45fe5ede6dba2c4bf8fe49c0762a25ab7793435", + "bf5fa8fd0514aa24f357d0f66cd0465c82d86082621c338d95aa1aff8a7ed773", + "69acb0005de4c9a37e2fa36727303c3178b8bd048c23ae9cf070c13d9362919c", + "b26cfa67118f4754818ee0169ab0ae99701768aab4b06bc74acd5eb373282d36", + "c07136f33dabfe424d7a5a17546a2eb5c37b3602d5319cae8c1accf84c7a79ad", + "ebd5e38a153a621064adc973b37ad9513607d6c38389ada35e0ae399aca3f494", + "4679e7eff52acd05926897cf4d6742aeec21172364c2c87280026e81d2ce2677", + "e5eb3ae6c2db548a9e3e70661ffa25f4c7b024d42c78fc28aca940cb015e9d8f", + "b44a65b6e9f9d92ad4c806f9ac45d0664232f1b47cb1b7201f1465044f1b69e4", + "fec4c7233c323f2a8da200a7cc366026eb097ea0076d0dd26d73095ce0c2dcb0", + "63dc131d314140dcb77e8de31b4b2d99c88939a5688a0f7a6b475086048ef875", + "fabeeae6081a4d8eb4db2601491bd82dde72a51f94b245bc7395efb6b6d59c5c", + "9da91e200f78c00fa9ee7e60946163767e682e5dd1189974b7e40f54823d6fb4", + "f25583c207c580d1e966e4441842bcf66386b9440753e0644ae41993b1f74ac2", + "fae4e69be63c394dc2f37a4a6260d269412faa0237bb523120ee19d54881104d", + "481efc479463a6d4740de195474fe32a81a50ddc9d582f024d372773a1467708", + "fc29e31df542f440f55b1e32f06dc280efbb1f7bdc99268d780c9b1bfd7f0d47", + "8170d9e9866a5ef1895b1be6756a548f5aac4d035853a728d26ee6a0b5cd0c49", + "0f5cc3fbae5c7e793c3939eb2a2c0e5557b2632ea174f4e4483f219cfc0309cc", + "44708915ff1dff37e6c5498b4b0cf30c47771bd3ecfbbb848cbafd8ffb41125b", + "144d1e1bea5f40edcef1013436309ae3cbeac9433262023962b6cc4aa08762d2", + "229e9cf787948b736f3641b03b5fc0f06e8edbe419bd1dfac99befc0b5904a6e", + "8b3c04fe724e9f81eadc7294f36ca84f19ff77313b2cdc6caf8694f53e325c45", + "1da0bc86d98dde6820431375d225fb992a8d92fb36b7c7b03cf72102c93a2126", + "6989ee7ac05a760e122f961b6d8144ea80627b817075a833d7b197374adacc1e", + "21300a0d8d34199411ca1e9a191ea1589598833831a36fc7ce92b0a855accf5d", + "ed963dce31bcefe81bb7a2a5c4a661627d75795efbcd9f62b0ff02688ae46699", + "c1ceb83d0a343492ba5143e06b1fe89065ab786da784293b45a01ff559170aeb", + "6457e87fbf1aa9ed18bdc45a1e7d585ab20fd21f19903d554aff585525865c72", + "c32ab59605f1654ceff378120152359d07975bae0183c91a14d0a4c629c2e79d", + "9776722a85e526b401344f6ef16571a1c744faa3659d29aa6a07c5f05bd8f5b7", + "fef6032fb255e8ef75ecc141601232a572e944ee066cb083fe20c1fa03292770", + "2490f29484072917ff9c5de8c1268b0a40d25abab8daa0256f0ac74470ab7274", + "3fd3445e3f37630f29a8c62bb797676d72d5157a39f75b06fc2d10e1b759fcb1", + "bf6c49dd3b9495129bc045282c81e96534dc2f66d7815d27adf1fbf38c3fe2a3", + "5cc72dbe9ce25ccb89e60b55915384a1badffe8fd59ed6d0bc5f182e03d69d00", + "337943524a53abc31550a59349edea50d4dae08c26dad887fa5c1fca6cd8b7ac", + "a2ef301d351355654cb81a29393c7e4f89cdea09794190a73dd8ed313fe577e4", + "4e5de5776fc7cecf9dd2fccde7302117d503a02f3e973481496bf3726288b409", + "83e5cc105f884049b98fcf6e8f3e5f8fdcb87858e8302d4ecf42503380503797", + "5e39494fccc9e72a248bf24d6a360ee2d0ce81605673393d0419988e22253756", + "775ead41b2ba8e77c1e22afaa25f68fdbd639caf07c3f5f5cad4f28b82d0c825", + "4dae656ba20a5994ff57df45670457fcdda8afc216bb8e304c0189e9c3a9ba39", + "e0b7967f0a22249761d9e181c6b1c432d99ab7638f6a07317a25886624831f5a", + "693cdfd508b4d7bfd900976e43944ed7e5353f507f550c37b8ca68316b763e80", + "8fc28ed6ddec97c21160fab65800e24cb3a63e245678e30adeeb4fee4647b08c", + "c40d100aa012d6435e65000c1ee0515098ef190b11d84dd00ff3f370e7537299", + "0b638c9e9e218adeee9ca5b8d21c9e07a943471b27d90c600d3b949dfaf30a91", + "29d14ab3849586c2c9532bad49a92fa840274290d68777ec8a3dd8fda6660531", + "7bb6cf40249386f29a1c5f92f14242cf26d9a2e4a612f3e3f14b0c569b64389a", + "25cd0fec6ea2c3328c09a9206dea14ff70aa228a0cc4ca02c8838e85bbf56681", + "791e2c61713c6a39279d0773d8f19637a8dca2bb62da6dd963fc3ca59bfbd50a", + "78a7750fbb4d979183b5ae3ea72e15276508724fcd88cd1073a2b49da21c1021", + "466fb6f0aedb337f184b473abfee2598e59b021bf4378889c88e5449d98d1473", + "4213060b6a92bc2813943e91e8a6e18bcfd75e57ddf98d6f69fa784f25fbd248", + "d9bef3dfcd15e00860e2026d13152ebc6cbdfc73024997410d08cd81fe83bcfb", + "c1da8ad3a13e6e0eb154dcbf2c0a67aaf6fecf7e665a465997b1828b4c22ff2f", + "370dc13ce382bcbb4f82b18def2c97dd17d981ab565df33a40e639f86c561cc6", + "f342fe7302a1fec27de9212a273172391f68757af917e572a7ae912182253a87", + "2ffafab64c222dad0fd3bbd1425d71e53f0176ad8ceb71a8c5a7163106747dd1", + "f7c8eb52c9299ab5e7fa49a56a1cbd8f3c0ef7c78553bdbe6c66c41b72d4f7bd", + "ec5848b046bee44a952dabdf76291294d3aac6200d9d8a8b8b38e428117f1642", + "3c06a1a12eb1ea9f6646574bbcce53b61b8721935b2b9909a7f4a4b4bd4aa7b2", + "df9267fedebe915887ff7777a5e451fc1ed2960ef817f307b3f413cb655b8fdf", + "7a47b560a227bc46e6867249eda5145ca535f1e30fe21c222307382ebac6fedb", + "4844bb5aed1b62d5aa9082dd1875a87adcf0d0a6b29dcb88c836c53dd3506121", + "66b059e5003e21cfb4144469860b0d465fee0571eb39924c40e4a2d8144e6225", + "d8ca363e8c60e2ff78c712b5c872c047ef4a8a2e15a40813ae31ff7583495da0", + "425ff2a7c3cfccf970c5cff98699ad4739ae847109025aa00e909e1e4f7a7ca8", + "206ae971529c282843a21a759ebb844a85e88064914100f6ffb1cde83da43bf6", + "7a78eac37aaf3c6128c13185289f57b93436db9bd191ee3622af7b860d4e50e7", + "2e05b16d6fc374d7159d86b6c6921cf2050f493563841eadc5ad56f218da9e14", + "9ffc407ceea24eb5c4396b649a9dc7716263218c3f52ed06e9fe2a1a382e08ea", + "7fd20d9333b9f55d36285aed4ae3344657bc0f14aa4a2ed91d217894ff53e513", + "a34e9eb29665037300770ffe95c9e0a80cce4a5eca595aaa84d4e8035f02ba65", + "cd66bb2312e397a10f615e73b6791a9136afa4e32a7bdb6bef1b6e904172e8e3", + "f6d79486b03cff3ce01754d742b0b54d3c933d6ecb86f99f612c3b09f717f03d", + "a8c87911f091d6b8bb1447848629d27cd9c40c9e0aea110658b68a19602ce878", + "806dd2ea3d73433f31a078d1b8b769bf095f1c5d2786b9f8e072329a0e8d3cf3", + "93beafaea6bbc14bab10d36092e73e101a1ef23ce02dc850789f8b30641d7262", + "a71708e14964384d1eb1cd2e05ba675b28bd948d53876d89911690418c08eccd", + "d5bd9f017fa984a47871a4c4a503b401e79ab4a1896f3934ab1b2aa796af87ec", + "f04943ff5e2da0eb0174e87422daabea4cb9a52ab100140b4aeb174f3069f224", + "a3b32eae627448a0e134b3605585d38bff408163054cadd536b121661bd89053", + "73acf791a870caf44d79f06946671a5818ea3d710bc54a8e5375677dfe39e956", + "6a6f51b4ef971d989dd52598f2eb9d643824dea08e2eff343412ae2b3cc466a4", + "9b15f5268c6fe235b07e2a299ac5ec8709a5af158fbcb371c017d38e1f77901b", + "c0fe50730cf0bd952c46aa3304ca9fca07e476c698fc26ec488e18e837681b08", + "fc8382d0190b8c4f945e1448a884317bf6d2805da207e534fb6c57a818f24f57", + "69f85043d5660c415031b0b402297c1af1240ee5ea4768a174d2c2002c42a43f", + "1657ac5561d48eadf8f192a89e3ffa714e79f36bda76ab89dc2687e24119dd86", + "158a84339c7e7a6d5b7ddb79b1ddb18eb4d2d59c01718bb9b09567fb07bb5591", + "3240acd62efecae14da1486fce2fb42386c724c0b384d45a098da01ea73b466f", + "762793b3e9044615ee87017835057077c843dab32509e5ef34f5546eee953840", + "84e91b4de021ac21b9e024738bc1bd3c59e75404c3dc87fe9298365e3c823216", + "a3b6850e99c096ebbcfd7f7048c25f1427281ffe86663d3b0b35d490eb29deb2", + "bbecd6708c30e04245908351ab9655f3cb44c5b2f94d43558e1ecb7369a48ab4", + "fcca27e2f86b9df9b150a76b009c6dd3f0a9695202199e57df24741088e6fd8a", + "e8541f25165001f07272652922c2c35d69b9ccf44b1bd37bbb4214b631589b56", + "d24954506ad50eb69a5fc617c531dcbbf3573c103ba55d955cff1ec453a9b9a9", + "3756b694282866a5e4ec546b3ac4911c1dbf0154ec3392745ffb1fce3258f66c", + "a0a8d7d1ba1208c22ce5dbd128acbf9e69080e0196338737e808d5d968e7a898", + "bbd3c3b9972c8cf6f54c6e33550dd1bad1f6d2f8053cd79030c772a2d0fee00a", + "65828d6d92fe8f175982a4edbc0769a828d8c7117e61a3259f0354c6cdb78876", + "e6eca0d2a63babe0bca007eb3cffa2642eb600e3f287ec27779fabcc57881ac0", + "f6ac5ee43873d38c665711edc1f13d4c9e578fee404048bd55fcd0fa3d1b33ef", + "8675acb283bc0c28394a9c0799866d0f8004f0c8d397d093cf548c0c3e2b42f6", + "0ed070016eeb56c24084c701219c44369776984a1621949aa93382e06f71a102", + "b07fef8f58fb119c0a92b450b1648601f22c9263c86edad31a79daf19d4ead77", + "1476f8b1c52c3bdeba62b6500177801a0e58f075bcf40cc74836ba7516ef41e7", + "6509740fdf90d3e4ee9e9c6fdaacbbe80f471985075dbf2466f6bb8f56b1a140", + "ee363938f39e9d0e46902ced2fb8935faf1132757f560d14f7cda641b59e074e", + "0ed5c3922753e04251813bb1ded6d2c6d0f5e1d5e103a89ee3fd81977d0eea44", + "41b6355c644dfae563e504dbad8e898c6b7b589bb49e1f1080e349f4917e1ff8", + "3d634d944f00ed9f43a0fdc1fe80f5ac5eed28ceca4e78d646c52d96386ac0ff", + "f58178e446913e4387cc51a17a6433d3756a6a9bb26263243334326436b18d37", + "85cb8f027b8c0ba5923b52c7dc35b3078f31617218ebbcce99d45febbeb90a97", + "f8da3613afb61eba426040d21df074411ccf14372fe0b850372771d3b641bf7a", + "51cfcdf82ef472df3bf33983b62f3c4166cba57d352bd14ae2a07023e7bf01ca", + "299c7650138a4415d9ef39c54cb8c16bfce3d7070078e4b920cfbf7da4c82c1c", + "06ef8dd7fabb61232dbcb4d97c4a506a37a222c516d90185d4b6ceae6b213623", + "8d41c8a210bd6c8ccfc44558fefcbbe4f94459bdc2f7e97d8fb006df12eeb240", + "f41006a5f3060b7f7dc7d20deb0f663e537da250dd854730b72c6516c363be64", + "ec6ccd4b31c2b59cecb9aa053627e965ccb086bc98d50fc11daa0b25b35a4961", + "fccdacc0470779a5fce6120846679603d37a75fee6f1fdee8677f710161d1522", + "60817b0509aca08534db470f49a8e47273452a3071bcdb46eca2f34a6ced13e8", + "603b920f4e2e8114c0922ef9320621eb244fa01db7856a2d00c942fe8ef769de", + "66ab649930ba98df991bc8b241e04270720fd765b19df661434b3a94ca2cedbf", + "e17167853726dd7f39543be172b05f8e24d314348ee72a150ab0c8c52bb4abd3", + "63f621c0330c12c080fac883d815b298f2bc08b4619f34f4ed520c5f7a2d877d", + "e1d151bcd1d300a99696617e1d77f921ffdeb9d8b37175e7272639e2b2057838", + "63f28d8c3700eb11de633e3a23c09a727fc9e1c3800c1fbd22a3ac764a18a598", + "acdf19f5d31727a48ace6bf5a4ef0e350291e8d6cf45416bfd1b9e4f1eb5354d", + "685411dcab8434dd3e20cc414bad4fc0567159feabeaa688af78fadd4f0ebccc", + "c5b4f397a481b6cab263d27b767a79d44e346eb999683279811015f0e2484cab", + "f412629c2c08ff47c500b586f87c36cccb7738170b61ab01864dea141ea2f794", + "9be8c99f34a8e6ee3acd1eb35951ac63cc66ea3fc14582ee398f0eb59bb0fab4", + "24bf25b41fe58f1b37965da189360710c16df4b3346e302588551577b8f3136f", + "d108d29342ffc15fbfc2f25ec7d43d540d20dbc84f92e8abea0c221a7dd66b8f", + "c0e3c78bc2f5a8079ca150f0fd23153cb54fa785b22901ff71f4489705cf1ef4", + "ac3022deeab8cffbc415bb95289fcd2df076b966b59ab0fbb12ce8ec8e61d5cc", + "0a2bef5b82efef3b7818897411ff3d6c9ba231c7d9c304af5fe39195578c6666", + "8950a67e79b415bdb2259f444911ddbaaece2844069940f4856f19cb4155621f", + "9422364af8b530ca0ff933aa65ca6246f65bfb61cc6173a32dad750dffc8f7bc", + "3d271e61c19790744a7d1e8b8a54f23b2dfc5627df3a9605fdcd6cbbc85ce785", + "489ab28a00ebb21dec3a0cbf8ccfc41eaacb713233b1a754c3446a706c52d538", + "eb4d6738a0d89181d0b503e1261fd69602975aa59a2a61392cacc65ef92e1e4a", + "c92ddc49e13f77e4444b251feadd5d5d10ea30e13811dc8ff8b0f4b88283c872", + "00969c6671e036f27733ae37204eeb947cc40f5627bf7b80ce1e4cb3e4460e04", + "b26cad8303035a7fbeec05a01a9af13733cb399f1e969ec5dcb5916e297a9689", } -const ropstenPreverifiedHeight uint64 = 12088512 +const ropstenPreverifiedHeight uint64 = 12138624 diff --git a/turbo/stages/headerdownload/preverified_hashes_sepolia.go b/turbo/stages/headerdownload/preverified_hashes_sepolia.go index bfd4d0b3b41..5c0f811d48e 100644 --- a/turbo/stages/headerdownload/preverified_hashes_sepolia.go +++ b/turbo/stages/headerdownload/preverified_hashes_sepolia.go @@ -2694,6 +2694,1360 @@ var sepoliaPreverifiedHashes = []string{ "5a430b72b2d0a5fcb31cd4e52ec8fd3346b81f0a04eac20d4f60c2a058fcc7c7", "3a5cd674803091499af865e6714be801c2458fc54df1a5ebde8934b2367d846f", "45b8ffeb50577c61d1bd98ba49969bc4095f84a84703fd8f4fda45ea13aa16d3", + "825ac7f4c3eaf37006ba1c4ddbd47bb33fc9758eea114fcd677f5cae0b7ad417", + "5643b8ad702553c0a5211022a53072613a15cd8c12c3fdfd9fdfc073b24aada0", + "da779c4b38712a6dbae86bd15657d36f8447be59fa449253c2567c355c8d6d1a", + "58e4e0115a96dd0f9e936f872c9762af10d00952fcb07145bc19db2c7f23e06f", + "f9505ffc1e3bbe1c9e05d83cee330a2d6709ae6cef205199182586429a9d5e08", + "1a4ae0675bad816e3bfb6be85dc779b696851a71da6901931fc453908355f01c", + "69646e92ca47be600786cbacee5ae04075fe272e09ddf00b2efac89c2701a3f8", + "4b149588f48f928702f3bb1bf9c97e59829a209d9e428076d0c649d86815b32b", + "83fdaa8e75069781039af520203d201e95f34f1f8d430e2d0d02d2f20e09dfd9", + "d44085572e1b52b027c7570dcd8c00cc2f2c8d0df87918fb5d5f9be45d19f17a", + "5f49d96e2071e8ca027bb15215576e5a7fd1523886b8c0592962e652f7225768", + "a2175d359abe5aeb8ba6d090b6715e19a32af37f0b790e98738f9633ab9637c7", + "48582c96ea2c4c172b23e32f4d0ef0a9d0e0be8bc184a374c0d51b5a858c8c25", + "f34443eb9098e35d83da397ceb15fa950d957d4050deeec696bd5e889152d3d5", + "3e25c79309a1c8901c59ce50594e168d4a806e7a4f94c2d9e71f2c10a11d727b", + "3cc64475d719986b12a884fb54791df8774b3503ac54f0684799b8142a9ca852", + "5df75b8c6374ed1c4fab0b24902537ccf31a2e1b2719d10e117e9015982b7737", + "84d17f9ea768d20752dd4967fe1e1e20f706f3acab68d29fa32e40c2675a274e", + "19237dda85f8e713c38fc58a8a60f4e685450b67d85cedd91234b553d13cee46", + "c70ac4fe2b2b3f369237b4c5a61c17d197efe54273bc1c39948440bbe3fee62d", + "9a017ba6331e85a665f5ea87b161be5e501803d043a0586f741cb00d78ecb22d", + "41ea24bf5e1e40a3b305e3c9ca00f014fb36711e23d1103621766e54881c7ad3", + "e0998a5387d06efcca864e7715ed22e16b183c16556307b464eec4e52511842e", + "dff5da78a361e21d9fd189652c45e973d0f921f3cd95e32ebcbc322c80280a0f", + "0bbacf479228598ac57b2f38d2fa3581085eae3fa9453fa21b057365a4febe96", + "c93ea4c6f4e31a89caa96f150982bd7127f8b02b25ee459c07d63a2959c6e284", + "381bcbd0e62d1cbcd82fa392beeb7b29abcce0f0dbba8b0bb2a31da7a74c7309", + "6c5bac3e0753cbde6a9a2cda25a0a6b8e3c432313da7567de3dfb9f2955b4d45", + "6e2188e0bd15de5ee069261f9e8910c9c5a5eeeb0b7541a1e38b0b65d774a53f", + "6be429f5bc14162f76bb7459df478b7ce73e4a394e9de61749b3ed3a9bca5f90", + "d0807ad7dcb78d4a116c351eaa34c05d92104790683d4ca5e12fb4bec4ad7227", + "bdadcfa4549137f929f80ec54a56c616a438bab2863f3926301030cc7a1add22", + "b86f76daeddbd49ace7c4793214a8b362aa4e095a738a9c140abf00a5ead92da", + "219f4cc4ef42f8eb99d64e1ecb16c84084185e813db1369cab2d7bfff3386bcc", + "9d0916238bd331ff055986e2f5a78468e267868784addc9f4cf6964ba1b9479c", + "9c6fd3c3393bb1f94dfb04e25eb7cf73db5640b122a2f477a6a2ba7a901bf0f9", + "31c51edc4fe446e8501ffc3089aa3188afce01022d16cdf72fdc28abb65cd4ab", + "442c72ac438ba178918b68c9fea0920c3d4816ed1b773af9cfc58c09c0cfcc67", + "53436579b585b52ed40b2fef1d36313d7175c55586be2986b1be7e2d949bf4e8", + "ca9678fce8e917a6c54905db41215acacd6026eeb7c812fd40ae474783138144", + "52540836b134d36d47af83f767fbfff2bb4bc46bb5c4db013e78a7c1ebba31c8", + "dbd82ea662f87aa08224dd4ceae395749c2284251f495a512ee88a4fc953402c", + "5fcc599b9174e0b197683233e8e9924462afba259130e0f1e4d8bae7a8da2919", + "9283c5e91465861108e58025b6ad36bd09533f9c50006388ef9de52428480990", + "4148506b0281494e770ec1823ef9eac60ec6a8f892d703ce321a090ef85edc4f", + "1dfdfb3f5a36398372034c73cf935b2e8a434f228f6bfde910eec33b33a28a40", + "8974d081aa944ae6406fe13ad70668763c263e936ef8624754189c792bac2d41", + "9c71bfa8c3c5081caf5e81c1447463837bb3eb566ad46548a0e92341189324ab", + "512092e1183541d38943dec377520b35ec7b6f2d5d99ba3bc283ed4e81b6f6f1", + "3849a6dd0431a88330300f2e2f022bd2a0449718b80121ad004d84ba3fa25537", + "838ade25576ad03c225a3c8bde7b0c3ee517d4af13de8386711508c438619f82", + "4cdab6210d8ee20bd1450d0db14bdf73f64e3f378a55ee524a4723a3287bc1c6", + "abaef58032fbab41449332ca209bb961ce80fd25d7d9c368323f81cec0750643", + "f4f16c66a1a87d0baea4b97c5caf17c18c1ddb40e97503e0945823fab6591d3f", + "3277d1c9bc3eeb37b1d862a71f9791ac363b58bc8acb38da509bf3974705a31e", + "7bb29795b908301f38eec101700aa67fc1afc2f7d4004145fcd4c4cb02076646", + "bffa8d8aadf6d188f926d788f3c9af562a752167814b8bc56db9c3bea7f319b5", + "797174954dd9c194625b85a035c6ecfe74dec8959a4ce8b6407253e217431d60", + "e4a7492403dbe56239ff1c5b6306a18dda5f17fe6a9457943c9bc8f04290620f", + "e7402135aff6009a6e5f0b808bbece1e63e97492724ab9ec39a9559f6b2a1854", + "26ad78cc0afb0b0d7416c86403b86f52f12650b977bbc97cb9546bec6f4843db", + "2d1db28336d620bafd99fbd1f10dfb836d7600c1376811195fe10608beae1088", + "d2b0825c6b789a556289f9b26a14827346477a7ef793abe6fbb26e3ea5b2b165", + "ff0d6eafcac0d48cd57c5140f0d8dacdaff4d3a968ef071b7f6ada83faa0e256", + "827337b6e14a731a7499be07eb4cdb6fc28b0890a1d29f23e821a2ca566e76c4", + "9761e3de69b7e9b1ff1a108f50b96400163f2e74fee6a6cd2e553395b80809e8", + "4e642f66dd733fe1cfd3a88430d15f69e54a205e8d02aeceab461e27e4f9f018", + "4e88a8ff95bffe4bd9b289824ec49732a59a7d9595df57acd754e29c1a847ae7", + "409745403fb7a1a80c5fdea16762466ed9ffdb257ffef6ad680af3722b6db01f", + "fbd26fad1ad2cd9661baa2e79ca4f0f4cfa58ddec39308aea4991391fbcc693e", + "04cf51f673b2b5d8197a51748d96adef42a7996167c165f20dc66427d10a171d", + "ba44bea37fd2527b108a6b0d632e521ddac333976053f18262ed89d3e81e07a8", + "3d6252e6a43fc45180be78c30a990950a7c715f6fb21aac65f999da66e071528", + "ece3539a4b549cfb1afe648855827412093ce892ec074599ed762f0deea19469", + "2239f39e15ba7d1b715362640c230d900171b6084740ec8f73bee43a55ceada9", + "52a5b8d5d34d0bf90191ad5c0be98b204c364f6c83409e0c1deae03cd90c1597", + "d2a6ccda6599ab9c46b534d51ab2c203d1944bdcb69ef948d9b1d2064ad2db41", + "131727d8f1dcbf0428595449b78c43ef383c4df5d92e2da75798eb968000fe50", + "a61d3e60845c36d72754143cc40ed5823d702ba3004caaeca1850f7e3d07c04a", + "cfd42f5092ba159cd497e5af481960163a2b1e59726a6623a84ccc53f8ac5d32", + "27c2652e730549c7660ca55892e356c85396ef2539ffccc1f2639d58a59d06fe", + "fcb8ec7c08869555f32b879c3565f3c46e4cb1dab8546afee5808a569a6fd85e", + "a8b7d634c223b111649dd07968c64abfa8d74e8581cf3388f1529d0a68adf2cf", + "23e6d24c4353a9445c58567a64ad83b3d65214a336fc2ddcb7d1051c796039c0", + "0ce1522b164ff0d27d8a58d514476308277344eb19b82c18519b52717c03f854", + "6016c177740ed7eb1a71be0762bfb881dd1775f4f9080bd9f6c6c99662dcc079", + "57a98cf0ac5d7ab89af004833891e9b2418c96aba2fc5b8cc6ab7b0d3972d6d3", + "e0f297957c1074f3cba2e13435830e6d2cb48174c50ed3f70dfbbdd8f58cb684", + "fd7573c2da582e336f32ade5bd10fdab510df27604cd8211fbd79fdbc7c9165c", + "eae75eaddad4b95f5b47549ae84024282c70b5702b073803afdd7c06db992ab3", + "43947c5ef9072637dd3c0789ced19ccaef56300694f5f6f38bfe66b1e1b5d16b", + "4aaef57cd2f8152d15d6a4feaf16183078ba6ee3fa87571b60df4dd323fb22ee", + "6d190f073d05e358206edb8b235cd9a3fad5a288677adcc30e949600ac2d6f0e", + "691cecd08f8af8ce8c13ae844eba2de9db4d50b5c0e43d2f7ccf238e9e33b1b6", + "028852cd16533738476a283aa7b5fe881fadfafb27a820f8f316e0e7f50af690", + "7d76a685b3233042beea34acf853adaddfd5b8a75b5978cd2bb6cc5db54ae948", + "505079bfab29ec4a1383f747109020d17b7f93a3a23ab9a88fc5b4827601dc43", + "a1303730b4e655f922c0155818694321c31e9323a8ed41aa148e385a7b12cd44", + "d770a6f2bc2b72094e9cc42585211a466ee1a70f39cb3862c8592b47ee2e2555", + "f47d1465a48eb85f2ea5dc01297873a71e060fbe24dc2d56c8104a5772553eca", + "76db3028ee28a9ac768306010bfa13521174e99317db81335701aede1763ad5d", + "7005166d96ad287ce08a827defc1a3ae48ae0210c2cf0724821eed11d061f394", + "1dfc631fc69854d36a2e4838dbc3283300fe589c83eb57046bf4e5be9f6a86c7", + "0fdeb7f4cb9ebbf8ba5a5de9b54904e4f733a32fdad70c578e9ebd47f21eb71a", + "ed273394fdf7e8e03629d58002f09697020c0bdbafc9e1dde2d93eefd4835099", + "eb24eea2b782e3a765b4d03bad12465e7a19bdc5fd7d51a50e28e1d199cf8dec", + "19cf8006d629d345ee3ef3e84059a733fe916b1494a4d77777f26fc8038f478f", + "3a80e755fd086f9ca1e51bb4353d6e010e455cafd9ff6a09d84a9dd9dffdb73f", + "b04c96a32563bd26faa7a1d2eb0c8c63751b969dc438bfc2cd1caee35ae95540", + "068658fe9b3505edeaa3e46a98d5b377988402ca703faa380c765cecb5f010f3", + "5a7b2de81788a1d0a8c8d0f92787495cef1aac9ce4ddb5a04f0289e302d042a0", + "0ca1a1e8e1982dc1c13b90889def6543b9d97830d7307fd3b13776398a8dcd89", + "70d1b1bbaa39f4f029cb4952b0f39940ad283036f6a691932deccabb2c71f9c7", + "2204f5a7dc662941613fa3ac1cab1b6709a20d2bb35778188afbd54a7ffd003c", + "b700acfb87160bcb36704790d39e58299285cd0fa741717496a5e98384c85635", + "6fd95e064824b6792d96286ef3449d912e81f1514acf7ccb86ffd315abea5e76", + "92fdb92c2be4c0e1ff91224a90591762989a5a3cf1abec9174986466281408d1", + "2dd62805095351027c4df4a83e4609e6c08dbe4c9363c0207eb39329a6b031fe", + "94e35d2b4a342a29a7673ed420d703e54fa846484fe329f651dc3b4adb7dbbc1", + "3c1b30ab9f991cd9c0546925739c67c697cef90bb5184d0c250c71c6aeb62fed", + "8bdcad9dbaaae7dac236cd06d5b759e49f116d725dbb135f03c5b2effc8a0019", + "daba93b65a62cd33e35a19a0671dae870eee0d3d03a9560b8d4849bbb2f13b7f", + "ed2144ab980d8227d5e260ff13ad18be3f33750b4573539527e6a287f7d38107", + "45ee1d5a0210ad375ab8edc5804e110e754180d33973ee1836f17bd2ce8857f9", + "42ef9f408f58ab36bc92900af81fb3a16e418adc5987e864ff29ec0d05ab48af", + "e78cb94457fd452d41c5b10acb99f0002820abdd282ed5245568e3c86e2151db", + "11bd71c0ff22109ab9d89ef5ccd4444861c5f878fa7f2540d96065c2da66c78c", + "b6fdf0c09d1b38efe5204ef3f88cdbe714d9e46cc4325f92bc36c8219e23126d", + "d83f29d6a052faa2e5e363d23520d9188c21b1e8f705675b31be2243f6047946", + "501b2ee944c1943e61fd36105f9de2a320c64f2916d5947b82bd61c793bdcf41", + "8becfeb86f1a8c0de7eb6d08e4dc843a9854f8d86b4d4b012f5970c1c8988ed1", + "2077454d60fcf830fb2410e1cee537cd4d003d2684c8d8b42e4be49c190ee6b6", + "18b689a3538e433153c1865d9c2a833a986d9e9048137765e731266deaa70cbb", + "5911818f725a8f716df75ec82e31a471187189dcb3b83e71a25f33c9dd5d5203", + "7d892c31a620820688d11baca7a33c61f16e67e539083d7622cbc34f657d61a1", + "034a3f89b2815ff24b22dea0766f00fa527eb2d1085e9b9ae49e42ccb2ba4e89", + "16bffc4087f5f7e29486843f865700336dbb789721257efe4d2b3e907158e03c", + "1041501fa1739a5c3a44549cfdff7658bbeaf2f9846bc586e7a6bdd1d0c6df04", + "ab46cf6d760edc02a2d51d79b90a7a57b283376e114217945fd158fba6de441f", + "457822a85b2e01a375ddcf40fd4c3c26c4759ecb3e30405e0d8962b5c278fdea", + "ec23474723b2e9f8ea0a5511db007fbdbc9715ad5932f7644b0a369556e1cf6c", + "0506ea2c60a471c44ca3ad3ef215d7c16dfbdebabc598c5576bff95b62c7713d", + "cb2ba47cb49de5524bd3ea9c8582d19e4936a87b1df793f5dec930e03e35bcc2", + "324f69d8aa700280048414ef9b84e4f579b86d9bc84e3f67f07354f4e2d52cdc", + "7015bd11ced0d5f4deec8159e7c75cf7746699772f885b66d438c0ce14a648b8", + "5c8215ba1bfb04e9345a261c33a7152875fe64b7de94e61edd0d74c8941abec7", + "6f253115979f75840f7f2e1ce9dabb7a73f0d16bca2345c9b4e49d8bc2d71e45", + "ec01e81099b033f25bd0c93fd304397474670afccba2a9a9eff64f9411904c5c", + "55c78253865f4f5e122daa372a58582109e4aad972104d3db89bae875c7489a9", + "6d4751b7b708aee4190ee84dde7b6b326dc8292b5495a8140d3e033867b35bac", + "08f4f6f7dedd542d218cfec3e823c2024d1c5ed383022c4a9aeb0882c34c5f82", + "32291ae41edf466a29129e6586fda95e7e4e952e27d1523315ab47853f81ee8b", + "c0abfa9f370acc151705972d35a7806c2486a16ede888dfada28fc0c30e58287", + "51c4412c55152df2812fe7cdff629db996c248d0573dc443951bc8b56eafa77a", + "f856d01fa8d8fd6355accd03ad1a3886893d4f56c0bdfeb06d97bac59c52f640", + "88169ff0eb214e89ace3f30f735b813ddccbdde9512bed782da3a2759e9d37fc", + "54602bde9ecb7a43ace530d4b28684a9746d618c8b9f702ce1c0220bc1e36291", + "a2eb712e971e86aaf244a806b81017332ed477610922e8948f60a627a38b7edd", + "28ca43cd31ca9983a47f02fbc80348941939aacba236d52952629f7e8858daa5", + "c552d0a6768c4615616dfcbe631291701ee7832b0dd37870d8b65e65daadc6e2", + "0a1b56dc3961efc79aa281f3b7f819cda39636d2df22073fa9b9c6bacdb9c8ac", + "a252020b7bc405b8e61dd1201f6ae1f0c99474aa86b9da55a93b6bebacf2c8ac", + "65de0246bf8c303ff42b3aa1e23f0e884440d1f7f19f547094558f7d7db0b279", + "5f522dbde472b43bee2889d0abe9badd44f75342e6b57f948b1f859bfcc5e26d", + "c10acde38adfd617aac724a4ab2bdf5fa4b02fbf3c54cae14094eedb2aeb51fd", + "ced1f2ae64b0882e52fb259ea8062e1d86c819baf75cd8d5fe007d0263494031", + "a8caf7ad1a9fadb7887b65e1e74e6ca506ed69f32dd175349bd3069cfdc402fd", + "4db6888df809dcbd797a62162ab8d8f222e0e0e98c408d8322da12e91d797d3a", + "88915abfe73479f988c34c45b58d9bffe9d67065685638559c2155e9ac0f85c9", + "af80bdef78edb47670c5c43a4b083343a58b982ef8d8a7e82f7825eb9c37578d", + "cdac0d90e407ea60e56a0a03e0bdd8e6b5c94956fec7929f789b976ca417b3f4", + "5e6e634fce8a0980ee81cba407333c54161e2bf118c3510dfb1b4465e9fdf299", + "589024a137bd4db248551a513a455967523c7d77463f9e1e707650c8e3fe33c9", + "2d4b4068838decc7dbc121b007cfbfd6a41131359ed2fad5ea5f5b90f166b116", + "c78b33e568c64281ac9e4267926f5ce08c2ab9dcfacbd05c85043b38ffde6adc", + "be154c2f148c3fa7dff51792f88ba20895414667fa641430fef366625fb309f1", + "f800b04b9dcfcf871e3a2b0a30e091416b25301cf064a4c804b85eafd322a825", + "387ab64de3cd9beb0b82bef8227026c99e78c4bf2c3139d9268ab37520dd20ba", + "94bd0f35532c8f1c402c7a1d3028058b551bd143421b8a0488cced224a26e8de", + "2a6bab17d752a26355bf7229dc3181b497e0349fcc9bef99bd1fe5f178c76295", + "27c785f77114d043164099d4321fbf63c07e23ff5f80e4c4589cc2a95cbd63e9", + "52e43bca70ea968ce5f5ce2ec4589c57ee855ce25db495d056bec0f3f42c0e63", + "2553d6daa61807dd1b13636b573a56f800ee6d77dfe0a5a1981fabb6b529f270", + "5f8e72b271f7b030ab618147a8e0aead78be28bf01756f45c1f6e175833252d7", + "d3abc441ff9041ae3e45c783ef9939f397117c139155b69d3284e1eaebf80127", + "7ec0308c921fbdd4dc54d63e712009521ad85f2ddd3df7233c37f531c8689f93", + "1948f50fb77c3d4ee879743111cfc3fb4331335828f60684f99ff4d070008a7d", + "68222e1c621f2f98ba359deb815d1e26d28ad2ef8ffa06965b68f5bf323a611e", + "cb77f07f5fb2004f20ecf18e67a3f15735072d38484b6d18d20f7deee3cc17e2", + "0822c3b99ddd823ce1890503c12510ed65a41758cc627efdf56e9e6bd46114e0", + "644e5066bb08f469d9ce1322bd72f499950c657df5331a29e8d51fbf61394f77", + "449e377a0a10a1486ced9391ad228df1b3b6f54e15b649af19b74b8511f82bfc", + "28c28ff341a3e31acec6cc92246891141bdcc0387331b76c5a27f5e323c7d014", + "a4a5d0c2b828d99504c779192230912928cbe15491174c82f6a84252fc9d8a03", + "2d37c4670739f29a2dce936de6a3b683068fe73e802e991a9c72568a5a9a7ec5", + "a2513d781bab5ca13c5a9fec0f1de7557dde052f870cf8a945c85bf11efda426", + "38b0f71aa04ae9293dd7811f661ed8b711ed48c1edc30dae3e3fb19c153539f9", + "448053f3bc810795eade91faf536ef09073cb7793ab73e3b4cfe3435a8617613", + "26f472e8574e3713ad1d6f6e1f3a70b655f4f9b476e416434242d93ca7a15909", + "49067a699f3e24e90c6a8c974c322d344365ab3c99fc8ffe7c88258b40a7bd9f", + "fd10ed26642f69b64407b3c86b472d8f554fa10ac7abae7610067a01c0a6687a", + "9c06bbcbfa5b6f13b33cdc34b46b460aea6e7c73384679ecdea6b5b7a8f0902b", + "5d3bba2f3f887b0df28fa2fa624d006e75ecde044ac9e52ed8123652abd628fa", + "972db41e1fb89de3fb0388db489c4e5ff31e92062949fd0bc5ec0c9b4f92142c", + "838f4ae7478eb00b12f1dc4209b084913a68994c99fdb5a58a289d3e83d55215", + "fc922547d86392d484d9c3c7439c6a4138ab8213c401f1be42afd65834e4a2d0", + "03f37ba6311627a33deb6ca497219f142efc3161b82d0e53348b6ae8341e77b0", + "1c55cad28c81cfece32e9bbe5bb8953a63d70b547f751fca55f326bdc739058e", + "45b59aabf904c019bd89222d4be46bec4c01a671ce6ce6f31cd333e01f132b0d", + "01bb1cd5fb0c626b324ef2bf6953d4e70f63b8f65b36a0d6a5c673e20159b6f9", + "cd2d8ce83105eb8578ea069665e632fd8832489369c2fe87c6a08fc1b754f1a2", + "1a0b46e30e2b452c4791f671f2b595eaac4de0930994652d280a38464cfd9f8b", + "79142847e76fc7751173ce5d6556c31703eab5fed76e179f495b09d3b69f9002", + "280d3ad89304926990a8ba029517cf188815aef7e7c8654fe862768783fe3a46", + "5567de0c9dfde7162bde2ebc9d81839c34571e4c16c178bf6f831d233ac6f0ef", + "a2d918152efb4b3cbc757294dfde898f016f6016d7e16d115093f7422c80346b", + "5af6a79150a894f229df6b4f8bf64dfc3585102f48b3e58e5c849d98972cda1b", + "3ea88e6de33345cf074b9210e78a49c7d2f52713fd99e7e9f0b408d9e6935cac", + "b55268bd26c38336542721bcfa0757e976c4ae29693a3959cb14bef0aba3603e", + "3f1fb560634f5b7960b3284b9939f62f413787af45962074ecaefa6c04d2e81e", + "f1543f85b5e6933bae35b3ba6abb262737ab26a7979d1024f18902a94f754bed", + "90f6235f5d52b9286c657d50d36214289f2e3909bc094bf3a7ab5a634974de99", + "63f4e54f59aae62c0d0d32c5cb23d52e79e8a7483e4d98a2cf1fde4c136d5f83", + "76ab6d38baf1b9390b75f73fd3a52b2c9b78182822328ca2b18ac64d8e83e6ce", + "3078db46f378b98eaf6423fb6a3b682c8ae0303d8b5936cb6db05ec531daa828", + "24792cc5d520d2a67a2325687c9d5d155fcc34bf6c8b6c947a292cb2ad08c859", + "d28f023fa46cf80a356a67acebac5a02377af05bdd968eca1c50fe8efc84b6f1", + "76ce814fa12c244f43acb0906ae08bd92b580a6702f3375b7c081145dc07c0fb", + "17f5431df5d59233dc5b06cc8aab4e9110bff64b0c214a208872a286acd941d0", + "968206d531d8114d1b8797e23c5f2d300e8f947b451d5f63799fea8b40edb136", + "68c9211abbf332f16ff254eb026d37a58ce86269f38bd2a017485ad05b638532", + "b71d3190c3ab662f40c77795a136c9033ce3aa832bad2a23762a12dab8f5abca", + "9174881b81b29712e4e48bfec666a862b69295539f93fe1e87f40040c8d1ad7a", + "79aadfb84b2e7ceab9315a7c7aa1614e10e0fc70ad0fd56aeec675e5cfe91c5c", + "c1cd7519977518331e95769790a2d70466f1a48f72a24b44952639af802242e5", + "26b06f4e8c0f4e7c316926d99479f2b8fc447090652dddd39b8d97e3fd235842", + "af4e4c0d9228c5e7d5474af63fec115319681dd599cfd3a421162caa8328ba47", + "3c86f0b61cdf5b68b0680000bd43bc96f37adfa81ae4adf60f5d1cb7cae6f15e", + "001106b6d7a47490ebfc4c81c11f01f516b6e4daeb5cf8b7313140ab1caa4316", + "b394bb53dab700f4685e2000389a17a68757dd413b853ae896362c85f37dbafb", + "2f53ba1bc4703738a21a561b8474b77a2bd08f8e0ef6a2bf9dc1bde2d78da6ad", + "351ba4ea67738c9cb0d90e9b0afe65c398c9ea44384e9bc8d5a5ca48aad343f1", + "619e56d671c0f79d6c34e92af46670d798a87ef61ef85a53717f7f920d694223", + "316346b2bd02fae1f2df682650fa242a6c6694ec7899ed2ac94c0df6eaa2b27d", + "f2288345d9ed0b198f1f96042327f8b34832e0d60524fdd51ace946a2ad55715", + "3546787b1e146e90520dc9886a8181e16e6d311c339a7896bc92e3ac07c87cda", + "5e8a01bb43849812125902a88641790cd0b6a114cf4d3cea3d042fe5e03654fb", + "00420aa903814417bbd1b4b97a9596cb20b03989acf4bb8ceb531081b62ae922", + "6449e9e28a1ad985c71570477267128ded179b96f108c6d90b4b45455f318951", + "257d6baaa08eed37a759b0f5c3d37ec67305710ae89769fb1c24cd91a15a859b", + "7207b5fe405c232cb9e7195748fc5bb936616418d7424e2690735b3686b337c9", + "d60e835b6b3c13f7d978e4afeeef698d06288db227969fa774fd01a3f28952da", + "f37936eb8c86861f931cf1d8483067c0c217a1343ee64233db14d93221046ce7", + "fb907f7b0505d999f837a49c1c43a8f8166687335e4bf97177e2179f74b0a450", + "222ca53000cddd97f9594ac7640f7ec3ac8915a542ec2fd4bc75b6d03a18296b", + "d66841bbe3ce2b7b0bf8736d74a709de6d683ae3b3c5173ec8f9ab1665e53ddc", + "a38064e3b533d7a119b30fe7a53344816f39cf6d23831470e7bb26052c3a01a4", + "9ff8259172d1169a0fc35e0e25efea54f0992ece48ef97fa38a7c4b6d2d8d6b5", + "df5d53836939ef370bdf62894992e0f1c03649d4ff8814cec757f4dd6bbd36c3", + "052a9d4dea41d790394e2857aa6f4bf3f06850af1c130a4cf0bab026301c530a", + "68a018fa5462ec8a927e56ff3fc6a767aec821a719c7001fc1921bffe545edb0", + "95f6b8af9a367d4050ba20636efd5eff28a9d61b5cf4016665df178516c0f085", + "27feada0b58dfa6356aa1e01679bdfceba99ac0fec1c8901826e1bde45ac7ffe", + "a92e6d04ea8ac0c265e9cfbee4fea8f064199cef9d9c979441c0e8b3480bd7d7", + "5032f69e47cc7310bf27266250c9ef00f64dde070aaa1134a2d635d189b3f16e", + "1ae3a44776bb90ad3e5b94a75f000b3fbee6a0fe1f0b0c6885ce7b85335c1498", + "54f70ac914b411c124fa65a171131382d41ba004676f17249cb9f97ad688473f", + "4be6278e7a0025fb8167541edcd59ee4e5a48f083a20c78c6e5c93b97df12b3c", + "484e5384d1d5e19be9bc5dbaed3a49e9321d76c7396a6e8e110893be8227692c", + "0392375ccffd490415347bbf4333982d38251f5bd00540ea7b97c18f923bfe39", + "fbf0afd96e0df590e90bd186ad7e637aee6e017c32ec43b89177478c84ea20a0", + "db85dc48645ff7857e699938cba97a9e44759f5a9ba7090e22f8267c8a6c4b79", + "9781f615b92bb5cb9c34381ca78e1bc641f7cb442a3b4998b4bd7127070365f2", + "dbc8f8678386c3803817866c115d281190377030912b2495cab134d6f5723915", + "ed27dd2e73e831284f100d01857661161ccae25644d0b9e93941ed8c72bf84e8", + "2d27636776127f7c5dd3d930c1687e9e580a8c03b8095e0c25b3e68d388e6b86", + "41a27a002bb1b3d782fec4f102a2de79014a51fa165e76df0365a6f87d950ed0", + "f238ef247278782d82c890f690d189c57d091d4a7048ca9131de6ab058798a16", + "3108d797f4b09c40e70470f2a20aa4928f23b819e09c1a5c224bd7ebf6a21734", + "03547e5978432e74876c9102003cda0b19a7698501aa026ee1e42618e4c19e02", + "d3264385f63fce953fdb38176f2b74c7bb592082544e65e316418a47223a3a65", + "b6543f36c24ba300959a993f1d8757d112acd49e6e8e35ed2c69ebb6f64805ae", + "ae2a93dd26d13883b46d243eca97e43a96b98044d4ea921131be3073f7e07e52", + "225d5de32149e1056d3c515d60f7e0581bbac6e19ae5e4e164b3ec5167cf0663", + "07b11c9114b58d506970f86fe9aaa4014e2fbe93523e9fd600550615deadc93e", + "9d85b1603d781bdeac2921ceb6b84784b79828707f85a29412f6b7269639da91", + "94dfa00f97530c2e68f4fc5a8821ad772ffc35a7dd481a50b0c720b5552b4f50", + "a41203152803171f2ccc8d0dd418d124e914c5d49e979ccd9e7a87cba9f6a147", + "060cd82de514463cd919236e3bb7cada0556c5c46ffd3a6dc21ccfefe7a8ec5f", + "73fcc28ebf619da2a1c3f70274af02536b2c7aaa82202359c32ae3de185336e1", + "f845c262c0ebf91f79f58727fdee0314c4030d77813ec91dc8fcf7ffdaf43218", + "c86c1f9be815648a7e0e23da6f9fc220c49b622b2344445df519b37224b5799c", + "bd2270bb72a1a481a6fd8dd7245ebd53014ece58310e7fcba48afe54ba6e87a2", + "ff737810ada2335deb50dfc5e3be801b8584cee9bc1cfdb0f22b2f496b5611f2", + "c6569af1d65e225a4d905189c7d9434b426e1d696eb72c8e3ef4fcc525394b5b", + "2a10c41fd951c77496847e9508698d13a121558df0842ce848949560285c8df8", + "5ccc3b23929699669af98c1ebb0058ee0eb5b0e969529b48cde51bbaf276bfd2", + "4234aac3cfec804c76697d2c2f14ec8d407289fe6dca23b80c2148633991757d", + "ea41653fd2b38d4796b74c4fb4e2451843a716254f882a2b856a6b7657371f8c", + "a602b9eba0988b2b4bfc0571afdff67206e043239c1b76323443760aebdbed99", + "1057d66ad0458d111e11bd5d710f44bfeaed8bd3301807bcc38d131d1dde6e84", + "9dd68a22aef999552a90cdaadc680d06c2c86ed8e0dcd73d151f4ba090dfdde1", + "f931ab5119a6ac22c52c3eec9dca5dd117b683cf063e18658f444db1115c2777", + "388ab75fe21ef75ad594a52eb7f4f09236695949031dff6749a386afa0fd7e01", + "677df57fb3856b17deb80fb9a7ffba55c7ccaac8dc9cbf11001047b9e0bba28d", + "58bae675f34fe2cf4f228db7fc629fbb4281172e091be30327d3bf27b5a330ac", + "3d7f13eff50562974c9824b625cf7bb8442250c65809f17e26d8cfd19f56dea4", + "990f7fb9b387ed3d0da613ed9e4c1f3e877f402db1b59882d11455e2688ef149", + "2be4bb11920a82c0545cfec09c398c292519777a2e3d4acc71ce521cf91769e0", + "0b9105a45b6ef672d66a0293fd87adda965111cca1be8499f2d38efe6d8bcded", + "df016e34cf8a0d7d11afab1fa5ad5d6f14b9c4ad2c7048ade0563db0fa7b3df4", + "8c043e9262d541555657771fbab50c25b19b8ce2e8f82621345db89f149105e9", + "4d5e9285ed2008a8547bdea99e1b00b0e6e6ab1f349d9d76373949062611a0ee", + "6fa3e41bc432cdd9c60f861a1d59e7eb90e34d91037aae0a3528aea0f95f1a05", + "1b47c6897eff643853a1467034db0b246d51f65c37084e19d8c338af5d1b23fd", + "4aa781a1472bb32ade03d76f5544233561410b957b48dbf6e8de444df687b24d", + "2efc0c2537193cda25705efdae4168990b6e4e19351596495c2c37d71670af11", + "33bad7285716213b02b5423e91099fd64d7512b3651d6100b5abc8ca55db1203", + "b9ed789edfc3abc44ba63f3d72f2a85edff5ad845e5624e3b36c035bf9f479b8", + "d96f1ff48d728430dcdaa4fd9e7c12d11d5888c9739699f9d37b299217bce27e", + "951b7880f66037a009f8b44686618555cf6ef81c80228e49a8ccaebf02c60d8f", + "d3ea68db9f6320c563867841c5628f06a2b9f5f279885cb2bdbee4b92d05bb51", + "b23f6f5f490cb45ad4a0845bc98c51cd38b990f1676d72ba56733509e594875b", + "07cddd8d8ef6066d1940a46ef800077cb101fd21238a5016402731690110e4a4", + "d6b30e8c0b7427b7cfc2688e68fd7bf68360dad232cda324803c74b092f8cac6", + "781df114562cdf573948401143ffda7e3dde56aa68c3cbb43dce23c0e37ba896", + "9f3f623f7e85215dfd3227fcd9b5ddf70952395481de40ee151d7ff02f9fc35a", + "e907056092b37aff71364600ef5906abead6310150a39217681a1d2ad73e5d14", + "c8b6c6cf160f6b336b0fad6382d300d878726ca1e57481a0ab7b9419f735636f", + "35c73e4315a66264dc468950a9a67e6f15e40d2301779e84415834bea3e01124", + "6aad66f8ea97acafd14b4b0171790574429c36d27b56bb3b09e312aa069d0d3a", + "1762cad7dff31347527a78e53555c790e0720daffc12100ef6d9072d7e30e113", + "366d9204ffd1def1aab6f4e1ba01b210dddc09a745a55203658be35f107f8767", + "0aa5a8995414518696dd44cd1908f5c5fec96bcc9e8d6986278815d053fd733a", + "cbe64576401ee731e8738a003a531f7503717113fe3c107e1a6ee4e6977145b6", + "420115dc364b62841ceea21e42cd696a3a5ed842db76ac97985f67e5c3c105c3", + "75e03619d554181b5092938932fd466b847aa6589884aedb10c2bd16cc1745b0", + "54cedd123d8900627629e02768759d8acf0c83cb2f37253b1a9449be8037ec6f", + "b72f5839b56d05d0c40234bd006407e01648dfa97a5297d867ad87208e402858", + "8ef99fdd306c6409be67d7b3c2ce2746d2b13af7466d276989aff3e4cb6438dd", + "70d603b89ba22b994dfd45e92b09b1ba663288f800d3fe7e74ed30581355189f", + "a87aa0644c8d5d63dcf15088fd12aeb70a9f51d14f2a0fc91b10f053f038a8b3", + "2c84ddbb9efa037a8cd79898a7cf6d7cd1d89eb284ac512a7b0361a67e9c0237", + "a057c14adc7e38f6e2604b98774f029a47131913bfed51752384e5d5d57ee701", + "c1d9993ddad3c943708050f25ad377449880860ec929b37147b9bb0ed2cd5ad7", + "539e5718ad9cd3cf892b80a37b036ce6e4e4e619c24fd14d8574a49af09fb31e", + "38d9050614f6cd34813e10e0f631a50e5084fbdde586a75613fa5bce9404e014", + "9b5e0cc504f45c88e3db19d7110ec69be0bb81802666dca7ea0070a8163ae9f7", + "c40061663479a01d0c658128cc9264e1d71b0841a3769529d2cb87f37c87d63b", + "26406e388ee7cddea7beedd4a8241f906a3122240d4dd3366d7c69879aeb922b", + "5b52cf146b27bde20a1c90eca7a40a83a9c0a8665302d2bfe2e6cb7e5f8fd6a5", + "6f8ea0e6afe60418733a3cb1ac3cb73104bbbcedecb131bcff1551f26569de46", + "bd5dc84ad0142859f2df327f6d7082635b10455da131a0e522552dc10126af6f", + "ac018494c4ed4ddce132e1cc2ff84a62d8f48bbcdf463f22dcaf3b154fe487ef", + "1033ecfe59699f34a33efadfa184973f2514db843df30ee48df81822c3830d32", + "bf85d087d6552544feb4cac033455123195879d0b8443e6546a021070436f461", + "375c2c2592ac6c167927c45b7819d7482d923c556b209dfc17a6dd2bfbbf3d38", + "72bda55655d0b082d7a5547744ef6317a769df83fb0605a4153d6911977c2108", + "5b7ad9e08206db0793f0304f252b053dbab0988f0e216004f6c9f4bffaf8f42b", + "ef3b5963020f9a4e4d4d6f68d45716906c070858581250883022d950a20e3c34", + "80a0ba0042ace34361b65e229238e89fe863c468f3ca6a1f279e807c905d1dd2", + "4acd7cf4140cb1d4a69b3707d274867de3d1ac89f19c1470e359601ba0fecf6f", + "353ceb5e08213b0b58829e4fb3ae35eee0ff244ef3094ad704a0b694c9d9b76e", + "ecf2726fefdcc42d28d2ac61c7698458728a7a3aae993dd9d1cbd7a10a96e7d8", + "f51d031cad0a6f2f8796855e34747e82c27153eee191ca9d862536bf70b186cf", + "f0b9c3b66eb37bdc5c239a40418d33e5e66d49786b5769fabd049b500151aab4", + "bd73898cf68b6f3a55d9ff4afc0f322cdff43e1c2752b56fd865525f4a28e564", + "0facdaa0da17fd7b91bc86bd9724178dfc1b90ffbdea90d5af56eec3b635a34b", + "8ddae7e303307f3073f34185eb6d31468f5642f2e77541fc61f0198c6b628f45", + "205d923689bbfbc6386afdab690537e1dfa2c92b031a1ab72ce204a016042c22", + "b98f2ca736e725ccd5114230af7cf6e111ce623f50bf266beabe9c7138f58130", + "74f81ce559d85c4ecaefd73f6e6538c450d910018975594a79fe5bdf96a0fbae", + "52faea2b90bb60bf08cfba71d8c661ac33c210c39f2f62f9ee1bf382f0bee1cf", + "5255d48b43d2a2ff29f598c5ffa8c57c9f2af2384b438b30b8e307fb06678f5a", + "0d0da14aa4483b9e4337ba811c556980738f0e5482d793e18c676d5789b5d546", + "04b78cded355966138cf6cb3e50ec0ef41ad1cd6b4902cc0653ec4ec2e63a632", + "329ec79b5db260771c4a3eae5ba13069030e415f0004b8d09bd56303e5ac14e7", + "5c0b533779f20c8980f49e74c22e0c0b0c3c93aa9dcee628e02d5879b726083d", + "5cdec084471962d220698766014d0d48c0f7c7a67d6cce1a5ce5450e160e5d1a", + "0c5e7b049cc3f5af8c4dad040f5ebbf69764925b3eea1f5699337fc18eb53bb0", + "681f5c96a70cb10063e507741485ad2119437589af54184d01e0b02df3977bd3", + "241ca2dda033fc827dd4096006c80cb4a3a5f62eac1d9024faa4d59130f8eb83", + "5f0df3a2ca58b447d1c12da3dffa31745ba062938a894fb32c8dbcca0eaf2371", + "0f04f14db45813be6042f4ba15d125b094a12a745ca513aa3dbf31898565ec3c", + "881709691cde9acbcdf50f8463f588e6d8e3b4b52eaf77a1a611c1a5389d948b", + "9f1fb7808299606b49224deed25b93973e82c078ca3976df72e3956c9acc7483", + "eb008399d4b2ba56bab93713cd88bdd26b0bed556c5de7a939e9e9557b95fc44", + "fe4934e053c44e63a79103b12f999f3dba7c0850a1fdf0dd43ce3a97bdac379e", + "71c2686857029c06ec75a8a2b50071fbb0bb0366e0b6c45131a70881ed7b2ec9", + "df63bbcaccb70d8b823b5256802bd7e13e726b7448e3354f51db3bdcc5c93837", + "eb266175d6d1dfaed9e06b7fb1ba0550a76e044756759db008fed6dd23b2d99b", + "88f6becb931d13725838baf586e17f74f2060c66b355af3b15ce69391651954f", + "8cb201fab5988cfab3f6c9fb5d68dffd08e8cb9679756c05b897956d8d3f5bf2", + "d4c6d44473a7a6efc3c0df54d1611ce10a14fccc1b18c367c3cca840c59b4e2d", + "85b255b8c54f1187abf5d62475d77d3912a87547156d61d7442c1fef26a09099", + "84c4bf0f6885c92bb32da95544d040d0626a24c960e9bc48ea098a30f49839d0", + "c045731b62b1d65311f3d650132de197bd3fb3f6dfc263d60db8ed6b12884646", + "92206078c9c0fcff3c917eb1c0fc8c7f69fa7b3ee46714ac0817fafdd467cbea", + "22ea5923c2ecdf0857963f0f6d5c874a0210d2e398ee6fe7ee78d7cbf741b122", + "a036974990c03622694e6d0bdd3db85b2222b122e7c53bb012fdbcb15c2c2a16", + "44be530e11dc151a21161803ad0affc3e800fa689f4930425b00e9b3b7722fa4", + "7166fc2af22acacceb10521332daed5276d84432bd5183badf0ac73116e9d27e", + "69ffd9d3e8352e0de7c95db02aedd3196888c7a0b7caf26e8d4924db5e277251", + "0c4d0c5bf56fefa901f0156ef5cfd304f1310180552b8c66fdb6effac4009256", + "277c16d7a4befa64b372667076abf20ccd11df9c7088477d45051ed104e95960", + "d265acdc2bd76f89c96adc44b31134564fb76ae6ddbb1fe1f1ffb633d947e3df", + "ca76b70475156a1acfac503ecdfedd779d7df2f1563bef3c534074870f7d0659", + "809cc9d915338dc6353f8fd8a11b6c1582ec4b665da4b37c29faa7583b33b2e0", + "56f4211c2ac50ac59c042a9a0efa6951eae1ed8815ca73cb4eb3a7237539fbf8", + "402a5dc120d775931738a3154927a5d5f0400a2c4d4bbf3193436ae98a2f0a2b", + "e58165ba8065b44dcf61165e4ec1bc4bf45390366aba13bd8078e58798cc25b2", + "68bb2aa5928d53e4c3f9d237d16ff845e9c0cb40b08e2c86e677021ca93f8159", + "04a2d9f174abfb6fcb5437f6c0678d959fb6ed62eabd740baee630a8d33b3bfb", + "40e9cba5d8484fa0b1b206deba9a7156f7d2f82e56a4100a8d346a486bce3559", + "3f00717a70df1798ca7d20f71bcd519f34f12697851a5120c14d4815c08b415f", + "4c8710c23532a4d4a116e591e0b5a6cb494cab93144851171261d6e2b8659516", + "7055d505330e13cef7a1e03f28212c2fcb4f25ecd478d7d8ca6caee0ac4c78b6", + "1f529399032382a8edea7cf53f2417096cd478078a91e8a342d9b27aeb186cca", + "05855b4bd9ac8afc4a9091f70da199ed4a818dae9e594be96acbec778a919bcd", + "06df93c067b175b468ff149e975353b41703dd2381bfb4b8184e60dfc80c7a3e", + "0e494efd6d370e2ff9cea297527ce3c7611ffe9c50d1d4fcb25b7342dd7d47e3", + "37c7f666716871ac5a3f349922026bfb5fa93ea28814adc4bbd9aed7ca2d8464", + "6e768b54286758b94dcbe878547e1a77c383f0c39c7c8346f85067f537bf23f6", + "8b5660cd070d5f396aa8ecd6ebea6afaa957fcfcfa6698fbecd43bcf28c3acf4", + "3605d5f9ed41fc3f9ca8258772511dc643b232a10914ccfc47296a61e569ebac", + "e0df7faec7b03a89faefae1c87451901dde0a9a509342b1d156b57b4181adf88", + "a94f7e7461941846707a56c3bed4b6ffb47ff7c30be1fb230b2a2796191b4a27", + "613c29600fe8ec006e5fcd2e83f3833944b0fb76750874aa31d3d4d8a89a4c02", + "d7e2686622d7e7c1c7e0fe3b4bc894213139a131867caaea33ef1a32d7cef3a0", + "63aff873bc5b09c62406d9f5d54ea6f6e8e915ed8a2250060a8391213f37010e", + "4d2369afab6d72a989297df3da601d382395e3cd45f7f877f22bcb26e3478e13", + "c928ce3a521d6a2ca31bf34bf238fb8736d5b4189d97342213f3f08d6d27f0f9", + "ccf300393f525f376499b93ef4addf1926127f146bef06d2df223bbe957df29a", + "5c3c52ee21048e61538e1ef0f0045b9d1f38b8ace8c5c056dce4d7de772d7033", + "67e1f4564203f4a60fc3f0e347977f4a68d3a2427d471c5fc7b40bb3742ba81b", + "659f2794644c103e210d0776a29122953ff95f95dd712a260d2ac0d271d4dfe1", + "d033363c4352ff6f40f2a5fd417ef1d3b2b1d076db2c4ea748e6638879e3353b", + "c9b9dc58d13c8fb665356a80a7006546409e78ef6a18eeaad334f6d8fa033a8b", + "2ca3579740df55d1d979f23e97992156fd8a9e60e4e1079edd5706ac87d1f2c4", + "0e9c7dc9705d93f1af800f1f58a0dc87f9c66a6a6e7e8c8bd3b5c44637f1a91a", + "52c55ed46912f34b32fd69c23588251246291835c39e24f4f2bc5b5652415684", + "48063c3856ec54e1a0e76713819785777bf8ee38f74f1279dec00318ae0e4e57", + "fae76c7ba81ba7cb89bfdd09f9a12531fee55940138b276d48018673a8328797", + "f2952105e0a085145119b9b5422ac4dfee7f318ac5ea3b920c98337c8b692ec5", + "6995e503fb2fe40d7d5d6787efe7fffa33e49ce7b26b971b038ac51bbdf7aa50", + "080e544e4cef69d8e3a2a05059fd79d7d30eaad01a9f4a23831cdbcdae039094", + "3d06d8e8d8b93a819373dbdf02309e02861708f98e0e65f6c29f8c4c86066c92", + "85f9526c34b3c2d7a7e7af67f19437b949339110d47b816d9277803ddcfe9138", + "6cffc4ea89036aeb2151dd7c0b84a610aa2d57e3bdfd2668d3c0ce9b91d78230", + "8d443803dc8b55084deed64f2f3fb929efc8055fa627ed8a721deb5ac6b520cb", + "2ca15075dd0251eb919771366899820f6a57d4daf2d90f87c3c2a3d9151e2b82", + "71363f46457aa1f5d78056fa49f98ceb155d0646f3aebcb54da1a9dcad162f9a", + "7576fc5ed77bab692ae406fc229affed2591fe18c560d59c61c7ace6511b17bb", + "a0f7afd10c3f897e524d810fb2108cdeb81644a9c56d5af8cdd7f9733250e643", + "ac6eb73b34af46cde6f5128d912e9a976671e1039ec442bce3387795f531355a", + "8630c1d3d93199d422eaceca632b04139af6bdd52ef3f9b1f1006b8e37694c46", + "7895bb925d4600e269e2bde3e263f2a5aad2f62a96631f80c3e051b61617240a", + "ae664db134fb562f34021f5449a241ba2d1c0859fa8a82ec13bddc376abbc7ae", + "de33fe17defc277b8aab8e1fad9c023749815f105e2e0afdfeb63e279ff6066f", + "dbac4dd87f7f5ba0f1810ac8e88df7fc5704e9ce11b283d256633417df115680", + "8c20d4e507054385a30a6d88bb6d9da2c4804ef97b12617ad48dffc50d43d01d", + "b3e4641eed0b67dd9a6e054f657475811582e759e18593edfe8f2c2c5fae24ac", + "a180fd127d25d3b55ef79dfded04d1febb71cf9e194864014b5baa471f1b884e", + "66bdf1783452dad4e6276315b4f4ee7a6964e4f12e0a4e858deccf350631ff84", + "d9aed41164f709b77d9c6ac340960a730e31ca550f831862c9b073827a7d1dc3", + "46ed59c7c5dcdaaf813b9d58e965964fea72f34ea322ab0cb398531457b1d4c4", + "48b5de5b84483665367c0a7b7f020cdfbcb28b5a9e59fc9cedf059540a91ed34", + "857f32bc83bdac9981397b06afce6189b6271dd14a37a537dfac164adeaadbf8", + "9afd5c151b1ce80f5ff4a0fc912f8fe1043a9a3e24e7ad6611902946c362d03b", + "72b08cc33b57fb5c7f8f47ba00d3bf665ea474e652ae006dd0818d788fe6dac5", + "884ba72a78b9761f53e92209c3128c07744cb3c4b0d7d7824e1fe1695eb31388", + "b8ed0fb86dc805037c2f00c7748c0fc15ce3c4e6cd000cd6d8c81e1e8bd3b01f", + "efb2c7e852958a662c03f97a89c177353217790c725422cc9e16077717f6a6f6", + "686676d749a610f6a85d02770e61d1553ebbed44d159500cb28906baedbc7305", + "be6bc20f4181f0710f3c70e146a4bd0613952245c5eb866afab8e3913b151936", + "9baa600a597e575f1061f6ba6d4bd6c48e6ae774355dcb61db7aef4029539bd1", + "a7d4b53283b1a418d7924c1e215b1ba9334cdb1d5e3ba14d9458d421325a3117", + "cda885eda6994df15dc3b3671ba171db977252fccc6ed92a3f96a49df92401f6", + "10d2e19c3be88a47935bd3dd139b15625f5f4b2cdc1a2fa38e6d8b1df0e4c32f", + "74e67fd555f87feda80cf505c1b99d10a18e5ed55e2bc5a5967d4ac19f3981cb", + "f2bfe53fcc7e32e2ba5fc89d041467dff66851eb549c297e5c180d812799a1cb", + "80e1309db5e15f1a7ed9ea1a280e2e63fd1718357923126368bae9e2cd8f6fd8", + "92397122272b511c444c76b27c3d3366ec03efdbd1fddf94268008adb640251d", + "371b2756dccc73392ce8d541480854646046973c1665e565f76d9229b8f9b8bf", + "bb99a848034486c01e64094257389f218ab6983837d2ef14bbb4d7772b0f3852", + "33906b48b7c44182c18e1fb6b36f012e7f85bd80be00b49d65b05f9bd2b82eed", + "97c079d2671f6a27b13b6ad7c8687c448a8dc3cbeab86cfe9349c74483bc96dc", + "d610a948f27510c4640bd44c796f9cff40000bfc37ec378889675d39424c3bbb", + "3f91baca5288ca0c9b82b3747cde20924b7aa26757df8780a130d0a57e18c250", + "e11ffb7bd402af49f1374cf523e2b3d52ca070d8842d8434b4be909e5a139f82", + "90fb0c79c20d21f9ed493fc97dfbf749e4526b4a53a7f71e0030726d26c230b5", + "b12debba623a6ad171e9af815c4c5631d1536900b7febf0a813b84ae038ab865", + "3728ac2ef1a865358881ed6744c91faf120513c5966182e328a1b8d7d07b1a72", + "ea20dd790be626a5324a4031648cffc00aaf5fffd6b8814a5a51994c4d73f8ff", + "fa3bd6e6d5d918ccf2d00ca52f734878b90679a44617b981d720e6bf619999b6", + "38ca57540d0468bbe572b3031344824210d25b78b487b6d5b5139de445220e0e", + "5a985a8afbd634fc590fb20d2c1186b1497fca896f2c4beee3f255f39fe5dcae", + "5610a3ca1d2c566665133f4993287e7e40ef4916cf23313a7ea8af0f17d70cb3", + "f1b104587bbcce4a9eed7e5053255149cade9cb530d640fcd4bc9d6277f2f35d", + "579c6bafa5097a529758b8deca97d7c7f5379db8fcb80204bf009077df2ba1ee", + "c745e7adc6c5a2e941ef39d899bd6550c3a6b4479f9d914098028a378b7bd318", + "fe394fefeea153052ff0add2029c8ba3a7f92564e7e926d9a7e5045549dfe31e", + "1c1ba94e377aaed65d4f500adf260907d84ca92ed492aee2e35b4df8dfc3d189", + "9ede36026646e85a9a82f288832328d1eccfbb3713625908e97e4079a64b9e68", + "77cd2943b2cbc3b6606fb55bc1b8f982b847ec125a845fac5bdb62e321b167fa", + "bc16fc9c110ac1222c3061b46c2169595381c00aea6b3ef3b137315724a2f5b5", + "6dd95d2415ba19c1735685333db62551ad15ae74266799359533ac77e79bc4f5", + "0aa9e1a753cbdf96d93aa6755613e513ef393fc7644ae62182e5a702b86b75f3", + "b9a9a8882e946014763f092ff3785fe0e1e6a6000573743464149c89e2809557", + "cb8482adb4e03a3786e104c22b25a6d7a0fb938e4985f0cc3bb4407d093a367c", + "5d2d9a9a101a3fbdd53a7ae6e27ec687cb4be5e700d323cc674b4bc54ad70507", + "ffe2bfdde52860ebdaf1db3a6c702096f25de177ca1a9b590fa02a331880b726", + "3785024bd6030c887b2987946587bced27b431662184be9a6952a00f44dbae32", + "96208491dd1bec1220e93325dd94779c857f0ad182f3ee04f1d5ff468b132302", + "65d9778726adfe07392fe7540e4d6bb79c3208b1417a78f2b09bb9946e12841e", + "8b17a35b16e82f64fc150c8e8f8ca6a4d7f66dc8ccfa352ab2bec067019233e7", + "0b4d26a7a284afd46eea82b054df27dfa96d34fc78432fbc81109a18fbf64751", + "6bd8131850c450242eeb13fb4ead24483e3d3dca5e5c58dd835b012d93a00c98", + "527d4d9880c6afe13f62950ad38c7ff40cc7fb9a5a1003f50831886d31c8de1c", + "0f010d43359bd0c55a087ee1db7d32767f0173c0bab3cc76c1d27f04ce3e4cd0", + "77c993f50c2c28f4de722123e7d4849b6c5f9636b41eaabe6507acf02c00988c", + "8bd33a241dab237954918b7e7027bd866fc73c2194666f24851a620f87172db5", + "2af15afd53fc9396cc69e073358804d19927d16e4ed723688248f47329c0f4ad", + "0b87c3590259be9fbbaf32ae46ac72cd24c9279964e2c2c84f24f5055cb584c6", + "55d5e95591583c5221b5fd141f95591e37155c146616b5f55d83d36c6c21351b", + "f36fb87e51aa04a989245c1d28a9f5bcf0574ae6ccc803facfaa6cadcfceabcf", + "9fa54ec341aafea22ae37182ac5082c3d8e765ce26b42a752781cf8853526b88", + "a577b05f724b2245fb5a37cd8d2464e027722743b0458825f52573b441a62f68", + "951ef13fab5b52db8944daa960becb7a75bd92489418bb5e5d3a5c0de5914357", + "f10dae7b117ede83a8d833f59e255cb2fd13795c15536c38352ac16937b2244f", + "042c44443b404342b9fb9862968629eff2c3f3cd86f526b6dd67ca5cd68984dc", + "d731326a3e1d35251f33310fab5207e35f6ea27acddc968bf6513d53fb1c980b", + "d8baed26f945b7e6d6471c22bda715c0598b4e0c651d7a72c98d40a721227586", + "229d4180f40459f79035865704e895fe061c85c772b574b4d982c40108effbe0", + "98f19b1e748a350894d3a78488b59aff95f610fd944f00c8045ec1da8187717f", + "9bbe6e9e5d596b5e58cdfd849f9db72b24f26e0e69492b3312a6f4a165d6c83b", + "8799d85f019adb9bc98c94a58d21c3fec06394d2f5cd2021f7634e410b2625f5", + "45255a35c7078aa19d3a277d03ff9f9a4835b3eee62d6cd674a44e9a7842d77c", + "c73a1e1975cb172ffe9d4800a6819d443c0f50b3e805bc0fbd4e7f43e350244f", + "974da57153995252f5cebef911b86c700a2986b7ca4e5ef80ea81eb8f00f6325", + "7170456c53fe203b1d319ddcb0756ec847841f2beff0779e62b4eb2a1616e78d", + "2cebb4962cd4de8aa1c416fa751317b503556bfcc1aa418b824573dcbc937a15", + "80b3f359c05101e9232c127c9e0f9a6037b67a4c60423ddf0d88fa3f746aaca2", + "224f0129a9e6a67b07fdc9e131c93857da91feb96e337fe0225b7f9a5f8ff76a", + "a1cc98cead4daf26f3306458db423528d1644bb8214e629d76e87d126670d616", + "499a74f1ee134f6b11217cbc6d9c60cdb6829089033722720d1b125167a1fc2f", + "f8acbe69bea6cf0cfcaf32f8d994bca48599cff4a62abfa45494ef4cdaf92053", + "8d5c0ed670255016fbd5757de8c2952ac99afac4642e02e74c60f0e422d5373d", + "f9d3e6d9b35bfefd6f04cbd46f415619894536afcd7674537f6c47ab38936241", + "4b7e7a39f7d0ea0307961c2465bb1b5ab7c743b22fe0bd414a67dff33929d6b3", + "12bf40dbaeed1683f75413c9df998ecfa99d8e489d78afbab37ddc035afd5dbd", + "a4f3dbe71fd9f37066b059dc69740c9d323b80ad5d8400db8a18f82e5050ffd6", + "b090a9227f5af6426550617e19eb91c85b8605a4b3978724cce12d6a4e907019", + "e896b40eda699d92c81400e239c85e7ba1d6c91ecd0c710ad4b68cb199cc3f9f", + "ef01c40a0bff0a5a3cd5b0c673a3dffba9fd8c876568c9eb146963fb000a7c60", + "239ca4ce3543367c1cb5e6597a5ca9909d92fc923f239ecc6bc9dd4ef9e58330", + "7c49718e66e695070d8a337d0ce46a0cb2f9f499ccdbb4068485349efcee34aa", + "9501f1ef00e2c47a87f70daee062d9c1b085f7fd6e84877db647f71a52e050cb", + "73615a8a6cdd4a4b74f58211e68210f873d736987c9baf82e7e512e1524e0a27", + "0c83b69f01fdfaee8304e13ff0614c86a3d383a21c68aa2f92322e3d8015bfc4", + "3aa14df6372661c89f06f84f7948f456359f09120414f0514f1235d1b6e37672", + "2fc894945a6a48d15f47a3ba574f11ec4f6069506ad08e36b59204e0d2fdddfd", + "3f59418559171335bd60447f1346e1198de873842cf620cf8d3336914b0f9678", + "be612e04b23e3bebc328fa00013fb77e724b191d9b4081f9ccffd9d4bc6b4edb", + "127844e0ee9c1193653c3994327c4290f01f31a2f593fe097984a57c9313a516", + "e38767a714537b0792575ef2ff8b84f8b830c3db66b0fde20ecb998adcbc941b", + "a0c0ecf9dc60b67dcc746935c01d4041cf70081fe3259620478a96decb37b18d", + "d38b8ee756c98c391187c6c813c55660ff44c9c387aeb6e56cafa25ac0b9c44e", + "ab32dea1b1b1f116c315001da952e8eebe7025739f55f44e3e16151e4368c37b", + "b194bf52f751764bdc89434ee591435eae841606ad1eadc4f964970c964d00ec", + "3020f6ca0e4d0d1b57131f4a1ac3ccf7f88bd9fd33724dfaa28387b4389f82bd", + "a76bec6953350e80b8877fbb4a1792b404ea691697191c2b4192359457136146", + "ff9b3725133bdd6c26742aa121be7b377459c8f2c3921727364a7cb918e23987", + "65e28463aee2c7348247af6b03d2e5844c5f7245a2022c7dba191ebb145f7f34", + "c3879352317cd5e9822f05208eda303f7b79dd5016d477e4dd09347574a637ec", + "627e0331ea69b1d3f7b737416b5902687659d3c85470f679a2cccb4027333198", + "e7fc02428fb6ef3c91252915159463c43dd568fa6c904a969994891ef99712ce", + "bb0003c4d7394d15011cae446d91162d391f57c445734d6b73977e5353e7f70b", + "503d1a3e1429107eca1c1f36f7818d0a81d26be757c8e5d6039cb20d7ebd7fd4", + "3c7b7b04fe590abcc60e80cb5738037c44db78ef802de8f1167bb145ca871ba1", + "97f3da5dedadbc14649d06749e5b87093f6f59bbbac9769d1e601afa2ead742c", + "77ff68679e5fa3e21687168ed366b2c16bc860e8843d027ad2a9311b350ef0bd", + "208a6bdf854fc2e586a5a04fddcb534369dd1297aa374a131cbe9771dece7583", + "5f3ad06ee9f0bc39a87697f6b47f983f7ae855b3a328b6aefe607c80901ef1b6", + "55c9abce7168a0652e0e32452fd0e63117b730705b4b14e850f23c7b7ead831e", + "676a952a68274e78578819dd276de8de2b7f0b294153fb7c80db27ceb0820a3d", + "80ae72bc6495bd5d3c5ccf04d3707ad28f8b8cd4429c6f79414260afb1d631f6", + "0c71d9785b9a405c88b373edd51ba9c04a1dd29608363232149c7d570c85f169", + "d3b76da901cb2ce23845943a56ddde61c7edd1f8ae37672429623b4ba66770d4", + "69d9142b7a5b6239dec908c312a3ac0cc66e7b15a3a6daa38a62b89a19b627a7", + "e7c81cf8f73b053804f285fcb8f90f4dcda9de766a3fc266266c74df2c4f6e3f", + "30e314395c2c25d8bf59e4deba866028f5bafd5029a74b39c41c798a01c395a5", + "9975e09f07c0420a1b0321fd888c66c864c3121874a8ab2c4d68c635241bea35", + "3743ac841f5c00e05e24b3d4fab672ac275fa8c66d1d06e41d15655f02f54248", + "10168ed4338085181396e20386d44e0f97f312ad6394f046e0ff022ab1292b3b", + "db5827b9e5b9f2f6813d9aa5f73daf68fb3ed3350dae866198841bdf0cfb5857", + "b5a0955838b8621a4155e85d92bc5fbe2fa589378e78bdb9e2fc8af37e177c45", + "55abf44ef3ba849eb3dc8be4f6a3be0d4119b667a0dfdd90abc5efadd18829e8", + "c6d7a12ceb6c51e70643147baa77739dc288bb2bb23be7600c3b3b023dafdd54", + "672a68e0b7287261338f0779209b8a12b6575f385d41bddf5a266b7cabe9ab89", + "d03f6c9e80d4086bcad541fc1e569d1d7f56d28a021d34a2071e29e70f4829e2", + "95ac232ba744fb03dc1d1996f60f12db83405383a0ea9bf3cadab88ec75485ec", + "f7664bac9c66b1efccde280147ccc07a2063da8289ed546251d92ba12a748d9b", + "51b76c92b8e1adceee43f151e30f69e8e560b0c73633afa7cf364d99abef842d", + "0e8d17cac8e2e6515d09c97ff6b275f497b77a1574b828195ed475efe24ea5a0", + "a4bac595b594a2d2859b8bd0e4a28e7dea5dfd3dc4cfcbd9254772fbfdee63b6", + "c32dccfa201e6ce63f7eae9e05921be5851b62f84cc9ec3450359da854a137c9", + "ddb5b0056a2fc460cf1dc0872e894cb2295fd21ed15435311b7eb4eafdcf6fb3", + "0df616aa20275ecbef13bbd4e2f30463860558c61bca6436973ca4079296a58a", + "a9dfa5966546ecf873e2f972ddf9399148577c386be0d808e667c491d01f653f", + "725dd3ea7a15c49e2d08056d1281bc3dbbc5f52ea97c40c771abec17b180828c", + "55dbb4afd60700caa0bcf90dc85997761d595191b4b47e20800703e6bbb696d6", + "e4a76ede2026b12e44f96adec4594e7f957496b3f43b85e515c65b8ff5a1e6c3", + "7c6e277e33c75bda6c62ccf51013075edda42e64134d79a86143fe93b2ec29c6", + "181fedc45c15b4cec491548f23cb828960e8b2a49b7759aba6f761903bc072ae", + "5f1718293727880d7863b1036cb51bbab6c2665644ebd953ba9413606b4a53f6", + "7711cb5058b4eadd80edef27af4c55f2d46845c3b5874fb31faf043774f72c34", + "381f59ed4ee45b8eaedb7e279ba77cc62feb0ba6e1fc95606393506622c1cb19", + "83bbcf83a5373947e9b8b1a6f33efa38714d6e6a928345b154540b65fd734bfa", + "34cc3864c3341a58daeefc85fca52dc2fa21ef06af411ee1ccf865f4a9e24ebc", + "0e9391a7ae7306d31883a7b59dc4540f4db75cec2243f9a8d87a56ea74de4f4d", + "6a830a039281407ccf5d80fb130dbaf2c5ea378e690e6bc1aa029ebdf0108973", + "c3ad42c4ecb799081c0852f1c6c0c7eca23996fc1b175195963c1270d901d533", + "4d13471b6e4fcae030c26ae0f558b87dc63dd99505de47cbed4f5192e31b0fb3", + "54ce77bde85b160645819313deaa63966c6e8b1456642f63543b8cf92f7a8ce4", + "482fae7d2b747f5c5d54aff040beae18cdcb8727fca4c8ad59fc652b09231abe", + "d2ebd51897fb742ff16c6d544303495201e170debb111570e077741d8c2f5b38", + "77ee6b6b91f9127d33ac58a74685195c5117c545114673e4649de4fd7377c7ff", + "4cb5df5666edb153c542953c7ec1d699a0265e7f4ef3951853928d194e168c8f", + "30cb9a8310d3570bba9b0869bc40f80058006a554fa70ba9fc733c87c5faa4b2", + "4d4ad00e5524bec2a990994a140041c3f1d571a892ca338a4a60493ea47a80e1", + "3342342e75a16c0d173686772254e47d6e7bd1823957c8ce0355bf5cad26c85f", + "379a3a73a32b94aff030f54927a5d5f777b718932809191983bc07317588cb89", + "5332db62664bca77db656e591d3cb1ef39030b11d3b477070f631836c98b59ff", + "f23fea13e9fed9c2f26f6097428feb22f59076a3ca58456210d20e03226e5bf2", + "e82dae8425762f0640b78ae1e500e7a77f933cb55fd731977ed24333ffb87c0b", + "d43cba34649576ce4d46376ba055459d6570685268ea0d2505e93c2f707c474f", + "7ed7b142d22a4be5c7426b18110d74cb64a09134fc4a56b8fac4344b465386ba", + "36ab48c833d8fc3e806987ebaa99c9c43fe5679432441ebf4a85c9c90c388181", + "3059fefd863a3a30a379d2474e0ff8a93f1171ed7b5b2c628f25892be36ccd3c", + "2277c29ef61df1280b84379541783d47771aa8cdbb667c5cc5132764d67cde16", + "0a4f6fb648202dc672ecace9d57c17fceeeb32a48487c58f0dc28d25b6711358", + "62429bf40466bf74093d7f1c5d77ebd1f3d4cceddc113e514ad2f556157c63a4", + "8de7988f783c080c7cb5b5406573a3a3510608e72c04a63e6227360f84280edc", + "33a38a090fdfaf0230fb3e6c74718032f7db77280bba2e24045d70d7087e9656", + "f3de535a098df38a4af811f8da859447f27ebe93a564547f809809aa7e21dcfb", + "535480e6e2883510746042d74c30e4a3b1f26d54d3c76e25993d3a2bd1252f9e", + "2194cc5a471e4825dd68315604dd7a15b73d79a0672f3349961a5c597b234811", + "451365dc9da0243457f9a247815056a2a204095267c946018598c8d7cc58174d", + "667f7dd15be6c8f7bf2c5986594b442576f18730e0705588bdad7b46655586b3", + "84c120fd1f4f99f68d96dc97bfc3c99a65c99225df58ef62f06e5e85cf0fdfa9", + "f6809f56f59f8d6bbe246d043564fd62a4af36cc85fbf43e334fa3990e7effe6", + "ab425b61c1ad5bb560382ee8928c3b47b08cfa41cf1227c25a5086bfd8ef85bc", + "161bf232b0acb908f47e7bc169a103abfd9f96891f0efa4364185c9448717f5d", + "7dcd59103b6eae8d6a96cd14bc496c38bf560b8b521088c50fb106fe763658bc", + "a4a5166f35beeec1ba7876a83892450856e37864d7936cdd7fc40d4583620f7f", + "1f260dd5a676aeb190e645f666da357debaa9b834330525cee2958a3220c223e", + "b89929b99d649d9034bdd2dd95cce7a3acfa0996140a034b50a13664105c9054", + "a35dd5c81acc39cc0a738da5fced9418d6935998eb1af5e9f4a1bc40bbec29db", + "8e69b78ec75bee0d3d00c7b4f4de868cc5e2470e5369b79a272647adc9241dcd", + "e890adb8a032f424eff949f89bc622ba8bcdb8974fcfe5630e8fd83893a2ca37", + "205f9b8c9555180dd23d20015e2b70dd9a29e2cfa15786f669f29dcbac6338ab", + "947ce09b396c0a873afbdb6ab691f631e885bb4a46e946b97660e78b6217e3a3", + "e607119df5855df9093b4822a1c5a2003f88d9f70173efe2fd53105958746659", + "46c11a200fd99aba677696839e1d5a2bc9068aec7c8e7826924b4d3ad16fb69c", + "f62e63aca522059b05d74ded9920c7d4c45b933b28f1085990a71c80a7f0e6cc", + "50991baf5e14d897df5c98a53537496046ba11849558520837161cf4097bf38a", + "23a121dadecf6326c0cfbf342809653eef019bd081fe0662997883c8c6a0508c", + "882594eb6467fee0c876552c9e1c1e22338db1b67767eadfae630c28155d4815", + "6c0c262f6bbb0e3ddb19e6181c5d5a0105f79932c62e6a65466ef6bebb1f7ce2", + "2ea3c3a96a74f0af6ff24b65a83707caf496e8503dcbc45de4a4d392eb4b853d", + "9d6d1222003866d2baab0523237df0212bca026e522ea261f3fc6722edfe9dea", + "e80b603cd1d8684079163522d105c0e5b8972fd25590da7018af4024239327c5", + "078cbbf6e5e730d6d2d5db332bec6b87f88f1e09e1064b079eadbb678189746f", + "99316abf2fee4cdc0106215efe94e129e161dadfc7fec486131f7237d8051b26", + "6df59db2dde2d63d2b1e86a3bf12936301ef5176191366f406c3a67ac6b1199b", + "427f347cb09dfeac2a5f810c12cac528510803f6cfc2b2e3a772b033e2c7a9cc", + "b8f494f52aa7116063420bffce86173a513fec3bfc5076da60e60129a11c2fec", + "2fecf2de585c1dd4e65a10f8a8666a2cf5b1e028dc10060c458bd2c42bf0820b", + "d582d6b8ae49913580aebcd46c1be90410e70e8caa05d1f311ff7f29a8efc2f4", + "345d635e00ee45e58ff67ea70c741079416ab7309e4298ab17a21d25f28973c7", + "acc6b1d6d409e6d6f1f01f48db133893a627d27a9046f605749c90b041265f93", + "cd8b36b64b43df5c4498b4683776929e6c2d4cd4aa81ae05e51b32c3887af278", + "9370d1c223c02ed70b77ac927c5eb6c461e753476c4a87a0cde18ef2238bc4b2", + "9507fab2343004177a7aea45814a9c182c4f4b3b120d3360cb9b71a67e6afabc", + "63ba5baf0d96f9d0030bcdf780ea37ef60c040955999177bd9412387d4ed8aba", + "1645513a81bb967f7c3018ad9621250088a5af894cf3642bcdf64bfdbd5c0701", + "f8784491db54ef0b196ddf628bd218c596ba5752fac4d251196596d0cdb0cd49", + "7946a0706fe1392b29ba24572f0bb5490498c2a7df52f79aa8efccde7c4b5ad2", + "696512bf7e0ed6586b50a6912e779a1e333c538b80e30582737a207a17277260", + "3f273dee6edc83f4deaf04207f784d1ed434d5089e19a7c0035fa98b0e79c996", + "ef395d7941878b3f0a3c466367026df1d1655509d55baf37ae8b7fe6279d1909", + "a9d5879e6a37132842ab26e94db14b202031293e8d862ac1906241de201de619", + "4513bdf0a831961cbcaa732e20a040d286a5ee794379718a693afcebd51a328b", + "d2ecd790874055957d324e10079e10a96ce15d5e7b2b1cc4c2da552f9643a6e5", + "bad58e8a0599b147d09ea9f68e115deaba699a7db38aba2b54de2d6d3e8edf4f", + "e1e77559e97608a6a74402ea8a0a643282e4fa01ea2f32dd4837eb43b5c3c092", + "a2a5eca03bef1f466431307a8338a92c5671793a6ccb89f02acca9091e456732", + "f3997d12d2a3518353f858b65f1ee294f0b86fd533a89f6f0ffd0e23fc965caf", + "61ac9693ecc378b64d49cfae77e5b5113567125740d62d79deaea323bd01e3ba", + "fde2bd600b2866fbb79e592d0ecd6a9e12779bbd023232d5398a4edad362a43d", + "e73f061187ead37b13923541dcf6d07970af91753050c95f4118881057360d98", + "35b57a35a0da75efbac874e0a16a386fcbd40d7c1c162115cfd33d8468114144", + "06c8f07598991470787aec1c5be6e0807e43516718c64b42aead21da55f08131", + "c91b186ac9b7f13fbdba231b14e86a6a7c6f8fc46784e68a541c10a1e017daea", + "386701553fba7b6cacea17fa86c3e8a33f80a1a08100def0117089671254de59", + "2c51abe182719cb26788afd7598f3549d64f19211db9d4084c4eb7eb0db8fc6e", + "58c770b1928621265903db1079ac2e3b74bd0e7ddcced3e9b76c23b718861184", + "f2c99445ceb220d87fffc38175cba30f5d2f931fa2951a0d3be8521629f37e12", + "a919c9ceabf98d56cbc73d0b7082803123a10c944ac43532415361bd0eb8d53f", + "f1e6a768823ce9f1ba74a1e8ed7702bcd39608335d56f3a27b89b660ec05df0b", + "aee19f4651db458dfcfecd0ed1b6201d838bc138bc48333dfd3bf1022ecff9b8", + "edc321e53ac6b5de40c2c4036b045641203876cd99280dd2f49541aa275a695f", + "7ba845dd85b51af3dc1dedd1dc4886ebb600da40be0d835c03fda21f4c3add4d", + "70bf9bb66262b300be0261f8ffe648bcd4bb89cb5d7fd649dbd1dc1254c577ee", + "d5dad475f61b530591481a340bf362b959faac8578d603e8807efe4d072b486b", + "2f7c9a9477a4d53d6115519e700b084c906f64085b47ad69da13bf356ef9808b", + "941879aa2f4354d61634d0edf270e792ae07f2c5691b86b08fafb922d02a6439", + "c73348a38fae75fbfa8d7f79504a299f10247bf9ee10633be0b62aa5da93725d", + "52b1f3e7539f12063504322a3cef786fc3c14f98a4cad86a5bdd69f268d302b9", + "1964c1cbc2f14e9591f62f5ed06787209eb2814a84b7a9c205217a820b5bab76", + "11938ec10f71a2ccafa5cecc83d1a1ad7f0d53107869d79fc20e9fae68ce9c89", + "2bcbbb06dad060a118efd746bc3463d401542b939079bc26acf1f5aa81249352", + "831afa34d89f0e134fdc440c9bdfed216be5cfc8b6797598a07841b94902ed8f", + "f07f013929bc9234e49b53eefad7a4d7d86e14f15d6670b66c6a06da29eccf3d", + "23eaaea1e863d42195e197343302a8d63430759eb8e70bd5d8347f8993d960f2", + "cf382f00ef6312fe97b8e6c66d96e1823e35f227af81e6a2f53ab7b37588a403", + "03655f97cf3cc1ddac524590e1800762348749b71566ca46c9211b27e3458d50", + "b576768147735d2665490b94b08d4599329cda0cf33bea22322eda9115aeb22d", + "f9fd72cc1484191afe8bc998e76edd6dd1363a08d212b11170652275f2b56d3b", + "b3ab284a1c8588c0e1a2deddf31d15f2b8571dd259c8873b448f5306a664172b", + "26414538d7bbca219a0c65614c94eb8c4ba7736ded67e96ff57de5b916237be7", + "4ec0ca81c7bd3397814b316ab2b3667bc0e53ffc0c45186499dd56164321e433", + "5e0ec7b2ea63f30b8f23673335282e7e069c88912a56b229a0771858049550a3", + "65ffd2a1aefb23d774a07c798ee686a356a05c47f78b8b88dcae0e2ee11a6298", + "8c0433738fe9162ad1afff18f8374526461365a60c48698815458d8e0dc423af", + "607e78b47f91b75a88af13d8ce83b12042537eb31fae301402fd6117b973aaa3", + "5686c81a793e7981756af8de6af910028800a57949ac5c7c9339f719a917ad60", + "3b37c9de3e3e751700981786d7e10f2711d498eda02bd510e20e48c95c8309aa", + "344920a5b2b29e986a46d1048c4a1c90ec1b0e5597e170a2caba3bc6c723cfe5", + "6c5be1ff205d40eea5e0b04b52aa1ab6015b2b9a5dd102831fa1ebb4d02eebc6", + "345b56072efc2da85b0738a51f916dec51a1174d16b7c90357f55782294f8c86", + "c2cd7d7a03c370985bdac2c261c75a640c7d955a5552b8b3e6c6151ae839ca00", + "c8321694d78a659ac6aafd9c12ed859e74ba50476075b2324bf67f513dd9f9d1", + "b596538086869bf3e8bfbd96185f7a48fd85f16dcb377b51bb0a4ce73f4f4ba1", + "31bc6535ca209e2e3567a42eca9434c6b08bdc161ac8ad0e3c5f45ccbdffb309", + "c8b1dcfb01a1b439acc186f6d5c158ef13e0507278095a3794dd3197cea94a9c", + "dfdf30e66f50c7beb673f8dc4ec437119ed9c2b5faf96ecc5913b27b570b7c04", + "817fbfa72cd34da2c46972812ab9a7c18df5232782cc316d4f906a063f2696f3", + "2fc60536f916179e8762f42ab628cad7ea35fcaf6859ae2c87a1333db79b9d72", + "7df34638e0fb9cbf3fa7cda1f7fae2616a86b51cb0258d46b5d0296e51590845", + "5b05e592a10f1517ac3d5e063db2ca667e3cd8388a30d0aad3ed29f322415318", + "c82ce9bc6cc044a3857ff73a01d4a54758446c5aee99f1c37078d3bf36b197dd", + "81bca40fa3a050a302470eb6c40071aa621d1b008cab16fedc072461d86fd4b7", + "b78ebea7ab8d01b33094f868e693af2eb8b693dabd1167e9476429d48b41baaf", + "b45ed1233445c66920d5ebe8f2319301fd2808c3e3f883780c498804179a1c79", + "703e1cbda9028f7762c6fe3c29e0f1c57b1f31735e3fe06a4d24163cf3ff6a20", + "0cad880127ab9ad925c66c21e89c2b94f1f5cded7e48eceb4bec30f0562ed480", + "44fe6f719802a9fe7568ebd8e01d652004e0b2e4949c6073b23ca1c920b801c8", + "5d66b4e41f2e11177d3a9f6bd43e15a0b84156410ce9625d1b5dbfb08a39c276", + "8ee1720dc97f7e1aa1f80b4eea11d5a4018a934b3ba6ff21a912125e6e7eb567", + "a058c1133469a24ddfe1a407e5eadb97ad442b555192acfcac4ccef93f23bf1f", + "97b0a446e818f2bb7ea445f3bc2dd1fb87ae905c9f229da6f7c7c3a5d558878c", + "55e345544a3f9be498b758d931dcd8e400c8efc6ebf4eff94f6ef3c6394e1832", + "f6e13ef57424da033d0957270b92cb2eec6708e75370c2fb25f2909fbc0eecda", + "1bc9634dd9dc33d7cec85dcf701c6e35e370ac190ab248a6982f5548a582e1aa", + "ce314a407fc77f73e9d6043fd86cca0433cba2db37862dcf7f014ad57110cb47", + "2668e6ff58da3a80443fa445a8fcb14b32d563abb555011aa9eae5b7e2442f05", + "411fd0784f1bbb4b4f0ff129e40bac450547f98a0c899aa242603db7d6a736a5", + "95f3f5bc2af4899257b2b86d942e9c8b9acf5de8206eb6149a77c2949ebb9772", + "20deeafd5baf623b58f9723a7a2a86dd2113e57722a2d4dd285d08fb3a8aa420", + "74840d98e4130a784687099e4937ea19290742e85b1bc07a6f2493481a9a4479", + "684f2cbfb0ad6c3e023b5944f3ee171ab4e6b5842656623b881e5e816c682935", + "3b44e1a8e0619cdc0d20749065d38c0eb8a0ec18a7a4744ec8029de6d035b8f8", + "f365cf9bd1017809d1046b455430a0d2878bcf6573ae0153a391ba2e2bd3cf81", + "2b79ad93cb0d2165a48765bffd0ffdd45e755cf33b8d92142719799d756fbf91", + "0be053b199e96e1506d4cbe3299b89522e8ebdee2e746af7a5300547274c7ff3", + "555af0088b905b3100efb3bb9232daf4efbada84b8260981a96b9b2bb9af299e", + "bf5f6df0b47c9249c9dd26d2bce442720b37f705e34db912b1ba53c985691479", + "2611d7de1aa49cc70ed8aeb8bbf098fa98882c3b8bebaa2e58232e0661eb8871", + "1158a98f305ad059463f5d5a381f0bff9c8db2e411bebb4ffe7d2435ed592922", + "7270993c49eeee05197278c9b9db6feabfeee113a4173270825e2042c895b6d3", + "94013ede48c56200946d74babd0b0b27428599d024487d90fdf2597bdc01bc2f", + "8201c9a9cbb658d48c05884ea946846e491deb093e23f5c0f3c1111e32beb9e8", + "7d8a008288c1bf9edb8a9beac27fcc3c9fd3264f66e76b5ab82820d42a8f2909", + "10719081d5d4f91b14ca547ecfcff09229a073e2e10dbe16be28a18e5738b5ec", + "e9562b9c368b8014281142b65d6f1bfb4b17df4afca158ac9b45a9784c66490d", + "b048a19fb47afa2c6ef6cd190cee84bf024dfd40a5e5f1ff52c4a30859a081ef", + "78267a3f114889e859072dafad86eed9c8403a43c218ae62cdb9e638c4f6d4de", + "ad074551f3a4eb6afec163bcf5131e1801ad261a059f947dfb4f1e92cf4d4442", + "cb24fb8a8e18e0ab16b59c35a5bdab3990d649ad56b40c5a76d8e9316ef17632", + "577caf724718ad09843b6573d6da1c85f3e22d03af605093b875fc0b1b97980b", + "d006c53ba56e0cb3cc80c2f8c5e90a195ccb8001e1e99e340b21215475e95418", + "c35cf85bd128d05cb0c595b45c23678e100fa36c3f6dd3133bb69614d1469b01", + "d14f395bd933f2096dde22e9eabb092679d3716a976fbeba3ddf2361fb2a50cd", + "f17ae5786ea073ef56215b026314550444e1410ca6130660dd1713d99b9038cf", + "e5d26267f8b0ae73535c28e0b21aaa6a6be0b34e974da9344140a2c5f26d58a1", + "8be82c75ff7429e0a39d3a730e9081582fead0ad04262fe07fe7e84a25e9efd5", + "5657c716e567634f42ddab59aeabaad60855a69515179345017abd5bc8c5f503", + "4ed7cc8a071d9ee3ab72fd734d44117e12b764e02873b0036dc4c8f589a65915", + "d0c8f438461d32d2c863d9b424c758c239fc062c69abba1e5a4a37fbf80d42d8", + "6e40fea776bf3b3d9d945be4266d623ad1c9823f1594f0efc672d148a6ab7ab5", + "fc50c8575fdecb5a2e3cfdf4c426c2a45e0908d96a35436672779ed1da8fbfe9", + "b3a585ddd7a96ea33664c30f5ca596e49675d6506851044613e0af2d74f98b56", + "48c814122dd58d8a83424efe7ac2b5e26d00f97848b577c1564fe647259d4f49", + "0a879c189af3f17e98e05d1ca0cafdfbd327b086119c91c811070fba55b516ce", + "3554f949cfc18ec8d11e7924692b9cad7932eab13058670be08291069f17947c", + "fee950830ff7674355533df4c7d52c0f43057138123ce6d5aa138ff8a64f7e12", + "a2aebe6972b7ebee7a3a4c5e8603fad0195cb532d957e8092ff04edc3d7f35e8", + "6680f9f689671da8116fa95375970029df0263ae487677c8f6f4fb1108476136", + "fd272d18a6b24c7d2ade98215ad673b19009e85be06ef6edb6fbd8b089d65ee7", + "d68410f1b284a17e8f92ba4f4cec9364901f76f886634bdd9acf061a5f746493", + "1c35765d70850021a893eae76bbdff7199585520c1b2d8fd893fa1d63ac0a557", + "e8766864fe2f0ab2221b3a9536d784e65c3aedfa8f4fc2fe4ca95ab82d864ca4", + "b4a918176b3880d6410b9c96af67e4652780c87641b826828cfc39af05d67031", + "92c393930c55a02875762b580f3660790a68e8888274770c5a95fd10b84bbdda", + "a9f63b5b4e79d30643742d5a24ab9f9598c68777411be48cbb15658b518b2919", + "70d31359fab715e0b01b7c7009fa315e4106d23e63704eb35f5b6f87fc3576ba", + "0dc99e3445baf47860cdebf5d729af914bff9f6f16beca45b8fb1b5e063b7787", + "5498c01a2f9fcc0efa2d6bf2f98197b0922d456e86d3c238a61528617f367c74", + "3e34813a05eedbf226d8ac957db25665548cb78e3ca17ff281d40d0b3cdbd3df", + "e68b1b3f0428903b71433a4427c65b5628208cb5e99155fefbe35cd4dbb031c5", + "fc63b359284553aec112ee5b421b4cf5e2fa2c720d97b4a28e2535950ad27b89", + "72a5806aeb21106819a0dfdbe6325190fb9535df4a236961bc8edff3d6a7a258", + "8f3bebca9022ec135a88445a84d00c99c6a521924fe419b76a07e396acc73912", + "c1afd8d6d42f4cf969e8dbd07c8496f651029fd56aceeca9a34d12a84e207508", + "5c11f11526c86f592de1541e787bdb979f971a77721da1ea7a9167977df06f4c", + "c633358c458a7a563c358723b74b9b8fb44bf17ea9b59987bcf4291a5cdcd87e", + "5c382febc9907471f0163bff4d0a2bf2657f6b1d2a48c700ac47b1a4cee1123e", + "8f0e234c5db5baa354ea572b1fb9ae94ffb54fe2a3f17087b4325455ffadf25f", + "e90ad45df6c236ab8e36627b19ce1bc43ebea9a1298267f7131335dd032b877c", + "3d5a9e373063ec4fe35eac77808569cc8464a92ba9a09ffd291b9cd027be3da8", + "68af09e4ff2d36c62ed5f6a527f2235e546380341d56dc9aa6a63ab05bbbbba8", + "efb483adefd0b9b133fa595961b86b44e608339524d97f434a8e58943701e94a", + "1a62563910ecb23e30fd41b3867f6280fbe5367a086bffde8772e06485243290", + "1dbacb3165a0364c806af1ac88f2ee7cf38a86eb2e6aaf4d63c91fdc58f235df", + "fe62733467eda3f48fe1535677b0f780554dd1327d93b4b9feec1fe63a494b6d", + "3d4607081a8e22dbd4a005d82db93874e9b75db0453b7d5ee18b1c640f534412", + "063956efb6e452cf62ed17a6848f2d3122f3f20aac6180794433aff9db398a8b", + "14c1f22125c8f3a3188be67ba58f3735347678eb186f918d4a03483b1f6ab1f9", + "874d910fbeef137cada8bf8d67aa9b690e129d9f73531a1ce31d4db7bac4fb43", + "a3f27d17b408a799a468c7c1e953529306a88554ba8e36745e26288ca1456bf3", + "b8f436c4021add4ea42f73c2a6d5cdf96090c05840b372a708979e4f04a87624", + "ff9f6e12bf699b0eb3bb2c18cef37f6b687dcf759488baaffe8c2f518c669a19", + "953572366d102913ea11863d31597a7e3df6f18e696c0f965745ac803e7d23bb", + "d5c8d910bf37623c74ce61bfa67d9e183e594f4286e418fb89aef06f5794b549", + "31cf9f975e00dc4b798707afb032776893b6ec931640c449b521c1553b8a2548", + "e6b190c3e494d2add2633a7ca96c2f9d771c1373cd72ec7252c67d8e61c55ebf", + "9960ff3313bb0bc435bd1b20b557e1293e13c4986a06064fc2cf9f432b1ef1de", + "d2f317aeaac62f00e53016b0734fe0272424bada92dc10d93ddec4f679f4a064", + "b60953f348f2646ec71e88d1506232daacfcf76025fc8f2449f9d0600102c4e5", + "d50f0aa5e427cf6977d8b299f2410571820f842593afc9b6386261250c81e9fd", + "256963d1214f986ccf73c1c22afdfaca2256bd3e930d4b27cd3b52f8ef01b59f", + "52b5c0b0d0084f873088e69cd9444016d9ec7e0c4edc40e7784fff6dcbc33f4a", + "95ca5091ba4d2149ce47662f46be8b17c0c806d48595403db2452b2303b4e873", + "9629d75fa5bc8bac8bbf7202861277e0f845688d3787482d2f742377ef9c4825", + "5f95aa631ffcb4904136c39867dedf4510d0fd317acd13e8d46a256cf92ff153", + "f58653d0a515b11bee570980d20c895a0eb8963a9bfa884a8d5a5b92cb9118af", + "928e819260450da77aaec13bb5cacbc755388b218cc7374fb327c1829a18ebfa", + "5447c8bf65edf10309a3ad75664f461bcfcdaa7ef362e67269d60a4701b419bd", + "8c2056c6be56c6a29e193f766b8f7cdbd271fbe56780f39d9e445a21547f8a73", + "ec6d29c52e6dda68f369d39f71080fb3529a43dadf140317f9c4085fcc030474", + "6e47fb29a0e691027a80ba58aba82ce6568ebf2b0bcb98f431974b505b21f83f", + "089af632d2dcec5d3a588c9e529a24cc592a3ed2c91aaf1436be23808e511a4d", + "3ce185e2388cb264031cccc497e3e9b274e3321c0a94c25dc13bcb8b2cc763e3", + "05e8a88e90f96918d0e873f7b565b19eeb9d26f0d83367dc0b4ea408fe4552e4", + "45082f1dd5a8bc6512410285874f362670210e3bf5a7459b659b35be04e798e2", + "0565974829a0e1711670a33d5e799765f69c54623ce59205161da241f2e9ef3f", + "0126f800c16d2a14118caaca96d5d762c3dfda2309f3791804bc938470fd68dd", + "c3da3bea04f1fbadbd662b8b3a117821bf8da479cccd5f89c82a656c972ef89a", + "a8d372cbde3f33c4edbbf64267845805bcf968f28791f4ae6deff7bf526441d7", + "e1a27571590c39dfa1d9ab290697c424ed4be02d2e46ecabe322dc17f74cb567", + "578b0daf9b0efa86aafbb7a214db1953196d85d4dc48ff549c23442b3635367d", + "fd8976c9972013521eab2952efa9a6c7eb75a58f7fc7900e9ab44e888531c97a", + "24f4d5d7e815b89f5cfa4f408d3e7821029e9e6ea57f26e0bfd00c66a17cc303", + "5d3c03cc70b07851abc2efa9b64e5249318e1c2c79d11d554133b6dd5fb7d646", + "de8bf78214ff9a0b6bae77dfa7c17c6419e378529c3f5129fef820c2ce38b3c9", + "849f901f94b4cf6f1f212eea4e0a881532419e5c294ca8511a2657c979840258", + "b7be043abcdb5fe6ee6ffad533c470bc00a2d01a00c99507bf48e41b63102e8d", + "f62680370b5aa3cf20d473429928e038e5fac678817f97501f84fc6f19dca647", + "ded4e7348cadbf6342294a077d67526bec807db36dcfdc4a05e9a2d37af81344", + "c05fd64aaa403e517656da427332a143a416987fb4db3a903da5c82a829f6483", + "dda6120bafd2dae341bfc2b7de7c5ecb2e27cab3b5d8023c26bbc5b83473f059", + "0495a1de7004a908f3ca8d933efae2057482f3f9ae95859c1e6cb9773c5066a7", + "cee597ce81ddcf1d8df1643714e0ee88976a8ce2b16313601f66e186d8b4ce16", + "3eb1ae7134bb6a70bc00c7793d6fce8326493dc86936d287d8fb6f8643acdb9c", + "cf37e36acf97d151a8f3c4aff3f788db7e9099d96dd6f6693f00358744fc3f30", + "c3239d07c0c8192013b3706785619751a0af5fcc855054d183c9086edf3f8e6a", + "55d3fbf77028366dc41bfdf3dcc4902ec6511de6fe204edf3defa6a849aebed5", + "f4025b8ba4f7a540e5ce39a69ed38de704abfbc17a6d94a4102004723553f2fd", + "38bc948f4123afd1529fb8c4cd064f2d86f887e57856937b04cdb2135a40b822", + "e59623a134bbd0df4864c36477cf0c34ade22b23678a78a16d2aa83857a821f9", + "d87efafa431d23c83e4428a7b0e486ffca045039cf546f3645af72b728c7c329", + "5f0f8a3fe91173ddd2b4f1304e0f3eaca834c6a4e690b18012c4e9b7c60326ad", + "1973ed512d88f81bafe336d0982f7456a8bef31635207bd361fa05dec1618b0f", + "ec9f1854a3e818ae1749f15179f5d39c5573875ff33254a0c13ebc5f857c7886", + "e165bcdb9fee4cae2d17f769738458feedd733fdc8cbc82e8d084ac574967dda", + "1f1bc179cc5c10f8f822c2ff4fe6de14ec01df1493a380602da4773849d41867", + "2da49b91388142728b74f23f1e945aedcf0c24980a43a9cffec04e664fd2f082", + "7277b3c02bb1dde8005e5a269af2c8f5b778733a664da70829a3e3c448e22f27", + "4c49a2a9ddd9ce803cbeff5c8bd122a106a1a4ca32404b8851c6aed1da2809f5", + "64aeb4821110fb6406a6db4ddb5f63bcafd75dc2cb03a8597321ab7d5d3c57e9", + "2e5b59afde8a7bffd9a9b84cabe4f186bf233544597b8f61c9ce50fc5906a5c7", + "a69b0c400f210568a9b5e84d354d7d870b10fb8147e4c712e4d71484838513b9", + "350f160429ccec3f71fa3f68354038464db0ddc0288ca7152bf1b2e9048b75fe", + "412f5707a7fd288617c853d12a05e9dd00377dae60503c3d7a61b8cedb183cd4", + "a1d83ce1f84ddff392abb4c9f167068808cb9bb3413e33a3200a1f6d9e81798f", + "48ffce205af358829511f7609efe8f3614d8cbf3d5e719975c4ec455c0f883d8", + "d8e1101ee0610500b9bd5b7b5ba452540062198f2a1b5be43be64bc09475c839", + "59eb8557e3a4a54d50df7b8d0a82e02af900777a19a2ccce7906eeed9cf6059a", + "85813ada23fd9bea7ee92fee8bc89d52d555513721ffce0742aed111843e454a", + "d5d809628e9db7c6bacea8cd512f02eceb22fffc54aba76c6dadee1a16b92d45", + "49174fc1c9c3cf963e39f61c74313fa4ccf1db13f989317c77456dd0d035aa86", + "76d061f00508bc39f90c29f13bf8816d89f673247f8b8d27e82ffa65ceab5121", + "8dcfc3a2e9886051709b807ef02aa12e07cdfb47b9fc7ca5da438b73b6cf71a2", + "5e3fc281bbc1627fce9a04028fdc6d7f5677a160bb0a2d0df6cb82a23cc9eb5b", + "e48e02d3f029fb25b74315eb036b82506f5ef0a60e6160daa539fa8d909ac334", + "0b7d6b4c570533c3a1bc5d797b839e2749a6e2a6839c9fffcb9b608c0366350d", + "9eda45596b628115943fa8eb3adbde92842e70eabd469b7af54e3fe6c76f374c", + "942c127b04f7e03b58664cf5f05f7b5849e9857c1ae62b0aa527c2b33ac39761", + "1499e10c61f034377809d14d8c996211982cd50874415c6f79455f6016c7a371", + "3f4b8ef808ebcffa0122b6bb8682bcbe81060acea82acd18b611f3fe2d45bd04", + "e2e3cc42343a6dda349f4e303026abc84ed4e9b0345d27ff9014936c20ad14de", + "f56e84082be2d04601f2df9eb51c9cb9a7bf631d3f7c29189b4e8c1d2726ec92", + "f0c92077c6ac768d3b5bf5232462ee6975c21723c846e413e65252a763f8eb14", + "e8e36057e5c87cdb2873759f7552c93260a5257daa0f6b77bf6cc1bc8cd3426a", + "bda2712c5ed06de63bd990076a96c2108bd28c8eae44c78a28e2b63b2fc85556", + "404b8172fdb29b2373307298a5cc38fb9c4a81001d84a21f86a9b2860a014e44", + "96c7eef7242c355c005fc096b0b87bb7a924285b3e02d5a8952d286007849b21", + "5fd9f7d73c912f0b67b6fd6045bb0aa57354361a69398d2f54e2421ebf378558", + "934e6e38ff54875190a26bfe21ec215ca733f6efd7a6b2b2b0b4a23794a8f75e", + "df73878aebeb58c2df35a01b918c508fe88293909ed0ffdc8048f224129aecdc", + "b0124a2055f7c8cabae9d37e41dbed5dd6a960902d1927327e1063db6dea6c06", + "5bdc6e20e1794f8a9800910a20e439fb4eb88f11b1e05bcb363d07f25e93536c", + "5cf88063d432e9a906b4cff19d0e0064fe81147cf62ba910bf6d362ffcc56d56", + "036bc105848a38fc5bf72bf6756931a2824dc7f9922800ab21a815c24dbee65f", + "2eab6eec5a2d7c9306a4970fac2fd01b3eea09ffaa84bb4e7985c5cb12ea6508", + "aa3577be2f67d1bc7c62e6ab531f458a1006e98304a01781d370fb56c8ee26b3", + "543ff654f4f4f8a8ca51947951b9122bc002b65dc138c465a90a0f02ea8e0cc3", + "1a6e5487d5d1d318287ad67f1ba9565fc63b9d4932f8536a8d5287cbfa3a28f8", + "618d75c9be7dfa99717ece3b6adb5cdf6bc7378a660b3a40e0ef6c0a5880be68", + "048f50e42ae109ebe9958a158c81f2c66aa1cfd47dd80c75764391abfe931cc8", + "bd986ec1ee1515c895f1c76826f3808a41f3fdb5e5149033174a02d8b0bf22f7", + "08eea7a4f060ec08cf3518ebc35a69177bb3f0766b2c6e0ccb2bb23b7f378a63", + "f0e73690d2c28c085c823886cc618477357b7c6a356153c457aac0782e9ff8a8", + "7b5aa4f34025fc41dc16b1dfcec1a30f47d2455caa7adddc7f3a7d630581dc55", + "5eff45d254937f9de5bf88ebf7f13ebe8b436d1f7a1315b3093c4d27d5b327f3", + "6e19148e4cbf12a1afb1bebe90d90b1b83faac5b8c0c57833a95fea3c196d2d3", + "1db45b720734fe79678fe41f1290e61b9e8984f19366991f26ccc2abcfd49272", + "8933c84d0c1e71db7a08aca5c62bc8f53f3802cc107a57fb7adb602496c2dacb", + "dacff35bd2bb39a3a3d550b5e9d3fd07ccc7d4e3bba9dd99e34d3c76d0c27ec9", + "e0f651567920d0fe7b1082c770f7061945f988701b33036238fe1d4405a5ddcf", + "0f109d3c5dde2def1eb65af02ceef8fbdd0c1c9085adce0c3d9e871880856e6c", + "46e64ee60d2152f8cea2448242edb31de19387f6512068bf6cd02648b2ef092d", + "8322db03c7b5ae5ac2827fbbf370cae2c326ec5439d145539801fe7ca36d77e7", + "209829a65d0f269dd636dede9f9d0bac7f4f6f73a939ef2cfdaca6ef6ec41a5f", + "d0e89c1f8ae3b765b24bcbb423cad1d85c2f145454316aeda862ae0518cfe1f4", + "71b45cc2f8c890b212d4bb4145235f53904b4421c545621a524b3aca33f053e3", + "f967f1e6a61d49adf4f1a48537b4e80b8917995cf96d9b557dca075c6395d7e1", + "cd95d46c84aefe0cb95d5e36c26829fd7bef068e0eae37b1f78bcec5e3695794", + "0acfd59b6f8e5674cafb178c6893ead5b08d503e2f81a7bd83daa71e9c9ee704", + "fb42a0a63431a41fcc1a69730c63ac2b762c90690752261d7a188068858f7b88", + "d9398250435f9e8be37116dee5ffff6d891968d5c77cbdfe9817881ff532f853", + "e52372ff5bc147455e0b8a93a1c933235522a90c48e961785cb5afa462f575eb", + "b47d28401cf0e69cc164df25d996bc0963e247eb9941ab4e78443573184b8f54", + "2133f2cfa7c49540145191323ad7e47c92427a016d8d0ad093f0d22d294b27b5", + "2fcd01fda46d9bc5f6cdfa889dbcf02d2194be0ca520afc0abba8d39e6464c59", + "3dc8cbe551cc7787da5f7df80709b9c74ae51939d12518e122f81edbcb4a2383", + "a0dd47e9470b3f727c3cfad7cdafd05dbfa05ae230ebb5b503c200002a4f4648", + "a6c3f21d700fc0fbf689ce1aa70076c2f06ba5c0404c03e020ec0f882d00685f", + "afe933dae84650945aa667c7115a05b9ebe4fa71112af9041cc3bee950789432", + "96b65c336f740f4fe6d4503f29fafc2083c670ba8168f1d2fde793a68a43d56a", + "18f343e655783d9ebd84dfb6a942cba4f7ba4f7b7bbc906de52a1c83a69242d8", + "15b44a5237a14de1aeec96402d370b41558eccfed85563711a6c852befb3f617", + "be26e58502f16455decc47a1247bfc1f6393aa0eb4a9e160d1d9cf4f2aa4b616", + "60e2203a23b8261fb512dff33400d4ccf02d4c05d7545b7714ff4620502aa3ab", + "6a5e9ccc29a5a62282009ea492eaeba004728bf8c6037b6930b08cc2f7778909", + "93224295f6ff6335c7d1f3b38415c26b7f772edd23b0ac041605c886609fbb61", + "da948c89f286745d1fadee91cb68e401f2127396dd3f4943ff5ba35b340766f3", + "02b66975a2decff34b987d30deeedb67d19c2279e00807c302298cfb0dd59f60", + "15527f7790b599a1c298759c2eac4039553a2fc5cbcfd775aa0e0050df77c4bf", + "7366c3ab76979e908318cd8539e703d1cf2ba927fc56503436edd7fa976663ba", + "5a8a7153e09d9fda4fa2b80f1a4d5754ef70f14a90a67b27f947b69e3be0110c", + "381f3184009653b9697f54e6046da35e3db0f8fcdacec99ec314ba19e36f81f0", + "4e0d54d01f6cf272eab604970505cb1c3f92bd3aee7975c518ba5b7ba77f705b", + "469da5a5275d221462c2faa0bfc262d1461f29133c1fe9d4cdadc4e314791647", + "da8e3b280c4a289898f23e30184f72642181310cb335fb5925ba5c1a3ee2f022", + "6c8e5873a513c3602f3eeae64818af84cba2945d2e3dfa0de12db7f810668cb0", + "2ba3d10e12b2ca223fa120d615956754bf4a516ed8c10d612fde32b02ecaf033", + "6b844748bdcfe3ad302b3f304c2aef01973536543ce69ef00ed21a23fd7ef025", + "8237396df516618664ded338080ca4969e208366b5382cefa83b906e6d6b93ba", + "9af799081d6cc83edcbd586ede8897d4c71653f93d7eb3dd39d45d30dcf1735d", + "7dcdd49087f3ece535c98b4ec65bdf21935b7aac380b3b986797d5f44a33c78a", + "614d0b0fd9a36321151f90b8949b03da04bcc25c5bc4af85689cb59d1d6478e9", + "d3de2ed868450eec0121b43617f1089c6d97524d7bdcb5fc3883dc07a0bd4733", + "be146969e4c1f92a89a2bb3249f7135c6c2817ab62e3a0f1d2fc631a16988826", + "bf2ccf4a5c4ba2d6c169fe459b8c7f9e6a22a613368bb81b9a772a6442de9f15", + "4944010a3413f861f0e08a0b4c82de52f5dddd92d208183a99c6d3bf5f8e3309", + "568bb180bf4738b4c9811ddb11406c30041374e321c19105bb14b36bf76fb248", + "97cdfff31665b93924191ea2488d60596ab9b84a2a72ef4db13abd26ef788e36", + "8477bea82365c652b3e8314dfa3ae7819ac51bf2e0ebbc0bbf7d252d3c429166", + "774ab4a23b6234aace48e54fe9fea6e82da1574aec9681c1f2766dcdfb729159", + "5eecca07e8851ddb6c9a0db3de5811c83eef82d8bfbc0d88a76dcc9965090b82", + "34d69de15a96f6d7c6c90585522b2e95ef6c3aabc7d88110bcc28d6f03e84c6a", + "53d40ce3868140bae80b585a128f42f522856e50b5fd8d2c8204a12e861fe1a8", + "2d997856a42f03aeca32390f869bba4cc428a3bfa13a0ae797dee72817610f8b", + "0c2425f3e082b28344f07453b8291824849a71bb08352b10e27da95440b3d2fb", + "f92e565eb04237cfc9d50f15be291e6f7611ed965bbeb8b4ce85ffb2a1e0bef8", + "ca83a216f5b6294d706efe00688a14e3fd5ea044693d17fcf26d4dc803482634", + "f03066a133f324b526e9181fc2e51389a10c9eb27b51e9b462cffe4c31329470", + "737efaeef013ba8bbc2cb5617765dc5b1da0860b0438dc2b760d93a0a7878dbe", + "f5524e032ecf5f60c175f984d6780f17827eba3b114582947ad2b69d1f4fe317", + "4c864adab893c38cec036cc1c8b7d2675f611f6b7a434433f16a5e59b5c43fa0", + "02cfc39bf27293c92e564e9d6ede83ef67726b2bbaf8c2b0822639f103428cdd", + "80145568c0937a3d95e1e65ef8d4ee3f9dee4d07e0aa395836f5fddb1e08cd95", + "9f8e632fd803c8902ca84cfd4bc54d1e3361c6f240142b6b7740aceaeb6af916", + "239835753db8870a0079ab4d9e407bd180775333b299a9683032d3685233e421", + "73cafadf8cb958e9bcd1ba5ec743ec58b747b4bdc5e3b2573690f962770104f7", + "3b4356344148ea8acd21e125374bf530328091657bed2c2d50af4ffa2575f346", + "91389018839aeb1b9e93fcd609cf932d71e2bf310ce7840d6134fdb8d8000813", + "f48a48255913666ebf7d61f39b283d5b3718359c5a8488a16adff6d77607e6c5", + "b5689232dea3e0dd3aa30eada35101506b973bcbf4a033491ea47593008b5e44", + "0e5a58f2059e541c2a7566e2e91796b9bd7d461a1f9d44727b7344042b2982d6", + "5c1c583905ea677a545cee6a9016e0caeff8b224fdb0edb0faab5d1d94cc40cd", + "48acf7c8f6f7e5fdd783f55eb7e4c22c63647b0f2a2b4e032b43382b26cf7692", + "adbfb1110bd9da9d2fe76ef5f30bc242c79843f0c03fa0e1cc3666465ac94bdf", + "6a1e2e9e28af0c871da56ebfaa60b8571549a5d52555e7013b84a615ac55bfba", + "8aaa67f1f4482ebc2db4d3761823bcbedc82761a3c8dcf77dc31f9a03da24dee", + "4468cd661e02819b9e78d00a6eb5554fb995560eabc53f7d6227b4f3d11fb510", + "354bf3bc935f92deb222aef44ddc317aea7b42be4792fdaebdf3eb5cd2066d14", + "1ccfbb2f75a9aff31692a15c129e7fb71cfa6a79aab7d9b4a923e9ff1095be1d", + "bc439a3bd8ab1d90eef777c3a96f8baa30474e7938f5fc18a3eead0ae7468cd4", + "86a8fc5b234d25dfe5fd0512679d58f967226e9d236e8592805d5240e51d7069", + "62a374b122f4f7aa97ae46f1c4f795416b8a56e6a94fd35183941cde0bbc3f70", + "c87b1933e731c00cd9ac053ac2ec815ea93dc90c705551ad2805e72db8596b54", + "406543390f3ced761721c76940d12276980c5b70a608f1760a3d80bed505b845", + "49cf7bc8a82d6ab7fbe18436fb6a62f29d42311b18cd44233bb129e5dc3e54a4", + "1d8d6cda9a2426b7b42e82bac26629c51039746ead4e4a08dcb7994c33aef3e9", + "f85cf11b9b8be5774337d7f160502946162d1816bf4526ac32c54395ccbaf974", + "72f5dca6832bbe0ed6b09f3a63dc973fa68f8b251c1f19c9d950075f06d32cba", + "56a510486c346f65be072ebaed1867b6c36267034e8b4ce586dfadae27684020", + "5e9e94f3d213c25b8c20383b394fa17cdbea256d0adba8698b0347403920ed1e", + "26857346a104a96d56afea8049075581506b1d7727bb0995398f3c97296998ad", + "5c7e655d48864bee55524792af07801bc64c10a8547b99e7e0d64fe2c65edaee", + "bbd4492cc4a3d92cbfaa93250940be52999ea64e9e18af904a72e027a5eb5977", + "d691f18d87f93d28283be973b369f98260b9a224b1b5c53293b1d9346d6fdb3c", + "a21e17fc59c6679307f78000c961e4f8833c705f4bfb01cafe7d523fb1eba0f2", + "189d8d2b0450f4252d8dee57b015085b6fb548e3a720f6c2d5573f7c52cbfc3d", + "f7e7287a54ced58e659bd204d90c34c22e6dc3763f6b264fcb6078402ee619f7", + "81bbf755acbbec340e71861cf5a5781977026723a8c13a1e6ec6742568cd4edb", + "9d2686511b3c6df6c4de86d6125cc3d748d42146361c380d0218864ee3893047", + "bd9c786b572e35607e58bd469ac30919def51928aa4a0d646ceeb8ed0bb992ec", + "c05c38b692516821e17ea7126284542f8ab2c590503c289b81641d5e0b1390ea", + "f64a92b3607216bdcfd6ce0bd300f772edbdc7b15099e510cebe28ca4542c533", + "a022e522b8675ac33064ff3e76316b7869e179499d65a9fc566f680581ed7aff", + "55ec2ef8ddc8fa122d6f058df40c47120207d8dc19d6770bead72575513cd88c", + "b4db01ca4ef2a742446abbb370a0e24d50f3d902757a9da28baf426258f75390", + "5d3dc475600e2b25e2d3ee4659fc94fc6b2b30afef571c017ab1bdfcd6d3f64e", + "dadbc10f2c19b105aa5afe8a7f54a4269fbae6a48631cf2f8f7f9fed57e5a89e", + "e9e1e223880b4aeabdf5c97cd59c8ef7868d4214dc0e20c6f0f21d7525eb2b10", + "ab4ec096fea39c53d9684deed4434849136e3e729718cd8af92d2ced63b78623", + "15a1c69830de8c046445636f29144664295cb2783def323e4d4771c712983f6f", + "f37078a6416f9d4dfe8327a3f7e3eee1d18c89a6ed90dc7e7fa4094e557c2db5", + "918494d48a1d200d1cdb88ff886815866e2de35ab7537737d0883e98c253ada1", + "4ccbf00c2db105288efcbcd63b42fe97a72d84bb66de467d06f1b6703ed8697b", + "940e3ccb95bd8e29c4dbfe8267a3094741bcb41ca8dec28b126f3f522fdceb64", + "284f05166e113902d4a4f813c5bf1dc91923afca0c334793c212d920ce36377a", + "334b2c85cf50ce9cc9b76451780ffc88b25ec13b1a22bc8565c33badf642d71e", + "d498001005c09f95e037a5f0c5424d964f0ba046bd74653ba471a6f56230789f", + "2e3041f7d6cc06f7eaf81ae4760ebac100560b86019c34395f2fac7dbac1b3c2", + "44c70e81ec1bc1bd6504cfe6caf592d493abd394d80424d30ea58568f4e71e41", + "16c28d242eea991e62d140ef493a9eff82cedb58cc586dd807faf8123bd0fc7a", + "1874320ebfd1026c7258bfb39b3097770f89161fcdac4d2416833c2a016be2c2", + "5cc559d70ad06d8bba0e9c003820fd6b76c875ec1e4ae4348b489c2d053fbcc3", + "09b171347113be89c403e37ecb182af7be4cea0d52dff64f431c2a661b8a9e97", + "f647c838058b2d85ffa2f8ebc8007bf879d9e29d3d5a79ae79bf92d35b70af27", + "b5a5c055d8e90f97c0a6723e40d5d9a6bd9e6abe06c67095ed3f1a989ecd6a2a", + "cedc080628439551ab4cdc6fc6b9305b5ab5092be53727be3172e7feb895b9dc", + "a6042c306db343d93e7f098670652e47f7e7ac8462a5bb1ee6a53ce776fd289d", + "e2c1989d920fba710aab3152a0b886f58250cf88a4ac75954e04548bbcd0c58a", + "861b04b19a0a99141b3065abe62ffc0552ce43682570df238a9f821298f55a42", + "29c831fc0807d0d58e742b1d56abd6f5d0d85d10b2610d14c356e36471d542e6", + "c03ede915187453e19ad752841e2455a526f9728588e644db2ec7c0b2a1cb01d", + "f848ea58dec2eb8c1fe1ac07dcc30c7d6155399da98bb336ff1696b54f05b27f", + "f1b642b288ed2c4f04da12c645e708854f1e2b545174d0e39c2f926fb1b5cc44", + "090947eabdc533f6b185996479b6788c9c7422e1b3440f131084e87cd263358f", + "15de1bf317216e831b2962820dbbc3bd59e8727d702d962cacaa8f919a2456f5", + "27698733c3b298e805ee2498f97e7277f52ba42824b1bddcbfe14ffc0b6117e4", + "e4bae653aa74055521d5f920b8332011f2536e1883ce8f51a24a52fcb1b8138a", + "030ba275831a40a7cb4363d2df8313765eb7742341d9980508a250e7bc92ab4a", + "a6a275e369535ef2e259ad4be9cabd6fb14322b2ea33495b38646b82059f03ab", + "c9fe8eb94090435ca82a471657da610723867554bf913159957a86d78f0e262e", + "2d07653b46af98727576ebe56c7d68342ffaa4deb4cb1a5c02bdbd8f0f27951f", + "5307adc9d472014e7c8234db8e7f9c25874bd4d4de913ee638c92036d814bec3", + "9b77deca8536e9eb22548085d70b01bf5bcaba72a49e8f0ee1bcc3afec394f62", + "6150f48f7acfb420f5128feb27b87b3fe75b8e03dee632bae6eb895b5000b888", + "028be86568ef4632ff36423b4c719a3c21e58df84ab3feef9dcdadd7c11762bf", + "4c142b20c58db2dd3ee11a86fa5f851e4c0e61b559394d349c1abc0b2059ad6b", + "75e5becf4bb126c847862e0dc0907166a059d71ab78bd01bff21749e3efda8ea", + "7f05152376e609b584f30d8a170646ff0f6d28250b197a060b9549f898d80496", + "ab9dc9f50f570415af218c597c7e557d497247b3cff2ac214d3072e9a36d2b0f", + "602e8e7254917e7b08f29762299c7d192f8935be98bfcc9cf1351fe99acc0dc6", + "a77b5e79375405ececa8a698384f5e17963c4fc34f2a8b7a9412ce0c709a2224", + "e5fb8f63cfed43e1a21d1ff388d3553fbc9666dcbdc8607f755dff28c7c303c9", + "a772627f1907e89976aadc8cae3f5cecbbf66eb253d5849776936b528c10a858", + "184e1599d1ed9d3ccb86ac151751d54b3162621a16012d1b6976157e092b2104", + "bf59bae64246359795f3c2f5f739f234ffd1a5e91d2cf2926f975f52e82b5d3f", + "4113215615e0b89b6ded257221139c48cf4c4103812fd1d8d5353d9da1d67839", + "aba4236b1e61d14ce78a2b203a3fc1078d6264ea96e686e2e8608de91916f35b", + "e353c547e1ab6976d65a3a2eafa13f1931be7365fe31ab2c248b76af57687c74", + "ace72fa6a948f6a6da027ff3156fcc5b9979f88a539297f2a1a7bf6c4a21d6da", + "b1d6402250dbec3c8e9cd4b03b3d469d0a382eb691945a347344e687c949a0d6", + "ad19da8e0ab8c9a42f4512fedaca0fe06cb21d5d8c5814e3f53da01ef4952115", + "2ea634347bce131094218cd8c4d88b5fff051601e7aed85ef6f6dfc9727d6a2d", + "68c18eadfd3ab2caa009e1f2ce6af71d3b41adde8638f776725143c789df3a55", + "c35dab8c43ce24c90076c8dbd22fe105ef63e6ec948b81151d526b0d2121f905", + "13faa128d3fe888e572d992c6028d6c78f0f5b7a45dd0eac6ad26c33e6afb4df", + "1936773a78313b78755d5f2aaad00139ec41a0275ead8529c56f909e9a7eda6f", + "b75cecdb83272407818302f4d614df87e47cba84ec7b8b8db1cc2456a68043ff", + "81e9b36a3089ec4c5a1b83e241f6fc9a3be5dbcba3a858aea9be4eda7cfa9111", + "03313a86462a8d73b0f2bd81bc5b61ea21bc1db858e1daf1bec5ef0d9260556d", + "edeac533a0f93f32de85980645e9aa81ebd5c43d549698cd7cec39c79929d29e", + "43e22342217b57c9dd09cea5e6518208e5b226383d48048128a7fd1f2092e0c7", + "a171beb9ff8933c0a3450395855f10c00e599a587d685773467e81e0a75d3447", + "e2be34e89a13036c7ce3d0a843051fc45bde301cd201439299bdf439bbe31ccd", + "de5252b6fea4602fae10ff43d57ba5f264eb830192ec10c1c4abfb5c3a0e118a", + "0fea5234f0f35f4f1c40bb423644f9cd202f4f3601b37c95817a2b39066e6d5d", + "a42fe9d01b6fa09b12ee6f0201378b0a0be444f7913d03cdcebdbbe1864a5c57", + "c6cb56c36dbd0b6148a4957a2d3bca2fa7efc581520d78ed65c8fd78de151423", + "889fd05f2f376dc6b8cfc5d1248d70ee1fa9115d4f48486440f2eed769aaaaac", + "e097e4f59d32e99f357675daf135b0fd2bb6aa1d23e6911acb7a23a8eef6c49c", + "00686ef075ce7f904f7156bd94a688d954dd49396f5ff845ea340091526e36f9", + "fe94cf5431ee307b59fabae6d101dfbed038c3298ff17cb77cfa5bac6ccad642", + "db7ac3ed5dd57ae0feba34cef24036b59221430ed5bc5b64d1b4efa3c409d704", + "055da9f1d345f34dc05b5cb4a62b23944f06c8f820ff1b034167d8cefedfbffd", + "46f20004db3e392c2ec6b2cab8a913a5738a6783c6a4705d5fcf8947975a7bcc", + "e7eeeba98352465456cfdf50ea906367ed724ed3788cf35a29bb979a751bafa6", + "3e004a9942c3faac76b9ed7cfba34b0cc14bc99ea54b906e2cbebca09dff4eb0", + "097e2fa5bb0cfcde93bcbd60b1797af029f832c247f65c281a3167c017a2ba9a", + "b989f9b59060a54fd95d420241a1adac7d846fade0a7d4156d936ee1a11a54f6", + "ee089d81e5260012b59ed1c60ea031709efb0dbdeee7d9ea371991b9e1b1c6f7", + "435b1f90b714bd7be148c81aa68630221cdf22354784deca5a82eebc0f854b66", + "d1182335054cc149b61748d213b891af2fe4bd2e7ee197e51d868dcd1f600471", + "e00875fa50ada35a2c56c6504eb36387a6aa1ae884a61938343d23b62bfb4df5", + "c141c6b57652a7bb41165595a87256a27ba4c6d5c925b4420d9dd01f348c43c8", + "3e4ead98a3e2226198a154ba76dceb834214a343ec0f7e4fec3f041a6111c548", + "6eb17eed8996692dd136d1c0dd16bc2497e458b1fef14b7e675a5364193537cf", + "30a80dc882bd665b43bd4540b28fe4cf53c93d3d3b02071849f20168965d1c6a", + "a48a4156b3a7b11911dcfe828f6f55c08d118adb3ef7f8c85096fead8461853b", + "9718db80f76d7a4cd46dfeea1804696b28cdb6ab2ad0c1667f08caa71ccb2dc6", + "06f0f24d62cf999e17e908c5fc66f65e9e4de474d9031c9a255e18cb1de43fbf", + "3234aca0fa8b97825c54d77e02d72ad2a14f8f9b3b65d0b54f1b5c813af432d6", + "96bd6c94d88a493c9dcdbbcc5d16c890866fb80ef46c4ec08ea028f4e4ab9b49", + "e342e1a2a646cd1586594fd697862fb1e7aea7da4eb4bb1e44aea2a47f722954", + "91f716d86fe79ab53ddb5f27092dd3dcf67946cb72c8406a73b1bf71deaba25b", + "313141416f3b9bfedc1f2cf00afb09944c291b3fe9de0cdd3681aae7fd56f1e2", + "4b92420dc41ed6fce2a747589f19d99683fd1090a029e9af6cd31f9bd46d4cf6", + "ceb508d693f20b0fb1a8a3e7c5548557fcc09291e66de3c7c80aa0d4fca89e86", + "506b9c17aded8f6c79c05c83b56f6d012b3ec1ff6cca9971b3dcdcb6bde63d94", + "97230db4f50c99d1cec9fd43115fdf462a14fbd74640af1bf0475c471ada6a0b", + "aaa933abb9dc4a1e55a89d4cedb58e3ba85c0a92e7117c61b1b20aa815862e20", + "015df4f68e5823986b30d5f89de4581b8305542ffef8fb5351b905d53708bc48", + "22c6b1b9e7832be1169c266c2be37e041d6bc06eb81c838a4f455a48a5103818", + "e7d880c1071601aa882ee08af9c398809d8424227b11f683a2a4a6f6790f6b25", + "bf11ef066900f9433b7a05b8384f0d8138714149c94eb424ae655b48ba27addd", + "64ab128a61287a7ea08d81a7ed934b2b5d48d287c218e56152b91ca1d056b2c0", + "6a134756ff9abcb9c5e4f255d5c92c536b6786e7247f3a776b0a6230b5a071c9", + "5572d1c59fe9cc14bdaae03c31000de2f912bb6ce6a1273d52e7c4a39822112b", + "20fae70d7947f515da41614cc6b1b8cca71db136e448b419335a6611ebc1c885", + "0c45ec44bc74deb7efe3cef22bc80406eae242e6a7c0dde693d230ea49fc1613", + "68e8487f46f5896733bcbe5e5a2ee0436651fbcb91c5abf1aa1e07af19bc88b4", + "ee4ad5193c4135616a2f3297959010b49364df369e5cfe19d4ef94ef02d165af", + "3c0d4fe0d018993e5ac3c1c9749361f3549bdc77b0dcb8cc6497657dbf44b9e1", + "1d9fb5707e5f1a9bf172384d108d9622425c881477a393fc4f8620abc91a2a08", + "5cc2c93f14f7ee2e3cc890d15d0a11bb92c2d7750521196ea4a9d135747a62f9", + "5e59df52d347f497a53b2101f6882d8d35292b100e3fdc6efcc38d3d53742b29", + "df764e81153c9b3b9b6d007f8ddd6861e4a171222cafacd7612945a0359c0a5a", + "613abc6315dea773dc084acf14bf8745141b74cb1e02248ce17f064f3f7a2d91", + "5f953b9da6fac1f2321f46f6789475d5f7e300c91882f0d1c3d0fc4d97543a15", + "3dc85a1602852a35c5b8312efa99a2b685ad9024479659ed630d75a92dbb2797", + "913f0f679492dfce9b00c4fce29daebf9a609c2897df4664bec5ea7af9fc5e2c", + "404f67ee61f605d3f9e42189c51964ca8f47fdebdf05d37438393197ab1d6f35", + "a50d0d3f5ea814a2a19487bee33149a3f8e5188587466ac0f2024db2362a8c75", + "6bea0d47264a64f29bc3a31f7d97847dad93b7d52db0150e28c970138dceda10", + "467e5b996a2540a55f3af31611f34e0c088b159a6d1cb56d1994fc91135d765a", + "f1e665fbe1bcc48e6d5249089cdcc2c4c435dec44cfdd4f430c74e264b883196", + "5fa191e939396dab6c5c6400ae316cafc6aee59156c6e6c6095094f3ebac5894", + "dd36a10a8a6fea86aab3680dfda749a11d32dc58a07456ae6ba31a5c85c556d0", + "57b8cbfc1c36f3a6cace383ea92f22f9a019d6f535aeb89f03571065bd24cea2", + "cee5062b9d2bc8f464a70ef86359810047abad5fd7b130b18a51e6df53ad9c74", + "b2d1de036d098fcde37b5b5d126cce99301b6aeec8ab9c7200775fd26e113978", + "ccf73a18c921a80ace312cb446164ba38019f4eaa06fb365eb5a1c21b84aef92", + "21a086e7c8600690a7470d09654ce2c3260d484b117c256c251080e303fefd9b", + "f15922d6e5e254f82b2814869f43e4a882c434a136678bdd8b5c5ccab983ed42", + "2f20b8e23c0a6d060dfb499fb198a5ff13985dca12d57d717fd53053bb5ef49a", + "3dbf98519501fd2f758df70c4e6ea4956cee36a25cccdc3c3de847deb7ef4eb8", + "b2649486405e4ff5393737415fc4c1001a7d0467815359594fb4ed2ce82ef188", + "2a28de30e0723c8b7ec8bbeedf0daa3506d04c18d62927d790892c53faeafded", + "a5e6014af0736129b032be53044e078cc566ada92f62c00c28d0154ac02cc552", + "6273394ccbe7511d7d12ebf9ba89f6255adf70d4047af1ecc8ea72742f58b87d", + "1647cbbffe9765f6a184f74b8e118762ec2f425684963869857d8bb6130a1266", + "c79b6fbc82a6ada277ab0aa5da8e2f8663e87abe074d419ba8065ea6d4de297d", + "e2a2b0d27c8d011963199ff927b0efb643b7e4b4c12f613e0c1b54bf53a7f081", + "05ca58aeee4716cda5a3b434970505e016755592703658779b462a8198492151", + "1ceeed86cdb8da669f681cc3c47d78882782c8a0ff2409c70c0945e7c917ba25", + "992b566f3b0320e7206be5882e7cffdf61a1020a343411d4653a09d3fb92d29e", + "6db0fffa30a0dd4aa3fd735858038254187ba4ef739facb135c02622115a3c8b", + "c8d7d8ba3e18d6f9af9516e07947c5ab586a9438d04d21e1794a798b6f1a2d7e", + "e85a2dd2a717b488447677622656ada6025d4069253e31c726fd1d22234ef30f", + "82cda538b0f00015f573bce919063f8ac22571b1e0f5292bb9c477a4a0498059", + "73c2d04e8c12d6b41b7ccd4afa37c385cb74103042e7bc4f5bcfeac6399ab068", + "0545f4eb52bea640f047c8c81b4fd0a029473eb4cd4fc3003c83b23a85713028", + "83a91ec662eed934657e4c63f0631307ceef9dd025f1eba396ad4b026df72202", + "6c41b6365e579eea6509b6a1c1b11c30173f86c817d2bcc49bb68987e3b2e3e4", + "7f84ca82fa622dc99240d5752fb43323de3f6bbc41c1dc51143e0c7b11604875", + "883c5f17a6a993518c361b71ab52b94b57a39aef82ea119872759ad18f639825", + "d07fe9b2df6df56ac3a1669e3c214effb588ea10cb04abacc8eca02b873bfcda", + "8494f49561f520d72b1b6417e706c9d958f506cf95d63cd60b606f856adb07df", + "c48b43f1049b451a8c455adf38eee72f10903554be04891a95d3a962c4e4c54e", + "cd907b894f5583ce11b02f7884a34adb0895197dc188e96954be0d5b06ad8174", + "33197484407c7866abe08856f2b3c735590bf06381838e6a6705978e5ed34b35", + "d0fbdbbc274464d6e0e9b4c8910b3b0a335762a16dc2b51f7c358ac7247b9850", + "d85d0cb4ca293fffb6fd20f25846eda8ff097f96fa8daef3656da2f7f12ac060", + "3d945ef57338b0ae987a32a22c3252133dd1dfeb5db2f20ebac2d00311ce7e36", + "1c588c8869c7473529f7504fa6c83d27fd265eb2643a3e5141c699a5c939af4f", + "89806c321ca9510d17abaf5323c0e74192797bf6d40167c7860b045187c6b695", + "b8a7e6ce1960552827c7b3970c8d3c3e0afb466bbebfab0afbece47bc91d014e", + "4dd8a15e5ffff79dcb9a118bc710c0045b215343f247b8cbcbf764200ca77168", + "447c6be0d9a844c70e5ec614863bda0cb7bd74ed550c718bac1641fb2817f9fb", + "b83d6513af56ea134433c49f49f4e4c2fa0e8c438ce1e924e68f3479fbd00379", + "140f4e76af24d255bf31460bae2e3a6ce6ba23ddd184bfb9805c28d45e1f048f", + "f6aa9cb304e3607cb0a357dc6a1aea857956dd70569719b5f6ff911e54aa3ee7", + "46b0ea28f2fb0310df31cf674c7494fd4654d0fd3c85d62bfd067fd2669ead19", + "e7151ce9904d497dfe77990b959c61abc7a12f1d35978981e056ab8e65842a19", + "1313a127a07bc947290c4da4a82710966f010cf57e5adbb71205ce62a736bafe", + "f2e1c5c81abb53e14b42390d795e64b4de24b63003983b4683450d328d1f3134", + "23bd273b5f07318cd45135d21dabc4b71b371ffdbdf223c600f47642bb17baac", + "06637e4b142389845dffcda460be4cbfaea25b0b37f775c58a4e113266085f0c", + "6a05d2cc0d653c2902b92b54f143a92acaae347a72ca5f64ddd1d56af282f049", + "08a6ca00cbde927e53c294a14977a0efd6f52e44381ac36cb203fe11b0e3f050", + "ffde4ffc22ce9af6f098731d6571a7a455ef391fd858785e8bc4c1b2bb7c67fd", + "3eb1bf0e2124b3cca8968c3b75ab0b3ffa62df7464046d62c0f93a503618152b", + "e3f7f44bdd59a4108ee44b0a1e83e560e772144c359835ecf97604b2af716256", + "a77020196dc226963faf55bac07dec81dc8d1e5ff759eb9d6836e170d811617f", + "0406ed8430a6c1da09055941a6aa486e0a92d41b126a0f47e653d885d3688c98", + "1a47419972a7b139d3787157468b8a4a5b814360ebe576b5c051170669b70c1b", + "812ea0abb436063a73f5e43778ead4f2ebf8e639fa14858e82b53d4ee3a907e7", + "a3139ceba2212e00acca971fa5d7e6933eaa8abfd19c081b947f505b2f77146b", + "ec9200c06d5b469fb436667bd4a23f9f83694f69690ef35cf7d82f3f51eb6618", + "31303a0b303eed67a44d27de5342d8dc96a8bd167a79746175bc3ce1c37cc9da", + "04280bb1dc3fb68bd0f79fa6d9f55a09c22ad00dcf4dba599621bbe5bf4d25d9", + "9cef3b90f617576991cae136a583840d378b2ebf5f4280f6028d742479e38467", + "2e6cf61b6b118ffb267bdb3896fb813bc4c618220f32cfd93204ba5d397251e9", + "f3d4280378058224c3a156e1ec52603f7739e91e76e7b7d28dd4b1890feb7217", + "1cd41a6c7e8fc45ae51f0ff7033d15c2e185eb5afc807bd2eddb36b62fc92e06", + "af719dd02d3b19a10aa55988e09bb36dbec0f92b96812366dd8f15511c0978bf", + "5f0d5ff99c91bbbc6c9ec8ef1737ba0c73ddb8add0042aa4eefbd6b63fd7baa0", + "0c554935992944e3ff5d73440616051eaf5ad234bd05b01f8aba5083de4a6dad", + "47922da7b08b450461d22f4868d0081cb2326f69c1fd1f8b3404187488642ffb", + "761455b8cdfdc610498ceb759767dbc1b09abe6b085d55d5902a930acecbf135", + "914c5ef6f6bf4b92e4f8c38512825d9425feb21951068270b2f3d10d547dd9d3", + "7071fbc2f3006c817dc6237b413d2c7204e04f578b5a6ddc85bd8699894db634", + "989627ec5d83d9d91780bbd75da90380e3528edf158271a4db475c0546145370", + "74e861622838e7a39e5c0de57799c72e607e19c0b18059f67e67ee85c651a651", + "7580a1cf2fdc9b2f9efb87a7117b80080c3827eaacbd65c0918d2e64eafc51cd", + "1e6a898e963f466a5f56e420416f6296668e50c7ab98bbd9c91ef3ee4d573541", + "714fb0853104279196e8d7c0a503ecea847cd1e6783004546bb179337ccc3528", + "d0720c5e9e2796d9100f7e67e677a6b35d78a511085ff6fcc2dcdb28eba0bb72", + "aa0e016f6a47d52f879f55642dd182ed9a4e37e36de3070e3b5a1c12ace6761c", + "1ad24fdcc801de9ec3807359aaaee01a83eb13355996ba44e782b5839c335fe0", + "7fb7ad749afa0f4bb00dca67b53fba269cc9101db92144877b1334b06e8802fa", + "d99bfd2c5bbada232612870bf7819c7766ebe0569c8f54e69006f3db050d59b1", + "e57add6b436351b7ddb82ac34d7e216bba6051e6983ef16208a3ab094f23b972", + "4050338307512cc89bb56d647783f719f3875d8a0af735f03d67c72b7221121d", + "de45dc6af2db46107c9901f0b7441873a9a0e2f170d9b896cc6a837892f4540d", + "60b8abb145615571a5a8911d88e6bc7587d487fda019540149a2bfe1be19d88d", + "4c85ea3cd4c497a68dff7b9ddf979bcd637543669bf01c8f0569db906db42b4a", + "80a87f882849082d345148aa4627c7c761853ecdd51d1dd036076c6920e44020", + "ef27f1c4d4684ceace9ca6fca93340d5ba451eec7aa86a5bb3e7aaf8113739b6", + "0df1ac1cd7cdaaf730bc4b76e3456348046637f684c052f0ca078f0bbce129a1", + "639bf2d246a59d7e88ba402d5001004432971c8aec7506a8f1d143716c3864c7", + "d7258a389c3958f336a69bd51e3509a27d5db5ba0a7af6953ef4be7c5682a32b", + "aca4c6c13388ba5598114467bfc10782a6b4b441ba7b1d31ab63b10556582a84", + "a054efa505c6cc2d4904c1d74c411a18e72f96cf91ef0d68434e8479024eb74c", + "0d8f6fc0b8cc9cbf42195cae60aac50daaa0adc2a467f2fd43ddda13efa80275", + "4b0fd60e4431d8b949b6695d62532128c7c6471c52d1f2e6d03d51840d907c4f", + "e93ac680c407938503a2950631686a79d1b78acac6183252f384d52cc4082d02", + "1b15a8a9ddb8a252afa86fcccb9e7da7efa6a44b4dc0a88216fd36e801020e36", + "6bd1d824129944e39143211fc97b018d0f6a26616f5018652a230d99b75dac0c", + "8b06e823d211b1b0ef745ae0c241b658e1ccf09c9411f6f9b5ad2fb75c4edbdb", + "60e97fce2458989db88a553418719e9c144fea6d1e566a26810379c28b8f8fab", + "767a8ca0f86d35b09498e4bd8d1775cf7941b76abc39f7d08fffc35289115e30", + "8210d0825c241a0779645349c4a63679848f65d51af3489a9b5f7a4b3af5c86c", + "6b7be4decf3c335f60ac1bb2b384efe9abf0f557f9bdc123584b854ae5165464", + "2a56c287ad540a6dfd51c6332d7ca5ea238d608c85d70d5abe7c057f916159ba", + "1e5b1a8a0b9e1e4f3a251079b29cf32299f9fa1df6b897bf7240d0e66710ae07", + "84f01f0ef0c3725a7b0d362a76550d6cec68a40b0618a25d4d8a2f791883fa99", + "e097c5857198f4abcc7ce72ca6f71ee5ae536773ddc448d1c8f8b9304a863e2e", + "a8ae7f072bc61de7206a22068612094868a783ff765a0c294d58a96ca0b11d5a", + "013d21e927ba634e3e395f454ec62bd943be9ebbd12159d6e1a4d2aff101ed34", + "6af947645e0135fd0ab92b204dcf9e8ca8cfbe0dbb6faf952561dff36ba7cb9e", + "fd5d2bb5c6dbd606915a24b93ad657126e9869ad918acbbb875c9273d228f6bc", + "8227f341399b28256cb0ffe8ce26a5e7e0e8707503bcf29e0e657502e4e6ace6", + "cf1ac570d3e0268a435c403965fefdfba513d52cbff6034e459299f747cf6982", + "8ffc8601d9a7e13d6bdd368472d1b51c121713d5268c5b929a3a69fdc5b24745", + "45dff33d2a8986f536430909fbc37bf72f441e13f022000dd6d54b9f7b2eba5d", + "128a96a8baa35f5a78ce516032013328cc78f2f0acaaa4ec80e53e915c10bca0", + "1fa119b98fbd00cb7bee290d6212ff5122c39e8aacf80c7f43df54ca9525a728", + "59920e5ffd66a95de6eacb0c46578c044ee62bc1a4d9aba0f714c1b962bbc363", + "4712b68b3f8e2360a42dfca85a5ab73c8c02af58ba370f625d44a8b445b1a08d", + "3b7c2c6e15540c1e8a2c424e0655b633b2c9d6cf0a8fe4cf3e27d4c46b042854", + "50a1db3cfe4e6a93e880386e1e274aeb0e2082d8b7e9a88e4d488cf42ac449d6", + "b9ca2782adce3c23772aad4af3e434767a2934ba3007b41cba0987f32010b8a9", + "a0877aac6a1f03f6b4f9c544fb1ec8c4d92dcaa3de21be80fad0501a7f2858a3", + "9d5abf96e559a1fab97e619ae447fd4bd474faf713f53fef44ca18e3101ab8e9", + "3408487ce8d7941a0da7fb4f5bfd3a1be39e73d1b0eff7b42b8742b80ab219d3", + "24be31e58f4379845c945ca8a88506bc51c1ca024a789226f7badacd94dec26e", + "0af546bb1087bda00fc2a1732ae9b44b3a9e791286c9ff807e20c677fc16a66c", + "20eeed9662ecbaeb26999579ae8e552f7ec278da06ee5de8d186224eb8e7b423", + "a93de347a0a7274f19a29680a6d0dab4fbd4aa4aa47f4b0a98e58eb963f30572", + "09c1c34eac231424c029bff5fbc3ae841a66b7ce4af9471469837ae95f1a55f2", + "fcd3d73e3d1c67116ac6e4b35fc27437b657beba59c9859b909657176fb2fab0", + "1e2f4cd0c33178e1ecc4246a157823ebaa798efd18c180a96c3d66224bb896ed", + "fe624ed152e761ba85bcd10360e5cc24a26763e13f19eae6a27c75a16701d099", + "48e146414c83b7bea69ce41e50e79dcc70c7c8ef643f6842f91ffd2e507f387d", + "6fa2bf6e36f7011ef0d3b4304d298d9251e32856c88b91b08d2d5b018c4cd1f1", + "87ac32ba601e6cb2e5c640d25f68f03e14704fc26ab25274d48d24dd0988bfe4", + "35e53c8ec127f2d40ca51515cf44e336a604b99c7e111b644d001c210133428b", + "175774520736d4079c9cd6f8237be78f7788b94402bafae303f0aa8f5fbbe75d", + "86bfccb263140a7bfaf4136f7d8dd0fb6b43307835b9f78ecfc9e1283349c245", + "f8d12a9eae463857b8921aab06805ea63bf612bd62fb319fea128598698a11ab", + "1ea2de9250fe82c0440f7a338c52a2b1a88307fc9d99205962f5e951e8eea129", + "42cc6125207cb48a7f89e18e2ec00f7773b7337ed82aeef78392701d282b2b32", + "c5e3df0c833eacac4ed9e856c8f9b9e4ebe6134f2e46a14fe6314a8a4fd889d6", + "cb96d880c8abca553029eb93387e190c047fc7fcd4d4de088b266a5c21348c38", + "0407d3c51afe1ad70a8011c6180ef454770c964039eed5cd65d15889fe63c2e7", + "f38e83a03db51cf761f883576caefda05515ae78b64bdb5128f4c197429dc023", + "52c00c760157a655b11f67eee8e2d46d606e7840985a494b789e6f3f80c8b804", + "e32556f76b9a7878d010e84a002f8090ce655dc20b583b19047bd2506ef52ad5", + "64fd99fe245b303e4004b7d34bbfb79db79f63aaef228e2a71bfc7f437d4d3f7", + "b54e144559bf922d18eb369c081c43c35703bce23d38b9c41a67dfe64faa2a87", + "32fadd8d481729040a3c0e5616001a23731ade4a5f57e3d6d0a4279ce95aba45", + "dc7374b67836b62eaa086f1a83083af938fbebb135da45f3a43badf2bcf27730", + "b2889c8940eeab594ed50ba5ae5f964f176b78404c335966b113c9c313d8a6df", + "c29a7133e34bc0bac7dba61a4bbc3a9fe81406bd97aeb14d58357524cce368c3", + "1bc76bd2d3cc27e761bd7c84fe4f53457adb913cb505ba7acc094f424b20c73f", + "c157cb4eb8870b5ccf13e00f6c6c73fc7e3cbf329d0bc5ad779ab1aa023b306b", + "bdbb464e970214ece2f51ffba8f602396e9e13e075423dfa34887627f12360b8", + "7fbbe3620f323c448f8b0755841f09fbd8eb55a897f221e88db0310617d54bb0", + "0b6d22ed5843dfd247a9e9cafea585310145f2e169850e0cde7ab04c364e4795", + "bc7aa313564a44dff711024f384cd8914041847cfc0dd14f94e3bf7a89c34340", + "440b6315007b402ad72934bcd32a44826c926c33dad0ca787b5ee05d952e4bc2", + "ba8ee8e4f4bbed5ccb2494a3a65dd56865906b1953d1830ed4f2bf34cb5633f7", + "773754537d3b25ddf8826d23be023edd49c8012ce4fce03fd98a2e6606c8c5e0", } -const sepoliaPreverifiedHeight uint64 = 516864 +const sepoliaPreverifiedHeight uint64 = 776832 From 12173a20ece1f27309a1c7676a12205511786f84 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Tue, 29 Mar 2022 13:45:46 +0700 Subject: [PATCH 206/261] Integration: reset StageFinish also (#3783) --- cmd/integration/commands/state_stages.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/integration/commands/state_stages.go b/cmd/integration/commands/state_stages.go index 900811b2987..5594b3528fb 100644 --- a/cmd/integration/commands/state_stages.go +++ b/cmd/integration/commands/state_stages.go @@ -179,7 +179,7 @@ func syncBySmallSteps(db kv.RwDB, miningConfig params.MiningConfig, ctx context. stateStages.DisableStages(stages.Headers, stages.BlockHashes, stages.Bodies, stages.Senders, stages.TxPool, // TODO: enable TxPoolDB stage - stages.Finish) + ) execCfg := stagedsync.StageExecuteBlocksCfg(db, pm, batchSize, changeSetHook, chainConfig, engine, vmConfig, nil, false, tmpDir) From ae9757f997748f7e277bdc3b21ddb0d346e50410 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Tue, 29 Mar 2022 13:46:16 +0700 Subject: [PATCH 207/261] docker hub - fetch git tags before build #3781 --- hooks/post_checkout | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hooks/post_checkout b/hooks/post_checkout index 1c6f495cf05..46be47cc3ae 100644 --- a/hooks/post_checkout +++ b/hooks/post_checkout @@ -2,3 +2,5 @@ # Docker hub does a recursive clone, then checks the branch out, # so when a PR adds a submodule (or updates it), it fails. git submodule update --init + +git fetch --tags From 73feffa57db009c8ad5735ce2fe42cf5eb0da146 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Fri, 1 Apr 2022 08:34:26 +0700 Subject: [PATCH 208/261] fix nil pointer in fetch.go (#3802) --- go.mod | 2 +- go.sum | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 9f653e59265..3e3587d212a 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20220327062501-84f0d06450aa + github.com/ledgerwatch/erigon-lib v0.0.0-20220331071652-74afd3864c53 github.com/ledgerwatch/log/v3 v3.4.1 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 diff --git a/go.sum b/go.sum index ff0bc01d920..fa637cd800d 100644 --- a/go.sum +++ b/go.sum @@ -493,8 +493,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20220327062501-84f0d06450aa h1:sogweFOU1SLPLZRL69cRRSRBLwDC+nNV9+EB0T72+ho= -github.com/ledgerwatch/erigon-lib v0.0.0-20220327062501-84f0d06450aa/go.mod h1:DuTHf07xXPh3sf0ON0Fsab3bNnqS+XVeKTFUN9Pv36Q= +github.com/ledgerwatch/erigon-lib v0.0.0-20220331071652-74afd3864c53 h1:9KQ0jD2zTCCGCaTxyH5F3elT0ZCOIxfZIJ5zABEdXLg= +github.com/ledgerwatch/erigon-lib v0.0.0-20220331071652-74afd3864c53/go.mod h1:ZJuSY/lTYzZnclDfGvxFfTGGJ4AWRmqkHe6E7dLiKYo= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/log/v3 v3.4.1 h1:/xGwlVulXnsO9Uq+tzaExc8OWmXXHU0dnLalpbnY5Bc= github.com/ledgerwatch/log/v3 v3.4.1/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= @@ -750,6 +750,7 @@ github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs= github.com/tklauser/numcpus v0.3.0 h1:ILuRUQBtssgnxw0XXIjKUC56fgnOrFoQQ/4+DeU2biQ= github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8= +github.com/torquem-ch/mdbx-go v0.23.0/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= github.com/torquem-ch/mdbx-go v0.23.1 h1:lclZI7qZu844VjMn6onSWWcQYCIEwbClML7we9qxz7E= github.com/torquem-ch/mdbx-go v0.23.1/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= From 59cd45bbe5c5da812420f5b083670e8bc2a1a613 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Tue, 5 Apr 2022 23:08:38 +0100 Subject: [PATCH 209/261] Update preverified hashes and skip analysis (#3831) (#3832) * Update skip_analysis * Preverified hashes Co-authored-by: Alexey Sharp Co-authored-by: Alexey Sharp --- core/skip_analysis.go | 2 +- .../preverified_hashes_mainnet.go | 329 +++++++++++++++++- .../preverified_hashes_ropsten.go | 141 +++++++- .../preverified_hashes_sepolia.go | 329 +++++++++++++++++- 4 files changed, 797 insertions(+), 4 deletions(-) diff --git a/core/skip_analysis.go b/core/skip_analysis.go index 82d4ca47148..ae471a86d65 100644 --- a/core/skip_analysis.go +++ b/core/skip_analysis.go @@ -21,7 +21,7 @@ import ( ) // MainnetNotCheckedFrom is the first block number not yet checked for invalid jumps -const MainnetNotCheckedFrom uint64 = 14464300 +const MainnetNotCheckedFrom uint64 = 14527100 // SkipAnalysis function tells us whether we can skip performing jumpdest analysis // for the historical blocks (on mainnet now but perhaps on the testsnets diff --git a/turbo/stages/headerdownload/preverified_hashes_mainnet.go b/turbo/stages/headerdownload/preverified_hashes_mainnet.go index 492969f1143..ae6b072c706 100644 --- a/turbo/stages/headerdownload/preverified_hashes_mainnet.go +++ b/turbo/stages/headerdownload/preverified_hashes_mainnet.go @@ -75337,6 +75337,333 @@ var mainnetPreverifiedHashes = []string{ "62e9d15602492611948bdcf0878115f75f95195c8d364a0b2cf66fa527428487", "bd1aad2f54609dfbf1390efb857b5bbc111face47c8061ed5d0b56f60e765b00", "9398ab637011f5824407a0b17a6db5db1d3918517d3f291dc0c82eca496aff23", + "77679e1b4942694a682745e1318e360bd143b97ec465beb5bbdfb76a06cdf35e", + "d47749743a1d1e84222841b8538ccc96798f667c414b0f498928ff774b253483", + "0d2ccd6c2517901816e1071f5e3848f3ed2cd96b1943d43dfff8ba80e9d6b6f3", + "04e8138467c61894cdf40cff408eda9015b708652cda0e8851396056b2891396", + "8c77389dee370990b8cd9a6d124bb3eb0df94e0083b31e3e94cf31978c32e7ef", + "45ebe7f137e95fa85043677cf54f77aa5d4977bb583eda7662133a155cc6ec0c", + "5be0f7e8d9a000b86b575eb2c0851bb19c6abbe5a7a592ab93ba409f3a7a4474", + "dded01e87e468b44ae71047c8e81045e056186b4d8a5ba8836298afa0de21608", + "f666ed5f3121a3e1b915a131f98a8f01418e0897cdc9ca7ad16c5202df4fa441", + "f0be922c12f9415dc8237d6eb036e46e46d3c87b05170e0c669ad9354364d068", + "7202a5aa1575de1a6c05f2e4a382c446bac0ba0520903d3f6eb2d78eaac98ccc", + "6b4d4de9b295bc10c4fe0cc64aa7a9f7a68fa3c27245bddd13acb879f87ae417", + "c63af409302c5149cf2dd8cd629b6a1695fa6ff09c5f7662ab67f90aaf2de8b7", + "b15a359e27fb447cd5971881efc2b99977864fb018b98a0cf5093d302a62883d", + "96f52c72336e6e66fae747958d05cab6898ebc72e10c78f3c0ebda760f6f8b5f", + "767785f2d0529f6adc522225fb91ea8cf143118368bc1f1512f7a3c8a0445304", + "2725025f89f3cc776278321776b65768b7d96072f603d2f3f0342258b12f74f8", + "4f4d7d8af0a274e76b2f04768bc75728d1e1d09fdb8cd37de00a977e2bb83b68", + "4096f3f6ba7371a5142e1e0874d9ea9955f6008b3c15a42d75c244ac8682334f", + "70f703759cc0977a4f17c3fe65fc3df457f106bedf5e92fcb4f0aae2a0b88709", + "c98abf090ff2d08fae1c74915de1809057a46e13153f227dcc9f18d08cd52d8a", + "399050a776790f04ccc6a600ce742b2111941088d552e56a42cba73aafad53d6", + "1a2ffcbcc7548fa14fac2ad8283990f5e678029ce0fdd34555664cf59d1abcd5", + "0602be6ffa7353865c58cd7a9b6b73fbf7ae120277273eeea4bf970aa0607839", + "79fb1d70781ea40316c7a834f3ac62d0c58cae0fa66a5e6eb1643417eb409acc", + "3b4f30fc61cbbdbe1f3f83d291fe2101a5f4367218ab6ffbd9dc0a975c8b1b02", + "abfacfc40509c9daedae01e3045c10617e88a4896342f0d9704e0e4ce3bc1799", + "a999e722c7e7007ce7bb7c71a8d9405375fe5e61f7cd84355765c0ab6b9d4d93", + "9721b203163fe43ca7310e99432d5957c4a6da1ed2665dff90884a4495710bf3", + "8ec5d40c72c9ad70efa4012f025f6913a35d95ccb6406d33d47f98214f11c55e", + "5ef2f24bb2e12b6f53d1f24f3e411a74d81817094a40de2ea6a117fd6b8ba263", + "cde97212758cd8a5912456e09406a15309b6e9894fb2d44d38b2304293e94799", + "a1b3f4d62a45b2a8ba63ce636c04e739db3fc5cda1b94a7484bad6183a9e0417", + "b561abd9c3bd851da63a488c2d7880ac36ced0327845ac6744d96222498fc273", + "ebf20d5bd109fe539da2b4b5cc1374c091bde23eed4460725f55f18a5be8e001", + "4753336570590fa09cf40bde13cd7171b164f2d9b3eeba8e751a6f08daf4b3a5", + "0c32b163088c45c41790a7e2a9cd8d0598eb59a29695e633c58bf72218bc8c1c", + "15480f02a9d2c683a40ceffe9f71b7083e2ae02c755ecebbcda991bad579e8ac", + "3d2a644184765860bc30119b855eddc3e3b05b89ab0cc07b69b237a9c0cb2fb0", + "5b5311d4aa27d8907fbe5fb1b82d61b66063788867f584396eeab4d1b79fd2b5", + "c24aafbd8aec56a95d6f0d164fc7c63d0744eda2caf2c85bc54398e99afe5ed4", + "e88e8c28150e043da3cff9803010e0f6eb90f9a866251b4b7b2f3d4241f44cbf", + "97151b5cbe76c78acad8ccfa0eb0aeec49847aa18c031d79034bce9adc4e673a", + "54ec194c9be3c73e0863dd6e2c766f10f6a72c55c821045bd1431b08125da03a", + "13fe379618950fff8af190462199c00846f62ca50415fb6cf810657e24d2cc71", + "bd33cf37e36204c759414dccb827ba53bf6b8176d3d389edf5fc3ca26e5ffce7", + "7bcb541848f237e7bb8ffb141b87c48a342af43ab26ec8cebb923e36658093ad", + "9f072b23d18e83ca964ea6bfe6faecd69799c0411e46527435e0b33904879329", + "18855b1e0cf79610ed820e50ebf28ef77bfce5ca6ed1ef5f87e9223872ea6ad0", + "afc2ab2a1225ce33cf58c6009cc0c50a6d0c1f60ca7ea8523e43fc524e953b7a", + "91ff6daf8037f59e308c40cd6b58939869bb66c41d3e7122465ffc2083bcfcb9", + "269f850d8f24f63d70db7b6ba8894a9165aa7762bc591cdae125f361494f2c44", + "3a062d377ce1336a128727f31fdb5aa9300a0cce92296267b8b94b31c63a8d21", + "7c72f1fe92a72a759a4e3b0ca37fbb75400837498ce474fca60b5bcf2d74b9c4", + "841a5ae7cd5460ebb32ff2b98fbe48d7f714c7ef75aa0e4fd1e4aeef07afce8d", + "589dfc1a757190a6e4bdd311d92c009e842c9b1b2a0fada133e6fd77af1d00b9", + "b88a9836810d2bc8f6890ece098445419e50bec5c97a2c368ac3e38eb245149f", + "2d411651131d78bb5825c745f80427812fd42d408d22dc961d05b4c91c94f189", + "1fa72da1969f94ba66e9f87fec085d81c690eab1d89c73e076615b50862acdfe", + "78c5a63d6ce8d146644ce9b2b345185ddc8f83619a7011c7785a9aa4b64ad381", + "a8dcb8f880ed3de4cf374997789c8872188c87a97e5955aa031024aff7471c47", + "c34616fa0aa33dbbaa6d2bf5f23571b8fab7a3611f1990e348b3036c3ffe08e2", + "3e6859886eb967ce3764ad4009440ed4811332886a3a625e3dc8f1d55f14ba9f", + "124ab422c71a1d6db3ee0dbcdcee410c05f2d33f5fca106a0a9ec806c3a8dd8c", + "4285408e6fdffb266139627a417907a19e9eae77e9bf43c1e67cba9f346c5646", + "e103c38978bbbf91345a1a0d460426d21a6aa21b697c8968034a8cde5be30669", + "bf9d2281eed6fdb40345711ad1f52a8dac9c9b2840e78186e4791a986ddb8f81", + "ab7600e34fbd01bd59d849685e1ab62effb12d8d6db4168effd4e4b8b0e7f321", + "4ab7e277c150a294632d5725892cfbff1d52eea31a61ba79650e79c2de109f9f", + "ad385e856a870dd425fb7e6f824d57ea4da21996755e204948ae63424e6497a3", + "c31eb921a656ad442aa958de79f39288539cfb23bdc60424491ddd23689336cb", + "d90fc280fc1b6345a5f063b767941d16c2b84ffa63b79f60b1e94d3eea8919c2", + "14c9efcb00270f4d68b0753535ec0db279262b740db8c913a670fdf5e2a33511", + "a5aa0a655f4021e4d88286e21dc4089e2f6e83e4b56f770418b8796f6912b75e", + "66ad16e608d5a78fba30e55c6ae8747e4bb900788573642c0dcddfddaf484b8d", + "3bfeab8b336a5172a95436cc629a7d12752587cf7ac0a677133d71a11f2b2165", + "4974667b715b7b2841e95e07d85647e2787267f930762004195fb58bbf521e05", + "8c72742c179fd94ab929c9d31fe86e02e09045aa82c580b2cad06f29fafeb0a7", + "f87ed7a381cc613f4e9bcfb881e0faf020eba2d46d089e2f9132d4126d217ecf", + "45962f556987f0b697e8f50d3dd270075d9eaf0986153d421dec32fe9f116390", + "e784d7b849b2078ac5847a28d37508f503edd3c1d6ddc923978be67010cca657", + "ee3d45d82aa03095dba21c339540b0f84ec4fc14864dd22790294873a6dcd494", + "a896f1572193d998e51f7e4dcd512700b8a168de2650c25f692e8b60f450599d", + "f4a1210e99d95978eab9fe4bd3043d71774fe59494b3b31a3b5516b17af772c9", + "a823ea8aebf95969dddb81961d3151190ec16c3ecd3eb1bab2673ff1d49b58c5", + "9d14b4685cc8da719987663108fe542ef41bb6ef0f8fed69dfe0875c398ba296", + "84d0cad14215ed4f8973ef2973cf31440d9f1e207479f12e2784ce4f25de716b", + "55d482eea955352916c93d3ea92e69ba0a21d5494a57456ea89439f4f2025479", + "c64913ec322c8637efedc5fa61fd80a656c505e83cd371322f6cea4e430cae05", + "38b8f8d9bd02539f0f9c5ff48dd50d5f2a694e88daba258a8072a772084e8d97", + "bdc46e9538fd4872d5a8fa795c6155ee3bfb89a95c33f6bf51ab52812ff99c0e", + "8cab0238ec3dc445c8a9475fcfb237c059ddae185d45e9a97806497a121759d6", + "8f05f68a0cf330b5323ce91ee0a6d885632ea8cc131800ea72533acbbc886423", + "3efb20f853d92a095f48182b8fc302a2eb4cdfa7344787382de5abb6da1cfc60", + "2bb1faa4685d4138199855da8c3adc8fc003d413c04f7b459ea8878c877cf25f", + "63f815aa055c5f023119754a4fb6ff5340ce1f5338a1a023fd48247657c00c8f", + "e91baebead811946fe97dd2fb0295583d6316d24d65ba6ccc2da664f62261486", + "74da78caff26fb1866054b62e47fbb91f5043c2a4b258044ae3541b9c002a0ed", + "c11f52ba4d6151884be3a8b9ffe31368a183d37dfb691c8aa53dadb7d124b370", + "a589b5d081067590fd3710d979cc1970dc0fcb6cf39d0c9de06789e50301e225", + "faad42331c9447fcecf77bbc9f08a9a8f9a5d2f96f06e6397e8cc4726f9f0020", + "a844a2245fb808cc555cc12c779a2a99fe2d49cf8784f80327a63f418c2cdd83", + "8cd99ea599ba60c93976a243072656aa1a0c799967ec12002d293a30e2132ab0", + "400e8d63cf97d7058f6aeb0cfefada8bbab70d8fba0a39586e075f4d444b2537", + "48fa3fbe0bc5663bc75246dd57208081c48a525675a14b71b28bf3ee61c6b267", + "878797ae58f069e40f654c395b51d51f21e15902f706867e9f08e8e6fc81ae90", + "1a8f7a7b4d69d7f9abea6e2a625b4379224ca11d2c12abf52bd0ff33ce0109e3", + "ad5674c03359bb96c669365cfb9197f2b3ceb3f5cd9e72da8eab4c698fc45683", + "a1d6dfb97fc70948d69da2ff923210f537513bbe5444eec0c27dcdb2b9887ec9", + "c88fcfdc2d8e0a34a8cfedeb3ccff58153cf7ae69b038adfcda618513db240ee", + "22515d2ee9de02c505a0d58f3085e3c3f690d095159aa5bcd81d66174aa4c6a6", + "d871c6fc28bc6d5f9f168b6a8d820cb7fb7264a7f90737f2f17129b1a8218553", + "e5700454f128f0b6bead8e439dd4395f6cbc9e2fe7317cd0b79c0480f7fa2005", + "c42810577395998947b3acb65a2a0b1b1e51e4e9ca8983f9746730a514c8f364", + "3cfc32d7e24424f16152ef90eb6591a3db27c9ee0b979b30cddc124f1b7c27ef", + "09de6423ed07d1d296d9bab1e5e025885561d7b7572957faf480b8b968791740", + "80951385f2ed8eca25c52e40b2d53d5a9d0ccba7c3fe6844198f18a21871e514", + "4f1a69efb2eb132c0b33d89cde38349dcfa60e6ce15fa102241d6e43d0747274", + "1d59ebf850d0d27029d52edb02463ad2b461a90ff8157fa6d2776bf03217256f", + "be1eaba9181aa9510d10600a9901a374a451878a1e25cb24cf45e9a132543b22", + "df30518faf9860d8fa4c68ff509ff8a75156e3ae7b648e78e1127c96595e2fc0", + "21e8729a29aa2fdee92a11c158bb7bc1b8e62fde32050e8d9cf612aaec9e29c8", + "258dcd1666ad6649d3c15087452cd4dc4da73a2c5fbf2c251899f3ac5fb8a711", + "458c02442588d8df43dc11f3b75cabde527538a04f657f88c369c236643ce181", + "0a0a743e3ddfc2f83a5d779ddb8b8596e8e6ac13c1786cab40a8bc69cd0f657f", + "cfe7a2b3b598a83b961c1b2e6be5b6afc2496a909985d27dfeb74d5ecabebfe7", + "673833cd0f9ed9cb85c5fc3c7710bd174832f611cf255ff6a15862aff0f1e7ac", + "3583bdddaa92e10b11cf03630a6b7440f5e9610ae09737a9c5dcb3f21db278e7", + "3c5765b27e1e98681e0cd2e3c1600d5535bf8c7d2f3c3c5d66634fa696ba6df2", + "a0b77259902bdfc34d8ac51eff322b62a2a801c082750abeba85ba49a79742b9", + "559c77168e7249279ddca2e5db58acc27586aa18320950d3cb445100f17408ec", + "12471ba66926ffd40c6f6b9e58dc003e9868fd94e880db28d74dfbf05d514cef", + "3f02ed42de08288960d8eefc694d211fb537a8bf3ac9735859937ef461fd9280", + "3bcb1cfc7312410cc607064a4256c008c3c6773eb82851ae5d7762cd22153bc5", + "d55e029ea251d82ce12e1ad126b976dcaa097ee73f968bfdfb5a1ba635f424b3", + "b848f5eda955012cda01c9962ee96871f2ed1e39058b25230ec8023d6874c45a", + "22f41749aadefcf6407cd76dcac69467e7419a3228f8692c9a6742fc2eb47b57", + "56b18a4baf52af5bcc62fc51836cc0ae7555958b56ef24918456b95d6a42d149", + "c9b3358814cc1ff787ed9f2d479d65d33528d58ab389de5491014e23260935fe", + "cd466969d5b13a6e4b169b99a519841fca692e520a8a2526b2d962b0cb92778d", + "1b8296051688b55aa32964413b6ce80676f7d4176b5f7014f3690919586fc156", + "b9a34beee2dd3f9ee1ce8eec3ac97bf3508e9a71dcede1f63e514f5eb6315d31", + "05c5784f6d7e2ed8371eb4db8dcc6c60026f2562facb2eaa826b8bd88dfaed16", + "606b2d4048e4b955466d6f3253a8e1225dba3b5cfb938cc9c8cf9279890862c9", + "dad1e12c1e7e9a8e83e9c065ba8c3fb1fb01315dd9fe7dd8acfe99d07eee380a", + "e59ff8093f11869693328bdf8fb43e359de1e2d64fa55377c1e7da6c7b8560a3", + "600eacb90ef412c68afd7e915d8396693248c18145d9aaac77c8dbb3ef32b6d8", + "2e0ca4f2145463d8a75e6ff05c6cd51ac465a5c571b54cf62cabfb636ccf5391", + "f74e6f5138043f3a238689c1687861d2b213659a06b4a0b5465780d333b79a88", + "b051860a83584d0975a4b438e014bda0fa5a8f78798dd26ecc99570602d4acf8", + "030019ebabac7692e71f5d124621e61ccb78e8d975355d3bc733a2901c538dc2", + "f1761ad5e272bd269cfc27915c718565597aeaaf8cc2c5b7ca71d2fabc11bf38", + "f908fa46773d2e36fa6c5984e863222f3f2f5c66e9caadf2184bd31502a8bfdf", + "0666949e278f78066c71d82fe6b5fe08bae4395a535ebee731d03d0934a1e623", + "a516fd72b95e0fde5f5bd28a89da4f1f75d0926d813d95d2c4ceb786538d2335", + "be9d26ed49093080c256f10936c38c4df612b466a06679f59820f502f2a5c3a4", + "c2a1fb18e0ec0cc17b0fc999a73db9083d732c9ae94fcf06a55aad130a70e56b", + "536b50d788c3cec742845b7df62d9d2eb57f261d5cdaea2ab41a055ffc3dbebb", + "b19c574bc8243c6f1e15b38ea40376fa980c83be46b1773cc8d2bba856104ee4", + "18cfdac616b48ad6129256017ec343e5f58e751de7468ac0c8d5cdff0b62342b", + "515e37238630c3f7c09c935866723d6ea7cadacecb41ef05117153da1b3736b4", + "6e861de73a524444e86fdb0dde40eae1b57df3924f9e58a4d3117be21b7cbb89", + "751a91fd09c65833297593de72e37e800dfb90321b25402264bcedda5471be12", + "bf5990f3c4a65f32aad67443a38891b23ce9a4ddf676b3f068c038b42e500eec", + "5243aa3c0de8a73f5fa0a50171c22badd0150d05e4555f59582bfa1c07913124", + "407e51cb651c3b6b38599a14144f6b6e3501565bfa50e31d5ff705bf0cf87f61", + "92bab9ef80b900a709ae612dcf3f7a4b75c2b9dc3716fd4a46cd73dd822d2319", + "638404cacf54f79ddddac3573ca98379f758c46a5738df533bd231e73e1b0bb5", + "0ab6a921a160b131e9849c3eb071078fd2f89b7364e1d6dda1cc38a558ca4f9f", + "140df3f365e9eef52fd442718983fe72a679f7561a4a4ff8fb447c56f5a44f34", + "def3d3f4444b549ab6c59fe6acab21b5ba763665abd8910562c7d66c4c1a4d95", + "c8280218d9c4cb8b4c8e2dba4b79ac65806a47f3531eaee0c416d282e5896587", + "40b52d0503aadbf4190169f471b226aff3dd22d0c6db92d7d6fcc8b0f0b61da4", + "b9b2cb145105b0a8f178b65bf781af3297cf460102a246565acd9099e233d030", + "f388df79dbb0e21f294b4744ebd6a524b39a9b622b8b966f70f04a99a49ef65a", + "46b189900a859b5748ff57b08f893b3fc4ec86da1de9a70b5bc653a375b37f99", + "61f1ff547ccb2f9e92b8ae5cf1b9189c9e0d9b372423e164dc568a270e2e9e65", + "b484c1306c9935567649f6ea7a60b3a8457b2ded7a4446b8d73462fff8022b5a", + "d9a0466504bafe31dd2f876f19b5c30a7906ca7efde603ab0dc53ce9fb17dd14", + "caff39c7f09c9b59a9bdfd834e0ec2f3ae8d0acdc8cfc209f8f305f490d41e50", + "0c7d04c2b7fe3794be165cb7c5edbffb048c1efaedffc25250a77958a8274e19", + "4a0749e532bcfbb77a7708d27a429269cd646703c971f0775cf335061f07cbcf", + "6fb68411752d2f29ed6869e7c7a0b4fbc6509a0d52a35d14f6d7a5f39ff012d3", + "fd55337bd61ba601bdb5e853028d18afd5779e6fcacbcbe9e7928d9f29178cc0", + "41c700aa7dc0f39e54b0422dc6e901cc1cda614afe96a88b414ca5fa07911b6c", + "4442078b51b5ca806d4fa2d3516276b5d6fd0be8411225bf93849270d12cc894", + "00cb170dee25fea0969b7cc745f50a8212687a25541271d1d6381201bbcadfb2", + "4fae5251ad09f921bf1d5b98221e94b36d856a05a27f60cbe392b46e788ab0ff", + "5e5ca2da260a1630abdfbe9e63252765683ca2bfae5b105b77fbb5e3a3d4a9e3", + "2aa913cc01169ff40533073badb27553c97f37aeb7946811c175f9c34b43ab28", + "9c35106b4bf8b18614d9dadf9b6eda755bffdef32af88886c53e8054949af799", + "23dc0ad7bc252b32834c7449e6fa2fe0271e739d616c2bba5c3d6d48a6480d1f", + "f3b993053afb0f85ea731c7be0922abf40affd5e4f26549ae83cef2b9750c09e", + "93dc72dc1ca3b70c118d128547d948099ed723766b2249eaf639fca4c468eb82", + "41e060dfd483ddcd4d762eabf7beefd27697c47d1b874371ea4cdd0c36d7046d", + "e785d651b2a3874d106229dfab16184b99866cd675be7d261d20c0378ad7ac70", + "f45a292c09b6f0d3b85f9384fbd7d38531304035ad6585284a6afa8fbc4b7d91", + "80ab84ad76c93bde16d2eea2a23caca273e2621fbec5e88ef6919586edb5af32", + "991e1cfcd32d636cf85ee567dbad59fc39be7f3267ce1474ef95dff5852e2f7e", + "d61ff04012a314bc40d8c9d8bf958f3b02c5fff5ff1057f5befc24fab2c33460", + "ba0e97c8058a744186cafafdfe3c244a206d1500abc9ca6a4fa6a64d66b3b674", + "343530c9592c63971d864fb77667a23f6611a385ffbee53d82226fa4a3065bd3", + "d497a5803ee6b176e161be71a35565ebaa4962bc857e22d6c1569bbfdb2763a8", + "32501091ec184abed7dd5ed611237f13a153a45e8c81a988ccb6dc7bad683550", + "2ba89a6efda8a88e810db9a597e4a0fd3288b616ea3bac8492d7064af4dc3564", + "6fca4e2002a7546105d27b2058ab96ea85eac16f01f5685258c16c8f64a5ce70", + "61cd23ef70140b7b3624eea1cae45fdbf432812ff42acbe396c758a06b992869", + "b2e0781693b0bc004d8d4897618fdc759c65e999664828ff7286662b4eb0a0d6", + "ef0dbb1501323a47766cbc905e7f15180d522a2f1e424898f34a4b255207ebf6", + "e18737b412412923cdc24e1d17abec4cc25e24ca9229f6885b0be042924d2354", + "fe91e368e45ba8a6e7d18b5f440fcdf0a606877f1534e88c05b83fe18140a8fd", + "57a7fd72097f2bf08180fe167ed21c0a31df0fefe8557dc9de98da4aa4cafc1c", + "3a4e320f0cc39a52033e7dfab616e467f6a1b9068ad798bad1b9d1ae82d5e7c6", + "a348ff5cd7656be80ea82e607a215c35dbf981b62c9d475c370bd29ce7505110", + "6d65143d7faf599efbf99cdca6dc291bfd9b41090e0850c1dc7ff8b84236f765", + "ca545f7e4bb9bdcc022b2ab4b8a2df3dad38ab9310d9c5fd9c95ca8178bcc02e", + "8266b0eca2fddd7e124871e7c5a7e56503841196d86ac948d7a497d3249b00a7", + "0e1e36eaaf680178653d76eb5ddc6f1573393959744c3cdf4a16da01e4b6558d", + "eee980cbbcc67dd3f2b0b54b7815caab7d93fc19e01188cbc25ffd242f518571", + "c3e1ab402c33d314d252908e1e8b2f162d911fd5fb41bca38f0156786dc89810", + "b8a042d90ecd8fda7f146052baa0201d197d20c52c6ea70e25e1c5074e86d442", + "0c148cbdc0cc53602975d99210af1eab388b2cf722b68b4a288d67bda93cc2ee", + "ec6665cc54bb9f6627edfbe79a6d22766a9fadc30bdfb2a21b90a60f8746f698", + "82b85a911203ec70671fab33be7337e614a1c7ac50b234b081cada1329914ac4", + "ed906312b0071405879be3cfaf22ecf6cd60fd427219d509a8a818ae793d29da", + "f85a9b978084d53336a4ed2f96389fd8448c4fa400d3fdd260bcf0d62123c23b", + "3630fc71f8a7fd9991ba01562a636c22067cbca4b567afde97e7251df5fedbfa", + "22ba19726cb3d19f06e10cda5d90b87eff2b08f1f65ebba848e4c69015c48440", + "2d6396c9c1b31cc33c531c3e6a06396282ed123724e8869115a0501378a381c1", + "c2f3c658851d0b43a9f7dfa7004ab6c0f3f5d5a7373a92e1a8985ec4cf02ad06", + "2813c3053eb10381c306c4f3e206fde6aacc250bcc0fdce0a3a2f43c8f58092c", + "b9e6a996af5e4c768d4f84b07af9f605e009206abaf22653f195ba4fd35f9141", + "895346a68e3fb3e648c36c6febc7fe9b8f5e3f34ebc4e3ac02615e4b49373bce", + "5633e611af6f480495f7a1de02cd8b4a631645a2810276f5dc979e3b30b02dfe", + "25866c93a4c51a54b6c0524e09149ff0a60e0e5adbaf070b389297883a9ebdab", + "161cd19e518a0021f501503aef5df456721f8d9e9c51b505ae950ad59ed4e435", + "d7c9bef6b3ef2e584cee3e06cbc7c302ef7b3b30ae9e7c965307d781bf8280ca", + "ffaffeb63d98b0bd9839b898c5313afa1f056a18af018426d77a72667dba4fdc", + "810548b6f0764a85a7b6f3a8c27bea80ef7afbd90571cc6d8d04215638cacc31", + "d257e7ad68b56d1f126b0b81914180d06598877f8f750d0dc5d1a5fc11d9edb5", + "caecc8ebabb7e62611aaee1fd382b760e9bcdf75d4548df43636737bbb33d080", + "f846988f39d3b4d0c0c96f769542611de48b48ad101018836a8f0082b7a52dea", + "1cc3c95ecea892455c56cc6d2def184cf60e6898962f8d20aebe70eb41050cde", + "010b6f5c9db6f738da47a33a716645f5a492188a2c05d16dcb0f5d509a136469", + "02936095d5062b0ce5165c82d58f9f36832c54a91d88a2c82825f9256321aa73", + "983de539d3a2dc7b5b5d48101aaf10499680338886da004405d2c8621004e5b7", + "bea060b6acc229f459d728273684a61aec85b586efa432c1aec41489debf4bd0", + "e4282cd7293bbd01222bf434540e47244c1415f530f635b1de19346168fc3805", + "2808fcaf85723513d4b1fc5f40c4c2c67453b0a321035355bafd9a7bb4e0f890", + "278af0dbb227f8f5e6df54c8154fe1f0d212aee50025ac662ba163380e123a45", + "b54a1bbee80210f645085da2632e4c8dc2c4869c8d69e4b7a94af7429a6b8091", + "8bebb941b1e61264412f90511a2ca18d5dcd7fd1a194cec0348b4b77cab8ba18", + "3ae0fbcb863251a0b5cf17e15f3db517bb357b10096e7a3b500d6d178661f155", + "3d9f9a5925f95b907dc49ac3b3a06ae478b233a509488deed2627b24e4dc3c8a", + "2f7b671c8b70b4e9cdfeec29647e4b11448992b27f4cdb23dea49f14cb8152da", + "f9b244456f22ad0d11c0e14ddd9d4702c4e731c6ff02e82015716a9873cda923", + "fd080797aa9696d9ad8b0ede2efc6f8f233c5757362b24afa738ab675478369a", + "dc4ea3b798f0138fb7881be59d445f94c8ed22ab88ac7d939d675d5b5d85ed32", + "0df4339691c45bd3d967841c1370421fac9d89d2b877ed66d9e846506f28444a", + "2e8f4670d37c3f3e021157d8a5ef3471ef1fa292cba7a274d727103ffebe2b29", + "4f9d34281c225503959bcf80011cfaabbbe6ffe3c78bdf5417826d31c9cbdbb4", + "87d27866b8fe98ad80655d5990308a200e47cd97da1517ca1b6b2b4a5595d136", + "d2a00ed4a37676f95e74d57ab5e59290cdd98b2928a5e4b2d8ca3325a15264bb", + "cdc67fe5d7faa9fb4cb57fba4de9bc87b01e0ce25dac18a6a0fd590294ddd538", + "a486faa99bb287fab09de6b72248e26c9c31b08fbff388ea91d1249744b96cb8", + "15ee4cb925ef85390e0214c2555ecab56a714e68f5e15106ae566b8109ebebfc", + "8bd1fff47a240a4b5d778dfbb564d680c0e99a9b47decfa88308ef394fb26086", + "5374f9dba0ef8dde2f9abb3e1d7fe364767f2a6571566bbd05d4b96269adb776", + "d97a551c46fdf4fe38b57031a79076fd846adddb04afad7fb938fb0b072ce94c", + "dbacbf1e3fb8e0660b08c861f1009b340a61bf36c6d0145bea0fdc11a7d4435d", + "8151641ad914b6aefd95a065bc052667480f93f8eb59fe9c7844f89aa6362a14", + "405de8d21f79e523b54e3efb3f43a32b98a0b80eacca622bc28e904197f09f30", + "9af578734220d71f344a2df024cd0db69ce21d8d1ba2ccbf71441fef33a5e7e1", + "300975721c2771deaea11bee03bc564b1d67f2d1e4316f8d23aa09c3fe15b422", + "fb75272f0346a696236cd7f006479fefe99029ab2deff3ea348895481f868ca1", + "eea306cede63a376263b461796a6a9be3d8ebb7ab4646c7d5fbbc54dc387fedc", + "d8d3bebabed7989597e5eb5624ee2409ceff8e9e6d84c5073f4dee22ef9b78e1", + "6704d6b5b0ac40454c714aeea769dd1f19b83495dab5cd0b5440e29de8038190", + "9a9e777a1f906855e8cf55019af4fa925f1b6e346ae55b7538fe94b8a4480b26", + "7a47a9bd91b1d0b81bc490d347f3046a2d18444ab74f82fe49e5d440de70d495", + "526e8116a5b4d44fd18e7797e305aa5291aeea10937d5326715d2ae8b6ba634e", + "fff79f1be0386122b03fec1c33af5e926bbe33c571054bbc329db62a98e50bde", + "69dc6e6e6d75951250bdaf809a27ba7ceb0b52ccfb51446083bbefef71b80847", + "7302e52b8e938a9b733b8ae944e00b9b69e6573d32c124eda5a62c14728e6536", + "a5158d20ce410a42d660da7197003b8bd71745a07419c3e9ed5f6991f118bd13", + "fa98fc9839ea92364534cf823e6b3fbec7ec27943b3345a5a148d0be01783db8", + "9eb1e1320a827f136f4555432b3d8a6ff950244dab3c189cf4098e73112e6936", + "2edbe724102b1e046683fbb01b5b677d9417abaecc0653b3eeb09302edc99a44", + "045c872ba82df6560fa368b2976bb6e534aa1c0d2c60a700f34422cddc915339", + "969585b96dbcffe008dbae9bf1df64dd74fb8412097cdef3bb16599a1626d21a", + "87ffe427299ac7575923bd11b45f6290b91ab853ba466c0ac0ff19ef01b761a0", + "cb0668a5cf33ce202c86f273af1605ff001fb9ca16227f55a32fb5c9b42cda78", + "514f1a142fd8ddaeec73fb3c0642ec87a27224f8fa814f6f9917a68042b41313", + "40f493fd410b30504ebec89ed4ae329a975bd58097bdfb2f46805a9d08740eba", + "077b7991c5cc2370b7726187d936530b82a16148d313a2b34bd287dc9841cead", + "9bc0949f9c312be808e108ac011711c514da0c45b65efdb4d074b258473e0a38", + "2deaf190acd68ea18ae79034e1ea398aaeecb3d71adff915bc31dd6db6384456", + "a8fe20e8fc8f55bd4b6c511734f2391d0701e7dd16a8c061f8c3c43af21e5133", + "cd2f74a0b042c7c1c56582a7c563270b24ee719f93d7bc4ef324831ec78e9cb8", + "440306a141a380865f5e9d1a54753085dcea4d1b9adf5d46ae4cf39678ff57f6", + "ebccaf3eeba37150ff9f39c850a33a4d0d0c95c263acebf600b48408c6e746a9", + "53c138591c84da04755c71621ccc10573f5514413232cb6a0095df7551dedcfe", + "2dcd611cbecf2eac6f16dc5f4770a63ebf71985c863e9094cd6b55e9a5f62596", + "5ac68caff22f292053a8bb87c6cf7d325b7660e1f5aada35213f3002365ca081", + "d8370da768777e61c746d0a7acf6bcfb35eb38930514ce77de0cc6c616c45e7c", + "ee53f7e5cc210a24e32de8d0a7699ac1918e5e745c7c949c279d1c03f550fcff", + "97abef5f37176c037072c0f49d0b278bfe3dec7174387d727b5bb57050a5d80f", + "6d7c651ba70ad3c69b40e538bc6734d19070417f2386f676511fb597dde2de95", + "236d1f48a15eb4b165326a8782391c1e5cf59d09a5c45d149ada8aaa3d09f411", + "dda722fc332263846b817f99b8a81811461b4612e8c183052f6cce4166ec4c8d", + "180c2d538ea77004f8aafee5bd7475b0473d4c47b7fcaa2a9d0fe8ba50f5fb6e", + "49de72427afdd8354c0f2c8d35c7ce7945dd9685f53236e009b7617ab7e5b954", + "759e8063c2ef3b024eb54ac1b58146a54a5ee0434c15295c2659439f6c9edb09", + "766453df0b5805ccb607cfbb516d41371a435e26209a3a4e4cc91f165c0a29b0", + "b6fdb56bbe2310e91485fc7ce93d9e93fab5dc531f248a19fbf25a4d645cf671", + "1c3cee0369c347a5655d725c4843de15d272137086d8b2bb1eb7f2886aed08be", + "f8203fab78d4f2604b7655ad1b5fe87b4f5f885bcec0aa7f27dca1d3a534b4b4", + "e4c17cd7e0b2d340f0073d13fb3ab6959b8fe371eef5715b7d0a694deccf4c80", + "d74d0b267a8be7c7a4e50a6f33eaa6098a0dda87aeaf643a53564fad7ea77676", + "fdaa185d558b86a2483b3859bc86256f8a3da79ffb249fb4d17c97cc8f1d744f", + "48d99904f30e6cc22e52b1adf5c5ced40e6d3282ca8464ca5359ade98af71db7", + "71ee3d10a220785c37f9a17b3b91133ce31a4f4b2323254e5024ae484b4ba676", + "43eb20a65b6bbafcc20e93769cabd593d357d2e9e747d72b19c3fc928c475c02", + "b7e7c86a12ac9907bebe29836ab5d854ac0e2b342c232769011c34b8d4224987", + "de957fb4d822423e64d4e95827bdda80cc481cda5bfd736b5cf516dfd5ccdbdc", + "6e17ff44e40fdc48d1a83e8bd4aa8921904e4b6691b1d4301922d0ee66e41c56", + "2518a86fa9b0363bd23f054450a62c5e81263eedd5ad0007ebf95a637f89e639", } -const mainnetPreverifiedHeight uint64 = 14464320 +const mainnetPreverifiedHeight uint64 = 14527104 diff --git a/turbo/stages/headerdownload/preverified_hashes_ropsten.go b/turbo/stages/headerdownload/preverified_hashes_ropsten.go index ef7081fabbe..32c285427a5 100644 --- a/turbo/stages/headerdownload/preverified_hashes_ropsten.go +++ b/turbo/stages/headerdownload/preverified_hashes_ropsten.go @@ -63224,6 +63224,145 @@ var ropstenPreverifiedHashes = []string{ "c92ddc49e13f77e4444b251feadd5d5d10ea30e13811dc8ff8b0f4b88283c872", "00969c6671e036f27733ae37204eeb947cc40f5627bf7b80ce1e4cb3e4460e04", "b26cad8303035a7fbeec05a01a9af13733cb399f1e969ec5dcb5916e297a9689", + "e182e8b37bf92e4df40191b012629b8d6f82c03b82f9fbf9f47ef5c0c88ef08d", + "09ebe4e097cbe7f6b55caf3db7c3f09f5390255df34044d7e3ac5efe7aba1fcf", + "85862eb6f808014986b0b24e3e64ff6913bdb97efff0f5883ca1898294173db6", + "da905765a2994ecefda6752b039512749e600572453bae2920bc18158b34c8fd", + "65f2862fba8839c3c984e733fb528c7384a90c39d9e50535a6d746a67938dcf2", + "a864fd76bd3eeb44f1fb6a5f1c222ecfb0bf9463d9256950e84fac019fd6e46c", + "a69773636d67af6b1d3fe4cabfb73b1816f7423051899559c9760141583e9909", + "51b8d090bb6e3ac2bcd3507b8fcfc82b2617202d4c7919ee473a5ae5e8a878a8", + "bd3d4bb54b76ebed24ad2fde294f0c07c647b26889971e5ecd1aac319ae0c3e6", + "6ce0ec8dbc34a869a211fe7d4f5216b41b11fc4bd3d9f68926c9f675699f0f71", + "f8244bf0f30f84deab04872b2bdc13e895d0f3d97cb2449f62523bce324fddd6", + "3651dcbe56aaa4dfe6cc207de2994a10416c2def1572a90b9750f88fc7768c60", + "bdc4356eaa138b22b4af387d90b862ef1b70ebae452ead90ecbe0cace89e4574", + "4ea0fdd82021e5cc6201efc6af539f99bc7309c68206bfc16dbf96360e6cd210", + "12afa2df7b6ea1418bdadae502bd3071ec48d20973bb6d35c9d205c4c97893e3", + "7a43f99ca3a66e667ad89caa3fabd1987aa27e603f9776225d5fb35dd158a1a9", + "c0fece8b3ad30175038b02e9d876f3f425921616e1a53866fc532b5929e1c54b", + "a3a6150fb8a9837608c2afce9440f891e95f2a6c1cfd6457751dd32e04210c1c", + "d0ea55a79d06a6d0f183a2c36b4a7fe1d5feb12d6d9a35aef941fd5a9021de09", + "464a624eab62ad132820215d1dc9b87732e7c5e1b8c8f66daa5c1cbba170d500", + "271b569a626092993eee4f8184fad4c64f49dd4edfc4352abea025843100bfcb", + "21a61ec85860c50518c10e33bc5039222f02a137e49ee5e8e353ab735d4fb3cb", + "b0732000c6066d11cbd71a7b5531210809657039bd95974b0a3f5264d14a30a6", + "9b83da85c601151a8cb4a6366a834f058de2a7e0af300cee01c602c1cfd4f86d", + "0662056c938834da9404b9b425c727ddba7fcc2f06735e95c86e784a9de90624", + "5d30a66f290ec99a43b06e800a1d77f3ea34f439740225ce15da37f38f11bc10", + "7a839bf0cc26cc0a04db567e1115fcdc72d901eefe842e3fd57c6e639c69457c", + "a2ffcf4cccc7ac9f4c5b6dbe89c9b0a8070e0f24b3cdfb1b51cc4143105244ee", + "e0295a50809d959e9ffa8c1bd32f4472a26ddedcd362d6b9ea24b318cab3c78a", + "4685aed508baae57b38466e15d26aae1bb3b7aa498368112fab7382299e8f81b", + "ec6bee6b486c4a42ae978837e1b46e129ae90698e35597d0b68177e07c4fd290", + "b5465932f090a914d7ce594bcbd7dff63a003cb0f6433ac792c2e8088fbb1bf5", + "5c0c64987e553dd439922c4c7a806949e60ef133e10609c9cc74d990cd35f003", + "70d8825136756e616138825142cbfcfad9f0ca241b304805e5f69bd835c960da", + "e502d3087d794bcd54dce20fa7c129fe43b35226e1f892a1f83485b07e574cc7", + "7188448871eaaeee026a9fe792c56ce2fcea15a0d15efbca7d96591ce49a22d3", + "e32273059cdf8474c0444d1e0f2bb91851531cfe11e8193f459c364cbdbeabc5", + "78bc4f6c07f5677bd753d3956560b355c0e69f0cf0bf1b8febb01f7b527abe5a", + "06fd6d552d54e13a2548fa5b13cd868214ff5483fc6dee69627ddd2409c891c7", + "e32c7b90f712c02ffd169276caca41a20df9c1baa4ae35600e2f683946e634e0", + "50ff823f5255a142a24f8ce214eb0335a28c44f9c6092c9b255bfff76a8231ff", + "c7669e68f38038f821db56fc52675c508e07bef0b17a53c0d97dcedc09d04293", + "88654272009451746e3b177cd7262d46d753f073b28a56a1e265141de545e646", + "f8e38e79eb2a5e6c4a255d0c92ea4273f49959059008672063a91e3e118992f3", + "ff58ff469ceed9b2dc72a7742c3f9dc62edd36cd233e305af20f097101f18e6a", + "9099e75c3b2beeb80557fb7c8cc4f56bf15db19c1cb95c599c373bfb2dc93ee5", + "23ce55bfea2f635da6c16afebfa4e7178082f351b97c8aa45494b2233c25aa2e", + "21ec56e7e798a5a2cff6826cf02a9d25431465d9d05d76973cdd1a5097281d6f", + "b56581eeab3bb95f1f7ea274d3d1ddf7c4475c7f2060a0375b0b3de543a5d3ac", + "8abaa879d09fb48c90970f59de113472de90b2bf1f8a897f36cfe280a60d8bc2", + "01fd918852218b5d6d4251a66a714f807f71de02d8348c1854145b0420676fbd", + "ceea87337326ca4c6239486433d86198243e900a0e58c161dcbb680f4946ac85", + "31dca51ac1842e214f7667b87b585046cf6c9c8900fae61cc59fc20b78a23b9b", + "8191bdecd7f8d18d2501895b706077d7f80a17c8850ae7babef873b95110b396", + "dbfbb96d5e792417b117972f3e503e23a17c0518747cf7e9637e5e6aa00d5eaf", + "7c83a45b002abca3f31b1ee8adf59c19d8a0106c5dd2dd8167283b9108f9a202", + "1ebb341d7f05a8652ece94681c256975bb66971d954151b59f3e03d9a5d6f5cf", + "3428e1c9be8005315c7dea7c7fd4889cdabb2b5387a0acd6b8e71c2f6976f9df", + "026683be3091db6bbae320c4c00d811fa6de0e7ccf6863535828f8fc9076b886", + "db4475010b29d2b40270e876140d37d3fa3cfc33f7900cdc077396ac72e9e427", + "3fd9056055a4df62aae842526f4cc427315e72a260738641e7cb3f660f2bacfa", + "56b9654d49bca76604cb99fd2e77fd2ab5c5207eb068be9df180f6cac1d14178", + "0de37ac9b6316a306cff5639409af2442844b5fe4f88d38e56b818b5da2b3073", + "c1ca15bf70e83b29c2fe930e7222b8a8e80eefd59f66795cbc1ca98ea2cb8f44", + "eff973d4beb69e3dff6fde5d6188b9f0b526ac0c6b6bf14146f122ca22e1868b", + "7fe5e795783f1b8d30ea9277d789475759810d997df3c93947c071bd5b81dc83", + "d8814050af840ddb1c79424408e0e9a3c162635bdd760d3db15986f146be6801", + "488227f19b9ebed1bee727cc8afa2f05d214210f27e598bc7a2aabe59c9e0e3c", + "b753945355529c4ad9252b8f287531ed416ad07f51952cb226218bf864391e94", + "a7bd4b665573d0c07a2c56620ba32495427ecf080b9dfb595a26127980246978", + "dd19ee971a6e409b7041d9ee2915f2bf7fc80ed437b6a18affd33643a433a84b", + "487fe2ebb7e2a4c481ae63138ba0e02e16b180f284d1947f3b148ef3cad6e842", + "60b6d4d43c955e656961dc6a7c8ad8ccab27e215588641edbed32ea8f5165edf", + "1070c56c4be35f1164c466eae7f62ee816ee77f00045e7bbe667f16d0a5da116", + "aed98492080a6c314bb84cea26a55c59061c606de7a844c8404fd27e2eed7239", + "662e5e142328b8d5560e8db5b294672641158b566077ffcb85eed1258104e96a", + "bebb74b23d16301cff6cb697127b7b0ad44b148f1b4df39a5019f4f3224a54d7", + "08cf496a7c6321db0177c8c3579fbea81a6714e48342c3c0d8fe58dee24d1a35", + "4725420a1e675fad3075c6d08a9a4d59ba3556439512774bac4e139a3e015246", + "81462930c1b3c6c28f034fc6837b6c9205735556541af11aa1c58ee96e4f1471", + "43db421acc6b9f4e5312bc718c3d84db3277c6e6b60a143975b41a61a8122eba", + "5068cce47f449a5b281137002e540d7d8bd7b7433a1309a631273db1805b11ac", + "23f2b06f35fc6126a74a47e499c20b64aadc84df2aa5008a901f0351cd2c5e5a", + "04daec52ba0ddfa370b896b3433000beea30bfdb5c3941ec277fb174d1b23680", + "0c486444239c8f43494f26bda574fc14bbb0f6fe7f09d62a7d7956ef824d1830", + "87b19d0473e0c6e3662ae418915efe997fec11779fe0f07b561401dd53104d45", + "16fe68a09baad22386c08f7789aa17d1c074f77e7703967ee59d2bcdb9a06887", + "b329a0758b913f8b8137431159f62b1f7d11e9f738a1e98f76f2bc52a55909b3", + "d3dd015d87f57af93197ba93e510b6d752c2042e86d01f21fed7eac2681e81c7", + "d6bdaadfa7b6a9c622cea87dd004d9b4b3ade4771077b28833d8496f128e09b2", + "42af02c98e5fdda1034dd8f00c45d9f7ce9df06ef5772cb12d2c7ee2dac7d15d", + "9c819d8c24349e3df5f7acf2170e07665c1f7b1020b0d8a69b9b04f90491ce69", + "650d39246bff8366e0977b2effdd40a5db1c7409f07b57ed531c5b86960915be", + "db9dc71a27731f9383d4f9b848dabfeadc6aadc5c72f0e61febd94c9f952eb00", + "9208c58d4642bf873935fed634aafa95deeb1fd086d01c742321824f7c05c1b6", + "8762fe3792fd3ac71da8247f4cad4c6b3f7671896a8d947744b5818d9bcb2554", + "c7ae5526351cd1921554284712e3d6c139de1ca36e80108506ac5641f1b85873", + "b7ff3cbe10479f60f390a4a3f64d027a9a6cfad37d5884a6538f7f8cbc68505f", + "d5f244d90317a8161cad93d994f4abf4b4e1adb29c6864035f5496f48e02cfc2", + "4b6cf84e8a9fc307f28cabc10c615e131719b996c8a80f8163ab2a3748665bdc", + "c4083da1b6a70d1aca36a6d5399013dbe36aa2ee180213a7f3e047742641d330", + "421511ce773ac744b0d276faaeed45bb31180970aed184815d4e0c5088631fd3", + "fb94e8635e33e0cea81d6e11039ada799a202bc3099350b71f4d3795ae123d6b", + "395d4ae9df22cd742598a8e6f5ec0fdca4a2b4c947f7528ff56b0421d89cc6f2", + "3b8cbf0be31e369e0fbb3699404e78b92659307fd219191d6f95d2bf8bac504b", + "c682cbf02daef56d0dbe1c8a90c8f93df205ec75b0920e18f83fc145292c7f27", + "c9c65bc1cec5430eb3aac8282c478670f08d78b2c9621900b3e3407fb393d61f", + "824e1ef9b5536dfbafd10d50c6e0351fd28358d2adae1e286b36480d1bd8eb54", + "6df29f63b7e2fb534f411995ab5c3aa8be924414fde00465453116e2edf10e89", + "4b8c592255a6fd3fa83170c21463d6162116534f531143474054cb7f924ce435", + "870db1b50e2d1dcd76791970722fe27ee7618c1db788336805cc0eeea1f3f06f", + "a2031e86a656387f323dc6e0c396c86067b7571503151b8fb51a8040ac994508", + "aa58f08c583f9d593e0165b92897a4da08855239367ccf665b76411882699361", + "777914d36dfb54cee91e2fa151089cb58b86eddf401e620d2d48a2e67ae94b2c", + "b61ed7a38391fc2d1e870eb2b2d1ea83ee5e64506b36d2b1eb532159e3c89902", + "9cf8fc4d3023adc8801865a9882bb684c0615c92e76ce24a29cc1d3eb46a81ee", + "6984b36071cdb8d9b7a2d1f69dfc92634f7930bd10696fddcb6ad936e724bca3", + "4d5eab07fb0540740ed317f080d07e59621cbfe6a50a1790f10613ac1380f867", + "4373b77cc89a1317160ca1bdac642be9c00da832bfbaf87ca5e310a70c2b7e93", + "40ab5d7cbd3938afa8d1fff32b527201c7e1c678441be6ff371b1d9322e4a3e6", + "e5cc6e9a3b07b1888f47e92573f1087d6c0b460fb6a09cec28d808646f918807", + "898f62f78d49205f4244141e353c373f77ed2d990d9321f1c14b0a3c3d6ddded", + "fa611be5622ebc6bc245edcb2d0813e4b67cc17fb09cfa181d48397a2b31384a", + "c62b9a854673052e8307533e6364d365dbed8a4ba787d4be73a16d4b8734b98a", + "445f64e8d0ba088e63f3a1c72ab24d05b7ef518373f4fe8088c08d70dc3f7695", + "7f01d6b43741ff8b435af481a9d925f5bcfb7304532ae98f7fde662f1966e3ec", + "65b79123b68b9bad7836031da68f53e8b7d680bb3cd4b94be6a005de926668ca", + "a081ce60c3b1f658d1a1f86be598933fac06dc6ab1496a0037d067a7fbf33a37", + "d83d5684a012ff88c1aa2259964114fc5336beb19c26ffcb7eb74d530f2ffc06", + "82ee17690d4194c2ee94c4b8e91f9e57f00125bb5758cc7c4061329fde8f5696", + "3ada453f7a6b210f57445aeeb2987671c65ba6b1aa9d7e90f4183d568ea2b726", + "da15c550d8eeb8acd42ec7487aff4c48823dea2a7ccd7e298bee6db2f43c92be", + "fa01d8d6f00d123bf453112351612af428cc473a12b4c750cb42e6362e3441c9", + "e80f1b5dfa89d425f3162c93cd30cb569712d3a214ef989f784535debca97c5a", + "9c2a6d4c7978098e5df05a90d083419e31f553ca982eb1c5fa96666aa9afae41", + "bf5bc1c9c63e2a907bfc74da18a1bacee773ee1a69f13800581ac56f9d053a40", + "be15db426f563cc8df473037faa2558eaacb1638a4bd4ab2bab052782b9455e5", + "88f361c33fb310a5ebb116e5d0ef13455c1ef2dfd007b5f7781c6017f8732d55", + "57101ca199446db044fc04ff4b3d4a6bb35802e17291a8f0f5f5abff6a496d7a", } -const ropstenPreverifiedHeight uint64 = 12138624 +const ropstenPreverifiedHeight uint64 = 12165312 diff --git a/turbo/stages/headerdownload/preverified_hashes_sepolia.go b/turbo/stages/headerdownload/preverified_hashes_sepolia.go index 5c0f811d48e..32855700c51 100644 --- a/turbo/stages/headerdownload/preverified_hashes_sepolia.go +++ b/turbo/stages/headerdownload/preverified_hashes_sepolia.go @@ -4048,6 +4048,333 @@ var sepoliaPreverifiedHashes = []string{ "440b6315007b402ad72934bcd32a44826c926c33dad0ca787b5ee05d952e4bc2", "ba8ee8e4f4bbed5ccb2494a3a65dd56865906b1953d1830ed4f2bf34cb5633f7", "773754537d3b25ddf8826d23be023edd49c8012ce4fce03fd98a2e6606c8c5e0", + "dd7dc234a537af1588a81abad556d8338142e665123d52d75b80b05ae8e595e1", + "723a238285e11968a60f7be5bd078a6deacaaca36cced4d138d5a06e751ea0e2", + "0e2ab7615bf6a978b332dc6ebb8e1683a43bec4e2059d52ed633165bf4dc1f1d", + "9279c39dfb91b6d56f7b188ca0f3aa693614f01951b83c485812c5324b62468c", + "467a231b38c6aa096c29f8c5f20f3f73eae6c7128381f962a4177c62f6d37595", + "6648a5fddbf2c1034abe339f98faeb41091880a55c98e5de3707804b44a1592e", + "f993e1d7fc6779cfb7f284a0bd75682b4941aa0dbeb65d3cbdb4675617d0eaa6", + "c0cd33e99ec972509fcef35ed0008210481308a0c9f82a9071e42bb14213c75e", + "d7f484efe309959a19f68239bb12548bc1e64664b5d4207e8a936385e4f7ee8e", + "e6021925d13749440df3f04f835f120a10ed4f473f079d18b3243fa4f09e4e04", + "431708f3b8ca7b64edef29074dc06dc1cf2777e5128b74738cf701dcce26e1cd", + "a7150905f63797437b534666c7d5ecfcb8e80b5cab477ffd0cf2a76fc79953a9", + "5d79209a468e317c30945ef1a39f2b64a8417f936ea6510fad409182bfcb1f2c", + "35de0ec4f5e75cc695bafa320b8e14cba3a7fc3e530272d0dd5775a5ab5678fc", + "d12bd6ac220259af2552f1b279005f02f6a584f629ce9cb9b6b6012bb361d134", + "c70917a60fee9b9a1dde8783239634db80ea683ac45cc43c46bbee81f68d4fea", + "2756e3880ced5de5d92acdb166e464a9dfb2aa08416137bd40154f6da1d7ba17", + "fd20690398c96429d1411261aa8771546efc7e03ab65e890fd62cf9a98829bd2", + "20f17c783dae695fe01e9cfe8fcfe88797c868d1a0492e70ec1337fa29e00b86", + "a4d3267cd410ea05416192c412b046104bec1594a5f832cc967d56a1b3615cff", + "54c15d5f468428a7804d8907da35edcae7b3c9c75228b51e5bc0d92ebbb059dd", + "162128cb1b9d7e1860b9daed213df6666f4d6d2b01d0fbff913cf3de8c37a50a", + "08a3834eef918e7c9a9efb77440b2f6d2ad93464528b7a6349d20339ed274d15", + "6c6aa2b513f0d90a790868e28ade6e1520e73b41ea75c2775faddf1d16f77fb1", + "8cdfafebf8a52d79f31c929a0c56ba8b3e73f89f1fa855470e13df69d2e3b759", + "71e6bae5f6c65b85f0d84920c8df2f4e77c3bab2d0c045e07a1a50af2a89d8a5", + "51e6b2df0d4366d5664024d7767b82f91a90c2c7079da361f4a0846933d3e322", + "621d80c04e5bee46f7ff9fb9929edcaae0e4648b5ff7d29afef929706a6ae8c7", + "6086e42af48356469b0bc4db93464db4f90f53f5e7a9ee967a155f556282e26b", + "9f32fd0c111cef20347d6730b9e51849b156cfcadceea6617dd49c9ee60a4752", + "59ad22b2a1491f58bdd28051f36de5fc581306705d833693a12555d466330eb3", + "e991c823f692bf606f9256ba49e4d88b01d2652e68f37c71ff14deb9e2126052", + "5883a96952e74feaba24fb3578652338789561f1f80983d7ecdcb3fd36fd188a", + "bc8430d48aee9809bb95015ee86774c113d8ebbc5e59531c244d5993b690ff8f", + "17c39e98cebe3a9d475dcb2a4dcade129ac8d7b3d50cd3e9ae764af0b1183235", + "a901f5ae569659370e91055291ecfc6232883a4c40c0ad03dec000046d123b9b", + "32bc27f4888db37f08024e4721713bc7cf131f5bb089db8292728f37bdeb5678", + "a583d6371f4dab8c25036f164937ace7f023858874e16dd172579bea5b381e43", + "ae3ad53a0000be9b7cf8b489f9c88a36ea3187b6380b6091254aafdf01f1147b", + "c18dd0b7a27b2effdcbe15330aa0c9952e2198f7db61065de307cfe85dfbcc2a", + "ed06ea040247b73ae228ab8ff3f788044e6bb2e5029c1d097d4de4d200ab00b5", + "25df1e1ddad2eeb4b28fc0b04861c53af30197e21970f54da2f401896522425b", + "35d46587239b4f5689c1215e13678ba97a028fde7f2cd69c87e04a6132a4f83f", + "a9b3439ca0233f8b98a00b879d262a44cc5899d54e28b630876c2265e71e92bf", + "9c301c160af3a410b292c82cfb922b57c5fe01379f42e5c4a157ec6453010d94", + "594d6993a8c613f979119bc0133b81cc4a90ce41e9bcb36059dc736223bcacec", + "cc388286d3de603246b1df9b6c46a9a768b2de1189e1a3ba882678b8e224a671", + "0bdd7afe8a9d677964cad6817d89612846f272307d7fb7220c57df95f0f11aa6", + "afa26c187f1f757bc5698daf438e6199ec4d382860d3a973e22aecc6631b2d4d", + "18f413b4d67f776e4bd93d43a814691c127890d5084fb484ca651a40fe0685a2", + "3db4d678ffcfd0c0661924e1a6fabb86ce32092b2a86cddd5a5af7e2e9ced2b9", + "c04b01ba06fc7249a98d1bf3d6ab4163000f780ba55f6b55497fb340c4ed5dfc", + "8cd7e18410d11ce0695e291d2fcfe06a1628c52fe1de45f826f06389456884f6", + "5b1614bcd3c6f44fe7a028c7196072500e199699489b51cfa2b2ee1117a5aa26", + "790a9dc159b858fba1853336d41831fa5345c6c01cc43c636661a95b7462d4a0", + "af1a5063c3b2d522745710761282eda95c1fce0b1d79a32eadfe70f43494ccf2", + "0e19c7b504c8fefc817199c457478df383a3d65fbec661fbc6b355c18c79fbb1", + "5d78a30e59d4bacff90179b43c0578287407b58037049feacc0eed2be524816a", + "c8b06b99b3c2eeb755b92f8b1a037aace21d91abaef27599c82540704cb60b02", + "a7e799295ec263ba75b0ba2ccb88c709708794ac06eea556acc27b6f2c3b992f", + "e438f1879ac62ba3bcc02e835d79b59b03c1202f55e4951bde7eae2d8eb28ab8", + "a03f5c453415a114401f112ac006858555322c64976f020b1aab05eb0b2d73f0", + "25652d5eee2796ca595d88df255c5b4e1651200dd616e08d7ef222d5f6c67114", + "5577a6833215fa9f9de840dbbf0f05d7c38a0f7f9500f9679688486f529aa3a3", + "aea9da8ba4dae7c32b25058a0d62e9ccdbd25608a9972bcb21adbd6ea8638ed7", + "a56f6a803f69c0f47e9806fd8373d229b380fd5834d4ae31d329db1301e1b7dd", + "3c6a977085be06e4294d1b7f0dc587a4710e7445c21ce303d74aefb245f11b97", + "b0ba676e99de6a2a6082e8094d60e4e375fad60ae094b98c1421da6a55ef39b7", + "b09de71f426bd708d34ce4db78a11d1c2ac50a5dc7461c0771c846b0738a3492", + "1993e67c15781cfcf5d2ac376ee4460c7f6051ab9da9c5427b32b0dc1e0daf3e", + "a56831e92f95301567df80b10cd7efa0fb377860d7f227a6f2b79e53908854a9", + "5d065fdc7e53c5cd6e1e4e4a8a1dda598e1c38929806f92072b169a9a1320edf", + "9c74a159f607c9a0ae3ebfef44c4a434584987b661436513e6bdab1253241863", + "96196adc25c521f570600de69b4e1fb4607ed34db53929a645dbd914b20d2821", + "0464e9f6dfe39c14f4ab9d271e19cf4e8f5eec5c5c6e49f1430f3594a1e64448", + "045a45d6acff230c46d3e234a07d8022f08afde39936d6c474ccc6503baef649", + "15f3c27d2c3f0d36b9e0bc89ad1c8e6d372969223b0f97621e860889152f4a6c", + "844f110fe17bf2e3f0e899ca93b2daf622589d086f44231f81d3900b2fdf15f0", + "48393367b8f78a51351111dc578cd82fab71ea4ec3ea54989556dae7b7067d90", + "321f422ba65a2be26af2eef38c9d83a5b4ee56f9660183a81578458afa977615", + "debdc8c8c776742c12e82cd946f4952dedd5f9a324fa5b56f950bb317bd7446e", + "74a64639ce90b19db51901507fa949950c00881a659082430f06563334e87054", + "8bc20875bbda4310e2fe230387684606ad211dbeb8287cba5d0de59bb8ef98db", + "150d15c91f49a83fd2f096c66c07f22cc463e7a2e552cd277de54fb770101f76", + "c718de14029684cc8729aba659592a07d774186914063a6277cf8d7f24f3b933", + "aaeedeed8513c85ce53f7fadd89642ea1b379c3887f71857c8c2cc21d2df22c9", + "c8adab02350da67a2bc6cfd08158a049137125c1d1040256bbb1a6e396c14037", + "5c51ea6751616309548f8279a6210f34baaea0e07b8e3e92980a5e986633f93c", + "79cd3777f4db5a94386bb23b5a76f3b1772ffad2dd8a89dba8ffe109476cce0c", + "e3d15ec9f4ddc3e8dd033260f571b0be1b2430d20ec1dc4984681860b4fea1d4", + "32b1b54bd898720b236f822c021edc0d63917ddb95056a2008c0b854ab612ae7", + "54c6e8a63f6784ea46f67d30c307a4544232ea54c5ad612147ebdc3633dd5ced", + "704bb5b59d7558c4e445483e7aca204e692af0edadb35770a3124ff67c034832", + "f5907ed272c2aac6ef52138df99fedcee3e12c0b945f3d330fa014f579f98af5", + "45e5ca774176bcc08db6de60cc5422de0986f3fb217f67ae8bb37c655205ae25", + "851220fc7911c2bc82b12c81fdd1208a9e7bab580bca1a31ba9b3d5ba78f456d", + "8dd03b885e074bb2f051a665d409cb48ef1875d7cab232c6485c6b6b0869af6e", + "4beab0a4f8321fdeafa59cd74c7e833cba6dfa1441f16af59b4948cfb23b14b0", + "24c912aca33ebf70de7363027c33afd855607678ca1fae4fe7dac8613ae17c9b", + "2fdad28c615f4c980ec68c195f58ba625d104185ec018f9c3f0ae5c48e2f0461", + "82c639c3f53bebc12ae8702906b868fce8e46292d9a74cf7361a67f66318aeaf", + "c9a58d38b61fa13a17c68dc3adb2442f5aca10ae19e03a988a34b6071a9aa967", + "b4ff416f585c0bf393b4f95363072c1a8ffa3f34728412a09cf420b4417872ee", + "1de78311517ce8bc92db142935a863f5e34dc10bfbd7c9cd4a312d3d812569fe", + "11092fbb862c674c7c2db8dc930bcdd869cd294e931a94e0804421eb149081f6", + "1aac1fd2a5a4373baf4e84ac0d1c74a5e9c46930666470cecaba6dff61d58e7a", + "cd5b39100c9aefa32cb9d38ad08e4f81cc0b7c43d0330761887547845d60611a", + "e640110dfaa388cc5542e4bb875c2e40ea0f92e01554a595f796b23ca7fc798f", + "98170f264f1faf7f641d0bc6d986cdb350d36043e3de65ee1b19ef4eb69c7c66", + "3e6670ca7baa63f70aabc3e83e39a6aa85ae3aa953be3379d628ad66df28830d", + "794b4e293d89cf3bfb19344ea7c83792677b8dfff2fe2a4b9775cc4fae6d8e38", + "255d73448c5875b8444a2dbc19c884b4c249eac00fafd10d2ac672e85407c29f", + "fe1429dbbabe6c8a1b8bdc7ff2c556d95fb6c730fc1522c846283bf42e7d8707", + "2399901d579181665aca51e5bbcb13cb63714c521200b3e16242c12f7e1792b1", + "203f3fbc5791e4fa3d11cfc2b1dd0b37996bf176b7e041f728ca67a68a574767", + "77c5d922b1c5937985d19069db90efe87cc213321612235d18c21597de2485b6", + "8c23f419937ab8237feb339156b07a8a35a5c1263c65e7137feaa53ed3776e46", + "010a436e9aa445f2bd121af051a8ca3932baa9e31ec7ed8852c2f7bcef5d8bf0", + "76d4b9506d3c1d46e36acff85c8ba2816ecd104896b3358836e1e41bdb7fed13", + "f7eadb648b689170b10944e227bec1114cf8e2a00b20f5e88f7955a16a206c42", + "a59d500816a89d70c312cfafc6aca2965859b7c5c1a6ae48d3cb0c3a355ec80c", + "633646f44b5046da0441a7ddb043888c4c6a31fd4d39e0b7eceb7eda29423527", + "aca3bc98ec072762658562dac6259c48d9f2c1c819e754c45ec1873891f514f9", + "cad2128df96903f854df919b731f9077a67ddf93d79d04ff59991ec122d1864f", + "3f48b312bef1f4f59cc066a7f591fbffc8b332036b2a58f0f8b11aab68df7173", + "b1a118a9629cfd8e57e1c448878293310ef580bf1c449a82835a8df8dfd9a465", + "5e6ffcb2a8f9ecdf2a2158a2d1e860687c9305de4d8eaf368b541031deecbf5b", + "b195215a896b4b25d26486fa3d5969c9b3643c24c40ecca68fba077d5c7fad97", + "87c2c977a30aef16cf6afbd2a66b4844386eca6f1227b42d77678ef5f6e4739d", + "40a7aea289a886aa51a3f91d582f9dafb1bea5f1e6805f756b612f71e019f6f1", + "0f03ac96c949b569aae99924299a85fd06449e3491c232c571fcd00131b46661", + "78b8655576e768bb82f6a247b92e0ebd142e2e4df2277632cfe957b2ac160248", + "c02f8440afd0c1e2582d44fcecd40345a7d40b6d64998ed45cda01e0d72b87fe", + "b73f0333943315572ab8c079417213ee60f2eb7c4fecfde117a40977c5976279", + "4ffa1009c34e0957fb81fe0f5188077faea53a57b7e107053da55eb1da177658", + "20ec016bedad3f19e81c6a88b75e1b6052c204ccd00d88c9faf22940d2a047dd", + "e6da1e0e50f19f0998f99fbdf16c12d6d0714b529b9c5cd73ec747dbe165224c", + "1d9ac04b3dbebbbe6f0a13064fda0f315bc77c9ce31e1d0f73dde083ccd9bc88", + "980c3d59c77817a7767582085fa4299c5ddb4f9b7264bd602f9cfa708752b92a", + "2b88d11a71a157857031b137d34cc665fd715f41f85544f32dca1a9b4c7f8035", + "3afd69cd10058b16b51eeea6a7123b327fe4347d4b6d7e3993b8142cdafc98f7", + "87ff28b2b0bfdb0197a369e1661ac272f293dab31e510af6d60aa1fe1756b0df", + "f18c49bd197275e9a1f1e056d06411fd26b12859eb64adf74595af2661e847ce", + "73a498ee2a43f83a60d7893961d183831d71e7b8752f497b2e8a62a7e8dcc164", + "e1b6d8bd63abeffad746b604c162dfd3fa35dfbe5a527fa9e756897dca3eb906", + "461a2df6e792f50a42948ca0e1a2bbb1ea5aa5dfceb6fed4cf3d6ecf01259086", + "0c9ddc90c7d88bfe3d2c03a32fc92cbfaf67cb8ddc6bd4d6c6429af3d72d7917", + "339ce60f9f346d9db6c91185722b572b2049d2a127fae874bfae419294a384cb", + "927642b4bb7a9bd64cac9c0f1104b79c2cc89cbd0116e293cbfa50927805a285", + "cdc91c4fc68da0fae9da7bada256d244f1cfbbeffb7e1a63d9159aeab28b2ff0", + "9262cbaf9916dbb4d144afd64d54c46707245db7cec986c08be17495eb754b31", + "1e613ca9f38921fd68c3f86fbc5bd75a4bdcfd8cfcc3e91991d9accd4cb41fb6", + "eccf23b8ffe2f7c22a5245cadac987a1bdfc156d529cac97c42e4fadee573986", + "d19a2d8c1f2d2e7cfac30be1bcf81c8aec1779232300475c495f577f98cfb1df", + "cec4eee8c67cd206c45d921d212d8c1f63f13e7d7c929a6b9786f868d9a36616", + "4116d8e5d9ddfc50a47fed20a4aee896073167e2a0fc461480f821f6ff7850df", + "a6682cfc685f6a802f08748c1bbe69d81bf2121b6e4c7288186e847887d301fc", + "a1ca95d728fc429714eadb8e4c64aa174b063708c9aefe2aa657509e3771a280", + "bc83686345f688bd2df614c3cd9d50820961f7f7dec18a78e0ae880071388312", + "21df1f321d5bf32a6fae5e2e1a4dfacc81cf1199ef4d7c79a9d6343192d8d098", + "d7ae503517210859770261b7fe63f3d1ed5d9e900cdcac3ad125ce7cfbb70895", + "a6ef3227d9fe407d8318ca71c22a9077da390db80b3b649912ce44b7fae14361", + "37ede399c72f0a577b72db4257497f1486ff63adb3aee1982870451fa326e94b", + "0f9c96ee65ee9b6cdef0961d4c4c17f8ed581897c5f5982cd4ecdda502a1bb67", + "8ecdbfa514252b6be839a5306ae4467d1712d70776ecae619194ddc6ce1c1cc5", + "7af023485316ef6e4da689f85da37d68203ecae422815e905d4e21b22c83ef51", + "51e9ba8f2a368de911e87a77c05601eb6869afc42c3da056c651c94e27519cd0", + "c099451de7f5ce016fdda173c19b92f06cf2bb048d31347dc7fb9a2a33fd2578", + "ecdbb760ce780b68b73492153c12f7f61f40531bf16d19eed933ea4b16f35c17", + "7c075b918b2dabbd3158b5d2187a6da5dcabdc222183e2445996cec0371fe67a", + "99c93dfbcd18b915f771b055bc89fa63f94aca75d0aea8c889bff55801250928", + "bca0c1aba8329fddaa1e123f717d72d3dc6be5ece6516bb66761507e5dbaf2a5", + "337e57f6848c6ef66e4c62baf0a1784fb4479401f8643dc56a3ebad8eb25580f", + "02093b95aeee79402e11681e0f5f20d92dfd65d9e71180f7b0ff97c823517e0b", + "d4ca374cd775abc7fb29ff32196efbcd13b8bc00e3d98a614aec71bfc19a10e2", + "1becf87cf5ff2fe8f102407be8c43eae2dba1e439e5252e350abea3b5c41cec2", + "6204c71c1eea3c293029157315619f8f46df4267440781235514f97df6f493e1", + "2ece03550e371c6bf444b437cb1418fb6baf0b34bc809480a96b5974a7c472a2", + "e610c3ffd5d6753c19cc8076ce847cdbbccc3b4739d632bf7b9690595a61ef7e", + "b9fd1cf79ac1eb72b66de988ce5117676a5de8819e92ffd095c565597a104874", + "ca03f31e4efdb9657a4d7000c41adbca9da47b6acc08ae571072dba65aea6f14", + "a67497cdec842d791f8b619918f6f75f9dc396350202895746b3cc5056876592", + "796c18403fee405ea91895f0c286ceac08e19ee19f1eb775379664eb22d5c17a", + "1474897f100e1e5235ee30cb69dc7c190d19e9852e12ee7372e850771bc15109", + "40954e1476db638ab1c7f3c54688949abc8a473f64ee4e4f803e57bbcac65193", + "cfb56aab33dc5e198ee8c63c6447a37c7b7bd6ce0fdb040a92081fc4caf63754", + "f0721ebb2c1b08f78cc42af0a20ad99a01fa72da1d055b3d7ff11f95fe938cd3", + "2c65b2803fadb656cb39494501ef0d5cea8826ec6e52a852fed95ab4f941926f", + "993466c5f5f1c42713591538b2b65c9e07a24dcbccc1c9cd4970f2fcc8e2abcf", + "aec1ad0a3a6dda0d2f0b6e842d5f3e3baad44fa9370ddb9616b6406fff967d4f", + "a9685c9183b2df954e1b198bed35ef78a75f0e43fc674e1bdc7c43680ca66c60", + "3e1ecd9f605eaef798c37e65fe4928047a69eaa903e388cf958fd2c300941c6c", + "0405d5438a780cc4fe182032918f46538c173f12dffb891a3de540f63c1ff67f", + "9b329c6ffc01a2e797f2cf8a5c033629bd2624c54b42a6ca1c8c3845dfb0a661", + "d0da9bbdee8cc60851f2369e5068125b720db607086b9c3b7205c52807a82499", + "2b57a2954ddb27d183d5e78e8a5a2ee3020b7d55447aefceb7d63f6e56803b9c", + "97cc40050db921a23fcc0a3bbaf9745a986ed782749731e466a4fd97d0f34b57", + "a45d6ed5ebc4fceed96c079d911a3219bb83e46cc91a9c6a2f9f74656514b774", + "af66e46268d94da5da14e8e4c2a45186eb9b54ac8039a64216ca4a438bd6e445", + "45db5fdeda7353ab4f0a6e2f106caab963d284adee4f5d24e2090240b836000d", + "90e42aab4fdcc0069aa543ef9949df76af051602fb1ff8bea4e4ac1adea1d9e3", + "7b72061e3b63bb052c19686a978a7fe2ce9931ca90a0bcb5343d577a8159a77e", + "2e2f55ce83d636159f364564e1c388b47614b299e69cb867fc7607aee08102f4", + "026617903a057960edcd2bc55c7e7a442e927e92b385e48e9bfbf4cd1a759dbf", + "2be48c4fe8243443ec92eba0c1cf7535bfdbbd92e30086f6daa914579f85e3e8", + "34b74aa86eb5e56507482fc50c8ae258993462f409d77d5caf8d61b07cc3c6ea", + "138359c1c812334ed88dd7c66c38057084a266e9d9c31f8a11630bd64aa84c2d", + "eb523e48a1034801a615a06283bc6cf4ab9d7ee4d7b27fadd1ce641e03b8c37d", + "07c84fa27563d4c3a6124606e059588e79d8ea18c9496ff4fd14b94490a523c7", + "1b6735fb0c69417c53cd857720481f43094ef60a8a6319f9ddfcd572246b99b8", + "fb35b01afa08aa216e3fc3d24e58c805663c40fe0042b2b9c0677c2465834573", + "0c93545c8e6443176553155a765f1d178a4083b336e7a7843f9621baa719503d", + "2da96293ffc8904d790ff0fa0d9f9e01aacb97f2bfaed6dfb25a7bcd3ac2c4c4", + "dfd188b7e6f91183e389d945a77be40402b6aaa9c95f88aadfb52b138e81b895", + "460166fdfdc149b25efbff23c729ef82c6a07efc75ccd2fc0491dfaf58153cfd", + "64a5b07ffc9eb5b1b0e3e9622cb41589fc6e5b1eaaa507baf3eb8c78c38a8ed0", + "4df04de47c31dffa9862eaf1a86f1e4f0bce50b9532696f9020d722deb5be333", + "38f36511fb1417c700b36c2b2019a51adf5bbecd0a91492df626985017f5f9f4", + "bda6e7e6597e7eb676a8077bca2c2efd51b3527b1fe31b69ff86331988e860fd", + "252eb6f26a4b51564634302bbe822dd6092e4d7c3ee1c9c9847bf7386819b8c9", + "311f5d8fea0e0c6668f0fd8dc850a0ca5aaf07fdb78e45187464cb18a4bba0cd", + "4cc2f2b448150e1e3097d7e622426f70e2e80955f351782b6ba2f65a028c95fa", + "515f4de4cb4961d5859a27b870df84d4c426c15c2ee1d0170236ec607d8e041f", + "c12d5f07ae3608cdce93d113c3d6a4b53e4dc83fd6fefeeb6793d72b2b0b6e1e", + "3e941c556308becd61e0d847a7c3aafddd83e96d5bd91f04e32b32d6229ebd60", + "000d42a21a0a933e5fb2908db2bc4735beb1d83fcc54312cf0de289c09b5b9fb", + "7e281f6f2dc7718be9502f15eefeec0be8c9c33d1edc75a95b8d5f2099b2b8c3", + "aba8c7630f9ff46666ea12aff815514da1accf0ec4a06bfe81b25b80c5ba28b8", + "a9a7c49bd1a33bd1d7e65050012dbdf18f8697c2f9bc53ed0e9fca9e484f6e1c", + "3425cc441b94fc936165ebda821634bd833747d66bf92b139a4d6dcc5eca6f52", + "3025f7bea6800100b4858cd6a0f85125bec48cbf9de2f41fd46aba72ef9c9563", + "860fa2ee8be2b2be16eafd4d9846bd8f1642b4ddafc3e60be6fdec56d30f123d", + "063aa327a9bee19a71f2f7989ef9f3734f911123e4fd1e75f93e63e8fb91ef98", + "88cddecac5ee90993fa499e6fc53459adf189225c1ba1b5e1458de6ed3a4dbc0", + "fbe669bd0d2241e6068cf1f39566a0787fc7c481f41c06d006a8a8720860f2e5", + "455831e400edf29ccf09776d0b911dd2a7993a71e05886ba5a413a064c44be90", + "cd9e223ef0c94fdec4d1e2f5fc4468d75e0db4935563e3a4a027a6e27f7288e6", + "2a39752024ba33de989da106bfbccaeffa06de744e5122a0dfd3d88daee0726c", + "d53a60138e386899fcd05d2c8338b2255432d30debdbdccfc4aa077742eb564d", + "c5f5fa3c9d45d031945e2d4128e2be51a2fa6115aceddb57eb09eb3b4a835e5c", + "24ad17679d1f74ab4c39407c9d80fc531f79ad467d5f89f614ded6c8559cf7c8", + "a32c79d9f49592c7c4b3fc18bb6ef387ec13ed4c94f11b52976d6babe2f60e66", + "91ea4b0eb2cf138e177e55b3b28feebae4f57be6b562bc27d93abd906c38eef3", + "5c36d27cadf7cebbee3dfb8199415a2edef8c4347b1376fc2672fce91b69b184", + "b84b4acb580cb51933b35c36217ace4a5ac792676c21d93fc1882fea034be4be", + "bd54c96a1c4b4dbde7d0d22f7bbae9ece4d4f834c3ffb8ba541c20196405e3f6", + "5300378b076c533cccff0f35c9e83adb14d811cf8e564a6731455bc80746e26a", + "fcc111a60a0e29e2774118ce3022af23f86181408e5db95a537b5bfaf2b3adf0", + "a99ad97f8ef8e0e77d82f1fe77e42fc1b2c7e627d5966dd396088c3ffc925fec", + "f0ae716036bae9f156dad111ffff037dc4399109d90a09637048de043c12be10", + "312d55ffde4b7001b19d9be38f9cb6243d7c34359dc4dbd2e6fac6a23741eb40", + "7f749c50ca2700a4a7f142e645c03b3354718b95732fc1c0c1277924a6be5932", + "e1a8c41f7f8edb2cc0acf73cde5695cebe37b9501f3c0f5a8b58de495088f3c8", + "083c68ebf6a88bf68a3db988ed7fbe3f4371657e35e3ba5417ea71a3143c9d05", + "4329ce1dfb8538bfaf7ac6ba645a825ca3117cd5e7bfa24700b650e3a583cf17", + "93568f01f52a523f23e30e50674515aa15f99af963e824097af91f208fa99b55", + "57b5ef4047cb2c8749e5c760f2fb9feb0488fbff7f293f90c283c3641f0b7590", + "bba088b26bf7ea3a8c5604e828ee039335710550ef97ca7524ee34c4197b307d", + "130078b5dcd78a81680094d5711ef763d7a903dbb0924ab9cff2d4b2fc6da71a", + "426c83bd075dfdfe8028cb52e6d6e60951cdbfd67aa9cb4ff5013b0cdc14679e", + "15413a1267c3b401e7bec24427f55c999c0fd5e729103f24e6308bc8ff7bba20", + "54b596cbaa0d85a91835fdb6199defb59602b1ea7a0f39a731cea10b9a08e51a", + "495356ecb4685d45358cd30d3e828cc300c91d4c4a56810c9b297a414973d596", + "b4aeb4bb521df4fae724645d55ad8b769b0c2b7ee1886c726e3ebaaa62caf406", + "474cf90f17f9c2d044a790b88bfe7c72d3f1f05cee49faea48a81544beff60de", + "92b61bc157704211cb011462bc38be711019434044b4dd7a1dc468dd15ffcfd4", + "42041e5c16b2e1ec71f05e01e5eb629fed05388f997dcf9faee348e09b48d059", + "553c728076a984aff13186553aa113dc6982a3bbc35525da6160163c4011ef4b", + "f0d80d03cfce867dc022b9a32a24acd72c2b635ed427c9889bff81c2e11ad0a3", + "b5230e23fdc6a79acd0ed82511031e938214b6af6ff3b88f37bf9c73c6a4e2a0", + "ed90717291139a8866895d1cc7bf21ef897b967c72ecdf087ff32db95c3c7929", + "baa92882d82541332bf3a0df0b1684fa4c453d07a6c98ba4173610f33b545738", + "6473b08ffbe010cb340100e1fa15fb3cebf8781fb6747df774bc0eff305743fa", + "f7be6900a8f56babc476ee6cbd72da3113f241b481c462686d6b3653342c776a", + "4ddc9b60cde4e2b7eb32db812fc9a75dd7a9d5796589c71c8a84dd3c3ff35908", + "04ec9c5f105b4290b96f14c4606a7058824daf4a2906d4eb6007f3df5b8398e6", + "ea34c6ab07a6d3122dcc39ace9c3d9d49e45b488c12f0dfef0150c86bc1797b1", + "875c3d596a1d236f5429c650f2e2f68c74311a8a03c46bd0c5d8fa979cf6f9d6", + "3f6e18497f8a905c5130fb720788b073c9682d90dbcbd61906c888fe1a1acdc0", + "d4addc969e187f3df65aaf9685f3d296a0ce82799a70855ea152dd4ee9f648c7", + "ec2908d552433cbdcff7a3fb4f0a734dff532734279b9d72140a3a63481d146b", + "ea46d64678cd53d6ef1dc4ba6ec3131e7a0630f0feb6dcd223906c9386b4ef2d", + "3f30cc95a5626b0f8d621510d742c3f6b32ddcc8801a33e78364777546c2c48d", + "f582fdb43594f6e7e2ec6de723614a3c220f36961777e614ddfb3f67bb537c0d", + "2277f336268d9a6a68dd3d219ff826f473201c35502cd1744ad199125bf0ef42", + "feb56ea31322ffc386427c857fca6b40b3eb41ce5b00154ef46789a5441baddb", + "26df2412bc5aabd72054609d75675834aaa97c0ddc65527b4c26ee038f436f04", + "62160dde876244853a1276bd5348c6c65fc2e7fa34391bf2df7b1840da794bc9", + "86006a25f27caa9a45e2d9632a432d24e9406f07ae27fe556a60c793b1f88bcb", + "1a107dd685931b90600de8cfe7fd9ff1440c65a97745f2a7c904e6296ea710dd", + "f9d3bb52414a8e5e5f2c54749cab572e8c24c4d7016aef8291840b1d8fb88de3", + "437944efd6bc1f3dac847250b3b17b262480f2d482557505db02af60a8ae58f7", + "f6e07379f4199d4ee18e349c84748b808bef93078776ebc7a21dccf5786be144", + "2a20970c1fdc4e8cfe402a360477ff7ed3fac87b1bf75a9c83a6a815cdc21cd3", + "f4e6d4b0256d2d2d8b8fc8487246cc0bb7f58e9609370475f376b78c1fd0810f", + "9ff636ed0696d3dbb25e89245aba5f2fde213d3c318f7838e8a4d88f3367709b", + "eafe5a189f585c05eeb18fe81a8387b0320afcc44299297ad2f56c43850a3b21", + "f18d64f1f2de6e7ba751e709e9abb8e3419280a00522c1aaed4a118a8b6a6229", + "50a5ba007d526c2d1ce58bc245541de98324adb41e273b42ed2dfafc12872d18", + "37415035ee1c9267ceb50d00376fbabf882fb1546cbe2572f0bb558ba3954e26", + "31b400a92f82c9fa57f737ad4b52bff4eccc2049198def1dc18db01726969160", + "5584bfdd8196d7dbb111eaa8a5afda98bdd75b13ac23de04c588887c3bacb8af", + "988b9f019f7582d0e9037bfd2cb67e264cbf438c7e5a75827486730499b190ad", + "f9d97615c20201db02c034c1ad7a7150e8a608898dbdca50a9f8642abfcd3600", + "af8c89b2a673953a9c27f959db496a60b2ee0b8895088f7fcc5c78a3af209bd6", + "ec86b5ec605b4bfbc4445bbc0fd0a4b1f4da0d683392d6ca3049db7d46041fa2", + "4ecdbb904012f422e53433c8d81fa82159d2b6953ba01d3beae265c5c90ff8fc", + "f619b1ed69a77937acb84e648b5453b177bc99fbcb24e0a57aa9fa73500ab00f", + "e2075375c4965dbc091a65835ba34a39534e6437b9b5d3c03cb04359f6f9174b", + "1aee40e0dbc49dce60a9bc05ce97bef6e084d5d3406a3d62c5e53639583eccd4", + "f38bb1cae09113a622ed1357532e6d74ce8523d5497da6356d2b943c9fb5abb6", + "f688e31d819802ac812bd8d52b031bd6831f8548df1e748609c09faed5739477", + "ea8b8eb031a04948a3e07496ed4fdb4eb823aa2a273c06e1e6854fed98e67c94", + "470d8f5f286d8b975747214eb60416ae94000a035abb14381b6fb5500a9336c8", + "151204775e182d13af76412a11557846f599ca4f5f5e424ab8aa7c14afe64548", + "9cdb09ef9cb75f0d03c68459ca8ffe8c37850dab522e358b41ffc406e990f6f3", + "d559f1a00c789dde739ba2d9d11c49e9f08c73fb28f1ffde8a32d3f7468f3543", + "95a3204d9b3b7e106e0403e5e48c4ba538aa54ff7725cabb84ef9c6866ccf02b", + "591068ca935960217605d596e2bd7751d83497ac12f28123b787093369ce761d", + "38916dff36aeb80d33e26705a00dd01f59dca18b2021d756bf1e8023a3c5d8b7", + "8bc3f2672525c2f2d57e5199cbed5821b5f550c944afb19ea9ab3f20f5a7679b", + "973491a5f78fd083faf95fc77316f10c1fe46c6394f789d907789a20864224dd", + "517506b8c5cf63d57c56877785ed44f78853b66dd7a156a9580ebcab5dbc943e", + "5ac64b875f9a88013c4d5abf132b94a2f541e918f4e65a1247c31294d08c4ede", + "c9291da8284edec9329a2d25fdaea63daf1c9c12a561db02080cfc5ace3f6cb8", + "51025ab573a0a1301e5ee3441cc59e8c2e622226a85bfd4cfcf37ece941d8b0c", + "a3d3433c35fcb983e2ff785e2d70df28a9db9d6e983e8800e302e690cd18860c", } -const sepoliaPreverifiedHeight uint64 = 776832 +const sepoliaPreverifiedHeight uint64 = 839616 From e0351715464c4e483a7f1328bc24acf1669abde7 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Tue, 5 Apr 2022 23:08:58 +0100 Subject: [PATCH 210/261] Fix 'all defaults' case for eth_estimateGas (#3790) (#3824) * Fix 'all defaults' case for eth_estimateGas * fix tests Co-authored-by: Igor Mandrigin Co-authored-by: Igor Mandrigin Co-authored-by: Igor Mandrigin --- cmd/rpcdaemon/commands/eth_api.go | 2 +- cmd/rpcdaemon/commands/eth_call.go | 8 +++++++- cmd/rpcdaemon/commands/eth_call_test.go | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/cmd/rpcdaemon/commands/eth_api.go b/cmd/rpcdaemon/commands/eth_api.go index a6174518813..76343881f93 100644 --- a/cmd/rpcdaemon/commands/eth_api.go +++ b/cmd/rpcdaemon/commands/eth_api.go @@ -75,7 +75,7 @@ type EthAPI interface { // Sending related (see ./eth_call.go) Call(ctx context.Context, args ethapi.CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *ethapi.StateOverrides) (hexutil.Bytes, error) - EstimateGas(ctx context.Context, args ethapi.CallArgs, blockNrOrHash *rpc.BlockNumberOrHash) (hexutil.Uint64, error) + EstimateGas(ctx context.Context, argsOrNil *ethapi.CallArgs, blockNrOrHash *rpc.BlockNumberOrHash) (hexutil.Uint64, error) SendRawTransaction(ctx context.Context, encodedTx hexutil.Bytes) (common.Hash, error) SendTransaction(_ context.Context, txObject interface{}) (common.Hash, error) Sign(ctx context.Context, _ common.Address, _ hexutil.Bytes) (hexutil.Bytes, error) diff --git a/cmd/rpcdaemon/commands/eth_call.go b/cmd/rpcdaemon/commands/eth_call.go index 4e94bc16e0e..5f6db539684 100644 --- a/cmd/rpcdaemon/commands/eth_call.go +++ b/cmd/rpcdaemon/commands/eth_call.go @@ -113,7 +113,13 @@ func HeaderByNumberOrHash(ctx context.Context, tx kv.Tx, blockNrOrHash rpc.Block } // EstimateGas implements eth_estimateGas. Returns an estimate of how much gas is necessary to allow the transaction to complete. The transaction will not be added to the blockchain. -func (api *APIImpl) EstimateGas(ctx context.Context, args ethapi.CallArgs, blockNrOrHash *rpc.BlockNumberOrHash) (hexutil.Uint64, error) { +func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi.CallArgs, blockNrOrHash *rpc.BlockNumberOrHash) (hexutil.Uint64, error) { + var args ethapi.CallArgs + // if we actually get CallArgs here, we use them + if argsOrNil != nil { + args = *argsOrNil + } + bNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber) if blockNrOrHash != nil { bNrOrHash = *blockNrOrHash diff --git a/cmd/rpcdaemon/commands/eth_call_test.go b/cmd/rpcdaemon/commands/eth_call_test.go index f3b9d8d5f66..a93165ec500 100644 --- a/cmd/rpcdaemon/commands/eth_call_test.go +++ b/cmd/rpcdaemon/commands/eth_call_test.go @@ -19,7 +19,7 @@ func TestEstimateGas(t *testing.T) { api := NewEthAPI(NewBaseApi(nil, stateCache, false), db, nil, nil, nil, 5000000) var from = common.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7") var to = common.HexToAddress("0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e") - if _, err := api.EstimateGas(context.Background(), ethapi.CallArgs{ + if _, err := api.EstimateGas(context.Background(), ðapi.CallArgs{ From: &from, To: &to, }, nil); err != nil { From dcf2e3221e71e18f176f30c8a9f85d72a21b73a3 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Tue, 5 Apr 2022 23:09:14 +0100 Subject: [PATCH 211/261] Update version.go (#3829) --- params/version.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/params/version.go b/params/version.go index da6ea7afc09..89f50c8da21 100644 --- a/params/version.go +++ b/params/version.go @@ -32,8 +32,8 @@ var ( // see https://calver.org const ( VersionMajor = 2022 // Major version component of the current release - VersionMinor = 3 // Minor version component of the current release - VersionMicro = 2 // Patch version component of the current release + VersionMinor = 4 // Minor version component of the current release + VersionMicro = 1 // Patch version component of the current release VersionModifier = "beta" // Patch version component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" From 3a2319a076d18b5421a701c6dd6ed1b0642059ad Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Fri, 15 Apr 2022 16:44:37 +0700 Subject: [PATCH 212/261] Change libmdbx submodule origin (#3894) * save * Restore testdata Co-authored-by: Alexey Sharp --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 5bc6224029f..16a02e5911b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,4 +3,4 @@ url = https://github.com/ethereum/tests [submodule "libmdbx"] path = libmdbx - url = https://github.com/erthink/libmdbx + url = https://abf.io/erthink/libmdbx.git From 3671b5814931b098c744a49fd72f08faba73ff00 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Fri, 15 Apr 2022 12:14:22 +0100 Subject: [PATCH 213/261] Update to erigon-lib stable (#3895) Co-authored-by: Alexey Sharp --- go.mod | 6 +++--- go.sum | 13 ++++++------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index 3e3587d212a..2a0f236540b 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20220331071652-74afd3864c53 + github.com/ledgerwatch/erigon-lib v0.0.0-20220415095037-bce96ae8d117 github.com/ledgerwatch/log/v3 v3.4.1 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/logrusorgru/aurora/v3 v3.0.0 @@ -45,8 +45,8 @@ require ( github.com/shirou/gopsutil/v3 v3.21.12 github.com/spf13/cobra v1.2.1 github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.7.1-0.20210427113832-6241f9ab9942 - github.com/torquem-ch/mdbx-go v0.23.1 + github.com/stretchr/testify v1.7.1 + github.com/torquem-ch/mdbx-go v0.23.2 github.com/ugorji/go/codec v1.1.13 github.com/ugorji/go/codec/codecgen v1.1.13 github.com/urfave/cli v1.22.5 diff --git a/go.sum b/go.sum index fa637cd800d..ff17d66f661 100644 --- a/go.sum +++ b/go.sum @@ -493,8 +493,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20220331071652-74afd3864c53 h1:9KQ0jD2zTCCGCaTxyH5F3elT0ZCOIxfZIJ5zABEdXLg= -github.com/ledgerwatch/erigon-lib v0.0.0-20220331071652-74afd3864c53/go.mod h1:ZJuSY/lTYzZnclDfGvxFfTGGJ4AWRmqkHe6E7dLiKYo= +github.com/ledgerwatch/erigon-lib v0.0.0-20220415095037-bce96ae8d117 h1:MS1Gx/NYHeJEStrEq89CcZDclVpIZ1aE+xAzu0zCLAw= +github.com/ledgerwatch/erigon-lib v0.0.0-20220415095037-bce96ae8d117/go.mod h1:AOND8R1lL1zuzQ/cISA5SQ5yShL/YMV2MV0Qjdo0wA0= github.com/ledgerwatch/log/v3 v3.4.0/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/log/v3 v3.4.1 h1:/xGwlVulXnsO9Uq+tzaExc8OWmXXHU0dnLalpbnY5Bc= github.com/ledgerwatch/log/v3 v3.4.1/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= @@ -736,8 +736,8 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1-0.20210427113832-6241f9ab9942 h1:t0lM6y/M5IiUZyvbBTcngso8SZEZICH7is9B6g/obVU= -github.com/stretchr/testify v1.7.1-0.20210427113832-6241f9ab9942/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syncthing/syncthing v0.14.48-rc.4/go.mod h1:nw3siZwHPA6M8iSfjDCWQ402eqvEIasMQOE8nFOxy7M= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= @@ -750,9 +750,8 @@ github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs= github.com/tklauser/numcpus v0.3.0 h1:ILuRUQBtssgnxw0XXIjKUC56fgnOrFoQQ/4+DeU2biQ= github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8= -github.com/torquem-ch/mdbx-go v0.23.0/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= -github.com/torquem-ch/mdbx-go v0.23.1 h1:lclZI7qZu844VjMn6onSWWcQYCIEwbClML7we9qxz7E= -github.com/torquem-ch/mdbx-go v0.23.1/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= +github.com/torquem-ch/mdbx-go v0.23.2 h1:7axXl0leix2v8No+mRzeTV32hJrV1817aKhh+hTEpC8= +github.com/torquem-ch/mdbx-go v0.23.2/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/ugorji/go v1.1.13 h1:nB3O5kBSQGjEQAcfe1aLUYuxmXdFKmYgBZhY32rQb6Q= From e6563fe1ae3d9550b3f9f6dd2df14d910b405e1b Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Fri, 15 Apr 2022 12:45:18 +0100 Subject: [PATCH 214/261] Update version.go (#3896) --- params/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/params/version.go b/params/version.go index 89f50c8da21..3bfa004b5fb 100644 --- a/params/version.go +++ b/params/version.go @@ -33,7 +33,7 @@ var ( const ( VersionMajor = 2022 // Major version component of the current release VersionMinor = 4 // Minor version component of the current release - VersionMicro = 1 // Patch version component of the current release + VersionMicro = 2 // Patch version component of the current release VersionModifier = "beta" // Patch version component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" From d139c750cba2d9ce03e4677d6700b21246c6813f Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Fri, 15 Apr 2022 22:42:12 +0100 Subject: [PATCH 215/261] Update skip_analysis.go (#3897) (#3898) --- core/skip_analysis.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/skip_analysis.go b/core/skip_analysis.go index ae471a86d65..0413016aa43 100644 --- a/core/skip_analysis.go +++ b/core/skip_analysis.go @@ -21,7 +21,7 @@ import ( ) // MainnetNotCheckedFrom is the first block number not yet checked for invalid jumps -const MainnetNotCheckedFrom uint64 = 14527100 +const MainnetNotCheckedFrom uint64 = 14590300 // SkipAnalysis function tells us whether we can skip performing jumpdest analysis // for the historical blocks (on mainnet now but perhaps on the testsnets From 1174db56cce9d5807c3be384d2f01ab4e41354ca Mon Sep 17 00:00:00 2001 From: Alex Sharp Date: Thu, 19 May 2022 07:56:30 +0100 Subject: [PATCH 216/261] Update version and erigon-lib --- go.mod | 2 +- go.sum | 4 ++-- params/version.go | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index d466c2ea607..9d8a442773e 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20220519045314-0819aa370518 + github.com/ledgerwatch/erigon-lib v0.0.0-20220519052736-7908982ed957 github.com/ledgerwatch/log/v3 v3.4.1 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/pelletier/go-toml v1.9.5 diff --git a/go.sum b/go.sum index 5d5e9c5095d..7841fd4897d 100644 --- a/go.sum +++ b/go.sum @@ -456,8 +456,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20220519045314-0819aa370518 h1:jZ3QOiHjBRwaEYLCG/tWu6LrlaclASe1krhRCWEkHeo= -github.com/ledgerwatch/erigon-lib v0.0.0-20220519045314-0819aa370518/go.mod h1:F5LaFSAgKHxkKjf5bHbtAhU424n+WNRREBssXYNC6Xo= +github.com/ledgerwatch/erigon-lib v0.0.0-20220519052736-7908982ed957 h1:yCnjRswSERBaQ+7Srntu9GpfRb9yuqBdggUHhBrcbig= +github.com/ledgerwatch/erigon-lib v0.0.0-20220519052736-7908982ed957/go.mod h1:F5LaFSAgKHxkKjf5bHbtAhU424n+WNRREBssXYNC6Xo= github.com/ledgerwatch/log/v3 v3.4.1 h1:/xGwlVulXnsO9Uq+tzaExc8OWmXXHU0dnLalpbnY5Bc= github.com/ledgerwatch/log/v3 v3.4.1/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= diff --git a/params/version.go b/params/version.go index 56d8388b83b..e2aa120b7ee 100644 --- a/params/version.go +++ b/params/version.go @@ -32,8 +32,8 @@ var ( // see https://calver.org const ( VersionMajor = 2022 // Major version component of the current release - VersionMinor = 99 // Minor version component of the current release - VersionMicro = 99 // Patch version component of the current release + VersionMinor = 5 // Minor version component of the current release + VersionMicro = 5 // Patch version component of the current release VersionModifier = "dev" // Modifier component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" From ff5b94ee737bcb0cbc135eb0bc40f9baa66f26ff Mon Sep 17 00:00:00 2001 From: Alex Sharp Date: Thu, 19 May 2022 07:57:10 +0100 Subject: [PATCH 217/261] Update version and erigon-lib --- params/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/params/version.go b/params/version.go index e2aa120b7ee..e0dfb8685ec 100644 --- a/params/version.go +++ b/params/version.go @@ -31,10 +31,10 @@ var ( // see https://calver.org const ( - VersionMajor = 2022 // Major version component of the current release - VersionMinor = 5 // Minor version component of the current release - VersionMicro = 5 // Patch version component of the current release - VersionModifier = "dev" // Modifier component of the current release + VersionMajor = 2022 // Major version component of the current release + VersionMinor = 5 // Minor version component of the current release + VersionMicro = 5 // Patch version component of the current release + VersionModifier = "alpha" // Modifier component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" ) From ad822cfd3f6255509e2be6028651754707c97414 Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Sat, 21 May 2022 13:32:34 +0100 Subject: [PATCH 218/261] [alpha] Move devel to alpha, update version (#4223) * allow --syncmode=snap for bor-mainnnet (#4206) * save * save * allow --syncmode=snap for bor-mainnnet #4206 * allow snap sync for mumbai chain (#4208) * save * mumbai * Bor: GetTransactionReceipt (#4209) * fixed miner.sigfile option (#4210) * Snap: reduced memory footprint on building huffman table (#4214) * save * save * save * save * Remove dependency on leveldb (#4213) * save * save * save * save * save * save * methods to read single txn by txnID (#4215) * It's safe now to open snapshots at app start (#4216) * removed obsolete trie variant (#4172) * up gods lib version (#4217) * Fix `rpc.BlockNumberOrHash` unmarshaling (#4218) * add test * fix unmarshaling bug Co-authored-by: Igor Mandrigin * return err on invalid syncmode (#4219) * save * save * save * fixed kiln bug (#4221) * Clean headers pointers when removing links (#4222) * Clean headers pointers when removing links * Replace the lock Co-authored-by: Alexey Sharp * Makefile: pass docker build arguments (#4212) Dockerfile requires some --build-arg options. Fix "docker" target to pass them. Fix GIT_TAG to reflect the most recent tag related to HEAD, instead of an unrelated most recent tag. Use it as the image VERSION. Image tags need to be passed explicitly if needed: DOCKER_FLAGS='-t erigon:latest' make docker * Update erigon-lib and version Co-authored-by: Alex Sharov Co-authored-by: Giulio rebuffo Co-authored-by: Artem Tsebrovskiy Co-authored-by: Igor Mandrigin Co-authored-by: Igor Mandrigin Co-authored-by: Alexey Sharp Co-authored-by: battlmonstr --- .github/workflows/ci.yml | 5 +- Dockerfile | 1 + Makefile | 9 +- cmd/integration/commands/stages.go | 5 +- cmd/rpcdaemon/commands/eth_receipts.go | 16 +- cmd/rpcdaemon/interfaces/interfaces.go | 3 +- cmd/state/commands/check_change_sets.go | 5 +- cmd/state/commands/erigon2.go | 9 +- cmd/utils/flags.go | 2 +- core/rawdb/accessors_chain.go | 14 + core/vm/lightclient/iavl/.gitignore | 14 + core/vm/lightclient/iavl/CHANGELOG.md | 150 +++++++++ core/vm/lightclient/iavl/CONTRIBUTING.md | 8 + core/vm/lightclient/iavl/LICENSE | 193 +++++++++++ core/vm/lightclient/iavl/Makefile | 54 ++++ core/vm/lightclient/iavl/PERFORMANCE.md | 111 +++++++ core/vm/lightclient/iavl/POEM | 29 ++ core/vm/lightclient/iavl/README.md | 13 + core/vm/lightclient/iavl/doc.go | 49 +++ core/vm/lightclient/iavl/key_format.go | 144 +++++++++ core/vm/lightclient/iavl/key_format_test.go | 70 ++++ core/vm/lightclient/iavl/proof.go | 135 ++++++++ .../vm/lightclient/iavl/proof_iavl_absence.go | 87 +++++ core/vm/lightclient/iavl/proof_iavl_value.go | 86 +++++ core/vm/lightclient/iavl/proof_path.go | 167 ++++++++++ core/vm/lightclient/iavl/proof_range.go | 305 ++++++++++++++++++ core/vm/lightclient/iavl/version.go | 4 + core/vm/lightclient/iavl/wire.go | 17 + core/vm/lightclient/multistoreproof.go | 6 +- core/vm/lightclient/utils.go | 2 + eth/backend.go | 8 +- eth/ethconfig/config.go | 13 +- eth/stagedsync/stage_senders.go | 4 +- go.mod | 24 +- go.sum | 280 +--------------- params/version.go | 2 +- rpc/types.go | 3 + rpc/types_test.go | 2 + turbo/app/snapshots.go | 49 +-- turbo/snapshotsync/block_reader.go | 130 +++++++- turbo/snapshotsync/snapshothashes/embed.go | 7 + .../snapshothashes/erigon-snapshots | 2 +- turbo/stages/headerdownload/header_algos.go | 51 +-- 43 files changed, 1883 insertions(+), 405 deletions(-) create mode 100644 core/vm/lightclient/iavl/.gitignore create mode 100644 core/vm/lightclient/iavl/CHANGELOG.md create mode 100644 core/vm/lightclient/iavl/CONTRIBUTING.md create mode 100644 core/vm/lightclient/iavl/LICENSE create mode 100644 core/vm/lightclient/iavl/Makefile create mode 100644 core/vm/lightclient/iavl/PERFORMANCE.md create mode 100644 core/vm/lightclient/iavl/POEM create mode 100644 core/vm/lightclient/iavl/README.md create mode 100644 core/vm/lightclient/iavl/doc.go create mode 100644 core/vm/lightclient/iavl/key_format.go create mode 100644 core/vm/lightclient/iavl/key_format_test.go create mode 100644 core/vm/lightclient/iavl/proof.go create mode 100644 core/vm/lightclient/iavl/proof_iavl_absence.go create mode 100644 core/vm/lightclient/iavl/proof_iavl_value.go create mode 100644 core/vm/lightclient/iavl/proof_path.go create mode 100644 core/vm/lightclient/iavl/proof_range.go create mode 100644 core/vm/lightclient/iavl/version.go create mode 100644 core/vm/lightclient/iavl/wire.go diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3933dac8152..636a25f1a0a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -102,5 +102,6 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v3 - - run: git submodule update --init --recursive --force - - run: docker build . + with: + fetch-depth: 0 # fetch git tags for "git describe" + - run: make docker diff --git a/Dockerfile b/Dockerfile index 099f4815c6f..1a723ac2115 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,6 +25,7 @@ EXPOSE 8545 8551 8546 30303 30303/udp 42069 42069/udp 8080 9090 6060 # https://github.com/opencontainers/image-spec/blob/main/annotations.md ARG BUILD_DATE ARG VCS_REF +ARG VERSION LABEL org.label-schema.build-date=$BUILD_DATE \ org.label-schema.name="Erigon" \ org.label-schema.description="Erigon Ethereum Client" \ diff --git a/Makefile b/Makefile index 1488c7928b3..52148926e06 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ GOBIN = $(CURDIR)/build/bin GIT_COMMIT ?= $(shell git rev-list -1 HEAD) GIT_BRANCH ?= $(shell git rev-parse --abbrev-ref HEAD) -GIT_TAG ?= $(shell git describe --tags `git rev-list --tags="v*" --max-count=1`) +GIT_TAG ?= $(shell git describe --tags --dirty) CGO_CFLAGS := $(shell $(GO) env CGO_CFLAGS) # don't loose default CGO_CFLAGS += -DMDBX_FORCE_ASSERTIONS=1 # Enable MDBX's asserts by default in 'devel' branch and disable in 'stable' @@ -30,7 +30,12 @@ go-version: fi docker: git-submodules - DOCKER_BUILDKIT=1 docker build -t erigon:latest --build-arg git_commit='${GIT_COMMIT}' --build-arg git_branch='${GIT_BRANCH}' --build-arg git_tag='${GIT_TAG}' . + DOCKER_BUILDKIT=1 docker build \ + --build-arg "BUILD_DATE=$(shell date -Iseconds)" \ + --build-arg VCS_REF=${GIT_COMMIT} \ + --build-arg VERSION=${GIT_TAG} \ + ${DOCKER_FLAGS} \ + . xdg_data_home := ~/.local/share ifdef XDG_DATA_HOME diff --git a/cmd/integration/commands/stages.go b/cmd/integration/commands/stages.go index d7bb3f72c82..141bf766c15 100644 --- a/cmd/integration/commands/stages.go +++ b/cmd/integration/commands/stages.go @@ -1088,7 +1088,10 @@ var _allSnapshotsSingleton *snapshotsync.RoSnapshots func allSnapshots(cc *params.ChainConfig) *snapshotsync.RoSnapshots { openSnapshotOnce.Do(func() { - syncmode := ethconfig.SyncModeByChainName(cc.ChainName, syncmodeStr) + syncmode, err := ethconfig.SyncModeByChainName(cc.ChainName, syncmodeStr) + if err != nil { + panic(err) + } if syncmode == ethconfig.SnapSync { snapshotCfg := ethconfig.NewSnapshotCfg(true, true) _allSnapshotsSingleton = snapshotsync.NewRoSnapshots(snapshotCfg, filepath.Join(datadir, "snapshots")) diff --git a/cmd/rpcdaemon/commands/eth_receipts.go b/cmd/rpcdaemon/commands/eth_receipts.go index 3e5e3c1cf4c..c9d3af633b9 100644 --- a/cmd/rpcdaemon/commands/eth_receipts.go +++ b/cmd/rpcdaemon/commands/eth_receipts.go @@ -255,8 +255,12 @@ func (api *APIImpl) GetTransactionReceipt(ctx context.Context, hash common.Hash) return nil, err } - if chainConfig.Bor != nil { - if blockNum == 0 { + blockNum, ok, err = api.txnLookup(ctx, tx, hash) + if err != nil { + return nil, err + } + if !ok { + if chainConfig.Bor != nil { var blocN uint64 borTx, blockHash, blocN, _, err = rawdb.ReadBorTransaction(tx, hash) if err != nil { @@ -266,13 +270,7 @@ func (api *APIImpl) GetTransactionReceipt(ctx context.Context, hash common.Hash) return nil, nil // not error, see https://github.com/ledgerwatch/erigon/issues/1645 } blockNum = blocN - } - } else { - blockNum, ok, err = api.txnLookup(ctx, tx, hash) - if err != nil { - return nil, err - } - if !ok { + } else { return nil, nil // not error, see https://github.com/ledgerwatch/erigon/issues/1645 } } diff --git a/cmd/rpcdaemon/interfaces/interfaces.go b/cmd/rpcdaemon/interfaces/interfaces.go index 1c7bcb4ba33..19bc7a5ac2c 100644 --- a/cmd/rpcdaemon/interfaces/interfaces.go +++ b/cmd/rpcdaemon/interfaces/interfaces.go @@ -31,9 +31,8 @@ type BodyReader interface { type TxnReader interface { TxnLookup(ctx context.Context, tx kv.Getter, txnHash common.Hash) (uint64, bool, error) - //TxnByHashDeprecated(ctx context.Context, tx kv.Getter, txnHash common.Hash) (txn types.Transaction, blockHash common.Hash, blockNum, txnIndex uint64, err error) + //TxnByIdxInBlock(ctx context.Context, tx kv.Getter, blockNum uint64, i int) (txn types.Transaction, err error) } - type HeaderAndCanonicalReader interface { HeaderReader CanonicalReader diff --git a/cmd/state/commands/check_change_sets.go b/cmd/state/commands/check_change_sets.go index d93b74dcda5..1302300d983 100644 --- a/cmd/state/commands/check_change_sets.go +++ b/cmd/state/commands/check_change_sets.go @@ -114,7 +114,10 @@ func CheckChangeSets(genesis *core.Genesis, logger log.Logger, blockNum uint64, var blockReader interfaces.FullBlockReader var allSnapshots *snapshotsync.RoSnapshots - syncMode := ethconfig.SyncModeByChainName(chainConfig.ChainName, syncmodeCli) + syncMode, err := ethconfig.SyncModeByChainName(chainConfig.ChainName, syncmodeCli) + if err != nil { + return err + } if syncMode == ethconfig.SnapSync { allSnapshots = snapshotsync.NewRoSnapshots(ethconfig.NewSnapshotCfg(true, false), path.Join(datadir, "snapshots")) defer allSnapshots.Close() diff --git a/cmd/state/commands/erigon2.go b/cmd/state/commands/erigon2.go index d21637f0db3..58f27746b90 100644 --- a/cmd/state/commands/erigon2.go +++ b/cmd/state/commands/erigon2.go @@ -150,10 +150,6 @@ func Erigon2(genesis *core.Genesis, chainConfig *params.ChainConfig, logger log. switch commitmentTrie { case "bin": logger.Info("using Binary Patricia Hashed Trie for commitments") - trieVariant = commitment.VariantReducedHexPatriciaTrie - blockRootMismatchExpected = true - case "bin-slow": - logger.Info("using slow Binary Patricia Hashed Trie for commitments") trieVariant = commitment.VariantBinPatriciaTrie blockRootMismatchExpected = true case "hex": @@ -228,7 +224,10 @@ func Erigon2(genesis *core.Genesis, chainConfig *params.ChainConfig, logger log. var blockReader interfaces.FullBlockReader var allSnapshots *snapshotsync.RoSnapshots - syncMode := ethconfig.SyncModeByChainName(chainConfig.ChainName, syncmodeCli) + syncMode, err := ethconfig.SyncModeByChainName(chainConfig.ChainName, syncmodeCli) + if err != nil { + return err + } if syncMode == ethconfig.SnapSync { allSnapshots = snapshotsync.NewRoSnapshots(ethconfig.NewSnapshotCfg(true, false), path.Join(datadir, "snapshots")) defer allSnapshots.Close() diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 4f245dc1a67..c8be9ddc5c0 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -957,7 +957,7 @@ func setEtherbase(ctx *cli.Context, cfg *ethconfig.Config) { networkname.RialtoChainName: true, networkname.ChapelChainName: true, } - if _, ok := chainsWithValidatorMode[ctx.GlobalString(ChainFlag.Name)]; ok { + if _, ok := chainsWithValidatorMode[ctx.GlobalString(ChainFlag.Name)]; ok || ctx.GlobalIsSet(MinerSigningKeyFileFlag.Name) { if ctx.GlobalIsSet(MiningEnabledFlag.Name) && !ctx.GlobalIsSet(MinerSigningKeyFileFlag.Name) { panic(fmt.Sprintf("Flag --%s is required in %s chain with --%s flag", MinerSigningKeyFileFlag.Name, ChainFlag.Name, MiningEnabledFlag.Name)) } diff --git a/core/rawdb/accessors_chain.go b/core/rawdb/accessors_chain.go index 71e806e69b2..10e46555da0 100644 --- a/core/rawdb/accessors_chain.go +++ b/core/rawdb/accessors_chain.go @@ -304,6 +304,20 @@ func ReadStorageBody(db kv.Getter, hash common.Hash, number uint64) (types.BodyF return *bodyForStorage, nil } +func CanonicalTxnByID(db kv.Getter, id uint64) (types.Transaction, error) { + txIdKey := make([]byte, 8) + binary.BigEndian.PutUint64(txIdKey, id) + v, err := db.GetOne(kv.EthTx, txIdKey) + if err != nil { + return nil, err + } + txn, err := types.DecodeTransaction(rlp.NewStream(bytes.NewReader(v), uint64(len(v)))) + if err != nil { + return nil, err + } + return txn, nil +} + func CanonicalTransactions(db kv.Getter, baseTxId uint64, amount uint32) ([]types.Transaction, error) { if amount == 0 { return []types.Transaction{}, nil diff --git a/core/vm/lightclient/iavl/.gitignore b/core/vm/lightclient/iavl/.gitignore new file mode 100644 index 00000000000..dff7e1bb135 --- /dev/null +++ b/core/vm/lightclient/iavl/.gitignore @@ -0,0 +1,14 @@ +vendor +.glide +*.swp +*.swo + +# created in test code +test.db + +# profiling data +*\.test +cpu*.out +mem*.out +cpu*.pdf +mem*.pdf diff --git a/core/vm/lightclient/iavl/CHANGELOG.md b/core/vm/lightclient/iavl/CHANGELOG.md new file mode 100644 index 00000000000..918f98739b7 --- /dev/null +++ b/core/vm/lightclient/iavl/CHANGELOG.md @@ -0,0 +1,150 @@ +# Changelog + +## 0.12.0 (November 26, 2018) + +BREAKING CHANGES + +- Uses new Tendermint ReverseIterator API. See https://github.com/tendermint/tendermint/pull/2913 + +## 0.11.1 (October 29, 2018) + +IMPROVEMENTS + +- Uses GoAmino v0.14 + +## 0.11.0 (September 7, 2018) + +BREAKING CHANGES + +- Changed internal database key format to store int64 key components in a full 8-byte fixed width ([#107]) +- Removed some architecture dependent methods (e.g., use `Get` instead of `Get64` etc) ([#96]) + +IMPROVEMENTS + +- Database key format avoids use of fmt.Sprintf fmt.Sscanf leading to ~10% speedup in benchmark BenchmarkTreeLoadAndDelete ([#107], thanks to [@silasdavis]) + +[#107]: https://github.com/tendermint/iavl/pull/107 +[@silasdavis]: https://github.com/silasdavis +[#96]: https://github.com/tendermint/iavl/pull/96 + +## 0.10.0 + +BREAKING CHANGES + +- refactored API for clean separation of [mutable][1] and [immutable][2] tree (#92, #88); +with possibility to: + - load read-only snapshots at previous versions on demand + - load mutable trees at the most recently saved tree + +[1]: https://github.com/tendermint/iavl/blob/9e62436856efa94c1223043be36ebda01ae0b6fc/mutable_tree.go#L14-L21 +[2]: https://github.com/tendermint/iavl/blob/9e62436856efa94c1223043be36ebda01ae0b6fc/immutable_tree.go#L10-L17 + +BUG FIXES + +- remove memory leaks (#92) + +IMPROVEMENTS + +- Change tendermint dep to ^v0.22.0 (#91) + +## 0.10.0 (July 11, 2018) + +BREAKING CHANGES + +- getRangeProof and Get\[Versioned\]\[Range\]WithProof return nil proof/error if tree is empty. + +## 0.9.2 (July 3, 2018) + +IMPROVEMENTS + +- some minor changes: mainly lints, updated parts of documentation, unexported some helpers (#80) + +## 0.9.1 (July 1, 2018) + +IMPROVEMENTS + +- RangeProof.ComputeRootHash() to compute root rather than provide as in Verify(hash) +- RangeProof.Verify\*() first require .Verify(root), which memoizes + +## 0.9.0 (July 1, 2018) + +BREAKING CHANGES + +- RangeProof.VerifyItem doesn't require an index. +- Only return values in range when getting proof. +- Return keys as well. + +BUG FIXES + +- traversal bugs in traverseRange. + +## 0.8.2 + +* Swap `tmlibs` for `tendermint/libs` +* Remove `sha256truncated` in favour of `tendermint/crypto/tmhash` - same hash + function but technically a breaking change to the API, though unlikely to effect anyone. + +NOTE this means IAVL is now dependent on Tendermint Core for the libs (since it +makes heavy use of the `db` package). Ideally, that dependency would be +abstracted away, and/or this repo will be merged into the Cosmos-SDK, which is +currently is primary consumer. Once it achieves greater stability, we could +consider breaking it out into it's own repo again. + +## 0.8.1 + +*July 1st, 2018* + +BUG FIXES + +- fix bug in iterator going outside its range + +## 0.8.0 (June 24, 2018) + +BREAKING CHANGES + +- Nodes are encoded using proto3/amino style integers and byte slices (ie. varints and + varint prefixed byte slices) +- Unified RangeProof +- Proofs are encoded using Amino +- Hash function changed from RIPEMD160 to the first 20 bytes of SHA256 output + +## 0.7.0 (March 21, 2018) + +BREAKING CHANGES + +- LoadVersion and Load return the loaded version number + - NOTE: this behaviour was lost previously and we failed to document in changelog, + but now it's back :) + +## 0.6.1 (March 2, 2018) + +IMPROVEMENT + +- Remove spurious print statement from LoadVersion + +## 0.6.0 (March 2, 2018) + +BREAKING CHANGES + +- NewTree order of arguments swapped +- int -> int64, uint64 -> int64 +- NewNode takes a version +- Node serialization format changed so version is written right after size +- SaveVersion takes no args (auto increments) +- tree.Get -> tree.Get64 +- nodeDB.SaveBranch does not take a callback +- orphaningTree.SaveVersion -> SaveAs +- proofInnerNode includes Version +- ReadKeyXxxProof consolidated into ReadKeyProof +- KeyAbsentProof doesn't include Version +- KeyRangeProof.Version -> Versions + +FEATURES + +- Implement chunking algorithm to serialize entire tree + +## 0.5.0 (October 27, 2017) + +First versioned release! +(Originally accidentally released as v0.2.0) + diff --git a/core/vm/lightclient/iavl/CONTRIBUTING.md b/core/vm/lightclient/iavl/CONTRIBUTING.md new file mode 100644 index 00000000000..c1cdd5283be --- /dev/null +++ b/core/vm/lightclient/iavl/CONTRIBUTING.md @@ -0,0 +1,8 @@ +# Contributing + +Thank you for considering making contributions to IAVL+! +This repository follows the [contribution guidelines] of tendermint and the corresponding [coding repo]. +Please take a look if you are not already familiar with those. + +[contribution guidelines]: https://github.com/tendermint/tendermint/blob/master/CONTRIBUTING.md +[coding repo]: https://github.com/tendermint/coding diff --git a/core/vm/lightclient/iavl/LICENSE b/core/vm/lightclient/iavl/LICENSE new file mode 100644 index 00000000000..bf0c346e6b7 --- /dev/null +++ b/core/vm/lightclient/iavl/LICENSE @@ -0,0 +1,193 @@ +Tendermint iavl +Copyright (C) 2015 Tendermint + + + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/core/vm/lightclient/iavl/Makefile b/core/vm/lightclient/iavl/Makefile new file mode 100644 index 00000000000..8d4c774b8ae --- /dev/null +++ b/core/vm/lightclient/iavl/Makefile @@ -0,0 +1,54 @@ +GOTOOLS := github.com/golang/dep/cmd/dep + +PDFFLAGS := -pdf --nodefraction=0.1 + +all: get_vendor_deps test + +test: + GOCACHE=off go test -v --race + +tools: + go get -u -v $(GOTOOLS) + +get_vendor_deps: tools + dep ensure + +# bench is the basic tests that shouldn't crash an aws instance +bench: + cd benchmarks && \ + go test -bench=RandomBytes . && \ + go test -bench=Small . && \ + go test -bench=Medium . && \ + go test -bench=BenchmarkMemKeySizes . + +# fullbench is extra tests needing lots of memory and to run locally +fullbench: + cd benchmarks && \ + go test -bench=RandomBytes . && \ + go test -bench=Small . && \ + go test -bench=Medium . && \ + go test -timeout=30m -bench=Large . && \ + go test -bench=Mem . && \ + go test -timeout=60m -bench=LevelDB . + + +# note that this just profiles the in-memory version, not persistence +profile: + cd benchmarks && \ + go test -bench=Mem -cpuprofile=cpu.out -memprofile=mem.out . && \ + go tool pprof ${PDFFLAGS} benchmarks.test cpu.out > cpu.pdf && \ + go tool pprof --alloc_space ${PDFFLAGS} benchmarks.test mem.out > mem_space.pdf && \ + go tool pprof --alloc_objects ${PDFFLAGS} benchmarks.test mem.out > mem_obj.pdf + +explorecpu: + cd benchmarks && \ + go tool pprof benchmarks.test cpu.out + +exploremem: + cd benchmarks && \ + go tool pprof --alloc_objects benchmarks.test mem.out + +delve: + dlv test ./benchmarks -- -test.bench=. + +.PHONY: all test tools diff --git a/core/vm/lightclient/iavl/PERFORMANCE.md b/core/vm/lightclient/iavl/PERFORMANCE.md new file mode 100644 index 00000000000..b1acdd932b5 --- /dev/null +++ b/core/vm/lightclient/iavl/PERFORMANCE.md @@ -0,0 +1,111 @@ +# Performance + +After some discussion with Jae on the usability, it seems performance is a big concern. If every write takes around 1ms, that puts a serious upper limit on the speed of the consensus engine (especially since with the check/tx dichotomy, we need at least two writes (to cache, only one to disk) and likely two or more queries to handle any transaction). + +As Jae notes: for CheckTx, a copy of IAVLTree doesn't need to be saved. During CheckTx it'll load inner nodes into the cache. The cache is shared w/ the AppendTx state IAVLTree, so during AppendTx we should save some time. There would only be 1 set of writes. Also, there's quite a bit of free time in between blocks as provided by Tendermint, during which CheckTx can run priming the cache, so hopefully this helps as well. + +Jae: That said, I'm not sure exactly what the tx throughput would be during normal running times. I'm hoping that we can have e.g. 3 second blocks w/ say over a hundred txs per sec per block w/ 1 million items. That will get us through for some time, but that time is limited. + +Ethan: I agree, and think this works now with goleveldb backing on most host machines. For public chains, maybe it is desired to push 1000 tx every 3 sec to a block, with a db size of 1 billion items. 10x the throughput with 1000x the data. That could be a long-term goal, and would scale to the cosmos and beyond. + +## Plan + +For any goal, we need some clear steps. + +1) Cleanup code, and write some more benchmark cases to capture "realistic" usage +2) Run tests on various hardware to see the best performing backing stores +3) Do profiling on the best performance to see if there are any easy performance gains +4) (Possibly) Write another implementation of merkle.Tree to improve all the memory overhead, consider CPU cache, etc.... +5) (Possibly) Write another backend datastore to persist the tree in a more efficient way + +The rest of this document is the planned or completed actions for the above-listed steps. + +## Cleanup + +Done in branch `cleanup_deps`: + * Fixed up dependeny management (tmlibs/db etc in glide/vendor) + * Updated Makefile (test, bench, get_deps) + * Fixed broken code - `looper.go` and one benchmark didn't run + +Benchmarks should be parameterized on: + 1) storage implementation + 2) initial data size + 3) length of keys + 4) length of data + 5) block size (frequency of copy/hash...) +Thus, we would see the same benchmark run against memdb with 100K items, goleveldb with 100K, leveldb with 100K, memdb with 10K, goleveldb with 10K... + +Scenarios to run after db is set up. + * Pure query time (known/hits, vs. random/misses) + * Write timing (known/updates, vs. random/inserts) + * Delete timing (existing keys only) + * TMSP Usage: + * For each block size: + * 2x copy "last commit" -> check and real + * repeat for each tx: + * (50% update + 50% insert?) + * query + insert/update in check + * query + insert/update in real + * get hash + * save real + * real -> "last commit" + + +## Benchmarks + +After writing the benchmarks, we can run them under various environments and store the results under benchmarks directory. Some useful environments to test: + + * Dev machines + * Digital ocean small/large machine + * Various AWS setups + +Please run the benchmark on more machines and add the result. Just type: `make record` in the directory and wait a (long) while (with little other load on the machine). + +This will require also a quick setup script to install go and run tests in these environments. Maybe some scripts even. Also, this will produce a lot of files and we may have to graph them to see something useful... + +But for starting, my laptop, and one digital ocean and one aws server should be sufficient. At least to find the winner, before profiling. + + +## Profiling + +Once we figure out which current implementation looks fastest, let's profile it to make it even faster. It is great to optimize the memdb code to really speed up the hashing and tree-building logic. And then focus on the backend implementation to optimize the disk storage, which will be the next major pain point. + +Some guides: + + * [Profiling benchmarks locally](https://medium.com/@hackintoshrao/daily-code-optimization-using-benchmarks-and-profiling-in-golang-gophercon-india-2016-talk-874c8b4dc3c5#.jmnd8w2qr) + * [On optimizing memory](https://signalfx.com/blog/a-pattern-for-optimizing-go-2/) + * [Profiling running programs](http://blog.ralch.com/tutorial/golang-performance-and-memory-analysis/) + * [Dave Chenny's profiler pkg](https://github.com/pkg/profile) + +Some ideas for speedups: + + * [Speedup SHA256 100x on ARM](https://blog.minio.io/accelerating-sha256-by-100x-in-golang-on-arm-1517225f5ff4#.pybt7bb3w) + * [Faster SHA256 golang implementation](https://github.com/minio/sha256-simd) + * [Data structure alignment](http://stackoverflow.com/questions/39063530/optimising-datastructure-word-alignment-padding-in-golang) + * [Slice alignment](http://blog.chewxy.com/2016/07/25/on-the-memory-alignment-of-go-slice-values/) + * [Tool to analyze your structs](https://github.com/dominikh/go-structlayout) + +## Tree Re-implementation + +If we want to copy lots of objects, it becomes better to think of using memcpy on large (eg. 4-16KB) buffers than copying individual structs. We also could allocate arrays of structs and align them to remove a lot of memory management and gc overhead. That means going down to some C-level coding... + +Some links for thought: + + * [Array representation of a binary tree](http://www.cse.hut.fi/en/research/SVG/TRAKLA2/tutorials/heap_tutorial/taulukkona.html) + * [Memcpy buffer size timing](http://stackoverflow.com/questions/21038965/why-does-the-speed-of-memcpy-drop-dramatically-every-4kb) + * [Calling memcpy from go](https://github.com/jsgilmore/shm/blob/master/memcpy.go) + * [Unsafe docs](https://godoc.org/unsafe) + * [...and how to use it](https://copyninja.info/blog/workaround-gotypesystems.html) + * [Or maybe just plain copy...](https://godoc.org/builtin#copy) + +## Backend implementation + +Storing each link in the tree in leveldb treats each node as an isolated item. Since we know some usage patterns (when a parent is hit, very likely one child will be hit), we could try to organize the memory and disk location of the nodes ourselves to make it more efficient. Or course, this could be a long, slippery slope. + +Inspired by the [Array representation](http://www.cse.hut.fi/en/research/SVG/TRAKLA2/tutorials/heap_tutorial/taulukkona.html) link above, we could consider other layouts for the nodes. For example, rather than store them alone, or the entire tree in one big array, the nodes could be placed in groups of 15 based on the parent (parent and 3 generations of children). Then we have 4 levels before jumping to another location. Maybe we just store this larger chunk as one leveldb location, or really try to do the mmap ourselves... + +In any case, assuming around 100 bytes for one non-leaf node (3 sha hashes, plus prefix, plus other data), 15 nodes would be a little less than 2K, maybe even go one more level to 31 nodes and 3-4KB, where we could take best advantage of the memory/disk page size. + +Some links for thought: + + * [Memory mapped files](https://github.com/edsrzf/mmap-go) diff --git a/core/vm/lightclient/iavl/POEM b/core/vm/lightclient/iavl/POEM new file mode 100644 index 00000000000..f361067a4da --- /dev/null +++ b/core/vm/lightclient/iavl/POEM @@ -0,0 +1,29 @@ +writing down, my checksum +waiting for the, data to come +no need to pray for integrity +thats cuz I use, a merkle tree + +grab the root, with a quick hash run +if the hash works out, +it must have been done + +theres no need, for trust to arise +thanks to the crypto +now that I can merkleyes + +take that data, merklize +ye, I merklize ... + +then the truth, begins to shine +the inverse of a hash, you will never find +and as I watch, the dataset grow +producing a proof, is never slow + +Where do I find, the will to hash +How do I teach it? +It doesn't pay in cash +Bitcoin, here, I've realized +Thats what I need now, +cuz real currencies merklize + +-EB diff --git a/core/vm/lightclient/iavl/README.md b/core/vm/lightclient/iavl/README.md new file mode 100644 index 00000000000..bb617d9b853 --- /dev/null +++ b/core/vm/lightclient/iavl/README.md @@ -0,0 +1,13 @@ +## IAVL+ Tree + +**Note: Requires Go 1.8+** + +A versioned, snapshottable (immutable) AVL+ tree for persistent data. + +The purpose of this data structure is to provide persistent storage for key-value pairs (say to store account balances) such that a deterministic merkle root hash can be computed. The tree is balanced using a variant of the [AVL algorithm](http://en.wikipedia.org/wiki/AVL_tree) so all operations are O(log(n)). + +Nodes of this tree are immutable and indexed by their hash. Thus any node serves as an immutable snapshot which lets us stage uncommitted transactions from the mempool cheaply, and we can instantly roll back to the last committed state to process transactions of a newly committed block (which may not be the same set of transactions as those from the mempool). + +In an AVL tree, the heights of the two child subtrees of any node differ by at most one. Whenever this condition is violated upon an update, the tree is rebalanced by creating O(log(n)) new nodes that point to unmodified nodes of the old tree. In the original AVL algorithm, inner nodes can also hold key-value pairs. The AVL+ algorithm (note the plus) modifies the AVL algorithm to keep all values on leaf nodes, while only using branch-nodes to store keys. This simplifies the algorithm while keeping the merkle hash trail short. + +In Ethereum, the analog is [Patricia tries](http://en.wikipedia.org/wiki/Radix_tree). There are tradeoffs. Keys do not need to be hashed prior to insertion in IAVL+ trees, so this provides faster iteration in the key space which may benefit some applications. The logic is simpler to implement, requiring only two types of nodes -- inner nodes and leaf nodes. On the other hand, while IAVL+ trees provide a deterministic merkle root hash, it depends on the order of transactions. In practice this shouldn't be a problem, since you can efficiently encode the tree structure when serializing the tree contents. diff --git a/core/vm/lightclient/iavl/doc.go b/core/vm/lightclient/iavl/doc.go new file mode 100644 index 00000000000..7751bccadd2 --- /dev/null +++ b/core/vm/lightclient/iavl/doc.go @@ -0,0 +1,49 @@ +// Package iavl implements a versioned, snapshottable (immutable) AVL+ tree +// for persisting key-value pairs. +// +// +// Basic usage of MutableTree. +// +// import "github.com/tendermint/iavl" +// import "github.com/tendermint/tendermint/libs/db" +// ... +// +// tree := iavl.NewMutableTree(db.NewMemDB(), 128) +// +// tree.IsEmpty() // true +// +// tree.Set([]byte("alice"), []byte("abc")) +// tree.SaveVersion(1) +// +// tree.Set([]byte("alice"), []byte("xyz")) +// tree.Set([]byte("bob"), []byte("xyz")) +// tree.SaveVersion(2) +// +// tree.LatestVersion() // 2 +// +// tree.GetVersioned([]byte("alice"), 1) // "abc" +// tree.GetVersioned([]byte("alice"), 2) // "xyz" +// +// Proof of existence: +// +// root := tree.Hash() +// val, proof, err := tree.GetVersionedWithProof([]byte("bob"), 2) // "xyz", RangeProof, nil +// proof.Verify([]byte("bob"), val, root) // nil +// +// Proof of absence: +// +// _, proof, err = tree.GetVersionedWithProof([]byte("tom"), 2) // nil, RangeProof, nil +// proof.Verify([]byte("tom"), nil, root) // nil +// +// Now we delete an old version: +// +// tree.DeleteVersion(1) +// tree.VersionExists(1) // false +// tree.Get([]byte("alice")) // "xyz" +// tree.GetVersioned([]byte("alice"), 1) // nil +// +// Can't create a proof of absence for a version we no longer have: +// +// _, proof, err = tree.GetVersionedWithProof([]byte("tom"), 1) // nil, nil, error +// +package iavl diff --git a/core/vm/lightclient/iavl/key_format.go b/core/vm/lightclient/iavl/key_format.go new file mode 100644 index 00000000000..b63f9ea7b38 --- /dev/null +++ b/core/vm/lightclient/iavl/key_format.go @@ -0,0 +1,144 @@ +package iavl + +import ( + "encoding/binary" + "fmt" +) + +// Provides a fixed-width lexicographically sortable []byte key format +type KeyFormat struct { + prefix byte + layout []int + length int +} + +// Create a []byte key format based on a single byte prefix and fixed width key segments each of whose length is +// specified by by the corresponding element of layout. +// +// For example, to store keys that could index some objects by a version number and their SHA256 hash using the form: +// 'c' then you would define the KeyFormat with: +// +// var keyFormat = NewKeyFormat('c', 8, 32) +// +// Then you can create a key with: +// +// func ObjectKey(version uint64, objectBytes []byte) []byte { +// hasher := sha256.New() +// hasher.Sum(nil) +// return keyFormat.Key(version, hasher.Sum(nil)) +// } +func NewKeyFormat(prefix byte, layout ...int) *KeyFormat { + // For prefix byte + length := 1 + for _, l := range layout { + length += int(l) + } + return &KeyFormat{ + prefix: prefix, + layout: layout, + length: length, + } +} + +// Format the byte segments into the key format - will panic if the segment lengths do not match the layout. +func (kf *KeyFormat) KeyBytes(segments ...[]byte) []byte { + key := make([]byte, kf.length) + key[0] = kf.prefix + n := 1 + for i, s := range segments { + l := kf.layout[i] + if len(s) > l { + panic(fmt.Errorf("length of segment %X provided to KeyFormat.KeyBytes() is longer than the %d bytes "+ + "required by layout for segment %d", s, l, i)) + } + n += l + // Big endian so pad on left if not given the full width for this segment + copy(key[n-len(s):n], s) + } + return key[:n] +} + +// Format the args passed into the key format - will panic if the arguments passed do not match the length +// of the segment to which they correspond. When called with no arguments returns the raw prefix (useful as a start +// element of the entire keys space when sorted lexicographically). +func (kf *KeyFormat) Key(args ...interface{}) []byte { + if len(args) > len(kf.layout) { + panic(fmt.Errorf("KeyFormat.Key() is provided with %d args but format only has %d segments", + len(args), len(kf.layout))) + } + segments := make([][]byte, len(args)) + for i, a := range args { + segments[i] = format(a) + } + return kf.KeyBytes(segments...) +} + +// Reads out the bytes associated with each segment of the key format from key. +func (kf *KeyFormat) ScanBytes(key []byte) [][]byte { + segments := make([][]byte, len(kf.layout)) + n := 1 + for i, l := range kf.layout { + n += l + if n > len(key) { + return segments[:i] + } + segments[i] = key[n-l : n] + } + return segments +} + +// Extracts the segments into the values pointed to by each of args. Each arg must be a pointer to int64, uint64, or +// []byte, and the width of the args must match layout. +func (kf *KeyFormat) Scan(key []byte, args ...interface{}) { + segments := kf.ScanBytes(key) + if len(args) > len(segments) { + panic(fmt.Errorf("KeyFormat.Scan() is provided with %d args but format only has %d segments in key %X", + len(args), len(segments), key)) + } + for i, a := range args { + scan(a, segments[i]) + } +} + +// Return the prefix as a string. +func (kf *KeyFormat) Prefix() string { + return string([]byte{kf.prefix}) +} + +func scan(a interface{}, value []byte) { + switch v := a.(type) { + case *int64: + // Negative values will be mapped correctly when read in as uint64 and then type converted + *v = int64(binary.BigEndian.Uint64(value)) + case *uint64: + *v = binary.BigEndian.Uint64(value) + case *[]byte: + *v = value + default: + panic(fmt.Errorf("KeyFormat scan() does not support scanning value of type %T: %v", a, a)) + } +} + +func format(a interface{}) []byte { + switch v := a.(type) { + case uint64: + return formatUint64(v) + case int64: + return formatUint64(uint64(v)) + // Provide formatting from int,uint as a convenience to avoid casting arguments + case uint: + return formatUint64(uint64(v)) + case int: + return formatUint64(uint64(v)) + case []byte: + return v + default: + panic(fmt.Errorf("KeyFormat format() does not support formatting value of type %T: %v", a, a)) + } +} + +func formatUint64(v uint64) []byte { + bs := make([]byte, 8) + binary.BigEndian.PutUint64(bs, v) + return bs +} diff --git a/core/vm/lightclient/iavl/key_format_test.go b/core/vm/lightclient/iavl/key_format_test.go new file mode 100644 index 00000000000..b6ea3010d2f --- /dev/null +++ b/core/vm/lightclient/iavl/key_format_test.go @@ -0,0 +1,70 @@ +package iavl + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestKeyFormatBytes(t *testing.T) { + kf := NewKeyFormat(byte('e'), 8, 8, 8) + assert.Equal(t, []byte{'e', 0, 0, 0, 0, 0, 1, 2, 3}, kf.KeyBytes([]byte{1, 2, 3})) + assert.Equal(t, []byte{'e', 1, 2, 3, 4, 5, 6, 7, 8}, kf.KeyBytes([]byte{1, 2, 3, 4, 5, 6, 7, 8})) + assert.Equal(t, []byte{'e', 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 1, 1, 2, 2, 3, 3}, + kf.KeyBytes([]byte{1, 2, 3, 4, 5, 6, 7, 8}, []byte{1, 2, 3, 4, 5, 6, 7, 8}, []byte{1, 1, 2, 2, 3, 3})) + assert.Equal(t, []byte{'e'}, kf.KeyBytes()) +} + +func TestKeyFormat(t *testing.T) { + kf := NewKeyFormat(byte('e'), 8, 8, 8) + key := []byte{'e', 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 200, 0, 0, 0, 0, 0, 0, 1, 144} + var a, b, c int64 = 100, 200, 400 + assert.Equal(t, key, kf.Key(a, b, c)) + + var ao, bo, co = new(int64), new(int64), new(int64) + kf.Scan(key, ao, bo, co) + assert.Equal(t, a, *ao) + assert.Equal(t, b, *bo) + assert.Equal(t, c, *co) + + bs := new([]byte) + kf.Scan(key, ao, bo, bs) + assert.Equal(t, a, *ao) + assert.Equal(t, b, *bo) + assert.Equal(t, []byte{0, 0, 0, 0, 0, 0, 1, 144}, *bs) + + assert.Equal(t, []byte{'e', 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 200}, kf.Key(a, b)) +} + +func TestNegativeKeys(t *testing.T) { + kf := NewKeyFormat(byte('e'), 8, 8) + + var a, b int64 = -100, -200 + // One's complement plus one + key := []byte{'e', + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, byte(0xff + a + 1), + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, byte(0xff + b + 1)} + assert.Equal(t, key, kf.Key(a, b)) + + var ao, bo = new(int64), new(int64) + kf.Scan(key, ao, bo) + assert.Equal(t, a, *ao) + assert.Equal(t, b, *bo) +} + +func TestOverflow(t *testing.T) { + kf := NewKeyFormat(byte('o'), 8, 8) + + var a int64 = 1 << 62 + var b uint64 = 1 << 63 + key := []byte{'o', + 0x40, 0, 0, 0, 0, 0, 0, 0, + 0x80, 0, 0, 0, 0, 0, 0, 0, + } + assert.Equal(t, key, kf.Key(a, b)) + + var ao, bo = new(int64), new(int64) + kf.Scan(key, ao, bo) + assert.Equal(t, a, *ao) + assert.Equal(t, int64(b), *bo) +} diff --git a/core/vm/lightclient/iavl/proof.go b/core/vm/lightclient/iavl/proof.go new file mode 100644 index 00000000000..585c9748823 --- /dev/null +++ b/core/vm/lightclient/iavl/proof.go @@ -0,0 +1,135 @@ +package iavl + +import ( + "bytes" + "fmt" + + "github.com/tendermint/go-amino" + "github.com/tendermint/tendermint/crypto/tmhash" + cmn "github.com/tendermint/tendermint/libs/common" +) + +var ( + // ErrInvalidProof is returned by Verify when a proof cannot be validated. + ErrInvalidProof = fmt.Errorf("invalid proof") + + // ErrInvalidInputs is returned when the inputs passed to the function are invalid. + ErrInvalidInputs = fmt.Errorf("invalid inputs") + + // ErrInvalidRoot is returned when the root passed in does not match the proof's. + ErrInvalidRoot = fmt.Errorf("invalid root") +) + +//---------------------------------------- + +type proofInnerNode struct { + Height int8 `json:"height"` + Size int64 `json:"size"` + Version int64 `json:"version"` + Left []byte `json:"left"` + Right []byte `json:"right"` +} + +func (pin proofInnerNode) String() string { + return pin.stringIndented("") +} + +func (pin proofInnerNode) stringIndented(indent string) string { + return fmt.Sprintf(`proofInnerNode{ +%s Height: %v +%s Size: %v +%s Version: %v +%s Left: %X +%s Right: %X +%s}`, + indent, pin.Height, + indent, pin.Size, + indent, pin.Version, + indent, pin.Left, + indent, pin.Right, + indent) +} + +func (pin proofInnerNode) Hash(childHash []byte) []byte { + hasher := tmhash.New() + buf := new(bytes.Buffer) + + err := amino.EncodeInt8(buf, pin.Height) + if err == nil { + err = amino.EncodeVarint(buf, pin.Size) + } + if err == nil { + err = amino.EncodeVarint(buf, pin.Version) + } + + if len(pin.Left) == 0 { + if err == nil { + err = amino.EncodeByteSlice(buf, childHash) + } + if err == nil { + err = amino.EncodeByteSlice(buf, pin.Right) + } + } else { + if err == nil { + err = amino.EncodeByteSlice(buf, pin.Left) + } + if err == nil { + err = amino.EncodeByteSlice(buf, childHash) + } + } + if err != nil { + panic(fmt.Sprintf("Failed to hash proofInnerNode: %v", err)) + } + + hasher.Write(buf.Bytes()) + return hasher.Sum(nil) +} + +//---------------------------------------- + +type proofLeafNode struct { + Key cmn.HexBytes `json:"key"` + ValueHash cmn.HexBytes `json:"value"` + Version int64 `json:"version"` +} + +func (pln proofLeafNode) String() string { + return pln.stringIndented("") +} + +func (pln proofLeafNode) stringIndented(indent string) string { + return fmt.Sprintf(`proofLeafNode{ +%s Key: %v +%s ValueHash: %X +%s Version: %v +%s}`, + indent, pln.Key, + indent, pln.ValueHash, + indent, pln.Version, + indent) +} + +func (pln proofLeafNode) Hash() []byte { + hasher := tmhash.New() + buf := new(bytes.Buffer) + + err := amino.EncodeInt8(buf, 0) + if err == nil { + err = amino.EncodeVarint(buf, 1) + } + if err == nil { + err = amino.EncodeVarint(buf, pln.Version) + } + if err == nil { + err = amino.EncodeByteSlice(buf, pln.Key) + } + if err == nil { + err = amino.EncodeByteSlice(buf, pln.ValueHash) + } + if err != nil { + panic(fmt.Sprintf("Failed to hash proofLeafNode: %v", err)) + } + hasher.Write(buf.Bytes()) + + return hasher.Sum(nil) +} diff --git a/core/vm/lightclient/iavl/proof_iavl_absence.go b/core/vm/lightclient/iavl/proof_iavl_absence.go new file mode 100644 index 00000000000..88a6587aee3 --- /dev/null +++ b/core/vm/lightclient/iavl/proof_iavl_absence.go @@ -0,0 +1,87 @@ +package iavl + +import ( + "fmt" + + "github.com/tendermint/tendermint/crypto/merkle" + cmn "github.com/tendermint/tendermint/libs/common" +) + +const ProofOpIAVLAbsence = "iavl:a" + +// IAVLAbsenceOp takes a key as its only argument +// +// If the produced root hash matches the expected hash, the proof +// is good. +type IAVLAbsenceOp struct { + // Encoded in ProofOp.Key. + key []byte + + // To encode in ProofOp.Data. + // Proof is nil for an empty tree. + // The hash of an empty tree is nil. + Proof *RangeProof `json:"proof"` +} + +var _ merkle.ProofOperator = IAVLAbsenceOp{} + +func NewIAVLAbsenceOp(key []byte, proof *RangeProof) IAVLAbsenceOp { + return IAVLAbsenceOp{ + key: key, + Proof: proof, + } +} + +func IAVLAbsenceOpDecoder(pop merkle.ProofOp) (merkle.ProofOperator, error) { + if pop.Type != ProofOpIAVLAbsence { + return nil, cmn.NewError("unexpected ProofOp.Type; got %v, want %v", pop.Type, ProofOpIAVLAbsence) + } + var op IAVLAbsenceOp // a bit strange as we'll discard this, but it works. + err := cdc.UnmarshalBinaryLengthPrefixed(pop.Data, &op) + if err != nil { + return nil, cmn.ErrorWrap(err, "decoding ProofOp.Data into IAVLAbsenceOp") + } + return NewIAVLAbsenceOp(pop.Key, op.Proof), nil +} + +func (op IAVLAbsenceOp) ProofOp() merkle.ProofOp { + bz := cdc.MustMarshalBinaryLengthPrefixed(op) + return merkle.ProofOp{ + Type: ProofOpIAVLAbsence, + Key: op.key, + Data: bz, + } +} + +func (op IAVLAbsenceOp) String() string { + return fmt.Sprintf("IAVLAbsenceOp{%v}", op.GetKey()) +} + +func (op IAVLAbsenceOp) Run(args [][]byte) ([][]byte, error) { + if len(args) != 0 { + return nil, cmn.NewError("expected 0 args, got %v", len(args)) + } + // If the tree is nil, the proof is nil, and all keys are absent. + if op.Proof == nil { + return [][]byte{[]byte(nil)}, nil + } + // Compute the root hash and assume it is valid. + // The caller checks the ultimate root later. + root := op.Proof.ComputeRootHash() + err := op.Proof.Verify(root) + if err != nil { + return nil, cmn.ErrorWrap(err, "computing root hash") + } + // XXX What is the encoding for keys? + // We should decode the key depending on whether it's a string or hex, + // maybe based on quotes and 0x prefix? + err = op.Proof.VerifyAbsence([]byte(op.key)) + if err != nil { + return nil, cmn.ErrorWrap(err, "verifying absence") + } + return [][]byte{root}, nil +} + +func (op IAVLAbsenceOp) GetKey() []byte { + return op.key +} diff --git a/core/vm/lightclient/iavl/proof_iavl_value.go b/core/vm/lightclient/iavl/proof_iavl_value.go new file mode 100644 index 00000000000..df3c905ef8d --- /dev/null +++ b/core/vm/lightclient/iavl/proof_iavl_value.go @@ -0,0 +1,86 @@ +package iavl + +import ( + "fmt" + + "github.com/tendermint/tendermint/crypto/merkle" + cmn "github.com/tendermint/tendermint/libs/common" +) + +const ProofOpIAVLValue = "iavl:v" + +// IAVLValueOp takes a key and a single value as argument and +// produces the root hash. +// +// If the produced root hash matches the expected hash, the proof +// is good. +type IAVLValueOp struct { + // Encoded in ProofOp.Key. + key []byte + + // To encode in ProofOp.Data. + // Proof is nil for an empty tree. + // The hash of an empty tree is nil. + Proof *RangeProof `json:"proof"` +} + +var _ merkle.ProofOperator = IAVLValueOp{} + +func NewIAVLValueOp(key []byte, proof *RangeProof) IAVLValueOp { + return IAVLValueOp{ + key: key, + Proof: proof, + } +} + +func IAVLValueOpDecoder(pop merkle.ProofOp) (merkle.ProofOperator, error) { + if pop.Type != ProofOpIAVLValue { + return nil, cmn.NewError("unexpected ProofOp.Type; got %v, want %v", pop.Type, ProofOpIAVLValue) + } + var op IAVLValueOp // a bit strange as we'll discard this, but it works. + err := cdc.UnmarshalBinaryLengthPrefixed(pop.Data, &op) + if err != nil { + return nil, cmn.ErrorWrap(err, "decoding ProofOp.Data into IAVLValueOp") + } + return NewIAVLValueOp(pop.Key, op.Proof), nil +} + +func (op IAVLValueOp) ProofOp() merkle.ProofOp { + bz := cdc.MustMarshalBinaryLengthPrefixed(op) + return merkle.ProofOp{ + Type: ProofOpIAVLValue, + Key: op.key, + Data: bz, + } +} + +func (op IAVLValueOp) String() string { + return fmt.Sprintf("IAVLValueOp{%v}", op.GetKey()) +} + +func (op IAVLValueOp) Run(args [][]byte) ([][]byte, error) { + if len(args) != 1 { + return nil, cmn.NewError("Value size is not 1") + } + value := args[0] + + // Compute the root hash and assume it is valid. + // The caller checks the ultimate root later. + root := op.Proof.ComputeRootHash() + err := op.Proof.Verify(root) + if err != nil { + return nil, cmn.ErrorWrap(err, "computing root hash") + } + // XXX What is the encoding for keys? + // We should decode the key depending on whether it's a string or hex, + // maybe based on quotes and 0x prefix? + err = op.Proof.VerifyItem([]byte(op.key), value) + if err != nil { + return nil, cmn.ErrorWrap(err, "verifying value") + } + return [][]byte{root}, nil +} + +func (op IAVLValueOp) GetKey() []byte { + return op.key +} diff --git a/core/vm/lightclient/iavl/proof_path.go b/core/vm/lightclient/iavl/proof_path.go new file mode 100644 index 00000000000..de366f33813 --- /dev/null +++ b/core/vm/lightclient/iavl/proof_path.go @@ -0,0 +1,167 @@ +package iavl + +import ( + "bytes" + "fmt" + "strings" + + cmn "github.com/tendermint/tendermint/libs/common" +) + +// pathWithLeaf is a path to a leaf node and the leaf node itself. +type pathWithLeaf struct { + Path PathToLeaf `json:"path"` + Leaf proofLeafNode `json:"leaf"` +} + +func (pwl pathWithLeaf) String() string { + return pwl.StringIndented("") +} + +func (pwl pathWithLeaf) StringIndented(indent string) string { + return fmt.Sprintf(`pathWithLeaf{ +%s Path: %v +%s Leaf: %v +%s}`, + indent, pwl.Path.stringIndented(indent+" "), + indent, pwl.Leaf.stringIndented(indent+" "), + indent) +} + +// `verify` checks that the leaf node's hash + the inner nodes merkle-izes to +// the given root. If it returns an error, it means the leafHash or the +// PathToLeaf is incorrect. +func (pwl pathWithLeaf) verify(root []byte) cmn.Error { + leafHash := pwl.Leaf.Hash() + return pwl.Path.verify(leafHash, root) +} + +// `computeRootHash` computes the root hash with leaf node. +// Does not verify the root hash. +func (pwl pathWithLeaf) computeRootHash() []byte { + leafHash := pwl.Leaf.Hash() + return pwl.Path.computeRootHash(leafHash) +} + +//---------------------------------------- + +// PathToLeaf represents an inner path to a leaf node. +// Note that the nodes are ordered such that the last one is closest +// to the root of the tree. +type PathToLeaf []proofInnerNode + +func (pl PathToLeaf) String() string { + return pl.stringIndented("") +} + +func (pl PathToLeaf) stringIndented(indent string) string { + if len(pl) == 0 { + return "empty-PathToLeaf" + } + strs := make([]string, len(pl)) + for i, pin := range pl { + if i == 20 { + strs[i] = fmt.Sprintf("... (%v total)", len(pl)) + break + } + strs[i] = fmt.Sprintf("%v:%v", i, pin.stringIndented(indent+" ")) + } + return fmt.Sprintf(`PathToLeaf{ +%s %v +%s}`, + indent, strings.Join(strs, "\n"+indent+" "), + indent) +} + +// `verify` checks that the leaf node's hash + the inner nodes merkle-izes to +// the given root. If it returns an error, it means the leafHash or the +// PathToLeaf is incorrect. +func (pl PathToLeaf) verify(leafHash []byte, root []byte) cmn.Error { + hash := leafHash + for i := len(pl) - 1; i >= 0; i-- { + pin := pl[i] + hash = pin.Hash(hash) + } + if !bytes.Equal(root, hash) { + return cmn.ErrorWrap(ErrInvalidProof, "") + } + return nil +} + +// `computeRootHash` computes the root hash assuming some leaf hash. +// Does not verify the root hash. +func (pl PathToLeaf) computeRootHash(leafHash []byte) []byte { + hash := leafHash + for i := len(pl) - 1; i >= 0; i-- { + pin := pl[i] + hash = pin.Hash(hash) + } + return hash +} + +func (pl PathToLeaf) isLeftmost() bool { + for _, node := range pl { + if len(node.Left) > 0 { + return false + } + } + return true +} + +func (pl PathToLeaf) isRightmost() bool { + for _, node := range pl { + if len(node.Right) > 0 { + return false + } + } + return true +} + +func (pl PathToLeaf) isEmpty() bool { + return pl == nil || len(pl) == 0 +} + +func (pl PathToLeaf) dropRoot() PathToLeaf { + if pl.isEmpty() { + return pl + } + return PathToLeaf(pl[:len(pl)-1]) +} + +func (pl PathToLeaf) hasCommonRoot(pl2 PathToLeaf) bool { + if pl.isEmpty() || pl2.isEmpty() { + return false + } + leftEnd := pl[len(pl)-1] + rightEnd := pl2[len(pl2)-1] + + return bytes.Equal(leftEnd.Left, rightEnd.Left) && + bytes.Equal(leftEnd.Right, rightEnd.Right) +} + +func (pl PathToLeaf) isLeftAdjacentTo(pl2 PathToLeaf) bool { + for pl.hasCommonRoot(pl2) { + pl, pl2 = pl.dropRoot(), pl2.dropRoot() + } + pl, pl2 = pl.dropRoot(), pl2.dropRoot() + + return pl.isRightmost() && pl2.isLeftmost() +} + +// returns -1 if invalid. +func (pl PathToLeaf) Index() (idx int64) { + for i, node := range pl { + if node.Left == nil { + continue + } else if node.Right == nil { + if i < len(pl)-1 { + idx += node.Size - pl[i+1].Size + } else { + idx += node.Size - 1 + } + } else { + return -1 + } + } + return idx +} diff --git a/core/vm/lightclient/iavl/proof_range.go b/core/vm/lightclient/iavl/proof_range.go new file mode 100644 index 00000000000..caca3fa293a --- /dev/null +++ b/core/vm/lightclient/iavl/proof_range.go @@ -0,0 +1,305 @@ +package iavl + +import ( + "bytes" + "fmt" + "sort" + "strings" + + "github.com/tendermint/tendermint/crypto/tmhash" + cmn "github.com/tendermint/tendermint/libs/common" +) + +type RangeProof struct { + // You don't need the right path because + // it can be derived from what we have. + LeftPath PathToLeaf `json:"left_path"` + InnerNodes []PathToLeaf `json:"inner_nodes"` + Leaves []proofLeafNode `json:"leaves"` + + // memoize + rootVerified bool + rootHash []byte // valid iff rootVerified is true + treeEnd bool // valid iff rootVerified is true + +} + +// Keys returns all the keys in the RangeProof. NOTE: The keys here may +// include more keys than provided by tree.GetRangeWithProof or +// MutableTree.GetVersionedRangeWithProof. The keys returned there are only +// in the provided [startKey,endKey){limit} range. The keys returned here may +// include extra keys, such as: +// - the key before startKey if startKey is provided and doesn't exist; +// - the key after a queried key with tree.GetWithProof, when the key is absent. +func (proof *RangeProof) Keys() (keys [][]byte) { + if proof == nil { + return nil + } + for _, leaf := range proof.Leaves { + keys = append(keys, leaf.Key) + } + return keys +} + +// String returns a string representation of the proof. +func (proof *RangeProof) String() string { + if proof == nil { + return "" + } + return proof.StringIndented("") +} + +func (proof *RangeProof) StringIndented(indent string) string { + istrs := make([]string, 0, len(proof.InnerNodes)) + for _, ptl := range proof.InnerNodes { + istrs = append(istrs, ptl.stringIndented(indent+" ")) + } + lstrs := make([]string, 0, len(proof.Leaves)) + for _, leaf := range proof.Leaves { + lstrs = append(lstrs, leaf.stringIndented(indent+" ")) + } + return fmt.Sprintf(`RangeProof{ +%s LeftPath: %v +%s InnerNodes: +%s %v +%s Leaves: +%s %v +%s (rootVerified): %v +%s (rootHash): %X +%s (treeEnd): %v +%s}`, + indent, proof.LeftPath.stringIndented(indent+" "), + indent, + indent, strings.Join(istrs, "\n"+indent+" "), + indent, + indent, strings.Join(lstrs, "\n"+indent+" "), + indent, proof.rootVerified, + indent, proof.rootHash, + indent, proof.treeEnd, + indent) +} + +// The index of the first leaf (of the whole tree). +// Returns -1 if the proof is nil. +func (proof *RangeProof) LeftIndex() int64 { + if proof == nil { + return -1 + } + return proof.LeftPath.Index() +} + +// Also see LeftIndex(). +// Verify that a key has some value. +// Does not assume that the proof itself is valid, call Verify() first. +func (proof *RangeProof) VerifyItem(key, value []byte) error { + leaves := proof.Leaves + if proof == nil { + return cmn.ErrorWrap(ErrInvalidProof, "proof is nil") + } + if !proof.rootVerified { + return cmn.NewError("must call Verify(root) first.") + } + i := sort.Search(len(leaves), func(i int) bool { + return bytes.Compare(key, leaves[i].Key) <= 0 + }) + if i >= len(leaves) || !bytes.Equal(leaves[i].Key, key) { + return cmn.ErrorWrap(ErrInvalidProof, "leaf key not found in proof") + } + valueHash := tmhash.Sum(value) + if !bytes.Equal(leaves[i].ValueHash, valueHash) { + return cmn.ErrorWrap(ErrInvalidProof, "leaf value hash not same") + } + return nil +} + +// Verify that proof is valid absence proof for key. +// Does not assume that the proof itself is valid. +// For that, use Verify(root). +func (proof *RangeProof) VerifyAbsence(key []byte) error { + if proof == nil { + return cmn.ErrorWrap(ErrInvalidProof, "proof is nil") + } + if !proof.rootVerified { + return cmn.NewError("must call Verify(root) first.") + } + cmp := bytes.Compare(key, proof.Leaves[0].Key) + if cmp < 0 { + if proof.LeftPath.isLeftmost() { + return nil + } else { + return cmn.NewError("absence not proved by left path") + } + } else if cmp == 0 { + return cmn.NewError("absence disproved via first item #0") + } + if len(proof.LeftPath) == 0 { + return nil // proof ok + } + if proof.LeftPath.isRightmost() { + return nil + } + + // See if any of the leaves are greater than key. + for i := 1; i < len(proof.Leaves); i++ { + leaf := proof.Leaves[i] + cmp := bytes.Compare(key, leaf.Key) + if cmp < 0 { + return nil // proof ok + } else if cmp == 0 { + return cmn.NewError("absence disproved via item #%v", i) + } else { + if i == len(proof.Leaves)-1 { + // If last item, check whether + // it's the last item in teh tree. + + } + continue + } + } + + // It's still a valid proof if our last leaf is the rightmost child. + if proof.treeEnd { + return nil // OK! + } + + // It's not a valid absence proof. + if len(proof.Leaves) < 2 { + return cmn.NewError("absence not proved by right leaf (need another leaf?)") + } else { + return cmn.NewError("absence not proved by right leaf") + } +} + +// Verify that proof is valid. +func (proof *RangeProof) Verify(root []byte) error { + if proof == nil { + return cmn.ErrorWrap(ErrInvalidProof, "proof is nil") + } + err := proof.verify(root) + return err +} + +func (proof *RangeProof) verify(root []byte) (err error) { + rootHash := proof.rootHash + if rootHash == nil { + derivedHash, err := proof.computeRootHash() + if err != nil { + return err + } + rootHash = derivedHash + } + if !bytes.Equal(rootHash, root) { + return cmn.ErrorWrap(ErrInvalidRoot, "root hash doesn't match") + } else { + proof.rootVerified = true + } + return nil +} + +// ComputeRootHash computes the root hash with leaves. +// Returns nil if error or proof is nil. +// Does not verify the root hash. +func (proof *RangeProof) ComputeRootHash() []byte { + if proof == nil { + return nil + } + rootHash, _ := proof.computeRootHash() + return rootHash +} + +func (proof *RangeProof) computeRootHash() (rootHash []byte, err error) { + rootHash, treeEnd, err := proof._computeRootHash() + if err == nil { + proof.rootHash = rootHash // memoize + proof.treeEnd = treeEnd // memoize + } + return rootHash, err +} + +func (proof *RangeProof) _computeRootHash() (rootHash []byte, treeEnd bool, err error) { + if len(proof.Leaves) == 0 { + return nil, false, cmn.ErrorWrap(ErrInvalidProof, "no leaves") + } + if len(proof.InnerNodes)+1 != len(proof.Leaves) { + return nil, false, cmn.ErrorWrap(ErrInvalidProof, "InnerNodes vs Leaves length mismatch, leaves should be 1 more.") + } + + // Start from the left path and prove each leaf. + + // shared across recursive calls + var leaves = proof.Leaves + var innersq = proof.InnerNodes + var COMPUTEHASH func(path PathToLeaf, rightmost bool) (hash []byte, treeEnd bool, done bool, err error) + + // rightmost: is the root a rightmost child of the tree? + // treeEnd: true iff the last leaf is the last item of the tree. + // Returns the (possibly intermediate, possibly root) hash. + COMPUTEHASH = func(path PathToLeaf, rightmost bool) (hash []byte, treeEnd bool, done bool, err error) { + + // Pop next leaf. + nleaf, rleaves := leaves[0], leaves[1:] + leaves = rleaves + + // Compute hash. + hash = (pathWithLeaf{ + Path: path, + Leaf: nleaf, + }).computeRootHash() + + // If we don't have any leaves left, we're done. + if len(leaves) == 0 { + rightmost = rightmost && path.isRightmost() + return hash, rightmost, true, nil + } + + // Prove along path (until we run out of leaves). + for len(path) > 0 { + + // Drop the leaf-most (last-most) inner nodes from path + // until we encounter one with a left hash. + // We assume that the left side is already verified. + // rpath: rest of path + // lpath: last path item + rpath, lpath := path[:len(path)-1], path[len(path)-1] + path = rpath + if len(lpath.Right) == 0 { + continue + } + + // Pop next inners, a PathToLeaf (e.g. []proofInnerNode). + inners, rinnersq := innersq[0], innersq[1:] + innersq = rinnersq + + // Recursively verify inners against remaining leaves. + derivedRoot, treeEnd, done, err := COMPUTEHASH(inners, rightmost && rpath.isRightmost()) + if err != nil { + return nil, treeEnd, false, cmn.ErrorWrap(err, "recursive COMPUTEHASH call") + } + if !bytes.Equal(derivedRoot, lpath.Right) { + return nil, treeEnd, false, cmn.ErrorWrap(ErrInvalidRoot, "intermediate root hash %X doesn't match, got %X", lpath.Right, derivedRoot) + } + if done { + return hash, treeEnd, true, nil + } + } + + // We're not done yet (leaves left over). No error, not done either. + // Technically if rightmost, we know there's an error "left over leaves + // -- malformed proof", but we return that at the top level, below. + return hash, false, false, nil + } + + // Verify! + path := proof.LeftPath + rootHash, treeEnd, done, err := COMPUTEHASH(path, true) + if err != nil { + return nil, treeEnd, cmn.ErrorWrap(err, "root COMPUTEHASH call") + } else if !done { + return nil, treeEnd, cmn.ErrorWrap(ErrInvalidProof, "left over leaves -- malformed proof") + } + + // Ok! + return rootHash, treeEnd, nil +} + +/////////////////////////////////////////////////////////////////////////////// diff --git a/core/vm/lightclient/iavl/version.go b/core/vm/lightclient/iavl/version.go new file mode 100644 index 00000000000..5b1eba83dc6 --- /dev/null +++ b/core/vm/lightclient/iavl/version.go @@ -0,0 +1,4 @@ +package iavl + +// Version of iavl. +const Version = "0.12.0" diff --git a/core/vm/lightclient/iavl/wire.go b/core/vm/lightclient/iavl/wire.go new file mode 100644 index 00000000000..8549ae4ab3e --- /dev/null +++ b/core/vm/lightclient/iavl/wire.go @@ -0,0 +1,17 @@ +package iavl + +import ( + "github.com/tendermint/go-amino" +) + +var cdc = amino.NewCodec() + +func init() { + // NOTE: It's important that there be no conflicts here, + // as that would change the canonical representations. + RegisterWire(cdc) +} + +func RegisterWire(cdc *amino.Codec) { + // TODO +} diff --git a/core/vm/lightclient/multistoreproof.go b/core/vm/lightclient/multistoreproof.go index 819b7f00118..fd00c2f1401 100644 --- a/core/vm/lightclient/multistoreproof.go +++ b/core/vm/lightclient/multistoreproof.go @@ -4,7 +4,7 @@ import ( "bytes" "fmt" - "github.com/tendermint/iavl" + iavl2 "github.com/ledgerwatch/erigon/core/vm/lightclient/iavl" "github.com/tendermint/tendermint/crypto/merkle" cmn "github.com/tendermint/tendermint/libs/common" ) @@ -131,8 +131,8 @@ func (op MultiStoreProofOp) Run(args [][]byte) ([][]byte, error) { func DefaultProofRuntime() (prt *merkle.ProofRuntime) { prt = merkle.NewProofRuntime() prt.RegisterOpDecoder(merkle.ProofOpSimpleValue, merkle.SimpleValueOpDecoder) - prt.RegisterOpDecoder(iavl.ProofOpIAVLValue, iavl.IAVLValueOpDecoder) - prt.RegisterOpDecoder(iavl.ProofOpIAVLAbsence, iavl.IAVLAbsenceOpDecoder) + prt.RegisterOpDecoder(iavl2.ProofOpIAVLValue, iavl2.IAVLValueOpDecoder) + prt.RegisterOpDecoder(iavl2.ProofOpIAVLAbsence, iavl2.IAVLAbsenceOpDecoder) prt.RegisterOpDecoder(ProofOpMultiStore, MultiStoreProofOpDecoder) return } diff --git a/core/vm/lightclient/utils.go b/core/vm/lightclient/utils.go index 381866b146a..20da6a1347b 100644 --- a/core/vm/lightclient/utils.go +++ b/core/vm/lightclient/utils.go @@ -1,5 +1,6 @@ package lightclient +/* import ( "fmt" @@ -84,3 +85,4 @@ func QueryKeyWithProof(node rpcclient.Client, key []byte, storeName string, heig return key, result.Response.Value, proofBytes, nil } +*/ diff --git a/eth/backend.go b/eth/backend.go index 60c958378c8..84732a47838 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -180,7 +180,10 @@ func New(stack *node.Node, config *ethconfig.Config, txpoolCfg txpool2.Config, l return nil, genesisErr } - config.SyncMode = ethconfig.SyncModeByChainName(chainConfig.ChainName, config.SyncModeCli) + config.SyncMode, err = ethconfig.SyncModeByChainName(chainConfig.ChainName, config.SyncModeCli) + if err != nil { + return nil, err + } config.Snapshot.Enabled = config.SyncMode == ethconfig.SnapSync types.SetHeaderSealFlag(chainConfig.IsHeaderWithSeal()) @@ -276,6 +279,9 @@ func New(stack *node.Node, config *ethconfig.Config, txpoolCfg txpool2.Config, l var allSnapshots *snapshotsync.RoSnapshots if config.Snapshot.Enabled { allSnapshots = snapshotsync.NewRoSnapshots(config.Snapshot, config.SnapDir) + if err = allSnapshots.Reopen(); err != nil { + return nil, fmt.Errorf("[Snapshots] Reopen: %w", err) + } blockReader = snapshotsync.NewBlockReaderWithSnapshots(allSnapshots) if len(stack.Config().DownloaderAddr) > 0 { diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index 654e72dc7fc..83b20e5e7a2 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -18,6 +18,7 @@ package ethconfig import ( + "fmt" "math/big" "os" "os/user" @@ -224,17 +225,19 @@ const ( SnapSync SyncMode = "snap" ) -func SyncModeByChainName(chain, syncCliFlag string) SyncMode { +func SyncModeByChainName(chain, syncCliFlag string) (SyncMode, error) { if syncCliFlag == "full" { - return FullSync + return FullSync, nil } else if syncCliFlag == "snap" { - return SnapSync + return SnapSync, nil + } else if syncCliFlag != "" { + return FullSync, fmt.Errorf("unexpected syncmode: %s, only next options are valid: %s, %s", syncCliFlag, FullSync, SnapSync) } switch chain { case networkname.MainnetChainName, networkname.BSCChainName, networkname.GoerliChainName, networkname.RopstenChainName: - return SnapSync + return SnapSync, nil default: - return FullSync + return FullSync, nil } } diff --git a/eth/stagedsync/stage_senders.go b/eth/stagedsync/stage_senders.go index 98b3f2a07f8..b2dd9e1164c 100644 --- a/eth/stagedsync/stage_senders.go +++ b/eth/stagedsync/stage_senders.go @@ -378,10 +378,10 @@ func PruneSendersStage(s *PruneState, tx kv.RwTx, cfg SendersCfg, ctx context.Co if cfg.blockRetire.Snapshots() != nil && cfg.blockRetire.Snapshots().Cfg().Enabled { if !cfg.blockRetire.Snapshots().Cfg().KeepBlocks { canDeleteTo := snapshotsync.CanDeleteTo(s.ForwardProgress, cfg.blockRetire.Snapshots()) - if err := rawdb.DeleteAncientBlocks(tx, canDeleteTo, 1_000); err != nil { + if err := rawdb.DeleteAncientBlocks(tx, canDeleteTo, 100); err != nil { return nil } - if err = PruneTable(tx, kv.Senders, canDeleteTo, ctx, 1_000); err != nil { + if err = PruneTable(tx, kv.Senders, canDeleteTo, ctx, 100); err != nil { return err } } diff --git a/go.mod b/go.mod index 9d8a442773e..fe6bfac63e9 100644 --- a/go.mod +++ b/go.mod @@ -2,8 +2,6 @@ module github.com/ledgerwatch/erigon go 1.18 -replace github.com/etcd-io/bbolt => go.etcd.io/bbolt v1.3.5 - require ( github.com/RoaringBitmap/roaring v0.9.4 github.com/VictoriaMetrics/fastcache v1.10.0 @@ -19,7 +17,7 @@ require ( github.com/dop251/goja v0.0.0-20211011172007-d99e4b8cbf48 github.com/edsrzf/mmap-go v1.0.0 github.com/emicklei/dot v0.16.0 - github.com/emirpasic/gods v1.12.0 + github.com/emirpasic/gods v1.18.1 github.com/fjl/gencodec v0.0.0-20191126094850-e283372f291f github.com/goccy/go-json v0.9.7 github.com/gofrs/flock v0.8.1 @@ -36,24 +34,23 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20220519052736-7908982ed957 + github.com/ledgerwatch/erigon-lib v0.0.0-20220521121514-b10a0d15f028 github.com/ledgerwatch/log/v3 v3.4.1 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/pelletier/go-toml v1.9.5 - github.com/pelletier/go-toml/v2 v2.0.0 + github.com/pelletier/go-toml/v2 v2.0.1 github.com/pion/stun v0.3.5 - github.com/quasilyte/go-ruleguard/dsl v0.3.19 + github.com/quasilyte/go-ruleguard/dsl v0.3.21 github.com/rs/cors v1.8.2 github.com/spf13/cobra v1.4.0 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.7.1 github.com/tendermint/go-amino v0.14.1 - github.com/tendermint/iavl v0.12.0 github.com/tendermint/tendermint v0.31.11 github.com/torquem-ch/mdbx-go v0.24.0 github.com/ugorji/go/codec v1.1.13 github.com/ugorji/go/codec/codecgen v1.1.13 - github.com/urfave/cli v1.22.5 + github.com/urfave/cli v1.22.8 github.com/valyala/fastjson v1.6.3 github.com/wcharczuk/go-chart/v2 v2.1.0 github.com/xsleonard/go-merkle v1.1.0 @@ -88,16 +85,13 @@ require ( github.com/anacrolix/upnp v0.1.3-0.20220123035249-922794e51c96 // indirect github.com/anacrolix/utp v0.1.0 // indirect github.com/benbjohnson/immutable v0.3.0 // indirect - github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.2.0 // indirect github.com/bradfitz/iter v0.0.0-20191230175014-e8f45d346db8 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 // indirect github.com/dustin/go-humanize v1.0.0 // indirect - github.com/etcd-io/bbolt v1.3.3 // indirect github.com/flanglet/kanzi-go v1.9.1-0.20211212184056-72dda96261ee // indirect - github.com/fortytw2/leaktest v1.3.0 // indirect github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61 // indirect github.com/go-kit/kit v0.10.0 // indirect github.com/go-logfmt/logfmt v0.5.0 // indirect @@ -109,14 +103,12 @@ require ( github.com/google/uuid v1.3.0 // indirect github.com/huandu/xstrings v1.3.2 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect - github.com/jmhodges/levigo v1.0.0 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/kr/pretty v0.3.0 // indirect github.com/kr/text v0.2.0 // indirect github.com/magiconair/properties v1.8.6 // indirect github.com/mattn/go-colorable v0.1.11 // indirect github.com/mattn/go-isatty v0.0.14 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mschoch/smat v0.2.0 // indirect @@ -138,17 +130,11 @@ require ( github.com/pion/webrtc/v3 v3.1.24-0.20220208053747-94262c1b2b38 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_golang v1.11.0 // indirect - github.com/prometheus/client_model v0.2.0 // indirect - github.com/prometheus/common v0.30.0 // indirect - github.com/prometheus/procfs v0.7.2 // indirect - github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a // indirect github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect github.com/rogpeppe/go-internal v1.8.0 // indirect github.com/rs/dnscache v0.0.0-20210201191234-295bba877686 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect - github.com/syndtr/goleveldb v1.0.0 // indirect github.com/tidwall/btree v0.7.2-0.20211211132910-4215444137fc // indirect github.com/valyala/fastrand v1.1.0 // indirect github.com/valyala/histogram v1.2.0 // indirect diff --git a/go.sum b/go.sum index 7841fd4897d..871cab464cf 100644 --- a/go.sum +++ b/go.sum @@ -1,44 +1,12 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= crawshaw.io/iox v0.0.0-20181124134642-c51c3df30797 h1:yDf7ARQc637HoxDho7xjqdvO5ZA2Yb+xzv/fOnnvZzw= crawshaw.io/iox v0.0.0-20181124134642-c51c3df30797/go.mod h1:sXBiorCo8c46JlQV3oXPKINnZ8mcqnye1EkVkqsectk= crawshaw.io/sqlite v0.3.2/go.mod h1:igAO5JulrQ1DbdZdtVq48mnZUBAPOeFzer7VhDWNtW4= crawshaw.io/sqlite v0.3.3-0.20210127221821-98b1f83c5508 h1:fILCBBFnjnrQ0whVJlGhfv1E/QiaFDNtGFBObEVRnYg= crawshaw.io/sqlite v0.3.3-0.20210127221821-98b1f83c5508/go.mod h1:igAO5JulrQ1DbdZdtVq48mnZUBAPOeFzer7VhDWNtW4= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/RoaringBitmap/roaring v0.4.7/go.mod h1:8khRDP4HmeXns4xIj9oGrKSz7XTQiJx2zgh7AcNke4w= github.com/RoaringBitmap/roaring v0.4.17/go.mod h1:D3qVegWTmfCaX4Bl5CrBE9hfrSrrXIr8KVNvRsDi1NI= @@ -51,7 +19,6 @@ github.com/VictoriaMetrics/fastcache v1.10.0 h1:5hDJnLsKLpnUEToub7ETuRu8RCkb40wo github.com/VictoriaMetrics/fastcache v1.10.0/go.mod h1:tjiYeEfYXCqacuvYw/7UoDIeJaNxq6132xHICNP77w8= github.com/VictoriaMetrics/metrics v1.18.1 h1:OZ0+kTTto8oPfHnVAnTOoyl0XlRhRkoQrD2n2cOuRw0= github.com/VictoriaMetrics/metrics v1.18.1/go.mod h1:ArjwVz7WpgpegX/JpB0zpNF2h2232kErkEnzH1sxMmA= -github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= @@ -61,7 +28,6 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/anacrolix/chansync v0.3.0 h1:lRu9tbeuw3wl+PhMu/r+JJCRu5ArFXIluOgdF0ao6/U= @@ -134,7 +100,6 @@ github.com/benbjohnson/immutable v0.3.0 h1:TVRhuZx2wG9SZ0LRdqlbs9S5BZ6Y24hJEHTCg github.com/benbjohnson/immutable v0.3.0/go.mod h1:uc6OHo6PN2++n98KHLxW8ef4W42ylHiQSENghE1ezxI= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bits-and-blooms/bitset v1.2.0 h1:Kn4yilvwNtMACtf1eYDlG8H77R07mZSPbMjLyS07ChA= @@ -165,9 +130,6 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= @@ -214,8 +176,8 @@ github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/emicklei/dot v0.16.0 h1:7PseyizTgeQ/aSF1eo4LcEfWlQSlzamFZpzY/nMB9EY= github.com/emicklei/dot v0.16.0/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s= -github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= -github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -228,8 +190,6 @@ github.com/fjl/gencodec v0.0.0-20191126094850-e283372f291f h1:Y/gg/utVetS+WS6htA github.com/fjl/gencodec v0.0.0-20191126094850-e283372f291f/go.mod h1:q+7Z5oyy8cvKF3TakcuihvQvBHFTnXjB+7UP1e2Q+1o= github.com/flanglet/kanzi-go v1.9.1-0.20211212184056-72dda96261ee h1:CaVlPeoz5kJQ+cAOV+ZDdlr3J2FmKyNkGu9LY+x7cDM= github.com/flanglet/kanzi-go v1.9.1-0.20211212184056-72dda96261ee/go.mod h1:/sUSVgDcbjsisuW42GPDgaMqvJ0McZERNICnD7b1nRA= -github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= -github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.9.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y= @@ -248,14 +208,10 @@ github.com/glycerine/goconvey v0.0.0-20180728074245-46e3a41ad493/go.mod h1:Ogl1T github.com/glycerine/goconvey v0.0.0-20190315024820-982ee783a72e/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4= @@ -284,21 +240,12 @@ github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGw github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -323,33 +270,19 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa h1:Q75Upo5UN4JbPFURXZ8nLKYUvF85dyFRop/vQ0Rv+64= github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190309154008-847fc94819f9/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -402,7 +335,6 @@ github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmK github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= @@ -411,21 +343,14 @@ github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+ github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= -github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= @@ -441,7 +366,6 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -456,8 +380,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20220519052736-7908982ed957 h1:yCnjRswSERBaQ+7Srntu9GpfRb9yuqBdggUHhBrcbig= -github.com/ledgerwatch/erigon-lib v0.0.0-20220519052736-7908982ed957/go.mod h1:F5LaFSAgKHxkKjf5bHbtAhU424n+WNRREBssXYNC6Xo= +github.com/ledgerwatch/erigon-lib v0.0.0-20220521121514-b10a0d15f028 h1:j8Jq/xXByc2yGQvwPu32PFA3TwDxAQb7wmoKHWd26pc= +github.com/ledgerwatch/erigon-lib v0.0.0-20220521121514-b10a0d15f028/go.mod h1:F5LaFSAgKHxkKjf5bHbtAhU424n+WNRREBssXYNC6Xo= github.com/ledgerwatch/log/v3 v3.4.1 h1:/xGwlVulXnsO9Uq+tzaExc8OWmXXHU0dnLalpbnY5Bc= github.com/ledgerwatch/log/v3 v3.4.1/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= @@ -478,7 +402,6 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-sqlite3 v1.14.12 h1:TJ1bhYJPV44phC+IMu1u2K/i5RriLTPe+yc68XDJ1Z0= github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= @@ -499,7 +422,6 @@ github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM= github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= @@ -540,8 +462,8 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml/v2 v2.0.0 h1:P7Bq0SaI8nsexyay5UAyDo+ICWy5MQPgEZ5+l8JQTKo= -github.com/pelletier/go-toml/v2 v2.0.0/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= +github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU= +github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= @@ -600,36 +522,23 @@ github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.30.0 h1:JEkYlQnpzrzQFxi6gnukFPdQ+ac82oRhzMcIduJu/Ug= -github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.2 h1:zE6zJjRS9S916ptrZ326OU0++1XRwHgxkvCFflxx6Fo= -github.com/prometheus/procfs v0.7.2/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/quasilyte/go-ruleguard/dsl v0.3.19 h1:5+KTKb2YREUYiqZFEIuifFyBxlcCUPWgNZkWy71XS0Q= -github.com/quasilyte/go-ruleguard/dsl v0.3.19/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ= +github.com/quasilyte/go-ruleguard/dsl v0.3.21 h1:vNkC6fC6qMLzCOGbnIHOd5ixUGgTbp3Z4fGnUgULlDA= +github.com/quasilyte/go-ruleguard/dsl v0.3.21/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= @@ -655,7 +564,6 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/assertions v0.0.0-20190215210624-980c5ac6f3ac/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= @@ -685,12 +593,8 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= -github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/tendermint/go-amino v0.14.1 h1:o2WudxNfdLNBwMyl2dqOJxiro5rfrEaU0Ugs6offJMk= github.com/tendermint/go-amino v0.14.1/go.mod h1:i/UKE5Uocn+argJJBb12qTZsCDBcAYMbR92AaJVmKso= -github.com/tendermint/iavl v0.12.0 h1:xcaFAr+ycqCj7WN1RzL2EfcBioRDOHcU1oWcg83K028= -github.com/tendermint/iavl v0.12.0/go.mod h1:EoKMMv++tDOL5qKKVnoIqtVPshRrEPeJ0WsgDOLAauM= github.com/tendermint/tendermint v0.31.11 h1:TIs//4WfEAG4TOZc2eUfJPI3T8KrywXQCCPnGAaM1Wo= github.com/tendermint/tendermint v0.31.11/go.mod h1:ymcPyWblXCplCPQjbOYbrF1fWnpslATMVqiGgWbZrlc= github.com/tidwall/btree v0.7.2-0.20211211132910-4215444137fc h1:THtJVe/QBctKEe8kjnXwt7RAlvHNtUjFJOEmgZkN05w= @@ -708,8 +612,8 @@ github.com/ugorji/go/codec/codecgen v1.1.13 h1:rGpZ4Q63VcWA3DMBbIHvg+SQweUkfXBBa github.com/ugorji/go/codec/codecgen v1.1.13/go.mod h1:EhCxlc7Crov+HLygD4+hBCitXNrrGKRrRWj+pRsyJGg= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU= -github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli v1.22.8 h1:9ic0a+f2TCJ5tSbVRX/FSSCIHJacFLYxcuNexNMJF8Q= +github.com/urfave/cli v1.22.8/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/valyala/fastjson v1.6.3 h1:tAKFnnwmeMGPbwJ7IwxcTPCNr3uIzoIj3/Fh90ra4xc= github.com/valyala/fastjson v1.6.3/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= github.com/valyala/fastrand v1.1.0 h1:f+5HkLW4rsgzdNoleUOB69hyT9IlD2ZQh9GyDMfb5G8= @@ -723,23 +627,16 @@ github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPy github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xsleonard/go-merkle v1.1.0 h1:fHe1fuhJjGH22ZzVTAH0jqHLhTGhOq3wQjJN+8P0jQg= github.com/xsleonard/go-merkle v1.1.0/go.mod h1:cW4z+UZ/4f2n9IJgIiyDCdYguchoDyDAPmpuOWGxdGg= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0= -go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -756,7 +653,6 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -768,37 +664,17 @@ golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220507011949-2cf3adece122 h1:NvGWuYG8dkDHFSKksI1P9faiVJ9rayE6l0+ouWVIDs8= golang.org/x/crypto v0.0.0-20220507011949-2cf3adece122/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20220428152302-39d4317da171 h1:TfdoLivD44QwvssI9Sv1xwa5DcL5XQr4au4sZ2F2NV4= golang.org/x/exp v0.0.0-20220428152302-39d4317da171/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20200927104501-e162460cd6b5 h1:QelT11PB4FXiDEXucrfNckHoFxwt8USGY1ajP1ZF5lM= golang.org/x/image v0.0.0-20200927104501-e162460cd6b5/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o= @@ -817,35 +693,18 @@ golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201201195509-5d6afe98e0b7/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211201190559-0a0e4e1bb54c/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -854,20 +713,14 @@ golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR3 golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -879,50 +732,28 @@ golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210326220804-49726bf1d181/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -935,17 +766,13 @@ golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 h1:nonptSpoQ4vQjyraW20DXPAgl golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220411224347-583f2d630306 h1:+gHMid33q6pen7kv9xvT+JRinntgeXO2AeZVd0AWD3w= golang.org/x/time v0.0.0-20220411224347-583f2d630306/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -955,48 +782,16 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191126055441-b0650ceb63d9/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -1008,60 +803,17 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987 h1:PDIOdWxZ8eRizhKa1AAvY53xsvLB1cWorMjslvY3VA8= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -1069,18 +821,13 @@ google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.46.2 h1:u+MLGgVf7vRdjEYZ8wDFhAVNmhkbJ5hmrA1LMWK1CAQ= @@ -1129,12 +876,8 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= lukechampine.com/uint128 v1.1.1 h1:pnxCASz787iMf+02ssImqk6OLt+Z5QHMoZyUXR4z6JU= lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= modernc.org/cc/v3 v3.33.6/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= @@ -1284,8 +1027,5 @@ modernc.org/z v1.4.0 h1:IpbQb3bOi5Fz17UVGU/mSor8sKIu/7pdCsmGGnQHcxs= modernc.org/z v1.4.0/go.mod h1:x6vxerH3hHCPGA3DAM5pERRzuyJEO4UGVfdQC4NZYl0= pgregory.net/rapid v0.4.7 h1:MTNRktPuv5FNqOO151TM9mDTa+XHcX6ypYeISDVD14g= pgregory.net/rapid v0.4.7/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/params/version.go b/params/version.go index e0dfb8685ec..78cbd91833f 100644 --- a/params/version.go +++ b/params/version.go @@ -33,7 +33,7 @@ var ( const ( VersionMajor = 2022 // Major version component of the current release VersionMinor = 5 // Minor version component of the current release - VersionMicro = 5 // Patch version component of the current release + VersionMicro = 6 // Patch version component of the current release VersionModifier = "alpha" // Modifier component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" diff --git a/rpc/types.go b/rpc/types.go index 86652f023b2..d6ddd664c36 100644 --- a/rpc/types.go +++ b/rpc/types.go @@ -136,6 +136,9 @@ func (bnh *BlockNumberOrHash) UnmarshalJSON(data []byte) error { if e.BlockNumber != nil && e.BlockHash != nil { return fmt.Errorf("cannot specify both BlockHash and BlockNumber, choose one or the other") } + if e.BlockNumber == nil && e.BlockHash == nil { + return fmt.Errorf("at least one of BlockNumber or BlockHash is needed if a dictionary is provided") + } bnh.BlockNumber = e.BlockNumber bnh.BlockHash = e.BlockHash bnh.RequireCanonical = e.RequireCanonical diff --git a/rpc/types_test.go b/rpc/types_test.go index 6b204d101f1..a5ce42daac9 100644 --- a/rpc/types_test.go +++ b/rpc/types_test.go @@ -98,6 +98,8 @@ func TestBlockNumberOrHash_UnmarshalJSON(t *testing.T) { 23: {`{"blockNumber":"latest"}`, false, BlockNumberOrHashWithNumber(LatestBlockNumber)}, 24: {`{"blockNumber":"earliest"}`, false, BlockNumberOrHashWithNumber(EarliestBlockNumber)}, 25: {`{"blockNumber":"0x1", "blockHash":"0x0000000000000000000000000000000000000000000000000000000000000000"}`, true, BlockNumberOrHash{}}, + 26: {`{}`, true, BlockNumberOrHash{}}, + 27: {`{"jsonrpc":"2.0","result":{"code":418,"message":"blabla"},"id":""}]`, true, BlockNumberOrHash{}}, } for i, test := range tests { diff --git a/turbo/app/snapshots.go b/turbo/app/snapshots.go index de183c9ab87..b5704a069de 100644 --- a/turbo/app/snapshots.go +++ b/turbo/app/snapshots.go @@ -21,7 +21,6 @@ import ( "github.com/ledgerwatch/erigon-lib/kv/mdbx" "github.com/ledgerwatch/erigon/cmd/hack/tool" "github.com/ledgerwatch/erigon/cmd/utils" - "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/eth/ethconfig" "github.com/ledgerwatch/erigon/internal/debug" "github.com/ledgerwatch/erigon/params" @@ -250,7 +249,9 @@ func doRetireCommand(cliCtx *cli.Context) error { chainConfig := tool.ChainConfigFromDB(chainDB) chainID, _ := uint256.FromBig(chainConfig.ChainID) snapshots := snapshotsync.NewRoSnapshots(cfg, snapDir) - snapshots.Reopen() + if err := snapshots.Reopen(); err != nil { + return err + } workers := runtime.GOMAXPROCS(-1) - 1 if workers < 1 { @@ -351,47 +352,3 @@ func snapshotBlocks(ctx context.Context, chainDB kv.RoDB, fromBlock, toBlock, bl } return nil } - -//nolint -func checkBlockSnapshot(chaindata string) error { - database := mdbx.MustOpen(chaindata) - defer database.Close() - datadir := path.Dir(chaindata) - chainConfig := tool.ChainConfigFromDB(database) - chainID, _ := uint256.FromBig(chainConfig.ChainID) - _ = chainID - - cfg := ethconfig.NewSnapshotCfg(true, true) - snapshots := snapshotsync.NewRoSnapshots(cfg, filepath.Join(datadir, "snapshots")) - snapshots.Reopen() - //if err := snapshots.BuildIndices(context.Background(), *chainID); err != nil { - // panic(err) - //} - - snBlockReader := snapshotsync.NewBlockReaderWithSnapshots(snapshots) - tx, err := database.BeginRo(context.Background()) - if err != nil { - return err - } - defer tx.Rollback() - - for i := uint64(0); i < snapshots.BlocksAvailable(); i++ { - hash, err := rawdb.ReadCanonicalHash(tx, i) - if err != nil { - return err - } - blockFromDB := rawdb.ReadBlock(tx, hash, i) - blockFromSnapshot, _, err := snBlockReader.BlockWithSenders(context.Background(), tx, hash, i) - if err != nil { - return err - } - - if blockFromSnapshot.Hash() != blockFromDB.Hash() { - panic(i) - } - if i%1_000 == 0 { - log.Info(fmt.Sprintf("Block Num: %dK", i/1_000)) - } - } - return nil -} diff --git a/turbo/snapshotsync/block_reader.go b/turbo/snapshotsync/block_reader.go index b0aa99669c4..c228b5a0459 100644 --- a/turbo/snapshotsync/block_reader.go +++ b/turbo/snapshotsync/block_reader.go @@ -3,6 +3,7 @@ package snapshotsync import ( "bytes" "context" + "encoding/binary" "fmt" "github.com/ledgerwatch/erigon-lib/gointerfaces" @@ -88,6 +89,28 @@ func (back *BlockReader) TxnLookup(ctx context.Context, tx kv.Getter, txnHash co } return *n, true, nil } +func (back *BlockReader) TxnByIdxInBlock(ctx context.Context, tx kv.Getter, blockNum uint64, i int) (txn types.Transaction, err error) { + canonicalHash, err := rawdb.ReadCanonicalHash(tx, blockNum) + if err != nil { + return nil, err + } + var k [8 + 32]byte + binary.BigEndian.PutUint64(k[:], blockNum) + copy(k[8:], canonicalHash[:]) + b, err := rawdb.ReadBodyForStorageByKey(tx, k[:]) + if err != nil { + return nil, err + } + if b == nil { + return nil, nil + } + + txn, err = rawdb.CanonicalTxnByID(tx, b.BaseTxId+1+uint64(i)) + if err != nil { + return nil, err + } + return txn, nil +} type RemoteBlockReader struct { client remote.ETHBACKENDClient @@ -108,6 +131,10 @@ func (back *RemoteBlockReader) TxnLookup(ctx context.Context, tx kv.Getter, txnH return reply.BlockNumber, true, nil } +func (back *RemoteBlockReader) TxnByIdxInBlock(ctx context.Context, tx kv.Getter, blockNum uint64, i int) (txn types.Transaction, err error) { + panic("not implemented") +} + func (back *RemoteBlockReader) BlockWithSenders(ctx context.Context, _ kv.Getter, hash common.Hash, blockHeight uint64) (block *types.Block, senders []common.Address, err error) { reply, err := back.client.Block(ctx, &remote.BlockRequest{BlockHash: gointerfaces.ConvertHashToH256(hash), BlockHeight: blockHeight}) if err != nil { @@ -475,8 +502,23 @@ func (back *BlockReaderWithSnapshots) headerFromSnapshotByHash(hash common.Hash, } func (back *BlockReaderWithSnapshots) bodyFromSnapshot(blockHeight uint64, sn *BodySegment, buf []byte) (*types.Body, uint64, uint32, []byte, error) { + b, buf, err := back.bodyForStorageFromSnapshot(blockHeight, sn, buf) + if err != nil { + return nil, 0, 0, buf, err + } + + body := new(types.Body) + body.Uncles = b.Uncles + var txsAmount uint32 + if b.TxAmount >= 2 { + txsAmount = b.TxAmount - 2 + } + return body, b.BaseTxId + 1, txsAmount, buf, nil // empty txs in the beginning and end of block +} + +func (back *BlockReaderWithSnapshots) bodyForStorageFromSnapshot(blockHeight uint64, sn *BodySegment, buf []byte) (*types.BodyForStorage, []byte, error) { if sn.idxBodyNumber == nil { - return nil, 0, 0, buf, nil + return nil, buf, nil } bodyOffset := sn.idxBodyNumber.Lookup2(blockHeight - sn.idxBodyNumber.BaseDataID()) @@ -484,25 +526,18 @@ func (back *BlockReaderWithSnapshots) bodyFromSnapshot(blockHeight uint64, sn *B gg.Reset(bodyOffset) buf, _ = gg.Next(buf[:0]) if len(buf) == 0 { - return nil, 0, 0, buf, nil + return nil, nil, nil } b := &types.BodyForStorage{} reader := bytes.NewReader(buf) if err := rlp.Decode(reader, b); err != nil { - return nil, 0, 0, buf, err + return nil, buf, err } if b.BaseTxId < sn.idxBodyNumber.BaseDataID() { - return nil, 0, 0, buf, fmt.Errorf(".idx file has wrong baseDataID? %d<%d, %s", b.BaseTxId, sn.idxBodyNumber.BaseDataID(), sn.seg.FilePath()) + return nil, buf, fmt.Errorf(".idx file has wrong baseDataID? %d<%d, %s", b.BaseTxId, sn.idxBodyNumber.BaseDataID(), sn.seg.FilePath()) } - - body := new(types.Body) - body.Uncles = b.Uncles - var txsAmount uint32 - if b.TxAmount >= 2 { - txsAmount = b.TxAmount - 2 - } - return body, b.BaseTxId + 1, txsAmount, buf, nil // empty txs in the beginning and end of block + return b, buf, nil } func (back *BlockReaderWithSnapshots) txsFromSnapshot(baseTxnID uint64, txsAmount uint32, txsSeg *TxnSegment, buf []byte) (txs []types.Transaction, senders []common.Address, err error) { @@ -542,6 +577,21 @@ func (back *BlockReaderWithSnapshots) txsFromSnapshot(baseTxnID uint64, txsAmoun return txs, senders, nil } +func (back *BlockReaderWithSnapshots) txnByID(txnID uint64, sn *TxnSegment, buf []byte) (txn types.Transaction, err error) { + offset := sn.IdxTxnHash.Lookup2(txnID - sn.IdxTxnHash.BaseDataID()) + gg := sn.Seg.MakeGetter() + gg.Reset(offset) + buf, _ = gg.Next(buf[:0]) + sender, txnRlp := buf[1:1+20], buf[1+20:] + + txn, err = types.DecodeTransaction(rlp.NewStream(bytes.NewReader(txnRlp), uint64(len(txnRlp)))) + if err != nil { + return + } + txn.SetSender(*(*common.Address)(sender)) // see: https://tip.golang.org/ref/spec#Conversions_from_slice_to_array_pointer + return +} + func (back *BlockReaderWithSnapshots) txnByHash(txnHash common.Hash, segments []*TxnSegment, buf []byte) (txn types.Transaction, blockNum, txnID uint64, err error) { for i := len(segments) - 1; i >= 0; i-- { sn := segments[i] @@ -578,6 +628,62 @@ func (back *BlockReaderWithSnapshots) txnByHash(txnHash common.Hash, segments [] return } +func (back *BlockReaderWithSnapshots) TxnByIdxInBlock(ctx context.Context, tx kv.Getter, blockNum uint64, i int) (txn types.Transaction, err error) { + var b *types.BodyForStorage + ok, err := back.sn.ViewBodies(blockNum, func(segment *BodySegment) error { + b, _, err = back.bodyForStorageFromSnapshot(blockNum, segment, nil) + if err != nil { + return err + } + if b == nil { + return nil + } + + return nil + }) + if ok { + ok, err = back.sn.Txs.ViewSegment(blockNum, func(segment *TxnSegment) error { + // +1 because block has system-txn in the beginning of block + txn, err = back.txnByID(b.BaseTxId+1+uint64(i), segment, nil) + if err != nil { + return err + } + if txn == nil { + return nil + } + return nil + }) + if err != nil { + return nil, err + } + if ok { + return txn, nil + } + return nil, nil + } + + canonicalHash, err := rawdb.ReadCanonicalHash(tx, blockNum) + if err != nil { + return nil, err + } + var k [8 + 32]byte + binary.BigEndian.PutUint64(k[:], blockNum) + copy(k[8:], canonicalHash[:]) + b, err = rawdb.ReadBodyForStorageByKey(tx, k[:]) + if err != nil { + return nil, err + } + if b == nil { + return nil, nil + } + + txn, err = rawdb.CanonicalTxnByID(tx, b.BaseTxId+1+uint64(i)) + if err != nil { + return nil, err + } + return txn, nil +} + // TxnLookup - find blockNumber and txnID by txnHash func (back *BlockReaderWithSnapshots) TxnLookup(ctx context.Context, tx kv.Getter, txnHash common.Hash) (uint64, bool, error) { n, err := rawdb.ReadTxLookupEntry(tx, txnHash) diff --git a/turbo/snapshotsync/snapshothashes/embed.go b/turbo/snapshotsync/snapshothashes/embed.go index f4e09f83b9a..891a8931782 100644 --- a/turbo/snapshotsync/snapshothashes/embed.go +++ b/turbo/snapshotsync/snapshothashes/embed.go @@ -27,6 +27,10 @@ var Bsc = fromToml(bsc) var ropsten []byte var Ropsten = fromToml(ropsten) +//go:embed erigon-snapshots/mumbai.toml +var mumbai []byte +var Mumbai = fromToml(mumbai) + type PreverifiedItem struct { Name string Hash string @@ -55,6 +59,7 @@ var ( GoerliChainSnapshotConfig = newConfig(Goerli) BscChainSnapshotConfig = newConfig(Bsc) RopstenChainSnapshotConfig = newConfig(Ropsten) + MumbaiChainSnapshotConfig = newConfig(Mumbai) ) func newConfig(preverified Preverified) *Config { @@ -106,6 +111,8 @@ func KnownConfig(networkName string) *Config { return BscChainSnapshotConfig case networkname.RopstenChainName: return RopstenChainSnapshotConfig + case networkname.MumbaiChainName: + return MumbaiChainSnapshotConfig default: return newConfig(Preverified{}) } diff --git a/turbo/snapshotsync/snapshothashes/erigon-snapshots b/turbo/snapshotsync/snapshothashes/erigon-snapshots index 9372e92cb4a..556c0ac3d58 160000 --- a/turbo/snapshotsync/snapshothashes/erigon-snapshots +++ b/turbo/snapshotsync/snapshothashes/erigon-snapshots @@ -1 +1 @@ -Subproject commit 9372e92cb4abe894c1123af8af3bb4d00e73c0b4 +Subproject commit 556c0ac3d58aae931bb404c8fb9aa3101503bb48 diff --git a/turbo/stages/headerdownload/header_algos.go b/turbo/stages/headerdownload/header_algos.go index 5e0a8531290..43c58a5c612 100644 --- a/turbo/stages/headerdownload/header_algos.go +++ b/turbo/stages/headerdownload/header_algos.go @@ -102,16 +102,7 @@ func (hd *HeaderDownload) ReportBadHeader(headerHash common.Hash) { hd.badHeaders[headerHash] = struct{}{} // Find the link, remove it and all its descendands from all the queues if link, ok := hd.links[headerHash]; ok { - removeList := []*Link{link} - for len(removeList) > 0 { - removal := removeList[len(removeList)-1] - removeList = removeList[:len(removeList)-1] - hd.moveLinkToQueue(removal, NoQueue) - delete(hd.links, removal.hash) - for child := removal.fChild; child != nil; child = child.next { - removeList = append(removeList, child) - } - } + hd.removeUpwards(link) } } @@ -146,16 +137,16 @@ func (hd *HeaderDownload) IsBadHeaderPoS(tipHash common.Hash) (bad bool, lastVal } func (hd *HeaderDownload) removeUpwards(link *Link) { - var toRemove []*Link - for child := link; child != nil; child = child.next { - toRemove = append(toRemove, child) + if link == nil { + return } + var toRemove []*Link = []*Link{link} for len(toRemove) > 0 { removal := toRemove[len(toRemove)-1] toRemove = toRemove[:len(toRemove)-1] delete(hd.links, removal.hash) hd.moveLinkToQueue(removal, NoQueue) - for child := removal.fChild; child != nil; child = child.next { + for child := removal.fChild; child != nil; child, child.next = child.next, nil { toRemove = append(toRemove, child) } } @@ -185,6 +176,8 @@ func (hd *HeaderDownload) removeAnchor(anchor *Anchor) { // Anchor is removed from the map, and from the priority queue delete(hd.anchors, anchor.parentHash) heap.Remove(hd.anchorQueue, anchor.idx) + for child := anchor.fLink; child != nil; child, child.next = child.next, nil { + } anchor.idx = -1 } @@ -192,6 +185,8 @@ func (hd *HeaderDownload) pruneLinkQueue() { for hd.linkQueue.Len() > hd.linkLimit { link := heap.Pop(&hd.linkQueue).(*Link) delete(hd.links, link.hash) + for child := link.fChild; child != nil; child, child.next = child.next, nil { + } if parentLink, ok := hd.links[link.header.ParentHash]; ok { var prevChild *Link for child := parentLink.fChild; child != nil && child != link; child = child.next { @@ -295,6 +290,8 @@ func (hd *HeaderDownload) RecoverFromDb(db kv.RoDB) error { for hd.persistedLinkQueue.Len() > 0 { link := heap.Pop(&hd.persistedLinkQueue).(*Link) delete(hd.links, link.hash) + for child := link.fChild; child != nil; child, child.next = child.next, nil { + } } err := db.View(context.Background(), func(tx kv.Tx) error { c, err := tx.Cursor(kv.Headers) @@ -448,7 +445,7 @@ func (hd *HeaderDownload) VerifyHeader(header *types.Header) error { type FeedHeaderFunc = func(header *types.Header, headerRaw []byte, hash common.Hash, blockHeight uint64) (td *big.Int, err error) -func (hd *HeaderDownload) InsertHeader(hf FeedHeaderFunc, terminalTotalDifficulty *big.Int, logPrefix string, logChannel <-chan time.Time) (bool, error) { +func (hd *HeaderDownload) InsertHeader(hf FeedHeaderFunc, terminalTotalDifficulty *big.Int, logPrefix string, logChannel <-chan time.Time) (bool, bool, error) { hd.lock.Lock() defer hd.lock.Unlock() if hd.insertQueue.Len() > 0 && hd.insertQueue[0].blockHeight <= hd.highestInDb+1 { @@ -461,19 +458,21 @@ func (hd *HeaderDownload) InsertHeader(hf FeedHeaderFunc, terminalTotalDifficult // If the link or its parent is marked bad, throw it out hd.moveLinkToQueue(link, NoQueue) delete(hd.links, link.hash) - return true, nil + hd.removeUpwards(link) + return true, false, nil } if !link.verified { if err := hd.VerifyHeader(link.header); err != nil { if errors.Is(err, consensus.ErrFutureBlock) { // This may become valid later log.Warn("Added future link", "hash", link.hash, "height", link.blockHeight, "timestamp", link.header.Time) - return false, nil // prevent removal of the link from the hd.linkQueue + return false, false, nil // prevent removal of the link from the hd.linkQueue } else { log.Debug("Verification failed for header", "hash", link.hash, "height", link.blockHeight, "err", err) hd.moveLinkToQueue(link, NoQueue) delete(hd.links, link.hash) - return true, nil + hd.removeUpwards(link) + return true, false, nil } } } @@ -486,7 +485,7 @@ func (hd *HeaderDownload) InsertHeader(hf FeedHeaderFunc, terminalTotalDifficult } td, err := hf(link.header, link.headerRaw, link.hash, link.blockHeight) if err != nil { - return false, err + return false, false, err } if td != nil { if hd.seenAnnounces.Pop(link.hash) { @@ -496,7 +495,7 @@ func (hd *HeaderDownload) InsertHeader(hf FeedHeaderFunc, terminalTotalDifficult if terminalTotalDifficulty != nil && td.Cmp(terminalTotalDifficulty) >= 0 { hd.highestInDb = link.blockHeight log.Info(POSPandaBanner) - return true, nil + return true, true, nil } } @@ -519,8 +518,10 @@ func (hd *HeaderDownload) InsertHeader(hf FeedHeaderFunc, terminalTotalDifficult for hd.persistedLinkQueue.Len() > hd.persistedLinkLimit { link := heap.Pop(&hd.persistedLinkQueue).(*Link) delete(hd.links, link.hash) + for child := link.fChild; child != nil; child, child.next = child.next, nil { + } } - return hd.insertQueue.Len() > 0 && hd.insertQueue[0].blockHeight <= hd.highestInDb+1, nil + return hd.insertQueue.Len() > 0 && hd.insertQueue[0].blockHeight <= hd.highestInDb+1, false, nil } // InsertHeaders attempts to insert headers into the database, verifying them first @@ -528,10 +529,14 @@ func (hd *HeaderDownload) InsertHeader(hf FeedHeaderFunc, terminalTotalDifficult func (hd *HeaderDownload) InsertHeaders(hf FeedHeaderFunc, terminalTotalDifficulty *big.Int, logPrefix string, logChannel <-chan time.Time) (bool, error) { var more bool = true var err error + var isPos bool for more { - if more, err = hd.InsertHeader(hf, terminalTotalDifficulty, logPrefix, logChannel); err != nil { + if more, isPos, err = hd.InsertHeader(hf, terminalTotalDifficulty, logPrefix, logChannel); err != nil { return false, err } + if isPos { + return true, nil + } } hd.lock.RLock() defer hd.lock.RUnlock() @@ -926,6 +931,8 @@ func (hd *HeaderDownload) ProcessHeaders(csHeaders []ChainSegmentHeader, newBloc requestMore = true } } + hd.lock.Lock() + defer hd.lock.Unlock() log.Trace("Link queue", "size", hd.linkQueue.Len()) if hd.linkQueue.Len() > hd.linkLimit { log.Trace("Too many links, cutting down", "count", hd.linkQueue.Len(), "tried to add", len(csHeaders), "limit", hd.linkLimit) From 327e7d969cf4448153d54761b4f160faf306d0ad Mon Sep 17 00:00:00 2001 From: ledgerwatch Date: Sat, 21 May 2022 20:09:40 +0100 Subject: [PATCH 219/261] [alpha] Move header stuck fix from devel (#4226) * allow --syncmode=snap for bor-mainnnet (#4206) * save * save * allow --syncmode=snap for bor-mainnnet #4206 * allow snap sync for mumbai chain (#4208) * save * mumbai * Bor: GetTransactionReceipt (#4209) * fixed miner.sigfile option (#4210) * Snap: reduced memory footprint on building huffman table (#4214) * save * save * save * save * Remove dependency on leveldb (#4213) * save * save * save * save * save * save * methods to read single txn by txnID (#4215) * It's safe now to open snapshots at app start (#4216) * removed obsolete trie variant (#4172) * up gods lib version (#4217) * Fix `rpc.BlockNumberOrHash` unmarshaling (#4218) * add test * fix unmarshaling bug Co-authored-by: Igor Mandrigin * return err on invalid syncmode (#4219) * save * save * save * fixed kiln bug (#4221) * Clean headers pointers when removing links (#4222) * Clean headers pointers when removing links * Replace the lock Co-authored-by: Alexey Sharp * Makefile: pass docker build arguments (#4212) Dockerfile requires some --build-arg options. Fix "docker" target to pass them. Fix GIT_TAG to reflect the most recent tag related to HEAD, instead of an unrelated most recent tag. Use it as the image VERSION. Image tags need to be passed explicitly if needed: DOCKER_FLAGS='-t erigon:latest' make docker * More header download diagnostics (#4224) Co-authored-by: Alexey Sharp * Clean anchors, forward sort of headers (#4225) Co-authored-by: Alexey Sharp Co-authored-by: Alex Sharov Co-authored-by: Giulio rebuffo Co-authored-by: Artem Tsebrovskiy Co-authored-by: Igor Mandrigin Co-authored-by: Igor Mandrigin Co-authored-by: Alexey Sharp Co-authored-by: battlmonstr --- cmd/sentry/sentry/sentry_multy_client.go | 3 +- eth/stagedsync/stage_headers.go | 2 +- turbo/stages/headerdownload/header_algos.go | 42 ++++++++++++++++----- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/cmd/sentry/sentry/sentry_multy_client.go b/cmd/sentry/sentry/sentry_multy_client.go index 50cb4093971..5fb8c1e2124 100644 --- a/cmd/sentry/sentry/sentry_multy_client.go +++ b/cmd/sentry/sentry/sentry_multy_client.go @@ -488,7 +488,7 @@ func (cs *MultyClient) blockHeaders(ctx context.Context, pkt eth.BlockHeadersPac }) } if cs.Hd.POSSync() { - sort.Sort(headerdownload.HeadersByHeightAndHash(csHeaders)) // Sorting by reverse order of block heights + sort.Sort(headerdownload.HeadersReverseSort(csHeaders)) // Sorting by reverse order of block heights tx, err := cs.db.BeginRo(ctx) defer tx.Rollback() if err != nil { @@ -502,6 +502,7 @@ func (cs *MultyClient) blockHeaders(ctx context.Context, pkt eth.BlockHeadersPac cs.Penalize(ctx, penalties) } } else { + sort.Sort(headerdownload.HeadersSort(csHeaders)) // Sorting by order of block heights canRequestMore := cs.Hd.ProcessHeaders(csHeaders, false /* newBlock */, ConvertH512ToPeerID(peerID)) if canRequestMore { diff --git a/eth/stagedsync/stage_headers.go b/eth/stagedsync/stage_headers.go index 84d359ddc54..003679872c3 100644 --- a/eth/stagedsync/stage_headers.go +++ b/eth/stagedsync/stage_headers.go @@ -821,7 +821,7 @@ Loop: log.Info("Req/resp stats", "req", reqCount, "reqMin", reqMin, "reqMax", reqMax, "skel", skeletonReqCount, "skelMin", skeletonReqMin, "skelMax", skeletonReqMax, "resp", respCount, "respMin", respMin, "respMax", respMax) - + cfg.hd.LogAnchorState() if noProgressCounter >= 5 && wasProgress { log.Warn("Looks like chain is not progressing, moving to the next stage") break Loop diff --git a/turbo/stages/headerdownload/header_algos.go b/turbo/stages/headerdownload/header_algos.go index 43c58a5c612..d7c2fcf62d4 100644 --- a/turbo/stages/headerdownload/header_algos.go +++ b/turbo/stages/headerdownload/header_algos.go @@ -56,13 +56,13 @@ const POSPandaBanner = ` ` // Implements sort.Interface so we can sort the incoming header in the message by block height -type HeadersByHeightAndHash []ChainSegmentHeader +type HeadersReverseSort []ChainSegmentHeader -func (h HeadersByHeightAndHash) Len() int { +func (h HeadersReverseSort) Len() int { return len(h) } -func (h HeadersByHeightAndHash) Less(i, j int) bool { +func (h HeadersReverseSort) Less(i, j int) bool { // Note - the ordering is the inverse ordering of the block heights if h[i].Number != h[j].Number { return h[i].Number > h[j].Number @@ -70,7 +70,26 @@ func (h HeadersByHeightAndHash) Less(i, j int) bool { return bytes.Compare(h[i].Hash[:], h[j].Hash[:]) > 0 } -func (h HeadersByHeightAndHash) Swap(i, j int) { +func (h HeadersReverseSort) Swap(i, j int) { + h[i], h[j] = h[j], h[i] +} + +// Implements sort.Interface so we can sort the incoming header in the message by block height +type HeadersSort []ChainSegmentHeader + +func (h HeadersSort) Len() int { + return len(h) +} + +func (h HeadersSort) Less(i, j int) bool { + // Note - the ordering is the inverse ordering of the block heights + if h[i].Number != h[j].Number { + return h[i].Number < h[j].Number + } + return bytes.Compare(h[i].Hash[:], h[j].Hash[:]) < 0 +} + +func (h HeadersSort) Swap(i, j int) { h[i], h[j] = h[j], h[i] } @@ -208,17 +227,20 @@ func (hd *HeaderDownload) pruneLinkQueue() { } else { prevChild.next = link.next } + if anchor.fLink == nil { + hd.removeAnchor(anchor) + } } } } -func (hd *HeaderDownload) AnchorState() string { +func (hd *HeaderDownload) LogAnchorState() { hd.lock.RLock() defer hd.lock.RUnlock() - return hd.anchorState() + hd.logAnchorState() } -func (hd *HeaderDownload) anchorState() string { +func (hd *HeaderDownload) logAnchorState() { //nolint:prealloc var ss []string for anchorParent, anchor := range hd.anchors { @@ -276,7 +298,9 @@ func (hd *HeaderDownload) anchorState() string { ss = append(ss, sb.String()) } sort.Strings(ss) - return strings.Join(ss, "\n") + for _, s := range ss { + log.Info(s) + } } func (hd *HeaderDownload) RecoverFromDb(db kv.RoDB) error { @@ -877,7 +901,7 @@ func (hd *HeaderDownload) ProcessHeader(sh ChainSegmentHeader, newBlock bool, pe return false } if len(hd.anchors) >= hd.anchorLimit { - log.Debug(fmt.Sprintf("too many anchors: %d, limit %d, state: %s", len(hd.anchors), hd.anchorLimit, hd.anchorState())) + log.Debug(fmt.Sprintf("too many anchors: %d, limit %d", len(hd.anchors), hd.anchorLimit)) return false } } From 97e8c42d5a271ca5c40af9bbd863af54a08fedce Mon Sep 17 00:00:00 2001 From: Alexey Sharp Date: Tue, 31 May 2022 09:09:10 +0100 Subject: [PATCH 220/261] Alpha modifications --- Makefile | 2 +- go.mod | 2 +- go.sum | 4 ++-- params/version.go | 8 ++++---- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 2636b5db4e7..1b82a61cf06 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ GIT_BRANCH ?= $(shell git rev-parse --abbrev-ref HEAD) GIT_TAG ?= $(shell git describe --tags '--match=v*' --dirty) CGO_CFLAGS := $(shell $(GO) env CGO_CFLAGS) # don't loose default -CGO_CFLAGS += -DMDBX_FORCE_ASSERTIONS=1 # Enable MDBX's asserts by default in 'devel' branch and disable in 'stable' +CGO_CFLAGS += -DMDBX_FORCE_ASSERTIONS=0 # Enable MDBX's asserts by default in 'devel' branch and disable in 'stable' CGO_CFLAGS := CGO_CFLAGS="$(CGO_CFLAGS)" DBG_CGO_CFLAGS += -DMDBX_DEBUG=1 diff --git a/go.mod b/go.mod index 6f2e89f5368..a4dbc633e3c 100644 --- a/go.mod +++ b/go.mod @@ -34,7 +34,7 @@ require ( github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/ledgerwatch/erigon-lib v0.0.0-20220530021709-f5c973d4c534 + github.com/ledgerwatch/erigon-lib v0.0.0-20220530021747-7e00e77ae503 github.com/ledgerwatch/log/v3 v3.4.1 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/pelletier/go-toml v1.9.5 diff --git a/go.sum b/go.sum index ae013d5e161..86a46d8db35 100644 --- a/go.sum +++ b/go.sum @@ -382,8 +382,8 @@ github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3P github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20220530021709-f5c973d4c534 h1:0qWu984eWUz6m4jcuskOTdoofqg0ca9mSbw8Gbbng4c= -github.com/ledgerwatch/erigon-lib v0.0.0-20220530021709-f5c973d4c534/go.mod h1:jNDE6PRPIA8wUdikJs8BvKtrFv101qOijIXA3HnDW8E= +github.com/ledgerwatch/erigon-lib v0.0.0-20220530021747-7e00e77ae503 h1:vTuo9xy5MuIVRat7k3ceYCIjRK7Osgww8nuMfBBZh3k= +github.com/ledgerwatch/erigon-lib v0.0.0-20220530021747-7e00e77ae503/go.mod h1:jNDE6PRPIA8wUdikJs8BvKtrFv101qOijIXA3HnDW8E= github.com/ledgerwatch/log/v3 v3.4.1 h1:/xGwlVulXnsO9Uq+tzaExc8OWmXXHU0dnLalpbnY5Bc= github.com/ledgerwatch/log/v3 v3.4.1/go.mod h1:VXcz6Ssn6XEeU92dCMc39/g1F0OYAjw1Mt+dGP5DjXY= github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf3YnwaQ= diff --git a/params/version.go b/params/version.go index 56d8388b83b..ac30f75b9dc 100644 --- a/params/version.go +++ b/params/version.go @@ -31,10 +31,10 @@ var ( // see https://calver.org const ( - VersionMajor = 2022 // Major version component of the current release - VersionMinor = 99 // Minor version component of the current release - VersionMicro = 99 // Patch version component of the current release - VersionModifier = "dev" // Modifier component of the current release + VersionMajor = 2022 // Major version component of the current release + VersionMinor = 5 // Minor version component of the current release + VersionMicro = 9 // Patch version component of the current release + VersionModifier = "alpha" // Modifier component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" ) From 5d5010453d6d8f20d55b9f7459651929352e66a3 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Wed, 1 Jun 2022 18:08:44 -0300 Subject: [PATCH 221/261] Add notices about erigon 1 vs 2 builds --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d5c10eebf81..19d8e7bf9c7 100644 --- a/README.md +++ b/README.md @@ -14,12 +14,19 @@ Erigon versioning schema follows this format: `YYYY.MM.nn`, where: For example `v2021.12.03` means it is the 3rd release of December, 2021. -They do weekly stable releases. This repository only builds on top of stable tags. We usually follow their releases 1:1 a few days after, so you might expect a corresponding patched release for every Erigon stable release, but it is not guaranteed, please check if the corresponding tag actually exists in our repository. +They do almost-weekly releases. This repository only builds on top of tags. We usually follow their releases 1:1 a few days after, so you might expect a corresponding patched release for every Erigon stable release, but it is not guaranteed, please check if the corresponding tag actually exists in our repository. Our tag format is `[-fix]-otterscan`, so for Erigon `v2021.12.03` there should be a `v2021.12.03-otterscan` tagged release. If there is some fix from our side on top of our own tag, we would add an additional suffix before `-otterscan`, like `v2021.12.03-1-otterscan`. You can checkout the desired tag from the git repository and follow the same build instructions from the upstream Erigon or download the automated built images from [Docker Hub](https://hub.docker.com/r/otterscan/erigon/tags). +### Branches + +In case you are feeling adventurous and want to follow our development branches, they are as follows: + +- `otterscan-develop`: this branch points to the development branch that follows Erigon 2. +- `otterscan-erigon1`: this branch points to the _soon-to-be-abandoned_ Erigon 1 stream of patched builds. Do not use it unless you know what you are doing. + ## Other docs The Otterscan's JSON-RPC API extensions are documented [here](https://github.com/wmitsuda/otterscan/blob/develop/docs/custom-jsonrpc.md). From 17806cffb09c90becd5e1068f8144760e5c95597 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Fri, 3 Jun 2022 18:44:53 -0300 Subject: [PATCH 222/261] Fix error msg params --- core/types/receipt.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/types/receipt.go b/core/types/receipt.go index 14fb4d73d22..ae64be28b0c 100644 --- a/core/types/receipt.go +++ b/core/types/receipt.go @@ -468,7 +468,7 @@ func (r Receipts) DeriveFields(hash common.Hash, number uint64, txs Transactions return fmt.Errorf("transaction and receipt count mismatch, tx count = %d, receipts count = %d", len(txs), len(r)) } if len(senders) != len(txs) { - return fmt.Errorf("transaction and senders count mismatch, tx count = %d, receipts count = %d", len(txs), len(r)) + return fmt.Errorf("transaction and senders count mismatch, tx count = %d, senders count = %d", len(txs), len(senders)) } for i := 0; i < len(r); i++ { // The transaction type and hash can be retrieved from the transaction itself From 1d3259aaa8f042816c0c5da6c13b8bc67184eda1 Mon Sep 17 00:00:00 2001 From: Alexey Sharp Date: Sun, 5 Jun 2022 22:44:25 +0100 Subject: [PATCH 223/261] Alpha changes --- Makefile | 2 +- params/version.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 15176d5aa15..9e563ca8e08 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ GIT_BRANCH ?= $(shell git rev-parse --abbrev-ref HEAD) GIT_TAG ?= $(shell git describe --tags '--match=v*' --dirty) CGO_CFLAGS := $(shell $(GO) env CGO_CFLAGS) # don't loose default -CGO_CFLAGS += -DMDBX_FORCE_ASSERTIONS=1 # Enable MDBX's asserts by default in 'devel' branch and disable in 'stable' +CGO_CFLAGS += -DMDBX_FORCE_ASSERTIONS=0 # Enable MDBX's asserts by default in 'devel' branch and disable in 'stable' CGO_CFLAGS := CGO_CFLAGS="$(CGO_CFLAGS)" DBG_CGO_CFLAGS += -DMDBX_DEBUG=1 diff --git a/params/version.go b/params/version.go index 56d8388b83b..90d2f38a565 100644 --- a/params/version.go +++ b/params/version.go @@ -31,10 +31,10 @@ var ( // see https://calver.org const ( - VersionMajor = 2022 // Major version component of the current release - VersionMinor = 99 // Minor version component of the current release - VersionMicro = 99 // Patch version component of the current release - VersionModifier = "dev" // Modifier component of the current release + VersionMajor = 2022 // Major version component of the current release + VersionMinor = 6 // Minor version component of the current release + VersionMicro = 1 // Patch version component of the current release + VersionModifier = "alpha" // Modifier component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" ) From aae183e2ca781b1d7c55a957475fa0e62688a727 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sun, 5 Jun 2022 22:16:35 -0300 Subject: [PATCH 224/261] Fix function signature changed between 2022.05.09 -> 2022.06.01 --- cmd/rpcdaemon/commands/otterscan_api.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 63a203ff9c9..db8d9661094 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -410,7 +410,7 @@ func (api *OtterscanAPIImpl) delegateIssuance(tx kv.Tx, block *types.Block, chai } func (api *OtterscanAPIImpl) delegateBlockFees(ctx context.Context, tx kv.Tx, block *types.Block, senders []common.Address, chainConfig *params.ChainConfig) (uint64, error) { - receipts, err := getReceipts(ctx, tx, chainConfig, block, senders) + receipts, err := api.getReceipts(ctx, tx, chainConfig, block, senders) if err != nil { return 0, fmt.Errorf("getReceipts error: %v", err) } @@ -476,7 +476,7 @@ func (api *OtterscanAPIImpl) GetBlockTransactions(ctx context.Context, number rp } // Receipts - receipts, err := getReceipts(ctx, tx, chainConfig, b, senders) + receipts, err := api.getReceipts(ctx, tx, chainConfig, b, senders) if err != nil { return nil, fmt.Errorf("getReceipts error: %v", err) } From 144e41b1913e0e399ce5a11d950eb37395a95b3d Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sun, 5 Jun 2022 23:58:23 -0300 Subject: [PATCH 225/261] Attempt to fix github actions build after alpha migration --- .github/workflows/docker-publish.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker-publish.yaml b/.github/workflows/docker-publish.yaml index 1118ddcd558..b66ab62bd09 100644 --- a/.github/workflows/docker-publish.yaml +++ b/.github/workflows/docker-publish.yaml @@ -21,9 +21,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2.3.4 + uses: actions/checkout@v3 with: submodules: recursive + fetch-depth: 0 # fetch git tags for "git describe" - name: Cache Docker layers uses: actions/cache@v2 From d60885cc90de6873ff8ad1893844f40c342b1060 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Mon, 6 Jun 2022 00:10:41 -0300 Subject: [PATCH 226/261] Bump github action versions --- .github/workflows/docker-publish.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/docker-publish.yaml b/.github/workflows/docker-publish.yaml index b66ab62bd09..7b9b1149427 100644 --- a/.github/workflows/docker-publish.yaml +++ b/.github/workflows/docker-publish.yaml @@ -27,7 +27,7 @@ jobs: fetch-depth: 0 # fetch git tags for "git describe" - name: Cache Docker layers - uses: actions/cache@v2 + uses: actions/cache@v3 with: path: /tmp/.buildx-cache key: ${{ runner.os }}-buildx-${{ github.sha }} @@ -35,35 +35,35 @@ jobs: ${{ runner.os }}-buildx- - name: Docker Setup Buildx - uses: docker/setup-buildx-action@v1.5.1 + uses: docker/setup-buildx-action@v2.0.0 with: driver: docker-container driver-opts: | image=moby/buildkit:master - name: Docker Login - uses: docker/login-action@v1.10.0 + uses: docker/login-action@v2.0.0 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Docker Login - uses: docker/login-action@v1.10.0 + uses: docker/login-action@v2.0.0 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Docker Metadata action id: meta - uses: docker/metadata-action@v3.4.1 + uses: docker/metadata-action@v4.0.1 with: images: | otterscan/erigon ghcr.io/${{ env.IMAGE_NAME }} - name: Build and push Docker images - uses: docker/build-push-action@v2.6.1 + uses: docker/build-push-action@v3.0.0 with: context: . push: true From fd0837d962987636649b5a2a5090601f3410d632 Mon Sep 17 00:00:00 2001 From: Alex Sharp Date: Tue, 7 Jun 2022 20:06:12 +0100 Subject: [PATCH 227/261] Alpha changes --- Makefile | 2 +- params/version.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 15176d5aa15..9e563ca8e08 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ GIT_BRANCH ?= $(shell git rev-parse --abbrev-ref HEAD) GIT_TAG ?= $(shell git describe --tags '--match=v*' --dirty) CGO_CFLAGS := $(shell $(GO) env CGO_CFLAGS) # don't loose default -CGO_CFLAGS += -DMDBX_FORCE_ASSERTIONS=1 # Enable MDBX's asserts by default in 'devel' branch and disable in 'stable' +CGO_CFLAGS += -DMDBX_FORCE_ASSERTIONS=0 # Enable MDBX's asserts by default in 'devel' branch and disable in 'stable' CGO_CFLAGS := CGO_CFLAGS="$(CGO_CFLAGS)" DBG_CGO_CFLAGS += -DMDBX_DEBUG=1 diff --git a/params/version.go b/params/version.go index 56d8388b83b..2fc34fed933 100644 --- a/params/version.go +++ b/params/version.go @@ -31,10 +31,10 @@ var ( // see https://calver.org const ( - VersionMajor = 2022 // Major version component of the current release - VersionMinor = 99 // Minor version component of the current release - VersionMicro = 99 // Patch version component of the current release - VersionModifier = "dev" // Modifier component of the current release + VersionMajor = 2022 // Major version component of the current release + VersionMinor = 6 // Minor version component of the current release + VersionMicro = 2 // Patch version component of the current release + VersionModifier = "alpha" // Modifier component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" ) From 50c8a11cf3656731336a352abb941b2e78d3df53 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Tue, 7 Jun 2022 17:51:36 -0300 Subject: [PATCH 228/261] Remove CI script from upstream --- .github/workflows/test-integration.yml | 72 -------------------------- 1 file changed, 72 deletions(-) delete mode 100644 .github/workflows/test-integration.yml diff --git a/.github/workflows/test-integration.yml b/.github/workflows/test-integration.yml deleted file mode 100644 index e8ddb57ed2e..00000000000 --- a/.github/workflows/test-integration.yml +++ /dev/null @@ -1,72 +0,0 @@ -name: Integration tests -on: - push: - branches: - - devel - - alpha - - stable - schedule: - - cron: '20 16 * * *' # daily at 16:20 UTC -jobs: - tests: - strategy: - matrix: - os: [ ubuntu-20.04, macos-11 ] # list of os: https://github.com/actions/virtual-environments - runs-on: ${{ matrix.os }} - - steps: - - uses: actions/checkout@v3 - - run: git submodule update --init --recursive --force - - uses: actions/setup-go@v3 - with: - go-version: 1.18.x - - name: Install dependencies on Linux - if: runner.os == 'Linux' - run: sudo apt update && sudo apt install build-essential - - - uses: actions/cache@v3 - with: - path: | - ~/.cache/go-build - ~/Library/Caches/go-build - ~/go/pkg/mod - key: go-${{ matrix.os }}-${{ hashFiles('**/go.sum') }} - restore-keys: go-${{ matrix.os }}- - - - name: test-integration - run: make test-integration - - tests-windows: - strategy: - matrix: - os: [ windows-2022 ] - runs-on: ${{ matrix.os }} - - steps: - - uses: actions/checkout@v3 - - run: git submodule update --init --recursive --force - - uses: actions/setup-go@v3 - with: - go-version: 1.18.x - - - uses: actions/cache@v3 - with: - path: | - C:\ProgramData\chocolatey\lib\mingw - C:\ProgramData\chocolatey\lib\cmake - key: chocolatey-${{ matrix.os }} - - name: Install dependencies - run: | - choco upgrade mingw -y --no-progress --version 11.2.0.07112021 - choco install cmake -y --no-progress --version 3.23.1 - - - uses: actions/cache@v3 - with: - path: | - ~\AppData\Local\go-build - ~\go\pkg\mod - key: go-${{ matrix.os }}-${{ hashFiles('**/go.sum') }} - restore-keys: go-${{ matrix.os }}- - - - name: test-integration - run: .\wmake.ps1 test-integration From 86ed5f20ceef799a8d6c60153fb0aa716859a96c Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sat, 11 Jun 2022 16:55:04 -0300 Subject: [PATCH 229/261] Reorg and cleanup tracers code --- cmd/rpcdaemon/commands/otterscan_api.go | 13 ++-- .../otterscan_contract_creator_tracer.go | 22 +----- .../commands/otterscan_default_tracer.go | 35 +++++++++ .../commands/otterscan_search_trace.go | 3 +- .../commands/otterscan_trace_operations.go | 60 +++++++++++++++ .../commands/otterscan_trace_touch.go | 27 +++++++ .../commands/otterscan_trace_transaction.go | 21 +---- otterscan/transactions/trace_operations.go | 77 ------------------- otterscan/transactions/trace_touch.go | 47 ----------- 9 files changed, 132 insertions(+), 173 deletions(-) create mode 100644 cmd/rpcdaemon/commands/otterscan_default_tracer.go create mode 100644 cmd/rpcdaemon/commands/otterscan_trace_operations.go create mode 100644 cmd/rpcdaemon/commands/otterscan_trace_touch.go rename otterscan/transactions/trace_transaction.go => cmd/rpcdaemon/commands/otterscan_trace_transaction.go (76%) delete mode 100644 otterscan/transactions/trace_operations.go delete mode 100644 otterscan/transactions/trace_touch.go diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index db8d9661094..307fa546297 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -23,7 +23,6 @@ import ( "github.com/ledgerwatch/erigon/core/vm" "github.com/ledgerwatch/erigon/ethdb" "github.com/ledgerwatch/erigon/internal/ethapi" - otterscan "github.com/ledgerwatch/erigon/otterscan/transactions" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/adapter" @@ -43,14 +42,14 @@ type TransactionsWithReceipts struct { type OtterscanAPI interface { GetApiLevel() uint8 - GetInternalOperations(ctx context.Context, hash common.Hash) ([]*otterscan.InternalOperation, error) + GetInternalOperations(ctx context.Context, hash common.Hash) ([]*InternalOperation, error) SearchTransactionsBefore(ctx context.Context, addr common.Address, blockNum uint64, pageSize uint16) (*TransactionsWithReceipts, error) SearchTransactionsAfter(ctx context.Context, addr common.Address, blockNum uint64, pageSize uint16) (*TransactionsWithReceipts, error) GetBlockDetails(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) GetBlockDetailsByHash(ctx context.Context, hash common.Hash) (map[string]interface{}, error) GetBlockTransactions(ctx context.Context, number rpc.BlockNumber, pageNumber uint8, pageSize uint8) (map[string]interface{}, error) HasCode(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (bool, error) - TraceTransaction(ctx context.Context, hash common.Hash) ([]*otterscan.TraceEntry, error) + TraceTransaction(ctx context.Context, hash common.Hash) ([]*TraceEntry, error) GetTransactionError(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) GetTransactionBySenderAndNonce(ctx context.Context, addr common.Address, nonce uint64) (*common.Hash, error) GetContractCreator(ctx context.Context, addr common.Address) (*ContractCreatorData, error) @@ -115,7 +114,7 @@ func (api *OtterscanAPIImpl) getTransactionByHash(ctx context.Context, tx kv.Tx, } // TODO: remove commented code from erigon1 merge after double-check -func (api *OtterscanAPIImpl) GetInternalOperations(ctx context.Context, hash common.Hash) ([]*otterscan.InternalOperation, error) { +func (api *OtterscanAPIImpl) GetInternalOperations(ctx context.Context, hash common.Hash) ([]*InternalOperation, error) { tx, err := api.db.BeginRo(ctx) if err != nil { return nil, err @@ -150,7 +149,7 @@ func (api *OtterscanAPIImpl) GetInternalOperations(ctx context.Context, hash com return nil, err } - tracer := otterscan.NewOperationsTracer(ctx) + tracer := NewOperationsTracer(ctx) vmenv := vm.NewEVM(blockCtx, txCtx, ibs, chainConfig, vm.Config{Debug: true, Tracer: tracer}) if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), true, false /* gasBailout */); err != nil { @@ -541,7 +540,7 @@ func (api *OtterscanAPIImpl) HasCode(ctx context.Context, address common.Address return !acc.IsEmptyCodeHash(), nil } -func (api *OtterscanAPIImpl) TraceTransaction(ctx context.Context, hash common.Hash) ([]*otterscan.TraceEntry, error) { +func (api *OtterscanAPIImpl) TraceTransaction(ctx context.Context, hash common.Hash) ([]*TraceEntry, error) { tx, err := api.db.BeginRo(ctx) if err != nil { return nil, err @@ -576,7 +575,7 @@ func (api *OtterscanAPIImpl) TraceTransaction(ctx context.Context, hash common.H return nil, err } - tracer := otterscan.NewTransactionTracer(ctx) + tracer := NewTransactionTracer(ctx) vmenv := vm.NewEVM(blockCtx, txCtx, ibs, chainConfig, vm.Config{Debug: true, Tracer: tracer}) if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), true, false /* gasBailout */); err != nil { diff --git a/cmd/rpcdaemon/commands/otterscan_contract_creator_tracer.go b/cmd/rpcdaemon/commands/otterscan_contract_creator_tracer.go index 02920aeb076..7875282934f 100644 --- a/cmd/rpcdaemon/commands/otterscan_contract_creator_tracer.go +++ b/cmd/rpcdaemon/commands/otterscan_contract_creator_tracer.go @@ -3,7 +3,6 @@ package commands import ( "context" "math/big" - "time" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/core/types" @@ -11,6 +10,7 @@ import ( ) type CreateTracer struct { + DefaultTracer ctx context.Context target common.Address found bool @@ -48,23 +48,3 @@ func (t *CreateTracer) CaptureStart(env *vm.EVM, depth int, from common.Address, t.found = true t.Creator = from } - -func (t *CreateTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { -} - -func (t *CreateTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) { -} - -func (t *CreateTracer) CaptureEnd(depth int, output []byte, startGas, endGas uint64, d time.Duration, err error) { -} - -func (t *CreateTracer) CaptureSelfDestruct(from common.Address, to common.Address, value *big.Int) { -} - -func (t *CreateTracer) CaptureAccountRead(account common.Address) error { - return nil -} - -func (t *CreateTracer) CaptureAccountWrite(account common.Address) error { - return nil -} diff --git a/cmd/rpcdaemon/commands/otterscan_default_tracer.go b/cmd/rpcdaemon/commands/otterscan_default_tracer.go new file mode 100644 index 00000000000..cd4caff2331 --- /dev/null +++ b/cmd/rpcdaemon/commands/otterscan_default_tracer.go @@ -0,0 +1,35 @@ +package commands + +import ( + "math/big" + "time" + + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/core/vm" +) + +type DefaultTracer struct { +} + +func (t *DefaultTracer) CaptureStart(env *vm.EVM, depth int, from common.Address, to common.Address, precompile bool, create bool, calltype vm.CallType, input []byte, gas uint64, value *big.Int, code []byte) { +} + +func (t *DefaultTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { +} + +func (t *DefaultTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) { +} + +func (t *DefaultTracer) CaptureEnd(depth int, output []byte, startGas, endGas uint64, d time.Duration, err error) { +} + +func (t *DefaultTracer) CaptureSelfDestruct(from common.Address, to common.Address, value *big.Int) { +} + +func (t *DefaultTracer) CaptureAccountRead(account common.Address) error { + return nil +} + +func (t *DefaultTracer) CaptureAccountWrite(account common.Address) error { + return nil +} diff --git a/cmd/rpcdaemon/commands/otterscan_search_trace.go b/cmd/rpcdaemon/commands/otterscan_search_trace.go index c123536320a..95f00afa1c5 100644 --- a/cmd/rpcdaemon/commands/otterscan_search_trace.go +++ b/cmd/rpcdaemon/commands/otterscan_search_trace.go @@ -13,7 +13,6 @@ import ( "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/vm" "github.com/ledgerwatch/erigon/ethdb" - otterscan "github.com/ledgerwatch/erigon/otterscan/transactions" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/turbo/shards" "github.com/ledgerwatch/log/v3" @@ -79,7 +78,7 @@ func (api *OtterscanAPIImpl) traceBlock(dbtx kv.Tx, ctx context.Context, blockNu msg, _ := tx.AsMessage(*signer, header.BaseFee, rules) - tracer := otterscan.NewTouchTracer(searchAddr) + tracer := NewTouchTracer(searchAddr) BlockContext := core.NewEVMBlockContext(header, getHeader, engine, nil, checkTEVM) TxContext := core.NewEVMTxContext(msg) diff --git a/cmd/rpcdaemon/commands/otterscan_trace_operations.go b/cmd/rpcdaemon/commands/otterscan_trace_operations.go new file mode 100644 index 00000000000..2512366bbcc --- /dev/null +++ b/cmd/rpcdaemon/commands/otterscan_trace_operations.go @@ -0,0 +1,60 @@ +package commands + +import ( + "context" + "math/big" + + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/common/hexutil" + "github.com/ledgerwatch/erigon/core/vm" +) + +type OperationType int + +const ( + OP_TRANSFER OperationType = 0 + OP_SELF_DESTRUCT OperationType = 1 + OP_CREATE OperationType = 2 + OP_CREATE2 OperationType = 3 +) + +type InternalOperation struct { + Type OperationType `json:"type"` + From common.Address `json:"from"` + To common.Address `json:"to"` + Value *hexutil.Big `json:"value"` +} + +type OperationsTracer struct { + DefaultTracer + ctx context.Context + Results []*InternalOperation +} + +func NewOperationsTracer(ctx context.Context) *OperationsTracer { + return &OperationsTracer{ + ctx: ctx, + Results: make([]*InternalOperation, 0), + } +} + +func (l *OperationsTracer) CaptureStart(env *vm.EVM, depth int, from common.Address, to common.Address, precompile bool, create bool, calltype vm.CallType, input []byte, gas uint64, value *big.Int, code []byte) { + if depth == 0 { + return + } + + if calltype == vm.CALLT && value.Uint64() != 0 { + l.Results = append(l.Results, &InternalOperation{OP_TRANSFER, from, to, (*hexutil.Big)(value)}) + return + } + if calltype == vm.CREATET { + l.Results = append(l.Results, &InternalOperation{OP_CREATE, from, to, (*hexutil.Big)(value)}) + } + if calltype == vm.CREATE2T { + l.Results = append(l.Results, &InternalOperation{OP_CREATE2, from, to, (*hexutil.Big)(value)}) + } +} + +func (l *OperationsTracer) CaptureSelfDestruct(from common.Address, to common.Address, value *big.Int) { + l.Results = append(l.Results, &InternalOperation{OP_SELF_DESTRUCT, from, to, (*hexutil.Big)(value)}) +} diff --git a/cmd/rpcdaemon/commands/otterscan_trace_touch.go b/cmd/rpcdaemon/commands/otterscan_trace_touch.go new file mode 100644 index 00000000000..e7bdc4af502 --- /dev/null +++ b/cmd/rpcdaemon/commands/otterscan_trace_touch.go @@ -0,0 +1,27 @@ +package commands + +import ( + "bytes" + "math/big" + + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/core/vm" +) + +type TouchTracer struct { + DefaultTracer + searchAddr common.Address + Found bool +} + +func NewTouchTracer(searchAddr common.Address) *TouchTracer { + return &TouchTracer{ + searchAddr: searchAddr, + } +} + +func (l *TouchTracer) CaptureStart(env *vm.EVM, depth int, from common.Address, to common.Address, precompile bool, create bool, calltype vm.CallType, input []byte, gas uint64, value *big.Int, code []byte) { + if !l.Found && (bytes.Equal(l.searchAddr.Bytes(), from.Bytes()) || bytes.Equal(l.searchAddr.Bytes(), to.Bytes())) { + l.Found = true + } +} diff --git a/otterscan/transactions/trace_transaction.go b/cmd/rpcdaemon/commands/otterscan_trace_transaction.go similarity index 76% rename from otterscan/transactions/trace_transaction.go rename to cmd/rpcdaemon/commands/otterscan_trace_transaction.go index 2ce25885bb7..b7bb42eb485 100644 --- a/otterscan/transactions/trace_transaction.go +++ b/cmd/rpcdaemon/commands/otterscan_trace_transaction.go @@ -1,9 +1,8 @@ -package otterscan +package commands import ( "context" "math/big" - "time" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/hexutil" @@ -20,6 +19,7 @@ type TraceEntry struct { } type TransactionTracer struct { + DefaultTracer ctx context.Context Results []*TraceEntry } @@ -66,24 +66,7 @@ func (l *TransactionTracer) CaptureStart(env *vm.EVM, depth int, from common.Add } } -func (l *TransactionTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { -} - -func (l *TransactionTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) { -} - -func (l *TransactionTracer) CaptureEnd(depth int, output []byte, startGas, endGas uint64, t time.Duration, err error) { -} - func (l *TransactionTracer) CaptureSelfDestruct(from common.Address, to common.Address, value *big.Int) { last := l.Results[len(l.Results)-1] l.Results = append(l.Results, &TraceEntry{"SELFDESTRUCT", last.Depth + 1, from, to, (*hexutil.Big)(value), nil}) } - -func (l *TransactionTracer) CaptureAccountRead(account common.Address) error { - return nil -} - -func (*TransactionTracer) CaptureAccountWrite(account common.Address) error { - return nil -} diff --git a/otterscan/transactions/trace_operations.go b/otterscan/transactions/trace_operations.go deleted file mode 100644 index 39eb9254123..00000000000 --- a/otterscan/transactions/trace_operations.go +++ /dev/null @@ -1,77 +0,0 @@ -package otterscan - -import ( - "context" - "math/big" - "time" - - "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/common/hexutil" - "github.com/ledgerwatch/erigon/core/vm" -) - -type OperationType int - -const ( - TRANSFER OperationType = 0 - SELF_DESTRUCT OperationType = 1 - CREATE OperationType = 2 - CREATE2 OperationType = 3 -) - -type InternalOperation struct { - Type OperationType `json:"type"` - From common.Address `json:"from"` - To common.Address `json:"to"` - Value *hexutil.Big `json:"value"` -} - -type OperationsTracer struct { - ctx context.Context - Results []*InternalOperation -} - -func NewOperationsTracer(ctx context.Context) *OperationsTracer { - return &OperationsTracer{ - ctx: ctx, - Results: make([]*InternalOperation, 0), - } -} - -func (l *OperationsTracer) CaptureStart(env *vm.EVM, depth int, from common.Address, to common.Address, precompile bool, create bool, calltype vm.CallType, input []byte, gas uint64, value *big.Int, code []byte) { - if depth == 0 { - return - } - - if calltype == vm.CALLT && value.Uint64() != 0 { - l.Results = append(l.Results, &InternalOperation{TRANSFER, from, to, (*hexutil.Big)(value)}) - return - } - if calltype == vm.CREATET { - l.Results = append(l.Results, &InternalOperation{CREATE, from, to, (*hexutil.Big)(value)}) - } - if calltype == vm.CREATE2T { - l.Results = append(l.Results, &InternalOperation{CREATE2, from, to, (*hexutil.Big)(value)}) - } -} - -func (l *OperationsTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { -} - -func (l *OperationsTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) { -} - -func (l *OperationsTracer) CaptureEnd(depth int, output []byte, startGas, endGas uint64, t time.Duration, err error) { -} - -func (l *OperationsTracer) CaptureSelfDestruct(from common.Address, to common.Address, value *big.Int) { - l.Results = append(l.Results, &InternalOperation{SELF_DESTRUCT, from, to, (*hexutil.Big)(value)}) -} - -func (l *OperationsTracer) CaptureAccountRead(account common.Address) error { - return nil -} - -func (l *OperationsTracer) CaptureAccountWrite(account common.Address) error { - return nil -} diff --git a/otterscan/transactions/trace_touch.go b/otterscan/transactions/trace_touch.go deleted file mode 100644 index 08457a46dc7..00000000000 --- a/otterscan/transactions/trace_touch.go +++ /dev/null @@ -1,47 +0,0 @@ -package otterscan - -import ( - "bytes" - "math/big" - "time" - - "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/core/vm" -) - -type TouchTracer struct { - searchAddr common.Address - Found bool -} - -func NewTouchTracer(searchAddr common.Address) *TouchTracer { - return &TouchTracer{ - searchAddr: searchAddr, - } -} - -func (l *TouchTracer) CaptureStart(env *vm.EVM, depth int, from common.Address, to common.Address, precompile bool, create bool, calltype vm.CallType, input []byte, gas uint64, value *big.Int, code []byte) { - if !l.Found && (bytes.Equal(l.searchAddr.Bytes(), from.Bytes()) || bytes.Equal(l.searchAddr.Bytes(), to.Bytes())) { - l.Found = true - } -} - -func (l *TouchTracer) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { -} - -func (l *TouchTracer) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) { -} - -func (l *TouchTracer) CaptureEnd(depth int, output []byte, startGas, endGas uint64, t time.Duration, err error) { -} - -func (l *TouchTracer) CaptureSelfDestruct(from common.Address, to common.Address, value *big.Int) { -} - -func (l *TouchTracer) CaptureAccountRead(account common.Address) error { - return nil -} - -func (l *TouchTracer) CaptureAccountWrite(account common.Address) error { - return nil -} From 7941c9dbc1fb9156c46c1dccce866ac388b247d4 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sat, 11 Jun 2022 17:00:02 -0300 Subject: [PATCH 230/261] Renames --- ...acer.go => otterscan_trace_contract_creator.go} | 0 .../commands/otterscan_trace_operations.go | 8 ++++---- cmd/rpcdaemon/commands/otterscan_trace_touch.go | 6 +++--- .../commands/otterscan_trace_transaction.go | 14 +++++++------- 4 files changed, 14 insertions(+), 14 deletions(-) rename cmd/rpcdaemon/commands/{otterscan_contract_creator_tracer.go => otterscan_trace_contract_creator.go} (100%) diff --git a/cmd/rpcdaemon/commands/otterscan_contract_creator_tracer.go b/cmd/rpcdaemon/commands/otterscan_trace_contract_creator.go similarity index 100% rename from cmd/rpcdaemon/commands/otterscan_contract_creator_tracer.go rename to cmd/rpcdaemon/commands/otterscan_trace_contract_creator.go diff --git a/cmd/rpcdaemon/commands/otterscan_trace_operations.go b/cmd/rpcdaemon/commands/otterscan_trace_operations.go index 2512366bbcc..59e8e05ec28 100644 --- a/cmd/rpcdaemon/commands/otterscan_trace_operations.go +++ b/cmd/rpcdaemon/commands/otterscan_trace_operations.go @@ -38,20 +38,20 @@ func NewOperationsTracer(ctx context.Context) *OperationsTracer { } } -func (l *OperationsTracer) CaptureStart(env *vm.EVM, depth int, from common.Address, to common.Address, precompile bool, create bool, calltype vm.CallType, input []byte, gas uint64, value *big.Int, code []byte) { +func (t *OperationsTracer) CaptureStart(env *vm.EVM, depth int, from common.Address, to common.Address, precompile bool, create bool, calltype vm.CallType, input []byte, gas uint64, value *big.Int, code []byte) { if depth == 0 { return } if calltype == vm.CALLT && value.Uint64() != 0 { - l.Results = append(l.Results, &InternalOperation{OP_TRANSFER, from, to, (*hexutil.Big)(value)}) + t.Results = append(t.Results, &InternalOperation{OP_TRANSFER, from, to, (*hexutil.Big)(value)}) return } if calltype == vm.CREATET { - l.Results = append(l.Results, &InternalOperation{OP_CREATE, from, to, (*hexutil.Big)(value)}) + t.Results = append(t.Results, &InternalOperation{OP_CREATE, from, to, (*hexutil.Big)(value)}) } if calltype == vm.CREATE2T { - l.Results = append(l.Results, &InternalOperation{OP_CREATE2, from, to, (*hexutil.Big)(value)}) + t.Results = append(t.Results, &InternalOperation{OP_CREATE2, from, to, (*hexutil.Big)(value)}) } } diff --git a/cmd/rpcdaemon/commands/otterscan_trace_touch.go b/cmd/rpcdaemon/commands/otterscan_trace_touch.go index e7bdc4af502..98db6a9bafc 100644 --- a/cmd/rpcdaemon/commands/otterscan_trace_touch.go +++ b/cmd/rpcdaemon/commands/otterscan_trace_touch.go @@ -20,8 +20,8 @@ func NewTouchTracer(searchAddr common.Address) *TouchTracer { } } -func (l *TouchTracer) CaptureStart(env *vm.EVM, depth int, from common.Address, to common.Address, precompile bool, create bool, calltype vm.CallType, input []byte, gas uint64, value *big.Int, code []byte) { - if !l.Found && (bytes.Equal(l.searchAddr.Bytes(), from.Bytes()) || bytes.Equal(l.searchAddr.Bytes(), to.Bytes())) { - l.Found = true +func (t *TouchTracer) CaptureStart(env *vm.EVM, depth int, from common.Address, to common.Address, precompile bool, create bool, calltype vm.CallType, input []byte, gas uint64, value *big.Int, code []byte) { + if !t.Found && (bytes.Equal(t.searchAddr.Bytes(), from.Bytes()) || bytes.Equal(t.searchAddr.Bytes(), to.Bytes())) { + t.Found = true } } diff --git a/cmd/rpcdaemon/commands/otterscan_trace_transaction.go b/cmd/rpcdaemon/commands/otterscan_trace_transaction.go index b7bb42eb485..5b0244ef783 100644 --- a/cmd/rpcdaemon/commands/otterscan_trace_transaction.go +++ b/cmd/rpcdaemon/commands/otterscan_trace_transaction.go @@ -31,7 +31,7 @@ func NewTransactionTracer(ctx context.Context) *TransactionTracer { } } -func (l *TransactionTracer) CaptureStart(env *vm.EVM, depth int, from common.Address, to common.Address, precompile bool, create bool, callType vm.CallType, input []byte, gas uint64, value *big.Int, code []byte) { +func (t *TransactionTracer) CaptureStart(env *vm.EVM, depth int, from common.Address, to common.Address, precompile bool, create bool, callType vm.CallType, input []byte, gas uint64, value *big.Int, code []byte) { if precompile { return } @@ -41,27 +41,27 @@ func (l *TransactionTracer) CaptureStart(env *vm.EVM, depth int, from common.Add _value := new(big.Int) _value.Set(value) if callType == vm.CALLT { - l.Results = append(l.Results, &TraceEntry{"CALL", depth, from, to, (*hexutil.Big)(_value), inputCopy}) + t.Results = append(t.Results, &TraceEntry{"CALL", depth, from, to, (*hexutil.Big)(_value), inputCopy}) return } if callType == vm.STATICCALLT { - l.Results = append(l.Results, &TraceEntry{"STATICCALL", depth, from, to, nil, inputCopy}) + t.Results = append(t.Results, &TraceEntry{"STATICCALL", depth, from, to, nil, inputCopy}) return } if callType == vm.DELEGATECALLT { - l.Results = append(l.Results, &TraceEntry{"DELEGATECALL", depth, from, to, nil, inputCopy}) + t.Results = append(t.Results, &TraceEntry{"DELEGATECALL", depth, from, to, nil, inputCopy}) return } if callType == vm.CALLCODET { - l.Results = append(l.Results, &TraceEntry{"CALLCODE", depth, from, to, (*hexutil.Big)(_value), inputCopy}) + t.Results = append(t.Results, &TraceEntry{"CALLCODE", depth, from, to, (*hexutil.Big)(_value), inputCopy}) return } if callType == vm.CREATET { - l.Results = append(l.Results, &TraceEntry{"CREATE", depth, from, to, (*hexutil.Big)(value), inputCopy}) + t.Results = append(t.Results, &TraceEntry{"CREATE", depth, from, to, (*hexutil.Big)(value), inputCopy}) return } if callType == vm.CREATE2T { - l.Results = append(l.Results, &TraceEntry{"CREATE2", depth, from, to, (*hexutil.Big)(value), inputCopy}) + t.Results = append(t.Results, &TraceEntry{"CREATE2", depth, from, to, (*hexutil.Big)(value), inputCopy}) return } } From ab29fc3adb6f147782f6e0c47b154b5b5f99aa02 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sat, 11 Jun 2022 17:05:34 -0300 Subject: [PATCH 231/261] Add docs --- cmd/rpcdaemon/commands/otterscan_default_tracer.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmd/rpcdaemon/commands/otterscan_default_tracer.go b/cmd/rpcdaemon/commands/otterscan_default_tracer.go index cd4caff2331..fa023183558 100644 --- a/cmd/rpcdaemon/commands/otterscan_default_tracer.go +++ b/cmd/rpcdaemon/commands/otterscan_default_tracer.go @@ -8,6 +8,9 @@ import ( "github.com/ledgerwatch/erigon/core/vm" ) +// Helper implementation of vm.Tracer; since the interface is big and most +// custom tracers implement just a few of the methods, this is a base struct +// to avoid lots of empty boilerplate code type DefaultTracer struct { } From dc32c4446a0875c0fdd8dc5543bdbf211a457602 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sat, 11 Jun 2022 18:35:11 -0300 Subject: [PATCH 232/261] Remove unnecessary extra block read --- cmd/rpcdaemon/commands/otterscan_api.go | 39 +++++++------------------ 1 file changed, 10 insertions(+), 29 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 307fa546297..8dc5c4f1bb2 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -72,22 +72,22 @@ func (api *OtterscanAPIImpl) GetApiLevel() uint8 { } // TODO: dedup from eth_txs.go#GetTransactionByHash -func (api *OtterscanAPIImpl) getTransactionByHash(ctx context.Context, tx kv.Tx, hash common.Hash) (types.Transaction, common.Hash, uint64, uint64, error) { +func (api *OtterscanAPIImpl) getTransactionByHash(ctx context.Context, tx kv.Tx, hash common.Hash) (types.Transaction, *types.Block, common.Hash, uint64, uint64, error) { // https://infura.io/docs/ethereum/json-rpc/eth-getTransactionByHash blockNum, ok, err := api.txnLookup(ctx, tx, hash) if err != nil { - return nil, common.Hash{}, 0, 0, err + return nil, nil, common.Hash{}, 0, 0, err } if !ok { - return nil, common.Hash{}, 0, 0, nil + return nil, nil, common.Hash{}, 0, 0, nil } block, err := api.blockByNumberWithSenders(tx, blockNum) if err != nil { - return nil, common.Hash{}, 0, 0, err + return nil, nil, common.Hash{}, 0, 0, err } if block == nil { - return nil, common.Hash{}, 0, 0, nil + return nil, nil, common.Hash{}, 0, 0, nil } blockHash := block.Hash() var txnIndex uint64 @@ -108,12 +108,11 @@ func (api *OtterscanAPIImpl) getTransactionByHash(ctx context.Context, tx kv.Tx, // if no transaction was found then we return nil if txn == nil { - return nil, common.Hash{}, 0, 0, nil + return nil, nil, common.Hash{}, 0, 0, nil } - return txn, blockHash, blockNum, txnIndex, nil + return txn, block, blockHash, blockNum, txnIndex, nil } -// TODO: remove commented code from erigon1 merge after double-check func (api *OtterscanAPIImpl) GetInternalOperations(ctx context.Context, hash common.Hash) ([]*InternalOperation, error) { tx, err := api.db.BeginRo(ctx) if err != nil { @@ -121,19 +120,13 @@ func (api *OtterscanAPIImpl) GetInternalOperations(ctx context.Context, hash com } defer tx.Rollback() - txn, blockHash, _, txIndex, err := api.getTransactionByHash(ctx, tx, hash) - // txn, blockHash, _, txIndex, err := rawdb.ReadTransactionByHash(tx, hash) + txn, block, blockHash, _, txIndex, err := api.getTransactionByHash(ctx, tx, hash) if err != nil { return nil, err } if txn == nil { return nil, fmt.Errorf("transaction %#x not found", hash) } - block, err := api.blockByHashWithSenders(tx, blockHash) - // block, err := rawdb.ReadBlockByHash(tx, blockHash) - if err != nil { - return nil, err - } chainConfig, err := api.chainConfig(tx) if err != nil { @@ -547,19 +540,13 @@ func (api *OtterscanAPIImpl) TraceTransaction(ctx context.Context, hash common.H } defer tx.Rollback() - txn, blockHash, _, txIndex, err := api.getTransactionByHash(ctx, tx, hash) - // txn, blockHash, _, txIndex, err := rawdb.ReadTransactionByHash(tx, hash) + txn, block, blockHash, _, txIndex, err := api.getTransactionByHash(ctx, tx, hash) if err != nil { return nil, err } if txn == nil { return nil, fmt.Errorf("transaction %#x not found", hash) } - block, err := api.blockByHashWithSenders(tx, blockHash) - // block, err := rawdb.ReadBlockByHash(tx, blockHash) - if err != nil { - return nil, err - } chainConfig, err := api.chainConfig(tx) if err != nil { @@ -592,19 +579,13 @@ func (api *OtterscanAPIImpl) GetTransactionError(ctx context.Context, hash commo } defer tx.Rollback() - txn, blockHash, _, txIndex, err := api.getTransactionByHash(ctx, tx, hash) - // txn, blockHash, _, txIndex, err := rawdb.ReadTransactionByHash(tx, hash) + txn, block, blockHash, _, txIndex, err := api.getTransactionByHash(ctx, tx, hash) if err != nil { return nil, err } if txn == nil { return nil, fmt.Errorf("transaction %#x not found", hash) } - block, err := api.blockByHashWithSenders(tx, blockHash) - // block, err := rawdb.ReadBlockByHash(tx, blockHash) - if err != nil { - return nil, err - } chainConfig, err := api.chainConfig(tx) if err != nil { From c03d40ad0fd0db132381f51b465f715d0f74ba43 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sat, 11 Jun 2022 20:11:19 -0300 Subject: [PATCH 233/261] Extract duplicate tracer setup code --- cmd/rpcdaemon/commands/otterscan_api.go | 62 +++++++++---------------- 1 file changed, 23 insertions(+), 39 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 8dc5c4f1bb2..03eaa47b8fa 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -113,24 +113,18 @@ func (api *OtterscanAPIImpl) getTransactionByHash(ctx context.Context, tx kv.Tx, return txn, block, blockHash, blockNum, txnIndex, nil } -func (api *OtterscanAPIImpl) GetInternalOperations(ctx context.Context, hash common.Hash) ([]*InternalOperation, error) { - tx, err := api.db.BeginRo(ctx) - if err != nil { - return nil, err - } - defer tx.Rollback() - +func (api *OtterscanAPIImpl) runTracer(ctx context.Context, tx kv.Tx, hash common.Hash, tracer vm.Tracer) error { txn, block, blockHash, _, txIndex, err := api.getTransactionByHash(ctx, tx, hash) if err != nil { - return nil, err + return err } if txn == nil { - return nil, fmt.Errorf("transaction %#x not found", hash) + return fmt.Errorf("transaction %#x not found", hash) } chainConfig, err := api.chainConfig(tx) if err != nil { - return nil, err + return err } getHeader := func(hash common.Hash, number uint64) *types.Header { @@ -139,14 +133,28 @@ func (api *OtterscanAPIImpl) GetInternalOperations(ctx context.Context, hash com checkTEVM := ethdb.GetHasTEVM(tx) msg, blockCtx, txCtx, ibs, _, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, checkTEVM, ethash.NewFaker(), tx, blockHash, txIndex) if err != nil { - return nil, err + return err } - tracer := NewOperationsTracer(ctx) vmenv := vm.NewEVM(blockCtx, txCtx, ibs, chainConfig, vm.Config{Debug: true, Tracer: tracer}) if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), true, false /* gasBailout */); err != nil { - return nil, fmt.Errorf("tracing failed: %v", err) + return fmt.Errorf("tracing failed: %v", err) + } + + return nil +} + +func (api *OtterscanAPIImpl) GetInternalOperations(ctx context.Context, hash common.Hash) ([]*InternalOperation, error) { + tx, err := api.db.BeginRo(ctx) + if err != nil { + return nil, err + } + defer tx.Rollback() + + tracer := NewOperationsTracer(ctx) + if err := api.runTracer(ctx, tx, hash, tracer); err != nil { + return nil, err } return tracer.Results, nil @@ -540,33 +548,9 @@ func (api *OtterscanAPIImpl) TraceTransaction(ctx context.Context, hash common.H } defer tx.Rollback() - txn, block, blockHash, _, txIndex, err := api.getTransactionByHash(ctx, tx, hash) - if err != nil { - return nil, err - } - if txn == nil { - return nil, fmt.Errorf("transaction %#x not found", hash) - } - - chainConfig, err := api.chainConfig(tx) - if err != nil { - return nil, err - } - - getHeader := func(hash common.Hash, number uint64) *types.Header { - return rawdb.ReadHeader(tx, hash, number) - } - checkTEVM := ethdb.GetHasTEVM(tx) - msg, blockCtx, txCtx, ibs, _, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, checkTEVM, ethash.NewFaker(), tx, blockHash, txIndex) - if err != nil { - return nil, err - } - tracer := NewTransactionTracer(ctx) - vmenv := vm.NewEVM(blockCtx, txCtx, ibs, chainConfig, vm.Config{Debug: true, Tracer: tracer}) - - if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), true, false /* gasBailout */); err != nil { - return nil, fmt.Errorf("tracing failed: %v", err) + if err := api.runTracer(ctx, tx, hash, tracer); err != nil { + return nil, err } return tracer.Results, nil From 0dd10da68235718edb5e12a40b3f4b2a5729d098 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sat, 11 Jun 2022 20:24:22 -0300 Subject: [PATCH 234/261] Simplify even more duplicated code --- cmd/rpcdaemon/commands/otterscan_api.go | 55 +++++++++---------------- 1 file changed, 19 insertions(+), 36 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 03eaa47b8fa..0af79a80bce 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -113,18 +113,18 @@ func (api *OtterscanAPIImpl) getTransactionByHash(ctx context.Context, tx kv.Tx, return txn, block, blockHash, blockNum, txnIndex, nil } -func (api *OtterscanAPIImpl) runTracer(ctx context.Context, tx kv.Tx, hash common.Hash, tracer vm.Tracer) error { +func (api *OtterscanAPIImpl) runTracer(ctx context.Context, tx kv.Tx, hash common.Hash, tracer vm.Tracer) (*core.ExecutionResult, error) { txn, block, blockHash, _, txIndex, err := api.getTransactionByHash(ctx, tx, hash) if err != nil { - return err + return nil, err } if txn == nil { - return fmt.Errorf("transaction %#x not found", hash) + return nil, fmt.Errorf("transaction %#x not found", hash) } chainConfig, err := api.chainConfig(tx) if err != nil { - return err + return nil, err } getHeader := func(hash common.Hash, number uint64) *types.Header { @@ -133,16 +133,23 @@ func (api *OtterscanAPIImpl) runTracer(ctx context.Context, tx kv.Tx, hash commo checkTEVM := ethdb.GetHasTEVM(tx) msg, blockCtx, txCtx, ibs, _, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, checkTEVM, ethash.NewFaker(), tx, blockHash, txIndex) if err != nil { - return err + return nil, err } - vmenv := vm.NewEVM(blockCtx, txCtx, ibs, chainConfig, vm.Config{Debug: true, Tracer: tracer}) + var vmConfig vm.Config + if tracer == nil { + vmConfig = vm.Config{} + } else { + vmConfig = vm.Config{Debug: true, Tracer: tracer} + } + vmenv := vm.NewEVM(blockCtx, txCtx, ibs, chainConfig, vmConfig) - if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), true, false /* gasBailout */); err != nil { - return fmt.Errorf("tracing failed: %v", err) + result, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), true, false /* gasBailout */) + if err != nil { + return nil, fmt.Errorf("tracing failed: %v", err) } - return nil + return result, nil } func (api *OtterscanAPIImpl) GetInternalOperations(ctx context.Context, hash common.Hash) ([]*InternalOperation, error) { @@ -153,7 +160,7 @@ func (api *OtterscanAPIImpl) GetInternalOperations(ctx context.Context, hash com defer tx.Rollback() tracer := NewOperationsTracer(ctx) - if err := api.runTracer(ctx, tx, hash, tracer); err != nil { + if _, err := api.runTracer(ctx, tx, hash, tracer); err != nil { return nil, err } @@ -549,7 +556,7 @@ func (api *OtterscanAPIImpl) TraceTransaction(ctx context.Context, hash common.H defer tx.Rollback() tracer := NewTransactionTracer(ctx) - if err := api.runTracer(ctx, tx, hash, tracer); err != nil { + if _, err := api.runTracer(ctx, tx, hash, tracer); err != nil { return nil, err } @@ -563,34 +570,10 @@ func (api *OtterscanAPIImpl) GetTransactionError(ctx context.Context, hash commo } defer tx.Rollback() - txn, block, blockHash, _, txIndex, err := api.getTransactionByHash(ctx, tx, hash) + result, err := api.runTracer(ctx, tx, hash, nil) if err != nil { return nil, err } - if txn == nil { - return nil, fmt.Errorf("transaction %#x not found", hash) - } - - chainConfig, err := api.chainConfig(tx) - if err != nil { - return nil, err - } - - getHeader := func(hash common.Hash, number uint64) *types.Header { - return rawdb.ReadHeader(tx, hash, number) - } - checkTEVM := ethdb.GetHasTEVM(tx) - msg, blockCtx, txCtx, ibs, _, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, checkTEVM, ethash.NewFaker(), tx, blockHash, txIndex) - if err != nil { - return nil, err - } - - vmenv := vm.NewEVM(blockCtx, txCtx, ibs, chainConfig, vm.Config{}) - - result, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), true, false /* gasBailout */) - if err != nil { - return nil, fmt.Errorf("tracing failed: %v", err) - } return result.Revert(), nil } From 4cadf1bbffc8b2177c0384ddd3af45e5db9e9604 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sat, 11 Jun 2022 20:30:32 -0300 Subject: [PATCH 235/261] Code cleanup --- cmd/rpcdaemon/commands/otterscan_api.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 0af79a80bce..78b6f7176b6 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -708,11 +708,6 @@ func (api *OtterscanAPIImpl) findNonce(ctx context.Context, tx kv.Tx, addr commo return false, common.Hash{}, err } block, senders, err := api._blockReader.BlockWithSenders(ctx, tx, hash, blockNum) - // senders, err := rawdb.ReadSenders(tx, hash, blockNum) - if err != nil { - return false, common.Hash{}, err - } - // body, err := rawdb.ReadBodyWithTransactions(tx, hash, blockNum) if err != nil { return false, common.Hash{}, err } @@ -724,7 +719,6 @@ func (api *OtterscanAPIImpl) findNonce(ctx context.Context, tx kv.Tx, addr commo } t := txs[i] - // t := body.Transactions[i] if t.GetNonce() == nonce { return true, t.Hash(), nil } From 3071f4f4757554b9d0b9b837d45b905eddbba54f Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Sun, 12 Jun 2022 21:28:13 -0300 Subject: [PATCH 236/261] Extract methods into its own files --- cmd/rpcdaemon/commands/otterscan_api.go | 206 ------------------ cmd/rpcdaemon/commands/otterscan_has_code.go | 31 +++ .../commands/otterscan_trace_transaction.go | 15 ++ ...terscan_transaction_by_sender_and_nonce.go | 163 ++++++++++++++ .../commands/otterscan_transaction_error.go | 23 ++ 5 files changed, 232 insertions(+), 206 deletions(-) create mode 100644 cmd/rpcdaemon/commands/otterscan_has_code.go create mode 100644 cmd/rpcdaemon/commands/otterscan_transaction_by_sender_and_nonce.go create mode 100644 cmd/rpcdaemon/commands/otterscan_transaction_error.go diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 78b6f7176b6..dd4aee2490e 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -1,32 +1,25 @@ package commands import ( - "bytes" "context" "errors" "fmt" "math/big" - "sort" "sync" - "github.com/RoaringBitmap/roaring/roaring64" "github.com/holiman/uint256" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/common/changeset" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/consensus/ethash" "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/types" - "github.com/ledgerwatch/erigon/core/types/accounts" "github.com/ledgerwatch/erigon/core/vm" "github.com/ledgerwatch/erigon/ethdb" "github.com/ledgerwatch/erigon/internal/ethapi" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/rpc" - "github.com/ledgerwatch/erigon/turbo/adapter" - "github.com/ledgerwatch/erigon/turbo/rpchelper" "github.com/ledgerwatch/erigon/turbo/transactions" ) @@ -527,202 +520,3 @@ func (api *OtterscanAPIImpl) GetBlockTransactions(ctx context.Context, number rp response["receipts"] = result[pageStart:pageEnd] return response, nil } - -func (api *OtterscanAPIImpl) HasCode(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (bool, error) { - tx, err := api.db.BeginRo(ctx) - if err != nil { - return false, fmt.Errorf("hasCode cannot open tx: %w", err) - } - defer tx.Rollback() - - blockNumber, _, _, err := rpchelper.GetBlockNumber(blockNrOrHash, tx, api.filters) - if err != nil { - return false, err - } - - reader := adapter.NewStateReader(tx, blockNumber) - acc, err := reader.ReadAccountData(address) - if acc == nil || err != nil { - return false, err - } - return !acc.IsEmptyCodeHash(), nil -} - -func (api *OtterscanAPIImpl) TraceTransaction(ctx context.Context, hash common.Hash) ([]*TraceEntry, error) { - tx, err := api.db.BeginRo(ctx) - if err != nil { - return nil, err - } - defer tx.Rollback() - - tracer := NewTransactionTracer(ctx) - if _, err := api.runTracer(ctx, tx, hash, tracer); err != nil { - return nil, err - } - - return tracer.Results, nil -} - -func (api *OtterscanAPIImpl) GetTransactionError(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) { - tx, err := api.db.BeginRo(ctx) - if err != nil { - return nil, err - } - defer tx.Rollback() - - result, err := api.runTracer(ctx, tx, hash, nil) - if err != nil { - return nil, err - } - - return result.Revert(), nil -} - -func (api *OtterscanAPIImpl) GetTransactionBySenderAndNonce(ctx context.Context, addr common.Address, nonce uint64) (*common.Hash, error) { - tx, err := api.db.BeginRo(ctx) - if err != nil { - return nil, err - } - defer tx.Rollback() - - accHistoryC, err := tx.Cursor(kv.AccountsHistory) - if err != nil { - return nil, err - } - defer accHistoryC.Close() - - accChangesC, err := tx.CursorDupSort(kv.AccountChangeSet) - if err != nil { - return nil, err - } - defer accChangesC.Close() - - // Locate the chunk where the nonce happens - acs := changeset.Mapper[kv.AccountChangeSet] - k, v, err := accHistoryC.Seek(acs.IndexChunkKey(addr.Bytes(), 0)) - if err != nil { - return nil, err - } - - bitmap := roaring64.New() - maxBlPrevChunk := uint64(0) - var acc accounts.Account - - for { - if k == nil || !bytes.HasPrefix(k, addr.Bytes()) { - // Check plain state - data, err := tx.GetOne(kv.PlainState, addr.Bytes()) - if err != nil { - return nil, err - } - if err := acc.DecodeForStorage(data); err != nil { - return nil, err - } - - // Nonce changed in plain state, so it means the last block of last chunk - // contains the actual nonce change - if acc.Nonce > nonce { - break - } - - // Not found; asked for nonce still not used - return nil, nil - } - - // Inspect block changeset - if _, err := bitmap.ReadFrom(bytes.NewReader(v)); err != nil { - return nil, err - } - maxBl := bitmap.Maximum() - data, err := acs.Find(accChangesC, maxBl, addr.Bytes()) - if err != nil { - return nil, err - } - if err := acc.DecodeForStorage(data); err != nil { - return nil, err - } - - // Desired nonce was found in this chunk - if acc.Nonce > nonce { - break - } - - maxBlPrevChunk = maxBl - k, v, err = accHistoryC.Next() - if err != nil { - return nil, err - } - } - - // Locate the exact block inside chunk when the nonce changed - blocks := bitmap.ToArray() - var errSearch error = nil - idx := sort.Search(len(blocks), func(i int) bool { - if errSearch != nil { - return false - } - - // Locate the block changeset - data, err := acs.Find(accChangesC, blocks[i], addr.Bytes()) - if err != nil { - errSearch = err - return false - } - - if err := acc.DecodeForStorage(data); err != nil { - errSearch = err - return false - } - - // Since the state contains the nonce BEFORE the block changes, we look for - // the block when the nonce changed to be > the desired once, which means the - // previous history block contains the actual change; it may contain multiple - // nonce changes. - return acc.Nonce > nonce - }) - if errSearch != nil { - return nil, errSearch - } - - // Since the changeset contains the state BEFORE the change, we inspect - // the block before the one we found; if it is the first block inside the chunk, - // we use the last block from prev chunk - nonceBlock := maxBlPrevChunk - if idx > 0 { - nonceBlock = blocks[idx-1] - } - found, txHash, err := api.findNonce(ctx, tx, addr, nonce, nonceBlock) - if err != nil { - return nil, err - } - if !found { - return nil, nil - } - - return &txHash, nil -} - -func (api *OtterscanAPIImpl) findNonce(ctx context.Context, tx kv.Tx, addr common.Address, nonce uint64, blockNum uint64) (bool, common.Hash, error) { - hash, err := rawdb.ReadCanonicalHash(tx, blockNum) - if err != nil { - return false, common.Hash{}, err - } - block, senders, err := api._blockReader.BlockWithSenders(ctx, tx, hash, blockNum) - if err != nil { - return false, common.Hash{}, err - } - - txs := block.Transactions() - for i, s := range senders { - if s != addr { - continue - } - - t := txs[i] - if t.GetNonce() == nonce { - return true, t.Hash(), nil - } - } - - return false, common.Hash{}, nil -} diff --git a/cmd/rpcdaemon/commands/otterscan_has_code.go b/cmd/rpcdaemon/commands/otterscan_has_code.go new file mode 100644 index 00000000000..d5b267ca8fb --- /dev/null +++ b/cmd/rpcdaemon/commands/otterscan_has_code.go @@ -0,0 +1,31 @@ +package commands + +import ( + "context" + "fmt" + + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/rpc" + "github.com/ledgerwatch/erigon/turbo/adapter" + "github.com/ledgerwatch/erigon/turbo/rpchelper" +) + +func (api *OtterscanAPIImpl) HasCode(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (bool, error) { + tx, err := api.db.BeginRo(ctx) + if err != nil { + return false, fmt.Errorf("hasCode cannot open tx: %w", err) + } + defer tx.Rollback() + + blockNumber, _, _, err := rpchelper.GetBlockNumber(blockNrOrHash, tx, api.filters) + if err != nil { + return false, err + } + + reader := adapter.NewStateReader(tx, blockNumber) + acc, err := reader.ReadAccountData(address) + if acc == nil || err != nil { + return false, err + } + return !acc.IsEmptyCodeHash(), nil +} diff --git a/cmd/rpcdaemon/commands/otterscan_trace_transaction.go b/cmd/rpcdaemon/commands/otterscan_trace_transaction.go index 5b0244ef783..3ba73df17e4 100644 --- a/cmd/rpcdaemon/commands/otterscan_trace_transaction.go +++ b/cmd/rpcdaemon/commands/otterscan_trace_transaction.go @@ -9,6 +9,21 @@ import ( "github.com/ledgerwatch/erigon/core/vm" ) +func (api *OtterscanAPIImpl) TraceTransaction(ctx context.Context, hash common.Hash) ([]*TraceEntry, error) { + tx, err := api.db.BeginRo(ctx) + if err != nil { + return nil, err + } + defer tx.Rollback() + + tracer := NewTransactionTracer(ctx) + if _, err := api.runTracer(ctx, tx, hash, tracer); err != nil { + return nil, err + } + + return tracer.Results, nil +} + type TraceEntry struct { Type string `json:"type"` Depth int `json:"depth"` diff --git a/cmd/rpcdaemon/commands/otterscan_transaction_by_sender_and_nonce.go b/cmd/rpcdaemon/commands/otterscan_transaction_by_sender_and_nonce.go new file mode 100644 index 00000000000..b94ee6064f1 --- /dev/null +++ b/cmd/rpcdaemon/commands/otterscan_transaction_by_sender_and_nonce.go @@ -0,0 +1,163 @@ +package commands + +import ( + "bytes" + "context" + "sort" + + "github.com/RoaringBitmap/roaring/roaring64" + "github.com/ledgerwatch/erigon-lib/kv" + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/common/changeset" + "github.com/ledgerwatch/erigon/core/rawdb" + "github.com/ledgerwatch/erigon/core/types/accounts" +) + +func (api *OtterscanAPIImpl) GetTransactionBySenderAndNonce(ctx context.Context, addr common.Address, nonce uint64) (*common.Hash, error) { + tx, err := api.db.BeginRo(ctx) + if err != nil { + return nil, err + } + defer tx.Rollback() + + accHistoryC, err := tx.Cursor(kv.AccountsHistory) + if err != nil { + return nil, err + } + defer accHistoryC.Close() + + accChangesC, err := tx.CursorDupSort(kv.AccountChangeSet) + if err != nil { + return nil, err + } + defer accChangesC.Close() + + // Locate the chunk where the nonce happens + acs := changeset.Mapper[kv.AccountChangeSet] + k, v, err := accHistoryC.Seek(acs.IndexChunkKey(addr.Bytes(), 0)) + if err != nil { + return nil, err + } + + bitmap := roaring64.New() + maxBlPrevChunk := uint64(0) + var acc accounts.Account + + for { + if k == nil || !bytes.HasPrefix(k, addr.Bytes()) { + // Check plain state + data, err := tx.GetOne(kv.PlainState, addr.Bytes()) + if err != nil { + return nil, err + } + if err := acc.DecodeForStorage(data); err != nil { + return nil, err + } + + // Nonce changed in plain state, so it means the last block of last chunk + // contains the actual nonce change + if acc.Nonce > nonce { + break + } + + // Not found; asked for nonce still not used + return nil, nil + } + + // Inspect block changeset + if _, err := bitmap.ReadFrom(bytes.NewReader(v)); err != nil { + return nil, err + } + maxBl := bitmap.Maximum() + data, err := acs.Find(accChangesC, maxBl, addr.Bytes()) + if err != nil { + return nil, err + } + if err := acc.DecodeForStorage(data); err != nil { + return nil, err + } + + // Desired nonce was found in this chunk + if acc.Nonce > nonce { + break + } + + maxBlPrevChunk = maxBl + k, v, err = accHistoryC.Next() + if err != nil { + return nil, err + } + } + + // Locate the exact block inside chunk when the nonce changed + blocks := bitmap.ToArray() + var errSearch error = nil + idx := sort.Search(len(blocks), func(i int) bool { + if errSearch != nil { + return false + } + + // Locate the block changeset + data, err := acs.Find(accChangesC, blocks[i], addr.Bytes()) + if err != nil { + errSearch = err + return false + } + + if err := acc.DecodeForStorage(data); err != nil { + errSearch = err + return false + } + + // Since the state contains the nonce BEFORE the block changes, we look for + // the block when the nonce changed to be > the desired once, which means the + // previous history block contains the actual change; it may contain multiple + // nonce changes. + return acc.Nonce > nonce + }) + if errSearch != nil { + return nil, errSearch + } + + // Since the changeset contains the state BEFORE the change, we inspect + // the block before the one we found; if it is the first block inside the chunk, + // we use the last block from prev chunk + nonceBlock := maxBlPrevChunk + if idx > 0 { + nonceBlock = blocks[idx-1] + } + found, txHash, err := api.findNonce(ctx, tx, addr, nonce, nonceBlock) + if err != nil { + return nil, err + } + if !found { + return nil, nil + } + + return &txHash, nil +} + +func (api *OtterscanAPIImpl) findNonce(ctx context.Context, tx kv.Tx, addr common.Address, nonce uint64, blockNum uint64) (bool, common.Hash, error) { + hash, err := rawdb.ReadCanonicalHash(tx, blockNum) + if err != nil { + return false, common.Hash{}, err + } + block, senders, err := api._blockReader.BlockWithSenders(ctx, tx, hash, blockNum) + if err != nil { + return false, common.Hash{}, err + } + + txs := block.Transactions() + for i, s := range senders { + if s != addr { + continue + } + + t := txs[i] + if t.GetNonce() == nonce { + return true, t.Hash(), nil + } + } + + return false, common.Hash{}, nil +} diff --git a/cmd/rpcdaemon/commands/otterscan_transaction_error.go b/cmd/rpcdaemon/commands/otterscan_transaction_error.go new file mode 100644 index 00000000000..2cccc802e9e --- /dev/null +++ b/cmd/rpcdaemon/commands/otterscan_transaction_error.go @@ -0,0 +1,23 @@ +package commands + +import ( + "context" + + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/common/hexutil" +) + +func (api *OtterscanAPIImpl) GetTransactionError(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) { + tx, err := api.db.BeginRo(ctx) + if err != nil { + return nil, err + } + defer tx.Rollback() + + result, err := api.runTracer(ctx, tx, hash, nil) + if err != nil { + return nil, err + } + + return result.Revert(), nil +} From 2a570ad599014c3bc522287967c778792a4eb4f4 Mon Sep 17 00:00:00 2001 From: Alexey Sharp Date: Wed, 15 Jun 2022 08:05:59 +0100 Subject: [PATCH 237/261] Alpha changes --- Makefile | 2 +- params/version.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 51104b84947..15b0644758e 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ GIT_BRANCH ?= $(shell git rev-parse --abbrev-ref HEAD) GIT_TAG ?= $(shell git describe --tags '--match=v*' --dirty) CGO_CFLAGS := $(shell $(GO) env CGO_CFLAGS) # don't loose default -CGO_CFLAGS += -DMDBX_FORCE_ASSERTIONS=1 # Enable MDBX's asserts by default in 'devel' branch and disable in 'stable' +CGO_CFLAGS += -DMDBX_FORCE_ASSERTIONS=0 # Enable MDBX's asserts by default in 'devel' branch and disable in 'stable' CGO_CFLAGS := CGO_CFLAGS="$(CGO_CFLAGS)" DBG_CGO_CFLAGS += -DMDBX_DEBUG=1 diff --git a/params/version.go b/params/version.go index 56d8388b83b..689f57951de 100644 --- a/params/version.go +++ b/params/version.go @@ -31,10 +31,10 @@ var ( // see https://calver.org const ( - VersionMajor = 2022 // Major version component of the current release - VersionMinor = 99 // Minor version component of the current release - VersionMicro = 99 // Patch version component of the current release - VersionModifier = "dev" // Modifier component of the current release + VersionMajor = 2022 // Major version component of the current release + VersionMinor = 6 // Minor version component of the current release + VersionMicro = 3 // Patch version component of the current release + VersionModifier = "alpha" // Modifier component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" ) From cf58be69ad027c6def9b3194636fbd407be6af4f Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Fri, 17 Jun 2022 00:24:13 -0300 Subject: [PATCH 238/261] Fix internal API changes from 2022.06.02 -> 03 --- cmd/rpcdaemon/commands/otterscan_api.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index dd4aee2490e..00a0616e36a 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -20,6 +20,7 @@ import ( "github.com/ledgerwatch/erigon/internal/ethapi" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/rpc" + "github.com/ledgerwatch/erigon/turbo/rpchelper" "github.com/ledgerwatch/erigon/turbo/transactions" ) @@ -437,15 +438,11 @@ func (api *OtterscanAPIImpl) getBlockWithSenders(ctx context.Context, number rpc return api.pendingBlock(), nil, nil } - n, err := getBlockNumber(number, tx) + n, hash, _, err := rpchelper.GetBlockNumber(rpc.BlockNumberOrHashWithNumber(number), tx, api.filters) if err != nil { return nil, nil, err } - hash, err := rawdb.ReadCanonicalHash(tx, n) - if err != nil { - return nil, nil, err - } block, senders, err := api._blockReader.BlockWithSenders(ctx, tx, hash, n) return block, senders, err } From e866889b60f8854d574c54686792488a2cacba95 Mon Sep 17 00:00:00 2001 From: Alexey Sharp Date: Fri, 17 Jun 2022 19:49:01 +0100 Subject: [PATCH 239/261] Alpha changes --- Makefile | 2 +- params/version.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 7a0dd3d99d5..ffe34180849 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ DOCKER_PID ?= 1000 DOCKER_TAG ?= thorax/erigon:latest CGO_CFLAGS := $(shell $(GO) env CGO_CFLAGS) # don't loose default -CGO_CFLAGS += -DMDBX_FORCE_ASSERTIONS=1 # Enable MDBX's asserts by default in 'devel' branch and disable in 'stable' +CGO_CFLAGS += -DMDBX_FORCE_ASSERTIONS=0 # Enable MDBX's asserts by default in 'devel' branch and disable in 'stable' CGO_CFLAGS := CGO_CFLAGS="$(CGO_CFLAGS)" DBG_CGO_CFLAGS += -DMDBX_DEBUG=1 diff --git a/params/version.go b/params/version.go index 56d8388b83b..b133e553cfa 100644 --- a/params/version.go +++ b/params/version.go @@ -31,10 +31,10 @@ var ( // see https://calver.org const ( - VersionMajor = 2022 // Major version component of the current release - VersionMinor = 99 // Minor version component of the current release - VersionMicro = 99 // Patch version component of the current release - VersionModifier = "dev" // Modifier component of the current release + VersionMajor = 2022 // Major version component of the current release + VersionMinor = 4 // Minor version component of the current release + VersionMicro = 4 // Patch version component of the current release + VersionModifier = "alpha" // Modifier component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" ) From 7724089985bf9cb8bb7d1bde92892256a6af859f Mon Sep 17 00:00:00 2001 From: Alex Sharp Date: Mon, 20 Jun 2022 16:55:24 +0100 Subject: [PATCH 240/261] Alpha modifications --- Makefile | 2 +- params/version.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 7a0dd3d99d5..ffe34180849 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ DOCKER_PID ?= 1000 DOCKER_TAG ?= thorax/erigon:latest CGO_CFLAGS := $(shell $(GO) env CGO_CFLAGS) # don't loose default -CGO_CFLAGS += -DMDBX_FORCE_ASSERTIONS=1 # Enable MDBX's asserts by default in 'devel' branch and disable in 'stable' +CGO_CFLAGS += -DMDBX_FORCE_ASSERTIONS=0 # Enable MDBX's asserts by default in 'devel' branch and disable in 'stable' CGO_CFLAGS := CGO_CFLAGS="$(CGO_CFLAGS)" DBG_CGO_CFLAGS += -DMDBX_DEBUG=1 diff --git a/params/version.go b/params/version.go index 56d8388b83b..8474bca70dc 100644 --- a/params/version.go +++ b/params/version.go @@ -31,10 +31,10 @@ var ( // see https://calver.org const ( - VersionMajor = 2022 // Major version component of the current release - VersionMinor = 99 // Minor version component of the current release - VersionMicro = 99 // Patch version component of the current release - VersionModifier = "dev" // Modifier component of the current release + VersionMajor = 2022 // Major version component of the current release + VersionMinor = 6 // Minor version component of the current release + VersionMicro = 6 // Patch version component of the current release + VersionModifier = "alpha" // Modifier component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" ) From 1c94c2c703e2407bc4a50fc5b82b4b44fc978517 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Thu, 23 Jun 2022 17:52:41 -0300 Subject: [PATCH 241/261] Fix crash in ots_getContractCreator; for some reason it didnt made it in last release; fix https://github.com/wmitsuda/otterscan/issues/281 --- cmd/rpcdaemon/commands/otterscan_generic_tracer.go | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_generic_tracer.go b/cmd/rpcdaemon/commands/otterscan_generic_tracer.go index 696c809b72a..c81392f853b 100644 --- a/cmd/rpcdaemon/commands/otterscan_generic_tracer.go +++ b/cmd/rpcdaemon/commands/otterscan_generic_tracer.go @@ -23,15 +23,12 @@ type GenericTracer interface { } func (api *OtterscanAPIImpl) genericTracer(dbtx kv.Tx, ctx context.Context, blockNum uint64, chainConfig *params.ChainConfig, tracer GenericTracer) error { - // Retrieve the transaction and assemble its EVM context - blockHash, err := rawdb.ReadCanonicalHash(dbtx, blockNum) + block, err := api.blockByNumberWithSenders(dbtx, blockNum) if err != nil { return err } - - block, _, err := rawdb.ReadBlockWithSenders(dbtx, blockHash, blockNum) - if err != nil { - return err + if block == nil { + return nil } reader := state.NewPlainState(dbtx, blockNum) @@ -49,7 +46,6 @@ func (api *OtterscanAPIImpl) genericTracer(dbtx kv.Tx, ctx context.Context, bloc engine := ethash.NewFaker() checkTEVM := ethdb.GetHasTEVM(dbtx) - // blockReceipts := rawdb.ReadReceipts(dbtx, block, senders) header := block.Header() rules := chainConfig.Rules(block.NumberU64()) for idx, tx := range block.Transactions() { From 2dea9b823f17fa2a4b22ee59953c14b2f8254e43 Mon Sep 17 00:00:00 2001 From: Alexey Sharp Date: Fri, 1 Jul 2022 12:17:26 +0100 Subject: [PATCH 242/261] Alpha modifications --- Makefile | 2 +- params/version.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 5fcc65b0ef1..d7d5e2298de 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ DOCKER_TAG ?= thorax/erigon:latest # Pipe error below to /dev/null since Makefile structure kind of expects # Go to be available, but with docker it's not strictly necessary CGO_CFLAGS := $(shell $(GO) env CGO_CFLAGS 2>/dev/null) # don't lose default -CGO_CFLAGS += -DMDBX_FORCE_ASSERTIONS=1 # Enable MDBX's asserts by default in 'devel' branch and disable in 'stable' +CGO_CFLAGS += -DMDBX_FORCE_ASSERTIONS=0 # Enable MDBX's asserts by default in 'devel' branch and disable in 'stable' CGO_CFLAGS := CGO_CFLAGS="$(CGO_CFLAGS)" DBG_CGO_CFLAGS += -DMDBX_DEBUG=1 diff --git a/params/version.go b/params/version.go index 56d8388b83b..95e0306ea23 100644 --- a/params/version.go +++ b/params/version.go @@ -31,10 +31,10 @@ var ( // see https://calver.org const ( - VersionMajor = 2022 // Major version component of the current release - VersionMinor = 99 // Minor version component of the current release - VersionMicro = 99 // Patch version component of the current release - VersionModifier = "dev" // Modifier component of the current release + VersionMajor = 2022 // Major version component of the current release + VersionMinor = 7 // Minor version component of the current release + VersionMicro = 1 // Patch version component of the current release + VersionModifier = "alpha" // Modifier component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" ) From 83c4298abf69f9383597caa67d232f85eff2b64f Mon Sep 17 00:00:00 2001 From: Andrew Ashikhmin <34320705+yperbasis@users.noreply.github.com> Date: Fri, 1 Jul 2022 15:32:54 +0200 Subject: [PATCH 243/261] More thorough (*ChainConfig) checkCompatible (#4601) --- params/config.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/params/config.go b/params/config.go index 6446c63eb19..3c7f8dffb5a 100644 --- a/params/config.go +++ b/params/config.go @@ -243,6 +243,7 @@ type ChainConfig struct { ArrowGlacierBlock *big.Int `json:"arrowGlacierBlock,omitempty"` // EIP-4345 (bomb delay) switch block (nil = no fork, 0 = already activated) GrayGlacierBlock *big.Int `json:"grayGlacierBlock,omitempty"` // EIP-5133 (bomb delay) switch block (nil = no fork, 0 = already activated) + // Parlia fork blocks RamanujanBlock *big.Int `json:"ramanujanBlock,omitempty" toml:",omitempty"` // ramanujanBlock switch block (nil = no fork, 0 = already activated) NielsBlock *big.Int `json:"nielsBlock,omitempty" toml:",omitempty"` // nielsBlock switch block (nil = no fork, 0 = already activated) MirrorSyncBlock *big.Int `json:"mirrorSyncBlock,omitempty" toml:",omitempty"` // mirrorSyncBlock switch block (nil = no fork, 0 = already activated) @@ -627,6 +628,7 @@ func (c *ChainConfig) CheckConfigForkOrder() error { } func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head uint64) *ConfigCompatError { + // Ethereum mainnet forks if isForkIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, head) { return newCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock) } @@ -676,6 +678,23 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head uint64) *ConfigC if isForkIncompatible(c.GrayGlacierBlock, newcfg.GrayGlacierBlock, head) { return newCompatError("Gray Glacier fork block", c.GrayGlacierBlock, newcfg.GrayGlacierBlock) } + if isForkIncompatible(c.MergeNetsplitBlock, newcfg.MergeNetsplitBlock, head) { + return newCompatError("Merge netsplit block", c.MergeNetsplitBlock, newcfg.MergeNetsplitBlock) + } + + // Parlia forks + if isForkIncompatible(c.RamanujanBlock, newcfg.RamanujanBlock, head) { + return newCompatError("Ramanujan fork block", c.RamanujanBlock, newcfg.RamanujanBlock) + } + if isForkIncompatible(c.NielsBlock, newcfg.NielsBlock, head) { + return newCompatError("Niels fork block", c.NielsBlock, newcfg.NielsBlock) + } + if isForkIncompatible(c.MirrorSyncBlock, newcfg.MirrorSyncBlock, head) { + return newCompatError("MirrorSync fork block", c.MirrorSyncBlock, newcfg.MirrorSyncBlock) + } + if isForkIncompatible(c.BrunoBlock, newcfg.BrunoBlock, head) { + return newCompatError("Bruno fork block", c.BrunoBlock, newcfg.BrunoBlock) + } if isForkIncompatible(c.EulerBlock, newcfg.EulerBlock, head) { return newCompatError("Euler fork block", c.EulerBlock, newcfg.EulerBlock) } From 3a7ecbfcf3b09acac2244d09e4a81046eaca241d Mon Sep 17 00:00:00 2001 From: Enrique Jose Avila Asapche Date: Fri, 1 Jul 2022 17:36:44 +0300 Subject: [PATCH 244/261] Changing rawdb to blockReader (#4602) --- cmd/rpcdaemon/commands/bor_helper.go | 13 +++++--- cmd/rpcdaemon/commands/bor_snapshot.go | 24 +++++++-------- cmd/rpcdaemon/commands/erigon_block.go | 37 ++++++++++++++++++++--- cmd/rpcdaemon/commands/eth_call_test.go | 8 ++++- cmd/rpcdaemon22/commands/bor_helper.go | 13 +++++--- cmd/rpcdaemon22/commands/bor_snapshot.go | 24 +++++++-------- cmd/rpcdaemon22/commands/erigon_block.go | 36 +++++++++++++++++++--- cmd/rpcdaemon22/commands/eth_call_test.go | 8 ++++- 8 files changed, 117 insertions(+), 46 deletions(-) diff --git a/cmd/rpcdaemon/commands/bor_helper.go b/cmd/rpcdaemon/commands/bor_helper.go index bb054a8054b..ef5cf774b4a 100644 --- a/cmd/rpcdaemon/commands/bor_helper.go +++ b/cmd/rpcdaemon/commands/bor_helper.go @@ -2,13 +2,13 @@ package commands import ( "bytes" + "context" "errors" "fmt" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/consensus/bor" - "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/params" @@ -45,7 +45,7 @@ var ( // getHeaderByNumber returns a block's header given a block number ignoring the block's transaction and uncle list (may be faster). // derived from erigon_getHeaderByNumber implementation (see ./erigon_block.go) -func getHeaderByNumber(number rpc.BlockNumber, api *BorImpl, tx kv.Tx) (*types.Header, error) { +func getHeaderByNumber(ctx context.Context, number rpc.BlockNumber, api *BorImpl, tx kv.Tx) (*types.Header, error) { // Pending block is only known by the miner if number == rpc.PendingBlockNumber { block := api.pendingBlock() @@ -60,7 +60,10 @@ func getHeaderByNumber(number rpc.BlockNumber, api *BorImpl, tx kv.Tx) (*types.H return nil, err } - header := rawdb.ReadHeaderByNumber(tx, blockNum) + header, err := api._blockReader.HeaderByNumber(ctx, tx, blockNum) + if err != nil { + return nil, err + } if header == nil { return nil, fmt.Errorf("block header not found: %d", blockNum) } @@ -70,8 +73,8 @@ func getHeaderByNumber(number rpc.BlockNumber, api *BorImpl, tx kv.Tx) (*types.H // getHeaderByHash returns a block's header given a block's hash. // derived from erigon_getHeaderByHash implementation (see ./erigon_block.go) -func getHeaderByHash(tx kv.Tx, hash common.Hash) (*types.Header, error) { - header, err := rawdb.ReadHeaderByHash(tx, hash) +func getHeaderByHash(ctx context.Context, api *BorImpl, tx kv.Tx, hash common.Hash) (*types.Header, error) { + header, err := api._blockReader.HeaderByHash(ctx, tx, hash) if err != nil { return nil, err } diff --git a/cmd/rpcdaemon/commands/bor_snapshot.go b/cmd/rpcdaemon/commands/bor_snapshot.go index 96d18cc86bf..2915afe9513 100644 --- a/cmd/rpcdaemon/commands/bor_snapshot.go +++ b/cmd/rpcdaemon/commands/bor_snapshot.go @@ -45,7 +45,7 @@ func (api *BorImpl) GetSnapshot(number *rpc.BlockNumber) (*Snapshot, error) { if number == nil || *number == rpc.LatestBlockNumber { header = rawdb.ReadCurrentHeader(tx) } else { - header, _ = getHeaderByNumber(*number, api, tx) + header, _ = getHeaderByNumber(ctx, *number, api, tx) } // Ensure we have an actually valid block if header == nil { @@ -58,7 +58,7 @@ func (api *BorImpl) GetSnapshot(number *rpc.BlockNumber) (*Snapshot, error) { return nil, err } defer borTx.Rollback() - return snapshot(api, tx, borTx, header) + return snapshot(ctx, api, tx, borTx, header) } // GetAuthor retrieves the author a block. @@ -75,7 +75,7 @@ func (api *BorImpl) GetAuthor(number *rpc.BlockNumber) (*common.Address, error) if number == nil || *number == rpc.LatestBlockNumber { header = rawdb.ReadCurrentHeader(tx) } else { - header, _ = getHeaderByNumber(*number, api, tx) + header, _ = getHeaderByNumber(ctx, *number, api, tx) } // Ensure we have an actually valid block if header == nil { @@ -96,7 +96,7 @@ func (api *BorImpl) GetSnapshotAtHash(hash common.Hash) (*Snapshot, error) { defer tx.Rollback() // Retreive the header - header, _ := getHeaderByHash(tx, hash) + header, _ := getHeaderByHash(ctx, api, tx, hash) // Ensure we have an actually valid block if header == nil { @@ -109,7 +109,7 @@ func (api *BorImpl) GetSnapshotAtHash(hash common.Hash) (*Snapshot, error) { return nil, err } defer borTx.Rollback() - return snapshot(api, tx, borTx, header) + return snapshot(ctx, api, tx, borTx, header) } // GetSigners retrieves the list of authorized signers at the specified block. @@ -127,7 +127,7 @@ func (api *BorImpl) GetSigners(number *rpc.BlockNumber) ([]common.Address, error if number == nil || *number == rpc.LatestBlockNumber { header = rawdb.ReadCurrentHeader(tx) } else { - header, _ = getHeaderByNumber(*number, api, tx) + header, _ = getHeaderByNumber(ctx, *number, api, tx) } // Ensure we have an actually valid block if header == nil { @@ -140,7 +140,7 @@ func (api *BorImpl) GetSigners(number *rpc.BlockNumber) ([]common.Address, error return nil, err } defer borTx.Rollback() - snap, err := snapshot(api, tx, borTx, header) + snap, err := snapshot(ctx, api, tx, borTx, header) return snap.signers(), err } @@ -155,7 +155,7 @@ func (api *BorImpl) GetSignersAtHash(hash common.Hash) ([]common.Address, error) defer tx.Rollback() // Retreive the header - header, _ := getHeaderByHash(tx, hash) + header, _ := getHeaderByHash(ctx, api, tx, hash) // Ensure we have an actually valid block if header == nil { @@ -169,7 +169,7 @@ func (api *BorImpl) GetSignersAtHash(hash common.Hash) ([]common.Address, error) } defer borTx.Rollback() - snap, err := snapshot(api, tx, borTx, header) + snap, err := snapshot(ctx, api, tx, borTx, header) return snap.signers(), err } @@ -214,7 +214,7 @@ func (api *BorImpl) GetRootHash(start, end uint64) (string, error) { } blockHeaders := make([]*types.Header, end-start+1) for number := start; number <= end; number++ { - blockHeaders[number-start], _ = getHeaderByNumber(rpc.BlockNumber(number), api, tx) + blockHeaders[number-start], _ = getHeaderByNumber(ctx, rpc.BlockNumber(number), api, tx) } headers := make([][32]byte, bor.NextPowerOfTwo(length)) @@ -354,7 +354,7 @@ func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) { } // snapshot retrieves the authorization snapshot at a given point in time. -func snapshot(api *BorImpl, db kv.Tx, borDb kv.Tx, header *types.Header) (*Snapshot, error) { +func snapshot(ctx context.Context, api *BorImpl, db kv.Tx, borDb kv.Tx, header *types.Header) (*Snapshot, error) { // Search for a snapshot on disk or build it from checkpoint var ( headers []*types.Header @@ -376,7 +376,7 @@ func snapshot(api *BorImpl, db kv.Tx, borDb kv.Tx, header *types.Header) (*Snaps // No snapshot for this header, move backward and check parent snapshots if header == nil { - header, _ = getHeaderByNumber(rpc.BlockNumber(number), api, db) + header, _ = getHeaderByNumber(ctx, rpc.BlockNumber(number), api, db) if header == nil { return nil, consensus.ErrUnknownAncestor } diff --git a/cmd/rpcdaemon/commands/erigon_block.go b/cmd/rpcdaemon/commands/erigon_block.go index f094311a6be..7a5bf1bda1d 100644 --- a/cmd/rpcdaemon/commands/erigon_block.go +++ b/cmd/rpcdaemon/commands/erigon_block.go @@ -2,6 +2,7 @@ package commands import ( "context" + "errors" "fmt" "sort" @@ -36,7 +37,11 @@ func (api *ErigonImpl) GetHeaderByNumber(ctx context.Context, blockNumber rpc.Bl return nil, err } - header := rawdb.ReadHeaderByNumber(tx, blockNum) + header, err := api._blockReader.HeaderByNumber(ctx, tx, blockNum) + if err != nil { + return nil, err + } + if header == nil { return nil, fmt.Errorf("block header not found: %d", blockNum) } @@ -52,7 +57,7 @@ func (api *ErigonImpl) GetHeaderByHash(ctx context.Context, hash common.Hash) (* } defer tx.Rollback() - header, err := rawdb.ReadHeaderByHash(tx, hash) + header, err := api._blockReader.HeaderByHash(ctx, tx, hash) if err != nil { return nil, err } @@ -76,7 +81,15 @@ func (api *ErigonImpl) GetBlockByTimestamp(ctx context.Context, timeStamp rpc.Ti currenttHeaderTime := currentHeader.Time highestNumber := currentHeader.Number.Uint64() - firstHeader := rawdb.ReadHeaderByNumber(tx, 0) + firstHeader, err := api._blockReader.HeaderByNumber(ctx, tx, 0) + if err != nil { + return nil, err + } + + if firstHeader == nil { + return nil, errors.New("no genesis header found") + } + firstHeaderTime := firstHeader.Time if currenttHeaderTime <= uintTimestamp { @@ -98,12 +111,26 @@ func (api *ErigonImpl) GetBlockByTimestamp(ctx context.Context, timeStamp rpc.Ti } blockNum := sort.Search(int(currentHeader.Number.Uint64()), func(blockNum int) bool { - currentHeader := rawdb.ReadHeaderByNumber(tx, uint64(blockNum)) + currentHeader, err := api._blockReader.HeaderByNumber(ctx, tx, uint64(blockNum)) + if err != nil { + return false + } + + if currentHeader == nil { + return false + } return currentHeader.Time >= uintTimestamp }) - resultingHeader := rawdb.ReadHeaderByNumber(tx, uint64(blockNum)) + resultingHeader, err := api._blockReader.HeaderByNumber(ctx, tx, uint64(blockNum)) + if err != nil { + return nil, err + } + + if resultingHeader == nil { + return nil, fmt.Errorf("no header found with header number: %d", blockNum) + } if resultingHeader.Time > uintTimestamp { response, err := buildBlockResponse(tx, uint64(blockNum)-1, fullTx) diff --git a/cmd/rpcdaemon/commands/eth_call_test.go b/cmd/rpcdaemon/commands/eth_call_test.go index a73a0b53342..fc204365a4f 100644 --- a/cmd/rpcdaemon/commands/eth_call_test.go +++ b/cmd/rpcdaemon/commands/eth_call_test.go @@ -180,7 +180,13 @@ func TestGetBlockByTimeMiddle(t *testing.T) { api := NewErigonAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), false), db, nil) currentHeader := rawdb.ReadCurrentHeader(tx) - oldestHeader := rawdb.ReadHeaderByNumber(tx, 0) + oldestHeader, err := api._blockReader.HeaderByNumber(ctx, tx, 0) + if err != nil { + t.Errorf("error getting oldest header %s", err) + } + if oldestHeader == nil { + t.Error("couldn't find oldest header") + } middleNumber := (currentHeader.Number.Uint64() + oldestHeader.Number.Uint64()) / 2 middleBlock, err := rawdb.ReadBlockByNumber(tx, middleNumber) diff --git a/cmd/rpcdaemon22/commands/bor_helper.go b/cmd/rpcdaemon22/commands/bor_helper.go index 49d074307da..51e60d5f70f 100644 --- a/cmd/rpcdaemon22/commands/bor_helper.go +++ b/cmd/rpcdaemon22/commands/bor_helper.go @@ -2,13 +2,13 @@ package commands import ( "bytes" + "context" "errors" "fmt" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/consensus/bor" - "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/params" @@ -44,7 +44,7 @@ var ( // getHeaderByNumber returns a block's header given a block number ignoring the block's transaction and uncle list (may be faster). // derived from erigon_getHeaderByNumber implementation (see ./erigon_block.go) -func getHeaderByNumber(number rpc.BlockNumber, api *BorImpl, tx kv.Tx) (*types.Header, error) { +func getHeaderByNumber(ctx context.Context, number rpc.BlockNumber, api *BorImpl, tx kv.Tx) (*types.Header, error) { // Pending block is only known by the miner if number == rpc.PendingBlockNumber { block := api.pendingBlock() @@ -59,7 +59,10 @@ func getHeaderByNumber(number rpc.BlockNumber, api *BorImpl, tx kv.Tx) (*types.H return nil, err } - header := rawdb.ReadHeaderByNumber(tx, blockNum) + header, err := api._blockReader.HeaderByNumber(ctx, tx, blockNum) + if err != nil { + return nil, err + } if header == nil { return nil, fmt.Errorf("block header not found: %d", blockNum) } @@ -69,8 +72,8 @@ func getHeaderByNumber(number rpc.BlockNumber, api *BorImpl, tx kv.Tx) (*types.H // getHeaderByHash returns a block's header given a block's hash. // derived from erigon_getHeaderByHash implementation (see ./erigon_block.go) -func getHeaderByHash(tx kv.Tx, hash common.Hash) (*types.Header, error) { - header, err := rawdb.ReadHeaderByHash(tx, hash) +func getHeaderByHash(ctx context.Context, api *BorImpl, tx kv.Tx, hash common.Hash) (*types.Header, error) { + header, err := api._blockReader.HeaderByHash(ctx, tx, hash) if err != nil { return nil, err } diff --git a/cmd/rpcdaemon22/commands/bor_snapshot.go b/cmd/rpcdaemon22/commands/bor_snapshot.go index 96d18cc86bf..2915afe9513 100644 --- a/cmd/rpcdaemon22/commands/bor_snapshot.go +++ b/cmd/rpcdaemon22/commands/bor_snapshot.go @@ -45,7 +45,7 @@ func (api *BorImpl) GetSnapshot(number *rpc.BlockNumber) (*Snapshot, error) { if number == nil || *number == rpc.LatestBlockNumber { header = rawdb.ReadCurrentHeader(tx) } else { - header, _ = getHeaderByNumber(*number, api, tx) + header, _ = getHeaderByNumber(ctx, *number, api, tx) } // Ensure we have an actually valid block if header == nil { @@ -58,7 +58,7 @@ func (api *BorImpl) GetSnapshot(number *rpc.BlockNumber) (*Snapshot, error) { return nil, err } defer borTx.Rollback() - return snapshot(api, tx, borTx, header) + return snapshot(ctx, api, tx, borTx, header) } // GetAuthor retrieves the author a block. @@ -75,7 +75,7 @@ func (api *BorImpl) GetAuthor(number *rpc.BlockNumber) (*common.Address, error) if number == nil || *number == rpc.LatestBlockNumber { header = rawdb.ReadCurrentHeader(tx) } else { - header, _ = getHeaderByNumber(*number, api, tx) + header, _ = getHeaderByNumber(ctx, *number, api, tx) } // Ensure we have an actually valid block if header == nil { @@ -96,7 +96,7 @@ func (api *BorImpl) GetSnapshotAtHash(hash common.Hash) (*Snapshot, error) { defer tx.Rollback() // Retreive the header - header, _ := getHeaderByHash(tx, hash) + header, _ := getHeaderByHash(ctx, api, tx, hash) // Ensure we have an actually valid block if header == nil { @@ -109,7 +109,7 @@ func (api *BorImpl) GetSnapshotAtHash(hash common.Hash) (*Snapshot, error) { return nil, err } defer borTx.Rollback() - return snapshot(api, tx, borTx, header) + return snapshot(ctx, api, tx, borTx, header) } // GetSigners retrieves the list of authorized signers at the specified block. @@ -127,7 +127,7 @@ func (api *BorImpl) GetSigners(number *rpc.BlockNumber) ([]common.Address, error if number == nil || *number == rpc.LatestBlockNumber { header = rawdb.ReadCurrentHeader(tx) } else { - header, _ = getHeaderByNumber(*number, api, tx) + header, _ = getHeaderByNumber(ctx, *number, api, tx) } // Ensure we have an actually valid block if header == nil { @@ -140,7 +140,7 @@ func (api *BorImpl) GetSigners(number *rpc.BlockNumber) ([]common.Address, error return nil, err } defer borTx.Rollback() - snap, err := snapshot(api, tx, borTx, header) + snap, err := snapshot(ctx, api, tx, borTx, header) return snap.signers(), err } @@ -155,7 +155,7 @@ func (api *BorImpl) GetSignersAtHash(hash common.Hash) ([]common.Address, error) defer tx.Rollback() // Retreive the header - header, _ := getHeaderByHash(tx, hash) + header, _ := getHeaderByHash(ctx, api, tx, hash) // Ensure we have an actually valid block if header == nil { @@ -169,7 +169,7 @@ func (api *BorImpl) GetSignersAtHash(hash common.Hash) ([]common.Address, error) } defer borTx.Rollback() - snap, err := snapshot(api, tx, borTx, header) + snap, err := snapshot(ctx, api, tx, borTx, header) return snap.signers(), err } @@ -214,7 +214,7 @@ func (api *BorImpl) GetRootHash(start, end uint64) (string, error) { } blockHeaders := make([]*types.Header, end-start+1) for number := start; number <= end; number++ { - blockHeaders[number-start], _ = getHeaderByNumber(rpc.BlockNumber(number), api, tx) + blockHeaders[number-start], _ = getHeaderByNumber(ctx, rpc.BlockNumber(number), api, tx) } headers := make([][32]byte, bor.NextPowerOfTwo(length)) @@ -354,7 +354,7 @@ func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) { } // snapshot retrieves the authorization snapshot at a given point in time. -func snapshot(api *BorImpl, db kv.Tx, borDb kv.Tx, header *types.Header) (*Snapshot, error) { +func snapshot(ctx context.Context, api *BorImpl, db kv.Tx, borDb kv.Tx, header *types.Header) (*Snapshot, error) { // Search for a snapshot on disk or build it from checkpoint var ( headers []*types.Header @@ -376,7 +376,7 @@ func snapshot(api *BorImpl, db kv.Tx, borDb kv.Tx, header *types.Header) (*Snaps // No snapshot for this header, move backward and check parent snapshots if header == nil { - header, _ = getHeaderByNumber(rpc.BlockNumber(number), api, db) + header, _ = getHeaderByNumber(ctx, rpc.BlockNumber(number), api, db) if header == nil { return nil, consensus.ErrUnknownAncestor } diff --git a/cmd/rpcdaemon22/commands/erigon_block.go b/cmd/rpcdaemon22/commands/erigon_block.go index d32557024e4..3d68de3a370 100644 --- a/cmd/rpcdaemon22/commands/erigon_block.go +++ b/cmd/rpcdaemon22/commands/erigon_block.go @@ -2,6 +2,7 @@ package commands import ( "context" + "errors" "fmt" "sort" @@ -35,7 +36,10 @@ func (api *ErigonImpl) GetHeaderByNumber(ctx context.Context, blockNumber rpc.Bl return nil, err } - header := rawdb.ReadHeaderByNumber(tx, blockNum) + header, err := api._blockReader.HeaderByNumber(ctx, tx, blockNum) + if err != nil { + return nil, err + } if header == nil { return nil, fmt.Errorf("block header not found: %d", blockNum) } @@ -51,7 +55,7 @@ func (api *ErigonImpl) GetHeaderByHash(ctx context.Context, hash common.Hash) (* } defer tx.Rollback() - header, err := rawdb.ReadHeaderByHash(tx, hash) + header, err := api._blockReader.HeaderByHash(ctx, tx, hash) if err != nil { return nil, err } @@ -75,7 +79,15 @@ func (api *ErigonImpl) GetBlockByTimestamp(ctx context.Context, timeStamp rpc.Ti currenttHeaderTime := currentHeader.Time highestNumber := currentHeader.Number.Uint64() - firstHeader := rawdb.ReadHeaderByNumber(tx, 0) + firstHeader, err := api._blockReader.HeaderByNumber(ctx, tx, 0) + if err != nil { + return nil, err + } + + if firstHeader == nil { + return nil, errors.New("genesis header not found") + } + firstHeaderTime := firstHeader.Time if currenttHeaderTime <= uintTimestamp { @@ -97,12 +109,26 @@ func (api *ErigonImpl) GetBlockByTimestamp(ctx context.Context, timeStamp rpc.Ti } blockNum := sort.Search(int(currentHeader.Number.Uint64()), func(blockNum int) bool { - currentHeader := rawdb.ReadHeaderByNumber(tx, uint64(blockNum)) + currentHeader, err := api._blockReader.HeaderByNumber(ctx, tx, uint64(blockNum)) + if err != nil { + return false + } + + if currentHeader == nil { + return false + } return currentHeader.Time >= uintTimestamp }) - resultingHeader := rawdb.ReadHeaderByNumber(tx, uint64(blockNum)) + resultingHeader, err := api._blockReader.HeaderByNumber(ctx, tx, uint64(blockNum)) + if err != nil { + return nil, err + } + + if resultingHeader == nil { + return nil, fmt.Errorf("no header found with block num %d", blockNum) + } if resultingHeader.Time > uintTimestamp { response, err := buildBlockResponse(tx, uint64(blockNum)-1, fullTx) diff --git a/cmd/rpcdaemon22/commands/eth_call_test.go b/cmd/rpcdaemon22/commands/eth_call_test.go index 6958651e4f5..714b47de951 100644 --- a/cmd/rpcdaemon22/commands/eth_call_test.go +++ b/cmd/rpcdaemon22/commands/eth_call_test.go @@ -174,7 +174,13 @@ func TestGetBlockByTimeMiddle(t *testing.T) { api := NewErigonAPI(NewBaseApi(nil, stateCache, snapshotsync.NewBlockReader(), nil, nil, false), db, nil) currentHeader := rawdb.ReadCurrentHeader(tx) - oldestHeader := rawdb.ReadHeaderByNumber(tx, 0) + oldestHeader, err := api._blockReader.HeaderByNumber(ctx, tx, 0) + if err != nil { + t.Errorf("error getting the oldest header %s", err) + } + if oldestHeader == nil { + t.Error("couldn't find oldest header") + } middleNumber := (currentHeader.Number.Uint64() + oldestHeader.Number.Uint64()) / 2 middleBlock, err := rawdb.ReadBlockByNumber(tx, middleNumber) From 0977639431fe520fc77399d03cdeba36526d2d52 Mon Sep 17 00:00:00 2001 From: primal_concrete_sledge Date: Fri, 1 Jul 2022 23:59:52 +0400 Subject: [PATCH 245/261] fix/issue-4593_fix_closed_chan (#4603) --- turbo/rpchelper/filters.go | 1 + 1 file changed, 1 insertion(+) diff --git a/turbo/rpchelper/filters.go b/turbo/rpchelper/filters.go index 1a90ee3754a..60a312d1961 100644 --- a/turbo/rpchelper/filters.go +++ b/turbo/rpchelper/filters.go @@ -315,6 +315,7 @@ func (ff *Filters) UnsubscribeHeads(id HeadsSubID) bool { defer ff.mu.Unlock() if ch, ok := ff.headsSubs[id]; ok { close(ch) + delete(ff.headsSubs, id) ff.storeMu.Lock() defer ff.storeMu.Unlock() delete(ff.pendingHeadsStores, id) From c7a94eeea05d7c0d569c811399642a7d108d8c82 Mon Sep 17 00:00:00 2001 From: Alex Sharp Date: Thu, 7 Jul 2022 08:39:31 +0100 Subject: [PATCH 246/261] Alpha modifications --- Makefile | 2 +- params/version.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 5fcc65b0ef1..d7d5e2298de 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ DOCKER_TAG ?= thorax/erigon:latest # Pipe error below to /dev/null since Makefile structure kind of expects # Go to be available, but with docker it's not strictly necessary CGO_CFLAGS := $(shell $(GO) env CGO_CFLAGS 2>/dev/null) # don't lose default -CGO_CFLAGS += -DMDBX_FORCE_ASSERTIONS=1 # Enable MDBX's asserts by default in 'devel' branch and disable in 'stable' +CGO_CFLAGS += -DMDBX_FORCE_ASSERTIONS=0 # Enable MDBX's asserts by default in 'devel' branch and disable in 'stable' CGO_CFLAGS := CGO_CFLAGS="$(CGO_CFLAGS)" DBG_CGO_CFLAGS += -DMDBX_DEBUG=1 diff --git a/params/version.go b/params/version.go index 56d8388b83b..be811a997a2 100644 --- a/params/version.go +++ b/params/version.go @@ -31,10 +31,10 @@ var ( // see https://calver.org const ( - VersionMajor = 2022 // Major version component of the current release - VersionMinor = 99 // Minor version component of the current release - VersionMicro = 99 // Patch version component of the current release - VersionModifier = "dev" // Modifier component of the current release + VersionMajor = 2022 // Major version component of the current release + VersionMinor = 7 // Minor version component of the current release + VersionMicro = 2 // Patch version component of the current release + VersionModifier = "alpha" // Modifier component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" ) From 47f5374abd587007a896c2dd5958d3ad7139bacd Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Wed, 20 Jul 2022 18:08:10 -0300 Subject: [PATCH 247/261] Fix search error on empty chains; empty call from/to index == eof error should be ignored --- cmd/rpcdaemon/commands/otterscan_types.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cmd/rpcdaemon/commands/otterscan_types.go b/cmd/rpcdaemon/commands/otterscan_types.go index 502e3fdee3e..d82ec682d1a 100644 --- a/cmd/rpcdaemon/commands/otterscan_types.go +++ b/cmd/rpcdaemon/commands/otterscan_types.go @@ -56,6 +56,7 @@ func newCallChunkLocator(cursor kv.Cursor, addr common.Address, navigateForward func newCallChunkProvider(cursor kv.Cursor, addr common.Address, navigateForward bool) ChunkProvider { first := true var err error + // TODO: is this flag really used? eof := false return func() ([]byte, bool, error) { if err != nil { @@ -79,7 +80,8 @@ func newCallChunkProvider(cursor kv.Cursor, addr common.Address, navigateForward if err != nil { eof = true - return nil, false, err + // Silence err; consider it EOF; handling empty chain case + return nil, false, nil } if !bytes.HasPrefix(k, addr.Bytes()) { eof = true From 49c8fc990a84bfd7bc886741b1707521dcf49211 Mon Sep 17 00:00:00 2001 From: Alexey Sharp Date: Sun, 24 Jul 2022 09:58:39 +0100 Subject: [PATCH 248/261] Alpha modifications --- params/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/params/version.go b/params/version.go index 56d8388b83b..c13a7800aea 100644 --- a/params/version.go +++ b/params/version.go @@ -31,10 +31,10 @@ var ( // see https://calver.org const ( - VersionMajor = 2022 // Major version component of the current release - VersionMinor = 99 // Minor version component of the current release - VersionMicro = 99 // Patch version component of the current release - VersionModifier = "dev" // Modifier component of the current release + VersionMajor = 2022 // Major version component of the current release + VersionMinor = 7 // Minor version component of the current release + VersionMicro = 3 // Patch version component of the current release + VersionModifier = "alpha" // Modifier component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" ) From af9f49ece7009fb62329c04e21bd3f807f6bd639 Mon Sep 17 00:00:00 2001 From: Alexey Sharp Date: Sun, 24 Jul 2022 10:28:05 +0100 Subject: [PATCH 249/261] Fix test compilation error --- cmd/rpcdaemon/commands/eth_call_test.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/cmd/rpcdaemon/commands/eth_call_test.go b/cmd/rpcdaemon/commands/eth_call_test.go index 6812cca6889..7f20bc8daca 100644 --- a/cmd/rpcdaemon/commands/eth_call_test.go +++ b/cmd/rpcdaemon/commands/eth_call_test.go @@ -22,7 +22,6 @@ import ( "github.com/ledgerwatch/erigon/core/state" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/crypto" - "github.com/ledgerwatch/erigon/eth/stagedsync" "github.com/ledgerwatch/erigon/internal/ethapi" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/rpc" @@ -361,19 +360,19 @@ func prune(t *testing.T, db kv.RwDB, pruneTo uint64) { logEvery := time.NewTicker(20 * time.Second) - err = stagedsync.PruneTableDupSort(tx, kv.AccountChangeSet, "", pruneTo, logEvery, ctx) + err = rawdb.PruneTableDupSort(tx, kv.AccountChangeSet, "", pruneTo, logEvery, ctx) assert.NoError(t, err) - err = stagedsync.PruneTableDupSort(tx, kv.StorageChangeSet, "", pruneTo, logEvery, ctx) + err = rawdb.PruneTableDupSort(tx, kv.StorageChangeSet, "", pruneTo, logEvery, ctx) assert.NoError(t, err) - err = stagedsync.PruneTable(tx, kv.Receipts, pruneTo, ctx, math.MaxInt32) + err = rawdb.PruneTable(tx, kv.Receipts, pruneTo, ctx, math.MaxInt32) assert.NoError(t, err) - err = stagedsync.PruneTable(tx, kv.Log, pruneTo, ctx, math.MaxInt32) + err = rawdb.PruneTable(tx, kv.Log, pruneTo, ctx, math.MaxInt32) assert.NoError(t, err) - err = stagedsync.PruneTableDupSort(tx, kv.CallTraceSet, "", pruneTo, logEvery, ctx) + err = rawdb.PruneTableDupSort(tx, kv.CallTraceSet, "", pruneTo, logEvery, ctx) assert.NoError(t, err) err = tx.Commit() From d88fc8242789a5f6df0ce77168e473715178d6df Mon Sep 17 00:00:00 2001 From: Alexey Sharp Date: Thu, 28 Jul 2022 08:45:22 +0100 Subject: [PATCH 250/261] Alpha modification --- params/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/params/version.go b/params/version.go index 56d8388b83b..ddec342ca38 100644 --- a/params/version.go +++ b/params/version.go @@ -31,10 +31,10 @@ var ( // see https://calver.org const ( - VersionMajor = 2022 // Major version component of the current release - VersionMinor = 99 // Minor version component of the current release - VersionMicro = 99 // Patch version component of the current release - VersionModifier = "dev" // Modifier component of the current release + VersionMajor = 2022 // Major version component of the current release + VersionMinor = 7 // Minor version component of the current release + VersionMicro = 4 // Patch version component of the current release + VersionModifier = "alpha" // Modifier component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" ) From c452cf2b9325ad3e261335bf7213574258789128 Mon Sep 17 00:00:00 2001 From: moshe-blox Date: Mon, 18 Jul 2022 17:14:28 +0300 Subject: [PATCH 251/261] Fix invalid call to `kv.Cursor.Current` after a nil `Seek` in `ChunkLocator` --- cmd/rpcdaemon/commands/otterscan_types.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cmd/rpcdaemon/commands/otterscan_types.go b/cmd/rpcdaemon/commands/otterscan_types.go index d82ec682d1a..ba42a2c43c6 100644 --- a/cmd/rpcdaemon/commands/otterscan_types.go +++ b/cmd/rpcdaemon/commands/otterscan_types.go @@ -42,7 +42,10 @@ const MaxBlockNum = ^uint64(0) func newCallChunkLocator(cursor kv.Cursor, addr common.Address, navigateForward bool) ChunkLocator { return func(minBlock uint64) (ChunkProvider, bool, error) { searchKey := callIndexKey(addr, minBlock) - _, _, err := cursor.Seek(searchKey) + k, _, err := cursor.Seek(searchKey) + if k == nil { + return nil, false, nil + } if err != nil { return nil, false, err } From 0e8879a07c057a1d1f002ca74510bc8987110380 Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Mon, 1 Aug 2022 23:55:18 -0300 Subject: [PATCH 252/261] Revert previous fix in favor of better one from previous PR --- cmd/rpcdaemon/commands/otterscan_types.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cmd/rpcdaemon/commands/otterscan_types.go b/cmd/rpcdaemon/commands/otterscan_types.go index ba42a2c43c6..ddd57f155e7 100644 --- a/cmd/rpcdaemon/commands/otterscan_types.go +++ b/cmd/rpcdaemon/commands/otterscan_types.go @@ -83,8 +83,7 @@ func newCallChunkProvider(cursor kv.Cursor, addr common.Address, navigateForward if err != nil { eof = true - // Silence err; consider it EOF; handling empty chain case - return nil, false, nil + return nil, false, err } if !bytes.HasPrefix(k, addr.Bytes()) { eof = true From 7dabdc3269f1e3b098fee5ab4d96ec843823a6fd Mon Sep 17 00:00:00 2001 From: Alexey Sharp Date: Fri, 5 Aug 2022 17:42:22 +0100 Subject: [PATCH 253/261] Alpha modifications --- params/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/params/version.go b/params/version.go index 56d8388b83b..81c10533336 100644 --- a/params/version.go +++ b/params/version.go @@ -31,10 +31,10 @@ var ( // see https://calver.org const ( - VersionMajor = 2022 // Major version component of the current release - VersionMinor = 99 // Minor version component of the current release - VersionMicro = 99 // Patch version component of the current release - VersionModifier = "dev" // Modifier component of the current release + VersionMajor = 2022 // Major version component of the current release + VersionMinor = 8 // Minor version component of the current release + VersionMicro = 1 // Patch version component of the current release + VersionModifier = "alpha" // Modifier component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" ) From 46f8c39f55d6f0c924a1749991a6e6e2747aa392 Mon Sep 17 00:00:00 2001 From: Alexey Sharp Date: Mon, 15 Aug 2022 08:31:16 +0100 Subject: [PATCH 254/261] Alpha modifications --- params/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/params/version.go b/params/version.go index d04bb02f4ad..5937d96db33 100644 --- a/params/version.go +++ b/params/version.go @@ -31,10 +31,10 @@ var ( // see https://calver.org const ( - VersionMajor = 2022 // Major version component of the current release - VersionMinor = 99 // Minor version component of the current release - VersionMicro = 99 // Patch version component of the current release - VersionModifier = "dev" // Modifier component of the current release + VersionMajor = 2022 // Major version component of the current release + VersionMinor = 8 // Minor version component of the current release + VersionMicro = 2 // Patch version component of the current release + VersionModifier = "alpha" // Modifier component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" ) From 35c4faa1b41e8379a74d0385505add0dd450c2ed Mon Sep 17 00:00:00 2001 From: Reinhard Schu Date: Mon, 15 Aug 2022 12:48:51 +0100 Subject: [PATCH 255/261] Update README.md (#5064) Revised getting started instructions to direct users to checkout the latest release --- README.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e2f772f07fa..641a29fab53 100644 --- a/README.md +++ b/README.md @@ -69,9 +69,22 @@ Usage ### Getting Started +For building a release (this will be suitable for most users just wanting to run a node): ```sh -git clone --recurse-submodules -j8 https://github.com/ledgerwatch/erigon.git +git clone https://github.com/ledgerwatch/erigon.git +cd erigon +git tag -l | grep 2022 +git checkout +make erigon +./build/bin/erigon +``` +You can also get the latest release tag by checking [the list of releases](https://github.com/ledgerwatch/erigon/releases) + +For building the bleeding edge development branch: +```sh +git clone --recurse-submodules https://github.com/ledgerwatch/erigon.git cd erigon +git checkout devel make erigon ./build/bin/erigon ``` From 65b8dcee74a5da9e562004c5fc2f0a626d890abb Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Wed, 17 Aug 2022 17:18:13 -0300 Subject: [PATCH 256/261] Workaround fix --- cmd/rpcdaemon/commands/otterscan_api.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 293541d3cb3..e7e9fb9a89b 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -367,6 +367,9 @@ func (api *OtterscanAPIImpl) delegateGetBlockByNumber(tx kv.Tx, b *types.Block, return nil, err } response, err := ethapi.RPCMarshalBlock(b, inclTx, inclTx) + if !inclTx { + delete(response, "transactions") // workaround for https://github.com/ledgerwatch/erigon/issues/4989#issuecomment-1218415666 + } response["totalDifficulty"] = (*hexutil.Big)(td) response["transactionCount"] = b.Transactions().Len() From defbddf8d64718c71ec24c408f31c7f28ecf3e9e Mon Sep 17 00:00:00 2001 From: Alex Sharp Date: Sat, 27 Aug 2022 14:47:14 +0100 Subject: [PATCH 257/261] Alpha modification --- params/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/params/version.go b/params/version.go index d04bb02f4ad..6171d8aac83 100644 --- a/params/version.go +++ b/params/version.go @@ -31,10 +31,10 @@ var ( // see https://calver.org const ( - VersionMajor = 2022 // Major version component of the current release - VersionMinor = 99 // Minor version component of the current release - VersionMicro = 99 // Patch version component of the current release - VersionModifier = "dev" // Modifier component of the current release + VersionMajor = 2022 // Major version component of the current release + VersionMinor = 8 // Minor version component of the current release + VersionMicro = 3 // Patch version component of the current release + VersionModifier = "alpha" // Modifier component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" ) From 9ea1c52f0fcf939c182e1e6d3725d24f6a60bfbf Mon Sep 17 00:00:00 2001 From: Willian Mitsuda Date: Mon, 29 Aug 2022 10:36:15 -0300 Subject: [PATCH 258/261] Remove workflows from upstream --- .github/workflows/coverage.yml | 55 --------------------------- .github/workflows/hive-results.yml | 60 ------------------------------ .github/workflows/release.yml | 41 -------------------- 3 files changed, 156 deletions(-) delete mode 100644 .github/workflows/coverage.yml delete mode 100644 .github/workflows/hive-results.yml delete mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml deleted file mode 100644 index b022cf5af81..00000000000 --- a/.github/workflows/coverage.yml +++ /dev/null @@ -1,55 +0,0 @@ -name: Coverage -on: - push: - branches: - - devel - -jobs: - coverage: - runs-on: ubuntu-20.04 - - steps: - - uses: actions/checkout@v3 - - run: git submodule update --init --recursive --force - - - uses: actions/setup-go@v3 - with: - go-version: 1.18.x - - - name: install dependencies on Linux - if: runner.os == 'Linux' - run: sudo apt update && sudo apt install build-essential - - - name: run coverage - run: echo "COVERAGE=$(make coverage)" >> $GITHUB_ENV - - - name: set badge color - shell: bash - run: | - if [ ${{ env.COVERAGE }} -lt 40 ] - then - echo "BADGE_COLOR=800000" >> $GITHUB_ENV - elif [ ${{ env.COVERAGE }} -lt 75 ] - then - echo "BADGE_COLOR=696969" >> $GITHUB_ENV - else - echo "BADGE_COLOR=31c653" >> $GITHUB_ENV - fi - - - name: create badge - uses: emibcn/badge-action@d6f51ff11b5c3382b3b88689ae2d6db22d9737d1 - with: - label: Coverage - status: ${{ env.COVERAGE }} - color: ${{ env.BADGE_COLOR }} - path: badge.svg - - - name: upload badge to gist - if: > - github.event_name == 'workflow_run' && github.event.workflow_run.head_branch == 'devel' || - github.event_name != 'workflow_run' && github.ref == 'refs/heads/devel' - uses: andymckay/append-gist-action@1fbfbbce708a39bd45846f0955ed5521f2099c6d - with: - token: ${{ secrets.GIST_TOKEN }} - gistURL: https://gist.githubusercontent.com/revitteth/ee38e9beb22353eef6b88f2ad6ed7aa9 - file: badge.svg \ No newline at end of file diff --git a/.github/workflows/hive-results.yml b/.github/workflows/hive-results.yml deleted file mode 100644 index be81bdd87cf..00000000000 --- a/.github/workflows/hive-results.yml +++ /dev/null @@ -1,60 +0,0 @@ - name: Hive results - - on: - workflow_run: - workflows: ["CI"] - types: - - completed - - jobs: - hive-results: - name: Hive results - runs-on: ubuntu-latest - if: github.event.workflow_run.conclusion != 'skipped' - - permissions: - checks: write - pull-requests: write - actions: read - - steps: - - name: parse hive results - uses: phoenix-actions/test-reporting@v8 - with: - artifact: test-results - name: Tests - path: '*.xml' - reporter: java-junit - - - name: set badge color - shell: bash - run: | - case ${{ fromJSON( steps.test-results.outputs.json ).conclusion }} in - success) - echo "BADGE_COLOR=31c653" >> $GITHUB_ENV - ;; - failure) - echo "BADGE_COLOR=800000" >> $GITHUB_ENV - ;; - neutral) - echo "BADGE_COLOR=696969" >> $GITHUB_ENV - ;; - esac - - - name: create badge - uses: emibcn/badge-action@d6f51ff11b5c3382b3b88689ae2d6db22d9737d1 - with: - label: Hive - status: '${{ fromJSON( steps.test-results.outputs.json ).formatted.stats.tests }} tests, ${{ fromJSON( steps.test-results.outputs.json ).formatted.stats.runs }} runs: ${{ fromJSON( steps.test-results.outputs.json ).conclusion }}' - color: ${{ env.BADGE_COLOR }} - path: badge.svg - - - name: upload badge to gist - if: > - github.event_name == 'workflow_run' && github.event.workflow_run.head_branch == 'devel' || - github.event_name != 'workflow_run' && github.ref == 'refs/heads/devel' - uses: andymckay/append-gist-action@1fbfbbce708a39bd45846f0955ed5521f2099c6d - with: - token: ${{ secrets.GIST_TOKEN }} - gistURL: https://gist.githubusercontent.com/revitteth/dc492845ba6eb694e6c7279224634b20 - file: badge.svg \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 29531622448..00000000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: Release - -on: - push: - branches-ignore: - - '**' - tags: - - 'v*.*.*' - # to be used by fork patch-releases ^^ - - 'v*.*.*-*' - -jobs: - goreleaser: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - - name: Set up Go - uses: actions/setup-go@master - with: - go-version: 1.18.x - - - name: Prepare - id: prepare - run: | - TAG=${GITHUB_REF#refs/tags/} - echo ::set-output name=tag_name::${TAG} - - name: Set up QEMU - uses: docker/setup-qemu-action@v1 - - - name: Run GoReleaser - run: | - make release - env: - GITHUB_TOKEN: ${{ secrets.GIT_TOKEN }} - VERSION: ${{ steps.prepare.outputs.tag_name }} - DOCKER_USERNAME: ${{ secrets.DOCKERHUB }} - DOCKER_PASSWORD: ${{ secrets.DOCKERHUB_KEY }} From 4067b7c4da6c5d741d3027d95ae2afdf6b7a943a Mon Sep 17 00:00:00 2001 From: Alexey Sharp Date: Sun, 4 Sep 2022 15:12:22 +0100 Subject: [PATCH 259/261] Alpha modifications --- params/version.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/params/version.go b/params/version.go index 6171d8aac83..7bebdde5ace 100644 --- a/params/version.go +++ b/params/version.go @@ -32,8 +32,8 @@ var ( // see https://calver.org const ( VersionMajor = 2022 // Major version component of the current release - VersionMinor = 8 // Minor version component of the current release - VersionMicro = 3 // Patch version component of the current release + VersionMinor = 9 // Minor version component of the current release + VersionMicro = 1 // Patch version component of the current release VersionModifier = "alpha" // Modifier component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" From 38b35e09fe8e2249f22570f60cf9407b05fc2b49 Mon Sep 17 00:00:00 2001 From: Alexey Sharp Date: Sat, 17 Sep 2022 13:27:26 +0100 Subject: [PATCH 260/261] Alpha modifications --- params/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/params/version.go b/params/version.go index ac573db3422..990de447223 100644 --- a/params/version.go +++ b/params/version.go @@ -31,10 +31,10 @@ var ( // see https://calver.org const ( - VersionMajor = 2022 // Major version component of the current release - VersionMinor = 9 // Minor version component of the current release - VersionMicro = 2 // Patch version component of the current release - VersionModifier = "dev" // Modifier component of the current release + VersionMajor = 2022 // Major version component of the current release + VersionMinor = 9 // Minor version component of the current release + VersionMicro = 2 // Patch version component of the current release + VersionModifier = "stable" // Modifier component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" ) From 32bd69e5316050005e34448ec6b0165f97173d50 Mon Sep 17 00:00:00 2001 From: Alexey Sharp Date: Tue, 20 Sep 2022 09:08:22 +0100 Subject: [PATCH 261/261] Alpha modifications --- params/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/params/version.go b/params/version.go index 747156e94c6..62e7fd0c12e 100644 --- a/params/version.go +++ b/params/version.go @@ -31,10 +31,10 @@ var ( // see https://calver.org const ( - VersionMajor = 2022 // Major version component of the current release - VersionMinor = 9 // Minor version component of the current release - VersionMicro = 3 // Patch version component of the current release - VersionModifier = "dev" // Modifier component of the current release + VersionMajor = 2022 // Major version component of the current release + VersionMinor = 9 // Minor version component of the current release + VersionMicro = 3 // Patch version component of the current release + VersionModifier = "stable" // Modifier component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" )