From ea6e75a58f607fe92c17c22526772bc4ba219ee3 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Wed, 23 Aug 2023 10:45:37 +0000 Subject: [PATCH 01/54] flags: set up preimage flags --- cmd/harmony/default.go | 12 +++++ cmd/harmony/flags.go | 53 ++++++++++++++++++++++ cmd/harmony/flags_test.go | 69 +++++++++++++++++++++++++++++ cmd/harmony/main.go | 1 + internal/cli/flag.go | 19 +++++++- internal/cli/parse.go | 15 +++++++ internal/configs/harmony/harmony.go | 8 ++++ 7 files changed, 176 insertions(+), 1 deletion(-) diff --git a/cmd/harmony/default.go b/cmd/harmony/default.go index 4cc20cfdf4..4e5c093bd6 100644 --- a/cmd/harmony/default.go +++ b/cmd/harmony/default.go @@ -149,6 +149,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, @@ -291,6 +298,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/flags.go b/cmd/harmony/flags.go index acf53d8b3a..06a7eeb20c 100644 --- a/cmd/harmony/flags.go +++ b/cmd/harmony/flags.go @@ -205,6 +205,13 @@ var ( revertBeforeFlag, } + preimageFlags = []cli.Flag{ + preimageImportFlag, + preimageExportFlag, + preimageGenerateStartFlag, + preimageGenerateEndFlag, + } + legacyRevertFlags = []cli.Flag{ legacyRevertBeaconFlag, legacyRevertBeforeFlag, @@ -1656,6 +1663,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..11d6bc274c 100644 --- a/cmd/harmony/flags_test.go +++ b/cmd/harmony/flags_test.go @@ -1509,6 +1509,75 @@ func TestRevertFlags(t *testing.T) { } } +func TestPreimageFlags(t *testing.T) { + tests := []struct { + args []string + expConfig harmonyconfig.PreimageConfig + expErr error + }{ + { + args: []string{}, + expConfig: harmonyconfig.PreimageConfig{ + ImportFrom: defaultPreimageConfig.ImportFrom, + ExportTo: defaultPreimageConfig.ExportTo, + GenerateStart: defaultPreimageConfig.GenerateStart, + GenerateEnd: defaultPreimageConfig.GenerateEnd, + }, + }, + { + 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..b075529289 100644 --- a/cmd/harmony/main.go +++ b/cmd/harmony/main.go @@ -246,6 +246,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) diff --git a/internal/cli/flag.go b/internal/cli/flag.go index 755a6a73b9..075dbe5aa2 100644 --- a/internal/cli/flag.go +++ b/internal/cli/flag.go @@ -71,7 +71,6 @@ type Int64Flag struct { Usage string Deprecated string Hidden bool - DefValue int64 } @@ -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..3fa92ce2bb 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 { @@ -303,6 +304,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"` From b419e2f22146ad742eda3a4ba5443ad7eb821b32 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 26 Aug 2023 08:49:54 +0000 Subject: [PATCH 02/54] hip30: set up preimage import, export, api --- cmd/harmony/flags.go | 2 +- cmd/harmony/flags_test.go | 17 +++---- cmd/harmony/main.go | 78 +++++++++++++++++++++++++++++ internal/configs/harmony/harmony.go | 2 +- 4 files changed, 86 insertions(+), 13 deletions(-) diff --git a/cmd/harmony/flags.go b/cmd/harmony/flags.go index 06a7eeb20c..87f86ecf89 100644 --- a/cmd/harmony/flags.go +++ b/cmd/harmony/flags.go @@ -1693,7 +1693,7 @@ var ( func applyPreimageFlags(cmd *cobra.Command, config *harmonyconfig.HarmonyConfig) { if cli.HasFlagsChanged(cmd, preimageFlags) { cfg := getDefaultPreimageConfigCopy() - config.Preimage = cfg + config.Preimage = &cfg } if cli.IsFlagChanged(cmd, preimageImportFlag) { config.Preimage.ImportFrom = cli.GetStringFlagValue(cmd, preimageImportFlag) diff --git a/cmd/harmony/flags_test.go b/cmd/harmony/flags_test.go index 11d6bc274c..60efb78cf8 100644 --- a/cmd/harmony/flags_test.go +++ b/cmd/harmony/flags_test.go @@ -1512,21 +1512,16 @@ func TestRevertFlags(t *testing.T) { func TestPreimageFlags(t *testing.T) { tests := []struct { args []string - expConfig harmonyconfig.PreimageConfig + expConfig *harmonyconfig.PreimageConfig expErr error }{ { args: []string{}, - expConfig: harmonyconfig.PreimageConfig{ - ImportFrom: defaultPreimageConfig.ImportFrom, - ExportTo: defaultPreimageConfig.ExportTo, - GenerateStart: defaultPreimageConfig.GenerateStart, - GenerateEnd: defaultPreimageConfig.GenerateEnd, - }, + expConfig: nil, }, { args: []string{"--preimage.import", "/path/to/source.csv"}, - expConfig: harmonyconfig.PreimageConfig{ + expConfig: &harmonyconfig.PreimageConfig{ ImportFrom: "/path/to/source.csv", ExportTo: defaultPreimageConfig.ExportTo, GenerateStart: defaultPreimageConfig.GenerateStart, @@ -1535,7 +1530,7 @@ func TestPreimageFlags(t *testing.T) { }, { args: []string{"--preimage.export", "/path/to/destination.csv"}, - expConfig: harmonyconfig.PreimageConfig{ + expConfig: &harmonyconfig.PreimageConfig{ ImportFrom: defaultPreimageConfig.ImportFrom, ExportTo: "/path/to/destination.csv", GenerateStart: defaultPreimageConfig.GenerateStart, @@ -1544,7 +1539,7 @@ func TestPreimageFlags(t *testing.T) { }, { args: []string{"--preimage.start", "1"}, - expConfig: harmonyconfig.PreimageConfig{ + expConfig: &harmonyconfig.PreimageConfig{ ImportFrom: defaultPreimageConfig.ImportFrom, ExportTo: defaultPreimageConfig.ExportTo, GenerateStart: 1, @@ -1553,7 +1548,7 @@ func TestPreimageFlags(t *testing.T) { }, { args: []string{"--preimage.end", "2"}, - expConfig: harmonyconfig.PreimageConfig{ + expConfig: &harmonyconfig.PreimageConfig{ ImportFrom: defaultPreimageConfig.ImportFrom, ExportTo: defaultPreimageConfig.ExportTo, GenerateStart: defaultPreimageConfig.GenerateStart, diff --git a/cmd/harmony/main.go b/cmd/harmony/main.go index b075529289..880c057ceb 100644 --- a/cmd/harmony/main.go +++ b/cmd/harmony/main.go @@ -1,7 +1,9 @@ package main import ( + "encoding/csv" "fmt" + "io" "io/ioutil" "math/big" "math/rand" @@ -21,6 +23,7 @@ import ( "github.com/harmony-one/harmony/internal/shardchain/tikv_manage" "github.com/harmony-one/harmony/internal/tikv/redis_helper" "github.com/harmony-one/harmony/internal/tikv/statedb_cache" + "github.com/harmony-one/harmony/rpc" "github.com/harmony-one/harmony/api/service/crosslink_sending" rosetta_common "github.com/harmony-one/harmony/rosetta/common" @@ -30,6 +33,8 @@ import ( ethCommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -60,6 +65,7 @@ import ( "github.com/harmony-one/harmony/p2p" "github.com/harmony-one/harmony/shard" "github.com/harmony-one/harmony/webhooks" + prom "github.com/prometheus/client_golang/prometheus" ) // Host @@ -376,6 +382,78 @@ func setupNodeAndRun(hc harmonyconfig.HarmonyConfig) { } } + //// code to handle pre-image export, import and generation + if hc.Preimage != nil { + if hc.Preimage.ImportFrom != "" { + reader, err := os.Open(hc.Preimage.ImportFrom) + if err != nil { + fmt.Println("Could not open file for reading", err) + os.Exit(1) + } + csvReader := csv.NewReader(reader) + chain := currentNode.Blockchain() + dbReader := chain.ChainDb() + for { + record, err := csvReader.Read() + if err == io.EOF { + fmt.Println("MyBlockNumber field missing, cannot proceed") + os.Exit(1) + } + if err != nil { + fmt.Println("Could not read from reader", err) + os.Exit(1) + } + // this means the address is a number + if blockNumber, err := strconv.ParseInt(record[1], 10, 64); err == nil { + if record[0] == "MyBlockNumber" { + // export blockNumber to prometheus + gauge := prom.NewGauge( + prom.GaugeOpts{ + Namespace: "hmy", + Subsystem: "blockchain", + Name: "last_preimage_import", + Help: "the last known block for which preimages were imported", + }, + ) + prometheus.PromRegistry().MustRegister( + gauge, + ) + gauge.Set(float64(blockNumber)) + // this is the last record + break + } + } + key := ethCommon.BytesToHash([]byte(record[0])) + value := []byte(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, + }, + ) + } + os.Exit(0) + } else if exportPath := hc.Preimage.ExportTo; exportPath != "" { + if err := rpc.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 && hc.Preimage.GenerateEnd > 0 { + // TODO + } + os.Exit(0) + } + startMsg := "==== New Harmony Node ====" if hc.General.NodeType == nodeTypeExplorer { startMsg = "==== New Explorer Node ====" diff --git a/internal/configs/harmony/harmony.go b/internal/configs/harmony/harmony.go index 3fa92ce2bb..b28fc847cd 100644 --- a/internal/configs/harmony/harmony.go +++ b/internal/configs/harmony/harmony.go @@ -36,7 +36,7 @@ type HarmonyConfig struct { DNSSync DnsSync ShardData ShardDataConfig GPO GasPriceOracleConfig - Preimage PreimageConfig + Preimage *PreimageConfig } func (hc HarmonyConfig) ToRPCServerConfig() nodeconfig.RPCServerConfig { From d398e50f88498444c86b9e7dfe3c32f480b898a1 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 26 Aug 2023 08:53:31 +0000 Subject: [PATCH 03/54] save pre-images by default --- core/blockchain_impl.go | 3 ++- internal/shardchain/shardchains.go | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/core/blockchain_impl.go b/core/blockchain_impl.go index 965dccd9a4..ccb0a6beba 100644 --- a/core/blockchain_impl.go +++ b/core/blockchain_impl.go @@ -149,6 +149,7 @@ var defaultCacheConfig = &CacheConfig{ TrieTimeLimit: 5 * time.Minute, SnapshotLimit: 256, SnapshotWait: true, + Preimages: true, } type BlockChainImpl struct { @@ -236,7 +237,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, 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) From 97d2c061ffbc26666bc8b9f00487803095672701 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 26 Aug 2023 09:50:21 +0000 Subject: [PATCH 04/54] add pre images api --- cmd/harmony/default.go | 1 + cmd/harmony/flags.go | 10 ++++++++++ cmd/harmony/flags_test.go | 25 +++++++++++++++++++++++++ internal/configs/harmony/harmony.go | 2 ++ internal/configs/node/config.go | 1 + rpc/rpc.go | 3 +++ 6 files changed, 42 insertions(+) diff --git a/cmd/harmony/default.go b/cmd/harmony/default.go index 4e5c093bd6..cbedc9370e 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", diff --git a/cmd/harmony/flags.go b/cmd/harmony/flags.go index 87f86ecf89..6b4d5402ce 100644 --- a/cmd/harmony/flags.go +++ b/cmd/harmony/flags.go @@ -90,6 +90,7 @@ var ( rpcOptFlags = []cli.Flag{ rpcDebugEnabledFlag, + rpcPreimagesEnabledFlag, rpcEthRPCsEnabledFlag, rpcStakingRPCsEnabledFlag, rpcLegacyRPCsEnabledFlag, @@ -834,6 +835,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", @@ -886,6 +893,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) } diff --git a/cmd/harmony/flags_test.go b/cmd/harmony/flags_test.go index 60efb78cf8..79a7cd6068 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, }, }, } diff --git a/internal/configs/harmony/harmony.go b/internal/configs/harmony/harmony.go index b28fc847cd..6e5591562c 100644 --- a/internal/configs/harmony/harmony.go +++ b/internal/configs/harmony/harmony.go @@ -85,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, @@ -288,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 { 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/rpc/rpc.go b/rpc/rpc.go index a8f1e121a9..89a0d35327 100644 --- a/rpc/rpc.go +++ b/rpc/rpc.go @@ -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) From 27b70ac0025efb7440c697688cf39c35eb598d2c Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 26 Aug 2023 09:54:44 +0000 Subject: [PATCH 05/54] goimports --- cmd/harmony/flags.go | 6 +++--- cmd/harmony/flags_test.go | 2 +- cmd/harmony/main.go | 2 +- internal/configs/harmony/harmony.go | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cmd/harmony/flags.go b/cmd/harmony/flags.go index 6b4d5402ce..779d50baf7 100644 --- a/cmd/harmony/flags.go +++ b/cmd/harmony/flags.go @@ -839,7 +839,7 @@ var ( Name: "rpc.preimages", Usage: "enable preimages export api", DefValue: defaultConfig.RPCOpt.PreimagesEnabled, - Hidden: true, // not for end users + Hidden: true, // not for end users } rpcEthRPCsEnabledFlag = cli.BoolFlag{ @@ -1675,8 +1675,8 @@ func applyRevertFlags(cmd *cobra.Command, config *harmonyconfig.HarmonyConfig) { var ( preimageImportFlag = cli.StringFlag{ - Name: "preimage.import", - Usage: "Import pre-images from CSV file", + Name: "preimage.import", + Usage: "Import pre-images from CSV file", Hidden: true, DefValue: defaultPreimageConfig.ImportFrom, } diff --git a/cmd/harmony/flags_test.go b/cmd/harmony/flags_test.go index 79a7cd6068..bea0e0eabe 100644 --- a/cmd/harmony/flags_test.go +++ b/cmd/harmony/flags_test.go @@ -1541,7 +1541,7 @@ func TestPreimageFlags(t *testing.T) { expErr error }{ { - args: []string{}, + args: []string{}, expConfig: nil, }, { diff --git a/cmd/harmony/main.go b/cmd/harmony/main.go index 880c057ceb..102d6ea9eb 100644 --- a/cmd/harmony/main.go +++ b/cmd/harmony/main.go @@ -447,7 +447,7 @@ func setupNodeAndRun(hc harmonyconfig.HarmonyConfig) { os.Exit(1) } os.Exit(0) - // both must be set + // both must be set } else if hc.Preimage.GenerateStart > 0 && hc.Preimage.GenerateEnd > 0 { // TODO } diff --git a/internal/configs/harmony/harmony.go b/internal/configs/harmony/harmony.go index 6e5591562c..2fcb200c42 100644 --- a/internal/configs/harmony/harmony.go +++ b/internal/configs/harmony/harmony.go @@ -289,7 +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 + PreimagesEnabled bool // Expose preimage API } type DevnetConfig struct { @@ -308,7 +308,7 @@ type RevertConfig struct { type PreimageConfig struct { ImportFrom string - ExportTo string + ExportTo string GenerateStart uint64 GenerateEnd uint64 } From 20ae5549a3edb04aac860050023a342dcb08cede Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 26 Aug 2023 10:10:44 +0000 Subject: [PATCH 06/54] commit rpc preimages file --- rpc/preimages.go | 128 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 rpc/preimages.go diff --git a/rpc/preimages.go b/rpc/preimages.go new file mode 100644 index 0000000000..941cc86272 --- /dev/null +++ b/rpc/preimages.go @@ -0,0 +1,128 @@ +package rpc + +import ( + "context" + "encoding/csv" + "fmt" + "os" + + ethCommon "github.com/ethereum/go-ethereum/common" + "github.com/harmony-one/harmony/core" + "github.com/harmony-one/harmony/core/rawdb" + "github.com/harmony-one/harmony/eth/rpc" + "github.com/harmony-one/harmony/hmy" + "github.com/harmony-one/harmony/internal/utils" +) + +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 ExportPreimages(s.hmy.BlockChain, path) +} + +// ExportPreimages is public so `main.go` can call it directly` +func ExportPreimages(chain core.BlockChain, path string) error { + // 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() { + // 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{ + // no 0x prefix, stored as hash + fmt.Sprintf("%x", asHash.Bytes()), + // with 0x prefix, stored as bytes + address.Hex(), + }) + } + } + // 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 core.BlockChain, start, end uint64) error { + // 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 + return nil +} \ No newline at end of file From 7fae8e83e291b27a493cf0c938de22eb2ee94ad8 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 26 Aug 2023 11:33:34 +0000 Subject: [PATCH 07/54] preimages: re-generate them using CLI --- cmd/harmony/main.go | 18 +++++++++++++++- core/blockchain.go | 1 + core/blockchain_impl.go | 4 ++++ core/blockchain_stub.go | 4 ++++ core/epochchain.go | 6 ++++++ rpc/preimages.go | 48 ++++++++++++++++++++++++++++++++++++++++- 6 files changed, 79 insertions(+), 2 deletions(-) diff --git a/cmd/harmony/main.go b/cmd/harmony/main.go index 102d6ea9eb..904f51f4bc 100644 --- a/cmd/harmony/main.go +++ b/cmd/harmony/main.go @@ -449,7 +449,23 @@ func setupNodeAndRun(hc harmonyconfig.HarmonyConfig) { os.Exit(0) // both must be set } else if hc.Preimage.GenerateStart > 0 && hc.Preimage.GenerateEnd > 0 { - // TODO + chain := currentNode.Blockchain() + end := hc.Preimage.GenerateEnd + if number := chain.CurrentBlock().NumberU64(); number > end { + fmt.Printf( + "Cropping generate endpoint from %d to %d\n", + number, end, + ) + end = number + } + if err := rpc.GeneratePreimages( + chain, + hc.Preimage.GenerateStart, end, + ); err != nil { + fmt.Println("Error generating", err) + os.Exit(1) + } + os.Exit(0) } os.Exit(0) } diff --git a/core/blockchain.go b/core/blockchain.go index f7e956dbbe..856b3b6f94 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -346,6 +346,7 @@ type BlockChain interface { ) (status WriteStatus, err error) GetLeaderPubKeyFromCoinbase(h *block.Header) (*bls.PublicKeyWrapper, error) + CommitPreimages() error // ========== Only For Tikv Start ========== diff --git a/core/blockchain_impl.go b/core/blockchain_impl.go index ccb0a6beba..b5c03150f7 100644 --- a/core/blockchain_impl.go +++ b/core/blockchain_impl.go @@ -3695,6 +3695,10 @@ func (bc *BlockChainImpl) InitTiKV(conf *harmonyconfig.TiKVConfig) { go bc.tikvCleanCache() } +func (bc *BlockChainImpl) CommitPreimages() error { + return bc.stateCache.TrieDB().CommitPreimages() +} + var ( leveldbErrSpec = "leveldb" tooManyOpenFilesErrStr = "Too many open files" diff --git a/core/blockchain_stub.go b/core/blockchain_stub.go index 5d83149a67..e6fa60fc18 100644 --- a/core/blockchain_stub.go +++ b/core/blockchain_stub.go @@ -439,3 +439,7 @@ func (a Stub) InitTiKV(conf *harmonyconfig.TiKVConfig) { 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) CommitPreimages() error { + return errors.Errorf("method CommitPreimages not implemented for %s", a.Name) +} \ No newline at end of file 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/rpc/preimages.go b/rpc/preimages.go index 941cc86272..a09f9c85b7 100644 --- a/rpc/preimages.go +++ b/rpc/preimages.go @@ -9,6 +9,8 @@ import ( ethCommon "github.com/ethereum/go-ethereum/common" "github.com/harmony-one/harmony/core" "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/eth/rpc" "github.com/harmony-one/harmony/hmy" "github.com/harmony-one/harmony/internal/utils" @@ -121,8 +123,52 @@ func ExportPreimages(chain core.BlockChain, path string) error { } func GeneratePreimages(chain core.BlockChain, start, end uint64) error { + if start < 2 { + return fmt.Errorf("too low starting point %d", start) + } // 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-- { + startingBlock = chain.GetBlockByNumber(i) + if startingBlock == nil { + // 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 + } + state, err := chain.StateAt(startingBlock.Root()) + if err == nil { + continue + } + startingState = state + break + } + if startingBlock == nil || startingState == nil { + return fmt.Errorf("no eligible starting block with state found") + } + + // now execute block T+1 based on starting state + for i := startingBlock.NumberU64() + 1; i <= end; 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) + } + _, _, _, _, _, _, endingState, err := chain.Processor().Process(block, startingState, *chain.GetVMConfig(), false) + if err == nil { + return fmt.Errorf("error executing block #%d: %s", i, err) + } + startingState = endingState + } + // force any pre-images in memory so far to go to disk, if they haven't already + if err := chain.CommitPreimages(); err != nil { + return fmt.Errorf("error committing preimages %s", err) + } return nil -} \ No newline at end of file +} From 35b0fac1e5778ed11fce42a7e211a2efa16411ec Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 26 Aug 2023 12:51:40 +0000 Subject: [PATCH 08/54] add metrics and numbers for pre-images --- cmd/harmony/main.go | 45 ++++++++++++++++++++++------------- core/rawdb/accessors_state.go | 38 +++++++++++++++++++++++++++++ core/rawdb/schema.go | 4 ++++ rpc/preimages.go | 45 ++++++++++++++++++++++++++++++++--- 4 files changed, 112 insertions(+), 20 deletions(-) diff --git a/cmd/harmony/main.go b/cmd/harmony/main.go index 904f51f4bc..f1746f4d2f 100644 --- a/cmd/harmony/main.go +++ b/cmd/harmony/main.go @@ -33,7 +33,6 @@ import ( ethCommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" "github.com/pkg/errors" @@ -50,6 +49,7 @@ import ( "github.com/harmony-one/harmony/common/ntp" "github.com/harmony-one/harmony/consensus" "github.com/harmony-one/harmony/core" + "github.com/harmony-one/harmony/core/rawdb" "github.com/harmony-one/harmony/hmy/downloader" "github.com/harmony-one/harmony/internal/cli" "github.com/harmony-one/harmony/internal/common" @@ -404,27 +404,38 @@ func setupNodeAndRun(hc harmonyconfig.HarmonyConfig) { os.Exit(1) } // this means the address is a number - if blockNumber, err := strconv.ParseInt(record[1], 10, 64); err == nil { + if blockNumber, err := strconv.ParseUint(record[1], 10, 64); err == nil { if record[0] == "MyBlockNumber" { - // export blockNumber to prometheus - gauge := prom.NewGauge( - prom.GaugeOpts{ - Namespace: "hmy", - Subsystem: "blockchain", - Name: "last_preimage_import", - Help: "the last known block for which preimages were imported", - }, - ) - prometheus.PromRegistry().MustRegister( - gauge, - ) - gauge.Set(float64(blockNumber)) + // set this value in database, and prometheus, if needed + prev, err := rawdb.ReadPreimageImportBlock(dbReader) + if err != nil { + fmt.Println("No prior value found, overwriting") + } + if blockNumber > prev { + // export blockNumber to prometheus + gauge := prom.NewGauge( + prom.GaugeOpts{ + Namespace: "hmy", + Subsystem: "blockchain", + Name: "last_preimage_import", + Help: "the last known block for which preimages were imported", + }, + ) + prometheus.PromRegistry().MustRegister( + gauge, + ) + gauge.Set(float64(blockNumber)) + if rawdb.WritePreimageImportBlock(dbReader, blockNumber) != nil { + fmt.Println("Error saving last import block", err) + os.Exit(1) + } + } // this is the last record break } } - key := ethCommon.BytesToHash([]byte(record[0])) - value := []byte(record[1]) + key := ethCommon.HexToHash(record[0]) + value := ethCommon.Hex2Bytes(record[1]) // validate if crypto.Keccak256Hash(value) != key { fmt.Println("Data mismatch: skipping", record) diff --git a/core/rawdb/accessors_state.go b/core/rawdb/accessors_state.go index 72dbe94fb6..018449a18b 100644 --- a/core/rawdb/accessors_state.go +++ b/core/rawdb/accessors_state.go @@ -147,3 +147,41 @@ 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.KeyValueWriter, start, end uint64) error { + if err1 := db.Put(preImageGenStartKey, encodeBlockNumber(start)); err1 != nil { + return err1 + } + if err2 := db.Put(preImageGenEndKey, encodeBlockNumber(end)); err2 != nil { + return err2 + } + return 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 +} \ No newline at end of file diff --git a/core/rawdb/schema.go b/core/rawdb/schema.go index 56147b51d3..cdc1fe5cf6 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/rpc/preimages.go b/rpc/preimages.go index a09f9c85b7..03ac155980 100644 --- a/rpc/preimages.go +++ b/rpc/preimages.go @@ -7,6 +7,7 @@ import ( "os" ethCommon "github.com/ethereum/go-ethereum/common" + "github.com/harmony-one/harmony/api/service/prometheus" "github.com/harmony-one/harmony/core" "github.com/harmony-one/harmony/core/rawdb" "github.com/harmony-one/harmony/core/state" @@ -14,6 +15,7 @@ import ( "github.com/harmony-one/harmony/eth/rpc" "github.com/harmony-one/harmony/hmy" "github.com/harmony-one/harmony/internal/utils" + prom "github.com/prometheus/client_golang/prometheus" ) type PreimagesService struct { @@ -97,10 +99,8 @@ func ExportPreimages(chain core.BlockChain, path string) error { address := ethCommon.BytesToAddress(preimage) // key value format, so hash of value is first csvWriter.Write([]string{ - // no 0x prefix, stored as hash fmt.Sprintf("%x", asHash.Bytes()), - // with 0x prefix, stored as bytes - address.Hex(), + fmt.Sprintf("%x", address.Bytes()), }) } } @@ -170,5 +170,44 @@ func GeneratePreimages(chain core.BlockChain, start, end uint64) error { if err := chain.CommitPreimages(); err != nil { return fmt.Errorf("error committing preimages %s", err) } + // save information about generated pre-images start and end nbs + toWrite := []uint64{0, 0} + existingStart, err := rawdb.ReadPreImageStartBlock(chain.ChainDb()) + if err != nil || existingStart > startingBlock.NumberU64() + 1 { + toWrite[0] = startingBlock.NumberU64() + 1 + } else { + toWrite[0] = existingStart + } + existingEnd, err := rawdb.ReadPreImageEndBlock(chain.ChainDb()) + if err != nil || existingEnd < end { + toWrite[1] = end + } else { + toWrite[1] = existingEnd + } + if err := rawdb.WritePreImageStartEndBlock(chain.ChainDb(), toWrite[0], toWrite[1]); err != nil { + return fmt.Errorf("error writing pre-image gen blocks %s", err) + } + // add prometheus metrics as well + startGauge := prom.NewGauge( + prom.GaugeOpts{ + Namespace: "hmy", + Subsystem: "blockchain", + Name: "preimage_start", + Help: "the first block for which pre-image generation ran locally", + }, + ) + endGauge := prom.NewGauge( + prom.GaugeOpts{ + Namespace: "hmy", + Subsystem: "blockchain", + Name: "preimage_end", + Help: "the last block for which pre-image generation ran locally", + }, + ) + prometheus.PromRegistry().MustRegister( + startGauge, endGauge, + ) + startGauge.Set(float64(toWrite[0])) + endGauge.Set(float64(toWrite[1])) return nil } From 745111ec959b5b5c2ffae12942f4d708d733cf61 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 26 Aug 2023 14:05:06 +0000 Subject: [PATCH 09/54] automate generation after import --- cmd/harmony/main.go | 17 ++++++++++ core/blockchain_impl.go | 10 ++++++ core/rawdb/accessors_state.go | 36 +++++++++++++++++---- rpc/preimages.go | 61 ++++++++++++++++++++++++++--------- 4 files changed, 102 insertions(+), 22 deletions(-) diff --git a/cmd/harmony/main.go b/cmd/harmony/main.go index f1746f4d2f..2081852a2c 100644 --- a/cmd/harmony/main.go +++ b/cmd/harmony/main.go @@ -393,6 +393,7 @@ func setupNodeAndRun(hc harmonyconfig.HarmonyConfig) { csvReader := csv.NewReader(reader) chain := currentNode.Blockchain() dbReader := chain.ChainDb() + imported := uint64(0) for { record, err := csvReader.Read() if err == io.EOF { @@ -431,6 +432,7 @@ func setupNodeAndRun(hc harmonyconfig.HarmonyConfig) { } } // this is the last record + imported = blockNumber break } } @@ -448,6 +450,21 @@ func setupNodeAndRun(hc harmonyconfig.HarmonyConfig) { }, ) } + // 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 := rpc.FindMissingRange(imported, genStart, genEnd, current) + if toGenStart != 0 && toGenEnd != 0 { + if err := rpc.GeneratePreimages( + chain, toGenStart, toGenEnd, + ); err != nil { + fmt.Println("Error generating", err) + os.Exit(1) + } + } + } os.Exit(0) } else if exportPath := hc.Preimage.ExportTo; exportPath != "" { if err := rpc.ExportPreimages( diff --git a/core/blockchain_impl.go b/core/blockchain_impl.go index b5c03150f7..bc40a36e95 100644 --- a/core/blockchain_impl.go +++ b/core/blockchain_impl.go @@ -367,6 +367,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 @@ -1209,6 +1215,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. diff --git a/core/rawdb/accessors_state.go b/core/rawdb/accessors_state.go index 018449a18b..1b5b53ec61 100644 --- a/core/rawdb/accessors_state.go +++ b/core/rawdb/accessors_state.go @@ -160,14 +160,38 @@ func ReadPreimageImportBlock(db ethdb.KeyValueReader) (uint64, error) { return decodeBlockNumber(val), nil } -func WritePreImageStartEndBlock(db ethdb.KeyValueWriter, start, end uint64) error { - if err1 := db.Put(preImageGenStartKey, encodeBlockNumber(start)); err1 != nil { - return err1 +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 err2 := db.Put(preImageGenEndKey, encodeBlockNumber(end)); err2 != nil { - return err2 + 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 nil + return returnStart, returnEnd, nil } func ReadPreImageStartBlock(db ethdb.KeyValueReader) (uint64, error) { diff --git a/rpc/preimages.go b/rpc/preimages.go index 03ac155980..1fec069d40 100644 --- a/rpc/preimages.go +++ b/rpc/preimages.go @@ -171,20 +171,9 @@ func GeneratePreimages(chain core.BlockChain, start, end uint64) error { return fmt.Errorf("error committing preimages %s", err) } // save information about generated pre-images start and end nbs - toWrite := []uint64{0, 0} - existingStart, err := rawdb.ReadPreImageStartBlock(chain.ChainDb()) - if err != nil || existingStart > startingBlock.NumberU64() + 1 { - toWrite[0] = startingBlock.NumberU64() + 1 - } else { - toWrite[0] = existingStart - } - existingEnd, err := rawdb.ReadPreImageEndBlock(chain.ChainDb()) - if err != nil || existingEnd < end { - toWrite[1] = end - } else { - toWrite[1] = existingEnd - } - if err := rawdb.WritePreImageStartEndBlock(chain.ChainDb(), toWrite[0], toWrite[1]); err != nil { + var gauge1, gauge2 uint64 + var err error + if gauge1, gauge2, err = rawdb.WritePreImageStartEndBlock(chain.ChainDb(), startingBlock.NumberU64() + 1, end); err != nil { return fmt.Errorf("error writing pre-image gen blocks %s", err) } // add prometheus metrics as well @@ -207,7 +196,47 @@ func GeneratePreimages(chain core.BlockChain, start, end uint64) error { prometheus.PromRegistry().MustRegister( startGauge, endGauge, ) - startGauge.Set(float64(toWrite[0])) - endGauge.Set(float64(toWrite[1])) + startGauge.Set(float64(gauge1)) + endGauge.Set(float64(gauge2)) 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 +} \ No newline at end of file From b9a7ba2ff83146e3540160d5d7bf49444d85eed7 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 26 Aug 2023 14:07:16 +0000 Subject: [PATCH 10/54] move from rpc to core --- cmd/harmony/main.go | 9 +- rpc/preimages.go | 215 +------------------------------------------- 2 files changed, 5 insertions(+), 219 deletions(-) diff --git a/cmd/harmony/main.go b/cmd/harmony/main.go index 2081852a2c..850fdce04e 100644 --- a/cmd/harmony/main.go +++ b/cmd/harmony/main.go @@ -23,7 +23,6 @@ import ( "github.com/harmony-one/harmony/internal/shardchain/tikv_manage" "github.com/harmony-one/harmony/internal/tikv/redis_helper" "github.com/harmony-one/harmony/internal/tikv/statedb_cache" - "github.com/harmony-one/harmony/rpc" "github.com/harmony-one/harmony/api/service/crosslink_sending" rosetta_common "github.com/harmony-one/harmony/rosetta/common" @@ -455,9 +454,9 @@ func setupNodeAndRun(hc harmonyconfig.HarmonyConfig) { genStart, _ := rawdb.ReadPreImageStartBlock(dbReader) genEnd, _ := rawdb.ReadPreImageEndBlock(dbReader) current := chain.CurrentBlock().NumberU64() - toGenStart, toGenEnd := rpc.FindMissingRange(imported, genStart, genEnd, current) + toGenStart, toGenEnd := core.FindMissingRange(imported, genStart, genEnd, current) if toGenStart != 0 && toGenEnd != 0 { - if err := rpc.GeneratePreimages( + if err := core.GeneratePreimages( chain, toGenStart, toGenEnd, ); err != nil { fmt.Println("Error generating", err) @@ -467,7 +466,7 @@ func setupNodeAndRun(hc harmonyconfig.HarmonyConfig) { } os.Exit(0) } else if exportPath := hc.Preimage.ExportTo; exportPath != "" { - if err := rpc.ExportPreimages( + if err := core.ExportPreimages( currentNode.Blockchain(), exportPath, ); err != nil { @@ -486,7 +485,7 @@ func setupNodeAndRun(hc harmonyconfig.HarmonyConfig) { ) end = number } - if err := rpc.GeneratePreimages( + if err := core.GeneratePreimages( chain, hc.Preimage.GenerateStart, end, ); err != nil { diff --git a/rpc/preimages.go b/rpc/preimages.go index 1fec069d40..672a32739e 100644 --- a/rpc/preimages.go +++ b/rpc/preimages.go @@ -2,20 +2,10 @@ package rpc import ( "context" - "encoding/csv" - "fmt" - "os" - ethCommon "github.com/ethereum/go-ethereum/common" - "github.com/harmony-one/harmony/api/service/prometheus" "github.com/harmony-one/harmony/core" - "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/eth/rpc" "github.com/harmony-one/harmony/hmy" - "github.com/harmony-one/harmony/internal/utils" - prom "github.com/prometheus/client_golang/prometheus" ) type PreimagesService struct { @@ -35,208 +25,5 @@ func NewPreimagesAPI(hmy *hmy.Harmony, version string) rpc.API { func (s *PreimagesService) Export(ctx context.Context, path string) error { // these are by default not blocking - return ExportPreimages(s.hmy.BlockChain, path) -} - -// ExportPreimages is public so `main.go` can call it directly` -func ExportPreimages(chain core.BlockChain, path string) error { - // 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() { - // 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 core.BlockChain, start, end uint64) error { - if start < 2 { - return fmt.Errorf("too low starting point %d", start) - } - // 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-- { - startingBlock = chain.GetBlockByNumber(i) - if startingBlock == nil { - // 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 - } - state, err := chain.StateAt(startingBlock.Root()) - if err == nil { - continue - } - startingState = state - break - } - if startingBlock == nil || startingState == nil { - return fmt.Errorf("no eligible starting block with state found") - } - - // now execute block T+1 based on starting state - for i := startingBlock.NumberU64() + 1; i <= end; 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) - } - _, _, _, _, _, _, endingState, err := chain.Processor().Process(block, startingState, *chain.GetVMConfig(), false) - if err == nil { - return fmt.Errorf("error executing block #%d: %s", i, err) - } - startingState = endingState - } - // force any pre-images in memory so far to go to disk, if they haven't already - if err := chain.CommitPreimages(); err != nil { - return fmt.Errorf("error committing preimages %s", err) - } - // save information about generated pre-images start and end nbs - var gauge1, gauge2 uint64 - var err error - if gauge1, gauge2, err = rawdb.WritePreImageStartEndBlock(chain.ChainDb(), startingBlock.NumberU64() + 1, end); err != nil { - return fmt.Errorf("error writing pre-image gen blocks %s", err) - } - // add prometheus metrics as well - startGauge := prom.NewGauge( - prom.GaugeOpts{ - Namespace: "hmy", - Subsystem: "blockchain", - Name: "preimage_start", - Help: "the first block for which pre-image generation ran locally", - }, - ) - endGauge := prom.NewGauge( - prom.GaugeOpts{ - Namespace: "hmy", - Subsystem: "blockchain", - Name: "preimage_end", - Help: "the last block for which pre-image generation ran locally", - }, - ) - prometheus.PromRegistry().MustRegister( - startGauge, endGauge, - ) - startGauge.Set(float64(gauge1)) - endGauge.Set(float64(gauge2)) - 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 + return core.ExportPreimages(s.hmy.BlockChain, path) } \ No newline at end of file From 350260310b900342789d2b4344d6a439eaa52397 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 26 Aug 2023 14:09:12 +0000 Subject: [PATCH 11/54] goimports --- core/blockchain_impl.go | 2 +- core/blockchain_stub.go | 2 +- core/rawdb/accessors_state.go | 2 +- core/rawdb/schema.go | 4 ++-- rpc/preimages.go | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/blockchain_impl.go b/core/blockchain_impl.go index bc40a36e95..37fa38582f 100644 --- a/core/blockchain_impl.go +++ b/core/blockchain_impl.go @@ -368,7 +368,7 @@ func newBlockChainWithOptions( } if cacheConfig.Preimages { - if _, _, err := rawdb.WritePreImageStartEndBlock(bc.ChainDb(), curHeader.NumberU64() + 1, 0); err != nil { + 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") } } diff --git a/core/blockchain_stub.go b/core/blockchain_stub.go index e6fa60fc18..9b59c9699e 100644 --- a/core/blockchain_stub.go +++ b/core/blockchain_stub.go @@ -442,4 +442,4 @@ func (a Stub) LeaderRotationMeta() (publicKeyBytes []byte, epoch, count, shifts func (a Stub) CommitPreimages() error { return errors.Errorf("method CommitPreimages not implemented for %s", a.Name) -} \ No newline at end of file +} diff --git a/core/rawdb/accessors_state.go b/core/rawdb/accessors_state.go index 1b5b53ec61..81adabbfd5 100644 --- a/core/rawdb/accessors_state.go +++ b/core/rawdb/accessors_state.go @@ -208,4 +208,4 @@ func ReadPreImageEndBlock(db ethdb.KeyValueReader) (uint64, error) { return 0, err } return decodeBlockNumber(val), nil -} \ No newline at end of file +} diff --git a/core/rawdb/schema.go b/core/rawdb/schema.go index cdc1fe5cf6..8251766ef2 100644 --- a/core/rawdb/schema.go +++ b/core/rawdb/schema.go @@ -149,9 +149,9 @@ var ( CliqueSnapshotPrefix = []byte("clique-") - preImageImportKey = []byte("preimage-import") + preImageImportKey = []byte("preimage-import") preImageGenStartKey = []byte("preimage-gen-start") - preImageGenEndKey = []byte("preimage-gen-end") + preImageGenEndKey = []byte("preimage-gen-end") ) // LegacyTxLookupEntry is the legacy TxLookupEntry definition with some unnecessary diff --git a/rpc/preimages.go b/rpc/preimages.go index 672a32739e..d0ab56f387 100644 --- a/rpc/preimages.go +++ b/rpc/preimages.go @@ -26,4 +26,4 @@ func NewPreimagesAPI(hmy *hmy.Harmony, version string) rpc.API { func (s *PreimagesService) Export(ctx context.Context, path string) error { // these are by default not blocking return core.ExportPreimages(s.hmy.BlockChain, path) -} \ No newline at end of file +} From 78f50b1940240a4ed806fefeabb83cf2262e44b4 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 26 Aug 2023 14:18:32 +0000 Subject: [PATCH 12/54] add back core/preimages.go file --- core/preimages.go | 218 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 core/preimages.go diff --git a/core/preimages.go b/core/preimages.go new file mode 100644 index 0000000000..69e03daee6 --- /dev/null +++ b/core/preimages.go @@ -0,0 +1,218 @@ +package core + +import ( + "encoding/csv" + "fmt" + "os" + + ethCommon "github.com/ethereum/go-ethereum/common" + "github.com/harmony-one/harmony/api/service/prometheus" + "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" + prom "github.com/prometheus/client_golang/prometheus" +) + +// ExportPreimages is public so `main.go` can call it directly` +func ExportPreimages(chain BlockChain, path string) error { + // 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() { + // 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) + } + // 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-- { + startingBlock = chain.GetBlockByNumber(i) + if startingBlock == nil { + // 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 + } + state, err := chain.StateAt(startingBlock.Root()) + if err == nil { + continue + } + startingState = state + break + } + if startingBlock == nil || startingState == nil { + return fmt.Errorf("no eligible starting block with state found") + } + + // now execute block T+1 based on starting state + for i := startingBlock.NumberU64() + 1; i <= end; 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) + } + _, _, _, _, _, _, endingState, err := chain.Processor().Process(block, startingState, *chain.GetVMConfig(), false) + if err == nil { + return fmt.Errorf("error executing block #%d: %s", i, err) + } + startingState = endingState + } + // force any pre-images in memory so far to go to disk, if they haven't already + if err := chain.CommitPreimages(); err != nil { + return fmt.Errorf("error committing preimages %s", err) + } + // save information about generated pre-images start and end nbs + var gauge1, gauge2 uint64 + var err error + if gauge1, gauge2, err = rawdb.WritePreImageStartEndBlock(chain.ChainDb(), startingBlock.NumberU64() + 1, end); err != nil { + return fmt.Errorf("error writing pre-image gen blocks %s", err) + } + // add prometheus metrics as well + startGauge := prom.NewGauge( + prom.GaugeOpts{ + Namespace: "hmy", + Subsystem: "blockchain", + Name: "preimage_start", + Help: "the first block for which pre-image generation ran locally", + }, + ) + endGauge := prom.NewGauge( + prom.GaugeOpts{ + Namespace: "hmy", + Subsystem: "blockchain", + Name: "preimage_end", + Help: "the last block for which pre-image generation ran locally", + }, + ) + prometheus.PromRegistry().MustRegister( + startGauge, endGauge, + ) + startGauge.Set(float64(gauge1)) + endGauge.Set(float64(gauge2)) + 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 +} \ No newline at end of file From d1a77766a27e9ca471cb9fec878f553cf3f45291 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 26 Aug 2023 14:24:07 +0000 Subject: [PATCH 13/54] HIP-30: sharding configuration boilerplate --- cmd/harmony/main.go | 8 +- internal/configs/sharding/instance.go | 34 +- internal/configs/sharding/localnet.go | 53 ++- internal/configs/sharding/mainnet.go | 167 +++++++- internal/configs/sharding/pangaea.go | 15 +- internal/configs/sharding/partner.go | 33 +- internal/configs/sharding/shardingconfig.go | 9 + internal/configs/sharding/stress.go | 25 +- internal/configs/sharding/testnet.go | 41 +- internal/genesis/harmony.go | 408 ++++++++++++++++++++ internal/params/config.go | 45 +++ 11 files changed, 795 insertions(+), 43 deletions(-) diff --git a/cmd/harmony/main.go b/cmd/harmony/main.go index 16f985beac..b70c41ec86 100644 --- a/cmd/harmony/main.go +++ b/cmd/harmony/main.go @@ -500,7 +500,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) diff --git a/internal/configs/sharding/instance.go b/internal/configs/sharding/instance.go index 90076e595b..296a4fe5cd 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,12 @@ func NewInstance( ) } } + if emissionFractionToRecovery.LT(numeric.ZeroDec()) || + emissionFractionToRecovery.GT(numeric.OneDec()) { + return nil, errors.Errorf( + "emission split must be within [0, 1]", + ) + } return instance{ numShards: numShards, @@ -108,6 +122,8 @@ func NewInstance( blocksPerEpoch: blocksE, slotsLimit: slotsLimit, feeCollectors: feeCollectors, + recoveryAddress: recoveryAddress, + emissionFraction: emissionFractionToRecovery, }, nil } @@ -122,12 +138,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 +243,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..06afba1a01 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" @@ -156,10 +157,50 @@ 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(), + ) ) diff --git a/internal/configs/sharding/mainnet.go b/internal/configs/sharding/mainnet.go index fb6b0f13bc..20502e14d6 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"), } + + hip30CollectionAddress = ethCommon.Address{} + // hip30CollectionAddress = mustAddress("0xMustAddress") ) 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..7514656d32 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" @@ -92,7 +93,31 @@ 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[0], numeric.ZeroDec(), ethCommon.Address{}, + partnerReshardingEpoch, PartnerSchedule.BlocksPerEpoch(), +) +var partnerV3 = MustNewInstance( + 2, 5, 4, 0, + numeric.MustNewDecFromStr("0.9"), genesis.TNHarmonyAccounts, + genesis.TNFoundationalAccounts, emptyAllowlist, + feeCollectorsDevnet[1], numeric.ZeroDec(), ethCommon.Address{}, + 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..da0143ef93 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" @@ -121,9 +122,39 @@ 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(), + ) ) 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..ace39224ff 100644 --- a/internal/params/config.go +++ b/internal/params/config.go @@ -73,6 +73,7 @@ var ( 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 + HIP30Epoch: EpochTBD, } // TestnetChainConfig contains the chain parameters to run a node on the harmony test network. @@ -114,6 +115,7 @@ var ( 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 + HIP30Epoch: EpochTBD, } // PangaeaChainConfig contains the chain parameters for the Pangaea network. // All features except for CrossLink are enabled at launch. @@ -155,6 +157,7 @@ var ( LeaderRotationExternalBeaconLeaders: EpochTBD, FeeCollectEpoch: EpochTBD, ValidatorCodeFixEpoch: EpochTBD, + HIP30Epoch: EpochTBD, } // PartnerChainConfig contains the chain parameters for the Partner network. @@ -197,6 +200,7 @@ var ( LeaderRotationExternalBeaconLeaders: EpochTBD, FeeCollectEpoch: big.NewInt(848), // 2023-04-28 04:33:33+00:00 ValidatorCodeFixEpoch: big.NewInt(848), + HIP30Epoch: EpochTBD, } // StressnetChainConfig contains the chain parameters for the Stress test network. @@ -239,6 +243,7 @@ var ( LeaderRotationExternalNonBeaconLeaders: EpochTBD, LeaderRotationExternalBeaconLeaders: EpochTBD, ValidatorCodeFixEpoch: EpochTBD, + HIP30Epoch: EpochTBD, } // LocalnetChainConfig contains the chain parameters to run for local development. @@ -280,6 +285,7 @@ var ( LeaderRotationExternalBeaconLeaders: big.NewInt(6), FeeCollectEpoch: big.NewInt(2), ValidatorCodeFixEpoch: big.NewInt(2), + HIP30Epoch: EpochTBD, } // AllProtocolChanges ... @@ -323,6 +329,7 @@ var ( big.NewInt(1), // LeaderRotationExternalBeaconLeaders big.NewInt(0), // FeeCollectEpoch big.NewInt(0), // ValidatorCodeFixEpoch + big.NewInt(0), // HIP30Epoch } // TestChainConfig ... @@ -366,6 +373,7 @@ var ( big.NewInt(1), // LeaderRotationExternalBeaconLeaders big.NewInt(0), // FeeCollectEpoch big.NewInt(0), // ValidatorCodeFixEpoch + big.NewInt(0), // HIP30Epoch } // TestRules ... @@ -522,6 +530,13 @@ 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"` } // String implements the fmt.Stringer interface. @@ -548,6 +563,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 +586,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. @@ -756,6 +791,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) +} + +// Towards the end of this epoch, shards 2 and 3 will start sending +// their balances over to shard 1. +func (c *ChainConfig) IsEpochBeforeHIP30(epoch *big.Int) bool { + return isForked(new(big.Int).Sub(c.HIP30Epoch, common.Big1), epoch) +} + // UpdateEthChainIDByShard update the ethChainID based on shard ID. func UpdateEthChainIDByShard(shardID uint32) { once.Do(func() { From c18d6c46f9e697ea08804b9b41c0803a0e36e16f Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 26 Aug 2023 14:24:28 +0000 Subject: [PATCH 14/54] update comments --- core/state/statedb.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) 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") From 672697431461799519cdf286e0445a6da0b88230 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 26 Aug 2023 14:57:48 +0000 Subject: [PATCH 15/54] goimports --- internal/configs/sharding/instance.go | 8 ++++---- internal/configs/sharding/localnet.go | 8 ++++---- internal/configs/sharding/mainnet.go | 6 +++--- internal/params/config.go | 16 ++++++++-------- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/internal/configs/sharding/instance.go b/internal/configs/sharding/instance.go index 296a4fe5cd..1bcd79a34f 100644 --- a/internal/configs/sharding/instance.go +++ b/internal/configs/sharding/instance.go @@ -37,8 +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 + emissionFraction numeric.Dec + recoveryAddress ethCommon.Address } type FeeCollectors map[ethCommon.Address]numeric.Dec @@ -122,8 +122,8 @@ func NewInstance( blocksPerEpoch: blocksE, slotsLimit: slotsLimit, feeCollectors: feeCollectors, - recoveryAddress: recoveryAddress, - emissionFraction: emissionFractionToRecovery, + recoveryAddress: recoveryAddress, + emissionFraction: emissionFractionToRecovery, }, nil } diff --git a/internal/configs/sharding/localnet.go b/internal/configs/sharding/localnet.go index 06afba1a01..ebb494196b 100644 --- a/internal/configs/sharding/localnet.go +++ b/internal/configs/sharding/localnet.go @@ -157,21 +157,21 @@ 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( + localnetV0 = MustNewInstance( 2, 7, 5, 0, numeric.OneDec(), genesis.LocalHarmonyAccounts, genesis.LocalFnAccounts, emptyAllowlist, nil, numeric.ZeroDec(), ethCommon.Address{}, localnetReshardingEpoch, LocalnetSchedule.BlocksPerEpochOld(), ) - localnetV1 = MustNewInstance( + localnetV1 = MustNewInstance( 2, 8, 5, 0, numeric.OneDec(), genesis.LocalHarmonyAccountsV1, genesis.LocalFnAccountsV1, emptyAllowlist, nil, numeric.ZeroDec(), ethCommon.Address{}, localnetReshardingEpoch, LocalnetSchedule.BlocksPerEpochOld(), ) - localnetV2 = MustNewInstance( + localnetV2 = MustNewInstance( 2, 9, 6, 0, numeric.MustNewDecFromStr("0.68"), genesis.LocalHarmonyAccountsV2, genesis.LocalFnAccountsV2, @@ -179,7 +179,7 @@ var ( numeric.ZeroDec(), ethCommon.Address{}, localnetReshardingEpoch, LocalnetSchedule.BlocksPerEpochOld(), ) - localnetV3 = MustNewInstance( + localnetV3 = MustNewInstance( 2, 9, 6, 0, numeric.MustNewDecFromStr("0.68"), genesis.LocalHarmonyAccountsV2, genesis.LocalFnAccountsV2, diff --git a/internal/configs/sharding/mainnet.go b/internal/configs/sharding/mainnet.go index 20502e14d6..e395912e05 100644 --- a/internal/configs/sharding/mainnet.go +++ b/internal/configs/sharding/mainnet.go @@ -228,7 +228,7 @@ 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( + mainnetV0 = MustNewInstance( 4, 150, 112, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccounts, emptyAllowlist, nil, @@ -263,7 +263,7 @@ var ( numeric.ZeroDec(), ethCommon.Address{}, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld(), ) - mainnetV1 = MustNewInstance( + mainnetV1 = MustNewInstance( 4, 250, 170, 0, numeric.OneDec(), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1, emptyAllowlist, nil, @@ -326,7 +326,7 @@ var ( numeric.ZeroDec(), ethCommon.Address{}, mainnetReshardingEpoch, MainnetSchedule.BlocksPerEpochOld(), ) - mainnetV3 = MustNewInstance( + mainnetV3 = MustNewInstance( 4, 250, 90, 0, numeric.MustNewDecFromStr("0.68"), genesis.HarmonyAccounts, genesis.FoundationalNodeAccountsV1_5, emptyAllowlist, nil, diff --git a/internal/params/config.go b/internal/params/config.go index ace39224ff..0deee9a1cc 100644 --- a/internal/params/config.go +++ b/internal/params/config.go @@ -73,7 +73,7 @@ var ( 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 - HIP30Epoch: EpochTBD, + HIP30Epoch: EpochTBD, } // TestnetChainConfig contains the chain parameters to run a node on the harmony test network. @@ -115,7 +115,7 @@ var ( 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 - HIP30Epoch: EpochTBD, + HIP30Epoch: EpochTBD, } // PangaeaChainConfig contains the chain parameters for the Pangaea network. // All features except for CrossLink are enabled at launch. @@ -157,7 +157,7 @@ var ( LeaderRotationExternalBeaconLeaders: EpochTBD, FeeCollectEpoch: EpochTBD, ValidatorCodeFixEpoch: EpochTBD, - HIP30Epoch: EpochTBD, + HIP30Epoch: EpochTBD, } // PartnerChainConfig contains the chain parameters for the Partner network. @@ -200,7 +200,7 @@ var ( LeaderRotationExternalBeaconLeaders: EpochTBD, FeeCollectEpoch: big.NewInt(848), // 2023-04-28 04:33:33+00:00 ValidatorCodeFixEpoch: big.NewInt(848), - HIP30Epoch: EpochTBD, + HIP30Epoch: EpochTBD, } // StressnetChainConfig contains the chain parameters for the Stress test network. @@ -243,7 +243,7 @@ var ( LeaderRotationExternalNonBeaconLeaders: EpochTBD, LeaderRotationExternalBeaconLeaders: EpochTBD, ValidatorCodeFixEpoch: EpochTBD, - HIP30Epoch: EpochTBD, + HIP30Epoch: EpochTBD, } // LocalnetChainConfig contains the chain parameters to run for local development. @@ -285,7 +285,7 @@ var ( LeaderRotationExternalBeaconLeaders: big.NewInt(6), FeeCollectEpoch: big.NewInt(2), ValidatorCodeFixEpoch: big.NewInt(2), - HIP30Epoch: EpochTBD, + HIP30Epoch: EpochTBD, } // AllProtocolChanges ... @@ -329,7 +329,7 @@ var ( big.NewInt(1), // LeaderRotationExternalBeaconLeaders big.NewInt(0), // FeeCollectEpoch big.NewInt(0), // ValidatorCodeFixEpoch - big.NewInt(0), // HIP30Epoch + big.NewInt(0), // HIP30Epoch } // TestChainConfig ... @@ -373,7 +373,7 @@ var ( big.NewInt(1), // LeaderRotationExternalBeaconLeaders big.NewInt(0), // FeeCollectEpoch big.NewInt(0), // ValidatorCodeFixEpoch - big.NewInt(0), // HIP30Epoch + big.NewInt(0), // HIP30Epoch } // TestRules ... From d7bd483677a3801767c7bace1ce4c439daa8ef0d Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 26 Aug 2023 15:00:55 +0000 Subject: [PATCH 16/54] HIP-30: minimum validator commission of 7% Based on #4495, which must be merged before this PR. This PR should be rebased with dev after #4495 is merged to retain atomicity of changes by pull request. --- core/staking_verifier.go | 13 ++++++++-- core/state_transition.go | 2 +- internal/chain/engine.go | 46 +++++++++++++++++++++++++++------ staking/availability/measure.go | 42 ++++++++++++++++++++++-------- 4 files changed, 81 insertions(+), 22 deletions(-) diff --git a/core/staking_verifier.go b/core/staking_verifier.go index 541d26f4e6..e854eba6d1 100644 --- a/core/staking_verifier.go +++ b/core/staking_verifier.go @@ -171,11 +171,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/state_transition.go b/core/state_transition.go index 9684812cbb..93e7f2322d 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") diff --git a/internal/chain/engine.go b/internal/chain/engine.go index 71bb0d3052..18096c157f 100644 --- a/internal/chain/engine.go +++ b/internal/chain/engine.go @@ -7,6 +7,7 @@ import ( "time" "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 +286,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") @@ -390,12 +391,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 +417,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/staking/availability/measure.go b/staking/availability/measure.go index 680092aa0d..7fc5efbf6f 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 } From 41e911a9ac65c63e42dc74a1901ec7ca6330044d Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 26 Aug 2023 15:04:44 +0000 Subject: [PATCH 17/54] goimports --- core/staking_verifier.go | 10 +++++----- staking/availability/measure.go | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/staking_verifier.go b/core/staking_verifier.go index e854eba6d1..7de6cdd39f 100644 --- a/core/staking_verifier.go +++ b/core/staking_verifier.go @@ -180,11 +180,11 @@ func VerifyAndEditValidatorFromMsg( promoPeriod := chainContext.Config().MinCommissionPromoPeriod.Int64() if firstEpoch.Uint64() != 0 && big.NewInt(0).Sub(epoch, firstEpoch).Int64() >= promoPeriod { return nil, - errors.Errorf( - "%s %d%%", - errCommissionRateChangeTooLowT, - minRate.MulInt64(100).Int64(), - ) + errors.Errorf( + "%s %d%%", + errCommissionRateChangeTooLowT, + minRate.MulInt64(100).Int64(), + ) } } diff --git a/staking/availability/measure.go b/staking/availability/measure.go index 7fc5efbf6f..881baa8553 100644 --- a/staking/availability/measure.go +++ b/staking/availability/measure.go @@ -254,7 +254,7 @@ func UpdateMinimumCommissionFee( // this can take decades of time without overflowing first := firstElectionEpoch.Uint64() election := electionEpoch.Uint64() - if first != 0 && election - first >= promoPeriod && election >= first { + if first != 0 && election-first >= promoPeriod && election >= first { if wrapper.Rate.LT(minRate) { utils.Logger().Info(). Str("addr", addr.Hex()). From a5f41ae15988a959314585364dd609c3dd279b6e Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 26 Aug 2023 15:13:31 +0000 Subject: [PATCH 18/54] HIP-30: Emission split implementation Note that the allocated split of the emission goes directly to the recipient (and not via the Reward). This is because rewards are indexed by validator and not by delegator, and the recipient may/may not have any delegations which we can reward. Even if one was guaranteed to exist, it would mess up the math of the validator. --- internal/chain/engine.go | 20 +++++++++- internal/chain/reward.go | 79 ++++++++++++++++++++++------------------ 2 files changed, 63 insertions(+), 36 deletions(-) diff --git a/internal/chain/engine.go b/internal/chain/engine.go index 18096c157f..4f3aac9ff4 100644 --- a/internal/chain/engine.go +++ b/internal/chain/engine.go @@ -6,6 +6,7 @@ import ( "sort" "time" + "github.com/harmony-one/harmony/common/denominations" "github.com/harmony-one/harmony/internal/params" "github.com/harmony-one/harmony/numeric" @@ -312,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 { @@ -332,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 diff --git a/internal/chain/reward.go b/internal/chain/reward.go index f06556412f..7843380933 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. @@ -240,14 +240,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 +258,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 +275,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 +300,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 +340,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 +355,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 +394,29 @@ 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( + return remainingReward, 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 +426,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 +436,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 +470,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 +496,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 +514,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 +537,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 +546,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 +560,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 } From e99fb7e08b668e1f890e7cd2f95355003bc6920e Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 26 Aug 2023 15:16:26 +0000 Subject: [PATCH 19/54] set up mainnet recipient of emission split --- internal/configs/sharding/mainnet.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/configs/sharding/mainnet.go b/internal/configs/sharding/mainnet.go index e395912e05..d5cee1a9b5 100644 --- a/internal/configs/sharding/mainnet.go +++ b/internal/configs/sharding/mainnet.go @@ -54,7 +54,7 @@ var ( mustAddress("0xbdFeE8587d347Cd8df002E6154763325265Fa84c"): numeric.MustNewDecFromStr("0.5"), } - hip30CollectionAddress = ethCommon.Address{} + hip30CollectionAddress = mustAddress("0xD8194284df879f465ed61DBA6fa8300940cacEA3") // hip30CollectionAddress = mustAddress("0xMustAddress") ) From ceda5434d7e37b2fb63c92345e50d672b5bb3e76 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 26 Aug 2023 15:27:57 +0000 Subject: [PATCH 20/54] HIP-30: Emission split addresses for non mainnet --- internal/configs/sharding/instance.go | 14 ++++++++++++++ internal/configs/sharding/localnet.go | 12 ++++++++++++ internal/configs/sharding/partner.go | 10 ++++++++++ internal/configs/sharding/testnet.go | 12 ++++++++++++ 4 files changed, 48 insertions(+) diff --git a/internal/configs/sharding/instance.go b/internal/configs/sharding/instance.go index 1bcd79a34f..0930c20b05 100644 --- a/internal/configs/sharding/instance.go +++ b/internal/configs/sharding/instance.go @@ -108,6 +108,20 @@ func NewInstance( "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, diff --git a/internal/configs/sharding/localnet.go b/internal/configs/sharding/localnet.go index ebb494196b..fb6050b1de 100644 --- a/internal/configs/sharding/localnet.go +++ b/internal/configs/sharding/localnet.go @@ -22,6 +22,9 @@ var feeCollectorsLocalnet = FeeCollectors{ mustAddress("0x1563915e194D8CfBA1943570603F7606A3115508"): numeric.MustNewDecFromStr("0.5"), } +// pk: 0x3333333333333333333333333333333333333333333333333333333333333333 +var hip30CollectionAddressLocalnet = mustAddress("0x5CbDd86a2FA8Dc4bDdd8a8f69dBa48572EeC07FB") + type localnetSchedule struct{} const ( @@ -36,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): @@ -203,4 +208,11 @@ var ( 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/partner.go b/internal/configs/sharding/partner.go index 7514656d32..2730726e0a 100644 --- a/internal/configs/sharding/partner.go +++ b/internal/configs/sharding/partner.go @@ -42,6 +42,8 @@ const ( func (ps partnerSchedule) InstanceForEpoch(epoch *big.Int) Instance { switch { + case params.PartnerChainConfig.IsHIP30(epoch): + return partnerV4 case params.PartnerChainConfig.IsFeeCollectEpoch(epoch): return partnerV3 case epoch.Cmp(feeCollectEpochV1) >= 0: @@ -121,3 +123,11 @@ var partnerV3 = MustNewInstance( feeCollectorsDevnet[1], numeric.ZeroDec(), ethCommon.Address{}, partnerReshardingEpoch, PartnerSchedule.BlocksPerEpoch(), ) +var partnerV4 = 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/testnet.go b/internal/configs/sharding/testnet.go index da0143ef93..7c2994071c 100644 --- a/internal/configs/sharding/testnet.go +++ b/internal/configs/sharding/testnet.go @@ -21,6 +21,8 @@ var feeCollectorsTestnet = FeeCollectors{ mustAddress("0xb41B6B8d9e68fD44caC8342BC2EEf4D59531d7d7"): numeric.MustNewDecFromStr("0.5"), } +var hip30CollectionAddressTestnet = mustAddress("0x58dB8BeCe892F343350D125ff22B242784a8BA38") + type testnetSchedule struct{} const ( @@ -40,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: @@ -157,4 +161,12 @@ var ( 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(), + ) ) From 4b78692306052d5b2d2f49098c6847998f84b27b Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 26 Aug 2023 15:33:23 +0000 Subject: [PATCH 21/54] HIP-30: deactivate shard 2 and 3 validators --- core/state_processor.go | 22 +++++++++++++++++----- node/node_newblock.go | 2 +- node/worker/worker.go | 6 +++--- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/core/state_processor.go b/core/state_processor.go index 7a2f2a5d47..a79a966b53 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -185,7 +185,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 } @@ -442,13 +442,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 +482,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 diff --git a/node/node_newblock.go b/node/node_newblock.go index 008182fbcc..97f5f7bc8b 100644 --- a/node/node_newblock.go +++ b/node/node_newblock.go @@ -265,7 +265,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( diff --git a/node/worker/worker.go b/node/worker/worker.go index 5a4234229a..845ce265a3 100644 --- a/node/worker/worker.go +++ b/node/worker/worker.go @@ -224,9 +224,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 ( From 157f5df5d2c733e15457cc14b97e2514bc11249f Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 26 Aug 2023 15:39:14 +0000 Subject: [PATCH 22/54] goimports --- core/preimages.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/preimages.go b/core/preimages.go index 69e03daee6..88d3dc40b8 100644 --- a/core/preimages.go +++ b/core/preimages.go @@ -128,7 +128,7 @@ func GeneratePreimages(chain BlockChain, start, end uint64) error { if startingBlock == nil || startingState == nil { return fmt.Errorf("no eligible starting block with state found") } - + // now execute block T+1 based on starting state for i := startingBlock.NumberU64() + 1; i <= end; i++ { block := chain.GetBlockByNumber(i) @@ -149,7 +149,7 @@ func GeneratePreimages(chain BlockChain, start, end uint64) error { // save information about generated pre-images start and end nbs var gauge1, gauge2 uint64 var err error - if gauge1, gauge2, err = rawdb.WritePreImageStartEndBlock(chain.ChainDb(), startingBlock.NumberU64() + 1, end); err != nil { + if gauge1, gauge2, err = rawdb.WritePreImageStartEndBlock(chain.ChainDb(), startingBlock.NumberU64()+1, end); err != nil { return fmt.Errorf("error writing pre-image gen blocks %s", err) } // add prometheus metrics as well @@ -215,4 +215,4 @@ func FindMissingRange( return 0, 0 } return 0, 0 -} \ No newline at end of file +} From c3ca02f148af84ecc3c4c3ffa7a1daadb2ab7ad3 Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 26 Aug 2023 15:45:51 +0000 Subject: [PATCH 23/54] update test --- consensus/quorum/quorom_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/consensus/quorum/quorom_test.go b/consensus/quorum/quorom_test.go index 09ec1779b8..a004941e16 100644 --- a/consensus/quorum/quorom_test.go +++ b/consensus/quorum/quorom_test.go @@ -565,7 +565,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++ { From 72e035aeafb645196484ce912551520e6c94535f Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 26 Aug 2023 16:50:20 +0000 Subject: [PATCH 24/54] goimports --- internal/cli/flag.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/cli/flag.go b/internal/cli/flag.go index 075dbe5aa2..7d3a93c3d3 100644 --- a/internal/cli/flag.go +++ b/internal/cli/flag.go @@ -71,7 +71,7 @@ type Int64Flag struct { Usage string Deprecated string Hidden bool - DefValue int64 + DefValue int64 } // RegisterTo register the int flag to FlagSet From 676a4b1096983c94a61347946769a7279552b28a Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 26 Aug 2023 17:27:27 +0000 Subject: [PATCH 25/54] migrate balance uring epoch T - 1 highly untested code. also missing is the ability to generate a pre-migration report for future verification. --- core/state_processor.go | 242 +++++++++++++++++++++++++---- internal/params/protocol_params.go | 2 + node/node.go | 33 +++- node/node_newblock.go | 8 +- node/worker/worker.go | 32 ++++ 5 files changed, 279 insertions(+), 38 deletions(-) diff --git a/core/state_processor.go b/core/state_processor.go index a79a966b53..0a581d2cf3 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -17,6 +17,8 @@ package core import ( + "encoding/binary" + "fmt" "math/big" "time" @@ -28,6 +30,7 @@ import ( "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 +44,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 ) @@ -128,43 +136,63 @@ 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, p.config, + ) + if err != nil { + if err == ErrNoMigrationPossible { + // ran out of accounts + processTxsAndStxs = false + } + if err != ErrNoMigrationRequired { 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.config, 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...) } - receipts = append(receipts, receipt) - 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 + } + 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() { @@ -500,3 +528,159 @@ func MayShardReduction(bc ChainContext, statedb *state.DB, header *block.Header) statedb.IntermediateRoot(bc.Config().IsS3(header.Epoch())) return nil } + +func MayBalanceMigration( + gasPool *GasPool, + header *block.Header, + db *state.DB, + chain BlockChain, + config *params.ChainConfig, +) (*types.CXReceipt, error) { + isMainnet := nodeconfig.GetDefaultConfig().GetNetworkType() == nodeconfig.Mainnet + if isMainnet { + if config.IsEpochBeforeHIP30(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 devnet + isDevnet := nodeconfig.GetDefaultConfig().GetNetworkType() == nodeconfig.Devnet + if isDevnet { + if config.IsEpochBeforeHIP30(header.Epoch()) { + if myShard := chain.ShardID(); myShard != shard.BeaconChainShardID { + parentRoot := chain.GetBlockByHash( + header.ParentHash(), + ).Root() // for examining MPT at this root, should exist + cx, err := generateOneMigrationMessage( + db, parentRoot, + header.NumberU64(), + myShard, shard.BeaconChainShardID, // dstShard + ) + if err != nil { + return nil, err + } + if cx != nil { + gasPool.SubGas(params.TxGasXShard) + return cx, nil + } + return nil, ErrNoMigrationPossible + } + } + } + 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/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/node/node.go b/node/node.go index 06aecb94d9..5d9e77763a 100644 --- a/node/node.go +++ b/node/node.go @@ -255,21 +255,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().IsEpochBeforeHIP30(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)...) diff --git a/node/node_newblock.go b/node/node_newblock.go index 97f5f7bc8b..2c4138cd2f 100644 --- a/node/node_newblock.go +++ b/node/node_newblock.go @@ -200,7 +200,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 { diff --git a/node/worker/worker.go b/node/worker/worker.go index 845ce265a3..77c3361bac 100644 --- a/node/worker/worker.go +++ b/node/worker/worker.go @@ -150,6 +150,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.beacon.CurrentHeader(), + w.current.state, + w.chain, + w.chain.Config(), + ) + if err != nil { + if err == core.ErrNoMigrationPossible { + // means we do not accept transactions from the network + return nil + } + if 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) From f0cfd8377a76e0858c5ba1977725e7f055e4a97e Mon Sep 17 00:00:00 2001 From: MaxMustermann2 <82761650+MaxMustermann2@users.noreply.github.com> Date: Sat, 26 Aug 2023 17:48:10 +0000 Subject: [PATCH 26/54] update test --- core/staking_verifier_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/staking_verifier_test.go b/core/staking_verifier_test.go index 01d24cc8d4..1a33f9848e 100644 --- a/core/staking_verifier_test.go +++ b/core/staking_verifier_test.go @@ -676,7 +676,7 @@ func TestVerifyAndEditValidatorFromMsg(t *testing.T) { return msg }(), - expErr: errCommissionRateChangeTooLow, + expErr: errCommissionRateChangeTooLowT, }, { // 15: Rate is ok within the promo period From b18118fcf1b5e23e244716464a430590610898db Mon Sep 17 00:00:00 2001 From: "Nita Neou (Soph)" Date: Mon, 4 Sep 2023 16:10:05 +0700 Subject: [PATCH 27/54] export prometheus metric when no error importing preimage --- cmd/harmony/main.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/harmony/main.go b/cmd/harmony/main.go index 850fdce04e..5544412da1 100644 --- a/cmd/harmony/main.go +++ b/cmd/harmony/main.go @@ -412,6 +412,10 @@ func setupNodeAndRun(hc harmonyconfig.HarmonyConfig) { fmt.Println("No prior value found, overwriting") } if blockNumber > prev { + if rawdb.WritePreimageImportBlock(dbReader, blockNumber) != nil { + fmt.Println("Error saving last import block", err) + os.Exit(1) + } // export blockNumber to prometheus gauge := prom.NewGauge( prom.GaugeOpts{ @@ -425,10 +429,6 @@ func setupNodeAndRun(hc harmonyconfig.HarmonyConfig) { gauge, ) gauge.Set(float64(blockNumber)) - if rawdb.WritePreimageImportBlock(dbReader, blockNumber) != nil { - fmt.Println("Error saving last import block", err) - os.Exit(1) - } } // this is the last record imported = blockNumber From db7c246b1dfd0d8064de8f9d12d020dfd4f53a45 Mon Sep 17 00:00:00 2001 From: "Nita Neou (Soph)" Date: Tue, 5 Sep 2023 13:20:17 +0700 Subject: [PATCH 28/54] add comment --- internal/params/config.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/params/config.go b/internal/params/config.go index 0deee9a1cc..acfe3921d4 100644 --- a/internal/params/config.go +++ b/internal/params/config.go @@ -795,8 +795,8 @@ func (c *ChainConfig) IsHIP30(epoch *big.Int) bool { return isForked(c.HIP30Epoch, epoch) } -// Towards the end of this epoch, shards 2 and 3 will start sending -// their balances over to shard 1. +// At this epoch, shards 2 and 3 will start sending +// their balances over to shard 0 or 1. func (c *ChainConfig) IsEpochBeforeHIP30(epoch *big.Int) bool { return isForked(new(big.Int).Sub(c.HIP30Epoch, common.Big1), epoch) } From 486543cf7bdfb4f191faef9377e4e088f6552c56 Mon Sep 17 00:00:00 2001 From: "Nita Neou (Soph)" Date: Tue, 5 Sep 2023 14:39:35 +0700 Subject: [PATCH 29/54] test account migration in localnet --- core/state_processor.go | 4 +++- internal/params/config.go | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/core/state_processor.go b/core/state_processor.go index 0a581d2cf3..43f2bf8692 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -572,7 +572,8 @@ func MayBalanceMigration( } // for testing balance migration on devnet isDevnet := nodeconfig.GetDefaultConfig().GetNetworkType() == nodeconfig.Devnet - if isDevnet { + isLocalnet := nodeconfig.GetDefaultConfig().GetNetworkType() == nodeconfig.Localnet + if isDevnet || isLocalnet { if config.IsEpochBeforeHIP30(header.Epoch()) { if myShard := chain.ShardID(); myShard != shard.BeaconChainShardID { parentRoot := chain.GetBlockByHash( @@ -594,6 +595,7 @@ func MayBalanceMigration( } } } + return nil, ErrNoMigrationRequired } diff --git a/internal/params/config.go b/internal/params/config.go index 4a0715a479..5d2053ce82 100644 --- a/internal/params/config.go +++ b/internal/params/config.go @@ -285,7 +285,7 @@ var ( LeaderRotationExternalBeaconLeaders: big.NewInt(6), FeeCollectEpoch: big.NewInt(2), ValidatorCodeFixEpoch: big.NewInt(2), - HIP30Epoch: EpochTBD, + HIP30Epoch: big.NewInt(3), } // AllProtocolChanges ... From 80715ae34d0fc32718c6d8a03d52f98a83a1a72f Mon Sep 17 00:00:00 2001 From: "Nita Neou (Soph)" Date: Thu, 7 Sep 2023 14:45:22 +0700 Subject: [PATCH 30/54] add preimages flags to rootflags --- cmd/harmony/flags.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/harmony/flags.go b/cmd/harmony/flags.go index 779d50baf7..46a1decb06 100644 --- a/cmd/harmony/flags.go +++ b/cmd/harmony/flags.go @@ -378,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...) From dddaa0f710a52efbd345b43d199a4fb84a3aad9b Mon Sep 17 00:00:00 2001 From: Diego Nava Date: Fri, 8 Sep 2023 18:40:15 +0100 Subject: [PATCH 31/54] enable preimages on the whitelist --- rpc/rpc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpc/rpc.go b/rpc/rpc.go index 89a0d35327..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"} From 5f609f769203c2594fb2f86d5de04507df795dd7 Mon Sep 17 00:00:00 2001 From: Diego Nava Date: Fri, 8 Sep 2023 19:17:03 +0100 Subject: [PATCH 32/54] add the generate method --- rpc/preimages.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/rpc/preimages.go b/rpc/preimages.go index d0ab56f387..a2a4beec96 100644 --- a/rpc/preimages.go +++ b/rpc/preimages.go @@ -2,6 +2,7 @@ package rpc import ( "context" + "fmt" "github.com/harmony-one/harmony/core" "github.com/harmony-one/harmony/eth/rpc" @@ -27,3 +28,14 @@ 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) Generate(ctx context.Context, start, end uint64) error { + if number := s.hmy.CurrentBlock().NumberU64(); number > end { + fmt.Printf( + "Cropping generate endpoint from %d to %d\n", + number, end, + ) + end = number + } + // these are by default not blocking + return core.GeneratePreimages(s.hmy.BlockChain, start, end) +} From d07cd9a3fc57a6ac3ad656d4988c566109834f08 Mon Sep 17 00:00:00 2001 From: Diego Nava Date: Fri, 8 Sep 2023 19:27:06 +0100 Subject: [PATCH 33/54] fix cropping log --- rpc/preimages.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpc/preimages.go b/rpc/preimages.go index a2a4beec96..679d98deb8 100644 --- a/rpc/preimages.go +++ b/rpc/preimages.go @@ -32,7 +32,7 @@ func (s *PreimagesService) Generate(ctx context.Context, start, end uint64) erro if number := s.hmy.CurrentBlock().NumberU64(); number > end { fmt.Printf( "Cropping generate endpoint from %d to %d\n", - number, end, + end, number, ) end = number } From 66cabb4aed1aa5d00d5da58e37fb774ab995f1e3 Mon Sep 17 00:00:00 2001 From: Diego Nava Date: Fri, 8 Sep 2023 19:29:24 +0100 Subject: [PATCH 34/54] fix cropping log --- rpc/preimages.go | 1 + 1 file changed, 1 insertion(+) diff --git a/rpc/preimages.go b/rpc/preimages.go index 679d98deb8..032ca2ad3e 100644 --- a/rpc/preimages.go +++ b/rpc/preimages.go @@ -29,6 +29,7 @@ func (s *PreimagesService) Export(ctx context.Context, path string) error { return core.ExportPreimages(s.hmy.BlockChain, path) } func (s *PreimagesService) Generate(ctx context.Context, start, end uint64) error { + fmt.Printf("Generating preimage from block %d to %d\n", start, end) if number := s.hmy.CurrentBlock().NumberU64(); number > end { fmt.Printf( "Cropping generate endpoint from %d to %d\n", From 65a2ce57e6e50684c25586f929f4f6f716338d19 Mon Sep 17 00:00:00 2001 From: Diego Nava Date: Fri, 8 Sep 2023 19:30:47 +0100 Subject: [PATCH 35/54] cropping startpoint when bigger than endpoint --- rpc/preimages.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/rpc/preimages.go b/rpc/preimages.go index 032ca2ad3e..9130c647ad 100644 --- a/rpc/preimages.go +++ b/rpc/preimages.go @@ -37,6 +37,14 @@ func (s *PreimagesService) Generate(ctx context.Context, start, end uint64) erro ) end = number } + + if start >= end { + fmt.Printf( + "Cropping generate startpoint from %d to %d\n", + start, end-100, + ) + start = end - 100 + } // these are by default not blocking return core.GeneratePreimages(s.hmy.BlockChain, start, end) } From 79c369562e317ea18d117f558f433ee1cc97ba20 Mon Sep 17 00:00:00 2001 From: Diego Nava Date: Fri, 8 Sep 2023 19:48:12 +0100 Subject: [PATCH 36/54] add support for the rpcblocknumer type --- rpc/preimages.go | 50 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/rpc/preimages.go b/rpc/preimages.go index 9130c647ad..11232b06f4 100644 --- a/rpc/preimages.go +++ b/rpc/preimages.go @@ -24,27 +24,57 @@ func NewPreimagesAPI(hmy *hmy.Harmony, version string) rpc.API { } } -func (s *PreimagesService) Export(ctx context.Context, path string) error { +func (s *PreimagesService) Export(_ context.Context, path string) error { // these are by default not blocking return core.ExportPreimages(s.hmy.BlockChain, path) } -func (s *PreimagesService) Generate(ctx context.Context, start, end uint64) error { - fmt.Printf("Generating preimage from block %d to %d\n", start, end) - if number := s.hmy.CurrentBlock().NumberU64(); number > end { +func (s *PreimagesService) Generate(_ context.Context, start, end rpc.BlockNumber) error { + // earliestBlock: the number of blocks in the past where you can generate the preimage from the last block + earliestBlock := uint64(10) // TODO: change it for the actual value + currentBlockNum := s.hmy.CurrentBlock().NumberU64() + + var startBlock uint64 + switch start { + case rpc.EarliestBlockNumber: + startBlock = currentBlockNum - earliestBlock + case rpc.LatestBlockNumber: + startBlock = currentBlockNum - earliestBlock + case rpc.PendingBlockNumber: + startBlock = currentBlockNum - earliestBlock + default: + startBlock = uint64(start) + } + + var endBlock = uint64(end) + switch end { + case rpc.EarliestBlockNumber: + endBlock = currentBlockNum - earliestBlock + case rpc.LatestBlockNumber: + endBlock = currentBlockNum + case rpc.PendingBlockNumber: + endBlock = currentBlockNum + default: + endBlock = uint64(end) + } + + fmt.Printf("Generating preimage from block %d to %d\n", startBlock, endBlock) + + if number := currentBlockNum; number > endBlock { fmt.Printf( "Cropping generate endpoint from %d to %d\n", - end, number, + endBlock, number, ) - end = number + endBlock = number } - if start >= end { + if startBlock >= endBlock { fmt.Printf( "Cropping generate startpoint from %d to %d\n", - start, end-100, + startBlock, endBlock-earliestBlock, ) - start = end - 100 + startBlock = endBlock - earliestBlock } + // these are by default not blocking - return core.GeneratePreimages(s.hmy.BlockChain, start, end) + return core.GeneratePreimages(s.hmy.BlockChain, startBlock, endBlock) } From 2cc35e13ec6d725c83fcffbacd9f626e23e2129f Mon Sep 17 00:00:00 2001 From: Diego Nava Date: Fri, 8 Sep 2023 20:05:06 +0100 Subject: [PATCH 37/54] enable import api --- cmd/harmony/main.go | 88 +++------------------------------------------ core/preimages.go | 84 +++++++++++++++++++++++++++++++++++++++++++ rpc/preimages.go | 4 +++ 3 files changed, 93 insertions(+), 83 deletions(-) diff --git a/cmd/harmony/main.go b/cmd/harmony/main.go index d90684aed7..a96745ac0d 100644 --- a/cmd/harmony/main.go +++ b/cmd/harmony/main.go @@ -1,9 +1,7 @@ package main import ( - "encoding/csv" "fmt" - "io" "io/ioutil" "math/big" "math/rand" @@ -32,7 +30,6 @@ import ( ethCommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -48,7 +45,6 @@ import ( "github.com/harmony-one/harmony/common/ntp" "github.com/harmony-one/harmony/consensus" "github.com/harmony-one/harmony/core" - "github.com/harmony-one/harmony/core/rawdb" "github.com/harmony-one/harmony/hmy/downloader" "github.com/harmony-one/harmony/internal/cli" "github.com/harmony-one/harmony/internal/common" @@ -64,7 +60,6 @@ import ( "github.com/harmony-one/harmony/p2p" "github.com/harmony-one/harmony/shard" "github.com/harmony-one/harmony/webhooks" - prom "github.com/prometheus/client_golang/prometheus" ) // Host @@ -384,86 +379,13 @@ func setupNodeAndRun(hc harmonyconfig.HarmonyConfig) { //// code to handle pre-image export, import and generation if hc.Preimage != nil { if hc.Preimage.ImportFrom != "" { - reader, err := os.Open(hc.Preimage.ImportFrom) - if err != nil { - fmt.Println("Could not open file for reading", err) + if err := core.ImportPreimages( + currentNode.Blockchain(), + hc.Preimage.ImportFrom, + ); err != nil { + fmt.Println("Error importing", err) os.Exit(1) } - csvReader := csv.NewReader(reader) - chain := currentNode.Blockchain() - dbReader := chain.ChainDb() - imported := uint64(0) - for { - record, err := csvReader.Read() - if err == io.EOF { - fmt.Println("MyBlockNumber field missing, cannot proceed") - os.Exit(1) - } - if err != nil { - fmt.Println("Could not read from reader", err) - os.Exit(1) - } - // 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 { - fmt.Println("No prior value found, overwriting") - } - if blockNumber > prev { - if rawdb.WritePreimageImportBlock(dbReader, blockNumber) != nil { - fmt.Println("Error saving last import block", err) - os.Exit(1) - } - // export blockNumber to prometheus - gauge := prom.NewGauge( - prom.GaugeOpts{ - Namespace: "hmy", - Subsystem: "blockchain", - Name: "last_preimage_import", - Help: "the last known block for which preimages were imported", - }, - ) - prometheus.PromRegistry().MustRegister( - gauge, - ) - gauge.Set(float64(blockNumber)) - } - // 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 := core.FindMissingRange(imported, genStart, genEnd, current) - if toGenStart != 0 && toGenEnd != 0 { - if err := core.GeneratePreimages( - chain, toGenStart, toGenEnd, - ); err != nil { - fmt.Println("Error generating", err) - os.Exit(1) - } - } - } os.Exit(0) } else if exportPath := hc.Preimage.ExportTo; exportPath != "" { if err := core.ExportPreimages( diff --git a/core/preimages.go b/core/preimages.go index 88d3dc40b8..95cf5a5dc0 100644 --- a/core/preimages.go +++ b/core/preimages.go @@ -3,7 +3,11 @@ package core import ( "encoding/csv" "fmt" + "io" "os" + "strconv" + + "github.com/ethereum/go-ethereum/crypto" ethCommon "github.com/ethereum/go-ethereum/common" "github.com/harmony-one/harmony/api/service/prometheus" @@ -14,6 +18,86 @@ import ( prom "github.com/prometheus/client_golang/prometheus" ) +// 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 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 { + 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) + } + // export blockNumber to prometheus + gauge := prom.NewGauge( + prom.GaugeOpts{ + Namespace: "hmy", + Subsystem: "blockchain", + Name: "last_preimage_import", + Help: "the last known block for which preimages were imported", + }, + ) + prometheus.PromRegistry().MustRegister( + gauge, + ) + gauge.Set(float64(blockNumber)) + } + // 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 { // set up csv diff --git a/rpc/preimages.go b/rpc/preimages.go index 11232b06f4..4529aff28f 100644 --- a/rpc/preimages.go +++ b/rpc/preimages.go @@ -28,6 +28,10 @@ func (s *PreimagesService) Export(_ context.Context, path string) error { // these are by default not blocking return core.ExportPreimages(s.hmy.BlockChain, path) } +func (s *PreimagesService) Import(_ context.Context, path string) error { + // these are by default not blocking + return core.ImportPreimages(s.hmy.BlockChain, path) +} func (s *PreimagesService) Generate(_ context.Context, start, end rpc.BlockNumber) error { // earliestBlock: the number of blocks in the past where you can generate the preimage from the last block earliestBlock := uint64(10) // TODO: change it for the actual value From 5232a9e6fbd4235fd420e331f74b0afd5d8d42de Mon Sep 17 00:00:00 2001 From: Diego Nava Date: Fri, 15 Sep 2023 16:44:50 +0200 Subject: [PATCH 38/54] use earlies block --- rpc/preimages.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/rpc/preimages.go b/rpc/preimages.go index 4529aff28f..695f530c0e 100644 --- a/rpc/preimages.go +++ b/rpc/preimages.go @@ -34,17 +34,17 @@ func (s *PreimagesService) Import(_ context.Context, path string) error { } func (s *PreimagesService) Generate(_ context.Context, start, end rpc.BlockNumber) error { // earliestBlock: the number of blocks in the past where you can generate the preimage from the last block - earliestBlock := uint64(10) // TODO: change it for the actual value + earliestBlock := uint64(2) currentBlockNum := s.hmy.CurrentBlock().NumberU64() var startBlock uint64 switch start { case rpc.EarliestBlockNumber: - startBlock = currentBlockNum - earliestBlock + startBlock = earliestBlock case rpc.LatestBlockNumber: - startBlock = currentBlockNum - earliestBlock + startBlock = earliestBlock case rpc.PendingBlockNumber: - startBlock = currentBlockNum - earliestBlock + startBlock = earliestBlock default: startBlock = uint64(start) } @@ -52,7 +52,7 @@ func (s *PreimagesService) Generate(_ context.Context, start, end rpc.BlockNumbe var endBlock = uint64(end) switch end { case rpc.EarliestBlockNumber: - endBlock = currentBlockNum - earliestBlock + endBlock = currentBlockNum case rpc.LatestBlockNumber: endBlock = currentBlockNum case rpc.PendingBlockNumber: From cb079547b72c10a72ea0e6811a6662007b83e3f1 Mon Sep 17 00:00:00 2001 From: Diego Nava Date: Fri, 15 Sep 2023 19:08:28 +0200 Subject: [PATCH 39/54] debug logs --- core/preimages.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/preimages.go b/core/preimages.go index 95cf5a5dc0..20a237bda0 100644 --- a/core/preimages.go +++ b/core/preimages.go @@ -195,13 +195,16 @@ func GeneratePreimages(chain BlockChain, start, end uint64) error { 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()) state, err := chain.StateAt(startingBlock.Root()) if err == nil { continue From 98c4eace8de881f9c4c82cde995e11f9ff4b014d Mon Sep 17 00:00:00 2001 From: Diego Nava Date: Fri, 15 Sep 2023 19:11:47 +0200 Subject: [PATCH 40/54] debug logs --- cmd/harmony/main.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmd/harmony/main.go b/cmd/harmony/main.go index a96745ac0d..944e7f224a 100644 --- a/cmd/harmony/main.go +++ b/cmd/harmony/main.go @@ -407,6 +407,7 @@ func setupNodeAndRun(hc harmonyconfig.HarmonyConfig) { ) end = number } + fmt.Println("Starting generation") if err := core.GeneratePreimages( chain, hc.Preimage.GenerateStart, end, @@ -414,6 +415,7 @@ func setupNodeAndRun(hc harmonyconfig.HarmonyConfig) { fmt.Println("Error generating", err) os.Exit(1) } + fmt.Println("Generation successful") os.Exit(0) } os.Exit(0) From acc21e0c93efeb50a6182ac95978fbdae3a77348 Mon Sep 17 00:00:00 2001 From: Diego Nava Date: Fri, 15 Sep 2023 19:15:03 +0200 Subject: [PATCH 41/54] debug logs --- core/preimages.go | 1 + 1 file changed, 1 insertion(+) diff --git a/core/preimages.go b/core/preimages.go index 20a237bda0..9ae25cbcd9 100644 --- a/core/preimages.go +++ b/core/preimages.go @@ -206,6 +206,7 @@ func GeneratePreimages(chain BlockChain, start, end uint64) error { } fmt.Println("found block number", startingBlock.NumberU64(), startingBlock.Root().Hex()) state, err := chain.StateAt(startingBlock.Root()) + fmt.Println("state error", err) if err == nil { continue } From 36bbf4721a818d0cd1a62ed1e78a7c11770ceb5f Mon Sep 17 00:00:00 2001 From: Diego Nava Date: Fri, 15 Sep 2023 19:16:53 +0200 Subject: [PATCH 42/54] debug logs --- core/preimages.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/preimages.go b/core/preimages.go index 9ae25cbcd9..c8f9553d79 100644 --- a/core/preimages.go +++ b/core/preimages.go @@ -206,7 +206,7 @@ func GeneratePreimages(chain BlockChain, start, end uint64) error { } fmt.Println("found block number", startingBlock.NumberU64(), startingBlock.Root().Hex()) state, err := chain.StateAt(startingBlock.Root()) - fmt.Println("state error", err) + fmt.Println("state error", err, state) if err == nil { continue } From 620df0ff5470b7792691453439ed8f1b955cc198 Mon Sep 17 00:00:00 2001 From: Diego Nava Date: Fri, 15 Sep 2023 19:20:02 +0200 Subject: [PATCH 43/54] fix error catching --- core/preimages.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/preimages.go b/core/preimages.go index c8f9553d79..7ca40f8fcc 100644 --- a/core/preimages.go +++ b/core/preimages.go @@ -206,8 +206,7 @@ func GeneratePreimages(chain BlockChain, start, end uint64) error { } fmt.Println("found block number", startingBlock.NumberU64(), startingBlock.Root().Hex()) state, err := chain.StateAt(startingBlock.Root()) - fmt.Println("state error", err, state) - if err == nil { + if err != nil { continue } startingState = state From 2c37801dc405a5a13e1dac06241a63dbcb988b70 Mon Sep 17 00:00:00 2001 From: Diego Nava Date: Fri, 15 Sep 2023 19:21:41 +0200 Subject: [PATCH 44/54] fix error catching --- core/preimages.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/preimages.go b/core/preimages.go index 7ca40f8fcc..0550035087 100644 --- a/core/preimages.go +++ b/core/preimages.go @@ -224,7 +224,7 @@ func GeneratePreimages(chain BlockChain, start, end uint64) error { return fmt.Errorf("block %d not found", i) } _, _, _, _, _, _, endingState, err := chain.Processor().Process(block, startingState, *chain.GetVMConfig(), false) - if err == nil { + if err != nil { return fmt.Errorf("error executing block #%d: %s", i, err) } startingState = endingState From aca5a56fe630046ae5e5fe51a7488fece54c9e99 Mon Sep 17 00:00:00 2001 From: Diego Nava Date: Fri, 15 Sep 2023 19:49:29 +0200 Subject: [PATCH 45/54] make end optional for the comand line --- cmd/harmony/main.go | 14 ++++++++++---- core/preimages.go | 5 +++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/cmd/harmony/main.go b/cmd/harmony/main.go index 944e7f224a..138082a744 100644 --- a/cmd/harmony/main.go +++ b/cmd/harmony/main.go @@ -397,16 +397,22 @@ func setupNodeAndRun(hc harmonyconfig.HarmonyConfig) { } os.Exit(0) // both must be set - } else if hc.Preimage.GenerateStart > 0 && hc.Preimage.GenerateEnd > 0 { + } else if hc.Preimage.GenerateStart > 0 { chain := currentNode.Blockchain() end := hc.Preimage.GenerateEnd - if number := chain.CurrentBlock().NumberU64(); number > end { + current := chain.CurrentBlock().NumberU64() + if current > end { fmt.Printf( "Cropping generate endpoint from %d to %d\n", - number, end, + current, end, ) - end = number + end = current } + + if end == 0 { + end = current + } + fmt.Println("Starting generation") if err := core.GeneratePreimages( chain, diff --git a/core/preimages.go b/core/preimages.go index 0550035087..7a5503d482 100644 --- a/core/preimages.go +++ b/core/preimages.go @@ -186,6 +186,7 @@ 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 @@ -218,6 +219,9 @@ func GeneratePreimages(chain BlockChain, start, end uint64) error { // now execute block T+1 based on starting state for i := startingBlock.NumberU64() + 1; i <= end; i++ { + if i%100000 == 0 { + fmt.Println("processing block", i) + } block := chain.GetBlockByNumber(i) if block == nil { // because we have startingBlock we must have all following @@ -230,6 +234,7 @@ func GeneratePreimages(chain BlockChain, start, end uint64) error { startingState = endingState } // force any pre-images in memory so far to go to disk, if they haven't already + fmt.Println("committing images") if err := chain.CommitPreimages(); err != nil { return fmt.Errorf("error committing preimages %s", err) } From be97bd80ea9d945f601cc7ebf145ecd8408faafe Mon Sep 17 00:00:00 2001 From: Diego Nava Date: Sat, 16 Sep 2023 14:24:15 +0200 Subject: [PATCH 46/54] fix cropping logic --- cmd/harmony/main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/harmony/main.go b/cmd/harmony/main.go index 138082a744..4175a087ea 100644 --- a/cmd/harmony/main.go +++ b/cmd/harmony/main.go @@ -401,10 +401,10 @@ func setupNodeAndRun(hc harmonyconfig.HarmonyConfig) { chain := currentNode.Blockchain() end := hc.Preimage.GenerateEnd current := chain.CurrentBlock().NumberU64() - if current > end { + if end > current { fmt.Printf( "Cropping generate endpoint from %d to %d\n", - current, end, + end, current, ) end = current } From 2f9103fe2949a8e7edb9f49b3a3b6a1033c5be60 Mon Sep 17 00:00:00 2001 From: Diego Nava Date: Sun, 17 Sep 2023 16:51:38 +0200 Subject: [PATCH 47/54] improve error when apply message fails --- core/state_processor.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/state_processor.go b/core/state_processor.go index 43f2bf8692..2e937b0bcb 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -312,7 +312,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, fmt.Errorf("apply failed from='%s' to='%s': %w", msg.From().Hex(), msg.To().Hex(), err) } // Update the state with pending changes var root []byte From edb9c865ff4ea32d91a69e0de3e166d4c5b9271a Mon Sep 17 00:00:00 2001 From: Diego Nava Date: Sun, 17 Sep 2023 17:02:19 +0200 Subject: [PATCH 48/54] add balance on the error --- core/state_processor.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/state_processor.go b/core/state_processor.go index 2e937b0bcb..c1a9050d2d 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -312,7 +312,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, fmt.Errorf("apply failed from='%s' to='%s': %w", msg.From().Hex(), msg.To().Hex(), err) + return nil, nil, nil, 0, fmt.Errorf("apply failed from='%s' to='%s' balance='%s': %w", msg.From().Hex(), msg.To().Hex(), statedb.GetBalance(msg.From()).String(), err) } // Update the state with pending changes var root []byte From a09708e926beca14eb484d3e63ba24416738c58b Mon Sep 17 00:00:00 2001 From: Diego Nava Date: Mon, 18 Sep 2023 14:26:21 +0200 Subject: [PATCH 49/54] fix importing --- core/preimages.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/preimages.go b/core/preimages.go index 31a425f31c..78fd36899e 100644 --- a/core/preimages.go +++ b/core/preimages.go @@ -7,9 +7,8 @@ import ( "os" "strconv" - "github.com/ethereum/go-ethereum/crypto" - ethCommon "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" "github.com/harmony-one/harmony/api/service/prometheus" "github.com/harmony-one/harmony/core/rawdb" "github.com/harmony-one/harmony/core/state" From cba5611e036a4bf94140e28a7f0482476ca0ab8e Mon Sep 17 00:00:00 2001 From: Diego Nava Date: Mon, 18 Sep 2023 14:28:02 +0200 Subject: [PATCH 50/54] remove unused imports --- cmd/harmony/main.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/cmd/harmony/main.go b/cmd/harmony/main.go index 57217a37a7..4175a087ea 100644 --- a/cmd/harmony/main.go +++ b/cmd/harmony/main.go @@ -1,9 +1,7 @@ package main import ( - "encoding/csv" "fmt" - "io" "io/ioutil" "math/big" "math/rand" @@ -32,7 +30,6 @@ import ( ethCommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" "github.com/pkg/errors" "github.com/spf13/cobra" @@ -48,7 +45,6 @@ import ( "github.com/harmony-one/harmony/common/ntp" "github.com/harmony-one/harmony/consensus" "github.com/harmony-one/harmony/core" - "github.com/harmony-one/harmony/core/rawdb" "github.com/harmony-one/harmony/hmy/downloader" "github.com/harmony-one/harmony/internal/cli" "github.com/harmony-one/harmony/internal/common" @@ -64,7 +60,6 @@ import ( "github.com/harmony-one/harmony/p2p" "github.com/harmony-one/harmony/shard" "github.com/harmony-one/harmony/webhooks" - prom "github.com/prometheus/client_golang/prometheus" ) // Host From bedc155edf6bda283cdc5a923f57f294359405d1 Mon Sep 17 00:00:00 2001 From: "Nita Neou (Soph)" Date: Mon, 18 Sep 2023 20:43:06 +0700 Subject: [PATCH 51/54] create preimage for genesis block --- core/genesis.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/genesis.go b/core/genesis.go index 3e230cf9e6..8f6d0777e2 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,6 +253,12 @@ func (g *Genesis) ToBlock(db ethdb.Database) *types.Block { for key, value := range account.Storage { statedb.SetState(addr, key, value) } + //statedb.AddPreimage(crypto.Keccak256Hash((addr[:])), addr.Bytes()[:]) + rawdb.WritePreimages( + statedb.Database().DiskDB(), map[ethCommon.Hash][]byte{ + crypto.Keccak256Hash((addr.Bytes())): addr.Bytes(), + }, + ) } root := statedb.IntermediateRoot(false) shardStateBytes, err := shard.EncodeWrapper(g.ShardState, false) From e43d97eaef65714577920249051fcb6d16e5ea01 Mon Sep 17 00:00:00 2001 From: "Nita Neou (Soph)" Date: Mon, 18 Sep 2023 20:49:00 +0700 Subject: [PATCH 52/54] fix consensus with No Migration Possible --- core/state_processor.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/state_processor.go b/core/state_processor.go index c1a9050d2d..ef9a4e5fa5 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -145,7 +145,7 @@ func (p *StateProcessor) Process( // ran out of accounts processTxsAndStxs = false } - if err != ErrNoMigrationRequired { + if err != ErrNoMigrationPossible && err != ErrNoMigrationRequired { return nil, nil, nil, nil, 0, nil, statedb, err } } else { From 809ce39827da0438dccdfd3284a36eb075c5b218 Mon Sep 17 00:00:00 2001 From: "Nita Neou (Soph)" Date: Mon, 18 Sep 2023 21:40:20 +0700 Subject: [PATCH 53/54] use correct header for migration --- node/worker/worker.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/node/worker/worker.go b/node/worker/worker.go index 77c3361bac..2804ff3640 100644 --- a/node/worker/worker.go +++ b/node/worker/worker.go @@ -160,7 +160,7 @@ func (w *Worker) CommitTransactions( // but the balance will immediately be returned to shard 1 cx, err := core.MayBalanceMigration( w.current.gasPool, - w.beacon.CurrentHeader(), + w.GetCurrentHeader(), w.current.state, w.chain, w.chain.Config(), From b76dcb594cbcd94b37446f940bd1bc207eb578c5 Mon Sep 17 00:00:00 2001 From: "Nita Neou (Soph)" Date: Mon, 18 Sep 2023 21:43:38 +0700 Subject: [PATCH 54/54] process all tx in all block for non shard 0 --- node/node_newblock.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/node/node_newblock.go b/node/node_newblock.go index 2c4138cd2f..1978ea87fc 100644 --- a/node/node_newblock.go +++ b/node/node_newblock.go @@ -157,7 +157,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") @@ -255,7 +256,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), )