diff --git a/.gitignore b/.gitignore index 0271db9ecd..d98f7c9227 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,5 @@ profile.cov **/yarn-error.log cmd/geth/node/ cmd/geth/__debug_bin +cmd/bootnode/bootnode +graphql/__debug_bin diff --git a/Dockerfile b/Dockerfile index 10bd6ba8c0..ecbc855cd4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,13 +6,15 @@ ARG BUILDNUM="" # Build Geth in a stock Go builder container FROM golang:1.19-alpine as builder -RUN apk add --no-cache make gcc musl-dev linux-headers git bash +RUN apk add --no-cache make cmake gcc musl-dev linux-headers git bash build-base libc-dev # Get dependencies - will also be cached if we won't change go.mod/go.sum COPY go.mod /go-ethereum/ COPY go.sum /go-ethereum/ RUN cd /go-ethereum && go mod download ADD . /go-ethereum +ENV CGO_CFLAGS="-O -D__BLST_PORTABLE__" +ENV CGO_CFLAGS_ALLOW="-O -D__BLST_PORTABLE__" RUN cd /go-ethereum && go run build/ci.go install ./cmd/geth # Pull Geth into a second stage deploy alpine container @@ -26,9 +28,10 @@ ENV BSC_HOME=/bsc ENV HOME=${BSC_HOME} ENV DATA_DIR=/data +ARG VERSION_GCC=11.2.1_git20220219-r2 ENV PACKAGES ca-certificates jq \ bash bind-tools tini \ - grep curl sed + grep curl sed gcc==${VERSION_GCC} RUN apk add --no-cache $PACKAGES \ && rm -rf /var/cache/apk/* \ @@ -56,4 +59,4 @@ USER ${BSC_USER_UID}:${BSC_USER_GID} # rpc ws graphql EXPOSE 8545 8546 8547 30303 30303/udp -ENTRYPOINT ["/sbin/tini", "--", "./docker-entrypoint.sh"] +ENTRYPOINT ["/sbin/tini", "--", "./docker-entrypoint.sh"] \ No newline at end of file diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index f8ceec8838..131ab8740f 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -826,11 +826,22 @@ type filterBackend struct { func (fb *filterBackend) ChainDb() ethdb.Database { return fb.db } func (fb *filterBackend) EventMux() *event.TypeMux { panic("not supported") } -func (fb *filterBackend) HeaderByNumber(ctx context.Context, block rpc.BlockNumber) (*types.Header, error) { - if block == rpc.LatestBlockNumber { +func (fb *filterBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) { + switch number { + case rpc.PendingBlockNumber: + if block := fb.backend.pendingBlock; block != nil { + return block.Header(), nil + } + return nil, nil + case rpc.LatestBlockNumber: return fb.bc.CurrentHeader(), nil + case rpc.FinalizedBlockNumber: + return fb.bc.CurrentFinalBlock(), nil + case rpc.SafeBlockNumber: + return fb.bc.CurrentSafeBlock(), nil + default: + return fb.bc.GetHeaderByNumber(uint64(number.Int64())), nil } - return fb.bc.GetHeaderByNumber(uint64(block.Int64())), nil } func (fb *filterBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) { @@ -869,10 +880,18 @@ func (fb *filterBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event. return nullSubscription() } +func (fb *filterBackend) SubscribeNewVoteEvent(ch chan<- core.NewVoteEvent) event.Subscription { + return nullSubscription() +} + func (fb *filterBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription { return fb.bc.SubscribeChainEvent(ch) } +func (fb *filterBackend) SubscribeFinalizedHeaderEvent(ch chan<- core.FinalizedHeaderEvent) event.Subscription { + return fb.bc.SubscribeFinalizedHeaderEvent(ch) +} + func (fb *filterBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription { return fb.bc.SubscribeRemovedLogsEvent(ch) } diff --git a/beacon/engine/types.go b/beacon/engine/types.go new file mode 100644 index 0000000000..ecdf67176c --- /dev/null +++ b/beacon/engine/types.go @@ -0,0 +1,18 @@ +// Copyright 2022 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// just for prysm compile pass +package engine diff --git a/cmd/geth/blsaccountcmd.go b/cmd/geth/blsaccountcmd.go new file mode 100644 index 0000000000..07c6b24814 --- /dev/null +++ b/cmd/geth/blsaccountcmd.go @@ -0,0 +1,552 @@ +package main + +import ( + "context" + "encoding/hex" + "encoding/json" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "strings" + + "github.com/google/uuid" + "github.com/logrusorgru/aurora" + "github.com/prysmaticlabs/prysm/v3/crypto/bls" + "github.com/prysmaticlabs/prysm/v3/encoding/bytesutil" + "github.com/prysmaticlabs/prysm/v3/io/prompt" + "github.com/prysmaticlabs/prysm/v3/validator/accounts" + "github.com/prysmaticlabs/prysm/v3/validator/accounts/iface" + "github.com/prysmaticlabs/prysm/v3/validator/accounts/petnames" + "github.com/prysmaticlabs/prysm/v3/validator/accounts/wallet" + "github.com/prysmaticlabs/prysm/v3/validator/keymanager" + "github.com/prysmaticlabs/prysm/v3/validator/keymanager/local" + keystorev4 "github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4" + "gopkg.in/urfave/cli.v1" + + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/signer/core" +) + +const ( + BLSWalletPath = "bls/wallet" + BLSKeystorePath = "bls/keystore" +) + +var ( + au = aurora.NewAurora(true) +) + +var ( + blsCommand = cli.Command{ + Name: "bls", + Usage: "Manage BLS wallet and accounts", + ArgsUsage: "", + Category: "BLS ACCOUNT COMMANDS", + Description: ` + +Manage BLS wallet and accounts, before creating or importing BLS accounts, create +BLS wallet first. One BLS wallet is enough for all BLS accounts, the first BLS +account in the wallet will be used to vote for fast finality now. + +It only supports interactive mode now, when you are prompted for password, please +input your password, and take care the wallet password which is different from accounts' +password. + +There are generally two steps to manage a BLS account: +1.Create a BLS wallet: geth bls wallet create +2.Create a BLS account: geth bls account new + or import a BLS account: geth bls account import `, + Subcommands: []cli.Command{ + { + Name: "wallet", + Usage: "Manage BLS wallet", + ArgsUsage: "", + Category: "BLS ACCOUNT COMMANDS", + Description: ` + +Create a BLS wallet to manage BLS accounts, this should before creating +or import a BLS account. The BLS wallet dir should be "/bls/wallet".`, + Subcommands: []cli.Command{ + { + Name: "create", + Usage: "Create BLS wallet", + Action: utils.MigrateFlags(blsWalletCreate), + ArgsUsage: "", + Category: "BLS ACCOUNT COMMANDS", + Flags: []cli.Flag{ + utils.DataDirFlag, + }, + Description: ` + geth bls wallet create + +will prompt for your password then create a BLS wallet in "/bls/wallet", +don't create BLS wallet repeatedly'.`, + }, + }, + }, + { + Name: "account", + Usage: "Manage BLS accounts", + ArgsUsage: "", + Category: "BLS ACCOUNT COMMANDS", + Description: ` + +Manage BLS accounts,list all existing accounts, import a BLS private key into +a new account, create a new account or delete an existing account. + +Make sure you remember the password you gave when creating a new account. +Without it you are not able to unlock your account. And this password is +different from the wallet password, please take care. + +Note that exporting your key in unencrypted format is NOT supported. + +Keys are stored under /bls/keystore. +It is safe to transfer the entire directory or the individual keys therein +between ethereum nodes by simply copying. + +Make sure you backup your BLS keys regularly.`, + Subcommands: []cli.Command{ + { + Name: "new", + Usage: "Create a BLS account", + Action: utils.MigrateFlags(blsAccountCreate), + ArgsUsage: "", + Category: "BLS ACCOUNT COMMANDS", + Flags: []cli.Flag{ + utils.DataDirFlag, + }, + Description: ` + geth bls account new + +Creates a new BLS account and imports the account into the BLS wallet. + +If the BLS wallet not created yet, it will try to create BLS wallet first. + +The account is saved in encrypted format, you are prompted for a password. +You must remember this password to unlock your account in the future.`, + }, + { + Name: "import", + Usage: "Import a BLS account", + Action: utils.MigrateFlags(blsAccountImport), + ArgsUsage: "", + Category: "BLS ACCOUNT COMMANDS", + Flags: []cli.Flag{ + utils.DataDirFlag, + }, + Description: ` + geth bls account import + +Import a encrypted BLS account from keystore file into the BLS wallet. + +If the BLS wallet not created yet, it will try to create BLS wallet first.`, + }, + { + Name: "list", + Usage: "Print summary of existing BLS accounts", + Action: utils.MigrateFlags(blsAccountList), + ArgsUsage: "", + Category: "BLS ACCOUNT COMMANDS", + Flags: []cli.Flag{ + utils.DataDirFlag, + }, + Description: ` + geth bls account list + +Print summary of existing BLS accounts in the current BLS wallet.`, + }, + { + Name: "delete", + Usage: "Delete the selected BLS account from the BLS wallet", + Action: utils.MigrateFlags(blsAccountDelete), + ArgsUsage: "", + Category: "BLS ACCOUNT COMMANDS", + Flags: []cli.Flag{ + utils.DataDirFlag, + }, + Description: ` + geth bls account delete + +Delete the selected BLS account from the BLS wallet.`, + }, + }, + }, + }, + } +) + +// blsWalletCreate creates a BLS wallet in /bls/wallet. +func blsWalletCreate(ctx *cli.Context) error { + cfg := gethConfig{Node: defaultNodeConfig()} + // Load config file. + if file := ctx.GlobalString(configFileFlag.Name); file != "" { + if err := loadConfig(file, &cfg); err != nil { + utils.Fatalf("%v", err) + } + } + utils.SetNodeConfig(ctx, &cfg.Node) + + dir := filepath.Join(cfg.Node.DataDir, BLSWalletPath) + dirExists, err := wallet.Exists(dir) + if err != nil { + utils.Fatalf("Check BLS wallet exists error: %v.", err) + } + if dirExists { + utils.Fatalf("BLS wallet already exists in /bls/wallet.") + } + + password := utils.GetPassPhrase("Your new BLS wallet will be locked with a password. Please give a password. Do not forget this password.", true) + + opts := []accounts.Option{} + opts = append(opts, accounts.WithWalletDir(dir)) + opts = append(opts, accounts.WithWalletPassword(password)) + opts = append(opts, accounts.WithKeymanagerType(keymanager.Local)) + opts = append(opts, accounts.WithSkipMnemonicConfirm(true)) + acc, err := accounts.NewCLIManager(opts...) + if err != nil { + utils.Fatalf("New Accounts CLI Manager failed: %v.", err) + } + if _, err := acc.WalletCreate(context.Background()); err != nil { + utils.Fatalf("Create BLS wallet failed: %v.", err) + } + + fmt.Println("Create BLS wallet successfully!") + return nil +} + +// openOrCreateBLSWallet opens BLS wallet in /bls/wallet, if wallet +// not exists, then creates BLS wallet in /bls/wallet. +func openOrCreateBLSWallet(ctx *cli.Context, cfg *gethConfig) (*wallet.Wallet, error) { + var w *wallet.Wallet + walletDir := filepath.Join(cfg.Node.DataDir, BLSWalletPath) + dirExists, err := wallet.Exists(walletDir) + if err != nil { + utils.Fatalf("Check dir %s failed: %v.", walletDir, err) + } + if !dirExists { + fmt.Println("BLS wallet not exists, creating BLS wallet...") + password := utils.GetPassPhrase("Your new BLS wallet will be locked with a password. Please give a password. Do not forget this password.", true) + + opts := []accounts.Option{} + opts = append(opts, accounts.WithWalletDir(walletDir)) + opts = append(opts, accounts.WithWalletPassword(password)) + opts = append(opts, accounts.WithKeymanagerType(keymanager.Local)) + opts = append(opts, accounts.WithSkipMnemonicConfirm(true)) + acc, err := accounts.NewCLIManager(opts...) + if err != nil { + utils.Fatalf("New Accounts CLI Manager failed: %v.", err) + } + w, err := acc.WalletCreate(context.Background()) + if err != nil { + utils.Fatalf("Create BLS wallet failed: %v.", err) + } + + fmt.Println("Create BLS wallet successfully!") + return w, nil + } + + walletPassword := utils.GetPassPhrase("Enter the password for your BLS wallet.", false) + w, err = wallet.OpenWallet(context.Background(), &wallet.Config{ + WalletDir: walletDir, + WalletPassword: walletPassword, + }) + if err != nil { + utils.Fatalf("Open BLS wallet failed: %v.", err) + } + return w, nil +} + +// blsAccountCreate creates a BLS account in /bls/keystore, +// and import the created account into the BLS wallet. +func blsAccountCreate(ctx *cli.Context) error { + cfg := gethConfig{Node: defaultNodeConfig()} + // Load config file. + if file := ctx.GlobalString(configFileFlag.Name); file != "" { + if err := loadConfig(file, &cfg); err != nil { + utils.Fatalf("%v", err) + } + } + utils.SetNodeConfig(ctx, &cfg.Node) + + w, _ := openOrCreateBLSWallet(ctx, &cfg) + if w.KeymanagerKind() != keymanager.Local { + utils.Fatalf("BLS wallet has wrong key manager kind.") + } + km, err := w.InitializeKeymanager(context.Background(), iface.InitKeymanagerConfig{ListenForChanges: false}) + if err != nil { + utils.Fatalf("Initialize key manager failed: %v.", err) + } + k, ok := km.(keymanager.Importer) + if !ok { + utils.Fatalf("The BLS keymanager cannot import keystores") + } + + keystoreDir := filepath.Join(cfg.Node.DataDir, BLSKeystorePath) + if err := os.MkdirAll(keystoreDir, 0755); err != nil { + utils.Fatalf("Could not access keystore dir: %v.", err) + } + accountPassword := utils.GetPassPhrase("Your new BLS account will be encrypted with a password. Please give a password. Do not forget this password.", true) + if err := core.ValidatePasswordFormat(accountPassword); err != nil { + utils.Fatalf("Password invalid: %v.", err) + } + + encryptor := keystorev4.New() + secretKey, err := bls.RandKey() + if err != nil { + utils.Fatalf("Could not generate BLS secret key: %v.", err) + } + pubKeyBytes := secretKey.PublicKey().Marshal() + cryptoFields, err := encryptor.Encrypt(secretKey.Marshal(), accountPassword) + if err != nil { + utils.Fatalf("Could not encrypt secret key: %v.", err) + } + id, err := uuid.NewRandom() + if err != nil { + utils.Fatalf("Could not generate uuid: %v.", err) + } + keystore := &keymanager.Keystore{ + Crypto: cryptoFields, + ID: id.String(), + Pubkey: fmt.Sprintf("%x", pubKeyBytes), + Version: encryptor.Version(), + Name: encryptor.Name(), + } + + encodedFile, err := json.MarshalIndent(keystore, "", "\t") + if err != nil { + utils.Fatalf("Could not marshal keystore to JSON file: %v.", err) + } + keystoreFile, err := os.Create(fmt.Sprintf("%s/keystore-%s.json", keystoreDir, petnames.DeterministicName(pubKeyBytes, "-"))) + if err != nil { + utils.Fatalf("Could not create keystore file: %v.", err) + } + if _, err := keystoreFile.Write(encodedFile); err != nil { + utils.Fatalf("Could not write keystore file contents: %v.", err) + } + fmt.Println("Successfully create a BLS account.") + + fmt.Println("Importing BLS account, this may take a while...") + _, err = accounts.ImportAccounts(context.Background(), &accounts.ImportAccountsConfig{ + Importer: k, + Keystores: []*keymanager.Keystore{keystore}, + AccountPassword: accountPassword, + }) + if err != nil { + utils.Fatalf("Import BLS account failed: %v.", err) + } + fmt.Printf("Successfully import created BLS account.\n") + return nil +} + +// blsAccountImport imports a BLS account into the BLS wallet. +func blsAccountImport(ctx *cli.Context) error { + keyfile := ctx.Args().First() + if len(keyfile) == 0 { + utils.Fatalf("The keystore file must be given as argument.") + } + keyJSON, err := ioutil.ReadFile(keyfile) + if err != nil { + utils.Fatalf("Could not read keystore file: %v", err) + } + keystore := &keymanager.Keystore{} + if err := json.Unmarshal(keyJSON, keystore); err != nil { + utils.Fatalf("Could not decode keystore file: %v.", err) + } + if keystore.Pubkey == "" { + utils.Fatalf(" Missing public key, wrong keystore file.") + } + + cfg := gethConfig{Node: defaultNodeConfig()} + // Load config file. + if file := ctx.GlobalString(configFileFlag.Name); file != "" { + if err := loadConfig(file, &cfg); err != nil { + utils.Fatalf("%v", err) + } + } + utils.SetNodeConfig(ctx, &cfg.Node) + + w, _ := openOrCreateBLSWallet(ctx, &cfg) + if w.KeymanagerKind() != keymanager.Local { + utils.Fatalf("BLS wallet has wrong key manager kind.") + } + km, err := w.InitializeKeymanager(context.Background(), iface.InitKeymanagerConfig{ListenForChanges: false}) + if err != nil { + utils.Fatalf("Initialize key manager failed: %v.", err) + } + k, ok := km.(keymanager.Importer) + if !ok { + utils.Fatalf("The BLS keymanager cannot import keystores") + } + + password := utils.GetPassPhrase("Enter the password for your imported account.", false) + fmt.Println("Importing BLS account, this may take a while...") + _, err = accounts.ImportAccounts(context.Background(), &accounts.ImportAccountsConfig{ + Importer: k, + Keystores: []*keymanager.Keystore{keystore}, + AccountPassword: password, + }) + if err != nil { + utils.Fatalf("Import BLS account failed: %v.", err) + } + fmt.Println("Successfully import BLS account.") + return nil +} + +// blsAccountList prints existing BLS accounts in the BLS wallet. +func blsAccountList(ctx *cli.Context) error { + cfg := gethConfig{Node: defaultNodeConfig()} + // Load config file. + if file := ctx.GlobalString(configFileFlag.Name); file != "" { + if err := loadConfig(file, &cfg); err != nil { + utils.Fatalf("%v", err) + } + } + utils.SetNodeConfig(ctx, &cfg.Node) + + walletDir := filepath.Join(cfg.Node.DataDir, BLSWalletPath) + dirExists, err := wallet.Exists(walletDir) + if err != nil || !dirExists { + utils.Fatalf("BLS wallet not exists.") + } + + walletPassword := utils.GetPassPhrase("Enter the password for your BLS wallet.", false) + w, err := wallet.OpenWallet(context.Background(), &wallet.Config{ + WalletDir: walletDir, + WalletPassword: walletPassword, + }) + if err != nil { + utils.Fatalf("Open BLS wallet failed: %v.", err) + } + km, err := w.InitializeKeymanager(context.Background(), iface.InitKeymanagerConfig{ListenForChanges: false}) + if err != nil { + utils.Fatalf("Initialize key manager failed: %v.", err) + } + + ikm, ok := km.(*local.Keymanager) + if !ok { + utils.Fatalf("Could not assert keymanager interface to concrete type.") + } + accountNames, err := ikm.ValidatingAccountNames() + if err != nil { + utils.Fatalf("Could not fetch account names: %v.", err) + } + numAccounts := au.BrightYellow(len(accountNames)) + fmt.Printf("(keymanager kind) %s\n", au.BrightGreen("imported wallet").Bold()) + fmt.Println("") + if len(accountNames) == 1 { + fmt.Printf("Showing %d BLS account\n", numAccounts) + } else { + fmt.Printf("Showing %d BLS accounts\n", numAccounts) + } + pubKeys, err := km.FetchValidatingPublicKeys(context.Background()) + if err != nil { + utils.Fatalf("Could not fetch BLS public keys: %v.", err) + } + for i := 0; i < len(accountNames); i++ { + fmt.Println("") + fmt.Printf("%s | %s\n", au.BrightBlue(fmt.Sprintf("Account %d", i)).Bold(), au.BrightGreen(accountNames[i]).Bold()) + fmt.Printf("%s %#x\n", au.BrightMagenta("[BLS public key]").Bold(), pubKeys[i]) + } + fmt.Println("") + return nil +} + +// blsAccountDelete deletes a selected BLS account from the BLS wallet. +func blsAccountDelete(ctx *cli.Context) error { + if len(ctx.Args()) == 0 { + utils.Fatalf("No BLS account specified to delete.") + } + var filteredPubKeys []bls.PublicKey + for _, str := range ctx.Args() { + pkString := str + if strings.Contains(pkString, "0x") { + pkString = pkString[2:] + } + pubKeyBytes, err := hex.DecodeString(pkString) + if err != nil { + utils.Fatalf("Could not decode string %s as hex.", pkString) + } + blsPublicKey, err := bls.PublicKeyFromBytes(pubKeyBytes) + if err != nil { + utils.Fatalf("%#x is not a valid BLS public key.", pubKeyBytes) + } + filteredPubKeys = append(filteredPubKeys, blsPublicKey) + } + + cfg := gethConfig{Node: defaultNodeConfig()} + // Load config file. + if file := ctx.GlobalString(configFileFlag.Name); file != "" { + if err := loadConfig(file, &cfg); err != nil { + utils.Fatalf("%v", err) + } + } + utils.SetNodeConfig(ctx, &cfg.Node) + + walletDir := filepath.Join(cfg.Node.DataDir, BLSWalletPath) + dirExists, err := wallet.Exists(walletDir) + if err != nil || !dirExists { + utils.Fatalf("BLS wallet not exists.") + } + + walletPassword := utils.GetPassPhrase("Enter the password for your BLS wallet.", false) + w, err := wallet.OpenWallet(context.Background(), &wallet.Config{ + WalletDir: walletDir, + WalletPassword: walletPassword, + }) + if err != nil { + utils.Fatalf("Open BLS wallet failed: %v.", err) + } + km, err := w.InitializeKeymanager(context.Background(), iface.InitKeymanagerConfig{ListenForChanges: false}) + if err != nil { + utils.Fatalf("Initialize key manager failed: %v.", err) + } + pubkeys, err := km.FetchValidatingPublicKeys(context.Background()) + if err != nil { + utils.Fatalf("Could not fetch BLS public keys: %v.", err) + } + + rawPublicKeys := make([][]byte, len(filteredPubKeys)) + formattedPubKeys := make([]string, len(filteredPubKeys)) + for i, pk := range filteredPubKeys { + pubKeyBytes := pk.Marshal() + rawPublicKeys[i] = pubKeyBytes + formattedPubKeys[i] = fmt.Sprintf("%#x", bytesutil.Trunc(pubKeyBytes)) + } + allAccountStr := strings.Join(formattedPubKeys, ", ") + if len(filteredPubKeys) == 1 { + promptText := "Are you sure you want to delete 1 account? (%s) Y/N" + resp, err := prompt.ValidatePrompt( + os.Stdin, fmt.Sprintf(promptText, au.BrightGreen(formattedPubKeys[0])), prompt.ValidateYesOrNo, + ) + if err != nil { + return err + } + if strings.EqualFold(resp, "n") { + return nil + } + } else { + promptText := "Are you sure you want to delete %d accounts? (%s) Y/N" + if len(filteredPubKeys) == len(pubkeys) { + promptText = fmt.Sprintf("Are you sure you want to delete all accounts? Y/N (%s)", au.BrightGreen(allAccountStr)) + } else { + promptText = fmt.Sprintf(promptText, len(filteredPubKeys), au.BrightGreen(allAccountStr)) + } + resp, err := prompt.ValidatePrompt(os.Stdin, promptText, prompt.ValidateYesOrNo) + if err != nil { + return err + } + if strings.EqualFold(resp, "n") { + return nil + } + } + + if err := accounts.DeleteAccount(context.Background(), &accounts.DeleteConfig{ + Keymanager: km, + DeletePublicKeys: rawPublicKeys, + }); err != nil { + utils.Fatalf("Delete account failed: %v.", err) + } + + return nil +} diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 6ea505b503..e65ac3dd08 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -72,6 +72,7 @@ var ( utils.DisableSnapProtocolFlag, utils.DisableDiffProtocolFlag, utils.EnableTrustProtocolFlag, + utils.DisableBscProtocolFlag, utils.DiffSyncFlag, utils.PipeCommitFlag, utils.RangeLimitFlag, @@ -168,6 +169,9 @@ var ( utils.BlockAmountReserved, utils.CheckSnapshotWithMPT, utils.EnableDoubleSignMonitorFlag, + utils.BLSPasswordFileFlag, + utils.BLSWalletDirFlag, + utils.VoteJournalDirFlag, } rpcFlags = []cli.Flag{ @@ -251,6 +255,7 @@ func init() { utils.ShowDeprecated, // See snapshot.go snapshotCommand, + blsCommand, } sort.Sort(cli.CommandsByName(app.Commands)) diff --git a/cmd/geth/usage.go b/cmd/geth/usage.go index 5054067909..52b3bcd09d 100644 --- a/cmd/geth/usage.go +++ b/cmd/geth/usage.go @@ -43,6 +43,7 @@ var AppHelpFlagGroups = []flags.FlagGroup{ utils.DisableSnapProtocolFlag, utils.DisableDiffProtocolFlag, utils.EnableTrustProtocolFlag, + utils.DisableBscProtocolFlag, utils.RangeLimitFlag, utils.SmartCardDaemonPathFlag, utils.NetworkIdFlag, @@ -59,6 +60,9 @@ var AppHelpFlagGroups = []flags.FlagGroup{ utils.TriesInMemoryFlag, utils.BlockAmountReserved, utils.CheckSnapshotWithMPT, + utils.BLSPasswordFileFlag, + utils.BLSWalletDirFlag, + utils.VoteJournalDirFlag, }, }, { @@ -237,6 +241,12 @@ var AppHelpFlagGroups = []flags.FlagGroup{ cli.HelpFlag, }, }, + { + Name: "BLS ACCOUNT", + Flags: []cli.Flag{ + utils.DataDirFlag, + }, + }, } func init() { diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 9f4e4b6d10..f7b0abcfe0 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -25,6 +25,7 @@ import ( "math" "math/big" "os" + "path/filepath" "runtime" godebug "runtime/debug" "strconv" @@ -133,6 +134,11 @@ var ( Name: "enabletrustprotocol", Usage: "Enable trust protocol", } + DisableBscProtocolFlag = cli.BoolFlag{ + Name: "disablebscprotocol", + Usage: "Disable bsc protocol", + } + DiffSyncFlag = cli.BoolFlag{ Name: "diffsync", Usage: "Enable diffy sync, Please note that enable diffsync will improve the syncing speed, " + @@ -890,6 +896,21 @@ var ( Name: "monitor.doublesign", Usage: "Enable double sign monitor to check whether any validator signs multiple blocks", } + + BLSPasswordFileFlag = cli.StringFlag{ + Name: "blspassword", + Usage: "File path for the BLS password, which contains the password to unlock BLS wallet for managing votes in fast_finality feature", + } + + BLSWalletDirFlag = DirectoryFlag{ + Name: "blswallet", + Usage: "Path for the blsWallet dir in fast finality feature (default = inside the datadir)", + } + + VoteJournalDirFlag = DirectoryFlag{ + Name: "vote-journal-path", + Usage: "Path for the voteJournal dir in fast finality feature (default = inside the datadir)", + } ) // MakeDataDir retrieves the currently requested data directory, terminating @@ -1305,6 +1326,8 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config) { setDataDir(ctx, cfg) setSmartCard(ctx, cfg) setMonitor(ctx, cfg) + setBLSWalletDir(ctx, cfg) + setVoteJournalDir(ctx, cfg) if ctx.GlobalIsSet(ExternalSignerFlag.Name) { cfg.ExternalSigner = ctx.GlobalString(ExternalSignerFlag.Name) @@ -1337,6 +1360,10 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config) { if ctx.GlobalIsSet(InsecureUnlockAllowedFlag.Name) { cfg.InsecureUnlockAllowed = ctx.GlobalBool(InsecureUnlockAllowedFlag.Name) } + + if ctx.GlobalIsSet(BLSPasswordFileFlag.Name) { + cfg.BLSPasswordFile = ctx.GlobalString(BLSPasswordFileFlag.Name) + } } func setSmartCard(ctx *cli.Context, cfg *node.Config) { @@ -1368,6 +1395,24 @@ func setDataDir(ctx *cli.Context, cfg *node.Config) { } } +func setVoteJournalDir(ctx *cli.Context, cfg *node.Config) { + dataDir := cfg.DataDir + if ctx.GlobalIsSet(VoteJournalDirFlag.Name) { + cfg.VoteJournalDir = ctx.GlobalString(VoteJournalDirFlag.Name) + } else { + cfg.VoteJournalDir = filepath.Join(dataDir, "voteJournal") + } +} + +func setBLSWalletDir(ctx *cli.Context, cfg *node.Config) { + dataDir := cfg.DataDir + if ctx.GlobalIsSet(BLSWalletDirFlag.Name) { + cfg.BLSWalletDir = ctx.GlobalString(BLSWalletDirFlag.Name) + } else { + cfg.BLSWalletDir = filepath.Join(dataDir, "bls/wallet") + } +} + func setGPO(ctx *cli.Context, cfg *gasprice.Config, light bool) { // If we are running the light client, apply another group // settings for gas oracle. @@ -1645,6 +1690,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { if ctx.GlobalIsSet(EnableTrustProtocolFlag.Name) { cfg.EnableTrustProtocol = ctx.GlobalIsSet(EnableTrustProtocolFlag.Name) } + if ctx.GlobalIsSet(DisableBscProtocolFlag.Name) { + cfg.DisableBscProtocol = ctx.GlobalIsSet(DisableBscProtocolFlag.Name) + } if ctx.GlobalIsSet(DiffSyncFlag.Name) { log.Warn("The --diffsync flag is deprecated and will be removed in the future!") } @@ -1721,7 +1769,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { cfg.RPCTxFeeCap = ctx.GlobalFloat64(RPCGlobalTxFeeCapFlag.Name) } if ctx.GlobalIsSet(NoDiscoverFlag.Name) { - cfg.EthDiscoveryURLs, cfg.SnapDiscoveryURLs, cfg.TrustDiscoveryURLs = []string{}, []string{}, []string{} + cfg.EthDiscoveryURLs, cfg.SnapDiscoveryURLs, cfg.TrustDiscoveryURLs, cfg.BscDiscoveryURLs = []string{}, []string{}, []string{}, []string{} } else if ctx.GlobalIsSet(DNSDiscoveryFlag.Name) { urls := ctx.GlobalString(DNSDiscoveryFlag.Name) if urls == "" { @@ -1812,6 +1860,7 @@ func SetDNSDiscoveryDefaults(cfg *ethconfig.Config, genesis common.Hash) { cfg.EthDiscoveryURLs = []string{url} cfg.SnapDiscoveryURLs = cfg.EthDiscoveryURLs cfg.TrustDiscoveryURLs = cfg.EthDiscoveryURLs + cfg.BscDiscoveryURLs = cfg.EthDiscoveryURLs } } diff --git a/common/math/integer.go b/common/math/integer.go index 50d3eba1f5..36643b5bca 100644 --- a/common/math/integer.go +++ b/common/math/integer.go @@ -96,3 +96,10 @@ func SafeMul(x, y uint64) (uint64, bool) { hi, lo := bits.Mul64(x, y) return lo, hi != 0 } + +func CeilDiv(x, y int) int { + if y == 0 { + return 0 + } + return (x + y - 1) / y +} diff --git a/consensus/consensus.go b/consensus/consensus.go index 87632a9d0d..30c4559043 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -57,6 +57,10 @@ type ChainHeaderReader interface { GetHighestVerifiedHeader() *types.Header } +type VotePool interface { + FetchVoteByBlockHash(blockHash common.Hash) []*types.VoteEnvelope +} + // ChainReader defines a small collection of methods needed to access the local // blockchain during header and/or uncle verification. type ChainReader interface { @@ -148,4 +152,8 @@ type PoSA interface { EnoughDistance(chain ChainReader, header *types.Header) bool IsLocalBlock(header *types.Header) bool AllowLightProcess(chain ChainReader, currentHeader *types.Header) bool + GetJustifiedNumberAndHash(chain ChainHeaderReader, header *types.Header) (uint64, common.Hash, error) + GetFinalizedHeader(chain ChainHeaderReader, header *types.Header) *types.Header + VerifyVote(chain ChainHeaderReader, vote *types.VoteEnvelope) error + IsActiveValidatorAt(chain ChainHeaderReader, header *types.Header) bool } diff --git a/consensus/parlia/abi.go b/consensus/parlia/abi.go index e841eb5cd5..16ddb1eab4 100644 --- a/consensus/parlia/abi.go +++ b/consensus/parlia/abi.go @@ -1,6 +1,6 @@ package parlia -const validatorSetABI = ` +const validatorSetABIBeforeBoneh = ` [ { "anonymous": false, @@ -1388,7 +1388,1605 @@ const validatorSetABI = ` "stateMutability": "view", "type": "function" } - ] +] +` + +const validatorSetABI = ` +[ + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"batchTransfer", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"string", + "name":"reason", + "type":"string" + } + ], + "name":"batchTransferFailed", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + }, + { + "indexed":false, + "internalType":"bytes", + "name":"reason", + "type":"bytes" + } + ], + "name":"batchTransferLowerFailed", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"validator", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"deprecatedDeposit", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"validator", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"deprecatedFinalityRewardDeposit", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address payable", + "name":"validator", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"directTransfer", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address payable", + "name":"validator", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"directTransferFail", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"string", + "name":"message", + "type":"string" + } + ], + "name":"failReasonWithStr", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"feeBurned", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"validator", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"finalityRewardDeposit", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"string", + "name":"key", + "type":"string" + }, + { + "indexed":false, + "internalType":"bytes", + "name":"value", + "type":"bytes" + } + ], + "name":"paramChange", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"systemTransfer", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":false, + "internalType":"uint8", + "name":"channelId", + "type":"uint8" + }, + { + "indexed":false, + "internalType":"bytes", + "name":"msgBytes", + "type":"bytes" + } + ], + "name":"unexpectedPackage", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"validator", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"validatorDeposit", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"validator", + "type":"address" + } + ], + "name":"validatorEmptyJailed", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"validator", + "type":"address" + } + ], + "name":"validatorEnterMaintenance", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"validator", + "type":"address" + } + ], + "name":"validatorExitMaintenance", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"validator", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"validatorFelony", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"validator", + "type":"address" + } + ], + "name":"validatorJailed", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + { + "indexed":true, + "internalType":"address", + "name":"validator", + "type":"address" + }, + { + "indexed":false, + "internalType":"uint256", + "name":"amount", + "type":"uint256" + } + ], + "name":"validatorMisdemeanor", + "type":"event" + }, + { + "anonymous":false, + "inputs":[ + + ], + "name":"validatorSetUpdated", + "type":"event" + }, + { + "inputs":[ + + ], + "name":"BIND_CHANNELID", + "outputs":[ + { + "internalType":"uint8", + "name":"", + "type":"uint8" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"BURN_ADDRESS", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"BURN_RATIO_SCALE", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"CODE_OK", + "outputs":[ + { + "internalType":"uint32", + "name":"", + "type":"uint32" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"CROSS_CHAIN_CONTRACT_ADDR", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"CROSS_STAKE_CHANNELID", + "outputs":[ + { + "internalType":"uint8", + "name":"", + "type":"uint8" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"DUSTY_INCOMING", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"EPOCH", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"ERROR_FAIL_CHECK_VALIDATORS", + "outputs":[ + { + "internalType":"uint32", + "name":"", + "type":"uint32" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"ERROR_FAIL_DECODE", + "outputs":[ + { + "internalType":"uint32", + "name":"", + "type":"uint32" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"ERROR_LEN_OF_VAL_MISMATCH", + "outputs":[ + { + "internalType":"uint32", + "name":"", + "type":"uint32" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"ERROR_RELAYFEE_TOO_LARGE", + "outputs":[ + { + "internalType":"uint32", + "name":"", + "type":"uint32" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"ERROR_UNKNOWN_PACKAGE_TYPE", + "outputs":[ + { + "internalType":"uint32", + "name":"", + "type":"uint32" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"EXPIRE_TIME_SECOND_GAP", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"GOV_CHANNELID", + "outputs":[ + { + "internalType":"uint8", + "name":"", + "type":"uint8" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"GOV_HUB_ADDR", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"INCENTIVIZE_ADDR", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"INIT_BURN_RATIO", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"INIT_FINALITY_REWARD_RATIO", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"INIT_MAINTAIN_SLASH_SCALE", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"INIT_MAX_NUM_OF_MAINTAINING", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"INIT_NUM_OF_CABINETS", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"INIT_VALIDATORSET_BYTES", + "outputs":[ + { + "internalType":"bytes", + "name":"", + "type":"bytes" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"JAIL_MESSAGE_TYPE", + "outputs":[ + { + "internalType":"uint8", + "name":"", + "type":"uint8" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"LIGHT_CLIENT_ADDR", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"MAX_NUM_OF_VALIDATORS", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"PRECISION", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"RELAYERHUB_CONTRACT_ADDR", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"SLASH_CHANNELID", + "outputs":[ + { + "internalType":"uint8", + "name":"", + "type":"uint8" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"SLASH_CONTRACT_ADDR", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"STAKING_CHANNELID", + "outputs":[ + { + "internalType":"uint8", + "name":"", + "type":"uint8" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"STAKING_CONTRACT_ADDR", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"SYSTEM_REWARD_ADDR", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"TOKEN_HUB_ADDR", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"TOKEN_MANAGER_ADDR", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"TRANSFER_IN_CHANNELID", + "outputs":[ + { + "internalType":"uint8", + "name":"", + "type":"uint8" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"TRANSFER_OUT_CHANNELID", + "outputs":[ + { + "internalType":"uint8", + "name":"", + "type":"uint8" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"VALIDATORS_UPDATE_MESSAGE_TYPE", + "outputs":[ + { + "internalType":"uint8", + "name":"", + "type":"uint8" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"VALIDATOR_CONTRACT_ADDR", + "outputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"alreadyInit", + "outputs":[ + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"bscChainID", + "outputs":[ + { + "internalType":"uint16", + "name":"", + "type":"uint16" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"burnRatio", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"burnRatioInitialized", + "outputs":[ + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"index", + "type":"uint256" + } + ], + "name":"canEnterMaintenance", + "outputs":[ + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "name":"currentValidatorSet", + "outputs":[ + { + "internalType":"address", + "name":"consensusAddress", + "type":"address" + }, + { + "internalType":"address payable", + "name":"feeAddress", + "type":"address" + }, + { + "internalType":"address", + "name":"BBCFeeAddress", + "type":"address" + }, + { + "internalType":"uint64", + "name":"votingPower", + "type":"uint64" + }, + { + "internalType":"bool", + "name":"jailed", + "type":"bool" + }, + { + "internalType":"uint256", + "name":"incoming", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"", + "type":"address" + } + ], + "name":"currentValidatorSetMap", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"valAddr", + "type":"address" + } + ], + "name":"deposit", + "outputs":[ + + ], + "stateMutability":"payable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address[]", + "name":"valAddrs", + "type":"address[]" + }, + { + "internalType":"uint256[]", + "name":"weights", + "type":"uint256[]" + } + ], + "name":"distributeFinalityReward", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"enterMaintenance", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"exitMaintenance", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"expireTimeSecondGap", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"validator", + "type":"address" + } + ], + "name":"felony", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"finalityRewardRatio", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"_validator", + "type":"address" + } + ], + "name":"getCurrentValidatorIndex", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"validator", + "type":"address" + } + ], + "name":"getIncoming", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"getLivingValidators", + "outputs":[ + { + "internalType":"address[]", + "name":"", + "type":"address[]" + }, + { + "internalType":"bytes[]", + "name":"", + "type":"bytes[]" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"getMiningValidators", + "outputs":[ + { + "internalType":"address[]", + "name":"", + "type":"address[]" + }, + { + "internalType":"bytes[]", + "name":"", + "type":"bytes[]" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"getValidators", + "outputs":[ + { + "internalType":"address[]", + "name":"", + "type":"address[]" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"getWorkingValidatorCount", + "outputs":[ + { + "internalType":"uint256", + "name":"workingValidatorCount", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint8", + "name":"channelId", + "type":"uint8" + }, + { + "internalType":"bytes", + "name":"msgBytes", + "type":"bytes" + } + ], + "name":"handleAckPackage", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint8", + "name":"channelId", + "type":"uint8" + }, + { + "internalType":"bytes", + "name":"msgBytes", + "type":"bytes" + } + ], + "name":"handleFailAckPackage", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint8", + "name":"", + "type":"uint8" + }, + { + "internalType":"bytes", + "name":"msgBytes", + "type":"bytes" + } + ], + "name":"handleSynPackage", + "outputs":[ + { + "internalType":"bytes", + "name":"responsePayload", + "type":"bytes" + } + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"init", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"validator", + "type":"address" + } + ], + "name":"isCurrentValidator", + "outputs":[ + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"index", + "type":"uint256" + } + ], + "name":"isWorkingValidator", + "outputs":[ + { + "internalType":"bool", + "name":"", + "type":"bool" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"maintainSlashScale", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"maxNumOfCandidates", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"maxNumOfMaintaining", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"maxNumOfWorkingCandidates", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"address", + "name":"validator", + "type":"address" + } + ], + "name":"misdemeanor", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"numOfCabinets", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"numOfJailed", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"numOfMaintaining", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"previousHeight", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + + ], + "name":"totalInComing", + "outputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"string", + "name":"key", + "type":"string" + }, + { + "internalType":"bytes", + "name":"value", + "type":"bytes" + } + ], + "name":"updateParam", + "outputs":[ + + ], + "stateMutability":"nonpayable", + "type":"function" + }, + { + "inputs":[ + { + "internalType":"uint256", + "name":"", + "type":"uint256" + } + ], + "name":"validatorExtraSet", + "outputs":[ + { + "internalType":"uint256", + "name":"enterMaintenanceHeight", + "type":"uint256" + }, + { + "internalType":"bool", + "name":"isMaintaining", + "type":"bool" + }, + { + "internalType":"bytes", + "name":"voteAddress", + "type":"bytes" + } + ], + "stateMutability":"view", + "type":"function" + }, + { + "stateMutability":"payable", + "type":"receive" + } +] ` const slashABI = ` diff --git a/consensus/parlia/bonehFork.go b/consensus/parlia/bonehFork.go new file mode 100644 index 0000000000..f8a262b406 --- /dev/null +++ b/consensus/parlia/bonehFork.go @@ -0,0 +1,49 @@ +package parlia + +import ( + "context" + "math/big" + + "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/core/systemcontracts" + "github.com/ethereum/go-ethereum/internal/ethapi" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rpc" +) + +func (p *Parlia) getCurrentValidatorsBeforeBoneh(blockHash common.Hash, blockNumber *big.Int) ([]common.Address, error) { + blockNr := rpc.BlockNumberOrHashWithHash(blockHash, false) + + // prepare different method + method := "getValidators" + if p.chainConfig.IsEuler(blockNumber) { + method = "getMiningValidators" + } + + ctx, cancel := context.WithCancel(context.Background()) + // cancel when we are finished consuming integers + defer cancel() + data, err := p.validatorSetABIBeforeBoneh.Pack(method) + if err != nil { + log.Error("Unable to pack tx for getValidators", "error", err) + return nil, err + } + // do smart contract call + msgData := (hexutil.Bytes)(data) + toAddress := common.HexToAddress(systemcontracts.ValidatorContract) + gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2)) + result, err := p.ethAPI.Call(ctx, ethapi.TransactionArgs{ + Gas: &gas, + To: &toAddress, + Data: &msgData, + }, blockNr, nil) + if err != nil { + return nil, err + } + + var valSet []common.Address + err = p.validatorSetABIBeforeBoneh.UnpackIntoInterface(&valSet, method, result) + return valSet, err +} diff --git a/consensus/parlia/parlia.go b/consensus/parlia/parlia.go index 7a483a8fb4..aaa2f32cb1 100644 --- a/consensus/parlia/parlia.go +++ b/consensus/parlia/parlia.go @@ -16,6 +16,8 @@ import ( "time" lru "github.com/hashicorp/golang-lru" + "github.com/prysmaticlabs/prysm/v3/crypto/bls" + "github.com/willf/bitset" "golang.org/x/crypto/sha3" "github.com/ethereum/go-ethereum" @@ -24,6 +26,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/gopool" "github.com/ethereum/go-ethereum/common/hexutil" + cmath "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/misc" "github.com/ethereum/go-ethereum/core" @@ -53,13 +56,17 @@ const ( extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal nextForkHashSize = 4 // Fixed number of extra-data suffix bytes reserved for nextForkHash. - validatorBytesLength = common.AddressLength - wiggleTime = uint64(1) // second, Random delay (per signer) to allow concurrent signers - initialBackOffTime = uint64(1) // second - processBackOffTime = uint64(1) // second + validatorBytesLengthBeforeBoneh = common.AddressLength + validatorBytesLength = common.AddressLength + types.BLSPublicKeyLength + validatorNumberSize = 1 // Fixed number of extra prefix bytes reserved for validator number after Boneh + + wiggleTime = uint64(1) // second, Random delay (per signer) to allow concurrent signers + initialBackOffTime = uint64(1) // second + processBackOffTime = uint64(1) // second systemRewardPercent = 4 // it means 1/2^4 = 1/16 percentage of gas fee incoming will be distributed to system + collectAdditionalVotesRewardRatio = float64(1) // ratio of additional reward for collecting more votes than needed ) var ( @@ -208,9 +215,11 @@ type Parlia struct { lock sync.RWMutex // Protects the signer fields - ethAPI *ethapi.PublicBlockChainAPI - validatorSetABI abi.ABI - slashABI abi.ABI + ethAPI *ethapi.PublicBlockChainAPI + VotePool consensus.VotePool + validatorSetABIBeforeBoneh abi.ABI + validatorSetABI abi.ABI + slashABI abi.ABI // The fields below are for testing only fakeDiff bool // Skip difficulty verifications @@ -240,6 +249,10 @@ func New( if err != nil { panic(err) } + vABIBeforeBoneh, err := abi.JSON(strings.NewReader(validatorSetABIBeforeBoneh)) + if err != nil { + panic(err) + } vABI, err := abi.JSON(strings.NewReader(validatorSetABI)) if err != nil { panic(err) @@ -249,16 +262,17 @@ func New( panic(err) } c := &Parlia{ - chainConfig: chainConfig, - config: parliaConfig, - genesisHash: genesisHash, - db: db, - ethAPI: ethAPI, - recentSnaps: recentSnaps, - signatures: signatures, - validatorSetABI: vABI, - slashABI: sABI, - signer: types.NewEIP155Signer(chainConfig.ChainID), + chainConfig: chainConfig, + config: parliaConfig, + genesisHash: genesisHash, + db: db, + ethAPI: ethAPI, + recentSnaps: recentSnaps, + signatures: signatures, + validatorSetABIBeforeBoneh: vABIBeforeBoneh, + validatorSetABI: vABI, + slashABI: sABI, + signer: types.NewEIP155Signer(chainConfig.ChainID), } return c @@ -317,6 +331,160 @@ func (p *Parlia) VerifyHeaders(chain consensus.ChainHeaderReader, headers []*typ return abort, results } +// getValidatorBytesFromHeader returns the validators bytes extracted from the header's extra field if exists. +// The validators bytes would be contained only in the epoch block's header, and its each validator bytes length is fixed. +// On boneh fork, we introduce vote attestation into the header's extra field, so extra format is different from before. +// Before boneh fork: |---Extra Vanity---|---Validators Bytes (or Empty)---|---Extra Seal---| +// After boneh fork: |---Extra Vanity---|---Validators Number and Validators Bytes (or Empty)---|---Vote Attestation (or Empty)---|---Extra Seal---| +func getValidatorBytesFromHeader(header *types.Header, chainConfig *params.ChainConfig, parliaConfig *params.ParliaConfig) []byte { + if len(header.Extra) <= extraVanity+extraSeal { + return nil + } + + if !chainConfig.IsBoneh(header.Number) { + if header.Number.Uint64()%parliaConfig.Epoch == 0 && (len(header.Extra)-extraSeal-extraVanity)%validatorBytesLengthBeforeBoneh != 0 { + return nil + } + return header.Extra[extraVanity : len(header.Extra)-extraSeal] + } + + if header.Number.Uint64()%parliaConfig.Epoch != 0 { + return nil + } + num := int(header.Extra[extraVanity]) + if num == 0 || len(header.Extra) <= extraVanity+extraSeal+num*validatorBytesLength { + return nil + } + start := extraVanity + validatorNumberSize + end := start + num*validatorBytesLength + return header.Extra[start:end] +} + +// getVoteAttestationFromHeader returns the vote attestation extracted from the header's extra field if exists. +func getVoteAttestationFromHeader(header *types.Header, chainConfig *params.ChainConfig, parliaConfig *params.ParliaConfig) (*types.VoteAttestation, error) { + if len(header.Extra) <= extraVanity+extraSeal { + return nil, nil + } + + if !chainConfig.IsBoneh(header.Number) { + return nil, nil + } + + var attestationBytes []byte + if header.Number.Uint64()%parliaConfig.Epoch != 0 { + attestationBytes = header.Extra[extraVanity : len(header.Extra)-extraSeal] + } else { + num := int(header.Extra[extraVanity]) + if len(header.Extra) <= extraVanity+extraSeal+validatorNumberSize+num*validatorBytesLength { + return nil, nil + } + start := extraVanity + validatorNumberSize + num*validatorBytesLength + end := len(header.Extra) - extraSeal + attestationBytes = header.Extra[start:end] + } + + var attestation types.VoteAttestation + if err := rlp.Decode(bytes.NewReader(attestationBytes), &attestation); err != nil { + return nil, fmt.Errorf("block %d has vote attestation info, decode err: %s", header.Number.Uint64(), err) + } + return &attestation, nil +} + +// verifyVoteAttestation checks whether the vote attestation in the header is valid. +func (p *Parlia) verifyVoteAttestation(chain consensus.ChainHeaderReader, header *types.Header, parents []*types.Header) error { + attestation, err := getVoteAttestationFromHeader(header, p.chainConfig, p.config) + if err != nil { + return err + } + if attestation == nil { + return nil + } + if attestation.Data == nil { + return fmt.Errorf("invalid attestation, vote data is nil") + } + if len(attestation.Extra) > types.MaxAttestationExtraLength { + return fmt.Errorf("invalid attestation, too large extra length: %d", len(attestation.Extra)) + } + + // Get parent block + number := header.Number.Uint64() + var parent *types.Header + if len(parents) > 0 { + parent = parents[len(parents)-1] + } else { + parent = chain.GetHeader(header.ParentHash, number-1) + } + if parent == nil || parent.Hash() != header.ParentHash { + return consensus.ErrUnknownAncestor + } + + // The target block should be direct parent. + targetNumber := attestation.Data.TargetNumber + targetHash := attestation.Data.TargetHash + if targetNumber != parent.Number.Uint64() || targetHash != parent.Hash() { + return fmt.Errorf("invalid attestation, target mismatch, expected block: %d, hash: %s; real block: %d, hash: %s", + parent.Number.Uint64(), parent.Hash(), targetNumber, targetHash) + } + + // The source block should be the highest justified block. + sourceNumber := attestation.Data.SourceNumber + sourceHash := attestation.Data.SourceHash + justifiedBlockNumber, justifiedBlockHash, err := p.GetJustifiedNumberAndHash(chain, parent) + if err != nil { + return fmt.Errorf("unexpected error when getting the highest justified number and hash") + } + if sourceNumber != justifiedBlockNumber || sourceHash != justifiedBlockHash { + return fmt.Errorf("invalid attestation, source mismatch, expected block: %d, hash: %s; real block: %d, hash: %s", + justifiedBlockNumber, justifiedBlockHash, sourceNumber, sourceHash) + } + + // The snapshot should be the targetNumber-1 block's snapshot. + if len(parents) > 1 { + parents = parents[:len(parents)-1] + } else { + parents = nil + } + snap, err := p.snapshot(chain, parent.Number.Uint64()-1, parent.ParentHash, parents) + if err != nil { + return err + } + + // Filter out valid validator from attestation. + validators := snap.validators() + validatorsBitSet := bitset.From([]uint64{uint64(attestation.VoteAddressSet)}) + if validatorsBitSet.Count() > uint(len(validators)) { + return fmt.Errorf("invalid attestation, vote number larger than validators number") + } + votedAddrs := make([]bls.PublicKey, 0, validatorsBitSet.Count()) + for index, val := range validators { + if !validatorsBitSet.Test(uint(index)) { + continue + } + + voteAddr, err := bls.PublicKeyFromBytes(snap.Validators[val].VoteAddress[:]) + if err != nil { + return fmt.Errorf("BLS public key converts failed: %v", err) + } + votedAddrs = append(votedAddrs, voteAddr) + } + + // The valid voted validators should be no less than 2/3 validators. + if len(votedAddrs) < cmath.CeilDiv(len(snap.Validators)*2, 3) { + return fmt.Errorf("invalid attestation, not enough validators voted") + } + + // Verify the aggregated signature. + aggSig, err := bls.SignatureFromBytes(attestation.AggSignature[:]) + if err != nil { + return fmt.Errorf("BLS signature converts failed: %v", err) + } + if !aggSig.FastAggregateVerify(votedAddrs, attestation.Data.Hash()) { + return fmt.Errorf("invalid attestation, signature verify failed") + } + + return nil +} + // verifyHeader checks whether a header conforms to the consensus rules.The // caller may optionally pass in a batch of parents (ascending order) to avoid // looking those up from the database. This is useful for concurrently verifying @@ -325,7 +493,6 @@ func (p *Parlia) verifyHeader(chain consensus.ChainHeaderReader, header *types.H if header.Number == nil { return errUnknownBlock } - number := header.Number.Uint64() // Don't waste time checking blocks from the future if header.Time > uint64(time.Now().Unix()) { @@ -338,16 +505,17 @@ func (p *Parlia) verifyHeader(chain consensus.ChainHeaderReader, header *types.H if len(header.Extra) < extraVanity+extraSeal { return errMissingSignature } + // check extra data + number := header.Number.Uint64() isEpoch := number%p.config.Epoch == 0 // Ensure that the extra-data contains a signer list on checkpoint, but none otherwise - signersBytes := len(header.Extra) - extraVanity - extraSeal - if !isEpoch && signersBytes != 0 { + signersBytes := getValidatorBytesFromHeader(header, p.chainConfig, p.config) + if !isEpoch && len(signersBytes) != 0 { return errExtraValidators } - - if isEpoch && signersBytes%validatorBytesLength != 0 { + if isEpoch && len(signersBytes) == 0 { return errInvalidSpanValidators } @@ -426,11 +594,23 @@ func (p *Parlia) verifyCascadingFields(chain consensus.ChainHeaderReader, header return fmt.Errorf("invalid gas limit: have %d, want %d += %d", header.GasLimit, parent.GasLimit, limit) } + // Verify vote attestation for fast finality. + if err := p.verifyVoteAttestation(chain, header, parents); err != nil { + if chain.Config().IsLynn(header.Number) { + return err + } + log.Warn("Verify vote attestation failed", "error", err, "hash", header.Hash(), "number", header.Number, + "parent", header.ParentHash, "coinbase", header.Coinbase, "extra", common.Bytes2Hex(header.Extra)) + } + // All basic checks passed, verify the seal and return return p.verifySeal(chain, header, parents) } // snapshot retrieves the authorization snapshot at a given point in time. +// !!! be careful +// the block with `number` and `hash` is just the last element of `parents`, +// unlike other interfaces such as verifyCascadingFields, `parents` are real parents func (p *Parlia) snapshot(chain consensus.ChainHeaderReader, number uint64, hash common.Hash, parents []*types.Header) (*Snapshot, error) { // Search for a snapshot in memory or on disk for checkpoints var ( @@ -463,18 +643,14 @@ func (p *Parlia) snapshot(chain consensus.ChainHeaderReader, number uint64, hash // get checkpoint data hash := checkpoint.Hash() - if len(checkpoint.Extra) <= extraVanity+extraSeal { - return nil, errors.New("invalid extra-data for genesis block, check the genesis.json file") - } - validatorBytes := checkpoint.Extra[extraVanity : len(checkpoint.Extra)-extraSeal] // get validators from headers - validators, err := ParseValidators(validatorBytes) + validators, voteAddrs, err := parseValidators(checkpoint, p.chainConfig, p.config) if err != nil { return nil, err } - // new snap shot - snap = newSnapshot(p.config, p.signatures, number, hash, validators, p.ethAPI) + // new snapshot + snap = newSnapshot(p.config, p.signatures, number, hash, validators, voteAddrs, p.ethAPI) if err := snap.store(p.db); err != nil { return nil, err } @@ -513,7 +689,15 @@ func (p *Parlia) snapshot(chain consensus.ChainHeaderReader, number uint64, hash headers[i], headers[len(headers)-1-i] = headers[len(headers)-1-i], headers[i] } - snap, err := snap.apply(headers, chain, parents, p.chainConfig.ChainID) + verifiedAttestations := make(map[common.Hash]struct{}, len(headers)) + for index, header := range headers { + // vote attestation should be checked here to decide whether to update attestation of snapshot between [Boneh,Lynn) + // because err of verifyVoteAttestation is ignored when importing blocks and headers before Lynn. + if p.chainConfig.IsBoneh(header.Number) && !p.chainConfig.IsLynn(header.Number) && p.verifyVoteAttestation(chain, header, headers[:index]) == nil { + verifiedAttestations[header.Hash()] = struct{}{} + } + } + snap, err := snap.apply(headers, chain, parents, p.chainConfig, verifiedAttestations) if err != nil { return nil, err } @@ -597,6 +781,109 @@ func (p *Parlia) verifySeal(chain consensus.ChainHeaderReader, header *types.Hea return nil } +func (p *Parlia) prepareValidators(header *types.Header) error { + if header.Number.Uint64()%p.config.Epoch != 0 { + return nil + } + + newValidators, voteAddressMap, err := p.getCurrentValidators(header.ParentHash, new(big.Int).Sub(header.Number, big.NewInt(1))) + if err != nil { + return err + } + // sort validator by address + sort.Sort(validatorsAscending(newValidators)) + if !p.chainConfig.IsBoneh(header.Number) { + for _, validator := range newValidators { + header.Extra = append(header.Extra, validator.Bytes()...) + } + } else { + header.Extra = append(header.Extra, byte(len(newValidators))) + for _, validator := range newValidators { + header.Extra = append(header.Extra, validator.Bytes()...) + header.Extra = append(header.Extra, voteAddressMap[validator].Bytes()...) + } + } + return nil +} + +func (p *Parlia) assembleVoteAttestation(chain consensus.ChainHeaderReader, header *types.Header) error { + if !p.chainConfig.IsBoneh(header.Number) || header.Number.Uint64() < 2 { + return nil + } + + if p.VotePool == nil { + return errors.New("vote pool is nil") + } + + // Fetch direct parent's votes + parent := chain.GetHeaderByHash(header.ParentHash) + if parent == nil { + return errors.New("parent not found") + } + snap, err := p.snapshot(chain, parent.Number.Uint64()-1, parent.ParentHash, nil) + if err != nil { + return err + } + votes := p.VotePool.FetchVoteByBlockHash(parent.Hash()) + if len(votes) < cmath.CeilDiv(len(snap.Validators)*2, 3) { + return nil + } + + // Prepare vote attestation + // Prepare vote data + justifiedBlockNumber, justifiedBlockHash, err := p.GetJustifiedNumberAndHash(chain, parent) + if err != nil { + return fmt.Errorf("unexpected error when getting the highest justified number and hash") + } + attestation := &types.VoteAttestation{ + Data: &types.VoteData{ + SourceNumber: justifiedBlockNumber, + SourceHash: justifiedBlockHash, + TargetNumber: parent.Number.Uint64(), + TargetHash: parent.Hash(), + }, + } + // Check vote data from votes + for _, vote := range votes { + if vote.Data.Hash() != attestation.Data.Hash() { + return fmt.Errorf("vote check error, expected: %v, real: %v", attestation.Data, vote) + } + } + // Prepare aggregated vote signature + voteAddrSet := make(map[types.BLSPublicKey]struct{}, len(votes)) + signatures := make([][]byte, 0, len(votes)) + for _, vote := range votes { + voteAddrSet[vote.VoteAddress] = struct{}{} + signatures = append(signatures, vote.Signature[:]) + } + sigs, err := bls.MultipleSignaturesFromBytes(signatures) + if err != nil { + return err + } + copy(attestation.AggSignature[:], bls.AggregateSignatures(sigs).Marshal()) + // Prepare vote address bitset. + for _, valInfo := range snap.Validators { + if _, ok := voteAddrSet[valInfo.VoteAddress]; ok { + attestation.VoteAddressSet |= 1 << (valInfo.Index - 1) //Index is offset by 1 + } + } + + // Append attestation to header extra field. + buf := new(bytes.Buffer) + err = rlp.Encode(buf, attestation) + if err != nil { + return err + } + + // Insert vote attestation into header extra ahead extra seal. + extraSealStart := len(header.Extra) - extraSeal + extraSealBytes := header.Extra[extraSealStart:] + header.Extra = append(header.Extra[0:extraSealStart], buf.Bytes()...) + header.Extra = append(header.Extra, extraSealBytes...) + + return nil +} + // Prepare implements consensus.Engine, preparing all the consensus fields of the // header for running the transactions on top. func (p *Parlia) Prepare(chain consensus.ChainHeaderReader, header *types.Header) error { @@ -620,16 +907,8 @@ func (p *Parlia) Prepare(chain consensus.ChainHeaderReader, header *types.Header nextForkHash := forkid.NextForkHash(p.chainConfig, p.genesisHash, number) header.Extra = append(header.Extra, nextForkHash[:]...) - if number%p.config.Epoch == 0 { - newValidators, err := p.getCurrentValidators(header.ParentHash, new(big.Int).Sub(header.Number, common.Big1)) - if err != nil { - return err - } - // sort validator by address - sort.Sort(validatorsAscending(newValidators)) - for _, validator := range newValidators { - header.Extra = append(header.Extra, validator.Bytes()...) - } + if err := p.prepareValidators(header); err != nil { + return err } // add extra seal space @@ -650,6 +929,114 @@ func (p *Parlia) Prepare(chain consensus.ChainHeaderReader, header *types.Header return nil } +func (p *Parlia) verifyValidators(header *types.Header) error { + if header.Number.Uint64()%p.config.Epoch != 0 { + return nil + } + + newValidators, voteAddressMap, err := p.getCurrentValidators(header.ParentHash, new(big.Int).Sub(header.Number, big.NewInt(1))) + if err != nil { + return err + } + // sort validator by address + sort.Sort(validatorsAscending(newValidators)) + var validatorsBytes []byte + validatorsNumber := len(newValidators) + if !p.chainConfig.IsBoneh(header.Number) { + validatorsBytes = make([]byte, validatorsNumber*validatorBytesLengthBeforeBoneh) + for i, validator := range newValidators { + copy(validatorsBytes[i*validatorBytesLengthBeforeBoneh:], validator.Bytes()) + } + } else { + if uint8(validatorsNumber) != header.Extra[extraVanity] { + return errMismatchingEpochValidators + } + validatorsBytes = make([]byte, validatorsNumber*validatorBytesLength) + for i, validator := range newValidators { + copy(validatorsBytes[i*validatorBytesLength:], validator.Bytes()) + copy(validatorsBytes[i*validatorBytesLength+common.AddressLength:], voteAddressMap[validator].Bytes()) + } + } + if !bytes.Equal(getValidatorBytesFromHeader(header, p.chainConfig, p.config), validatorsBytes) { + return errMismatchingEpochValidators + } + return nil +} + +func (p *Parlia) distributeFinalityReward(chain consensus.ChainHeaderReader, state *state.StateDB, header *types.Header, + cx core.ChainContext, txs *[]*types.Transaction, receipts *[]*types.Receipt, systemTxs *[]*types.Transaction, + usedGas *uint64, mining bool) error { + currentHeight := header.Number.Uint64() + epoch := p.config.Epoch + chainConfig := chain.Config() + if currentHeight%epoch != 0 { + return nil + } + + head := header + accumulatedWeights := make(map[common.Address]uint64) + for height := currentHeight - 1; height+epoch >= currentHeight && height >= 1; height-- { + head = chain.GetHeaderByHash(head.ParentHash) + if head == nil { + return fmt.Errorf("header is nil at height %d", height) + } + voteAttestation, err := getVoteAttestationFromHeader(head, chainConfig, p.config) + if err != nil { + return err + } + if voteAttestation == nil { + continue + } + justifiedBlock := chain.GetHeaderByHash(voteAttestation.Data.TargetHash) + if justifiedBlock == nil { + log.Warn("justifiedBlock is nil at height %d", voteAttestation.Data.TargetNumber) + continue + } + + snap, err := p.snapshot(chain, justifiedBlock.Number.Uint64()-1, justifiedBlock.ParentHash, nil) + if err != nil { + return err + } + validators := snap.validators() + validatorsBitSet := bitset.From([]uint64{uint64(voteAttestation.VoteAddressSet)}) + if validatorsBitSet.Count() > uint(len(validators)) { + log.Error("invalid attestation, vote number larger than validators number") + continue + } + validVoteCount := 0 + for index, val := range validators { + if validatorsBitSet.Test(uint(index)) { + accumulatedWeights[val] += 1 + validVoteCount += 1 + } + } + quorum := cmath.CeilDiv(len(snap.Validators)*2, 3) + if validVoteCount > quorum { + accumulatedWeights[head.Coinbase] += uint64(float64(validVoteCount-quorum) * collectAdditionalVotesRewardRatio) + } + } + + validators := make([]common.Address, 0, len(accumulatedWeights)) + weights := make([]*big.Int, 0, len(accumulatedWeights)) + for val := range accumulatedWeights { + validators = append(validators, val) + } + sort.Sort(validatorsAscending(validators)) + for _, val := range validators { + weights = append(weights, big.NewInt(int64(accumulatedWeights[val]))) + } + + // generate system transaction + method := "distributeFinalityReward" + data, err := p.validatorSetABI.Pack(method, validators, weights) + if err != nil { + log.Error("Unable to pack tx for distributeFinalityReward", "error", err) + return err + } + msg := p.getSystemMessage(header.Coinbase, common.HexToAddress(systemcontracts.ValidatorContract), data, common.Big0) + return p.applyTransaction(msg, state, header, cx, txs, receipts, systemTxs, usedGas, mining) +} + // Finalize implements consensus.Engine, ensuring no uncles are set, nor block // rewards given. func (p *Parlia) Finalize(chain consensus.ChainHeaderReader, header *types.Header, state *state.StateDB, txs *[]*types.Transaction, @@ -664,27 +1051,15 @@ func (p *Parlia) Finalize(chain consensus.ChainHeaderReader, header *types.Heade if !snap.isMajorityFork(hex.EncodeToString(nextForkHash[:])) { log.Debug("there is a possible fork, and your client is not the majority. Please check...", "nextForkHash", hex.EncodeToString(nextForkHash[:])) } - // If the block is a epoch end block, verify the validator list + // If the block is an epoch end block, verify the validator list // The verification can only be done when the state is ready, it can't be done in VerifyHeader. - if header.Number.Uint64()%p.config.Epoch == 0 { - newValidators, err := p.getCurrentValidators(header.ParentHash, new(big.Int).Sub(header.Number, common.Big1)) - if err != nil { - return err - } - // sort validator by address - sort.Sort(validatorsAscending(newValidators)) - validatorsBytes := make([]byte, len(newValidators)*validatorBytesLength) - for i, validator := range newValidators { - copy(validatorsBytes[i*validatorBytesLength:], validator.Bytes()) - } - - extraSuffix := len(header.Extra) - extraSeal - if !bytes.Equal(header.Extra[extraVanity:extraSuffix], validatorsBytes) { - return errMismatchingEpochValidators - } + if err := p.verifyValidators(header); err != nil { + return err } - // No block rewards in PoA, so the state remains as is and uncles are dropped + cx := chainContext{Chain: chain, parlia: p} + + // No block rewards in PoA, so the state remains as is and uncles are dropped if header.Number.Cmp(common.Big1) == 0 { err := p.initContract(state, header, cx, txs, receipts, systemTxs, usedGas, false) if err != nil { @@ -714,6 +1089,12 @@ func (p *Parlia) Finalize(chain consensus.ChainHeaderReader, header *types.Heade if err != nil { return err } + + if p.chainConfig.IsLynn(header.Number) { + if err := p.distributeFinalityReward(chain, state, header, cx, txs, receipts, systemTxs, usedGas, false); err != nil { + return err + } + } if len(*systemTxs) > 0 { return errors.New("the length of systemTxs do not match") } @@ -760,10 +1141,18 @@ func (p *Parlia) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header * } } } + err := p.distributeIncoming(p.val, state, header, cx, &txs, &receipts, nil, &header.GasUsed, true) if err != nil { return nil, nil, err } + + if p.chainConfig.IsLynn(header.Number) { + if err := p.distributeFinalityReward(chain, state, header, cx, &txs, &receipts, nil, &header.GasUsed, true); err != nil { + return nil, nil, err + } + } + // should not happen. Once happen, stop the node is better than broadcast the block if header.GasLimit < header.GasUsed { return nil, nil, errors.New("gas consumption of system txs exceed the gas limit") @@ -787,6 +1176,59 @@ func (p *Parlia) FinalizeAndAssemble(chain consensus.ChainHeaderReader, header * return blk, receipts, nil } +func (p *Parlia) IsActiveValidatorAt(chain consensus.ChainHeaderReader, header *types.Header) bool { + number := header.Number.Uint64() + snap, err := p.snapshot(chain, number-1, header.ParentHash, nil) + if err != nil { + log.Error("failed to get the snapshot from consensus", "error", err) + return false + } + validators := snap.Validators + _, ok := validators[p.val] + return ok +} + +// VerifyVote will verify: 1. If the vote comes from valid validators 2. If the vote's sourceNumber and sourceHash are correct +func (p *Parlia) VerifyVote(chain consensus.ChainHeaderReader, vote *types.VoteEnvelope) error { + targetNumber := vote.Data.TargetNumber + targetHash := vote.Data.TargetHash + header := chain.GetHeaderByHash(targetHash) + if header == nil { + log.Warn("BlockHeader at current voteBlockNumber is nil", "targetNumber", targetNumber, "targetHash", targetHash) + return fmt.Errorf("BlockHeader at current voteBlockNumber is nil") + } + if header.Number.Uint64() != targetNumber { + log.Warn("unexpected target number", "expect", header.Number.Uint64(), "real", targetNumber) + return fmt.Errorf("target number mismatch") + } + + justifiedBlockNumber, justifiedBlockHash, err := p.GetJustifiedNumberAndHash(chain, header) + if err != nil { + log.Error("failed to get the highest justified number and hash", "headerNumber", header.Number, "headerHash", header.Hash()) + return fmt.Errorf("unexpected error when getting the highest justified number and hash") + } + if vote.Data.SourceNumber != justifiedBlockNumber || vote.Data.SourceHash != justifiedBlockHash { + return fmt.Errorf("vote source block mismatch") + } + + number := header.Number.Uint64() + snap, err := p.snapshot(chain, number-1, header.ParentHash, nil) + if err != nil { + log.Error("failed to get the snapshot from consensus", "error", err) + return fmt.Errorf("failed to get the snapshot from consensus") + } + + validators := snap.Validators + voteAddress := vote.VoteAddress + for _, validator := range validators { + if validator.VoteAddress == voteAddress { + return nil + } + } + + return fmt.Errorf("vote verification failed") +} + // Authorize injects a private key into the consensus engine to mint new blocks // with. func (p *Parlia) Authorize(val common.Address, signFn SignerFn, signTxFn SignerTxFn) { @@ -871,13 +1313,6 @@ func (p *Parlia) Seal(chain consensus.ChainHeaderReader, block *types.Block, res log.Info("Sealing block with", "number", number, "delay", delay, "headerDifficulty", header.Difficulty, "val", val.Hex()) - // Sign all the things! - sig, err := signFn(accounts.Account{Address: val}, accounts.MimetypeParlia, ParliaRLP(header, p.chainConfig.ChainID)) - if err != nil { - return err - } - copy(header.Extra[len(header.Extra)-extraSeal:], sig) - // Wait until sealing is terminated or delay timeout. log.Trace("Waiting for slot to sign and propagate", "delay", common.PrettyDuration(delay)) go func() { @@ -886,6 +1321,22 @@ func (p *Parlia) Seal(chain consensus.ChainHeaderReader, block *types.Block, res return case <-time.After(delay): } + + err := p.assembleVoteAttestation(chain, header) + if err != nil { + /* If the vote attestation can't be assembled successfully, the blockchain won't get + fast finalized, but it can be tolerated, so just report this error here. */ + log.Error("Assemble vote attestation failed when sealing", "err", err) + } + + // Sign all the things! + sig, err := signFn(accounts.Account{Address: val}, accounts.MimetypeParlia, ParliaRLP(header, p.chainConfig.ChainID)) + if err != nil { + log.Error("Sign for the block header failed when sealing", "err", err) + return + } + copy(header.Extra[len(header.Extra)-extraSeal:], sig) + if p.shouldWaitForCurrentBlockProcess(chain, header, snap) { log.Info("Waiting for received in turn block to process") select { @@ -964,11 +1415,13 @@ func (p *Parlia) SignRecently(chain consensus.ChainReader, parent *types.Block) // If we're amongst the recent signers, wait for the next block number := parent.NumberU64() + 1 for seen, recent := range snap.Recents { - if recent == p.val { - // Signer is among recents, only wait if the current block doesn't shift it out - if limit := uint64(len(snap.Validators)/2 + 1); number < limit || seen > number-limit { - return true, nil - } + if recent != p.val { + continue + } + + // Signer is among recents, only wait if the current block doesn't shift it out + if limit := uint64(len(snap.Validators)/2 + 1); number < limit || seen > number-limit { + return true, nil } } return false, nil @@ -995,9 +1448,13 @@ func CalcDifficulty(snap *Snapshot, signer common.Address) *big.Int { return new(big.Int).Set(diffNoTurn) } -// SealHash returns the hash of a block prior to it being sealed. -func (p *Parlia) SealHash(header *types.Header) common.Hash { - return SealHash(header, p.chainConfig.ChainID) +// SealHash returns the hash of a block without vote attestation prior to it being sealed. +// So it's not the real hash of a block, just used as unique id to distinguish task +func (p *Parlia) SealHash(header *types.Header) (hash common.Hash) { + hasher := sha3.NewLegacyKeccak256() + encodeSigHeaderWithoutVoteAttestation(hasher, header, p.chainConfig.ChainID) + hasher.Sum(hash[:0]) + return hash } // APIs implements consensus.Engine, returning the user facing RPC API to query snapshot. @@ -1018,23 +1475,25 @@ func (p *Parlia) Close() error { // ========================== interaction with contract/account ========= // getCurrentValidators get current validators -func (p *Parlia) getCurrentValidators(blockHash common.Hash, blockNumber *big.Int) ([]common.Address, error) { +func (p *Parlia) getCurrentValidators(blockHash common.Hash, blockNum *big.Int) ([]common.Address, map[common.Address]*types.BLSPublicKey, error) { // block blockNr := rpc.BlockNumberOrHashWithHash(blockHash, false) - // method - method := "getValidators" - if p.chainConfig.IsEuler(blockNumber) { - method = "getMiningValidators" + if !p.chainConfig.IsBoneh(blockNum) { + validators, err := p.getCurrentValidatorsBeforeBoneh(blockHash, blockNum) + return validators, nil, err } + // method + method := "getMiningValidators" + ctx, cancel := context.WithCancel(context.Background()) defer cancel() // cancel when we are finished consuming integers data, err := p.validatorSetABI.Pack(method) if err != nil { - log.Error("Unable to pack tx for getValidators", "error", err) - return nil, err + log.Error("Unable to pack tx for getMiningValidators", "error", err) + return nil, nil, err } // call msgData := (hexutil.Bytes)(data) @@ -1046,24 +1505,21 @@ func (p *Parlia) getCurrentValidators(blockHash common.Hash, blockNumber *big.In Data: &msgData, }, blockNr, nil) if err != nil { - return nil, err + return nil, nil, err } - var ( - ret0 = new([]common.Address) - ) - out := ret0 + var valSet []common.Address + var voteAddrSet []types.BLSPublicKey - if err := p.validatorSetABI.UnpackIntoInterface(out, method, result); err != nil { - return nil, err + if err := p.validatorSetABI.UnpackIntoInterface(&[]interface{}{&valSet, &voteAddrSet}, method, result); err != nil { + return nil, nil, err } - valz := make([]common.Address, len(*ret0)) - // nolint: gosimple - for i, a := range *ret0 { - valz[i] = a + voteAddrmap := make(map[common.Address]*types.BLSPublicKey, len(valSet)) + for i := 0; i < len(valSet); i++ { + voteAddrmap[valSet[i]] = &(voteAddrSet)[i] } - return valz, nil + return valSet, voteAddrmap, nil } // slash spoiled validators @@ -1254,6 +1710,65 @@ func (p *Parlia) applyTransaction( return nil } +// GetJustifiedNumberAndHash returns the highest justified block's number and hash on the branch including and before `header` +func (p *Parlia) GetJustifiedNumberAndHash(chain consensus.ChainHeaderReader, header *types.Header) (uint64, common.Hash, error) { + if chain == nil || header == nil { + return 0, common.Hash{}, fmt.Errorf("illegal chain or header") + } + snap, err := p.snapshot(chain, header.Number.Uint64(), header.Hash(), nil) + if err != nil { + log.Error("Unexpected error when getting snapshot", + "error", err, "blockNumber", header.Number.Uint64(), "blockHash", header.Hash()) + return 0, common.Hash{}, err + } + + if snap.Attestation == nil { + if p.chainConfig.IsBoneh(header.Number) { + log.Debug("once one attestation generated, attestation of snap would not be nil forever basically") + } + return 0, chain.GetHeaderByNumber(0).Hash(), nil + } + return snap.Attestation.TargetNumber, snap.Attestation.TargetHash, nil +} + +// GetFinalizedHeader returns highest finalized block header. +// It will find vote finalized block within NaturallyFinalizedDist blocks firstly, +// If the vote finalized block not found, return its naturally finalized block. +func (p *Parlia) GetFinalizedHeader(chain consensus.ChainHeaderReader, header *types.Header) *types.Header { + backward := uint64(types.NaturallyFinalizedDist) + if chain == nil || header == nil { + return nil + } + if !chain.Config().IsLynn(header.Number) { + return chain.GetHeaderByNumber(0) + } + if header.Number.Uint64() < backward { + backward = header.Number.Uint64() + } + + snap, err := p.snapshot(chain, header.Number.Uint64(), header.Hash(), nil) + if err != nil { + log.Error("Unexpected error when getting snapshot", + "error", err, "blockNumber", header.Number.Uint64(), "blockHash", header.Hash()) + return nil + } + + for snap.Attestation != nil && snap.Attestation.SourceNumber >= header.Number.Uint64()-backward { + if snap.Attestation.TargetNumber == snap.Attestation.SourceNumber+1 { + return chain.GetHeaderByHash(snap.Attestation.SourceHash) + } + + snap, err = p.snapshot(chain, snap.Attestation.SourceNumber, snap.Attestation.SourceHash, nil) + if err != nil { + log.Error("Unexpected error when getting snapshot", + "error", err, "blockNumber", snap.Attestation.SourceNumber, "blockHash", snap.Attestation.SourceHash) + return nil + } + } + + return FindAncientHeader(header, backward, chain, nil) +} + // =========================== utility function ========================== // SealHash returns the hash of a block prior to it being sealed. func SealHash(header *types.Header, chainId *big.Int) (hash common.Hash) { @@ -1287,6 +1802,30 @@ func encodeSigHeader(w io.Writer, header *types.Header, chainId *big.Int) { } } +func encodeSigHeaderWithoutVoteAttestation(w io.Writer, header *types.Header, chainId *big.Int) { + err := rlp.Encode(w, []interface{}{ + chainId, + header.ParentHash, + header.UncleHash, + header.Coinbase, + header.Root, + header.TxHash, + header.ReceiptHash, + header.Bloom, + header.Difficulty, + header.Number, + header.GasLimit, + header.GasUsed, + header.Time, + header.Extra[:extraVanity], // this will panic if extra is too short, should check before calling encodeSigHeaderWithoutVoteAttestation + header.MixDigest, + header.Nonce, + }) + if err != nil { + panic("can't encode: " + err.Error()) + } +} + func (p *Parlia) backOffTime(snap *Snapshot, header *types.Header, val common.Address) uint64 { if snap.inturn(val) { return 0 diff --git a/consensus/parlia/parlia_test.go b/consensus/parlia/parlia_test.go index fc05013e92..6442f16466 100644 --- a/consensus/parlia/parlia_test.go +++ b/consensus/parlia/parlia_test.go @@ -5,7 +5,16 @@ import ( "math/rand" "testing" + "golang.org/x/crypto/sha3" + "github.com/ethereum/go-ethereum/common" + cmath "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" +) + +const ( + upperLimitOfVoteBlockNumber = 11 ) func TestImpactOfValidatorOutOfService(t *testing.T) { @@ -144,3 +153,449 @@ func randomAddress() common.Address { rand.Read(addrBytes) return common.BytesToAddress(addrBytes) } + +// ========================================================================= +// ======= Simulator P2P network to verify fast finality ============ +// ========================================================================= + +type MockBlock struct { + parent *MockBlock + + blockNumber uint64 + blockHash common.Hash + coinbase *MockValidator + td uint64 // Total difficulty from genesis block to current block + attestation uint64 // Vote attestation for parent block, zero means no attestation +} + +var GenesisBlock = &MockBlock{ + parent: nil, + blockNumber: 0, + blockHash: common.Hash{}, + coinbase: nil, + td: diffInTurn.Uint64(), + attestation: 0, +} + +func (b *MockBlock) Hash() (hash common.Hash) { + hasher := sha3.NewLegacyKeccak256() + rlp.Encode(hasher, []interface{}{ + b.parent, + b.blockNumber, + b.coinbase, + b.td, + b.attestation, + }) + hasher.Sum(hash[:0]) + return hash +} + +func (b *MockBlock) IsConflicted(a *MockBlock) bool { + if a.blockNumber > b.blockNumber { + p := a.parent + for ; p.blockNumber > b.blockNumber; p = p.parent { + } + + return p.blockHash != b.blockHash + } + + if a.blockNumber < b.blockNumber { + p := b.parent + for ; p.blockNumber > a.blockNumber; p = p.parent { + } + + return p.blockHash != a.blockHash + } + + return a.blockHash != b.blockHash +} + +// GetJustifiedNumberAndHash returns number and hash of the highest justified block, +// keep same func signature with consensus even if `error` will be nil definitely +func (b *MockBlock) GetJustifiedNumberAndHash() (uint64, common.Hash, error) { + justifiedBlock := GenesisBlock + for curBlock := b; curBlock.blockNumber > 1; curBlock = curBlock.parent { + // justified + if curBlock.attestation != 0 { + justifiedBlock = curBlock.parent + break + } + + } + + return justifiedBlock.blockNumber, justifiedBlock.blockHash, nil +} + +func (b *MockBlock) GetJustifiedNumber() uint64 { + justifiedBlockNumber, _, _ := b.GetJustifiedNumberAndHash() + return justifiedBlockNumber +} + +// GetFinalizedBlock returns highest finalized block, +// include current block's attestation. +func (b *MockBlock) GetFinalizedBlock() *MockBlock { + if b.blockNumber < 3 { + return GenesisBlock + } + + if b.attestation != 0 && b.parent.attestation != 0 { + return b.parent.parent + } + + return b.parent.GetFinalizedBlock() +} + +type MockValidator struct { + index int + validatorSet int // validators number + head *MockBlock + voteRecords map[uint64]*types.VoteData +} + +func NewMockValidator(index int, validatorSet int) *MockValidator { + v := &MockValidator{ + index: index, + validatorSet: validatorSet, + head: GenesisBlock, + voteRecords: make(map[uint64]*types.VoteData), + } + return v +} + +func (v *MockValidator) SignRecently() bool { + parent := v.head + for i := 0; i < v.validatorSet*1/2; i++ { + if parent.blockNumber == 0 { + return false + } + + if parent.coinbase == v { + return true + } + + parent = parent.parent + } + + return false +} + +func (v *MockValidator) Produce(attestation uint64) (*MockBlock, error) { + if v.SignRecently() { + return nil, fmt.Errorf("v %d sign recently", v.index) + } + + block := &MockBlock{ + parent: v.head, + blockNumber: v.head.blockNumber + 1, + coinbase: v, + td: v.head.td + 1, + attestation: attestation, + } + + if (block.blockNumber-1)%uint64(v.validatorSet) == uint64(v.index) { + block.td = v.head.td + 2 + } + + block.blockHash = block.Hash() + return block, nil +} + +func (v *MockValidator) Vote(block *MockBlock) bool { + // Rule 3: The block should be the latest block of canonical chain + if block != v.head { + return false + } + + // Rule 1: No double vote + if _, ok := v.voteRecords[block.blockNumber]; ok { + return false + } + + // Rule 2: No surround vote + justifiedBlockNumber, justifiedBlockHash, _ := block.GetJustifiedNumberAndHash() + for targetNumber := justifiedBlockNumber + 1; targetNumber < block.blockNumber; targetNumber++ { + if vote, ok := v.voteRecords[targetNumber]; ok { + if vote.SourceNumber > justifiedBlockNumber { + return false + } + } + } + for targetNumber := block.blockNumber; targetNumber <= block.blockNumber+upperLimitOfVoteBlockNumber; targetNumber++ { + if vote, ok := v.voteRecords[targetNumber]; ok { + if vote.SourceNumber < justifiedBlockNumber { + return false + } + } + } + + v.voteRecords[block.blockNumber] = &types.VoteData{ + SourceNumber: justifiedBlockNumber, + SourceHash: justifiedBlockHash, + TargetNumber: block.blockNumber, + TargetHash: block.blockHash, + } + return true +} + +func (v *MockValidator) InsertBlock(block *MockBlock) { + // Reject block too old. + if block.blockNumber+13 < v.head.blockNumber { + return + } + + // The higher justified block is the longest chain. + if block.GetJustifiedNumber() < v.head.GetJustifiedNumber() { + return + } + if block.GetJustifiedNumber() > v.head.GetJustifiedNumber() { + v.head = block + return + } + + // The same finalized number, the larger difficulty is the longest chain. + if block.td > v.head.td { + v.head = block + } +} + +type BlockSimulator struct { + blockNumber uint64 + coinbaseIndex int + voteMap uint64 + insertMap uint64 +} + +type ChainSimulator []*BlockSimulator + +func (s ChainSimulator) Valid() bool { + var pre *BlockSimulator + for index, bs := range s { + if index == 0 { + if bs.blockNumber != 1 { + return false + } + } else { + if bs.blockNumber != pre.blockNumber+1 { + return false + } + } + + pre = bs + } + return true +} + +type Coordinator struct { + validators []*MockValidator + attestations map[common.Hash]uint64 +} + +func NewCoordinator(validatorsNumber int) *Coordinator { + validators := make([]*MockValidator, validatorsNumber) + for i := 0; i < validatorsNumber; i++ { + validators[i] = NewMockValidator(i, validatorsNumber) + } + + return &Coordinator{ + validators: validators, + attestations: make(map[common.Hash]uint64), + } +} + +// SimulateP2P simulate a P2P network +func (c *Coordinator) SimulateP2P(cs ChainSimulator) error { + for _, bs := range cs { + parent := c.validators[bs.coinbaseIndex].head + if bs.blockNumber != parent.blockNumber+1 { + return fmt.Errorf("can't produce discontinuous block, head block: %d, expect produce: %d", parent.blockNumber, bs.blockNumber) + } + attestation := c.attestations[parent.blockHash] + block, err := c.validators[bs.coinbaseIndex].Produce(attestation) + if err != nil { + return fmt.Errorf("produce block %v error %v", bs, err) + } + + c.PropagateBlock(bs, block) + err = c.AggregateVotes(bs, block) + if err != nil { + return err + } + } + + return nil +} + +func (c *Coordinator) AggregateVotes(bs *BlockSimulator, block *MockBlock) error { + var attestation uint64 + count := 0 + for index, voteMap := 0, bs.voteMap; voteMap > 0; index, voteMap = index+1, voteMap>>1 { + if voteMap&0x1 == 0 { + continue + } + + if !c.validators[index].Vote(block) { + return fmt.Errorf("validator(%d) couldn't vote for block %d produced by validator(%d)", index, block.blockNumber, block.coinbase.index) + } + attestation |= 1 << index + count++ + } + + if count >= cmath.CeilDiv(len(c.validators)*2, 3) { + c.attestations[block.blockHash] = attestation + } + + return nil +} + +func (c *Coordinator) PropagateBlock(bs *BlockSimulator, block *MockBlock) { + for index, insertMap := 0, bs.insertMap; insertMap > 0; index, insertMap = index+1, insertMap>>1 { + if insertMap&0x1 == 0 { + continue + } + + c.validators[index].InsertBlock(block) + } +} + +func (c *Coordinator) CheckChain() bool { + // All validators highest finalized block should not be conflicted + finalizedBlocks := make([]*MockBlock, len(c.validators)) + for index, val := range c.validators { + finalizedBlocks[index] = val.head.GetFinalizedBlock() + } + + for i := 0; i < len(finalizedBlocks)-1; i++ { + for j := i + 1; j < len(finalizedBlocks); j++ { + if finalizedBlocks[i].IsConflicted(finalizedBlocks[j]) { + return false + } + } + } + + return true +} + +type TestSimulatorParam struct { + validatorsNumber int + cs ChainSimulator +} + +var simulatorTestcases = []*TestSimulatorParam{ + { + // 3 validators, all active + validatorsNumber: 3, + cs: []*BlockSimulator{ + {1, 0, 0x7, 0x7}, + {2, 1, 0x7, 0x7}, + {3, 2, 0x7, 0x7}, + {4, 0, 0x7, 0x7}, + {5, 1, 0x7, 0x7}, + }, + }, + { + // 5 validators, 4 active, 1 down + validatorsNumber: 5, + cs: []*BlockSimulator{ + {1, 0, 0x1f, 0x1f}, + {2, 1, 0x1f, 0x1f}, + {3, 2, 0x1f, 0x1f}, + {4, 3, 0x1f, 0x1f}, + {5, 0, 0x1f, 0x1f}, + {6, 1, 0x1f, 0x1f}, + {7, 2, 0x1f, 0x1f}, + }, + }, + { + // 21 validators, all active + validatorsNumber: 21, + cs: []*BlockSimulator{ + {1, 0, 0x1fffff, 0x1fffff}, + {2, 1, 0x1fffff, 0x1fffff}, + {3, 2, 0x1fffff, 0x1fffff}, + {4, 3, 0x1fffff, 0x1fffff}, + {5, 4, 0x1fffff, 0x1fffff}, + {6, 5, 0x1fffff, 0x1fffff}, + {7, 6, 0x1fffff, 0x1fffff}, + {8, 7, 0x1fffff, 0x1fffff}, + {9, 8, 0x1fffff, 0x1fffff}, + {10, 9, 0x1fffff, 0x1fffff}, + {11, 10, 0x1fffff, 0x1fffff}, + {12, 11, 0x1fffff, 0x1fffff}, + {13, 12, 0x1fffff, 0x1fffff}, + {14, 13, 0x1fffff, 0x1fffff}, + {15, 14, 0x1fffff, 0x1fffff}, + {16, 0, 0x1fffff, 0x1fffff}, + {17, 1, 0x1fffff, 0x1fffff}, + {18, 2, 0x1fffff, 0x1fffff}, + }, + }, + { + // 21 validators, all active, the finalized fork can keep grow + validatorsNumber: 21, + cs: []*BlockSimulator{ + {1, 1, 0x00fffe, 0x00fffe}, + {2, 2, 0x00fffe, 0x00fffe}, + {1, 0, 0x1f0001, 0x1fffff}, + {2, 16, 0x1f0001, 0x1ffff1}, + {3, 17, 0x1f0001, 0x1ffff1}, + {4, 18, 0x1f0001, 0x1ffff1}, + {5, 19, 0x1f0001, 0x1ffff1}, + {3, 3, 0x00fffe, 0x00fffe}, // justify block 2 and finalize block 1 + {6, 20, 0x1f0001, 0x1fffff}, + {4, 4, 0x00fffe, 0x1fffff}, + {5, 5, 0x00fffe, 0x1fffff}, + {6, 6, 0x00fffe, 0x1fffff}, + {7, 7, 0x1fffff, 0x1fffff}, + {8, 8, 0x1fffff, 0x1fffff}, + }, + }, + { + // 21 validators, all active, the finalized fork can keep grow + validatorsNumber: 21, + cs: []*BlockSimulator{ + {1, 14, 0x00fffe, 0x00fffe}, + {2, 15, 0x00fffe, 0x00fffe}, // The block 3 will never produce + {1, 0, 0x1f0001, 0x1fffff}, + {2, 16, 0x1f0001, 0x1fffff}, + {3, 1, 0x1f0001, 0x1fffff}, // based block produced by 15 + {4, 2, 0x1f0001, 0x1fffff}, + {5, 3, 0x1f0001, 0x1fffff}, + {6, 4, 0x1f0001, 0x1fffff}, + {7, 5, 0x1f0001, 0x1fffff}, + {8, 6, 0x1f0001, 0x1fffff}, + {9, 7, 0x1f0001, 0x1fffff}, + {10, 8, 0x1f0001, 0x1fffff}, + {11, 9, 0x1f0001, 0x1fffff}, + {12, 10, 0x1f0001, 0x1fffff}, + {13, 11, 0x1f0001, 0x1fffff}, + {14, 12, 0x1f0001, 0x1fffff}, + {15, 13, 0x1f0001, 0x1fffff}, + {16, 14, 0x1f0001, 0x1fffff}, + {17, 15, 0x1fffff, 0x1fffff}, // begin new round vote + {18, 16, 0x1fffff, 0x1fffff}, // attestation for block 17 + {19, 17, 0x1fffff, 0x1fffff}, // attestation for block 18 + }, + }, +} + +func TestSimulateP2P(t *testing.T) { + for index, testcase := range simulatorTestcases { + c := NewCoordinator(testcase.validatorsNumber) + err := c.SimulateP2P(testcase.cs) + if err != nil { + t.Fatalf("[Testcase %d] simulate P2P error: %v", index, err) + } + for _, val := range c.validators { + t.Logf("[Testcase %d] validator(%d) head block: %d", + index, val.index, val.head.blockNumber) + t.Logf("[Testcase %d] validator(%d) highest justified block: %d", + index, val.index, val.head.GetJustifiedNumber()) + t.Logf("[Testcase %d] validator(%d) highest finalized block: %d", + index, val.index, val.head.GetFinalizedBlock().blockNumber) + } + + if c.CheckChain() == false { + t.Fatalf("[Testcase %d] chain not works as expected", index) + } + } +} diff --git a/consensus/parlia/snapshot.go b/consensus/parlia/snapshot.go index 95aaf861de..7be414421c 100644 --- a/consensus/parlia/snapshot.go +++ b/consensus/parlia/snapshot.go @@ -21,7 +21,6 @@ import ( "encoding/hex" "encoding/json" "errors" - "math/big" "sort" "github.com/ethereum/go-ethereum/common" @@ -39,11 +38,17 @@ type Snapshot struct { ethAPI *ethapi.PublicBlockChainAPI sigCache *lru.ARCCache // Cache of recent block signatures to speed up ecrecover - Number uint64 `json:"number"` // Block number where the snapshot was created - Hash common.Hash `json:"hash"` // Block hash where the snapshot was created - Validators map[common.Address]struct{} `json:"validators"` // Set of authorized validators at this moment - Recents map[uint64]common.Address `json:"recents"` // Set of recent validators for spam protections - RecentForkHashes map[uint64]string `json:"recent_fork_hashes"` // Set of recent forkHash + Number uint64 `json:"number"` // Block number where the snapshot was created + Hash common.Hash `json:"hash"` // Block hash where the snapshot was created + Validators map[common.Address]*ValidatorInfo `json:"validators"` // Set of authorized validators at this moment + Recents map[uint64]common.Address `json:"recents"` // Set of recent validators for spam protections + RecentForkHashes map[uint64]string `json:"recent_fork_hashes"` // Set of recent forkHash + Attestation *types.VoteData `json:"attestation:omitempty"` // Attestation for fast finality +} + +type ValidatorInfo struct { + Index int `json:"index:omitempty"` // The index should offset by 1 + VoteAddress types.BLSPublicKey `json:"vote_address,omitempty"` } // newSnapshot creates a new snapshot with the specified startup parameters. This @@ -55,6 +60,7 @@ func newSnapshot( number uint64, hash common.Hash, validators []common.Address, + voteAddrs []types.BLSPublicKey, ethAPI *ethapi.PublicBlockChainAPI, ) *Snapshot { snap := &Snapshot{ @@ -65,10 +71,25 @@ func newSnapshot( Hash: hash, Recents: make(map[uint64]common.Address), RecentForkHashes: make(map[uint64]string), - Validators: make(map[common.Address]struct{}), + Validators: make(map[common.Address]*ValidatorInfo), } - for _, v := range validators { - snap.Validators[v] = struct{}{} + for idx, v := range validators { + // The boneh fork from the genesis block + if len(voteAddrs) == len(validators) { + snap.Validators[v] = &ValidatorInfo{ + VoteAddress: voteAddrs[idx], + } + } else { + snap.Validators[v] = &ValidatorInfo{} + } + } + + // The boneh fork from the genesis block + if len(voteAddrs) == len(validators) { + validators := snap.validators() + for idx, v := range validators { + snap.Validators[v].Index = idx + 1 // offset by 1 + } } return snap } @@ -114,13 +135,16 @@ func (s *Snapshot) copy() *Snapshot { sigCache: s.sigCache, Number: s.Number, Hash: s.Hash, - Validators: make(map[common.Address]struct{}), + Validators: make(map[common.Address]*ValidatorInfo), Recents: make(map[uint64]common.Address), RecentForkHashes: make(map[uint64]string), } for v := range s.Validators { - cpy.Validators[v] = struct{}{} + cpy.Validators[v] = &ValidatorInfo{ + Index: s.Validators[v].Index, + VoteAddress: s.Validators[v].VoteAddress, + } } for block, v := range s.Recents { cpy.Recents[block] = v @@ -128,6 +152,14 @@ func (s *Snapshot) copy() *Snapshot { for block, id := range s.RecentForkHashes { cpy.RecentForkHashes[block] = id } + if s.Attestation != nil { + cpy.Attestation = &types.VoteData{ + SourceNumber: s.Attestation.SourceNumber, + SourceHash: s.Attestation.SourceHash, + TargetNumber: s.Attestation.TargetNumber, + TargetHash: s.Attestation.TargetHash, + } + } return cpy } @@ -141,7 +173,23 @@ func (s *Snapshot) isMajorityFork(forkHash string) bool { return ally > len(s.RecentForkHashes)/2 } -func (s *Snapshot) apply(headers []*types.Header, chain consensus.ChainHeaderReader, parents []*types.Header, chainId *big.Int) (*Snapshot, error) { +func (s *Snapshot) updateAttestation(header *types.Header, chainConfig *params.ChainConfig, parliaConfig *params.ParliaConfig) { + // The attestation should have been checked in verify header, update directly + attestation, _ := getVoteAttestationFromHeader(header, chainConfig, parliaConfig) + if attestation == nil { + return + } + + // Update attestation + s.Attestation = &types.VoteData{ + SourceNumber: attestation.Data.SourceNumber, + SourceHash: attestation.Data.SourceHash, + TargetNumber: attestation.Data.TargetNumber, + TargetHash: attestation.Data.TargetHash, + } +} + +func (s *Snapshot) apply(headers []*types.Header, chain consensus.ChainHeaderReader, parents []*types.Header, chainConfig *params.ChainConfig, verifiedAttestations map[common.Hash]struct{}) (*Snapshot, error) { // Allow passing in no headers for cleaner code if len(headers) == 0 { return s, nil @@ -174,7 +222,7 @@ func (s *Snapshot) apply(headers []*types.Header, chain consensus.ChainHeaderRea delete(snap.RecentForkHashes, number-limit) } // Resolve the authorization key and check against signers - validator, err := ecrecover(header, s.sigCache, chainId) + validator, err := ecrecover(header, s.sigCache, chainConfig.ChainID) if err != nil { return nil, err } @@ -194,15 +242,20 @@ func (s *Snapshot) apply(headers []*types.Header, chain consensus.ChainHeaderRea return nil, consensus.ErrUnknownAncestor } - validatorBytes := checkpointHeader.Extra[extraVanity : len(checkpointHeader.Extra)-extraSeal] // get validators from headers and use that for new validator set - newValArr, err := ParseValidators(validatorBytes) + newValArr, voteAddrs, err := parseValidators(checkpointHeader, chainConfig, s.config) if err != nil { return nil, err } - newVals := make(map[common.Address]struct{}, len(newValArr)) - for _, val := range newValArr { - newVals[val] = struct{}{} + newVals := make(map[common.Address]*ValidatorInfo, len(newValArr)) + for idx, val := range newValArr { + if !chainConfig.IsBoneh(header.Number) { + newVals[val] = &ValidatorInfo{} + } else { + newVals[val] = &ValidatorInfo{ + VoteAddress: voteAddrs[idx], + } + } } oldLimit := len(snap.Validators)/2 + 1 newLimit := len(newVals)/2 + 1 @@ -219,7 +272,19 @@ func (s *Snapshot) apply(headers []*types.Header, chain consensus.ChainHeaderRea } } snap.Validators = newVals + if chainConfig.IsBoneh(header.Number) { + validators := snap.validators() + for idx, val := range validators { + snap.Validators[val].Index = idx + 1 // offset by 1 + } + } } + + _, voteAssestationNoErr := verifiedAttestations[header.Hash()] + if chainConfig.IsLynn(header.Number) || (chainConfig.IsBoneh(header.Number) && voteAssestationNoErr) { + snap.updateAttestation(header, chainConfig, s.config) + } + snap.RecentForkHashes[number] = hex.EncodeToString(header.Extra[extraVanity-nextForkHashSize : extraVanity]) } snap.Number += uint64(len(headers)) @@ -265,6 +330,10 @@ func (s *Snapshot) enoughDistance(validator common.Address, header *types.Header } func (s *Snapshot) indexOfVal(validator common.Address) int { + if validator, ok := s.Validators[validator]; ok && validator.Index > 0 { + return validator.Index - 1 // Index is offset by 1 + } + validators := s.validators() for idx, val := range validators { if val == validator { @@ -280,18 +349,29 @@ func (s *Snapshot) supposeValidator() common.Address { return validators[index] } -func ParseValidators(validatorsBytes []byte) ([]common.Address, error) { - if len(validatorsBytes)%validatorBytesLength != 0 { - return nil, errors.New("invalid validators bytes") +func parseValidators(header *types.Header, chainConfig *params.ChainConfig, parliaConfig *params.ParliaConfig) ([]common.Address, []types.BLSPublicKey, error) { + validatorsBytes := getValidatorBytesFromHeader(header, chainConfig, parliaConfig) + if len(validatorsBytes) == 0 { + return nil, nil, errors.New("invalid validators bytes") + } + + if !chainConfig.IsBoneh(header.Number) { + n := len(validatorsBytes) / validatorBytesLengthBeforeBoneh + result := make([]common.Address, n) + for i := 0; i < n; i++ { + result[i] = common.BytesToAddress(validatorsBytes[i*validatorBytesLengthBeforeBoneh : (i+1)*validatorBytesLengthBeforeBoneh]) + } + return result, nil, nil } + n := len(validatorsBytes) / validatorBytesLength - result := make([]common.Address, n) + cnsAddrs := make([]common.Address, n) + voteAddrs := make([]types.BLSPublicKey, n) for i := 0; i < n; i++ { - address := make([]byte, validatorBytesLength) - copy(address, validatorsBytes[i*validatorBytesLength:(i+1)*validatorBytesLength]) - result[i] = common.BytesToAddress(address) + cnsAddrs[i] = common.BytesToAddress(validatorsBytes[i*validatorBytesLength : i*validatorBytesLength+common.AddressLength]) + copy(voteAddrs[i][:], validatorsBytes[i*validatorBytesLength+common.AddressLength:(i+1)*validatorBytesLength]) } - return result, nil + return cnsAddrs, voteAddrs, nil } func FindAncientHeader(header *types.Header, ite uint64, chain consensus.ChainHeaderReader, candidateParents []*types.Header) *types.Header { diff --git a/core/blockchain.go b/core/blockchain.go index b7838a7719..43d899d77e 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -55,6 +55,9 @@ var ( headHeaderGauge = metrics.NewRegisteredGauge("chain/head/header", nil) headFastBlockGauge = metrics.NewRegisteredGauge("chain/head/receipt", nil) + justifiedBlockGauge = metrics.NewRegisteredGauge("chain/head/justified", nil) + finalizedBlockGauge = metrics.NewRegisteredGauge("chain/head/finalized", nil) + accountReadTimer = metrics.NewRegisteredTimer("chain/account/reads", nil) accountHashTimer = metrics.NewRegisteredTimer("chain/account/hashes", nil) accountUpdateTimer = metrics.NewRegisteredTimer("chain/account/updates", nil) @@ -200,16 +203,17 @@ type BlockChain struct { txLookupLimit uint64 triesInMemory uint64 - hc *HeaderChain - rmLogsFeed event.Feed - chainFeed event.Feed - chainSideFeed event.Feed - chainHeadFeed event.Feed - chainBlockFeed event.Feed - logsFeed event.Feed - blockProcFeed event.Feed - scope event.SubscriptionScope - genesisBlock *types.Block + hc *HeaderChain + rmLogsFeed event.Feed + chainFeed event.Feed + chainSideFeed event.Feed + chainHeadFeed event.Feed + chainBlockFeed event.Feed + logsFeed event.Feed + blockProcFeed event.Feed + finalizedHeaderFeed event.Feed + scope event.SubscriptionScope + genesisBlock *types.Block // This mutex synchronizes chain write operations. // Readers don't need to take it, they can just read the database. @@ -590,6 +594,30 @@ func (bc *BlockChain) empty() bool { return true } +// GetJustifiedNumber returns the highest justified blockNumber on the branch including and before `header`. +func (bc *BlockChain) GetJustifiedNumber(header *types.Header) uint64 { + if p, ok := bc.engine.(consensus.PoSA); ok { + justifiedBlockNumber, _, err := p.GetJustifiedNumberAndHash(bc, header) + if err == nil { + return justifiedBlockNumber + } + } + // return 0 when err!=nil + // so the input `header` will at a disadvantage during reorg + return 0 +} + +// getFinalizedNumber returns the highest finalized number before the specific block. +func (bc *BlockChain) getFinalizedNumber(header *types.Header) uint64 { + if p, ok := bc.engine.(consensus.PoSA); ok { + if finalizedHeader := p.GetFinalizedHeader(bc, header); finalizedHeader != nil { + return finalizedHeader.Number.Uint64() + } + } + + return 0 +} + // loadLastState loads the last known chain state from the database. This method // assumes that the chain manager mutex is held. func (bc *BlockChain) loadLastState() error { @@ -611,6 +639,8 @@ func (bc *BlockChain) loadLastState() error { // Everything seems to be fine, set as the head block bc.currentBlock.Store(currentBlock) headBlockGauge.Update(int64(currentBlock.NumberU64())) + justifiedBlockGauge.Update(int64(bc.GetJustifiedNumber(currentBlock.Header()))) + finalizedBlockGauge.Update(int64(bc.getFinalizedNumber(currentBlock.Header()))) // Restore the last known head header currentHeader := currentBlock.Header() @@ -759,6 +789,8 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, root common.Hash, repair bo // to low, so it's safe to update in-memory markers directly. bc.currentBlock.Store(newHeadBlock) headBlockGauge.Update(int64(newHeadBlock.NumberU64())) + justifiedBlockGauge.Update(int64(bc.GetJustifiedNumber(newHeadBlock.Header()))) + finalizedBlockGauge.Update(int64(bc.getFinalizedNumber(newHeadBlock.Header()))) } // Rewind the fast block in a simpleton way to the target head if currentFastBlock := bc.CurrentFastBlock(); currentFastBlock != nil && header.Number.Uint64() < currentFastBlock.NumberU64() { @@ -849,6 +881,8 @@ func (bc *BlockChain) SnapSyncCommitHead(hash common.Hash) error { } bc.currentBlock.Store(block) headBlockGauge.Update(int64(block.NumberU64())) + justifiedBlockGauge.Update(int64(bc.GetJustifiedNumber(block.Header()))) + finalizedBlockGauge.Update(int64(bc.getFinalizedNumber(block.Header()))) bc.chainmu.Unlock() // Destroy any existing state snapshot and regenerate it in the background, @@ -895,6 +929,8 @@ func (bc *BlockChain) ResetWithGenesisBlock(genesis *types.Block) error { bc.genesisBlock = genesis bc.currentBlock.Store(bc.genesisBlock) headBlockGauge.Update(int64(bc.genesisBlock.NumberU64())) + justifiedBlockGauge.Update(int64(bc.genesisBlock.NumberU64())) + finalizedBlockGauge.Update(int64(bc.genesisBlock.NumberU64())) bc.hc.SetGenesis(bc.genesisBlock.Header()) bc.hc.SetCurrentHeader(bc.genesisBlock.Header()) bc.currentFastBlock.Store(bc.genesisBlock) @@ -966,6 +1002,8 @@ func (bc *BlockChain) writeHeadBlock(block *types.Block) { bc.currentBlock.Store(block) headBlockGauge.Update(int64(block.NumberU64())) + justifiedBlockGauge.Update(int64(bc.GetJustifiedNumber(block.Header()))) + finalizedBlockGauge.Update(int64(bc.getFinalizedNumber(block.Header()))) } // GetDiffLayerRLP retrieves a diff layer in RLP encoding from the cache or database by blockHash @@ -1203,7 +1241,7 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [ // Rewind may have occurred, skip in that case. if bc.CurrentHeader().Number.Cmp(head.Number()) >= 0 { - reorg, err := bc.forker.ReorgNeeded(bc.CurrentFastBlock().Header(), head.Header()) + reorg, err := bc.forker.ReorgNeededWithFastFinality(bc.CurrentFastBlock().Header(), head.Header()) if err != nil { log.Warn("Reorg failed", "err", err) return false @@ -1605,7 +1643,7 @@ func (bc *BlockChain) writeBlockAndSetHead(block *types.Block, receipts []*types return NonStatTy, err } currentBlock := bc.CurrentBlock() - reorg, err := bc.forker.ReorgNeeded(currentBlock.Header(), block.Header()) + reorg, err := bc.forker.ReorgNeededWithFastFinality(currentBlock.Header(), block.Header()) if err != nil { return NonStatTy, err } @@ -1638,6 +1676,11 @@ func (bc *BlockChain) writeBlockAndSetHead(block *types.Block, receipts []*types // event here. if emitHeadEvent { bc.chainHeadFeed.Send(ChainHeadEvent{Block: block}) + if posa, ok := bc.Engine().(consensus.PoSA); ok { + if finalizedHeader := posa.GetFinalizedHeader(bc, block.Header()); finalizedHeader != nil { + bc.finalizedHeaderFeed.Send(FinalizedHeaderEvent{finalizedHeader}) + } + } } } else { bc.chainSideFeed.Send(ChainSideEvent{Block: block}) @@ -1725,6 +1768,11 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals, setHead bool) defer func() { if lastCanon != nil && bc.CurrentBlock().Hash() == lastCanon.Hash() { bc.chainHeadFeed.Send(ChainHeadEvent{lastCanon}) + if posa, ok := bc.Engine().(consensus.PoSA); ok { + if finalizedHeader := posa.GetFinalizedHeader(bc, lastCanon.Header()); finalizedHeader != nil { + bc.finalizedHeaderFeed.Send(FinalizedHeaderEvent{finalizedHeader}) + } + } } }() // Start the parallel header verifier @@ -1754,7 +1802,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals, setHead bool) current = bc.CurrentBlock() ) for block != nil && bc.skipBlock(err, it) { - reorg, err = bc.forker.ReorgNeeded(current.Header(), block.Header()) + reorg, err = bc.forker.ReorgNeededWithFastFinality(current.Header(), block.Header()) if err != nil { return it.index, err } @@ -2132,7 +2180,7 @@ func (bc *BlockChain) insertSideChain(block *types.Block, it *insertIterator) (i // // If the externTd was larger than our local TD, we now need to reimport the previous // blocks to regenerate the required state - reorg, err := bc.forker.ReorgNeeded(current.Header(), lastBlock.Header()) + reorg, err := bc.forker.ReorgNeededWithFastFinality(current.Header(), lastBlock.Header()) if err != nil { return it.index, err } diff --git a/core/blockchain_reader.go b/core/blockchain_reader.go index b28661da3e..d4b11aa3f0 100644 --- a/core/blockchain_reader.go +++ b/core/blockchain_reader.go @@ -42,6 +42,36 @@ func (bc *BlockChain) CurrentBlock() *types.Block { return bc.currentBlock.Load().(*types.Block) } +// CurrentFinalBlock retrieves the current finalized block of the canonical +// chain. The block is retrieved from the blockchain's internal cache. +func (bc *BlockChain) CurrentFinalBlock() *types.Header { + if p, ok := bc.engine.(consensus.PoSA); ok { + currentHeader := bc.CurrentHeader() + if currentHeader == nil { + return nil + } + return p.GetFinalizedHeader(bc, currentHeader) + } + + return nil +} + +// CurrentSafeBlock retrieves the current safe block of the canonical +// chain. The block is retrieved from the blockchain's internal cache. +func (bc *BlockChain) CurrentSafeBlock() *types.Header { + if p, ok := bc.engine.(consensus.PoSA); ok { + currentHeader := bc.CurrentHeader() + if currentHeader == nil { + return nil + } + _, justifiedBlockHash, err := p.GetJustifiedNumberAndHash(bc, currentHeader) + if err == nil { + return bc.GetHeaderByHash(justifiedBlockHash) + } + } + return nil +} + // CurrentFastBlock retrieves the current fast-sync head block of the canonical // chain. The block is retrieved from the blockchain's internal cache. func (bc *BlockChain) CurrentFastBlock() *types.Block { @@ -399,3 +429,8 @@ func (bc *BlockChain) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscript func (bc *BlockChain) SubscribeBlockProcessingEvent(ch chan<- bool) event.Subscription { return bc.scope.Track(bc.blockProcFeed.Subscribe(ch)) } + +// SubscribeFinalizedHeaderEvent registers a subscription of FinalizedHeaderEvent. +func (bc *BlockChain) SubscribeFinalizedHeaderEvent(ch chan<- FinalizedHeaderEvent) event.Subscription { + return bc.scope.Track(bc.finalizedHeaderFeed.Subscribe(ch)) +} diff --git a/core/events.go b/core/events.go index 5e730a24a7..ce8bcca744 100644 --- a/core/events.go +++ b/core/events.go @@ -21,7 +21,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" ) -// NewTxsEvent is posted when a batch of transactions enter the transaction pool. +// NewTxsEvent is posted when a batch of transactions enters the transaction pool. type NewTxsEvent struct{ Txs []*types.Transaction } // ReannoTxsEvent is posted when a batch of local pending transactions exceed a specified duration. @@ -33,6 +33,12 @@ type NewMinedBlockEvent struct{ Block *types.Block } // RemovedLogsEvent is posted when a reorg happens type RemovedLogsEvent struct{ Logs []*types.Log } +// NewVoteEvent is posted when a batch of votes enters the vote pool. +type NewVoteEvent struct{ Vote *types.VoteEnvelope } + +// FinalizedHeaderEvent is posted when a finalized header is reached. +type FinalizedHeaderEvent struct{ Header *types.Header } + type ChainEvent struct { Block *types.Block Hash common.Hash diff --git a/core/forkchoice.go b/core/forkchoice.go index b0dbb200ec..da32ccce6c 100644 --- a/core/forkchoice.go +++ b/core/forkchoice.go @@ -24,6 +24,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" @@ -36,6 +37,12 @@ type ChainReader interface { // Config retrieves the header chain's chain configuration. Config() *params.ChainConfig + // Engine retrieves the blockchain's consensus engine. + Engine() consensus.Engine + + // GetJustifiedNumber returns the highest justified blockNumber on the branch including and before `header` + GetJustifiedNumber(header *types.Header) uint64 + // GetTd returns the total difficulty of a local block. GetTd(common.Hash, uint64) *big.Int } @@ -69,12 +76,12 @@ func NewForkChoice(chainReader ChainReader, preserve func(header *types.Header) } } -// ReorgNeeded returns whether the reorg should be applied +// reorgNeeded returns whether the reorg should be applied // based on the given external header and local canonical chain. // In the td mode, the new head is chosen if the corresponding // total difficulty is higher. In the extern mode, the trusted // header is always selected as the head. -func (f *ForkChoice) ReorgNeeded(current *types.Header, header *types.Header) (bool, error) { +func (f *ForkChoice) reorgNeeded(current *types.Header, header *types.Header) (bool, error) { var ( localTD = f.chain.GetTd(current.Hash(), current.Number.Uint64()) externTd = f.chain.GetTd(header.Hash(), header.Number.Uint64()) @@ -106,3 +113,24 @@ func (f *ForkChoice) ReorgNeeded(current *types.Header, header *types.Header) (b } return reorg, nil } + +// ReorgNeededWithFastFinality compares justified block numbers firstly, backoff to compare tds when equal +func (f *ForkChoice) ReorgNeededWithFastFinality(current *types.Header, header *types.Header) (bool, error) { + _, ok := f.chain.Engine().(consensus.PoSA) + if !ok { + return f.reorgNeeded(current, header) + } + + justifiedNumber, curJustifiedNumber := uint64(0), uint64(0) + if f.chain.Config().IsLynn(header.Number) { + justifiedNumber = f.chain.GetJustifiedNumber(header) + } + if f.chain.Config().IsLynn(current.Number) { + curJustifiedNumber = f.chain.GetJustifiedNumber(current) + } + if justifiedNumber == curJustifiedNumber { + return f.reorgNeeded(current, header) + } + + return justifiedNumber > curJustifiedNumber, nil +} diff --git a/core/headerchain.go b/core/headerchain.go index c55f7c32c7..88ad7593bd 100644 --- a/core/headerchain.go +++ b/core/headerchain.go @@ -109,9 +109,36 @@ func NewHeaderChain(chainDb ethdb.Database, config *params.ChainConfig, engine c } hc.currentHeaderHash = hc.CurrentHeader().Hash() headHeaderGauge.Update(hc.CurrentHeader().Number.Int64()) + justifiedBlockGauge.Update(int64(hc.GetJustifiedNumber(hc.CurrentHeader()))) + finalizedBlockGauge.Update(int64(hc.getFinalizedNumber(hc.CurrentHeader()))) + return hc, nil } +// GetJustifiedNumber returns the highest justified blockNumber on the branch including and before `header`. +func (hc *HeaderChain) GetJustifiedNumber(header *types.Header) uint64 { + if p, ok := hc.engine.(consensus.PoSA); ok { + justifiedBlockNumber, _, err := p.GetJustifiedNumberAndHash(hc, header) + if err == nil { + return justifiedBlockNumber + } + } + // return 0 when err!=nil + // so the input `header` will at a disadvantage during reorg + return 0 +} + +// getFinalizedNumber returns the highest finalized number before the specific block. +func (hc *HeaderChain) getFinalizedNumber(header *types.Header) uint64 { + if p, ok := hc.engine.(consensus.PoSA); ok { + if finalizedHeader := p.GetFinalizedHeader(hc, header); finalizedHeader != nil { + return finalizedHeader.Number.Uint64() + } + } + + return 0 +} + // GetBlockNumber retrieves the block number belonging to the given hash // from the cache or database func (hc *HeaderChain) GetBlockNumber(hash common.Hash) *uint64 { @@ -285,7 +312,7 @@ func (hc *HeaderChain) writeHeadersAndSetHead(headers []*types.Header, forker *F } ) // Ask the fork choicer if the reorg is necessary - if reorg, err := forker.ReorgNeeded(hc.CurrentHeader(), lastHeader); err != nil { + if reorg, err := forker.ReorgNeededWithFastFinality(hc.CurrentHeader(), lastHeader); err != nil { return nil, err } else if !reorg { if inserted != 0 { @@ -583,6 +610,8 @@ func (hc *HeaderChain) SetCurrentHeader(head *types.Header) { hc.currentHeader.Store(head) hc.currentHeaderHash = head.Hash() headHeaderGauge.Update(head.Number.Int64()) + justifiedBlockGauge.Update(int64(hc.GetJustifiedNumber(head))) + finalizedBlockGauge.Update(int64(hc.getFinalizedNumber(head))) } type ( @@ -638,6 +667,8 @@ func (hc *HeaderChain) SetHead(head uint64, updateFn UpdateHeadBlocksCallback, d hc.currentHeader.Store(parent) hc.currentHeaderHash = parentHash headHeaderGauge.Update(parent.Number.Int64()) + justifiedBlockGauge.Update(int64(hc.GetJustifiedNumber(parent))) + finalizedBlockGauge.Update(int64(hc.getFinalizedNumber(parent))) // If this is the first iteration, wipe any leftover data upwards too so // we don't end up with dangling daps in the database diff --git a/core/state/snapshot/generate.go b/core/state/snapshot/generate.go index 9d74ca4d9b..98fa40ad2e 100644 --- a/core/state/snapshot/generate.go +++ b/core/state/snapshot/generate.go @@ -199,7 +199,7 @@ func journalProgress(db ethdb.KeyValueWriter, marker []byte, stats *generatorSta default: logstr = fmt.Sprintf("%#x:%#x", marker[:common.HashLength], marker[common.HashLength:]) } - log.Debug("Journalled generator progress", "progress", logstr) + log.Debug("Journaled generator progress", "progress", logstr) rawdb.WriteSnapshotGenerator(db, blob) } diff --git a/core/systemcontracts/upgrade.go b/core/systemcontracts/upgrade.go index 3255a4605b..feae2f0133 100644 --- a/core/systemcontracts/upgrade.go +++ b/core/systemcontracts/upgrade.go @@ -51,6 +51,8 @@ var ( moranUpgrade = make(map[string]*Upgrade) planckUpgrade = make(map[string]*Upgrade) + + bonehUpgrade = make(map[string]*Upgrade) ) func init() { @@ -551,6 +553,68 @@ func init() { }, } + bonehUpgrade[mainNet] = &Upgrade{ + UpgradeName: "boneh", + Configs: []*UpgradeConfig{ + { + ContractAddr: common.HexToAddress(ValidatorContract), + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/f8bab13f56955e979bfb754425dab1e62e52f151", + Code: "60806040526004361061046c5760003560e01c8063862498821161024a578063c6d3394511610139578063e40716a1116100b6578063f9a2bbc71161007a578063f9a2bbc714610b6b578063fc3e590814610b80578063fccc281314610b95578063fd4ad81f14610baa578063fd6a687914610bd957610473565b8063e40716a114610af9578063eb57e20214610b0e578063eda5868c14610b2e578063f340fa0114610b43578063f92eb86b14610b5657610473565b8063d86222d5116100fd578063d86222d514610a90578063daacdb6614610aa5578063dc927faf14610aba578063e086c7b114610acf578063e1c7392a14610ae457610473565b8063c6d3394514610a3c578063c81b166214610a51578063c8509d811461085f578063d04aa99614610a66578063d68fb56a14610a7b57610473565b8063a5422d5c116101c7578063ad3c9da61161018b578063ad3c9da6146109d0578063aef198a9146109f0578063b7ab4db514610a05578063b8cf4ef114610a27578063bf9f49951461062f57610473565b8063a5422d5c1461095c578063a78abc1614610971578063aaf5eb6814610986578063ab51bb961461099b578063ac431751146109b057610473565b806396713da91161020e57806396713da9146108f35780639dc09262146109085780639fe0f8161461091d578063a0dc275814610932578063a1a11bf51461094757610473565b8063862498821461087f57806388b32f11146108945780638b5ad0c9146108a95780638d19a410146108be5780639369d7de146108de57610473565b80634df6e0c3116103665780636e47b482116102e35780637942fd05116102a75780637942fd05146108205780637a84ca2a1461083557806381650b621461084a578063831d65d11461085f578063853230aa1461080b57610473565b80636e47b482146107b757806370fd5bad146107cc578063718a8aa8146107e157806375d47a0a146107f657806378dfed4a1461080b57610473565b8063565c56b31161032a578063565c56b3146107265780635667515a146107465780635d77156c1461075b57806362b72cf5146107705780636969a25c1461078557610473565b80634df6e0c3146106b25780635192c82c146106c757806351e80672146106dc578063549b03f2146106f157806355614fcc1461070657610473565b8063321d398a116103f45780633dffc387116103b85780633dffc3871461062f57806343756e5c1461065157806345cf9daf14610666578063493279b11461067b5780634bf6c8821461069d57610473565b8063321d398a146105975780633365af3a146105b757806335409f7f146105d75780633b071dcc146105f75780633de0f0d81461061a57610473565b80631182b8751161043b5780631182b875146104fe578063152ad3b81461052b5780631ff180691461054d578063219f22d514610562578063300c35671461057757610473565b806304c4fec61461047857806307a568471461048f5780630bee7a67146104ba5780630e2374a5146104dc57610473565b3661047357005b600080fd5b34801561048457600080fd5b5061048d610bee565b005b34801561049b57600080fd5b506104a4610c60565b6040516104b19190616d9d565b60405180910390f35b3480156104c657600080fd5b506104cf610c66565b6040516104b19190616dc7565b3480156104e857600080fd5b506104f1610c6b565b6040516104b191906161a4565b34801561050a57600080fd5b5061051e61051936600461608a565b610c71565b6040516104b1919061631b565b34801561053757600080fd5b50610540610ea9565b6040516104b19190616310565b34801561055957600080fd5b506104a4610eb2565b34801561056e57600080fd5b506104cf610eb8565b34801561058357600080fd5b5061048d610592366004615f53565b610ebd565b3480156105a357600080fd5b506105406105b2366004616037565b611263565b3480156105c357600080fd5b506105406105d2366004616037565b611332565b3480156105e357600080fd5b5061048d6105f2366004615f2c565b6113e3565b34801561060357600080fd5b5061060c61153c565b6040516104b1929190616226565b34801561062657600080fd5b506104a4611818565b34801561063b57600080fd5b5061064461181e565b6040516104b19190616dd8565b34801561065d57600080fd5b506104f1611823565b34801561067257600080fd5b506104a4611829565b34801561068757600080fd5b5061069061182f565b6040516104b19190616d8e565b3480156106a957600080fd5b50610644611834565b3480156106be57600080fd5b5061060c611839565b3480156106d357600080fd5b506104a46119b7565b3480156106e857600080fd5b506104f16119bd565b3480156106fd57600080fd5b506104a46119c3565b34801561071257600080fd5b50610540610721366004615f2c565b6119c9565b34801561073257600080fd5b506104a4610741366004615f2c565b6119fe565b34801561075257600080fd5b50610644611a4f565b34801561076757600080fd5b506104cf611a54565b34801561077c57600080fd5b506104a4611a59565b34801561079157600080fd5b506107a56107a0366004616037565b611a5f565b6040516104b1969594939291906161d1565b3480156107c357600080fd5b506104f1611ac3565b3480156107d857600080fd5b50610644611ac9565b3480156107ed57600080fd5b50610644611ace565b34801561080257600080fd5b506104f1611ad3565b34801561081757600080fd5b506104a4611ad9565b34801561082c57600080fd5b50610644611adf565b34801561084157600080fd5b506104a4611ae4565b34801561085657600080fd5b506104cf611aea565b34801561086b57600080fd5b5061048d61087a36600461608a565b611aef565b34801561088b57600080fd5b506104a4611b50565b3480156108a057600080fd5b506104a4611b56565b3480156108b557600080fd5b506104a4611b5c565b3480156108ca57600080fd5b506104a46108d9366004615f2c565b611b62565b3480156108ea57600080fd5b5061048d611ba2565b3480156108ff57600080fd5b50610644611cb6565b34801561091457600080fd5b506104f1611cbb565b34801561092957600080fd5b506104a4611cc1565b34801561093e57600080fd5b506104a4611cc6565b34801561095357600080fd5b506104f1611ccb565b34801561096857600080fd5b5061051e611cd1565b34801561097d57600080fd5b50610540611cf0565b34801561099257600080fd5b506104a4611cf9565b3480156109a757600080fd5b506104cf611a4f565b3480156109bc57600080fd5b5061048d6109cb366004615fdb565b611d02565b3480156109dc57600080fd5b506104a46109eb366004615f2c565b6125ae565b3480156109fc57600080fd5b506104a46125c0565b348015610a1157600080fd5b50610a1a6125cd565b6040516104b19190616213565b348015610a3357600080fd5b506104a46126b9565b348015610a4857600080fd5b506104a4611ac9565b348015610a5d57600080fd5b506104f16126be565b348015610a7257600080fd5b506104a46126c4565b348015610a8757600080fd5b506104a46126c9565b348015610a9c57600080fd5b506104a4612708565b348015610ab157600080fd5b506104a4612714565b348015610ac657600080fd5b506104f161271a565b348015610adb57600080fd5b506104a4612720565b348015610af057600080fd5b5061048d612725565b348015610b0557600080fd5b506104a46128d4565b348015610b1a57600080fd5b5061048d610b29366004615f2c565b6128da565b348015610b3a57600080fd5b506104cf6129e2565b61048d610b51366004615f2c565b6129e7565b348015610b6257600080fd5b506104a4612c6f565b348015610b7757600080fd5b506104f1612c75565b348015610b8c57600080fd5b50610644611cc1565b348015610ba157600080fd5b506104f1612c7b565b348015610bb657600080fd5b50610bca610bc5366004616037565b612c81565b6040516104b193929190616da6565b348015610be557600080fd5b506104f1612d43565b6000610bf933611b62565b9050600b8181548110610c0857fe5b600091825260209091206001601690920201015460ff16610c445760405162461bcd60e51b8152600401610c3b90616a46565b60405180910390fd5b6000610c4e6126c9565b9050610c5b338383612d49565b505050565b60095481565b606481565b61200181565b60005460609060ff16610c965760405162461bcd60e51b8152600401610c3b906164da565b3361200014610cb75760405162461bcd60e51b8152600401610c3b90616c25565b600b54610d7557610cc6615c18565b60015460005b81811015610d7157600b80546001810182556000919091528351600080516020616e50833981519152601690920291820190815560208086015160008051602061747f8339815191528401805460ff1916911515919091179055604086015180518794610d4d93600080516020616e70833981519152909101920190615c47565b506060820151610d639060038301906013615cc1565b505050806001019050610ccc565b5050505b610d7d615cee565b6000610dbe85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612f3592505050565b9150915080610dda57610dd160646130f1565b92505050610ea2565b815160009060ff16610dff57610df883602001518460400151613152565b9050610e6e565b825160ff1660011415610e6a57826020015151600114610e4457600080516020616e30833981519152604051610e349061692d565b60405180910390a1506067610e65565b610df88360200151600081518110610e5857fe5b6020026020010151613da6565b610e6e565b5060655b63ffffffff8116610e935750506040805160008152602081019091529150610ea29050565b610e9c816130f1565b93505050505b9392505050565b60075460ff1681565b60035481565b606881565b334114610edc5760405162461bcd60e51b8152600401610c3b90616c74565b6010544311610efd5760405162461bcd60e51b8152600401610c3b90616636565b60005460ff16610f1f5760405162461bcd60e51b8152600401610c3b906164da565b600f54610f37576032600f5561100231601155611259565b60006110023181610f578268056bc75e2d6310000063ffffffff613f1d16565b1115610f7557610f6e81606463ffffffff613f5f16565b9150610fd1565b6000610f8c60115483613f1d90919063ffffffff16565b1115610fca57610f6e6064610fbe600f54610fb260115486613f1d90919063ffffffff16565b9063ffffffff613fa116565b9063ffffffff613f5f16565b5050611259565b6040516309a99b4f60e41b815261100290639a99b4f090610ff890309086906004016161b8565b602060405180830381600087803b15801561101257600080fd5b505af1158015611026573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061104a919061604f565b6110023160115591508161105f575050611259565b6000805b8481101561108d5785858281811061107757fe5b9050602002013582019150806001019050611063565b508061109b57505050611259565b6000806000805b8981101561125157848989838181106110b757fe5b905060200201358802816110c757fe5b0493508a8a828181106110d657fe5b90506020020160208101906110eb9190615f2c565b6001600160a01b0381166000908152600460205260409020549093509150811561120757600060018084038154811061112057fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff161561118d57836001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d85866040516111809190616d9d565b60405180910390a2611201565b6003546111a0908663ffffffff613fdb16565b60039081558101546111b8908663ffffffff613fdb16565b60038201556040516001600160a01b038516907fcb0aad6cf9cd03bdf6137e359f541c42f38b39f007cae8e89e88aa7d8c6617b2906111f8908890616d9d565b60405180910390a25b50611249565b826001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d85856040516112409190616d9d565b60405180910390a25b6001016110a2565b505050505050505b5050436010555050565b60015460009082106112775750600061132d565b60006001600160a01b03166001838154811061128f57fe5b60009182526020909120600490910201546001600160a01b031614806112bf575060085415806112bf5750600a54155b806112ce575060085460095410155b806112df57506112dd82611332565b155b8061130857506000600b83815481106112f457fe5b906000526020600020906016020160000154115b8061131c575060016113186125cd565b5111155b156113295750600061132d565b5060015b919050565b60015460009082106113465750600061132d565b600b548210611383576001828154811061135c57fe5b9060005260206000209060040201600201601c9054906101000a900460ff1615905061132d565b6001828154811061139057fe5b9060005260206000209060040201600201601c9054906101000a900460ff161580156113dd5750600b82815481106113c457fe5b600091825260209091206001601690920201015460ff16155b92915050565b33611001146114045760405162461bcd60e51b8152600401610c3b90616d45565b600b546114c257611413615c18565b60015460005b818110156114be57600b80546001810182556000919091528351600080516020616e50833981519152601690920291820190815560208086015160008051602061747f8339815191528401805460ff191691151591909117905560408601518051879461149a93600080516020616e70833981519152909101920190615c47565b5060608201516114b09060038301906013615cc1565b505050806001019050611419565b5050505b6001600160a01b038116600090815260046020526040902054806114e65750611539565b6001810390506000600b82815481106114fb57fe5b600091825260209091206001601690920201015460ff16905061151e8383614000565b80156115275750805b15610c5b576009805460001901905550505b50565b60015460609081906000805b8281101561158f576001818154811061155d57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611587576001909101905b600101611548565b506060816040519080825280602002602001820160405280156115bc578160200160208202803683370190505b5090506060826040519080825280602002602001820160405280156115f557816020015b60608152602001906001900390816115e05790505b50600b54600094509091508414156117705760005b8481101561176a576001818154811061161f57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611762576001818154811061164f57fe5b600091825260209091206004909102015483516001600160a01b039091169084908690811061167a57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600b81815481106116a757fe5b600091825260209182902060026016909202018101805460408051601f60001961010060018616150201909316949094049182018590048502840185019052808352919290919083018282801561173f5780601f106117145761010080835404028352916020019161173f565b820191906000526020600020905b81548152906001019060200180831161172257829003601f168201915b505050505082858151811061175057fe5b60209081029190910101526001909301925b60010161160a565b5061180c565b60005b8481101561180a576001818154811061178857fe5b9060005260206000209060040201600201601c9054906101000a900460ff1661180257600181815481106117b857fe5b600091825260209091206004909102015483516001600160a01b03909116908490869081106117e357fe5b6001600160a01b03909216602092830291909101909101526001909301925b600101611773565b505b909450925050505b9091565b61271081565b600181565b61100181565b60085481565b603881565b600881565b600e54600c5460609182918061184d575060155b60606118576125cd565b90506060611864826143b3565b90508282511161187b579094509250611814915050565b8383835103101561188d578282510393505b83156118c35760c843046118a983838388880360008a8a614521565b6118c18383838888038989038a8b8b8b510301614521565b505b6060836040519080825280602002602001820160405280156118ef578160200160208202803683370190505b50905060608460405190808252806020026020018201604052801561192857816020015b60608152602001906001900390816119135790505b50905060005b858110156119a95784818151811061194257fe5b602002602001015183828151811061195657fe5b60200260200101906001600160a01b031690816001600160a01b03168152505083818151811061198257fe5b602002602001015182828151811061199657fe5b602090810291909101015260010161192e565b509096509450505050509091565b60065481565b61200081565b600f5481565b6001600160a01b038116600090815260046020526040812054806119f157600091505061132d565b60001901610ea281611332565b6001600160a01b03811660009081526004602052604081205480611a2657600091505061132d565b600180820381548110611a3557fe5b906000526020600020906004020160030154915050919050565b600081565b606781565b60105481565b60018181548110611a6c57fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b0392831694509082169291821691600160a01b81046001600160401b031691600160e01b90910460ff169086565b61100581565b600281565b601081565b61100881565b6103e881565b600b81565b600c5481565b606681565b3361200014611b105760405162461bcd60e51b8152600401610c3b90616c25565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051611b4393929190616de6565b60405180910390a1505050565b60025481565b60115481565b600a5481565b6001600160a01b03811660009081526004602052604081205480611b985760405162461bcd60e51b8152600401610c3b90616bad565b6000190192915050565b600b54611c6057611bb1615c18565b60015460005b81811015611c5c57600b80546001810182556000919091528351600080516020616e50833981519152601690920291820190815560208086015160008051602061747f8339815191528401805460ff1916911515919091179055604086015180518794611c3893600080516020616e70833981519152909101920190615c47565b506060820151611c4e9060038301906013615cc1565b505050806001019050611bb7565b5050505b600854611c6d5760036008555b600a54611c7a576002600a555b6000611c8533611b62565b9050611c9081611263565b611cac5760405162461bcd60e51b8152600401610c3b906168ea565b6115393382614678565b600981565b61100781565b600381565b60c881565b61100681565b6040518061062001604052806105ef8152602001616e906105ef913981565b60005460ff1681565b6402540be40081565b60005460ff16611d245760405162461bcd60e51b8152600401610c3b906164da565b3361100714611d455760405162461bcd60e51b8152600401610c3b906169b3565b611daf84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526013815272065787069726554696d655365636f6e6447617606c1b602082015291506147109050565b15611e4c5760208114611dd45760405162461bcd60e51b8152600401610c3b90616b67565b604080516020601f8401819004810282018101909252828152600091611e129185858083850183828082843760009201919091525061476992505050565b905060648110158015611e285750620186a08111155b611e445760405162461bcd60e51b8152600401610c3b90616793565b60025561256b565b611eac84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260098152686275726e526174696f60b81b602082015291506147109050565b15611f485760208114611ed15760405162461bcd60e51b8152600401610c3b90616360565b604080516020601f8401819004810282018101909252828152600091611f0f9185858083850183828082843760009201919091525061476992505050565b9050612710811115611f335760405162461bcd60e51b8152600401610c3b90616678565b6006556007805460ff1916600117905561256b565b611fb284848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260138152726d61784e756d4f664d61696e7461696e696e6760681b602082015291506147109050565b1561204c5760208114611fd75760405162461bcd60e51b8152600401610c3b90616397565b604080516020601f84018190048102820181019092528281526000916120159185858083850183828082843760009201919091525061476992505050565b600c5490915080612024575060155b8082106120435760405162461bcd60e51b8152600401610c3b906166eb565b5060085561256b565b6120b584848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61696e7461696e536c6173685363616c6560701b602082015291506147109050565b1561214e57602081146120da5760405162461bcd60e51b8152600401610c3b90616460565b604080516020601f84018190048102820181019092528281526000916121189185858083850183828082843760009201919091525061476992505050565b905060008111801561212a5750600a81105b6121465760405162461bcd60e51b8152600401610c3b90616cc1565b600a5561256b565b6121c284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601981527f6d61784e756d4f66576f726b696e6743616e6469646174657300000000000000602082015291506147109050565b1561225157602081146121e75760405162461bcd60e51b8152600401610c3b90616414565b604080516020601f84018190048102820181019092528281526000916122259185858083850183828082843760009201919091525061476992505050565b9050600d548111156122495760405162461bcd60e51b8152600401610c3b90616809565b600e5561256b565b6122ba84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61784e756d4f6643616e6469646174657360701b602082015291506147109050565b1561233c57602081146122df5760405162461bcd60e51b8152600401610c3b90616a01565b604080516020601f840181900481028201810190925282815260009161231d9185858083850183828082843760009201919091525061476992505050565b600d819055600e5490915081101561233657600d54600e555b5061256b565b6123a084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c6e756d4f66436162696e65747360981b602082015291506147109050565b1561244e57602081146123c55760405162461bcd60e51b8152600401610c3b906164a5565b604080516020601f84018190048102820181019092528281526000916124039185858083850183828082843760009201919091525061476992505050565b9050600081116124255760405162461bcd60e51b8152600401610c3b90616548565b60298111156124465760405162461bcd60e51b8152600401610c3b90616590565b600c5561256b565b6124b884848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601381527266696e616c697479526577617264526174696f60681b602082015291506147109050565b1561255357602081146124dd5760405162461bcd60e51b8152600401610c3b90616aea565b604080516020601f840181900481028201810190925282815260009161251b9185858083850183828082843760009201919091525061476992505050565b90506001811015801561252f575060648111155b61254b5760405162461bcd60e51b8152600401610c3b90616878565b600f5561256b565b60405162461bcd60e51b8152600401610c3b90616d1e565b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040516125a0949392919061632e565b60405180910390a150505050565b60046020526000908152604090205481565b68056bc75e2d6310000081565b6001546060906000805b828110156125fc576125e881611332565b156125f4578160010191505b6001016125d7565b50606081604051908082528060200260200182016040528015612629578160200160208202803683370190505b5090506000915060005b838110156126b05761264481611332565b156126a8576001818154811061265657fe5b600091825260209091206004909102015482516001600160a01b039091169083908590811061268157fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508260010192505b600101612633565b50925050505b90565b601581565b61100281565b603281565b60006126d36125cd565b519050600080600c54116126e85760156126ec565b600c545b9050808211156126fa578091505b8161270457600191505b5090565b67016345785d8a000081565b60055481565b61100381565b602981565b60005460ff16156127485760405162461bcd60e51b8152600401610c3b90616ab3565b612750615cee565b60006127766040518061062001604052806105ef8152602001616e906105ef9139612f35565b91509150806127975760405162461bcd60e51b8152600401610c3b90616be4565b60005b8260200151518110156128bc576001836020015182815181106127b957fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782558587015182850180549185169183169190911790556040860151600283018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590981692909516919091179290921694909417161790915560a09093015160039093019290925591860151805191850193918590811061288f57fe5b602090810291909101810151516001600160a01b031682528101919091526040016000205560010161279a565b50506103e8600255506000805460ff19166001179055565b600d5481565b33611001146128fb5760405162461bcd60e51b8152600401610c3b90616d45565b600b546129b95761290a615c18565b60015460005b818110156129b557600b80546001810182556000919091528351600080516020616e50833981519152601690920291820190815560208086015160008051602061747f8339815191528401805460ff191691151591909117905560408601518051879461299193600080516020616e70833981519152909101920190615c47565b5060608201516129a79060038301906013615cc1565b505050806001019050612910565b5050505b60006129c48261476e565b90506129cf81611263565b156129de576129de8282614678565b5050565b606581565b334114612a065760405162461bcd60e51b8152600401610c3b90616c74565b60005460ff16612a285760405162461bcd60e51b8152600401610c3b906164da565b60003411612a485760405162461bcd60e51b8152600401610c3b906167da565b6001600160a01b0381166000908152600460205260409020546007543491906103e89060ff1615612a7857506006545b600083118015612a885750600081115b15612b29576000612aa5612710610fbe868563ffffffff613fa116565b90508015612b275760405161dead9082156108fc029083906000818181858888f19350505050158015612adc573d6000803e3d6000fd5b507f627059660ea01c4733a328effb2294d2f86905bf806da763a89cee254de8bee581604051612b0c9190616d9d565b60405180910390a1612b24848263ffffffff613f1d16565b93505b505b8115612c27576000600180840381548110612b4057fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff1615612bad57846001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b485604051612ba09190616d9d565b60405180910390a2612c21565b600354612bc0908563ffffffff613fdb16565b6003908155810154612bd8908563ffffffff613fdb16565b60038201556040516001600160a01b038616907f93a090ecc682c002995fad3c85b30c5651d7fd29b0be5da9d784a3302aedc05590612c18908790616d9d565b60405180910390a25b50612c69565b836001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b484604051612c609190616d9d565b60405180910390a25b50505050565b600e5481565b61100081565b61dead81565b600b8181548110612c8e57fe5b6000918252602091829020601691909102018054600180830154600280850180546040805161010096831615969096026000190190911692909204601f810188900488028501880190925281845293965060ff90911694919291830182828015612d395780601f10612d0e57610100808354040283529160200191612d39565b820191906000526020600020905b815481529060010190602001808311612d1c57829003601f168201915b5050505050905083565b61100481565b6000600a5460001480612d5a575081155b80612d655750600954155b15612d7257506000610ea2565b60096000815460019003919050819055506000612dbd600a54610fbe85610fbe600b8981548110612d9f57fe5b6000918252602090912060169091020154439063ffffffff613f1d16565b90506000600b8581548110612dce57fe5b906000526020600020906016020160010160006101000a81548160ff0219169083151502179055506000806110016001600160a01b0316638256ace66040518163ffffffff1660e01b8152600401604080518083038186803b158015612e3357600080fd5b505afa158015612e47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e6b9190616067565b9150915060009350808310612ee557612e848787614000565b506040516305bfb49960e41b815261100190635bfb499090612eaa908a906004016161a4565b600060405180830381600087803b158015612ec457600080fd5b505af1158015612ed8573d6000803e3d6000fd5b5050505060019350612ef7565b818310612ef757612ef58761476e565b505b6040516001600160a01b038816907fb9d38178dc641ff1817967a63c9078cbcd955a9f1fcd75e0e3636de615d44d3b90600090a25050509392505050565b612f3d615cee565b6000612f47615cee565b612f4f615d12565b612f60612f5b86614911565b614936565b90506000805b612f6f83614980565b156130e35780612f9457612f8a612f85846149a1565b6149ef565b60ff1684526130db565b80600114156130d6576060612fb0612fab856149a1565b614a6f565b90508051604051908082528060200260200182016040528015612fed57816020015b612fda615d32565b815260200190600190039081612fd25790505b508560200181905250805160405190808252806020026020018201604052801561302b57816020015b60608152602001906001900390816130165790505b50604086015260005b81518110156130cb57613045615d32565b6060600061306585858151811061305857fe5b6020026020010151614b40565b92509250925080613085578860009a509a505050505050505050506130ec565b828960200151858151811061309657fe5b602002602001018190525081896040015185815181106130b257fe5b6020026020010181905250505050806001019050613034565b5060019250506130db565b6130e3565b600101612f66565b50919350909150505b915091565b604080516001808252818301909252606091829190816020015b606081526020019060019003908161310b5790505090506131318363ffffffff16614c5a565b8160008151811061313e57fe5b6020026020010181905250610ea281614c6d565b600060298351111561318957600080516020616e30833981519152604051613179906165ed565b60405180910390a15060666113dd565b60005b83518110156132275760005b8181101561321e578481815181106131ac57fe5b6020026020010151600001516001600160a01b03168583815181106131cd57fe5b6020026020010151600001516001600160a01b0316141561321657600080516020616e3083398151915260405161320390616748565b60405180910390a16066925050506113dd565b600101613198565b5060010161318c565b506060806132358585614cf7565b60015491935091506000908190815b818110156132ba5767016345785d8a00006001828154811061326257fe5b90600052602060002090600402016003015410613284578360010193506132b2565b60006001828154811061329357fe5b90600052602060002090600402016003015411156132b2578260010192505b600101613244565b506060836040519080825280602002602001820160405280156132e7578160200160208202803683370190505b509050606084604051908082528060200260200182016040528015613316578160200160208202803683370190505b509050606085604051908082528060200260200182016040528015613345578160200160208202803683370190505b509050606086604051908082528060200260200182016040528015613374578160200160208202803683370190505b50905060006060876040519080825280602002602001820160405280156133a5578160200160208202803683370190505b5090506060886040519080825280602002602001820160405280156133d4578160200160208202803683370190505b509050600099506000985060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b15801561341c57600080fd5b505afa158015613430573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613454919061604f565b905067016345785d8a000081111561349f57600080516020616e3083398151915260405161348190616a72565b60405180910390a160689d50505050505050505050505050506113dd565b60005b898110156137105767016345785d8a0000600182815481106134c057fe5b9060005260206000209060040201600301541061364557600181815481106134e457fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316898d8151811061351557fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060006402540be4006001838154811061354a57fe5b9060005260206000209060040201600301548161356357fe5b066001838154811061357157fe5b9060005260206000209060040201600301540390506135998382613f1d90919063ffffffff16565b898e815181106135a557fe5b602002602001018181525050600182815481106135be57fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316878e815181106135ef57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505081888e8151811061361c57fe5b6020908102919091010152613637868263ffffffff613fdb16565b95508c6001019c5050613708565b60006001828154811061365457fe5b9060005260206000209060040201600301541115613708576001818154811061367957fe5b906000526020600020906004020160010160009054906101000a90046001600160a01b0316848c815181106136aa57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600181815481106136d757fe5b906000526020600020906004020160030154838c815181106136f557fe5b6020026020010181815250508a6001019a505b6001016134a2565b5060008415613986576002546040516303702b2960e51b815261100491636e05652091889161374a918e918e918d91420190600401616296565b6020604051808303818588803b15801561376357600080fd5b505af193505050508015613794575060408051601f3d908101601f1916820190925261379191810190615fbb565b60015b61390b576040516000815260443d10156137b05750600061384b565b60046000803e60005160e01c6308c379a081146137d157600091505061384b565b60043d036004833e81513d60248201116001600160401b03821117156137fc5760009250505061384b565b80830180516001600160401b0381111561381d57600094505050505061384b565b8060208301013d860181111561383b5760009550505050505061384b565b601f01601f191660405250925050505b806138565750613898565b60019150857fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf2808260405161388a919061631b565b60405180910390a250613906565b3d8080156138c2576040519150601f19603f3d011682016040523d82523d6000602084013e6138c7565b606091505b5060019150857fbfa884552dd8921b6ce90bfe906952ae5b3b29be0cc1a951d4f62697635a3a45826040516138fc919061631b565b60405180910390a2505b613986565b801561394d577fa217d08e65f80c73121cd9db834d81652d544bfbf452f6d04922b16c90a37b70866040516139409190616d9d565b60405180910390a1613984565b857fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf28060405161397b906163dd565b60405180910390a25b505b8015613b3c5760005b8751811015613b3a5760008882815181106139a657fe5b602002602001015190506000600182815481106139bf57fe5b60009182526020909120600160049092020181015481546001600160a01b03909116916108fc91859081106139f057fe5b9060005260206000209060040201600301549081150290604051600060405180830381858888f1935050505090508015613aac5760018281548110613a3157fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d9185908110613a8057fe5b906000526020600020906004020160030154604051613a9f9190616d9d565b60405180910390a2613b30565b60018281548110613ab957fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d9185908110613b0857fe5b906000526020600020906004020160030154604051613b279190616d9d565b60405180910390a25b505060010161398f565b505b835115613c865760005b8451811015613c84576000858281518110613b5d57fe5b60200260200101516001600160a01b03166108fc868481518110613b7d57fe5b60200260200101519081150290604051600060405180830381858888f1935050505090508015613c1357858281518110613bb357fe5b60200260200101516001600160a01b03167f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d868481518110613bf157fe5b6020026020010151604051613c069190616d9d565b60405180910390a2613c7b565b858281518110613c1f57fe5b60200260200101516001600160a01b03167f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d868481518110613c5d57fe5b6020026020010151604051613c729190616d9d565b60405180910390a25b50600101613b46565b505b5050505050505050505050506000471115613d02577f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d47604051613cca9190616d9d565b60405180910390a1604051611002904780156108fc02916000818181858888f19350505050158015613d00573d6000803e3d6000fd5b505b60006003819055600555815115613d1d57613d1d8282614f30565b6110016001600160a01b031663fc4333cd6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015613d5a57600080fd5b505af1158015613d6e573d6000803e3d6000fd5b50506040517fedd8d7296956dd970ab4de3f2fc03be2b0ffc615d20cd4c72c6e44f928630ebf925060009150a1506000949350505050565b80516001600160a01b0316600090815260046020526040812054801580613df75750600180820381548110613dd757fe5b9060005260206000209060040201600201601c9054906101000a900460ff165b15613e3d5782516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a2600091505061132d565b600154600554600019820111801590613e935784516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a26000935050505061132d565b600580546001908101909155805481906000198601908110613eb157fe5b6000918252602082206002600490920201018054921515600160e01b0260ff60e01b199093169290921790915585516040516001600160a01b03909116917ff226e7d8f547ff903d9d419cf5f54e0d7d07efa9584135a53a057c5f1f27f49a91a2506000949350505050565b6000610ea283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506155fe565b6000610ea283836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061562a565b600082613fb0575060006113dd565b82820282848281613fbd57fe5b0414610ea25760405162461bcd60e51b8152600401610c3b90616972565b600082820183811015610ea25760405162461bcd60e51b8152600401610c3b90616511565b6000806001838154811061401057fe5b9060005260206000209060040201600301549050600060018080549050039050600161403a6125cd565b511161406f5760006001858154811061404f57fe5b9060005260206000209060040201600301819055506000925050506113dd565b846001600160a01b03167f3b6f9ef90462b512a1293ecec018670bf7b7f1876fb727590a8a6d7643130a70836040516140a89190616d9d565b60405180910390a26001600160a01b038516600090815260046020526040812055835b6001546000190181101561429557600181600101815481106140e957fe5b90600052602060002090600402016001828154811061410457fe5b60009182526020909120825460049092020180546001600160a01b03199081166001600160a01b0393841617825560018085015481840180548416918616919091179055600280860180549185018054909416919095161780835584546001600160401b03600160a01b91829004160267ffffffffffffffff60a01b1990911617808355935460ff600160e01b918290041615150260ff60e01b19909416939093179055600392830154920191909155600b8054909183019081106141c557fe5b9060005260206000209060160201600b82815481106141e057fe5b600091825260209091208254601690920201908155600180830154818301805460ff909216151560ff1990921691909117905560028084018054614237938386019390821615610100026000190190911604615d67565b5061424a60038281019084016013615ddc565b5090505080600101600460006001848154811061426357fe5b600091825260208083206004909202909101546001600160a01b031683528201929092526040019020556001016140cb565b5060018054806142a157fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b8054806142f457fe5b60008281526020812060166000199093019283020181815560018101805460ff19169055906143266002830182615e06565b614334600383016000615e4a565b50509055600081838161434357fe5b04905080156143a75760015460005b818110156143a457826001828154811061436857fe5b906000526020600020906004020160030154016001828154811061438857fe5b6000918252602090912060036004909202010155600101614352565b50505b50600195945050505050565b6001548151604080518281526020808402820101909152606092919083908280156143f257816020015b60608152602001906001900390816143dd5790505b50600b54909150831461440957925061132d915050565b60005b8281101561451857600b60016004600089858151811061442857fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002054038154811061445c57fe5b600091825260209182902060026016909202018101805460408051601f6000196101006001861615020190931694909404918201859004850284018501905280835291929091908301828280156144f45780601f106144c9576101008083540402835291602001916144f4565b820191906000526020600020905b8154815290600101906020018083116144d757829003601f168201915b505050505082828151811061450557fe5b602090810291909101015260010161440c565b50949350505050565b60005b8281101561466e5760008287838801604051602001614544929190616196565b6040516020818303038152906040528051906020012060001c8161456457fe5b06905080850182870114614665576000898388018151811061458257fe5b602002602001015190506060898489018151811061459c57fe5b602002602001015190508a838801815181106145b457fe5b60200260200101518b858a01815181106145ca57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050818b848901815181106145f957fe5b60200260200101906001600160a01b031690816001600160a01b031681525050898388018151811061462757fe5b60200260200101518a858a018151811061463d57fe5b6020026020010181905250808a8489018151811061465757fe5b602002602001018190525050505b50600101614524565b5050505050505050565b600980546001908101909155600b80548390811061469257fe5b906000526020600020906016020160010160006101000a81548160ff02191690831515021790555043600b82815481106146c857fe5b600091825260208220601690910201919091556040516001600160a01b038416917ff62981a567ec3cec866c6fa93c55bcdf841d6292d18b8d522ececa769375d82d91a25050565b600081604051602001614723919061617a565b604051602081830303815290604052805190602001208360405160200161474a919061617a565b6040516020818303038152906040528051906020012014905092915050565b015190565b6001600160a01b038116600090815260046020526040812054806147975750600019905061132d565b6001810390506000600182815481106147ac57fe5b90600052602060002090600402016003015490506000600183815481106147cf57fe5b6000918252602090912060036004909202010155600154604051600019909101906001600160a01b038616907f8cd4e147d8af98a9e3b6724021b8bf6aed2e5dac71c38f2dce8161b82585b25d90614828908590616d9d565b60405180910390a2806148405782935050505061132d565b600081838161484b57fe5b04905080156149075760005b848110156148a957816001828154811061486d57fe5b906000526020600020906004020160030154016001828154811061488d57fe5b6000918252602090912060036004909202010155600101614857565b50600180549085015b818110156149045782600182815481106148c857fe5b90600052602060002090600402016003015401600182815481106148e857fe5b60009182526020909120600360049092020101556001016148b2565b50505b5091949350505050565b614919615e59565b506040805180820190915281518152602082810190820152919050565b61493e615d12565b61494782615661565b61495057600080fd5b600061495f836020015161569b565b60208085015160408051808201909152868152920190820152915050919050565b600061498a615e59565b505080518051602091820151919092015191011190565b6149a9615e59565b6149b282614980565b6149bb57600080fd5b602082015160006149cb826156fe565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590614a0457508151602110155b614a0d57600080fd5b6000614a1c836020015161569b565b90508083600001511015614a425760405162461bcd60e51b8152600401610c3b90616b30565b82516020808501518301805192849003929183101561451857506020919091036101000a90049392505050565b6060614a7a82615661565b614a8357600080fd5b6000614a8e836157df565b9050606081604051908082528060200260200182016040528015614acc57816020015b614ab9615e59565b815260200190600190039081614ab15790505b5090506000614ade856020015161569b565b60208601510190506000805b84811015614b3557614afb836156fe565b9150604051806040016040528083815260200184815250848281518110614b1e57fe5b602090810291909101015291810191600101614aea565b509195945050505050565b614b48615d32565b60606000614b54615d32565b6060614b5e615d12565b614b6787614936565b90506000805b614b7683614980565b15614c4b5780614ba157614b91614b8c846149a1565b61583b565b6001600160a01b03168552614c43565b8060011415614bc957614bb6614b8c846149a1565b6001600160a01b03166020860152614c43565b8060021415614bf157614bde614b8c846149a1565b6001600160a01b03166040860152614c43565b8060031415614c1d57614c06612f85846149a1565b6001600160401b0316606086015260019150614c43565b8060041415614c3e57614c37614c32846149a1565b615855565b9350614c43565b614c4b565b600101614b6d565b50929791965091945092505050565b60606113dd614c68836158c5565b6159ab565b6060815160001415614c8e575060408051600081526020810190915261132d565b606082600081518110614c9d57fe5b602002602001015190506000600190505b8351811015614cde57614cd482858381518110614cc757fe5b60200260200101516159fd565b9150600101614cae565b50610ea2614cf1825160c060ff16615a7a565b826159fd565b606080600080808080614d086126c9565b6001549091505b8015614e1657600181039250600b8381548110614d2857fe5b600091825260209091206001601690920201015460ff16614d4857614e0d565b60018381548110614d5557fe5b60009182526020909120600490910201546001600160a01b03169450614d7c858484612d49565b9350831580614d8f575060018a51038610155b15614d9957614e0d565b60005b8a51811015614e0b57856001600160a01b03168b8281518110614dbb57fe5b6020026020010151600001516001600160a01b03161415614e035760018b8281518110614de457fe5b6020908102919091010151901515608090910152600190960195614e0b565b600101614d9c565b505b60001901614d0f565b5084895103604051908082528060200260200182016040528015614e5457816020015b614e41615d32565b815260200190600190039081614e395790505b50965084895103604051908082528060200260200182016040528015614e8e57816020015b6060815260200190600190039081614e795790505b5095506000915060005b8951811015614f2257898181518110614ead57fe5b602002602001015160800151614f1a57898181518110614ec957fe5b6020026020010151888481518110614edd57fe5b6020026020010181905250888181518110614ef457fe5b6020026020010151878481518110614f0857fe5b60200260200101819052508260010192505b600101614e98565b5050505050505b9250929050565b600154825160005b8281101561504d576001614f4a615d32565b60018381548110614f5757fe5b600091825260208083206040805160c08101825260049490940290910180546001600160a01b0390811685526001820154811693850193909352600281015492831691840191909152600160a01b82046001600160401b03166060840152600160e01b90910460ff16151560808301526003015460a082015291505b8481101561502157878181518110614fe757fe5b6020026020010151600001516001600160a01b031682600001516001600160a01b031614156150195760009250615021565b600101614fd3565b5081156150435780516001600160a01b03166000908152600460205260408120555b5050600101614f38565b508082111561510c57805b8281101561510a57600180548061506b57fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b8054806150be57fe5b60008281526020812060166000199093019283020181815560018101805460ff19169055906150f06002830182615e06565b6150fe600383016000615e4a565b50509055600101615058565b505b600081831061511b578161511d565b825b905060005b818110156153b0576151cf86828151811061513957fe5b60200260200101516001838154811061514e57fe5b60009182526020918290206040805160c08101825260049390930290910180546001600160a01b0390811684526001820154811694840194909452600281015493841691830191909152600160a01b83046001600160401b03166060830152600160e01b90920460ff161515608082015260039091015460a0820152615b4c565b6153835780600101600460008884815181106151e757fe5b6020026020010151600001516001600160a01b03166001600160a01b031681526020019081526020016000208190555085818151811061522357fe5b60200260200101516001828154811061523857fe5b6000918252602091829020835160049092020180546001600160a01b039283166001600160a01b0319918216178255928401516001820180549184169185169190911790556040840151600282018054606087015160808801511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909716929097169190911792909216939093171692909217905560a09091015160039091015584518590829081106152f357fe5b6020026020010151600b828154811061530857fe5b9060005260206000209060160201600201908051906020019061532c929190615c47565b506000600b828154811061533c57fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b80548390811061536d57fe5b60009182526020909120601690910201556153a8565b60006001828154811061539257fe5b9060005260206000209060040201600301819055505b600101615122565b5082821115615588576153c1615c18565b835b83811015615585578581815181106153d757fe5b6020026020010151826040018190525060018782815181106153f557fe5b6020908102919091018101518254600181810185556000948552838520835160049093020180546001600160a01b039384166001600160a01b0319918216178255848601518284018054918616918316919091179055604080860151600284018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909a1692909616919091179290921696909617169190911790935560a090930151600390930192909255600b8054928301815590935284516016909102600080516020616e5083398151915281019182558583015160008051602061747f8339815191528201805491151560ff199092169190911790559285015180518694929361552b93600080516020616e7083398151915201920190615c47565b5060608201516155419060038301906013615cc1565b505050806001016004600089848151811061555857fe5b602090810291909101810151516001600160a01b03168252810191909152604001600020556001016153c3565b50505b6000600981905560015493505b838110156155f6576000600b82815481106155ac57fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b8054839081106155dd57fe5b6000918252602090912060169091020155600101615595565b505050505050565b600081848411156156225760405162461bcd60e51b8152600401610c3b919061631b565b505050900390565b6000818361564b5760405162461bcd60e51b8152600401610c3b919061631b565b50600083858161565757fe5b0495945050505050565b80516000906156725750600061132d565b6020820151805160001a9060c08210156156915760009250505061132d565b5060019392505050565b8051600090811a60808110156156b557600091505061132d565b60b88110806156d0575060c081108015906156d0575060f881105b156156df57600191505061132d565b60c08110156156f35760b51901905061132d565b60f51901905061132d565b80516000908190811a608081101561571957600191506157d8565b60b881101561572e57607e19810191506157d8565b60c081101561577f57600060b78203600186019550806020036101000a8651049150600181018201935050808310156157795760405162461bcd60e51b8152600401610c3b906168bf565b506157d8565b60f88110156157945760be19810191506157d8565b600060f78203600186019550806020036101000a8651049150600181018201935050808310156157d65760405162461bcd60e51b8152600401610c3b906168bf565b505b5092915050565b80516000906157f05750600061132d565b60008090506000615804846020015161569b565b602085015185519181019250015b8082101561583257615823826156fe565b82019150826001019250615812565b50909392505050565b805160009060151461584c57600080fd5b6113dd826149ef565b805160609061586357600080fd5b6000615872836020015161569b565b83516040805191839003808352601f19601f82011683016020019091529192506060908280156158a9576020820181803683370190505b5090506000816020019050614518848760200151018285615bcd565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166159095750601861592d565b6fffffffffffffffffffffffffffffffff1984166159295750601061592d565b5060005b60208110156159635781818151811061594257fe5b01602001516001600160f81b0319161561595b57615963565b60010161592d565b60008160200390506060816040519080825280601f01601f191660200182016040528015615998576020820181803683370190505b5080830196909652508452509192915050565b6060815160011480156159dd5750607f60f81b826000815181106159cb57fe5b01602001516001600160f81b03191611155b156159e957508061132d565b6113dd6159fb8351608060ff16615a7a565b835b6060806040519050835180825260208201818101602087015b81831015615a2e578051835260209283019201615a16565b50855184518101855292509050808201602086015b81831015615a5b578051835260209283019201615a43565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310615aa45760405162461bcd60e51b8152600401610c3b906166c3565b60408051600180825281830190925260609160208201818036833701905050905060378411615afe5782840160f81b81600081518110615ae057fe5b60200101906001600160f81b031916908160001a90535090506113dd565b6060615b09856158c5565b90508381510160370160f81b82600081518110615b2257fe5b60200101906001600160f81b031916908160001a905350615b4382826159fd565b95945050505050565b805182516000916001600160a01b039182169116148015615b86575081602001516001600160a01b031683602001516001600160a01b0316145b8015615bab575081604001516001600160a01b031683604001516001600160a01b0316145b8015610ea25750506060908101519101516001600160401b0390811691161490565b80615bd757610c5b565b5b60208110615bf7578251825260209283019290910190601f1901615bd8565b915181516020939093036101000a6000190180199091169216919091179052565b60405180608001604052806000815260200160001515815260200160608152602001615c42615e73565b905290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615c8857805160ff1916838001178555615cb5565b82800160010185558215615cb5579182015b82811115615cb5578251825591602001919060010190615c9a565b50612704929150615e92565b8260138101928215615cb55791602002820182811115615cb5578251825591602001919060010190615c9a565b6040518060600160405280600060ff16815260200160608152602001606081525090565b6040518060400160405280615d25615e59565b8152602001600081525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615da05780548555615cb5565b82800160010185558215615cb557600052602060002091601f016020900482015b82811115615cb5578254825591600101919060010190615dc1565b8260138101928215615cb55791820182811115615cb5578254825591600101919060010190615dc1565b50805460018160011615610100020316600290046000825580601f10615e2c5750611539565b601f0160209004906000526020600020908101906115399190615e92565b50611539906013810190615e92565b604051806040016040528060008152602001600081525090565b6040518061026001604052806013906020820280368337509192915050565b6126b691905b808211156127045760008155600101615e98565b60008083601f840112615ebd578182fd5b5081356001600160401b03811115615ed3578182fd5b6020830191508360208083028501011115614f2957600080fd5b60008083601f840112615efe578182fd5b5081356001600160401b03811115615f14578182fd5b602083019150836020828501011115614f2957600080fd5b600060208284031215615f3d578081fd5b81356001600160a01b0381168114610ea2578182fd5b60008060008060408587031215615f68578283fd5b84356001600160401b0380821115615f7e578485fd5b615f8a88838901615eac565b90965094506020870135915080821115615fa2578384fd5b50615faf87828801615eac565b95989497509550505050565b600060208284031215615fcc578081fd5b81518015158114610ea2578182fd5b60008060008060408587031215615ff0578384fd5b84356001600160401b0380821115616006578586fd5b61601288838901615eed565b9096509450602087013591508082111561602a578384fd5b50615faf87828801615eed565b600060208284031215616048578081fd5b5035919050565b600060208284031215616060578081fd5b5051919050565b60008060408385031215616079578182fd5b505080516020909101519092909150565b60008060006040848603121561609e578283fd5b833560ff811681146160ae578384fd5b925060208401356001600160401b038111156160c8578283fd5b6160d486828701615eed565b9497909650939450505050565b6000815180845260208085019450808401835b838110156161195781516001600160a01b0316875295820195908201906001016160f4565b509495945050505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452616166816020860160208601616e03565b601f01601f19169290920160200192915050565b6000825161618c818460208701616e03565b9190910192915050565b918252602082015260400190565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03968716815294861660208601529290941660408401526001600160401b03166060830152911515608082015260a081019190915260c00190565b600060208252610ea260208301846160e1565b60006040825261623960408301856160e1565b602083820381850152818551808452828401915082838202850101838801865b8381101561628757601f1987840301855261627583835161614e565b94860194925090850190600101616259565b50909998505050505050505050565b6000608082526162a960808301876160e1565b828103602084810191909152865180835287820192820190845b818110156162df578451835293830193918301916001016162c3565b505084810360408601526162f381886160e1565b93505050506001600160401b038316606083015295945050505050565b901515815260200190565b600060208252610ea2602083018461614e565b600060408252616342604083018688616124565b8281036020840152616355818587616124565b979650505050505050565b6020808252601c908201527f6c656e677468206f66206275726e526174696f206d69736d6174636800000000604082015260600190565b60208082526026908201527f6c656e677468206f66206d61784e756d4f664d61696e7461696e696e67206d696040820152650e6dac2e8c6d60d31b606082015260800190565b6020808252601b908201527f6261746368207472616e736665722072657475726e2066616c73650000000000604082015260600190565b6020808252602c908201527f6c656e677468206f66206d61784e756d4f66576f726b696e6743616e6469646160408201526b0e8cae640dad2e6dac2e8c6d60a31b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61696e7461696e536c6173685363616c65206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252818101527f6c656e677468206f66206e756d4f66436162696e657473206d69736d61746368604082015260600190565b60208082526019908201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526028908201527f746865206e756d4f66436162696e657473206d75737420626520677265617465604082015267072207468616e20360c41b606082015260800190565b60208082526039908201527f746865206e756d4f66436162696e657473206d757374206265206c657373207460408201527f68616e204d41585f4e554d5f4f465f56414c494441544f525300000000000000606082015260800190565b60208082526029908201527f746865206e756d626572206f662076616c696461746f727320657863656564206040820152681d1a19481b1a5b5a5d60ba1b606082015260800190565b60208082526022908201527f63616e206e6f7420646f207468697320747769636520696e206f6e6520626c6f604082015261636b60f01b606082015260800190565b6020808252602b908201527f746865206275726e526174696f206d757374206265206e6f206772656174657260408201526a0207468616e2031303030360ac1b606082015260800190565b6020808252600e908201526d696e70757420746f6f206c6f6e6760901b604082015260600190565b60208082526037908201527f746865206d61784e756d4f664d61696e7461696e696e67206d7573742062652060408201527f6c657373207468616e206e756d4f66436162696e657473000000000000000000606082015260800190565b6020808252602b908201527f6475706c696361746520636f6e73656e7375732061646472657373206f66207660408201526a185b1a59185d1bdc94d95d60aa1b606082015260800190565b60208082526027908201527f7468652065787069726554696d655365636f6e64476170206973206f7574206f604082015266662072616e676560c81b606082015260800190565b6020808252601590820152746465706f7369742076616c7565206973207a65726f60581b604082015260600190565b60208082526049908201527f746865206d61784e756d4f66576f726b696e6743616e64696461746573206d7560408201527f7374206265206e6f742067726561746572207468616e206d61784e756d4f6643606082015268616e6469646174657360b81b608082015260a00190565b60208082526027908201527f7468652066696e616c697479526577617264526174696f206973206f7574206f604082015266662072616e676560c81b606082015260800190565b6020808252601190820152706164646974696f6e206f766572666c6f7760781b604082015260600190565b60208082526023908201527f63616e206e6f7420656e7465722054656d706f72617279204d61696e74656e616040820152626e636560e81b606082015260800190565b60208082526025908201527f6c656e677468206f66206a61696c2076616c696461746f7273206d757374206260408201526465206f6e6560d81b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252602e908201527f746865206d6573736167652073656e646572206d75737420626520676f76657260408201526d1b985b98d94818dbdb9d1c9858dd60921b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61784e756d4f6643616e64696461746573206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252601290820152716e6f7420696e206d61696e74656e616e636560701b604082015260600190565b60208082526021908201527f666565206973206c6172676572207468616e2044555354595f494e434f4d494e6040820152604760f81b606082015260800190565b60208082526019908201527f74686520636f6e747261637420616c726561647920696e697400000000000000604082015260600190565b60208082526026908201527f6c656e677468206f662066696e616c697479526577617264526174696f206d696040820152650e6dac2e8c6d60d31b606082015260800190565b6020808252601a908201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604082015260600190565b60208082526026908201527f6c656e677468206f662065787069726554696d655365636f6e64476170206d696040820152650e6dac2e8c6d60d31b606082015260800190565b60208082526017908201527f6f6e6c792063757272656e742076616c696461746f7273000000000000000000604082015260600190565b60208082526021908201527f6661696c656420746f20706172736520696e69742076616c696461746f7253656040820152601d60fa1b606082015260800190565b6020808252602f908201527f746865206d6573736167652073656e646572206d7573742062652063726f737360408201526e0818da185a5b8818dbdb9d1c9858dd608a1b606082015260800190565b6020808252602d908201527f746865206d6573736167652073656e646572206d75737420626520746865206260408201526c3637b1b590383937b23ab1b2b960991b606082015260800190565b6020808252603e908201527f746865206d61696e7461696e536c6173685363616c65206d757374206265206760408201527f726561746572207468616e203020616e64206c657373207468616e2031300000606082015260800190565b6020808252600d908201526c756e6b6e6f776e20706172616d60981b604082015260600190565b60208082526029908201527f746865206d6573736167652073656e646572206d75737420626520736c6173686040820152680818dbdb9d1c9858dd60ba1b606082015260800190565b61ffff91909116815260200190565b90815260200190565b6000848252831515602083015260606040830152615b43606083018461614e565b63ffffffff91909116815260200190565b60ff91909116815260200190565b600060ff8516825260406020830152615b43604083018486616124565b60005b83811015616e1e578181015183820152602001616e06565b83811115612c69575050600091015256fe70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb20175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db90175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbbf905ec80f905e8f846942a7cdd959bfe8d9487b2a43b33565295a698f7e294b6a7edd747c0554875d3fc531d19ba1497992c5e941ff80f3f7f110ffd8920a3ac38fdef318fe94a3f86048c27395000f846946488aa4d1955ee33403f8ccb1d4de5fb97c7ade294220f003d8bdfaadf52aa1e55ae4cc485e6794875941a87e90e440a39c99aa9cb5cea0ad6a3f0b2407b86048c27395000f846949ef9f4360c606c7ab4db26b016007d3ad0ab86a0946103af86a874b705854033438383c82575f25bc29418e2db06cbff3e3c5f856410a1838649e760175786048c27395000f84694ee01c3b1283aa067c58eab4709f85e99d46de5fe94ee4b9bfb1871c64e2bcabb1dc382dc8b7c4218a29415904ab26ab0e99d70b51c220ccdcccabee6e29786048c27395000f84694685b1ded8013785d6623cc18d214320b6bb6475994a20ef4e5e4e7e36258dbf51f4d905114cb1b34bc9413e39085dc88704f4394d35209a02b1a9520320c86048c27395000f8469478f3adfc719c99674c072166708589033e2d9afe9448a30d5eaa7b64492a160f139e2da2800ec3834e94055838358c29edf4dcc1ba1985ad58aedbb6be2b86048c27395000f84694c2be4ec20253b8642161bc3f444f53679c1f3d479466f50c616d737e60d7ca6311ff0d9c434197898a94d1d678a2506eeaa365056fe565df8bc8659f28b086048c27395000f846942f7be8361c80a4c1e7e9aaf001d0877f1cfde218945f93992ac37f3e61db2ef8a587a436a161fd210b94ecbc4fb1a97861344dad0867ca3cba2b860411f086048c27395000f84694ce2fd7544e0b2cc94692d4a704debef7bcb613289444abc67b4b2fba283c582387f54c9cba7c34bafa948acc2ab395ded08bb75ce85bf0f95ad2abc51ad586048c27395000f84694b8f7166496996a7da21cf1f1b04d9b3e26a3d077946770572763289aac606e4f327c2f6cc1aa3b3e3b94882d745ed97d4422ca8da1c22ec49d880c4c097286048c27395000f846942d4c407bbe49438ed859fe965b140dcf1aab71a9943ad0939e120f33518fbba04631afe7a3ed6327b194b2bbb170ca4e499a2b0f3cc85ebfa6e8c4dfcbea86048c27395000f846946bbad7cf34b5fa511d8e963dbba288b1960e75d694853b0f6c324d1f4e76c8266942337ac1b0af1a229442498946a51ca5924552ead6fc2af08b94fcba648601d1a94a2000f846944430b3230294d12c6ab2aac5c2cd68e80b16b581947b107f4976a252a6939b771202c28e64e03f52d694795811a7f214084116949fc4f53cedbf189eeab28601d1a94a2000f84694ea0a6e3c511bbd10f4519ece37dc24887e11b55d946811ca77acfb221a49393c193f3a22db829fcc8e9464feb7c04830dd9ace164fc5c52b3f5a29e5018a8601d1a94a2000f846947ae2f5b9e386cd1b50a4550696d957cb4900f03a94e83bcc5077e6b873995c24bac871b5ad856047e19464e48d4057a90b233e026c1041e6012ada897fe88601d1a94a2000f8469482012708dafc9e1b880fd083b32182b869be8e09948e5adc73a2d233a1b496ed3115464dd6c7b887509428b383d324bc9a37f4e276190796ba5a8947f5ed8601d1a94a2000f8469422b81f8e175ffde54d797fe11eb03f9e3bf75f1d94a1c3ef7ca38d8ba80cce3bfc53ebd2903ed21658942767f7447f7b9b70313d4147b795414aecea54718601d1a94a2000f8469468bf0b8b6fb4e317a0f9d6f03eaf8ce6675bc60d94675cfe570b7902623f47e7f59c9664b5f5065dcf94d84f0d2e50bcf00f2fc476e1c57f5ca2d57f625b8601d1a94a2000f846948c4d90829ce8f72d0163c1d5cf348a862d5506309485c42a7b34309bee2ed6a235f86d16f059deec5894cc2cedc53f0fa6d376336efb67e43d167169f3b78601d1a94a2000f8469435e7a025f4da968de7e4d7e4004197917f4070f194b1182abaeeb3b4d8eba7e6a4162eac7ace23d57394c4fd0d870da52e73de2dd8ded19fe3d26f43a1138601d1a94a2000f84694d6caa02bbebaebb5d7e581e4b66559e635f805ff94c07335cf083c1c46a487f0325769d88e163b653694efaff03b42e41f953a925fc43720e45fb61a19938601d1a94a20000175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbaa2646970667358221220e27eda2c66e25ae7b26ab5145965b2a511fc42ef0bfcbd883a69eaaf8c697cfa64736f6c63430006040033", + }, + { + ContractAddr: common.HexToAddress(SlashContract), + CommitUrl: "https://github.com/node-real/bsc-genesis-contract/commit/f8bab13f56955e979bfb754425dab1e62e52f151", + Code: "608060405234801561001057600080fd5b50600436106102745760003560e01c80638256ace611610151578063c81b1662116100c3578063dc927faf11610087578063dc927faf1461049a578063e1c7392a146104a2578063f9a2bbc7146104aa578063fc3e5908146104b2578063fc4333cd146104ba578063fd6a6879146104c257610274565b8063c81b166214610451578063c8509d8114610459578063c96be4cb1461046c578063cc844b731461047f578063d2a42e4b1461049257610274565b8063a1a11bf511610115578063a1a11bf514610409578063a78abc1614610411578063ab51bb9614610426578063ac0af6291461042e578063ac43175114610436578063c80d4b8f1461044957610274565b80638256ace6146103d6578063831d65d1146103de57806396713da9146103f15780639bc8e4f2146103f95780639dc092621461040157610274565b80634bf6c882116101ea5780636e47b482116101ae5780636e47b482146103a657806370fd5bad146103ae578063718a8aa8146103b657806375d47a0a146103be5780637912a65d146103c65780637942fd05146103ce57610274565b80634bf6c8821461037157806351e8067214610379578063567a372d146103815780635bfb49901461038957806362b72cf51461039e57610274565b806337c8dab91161023c57806337c8dab914610301578063389f4f71146103225780633a63f4b1146103375780633dffc3871461033f57806343756e5c14610354578063493279b11461035c57610274565b80630bee7a67146102795780630e2374a5146102975780631182b875146102ac57806323bac5a2146102cc57806335aa2e44146102ee575b600080fd5b6102816104ca565b60405161028e9190613056565b60405180910390f35b61029f6104cf565b60405161028e9190612987565b6102bf6102ba3660046128bd565b6104d5565b60405161028e91906129bf565b6102df6102da36600461266b565b61053b565b60405161028e9392919061303e565b61029f6102fc36600461288d565b61055e565b61031461030f36600461266b565b610585565b60405161028e929190613030565b61032a6105dc565b60405161028e9190613006565b61032a6105e2565b6103476105e8565b60405161028e9190613067565b61029f6105ed565b6103646105f3565b60405161028e9190612ff7565b6103476105f8565b61029f6105fd565b61032a610603565b61039c61039736600461266b565b610609565b005b61032a6106b4565b61029f6106ba565b6103476106c0565b6103476106c5565b61029f6106ca565b61032a6106d0565b6103476106d5565b6103146106da565b61039c6103ec3660046128bd565b6106e4565b6103476107f6565b61032a6107fb565b61029f610806565b61029f61080c565b610419610812565b60405161028e91906129b4565b61028161081b565b61032a610820565b61039c610444366004612771565b610825565b61032a610bd9565b61029f610bde565b61039c6104673660046128bd565b610be4565b61039c61047a36600461266b565b610c55565b61039c61048d3660046127da565b611046565b61032a61151c565b61029f611521565b61039c611527565b61029f611563565b610347611569565b61039c61156e565b61029f6119b7565b606481565b61200181565b606033612000146105015760405162461bcd60e51b81526004016104f890612e7d565b60405180910390fd5b60005460ff166105235760405162461bcd60e51b81526004016104f890612a6b565b60405162461bcd60e51b81526004016104f890612f40565b600260208190526000918252604090912080546001820154919092015460ff1683565b6001818154811061056b57fe5b6000918252602090912001546001600160a01b0316905081565b600080610590612452565b5050506001600160a01b0316600090815260026020818152604092839020835160608101855281548082526001830154938201849052919093015460ff16151592909301919091529091565b60055481565b60065481565b600181565b61100181565b603881565b600881565b61200081565b60045481565b336110001461062a5760405162461bcd60e51b81526004016104f890612c91565b60005460ff1661064c5760405162461bcd60e51b81526004016104f890612a6b565b61200063f7a251d7600b61065f846119bd565b60006040518463ffffffff1660e01b815260040161067f93929190613075565b600060405180830381600087803b15801561069957600080fd5b505af11580156106ad573d6000803e3d6000fd5b5050505050565b60035481565b61100581565b600281565b601081565b61100881565b603281565b600b81565b6004546005549091565b33612000146107055760405162461bcd60e51b81526004016104f890612e7d565b60005460ff166107275760405162461bcd60e51b81526004016104f890612a6b565b61072f612475565b600061077084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a8f92505050565b9150915080156107b75781516040517f7f0956d47419b9525356e7111652b653b530ec6f5096dccc04589bc38e629967916107aa91613056565b60405180910390a16106ad565b81516040517f7d45f62d17443dd4547bca8a8112c60e2385669318dc300ec61a5d2492f262e7916107e791613056565b60405180910390a15050505050565b600981565b662386f26fc1000081565b61100781565b61100681565b60005460ff1681565b600081565b600481565b60005460ff166108475760405162461bcd60e51b81526004016104f890612a6b565b33611007146108685760405162461bcd60e51b81526004016104f890612d3a565b6108d384848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260148152731b5a5cd9195b59585b9bdc951a1c995cda1bdb1960621b60208201529150611b0f9050565b1561096e57602081146108f85760405162461bcd60e51b81526004016104f890612c1d565b604080516020601f840181900481028201810190925282815260009161093691858580838501838280828437600092019190915250611b6992505050565b90506001811015801561094a575060055481105b6109665760405162461bcd60e51b81526004016104f890612e38565b600455610b96565b6109d484848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e19995b1bdb9e551a1c995cda1bdb19608a1b60208201529150611b0f9050565b15610a7057602081146109f95760405162461bcd60e51b81526004016104f890612d88565b604080516020601f8401819004810282018101909252828152600091610a3791858580838501838280828437600092019190915250611b6992505050565b90506103e88111158015610a4c575060045481115b610a685760405162461bcd60e51b81526004016104f890612ad9565b600555610b96565b610ae484848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601881527f66696e616c697479536c617368526577617264526174696f000000000000000060208201529150611b0f9050565b15610b7e5760208114610b095760405162461bcd60e51b81526004016104f890612f77565b604080516020601f8401819004810282018101909252828152600091610b4791858580838501838280828437600092019190915250611b6992505050565b9050600a8110158015610b5a5750606481105b610b765760405162461bcd60e51b81526004016104f890612bd1565b600655610b96565b60405162461bcd60e51b81526004016104f890612f19565b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a84848484604051610bcb94939291906129d2565b60405180910390a150505050565b609681565b61100281565b3361200014610c055760405162461bcd60e51b81526004016104f890612e7d565b60005460ff16610c275760405162461bcd60e51b81526004016104f890612a6b565b6040517f07db600eebe2ac176be8dcebad61858c245a4961bb32ca2aa3d159b09aa0810e90600090a1505050565b334114610c745760405162461bcd60e51b81526004016104f890612ecc565b60005460ff16610c965760405162461bcd60e51b81526004016104f890612a6b565b6003544311610cb75760405162461bcd60e51b81526004016104f890612fc2565b3a15610cd55760405162461bcd60e51b81526004016104f890612d0c565b60405163155853f360e21b8152611000906355614fcc90610cfa908490600401612987565b60206040518083038186803b158015610d1257600080fd5b505afa158015610d26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4a9190612751565b610d535761103f565b610d5b612452565b506001600160a01b0381166000908152600260208181526040928390208351606081018552815481526001820154928101929092529091015460ff161580159282019290925290610db6576020810180516001019052610e0f565b60016040820181905260208201819052805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0384161790555b438152600554602082015181610e2157fe5b06610f6d57600060208201526040516335409f7f60e01b8152611000906335409f7f90610e52908590600401612987565b600060405180830381600087803b158015610e6c57600080fd5b505af1158015610e80573d6000803e3d6000fd5b505050506120006001600160a01b031663f7a251d7600b610ea0856119bd565b60006040518463ffffffff1660e01b8152600401610ec093929190613075565b600060405180830381600087803b158015610eda57600080fd5b505af1925050508015610eeb575060015b610f68573d808015610f19576040519150601f19603f3d011682016040523d82523d6000602084013e610f1e565b606091505b50826001600160a01b03167fd7bc86ff5d08c8ab043edec743302aba2520e6635172a428bc956721db9e2d1c836020015183604051610f5e92919061300f565b60405180910390a2505b610fd9565b600454816020015181610f7c57fe5b06610fd9576040516375abf10160e11b81526110009063eb57e20290610fa6908590600401612987565b600060405180830381600087803b158015610fc057600080fd5b505af1158015610fd4573d6000803e3d6000fd5b505050505b6001600160a01b0382166000818152600260208181526040808420865181559186015160018301558581015191909201805460ff1916911515919091179055517fddb6012116e51abf5436d956a4f0ebd927e92c576ff96d7918290c8782291e3e9190a2505b5043600355565b60005460ff166110685760405162461bcd60e51b81526004016104f890612a6b565b604051630a83aaa960e31b81526110069063541d55489061108d903390600401612987565b60206040518083038186803b1580156110a557600080fd5b505afa1580156110b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110dd9190612751565b6110f95760405162461bcd60e51b81526004016104f890612a04565b6006546111065760146006555b8051514361010090910111801561112857504381602001516000015161010001115b6111445760405162461bcd60e51b81526004016104f890612a3b565b8060200151602001518160000151602001511480156111725750806020015160600151816000015160600151145b1561118f5760405162461bcd60e51b81526004016104f890612c64565b8051604081015190511080156111ae5750602081015160408101519051105b6111ca5760405162461bcd60e51b81526004016104f890612b6d565b6020810151518151511080156111ef5750806000015160400151816020015160400151105b8061121a575080515160208201515110801561121a5750806020015160400151816000015160400151105b806112345750806020015160400151816000015160400151145b6112505760405162461bcd60e51b81526004016104f890612aa2565b6060806110006001600160a01b0316633b071dcc6040518163ffffffff1660e01b815260040160006040518083038186803b15801561128e57600080fd5b505afa1580156112a2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526112ca919081019061268e565b60408501519193509150600090815b8351811015611327576112ff8482815181106112f157fe5b602002602001015183611b6e565b1561131f5784818151811061131057fe5b60200260200101519250611327565b6001016112d9565b506001600160a01b03821661134e5760405162461bcd60e51b81526004016104f890612ba4565b61136085600001518660400151611bd2565b8015611379575061137985602001518660400151611bd2565b6113955760405162461bcd60e51b81526004016104f890612b0e565b6006546040516309a99b4f60e41b815260646110028031909302049190639a99b4f0906113c8903390859060040161299b565b602060405180830381600087803b1580156113e257600080fd5b505af11580156113f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141a91906128a5565b506040516335409f7f60e01b8152611000906335409f7f90611440908690600401612987565b600060405180830381600087803b15801561145a57600080fd5b505af115801561146e573d6000803e3d6000fd5b505050506120006001600160a01b031663f7a251d7600b61148e866119bd565b60006040518463ffffffff1660e01b81526004016114ae93929190613075565b600060405180830381600087803b1580156114c857600080fd5b505af11580156114dc573d6000803e3d6000fd5b50506040516001600160a01b03861692507fddb6012116e51abf5436d956a4f0ebd927e92c576ff96d7918290c8782291e3e9150600090a2505050505050565b601481565b61100381565b60005460ff161561154a5760405162461bcd60e51b81526004016104f890612dca565b603260045560966005556000805460ff19166001179055565b61100081565b600381565b336110001461158f5760405162461bcd60e51b81526004016104f890612c91565b60005460ff166115b15760405162461bcd60e51b81526004016104f890612a6b565b6001546115bd576119b5565b600154600090600019015b808211611989576000805b828410156116ec576115e3612452565b60026000600187815481106115f457fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff1615159082015260055490915060049004816020015111156116d65760046005548161166157fe5b0481602001510381602001818152505080600260006001888154811061168357fe5b6000918252602080832091909101546001600160a01b0316835282810193909352604091820190208351815591830151600183015591909101516002909101805460ff19169115159190911790556116e0565b60019250506116ec565b508360010193506115d3565b828411611883576116fb612452565b600260006001868154811061170c57fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff1615159082015260055490915060049004816020015111156117f45760046005548161177957fe5b0481602001510381602001818152505080600260006001878154811061179b57fe5b6000918252602080832091909101546001600160a01b03168352828101939093526040918201902083518155918301516001808401919091559201516002909101805460ff191691151591909117905591506118839050565b600260006001868154811061180557fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff1916905580548061184957fe5b600082815260209020810160001990810180546001600160a01b0319169055019055836118765750611883565b50600019909201916116ec565b81801561188d5750805b1561196c5760026000600186815481106118a357fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff191690558054849081106118ea57fe5b600091825260209091200154600180546001600160a01b03909216918690811061191057fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600180548061194957fe5b600082815260209020810160001990810180546001600160a01b03191690550190555b82611978575050611989565b5050600190910190600019016115c8565b6040517fcfdb3b6ccaeccbdc68be3c59c840e3b3c90f0a7c491f5fff1cf56cfda200dd9c90600090a150505b565b61100481565b60408051600480825260a08201909252606091829190816020015b60608152602001906001900390816119d8579050509050611a01836001600160a01b0316611daa565b81600081518110611a0e57fe5b6020026020010181905250611a2243611dcd565b81600181518110611a2f57fe5b6020908102919091010152611a446038611dcd565b81600281518110611a5157fe5b6020026020010181905250611a6542611dcd565b81600381518110611a7257fe5b6020026020010181905250611a8681611de0565b9150505b919050565b611a97612475565b6000611aa1612475565b611aa9612487565b611aba611ab586611e6a565b611e8f565b90506000805b611ac983611ed9565b15611b025780611af557611ae4611adf84611efa565b611f48565b63ffffffff16845260019150611afa565b611b02565b600101611ac0565b5091935090915050915091565b600081604051602001611b22919061296b565b6040516020818303038152906040528051906020012083604051602001611b49919061296b565b604051602081830303815290604052805190602001201490505b92915050565b015190565b815181516000916001918114808314611b8a5760009250611bc8565b600160208701838101602088015b600284838510011415611bc3578051835114611bb75760009650600093505b60209283019201611b98565b505050505b5090949350505050565b60408051600480825260a0820190925260009160609190816020015b6060815260200190600190039081611bee575050604080516020808252818301909252919250606091908082018180368337019050509050611c338560000151611dcd565b82600081518110611c4057fe5b6020026020010181905250611c5b6020866020015183611fca565b611c6481611fda565b82600181518110611c7157fe5b6020026020010181905250611c898560400151611dcd565b82600281518110611c9657fe5b6020026020010181905250611cb16020866060015183611fca565b611cba81611fda565b82600381518110611cc757fe5b6020026020010181905250611ced6020611ce084611de0565b8051906020012083611fca565b6040805160b080825260e08201909252606091602082018180368337019050509050611d1d818360006020612030565b611d2f81876080015160206060612030565b611d3d818660806030612030565b604080516001808252818301909252606091602082018180368337019050509050815160016020830182602086016066600019fa611d7a57600080fd5b506001611d88826000612083565b60ff1614611d9d576000945050505050611b63565b5060019695505050505050565b60408051600560a21b8318601482015260348101909152606090611a8681611fda565b6060611b63611ddb8361209f565b611fda565b6060815160001415611e015750604080516000815260208101909152611a8a565b606082600081518110611e1057fe5b602002602001015190506000600190505b8351811015611e5157611e4782858381518110611e3a57fe5b6020026020010151612185565b9150600101611e21565b50611a86611e64825160c060ff16612202565b82612185565b611e726124a7565b506040805180820190915281518152602082810190820152919050565b611e97612487565b611ea0826122d4565b611ea957600080fd5b6000611eb8836020015161230e565b60208085015160408051808201909152868152920190820152915050919050565b6000611ee36124a7565b505080518051602091820151919092015191011190565b611f026124a7565b611f0b82611ed9565b611f1457600080fd5b60208201516000611f2482612371565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590611f5d57508151602110155b611f6657600080fd5b6000611f75836020015161230e565b90508083600001511015611f9b5760405162461bcd60e51b81526004016104f890612e01565b825160208085015183018051928490039291831015611fc157826020036101000a820491505b50949350505050565b9091018181526020918201910152565b60608151600114801561200c5750607f60f81b82600081518110611ffa57fe5b01602001516001600160f81b03191611155b15612018575080611a8a565b611b6361202a8351608060ff16612202565b83612185565b60005b818110156106ad5783818151811061204757fe5b602001015160f81c60f81b85848060010195508151811061206457fe5b60200101906001600160f81b031916908160001a905350600101612033565b6000816001018351101561209657600080fd5b50016001015190565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166120e357506018612107565b6fffffffffffffffffffffffffffffffff19841661210357506010612107565b5060005b602081101561213d5781818151811061211c57fe5b01602001516001600160f81b031916156121355761213d565b600101612107565b60008160200390506060816040519080825280601f01601f191660200182016040528015612172576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b818310156121b657805183526020928301920161219e565b50855184518101855292509050808201602086015b818310156121e35780518352602092830192016121cb565b508651929092011591909101601f01601f191660405250905092915050565b606068010000000000000000831061222c5760405162461bcd60e51b81526004016104f890612b45565b604080516001808252818301909252606091602082018180368337019050509050603784116122865782840160f81b8160008151811061226857fe5b60200101906001600160f81b031916908160001a9053509050611b63565b60606122918561209f565b90508381510160370160f81b826000815181106122aa57fe5b60200101906001600160f81b031916908160001a9053506122cb8282612185565b95945050505050565b80516000906122e557506000611a8a565b6020820151805160001a9060c082101561230457600092505050611a8a565b5060019392505050565b8051600090811a6080811015612328576000915050611a8a565b60b8811080612343575060c08110801590612343575060f881105b15612352576001915050611a8a565b60c08110156123665760b519019050611a8a565b60f519019050611a8a565b80516000908190811a608081101561238c576001915061244b565b60b88110156123a157607e198101915061244b565b60c08110156123f257600060b78203600186019550806020036101000a8651049150600181018201935050808310156123ec5760405162461bcd60e51b81526004016104f890612ce1565b5061244b565b60f88110156124075760be198101915061244b565b600060f78203600186019550806020036101000a8651049150600181018201935050808310156124495760405162461bcd60e51b81526004016104f890612ce1565b505b5092915050565b604051806060016040528060008152602001600081526020016000151581525090565b60408051602081019091526000815290565b604051806040016040528061249a6124a7565b8152602001600081525090565b604051806040016040528060008152602001600081525090565b600082601f8301126124d1578081fd5b81516124e46124df826130c8565b6130a1565b818152915060208083019084810160005b8481101561255a578151870188603f82011261251057600080fd5b838101516125206124df826130e8565b81815260408b8184860101111561253657600080fd5b6125458388840183870161310c565b508652505092820192908201906001016124f5565b505050505092915050565b60008083601f840112612576578182fd5b50813567ffffffffffffffff81111561258d578182fd5b6020830191508360208285010111156125a557600080fd5b9250929050565b600082601f8301126125bc578081fd5b81356125ca6124df826130e8565b91508082528360208285010111156125e157600080fd5b8060208401602084013760009082016020015292915050565b600060a0828403121561260b578081fd5b61261560a06130a1565b905081358152602082013560208201526040820135604082015260608201356060820152608082013567ffffffffffffffff81111561265357600080fd5b61265f848285016125ac565b60808301525092915050565b60006020828403121561267c578081fd5b81356126878161313c565b9392505050565b600080604083850312156126a0578081fd5b825167ffffffffffffffff808211156126b7578283fd5b81850186601f8201126126c8578384fd5b805192506126d86124df846130c8565b80848252602080830192508084018a8283890287010111156126f8578788fd5b8794505b8685101561272357805161270f8161313c565b8452600194909401939281019281016126fc565b50880151909650935050508082111561273a578283fd5b50612747858286016124c1565b9150509250929050565b600060208284031215612762578081fd5b81518015158114612687578182fd5b60008060008060408587031215612786578182fd5b843567ffffffffffffffff8082111561279d578384fd5b6127a988838901612565565b909650945060208701359150808211156127c1578384fd5b506127ce87828801612565565b95989497509550505050565b6000602082840312156127eb578081fd5b813567ffffffffffffffff80821115612802578283fd5b81840160608187031215612814578384fd5b61281e60606130a1565b925080358281111561282e578485fd5b61283a878284016125fa565b84525060208101358281111561284e578485fd5b61285a878284016125fa565b602085015250604081013582811115612871578485fd5b61287d878284016125ac565b6040850152509195945050505050565b60006020828403121561289e578081fd5b5035919050565b6000602082840312156128b6578081fd5b5051919050565b6000806000604084860312156128d1578283fd5b833560ff811681146128e1578384fd5b9250602084013567ffffffffffffffff8111156128fc578283fd5b61290886828701612565565b9497909650939450505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b6000815180845261295781602086016020860161310c565b601f01601f19169290920160200192915050565b6000825161297d81846020870161310c565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b600060208252612687602083018461293f565b6000604082526129e6604083018688612915565b82810360208401526129f9818587612915565b979650505050505050565b6020808252601f908201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604082015260600190565b6020808252601690820152751d1bdbc81bdb1908189b1bd8dac81a5b9d9bdb1d995960521b604082015260600190565b60208082526019908201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604082015260600190565b6020808252601a908201527f6e6f2076696f6c6174696f6e206f6620766f74652072756c6573000000000000604082015260600190565b6020808252818101527f7468652066656c6f6e795468726573686f6c64206f7574206f662072616e6765604082015260600190565b60208082526017908201527f766572696679207369676e6174757265206661696c6564000000000000000000604082015260600190565b6020808252600e908201526d696e70757420746f6f206c6f6e6760901b604082015260600190565b60208082526019908201527f7372634e756d20626967676572207468616e207461724e756d00000000000000604082015260600190565b6020808252601390820152721d985b1a59185d1bdc881b9bdd08195e1a5cdd606a1b604082015260600190565b6020808252602c908201527f7468652066696e616c69747920736c6173682072657761726420726174696f2060408201526b6f7574206f662072616e676560a01b606082015260800190565b60208082526027908201527f6c656e677468206f66206d697364656d65616e6f725468726573686f6c64206d6040820152660d2e6dac2e8c6d60cb1b606082015260800190565b60208082526013908201527274776f206964656e746963616c20766f74657360681b604082015260600190565b60208082526030908201527f746865206d6573736167652073656e646572206d7573742062652076616c696460408201526f185d1bdc94d95d0818dbdb9d1c9858dd60821b606082015260800190565b6020808252601190820152706164646974696f6e206f766572666c6f7760781b604082015260600190565b6020808252601490820152736761737072696365206973206e6f74207a65726f60601b604082015260600190565b6020808252602e908201527f746865206d6573736167652073656e646572206d75737420626520676f76657260408201526d1b985b98d94818dbdb9d1c9858dd60921b606082015260800190565b60208082526022908201527f6c656e677468206f662066656c6f6e795468726573686f6c64206d69736d61746040820152610c6d60f31b606082015260800190565b60208082526019908201527f74686520636f6e747261637420616c726561647920696e697400000000000000604082015260600190565b6020808252601a908201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604082015260600190565b60208082526025908201527f746865206d697364656d65616e6f725468726573686f6c64206f7574206f662060408201526472616e676560d81b606082015260800190565b6020808252602f908201527f746865206d6573736167652073656e646572206d7573742062652063726f737360408201526e0818da185a5b8818dbdb9d1c9858dd608a1b606082015260800190565b6020808252602d908201527f746865206d6573736167652073656e646572206d75737420626520746865206260408201526c3637b1b590383937b23ab1b2b960991b606082015260800190565b6020808252600d908201526c756e6b6e6f776e20706172616d60981b604082015260600190565b6020808252601e908201527f7265636569766520756e65787065637465642073796e207061636b6167650000604082015260600190565b6020808252602b908201527f6c656e677468206f662066696e616c697479536c61736852657761726452617460408201526a0d2de40dad2e6dac2e8c6d60ab1b606082015260800190565b6020808252818101527f63616e206e6f7420736c61736820747769636520696e206f6e6520626c6f636b604082015260600190565b61ffff91909116815260200190565b90815260200190565b600083825260406020830152613028604083018461293f565b949350505050565b918252602082015260400190565b92835260208301919091521515604082015260600190565b63ffffffff91909116815260200190565b60ff91909116815260200190565b600060ff8516825260606020830152613091606083018561293f565b9050826040830152949350505050565b60405181810167ffffffffffffffff811182821017156130c057600080fd5b604052919050565b600067ffffffffffffffff8211156130de578081fd5b5060209081020190565b600067ffffffffffffffff8211156130fe578081fd5b50601f01601f191660200190565b60005b8381101561312757818101518382015260200161310f565b83811115613136576000848401525b50505050565b6001600160a01b038116811461315157600080fd5b5056fea264697066735822122086a5b0c3194fbead4808634d6137151c6cb6180aacf059312af931e2f7b5c7ff64736f6c63430006040033", + }, + { + ContractAddr: common.HexToAddress(SystemRewardContract), + CommitUrl: "https://github.com/node-real/bsc-genesis-contract/commit/f8bab13f56955e979bfb754425dab1e62e52f151", + Code: "6080604052600436106101a05760003560e01c80637942fd05116100ec578063ac4317511161008a578063f9a2bbc711610064578063f9a2bbc714610550578063fb5478b314610565578063fc3e59081461057a578063fd6a68791461058f576101e4565b8063ac43175114610457578063c81b166214610526578063dc927faf1461053b576101e4565b80639dc09262116100c65780639dc0926214610403578063a1a11bf514610418578063a78abc161461042d578063ab51bb9614610442576101e4565b80637942fd05146103a057806396713da9146103b55780639a99b4f0146103ca576101e4565b80634bf6c882116101595780636e47b482116101335780636e47b4821461034c57806370fd5bad14610361578063718a8aa81461037657806375d47a0a1461038b576101e4565b80634bf6c882146102db57806351e80672146102f05780636d70f7ae14610305576101e4565b80630bee7a67146101e95780630e2374a5146102175780633a0b0eff146102485780633dffc3871461026f57806343756e5c1461029a578063493279b1146102af576101e4565b366101e45734156101e25760408051348152905133917f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db919081900360200190a25b005b600080fd5b3480156101f557600080fd5b506101fe6105a4565b6040805163ffffffff9092168252519081900360200190f35b34801561022357600080fd5b5061022c6105a9565b604080516001600160a01b039092168252519081900360200190f35b34801561025457600080fd5b5061025d6105af565b60408051918252519081900360200190f35b34801561027b57600080fd5b506102846105b5565b6040805160ff9092168252519081900360200190f35b3480156102a657600080fd5b5061022c6105ba565b3480156102bb57600080fd5b506102c46105c0565b6040805161ffff9092168252519081900360200190f35b3480156102e757600080fd5b506102846105c5565b3480156102fc57600080fd5b5061022c6105ca565b34801561031157600080fd5b506103386004803603602081101561032857600080fd5b50356001600160a01b03166105d0565b604080519115158252519081900360200190f35b34801561035857600080fd5b5061022c6105ee565b34801561036d57600080fd5b506102846105f4565b34801561038257600080fd5b506102846105f9565b34801561039757600080fd5b5061022c6105fe565b3480156103ac57600080fd5b50610284610604565b3480156103c157600080fd5b50610284610609565b3480156103d657600080fd5b5061025d600480360360408110156103ed57600080fd5b506001600160a01b03813516906020013561060e565b34801561040f57600080fd5b5061022c6107b9565b34801561042457600080fd5b5061022c6107bf565b34801561043957600080fd5b506103386107c5565b34801561044e57600080fd5b506101fe6107ce565b34801561046357600080fd5b506101e26004803603604081101561047a57600080fd5b81019060208101813564010000000081111561049557600080fd5b8201836020820111156104a757600080fd5b803590602001918460018302840111640100000000831117156104c957600080fd5b9193909290916020810190356401000000008111156104e757600080fd5b8201836020820111156104f957600080fd5b8035906020019184600183028401116401000000008311171561051b57600080fd5b5090925090506107d3565b34801561053257600080fd5b5061022c610b56565b34801561054757600080fd5b5061022c610b5c565b34801561055c57600080fd5b5061022c610b62565b34801561057157600080fd5b5061025d610b68565b34801561058657600080fd5b50610284610b74565b34801561059b57600080fd5b5061022c610b79565b606481565b61200181565b60015481565b600181565b61100181565b603881565b600881565b61200081565b6001600160a01b031660009081526002602052604090205460ff1690565b61100581565b600281565b601081565b61100881565b600b81565b600981565b6000805460ff1661068b57600260208190527fe57bda0a954a7c7381b17b2c763e646ba2c60f67292d287ba583603e2c1c41668054600160ff19918216811790925561100560009081527fe25235fc0de9d7165652bef0846fefda506174abb9a190f03d0f7bcc6146dbce80548316841790559282558254161790555b3360009081526002602052604090205460ff166106d95760405162461bcd60e51b815260040180806020018281038252602b815260200180610c67602b913960400191505060405180910390fd5b60004783106106e857476106ea565b825b9050670de0b6b3a76400008111156107075750670de0b6b3a76400005b8015610788576040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015610743573d6000803e3d6000fd5b506040805182815290516001600160a01b038616917ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0919081900360200190a26107b2565b6040517fe589651933c2457488cc0d8e0941518abf748e799435e4e396d9c4d0b2db2d4d90600090a15b9392505050565b61100781565b61100681565b60005460ff1681565b600081565b33611007146108135760405162461bcd60e51b815260040180806020018281038252602e815260200180610cc1602e913960400191505060405180910390fd5b61087584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600b81526a30b23227b832b930ba37b960a91b60208201529150610b7f9050565b1561094d57606082828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050825192935050601490911490506108f85760405162461bcd60e51b815260040180806020018281038252602c815260200180610cef602c913960400191505060405180910390fd5b60148101516001600160a01b038116600081815260026020526040808220805460ff19166001179055517f9870d7fe5d112134c55844951dedf365363006d9c588db07c4c85af6322a06199190a25050610ac4565b6109b284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600e81526d3232b632ba32a7b832b930ba37b960911b60208201529150610b7f9050565b15610a8757606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060149091149050610a355760405162461bcd60e51b815260040180806020018281038252602f815260200180610c92602f913960400191505060405180910390fd5b60148101516001600160a01b038116600081815260026020526040808220805460ff19169055517fb40992a19dba61ea600e87fce607102bf5908dc89076217b6ca6ae195224f7029190a25050610ac4565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b61100081565b670de0b6b3a764000081565b600381565b61100481565b6000816040516020018082805190602001908083835b60208310610bb45780518252601f199092019160209182019101610b95565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310610c225780518252601f199092019160209182019101610c03565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490509291505056fe6f6e6c79206f70657261746f7220697320616c6c6f77656420746f2063616c6c20746865206d6574686f646c656e677468206f662076616c756520666f722064656c6574654f70657261746f722073686f756c64206265203230746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f72206164644f70657261746f722073686f756c64206265203230a264697066735822122078be72e2672a87e28d3e6849bea141a139b304a089fceb003c016dabd5f556fb64736f6c63430006040033", + }, + }, + } + + bonehUpgrade[chapelNet] = &Upgrade{ + UpgradeName: "boneh", + Configs: []*UpgradeConfig{ + { + ContractAddr: common.HexToAddress(ValidatorContract), + CommitUrl: "https://github.com/node-real/bsc-genesis-contract/commit/f8bab13f56955e979bfb754425dab1e62e52f151", + Code: "60806040526004361061046c5760003560e01c8063862498821161024a578063c6d3394511610139578063e40716a1116100b6578063f9a2bbc71161007a578063f9a2bbc714610b6b578063fc3e590814610b80578063fccc281314610b95578063fd4ad81f14610baa578063fd6a687914610bd957610473565b8063e40716a114610af9578063eb57e20214610b0e578063eda5868c14610b2e578063f340fa0114610b43578063f92eb86b14610b5657610473565b8063d86222d5116100fd578063d86222d514610a90578063daacdb6614610aa5578063dc927faf14610aba578063e086c7b114610acf578063e1c7392a14610ae457610473565b8063c6d3394514610a3c578063c81b166214610a51578063c8509d811461085f578063d04aa99614610a66578063d68fb56a14610a7b57610473565b8063a5422d5c116101c7578063ad3c9da61161018b578063ad3c9da6146109d0578063aef198a9146109f0578063b7ab4db514610a05578063b8cf4ef114610a27578063bf9f49951461062f57610473565b8063a5422d5c1461095c578063a78abc1614610971578063aaf5eb6814610986578063ab51bb961461099b578063ac431751146109b057610473565b806396713da91161020e57806396713da9146108f35780639dc09262146109085780639fe0f8161461091d578063a0dc275814610932578063a1a11bf51461094757610473565b8063862498821461087f57806388b32f11146108945780638b5ad0c9146108a95780638d19a410146108be5780639369d7de146108de57610473565b80634df6e0c3116103665780636e47b482116102e35780637942fd05116102a75780637942fd05146108205780637a84ca2a1461083557806381650b621461084a578063831d65d11461085f578063853230aa1461080b57610473565b80636e47b482146107b757806370fd5bad146107cc578063718a8aa8146107e157806375d47a0a146107f657806378dfed4a1461080b57610473565b8063565c56b31161032a578063565c56b3146107265780635667515a146107465780635d77156c1461075b57806362b72cf5146107705780636969a25c1461078557610473565b80634df6e0c3146106b25780635192c82c146106c757806351e80672146106dc578063549b03f2146106f157806355614fcc1461070657610473565b8063321d398a116103f45780633dffc387116103b85780633dffc3871461062f57806343756e5c1461065157806345cf9daf14610666578063493279b11461067b5780634bf6c8821461069d57610473565b8063321d398a146105975780633365af3a146105b757806335409f7f146105d75780633b071dcc146105f75780633de0f0d81461061a57610473565b80631182b8751161043b5780631182b875146104fe578063152ad3b81461052b5780631ff180691461054d578063219f22d514610562578063300c35671461057757610473565b806304c4fec61461047857806307a568471461048f5780630bee7a67146104ba5780630e2374a5146104dc57610473565b3661047357005b600080fd5b34801561048457600080fd5b5061048d610bee565b005b34801561049b57600080fd5b506104a4610c60565b6040516104b19190616d9d565b60405180910390f35b3480156104c657600080fd5b506104cf610c66565b6040516104b19190616dc7565b3480156104e857600080fd5b506104f1610c6b565b6040516104b191906161a4565b34801561050a57600080fd5b5061051e61051936600461608a565b610c71565b6040516104b1919061631b565b34801561053757600080fd5b50610540610ea9565b6040516104b19190616310565b34801561055957600080fd5b506104a4610eb2565b34801561056e57600080fd5b506104cf610eb8565b34801561058357600080fd5b5061048d610592366004615f53565b610ebd565b3480156105a357600080fd5b506105406105b2366004616037565b611263565b3480156105c357600080fd5b506105406105d2366004616037565b611332565b3480156105e357600080fd5b5061048d6105f2366004615f2c565b6113e3565b34801561060357600080fd5b5061060c61153c565b6040516104b1929190616226565b34801561062657600080fd5b506104a4611818565b34801561063b57600080fd5b5061064461181e565b6040516104b19190616dd8565b34801561065d57600080fd5b506104f1611823565b34801561067257600080fd5b506104a4611829565b34801561068757600080fd5b5061069061182f565b6040516104b19190616d8e565b3480156106a957600080fd5b50610644611834565b3480156106be57600080fd5b5061060c611839565b3480156106d357600080fd5b506104a46119b7565b3480156106e857600080fd5b506104f16119bd565b3480156106fd57600080fd5b506104a46119c3565b34801561071257600080fd5b50610540610721366004615f2c565b6119c9565b34801561073257600080fd5b506104a4610741366004615f2c565b6119fe565b34801561075257600080fd5b50610644611a4f565b34801561076757600080fd5b506104cf611a54565b34801561077c57600080fd5b506104a4611a59565b34801561079157600080fd5b506107a56107a0366004616037565b611a5f565b6040516104b1969594939291906161d1565b3480156107c357600080fd5b506104f1611ac3565b3480156107d857600080fd5b50610644611ac9565b3480156107ed57600080fd5b50610644611ace565b34801561080257600080fd5b506104f1611ad3565b34801561081757600080fd5b506104a4611ad9565b34801561082c57600080fd5b50610644611adf565b34801561084157600080fd5b506104a4611ae4565b34801561085657600080fd5b506104cf611aea565b34801561086b57600080fd5b5061048d61087a36600461608a565b611aef565b34801561088b57600080fd5b506104a4611b50565b3480156108a057600080fd5b506104a4611b56565b3480156108b557600080fd5b506104a4611b5c565b3480156108ca57600080fd5b506104a46108d9366004615f2c565b611b62565b3480156108ea57600080fd5b5061048d611ba2565b3480156108ff57600080fd5b50610644611cb6565b34801561091457600080fd5b506104f1611cbb565b34801561092957600080fd5b506104a4611cc1565b34801561093e57600080fd5b506104a4611cc6565b34801561095357600080fd5b506104f1611ccb565b34801561096857600080fd5b5061051e611cd1565b34801561097d57600080fd5b50610540611cf0565b34801561099257600080fd5b506104a4611cf9565b3480156109a757600080fd5b506104cf611a4f565b3480156109bc57600080fd5b5061048d6109cb366004615fdb565b611d02565b3480156109dc57600080fd5b506104a46109eb366004615f2c565b6125ae565b3480156109fc57600080fd5b506104a46125c0565b348015610a1157600080fd5b50610a1a6125cd565b6040516104b19190616213565b348015610a3357600080fd5b506104a46126b9565b348015610a4857600080fd5b506104a4611ac9565b348015610a5d57600080fd5b506104f16126be565b348015610a7257600080fd5b506104a46126c4565b348015610a8757600080fd5b506104a46126c9565b348015610a9c57600080fd5b506104a4612708565b348015610ab157600080fd5b506104a4612714565b348015610ac657600080fd5b506104f161271a565b348015610adb57600080fd5b506104a4612720565b348015610af057600080fd5b5061048d612725565b348015610b0557600080fd5b506104a46128d4565b348015610b1a57600080fd5b5061048d610b29366004615f2c565b6128da565b348015610b3a57600080fd5b506104cf6129e2565b61048d610b51366004615f2c565b6129e7565b348015610b6257600080fd5b506104a4612c6f565b348015610b7757600080fd5b506104f1612c75565b348015610b8c57600080fd5b50610644611cc1565b348015610ba157600080fd5b506104f1612c7b565b348015610bb657600080fd5b50610bca610bc5366004616037565b612c81565b6040516104b193929190616da6565b348015610be557600080fd5b506104f1612d43565b6000610bf933611b62565b9050600b8181548110610c0857fe5b600091825260209091206001601690920201015460ff16610c445760405162461bcd60e51b8152600401610c3b90616a46565b60405180910390fd5b6000610c4e6126c9565b9050610c5b338383612d49565b505050565b60095481565b606481565b61200181565b60005460609060ff16610c965760405162461bcd60e51b8152600401610c3b906164da565b3361200014610cb75760405162461bcd60e51b8152600401610c3b90616c25565b600b54610d7557610cc6615c18565b60015460005b81811015610d7157600b80546001810182556000919091528351600080516020616ffb833981519152601690920291820190815560208086015160008051602061703b8339815191528401805460ff1916911515919091179055604086015180518794610d4d9360008051602061701b833981519152909101920190615c47565b506060820151610d639060038301906013615cc1565b505050806001019050610ccc565b5050505b610d7d615cee565b6000610dbe85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612f3592505050565b9150915080610dda57610dd160646130f1565b92505050610ea2565b815160009060ff16610dff57610df883602001518460400151613152565b9050610e6e565b825160ff1660011415610e6a57826020015151600114610e4457600080516020616fdb833981519152604051610e349061692d565b60405180910390a1506067610e65565b610df88360200151600081518110610e5857fe5b6020026020010151613da6565b610e6e565b5060655b63ffffffff8116610e935750506040805160008152602081019091529150610ea29050565b610e9c816130f1565b93505050505b9392505050565b60075460ff1681565b60035481565b606881565b334114610edc5760405162461bcd60e51b8152600401610c3b90616c74565b6010544311610efd5760405162461bcd60e51b8152600401610c3b90616636565b60005460ff16610f1f5760405162461bcd60e51b8152600401610c3b906164da565b600f54610f37576032600f5561100231601155611259565b60006110023181610f578268056bc75e2d6310000063ffffffff613f1d16565b1115610f7557610f6e81606463ffffffff613f5f16565b9150610fd1565b6000610f8c60115483613f1d90919063ffffffff16565b1115610fca57610f6e6064610fbe600f54610fb260115486613f1d90919063ffffffff16565b9063ffffffff613fa116565b9063ffffffff613f5f16565b5050611259565b6040516309a99b4f60e41b815261100290639a99b4f090610ff890309086906004016161b8565b602060405180830381600087803b15801561101257600080fd5b505af1158015611026573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061104a919061604f565b6110023160115591508161105f575050611259565b6000805b8481101561108d5785858281811061107757fe5b9050602002013582019150806001019050611063565b508061109b57505050611259565b6000806000805b8981101561125157848989838181106110b757fe5b905060200201358802816110c757fe5b0493508a8a828181106110d657fe5b90506020020160208101906110eb9190615f2c565b6001600160a01b0381166000908152600460205260409020549093509150811561120757600060018084038154811061112057fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff161561118d57836001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d85866040516111809190616d9d565b60405180910390a2611201565b6003546111a0908663ffffffff613fdb16565b60039081558101546111b8908663ffffffff613fdb16565b60038201556040516001600160a01b038516907fcb0aad6cf9cd03bdf6137e359f541c42f38b39f007cae8e89e88aa7d8c6617b2906111f8908890616d9d565b60405180910390a25b50611249565b826001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d85856040516112409190616d9d565b60405180910390a25b6001016110a2565b505050505050505b5050436010555050565b60015460009082106112775750600061132d565b60006001600160a01b03166001838154811061128f57fe5b60009182526020909120600490910201546001600160a01b031614806112bf575060085415806112bf5750600a54155b806112ce575060085460095410155b806112df57506112dd82611332565b155b8061130857506000600b83815481106112f457fe5b906000526020600020906016020160000154115b8061131c575060016113186125cd565b5111155b156113295750600061132d565b5060015b919050565b60015460009082106113465750600061132d565b600b548210611383576001828154811061135c57fe5b9060005260206000209060040201600201601c9054906101000a900460ff1615905061132d565b6001828154811061139057fe5b9060005260206000209060040201600201601c9054906101000a900460ff161580156113dd5750600b82815481106113c457fe5b600091825260209091206001601690920201015460ff16155b92915050565b33611001146114045760405162461bcd60e51b8152600401610c3b90616d45565b600b546114c257611413615c18565b60015460005b818110156114be57600b80546001810182556000919091528351600080516020616ffb833981519152601690920291820190815560208086015160008051602061703b8339815191528401805460ff191691151591909117905560408601518051879461149a9360008051602061701b833981519152909101920190615c47565b5060608201516114b09060038301906013615cc1565b505050806001019050611419565b5050505b6001600160a01b038116600090815260046020526040902054806114e65750611539565b6001810390506000600b82815481106114fb57fe5b600091825260209091206001601690920201015460ff16905061151e8383614000565b80156115275750805b15610c5b576009805460001901905550505b50565b60015460609081906000805b8281101561158f576001818154811061155d57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611587576001909101905b600101611548565b506060816040519080825280602002602001820160405280156115bc578160200160208202803683370190505b5090506060826040519080825280602002602001820160405280156115f557816020015b60608152602001906001900390816115e05790505b50600b54600094509091508414156117705760005b8481101561176a576001818154811061161f57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611762576001818154811061164f57fe5b600091825260209091206004909102015483516001600160a01b039091169084908690811061167a57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600b81815481106116a757fe5b600091825260209182902060026016909202018101805460408051601f60001961010060018616150201909316949094049182018590048502840185019052808352919290919083018282801561173f5780601f106117145761010080835404028352916020019161173f565b820191906000526020600020905b81548152906001019060200180831161172257829003601f168201915b505050505082858151811061175057fe5b60209081029190910101526001909301925b60010161160a565b5061180c565b60005b8481101561180a576001818154811061178857fe5b9060005260206000209060040201600201601c9054906101000a900460ff1661180257600181815481106117b857fe5b600091825260209091206004909102015483516001600160a01b03909116908490869081106117e357fe5b6001600160a01b03909216602092830291909101909101526001909301925b600101611773565b505b909450925050505b9091565b61271081565b600181565b61100181565b60085481565b606181565b600881565b600e54600c5460609182918061184d575060155b60606118576125cd565b90506060611864826143b3565b90508282511161187b579094509250611814915050565b8383835103101561188d578282510393505b83156118c35760c843046118a983838388880360008a8a614521565b6118c18383838888038989038a8b8b8b510301614521565b505b6060836040519080825280602002602001820160405280156118ef578160200160208202803683370190505b50905060608460405190808252806020026020018201604052801561192857816020015b60608152602001906001900390816119135790505b50905060005b858110156119a95784818151811061194257fe5b602002602001015183828151811061195657fe5b60200260200101906001600160a01b031690816001600160a01b03168152505083818151811061198257fe5b602002602001015182828151811061199657fe5b602090810291909101015260010161192e565b509096509450505050509091565b60065481565b61200081565b600f5481565b6001600160a01b038116600090815260046020526040812054806119f157600091505061132d565b60001901610ea281611332565b6001600160a01b03811660009081526004602052604081205480611a2657600091505061132d565b600180820381548110611a3557fe5b906000526020600020906004020160030154915050919050565b600081565b606781565b60105481565b60018181548110611a6c57fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b0392831694509082169291821691600160a01b81046001600160401b031691600160e01b90910460ff169086565b61100581565b600281565b601081565b61100881565b6103e881565b600b81565b600c5481565b606681565b3361200014611b105760405162461bcd60e51b8152600401610c3b90616c25565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051611b4393929190616de6565b60405180910390a1505050565b60025481565b60115481565b600a5481565b6001600160a01b03811660009081526004602052604081205480611b985760405162461bcd60e51b8152600401610c3b90616bad565b6000190192915050565b600b54611c6057611bb1615c18565b60015460005b81811015611c5c57600b80546001810182556000919091528351600080516020616ffb833981519152601690920291820190815560208086015160008051602061703b8339815191528401805460ff1916911515919091179055604086015180518794611c389360008051602061701b833981519152909101920190615c47565b506060820151611c4e9060038301906013615cc1565b505050806001019050611bb7565b5050505b600854611c6d5760036008555b600a54611c7a576002600a555b6000611c8533611b62565b9050611c9081611263565b611cac5760405162461bcd60e51b8152600401610c3b906168ea565b6115393382614678565b600981565b61100781565b600381565b60c881565b61100681565b604051806101e001604052806101ab8152602001616e306101ab913981565b60005460ff1681565b6402540be40081565b60005460ff16611d245760405162461bcd60e51b8152600401610c3b906164da565b3361100714611d455760405162461bcd60e51b8152600401610c3b906169b3565b611daf84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526013815272065787069726554696d655365636f6e6447617606c1b602082015291506147109050565b15611e4c5760208114611dd45760405162461bcd60e51b8152600401610c3b90616b67565b604080516020601f8401819004810282018101909252828152600091611e129185858083850183828082843760009201919091525061476992505050565b905060648110158015611e285750620186a08111155b611e445760405162461bcd60e51b8152600401610c3b90616793565b60025561256b565b611eac84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260098152686275726e526174696f60b81b602082015291506147109050565b15611f485760208114611ed15760405162461bcd60e51b8152600401610c3b90616360565b604080516020601f8401819004810282018101909252828152600091611f0f9185858083850183828082843760009201919091525061476992505050565b9050612710811115611f335760405162461bcd60e51b8152600401610c3b90616678565b6006556007805460ff1916600117905561256b565b611fb284848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260138152726d61784e756d4f664d61696e7461696e696e6760681b602082015291506147109050565b1561204c5760208114611fd75760405162461bcd60e51b8152600401610c3b90616397565b604080516020601f84018190048102820181019092528281526000916120159185858083850183828082843760009201919091525061476992505050565b600c5490915080612024575060155b8082106120435760405162461bcd60e51b8152600401610c3b906166eb565b5060085561256b565b6120b584848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61696e7461696e536c6173685363616c6560701b602082015291506147109050565b1561214e57602081146120da5760405162461bcd60e51b8152600401610c3b90616460565b604080516020601f84018190048102820181019092528281526000916121189185858083850183828082843760009201919091525061476992505050565b905060008111801561212a5750600a81105b6121465760405162461bcd60e51b8152600401610c3b90616cc1565b600a5561256b565b6121c284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601981527f6d61784e756d4f66576f726b696e6743616e6469646174657300000000000000602082015291506147109050565b1561225157602081146121e75760405162461bcd60e51b8152600401610c3b90616414565b604080516020601f84018190048102820181019092528281526000916122259185858083850183828082843760009201919091525061476992505050565b9050600d548111156122495760405162461bcd60e51b8152600401610c3b90616809565b600e5561256b565b6122ba84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61784e756d4f6643616e6469646174657360701b602082015291506147109050565b1561233c57602081146122df5760405162461bcd60e51b8152600401610c3b90616a01565b604080516020601f840181900481028201810190925282815260009161231d9185858083850183828082843760009201919091525061476992505050565b600d819055600e5490915081101561233657600d54600e555b5061256b565b6123a084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c6e756d4f66436162696e65747360981b602082015291506147109050565b1561244e57602081146123c55760405162461bcd60e51b8152600401610c3b906164a5565b604080516020601f84018190048102820181019092528281526000916124039185858083850183828082843760009201919091525061476992505050565b9050600081116124255760405162461bcd60e51b8152600401610c3b90616548565b60298111156124465760405162461bcd60e51b8152600401610c3b90616590565b600c5561256b565b6124b884848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601381527266696e616c697479526577617264526174696f60681b602082015291506147109050565b1561255357602081146124dd5760405162461bcd60e51b8152600401610c3b90616aea565b604080516020601f840181900481028201810190925282815260009161251b9185858083850183828082843760009201919091525061476992505050565b90506001811015801561252f575060648111155b61254b5760405162461bcd60e51b8152600401610c3b90616878565b600f5561256b565b60405162461bcd60e51b8152600401610c3b90616d1e565b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040516125a0949392919061632e565b60405180910390a150505050565b60046020526000908152604090205481565b68056bc75e2d6310000081565b6001546060906000805b828110156125fc576125e881611332565b156125f4578160010191505b6001016125d7565b50606081604051908082528060200260200182016040528015612629578160200160208202803683370190505b5090506000915060005b838110156126b05761264481611332565b156126a8576001818154811061265657fe5b600091825260209091206004909102015482516001600160a01b039091169083908590811061268157fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508260010192505b600101612633565b50925050505b90565b601581565b61100281565b603281565b60006126d36125cd565b519050600080600c54116126e85760156126ec565b600c545b9050808211156126fa578091505b8161270457600191505b5090565b67016345785d8a000081565b60055481565b61100381565b602981565b60005460ff16156127485760405162461bcd60e51b8152600401610c3b90616ab3565b612750615cee565b6000612776604051806101e001604052806101ab8152602001616e306101ab9139612f35565b91509150806127975760405162461bcd60e51b8152600401610c3b90616be4565b60005b8260200151518110156128bc576001836020015182815181106127b957fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782558587015182850180549185169183169190911790556040860151600283018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590981692909516919091179290921694909417161790915560a09093015160039093019290925591860151805191850193918590811061288f57fe5b602090810291909101810151516001600160a01b031682528101919091526040016000205560010161279a565b50506103e8600255506000805460ff19166001179055565b600d5481565b33611001146128fb5760405162461bcd60e51b8152600401610c3b90616d45565b600b546129b95761290a615c18565b60015460005b818110156129b557600b80546001810182556000919091528351600080516020616ffb833981519152601690920291820190815560208086015160008051602061703b8339815191528401805460ff19169115159190911790556040860151805187946129919360008051602061701b833981519152909101920190615c47565b5060608201516129a79060038301906013615cc1565b505050806001019050612910565b5050505b60006129c48261476e565b90506129cf81611263565b156129de576129de8282614678565b5050565b606581565b334114612a065760405162461bcd60e51b8152600401610c3b90616c74565b60005460ff16612a285760405162461bcd60e51b8152600401610c3b906164da565b60003411612a485760405162461bcd60e51b8152600401610c3b906167da565b6001600160a01b0381166000908152600460205260409020546007543491906103e89060ff1615612a7857506006545b600083118015612a885750600081115b15612b29576000612aa5612710610fbe868563ffffffff613fa116565b90508015612b275760405161dead9082156108fc029083906000818181858888f19350505050158015612adc573d6000803e3d6000fd5b507f627059660ea01c4733a328effb2294d2f86905bf806da763a89cee254de8bee581604051612b0c9190616d9d565b60405180910390a1612b24848263ffffffff613f1d16565b93505b505b8115612c27576000600180840381548110612b4057fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff1615612bad57846001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b485604051612ba09190616d9d565b60405180910390a2612c21565b600354612bc0908563ffffffff613fdb16565b6003908155810154612bd8908563ffffffff613fdb16565b60038201556040516001600160a01b038616907f93a090ecc682c002995fad3c85b30c5651d7fd29b0be5da9d784a3302aedc05590612c18908790616d9d565b60405180910390a25b50612c69565b836001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b484604051612c609190616d9d565b60405180910390a25b50505050565b600e5481565b61100081565b61dead81565b600b8181548110612c8e57fe5b6000918252602091829020601691909102018054600180830154600280850180546040805161010096831615969096026000190190911692909204601f810188900488028501880190925281845293965060ff90911694919291830182828015612d395780601f10612d0e57610100808354040283529160200191612d39565b820191906000526020600020905b815481529060010190602001808311612d1c57829003601f168201915b5050505050905083565b61100481565b6000600a5460001480612d5a575081155b80612d655750600954155b15612d7257506000610ea2565b60096000815460019003919050819055506000612dbd600a54610fbe85610fbe600b8981548110612d9f57fe5b6000918252602090912060169091020154439063ffffffff613f1d16565b90506000600b8581548110612dce57fe5b906000526020600020906016020160010160006101000a81548160ff0219169083151502179055506000806110016001600160a01b0316638256ace66040518163ffffffff1660e01b8152600401604080518083038186803b158015612e3357600080fd5b505afa158015612e47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e6b9190616067565b9150915060009350808310612ee557612e848787614000565b506040516305bfb49960e41b815261100190635bfb499090612eaa908a906004016161a4565b600060405180830381600087803b158015612ec457600080fd5b505af1158015612ed8573d6000803e3d6000fd5b5050505060019350612ef7565b818310612ef757612ef58761476e565b505b6040516001600160a01b038816907fb9d38178dc641ff1817967a63c9078cbcd955a9f1fcd75e0e3636de615d44d3b90600090a25050509392505050565b612f3d615cee565b6000612f47615cee565b612f4f615d12565b612f60612f5b86614911565b614936565b90506000805b612f6f83614980565b156130e35780612f9457612f8a612f85846149a1565b6149ef565b60ff1684526130db565b80600114156130d6576060612fb0612fab856149a1565b614a6f565b90508051604051908082528060200260200182016040528015612fed57816020015b612fda615d32565b815260200190600190039081612fd25790505b508560200181905250805160405190808252806020026020018201604052801561302b57816020015b60608152602001906001900390816130165790505b50604086015260005b81518110156130cb57613045615d32565b6060600061306585858151811061305857fe5b6020026020010151614b40565b92509250925080613085578860009a509a505050505050505050506130ec565b828960200151858151811061309657fe5b602002602001018190525081896040015185815181106130b257fe5b6020026020010181905250505050806001019050613034565b5060019250506130db565b6130e3565b600101612f66565b50919350909150505b915091565b604080516001808252818301909252606091829190816020015b606081526020019060019003908161310b5790505090506131318363ffffffff16614c5a565b8160008151811061313e57fe5b6020026020010181905250610ea281614c6d565b600060298351111561318957600080516020616fdb833981519152604051613179906165ed565b60405180910390a15060666113dd565b60005b83518110156132275760005b8181101561321e578481815181106131ac57fe5b6020026020010151600001516001600160a01b03168583815181106131cd57fe5b6020026020010151600001516001600160a01b0316141561321657600080516020616fdb83398151915260405161320390616748565b60405180910390a16066925050506113dd565b600101613198565b5060010161318c565b506060806132358585614cf7565b60015491935091506000908190815b818110156132ba5767016345785d8a00006001828154811061326257fe5b90600052602060002090600402016003015410613284578360010193506132b2565b60006001828154811061329357fe5b90600052602060002090600402016003015411156132b2578260010192505b600101613244565b506060836040519080825280602002602001820160405280156132e7578160200160208202803683370190505b509050606084604051908082528060200260200182016040528015613316578160200160208202803683370190505b509050606085604051908082528060200260200182016040528015613345578160200160208202803683370190505b509050606086604051908082528060200260200182016040528015613374578160200160208202803683370190505b50905060006060876040519080825280602002602001820160405280156133a5578160200160208202803683370190505b5090506060886040519080825280602002602001820160405280156133d4578160200160208202803683370190505b509050600099506000985060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b15801561341c57600080fd5b505afa158015613430573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613454919061604f565b905067016345785d8a000081111561349f57600080516020616fdb83398151915260405161348190616a72565b60405180910390a160689d50505050505050505050505050506113dd565b60005b898110156137105767016345785d8a0000600182815481106134c057fe5b9060005260206000209060040201600301541061364557600181815481106134e457fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316898d8151811061351557fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060006402540be4006001838154811061354a57fe5b9060005260206000209060040201600301548161356357fe5b066001838154811061357157fe5b9060005260206000209060040201600301540390506135998382613f1d90919063ffffffff16565b898e815181106135a557fe5b602002602001018181525050600182815481106135be57fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316878e815181106135ef57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505081888e8151811061361c57fe5b6020908102919091010152613637868263ffffffff613fdb16565b95508c6001019c5050613708565b60006001828154811061365457fe5b9060005260206000209060040201600301541115613708576001818154811061367957fe5b906000526020600020906004020160010160009054906101000a90046001600160a01b0316848c815181106136aa57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600181815481106136d757fe5b906000526020600020906004020160030154838c815181106136f557fe5b6020026020010181815250508a6001019a505b6001016134a2565b5060008415613986576002546040516303702b2960e51b815261100491636e05652091889161374a918e918e918d91420190600401616296565b6020604051808303818588803b15801561376357600080fd5b505af193505050508015613794575060408051601f3d908101601f1916820190925261379191810190615fbb565b60015b61390b576040516000815260443d10156137b05750600061384b565b60046000803e60005160e01c6308c379a081146137d157600091505061384b565b60043d036004833e81513d60248201116001600160401b03821117156137fc5760009250505061384b565b80830180516001600160401b0381111561381d57600094505050505061384b565b8060208301013d860181111561383b5760009550505050505061384b565b601f01601f191660405250925050505b806138565750613898565b60019150857fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf2808260405161388a919061631b565b60405180910390a250613906565b3d8080156138c2576040519150601f19603f3d011682016040523d82523d6000602084013e6138c7565b606091505b5060019150857fbfa884552dd8921b6ce90bfe906952ae5b3b29be0cc1a951d4f62697635a3a45826040516138fc919061631b565b60405180910390a2505b613986565b801561394d577fa217d08e65f80c73121cd9db834d81652d544bfbf452f6d04922b16c90a37b70866040516139409190616d9d565b60405180910390a1613984565b857fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf28060405161397b906163dd565b60405180910390a25b505b8015613b3c5760005b8751811015613b3a5760008882815181106139a657fe5b602002602001015190506000600182815481106139bf57fe5b60009182526020909120600160049092020181015481546001600160a01b03909116916108fc91859081106139f057fe5b9060005260206000209060040201600301549081150290604051600060405180830381858888f1935050505090508015613aac5760018281548110613a3157fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d9185908110613a8057fe5b906000526020600020906004020160030154604051613a9f9190616d9d565b60405180910390a2613b30565b60018281548110613ab957fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d9185908110613b0857fe5b906000526020600020906004020160030154604051613b279190616d9d565b60405180910390a25b505060010161398f565b505b835115613c865760005b8451811015613c84576000858281518110613b5d57fe5b60200260200101516001600160a01b03166108fc868481518110613b7d57fe5b60200260200101519081150290604051600060405180830381858888f1935050505090508015613c1357858281518110613bb357fe5b60200260200101516001600160a01b03167f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d868481518110613bf157fe5b6020026020010151604051613c069190616d9d565b60405180910390a2613c7b565b858281518110613c1f57fe5b60200260200101516001600160a01b03167f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d868481518110613c5d57fe5b6020026020010151604051613c729190616d9d565b60405180910390a25b50600101613b46565b505b5050505050505050505050506000471115613d02577f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d47604051613cca9190616d9d565b60405180910390a1604051611002904780156108fc02916000818181858888f19350505050158015613d00573d6000803e3d6000fd5b505b60006003819055600555815115613d1d57613d1d8282614f30565b6110016001600160a01b031663fc4333cd6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015613d5a57600080fd5b505af1158015613d6e573d6000803e3d6000fd5b50506040517fedd8d7296956dd970ab4de3f2fc03be2b0ffc615d20cd4c72c6e44f928630ebf925060009150a1506000949350505050565b80516001600160a01b0316600090815260046020526040812054801580613df75750600180820381548110613dd757fe5b9060005260206000209060040201600201601c9054906101000a900460ff165b15613e3d5782516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a2600091505061132d565b600154600554600019820111801590613e935784516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a26000935050505061132d565b600580546001908101909155805481906000198601908110613eb157fe5b6000918252602082206002600490920201018054921515600160e01b0260ff60e01b199093169290921790915585516040516001600160a01b03909116917ff226e7d8f547ff903d9d419cf5f54e0d7d07efa9584135a53a057c5f1f27f49a91a2506000949350505050565b6000610ea283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506155fe565b6000610ea283836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061562a565b600082613fb0575060006113dd565b82820282848281613fbd57fe5b0414610ea25760405162461bcd60e51b8152600401610c3b90616972565b600082820183811015610ea25760405162461bcd60e51b8152600401610c3b90616511565b6000806001838154811061401057fe5b9060005260206000209060040201600301549050600060018080549050039050600161403a6125cd565b511161406f5760006001858154811061404f57fe5b9060005260206000209060040201600301819055506000925050506113dd565b846001600160a01b03167f3b6f9ef90462b512a1293ecec018670bf7b7f1876fb727590a8a6d7643130a70836040516140a89190616d9d565b60405180910390a26001600160a01b038516600090815260046020526040812055835b6001546000190181101561429557600181600101815481106140e957fe5b90600052602060002090600402016001828154811061410457fe5b60009182526020909120825460049092020180546001600160a01b03199081166001600160a01b0393841617825560018085015481840180548416918616919091179055600280860180549185018054909416919095161780835584546001600160401b03600160a01b91829004160267ffffffffffffffff60a01b1990911617808355935460ff600160e01b918290041615150260ff60e01b19909416939093179055600392830154920191909155600b8054909183019081106141c557fe5b9060005260206000209060160201600b82815481106141e057fe5b600091825260209091208254601690920201908155600180830154818301805460ff909216151560ff1990921691909117905560028084018054614237938386019390821615610100026000190190911604615d67565b5061424a60038281019084016013615ddc565b5090505080600101600460006001848154811061426357fe5b600091825260208083206004909202909101546001600160a01b031683528201929092526040019020556001016140cb565b5060018054806142a157fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b8054806142f457fe5b60008281526020812060166000199093019283020181815560018101805460ff19169055906143266002830182615e06565b614334600383016000615e4a565b50509055600081838161434357fe5b04905080156143a75760015460005b818110156143a457826001828154811061436857fe5b906000526020600020906004020160030154016001828154811061438857fe5b6000918252602090912060036004909202010155600101614352565b50505b50600195945050505050565b6001548151604080518281526020808402820101909152606092919083908280156143f257816020015b60608152602001906001900390816143dd5790505b50600b54909150831461440957925061132d915050565b60005b8281101561451857600b60016004600089858151811061442857fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002054038154811061445c57fe5b600091825260209182902060026016909202018101805460408051601f6000196101006001861615020190931694909404918201859004850284018501905280835291929091908301828280156144f45780601f106144c9576101008083540402835291602001916144f4565b820191906000526020600020905b8154815290600101906020018083116144d757829003601f168201915b505050505082828151811061450557fe5b602090810291909101015260010161440c565b50949350505050565b60005b8281101561466e5760008287838801604051602001614544929190616196565b6040516020818303038152906040528051906020012060001c8161456457fe5b06905080850182870114614665576000898388018151811061458257fe5b602002602001015190506060898489018151811061459c57fe5b602002602001015190508a838801815181106145b457fe5b60200260200101518b858a01815181106145ca57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050818b848901815181106145f957fe5b60200260200101906001600160a01b031690816001600160a01b031681525050898388018151811061462757fe5b60200260200101518a858a018151811061463d57fe5b6020026020010181905250808a8489018151811061465757fe5b602002602001018190525050505b50600101614524565b5050505050505050565b600980546001908101909155600b80548390811061469257fe5b906000526020600020906016020160010160006101000a81548160ff02191690831515021790555043600b82815481106146c857fe5b600091825260208220601690910201919091556040516001600160a01b038416917ff62981a567ec3cec866c6fa93c55bcdf841d6292d18b8d522ececa769375d82d91a25050565b600081604051602001614723919061617a565b604051602081830303815290604052805190602001208360405160200161474a919061617a565b6040516020818303038152906040528051906020012014905092915050565b015190565b6001600160a01b038116600090815260046020526040812054806147975750600019905061132d565b6001810390506000600182815481106147ac57fe5b90600052602060002090600402016003015490506000600183815481106147cf57fe5b6000918252602090912060036004909202010155600154604051600019909101906001600160a01b038616907f8cd4e147d8af98a9e3b6724021b8bf6aed2e5dac71c38f2dce8161b82585b25d90614828908590616d9d565b60405180910390a2806148405782935050505061132d565b600081838161484b57fe5b04905080156149075760005b848110156148a957816001828154811061486d57fe5b906000526020600020906004020160030154016001828154811061488d57fe5b6000918252602090912060036004909202010155600101614857565b50600180549085015b818110156149045782600182815481106148c857fe5b90600052602060002090600402016003015401600182815481106148e857fe5b60009182526020909120600360049092020101556001016148b2565b50505b5091949350505050565b614919615e59565b506040805180820190915281518152602082810190820152919050565b61493e615d12565b61494782615661565b61495057600080fd5b600061495f836020015161569b565b60208085015160408051808201909152868152920190820152915050919050565b600061498a615e59565b505080518051602091820151919092015191011190565b6149a9615e59565b6149b282614980565b6149bb57600080fd5b602082015160006149cb826156fe565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590614a0457508151602110155b614a0d57600080fd5b6000614a1c836020015161569b565b90508083600001511015614a425760405162461bcd60e51b8152600401610c3b90616b30565b82516020808501518301805192849003929183101561451857506020919091036101000a90049392505050565b6060614a7a82615661565b614a8357600080fd5b6000614a8e836157df565b9050606081604051908082528060200260200182016040528015614acc57816020015b614ab9615e59565b815260200190600190039081614ab15790505b5090506000614ade856020015161569b565b60208601510190506000805b84811015614b3557614afb836156fe565b9150604051806040016040528083815260200184815250848281518110614b1e57fe5b602090810291909101015291810191600101614aea565b509195945050505050565b614b48615d32565b60606000614b54615d32565b6060614b5e615d12565b614b6787614936565b90506000805b614b7683614980565b15614c4b5780614ba157614b91614b8c846149a1565b61583b565b6001600160a01b03168552614c43565b8060011415614bc957614bb6614b8c846149a1565b6001600160a01b03166020860152614c43565b8060021415614bf157614bde614b8c846149a1565b6001600160a01b03166040860152614c43565b8060031415614c1d57614c06612f85846149a1565b6001600160401b0316606086015260019150614c43565b8060041415614c3e57614c37614c32846149a1565b615855565b9350614c43565b614c4b565b600101614b6d565b50929791965091945092505050565b60606113dd614c68836158c5565b6159ab565b6060815160001415614c8e575060408051600081526020810190915261132d565b606082600081518110614c9d57fe5b602002602001015190506000600190505b8351811015614cde57614cd482858381518110614cc757fe5b60200260200101516159fd565b9150600101614cae565b50610ea2614cf1825160c060ff16615a7a565b826159fd565b606080600080808080614d086126c9565b6001549091505b8015614e1657600181039250600b8381548110614d2857fe5b600091825260209091206001601690920201015460ff16614d4857614e0d565b60018381548110614d5557fe5b60009182526020909120600490910201546001600160a01b03169450614d7c858484612d49565b9350831580614d8f575060018a51038610155b15614d9957614e0d565b60005b8a51811015614e0b57856001600160a01b03168b8281518110614dbb57fe5b6020026020010151600001516001600160a01b03161415614e035760018b8281518110614de457fe5b6020908102919091010151901515608090910152600190960195614e0b565b600101614d9c565b505b60001901614d0f565b5084895103604051908082528060200260200182016040528015614e5457816020015b614e41615d32565b815260200190600190039081614e395790505b50965084895103604051908082528060200260200182016040528015614e8e57816020015b6060815260200190600190039081614e795790505b5095506000915060005b8951811015614f2257898181518110614ead57fe5b602002602001015160800151614f1a57898181518110614ec957fe5b6020026020010151888481518110614edd57fe5b6020026020010181905250888181518110614ef457fe5b6020026020010151878481518110614f0857fe5b60200260200101819052508260010192505b600101614e98565b5050505050505b9250929050565b600154825160005b8281101561504d576001614f4a615d32565b60018381548110614f5757fe5b600091825260208083206040805160c08101825260049490940290910180546001600160a01b0390811685526001820154811693850193909352600281015492831691840191909152600160a01b82046001600160401b03166060840152600160e01b90910460ff16151560808301526003015460a082015291505b8481101561502157878181518110614fe757fe5b6020026020010151600001516001600160a01b031682600001516001600160a01b031614156150195760009250615021565b600101614fd3565b5081156150435780516001600160a01b03166000908152600460205260408120555b5050600101614f38565b508082111561510c57805b8281101561510a57600180548061506b57fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b8054806150be57fe5b60008281526020812060166000199093019283020181815560018101805460ff19169055906150f06002830182615e06565b6150fe600383016000615e4a565b50509055600101615058565b505b600081831061511b578161511d565b825b905060005b818110156153b0576151cf86828151811061513957fe5b60200260200101516001838154811061514e57fe5b60009182526020918290206040805160c08101825260049390930290910180546001600160a01b0390811684526001820154811694840194909452600281015493841691830191909152600160a01b83046001600160401b03166060830152600160e01b90920460ff161515608082015260039091015460a0820152615b4c565b6153835780600101600460008884815181106151e757fe5b6020026020010151600001516001600160a01b03166001600160a01b031681526020019081526020016000208190555085818151811061522357fe5b60200260200101516001828154811061523857fe5b6000918252602091829020835160049092020180546001600160a01b039283166001600160a01b0319918216178255928401516001820180549184169185169190911790556040840151600282018054606087015160808801511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909716929097169190911792909216939093171692909217905560a09091015160039091015584518590829081106152f357fe5b6020026020010151600b828154811061530857fe5b9060005260206000209060160201600201908051906020019061532c929190615c47565b506000600b828154811061533c57fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b80548390811061536d57fe5b60009182526020909120601690910201556153a8565b60006001828154811061539257fe5b9060005260206000209060040201600301819055505b600101615122565b5082821115615588576153c1615c18565b835b83811015615585578581815181106153d757fe5b6020026020010151826040018190525060018782815181106153f557fe5b6020908102919091018101518254600181810185556000948552838520835160049093020180546001600160a01b039384166001600160a01b0319918216178255848601518284018054918616918316919091179055604080860151600284018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909a1692909616919091179290921696909617169190911790935560a090930151600390930192909255600b8054928301815590935284516016909102600080516020616ffb83398151915281019182558583015160008051602061703b8339815191528201805491151560ff199092169190911790559285015180518694929361552b9360008051602061701b83398151915201920190615c47565b5060608201516155419060038301906013615cc1565b505050806001016004600089848151811061555857fe5b602090810291909101810151516001600160a01b03168252810191909152604001600020556001016153c3565b50505b6000600981905560015493505b838110156155f6576000600b82815481106155ac57fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b8054839081106155dd57fe5b6000918252602090912060169091020155600101615595565b505050505050565b600081848411156156225760405162461bcd60e51b8152600401610c3b919061631b565b505050900390565b6000818361564b5760405162461bcd60e51b8152600401610c3b919061631b565b50600083858161565757fe5b0495945050505050565b80516000906156725750600061132d565b6020820151805160001a9060c08210156156915760009250505061132d565b5060019392505050565b8051600090811a60808110156156b557600091505061132d565b60b88110806156d0575060c081108015906156d0575060f881105b156156df57600191505061132d565b60c08110156156f35760b51901905061132d565b60f51901905061132d565b80516000908190811a608081101561571957600191506157d8565b60b881101561572e57607e19810191506157d8565b60c081101561577f57600060b78203600186019550806020036101000a8651049150600181018201935050808310156157795760405162461bcd60e51b8152600401610c3b906168bf565b506157d8565b60f88110156157945760be19810191506157d8565b600060f78203600186019550806020036101000a8651049150600181018201935050808310156157d65760405162461bcd60e51b8152600401610c3b906168bf565b505b5092915050565b80516000906157f05750600061132d565b60008090506000615804846020015161569b565b602085015185519181019250015b8082101561583257615823826156fe565b82019150826001019250615812565b50909392505050565b805160009060151461584c57600080fd5b6113dd826149ef565b805160609061586357600080fd5b6000615872836020015161569b565b83516040805191839003808352601f19601f82011683016020019091529192506060908280156158a9576020820181803683370190505b5090506000816020019050614518848760200151018285615bcd565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166159095750601861592d565b6fffffffffffffffffffffffffffffffff1984166159295750601061592d565b5060005b60208110156159635781818151811061594257fe5b01602001516001600160f81b0319161561595b57615963565b60010161592d565b60008160200390506060816040519080825280601f01601f191660200182016040528015615998576020820181803683370190505b5080830196909652508452509192915050565b6060815160011480156159dd5750607f60f81b826000815181106159cb57fe5b01602001516001600160f81b03191611155b156159e957508061132d565b6113dd6159fb8351608060ff16615a7a565b835b6060806040519050835180825260208201818101602087015b81831015615a2e578051835260209283019201615a16565b50855184518101855292509050808201602086015b81831015615a5b578051835260209283019201615a43565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310615aa45760405162461bcd60e51b8152600401610c3b906166c3565b60408051600180825281830190925260609160208201818036833701905050905060378411615afe5782840160f81b81600081518110615ae057fe5b60200101906001600160f81b031916908160001a90535090506113dd565b6060615b09856158c5565b90508381510160370160f81b82600081518110615b2257fe5b60200101906001600160f81b031916908160001a905350615b4382826159fd565b95945050505050565b805182516000916001600160a01b039182169116148015615b86575081602001516001600160a01b031683602001516001600160a01b0316145b8015615bab575081604001516001600160a01b031683604001516001600160a01b0316145b8015610ea25750506060908101519101516001600160401b0390811691161490565b80615bd757610c5b565b5b60208110615bf7578251825260209283019290910190601f1901615bd8565b915181516020939093036101000a6000190180199091169216919091179052565b60405180608001604052806000815260200160001515815260200160608152602001615c42615e73565b905290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615c8857805160ff1916838001178555615cb5565b82800160010185558215615cb5579182015b82811115615cb5578251825591602001919060010190615c9a565b50612704929150615e92565b8260138101928215615cb55791602002820182811115615cb5578251825591602001919060010190615c9a565b6040518060600160405280600060ff16815260200160608152602001606081525090565b6040518060400160405280615d25615e59565b8152602001600081525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615da05780548555615cb5565b82800160010185558215615cb557600052602060002091601f016020900482015b82811115615cb5578254825591600101919060010190615dc1565b8260138101928215615cb55791820182811115615cb5578254825591600101919060010190615dc1565b50805460018160011615610100020316600290046000825580601f10615e2c5750611539565b601f0160209004906000526020600020908101906115399190615e92565b50611539906013810190615e92565b604051806040016040528060008152602001600081525090565b6040518061026001604052806013906020820280368337509192915050565b6126b691905b808211156127045760008155600101615e98565b60008083601f840112615ebd578182fd5b5081356001600160401b03811115615ed3578182fd5b6020830191508360208083028501011115614f2957600080fd5b60008083601f840112615efe578182fd5b5081356001600160401b03811115615f14578182fd5b602083019150836020828501011115614f2957600080fd5b600060208284031215615f3d578081fd5b81356001600160a01b0381168114610ea2578182fd5b60008060008060408587031215615f68578283fd5b84356001600160401b0380821115615f7e578485fd5b615f8a88838901615eac565b90965094506020870135915080821115615fa2578384fd5b50615faf87828801615eac565b95989497509550505050565b600060208284031215615fcc578081fd5b81518015158114610ea2578182fd5b60008060008060408587031215615ff0578384fd5b84356001600160401b0380821115616006578586fd5b61601288838901615eed565b9096509450602087013591508082111561602a578384fd5b50615faf87828801615eed565b600060208284031215616048578081fd5b5035919050565b600060208284031215616060578081fd5b5051919050565b60008060408385031215616079578182fd5b505080516020909101519092909150565b60008060006040848603121561609e578283fd5b833560ff811681146160ae578384fd5b925060208401356001600160401b038111156160c8578283fd5b6160d486828701615eed565b9497909650939450505050565b6000815180845260208085019450808401835b838110156161195781516001600160a01b0316875295820195908201906001016160f4565b509495945050505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452616166816020860160208601616e03565b601f01601f19169290920160200192915050565b6000825161618c818460208701616e03565b9190910192915050565b918252602082015260400190565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03968716815294861660208601529290941660408401526001600160401b03166060830152911515608082015260a081019190915260c00190565b600060208252610ea260208301846160e1565b60006040825261623960408301856160e1565b602083820381850152818551808452828401915082838202850101838801865b8381101561628757601f1987840301855261627583835161614e565b94860194925090850190600101616259565b50909998505050505050505050565b6000608082526162a960808301876160e1565b828103602084810191909152865180835287820192820190845b818110156162df578451835293830193918301916001016162c3565b505084810360408601526162f381886160e1565b93505050506001600160401b038316606083015295945050505050565b901515815260200190565b600060208252610ea2602083018461614e565b600060408252616342604083018688616124565b8281036020840152616355818587616124565b979650505050505050565b6020808252601c908201527f6c656e677468206f66206275726e526174696f206d69736d6174636800000000604082015260600190565b60208082526026908201527f6c656e677468206f66206d61784e756d4f664d61696e7461696e696e67206d696040820152650e6dac2e8c6d60d31b606082015260800190565b6020808252601b908201527f6261746368207472616e736665722072657475726e2066616c73650000000000604082015260600190565b6020808252602c908201527f6c656e677468206f66206d61784e756d4f66576f726b696e6743616e6469646160408201526b0e8cae640dad2e6dac2e8c6d60a31b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61696e7461696e536c6173685363616c65206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252818101527f6c656e677468206f66206e756d4f66436162696e657473206d69736d61746368604082015260600190565b60208082526019908201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526028908201527f746865206e756d4f66436162696e657473206d75737420626520677265617465604082015267072207468616e20360c41b606082015260800190565b60208082526039908201527f746865206e756d4f66436162696e657473206d757374206265206c657373207460408201527f68616e204d41585f4e554d5f4f465f56414c494441544f525300000000000000606082015260800190565b60208082526029908201527f746865206e756d626572206f662076616c696461746f727320657863656564206040820152681d1a19481b1a5b5a5d60ba1b606082015260800190565b60208082526022908201527f63616e206e6f7420646f207468697320747769636520696e206f6e6520626c6f604082015261636b60f01b606082015260800190565b6020808252602b908201527f746865206275726e526174696f206d757374206265206e6f206772656174657260408201526a0207468616e2031303030360ac1b606082015260800190565b6020808252600e908201526d696e70757420746f6f206c6f6e6760901b604082015260600190565b60208082526037908201527f746865206d61784e756d4f664d61696e7461696e696e67206d7573742062652060408201527f6c657373207468616e206e756d4f66436162696e657473000000000000000000606082015260800190565b6020808252602b908201527f6475706c696361746520636f6e73656e7375732061646472657373206f66207660408201526a185b1a59185d1bdc94d95d60aa1b606082015260800190565b60208082526027908201527f7468652065787069726554696d655365636f6e64476170206973206f7574206f604082015266662072616e676560c81b606082015260800190565b6020808252601590820152746465706f7369742076616c7565206973207a65726f60581b604082015260600190565b60208082526049908201527f746865206d61784e756d4f66576f726b696e6743616e64696461746573206d7560408201527f7374206265206e6f742067726561746572207468616e206d61784e756d4f6643606082015268616e6469646174657360b81b608082015260a00190565b60208082526027908201527f7468652066696e616c697479526577617264526174696f206973206f7574206f604082015266662072616e676560c81b606082015260800190565b6020808252601190820152706164646974696f6e206f766572666c6f7760781b604082015260600190565b60208082526023908201527f63616e206e6f7420656e7465722054656d706f72617279204d61696e74656e616040820152626e636560e81b606082015260800190565b60208082526025908201527f6c656e677468206f66206a61696c2076616c696461746f7273206d757374206260408201526465206f6e6560d81b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252602e908201527f746865206d6573736167652073656e646572206d75737420626520676f76657260408201526d1b985b98d94818dbdb9d1c9858dd60921b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61784e756d4f6643616e64696461746573206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252601290820152716e6f7420696e206d61696e74656e616e636560701b604082015260600190565b60208082526021908201527f666565206973206c6172676572207468616e2044555354595f494e434f4d494e6040820152604760f81b606082015260800190565b60208082526019908201527f74686520636f6e747261637420616c726561647920696e697400000000000000604082015260600190565b60208082526026908201527f6c656e677468206f662066696e616c697479526577617264526174696f206d696040820152650e6dac2e8c6d60d31b606082015260800190565b6020808252601a908201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604082015260600190565b60208082526026908201527f6c656e677468206f662065787069726554696d655365636f6e64476170206d696040820152650e6dac2e8c6d60d31b606082015260800190565b60208082526017908201527f6f6e6c792063757272656e742076616c696461746f7273000000000000000000604082015260600190565b60208082526021908201527f6661696c656420746f20706172736520696e69742076616c696461746f7253656040820152601d60fa1b606082015260800190565b6020808252602f908201527f746865206d6573736167652073656e646572206d7573742062652063726f737360408201526e0818da185a5b8818dbdb9d1c9858dd608a1b606082015260800190565b6020808252602d908201527f746865206d6573736167652073656e646572206d75737420626520746865206260408201526c3637b1b590383937b23ab1b2b960991b606082015260800190565b6020808252603e908201527f746865206d61696e7461696e536c6173685363616c65206d757374206265206760408201527f726561746572207468616e203020616e64206c657373207468616e2031300000606082015260800190565b6020808252600d908201526c756e6b6e6f776e20706172616d60981b604082015260600190565b60208082526029908201527f746865206d6573736167652073656e646572206d75737420626520736c6173686040820152680818dbdb9d1c9858dd60ba1b606082015260800190565b61ffff91909116815260200190565b90815260200190565b6000848252831515602083015260606040830152615b43606083018461614e565b63ffffffff91909116815260200190565b60ff91909116815260200190565b600060ff8516825260406020830152615b43604083018486616124565b60005b83811015616e1e578181015183820152602001616e06565b83811115612c69575050600091015256fef901a880f901a4f844941284214b9b9c85549ab3d2b972df0deef66ac2c9946ddf42a51534fc98d0c0a3b42c963cace8441ddf946ddf42a51534fc98d0c0a3b42c963cace8441ddf8410000000f84494a2959d3f95eae5dc7d70144ce1b73b403b7eb6e0948081ef03f1d9e0bb4a5bf38f16285c879299f07f948081ef03f1d9e0bb4a5bf38f16285c879299f07f8410000000f8449435552c16704d214347f29fa77f77da6d75d7c75294dc4973e838e3949c77aced16ac2315dc2d7ab11194dc4973e838e3949c77aced16ac2315dc2d7ab1118410000000f84494980a75ecd1309ea12fa2ed87a8744fbfc9b863d594cc6ac05c95a99c1f7b5f88de0e3486c82293b27094cc6ac05c95a99c1f7b5f88de0e3486c82293b2708410000000f84494f474cf03cceff28abc65c9cbae594f725c80e12d94e61a183325a18a173319dd8e19c8d069459e217594e61a183325a18a173319dd8e19c8d069459e21758410000000f84494b71b214cb885500844365e95cd9942c7276e7fd894d22ca3ba2141d23adab65ce4940eb7665ea2b6a794d22ca3ba2141d23adab65ce4940eb7665ea2b6a7841000000070e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb20175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db90175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbb0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbaa264697066735822122066baf1b414176214a54e961d8a8bfa2613b6bb53f85786a9a7171a3bac231aa564736f6c63430006040033", + }, + { + ContractAddr: common.HexToAddress(SlashContract), + CommitUrl: "https://github.com/node-real/bsc-genesis-contract/commit/f8bab13f56955e979bfb754425dab1e62e52f151", + Code: "608060405234801561001057600080fd5b50600436106102745760003560e01c80638256ace611610151578063c81b1662116100c3578063dc927faf11610087578063dc927faf1461049a578063e1c7392a146104a2578063f9a2bbc7146104aa578063fc3e5908146104b2578063fc4333cd146104ba578063fd6a6879146104c257610274565b8063c81b166214610451578063c8509d8114610459578063c96be4cb1461046c578063cc844b731461047f578063d2a42e4b1461049257610274565b8063a1a11bf511610115578063a1a11bf514610409578063a78abc1614610411578063ab51bb9614610426578063ac0af6291461042e578063ac43175114610436578063c80d4b8f1461044957610274565b80638256ace6146103d6578063831d65d1146103de57806396713da9146103f15780639bc8e4f2146103f95780639dc092621461040157610274565b80634bf6c882116101ea5780636e47b482116101ae5780636e47b482146103a657806370fd5bad146103ae578063718a8aa8146103b657806375d47a0a146103be5780637912a65d146103c65780637942fd05146103ce57610274565b80634bf6c8821461037157806351e8067214610379578063567a372d146103815780635bfb49901461038957806362b72cf51461039e57610274565b806337c8dab91161023c57806337c8dab914610301578063389f4f71146103225780633a63f4b1146103375780633dffc3871461033f57806343756e5c14610354578063493279b11461035c57610274565b80630bee7a67146102795780630e2374a5146102975780631182b875146102ac57806323bac5a2146102cc57806335aa2e44146102ee575b600080fd5b6102816104ca565b60405161028e9190613056565b60405180910390f35b61029f6104cf565b60405161028e9190612987565b6102bf6102ba3660046128bd565b6104d5565b60405161028e91906129bf565b6102df6102da36600461266b565b61053b565b60405161028e9392919061303e565b61029f6102fc36600461288d565b61055e565b61031461030f36600461266b565b610585565b60405161028e929190613030565b61032a6105dc565b60405161028e9190613006565b61032a6105e2565b6103476105e8565b60405161028e9190613067565b61029f6105ed565b6103646105f3565b60405161028e9190612ff7565b6103476105f8565b61029f6105fd565b61032a610603565b61039c61039736600461266b565b610609565b005b61032a6106b4565b61029f6106ba565b6103476106c0565b6103476106c5565b61029f6106ca565b61032a6106d0565b6103476106d5565b6103146106da565b61039c6103ec3660046128bd565b6106e4565b6103476107f6565b61032a6107fb565b61029f610806565b61029f61080c565b610419610812565b60405161028e91906129b4565b61028161081b565b61032a610820565b61039c610444366004612771565b610825565b61032a610bd9565b61029f610bde565b61039c6104673660046128bd565b610be4565b61039c61047a36600461266b565b610c55565b61039c61048d3660046127da565b611046565b61032a61151c565b61029f611521565b61039c611527565b61029f611563565b610347611569565b61039c61156e565b61029f6119b7565b606481565b61200181565b606033612000146105015760405162461bcd60e51b81526004016104f890612e7d565b60405180910390fd5b60005460ff166105235760405162461bcd60e51b81526004016104f890612a6b565b60405162461bcd60e51b81526004016104f890612f40565b600260208190526000918252604090912080546001820154919092015460ff1683565b6001818154811061056b57fe5b6000918252602090912001546001600160a01b0316905081565b600080610590612452565b5050506001600160a01b0316600090815260026020818152604092839020835160608101855281548082526001830154938201849052919093015460ff16151592909301919091529091565b60055481565b60065481565b600181565b61100181565b606181565b600881565b61200081565b60045481565b336110001461062a5760405162461bcd60e51b81526004016104f890612c91565b60005460ff1661064c5760405162461bcd60e51b81526004016104f890612a6b565b61200063f7a251d7600b61065f846119bd565b60006040518463ffffffff1660e01b815260040161067f93929190613075565b600060405180830381600087803b15801561069957600080fd5b505af11580156106ad573d6000803e3d6000fd5b5050505050565b60035481565b61100581565b600281565b601081565b61100881565b603281565b600b81565b6004546005549091565b33612000146107055760405162461bcd60e51b81526004016104f890612e7d565b60005460ff166107275760405162461bcd60e51b81526004016104f890612a6b565b61072f612475565b600061077084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a8f92505050565b9150915080156107b75781516040517f7f0956d47419b9525356e7111652b653b530ec6f5096dccc04589bc38e629967916107aa91613056565b60405180910390a16106ad565b81516040517f7d45f62d17443dd4547bca8a8112c60e2385669318dc300ec61a5d2492f262e7916107e791613056565b60405180910390a15050505050565b600981565b662386f26fc1000081565b61100781565b61100681565b60005460ff1681565b600081565b600481565b60005460ff166108475760405162461bcd60e51b81526004016104f890612a6b565b33611007146108685760405162461bcd60e51b81526004016104f890612d3a565b6108d384848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260148152731b5a5cd9195b59585b9bdc951a1c995cda1bdb1960621b60208201529150611b0f9050565b1561096e57602081146108f85760405162461bcd60e51b81526004016104f890612c1d565b604080516020601f840181900481028201810190925282815260009161093691858580838501838280828437600092019190915250611b6992505050565b90506001811015801561094a575060055481105b6109665760405162461bcd60e51b81526004016104f890612e38565b600455610b96565b6109d484848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e19995b1bdb9e551a1c995cda1bdb19608a1b60208201529150611b0f9050565b15610a7057602081146109f95760405162461bcd60e51b81526004016104f890612d88565b604080516020601f8401819004810282018101909252828152600091610a3791858580838501838280828437600092019190915250611b6992505050565b90506103e88111158015610a4c575060045481115b610a685760405162461bcd60e51b81526004016104f890612ad9565b600555610b96565b610ae484848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601881527f66696e616c697479536c617368526577617264526174696f000000000000000060208201529150611b0f9050565b15610b7e5760208114610b095760405162461bcd60e51b81526004016104f890612f77565b604080516020601f8401819004810282018101909252828152600091610b4791858580838501838280828437600092019190915250611b6992505050565b9050600a8110158015610b5a5750606481105b610b765760405162461bcd60e51b81526004016104f890612bd1565b600655610b96565b60405162461bcd60e51b81526004016104f890612f19565b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a84848484604051610bcb94939291906129d2565b60405180910390a150505050565b609681565b61100281565b3361200014610c055760405162461bcd60e51b81526004016104f890612e7d565b60005460ff16610c275760405162461bcd60e51b81526004016104f890612a6b565b6040517f07db600eebe2ac176be8dcebad61858c245a4961bb32ca2aa3d159b09aa0810e90600090a1505050565b334114610c745760405162461bcd60e51b81526004016104f890612ecc565b60005460ff16610c965760405162461bcd60e51b81526004016104f890612a6b565b6003544311610cb75760405162461bcd60e51b81526004016104f890612fc2565b3a15610cd55760405162461bcd60e51b81526004016104f890612d0c565b60405163155853f360e21b8152611000906355614fcc90610cfa908490600401612987565b60206040518083038186803b158015610d1257600080fd5b505afa158015610d26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4a9190612751565b610d535761103f565b610d5b612452565b506001600160a01b0381166000908152600260208181526040928390208351606081018552815481526001820154928101929092529091015460ff161580159282019290925290610db6576020810180516001019052610e0f565b60016040820181905260208201819052805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0384161790555b438152600554602082015181610e2157fe5b06610f6d57600060208201526040516335409f7f60e01b8152611000906335409f7f90610e52908590600401612987565b600060405180830381600087803b158015610e6c57600080fd5b505af1158015610e80573d6000803e3d6000fd5b505050506120006001600160a01b031663f7a251d7600b610ea0856119bd565b60006040518463ffffffff1660e01b8152600401610ec093929190613075565b600060405180830381600087803b158015610eda57600080fd5b505af1925050508015610eeb575060015b610f68573d808015610f19576040519150601f19603f3d011682016040523d82523d6000602084013e610f1e565b606091505b50826001600160a01b03167fd7bc86ff5d08c8ab043edec743302aba2520e6635172a428bc956721db9e2d1c836020015183604051610f5e92919061300f565b60405180910390a2505b610fd9565b600454816020015181610f7c57fe5b06610fd9576040516375abf10160e11b81526110009063eb57e20290610fa6908590600401612987565b600060405180830381600087803b158015610fc057600080fd5b505af1158015610fd4573d6000803e3d6000fd5b505050505b6001600160a01b0382166000818152600260208181526040808420865181559186015160018301558581015191909201805460ff1916911515919091179055517fddb6012116e51abf5436d956a4f0ebd927e92c576ff96d7918290c8782291e3e9190a2505b5043600355565b60005460ff166110685760405162461bcd60e51b81526004016104f890612a6b565b604051630a83aaa960e31b81526110069063541d55489061108d903390600401612987565b60206040518083038186803b1580156110a557600080fd5b505afa1580156110b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110dd9190612751565b6110f95760405162461bcd60e51b81526004016104f890612a04565b6006546111065760146006555b8051514361010090910111801561112857504381602001516000015161010001115b6111445760405162461bcd60e51b81526004016104f890612a3b565b8060200151602001518160000151602001511480156111725750806020015160600151816000015160600151145b1561118f5760405162461bcd60e51b81526004016104f890612c64565b8051604081015190511080156111ae5750602081015160408101519051105b6111ca5760405162461bcd60e51b81526004016104f890612b6d565b6020810151518151511080156111ef5750806000015160400151816020015160400151105b8061121a575080515160208201515110801561121a5750806020015160400151816000015160400151105b806112345750806020015160400151816000015160400151145b6112505760405162461bcd60e51b81526004016104f890612aa2565b6060806110006001600160a01b0316633b071dcc6040518163ffffffff1660e01b815260040160006040518083038186803b15801561128e57600080fd5b505afa1580156112a2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526112ca919081019061268e565b60408501519193509150600090815b8351811015611327576112ff8482815181106112f157fe5b602002602001015183611b6e565b1561131f5784818151811061131057fe5b60200260200101519250611327565b6001016112d9565b506001600160a01b03821661134e5760405162461bcd60e51b81526004016104f890612ba4565b61136085600001518660400151611bd2565b8015611379575061137985602001518660400151611bd2565b6113955760405162461bcd60e51b81526004016104f890612b0e565b6006546040516309a99b4f60e41b815260646110028031909302049190639a99b4f0906113c8903390859060040161299b565b602060405180830381600087803b1580156113e257600080fd5b505af11580156113f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141a91906128a5565b506040516335409f7f60e01b8152611000906335409f7f90611440908690600401612987565b600060405180830381600087803b15801561145a57600080fd5b505af115801561146e573d6000803e3d6000fd5b505050506120006001600160a01b031663f7a251d7600b61148e866119bd565b60006040518463ffffffff1660e01b81526004016114ae93929190613075565b600060405180830381600087803b1580156114c857600080fd5b505af11580156114dc573d6000803e3d6000fd5b50506040516001600160a01b03861692507fddb6012116e51abf5436d956a4f0ebd927e92c576ff96d7918290c8782291e3e9150600090a2505050505050565b601481565b61100381565b60005460ff161561154a5760405162461bcd60e51b81526004016104f890612dca565b603260045560966005556000805460ff19166001179055565b61100081565b600381565b336110001461158f5760405162461bcd60e51b81526004016104f890612c91565b60005460ff166115b15760405162461bcd60e51b81526004016104f890612a6b565b6001546115bd576119b5565b600154600090600019015b808211611989576000805b828410156116ec576115e3612452565b60026000600187815481106115f457fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff1615159082015260055490915060049004816020015111156116d65760046005548161166157fe5b0481602001510381602001818152505080600260006001888154811061168357fe5b6000918252602080832091909101546001600160a01b0316835282810193909352604091820190208351815591830151600183015591909101516002909101805460ff19169115159190911790556116e0565b60019250506116ec565b508360010193506115d3565b828411611883576116fb612452565b600260006001868154811061170c57fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff1615159082015260055490915060049004816020015111156117f45760046005548161177957fe5b0481602001510381602001818152505080600260006001878154811061179b57fe5b6000918252602080832091909101546001600160a01b03168352828101939093526040918201902083518155918301516001808401919091559201516002909101805460ff191691151591909117905591506118839050565b600260006001868154811061180557fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff1916905580548061184957fe5b600082815260209020810160001990810180546001600160a01b0319169055019055836118765750611883565b50600019909201916116ec565b81801561188d5750805b1561196c5760026000600186815481106118a357fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff191690558054849081106118ea57fe5b600091825260209091200154600180546001600160a01b03909216918690811061191057fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600180548061194957fe5b600082815260209020810160001990810180546001600160a01b03191690550190555b82611978575050611989565b5050600190910190600019016115c8565b6040517fcfdb3b6ccaeccbdc68be3c59c840e3b3c90f0a7c491f5fff1cf56cfda200dd9c90600090a150505b565b61100481565b60408051600480825260a08201909252606091829190816020015b60608152602001906001900390816119d8579050509050611a01836001600160a01b0316611daa565b81600081518110611a0e57fe5b6020026020010181905250611a2243611dcd565b81600181518110611a2f57fe5b6020908102919091010152611a446061611dcd565b81600281518110611a5157fe5b6020026020010181905250611a6542611dcd565b81600381518110611a7257fe5b6020026020010181905250611a8681611de0565b9150505b919050565b611a97612475565b6000611aa1612475565b611aa9612487565b611aba611ab586611e6a565b611e8f565b90506000805b611ac983611ed9565b15611b025780611af557611ae4611adf84611efa565b611f48565b63ffffffff16845260019150611afa565b611b02565b600101611ac0565b5091935090915050915091565b600081604051602001611b22919061296b565b6040516020818303038152906040528051906020012083604051602001611b49919061296b565b604051602081830303815290604052805190602001201490505b92915050565b015190565b815181516000916001918114808314611b8a5760009250611bc8565b600160208701838101602088015b600284838510011415611bc3578051835114611bb75760009650600093505b60209283019201611b98565b505050505b5090949350505050565b60408051600480825260a0820190925260009160609190816020015b6060815260200190600190039081611bee575050604080516020808252818301909252919250606091908082018180368337019050509050611c338560000151611dcd565b82600081518110611c4057fe5b6020026020010181905250611c5b6020866020015183611fca565b611c6481611fda565b82600181518110611c7157fe5b6020026020010181905250611c898560400151611dcd565b82600281518110611c9657fe5b6020026020010181905250611cb16020866060015183611fca565b611cba81611fda565b82600381518110611cc757fe5b6020026020010181905250611ced6020611ce084611de0565b8051906020012083611fca565b6040805160b080825260e08201909252606091602082018180368337019050509050611d1d818360006020612030565b611d2f81876080015160206060612030565b611d3d818660806030612030565b604080516001808252818301909252606091602082018180368337019050509050815160016020830182602086016066600019fa611d7a57600080fd5b506001611d88826000612083565b60ff1614611d9d576000945050505050611b63565b5060019695505050505050565b60408051600560a21b8318601482015260348101909152606090611a8681611fda565b6060611b63611ddb8361209f565b611fda565b6060815160001415611e015750604080516000815260208101909152611a8a565b606082600081518110611e1057fe5b602002602001015190506000600190505b8351811015611e5157611e4782858381518110611e3a57fe5b6020026020010151612185565b9150600101611e21565b50611a86611e64825160c060ff16612202565b82612185565b611e726124a7565b506040805180820190915281518152602082810190820152919050565b611e97612487565b611ea0826122d4565b611ea957600080fd5b6000611eb8836020015161230e565b60208085015160408051808201909152868152920190820152915050919050565b6000611ee36124a7565b505080518051602091820151919092015191011190565b611f026124a7565b611f0b82611ed9565b611f1457600080fd5b60208201516000611f2482612371565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590611f5d57508151602110155b611f6657600080fd5b6000611f75836020015161230e565b90508083600001511015611f9b5760405162461bcd60e51b81526004016104f890612e01565b825160208085015183018051928490039291831015611fc157826020036101000a820491505b50949350505050565b9091018181526020918201910152565b60608151600114801561200c5750607f60f81b82600081518110611ffa57fe5b01602001516001600160f81b03191611155b15612018575080611a8a565b611b6361202a8351608060ff16612202565b83612185565b60005b818110156106ad5783818151811061204757fe5b602001015160f81c60f81b85848060010195508151811061206457fe5b60200101906001600160f81b031916908160001a905350600101612033565b6000816001018351101561209657600080fd5b50016001015190565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166120e357506018612107565b6fffffffffffffffffffffffffffffffff19841661210357506010612107565b5060005b602081101561213d5781818151811061211c57fe5b01602001516001600160f81b031916156121355761213d565b600101612107565b60008160200390506060816040519080825280601f01601f191660200182016040528015612172576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b818310156121b657805183526020928301920161219e565b50855184518101855292509050808201602086015b818310156121e35780518352602092830192016121cb565b508651929092011591909101601f01601f191660405250905092915050565b606068010000000000000000831061222c5760405162461bcd60e51b81526004016104f890612b45565b604080516001808252818301909252606091602082018180368337019050509050603784116122865782840160f81b8160008151811061226857fe5b60200101906001600160f81b031916908160001a9053509050611b63565b60606122918561209f565b90508381510160370160f81b826000815181106122aa57fe5b60200101906001600160f81b031916908160001a9053506122cb8282612185565b95945050505050565b80516000906122e557506000611a8a565b6020820151805160001a9060c082101561230457600092505050611a8a565b5060019392505050565b8051600090811a6080811015612328576000915050611a8a565b60b8811080612343575060c08110801590612343575060f881105b15612352576001915050611a8a565b60c08110156123665760b519019050611a8a565b60f519019050611a8a565b80516000908190811a608081101561238c576001915061244b565b60b88110156123a157607e198101915061244b565b60c08110156123f257600060b78203600186019550806020036101000a8651049150600181018201935050808310156123ec5760405162461bcd60e51b81526004016104f890612ce1565b5061244b565b60f88110156124075760be198101915061244b565b600060f78203600186019550806020036101000a8651049150600181018201935050808310156124495760405162461bcd60e51b81526004016104f890612ce1565b505b5092915050565b604051806060016040528060008152602001600081526020016000151581525090565b60408051602081019091526000815290565b604051806040016040528061249a6124a7565b8152602001600081525090565b604051806040016040528060008152602001600081525090565b600082601f8301126124d1578081fd5b81516124e46124df826130c8565b6130a1565b818152915060208083019084810160005b8481101561255a578151870188603f82011261251057600080fd5b838101516125206124df826130e8565b81815260408b8184860101111561253657600080fd5b6125458388840183870161310c565b508652505092820192908201906001016124f5565b505050505092915050565b60008083601f840112612576578182fd5b50813567ffffffffffffffff81111561258d578182fd5b6020830191508360208285010111156125a557600080fd5b9250929050565b600082601f8301126125bc578081fd5b81356125ca6124df826130e8565b91508082528360208285010111156125e157600080fd5b8060208401602084013760009082016020015292915050565b600060a0828403121561260b578081fd5b61261560a06130a1565b905081358152602082013560208201526040820135604082015260608201356060820152608082013567ffffffffffffffff81111561265357600080fd5b61265f848285016125ac565b60808301525092915050565b60006020828403121561267c578081fd5b81356126878161313c565b9392505050565b600080604083850312156126a0578081fd5b825167ffffffffffffffff808211156126b7578283fd5b81850186601f8201126126c8578384fd5b805192506126d86124df846130c8565b80848252602080830192508084018a8283890287010111156126f8578788fd5b8794505b8685101561272357805161270f8161313c565b8452600194909401939281019281016126fc565b50880151909650935050508082111561273a578283fd5b50612747858286016124c1565b9150509250929050565b600060208284031215612762578081fd5b81518015158114612687578182fd5b60008060008060408587031215612786578182fd5b843567ffffffffffffffff8082111561279d578384fd5b6127a988838901612565565b909650945060208701359150808211156127c1578384fd5b506127ce87828801612565565b95989497509550505050565b6000602082840312156127eb578081fd5b813567ffffffffffffffff80821115612802578283fd5b81840160608187031215612814578384fd5b61281e60606130a1565b925080358281111561282e578485fd5b61283a878284016125fa565b84525060208101358281111561284e578485fd5b61285a878284016125fa565b602085015250604081013582811115612871578485fd5b61287d878284016125ac565b6040850152509195945050505050565b60006020828403121561289e578081fd5b5035919050565b6000602082840312156128b6578081fd5b5051919050565b6000806000604084860312156128d1578283fd5b833560ff811681146128e1578384fd5b9250602084013567ffffffffffffffff8111156128fc578283fd5b61290886828701612565565b9497909650939450505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b6000815180845261295781602086016020860161310c565b601f01601f19169290920160200192915050565b6000825161297d81846020870161310c565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b600060208252612687602083018461293f565b6000604082526129e6604083018688612915565b82810360208401526129f9818587612915565b979650505050505050565b6020808252601f908201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604082015260600190565b6020808252601690820152751d1bdbc81bdb1908189b1bd8dac81a5b9d9bdb1d995960521b604082015260600190565b60208082526019908201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604082015260600190565b6020808252601a908201527f6e6f2076696f6c6174696f6e206f6620766f74652072756c6573000000000000604082015260600190565b6020808252818101527f7468652066656c6f6e795468726573686f6c64206f7574206f662072616e6765604082015260600190565b60208082526017908201527f766572696679207369676e6174757265206661696c6564000000000000000000604082015260600190565b6020808252600e908201526d696e70757420746f6f206c6f6e6760901b604082015260600190565b60208082526019908201527f7372634e756d20626967676572207468616e207461724e756d00000000000000604082015260600190565b6020808252601390820152721d985b1a59185d1bdc881b9bdd08195e1a5cdd606a1b604082015260600190565b6020808252602c908201527f7468652066696e616c69747920736c6173682072657761726420726174696f2060408201526b6f7574206f662072616e676560a01b606082015260800190565b60208082526027908201527f6c656e677468206f66206d697364656d65616e6f725468726573686f6c64206d6040820152660d2e6dac2e8c6d60cb1b606082015260800190565b60208082526013908201527274776f206964656e746963616c20766f74657360681b604082015260600190565b60208082526030908201527f746865206d6573736167652073656e646572206d7573742062652076616c696460408201526f185d1bdc94d95d0818dbdb9d1c9858dd60821b606082015260800190565b6020808252601190820152706164646974696f6e206f766572666c6f7760781b604082015260600190565b6020808252601490820152736761737072696365206973206e6f74207a65726f60601b604082015260600190565b6020808252602e908201527f746865206d6573736167652073656e646572206d75737420626520676f76657260408201526d1b985b98d94818dbdb9d1c9858dd60921b606082015260800190565b60208082526022908201527f6c656e677468206f662066656c6f6e795468726573686f6c64206d69736d61746040820152610c6d60f31b606082015260800190565b60208082526019908201527f74686520636f6e747261637420616c726561647920696e697400000000000000604082015260600190565b6020808252601a908201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604082015260600190565b60208082526025908201527f746865206d697364656d65616e6f725468726573686f6c64206f7574206f662060408201526472616e676560d81b606082015260800190565b6020808252602f908201527f746865206d6573736167652073656e646572206d7573742062652063726f737360408201526e0818da185a5b8818dbdb9d1c9858dd608a1b606082015260800190565b6020808252602d908201527f746865206d6573736167652073656e646572206d75737420626520746865206260408201526c3637b1b590383937b23ab1b2b960991b606082015260800190565b6020808252600d908201526c756e6b6e6f776e20706172616d60981b604082015260600190565b6020808252601e908201527f7265636569766520756e65787065637465642073796e207061636b6167650000604082015260600190565b6020808252602b908201527f6c656e677468206f662066696e616c697479536c61736852657761726452617460408201526a0d2de40dad2e6dac2e8c6d60ab1b606082015260800190565b6020808252818101527f63616e206e6f7420736c61736820747769636520696e206f6e6520626c6f636b604082015260600190565b61ffff91909116815260200190565b90815260200190565b600083825260406020830152613028604083018461293f565b949350505050565b918252602082015260400190565b92835260208301919091521515604082015260600190565b63ffffffff91909116815260200190565b60ff91909116815260200190565b600060ff8516825260606020830152613091606083018561293f565b9050826040830152949350505050565b60405181810167ffffffffffffffff811182821017156130c057600080fd5b604052919050565b600067ffffffffffffffff8211156130de578081fd5b5060209081020190565b600067ffffffffffffffff8211156130fe578081fd5b50601f01601f191660200190565b60005b8381101561312757818101518382015260200161310f565b83811115613136576000848401525b50505050565b6001600160a01b038116811461315157600080fd5b5056fea26469706673582212201998b6d3cfafcfa417a78cc743a5d15a50d1d5c8615cc00839d6f07e9545a35b64736f6c63430006040033", + }, + { + ContractAddr: common.HexToAddress(SystemRewardContract), + CommitUrl: "https://github.com/node-real/bsc-genesis-contract/commit/f8bab13f56955e979bfb754425dab1e62e52f151", + Code: "6080604052600436106101a05760003560e01c80637942fd05116100ec578063ac4317511161008a578063f9a2bbc711610064578063f9a2bbc714610550578063fb5478b314610565578063fc3e59081461057a578063fd6a68791461058f576101e4565b8063ac43175114610457578063c81b166214610526578063dc927faf1461053b576101e4565b80639dc09262116100c65780639dc0926214610403578063a1a11bf514610418578063a78abc161461042d578063ab51bb9614610442576101e4565b80637942fd05146103a057806396713da9146103b55780639a99b4f0146103ca576101e4565b80634bf6c882116101595780636e47b482116101335780636e47b4821461034c57806370fd5bad14610361578063718a8aa81461037657806375d47a0a1461038b576101e4565b80634bf6c882146102db57806351e80672146102f05780636d70f7ae14610305576101e4565b80630bee7a67146101e95780630e2374a5146102175780633a0b0eff146102485780633dffc3871461026f57806343756e5c1461029a578063493279b1146102af576101e4565b366101e45734156101e25760408051348152905133917f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db919081900360200190a25b005b600080fd5b3480156101f557600080fd5b506101fe6105a4565b6040805163ffffffff9092168252519081900360200190f35b34801561022357600080fd5b5061022c6105a9565b604080516001600160a01b039092168252519081900360200190f35b34801561025457600080fd5b5061025d6105af565b60408051918252519081900360200190f35b34801561027b57600080fd5b506102846105b5565b6040805160ff9092168252519081900360200190f35b3480156102a657600080fd5b5061022c6105ba565b3480156102bb57600080fd5b506102c46105c0565b6040805161ffff9092168252519081900360200190f35b3480156102e757600080fd5b506102846105c5565b3480156102fc57600080fd5b5061022c6105ca565b34801561031157600080fd5b506103386004803603602081101561032857600080fd5b50356001600160a01b03166105d0565b604080519115158252519081900360200190f35b34801561035857600080fd5b5061022c6105ee565b34801561036d57600080fd5b506102846105f4565b34801561038257600080fd5b506102846105f9565b34801561039757600080fd5b5061022c6105fe565b3480156103ac57600080fd5b50610284610604565b3480156103c157600080fd5b50610284610609565b3480156103d657600080fd5b5061025d600480360360408110156103ed57600080fd5b506001600160a01b03813516906020013561060e565b34801561040f57600080fd5b5061022c6107b9565b34801561042457600080fd5b5061022c6107bf565b34801561043957600080fd5b506103386107c5565b34801561044e57600080fd5b506101fe6107ce565b34801561046357600080fd5b506101e26004803603604081101561047a57600080fd5b81019060208101813564010000000081111561049557600080fd5b8201836020820111156104a757600080fd5b803590602001918460018302840111640100000000831117156104c957600080fd5b9193909290916020810190356401000000008111156104e757600080fd5b8201836020820111156104f957600080fd5b8035906020019184600183028401116401000000008311171561051b57600080fd5b5090925090506107d3565b34801561053257600080fd5b5061022c610b56565b34801561054757600080fd5b5061022c610b5c565b34801561055c57600080fd5b5061022c610b62565b34801561057157600080fd5b5061025d610b68565b34801561058657600080fd5b50610284610b74565b34801561059b57600080fd5b5061022c610b79565b606481565b61200181565b60015481565b600181565b61100181565b606181565b600881565b61200081565b6001600160a01b031660009081526002602052604090205460ff1690565b61100581565b600281565b601081565b61100881565b600b81565b600981565b6000805460ff1661068b57600260208190527fe57bda0a954a7c7381b17b2c763e646ba2c60f67292d287ba583603e2c1c41668054600160ff19918216811790925561100560009081527fe25235fc0de9d7165652bef0846fefda506174abb9a190f03d0f7bcc6146dbce80548316841790559282558254161790555b3360009081526002602052604090205460ff166106d95760405162461bcd60e51b815260040180806020018281038252602b815260200180610c67602b913960400191505060405180910390fd5b60004783106106e857476106ea565b825b9050670de0b6b3a76400008111156107075750670de0b6b3a76400005b8015610788576040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015610743573d6000803e3d6000fd5b506040805182815290516001600160a01b038616917ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0919081900360200190a26107b2565b6040517fe589651933c2457488cc0d8e0941518abf748e799435e4e396d9c4d0b2db2d4d90600090a15b9392505050565b61100781565b61100681565b60005460ff1681565b600081565b33611007146108135760405162461bcd60e51b815260040180806020018281038252602e815260200180610cc1602e913960400191505060405180910390fd5b61087584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600b81526a30b23227b832b930ba37b960a91b60208201529150610b7f9050565b1561094d57606082828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050825192935050601490911490506108f85760405162461bcd60e51b815260040180806020018281038252602c815260200180610cef602c913960400191505060405180910390fd5b60148101516001600160a01b038116600081815260026020526040808220805460ff19166001179055517f9870d7fe5d112134c55844951dedf365363006d9c588db07c4c85af6322a06199190a25050610ac4565b6109b284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600e81526d3232b632ba32a7b832b930ba37b960911b60208201529150610b7f9050565b15610a8757606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060149091149050610a355760405162461bcd60e51b815260040180806020018281038252602f815260200180610c92602f913960400191505060405180910390fd5b60148101516001600160a01b038116600081815260026020526040808220805460ff19169055517fb40992a19dba61ea600e87fce607102bf5908dc89076217b6ca6ae195224f7029190a25050610ac4565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b61100081565b670de0b6b3a764000081565b600381565b61100481565b6000816040516020018082805190602001908083835b60208310610bb45780518252601f199092019160209182019101610b95565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310610c225780518252601f199092019160209182019101610c03565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490509291505056fe6f6e6c79206f70657261746f7220697320616c6c6f77656420746f2063616c6c20746865206d6574686f646c656e677468206f662076616c756520666f722064656c6574654f70657261746f722073686f756c64206265203230746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f72206164644f70657261746f722073686f756c64206265203230a26469706673582212205c998ac20925f17d8af20803f32be2cf1698c9a844de45001ca5ed8c879cc93f64736f6c63430006040033", + }, + }, + } + + bonehUpgrade[rialtoNet] = &Upgrade{ + UpgradeName: "boneh", + Configs: []*UpgradeConfig{ + { + ContractAddr: common.HexToAddress(ValidatorContract), + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/030cf951e9f5ae1f8211333af807e5d30f3b5a85", + Code: "60806040526004361061046c5760003560e01c8063862498821161024a578063c6d3394511610139578063e40716a1116100b6578063f9a2bbc71161007a578063f9a2bbc714610b6b578063fc3e590814610b80578063fccc281314610b95578063fd4ad81f14610baa578063fd6a687914610bd957610473565b8063e40716a114610af9578063eb57e20214610b0e578063eda5868c14610b2e578063f340fa0114610b43578063f92eb86b14610b5657610473565b8063d86222d5116100fd578063d86222d514610a90578063daacdb6614610aa5578063dc927faf14610aba578063e086c7b114610acf578063e1c7392a14610ae457610473565b8063c6d3394514610a3c578063c81b166214610a51578063c8509d811461085f578063d04aa99614610a66578063d68fb56a14610a7b57610473565b8063a5422d5c116101c7578063ad3c9da61161018b578063ad3c9da6146109d0578063aef198a9146109f0578063b7ab4db514610a05578063b8cf4ef114610a27578063bf9f49951461062f57610473565b8063a5422d5c1461095c578063a78abc1614610971578063aaf5eb6814610986578063ab51bb961461099b578063ac431751146109b057610473565b806396713da91161020e57806396713da9146108f35780639dc09262146109085780639fe0f8161461091d578063a0dc275814610932578063a1a11bf51461094757610473565b8063862498821461087f57806388b32f11146108945780638b5ad0c9146108a95780638d19a410146108be5780639369d7de146108de57610473565b80634df6e0c3116103665780636e47b482116102e35780637942fd05116102a75780637942fd05146108205780637a84ca2a1461083557806381650b621461084a578063831d65d11461085f578063853230aa1461080b57610473565b80636e47b482146107b757806370fd5bad146107cc578063718a8aa8146107e157806375d47a0a146107f657806378dfed4a1461080b57610473565b8063565c56b31161032a578063565c56b3146107265780635667515a146107465780635d77156c1461075b57806362b72cf5146107705780636969a25c1461078557610473565b80634df6e0c3146106b25780635192c82c146106c757806351e80672146106dc578063549b03f2146106f157806355614fcc1461070657610473565b8063321d398a116103f45780633dffc387116103b85780633dffc3871461062f57806343756e5c1461065157806345cf9daf14610666578063493279b11461067b5780634bf6c8821461069d57610473565b8063321d398a146105975780633365af3a146105b757806335409f7f146105d75780633b071dcc146105f75780633de0f0d81461061a57610473565b80631182b8751161043b5780631182b875146104fe578063152ad3b81461052b5780631ff180691461054d578063219f22d514610562578063300c35671461057757610473565b806304c4fec61461047857806307a568471461048f5780630bee7a67146104ba5780630e2374a5146104dc57610473565b3661047357005b600080fd5b34801561048457600080fd5b5061048d610bee565b005b34801561049b57600080fd5b506104a4610c60565b6040516104b19190616ef1565b60405180910390f35b3480156104c657600080fd5b506104cf610c66565b6040516104b19190616f1b565b3480156104e857600080fd5b506104f1610c6b565b6040516104b191906162f8565b34801561050a57600080fd5b5061051e6105193660046161de565b610c71565b6040516104b1919061646f565b34801561053757600080fd5b50610540610ea9565b6040516104b19190616464565b34801561055957600080fd5b506104a4610eb2565b34801561056e57600080fd5b506104cf610eb8565b34801561058357600080fd5b5061048d6105923660046160a7565b610ebd565b3480156105a357600080fd5b506105406105b236600461618b565b611241565b3480156105c357600080fd5b506105406105d236600461618b565b611310565b3480156105e357600080fd5b5061048d6105f2366004616080565b6113c1565b34801561060357600080fd5b5061060c61151a565b6040516104b192919061637a565b34801561062657600080fd5b506104a46117f6565b34801561063b57600080fd5b506106446117fc565b6040516104b19190616f2c565b34801561065d57600080fd5b506104f1611801565b34801561067257600080fd5b506104a4611807565b34801561068757600080fd5b5061069061180d565b6040516104b19190616ee2565b3480156106a957600080fd5b50610644611813565b3480156106be57600080fd5b5061060c611818565b3480156106d357600080fd5b506104a4611996565b3480156106e857600080fd5b506104f161199c565b3480156106fd57600080fd5b506104a46119a2565b34801561071257600080fd5b50610540610721366004616080565b6119a8565b34801561073257600080fd5b506104a4610741366004616080565b6119dd565b34801561075257600080fd5b50610644611a2e565b34801561076757600080fd5b506104cf611a33565b34801561077c57600080fd5b506104a4611a38565b34801561079157600080fd5b506107a56107a036600461618b565b611a3e565b6040516104b196959493929190616325565b3480156107c357600080fd5b506104f1611aa2565b3480156107d857600080fd5b50610644611aa8565b3480156107ed57600080fd5b50610644611aad565b34801561080257600080fd5b506104f1611ab2565b34801561081757600080fd5b506104a4611ab8565b34801561082c57600080fd5b50610644611abe565b34801561084157600080fd5b506104a4611ac3565b34801561085657600080fd5b506104cf611ac9565b34801561086b57600080fd5b5061048d61087a3660046161de565b611ace565b34801561088b57600080fd5b506104a4611b2f565b3480156108a057600080fd5b506104a4611b35565b3480156108b557600080fd5b506104a4611b3b565b3480156108ca57600080fd5b506104a46108d9366004616080565b611b41565b3480156108ea57600080fd5b5061048d611b81565b3480156108ff57600080fd5b50610644611c95565b34801561091457600080fd5b506104f1611c9a565b34801561092957600080fd5b506104a4611ca0565b34801561093e57600080fd5b506104a4611ca5565b34801561095357600080fd5b506104f1611caa565b34801561096857600080fd5b5061051e611cb0565b34801561097d57600080fd5b50610540611ccf565b34801561099257600080fd5b506104a4611cd8565b3480156109a757600080fd5b506104cf611a2e565b3480156109bc57600080fd5b5061048d6109cb36600461612f565b611ce1565b3480156109dc57600080fd5b506104a46109eb366004616080565b61258d565b3480156109fc57600080fd5b506104a461259f565b348015610a1157600080fd5b50610a1a6125ac565b6040516104b19190616367565b348015610a3357600080fd5b506104a4612698565b348015610a4857600080fd5b506104a4611aa8565b348015610a5d57600080fd5b506104f161269d565b348015610a7257600080fd5b506104a46126a3565b348015610a8757600080fd5b506104a46126a8565b348015610a9c57600080fd5b506104a46126e7565b348015610ab157600080fd5b506104a46126f3565b348015610ac657600080fd5b506104f16126f9565b348015610adb57600080fd5b506104a46126ff565b348015610af057600080fd5b5061048d612704565b348015610b0557600080fd5b506104a46128b3565b348015610b1a57600080fd5b5061048d610b29366004616080565b6128b9565b348015610b3a57600080fd5b506104cf6129c1565b61048d610b51366004616080565b6129c6565b348015610b6257600080fd5b506104a4612c4e565b348015610b7757600080fd5b506104f1612c54565b348015610b8c57600080fd5b50610644611ca0565b348015610ba157600080fd5b506104f1612c5a565b348015610bb657600080fd5b50610bca610bc536600461618b565b612c60565b6040516104b193929190616efa565b348015610be557600080fd5b506104f1612d22565b6000610bf933611b41565b9050600b8181548110610c0857fe5b600091825260209091206001601690920201015460ff16610c445760405162461bcd60e51b8152600401610c3b90616b9a565b60405180910390fd5b6000610c4e6126a8565b9050610c5b338383612d28565b505050565b60095481565b606481565b61200181565b60005460609060ff16610c965760405162461bcd60e51b8152600401610c3b9061662e565b3361200014610cb75760405162461bcd60e51b8152600401610c3b90616d79565b600b54610d7557610cc6615d6c565b60015460005b81811015610d7157600b8054600181018255600091909152835160008051602061714f833981519152601690920291820190815560208086015160008051602061718f8339815191528401805460ff1916911515919091179055604086015180518794610d4d9360008051602061716f833981519152909101920190615d9b565b506060820151610d639060038301906013615e15565b505050806001019050610ccc565b5050505b610d7d615e42565b6000610dbe85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612f1492505050565b9150915080610dda57610dd160646130d0565b92505050610ea2565b815160009060ff16610dff57610df883602001518460400151613131565b9050610e6e565b825160ff1660011415610e6a57826020015151600114610e445760008051602061712f833981519152604051610e3490616a81565b60405180910390a1506067610e65565b610df88360200151600081518110610e5857fe5b6020026020010151613d85565b610e6e565b5060655b63ffffffff8116610e935750506040805160008152602081019091529150610ea29050565b610e9c816130d0565b93505050505b9392505050565b60075460ff1681565b60035481565b606881565b334114610edc5760405162461bcd60e51b8152600401610c3b90616dc8565b6010544311610efd5760405162461bcd60e51b8152600401610c3b9061678a565b60005460ff16610f1f5760405162461bcd60e51b8152600401610c3b9061662e565b600f54610f37576032600f5561100231601155611237565b60006110023168056bc75e2d63100000811115610f6657610f5f81606463ffffffff613efc16565b9150610faf565b601154811115610fa857610f5f6064610f9c600f54610f9060115486613f3e90919063ffffffff16565b9063ffffffff613f8016565b9063ffffffff613efc16565b5050611237565b6040516309a99b4f60e41b815261100290639a99b4f090610fd6903090869060040161630c565b602060405180830381600087803b158015610ff057600080fd5b505af1158015611004573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061102891906161a3565b6110023160115591508161103d575050611237565b6000805b8481101561106b5785858281811061105557fe5b9050602002013582019150806001019050611041565b508061107957505050611237565b6000806000805b8981101561122f578489898381811061109557fe5b905060200201358802816110a557fe5b0493508a8a828181106110b457fe5b90506020020160208101906110c99190616080565b6001600160a01b038116600090815260046020526040902054909350915081156111e55760006001808403815481106110fe57fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff161561116b57836001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d858660405161115e9190616ef1565b60405180910390a26111df565b60035461117e908663ffffffff613fba16565b6003908155810154611196908663ffffffff613fba16565b60038201556040516001600160a01b038516907fcb0aad6cf9cd03bdf6137e359f541c42f38b39f007cae8e89e88aa7d8c6617b2906111d6908890616ef1565b60405180910390a25b50611227565b826001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d858560405161121e9190616ef1565b60405180910390a25b600101611080565b505050505050505b5050436010555050565b60015460009082106112555750600061130b565b60006001600160a01b03166001838154811061126d57fe5b60009182526020909120600490910201546001600160a01b0316148061129d5750600854158061129d5750600a54155b806112ac575060085460095410155b806112bd57506112bb82611310565b155b806112e657506000600b83815481106112d257fe5b906000526020600020906016020160000154115b806112fa575060016112f66125ac565b5111155b156113075750600061130b565b5060015b919050565b60015460009082106113245750600061130b565b600b548210611361576001828154811061133a57fe5b9060005260206000209060040201600201601c9054906101000a900460ff1615905061130b565b6001828154811061136e57fe5b9060005260206000209060040201600201601c9054906101000a900460ff161580156113bb5750600b82815481106113a257fe5b600091825260209091206001601690920201015460ff16155b92915050565b33611001146113e25760405162461bcd60e51b8152600401610c3b90616e99565b600b546114a0576113f1615d6c565b60015460005b8181101561149c57600b8054600181018255600091909152835160008051602061714f833981519152601690920291820190815560208086015160008051602061718f8339815191528401805460ff19169115159190911790556040860151805187946114789360008051602061716f833981519152909101920190615d9b565b50606082015161148e9060038301906013615e15565b5050508060010190506113f7565b5050505b6001600160a01b038116600090815260046020526040902054806114c45750611517565b6001810390506000600b82815481106114d957fe5b600091825260209091206001601690920201015460ff1690506114fc8383613fdf565b80156115055750805b15610c5b576009805460001901905550505b50565b60015460609081906000805b8281101561156d576001818154811061153b57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611565576001909101905b600101611526565b5060608160405190808252806020026020018201604052801561159a578160200160208202803683370190505b5090506060826040519080825280602002602001820160405280156115d357816020015b60608152602001906001900390816115be5790505b50600b546000945090915084141561174e5760005b8481101561174857600181815481106115fd57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611740576001818154811061162d57fe5b600091825260209091206004909102015483516001600160a01b039091169084908690811061165857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600b818154811061168557fe5b600091825260209182902060026016909202018101805460408051601f60001961010060018616150201909316949094049182018590048502840185019052808352919290919083018282801561171d5780601f106116f25761010080835404028352916020019161171d565b820191906000526020600020905b81548152906001019060200180831161170057829003601f168201915b505050505082858151811061172e57fe5b60209081029190910101526001909301925b6001016115e8565b506117ea565b60005b848110156117e8576001818154811061176657fe5b9060005260206000209060040201600201601c9054906101000a900460ff166117e0576001818154811061179657fe5b600091825260209091206004909102015483516001600160a01b03909116908490869081106117c157fe5b6001600160a01b03909216602092830291909101909101526001909301925b600101611751565b505b909450925050505b9091565b61271081565b600181565b61100181565b60085481565b6102ca81565b600881565b600e54600c5460609182918061182c575060155b60606118366125ac565b9050606061184382614392565b90508282511161185a5790945092506117f2915050565b8383835103101561186c578282510393505b83156118a25760c8430461188883838388880360008a8a614500565b6118a08383838888038989038a8b8b8b510301614500565b505b6060836040519080825280602002602001820160405280156118ce578160200160208202803683370190505b50905060608460405190808252806020026020018201604052801561190757816020015b60608152602001906001900390816118f25790505b50905060005b858110156119885784818151811061192157fe5b602002602001015183828151811061193557fe5b60200260200101906001600160a01b031690816001600160a01b03168152505083818151811061196157fe5b602002602001015182828151811061197557fe5b602090810291909101015260010161190d565b509096509450505050509091565b60065481565b61200081565b600f5481565b6001600160a01b038116600090815260046020526040812054806119d057600091505061130b565b60001901610ea281611310565b6001600160a01b03811660009081526004602052604081205480611a0557600091505061130b565b600180820381548110611a1457fe5b906000526020600020906004020160030154915050919050565b600081565b606781565b60105481565b60018181548110611a4b57fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b0392831694509082169291821691600160a01b81046001600160401b031691600160e01b90910460ff169086565b61100581565b600281565b601081565b61100881565b6103e881565b600b81565b600c5481565b606681565b3361200014611aef5760405162461bcd60e51b8152600401610c3b90616d79565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051611b2293929190616f3a565b60405180910390a1505050565b60025481565b60115481565b600a5481565b6001600160a01b03811660009081526004602052604081205480611b775760405162461bcd60e51b8152600401610c3b90616d01565b6000190192915050565b600b54611c3f57611b90615d6c565b60015460005b81811015611c3b57600b8054600181018255600091909152835160008051602061714f833981519152601690920291820190815560208086015160008051602061718f8339815191528401805460ff1916911515919091179055604086015180518794611c179360008051602061716f833981519152909101920190615d9b565b506060820151611c2d9060038301906013615e15565b505050806001019050611b96565b5050505b600854611c4c5760036008555b600a54611c59576002600a555b6000611c6433611b41565b9050611c6f81611241565b611c8b5760405162461bcd60e51b8152600401610c3b90616a3e565b6115173382614657565b600981565b61100781565b600381565b60c881565b61100681565b604051806101e001604052806101ab8152602001616f846101ab913981565b60005460ff1681565b6402540be40081565b60005460ff16611d035760405162461bcd60e51b8152600401610c3b9061662e565b3361100714611d245760405162461bcd60e51b8152600401610c3b90616b07565b611d8e84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526013815272065787069726554696d655365636f6e6447617606c1b602082015291506146ef9050565b15611e2b5760208114611db35760405162461bcd60e51b8152600401610c3b90616cbb565b604080516020601f8401819004810282018101909252828152600091611df19185858083850183828082843760009201919091525061474892505050565b905060648110158015611e075750620186a08111155b611e235760405162461bcd60e51b8152600401610c3b906168e7565b60025561254a565b611e8b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260098152686275726e526174696f60b81b602082015291506146ef9050565b15611f275760208114611eb05760405162461bcd60e51b8152600401610c3b906164b4565b604080516020601f8401819004810282018101909252828152600091611eee9185858083850183828082843760009201919091525061474892505050565b9050612710811115611f125760405162461bcd60e51b8152600401610c3b906167cc565b6006556007805460ff1916600117905561254a565b611f9184848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260138152726d61784e756d4f664d61696e7461696e696e6760681b602082015291506146ef9050565b1561202b5760208114611fb65760405162461bcd60e51b8152600401610c3b906164eb565b604080516020601f8401819004810282018101909252828152600091611ff49185858083850183828082843760009201919091525061474892505050565b600c5490915080612003575060155b8082106120225760405162461bcd60e51b8152600401610c3b9061683f565b5060085561254a565b61209484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61696e7461696e536c6173685363616c6560701b602082015291506146ef9050565b1561212d57602081146120b95760405162461bcd60e51b8152600401610c3b906165b4565b604080516020601f84018190048102820181019092528281526000916120f79185858083850183828082843760009201919091525061474892505050565b90506000811180156121095750600a81105b6121255760405162461bcd60e51b8152600401610c3b90616e15565b600a5561254a565b6121a184848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601981527f6d61784e756d4f66576f726b696e6743616e6469646174657300000000000000602082015291506146ef9050565b1561223057602081146121c65760405162461bcd60e51b8152600401610c3b90616568565b604080516020601f84018190048102820181019092528281526000916122049185858083850183828082843760009201919091525061474892505050565b9050600d548111156122285760405162461bcd60e51b8152600401610c3b9061695d565b600e5561254a565b61229984848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61784e756d4f6643616e6469646174657360701b602082015291506146ef9050565b1561231b57602081146122be5760405162461bcd60e51b8152600401610c3b90616b55565b604080516020601f84018190048102820181019092528281526000916122fc9185858083850183828082843760009201919091525061474892505050565b600d819055600e5490915081101561231557600d54600e555b5061254a565b61237f84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c6e756d4f66436162696e65747360981b602082015291506146ef9050565b1561242d57602081146123a45760405162461bcd60e51b8152600401610c3b906165f9565b604080516020601f84018190048102820181019092528281526000916123e29185858083850183828082843760009201919091525061474892505050565b9050600081116124045760405162461bcd60e51b8152600401610c3b9061669c565b60298111156124255760405162461bcd60e51b8152600401610c3b906166e4565b600c5561254a565b61249784848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601381527266696e616c697479526577617264526174696f60681b602082015291506146ef9050565b1561253257602081146124bc5760405162461bcd60e51b8152600401610c3b90616c3e565b604080516020601f84018190048102820181019092528281526000916124fa9185858083850183828082843760009201919091525061474892505050565b90506001811015801561250e575060648111155b61252a5760405162461bcd60e51b8152600401610c3b906169cc565b600f5561254a565b60405162461bcd60e51b8152600401610c3b90616e72565b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a8484848460405161257f9493929190616482565b60405180910390a150505050565b60046020526000908152604090205481565b68056bc75e2d6310000081565b6001546060906000805b828110156125db576125c781611310565b156125d3578160010191505b6001016125b6565b50606081604051908082528060200260200182016040528015612608578160200160208202803683370190505b5090506000915060005b8381101561268f5761262381611310565b15612687576001818154811061263557fe5b600091825260209091206004909102015482516001600160a01b039091169083908590811061266057fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508260010192505b600101612612565b50925050505b90565b601581565b61100281565b603281565b60006126b26125ac565b519050600080600c54116126c75760156126cb565b600c545b9050808211156126d9578091505b816126e357600191505b5090565b67016345785d8a000081565b60055481565b61100381565b602981565b60005460ff16156127275760405162461bcd60e51b8152600401610c3b90616c07565b61272f615e42565b6000612755604051806101e001604052806101ab8152602001616f846101ab9139612f14565b91509150806127765760405162461bcd60e51b8152600401610c3b90616d38565b60005b82602001515181101561289b5760018360200151828151811061279857fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782558587015182850180549185169183169190911790556040860151600283018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590981692909516919091179290921694909417161790915560a09093015160039093019290925591860151805191850193918590811061286e57fe5b602090810291909101810151516001600160a01b0316825281019190915260400160002055600101612779565b50506103e8600255506000805460ff19166001179055565b600d5481565b33611001146128da5760405162461bcd60e51b8152600401610c3b90616e99565b600b54612998576128e9615d6c565b60015460005b8181101561299457600b8054600181018255600091909152835160008051602061714f833981519152601690920291820190815560208086015160008051602061718f8339815191528401805460ff19169115159190911790556040860151805187946129709360008051602061716f833981519152909101920190615d9b565b5060608201516129869060038301906013615e15565b5050508060010190506128ef565b5050505b60006129a38261474d565b90506129ae81611241565b156129bd576129bd8282614657565b5050565b606581565b3341146129e55760405162461bcd60e51b8152600401610c3b90616dc8565b60005460ff16612a075760405162461bcd60e51b8152600401610c3b9061662e565b60003411612a275760405162461bcd60e51b8152600401610c3b9061692e565b6001600160a01b0381166000908152600460205260409020546007543491906103e89060ff1615612a5757506006545b600083118015612a675750600081115b15612b08576000612a84612710610f9c868563ffffffff613f8016565b90508015612b065760405161dead9082156108fc029083906000818181858888f19350505050158015612abb573d6000803e3d6000fd5b507f627059660ea01c4733a328effb2294d2f86905bf806da763a89cee254de8bee581604051612aeb9190616ef1565b60405180910390a1612b03848263ffffffff613f3e16565b93505b505b8115612c06576000600180840381548110612b1f57fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff1615612b8c57846001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b485604051612b7f9190616ef1565b60405180910390a2612c00565b600354612b9f908563ffffffff613fba16565b6003908155810154612bb7908563ffffffff613fba16565b60038201556040516001600160a01b038616907f93a090ecc682c002995fad3c85b30c5651d7fd29b0be5da9d784a3302aedc05590612bf7908790616ef1565b60405180910390a25b50612c48565b836001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b484604051612c3f9190616ef1565b60405180910390a25b50505050565b600e5481565b61100081565b61dead81565b600b8181548110612c6d57fe5b6000918252602091829020601691909102018054600180830154600280850180546040805161010096831615969096026000190190911692909204601f810188900488028501880190925281845293965060ff90911694919291830182828015612d185780601f10612ced57610100808354040283529160200191612d18565b820191906000526020600020905b815481529060010190602001808311612cfb57829003601f168201915b5050505050905083565b61100481565b6000600a5460001480612d39575081155b80612d445750600954155b15612d5157506000610ea2565b60096000815460019003919050819055506000612d9c600a54610f9c85610f9c600b8981548110612d7e57fe5b6000918252602090912060169091020154439063ffffffff613f3e16565b90506000600b8581548110612dad57fe5b906000526020600020906016020160010160006101000a81548160ff0219169083151502179055506000806110016001600160a01b0316638256ace66040518163ffffffff1660e01b8152600401604080518083038186803b158015612e1257600080fd5b505afa158015612e26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e4a91906161bb565b9150915060009350808310612ec457612e638787613fdf565b506040516305bfb49960e41b815261100190635bfb499090612e89908a906004016162f8565b600060405180830381600087803b158015612ea357600080fd5b505af1158015612eb7573d6000803e3d6000fd5b5050505060019350612ed6565b818310612ed657612ed48761474d565b505b6040516001600160a01b038816907fb9d38178dc641ff1817967a63c9078cbcd955a9f1fcd75e0e3636de615d44d3b90600090a25050509392505050565b612f1c615e42565b6000612f26615e42565b612f2e615e66565b612f3f612f3a866148f0565b614915565b90506000805b612f4e8361495f565b156130c25780612f7357612f69612f6484614980565b6149ce565b60ff1684526130ba565b80600114156130b5576060612f8f612f8a85614980565b614a4e565b90508051604051908082528060200260200182016040528015612fcc57816020015b612fb9615e86565b815260200190600190039081612fb15790505b508560200181905250805160405190808252806020026020018201604052801561300a57816020015b6060815260200190600190039081612ff55790505b50604086015260005b81518110156130aa57613024615e86565b6060600061304485858151811061303757fe5b6020026020010151614b1f565b92509250925080613064578860009a509a505050505050505050506130cb565b828960200151858151811061307557fe5b6020026020010181905250818960400151858151811061309157fe5b6020026020010181905250505050806001019050613013565b5060019250506130ba565b6130c2565b600101612f45565b50919350909150505b915091565b604080516001808252818301909252606091829190816020015b60608152602001906001900390816130ea5790505090506131108363ffffffff16614c39565b8160008151811061311d57fe5b6020026020010181905250610ea281614c4c565b60006029835111156131685760008051602061712f83398151915260405161315890616741565b60405180910390a15060666113bb565b60005b83518110156132065760005b818110156131fd5784818151811061318b57fe5b6020026020010151600001516001600160a01b03168583815181106131ac57fe5b6020026020010151600001516001600160a01b031614156131f55760008051602061712f8339815191526040516131e29061689c565b60405180910390a16066925050506113bb565b600101613177565b5060010161316b565b506060806132148585614cd6565b60015491935091506000908190815b818110156132995767016345785d8a00006001828154811061324157fe5b9060005260206000209060040201600301541061326357836001019350613291565b60006001828154811061327257fe5b9060005260206000209060040201600301541115613291578260010192505b600101613223565b506060836040519080825280602002602001820160405280156132c6578160200160208202803683370190505b5090506060846040519080825280602002602001820160405280156132f5578160200160208202803683370190505b509050606085604051908082528060200260200182016040528015613324578160200160208202803683370190505b509050606086604051908082528060200260200182016040528015613353578160200160208202803683370190505b5090506000606087604051908082528060200260200182016040528015613384578160200160208202803683370190505b5090506060886040519080825280602002602001820160405280156133b3578160200160208202803683370190505b509050600099506000985060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b1580156133fb57600080fd5b505afa15801561340f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061343391906161a3565b905067016345785d8a000081111561347e5760008051602061712f83398151915260405161346090616bc6565b60405180910390a160689d50505050505050505050505050506113bb565b60005b898110156136ef5767016345785d8a00006001828154811061349f57fe5b9060005260206000209060040201600301541061362457600181815481106134c357fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316898d815181106134f457fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060006402540be4006001838154811061352957fe5b9060005260206000209060040201600301548161354257fe5b066001838154811061355057fe5b9060005260206000209060040201600301540390506135788382613f3e90919063ffffffff16565b898e8151811061358457fe5b6020026020010181815250506001828154811061359d57fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316878e815181106135ce57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505081888e815181106135fb57fe5b6020908102919091010152613616868263ffffffff613fba16565b95508c6001019c50506136e7565b60006001828154811061363357fe5b90600052602060002090600402016003015411156136e7576001818154811061365857fe5b906000526020600020906004020160010160009054906101000a90046001600160a01b0316848c8151811061368957fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600181815481106136b657fe5b906000526020600020906004020160030154838c815181106136d457fe5b6020026020010181815250508a6001019a505b600101613481565b5060008415613965576002546040516303702b2960e51b815261100491636e056520918891613729918e918e918d914201906004016163ea565b6020604051808303818588803b15801561374257600080fd5b505af193505050508015613773575060408051601f3d908101601f191682019092526137709181019061610f565b60015b6138ea576040516000815260443d101561378f5750600061382a565b60046000803e60005160e01c6308c379a081146137b057600091505061382a565b60043d036004833e81513d60248201116001600160401b03821117156137db5760009250505061382a565b80830180516001600160401b038111156137fc57600094505050505061382a565b8060208301013d860181111561381a5760009550505050505061382a565b601f01601f191660405250925050505b806138355750613877565b60019150857fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf28082604051613869919061646f565b60405180910390a2506138e5565b3d8080156138a1576040519150601f19603f3d011682016040523d82523d6000602084013e6138a6565b606091505b5060019150857fbfa884552dd8921b6ce90bfe906952ae5b3b29be0cc1a951d4f62697635a3a45826040516138db919061646f565b60405180910390a2505b613965565b801561392c577fa217d08e65f80c73121cd9db834d81652d544bfbf452f6d04922b16c90a37b708660405161391f9190616ef1565b60405180910390a1613963565b857fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf28060405161395a90616531565b60405180910390a25b505b8015613b1b5760005b8751811015613b1957600088828151811061398557fe5b6020026020010151905060006001828154811061399e57fe5b60009182526020909120600160049092020181015481546001600160a01b03909116916108fc91859081106139cf57fe5b9060005260206000209060040201600301549081150290604051600060405180830381858888f1935050505090508015613a8b5760018281548110613a1057fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d9185908110613a5f57fe5b906000526020600020906004020160030154604051613a7e9190616ef1565b60405180910390a2613b0f565b60018281548110613a9857fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d9185908110613ae757fe5b906000526020600020906004020160030154604051613b069190616ef1565b60405180910390a25b505060010161396e565b505b835115613c655760005b8451811015613c63576000858281518110613b3c57fe5b60200260200101516001600160a01b03166108fc868481518110613b5c57fe5b60200260200101519081150290604051600060405180830381858888f1935050505090508015613bf257858281518110613b9257fe5b60200260200101516001600160a01b03167f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d868481518110613bd057fe5b6020026020010151604051613be59190616ef1565b60405180910390a2613c5a565b858281518110613bfe57fe5b60200260200101516001600160a01b03167f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d868481518110613c3c57fe5b6020026020010151604051613c519190616ef1565b60405180910390a25b50600101613b25565b505b5050505050505050505050506000471115613ce1577f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d47604051613ca99190616ef1565b60405180910390a1604051611002904780156108fc02916000818181858888f19350505050158015613cdf573d6000803e3d6000fd5b505b60006003819055600555815115613cfc57613cfc8282614f0f565b6110016001600160a01b031663fc4333cd6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015613d3957600080fd5b505af1158015613d4d573d6000803e3d6000fd5b50506040517fedd8d7296956dd970ab4de3f2fc03be2b0ffc615d20cd4c72c6e44f928630ebf925060009150a1506000949350505050565b80516001600160a01b0316600090815260046020526040812054801580613dd65750600180820381548110613db657fe5b9060005260206000209060040201600201601c9054906101000a900460ff165b15613e1c5782516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a2600091505061130b565b600154600554600019820111801590613e725784516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a26000935050505061130b565b600580546001908101909155805481906000198601908110613e9057fe5b6000918252602082206002600490920201018054921515600160e01b0260ff60e01b199093169290921790915585516040516001600160a01b03909116917ff226e7d8f547ff903d9d419cf5f54e0d7d07efa9584135a53a057c5f1f27f49a91a2506000949350505050565b6000610ea283836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506156ee565b6000610ea283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250615725565b600082613f8f575060006113bb565b82820282848281613f9c57fe5b0414610ea25760405162461bcd60e51b8152600401610c3b90616ac6565b600082820183811015610ea25760405162461bcd60e51b8152600401610c3b90616665565b60008060018381548110613fef57fe5b906000526020600020906004020160030154905060006001808054905003905060016140196125ac565b511161404e5760006001858154811061402e57fe5b9060005260206000209060040201600301819055506000925050506113bb565b846001600160a01b03167f3b6f9ef90462b512a1293ecec018670bf7b7f1876fb727590a8a6d7643130a70836040516140879190616ef1565b60405180910390a26001600160a01b038516600090815260046020526040812055835b6001546000190181101561427457600181600101815481106140c857fe5b9060005260206000209060040201600182815481106140e357fe5b60009182526020909120825460049092020180546001600160a01b03199081166001600160a01b0393841617825560018085015481840180548416918616919091179055600280860180549185018054909416919095161780835584546001600160401b03600160a01b91829004160267ffffffffffffffff60a01b1990911617808355935460ff600160e01b918290041615150260ff60e01b19909416939093179055600392830154920191909155600b8054909183019081106141a457fe5b9060005260206000209060160201600b82815481106141bf57fe5b600091825260209091208254601690920201908155600180830154818301805460ff909216151560ff1990921691909117905560028084018054614216938386019390821615610100026000190190911604615ebb565b5061422960038281019084016013615f30565b5090505080600101600460006001848154811061424257fe5b600091825260208083206004909202909101546001600160a01b031683528201929092526040019020556001016140aa565b50600180548061428057fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b8054806142d357fe5b60008281526020812060166000199093019283020181815560018101805460ff19169055906143056002830182615f5a565b614313600383016000615f9e565b50509055600081838161432257fe5b04905080156143865760015460005b8181101561438357826001828154811061434757fe5b906000526020600020906004020160030154016001828154811061436757fe5b6000918252602090912060036004909202010155600101614331565b50505b50600195945050505050565b6001548151604080518281526020808402820101909152606092919083908280156143d157816020015b60608152602001906001900390816143bc5790505b50600b5490915083146143e857925061130b915050565b60005b828110156144f757600b60016004600089858151811061440757fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002054038154811061443b57fe5b600091825260209182902060026016909202018101805460408051601f6000196101006001861615020190931694909404918201859004850284018501905280835291929091908301828280156144d35780601f106144a8576101008083540402835291602001916144d3565b820191906000526020600020905b8154815290600101906020018083116144b657829003601f168201915b50505050508282815181106144e457fe5b60209081029190910101526001016143eb565b50949350505050565b60005b8281101561464d57600082878388016040516020016145239291906162ea565b6040516020818303038152906040528051906020012060001c8161454357fe5b06905080850182870114614644576000898388018151811061456157fe5b602002602001015190506060898489018151811061457b57fe5b602002602001015190508a8388018151811061459357fe5b60200260200101518b858a01815181106145a957fe5b60200260200101906001600160a01b031690816001600160a01b031681525050818b848901815181106145d857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050898388018151811061460657fe5b60200260200101518a858a018151811061461c57fe5b6020026020010181905250808a8489018151811061463657fe5b602002602001018190525050505b50600101614503565b5050505050505050565b600980546001908101909155600b80548390811061467157fe5b906000526020600020906016020160010160006101000a81548160ff02191690831515021790555043600b82815481106146a757fe5b600091825260208220601690910201919091556040516001600160a01b038416917ff62981a567ec3cec866c6fa93c55bcdf841d6292d18b8d522ececa769375d82d91a25050565b60008160405160200161470291906162ce565b604051602081830303815290604052805190602001208360405160200161472991906162ce565b6040516020818303038152906040528051906020012014905092915050565b015190565b6001600160a01b038116600090815260046020526040812054806147765750600019905061130b565b60018103905060006001828154811061478b57fe5b90600052602060002090600402016003015490506000600183815481106147ae57fe5b6000918252602090912060036004909202010155600154604051600019909101906001600160a01b038616907f8cd4e147d8af98a9e3b6724021b8bf6aed2e5dac71c38f2dce8161b82585b25d90614807908590616ef1565b60405180910390a28061481f5782935050505061130b565b600081838161482a57fe5b04905080156148e65760005b8481101561488857816001828154811061484c57fe5b906000526020600020906004020160030154016001828154811061486c57fe5b6000918252602090912060036004909202010155600101614836565b50600180549085015b818110156148e35782600182815481106148a757fe5b90600052602060002090600402016003015401600182815481106148c757fe5b6000918252602090912060036004909202010155600101614891565b50505b5091949350505050565b6148f8615fad565b506040805180820190915281518152602082810190820152919050565b61491d615e66565b61492682615751565b61492f57600080fd5b600061493e836020015161578b565b60208085015160408051808201909152868152920190820152915050919050565b6000614969615fad565b505080518051602091820151919092015191011190565b614988615fad565b6149918261495f565b61499a57600080fd5b602082015160006149aa826157ee565b80830160209586015260408051808201909152908152938401919091525090919050565b8051600090158015906149e357508151602110155b6149ec57600080fd5b60006149fb836020015161578b565b90508083600001511015614a215760405162461bcd60e51b8152600401610c3b90616c84565b8251602080850151830180519284900392918310156144f757506020919091036101000a90049392505050565b6060614a5982615751565b614a6257600080fd5b6000614a6d836158cf565b9050606081604051908082528060200260200182016040528015614aab57816020015b614a98615fad565b815260200190600190039081614a905790505b5090506000614abd856020015161578b565b60208601510190506000805b84811015614b1457614ada836157ee565b9150604051806040016040528083815260200184815250848281518110614afd57fe5b602090810291909101015291810191600101614ac9565b509195945050505050565b614b27615e86565b60606000614b33615e86565b6060614b3d615e66565b614b4687614915565b90506000805b614b558361495f565b15614c2a5780614b8057614b70614b6b84614980565b61592b565b6001600160a01b03168552614c22565b8060011415614ba857614b95614b6b84614980565b6001600160a01b03166020860152614c22565b8060021415614bd057614bbd614b6b84614980565b6001600160a01b03166040860152614c22565b8060031415614bfc57614be5612f6484614980565b6001600160401b0316606086015260019150614c22565b8060041415614c1d57614c16614c1184614980565b615945565b9350614c22565b614c2a565b600101614b4c565b50929791965091945092505050565b60606113bb614c47836159b5565b615a9b565b6060815160001415614c6d575060408051600081526020810190915261130b565b606082600081518110614c7c57fe5b602002602001015190506000600190505b8351811015614cbd57614cb382858381518110614ca657fe5b6020026020010151615aed565b9150600101614c8d565b50610ea2614cd0825160c060ff16615b6a565b82615aed565b606080600080808080614ce76126a8565b6001549091505b8015614df557600181039250600b8381548110614d0757fe5b600091825260209091206001601690920201015460ff16614d2757614dec565b60018381548110614d3457fe5b60009182526020909120600490910201546001600160a01b03169450614d5b858484612d28565b9350831580614d6e575060018a51038610155b15614d7857614dec565b60005b8a51811015614dea57856001600160a01b03168b8281518110614d9a57fe5b6020026020010151600001516001600160a01b03161415614de25760018b8281518110614dc357fe5b6020908102919091010151901515608090910152600190960195614dea565b600101614d7b565b505b60001901614cee565b5084895103604051908082528060200260200182016040528015614e3357816020015b614e20615e86565b815260200190600190039081614e185790505b50965084895103604051908082528060200260200182016040528015614e6d57816020015b6060815260200190600190039081614e585790505b5095506000915060005b8951811015614f0157898181518110614e8c57fe5b602002602001015160800151614ef957898181518110614ea857fe5b6020026020010151888481518110614ebc57fe5b6020026020010181905250888181518110614ed357fe5b6020026020010151878481518110614ee757fe5b60200260200101819052508260010192505b600101614e77565b5050505050505b9250929050565b600154825160005b8281101561502c576001614f29615e86565b60018381548110614f3657fe5b600091825260208083206040805160c08101825260049490940290910180546001600160a01b0390811685526001820154811693850193909352600281015492831691840191909152600160a01b82046001600160401b03166060840152600160e01b90910460ff16151560808301526003015460a082015291505b8481101561500057878181518110614fc657fe5b6020026020010151600001516001600160a01b031682600001516001600160a01b03161415614ff85760009250615000565b600101614fb2565b5081156150225780516001600160a01b03166000908152600460205260408120555b5050600101614f17565b50808211156150eb57805b828110156150e957600180548061504a57fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b80548061509d57fe5b60008281526020812060166000199093019283020181815560018101805460ff19169055906150cf6002830182615f5a565b6150dd600383016000615f9e565b50509055600101615037565b505b60008183106150fa57816150fc565b825b905060005b818110156154a0576151ae86828151811061511857fe5b60200260200101516001838154811061512d57fe5b60009182526020918290206040805160c08101825260049390930290910180546001600160a01b0390811684526001820154811694840194909452600281015493841691830191909152600160a01b83046001600160401b03166060830152600160e01b90920460ff161515608082015260039091015460a0820152615c3c565b6153625780600101600460008884815181106151c657fe5b6020026020010151600001516001600160a01b03166001600160a01b031681526020019081526020016000208190555085818151811061520257fe5b60200260200101516001828154811061521757fe5b6000918252602091829020835160049092020180546001600160a01b039283166001600160a01b0319918216178255928401516001820180549184169185169190911790556040840151600282018054606087015160808801511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909716929097169190911792909216939093171692909217905560a09091015160039091015584518590829081106152d257fe5b6020026020010151600b82815481106152e757fe5b9060005260206000209060160201600201908051906020019061530b929190615d9b565b506000600b828154811061531b57fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b80548390811061534c57fe5b6000918252602090912060169091020155615498565b61542885828151811061537157fe5b6020026020010151600b838154811061538657fe5b600091825260209182902060026016909202018101805460408051601f60001961010060018616150201909316949094049182018590048502840185019052808352919290919083018282801561541e5780601f106153f35761010080835404028352916020019161541e565b820191906000526020600020905b81548152906001019060200180831161540157829003601f168201915b5050505050615cbd565b6154735784818151811061543857fe5b6020026020010151600b828154811061544d57fe5b90600052602060002090601602016002019080519060200190615471929190615d9b565b505b60006001828154811061548257fe5b9060005260206000209060040201600301819055505b600101615101565b5082821115615678576154b1615d6c565b835b83811015615675578581815181106154c757fe5b6020026020010151826040018190525060018782815181106154e557fe5b6020908102919091018101518254600181810185556000948552838520835160049093020180546001600160a01b039384166001600160a01b0319918216178255848601518284018054918616918316919091179055604080860151600284018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909a1692909616919091179290921696909617169190911790935560a090930151600390930192909255600b805492830181559093528451601690910260008051602061714f83398151915281019182558583015160008051602061718f8339815191528201805491151560ff199092169190911790559285015180518694929361561b9360008051602061716f83398151915201920190615d9b565b5060608201516156319060038301906013615e15565b505050806001016004600089848151811061564857fe5b602090810291909101810151516001600160a01b03168252810191909152604001600020556001016154b3565b50505b6000600981905560015493505b838110156156e6576000600b828154811061569c57fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b8054839081106156cd57fe5b6000918252602090912060169091020155600101615685565b505050505050565b6000818361570f5760405162461bcd60e51b8152600401610c3b919061646f565b50600083858161571b57fe5b0495945050505050565b600081848411156157495760405162461bcd60e51b8152600401610c3b919061646f565b505050900390565b80516000906157625750600061130b565b6020820151805160001a9060c08210156157815760009250505061130b565b5060019392505050565b8051600090811a60808110156157a557600091505061130b565b60b88110806157c0575060c081108015906157c0575060f881105b156157cf57600191505061130b565b60c08110156157e35760b51901905061130b565b60f51901905061130b565b80516000908190811a608081101561580957600191506158c8565b60b881101561581e57607e19810191506158c8565b60c081101561586f57600060b78203600186019550806020036101000a8651049150600181018201935050808310156158695760405162461bcd60e51b8152600401610c3b90616a13565b506158c8565b60f88110156158845760be19810191506158c8565b600060f78203600186019550806020036101000a8651049150600181018201935050808310156158c65760405162461bcd60e51b8152600401610c3b90616a13565b505b5092915050565b80516000906158e05750600061130b565b600080905060006158f4846020015161578b565b602085015185519181019250015b8082101561592257615913826157ee565b82019150826001019250615902565b50909392505050565b805160009060151461593c57600080fd5b6113bb826149ce565b805160609061595357600080fd5b6000615962836020015161578b565b83516040805191839003808352601f19601f8201168301602001909152919250606090828015615999576020820181803683370190505b50905060008160200190506144f7848760200151018285615d21565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166159f957506018615a1d565b6fffffffffffffffffffffffffffffffff198416615a1957506010615a1d565b5060005b6020811015615a5357818181518110615a3257fe5b01602001516001600160f81b03191615615a4b57615a53565b600101615a1d565b60008160200390506060816040519080825280601f01601f191660200182016040528015615a88576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015615acd5750607f60f81b82600081518110615abb57fe5b01602001516001600160f81b03191611155b15615ad957508061130b565b6113bb615aeb8351608060ff16615b6a565b835b6060806040519050835180825260208201818101602087015b81831015615b1e578051835260209283019201615b06565b50855184518101855292509050808201602086015b81831015615b4b578051835260209283019201615b33565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310615b945760405162461bcd60e51b8152600401610c3b90616817565b60408051600180825281830190925260609160208201818036833701905050905060378411615bee5782840160f81b81600081518110615bd057fe5b60200101906001600160f81b031916908160001a90535090506113bb565b6060615bf9856159b5565b90508381510160370160f81b82600081518110615c1257fe5b60200101906001600160f81b031916908160001a905350615c338282615aed565b95945050505050565b805182516000916001600160a01b039182169116148015615c76575081602001516001600160a01b031683602001516001600160a01b0316145b8015615c9b575081604001516001600160a01b031683604001516001600160a01b0316145b8015610ea25750506060908101519101516001600160401b0390811691161490565b815181516000916001918114808314615cd95760009250615d17565b600160208701838101602088015b600284838510011415615d12578051835114615d065760009650600093505b60209283019201615ce7565b505050505b5090949350505050565b80615d2b57610c5b565b5b60208110615d4b578251825260209283019290910190601f1901615d2c565b915181516020939093036101000a6000190180199091169216919091179052565b60405180608001604052806000815260200160001515815260200160608152602001615d96615fc7565b905290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615ddc57805160ff1916838001178555615e09565b82800160010185558215615e09579182015b82811115615e09578251825591602001919060010190615dee565b506126e3929150615fe6565b8260138101928215615e095791602002820182811115615e09578251825591602001919060010190615dee565b6040518060600160405280600060ff16815260200160608152602001606081525090565b6040518060400160405280615e79615fad565b8152602001600081525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615ef45780548555615e09565b82800160010185558215615e0957600052602060002091601f016020900482015b82811115615e09578254825591600101919060010190615f15565b8260138101928215615e095791820182811115615e09578254825591600101919060010190615f15565b50805460018160011615610100020316600290046000825580601f10615f805750611517565b601f0160209004906000526020600020908101906115179190615fe6565b50611517906013810190615fe6565b604051806040016040528060008152602001600081525090565b6040518061026001604052806013906020820280368337509192915050565b61269591905b808211156126e35760008155600101615fec565b60008083601f840112616011578182fd5b5081356001600160401b03811115616027578182fd5b6020830191508360208083028501011115614f0857600080fd5b60008083601f840112616052578182fd5b5081356001600160401b03811115616068578182fd5b602083019150836020828501011115614f0857600080fd5b600060208284031215616091578081fd5b81356001600160a01b0381168114610ea2578182fd5b600080600080604085870312156160bc578283fd5b84356001600160401b03808211156160d2578485fd5b6160de88838901616000565b909650945060208701359150808211156160f6578384fd5b5061610387828801616000565b95989497509550505050565b600060208284031215616120578081fd5b81518015158114610ea2578182fd5b60008060008060408587031215616144578384fd5b84356001600160401b038082111561615a578586fd5b61616688838901616041565b9096509450602087013591508082111561617e578384fd5b5061610387828801616041565b60006020828403121561619c578081fd5b5035919050565b6000602082840312156161b4578081fd5b5051919050565b600080604083850312156161cd578182fd5b505080516020909101519092909150565b6000806000604084860312156161f2578283fd5b833560ff81168114616202578384fd5b925060208401356001600160401b0381111561621c578283fd5b61622886828701616041565b9497909650939450505050565b6000815180845260208085019450808401835b8381101561626d5781516001600160a01b031687529582019590820190600101616248565b509495945050505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b600081518084526162ba816020860160208601616f57565b601f01601f19169290920160200192915050565b600082516162e0818460208701616f57565b9190910192915050565b918252602082015260400190565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03968716815294861660208601529290941660408401526001600160401b03166060830152911515608082015260a081019190915260c00190565b600060208252610ea26020830184616235565b60006040825261638d6040830185616235565b602083820381850152818551808452828401915082838202850101838801865b838110156163db57601f198784030185526163c98383516162a2565b948601949250908501906001016163ad565b50909998505050505050505050565b6000608082526163fd6080830187616235565b828103602084810191909152865180835287820192820190845b8181101561643357845183529383019391830191600101616417565b505084810360408601526164478188616235565b93505050506001600160401b038316606083015295945050505050565b901515815260200190565b600060208252610ea260208301846162a2565b600060408252616496604083018688616278565b82810360208401526164a9818587616278565b979650505050505050565b6020808252601c908201527f6c656e677468206f66206275726e526174696f206d69736d6174636800000000604082015260600190565b60208082526026908201527f6c656e677468206f66206d61784e756d4f664d61696e7461696e696e67206d696040820152650e6dac2e8c6d60d31b606082015260800190565b6020808252601b908201527f6261746368207472616e736665722072657475726e2066616c73650000000000604082015260600190565b6020808252602c908201527f6c656e677468206f66206d61784e756d4f66576f726b696e6743616e6469646160408201526b0e8cae640dad2e6dac2e8c6d60a31b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61696e7461696e536c6173685363616c65206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252818101527f6c656e677468206f66206e756d4f66436162696e657473206d69736d61746368604082015260600190565b60208082526019908201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526028908201527f746865206e756d4f66436162696e657473206d75737420626520677265617465604082015267072207468616e20360c41b606082015260800190565b60208082526039908201527f746865206e756d4f66436162696e657473206d757374206265206c657373207460408201527f68616e204d41585f4e554d5f4f465f56414c494441544f525300000000000000606082015260800190565b60208082526029908201527f746865206e756d626572206f662076616c696461746f727320657863656564206040820152681d1a19481b1a5b5a5d60ba1b606082015260800190565b60208082526022908201527f63616e206e6f7420646f207468697320747769636520696e206f6e6520626c6f604082015261636b60f01b606082015260800190565b6020808252602b908201527f746865206275726e526174696f206d757374206265206e6f206772656174657260408201526a0207468616e2031303030360ac1b606082015260800190565b6020808252600e908201526d696e70757420746f6f206c6f6e6760901b604082015260600190565b60208082526037908201527f746865206d61784e756d4f664d61696e7461696e696e67206d7573742062652060408201527f6c657373207468616e206e756d4f66436162696e657473000000000000000000606082015260800190565b6020808252602b908201527f6475706c696361746520636f6e73656e7375732061646472657373206f66207660408201526a185b1a59185d1bdc94d95d60aa1b606082015260800190565b60208082526027908201527f7468652065787069726554696d655365636f6e64476170206973206f7574206f604082015266662072616e676560c81b606082015260800190565b6020808252601590820152746465706f7369742076616c7565206973207a65726f60581b604082015260600190565b60208082526049908201527f746865206d61784e756d4f66576f726b696e6743616e64696461746573206d7560408201527f7374206265206e6f742067726561746572207468616e206d61784e756d4f6643606082015268616e6469646174657360b81b608082015260a00190565b60208082526027908201527f7468652066696e616c697479526577617264526174696f206973206f7574206f604082015266662072616e676560c81b606082015260800190565b6020808252601190820152706164646974696f6e206f766572666c6f7760781b604082015260600190565b60208082526023908201527f63616e206e6f7420656e7465722054656d706f72617279204d61696e74656e616040820152626e636560e81b606082015260800190565b60208082526025908201527f6c656e677468206f66206a61696c2076616c696461746f7273206d757374206260408201526465206f6e6560d81b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252602e908201527f746865206d6573736167652073656e646572206d75737420626520676f76657260408201526d1b985b98d94818dbdb9d1c9858dd60921b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61784e756d4f6643616e64696461746573206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252601290820152716e6f7420696e206d61696e74656e616e636560701b604082015260600190565b60208082526021908201527f666565206973206c6172676572207468616e2044555354595f494e434f4d494e6040820152604760f81b606082015260800190565b60208082526019908201527f74686520636f6e747261637420616c726561647920696e697400000000000000604082015260600190565b60208082526026908201527f6c656e677468206f662066696e616c697479526577617264526174696f206d696040820152650e6dac2e8c6d60d31b606082015260800190565b6020808252601a908201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604082015260600190565b60208082526026908201527f6c656e677468206f662065787069726554696d655365636f6e64476170206d696040820152650e6dac2e8c6d60d31b606082015260800190565b60208082526017908201527f6f6e6c792063757272656e742076616c696461746f7273000000000000000000604082015260600190565b60208082526021908201527f6661696c656420746f20706172736520696e69742076616c696461746f7253656040820152601d60fa1b606082015260800190565b6020808252602f908201527f746865206d6573736167652073656e646572206d7573742062652063726f737360408201526e0818da185a5b8818dbdb9d1c9858dd608a1b606082015260800190565b6020808252602d908201527f746865206d6573736167652073656e646572206d75737420626520746865206260408201526c3637b1b590383937b23ab1b2b960991b606082015260800190565b6020808252603e908201527f746865206d61696e7461696e536c6173685363616c65206d757374206265206760408201527f726561746572207468616e203020616e64206c657373207468616e2031300000606082015260800190565b6020808252600d908201526c756e6b6e6f776e20706172616d60981b604082015260600190565b60208082526029908201527f746865206d6573736167652073656e646572206d75737420626520736c6173686040820152680818dbdb9d1c9858dd60ba1b606082015260800190565b61ffff91909116815260200190565b90815260200190565b6000848252831515602083015260606040830152615c3360608301846162a2565b63ffffffff91909116815260200190565b60ff91909116815260200190565b600060ff8516825260406020830152615c33604083018486616278565b60005b83811015616f72578181015183820152602001616f5a565b83811115612c48575050600091015256fef901a880f901a4f844941284214b9b9c85549ab3d2b972df0deef66ac2c9946ddf42a51534fc98d0c0a3b42c963cace8441ddf946ddf42a51534fc98d0c0a3b42c963cace8441ddf8410000000f84494a2959d3f95eae5dc7d70144ce1b73b403b7eb6e0948081ef03f1d9e0bb4a5bf38f16285c879299f07f948081ef03f1d9e0bb4a5bf38f16285c879299f07f8410000000f8449435552c16704d214347f29fa77f77da6d75d7c75294dc4973e838e3949c77aced16ac2315dc2d7ab11194dc4973e838e3949c77aced16ac2315dc2d7ab1118410000000f84494980a75ecd1309ea12fa2ed87a8744fbfc9b863d594cc6ac05c95a99c1f7b5f88de0e3486c82293b27094cc6ac05c95a99c1f7b5f88de0e3486c82293b2708410000000f84494f474cf03cceff28abc65c9cbae594f725c80e12d94e61a183325a18a173319dd8e19c8d069459e217594e61a183325a18a173319dd8e19c8d069459e21758410000000f84494b71b214cb885500844365e95cd9942c7276e7fd894d22ca3ba2141d23adab65ce4940eb7665ea2b6a794d22ca3ba2141d23adab65ce4940eb7665ea2b6a7841000000070e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb20175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db90175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbb0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbaa2646970667358221220cdf966601ebb54cb0e5a2ce03b7bba1df8f8464b1bf85237f62391faa3c8dd5164736f6c63430006040033", + }, + { + ContractAddr: common.HexToAddress(SlashContract), + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/030cf951e9f5ae1f8211333af807e5d30f3b5a85", + Code: "608060405234801561001057600080fd5b50600436106102745760003560e01c80638256ace611610151578063c81b1662116100c3578063dc927faf11610087578063dc927faf1461049a578063e1c7392a146104a2578063f9a2bbc7146104aa578063fc3e5908146104b2578063fc4333cd146104ba578063fd6a6879146104c257610274565b8063c81b166214610451578063c8509d8114610459578063c96be4cb1461046c578063cc844b731461047f578063d2a42e4b1461049257610274565b8063a1a11bf511610115578063a1a11bf514610409578063a78abc1614610411578063ab51bb9614610426578063ac0af6291461042e578063ac43175114610436578063c80d4b8f1461044957610274565b80638256ace6146103d6578063831d65d1146103de57806396713da9146103f15780639bc8e4f2146103f95780639dc092621461040157610274565b80634bf6c882116101ea5780636e47b482116101ae5780636e47b482146103a657806370fd5bad146103ae578063718a8aa8146103b657806375d47a0a146103be5780637912a65d146103c65780637942fd05146103ce57610274565b80634bf6c8821461037157806351e8067214610379578063567a372d146103815780635bfb49901461038957806362b72cf51461039e57610274565b806337c8dab91161023c57806337c8dab914610301578063389f4f71146103225780633a63f4b1146103375780633dffc3871461033f57806343756e5c14610354578063493279b11461035c57610274565b80630bee7a67146102795780630e2374a5146102975780631182b875146102ac57806323bac5a2146102cc57806335aa2e44146102ee575b600080fd5b6102816104ca565b60405161028e9190613058565b60405180910390f35b61029f6104cf565b60405161028e9190612989565b6102bf6102ba3660046128bf565b6104d5565b60405161028e91906129c1565b6102df6102da36600461266d565b61053b565b60405161028e93929190613040565b61029f6102fc36600461288f565b61055e565b61031461030f36600461266d565b610585565b60405161028e929190613032565b61032a6105dc565b60405161028e9190613008565b61032a6105e2565b6103476105e8565b60405161028e9190613069565b61029f6105ed565b6103646105f3565b60405161028e9190612ff9565b6103476105f9565b61029f6105fe565b61032a610604565b61039c61039736600461266d565b61060a565b005b61032a6106b5565b61029f6106bb565b6103476106c1565b6103476106c6565b61029f6106cb565b61032a6106d1565b6103476106d6565b6103146106db565b61039c6103ec3660046128bf565b6106e5565b6103476107f7565b61032a6107fc565b61029f610807565b61029f61080d565b610419610813565b60405161028e91906129b6565b61028161081c565b61032a610821565b61039c610444366004612773565b610826565b61032a610bda565b61029f610bdf565b61039c6104673660046128bf565b610be5565b61039c61047a36600461266d565b610c56565b61039c61048d3660046127dc565b611047565b61032a61151d565b61029f611522565b61039c611528565b61029f611564565b61034761156a565b61039c61156f565b61029f6119b8565b606481565b61200181565b606033612000146105015760405162461bcd60e51b81526004016104f890612e7f565b60405180910390fd5b60005460ff166105235760405162461bcd60e51b81526004016104f890612a6d565b60405162461bcd60e51b81526004016104f890612f42565b600260208190526000918252604090912080546001820154919092015460ff1683565b6001818154811061056b57fe5b6000918252602090912001546001600160a01b0316905081565b600080610590612454565b5050506001600160a01b0316600090815260026020818152604092839020835160608101855281548082526001830154938201849052919093015460ff16151592909301919091529091565b60055481565b60065481565b600181565b61100181565b6102ca81565b600881565b61200081565b60045481565b336110001461062b5760405162461bcd60e51b81526004016104f890612c93565b60005460ff1661064d5760405162461bcd60e51b81526004016104f890612a6d565b61200063f7a251d7600b610660846119be565b60006040518463ffffffff1660e01b815260040161068093929190613077565b600060405180830381600087803b15801561069a57600080fd5b505af11580156106ae573d6000803e3d6000fd5b5050505050565b60035481565b61100581565b600281565b601081565b61100881565b603281565b600b81565b6004546005549091565b33612000146107065760405162461bcd60e51b81526004016104f890612e7f565b60005460ff166107285760405162461bcd60e51b81526004016104f890612a6d565b610730612477565b600061077184848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a9192505050565b9150915080156107b85781516040517f7f0956d47419b9525356e7111652b653b530ec6f5096dccc04589bc38e629967916107ab91613058565b60405180910390a16106ae565b81516040517f7d45f62d17443dd4547bca8a8112c60e2385669318dc300ec61a5d2492f262e7916107e891613058565b60405180910390a15050505050565b600981565b662386f26fc1000081565b61100781565b61100681565b60005460ff1681565b600081565b600481565b60005460ff166108485760405162461bcd60e51b81526004016104f890612a6d565b33611007146108695760405162461bcd60e51b81526004016104f890612d3c565b6108d484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260148152731b5a5cd9195b59585b9bdc951a1c995cda1bdb1960621b60208201529150611b119050565b1561096f57602081146108f95760405162461bcd60e51b81526004016104f890612c1f565b604080516020601f840181900481028201810190925282815260009161093791858580838501838280828437600092019190915250611b6b92505050565b90506001811015801561094b575060055481105b6109675760405162461bcd60e51b81526004016104f890612e3a565b600455610b97565b6109d584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e19995b1bdb9e551a1c995cda1bdb19608a1b60208201529150611b119050565b15610a7157602081146109fa5760405162461bcd60e51b81526004016104f890612d8a565b604080516020601f8401819004810282018101909252828152600091610a3891858580838501838280828437600092019190915250611b6b92505050565b90506103e88111158015610a4d575060045481115b610a695760405162461bcd60e51b81526004016104f890612adb565b600555610b97565b610ae584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601881527f66696e616c697479536c617368526577617264526174696f000000000000000060208201529150611b119050565b15610b7f5760208114610b0a5760405162461bcd60e51b81526004016104f890612f79565b604080516020601f8401819004810282018101909252828152600091610b4891858580838501838280828437600092019190915250611b6b92505050565b9050600a8110158015610b5b5750606481105b610b775760405162461bcd60e51b81526004016104f890612bd3565b600655610b97565b60405162461bcd60e51b81526004016104f890612f1b565b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a84848484604051610bcc94939291906129d4565b60405180910390a150505050565b609681565b61100281565b3361200014610c065760405162461bcd60e51b81526004016104f890612e7f565b60005460ff16610c285760405162461bcd60e51b81526004016104f890612a6d565b6040517f07db600eebe2ac176be8dcebad61858c245a4961bb32ca2aa3d159b09aa0810e90600090a1505050565b334114610c755760405162461bcd60e51b81526004016104f890612ece565b60005460ff16610c975760405162461bcd60e51b81526004016104f890612a6d565b6003544311610cb85760405162461bcd60e51b81526004016104f890612fc4565b3a15610cd65760405162461bcd60e51b81526004016104f890612d0e565b60405163155853f360e21b8152611000906355614fcc90610cfb908490600401612989565b60206040518083038186803b158015610d1357600080fd5b505afa158015610d27573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4b9190612753565b610d5457611040565b610d5c612454565b506001600160a01b0381166000908152600260208181526040928390208351606081018552815481526001820154928101929092529091015460ff161580159282019290925290610db7576020810180516001019052610e10565b60016040820181905260208201819052805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0384161790555b438152600554602082015181610e2257fe5b06610f6e57600060208201526040516335409f7f60e01b8152611000906335409f7f90610e53908590600401612989565b600060405180830381600087803b158015610e6d57600080fd5b505af1158015610e81573d6000803e3d6000fd5b505050506120006001600160a01b031663f7a251d7600b610ea1856119be565b60006040518463ffffffff1660e01b8152600401610ec193929190613077565b600060405180830381600087803b158015610edb57600080fd5b505af1925050508015610eec575060015b610f69573d808015610f1a576040519150601f19603f3d011682016040523d82523d6000602084013e610f1f565b606091505b50826001600160a01b03167fd7bc86ff5d08c8ab043edec743302aba2520e6635172a428bc956721db9e2d1c836020015183604051610f5f929190613011565b60405180910390a2505b610fda565b600454816020015181610f7d57fe5b06610fda576040516375abf10160e11b81526110009063eb57e20290610fa7908590600401612989565b600060405180830381600087803b158015610fc157600080fd5b505af1158015610fd5573d6000803e3d6000fd5b505050505b6001600160a01b0382166000818152600260208181526040808420865181559186015160018301558581015191909201805460ff1916911515919091179055517fddb6012116e51abf5436d956a4f0ebd927e92c576ff96d7918290c8782291e3e9190a2505b5043600355565b60005460ff166110695760405162461bcd60e51b81526004016104f890612a6d565b604051630a83aaa960e31b81526110069063541d55489061108e903390600401612989565b60206040518083038186803b1580156110a657600080fd5b505afa1580156110ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110de9190612753565b6110fa5760405162461bcd60e51b81526004016104f890612a06565b6006546111075760146006555b8051514361010090910111801561112957504381602001516000015161010001115b6111455760405162461bcd60e51b81526004016104f890612a3d565b8060200151602001518160000151602001511480156111735750806020015160600151816000015160600151145b156111905760405162461bcd60e51b81526004016104f890612c66565b8051604081015190511080156111af5750602081015160408101519051105b6111cb5760405162461bcd60e51b81526004016104f890612b6f565b6020810151518151511080156111f05750806000015160400151816020015160400151105b8061121b575080515160208201515110801561121b5750806020015160400151816000015160400151105b806112355750806020015160400151816000015160400151145b6112515760405162461bcd60e51b81526004016104f890612aa4565b6060806110006001600160a01b0316633b071dcc6040518163ffffffff1660e01b815260040160006040518083038186803b15801561128f57600080fd5b505afa1580156112a3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526112cb9190810190612690565b60408501519193509150600090815b8351811015611328576113008482815181106112f257fe5b602002602001015183611b70565b156113205784818151811061131157fe5b60200260200101519250611328565b6001016112da565b506001600160a01b03821661134f5760405162461bcd60e51b81526004016104f890612ba6565b61136185600001518660400151611bd4565b801561137a575061137a85602001518660400151611bd4565b6113965760405162461bcd60e51b81526004016104f890612b10565b6006546040516309a99b4f60e41b815260646110028031909302049190639a99b4f0906113c9903390859060040161299d565b602060405180830381600087803b1580156113e357600080fd5b505af11580156113f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141b91906128a7565b506040516335409f7f60e01b8152611000906335409f7f90611441908690600401612989565b600060405180830381600087803b15801561145b57600080fd5b505af115801561146f573d6000803e3d6000fd5b505050506120006001600160a01b031663f7a251d7600b61148f866119be565b60006040518463ffffffff1660e01b81526004016114af93929190613077565b600060405180830381600087803b1580156114c957600080fd5b505af11580156114dd573d6000803e3d6000fd5b50506040516001600160a01b03861692507fddb6012116e51abf5436d956a4f0ebd927e92c576ff96d7918290c8782291e3e9150600090a2505050505050565b601481565b61100381565b60005460ff161561154b5760405162461bcd60e51b81526004016104f890612dcc565b603260045560966005556000805460ff19166001179055565b61100081565b600381565b33611000146115905760405162461bcd60e51b81526004016104f890612c93565b60005460ff166115b25760405162461bcd60e51b81526004016104f890612a6d565b6001546115be576119b6565b600154600090600019015b80821161198a576000805b828410156116ed576115e4612454565b60026000600187815481106115f557fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff1615159082015260055490915060049004816020015111156116d75760046005548161166257fe5b0481602001510381602001818152505080600260006001888154811061168457fe5b6000918252602080832091909101546001600160a01b0316835282810193909352604091820190208351815591830151600183015591909101516002909101805460ff19169115159190911790556116e1565b60019250506116ed565b508360010193506115d4565b828411611884576116fc612454565b600260006001868154811061170d57fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff1615159082015260055490915060049004816020015111156117f55760046005548161177a57fe5b0481602001510381602001818152505080600260006001878154811061179c57fe5b6000918252602080832091909101546001600160a01b03168352828101939093526040918201902083518155918301516001808401919091559201516002909101805460ff191691151591909117905591506118849050565b600260006001868154811061180657fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff1916905580548061184a57fe5b600082815260209020810160001990810180546001600160a01b0319169055019055836118775750611884565b50600019909201916116ed565b81801561188e5750805b1561196d5760026000600186815481106118a457fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff191690558054849081106118eb57fe5b600091825260209091200154600180546001600160a01b03909216918690811061191157fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600180548061194a57fe5b600082815260209020810160001990810180546001600160a01b03191690550190555b8261197957505061198a565b5050600190910190600019016115c9565b6040517fcfdb3b6ccaeccbdc68be3c59c840e3b3c90f0a7c491f5fff1cf56cfda200dd9c90600090a150505b565b61100481565b60408051600480825260a08201909252606091829190816020015b60608152602001906001900390816119d9579050509050611a02836001600160a01b0316611dac565b81600081518110611a0f57fe5b6020026020010181905250611a2343611dcf565b81600181518110611a3057fe5b6020908102919091010152611a466102ca611dcf565b81600281518110611a5357fe5b6020026020010181905250611a6742611dcf565b81600381518110611a7457fe5b6020026020010181905250611a8881611de2565b9150505b919050565b611a99612477565b6000611aa3612477565b611aab612489565b611abc611ab786611e6c565b611e91565b90506000805b611acb83611edb565b15611b045780611af757611ae6611ae184611efc565b611f4a565b63ffffffff16845260019150611afc565b611b04565b600101611ac2565b5091935090915050915091565b600081604051602001611b24919061296d565b6040516020818303038152906040528051906020012083604051602001611b4b919061296d565b604051602081830303815290604052805190602001201490505b92915050565b015190565b815181516000916001918114808314611b8c5760009250611bca565b600160208701838101602088015b600284838510011415611bc5578051835114611bb95760009650600093505b60209283019201611b9a565b505050505b5090949350505050565b60408051600480825260a0820190925260009160609190816020015b6060815260200190600190039081611bf0575050604080516020808252818301909252919250606091908082018180368337019050509050611c358560000151611dcf565b82600081518110611c4257fe5b6020026020010181905250611c5d6020866020015183611fcc565b611c6681611fdc565b82600181518110611c7357fe5b6020026020010181905250611c8b8560400151611dcf565b82600281518110611c9857fe5b6020026020010181905250611cb36020866060015183611fcc565b611cbc81611fdc565b82600381518110611cc957fe5b6020026020010181905250611cef6020611ce284611de2565b8051906020012083611fcc565b6040805160b080825260e08201909252606091602082018180368337019050509050611d1f818360006020612032565b611d3181876080015160206060612032565b611d3f818660806030612032565b604080516001808252818301909252606091602082018180368337019050509050815160016020830182602086016066600019fa611d7c57600080fd5b506001611d8a826000612085565b60ff1614611d9f576000945050505050611b65565b5060019695505050505050565b60408051600560a21b8318601482015260348101909152606090611a8881611fdc565b6060611b65611ddd836120a1565b611fdc565b6060815160001415611e035750604080516000815260208101909152611a8c565b606082600081518110611e1257fe5b602002602001015190506000600190505b8351811015611e5357611e4982858381518110611e3c57fe5b6020026020010151612187565b9150600101611e23565b50611a88611e66825160c060ff16612204565b82612187565b611e746124a9565b506040805180820190915281518152602082810190820152919050565b611e99612489565b611ea2826122d6565b611eab57600080fd5b6000611eba8360200151612310565b60208085015160408051808201909152868152920190820152915050919050565b6000611ee56124a9565b505080518051602091820151919092015191011190565b611f046124a9565b611f0d82611edb565b611f1657600080fd5b60208201516000611f2682612373565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590611f5f57508151602110155b611f6857600080fd5b6000611f778360200151612310565b90508083600001511015611f9d5760405162461bcd60e51b81526004016104f890612e03565b825160208085015183018051928490039291831015611fc357826020036101000a820491505b50949350505050565b9091018181526020918201910152565b60608151600114801561200e5750607f60f81b82600081518110611ffc57fe5b01602001516001600160f81b03191611155b1561201a575080611a8c565b611b6561202c8351608060ff16612204565b83612187565b60005b818110156106ae5783818151811061204957fe5b602001015160f81c60f81b85848060010195508151811061206657fe5b60200101906001600160f81b031916908160001a905350600101612035565b6000816001018351101561209857600080fd5b50016001015190565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166120e557506018612109565b6fffffffffffffffffffffffffffffffff19841661210557506010612109565b5060005b602081101561213f5781818151811061211e57fe5b01602001516001600160f81b031916156121375761213f565b600101612109565b60008160200390506060816040519080825280601f01601f191660200182016040528015612174576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b818310156121b85780518352602092830192016121a0565b50855184518101855292509050808201602086015b818310156121e55780518352602092830192016121cd565b508651929092011591909101601f01601f191660405250905092915050565b606068010000000000000000831061222e5760405162461bcd60e51b81526004016104f890612b47565b604080516001808252818301909252606091602082018180368337019050509050603784116122885782840160f81b8160008151811061226a57fe5b60200101906001600160f81b031916908160001a9053509050611b65565b6060612293856120a1565b90508381510160370160f81b826000815181106122ac57fe5b60200101906001600160f81b031916908160001a9053506122cd8282612187565b95945050505050565b80516000906122e757506000611a8c565b6020820151805160001a9060c082101561230657600092505050611a8c565b5060019392505050565b8051600090811a608081101561232a576000915050611a8c565b60b8811080612345575060c08110801590612345575060f881105b15612354576001915050611a8c565b60c08110156123685760b519019050611a8c565b60f519019050611a8c565b80516000908190811a608081101561238e576001915061244d565b60b88110156123a357607e198101915061244d565b60c08110156123f457600060b78203600186019550806020036101000a8651049150600181018201935050808310156123ee5760405162461bcd60e51b81526004016104f890612ce3565b5061244d565b60f88110156124095760be198101915061244d565b600060f78203600186019550806020036101000a86510491506001810182019350508083101561244b5760405162461bcd60e51b81526004016104f890612ce3565b505b5092915050565b604051806060016040528060008152602001600081526020016000151581525090565b60408051602081019091526000815290565b604051806040016040528061249c6124a9565b8152602001600081525090565b604051806040016040528060008152602001600081525090565b600082601f8301126124d3578081fd5b81516124e66124e1826130ca565b6130a3565b818152915060208083019084810160005b8481101561255c578151870188603f82011261251257600080fd5b838101516125226124e1826130ea565b81815260408b8184860101111561253857600080fd5b6125478388840183870161310e565b508652505092820192908201906001016124f7565b505050505092915050565b60008083601f840112612578578182fd5b50813567ffffffffffffffff81111561258f578182fd5b6020830191508360208285010111156125a757600080fd5b9250929050565b600082601f8301126125be578081fd5b81356125cc6124e1826130ea565b91508082528360208285010111156125e357600080fd5b8060208401602084013760009082016020015292915050565b600060a0828403121561260d578081fd5b61261760a06130a3565b905081358152602082013560208201526040820135604082015260608201356060820152608082013567ffffffffffffffff81111561265557600080fd5b612661848285016125ae565b60808301525092915050565b60006020828403121561267e578081fd5b81356126898161313e565b9392505050565b600080604083850312156126a2578081fd5b825167ffffffffffffffff808211156126b9578283fd5b81850186601f8201126126ca578384fd5b805192506126da6124e1846130ca565b80848252602080830192508084018a8283890287010111156126fa578788fd5b8794505b868510156127255780516127118161313e565b8452600194909401939281019281016126fe565b50880151909650935050508082111561273c578283fd5b50612749858286016124c3565b9150509250929050565b600060208284031215612764578081fd5b81518015158114612689578182fd5b60008060008060408587031215612788578182fd5b843567ffffffffffffffff8082111561279f578384fd5b6127ab88838901612567565b909650945060208701359150808211156127c3578384fd5b506127d087828801612567565b95989497509550505050565b6000602082840312156127ed578081fd5b813567ffffffffffffffff80821115612804578283fd5b81840160608187031215612816578384fd5b61282060606130a3565b9250803582811115612830578485fd5b61283c878284016125fc565b845250602081013582811115612850578485fd5b61285c878284016125fc565b602085015250604081013582811115612873578485fd5b61287f878284016125ae565b6040850152509195945050505050565b6000602082840312156128a0578081fd5b5035919050565b6000602082840312156128b8578081fd5b5051919050565b6000806000604084860312156128d3578283fd5b833560ff811681146128e3578384fd5b9250602084013567ffffffffffffffff8111156128fe578283fd5b61290a86828701612567565b9497909650939450505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b6000815180845261295981602086016020860161310e565b601f01601f19169290920160200192915050565b6000825161297f81846020870161310e565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b6000602082526126896020830184612941565b6000604082526129e8604083018688612917565b82810360208401526129fb818587612917565b979650505050505050565b6020808252601f908201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604082015260600190565b6020808252601690820152751d1bdbc81bdb1908189b1bd8dac81a5b9d9bdb1d995960521b604082015260600190565b60208082526019908201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604082015260600190565b6020808252601a908201527f6e6f2076696f6c6174696f6e206f6620766f74652072756c6573000000000000604082015260600190565b6020808252818101527f7468652066656c6f6e795468726573686f6c64206f7574206f662072616e6765604082015260600190565b60208082526017908201527f766572696679207369676e6174757265206661696c6564000000000000000000604082015260600190565b6020808252600e908201526d696e70757420746f6f206c6f6e6760901b604082015260600190565b60208082526019908201527f7372634e756d20626967676572207468616e207461724e756d00000000000000604082015260600190565b6020808252601390820152721d985b1a59185d1bdc881b9bdd08195e1a5cdd606a1b604082015260600190565b6020808252602c908201527f7468652066696e616c69747920736c6173682072657761726420726174696f2060408201526b6f7574206f662072616e676560a01b606082015260800190565b60208082526027908201527f6c656e677468206f66206d697364656d65616e6f725468726573686f6c64206d6040820152660d2e6dac2e8c6d60cb1b606082015260800190565b60208082526013908201527274776f206964656e746963616c20766f74657360681b604082015260600190565b60208082526030908201527f746865206d6573736167652073656e646572206d7573742062652076616c696460408201526f185d1bdc94d95d0818dbdb9d1c9858dd60821b606082015260800190565b6020808252601190820152706164646974696f6e206f766572666c6f7760781b604082015260600190565b6020808252601490820152736761737072696365206973206e6f74207a65726f60601b604082015260600190565b6020808252602e908201527f746865206d6573736167652073656e646572206d75737420626520676f76657260408201526d1b985b98d94818dbdb9d1c9858dd60921b606082015260800190565b60208082526022908201527f6c656e677468206f662066656c6f6e795468726573686f6c64206d69736d61746040820152610c6d60f31b606082015260800190565b60208082526019908201527f74686520636f6e747261637420616c726561647920696e697400000000000000604082015260600190565b6020808252601a908201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604082015260600190565b60208082526025908201527f746865206d697364656d65616e6f725468726573686f6c64206f7574206f662060408201526472616e676560d81b606082015260800190565b6020808252602f908201527f746865206d6573736167652073656e646572206d7573742062652063726f737360408201526e0818da185a5b8818dbdb9d1c9858dd608a1b606082015260800190565b6020808252602d908201527f746865206d6573736167652073656e646572206d75737420626520746865206260408201526c3637b1b590383937b23ab1b2b960991b606082015260800190565b6020808252600d908201526c756e6b6e6f776e20706172616d60981b604082015260600190565b6020808252601e908201527f7265636569766520756e65787065637465642073796e207061636b6167650000604082015260600190565b6020808252602b908201527f6c656e677468206f662066696e616c697479536c61736852657761726452617460408201526a0d2de40dad2e6dac2e8c6d60ab1b606082015260800190565b6020808252818101527f63616e206e6f7420736c61736820747769636520696e206f6e6520626c6f636b604082015260600190565b61ffff91909116815260200190565b90815260200190565b60008382526040602083015261302a6040830184612941565b949350505050565b918252602082015260400190565b92835260208301919091521515604082015260600190565b63ffffffff91909116815260200190565b60ff91909116815260200190565b600060ff85168252606060208301526130936060830185612941565b9050826040830152949350505050565b60405181810167ffffffffffffffff811182821017156130c257600080fd5b604052919050565b600067ffffffffffffffff8211156130e0578081fd5b5060209081020190565b600067ffffffffffffffff821115613100578081fd5b50601f01601f191660200190565b60005b83811015613129578181015183820152602001613111565b83811115613138576000848401525b50505050565b6001600160a01b038116811461315357600080fd5b5056fea264697066735822122062d6936d7751cb36a7753c3187f769a6c7d5ce515f68149fca01eefaf8f04af564736f6c63430006040033", + }, + { + ContractAddr: common.HexToAddress(SystemRewardContract), + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/030cf951e9f5ae1f8211333af807e5d30f3b5a85", + Code: "6080604052600436106101a05760003560e01c80637942fd05116100ec578063ac4317511161008a578063f9a2bbc711610064578063f9a2bbc714610550578063fb5478b314610565578063fc3e59081461057a578063fd6a68791461058f576101e4565b8063ac43175114610457578063c81b166214610526578063dc927faf1461053b576101e4565b80639dc09262116100c65780639dc0926214610403578063a1a11bf514610418578063a78abc161461042d578063ab51bb9614610442576101e4565b80637942fd05146103a057806396713da9146103b55780639a99b4f0146103ca576101e4565b80634bf6c882116101595780636e47b482116101335780636e47b4821461034c57806370fd5bad14610361578063718a8aa81461037657806375d47a0a1461038b576101e4565b80634bf6c882146102db57806351e80672146102f05780636d70f7ae14610305576101e4565b80630bee7a67146101e95780630e2374a5146102175780633a0b0eff146102485780633dffc3871461026f57806343756e5c1461029a578063493279b1146102af576101e4565b366101e45734156101e25760408051348152905133917f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db919081900360200190a25b005b600080fd5b3480156101f557600080fd5b506101fe6105a4565b6040805163ffffffff9092168252519081900360200190f35b34801561022357600080fd5b5061022c6105a9565b604080516001600160a01b039092168252519081900360200190f35b34801561025457600080fd5b5061025d6105af565b60408051918252519081900360200190f35b34801561027b57600080fd5b506102846105b5565b6040805160ff9092168252519081900360200190f35b3480156102a657600080fd5b5061022c6105ba565b3480156102bb57600080fd5b506102c46105c0565b6040805161ffff9092168252519081900360200190f35b3480156102e757600080fd5b506102846105c6565b3480156102fc57600080fd5b5061022c6105cb565b34801561031157600080fd5b506103386004803603602081101561032857600080fd5b50356001600160a01b03166105d1565b604080519115158252519081900360200190f35b34801561035857600080fd5b5061022c6105ef565b34801561036d57600080fd5b506102846105f5565b34801561038257600080fd5b506102846105fa565b34801561039757600080fd5b5061022c6105ff565b3480156103ac57600080fd5b50610284610605565b3480156103c157600080fd5b5061028461060a565b3480156103d657600080fd5b5061025d600480360360408110156103ed57600080fd5b506001600160a01b03813516906020013561060f565b34801561040f57600080fd5b5061022c6107ba565b34801561042457600080fd5b5061022c6107c0565b34801561043957600080fd5b506103386107c6565b34801561044e57600080fd5b506101fe6107cf565b34801561046357600080fd5b506101e26004803603604081101561047a57600080fd5b81019060208101813564010000000081111561049557600080fd5b8201836020820111156104a757600080fd5b803590602001918460018302840111640100000000831117156104c957600080fd5b9193909290916020810190356401000000008111156104e757600080fd5b8201836020820111156104f957600080fd5b8035906020019184600183028401116401000000008311171561051b57600080fd5b5090925090506107d4565b34801561053257600080fd5b5061022c610b57565b34801561054757600080fd5b5061022c610b5d565b34801561055c57600080fd5b5061022c610b63565b34801561057157600080fd5b5061025d610b69565b34801561058657600080fd5b50610284610b75565b34801561059b57600080fd5b5061022c610b7a565b606481565b61200181565b60015481565b600181565b61100181565b6102ca81565b600881565b61200081565b6001600160a01b031660009081526002602052604090205460ff1690565b61100581565b600281565b601081565b61100881565b600b81565b600981565b6000805460ff1661068c57600260208190527fe57bda0a954a7c7381b17b2c763e646ba2c60f67292d287ba583603e2c1c41668054600160ff19918216811790925561100560009081527fe25235fc0de9d7165652bef0846fefda506174abb9a190f03d0f7bcc6146dbce80548316841790559282558254161790555b3360009081526002602052604090205460ff166106da5760405162461bcd60e51b815260040180806020018281038252602b815260200180610c68602b913960400191505060405180910390fd5b60004783106106e957476106eb565b825b9050670de0b6b3a76400008111156107085750670de0b6b3a76400005b8015610789576040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015610744573d6000803e3d6000fd5b506040805182815290516001600160a01b038616917ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0919081900360200190a26107b3565b6040517fe589651933c2457488cc0d8e0941518abf748e799435e4e396d9c4d0b2db2d4d90600090a15b9392505050565b61100781565b61100681565b60005460ff1681565b600081565b33611007146108145760405162461bcd60e51b815260040180806020018281038252602e815260200180610cc2602e913960400191505060405180910390fd5b61087684848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600b81526a30b23227b832b930ba37b960a91b60208201529150610b809050565b1561094e57606082828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050825192935050601490911490506108f95760405162461bcd60e51b815260040180806020018281038252602c815260200180610cf0602c913960400191505060405180910390fd5b60148101516001600160a01b038116600081815260026020526040808220805460ff19166001179055517f9870d7fe5d112134c55844951dedf365363006d9c588db07c4c85af6322a06199190a25050610ac5565b6109b384848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600e81526d3232b632ba32a7b832b930ba37b960911b60208201529150610b809050565b15610a8857606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060149091149050610a365760405162461bcd60e51b815260040180806020018281038252602f815260200180610c93602f913960400191505060405180910390fd5b60148101516001600160a01b038116600081815260026020526040808220805460ff19169055517fb40992a19dba61ea600e87fce607102bf5908dc89076217b6ca6ae195224f7029190a25050610ac5565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b61100081565b670de0b6b3a764000081565b600381565b61100481565b6000816040516020018082805190602001908083835b60208310610bb55780518252601f199092019160209182019101610b96565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310610c235780518252601f199092019160209182019101610c04565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490509291505056fe6f6e6c79206f70657261746f7220697320616c6c6f77656420746f2063616c6c20746865206d6574686f646c656e677468206f662076616c756520666f722064656c6574654f70657261746f722073686f756c64206265203230746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f72206164644f70657261746f722073686f756c64206265203230a2646970667358221220dfab8b447e80ff45b4921032d6fc749c076c81bafdd35dc3adbf21cb41cdac7964736f6c63430006040033", + }, + }, + } } func UpgradeBuildInSystemContract(config *params.ChainConfig, blockNumber *big.Int, statedb *state.StateDB) { @@ -603,6 +667,10 @@ func UpgradeBuildInSystemContract(config *params.ChainConfig, blockNumber *big.I applySystemContractUpgrade(planckUpgrade[network], blockNumber, statedb, logger) } + if config.IsOnBoneh(blockNumber) { + applySystemContractUpgrade(bonehUpgrade[network], blockNumber, statedb, logger) + } + /* apply other upgrades */ diff --git a/core/types/vote.go b/core/types/vote.go new file mode 100644 index 0000000000..e631b7294d --- /dev/null +++ b/core/types/vote.go @@ -0,0 +1,92 @@ +package types + +import ( + "sync/atomic" + + "github.com/pkg/errors" + "github.com/prysmaticlabs/prysm/v3/crypto/bls" + + "github.com/ethereum/go-ethereum/common" +) + +const ( + BLSPublicKeyLength = 48 + BLSSignatureLength = 96 + + MaxAttestationExtraLength = 256 + NaturallyFinalizedDist = 21 // The distance to naturally finalized a block +) + +type BLSPublicKey [BLSPublicKeyLength]byte +type BLSSignature [BLSSignatureLength]byte +type ValidatorsBitSet uint64 + +// VoteData represents the vote range that validator voted for fast finality. +type VoteData struct { + SourceNumber uint64 // The source block number should be the latest justified block number. + SourceHash common.Hash // The block hash of the source block. + TargetNumber uint64 // The target block number which validator wants to vote for. + TargetHash common.Hash // The block hash of the target block. +} + +// Hash returns the hash of the vote data. +func (d *VoteData) Hash() common.Hash { return rlpHash(d) } + +// VoteEnvelope represents the vote of a single validator. +type VoteEnvelope struct { + VoteAddress BLSPublicKey // The BLS public key of the validator. + Signature BLSSignature // Validator's signature for the vote data. + Data *VoteData // The vote data for fast finality. + + // caches + hash atomic.Value +} + +// VoteAttestation represents the votes of super majority validators. +type VoteAttestation struct { + VoteAddressSet ValidatorsBitSet // The bitset marks the voted validators. + AggSignature BLSSignature // The aggregated BLS signature of the voted validators' signatures. + Data *VoteData // The vote data for fast finality. + Extra []byte // Reserved for future usage. +} + +// Hash returns the vote's hash. +func (v *VoteEnvelope) Hash() common.Hash { + if hash := v.hash.Load(); hash != nil { + return hash.(common.Hash) + } + + h := v.calcVoteHash() + v.hash.Store(h) + return h +} + +func (v *VoteEnvelope) calcVoteHash() common.Hash { + vote := struct { + VoteAddress BLSPublicKey + Signature BLSSignature + Data *VoteData + }{v.VoteAddress, v.Signature, v.Data} + return rlpHash(vote) +} + +func (b BLSPublicKey) Bytes() []byte { return b[:] } + +// Verify vote using BLS. +func (vote *VoteEnvelope) Verify() error { + blsPubKey, err := bls.PublicKeyFromBytes(vote.VoteAddress[:]) + if err != nil { + return errors.Wrap(err, "convert public key from bytes to bls failed") + } + + sig, err := bls.SignatureFromBytes(vote.Signature[:]) + if err != nil { + return errors.Wrap(err, "invalid signature") + } + + voteDataHash := vote.Data.Hash() + if !sig.Verify(blsPubKey, voteDataHash[:]) { + return errors.New("verify bls signature failed.") + } + return nil +} diff --git a/core/vm/contracts.go b/core/vm/contracts.go index d0f3a1ba03..3db2bf8477 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -22,16 +22,17 @@ import ( "errors" "math/big" + "github.com/prysmaticlabs/prysm/v3/crypto/bls" + "golang.org/x/crypto/ripemd160" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto/blake2b" "github.com/ethereum/go-ethereum/crypto/bls12381" "github.com/ethereum/go-ethereum/crypto/bn256" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" - - //lint:ignore SA1019 Needed for precompile - "golang.org/x/crypto/ripemd160" ) // PrecompiledContract is the basic interface for native Go contracts. The implementation @@ -140,6 +141,24 @@ var PrecompiledContractsBerlin = map[common.Address]PrecompiledContract{ common.BytesToAddress([]byte{9}): &blake2F{}, } +// PrecompiledContractsBoneh contains the default set of pre-compiled Ethereum +// contracts used in the Boneh release. +var PrecompiledContractsBoneh = map[common.Address]PrecompiledContract{ + common.BytesToAddress([]byte{1}): &ecrecover{}, + common.BytesToAddress([]byte{2}): &sha256hash{}, + common.BytesToAddress([]byte{3}): &ripemd160hash{}, + common.BytesToAddress([]byte{4}): &dataCopy{}, + common.BytesToAddress([]byte{5}): &bigModExp{}, + common.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, + common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, + common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, + common.BytesToAddress([]byte{9}): &blake2F{}, + + common.BytesToAddress([]byte{100}): &tmHeaderValidate{}, + common.BytesToAddress([]byte{101}): &iavlMerkleProofValidatePlanck{}, + common.BytesToAddress([]byte{102}): &blsSignatureVerify{}, +} + // PrecompiledContractsBLS contains the set of pre-compiled Ethereum // contracts specified in EIP-2537. These are exported for testing purposes. var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{ @@ -155,6 +174,7 @@ var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{ } var ( + PrecompiledAddressesBoneh []common.Address PrecompiledAddressesPlanck []common.Address PrecompiledAddressesMoran []common.Address PrecompiledAddressesNano []common.Address @@ -186,11 +206,16 @@ func init() { for k := range PrecompiledContractsPlanck { PrecompiledAddressesPlanck = append(PrecompiledAddressesPlanck, k) } + for k := range PrecompiledContractsBoneh { + PrecompiledAddressesBoneh = append(PrecompiledAddressesBoneh, k) + } } // ActivePrecompiles returns the precompiles enabled with the current configuration. func ActivePrecompiles(rules params.Rules) []common.Address { switch { + case rules.IsBoneh: + return PrecompiledAddressesBoneh case rules.IsPlanck: return PrecompiledAddressesPlanck case rules.IsMoran: @@ -271,6 +296,7 @@ type sha256hash struct{} func (c *sha256hash) RequiredGas(input []byte) uint64 { return uint64(len(input)+31)/32*params.Sha256PerWordGas + params.Sha256BaseGas } + func (c *sha256hash) Run(input []byte) ([]byte, error) { h := sha256.Sum256(input) return h[:], nil @@ -286,6 +312,7 @@ type ripemd160hash struct{} func (c *ripemd160hash) RequiredGas(input []byte) uint64 { return uint64(len(input)+31)/32*params.Ripemd160PerWordGas + params.Ripemd160BaseGas } + func (c *ripemd160hash) Run(input []byte) ([]byte, error) { ripemd := ripemd160.New() ripemd.Write(input) @@ -302,6 +329,7 @@ type dataCopy struct{} func (c *dataCopy) RequiredGas(input []byte) uint64 { return uint64(len(input)+31)/32*params.IdentityPerWordGas + params.IdentityBaseGas } + func (c *dataCopy) Run(in []byte) ([]byte, error) { return in, nil } @@ -402,7 +430,7 @@ func (c *bigModExp) RequiredGas(input []byte) uint64 { // def mult_complexity(x): // ceiling(x/8)^2 // - //where is x is max(length_of_MODULUS, length_of_BASE) + // where is x is max(length_of_MODULUS, length_of_BASE) gas = gas.Add(gas, big7) gas = gas.Div(gas, big8) gas.Mul(gas, gas) @@ -1110,3 +1138,72 @@ func (c *bls12381MapG2) Run(input []byte) ([]byte, error) { // Encode the G2 point to 256 bytes return g.EncodePoint(r), nil } + +// blsSignatureVerify implements bls signature verification precompile. +type blsSignatureVerify struct{} + +const ( + msgHashLength = uint64(32) + signatureLength = uint64(96) + singleBlsPubkeyLength = uint64(48) +) + +// RequiredGas returns the gas required to execute the pre-compiled contract. +func (c *blsSignatureVerify) RequiredGas(input []byte) uint64 { + msgAndSigLength := msgHashLength + signatureLength + inputLen := uint64(len(input)) + if inputLen <= msgAndSigLength || + (inputLen-msgAndSigLength)%singleBlsPubkeyLength != 0 { + return params.BlsSignatureVerifyBaseGas + } + pubKeyNumber := (inputLen - msgAndSigLength) / singleBlsPubkeyLength + return params.BlsSignatureVerifyBaseGas + pubKeyNumber*params.BlsSignatureVerifyPerKeyGas +} + +// Run input: +// msg | signature | [{bls pubkey}] | +// 32 bytes | 96 bytes | [{48 bytes}] | +func (c *blsSignatureVerify) Run(input []byte) ([]byte, error) { + msgAndSigLength := msgHashLength + signatureLength + inputLen := uint64(len(input)) + if inputLen <= msgAndSigLength || + (inputLen-msgAndSigLength)%singleBlsPubkeyLength != 0 { + log.Debug("blsSignatureVerify input size wrong", "inputLen", inputLen) + return nil, ErrExecutionReverted + } + + var msg [32]byte + msgBytes := getData(input, 0, msgHashLength) + copy(msg[:], msgBytes) + + signatureBytes := getData(input, msgHashLength, signatureLength) + sig, err := bls.SignatureFromBytes(signatureBytes) + if err != nil { + log.Debug("blsSignatureVerify invalid signature", "err", err) + return nil, ErrExecutionReverted + } + + pubKeyNumber := (inputLen - msgAndSigLength) / singleBlsPubkeyLength + pubKeys := make([]bls.PublicKey, pubKeyNumber) + for i := uint64(0); i < pubKeyNumber; i++ { + pubKeyBytes := getData(input, msgAndSigLength+i*singleBlsPubkeyLength, singleBlsPubkeyLength) + pubKey, err := bls.PublicKeyFromBytes(pubKeyBytes) + if err != nil { + log.Debug("blsSignatureVerify invalid pubKey", "err", err) + return nil, ErrExecutionReverted + } + pubKeys[i] = pubKey + } + + if pubKeyNumber > 1 { + if !sig.FastAggregateVerify(pubKeys, msg) { + return big0.Bytes(), nil + } + } else { + if !sig.Verify(pubKeys[0], msgBytes) { + return big0.Bytes(), nil + } + } + + return big1.Bytes(), nil +} diff --git a/core/vm/contracts_test.go b/core/vm/contracts_test.go index aa8d2f1eb3..80505d7e72 100644 --- a/core/vm/contracts_test.go +++ b/core/vm/contracts_test.go @@ -65,6 +65,7 @@ var allPrecompiles = map[common.Address]PrecompiledContract{ common.BytesToAddress([]byte{16}): &bls12381Pairing{}, common.BytesToAddress([]byte{17}): &bls12381MapG1{}, common.BytesToAddress([]byte{18}): &bls12381MapG2{}, + common.BytesToAddress([]byte{102}): &blsSignatureVerify{}, } // EIP-152 test vectors @@ -179,7 +180,7 @@ func benchmarkPrecompiled(addr string, test precompiledTest, bench *testing.B) { // Keep it as uint64, multiply 100 to get two digit float later mgasps := (100 * 1000 * gasUsed) / elapsed bench.ReportMetric(float64(mgasps)/100, "mgas/s") - //Check if it is correct + // Check if it is correct if err != nil { bench.Error(err) return @@ -231,6 +232,16 @@ func BenchmarkPrecompiledIdentity(bench *testing.B) { benchmarkPrecompiled("04", t, bench) } +// Benchmarks the sample inputs from the blsSignatureVerify precompile. +func BenchmarkPrecompiledBlsSignatureVerify(bench *testing.B) { + t := precompiledTest{ + Input: "f2d8e8e5bf354429e3ce8b97c4e88f7a0bf7bc917e856de762ed6d70dd8ec2d289a04d63285e4b45309e7c180ea82565e375dd62c7b80d957aea4c9b7e16bdb28a0f910036bd3220fe3d7614fb137a8f0a68b3c564ddd214b5041d8f7a124e6e7285ac42635e75eeb9051a052fb500b1c2bc23bd4290db59fc02be11f2b80896b6e22d5b8dd31ba2e49b13cd6be19fcd01c1e23af3e5165d88d8b9deaf38baa77770fa6a358e2eebdffd1bd8a1eb7386", + Expected: "01", + Name: "", + } + benchmarkPrecompiled("66", t, bench) +} + // Tests the sample inputs from the ModExp EIP 198. func TestPrecompiledModExp(t *testing.T) { testJson("modexp", "05", t) } func BenchmarkPrecompiledModExp(b *testing.B) { benchJson("modexp", "05", b) } diff --git a/core/vm/evm.go b/core/vm/evm.go index eb483fd6de..7ad12a8256 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -52,6 +52,8 @@ type ( func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) { var precompiles map[common.Address]PrecompiledContract switch { + case evm.chainRules.IsBoneh: + precompiles = PrecompiledContractsBoneh case evm.chainRules.IsPlanck: precompiles = PrecompiledContractsPlanck case evm.chainRules.IsMoran: @@ -256,7 +258,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas gas = 0 } // TODO: consider clearing up unused snapshots: - //} else { + // } else { // evm.StateDB.DiscardSnapshot(snapshot) } return ret, gas, err diff --git a/core/vote/vote_journal.go b/core/vote/vote_journal.go new file mode 100644 index 0000000000..3fede24076 --- /dev/null +++ b/core/vote/vote_journal.go @@ -0,0 +1,124 @@ +package vote + +import ( + "encoding/json" + + lru "github.com/hashicorp/golang-lru" + "github.com/tidwall/wal" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" +) + +const ( + maxSizeOfRecentEntry = 512 +) + +type VoteJournal struct { + journalPath string // file path of disk journal for saving the vote. + + walLog *wal.Log + + voteDataBuffer *lru.Cache +} + +var voteJournalError = metrics.NewRegisteredGauge("voteJournal/local", nil) + +func NewVoteJournal(filePath string) (*VoteJournal, error) { + walLog, err := wal.Open(filePath, &wal.Options{ + LogFormat: wal.JSON, + SegmentCacheSize: maxSizeOfRecentEntry, + }) + if err != nil { + log.Error("Failed to open vote journal", "err", err) + return nil, err + } + + voteDataBuffer, err := lru.New(maxSizeOfRecentEntry) + if err != nil { + return nil, err + } + + firstIndex, err := walLog.FirstIndex() + if err != nil { + log.Error("Failed to get first index of votes journal", "err", err) + } + + lastIndex, err := walLog.LastIndex() + if err != nil { + log.Error("Failed to get lastIndex of vote journal", "err", err) + return nil, err + } + + voteJournal := &VoteJournal{ + journalPath: filePath, + walLog: walLog, + } + + // Reload all voteData from journal to lru memory everytime node reboot. + for index := firstIndex; index <= lastIndex; index++ { + if voteEnvelop, err := voteJournal.ReadVote(index); err == nil && voteEnvelop != nil { + voteData := voteEnvelop.Data + voteDataBuffer.Add(voteData.TargetNumber, voteData) + } + } + voteJournal.voteDataBuffer = voteDataBuffer + + return voteJournal, nil +} + +func (journal *VoteJournal) WriteVote(voteMessage *types.VoteEnvelope) error { + walLog := journal.walLog + + vote, err := json.Marshal(voteMessage) + if err != nil { + log.Error("Failed to unmarshal vote", "err", err) + return err + } + + lastIndex, err := walLog.LastIndex() + if err != nil { + log.Error("Failed to get lastIndex of vote journal", "err", err) + return err + } + + lastIndex += 1 + if err = walLog.Write(lastIndex, vote); err != nil { + log.Error("Failed to write vote journal", "err", err) + return err + } + + firstIndex, err := walLog.FirstIndex() + if err != nil { + log.Error("Failed to get first index of votes journal", "err", err) + } + + if lastIndex-firstIndex+1 > maxSizeOfRecentEntry { + if err := walLog.TruncateFront(lastIndex - maxSizeOfRecentEntry + 1); err != nil { + log.Error("Failed to truncate votes journal", "err", err) + } + } + + journal.voteDataBuffer.Add(voteMessage.Data.TargetNumber, voteMessage.Data) + return nil +} + +func (journal *VoteJournal) ReadVote(index uint64) (*types.VoteEnvelope, error) { + voteMessage, err := journal.walLog.Read(index) + if err != nil && err != wal.ErrNotFound { + log.Error("Failed to read votes journal", "err", err) + return nil, err + } + + var vote *types.VoteEnvelope + if voteMessage != nil { + vote = &types.VoteEnvelope{} + if err := json.Unmarshal(voteMessage, vote); err != nil { + log.Error("Failed to read vote from voteJournal", "err", err) + return nil, err + } + } + + return vote, nil +} diff --git a/core/vote/vote_manager.go b/core/vote/vote_manager.go new file mode 100644 index 0000000000..c35245694d --- /dev/null +++ b/core/vote/vote_manager.go @@ -0,0 +1,219 @@ +package vote + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/params" +) + +// VoteManager will handle the vote produced by self. +type VoteManager struct { + mux *event.TypeMux + + chain *core.BlockChain + chainconfig *params.ChainConfig + + chainHeadCh chan core.ChainHeadEvent + chainHeadSub event.Subscription + + pool *VotePool + signer *VoteSigner + journal *VoteJournal + + engine consensus.PoSA +} + +func NewVoteManager(mux *event.TypeMux, chainconfig *params.ChainConfig, chain *core.BlockChain, pool *VotePool, journalPath, blsPasswordPath, blsWalletPath string, engine consensus.PoSA) (*VoteManager, error) { + voteManager := &VoteManager{ + mux: mux, + + chain: chain, + chainconfig: chainconfig, + chainHeadCh: make(chan core.ChainHeadEvent, chainHeadChanSize), + + pool: pool, + engine: engine, + } + + // Create voteSigner. + voteSigner, err := NewVoteSigner(blsPasswordPath, blsWalletPath) + if err != nil { + return nil, err + } + log.Info("Create voteSigner successfully") + voteManager.signer = voteSigner + + // Create voteJournal + voteJournal, err := NewVoteJournal(journalPath) + if err != nil { + return nil, err + } + log.Info("Create voteJournal successfully") + voteManager.journal = voteJournal + + // Subscribe to chain head event. + voteManager.chainHeadSub = voteManager.chain.SubscribeChainHeadEvent(voteManager.chainHeadCh) + + go voteManager.loop() + + return voteManager, nil +} + +func (voteManager *VoteManager) loop() { + log.Debug("vote manager routine loop started") + events := voteManager.mux.Subscribe(downloader.StartEvent{}, downloader.DoneEvent{}, downloader.FailedEvent{}) + defer func() { + log.Debug("vote manager loop defer func occur") + if !events.Closed() { + log.Debug("event not closed, unsubscribed by vote manager loop") + events.Unsubscribe() + } + }() + + dlEventCh := events.Chan() + + startVote := true + for { + select { + case ev := <-dlEventCh: + if ev == nil { + log.Debug("dlEvent is nil, continue") + continue + } + switch ev.Data.(type) { + case downloader.StartEvent: + log.Debug("downloader is in startEvent mode, will not startVote") + startVote = false + case downloader.FailedEvent: + log.Debug("downloader is in FailedEvent mode, set startVote flag as true") + startVote = true + case downloader.DoneEvent: + log.Debug("downloader is in DoneEvent mode, set the startVote flag to true") + startVote = true + } + case cHead := <-voteManager.chainHeadCh: + if !startVote { + log.Debug("startVote flag is false, continue") + continue + } + + if cHead.Block == nil { + log.Debug("cHead.Block is nil, continue") + continue + } + + curHead := cHead.Block.Header() + // Check if cur validator is within the validatorSet at curHead + if !voteManager.engine.IsActiveValidatorAt(voteManager.chain, curHead) { + log.Debug("cur validator is not within the validatorSet at curHead") + continue + } + + // Vote for curBlockHeader block. + vote := &types.VoteData{ + TargetNumber: curHead.Number.Uint64(), + TargetHash: curHead.Hash(), + } + voteMessage := &types.VoteEnvelope{ + Data: vote, + } + + // Put Vote into journal and VotesPool if we are active validator and allow to sign it. + if ok, sourceNumber, sourceHash := voteManager.UnderRules(curHead); ok { + log.Debug("curHead is underRules for voting") + if sourceHash == (common.Hash{}) { + log.Debug("sourceHash is empty") + continue + } + + voteMessage.Data.SourceNumber = sourceNumber + voteMessage.Data.SourceHash = sourceHash + + if err := voteManager.signer.SignVote(voteMessage); err != nil { + log.Error("Failed to sign vote", "err", err) + votesSigningErrorMetric(vote.TargetNumber, vote.TargetHash).Inc(1) + continue + } + if err := voteManager.journal.WriteVote(voteMessage); err != nil { + log.Error("Failed to write vote into journal", "err", err) + voteJournalError.Inc(1) + continue + } + + log.Debug("vote manager produced vote", "votedBlockNumber", voteMessage.Data.TargetNumber, "votedBlockHash", voteMessage.Data.TargetHash, "voteMessageHash", voteMessage.Hash()) + voteManager.pool.PutVote(voteMessage) + votesManagerMetric(vote.TargetNumber, vote.TargetHash).Inc(1) + } + case <-voteManager.chainHeadSub.Err(): + log.Debug("voteManager subscribed chainHead failed") + return + } + } +} + +// UnderRules checks if the produced header under the following rules: +// A validator must not publish two distinct votes for the same height. (Rule 1) +// A validator must not vote within the span of its other votes . (Rule 2) +// Validators always vote for their canonical chain’s latest block. (Rule 3) +func (voteManager *VoteManager) UnderRules(header *types.Header) (bool, uint64, common.Hash) { + sourceNumber, sourceHash, err := voteManager.engine.GetJustifiedNumberAndHash(voteManager.chain, header) + if err != nil { + log.Error("failed to get the highest justified number and hash at cur header", "curHeader's BlockNumber", header.Number, "curHeader's BlockHash", header.Hash()) + return false, 0, common.Hash{} + } + + targetNumber := header.Number.Uint64() + + voteDataBuffer := voteManager.journal.voteDataBuffer + //Rule 1: A validator must not publish two distinct votes for the same height. + if voteDataBuffer.Contains(targetNumber) { + log.Debug("err: A validator must not publish two distinct votes for the same height.") + return false, 0, common.Hash{} + } + + //Rule 2: A validator must not vote within the span of its other votes. + for blockNumber := sourceNumber + 1; blockNumber < targetNumber; blockNumber++ { + if voteDataBuffer.Contains(blockNumber) { + voteData, ok := voteDataBuffer.Get(blockNumber) + if !ok { + log.Error("Failed to get voteData info from LRU cache.") + continue + } + if voteData.(*types.VoteData).SourceNumber > sourceNumber { + log.Debug("error: cur vote is within the span of other votes") + return false, 0, common.Hash{} + } + } + } + for blockNumber := targetNumber + 1; blockNumber <= targetNumber+upperLimitOfVoteBlockNumber; blockNumber++ { + if voteDataBuffer.Contains(blockNumber) { + voteData, ok := voteDataBuffer.Get(blockNumber) + if !ok { + log.Error("Failed to get voteData info from LRU cache.") + continue + } + if voteData.(*types.VoteData).SourceNumber < sourceNumber { + log.Debug("error: other votes are within span of cur vote") + return false, 0, common.Hash{} + } + } + } + + // Rule 3: Validators always vote for their canonical chain’s latest block. + // Since the header subscribed to is the canonical chain, so this rule is satisified by default. + log.Debug("All three rules check passed") + return true, sourceNumber, sourceHash +} + +// Metrics to monitor if voteManager worked in the expetected logic. +func votesManagerMetric(blockNumber uint64, blockHash common.Hash) metrics.Gauge { + return metrics.GetOrRegisterGauge(fmt.Sprintf("voteManager/blockNumber/%d/blockHash/%s", blockNumber, blockHash), nil) +} diff --git a/core/vote/vote_pool.go b/core/vote/vote_pool.go new file mode 100644 index 0000000000..0e12855b6c --- /dev/null +++ b/core/vote/vote_pool.go @@ -0,0 +1,396 @@ +package vote + +import ( + "container/heap" + "sync" + + mapset "github.com/deckarep/golang-set" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/params" +) + +const ( + maxCurVoteAmountPerBlock = 21 + maxFutureVoteAmountPerBlock = 50 + + voteBufferForPut = 256 + // votes in the range (currentBlockNum-256,currentBlockNum+11] will be stored + lowerLimitOfVoteBlockNumber = 256 + upperLimitOfVoteBlockNumber = 11 // refer to fetcher.maxUncleDist + + chainHeadChanSize = 10 // chainHeadChanSize is the size of channel listening to ChainHeadEvent. +) + +var ( + localCurVotesGauge = metrics.NewRegisteredGauge("curVotes/local", nil) + localFutureVotesGauge = metrics.NewRegisteredGauge("futureVotes/local", nil) + + localReceivedVotesGauge = metrics.NewRegisteredGauge("receivedVotes/local", nil) + + localCurVotesPqGauge = metrics.NewRegisteredGauge("curVotesPq/local", nil) + localFutureVotesPqGauge = metrics.NewRegisteredGauge("futureVotesPq/local", nil) +) + +type VoteBox struct { + blockNumber uint64 + voteMessages []*types.VoteEnvelope +} + +type VotePool struct { + chain *core.BlockChain + chainconfig *params.ChainConfig + mu sync.RWMutex + + votesFeed event.Feed + scope event.SubscriptionScope + + receivedVotes mapset.Set + + curVotes map[common.Hash]*VoteBox + futureVotes map[common.Hash]*VoteBox + + curVotesPq *votesPriorityQueue + futureVotesPq *votesPriorityQueue + + chainHeadCh chan core.ChainHeadEvent + chainHeadSub event.Subscription + + votesCh chan *types.VoteEnvelope + + engine consensus.PoSA +} + +type votesPriorityQueue []*types.VoteData + +func NewVotePool(chainconfig *params.ChainConfig, chain *core.BlockChain, engine consensus.PoSA) *VotePool { + votePool := &VotePool{ + chain: chain, + chainconfig: chainconfig, + receivedVotes: mapset.NewSet(), + curVotes: make(map[common.Hash]*VoteBox), + futureVotes: make(map[common.Hash]*VoteBox), + curVotesPq: &votesPriorityQueue{}, + futureVotesPq: &votesPriorityQueue{}, + chainHeadCh: make(chan core.ChainHeadEvent, chainHeadChanSize), + votesCh: make(chan *types.VoteEnvelope, voteBufferForPut), + engine: engine, + } + + // Subscribe events from blockchain and start the main event loop. + votePool.chainHeadSub = votePool.chain.SubscribeChainHeadEvent(votePool.chainHeadCh) + + go votePool.loop() + return votePool +} + +// loop is the vote pool's main even loop, waiting for and reacting to outside blockchain events and votes channel event. +func (pool *VotePool) loop() { + for { + select { + // Handle ChainHeadEvent. + case ev := <-pool.chainHeadCh: + if ev.Block != nil { + latestBlockNumber := ev.Block.NumberU64() + pool.prune(latestBlockNumber) + pool.transferVotesFromFutureToCur(ev.Block.Header()) + } + case <-pool.chainHeadSub.Err(): + return + + // Handle votes channel and put the vote into vote pool. + case vote := <-pool.votesCh: + pool.putIntoVotePool(vote) + } + } +} + +func (pool *VotePool) PutVote(vote *types.VoteEnvelope) { + pool.votesCh <- vote +} + +func (pool *VotePool) putIntoVotePool(vote *types.VoteEnvelope) bool { + targetNumber := vote.Data.TargetNumber + targetHash := vote.Data.TargetHash + header := pool.chain.CurrentBlock().Header() + headNumber := header.Number.Uint64() + + // Make sure in the range (currentHeight-lowerLimitOfVoteBlockNumber, currentHeight+upperLimitOfVoteBlockNumber]. + if targetNumber+lowerLimitOfVoteBlockNumber-1 < headNumber || targetNumber > headNumber+upperLimitOfVoteBlockNumber { + log.Debug("BlockNumber of vote is outside the range of header-256~header+11, will be discarded") + return false + } + + voteData := &types.VoteData{ + TargetNumber: targetNumber, + TargetHash: targetHash, + } + + var votes map[common.Hash]*VoteBox + var votesPq *votesPriorityQueue + isFutureVote := false + + voteBlock := pool.chain.GetHeaderByHash(targetHash) + if voteBlock == nil { + votes = pool.futureVotes + votesPq = pool.futureVotesPq + isFutureVote = true + } else { + votes = pool.curVotes + votesPq = pool.curVotesPq + } + + voteHash := vote.Hash() + if ok := pool.basicVerify(vote, headNumber, votes, isFutureVote, voteHash); !ok { + return false + } + + if !isFutureVote { + // Verify if the vote comes from valid validators based on voteAddress (BLSPublicKey), only verify curVotes here, will verify futureVotes in transfer process. + if pool.engine.VerifyVote(pool.chain, vote) != nil { + return false + } + + // Send vote for handler usage of broadcasting to peers. + voteEv := core.NewVoteEvent{Vote: vote} + pool.votesFeed.Send(voteEv) + } + + pool.putVote(votes, votesPq, vote, voteData, voteHash, isFutureVote) + + return true +} + +func (pool *VotePool) SubscribeNewVoteEvent(ch chan<- core.NewVoteEvent) event.Subscription { + return pool.scope.Track(pool.votesFeed.Subscribe(ch)) +} + +func (pool *VotePool) putVote(m map[common.Hash]*VoteBox, votesPq *votesPriorityQueue, vote *types.VoteEnvelope, voteData *types.VoteData, voteHash common.Hash, isFutureVote bool) { + targetHash := vote.Data.TargetHash + targetNumber := vote.Data.TargetNumber + + log.Debug("The vote info to put is:", "voteBlockNumber", targetNumber, "voteBlockHash", targetHash) + + pool.mu.Lock() + defer pool.mu.Unlock() + if _, ok := m[targetHash]; !ok { + // Push into votes priorityQueue if not exist in corresponding votes Map. + // To be noted: will not put into priorityQueue if exists in map to avoid duplicate element with the same voteData. + heap.Push(votesPq, voteData) + voteBox := &VoteBox{ + blockNumber: targetNumber, + voteMessages: make([]*types.VoteEnvelope, 0, maxFutureVoteAmountPerBlock), + } + m[targetHash] = voteBox + + if isFutureVote { + localFutureVotesPqGauge.Update(int64(votesPq.Len())) + } else { + localCurVotesPqGauge.Update(int64(votesPq.Len())) + } + } + + // Put into corresponding votes map. + m[targetHash].voteMessages = append(m[targetHash].voteMessages, vote) + // Add into received vote to avoid future duplicated vote comes. + pool.receivedVotes.Add(voteHash) + log.Debug("VoteHash put into votepool is:", "voteHash", voteHash) + + if isFutureVote { + localFutureVotesGauge.Inc(1) + } else { + localCurVotesGauge.Inc(1) + } + localReceivedVotesGauge.Update(int64(pool.receivedVotes.Cardinality())) +} + +func (pool *VotePool) transferVotesFromFutureToCur(latestBlockHeader *types.Header) { + pool.mu.Lock() + defer pool.mu.Unlock() + + futurePq := pool.futureVotesPq + latestBlockNumber := latestBlockHeader.Number.Uint64() + + // For vote in the range [,latestBlockNumber-11), transfer to cur if valid. + for futurePq.Len() > 0 && futurePq.Peek().TargetNumber+upperLimitOfVoteBlockNumber < latestBlockNumber { + blockHash := futurePq.Peek().TargetHash + pool.transfer(blockHash) + } + + // For vote in the range [latestBlockNumber-11,latestBlockNumber], only transfer the vote inside the local fork. + futurePqBuffer := make([]*types.VoteData, 0) + for futurePq.Len() > 0 && futurePq.Peek().TargetNumber <= latestBlockNumber { + blockHash := futurePq.Peek().TargetHash + header := pool.chain.GetHeaderByHash(blockHash) + if header == nil { + // Put into pq buffer used for later put again into futurePq + futurePqBuffer = append(futurePqBuffer, heap.Pop(futurePq).(*types.VoteData)) + continue + } + pool.transfer(blockHash) + } + + for _, voteData := range futurePqBuffer { + heap.Push(futurePq, voteData) + } +} + +func (pool *VotePool) transfer(blockHash common.Hash) { + curPq, futurePq := pool.curVotesPq, pool.futureVotesPq + curVotes, futureVotes := pool.curVotes, pool.futureVotes + voteData := heap.Pop(futurePq) + + defer localFutureVotesPqGauge.Update(int64(futurePq.Len())) + + voteBox, ok := futureVotes[blockHash] + if !ok { + return + } + + validVotes := make([]*types.VoteEnvelope, 0, len(voteBox.voteMessages)) + for _, vote := range voteBox.voteMessages { + // Verify if the vote comes from valid validators based on voteAddress (BLSPublicKey). + if pool.engine.VerifyVote(pool.chain, vote) != nil { + continue + } + + // In the process of transfer, send valid vote to votes channel for handler usage + voteEv := core.NewVoteEvent{Vote: vote} + pool.votesFeed.Send(voteEv) + validVotes = append(validVotes, vote) + } + + // may len(curVotes[blockHash].voteMessages) extra maxCurVoteAmountPerBlock, but it doesn't matter + if _, ok := curVotes[blockHash]; !ok { + heap.Push(curPq, voteData) + curVotes[blockHash] = &VoteBox{voteBox.blockNumber, validVotes} + localCurVotesPqGauge.Update(int64(curPq.Len())) + } else { + curVotes[blockHash].voteMessages = append(curVotes[blockHash].voteMessages, validVotes...) + } + + delete(futureVotes, blockHash) + + localCurVotesGauge.Inc(int64(len(validVotes))) + localFutureVotesGauge.Dec(int64(len(voteBox.voteMessages))) +} + +// Prune old data of duplicationSet, curVotePq and curVotesMap. +func (pool *VotePool) prune(latestBlockNumber uint64) { + pool.mu.Lock() + defer pool.mu.Unlock() + curVotes := pool.curVotes + curVotesPq := pool.curVotesPq + + // delete votes in the range [,latestBlockNumber-lowerLimitOfVoteBlockNumber] + for curVotesPq.Len() > 0 && curVotesPq.Peek().TargetNumber+lowerLimitOfVoteBlockNumber-1 < latestBlockNumber { + // Prune curPriorityQueue. + blockHash := heap.Pop(curVotesPq).(*types.VoteData).TargetHash + localCurVotesPqGauge.Update(int64(curVotesPq.Len())) + if voteBox, ok := curVotes[blockHash]; ok { + voteMessages := voteBox.voteMessages + // Prune duplicationSet. + for _, voteMessage := range voteMessages { + voteHash := voteMessage.Hash() + pool.receivedVotes.Remove(voteHash) + } + // Prune curVotes Map. + delete(curVotes, blockHash) + + localCurVotesGauge.Dec(int64(len(voteMessages))) + localReceivedVotesGauge.Update(int64(pool.receivedVotes.Cardinality())) + } + } +} + +// GetVotes as batch. +func (pool *VotePool) GetVotes() []*types.VoteEnvelope { + pool.mu.RLock() + defer pool.mu.RUnlock() + + votesRes := make([]*types.VoteEnvelope, 0) + curVotes := pool.curVotes + for _, voteBox := range curVotes { + votesRes = append(votesRes, voteBox.voteMessages...) + } + return votesRes +} + +func (pool *VotePool) FetchVoteByBlockHash(blockHash common.Hash) []*types.VoteEnvelope { + pool.mu.RLock() + defer pool.mu.RUnlock() + if _, ok := pool.curVotes[blockHash]; ok { + return pool.curVotes[blockHash].voteMessages + } + return nil +} + +func (pool *VotePool) basicVerify(vote *types.VoteEnvelope, headNumber uint64, m map[common.Hash]*VoteBox, isFutureVote bool, voteHash common.Hash) bool { + targetHash := vote.Data.TargetHash + pool.mu.RLock() + defer pool.mu.RUnlock() + + // Check duplicate voteMessage firstly. + if pool.receivedVotes.Contains(voteHash) { + log.Debug("Vote pool already contained the same vote", "voteHash", voteHash) + return false + } + + // To prevent DOS attacks, make sure no more than 21 votes per blockHash if not futureVotes + // and no more than 50 votes per blockHash if futureVotes. + maxVoteAmountPerBlock := maxCurVoteAmountPerBlock + if isFutureVote { + maxVoteAmountPerBlock = maxFutureVoteAmountPerBlock + } + if voteBox, ok := m[targetHash]; ok { + if len(voteBox.voteMessages) >= maxVoteAmountPerBlock { + return false + } + } + + // Verify bls signature. + if err := vote.Verify(); err != nil { + log.Error("Failed to verify voteMessage", "err", err) + return false + } + + return true +} + +func (pq votesPriorityQueue) Less(i, j int) bool { + return pq[i].TargetNumber < pq[j].TargetNumber +} + +func (pq votesPriorityQueue) Len() int { + return len(pq) +} + +func (pq votesPriorityQueue) Swap(i, j int) { + pq[i], pq[j] = pq[j], pq[i] +} + +func (pq *votesPriorityQueue) Push(vote interface{}) { + curVote := vote.(*types.VoteData) + *pq = append(*pq, curVote) +} + +func (pq *votesPriorityQueue) Pop() interface{} { + tmp := *pq + l := len(tmp) + var res interface{} = tmp[l-1] + *pq = tmp[:l-1] + return res +} + +func (pq *votesPriorityQueue) Peek() *types.VoteData { + if pq.Len() == 0 { + return nil + } + return (*pq)[0] +} diff --git a/core/vote/vote_pool_test.go b/core/vote/vote_pool_test.go new file mode 100644 index 0000000000..a1bcd8d232 --- /dev/null +++ b/core/vote/vote_pool_test.go @@ -0,0 +1,446 @@ +// Copyright 2014 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package vote + +import ( + "container/heap" + "context" + "encoding/json" + "fmt" + "io/ioutil" + "math/big" + "os" + "path/filepath" + "testing" + "time" + + "github.com/google/uuid" + "github.com/prysmaticlabs/prysm/v3/crypto/bls" + "github.com/prysmaticlabs/prysm/v3/validator/accounts" + "github.com/prysmaticlabs/prysm/v3/validator/accounts/iface" + "github.com/prysmaticlabs/prysm/v3/validator/keymanager" + keystorev4 "github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/params" +) + +var ( + // testKey is a private key to use for funding a tester account. + testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + + // testAddr is the Ethereum address of the tester account. + testAddr = crypto.PubkeyToAddress(testKey.PublicKey) + + password = "secretPassword" + + timeThreshold = 30 +) + +type mockPOSA struct { + consensus.PoSA +} + +type mockInvalidPOSA struct { + consensus.PoSA +} + +func (p *mockPOSA) GetJustifiedNumberAndHash(chain consensus.ChainHeaderReader, header *types.Header) (uint64, common.Hash, error) { + parentHeader := chain.GetHeaderByHash(header.ParentHash) + if parentHeader == nil { + return 0, common.Hash{}, fmt.Errorf("unexpected error") + } + return parentHeader.Number.Uint64(), parentHeader.Hash(), nil +} + +func (p *mockInvalidPOSA) GetJustifiedNumberAndHash(chain consensus.ChainHeaderReader, header *types.Header) (uint64, common.Hash, error) { + return 0, common.Hash{}, fmt.Errorf("not supported") +} + +func (m *mockPOSA) VerifyVote(chain consensus.ChainHeaderReader, vote *types.VoteEnvelope) error { + return nil +} + +func (m *mockInvalidPOSA) VerifyVote(chain consensus.ChainHeaderReader, vote *types.VoteEnvelope) error { + return nil +} + +func (m *mockPOSA) IsActiveValidatorAt(chain consensus.ChainHeaderReader, header *types.Header) bool { + return true +} + +func (m *mockInvalidPOSA) IsActiveValidatorAt(chain consensus.ChainHeaderReader, header *types.Header) bool { + return true +} + +func (pool *VotePool) verifyStructureSizeOfVotePool(receivedVotes, curVotes, futureVotes, curVotesPq, futureVotesPq int) bool { + for i := 0; i < timeThreshold; i++ { + time.Sleep(1 * time.Second) + if pool.receivedVotes.Cardinality() == receivedVotes && len(pool.curVotes) == curVotes && len(pool.futureVotes) == futureVotes && pool.curVotesPq.Len() == curVotesPq && pool.futureVotesPq.Len() == futureVotesPq { + return true + } + } + return false +} + +func (journal *VoteJournal) verifyJournal(size, lastLatestVoteNumber int) bool { + for i := 0; i < timeThreshold; i++ { + time.Sleep(1 * time.Second) + lastIndex, _ := journal.walLog.LastIndex() + firstIndex, _ := journal.walLog.FirstIndex() + if int(lastIndex)-int(firstIndex)+1 == size { + return true + } + lastVote, _ := journal.ReadVote(lastIndex) + if lastVote != nil && lastVote.Data.TargetNumber == uint64(lastLatestVoteNumber) { + return true + } + } + return false +} + +func TestValidVotePool(t *testing.T) { + testVotePool(t, true) +} + +func TestInvalidVotePool(t *testing.T) { + testVotePool(t, false) +} + +func testVotePool(t *testing.T, isValidRules bool) { + walletPasswordDir, walletDir := setUpKeyManager(t) + + // Create a database pre-initialize with a genesis block + db := rawdb.NewMemoryDatabase() + (&core.Genesis{ + Config: params.TestChainConfig, + Alloc: core.GenesisAlloc{testAddr: {Balance: big.NewInt(1000000)}}, + }).MustCommit(db) + + chain, _ := core.NewBlockChain(db, nil, params.TestChainConfig, ethash.NewFullFaker(), vm.Config{}, nil, nil) + + mux := new(event.TypeMux) + + var mockEngine consensus.PoSA + if isValidRules { + mockEngine = &mockPOSA{} + } else { + mockEngine = &mockInvalidPOSA{} + } + + // Create vote pool + votePool := NewVotePool(params.TestChainConfig, chain, mockEngine) + + // Create vote manager + // Create a temporary file for the votes journal + file, err := ioutil.TempFile("", "") + if err != nil { + t.Fatalf("failed to create temporary file path: %v", err) + } + journal := file.Name() + defer os.Remove(journal) + + // Clean up the temporary file, we only need the path for now + file.Close() + os.Remove(journal) + + voteManager, err := NewVoteManager(mux, params.TestChainConfig, chain, votePool, journal, walletPasswordDir, walletDir, mockEngine) + if err != nil { + t.Fatalf("failed to create vote managers") + } + + voteJournal := voteManager.journal + + // Send the done event of downloader + time.Sleep(10 * time.Millisecond) + mux.Post(downloader.DoneEvent{}) + + bs, _ := core.GenerateChain(params.TestChainConfig, chain.Genesis(), ethash.NewFaker(), db, 1, nil) + if _, err := chain.InsertChain(bs); err != nil { + panic(err) + } + for i := 0; i < 10; i++ { + bs, _ = core.GenerateChain(params.TestChainConfig, bs[len(bs)-1], ethash.NewFaker(), db, 1, nil) + if _, err := chain.InsertChain(bs); err != nil { + panic(err) + } + } + + if !isValidRules { + if votePool.verifyStructureSizeOfVotePool(11, 11, 0, 11, 0) { + t.Fatalf("put vote failed") + } + return + } + + if !votePool.verifyStructureSizeOfVotePool(11, 11, 0, 11, 0) { + t.Fatalf("put vote failed") + } + + // Verify if votesPq is min heap + votesPq := votePool.curVotesPq + pqBuffer := make([]*types.VoteData, 0) + lastVotedBlockNumber := uint64(0) + for votesPq.Len() > 0 { + voteData := heap.Pop(votesPq).(*types.VoteData) + if voteData.TargetNumber < lastVotedBlockNumber { + t.Fatalf("votesPq verification failed") + } + lastVotedBlockNumber = voteData.TargetNumber + pqBuffer = append(pqBuffer, voteData) + } + for _, voteData := range pqBuffer { + heap.Push(votesPq, voteData) + } + + // Verify journal + if !voteJournal.verifyJournal(11, 11) { + t.Fatalf("journal failed") + } + + bs, _ = core.GenerateChain(params.TestChainConfig, bs[len(bs)-1], ethash.NewFaker(), db, 1, nil) + if _, err := chain.InsertChain(bs); err != nil { + panic(err) + } + + if !votePool.verifyStructureSizeOfVotePool(12, 12, 0, 12, 0) { + t.Fatalf("put vote failed") + } + + // Verify journal + if !voteJournal.verifyJournal(12, 12) { + t.Fatalf("journal failed") + } + + for i := 0; i < 256; i++ { + bs, _ = core.GenerateChain(params.TestChainConfig, bs[len(bs)-1], ethash.NewFaker(), db, 1, nil) + if _, err := chain.InsertChain(bs); err != nil { + panic(err) + } + } + + // Verify journal + if !voteJournal.verifyJournal(268, 268) { + t.Fatalf("journal failed") + } + + // currently chain size is 268, and votePool should be pruned, so vote pool size should be 256! + if !votePool.verifyStructureSizeOfVotePool(256, 256, 0, 256, 0) { + t.Fatalf("put vote failed") + } + + // Test invalid vote whose number larger than latestHeader + 13 + invalidVote := &types.VoteEnvelope{ + Data: &types.VoteData{ + TargetNumber: 1000, + }, + } + voteManager.pool.PutVote(invalidVote) + + if !votePool.verifyStructureSizeOfVotePool(256, 256, 0, 256, 0) { + t.Fatalf("put vote failed") + } + + votes := votePool.GetVotes() + if len(votes) != 256 { + t.Fatalf("get votes failed") + } + + // Verify journal + if !voteJournal.verifyJournal(268, 268) { + t.Fatalf("journal failed") + } + + // Test future votes scenario: votes number within latestBlockHeader ~ latestBlockHeader + 13 + futureVote := &types.VoteEnvelope{ + Data: &types.VoteData{ + TargetNumber: 279, + }, + } + if err := voteManager.signer.SignVote(futureVote); err != nil { + t.Fatalf("sign vote failed") + } + voteManager.pool.PutVote(futureVote) + + if !votePool.verifyStructureSizeOfVotePool(257, 256, 1, 256, 1) { + t.Fatalf("put vote failed") + } + + // Verify journal + if !voteJournal.verifyJournal(268, 268) { + t.Fatalf("journal failed") + } + + // Test duplicate vote case, shouldn'd be put into vote pool + duplicateVote := &types.VoteEnvelope{ + Data: &types.VoteData{ + TargetNumber: 279, + }, + } + if err := voteManager.signer.SignVote(duplicateVote); err != nil { + t.Fatalf("sign vote failed") + } + voteManager.pool.PutVote(duplicateVote) + + if !votePool.verifyStructureSizeOfVotePool(257, 256, 1, 256, 1) { + t.Fatalf("put vote failed") + } + + // Verify journal + if !voteJournal.verifyJournal(268, 268) { + t.Fatalf("journal failed") + } + + // Test future votes larger than latestBlockNumber + 13 should be rejected + futureVote = &types.VoteEnvelope{ + Data: &types.VoteData{ + TargetNumber: 282, + TargetHash: common.Hash{}, + }, + } + voteManager.pool.PutVote(futureVote) + if !votePool.verifyStructureSizeOfVotePool(257, 256, 1, 256, 1) { + t.Fatalf("put vote failed") + } + + // Test transfer votes from future to cur, latest block header is #288 after the following generation + // For the above BlockNumber 279, it did not have blockHash, should be assigned as well below. + curNumber := 268 + var futureBlockHash common.Hash + for i := 0; i < 20; i++ { + bs, _ = core.GenerateChain(params.TestChainConfig, bs[len(bs)-1], ethash.NewFaker(), db, 1, nil) + curNumber += 1 + if curNumber == 279 { + futureBlockHash = bs[0].Hash() + futureVotesMap := votePool.futureVotes + voteBox := futureVotesMap[common.Hash{}] + futureVotesMap[futureBlockHash] = voteBox + delete(futureVotesMap, common.Hash{}) + futureVotesPq := votePool.futureVotesPq + futureVotesPq.Peek().TargetHash = futureBlockHash + } + if _, err := chain.InsertChain(bs); err != nil { + panic(err) + } + } + + for i := 0; i < timeThreshold; i++ { + time.Sleep(1 * time.Second) + _, ok := votePool.curVotes[futureBlockHash] + if ok && len(votePool.curVotes[futureBlockHash].voteMessages) == 2 { + break + } + } + if votePool.curVotes[futureBlockHash] == nil || len(votePool.curVotes[futureBlockHash].voteMessages) != 2 { + t.Fatalf("transfer vote failed") + } + + // Pruner will keep the size of votePool as latestBlockHeader-255~latestBlockHeader, then final result should be 256! + if !votePool.verifyStructureSizeOfVotePool(257, 256, 0, 256, 0) { + t.Fatalf("put vote failed") + } + + // Verify journal + if !voteJournal.verifyJournal(288, 288) { + t.Fatalf("journal failed") + } + + for i := 0; i < 224; i++ { + bs, _ = core.GenerateChain(params.TestChainConfig, bs[len(bs)-1], ethash.NewFaker(), db, 1, nil) + if _, err := chain.InsertChain(bs); err != nil { + panic(err) + } + } + + // Verify journal + if !voteJournal.verifyJournal(512, 512) { + t.Fatalf("journal failed") + } + + bs, _ = core.GenerateChain(params.TestChainConfig, bs[len(bs)-1], ethash.NewFaker(), db, 1, nil) + if _, err := chain.InsertChain(bs); err != nil { + panic(err) + } + + // Verify if journal no longer than 512 + if !voteJournal.verifyJournal(512, 513) { + t.Fatalf("journal failed") + } +} + +func setUpKeyManager(t *testing.T) (string, string) { + walletDir := filepath.Join(t.TempDir(), "wallet") + opts := []accounts.Option{} + opts = append(opts, accounts.WithWalletDir(walletDir)) + opts = append(opts, accounts.WithWalletPassword(password)) + opts = append(opts, accounts.WithKeymanagerType(keymanager.Local)) + opts = append(opts, accounts.WithSkipMnemonicConfirm(true)) + acc, err := accounts.NewCLIManager(opts...) + if err != nil { + t.Fatalf("New Accounts CLI Manager failed: %v.", err) + } + walletPasswordDir := filepath.Join(t.TempDir(), "password") + if err := os.MkdirAll(filepath.Dir(walletPasswordDir), 0700); err != nil { + t.Fatalf("failed to create walletPassword dir: %v", err) + } + if err := ioutil.WriteFile(walletPasswordDir, []byte(password), 0600); err != nil { + t.Fatalf("failed to write wallet password dir: %v", err) + } + + w, err := acc.WalletCreate(context.Background()) + if err != nil { + t.Fatalf("failed to create wallet: %v", err) + } + km, _ := w.InitializeKeymanager(context.Background(), iface.InitKeymanagerConfig{ListenForChanges: false}) + k, _ := km.(keymanager.Importer) + secretKey, _ := bls.RandKey() + encryptor := keystorev4.New() + pubKeyBytes := secretKey.PublicKey().Marshal() + cryptoFields, err := encryptor.Encrypt(secretKey.Marshal(), password) + if err != nil { + t.Fatalf("failed: %v", err) + } + + id, _ := uuid.NewRandom() + keystore := &keymanager.Keystore{ + Crypto: cryptoFields, + ID: id.String(), + Pubkey: fmt.Sprintf("%x", pubKeyBytes), + Version: encryptor.Version(), + Name: encryptor.Name(), + } + + encodedFile, _ := json.MarshalIndent(keystore, "", "\t") + keyStoreDir := filepath.Join(t.TempDir(), "keystore") + keystoreFile, _ := os.Create(fmt.Sprintf("%s/keystore-%s.json", keyStoreDir, "publichh")) + keystoreFile.Write(encodedFile) + accounts.ImportAccounts(context.Background(), &accounts.ImportAccountsConfig{ + Importer: k, + Keystores: []*keymanager.Keystore{keystore}, + AccountPassword: password, + }) + return walletPasswordDir, walletDir +} diff --git a/core/vote/vote_signer.go b/core/vote/vote_signer.go new file mode 100644 index 0000000000..1ea7c95f14 --- /dev/null +++ b/core/vote/vote_signer.go @@ -0,0 +1,110 @@ +package vote + +import ( + "context" + "fmt" + "io/ioutil" + "time" + + "github.com/pkg/errors" + + "github.com/prysmaticlabs/prysm/v3/crypto/bls" + validatorpb "github.com/prysmaticlabs/prysm/v3/proto/prysm/v1alpha1/validator-client" + "github.com/prysmaticlabs/prysm/v3/validator/accounts/iface" + "github.com/prysmaticlabs/prysm/v3/validator/accounts/wallet" + "github.com/prysmaticlabs/prysm/v3/validator/keymanager" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" +) + +const ( + voteSignerTimeout = time.Second * 5 +) + +type VoteSigner struct { + km *keymanager.IKeymanager + pubKey [48]byte +} + +func NewVoteSigner(blsPasswordPath, blsWalletPath string) (*VoteSigner, error) { + dirExists, err := wallet.Exists(blsWalletPath) + if err != nil { + log.Error("Check BLS wallet exists", "err", err) + return nil, err + } + if !dirExists { + log.Error("BLS wallet did not exists.") + return nil, fmt.Errorf("BLS wallet did not exists.") + } + + walletPassword, err := ioutil.ReadFile(blsPasswordPath) + if err != nil { + log.Error("Read BLS wallet password", "err", err) + return nil, err + } + log.Info("Read BLS wallet password successfully") + + w, err := wallet.OpenWallet(context.Background(), &wallet.Config{ + WalletDir: blsWalletPath, + WalletPassword: string(walletPassword), + }) + if err != nil { + log.Error("Open BLS wallet failed", "err", err) + return nil, err + } + log.Info("Open BLS wallet successfully") + + km, err := w.InitializeKeymanager(context.Background(), iface.InitKeymanagerConfig{ListenForChanges: false}) + if err != nil { + log.Error("Initialize key manager failed", "err", err) + return nil, err + } + log.Info("Initialized keymanager successfully") + + ctx, cancel := context.WithTimeout(context.Background(), voteSignerTimeout) + defer cancel() + + pubKeys, err := km.FetchValidatingPublicKeys(ctx) + if err != nil { + return nil, errors.Wrap(err, "could not fetch validating public keys") + } + + return &VoteSigner{ + km: &km, + pubKey: pubKeys[0], + }, nil +} + +func (signer *VoteSigner) SignVote(vote *types.VoteEnvelope) error { + // Sign the vote, fetch the first pubKey as validator's bls public key. + pubKey := signer.pubKey + blsPubKey, err := bls.PublicKeyFromBytes(pubKey[:]) + if err != nil { + return errors.Wrap(err, "convert public key from bytes to bls failed") + } + + voteDataHash := vote.Data.Hash() + + ctx, cancel := context.WithTimeout(context.Background(), voteSignerTimeout) + defer cancel() + + signature, err := (*signer.km).Sign(ctx, &validatorpb.SignRequest{ + PublicKey: pubKey[:], + SigningRoot: voteDataHash[:], + }) + if err != nil { + return err + } + + copy(vote.VoteAddress[:], blsPubKey.Marshal()[:]) + copy(vote.Signature[:], signature.Marshal()[:]) + return nil +} + +// Metrics to indicate if there's any failed signing. +func votesSigningErrorMetric(blockNumber uint64, blockHash common.Hash) metrics.Gauge { + return metrics.GetOrRegisterGauge(fmt.Sprintf("voteSigning/blockNumber/%d/blockHash/%s", blockNumber, blockHash), nil) +} diff --git a/docker/Dockerfile b/docker/Dockerfile index b703371707..484a12f45b 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,9 +1,11 @@ FROM golang:1.19-alpine as bsc -RUN apk add --no-cache make gcc musl-dev linux-headers git bash +RUN apk add --no-cache make cmake gcc musl-dev linux-headers git bash build-base libc-dev ADD . /bsc WORKDIR /bsc +ENV CGO_CFLAGS="-O -D__BLST_PORTABLE__" +ENV CGO_CFLAGS_ALLOW="-O -D__BLST_PORTABLE__" RUN make geth RUN mv /bsc/build/bin/geth /usr/local/bin/geth @@ -12,7 +14,7 @@ ENTRYPOINT [ "/usr/local/bin/geth" ] FROM ethereum/solc:0.6.4-alpine as bsc-genesis -RUN apk add --d --no-cache ca-certificates npm nodejs bash alpine-sdk +RUN apk add --no-cache ca-certificates npm nodejs bash alpine-sdk expect RUN git clone https://github.com/binance-chain/bsc-genesis-contract.git /root/genesis \ && cd /root/genesis && npm install diff --git a/docker/Dockerfile.truffle b/docker/Dockerfile.truffle index 28ab9da393..93675241c2 100644 --- a/docker/Dockerfile.truffle +++ b/docker/Dockerfile.truffle @@ -1,6 +1,6 @@ FROM ethereum/solc:0.6.4-alpine -RUN apk add --d --no-cache ca-certificates npm nodejs bash alpine-sdk git +RUN apk add --no-cache ca-certificates npm nodejs bash alpine-sdk git RUN git clone https://github.com/binance-chain/canonical-upgradeable-bep20.git /usr/app/canonical-upgradeable-bep20 diff --git a/eth/api.go b/eth/api.go index f81dfa922b..f7e16b9d61 100644 --- a/eth/api.go +++ b/eth/api.go @@ -282,16 +282,24 @@ func (api *PublicDebugAPI) DumpBlock(blockNr rpc.BlockNumber) (state.Dump, error _, stateDb := api.eth.miner.Pending() return stateDb.RawDump(opts), nil } - var block *types.Block + var header *types.Header if blockNr == rpc.LatestBlockNumber { - block = api.eth.blockchain.CurrentBlock() + header = api.eth.blockchain.CurrentHeader() + } else if blockNr == rpc.FinalizedBlockNumber { + header = api.eth.blockchain.CurrentFinalBlock() + } else if blockNr == rpc.SafeBlockNumber { + header = api.eth.blockchain.CurrentSafeBlock() } else { - block = api.eth.blockchain.GetBlockByNumber(uint64(blockNr)) + block := api.eth.blockchain.GetBlockByNumber(uint64(blockNr)) + if block == nil { + return state.Dump{}, fmt.Errorf("block #%d not found", blockNr) + } + header = block.Header() } - if block == nil { + if header == nil { return state.Dump{}, fmt.Errorf("block #%d not found", blockNr) } - stateDb, err := api.eth.BlockChain().StateAt(block.Root()) + stateDb, err := api.eth.BlockChain().StateAt(header.Root) if err != nil { return state.Dump{}, err } @@ -370,16 +378,24 @@ func (api *PublicDebugAPI) AccountRange(blockNrOrHash rpc.BlockNumberOrHash, sta // the miner and operate on those _, stateDb = api.eth.miner.Pending() } else { - var block *types.Block + var header *types.Header if number == rpc.LatestBlockNumber { - block = api.eth.blockchain.CurrentBlock() + header = api.eth.blockchain.CurrentHeader() + } else if number == rpc.FinalizedBlockNumber { + header = api.eth.blockchain.CurrentFinalBlock() + } else if number == rpc.SafeBlockNumber { + header = api.eth.blockchain.CurrentSafeBlock() } else { - block = api.eth.blockchain.GetBlockByNumber(uint64(number)) + block := api.eth.blockchain.GetBlockByNumber(uint64(number)) + if block == nil { + return state.IteratorDump{}, fmt.Errorf("block #%d not found", number) + } + header = block.Header() } - if block == nil { + if header == nil { return state.IteratorDump{}, fmt.Errorf("block #%d not found", number) } - stateDb, err = api.eth.BlockChain().StateAt(block.Root()) + stateDb, err = api.eth.BlockChain().StateAt(header.Root) if err != nil { return state.IteratorDump{}, err } diff --git a/eth/api_backend.go b/eth/api_backend.go index 7c0f1f0482..dc48c3f073 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -19,6 +19,7 @@ package eth import ( "context" "errors" + "fmt" "math/big" "time" @@ -32,6 +33,7 @@ import ( "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/gasprice" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" @@ -70,7 +72,21 @@ func (b *EthAPIBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumb } // Otherwise resolve and return the block if number == rpc.LatestBlockNumber { - return b.eth.blockchain.CurrentBlock().Header(), nil + return b.eth.blockchain.CurrentHeader(), nil + } + if number == rpc.FinalizedBlockNumber { + block := b.eth.blockchain.CurrentFinalBlock() + if block != nil { + return block, nil + } + return nil, errors.New("finalized block not found") + } + if number == rpc.SafeBlockNumber { + block := b.eth.blockchain.CurrentSafeBlock() + if block != nil { + return block, nil + } + return nil, errors.New("safe block not found") } return b.eth.blockchain.GetHeaderByNumber(uint64(number)), nil } @@ -106,6 +122,20 @@ func (b *EthAPIBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumbe if number == rpc.LatestBlockNumber { return b.eth.blockchain.CurrentBlock(), nil } + if number == rpc.FinalizedBlockNumber { + header := b.eth.blockchain.CurrentFinalBlock() + if header == nil { + return nil, fmt.Errorf("block #%d not found", number) + } + return b.eth.blockchain.GetBlock(header.Hash(), header.Number.Uint64()), nil + } + if number == rpc.SafeBlockNumber { + header := b.eth.blockchain.CurrentSafeBlock() + if header == nil { + return nil, fmt.Errorf("block #%d not found", number) + } + return b.eth.blockchain.GetBlock(header.Hash(), header.Number.Uint64()), nil + } return b.eth.blockchain.GetBlockByNumber(uint64(number)), nil } @@ -227,6 +257,10 @@ func (b *EthAPIBackend) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) e return b.eth.BlockChain().SubscribeChainHeadEvent(ch) } +func (b *EthAPIBackend) SubscribeFinalizedHeaderEvent(ch chan<- core.FinalizedHeaderEvent) event.Subscription { + return b.eth.BlockChain().SubscribeFinalizedHeaderEvent(ch) +} + func (b *EthAPIBackend) SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription { return b.eth.BlockChain().SubscribeChainSideEvent(ch) } @@ -281,6 +315,17 @@ func (b *EthAPIBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.S return b.eth.TxPool().SubscribeNewTxsEvent(ch) } +func (b *EthAPIBackend) SubscribeNewVoteEvent(ch chan<- core.NewVoteEvent) event.Subscription { + if b.eth.VotePool() == nil { + return nil + } + return b.eth.VotePool().SubscribeNewVoteEvent(ch) +} + +func (b *EthAPIBackend) Downloader() *downloader.Downloader { + return b.eth.Downloader() +} + func (b *EthAPIBackend) SyncProgress() ethereum.SyncProgress { return b.eth.Downloader().Progress() } diff --git a/eth/backend.go b/eth/backend.go index fc0ca6534c..25d0f908b3 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -39,10 +39,12 @@ import ( "github.com/ethereum/go-ethereum/core/state/pruner" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/core/vote" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/eth/filters" "github.com/ethereum/go-ethereum/eth/gasprice" + "github.com/ethereum/go-ethereum/eth/protocols/bsc" "github.com/ethereum/go-ethereum/eth/protocols/diff" "github.com/ethereum/go-ethereum/eth/protocols/eth" "github.com/ethereum/go-ethereum/eth/protocols/snap" @@ -77,6 +79,7 @@ type Ethereum struct { ethDialCandidates enode.Iterator snapDialCandidates enode.Iterator trustDialCandidates enode.Iterator + bscDialCandidates enode.Iterator merger *consensus.Merger // DB interfaces @@ -104,6 +107,8 @@ type Ethereum struct { lock sync.RWMutex // Protects the variadic fields (e.g. gas price and etherbase) shutdownTracker *shutdowncheck.ShutdownTracker // Tracks if and when the node has shutdown ungracefully + + votePool *vote.VotePool } // New creates a new Ethereum object (including the @@ -244,6 +249,30 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { } eth.txPool = core.NewTxPool(config.TxPool, chainConfig, eth.blockchain) + conf := stack.Config() + blsPasswordPath := stack.ResolvePath(conf.BLSPasswordFile) + blsWalletPath := stack.ResolvePath(conf.BLSWalletDir) + voteJournalPath := stack.ResolvePath(conf.VoteJournalDir) + + // Create voteManager instance + if posa, ok := eth.engine.(consensus.PoSA); ok { + // Create votePool instance + votePool := vote.NewVotePool(chainConfig, eth.blockchain, posa) + eth.votePool = votePool + if parlia, ok := eth.engine.(*parlia.Parlia); ok { + parlia.VotePool = votePool + } else { + return nil, fmt.Errorf("Engine is not Parlia type") + } + log.Info("Create votePool successfully") + + if _, err := vote.NewVoteManager(eth.EventMux(), chainConfig, eth.blockchain, votePool, voteJournalPath, blsPasswordPath, blsWalletPath, posa); err != nil { + log.Error("Failed to Initialize voteManager", "err", err) + return nil, err + } + log.Info("Create voteManager successfully") + } + // Permit the downloader to use the trie cache allowance during fast sync cacheLimit := cacheConfig.TrieCleanLimit + cacheConfig.TrieDirtyLimit + cacheConfig.SnapshotLimit checkpoint := config.Checkpoint @@ -269,6 +298,9 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { }); err != nil { return nil, err } + if eth.votePool != nil { + eth.handler.votepool = eth.votePool + } eth.miner = miner.New(eth, &config.Miner, chainConfig, eth.EventMux(), eth.engine, eth.isLocalBlock) eth.miner.SetExtra(makeExtraData(config.Miner.ExtraData)) @@ -293,6 +325,10 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { if err != nil { return nil, err } + eth.bscDialCandidates, err = dnsclient.NewIterator(eth.config.BscDiscoveryURLs...) + if err != nil { + return nil, err + } // Start the RPC service eth.netRPCService = ethapi.NewPublicNetAPI(eth.p2pServer, config.NetworkId) @@ -558,6 +594,7 @@ func (s *Ethereum) Miner() *miner.Miner { return s.miner } func (s *Ethereum) AccountManager() *accounts.Manager { return s.accountManager } func (s *Ethereum) BlockChain() *core.BlockChain { return s.blockchain } func (s *Ethereum) TxPool() *core.TxPool { return s.txPool } +func (s *Ethereum) VotePool() *vote.VotePool { return s.votePool } func (s *Ethereum) EventMux() *event.TypeMux { return s.eventMux } func (s *Ethereum) Engine() consensus.Engine { return s.engine } func (s *Ethereum) ChainDb() ethdb.Database { return s.chainDb } @@ -587,6 +624,9 @@ func (s *Ethereum) Protocols() []p2p.Protocol { if s.config.EnableTrustProtocol { protos = append(protos, trust.MakeProtocols((*trustHandler)(s.handler), s.snapDialCandidates)...) } + if !s.config.DisableBscProtocol { + protos = append(protos, bsc.MakeProtocols((*bscHandler)(s.handler), s.bscDialCandidates)...) + } return protos } @@ -621,6 +661,7 @@ func (s *Ethereum) Stop() error { s.ethDialCandidates.Close() s.snapDialCandidates.Close() s.trustDialCandidates.Close() + s.bscDialCandidates.Close() s.handler.Stop() // Then stop everything else. diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index a5ac153afc..70dc7e15b9 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -374,8 +374,8 @@ func (d *Downloader) UnregisterPeer(id string) error { return nil } -// Synchronise tries to sync up our local block chain with a remote peer, both -// adding various sanity checks as well as wrapping it with various log entries. +// Synchronise tries to sync up our local blockchain with a remote peer, both +// adding various sanity checks and wrapping it with various log entries. func (d *Downloader) Synchronise(id string, head common.Hash, td *big.Int, mode SyncMode) error { err := d.synchronise(id, head, td, mode) diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index 8d032260a7..29bb597410 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -144,12 +144,14 @@ type Config struct { EthDiscoveryURLs []string SnapDiscoveryURLs []string TrustDiscoveryURLs []string + BscDiscoveryURLs []string NoPruning bool // Whether to disable pruning and flush everything to disk DirectBroadcast bool DisableSnapProtocol bool //Whether disable snap protocol DisableDiffProtocol bool //Whether disable diff protocol EnableTrustProtocol bool //Whether enable trust protocol + DisableBscProtocol bool //Whether disable bsc protocol DiffSync bool // Whether support diff sync PipeCommit bool RangeLimit bool diff --git a/eth/ethconfig/gen_config.go b/eth/ethconfig/gen_config.go index c0d44ce141..13891c04c9 100644 --- a/eth/ethconfig/gen_config.go +++ b/eth/ethconfig/gen_config.go @@ -18,64 +18,66 @@ import ( // MarshalTOML marshals as TOML. func (c Config) MarshalTOML() (interface{}, error) { type Config struct { - Genesis *core.Genesis `toml:",omitempty"` - NetworkId uint64 - SyncMode downloader.SyncMode - DisablePeerTxBroadcast bool - EthDiscoveryURLs []string - SnapDiscoveryURLs []string - TrustDiscoveryURLs []string - NoPruning bool - NoPrefetch bool - DirectBroadcast bool - DisableSnapProtocol bool - DisableDiffProtocol bool - EnableTrustProtocol bool - DiffSync bool - RangeLimit bool - TxLookupLimit uint64 `toml:",omitempty"` - Whitelist map[uint64]common.Hash `toml:"-"` - LightServ int `toml:",omitempty"` - LightIngress int `toml:",omitempty"` - LightEgress int `toml:",omitempty"` - LightPeers int `toml:",omitempty"` - LightNoPrune bool `toml:",omitempty"` - LightNoSyncServe bool `toml:",omitempty"` - SyncFromCheckpoint bool `toml:",omitempty"` - UltraLightServers []string `toml:",omitempty"` - UltraLightFraction int `toml:",omitempty"` - UltraLightOnlyAnnounce bool `toml:",omitempty"` - SkipBcVersionCheck bool `toml:"-"` - DatabaseHandles int `toml:"-"` - DatabaseCache int - DatabaseFreezer string - DatabaseDiff string - TrieCleanCache int - TrieCleanCacheJournal string `toml:",omitempty"` - TrieCleanCacheRejournal time.Duration `toml:",omitempty"` - TrieDirtyCache int - TrieTimeout time.Duration - SnapshotCache int - TriesInMemory uint64 - TriesVerifyMode core.VerifyMode - Preimages bool - PersistDiff bool - DiffBlock uint64 `toml:",omitempty"` - PruneAncientData bool - Miner miner.Config - Ethash ethash.Config `toml:",omitempty"` - TxPool core.TxPoolConfig - GPO gasprice.Config - EnablePreimageRecording bool - DocRoot string `toml:"-"` - EWASMInterpreter string - EVMInterpreter string - RPCGasCap uint64 - RPCEVMTimeout time.Duration - RPCTxFeeCap float64 - Checkpoint *params.TrustedCheckpoint `toml:",omitempty"` - CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"` - OverrideBerlin *big.Int `toml:",omitempty"` + Genesis *core.Genesis `toml:",omitempty"` + NetworkId uint64 + SyncMode downloader.SyncMode + DisablePeerTxBroadcast bool + EthDiscoveryURLs []string + SnapDiscoveryURLs []string + TrustDiscoveryURLs []string + BscDiscoveryURLs []string + NoPruning bool + NoPrefetch bool + DirectBroadcast bool + DisableSnapProtocol bool + DisableDiffProtocol bool + EnableTrustProtocol bool + DisableBscProtocol bool + DiffSync bool + RangeLimit bool + TxLookupLimit uint64 `toml:",omitempty"` + Whitelist map[uint64]common.Hash `toml:"-"` + LightServ int `toml:",omitempty"` + LightIngress int `toml:",omitempty"` + LightEgress int `toml:",omitempty"` + LightPeers int `toml:",omitempty"` + LightNoPrune bool `toml:",omitempty"` + LightNoSyncServe bool `toml:",omitempty"` + SyncFromCheckpoint bool `toml:",omitempty"` + UltraLightServers []string `toml:",omitempty"` + UltraLightFraction int `toml:",omitempty"` + UltraLightOnlyAnnounce bool `toml:",omitempty"` + SkipBcVersionCheck bool `toml:"-"` + DatabaseHandles int `toml:"-"` + DatabaseCache int + DatabaseFreezer string + DatabaseDiff string + TrieCleanCache int + TrieCleanCacheJournal string `toml:",omitempty"` + TrieCleanCacheRejournal time.Duration `toml:",omitempty"` + TrieDirtyCache int + TrieTimeout time.Duration + SnapshotCache int + TriesInMemory uint64 + TriesVerifyMode core.VerifyMode + Preimages bool + PersistDiff bool + DiffBlock uint64 `toml:",omitempty"` + PruneAncientData bool + Miner miner.Config + Ethash ethash.Config `toml:",omitempty"` + TxPool core.TxPoolConfig + GPO gasprice.Config + EnablePreimageRecording bool + DocRoot string `toml:"-"` + EWASMInterpreter string + EVMInterpreter string + RPCGasCap uint64 + RPCEVMTimeout time.Duration + RPCTxFeeCap float64 + Checkpoint *params.TrustedCheckpoint `toml:",omitempty"` + CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"` + OverrideBerlin *big.Int `toml:",omitempty"` OverrideArrowGlacier *big.Int `toml:",omitempty"` OverrideTerminalTotalDifficulty *big.Int `toml:",omitempty"` } @@ -87,11 +89,13 @@ func (c Config) MarshalTOML() (interface{}, error) { enc.EthDiscoveryURLs = c.EthDiscoveryURLs enc.SnapDiscoveryURLs = c.SnapDiscoveryURLs enc.TrustDiscoveryURLs = c.TrustDiscoveryURLs + enc.BscDiscoveryURLs = c.BscDiscoveryURLs enc.NoPruning = c.NoPruning enc.DirectBroadcast = c.DirectBroadcast enc.DisableSnapProtocol = c.DisableSnapProtocol enc.DisableDiffProtocol = c.DisableDiffProtocol enc.EnableTrustProtocol = c.EnableTrustProtocol + enc.DisableBscProtocol = c.DisableBscProtocol enc.DiffSync = c.DiffSync enc.RangeLimit = c.RangeLimit enc.TxLookupLimit = c.TxLookupLimit @@ -145,64 +149,66 @@ func (c Config) MarshalTOML() (interface{}, error) { // UnmarshalTOML unmarshals from TOML. func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { type Config struct { - Genesis *core.Genesis `toml:",omitempty"` - NetworkId *uint64 - SyncMode *downloader.SyncMode - DisablePeerTxBroadcast *bool - EthDiscoveryURLs []string - SnapDiscoveryURLs []string - TrustDiscoveryURLs []string - NoPruning *bool - NoPrefetch *bool - DirectBroadcast *bool - DisableSnapProtocol *bool - DisableDiffProtocol *bool - EnableTrustProtocol *bool - DiffSync *bool - RangeLimit *bool - TxLookupLimit *uint64 `toml:",omitempty"` - Whitelist map[uint64]common.Hash `toml:"-"` - LightServ *int `toml:",omitempty"` - LightIngress *int `toml:",omitempty"` - LightEgress *int `toml:",omitempty"` - LightPeers *int `toml:",omitempty"` - LightNoPrune *bool `toml:",omitempty"` - LightNoSyncServe *bool `toml:",omitempty"` - SyncFromCheckpoint *bool `toml:",omitempty"` - UltraLightServers []string `toml:",omitempty"` - UltraLightFraction *int `toml:",omitempty"` - UltraLightOnlyAnnounce *bool `toml:",omitempty"` - SkipBcVersionCheck *bool `toml:"-"` - DatabaseHandles *int `toml:"-"` - DatabaseCache *int - DatabaseFreezer *string - DatabaseDiff *string - PersistDiff *bool - DiffBlock *uint64 `toml:",omitempty"` - PruneAncientData *bool - TrieCleanCache *int - TrieCleanCacheJournal *string `toml:",omitempty"` - TrieCleanCacheRejournal *time.Duration `toml:",omitempty"` - TrieDirtyCache *int - TrieTimeout *time.Duration - SnapshotCache *int - TriesInMemory *uint64 - TriesVerifyMode *core.VerifyMode - Preimages *bool - Miner *miner.Config - Ethash *ethash.Config `toml:",omitempty"` - TxPool *core.TxPoolConfig - GPO *gasprice.Config - EnablePreimageRecording *bool - DocRoot *string `toml:"-"` - EWASMInterpreter *string - EVMInterpreter *string - RPCGasCap *uint64 + Genesis *core.Genesis `toml:",omitempty"` + NetworkId *uint64 + SyncMode *downloader.SyncMode + DisablePeerTxBroadcast *bool + EthDiscoveryURLs []string + SnapDiscoveryURLs []string + TrustDiscoveryURLs []string + BscDiscoveryURLs []string + NoPruning *bool + NoPrefetch *bool + DirectBroadcast *bool + DisableSnapProtocol *bool + DisableDiffProtocol *bool + EnableTrustProtocol *bool + DisableBscProtocol *bool + DiffSync *bool + RangeLimit *bool + TxLookupLimit *uint64 `toml:",omitempty"` + Whitelist map[uint64]common.Hash `toml:"-"` + LightServ *int `toml:",omitempty"` + LightIngress *int `toml:",omitempty"` + LightEgress *int `toml:",omitempty"` + LightPeers *int `toml:",omitempty"` + LightNoPrune *bool `toml:",omitempty"` + LightNoSyncServe *bool `toml:",omitempty"` + SyncFromCheckpoint *bool `toml:",omitempty"` + UltraLightServers []string `toml:",omitempty"` + UltraLightFraction *int `toml:",omitempty"` + UltraLightOnlyAnnounce *bool `toml:",omitempty"` + SkipBcVersionCheck *bool `toml:"-"` + DatabaseHandles *int `toml:"-"` + DatabaseCache *int + DatabaseFreezer *string + DatabaseDiff *string + PersistDiff *bool + DiffBlock *uint64 `toml:",omitempty"` + PruneAncientData *bool + TrieCleanCache *int + TrieCleanCacheJournal *string `toml:",omitempty"` + TrieCleanCacheRejournal *time.Duration `toml:",omitempty"` + TrieDirtyCache *int + TrieTimeout *time.Duration + SnapshotCache *int + TriesInMemory *uint64 + TriesVerifyMode *core.VerifyMode + Preimages *bool + Miner *miner.Config + Ethash *ethash.Config `toml:",omitempty"` + TxPool *core.TxPoolConfig + GPO *gasprice.Config + EnablePreimageRecording *bool + DocRoot *string `toml:"-"` + EWASMInterpreter *string + EVMInterpreter *string + RPCGasCap *uint64 RPCEVMTimeout *time.Duration - RPCTxFeeCap *float64 - Checkpoint *params.TrustedCheckpoint `toml:",omitempty"` - CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"` - OverrideBerlin *big.Int `toml:",omitempty"` + RPCTxFeeCap *float64 + Checkpoint *params.TrustedCheckpoint `toml:",omitempty"` + CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"` + OverrideBerlin *big.Int `toml:",omitempty"` OverrideArrowGlacier *big.Int `toml:",omitempty"` OverrideTerminalTotalDifficulty *big.Int `toml:",omitempty"` } @@ -231,6 +237,9 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.TrustDiscoveryURLs != nil { c.TrustDiscoveryURLs = dec.TrustDiscoveryURLs } + if dec.BscDiscoveryURLs != nil { + c.BscDiscoveryURLs = dec.BscDiscoveryURLs + } if dec.NoPruning != nil { c.NoPruning = *dec.NoPruning } @@ -246,6 +255,9 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.EnableTrustProtocol != nil { c.EnableTrustProtocol = *dec.EnableTrustProtocol } + if dec.DisableBscProtocol != nil { + c.DisableBscProtocol = *dec.DisableBscProtocol + } if dec.DiffSync != nil { c.DiffSync = *dec.DiffSync } diff --git a/eth/fetcher/tx_fetcher.go b/eth/fetcher/tx_fetcher.go index 6cdb5b8804..20eaada986 100644 --- a/eth/fetcher/tx_fetcher.go +++ b/eth/fetcher/tx_fetcher.go @@ -261,7 +261,7 @@ func (f *TxFetcher) Notify(peer string, hashes []common.Hash) error { // Enqueue imports a batch of received transaction into the transaction pool // and the fetcher. This method may be called by both transaction broadcasts and // direct request replies. The differentiation is important so the fetcher can -// re-shedule missing transactions as soon as possible. +// re-schedule missing transactions as soon as possible. func (f *TxFetcher) Enqueue(peer string, txs []*types.Transaction, direct bool) error { // Keep track of all the propagated transactions if direct { diff --git a/eth/filters/api.go b/eth/filters/api.go index 56ee044274..0cacd2cf39 100644 --- a/eth/filters/api.go +++ b/eth/filters/api.go @@ -171,6 +171,68 @@ func (api *PublicFilterAPI) NewPendingTransactions(ctx context.Context) (*rpc.Su return rpcSub, nil } +// NewVotesFilter creates a filter that fetches votes that entered the vote pool. +// It is part of the filter package since polling goes with eth_getFilterChanges. +func (api *PublicFilterAPI) NewVotesFilter() rpc.ID { + var ( + votes = make(chan *types.VoteEnvelope) + voteSub = api.events.SubscribeNewVotes(votes) + ) + api.filtersMu.Lock() + api.filters[voteSub.ID] = &filter{typ: VotesSubscription, deadline: time.NewTimer(api.timeout), hashes: make([]common.Hash, 0), s: voteSub} + api.filtersMu.Unlock() + + gopool.Submit(func() { + for { + select { + case vote := <-votes: + api.filtersMu.Lock() + if f, found := api.filters[voteSub.ID]; found { + f.hashes = append(f.hashes, vote.Hash()) + } + api.filtersMu.Unlock() + case <-voteSub.Err(): + api.filtersMu.Lock() + delete(api.filters, voteSub.ID) + api.filtersMu.Unlock() + return + } + } + }) + + return voteSub.ID +} + +// NewVotes creates a subscription that is triggered each time a vote enters the vote pool. +func (api *PublicFilterAPI) NewVotes(ctx context.Context) (*rpc.Subscription, error) { + notifier, supported := rpc.NotifierFromContext(ctx) + if !supported { + return &rpc.Subscription{}, rpc.ErrNotificationsUnsupported + } + + rpcSub := notifier.CreateSubscription() + + gopool.Submit(func() { + votes := make(chan *types.VoteEnvelope, 128) + voteSub := api.events.SubscribeNewVotes(votes) + + for { + select { + case vote := <-votes: + notifier.Notify(rpcSub.ID, vote) + case <-rpcSub.Err(): + voteSub.Unsubscribe() + return + case <-notifier.Closed(): + voteSub.Unsubscribe() + return + } + } + }) + + return rpcSub, nil +} + // NewBlockFilter creates a filter that fetches blocks that are imported into the chain. // It is part of the filter package since polling goes with eth_getFilterChanges. // @@ -236,6 +298,68 @@ func (api *PublicFilterAPI) NewHeads(ctx context.Context) (*rpc.Subscription, er return rpcSub, nil } +// NewFinalizedHeaderFilter creates a filter that fetches finalized headers that are reached. +func (api *PublicFilterAPI) NewFinalizedHeaderFilter() rpc.ID { + var ( + headers = make(chan *types.Header) + headerSub = api.events.SubscribeNewFinalizedHeaders(headers) + ) + + api.filtersMu.Lock() + api.filters[headerSub.ID] = &filter{typ: FinalizedHeadersSubscription, deadline: time.NewTimer(api.timeout), hashes: make([]common.Hash, 0), s: headerSub} + api.filtersMu.Unlock() + + gopool.Submit(func() { + for { + select { + case h := <-headers: + api.filtersMu.Lock() + if f, found := api.filters[headerSub.ID]; found { + f.hashes = append(f.hashes, h.Hash()) + } + api.filtersMu.Unlock() + case <-headerSub.Err(): + api.filtersMu.Lock() + delete(api.filters, headerSub.ID) + api.filtersMu.Unlock() + return + } + } + }) + + return headerSub.ID +} + +// NewFinalizedHeaders send a notification each time a new finalized header is reached. +func (api *PublicFilterAPI) NewFinalizedHeaders(ctx context.Context) (*rpc.Subscription, error) { + notifier, supported := rpc.NotifierFromContext(ctx) + if !supported { + return &rpc.Subscription{}, rpc.ErrNotificationsUnsupported + } + + rpcSub := notifier.CreateSubscription() + + gopool.Submit(func() { + headers := make(chan *types.Header) + headersSub := api.events.SubscribeNewFinalizedHeaders(headers) + + for { + select { + case h := <-headers: + notifier.Notify(rpcSub.ID, h) + case <-rpcSub.Err(): + headersSub.Unsubscribe() + return + case <-notifier.Closed(): + headersSub.Unsubscribe() + return + } + } + }) + + return rpcSub, nil +} + // Logs creates a subscription that fires for all new log that match the given filter criteria. func (api *PublicFilterAPI) Logs(ctx context.Context, crit FilterCriteria) (*rpc.Subscription, error) { notifier, supported := rpc.NotifierFromContext(ctx) @@ -427,7 +551,7 @@ func (api *PublicFilterAPI) GetFilterChanges(id rpc.ID) (interface{}, error) { f.deadline.Reset(api.timeout) switch f.typ { - case PendingTransactionsSubscription, BlocksSubscription: + case PendingTransactionsSubscription, BlocksSubscription, VotesSubscription: hashes := f.hashes f.hashes = nil return returnHashes(hashes), nil diff --git a/eth/filters/filter.go b/eth/filters/filter.go index 2762993dad..40668cb2ee 100644 --- a/eth/filters/filter.go +++ b/eth/filters/filter.go @@ -19,7 +19,6 @@ package filters import ( "context" "errors" - "fmt" "math/big" "github.com/ethereum/go-ethereum/common" @@ -43,9 +42,11 @@ type Backend interface { SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription + SubscribeFinalizedHeaderEvent(ch chan<- core.FinalizedHeaderEvent) event.Subscription SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription + SubscribeNewVoteEvent(chan<- core.NewVoteEvent) event.Subscription BloomStatus() (uint64, uint64) ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) @@ -148,23 +149,44 @@ func (f *Filter) Logs(ctx context.Context) ([]*types.Log, error) { return nil, nil } var ( - head = header.Number.Uint64() - end = uint64(f.end) + err error + head = header.Number.Int64() pending = f.end == rpc.PendingBlockNumber.Int64() ) - if f.begin == rpc.LatestBlockNumber.Int64() { - f.begin = int64(head) + resolveSpecial := func(number int64) (int64, error) { + var hdr *types.Header + switch number { + case rpc.LatestBlockNumber.Int64(): + return head, nil + case rpc.PendingBlockNumber.Int64(): + // we should return head here since we've already captured + // that we need to get the pending logs in the pending boolean above + return head, nil + case rpc.FinalizedBlockNumber.Int64(): + hdr, _ = f.backend.HeaderByNumber(ctx, rpc.FinalizedBlockNumber) + if hdr == nil { + return 0, errors.New("finalized header not found") + } + case rpc.SafeBlockNumber.Int64(): + hdr, _ = f.backend.HeaderByNumber(ctx, rpc.SafeBlockNumber) + if hdr == nil { + return 0, errors.New("safe header not found") + } + default: + return number, nil + } + return hdr.Number.Int64(), nil } - if f.end == rpc.LatestBlockNumber.Int64() || f.end == rpc.PendingBlockNumber.Int64() { - end = head + if f.begin, err = resolveSpecial(f.begin); err != nil { + return nil, err } - if f.rangeLimit && (int64(end)-f.begin) > maxFilterBlockRange { - return nil, fmt.Errorf("exceed maximum block range: %d", maxFilterBlockRange) + if f.end, err = resolveSpecial(f.end); err != nil { + return nil, err } // Gather all indexed logs, and finish with non indexed ones var ( logs []*types.Log - err error + end = uint64(f.end) size, sections = f.backend.BloomStatus() ) if indexed := sections * size; indexed > uint64(f.begin) { diff --git a/eth/filters/filter_system.go b/eth/filters/filter_system.go index 12f037d0f9..bf461a1c5c 100644 --- a/eth/filters/filter_system.go +++ b/eth/filters/filter_system.go @@ -52,7 +52,11 @@ const ( PendingTransactionsSubscription // BlocksSubscription queries hashes for blocks that are imported BlocksSubscription - // LastSubscription keeps track of the last index + // VotesSubscription queries vote hashes for votes entering the vote pool + VotesSubscription + // FinalizedHeadersSubscription queries hashes for finalized headers that are reached + FinalizedHeadersSubscription + // LastIndexSubscription keeps track of the last index LastIndexSubscription ) @@ -66,18 +70,25 @@ const ( logsChanSize = 10 // chainEvChanSize is the size of channel listening to ChainEvent. chainEvChanSize = 10 + // finalizedHeaderEvChanSize is the size of channel listening to FinalizedHeaderEvent. + finalizedHeaderEvChanSize = 10 + // voteChanSize is the size of channel listening to NewVoteEvent. + // The number is referenced from the size of vote pool. + voteChanSize = 256 ) type subscription struct { - id rpc.ID - typ Type - created time.Time - logsCrit ethereum.FilterQuery - logs chan []*types.Log - hashes chan []common.Hash - headers chan *types.Header - installed chan struct{} // closed when the filter is installed - err chan error // closed when the filter is uninstalled + id rpc.ID + typ Type + created time.Time + logsCrit ethereum.FilterQuery + logs chan []*types.Log + hashes chan []common.Hash + headers chan *types.Header + finalizedHeaders chan *types.Header + votes chan *types.VoteEnvelope + installed chan struct{} // closed when the filter is installed + err chan error // closed when the filter is uninstalled } // EventSystem creates subscriptions, processes events and broadcasts them to the @@ -88,20 +99,24 @@ type EventSystem struct { lastHead *types.Header // Subscriptions - txsSub event.Subscription // Subscription for new transaction event - logsSub event.Subscription // Subscription for new log event - rmLogsSub event.Subscription // Subscription for removed log event - pendingLogsSub event.Subscription // Subscription for pending log event - chainSub event.Subscription // Subscription for new chain event + txsSub event.Subscription // Subscription for new transaction event + logsSub event.Subscription // Subscription for new log event + rmLogsSub event.Subscription // Subscription for removed log event + pendingLogsSub event.Subscription // Subscription for pending log event + chainSub event.Subscription // Subscription for new chain event + finalizedHeaderSub event.Subscription // Subscription for new finalized header + voteSub event.Subscription // Subscription for new vote event // Channels - install chan *subscription // install filter for event notification - uninstall chan *subscription // remove filter for event notification - txsCh chan core.NewTxsEvent // Channel to receive new transactions event - logsCh chan []*types.Log // Channel to receive new log event - pendingLogsCh chan []*types.Log // Channel to receive new log event - rmLogsCh chan core.RemovedLogsEvent // Channel to receive removed log event - chainCh chan core.ChainEvent // Channel to receive new chain event + install chan *subscription // install filter for event notification + uninstall chan *subscription // remove filter for event notification + txsCh chan core.NewTxsEvent // Channel to receive new transactions event + logsCh chan []*types.Log // Channel to receive new log event + pendingLogsCh chan []*types.Log // Channel to receive new log event + rmLogsCh chan core.RemovedLogsEvent // Channel to receive removed log event + chainCh chan core.ChainEvent // Channel to receive new chain event + finalizedHeaderCh chan core.FinalizedHeaderEvent // Channel to receive new finalized header event + voteCh chan core.NewVoteEvent // Channel to receive new vote event } // NewEventSystem creates a new manager that listens for event on the given mux, @@ -112,15 +127,17 @@ type EventSystem struct { // or by stopping the given mux. func NewEventSystem(backend Backend, lightMode bool) *EventSystem { m := &EventSystem{ - backend: backend, - lightMode: lightMode, - install: make(chan *subscription), - uninstall: make(chan *subscription), - txsCh: make(chan core.NewTxsEvent, txChanSize), - logsCh: make(chan []*types.Log, logsChanSize), - rmLogsCh: make(chan core.RemovedLogsEvent, rmLogsChanSize), - pendingLogsCh: make(chan []*types.Log, logsChanSize), - chainCh: make(chan core.ChainEvent, chainEvChanSize), + backend: backend, + lightMode: lightMode, + install: make(chan *subscription), + uninstall: make(chan *subscription), + txsCh: make(chan core.NewTxsEvent, txChanSize), + logsCh: make(chan []*types.Log, logsChanSize), + rmLogsCh: make(chan core.RemovedLogsEvent, rmLogsChanSize), + pendingLogsCh: make(chan []*types.Log, logsChanSize), + chainCh: make(chan core.ChainEvent, chainEvChanSize), + finalizedHeaderCh: make(chan core.FinalizedHeaderEvent, finalizedHeaderEvChanSize), + voteCh: make(chan core.NewVoteEvent, voteChanSize), } // Subscribe events @@ -129,11 +146,16 @@ func NewEventSystem(backend Backend, lightMode bool) *EventSystem { m.rmLogsSub = m.backend.SubscribeRemovedLogsEvent(m.rmLogsCh) m.chainSub = m.backend.SubscribeChainEvent(m.chainCh) m.pendingLogsSub = m.backend.SubscribePendingLogsEvent(m.pendingLogsCh) + m.finalizedHeaderSub = m.backend.SubscribeFinalizedHeaderEvent(m.finalizedHeaderCh) + m.voteSub = m.backend.SubscribeNewVoteEvent(m.voteCh) // Make sure none of the subscriptions are empty if m.txsSub == nil || m.logsSub == nil || m.rmLogsSub == nil || m.chainSub == nil || m.pendingLogsSub == nil { log.Crit("Subscribe for event system failed") } + if m.voteSub == nil || m.finalizedHeaderSub == nil { + log.Warn("Subscribe for vote or finalized header event failed") + } go m.eventLoop() return m @@ -167,6 +189,7 @@ func (sub *Subscription) Unsubscribe() { case <-sub.f.logs: case <-sub.f.hashes: case <-sub.f.headers: + case <-sub.f.votes: } } @@ -234,6 +257,7 @@ func (es *EventSystem) subscribeMinedPendingLogs(crit ethereum.FilterQuery, logs logs: logs, hashes: make(chan []common.Hash), headers: make(chan *types.Header), + votes: make(chan *types.VoteEnvelope), installed: make(chan struct{}), err: make(chan error), } @@ -251,6 +275,7 @@ func (es *EventSystem) subscribeLogs(crit ethereum.FilterQuery, logs chan []*typ logs: logs, hashes: make(chan []common.Hash), headers: make(chan *types.Header), + votes: make(chan *types.VoteEnvelope), installed: make(chan struct{}), err: make(chan error), } @@ -268,6 +293,7 @@ func (es *EventSystem) subscribePendingLogs(crit ethereum.FilterQuery, logs chan logs: logs, hashes: make(chan []common.Hash), headers: make(chan *types.Header), + votes: make(chan *types.VoteEnvelope), installed: make(chan struct{}), err: make(chan error), } @@ -284,6 +310,24 @@ func (es *EventSystem) SubscribeNewHeads(headers chan *types.Header) *Subscripti logs: make(chan []*types.Log), hashes: make(chan []common.Hash), headers: headers, + votes: make(chan *types.VoteEnvelope), + installed: make(chan struct{}), + err: make(chan error), + } + return es.subscribe(sub) +} + +// SubscribeNewFinalizedHeaders creates a subscription that writes the finalized header of a block that is +// reached recently. +func (es *EventSystem) SubscribeNewFinalizedHeaders(headers chan *types.Header) *Subscription { + sub := &subscription{ + id: rpc.NewID(), + typ: FinalizedHeadersSubscription, + created: time.Now(), + logs: make(chan []*types.Log), + hashes: make(chan []common.Hash), + headers: headers, + votes: make(chan *types.VoteEnvelope), installed: make(chan struct{}), err: make(chan error), } @@ -300,6 +344,24 @@ func (es *EventSystem) SubscribePendingTxs(hashes chan []common.Hash) *Subscript logs: make(chan []*types.Log), hashes: hashes, headers: make(chan *types.Header), + votes: make(chan *types.VoteEnvelope), + installed: make(chan struct{}), + err: make(chan error), + } + return es.subscribe(sub) +} + +// SubscribeNewVotes creates a subscription that writes transaction hashes for +// transactions that enter the transaction pool. +func (es *EventSystem) SubscribeNewVotes(votes chan *types.VoteEnvelope) *Subscription { + sub := &subscription{ + id: rpc.NewID(), + typ: VotesSubscription, + created: time.Now(), + logs: make(chan []*types.Log), + hashes: make(chan []common.Hash), + headers: make(chan *types.Header), + votes: votes, installed: make(chan struct{}), err: make(chan error), } @@ -351,6 +413,12 @@ func (es *EventSystem) handleTxsEvent(filters filterIndex, ev core.NewTxsEvent) } } +func (es *EventSystem) handleVoteEvent(filters filterIndex, ev core.NewVoteEvent) { + for _, f := range filters[VotesSubscription] { + f.votes <- ev.Vote + } +} + func (es *EventSystem) handleChainEvent(filters filterIndex, ev core.ChainEvent) { for _, f := range filters[BlocksSubscription] { f.headers <- ev.Block.Header() @@ -366,6 +434,12 @@ func (es *EventSystem) handleChainEvent(filters filterIndex, ev core.ChainEvent) } } +func (es *EventSystem) handleFinalizedHeaderEvent(filters filterIndex, ev core.FinalizedHeaderEvent) { + for _, f := range filters[FinalizedHeadersSubscription] { + f.headers <- ev.Header + } +} + func (es *EventSystem) lightFilterNewHead(newHeader *types.Header, callBack func(*types.Header, bool)) { oldh := es.lastHead es.lastHead = newHeader @@ -448,6 +522,10 @@ func (es *EventSystem) eventLoop() { es.rmLogsSub.Unsubscribe() es.pendingLogsSub.Unsubscribe() es.chainSub.Unsubscribe() + es.finalizedHeaderSub.Unsubscribe() + if es.voteSub != nil { + es.voteSub.Unsubscribe() + } }() index := make(filterIndex) @@ -455,6 +533,10 @@ func (es *EventSystem) eventLoop() { index[i] = make(map[rpc.ID]*subscription) } + var voteSubErr <-chan error + if es.voteSub != nil { + voteSubErr = es.voteSub.Err() + } for { select { case ev := <-es.txsCh: @@ -467,6 +549,10 @@ func (es *EventSystem) eventLoop() { es.handlePendingLogs(index, ev) case ev := <-es.chainCh: es.handleChainEvent(index, ev) + case ev := <-es.finalizedHeaderCh: + es.handleFinalizedHeaderEvent(index, ev) + case ev := <-es.voteCh: + es.handleVoteEvent(index, ev) case f := <-es.install: if f.typ == MinedAndPendingLogsSubscription { @@ -497,6 +583,10 @@ func (es *EventSystem) eventLoop() { return case <-es.chainSub.Err(): return + case <-es.finalizedHeaderSub.Err(): + return + case <-voteSubErr: + return } } } diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go index 7435a19e86..737eaa17c7 100644 --- a/eth/filters/filter_system_test.go +++ b/eth/filters/filter_system_test.go @@ -18,6 +18,7 @@ package filters import ( "context" + "errors" "fmt" "math/big" "math/rand" @@ -44,14 +45,16 @@ var ( ) type testBackend struct { - mux *event.TypeMux - db ethdb.Database - sections uint64 - txFeed event.Feed - logsFeed event.Feed - rmLogsFeed event.Feed - pendingLogsFeed event.Feed - chainFeed event.Feed + mux *event.TypeMux + db ethdb.Database + sections uint64 + txFeed event.Feed + logsFeed event.Feed + rmLogsFeed event.Feed + pendingLogsFeed event.Feed + chainFeed event.Feed + finalizedHeaderFeed event.Feed + voteFeed event.Feed } func (b *testBackend) ChainDb() ethdb.Database { @@ -63,14 +66,19 @@ func (b *testBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumbe hash common.Hash num uint64 ) - if blockNr == rpc.LatestBlockNumber { + switch blockNr { + case rpc.LatestBlockNumber: hash = rawdb.ReadHeadBlockHash(b.db) number := rawdb.ReadHeaderNumber(b.db, hash) if number == nil { return nil, nil } num = *number - } else { + case rpc.FinalizedBlockNumber: + return nil, errors.New("finalized block not found") + case rpc.SafeBlockNumber: + return nil, errors.New("safe block not found") + default: num = uint64(blockNr) hash = rawdb.ReadCanonicalHash(b.db, num) } @@ -130,6 +138,14 @@ func (b *testBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subsc return b.chainFeed.Subscribe(ch) } +func (b *testBackend) SubscribeFinalizedHeaderEvent(ch chan<- core.FinalizedHeaderEvent) event.Subscription { + return b.finalizedHeaderFeed.Subscribe(ch) +} + +func (b *testBackend) SubscribeNewVoteEvent(ch chan<- core.NewVoteEvent) event.Subscription { + return b.voteFeed.Subscribe(ch) +} + func (b *testBackend) BloomStatus() (uint64, uint64) { return params.BloomBitsBlocks, b.sections } @@ -735,3 +751,79 @@ func flattenLogs(pl [][]*types.Log) []*types.Log { } return logs } + +func TestVoteSubscription(t *testing.T) { + t.Parallel() + + var ( + db = rawdb.NewMemoryDatabase() + backend = &testBackend{db: db} + api = NewPublicFilterAPI(backend, false, deadline, false) + votes = []*types.VoteEnvelope{ + &types.VoteEnvelope{ + VoteAddress: types.BLSPublicKey{}, + Signature: types.BLSSignature{}, + Data: &types.VoteData{ + SourceNumber: uint64(0), + SourceHash: common.BytesToHash(common.Hex2Bytes(string(rune(0)))), + TargetNumber: uint64(1), + TargetHash: common.BytesToHash(common.Hex2Bytes(string(rune(1)))), + }, + }, + &types.VoteEnvelope{ + VoteAddress: types.BLSPublicKey{}, + Signature: types.BLSSignature{}, + Data: &types.VoteData{ + SourceNumber: uint64(0), + SourceHash: common.BytesToHash(common.Hex2Bytes(string(rune(0)))), + TargetNumber: uint64(2), + TargetHash: common.BytesToHash(common.Hex2Bytes(string(rune(2)))), + }, + }, + &types.VoteEnvelope{ + VoteAddress: types.BLSPublicKey{}, + Signature: types.BLSSignature{}, + Data: &types.VoteData{ + SourceNumber: uint64(0), + SourceHash: common.BytesToHash(common.Hex2Bytes(string(rune(0)))), + TargetNumber: uint64(3), + TargetHash: common.BytesToHash(common.Hex2Bytes(string(rune(3)))), + }, + }, + &types.VoteEnvelope{ + VoteAddress: types.BLSPublicKey{}, + Signature: types.BLSSignature{}, + Data: &types.VoteData{ + SourceNumber: uint64(0), + SourceHash: common.BytesToHash(common.Hex2Bytes(string(rune(0)))), + TargetNumber: uint64(4), + TargetHash: common.BytesToHash(common.Hex2Bytes(string(rune(4)))), + }, + }, + } + ) + + chan0 := make(chan *types.VoteEnvelope) + sub0 := api.events.SubscribeNewVotes(chan0) + + go func() { // simulate client + i := 0 + for i != len(votes) { + vote := <-chan0 + if votes[i].Hash() != vote.Hash() { + t.Errorf("sub received invalid hash on index %d, want %x, got %x", i, votes[i].Hash(), vote.Hash()) + } + i++ + } + + sub0.Unsubscribe() + }() + + time.Sleep(1 * time.Second) + for _, v := range votes { + ev := core.NewVoteEvent{Vote: v} + backend.voteFeed.Send(ev) + } + + <-sub0.Err() +} diff --git a/eth/gasprice/feehistory.go b/eth/gasprice/feehistory.go index 78bade5ae8..ae7d0069a1 100644 --- a/eth/gasprice/feehistory.go +++ b/eth/gasprice/feehistory.go @@ -137,44 +137,68 @@ func (oracle *Oracle) processBlock(bf *blockFees, percentiles []float64) { // also returned if requested and available. // Note: an error is only returned if retrieving the head header has failed. If there are no // retrievable blocks in the specified range then zero block count is returned with no error. -func (oracle *Oracle) resolveBlockRange(ctx context.Context, lastBlock rpc.BlockNumber, blocks int) (*types.Block, []*types.Receipt, uint64, int, error) { +func (oracle *Oracle) resolveBlockRange(ctx context.Context, reqEnd rpc.BlockNumber, blocks int) (*types.Block, []*types.Receipt, uint64, int, error) { var ( - headBlock rpc.BlockNumber + headBlock *types.Header pendingBlock *types.Block pendingReceipts types.Receipts + err error ) - // query either pending block or head header and set headBlock - if lastBlock == rpc.PendingBlockNumber { - if pendingBlock, pendingReceipts = oracle.backend.PendingBlockAndReceipts(); pendingBlock != nil { - lastBlock = rpc.BlockNumber(pendingBlock.NumberU64()) - headBlock = lastBlock - 1 - } else { - // pending block not supported by backend, process until latest block - lastBlock = rpc.LatestBlockNumber - blocks-- - if blocks == 0 { - return nil, nil, 0, 0, nil + + // Get the chain's current head. + if headBlock, err = oracle.backend.HeaderByNumber(ctx, rpc.LatestBlockNumber); err != nil { + return nil, nil, 0, 0, err + } + head := rpc.BlockNumber(headBlock.Number.Uint64()) + + // Fail if request block is beyond the chain's current head. + if head < reqEnd { + return nil, nil, 0, 0, fmt.Errorf("%w: requested %d, head %d", errRequestBeyondHead, reqEnd, head) + } + + // Resolve block tag. + if reqEnd < 0 { + var ( + resolved *types.Header + err error + ) + switch reqEnd { + case rpc.PendingBlockNumber: + if pendingBlock, pendingReceipts = oracle.backend.PendingBlockAndReceipts(); pendingBlock != nil { + resolved = pendingBlock.Header() + } else { + // Pending block not supported by backend, process only until latest block. + resolved = headBlock + + // Update total blocks to return to account for this. + blocks-- } + case rpc.LatestBlockNumber: + // Retrieved above. + resolved = headBlock + case rpc.SafeBlockNumber: + resolved, err = oracle.backend.HeaderByNumber(ctx, rpc.SafeBlockNumber) + case rpc.FinalizedBlockNumber: + resolved, err = oracle.backend.HeaderByNumber(ctx, rpc.FinalizedBlockNumber) + case rpc.EarliestBlockNumber: + resolved, err = oracle.backend.HeaderByNumber(ctx, rpc.EarliestBlockNumber) } - } - if pendingBlock == nil { - // if pending block is not fetched then we retrieve the head header to get the head block number - if latestHeader, err := oracle.backend.HeaderByNumber(ctx, rpc.LatestBlockNumber); err == nil && latestHeader != nil { - headBlock = rpc.BlockNumber(latestHeader.Number.Uint64()) - } else { + if resolved == nil || err != nil { return nil, nil, 0, 0, err } + // Absolute number resolved. + reqEnd = rpc.BlockNumber(resolved.Number.Uint64()) } - if lastBlock == rpc.LatestBlockNumber { - lastBlock = headBlock - } else if pendingBlock == nil && lastBlock > headBlock { - return nil, nil, 0, 0, fmt.Errorf("%w: requested %d, head %d", errRequestBeyondHead, lastBlock, headBlock) + + // If there are no blocks to return, short circuit. + if blocks == 0 { + return nil, nil, 0, 0, nil } - // ensure not trying to retrieve before genesis - if rpc.BlockNumber(blocks) > lastBlock+1 { - blocks = int(lastBlock + 1) + // Ensure not trying to retrieve before genesis. + if uint64(reqEnd+1) < uint64(blocks) { + blocks = int(reqEnd + 1) } - return pendingBlock, pendingReceipts, uint64(lastBlock), blocks, nil + return pendingBlock, pendingReceipts, uint64(reqEnd), blocks, nil } // FeeHistory returns data relevant for fee estimation based on the specified range of blocks. diff --git a/eth/gasprice/feehistory_test.go b/eth/gasprice/feehistory_test.go index c259eb0acf..25a685effc 100644 --- a/eth/gasprice/feehistory_test.go +++ b/eth/gasprice/feehistory_test.go @@ -50,6 +50,8 @@ func TestFeeHistory(t *testing.T) { {false, 1000, 1000, 2, rpc.PendingBlockNumber, nil, 32, 1, nil}, {true, 1000, 1000, 2, rpc.PendingBlockNumber, nil, 32, 2, nil}, {true, 1000, 1000, 2, rpc.PendingBlockNumber, []float64{0, 10}, 32, 2, nil}, + // {false, 1000, 1000, 2, rpc.FinalizedBlockNumber, []float64{0, 10}, 24, 2, nil}, + // {false, 1000, 1000, 2, rpc.SafeBlockNumber, []float64{0, 10}, 24, 2, nil}, } for i, c := range cases { config := Config{ diff --git a/eth/gasprice/gasprice_test.go b/eth/gasprice/gasprice_test.go index 01edde38ce..a6f0f53643 100644 --- a/eth/gasprice/gasprice_test.go +++ b/eth/gasprice/gasprice_test.go @@ -18,6 +18,7 @@ package gasprice import ( "context" + "errors" "math" "math/big" "testing" @@ -45,6 +46,15 @@ func (b *testBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber if number > testHead { return nil, nil } + if number == rpc.EarliestBlockNumber { + number = 0 + } + if number == rpc.FinalizedBlockNumber { + return b.chain.CurrentFinalBlock(), nil + } + if number == rpc.SafeBlockNumber { + return b.chain.CurrentSafeBlock(), nil + } if number == rpc.LatestBlockNumber { number = testHead } @@ -62,6 +72,23 @@ func (b *testBackend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) if number > testHead { return nil, nil } + if number == rpc.EarliestBlockNumber { + number = 0 + } + if number == rpc.FinalizedBlockNumber { + header := b.chain.CurrentFinalBlock() + if header == nil { + return nil, errors.New("finalized block not found") + } + number = rpc.BlockNumber(header.Number.Uint64()) + } + if number == rpc.SafeBlockNumber { + header := b.chain.CurrentSafeBlock() + if header == nil { + return nil, errors.New("safe block not found") + } + number = rpc.BlockNumber(header.Number.Uint64()) + } if number == rpc.LatestBlockNumber { number = testHead } @@ -109,6 +136,8 @@ func newTestBackend(t *testing.T, londonBlock *big.Int, pending bool) *testBacke config.LondonBlock = londonBlock config.ArrowGlacierBlock = londonBlock config.GibbsBlock = nil + config.BonehBlock = nil + config.LynnBlock = nil engine := ethash.NewFaker() db := rawdb.NewMemoryDatabase() genesis, err := gspec.Commit(db) diff --git a/eth/handler.go b/eth/handler.go index 19de9ad872..92e2b78f10 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -33,6 +33,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/fetcher" + "github.com/ethereum/go-ethereum/eth/protocols/bsc" "github.com/ethereum/go-ethereum/eth/protocols/diff" "github.com/ethereum/go-ethereum/eth/protocols/eth" "github.com/ethereum/go-ethereum/eth/protocols/snap" @@ -49,6 +50,12 @@ const ( // txChanSize is the size of channel listening to NewTxsEvent. // The number is referenced from the size of tx pool. txChanSize = 4096 + + // voteChanSize is the size of channel listening to NewVotesEvent. + voteChanSize = 256 + + // deltaTdThreshold is the threshold of TD difference for peers to broadcast votes. + deltaTdThreshold = 20 ) var ( @@ -82,12 +89,24 @@ type txPool interface { SubscribeReannoTxsEvent(chan<- core.ReannoTxsEvent) event.Subscription } +// votePool defines the methods needed from a votes pool implementation to +// support all the operations needed by the Ethereum chain protocols. +type votePool interface { + PutVote(vote *types.VoteEnvelope) + GetVotes() []*types.VoteEnvelope + + // SubscribeNewVoteEvent should return an event subscription of + // NewVotesEvent and send events to the given channel. + SubscribeNewVoteEvent(ch chan<- core.NewVoteEvent) event.Subscription +} + // handlerConfig is the collection of initialization parameters to create a full // node network handler. type handlerConfig struct { - Database ethdb.Database // Database for direct sync insertions - Chain *core.BlockChain // Blockchain to serve data from - TxPool txPool // Transaction pool to propagate from + Database ethdb.Database // Database for direct sync insertions + Chain *core.BlockChain // Blockchain to serve data from + TxPool txPool // Transaction pool to propagate from + VotePool votePool Merger *consensus.Merger // The manager for eth1/2 transition Network uint64 // Network identifier to adfvertise Sync downloader.SyncMode // Whether to snap or full sync @@ -116,6 +135,7 @@ type handler struct { database ethdb.Database txpool txPool + votepool votePool chain *core.BlockChain maxPeers int @@ -131,6 +151,8 @@ type handler struct { reannoTxsCh chan core.ReannoTxsEvent reannoTxsSub event.Subscription minedBlockSub *event.TypeMuxSubscription + voteCh chan core.NewVoteEvent + votesSub event.Subscription whitelist map[uint64]common.Hash @@ -158,6 +180,7 @@ func newHandler(config *handlerConfig) (*handler, error) { eventMux: config.EventMux, database: config.Database, txpool: config.TxPool, + votepool: config.VotePool, chain: config.Chain, peers: config.PeerSet, merger: config.Merger, @@ -306,7 +329,7 @@ func newHandler(config *handlerConfig) (*handler, error) { } // runEthPeer registers an eth peer into the joint eth/snap peerset, adds it to -// various subsistems and starts handling messages. +// various subsystems and starts handling messages. func (h *handler) runEthPeer(peer *eth.Peer, handler eth.Handler) error { // If the peer has a `snap` extension, wait for it to connect so we can have // a uniform initialization/teardown mechanism @@ -325,6 +348,11 @@ func (h *handler) runEthPeer(peer *eth.Peer, handler eth.Handler) error { peer.Log().Error("Trust extension barrier failed", "err", err) return err } + bsc, err := h.peers.waitBscExtension(peer) + if err != nil { + peer.Log().Error("Bsc extension barrier failed", "err", err) + return err + } // TODO(karalabe): Not sure why this is needed if !h.chainSync.handlePeerEvent(peer) { return p2p.DiscQuitting @@ -365,7 +393,7 @@ func (h *handler) runEthPeer(peer *eth.Peer, handler eth.Handler) error { peer.Log().Debug("Ethereum peer connected", "name", peer.Name()) // Register the peer locally - if err := h.peers.registerPeer(peer, snap, diff, trust); err != nil { + if err := h.peers.registerPeer(peer, snap, diff, trust, bsc); err != nil { peer.Log().Error("Ethereum peer registration failed", "err", err) return err } @@ -388,9 +416,12 @@ func (h *handler) runEthPeer(peer *eth.Peer, handler eth.Handler) error { } h.chainSync.handlePeerEvent(peer) - // Propagate existing transactions. new transactions appearing + // Propagate existing transactions and votes. new transactions and votes appearing // after this will be sent via broadcasts. h.syncTransactions(peer) + if h.votepool != nil && p.bscExt != nil { + h.syncVotes(p.bscExt) + } // Create a notification channel for pending requests if the peer goes down dead := make(chan struct{}) @@ -540,6 +571,21 @@ func (h *handler) runTrustExtension(peer *trust.Peer, handler trust.Handler) err return handler(peer) } +// runBscExtension registers a `bsc` peer into the joint eth/bsc peerset and +// starts handling inbound messages. As `bsc` is only a satellite protocol to +// `eth`, all subsystem registrations and lifecycle management will be done by +// the main `eth` handler to prevent strange races. +func (h *handler) runBscExtension(peer *bsc.Peer, handler bsc.Handler) error { + h.peerWG.Add(1) + defer h.peerWG.Done() + + if err := h.peers.registerBscExtension(peer); err != nil { + peer.Log().Error("Bsc extension registration failed", "err", err) + return err + } + return handler(peer) +} + // removePeer requests disconnection of a peer. func (h *handler) removePeer(id string) { peer := h.peers.peer(id) @@ -589,6 +635,14 @@ func (h *handler) Start(maxPeers int) { h.txsSub = h.txpool.SubscribeNewTxsEvent(h.txsCh) go h.txBroadcastLoop() + // broadcast votes + if h.votepool != nil { + h.wg.Add(1) + h.voteCh = make(chan core.NewVoteEvent, voteChanSize) + h.votesSub = h.votepool.SubscribeNewVoteEvent(h.voteCh) + go h.voteBroadcastLoop() + } + // announce local pending transactions again h.wg.Add(1) h.reannoTxsCh = make(chan core.ReannoTxsEvent, txChanSize) @@ -609,6 +663,9 @@ func (h *handler) Stop() { h.txsSub.Unsubscribe() // quits txBroadcastLoop h.reannoTxsSub.Unsubscribe() // quits txReannounceLoop h.minedBlockSub.Unsubscribe() // quits blockBroadcastLoop + if h.votepool != nil { + h.votesSub.Unsubscribe() // quits voteBroadcastLoop + } // Quit chainSync and txsync64. // After this is done, no new peers will be accepted. @@ -671,7 +728,7 @@ func (h *handler) BroadcastBlock(block *types.Block, propagate bool) { log.Trace("Propagated block", "hash", hash, "recipients", len(transfer), "duration", common.PrettyDuration(time.Since(block.ReceivedAt))) return } - // Otherwise if the block is indeed in out own chain, announce it + // Otherwise if the block is indeed in our own chain, announce it if h.chain.HasBlock(hash, block.NumberU64()) { for _, peer := range peers { peer.AsyncSendNewBlockHash(block) @@ -741,6 +798,37 @@ func (h *handler) ReannounceTransactions(txs types.Transactions) { "announce packs", peersCount, "announced hashes", peersCount*uint(len(hashes))) } +// BroadcastVote will propagate a batch of votes to all peers +// which are not known to already have the given vote. +func (h *handler) BroadcastVote(vote *types.VoteEnvelope) { + var ( + directCount int // Count of announcements made + directPeers int + + voteMap = make(map[*ethPeer]*types.VoteEnvelope) // Set peer->hash to transfer directly + ) + + // Broadcast vote to a batch of peers not knowing about it + peers := h.peers.peersWithoutVote(vote.Hash()) + headBlock := h.chain.CurrentBlock() + currentTD := h.chain.GetTd(headBlock.Hash(), headBlock.NumberU64()) + for _, peer := range peers { + _, peerTD := peer.Head() + deltaTD := new(big.Int).Abs(new(big.Int).Sub(currentTD, peerTD)) + if deltaTD.Cmp(big.NewInt(deltaTdThreshold)) < 1 && peer.bscExt != nil { + voteMap[peer] = vote + } + } + + for peer, _vote := range voteMap { + directPeers++ + directCount += 1 + votes := []*types.VoteEnvelope{_vote} + peer.bscExt.AsyncSendVotes(votes) + } + log.Debug("Vote broadcast", "vote packs", directPeers, "broadcast vote", directCount) +} + // minedBroadcastLoop sends mined blocks to connected peers. func (h *handler) minedBroadcastLoop() { defer h.wg.Done() @@ -778,3 +866,16 @@ func (h *handler) txReannounceLoop() { } } } + +// voteBroadcastLoop announces new vote to connected peers. +func (h *handler) voteBroadcastLoop() { + defer h.wg.Done() + for { + select { + case event := <-h.voteCh: + h.BroadcastVote(event.Vote) + case <-h.votesSub.Err(): + return + } + } +} diff --git a/eth/handler_bsc.go b/eth/handler_bsc.go new file mode 100644 index 0000000000..59943aadab --- /dev/null +++ b/eth/handler_bsc.go @@ -0,0 +1,68 @@ +package eth + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth/protocols/bsc" + "github.com/ethereum/go-ethereum/p2p/enode" +) + +// bscHandler implements the bsc.Backend interface to handle the various network +// packets that are sent as broadcasts. +type bscHandler handler + +func (h *bscHandler) Chain() *core.BlockChain { return h.chain } + +// RunPeer is invoked when a peer joins on the `bsc` protocol. +func (h *bscHandler) RunPeer(peer *bsc.Peer, hand bsc.Handler) error { + if err := peer.Handshake(); err != nil { + // ensure that waitBscExtension receives the exit signal normally + // otherwise, can't graceful shutdown + ps := h.peers + id := peer.ID() + + // Ensure nobody can double connect + ps.lock.Lock() + if wait, ok := ps.bscWait[id]; ok { + delete(ps.bscWait, id) + wait <- peer + } + ps.lock.Unlock() + return err + } + return (*handler)(h).runBscExtension(peer, hand) +} + +// PeerInfo retrieves all known `bsc` information about a peer. +func (h *bscHandler) PeerInfo(id enode.ID) interface{} { + if p := h.peers.peer(id.String()); p != nil && p.bscExt != nil { + return p.bscExt.info() + } + return nil +} + +// Handle is invoked from a peer's message handler when it receives a new remote +// message that the handler couldn't consume and serve itself. +func (h *bscHandler) Handle(peer *bsc.Peer, packet bsc.Packet) error { + // DeliverSnapPacket is invoked from a peer's message handler when it transmits a + // data packet for the local node to consume. + switch packet := packet.(type) { + case *bsc.VotesPacket: + return h.handleVotesBroadcast(peer, packet.Votes) + + default: + return fmt.Errorf("unexpected bsc packet type: %T", packet) + } +} + +// handleVotesBroadcast is invoked from a peer's message handler when it transmits a +// votes broadcast for the local node to process. +func (h *bscHandler) handleVotesBroadcast(peer *bsc.Peer, votes []*types.VoteEnvelope) error { + // Try to put votes into votepool + for _, vote := range votes { + h.votepool.PutVote(vote) + } + return nil +} diff --git a/eth/handler_bsc_test.go b/eth/handler_bsc_test.go new file mode 100644 index 0000000000..932826a886 --- /dev/null +++ b/eth/handler_bsc_test.go @@ -0,0 +1,276 @@ +package eth + +import ( + "fmt" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/forkid" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth/protocols/bsc" + "github.com/ethereum/go-ethereum/eth/protocols/eth" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/enode" +) + +type testBscHandler struct { + voteBroadcasts event.Feed +} + +func (h *testBscHandler) Chain() *core.BlockChain { panic("no backing chain") } +func (h *testBscHandler) RunPeer(peer *bsc.Peer, handler bsc.Handler) error { + panic("not used in tests") +} +func (h *testBscHandler) PeerInfo(enode.ID) interface{} { panic("not used in tests") } +func (h *testBscHandler) Handle(peer *bsc.Peer, packet bsc.Packet) error { + switch packet := packet.(type) { + case *bsc.VotesPacket: + h.voteBroadcasts.Send(packet.Votes) + return nil + + default: + panic(fmt.Sprintf("unexpected bsc packet type in tests: %T", packet)) + } +} + +func TestSendVotes67(t *testing.T) { testSendVotes(t, eth.ETH67) } + +func testSendVotes(t *testing.T, protocol uint) { + t.Parallel() + + // Create a message handler and fill the pool with big votes + handler := newTestHandler() + defer handler.close() + + insert := make([]*types.VoteEnvelope, 100) + for index := range insert { + vote := types.VoteEnvelope{ + VoteAddress: types.BLSPublicKey{}, + Signature: types.BLSSignature{}, + Data: &types.VoteData{ + SourceNumber: uint64(0), + SourceHash: common.BytesToHash(common.Hex2Bytes(string(rune(0)))), + TargetNumber: uint64(index), + TargetHash: common.BytesToHash(common.Hex2Bytes(string(rune(index)))), + }, + } + insert[index] = &vote + go handler.votepool.PutVote(&vote) + } + time.Sleep(250 * time.Millisecond) // Wait until vote events get out of the system (can't use events, vote broadcaster races with peer join) + + protos := []p2p.Protocol{ + { + Name: "eth", + Version: eth.ETH66, + }, + { + Name: "eth", + Version: eth.ETH67, + }, + { + Name: "bsc", + Version: bsc.Bsc1, + }, + } + caps := []p2p.Cap{ + { + Name: "eth", + Version: eth.ETH66, + }, + { + Name: "eth", + Version: eth.ETH67, + }, + { + Name: "bsc", + Version: bsc.Bsc1, + }, + } + + // Create a source handler to send messages through and a sink peer to receive them + p2pEthSrc, p2pEthSink := p2p.MsgPipe() + defer p2pEthSrc.Close() + defer p2pEthSink.Close() + + localEth := eth.NewPeer(protocol, p2p.NewPeerWithProtocols(enode.ID{1}, protos, "", caps), p2pEthSrc, nil) + remoteEth := eth.NewPeer(protocol, p2p.NewPeerWithProtocols(enode.ID{2}, protos, "", caps), p2pEthSink, nil) + defer localEth.Close() + defer remoteEth.Close() + + p2pBscSrc, p2pBscSink := p2p.MsgPipe() + defer p2pBscSrc.Close() + defer p2pBscSink.Close() + + localBsc := bsc.NewPeer(bsc.Bsc1, p2p.NewPeerWithProtocols(enode.ID{1}, protos, "", caps), p2pBscSrc) + remoteBsc := bsc.NewPeer(bsc.Bsc1, p2p.NewPeerWithProtocols(enode.ID{3}, protos, "", caps), p2pBscSink) + defer localBsc.Close() + defer remoteBsc.Close() + + go func(p *bsc.Peer) { + (*bscHandler)(handler.handler).RunPeer(p, func(peer *bsc.Peer) error { + return bsc.Handle((*bscHandler)(handler.handler), peer) + }) + }(localBsc) + + time.Sleep(200 * time.Millisecond) + remoteBsc.Handshake() + + time.Sleep(200 * time.Millisecond) + go func(p *eth.Peer) { + handler.handler.runEthPeer(p, func(peer *eth.Peer) error { + return eth.Handle((*ethHandler)(handler.handler), peer) + }) + }(localEth) + + // Run the handshake locally to avoid spinning up a source handler + var ( + genesis = handler.chain.Genesis() + head = handler.chain.CurrentBlock() + td = handler.chain.GetTd(head.Hash(), head.NumberU64()) + ) + time.Sleep(200 * time.Millisecond) + if err := remoteEth.Handshake(1, td, head.Hash(), genesis.Hash(), forkid.NewIDWithChain(handler.chain), forkid.NewFilter(handler.chain), nil); err != nil { + t.Fatalf("failed to run protocol handshake: %d", err) + } + // After the handshake completes, the source handler should stream the sink + // the votes, subscribe to all inbound network events + backend := new(testBscHandler) + bcasts := make(chan []*types.VoteEnvelope) + bcastSub := backend.voteBroadcasts.Subscribe(bcasts) + defer bcastSub.Unsubscribe() + + go bsc.Handle(backend, remoteBsc) + + // Make sure we get all the votes on the correct channels + seen := make(map[common.Hash]struct{}) + for len(seen) < len(insert) { + votes := <-bcasts + for _, vote := range votes { + if _, ok := seen[vote.Hash()]; ok { + t.Errorf("duplicate vote broadcast: %x", vote.Hash()) + } + seen[vote.Hash()] = struct{}{} + } + } + for _, vote := range insert { + if _, ok := seen[vote.Hash()]; !ok { + t.Errorf("missing vote: %x", vote.Hash()) + } + } + +} + +func TestRecvVotes67(t *testing.T) { testRecvVotes(t, eth.ETH67) } + +func testRecvVotes(t *testing.T, protocol uint) { + t.Parallel() + + // Create a message handler and fill the pool with big votes + handler := newTestHandler() + defer handler.close() + + protos := []p2p.Protocol{ + { + Name: "eth", + Version: eth.ETH66, + }, + { + Name: "eth", + Version: eth.ETH67, + }, + { + Name: "bsc", + Version: bsc.Bsc1, + }, + } + caps := []p2p.Cap{ + { + Name: "eth", + Version: eth.ETH66, + }, + { + Name: "eth", + Version: eth.ETH67, + }, + { + Name: "bsc", + Version: bsc.Bsc1, + }, + } + + // Create a source handler to send messages through and a sink peer to receive them + p2pEthSrc, p2pEthSink := p2p.MsgPipe() + defer p2pEthSrc.Close() + defer p2pEthSink.Close() + + localEth := eth.NewPeer(protocol, p2p.NewPeerWithProtocols(enode.ID{1}, protos, "", caps), p2pEthSrc, nil) + remoteEth := eth.NewPeer(protocol, p2p.NewPeerWithProtocols(enode.ID{2}, protos, "", caps), p2pEthSink, nil) + defer localEth.Close() + defer remoteEth.Close() + + p2pBscSrc, p2pBscSink := p2p.MsgPipe() + defer p2pBscSrc.Close() + defer p2pBscSink.Close() + + localBsc := bsc.NewPeer(bsc.Bsc1, p2p.NewPeerWithProtocols(enode.ID{1}, protos, "", caps), p2pBscSrc) + remoteBsc := bsc.NewPeer(bsc.Bsc1, p2p.NewPeerWithProtocols(enode.ID{3}, protos, "", caps), p2pBscSink) + defer localBsc.Close() + defer remoteBsc.Close() + + go func(p *bsc.Peer) { + (*bscHandler)(handler.handler).RunPeer(p, func(peer *bsc.Peer) error { + return bsc.Handle((*bscHandler)(handler.handler), peer) + }) + }(localBsc) + + time.Sleep(200 * time.Millisecond) + remoteBsc.Handshake() + + time.Sleep(200 * time.Millisecond) + go func(p *eth.Peer) { + handler.handler.runEthPeer(p, func(peer *eth.Peer) error { + return eth.Handle((*ethHandler)(handler.handler), peer) + }) + }(localEth) + + // Run the handshake locally to avoid spinning up a source handler + var ( + genesis = handler.chain.Genesis() + head = handler.chain.CurrentBlock() + td = handler.chain.GetTd(head.Hash(), head.NumberU64()) + ) + time.Sleep(200 * time.Millisecond) + if err := remoteEth.Handshake(1, td, head.Hash(), genesis.Hash(), forkid.NewIDWithChain(handler.chain), forkid.NewFilter(handler.chain), nil); err != nil { + t.Fatalf("failed to run protocol handshake: %d", err) + } + + votesCh := make(chan core.NewVoteEvent) + sub := handler.votepool.SubscribeNewVoteEvent(votesCh) + defer sub.Unsubscribe() + // Send the vote to the sink and verify that it's added to the vote pool + vote := types.VoteEnvelope{ + VoteAddress: types.BLSPublicKey{}, + Signature: types.BLSSignature{}, + Data: &types.VoteData{ + SourceNumber: uint64(0), + SourceHash: common.BytesToHash(common.Hex2Bytes(string(rune(0)))), + TargetNumber: uint64(1), + TargetHash: common.BytesToHash(common.Hex2Bytes(string(rune(1)))), + }, + } + + remoteBsc.AsyncSendVotes([]*types.VoteEnvelope{&vote}) + time.Sleep(100 * time.Millisecond) + select { + case event := <-votesCh: + if event.Vote.Hash() != vote.Hash() { + t.Errorf("added wrong vote hash: got %v, want %v", event.Vote.Hash(), vote.Hash()) + } + case <-time.After(2 * time.Second): + t.Errorf("no NewVotesEvent received within 2 seconds") + } +} diff --git a/eth/handler_diff_test.go b/eth/handler_diff_test.go index 0956459d98..06d16b4116 100644 --- a/eth/handler_diff_test.go +++ b/eth/handler_diff_test.go @@ -84,11 +84,13 @@ func newTestBackendWithGenerator(blocks int) *testBackend { panic(err) } txpool := newTestTxPool() + votepool := newTestVotePool() handler, _ := newHandler(&handlerConfig{ Database: db, Chain: chain, TxPool: txpool, + VotePool: votepool, Network: 1, Sync: downloader.FullSync, BloomCache: 1, diff --git a/eth/handler_eth.go b/eth/handler_eth.go index 8f01cf528c..f7e3fba880 100644 --- a/eth/handler_eth.go +++ b/eth/handler_eth.go @@ -76,6 +76,7 @@ func (h *ethHandler) Handle(peer *eth.Peer, packet eth.Packet) error { case *eth.PooledTransactionsPacket: return h.txFetcher.Enqueue(peer.ID(), *packet, true) + default: return fmt.Errorf("unexpected eth packet type: %T", packet) } diff --git a/eth/handler_eth_test.go b/eth/handler_eth_test.go index 74db6668c3..de57e475c4 100644 --- a/eth/handler_eth_test.go +++ b/eth/handler_eth_test.go @@ -33,6 +33,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/eth/protocols/bsc" "github.com/ethereum/go-ethereum/eth/protocols/eth" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/p2p" @@ -90,11 +91,25 @@ func testForkIDSplit(t *testing.T, protocol uint) { configNoFork = ¶ms.ChainConfig{HomesteadBlock: big.NewInt(1)} configProFork = ¶ms.ChainConfig{ - HomesteadBlock: big.NewInt(1), - EIP150Block: big.NewInt(2), - EIP155Block: big.NewInt(2), - EIP158Block: big.NewInt(2), - ByzantiumBlock: big.NewInt(3), + HomesteadBlock: big.NewInt(1), + EIP150Block: big.NewInt(2), + EIP155Block: big.NewInt(2), + EIP158Block: big.NewInt(2), + ByzantiumBlock: big.NewInt(3), + ConstantinopleBlock: big.NewInt(4), + PetersburgBlock: big.NewInt(4), + IstanbulBlock: big.NewInt(4), + MuirGlacierBlock: big.NewInt(4), + RamanujanBlock: big.NewInt(4), + NielsBlock: big.NewInt(4), + MirrorSyncBlock: big.NewInt(4), + BrunoBlock: big.NewInt(4), + EulerBlock: big.NewInt(5), + GibbsBlock: big.NewInt(5), + NanoBlock: big.NewInt(5), + MoranBlock: big.NewInt(5), + BonehBlock: big.NewInt(6), + LynnBlock: big.NewInt(6), } dbNoFork = rawdb.NewMemoryDatabase() dbProFork = rawdb.NewMemoryDatabase() @@ -115,6 +130,7 @@ func testForkIDSplit(t *testing.T, protocol uint) { Database: dbNoFork, Chain: chainNoFork, TxPool: newTestTxPool(), + VotePool: newTestVotePool(), Merger: consensus.NewMerger(rawdb.NewMemoryDatabase()), Network: 1, Sync: downloader.FullSync, @@ -124,6 +140,7 @@ func testForkIDSplit(t *testing.T, protocol uint) { Database: dbProFork, Chain: chainProFork, TxPool: newTestTxPool(), + VotePool: newTestVotePool(), Merger: consensus.NewMerger(rawdb.NewMemoryDatabase()), Network: 1, Sync: downloader.FullSync, @@ -230,7 +247,7 @@ func testForkIDSplit(t *testing.T, protocol uint) { t.Fatalf("fork ID rejection didn't happen") } } - case <-time.After(250 * time.Millisecond): + case <-time.After(10000 * time.Millisecond): t.Fatalf("split peers not rejected") } } @@ -239,7 +256,63 @@ func testForkIDSplit(t *testing.T, protocol uint) { // Tests that received transactions are added to the local pool. func TestRecvTransactions66(t *testing.T) { testRecvTransactions(t, eth.ETH66) } -func TestWaitDiffExtensionTimout(t *testing.T) { +func testRecvTransactions(t *testing.T, protocol uint) { + t.Parallel() + + // Create a message handler, configure it to accept transactions and watch them + handler := newTestHandler() + defer handler.close() + + handler.handler.acceptTxs = 1 // mark synced to accept transactions + + txs := make(chan core.NewTxsEvent) + sub := handler.txpool.SubscribeNewTxsEvent(txs) + defer sub.Unsubscribe() + + // Create a source peer to send messages through and a sink handler to receive them + p2pSrc, p2pSink := p2p.MsgPipe() + defer p2pSrc.Close() + defer p2pSink.Close() + + src := eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{1}, "", nil, p2pSrc), p2pSrc, handler.txpool) + sink := eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{2}, "", nil, p2pSink), p2pSink, handler.txpool) + defer src.Close() + defer sink.Close() + + go handler.handler.runEthPeer(sink, func(peer *eth.Peer) error { + return eth.Handle((*ethHandler)(handler.handler), peer) + }) + // Run the handshake locally to avoid spinning up a source handler + var ( + genesis = handler.chain.Genesis() + head = handler.chain.CurrentBlock() + td = handler.chain.GetTd(head.Hash(), head.NumberU64()) + ) + if err := src.Handshake(1, td, head.Hash(), genesis.Hash(), forkid.NewIDWithChain(handler.chain), forkid.NewFilter(handler.chain), nil); err != nil { + t.Fatalf("failed to run protocol handshake") + } + // Send the transaction to the sink and verify that it's added to the tx pool + tx := types.NewTransaction(0, common.Address{}, big.NewInt(0), 100000, big.NewInt(0), nil) + tx, _ = types.SignTx(tx, types.HomesteadSigner{}, testKey) + + if err := src.SendTransactions([]*types.Transaction{tx}); err != nil { + t.Fatalf("failed to send transaction: %v", err) + } + select { + case event := <-txs: + if len(event.Txs) != 1 { + t.Errorf("wrong number of added transactions: got %d, want 1", len(event.Txs)) + } else if event.Txs[0].Hash() != tx.Hash() { + t.Errorf("added wrong tx hash: got %v, want %v", event.Txs[0].Hash(), tx.Hash()) + } + case <-time.After(2 * time.Second): + t.Errorf("no NewTxsEvent received within 2 seconds") + } +} + +func TestWaitDiffExtensionTimout67(t *testing.T) { testWaitDiffExtensionTimout(t, eth.ETH67) } + +func testWaitDiffExtensionTimout(t *testing.T, protocol uint) { t.Parallel() // Create a message handler, configure it to accept transactions and watch them @@ -257,7 +330,7 @@ func TestWaitDiffExtensionTimout(t *testing.T) { }, } - sink := eth.NewPeer(eth.ETH67, p2p.NewPeerWithProtocols(enode.ID{2}, protos, "", []p2p.Cap{ + sink := eth.NewPeer(protocol, p2p.NewPeerWithProtocols(enode.ID{2}, protos, "", []p2p.Cap{ { Name: "diff", Version: 1, @@ -274,7 +347,9 @@ func TestWaitDiffExtensionTimout(t *testing.T) { } } -func TestWaitSnapExtensionTimout(t *testing.T) { +func TestWaitSnapExtensionTimout67(t *testing.T) { testWaitSnapExtensionTimout(t, eth.ETH67) } + +func testWaitSnapExtensionTimout(t *testing.T, protocol uint) { t.Parallel() // Create a message handler, configure it to accept transactions and watch them @@ -292,7 +367,7 @@ func TestWaitSnapExtensionTimout(t *testing.T) { }, } - sink := eth.NewPeer(eth.ETH67, p2p.NewPeerWithProtocols(enode.ID{2}, protos, "", []p2p.Cap{ + sink := eth.NewPeer(protocol, p2p.NewPeerWithProtocols(enode.ID{2}, protos, "", []p2p.Cap{ { Name: "snap", Version: 1, @@ -309,57 +384,40 @@ func TestWaitSnapExtensionTimout(t *testing.T) { } } -func testRecvTransactions(t *testing.T, protocol uint) { +func TestWaitBscExtensionTimout67(t *testing.T) { testWaitBscExtensionTimout(t, eth.ETH67) } + +func testWaitBscExtensionTimout(t *testing.T, protocol uint) { t.Parallel() // Create a message handler, configure it to accept transactions and watch them handler := newTestHandler() defer handler.close() - handler.handler.acceptTxs = 1 // mark synced to accept transactions - - txs := make(chan core.NewTxsEvent) - sub := handler.txpool.SubscribeNewTxsEvent(txs) - defer sub.Unsubscribe() - // Create a source peer to send messages through and a sink handler to receive them - p2pSrc, p2pSink := p2p.MsgPipe() - defer p2pSrc.Close() + _, p2pSink := p2p.MsgPipe() defer p2pSink.Close() - src := eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{1}, "", nil, p2pSrc), p2pSrc, handler.txpool) - sink := eth.NewPeer(protocol, p2p.NewPeerPipe(enode.ID{2}, "", nil, p2pSink), p2pSink, handler.txpool) - defer src.Close() + protos := []p2p.Protocol{ + { + Name: "bsc", + Version: bsc.Bsc1, + }, + } + + sink := eth.NewPeer(protocol, p2p.NewPeerWithProtocols(enode.ID{2}, protos, "", []p2p.Cap{ + { + Name: "bsc", + Version: bsc.Bsc1, + }, + }), p2pSink, nil) defer sink.Close() - go handler.handler.runEthPeer(sink, func(peer *eth.Peer) error { + err := handler.handler.runEthPeer(sink, func(peer *eth.Peer) error { return eth.Handle((*ethHandler)(handler.handler), peer) }) - // Run the handshake locally to avoid spinning up a source handler - var ( - genesis = handler.chain.Genesis() - head = handler.chain.CurrentBlock() - td = handler.chain.GetTd(head.Hash(), head.NumberU64()) - ) - if err := src.Handshake(1, td, head.Hash(), genesis.Hash(), forkid.NewIDWithChain(handler.chain), forkid.NewFilter(handler.chain), nil); err != nil { - t.Fatalf("failed to run protocol handshake") - } - // Send the transaction to the sink and verify that it's added to the tx pool - tx := types.NewTransaction(0, common.Address{}, big.NewInt(0), 100000, big.NewInt(0), nil) - tx, _ = types.SignTx(tx, types.HomesteadSigner{}, testKey) - if err := src.SendTransactions([]*types.Transaction{tx}); err != nil { - t.Fatalf("failed to send transaction: %v", err) - } - select { - case event := <-txs: - if len(event.Txs) != 1 { - t.Errorf("wrong number of added transactions: got %d, want 1", len(event.Txs)) - } else if event.Txs[0].Hash() != tx.Hash() { - t.Errorf("added wrong tx hash: got %v, want %v", event.Txs[0].Hash(), tx.Hash()) - } - case <-time.After(2 * time.Second): - t.Errorf("no NewTxsEvent received within 2 seconds") + if err == nil || err.Error() != "peer wait timeout" { + t.Fatalf("error should be `peer wait timeout`") } } diff --git a/eth/handler_test.go b/eth/handler_test.go index 4d4c11592c..b38248e47b 100644 --- a/eth/handler_test.go +++ b/eth/handler_test.go @@ -136,10 +136,11 @@ func (p *testTxPool) SubscribeReannoTxsEvent(ch chan<- core.ReannoTxsEvent) even // preinitialized with some sane testing defaults and the transaction pool mocked // out. type testHandler struct { - db ethdb.Database - chain *core.BlockChain - txpool *testTxPool - handler *handler + db ethdb.Database + chain *core.BlockChain + txpool *testTxPool + votepool *testVotePool + handler *handler } // newTestHandler creates a new handler for testing purposes with no blocks. @@ -164,12 +165,14 @@ func newTestHandlerWithBlocks(blocks int) *testHandler { panic(err) } txpool := newTestTxPool() + votepool := newTestVotePool() handler, _ := newHandler(&handlerConfig{ Database: db, Chain: chain, TxPool: txpool, Merger: consensus.NewMerger(rawdb.NewMemoryDatabase()), + VotePool: votepool, Network: 1, Sync: downloader.SnapSync, BloomCache: 1, @@ -177,10 +180,11 @@ func newTestHandlerWithBlocks(blocks int) *testHandler { handler.Start(1000) return &testHandler{ - db: db, - chain: chain, - txpool: txpool, - handler: handler, + db: db, + chain: chain, + txpool: txpool, + votepool: votepool, + handler: handler, } } @@ -189,3 +193,45 @@ func (b *testHandler) close() { b.handler.Stop() b.chain.Stop() } + +// newTestVotePool creates a mock vote pool. +type testVotePool struct { + pool map[common.Hash]*types.VoteEnvelope // Hash map of collected votes + + voteFeed event.Feed // Notification feed to allow waiting for inclusion + lock sync.RWMutex // Protects the vote pool +} + +// newTestVotePool creates a mock vote pool. +func newTestVotePool() *testVotePool { + return &testVotePool{ + pool: make(map[common.Hash]*types.VoteEnvelope), + } +} + +func (t *testVotePool) PutVote(vote *types.VoteEnvelope) { + t.lock.Lock() + defer t.lock.Unlock() + + t.pool[vote.Hash()] = vote + t.voteFeed.Send(core.NewVoteEvent{Vote: vote}) +} + +func (t *testVotePool) FetchVoteByBlockHash(blockHash common.Hash) []*types.VoteEnvelope { + panic("implement me") +} + +func (t *testVotePool) GetVotes() []*types.VoteEnvelope { + t.lock.RLock() + defer t.lock.RUnlock() + + votes := make([]*types.VoteEnvelope, 0, len(t.pool)) + for _, vote := range t.pool { + votes = append(votes, vote) + } + return votes +} + +func (t *testVotePool) SubscribeNewVoteEvent(ch chan<- core.NewVoteEvent) event.Subscription { + return t.voteFeed.Subscribe(ch) +} diff --git a/eth/peer.go b/eth/peer.go index 802d1e5aac..77a150434c 100644 --- a/eth/peer.go +++ b/eth/peer.go @@ -20,6 +20,7 @@ import ( "math/big" "time" + "github.com/ethereum/go-ethereum/eth/protocols/bsc" "github.com/ethereum/go-ethereum/eth/protocols/trust" "github.com/ethereum/go-ethereum/eth/protocols/diff" @@ -41,6 +42,7 @@ type ethPeer struct { snapExt *snapPeer // Satellite `snap` connection diffExt *diffPeer trustExt *trustPeer + bscExt *bscPeer // Satellite `bsc` connection syncDrop *time.Timer // Connection dropper if `eth` sync progress isn't validated in time snapWait chan struct{} // Notification channel for snap connections @@ -76,6 +78,12 @@ type trustPeerInfo struct { Version uint `json:"version"` // Trust protocol version negotiated } +// bscPeerInfo represents a short summary of the `bsc` sub-protocol metadata known +// about a connected peer. +type bscPeerInfo struct { + Version uint `json:"version"` // bsc protocol version negotiated +} + // snapPeer is a wrapper around snap.Peer to maintain a few extra metadata. type snapPeer struct { *snap.Peer @@ -91,6 +99,11 @@ type trustPeer struct { *trust.Peer } +// bscPeer is a wrapper around bsc.Peer to maintain a few extra metadata. +type bscPeer struct { + *bsc.Peer +} + // info gathers and returns some `diff` protocol metadata known about a peer. func (p *diffPeer) info() *diffPeerInfo { return &diffPeerInfo{ @@ -112,3 +125,10 @@ func (p *trustPeer) info() *trustPeerInfo { Version: p.Version(), } } + +// info gathers and returns some `bsc` protocol metadata known about a peer. +func (p *bscPeer) info() *bscPeerInfo { + return &bscPeerInfo{ + Version: p.Version(), + } +} diff --git a/eth/peerset.go b/eth/peerset.go index 6484dae8dd..6a84449fe1 100644 --- a/eth/peerset.go +++ b/eth/peerset.go @@ -25,6 +25,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/eth/protocols/bsc" "github.com/ethereum/go-ethereum/eth/protocols/diff" "github.com/ethereum/go-ethereum/eth/protocols/eth" "github.com/ethereum/go-ethereum/eth/protocols/snap" @@ -59,6 +60,10 @@ var ( // errTrustWithoutEth is returned if a peer attempts to connect only on the // trust protocol without advertising the eth main protocol. errTrustWithoutEth = errors.New("peer connected on trust without compatible eth support") + + // errBscWithoutEth is returned if a peer attempts to connect only on the + // bsc protocol without advertising the eth main protocol. + errBscWithoutEth = errors.New("peer connected on bsc without compatible eth support") ) const ( @@ -82,6 +87,9 @@ type peerSet struct { trustWait map[string]chan *trust.Peer // Peers connected on `eth` waiting for their trust extension trustPend map[string]*trust.Peer // Peers connected on the `trust` protocol, but not yet on `eth` + bscWait map[string]chan *bsc.Peer // Peers connected on `eth` waiting for their bsc extension + bscPend map[string]*bsc.Peer // Peers connected on the `bsc` protocol, but not yet on `eth` + lock sync.RWMutex closed bool } @@ -96,6 +104,8 @@ func newPeerSet() *peerSet { diffPend: make(map[string]*diff.Peer), trustWait: make(map[string]chan *trust.Peer), trustPend: make(map[string]*trust.Peer), + bscWait: make(map[string]chan *bsc.Peer), + bscPend: make(map[string]*bsc.Peer), } } @@ -193,6 +203,36 @@ func (ps *peerSet) registerTrustExtension(peer *trust.Peer) error { return nil } +// registerBscExtension unblocks an already connected `eth` peer waiting for its +// `bsc` extension, or if no such peer exists, tracks the extension for the time +// being until the `eth` main protocol starts looking for it. +func (ps *peerSet) registerBscExtension(peer *bsc.Peer) error { + // Reject the peer if it advertises `bsc` without `eth` as `bsc` is only a + // satellite protocol meaningful with the chain selection of `eth` + if !peer.RunningCap(eth.ProtocolName, eth.ProtocolVersions) { + return errBscWithoutEth + } + // Ensure nobody can double connect + ps.lock.Lock() + defer ps.lock.Unlock() + + id := peer.ID() + if _, ok := ps.peers[id]; ok { + return errPeerAlreadyRegistered // avoid connections with the same id as existing ones + } + if _, ok := ps.bscPend[id]; ok { + return errPeerAlreadyRegistered // avoid connections with the same id as pending ones + } + // Inject the peer into an `eth` counterpart is available, otherwise save for later + if wait, ok := ps.bscWait[id]; ok { + delete(ps.bscWait, id) + wait <- peer + return nil + } + ps.bscPend[id] = peer + return nil +} + // waitExtensions blocks until all satellite protocols are connected and tracked // by the peerset. func (ps *peerSet) waitSnapExtension(peer *eth.Peer) (*snap.Peer, error) { @@ -326,6 +366,49 @@ func (ps *peerSet) waitTrustExtension(peer *eth.Peer) (*trust.Peer, error) { } } +// waitBscExtension blocks until all satellite protocols are connected and tracked +// by the peerset. +func (ps *peerSet) waitBscExtension(peer *eth.Peer) (*bsc.Peer, error) { + // If the peer does not support a compatible `bsc`, don't wait + if !peer.RunningCap(bsc.ProtocolName, bsc.ProtocolVersions) { + return nil, nil + } + // Ensure nobody can double connect + ps.lock.Lock() + + id := peer.ID() + if _, ok := ps.peers[id]; ok { + ps.lock.Unlock() + return nil, errPeerAlreadyRegistered // avoid connections with the same id as existing ones + } + if _, ok := ps.bscWait[id]; ok { + ps.lock.Unlock() + return nil, errPeerAlreadyRegistered // avoid connections with the same id as pending ones + } + // If `bsc` already connected, retrieve the peer from the pending set + if bsc, ok := ps.bscPend[id]; ok { + delete(ps.bscPend, id) + + ps.lock.Unlock() + return bsc, nil + } + // Otherwise wait for `bsc` to connect concurrently + wait := make(chan *bsc.Peer) + ps.bscWait[id] = wait + ps.lock.Unlock() + + select { + case peer := <-wait: + return peer, nil + + case <-time.After(extensionWaitTimeout): + ps.lock.Lock() + delete(ps.bscWait, id) + ps.lock.Unlock() + return nil, errPeerWaitTimeout + } +} + func (ps *peerSet) GetDiffPeer(pid string) downloader.IDiffPeer { if p := ps.peer(pid); p != nil && p.diffExt != nil { return p.diffExt @@ -349,7 +432,7 @@ func (ps *peerSet) GetVerifyPeers() []core.VerifyPeer { // registerPeer injects a new `eth` peer into the working set, or returns an error // if the peer is already known. -func (ps *peerSet) registerPeer(peer *eth.Peer, ext *snap.Peer, diffExt *diff.Peer, trustExt *trust.Peer) error { +func (ps *peerSet) registerPeer(peer *eth.Peer, ext *snap.Peer, diffExt *diff.Peer, trustExt *trust.Peer, bscExt *bsc.Peer) error { // Start tracking the new peer ps.lock.Lock() defer ps.lock.Unlock() @@ -374,6 +457,9 @@ func (ps *peerSet) registerPeer(peer *eth.Peer, ext *snap.Peer, diffExt *diff.Pe if trustExt != nil { eth.trustExt = &trustPeer{trustExt} } + if bscExt != nil { + eth.bscExt = &bscPeer{bscExt} + } ps.peers[id] = eth return nil } @@ -420,7 +506,7 @@ func (ps *peerSet) headPeers(num uint) []*ethPeer { } // peersWithoutBlock retrieves a list of peers that do not have a given block in -// their set of known hashes so it might be propagated to them. +// their set of known hashes, so it might be propagated to them. func (ps *peerSet) peersWithoutBlock(hash common.Hash) []*ethPeer { ps.lock.RLock() defer ps.lock.RUnlock() @@ -449,6 +535,21 @@ func (ps *peerSet) peersWithoutTransaction(hash common.Hash) []*ethPeer { return list } +// peersWithoutVote retrieves a list of peers that do not have a given +// vote in their set of known hashes. +func (ps *peerSet) peersWithoutVote(hash common.Hash) []*ethPeer { + ps.lock.RLock() + defer ps.lock.RUnlock() + + list := make([]*ethPeer, 0, len(ps.peers)) + for _, p := range ps.peers { + if p.bscExt != nil && !p.bscExt.KnownVote(hash) { + list = append(list, p) + } + } + return list +} + // len returns if the current number of `eth` peers in the set. Since the `snap` // peers are tied to the existence of an `eth` connection, that will always be a // subset of `eth`. diff --git a/eth/protocols/bsc/discovery.go b/eth/protocols/bsc/discovery.go new file mode 100644 index 0000000000..6a4fac346e --- /dev/null +++ b/eth/protocols/bsc/discovery.go @@ -0,0 +1,16 @@ +package bsc + +import ( + "github.com/ethereum/go-ethereum/rlp" +) + +// enrEntry is the ENR entry which advertises `bsc` protocol on the discovery. +type enrEntry struct { + // Ignore additional fields (for forward compatibility). + Rest []rlp.RawValue `rlp:"tail"` +} + +// ENRKey implements enr.Entry. +func (e enrEntry) ENRKey() string { + return "bsc" +} diff --git a/eth/protocols/bsc/handler.go b/eth/protocols/bsc/handler.go new file mode 100644 index 0000000000..e993f255f3 --- /dev/null +++ b/eth/protocols/bsc/handler.go @@ -0,0 +1,145 @@ +package bsc + +import ( + "fmt" + "time" + + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/ethereum/go-ethereum/p2p/enr" +) + +// Handler is a callback to invoke from an outside runner after the boilerplate +// exchanges have passed. +type Handler func(peer *Peer) error + +type Backend interface { + // Chain retrieves the blockchain object to serve data. + Chain() *core.BlockChain + + // RunPeer is invoked when a peer joins on the `bsc` protocol. The handler + // should do any peer maintenance work, handshakes and validations. If all + // is passed, control should be given back to the `handler` to process the + // inbound messages going forward. + RunPeer(peer *Peer, handler Handler) error + + // PeerInfo retrieves all known `bsc` information about a peer. + PeerInfo(id enode.ID) interface{} + + // Handle is a callback to be invoked when a data packet is received from + // the remote peer. Only packets not consumed by the protocol handler will + // be forwarded to the backend. + Handle(peer *Peer, packet Packet) error +} + +// MakeProtocols constructs the P2P protocol definitions for `bsc`. +func MakeProtocols(backend Backend, dnsdisc enode.Iterator) []p2p.Protocol { + // Filter the discovery iterator for nodes advertising vote support. + dnsdisc = enode.Filter(dnsdisc, func(n *enode.Node) bool { + var vote enrEntry + return n.Load(&vote) == nil + }) + + protocols := make([]p2p.Protocol, len(ProtocolVersions)) + for i, version := range ProtocolVersions { + version := version // Closure + + protocols[i] = p2p.Protocol{ + Name: ProtocolName, + Version: version, + Length: protocolLengths[version], + Run: func(p *p2p.Peer, rw p2p.MsgReadWriter) error { + peer := NewPeer(version, p, rw) + defer peer.Close() + + return backend.RunPeer(peer, func(peer *Peer) error { + return Handle(backend, peer) + }) + }, + NodeInfo: func() interface{} { + return nodeInfo(backend.Chain()) + }, + PeerInfo: func(id enode.ID) interface{} { + return backend.PeerInfo(id) + }, + Attributes: []enr.Entry{&enrEntry{}}, + DialCandidates: dnsdisc, + } + } + return protocols +} + +// Handle is the callback invoked to manage the life cycle of a `bsc` peer. +// When this function terminates, the peer is disconnected. +func Handle(backend Backend, peer *Peer) error { + for { + if err := handleMessage(backend, peer); err != nil { + peer.Log().Debug("Message handling failed in `bsc`", "err", err) + return err + } + } +} + +type msgHandler func(backend Backend, msg Decoder, peer *Peer) error +type Decoder interface { + Decode(val interface{}) error +} + +var bsc1 = map[uint64]msgHandler{ + VotesMsg: handleVotes, +} + +// handleMessage is invoked whenever an inbound message is received from a +// remote peer on the `bsc` protocol. The remote connection is torn down upon +// returning any error. +func handleMessage(backend Backend, peer *Peer) error { + // Read the next message from the remote peer, and ensure it's fully consumed + msg, err := peer.rw.ReadMsg() + if err != nil { + return err + } + if msg.Size > maxMessageSize { + return fmt.Errorf("%w: %v > %v", errMsgTooLarge, msg.Size, maxMessageSize) + } + defer msg.Discard() + + var handlers = bsc1 + + // Track the amount of time it takes to serve the request and run the handler + if metrics.Enabled { + h := fmt.Sprintf("%s/%s/%d/%#02x", p2p.HandleHistName, ProtocolName, peer.Version(), msg.Code) + defer func(start time.Time) { + sampler := func() metrics.Sample { + return metrics.ResettingSample( + metrics.NewExpDecaySample(1028, 0.015), + ) + } + metrics.GetOrRegisterHistogramLazy(h, nil, sampler).Update(time.Since(start).Microseconds()) + }(time.Now()) + } + if handler := handlers[msg.Code]; handler != nil { + return handler(backend, msg, peer) + } + return fmt.Errorf("%w: %v", errInvalidMsgCode, msg.Code) +} + +func handleVotes(backend Backend, msg Decoder, peer *Peer) error { + ann := new(VotesPacket) + if err := msg.Decode(ann); err != nil { + return fmt.Errorf("%w: message %v: %v", errDecode, msg, err) + } + // Schedule all the unknown hashes for retrieval + peer.markVotes(ann.Votes) + return backend.Handle(peer, ann) +} + +// NodeInfo represents a short summary of the `bsc` sub-protocol metadata +// known about the host peer. +type NodeInfo struct{} + +// nodeInfo retrieves some `bsc` protocol metadata about the running host node. +func nodeInfo(_ *core.BlockChain) *NodeInfo { + return &NodeInfo{} +} diff --git a/eth/protocols/bsc/handshake.go b/eth/protocols/bsc/handshake.go new file mode 100644 index 0000000000..c8e74f3d12 --- /dev/null +++ b/eth/protocols/bsc/handshake.go @@ -0,0 +1,68 @@ +package bsc + +import ( + "fmt" + "time" + + "github.com/ethereum/go-ethereum/common/gopool" + "github.com/ethereum/go-ethereum/p2p" +) + +const ( + // handshakeTimeout is the maximum allowed time for the `bsc` handshake to + // complete before dropping the connection as malicious. + handshakeTimeout = 5 * time.Second +) + +// Handshake executes the bsc protocol handshake, +func (p *Peer) Handshake() error { + // Send out own handshake in a new thread + errc := make(chan error, 2) + + var cap BscCapPacket // safe to read after two values have been received from errc + + gopool.Submit(func() { + errc <- p2p.Send(p.rw, BscCapMsg, &BscCapPacket{ + ProtocolVersion: p.version, + Extra: defaultExtra, + }) + }) + gopool.Submit(func() { + errc <- p.readCap(&cap) + }) + timeout := time.NewTimer(handshakeTimeout) + defer timeout.Stop() + for i := 0; i < 2; i++ { + select { + case err := <-errc: + if err != nil { + return err + } + case <-timeout.C: + return p2p.DiscReadTimeout + } + } + return nil +} + +// readCap reads the remote handshake message. +func (p *Peer) readCap(cap *BscCapPacket) error { + msg, err := p.rw.ReadMsg() + if err != nil { + return err + } + if msg.Code != BscCapMsg { + return fmt.Errorf("%w: first msg has code %x (!= %x)", errNoBscCapMsg, msg.Code, BscCapMsg) + } + if msg.Size > maxMessageSize { + return fmt.Errorf("%w: %v > %v", errMsgTooLarge, msg.Size, maxMessageSize) + } + // Decode the handshake and make sure everything matches + if err := msg.Decode(cap); err != nil { + return fmt.Errorf("%w: message %v: %v", errDecode, msg, err) + } + if cap.ProtocolVersion != p.version { + return fmt.Errorf("%w: %d (!= %d)", errProtocolVersionMismatch, cap.ProtocolVersion, p.version) + } + return nil +} diff --git a/eth/protocols/bsc/peer.go b/eth/protocols/bsc/peer.go new file mode 100644 index 0000000000..e66ab2a6b3 --- /dev/null +++ b/eth/protocols/bsc/peer.go @@ -0,0 +1,157 @@ +package bsc + +import ( + mapset "github.com/deckarep/golang-set" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p" +) + +const ( + // maxKnownVotes is the maximum vote hashes to keep in the known list + // before starting to randomly evict them. + maxKnownVotes = 5376 +) + +// max is a helper function which returns the larger of the two given integers. +func max(a, b int) int { + if a > b { + return a + } + return b +} + +// Peer is a collection of relevant information we have about a `bsc` peer. +type Peer struct { + id string // Unique ID for the peer, cached + knownVotes *knownCache // Set of vote hashes known to be known by this peer + voteBroadcast chan []*types.VoteEnvelope // Channel used to queue votes propagation requests + + *p2p.Peer // The embedded P2P package peer + rw p2p.MsgReadWriter // Input/output streams for bsc + version uint // Protocol version negotiated + logger log.Logger // Contextual logger with the peer id injected + term chan struct{} // Termination channel to stop the broadcasters +} + +// NewPeer create a wrapper for a network connection and negotiated protocol +// version. +func NewPeer(version uint, p *p2p.Peer, rw p2p.MsgReadWriter) *Peer { + id := p.ID().String() + peer := &Peer{ + id: id, + knownVotes: newKnownCache(maxKnownVotes), + voteBroadcast: make(chan []*types.VoteEnvelope), + Peer: p, + rw: rw, + version: version, + logger: log.New("peer", id[:8]), + term: make(chan struct{}), + } + go peer.broadcastVotes() + return peer +} + +// ID retrieves the peer's unique identifier. +func (p *Peer) ID() string { + return p.id +} + +// Version retrieves the peer's negotiated `bsc` protocol version. +func (p *Peer) Version() uint { + return p.version +} + +// Log overrides the P2P logget with the higher level one containing only the id. +func (p *Peer) Log() log.Logger { + return p.logger +} + +// Close signals the broadcast goroutine to terminate. Only ever call this if +// you created the peer yourself via NewPeer. Otherwise let whoever created it +// clean it up! +func (p *Peer) Close() { + close(p.term) +} + +// KnownVote returns whether peer is known to already have a vote. +func (p *Peer) KnownVote(hash common.Hash) bool { + return p.knownVotes.contains(hash) +} + +// markVotes marks votes as known for the peer, ensuring that they +// will never be repropagated to this particular peer. +func (p *Peer) markVotes(votes []*types.VoteEnvelope) { + for _, vote := range votes { + if !p.knownVotes.contains(vote.Hash()) { + // If we reached the memory allowance, drop a previously known vote hash + p.knownVotes.add(vote.Hash()) + } + } +} + +// sendVotes propagates a batch of votes to the remote peer. +func (p *Peer) sendVotes(votes []*types.VoteEnvelope) error { + // Mark all the votes as known, but ensure we don't overflow our limits + p.markVotes(votes) + return p2p.Send(p.rw, VotesMsg, &VotesPacket{votes}) +} + +// AsyncSendVotes queues a batch of vote hashes for propagation to a remote peer. If +// the peer's broadcast queue is full, the event is silently dropped. +func (p *Peer) AsyncSendVotes(votes []*types.VoteEnvelope) { + select { + case p.voteBroadcast <- votes: + case <-p.term: + p.Log().Debug("Dropping vote propagation", "count", len(votes)) + } +} + +// broadcastVotes is a write loop that schedules votes broadcasts +// to the remote peer. The goal is to have an async writer that does not lock up +// node internals and at the same time rate limits queued data. +func (p *Peer) broadcastVotes() { + for { + select { + case votes := <-p.voteBroadcast: + if err := p.sendVotes(votes); err != nil { + return + } + p.Log().Trace("Sent votes", "count", len(votes)) + + case <-p.term: + return + } + } +} + +// knownCache is a cache for known hashes. +type knownCache struct { + hashes mapset.Set + max int +} + +// newKnownCache creates a new knownCache with a max capacity. +func newKnownCache(max int) *knownCache { + return &knownCache{ + max: max, + hashes: mapset.NewSet(), + } +} + +// add adds a list of elements to the set. +func (k *knownCache) add(hashes ...common.Hash) { + for k.hashes.Cardinality() > max(0, k.max-len(hashes)) { + k.hashes.Pop() + } + for _, hash := range hashes { + k.hashes.Add(hash) + } +} + +// contains returns whether the given item is in the set. +func (k *knownCache) contains(hash common.Hash) bool { + return k.hashes.Contains(hash) +} diff --git a/eth/protocols/bsc/protocol.go b/eth/protocols/bsc/protocol.go new file mode 100644 index 0000000000..a063531f07 --- /dev/null +++ b/eth/protocols/bsc/protocol.go @@ -0,0 +1,66 @@ +package bsc + +import ( + "errors" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" +) + +// Constants to match up protocol versions and messages +const ( + Bsc1 = 1 +) + +// ProtocolName is the official short name of the `bsc` protocol used during +// devp2p capability negotiation. +const ProtocolName = "bsc" + +// ProtocolVersions are the supported versions of the `bsc` protocol (first +// is primary). +var ProtocolVersions = []uint{Bsc1} + +// protocolLengths are the number of implemented message corresponding to +// different protocol versions. +var protocolLengths = map[uint]uint64{Bsc1: 2} + +// maxMessageSize is the maximum cap on the size of a protocol message. +const maxMessageSize = 10 * 1024 * 1024 + +const ( + BscCapMsg = 0x00 // bsc capability msg used upon handshake + VotesMsg = 0x01 +) + +var defaultExtra = []byte{0x00} + +var ( + errNoBscCapMsg = errors.New("no bsc capability message") + errMsgTooLarge = errors.New("message too long") + errDecode = errors.New("invalid message") + errInvalidMsgCode = errors.New("invalid message code") + errProtocolVersionMismatch = errors.New("protocol version mismatch") +) + +// Packet represents a p2p message in the `bsc` protocol. +type Packet interface { + Name() string // Name returns a string corresponding to the message type. + Kind() byte // Kind returns the message type. +} + +// BscCapPacket is the network packet for bsc capability message. +type BscCapPacket struct { + ProtocolVersion uint + Extra rlp.RawValue // for extension +} + +// VotesPacket is the network packet for votes record. +type VotesPacket struct { + Votes []*types.VoteEnvelope +} + +func (*BscCapPacket) Name() string { return "BscCap" } +func (*BscCapPacket) Kind() byte { return BscCapMsg } + +func (*VotesPacket) Name() string { return "Votes" } +func (*VotesPacket) Kind() byte { return VotesMsg } diff --git a/eth/protocols/bsc/protocol_test.go b/eth/protocols/bsc/protocol_test.go new file mode 100644 index 0000000000..8597021411 --- /dev/null +++ b/eth/protocols/bsc/protocol_test.go @@ -0,0 +1,132 @@ +package bsc + +import ( + "bytes" + "encoding/hex" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" +) + +// TestBsc1Messages tests the encoding of defined Bsc1 messages +func TestBsc1Messages(t *testing.T) { + var ( + BLSPublicKey = "b32d4d46a7127dcc865f0d30f2ee3dcd5983b686f4e3a9202afc8b608652001c9938906ae1ff1417486096e32511f1bc" + voteDataSet = []types.VoteData{ + { + SourceNumber: 0, + SourceHash: common.HexToHash("0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34"), + TargetNumber: 1, + TargetHash: common.HexToHash("0xd0bc67b50915467ada963c35ee00950f664788e47da8139d8c178653171034f1"), + }, + { + SourceNumber: 0, + SourceHash: common.HexToHash("0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34"), + TargetNumber: 2, + TargetHash: common.HexToHash("0xc2d18d5a59d65da573f70c4d30448482418894e018b0d189db24ea4fd02d7aa1"), + }, + { + SourceNumber: 0, + SourceHash: common.HexToHash("0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34"), + TargetNumber: 4, + TargetHash: common.HexToHash("0xbd1bdaf8a8f5c00c464df2856a9e2ef23b8dcc906e6490d3cd295ebb5eb124c3"), + }, + { + SourceNumber: 0, + SourceHash: common.HexToHash("0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34"), + TargetNumber: 8, + TargetHash: common.HexToHash("0x3073782ecabb5ef0673e95962273482347a2c7b30a0a7124c664443d0a43f1e1"), + }, + { + SourceNumber: 0, + SourceHash: common.HexToHash("0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34"), + TargetNumber: 16, + TargetHash: common.HexToHash("0xc119833266327fd7e0cd929c6a847ae7d1689df5066dfdde2e52f51c0ecbcc3f"), + }, + { + SourceNumber: 0, + SourceHash: common.HexToHash("0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34"), + TargetNumber: 32, + TargetHash: common.HexToHash("0x3b5650bcb98381e463871a15a3f601cdc26843d76f4d3461333d7feae38a1786"), + }, + { + SourceNumber: 0, + SourceHash: common.HexToHash("0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34"), + TargetNumber: 64, + TargetHash: common.HexToHash("0x5e38b4d98904178d60d58f5bc1687b0c7df114a51f2007d3ee3e6e732539f130"), + }, + { + SourceNumber: 0, + SourceHash: common.HexToHash("0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34"), + TargetNumber: 128, + TargetHash: common.HexToHash("0xa4a64a7d511d3ff6982b5a79e9a485508477b98996c570a220f9daea0c7682f8"), + }, + { + SourceNumber: 0, + SourceHash: common.HexToHash("0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34"), + TargetNumber: 256, + TargetHash: common.HexToHash("0xd313672c2653fc13e75a9dafdcee93f444caf2cffb04585d3e306fd15418b7e2"), + }, + { + SourceNumber: 0, + SourceHash: common.HexToHash("0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34"), + TargetNumber: 512, + TargetHash: common.HexToHash("0x3c5fe2e5439ca7a7f1a3de7d5c0914c37261451c87654397dd45f207109839ae"), + }, + { + SourceNumber: 0, + SourceHash: common.HexToHash("0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34"), + TargetNumber: 1024, + TargetHash: common.HexToHash("0x088eeeb07acff0db3ae2585195e9fd23bdf54b55077cab87d1632b08dd2c043b"), + }, + } + signatures = []string{ + "91f8a39f99a0b3632d248e635ab0e7b5ff68071fa4def5c2df9f249db7d393c0ba89eb28a65f2a6ba836baddb961b9c312c70a87d130edf944b340649218335c91078cce808da75ff69f673bab3ecdf068c33b1ab147c54298056b19e9cc625d", + "a56cd257f9a4b4830c9bfadaa751c7b1d4e9c6899127c145987a55a7cfa0d1b7d114cb2523ea4e2efee0326cfc5a1cd912eaf7f0c4c0be3193677284533f1709fbd75471a9fb22aea358cdbf2e900628d7c504ce7245e8af6fdd1039dfa3c0bd", + "893f8aff7fc523a7aff006aaba71fbde5f1eee1f4683d405892ffb9ab9282a5dae01054210ff6873ee76f86b9afdef2e128932b26696e3f7e1de7fe7d3fdd1c41273912ff5d1002cba176dbf84e1fe2edb60b114129b89e1329a03f7d9843d04", + "b3585bf55f1e0d8bc0f544a386e6fc4ec37de52330f69b450f579050acda6279a8a38172ed2f01dfdb57cf7dd2a314970aa8a3168234cbd29adfc6a0efd080f57d7e195dafbf5b6db087e8b943aa634f797f8f6d4e5bf04681d7ce2218e59465", + "9366e823b456049cd10ed1aa8f02a58ce2fa4caea7e8c776d6aec9c42f4263b40b0f2d76cc55a598b378381f32ef33520d47e28707027c25e38eb971cddb379e0ded5e814ce70108d65855084a11484fd08447520b7ce79ac1e680020b243747", + "aafd383c9537d750358ea077d45476cf6c1541e717c690ebe5dc5442c2af732fba17b45c60b2c49de94f5121f318b6ae021c56ae06588c6552f1d5b87a166cb8050f287b528b20556033603f6a6649ccec4792c86ae5f6353cf6b7527ac40127", + "90d9dc467a64fe7852b2e0117806409a8f12a036849d69396282088f8d86adb3adcd46b1fde51b4630a6b64c2f8652f30a46609c49b33f50c9f4641e30900ee420f9b81b2ad59a2376dcf4e065ecf832fbf738ad5b73becd2f7add27e6c14d5f", + "8f7d6bc28626dc143208aaa7b97146510f01b1a108dead65f8fddf0ec07835bca91081f9e759656d52dd7d4adaac14220c8c62aa1dd09151fe8000ce4347b100ac496593058ae11b40c74b3049d38076d07301c9dc9586baf93d9c81b4e5d424", + "b6c17077217baa5930fb04e14b6ba7203b3c854e8f1363b48ad753d96db1b4ffed36d60d8b67e86f7f76504f0abefff80ed1e4f11ff192dbfc26a0f059f7b9f66f9e883fef208cc3f58c7ce49d8e854cf8a0e48c59c7407ebfe946cfd62bf3be", + "979b1d101e51731749c72fb160dd1245d69ebd6ca81c0519464d3bca9ec3db493cf4b45ebbb7f60fbd12f0705bd788000558bdedc335cedac2100169965b2794fae8a386b2e9ece86ea6952fadeb8501d9aad00e091713cc06d30c5885c3ecf0", + "8d035b04d8ef6c13117acc1ed9d0586a141f123494f21eeaaead5dd9f623933541b293eef403d2f3e8ede84f9dfe3dc10cbd3fa6bdf3e977dcf2d18a4dca84f8bd9b24fca8e7de4180b9aa6208ad6e756b1c81e98afc8e6994824b5c076857f8", + } + + votesSet []*types.VoteEnvelope + ) + + // Init the vote data, taken from a local node + pubKeyBytes, _ := hex.DecodeString(BLSPublicKey) + { + for i, voteData := range voteDataSet { + vote := new(types.VoteEnvelope) + voteAddress := new(types.BLSPublicKey) + signature := new(types.BLSSignature) + sigBytes, _ := hex.DecodeString(signatures[i]) + copy(voteAddress[:], pubKeyBytes) + copy(signature[:], sigBytes) + vote.VoteAddress = *voteAddress + vote.Signature = *signature + vote.Data = &voteData + votesSet = append(votesSet, vote) + } + } + + for i, tc := range []struct { + message interface{} + want []byte + }{ + { + VotesPacket{votesSet}, + common.FromHex("f90982f9097ff8dbb0b32d4d46a7127dcc865f0d30f2ee3dcd5983b686f4e3a9202afc8b608652001c9938906ae1ff1417486096e32511f1bcb86091f8a39f99a0b3632d248e635ab0e7b5ff68071fa4def5c2df9f249db7d393c0ba89eb28a65f2a6ba836baddb961b9c312c70a87d130edf944b340649218335c91078cce808da75ff69f673bab3ecdf068c33b1ab147c54298056b19e9cc625df84680a06d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34820400a0088eeeb07acff0db3ae2585195e9fd23bdf54b55077cab87d1632b08dd2c043bf8dbb0b32d4d46a7127dcc865f0d30f2ee3dcd5983b686f4e3a9202afc8b608652001c9938906ae1ff1417486096e32511f1bcb860a56cd257f9a4b4830c9bfadaa751c7b1d4e9c6899127c145987a55a7cfa0d1b7d114cb2523ea4e2efee0326cfc5a1cd912eaf7f0c4c0be3193677284533f1709fbd75471a9fb22aea358cdbf2e900628d7c504ce7245e8af6fdd1039dfa3c0bdf84680a06d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34820400a0088eeeb07acff0db3ae2585195e9fd23bdf54b55077cab87d1632b08dd2c043bf8dbb0b32d4d46a7127dcc865f0d30f2ee3dcd5983b686f4e3a9202afc8b608652001c9938906ae1ff1417486096e32511f1bcb860893f8aff7fc523a7aff006aaba71fbde5f1eee1f4683d405892ffb9ab9282a5dae01054210ff6873ee76f86b9afdef2e128932b26696e3f7e1de7fe7d3fdd1c41273912ff5d1002cba176dbf84e1fe2edb60b114129b89e1329a03f7d9843d04f84680a06d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34820400a0088eeeb07acff0db3ae2585195e9fd23bdf54b55077cab87d1632b08dd2c043bf8dbb0b32d4d46a7127dcc865f0d30f2ee3dcd5983b686f4e3a9202afc8b608652001c9938906ae1ff1417486096e32511f1bcb860b3585bf55f1e0d8bc0f544a386e6fc4ec37de52330f69b450f579050acda6279a8a38172ed2f01dfdb57cf7dd2a314970aa8a3168234cbd29adfc6a0efd080f57d7e195dafbf5b6db087e8b943aa634f797f8f6d4e5bf04681d7ce2218e59465f84680a06d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34820400a0088eeeb07acff0db3ae2585195e9fd23bdf54b55077cab87d1632b08dd2c043bf8dbb0b32d4d46a7127dcc865f0d30f2ee3dcd5983b686f4e3a9202afc8b608652001c9938906ae1ff1417486096e32511f1bcb8609366e823b456049cd10ed1aa8f02a58ce2fa4caea7e8c776d6aec9c42f4263b40b0f2d76cc55a598b378381f32ef33520d47e28707027c25e38eb971cddb379e0ded5e814ce70108d65855084a11484fd08447520b7ce79ac1e680020b243747f84680a06d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34820400a0088eeeb07acff0db3ae2585195e9fd23bdf54b55077cab87d1632b08dd2c043bf8dbb0b32d4d46a7127dcc865f0d30f2ee3dcd5983b686f4e3a9202afc8b608652001c9938906ae1ff1417486096e32511f1bcb860aafd383c9537d750358ea077d45476cf6c1541e717c690ebe5dc5442c2af732fba17b45c60b2c49de94f5121f318b6ae021c56ae06588c6552f1d5b87a166cb8050f287b528b20556033603f6a6649ccec4792c86ae5f6353cf6b7527ac40127f84680a06d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34820400a0088eeeb07acff0db3ae2585195e9fd23bdf54b55077cab87d1632b08dd2c043bf8dbb0b32d4d46a7127dcc865f0d30f2ee3dcd5983b686f4e3a9202afc8b608652001c9938906ae1ff1417486096e32511f1bcb86090d9dc467a64fe7852b2e0117806409a8f12a036849d69396282088f8d86adb3adcd46b1fde51b4630a6b64c2f8652f30a46609c49b33f50c9f4641e30900ee420f9b81b2ad59a2376dcf4e065ecf832fbf738ad5b73becd2f7add27e6c14d5ff84680a06d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34820400a0088eeeb07acff0db3ae2585195e9fd23bdf54b55077cab87d1632b08dd2c043bf8dbb0b32d4d46a7127dcc865f0d30f2ee3dcd5983b686f4e3a9202afc8b608652001c9938906ae1ff1417486096e32511f1bcb8608f7d6bc28626dc143208aaa7b97146510f01b1a108dead65f8fddf0ec07835bca91081f9e759656d52dd7d4adaac14220c8c62aa1dd09151fe8000ce4347b100ac496593058ae11b40c74b3049d38076d07301c9dc9586baf93d9c81b4e5d424f84680a06d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34820400a0088eeeb07acff0db3ae2585195e9fd23bdf54b55077cab87d1632b08dd2c043bf8dbb0b32d4d46a7127dcc865f0d30f2ee3dcd5983b686f4e3a9202afc8b608652001c9938906ae1ff1417486096e32511f1bcb860b6c17077217baa5930fb04e14b6ba7203b3c854e8f1363b48ad753d96db1b4ffed36d60d8b67e86f7f76504f0abefff80ed1e4f11ff192dbfc26a0f059f7b9f66f9e883fef208cc3f58c7ce49d8e854cf8a0e48c59c7407ebfe946cfd62bf3bef84680a06d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34820400a0088eeeb07acff0db3ae2585195e9fd23bdf54b55077cab87d1632b08dd2c043bf8dbb0b32d4d46a7127dcc865f0d30f2ee3dcd5983b686f4e3a9202afc8b608652001c9938906ae1ff1417486096e32511f1bcb860979b1d101e51731749c72fb160dd1245d69ebd6ca81c0519464d3bca9ec3db493cf4b45ebbb7f60fbd12f0705bd788000558bdedc335cedac2100169965b2794fae8a386b2e9ece86ea6952fadeb8501d9aad00e091713cc06d30c5885c3ecf0f84680a06d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34820400a0088eeeb07acff0db3ae2585195e9fd23bdf54b55077cab87d1632b08dd2c043bf8dbb0b32d4d46a7127dcc865f0d30f2ee3dcd5983b686f4e3a9202afc8b608652001c9938906ae1ff1417486096e32511f1bcb8608d035b04d8ef6c13117acc1ed9d0586a141f123494f21eeaaead5dd9f623933541b293eef403d2f3e8ede84f9dfe3dc10cbd3fa6bdf3e977dcf2d18a4dca84f8bd9b24fca8e7de4180b9aa6208ad6e756b1c81e98afc8e6994824b5c076857f8f84680a06d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34820400a0088eeeb07acff0db3ae2585195e9fd23bdf54b55077cab87d1632b08dd2c043b"), + }, + } { + if have, _ := rlp.EncodeToBytes(tc.message); !bytes.Equal(have, tc.want) { + t.Errorf("test %d, type %T, have\n\t%x\nwant\n\t%x", i, tc.message, have, tc.want) + } + } +} diff --git a/eth/protocols/diff/handler.go b/eth/protocols/diff/handler.go index 18ec4e2541..4bbf24f6fe 100644 --- a/eth/protocols/diff/handler.go +++ b/eth/protocols/diff/handler.go @@ -101,7 +101,7 @@ func handleMessage(backend Backend, peer *Peer) error { } defer msg.Discard() start := time.Now() - // Track the emount of time it takes to serve the request and run the handler + // Track the amount of time it takes to serve the request and run the handler if metrics.Enabled { h := fmt.Sprintf("%s/%s/%d/%#02x", p2p.HandleHistName, ProtocolName, peer.Version(), msg.Code) defer func(start time.Time) { diff --git a/eth/protocols/eth/handler.go b/eth/protocols/eth/handler.go index 81d45d8b8f..9eb949f139 100644 --- a/eth/protocols/eth/handler.go +++ b/eth/protocols/eth/handler.go @@ -195,9 +195,6 @@ func handleMessage(backend Backend, peer *Peer) error { defer msg.Discard() var handlers = eth66 - //if peer.Version() >= ETH67 { // Left in as a sample when new protocol is added - // handlers = eth67 - //} // Track the amount of time it takes to serve the request and run the handler if metrics.Enabled { diff --git a/eth/protocols/eth/handler_test.go b/eth/protocols/eth/handler_test.go index 55e612b801..b12be49bbf 100644 --- a/eth/protocols/eth/handler_test.go +++ b/eth/protocols/eth/handler_test.go @@ -94,8 +94,8 @@ func (b *testBackend) Chain() *core.BlockChain { return b.chain } func (b *testBackend) TxPool() TxPool { return b.txpool } func (b *testBackend) RunPeer(peer *Peer, handler Handler) error { - // Normally the backend would do peer mainentance and handshakes. All that - // is omitted and we will just give control back to the handler. + // Normally the backend would do peer maintenance and handshakes. All that + // is omitted, and we will just give control back to the handler. return handler(peer) } func (b *testBackend) PeerInfo(enode.ID) interface{} { panic("not implemented") } @@ -247,7 +247,7 @@ func testGetBlockHeaders(t *testing.T, protocol uint) { backend.chain.GetBlockByNumber(1).Hash(), }, }, - // Check that non existing headers aren't returned + // Check that non-existing headers aren't returned { &GetBlockHeadersPacket{Origin: HashOrNumber{Hash: unknown}, Amount: 1}, []common.Hash{}, diff --git a/eth/protocols/eth/peer.go b/eth/protocols/eth/peer.go index 8bf973f9c3..b39aa56eee 100644 --- a/eth/protocols/eth/peer.go +++ b/eth/protocols/eth/peer.go @@ -122,7 +122,6 @@ func NewPeer(version uint, p *p2p.Peer, rw p2p.MsgReadWriter, txpool TxPool) *Pe go peer.broadcastTransactions() go peer.announceTransactions() go peer.dispatcher() - return peer } @@ -149,7 +148,7 @@ func (p *Peer) ID() string { return p.id } -// Version retrieves the peer's negoatiated `eth` protocol version. +// Version retrieves the peer's negotiated `eth` protocol version. func (p *Peer) Version() uint { return p.version } @@ -324,6 +323,11 @@ func (p *Peer) AsyncSendNewBlock(block *types.Block, td *big.Int) { } } +// SendBlockHeaders sends a batch of block headers to the remote peer. +func (p *Peer) SendBlockHeaders(headers []*types.Header) error { + return p2p.Send(p.rw, BlockHeadersMsg, BlockHeadersPacket(headers)) +} + // ReplyBlockHeaders is the eth/66 version of SendBlockHeaders. func (p *Peer) ReplyBlockHeadersRLP(id uint64, headers []rlp.RawValue) error { return p2p.Send(p.rw, BlockHeadersMsg, &BlockHeadersRLPPacket66{ diff --git a/eth/protocols/eth/protocol.go b/eth/protocols/eth/protocol.go index 66ff9220cc..3e171d6f3e 100644 --- a/eth/protocols/eth/protocol.go +++ b/eth/protocols/eth/protocol.go @@ -202,7 +202,7 @@ func (hn *HashOrNumber) DecodeRLP(s *rlp.Stream) error { // BlockHeadersPacket represents a block header response. type BlockHeadersPacket []*types.Header -// BlockHeadersPacket represents a block header response over eth/66. +// BlockHeadersPacket66 represents a block header response over eth/66. type BlockHeadersPacket66 struct { RequestId uint64 BlockHeadersPacket @@ -240,7 +240,7 @@ func (request *NewBlockPacket) sanityCheck() error { // GetBlockBodiesPacket represents a block body query. type GetBlockBodiesPacket []common.Hash -// GetBlockBodiesPacket represents a block body query over eth/66. +// GetBlockBodiesPacket66 represents a block body query over eth/66. type GetBlockBodiesPacket66 struct { RequestId uint64 GetBlockBodiesPacket @@ -249,7 +249,7 @@ type GetBlockBodiesPacket66 struct { // BlockBodiesPacket is the network packet for block content distribution. type BlockBodiesPacket []*BlockBody -// BlockBodiesPacket is the network packet for block content distribution over eth/66. +// BlockBodiesPacket66 is the network packet for block content distribution over eth/66. type BlockBodiesPacket66 struct { RequestId uint64 BlockBodiesPacket @@ -288,7 +288,7 @@ func (p *BlockBodiesPacket) Unpack() ([][]*types.Transaction, [][]*types.Header) // GetNodeDataPacket represents a trie node data query. type GetNodeDataPacket []common.Hash -// GetNodeDataPacket represents a trie node data query over eth/66. +// GetNodeDataPacket66 represents a trie node data query over eth/66. type GetNodeDataPacket66 struct { RequestId uint64 GetNodeDataPacket @@ -297,7 +297,7 @@ type GetNodeDataPacket66 struct { // NodeDataPacket is the network packet for trie node data distribution. type NodeDataPacket [][]byte -// NodeDataPacket is the network packet for trie node data distribution over eth/66. +// NodeDataPacket66 is the network packet for trie node data distribution over eth/66. type NodeDataPacket66 struct { RequestId uint64 NodeDataPacket @@ -306,7 +306,7 @@ type NodeDataPacket66 struct { // GetReceiptsPacket represents a block receipts query. type GetReceiptsPacket []common.Hash -// GetReceiptsPacket represents a block receipts query over eth/66. +// GetReceiptsPacket66 represents a block receipts query over eth/66. type GetReceiptsPacket66 struct { RequestId uint64 GetReceiptsPacket @@ -315,7 +315,7 @@ type GetReceiptsPacket66 struct { // ReceiptsPacket is the network packet for block receipts distribution. type ReceiptsPacket [][]*types.Receipt -// ReceiptsPacket is the network packet for block receipts distribution over eth/66. +// ReceiptsPacket66 is the network packet for block receipts distribution over eth/66. type ReceiptsPacket66 struct { RequestId uint64 ReceiptsPacket @@ -324,7 +324,7 @@ type ReceiptsPacket66 struct { // ReceiptsRLPPacket is used for receipts, when we already have it encoded type ReceiptsRLPPacket []rlp.RawValue -// ReceiptsPacket66 is the eth-66 version of ReceiptsRLPPacket +// ReceiptsRLPPacket66 is the eth-66 version of ReceiptsRLPPacket type ReceiptsRLPPacket66 struct { RequestId uint64 ReceiptsRLPPacket @@ -344,13 +344,13 @@ type GetPooledTransactionsPacket66 struct { // PooledTransactionsPacket is the network packet for transaction distribution. type PooledTransactionsPacket []*types.Transaction -// PooledTransactionsPacket is the network packet for transaction distribution over eth/66. +// PooledTransactionsPacket66 is the network packet for transaction distribution over eth/66. type PooledTransactionsPacket66 struct { RequestId uint64 PooledTransactionsPacket } -// PooledTransactionsPacket is the network packet for transaction distribution, used +// PooledTransactionsRLPPacket is the network packet for transaction distribution, used // in the cases we already have them in rlp-encoded form type PooledTransactionsRLPPacket []rlp.RawValue diff --git a/eth/sync.go b/eth/sync.go index 22e2b293fe..a32d305c77 100644 --- a/eth/sync.go +++ b/eth/sync.go @@ -60,6 +60,15 @@ func (h *handler) syncTransactions(p *eth.Peer) { p.AsyncSendPooledTransactionHashes(hashes) } +// syncVotes starts sending all currently pending votes to the given peer. +func (h *handler) syncVotes(p *bscPeer) { + votes := h.votepool.GetVotes() + if len(votes) == 0 { + return + } + p.AsyncSendVotes(votes) +} + // chainSyncer coordinates blockchain sync components. type chainSyncer struct { handler *handler diff --git a/eth/tracers/js/tracer_test.go b/eth/tracers/js/tracer_test.go index 4389004dcc..b58b5ae94a 100644 --- a/eth/tracers/js/tracer_test.go +++ b/eth/tracers/js/tracer_test.go @@ -103,15 +103,15 @@ func TestTracer(t *testing.T) { { // tests that we don't panic on bad arguments to memory access code: "{depths: [], step: function(log) { this.depths.push(log.memory.slice(-1,-2)); }, fault: function() {}, result: function() { return this.depths; }}", want: ``, - fail: "Tracer accessed out of bound memory: offset -1, end -2 at step (:1:53(15)) in server-side tracer function 'step'", + fail: "Tracer accessed out of bound memory: offset -1, end -2 at step (:1:53(13)) in server-side tracer function 'step'", }, { // tests that we don't panic on bad arguments to stack peeks code: "{depths: [], step: function(log) { this.depths.push(log.stack.peek(-1)); }, fault: function() {}, result: function() { return this.depths; }}", want: ``, - fail: "Tracer accessed out of bound stack: size 0, index -1 at step (:1:53(13)) in server-side tracer function 'step'", + fail: "Tracer accessed out of bound stack: size 0, index -1 at step (:1:53(11)) in server-side tracer function 'step'", }, { // tests that we don't panic on bad arguments to memory getUint code: "{ depths: [], step: function(log, db) { this.depths.push(log.memory.getUint(-64));}, fault: function() {}, result: function() { return this.depths; }}", want: ``, - fail: "Tracer accessed out of bound memory: available 0, offset -64, size 32 at step (:1:58(13)) in server-side tracer function 'step'", + fail: "Tracer accessed out of bound memory: available 0, offset -64, size 32 at step (:1:58(11)) in server-side tracer function 'step'", }, { // tests some general counting code: "{count: 0, step: function() { this.count += 1; }, fault: function() {}, result: function() { return this.count; }}", want: `3`, diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go index db388a3d9d..7e6333739f 100644 --- a/ethclient/ethclient.go +++ b/ethclient/ethclient.go @@ -370,6 +370,17 @@ func (ec *Client) SubscribeNewHead(ctx context.Context, ch chan<- *types.Header) return ec.c.EthSubscribe(ctx, ch, "newHeads") } +// SubscribeNewFinalizedHeader subscribes to notifications about the current blockchain finalized header +// on the given channel. +func (ec *Client) SubscribeNewFinalizedHeader(ctx context.Context, ch chan<- *types.Header) (ethereum.Subscription, error) { + return ec.c.EthSubscribe(ctx, ch, "newFinalizedHeaders") +} + +// SubscribeNewVotes subscribes to notifications about the new votes into vote pool +func (ec *Client) SubscribeNewVotes(ctx context.Context, ch chan<- *types.VoteEnvelope) (ethereum.Subscription, error) { + return ec.c.EthSubscribe(ctx, ch, "newVotes") +} + // State Access // NetworkID returns the network ID (also known as the chain ID) for this chain. @@ -579,6 +590,14 @@ func toBlockNumArg(number *big.Int) string { if number.Cmp(pending) == 0 { return "pending" } + finalized := big.NewInt(int64(rpc.FinalizedBlockNumber)) + if number.Cmp(finalized) == 0 { + return "finalized" + } + safe := big.NewInt(int64(rpc.SafeBlockNumber)) + if number.Cmp(safe) == 0 { + return "safe" + } return hexutil.EncodeBig(number) } diff --git a/ethclient/gethclient/gethclient.go b/ethclient/gethclient/gethclient.go index 7af2bf45d7..3795b182e1 100644 --- a/ethclient/gethclient/gethclient.go +++ b/ethclient/gethclient/gethclient.go @@ -188,6 +188,14 @@ func toBlockNumArg(number *big.Int) string { if number.Cmp(pending) == 0 { return "pending" } + finalized := big.NewInt(int64(rpc.FinalizedBlockNumber)) + if number.Cmp(finalized) == 0 { + return "finalized" + } + safe := big.NewInt(int64(rpc.SafeBlockNumber)) + if number.Cmp(safe) == 0 { + return "safe" + } return hexutil.EncodeBig(number) } diff --git a/go.mod b/go.mod index 1f6561f4a7..b9b3cc8b18 100644 --- a/go.mod +++ b/go.mod @@ -4,30 +4,31 @@ go 1.19 require ( github.com/Azure/azure-storage-blob-go v0.7.0 - github.com/VictoriaMetrics/fastcache v1.6.0 + github.com/VictoriaMetrics/fastcache v1.10.0 github.com/aws/aws-sdk-go-v2 v1.2.0 github.com/aws/aws-sdk-go-v2/config v1.1.1 github.com/aws/aws-sdk-go-v2/credentials v1.1.1 github.com/aws/aws-sdk-go-v2/service/route53 v1.1.1 - github.com/bnb-chain/ics23 v0.1.0 - github.com/cespare/cp v0.1.0 + github.com/btcsuite/btcd/btcec/v2 v2.3.2 + github.com/cespare/cp v1.1.1 github.com/cloudflare/cloudflare-go v0.14.0 github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f github.com/davecgh/go-spew v1.1.1 github.com/deckarep/golang-set v1.8.0 github.com/deepmap/oapi-codegen v1.8.2 // indirect github.com/docker/docker v1.6.1 - github.com/dop251/goja v0.0.0-20220405120441-9037c2b61cbf - github.com/edsrzf/mmap-go v1.0.0 - github.com/fatih/color v1.7.0 + github.com/dop251/goja v0.0.0-20230122112309-96b1610dd4f7 + github.com/edsrzf/mmap-go v1.1.0 + github.com/etcd-io/bbolt v1.3.3 // indirect + github.com/fatih/color v1.9.0 github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 - github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff - github.com/go-stack/stack v1.8.0 + github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 + github.com/go-stack/stack v1.8.1 github.com/golang/protobuf v1.5.2 github.com/golang/snappy v0.0.4 github.com/google/gofuzz v1.2.0 - github.com/google/pprof v0.0.0-20220829040838-70bd9ae97f40 - github.com/google/uuid v1.1.5 + github.com/google/pprof v0.0.0-20221203041831-ce31453925ec + github.com/google/uuid v1.3.0 github.com/gorilla/websocket v1.5.0 github.com/graph-gophers/graphql-go v1.3.0 github.com/hashicorp/go-bexpr v0.1.10 @@ -39,89 +40,234 @@ require ( github.com/influxdata/influxdb-client-go/v2 v2.4.0 github.com/jackpal/go-nat-pmp v1.0.2 github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e + github.com/jmhodges/levigo v1.0.0 // indirect github.com/julienschmidt/httprouter v1.3.0 github.com/karalabe/usb v0.0.2 - github.com/mattn/go-colorable v0.1.8 - github.com/mattn/go-isatty v0.0.12 + github.com/logrusorgru/aurora v2.0.3+incompatible + github.com/mattn/go-colorable v0.1.13 + github.com/mattn/go-isatty v0.0.16 github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 github.com/olekukonko/tablewriter v0.0.5 github.com/panjf2000/ants/v2 v2.4.5 - github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 - github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/tsdb v0.7.1 + github.com/peterh/liner v1.2.0 + github.com/pkg/errors v0.9.1 + github.com/prometheus/tsdb v0.10.0 + github.com/prysmaticlabs/prysm/v3 v3.2.2 github.com/rjeczalik/notify v0.9.1 github.com/rs/cors v1.7.0 github.com/shirou/gopsutil v3.21.11+incompatible - github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4 + github.com/status-im/keycard-go v0.2.0 github.com/stretchr/testify v1.8.1 - github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 + github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d github.com/tendermint/go-amino v0.14.1 github.com/tendermint/iavl v0.12.0 - github.com/tendermint/tendermint v0.31.12 - github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef + github.com/tendermint/tendermint v0.31.15 + github.com/tidwall/wal v1.1.7 + github.com/tyler-smith/go-bip39 v1.1.0 + github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.1.3 + github.com/willf/bitset v1.1.3 golang.org/x/crypto v0.5.0 golang.org/x/sync v0.1.0 - golang.org/x/sys v0.4.0 - golang.org/x/text v0.6.0 - golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba - golang.org/x/tools v0.1.12 + golang.org/x/sys v0.5.0 + golang.org/x/text v0.7.0 + golang.org/x/time v0.0.0-20220922220347-f3bd1da661af + golang.org/x/tools v0.6.0 gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce gopkg.in/urfave/cli.v1 v1.20.0 ) require ( - github.com/btcsuite/btcd/btcec/v2 v2.3.2 + github.com/bnb-chain/ics23 v0.1.0 github.com/fatih/structs v1.1.0 ) require github.com/yusufpapurcu/wmi v1.2.2 // indirect require ( + contrib.go.opencensus.io/exporter/jaeger v0.2.1 // indirect github.com/Azure/azure-pipeline-go v0.2.2 // indirect github.com/Azure/go-autorest/autorest/adal v0.8.0 // indirect + github.com/BurntSushi/toml v1.2.1 // indirect + github.com/allegro/bigcache v1.2.1 // indirect + github.com/aristanetworks/goarista v0.0.0-20200805130819-fd197cf57d96 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.2 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.2 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.1.1 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.1.1 // indirect github.com/aws/smithy-go v1.1.0 // indirect + github.com/benbjohnson/clock v1.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect - github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 // indirect - github.com/etcd-io/bbolt v1.3.3 // indirect - github.com/fortytw2/leaktest v1.3.0 // indirect - github.com/go-kit/kit v0.9.0 // indirect + github.com/cespare/xxhash v1.1.0 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/chzyer/readline v1.5.0 // indirect + github.com/containerd/cgroups v1.0.4 // indirect + github.com/coreos/go-systemd/v22 v22.5.0 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect + github.com/dgraph-io/ristretto v0.0.4-0.20210318174700-74754f61e018 // indirect + github.com/dlclark/regexp2 v1.7.0 // indirect + github.com/docker/go-units v0.5.0 // indirect + github.com/dustin/go-humanize v1.0.0 // indirect + github.com/elastic/gosigar v0.14.2 // indirect + github.com/ferranbt/fastssz v0.0.0-20210905181407-59cf6761a7d5 // indirect + github.com/flynn/noise v1.0.0 // indirect + github.com/francoispqt/gojay v1.2.13 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/go-kit/kit v0.10.0 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect + github.com/go-logr/logr v1.2.3 // indirect github.com/go-ole/go-ole v1.2.6 // indirect + github.com/go-playground/locales v0.14.0 // indirect + github.com/go-playground/universal-translator v0.18.0 // indirect + github.com/go-playground/validator/v10 v10.11.1 // indirect github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect + github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect + github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang-jwt/jwt/v4 v4.3.0 // indirect + github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect + github.com/golang/mock v1.6.0 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/gopacket v1.1.19 // indirect + github.com/gorilla/mux v1.8.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware v1.2.2 // indirect + github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.0.1 // indirect + github.com/herumi/bls-eth-go-binary v0.0.0-20210917013441-d37c07cfda4e // indirect github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 // indirect - github.com/jmhodges/levigo v1.0.0 // indirect - github.com/kylelemons/godebug v1.1.0 // indirect + github.com/ipfs/go-cid v0.3.2 // indirect + github.com/ipfs/go-log v1.0.5 // indirect + github.com/ipfs/go-log/v2 v2.5.1 // indirect + github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a // indirect + github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213 // indirect + github.com/klauspost/compress v1.15.15 // indirect + github.com/klauspost/cpuid/v2 v2.2.1 // indirect + github.com/koron/go-ssdp v0.0.3 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/leodido/go-urn v1.2.1 // indirect + github.com/libp2p/go-buffer-pool v0.1.0 // indirect + github.com/libp2p/go-cidranger v1.1.0 // indirect + github.com/libp2p/go-flow-metrics v0.1.0 // indirect + github.com/libp2p/go-libp2p v0.24.0 // indirect + github.com/libp2p/go-libp2p-asn-util v0.2.0 // indirect + github.com/libp2p/go-libp2p-pubsub v0.8.0 // indirect + github.com/libp2p/go-mplex v0.7.0 // indirect + github.com/libp2p/go-msgio v0.2.0 // indirect + github.com/libp2p/go-nat v0.1.0 // indirect + github.com/libp2p/go-netroute v0.2.1 // indirect + github.com/libp2p/go-openssl v0.1.0 // indirect + github.com/libp2p/go-reuseport v0.2.0 // indirect + github.com/libp2p/go-yamux/v4 v4.0.0 // indirect + github.com/lucas-clemente/quic-go v0.31.0 // indirect + github.com/lunixbochs/vtclean v1.0.0 // indirect + github.com/manifoldco/promptui v0.7.0 // indirect + github.com/marten-seemann/qtls-go1-18 v0.1.3 // indirect + github.com/marten-seemann/qtls-go1-19 v0.1.1 // indirect + github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d // indirect - github.com/mattn/go-runewidth v0.0.9 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/mattn/go-pointer v0.0.1 // indirect + github.com/mattn/go-runewidth v0.0.13 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/miekg/dns v1.1.50 // indirect + github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect + github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect + github.com/minio/highwayhash v1.0.1 // indirect + github.com/minio/sha256-simd v1.0.0 // indirect + github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/mitchellh/mapstructure v1.4.1 // indirect github.com/mitchellh/pointerstructure v1.2.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect + github.com/mr-tron/base58 v1.2.0 // indirect + github.com/multiformats/go-base32 v0.1.0 // indirect + github.com/multiformats/go-base36 v0.2.0 // indirect + github.com/multiformats/go-multiaddr v0.8.0 // indirect + github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect + github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect + github.com/multiformats/go-multibase v0.1.1 // indirect + github.com/multiformats/go-multicodec v0.7.0 // indirect + github.com/multiformats/go-multihash v0.2.1 // indirect + github.com/multiformats/go-multistream v0.3.3 // indirect + github.com/multiformats/go-varint v0.0.7 // indirect github.com/naoina/go-stringutil v0.1.0 // indirect - github.com/opentracing/opentracing-go v1.1.0 // indirect + github.com/onsi/ginkgo/v2 v2.5.1 // indirect + github.com/opencontainers/runtime-spec v1.0.2 // indirect + github.com/opentracing/opentracing-go v1.2.0 // indirect + github.com/patrickmn/go-cache v2.1.0+incompatible // indirect + github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.14.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.37.0 // indirect - github.com/prometheus/procfs v0.8.0 // indirect + github.com/prometheus/common v0.39.0 // indirect + github.com/prometheus/procfs v0.9.0 // indirect + github.com/prometheus/prom2json v1.3.0 // indirect + github.com/prysmaticlabs/fastssz v0.0.0-20220628121656-93dfe28febab // indirect + github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7 // indirect + github.com/prysmaticlabs/gohashtree v0.0.2-alpha // indirect + github.com/prysmaticlabs/prombbolt v0.0.0-20210126082820-9b7adba6db7c // indirect + github.com/r3labs/sse v0.0.0-20210224172625-26fe804710bc // indirect + github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563 // indirect - github.com/tklauser/go-sysconf v0.3.5 // indirect - github.com/tklauser/numcpus v0.2.2 // indirect + github.com/rivo/uniseg v0.3.4 // indirect + github.com/rogpeppe/go-internal v1.9.0 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/schollz/progressbar/v3 v3.3.4 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect + github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect + github.com/spaolacci/murmur3 v1.1.0 // indirect + github.com/supranational/blst v0.3.8-0.20220526154634-513d2456b344 // indirect + github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e // indirect + github.com/tidwall/gjson v1.10.2 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.0 // indirect + github.com/tidwall/tinylru v1.1.0 // indirect + github.com/tklauser/go-sysconf v0.3.10 // indirect + github.com/tklauser/numcpus v0.5.0 // indirect + github.com/trailofbits/go-mutexasserts v0.0.0-20200708152505-19999e7d3cef // indirect + github.com/uber/jaeger-client-go v2.25.0+incompatible // indirect + github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa // indirect + github.com/wealdtech/go-bytesutil v1.1.1 // indirect + github.com/wealdtech/go-eth2-types/v2 v2.5.2 // indirect + github.com/wealdtech/go-eth2-util v1.6.3 // indirect + github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee // indirect + github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect go.etcd.io/bbolt v1.3.7 // indirect - golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect - golang.org/x/net v0.5.0 // indirect - golang.org/x/term v0.4.0 // indirect - google.golang.org/genproto v0.0.0-20200825200019-8632dd797987 // indirect - google.golang.org/grpc v1.31.0 // indirect + go.opencensus.io v0.24.0 // indirect + go.uber.org/atomic v1.10.0 // indirect + go.uber.org/dig v1.15.0 // indirect + go.uber.org/fx v1.18.2 // indirect + go.uber.org/multierr v1.8.0 // indirect + go.uber.org/zap v1.24.0 // indirect + golang.org/x/exp v0.0.0-20230206171751-46f607a40771 // indirect + golang.org/x/mod v0.8.0 // indirect + golang.org/x/net v0.7.0 // indirect + golang.org/x/oauth2 v0.3.0 // indirect + golang.org/x/term v0.5.0 // indirect + google.golang.org/api v0.34.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84 // indirect + google.golang.org/grpc v1.40.0 // indirect google.golang.org/protobuf v1.28.1 // indirect + gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/apimachinery v0.18.3 // indirect + k8s.io/client-go v0.18.3 // indirect + k8s.io/klog v1.0.0 // indirect + k8s.io/klog/v2 v2.80.0 // indirect + k8s.io/utils v0.0.0-20200520001619-278ece378a50 // indirect + lukechampine.com/blake3 v1.1.7 // indirect + sigs.k8s.io/structured-merge-diff/v3 v3.0.0 // indirect + sigs.k8s.io/yaml v1.2.0 // indirect ) -replace github.com/tendermint/tendermint => github.com/bnb-chain/tendermint v0.31.15 +replace ( + github.com/grpc-ecosystem/grpc-gateway/v2 => github.com/prysmaticlabs/grpc-gateway/v2 v2.3.1-0.20210702154020-550e1cd83ec1 + github.com/tendermint/tendermint => github.com/bnb-chain/tendermint v0.31.15 +) diff --git a/go.sum b/go.sum index e838e4df64..2a5734114f 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.43.0/go.mod h1:BOSR3VbTLkk6FDC/TcffxP4NF/FFBGA5ku+jvKOP7pg= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= @@ -24,6 +26,7 @@ cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM7 cloud.google.com/go/bigtable v1.2.0/go.mod h1:JcVAOl45lrTmQfLj7T6TxyMzIN/3FGGcFm+2xVAli2o= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -34,7 +37,14 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= +contrib.go.opencensus.io/exporter/jaeger v0.2.1 h1:yGBYzYMewVL0yO9qqJv3Z5+IRhPdU7e9o/2oKpX4YvI= +contrib.go.opencensus.io/exporter/jaeger v0.2.1/go.mod h1:Y8IsLgdxqh1QxYxPC5IgXVmBaeLUeQFfBeBi9PbeZd0= +dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= +dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= +dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= +git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= github.com/Azure/azure-pipeline-go v0.2.2 h1:6oiIS9yaG6XCCzhgAgKFfIWyo4LLCiDhZot6ltoThhY= github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc= @@ -56,22 +66,51 @@ github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6L github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k= github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= +github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/VictoriaMetrics/fastcache v1.6.0 h1:C/3Oi3EiBCqufydp1neRZkqcwmEiuRT9c3fqvvgKm5o= -github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/sarama v1.26.1/go.mod h1:NbSGBSSndYaIhRcBtY9V0U7AyH+x71bG668AuWys/yU= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/VictoriaMetrics/fastcache v1.10.0 h1:5hDJnLsKLpnUEToub7ETuRu8RCkb40woBZAUiKonXzY= +github.com/VictoriaMetrics/fastcache v1.10.0/go.mod h1:tjiYeEfYXCqacuvYw/7UoDIeJaNxq6132xHICNP77w8= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= +github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc= +github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/aristanetworks/fsnotify v1.4.2/go.mod h1:D/rtu7LpjYM8tRJphJ0hUBYpjai8SfX+aSNsWDTq/Ks= +github.com/aristanetworks/glog v0.0.0-20191112221043-67e8567f59f3/go.mod h1:KASm+qXFKs/xjSoWn30NrWBBvdTTQq+UjkhjEJHfSFA= +github.com/aristanetworks/goarista v0.0.0-20200805130819-fd197cf57d96 h1:XJH0YfVFKbq782tlNThzN/Ud5qm/cx6LXOA/P6RkTxc= +github.com/aristanetworks/goarista v0.0.0-20200805130819-fd197cf57d96/go.mod h1:QZe5Yh80Hp1b6JxQdpfSEEe8X7hTyTEZSosSrFf/oJE= +github.com/aristanetworks/splunk-hec-go v0.3.3/go.mod h1:1VHO9r17b0K7WmOlLb9nTk/2YanvOEnLMUgsFrxBROc= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/aws/aws-sdk-go-v2 v1.2.0 h1:BS+UYpbsElC82gB+2E2jiCBg36i8HlubTB/dO/moQ9c= github.com/aws/aws-sdk-go-v2 v1.2.0/go.mod h1:zEQs02YRBw1DjK0PoJv3ygDYOFTre1ejlJWl8FwAuQo= github.com/aws/aws-sdk-go-v2/config v1.1.1 h1:ZAoq32boMzcaTW9bcUacBswAmHTbvlvDJICgHFZuECo= @@ -90,127 +129,257 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.1.1 h1:TJoIfnIFubCX0ACVeJ0w46HEH5Mwj github.com/aws/aws-sdk-go-v2/service/sts v1.1.1/go.mod h1:Wi0EBZwiz/K44YliU0EKxqTCJGUfYTWXrrBwkq736bM= github.com/aws/smithy-go v1.1.0 h1:D6CSsM3gdxaGaqXnPgOBCeL6Mophqzu7KJOu7zW78sU= github.com/aws/smithy-go v1.1.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw= +github.com/bazelbuild/rules_go v0.23.2 h1:Wxu7JjqnF78cKZbsBsARLSXx/jlGaSLCnUV3mTlyHvM= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= +github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= github.com/bnb-chain/ics23 v0.1.0 h1:DvjGOts2FBfbxB48384CYD1LbcrfjThFz8kowY/7KxU= github.com/bnb-chain/ics23 v0.1.0/go.mod h1:cU6lTGolbbLFsGCgceNB2AzplH1xecLp6+KXvxM32nI= github.com/bnb-chain/tendermint v0.31.15 h1:Xyn/Hifb/7X4E1zSuMdnZdMSoM2Fx6cZuKCNnqIxbNU= github.com/bnb-chain/tendermint v0.31.15/go.mod h1:cmt8HHmQUSVaWQ/hoTefRxsh5X3ERaM1zCUIR0DPbFU= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= +github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/btcutil v1.1.3 h1:xfbtw8lwpp0G6NwSHb+UE67ryTFHJAiNuipusjXSohQ= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= +github.com/bufbuild/buf v0.37.0/go.mod h1:lQ1m2HkIaGOFba6w/aC3KYBHhKEOESP3gaAEpS3dAFM= +github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= -github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= +github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU= +github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/logex v1.2.0 h1:+eqR0HfOetur4tgnC8ftU5imRnhi4te+BadWS95c5AM= +github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/readline v1.5.0 h1:lSwwFrbNviGePhkewF1az4oLmcwqCZijQ2/Wi3BGHAI= +github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/chzyer/test v0.0.0-20210722231415-061457976a23 h1:dZ0/VyGgQdVGAss6Ju0dt5P0QltE0SFY5Woh6hbIfiQ= +github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= +github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/cloudflare-go v0.14.0 h1:gFqGlGl/5f9UGXAaKapCGUfaTCgRKKnzu2VvzMZlOFA= github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f h1:C43yEtQ6NIf4ftFXD/V55gnGFgPbMQobd//YlnLjUJ8= github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q= +github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= +github.com/containerd/cgroups v1.0.4 h1:jN/mbWBEaz+T1pi5OFtnkQ+8qnmEbAr1Oo1FRm5B0dA= +github.com/containerd/cgroups v1.0.4/go.mod h1:nLNQtsF7Sl2HxNebu77i1R0oDlhiTG+kO4JTrUzo6IA= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= +github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= +github.com/d4l3k/messagediff v1.2.1 h1:ZcAIMYsUg0EAp9X+tt8/enBE/Q8Yd5kzPynLyKptt9U= github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= +github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4= github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= -github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= github.com/deepmap/oapi-codegen v1.8.2 h1:SegyeYGcdi0jLLrpbCMoJxnUUn8GBXHsvr4rbzjuhfU= github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= +github.com/dgraph-io/ristretto v0.0.4-0.20210318174700-74754f61e018 h1:cNcG4c2n5xanQzp2hMyxDxPYVQmZ91y4WN6fJFlndLo= +github.com/dgraph-io/ristretto v0.0.4-0.20210318174700-74754f61e018/go.mod h1:MIonLggsKgZLUSt414ExgwNtlOL5MuEoAJP514mwGe8= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 h1:Izz0+t1Z5nI16/II7vuEo/nHjodOg0p7+OiDpjX5t1E= github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= +github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/docker/docker v1.6.1 h1:4xYASHy5cScPkLD7PO0uTmnVc860m9NarPN1X8zeMe8= github.com/docker/docker v1.6.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/dop251/goja v0.0.0-20220405120441-9037c2b61cbf h1:Yt+4K30SdjOkRoRRm3vYNQgR+/ZIy0RmeUDZo7Y8zeQ= -github.com/dop251/goja v0.0.0-20220405120441-9037c2b61cbf/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= +github.com/dop251/goja v0.0.0-20230122112309-96b1610dd4f7 h1:kgvzE5wLsLa7XKfV85VZl40QXaMCaeFtHpPwJ8fhotY= +github.com/dop251/goja v0.0.0-20230122112309-96b1610dd4f7/go.mod h1:yRkwfj0CBpOGre+TwBsqPV0IH0Pk73e4PXJOeNDboGs= github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= +github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= -github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ= +github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q= +github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= +github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= +github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= +github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/etcd-io/bbolt v1.3.3 h1:gSJmxrs37LgTqR/oyJBWok6k6SvXEUerFTbltIhXkBM= github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= -github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= +github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/ferranbt/fastssz v0.0.0-20210120143747-11b9eff30ea9/go.mod h1:DyEu2iuLBnb/T51BlsiO3yLYdJC6UbGMrIkqK1KmQxM= +github.com/ferranbt/fastssz v0.0.0-20210905181407-59cf6761a7d5 h1:6dVcS0LktRSyEEgldFY4N9J17WjUoiJStttH+RZj0Wo= +github.com/ferranbt/fastssz v0.0.0-20210905181407-59cf6761a7d5/go.mod h1:S8yiDeAXy8f88W4Ul+0dBMPx49S05byYbmZD6Uv94K4= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= +github.com/flynn/noise v1.0.0 h1:DlTHqmzmvcEiKj+4RYo/imoswx/4r6iBlCMfVtrMXpQ= +github.com/flynn/noise v1.0.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= +github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= +github.com/frankban/quicktest v1.7.2/go.mod h1:jaStnuzAqU1AJdCO0l53JDCJrVDKcS03DbaAcR7Ks/o= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= -github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= +github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= +github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= +github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= +github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= +github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= +github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= +github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= +github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= +github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= +github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-yaml/yaml v2.1.0+incompatible h1:RYi2hDdss1u4YE7GwixGzWwVo47T8UQwnTLB6vQiq+o= +github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= +github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt/v4 v4.3.0 h1:kHL1vqdqWNfATmA0FNMdmZNMyZI1U6O31X4rlIPoBog= +github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -218,6 +387,9 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -236,6 +408,7 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -250,12 +423,21 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= +github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= +github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -265,40 +447,98 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20220829040838-70bd9ae97f40 h1:ykKxL12NZd3JmWZnyqarJGsF73M9Xhtrik/FEtEeFRE= -github.com/google/pprof v0.0.0-20220829040838-70bd9ae97f40/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20221203041831-ce31453925ec h1:fR20TYVVwhK4O7r7y+McjRYyaTH6/vjwJOajE+XhlzM= +github.com/google/pprof v0.0.0-20221203041831-ce31453925ec/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.5 h1:kxhtnfFVi+rYdOALN0B3k9UT86zVJKfBimRaciULW4I= -github.com/google/uuid v1.1.5/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= +github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0= github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.2.2 h1:FlFbCRLd5Jr4iYXZufAvgWN6Ao0JrI5chLINnUXDDr0= +github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/herumi/bls-eth-go-binary v0.0.0-20210130185500-57372fb27371/go.mod h1:luAnRm3OsMQeokhGzpYmc0ZKwawY7o87PUEP11Z7r7U= +github.com/herumi/bls-eth-go-binary v0.0.0-20210917013441-d37c07cfda4e h1:wCMygKUQhmcQAjlk2Gquzq6dLmyMv2kF+llRspoRgrk= +github.com/herumi/bls-eth-go-binary v0.0.0-20210917013441-d37c07cfda4e/go.mod h1:luAnRm3OsMQeokhGzpYmc0ZKwawY7o87PUEP11Z7r7U= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.2.0 h1:gpSYcPLWGv4sG43I2mVLiDZCNDh/EpGjSk8tmtxitHM= github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= +github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY= github.com/influxdata/influxdb v1.8.3 h1:WEypI1BQFTT4teLM+1qkEcvUi0dAvopAI/ir0vAiBg8= github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI= github.com/influxdata/influxdb-client-go/v2 v2.4.0 h1:HGBfZYStlx3Kqvsv1h2pJixbCl/jhnFtxpKFAv9Tu5k= github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/influxdata/influxql v1.1.1-0.20200828144457-65d3ef77d385/go.mod h1:gHp9y86a/pxhjJ+zMjNXiQAA197Xk9wLxaz+fGG+kWk= github.com/influxdata/line-protocol v0.0.0-20180522152040-32c6aa80de5e/go.mod h1:4kt73NQhadE3daL3WhR5EJ/J2ocX0PZzwxQ0gXJ7oFE= github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= @@ -308,44 +548,88 @@ github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19y github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE= github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0= github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po= +github.com/ipfs/go-cid v0.3.2 h1:OGgOd+JCFM+y1DjWPmVH+2/4POtpDzwcr7VgnB7mZXc= +github.com/ipfs/go-cid v0.3.2/go.mod h1:gQ8pKqT/sUxGY+tIwy1RPpAojYu7jAyCp5Tz1svoupw= +github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= +github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= +github.com/ipfs/go-log v1.0.5 h1:2dOuUCB1Z7uoczMWgAyDck5JLb72zHzrMnGnCNNbvY8= +github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= +github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= +github.com/ipfs/go-log/v2 v2.5.1 h1:1XdUzF7048prq4aBjDQQ4SL5RxftpRGdXhNRwKSAlcY= +github.com/ipfs/go-log/v2 v2.5.1/go.mod h1:prSpmC1Gpllc9UYWxDiZDreBYw7zp4Iqp1kOLU9U5UI= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= +github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= +github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e h1:UvSe12bq+Uj2hWd8aOlwPmoZ+CITRFrdit+sDGfAg8U= github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= +github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= +github.com/jhump/protoreflect v1.8.1/go.mod h1:7GcYQDdMU/O/BBrl/cX6PNHpXh6cenjd8pneu5yW7Tg= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a h1:FaWFmfWdAUKbSCtOU2QjDaorUexogfaMgbipgYATUMU= +github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0= +github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213 h1:qGQQKEcAR99REcMpsXCp3lJ03zYT1PkRd3kQGPn9GVg= +github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw= github.com/karalabe/usb v0.0.2 h1:M6QQBNxF+CQ8OFvxrT90BA0qBOXymndZnk5q235mFc4= github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.9.8/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.10.1/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= +github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.1 h1:U33DW0aiEj633gHYw3LoDNfkDiYnE5Q8M/TKJn2f2jI= +github.com/klauspost/cpuid/v2 v2.2.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= +github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= +github.com/klauspost/reedsolomon v1.9.3/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= +github.com/koron/go-ssdp v0.0.3 h1:JivLMY45N76b4p/vsWGOKewBQu6uf39y8l+AQ7sDKx8= +github.com/koron/go-ssdp v0.0.3/go.mod h1:b2MxI6yh02pKrsyNoQUsk4+YNikaGhe4894J+Q5lDvA= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= @@ -355,133 +639,414 @@ github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4F github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= +github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= +github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= +github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= +github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= +github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= +github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= +github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= +github.com/libp2p/go-libp2p v0.24.0 h1:DQk/5bBon+yUVIGTeRVBmOYpZzoBHx/VTC0xoLgJGG4= +github.com/libp2p/go-libp2p v0.24.0/go.mod h1:28t24CYDlnBs23rIs1OclU89YbhgibrBq2LFbMe+cFw= +github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= +github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= +github.com/libp2p/go-libp2p-pubsub v0.8.0 h1:KygfDpaa9AeUPGCVcpVenpXNFauDn+5kBYu3EjcL3Tg= +github.com/libp2p/go-libp2p-pubsub v0.8.0/go.mod h1:e4kT+DYjzPUYGZeWk4I+oxCSYTXizzXii5LDRRhjKSw= +github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= +github.com/libp2p/go-mplex v0.7.0 h1:BDhFZdlk5tbr0oyFq/xv/NPGfjbnrsDam1EvutpBDbY= +github.com/libp2p/go-mplex v0.7.0/go.mod h1:rW8ThnRcYWft/Jb2jeORBmPd6xuG3dGxWN/W168L9EU= +github.com/libp2p/go-msgio v0.2.0 h1:W6shmB+FeynDrUVl2dgFQvzfBZcXiyqY4VmpQLu9FqU= +github.com/libp2p/go-msgio v0.2.0/go.mod h1:dBVM1gW3Jk9XqHkU4eKdGvVHdLa51hoGfll6jMJMSlY= +github.com/libp2p/go-nat v0.1.0 h1:MfVsH6DLcpa04Xr+p8hmVRG4juse0s3J8HyNWYHffXg= +github.com/libp2p/go-nat v0.1.0/go.mod h1:X7teVkwRHNInVNWQiO/tAiAVRwSr5zoRz4YSTC3uRBM= +github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= +github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= +github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= +github.com/libp2p/go-openssl v0.1.0 h1:LBkKEcUv6vtZIQLVTegAil8jbNpJErQ9AnT+bWV+Ooo= +github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc= +github.com/libp2p/go-reuseport v0.2.0 h1:18PRvIMlpY6ZK85nIAicSBuXXvrYoSw3dsBAR7zc560= +github.com/libp2p/go-reuseport v0.2.0/go.mod h1:bvVho6eLMm6Bz5hmU0LYN3ixd3nPPvtIlaURZZgOY4k= +github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= +github.com/libp2p/go-yamux/v4 v4.0.0 h1:+Y80dV2Yx/kv7Y7JKu0LECyVdMXm1VUoko+VQ9rBfZQ= +github.com/libp2p/go-yamux/v4 v4.0.0/go.mod h1:NWjl8ZTLOGlozrXSOZ/HlfG++39iKNnM5wwmtQP1YB4= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= +github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/lucas-clemente/quic-go v0.31.0 h1:MfNp3fk0wjWRajw6quMFA3ap1AVtlU+2mtwmbVogB2M= +github.com/lucas-clemente/quic-go v0.31.0/go.mod h1:0wFbizLgYzqHqtlyxyCaJKlE7bYgE6JQ+54TLd/Dq2g= +github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= +github.com/lunixbochs/vtclean v1.0.0 h1:xu2sLAri4lGiovBDQKxl5mrXyESr3gUr5m5SM5+LVb8= +github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/manifoldco/promptui v0.7.0 h1:3l11YT8tm9MnwGFQ4kETwkzpAwY2Jt9lCrumCUW4+z4= +github.com/manifoldco/promptui v0.7.0/go.mod h1:n4zTdgP0vr0S3w7/O/g98U+e0gwLScEXGwov2nIKuGQ= +github.com/marten-seemann/qpack v0.3.0 h1:UiWstOgT8+znlkDPOg2+3rIuYXJ2CnGDkGUXN6ki6hE= +github.com/marten-seemann/qtls-go1-18 v0.1.3 h1:R4H2Ks8P6pAtUagjFty2p7BVHn3XiwDAl7TTQf5h7TI= +github.com/marten-seemann/qtls-go1-18 v0.1.3/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4= +github.com/marten-seemann/qtls-go1-19 v0.1.1 h1:mnbxeq3oEyQxQXwI4ReCgW9DPoPR94sNlqWoDZnjRIE= +github.com/marten-seemann/qtls-go1-19 v0.1.1/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI= +github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk= +github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= +github.com/marten-seemann/webtransport-go v0.4.1 h1:8Ir7OoAvtp79yxQpa3foTKIPuoH+0eKpisHObJyu9Sk= github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d h1:oNAwILwmgWKFpuU+dXvI6dl9jG2mAWAZLX3r9s0PPiw= github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= +github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= -github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= +github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= +github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= +github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= +github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= +github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= +github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b/go.mod h1:lxPUiZwKoFL8DUUmalo2yJJUCxbPKtm8OKfqr2/FTNU= +github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc h1:PTfri+PuQmWDqERdnNMiD9ZejrlswWrCpBEZgWOiTrc= +github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc/go.mod h1:cGKTAVKx4SxOuR/czcZ/E2RSJ3sfHs8FpHhQ5CWMf9s= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/highwayhash v1.0.1 h1:dZ6IIu8Z14VlC0VpfKofAhCy74wu/Qb5gcn52yWoz/0= +github.com/minio/highwayhash v1.0.1/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= +github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= +github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= +github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= +github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= +github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= +github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= +github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= +github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= +github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= +github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= +github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= +github.com/multiformats/go-multiaddr v0.8.0 h1:aqjksEcqK+iD/Foe1RRFsGZh8+XFiGo7FgUCZlpv3LU= +github.com/multiformats/go-multiaddr v0.8.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs= +github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= +github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= +github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= +github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= +github.com/multiformats/go-multibase v0.1.1 h1:3ASCDsuLX8+j4kx58qnJ4YFq/JWTJpCyDW27ztsVTOI= +github.com/multiformats/go-multibase v0.1.1/go.mod h1:ZEjHE+IsUrgp5mhlEAYjMtZwK1k4haNkcaPg9aoe1a8= +github.com/multiformats/go-multicodec v0.7.0 h1:rTUjGOwjlhGHbEMbPoSUJowG1spZTVsITRANCjKTUAQ= +github.com/multiformats/go-multicodec v0.7.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw= +github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= +github.com/multiformats/go-multihash v0.2.1 h1:aem8ZT0VA2nCHHk7bPJ1BjUbHNciqZC/d16Vve9l108= +github.com/multiformats/go-multihash v0.2.1/go.mod h1:WxoMcYG85AZVQUyRyo9s4wULvW5qrI9vb2Lt6evduFc= +github.com/multiformats/go-multistream v0.3.3 h1:d5PZpjwRgVlbwfdTDjife7XszfZd8KYWfROYFlGcR8o= +github.com/multiformats/go-multistream v0.3.3/go.mod h1:ODRoqamLUsETKS9BNcII4gcRsJBU5VAwRIv7O39cEXg= +github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= +github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= +github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/naoina/go-stringutil v0.1.0 h1:rCUeRUHjBjGTSHl0VC00jUPLz8/F9dDzYI70Hzifhks= github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 h1:shk/vn9oCoOTmwcouEdwIeOtOGA/ELRUw/GwvxwfT+0= github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= -github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= +github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= +github.com/nishanths/predeclared v0.0.0-20200524104333-86fad755b4d3/go.mod h1:nt3d53pc1VYcphSCIaYAJtnPYnr3Zyn8fMq2wvPGPso= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= -github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.5.1 h1:auzK7OI497k6x4OvWq+TKAcpcSAlod0doAH72oIN0Jw= +github.com/onsi/ginkgo/v2 v2.5.1/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/openconfig/gnmi v0.0.0-20190823184014-89b2bf29312c/go.mod h1:t+O9It+LKzfOAhKTT5O0ehDix+MTqbtT0T9t+7zzOvc= +github.com/openconfig/reference v0.0.0-20190727015836-8dfd928c9696/go.mod h1:ym2A+zigScwkSEb/cVQB0/ZMpU3rqiH6X7WRRsxgOGw= +github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= +github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= +github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/panjf2000/ants/v2 v2.4.5 h1:kcGvjXB7ea0MrzzszpnlVFthhYKoFxLi75nRbsq01HY= github.com/panjf2000/ants/v2 v2.4.5/go.mod h1:f6F0NZVFsGCp5A7QW/Zj/m92atWwOkY0OIhFxRNFr4A= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= +github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/paulbellamy/ratecounter v0.2.0/go.mod h1:Hfx1hDpSGoqxkVVpBi/IlYD7kChlfo5C6hzIHwPqfFE= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= -github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 h1:oYW+YCJ1pachXTQmzR3rNLYGGz4g/UgFcjb28p/viDM= -github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= +github.com/peterh/liner v1.2.0 h1:w/UPXyl5GfahFxcTOz2j9wCIHNI+pUPr2laqpojKNCg= +github.com/peterh/liner v1.2.0/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrec/lz4 v2.4.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pkg/profile v1.5.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= +github.com/prometheus/client_golang v1.4.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU= github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= -github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI= +github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y= +github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.0.10/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= -github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= -github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA= +github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= +github.com/prometheus/prom2json v1.3.0 h1:BlqrtbT9lLH3ZsOVhXPsHzFrApCTKRifB7gjJuypu6Y= +github.com/prometheus/prom2json v1.3.0/go.mod h1:rMN7m0ApCowcoDlypBHlkNbp5eJQf/+1isKykIP5ZnM= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/prometheus/tsdb v0.10.0 h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38ic= +github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4= +github.com/prysmaticlabs/fastssz v0.0.0-20220628121656-93dfe28febab h1:Y3PcvUrnneMWLuypZpwPz8P70/DQsz6KgV9JveKpyZs= +github.com/prysmaticlabs/fastssz v0.0.0-20220628121656-93dfe28febab/go.mod h1:MA5zShstUwCQaE9faGHgCGvEWUbG87p4SAXINhmCkvg= +github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7 h1:0tVE4tdWQK9ZpYygoV7+vS6QkDvQVySboMVEIxBJmXw= +github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7/go.mod h1:wmuf/mdK4VMD+jA9ThwcUKjg3a2XWM9cVfFYjDyY4j4= +github.com/prysmaticlabs/gohashtree v0.0.2-alpha h1:hk5ZsDQuSkyUMhTd55qB396P1+dtyIKiSwMmYE/hyEU= +github.com/prysmaticlabs/gohashtree v0.0.2-alpha/go.mod h1:4pWaT30XoEx1j8KNJf3TV+E3mQkaufn7mf+jRNb/Fuk= +github.com/prysmaticlabs/grpc-gateway/v2 v2.3.1-0.20210702154020-550e1cd83ec1 h1:xcu59yYL6AWWTl6jtejBfE0y8uF35fArCBeZjRlvJss= +github.com/prysmaticlabs/grpc-gateway/v2 v2.3.1-0.20210702154020-550e1cd83ec1/go.mod h1:IOyTYjcIO0rkmnGBfJTL0NJ11exy/Tc2QEuv7hCXp24= +github.com/prysmaticlabs/prombbolt v0.0.0-20210126082820-9b7adba6db7c h1:9PHRCuO/VN0s9k+RmLykho7AjDxblNYI5bYKed16NPU= +github.com/prysmaticlabs/prombbolt v0.0.0-20210126082820-9b7adba6db7c/go.mod h1:ZRws458tYHS/Zs936OQ6oCrL+Ict5O4Xpwve1UQ6C9M= +github.com/prysmaticlabs/protoc-gen-go-cast v0.0.0-20230228205207-28762a7b9294 h1:q9wE0ZZRdTUAAeyFP/w0SwBEnCqlVy2+on6X2/e+eAU= +github.com/prysmaticlabs/prysm/v3 v3.2.2 h1:8lC6vX4F/gVPVOrOZ49SkHjxZIpl0XLziIvlFKdyLwA= +github.com/prysmaticlabs/prysm/v3 v3.2.2/go.mod h1:tk/LvCJpiq/EpMPkSJwE0OYBLnXOiMktEN+Xt1IIKkE= +github.com/r3labs/sse v0.0.0-20210224172625-26fe804710bc h1:zAsgcP8MhzAbhMnB1QQ2O7ZhWYVGYSR2iVcjzQuPV+o= +github.com/r3labs/sse v0.0.0-20210224172625-26fe804710bc/go.mod h1:S8xSOnV3CgpNrWd0GQ/OoQfMtlg2uPRSuTzcSGrzwK8= +github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= +github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563 h1:dY6ETXrvDG7Sa4vE8ZQG4yqWg6UnOcbqTAahkV813vQ= github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.3.4 h1:3Z3Eu6FGHZWSfNKJTOUiPatWwfc7DzJRU04jFUqJODw= +github.com/rivo/uniseg v0.3.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rjeczalik/notify v0.9.1 h1:CLCKso/QK1snAlnhNR/CNvNiFU2saUtjV0bx3EwNeCE= github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/schollz/progressbar/v3 v3.3.4 h1:nMinx+JaEm/zJz4cEyClQeAw5rsYSB5th3xv+5lV6Vg= +github.com/schollz/progressbar/v3 v3.3.4/go.mod h1:Rp5lZwpgtYmlvmGo1FyDwXMqagyRBQYSDwzlP9QDu84= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= +github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= +github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= +github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= +github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= +github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw= +github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI= +github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= +github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag= +github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg= +github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw= +github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y= +github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= +github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q= +github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ= +github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I= +github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0= +github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= +github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk= +github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= +github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= +github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v1.0.1-0.20201006035406-b97b5ead31f7/go.mod h1:yk5b0mALVusDL5fMM6Rd1wgnoO5jUPhwsQ6LQAJTidQ= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4 h1:Gb2Tyox57NRNuZ2d3rmvB3pcmbu7O1RS3m8WRx7ilrg= -github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= +github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -491,57 +1056,162 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= -github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/supranational/blst v0.3.8-0.20220526154634-513d2456b344 h1:m+8fKfQwCAy1QjzINvKe/pYtLjo2dl59x2w9YSEJxuY= +github.com/supranational/blst v0.3.8-0.20220526154634-513d2456b344/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= +github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= +github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= +github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU= +github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4= github.com/tendermint/go-amino v0.14.1 h1:o2WudxNfdLNBwMyl2dqOJxiro5rfrEaU0Ugs6offJMk= github.com/tendermint/go-amino v0.14.1/go.mod h1:i/UKE5Uocn+argJJBb12qTZsCDBcAYMbR92AaJVmKso= github.com/tendermint/iavl v0.12.0 h1:xcaFAr+ycqCj7WN1RzL2EfcBioRDOHcU1oWcg83K028= github.com/tendermint/iavl v0.12.0/go.mod h1:EoKMMv++tDOL5qKKVnoIqtVPshRrEPeJ0WsgDOLAauM= +github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e h1:cR8/SYRgyQCt5cNCMniB/ZScMkhI9nk8U5C7SbISXjo= +github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e/go.mod h1:Tu4lItkATkonrYuvtVjG0/rhy15qrNGNTjPdaphtZ/8= +github.com/tidwall/gjson v1.10.2 h1:APbLGOM0rrEkd8WBw9C24nllro4ajFuJu0Sc9hRz8Bo= +github.com/tidwall/gjson v1.10.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/tinylru v1.1.0 h1:XY6IUfzVTU9rpwdhKUF6nQdChgCdGjkMfLzbWyiau6I= +github.com/tidwall/tinylru v1.1.0/go.mod h1:3+bX+TJ2baOLMWTnlyNWHh4QMnFyARg2TLTQ6OFbzw8= +github.com/tidwall/wal v1.1.7 h1:emc1TRjIVsdKKSnpwGBAcsAGg0767SvUk8+ygx7Bb+4= +github.com/tidwall/wal v1.1.7/go.mod h1:r6lR1j27W9EPalgHiB7zLJDYu3mzW5BQP5KrzBpYY/E= github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= -github.com/tklauser/go-sysconf v0.3.5 h1:uu3Xl4nkLzQfXNsWn15rPc/HQCJKObbt1dKJeWp3vU4= -github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= -github.com/tklauser/numcpus v0.2.2 h1:oyhllyrScuYI6g+h/zUvNXNp1wy7x8qQy3t/piefldA= -github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= -github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef h1:wHSqTBrZW24CsNJDfeh9Ex6Pm0Rcpc7qrgKBiL44vF4= -github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= +github.com/tjfoc/gmsm v1.3.0/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w= +github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw= +github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk= +github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ= +github.com/tklauser/numcpus v0.5.0 h1:ooe7gN0fg6myJ0EKoTAf5hebTZrH52px3New/D9iJ+A= +github.com/tklauser/numcpus v0.5.0/go.mod h1:OGzpTxpcIMNGYQdit2BYL1pvk/dSOaJWjKoflh+RQjo= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/trailofbits/go-mutexasserts v0.0.0-20200708152505-19999e7d3cef h1:8LRP+2JK8piIUU16ZDgWDXwjJcuJNTtCzadjTZj8Jf0= +github.com/trailofbits/go-mutexasserts v0.0.0-20200708152505-19999e7d3cef/go.mod h1:+SV/613m53DNAmlXPTWGZhIyt4E/qDvn9g/lOPRiy0A= +github.com/twitchtv/twirp v7.1.0+incompatible/go.mod h1:RRJoFSAmTEh2weEqWtpPE3vFK5YBhA6bqp2l1kfCC5A= +github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= +github.com/uber/jaeger-client-go v2.25.0+incompatible h1:IxcNZ7WRY1Y3G4poYlx24szfsn/3LvK9QHCq9oQw8+U= +github.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa h1:5SqCsI/2Qya2bCzK15ozrqo2sZxkh0FHynJZOTVoV6Q= +github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= +github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= +github.com/wealdtech/go-bytesutil v1.1.1 h1:ocEg3Ke2GkZ4vQw5lp46rmO+pfqCCTgq35gqOy8JKVc= +github.com/wealdtech/go-bytesutil v1.1.1/go.mod h1:jENeMqeTEU8FNZyDFRVc7KqBdRKSnJ9CCh26TcuNb9s= +github.com/wealdtech/go-eth2-types/v2 v2.5.2 h1:tiA6T88M6XQIbrV5Zz53l1G5HtRERcxQfmET225V4Ls= +github.com/wealdtech/go-eth2-types/v2 v2.5.2/go.mod h1:8lkNUbgklSQ4LZ2oMSuxSdR7WwJW3L9ge1dcoCVyzws= +github.com/wealdtech/go-eth2-util v1.6.3 h1:2INPeOR35x5LdFFpSzyw954WzTD+DFyHe3yKlJnG5As= +github.com/wealdtech/go-eth2-util v1.6.3/go.mod h1:0hFMj/qtio288oZFHmAbCnPQ9OB3c4WFzs5NVPKTY4k= +github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.1.3 h1:SxrDVSr+oXuT1x8kZt4uWqNCvv5xXEGV9zd7cuSrZS8= +github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.1.3/go.mod h1:qiIimacW5NhVRy8o+YxWo9YrecXqDAKKbL0+sOa0SJ4= +github.com/wealdtech/go-eth2-wallet-types/v2 v2.8.2 h1:264/meVYWt1wFw6Mtn+xwkZkXjID42gNra4rycoiDXI= +github.com/wealdtech/go-eth2-wallet-types/v2 v2.8.2/go.mod h1:k6kmiKWSWBTd4OxFifTEkPaBLhZspnO2KFD5XJY9nqg= +github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee h1:lYbXeSvJi5zk5GLKVuid9TVjS9a0OmLIDKTfoZBL6Ow= +github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee/go.mod h1:m2aV4LZI4Aez7dP5PMyVKEHhUyEJ/RjmPEDOpDvudHg= +github.com/willf/bitset v1.1.3 h1:ekJIKh6+YbUIVt9DfNbkR5d6aFcFTLDRyJNAACURBg8= github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= +github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= +github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +github.com/xtaci/kcp-go v5.4.20+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE= +github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.6/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= +go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/dig v1.15.0 h1:vq3YWr8zRj1eFGC7Gvf907hE0eRjPTZ1d3xHadD6liE= +go.uber.org/dig v1.15.0/go.mod h1:pKHs0wMynzL6brANhB2hLMro+zalv1osARTviTcqHLM= +go.uber.org/fx v1.18.2 h1:bUNI6oShr+OVFQeU8cDNbnN7VFsu+SsjHzUF51V/GAU= +go.uber.org/fx v1.18.2/go.mod h1:g0V1KMQ66zIRk8bLu3Ea5Jt2w/cHlOIp4wdRsgh0JaY= +go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= +go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= +go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= +golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200602180216-279210d13fed/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -557,9 +1227,13 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= +golang.org/x/exp v0.0.0-20230206171751-46f607a40771 h1:xP7rWLUr1e1n2xkK5YB4LI0hPEy3LJC6Wk+D4pGlOJg= +golang.org/x/exp v0.0.0-20230206171751-46f607a40771/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -570,6 +1244,8 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -579,15 +1255,24 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -596,6 +1281,9 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191116160921-f9c825593386/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -603,6 +1291,7 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= @@ -610,24 +1299,33 @@ golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= -golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.3.0 h1:6l90koy8/LaBLmLu8jpHeHexzMwEita0zFfYlggy2F8= +golang.org/x/oauth2 v0.3.0/go.mod h1:rQrIauxkUhJ6CuwEXwymO2/eh4xz2ZWF1nBkcxS+tGk= +golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -637,18 +1335,28 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -657,54 +1365,76 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200219091948-cb0a6d8edb6c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= -golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg= -golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -714,16 +1444,22 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= -golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220922220347-f3bd1da661af h1:Yx9k8YCG3dvF87UAn2tu2HQLf2dt/eR1bXxpLMWeH+Y= +golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -741,6 +1477,9 @@ golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -748,6 +1487,7 @@ golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -755,6 +1495,7 @@ golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200221224223-e1da425f72fd/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= @@ -763,26 +1504,38 @@ golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWc golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200717024301-6ddee64345a6/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= gonum.org/v1/netlib v0.0.0-20181029234149-ec6d1f5cefe6/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= +google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -799,17 +1552,28 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.34.0 h1:k40adF3uR+6x/+hO5Dh4ZFUqFp67vxvbpafFiJxl10A= +google.golang.org/api v0.34.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= +google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= @@ -823,24 +1587,38 @@ google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200218151345-dad8c97a84f5/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987 h1:PDIOdWxZ8eRizhKa1AAvY53xsvLB1cWorMjslvY3VA8= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210207032614-bba0dbe2a9ea/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210426193834-eac7f76ac494/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84 h1:R1r5J0u6Cx+RNl/6mezTw6oA14cmKC96FeUwL6A9bd4= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= @@ -848,8 +1626,18 @@ google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0 h1:T7P4R73V3SSDPhH7WW7ATbfViLtmamH0DKrP3f9AuDI= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.35.0-dev.0.20201218190559-666aea1fb34c/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.0.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -860,24 +1648,44 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.25.1-0.20200805231151-a709e31e5d12/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.25.1-0.20201208041424-160c7477e0e8/go.mod h1:hFxJC2f0epmp1elRCiEGJTKAWbwxZ2nvqZdHl3FQXCY= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/bsm/ratelimit.v1 v1.0.0-20160220154919-db14e161995a/go.mod h1:KF9sEfUPAXdG8Oev9e99iLGnl2uJMjc5B+4y3O7x610= +gopkg.in/cenkalti/backoff.v1 v1.1.0 h1:Arh75ttbsvlpVA7WtVpH4u9h6Zl46xuptxqLxPiSo4Y= +gopkg.in/cenkalti/backoff.v1 v1.1.0/go.mod h1:J6Vskwqd+OMVJl8C33mmtxTBs2gyzfv7UDAkHu8BrjI= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/d4l3k/messagediff.v1 v1.2.1 h1:70AthpjunwzUiarMHyED52mj9UwtAnE89l1Gmrt3EU0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= +gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= +gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4= +gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= +gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= +gopkg.in/redis.v4 v4.2.4/go.mod h1:8KREHdypkCEojGKQcjMqAODMICIVwZAONWq8RowTITA= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/urfave/cli.v1 v1.20.0 h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0= gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -889,8 +1697,11 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -899,7 +1710,36 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= +k8s.io/api v0.18.3 h1:2AJaUQdgUZLoDZHrun21PW2Nx9+ll6cUzvn3IKhSIn0= +k8s.io/api v0.18.3/go.mod h1:UOaMwERbqJMfeeeHc8XJKawj4P9TgDRnViIqqBeH2QA= +k8s.io/apimachinery v0.18.3 h1:pOGcbVAhxADgUYnjS08EFXs9QMl8qaH5U4fr5LGUrSk= +k8s.io/apimachinery v0.18.3/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko= +k8s.io/client-go v0.18.3 h1:QaJzz92tsN67oorwzmoB0a9r9ZVHuD5ryjbCKP0U22k= +k8s.io/client-go v0.18.3/go.mod h1:4a/dpQEvzAhT1BbuWW09qvIaGw6Gbu1gZYiQZIi1DMw= +k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= +k8s.io/klog/v2 v2.80.0 h1:lyJt0TWMPaGoODa8B8bUuxgHS3W/m/bNr2cca3brA/g= +k8s.io/klog/v2 v2.80.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= +k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/utils v0.0.0-20200520001619-278ece378a50 h1:ZtTUW5+ZWaoqjR3zOpRa7oFJ5d4aA22l4me/xArfOIc= +k8s.io/utils v0.0.0-20200520001619-278ece378a50/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= +lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0 h1:dOmIZBMfhcHS09XZkMyUgkq5trg3/jRyJYFZUiaOp8E= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= +sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= +sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go index 889370440e..244279624b 100644 --- a/internal/ethapi/backend.go +++ b/internal/ethapi/backend.go @@ -93,6 +93,8 @@ type Backend interface { SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription + SubscribeNewVoteEvent(chan<- core.NewVoteEvent) event.Subscription + SubscribeFinalizedHeaderEvent(ch chan<- core.FinalizedHeaderEvent) event.Subscription ChainConfig() *params.ChainConfig Engine() consensus.Engine diff --git a/les/api_backend.go b/les/api_backend.go index 0e02a03050..e354b19fe6 100644 --- a/les/api_backend.go +++ b/les/api_backend.go @@ -36,6 +36,7 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/light" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" ) @@ -231,6 +232,11 @@ func (b *LesApiBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.S return b.eth.txPool.SubscribeNewTxsEvent(ch) } +func (b *LesApiBackend) SubscribeNewVoteEvent(ch chan<- core.NewVoteEvent) event.Subscription { + log.Error("light ethereum does not support SubscribeNewVoteEvent") + return nil +} + func (b *LesApiBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription { return b.eth.blockchain.SubscribeChainEvent(ch) } @@ -239,6 +245,10 @@ func (b *LesApiBackend) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) e return b.eth.blockchain.SubscribeChainHeadEvent(ch) } +func (b *LesApiBackend) SubscribeFinalizedHeaderEvent(ch chan<- core.FinalizedHeaderEvent) event.Subscription { + return b.eth.blockchain.SubscribeFinalizedHeaderEvent(ch) +} + func (b *LesApiBackend) SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription { return b.eth.blockchain.SubscribeChainSideEvent(ch) } diff --git a/light/lightchain.go b/light/lightchain.go index 7ce0b2698d..086b673d30 100644 --- a/light/lightchain.go +++ b/light/lightchain.go @@ -50,17 +50,18 @@ var ( // headers, downloading block bodies and receipts on demand through an ODR // interface. It only does header validation during chain insertion. type LightChain struct { - hc *core.HeaderChain - indexerConfig *IndexerConfig - chainDb ethdb.Database - engine consensus.Engine - odr OdrBackend - chainFeed event.Feed - chainSideFeed event.Feed - chainHeadFeed event.Feed - scope event.SubscriptionScope - genesisBlock *types.Block - forker *core.ForkChoice + hc *core.HeaderChain + indexerConfig *IndexerConfig + chainDb ethdb.Database + engine consensus.Engine + odr OdrBackend + chainFeed event.Feed + chainSideFeed event.Feed + chainHeadFeed event.Feed + finalizedHeaderFeed event.Feed + scope event.SubscriptionScope + genesisBlock *types.Block + forker *core.ForkChoice bodyCache *lru.Cache // Cache for the most recent block bodies bodyRLPCache *lru.Cache // Cache for the most recent block bodies in RLP encoded format @@ -370,6 +371,8 @@ func (lc *LightChain) postChainEvents(events []interface{}) { lc.chainHeadFeed.Send(core.ChainHeadEvent{Block: ev.Block}) } lc.chainFeed.Send(ev) + case core.FinalizedHeaderEvent: + lc.finalizedHeaderFeed.Send(ev) case core.ChainSideEvent: lc.chainSideFeed.Send(ev) } @@ -456,6 +459,9 @@ func (lc *LightChain) InsertHeaderChain(chain []*types.Header, checkFreq int) (i case core.CanonStatTy: lc.chainFeed.Send(core.ChainEvent{Block: block, Hash: block.Hash()}) lc.chainHeadFeed.Send(core.ChainHeadEvent{Block: block}) + if posa, ok := lc.Engine().(consensus.PoSA); ok { + lc.finalizedHeaderFeed.Send(core.FinalizedHeaderEvent{Header: posa.GetFinalizedHeader(lc, block.Header())}) + } case core.SideStatTy: lc.chainSideFeed.Send(core.ChainSideEvent{Block: block}) } @@ -468,6 +474,19 @@ func (lc *LightChain) CurrentHeader() *types.Header { return lc.hc.CurrentHeader() } +// GetJustifiedNumber returns the highest justified blockNumber on the branch including and before `header` +func (lc *LightChain) GetJustifiedNumber(header *types.Header) uint64 { + if p, ok := lc.engine.(consensus.PoSA); ok { + justifiedBlockNumber, _, err := p.GetJustifiedNumberAndHash(lc.hc, header) + if err == nil { + return justifiedBlockNumber + } + } + // return 0 when err!=nil + // so the input `header` will at a disadvantage during reorg + return 0 +} + // GetTd retrieves a block's total difficulty in the canonical chain from the // database by hash and number, caching it if found. func (lc *LightChain) GetTd(hash common.Hash, number uint64) *big.Int { @@ -588,6 +607,11 @@ func (lc *LightChain) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) eve return lc.scope.Track(lc.chainHeadFeed.Subscribe(ch)) } +// SubscribeFinalizedHeaderEvent registers a subscription of FinalizedHeaderEvent. +func (lc *LightChain) SubscribeFinalizedHeaderEvent(ch chan<- core.FinalizedHeaderEvent) event.Subscription { + return lc.scope.Track(lc.finalizedHeaderFeed.Subscribe(ch)) +} + // SubscribeChainSideEvent registers a subscription of ChainSideEvent. func (lc *LightChain) SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription { return lc.scope.Track(lc.chainSideFeed.Subscribe(ch)) diff --git a/mobile/ethclient.go b/mobile/ethclient.go index 662125c4ad..59e39e53ec 100644 --- a/mobile/ethclient.go +++ b/mobile/ethclient.go @@ -148,6 +148,74 @@ func (ec *EthereumClient) SubscribeNewHead(ctx *Context, handler NewHeadHandler, return &Subscription{rawSub}, nil } +// NewFinalizedHeaderHandler is a client-side subscription callback to invoke on events and +// subscription failure. +type NewFinalizedHeaderHandler interface { + OnNewFinalizedHeader(header *Header) + OnError(failure string) +} + +// SubscribeNewFinalizedHeader subscribes to notifications about the current blockchain finalized header +// on the given channel. +func (ec *EthereumClient) SubscribeNewFinalizedHeader(ctx *Context, handler NewFinalizedHeaderHandler, buffer int) (sub *Subscription, _ error) { + // Subscribe to the event internally + ch := make(chan *types.Header, buffer) + rawSub, err := ec.client.SubscribeNewFinalizedHeader(ctx.context, ch) + if err != nil { + return nil, err + } + // Start up a dispatcher to feed into the callback + go func() { + for { + select { + case header := <-ch: + handler.OnNewFinalizedHeader(&Header{header}) + + case err := <-rawSub.Err(): + if err != nil { + handler.OnError(err.Error()) + } + return + } + } + }() + return &Subscription{rawSub}, nil +} + +// NewVoteHandler is a client-side subscription callback to invoke on events and +// subscription failure. +type NewVoteHandler interface { + OnNewVote(vote *types.VoteEnvelope) + OnError(failure string) +} + +// SubscribeNewVotes subscribes to notifications about the new votes into the vote pool +// on the given channel. +func (ec *EthereumClient) SubscribeNewVotes(ctx *Context, handler NewVoteHandler, buffer int) (sub *Subscription, _ error) { + // Subscribe to the event internally + ch := make(chan *types.VoteEnvelope, buffer) + rawSub, err := ec.client.SubscribeNewVotes(ctx.context, ch) + if err != nil { + return nil, err + } + // Start up a dispatcher to feed into the callback + go func() { + for { + select { + case vote := <-ch: + handler.OnNewVote(vote) + + case err := <-rawSub.Err(): + if err != nil { + handler.OnError(err.Error()) + } + return + } + } + }() + return &Subscription{rawSub}, nil +} + // State Access // GetBalanceAt returns the wei balance of the given account. diff --git a/node/config.go b/node/config.go index b4f1378c8f..cd87e26362 100644 --- a/node/config.go +++ b/node/config.go @@ -204,6 +204,17 @@ type Config struct { // EnableDoubleSignMonitor is a flag that whether to enable the double signature checker EnableDoubleSignMonitor bool `toml:",omitempty"` + + // BLSPasswordFile is the file that contains BLS wallet password. + BLSPasswordFile string `toml:",omitempty"` + + // BLSWalletDir is the file system folder of BLS wallet. The directory can + // be specified as a relative path, in which case it is resolved relative to the + // current directory. + BLSWalletDir string `toml:",omitempty"` + + // VoteJournalDir is the directory to store votes in the fast finality feature. + VoteJournalDir string `toml:",omitempty"` } // IPCEndpoint resolves an IPC endpoint based on a configured value, taking into diff --git a/p2p/discover/v5_udp.go b/p2p/discover/v5_udp.go index 1e9909559f..f98b8eadd9 100644 --- a/p2p/discover/v5_udp.go +++ b/p2p/discover/v5_udp.go @@ -54,7 +54,7 @@ type codecV5 interface { // Encode encodes a packet. Encode(enode.ID, string, v5wire.Packet, *v5wire.Whoareyou) ([]byte, v5wire.Nonce, error) - // decode decodes a packet. It returns a *v5wire.Unknown packet if decryption fails. + // Decode decodes a packet. It returns a *v5wire.Unknown packet if decryption fails. // The *enode.Node return value is non-nil when the input contains a handshake response. Decode([]byte, string) (enode.ID, *enode.Node, v5wire.Packet, error) } diff --git a/p2p/transport.go b/p2p/transport.go index de9e685ed4..f71fce070c 100644 --- a/p2p/transport.go +++ b/p2p/transport.go @@ -136,7 +136,7 @@ func (t *rlpxTransport) doProtoHandshake(our *protoHandshake) (their *protoHands // Writing our handshake happens concurrently, we prefer // returning the handshake read error. If the remote side // disconnects us early with a valid reason, we should return it - // as the error so it can be tracked elsewhere. + // as the error, so it can be tracked elsewhere. werr := make(chan error, 1) gopool.Submit(func() { werr <- Send(t, handshakeMsg, our) }) if their, err = readProtocolHandshake(t); err != nil { diff --git a/params/config.go b/params/config.go index f4c485f227..afd523a52c 100644 --- a/params/config.go +++ b/params/config.go @@ -74,6 +74,58 @@ var ( Ethash: new(EthashConfig), } + // just for prysm compile pass + // SepoliaChainConfig contains the chain parameters to run a node on the Sepolia test network. + SepoliaChainConfig = &ChainConfig{ + ChainID: big.NewInt(11155111), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: nil, + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + MirrorSyncBlock: big.NewInt(0), + BrunoBlock: big.NewInt(0), + EulerBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + Ethash: new(EthashConfig), + } + + // just for prysm compile pass + // GoerliChainConfig contains the chain parameters to run a node on the Görli test network. + GoerliChainConfig = &ChainConfig{ + ChainID: big.NewInt(5), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: nil, + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + RamanujanBlock: big.NewInt(0), + NielsBlock: big.NewInt(0), + MirrorSyncBlock: big.NewInt(0), + BrunoBlock: big.NewInt(0), + EulerBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(1_561_651), + MuirGlacierBlock: nil, + BerlinBlock: big.NewInt(4_460_644), + LondonBlock: big.NewInt(5_062_605), + ArrowGlacierBlock: nil, + Clique: &CliqueConfig{ + Period: 15, + Epoch: 30000, + }, + } + // MainnetTrustedCheckpoint contains the light client trusted checkpoint for the main network. MainnetTrustedCheckpoint = &TrustedCheckpoint{ SectionIndex: 413, @@ -116,6 +168,11 @@ var ( GibbsBlock: big.NewInt(23846001), PlanckBlock: big.NewInt(27281024), + // TODO modify blockNumber, make sure the blockNumber is not an integer multiple of 200 (epoch number) + // TODO Caution !!! it should be very careful !!! + BonehBlock: nil, + LynnBlock: nil, + Parlia: &ParliaConfig{ Period: 3, Epoch: 200, @@ -142,6 +199,12 @@ var ( NanoBlock: big.NewInt(23482428), MoranBlock: big.NewInt(23603940), PlanckBlock: big.NewInt(28196022), + + // TODO modify blockNumber, make sure the blockNumber is not an integer multiple of 200 (epoch number) + // TODO Caution !!! it should be very careful !!! + BonehBlock: nil, + LynnBlock: nil, + Parlia: &ParliaConfig{ Period: 3, Epoch: 200, @@ -169,6 +232,10 @@ var ( MoranBlock: nil, PlanckBlock: nil, + // TODO + BonehBlock: nil, + LynnBlock: nil, + Parlia: &ParliaConfig{ Period: 3, Epoch: 200, @@ -180,16 +247,17 @@ var ( // // This configuration is intentionally not using keyed fields to force anyone // adding flags to the config to also have to set these fields. - AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), new(EthashConfig), nil, nil} + + AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), new(EthashConfig), nil, nil} // AllCliqueProtocolChanges contains every protocol change (EIPs) introduced // and accepted by the Ethereum core developers into the Clique consensus. // // This configuration is intentionally not using keyed fields to force anyone // adding flags to the config to also have to set these fields. - AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), nil, nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil} + AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), nil, nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, big.NewInt(0), big.NewInt(0), nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil} - TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, new(EthashConfig), nil, nil} + TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), big.NewInt(0), new(EthashConfig), nil, nil} TestRules = TestChainConfig.Rules(new(big.Int), false) ) @@ -286,6 +354,8 @@ type ChainConfig struct { NanoBlock *big.Int `json:"nanoBlock,omitempty" toml:",omitempty"` // nanoBlock switch block (nil = no fork, 0 = already activated) MoranBlock *big.Int `json:"moranBlock,omitempty" toml:",omitempty"` // moranBlock switch block (nil = no fork, 0 = already activated) PlanckBlock *big.Int `json:"planckBlock,omitempty" toml:",omitempty"` // planckBlock switch block (nil = no fork, 0 = already activated) + BonehBlock *big.Int `json:"bonehBlock,omitempty" toml:",omitempty"` // bonehBlock switch block (nil = no fork, 0 = already activated) + LynnBlock *big.Int `json:"lynnBlock,omitempty" toml:",omitempty"` // lynnBlock switch block (nil = no fork, 0 = already activated) // Various consensus engines Ethash *EthashConfig `json:"ethash,omitempty" toml:",omitempty"` @@ -336,7 +406,8 @@ func (c *ChainConfig) String() string { default: engine = "unknown" } - return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Ramanujan: %v, Niels: %v, MirrorSync: %v, Bruno: %v, Berlin: %v, YOLO v3: %v, CatalystBlock: %v, London: %v, ArrowGlacier: %v, MergeFork:%v, Euler: %v, Gibbs: %v, Nano: %v, Moran: %v, Planck: %v, Engine: %v}", + + return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Ramanujan: %v, Niels: %v, MirrorSync: %v, Bruno: %v, Berlin: %v, YOLO v3: %v, CatalystBlock: %v, London: %v, ArrowGlacier: %v, MergeFork:%v, Euler: %v, Gibbs: %v, Nano: %v, Moran: %v, Planck: %v,Boneh: %v, Lynn: %v, Engine: %v}", c.ChainID, c.HomesteadBlock, c.DAOForkBlock, @@ -364,6 +435,8 @@ func (c *ChainConfig) String() string { c.NanoBlock, c.MoranBlock, c.PlanckBlock, + c.BonehBlock, + c.LynnBlock, engine, ) } @@ -453,6 +526,26 @@ func (c *ChainConfig) IsOnEuler(num *big.Int) bool { return configNumEqual(c.EulerBlock, num) } +// IsBoneh returns whether num is either equal to the first fast finality fork block or greater. +func (c *ChainConfig) IsBoneh(num *big.Int) bool { + return isForked(c.BonehBlock, num) +} + +// IsOnBoneh returns whether num is equal to the first fast finality fork block. +func (c *ChainConfig) IsOnBoneh(num *big.Int) bool { + return configNumEqual(c.BonehBlock, num) +} + +// IsLynn returns whether num is either equal to the second fast finality fork block or greater. +func (c *ChainConfig) IsLynn(num *big.Int) bool { + return isForked(c.LynnBlock, num) +} + +// IsOnLynn returns whether num is equal to the second fast finality fork block. +func (c *ChainConfig) IsOnLynn(num *big.Int) bool { + return configNumEqual(c.LynnBlock, num) +} + // IsMuirGlacier returns whether num is either equal to the Muir Glacier (EIP-2384) fork block or greater. func (c *ChainConfig) IsMuirGlacier(num *big.Int) bool { return isForked(c.MuirGlacierBlock, num) @@ -559,6 +652,8 @@ func (c *ChainConfig) CheckConfigForkOrder() error { {name: "brunoBlock", block: c.BrunoBlock}, {name: "eulerBlock", block: c.EulerBlock}, {name: "gibbsBlock", block: c.GibbsBlock}, + {name: "bonehBlock", block: c.BonehBlock}, + {name: "lynnBlock", block: c.LynnBlock}, } { if lastFork.name != "" { // Next one must be higher number @@ -658,6 +753,12 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *Confi if isForkIncompatible(c.PlanckBlock, newcfg.PlanckBlock, head) { return newCompatError("planck fork block", c.PlanckBlock, newcfg.PlanckBlock) } + if isForkIncompatible(c.BonehBlock, newcfg.BonehBlock, head) { + return newCompatError("boneh fork block", c.BonehBlock, newcfg.BonehBlock) + } + if isForkIncompatible(c.LynnBlock, newcfg.LynnBlock, head) { + return newCompatError("lynn fork block", c.LynnBlock, newcfg.LynnBlock) + } return nil } @@ -730,6 +831,7 @@ type Rules struct { IsNano bool IsMoran bool IsPlanck bool + IsBoneh bool } // Rules ensures c's ChainID is not nil. @@ -754,5 +856,6 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool) Rules { IsNano: c.IsNano(num), IsMoran: c.IsMoran(num), IsPlanck: c.IsPlanck(num), + IsBoneh: c.IsBoneh(num), } } diff --git a/params/protocol_params.go b/params/protocol_params.go index e244c24231..653377cc41 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -132,13 +132,15 @@ const ( TendermintHeaderValidateGas uint64 = 3000 // Gas for validate tendermiint consensus state IAVLMerkleProofValidateGas uint64 = 3000 // Gas for validate merkle proof - EcrecoverGas uint64 = 3000 // Elliptic curve sender recovery gas price - Sha256BaseGas uint64 = 60 // Base price for a SHA256 operation - Sha256PerWordGas uint64 = 12 // Per-word price for a SHA256 operation - Ripemd160BaseGas uint64 = 600 // Base price for a RIPEMD160 operation - Ripemd160PerWordGas uint64 = 120 // Per-word price for a RIPEMD160 operation - IdentityBaseGas uint64 = 15 // Base price for a data copy operation - IdentityPerWordGas uint64 = 3 // Per-work price for a data copy operation + EcrecoverGas uint64 = 3000 // Elliptic curve sender recovery gas price + Sha256BaseGas uint64 = 60 // Base price for a SHA256 operation + Sha256PerWordGas uint64 = 12 // Per-word price for a SHA256 operation + Ripemd160BaseGas uint64 = 600 // Base price for a RIPEMD160 operation + Ripemd160PerWordGas uint64 = 120 // Per-word price for a RIPEMD160 operation + IdentityBaseGas uint64 = 15 // Base price for a data copy operation + IdentityPerWordGas uint64 = 3 // Per-work price for a data copy operation + BlsSignatureVerifyBaseGas uint64 = 1000 // base price for a BLS signature verify operation + BlsSignatureVerifyPerKeyGas uint64 = 3500 // Per-key price for a BLS signature verify operation Bn256AddGasByzantium uint64 = 500 // Byzantium gas needed for an elliptic curve addition Bn256AddGasIstanbul uint64 = 150 // Gas needed for an elliptic curve addition diff --git a/rpc/client.go b/rpc/client.go index a89f8ba18c..c8a1a343bc 100644 --- a/rpc/client.go +++ b/rpc/client.go @@ -187,6 +187,18 @@ func DialContext(ctx context.Context, rawurl string) (*Client, error) { } } +// DialOptions creates a new RPC client for the given URL. You can supply any of the +// pre-defined client options to configure the underlying transport. +// +// The context is used to cancel or time out the initial connection establishment. It does +// not affect subsequent interactions with the client. +// +// The client reconnects automatically when the connection is lost. +func DialOptions(ctx context.Context, rawurl string, options ...ClientOption) (*Client, error) { + // just for prysm compile pass + return nil, fmt.Errorf("not supported") +} + // Client retrieves the client from the context, if any. This can be used to perform // 'reverse calls' in a handler method. func ClientFromContext(ctx context.Context) (*Client, bool) { diff --git a/rpc/client_opt.go b/rpc/client_opt.go new file mode 100644 index 0000000000..5ad7c22b3c --- /dev/null +++ b/rpc/client_opt.go @@ -0,0 +1,106 @@ +// Copyright 2022 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package rpc + +import ( + "net/http" + + "github.com/gorilla/websocket" +) + +// ClientOption is a configuration option for the RPC client. +type ClientOption interface { + applyOption(*clientConfig) +} + +type clientConfig struct { + httpClient *http.Client + httpHeaders http.Header + httpAuth HTTPAuth + + wsDialer *websocket.Dialer +} + +func (cfg *clientConfig) initHeaders() { + if cfg.httpHeaders == nil { + cfg.httpHeaders = make(http.Header) + } +} + +func (cfg *clientConfig) setHeader(key, value string) { + cfg.initHeaders() + cfg.httpHeaders.Set(key, value) +} + +type optionFunc func(*clientConfig) + +func (fn optionFunc) applyOption(opt *clientConfig) { + fn(opt) +} + +// WithWebsocketDialer configures the websocket.Dialer used by the RPC client. +func WithWebsocketDialer(dialer websocket.Dialer) ClientOption { + return optionFunc(func(cfg *clientConfig) { + cfg.wsDialer = &dialer + }) +} + +// WithHeader configures HTTP headers set by the RPC client. Headers set using this option +// will be used for both HTTP and WebSocket connections. +func WithHeader(key, value string) ClientOption { + return optionFunc(func(cfg *clientConfig) { + cfg.initHeaders() + cfg.httpHeaders.Set(key, value) + }) +} + +// WithHeaders configures HTTP headers set by the RPC client. Headers set using this +// option will be used for both HTTP and WebSocket connections. +func WithHeaders(headers http.Header) ClientOption { + return optionFunc(func(cfg *clientConfig) { + cfg.initHeaders() + for k, vs := range headers { + cfg.httpHeaders[k] = vs + } + }) +} + +// WithHTTPClient configures the http.Client used by the RPC client. +func WithHTTPClient(c *http.Client) ClientOption { + return optionFunc(func(cfg *clientConfig) { + cfg.httpClient = c + }) +} + +// WithHTTPAuth configures HTTP request authentication. The given provider will be called +// whenever a request is made. Note that only one authentication provider can be active at +// any time. +func WithHTTPAuth(a HTTPAuth) ClientOption { + if a == nil { + panic("nil auth") + } + return optionFunc(func(cfg *clientConfig) { + cfg.httpAuth = a + }) +} + +// A HTTPAuth function is called by the client whenever a HTTP request is sent. +// The function must be safe for concurrent use. +// +// Usually, HTTPAuth functions will call h.Set("authorization", "...") to add +// auth information to the request. +type HTTPAuth func(h http.Header) error diff --git a/rpc/subscription.go b/rpc/subscription.go index 942e764e5d..d7ba784fc5 100644 --- a/rpc/subscription.go +++ b/rpc/subscription.go @@ -34,7 +34,7 @@ import ( var ( // ErrNotificationsUnsupported is returned when the connection doesn't support notifications ErrNotificationsUnsupported = errors.New("notifications not supported") - // ErrNotificationNotFound is returned when the notification for the given id is not found + // ErrSubscriptionNotFound is returned when the notification for the given id is not found ErrSubscriptionNotFound = errors.New("subscription not found") ) diff --git a/rpc/types.go b/rpc/types.go index 959e383723..151e5ee27e 100644 --- a/rpc/types.go +++ b/rpc/types.go @@ -60,13 +60,15 @@ type jsonWriter interface { type BlockNumber int64 const ( - PendingBlockNumber = BlockNumber(-2) - LatestBlockNumber = BlockNumber(-1) - EarliestBlockNumber = BlockNumber(0) + SafeBlockNumber = BlockNumber(-4) + FinalizedBlockNumber = BlockNumber(-3) + PendingBlockNumber = BlockNumber(-2) + LatestBlockNumber = BlockNumber(-1) + EarliestBlockNumber = BlockNumber(0) ) // UnmarshalJSON parses the given JSON fragment into a BlockNumber. It supports: -// - "latest", "earliest" or "pending" as string arguments +// - "safe", "finalized", "latest", "earliest" or "pending" as string arguments // - the block number // Returned errors: // - an invalid block number error when the given argument isn't a known strings @@ -87,6 +89,12 @@ func (bn *BlockNumber) UnmarshalJSON(data []byte) error { case "pending": *bn = PendingBlockNumber return nil + case "finalized": + *bn = FinalizedBlockNumber + return nil + case "safe": + *bn = SafeBlockNumber + return nil } blckNum, err := hexutil.DecodeUint64(input) @@ -101,7 +109,7 @@ func (bn *BlockNumber) UnmarshalJSON(data []byte) error { } // MarshalText implements encoding.TextMarshaler. It marshals: -// - "latest", "earliest" or "pending" as strings +// - "safe", "finalized", "latest", "earliest" or "pending" as strings // - other numbers as hex func (bn BlockNumber) MarshalText() ([]byte, error) { switch bn { @@ -111,6 +119,10 @@ func (bn BlockNumber) MarshalText() ([]byte, error) { return []byte("latest"), nil case PendingBlockNumber: return []byte("pending"), nil + case FinalizedBlockNumber: + return []byte("finalized"), nil + case SafeBlockNumber: + return []byte("safe"), nil default: return hexutil.Uint64(bn).MarshalText() } @@ -157,6 +169,14 @@ func (bnh *BlockNumberOrHash) UnmarshalJSON(data []byte) error { bn := PendingBlockNumber bnh.BlockNumber = &bn return nil + case "finalized": + bn := FinalizedBlockNumber + bnh.BlockNumber = &bn + return nil + case "safe": + bn := SafeBlockNumber + bnh.BlockNumber = &bn + return nil default: if len(input) == 66 { hash := common.Hash{} diff --git a/tests/truffle/.env b/tests/truffle/.env index d933e4cfef..e2b3e27f5c 100644 --- a/tests/truffle/.env +++ b/tests/truffle/.env @@ -1,4 +1,4 @@ -BSC_CHAIN_ID="99" +BSC_CHAIN_ID=99 CLUSTER_CIDR=99.1.0.0/16 BOOTSTRAP_PUB_KEY=177ae5db445a2f70db781b019aedd928f5b1528a7a43448840b022408f9a21509adcce0b37c87d59da68d47a16879cc1e95a62bbac9723f7b22f4365b2afabbe BOOTSTRAP_TCP_PORT=30311 diff --git a/tests/truffle/scripts/bootstrap.sh b/tests/truffle/scripts/bootstrap.sh index 0e5e00df99..653059115d 100755 --- a/tests/truffle/scripts/bootstrap.sh +++ b/tests/truffle/scripts/bootstrap.sh @@ -42,19 +42,38 @@ function init_genesis_data() { fi } +function prepareBLSWallet(){ + node_id=$1 + echo "123456" > ${workspace}/storage/${node_id}/blspassword.txt + expect ${workspace}/scripts/create_bls_key.sh ${workspace}/storage/${node_id} + + sed -i -e 's/DataDir/BLSPasswordFile = \"{{BLSPasswordFile}}\"\nBLSWalletDir = \"{{BLSWalletDir}}\"\nDataDir/g' ${workspace}/storage/${node_id}/config.toml + PassWordPath="/root/.ethereum/blspassword.txt" + sed -i -e "s:{{BLSPasswordFile}}:${PassWordPath}:g" ${workspace}/storage/${node_id}/config.toml + WalletPath="/root/.ethereum/bls/wallet" + sed -i -e "s:{{BLSWalletDir}}:${WalletPath}:g" ${workspace}/storage/${node_id}/config.toml +} + prepare -# First, generate config for each validator +# Step 1, generate config for each validator for((i=1;i<=${NUMS_OF_VALIDATOR};i++)); do init_validator "bsc-validator${i}" done -# Then, use validator configs to generate genesis file +# Step 2, use validator configs to generate genesis file generate_genesis -# Finally, use genesis file to init cluster data +# Step 3, use genesis file to init cluster data init_genesis_data bsc-rpc bsc-rpc for((i=1;i<=${NUMS_OF_VALIDATOR};i++)); do init_genesis_data validator "bsc-validator${i}" done + +#Step 4, prepare bls wallet, used by fast finality vote +prepareBLSWallet bsc-rpc + +for((i=1;i<=${NUMS_OF_VALIDATOR};i++)); do + prepareBLSWallet "bsc-validator${i}" +done \ No newline at end of file diff --git a/tests/truffle/scripts/create_bls_key.sh b/tests/truffle/scripts/create_bls_key.sh new file mode 100644 index 0000000000..a1a4d97bd6 --- /dev/null +++ b/tests/truffle/scripts/create_bls_key.sh @@ -0,0 +1,17 @@ +#!/usr/bin/expect +# 6 num wanted +set wallet_password 123456 +# 10 characters at least wanted +set account_password 1234567890 + +set timeout 5 +spawn geth bls account new --datadir [lindex $argv 0] +expect "*assword:*" +send "$wallet_password\r" +expect "*assword:*" +send "$wallet_password\r" +expect "*assword:*" +send "$account_password\r" +expect "*assword:*" +send "$account_password\r" +expect EOF \ No newline at end of file