diff --git a/Makefile b/Makefile index ee1d40faa0..deb990bf50 100644 --- a/Makefile +++ b/Makefile @@ -56,6 +56,7 @@ trace-pointer: bash ./scripts/go_executable_build.sh -t debug: + rm -rf .dht-127.0.0.1* bash ./test/debug.sh debug-kill: @@ -167,3 +168,15 @@ docker: travis_go_checker: bash ./scripts/travis_go_checker.sh + +travis_rpc_checker: + bash ./scripts/travis_rpc_checker.sh + +travis_rosetta_checker: + bash ./scripts/travis_rosetta_checker.sh + +debug_external: clean + bash test/debug-external.sh + +build_localnet_validator: + bash test/build-localnet-validator.sh \ No newline at end of file diff --git a/accounts/abi/bind/auth.go b/accounts/abi/bind/auth.go index ee29295d4d..4f89bf595b 100644 --- a/accounts/abi/bind/auth.go +++ b/accounts/abi/bind/auth.go @@ -20,7 +20,6 @@ import ( "crypto/ecdsa" "errors" "io" - "io/ioutil" "math/big" "github.com/ethereum/go-ethereum/common" @@ -44,7 +43,7 @@ var ErrNotAuthorized = errors.New("not authorized to sign this account") // Deprecated: Use NewTransactorWithChainID instead. func NewTransactor(keyin io.Reader, passphrase string) (*TransactOpts, error) { log.Warn("WARNING: NewTransactor has been deprecated in favour of NewTransactorWithChainID") - json, err := ioutil.ReadAll(keyin) + json, err := io.ReadAll(keyin) if err != nil { return nil, err } @@ -103,7 +102,7 @@ func NewKeyedTransactor(key *ecdsa.PrivateKey) *TransactOpts { // NewTransactorWithChainID is a utility method to easily create a transaction signer from // an encrypted json key stream and the associated passphrase. func NewTransactorWithChainID(keyin io.Reader, passphrase string, chainID *big.Int) (*TransactOpts, error) { - json, err := ioutil.ReadAll(keyin) + json, err := io.ReadAll(keyin) if err != nil { return nil, err } diff --git a/accounts/keystore/account_cache_test.go b/accounts/keystore/account_cache_test.go index 1ced434c52..d6ecefe88e 100644 --- a/accounts/keystore/account_cache_test.go +++ b/accounts/keystore/account_cache_test.go @@ -18,7 +18,6 @@ package keystore import ( "fmt" - "io/ioutil" "math/rand" "os" "path/filepath" @@ -133,11 +132,11 @@ func TestUpdatedKeyfileContents(t *testing.T) { return } - // needed so that modTime of `file` is different to its current value after ioutil.WriteFile + // needed so that modTime of `file` is different to its current value after io.WriteFile time.Sleep(1000 * time.Millisecond) // Now replace file contents with crap - if err := ioutil.WriteFile(file, []byte("foo"), 0644); err != nil { + if err := os.WriteFile(file, []byte("foo"), 0644); err != nil { t.Fatal(err) return } @@ -150,9 +149,9 @@ func TestUpdatedKeyfileContents(t *testing.T) { // forceCopyFile is like cp.CopyFile, but doesn't complain if the destination exists. func forceCopyFile(dst, src string) error { - data, err := ioutil.ReadFile(src) + data, err := os.ReadFile(src) if err != nil { return err } - return ioutil.WriteFile(dst, data, 0644) + return os.WriteFile(dst, data, 0644) } diff --git a/accounts/keystore/file_cache.go b/accounts/keystore/file_cache.go index bd22a9f519..5bf6cc4955 100644 --- a/accounts/keystore/file_cache.go +++ b/accounts/keystore/file_cache.go @@ -17,7 +17,7 @@ package keystore import ( - "io/ioutil" + "io/fs" "os" "path/filepath" "strings" @@ -42,7 +42,7 @@ func (fc *fileCache) scan(keyDir string) (mapset.Set, mapset.Set, mapset.Set, er t0 := time.Now() // List all the failes from the keystore folder - files, err := ioutil.ReadDir(keyDir) + files, err := os.ReadDir(keyDir) if err != nil { return nil, nil, nil, err } @@ -63,15 +63,19 @@ func (fc *fileCache) scan(keyDir string) (mapset.Set, mapset.Set, mapset.Set, er utils.Logger().Debug().Str("path", path).Msg("Ignoring file on account scan") continue } - // Gather the set of all and fresly modified files + // Gather the set of all and freshly modified files all.Add(path) - modified := fi.ModTime() - if modified.After(fc.lastMod) { - mods.Add(path) - } - if modified.After(newLastMod) { - newLastMod = modified + if info, err := fi.Info(); err != nil { + continue + } else { + modified := info.ModTime() + if modified.After(fc.lastMod) { + mods.Add(path) + } + if modified.After(newLastMod) { + newLastMod = modified + } } } t2 := time.Now() @@ -94,14 +98,18 @@ func (fc *fileCache) scan(keyDir string) (mapset.Set, mapset.Set, mapset.Set, er } // nonKeyFile ignores editor backups, hidden files and folders/symlinks. -func nonKeyFile(fi os.FileInfo) bool { +func nonKeyFile(fi fs.DirEntry) bool { // Skip editor backups and UNIX-style hidden files. if strings.HasSuffix(fi.Name(), "~") || strings.HasPrefix(fi.Name(), ".") { return true } // Skip misc special files, directories (yes, symlinks too). - if fi.IsDir() || fi.Mode()&os.ModeType != 0 { + if info, err := fi.Info(); err != nil { return true + } else { + if fi.IsDir() || info.Mode()&os.ModeType != 0 { + return true + } } return false } diff --git a/accounts/keystore/key.go b/accounts/keystore/key.go index 14e0018e20..c632acf2e5 100644 --- a/accounts/keystore/key.go +++ b/accounts/keystore/key.go @@ -23,7 +23,6 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "os" "path/filepath" "strings" @@ -195,7 +194,7 @@ func writeTemporaryKeyFile(file string, content []byte) (string, error) { } // Atomic write: create a temporary hidden file first // then move it into place. TempFile assigns mode 0600. - f, err := ioutil.TempFile(filepath.Dir(file), "."+filepath.Base(file)+".tmp") + f, err := os.CreateTemp(filepath.Dir(file), "."+filepath.Base(file)+".tmp") if err != nil { return "", err } diff --git a/accounts/keystore/keystore_test.go b/accounts/keystore/keystore_test.go index fa5392209c..420332a150 100644 --- a/accounts/keystore/keystore_test.go +++ b/accounts/keystore/keystore_test.go @@ -17,7 +17,6 @@ package keystore import ( - "io/ioutil" "os" "runtime" "strings" @@ -213,7 +212,7 @@ func TestSignRace(t *testing.T) { } func tmpKeyStore(t *testing.T, encrypted bool) (string, *KeyStore) { - d, err := ioutil.TempDir("", "eth-keystore-test") + d, err := os.MkdirTemp("", "eth-keystore-test") if err != nil { t.Fatal(err) } diff --git a/accounts/keystore/passphrase.go b/accounts/keystore/passphrase.go index 221f82da46..ffeddd7846 100644 --- a/accounts/keystore/passphrase.go +++ b/accounts/keystore/passphrase.go @@ -34,7 +34,6 @@ import ( "encoding/json" "fmt" "io" - "io/ioutil" "os" "path/filepath" @@ -82,7 +81,7 @@ type keyStorePassphrase struct { func (ks keyStorePassphrase) GetKey(addr common.Address, filename, auth string) (*Key, error) { // Load the key from the keystore and decrypt its contents - keyjson, err := ioutil.ReadFile(filename) + keyjson, err := os.ReadFile(filename) if err != nil { return nil, err } diff --git a/accounts/keystore/passphrase_test.go b/accounts/keystore/passphrase_test.go index 630682cebd..b94fce8edc 100644 --- a/accounts/keystore/passphrase_test.go +++ b/accounts/keystore/passphrase_test.go @@ -17,7 +17,7 @@ package keystore import ( - "io/ioutil" + "os" "testing" "github.com/ethereum/go-ethereum/common" @@ -30,7 +30,7 @@ const ( // Tests that a json key file can be decrypted and encrypted in multiple rounds. func TestKeyEncryptDecrypt(t *testing.T) { - keyjson, err := ioutil.ReadFile("testdata/very-light-scrypt.json") + keyjson, err := os.ReadFile("testdata/very-light-scrypt.json") if err != nil { t.Fatal(err) } diff --git a/accounts/keystore/plain_test.go b/accounts/keystore/plain_test.go index 2cccb8e3bd..2ab50a9bf8 100644 --- a/accounts/keystore/plain_test.go +++ b/accounts/keystore/plain_test.go @@ -20,7 +20,6 @@ import ( "crypto/rand" "encoding/hex" "fmt" - "io/ioutil" "os" "path/filepath" "reflect" @@ -32,7 +31,7 @@ import ( ) func tmpKeyStoreIface(t *testing.T, encrypted bool) (dir string, ks keyStore) { - d, err := ioutil.TempDir("", "geth-keystore-test") + d, err := os.MkdirTemp("", "geth-keystore-test") if err != nil { t.Fatal(err) } diff --git a/api/service/legacysync/syncing.go b/api/service/legacysync/syncing.go index 3375ccdc50..44c5de64a2 100644 --- a/api/service/legacysync/syncing.go +++ b/api/service/legacysync/syncing.go @@ -25,7 +25,6 @@ import ( "github.com/harmony-one/harmony/internal/chain" nodeconfig "github.com/harmony-one/harmony/internal/configs/node" "github.com/harmony-one/harmony/internal/utils" - "github.com/harmony-one/harmony/node/worker" "github.com/harmony-one/harmony/p2p" libp2p_peer "github.com/libp2p/go-libp2p/core/peer" "github.com/pkg/errors" @@ -932,7 +931,7 @@ func (ss *StateSync) UpdateBlockAndStatus(block *types.Block, bc core.BlockChain } // generateNewState will construct most recent state from downloaded blocks -func (ss *StateSync) generateNewState(bc core.BlockChain, worker *worker.Worker) error { +func (ss *StateSync) generateNewState(bc core.BlockChain) error { // update blocks created before node start sync parentHash := bc.CurrentBlock().Hash() @@ -995,7 +994,7 @@ func (ss *StateSync) generateNewState(bc core.BlockChain, worker *worker.Worker) } // ProcessStateSync processes state sync from the blocks received but not yet processed so far -func (ss *StateSync) ProcessStateSync(startHash []byte, size uint32, bc core.BlockChain, worker *worker.Worker) error { +func (ss *StateSync) ProcessStateSync(startHash []byte, size uint32, bc core.BlockChain) error { // Gets consensus hashes. if err := ss.getConsensusHashes(startHash, size); err != nil { return errors.Wrap(err, "getConsensusHashes") @@ -1005,7 +1004,7 @@ func (ss *StateSync) ProcessStateSync(startHash []byte, size uint32, bc core.Blo if ss.stateSyncTaskQueue.Len() > 0 { ss.downloadBlocks(bc) } - return ss.generateNewState(bc, worker) + return ss.generateNewState(bc) } func (peerConfig *SyncPeerConfig) registerToBroadcast(peerHash []byte, ip, port string) error { @@ -1076,7 +1075,7 @@ func (ss *StateSync) GetMaxPeerHeight() (uint64, error) { } // SyncLoop will keep syncing with peers until catches up -func (ss *StateSync) SyncLoop(bc core.BlockChain, worker *worker.Worker, isBeacon bool, consensus *consensus.Consensus, loopMinTime time.Duration) { +func (ss *StateSync) SyncLoop(bc core.BlockChain, isBeacon bool, consensus *consensus.Consensus, loopMinTime time.Duration) { utils.Logger().Info().Msgf("legacy sync is executing ...") if !isBeacon { ss.RegisterNodeInfo() @@ -1110,7 +1109,7 @@ func (ss *StateSync) SyncLoop(bc core.BlockChain, worker *worker.Worker, isBeaco if size > SyncLoopBatchSize { size = SyncLoopBatchSize } - err := ss.ProcessStateSync(startHash[:], size, bc, worker) + err := ss.ProcessStateSync(startHash[:], size, bc) if err != nil { utils.Logger().Error().Err(err). Msgf("[SYNC] ProcessStateSync failed (isBeacon: %t, ShardID: %d, otherHeight: %d, currentHeight: %d)", diff --git a/api/service/stagedstreamsync/const.go b/api/service/stagedstreamsync/const.go index 5c735d764b..048b5d812d 100644 --- a/api/service/stagedstreamsync/const.go +++ b/api/service/stagedstreamsync/const.go @@ -23,9 +23,6 @@ const ( // no more request will be assigned to workers to wait for InsertChain to finish. SoftQueueCap int = 100 - // DefaultConcurrency is the default settings for concurrency - DefaultConcurrency int = 4 - // ShortRangeTimeout is the timeout for each short range sync, which allow short range sync // to restart automatically when stuck in `getBlockHashes` ShortRangeTimeout time.Duration = 1 * time.Minute @@ -74,10 +71,10 @@ type ( func (c *Config) fixValues() { if c.Concurrency == 0 { - c.Concurrency = DefaultConcurrency + c.Concurrency = c.MinStreams } if c.Concurrency > c.MinStreams { - c.MinStreams = c.Concurrency + c.Concurrency = c.MinStreams } if c.MinStreams > c.InitStreams { c.InitStreams = c.MinStreams diff --git a/api/service/stagedstreamsync/downloader.go b/api/service/stagedstreamsync/downloader.go index 96add97fd3..3711048955 100644 --- a/api/service/stagedstreamsync/downloader.go +++ b/api/service/stagedstreamsync/downloader.go @@ -153,6 +153,17 @@ func (d *Downloader) SubscribeDownloadFinished(ch chan struct{}) event.Subscript // waitForBootFinish waits for stream manager to finish the initial discovery and have // enough peers to start downloader func (d *Downloader) waitForBootFinish() { + bootCompleted, numStreams := d.waitForEnoughStreams(d.config.InitStreams) + if bootCompleted { + fmt.Printf("boot completed for shard %d ( %d streams are connected )\n", + d.bc.ShardID(), numStreams) + } +} + +func (d *Downloader) waitForEnoughStreams(requiredStreams int) (bool, int) { + d.logger.Info().Int("requiredStreams", requiredStreams). + Msg("waiting for enough stream connections to continue syncing") + evtCh := make(chan streammanager.EvtStreamAdded, 1) sub := d.syncProtocol.SubscribeAddStreamEvent(evtCh) defer sub.Unsubscribe() @@ -177,12 +188,11 @@ func (d *Downloader) waitForBootFinish() { trigger() case <-checkCh: - if d.syncProtocol.NumStreams() >= d.config.InitStreams { - fmt.Printf("boot completed for shard %d ( %d streams are connected )\n", d.bc.ShardID(), d.syncProtocol.NumStreams()) - return + if d.syncProtocol.NumStreams() >= requiredStreams { + return true, d.syncProtocol.NumStreams() } case <-d.closeC: - return + return false, d.syncProtocol.NumStreams() } } } @@ -212,6 +222,9 @@ func (d *Downloader) loop() { case <-d.downloadC: bnBeforeSync := d.bc.CurrentBlock().NumberU64() estimatedHeight, addedBN, err := d.stagedSyncInstance.doSync(d.ctx, initSync) + if err == ErrNotEnoughStreams { + d.waitForEnoughStreams(d.config.MinStreams) + } if err != nil { //TODO: if there is a bad block which can't be resolved if d.stagedSyncInstance.invalidBlock.Active { diff --git a/api/service/stagedstreamsync/errors.go b/api/service/stagedstreamsync/errors.go index d18020dd06..9f1e1eb60b 100644 --- a/api/service/stagedstreamsync/errors.go +++ b/api/service/stagedstreamsync/errors.go @@ -14,7 +14,7 @@ var ( ErrUnexpectedNumberOfBlockHashes = WrapStagedSyncError("unexpected number of getBlocksByHashes result") ErrUnexpectedBlockHashes = WrapStagedSyncError("unexpected get block hashes result delivered") ErrNilBlock = WrapStagedSyncError("nil block found") - ErrNotEnoughStreams = WrapStagedSyncError("not enough streams") + ErrNotEnoughStreams = WrapStagedSyncError("number of streams smaller than minimum required") ErrParseCommitSigAndBitmapFail = WrapStagedSyncError("parse commitSigAndBitmap failed") ErrVerifyHeaderFail = WrapStagedSyncError("verify header failed") ErrInsertChainFail = WrapStagedSyncError("insert to chain failed") diff --git a/api/service/stagedstreamsync/short_range_helper.go b/api/service/stagedstreamsync/short_range_helper.go index 42327c78df..aa6b785120 100644 --- a/api/service/stagedstreamsync/short_range_helper.go +++ b/api/service/stagedstreamsync/short_range_helper.go @@ -7,6 +7,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/harmony-one/harmony/core/types" + "github.com/harmony-one/harmony/internal/utils" syncProto "github.com/harmony-one/harmony/p2p/stream/protocols/sync" sttypes "github.com/harmony-one/harmony/p2p/stream/types" "github.com/pkg/errors" @@ -132,6 +133,10 @@ func (sh *srHelper) getBlocksByHashes(ctx context.Context, hashes []common.Hash, func (sh *srHelper) checkPrerequisites() error { if sh.syncProtocol.NumStreams() < sh.config.Concurrency { + utils.Logger().Info(). + Int("available streams", sh.syncProtocol.NumStreams()). + Interface("concurrency", sh.config.Concurrency). + Msg("not enough streams to do concurrent processes") return ErrNotEnoughStreams } return nil diff --git a/api/service/stagedstreamsync/stage_bodies.go b/api/service/stagedstreamsync/stage_bodies.go index 4996ea78b7..b5d92e3a1a 100644 --- a/api/service/stagedstreamsync/stage_bodies.go +++ b/api/service/stagedstreamsync/stage_bodies.go @@ -167,13 +167,22 @@ func (b *StageBodies) runBlockWorkerLoop(ctx context.Context, gbm *blockDownload Msg(WrapStagedSyncMsg("downloadRawBlocks failed")) err = errors.Wrap(err, "request error") gbm.HandleRequestError(batch, err, stid) - } else if blockBytes == nil || len(blockBytes) == 0 { + } else if blockBytes == nil { utils.Logger().Warn(). Str("stream", string(stid)). Interface("block numbers", batch). - Msg(WrapStagedSyncMsg("downloadRawBlocks failed, received empty blockBytes")) + Msg(WrapStagedSyncMsg("downloadRawBlocks failed, received invalid (nil) blockBytes")) + err := errors.New("downloadRawBlocks received invalid (nil) blockBytes") + gbm.HandleRequestError(batch, err, stid) + b.configs.protocol.StreamFailed(stid, "downloadRawBlocks failed") + } else if len(blockBytes) == 0 { + utils.Logger().Warn(). + Str("stream", string(stid)). + Interface("block numbers", batch). + Msg(WrapStagedSyncMsg("downloadRawBlocks failed, received empty blockBytes, remote peer is not fully synced")) err := errors.New("downloadRawBlocks received empty blockBytes") gbm.HandleRequestError(batch, err, stid) + b.configs.protocol.RemoveStream(stid) } else { if err = b.saveBlocks(ctx, gbm.tx, batch, blockBytes, sigBytes, loopID, stid); err != nil { panic(ErrSaveBlocksToDbFailed) diff --git a/api/service/stagedstreamsync/stage_epoch.go b/api/service/stagedstreamsync/stage_epoch.go index 2c51aa1f94..e84b74f340 100644 --- a/api/service/stagedstreamsync/stage_epoch.go +++ b/api/service/stagedstreamsync/stage_epoch.go @@ -92,7 +92,12 @@ func (sr *StageEpoch) doShortRangeSyncForEpochSync(ctx context.Context, s *Stage } if err := sh.checkPrerequisites(); err != nil { - return 0, errors.Wrap(err, "prerequisite") + // if error is ErrNotEnoughStreams but still some streams available, + // it can continue syncing, otherwise return error + // here we are not doing concurrent processes, so even 1 stream should be enough + if err != ErrNotEnoughStreams || s.state.protocol.NumStreams() == 0 { + return 0, errors.Wrap(err, "prerequisite") + } } curBN := s.state.bc.CurrentBlock().NumberU64() bns := make([]uint64, 0, BlocksPerRequest) diff --git a/api/service/stagedstreamsync/stage_short_range.go b/api/service/stagedstreamsync/stage_short_range.go index 54534bfbb1..ce6cdf36bc 100644 --- a/api/service/stagedstreamsync/stage_short_range.go +++ b/api/service/stagedstreamsync/stage_short_range.go @@ -97,7 +97,12 @@ func (sr *StageShortRange) doShortRangeSync(ctx context.Context, s *StageState) } if err := sh.checkPrerequisites(); err != nil { - return 0, errors.Wrap(err, "prerequisite") + // if error is ErrNotEnoughStreams but still two streams available, + // it can continue syncing, otherwise return error + // at least 2 streams are needed to do concurrent processes + if err != ErrNotEnoughStreams || s.state.protocol.NumStreams() < 2 { + return 0, errors.Wrap(err, "prerequisite") + } } curBN := sr.configs.bc.CurrentBlock().NumberU64() blkNums := sh.prepareBlockHashNumbers(curBN) diff --git a/api/service/stagedstreamsync/staged_stream_sync.go b/api/service/stagedstreamsync/staged_stream_sync.go index 3cd8756604..1592186b52 100644 --- a/api/service/stagedstreamsync/staged_stream_sync.go +++ b/api/service/stagedstreamsync/staged_stream_sync.go @@ -337,8 +337,9 @@ func (s *StagedStreamSync) promLabels() prometheus.Labels { func (s *StagedStreamSync) checkHaveEnoughStreams() error { numStreams := s.protocol.NumStreams() if numStreams < s.config.MinStreams { - return fmt.Errorf("number of streams smaller than minimum: %v < %v", + s.logger.Debug().Msgf("number of streams smaller than minimum: %v < %v", numStreams, s.config.MinStreams) + return ErrNotEnoughStreams } return nil } diff --git a/api/service/stagedsync/sync_config.go b/api/service/stagedsync/sync_config.go index 91b3a4d739..7d20670818 100644 --- a/api/service/stagedsync/sync_config.go +++ b/api/service/stagedsync/sync_config.go @@ -23,9 +23,8 @@ const ( downloadBlocksRetryLimit = 3 // downloadBlocks service retry limit RegistrationNumber = 3 SyncingPortDifference = 3000 - inSyncThreshold = 0 // when peerBlockHeight - myBlockHeight <= inSyncThreshold, it's ready to join consensus - SyncLoopBatchSize uint32 = 30 // maximum size for one query of block hashes - verifyHeaderBatchSize uint64 = 100 // block chain header verification batch size (not used for now) + inSyncThreshold = 0 // when peerBlockHeight - myBlockHeight <= inSyncThreshold, it's ready to join consensus + SyncLoopBatchSize uint32 = 30 // maximum size for one query of block hashes LastMileBlocksSize = 50 // after cutting off a number of connected peers, the result number of peers @@ -53,14 +52,6 @@ type SyncPeerConfig struct { failedTimes uint64 } -// CreateTestSyncPeerConfig used for testing. -func CreateTestSyncPeerConfig(client *downloader.Client, blockHashes [][]byte) *SyncPeerConfig { - return &SyncPeerConfig{ - client: client, - blockHashes: blockHashes, - } -} - // GetClient returns client pointer of downloader.Client func (peerConfig *SyncPeerConfig) GetClient() *downloader.Client { return peerConfig.client @@ -303,21 +294,21 @@ func (sc *SyncConfig) FindPeerByHash(peerHash []byte) *SyncPeerConfig { // getHowManyMaxConsensus returns max number of consensus nodes and the first ID of consensus group. // Assumption: all peers are sorted by CompareSyncPeerConfigByBlockHashes first. // Caller shall ensure mtx is locked for reading. -func (sc *SyncConfig) getHowManyMaxConsensus() (int, int) { +func getHowManyMaxConsensus(peers []*SyncPeerConfig) (int, int) { // As all peers are sorted by their blockHashes, all equal blockHashes should come together and consecutively. - if len(sc.peers) == 0 { + if len(peers) == 0 { return -1, 0 - } else if len(sc.peers) == 1 { + } else if len(peers) == 1 { return 0, 1 } - maxFirstID := len(sc.peers) - 1 + maxFirstID := len(peers) - 1 for i := maxFirstID - 1; i >= 0; i-- { - if CompareSyncPeerConfigByblockHashes(sc.peers[maxFirstID], sc.peers[i]) != 0 { + if CompareSyncPeerConfigByblockHashes(peers[maxFirstID], peers[i]) != 0 { break } maxFirstID = i } - maxCount := len(sc.peers) - maxFirstID + maxCount := len(peers) - maxFirstID return maxFirstID, maxCount } @@ -386,7 +377,7 @@ func (sc *SyncConfig) GetBlockHashesConsensusAndCleanUp(bgMode bool) error { sort.Slice(sc.peers, func(i, j int) bool { return CompareSyncPeerConfigByblockHashes(sc.peers[i], sc.peers[j]) == -1 }) - maxFirstID, maxCount := sc.getHowManyMaxConsensus() + maxFirstID, maxCount := getHowManyMaxConsensus(sc.peers) if maxFirstID == -1 { return errors.New("invalid peer index -1 for block hashes query") } diff --git a/api/service/stagedsync/syncing.go b/api/service/stagedsync/syncing.go index a22a4e9253..623ea476d9 100644 --- a/api/service/stagedsync/syncing.go +++ b/api/service/stagedsync/syncing.go @@ -11,7 +11,6 @@ import ( "github.com/harmony-one/harmony/core" nodeconfig "github.com/harmony-one/harmony/internal/configs/node" "github.com/harmony-one/harmony/internal/utils" - "github.com/harmony-one/harmony/node/worker" "github.com/harmony-one/harmony/shard" "github.com/ledgerwatch/erigon-lib/kv" @@ -163,7 +162,7 @@ func initDB(ctx context.Context, db kv.RwDB) error { } // SyncLoop will keep syncing with peers until catches up -func (s *StagedSync) SyncLoop(bc core.BlockChain, worker *worker.Worker, isBeacon bool, consensus *consensus.Consensus, loopMinTime time.Duration) { +func (s *StagedSync) SyncLoop(bc core.BlockChain, isBeacon bool, consensus *consensus.Consensus, loopMinTime time.Duration) { utils.Logger().Info(). Uint64("current height", bc.CurrentBlock().NumberU64()). @@ -204,7 +203,7 @@ func (s *StagedSync) SyncLoop(bc core.BlockChain, worker *worker.Worker, isBeaco } startTime := time.Now() - if err := s.runSyncCycle(bc, worker, isBeacon, consensus, maxPeersHeight); err != nil { + if err := s.runSyncCycle(bc, isBeacon, consensus, maxPeersHeight); err != nil { utils.Logger().Error(). Err(err). Bool("isBeacon", isBeacon). @@ -266,7 +265,7 @@ func (s *StagedSync) SyncLoop(bc core.BlockChain, worker *worker.Worker, isBeaco } // runSyncCycle will run one cycle of staged syncing -func (s *StagedSync) runSyncCycle(bc core.BlockChain, worker *worker.Worker, isBeacon bool, consensus *consensus.Consensus, maxPeersHeight uint64) error { +func (s *StagedSync) runSyncCycle(bc core.BlockChain, isBeacon bool, consensus *consensus.Consensus, maxPeersHeight uint64) error { canRunCycleInOneTransaction := s.MaxBlocksPerSyncCycle > 0 && s.MaxBlocksPerSyncCycle <= s.MaxMemSyncCycleSize var tx kv.RwTx if canRunCycleInOneTransaction { diff --git a/cmd/harmony/config.go b/cmd/harmony/config.go index 30c72c2e25..5a41f22da8 100644 --- a/cmd/harmony/config.go +++ b/cmd/harmony/config.go @@ -3,7 +3,6 @@ package main import ( "errors" "fmt" - "io/ioutil" "os" "strings" "time" @@ -221,7 +220,7 @@ func promptConfigUpdate() bool { } func loadHarmonyConfig(file string) (harmonyconfig.HarmonyConfig, string, error) { - b, err := ioutil.ReadFile(file) + b, err := os.ReadFile(file) if err != nil { return harmonyconfig.HarmonyConfig{}, "", err } @@ -234,12 +233,12 @@ func loadHarmonyConfig(file string) (harmonyconfig.HarmonyConfig, string, error) } func updateConfigFile(file string) error { - configBytes, err := ioutil.ReadFile(file) + configBytes, err := os.ReadFile(file) if err != nil { return err } backup := fmt.Sprintf("%s.backup", file) - if err := ioutil.WriteFile(backup, configBytes, 0664); err != nil { + if err := os.WriteFile(backup, configBytes, 0664); err != nil { return err } fmt.Printf("Original config backed up to %s\n", fmt.Sprintf("%s.backup", file)) @@ -259,5 +258,5 @@ func writeHarmonyConfigToFile(config harmonyconfig.HarmonyConfig, file string) e if err != nil { return err } - return ioutil.WriteFile(file, b, 0644) + return os.WriteFile(file, b, 0644) } diff --git a/cmd/harmony/config_test.go b/cmd/harmony/config_test.go index d19f5d9858..2711041de8 100644 --- a/cmd/harmony/config_test.go +++ b/cmd/harmony/config_test.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "io/ioutil" "os" "path/filepath" "reflect" @@ -120,7 +119,7 @@ Version = "1.0.4" os.RemoveAll(testDir) os.MkdirAll(testDir, 0777) file := filepath.Join(testDir, "test.config") - err := ioutil.WriteFile(file, []byte(testConfig), 0644) + err := os.WriteFile(file, []byte(testConfig), 0644) if err != nil { t.Fatal(err) } diff --git a/cmd/harmony/default.go b/cmd/harmony/default.go index 4cc20cfdf4..986a2f7f66 100644 --- a/cmd/harmony/default.go +++ b/cmd/harmony/default.go @@ -65,6 +65,7 @@ var defaultConfig = harmonyconfig.HarmonyConfig{ RateLimterEnabled: true, RequestsPerSecond: nodeconfig.DefaultRPCRateLimit, EvmCallTimeout: nodeconfig.DefaultEvmCallTimeout, + PreimagesEnabled: false, }, BLSKeys: harmonyconfig.BlsConfig{ KeyDir: "./.hmy/blskeys", @@ -149,6 +150,13 @@ var defaultRevertConfig = harmonyconfig.RevertConfig{ RevertTo: 0, } +var defaultPreimageConfig = harmonyconfig.PreimageConfig{ + ImportFrom: "", + ExportTo: "", + GenerateStart: 0, + GenerateEnd: 0, +} + var defaultLogContext = harmonyconfig.LogContext{ IP: "127.0.0.1", Port: 9000, @@ -232,7 +240,7 @@ var ( Downloader: true, StagedSync: false, StagedSyncCfg: defaultStagedSyncConfig, - Concurrency: 4, + Concurrency: 2, MinPeers: 2, InitStreams: 2, MaxAdvertiseWaitTime: 2, //minutes @@ -291,6 +299,11 @@ func getDefaultRevertConfigCopy() harmonyconfig.RevertConfig { return config } +func getDefaultPreimageConfigCopy() harmonyconfig.PreimageConfig { + config := defaultPreimageConfig + return config +} + func getDefaultLogContextCopy() harmonyconfig.LogContext { config := defaultLogContext return config diff --git a/cmd/harmony/dumpdb.go b/cmd/harmony/dumpdb.go index 5803359e5b..fd506ee05b 100644 --- a/cmd/harmony/dumpdb.go +++ b/cmd/harmony/dumpdb.go @@ -103,7 +103,7 @@ const ( STATEDB_CACHE_SIZE = 64 // size in MB LEVELDB_CACHE_SIZE = 256 LEVELDB_HANDLES = 1024 - LRU_CACHE_SIZE = 64 * 1024 * 1024 + LRU_CACHE_SIZE = 512 ) const ( @@ -156,6 +156,7 @@ func (db *KakashiDB) copyKV(key, value []byte) { db.toDBBatch.Put(key, value) snapdbInfo.DumpedSize += uint64(len(key) + len(value)) dumpPrint("copyKV", false) + db.flush() } func (db *KakashiDB) flush() { diff --git a/cmd/harmony/flags.go b/cmd/harmony/flags.go index acf53d8b3a..46a1decb06 100644 --- a/cmd/harmony/flags.go +++ b/cmd/harmony/flags.go @@ -90,6 +90,7 @@ var ( rpcOptFlags = []cli.Flag{ rpcDebugEnabledFlag, + rpcPreimagesEnabledFlag, rpcEthRPCsEnabledFlag, rpcStakingRPCsEnabledFlag, rpcLegacyRPCsEnabledFlag, @@ -205,6 +206,13 @@ var ( revertBeforeFlag, } + preimageFlags = []cli.Flag{ + preimageImportFlag, + preimageExportFlag, + preimageGenerateStartFlag, + preimageGenerateEndFlag, + } + legacyRevertFlags = []cli.Flag{ legacyRevertBeaconFlag, legacyRevertBeforeFlag, @@ -370,6 +378,7 @@ func getRootFlags() []cli.Flag { flags = append(flags, sysFlags...) flags = append(flags, devnetFlags...) flags = append(flags, revertFlags...) + flags = append(flags, preimageFlags...) flags = append(flags, legacyMiscFlags...) flags = append(flags, prometheusFlags...) flags = append(flags, syncFlags...) @@ -827,6 +836,12 @@ var ( DefValue: defaultConfig.RPCOpt.DebugEnabled, Hidden: true, } + rpcPreimagesEnabledFlag = cli.BoolFlag{ + Name: "rpc.preimages", + Usage: "enable preimages export api", + DefValue: defaultConfig.RPCOpt.PreimagesEnabled, + Hidden: true, // not for end users + } rpcEthRPCsEnabledFlag = cli.BoolFlag{ Name: "rpc.eth", @@ -879,6 +894,9 @@ func applyRPCOptFlags(cmd *cobra.Command, config *harmonyconfig.HarmonyConfig) { if cli.IsFlagChanged(cmd, rpcDebugEnabledFlag) { config.RPCOpt.DebugEnabled = cli.GetBoolFlagValue(cmd, rpcDebugEnabledFlag) } + if cli.IsFlagChanged(cmd, rpcPreimagesEnabledFlag) { + config.RPCOpt.PreimagesEnabled = cli.GetBoolFlagValue(cmd, rpcPreimagesEnabledFlag) + } if cli.IsFlagChanged(cmd, rpcEthRPCsEnabledFlag) { config.RPCOpt.EthRPCsEnabled = cli.GetBoolFlagValue(cmd, rpcEthRPCsEnabledFlag) } @@ -1656,6 +1674,52 @@ func applyRevertFlags(cmd *cobra.Command, config *harmonyconfig.HarmonyConfig) { } } +var ( + preimageImportFlag = cli.StringFlag{ + Name: "preimage.import", + Usage: "Import pre-images from CSV file", + Hidden: true, + DefValue: defaultPreimageConfig.ImportFrom, + } + preimageExportFlag = cli.StringFlag{ + Name: "preimage.export", + Usage: "Export pre-images to CSV file", + Hidden: true, + DefValue: defaultPreimageConfig.ExportTo, + } + preimageGenerateStartFlag = cli.Uint64Flag{ + Name: "preimage.start", + Usage: "The block number from which pre-images are to be generated", + Hidden: true, + DefValue: defaultPreimageConfig.GenerateStart, + } + preimageGenerateEndFlag = cli.Uint64Flag{ + Name: "preimage.end", + Usage: "The block number upto and including which pre-images are to be generated", + Hidden: true, + DefValue: defaultPreimageConfig.GenerateEnd, + } +) + +func applyPreimageFlags(cmd *cobra.Command, config *harmonyconfig.HarmonyConfig) { + if cli.HasFlagsChanged(cmd, preimageFlags) { + cfg := getDefaultPreimageConfigCopy() + config.Preimage = &cfg + } + if cli.IsFlagChanged(cmd, preimageImportFlag) { + config.Preimage.ImportFrom = cli.GetStringFlagValue(cmd, preimageImportFlag) + } + if cli.IsFlagChanged(cmd, preimageExportFlag) { + config.Preimage.ExportTo = cli.GetStringFlagValue(cmd, preimageExportFlag) + } + if cli.IsFlagChanged(cmd, preimageGenerateStartFlag) { + config.Preimage.GenerateStart = cli.GetUint64FlagValue(cmd, preimageGenerateStartFlag) + } + if cli.IsFlagChanged(cmd, preimageGenerateEndFlag) { + config.Preimage.GenerateEnd = cli.GetUint64FlagValue(cmd, preimageGenerateEndFlag) + } +} + var ( legacyPortFlag = cli.IntFlag{ Name: "port", diff --git a/cmd/harmony/flags_test.go b/cmd/harmony/flags_test.go index 054c804215..bea0e0eabe 100644 --- a/cmd/harmony/flags_test.go +++ b/cmd/harmony/flags_test.go @@ -92,6 +92,7 @@ func TestHarmonyFlags(t *testing.T) { RateLimterEnabled: true, RequestsPerSecond: 1000, EvmCallTimeout: defaultConfig.RPCOpt.EvmCallTimeout, + PreimagesEnabled: defaultConfig.RPCOpt.PreimagesEnabled, }, WS: harmonyconfig.WsConfig{ Enabled: true, @@ -752,6 +753,7 @@ func TestRPCOptFlags(t *testing.T) { RateLimterEnabled: true, RequestsPerSecond: 1000, EvmCallTimeout: defaultConfig.RPCOpt.EvmCallTimeout, + PreimagesEnabled: defaultConfig.RPCOpt.PreimagesEnabled, }, }, @@ -766,6 +768,7 @@ func TestRPCOptFlags(t *testing.T) { RateLimterEnabled: true, RequestsPerSecond: 1000, EvmCallTimeout: defaultConfig.RPCOpt.EvmCallTimeout, + PreimagesEnabled: defaultConfig.RPCOpt.PreimagesEnabled, }, }, @@ -780,6 +783,7 @@ func TestRPCOptFlags(t *testing.T) { RateLimterEnabled: true, RequestsPerSecond: 1000, EvmCallTimeout: defaultConfig.RPCOpt.EvmCallTimeout, + PreimagesEnabled: defaultConfig.RPCOpt.PreimagesEnabled, }, }, @@ -794,6 +798,7 @@ func TestRPCOptFlags(t *testing.T) { RateLimterEnabled: true, RequestsPerSecond: 1000, EvmCallTimeout: defaultConfig.RPCOpt.EvmCallTimeout, + PreimagesEnabled: defaultConfig.RPCOpt.PreimagesEnabled, }, }, @@ -808,6 +813,7 @@ func TestRPCOptFlags(t *testing.T) { RateLimterEnabled: true, RequestsPerSecond: 1000, EvmCallTimeout: defaultConfig.RPCOpt.EvmCallTimeout, + PreimagesEnabled: defaultConfig.RPCOpt.PreimagesEnabled, }, }, @@ -822,6 +828,7 @@ func TestRPCOptFlags(t *testing.T) { RateLimterEnabled: true, RequestsPerSecond: 1000, EvmCallTimeout: defaultConfig.RPCOpt.EvmCallTimeout, + PreimagesEnabled: defaultConfig.RPCOpt.PreimagesEnabled, }, }, @@ -836,6 +843,7 @@ func TestRPCOptFlags(t *testing.T) { RateLimterEnabled: true, RequestsPerSecond: 2000, EvmCallTimeout: defaultConfig.RPCOpt.EvmCallTimeout, + PreimagesEnabled: defaultConfig.RPCOpt.PreimagesEnabled, }, }, @@ -850,6 +858,7 @@ func TestRPCOptFlags(t *testing.T) { RateLimterEnabled: false, RequestsPerSecond: 2000, EvmCallTimeout: defaultConfig.RPCOpt.EvmCallTimeout, + PreimagesEnabled: defaultConfig.RPCOpt.PreimagesEnabled, }, }, @@ -864,6 +873,22 @@ func TestRPCOptFlags(t *testing.T) { RateLimterEnabled: true, RequestsPerSecond: 1000, EvmCallTimeout: "10s", + PreimagesEnabled: defaultConfig.RPCOpt.PreimagesEnabled, + }, + }, + + { + args: []string{"--rpc.preimages"}, + expConfig: harmonyconfig.RpcOptConfig{ + DebugEnabled: false, + EthRPCsEnabled: true, + StakingRPCsEnabled: true, + LegacyRPCsEnabled: true, + RpcFilterFile: "./.hmy/rpc_filter.txt", + RateLimterEnabled: true, + RequestsPerSecond: 1000, + EvmCallTimeout: defaultConfig.RPCOpt.EvmCallTimeout, + PreimagesEnabled: true, }, }, } @@ -1509,6 +1534,70 @@ func TestRevertFlags(t *testing.T) { } } +func TestPreimageFlags(t *testing.T) { + tests := []struct { + args []string + expConfig *harmonyconfig.PreimageConfig + expErr error + }{ + { + args: []string{}, + expConfig: nil, + }, + { + args: []string{"--preimage.import", "/path/to/source.csv"}, + expConfig: &harmonyconfig.PreimageConfig{ + ImportFrom: "/path/to/source.csv", + ExportTo: defaultPreimageConfig.ExportTo, + GenerateStart: defaultPreimageConfig.GenerateStart, + GenerateEnd: defaultPreimageConfig.GenerateEnd, + }, + }, + { + args: []string{"--preimage.export", "/path/to/destination.csv"}, + expConfig: &harmonyconfig.PreimageConfig{ + ImportFrom: defaultPreimageConfig.ImportFrom, + ExportTo: "/path/to/destination.csv", + GenerateStart: defaultPreimageConfig.GenerateStart, + GenerateEnd: defaultPreimageConfig.GenerateEnd, + }, + }, + { + args: []string{"--preimage.start", "1"}, + expConfig: &harmonyconfig.PreimageConfig{ + ImportFrom: defaultPreimageConfig.ImportFrom, + ExportTo: defaultPreimageConfig.ExportTo, + GenerateStart: 1, + GenerateEnd: defaultPreimageConfig.GenerateEnd, + }, + }, + { + args: []string{"--preimage.end", "2"}, + expConfig: &harmonyconfig.PreimageConfig{ + ImportFrom: defaultPreimageConfig.ImportFrom, + ExportTo: defaultPreimageConfig.ExportTo, + GenerateStart: defaultPreimageConfig.GenerateStart, + GenerateEnd: 2, + }, + }, + } + for i, test := range tests { + ts := newFlagTestSuite(t, preimageFlags, applyPreimageFlags) + hc, err := ts.run(test.args) + + if assErr := assertError(err, test.expErr); assErr != nil { + t.Fatalf("Test %v: %v", i, assErr) + } + if err != nil || test.expErr != nil { + continue + } + if !reflect.DeepEqual(hc.Preimage, test.expConfig) { + t.Errorf("Test %v:\n\t%+v\n\t%+v", i, hc.Preimage, test.expConfig) + } + ts.tearDown() + } +} + func TestDNSSyncFlags(t *testing.T) { tests := []struct { args []string diff --git a/cmd/harmony/main.go b/cmd/harmony/main.go index 16f985beac..9fc89d45da 100644 --- a/cmd/harmony/main.go +++ b/cmd/harmony/main.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "io/ioutil" "math/big" "math/rand" _ "net/http/pprof" @@ -246,6 +245,7 @@ func applyRootFlags(cmd *cobra.Command, config *harmonyconfig.HarmonyConfig) { applySysFlags(cmd, config) applyDevnetFlags(cmd, config) applyRevertFlags(cmd, config) + applyPreimageFlags(cmd, config) applyPrometheusFlags(cmd, config) applySyncFlags(cmd, config) applyShardDataFlags(cmd, config) @@ -268,6 +268,29 @@ func setupNodeLog(config harmonyconfig.HarmonyConfig) { } } +func revert(chain core.BlockChain, hc harmonyconfig.HarmonyConfig) { + curNum := chain.CurrentBlock().NumberU64() + if curNum < uint64(hc.Revert.RevertBefore) && curNum >= uint64(hc.Revert.RevertTo) { + // Remove invalid blocks + for chain.CurrentBlock().NumberU64() >= uint64(hc.Revert.RevertTo) { + curBlock := chain.CurrentBlock() + rollbacks := []ethCommon.Hash{curBlock.Hash()} + if err := chain.Rollback(rollbacks); err != nil { + fmt.Printf("Revert failed: %v\n", err) + os.Exit(1) + } + lastSig := curBlock.Header().LastCommitSignature() + sigAndBitMap := append(lastSig[:], curBlock.Header().LastCommitBitmap()...) + chain.WriteCommitSig(curBlock.NumberU64()-1, sigAndBitMap) + } + fmt.Printf("Revert finished. Current block: %v\n", chain.CurrentBlock().NumberU64()) + utils.Logger().Warn(). + Uint64("Current Block", chain.CurrentBlock().NumberU64()). + Msg("Revert finished.") + os.Exit(1) + } +} + func setupNodeAndRun(hc harmonyconfig.HarmonyConfig) { var err error @@ -353,26 +376,58 @@ func setupNodeAndRun(hc harmonyconfig.HarmonyConfig) { if hc.Revert.RevertBeacon { chain = currentNode.Beaconchain() } - curNum := chain.CurrentBlock().NumberU64() - if curNum < uint64(hc.Revert.RevertBefore) && curNum >= uint64(hc.Revert.RevertTo) { - // Remove invalid blocks - for chain.CurrentBlock().NumberU64() >= uint64(hc.Revert.RevertTo) { - curBlock := chain.CurrentBlock() - rollbacks := []ethCommon.Hash{curBlock.Hash()} - if err := chain.Rollback(rollbacks); err != nil { - fmt.Printf("Revert failed: %v\n", err) - os.Exit(1) - } - lastSig := curBlock.Header().LastCommitSignature() - sigAndBitMap := append(lastSig[:], curBlock.Header().LastCommitBitmap()...) - chain.WriteCommitSig(curBlock.NumberU64()-1, sigAndBitMap) + revert(chain, hc) + } + + //// code to handle pre-image export, import and generation + if hc.Preimage != nil { + if hc.Preimage.ImportFrom != "" { + if err := core.ImportPreimages( + currentNode.Blockchain(), + hc.Preimage.ImportFrom, + ); err != nil { + fmt.Println("Error importing", err) + os.Exit(1) } - fmt.Printf("Revert finished. Current block: %v\n", chain.CurrentBlock().NumberU64()) - utils.Logger().Warn(). - Uint64("Current Block", chain.CurrentBlock().NumberU64()). - Msg("Revert finished.") - os.Exit(1) + os.Exit(0) + } else if exportPath := hc.Preimage.ExportTo; exportPath != "" { + if err := core.ExportPreimages( + currentNode.Blockchain(), + exportPath, + ); err != nil { + fmt.Println("Error exporting", err) + os.Exit(1) + } + os.Exit(0) + // both must be set + } else if hc.Preimage.GenerateStart > 0 { + chain := currentNode.Blockchain() + end := hc.Preimage.GenerateEnd + current := chain.CurrentBlock().NumberU64() + if end > current { + fmt.Printf( + "Cropping generate endpoint from %d to %d\n", + end, current, + ) + end = current + } + + if end == 0 { + end = current + } + + fmt.Println("Starting generation") + if err := core.GeneratePreimages( + chain, + hc.Preimage.GenerateStart, end, + ); err != nil { + fmt.Println("Error generating", err) + os.Exit(1) + } + fmt.Println("Generation successful") + os.Exit(0) } + os.Exit(0) } startMsg := "==== New Harmony Node ====" @@ -452,6 +507,11 @@ func setupNodeAndRun(hc harmonyconfig.HarmonyConfig) { Msg("Start Rosetta failed") } + go core.WritePreimagesMetricsIntoPrometheus( + currentNode.Blockchain(), + currentNode.Consensus.UpdatePreimageGenerationMetrics, + ) + go listenOSSigAndShutDown(currentNode) if !hc.General.IsOffline { @@ -500,7 +560,13 @@ func nodeconfigSetShardSchedule(config harmonyconfig.HarmonyConfig) { } devnetConfig, err := shardingconfig.NewInstance( - uint32(dnConfig.NumShards), dnConfig.ShardSize, dnConfig.HmyNodeSize, dnConfig.SlotsLimit, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccounts, shardingconfig.Allowlist{}, nil, nil, shardingconfig.VLBPE) + uint32(dnConfig.NumShards), dnConfig.ShardSize, + dnConfig.HmyNodeSize, dnConfig.SlotsLimit, + numeric.OneDec(), genesis.HarmonyAccounts, + genesis.FoundationalNodeAccounts, shardingconfig.Allowlist{}, + nil, numeric.ZeroDec(), ethCommon.Address{}, + nil, shardingconfig.VLBPE, + ) if err != nil { _, _ = fmt.Fprintf(os.Stderr, "ERROR invalid devnet sharding config: %s", err) @@ -665,31 +731,7 @@ func createGlobalConfig(hc harmonyconfig.HarmonyConfig) (*nodeconfig.ConfigType, return nodeConfig, nil } -func setupConsensusAndNode(hc harmonyconfig.HarmonyConfig, nodeConfig *nodeconfig.ConfigType, registry *registry.Registry) *node.Node { - // Parse minPeers from harmonyconfig.HarmonyConfig - var minPeers int - var aggregateSig bool - if hc.Consensus != nil { - minPeers = hc.Consensus.MinPeers - aggregateSig = hc.Consensus.AggregateSig - } else { - minPeers = defaultConsensusConfig.MinPeers - aggregateSig = defaultConsensusConfig.AggregateSig - } - - blacklist, err := setupBlacklist(hc) - if err != nil { - utils.Logger().Warn().Msgf("Blacklist setup error: %s", err.Error()) - } - allowedTxs, err := setupAllowedTxs(hc) - if err != nil { - utils.Logger().Warn().Msgf("AllowedTxs setup error: %s", err.Error()) - } - - localAccounts, err := setupLocalAccounts(hc, blacklist) - if err != nil { - utils.Logger().Warn().Msgf("local accounts setup error: %s", err.Error()) - } +func setupChain(hc harmonyconfig.HarmonyConfig, nodeConfig *nodeconfig.ConfigType, registry *registry.Registry) *registry.Registry { // Current node. var chainDBFactory shardchain.DBFactory @@ -708,6 +750,7 @@ func setupConsensusAndNode(hc harmonyconfig.HarmonyConfig, nodeConfig *nodeconfi } engine := chain.NewEngine() + registry.SetEngine(engine) chainConfig := nodeConfig.GetNetworkType().ChainConfig() collection := shardchain.NewCollection( @@ -718,6 +761,7 @@ func setupConsensusAndNode(hc harmonyconfig.HarmonyConfig, nodeConfig *nodeconfi collection.DisableCache(shardID) } } + registry.SetShardChainCollection(collection) var blockchain core.BlockChain @@ -731,17 +775,48 @@ func setupConsensusAndNode(hc harmonyconfig.HarmonyConfig, nodeConfig *nodeconfi registry.SetBeaconchain(beacon) } - blockchain, err = collection.ShardChain(nodeConfig.ShardID) + blockchain, err := collection.ShardChain(nodeConfig.ShardID) if err != nil { _, _ = fmt.Fprintf(os.Stderr, "Error :%v \n", err) os.Exit(1) } registry.SetBlockchain(blockchain) - registry.SetWebHooks(nodeConfig.WebHooks.Hooks) if registry.GetBeaconchain() == nil { registry.SetBeaconchain(registry.GetBlockchain()) } + return registry +} +func setupConsensusAndNode(hc harmonyconfig.HarmonyConfig, nodeConfig *nodeconfig.ConfigType, registry *registry.Registry) *node.Node { + // Parse minPeers from harmonyconfig.HarmonyConfig + var minPeers int + var aggregateSig bool + if hc.Consensus != nil { + minPeers = hc.Consensus.MinPeers + aggregateSig = hc.Consensus.AggregateSig + } else { + minPeers = defaultConsensusConfig.MinPeers + aggregateSig = defaultConsensusConfig.AggregateSig + } + + blacklist, err := setupBlacklist(hc) + if err != nil { + utils.Logger().Warn().Msgf("Blacklist setup error: %s", err.Error()) + } + allowedTxs, err := setupAllowedTxs(hc) + if err != nil { + utils.Logger().Warn().Msgf("AllowedTxs setup error: %s", err.Error()) + } + localAccounts, err := setupLocalAccounts(hc, blacklist) + if err != nil { + utils.Logger().Warn().Msgf("local accounts setup error: %s", err.Error()) + } + + registry = setupChain(hc, nodeConfig, registry) + if registry.GetShardChainCollection() == nil { + panic("shard chain collection is nil1111111") + } + registry.SetWebHooks(nodeConfig.WebHooks.Hooks) cxPool := core.NewCxPool(core.CxPoolSize) registry.SetCxPool(cxPool) @@ -756,7 +831,7 @@ func setupConsensusAndNode(hc harmonyconfig.HarmonyConfig, nodeConfig *nodeconfi os.Exit(1) } - currentNode := node.New(myHost, currentConsensus, engine, collection, blacklist, allowedTxs, localAccounts, nodeConfig.ArchiveModes(), &hc, registry) + currentNode := node.New(myHost, currentConsensus, blacklist, allowedTxs, localAccounts, &hc, registry) if hc.Legacy != nil && hc.Legacy.TPBroadcastInvalidTxn != nil { currentNode.BroadcastInvalidTx = *hc.Legacy.TPBroadcastInvalidTxn @@ -971,7 +1046,7 @@ func setupBlacklist(hc harmonyconfig.HarmonyConfig) (map[ethCommon.Address]struc rosetta_common.InitRosettaFile(hc.TxPool.RosettaFixFile) utils.Logger().Debug().Msgf("Using blacklist file at `%s`", hc.TxPool.BlacklistFile) - dat, err := ioutil.ReadFile(hc.TxPool.BlacklistFile) + dat, err := os.ReadFile(hc.TxPool.BlacklistFile) if err != nil { return nil, err } @@ -1022,7 +1097,7 @@ func parseAllowedTxs(data []byte) (map[ethCommon.Address]core.AllowedTxData, err func setupAllowedTxs(hc harmonyconfig.HarmonyConfig) (map[ethCommon.Address]core.AllowedTxData, error) { utils.Logger().Debug().Msgf("Using AllowedTxs file at `%s`", hc.TxPool.AllowedTxsFile) - data, err := ioutil.ReadFile(hc.TxPool.AllowedTxsFile) + data, err := os.ReadFile(hc.TxPool.AllowedTxsFile) if err != nil { return nil, err } @@ -1034,7 +1109,7 @@ func setupLocalAccounts(hc harmonyconfig.HarmonyConfig, blacklist map[ethCommon. // check if file exist var fileData string if _, err := os.Stat(file); err == nil { - b, err := ioutil.ReadFile(file) + b, err := os.ReadFile(file) if err != nil { return nil, err } @@ -1050,22 +1125,23 @@ func setupLocalAccounts(hc harmonyconfig.HarmonyConfig, blacklist map[ethCommon. localAccounts := make(map[ethCommon.Address]struct{}) lines := strings.Split(fileData, "\n") for _, line := range lines { - if len(line) != 0 { // the file may have trailing empty string line - trimmedLine := strings.TrimSpace(line) - if strings.HasPrefix(trimmedLine, "#") { //check the line is not commented - continue - } - addr, err := common.Bech32ToAddress(trimmedLine) - if err != nil { - return nil, err - } - // skip the blacklisted addresses - if _, exists := blacklist[addr]; exists { - utils.Logger().Warn().Msgf("local account with address %s is blacklisted", addr.String()) - continue - } - localAccounts[addr] = struct{}{} + if len(line) == 0 { // the file may have trailing empty string line + continue + } + addrPart := strings.TrimSpace(strings.Split(string(line), "#")[0]) + if len(addrPart) == 0 { // if the line is commented by # + continue + } + addr, err := common.ParseAddr(addrPart) + if err != nil { + return nil, err + } + // skip the blacklisted addresses + if _, exists := blacklist[addr]; exists { + utils.Logger().Warn().Msgf("local account with address %s is blacklisted", addr.String()) + continue } + localAccounts[addr] = struct{}{} } uniqueAddresses := make([]ethCommon.Address, 0, len(localAccounts)) for addr := range localAccounts { diff --git a/consensus/consensus_service.go b/consensus/consensus_service.go index 3ebfa5e307..23f0b47519 100644 --- a/consensus/consensus_service.go +++ b/consensus/consensus_service.go @@ -95,7 +95,7 @@ func (consensus *Consensus) updatePublicKeys(pubKeys, allowlist []bls_cosi.Publi if len(allKeys) != 0 { consensus.LeaderPubKey = &allKeys[0] consensus.getLogger().Info(). - Str("info", consensus.LeaderPubKey.Bytes.Hex()).Msg("My Leader") + Str("info", consensus.LeaderPubKey.Bytes.Hex()).Msg("Setting leader as first validator, because provided new keys") } else { consensus.getLogger().Error(). Msg("[UpdatePublicKeys] Participants is empty") @@ -663,6 +663,12 @@ func (consensus *Consensus) getLogger() *zerolog.Logger { func VerifyNewBlock(hooks *webhooks.Hooks, blockChain core.BlockChain, beaconChain core.BlockChain) func(*types.Block) error { return func(newBlock *types.Block) error { if err := blockChain.ValidateNewBlock(newBlock, beaconChain); err != nil { + switch { + case errors.Is(err, core.ErrKnownBlock): + return nil + default: + } + if hooks := hooks; hooks != nil { if p := hooks.ProtocolIssues; p != nil { url := p.OnCannotCommit @@ -680,7 +686,7 @@ func VerifyNewBlock(hooks *webhooks.Hooks, blockChain core.BlockChain, beaconCha Int("numStakingTx", len(newBlock.StakingTransactions())). Err(err). Msgf("[VerifyNewBlock] Cannot Verify New Block!!!, blockHeight %d, myHeight %d", newBlock.NumberU64(), blockChain.CurrentHeader().NumberU64()) - return errors.Errorf( + return errors.WithMessagef(err, "[VerifyNewBlock] Cannot Verify New Block!!! block-hash %s txn-count %d", newBlock.Hash().Hex(), len(newBlock.Transactions()), diff --git a/consensus/consensus_service_test.go b/consensus/consensus_service_test.go index 00b8bd3462..b3e2e73ac9 100644 --- a/consensus/consensus_service_test.go +++ b/consensus/consensus_service_test.go @@ -5,6 +5,8 @@ import ( "github.com/harmony-one/harmony/crypto/bls" "github.com/harmony-one/harmony/internal/registry" + "github.com/pkg/errors" + "github.com/stretchr/testify/require" msg_pb "github.com/harmony-one/harmony/api/proto/message" "github.com/harmony-one/harmony/consensus/quorum" @@ -73,3 +75,18 @@ func TestSetViewID(t *testing.T) { t.Errorf("Cannot set consensus ID. Got: %v, Expected: %v", consensus.GetCurBlockViewID(), height) } } + +func TestErrors(t *testing.T) { + e1 := errors.New("e1") + require.True(t, errors.Is(e1, e1)) + + t.Run("wrap", func(t *testing.T) { + e2 := errors.Wrap(e1, "e2") + require.True(t, errors.Is(e2, e1)) + }) + + t.Run("withMessage", func(t *testing.T) { + e2 := errors.WithMessage(e1, "e2") + require.True(t, errors.Is(e2, e1)) + }) +} diff --git a/consensus/consensus_v2.go b/consensus/consensus_v2.go index 3627f0b658..bc0d185bdf 100644 --- a/consensus/consensus_v2.go +++ b/consensus/consensus_v2.go @@ -11,6 +11,7 @@ import ( "github.com/ethereum/go-ethereum/common" bls2 "github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/harmony/consensus/signature" + "github.com/harmony-one/harmony/core" nodeconfig "github.com/harmony-one/harmony/internal/configs/node" "github.com/harmony-one/harmony/internal/utils" "github.com/rs/zerolog" @@ -31,7 +32,6 @@ import ( var ( errSenderPubKeyNotLeader = errors.New("sender pubkey doesn't match leader") errVerifyMessageSignature = errors.New("verify message signature failed") - errParsingFBFTMessage = errors.New("failed parsing FBFT message") ) // timeout constant @@ -578,8 +578,13 @@ func (consensus *Consensus) preCommitAndPropose(blk *types.Block) error { } if _, err := consensus.Blockchain().InsertChain([]*types.Block{blk}, !consensus.FBFTLog().IsBlockVerified(blk.Hash())); err != nil { - consensus.getLogger().Error().Err(err).Msg("[preCommitAndPropose] Failed to add block to chain") - return + switch { + case errors.Is(err, core.ErrKnownBlock): + consensus.getLogger().Info().Msg("[preCommitAndPropose] Block already known") + default: + consensus.getLogger().Error().Err(err).Msg("[preCommitAndPropose] Failed to add block to chain") + return + } } consensus.getLogger().Info().Msg("[preCommitAndPropose] Start consensus timer") @@ -693,7 +698,7 @@ func (consensus *Consensus) rotateLeader(epoch *big.Int) { prev = consensus.getLeaderPubKey() leader = consensus.getLeaderPubKey() ) - utils.Logger().Info().Msgf("[Rotating leader] epoch: %v rotation:%v external rotation %v", epoch.Uint64(), bc.Config().IsLeaderRotation(epoch), bc.Config().IsLeaderRotationExternalValidatorsAllowed(epoch, consensus.ShardID)) + utils.Logger().Info().Msgf("[Rotating leader] epoch: %v rotation:%v external rotation %v", epoch.Uint64(), bc.Config().IsLeaderRotationInternalValidators(epoch), bc.Config().IsLeaderRotationExternalValidatorsAllowed(epoch)) ss, err := bc.ReadShardState(epoch) if err != nil { utils.Logger().Error().Err(err).Msg("Failed to read shard state") @@ -721,24 +726,17 @@ func (consensus *Consensus) rotateLeader(epoch *big.Int) { // mine no less than 3 blocks in a row numBlocksProducedByLeader = minimumBlocksForLeaderInRow } - type stored struct { - pub []byte - epoch uint64 - count uint64 - shifts uint64 // count how much changes validator per epoch - } - var s stored - s.pub, s.epoch, s.count, s.shifts, _ = bc.LeaderRotationMeta() - if !bytes.Equal(leader.Bytes[:], s.pub) { + s := bc.LeaderRotationMeta() + if !bytes.Equal(leader.Bytes[:], s.Pub) { // Another leader. return } - // if it is the first validator which produce blocks, then it should produce `rest` blocks too. - if s.shifts == 0 { + // If it is the first validator producing blocks, it should also produce the remaining 'rest' of the blocks. + if s.Shifts == 0 { numBlocksProducedByLeader += rest } - if s.count < numBlocksProducedByLeader { - // Not enough blocks produced by the leader. + if s.Count < numBlocksProducedByLeader { + // Not enough blocks produced by the leader, continue producing by the same leader. return } // Passed all checks, we can change leader. @@ -748,8 +746,8 @@ func (consensus *Consensus) rotateLeader(epoch *big.Int) { wasFound bool next *bls.PublicKeyWrapper ) - if bc.Config().IsLeaderRotationExternalValidatorsAllowed(epoch, consensus.ShardID) { - wasFound, next = consensus.Decider.NthNext(leader, 1) + if bc.Config().IsLeaderRotationExternalValidatorsAllowed(epoch) { + wasFound, next = consensus.Decider.NthNextValidator(committee.Slots, leader, 1) } else { wasFound, next = consensus.Decider.NthNextHmy(shard.Schedule.InstanceForEpoch(epoch), leader, 1) } @@ -778,7 +776,7 @@ func (consensus *Consensus) setupForNewConsensus(blk *types.Block, committedMsg } else { epoch = blk.Epoch() } - if consensus.Blockchain().Config().IsLeaderRotation(epoch) { + if consensus.Blockchain().Config().IsLeaderRotationInternalValidators(epoch) { consensus.rotateLeader(epoch) } diff --git a/consensus/metrics.go b/consensus/metrics.go index 81ed6343c1..fa460f4b7e 100644 --- a/consensus/metrics.go +++ b/consensus/metrics.go @@ -9,6 +9,52 @@ import ( ) var ( + preimageStartGauge = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Namespace: "hmy", + Subsystem: "blockchain", + Name: "preimage_start", + Help: "the first block for which pre-image generation ran locally", + ConstLabels: map[string]string{}, + }, + []string{ + "shard", + }, + ) + preimageEndGauge = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Namespace: "hmy", + Subsystem: "blockchain", + Name: "preimage_end", + Help: "the last block for which pre-image generation ran locally", + }, + []string{ + "shard", + }, + ) + verifiedPreimagesGauge = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Namespace: "hmy", + Subsystem: "blockchain", + Name: "verified_preimages", + Help: "the number of verified preimages", + }, + []string{ + "shard", + }, + ) + lastPreimageImportGauge = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Namespace: "hmy", + Subsystem: "blockchain", + Name: "last_preimage_import", + Help: "the last known block for which preimages were imported", + }, + []string{ + "shard", + }, + ) + // consensusCounterVec is used to keep track of consensus reached consensusCounterVec = prometheus.NewCounterVec( prometheus.CounterOpts{ @@ -103,6 +149,26 @@ func (consensus *Consensus) UpdateLeaderMetrics(numCommits float64, blockNum flo consensusCounterVec.With(prometheus.Labels{"consensus": "num_commits"}).Add(numCommits) consensusGaugeVec.With(prometheus.Labels{"consensus": "num_commits"}).Set(numCommits) } +func (consensus *Consensus) UpdatePreimageGenerationMetrics( + preimageStart uint64, + preimageEnd uint64, + lastPreimageImport uint64, + verifiedAddresses uint64, + shard uint32, +) { + if lastPreimageImport > 0 { + lastPreimageImportGauge.With(prometheus.Labels{"shard": fmt.Sprintf("%d", shard)}).Set(float64(lastPreimageImport)) + } + if preimageStart > 0 { + preimageStartGauge.With(prometheus.Labels{"shard": fmt.Sprintf("%d", shard)}).Set(float64(preimageStart)) + } + if preimageEnd > 0 { + preimageEndGauge.With(prometheus.Labels{"shard": fmt.Sprintf("%d", shard)}).Set(float64(preimageEnd)) + } + if verifiedAddresses > 0 { + verifiedPreimagesGauge.With(prometheus.Labels{"shard": fmt.Sprintf("%d", shard)}).Set(float64(verifiedAddresses)) + } +} // AddPubkeyMetrics add the list of blskeys to prometheus metrics func (consensus *Consensus) AddPubkeyMetrics() { @@ -122,6 +188,10 @@ func initMetrics() { consensusGaugeVec, consensusPubkeyVec, consensusFinalityHistogram, + lastPreimageImportGauge, + preimageEndGauge, + preimageStartGauge, + verifiedPreimagesGauge, ) }) } diff --git a/consensus/quorum/quorom_test.go b/consensus/quorum/quorom_test.go index 09ec1779b8..0b5c265b14 100644 --- a/consensus/quorum/quorom_test.go +++ b/consensus/quorum/quorom_test.go @@ -11,6 +11,7 @@ import ( "github.com/harmony-one/harmony/numeric" "github.com/harmony-one/harmony/shard" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/ethereum/go-ethereum/common" "github.com/harmony-one/harmony/crypto/bls" @@ -565,7 +566,7 @@ func TestNthNextHmyExt(test *testing.T) { allLeaders := append(blsKeys[:numHmyNodes], allowlistLeaders...) decider := NewDecider(SuperMajorityVote, shard.BeaconChainShardID) - fakeInstance := shardingconfig.MustNewInstance(2, 20, numHmyNodes, 0, numeric.OneDec(), nil, nil, allowlist, nil, nil, 0) + fakeInstance := shardingconfig.MustNewInstance(2, 20, numHmyNodes, 0, numeric.OneDec(), nil, nil, allowlist, nil, numeric.ZeroDec(), common.Address{}, nil, 0) decider.UpdateParticipants(blsKeys, allowlistLeaders) for i := 0; i < len(allLeaders); i++ { @@ -593,3 +594,33 @@ func TestNthNextHmyExt(test *testing.T) { } } } + +func TestCIdentities_NthNextValidatorHmy(t *testing.T) { + address := []common.Address{ + common.HexToAddress("0x1"), + common.HexToAddress("0x2"), + common.HexToAddress("0x3"), + } + slots := shard.SlotList{} + list := []harmony_bls.PublicKeyWrapper{} + for i := 0; i < 3; i++ { + for j := 0; j < 3; j++ { + blsKey := harmony_bls.RandPrivateKey() + wrapper := harmony_bls.PublicKeyWrapper{Object: blsKey.GetPublicKey()} + wrapper.Bytes.FromLibBLSPublicKey(wrapper.Object) + slots = append(slots, shard.Slot{ + EcdsaAddress: address[i%3], + BLSPublicKey: wrapper.Bytes, + EffectiveStake: nil, + }) + list = append(list, wrapper) + } + } + + c := newCIdentities() + c.UpdateParticipants(list, []bls.PublicKeyWrapper{}) + found, key := c.NthNextValidator(slots, &list[0], 1) + require.Equal(t, true, found) + // because we skip 3 keys of current validator + require.Equal(t, 3, c.IndexOf(key.Bytes)) +} diff --git a/consensus/quorum/quorum.go b/consensus/quorum/quorum.go index aba62fa53f..aaeaab236d 100644 --- a/consensus/quorum/quorum.go +++ b/consensus/quorum/quorum.go @@ -75,7 +75,8 @@ type ParticipantTracker interface { Participants() multibls.PublicKeys IndexOf(bls.SerializedPublicKey) int ParticipantsCount() int64 - NthNext(*bls.PublicKeyWrapper, int) (bool, *bls.PublicKeyWrapper) + // NthNextValidator returns key for next validator. It assumes external validators and leader rotation. + NthNextValidator(slotList shard.SlotList, pubKey *bls.PublicKeyWrapper, next int) (bool, *bls.PublicKeyWrapper) NthNextHmy(shardingconfig.Instance, *bls.PublicKeyWrapper, int) (bool, *bls.PublicKeyWrapper) NthNextHmyExt(shardingconfig.Instance, *bls.PublicKeyWrapper, int) (bool, *bls.PublicKeyWrapper) FirstParticipant(shardingconfig.Instance) *bls.PublicKeyWrapper @@ -217,7 +218,42 @@ func (s *cIdentities) NthNext(pubKey *bls.PublicKeyWrapper, next int) (bool, *bl return found, &s.publicKeys[idx] } -// NthNextHmy return the Nth next pubkey of Harmony nodes, next can be negative number +// NthNextValidator return the Nth next pubkey nodes, but from another validator. +func (s *cIdentities) NthNextValidator(slotList shard.SlotList, pubKey *bls.PublicKeyWrapper, next int) (bool, *bls.PublicKeyWrapper) { + found := false + + if len(s.publicKeys) == 0 { + return false, pubKey + } + if next < 0 { + return false, pubKey + } + + publicToAddress := make(map[bls.SerializedPublicKey]common.Address) + for _, slot := range slotList { + publicToAddress[slot.BLSPublicKey] = slot.EcdsaAddress + } + + idx := s.IndexOf(pubKey.Bytes) + if idx != -1 { + found = true + } else { + utils.Logger().Error(). + Str("key", pubKey.Bytes.Hex()). + Msg("[NthNextHmy] pubKey not found") + } + for { + numNodes := len(s.publicKeys) + idx = (idx + next) % numNodes + if publicToAddress[s.publicKeys[idx].Bytes] == publicToAddress[pubKey.Bytes] { + // same validator, go next + idx++ + continue + } + return found, &s.publicKeys[idx] + } +} + func (s *cIdentities) NthNextHmy(instance shardingconfig.Instance, pubKey *bls.PublicKeyWrapper, next int) (bool, *bls.PublicKeyWrapper) { found := false @@ -410,7 +446,7 @@ func (s *cIdentities) ReadAllBallots(p Phase) []*votepower.Ballot { return ballots } -func newBallotsBackedSignatureReader() *cIdentities { +func newCIdentities() *cIdentities { return &cIdentities{ publicKeys: []bls.PublicKeyWrapper{}, keyIndexMap: map[bls.SerializedPublicKey]int{}, @@ -420,6 +456,10 @@ func newBallotsBackedSignatureReader() *cIdentities { } } +func newBallotsBackedSignatureReader() *cIdentities { + return newCIdentities() +} + // NewDecider .. func NewDecider(p Policy, shardID uint32) Decider { switch p { diff --git a/consensus/view_change.go b/consensus/view_change.go index 3927714e9a..efc1760e84 100644 --- a/consensus/view_change.go +++ b/consensus/view_change.go @@ -149,7 +149,7 @@ func (consensus *Consensus) getNextViewID() (uint64, time.Duration) { // It reads the current leader's pubkey based on the blockchain data and returns // the next leader based on the gap of the viewID of the view change and the last // know view id of the block. -func (consensus *Consensus) getNextLeaderKey(viewID uint64) *bls.PublicKeyWrapper { +func (consensus *Consensus) getNextLeaderKey(viewID uint64, committee *shard.Committee) *bls.PublicKeyWrapper { gap := 1 cur := consensus.getCurBlockViewID() @@ -202,9 +202,10 @@ func (consensus *Consensus) getNextLeaderKey(viewID uint64) *bls.PublicKeyWrappe // FIXME: rotate leader on harmony nodes only before fully externalization var wasFound bool var next *bls.PublicKeyWrapper - if blockchain != nil && blockchain.Config().IsLeaderRotation(epoch) { - if blockchain.Config().IsLeaderRotationExternalValidatorsAllowed(epoch, consensus.ShardID) { - wasFound, next = consensus.Decider.NthNext( + if blockchain != nil && blockchain.Config().IsLeaderRotationInternalValidators(epoch) { + if blockchain.Config().IsLeaderRotationExternalValidatorsAllowed(epoch) { + wasFound, next = consensus.Decider.NthNextValidator( + committee.Slots, lastLeaderPubKey, gap) } else { @@ -249,13 +250,24 @@ func (consensus *Consensus) startViewChange() { consensus.current.SetMode(ViewChanging) nextViewID, duration := consensus.getNextViewID() consensus.setViewChangingID(nextViewID) + epoch := consensus.Blockchain().CurrentHeader().Epoch() + ss, err := consensus.Blockchain().ReadShardState(epoch) + if err != nil { + utils.Logger().Error().Err(err).Msg("Failed to read shard state") + return + } + committee, err := ss.FindCommitteeByID(consensus.ShardID) + if err != nil { + utils.Logger().Error().Err(err).Msg("Failed to find committee") + return + } // TODO: set the Leader PubKey to the next leader for view change // this is dangerous as the leader change is not succeeded yet // we use it this way as in many code we validate the messages // aganist the consensus.LeaderPubKey variable. // Ideally, we shall use another variable to keep track of the // leader pubkey in viewchange mode - consensus.LeaderPubKey = consensus.getNextLeaderKey(nextViewID) + consensus.LeaderPubKey = consensus.getNextLeaderKey(nextViewID, committee) consensus.getLogger().Warn(). Uint64("nextViewID", nextViewID). diff --git a/consensus/view_change_test.go b/consensus/view_change_test.go index 2d149b6b7b..96d8fbc865 100644 --- a/consensus/view_change_test.go +++ b/consensus/view_change_test.go @@ -87,7 +87,7 @@ func TestGetNextLeaderKeyShouldFailForStandardGeneratedConsensus(t *testing.T) { // The below results in: "panic: runtime error: integer divide by zero" // This happens because there's no check for if there are any participants or not in https://github.com/harmony-one/harmony/blob/main/consensus/quorum/quorum.go#L188-L197 - assert.Panics(t, func() { consensus.getNextLeaderKey(uint64(1)) }) + assert.Panics(t, func() { consensus.getNextLeaderKey(uint64(1), nil) }) } func TestGetNextLeaderKeyShouldSucceed(t *testing.T) { @@ -115,7 +115,7 @@ func TestGetNextLeaderKeyShouldSucceed(t *testing.T) { assert.Equal(t, keyCount, consensus.Decider.ParticipantsCount()) consensus.LeaderPubKey = &wrappedBLSKeys[0] - nextKey := consensus.getNextLeaderKey(uint64(1)) + nextKey := consensus.getNextLeaderKey(uint64(1), nil) assert.Equal(t, nextKey, &wrappedBLSKeys[1]) } diff --git a/core/block_validator.go b/core/block_validator.go index fe5ff0f44a..4e097b94d0 100644 --- a/core/block_validator.go +++ b/core/block_validator.go @@ -40,17 +40,13 @@ import ( // // BlockValidator implements validator. type BlockValidator struct { - config *params.ChainConfig // Chain configuration options - bc BlockChain // Canonical blockchain - engine consensus_engine.Engine // Consensus engine used for validating + bc BlockChain // Canonical blockchain } // NewBlockValidator returns a new block validator which is safe for re-use -func NewBlockValidator(config *params.ChainConfig, blockchain BlockChain, engine consensus_engine.Engine) *BlockValidator { +func NewBlockValidator(blockchain BlockChain) *BlockValidator { validator := &BlockValidator{ - config: config, - engine: engine, - bc: blockchain, + bc: blockchain, } return validator } @@ -103,7 +99,7 @@ func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.DB, re return fmt.Errorf("invalid receipt root hash (remote: %x local: %x)", header.ReceiptHash(), receiptSha) } - if v.config.AcceptsCrossTx(block.Epoch()) { + if v.bc.Config().AcceptsCrossTx(block.Epoch()) { cxsSha := cxReceipts.ComputeMerkleRoot() if cxsSha != header.OutgoingReceiptHash() { legacySha := types.DeriveMultipleShardsSha(cxReceipts) @@ -115,7 +111,7 @@ func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.DB, re // Validate the state root against the received state root and throw // an error if they don't match. - if root := statedb.IntermediateRoot(v.config.IsS3(header.Epoch())); header.Root() != root { + if root := statedb.IntermediateRoot(v.bc.Config().IsS3(header.Epoch())); header.Root() != root { dump, _ := rlp.EncodeToBytes(header) const msg = "invalid merkle root (remote: %x local: %x, rlp dump %s)" return fmt.Errorf(msg, header.Root(), root, hex.EncodeToString(dump)) @@ -131,25 +127,11 @@ func (v *BlockValidator) ValidateHeader(block *types.Block, seal bool) error { return errors.New("block is nil") } if h := block.Header(); h != nil { - return v.engine.VerifyHeader(v.bc, h, true) + return v.bc.Engine().VerifyHeader(v.bc, h, true) } return errors.New("header field was nil") } -// ValidateHeaders verifies a batch of blocks' headers concurrently. The method returns a quit channel -// to abort the operations and a results channel to retrieve the async verifications -func (v *BlockValidator) ValidateHeaders(chain []*types.Block) (chan<- struct{}, <-chan error) { - // Start the parallel header verifier - headers := make([]*block.Header, len(chain)) - seals := make([]bool, len(chain)) - - for i, block := range chain { - headers[i] = block.Header() - seals[i] = true - } - return v.engine.VerifyHeaders(v.bc, headers, seals) -} - // 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 @@ -189,7 +171,7 @@ func CalcGasLimit(parent *block.Header, gasFloor, gasCeil uint64) uint64 { // ValidateCXReceiptsProof checks whether the given CXReceiptsProof is consistency with itself func (v *BlockValidator) ValidateCXReceiptsProof(cxp *types.CXReceiptsProof) error { - if !v.config.AcceptsCrossTx(cxp.Header.Epoch()) { + if !v.bc.Config().AcceptsCrossTx(cxp.Header.Epoch()) { return errors.New("[ValidateCXReceiptsProof] cross shard receipt received before cx fork") } @@ -249,5 +231,5 @@ func (v *BlockValidator) ValidateCXReceiptsProof(cxp *types.CXReceiptsProof) err // (4) verify blockHeader with seal var commitSig bls.SerializedSignature copy(commitSig[:], cxp.CommitSig) - return v.engine.VerifyHeaderSignature(v.bc, cxp.Header, commitSig, cxp.CommitBitmap) + return v.bc.Engine().VerifyHeaderSignature(v.bc, cxp.Header, commitSig, cxp.CommitBitmap) } diff --git a/core/blockchain.go b/core/blockchain.go index f7e956dbbe..24272a91ef 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -11,6 +11,7 @@ import ( "github.com/harmony-one/harmony/consensus/reward" "github.com/harmony-one/harmony/core/rawdb" "github.com/harmony-one/harmony/core/state" + "github.com/harmony-one/harmony/core/state/snapshot" "github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/vm" "github.com/harmony-one/harmony/crypto/bls" @@ -55,8 +56,6 @@ type BlockChain interface { // CurrentBlock retrieves the current head block of the canonical chain. The // block is retrieved from the blockchain's internal cache. CurrentBlock() *types.Block - // Validator returns the current validator. - Validator() Validator // Processor returns the current processor. Processor() Processor // State returns a new mutable state based on the current HEAD block. @@ -122,8 +121,8 @@ type BlockChain interface { // // After insertion is done, all accumulated events will be fired. InsertChain(chain types.Blocks, verifyHeaders bool) (int, error) - // LeaderRotationMeta returns the number of continuous blocks by the leader. - LeaderRotationMeta() (publicKeyBytes []byte, epoch, count, shifts uint64, err error) + // LeaderRotationMeta returns info about leader rotation. + LeaderRotationMeta() LeaderRotationMeta // BadBlocks returns a list of the last 'bad blocks' that // the client has seen on the network. BadBlocks() []BadBlock @@ -346,6 +345,9 @@ type BlockChain interface { ) (status WriteStatus, err error) GetLeaderPubKeyFromCoinbase(h *block.Header) (*bls.PublicKeyWrapper, error) + CommitPreimages() error + GetStateCache() state.Database + GetSnapshotTrie() *snapshot.Tree // ========== Only For Tikv Start ========== diff --git a/core/blockchain_impl.go b/core/blockchain_impl.go index 965dccd9a4..3b5bc6bb10 100644 --- a/core/blockchain_impl.go +++ b/core/blockchain_impl.go @@ -90,7 +90,8 @@ var ( blockWriteTimer = metrics.NewRegisteredTimer("chain/write", nil) // ErrNoGenesis is the error when there is no genesis. - ErrNoGenesis = errors.New("Genesis not found in chain") + ErrNoGenesis = errors.New("Genesis not found in chain") + ErrEmptyChain = errors.New("empty chain") // errExceedMaxPendingSlashes .. errExceedMaxPendingSlashes = errors.New("exceeed max pending slashes") errNilEpoch = errors.New("nil epoch for voting power computation") @@ -149,6 +150,7 @@ var defaultCacheConfig = &CacheConfig{ TrieTimeLimit: 5 * time.Minute, SnapshotLimit: 256, SnapshotWait: true, + Preimages: true, } type BlockChainImpl struct { @@ -215,13 +217,13 @@ type BlockChainImpl struct { procInterrupt int32 // interrupt signaler for block processing engine consensus_engine.Engine - processor Processor // block processor interface - validator Validator // block and state validator interface + processor *StateProcessor // block processor interface + validator *BlockValidator vmConfig vm.Config badBlocks *lru.Cache // Bad block cache pendingSlashes slash.Records maxGarbCollectedBlkNum int64 - leaderRotationMeta leaderRotationMeta + leaderRotationMeta LeaderRotationMeta options Options } @@ -236,7 +238,7 @@ func NewBlockChainWithOptions( // NewBlockChain returns a fully initialised block chain using information // available in the database. It initialises the default Ethereum validator and -// Processor. +// Processor. As of Aug-23, this is only used by tests func NewBlockChain( db ethdb.Database, stateCache state.Database, beaconChain BlockChain, cacheConfig *CacheConfig, chainConfig *params.ChainConfig, engine consensus_engine.Engine, vmConfig vm.Config, @@ -335,8 +337,8 @@ func newBlockChainWithOptions( beaconChain = bc } - bc.SetValidator(NewBlockValidator(chainConfig, bc, engine)) - bc.SetProcessor(NewStateProcessor(chainConfig, bc, beaconChain, engine)) + bc.validator = NewBlockValidator(bc) + bc.processor = NewStateProcessor(bc, beaconChain) // Load any existing snapshot, regenerating it if loading failed if bc.cacheConfig.SnapshotLimit > 0 { @@ -366,6 +368,12 @@ func newBlockChainWithOptions( return nil, errors.WithMessage(err, "failed to build leader rotation meta") } + if cacheConfig.Preimages { + if _, _, err := rawdb.WritePreImageStartEndBlock(bc.ChainDb(), curHeader.NumberU64()+1, 0); err != nil { + return nil, errors.WithMessage(err, "failed to write pre-image start end blocks") + } + } + // Take ownership of this particular state go bc.update() return bc, nil @@ -454,7 +462,7 @@ func VerifyIncomingReceipts(blockchain BlockChain, block *types.Block) error { } } - if err := blockchain.Validator().ValidateCXReceiptsProof(cxp); err != nil { + if err := NewBlockValidator(blockchain).ValidateCXReceiptsProof(cxp); err != nil { return errors.Wrapf(err, "[verifyIncomingReceipts] verification failed") } } @@ -486,7 +494,7 @@ func (bc *BlockChainImpl) ValidateNewBlock(block *types.Block, beaconChain Block if block.NumberU64() <= bc.CurrentBlock().NumberU64() { return errors.Errorf("block with the same block number is already committed: %d", block.NumberU64()) } - if err := bc.Validator().ValidateHeader(block, true); err != nil { + if err := bc.validator.ValidateHeader(block, true); err != nil { utils.Logger().Error(). Str("blockHash", block.Hash().Hex()). Err(err). @@ -548,7 +556,7 @@ func (bc *BlockChainImpl) validateNewBlock(block *types.Block) error { } // Verify all the hash roots (state, txns, receipts, cross-shard) - if err := bc.Validator().ValidateState( + if err := bc.validator.ValidateState( block, state, receipts, cxReceipts, usedGas, ); err != nil { bc.reportBlock(block, receipts, err) @@ -734,24 +742,6 @@ func (bc *BlockChainImpl) CurrentFastBlock() *types.Block { return bc.currentFastBlock.Load().(*types.Block) } -func (bc *BlockChainImpl) SetProcessor(processor Processor) { - bc.procmu.Lock() - defer bc.procmu.Unlock() - bc.processor = processor -} - -func (bc *BlockChainImpl) SetValidator(validator Validator) { - bc.procmu.Lock() - defer bc.procmu.Unlock() - bc.validator = validator -} - -func (bc *BlockChainImpl) Validator() Validator { - bc.procmu.RLock() - defer bc.procmu.RUnlock() - return bc.validator -} - func (bc *BlockChainImpl) Processor() Processor { bc.procmu.RLock() defer bc.procmu.RUnlock() @@ -1208,6 +1198,10 @@ func (bc *BlockChainImpl) Stop() { // Flush the collected preimages to disk if err := bc.stateCache.TrieDB().CommitPreimages(); err != nil { utils.Logger().Error().Interface("err", err).Msg("Failed to commit trie preimages") + } else { + if _, _, err := rawdb.WritePreImageStartEndBlock(bc.ChainDb(), 0, bc.CurrentBlock().NumberU64()); err != nil { + utils.Logger().Error().Interface("err", err).Msg("Failed to mark preimages end block") + } } // Ensure all live cached entries be saved into disk, so that we can skip // cache warmup when node restarts. @@ -1639,9 +1633,20 @@ func (bc *BlockChainImpl) InsertChain(chain types.Blocks, verifyHeaders bool) (i return len(chain), nil } + for _, b := range chain { + // check if blocks already exist + if bc.HasBlock(b.Hash(), b.NumberU64()) { + return 0, errors.Wrapf(ErrKnownBlock, "block %s %d already exists", b.Hash().Hex(), b.NumberU64()) + } + } + + prevHash := bc.CurrentBlock().Hash() n, events, logs, err := bc.insertChain(chain, verifyHeaders) bc.PostChainEvents(events, logs) if err == nil { + if prevHash == bc.CurrentBlock().Hash() { + panic("insertChain failed to update current block") + } // there should be only 1 block. for _, b := range chain { if b.Epoch().Uint64() > 0 { @@ -1660,75 +1665,8 @@ func (bc *BlockChainImpl) InsertChain(chain types.Blocks, verifyHeaders bool) (i return n, err } -// buildLeaderRotationMeta builds leader rotation meta if feature is activated. -func (bc *BlockChainImpl) buildLeaderRotationMeta(curHeader *block.Header) error { - if !bc.chainConfig.IsLeaderRotation(curHeader.Epoch()) { - return nil - } - if curHeader.NumberU64() == 0 { - return errors.New("current header is genesis") - } - curPubKey, err := bc.getLeaderPubKeyFromCoinbase(curHeader) - if err != nil { - return err - } - for i := curHeader.NumberU64() - 1; i >= 0; i-- { - header := bc.GetHeaderByNumber(i) - if header == nil { - return errors.New("header is nil") - } - blockPubKey, err := bc.getLeaderPubKeyFromCoinbase(header) - if err != nil { - return err - } - if curPubKey.Bytes != blockPubKey.Bytes || curHeader.Epoch().Uint64() != header.Epoch().Uint64() { - for j := i; i <= curHeader.NumberU64(); j++ { - header := bc.GetHeaderByNumber(i) - if header == nil { - return errors.New("header is nil") - } - err := bc.saveLeaderRotationMeta(header) - if err != nil { - utils.Logger().Error().Err(err).Msg("save leader continuous blocks count error") - return err - } - } - return nil - } - } - return errors.New("no leader rotation meta to save") -} - -func (bc *BlockChainImpl) saveLeaderRotationMeta(h *block.Header) error { - blockPubKey, err := bc.getLeaderPubKeyFromCoinbase(h) - if err != nil { - return err - } - - var s = bc.leaderRotationMeta - - // increase counter only if the same leader and epoch - if bytes.Equal(s.pub, blockPubKey.Bytes[:]) && s.epoch == h.Epoch().Uint64() { - s.count++ - } else { - s.count = 1 - } - // we should increase shifts if the leader is changed. - if !bytes.Equal(s.pub, blockPubKey.Bytes[:]) { - s.shifts++ - } - // but set to zero if new - if s.epoch != h.Epoch().Uint64() { - s.shifts = 0 - } - s.epoch = h.Epoch().Uint64() - bc.leaderRotationMeta = s - - return nil -} - -func (bc *BlockChainImpl) LeaderRotationMeta() (publicKeyBytes []byte, epoch, count, shifts uint64, err error) { - return rawdb.ReadLeaderRotationMeta(bc.db) +func (bc *BlockChainImpl) LeaderRotationMeta() LeaderRotationMeta { + return bc.leaderRotationMeta.Clone() } // insertChain will execute the actual chain insertion and event aggregation. The @@ -1737,7 +1675,7 @@ func (bc *BlockChainImpl) LeaderRotationMeta() (publicKeyBytes []byte, epoch, co func (bc *BlockChainImpl) insertChain(chain types.Blocks, verifyHeaders bool) (int, []interface{}, []*types.Log, error) { // Sanity check that we have something meaningful to import if len(chain) == 0 { - return 0, nil, nil, nil + return 0, nil, nil, ErrEmptyChain } // Do a sanity check that the provided chain is actually ordered and linked for i := 1; i < len(chain); i++ { @@ -1804,7 +1742,7 @@ func (bc *BlockChainImpl) insertChain(chain types.Blocks, verifyHeaders bool) (i err = <-verifyHeadersResults } if err == nil { - err = bc.Validator().ValidateBody(block) + err = NewBlockValidator(bc).ValidateBody(block) } switch { case err == ErrKnownBlock: @@ -1922,7 +1860,7 @@ func (bc *BlockChainImpl) insertChain(chain types.Blocks, verifyHeaders bool) (i // Validate the state using the default validator substart = time.Now() - if err := bc.Validator().ValidateState( + if err := bc.validator.ValidateState( block, state, receipts, cxReceipts, usedGas, ); err != nil { bc.reportBlock(block, receipts, err) @@ -3694,6 +3632,18 @@ func (bc *BlockChainImpl) InitTiKV(conf *harmonyconfig.TiKVConfig) { go bc.tikvCleanCache() } +func (bc *BlockChainImpl) CommitPreimages() error { + return bc.stateCache.TrieDB().CommitPreimages() +} + +func (bc *BlockChainImpl) GetStateCache() state.Database { + return bc.stateCache +} + +func (bc *BlockChainImpl) GetSnapshotTrie() *snapshot.Tree { + return bc.snaps +} + var ( leveldbErrSpec = "leveldb" tooManyOpenFilesErrStr = "Too many open files" diff --git a/core/blockchain_leader_rotation.go b/core/blockchain_leader_rotation.go index 6b9c91a927..b7cdef5190 100644 --- a/core/blockchain_leader_rotation.go +++ b/core/blockchain_leader_rotation.go @@ -1,8 +1,127 @@ package core -type leaderRotationMeta struct { - pub []byte - epoch uint64 - count uint64 - shifts uint64 +import ( + "bytes" + "hash/crc32" + "strconv" + "strings" + + "github.com/harmony-one/harmony/block" + "github.com/harmony-one/harmony/crypto/bls" + "github.com/harmony-one/harmony/internal/utils" + "github.com/pkg/errors" +) + +// LeaderRotationMeta contains information about leader rotation +type LeaderRotationMeta struct { + Pub []byte // bls public key of previous block miner + Epoch uint64 // epoch number of previously inserted block + Count uint64 // quantity of continuous blocks inserted by the same leader + Shifts uint64 // number of leader shifts, shift happens when leader changes +} + +// ShortString returns string representation of the struct +func (a LeaderRotationMeta) ShortString() string { + s := strings.Builder{} + s.Write(a.Pub[3:]) + s.WriteString(" ") + s.WriteString(strconv.FormatUint(a.Epoch, 10)) + s.WriteString(" ") + s.WriteString(strconv.FormatUint(a.Count, 10)) + s.WriteString(" ") + s.WriteString(strconv.FormatUint(a.Shifts, 10)) + return s.String() +} + +// Hash returns hash of the struct +func (a LeaderRotationMeta) Hash() []byte { + c := crc32.NewIEEE() + c.Write(a.Pub) + c.Write([]byte(strconv.FormatUint(a.Epoch, 10))) + c.Write([]byte(strconv.FormatUint(a.Count, 10))) + c.Write([]byte(strconv.FormatUint(a.Shifts, 10))) + return c.Sum(nil) +} + +// Clone returns a copy of the struct +func (a LeaderRotationMeta) Clone() LeaderRotationMeta { + return LeaderRotationMeta{ + Pub: append([]byte{}, a.Pub...), + Epoch: a.Epoch, + Count: a.Count, + Shifts: a.Shifts, + } +} + +// buildLeaderRotationMeta builds leader rotation meta if feature is activated. +func (bc *BlockChainImpl) buildLeaderRotationMeta(curHeader *block.Header) error { + if !bc.chainConfig.IsLeaderRotationInternalValidators(curHeader.Epoch()) { + return nil + } + if curHeader.NumberU64() == 0 { + return errors.New("current header is genesis") + } + curPubKey, err := bc.getLeaderPubKeyFromCoinbase(curHeader) + if err != nil { + return err + } + for i := curHeader.NumberU64() - 1; i >= 0; i-- { + header := bc.GetHeaderByNumber(i) + if header == nil { + return errors.New("header is nil") + } + blockPubKey, err := bc.getLeaderPubKeyFromCoinbase(header) + if err != nil { + return err + } + if curPubKey.Bytes != blockPubKey.Bytes || curHeader.Epoch().Uint64() != header.Epoch().Uint64() { + for j := i; j <= curHeader.NumberU64(); j++ { + header := bc.GetHeaderByNumber(j) + if header == nil { + return errors.New("header is nil") + } + err := bc.saveLeaderRotationMeta(header) + if err != nil { + utils.Logger().Error().Err(err).Msg("save leader continuous blocks count error") + return err + } + } + return nil + } + } + return errors.New("no leader rotation meta to save") +} + +// saveLeaderRotationMeta saves leader rotation meta if feature is activated. +func (bc *BlockChainImpl) saveLeaderRotationMeta(h *block.Header) error { + blockPubKey, err := bc.getLeaderPubKeyFromCoinbase(h) + if err != nil { + return err + } + bc.leaderRotationMeta = processRotationMeta(h.Epoch().Uint64(), blockPubKey.Bytes, bc.leaderRotationMeta) + return nil +} + +func processRotationMeta(epoch uint64, blockPubKey bls.SerializedPublicKey, s LeaderRotationMeta) LeaderRotationMeta { + // increase counter only if the same leader and epoch + if bytes.Equal(s.Pub, blockPubKey[:]) && s.Epoch == epoch { + s.Count++ + } else { + s.Count = 1 + } + // we should increase shifts if the leader has changed. + if !bytes.Equal(s.Pub, blockPubKey[:]) { + s.Shifts++ + } + // but set to zero if new + if s.Epoch != epoch { + s.Shifts = 0 + } + s.Epoch = epoch + return LeaderRotationMeta{ + Pub: blockPubKey[:], + Epoch: s.Epoch, + Count: s.Count, + Shifts: s.Shifts, + } } diff --git a/core/blockchain_leader_rotation_test.go b/core/blockchain_leader_rotation_test.go new file mode 100644 index 0000000000..047dbdd636 --- /dev/null +++ b/core/blockchain_leader_rotation_test.go @@ -0,0 +1,57 @@ +package core + +import ( + "testing" + + "github.com/harmony-one/harmony/crypto/bls" + "github.com/stretchr/testify/require" +) + +var k1 = bls.SerializedPublicKey{1, 2, 3} + +func TestRotationMetaProcess(t *testing.T) { + t.Run("same_leader_increase_count", func(t *testing.T) { + rs := processRotationMeta(1, bls.SerializedPublicKey{}, LeaderRotationMeta{ + Pub: bls.SerializedPublicKey{}.Bytes(), + Epoch: 1, + Count: 1, + Shifts: 1, + }) + require.Equal(t, LeaderRotationMeta{ + Pub: bls.SerializedPublicKey{}.Bytes(), + Epoch: 1, + Count: 2, + Shifts: 1, + }, rs) + }) + + t.Run("new_leader_increase_shifts", func(t *testing.T) { + rs := processRotationMeta(1, k1, LeaderRotationMeta{ + Pub: bls.SerializedPublicKey{}.Bytes(), + Epoch: 1, + Count: 1, + Shifts: 1, + }) + require.Equal(t, LeaderRotationMeta{ + Pub: k1.Bytes(), + Epoch: 1, + Count: 1, + Shifts: 2, + }, rs) + }) + + t.Run("new_epoch_reset_count", func(t *testing.T) { + rs := processRotationMeta(2, k1, LeaderRotationMeta{ + Pub: bls.SerializedPublicKey{}.Bytes(), + Epoch: 1, + Count: 1, + Shifts: 1, + }) + require.Equal(t, LeaderRotationMeta{ + Pub: k1.Bytes(), + Epoch: 2, + Count: 1, + Shifts: 0, + }, rs) + }) +} diff --git a/core/blockchain_stub.go b/core/blockchain_stub.go index 5d83149a67..804b48a00a 100644 --- a/core/blockchain_stub.go +++ b/core/blockchain_stub.go @@ -3,6 +3,8 @@ package core import ( "math/big" + "github.com/harmony-one/harmony/core/state/snapshot" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" @@ -436,6 +438,18 @@ func (a Stub) InitTiKV(conf *harmonyconfig.TiKVConfig) { return } -func (a Stub) LeaderRotationMeta() (publicKeyBytes []byte, epoch, count, shifts uint64, err error) { - return nil, 0, 0, 0, errors.Errorf("method LeaderRotationMeta not implemented for %s", a.Name) +func (a Stub) LeaderRotationMeta() LeaderRotationMeta { + return LeaderRotationMeta{} +} + +func (a Stub) CommitPreimages() error { + return errors.Errorf("method CommitPreimages not implemented for %s", a.Name) +} + +func (a Stub) GetStateCache() state.Database { + return nil +} + +func (a Stub) GetSnapshotTrie() *snapshot.Tree { + return nil } diff --git a/core/epochchain.go b/core/epochchain.go index bcf00f5a89..7a3c40677b 100644 --- a/core/epochchain.go +++ b/core/epochchain.go @@ -323,3 +323,9 @@ func (bc *EpochChain) IsSameLeaderAsPreviousBlock(block *types.Block) bool { func (bc *EpochChain) GetVMConfig() *vm.Config { return bc.vmConfig } + +func (bc *EpochChain) CommitPreimages() error { + // epoch chain just has last block, which does not have any txs + // so no pre-images here + return nil +} diff --git a/core/genesis.go b/core/genesis.go index 3e230cf9e6..e706235005 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -28,6 +28,7 @@ import ( "strings" "github.com/ethereum/go-ethereum/common" + ethCommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/crypto" @@ -252,11 +253,19 @@ func (g *Genesis) ToBlock(db ethdb.Database) *types.Block { for key, value := range account.Storage { statedb.SetState(addr, key, value) } + if err := rawdb.WritePreimages( + statedb.Database().DiskDB(), map[ethCommon.Hash][]byte{ + crypto.Keccak256Hash(addr.Bytes()): addr.Bytes(), + }, + ); err != nil { + utils.Logger().Error().Err(err).Msg("Failed to store preimage") + os.Exit(1) + } } root := statedb.IntermediateRoot(false) shardStateBytes, err := shard.EncodeWrapper(g.ShardState, false) if err != nil { - utils.Logger().Error().Msg("failed to rlp-serialize genesis shard state") + utils.Logger().Error().Err(err).Msg("failed to rlp-serialize genesis shard state") os.Exit(1) } head := g.Factory.NewHeader(common.Big0).With(). diff --git a/core/genesis_util.go b/core/genesis_util.go index 45a075976d..949a6933ba 100644 --- a/core/genesis_util.go +++ b/core/genesis_util.go @@ -3,8 +3,8 @@ package core import ( "encoding/json" "fmt" - "io/ioutil" "math/big" + "os" "sort" "github.com/ethereum/go-ethereum/rlp" @@ -29,7 +29,7 @@ func encodeGenesisConfig(ga []GenesisItem) string { } func parseGenesisConfigFile(fileName string) genesisConfig { - input, err := ioutil.ReadFile(fileName) + input, err := os.ReadFile(fileName) if err != nil { panic(fmt.Sprintf("cannot open genesisblock config file %v, err %v\n", fileName, err)) } diff --git a/core/preimages.go b/core/preimages.go new file mode 100644 index 0000000000..5034cc0e95 --- /dev/null +++ b/core/preimages.go @@ -0,0 +1,378 @@ +package core + +import ( + "encoding/csv" + "fmt" + "io" + "os" + "strconv" + "time" + + "github.com/ethereum/go-ethereum/common" + ethCommon "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/harmony-one/harmony/block" + "github.com/harmony-one/harmony/core/rawdb" + "github.com/harmony-one/harmony/core/state" + "github.com/harmony-one/harmony/core/types" + "github.com/harmony-one/harmony/internal/utils" + "github.com/pkg/errors" + "github.com/syndtr/goleveldb/leveldb" +) + +// ImportPreimages is public so `main.go` can call it directly` +func ImportPreimages(chain BlockChain, path string) error { + reader, err := os.Open(path) + if err != nil { + return fmt.Errorf("could not open file for reading: %s", err) + } + csvReader := csv.NewReader(reader) + dbReader := chain.ChainDb() + imported := uint64(0) + for { + record, err := csvReader.Read() + if errors.Is(err, io.EOF) { + return fmt.Errorf("MyBlockNumber field missing, cannot proceed") + } + if err != nil { + return fmt.Errorf("could not read from reader: %s", err) + } + // this means the address is a number + if blockNumber, err := strconv.ParseUint(record[1], 10, 64); err == nil { + if record[0] == "MyBlockNumber" { + // set this value in database, and prometheus, if needed + prev, err := rawdb.ReadPreimageImportBlock(dbReader) + if err != nil { + if !errors.Is(err, leveldb.ErrNotFound) { + return fmt.Errorf("no prior value found, overwriting: %s", err) + } + } + if blockNumber > prev { + if rawdb.WritePreimageImportBlock(dbReader, blockNumber) != nil { + return fmt.Errorf("error saving last import block: %s", err) + } + } + // this is the last record + imported = blockNumber + break + } + } + key := ethCommon.HexToHash(record[0]) + value := ethCommon.Hex2Bytes(record[1]) + // validate + if crypto.Keccak256Hash(value) != key { + fmt.Println("Data mismatch: skipping", record) + continue + } + // add to database + _ = rawdb.WritePreimages( + dbReader, map[ethCommon.Hash][]byte{ + key: value, + }, + ) + } + // now, at this point, we will have to generate missing pre-images + if imported != 0 { + genStart, _ := rawdb.ReadPreImageStartBlock(dbReader) + genEnd, _ := rawdb.ReadPreImageEndBlock(dbReader) + current := chain.CurrentBlock().NumberU64() + toGenStart, toGenEnd := FindMissingRange(imported, genStart, genEnd, current) + if toGenStart != 0 && toGenEnd != 0 { + if err := GeneratePreimages( + chain, toGenStart, toGenEnd, + ); err != nil { + return fmt.Errorf("error generating: %s", err) + } + } + } + + return nil +} + +// ExportPreimages is public so `main.go` can call it directly` +func ExportPreimages(chain BlockChain, path string) error { + if err := chain.CommitPreimages(); err != nil { + return fmt.Errorf("unable to commit preimages: %w", err) + } + // set up csv + writer, err := os.Create(path) + if err != nil { + utils.Logger().Error(). + Msgf("unable to create file at %s due to %s", path, err) + return fmt.Errorf( + "unable to create file at %s due to %s", + path, err, + ) + } + csvWriter := csv.NewWriter(writer) + // open trie + block := chain.CurrentBlock() + statedb, err := chain.StateAt(block.Root()) + if err != nil { + utils.Logger().Error(). + Msgf( + "unable to open statedb at %s due to %s", + block.Root(), err, + ) + return fmt.Errorf( + "unable to open statedb at %x due to %s", + block.Root(), err, + ) + } + trie, err := statedb.Database().OpenTrie( + block.Root(), + ) + if err != nil { + utils.Logger().Error(). + Msgf( + "unable to open trie at %x due to %s", + block.Root(), err, + ) + return fmt.Errorf( + "unable to open trie at %x due to %s", + block.Root(), err, + ) + } + accountIterator := trie.NodeIterator(nil) + dbReader := chain.ChainDb() + for accountIterator.Next(true) { + // the leaf nodes of the MPT represent accounts + if !accountIterator.Leaf() { + continue + } + // the leaf key is the hashed address + hashed := accountIterator.LeafKey() + asHash := ethCommon.BytesToHash(hashed) + // obtain the corresponding address + preimage := rawdb.ReadPreimage( + dbReader, asHash, + ) + if len(preimage) == 0 { + utils.Logger().Warn(). + Msgf("Address not found for %x", asHash) + continue + } + address := ethCommon.BytesToAddress(preimage) + // key value format, so hash of value is first + csvWriter.Write([]string{ + fmt.Sprintf("%x", asHash.Bytes()), + fmt.Sprintf("%x", address.Bytes()), + }) + } + // lastly, write the block number + csvWriter.Write( + []string{ + "MyBlockNumber", + block.Number().String(), + }, + ) + // to disk + csvWriter.Flush() + if err := csvWriter.Error(); err != nil { + utils.Logger().Error(). + Msgf("unable to write csv due to %s", err) + return fmt.Errorf("unable to write csv due to %s", err) + } + writer.Close() + return nil +} + +func GeneratePreimages(chain BlockChain, start, end uint64) error { + if start < 2 { + return fmt.Errorf("too low starting point %d", start) + } + fmt.Println("generating from", start, "to", end) + + // fetch all the blocks, from start and end both inclusive + // then execute them - the execution will write the pre-images + // to disk and we are good to go + + // attempt to find a block number for which we have block and state + // with number < start + var startingState *state.DB + var startingBlock *types.Block + for i := start - 1; i > 0; i-- { + fmt.Println("finding block number", i) + startingBlock = chain.GetBlockByNumber(i) + if startingBlock == nil { + fmt.Println("not found block number", i) + // rewound too much in snapdb, so exit loop + // although this is only designed for s2/s3 nodes in mind + // which do not have such a snapdb + break + } + fmt.Println("found block number", startingBlock.NumberU64(), startingBlock.Root().Hex()) + stateAt, err := chain.StateAt(startingBlock.Root()) + if err != nil { + continue + } + startingState = stateAt + break + } + if startingBlock == nil || startingState == nil { + return fmt.Errorf("no eligible starting block with state found") + } + + var endingState *state.DB + var errProcess error + // now execute block T+1 based on starting state + for i := startingBlock.NumberU64() + 1; i <= end; i++ { + if i%10000 == 0 { + fmt.Println("processing block", i) + } + block := chain.GetBlockByNumber(i) + if block == nil { + // because we have startingBlock we must have all following + return fmt.Errorf("block %d not found", i) + } + stateAt, _ := chain.StateAt(block.Root()) + _, _, _, _, _, _, endingState, errProcess = chain.Processor().Process(block, startingState, *chain.GetVMConfig(), false) + if errProcess != nil { + return fmt.Errorf("error executing block #%d: %s", i, errProcess) + } + + if stateAt != nil { + if root, err := endingState.Commit(false); err != nil { + return fmt.Errorf("unable to commit state for block '%d': %w", i, err) + } else if root.Hex() != block.Root().Hex() { + return fmt.Errorf("block root hashes different after commit commitRoot='%s' blockRoot='%s'", root.Hex(), block.Root().Hex()) + } + + if err := chain.CommitPreimages(); err != nil { + return fmt.Errorf("error committing preimages for block '%d': %w", i, err) + } + startingState = stateAt + } else { + startingState = endingState + } + } + // force any pre-images in memory so far to go to disk, if they haven't already + fmt.Println("committing images") + if endingState != nil { + if _, err := endingState.Commit(false); err != nil { + return fmt.Errorf("unable to commit state for block: %w", err) + } + } + if err := chain.CommitPreimages(); err != nil { + return fmt.Errorf("error committing preimages %s", err) + } + + if _, _, err := rawdb.WritePreImageStartEndBlock(chain.ChainDb(), startingBlock.NumberU64(), end); err != nil { + return fmt.Errorf("error writing pre-image gen blocks %s", err) + } + return nil +} +func FindMissingRange( + imported, start, end, current uint64, +) (uint64, uint64) { + // both are unset + if start == 0 && end == 0 { + if imported < current { + return imported + 1, current + } else { + return 0, 0 + } + } + // constraints: start <= end <= current + // in regular usage, we should have end == current + // however, with the GenerateFlag usage, we can have end < current + check1 := start <= end + if !check1 { + panic("Start > End") + } + check2 := end <= current + if !check2 { + panic("End > Current") + } + // imported can sit in any of the 4 ranges + if imported < start { + // both inclusive + return imported + 1, start - 1 + } + if imported < end { + return end + 1, current + } + if imported < current { + return imported + 1, current + } + // future data imported + if current < imported { + return 0, 0 + } + return 0, 0 +} + +func VerifyPreimages(header *block.Header, chain BlockChain) (uint64, error) { + var existingPreimages uint64 + parentRoot := chain.GetBlockByHash( + header.ParentHash(), + ).Root() // for examining MPT at this root, should exist + + db, err := chain.StateAt(parentRoot) + if err != nil { + return 0, err + } + + trie, err := db.Database().OpenTrie(parentRoot) + if err != nil { + return 0, err + } + + if err := chain.CommitPreimages(); err != nil { + return 0, fmt.Errorf("unable to commit preimages: %w", err) + } + + diskDB := db.Database().DiskDB() + // start the iteration + accountIterator := trie.NodeIterator(nil) + for accountIterator.Next(true) { + // leaf means leaf node of the MPT, which is an account + // the leaf key is the address + if accountIterator.Leaf() { + key := accountIterator.LeafKey() + preimage := rawdb.ReadPreimage(diskDB, common.BytesToHash(key)) + if len(preimage) == 0 { + err := errors.New( + fmt.Sprintf( + "cannot find preimage for %x after '%d' accounts", key, existingPreimages, + ), + ) + utils.Logger().Warn().Msg(err.Error()) + return existingPreimages, err + } + address := common.BytesToAddress(preimage) + // skip blank address + if address == (common.Address{}) { + continue + } + + existingPreimages++ + } + } + + return existingPreimages, nil +} + +func WritePreimagesMetricsIntoPrometheus(chain BlockChain, sendMetrics func(preimageStart, preimageEnd, lastPreimageImport, verifiedAddresses uint64, shard uint32)) { + shardID := chain.ShardID() + if shardID < 2 { + return + } + + ticker := time.NewTicker(time.Minute * 5) + dbReader := chain.ChainDb() + + for { + select { + case <-ticker.C: + lastImport, _ := rawdb.ReadPreimageImportBlock(dbReader) + startBlock, _ := rawdb.ReadPreImageStartBlock(dbReader) + endBlock, _ := rawdb.ReadPreImageEndBlock(dbReader) + + chain.CurrentBlock().NumberU64() + verify, _ := VerifyPreimages(chain.CurrentBlock().Header(), chain) + + sendMetrics(startBlock, endBlock, lastImport, verify, shardID) + } + } +} diff --git a/core/rawdb/accessors_state.go b/core/rawdb/accessors_state.go index 72dbe94fb6..81adabbfd5 100644 --- a/core/rawdb/accessors_state.go +++ b/core/rawdb/accessors_state.go @@ -147,3 +147,65 @@ func DeleteValidatorCode(db ethdb.KeyValueWriter, hash common.Hash) { utils.Logger().Error().Err(err).Msg("Failed to delete validator code") } } + +func WritePreimageImportBlock(db ethdb.KeyValueWriter, number uint64) error { + return db.Put(preImageImportKey, encodeBlockNumber(number)) +} + +func ReadPreimageImportBlock(db ethdb.KeyValueReader) (uint64, error) { + val, err := db.Get(preImageImportKey) + if err != nil { + return 0, err + } + return decodeBlockNumber(val), nil +} + +func WritePreImageStartEndBlock( + db ethdb.KeyValueStore, + start uint64, + end uint64, +) ( + uint64, + uint64, + error, +) { + returnStart := start + returnEnd := end + if start != 0 { + existingStart, err := ReadPreImageStartBlock(db) + if err != nil || existingStart > start { + if err := db.Put(preImageGenStartKey, encodeBlockNumber(start)); err != nil { + return 0, 0, err + } else { + returnStart = existingStart + } + } + } + if end != 0 { + existingEnd, err := ReadPreImageEndBlock(db) + if err != nil || existingEnd < end { + if err := db.Put(preImageGenEndKey, encodeBlockNumber(end)); err != nil { + return 0, 0, err + } else { + returnEnd = existingEnd + } + } + } + return returnStart, returnEnd, nil +} + +func ReadPreImageStartBlock(db ethdb.KeyValueReader) (uint64, error) { + val, err := db.Get(preImageGenStartKey) + if err != nil { + return 0, err + } + return decodeBlockNumber(val), nil +} + +func ReadPreImageEndBlock(db ethdb.KeyValueReader) (uint64, error) { + val, err := db.Get(preImageGenEndKey) + if err != nil { + return 0, err + } + return decodeBlockNumber(val), nil +} diff --git a/core/rawdb/schema.go b/core/rawdb/schema.go index 56147b51d3..8251766ef2 100644 --- a/core/rawdb/schema.go +++ b/core/rawdb/schema.go @@ -148,6 +148,10 @@ var ( BloomTrieIndexPrefix = []byte("bltIndex-") CliqueSnapshotPrefix = []byte("clique-") + + preImageImportKey = []byte("preimage-import") + preImageGenStartKey = []byte("preimage-gen-start") + preImageGenEndKey = []byte("preimage-gen-end") ) // LegacyTxLookupEntry is the legacy TxLookupEntry definition with some unnecessary diff --git a/core/staking_verifier.go b/core/staking_verifier.go index 541d26f4e6..c36d24e689 100644 --- a/core/staking_verifier.go +++ b/core/staking_verifier.go @@ -30,14 +30,9 @@ var ( ) func checkDuplicateFields( - bc ChainContext, state vm.StateDB, + addrs []common.Address, state vm.StateDB, validator common.Address, identity string, blsKeys []bls.SerializedPublicKey, ) error { - addrs, err := bc.ReadValidatorList() - if err != nil { - return err - } - checkIdentity := identity != "" checkBlsKeys := len(blsKeys) != 0 @@ -99,8 +94,12 @@ func VerifyAndCreateValidatorFromMsg( errValidatorExist, common2.MustAddressToBech32(msg.ValidatorAddress), ) } + addrs, err := chainContext.ReadValidatorList() + if err != nil { + return nil, err + } if err := checkDuplicateFields( - chainContext, stateDB, + addrs, stateDB, msg.ValidatorAddress, msg.Identity, msg.SlotPubKeys); err != nil { @@ -151,8 +150,12 @@ func VerifyAndEditValidatorFromMsg( if msg.SlotKeyToAdd != nil { newBlsKeys = append(newBlsKeys, *msg.SlotKeyToAdd) } + addrs, err := chainContext.ReadValidatorList() + if err != nil { + return nil, err + } if err := checkDuplicateFields( - chainContext, stateDB, + addrs, stateDB, msg.ValidatorAddress, msg.Identity, newBlsKeys); err != nil { @@ -171,11 +174,20 @@ func VerifyAndEditValidatorFromMsg( return nil, errCommissionRateChangeTooHigh } - if chainContext.Config().IsMinCommissionRate(epoch) && newRate.LT(availability.MinCommissionRate) { + minRate := availability.MinCommissionRate( + chainContext.Config().IsMinCommissionRate(epoch), + chainContext.Config().IsHIP30(epoch), + ) + if newRate.LT(minRate) { firstEpoch := stateDB.GetValidatorFirstElectionEpoch(msg.ValidatorAddress) promoPeriod := chainContext.Config().MinCommissionPromoPeriod.Int64() if firstEpoch.Uint64() != 0 && big.NewInt(0).Sub(epoch, firstEpoch).Int64() >= promoPeriod { - return nil, errCommissionRateChangeTooLow + return nil, + errors.Errorf( + "%s %d%%", + errCommissionRateChangeTooLowT, + minRate.MulInt64(100).Int64(), + ) } } diff --git a/core/staking_verifier_test.go b/core/staking_verifier_test.go index 01d24cc8d4..53d47a4788 100644 --- a/core/staking_verifier_test.go +++ b/core/staking_verifier_test.go @@ -153,16 +153,6 @@ func TestCheckDuplicateFields(t *testing.T) { expErr: nil, }, - { - // chain error - bc: &fakeErrChainContext{}, - sdb: makeStateDBForStake(t), - validator: createValidatorAddr, - identity: makeIdentityStr("new validator"), - pubs: []bls.SerializedPublicKey{blsKeys[11].pub}, - - expErr: errors.New("error intended"), - }, { // validators read from chain not in state bc: func() *fakeChainContext { @@ -201,7 +191,11 @@ func TestCheckDuplicateFields(t *testing.T) { }, } for i, test := range tests { - err := checkDuplicateFields(test.bc, test.sdb, test.validator, test.identity, test.pubs) + addrs, err := test.bc.ReadValidatorList() + if err != nil { + t.Fatal(err) + } + err = checkDuplicateFields(addrs, test.sdb, test.validator, test.identity, test.pubs) if assErr := assertError(err, test.expErr); assErr != nil { t.Errorf("Test %v: %v", i, assErr) @@ -676,7 +670,7 @@ func TestVerifyAndEditValidatorFromMsg(t *testing.T) { return msg }(), - expErr: errCommissionRateChangeTooLow, + expErr: errCommissionRateChangeTooLowT, }, { // 15: Rate is ok within the promo period diff --git a/core/state/statedb.go b/core/state/statedb.go index e84084c02c..96bd4d26ec 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -1222,9 +1222,9 @@ var ( // ValidatorWrapper retrieves the existing validator in the cache, if sendOriginal // else it will return a copy of the wrapper - which needs to be explicitly committed -// with UpdateValidatorWrapper -// to conserve memory, the copy can optionally avoid deep copying delegations -// Revert in UpdateValidatorWrapper does not work if sendOriginal == true +// with UpdateValidatorWrapper. +// To conserve memory, the copy can optionally avoid deep copying delegations. +// Revert in UpdateValidatorWrapper does not work if sendOriginal == true. func (db *DB) ValidatorWrapper( addr common.Address, sendOriginal bool, @@ -1362,7 +1362,11 @@ var ( ) // AddReward distributes the reward to all the delegators based on stake percentage. -func (db *DB) AddReward(snapshot *stk.ValidatorWrapper, reward *big.Int, shareLookup map[common.Address]numeric.Dec) error { +func (db *DB) AddReward( + snapshot *stk.ValidatorWrapper, + reward *big.Int, + shareLookup map[common.Address]numeric.Dec, +) error { if reward.Cmp(common.Big0) == 0 { utils.Logger().Info().RawJSON("validator", []byte(snapshot.String())). Msg("0 given as reward") diff --git a/core/state_processor.go b/core/state_processor.go index 7a2f2a5d47..6ea9e244a6 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -17,6 +17,8 @@ package core import ( + "encoding/binary" + "fmt" "math/big" "time" @@ -26,8 +28,8 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/rlp" "github.com/harmony-one/harmony/block" - consensus_engine "github.com/harmony-one/harmony/consensus/engine" "github.com/harmony-one/harmony/consensus/reward" + "github.com/harmony-one/harmony/core/rawdb" "github.com/harmony-one/harmony/core/state" "github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/vm" @@ -41,6 +43,11 @@ import ( "github.com/pkg/errors" ) +var ( + ErrNoMigrationRequired = errors.New("No balance migration required") + ErrNoMigrationPossible = errors.New("No balance migration possible") +) + const ( resultCacheLimit = 64 // The number of cached results from processing blocks ) @@ -50,11 +57,9 @@ const ( // // StateProcessor implements Processor. type StateProcessor struct { - config *params.ChainConfig // Chain configuration options - bc BlockChain // Canonical blockchain - beacon BlockChain // Beacon chain - engine consensus_engine.Engine // Consensus engine used for block rewards - resultCache *lru.Cache // Cache for result after a certain block is processed + bc BlockChain // Canonical blockchain + beacon BlockChain // Beacon chain + resultCache *lru.Cache // Cache for result after a certain block is processed } // this structure is cached, and each individual element is returned @@ -70,7 +75,7 @@ type ProcessorResult struct { // NewStateProcessor initialises a new StateProcessor. func NewStateProcessor( - config *params.ChainConfig, bc BlockChain, beacon BlockChain, engine consensus_engine.Engine, + bc BlockChain, beacon BlockChain, ) *StateProcessor { if bc == nil { panic("bc is nil") @@ -80,14 +85,14 @@ func NewStateProcessor( } resultCache, _ := lru.New(resultCacheLimit) return &StateProcessor{ - config: config, bc: bc, beacon: beacon, - engine: engine, resultCache: resultCache, } } +type UsedGas = uint64 + // Process processes the state changes according to the Ethereum rules by running // the transaction messages using the statedb and applying any rewards to both // the processor (coinbase) and any included uncles. @@ -99,7 +104,7 @@ func (p *StateProcessor) Process( block *types.Block, statedb *state.DB, cfg vm.Config, readCache bool, ) ( types.Receipts, types.CXReceipts, []staking.StakeMsg, - []*types.Log, uint64, reward.Reader, *state.DB, error, + []*types.Log, UsedGas, reward.Reader, *state.DB, error, ) { cacheKey := block.Hash() if readCache { @@ -128,48 +133,68 @@ func (p *StateProcessor) Process( return nil, nil, nil, nil, 0, nil, statedb, err } - startTime := time.Now() - // Iterate over and process the individual transactions - for i, tx := range block.Transactions() { - statedb.Prepare(tx.Hash(), block.Hash(), i) - receipt, cxReceipt, stakeMsgs, _, err := ApplyTransaction( - p.config, p.bc, &beneficiary, gp, statedb, header, tx, usedGas, cfg, - ) - if err != nil { + processTxsAndStxs := true + cxReceipt, err := MayBalanceMigration(gp, header, statedb, p.bc) + if err != nil { + if errors.Is(err, ErrNoMigrationPossible) { + // ran out of accounts + processTxsAndStxs = false + } + if !errors.Is(err, ErrNoMigrationRequired) && !errors.Is(err, ErrNoMigrationPossible) { return nil, nil, nil, nil, 0, nil, statedb, err } - receipts = append(receipts, receipt) + } else { if cxReceipt != nil { outcxs = append(outcxs, cxReceipt) + // only 1 cx per block + processTxsAndStxs = false } - if len(stakeMsgs) > 0 { - blockStakeMsgs = append(blockStakeMsgs, stakeMsgs...) - } - allLogs = append(allLogs, receipt.Logs...) } - utils.Logger().Debug().Int64("elapsed time", time.Now().Sub(startTime).Milliseconds()).Msg("Process Normal Txns") - startTime = time.Now() - // Iterate over and process the staking transactions - L := len(block.Transactions()) - for i, tx := range block.StakingTransactions() { - statedb.Prepare(tx.Hash(), block.Hash(), i+L) - receipt, _, err := ApplyStakingTransaction( - p.config, p.bc, &beneficiary, gp, statedb, header, tx, usedGas, cfg, - ) - if err != nil { - return nil, nil, nil, nil, 0, nil, statedb, err + if processTxsAndStxs { + startTime := time.Now() + // Iterate over and process the individual transactions + for i, tx := range block.Transactions() { + statedb.Prepare(tx.Hash(), block.Hash(), i) + receipt, cxReceipt, stakeMsgs, _, err := ApplyTransaction( + p.bc, &beneficiary, gp, statedb, header, tx, usedGas, cfg, + ) + if err != nil { + return nil, nil, nil, nil, 0, nil, statedb, err + } + receipts = append(receipts, receipt) + if cxReceipt != nil { + outcxs = append(outcxs, cxReceipt) + } + if len(stakeMsgs) > 0 { + blockStakeMsgs = append(blockStakeMsgs, stakeMsgs...) + } + + allLogs = append(allLogs, receipt.Logs...) + } + utils.Logger().Debug().Int64("elapsed time", time.Now().Sub(startTime).Milliseconds()).Msg("Process Normal Txns") + + startTime = time.Now() + // Iterate over and process the staking transactions + L := len(block.Transactions()) + for i, tx := range block.StakingTransactions() { + statedb.Prepare(tx.Hash(), block.Hash(), i+L) + receipt, _, err := ApplyStakingTransaction( + p.bc, &beneficiary, gp, statedb, header, tx, usedGas, cfg, + ) + if err != nil { + return nil, nil, nil, nil, 0, nil, statedb, err + } + receipts = append(receipts, receipt) + allLogs = append(allLogs, receipt.Logs...) } - receipts = append(receipts, receipt) - allLogs = append(allLogs, receipt.Logs...) + utils.Logger().Debug().Int64("elapsed time", time.Now().Sub(startTime).Milliseconds()).Msg("Process Staking Txns") } - utils.Logger().Debug().Int64("elapsed time", time.Now().Sub(startTime).Milliseconds()).Msg("Process Staking Txns") - // incomingReceipts should always be processed // after transactions (to be consistent with the block proposal) for _, cx := range block.IncomingReceipts() { if err := ApplyIncomingReceipt( - p.config, statedb, header, cx, + p.bc.Config(), statedb, header, cx, ); err != nil { return nil, nil, nil, nil, 0, nil, statedb, errors.New("[Process] Cannot apply incoming receipts") @@ -185,7 +210,7 @@ func (p *StateProcessor) Process( } } - if err := MayTestnetShardReduction(p.bc, statedb, header); err != nil { + if err := MayShardReduction(p.bc, statedb, header); err != nil { return nil, nil, nil, nil, 0, nil, statedb, err } @@ -195,7 +220,7 @@ func (p *StateProcessor) Process( // Block processing don't need to block on reward computation as in block proposal sigsReady <- true }() - _, payout, err := p.engine.Finalize( + _, payout, err := p.bc.Engine().Finalize( p.bc, p.beacon, header, statedb, block.Transactions(), @@ -246,8 +271,9 @@ func getTransactionType( // and uses the input parameters for its environment. It returns the receipt // for the transaction, gas used and an error if the transaction failed, // indicating the block was invalid. -func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.DB, header *block.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, *types.CXReceipt, []staking.StakeMsg, uint64, error) { - txType := getTransactionType(config, header, tx) +func ApplyTransaction(bc ChainContext, author *common.Address, gp *GasPool, statedb *state.DB, header *block.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, *types.CXReceipt, []staking.StakeMsg, uint64, error) { + config := bc.Config() + txType := getTransactionType(bc.Config(), header, tx) if txType == types.InvalidTx { return nil, nil, nil, 0, errors.New("Invalid Transaction Type") } @@ -284,7 +310,7 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo // Apply the transaction to the current state (included in the env) result, err := ApplyMessage(vmenv, msg, gp) if err != nil { - return nil, nil, nil, 0, err + return nil, nil, nil, 0, errors.Wrapf(err, "apply failed from='%s' to='%s' balance='%s'", msg.From().Hex(), msg.To().Hex(), statedb.GetBalance(msg.From()).String()) } // Update the state with pending changes var root []byte @@ -350,9 +376,9 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo // indicating the block was invalid. // staking transaction will use the code field in the account to store the staking information func ApplyStakingTransaction( - config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.DB, + bc ChainContext, author *common.Address, gp *GasPool, statedb *state.DB, header *block.Header, tx *staking.StakingTransaction, usedGas *uint64, cfg vm.Config) (receipt *types.Receipt, gas uint64, err error) { - + config := bc.Config() msg, err := StakingToMessage(tx, header.Number()) if err != nil { return nil, 0, err @@ -366,7 +392,7 @@ func ApplyStakingTransaction( vmenv := vm.NewEVM(context, statedb, config, cfg) // Apply the transaction to the current state (included in the env) - gas, err = ApplyStakingMessage(vmenv, msg, gp, bc) + gas, err = ApplyStakingMessage(vmenv, msg, gp) if err != nil { return nil, 0, err } @@ -442,13 +468,16 @@ func StakingToMessage( return msg, nil } -// MayTestnetShardReduction handles the change in the number of Shards. It will mark the affected validator as inactive. +// MayShardReduction handles the change in the number of Shards. It will mark the affected validator as inactive. // This function does not handle all cases, only for ShardNum from 4 to 2. -func MayTestnetShardReduction(bc ChainContext, statedb *state.DB, header *block.Header) error { +func MayShardReduction(bc ChainContext, statedb *state.DB, header *block.Header) error { isBeaconChain := header.ShardID() == shard.BeaconChainShardID isLastBlock := shard.Schedule.IsLastBlock(header.Number().Uint64()) - isTestnet := nodeconfig.GetDefaultConfig().GetNetworkType() == nodeconfig.Testnet - if !(isTestnet && isBeaconChain && isLastBlock) { + networkType := nodeconfig.GetDefaultConfig().GetNetworkType() + isTestnet := networkType == nodeconfig.Testnet + isMainnet := networkType == nodeconfig.Mainnet + isReducenet := isMainnet || isTestnet + if !(isReducenet && isBeaconChain && isLastBlock) { return nil } curInstance := shard.Schedule.InstanceForEpoch(header.Epoch()) @@ -479,6 +508,15 @@ func MayTestnetShardReduction(bc ChainContext, statedb *state.DB, header *block. for _, pubKey := range validator.SlotPubKeys { curShard := new(big.Int).Mod(pubKey.Big(), big.NewInt(int64(curNumShards))).Uint64() nextShard := new(big.Int).Mod(pubKey.Big(), big.NewInt(int64(nextNumShards))).Uint64() + // background: any editValidator transactions take effect at next epoch. + // assumption: shard reduction happens at epoch X. + // validators who wish to continue validating after the shard reduction occurs + // must have a different node running with a key from shard 0 or 1. + // this key must be added to the validator during epoch X - 1 + // and keys belonging to shards 2 and 3 removed at that point in time. + // the different node running will be unelected, but continue syncing in X - 1. + // if elected, it will start validating in epoch X. + // once epoch X begins, they can terminate servers from shards 2 and 3. if curShard >= uint64(nextNumShards) || curShard != nextShard { validator.Status = effective.Inactive break @@ -488,3 +526,165 @@ func MayTestnetShardReduction(bc ChainContext, statedb *state.DB, header *block. statedb.IntermediateRoot(bc.Config().IsS3(header.Epoch())) return nil } + +func MayBalanceMigration( + gasPool *GasPool, + header *block.Header, + db *state.DB, + chain BlockChain, +) (*types.CXReceipt, error) { + config := chain.Config() + isMainnet := nodeconfig.GetDefaultConfig().GetNetworkType() == nodeconfig.Mainnet + if isMainnet { + if config.IsOneEpochBeforeHIP30(header.Epoch()) { + nxtShards := shard.Schedule.InstanceForEpoch( + new(big.Int).Add(header.Epoch(), common.Big1), + ).NumShards() + if myShard := chain.ShardID(); myShard >= nxtShards { + // i need to send my balances to the destination shard + // however, i do not know when the next epoch will begin + // because only shard 0 can govern that + // so i will just generate one cross shard transaction + // in each block of the epoch. this epoch is defined by + // nxtShards = 2 and curShards = 4 + parentRoot := chain.GetBlockByHash( + header.ParentHash(), + ).Root() // for examining MPT at this root, should exist + cx, err := generateOneMigrationMessage( + db, parentRoot, + header.NumberU64(), + myShard, uint32(1), // dstShard is always 1 + ) + if err != nil { + return nil, err + } + if cx != nil { + gasPool.SubGas(params.TxGasXShard) + return cx, nil + } + // both err and cx are nil, which means we + // ran out of eligible accounts in MPT + return nil, ErrNoMigrationPossible + } + } + } + // for testing balance migration on testnet + isTestnet := nodeconfig.GetDefaultConfig().GetNetworkType() == nodeconfig.Testnet + // for testing balance migration on devnet + isDevnet := nodeconfig.GetDefaultConfig().GetNetworkType() == nodeconfig.Partner + isLocalnet := nodeconfig.GetDefaultConfig().GetNetworkType() == nodeconfig.Localnet + if isDevnet || isLocalnet || isTestnet { + if config.IsOneEpochBeforeHIP30(header.Epoch()) { + if myShard := chain.ShardID(); myShard != shard.BeaconChainShardID { + parentRoot := chain.GetBlockByHash( + header.ParentHash(), + ).Root() // for examining MPT at this root, should exist + // for examining MPT at this root, should exist + cx, err := generateOneMigrationMessage( + db, parentRoot, + header.NumberU64(), + myShard, shard.BeaconChainShardID, // dstShard + ) + if err != nil { + return nil, errors.Wrap(err, "generateOneMigrationMessage") + } + if cx != nil { + gasPool.SubGas(params.TxGasXShard) + return cx, nil + } + //return nil, errors.Wrap(ErrNoMigrationPossible, "MayBalanceMigration: cx is nil") + return nil, nil + } + } + } + + return nil, ErrNoMigrationRequired +} + +func generateOneMigrationMessage( + statedb *state.DB, + parentRoot common.Hash, + number uint64, + myShard uint32, + dstShard uint32, +) (*types.CXReceipt, error) { + // set up txHash prefix + txHash := make([]byte, + // 8 for uint64 block number + // 4 for uint32 shard id + 8+4, + ) + binary.LittleEndian.PutUint64(txHash[:8], number) + binary.LittleEndian.PutUint32(txHash[8:], myShard) + // open the trie, as of previous block. + // in this block we aren't processing transactions anyway. + trie, err := statedb.Database().OpenTrie( + parentRoot, + ) + if err != nil { + return nil, err + } + // disk db, for use by rawdb + // this is same as blockchain.ChainDb + db := statedb.Database().DiskDB() + // start the iteration + accountIterator := trie.NodeIterator(nil) + // TODO: cache this iteration? + for accountIterator.Next(true) { + // leaf means leaf node of the MPT, which is an account + // the leaf key is the address + if accountIterator.Leaf() { + key := accountIterator.LeafKey() + preimage := rawdb.ReadPreimage(db, common.BytesToHash(key)) + if len(preimage) == 0 { + return nil, errors.New( + fmt.Sprintf( + "cannot find preimage for %x", key, + ), + ) + } + address := common.BytesToAddress(preimage) + // skip blank address + if address == (common.Address{}) { + continue + } + // deserialize + var account state.Account + if err = rlp.DecodeBytes(accountIterator.LeafBlob(), &account); err != nil { + return nil, err + } + // skip contracts + if common.BytesToHash(account.CodeHash) != state.EmptyCodeHash { + continue + } + // skip anything with storage + if account.Root != state.EmptyRootHash { + continue + } + // skip no (or negative?) balance + if account.Balance.Cmp(common.Big0) <= 0 { + continue + } + // for safety, fetch the latest balance (again) + balance := statedb.GetBalance(address) + if balance.Cmp(common.Big0) <= 0 { + continue + } + // adds a journal entry (dirtied) + statedb.SubBalance(address, balance) + // create the receipt + res := &types.CXReceipt{ + From: address, + To: &address, + ShardID: myShard, + ToShardID: dstShard, + Amount: balance, + TxHash: common.BytesToHash(txHash), + } + // move from dirty to pending, same as b/w 2 txs + statedb.Finalise(true) + return res, nil + } + } + return nil, nil +} diff --git a/core/state_transition.go b/core/state_transition.go index 9684812cbb..27c3590745 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -40,7 +40,7 @@ var ( errNoDelegationToUndelegate = errors.New("no delegation to undelegate") errCommissionRateChangeTooFast = errors.New("change on commission rate can not be more than max change rate within the same epoch") errCommissionRateChangeTooHigh = errors.New("commission rate can not be higher than maximum commission rate") - errCommissionRateChangeTooLow = errors.New("commission rate can not be lower than min rate of 5%") + errCommissionRateChangeTooLowT = errors.New("commission rate can not be lower than min rate of ") errNoRewardsToCollect = errors.New("no rewards to collect") errNegativeAmount = errors.New("amount can not be negative") errDupIdentity = errors.New("validator identity exists") @@ -76,7 +76,6 @@ type StateTransition struct { data []byte state vm.StateDB evm *vm.EVM - bc ChainContext } // Message represents a message sent to a contract. @@ -131,7 +130,7 @@ func (result *ExecutionResult) Revert() []byte { } // NewStateTransition initialises and returns a new state transition object. -func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool, bc ChainContext) *StateTransition { +func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition { return &StateTransition{ gp: gp, evm: evm, @@ -140,7 +139,6 @@ func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool, bc ChainContext) value: msg.Value(), data: msg.Data(), state: evm.StateDB, - bc: bc, } } @@ -152,12 +150,12 @@ func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool, bc ChainContext) // indicates a core error meaning that the message would always fail for that particular // state and would never be accepted within a block. func ApplyMessage(evm *vm.EVM, msg Message, gp *GasPool) (ExecutionResult, error) { - return NewStateTransition(evm, msg, gp, nil).TransitionDb() + return NewStateTransition(evm, msg, gp).TransitionDb() } // ApplyStakingMessage computes the new state for staking message -func ApplyStakingMessage(evm *vm.EVM, msg Message, gp *GasPool, bc ChainContext) (uint64, error) { - return NewStateTransition(evm, msg, gp, bc).StakingTransitionDb() +func ApplyStakingMessage(evm *vm.EVM, msg Message, gp *GasPool) (uint64, error) { + return NewStateTransition(evm, msg, gp).StakingTransitionDb() } // to returns the recipient of the message. diff --git a/core/state_transition_test.go b/core/state_transition_test.go index 2a335ef779..665549f9d9 100644 --- a/core/state_transition_test.go +++ b/core/state_transition_test.go @@ -76,7 +76,7 @@ func testApplyStakingMessage(test applyStakingMessageTest, t *testing.T) { vmenv := vm.NewEVM(ctx, db, params.TestChainConfig, vm.Config{}) // run the staking tx - _, err := ApplyStakingMessage(vmenv, msg, gp, chain) + _, err := ApplyStakingMessage(vmenv, msg, gp) if err != nil { if test.expectedError == nil { t.Errorf(fmt.Sprintf("Got error %v but expected none", err)) @@ -193,7 +193,7 @@ func TestCollectGasRounding(t *testing.T) { vmenv := vm.NewEVM(ctx, db, params.TestChainConfig, vm.Config{}) gasPool := new(GasPool).AddGas(math.MaxUint64) - st := NewStateTransition(vmenv, msg, gasPool, nil) + st := NewStateTransition(vmenv, msg, gasPool) // buy gas to set initial gas to 5: gasLimit * gasPrice if err := st.buyGas(); err != nil { t.Fatal(err) diff --git a/core/tx_pool_test.go b/core/tx_pool_test.go index 4e1c214b1a..0d1dfbd2b9 100644 --- a/core/tx_pool_test.go +++ b/core/tx_pool_test.go @@ -19,7 +19,6 @@ package core import ( "crypto/ecdsa" "fmt" - "io/ioutil" "math/big" "math/rand" "os" @@ -1354,7 +1353,7 @@ func testTransactionJournaling(t *testing.T, nolocals bool) { t.Parallel() // Create a temporary file for the journal - file, err := ioutil.TempFile("", "") + file, err := os.CreateTemp("", "") if err != nil { t.Fatalf("failed to create temporary journal: %v", err) } diff --git a/core/types.go b/core/types.go index b613a1f373..4dfd24164f 100644 --- a/core/types.go +++ b/core/types.go @@ -40,10 +40,6 @@ type Validator interface { // via the VerifySeal method. ValidateHeader(block *types.Block, seal bool) error - // ValidateHeaders verifies a batch of blocks' headers concurrently. The method returns a quit channel - // to abort the operations and a results channel to retrieve the async verifications - ValidateHeaders(chain []*types.Block) (chan<- struct{}, <-chan error) - // ValidateCXReceiptsProof checks whether the given CXReceiptsProof is consistency with itself ValidateCXReceiptsProof(cxp *types.CXReceiptsProof) error } diff --git a/core/vm/instructions_test.go b/core/vm/instructions_test.go index f2666c2f39..634b5c9276 100644 --- a/core/vm/instructions_test.go +++ b/core/vm/instructions_test.go @@ -20,8 +20,8 @@ import ( "bytes" "encoding/json" "fmt" - "io/ioutil" "math/big" + "os" "testing" "github.com/ethereum/go-ethereum/common" @@ -240,7 +240,7 @@ func TestWriteExpectedValues(t *testing.T) { if err != nil { t.Fatal(err) } - _ = ioutil.WriteFile(fmt.Sprintf("testdata/testcases_%v.json", name), data, 0644) + _ = os.WriteFile(fmt.Sprintf("testdata/testcases_%v.json", name), data, 0644) if err != nil { t.Fatal(err) } @@ -250,7 +250,7 @@ func TestWriteExpectedValues(t *testing.T) { // TestJsonTestcases runs through all the testcases defined as json-files func TestJsonTestcases(t *testing.T) { for name := range twoOpMethods { - data, err := ioutil.ReadFile(fmt.Sprintf("testdata/testcases_%v.json", name)) + data, err := os.ReadFile(fmt.Sprintf("testdata/testcases_%v.json", name)) if err != nil { t.Fatal("Failed to read file", err) } diff --git a/core_test/shardchain_test.go b/core_test/shardchain_test.go index 36a32f5433..a6a9238bab 100644 --- a/core_test/shardchain_test.go +++ b/core_test/shardchain_test.go @@ -1,7 +1,6 @@ package core_test import ( - "fmt" "testing" "github.com/ethereum/go-ethereum/common" @@ -48,7 +47,10 @@ func TestAddNewBlock(t *testing.T) { if err != nil { t.Fatal("cannot get blockchain") } - reg := registry.New().SetBlockchain(blockchain) + reg := registry.New(). + SetBlockchain(blockchain). + SetEngine(engine). + SetShardChainCollection(collection) consensus, err := consensus.New( host, shard.BeaconChainShardID, multibls.GetPrivateKeys(blsKey), reg, decider, 3, false, ) @@ -57,7 +59,7 @@ func TestAddNewBlock(t *testing.T) { } nodeconfig.SetNetworkType(nodeconfig.Testnet) var block *types.Block - node := node.New(host, consensus, engine, collection, nil, nil, nil, nil, nil, reg) + node := node.New(host, consensus, nil, nil, nil, nil, reg) commitSigs := make(chan []byte, 1) commitSigs <- []byte{} block, err = node.Worker.FinalizeNewBlock( @@ -73,8 +75,8 @@ func TestAddNewBlock(t *testing.T) { _, err = blockchain.InsertChain([]*types.Block{block}, false) require.NoError(t, err, "error when adding new block") - pk, epoch, count, shifts, err := blockchain.LeaderRotationMeta() - fmt.Println("pk", pk, "epoch", epoch, "count", count, "shifts", shifts, "err", err) + meta := blockchain.LeaderRotationMeta() + require.NotEmptyf(t, meta, "error when getting leader rotation meta") t.Log("#", block.Header().NumberU64(), node.Blockchain().CurrentBlock().NumberU64(), block.Hash().Hex(), block.ParentHash()) diff --git a/crypto/bls/bls.go b/crypto/bls/bls.go index 54916278be..7a8159ef87 100644 --- a/crypto/bls/bls.go +++ b/crypto/bls/bls.go @@ -64,6 +64,11 @@ type SerializedPublicKey [PublicKeySizeInBytes]byte // SerializedSignature defines the bls signature type SerializedSignature [BLSSignatureSizeInBytes]byte +// Bytes returns the byte array of bls signature +func (pk SerializedPublicKey) Bytes() []byte { + return pk[:] +} + // Big .. func (pk SerializedPublicKey) Big() *big.Int { return new(big.Int).SetBytes(pk[:]) diff --git a/eth/rpc/gzip.go b/eth/rpc/gzip.go index a14fd09d54..4e456a2b66 100644 --- a/eth/rpc/gzip.go +++ b/eth/rpc/gzip.go @@ -19,7 +19,6 @@ package rpc import ( "compress/gzip" "io" - "io/ioutil" "net/http" "strings" "sync" @@ -27,7 +26,7 @@ import ( var gzPool = sync.Pool{ New: func() interface{} { - w := gzip.NewWriter(ioutil.Discard) + w := gzip.NewWriter(io.Discard) return w }, } diff --git a/eth/rpc/http.go b/eth/rpc/http.go index 0de127c808..0dba651e59 100644 --- a/eth/rpc/http.go +++ b/eth/rpc/http.go @@ -23,7 +23,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "mime" "net" "net/http" @@ -172,7 +171,7 @@ func (hc *httpConn) doRequest(ctx context.Context, msg interface{}) (io.ReadClos return nil, err } req := hc.req.WithContext(ctx) - req.Body = ioutil.NopCloser(bytes.NewReader(body)) + req.Body = io.NopCloser(bytes.NewReader(body)) req.ContentLength = int64(len(body)) resp, err := hc.client.Do(req) diff --git a/eth/rpc/method_filter.go b/eth/rpc/method_filter.go index 0cc8b3cdd5..4fbbeb7a9c 100644 --- a/eth/rpc/method_filter.go +++ b/eth/rpc/method_filter.go @@ -3,7 +3,6 @@ package rpc import ( "errors" "fmt" - "io/ioutil" "os" "regexp" "strings" @@ -32,7 +31,7 @@ Deny = [ ... ] func (rmf *RpcMethodFilter) LoadRpcMethodFiltersFromFile(file string) error { // check if file exist if _, err := os.Stat(file); err == nil { - b, errRead := ioutil.ReadFile(file) + b, errRead := os.ReadFile(file) if errRead != nil { return fmt.Errorf("rpc filter file read error - %s", errRead.Error()) } diff --git a/eth/rpc/server_test.go b/eth/rpc/server_test.go index 9002f6dc23..1c32aad989 100644 --- a/eth/rpc/server_test.go +++ b/eth/rpc/server_test.go @@ -20,8 +20,8 @@ import ( "bufio" "bytes" "io" - "io/ioutil" "net" + "os" "path/filepath" "strings" "testing" @@ -52,7 +52,7 @@ func TestServerRegisterName(t *testing.T) { } func TestServer(t *testing.T) { - files, err := ioutil.ReadDir("testdata") + files, err := os.ReadDir("testdata") if err != nil { t.Fatal("where'd my testdata go?") } @@ -70,7 +70,7 @@ func TestServer(t *testing.T) { func runTestScript(t *testing.T, file string) { server := newTestServer() - content, err := ioutil.ReadFile(file) + content, err := os.ReadFile(file) if err != nil { t.Fatal(err) } diff --git a/go.mod b/go.mod index 32ac5feea0..8644ba7bd4 100644 --- a/go.mod +++ b/go.mod @@ -29,10 +29,10 @@ require ( github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d github.com/ipfs/go-ds-badger v0.3.0 github.com/json-iterator/go v1.1.12 - github.com/libp2p/go-libp2p v0.24.0 - github.com/libp2p/go-libp2p-kad-dht v0.19.0 - github.com/libp2p/go-libp2p-pubsub v0.8.2 - github.com/multiformats/go-multiaddr v0.8.0 + github.com/libp2p/go-libp2p v0.27.9 + github.com/libp2p/go-libp2p-kad-dht v0.21.0 + github.com/libp2p/go-libp2p-pubsub v0.9.3 + github.com/multiformats/go-multiaddr v0.9.0 github.com/multiformats/go-multiaddr-dns v0.3.1 github.com/natefinch/lumberjack v2.0.0+incompatible github.com/pborman/uuid v1.2.0 @@ -71,7 +71,6 @@ require ( github.com/holiman/bloomfilter/v2 v2.0.3 github.com/ledgerwatch/erigon-lib v0.0.0-20230607152933-42c9c28cac68 github.com/ledgerwatch/log/v3 v3.8.0 - github.com/libp2p/go-libp2p-core v0.20.1 github.com/olekukonko/tablewriter v0.0.5 ) @@ -93,7 +92,7 @@ require ( github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/pebble v0.0.0-20230302152029-717cbce0c2e3 // indirect github.com/cockroachdb/redact v1.1.3 // indirect - github.com/containerd/cgroups v1.0.4 // indirect + github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect github.com/deckarep/golang-set/v2 v2.3.0 // indirect @@ -115,7 +114,7 @@ require ( github.com/go-lintpack/lintpack v0.5.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-stack/stack v1.8.1 // indirect - github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect + github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect github.com/go-toolsmith/astcast v1.0.0 // indirect github.com/go-toolsmith/astcopy v1.0.0 // indirect github.com/go-toolsmith/astequal v1.0.0 // indirect @@ -144,18 +143,19 @@ require ( github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect github.com/google/btree v1.1.2 // indirect github.com/google/gopacket v1.1.19 // indirect - github.com/google/pprof v0.0.0-20221203041831-ce31453925ec // indirect + github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b // indirect github.com/google/uuid v1.3.0 // indirect github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.2 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e // indirect github.com/holiman/uint256 v1.2.2 // indirect - github.com/huin/goupnp v1.0.3 // indirect + github.com/huin/goupnp v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect - github.com/ipfs/go-cid v0.3.2 // indirect + github.com/ipfs/go-cid v0.4.1 // indirect github.com/ipfs/go-datastore v0.6.0 // indirect github.com/ipfs/go-ipfs-util v0.0.2 // indirect github.com/ipfs/go-ipns v0.2.0 // indirect @@ -167,37 +167,30 @@ require ( github.com/jbenet/goprocess v0.1.4 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/kisielk/gotool v1.0.0 // indirect - github.com/klauspost/compress v1.16.0 // indirect - github.com/klauspost/cpuid/v2 v2.2.1 // indirect - github.com/koron/go-ssdp v0.0.3 // indirect + github.com/klauspost/compress v1.16.4 // indirect + github.com/klauspost/cpuid/v2 v2.2.4 // indirect + github.com/koron/go-ssdp v0.0.4 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect - github.com/ledgerwatch/interfaces v0.0.0-20230602104541-cdc6e215fb3e // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-flow-metrics v0.1.0 // indirect - github.com/libp2p/go-libp2p-asn-util v0.2.0 // indirect + github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect github.com/libp2p/go-libp2p-kbucket v0.5.0 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect - github.com/libp2p/go-msgio v0.2.0 // indirect + github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-nat v0.1.0 // indirect github.com/libp2p/go-netroute v0.2.1 // indirect - github.com/libp2p/go-openssl v0.1.0 // indirect github.com/libp2p/go-reuseport v0.2.0 // indirect github.com/libp2p/go-yamux/v4 v4.0.0 // indirect - github.com/lucas-clemente/quic-go v0.31.0 // indirect github.com/magiconair/properties v1.8.6 // indirect - github.com/marten-seemann/qtls-go1-18 v0.1.3 // indirect - github.com/marten-seemann/qtls-go1-19 v0.1.1 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb // indirect - github.com/matryer/moq v0.3.1 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.17 // indirect - github.com/mattn/go-pointer v0.0.1 // indirect + github.com/mattn/go-isatty v0.0.18 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/miekg/dns v1.1.50 // indirect + github.com/miekg/dns v1.1.53 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/sha256-simd v1.0.0 // indirect @@ -210,13 +203,13 @@ require ( github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect - github.com/multiformats/go-multibase v0.1.1 // indirect - github.com/multiformats/go-multicodec v0.7.0 // indirect + github.com/multiformats/go-multibase v0.2.0 // indirect + github.com/multiformats/go-multicodec v0.8.1 // indirect github.com/multiformats/go-multihash v0.2.1 // indirect - github.com/multiformats/go-multistream v0.3.3 // indirect + github.com/multiformats/go-multistream v0.4.1 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d // indirect - github.com/onsi/ginkgo/v2 v2.5.1 // indirect + github.com/onsi/ginkgo/v2 v2.9.2 // indirect github.com/opencontainers/runtime-spec v1.0.2 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect @@ -228,10 +221,14 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e // indirect github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.41.0 // indirect + github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/prometheus/tsdb v0.10.0 // indirect - github.com/quasilyte/go-ruleguard/dsl v0.3.22 // indirect + github.com/quic-go/qpack v0.4.0 // indirect + github.com/quic-go/qtls-go1-19 v0.3.3 // indirect + github.com/quic-go/qtls-go1-20 v0.2.3 // indirect + github.com/quic-go/quic-go v0.33.1 // indirect + github.com/quic-go/webtransport-go v0.5.2 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rivo/uniseg v0.4.4 // indirect github.com/rogpeppe/go-internal v1.9.0 // indirect @@ -239,7 +236,6 @@ require ( github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/sirupsen/logrus v1.9.0 // indirect github.com/sourcegraph/go-diff v0.5.1 // indirect - github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/spf13/afero v1.9.2 // indirect github.com/spf13/cast v1.5.0 // indirect @@ -263,15 +259,14 @@ require ( github.com/yusufpapurcu/wmi v1.2.2 // indirect go.opencensus.io v0.24.0 // indirect go.uber.org/atomic v1.10.0 // indirect - go.uber.org/dig v1.15.0 // indirect - go.uber.org/fx v1.18.2 // indirect - go.uber.org/multierr v1.8.0 // indirect + go.uber.org/dig v1.16.1 // indirect + go.uber.org/fx v1.19.2 // indirect + go.uber.org/multierr v1.11.0 // indirect golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect golang.org/x/mod v0.10.0 // indirect golang.org/x/term v0.8.0 // indirect golang.org/x/text v0.9.0 // indirect google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect - google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect @@ -280,6 +275,7 @@ require ( mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f // indirect + nhooyr.io/websocket v1.8.7 // indirect sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4 // indirect ) diff --git a/go.sum b/go.sum index 51be04743c..d5200066de 100644 --- a/go.sum +++ b/go.sum @@ -88,8 +88,6 @@ github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrU github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw= github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= -github.com/VictoriaMetrics/metrics v1.23.0 h1:WzfqyzCaxUZip+OBbg1+lV33WChDSu4ssYII3nxtpeA= -github.com/VictoriaMetrics/metrics v1.23.0/go.mod h1:rAr/llLpEnAdTehiNlUxKgnjcOuROSzpw0GvjpEbvFc= github.com/VictoriaMetrics/metrics v1.23.1 h1:/j8DzeJBxSpL2qSIdqnRFLvQQhbJyJbbEi22yMm7oL0= github.com/VictoriaMetrics/metrics v1.23.1/go.mod h1:rAr/llLpEnAdTehiNlUxKgnjcOuROSzpw0GvjpEbvFc= github.com/Workiva/go-datastructures v1.0.50 h1:slDmfW6KCHcC7U+LP3DDBbm4fqTwZGn1beOFPfGaLvo= @@ -140,8 +138,6 @@ 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/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= -github.com/bits-and-blooms/bitset v1.2.2 h1:J5gbX05GpMdBjCvQ9MteIg2KKDExr7DrgK+Yc15FvIk= -github.com/bits-and-blooms/bitset v1.2.2/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bits-and-blooms/bitset v1.5.0 h1:NpE8frKRLGHIcEzkR+gZhiioW1+WbYV6fKwD6ZIpQT8= github.com/bits-and-blooms/bitset v1.5.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= @@ -189,7 +185,6 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927/go.mod h1:h/aW8ynjgkuj+NQRlZcDbAbM1ORAbXjXX77sX7T289U= 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= @@ -228,8 +223,8 @@ github.com/coinbase/rosetta-sdk-go v0.7.0/go.mod h1:7nD3oBPIiHqhRprqvMgPoGxe/nyq github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= github.com/consensys/gnark-crypto v0.9.1-0.20230105202408-1a7a29904a7c/go.mod h1:CkbdF9hbRidRJYMRzmfX8TMOr95I2pYXRHF18MzRrvA= github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= -github.com/containerd/cgroups v1.0.4 h1:jN/mbWBEaz+T1pi5OFtnkQ+8qnmEbAr1Oo1FRm5B0dA= -github.com/containerd/cgroups v1.0.4/go.mod h1:nLNQtsF7Sl2HxNebu77i1R0oDlhiTG+kO4JTrUzo6IA= +github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= +github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= @@ -262,7 +257,6 @@ github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4= github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= -github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/deckarep/golang-set/v2 v2.3.0 h1:qs18EKUfHm2X9fA50Mr/M5hccg2tNnVqsiBImnyDs0g= github.com/deckarep/golang-set/v2 v2.3.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= @@ -363,8 +357,11 @@ github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnR github.com/ghemawat/stream v0.0.0-20171120220530-696b145b53b9/go.mod h1:106OIgooyS7OzLDOpUGgm9fA3bQENb/cFSyyBmMoJDs= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= 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= @@ -401,9 +398,15 @@ github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiU github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= +github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= @@ -414,8 +417,9 @@ github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LB github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g= github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= github.com/go-toolsmith/astcopy v1.0.0 h1:OMgl1b1MEpjFQ1m5ztEO06rz5CUd3oBv9RF7+DyvdG8= @@ -440,12 +444,16 @@ github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2 github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/gobwas/ws v1.1.0 h1:7RFti/xnNkMJnrK7D1yQ/iCIB5OrrY/54/H930kIbHA= github.com/gobwas/ws v1.1.0/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk= github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -503,7 +511,6 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= @@ -590,8 +597,8 @@ github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20221203041831-ce31453925ec h1:fR20TYVVwhK4O7r7y+McjRYyaTH6/vjwJOajE+XhlzM= -github.com/google/pprof v0.0.0-20221203041831-ce31453925ec/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= +github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b h1:Qcx5LM0fSiks9uCyFZwDBUasd3lxd1RM0GYpL+Li5o4= +github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -622,8 +629,6 @@ github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLt github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= @@ -664,6 +669,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru/v2 v2.0.2 h1:Dwmkdr5Nc/oBiXgJS3CDHNhJtIHkuZ3DZF5twqnfBdU= +github.com/hashicorp/golang-lru/v2 v2.0.2/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= @@ -675,14 +682,13 @@ github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e/go.mod h1:j9cQbcqHQujT github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= -github.com/holiman/uint256 v1.2.1 h1:XRtyuda/zw2l+Bq/38n5XUoEF72aSOu/77Thd9pPp2o= -github.com/holiman/uint256 v1.2.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= github.com/holiman/uint256 v1.2.2 h1:TXKcSGc2WaxPD2+bmzAsVthL4+pEN0YwXcL5qED83vk= github.com/holiman/uint256 v1.2.2/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= -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/goupnp v1.1.0 h1:gEe0Dp/lZmPZiDFzJJaOfUpOvv2MKUkoBX8lDrn9vKU= +github.com/huin/goupnp v1.1.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= @@ -702,8 +708,8 @@ github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19y github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE= github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0= github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po= -github.com/ipfs/go-cid v0.3.2 h1:OGgOd+JCFM+y1DjWPmVH+2/4POtpDzwcr7VgnB7mZXc= -github.com/ipfs/go-cid v0.3.2/go.mod h1:gQ8pKqT/sUxGY+tIwy1RPpAojYu7jAyCp5Tz1svoupw= +github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= +github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= github.com/ipfs/go-datastore v0.5.0/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk= github.com/ipfs/go-datastore v0.6.0 h1:JKyz+Gvz1QEZw0LsX1IBn+JFCJQH4SJVFtM4uWU0Myk= github.com/ipfs/go-datastore v0.6.0/go.mod h1:rt5M3nNbSO/8q1t4LNkLyUwRs8HupMeN/8O4Vn9YAT8= @@ -803,29 +809,30 @@ github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0 github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.14.4/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.10/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= -github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= -github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.16.4 h1:91KN02FnsOYhuunwU4ssRe8lc2JosWmizWa91B5v1PU= +github.com/klauspost/compress v1.16.4/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.1 h1:U33DW0aiEj633gHYw3LoDNfkDiYnE5Q8M/TKJn2f2jI= -github.com/klauspost/cpuid/v2 v2.2.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= +github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= +github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= 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/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= -github.com/koron/go-ssdp v0.0.3 h1:JivLMY45N76b4p/vsWGOKewBQu6uf39y8l+AQ7sDKx8= -github.com/koron/go-ssdp v0.0.3/go.mod h1:b2MxI6yh02pKrsyNoQUsk4+YNikaGhe4894J+Q5lDvA= +github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= +github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= 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= @@ -849,16 +856,12 @@ github.com/labstack/echo/v4 v4.9.0/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20L github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20221218022306-0f8fdd40c2db h1:wV9YkkYQArbUdTdlPxXi5BW6H9ovYbyUT8Af7foetvQ= -github.com/ledgerwatch/erigon-lib v0.0.0-20221218022306-0f8fdd40c2db/go.mod h1:5GCPOzxAshLF7f0wrMZu2Bdq0qqIiMcIubM9n+25gGo= github.com/ledgerwatch/erigon-lib v0.0.0-20230607152933-42c9c28cac68 h1:eKTHu42qcMwDR2qi2KfR3cKGU6Qli7ilPwqQDsT5XL0= github.com/ledgerwatch/erigon-lib v0.0.0-20230607152933-42c9c28cac68/go.mod h1:gV87KL7+CmJ31bLSk0FbCnowHYi6w7kF8Q1vyiwttqg= -github.com/ledgerwatch/interfaces v0.0.0-20230602104541-cdc6e215fb3e h1:2tltVQCyMEk6Az7uSNRAt4S0+2rV4VJ4PCHK1f1rung= -github.com/ledgerwatch/interfaces v0.0.0-20230602104541-cdc6e215fb3e/go.mod h1:ugQv1QllJzBny3cKZKxUrSnykkjkBgm27eQM6dnGAcc= -github.com/ledgerwatch/log/v3 v3.6.0 h1:JBUSK1epPyutUrz7KYDTcJtQLEHnehECRpKbM1ugy5M= -github.com/ledgerwatch/log/v3 v3.6.0/go.mod h1:L+Sp+ma/h205EdCjviZECjGEvYUYEyXSdiuHNZzg+xQ= github.com/ledgerwatch/log/v3 v3.8.0 h1:gCpp7uGtIerEz1jKVPeDnbIopFPud9ZnCpBLlLBGqPU= github.com/ledgerwatch/log/v3 v3.8.0/go.mod h1:J2Jl6zV/58LeA6LTaVVnCGyf1/cYYSEOOLHY4ZN8S2A= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -868,38 +871,32 @@ github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38y github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.24.0 h1:DQk/5bBon+yUVIGTeRVBmOYpZzoBHx/VTC0xoLgJGG4= -github.com/libp2p/go-libp2p v0.24.0/go.mod h1:28t24CYDlnBs23rIs1OclU89YbhgibrBq2LFbMe+cFw= -github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= -github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= -github.com/libp2p/go-libp2p-core v0.20.1 h1:fQz4BJyIFmSZAiTbKV8qoYhEH5Dtv/cVhZbG3Ib/+Cw= -github.com/libp2p/go-libp2p-core v0.20.1/go.mod h1:6zR8H7CvQWgYLsbG4on6oLNSGcyKaYFSEYyDt51+bIY= -github.com/libp2p/go-libp2p-kad-dht v0.19.0 h1:2HuiInHZTm9ZvQajaqdaPLHr0PCKKigWiflakimttE0= -github.com/libp2p/go-libp2p-kad-dht v0.19.0/go.mod h1:qPIXdiZsLczhV4/+4EO1jE8ae0YCW4ZOogc4WVIyTEU= +github.com/libp2p/go-libp2p v0.27.9 h1:n5p5bQD469v7I/1qncaHDq0BeSx4iT2fHF3NyNuKOmY= +github.com/libp2p/go-libp2p v0.27.9/go.mod h1:Tdx7ZuJl9NE78PkB4FjPVbf6kaQNOh2ppU/OVvVB6Wc= +github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s= +github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w= +github.com/libp2p/go-libp2p-kad-dht v0.21.0 h1:J0Yd22VA+sk0CJRGMgtfHvLVIkZDyJ3AJGiljywIw5U= +github.com/libp2p/go-libp2p-kad-dht v0.21.0/go.mod h1:Bhm9diAFmc6qcWAr084bHNL159srVZRKADdp96Qqd1I= github.com/libp2p/go-libp2p-kbucket v0.5.0 h1:g/7tVm8ACHDxH29BGrpsQlnNeu+6OF1A9bno/4/U1oA= github.com/libp2p/go-libp2p-kbucket v0.5.0/go.mod h1:zGzGCpQd78b5BNTDGHNDLaTt9aDK/A02xeZp9QeFC4U= -github.com/libp2p/go-libp2p-pubsub v0.8.2 h1:QLGUmkgKmwEVxVDYGsqc5t9CykOMY2Y21cXQHjR462I= -github.com/libp2p/go-libp2p-pubsub v0.8.2/go.mod h1:e4kT+DYjzPUYGZeWk4I+oxCSYTXizzXii5LDRRhjKSw= +github.com/libp2p/go-libp2p-pubsub v0.9.3 h1:ihcz9oIBMaCK9kcx+yHWm3mLAFBMAUsM4ux42aikDxo= +github.com/libp2p/go-libp2p-pubsub v0.9.3/go.mod h1:RYA7aM9jIic5VV47WXu4GkcRxRhrdElWf8xtyli+Dzc= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= -github.com/libp2p/go-msgio v0.2.0 h1:W6shmB+FeynDrUVl2dgFQvzfBZcXiyqY4VmpQLu9FqU= -github.com/libp2p/go-msgio v0.2.0/go.mod h1:dBVM1gW3Jk9XqHkU4eKdGvVHdLa51hoGfll6jMJMSlY= +github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= +github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= github.com/libp2p/go-nat v0.1.0 h1:MfVsH6DLcpa04Xr+p8hmVRG4juse0s3J8HyNWYHffXg= github.com/libp2p/go-nat v0.1.0/go.mod h1:X7teVkwRHNInVNWQiO/tAiAVRwSr5zoRz4YSTC3uRBM= github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= -github.com/libp2p/go-openssl v0.1.0 h1:LBkKEcUv6vtZIQLVTegAil8jbNpJErQ9AnT+bWV+Ooo= -github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc= github.com/libp2p/go-reuseport v0.2.0 h1:18PRvIMlpY6ZK85nIAicSBuXXvrYoSw3dsBAR7zc560= github.com/libp2p/go-reuseport v0.2.0/go.mod h1:bvVho6eLMm6Bz5hmU0LYN3ixd3nPPvtIlaURZZgOY4k= github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ= github.com/libp2p/go-yamux/v4 v4.0.0/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= -github.com/lucas-clemente/quic-go v0.31.0 h1:MfNp3fk0wjWRajw6quMFA3ap1AVtlU+2mtwmbVogB2M= -github.com/lucas-clemente/quic-go v0.31.0/go.mod h1:0wFbizLgYzqHqtlyxyCaJKlE7bYgE6JQ+54TLd/Dq2g= github.com/lucasjones/reggen v0.0.0-20180717132126-cdb49ff09d77/go.mod h1:5ELEyG+X8f+meRWHuqUOewBOhvHkl7M76pdGEansxW4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= @@ -913,21 +910,11 @@ github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/marten-seemann/qpack v0.3.0 h1:UiWstOgT8+znlkDPOg2+3rIuYXJ2CnGDkGUXN6ki6hE= -github.com/marten-seemann/qtls-go1-16 v0.1.5/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk= -github.com/marten-seemann/qtls-go1-17 v0.1.2/go.mod h1:C2ekUKcDdz9SDWxec1N/MvcXBpaX9l3Nx67XaR84L5s= -github.com/marten-seemann/qtls-go1-18 v0.1.3 h1:R4H2Ks8P6pAtUagjFty2p7BVHn3XiwDAl7TTQf5h7TI= -github.com/marten-seemann/qtls-go1-18 v0.1.3/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4= -github.com/marten-seemann/qtls-go1-19 v0.1.1 h1:mnbxeq3oEyQxQXwI4ReCgW9DPoPR94sNlqWoDZnjRIE= -github.com/marten-seemann/qtls-go1-19 v0.1.1/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= -github.com/marten-seemann/webtransport-go v0.4.1 h1:8Ir7OoAvtp79yxQpa3foTKIPuoH+0eKpisHObJyu9Sk= github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb h1:RHba4YImhrUVQDHUCe2BNSOz4tVy2yGyXhvYDvxGgeE= github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= -github.com/matryer/moq v0.3.1 h1:kLDiBJoGcusWS2BixGyTkF224aSCD8nLY24tj/NcTCs= -github.com/matryer/moq v0.3.1/go.mod h1:RJ75ZZZD71hejp39j4crZLsEDszGk6iH4v4YsWFKH4s= github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2/go.mod h1:0KeJpeMD6o+O4hW7qJOT7vyQPKrWmj26uf5wMc/IiIs= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -946,12 +933,10 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= -github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= +github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= +github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= @@ -973,8 +958,8 @@ github.com/microcosm-cc/bluemonday v1.0.20/go.mod h1:yfBmMi8mxvaZut3Yytv+jTXRY8m github.com/microcosm-cc/bluemonday v1.0.21/go.mod h1:ytNkv4RrDrLJ2pqlsSI46O6IVXmZOBBD4SaJyDwwTkM= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= -github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= +github.com/miekg/dns v1.1.53 h1:ZBkuHr5dxHtB1caEOlZTLPo7D3L3TWckgUUs/RHfDxw= +github.com/miekg/dns v1.1.53/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -1027,22 +1012,22 @@ github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9 github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.8.0 h1:aqjksEcqK+iD/Foe1RRFsGZh8+XFiGo7FgUCZlpv3LU= -github.com/multiformats/go-multiaddr v0.8.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs= +github.com/multiformats/go-multiaddr v0.9.0 h1:3h4V1LHIk5w4hJHekMKWALPXErDfz/sggzwC/NcqbDQ= +github.com/multiformats/go-multiaddr v0.9.0/go.mod h1:mI67Lb1EeTOYb8GQfL/7wpIZwc46ElrvzhYnoJOmTT0= github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= -github.com/multiformats/go-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI= -github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8= -github.com/multiformats/go-multicodec v0.7.0 h1:rTUjGOwjlhGHbEMbPoSUJowG1spZTVsITRANCjKTUAQ= -github.com/multiformats/go-multicodec v0.7.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw= +github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= +github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= +github.com/multiformats/go-multicodec v0.8.1 h1:ycepHwavHafh3grIbR1jIXnKCsFm0fqsfEOsJ8NtKE8= +github.com/multiformats/go-multicodec v0.8.1/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d16Vve9l108= github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= -github.com/multiformats/go-multistream v0.3.3 h1:d5PZpjwRgVlbwfdTDjife7XszfZd8KYWfROYFlGcR8o= -github.com/multiformats/go-multistream v0.3.3/go.mod h1:ODRoqamLUsETKS9BNcII4gcRsJBU5VAwRIv7O39cEXg= +github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= +github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= @@ -1089,8 +1074,8 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.5.1 h1:auzK7OI497k6x4OvWq+TKAcpcSAlod0doAH72oIN0Jw= -github.com/onsi/ginkgo/v2 v2.5.1/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc= +github.com/onsi/ginkgo/v2 v2.9.2 h1:BA2GMJOtfGAfagzYtrAlufIP0lq6QERkFmHLMLPwFSU= +github.com/onsi/ginkgo/v2 v2.9.2/go.mod h1:WHcJJG2dIlcCqVfBAwUCrJxSPFb6v4azBwgxeMeDuts= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -1098,7 +1083,7 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= -github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg= +github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E= github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -1181,8 +1166,8 @@ github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9 github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y= -github.com/prometheus/common v0.41.0 h1:npo01n6vUlRViIj5fgwiK8vlNIh8bnoxqh3gypKsyAw= -github.com/prometheus/common v0.41.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= +github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= @@ -1197,8 +1182,16 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T github.com/prometheus/tsdb v0.10.0 h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38ic= github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4= github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= -github.com/quasilyte/go-ruleguard/dsl v0.3.22 h1:wd8zkOhSNr+I+8Qeciml08ivDt1pSXe60+5DqOpCjPE= -github.com/quasilyte/go-ruleguard/dsl v0.3.22/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= +github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= +github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= +github.com/quic-go/qtls-go1-19 v0.3.3 h1:wznEHvJwd+2X3PqftRha0SUKmGsnb6dfArMhy9PeJVE= +github.com/quic-go/qtls-go1-19 v0.3.3/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= +github.com/quic-go/qtls-go1-20 v0.2.3 h1:m575dovXn1y2ATOb1XrRFcrv0F+EQmlowTkoraNkDPI= +github.com/quic-go/qtls-go1-20 v0.2.3/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= +github.com/quic-go/quic-go v0.33.1 h1:EVsG7O/7FVZI8Za71GzpHDoWpBTKdjDv1/x0KFcckho= +github.com/quic-go/quic-go v0.33.1/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= +github.com/quic-go/webtransport-go v0.5.2 h1:GA6Bl6oZY+g/flt00Pnu0XtivSD8vukOu3lYhJjnGEk= +github.com/quic-go/webtransport-go v0.5.2/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ= @@ -1294,8 +1287,6 @@ github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:Udh github.com/sourcegraph/go-diff v0.5.1 h1:gO6i5zugwzo1RVTvgvfwCOSVegNuvnNi6bAD1QCmkHs= github.com/sourcegraph/go-diff v0.5.1/go.mod h1:j2dHj3m8aZgQO8lMTcTnBcXkRRRqi34cd2MNlA9u1mE= github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= -github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= -github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -1344,7 +1335,6 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= @@ -1382,8 +1372,6 @@ github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tommy-muehle/go-mnd v1.1.1 h1:4D0wuPKjOTiK2garzuPGGvm4zZ/wLYDOH8TJSABC7KU= github.com/tommy-muehle/go-mnd v1.1.1/go.mod h1:dSUh0FtTP8VhvkL1S+gUR1OKd9ZnSaozuI6r3m6wOig= -github.com/torquem-ch/mdbx-go v0.27.0 h1:FquhRvKL2zweMdk1R6UdOx3h6DiHgJ0+P9yQvSouURI= -github.com/torquem-ch/mdbx-go v0.27.0/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= github.com/torquem-ch/mdbx-go v0.27.10 h1:iwb8Wn9gse4MEYIltAna+pxMPCY7hA1/5LLN/Qrcsx0= github.com/torquem-ch/mdbx-go v0.27.10/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= github.com/twmb/murmur3 v1.1.3/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ= @@ -1392,9 +1380,11 @@ github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2n github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo= github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= github.com/ultraware/funlen v0.0.2 h1:Av96YVBwwNSe4MLR7iI/BIa3VyI7/djnto/pK3Uxbdo= github.com/ultraware/funlen v0.0.2/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= @@ -1429,7 +1419,6 @@ github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a h1:G++j5e0OC488te356JvdhaM8YS6nMsjLAYF7JxCv07w= -github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee h1:lYbXeSvJi5zk5GLKVuid9TVjS9a0OmLIDKTfoZBL6Ow= @@ -1486,10 +1475,10 @@ go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.15.0 h1:vq3YWr8zRj1eFGC7Gvf907hE0eRjPTZ1d3xHadD6liE= -go.uber.org/dig v1.15.0/go.mod h1:pKHs0wMynzL6brANhB2hLMro+zalv1osARTviTcqHLM= -go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= -go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= +go.uber.org/dig v1.16.1 h1:+alNIBsl0qfY0j6epRubp/9obgtrObRAc5aD+6jbWY8= +go.uber.org/dig v1.16.1/go.mod h1:557JTAUZT5bUK0SvCwikmLPPtdQhfvLYtO5tJgQSbnk= +go.uber.org/fx v1.19.2 h1:SyFgYQFr1Wl0AYstE8vyYIzP4bFz2URrScjwC4cwUvY= +go.uber.org/fx v1.19.2/go.mod h1:43G1VcqSzbIv77y00p1DRAsyZS8WdzuYdhZXmEUkMyQ= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= @@ -1501,8 +1490,8 @@ go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+ go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= -go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= -go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/ratelimit v0.1.0 h1:U2AruXqeTb4Eh9sYQSTrMhH8Cb7M0Ian2ibBOnBcnAw= go.uber.org/ratelimit v0.1.0/go.mod h1:2X8KaoNd1J0lZV+PxJk/5+DGbO/tpwLR1m++a7FnB/Y= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= @@ -1557,8 +1546,6 @@ golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= -golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1577,8 +1564,6 @@ golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMk golang.org/x/exp v0.0.0-20200513190911-00229845015e/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= golang.org/x/exp v0.0.0-20220426173459-3bcf042a4bf5/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= golang.org/x/exp v0.0.0-20230206171751-46f607a40771/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= -golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 h1:Jvc7gsqn21cJHCmAWx0LiimpP18LZmUxkT5Mp7EZ1mI= -golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= @@ -1612,8 +1597,6 @@ golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= -golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= -golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1677,7 +1660,6 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b 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-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -1691,8 +1673,6 @@ golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfS golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1726,7 +1706,6 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1845,8 +1824,8 @@ golang.org/x/sys v0.0.0-20221013171732-95e765b1cc43/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -1854,8 +1833,6 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= -golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1869,7 +1846,6 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= @@ -1882,8 +1858,6 @@ golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.2.0 h1:52I/1L54xyEQAYdtcSuxtiT84KGYTBGXwayxmIpNJhE= -golang.org/x/time v0.2.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1969,12 +1943,9 @@ golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= -golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM= -golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM= golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -2076,8 +2047,6 @@ google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e h1:S9GbmC1iCgvbLyAokVCwiO6tVIrU9Y7c5oMx1V/ki/Y= -google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA= google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= @@ -2107,12 +2076,8 @@ google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG 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.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U= -google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 h1:rNBFJjBCOgVr9pWD7rs/knKL4FRTKgpZmsRfV214zcA= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0/go.mod h1:Dk1tviKTvMCz5tvh7t+fh94dhmQVHuCt2OzJB3CTW9Y= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -2127,7 +2092,6 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= @@ -2195,6 +2159,8 @@ mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphD mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f h1:Cq7MalBHYACRd6EesksG1Q8EoIAKOsiZviGKbOLIej4= mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw= +nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= +nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= diff --git a/hmy/tracer.go b/hmy/tracer.go index 2529e7a2f6..debfd59a5e 100644 --- a/hmy/tracer.go +++ b/hmy/tracer.go @@ -22,7 +22,6 @@ import ( "encoding/hex" "errors" "fmt" - "io/ioutil" "math/big" "os" "runtime" @@ -577,7 +576,7 @@ func (hmy *Harmony) standardTraceBlockToFile(ctx context.Context, block *types.B // Generate a unique temporary file to dump it into prefix := fmt.Sprintf("block_%#x-%d-%#x-", block.Hash().Bytes()[:4], i, tx.Hash().Bytes()[:4]) - dump, err = ioutil.TempFile(os.TempDir(), prefix) + dump, err = os.CreateTemp(os.TempDir(), prefix) if err != nil { return nil, err } diff --git a/hmy/tracers/internal/tracers/assets.go b/hmy/tracers/internal/tracers/assets.go index a285c53e33..d7b1b38f1d 100644 --- a/hmy/tracers/internal/tracers/assets.go +++ b/hmy/tracers/internal/tracers/assets.go @@ -19,7 +19,6 @@ import ( "compress/gzip" "fmt" "io" - "io/ioutil" "os" "path/filepath" "strings" @@ -410,7 +409,7 @@ func RestoreAsset(dir, name string) error { if err != nil { return err } - err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode()) + err = os.WriteFile(_filePath(dir, name), data, info.Mode()) if err != nil { return err } diff --git a/internal/blsgen/kms.go b/internal/blsgen/kms.go index 8318c818b1..0a197a54e0 100644 --- a/internal/blsgen/kms.go +++ b/internal/blsgen/kms.go @@ -3,7 +3,7 @@ package blsgen import ( "encoding/json" "fmt" - "io/ioutil" + "os" "sync" "time" @@ -178,7 +178,7 @@ func newFileACProvider(file string) *fileACProvider { } func (provider *fileACProvider) getAwsConfig() (*AwsConfig, error) { - b, err := ioutil.ReadFile(provider.file) + b, err := os.ReadFile(provider.file) if err != nil { return nil, err } diff --git a/internal/blsgen/kms_test.go b/internal/blsgen/kms_test.go index b4c1d06882..7fde9fdfcb 100644 --- a/internal/blsgen/kms_test.go +++ b/internal/blsgen/kms_test.go @@ -5,7 +5,6 @@ import ( "encoding/json" "errors" "fmt" - "io/ioutil" "os" "path/filepath" "reflect" @@ -107,7 +106,7 @@ func writeAwsConfigFile(file string, config AwsConfig) error { return err } } - return ioutil.WriteFile(file, b, 0700) + return os.WriteFile(file, b, 0700) } func TestPromptACProvider_getAwsConfig(t *testing.T) { diff --git a/internal/blsgen/lib.go b/internal/blsgen/lib.go index c81ae71fce..ec1edc0b4f 100644 --- a/internal/blsgen/lib.go +++ b/internal/blsgen/lib.go @@ -6,8 +6,8 @@ import ( "crypto/md5" "crypto/rand" "encoding/hex" + "fmt" "io" - "io/ioutil" "os" "strings" @@ -50,7 +50,7 @@ func WriteToFile(filename string, data string) error { // LoadBLSKeyWithPassPhrase loads bls key with passphrase. func LoadBLSKeyWithPassPhrase(fileName, passphrase string) (*ffi_bls.SecretKey, error) { - encryptedPrivateKeyBytes, err := ioutil.ReadFile(fileName) + encryptedPrivateKeyBytes, err := os.ReadFile(fileName) if err != nil { return nil, errors.Wrapf(err, "attempted to load from %s", fileName) } @@ -72,7 +72,7 @@ func LoadBLSKeyWithPassPhrase(fileName, passphrase string) (*ffi_bls.SecretKey, // LoadAwsCMKEncryptedBLSKey loads aws encrypted bls key. func LoadAwsCMKEncryptedBLSKey(fileName string, kmsClient *kms.KMS) (*ffi_bls.SecretKey, error) { - encryptedPrivateKeyBytes, err := ioutil.ReadFile(fileName) + encryptedPrivateKeyBytes, err := os.ReadFile(fileName) if err != nil { return nil, errors.Wrapf(err, "fail read at: %s", fileName) } @@ -136,6 +136,9 @@ func decrypt(encrypted []byte, passphrase string) (decrypted []byte, err error) } func decryptRaw(data []byte, passphrase string) ([]byte, error) { + if len(data) == 0 { + return nil, fmt.Errorf("unable to decrypt raw data with the provided passphrase; the data is empty") + } var err error key := []byte(createHash(passphrase)) block, err := aes.NewCipher(key) @@ -147,6 +150,9 @@ func decryptRaw(data []byte, passphrase string) ([]byte, error) { return nil, err } nonceSize := gcm.NonceSize() + if len(data) < nonceSize { + return nil, fmt.Errorf("failed to decrypt raw data with the provided passphrase; the data size is invalid") + } nonce, ciphertext := data[:nonceSize], data[nonceSize:] plaintext, err := gcm.Open(nil, nonce, ciphertext, nil) return plaintext, err diff --git a/internal/blsgen/passphrase.go b/internal/blsgen/passphrase.go index e0109fc7dd..e26a0a1ebd 100644 --- a/internal/blsgen/passphrase.go +++ b/internal/blsgen/passphrase.go @@ -3,7 +3,7 @@ package blsgen import ( "errors" "fmt" - "io/ioutil" + "io" "os" "strings" "sync" @@ -177,7 +177,7 @@ func (provider *promptPassProvider) persistPassphrase(keyFile string, passPhrase return err } - return ioutil.WriteFile(passFile, []byte(passPhrase), defWritePassFileMode) + return os.WriteFile(passFile, []byte(passPhrase), defWritePassFileMode) } // staticPassProvider provide the bls passphrase from a static .pass file @@ -222,7 +222,7 @@ func readPassFromFile(file string) (string, error) { } defer f.Close() - b, err := ioutil.ReadAll(f) + b, err := io.ReadAll(f) if err != nil { return "", err } diff --git a/internal/blsgen/passphrase_test.go b/internal/blsgen/passphrase_test.go index dbeab26121..31e99dc8dd 100644 --- a/internal/blsgen/passphrase_test.go +++ b/internal/blsgen/passphrase_test.go @@ -4,7 +4,6 @@ import ( "bytes" "errors" "fmt" - "io/ioutil" "os" "path/filepath" "reflect" @@ -315,7 +314,7 @@ func TestPromptPassProvider_getPassphrase(t *testing.T) { t.Errorf("Test %v: pass file exist %v", i, passFile) } } else { - b, err := ioutil.ReadFile(passFile) + b, err := os.ReadFile(passFile) if err != nil { t.Error(err) continue diff --git a/internal/blsgen/utils_test.go b/internal/blsgen/utils_test.go index 04d0bf2a7f..fcfc1dccfb 100644 --- a/internal/blsgen/utils_test.go +++ b/internal/blsgen/utils_test.go @@ -2,7 +2,6 @@ package blsgen import ( "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -47,7 +46,7 @@ var testKeys = []testKey{ func writeFile(file string, data string) error { dir := filepath.Dir(file) os.MkdirAll(dir, 0700) - return ioutil.WriteFile(file, []byte(data), 0600) + return os.WriteFile(file, []byte(data), 0600) } func TestPromptYesNo(t *testing.T) { diff --git a/internal/chain/engine.go b/internal/chain/engine.go index 71bb0d3052..4f3aac9ff4 100644 --- a/internal/chain/engine.go +++ b/internal/chain/engine.go @@ -6,7 +6,9 @@ import ( "sort" "time" + "github.com/harmony-one/harmony/common/denominations" "github.com/harmony-one/harmony/internal/params" + "github.com/harmony-one/harmony/numeric" bls2 "github.com/harmony-one/bls/ffi/go/bls" blsvrf "github.com/harmony-one/harmony/crypto/vrf/bls" @@ -285,7 +287,7 @@ func (e *engineImpl) Finalize( // depends on the old LastEpochInCommittee startTime = time.Now() - if err := setElectionEpochAndMinFee(header, state, chain.Config()); err != nil { + if err := setElectionEpochAndMinFee(chain, header, state, chain.Config()); err != nil { return nil, nil, err } utils.Logger().Debug().Int64("elapsed time", time.Now().Sub(startTime).Milliseconds()).Msg("SetElectionEpochAndMinFee") @@ -311,7 +313,7 @@ func (e *engineImpl) Finalize( // Accumulate block rewards and commit the final state root // Header seems complete, assemble into a block and return - payout, err := AccumulateRewardsAndCountSigs( + remainder, payout, err := AccumulateRewardsAndCountSigs( chain, state, header, beacon, sigsReady, ) if err != nil { @@ -331,6 +333,23 @@ func (e *engineImpl) Finalize( // TODO: make the viewID fetch from caller of the block proposal. header.SetViewID(new(big.Int).SetUint64(viewID())) + // Add the emission recovery split to the balance + if chain.Config().IsHIP30(header.Epoch()) { + // convert to ONE - note that numeric.Dec + // is designed for staking decimals and not + // ONE balances so we use big.Int for this math + remainderOne := new(big.Int).Div( + remainder.Int, big.NewInt(denominations.One), + ) + // this goes directly to the balance (on shard 0, of course) + // because the reward mechanism isn't built to handle + // rewards not obtained from any delegations + state.AddBalance( + shard.Schedule.InstanceForEpoch(header.Epoch()). + HIP30RecoveryAddress(), + remainderOne, + ) + } // Finalize the state root header.SetRoot(state.IntermediateRoot(chain.Config().IsS3(header.Epoch()))) return types.NewBlock(header, txs, receipts, outcxs, incxs, stks), payout, nil @@ -390,12 +409,23 @@ func IsCommitteeSelectionBlock(chain engine.ChainReader, header *block.Header) b return isBeaconChain && header.IsLastBlockInEpoch() && inPreStakingEra } -func setElectionEpochAndMinFee(header *block.Header, state *state.DB, config *params.ChainConfig) error { +func setElectionEpochAndMinFee(chain engine.ChainReader, header *block.Header, state *state.DB, config *params.ChainConfig) error { newShardState, err := header.GetShardState() if err != nil { const msg = "[Finalize] failed to read shard state" return errors.New(msg) } + // these 2 should be created outside of loop to optimize + minRate := availability.MinCommissionRate( + config.IsMinCommissionRate(newShardState.Epoch), + config.IsHIP30(newShardState.Epoch), + ) + minRateNotZero := !minRate.Equal(numeric.ZeroDec()) + // elected validators have their fee updated, if required to do so + isElected := make( + map[common.Address]struct{}, + len(newShardState.StakedValidators().Addrs), + ) for _, addr := range newShardState.StakedValidators().Addrs { wrapper, err := state.ValidatorWrapper(addr, true, false) if err != nil { @@ -405,14 +435,32 @@ func setElectionEpochAndMinFee(header *block.Header, state *state.DB, config *pa } // Set last epoch in committee wrapper.LastEpochInCommittee = newShardState.Epoch - - if config.IsMinCommissionRate(newShardState.Epoch) { - // Set first election epoch + if minRateNotZero { + // Set first election epoch (applies only if previously unset) state.SetValidatorFirstElectionEpoch(addr, newShardState.Epoch) - // Update minimum commission fee - if err := availability.UpdateMinimumCommissionFee( - newShardState.Epoch, state, addr, config.MinCommissionPromoPeriod.Int64(), + if _, err := availability.UpdateMinimumCommissionFee( + newShardState.Epoch, state, addr, minRate, + config.MinCommissionPromoPeriod.Uint64(), + ); err != nil { + return err + } + } + isElected[addr] = struct{}{} + } + // due to a bug in the old implementation of the minimum fee, + // unelected validators did not have their fee updated even + // when the protocol required them to do so. here we fix it, + // but only after the HIP-30 hard fork is effective. + if config.IsHIP30(newShardState.Epoch) { + for _, addr := range chain.ValidatorCandidates() { + // skip elected validator + if _, ok := isElected[addr]; ok { + continue + } + if _, err := availability.UpdateMinimumCommissionFee( + newShardState.Epoch, state, addr, minRate, + config.MinCommissionPromoPeriod.Uint64(), ); err != nil { return err } diff --git a/internal/chain/reward.go b/internal/chain/reward.go index f06556412f..c64199a20c 100644 --- a/internal/chain/reward.go +++ b/internal/chain/reward.go @@ -139,11 +139,11 @@ func lookupDelegatorShares( func accumulateRewardsAndCountSigsBeforeStaking( bc engine.ChainReader, state *state.DB, header *block.Header, sigsReady chan bool, -) (reward.Reader, error) { +) (numeric.Dec, reward.Reader, error) { parentHeader := bc.GetHeaderByHash(header.ParentHash()) if parentHeader == nil { - return network.EmptyPayout, errors.Errorf( + return numeric.ZeroDec(), network.EmptyPayout, errors.Errorf( "cannot find parent block header in DB at parent hash %s", header.ParentHash().Hex(), ) @@ -151,11 +151,11 @@ func accumulateRewardsAndCountSigsBeforeStaking( if parentHeader.Number().Cmp(common.Big0) == 0 { // Parent is an epoch block, // which is not signed in the usual manner therefore rewards nothing. - return network.EmptyPayout, nil + return numeric.ZeroDec(), network.EmptyPayout, nil } parentShardState, err := bc.ReadShardState(parentHeader.Epoch()) if err != nil { - return nil, errors.Wrapf( + return numeric.ZeroDec(), nil, errors.Wrapf( err, "cannot read shard state at epoch %v", parentHeader.Epoch(), ) } @@ -163,7 +163,7 @@ func accumulateRewardsAndCountSigsBeforeStaking( // Block here until the commit sigs are ready or timeout. // sigsReady signal indicates that the commit sigs are already populated in the header object. if err := waitForCommitSigs(sigsReady); err != nil { - return network.EmptyPayout, err + return numeric.ZeroDec(), network.EmptyPayout, err } _, signers, _, err := availability.BallotResult( @@ -171,7 +171,7 @@ func accumulateRewardsAndCountSigsBeforeStaking( ) if err != nil { - return network.EmptyPayout, err + return numeric.ZeroDec(), network.EmptyPayout, err } totalAmount := big.NewInt(0) @@ -194,12 +194,12 @@ func accumulateRewardsAndCountSigsBeforeStaking( Int64("block-reward", stakingReward.PreStakedBlocks.Int64()). Int64("total-amount-paid-out", totalAmount.Int64()). Msg("Total paid out was not equal to block-reward") - return nil, errors.Wrapf( + return numeric.ZeroDec(), nil, errors.Wrapf( network.ErrPayoutNotEqualBlockReward, "payout "+totalAmount.String(), ) } - return network.NewPreStakingEraRewarded(totalAmount), nil + return numeric.ZeroDec(), network.NewPreStakingEraRewarded(totalAmount), nil } // getDefaultStakingReward returns the static default reward based on the the block production interval and the chain. @@ -224,7 +224,9 @@ func getDefaultStakingReward(bc engine.ChainReader, epoch *big.Int, blockNum uin } } else { // Mainnet (other nets): - if bc.Config().IsTwoSeconds(epoch) { + if bc.Config().IsHIP30(epoch) { + defaultReward = stakingReward.HIP30StakedBlocks + } else if bc.Config().IsTwoSeconds(epoch) { defaultReward = stakingReward.TwoSecStakedBlocks } else if bc.Config().IsFiveSeconds(epoch) { defaultReward = stakingReward.FiveSecStakedBlocks @@ -240,14 +242,14 @@ func getDefaultStakingReward(bc engine.ChainReader, epoch *big.Int, blockNum uin func AccumulateRewardsAndCountSigs( bc engine.ChainReader, state *state.DB, header *block.Header, beaconChain engine.ChainReader, sigsReady chan bool, -) (reward.Reader, error) { +) (numeric.Dec, reward.Reader, error) { blockNum := header.Number().Uint64() epoch := header.Epoch() isBeaconChain := bc.CurrentHeader().ShardID() == shard.BeaconChainShardID if blockNum == 0 { err := waitForCommitSigs(sigsReady) // wait for commit signatures, or timeout and return err. - return network.EmptyPayout, err + return numeric.ZeroDec(), network.EmptyPayout, err } // Pre-staking era @@ -258,12 +260,12 @@ func AccumulateRewardsAndCountSigs( // Rewards are accumulated only in the beaconchain, so just wait for commit sigs and return. if !isBeaconChain { err := waitForCommitSigs(sigsReady) - return network.EmptyPayout, err + return numeric.ZeroDec(), network.EmptyPayout, err } defaultReward := getDefaultStakingReward(bc, epoch, blockNum) if defaultReward.IsNegative() { // TODO: Figure out whether that's possible. - return network.EmptyPayout, nil + return numeric.ZeroDec(), network.EmptyPayout, nil } // Handle rewards on pre-aggregated rewards era. @@ -275,12 +277,12 @@ func AccumulateRewardsAndCountSigs( // Wait for commit signatures, or timeout and return err. if err := waitForCommitSigs(sigsReady); err != nil { - return network.EmptyPayout, err + return numeric.ZeroDec(), network.EmptyPayout, err } // Only do reward distribution at the 63th block in the modulus. if blockNum%RewardFrequency != RewardFrequency-1 { - return network.EmptyPayout, nil + return numeric.ZeroDec(), network.EmptyPayout, nil } return distributeRewardAfterAggregateEpoch(bc, state, header, beaconChain, defaultReward) @@ -300,7 +302,16 @@ func waitForCommitSigs(sigsReady chan bool) error { } func distributeRewardAfterAggregateEpoch(bc engine.ChainReader, state *state.DB, header *block.Header, beaconChain engine.ChainReader, - defaultReward numeric.Dec) (reward.Reader, error) { + rewardToDistribute numeric.Dec) (numeric.Dec, reward.Reader, error) { + epoch := header.Epoch() + defaultReward := rewardToDistribute + remainingReward := numeric.ZeroDec() + if bc.Config().IsHIP30(epoch) { + fractionToRecovery := shard.Schedule.InstanceForEpoch(epoch).HIP30EmissionFraction() + fractionToValidators := numeric.OneDec().Sub(fractionToRecovery) + defaultReward = rewardToDistribute.Mul(fractionToValidators) + remainingReward = rewardToDistribute.Mul(fractionToRecovery) + } newRewards, payouts := big.NewInt(0), []reward.Payout{} @@ -331,7 +342,7 @@ func distributeRewardAfterAggregateEpoch(bc engine.ChainReader, state *state.DB, if cxLinks := curHeader.CrossLinks(); len(cxLinks) > 0 { crossLinks := types.CrossLinks{} if err := rlp.DecodeBytes(cxLinks, &crossLinks); err != nil { - return network.EmptyPayout, err + return numeric.ZeroDec(), network.EmptyPayout, err } allCrossLinks = append(allCrossLinks, crossLinks...) } @@ -346,7 +357,7 @@ func distributeRewardAfterAggregateEpoch(bc engine.ChainReader, state *state.DB, payables, _, err := processOneCrossLink(bc, state, cxLink, defaultReward, i) if err != nil { - return network.EmptyPayout, err + return numeric.ZeroDec(), network.EmptyPayout, err } allPayables = append(allPayables, payables...) @@ -385,29 +396,30 @@ func distributeRewardAfterAggregateEpoch(bc engine.ChainReader, state *state.DB, for _, addr := range allAddresses { snapshot, err := bc.ReadValidatorSnapshot(addr) if err != nil { - return network.EmptyPayout, err + return numeric.ZeroDec(), network.EmptyPayout, err } due := allValidatorPayable[addr] newRewards.Add(newRewards, due) shares, err := lookupDelegatorShares(snapshot) if err != nil { - return network.EmptyPayout, err + return numeric.ZeroDec(), network.EmptyPayout, err } if err := state.AddReward(snapshot.Validator, due, shares); err != nil { - return network.EmptyPayout, err + return numeric.ZeroDec(), network.EmptyPayout, err } } utils.Logger().Debug().Int64("elapsed time", time.Now().Sub(startTimeLocal).Milliseconds()).Msg("After Chain Reward (AddReward)") utils.Logger().Debug().Int64("elapsed time", time.Now().Sub(startTime).Milliseconds()).Msg("After Chain Reward") - return network.NewStakingEraRewardForRound( + // remainingReward needs to be multipled with the number of crosslinks across all shards + return remainingReward.MulInt(big.NewInt(int64(len(allCrossLinks)))), network.NewStakingEraRewardForRound( newRewards, payouts, ), nil } func distributeRewardBeforeAggregateEpoch(bc engine.ChainReader, state *state.DB, header *block.Header, beaconChain engine.ChainReader, - defaultReward numeric.Dec, sigsReady chan bool) (reward.Reader, error) { + defaultReward numeric.Dec, sigsReady chan bool) (numeric.Dec, reward.Reader, error) { newRewards, payouts := big.NewInt(0), []reward.Payout{} @@ -417,7 +429,7 @@ func distributeRewardBeforeAggregateEpoch(bc engine.ChainReader, state *state.DB startTime := time.Now() crossLinks := types.CrossLinks{} if err := rlp.DecodeBytes(cxLinks, &crossLinks); err != nil { - return network.EmptyPayout, err + return numeric.ZeroDec(), network.EmptyPayout, err } utils.Logger().Debug().Int64("elapsed time", time.Now().Sub(startTime).Milliseconds()).Msg("Decode Cross Links") @@ -427,7 +439,7 @@ func distributeRewardBeforeAggregateEpoch(bc engine.ChainReader, state *state.DB payables, _, err := processOneCrossLink(bc, state, cxLink, defaultReward, i) if err != nil { - return network.EmptyPayout, err + return numeric.ZeroDec(), network.EmptyPayout, err } allPayables = append(allPayables, payables...) @@ -461,17 +473,17 @@ func distributeRewardBeforeAggregateEpoch(bc engine.ChainReader, state *state.DB payable.EcdsaAddress, ) if err != nil { - return network.EmptyPayout, err + return numeric.ZeroDec(), network.EmptyPayout, err } due := resultsHandle[bucket][payThem].payout newRewards.Add(newRewards, due) shares, err := lookupDelegatorShares(snapshot) if err != nil { - return network.EmptyPayout, err + return numeric.ZeroDec(), network.EmptyPayout, err } if err := state.AddReward(snapshot.Validator, due, shares); err != nil { - return network.EmptyPayout, err + return numeric.ZeroDec(), network.EmptyPayout, err } payouts = append(payouts, reward.Payout{ Addr: payable.EcdsaAddress, @@ -487,14 +499,14 @@ func distributeRewardBeforeAggregateEpoch(bc engine.ChainReader, state *state.DB // Block here until the commit sigs are ready or timeout. // sigsReady signal indicates that the commit sigs are already populated in the header object. if err := waitForCommitSigs(sigsReady); err != nil { - return network.EmptyPayout, err + return numeric.ZeroDec(), network.EmptyPayout, err } startTime := time.Now() // Take care of my own beacon chain committee, _ is missing, for slashing parentE, members, payable, missing, err := ballotResultBeaconchain(beaconChain, header) if err != nil { - return network.EmptyPayout, errors.Wrapf(err, "shard 0 block %d reward error with bitmap %x", header.Number(), header.LastCommitBitmap()) + return numeric.ZeroDec(), network.EmptyPayout, errors.Wrapf(err, "shard 0 block %d reward error with bitmap %x", header.Number(), header.LastCommitBitmap()) } subComm := shard.Committee{ShardID: shard.BeaconChainShardID, Slots: members} @@ -505,13 +517,13 @@ func distributeRewardBeforeAggregateEpoch(bc engine.ChainReader, state *state.DB payable, missing, ); err != nil { - return network.EmptyPayout, err + return numeric.ZeroDec(), network.EmptyPayout, err } votingPower, err := lookupVotingPower( parentE, &subComm, ) if err != nil { - return network.EmptyPayout, err + return numeric.ZeroDec(), network.EmptyPayout, err } allSignersShare := numeric.ZeroDec() @@ -528,7 +540,7 @@ func distributeRewardBeforeAggregateEpoch(bc engine.ChainReader, state *state.DB if !voter.IsHarmonyNode { snapshot, err := bc.ReadValidatorSnapshot(voter.EarningAccount) if err != nil { - return network.EmptyPayout, err + return numeric.ZeroDec(), network.EmptyPayout, err } due := defaultReward.Mul( voter.OverallPercent.Quo(allSignersShare), @@ -537,10 +549,10 @@ func distributeRewardBeforeAggregateEpoch(bc engine.ChainReader, state *state.DB shares, err := lookupDelegatorShares(snapshot) if err != nil { - return network.EmptyPayout, err + return numeric.ZeroDec(), network.EmptyPayout, err } if err := state.AddReward(snapshot.Validator, due, shares); err != nil { - return network.EmptyPayout, err + return numeric.ZeroDec(), network.EmptyPayout, err } payouts = append(payouts, reward.Payout{ Addr: voter.EarningAccount, @@ -551,7 +563,7 @@ func distributeRewardBeforeAggregateEpoch(bc engine.ChainReader, state *state.DB } utils.Logger().Debug().Int64("elapsed time", time.Now().Sub(startTime).Milliseconds()).Msg("Beacon Chain Reward") - return network.NewStakingEraRewardForRound( + return numeric.ZeroDec(), network.NewStakingEraRewardForRound( newRewards, payouts, ), nil } diff --git a/internal/cli/flag.go b/internal/cli/flag.go index 755a6a73b9..7d3a93c3d3 100644 --- a/internal/cli/flag.go +++ b/internal/cli/flag.go @@ -71,8 +71,7 @@ type Int64Flag struct { Usage string Deprecated string Hidden bool - - DefValue int64 + DefValue int64 } // RegisterTo register the int flag to FlagSet @@ -81,6 +80,22 @@ func (f Int64Flag) RegisterTo(fs *pflag.FlagSet) error { return markHiddenOrDeprecated(fs, f.Name, f.Deprecated, f.Hidden) } +// Uint64Flag is the flag with uint64 value, used for block number configurations +type Uint64Flag struct { + Name string + Shorthand string + Usage string + Deprecated string + Hidden bool + DefValue uint64 +} + +// RegisterTo register the int flag to FlagSet +func (f Uint64Flag) RegisterTo(fs *pflag.FlagSet) error { + fs.Uint64P(f.Name, f.Shorthand, f.DefValue, f.Usage) + return markHiddenOrDeprecated(fs, f.Name, f.Deprecated, f.Hidden) +} + // StringSliceFlag is the flag with string slice value type StringSliceFlag struct { Name string @@ -143,6 +158,8 @@ func getFlagName(flag Flag) string { return f.Name case Int64Flag: return f.Name + case Uint64Flag: + return f.Name } return "" } diff --git a/internal/cli/parse.go b/internal/cli/parse.go index 326c923ad5..13fc5bdce8 100644 --- a/internal/cli/parse.go +++ b/internal/cli/parse.go @@ -76,6 +76,12 @@ func GetInt64FlagValue(cmd *cobra.Command, flag Int64Flag) int64 { return getInt64FlagValue(cmd.Flags(), flag) } +// GetInt64FlagValue get the int value for the given Int64Flag from the local flags of the +// cobra command. +func GetUint64FlagValue(cmd *cobra.Command, flag Uint64Flag) uint64 { + return getUint64FlagValue(cmd.Flags(), flag) +} + // GetIntPersistentFlagValue get the int value for the given IntFlag from the persistent // flags of the cobra command. func GetIntPersistentFlagValue(cmd *cobra.Command, flag IntFlag) int { @@ -100,6 +106,15 @@ func getInt64FlagValue(fs *pflag.FlagSet, flag Int64Flag) int64 { return val } +func getUint64FlagValue(fs *pflag.FlagSet, flag Uint64Flag) uint64 { + val, err := fs.GetUint64(flag.Name) + if err != nil { + handleParseError(err) + return 0 + } + return val +} + // GetStringSliceFlagValue get the string slice value for the given StringSliceFlag from // the local flags of the cobra command. func GetStringSliceFlagValue(cmd *cobra.Command, flag StringSliceFlag) []string { diff --git a/internal/configs/harmony/harmony.go b/internal/configs/harmony/harmony.go index 5aca663a89..2fcb200c42 100644 --- a/internal/configs/harmony/harmony.go +++ b/internal/configs/harmony/harmony.go @@ -36,6 +36,7 @@ type HarmonyConfig struct { DNSSync DnsSync ShardData ShardDataConfig GPO GasPriceOracleConfig + Preimage *PreimageConfig } func (hc HarmonyConfig) ToRPCServerConfig() nodeconfig.RPCServerConfig { @@ -84,6 +85,7 @@ func (hc HarmonyConfig) ToRPCServerConfig() nodeconfig.RPCServerConfig { WSPort: hc.WS.Port, WSAuthPort: hc.WS.AuthPort, DebugEnabled: hc.RPCOpt.DebugEnabled, + PreimagesEnabled: hc.RPCOpt.PreimagesEnabled, EthRPCsEnabled: hc.RPCOpt.EthRPCsEnabled, StakingRPCsEnabled: hc.RPCOpt.StakingRPCsEnabled, LegacyRPCsEnabled: hc.RPCOpt.LegacyRPCsEnabled, @@ -287,6 +289,7 @@ type RpcOptConfig struct { RateLimterEnabled bool // Enable Rate limiter for RPC RequestsPerSecond int // for RPC rate limiter EvmCallTimeout string // Timeout for eth_call + PreimagesEnabled bool // Expose preimage API } type DevnetConfig struct { @@ -303,6 +306,13 @@ type RevertConfig struct { RevertBefore int } +type PreimageConfig struct { + ImportFrom string + ExportTo string + GenerateStart uint64 + GenerateEnd uint64 +} + type LegacyConfig struct { WebHookConfig *string `toml:",omitempty"` TPBroadcastInvalidTxn *bool `toml:",omitempty"` diff --git a/internal/configs/node/config.go b/internal/configs/node/config.go index 5370a2e52f..11dd5ba59a 100644 --- a/internal/configs/node/config.go +++ b/internal/configs/node/config.go @@ -153,6 +153,7 @@ type RPCServerConfig struct { DebugEnabled bool + PreimagesEnabled bool EthRPCsEnabled bool StakingRPCsEnabled bool LegacyRPCsEnabled bool diff --git a/internal/configs/sharding/instance.go b/internal/configs/sharding/instance.go index 90076e595b..0930c20b05 100644 --- a/internal/configs/sharding/instance.go +++ b/internal/configs/sharding/instance.go @@ -37,6 +37,8 @@ type instance struct { slotsLimit int // HIP-16: The absolute number of maximum effective slots per shard limit for each validator. 0 means no limit. allowlist Allowlist feeCollectors FeeCollectors + emissionFraction numeric.Dec + recoveryAddress ethCommon.Address } type FeeCollectors map[ethCommon.Address]numeric.Dec @@ -44,11 +46,17 @@ type FeeCollectors map[ethCommon.Address]numeric.Dec // NewInstance creates and validates a new sharding configuration based // upon given parameters. func NewInstance( - numShards uint32, numNodesPerShard, numHarmonyOperatedNodesPerShard, slotsLimit int, harmonyVotePercent numeric.Dec, + numShards uint32, + numNodesPerShard, + numHarmonyOperatedNodesPerShard, + slotsLimit int, + harmonyVotePercent numeric.Dec, hmyAccounts []genesis.DeployAccount, fnAccounts []genesis.DeployAccount, allowlist Allowlist, feeCollectors FeeCollectors, + emissionFractionToRecovery numeric.Dec, + recoveryAddress ethCommon.Address, reshardingEpoch []*big.Int, blocksE uint64, ) (Instance, error) { if numShards < 1 { @@ -94,6 +102,26 @@ func NewInstance( ) } } + if emissionFractionToRecovery.LT(numeric.ZeroDec()) || + emissionFractionToRecovery.GT(numeric.OneDec()) { + return nil, errors.Errorf( + "emission split must be within [0, 1]", + ) + } + if !emissionFractionToRecovery.Equal(numeric.ZeroDec()) { + if recoveryAddress == (ethCommon.Address{}) { + return nil, errors.Errorf( + "have non-zero emission split but no target address", + ) + } + } + if recoveryAddress != (ethCommon.Address{}) { + if emissionFractionToRecovery.Equal(numeric.ZeroDec()) { + return nil, errors.Errorf( + "have target address but no emission split", + ) + } + } return instance{ numShards: numShards, @@ -108,6 +136,8 @@ func NewInstance( blocksPerEpoch: blocksE, slotsLimit: slotsLimit, feeCollectors: feeCollectors, + recoveryAddress: recoveryAddress, + emissionFraction: emissionFractionToRecovery, }, nil } @@ -122,12 +152,16 @@ func MustNewInstance( fnAccounts []genesis.DeployAccount, allowlist Allowlist, feeCollectors FeeCollectors, + emissionFractionToRecovery numeric.Dec, + recoveryAddress ethCommon.Address, reshardingEpoch []*big.Int, blocksPerEpoch uint64, ) Instance { slotsLimit := int(float32(numNodesPerShard-numHarmonyOperatedNodesPerShard) * slotsLimitPercent) sc, err := NewInstance( - numShards, numNodesPerShard, numHarmonyOperatedNodesPerShard, slotsLimit, harmonyVotePercent, - hmyAccounts, fnAccounts, allowlist, feeCollectors, reshardingEpoch, blocksPerEpoch, + numShards, numNodesPerShard, numHarmonyOperatedNodesPerShard, + slotsLimit, harmonyVotePercent, hmyAccounts, fnAccounts, + allowlist, feeCollectors, emissionFractionToRecovery, + recoveryAddress, reshardingEpoch, blocksPerEpoch, ) if err != nil { panic(err) @@ -223,3 +257,11 @@ func (sc instance) ExternalAllowlist() []bls.PublicKeyWrapper { func (sc instance) ExternalAllowlistLimit() int { return sc.allowlist.MaxLimitPerShard } + +func (sc instance) HIP30RecoveryAddress() ethCommon.Address { + return sc.recoveryAddress +} + +func (sc instance) HIP30EmissionFraction() numeric.Dec { + return sc.emissionFraction +} diff --git a/internal/configs/sharding/localnet.go b/internal/configs/sharding/localnet.go index 00ea1a7ac2..fb6050b1de 100644 --- a/internal/configs/sharding/localnet.go +++ b/internal/configs/sharding/localnet.go @@ -4,6 +4,7 @@ import ( "fmt" "math/big" + ethCommon "github.com/ethereum/go-ethereum/common" "github.com/harmony-one/harmony/internal/params" "github.com/harmony-one/harmony/numeric" @@ -21,6 +22,9 @@ var feeCollectorsLocalnet = FeeCollectors{ mustAddress("0x1563915e194D8CfBA1943570603F7606A3115508"): numeric.MustNewDecFromStr("0.5"), } +// pk: 0x3333333333333333333333333333333333333333333333333333333333333333 +var hip30CollectionAddressLocalnet = mustAddress("0x5CbDd86a2FA8Dc4bDdd8a8f69dBa48572EeC07FB") + type localnetSchedule struct{} const ( @@ -35,6 +39,8 @@ const ( func (ls localnetSchedule) InstanceForEpoch(epoch *big.Int) Instance { switch { + case params.LocalnetChainConfig.IsHIP30(epoch): + return localnetV4 case params.LocalnetChainConfig.IsFeeCollectEpoch(epoch): return localnetV3_2 case params.LocalnetChainConfig.IsSixtyPercent(epoch): @@ -156,10 +162,57 @@ var ( big.NewInt(0), big.NewInt(localnetV1Epoch), params.LocalnetChainConfig.StakingEpoch, params.LocalnetChainConfig.TwoSecondsEpoch, } // Number of shards, how many slots on each , how many slots owned by Harmony - localnetV0 = MustNewInstance(2, 7, 5, 0, numeric.OneDec(), genesis.LocalHarmonyAccounts, genesis.LocalFnAccounts, emptyAllowlist, nil, localnetReshardingEpoch, LocalnetSchedule.BlocksPerEpochOld()) - localnetV1 = MustNewInstance(2, 8, 5, 0, numeric.OneDec(), genesis.LocalHarmonyAccountsV1, genesis.LocalFnAccountsV1, emptyAllowlist, nil, localnetReshardingEpoch, LocalnetSchedule.BlocksPerEpochOld()) - localnetV2 = MustNewInstance(2, 9, 6, 0, numeric.MustNewDecFromStr("0.68"), genesis.LocalHarmonyAccountsV2, genesis.LocalFnAccountsV2, emptyAllowlist, nil, localnetReshardingEpoch, LocalnetSchedule.BlocksPerEpochOld()) - localnetV3 = MustNewInstance(2, 9, 6, 0, numeric.MustNewDecFromStr("0.68"), genesis.LocalHarmonyAccountsV2, genesis.LocalFnAccountsV2, emptyAllowlist, nil, localnetReshardingEpoch, LocalnetSchedule.BlocksPerEpoch()) - localnetV3_1 = MustNewInstance(2, 9, 6, 0, numeric.MustNewDecFromStr("0.68"), genesis.LocalHarmonyAccountsV2, genesis.LocalFnAccountsV2, emptyAllowlist, nil, localnetReshardingEpoch, LocalnetSchedule.BlocksPerEpoch()) - localnetV3_2 = MustNewInstance(2, 9, 6, 0, numeric.MustNewDecFromStr("0.68"), genesis.LocalHarmonyAccountsV2, genesis.LocalFnAccountsV2, emptyAllowlist, feeCollectorsLocalnet, localnetReshardingEpoch, LocalnetSchedule.BlocksPerEpoch()) + localnetV0 = MustNewInstance( + 2, 7, 5, 0, + numeric.OneDec(), genesis.LocalHarmonyAccounts, + genesis.LocalFnAccounts, emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + localnetReshardingEpoch, LocalnetSchedule.BlocksPerEpochOld(), + ) + localnetV1 = MustNewInstance( + 2, 8, 5, 0, + numeric.OneDec(), genesis.LocalHarmonyAccountsV1, + genesis.LocalFnAccountsV1, emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + localnetReshardingEpoch, LocalnetSchedule.BlocksPerEpochOld(), + ) + localnetV2 = MustNewInstance( + 2, 9, 6, 0, + numeric.MustNewDecFromStr("0.68"), + genesis.LocalHarmonyAccountsV2, genesis.LocalFnAccountsV2, + emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + localnetReshardingEpoch, LocalnetSchedule.BlocksPerEpochOld(), + ) + localnetV3 = MustNewInstance( + 2, 9, 6, 0, + numeric.MustNewDecFromStr("0.68"), + genesis.LocalHarmonyAccountsV2, genesis.LocalFnAccountsV2, + emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + localnetReshardingEpoch, LocalnetSchedule.BlocksPerEpoch(), + ) + localnetV3_1 = MustNewInstance( + 2, 9, 6, 0, + numeric.MustNewDecFromStr("0.68"), + genesis.LocalHarmonyAccountsV2, genesis.LocalFnAccountsV2, + emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + localnetReshardingEpoch, LocalnetSchedule.BlocksPerEpoch(), + ) + localnetV3_2 = MustNewInstance( + 2, 9, 6, 0, + numeric.MustNewDecFromStr("0.68"), + genesis.LocalHarmonyAccountsV2, genesis.LocalFnAccountsV2, + emptyAllowlist, feeCollectorsLocalnet, + numeric.ZeroDec(), ethCommon.Address{}, + localnetReshardingEpoch, LocalnetSchedule.BlocksPerEpoch(), + ) + localnetV4 = MustNewInstance( + 2, 9, 6, 0, numeric.MustNewDecFromStr("0.68"), + genesis.LocalHarmonyAccountsV2, genesis.LocalFnAccountsV2, + emptyAllowlist, feeCollectorsLocalnet, + numeric.MustNewDecFromStr("0.25"), hip30CollectionAddressLocalnet, + localnetReshardingEpoch, LocalnetSchedule.BlocksPerEpoch(), + ) ) diff --git a/internal/configs/sharding/mainnet.go b/internal/configs/sharding/mainnet.go index fb6b0f13bc..2106b58d8c 100644 --- a/internal/configs/sharding/mainnet.go +++ b/internal/configs/sharding/mainnet.go @@ -53,6 +53,9 @@ var ( // Community mustAddress("0xbdFeE8587d347Cd8df002E6154763325265Fa84c"): numeric.MustNewDecFromStr("0.5"), } + + // Emission DAO + hip30CollectionAddress = mustAddress("0xD8194284df879f465ed61DBA6fa8300940cacEA3") ) func mustAddress(addrStr string) ethCommon.Address { @@ -70,6 +73,8 @@ type mainnetSchedule struct{} func (ms mainnetSchedule) InstanceForEpoch(epoch *big.Int) Instance { switch { + case params.MainnetChainConfig.IsHIP30(epoch): + return mainnetV4 case params.MainnetChainConfig.IsFeeCollectEpoch(epoch): return mainnetV3_4 case params.MainnetChainConfig.IsSlotsLimited(epoch): @@ -223,23 +228,147 @@ func (ms mainnetSchedule) IsSkippedEpoch(shardID uint32, epoch *big.Int) bool { var mainnetReshardingEpoch = []*big.Int{big.NewInt(0), big.NewInt(mainnetV0_1Epoch), big.NewInt(mainnetV0_2Epoch), big.NewInt(mainnetV0_3Epoch), big.NewInt(mainnetV0_4Epoch), big.NewInt(mainnetV1Epoch), big.NewInt(mainnetV1_1Epoch), big.NewInt(mainnetV1_2Epoch), big.NewInt(mainnetV1_3Epoch), big.NewInt(mainnetV1_4Epoch), big.NewInt(mainnetV1_5Epoch), big.NewInt(mainnetV2_0Epoch), big.NewInt(mainnetV2_1Epoch), big.NewInt(mainnetV2_2Epoch), params.MainnetChainConfig.TwoSecondsEpoch, params.MainnetChainConfig.SixtyPercentEpoch, params.MainnetChainConfig.HIP6And8Epoch} var ( - mainnetV0 = MustNewInstance(4, 150, 112, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccounts, emptyAllowlist, nil, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) - mainnetV0_1 = MustNewInstance(4, 152, 112, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV0_1, emptyAllowlist, nil, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) - mainnetV0_2 = MustNewInstance(4, 200, 148, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV0_2, emptyAllowlist, nil, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) - mainnetV0_3 = MustNewInstance(4, 210, 148, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV0_3, emptyAllowlist, nil, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) - mainnetV0_4 = MustNewInstance(4, 216, 148, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV0_4, emptyAllowlist, nil, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) - mainnetV1 = MustNewInstance(4, 250, 170, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1, emptyAllowlist, nil, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) - mainnetV1_1 = MustNewInstance(4, 250, 170, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_1, emptyAllowlist, nil, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) - mainnetV1_2 = MustNewInstance(4, 250, 170, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_2, emptyAllowlist, nil, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) - mainnetV1_3 = MustNewInstance(4, 250, 170, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_3, emptyAllowlist, nil, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) - mainnetV1_4 = MustNewInstance(4, 250, 170, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_4, emptyAllowlist, nil, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) - mainnetV1_5 = MustNewInstance(4, 250, 170, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_5, emptyAllowlist, nil, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) - mainnetV2_0 = MustNewInstance(4, 250, 170, 0, numeric.MustNewDecFromStr("0.68"), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_5, emptyAllowlist, nil, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) - mainnetV2_1 = MustNewInstance(4, 250, 130, 0, numeric.MustNewDecFromStr("0.68"), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_5, emptyAllowlist, nil, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) - mainnetV2_2 = MustNewInstance(4, 250, 90, 0, numeric.MustNewDecFromStr("0.68"), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_5, emptyAllowlist, nil, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld()) - mainnetV3 = MustNewInstance(4, 250, 90, 0, numeric.MustNewDecFromStr("0.68"), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_5, emptyAllowlist, nil, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpoch()) - mainnetV3_1 = MustNewInstance(4, 250, 50, 0, numeric.MustNewDecFromStr("0.60"), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_5, emptyAllowlist, nil, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpoch()) - mainnetV3_2 = MustNewInstance(4, 250, 25, 0, numeric.MustNewDecFromStr("0.49"), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_5, emptyAllowlist, nil, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpoch()) - mainnetV3_3 = MustNewInstance(4, 250, 25, 0.06, numeric.MustNewDecFromStr("0.49"), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_5, emptyAllowlist, nil, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpoch()) - mainnetV3_4 = MustNewInstance(4, 250, 25, 0.06, numeric.MustNewDecFromStr("0.49"), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_5, emptyAllowlist, feeCollectorsMainnet, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpoch()) + mainnetV0 = MustNewInstance( + 4, 150, 112, 0, + numeric.OneDec(), genesis.HarmonyAccounts, + genesis.FoundationalNodeAccounts, emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld(), + ) + mainnetV0_1 = MustNewInstance( + 4, 152, 112, 0, + numeric.OneDec(), genesis.HarmonyAccounts, + genesis.FoundationalNodeAccountsV0_1, emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld(), + ) + mainnetV0_2 = MustNewInstance( + 4, 200, 148, 0, + numeric.OneDec(), genesis.HarmonyAccounts, + genesis.FoundationalNodeAccountsV0_2, emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld(), + ) + mainnetV0_3 = MustNewInstance( + 4, 210, 148, 0, + numeric.OneDec(), genesis.HarmonyAccounts, + genesis.FoundationalNodeAccountsV0_3, emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld(), + ) + mainnetV0_4 = MustNewInstance( + 4, 216, 148, 0, + numeric.OneDec(), genesis.HarmonyAccounts, + genesis.FoundationalNodeAccountsV0_4, emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld(), + ) + mainnetV1 = MustNewInstance( + 4, 250, 170, 0, + numeric.OneDec(), genesis.HarmonyAccounts, + genesis.FoundationalNodeAccountsV1, emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld(), + ) + mainnetV1_1 = MustNewInstance( + 4, 250, 170, 0, + numeric.OneDec(), genesis.HarmonyAccounts, + genesis.FoundationalNodeAccountsV1_1, emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld(), + ) + mainnetV1_2 = MustNewInstance( + 4, 250, 170, 0, + numeric.OneDec(), genesis.HarmonyAccounts, + genesis.FoundationalNodeAccountsV1_2, emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld(), + ) + mainnetV1_3 = MustNewInstance( + 4, 250, 170, 0, + numeric.OneDec(), genesis.HarmonyAccounts, + genesis.FoundationalNodeAccountsV1_3, emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld(), + ) + mainnetV1_4 = MustNewInstance( + 4, 250, 170, 0, + numeric.OneDec(), genesis.HarmonyAccounts, + genesis.FoundationalNodeAccountsV1_4, emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld(), + ) + mainnetV1_5 = MustNewInstance( + 4, 250, 170, 0, + numeric.OneDec(), genesis.HarmonyAccounts, + genesis.FoundationalNodeAccountsV1_5, emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld(), + ) + mainnetV2_0 = MustNewInstance( + 4, 250, 170, 0, + numeric.MustNewDecFromStr("0.68"), genesis.HarmonyAccounts, + genesis.FoundationalNodeAccountsV1_5, emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld(), + ) + mainnetV2_1 = MustNewInstance( + 4, 250, 130, 0, + numeric.MustNewDecFromStr("0.68"), genesis.HarmonyAccounts, + genesis.FoundationalNodeAccountsV1_5, emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld(), + ) + mainnetV2_2 = MustNewInstance( + 4, 250, 90, 0, + numeric.MustNewDecFromStr("0.68"), genesis.HarmonyAccounts, + genesis.FoundationalNodeAccountsV1_5, emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld(), + ) + mainnetV3 = MustNewInstance( + 4, 250, 90, 0, + numeric.MustNewDecFromStr("0.68"), genesis.HarmonyAccounts, + genesis.FoundationalNodeAccountsV1_5, emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpoch(), + ) + mainnetV3_1 = MustNewInstance( + 4, 250, 50, 0, + numeric.MustNewDecFromStr("0.60"), genesis.HarmonyAccounts, + genesis.FoundationalNodeAccountsV1_5, emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpoch(), + ) + mainnetV3_2 = MustNewInstance( + 4, 250, 25, 0, + numeric.MustNewDecFromStr("0.49"), genesis.HarmonyAccounts, + genesis.FoundationalNodeAccountsV1_5, emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpoch(), + ) + mainnetV3_3 = MustNewInstance( + 4, 250, 25, 0.06, + numeric.MustNewDecFromStr("0.49"), genesis.HarmonyAccounts, + genesis.FoundationalNodeAccountsV1_5, emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpoch(), + ) + mainnetV3_4 = MustNewInstance( + 4, 250, 25, 0.06, + numeric.MustNewDecFromStr("0.49"), genesis.HarmonyAccounts, + genesis.FoundationalNodeAccountsV1_5, emptyAllowlist, + feeCollectorsMainnet, numeric.ZeroDec(), ethCommon.Address{}, + mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpoch(), + ) + mainnetV4 = MustNewInstance( + // internal slots are 10% of total slots + 2, 200, 20, 0.06, + numeric.MustNewDecFromStr("0.49"), + genesis.HarmonyAccountsPostHIP30, + genesis.FoundationalNodeAccountsV1_5, emptyAllowlist, + feeCollectorsMainnet, numeric.MustNewDecFromStr("0.25"), + hip30CollectionAddress, mainnetReshardingEpoch, + MainnetSchedule.BlocksPerEpoch(), + ) ) diff --git a/internal/configs/sharding/pangaea.go b/internal/configs/sharding/pangaea.go index 12ffc7fe59..46e87b1042 100644 --- a/internal/configs/sharding/pangaea.go +++ b/internal/configs/sharding/pangaea.go @@ -3,6 +3,7 @@ package shardingconfig import ( "math/big" + ethCommon "github.com/ethereum/go-ethereum/common" "github.com/harmony-one/harmony/numeric" "github.com/harmony-one/harmony/internal/genesis" @@ -75,5 +76,15 @@ var pangaeaReshardingEpoch = []*big.Int{ params.PangaeaChainConfig.StakingEpoch, } -var pangaeaV0 = MustNewInstance(4, 30, 30, 0, numeric.OneDec(), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, emptyAllowlist, nil, pangaeaReshardingEpoch, PangaeaSchedule.BlocksPerEpoch()) -var pangaeaV1 = MustNewInstance(4, 110, 30, 0, numeric.MustNewDecFromStr("0.68"), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, emptyAllowlist, nil, pangaeaReshardingEpoch, PangaeaSchedule.BlocksPerEpoch()) +var pangaeaV0 = MustNewInstance( + 4, 30, 30, 0, numeric.OneDec(), genesis.TNHarmonyAccounts, + genesis.TNFoundationalAccounts, emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + pangaeaReshardingEpoch, PangaeaSchedule.BlocksPerEpoch(), +) +var pangaeaV1 = MustNewInstance( + 4, 110, 30, 0, numeric.MustNewDecFromStr("0.68"), + genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, + emptyAllowlist, nil, numeric.ZeroDec(), ethCommon.Address{}, + pangaeaReshardingEpoch, PangaeaSchedule.BlocksPerEpoch(), +) diff --git a/internal/configs/sharding/partner.go b/internal/configs/sharding/partner.go index 9cd6f69305..99ea96141b 100644 --- a/internal/configs/sharding/partner.go +++ b/internal/configs/sharding/partner.go @@ -3,6 +3,7 @@ package shardingconfig import ( "math/big" + ethCommon "github.com/ethereum/go-ethereum/common" "github.com/harmony-one/harmony/numeric" "github.com/harmony-one/harmony/internal/genesis" @@ -13,8 +14,6 @@ import ( // configuration schedule. var PartnerSchedule partnerSchedule -var feeCollectEpochV1 = big.NewInt(574) - var feeCollectorsDevnet = []FeeCollectors{ FeeCollectors{ mustAddress("0xb728AEaBF60fD01816ee9e756c18bc01dC91ba5D"): numeric.OneDec(), @@ -28,8 +27,8 @@ var feeCollectorsDevnet = []FeeCollectors{ type partnerSchedule struct{} const ( - // 12 hours per epoch (at 2s/block) - partnerBlocksPerEpoch = 21600 + // 30 min per epoch (at 2s/block) + partnerBlocksPerEpoch = 900 partnerVdfDifficulty = 10000 // This takes about 20s to finish the vdf @@ -41,9 +40,7 @@ const ( func (ps partnerSchedule) InstanceForEpoch(epoch *big.Int) Instance { switch { - case params.PartnerChainConfig.IsFeeCollectEpoch(epoch): - return partnerV3 - case epoch.Cmp(feeCollectEpochV1) >= 0: + case params.PartnerChainConfig.IsHIP30(epoch): return partnerV2 case epoch.Cmp(params.PartnerChainConfig.StakingEpoch) >= 0: return partnerV1 @@ -92,7 +89,25 @@ var partnerReshardingEpoch = []*big.Int{ params.PartnerChainConfig.StakingEpoch, } -var partnerV0 = MustNewInstance(2, 5, 5, 0, numeric.OneDec(), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, emptyAllowlist, nil, partnerReshardingEpoch, PartnerSchedule.BlocksPerEpoch()) -var partnerV1 = MustNewInstance(2, 5, 4, 0, numeric.MustNewDecFromStr("0.9"), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, emptyAllowlist, nil, partnerReshardingEpoch, PartnerSchedule.BlocksPerEpoch()) -var partnerV2 = MustNewInstance(2, 5, 4, 0, numeric.MustNewDecFromStr("0.9"), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, emptyAllowlist, feeCollectorsDevnet[0], partnerReshardingEpoch, PartnerSchedule.BlocksPerEpoch()) -var partnerV3 = MustNewInstance(2, 5, 4, 0, numeric.MustNewDecFromStr("0.9"), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, emptyAllowlist, feeCollectorsDevnet[1], partnerReshardingEpoch, PartnerSchedule.BlocksPerEpoch()) +var partnerV0 = MustNewInstance( + 2, 5, 5, 0, + numeric.OneDec(), genesis.TNHarmonyAccounts, + genesis.TNFoundationalAccounts, emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + partnerReshardingEpoch, PartnerSchedule.BlocksPerEpoch(), +) +var partnerV1 = MustNewInstance( + 2, 5, 4, 0, + numeric.MustNewDecFromStr("0.9"), genesis.TNHarmonyAccounts, + genesis.TNFoundationalAccounts, emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + partnerReshardingEpoch, PartnerSchedule.BlocksPerEpoch(), +) +var partnerV2 = MustNewInstance( + 2, 5, 4, 0, + numeric.MustNewDecFromStr("0.9"), genesis.TNHarmonyAccounts, + genesis.TNFoundationalAccounts, emptyAllowlist, + feeCollectorsDevnet[1], numeric.MustNewDecFromStr("0.25"), + hip30CollectionAddressTestnet, partnerReshardingEpoch, + PartnerSchedule.BlocksPerEpoch(), +) diff --git a/internal/configs/sharding/shardingconfig.go b/internal/configs/sharding/shardingconfig.go index 577839dfc1..740e83ffb4 100644 --- a/internal/configs/sharding/shardingconfig.go +++ b/internal/configs/sharding/shardingconfig.go @@ -6,6 +6,7 @@ import ( "fmt" "math/big" + ethCommon "github.com/ethereum/go-ethereum/common" "github.com/harmony-one/harmony/crypto/bls" "github.com/harmony-one/harmony/numeric" @@ -85,6 +86,14 @@ type Instance interface { // FeeCollector returns a mapping of address to decimal % of fee FeeCollectors() FeeCollectors + + // HIP30RecoveryAddress returns the address to which + // HIP30EmissionSplit % income is sent + HIP30RecoveryAddress() ethCommon.Address + + // HIP30EmissionFraction is the percentage of the emission + // sent to the Recovery Address + HIP30EmissionFraction() numeric.Dec } // genShardingStructure return sharding structure, given shard number and its patterns. diff --git a/internal/configs/sharding/stress.go b/internal/configs/sharding/stress.go index 70c294c637..eadd07d74a 100644 --- a/internal/configs/sharding/stress.go +++ b/internal/configs/sharding/stress.go @@ -3,6 +3,7 @@ package shardingconfig import ( "math/big" + ethCommon "github.com/ethereum/go-ethereum/common" "github.com/harmony-one/harmony/numeric" "github.com/harmony-one/harmony/internal/genesis" @@ -78,6 +79,24 @@ var stressnetReshardingEpoch = []*big.Int{ params.StressnetChainConfig.StakingEpoch, } -var stressnetV0 = MustNewInstance(2, 10, 10, 0, numeric.OneDec(), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, emptyAllowlist, nil, stressnetReshardingEpoch, StressNetSchedule.BlocksPerEpoch()) -var stressnetV1 = MustNewInstance(2, 30, 10, 0, numeric.MustNewDecFromStr("0.9"), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, emptyAllowlist, nil, stressnetReshardingEpoch, StressNetSchedule.BlocksPerEpoch()) -var stressnetV2 = MustNewInstance(2, 30, 10, 0, numeric.MustNewDecFromStr("0.6"), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, emptyAllowlist, nil, stressnetReshardingEpoch, StressNetSchedule.BlocksPerEpoch()) +var stressnetV0 = MustNewInstance( + 2, 10, 10, 0, + numeric.OneDec(), genesis.TNHarmonyAccounts, + genesis.TNFoundationalAccounts, emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + stressnetReshardingEpoch, StressNetSchedule.BlocksPerEpoch(), +) +var stressnetV1 = MustNewInstance( + 2, 30, 10, 0, + numeric.MustNewDecFromStr("0.9"), genesis.TNHarmonyAccounts, + genesis.TNFoundationalAccounts, emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + stressnetReshardingEpoch, StressNetSchedule.BlocksPerEpoch(), +) +var stressnetV2 = MustNewInstance( + 2, 30, 10, 0, + numeric.MustNewDecFromStr("0.6"), genesis.TNHarmonyAccounts, + genesis.TNFoundationalAccounts, emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + stressnetReshardingEpoch, StressNetSchedule.BlocksPerEpoch(), +) diff --git a/internal/configs/sharding/testnet.go b/internal/configs/sharding/testnet.go index 6ef55775e9..7c2994071c 100644 --- a/internal/configs/sharding/testnet.go +++ b/internal/configs/sharding/testnet.go @@ -3,6 +3,7 @@ package shardingconfig import ( "math/big" + ethCommon "github.com/ethereum/go-ethereum/common" "github.com/harmony-one/harmony/internal/genesis" "github.com/harmony-one/harmony/internal/params" "github.com/harmony-one/harmony/numeric" @@ -20,6 +21,8 @@ var feeCollectorsTestnet = FeeCollectors{ mustAddress("0xb41B6B8d9e68fD44caC8342BC2EEf4D59531d7d7"): numeric.MustNewDecFromStr("0.5"), } +var hip30CollectionAddressTestnet = mustAddress("0x58dB8BeCe892F343350D125ff22B242784a8BA38") + type testnetSchedule struct{} const ( @@ -39,6 +42,8 @@ const ( func (ts testnetSchedule) InstanceForEpoch(epoch *big.Int) Instance { switch { + case params.TestnetChainConfig.IsHIP30(epoch): + return testnetV5 case params.TestnetChainConfig.IsFeeCollectEpoch(epoch): return testnetV4 case epoch.Cmp(shardReductionEpoch) >= 0: @@ -121,9 +126,47 @@ var testnetReshardingEpoch = []*big.Int{ } var ( - testnetV0 = MustNewInstance(4, 8, 8, 0, numeric.OneDec(), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, emptyAllowlist, nil, testnetReshardingEpoch, TestnetSchedule.BlocksPerEpoch()) - testnetV1 = MustNewInstance(4, 30, 8, 0.15, numeric.MustNewDecFromStr("0.70"), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, emptyAllowlist, nil, testnetReshardingEpoch, TestnetSchedule.BlocksPerEpoch()) - testnetV2 = MustNewInstance(4, 30, 8, 0.15, numeric.MustNewDecFromStr("0.90"), genesis.TNHarmonyAccounts, genesis.TNFoundationalAccounts, emptyAllowlist, nil, testnetReshardingEpoch, TestnetSchedule.BlocksPerEpoch()) - testnetV3 = MustNewInstance(2, 30, 8, 0.15, numeric.MustNewDecFromStr("0.90"), genesis.TNHarmonyAccountsV1, genesis.TNFoundationalAccounts, emptyAllowlist, nil, testnetReshardingEpoch, TestnetSchedule.BlocksPerEpoch()) - testnetV4 = MustNewInstance(2, 30, 8, 0.15, numeric.MustNewDecFromStr("0.90"), genesis.TNHarmonyAccountsV1, genesis.TNFoundationalAccounts, emptyAllowlist, feeCollectorsTestnet, testnetReshardingEpoch, TestnetSchedule.BlocksPerEpoch()) + testnetV0 = MustNewInstance( + 4, 8, 8, 0, + numeric.OneDec(), genesis.TNHarmonyAccounts, + genesis.TNFoundationalAccounts, emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + testnetReshardingEpoch, TestnetSchedule.BlocksPerEpoch(), + ) + testnetV1 = MustNewInstance( + 4, 30, 8, 0.15, + numeric.MustNewDecFromStr("0.70"), genesis.TNHarmonyAccounts, + genesis.TNFoundationalAccounts, emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + testnetReshardingEpoch, TestnetSchedule.BlocksPerEpoch(), + ) + testnetV2 = MustNewInstance( + 4, 30, 8, 0.15, + numeric.MustNewDecFromStr("0.90"), genesis.TNHarmonyAccounts, + genesis.TNFoundationalAccounts, emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + testnetReshardingEpoch, TestnetSchedule.BlocksPerEpoch(), + ) + testnetV3 = MustNewInstance( + 2, 30, 8, 0.15, + numeric.MustNewDecFromStr("0.90"), genesis.TNHarmonyAccountsV1, + genesis.TNFoundationalAccounts, emptyAllowlist, nil, + numeric.ZeroDec(), ethCommon.Address{}, + testnetReshardingEpoch, TestnetSchedule.BlocksPerEpoch(), + ) + testnetV4 = MustNewInstance( + 2, 30, 8, 0.15, + numeric.MustNewDecFromStr("0.90"), genesis.TNHarmonyAccountsV1, + genesis.TNFoundationalAccounts, emptyAllowlist, + feeCollectorsTestnet, numeric.ZeroDec(), ethCommon.Address{}, + testnetReshardingEpoch, TestnetSchedule.BlocksPerEpoch(), + ) + testnetV5 = MustNewInstance( + 2, 30, 8, 0.15, + numeric.MustNewDecFromStr("0.90"), genesis.TNHarmonyAccountsV1, + genesis.TNFoundationalAccounts, emptyAllowlist, + feeCollectorsTestnet, numeric.MustNewDecFromStr("0.25"), + hip30CollectionAddressTestnet, testnetReshardingEpoch, + TestnetSchedule.BlocksPerEpoch(), + ) ) diff --git a/internal/genesis/harmony.go b/internal/genesis/harmony.go index 4c02e2fffc..9cd5dbbf2a 100644 --- a/internal/genesis/harmony.go +++ b/internal/genesis/harmony.go @@ -807,3 +807,411 @@ var HarmonyAccounts = []DeployAccount{ {Index: " 802 ", Address: "one1rvn9p9vnu88r0kfksup9nhx7r39rvvhus7lmxv", BLSPublicKey: "3cacd54e3fcb32ceb19eb0994c9d7c226c67823cb5d8221b75a1c31c79c5384aa4225890c435b15ccac7b11e7bfb5387"}, {Index: " 803 ", Address: "one1rvp6sp854guwtt8twrkt9hvezs2fujgcyarmtv", BLSPublicKey: "c2962419d9999a87daa134f6d177f9ccabfe168a470587b13dd02ce91d1690a92170e5949d3dbdfc1b13fd7327dbef8c"}, } + +// HarmonyAccountsPostHIP30 are the accounts after shard and node count reduction. +// It is calculated by removing shard 2 / 3 keys from HarmonyAccounts. +// There is no need to remove 10% (40) keys from the bottom because they will simply be unelected +var HarmonyAccountsPostHIP30 = []DeployAccount{ + {Index: " 0 ", Address: "one1gh043zc95e6mtutwy5a2zhvsxv7lnlklkj42ux", BLSPublicKey: "ca23704be46ce9c4704681ac9c08ddc644f1858a5c28ce236e1b5d9dee67c1f5a28075b5ef089adeffa8a372c1762007"}, + {Index: " 1 ", Address: "one1u0kt4ng2x9c0zl0jv57rwj4rvw8fhem2vqksdv", BLSPublicKey: "c6c008ec354ac776fce5c24ce46d5a9897449b66d91d8bbe2ca0249f1e1fce1a5577cf6f91067b060ee20114ac726297"}, + {Index: " 4 ", Address: "one1jyvcqu4k0rszgf3r2a02tm89dzd68arw5lz9vl", BLSPublicKey: "50b20b4eb89041aa4715e87e4aa6430e674658959d8be657d43e4d3d4c35d7507d6a40aec5188218dcbb5460e354fd12"}, + {Index: " 5 ", Address: "one1ud4zg04zmvw9jc6yw9dpes4vpyqcpuh4wvn9sh", BLSPublicKey: "56c8ebcce3dcacd9fb4209805b141c52efa79842de0098821b4010e2998b7441690245476874878ef07d8fbed32aa917"}, + {Index: " 8 ", Address: "one1nn2c86kwaq4nk8lda50fnepepqr9y73kd9w2z3", BLSPublicKey: "5ecf182ef0cfe449470d900dbe4ce312d534c882765e639c59525f2710d9f96a04abd871e4f0afadc1bd4b07a54ea106"}, + {Index: " 9 ", Address: "one1ff0e7furnnhhnkwy3x7dz7uex5v2tn9p25hycw", BLSPublicKey: "5438b795c8652f901b948e886085d6386608875c5e8c1474813c82a6079df3bd8b261f25241c3ed825675f58a1f79491"}, + {Index: " 12 ", Address: "one1u7jzpkd3sr40kzw62vjval85dkzeyn3g2shz83", BLSPublicKey: "6350958f98fad3d2aa3d8655d11f60acd67a8f9574f580b5f09bd602c644365c548484a0d2a06714124b9f6e01dcd794"}, + {Index: " 13 ", Address: "one1z8v8nr29qthr74390rlk57drz0v4zrx79w20ve", BLSPublicKey: "9f4ef042e95194dcdbef69f586fed7e341d81cd7f2b78e342fa045017ac93a1dfcd6c5bcfa5af84a46b2a6eafcc76701"}, + {Index: " 16 ", Address: "one1tfrpfvrgj5tnxj029xsdkl33hmrsry056nrpvt", BLSPublicKey: "a54fdb9bdb8fd96ff9c58002ab528e2b1515be0dcf45a92ac03b47c0995d93ee41901d611cf13d92c20fb03d6abddb08"}, + {Index: " 17 ", Address: "one1pyffgruqap6uc5c30yuvv92wutzpx42t6a7n46", BLSPublicKey: "d922b97431f3cc13c74eb2101ad120752bfa3c2a2fe4c9d553094780f02ed9084eaaf9968ee955398646d0fd4ba77384"}, + {Index: " 20 ", Address: "one1fg0nrc7djkm2p47tjsuhd8n9435mz9ed57dj8v", BLSPublicKey: "cfdbceeeb2bfe61ae2bb8c5743f7c51cf8767945f66f3701d8350f319d6a487470d8a871e21279172944c0d06070eb87"}, + {Index: " 21 ", Address: "one1zjy35mzrfczelpz63cnp9uzsh0hdlrdhlap082", BLSPublicKey: "1d03e4de8ddd3fcdfaed44ef2123bb4d8328e6befde01b2796628a0a2bd85e8845cc50be1b3666ebe9b614c105310182"}, + {Index: " 24 ", Address: "one15jv9h2rwtczgmre923nde50jfz0sjs8c9gnwpd", BLSPublicKey: "0110a0a1e55cfbe6928e1997f26a0cc8264c61e43a76c66ded32a0ca40b610656b20d4677175f80df055669a50390c03"}, + {Index: " 25 ", Address: "one1fhwkcx446gxn46gwaz9zpkpddlqs8xwhrqgxad", BLSPublicKey: "b021214d1bc3719324cdea55a2291e20822866758add096e823bd2cf0ebe8161b86ca5dd098265c82f8dd59389f87808"}, + {Index: " 28 ", Address: "one145zhxlug79wjwlf9wrx5vh90u2t7nfu562rdlh", BLSPublicKey: "f9d624113a56ef8ea08119a0162fa81b6e644b98af6c1029c98ca72e1fd79ca4c36dd1a2b4ea2ac916d08a3740c25c19"}, + {Index: " 29 ", Address: "one1rqc0529g9amtr5jtgpl8f4cdrg9u0qgfv3yq7f", BLSPublicKey: "61d3f282094624c95876b1828649dd4cbe80db24e9f94e8421b9f1c466c11416a624961a7a5d2e89f49db51e34676f09"}, + {Index: " 32 ", Address: "one17fn65sgdnp9hphg6vn58h90k3ujt07xtqrnn3y", BLSPublicKey: "02bd0857e2cf224d5f4a7cdbccbce0ece8eecb560e49f5955f28d98e22e60b6975d5cd890ad70cc557b7c1879da44a82"}, + {Index: " 33 ", Address: "one1r4g3s4x3npuufc40vdd43teu0r3fepzsesnp8k", BLSPublicKey: "92c7c513efc442974e784863a6e1037601802275094b907ecebfb72a2ab915cc5a3c1b599f1b50d0433211552d0c6492"}, + {Index: " 36 ", Address: "one1ssctny3j3hs92wnetqgkrncwfatq6er6rhede9", BLSPublicKey: "5ae80464819a6062b2c93f2884dd3400aab970a0e70dc58bac7d5b394971c338598e0ee5aa8812adcb0b40898a08a590"}, + {Index: " 37 ", Address: "one1cdfc2sx50f68v3p4e7xjpg5zta9juyhy7shkfc", BLSPublicKey: "1c33be6bf798a2b961816f30631c136ef0cc61fea3848a491dd20c15bdace05545d9ded4598e3bebfe1653d9b8142809"}, + {Index: " 40 ", Address: "one1uevxtwdqehq7k2v5jdm6mz4m492f3qpja4e36q", BLSPublicKey: "ea781dff5e22998622b7b19c189b8bbf4050384238853fe3b8f2f0a80401364589b5e67ff54f05878fff42d7b48aeb00"}, + {Index: " 41 ", Address: "one1267mpm2mtyrf4nfwuw4f0dspk7mptk4hurr2fc", BLSPublicKey: "d5e71c145152c7a53ffe5090fdd5dbf8595428053d8e85f858c2d831926a933e2be76d86aa8ca7feb2146c3a6c27668e"}, + {Index: " 44 ", Address: "one1m4909gjt2g4fsl2jw95kxmjmja2ka4cc6d4sgs", BLSPublicKey: "6bfaabe3a12ebb4c8991f1221a995fb0a2756b2d48ddfdfd2fc3df42e554187d473634cee58159dd81ecc24989b5d38b"}, + {Index: " 45 ", Address: "one1x24etmqfva9f2m39hljmlx2sumvh920q7lw5dy", BLSPublicKey: "a0d453943f069eb6dc3cdecf5c96783d2076d81ffb995251d19387bdf48423035801f1229792feebd381a1d25f91f88e"}, + {Index: " 48 ", Address: "one1sdrc3dla7zzd5pdqjagywfdumnqsyl57ql7sj2", BLSPublicKey: "b885040f11b742de68d121cb8da133099afb876658ab7cabb5624794b37f48b00e438ad447478343375dba7b3099a991"}, + {Index: " 49 ", Address: "one1rn7amacj6qxna4u4jhmnf66644jz4vun5suazk", BLSPublicKey: "bd69a3a69b4eea1fd2fae1d8b2195ef6de953bbcaddc2a0a78aaffe2aee60dbe836f649b2f9855722865a08bc38a1e14"}, + {Index: " 52 ", Address: "one1w4ekumvg88ex5txjrzk9qgfx3xheua4djrphld", BLSPublicKey: "c42479699f74dddc90caf2ec5f8825fad746826797948c299f7a64ade7c8b37a9ecfdc8cc714204e813413073ac12d0c"}, + {Index: " 53 ", Address: "one168rzn68g9k6lc4kq5gpt233m6t6tmcs66sqy7w", BLSPublicKey: "672ff818fb0cdd96aa62ca11bb20b5b3b178e4990f68733eadabba040233de25ffc56ccd073cbe58fcaa7b3f295ef381"}, + {Index: " 56 ", Address: "one1h3ztpa75txa2ng20jzzekqzcfmxx9v83lpeuaz", BLSPublicKey: "ae420cc03a18543fb2e57e1434b52fb65981465265b60dfd375fee68c910a893e93db23b258da658449ac055d8a7eb0f"}, + {Index: " 57 ", Address: "one1369pd4tu0v9vtp5ltscdg2f6q57fnr9d4dhw7a", BLSPublicKey: "ab3fd464dfd476a45fc617ed232173e5b48db87adb75aa0d612cade4493537a4d13a91d6157003fc18e886b296a99012"}, + {Index: " 60 ", Address: "one1zsk49ypjc540vy2663gpn76d8z0mg577d8x5kw", BLSPublicKey: "225065e248691c59e004808b45733e3a84b53b977580e193057c337dafc43bbf39963bb37b9564ea39d72361c78fbf0b"}, + {Index: " 61 ", Address: "one138znnmggmg374yqf9k5rgayvfs2u2ggd7tqh88", BLSPublicKey: "89695d68aabfbf87fd32eb2fa5c41308fd1d1a0132e45e1cc8e1e7fc837cd7da50127fe5672c1274efb00142a9a9d186"}, + {Index: " 64 ", Address: "one1pq9zk56dsapwracyx0z7lgz32603hzfk7f2t2e", BLSPublicKey: "7f5eb00ed4b061ab486ab66c28ec70ee3bd3f88b3348f9b4f6ad9ad820daef4b5242a780737021b5a5f675ab78f53e8c"}, + {Index: " 65 ", Address: "one1f6zyrc967f5069qnw4dd4su0jzxnx7nkddcu3k", BLSPublicKey: "745a1477d0a8c211d6ec61a01590616dbe82a80bd3eb4849e3c9a2602602fa8e24c6ef84e1b1fb5c2b7fb3f0a5a3a58c"}, + {Index: " 68 ", Address: "one16dllsrjr04uhzsuw7raaq4cszpkt3g997yev2s", BLSPublicKey: "aeab90cb890d1419bd6d215e65f473b73efae07a9686bec906e300e223abeaffb7da06a6fb42abf3dee9e828ebbfec12"}, + {Index: " 69 ", Address: "one1paflmvga4ymfmkzqzjjdm7pzz6l8tvc52mv7mp", BLSPublicKey: "98168c8d350da6d8e22e57f5d2613fc9ee7a37c4d7bdacf45e3e2997a5c79fd3ff03c40266afbc5feb03554f9ae7b716"}, + {Index: " 72 ", Address: "one1rs666h8mfgm33kqdkzzq4s6klem4d0hk9lldc4", BLSPublicKey: "1c193e6077a36d290a29d4d6c45ad2cb7163ba98f29029b3ef968a5e464561806ef0d86ed0c81e98d83ae4f87d0f7309"}, + {Index: " 73 ", Address: "one1dadw84g7vlfxgzddpa2rpne4pvlpfkaknl5rst", BLSPublicKey: "01912adee0e1f3809b63fdeb86cbbf944aa23e649e5fc4a34c259cacdac6dcb3643c66e1bafae41e611ab0466a70cf90"}, + {Index: " 76 ", Address: "one1xgk5rmygeuh5p4m2uhp048dfucr7avf7tzj6w4", BLSPublicKey: "927d06aa9bc1334ef5c2cd08b6138574509ff0e62aa0bc5b207119e75aaec13e1e81df367a648c74cd15f40e63634485"}, + {Index: " 77 ", Address: "one1qz7rtkl7x3rm7ys4e43d6rm0jl8ug35970nvex", BLSPublicKey: "73e288038128e27b1f3b78352f919f44a6e9015589945f63be8d917734c45470b91e79859ce6487adab956a312ba2281"}, + {Index: " 80 ", Address: "one1jyzcklsqmr5r5qvvyh0r0e2436ss6vteap69kv", BLSPublicKey: "78c409907db47d0872eaa7ebeb35f2ffcc9c9a69b1179676f9783b39fcefe66e96060305419561ac7cd0b0d70f950007"}, + {Index: " 81 ", Address: "one1a4y6qz32f6qjp8p5z30xh4fpux9mlxm6uxgesn", BLSPublicKey: "6e749ef61bc1d9eaf0a36da6cb4ce7ae5f32615647fbe5a8f074e664359a8be4c45995e6a265339a82ace3d077f6eb8b"}, + {Index: " 84 ", Address: "one1mvlwv0wjp9u6yv2v0ema3qurlnxkp5ftekegm8", BLSPublicKey: "0383b668cf36b3887e48004734ebf989d5547b5c153e8eae1ed568a4fab1972e4bac08e4985e15bd582c9f6d28941c0b"}, + {Index: " 85 ", Address: "one1tkumu4trrrce6v7gll4wm98hw0nurlcmjahtyq", BLSPublicKey: "91ffa107972781b9ed07953c1efeba35d4c25cce2e2dd22bd21ce9c75658dd880e03440006fe1aba9c1d7fcd537f2211"}, + {Index: " 88 ", Address: "one12q6kh768sn3m2dwf5vhn7nfuxstp6xvtf35m4r", BLSPublicKey: "2a7416c9b57cb1e34978ef473bf9bc2acaab509fd9cc542056aa60fe0780a69cbd49f5a91129fd6c4f98ae7312495499"}, + {Index: " 89 ", Address: "one1yr23uytpqg7y3fxqvhhy4207g8ncadkercfk4d", BLSPublicKey: "16a91fdeac0c45f45df272ce980612f6650141bf25a54d2f95ca5a1dc940bfc617c203a9b3c1a1102333992239b16111"}, + {Index: " 92 ", Address: "one198as6uj8p4yucttkkhzrtpu9z8nfwqrgh7d3g6", BLSPublicKey: "a1d2c2c919682772190ed2d0d5fd592538964ec8d5ac066c03177b2a840e1ff5c81418473169fdd9017591209979df15"}, + {Index: " 93 ", Address: "one1fwg40dmtat2pq30p3a707qz0vu726l6tr4e0lq", BLSPublicKey: "c9d8c73e69151bc5020d22a6e0be30def18190aac28e2752e6759530adbb5ef715ce783f617ec8bba29b5a064e48a502"}, + {Index: " 96 ", Address: "one1su2vsv854y639m0qlst580ctx7sm4zwsy60xq7", BLSPublicKey: "a9c788233dda857bd19233cd4b547bcafc4211e6cc6cfe43ef2ccd0ac576ae944683b27a003fa95d246b71579164e00c"}, + {Index: " 97 ", Address: "one1t5xlzlx5sw9zs0jpzpxstdmv8d4k0dt64v70z5", BLSPublicKey: "579684aa6f2f0ddc0ecbc82dc2943aaeeed612367f9c88dd44c920ce09b300d85c88723c05a1f24cbe361fd683e9da02"}, + {Index: " 100 ", Address: "one1x0sm3y8e2cgql05spqc2y20xwgx9m9trpfn2pq", BLSPublicKey: "ad009861e1389ed152b8a5ca48f9a095f4d29701ada0ef126f6bb6ae01995e38b0c527fa1c479e77bb9fb61171dd060e"}, + {Index: " 101 ", Address: "one1ulf83pajcmmgu8nnzrm46spega9lhrt9jcrsx0", BLSPublicKey: "b22d52ab0730ffb9ed0f63daaa0bbc308d503d38de71dfa2eaaec5db5c794beccdcda7ed8d05e39b37cc8b15fca89998"}, + {Index: " 104 ", Address: "one1curhrds59j26ldue4x8sx3glf6dxnfkk3lqa53", BLSPublicKey: "38d7ecfd350b40b51408392a7d589a6aec2315053c94226fe8aafbfcf9575497b55e3a90e3e1639c09fcf4db34c7d503"}, + {Index: " 105 ", Address: "one1zf7efk3w5dae98msd4uvk9vs2er5urvgcsjpwh", BLSPublicKey: "1a2544fb2c0683ccf74e677b7d1e6318f3e137a84f6071006e2af75b750c2bfad52e3c6433bae3dbb5206488c796cc14"}, + {Index: " 108 ", Address: "one1uzsl45tzdn652xkqdc60w42hehrc0nrd7lj7zu", BLSPublicKey: "22721801c98e71190bc64eddc04b2d422f5f0fff4b939654e00e4063754d2ef0921627fd6f96f1db112724e139c05318"}, + {Index: " 109 ", Address: "one1jfjfp656k9gya46p5wlpfpgck0hduqkw8qph84", BLSPublicKey: "91fe8bdee2c777922a33cf5d701c7349697d80049037e130eec2ab75664cd63292d67d264519cf18e4d24a7151858113"}, + {Index: " 112 ", Address: "one135nj2r8jd88uffht52q4zs88h6vpwmy6f88vjr", BLSPublicKey: "5a34b281d855a854ac7eef415a51c632d5de84a63e5500f4929bc9860a552a36034b7a318c271c87c8765b4ae4528413"}, + {Index: " 113 ", Address: "one1zg3vxjv5kgv86pvg85vvgk8arxawzhas62ataw", BLSPublicKey: "e40fac4db93914df760d92227beef9208d26b2dced6906093acc740cd0dc79ca71e7d7266394c84c274aa97f86b6308d"}, + {Index: " 116 ", Address: "one1vg5frvtn82thc5vv0rytysdwtl6qcsjpessvst", BLSPublicKey: "4011d03567248f5ffef3a82b9b5ac94f327bbff25f955123371ce0c1a90cdb469e8ba200e24a5e552a0efadce58c1e89"}, + {Index: " 117 ", Address: "one13vpshpmcfdm07hqzck03wwzfrfepaslyjm3ys5", BLSPublicKey: "d269d3fb01d5a3a1c615f8904aae5cabc71e725eee3486f567e14d14bcd5e02c1e54e4e9eb5accc2b774b05c1ba2f119"}, + {Index: " 120 ", Address: "one1xlnx308wrvfjxxs4h8v894vwz35tpcfyex63um", BLSPublicKey: "9792041e8264bfadf82ac62dbd7ff22c0681fb4dae9a111dd528aacb0bcae4ac8bd16afa2874f86d4beb9cfea69bb30e"}, + {Index: " 121 ", Address: "one1t7nrh7s8zhujl0lt3x5d6tdfwekqy4zkeqx770", BLSPublicKey: "27d3591a48b4cac3c7801db17a57d35b04bc2af97e286c7c9f948cfa318bb53124a283b6f49f99d3fbf87524cf41c80b"}, + {Index: " 124 ", Address: "one1jegwvj0vpkncgsw9p3nuyt36dp94erdu79kv5j", BLSPublicKey: "d1a74426b887744b32f62b2f070f0b8ba8010fba4581189c35a51d241958ce93239a0c1a749495573003049f59f1918f"}, + {Index: " 125 ", Address: "one1d7gueevf4q3k46qnt0tj8rdca2vmzqu6zkp7wt", BLSPublicKey: "a84342997e747ed6aad830ebac6caf7abd628e6e7dcd2b9615a56c3a98c0f05c3846c79ecf6aa84e41790bf0f99c558b"}, + {Index: " 128 ", Address: "one1el39ku64kkdpmrv598d8g63r9ftd25nc8ppuly", BLSPublicKey: "5b38c8854996464cd60656ac0afec5b460f9451124fe576229aafd8775e217e0e6f783ce56235957adb137c7e7caa30e"}, + {Index: " 129 ", Address: "one1962lp4zkn9nafqghz2sdezjlwywr4a83c5s37g", BLSPublicKey: "5b98ca41ddba38de2d7b3e5a227d40df268f1121e1653cd3896c3f7719db364fa4c8383e1a30ef183066dfcbb1261492"}, + {Index: " 132 ", Address: "one1s3vgvw85j4055tq7ky7say5n80hy2vws8hgvfu", BLSPublicKey: "49c69f426110466721d9dc4fa2f0b4808c546088ccfecf77e42f1d60719b7932c44e7c18771057f164e03cdb6486d000"}, + {Index: " 133 ", Address: "one1fr3vgh7gss92d4yv8rzkjfpkdsahufhk6mmyaz", BLSPublicKey: "741e4a76d974539212cf368946f63564fcac80c58422bdab9061e60974561377fa6edcaec9b638b4d5e8dd5797d9eb8e"}, + {Index: " 136 ", Address: "one1tmxgqudfnzuy5y9wf7gsntwv6f768878r3q8q6", BLSPublicKey: "deec63912e755be51ad225d9feccc89a97dcb02b4047cc04c8c9312b8e9076aa21b0a96c0ea2ca904213ca349b253d93"}, + {Index: " 137 ", Address: "one1x897lk8tks3ty5a93f6782jm4d76vp0twxugj3", BLSPublicKey: "cfcd849400bd1f9d58914f61bbacad5a73e36db5d6b420dfa5fce21e33f8f7f8e01b6672e03d6917d007faea4f67868d"}, + {Index: " 140 ", Address: "one13fjjymcva76vzn6e4ykde77wt5j4jyr60u778j", BLSPublicKey: "a27eeb7976954d052078c8a3512449b61886418677131bde005441dd4738c90a783474bffd91023631a4a62286563b96"}, + {Index: " 141 ", Address: "one164n7p8jhu2s97w4zc9cpx3tvzwta2u7eeqth7m", BLSPublicKey: "7c72c90d54ea5498e14098bc364b7ddb991b5f2aa0f926c328c6ac61351ad18f70d453373f5518107b71c587814f2005"}, + {Index: " 144 ", Address: "one1cfq2v4kysk3vdrjtjju2q7d2k8qa204cqcsqsq", BLSPublicKey: "11a25753e8d36f97580e6e15790ea47e22ad84a8b638e880e42bca765d9587cacf3ac1fedb3cef6f4087b071bfc1278d"}, + {Index: " 145 ", Address: "one18h6suyhvqwr7lcf3s6j3csfgnc5sj2vh252f7p", BLSPublicKey: "9adf49ac1fb43ddbcc28d9a2e4fab7519504db9df44ee2b3d4d2a8a157d32f90d06e501cce9f449fcc771900a7ec9711"}, + {Index: " 148 ", Address: "one1g2rm7ay0htx5tlkgqwvvwk4sq2tgm5wratfzq2", BLSPublicKey: "0a186205b9ac93d83d1d474c3e548715e8c3dbdb4882d60c8ff69b01e950b6c4f3db5b680377701299345f17a509570e"}, + {Index: " 149 ", Address: "one14t98zuacc6jgvj2nh06shfgl73l59cmu6pvy45", BLSPublicKey: "e43d5ed52f2e09eb88604874f5ed83f7e9b480f78047926d53c98831f090144f26be7587586c6dcb4139b29b7f9bce0b"}, + {Index: " 152 ", Address: "one1nsu6n9sv7ztgcrred3lnml7qxmr3la94ymsrw0", BLSPublicKey: "11c3606099680455db309cfa732e8e362a139259e1b89418662577a4d8a0851cdec0488acd8d8eee6adbed4e4cd68d88"}, + {Index: " 153 ", Address: "one19mrkhzvp90ujk9qrufn9xt2lq7hvfhwhj958y0", BLSPublicKey: "26c08b3f7c2ee7ca282f1d4c176cce478749f448581a8d2e54a6764ef6e0ba17b216c4bfc2d12739cea1ef3e6d75bb0a"}, + {Index: " 156 ", Address: "one10tu906wspjnc3mn5kvzlr36882swkwf9s8e5xd", BLSPublicKey: "514e2df4d945d40f873f8b4b77de13a9128377a142aa30c6f3ef2554622f708a30cb0277a17d7d5babef7d79ceedff97"}, + {Index: " 157 ", Address: "one10qynxfuq4cr9pfmwaf7aej89p3q943kymd23j9", BLSPublicKey: "d509600371b0ffb4cc3d32ff8fe7bf6f73cb15c60f1dfb9c89b72b0e78bc791680fee1dceecc092940079155776f060d"}, + {Index: " 160 ", Address: "one1chxf96l9c0g0w55703j0q37gtnedg424zlmraf", BLSPublicKey: "98452fd6a94d63c8e3a20e3514f38fbc043a7290ce1a7e93711d06eadb4e5296ead92c63105f8287cd45c9f0b8725293"}, + {Index: " 161 ", Address: "one1ku9r7hgzxqdeyeagtezrge0mdw96w6zqd9clml", BLSPublicKey: "5ca3a829c80c11bbfc662e522aa385240acd53742c696de3e33812d43403b460f5b032ec349a7e5d09f4e74ace7ba082"}, + {Index: " 164 ", Address: "one1gum0zqu2zstptk7fdl8v2wsdrfdtl054qx8jar", BLSPublicKey: "e4060b4bf6fc2bac221c0ae3de202bbaaf18a66c1b840383096151815b6f6dde0ac33b9233191e41ab1f425471f0b394"}, + {Index: " 165 ", Address: "one1j2z57yrqazy3nnuta20daqrced0gfx48cqlhdw", BLSPublicKey: "7b02c517a5065f8cf1773a75b23542365330c16e8f97e3a01ee2f293b8c510d2d2b6388e8bb89e7fc1605d6aefd56208"}, + {Index: " 168 ", Address: "one1gugtmrxusqk2j7xce3sltnc0sgegnnfuv6hq80", BLSPublicKey: "a52247e43b6abebf86b8c8697e7c6fd8994ca343e4311c0f6acf6c8a1738a96ab2c09d86edc3729a5e911149347d5689"}, + {Index: " 169 ", Address: "one1274jyz5qspmjuy8wwrh4s4lga6spumwlul6ufk", BLSPublicKey: "551019b5fff1e43c5c969e5459d599c2ffb8d85b358d6a0fc4c9d6b5f884cccd3d474f84be88ef11121c851a08674b14"}, + {Index: " 172 ", Address: "one1ekllcv39gdpac9497gc3894ddsehkzlqds7ewl", BLSPublicKey: "295d06ba7b2b58896bb68ad324f58399553e3d5e774a80170ff8673b3b9fbb7e5604bdacf381b7d598cd471a3a49b190"}, + {Index: " 173 ", Address: "one1kjw36799v7jnggvy63kv3x6ttfek047qwplltl", BLSPublicKey: "be33e190368b26a8dc0d5148ed87cafad7f11bcd9405f542665f97a30859bb9c8944fa91318e3ac4e2094f383e7e9a0d"}, + {Index: " 176 ", Address: "one18pymc7sn6e3jk07xx3gagrfgmkcmgtuxa428s6", BLSPublicKey: "fcd1036b8c7d59006ffcf8e1ecd3faf567ddb25155fa505eb2082ca886c5fe0f8b62556a78438b526777ed9692ccfb0d"}, + {Index: " 177 ", Address: "one132yeuy3js36zqhupv37ap3m2mj073qdgrafkxh", BLSPublicKey: "842a1b74ae7ecb2946bfa5e55a680b444c9cdd3a4a511b8625a6f96349ef7cab0a658f8c7b3e27fe363e9a9b1475a18a"}, + {Index: " 180 ", Address: "one147x8wxytztf80avpy4s4f99t5u3ksfr7h02j4x", BLSPublicKey: "dbee77bce2f00706d226cbc89f085c7bee45e0b11cfce8c5654636ee8c1a5a635b27c0c010b7ddde266ce44ea1435b8d"}, + {Index: " 181 ", Address: "one1s568nnxwqqjxypx53edk8vg8z29p605qu0j90p", BLSPublicKey: "eaba02b4c29ad6dce8109579cdc60d89730d2be7ac10ef426f8c1e47707592d223dc069c0dd59cb9f7ece5ce71aa0f89"}, + {Index: " 184 ", Address: "one1vfy349h4y44244zf3zm47jwc7z4jdwpgsgdtm3", BLSPublicKey: "f1db95e67a4f1baf48a2dea65a5172a402d1369bc9d05422fb9539eff5dfa2537c2112513736ad626923092bdc0b580b"}, + {Index: " 185 ", Address: "one1qje5hy38mq87v6gvjfwgdd77m3hcex32f92su7", BLSPublicKey: "c9430775294429fa1807195ad3e9de9c23047454d466d218f3c580c7c41ee3bbf58000426edb50202df18af4f64a0f95"}, + {Index: " 188 ", Address: "one14hrttmv9xapdkj0auuwlgpvmmhfz2mp4a2c8ey", BLSPublicKey: "13d936398c988a598e96db9ef5980da9347dcb1a34e87f4a403db8901c33dfea76433c7105890c9ffc44fdcecda10c04"}, + {Index: " 189 ", Address: "one1zu69u7qt5uquh2mgl2pjrspvv4rsn7qnsq7wdp", BLSPublicKey: "ebd22515655a3ef506c68badb47d8a8271624941d92c0258e22796261ba89c0fe5528f1484ac85a2a91f2bcedbae7209"}, + {Index: " 192 ", Address: "one1ktud786d0w6ww8gt8crra4mg6zyl7xf7xr47u6", BLSPublicKey: "89ee8d5bc9ff2db7315525264c13c133b91516a78516d9574c347b08d5f8761dad4e1a8d3a8ba58e003e250a8c804490"}, + {Index: " 193 ", Address: "one1v80qhza089aege2ngxv8xnjv36ga4sxwhajau0", BLSPublicKey: "b7ed2a4cf93689d442165afd9b6a88e15858f22b919cd7aa210d711d03e2b3b7a253bc507b98cd1179cd92c1a77ece99"}, + {Index: " 196 ", Address: "one18jsru7gjz8tex8nux0xe4agffwz2mvq62xjp2x", BLSPublicKey: "c7f37568afec98cdd729e6f33b6b095284a96eea59389bf88239f640145c4285e342b6936968b17b9881ebf306546f17"}, + {Index: " 197 ", Address: "one1zjmecl2we3vtkf9g2a36n2793y8sp4s7mzxkn9", BLSPublicKey: "521e353fe292742571c6617db1a1c992e21ee5b1e604110f958ed016d718f6d4de4dcf36217f7dbc492d0066206c6012"}, + {Index: " 200 ", Address: "one1a29x52lelvelspzx9scdml3nhy9hrau9k5mvdn", BLSPublicKey: "7818a1a592f321279dbc1f53732de2fe7640b5294e38ea895bf4cc53e90d61015bb0fe0e9b76ea5bbde9863a51ccf899"}, + {Index: " 201 ", Address: "one1ql3w33ys0u80r938y66sndl9z7upkde5m99agx", BLSPublicKey: "62a077a367af05574d7a380c6ad258c888a7266a2127ea68a39321753650a05046f1e408281e19ffe38d9a6129972895"}, + {Index: " 204 ", Address: "one13ar9c7czmg5j26fcpwqckj5kx5kyk02j0nqvjr", BLSPublicKey: "7e5f9270132f34b5c9dc6c79644bf79a790a42baa1bebe76b6477aac912a9dc1f0251f57c2a06306ef7fd7d7684d9483"}, + {Index: " 205 ", Address: "one1dy6d7tyrxjdg4z28wkq8ac7lqkq8yn2tfjqwrd", BLSPublicKey: "e3ca514b3fdd4680786f565b4f504d5d85a35de326734c2991acd775627737ae0f1808c1ed0676df7c940005305ca08d"}, + {Index: " 208 ", Address: "one19hnhhs2dkxl0v0gr0h755y6f9l86emt0z3zuj7", BLSPublicKey: "1aeb918501c4657b175d90527b67edd8844bab6977e9630d1fa73b373a1ed88a1c44036ccfbb83792673554ff14da599"}, + {Index: " 209 ", Address: "one17x66fkapn4z24tw2f8cpyvnc4s8fm5kve3zm2m", BLSPublicKey: "9d61af8a2b8526f9761415e0bcaa3ae33f56e03c79610166c67b66384a811799a92853275f9363e37b568f29ecfbf710"}, + {Index: " 212 ", Address: "one1uwkgzutlp76qhvuhtlvhpd77gyuxlm0w3nj0fx", BLSPublicKey: "514c26eb13b9ac9902dcd6516cb086d366ba6cc7415d79a227eab1c7517791ffcc53d0f8ecbd1c6722b18c17f9f3a590"}, + {Index: " 213 ", Address: "one1kxw3ul6vpq4nup6as5nkemxhjakvlrzg069spp", BLSPublicKey: "836279e16ae9ea5599de33e0f2dcdbf805239ffea6cf47f3d4217036f64a9ba16e6f06438c82c628e16080a540616219"}, + {Index: " 216 ", Address: "one10jg0a2wv5fk9042us876xt57ej0lqm6xvm5vxu", BLSPublicKey: "aa4ee9698743ec6114251796861422de7dcd182ccebf6aafe65e9bda48577330061e2880851437f4d054b57fcb74ca10"}, + {Index: " 217 ", Address: "one1yr623algghp3gm6vjrg9vfh9mtmqkfc5e9zply", BLSPublicKey: "81a756857f00c78b7d6299984c482d6b380afaddf60c95f55de354e3e755ed2b8bdab91fb8baefe4a5c36dd3c2bbd78b"}, + {Index: " 220 ", Address: "one1hhf55rl0jzjyshlw4ftlm25ylxhsc5rrq7rznd", BLSPublicKey: "e611da8fa8887d160ce8d76b0d50d45f18b89e6652b2cbcddf8d2bcd48c1758654c5c8cb907138e6a3fc51847d3c6918"}, + {Index: " 221 ", Address: "one14z6m6u4gp6xaurgrnnmxx6h7lacz3458sssnkm", BLSPublicKey: "14cf9ffa4fc6279849ee3c26fc6028a4d455df52b9431d7fea61064c37ab6b76ef233c596deb3c414c136fa0c217e891"}, + {Index: " 224 ", Address: "one1pegk36wh4dnyv29dhe5s3faveenhl60wcef9y2", BLSPublicKey: "a845c999642fb6ff96ab50cf0de871b9ccf9bba3471e69a7254c5b3dfabd62743c4d2a63dffb480554a78de7429e858a"}, + {Index: " 225 ", Address: "one1f0qjrnwdg70erc4nwufapcs834aggq2qclrjqr", BLSPublicKey: "b3a606fe9179eabaf5dcd631178022e49cab8640703e18426d4e580a7b164b7a0b4c6fd1d2982100d71663641be37e90"}, + {Index: " 228 ", Address: "one1y82p9rex6ezqenjze8yxe5a0nhskvamcgn8rqc", BLSPublicKey: "9749b71a42cf13ef035b676553e2926c815be906c4173bde249ac76423e2dd6ccee1b8244a25f667bbde1c4ef87ef500"}, + {Index: " 229 ", Address: "one1t488r3xlwunzxstpst3d0a6qh6xrzuykk9c8hx", BLSPublicKey: "74fde419eb7729ef9ed6b6a553ad11aa6d07e29f57813d99fffc298d9a629c23293707ddd021d54c17bf579c035eb103"}, + {Index: " 232 ", Address: "one1yu2wdsl7x5k58zecsdh5p0ucapfe74mrydwks9", BLSPublicKey: "9a7f7d02338bbc8ae41f1957d349a30301cca90ba4886f4cb23b0a71e8b4ee9f13a5ea7081c6a5bc6617278e3a650213"}, + {Index: " 233 ", Address: "one1xklewq75gd387vqlld6qalcn9x8xyx9p5r3s7h", BLSPublicKey: "a1df3858018981dbb31a0df7025cae7d6ef014a4c65ee46bc926ed6d7f277332b4f051413ce2fe52416de3b76e68b513"}, + {Index: " 236 ", Address: "one1kgyntj9yg6vvasmt06g5w7x8e84z84hnlx4eda", BLSPublicKey: "5282fa73531fd810ad854be2bdebd09d1efaa463564c6bf52624968be6b707e76672bdc3efe6e7761e8ee7bb8e5e3b92"}, + {Index: " 237 ", Address: "one1tz49z0wk3yta2tu60twac7q8x5gj8dl0qqfl4x", BLSPublicKey: "5803fbe842c877ded50b91facc10b781cdd3b0fe4c7d3ba88293d1cf7f2f61fb2ea0c58ee3cb32bb635a3f4e15b95615"}, + {Index: " 240 ", Address: "one1uc3xg782sslsrkyffvaakmy8dw0evl0zzq06ts", BLSPublicKey: "a9a83a4842dcaa3133f34e333764d3e33062a5669f75e9faac6e734360781984a3a99367f995dfda3faafb648236a991"}, + {Index: " 241 ", Address: "one1fu2mda5qe5rc0vmcamgmwpwe9uh375kr5wtjm0", BLSPublicKey: "9453f11dd452d9cd2c0bc2c5bf272d4ffabb0f9f2605955f7f6e5dd5028f91c4fd594c15360f9477a853bc0f5f8dee8f"}, + {Index: " 244 ", Address: "one1tvtrynm5rp8gsxf69hhy7mx0uljlzguxwxgtjy", BLSPublicKey: "e90c79600e596ff981d872d812b0644fd928eb556f369476db86b02be3143990d734e69aa8e0c6b6cf29003ab697bc19"}, + {Index: " 245 ", Address: "one10ucm2t8zpemv6r6v0deka86ztvzvxld5qcuu2n", BLSPublicKey: "7b7a755f65c51a28957d3143b1d02e924675ad90b8474066f8013f324a3eaaef1654b6d87e8c1ebdbc022d0ebef46d15"}, + {Index: " 248 ", Address: "one1t03xpg9f6tgguwke23e56k3chd28d2d37ttxqw", BLSPublicKey: "3cabd9bc1ac865ce5b3655a1f15e4657a99b56cb29984d00e21142b9b8dfc69d96b8bec5071272966989d711a8e32617"}, + {Index: " 249 ", Address: "one1mag8nkvdaau5epkwrks0zedsnxatdgq4equ7sr", BLSPublicKey: "17edd1db18446e06a591e5d213c6727f2da5a137e1378ad34d4c91264013aeadda5da4bc424c0ea6cfe9f19195eb6393"}, + {Index: " 252 ", Address: "one1khln4errq87hnpjs9zqxmll9slwxwywtxy0y3d", BLSPublicKey: "8c48db351942443c6b91e03c27fe612d34c6cb3d1fd108428f04df762a8acab8d14a6d0456543be4e4dd56d49ddf6e80"}, + {Index: " 253 ", Address: "one1sx0rs80aqzwkupclgssl5vhhf9nejpyg9k2g92", BLSPublicKey: "6cc7cc110633d7b6d3cdc473cbc85e76af002d9cafb9f015b08943e90426aad96b1dbe1a02b691722b2a6da565b50a0c"}, + {Index: " 256 ", Address: "one14jntfqa47hatag382uaxkp2zddhwwgwf3wl33x", BLSPublicKey: "077edde9fa10c8c1663bb50ac4d28ceb2d58283c759341963683ba6d43a73fbc31cc9145107abf0ef82930fae6440994"}, + {Index: " 257 ", Address: "one1vz5d0gutlv6a42tsg8luf9e9aghx65aqa08zfa", BLSPublicKey: "d87d9546bb76785a32e2f533c3fc83157ac77d2e6950f5f6574e0cd1eca05c0102b98af4be96ef5838aaba5bdbac0299"}, + {Index: " 260 ", Address: "one1ycdxxqd4x5wgu3wjc26edsjkc3cztm99jpnfry", BLSPublicKey: "623718098929bb558b9a46ee2aa32402f9c8e5ac959ab7a0a5241ca69d704f50fad168efe6f363fe1a19ff7c33405299"}, + {Index: " 261 ", Address: "one1u27tstxep9ntkaz92y92mxauy06y2kv7lp0ve4", BLSPublicKey: "33cd7292140a550b203328ebe44e19cd50ec9114c52ba2cfb94a302039e3526580c4d3a9f8b8d5f931ef66eb4c66c013"}, + {Index: " 264 ", Address: "one13rtrd09sxez76efdqhmtamfclt44ew02auyhwa", BLSPublicKey: "03a3431e0d925662bc4da71966fe34933a50d29388327d608f8ead841132c970b8d22244f0c8fca157c08c04e8751787"}, + {Index: " 265 ", Address: "one1p720ps3pl5y9jg4tk2peehjhapdfyn9z6pf9rn", BLSPublicKey: "274750b387926a11fb0312259c6ed9918f40083573cd2be593eedafc8773a081126906ec4926e9a60bbe1570bd300d80"}, + {Index: " 268 ", Address: "one18hmhzhfnm47sjwcaz73tjhz09zay4jrc2stagj", BLSPublicKey: "ae02cceb71c354576b7af662695a24def1f646f71e1fda19b541cded3fb43076d68f03e1160009414936b434035f3911"}, + {Index: " 269 ", Address: "one1z4gpwvx68ct5z3n6xffj8zhw504kvyucs26wa3", BLSPublicKey: "771871f3e2d5b4be1a681759184a3c8465b14b377c3b214b5235609405775534a42603d18a7408c81b6129d6d960e50f"}, + {Index: " 272 ", Address: "one19lp6lj7j5efhtv6f4mjwyu3c50ey84ajnfntsa", BLSPublicKey: "a2219d19d547f78fa04282f1e3d55d28d7b8f04ea6f347abf9e009d2eb4ba63ba43c8a657a72023dfcd92b3fe36fd612"}, + {Index: " 273 ", Address: "one1xevk8k8rnlhxwkh5xf2ghk92tr6pans0xvk3re", BLSPublicKey: "267f3689f881784817cf6878688ad0c18b17f086f79a21f0410c57740fb73069b9a7a3a27ece051522302e114058320d"}, + {Index: " 276 ", Address: "one10t76e65x7m0pfkhmpwm4wgr7u3xu3t8qndvq5e", BLSPublicKey: "d2173075cda0ae34a76b2407b2b6b7b87f42012b313be63cacb41fd5115f31da7bc3f77c09de396badc48b122be4a216"}, + {Index: " 277 ", Address: "one1rjl48v6v4x3ae7j04qpw46frvjlavxyqnp486s", BLSPublicKey: "0df729418ab50873f5b266ca2b8abb3d8a0b1a0df89d3893db9cb6d5c441430d11d50d368f9dc5c827d4dbc1dfb49a89"}, + {Index: " 280 ", Address: "one1w70ts3l3ehdws08sdx7n639lxp4fgg4ztxxp4s", BLSPublicKey: "57ca05a5cd653662f4004dd409a057831a79a4d7ee0b03a402c92db90ce687f8ec6caee0c3c03778e1deabb623c18f10"}, + {Index: " 281 ", Address: "one17h885c4jrxhp97k5vrvp09trt5g9ajg23fnvf5", BLSPublicKey: "a110d8d1a3626e6b23d61a012bbfec6536c5f2c93d395a2345354f17ffda220e9cf0b4a3ac7a5e4009b80c0453a0dc82"}, + {Index: " 284 ", Address: "one1445u8kcryuz98d0husyrn0dnudfs77fuzdtqfm", BLSPublicKey: "cedb69f6dde95d8464fc81b053eeb9f377b47458c83d0a5cd837b978d5e1a1fc2a1ac4970c3606c576cd1074aef12112"}, + {Index: " 285 ", Address: "one1nzxn9m4ull3nvaer2yvvhhk086sqrn6emqwkge", BLSPublicKey: "d3a862d872780701c6f7f495c4309bf1afc21fe394e7d903380c18ff90c80e24603eee3a52287ec2004b73fe883e7f04"}, + {Index: " 288 ", Address: "one12h79f9lmyyrzfcf08a2zzuv4mct72e0vsyfcax", BLSPublicKey: "172793ea5eec637a28bc210df85acb932683c38b37b8a8e6ca8e75b0f8c00c0a9195d55ee6bcbdc36e57137681378005"}, + {Index: " 289 ", Address: "one19khjzk9230e3c8rcshzuzt7emw94sh9902kl5m", BLSPublicKey: "6b922b2188ab7cf777e66f4447c18dc9d733606a7c1c5a50f61f528a12dc461e2db1e47e9af78d0a2446ed2007a6de8a"}, + {Index: " 292 ", Address: "one17fth44p5a89fyck8sxxz767sqzt35frxj9f0lq", BLSPublicKey: "caf70afcb26d571d355140182cb8e22215abd27f6e833340c88c080eb8bc2e8d61fbc95b46cc99cfdb64825d1ab21595"}, + {Index: " 293 ", Address: "one19yhxw8lvnlwv2anuqt02pu4twswespstver580", BLSPublicKey: "94a9742a5683b6dbf769932494b8ff08d6a7e0a298b2d252ef61079fbedaa1a2f117a4d3bea20b7466c8a30396e7af03"}, + {Index: " 296 ", Address: "one1lml39n0qemt2gg7r6kwl0gerue0q7sr4u6rqjq", BLSPublicKey: "458e57f12ea9c1a92c237baec06a0d0335ad458d894f8d6fed29a1fb54948327096e85d196c240ef4178f2d2dd6cee89"}, + {Index: " 297 ", Address: "one1hh358aymszej4gxftkq96f8yh5hlpaflvq4rmn", BLSPublicKey: "053c8b40358a70305b1dbb687a701ba70b1746e4fd7ebd9b476356996e858d908072f3fb04afa79b9648061f8c224618"}, + {Index: " 300 ", Address: "one15wh83u4p54dfrjmmk79t4e2dgn0fw6c54ml0vz", BLSPublicKey: "dd668b34d02c53c8db16a14749365edeff51ea6edd91e4bdaae9e738a8dbf5ab9f6d226852a814df1576b311a376f198"}, + {Index: " 301 ", Address: "one1e4t557ajgulyz328cdezladvctrwk80srrursl", BLSPublicKey: "fe51bbc6b3565fcdabea0ae46ac18fcf3a98413bfa3b7e24f676d16980e26d33de4d567808e897b874ad037b66ce7883"}, + {Index: " 304 ", Address: "one17jzfd3pwu4peerl26yxr7rkynv8385dczppnnc", BLSPublicKey: "39accf250b555fe249c838b5a969f49c7f9f69c55387b1b830daa4e8e72c28f5a7e7029c9a5916e474adef933162fc97"}, + {Index: " 305 ", Address: "one1f0pzlm8x56ps2hpe93mphva5fx2u59sp2v2qaa", BLSPublicKey: "45fc886b512121ed5a00af63f152cc8f341630f2b4803d041794c0422c1b3164953a75be8e6f2b5e0cf7e722b869bd16"}, + {Index: " 308 ", Address: "one156pcuu77dxef29cc6nu5wsjndmk9cw4ta7crpx", BLSPublicKey: "1f3e059b9ccea9b9f5f223a04fb0f28c890039d20bc016173e4f8c60af00e0e0d547893b9ecc2e22a6ee204e8dfeea83"}, + {Index: " 309 ", Address: "one15yfz8y6ha0xzj4y7668k4nn7frnyz7kqsnzmzm", BLSPublicKey: "bfb66b6a1253e006451ae27e77679ede65fadda0c925b4bcc2ede83d5cef94a2b364bd07dda1096772bbd140209f5797"}, + {Index: " 312 ", Address: "one1wjqtk2krrlsqxcr2jgau7s58vuf2fepdu3cwnu", BLSPublicKey: "b42b39da95826568dbaaec0fc7cf0d6a8e5b270ef2091aa15f9efef8bed4f510bba51ba11195da855d44b3bd25803d85"}, + {Index: " 313 ", Address: "one162qad6qul594runfeuk7t3vdayvkexnvzph45m", BLSPublicKey: "8d52d8d24204859abbc0bd68594d88745b2cbb0e9fb892adbf6a356b0268e8e776016fa8337eec989ccf854d9067f799"}, + {Index: " 316 ", Address: "one1t0y5jmv84cu4eqeev2cczpwr63flrz22ptmnf8", BLSPublicKey: "4a3cb3bf33c5133e5fcf801a52db000b62ef82fefa98cd90f8d12eb807dfcdc87d12a5c28bd6b34a6a228863ed05b190"}, + {Index: " 317 ", Address: "one1ehes8t79lrc7sqagsjrv28e29xlzkmelax7zkt", BLSPublicKey: "2dac109932443061c99674e0f25a2f2f091e60ac50904b8ceeaed85a014adae977a943e2a91814c40b0aec2d55a09180"}, + {Index: " 320 ", Address: "one168rjtx20cyyqjygt248gxpcqqcw7a08ga93kvh", BLSPublicKey: "9b384ec4abe732cc2855faa80e02e47159b35ad23819631bb0e5562a51f4ddf45da81b2a09e0782b3bd0e94a6316a817"}, + {Index: " 321 ", Address: "one1cfx2x23um3w2x2rvqcue9vem0yy4p0h5vyzuua", BLSPublicKey: "85747fd93d0b91c60c5d2c3f6adcf79708f8330402e2df9096037690d68b91636ff9ebb110abb9b05e0c2c5aa02e5c19"}, + {Index: " 324 ", Address: "one1v525e2ddyq5xpecnq9f3gtpz6dlggg93l2uac7", BLSPublicKey: "9fe2ce7d413b0b2930d8f00c99e8500780541aa5d72f9b0d19ba6364d8dbadc30e14ea2885f6d65bf7272158ba113307"}, + {Index: " 325 ", Address: "one13fu462suvr2x93dadtsxers9hdq4a89s4hryy0", BLSPublicKey: "2343d95555916cedfca8627d6d5a02a665260657c068a29af628ccf4dce0037296c9b4010dd1a4d8dabe10a7eeedf002"}, + {Index: " 328 ", Address: "one13j7h7mmlmlypxa2aefuuf5xrw0vjn5ahp0zfr0", BLSPublicKey: "738cb0203a6c01c64031e22a76b117061b85f499faa446e0b7f0bf81804b61302626729afa0b6b2073dd77c044b49093"}, + {Index: " 329 ", Address: "one17qzuw6l7m8tw8k902m05egddcuajcqkd2ge4xh", BLSPublicKey: "979bee891bb0bef898c6957a402d8c84f9db47881a266d77a60c006c9ed2b9bd6aafef1b6a608fe73258061b3fcc3a05"}, + {Index: " 332 ", Address: "one12su07r3rk8hgg8e36gds92z5370t8yhjyxpp0h", BLSPublicKey: "479b35fc9b04c2027d9818fc42133eab872ad89c1e4d434523e3ee06f434601e3c52de77a0fa1989bb0ff4e0fb9a0c19"}, + {Index: " 333 ", Address: "one15qj8q6ehpalzpdglem5pshc5nns0fpjn52y7fv", BLSPublicKey: "32bbd21526b10c332d5f6df253597a36dd134e6f29b5d3388a75d454a9aa553872dc8ba64b0e34428babccf0a67fd713"}, + {Index: " 336 ", Address: "one10urht2e6gfeq4fskmnwrlxnx4vqhaxzz3d00em", BLSPublicKey: "0995dce1f64701c2502fc8b627df9e57d10ca49875022b8a7a7b447c9672be04a7771fc97eb8190df8002536f93ca78e"}, + {Index: " 337 ", Address: "one15ewlqsk0gt4ekwy9fdr48v7nph5r3dxekyl7ek", BLSPublicKey: "852d3b996add6a693b2ddccf23b8fb28f6b21be416838752e490bb90ae35f868a945bbef166a9d9776a7674624e69d83"}, + {Index: " 340 ", Address: "one1g4g72jk5cumlmnkzzslzhlv9vwp85clx2mmzau", BLSPublicKey: "f296c15a7015503a346f542a9da87eec2fe5c06036c12fca7b182c2183484848d4f8b1edf0c5d71be59ce52dda9fe190"}, + {Index: " 341 ", Address: "one1lae40kufwqh9pqag4a7ta33zaez0egqzgrufhp", BLSPublicKey: "5e5bd91b46238b7d3c39aac1dfbf646948b51be978088e520b7dffb360765192df9a33ea2fbf3be40c1d758f069b5c8e"}, + {Index: " 344 ", Address: "one1pey5w5wjv03acwwj0rwhft7wr6dulesjkrl4ah", BLSPublicKey: "d347b60a226fb55e3f3624b5a40d08b5958f8a44c3c89274105108c2afb3da9156d4bde1ec16ea33b409a980d4efd293"}, + {Index: " 345 ", Address: "one1k6asaq4dsz5t7us2s89l7jxxe627c6vfryld83", BLSPublicKey: "f0760d3ece1c214357937cb93f9081a999bd9adf38445f2bcf5a6f82919d7ed5b803c7863d5776f50486b95618beb615"}, + {Index: " 348 ", Address: "one1dzr9ruh47we0lmtkaxk4an7hxe8qp2u6fqsett", BLSPublicKey: "376b54621b144654dba41295e76d413c222688c12ac4cfdb1379260cea4870344db655e72e16c388cf59ef6e0de39288"}, + {Index: " 349 ", Address: "one1lk46twyvhk7ck30994vnwflwl59tk5ksdxulzy", BLSPublicKey: "070700a3b90725d43e4105f4dd9fb0b653e6154af81493aec48330c234067cae6ca465b97c2e30d3f9085660c74bc08e"}, + {Index: " 352 ", Address: "one1qt8z2h76unuz4jh60hupddlct8pes30hfclm4h", BLSPublicKey: "4d179bf6082a2436540c5fe1d84cdd2868377af042ee18e17876d5f8e22ad1aeb8ef4480271d5b29d15bc8c9228f7611"}, + {Index: " 353 ", Address: "one1yy7pluu0dl263gey5n2yvwqdf6ka0aq2gt85zw", BLSPublicKey: "105947b76d98c3a83aed898aee864c0465ad0cb985ebbe60f196ddb208fb197f587c242a66d67d486f44c6b7d71a9b12"}, + {Index: " 356 ", Address: "one12p85puccq3h6fgdtvhvmu2932yutv8xgk3lynk", BLSPublicKey: "6faad32b862cd7b52ca315cee857de8aab3d4b6b04e5b6c46223b8f4a49b6420019abab977378bb0577ca8ece8f7e604"}, + {Index: " 357 ", Address: "one1rgylqupcp9u2k973lh6g6ge7gafemvjyqsgdtv", BLSPublicKey: "5fcd78ea1779519c087c0700a0381e1554505776343ca4a4b706347787b2cabd80e7320c1a6bddbac9f6cfa6ab2f6b92"}, + {Index: " 360 ", Address: "one1cppp40k4kkjq4dwa9lv60wgc8fhx0c7yzr88l9", BLSPublicKey: "a99d649ff8d94c826c3dc3a21b52095425122003b0dfa0ae269915d0488328c1d67a5e46fd1e60ee1ee81b3b8e438519"}, + {Index: " 361 ", Address: "one1w42wl0gzee5vttlnadktzfyae6gq9drgjys7a6", BLSPublicKey: "0067cc6609ca731b998180e81ff742bea9bfab2ba9009b8e56cca4ae9db7bfa1d042be1cb17c625e97efe0cac371e98a"}, + {Index: " 364 ", Address: "one13rdkjur7mzqvvxvpp644eehr50zqvahrmxg6n5", BLSPublicKey: "d809b93446ce9a379fac35eb823809b36e4da993170ea014a76119092b6ee7825e55ae1bd63a2a6bb4bc6504edde768e"}, + {Index: " 365 ", Address: "one1sjj2kp6u0g68zwxj4p0svfzxlyk5fw6v8l0ql7", BLSPublicKey: "c5e997ba1c7f6085161be40bcba2dc4aa514a512e5d88948f9db4b855dd9e982b8db81edeeebefc06ca9aa8d26e82c92"}, + {Index: " 368 ", Address: "one16fcp2y6fagty2wmc7qglcezhvk9sa9vqtkp8h0", BLSPublicKey: "5367b3bce6b557c719f65d5ea0061363a8980d30c185076c1c12ee4d683c26d1749ff5820421bad66157ce62f71c3510"}, + {Index: " 369 ", Address: "one1nhzm46un3ch7ggkvle4qff24suqteg9sdcph8l", BLSPublicKey: "0013cf6d7eddc1cd89ba73fe9444a3df680618d5a1f15e68b745c0f6521746058ce455a411ae05bc956c3b01c3937d13"}, + {Index: " 372 ", Address: "one1stcz8mr4u0efye4vl4nefq8k0v6cdx8aalxw09", BLSPublicKey: "01f743d70cc3ac969b1da159a87ef2b098ce849d71dcca2fda81481fd4bd0ed3b1a0e4e092f6d451cedc2b0afc5df313"}, + {Index: " 373 ", Address: "one1tj9mla5lrnycf5wfp4dcqpjtr7c3nknj96jc5s", BLSPublicKey: "a95c4ac6defa978ea04c9f9f2428f20ea6ebf9a786f170ec400caf649284a08680305ad1573e972bc3b38191e625b206"}, + {Index: " 376 ", Address: "one1xreg53amt4gke3g3jag4h64h4n0ndprsu2nuep", BLSPublicKey: "613feef4c14f916d63a8645a623eeb394c55eb78a05c7be8719ff56f62e9c8cff1ad97f20280fe47e209887a8bc69704"}, + {Index: " 377 ", Address: "one1u2u0ws5xa3pt9ka7je4camwurkvzg85r9hn46a", BLSPublicKey: "ccabf9a34f122a5d2e73cf81d6b5cd6457d05914a25ec6089f5e5ce031835fb674b93cecbcb6a4ac2d212580531be08c"}, + {Index: " 380 ", Address: "one1ln27g8ypym49v7pudkazp0ftv9lekdy7hxldky", BLSPublicKey: "396c1d565943c941b832d2999b48a36efab2c1081086428fedf85325093a9588c710251a6bae45d0f452ff6363a71f13"}, + {Index: " 381 ", Address: "one1wgx5yerhgzjag6x8qlwqfwarzwf4649wwsvwpz", BLSPublicKey: "a949acd5fd0afa0229f571a24a6d07100a92f14684f03e5acb1f64ab607fe9924faa669bf0a195ff5b964b67cfbe1a84"}, + {Index: " 384 ", Address: "one1pr0cgkwwv7h9dpud02uqje582xjanfxycfzr07", BLSPublicKey: "f25f453d7a223950e2155f91b0deee7db3499b0b6ae19324dc118aaf3d630be4f52b7e8a12fa391a1033a5a7e28db00e"}, + {Index: " 385 ", Address: "one1mx4jcuy2tnlj2mm5m5kt4yzr33ynuhl3svays4", BLSPublicKey: "5d155ac5fe931a9541550fe02d6a4a99b9132de66303a169563c5a04790d6cf14ff8474ad5e4793d6e4250aa033c7984"}, + {Index: " 388 ", Address: "one152hm7nxgr3ng4xwpv7dghtntjza9sq58q7za67", BLSPublicKey: "1f2d74b5befca2f60acf948b7aaff960cfc628a2f8042fbdfc123c102f7ca7758279bce4a20d2b98c5493fea8ba8c708"}, + {Index: " 389 ", Address: "one1ufga9u2ylnvvm8s9c0wayenzja6qe6nhv005me", BLSPublicKey: "749fae831d431eb8a8100fd91fed129f01bd2095afd83c3870520dde02c97855b137423109ff3e18468859d2c9dcbb87"}, + {Index: " 392 ", Address: "one1q942nk0nh04phhlcsurzfj4a0e6rqdwvasfa7k", BLSPublicKey: "0d73e64927d37dbd7297c7ece55ddaec6f427217165e6e482e0cabe8b67327a1907de8f69e58482824aac4aaac47e602"}, + {Index: " 393 ", Address: "one1d0wmzfvqs5y9a9jz4fh2v9xwmndenlxhyrcg22", BLSPublicKey: "cc5671f3510a7bf16ee5ff84213fa651f86c30cdd9b68d9d43507c189b1344dd2937326eec1a7605050ea793b6085900"}, + {Index: " 396 ", Address: "one17n0pxvjsz5sgan0hnu5pj6vt25u44urnm9cp3e", BLSPublicKey: "b4253fa4e998c80672789b2dafd6e8821b7a03e258a0395e639337d7ad18463b28cdc55093196246a6aba513e63e970b"}, + {Index: " 397 ", Address: "one1lymxtrk82tfa2g3nrxzgngfd62y8pqvvhav30y", BLSPublicKey: "c654f022ca57542f8c0c52e702e9ff2f16998ab6b97d7beae4c77f19c9f44517da2ef5844618d06e5c4375235183958a"}, + {Index: " 400 ", Address: "one1cjkgecdwqks3st9qxt4ns3y848evl2jwxcxsh8", BLSPublicKey: "5210d58005e37c9d54db3d2dead462d6f896b36db43ade706e2d28f2d7a99a14d1119b2a45d4c09d348c6e399a171b80"}, + {Index: " 401 ", Address: "one1a8z4nctwtveugvtht4qljz286jpwcu2l5xmxnh", BLSPublicKey: "1af7c66b9d9d1cbb4afa2f518603de6c998c4828d0aaab37e68c7f7ccf251c45097f585d829b945e4254ca29ecaa998e"}, + {Index: " 404 ", Address: "one1rcl2ax4y5ksa67d5c6qnavgk79xstz7wxu5k3u", BLSPublicKey: "996021ce105fa2d44925f51efc3834fcc5d551c72391d387669a657f30877058cb641c348292442d488879de562a4f95"}, + {Index: " 405 ", Address: "one1lndcdrwpg87ydeml9a6p89w0p9pu2fyraunnsr", BLSPublicKey: "8534e7eeecca1fcc87906dede5082c043715bd47918870fe71f77a2451f47644ee51a4de9355ca5136d45803d08e2e11"}, + {Index: " 408 ", Address: "one1prmemfp0txxqmf0rh6an5w5hc4mmcghnlc0pn3", BLSPublicKey: "b5cb74f26c0fefc937fe1a6d38bc5c9571f95607f02db3a4392cb2ae55d408d645ac9f1e9bc88c486185b371d26bbf92"}, + {Index: " 409 ", Address: "one1gt804fspkd9ddqtn5u0jzuyp34rvhsj6m727cm", BLSPublicKey: "348e052224aa4dc965f8b7811a56869034b6f2defaac644a5ac366e56d8318fff36d6b06e598933c9a59c3f24d964a17"}, + {Index: " 412 ", Address: "one1597ccchp5npfpkad505snsnjzlxzmcyye5dk3t", BLSPublicKey: "a0a3e37f8ebf345ea1cf3c9915e203dadc9568caeca69d61ead3357c26aaf7f568476d588f0d2eba227500acb0527183"}, + {Index: " 413 ", Address: "one13s99hkdrrn87pukzdw3s8mkj2hfpzsn6jj5c7t", BLSPublicKey: "f69d4c1edae9cecaf3677315df7f4f8aa07b91e0ffe82af956b6e55a60f123a4d67f0c74571567bf09505b6d9ee6738b"}, + {Index: " 416 ", Address: "one1mhc3sl6u43uvwxapy9h04th2fq4mpsqg0d7gpf", BLSPublicKey: "c5cab19917002a47aae411017695af5bb7fc60a12e01175e8f9f8591e6905644011ff168ce204e0e625d7cc5944e020c"}, + {Index: " 417 ", Address: "one165s7lt36cg77j07umppu7h2f6f705rqz80ldv8", BLSPublicKey: "bf9c1498d38251dba2807995f88cb8208e45f5185ca69c4795e304c6eb0cd2c8f37d4c55d462b58573d6508398840e01"}, + {Index: " 420 ", Address: "one1vhcut4wcgu8wmm0t890mlknh2qmm8y8zjw588h", BLSPublicKey: "fb4011905e4505eda64f465013e6334c718708747c03c2cba8ec98c0881e1e1f82383cee23cffdbcaf98e5a14e9ab30d"}, + {Index: " 421 ", Address: "one1fydduy7g44aa24j0eh7sk988e0v9ps3psthmxg", BLSPublicKey: "4dda91966065507e0732f5ab6f46af4e65b5805e3276393e44b7b52cb373e1f0c0d3374c95f73e52ce6528d51d083f97"}, + {Index: " 424 ", Address: "one1fnr7raecmnu0vegqg5t2ssgewkz97m03z0uppe", BLSPublicKey: "e2cd254c82718e67b2bf07ea4051ac6922ae38292f1e28224d0569530d3bfde1343e56a322bba09b6b69b489ece24017"}, + {Index: " 425 ", Address: "one1j554393r37g72nvvpkk67pm2ahf8zxqfc0x3ma", BLSPublicKey: "b237501ef691bb07b160931e1f39089c2e89a2e31d63905f182df4556857f7c626a79bd8426cccf114f678e388007719"}, + {Index: " 428 ", Address: "one1g568wpxknsp7j27nun27p7fa3ll0fej0h42j7v", BLSPublicKey: "0a2c8055849a7d06aac00a6d7e2a884b6d9c36baf52faa0c96087a35abaa54e32429a280238402cda4773dafbe512d82"}, + {Index: " 429 ", Address: "one1rxp04n5skqejjujk5h2wq7vj8qzv7czs6r6he0", BLSPublicKey: "1bb9e2ba373cd98d719c3587610b9066fac82f05ddb440844db1ec0298cdd9f7a0fbe0c3e404af003d565072abcfa690"}, + {Index: " 432 ", Address: "one163zz9czzgkc47taypfpl2axy9tuyugr8a49rjf", BLSPublicKey: "09ede6fe871b8f629a487ef070448fb82b1ef7075eb7aec2941ca3f1a39cfc054bcd3419571034b2f676d285e3d43518"}, + {Index: " 433 ", Address: "one1rwq4udpkj8n5cj098qkpt7qq9mnrmv7whs5wu8", BLSPublicKey: "3235794c1e23cde77616c5fe6528f6d1d6794a969de5d59d83ccc6766ca6f43f7f24a3f6f771cb4997c3332e654e4210"}, + {Index: " 436 ", Address: "one1nyewdjjvm53ytz8ag496x9ye7lmw0qaayr6qqu", BLSPublicKey: "0485ad94e8d85d716b03b187e16a6cdf5c3b3b23e00b06edc292721053d475d3fb959aea44e45e2d5b3d8b8bdce2e309"}, + {Index: " 437 ", Address: "one1ylelue7p6559nllmxxhaq34a3hmch82mjlrgt8", BLSPublicKey: "f6d2ebc992cfded979889c83d6ab6d650cff2870dd8df73a8a863d2c5c7f12ce0dc7b50cba98ffb7cdddf77c226ab805"}, + {Index: " 440 ", Address: "one1tj8vz0qdgaf78nwuqqee20cfn036e2s5nfgdgq", BLSPublicKey: "ba69a459478fc0d48eaca27a1c1fe47cf6b51329f2f7ad166a81d90d1401c9f3e54d5de6c763a643e1bfe51d5b4e6306"}, + {Index: " 441 ", Address: "one17kmpjrmurr2vumkrps46n9hx98arhvjkf85m4m", BLSPublicKey: "315518b3cf5bd319d21d02d10731cbaa341cbac9969ef92cba5f493183c7624e2ea397ad980b7868c2dd09df1ec7e890"}, + {Index: " 444 ", Address: "one1cfrtcemg94y5n5ke0a4hfwf9fp9hhdhf5kcg9u", BLSPublicKey: "65558b383e981a224d58d6221ba295c8f4fb4ab914f6bca4eb5b671f8c28b8bba103f5ca0c7b951bad02332adc4d2505"}, + {Index: " 445 ", Address: "one1zzcgwtv67uur82p59ja8xzlpyzmu0ejfxm6s99", BLSPublicKey: "a44ebc8350af51c95ac0d473d0a7d1b14e88babc0d58fc6324266cc1800ab71a0fe3f02216438d02a750fcac590a0a09"}, + {Index: " 448 ", Address: "one1vqgtzsdqlhaz0ygpl08202vl2j3dflcs2pa5h5", BLSPublicKey: "1526e79b1bc8df2cf86115013d84ebd35869cca5f194d466ff6e9c06ccf4fe7d2557daaf645a0d6fda171868b06ea518"}, + {Index: " 449 ", Address: "one1uuwvhxrp3xfegfe7d9h0qpk4uy79f4tp85zu6v", BLSPublicKey: "6551f3fa75803cc343d332245fc10c23728e835af09d5d2946891b9d5fc45d1a2ae185e2761639b7be8ee8928da5a202"}, + {Index: " 452 ", Address: "one1m6p3xd309ad0vtw5zjydc2snvc28lh5j6qra3j", BLSPublicKey: "5b6d1d4ff7becdafef42f66a267d3c9eedfadd331430fe88ec7e0dd9718d398258bb202d9f53a65f9c54a24d416e2400"}, + {Index: " 453 ", Address: "one1qnsge2u5a2wrtjv4pztd3wgc7ljwfjn8dl2pn3", BLSPublicKey: "68e688742b36349d7aed00560bb48405de3436cc8c7133491761f3837f705f3c671ee3f973a49134214af00055214789"}, + {Index: " 456 ", Address: "one109j4kfsx5krmsgxpsmladp84mwlav5hzgv7fz4", BLSPublicKey: "32f0013e8ac1be6e61dfbbcc54044abe944199e753ae639077e68554b9f6857674d4072d67eabb0c9011c39ddbf0e98d"}, + {Index: " 457 ", Address: "one1vy3aul0xs2vnf72nkq49546wsrwj8zm8palerg", BLSPublicKey: "edcabedc454942d9b8b025e3cf4afade3e3b185062367eedb97d0d12a9e4721b5520ea470bfe360d5e44360755564d06"}, + {Index: " 460 ", Address: "one18jp892w593w0hefvxclwd7ttxpw09n25esaf8g", BLSPublicKey: "90cbbd18a28135ca6b722602a0cf9691980addb93356a337caefc91e13559106c155db8e26db6e01cc1fb2675376ae84"}, + {Index: " 461 ", Address: "one12kptp6uyp78rlkaqqhptu3dw0hrtfs3sl3lwkd", BLSPublicKey: "5b0cf32a09878ab944db609a326a31b7da3928c9a9155f2b767f9e692da2e702a4138cfbaa72794c30f2394d27ba4e17"}, + {Index: " 464 ", Address: "one1wfdp0ugm0jqyhjreqq7mf6rf5uk69s44njd64x", BLSPublicKey: "f065477ac75e6315fd707a4a7f75134856820d5cbbdcd6ba38def02bbf7db38d7830a2f6276a7be60a89b7225a16cc8a"}, + {Index: " 465 ", Address: "one1m4qp793689qk7s5dw8350hdzpcplke9mrj8dra", BLSPublicKey: "7db76f785a5c0e4bf3691c61b599a4ddfa1cdfd4e653025d1db2af184220d96e56bcc3cb525da334453d1468a85f6315"}, + {Index: " 468 ", Address: "one1yn50nm2axhnhgw2yxt9yw48n8sykf97cfdj8r9", BLSPublicKey: "8b787bdf03b5b2bc7ed77ed8ca3cb76a129d3f094ef5d779e87cd569298f01bf5717b6fec38d6f351b9e53c0efdf3d90"}, + {Index: " 469 ", Address: "one1kc4ck4v4x0lg40ujzhl28h8s5mmmv3x3c6l39y", BLSPublicKey: "2e58d7a1c39a08fc0d159d254383b0b90f744167c58c3414293e0d28debabb86d62ef200c30bb5ee84e89e4a9282190e"}, + {Index: " 472 ", Address: "one1kn9yf87eevm25d2j9dn5hat7y7qxq8k389vdfp", BLSPublicKey: "b3282ac8b118e60a3ba6d7058a293a2c08472ca65c662d8dcfa289767232708df55e08a6d59f89873257281f1618a890"}, + {Index: " 473 ", Address: "one1vwm2f0pthuhjstvqljuap7jq2f8zmrr3gympr3", BLSPublicKey: "f2aedca886fc2e8ecbbe15ffdd2060bc348650beff8d565c0ab668293c82123dbead71a40cb2a07331dfd89ff8133f84"}, + {Index: " 476 ", Address: "one1wfr4azaaaqy2wtf50m4tludtfn4f0p3xk2zamg", BLSPublicKey: "4c5a11004797783cbed49f9f0819f5eda76a6e053232baa9d1a74fb003c811c0853c019bb41486c541201b44f799b897"}, + {Index: " 477 ", Address: "one1djg4vrpr3r4xcf26cwv0rk0nnwag8ux0amrjd4", BLSPublicKey: "8d91d6db4708835c6cb8dfcc479582daaa7f789472b89943d806df42be04d6bedda359ba5804c1e7b6dd50b9fc47060c"}, + {Index: " 480 ", Address: "one1jnzv6ky8mpafuwy4gt3uc9ftqp6sekx76tnwaa", BLSPublicKey: "08adb699fc5bdaddb8a226c317a87c7ccaaf0dece03066e239138d12e2f25a72d84d67d2db99fc358a36491c017c3987"}, + {Index: " 481 ", Address: "one1rcujleprl6vdps5p6f6rm4s760g53hy0myfsd0", BLSPublicKey: "1bd12dc05f3b2711d40f100aa830edafac568358ee160e50f241727f3cd76a04d06db5071170b9d819047a508924bf8d"}, + {Index: " 484 ", Address: "one1g2whlzksmew2yxuj5mkm504atl36rd5al05jnr", BLSPublicKey: "b6294d36383c7e37c3a8213b3fa5ee8a1e88b4739541be32f9761080eda7d7ac0000e5ea84a549f439b7b71274bb1500"}, + {Index: " 485 ", Address: "one1xth5w44nwmawuj4lt7jgp0g0pu05zaprkfnh0k", BLSPublicKey: "19bd4a372c0115d6a2e60abc040d2b95e3c14fab01b97c4531c31e469d18893c34116c0a5644029b268c020aa15c0c12"}, + {Index: " 488 ", Address: "one1333fc9npsthfazzvgr680f7unlk54e2lh7sspl", BLSPublicKey: "ab30febf8890f038221ce9ad1f79d788c6dc906c760b8fad86515f48cef05a7b32a5fbe7df2e9d84ef6ad1130a968e8d"}, + {Index: " 489 ", Address: "one1mdxmcluecuh76wqjaw3plldue6vp4zk2njqhnm", BLSPublicKey: "cf83999563899c3b0e786ac7476661e2151a4254a8969c38bea833ad9aaa63585999b4f7be98901027b62746251be60b"}, + {Index: " 492 ", Address: "one1kllaas2wa7ucumu2a9dhdd7j2gxclmwa7r4ntu", BLSPublicKey: "0f0df95160a51d71cc1528ef13318f4d5702b2a063b9a0921dd9f08e33fbc1004a0bec1201f9edf4fb06d9bbfa5eed97"}, + {Index: " 493 ", Address: "one168gvnj9ztqdsjg2q9x606f9hpp9kklnc5357el", BLSPublicKey: "4d72595b37834e5091e6618ffbdc8bff300d12c03d8cfa0f9fc78c571eeb2329adec56e0aafbcefb1c5992198876ef00"}, + {Index: " 496 ", Address: "one1fkcetnzejc5yd3lhk0wk62kfnl27g8kmsd6c8y", BLSPublicKey: "af57896d3f1cf8eea3f86d2ccb2a966e56263526905a1c708e0d46844ddf75bd428c747cf051b5136548d30d20bbc195"}, + {Index: " 497 ", Address: "one17665racwmgel2qyel8t975lclfuursk792uk2r", BLSPublicKey: "62b5afc40e2b25e804e50c11f83c14ce7a0e7370745d13728e26d26ef144243fdd0f89805919751fee4ec4a88e841f89"}, + {Index: " 500 ", Address: "one1t3k6h5csqhvt3aqq4cy6kds9eq4e4wayzc62jq", BLSPublicKey: "4ccb25f475524f8e4a83d81d8d1cc6ce34f00db6b9cc98a64cf3c31b384461ff9becb99e86cc271727d0adf171bc5d15"}, + {Index: " 501 ", Address: "one13akpuhhv3mc4eatngnqqn5makhwvv4ntgylmy3", BLSPublicKey: "722bbae0910b9ce665e5fce24097d2f3286728b1019d78e0c0be58c30c01aa65569fb55e47881028d8e5c97dfc35340b"}, + {Index: " 504 ", Address: "one1t5npgfxkywr7l8985ncy4dlvxd4n2zwc3v28d2", BLSPublicKey: "0c7d92ba1a87533aa85fe55c517826ccf0518d2587d56f7dcfddbcbe93bda99cb10ecd8769ff18c466ce04c91d3edb08"}, + {Index: " 505 ", Address: "one1aqnmsdgpxsam42dg6v0y0ugcuc9j5v00sh6y33", BLSPublicKey: "eace31f581da018da1f7264d8bc1222c74a17c9ca0e7765b6e5be3b093db18a05cc0812ae14c5f9c328658951c7dcc84"}, + {Index: " 508 ", Address: "one1ws8f0vkxsx4mjscc4qpr647h8j2srdj98v9ady", BLSPublicKey: "8fcf78a43f192498ec405be9856df4c3853f91fd62a0dbf877fdfc7953f13c292b224b0ec376b7c8c0e0b936f212c007"}, + {Index: " 509 ", Address: "one1gzqtdrwapngs4rqgahxafsyqdtzshlqmd703c8", BLSPublicKey: "c63b5bf920e9e12e8579b36afc90d7369adb8cbe2c738953458040d9ac2513b17a8971a1e66375c08cb56430f9daa080"}, + {Index: " 512 ", Address: "one1k4aqkd7s6svdkzrr95pq7unrmre2xan8uhqrsm", BLSPublicKey: "e4aa2e1f2908a191a061547212b9ad0aa178e3390352f8993a3c48447aa72486d302e95f13fee8defc1c6fff9fdabf85"}, + {Index: " 513 ", Address: "one1cr5xtllmpapjq2w4kftfugahqpherjrhfwru4t", BLSPublicKey: "f29cc31615b0d870f96e014065d16a9a6d60e1a101c63c63d2470be8317c47ea5bd1b55742ba0938179e619476ebde02"}, + {Index: " 516 ", Address: "one1wgmr2ukj6k255g0lu2ysf5rak3t4qyjgtn0tez", BLSPublicKey: "95209d7f4f582e759cc11a44a65a29c1379618d6f41f4da3f861f679e2fca937a71e8b81018bbe91a633c78284e0218a"}, + {Index: " 517 ", Address: "one1svjer6nquv74mfkwg0z2upky7xz907sej2hqtc", BLSPublicKey: "885f70a811f2e94cce006c6b3717310521037b662c3cbecdb8a201f42f45efb988dbc8ea097dbccf55f0b9ed7504598d"}, + {Index: " 520 ", Address: "one1zyc95lcpy4lct008ay7uhxp2nwlyrhgcevh4vs", BLSPublicKey: "3d8bd50a4402036d46b53b2397dd0c2ba63e1bbfe0bbd0039ef5c9b25d9f8726ccb1fe20ca56e5ec4d539a4fe0b99211"}, + {Index: " 521 ", Address: "one1lxfgw6q3svz5wdktttt8p4cd3p9f2tfaug49tc", BLSPublicKey: "0561ec8478045645dc5ce0cfdfa4fc62719e339ca4653dd95f14a2ecdcacfa74055cd1b820087e76646875b48f555916"}, + {Index: " 524 ", Address: "one1j5azkeqcg3kq0zgpur0m88l0dysmktx5tmd6x3", BLSPublicKey: "eda9243868a03d60e0873ce072f222aaa404b5132491f9dbae3e1d9c1c435312bc9f2889cf39d8ee98531917b3e93713"}, + {Index: " 525 ", Address: "one177jx7zyqc8c3xxjpttm7c68289uzkhqq8t4exc", BLSPublicKey: "4fb99279952e65a73d8c88f6981b90aa2440658af186fa5c06287174cdb1df254ffb64277b3afda3c2bee7e75b2b4692"}, + {Index: " 528 ", Address: "one1tvw7ga4glzrxg9cguj9qjg3kspjaxsm320px2s", BLSPublicKey: "0036d2ad658150125cd49f5b793327bc7c37a032e7a5e15c743ea108dc5a5ea16da38b4d463b6e9732eb3fb94ee52b17"}, + {Index: " 529 ", Address: "one1w5xlj2t4r6xg9r9fgyv4vtj95cje0kjvugh3s9", BLSPublicKey: "29790b08c04ce12cc7d3df238fee658df2f5aacf887d3aa4f72ac0e29d5e1079860662f987698f0ec5438d49be794b0d"}, + {Index: " 532 ", Address: "one15ddy7z7sn9hwfvrxjczrnwwtjf97s3zsmh8sz7", BLSPublicKey: "40389ed2090fcf413fe55dc42927a1058bd104b091574ff56477869aeb3d3570b13cf683cd9512a2f963e3a055350316"}, + {Index: " 533 ", Address: "one1wfvg9hmqk8z50zavv5pw9pw3zptxzkc78yfyk8", BLSPublicKey: "bad1a7681e6eda70a632e24972e362c6e61fc33c7819e8c28de49f798ab720257021369ef008d5055e5a7df1b0e3d98e"}, + {Index: " 536 ", Address: "one1f62v0knx2q05yg2ggk9xprnteptzk29jl54rkn", BLSPublicKey: "5b9c282ee3d8b6142703bb6c93f0ed8d0b829d6f1b18e7ad4754c2bfae9155729b6eadc2cc835d6979e147d78fa45881"}, + {Index: " 537 ", Address: "one1peyc4jnxq8fk4845azs77pq68aqw40xdt020sr", BLSPublicKey: "c4ac3b715c55bfbbf9ef4254ab8ab3c1620eb45ed1b281eb3615f836319fa0d607ce0a4c6459318e36b91c3c6622e588"}, + {Index: " 540 ", Address: "one16zf45g2phcmx4hlgh7s46939sud9p94njyev95", BLSPublicKey: "c37cd83fc126b9f9ad4f657914afb26168f7ad4c0ca316cd3c6d0c99a485baa1884af639dfa110443413524d380b4514"}, + {Index: " 541 ", Address: "one1ajg7xxvxrrjhvgew3s22vnhhnetx0rnzcf7mqt", BLSPublicKey: "80419254c1b381f9df56f1922430b6d155386f4369fa466db7908bfd9c1cd653372aa4b825aade78927d59a33ee8a48b"}, + {Index: " 544 ", Address: "one1q5wduaywa2sg4z559wtp79ewavzypenyp3zqr8", BLSPublicKey: "3c991ee15a9ffe98be4bc9bfbf0b52fd6e27f2a74a570c97b0e2a2e6139901128f3a15f1d2243eec4e89df0dff39cf0e"}, + {Index: " 545 ", Address: "one1kd0erztd809u40qrsvseeuw6xt9w2mx725qjq8", BLSPublicKey: "5debcba4aee531226e5a25fdcb09cf72cc4a3384ef39ddd007be9506668af5395596ccbe276e13bddda1a964f728920e"}, + {Index: " 548 ", Address: "one1ersn3rcc0vxawgv0hrc6w673ufe5e72xka2e93", BLSPublicKey: "8dfe7ef371b2cbd21b80087595fc5182fad1428cb9a06f3f93ce4b6f9861455fa96f4f305fef2531743d9db0c1a7cb8a"}, + {Index: " 549 ", Address: "one1h8qg40hxpdqtsthkce047fj73w3nqasm52ls9z", BLSPublicKey: "8a5cfed151143806ed1f56e02f2cb763a6f01d61258a7949c8387a783322413a316757abbb609fee372884f99f70e98a"}, + {Index: " 552 ", Address: "one1l5ue32mux9wurpkj0vt7rywm2aglf7l5qsl548", BLSPublicKey: "5218c14ce356ecc55e9c0932f152190d3729e98dacd40412d23fafd0ef9f36dff9ea54032ffc9125d7786c7a1766e502"}, + {Index: " 553 ", Address: "one1te0ccrj8ca68cqulys9vk0kwu39an2avsv8hst", BLSPublicKey: "f7b6b4c944f5263049f93a63a0188df48cd20a2009973156d865a3422d197c2b20deaa470a48df3c2e0459620903c481"}, + {Index: " 556 ", Address: "one1x4reytpklja6hthxl74fu85kzrvyyvqa3pyyku", BLSPublicKey: "bb912c8e0bcc610d0d38d075bbcfdf2f1036f1450d6db6b33816b960ccc9a0b641f33be387e64ced8b8f59bab057ea14"}, + {Index: " 557 ", Address: "one130gpj2cx2fd7u2fmy3pcuhknet6eah8zdn6cla", BLSPublicKey: "2ce09e7b675960b7fdb6a82c8f67d0556156313ced40fa3db1cd77fcd0028fdd2f16b4b8d89fd4b9990098a8818e2818"}, + {Index: " 560 ", Address: "one1ansdnnnshnyd669adv0hgyrp5tpp3j7qk9eu29", BLSPublicKey: "9aa9ba631391e8b5f708773ce30cec848c4da6295fe1a466c10df4d27289c66a8161e31b96353d5603cb028afbc2cb05"}, + {Index: " 561 ", Address: "one1tfdt83aza542t8ad2ptmtc2wqrrd407lmecajw", BLSPublicKey: "bef5c9fc522f0919d1f6f092f2eeff2f85f02b3c20958a7ea80bb4b627c683c4d485a868f50a23372402e21870e85999"}, + {Index: " 564 ", Address: "one1as4gl4z6umd3l9tekwejqpjgvuyy5ffxwc46sl", BLSPublicKey: "633f2d839ee98c487112fb5477df884b3382d408d5299ec2c4041b67ca8ab7bd088548dfedbf2dbb40c3e1bbf2952508"}, + {Index: " 565 ", Address: "one1hjxmp2tef0ff2t2u7w7yjn9va07h76lw8ur75j", BLSPublicKey: "b30ec2552015cc0a46294008d26568afb913eb99dae8a35453f562c82e8175c4c1b1a342c9b970875a1ca3c20fc17608"}, + {Index: " 568 ", Address: "one1q4mcz4x334mjzsdvmdkm5x63xf8gpfagu4v5k6", BLSPublicKey: "6ca80631b78eff24bdfea51dad12338a9c825dcd8c03729d84d74cbc22a28ac30b7fb72afa0eabdd0df39bfaae3f4a03"}, + {Index: " 569 ", Address: "one1ydhg7kpvlagpckneg0hpj5h9cuj5g0skm58e2t", BLSPublicKey: "62b601aa82ff6320e5da5b7ab7c0c1cdf9fb9824467e40451226c75c6db9b5546acea177c01d1706dde46abe7252bd13"}, + {Index: " 572 ", Address: "one16uhe39u96r3zs9w8swjtfg4hecrw7mcc82a77m", BLSPublicKey: "3cdc3146616fba161004777505b3e56f22fa1d9e120a50f0aa0b034caa62744b3437a57c6536b18f5336a57040e87a8b"}, + {Index: " 573 ", Address: "one1p38fy2akp4fz3jmqm9354k25eauhh4rpfev0mj", BLSPublicKey: "c17eb357c25e59e810cca39faffb9bef56068a388095f814a1309b80ed77c2feb85844859af39708aa2e8da98b966397"}, + {Index: " 576 ", Address: "one186xdc07sysqw6p4fzhcp6jwt2vcdxlggj6vmgs", BLSPublicKey: "8b1e5de4ff48a4a9600972bbc535650c054d0259717c8a14b96c4baf131eb388710357deb2c37ad98a4c688a60702588"}, + {Index: " 577 ", Address: "one137jx38kdjhney5vvxl2tfmf3h6m0cqf8ws6p0e", BLSPublicKey: "c8947b7a12ea5542348ae2c59e74077178e70640e1536a348adf820fc75acaaa0b2eb68ecb62efa8305289b61a070087"}, + {Index: " 580 ", Address: "one1nkw9mztlc4lpusu8tsmpn7k6wh3vmq7m6lakd9", BLSPublicKey: "dc236f2df1d8f0ade010c2ef3b930f7453adfcf040b2cdecf53b5f6fe9622d2fe2d0a1d0e800dfdc08caafacefafbd88"}, + {Index: " 581 ", Address: "one17fgnz4jdh7dm2m578z0nqzuu76rr5nx679vw6q", BLSPublicKey: "68849fa0b7c8efdd60a24848ae79b5e8ce50b73565fa52c1dda9d4ca91dc49333ff12626c6740b54dc8a173e35c7bb10"}, + {Index: " 584 ", Address: "one1ctuqk9a0vmvttw8ta5gv8yqp0phpljskdyh64k", BLSPublicKey: "3f5a8c95725f5936f426897ae97254fb3b0894c6045507b783531521c37fe581685c7f54f5f661f0f7a9c70d21c75484"}, + {Index: " 585 ", Address: "one1nk8aqankqljslugz3nrl72sk82e7vdw6x50w0c", BLSPublicKey: "b3936555a070e26f17f7f718a59ca911b7babac3bfd5aaae2d3a92604872b56e2eb5c2aa762e82cbc11c1bccc481fd04"}, + {Index: " 588 ", Address: "one1nag927g3kkmqv90zzdtjqufqnmrhfd95669xmg", BLSPublicKey: "e5917a0d65494ca90f634402231a8527ec9f7a98a280b09cbcd7a87fe64b275aaa3502fe332305e6f6f580d1df9b0a16"}, + {Index: " 589 ", Address: "one1a9h4243kwm8t0m8seay9anhd6tnpjqp7z2lt8q", BLSPublicKey: "ed911d0f7afa3baefcb0dbad3efaf2d10c1a91ad7bcd7ee58d188969a21ec353eb87b3b3903cb213b25e79219d6a028e"}, + {Index: " 592 ", Address: "one1896gz9wxlne9vnea4pllfheyn3m3a3mq7z7jkp", BLSPublicKey: "0e790e10f49717e99be4fabf6ec497692557c81b6f932344e2877a7d1fe552874d7c79d99c366e25ddee27647e56ad94"}, + {Index: " 593 ", Address: "one162y782qyxsst93lgske76gcr3eeva5ugaq37f7", BLSPublicKey: "5186968254f56e62edc3781e20134344b32fdf38f53723918e02a746a2caf7065dfc738ea2bb17216fcaf97cf610ef09"}, + {Index: " 596 ", Address: "one1yyqdjhq865rhef6p8kh8v3cdqg8nk0z3pyfnx7", BLSPublicKey: "359c042fd49bd54f56c805d664a062284be4fd97dfc121431465ef94191ce8e17af4106a14a5f3c50530025cb4945c0a"}, + {Index: " 597 ", Address: "one1ruynv0wfu0tlt6mxja5m7exj8qns8jsyh34cu0", BLSPublicKey: "d76857e0a4732bd5d5368738c2fe1e96fddc92f8d099325d3846039661bc3e308ade6ff8928c4ee87f35c42f3d1a830b"}, + {Index: " 600 ", Address: "one14qvmnxm8dyknat2sxerdlju63z5ejue2d6vfc4", BLSPublicKey: "2cf5c0cbb3def2712e5f151d3205829f4abd30b1bc3f49f9422ae8331685f200a994f3122163267d274e7b0a453e4419"}, + {Index: " 601 ", Address: "one179turt3cf99tec82srez2l5fetrckvm3jhsqjc", BLSPublicKey: "f61ebd9b3b4d06a94901c74cc4ded7fb7af892a5f57f5777549e6efbcb7d437859028a952fb53821d89bc5324649c18b"}, + {Index: " 604 ", Address: "one1dlguvc6fjtw8yp86zd7eez2y0ecl2t058zzd5n", BLSPublicKey: "b8520aa59833a8692bb7c8821b967656dd371889ef83be6fc4cd44cebe1966d8a474546548bc0a89bc4f16537037cf0f"}, + {Index: " 605 ", Address: "one1p0z0spkesyacmsw3xvqd3hz7k0af0venkdl6kg", BLSPublicKey: "b3eb7aaf1a8f3e67ab77da84cdf1afa30072b84a7087747120f4b17aca0e13bf004f450e715812229d2c109551d14010"}, + {Index: " 608 ", Address: "one16pvxh9qgd5tf0ee2u7777nt6x0u204wy4tstxs", BLSPublicKey: "549bde3dce69c8e87ca1d2f7c2d75b96b8d8b10d9b9487676522b88e5eab65203c8103f660c993b09a7907cabb79ed85"}, + {Index: " 609 ", Address: "one160w0sw5u27w95h9q8s0aefp2at4vze6e5tzxj6", BLSPublicKey: "6f9baaca37150ba3ef66ea7f68433f41152c2587febe76ca1a40451afb8c93174abb369cac109d26315952030ec66a83"}, + {Index: " 612 ", Address: "one19rdv5vngkdga0mpyrwtw4gvh9kv0ywwhfzgqs7", BLSPublicKey: "909db0568d9dfef14adc538c880ab9d5a5e994f93acce6399516cb99526666ab7281baefe449dc586634240fbf26c987"}, + {Index: " 613 ", Address: "one183p7p5jhpd5v435jjudv9n4w7k0zg99hf38kpr", BLSPublicKey: "b0e7619660df7cc20329ee6692437aed99b33cd0c65475493ce635b96d90251c7cdb2c295fb39c737f3695329559f488"}, + {Index: " 616 ", Address: "one1mj8k8s0gynk854md5rz0ydavll44knr05z2y8u", BLSPublicKey: "6c73b8c6af05a5862c3e734fef680dcfa8e91991dade76443304dcbbbb5fa1cb5ee6fc9d49586b5cbb46758b60f41995"}, + {Index: " 617 ", Address: "one1sf3agmp4cejq6eaa6266t5q22qqv3j6c50snh8", BLSPublicKey: "f3e9e75872cd60043397065f5107e5f53f815d290a305117521dbc6c790a7baba4800be861f890646731da567b213984"}, + {Index: " 620 ", Address: "one1q46d5ut6nl2xqpmmqhtaj09zx95720s02q80cf", BLSPublicKey: "242390df1978e015bc72076ded4c238298abef17fd322e4ed0c99dc8e05722beeda79df1d3b16883a286e781ce1ffc00"}, + {Index: " 621 ", Address: "one1jsvf4flnkpf2vek33cjrw3adyml5w2rkc49rc0", BLSPublicKey: "7bac332aaa456dd5703e019b00adf29775507b85b3cf804c01b872c4ec3d061aa3efd8a2b80729b5b018dd6fac759180"}, + {Index: " 624 ", Address: "one14gj85plrdxwnlse3qynsqafzjnqs8n2ye2hl5x", BLSPublicKey: "9912c23efb089d31ea4bcf218f4db2d2190c324c9435de81643bf0120f8d7ea597dafa305cefd2407a63c2d1e7ad6490"}, + {Index: " 625 ", Address: "one1llccshaggpwx8v3a0nfml6vpvvwy6czzhzapyv", BLSPublicKey: "b683209de38bae60911f96d54fc64a72431624715f8d94bddd8bc8c98fad0c19d21ebefea4b2469e3fd2e02624d3b196"}, + {Index: " 628 ", Address: "one1nnn3ah2p0c2thfcgkprf2z45fd8l7xck7k94av", BLSPublicKey: "bb43b6e4ccd425de25074a5002065e8b3fbe9cbb3e1240aa8cc3333315b5c8338801b5000ad6a8ce2e8ac96c48bb410f"}, + {Index: " 629 ", Address: "one1vghxn0w64yhpkrd333uq2mcn70eky65xdnldc5", BLSPublicKey: "bd79809aed2dd837c417df7a6b3689d3ddc0ea6ab47692c7a8c29b27ac010dd4110418904d5d0e1e859211dfd2055e03"}, + {Index: " 632 ", Address: "one1vu63v592efy7l9mw7zms6tjfglmm2k27vrz7rp", BLSPublicKey: "954bddecd7ab7b95b3cc194c68488d5fa4c8061f2d0feb701a6ea4692ba6519a3cae65b4e9c9bf7e81c78bc0099c1983"}, + {Index: " 633 ", Address: "one1752d26tqy6xzq5r7q05a799498hl6f99e55dj9", BLSPublicKey: "226278f4a3241f5dc11b83b74750209ef3b5293feca9f419db8f66893af59e5632ccef6836e8d7ffdae135cccd737211"}, + {Index: " 636 ", Address: "one1k23afqflxe9gwpw7ug2zuzq869yfcpzl2c2reh", BLSPublicKey: "169c0cec1e2c7dde211ce53d10cf30243fc7f60718d547db8777aa266c5f41f787ea1be33601a12002d098d6aec9190a"}, + {Index: " 637 ", Address: "one1ajj9jgnvnnf74ydp5lr7qmxgw6jv0ttzsv2v0a", BLSPublicKey: "2e928f75f1b93c927297fe48bc4148bb3af7f662a6ceea25db82065aca7032869668924ac8cdb09a33447c2bdcac6b8f"}, + {Index: " 640 ", Address: "one1wvjmmrrm5xl5d7ukqc9u2t30ndc7a2gk6ee37q", BLSPublicKey: "9bfa44068dbe442dcc86636c403311be4b2aa09a5dcb352e62e72571ffabfe162d968b4d22f28a3b1540f6f6f7acdb06"}, + {Index: " 641 ", Address: "one17w24f4xsdwg0j34zvsecht5u08w5ynqeladn5f", BLSPublicKey: "e7c30550b0f4cb1885f1cf77146e32602be4447e59480b20351ae036ec1bb9f3cb0d3c609aeee59fb3349fb3302f0519"}, + {Index: " 644 ", Address: "one1tt97m6nw6mjwg4lj3uckqsc0hdn82kn9ukwntl", BLSPublicKey: "15c6142dd564d64b888a183d63cca3ded2ffaf95f69210b0ccf99f2bcb24b2b67ecf08fc607a83a028e5cac8d0a15711"}, + {Index: " 645 ", Address: "one1cawmtcxlvha9hxk72vdpccpujz2lud85yepshl", BLSPublicKey: "011cf30ceb44f51d2101b6bf37c19690642111930e11ad5c9b4aefbc670a20e97e8f25d18eecbfaf565bdb8409be0c81"}, + {Index: " 648 ", Address: "one1gxj02jy02f0fegz59xsl8y9l570mfe66y2kmck", BLSPublicKey: "e68af47a80574ce10eff52abdcbc97609d91b21d8980161783868474873f2c35acb1e149b9b6392bae3760a4ac75058d"}, + {Index: " 649 ", Address: "one10y35x3r08trhz8yfy0z0dlmrym0mhqu68ep8zp", BLSPublicKey: "c395345d687d1a89bb34e1771128d53a65656ab0de33f05524a840d5fbf3a6abeb7ef0f83182b9b4f365c5ed56995091"}, + {Index: " 652 ", Address: "one1cel2tkrszr97dez7sx7vzfssr369yk6dh4d658", BLSPublicKey: "03faf54df36a98fe50da5bec411910939a463110d744045fcd620ed85e315800234e6795e97bc85025b0812757fed203"}, + {Index: " 653 ", Address: "one1d7hwydu8clyz6spd48p2hwr3fn8ssh7hn3ucq3", BLSPublicKey: "8834fc9bc16bc2bc0ef665848991a2173387845f3844f31587897d75f15ca3f278fc090ef2284a0d1e1aa38eb3c7ae85"}, + {Index: " 656 ", Address: "one1qv6stetdse59g7l56umrwaegqlsa8zhzzzxjkp", BLSPublicKey: "de8a6261cba0ed1b9d9ab24e05fe596fc60bd17bc3aab039a0d07f98ccbe632afb9ebbefdefab6ce010d9e4210e9ad97"}, + {Index: " 657 ", Address: "one1lju00gv7z7zv9cacpq64c48mt8xasqlmdteec6", BLSPublicKey: "9cb173d0092fc755b2fd1192cff06860e022a19fd7a1f5fbe734d5e6477753919cb3224281fd63a69fcb1c06dbd79206"}, + {Index: " 660 ", Address: "one1ugzg5cn6l2ew8wk7dv6tm4ysx98vw0m7t5tj9s", BLSPublicKey: "db3c5170e2b2cb09ada243288deb8c8e456d76ad9fc22e89a8f4552bb41bb91d67a0eb225ef691023de052ee5962b985"}, + {Index: " 661 ", Address: "one13hxzw3q293zta8ny6enr4lqjjvywm4dz3kr5ar", BLSPublicKey: "2d3a95af9823223faa87bfce387e6f82fbe437167883233a49b2dd5cc6e6e0fcfb7921f60fc0903093aec1837dd8f08d"}, + {Index: " 664 ", Address: "one1ky5w77a8j837y82uhp3vtjuxw3pyl0eqjn3tpv", BLSPublicKey: "f09600a0b13aed6c8974dd89b1b5dd79a87ac4aa68fcb67f2203a74f2216c9ce8a3fe02c635ec3d838c4a3b938023911"}, + {Index: " 665 ", Address: "one1tzkdmhl52gen8kulut8fxcxa97q02a60t04akl", BLSPublicKey: "6e0e390391d1c204333bb1de87a650bad0c501bddd625ce85e10837dad1febd14036640a2364beed62bc333bb48c3392"}, + {Index: " 668 ", Address: "one1f70vw8y5nxq5eq33vwfcr5wtlzwa5zfguewj9l", BLSPublicKey: "fbfadc62ab177d215f68d520418ef1b5a5b14ebf4b283d17428298ef07ceeb328f1dca33705705e1f150007859754399"}, + {Index: " 669 ", Address: "one17sdvecywxf604c0z7349278zdxwmy0r28e3rhd", BLSPublicKey: "00ee94447564bf4e3dbcab9ac3796fc0fe61c0d69c2e637e55b97b482d2365b89ac9390a5695b14fa99714c598429082"}, + {Index: " 672 ", Address: "one1x34tcthev3k7dkry4khr8mmc539aqeug36uwaw", BLSPublicKey: "f5f2f3bddac012235f74b739c94732b2603746dc96699c6f73bd4697158a83468409e16d023f9cea84b13c9a9cc80e88"}, + {Index: " 673 ", Address: "one136la0ye4wah2twka5wec6w3qs6zax27krxxzah", BLSPublicKey: "f1ad239b91acd31217f232bd5530ccbbe4f8f819fc24292d14166acc364fecfc077bbd053a0e5c233ccd515e86a7e78e"}, + {Index: " 676 ", Address: "one194rdaj07wqar35zwxjnz8fyd754phur40ctt24", BLSPublicKey: "9179e0fe94bc73915c00ef41001f296a67d5e28fd92e74a5c68315496ad80521c1563192acbae0e1f47581f323ae5983"}, + {Index: " 677 ", Address: "one1wu3uvjgswkx0cqfdyjha4cs85dergpc4teswq9", BLSPublicKey: "f43552a73b6726c9ecba97a7e796cfbc86baded01c83ca875cca12c06630b3bc96ad02c7fc262f5ae04f9c57d8310885"}, + {Index: " 680 ", Address: "one1uuqzehdgk0lxtw6fpkqy9cwdtzjnjr48kjxxx5", BLSPublicKey: "87c7f6e0476392e88953e2c76839fcc41ba822178cfc8122b3b4c0cf9d4cb0908c8acd8c877281f7b731c06c136d780a"}, + {Index: " 681 ", Address: "one1a3jx4m4vtgn55j74ea5yqk6mv92re3jme7zynh", BLSPublicKey: "651c2bd036efba1698de6f2a9481ea2750aa9811197e560fee55830b9f99da1ba1f7b5fbbac166c8397f73ed3ec0e20e"}, + {Index: " 684 ", Address: "one10htague943jp9vdp624t6ysmcw6edlnnl26r3y", BLSPublicKey: "55bbee339fa1821768c47c820b73aba2daa3a6a3143c6dd2169fcd206fa076784898cffae91ca31877a3a8dad206d791"}, + {Index: " 685 ", Address: "one1ky5syc5ggmg7tmvz4lvgd68xetgacsay4vnmqx", BLSPublicKey: "72b5c4036c10bc79f733a3d38daea288ee91af5838c78f83e3a774ed9c3630b42651c86df07b3b77ee1ba3891084e60f"}, + {Index: " 688 ", Address: "one1cgsrjw0uzv4pqtvvuppef68kk9tz4xmdu9prel", BLSPublicKey: "696e60fe38e396b41ddced9b46a2cf4c1efe74dc2ab990f53be41f4d225a1652b6a3c6766a1c7dd6abc7e16693365480"}, + {Index: " 689 ", Address: "one12qv54g8r9rpu0q9qsjn8zpqm7sjqdef0r36xcx", BLSPublicKey: "7ed29a23c9dee127c8784a2a8ee09e4d3a84db49fe25009ba3427116b8d939225e49e4cde89b9ff803fb6546c9a50711"}, + {Index: " 692 ", Address: "one1cw67f3sn60kvglmp95ljf764r3jetc9rwxph08", BLSPublicKey: "fbf6fc4c014335681bb3bac779bc204df6c90c927ff83f6e2aeccbf382e9227a8c50ffc46ce1119c64ca1306e1955203"}, + {Index: " 693 ", Address: "one1vee48z2fhhgf6h00g3pxsamq5lnt4tc75p3h9y", BLSPublicKey: "e1d83860818ebef5452b715462a8700f1bf3b6dea2ddd8d15f17f4464fad4c0d2bba426b9ec1c7df0fa170fa22d3d481"}, + {Index: " 696 ", Address: "one1fkn599paqhqdgkm0nccsf5jflext70jxdd7e7q", BLSPublicKey: "a204a5dcf9b8dbbc3f0168ffea118588c397e15832bbc11b69a42fbc5c97f76e8b67e0a8170f6285032402fda3a6768e"}, + {Index: " 697 ", Address: "one13em34f3a6lkm9m6aedrm284jythtlg0y4l7ytp", BLSPublicKey: "b4a3b85e76bb55765927fa7b3b1fa2d3c2468af10a8c0b0779b26d1bf25b6e093d55cf0fc52c0fdcbf3d3805e8724d96"}, + {Index: " 700 ", Address: "one1ju0m9t5dux9pwdwjnej0hekfau7ecds32ytjwe", BLSPublicKey: "e75e425b29a84a9bcffb9ddbe10aa132aab965d3310bd0cf266b72d5664ac1e77dadd3ada3bc883180701ed48498b014"}, + {Index: " 701 ", Address: "one15lque84s325tq8hjjgyk00cjtzz2urs9q90075", BLSPublicKey: "1e965c488613028c25d2766033536d3945aeb1ec77fb5dc0d1d878b2262622674822aac1f99d2cf86299dec59a96e881"}, + {Index: " 704 ", Address: "one1n5ep36kln3y4536qzarets5x9tcqzgfzj5etf5", BLSPublicKey: "95e418d0876e6f2fa39bff6bff59e8273f14eadeb1b6c5d7fe532958477596b2b2672e455c992d7b926e8f2d8d35748e"}, + {Index: " 705 ", Address: "one1f495vn4qpkqs5ueu3mfyeap4pkkkccectjtw08", BLSPublicKey: "31a4150b05ccedfc46a4cee712e266f836650d53850e76b9129ecc4c32833f390ead1e384dd69970fa5683f8420cb985"}, + {Index: " 708 ", Address: "one16cjqga90ms6ne9hnzda9d0d9pvwwuxd270pzf4", BLSPublicKey: "5dca0f8185ab8814b570861adaae936e87921b3cd93008b8a24e778643cd3f2dc56bccc81542900e4b6e376c0c169310"}, + {Index: " 709 ", Address: "one1ustd0zm3l3x8h0s4jtc5eaquhp3vfxmgq4k3jh", BLSPublicKey: "5f60c7f1c14ae4966d1d5c0fc8ab2571111313ab2344c3aa1593fdb91c74ecb385d20b3072b4dcac36f042d57af4650e"}, + {Index: " 712 ", Address: "one10kf6cugzzyw2eg2tdk66fcfw847jzdq6phz74h", BLSPublicKey: "b6bf1de29dcc9647b8414a7f4e3f6a2d1e00e8fc282f89f560c66be704958ef617f83dcbe1bcb95dd9d6d9651a52bc0b"}, + {Index: " 713 ", Address: "one19hjulxkwta48m6yksfp7ypepcuptz6fryt8e4u", BLSPublicKey: "65b2b22e9c0f18e7624952d2db04f8ac450de6e8873fe2b429ce67b32b614cace3783dfca84ba611e5947c47abbb3712"}, + {Index: " 716 ", Address: "one1u626nxz6hdwn064dsqh32qmz44y02phyn9xl65", BLSPublicKey: "706b7856b3815a786e2ef5c93ba3c422c14d57b49eb5ba7d993ed392b18a2ba2a614b7578a9f5eff12d050ce202d4a85"}, + {Index: " 717 ", Address: "one1pa7xx8t08llukj66kpdpcl3jrjpzvv3gepcz90", BLSPublicKey: "9f3505188f1aabf9d1d864fa2655376acde3dda7ecd9596341144c188e97d3fa712bbab5e628c178d566468b8e864001"}, + {Index: " 720 ", Address: "one124cskagud8kmag9rmcnc4p9d5wqn5wkm0x3rla", BLSPublicKey: "3fd76a72cde0e91e7ff3849bb800aa88fa123ef0fbc504328e4e2a8c457ae766ed9e2422a9272a5edd96e33b5719320a"}, + {Index: " 721 ", Address: "one17dwmglcm5uffrdmye7dp7njrg4rhmn9qnsq7zs", BLSPublicKey: "539343e5507f2be080c10997eebd113df7b2db7e5cf77ebf5428fbf62e0d724baf0b4d139c830acf0dd4d2505c28fa81"}, + {Index: " 724 ", Address: "one1tmqkgermcyuv55686322j0wgy83z8zwnm977w3", BLSPublicKey: "a667572a798036e1afadcb88f0d974babba45e34a66e29c8de332fe65094c6bebf03eacd41843cb47bb4cb0a62c8a205"}, + {Index: " 725 ", Address: "one15l2e5c74mk90kds44frk5krgy67kk7sfuzkd00", BLSPublicKey: "4da2dda2eccbf4024f72383c7a7f2d9600c71cdfe3c5ce5101ab0bd5fe9ee042ad7e7ff8edc0a655b237598df723bc8d"}, + {Index: " 728 ", Address: "one1u8rkerahatqz6ut3d00muung8mfhp0kf5z02qz", BLSPublicKey: "fdbbd4b21f8e78b203de45b57447905e3afe9ac1c852510d02e0ec8a30fa68cb50ea9788e95ae6fb618d6c2938eba015"}, + {Index: " 729 ", Address: "one1krmdxfqwy89hhl2jl38lzfrk6uaj2lzeypq6v8", BLSPublicKey: "3973ed4fe794207427a052a547350803f61df9b81463846e8b7eda35b1ca630400997938593980a2b8dfb623b17bb691"}, + {Index: " 732 ", Address: "one1asc7k20nkayu52u82c22ew00hckq6czk85latq", BLSPublicKey: "29690e83ccdfbf6406fbea9c7f48ad67bb1467a79ae84e779d65aa10ae5db437b624ab005c45247cc55cb8ef4722f78d"}, + {Index: " 733 ", Address: "one17facy58xh3yee0jhaesj4044j5nvrfdqu7mtmm", BLSPublicKey: "2adbeafe0a2e90b9e90fb40a9838c2b8f80d729a15a6e38b175da55788f639a41bc5c8853e8c02e4a17fdcf2b6b6dd14"}, + {Index: " 736 ", Address: "one1qls5c03e4gn3h9lm9t6r0uhhg8ld2h05szc647", BLSPublicKey: "0f60effcaecef5774508002c451515da69f898b9e658ba4b53c1bed5ee7112de6b7b09183d961582a363832c575c6d95"}, + {Index: " 737 ", Address: "one104d96j0n2wvxk2q4hzw455fgj0gxq2sqegh6hm", BLSPublicKey: "8a4cb7a7dc9166492831951a6085a7df10e6d4492f6a8b10ac42eb94a74fe0b7a503d85cc859a9e7fe026dc4b3bee007"}, + {Index: " 740 ", Address: "one1plyn69vck7dnrxydlhsz962dfyc7aj4xfvrn3p", BLSPublicKey: "05d53371a265f2981d4f433eecdab808c9a351323eddf4ff722fb81bdd3e9b41cbf05f685c8d73dc3e1e8268d8fede8d"}, + {Index: " 741 ", Address: "one14nu6w5jnnx9exc98hkx98l0smxgt0kwkyym3hd", BLSPublicKey: "15fead53ed6ce16571ae4c6578e6947baf293e72e8aadc465bc655bad419c4aa94809ddb7d1a44c18713d505d4836a0f"}, + {Index: " 744 ", Address: "one1s38uzczd8s8nj69hrv4lkjv5msvgvrkcf7838n", BLSPublicKey: "59a49852b74712012ffa6640a53b66063f027945563eebadb4f6215ed3b3db2e2ae8f7c6474a3c68139f45c1179e6816"}, + {Index: " 745 ", Address: "one1a8djqrqj5uqnmvmdk5qm6cwmz7nz6zgcunytdg", BLSPublicKey: "ff2e266a92477510842874f5db7d68f8b676d2bdc9b40bb51f2a47177b8b0fce61393c23a1d1c721305dce931d49458a"}, + {Index: " 748 ", Address: "one1qctuk3zukhnzcl7484dq37pcvmatal5g84v6q9", BLSPublicKey: "e52dfc7662712f35392cab9cab95fe8f268b8bc8c47e014b046a320fe3f0c8f7c0697ebd555bd16ea226309ee80b4881"}, + {Index: " 749 ", Address: "one1x6jzswk854wpvzauq49qru7alp7vdfmjyyzl40", BLSPublicKey: "943abfb88d1b125b046d76f056f07d3e1813618f4b76a9e69e281052a2b6bcdbada67cf852d39dc575e50174f0703405"}, + {Index: " 752 ", Address: "one1sk4g502rw6f5fz3rhdhskwzmkxy5c3f9dfhffw", BLSPublicKey: "4b6e2dbb45cfd9491f0d5d0bf6b152c67dde7585501268565eb392410e6e2b748e454194df8fcde91242a4d43afccb83"}, + {Index: " 753 ", Address: "one1h550h8m9scfcpkr7tm7v000tkrte225n6whl4x", BLSPublicKey: "8612fe87348188e408263a4fd3558ee26cfb8dbd194ab6d0e05a182d57bb20c7942ac9595f378dd44cb0d369555ab60d"}, + {Index: " 756 ", Address: "one1x2aw9nj6lunf5qa8zkw9duzd0fy4zh6pamz3e4", BLSPublicKey: "a7f4d046de8a1f1a99be64b6c9cca0ce48610605d4507c7b6ad7f54a450ced171f237d8b0bacd19e6c6e18927ab92916"}, + {Index: " 757 ", Address: "one1n30nql6474r0kzeyp5rtp7436jjj43ylty7r5j", BLSPublicKey: "2f95f3382e11dcf1dd7f462dbf879a806d063a5e79e448456e1078b1beb3c3b1f38b6ca9d04ecec3add843ffd946c489"}, + {Index: " 760 ", Address: "one1uca2sp9a7vz7rzdaucm73q6uuu7l0slv2q8vnm", BLSPublicKey: "285000a79bb038e985a92459a2efc8c09105e610d7a5f6e97df98cc8d510780ff55e69447d1767054f5714e245ef6f02"}, + {Index: " 761 ", Address: "one1t95j4t7uvz93veq65tz2kshx8jk84sz929vccz", BLSPublicKey: "63149e8a6ea1a63bbd21379a6aa8133f9ae6392916b6710e586edf1c9e6754757457545ce8f6cee66c569b46b23fcf0f"}, + {Index: " 764 ", Address: "one1tlzxwhllrat5fegd39pfyt5rzc0u9sr4fx8dxc", BLSPublicKey: "76efa88a05efb817a25be18b1bd671555c1938935e3ecabb1ceba1f88cae68add8a942f54bf6473e4fd19788a562a393"}, + {Index: " 765 ", Address: "one1c4lmqgln0all7gnmy36h6etk805ra2g8vwyvs3", BLSPublicKey: "4a611140e951b2a91c31a9839a8dd684641fc0430243359a48c76828a5f9b25240be1342686bcca43813feac83e54a16"}, + {Index: " 768 ", Address: "one1gm7ts7rt2xatu8d6m4dj6ydt3z9qtpzn0lu7cy", BLSPublicKey: "ba33d39c9380ffe740c527b6bf328765c50d004d8339d3e3a0570a529522f72cb0d2e3c8c3f91c71ef05b175be64b80c"}, + {Index: " 769 ", Address: "one1e497p9fv949zuh79xhm3rd426xnnwcnsxnsv0z", BLSPublicKey: "279664f37a81b43ad3e356f5fc10cbfceded208dde25b33e5ddeb5fe5a319a63c9645e671f38adc9e96e47b1c2028708"}, + {Index: " 772 ", Address: "one192ly7vkgmyn80rpl4ql9dq4q07rn26llh6xws4", BLSPublicKey: "d9bcfe03a9a23decbb22ff147d94d609cee64dfc2f711b25a3201d43b12be3b880bd22503be43e2a974e4d28d8fb3712"}, + {Index: " 773 ", Address: "one172acg2z6n9nut7a9mn8j8pl926v4ja7wjwp5js", BLSPublicKey: "260287f785a1150fe3499c6e634bca63ac6c89bf935a8f831e146f3d494ded68d77f4b71555479b437e15c4014544502"}, + {Index: " 776 ", Address: "one1e2sdk7e98sjd07mesh2z3kanhk78n9dajc6xw2", BLSPublicKey: "8cd9459f4a546236b53dfef3ac68524a096ebdfe2690bad6d530ba5e850011ef05f014a72a4a3f95c90a615576557395"}, + {Index: " 777 ", Address: "one1jr3ame92657c8xg628qym5035j6fj4lv5m9wsv", BLSPublicKey: "0d7f709c9e562c1caed8c3769c03d5a47390a5cff2fbf973c0845f60d9132a97fd0bebb94c1d8e34ffd091e2a796148f"}, + {Index: " 780 ", Address: "one1kpu7ymtjcu3g7pcjknp4gxjrvsgksukewze0e8", BLSPublicKey: "5fac88f67ccef82aa9e5de9d4fc3a404baa6b7c2953422c779df99743eb21e3ee2c150198c869e7e9a6c4f5778554106"}, + {Index: " 781 ", Address: "one1zfrv5yverxxrcl065jwemsjw8e0faddvk7eee8", BLSPublicKey: "bade3372ad23e05b99e712f36d1d226bcd6f80f9a83625c042c2bfca1ac4f2aec9d79d0bc5fb7246e77357238f59f501"}, + {Index: " 784 ", Address: "one1facpv5g2qjegx97su83al7tzruruucnqce4xxe", BLSPublicKey: "3702bda52cad8e3b198188e6ceed15be50ba3c806b074b158e8cc6d7cf4b0f373913a85d33aeb4e64d9ba9c241dc4681"}, + {Index: " 785 ", Address: "one1c06aqrjy7p2l0jst6znhmfvg4f2vsaltwg6t6r", BLSPublicKey: "7e6c9d73b767de31cc992978f15c61d90b229343472ee22cac62990ca2578197dfd365bd5fc0e4de8ae2f9645b483d08"}, + {Index: " 788 ", Address: "one1x56753w9a37gfvtft38uwftehzn6u5z72l8x4u", BLSPublicKey: "ba834e43b8b8a6427960e02f485354bb1bec4fb7091f98bef503ac36dae72a614eb4c89c1cd3a8b08b2d2adbba6c6f15"}, + {Index: " 789 ", Address: "one19dsah5q49r6zg6hmkp5s5j042y8rau3sn0clpn", BLSPublicKey: "b7cc10c8777903aa49867a7f128cc51dbc5bd52ccc626e21035685f5c5f3de12d9ff9ad947398b59cdb40aba31a1ad11"}, + {Index: " 792 ", Address: "one1lpajddtl2hn4ghh0d3ndulhl0n3vq339svfenq", BLSPublicKey: "518cac76104f84f0b85d9ef9d032e0ba9a3b0560c62abb11625c67149d24f06c6e2f42941d96a9faebc32834a41a1702"}, + {Index: " 793 ", Address: "one1955anhqvh5ty4zvej6q7cmz7lhee0sqhpxwll9", BLSPublicKey: "c65ed895cc99cd6c1b591655969f3c440175f4a9422fc20273e4c449e95c86e4f8c0dd419e3345b833ca3763d08dc610"}, + {Index: " 796 ", Address: "one1227mts6xmt5c25nllp6hxfgknfct6jw6ljs4e5", BLSPublicKey: "a68d9749bceae897217962e9634a2ab2a8ead9c0631fbe50e2edc0b7cd5ad994f44153d3f364e800e4f20abf02f54d90"}, + {Index: " 797 ", Address: "one1hkgmye3nk0943c67yvpq05spzvpsv8k7dylr26", BLSPublicKey: "904a3527107fc9d1947020810ae0ff222d83ca367e96edd2c3e18a19bacd194acafc05ccff2a96ffc5b1a061e4cf0795"}, + {Index: " 800 ", Address: "one1etve7cfx8h5ufy360l33v6fj4klv9pyjggwax2", BLSPublicKey: "239cadb7e4d39e715bd45979d5ca870a5f8c7f773100260c547b5e4a9098e25c536d859c3a85c683c3ad3350c4e5a583"}, + {Index: " 801 ", Address: "one17mfpwyg0yuphz5xtwx8jc3cadrdsgjgwh9lu2j", BLSPublicKey: "f2b8c137c9e76ed7f7f68fd22efe6cb5cf0456bb8a86af043634c47f30105f211e59d7adf7452ccbc7c72a064b62a208"}, +} diff --git a/internal/params/config.go b/internal/params/config.go index 7cd31bb9df..86695ba40e 100644 --- a/internal/params/config.go +++ b/internal/params/config.go @@ -36,250 +36,262 @@ var once sync.Once var ( // MainnetChainConfig is the chain parameters to run a node on the main network. MainnetChainConfig = &ChainConfig{ - ChainID: MainnetChainID, - EthCompatibleChainID: EthMainnetShard0ChainID, - EthCompatibleShard0ChainID: EthMainnetShard0ChainID, - EthCompatibleEpoch: big.NewInt(442), // Around Thursday Feb 4th 2020, 10AM PST - CrossTxEpoch: big.NewInt(28), - CrossLinkEpoch: big.NewInt(186), - AggregatedRewardEpoch: big.NewInt(689), // Around Wed Sept 15th 2021 with 3.5s block time - StakingEpoch: big.NewInt(186), - PreStakingEpoch: big.NewInt(185), - QuickUnlockEpoch: big.NewInt(191), - FiveSecondsEpoch: big.NewInt(230), - TwoSecondsEpoch: big.NewInt(366), // Around Tuesday Dec 8th 2020, 8AM PST - SixtyPercentEpoch: big.NewInt(530), // Around Monday Apr 12th 2021, 22:30 UTC - RedelegationEpoch: big.NewInt(290), - NoEarlyUnlockEpoch: big.NewInt(530), // Around Monday Apr 12th 2021, 22:30 UTC - VRFEpoch: big.NewInt(631), // Around Wed July 7th 2021 - PrevVRFEpoch: big.NewInt(689), // Around Wed Sept 15th 2021 with 3.5s block time - MinDelegation100Epoch: big.NewInt(631), // Around Wed July 7th 2021 - MinCommissionRateEpoch: big.NewInt(631), // Around Wed July 7th 2021 - MinCommissionPromoPeriod: big.NewInt(100), - EPoSBound35Epoch: big.NewInt(631), // Around Wed July 7th 2021 - EIP155Epoch: big.NewInt(28), - S3Epoch: big.NewInt(28), - DataCopyFixEpoch: big.NewInt(689), // Around Wed Sept 15th 2021 with 3.5s block time - IstanbulEpoch: big.NewInt(314), - ReceiptLogEpoch: big.NewInt(101), - SHA3Epoch: big.NewInt(725), // Around Mon Oct 11 2021, 19:00 UTC - HIP6And8Epoch: big.NewInt(725), // Around Mon Oct 11 2021, 19:00 UTC - StakingPrecompileEpoch: big.NewInt(871), // Around Tue Feb 11 2022 - ChainIdFixEpoch: big.NewInt(1323), // Around Wed 8 Feb 11:30PM UTC - SlotsLimitedEpoch: big.NewInt(999), // Around Fri, 27 May 2022 09:41:02 UTC with 2s block time - CrossShardXferPrecompileEpoch: big.NewInt(1323), // Around Wed 8 Feb 11:30PM UTC - AllowlistEpoch: EpochTBD, - LeaderRotationExternalNonBeaconLeaders: EpochTBD, - LeaderRotationExternalBeaconLeaders: EpochTBD, - FeeCollectEpoch: big.NewInt(1535), // 2023-07-20 05:51:07+00:00 - ValidatorCodeFixEpoch: big.NewInt(1535), // 2023-07-20 05:51:07+00:00 + ChainID: MainnetChainID, + EthCompatibleChainID: EthMainnetShard0ChainID, + EthCompatibleShard0ChainID: EthMainnetShard0ChainID, + EthCompatibleEpoch: big.NewInt(442), // Around Thursday Feb 4th 2020, 10AM PST + CrossTxEpoch: big.NewInt(28), + CrossLinkEpoch: big.NewInt(186), + AggregatedRewardEpoch: big.NewInt(689), // Around Wed Sept 15th 2021 with 3.5s block time + StakingEpoch: big.NewInt(186), + PreStakingEpoch: big.NewInt(185), + QuickUnlockEpoch: big.NewInt(191), + FiveSecondsEpoch: big.NewInt(230), + TwoSecondsEpoch: big.NewInt(366), // Around Tuesday Dec 8th 2020, 8AM PST + SixtyPercentEpoch: big.NewInt(530), // Around Monday Apr 12th 2021, 22:30 UTC + RedelegationEpoch: big.NewInt(290), + NoEarlyUnlockEpoch: big.NewInt(530), // Around Monday Apr 12th 2021, 22:30 UTC + VRFEpoch: big.NewInt(631), // Around Wed July 7th 2021 + PrevVRFEpoch: big.NewInt(689), // Around Wed Sept 15th 2021 with 3.5s block time + MinDelegation100Epoch: big.NewInt(631), // Around Wed July 7th 2021 + MinCommissionRateEpoch: big.NewInt(631), // Around Wed July 7th 2021 + MinCommissionPromoPeriod: big.NewInt(100), + EPoSBound35Epoch: big.NewInt(631), // Around Wed July 7th 2021 + EIP155Epoch: big.NewInt(28), + S3Epoch: big.NewInt(28), + DataCopyFixEpoch: big.NewInt(689), // Around Wed Sept 15th 2021 with 3.5s block time + IstanbulEpoch: big.NewInt(314), + ReceiptLogEpoch: big.NewInt(101), + SHA3Epoch: big.NewInt(725), // Around Mon Oct 11 2021, 19:00 UTC + HIP6And8Epoch: big.NewInt(725), // Around Mon Oct 11 2021, 19:00 UTC + StakingPrecompileEpoch: big.NewInt(871), // Around Tue Feb 11 2022 + ChainIdFixEpoch: big.NewInt(1323), // Around Wed 8 Feb 11:30PM UTC + SlotsLimitedEpoch: big.NewInt(999), // Around Fri, 27 May 2022 09:41:02 UTC with 2s block time + CrossShardXferPrecompileEpoch: big.NewInt(1323), // Around Wed 8 Feb 11:30PM UTC + AllowlistEpoch: EpochTBD, + LeaderRotationInternalValidatorsEpoch: EpochTBD, + LeaderRotationExternalValidatorsEpoch: EpochTBD, + FeeCollectEpoch: big.NewInt(1535), // 2023-07-20 05:51:07+00:00 + ValidatorCodeFixEpoch: big.NewInt(1535), // 2023-07-20 05:51:07+00:00 + HIP30Epoch: big.NewInt(1673), // 2023-11-02 17:30:00+00:00 + BlockGas30MEpoch: big.NewInt(1673), // 2023-11-02 17:30:00+00:00 } // TestnetChainConfig contains the chain parameters to run a node on the harmony test network. TestnetChainConfig = &ChainConfig{ - ChainID: TestnetChainID, - EthCompatibleChainID: EthTestnetShard0ChainID, - EthCompatibleShard0ChainID: EthTestnetShard0ChainID, - EthCompatibleEpoch: big.NewInt(0), - CrossTxEpoch: big.NewInt(0), - CrossLinkEpoch: big.NewInt(2), - AggregatedRewardEpoch: big.NewInt(2), - StakingEpoch: big.NewInt(2), - PreStakingEpoch: big.NewInt(1), - QuickUnlockEpoch: big.NewInt(0), - FiveSecondsEpoch: big.NewInt(0), - TwoSecondsEpoch: big.NewInt(2), - SixtyPercentEpoch: big.NewInt(2), - RedelegationEpoch: big.NewInt(2), - NoEarlyUnlockEpoch: big.NewInt(2), - VRFEpoch: big.NewInt(2), - PrevVRFEpoch: big.NewInt(2), - MinDelegation100Epoch: big.NewInt(2), - MinCommissionRateEpoch: big.NewInt(2), - MinCommissionPromoPeriod: big.NewInt(2), - EPoSBound35Epoch: big.NewInt(2), - EIP155Epoch: big.NewInt(0), - S3Epoch: big.NewInt(0), - DataCopyFixEpoch: big.NewInt(0), - IstanbulEpoch: big.NewInt(0), - ReceiptLogEpoch: big.NewInt(0), - SHA3Epoch: big.NewInt(0), - HIP6And8Epoch: big.NewInt(2), - StakingPrecompileEpoch: big.NewInt(2), - SlotsLimitedEpoch: big.NewInt(2), - ChainIdFixEpoch: big.NewInt(0), - CrossShardXferPrecompileEpoch: big.NewInt(2), - AllowlistEpoch: big.NewInt(2), - LeaderRotationExternalNonBeaconLeaders: EpochTBD, - LeaderRotationExternalBeaconLeaders: EpochTBD, - FeeCollectEpoch: big.NewInt(1296), // 2023-04-28 07:14:20+00:00 - ValidatorCodeFixEpoch: big.NewInt(1296), // 2023-04-28 07:14:20+00:00 + ChainID: TestnetChainID, + EthCompatibleChainID: EthTestnetShard0ChainID, + EthCompatibleShard0ChainID: EthTestnetShard0ChainID, + EthCompatibleEpoch: big.NewInt(0), + CrossTxEpoch: big.NewInt(0), + CrossLinkEpoch: big.NewInt(2), + AggregatedRewardEpoch: big.NewInt(2), + StakingEpoch: big.NewInt(2), + PreStakingEpoch: big.NewInt(1), + QuickUnlockEpoch: big.NewInt(0), + FiveSecondsEpoch: big.NewInt(0), + TwoSecondsEpoch: big.NewInt(2), + SixtyPercentEpoch: big.NewInt(2), + RedelegationEpoch: big.NewInt(2), + NoEarlyUnlockEpoch: big.NewInt(2), + VRFEpoch: big.NewInt(2), + PrevVRFEpoch: big.NewInt(2), + MinDelegation100Epoch: big.NewInt(2), + MinCommissionRateEpoch: big.NewInt(2), + MinCommissionPromoPeriod: big.NewInt(2), + EPoSBound35Epoch: big.NewInt(2), + EIP155Epoch: big.NewInt(0), + S3Epoch: big.NewInt(0), + DataCopyFixEpoch: big.NewInt(0), + IstanbulEpoch: big.NewInt(0), + ReceiptLogEpoch: big.NewInt(0), + SHA3Epoch: big.NewInt(0), + HIP6And8Epoch: big.NewInt(2), + StakingPrecompileEpoch: big.NewInt(2), + SlotsLimitedEpoch: big.NewInt(2), + ChainIdFixEpoch: big.NewInt(0), + CrossShardXferPrecompileEpoch: big.NewInt(2), + AllowlistEpoch: big.NewInt(2), + LeaderRotationInternalValidatorsEpoch: EpochTBD, + LeaderRotationExternalValidatorsEpoch: EpochTBD, + FeeCollectEpoch: big.NewInt(1296), // 2023-04-28 07:14:20+00:00 + ValidatorCodeFixEpoch: big.NewInt(1296), // 2023-04-28 07:14:20+00:00 + HIP30Epoch: big.NewInt(2176), // 2023-10-12 10:00:00+00:00 + BlockGas30MEpoch: big.NewInt(2176), // 2023-10-12 10:00:00+00:00 } // PangaeaChainConfig contains the chain parameters for the Pangaea network. // All features except for CrossLink are enabled at launch. PangaeaChainConfig = &ChainConfig{ - ChainID: PangaeaChainID, - EthCompatibleChainID: EthPangaeaShard0ChainID, - EthCompatibleShard0ChainID: EthPangaeaShard0ChainID, - EthCompatibleEpoch: big.NewInt(0), - CrossTxEpoch: big.NewInt(0), - CrossLinkEpoch: big.NewInt(2), - AggregatedRewardEpoch: big.NewInt(3), - StakingEpoch: big.NewInt(2), - PreStakingEpoch: big.NewInt(1), - QuickUnlockEpoch: big.NewInt(0), - FiveSecondsEpoch: big.NewInt(0), - TwoSecondsEpoch: big.NewInt(0), - SixtyPercentEpoch: big.NewInt(0), - RedelegationEpoch: big.NewInt(0), - NoEarlyUnlockEpoch: big.NewInt(0), - VRFEpoch: big.NewInt(0), - PrevVRFEpoch: big.NewInt(0), - MinDelegation100Epoch: big.NewInt(0), - MinCommissionRateEpoch: big.NewInt(0), - MinCommissionPromoPeriod: big.NewInt(10), - EPoSBound35Epoch: big.NewInt(0), - EIP155Epoch: big.NewInt(0), - S3Epoch: big.NewInt(0), - DataCopyFixEpoch: big.NewInt(0), - IstanbulEpoch: big.NewInt(0), - ReceiptLogEpoch: big.NewInt(0), - SHA3Epoch: big.NewInt(0), - HIP6And8Epoch: big.NewInt(0), - StakingPrecompileEpoch: big.NewInt(2), // same as staking - ChainIdFixEpoch: big.NewInt(0), - SlotsLimitedEpoch: EpochTBD, // epoch to enable HIP-16 - CrossShardXferPrecompileEpoch: big.NewInt(1), - AllowlistEpoch: EpochTBD, - LeaderRotationExternalNonBeaconLeaders: EpochTBD, - LeaderRotationExternalBeaconLeaders: EpochTBD, - FeeCollectEpoch: EpochTBD, - ValidatorCodeFixEpoch: EpochTBD, + ChainID: PangaeaChainID, + EthCompatibleChainID: EthPangaeaShard0ChainID, + EthCompatibleShard0ChainID: EthPangaeaShard0ChainID, + EthCompatibleEpoch: big.NewInt(0), + CrossTxEpoch: big.NewInt(0), + CrossLinkEpoch: big.NewInt(2), + AggregatedRewardEpoch: big.NewInt(3), + StakingEpoch: big.NewInt(2), + PreStakingEpoch: big.NewInt(1), + QuickUnlockEpoch: big.NewInt(0), + FiveSecondsEpoch: big.NewInt(0), + TwoSecondsEpoch: big.NewInt(0), + SixtyPercentEpoch: big.NewInt(0), + RedelegationEpoch: big.NewInt(0), + NoEarlyUnlockEpoch: big.NewInt(0), + VRFEpoch: big.NewInt(0), + PrevVRFEpoch: big.NewInt(0), + MinDelegation100Epoch: big.NewInt(0), + MinCommissionRateEpoch: big.NewInt(0), + MinCommissionPromoPeriod: big.NewInt(10), + EPoSBound35Epoch: big.NewInt(0), + EIP155Epoch: big.NewInt(0), + S3Epoch: big.NewInt(0), + DataCopyFixEpoch: big.NewInt(0), + IstanbulEpoch: big.NewInt(0), + ReceiptLogEpoch: big.NewInt(0), + SHA3Epoch: big.NewInt(0), + HIP6And8Epoch: big.NewInt(0), + StakingPrecompileEpoch: big.NewInt(2), // same as staking + ChainIdFixEpoch: big.NewInt(0), + SlotsLimitedEpoch: EpochTBD, // epoch to enable HIP-16 + CrossShardXferPrecompileEpoch: big.NewInt(1), + AllowlistEpoch: EpochTBD, + LeaderRotationInternalValidatorsEpoch: EpochTBD, + LeaderRotationExternalValidatorsEpoch: EpochTBD, + FeeCollectEpoch: EpochTBD, + ValidatorCodeFixEpoch: EpochTBD, + HIP30Epoch: EpochTBD, + BlockGas30MEpoch: big.NewInt(0), } // PartnerChainConfig contains the chain parameters for the Partner network. // This is the Devnet config PartnerChainConfig = &ChainConfig{ - ChainID: PartnerChainID, - EthCompatibleChainID: EthPartnerShard0ChainID, - EthCompatibleShard0ChainID: EthPartnerShard0ChainID, - EthCompatibleEpoch: big.NewInt(0), - CrossTxEpoch: big.NewInt(0), - CrossLinkEpoch: big.NewInt(2), - AggregatedRewardEpoch: big.NewInt(3), - StakingEpoch: big.NewInt(2), - PreStakingEpoch: big.NewInt(1), - QuickUnlockEpoch: big.NewInt(0), - FiveSecondsEpoch: big.NewInt(0), - TwoSecondsEpoch: big.NewInt(0), - SixtyPercentEpoch: big.NewInt(4), - RedelegationEpoch: big.NewInt(0), - NoEarlyUnlockEpoch: big.NewInt(0), - VRFEpoch: big.NewInt(0), - PrevVRFEpoch: big.NewInt(0), - MinDelegation100Epoch: big.NewInt(0), - MinCommissionRateEpoch: big.NewInt(0), - MinCommissionPromoPeriod: big.NewInt(10), - EPoSBound35Epoch: big.NewInt(0), - EIP155Epoch: big.NewInt(0), - S3Epoch: big.NewInt(0), - DataCopyFixEpoch: big.NewInt(0), - IstanbulEpoch: big.NewInt(0), - ReceiptLogEpoch: big.NewInt(0), - SHA3Epoch: big.NewInt(0), - HIP6And8Epoch: big.NewInt(0), - StakingPrecompileEpoch: big.NewInt(2), - ChainIdFixEpoch: big.NewInt(0), - SlotsLimitedEpoch: EpochTBD, // epoch to enable HIP-16 - CrossShardXferPrecompileEpoch: big.NewInt(1), - AllowlistEpoch: EpochTBD, - LeaderRotationExternalNonBeaconLeaders: EpochTBD, - LeaderRotationExternalBeaconLeaders: EpochTBD, - FeeCollectEpoch: big.NewInt(848), // 2023-04-28 04:33:33+00:00 - ValidatorCodeFixEpoch: big.NewInt(848), + ChainID: PartnerChainID, + EthCompatibleChainID: EthPartnerShard0ChainID, + EthCompatibleShard0ChainID: EthPartnerShard0ChainID, + EthCompatibleEpoch: big.NewInt(0), + CrossTxEpoch: big.NewInt(0), + CrossLinkEpoch: big.NewInt(2), + AggregatedRewardEpoch: big.NewInt(3), + StakingEpoch: big.NewInt(2), + PreStakingEpoch: big.NewInt(1), + QuickUnlockEpoch: big.NewInt(0), + FiveSecondsEpoch: big.NewInt(0), + TwoSecondsEpoch: big.NewInt(0), + SixtyPercentEpoch: EpochTBD, + RedelegationEpoch: big.NewInt(0), + NoEarlyUnlockEpoch: big.NewInt(0), + VRFEpoch: big.NewInt(0), + PrevVRFEpoch: big.NewInt(0), + MinDelegation100Epoch: big.NewInt(0), + MinCommissionRateEpoch: big.NewInt(0), + MinCommissionPromoPeriod: big.NewInt(10), + EPoSBound35Epoch: big.NewInt(0), + EIP155Epoch: big.NewInt(0), + S3Epoch: big.NewInt(0), + DataCopyFixEpoch: big.NewInt(0), + IstanbulEpoch: big.NewInt(0), + ReceiptLogEpoch: big.NewInt(0), + SHA3Epoch: big.NewInt(0), + HIP6And8Epoch: big.NewInt(0), + StakingPrecompileEpoch: big.NewInt(5), + ChainIdFixEpoch: big.NewInt(5), + SlotsLimitedEpoch: EpochTBD, // epoch to enable HIP-16 + CrossShardXferPrecompileEpoch: big.NewInt(5), + AllowlistEpoch: EpochTBD, + LeaderRotationInternalValidatorsEpoch: EpochTBD, + LeaderRotationExternalValidatorsEpoch: EpochTBD, + FeeCollectEpoch: big.NewInt(5), + ValidatorCodeFixEpoch: big.NewInt(5), + HIP30Epoch: big.NewInt(7), + BlockGas30MEpoch: big.NewInt(7), } // StressnetChainConfig contains the chain parameters for the Stress test network. // All features except for CrossLink are enabled at launch. StressnetChainConfig = &ChainConfig{ - ChainID: StressnetChainID, - EthCompatibleChainID: EthStressnetShard0ChainID, - EthCompatibleShard0ChainID: EthStressnetShard0ChainID, - EthCompatibleEpoch: big.NewInt(0), - CrossTxEpoch: big.NewInt(0), - CrossLinkEpoch: big.NewInt(2), - AggregatedRewardEpoch: big.NewInt(3), - StakingEpoch: big.NewInt(2), - PreStakingEpoch: big.NewInt(1), - QuickUnlockEpoch: big.NewInt(0), - FiveSecondsEpoch: big.NewInt(0), - TwoSecondsEpoch: big.NewInt(0), - SixtyPercentEpoch: big.NewInt(10), - RedelegationEpoch: big.NewInt(0), - NoEarlyUnlockEpoch: big.NewInt(0), - VRFEpoch: big.NewInt(0), - PrevVRFEpoch: big.NewInt(0), - MinDelegation100Epoch: big.NewInt(0), - MinCommissionRateEpoch: big.NewInt(0), - MinCommissionPromoPeriod: big.NewInt(10), - EPoSBound35Epoch: big.NewInt(0), - EIP155Epoch: big.NewInt(0), - S3Epoch: big.NewInt(0), - DataCopyFixEpoch: big.NewInt(0), - IstanbulEpoch: big.NewInt(0), - ReceiptLogEpoch: big.NewInt(0), - SHA3Epoch: big.NewInt(0), - HIP6And8Epoch: big.NewInt(0), - StakingPrecompileEpoch: big.NewInt(2), - ChainIdFixEpoch: big.NewInt(0), - SlotsLimitedEpoch: EpochTBD, // epoch to enable HIP-16 - CrossShardXferPrecompileEpoch: big.NewInt(1), - AllowlistEpoch: EpochTBD, - FeeCollectEpoch: EpochTBD, - LeaderRotationExternalNonBeaconLeaders: EpochTBD, - LeaderRotationExternalBeaconLeaders: EpochTBD, - ValidatorCodeFixEpoch: EpochTBD, + ChainID: StressnetChainID, + EthCompatibleChainID: EthStressnetShard0ChainID, + EthCompatibleShard0ChainID: EthStressnetShard0ChainID, + EthCompatibleEpoch: big.NewInt(0), + CrossTxEpoch: big.NewInt(0), + CrossLinkEpoch: big.NewInt(2), + AggregatedRewardEpoch: big.NewInt(3), + StakingEpoch: big.NewInt(2), + PreStakingEpoch: big.NewInt(1), + QuickUnlockEpoch: big.NewInt(0), + FiveSecondsEpoch: big.NewInt(0), + TwoSecondsEpoch: big.NewInt(0), + SixtyPercentEpoch: big.NewInt(10), + RedelegationEpoch: big.NewInt(0), + NoEarlyUnlockEpoch: big.NewInt(0), + VRFEpoch: big.NewInt(0), + PrevVRFEpoch: big.NewInt(0), + MinDelegation100Epoch: big.NewInt(0), + MinCommissionRateEpoch: big.NewInt(0), + MinCommissionPromoPeriod: big.NewInt(10), + EPoSBound35Epoch: big.NewInt(0), + EIP155Epoch: big.NewInt(0), + S3Epoch: big.NewInt(0), + DataCopyFixEpoch: big.NewInt(0), + IstanbulEpoch: big.NewInt(0), + ReceiptLogEpoch: big.NewInt(0), + SHA3Epoch: big.NewInt(0), + HIP6And8Epoch: big.NewInt(0), + StakingPrecompileEpoch: big.NewInt(2), + ChainIdFixEpoch: big.NewInt(0), + SlotsLimitedEpoch: EpochTBD, // epoch to enable HIP-16 + CrossShardXferPrecompileEpoch: big.NewInt(1), + AllowlistEpoch: EpochTBD, + FeeCollectEpoch: EpochTBD, + LeaderRotationInternalValidatorsEpoch: EpochTBD, + LeaderRotationExternalValidatorsEpoch: EpochTBD, + ValidatorCodeFixEpoch: EpochTBD, + HIP30Epoch: EpochTBD, + BlockGas30MEpoch: big.NewInt(0), } // LocalnetChainConfig contains the chain parameters to run for local development. LocalnetChainConfig = &ChainConfig{ - ChainID: TestnetChainID, - EthCompatibleChainID: EthTestnetShard0ChainID, - EthCompatibleShard0ChainID: EthTestnetShard0ChainID, - EthCompatibleEpoch: big.NewInt(0), - CrossTxEpoch: big.NewInt(0), - CrossLinkEpoch: big.NewInt(2), - AggregatedRewardEpoch: big.NewInt(3), - StakingEpoch: big.NewInt(2), - PreStakingEpoch: big.NewInt(0), - QuickUnlockEpoch: big.NewInt(0), - FiveSecondsEpoch: big.NewInt(0), - TwoSecondsEpoch: big.NewInt(0), - SixtyPercentEpoch: EpochTBD, // Never enable it for localnet as localnet has no external validator setup - RedelegationEpoch: big.NewInt(0), - NoEarlyUnlockEpoch: big.NewInt(0), - VRFEpoch: big.NewInt(0), - PrevVRFEpoch: big.NewInt(0), - MinDelegation100Epoch: big.NewInt(0), - MinCommissionRateEpoch: big.NewInt(0), - MinCommissionPromoPeriod: big.NewInt(10), - EPoSBound35Epoch: big.NewInt(0), - EIP155Epoch: big.NewInt(0), - S3Epoch: big.NewInt(0), - DataCopyFixEpoch: big.NewInt(0), - IstanbulEpoch: big.NewInt(0), - ReceiptLogEpoch: big.NewInt(0), - SHA3Epoch: big.NewInt(0), - HIP6And8Epoch: EpochTBD, // Never enable it for localnet as localnet has no external validator setup - StakingPrecompileEpoch: big.NewInt(2), - ChainIdFixEpoch: big.NewInt(0), - SlotsLimitedEpoch: EpochTBD, // epoch to enable HIP-16 - CrossShardXferPrecompileEpoch: big.NewInt(1), - AllowlistEpoch: EpochTBD, - LeaderRotationExternalNonBeaconLeaders: big.NewInt(5), - LeaderRotationExternalBeaconLeaders: big.NewInt(6), - FeeCollectEpoch: big.NewInt(2), - ValidatorCodeFixEpoch: big.NewInt(2), + ChainID: TestnetChainID, + EthCompatibleChainID: EthTestnetShard0ChainID, + EthCompatibleShard0ChainID: EthTestnetShard0ChainID, + EthCompatibleEpoch: big.NewInt(0), + CrossTxEpoch: big.NewInt(0), + CrossLinkEpoch: big.NewInt(2), + AggregatedRewardEpoch: big.NewInt(3), + StakingEpoch: big.NewInt(2), + PreStakingEpoch: big.NewInt(0), + QuickUnlockEpoch: big.NewInt(0), + FiveSecondsEpoch: big.NewInt(0), + TwoSecondsEpoch: big.NewInt(0), + SixtyPercentEpoch: EpochTBD, // Never enable it for localnet as localnet has no external validator setup + RedelegationEpoch: big.NewInt(0), + NoEarlyUnlockEpoch: big.NewInt(0), + VRFEpoch: big.NewInt(0), + PrevVRFEpoch: big.NewInt(0), + MinDelegation100Epoch: big.NewInt(0), + MinCommissionRateEpoch: big.NewInt(0), + MinCommissionPromoPeriod: big.NewInt(10), + EPoSBound35Epoch: big.NewInt(0), + EIP155Epoch: big.NewInt(0), + S3Epoch: big.NewInt(0), + DataCopyFixEpoch: big.NewInt(0), + IstanbulEpoch: big.NewInt(0), + ReceiptLogEpoch: big.NewInt(0), + SHA3Epoch: big.NewInt(0), + HIP6And8Epoch: EpochTBD, // Never enable it for localnet as localnet has no external validator setup + StakingPrecompileEpoch: big.NewInt(2), + ChainIdFixEpoch: big.NewInt(0), + SlotsLimitedEpoch: EpochTBD, // epoch to enable HIP-16 + CrossShardXferPrecompileEpoch: big.NewInt(1), + AllowlistEpoch: EpochTBD, + LeaderRotationInternalValidatorsEpoch: big.NewInt(5), + LeaderRotationExternalValidatorsEpoch: big.NewInt(6), + FeeCollectEpoch: big.NewInt(2), + ValidatorCodeFixEpoch: big.NewInt(2), + HIP30Epoch: EpochTBD, + BlockGas30MEpoch: big.NewInt(0), } // AllProtocolChanges ... @@ -323,6 +335,8 @@ var ( big.NewInt(1), // LeaderRotationExternalBeaconLeaders big.NewInt(0), // FeeCollectEpoch big.NewInt(0), // ValidatorCodeFixEpoch + big.NewInt(0), // BlockGas30M + big.NewInt(0), // HIP30Epoch } // TestChainConfig ... @@ -366,6 +380,8 @@ var ( big.NewInt(1), // LeaderRotationExternalBeaconLeaders big.NewInt(0), // FeeCollectEpoch big.NewInt(0), // ValidatorCodeFixEpoch + big.NewInt(0), // HIP30Epoch + big.NewInt(0), // BlockGas30M } // TestRules ... @@ -505,9 +521,9 @@ type ChainConfig struct { // AllowlistEpoch is the first epoch to support allowlist of HIP18 AllowlistEpoch *big.Int - LeaderRotationExternalNonBeaconLeaders *big.Int `json:"leader-rotation-external-non-beacon-leaders,omitempty"` + LeaderRotationInternalValidatorsEpoch *big.Int `json:"leader-rotation-internal-validators,omitempty"` - LeaderRotationExternalBeaconLeaders *big.Int `json:"leader-rotation-external-beacon-leaders,omitempty"` + LeaderRotationExternalValidatorsEpoch *big.Int `json:"leader-rotation-external-validators,omitempty"` // FeeCollectEpoch is the first epoch that enables txn fees to be collected into the community-managed account. // It should >= StakingEpoch. @@ -522,6 +538,15 @@ type ChainConfig struct { // Contracts can check the (presence of) validator code by calling the following: // extcodesize, extcodecopy and extcodehash. ValidatorCodeFixEpoch *big.Int `json:"validator-code-fix-epoch,omitempty"` + + // The epoch at which HIP30 goes into effect. + // 1. Number of shards decrease from 4 to 2 (mainnet and localnet) + // 2. Split emission into 75% for staking rewards, and 25% for recovery (all nets) + // 3. Change from 250 to 200 nodes for remaining shards (mainnet and localnet) + // 4. Change the minimum validator commission from 5 to 7% (all nets) + HIP30Epoch *big.Int `json:"hip30-epoch,omitempty"` + + BlockGas30MEpoch *big.Int `json:"block-gas-30m-epoch,omitempty"` } // String implements the fmt.Stringer interface. @@ -548,6 +573,10 @@ func (c *ChainConfig) mustValid() { panic(err) } } + // to ensure at least RewardFrequency blocks have passed + require(c.AggregatedRewardEpoch.Cmp(common.Big0) > 0, + "must satisfy: AggregatedRewardEpoch > 0", + ) // before staking epoch, fees were sent to coinbase require(c.FeeCollectEpoch.Cmp(c.StakingEpoch) >= 0, "must satisfy: FeeCollectEpoch >= StakingEpoch") @@ -567,6 +596,22 @@ func (c *ChainConfig) mustValid() { // we accept validator creation transactions starting at PreStakingEpoch require(c.ValidatorCodeFixEpoch.Cmp(c.PreStakingEpoch) >= 0, "must satisfy: ValidatorCodeFixEpoch >= PreStakingEpoch") + // staking epoch must pass for validator count reduction + require(c.HIP30Epoch.Cmp(c.StakingEpoch) > 0, + "must satisfy: HIP30Epoch > StakingEpoch") + // min commission increase 2.0 must happen on or after 1.0 + require(c.HIP30Epoch.Cmp(c.MinCommissionRateEpoch) >= 0, + "must satisfy: HIP30Epoch > MinCommissionRateEpoch") + // the HIP30 split distribution of rewards is only implemented + // for the post aggregated epoch + require(c.HIP30Epoch.Cmp(c.AggregatedRewardEpoch) >= 0, + "must satisfy: HIP30Epoch >= MinCommissionRateEpoch") + // the migration of shard 2 and 3 balances assumes S3 + require(c.HIP30Epoch.Cmp(c.S3Epoch) >= 0, + "must satisfy: HIP30Epoch >= S3Epoch") + // capabilities required to transfer balance across shards + require(c.HIP30Epoch.Cmp(c.CrossTxEpoch) > 0, + "must satisfy: HIP30Epoch > CrossTxEpoch") } // IsEIP155 returns whether epoch is either equal to the EIP155 fork epoch or greater. @@ -733,18 +778,16 @@ func (c *ChainConfig) IsAllowlistEpoch(epoch *big.Int) bool { return isForked(c.AllowlistEpoch, epoch) } -func (c *ChainConfig) IsLeaderRotation(epoch *big.Int) bool { - return isForked(c.LeaderRotationExternalNonBeaconLeaders, epoch) +func (c *ChainConfig) IsLeaderRotationInternalValidators(epoch *big.Int) bool { + return isForked(c.LeaderRotationInternalValidatorsEpoch, epoch) } -func (c *ChainConfig) IsLeaderRotationExternalValidatorsAllowed(epoch *big.Int, shardID uint32) bool { - if !c.IsLeaderRotation(epoch) { - return false - } - if shardID == 0 { - return isForked(c.LeaderRotationExternalBeaconLeaders, epoch) - } - return true +func (c *ChainConfig) IsBlockGas30M(epoch *big.Int) bool { + return isForked(c.BlockGas30MEpoch, epoch) +} + +func (c *ChainConfig) IsLeaderRotationExternalValidatorsAllowed(epoch *big.Int) bool { + return isForked(c.LeaderRotationExternalValidatorsEpoch, epoch) } // IsFeeCollectEpoch determines whether Txn Fees will be collected into the community-managed account. @@ -756,6 +799,16 @@ func (c *ChainConfig) IsValidatorCodeFix(epoch *big.Int) bool { return isForked(c.ValidatorCodeFixEpoch, epoch) } +func (c *ChainConfig) IsHIP30(epoch *big.Int) bool { + return isForked(c.HIP30Epoch, epoch) +} + +// During this epoch, shards 2 and 3 will start sending +// their balances over to shard 0 or 1. +func (c *ChainConfig) IsOneEpochBeforeHIP30(epoch *big.Int) bool { + return new(big.Int).Sub(c.HIP30Epoch, epoch).Cmp(common.Big1) == 0 +} + // UpdateEthChainIDByShard update the ethChainID based on shard ID. func UpdateEthChainIDByShard(shardID uint32) { once.Do(func() { diff --git a/internal/params/config_test.go b/internal/params/config_test.go new file mode 100644 index 0000000000..c650437a29 --- /dev/null +++ b/internal/params/config_test.go @@ -0,0 +1,17 @@ +package params + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestIsOneEpochBeforeHIP30(t *testing.T) { + c := ChainConfig{ + HIP30Epoch: big.NewInt(3), + } + + require.True(t, c.IsOneEpochBeforeHIP30(big.NewInt(2))) + require.False(t, c.IsOneEpochBeforeHIP30(big.NewInt(3))) +} diff --git a/internal/params/protocol_params.go b/internal/params/protocol_params.go index 3160118411..971f1e5ae2 100644 --- a/internal/params/protocol_params.go +++ b/internal/params/protocol_params.go @@ -24,6 +24,8 @@ const ( CallNewAccountGas uint64 = 25000 // Paid for CALL when the destination address didn't exist prior. // TxGas ... TxGas uint64 = 21000 // Per transaction not creating a contract. NOTE: Not payable on data of calls between transactions. + // TxGasXShard + TxGasXShard uint64 = 23000 // Approximate cost for transferring native tokens across shards. Used in balance migration // TxGasContractCreation ... TxGasContractCreation uint64 = 53000 // Per transaction that creates a contract. NOTE: Not payable on data of calls between transactions. // TxGasValidatorCreation ... diff --git a/internal/registry/registry.go b/internal/registry/registry.go index 7032609103..50398bc5ca 100644 --- a/internal/registry/registry.go +++ b/internal/registry/registry.go @@ -3,7 +3,9 @@ package registry import ( "sync" + "github.com/harmony-one/harmony/consensus/engine" "github.com/harmony-one/harmony/core" + "github.com/harmony-one/harmony/internal/shardchain" "github.com/harmony-one/harmony/webhooks" ) @@ -16,6 +18,8 @@ type Registry struct { txPool *core.TxPool cxPool *core.CxPool isBackup bool + engine engine.Engine + collection *shardchain.CollectionImpl } // New creates a new registry. @@ -122,3 +126,37 @@ func (r *Registry) GetCxPool() *core.CxPool { return r.cxPool } + +// SetEngine sets the engine to registry. +func (r *Registry) SetEngine(engine engine.Engine) *Registry { + r.mu.Lock() + defer r.mu.Unlock() + + r.engine = engine + return r +} + +// GetEngine gets the engine from registry. +func (r *Registry) GetEngine() engine.Engine { + r.mu.Lock() + defer r.mu.Unlock() + + return r.engine +} + +// SetShardChainCollection sets the shard chain collection to registry. +func (r *Registry) SetShardChainCollection(collection *shardchain.CollectionImpl) *Registry { + r.mu.Lock() + defer r.mu.Unlock() + + r.collection = collection + return r +} + +// GetShardChainCollection gets the shard chain collection from registry. +func (r *Registry) GetShardChainCollection() *shardchain.CollectionImpl { + r.mu.Lock() + defer r.mu.Unlock() + + return r.collection +} diff --git a/internal/shardchain/shardchains.go b/internal/shardchain/shardchains.go index 66cfad220a..5da1b9186f 100644 --- a/internal/shardchain/shardchains.go +++ b/internal/shardchain/shardchains.go @@ -100,8 +100,12 @@ func (sc *CollectionImpl) ShardChain(shardID uint32, options ...core.Options) (c } } var cacheConfig *core.CacheConfig + // archival node if sc.disableCache[shardID] { - cacheConfig = &core.CacheConfig{Disabled: true} + cacheConfig = &core.CacheConfig{ + Disabled: true, + Preimages: true, + } utils.Logger().Info(). Uint32("shardID", shardID). Msg("disable cache, running in archival mode") @@ -110,6 +114,7 @@ func (sc *CollectionImpl) ShardChain(shardID uint32, options ...core.Options) (c TrieNodeLimit: 256, TrieTimeLimit: 2 * time.Minute, TriesInMemory: 128, + Preimages: true, } if sc.harmonyconfig != nil { cacheConfig.TriesInMemory = uint64(sc.harmonyconfig.General.TriesInMemory) diff --git a/internal/utils/passphrase.go b/internal/utils/passphrase.go index e46a9e7c5a..35b7606a7c 100644 --- a/internal/utils/passphrase.go +++ b/internal/utils/passphrase.go @@ -3,7 +3,6 @@ package utils import ( "fmt" "io" - "io/ioutil" "os" "strconv" "strings" @@ -28,7 +27,7 @@ func AskForPassphrase(prompt string) string { // readAllAsString reads the entire file contents as a string. func readAllAsString(r io.Reader) (data string, err error) { - bytes, err := ioutil.ReadAll(r) + bytes, err := io.ReadAll(r) return string(bytes), err } diff --git a/internal/utils/testing/tempfile.go b/internal/utils/testing/tempfile.go index b20e61fd4a..4fbf99497a 100644 --- a/internal/utils/testing/tempfile.go +++ b/internal/utils/testing/tempfile.go @@ -2,7 +2,6 @@ package testutils import ( "io" - "io/ioutil" "os" "strings" "testing" @@ -13,7 +12,7 @@ import ( // NewTempFile creates a new, empty temp file for testing. Errors are fatal. func NewTempFile(t *testing.T) *os.File { pattern := strings.ReplaceAll(t.Name(), string(os.PathSeparator), "_") - f, err := ioutil.TempFile("", pattern) + f, err := os.CreateTemp("", pattern) if err != nil { t.Fatal(errors.Wrap(err, "cannot create temp file")) } diff --git a/node/node.go b/node/node.go index 06aecb94d9..e4d567066b 100644 --- a/node/node.go +++ b/node/node.go @@ -4,7 +4,6 @@ import ( "bytes" "context" "fmt" - "io/ioutil" "math/big" "os" "runtime/pprof" @@ -12,7 +11,6 @@ import ( "sync" "time" - "github.com/harmony-one/harmony/consensus/engine" "github.com/harmony-one/harmony/internal/registry" "github.com/harmony-one/harmony/internal/shardchain/tikv_manage" "github.com/harmony-one/harmony/internal/tikv" @@ -50,7 +48,6 @@ import ( common2 "github.com/harmony-one/harmony/internal/common" nodeconfig "github.com/harmony-one/harmony/internal/configs/node" "github.com/harmony-one/harmony/internal/params" - "github.com/harmony-one/harmony/internal/shardchain" "github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/node/worker" "github.com/harmony-one/harmony/p2p" @@ -89,7 +86,7 @@ type ISync interface { AddLastMileBlock(block *types.Block) GetActivePeerNumber() int CreateSyncConfig(peers []p2p.Peer, shardID uint32, selfPeerID libp2p_peer.ID, waitForEachPeerToConnect bool) error - SyncLoop(bc core.BlockChain, worker *worker.Worker, isBeacon bool, consensus *consensus.Consensus, loopMinTime time.Duration) + SyncLoop(bc core.BlockChain, isBeacon bool, consensus *consensus.Consensus, loopMinTime time.Duration) IsSynchronized() bool IsSameBlockchainHeight(bc core.BlockChain) (uint64, bool) AddNewBlock(peerHash []byte, block *types.Block) @@ -105,8 +102,7 @@ type Node struct { pendingCXReceipts map[string]*types.CXReceiptsProof // All the receipts received but not yet processed for Consensus pendingCXMutex sync.Mutex crosslinks *crosslinks.Crosslinks // Memory storage for crosslink processing. - // Shard databases - shardChains shardchain.Collection + SelfPeer p2p.Peer stateMutex sync.Mutex // mutex for change node state TxPool *core.TxPool @@ -194,7 +190,10 @@ func (node *Node) Beaconchain() core.BlockChain { } func (node *Node) chain(shardID uint32, options core.Options) core.BlockChain { - bc, err := node.shardChains.ShardChain(shardID, options) + if node.registry.GetShardChainCollection() == nil { + panic("shard chain collection is nil") + } + bc, err := node.registry.GetShardChainCollection().ShardChain(shardID, options) if err != nil { utils.Logger().Error().Err(err).Msg("cannot get beaconchain") } @@ -255,21 +254,38 @@ func (node *Node) tryBroadcastStaking(stakingTx *staking.StakingTransaction) { // Add new transactions to the pending transaction list. func addPendingTransactions(registry *registry.Registry, newTxs types.Transactions) []error { var ( - errs []error - bc = registry.GetBlockchain() - txPool = registry.GetTxPool() - poolTxs = types.PoolTransactions{} - acceptCx = bc.Config().AcceptsCrossTx(bc.CurrentHeader().Epoch()) + errs []error + bc = registry.GetBlockchain() + txPool = registry.GetTxPool() + poolTxs = types.PoolTransactions{} + epoch = bc.CurrentHeader().Epoch() + acceptCx = bc.Config().AcceptsCrossTx(epoch) + isBeforeHIP30 = bc.Config().IsOneEpochBeforeHIP30(epoch) + nxtShards = shard.Schedule.InstanceForEpoch(new(big.Int).Add(epoch, common.Big1)).NumShards() ) for _, tx := range newTxs { - if tx.ShardID() != tx.ToShardID() && !acceptCx { - errs = append(errs, errors.WithMessage(errInvalidEpoch, "cross-shard tx not accepted yet")) - continue + if tx.ShardID() != tx.ToShardID() { + if !acceptCx { + errs = append(errs, errors.WithMessage(errInvalidEpoch, "cross-shard tx not accepted yet")) + continue + } + if isBeforeHIP30 { + if tx.ToShardID() >= nxtShards { + errs = append(errs, errors.New("shards 2 and 3 are shutting down in the next epoch")) + continue + } + } } if tx.IsEthCompatible() && !bc.Config().IsEthCompatible(bc.CurrentBlock().Epoch()) { errs = append(errs, errors.WithMessage(errInvalidEpoch, "ethereum tx not accepted yet")) continue } + if isBeforeHIP30 { + if bc.ShardID() >= nxtShards { + errs = append(errs, errors.New("shards 2 and 3 are shutting down in the next epoch")) + continue + } + } poolTxs = append(poolTxs, tx) } errs = append(errs, registry.GetTxPool().AddRemotes(poolTxs)...) @@ -375,7 +391,7 @@ func (node *Node) AddPendingReceipts(receipts *types.CXReceiptsProof) { // Sanity checks - if err := node.Blockchain().Validator().ValidateCXReceiptsProof(receipts); err != nil { + if err := core.NewBlockValidator(node.Blockchain()).ValidateCXReceiptsProof(receipts); err != nil { if !strings.Contains(err.Error(), rawdb.MsgNoShardStateFromDB) { utils.Logger().Error().Err(err).Msg("[AddPendingReceipts] Invalid CXReceiptsProof") return @@ -480,7 +496,8 @@ func (node *Node) validateNodeMessage(ctx context.Context, payload []byte) ( if err := rlp.DecodeBytes(blocksPayload, &blocks); err != nil { return nil, 0, errors.Wrap(err, "block decode error") } - curBeaconHeight := node.Beaconchain().CurrentBlock().NumberU64() + curBeaconBlock := node.EpochChain().CurrentBlock() + curBeaconHeight := curBeaconBlock.NumberU64() for _, block := range blocks { // Ban blocks number that is smaller than tolerance if block.NumberU64()+beaconBlockHeightTolerance <= curBeaconHeight { @@ -490,7 +507,7 @@ func (node *Node) validateNodeMessage(ctx context.Context, payload []byte) ( } else if block.NumberU64()-beaconBlockHeightTolerance > curBeaconHeight { utils.Logger().Debug().Uint64("receivedNum", block.NumberU64()). Uint64("currentNum", curBeaconHeight).Msg("beacon block sync message rejected") - return nil, 0, errors.New("beacon block height too much higher than current height beyond tolerance") + return nil, 0, errors.Errorf("beacon block height too much higher than current height beyond tolerance, block %d, current %d, epoch %d , current %d", block.NumberU64(), curBeaconHeight, block.Epoch().Uint64(), curBeaconBlock.Epoch().Uint64()) } else if block.NumberU64() <= curBeaconHeight { utils.Logger().Debug().Uint64("receivedNum", block.NumberU64()). Uint64("currentNum", curBeaconHeight).Msg("beacon block sync message ignored") @@ -1009,12 +1026,9 @@ func (node *Node) GetSyncID() [SyncIDLength]byte { func New( host p2p.Host, consensusObj *consensus.Consensus, - engine engine.Engine, - collection *shardchain.CollectionImpl, blacklist map[common.Address]struct{}, allowedTxs map[common.Address]core.AllowedTxData, localAccounts []common.Address, - isArchival map[uint32]bool, harmonyconfig *harmonyconfig.HarmonyConfig, registry *registry.Registry, ) *Node { @@ -1041,7 +1055,6 @@ func New( networkType := node.NodeConfig.GetNetworkType() chainConfig := networkType.ChainConfig() node.chainConfig = chainConfig - node.shardChains = collection node.IsSynchronized = abool.NewBool(false) if host != nil { @@ -1064,9 +1077,9 @@ func New( if b2 { shardID := node.NodeConfig.ShardID // HACK get the real error reason - _, err = node.shardChains.ShardChain(shardID) + _, err = node.registry.GetShardChainCollection().ShardChain(shardID) } else { - _, err = node.shardChains.ShardChain(shard.BeaconChainShardID) + _, err = node.registry.GetShardChainCollection().ShardChain(shard.BeaconChainShardID) } fmt.Fprintf(os.Stderr, "Cannot initialize node: %v\n", err) os.Exit(-1) @@ -1108,7 +1121,7 @@ func New( node.TxPool = core.NewTxPool(txPoolConfig, node.Blockchain().Config(), blockchain, node.TransactionErrorSink) node.registry.SetTxPool(node.TxPool) node.CxPool = node.registry.GetCxPool() - node.Worker = worker.New(node.Blockchain().Config(), blockchain, beaconChain, engine) + node.Worker = worker.New(blockchain, beaconChain) node.deciderCache, _ = lru.New(16) node.committeeCache, _ = lru.New(16) @@ -1416,7 +1429,7 @@ func (node *Node) syncFromTiKVWriter() { if err != nil { panic(err) } - err = ioutil.WriteFile(fmt.Sprintf("/local/%s", time.Now().Format("hmy_0102150405.error.log")), buf.Bytes(), 0644) + err = os.WriteFile(fmt.Sprintf("/local/%s", time.Now().Format("hmy_0102150405.error.log")), buf.Bytes(), 0644) if err != nil { panic(err) } diff --git a/node/node_handler_test.go b/node/node_handler_test.go index 307e21b11a..a5085652b0 100644 --- a/node/node_handler_test.go +++ b/node/node_handler_test.go @@ -45,13 +45,16 @@ func TestAddNewBlock(t *testing.T) { if err != nil { t.Fatal("cannot get blockchain") } - reg := registry.New().SetBlockchain(blockchain) + reg := registry.New(). + SetBlockchain(blockchain). + SetEngine(engine). + SetShardChainCollection(collection) consensus, err := consensus.New(host, shard.BeaconChainShardID, multibls.GetPrivateKeys(blsKey), reg, decider, 3, false) if err != nil { t.Fatalf("Cannot craeate consensus: %v", err) } nodeconfig.SetNetworkType(nodeconfig.Testnet) - node := New(host, consensus, engine, collection, nil, nil, nil, nil, nil, reg) + node := New(host, consensus, nil, nil, nil, nil, reg) txs := make(map[common.Address]types.Transactions) stks := staking.StakingTransactions{} @@ -100,7 +103,11 @@ func TestVerifyNewBlock(t *testing.T) { if err != nil { t.Fatal("cannot get blockchain") } - reg := registry.New().SetBlockchain(blockchain) + reg := registry.New(). + SetBlockchain(blockchain). + SetEngine(engine). + SetShardChainCollection(collection) + consensusObj, err := consensus.New( host, shard.BeaconChainShardID, multibls.GetPrivateKeys(blsKey), reg, decider, 3, false, ) @@ -110,7 +117,7 @@ func TestVerifyNewBlock(t *testing.T) { archiveMode := make(map[uint32]bool) archiveMode[0] = true archiveMode[1] = false - node := New(host, consensusObj, engine, collection, nil, nil, nil, archiveMode, nil, reg) + node := New(host, consensusObj, nil, nil, nil, nil, reg) txs := make(map[common.Address]types.Transactions) stks := staking.StakingTransactions{} @@ -156,7 +163,10 @@ func TestVerifyVRF(t *testing.T) { decider := quorum.NewDecider( quorum.SuperMajorityVote, shard.BeaconChainShardID, ) - reg := registry.New().SetBlockchain(blockchain) + reg := registry.New(). + SetBlockchain(blockchain). + SetEngine(engine). + SetShardChainCollection(collection) consensus, err := consensus.New( host, shard.BeaconChainShardID, multibls.GetPrivateKeys(blsKey), reg, decider, 3, false, ) @@ -166,7 +176,7 @@ func TestVerifyVRF(t *testing.T) { archiveMode := make(map[uint32]bool) archiveMode[0] = true archiveMode[1] = false - node := New(host, consensus, engine, collection, nil, nil, nil, archiveMode, nil, reg) + node := New(host, consensus, nil, nil, nil, nil, reg) txs := make(map[common.Address]types.Transactions) stks := staking.StakingTransactions{} diff --git a/node/node_newblock.go b/node/node_newblock.go index 008182fbcc..fdca8b741b 100644 --- a/node/node_newblock.go +++ b/node/node_newblock.go @@ -1,13 +1,14 @@ package node import ( - "errors" "sort" "strings" "time" "github.com/harmony-one/harmony/consensus" + "github.com/harmony-one/harmony/core" "github.com/harmony-one/harmony/crypto/bls" + "github.com/pkg/errors" staking "github.com/harmony-one/harmony/staking/types" @@ -92,7 +93,7 @@ func (node *Node) WaitForConsensusReadyV2(cs *consensus.Consensus, stopChan chan Int("numTxs", newBlock.Transactions().Len()). Int("numStakingTxs", newBlock.StakingTransactions().Len()). Int("crossShardReceipts", newBlock.IncomingReceipts().Len()). - Msg("=========Successfully Proposed New Block==========") + Msgf("=========Successfully Proposed New Block, shard: %d epoch: %d number: %d ==========", newBlock.ShardID(), newBlock.Epoch().Uint64(), newBlock.NumberU64()) // Send the new block to Consensus so it can be confirmed. cs.BlockChannel(newBlock) @@ -115,16 +116,18 @@ func (node *Node) ProposeNewBlock(commitSigs chan []byte) (*types.Block, error) utils.AnalysisStart("ProposeNewBlock", nowEpoch, blockNow) defer utils.AnalysisEnd("ProposeNewBlock", nowEpoch, blockNow) - node.Worker.UpdateCurrent() - - header := node.Worker.GetCurrentHeader() // Update worker's current header and // state data in preparation to propose/process new transactions - leaderKey := node.Consensus.GetLeaderPubKey() + env, err := node.Worker.UpdateCurrent() + if err != nil { + return nil, errors.Wrap(err, "failed to update worker") + } + var ( + header = env.CurrentHeader() + leaderKey = node.Consensus.GetLeaderPubKey() coinbase = node.GetAddressForBLSKey(leaderKey.Object, header.Epoch()) beneficiary = coinbase - err error ) // After staking, all coinbase will be the address of bls pub key @@ -133,8 +136,7 @@ func (node *Node) ProposeNewBlock(commitSigs chan []byte) (*types.Block, error) coinbase.SetBytes(blsPubKeyBytes[:]) } - emptyAddr := common.Address{} - if coinbase == emptyAddr { + if coinbase == (common.Address{}) { return nil, errors.New("[ProposeNewBlock] Failed setting coinbase") } @@ -157,7 +159,8 @@ func (node *Node) ProposeNewBlock(commitSigs chan []byte) (*types.Block, error) } } - if !shard.Schedule.IsLastBlock(header.Number().Uint64()) { + // Execute all the time except for last block of epoch for shard 0 + if !shard.Schedule.IsLastBlock(header.Number().Uint64()) || node.Consensus.ShardID != 0 { // Prepare normal and staking transactions retrieved from transaction pool utils.AnalysisStart("proposeNewBlockChooseFromTxnPool") @@ -200,7 +203,13 @@ func (node *Node) ProposeNewBlock(commitSigs chan []byte) (*types.Block, error) utils.AnalysisEnd("proposeNewBlockChooseFromTxnPool") } - // Prepare cross shard transaction receipts + // Prepare incoming cross shard transaction receipts + // These are accepted even during the epoch before hip-30 + // because the destination shard only receives them after + // balance is deducted on source shard. to prevent this from + // being a significant problem, the source shards will stop + // accepting txs destined to the shards which are shutting down + // one epoch prior the shut down receiptsList := node.proposeReceiptsProof() if len(receiptsList) != 0 { if err := node.Worker.CommitReceipts(receiptsList); err != nil { @@ -249,7 +258,7 @@ func (node *Node) ProposeNewBlock(commitSigs chan []byte) (*types.Block, error) len(crossLinksToPropose), len(allPending), ) } else { - utils.Logger().Error().Err(err).Msgf( + utils.Logger().Warn().Err(err).Msgf( "[ProposeNewBlock] Unable to Read PendingCrossLinks, number of crosslinks: %d", len(allPending), ) @@ -265,7 +274,7 @@ func (node *Node) ProposeNewBlock(commitSigs chan []byte) (*types.Block, error) } } - node.Worker.ApplyTestnetShardReduction() + node.Worker.ApplyShardReduction() // Prepare shard state var shardState *shard.State if shardState, err = node.Blockchain().SuperCommitteeForNextEpoch( @@ -285,8 +294,10 @@ func (node *Node) ProposeNewBlock(commitSigs chan []byte) (*types.Block, error) utils.Logger().Error().Err(err).Msg("[ProposeNewBlock] Failed finalizing the new block") return nil, err } + utils.Logger().Info().Msg("[ProposeNewBlock] verifying the new block header") - err = node.Blockchain().Validator().ValidateHeader(finalizedBlock, true) + // err = node.Blockchain().Validator().ValidateHeader(finalizedBlock, true) + err = core.NewBlockValidator(node.Blockchain()).ValidateHeader(finalizedBlock, true) if err != nil { utils.Logger().Error().Err(err).Msg("[ProposeNewBlock] Failed verifying the new block header") @@ -353,7 +364,7 @@ Loop: } } - if err := node.Blockchain().Validator().ValidateCXReceiptsProof(cxp); err != nil { + if err := core.NewBlockValidator(node.Blockchain()).ValidateCXReceiptsProof(cxp); err != nil { if strings.Contains(err.Error(), rawdb.MsgNoShardStateFromDB) { pendingReceiptsList = append(pendingReceiptsList, cxp) } else { diff --git a/node/node_newblock_test.go b/node/node_newblock_test.go index 963af2f55b..86dd1e6c7e 100644 --- a/node/node_newblock_test.go +++ b/node/node_newblock_test.go @@ -46,7 +46,11 @@ func TestFinalizeNewBlockAsync(t *testing.T) { decider := quorum.NewDecider( quorum.SuperMajorityVote, shard.BeaconChainShardID, ) - reg := registry.New().SetBlockchain(blockchain).SetBeaconchain(blockchain) + reg := registry.New(). + SetBlockchain(blockchain). + SetBeaconchain(blockchain). + SetEngine(engine). + SetShardChainCollection(collection) consensusObj, err := consensus.New( host, shard.BeaconChainShardID, multibls.GetPrivateKeys(blsKey), reg, decider, 3, false, ) @@ -54,7 +58,7 @@ func TestFinalizeNewBlockAsync(t *testing.T) { t.Fatalf("Cannot craeate consensus: %v", err) } - node := New(host, consensusObj, engine, collection, nil, nil, nil, nil, nil, registry.New().SetBlockchain(blockchain)) + node := New(host, consensusObj, nil, nil, nil, nil, reg) node.Worker.UpdateCurrent() diff --git a/node/node_syncing.go b/node/node_syncing.go index 68c3338362..fa90ec5c78 100644 --- a/node/node_syncing.go +++ b/node/node_syncing.go @@ -29,7 +29,6 @@ import ( "github.com/harmony-one/harmony/core/types" nodeconfig "github.com/harmony-one/harmony/internal/configs/node" "github.com/harmony-one/harmony/internal/utils" - "github.com/harmony-one/harmony/node/worker" "github.com/harmony-one/harmony/p2p" "github.com/harmony-one/harmony/shard" ) @@ -269,7 +268,7 @@ func (node *Node) doBeaconSyncing() { } // DoSyncing keep the node in sync with other peers, willJoinConsensus means the node will try to join consensus after catch up -func (node *Node) DoSyncing(bc core.BlockChain, worker *worker.Worker, willJoinConsensus bool) { +func (node *Node) DoSyncing(bc core.BlockChain, willJoinConsensus bool) { if node.NodeConfig.IsOffline { return } @@ -280,15 +279,15 @@ func (node *Node) DoSyncing(bc core.BlockChain, worker *worker.Worker, willJoinC for { select { case <-ticker.C: - node.doSync(bc, worker, willJoinConsensus) + node.doSync(bc, willJoinConsensus) case <-node.Consensus.BlockNumLowChan: - node.doSync(bc, worker, willJoinConsensus) + node.doSync(bc, willJoinConsensus) } } } // doSync keep the node in sync with other peers, willJoinConsensus means the node will try to join consensus after catch up -func (node *Node) doSync(bc core.BlockChain, worker *worker.Worker, willJoinConsensus bool) { +func (node *Node) doSync(bc core.BlockChain, willJoinConsensus bool) { syncInstance := node.SyncInstance() if syncInstance.GetActivePeerNumber() < legacysync.NumPeersLowBound { @@ -317,7 +316,7 @@ func (node *Node) doSync(bc core.BlockChain, worker *worker.Worker, willJoinCons node.Consensus.BlocksNotSynchronized() } isBeacon := bc.ShardID() == shard.BeaconChainShardID - syncInstance.SyncLoop(bc, worker, isBeacon, node.Consensus, legacysync.LoopMinTime) + syncInstance.SyncLoop(bc, isBeacon, node.Consensus, legacysync.LoopMinTime) if willJoinConsensus { node.IsSynchronized.Set() node.Consensus.BlocksSynchronized() @@ -388,7 +387,7 @@ func (node *Node) supportSyncing() { utils.Logger().Debug().Msg("[SYNC] initialized state for staged sync") } - go node.DoSyncing(node.Blockchain(), node.Worker, joinConsensus) + go node.DoSyncing(node.Blockchain(), joinConsensus) } // InitSyncingServer starts downloader server. diff --git a/node/node_test.go b/node/node_test.go index 49ba5d164d..d96a266241 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -46,7 +46,11 @@ func TestNewNode(t *testing.T) { if err != nil { t.Fatal("cannot get blockchain") } - reg := registry.New().SetBlockchain(blockchain) + reg := registry.New(). + SetBlockchain(blockchain). + SetEngine(engine). + SetShardChainCollection(collection) + consensus, err := consensus.New( host, shard.BeaconChainShardID, multibls.GetPrivateKeys(blsKey), reg, decider, 3, false, ) @@ -54,7 +58,7 @@ func TestNewNode(t *testing.T) { t.Fatalf("Cannot craeate consensus: %v", err) } - node := New(host, consensus, engine, collection, nil, nil, nil, nil, nil, reg) + node := New(host, consensus, nil, nil, nil, nil, reg) if node.Consensus == nil { t.Error("Consensus is not initialized for the node") } diff --git a/node/worker/types.go b/node/worker/types.go new file mode 100644 index 0000000000..87b7195dd3 --- /dev/null +++ b/node/worker/types.go @@ -0,0 +1,7 @@ +package worker + +import "github.com/harmony-one/harmony/block" + +type Environment interface { + CurrentHeader() *block.Header +} diff --git a/node/worker/worker.go b/node/worker/worker.go index 5a4234229a..db5d855b0e 100644 --- a/node/worker/worker.go +++ b/node/worker/worker.go @@ -7,10 +7,8 @@ import ( "sort" "time" - "github.com/harmony-one/harmony/consensus/reward" - "github.com/harmony-one/harmony/consensus" - + "github.com/harmony-one/harmony/consensus/reward" "github.com/harmony-one/harmony/crypto/bls" "github.com/harmony-one/harmony/crypto/hash" @@ -19,7 +17,6 @@ import ( "github.com/ethereum/go-ethereum/rlp" "github.com/harmony-one/harmony/block" blockfactory "github.com/harmony-one/harmony/block/factory" - consensus_engine "github.com/harmony-one/harmony/consensus/engine" "github.com/harmony-one/harmony/core" "github.com/harmony-one/harmony/core/state" "github.com/harmony-one/harmony/core/types" @@ -51,6 +48,10 @@ type environment struct { stakeMsgs []staking.StakeMsg } +func (env *environment) CurrentHeader() *block.Header { + return env.header +} + // Worker is the main object which takes care of submitting new work to consensus engine // and gathering the sealing result. type Worker struct { @@ -59,23 +60,50 @@ type Worker struct { chain core.BlockChain beacon core.BlockChain current *environment // An environment for current running cycle. - engine consensus_engine.Engine gasFloor uint64 gasCeil uint64 } +// New create a new worker object. +func New( + chain core.BlockChain, beacon core.BlockChain, +) *Worker { + worker := newWorker(chain.Config(), chain, beacon) + + parent := chain.CurrentBlock().Header() + num := parent.Number() + timestamp := time.Now().Unix() + + epoch := GetNewEpoch(chain) + header := blockfactory.NewFactory(chain.Config()).NewHeader(epoch).With(). + ParentHash(parent.Hash()). + Number(num.Add(num, common.Big1)). + GasLimit(worker.GasFloor(epoch)). //core.CalcGasLimit(parent, worker.gasFloor, worker.gasCeil)). + Time(big.NewInt(timestamp)). + ShardID(chain.ShardID()). + Header() + worker.makeCurrent(parent, header) + + return worker +} + +func newWorker(config *params.ChainConfig, chain, beacon core.BlockChain) *Worker { + return &Worker{ + config: config, + factory: blockfactory.NewFactory(config), + chain: chain, + beacon: beacon, + gasFloor: 80000000, + gasCeil: 120000000, + } +} + // CommitSortedTransactions commits transactions for new block. func (w *Worker) CommitSortedTransactions( txs *types.TransactionsByPriceAndNonce, coinbase common.Address, ) { for { - if w.current.gasPool.Gas() < 50000000 { - // Temporary solution to reduce the fullness of the block. Break here when the available gas left hit 50M. - // Effectively making the gas limit 30M (since 80M is the default gas limit) - utils.Logger().Info().Uint64("have", w.current.gasPool.Gas()).Uint64("want", params.TxGas).Msg("[Temp Gas Limit] Not enough gas for further transactions") - break - } // If we don't have enough gas for any further transactions then we're done if w.current.gasPool.Gas() < params.TxGas { utils.Logger().Info().Uint64("have", w.current.gasPool.Gas()).Uint64("want", params.TxGas).Msg("Not enough gas for further transactions") @@ -96,7 +124,7 @@ func (w *Worker) CommitSortedTransactions( from, _ := types.Sender(signer, tx) // Check whether the tx is replay protected. If we're not in the EIP155 hf // phase, start ignoring the sender until we do. - if tx.Protected() && !w.config.IsEIP155(w.current.header.Epoch()) { + if tx.Protected() && !w.chain.Config().IsEIP155(w.current.header.Epoch()) { utils.Logger().Info().Str("hash", tx.Hash().Hex()).Str("eip155Epoch", w.config.EIP155Epoch.String()).Msg("Ignoring reply protected transaction") txs.Pop() continue @@ -150,6 +178,38 @@ func (w *Worker) CommitTransactions( w.current.gasPool = new(core.GasPool).AddGas(w.current.header.GasLimit()) } + // if this is epoch for balance migration, no txs (or stxs) + // will be included in the block + // it is technically feasible for some to end up in the pool + // say, from the last epoch, but those will not be executed + // and no balance will be lost + // any cross-shard transfers destined to a shard being shut down + // will execute (since they are already spent on the source shard) + // but the balance will immediately be returned to shard 1 + cx, err := core.MayBalanceMigration( + w.current.gasPool, + w.GetCurrentHeader(), + w.current.state, + w.chain, + ) + if err != nil { + if errors.Is(err, core.ErrNoMigrationPossible) { + // means we do not accept transactions from the network + return nil + } + if !errors.Is(err, core.ErrNoMigrationRequired) { + + // this shard not migrating => ErrNoMigrationRequired + // any other error means exit this block + return err + } + } else { + if cx != nil { + w.current.outcxs = append(w.current.outcxs, cx) + return nil + } + } + // HARMONY TXNS normalTxns := types.NewTransactionsByPriceAndNonce(w.current.signer, w.current.ethSigner, pendingNormal) @@ -202,7 +262,7 @@ func (w *Worker) commitStakingTransaction( snap := w.current.state.Snapshot() gasUsed := w.current.header.GasUsed() receipt, _, err := core.ApplyStakingTransaction( - w.config, w.chain, &coinbase, w.current.gasPool, + w.chain, &coinbase, w.current.gasPool, w.current.state, w.current.header, tx, &gasUsed, vm.Config{}, ) w.current.header.SetGasUsed(gasUsed) @@ -224,9 +284,9 @@ func (w *Worker) commitStakingTransaction( return nil } -// ApplyTestnetShardReduction only used to reduce shards of Testnet -func (w *Worker) ApplyTestnetShardReduction() { - core.MayTestnetShardReduction(w.chain, w.current.state, w.current.header) +// ApplyShardReduction only used to reduce shards of Testnet +func (w *Worker) ApplyShardReduction() { + core.MayShardReduction(w.chain, w.current.state, w.current.header) } var ( @@ -239,7 +299,6 @@ func (w *Worker) commitTransaction( snap := w.current.state.Snapshot() gasUsed := w.current.header.GasUsed() receipt, cx, stakeMsgs, _, err := core.ApplyTransaction( - w.config, w.chain, &coinbase, w.current.gasPool, @@ -299,16 +358,16 @@ func (w *Worker) CommitReceipts(receiptsList []*types.CXReceiptsProof) error { } // UpdateCurrent updates the current environment with the current state and header. -func (w *Worker) UpdateCurrent() error { +func (w *Worker) UpdateCurrent() (Environment, error) { parent := w.chain.CurrentHeader() num := parent.Number() timestamp := time.Now().Unix() - epoch := w.GetNewEpoch() + epoch := GetNewEpoch(w.chain) header := w.factory.NewHeader(epoch).With(). ParentHash(parent.Hash()). Number(num.Add(num, common.Big1)). - GasLimit(core.CalcGasLimit(parent, w.gasFloor, w.gasCeil)). + GasLimit(core.CalcGasLimit(parent, w.GasFloor(epoch), w.GasCeil())). Time(big.NewInt(timestamp)). ShardID(w.chain.ShardID()). Header() @@ -321,20 +380,28 @@ func (w *Worker) GetCurrentHeader() *block.Header { } // makeCurrent creates a new environment for the current cycle. -func (w *Worker) makeCurrent(parent *block.Header, header *block.Header) error { - state, err := w.chain.StateAt(parent.Root()) +func (w *Worker) makeCurrent(parent *block.Header, header *block.Header) (*environment, error) { + env, err := makeEnvironment(w.chain, parent, header) if err != nil { - return err + return nil, err + } + + w.current = env + return w.current, nil +} + +func makeEnvironment(chain core.BlockChain, parent *block.Header, header *block.Header) (*environment, error) { + state, err := chain.StateAt(parent.Root()) + if err != nil { + return nil, err } env := &environment{ - signer: types.NewEIP155Signer(w.config.ChainID), - ethSigner: types.NewEIP155Signer(w.config.EthCompatibleChainID), + signer: types.NewEIP155Signer(chain.Config().ChainID), + ethSigner: types.NewEIP155Signer(chain.Config().EthCompatibleChainID), state: state, header: header, } - - w.current = env - return nil + return env, nil } // GetCurrentResult gets the current block processing result. @@ -356,14 +423,14 @@ func (w *Worker) GetCurrentState() *state.DB { } // GetNewEpoch gets the current epoch. -func (w *Worker) GetNewEpoch() *big.Int { - parent := w.chain.CurrentBlock() +func GetNewEpoch(chain core.BlockChain) *big.Int { + parent := chain.CurrentBlock() epoch := new(big.Int).Set(parent.Header().Epoch()) shardState, err := parent.Header().GetShardState() if err == nil && shardState.Epoch != nil && - w.config.IsStaking(shardState.Epoch) { + chain.Config().IsStaking(shardState.Epoch) { // For shard state of staking epochs, the shard state will // have an epoch and it will decide the next epoch for following blocks epoch = new(big.Int).Set(shardState.Epoch) @@ -381,16 +448,6 @@ func (w *Worker) GetCurrentReceipts() []*types.Receipt { return w.current.receipts } -// OutgoingReceipts get the receipts generated starting from the last state. -func (w *Worker) OutgoingReceipts() []*types.CXReceipt { - return w.current.outcxs -} - -// IncomingReceipts get incoming receipts in destination shard that is received from source shard -func (w *Worker) IncomingReceipts() []*types.CXReceiptsProof { - return w.current.incxs -} - // CollectVerifiedSlashes sets w.current.slashes only to those that // past verification func (w *Worker) CollectVerifiedSlashes() error { @@ -558,7 +615,7 @@ func (w *Worker) FinalizeNewBlock( } }() - block, payout, err := w.engine.Finalize( + block, payout, err := w.chain.Engine().Finalize( w.chain, w.beacon, copyHeader, state, w.current.txs, w.current.receipts, @@ -572,33 +629,14 @@ func (w *Worker) FinalizeNewBlock( return block, nil } -// New create a new worker object. -func New( - config *params.ChainConfig, chain core.BlockChain, beacon core.BlockChain, engine consensus_engine.Engine, -) *Worker { - worker := &Worker{ - config: config, - factory: blockfactory.NewFactory(config), - chain: chain, - beacon: beacon, - engine: engine, +func (w *Worker) GasFloor(epoch *big.Int) uint64 { + if w.config.IsBlockGas30M(epoch) { + return 30_000_000 } - worker.gasFloor = 80000000 - worker.gasCeil = 120000000 - - parent := worker.chain.CurrentBlock().Header() - num := parent.Number() - timestamp := time.Now().Unix() - epoch := worker.GetNewEpoch() - header := worker.factory.NewHeader(epoch).With(). - ParentHash(parent.Hash()). - Number(num.Add(num, common.Big1)). - GasLimit(worker.gasFloor). //core.CalcGasLimit(parent, worker.gasFloor, worker.gasCeil)). - Time(big.NewInt(timestamp)). - ShardID(worker.chain.ShardID()). - Header() - worker.makeCurrent(parent, header) + return w.gasFloor +} - return worker +func (w *Worker) GasCeil() uint64 { + return w.gasCeil } diff --git a/node/worker/worker_test.go b/node/worker/worker_test.go index 4c87c99377..8dc84e14e7 100644 --- a/node/worker/worker_test.go +++ b/node/worker/worker_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/harmony-one/harmony/core/rawdb" + "github.com/stretchr/testify/require" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" @@ -50,7 +51,7 @@ func TestNewWorker(t *testing.T) { t.Error(err) } // Create a new worker - worker := New(params.TestChainConfig, chain, nil, engine) + worker := New(chain, nil) if worker.GetCurrentState().GetBalance(crypto.PubkeyToAddress(testBankKey.PublicKey)).Cmp(testBankFunds) != 0 { t.Error("Worker state is not setup correctly") @@ -75,7 +76,7 @@ func TestCommitTransactions(t *testing.T) { chain, _ := core.NewBlockChain(database, nil, nil, cacheConfig, gspec.Config, engine, vm.Config{}) // Create a new worker - worker := New(params.TestChainConfig, chain, nil, engine) + worker := New(chain, nil) // Generate a test tx baseNonce := worker.GetCurrentState().GetNonce(crypto.PubkeyToAddress(testBankKey.PublicKey)) @@ -100,3 +101,12 @@ func TestCommitTransactions(t *testing.T) { t.Error("Transaction is not committed") } } + +func TestGasLimit(t *testing.T) { + w := newWorker( + ¶ms.ChainConfig{ + BlockGas30MEpoch: big.NewInt(10), + }, nil, nil) + require.EqualValues(t, 80_000_000, w.GasFloor(big.NewInt(3))) + require.EqualValues(t, 30_000_000, w.GasFloor(big.NewInt(10))) +} diff --git a/p2p/host.go b/p2p/host.go index 246b598b22..31c9c2c44a 100644 --- a/p2p/host.go +++ b/p2p/host.go @@ -536,7 +536,7 @@ func (host *HostV2) ListenClose(net libp2p_network.Network, addr ma.Multiaddr) { // called when a connection opened func (host *HostV2) Connected(net libp2p_network.Network, conn libp2p_network.Conn) { - host.logger.Info().Interface("node", conn.RemotePeer()).Msg("peer connected") + host.logger.Debug().Interface("node", conn.RemotePeer()).Msg("peer connected") for _, function := range host.onConnections.GetAll() { if err := function(net, conn); err != nil { @@ -547,7 +547,7 @@ func (host *HostV2) Connected(net libp2p_network.Network, conn libp2p_network.Co // called when a connection closed func (host *HostV2) Disconnected(net libp2p_network.Network, conn libp2p_network.Conn) { - host.logger.Info().Interface("node", conn.RemotePeer()).Msg("peer disconnected") + host.logger.Debug().Interface("node", conn.RemotePeer()).Msg("peer disconnected") for _, function := range host.onDisconnects.GetAll() { if err := function(conn); err != nil { diff --git a/p2p/security/security_test.go b/p2p/security/security_test.go index a53b2cc4da..73ce4741e7 100644 --- a/p2p/security/security_test.go +++ b/p2p/security/security_test.go @@ -163,6 +163,7 @@ func (conn *fakeConn) RemoteMultiaddr() ma.Multiaddr { } func (conn *fakeConn) Stat() libp2p_network.ConnStats { return libp2p_network.ConnStats{} } func (conn *fakeConn) Scope() libp2p_network.ConnScope { return nil } +func (conn *fakeConn) IsClosed() bool { return false } func TestGetRemoteIP(t *testing.T) { ip, err := getRemoteIP(&fakeConn{}) diff --git a/p2p/stream/common/requestmanager/interface_test.go b/p2p/stream/common/requestmanager/interface_test.go index c51303ccba..dd9c772fb8 100644 --- a/p2p/stream/common/requestmanager/interface_test.go +++ b/p2p/stream/common/requestmanager/interface_test.go @@ -5,6 +5,7 @@ import ( "fmt" "strconv" "sync" + "time" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/rlp" @@ -118,7 +119,7 @@ func (st *testStream) FailedTimes() int { return 0 } -func (st *testStream) AddFailedTimes() { +func (st *testStream) AddFailedTimes(faultRecoveryThreshold time.Duration) { return } diff --git a/p2p/stream/common/streammanager/interface_test.go b/p2p/stream/common/streammanager/interface_test.go index 5a9bb44366..6933615f9a 100644 --- a/p2p/stream/common/streammanager/interface_test.go +++ b/p2p/stream/common/streammanager/interface_test.go @@ -6,6 +6,7 @@ import ( "strconv" "sync" "sync/atomic" + "time" sttypes "github.com/harmony-one/harmony/p2p/stream/types" "github.com/libp2p/go-libp2p/core/network" @@ -74,7 +75,7 @@ func (st *testStream) FailedTimes() int { return 0 } -func (st *testStream) AddFailedTimes() { +func (st *testStream) AddFailedTimes(faultRecoveryThreshold time.Duration) { return } diff --git a/p2p/stream/protocols/sync/chain.go b/p2p/stream/protocols/sync/chain.go index 14e3be5f8e..a095fffc1f 100644 --- a/p2p/stream/protocols/sync/chain.go +++ b/p2p/stream/protocols/sync/chain.go @@ -168,8 +168,7 @@ func (ch *chainHelperImpl) getNodeData(hs []common.Hash) ([][]byte, error) { // getReceipts assembles the response to a receipt query. func (ch *chainHelperImpl) getReceipts(hs []common.Hash) ([]types.Receipts, error) { - var receipts []types.Receipts - + receipts := make([]types.Receipts, len(hs)) for i, hash := range hs { // Retrieve the requested block's receipts results := ch.chain.GetReceiptsByHash(hash) @@ -177,8 +176,9 @@ func (ch *chainHelperImpl) getReceipts(hs []common.Hash) ([]types.Receipts, erro if header := ch.chain.GetHeaderByHash(hash); header == nil || header.ReceiptHash() != types.EmptyRootHash { continue } + return nil, errors.New("invalid hashes to get receipts") } - receipts[i] = append(receipts[i], results...) + receipts[i] = results } return receipts, nil } diff --git a/p2p/stream/protocols/sync/chain_test.go b/p2p/stream/protocols/sync/chain_test.go index 8883d7cb5d..8d478e2b3f 100644 --- a/p2p/stream/protocols/sync/chain_test.go +++ b/p2p/stream/protocols/sync/chain_test.go @@ -53,13 +53,43 @@ func (tch *testChainHelper) getNodeData(hs []common.Hash) ([][]byte, error) { func (tch *testChainHelper) getReceipts(hs []common.Hash) ([]types.Receipts, error) { testReceipts := makeTestReceipts(len(hs), 3) - receipts := make([]types.Receipts, len(hs)*3) + receipts := make([]types.Receipts, len(hs)) for i, _ := range hs { receipts[i] = testReceipts } return receipts, nil } +func checkGetReceiptsResult(b []byte, hs []common.Hash) error { + var msg = &syncpb.Message{} + if err := protobuf.Unmarshal(b, msg); err != nil { + return err + } + bhResp, err := msg.GetReceiptsResponse() + if err != nil { + return err + } + if len(hs) != len(bhResp.Receipts) { + return errors.New("unexpected size") + } + return nil +} + +func checkGetNodeDataResult(b []byte, hs []common.Hash) error { + var msg = &syncpb.Message{} + if err := protobuf.Unmarshal(b, msg); err != nil { + return err + } + bhResp, err := msg.GetNodeDataResponse() + if err != nil { + return err + } + if len(hs) != len(bhResp.DataBytes) { + return errors.New("unexpected size") + } + return nil +} + func numberToHash(bn uint64) common.Hash { var h common.Hash binary.LittleEndian.PutUint64(h[:], bn) diff --git a/p2p/stream/protocols/sync/const.go b/p2p/stream/protocols/sync/const.go index 745ed35ba9..b4cf4410af 100644 --- a/p2p/stream/protocols/sync/const.go +++ b/p2p/stream/protocols/sync/const.go @@ -19,14 +19,18 @@ const ( // GetNodeDataCap is the cap of request of single GetNodeData request // This number has an effect on maxMsgBytes as 20MB defined in github.com/harmony-one/harmony/p2p/stream/types. - GetNodeDataCap = 10 + GetNodeDataCap = 256 // GetReceiptsCap is the cap of request of single GetReceipts request // This number has an effect on maxMsgBytes as 20MB defined in github.com/harmony-one/harmony/p2p/stream/types. - GetReceiptsCap = 10 + GetReceiptsCap = 128 // MaxStreamFailures is the maximum allowed failures before stream gets removed - MaxStreamFailures = 3 + MaxStreamFailures = 5 + + // FaultRecoveryThreshold is the minimum duration before it resets the previous failures + // So, if stream hasn't had any issue for a certain amount of time since last failure, we can still trust it + FaultRecoveryThreshold = 30 * time.Minute // minAdvertiseInterval is the minimum advertise interval minAdvertiseInterval = 1 * time.Minute diff --git a/p2p/stream/protocols/sync/message/parse.go b/p2p/stream/protocols/sync/message/parse.go index 22e6102204..b0bf360a8a 100644 --- a/p2p/stream/protocols/sync/message/parse.go +++ b/p2p/stream/protocols/sync/message/parse.go @@ -79,3 +79,35 @@ func (msg *Message) GetBlocksByHashesResponse() (*GetBlocksByHashesResponse, err } return gbResp, nil } + +// GetReceiptsResponse parse the message to GetReceiptsResponse +func (msg *Message) GetReceiptsResponse() (*GetReceiptsResponse, error) { + resp := msg.GetResp() + if resp == nil { + return nil, errors.New("not response message") + } + if errResp := resp.GetErrorResponse(); errResp != nil { + return nil, &ResponseError{errResp.Error} + } + grResp := resp.GetGetReceiptsResponse() + if grResp == nil { + return nil, errors.New("not GetGetReceiptsResponse") + } + return grResp, nil +} + +// GetNodeDataResponse parse the message to GetNodeDataResponse +func (msg *Message) GetNodeDataResponse() (*GetNodeDataResponse, error) { + resp := msg.GetResp() + if resp == nil { + return nil, errors.New("not response message") + } + if errResp := resp.GetErrorResponse(); errResp != nil { + return nil, &ResponseError{errResp.Error} + } + gnResp := resp.GetGetNodeDataResponse() + if gnResp == nil { + return nil, errors.New("not GetGetNodeDataResponse") + } + return gnResp, nil +} diff --git a/p2p/stream/protocols/sync/protocol.go b/p2p/stream/protocols/sync/protocol.go index ca4590c972..0cb48bfff3 100644 --- a/p2p/stream/protocols/sync/protocol.go +++ b/p2p/stream/protocols/sync/protocol.go @@ -19,6 +19,7 @@ import ( "github.com/hashicorp/go-version" libp2p_host "github.com/libp2p/go-libp2p/core/host" libp2p_network "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/protocol" "github.com/rs/zerolog" ) @@ -149,7 +150,7 @@ func (p *Protocol) IsBeaconNode() bool { } // Match checks the compatibility to the target protocol ID. -func (p *Protocol) Match(targetID string) bool { +func (p *Protocol) Match(targetID protocol.ID) bool { target, err := sttypes.ProtoIDToProtoSpec(sttypes.ProtoID(targetID)) if err != nil { return false @@ -272,13 +273,16 @@ func (p *Protocol) RemoveStream(stID sttypes.StreamID) { st.Close() // stream manager removes this stream from the list and triggers discovery if number of streams are not enough p.sm.RemoveStream(stID) //TODO: double check to see if this part is needed + p.logger.Info(). + Str("stream ID", string(stID)). + Msg("stream removed") } } func (p *Protocol) StreamFailed(stID sttypes.StreamID, reason string) { st, exist := p.sm.GetStreamByID(stID) if exist && st != nil { - st.AddFailedTimes() + st.AddFailedTimes(FaultRecoveryThreshold) p.logger.Info(). Str("stream ID", string(st.ID())). Int("num failures", st.FailedTimes()). diff --git a/p2p/stream/protocols/sync/protocol_test.go b/p2p/stream/protocols/sync/protocol_test.go index 0e40f60175..cb6a7c0875 100644 --- a/p2p/stream/protocols/sync/protocol_test.go +++ b/p2p/stream/protocols/sync/protocol_test.go @@ -8,11 +8,12 @@ import ( "github.com/libp2p/go-libp2p/core/discovery" libp2p_peer "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" ) func TestProtocol_Match(t *testing.T) { tests := []struct { - targetID string + targetID protocol.ID exp bool }{ {"harmony/sync/unitest/0/1.0.1/1", true}, diff --git a/p2p/stream/protocols/sync/stream_test.go b/p2p/stream/protocols/sync/stream_test.go index a9aae57faa..f33bc3eb9f 100644 --- a/p2p/stream/protocols/sync/stream_test.go +++ b/p2p/stream/protocols/sync/stream_test.go @@ -40,6 +40,26 @@ var ( } testGetBlocksByHashesRequest = syncpb.MakeGetBlocksByHashesRequest(testGetBlockByHashes) testGetBlocksByHashesRequestMsg = syncpb.MakeMessageFromRequest(testGetBlocksByHashesRequest) + + testGetReceipts = []common.Hash{ + numberToHash(1), + numberToHash(2), + numberToHash(3), + numberToHash(4), + numberToHash(5), + } + testGetReceiptsRequest = syncpb.MakeGetReceiptsRequest(testGetReceipts) + testGetReceiptsRequestMsg = syncpb.MakeMessageFromRequest(testGetReceiptsRequest) + + testGetNodeData = []common.Hash{ + numberToHash(1), + numberToHash(2), + numberToHash(3), + numberToHash(4), + numberToHash(5), + } + testGetNodeDataRequest = syncpb.MakeGetNodeDataRequest(testGetNodeData) + testGetNodeDataRequestMsg = syncpb.MakeMessageFromRequest(testGetNodeDataRequest) ) func TestSyncStream_HandleGetBlocksByRequest(t *testing.T) { @@ -126,6 +146,48 @@ func TestSyncStream_HandleGetBlocksByHashes(t *testing.T) { } } +func TestSyncStream_HandleGetReceipts(t *testing.T) { + st, remoteSt := makeTestSyncStream() + + go st.run() + defer close(st.closeC) + + req := testGetReceiptsRequestMsg + b, _ := protobuf.Marshal(req) + err := remoteSt.WriteBytes(b) + if err != nil { + t.Fatal(err) + } + + time.Sleep(200 * time.Millisecond) + receivedBytes, _ := remoteSt.ReadBytes() + + if err := checkGetReceiptsResult(receivedBytes, testGetReceipts); err != nil { + t.Fatal(err) + } +} + +func TestSyncStream_HandleGetNodeData(t *testing.T) { + st, remoteSt := makeTestSyncStream() + + go st.run() + defer close(st.closeC) + + req := testGetNodeDataRequestMsg + b, _ := protobuf.Marshal(req) + err := remoteSt.WriteBytes(b) + if err != nil { + t.Fatal(err) + } + + time.Sleep(200 * time.Millisecond) + receivedBytes, _ := remoteSt.ReadBytes() + + if err := checkGetNodeDataResult(receivedBytes, testGetNodeData); err != nil { + t.Fatal(err) + } +} + func makeTestSyncStream() (*syncStream, *testRemoteBaseStream) { localRaw, remoteRaw := makePairP2PStreams() remote := newTestRemoteBaseStream(remoteRaw) @@ -230,6 +292,10 @@ func (st *testRemoteBaseStream) WriteBytes(b []byte) error { type fakeConn struct{} +func (conn *fakeConn) IsClosed() bool { + return false +} + func (conn *fakeConn) ID() string { return "" } func (conn *fakeConn) NewStream(context.Context) (libp2p_network.Stream, error) { return nil, nil } func (conn *fakeConn) GetStreams() []libp2p_network.Stream { return nil } diff --git a/p2p/stream/types/interface.go b/p2p/stream/types/interface.go index d7b60f78c3..8cc9062afd 100644 --- a/p2p/stream/types/interface.go +++ b/p2p/stream/types/interface.go @@ -4,6 +4,7 @@ import ( p2ptypes "github.com/harmony-one/harmony/p2p/types" "github.com/hashicorp/go-version" libp2p_network "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/protocol" ) // Protocol is the interface of protocol to be registered to libp2p. @@ -15,7 +16,7 @@ type Protocol interface { ProtoID() ProtoID // ShardProtoID() ProtoID IsBeaconNode() bool - Match(string) bool + Match(id protocol.ID) bool HandleStream(st libp2p_network.Stream) } diff --git a/p2p/stream/types/stream.go b/p2p/stream/types/stream.go index 18b47f6158..12581b7de0 100644 --- a/p2p/stream/types/stream.go +++ b/p2p/stream/types/stream.go @@ -5,6 +5,7 @@ import ( "encoding/binary" "io" "sync" + "time" libp2p_network "github.com/libp2p/go-libp2p/core/network" "github.com/pkg/errors" @@ -22,7 +23,7 @@ type Stream interface { Close() error CloseOnExit() error FailedTimes() int - AddFailedTimes() + AddFailedTimes(faultRecoveryThreshold time.Duration) ResetFailedTimes() } @@ -38,7 +39,8 @@ type BaseStream struct { specErr error specOnce sync.Once - failedTimes int + failedTimes int + lastFailureTime time.Time } // NewBaseStream creates BaseStream as the wrapper of libp2p Stream @@ -82,8 +84,15 @@ func (st *BaseStream) FailedTimes() int { return st.failedTimes } -func (st *BaseStream) AddFailedTimes() { +func (st *BaseStream) AddFailedTimes(faultRecoveryThreshold time.Duration) { + if st.failedTimes > 0 { + durationSinceLastFailure := time.Now().Sub(st.lastFailureTime) + if durationSinceLastFailure >= faultRecoveryThreshold { + st.ResetFailedTimes() + } + } st.failedTimes++ + st.lastFailureTime = time.Now() } func (st *BaseStream) ResetFailedTimes() { diff --git a/rpc/preimages.go b/rpc/preimages.go new file mode 100644 index 0000000000..cd5b8d5270 --- /dev/null +++ b/rpc/preimages.go @@ -0,0 +1,35 @@ +package rpc + +import ( + "context" + + "github.com/harmony-one/harmony/core" + "github.com/harmony-one/harmony/eth/rpc" + "github.com/harmony-one/harmony/hmy" +) + +type PreimagesService struct { + hmy *hmy.Harmony +} + +// NewPreimagesAPI creates a new API for the RPC interface +func NewPreimagesAPI(hmy *hmy.Harmony, version string) rpc.API { + var service interface{} = &PreimagesService{hmy} + return rpc.API{ + Namespace: version, + Version: APIVersion, + Service: service, + Public: true, + } +} + +func (s *PreimagesService) Export(ctx context.Context, path string) error { + // these are by default not blocking + return core.ExportPreimages(s.hmy.BlockChain, path) +} + +func (s *PreimagesService) Verify(ctx context.Context) (uint64, error) { + currentBlock := s.hmy.CurrentBlock() + // these are by default not blocking + return core.VerifyPreimages(currentBlock.Header(), s.hmy.BlockChain) +} diff --git a/rpc/rpc.go b/rpc/rpc.go index a8f1e121a9..96f042f6e7 100644 --- a/rpc/rpc.go +++ b/rpc/rpc.go @@ -42,7 +42,7 @@ const ( var ( // HTTPModules .. - HTTPModules = []string{"hmy", "hmyv2", "eth", "debug", "trace", netNamespace, netV1Namespace, netV2Namespace, web3Namespace, "explorer"} + HTTPModules = []string{"hmy", "hmyv2", "eth", "debug", "trace", netNamespace, netV1Namespace, netV2Namespace, web3Namespace, "explorer", "preimages"} // WSModules .. WSModules = []string{"hmy", "hmyv2", "eth", "debug", "trace", netNamespace, netV1Namespace, netV2Namespace, web3Namespace, "web3"} @@ -71,6 +71,9 @@ func (n Version) Namespace() string { func StartServers(hmy *hmy.Harmony, apis []rpc.API, config nodeconfig.RPCServerConfig, rpcOpt harmony.RpcOptConfig) error { apis = append(apis, getAPIs(hmy, config)...) authApis := append(apis, getAuthAPIs(hmy, config.DebugEnabled, config.RateLimiterEnabled, config.RequestsPerSecond)...) + if rpcOpt.PreimagesEnabled { + authApis = append(authApis, NewPreimagesAPI(hmy, "preimages")) + } // load method filter from file (if exist) var rmf rpc.RpcMethodFilter rpcFilterFilePath := strings.TrimSpace(rpcOpt.RpcFilterFile) diff --git a/staking/availability/measure.go b/staking/availability/measure.go index 680092aa0d..881baa8553 100644 --- a/staking/availability/measure.go +++ b/staking/availability/measure.go @@ -18,11 +18,25 @@ import ( var ( measure = numeric.NewDec(2).Quo(numeric.NewDec(3)) - MinCommissionRate = numeric.MustNewDecFromStr("0.05") + minCommissionRateEra1 = numeric.MustNewDecFromStr("0.05") + minCommissionRateEra2 = numeric.MustNewDecFromStr("0.07") // ErrDivByZero .. ErrDivByZero = errors.New("toSign of availability cannot be 0, mistake in protocol") ) +// Returns the minimum commission rate between the two options. +// The later rate supersedes the earlier rate. +// If neither is applicable, returns 0. +func MinCommissionRate(era1, era2 bool) numeric.Dec { + if era2 { + return minCommissionRateEra2 + } + if era1 { + return minCommissionRateEra1 + } + return numeric.ZeroDec() +} + // BlockSigners .. func BlockSigners( bitmap []byte, parentCommittee *shard.Committee, @@ -217,33 +231,39 @@ func ComputeAndMutateEPOSStatus( return nil } -// UpdateMinimumCommissionFee update the validator commission fee to the minimum 5% -// if the validator has a lower commission rate and 100 epochs have passed after -// the validator was first elected. +// UpdateMinimumCommissionFee update the validator commission fee to the minRate +// if the validator has a lower commission rate and promoPeriod epochs have passed after +// the validator was first elected. It returns true if the commission was updated func UpdateMinimumCommissionFee( electionEpoch *big.Int, state *state.DB, addr common.Address, - promoPeriod int64, -) error { + minRate numeric.Dec, + promoPeriod uint64, +) (bool, error) { utils.Logger().Info().Msg("begin update min commission fee") wrapper, err := state.ValidatorWrapper(addr, true, false) if err != nil { - return err + return false, err } firstElectionEpoch := state.GetValidatorFirstElectionEpoch(addr) - if firstElectionEpoch.Uint64() != 0 && big.NewInt(0).Sub(electionEpoch, firstElectionEpoch).Int64() >= int64(promoPeriod) { - if wrapper.Rate.LT(MinCommissionRate) { + // convert all to uint64 for easy maths + // this can take decades of time without overflowing + first := firstElectionEpoch.Uint64() + election := electionEpoch.Uint64() + if first != 0 && election-first >= promoPeriod && election >= first { + if wrapper.Rate.LT(minRate) { utils.Logger().Info(). Str("addr", addr.Hex()). Str("old rate", wrapper.Rate.String()). Str("firstElectionEpoch", firstElectionEpoch.String()). Msg("updating min commission rate") - wrapper.Rate.SetBytes(MinCommissionRate.Bytes()) + wrapper.Rate.SetBytes(minRate.Bytes()) + return true, nil } } - return nil + return false, nil } diff --git a/staking/effective/calculate_test.go b/staking/effective/calculate_test.go index 28ae4cbfb2..7127192c3b 100644 --- a/staking/effective/calculate_test.go +++ b/staking/effective/calculate_test.go @@ -3,9 +3,9 @@ package effective import ( "encoding/json" "fmt" - "io/ioutil" "math/big" "math/rand" + "os" "sort" "testing" @@ -35,7 +35,7 @@ type slotsData struct { } func init() { - input, err := ioutil.ReadFile(eposTestingFile) + input, err := os.ReadFile(eposTestingFile) if err != nil { panic( fmt.Sprintf("cannot open genesisblock config file %v, err %v\n", diff --git a/staking/reward/values.go b/staking/reward/values.go index 805c2f38fc..a8a6f9ba37 100644 --- a/staking/reward/values.go +++ b/staking/reward/values.go @@ -31,6 +31,13 @@ var ( TwoSecStakedBlocks = numeric.NewDecFromBigInt(new(big.Int).Mul( big.NewInt(7*denominations.Nano), big.NewInt(denominations.Nano), )) + // HIP30StakedBlocks is the reward received after HIP-30 goes into + // effect. It is simply double the TwoSecStakedBlocks reward, since + // the number of shards is being halved and we keep emission + // constant. + HIP30StakedBlocks = numeric.NewDecFromBigInt(new(big.Int).Mul( + big.NewInt(14*denominations.Nano), big.NewInt(denominations.Nano), + )) // TotalInitialTokens is the total amount of tokens (in ONE) at block 0 of the network. // This should be set/change on the node's init according to the core.GenesisSpec. diff --git a/test/build-localnet-validator.sh b/test/build-localnet-validator.sh index bffc7b94a9..08d9877779 100644 --- a/test/build-localnet-validator.sh +++ b/test/build-localnet-validator.sh @@ -19,13 +19,13 @@ hmy --node=http://127.0.0.1:9500 transfer --from one1zksj3evekayy90xt4psrz8h #wait for epoch 2 epoch=$(hmy blockchain latest-headers --node="http://localhost:9500" | jq -r '.["result"]["beacon-chain-header"]["epoch"]') -while (( epoch < 2 )); do - echo "Not yet on epoch 2 .. waiting 30s" +while (( epoch < 1 )); do + echo "Not yet on epoch 1 .. waiting 30s" epoch=$(hmy blockchain latest-headers --node="http://localhost:9500" | jq -r '.["result"]["beacon-chain-header"]["epoch"]') sleep 30 done -echo "Now in epoch 2, we'll create the external validators" +echo "Now in epoch 1, we'll create the external validators" hmy --node="http://localhost:9500" staking create-validator \ --validator-addr one17ughrllgnzx9sfa46p568k8rdmtz7qj85slc6t --amount 10000 \ diff --git a/test/chain/chain/chain_makers.go b/test/chain/chain/chain_makers.go index be9096e575..2b82beb575 100644 --- a/test/chain/chain/chain_makers.go +++ b/test/chain/chain/chain_makers.go @@ -102,7 +102,7 @@ func (b *BlockGen) AddTxWithChain(bc core.BlockChain, tx *types.Transaction) { b.statedb.Prepare(tx.Hash(), common.Hash{}, len(b.txs)) coinbase := b.header.Coinbase() gasUsed := b.header.GasUsed() - receipt, _, _, _, err := core.ApplyTransaction(b.config, bc, &coinbase, b.gasPool, b.statedb, b.header, tx, &gasUsed, vm.Config{}) + receipt, _, _, _, err := core.ApplyTransaction(bc, &coinbase, b.gasPool, b.statedb, b.header, tx, &gasUsed, vm.Config{}) b.header.SetGasUsed(gasUsed) b.header.SetCoinbase(coinbase) if err != nil { diff --git a/test/chain/main.go b/test/chain/main.go index ec28ead0cd..4b935292f0 100644 --- a/test/chain/main.go +++ b/test/chain/main.go @@ -93,7 +93,7 @@ func fundFaucetContract(chain core.BlockChain) { fmt.Println("--------- Funding addresses for Faucet Contract Call ---------") fmt.Println() - contractworker = pkgworker.New(params.TestChainConfig, chain, nil, chain.Engine()) + contractworker = pkgworker.New(chain, nil) nonce = contractworker.GetCurrentState().GetNonce(crypto.PubkeyToAddress(FaucetPriKey.PublicKey)) dataEnc = common.FromHex(FaucetContractBinary) ftx, _ := types.SignTx( diff --git a/test/kill_node.sh b/test/kill_node.sh index 1f6f200e1f..c70f82bd5c 100755 --- a/test/kill_node.sh +++ b/test/kill_node.sh @@ -3,9 +3,15 @@ # list of process name to be killed targetProcess=( "harmony" "bootnode" "soldier" "commander" "profiler" ) +NAME="$(uname -s)" + for pname in "${targetProcess[@]}" do - sudo pkill -9 -e "^(${pname})$" + if [ $NAME == "Darwin" ]; then + pkill -9 "^(${pname})$" + else + pkill -9 -e "^(${pname})$" + fi done rm -rf db-127.0.0.1-* \ No newline at end of file diff --git a/webhooks/yaml.go b/webhooks/yaml.go index 2c0331fcc0..2d7521c0ee 100644 --- a/webhooks/yaml.go +++ b/webhooks/yaml.go @@ -3,8 +3,9 @@ package webhooks import ( "bytes" "encoding/json" - "io/ioutil" + "io" "net/http" + "os" "gopkg.in/yaml.v2" ) @@ -63,7 +64,7 @@ func DoPost(url string, record interface{}) (*ReportResult, error) { return nil, err } defer resp.Body.Close() - result, err := ioutil.ReadAll(resp.Body) + result, err := io.ReadAll(resp.Body) if err != nil { return nil, err } @@ -76,7 +77,7 @@ func DoPost(url string, record interface{}) (*ReportResult, error) { // NewWebHooksFromPath .. func NewWebHooksFromPath(yamlPath string) (*Hooks, error) { - rawYAML, err := ioutil.ReadFile(yamlPath) + rawYAML, err := os.ReadFile(yamlPath) if err != nil { return nil, err }