From 38fb38a92edccb9ea1505686ed5e361208bf81f1 Mon Sep 17 00:00:00 2001 From: Alexey Sharp Date: Mon, 6 Mar 2023 12:58:27 +0000 Subject: [PATCH 01/18] Stable modification --- params/version.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/params/version.go b/params/version.go index 40aeaf048b6..c24bca3c3f1 100644 --- a/params/version.go +++ b/params/version.go @@ -31,10 +31,10 @@ var ( // see https://calver.org const ( - VersionMajor = 2 // Major version component of the current release - VersionMinor = 40 // Minor version component of the current release - VersionMicro = 0 // Patch version component of the current release - VersionModifier = "dev" // Modifier component of the current release + VersionMajor = 2 // Major version component of the current release + VersionMinor = 40 // Minor version component of the current release + VersionMicro = 0 // Patch version component of the current release + VersionModifier = "stable" // Modifier component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" ) From 36b03c13b50c3db68bc49922e185a23dd8bc7a56 Mon Sep 17 00:00:00 2001 From: Alexey Sharp Date: Tue, 7 Mar 2023 11:08:55 +0000 Subject: [PATCH 02/18] Bump patch version --- params/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/params/version.go b/params/version.go index c24bca3c3f1..72b694aa5cc 100644 --- a/params/version.go +++ b/params/version.go @@ -33,7 +33,7 @@ var ( const ( VersionMajor = 2 // Major version component of the current release VersionMinor = 40 // Minor version component of the current release - VersionMicro = 0 // Patch version component of the current release + VersionMicro = 1 // Patch version component of the current release VersionModifier = "stable" // Modifier component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" From b66199b3d0290dc3d37f25cc1d6532bf0ce2cd5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Loeuillet?= Date: Mon, 6 Mar 2023 19:58:10 +0100 Subject: [PATCH 03/18] graphql: add missing fields in block.transaction (#7034) --- cmd/rpcdaemon/commands/graphql_api.go | 8 +++++++- cmd/rpcdaemon/graphql/graph/helpers.go | 13 ++++++++++--- cmd/rpcdaemon/graphql/graph/schema.resolvers.go | 12 ++++-------- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/cmd/rpcdaemon/commands/graphql_api.go b/cmd/rpcdaemon/commands/graphql_api.go index a81ca838a05..947540fb858 100644 --- a/cmd/rpcdaemon/commands/graphql_api.go +++ b/cmd/rpcdaemon/commands/graphql_api.go @@ -79,7 +79,13 @@ func (api *GraphQLAPIImpl) GetBlockDetails(ctx context.Context, blockNumber rpc. result := make([]map[string]interface{}, 0, len(receipts)) for _, receipt := range receipts { txn := block.Transactions()[receipt.TransactionIndex] - result = append(result, marshalReceipt(receipt, txn, chainConfig, block.HeaderNoCopy(), txn.Hash(), true)) + + transaction := marshalReceipt(receipt, txn, chainConfig, block.HeaderNoCopy(), txn.Hash(), true) + transaction["nonce"] = txn.GetNonce() + transaction["value"] = txn.GetValue() + transaction["data"] = txn.GetData() + transaction["gasPrice"] = txn.GetPrice() + result = append(result, transaction) } response := map[string]interface{}{} diff --git a/cmd/rpcdaemon/graphql/graph/helpers.go b/cmd/rpcdaemon/graphql/graph/helpers.go index 1b780f9f2b0..812a283b13b 100644 --- a/cmd/rpcdaemon/graphql/graph/helpers.go +++ b/cmd/rpcdaemon/graphql/graph/helpers.go @@ -6,6 +6,7 @@ import ( "reflect" "strconv" + "github.com/holiman/uint256" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/core/types" @@ -35,8 +36,12 @@ func convertDataToStringP(abstractMap map[string]interface{}, field string) *str result = hex.EncodeToString(v.Bytes()) case types.BlockNonce: result = "0x" + strconv.FormatInt(int64(v.Uint64()), 16) + case []uint8: + result = "0x" + hex.EncodeToString(v) + case *uint256.Int: + result = v.Hex() default: - fmt.Println("string", field, abstractMap[field], reflect.TypeOf(abstractMap[field])) + fmt.Println("unhandled/string", reflect.TypeOf(abstractMap[field]), field, abstractMap[field]) result = "unhandled" } return &result @@ -63,7 +68,7 @@ func convertDataToIntP(abstractMap map[string]interface{}, field string) *int { case int: result = v default: - fmt.Println("int", field, abstractMap[field], reflect.TypeOf(abstractMap[field])) + fmt.Println("unhandled/int", reflect.TypeOf(abstractMap[field]), field, abstractMap[field]) result = 0 } @@ -92,8 +97,10 @@ func convertDataToUint64P(abstractMap map[string]interface{}, field string) *uin result = v.ToInt().Uint64() case int: result = abstractMap[field].(uint64) + case uint64: + result = abstractMap[field].(uint64) default: - fmt.Println("uint64", field, abstractMap[field], reflect.TypeOf(abstractMap[field])) + fmt.Println("unhandled/uint64", reflect.TypeOf(abstractMap[field]), field, abstractMap[field]) result = 0 } diff --git a/cmd/rpcdaemon/graphql/graph/schema.resolvers.go b/cmd/rpcdaemon/graphql/graph/schema.resolvers.go index db4865b21fd..69022758e34 100644 --- a/cmd/rpcdaemon/graphql/graph/schema.resolvers.go +++ b/cmd/rpcdaemon/graphql/graph/schema.resolvers.go @@ -98,12 +98,16 @@ func (r *queryResolver) Block(ctx context.Context, number *string, hash *string) for _, transReceipt := range rcp { trans := &model.Transaction{} trans.CumulativeGasUsed = convertDataToUint64P(transReceipt, "cumulativeGasUsed") + trans.InputData = *convertDataToStringP(transReceipt, "data") trans.EffectiveGasPrice = convertDataToStringP(transReceipt, "effectiveGasPrice") + trans.GasPrice = *convertDataToStringP(transReceipt, "gasPrice") trans.GasUsed = convertDataToUint64P(transReceipt, "gasUsed") trans.Hash = *convertDataToStringP(transReceipt, "transactionHash") trans.Index = convertDataToIntP(transReceipt, "transactionIndex") + trans.Nonce = *convertDataToUint64P(transReceipt, "nonce") trans.Status = convertDataToUint64P(transReceipt, "status") trans.Type = convertDataToIntP(transReceipt, "type") + trans.Value = *convertDataToStringP(transReceipt, "value") trans.Logs = make([]*model.Log, 0) trans.From = &model.Account{} @@ -113,14 +117,6 @@ func (r *queryResolver) Block(ctx context.Context, number *string, hash *string) trans.To.Address = strings.ToLower(*convertDataToStringP(transReceipt, "to")) block.Transactions = append(block.Transactions, trans) - - /* - Missing Transaction fields to fill : - - gasPrice - - inputData (even if geth often display "0x") - - nonce (we get 0, geth displays "0xZZZZZZZ" hex data) - - value - */ } return block, ctx.Err() From 697ff09fc2b25457c5c19095a6842b78ca66f6eb Mon Sep 17 00:00:00 2001 From: hexoscott <70711990+hexoscott@users.noreply.github.com> Date: Mon, 6 Mar 2023 18:59:14 +0000 Subject: [PATCH 04/18] remove PeerUseless calls (#7032) --- cmd/erigon-el/backend/backend.go | 4 +++- cmd/integration/commands/stages.go | 10 ++++++---- cmd/sentry/sentry/sentry_grpc_server.go | 18 ++++++------------ cmd/sentry/sentry/sentry_multi_client.go | 17 ++++++++++------- cmd/utils/flags.go | 10 ++++++++++ eth/backend.go | 6 ++++-- eth/ethconfig/config.go | 3 +++ go.mod | 2 +- go.sum | 4 ++-- turbo/cli/default_flags.go | 1 + turbo/stages/mock_sentry.go | 6 ++++-- 11 files changed, 50 insertions(+), 31 deletions(-) diff --git a/cmd/erigon-el/backend/backend.go b/cmd/erigon-el/backend/backend.go index 3a8f837d72a..725219be4e2 100644 --- a/cmd/erigon-el/backend/backend.go +++ b/cmd/erigon-el/backend/backend.go @@ -39,13 +39,14 @@ import ( txpool2 "github.com/ledgerwatch/erigon-lib/txpool" "github.com/ledgerwatch/erigon-lib/txpool/txpooluitl" types2 "github.com/ledgerwatch/erigon-lib/types" - "github.com/ledgerwatch/erigon/core/systemcontracts" "github.com/ledgerwatch/log/v3" "golang.org/x/exp/slices" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/protobuf/types/known/emptypb" + "github.com/ledgerwatch/erigon/core/systemcontracts" + "github.com/ledgerwatch/erigon/core/state/historyv2read" "github.com/ledgerwatch/erigon/core/types/accounts" "github.com/ledgerwatch/erigon/p2p/dnsdisc" @@ -446,6 +447,7 @@ func NewBackend(stack *node.Node, config *ethconfig.Config, logger log.Logger) ( backend.blockReader, stack.Config().SentryLogPeerInfo, backend.forkValidator, + config.DropUselessPeers, ) if err != nil { return nil, err diff --git a/cmd/integration/commands/stages.go b/cmd/integration/commands/stages.go index bf10ac722fe..04b429ef266 100644 --- a/cmd/integration/commands/stages.go +++ b/cmd/integration/commands/stages.go @@ -19,6 +19,11 @@ import ( "github.com/ledgerwatch/erigon-lib/kv/kvcfg" "github.com/ledgerwatch/erigon-lib/kv/rawdbv3" libstate "github.com/ledgerwatch/erigon-lib/state" + "github.com/ledgerwatch/log/v3" + "github.com/ledgerwatch/secp256k1" + "github.com/spf13/cobra" + "golang.org/x/exp/slices" + "github.com/ledgerwatch/erigon/cmd/hack/tool/fromdb" "github.com/ledgerwatch/erigon/cmd/sentry/sentry" "github.com/ledgerwatch/erigon/consensus" @@ -42,10 +47,6 @@ import ( "github.com/ledgerwatch/erigon/turbo/snapshotsync" "github.com/ledgerwatch/erigon/turbo/snapshotsync/snap" stages2 "github.com/ledgerwatch/erigon/turbo/stages" - "github.com/ledgerwatch/log/v3" - "github.com/ledgerwatch/secp256k1" - "github.com/spf13/cobra" - "golang.org/x/exp/slices" ) var cmdStageSnapshots = &cobra.Command{ @@ -1276,6 +1277,7 @@ func newSync(ctx context.Context, db kv.RwDB, miningConfig *params.MiningConfig) br, false, nil, + ethconfig.Defaults.DropUselessPeers, ) if err != nil { panic(err) diff --git a/cmd/sentry/sentry/sentry_grpc_server.go b/cmd/sentry/sentry/sentry_grpc_server.go index 52c9f1b3e2a..0a30daec43a 100644 --- a/cmd/sentry/sentry/sentry_grpc_server.go +++ b/cmd/sentry/sentry/sentry_grpc_server.go @@ -741,7 +741,12 @@ func (ss *GrpcServer) startSync(ctx context.Context, bestHash libcommon.Hash, pe func (ss *GrpcServer) PenalizePeer(_ context.Context, req *proto_sentry.PenalizePeerRequest) (*emptypb.Empty, error) { //log.Warn("Received penalty", "kind", req.GetPenalty().Descriptor().FullName, "from", fmt.Sprintf("%s", req.GetPeerId())) peerID := ConvertH512ToPeerID(req.PeerId) - ss.removePeer(peerID) + peerInfo := ss.getPeer(peerID) + if ss.statusData != nil && peerInfo != nil && !peerInfo.peer.Info().Network.Static && !peerInfo.peer.Info().Network.Trusted { + ss.removePeer(peerID) + printablePeerID := hex.EncodeToString(peerID[:])[:8] + log.Debug("[p2p] Penalized peer", "peerId", printablePeerID, "name", peerInfo.peer.Name()) + } return &emptypb.Empty{}, nil } @@ -753,17 +758,6 @@ func (ss *GrpcServer) PeerMinBlock(_ context.Context, req *proto_sentry.PeerMinB return &emptypb.Empty{}, nil } -func (ss *GrpcServer) PeerUseless(_ context.Context, req *proto_sentry.PeerUselessRequest) (*emptypb.Empty, error) { - peerID := ConvertH512ToPeerID(req.PeerId) - peerInfo := ss.getPeer(peerID) - if ss.statusData != nil && peerInfo != nil && !peerInfo.peer.Info().Network.Static && !peerInfo.peer.Info().Network.Trusted { - ss.removePeer(peerID) - printablePeerID := hex.EncodeToString(peerID[:])[:8] - log.Debug("[p2p] Removed useless peer", "peerId", printablePeerID, "name", peerInfo.peer.Name()) - } - return &emptypb.Empty{}, nil -} - func (ss *GrpcServer) findBestPeersWithPermit(peerCount int) []*PeerInfo { // Choose peer(s) that we can send this request to, with maximum number of permits now := time.Now() diff --git a/cmd/sentry/sentry/sentry_multi_client.go b/cmd/sentry/sentry/sentry_multi_client.go index e7715bcaf61..b56b1cd1006 100644 --- a/cmd/sentry/sentry/sentry_multi_client.go +++ b/cmd/sentry/sentry/sentry_multi_client.go @@ -266,7 +266,8 @@ type MultiClient struct { logPeerInfo bool sendHeaderRequestsToMultiplePeers bool - historyV3 bool + historyV3 bool + dropUselessPeers bool } func NewMultiClient( @@ -281,6 +282,7 @@ func NewMultiClient( blockReader services.HeaderAndCanonicalReader, logPeerInfo bool, forkValidator *engineapi.ForkValidator, + dropUselessPeers bool, ) (*MultiClient, error) { historyV3 := kvcfg.HistoryV3.FromDB(db) @@ -311,6 +313,7 @@ func NewMultiClient( forkValidator: forkValidator, historyV3: historyV3, sendHeaderRequestsToMultiplePeers: chainConfig.TerminalTotalDifficultyPassed, + dropUselessPeers: dropUselessPeers, } cs.ChainConfig = chainConfig cs.heightForks, cs.timeForks = forkid.GatherForks(cs.ChainConfig) @@ -392,11 +395,11 @@ func (cs *MultiClient) blockHeaders66(ctx context.Context, in *proto_sentry.Inbo } func (cs *MultiClient) blockHeaders(ctx context.Context, pkt eth.BlockHeadersPacket, rlpStream *rlp.Stream, peerID *proto_types.H512, sentry direct.SentryClient) error { - if len(pkt) == 0 { - outreq := proto_sentry.PeerUselessRequest{ + if cs.dropUselessPeers && len(pkt) == 0 { + outreq := proto_sentry.PenalizePeerRequest{ PeerId: peerID, } - if _, err := sentry.PeerUseless(ctx, &outreq, &grpc.EmptyCallOption{}); err != nil { + if _, err := sentry.PenalizePeer(ctx, &outreq, &grpc.EmptyCallOption{}); err != nil { return fmt.Errorf("sending peer useless request: %v", err) } log.Debug("Requested removal of peer for empty header response", "peerId", fmt.Sprintf("%x", ConvertH512ToPeerID(peerID))[:8]) @@ -556,11 +559,11 @@ func (cs *MultiClient) blockBodies66(ctx context.Context, inreq *proto_sentry.In return fmt.Errorf("decode BlockBodiesPacket66: %w", err) } txs, uncles, withdrawals := request.BlockRawBodiesPacket.Unpack() - if len(txs) == 0 && len(uncles) == 0 && len(withdrawals) == 0 { - outreq := proto_sentry.PeerUselessRequest{ + if cs.dropUselessPeers && len(txs) == 0 && len(uncles) == 0 && len(withdrawals) == 0 { + outreq := proto_sentry.PenalizePeerRequest{ PeerId: inreq.PeerId, } - if _, err := sentry.PeerUseless(ctx, &outreq, &grpc.EmptyCallOption{}); err != nil { + if _, err := sentry.PenalizePeer(ctx, &outreq, &grpc.EmptyCallOption{}); err != nil { return fmt.Errorf("sending peer useless request: %v", err) } log.Debug("Requested removal of peer for empty body response", "peerId", fmt.Sprintf("%x", ConvertH512ToPeerID(inreq.PeerId))) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 423fe073f6e..2d60266b689 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -500,6 +500,11 @@ var ( Name: "sentry.log-peer-info", Usage: "Log detailed peer info when a peer connects or disconnects. Enable to integrate with observer.", } + SentryDropUselessPeers = cli.BoolFlag{ + Name: "sentry.drop-useless-peers", + Usage: "Drop useless peers, those returning empty body or header responses", + Value: false, + } DownloaderAddrFlag = cli.StringFlag{ Name: "downloader.api.addr", Usage: "downloader address ':'", @@ -1577,7 +1582,12 @@ func SetEthConfig(ctx *cli.Context, nodeConfig *nodecfg.Config, cfg *ethconfig.C } else { cfg.ExternalCL = !clparams.EmbeddedEnabledByDefault(cfg.NetworkID) } + nodeConfig.Http.InternalCL = !cfg.ExternalCL + + if ctx.IsSet(SentryDropUselessPeers.Name) { + cfg.DropUselessPeers = ctx.Bool(SentryDropUselessPeers.Name) + } } // SetDNSDiscoveryDefaults configures DNS discovery with the given URL if diff --git a/eth/backend.go b/eth/backend.go index 9ac659a7080..e97975e9ca6 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -55,14 +55,15 @@ import ( txpool2 "github.com/ledgerwatch/erigon-lib/txpool" "github.com/ledgerwatch/erigon-lib/txpool/txpooluitl" types2 "github.com/ledgerwatch/erigon-lib/types" - "github.com/ledgerwatch/erigon/core/systemcontracts" - "github.com/ledgerwatch/erigon/p2p/enode" "github.com/ledgerwatch/log/v3" "golang.org/x/exp/slices" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/protobuf/types/known/emptypb" + "github.com/ledgerwatch/erigon/core/systemcontracts" + "github.com/ledgerwatch/erigon/p2p/enode" + "github.com/ledgerwatch/erigon/core/state/historyv2read" "github.com/ledgerwatch/erigon/core/state/temporal" "github.com/ledgerwatch/erigon/core/types/accounts" @@ -471,6 +472,7 @@ func New(stack *node.Node, config *ethconfig.Config, logger log.Logger) (*Ethere blockReader, stack.Config().SentryLogPeerInfo, backend.forkValidator, + config.DropUselessPeers, ) if err != nil { return nil, err diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index b8a4c1e95fe..4b753242ed1 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -101,6 +101,7 @@ var Defaults = Config{ KeepBlocks: false, Produce: true, }, + DropUselessPeers: false, } func init() { @@ -249,6 +250,8 @@ type Config struct { SentinelPort uint64 OverrideShanghaiTime *big.Int `toml:",omitempty"` + + DropUselessPeers bool } type Sync struct { diff --git a/go.mod b/go.mod index 1ad84dbfa15..2f39375dfe9 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/ledgerwatch/erigon go 1.18 require ( - github.com/ledgerwatch/erigon-lib v0.0.0-20230305180029-3d69e5177fc4 + github.com/ledgerwatch/erigon-lib v0.0.0-20230306114514-2c4c92fd1fce github.com/ledgerwatch/erigon-snapshot v1.1.1-0.20230306083105-1391330d62a3 github.com/ledgerwatch/log/v3 v3.7.0 github.com/ledgerwatch/secp256k1 v1.0.0 diff --git a/go.sum b/go.sum index 900aaba7fb1..10d3cc143ee 100644 --- a/go.sum +++ b/go.sum @@ -517,8 +517,8 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3PYPwICLl+/9oulQauOuETfgFvhBDffs0= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20230305180029-3d69e5177fc4 h1:ZTYSqbza9J+Nuc/XdJJlzSWapol0/8GE1aiHuHLpnrA= -github.com/ledgerwatch/erigon-lib v0.0.0-20230305180029-3d69e5177fc4/go.mod h1:xcrJLJiNfthKFectsWBUtRJK9d6XtjiyQRGVeImRYRs= +github.com/ledgerwatch/erigon-lib v0.0.0-20230306114514-2c4c92fd1fce h1:KsoGX2RLGvqTc97Et7wAwaRNk1/RDAUbe20B9TM7/70= +github.com/ledgerwatch/erigon-lib v0.0.0-20230306114514-2c4c92fd1fce/go.mod h1:/xzmS14QeWZFjRXDiTdeqcSW4IrrUSYkCXZRfsZ5XbI= github.com/ledgerwatch/erigon-snapshot v1.1.1-0.20230306083105-1391330d62a3 h1:tfzawK1gIIgRjVZeANXOr0Ziu+kqCIBuKMe0TXfl5Aw= github.com/ledgerwatch/erigon-snapshot v1.1.1-0.20230306083105-1391330d62a3/go.mod h1:3AuPxZc85jkehh/HA9h8gabv5MSi3kb/ddtzBsTVJFo= github.com/ledgerwatch/log/v3 v3.7.0 h1:aFPEZdwZx4jzA3+/Pf8wNDN5tCI0cIolq/kfvgcM+og= diff --git a/turbo/cli/default_flags.go b/turbo/cli/default_flags.go index 687409b18cf..c31aa481f71 100644 --- a/turbo/cli/default_flags.go +++ b/turbo/cli/default_flags.go @@ -134,6 +134,7 @@ var DefaultFlags = []cli.Flag{ &utils.MinerSigningKeyFileFlag, &utils.SentryAddrFlag, &utils.SentryLogPeerInfoFlag, + &utils.SentryDropUselessPeers, &utils.DownloaderAddrFlag, &utils.DisableIPV4, &utils.DisableIPV6, diff --git a/turbo/stages/mock_sentry.go b/turbo/stages/mock_sentry.go index f3da029aecb..6a980bbd426 100644 --- a/turbo/stages/mock_sentry.go +++ b/turbo/stages/mock_sentry.go @@ -28,11 +28,12 @@ import ( libstate "github.com/ledgerwatch/erigon-lib/state" "github.com/ledgerwatch/erigon-lib/txpool" types2 "github.com/ledgerwatch/erigon-lib/types" - "github.com/ledgerwatch/erigon/core/systemcontracts" - "github.com/ledgerwatch/erigon/turbo/rpchelper" "github.com/ledgerwatch/log/v3" "google.golang.org/protobuf/types/known/emptypb" + "github.com/ledgerwatch/erigon/core/systemcontracts" + "github.com/ledgerwatch/erigon/turbo/rpchelper" + "github.com/ledgerwatch/erigon/core/state/historyv2read" "github.com/ledgerwatch/erigon/core/state/temporal" "github.com/ledgerwatch/erigon/core/types/accounts" @@ -379,6 +380,7 @@ func MockWithEverything(t *testing.T, gspec *core.Genesis, key *ecdsa.PrivateKey blockReader, false, forkValidator, + cfg.DropUselessPeers, ) mock.sentriesClient.IsMock = true From cc4521a25c6567ea9cd556520e3a6f9d99cc25e2 Mon Sep 17 00:00:00 2001 From: Anshal Shukla <53994948+anshalshukla@users.noreply.github.com> Date: Tue, 7 Mar 2023 15:07:33 +0530 Subject: [PATCH 05/18] use bor interface (#7045) --- consensus/bor/heimdall/span/spanner.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/consensus/bor/heimdall/span/spanner.go b/consensus/bor/heimdall/span/spanner.go index b978294e119..85eb4440c3b 100644 --- a/consensus/bor/heimdall/span/spanner.go +++ b/consensus/bor/heimdall/span/spanner.go @@ -6,8 +6,8 @@ import ( "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" - "github.com/ledgerwatch/erigon/accounts/abi" "github.com/ledgerwatch/erigon/consensus" + "github.com/ledgerwatch/erigon/consensus/bor/abi" "github.com/ledgerwatch/erigon/consensus/bor/valset" "github.com/ledgerwatch/erigon/params/networkname" "github.com/ledgerwatch/erigon/rlp" From 9a65dd1c219be8a7658c72b3ab3fa13b536d34ef Mon Sep 17 00:00:00 2001 From: Krishna Upadhyaya Date: Tue, 7 Mar 2023 16:14:31 +0530 Subject: [PATCH 06/18] Update validator map when loading snapshot (#7046) --- consensus/bor/snapshot.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/consensus/bor/snapshot.go b/consensus/bor/snapshot.go index 028d23246ac..1ebcb56b808 100644 --- a/consensus/bor/snapshot.go +++ b/consensus/bor/snapshot.go @@ -74,6 +74,8 @@ func loadSnapshot(config *chain.BorConfig, sigcache *lru2.ARCCache[libcommon.Has return nil, err } + snap.ValidatorSet.UpdateValidatorMap() + snap.config = config snap.sigcache = sigcache From c9513f5cd49c241f9057a0dc21bbf0143f0c7081 Mon Sep 17 00:00:00 2001 From: Alex Sharov Date: Tue, 7 Mar 2023 15:37:21 +0700 Subject: [PATCH 07/18] nil ptr in checkPruneHistory (#7042) --- cmd/rpcdaemon/commands/eth_api.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmd/rpcdaemon/commands/eth_api.go b/cmd/rpcdaemon/commands/eth_api.go index 27b25ed9ccd..97edc621420 100644 --- a/cmd/rpcdaemon/commands/eth_api.go +++ b/cmd/rpcdaemon/commands/eth_api.go @@ -279,6 +279,9 @@ func (api *BaseAPI) checkPruneHistory(tx kv.Tx, block uint64) error { if err != nil { return err } + if latest == nil { + return nil + } prunedTo := p.History.PruneTo(latest.Number().Uint64()) if block < prunedTo { return fmt.Errorf("history has been pruned for this block") From 94b4cee5a898a47b9241ce824622af6350e5dc5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Loeuillet?= Date: Tue, 7 Mar 2023 13:20:18 +0100 Subject: [PATCH 08/18] =?UTF-8?q?graphql:=20protect=20against=20nil=20poin?= =?UTF-8?q?ter=20deref=20on=20cases=20like=20TX=20with=20nil=20=E2=80=A6?= =?UTF-8?q?=20(#7047)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …To address (contract creation) --- cmd/rpcdaemon/graphql/graph/helpers.go | 5 + .../graphql/graph/schema.resolvers.go | 126 ++++++++++-------- 2 files changed, 76 insertions(+), 55 deletions(-) diff --git a/cmd/rpcdaemon/graphql/graph/helpers.go b/cmd/rpcdaemon/graphql/graph/helpers.go index 812a283b13b..5d7b8cd9e26 100644 --- a/cmd/rpcdaemon/graphql/graph/helpers.go +++ b/cmd/rpcdaemon/graphql/graph/helpers.go @@ -15,6 +15,10 @@ import ( func convertDataToStringP(abstractMap map[string]interface{}, field string) *string { var result string + if reflect.ValueOf(abstractMap[field]).IsZero() { + return nil + } + switch v := abstractMap[field].(type) { case int64: result = strconv.FormatInt(v, 10) @@ -44,6 +48,7 @@ func convertDataToStringP(abstractMap map[string]interface{}, field string) *str fmt.Println("unhandled/string", reflect.TypeOf(abstractMap[field]), field, abstractMap[field]) result = "unhandled" } + return &result } diff --git a/cmd/rpcdaemon/graphql/graph/schema.resolvers.go b/cmd/rpcdaemon/graphql/graph/schema.resolvers.go index 69022758e34..061f27bc2b5 100644 --- a/cmd/rpcdaemon/graphql/graph/schema.resolvers.go +++ b/cmd/rpcdaemon/graphql/graph/schema.resolvers.go @@ -60,63 +60,79 @@ func (r *queryResolver) Block(ctx context.Context, number *string, hash *string) return nil, err } + block := &model.Block{} absBlk := res["block"] - blk := absBlk.(map[string]interface{}) - block := &model.Block{} - block.Difficulty = *convertDataToStringP(blk, "difficulty") - block.ExtraData = *convertDataToStringP(blk, "extraData") - block.GasLimit = uint64(*convertDataToUint64P(blk, "gasLimit")) - block.GasUsed = *convertDataToUint64P(blk, "gasUsed") - block.Hash = *convertDataToStringP(blk, "hash") - block.Miner = &model.Account{} - block.Miner.Address = strings.ToLower(*convertDataToStringP(blk, "miner")) - block.MixHash = *convertDataToStringP(blk, "mixHash") - block.Nonce = *convertDataToStringP(blk, "nonce") - block.Number = *convertDataToUint64P(blk, "number") - block.Ommers = []*model.Block{} - block.Parent = &model.Block{} - block.Parent.Hash = *convertDataToStringP(blk, "parentHash") - block.ReceiptsRoot = *convertDataToStringP(blk, "receiptsRoot") - block.StateRoot = *convertDataToStringP(blk, "stateRoot") - block.Timestamp = *convertDataToUint64P(blk, "timestamp") // int in the schema but Geth displays in HEX !!! - block.TransactionCount = convertDataToIntP(blk, "transactionCount") - block.TransactionsRoot = *convertDataToStringP(blk, "transactionsRoot") - block.TotalDifficulty = *convertDataToStringP(blk, "totalDifficulty") - block.Transactions = []*model.Transaction{} - - block.LogsBloom = "0x" + *convertDataToStringP(blk, "logsBloom") - block.OmmerHash = "" // OmmerHash: gointerfaces.ConvertHashToH256(header.UncleHash), - - /* - Missing Block fields to fill : - - ommerHash - */ - - absRcp := res["receipts"] - rcp := absRcp.([]map[string]interface{}) - for _, transReceipt := range rcp { - trans := &model.Transaction{} - trans.CumulativeGasUsed = convertDataToUint64P(transReceipt, "cumulativeGasUsed") - trans.InputData = *convertDataToStringP(transReceipt, "data") - trans.EffectiveGasPrice = convertDataToStringP(transReceipt, "effectiveGasPrice") - trans.GasPrice = *convertDataToStringP(transReceipt, "gasPrice") - trans.GasUsed = convertDataToUint64P(transReceipt, "gasUsed") - trans.Hash = *convertDataToStringP(transReceipt, "transactionHash") - trans.Index = convertDataToIntP(transReceipt, "transactionIndex") - trans.Nonce = *convertDataToUint64P(transReceipt, "nonce") - trans.Status = convertDataToUint64P(transReceipt, "status") - trans.Type = convertDataToIntP(transReceipt, "type") - trans.Value = *convertDataToStringP(transReceipt, "value") - trans.Logs = make([]*model.Log, 0) - - trans.From = &model.Account{} - trans.From.Address = strings.ToLower(*convertDataToStringP(transReceipt, "from")) - - trans.To = &model.Account{} - trans.To.Address = strings.ToLower(*convertDataToStringP(transReceipt, "to")) - - block.Transactions = append(block.Transactions, trans) + if absBlk != nil { + blk := absBlk.(map[string]interface{}) + + block.Difficulty = *convertDataToStringP(blk, "difficulty") + block.ExtraData = *convertDataToStringP(blk, "extraData") + block.GasLimit = uint64(*convertDataToUint64P(blk, "gasLimit")) + block.GasUsed = *convertDataToUint64P(blk, "gasUsed") + block.Hash = *convertDataToStringP(blk, "hash") + block.Miner = &model.Account{} + address := convertDataToStringP(blk, "miner") + if address != nil { + block.Miner.Address = strings.ToLower(*address) + } + mixHash := convertDataToStringP(blk, "mixHash") + if mixHash != nil { + block.MixHash = *mixHash + } + blockNonce := convertDataToStringP(blk, "nonce") + if blockNonce != nil { + block.Nonce = *blockNonce + } + block.Number = *convertDataToUint64P(blk, "number") + block.Ommers = []*model.Block{} + block.Parent = &model.Block{} + block.Parent.Hash = *convertDataToStringP(blk, "parentHash") + block.ReceiptsRoot = *convertDataToStringP(blk, "receiptsRoot") + block.StateRoot = *convertDataToStringP(blk, "stateRoot") + block.Timestamp = *convertDataToUint64P(blk, "timestamp") // int in the schema but Geth displays in HEX !!! + block.TransactionCount = convertDataToIntP(blk, "transactionCount") + block.TransactionsRoot = *convertDataToStringP(blk, "transactionsRoot") + block.TotalDifficulty = *convertDataToStringP(blk, "totalDifficulty") + block.Transactions = []*model.Transaction{} + + block.LogsBloom = "0x" + *convertDataToStringP(blk, "logsBloom") + block.OmmerHash = "" // OmmerHash: gointerfaces.ConvertHashToH256(header.UncleHash), + + /* + Missing Block fields to fill : + - ommerHash + */ + + absRcp := res["receipts"] + rcp := absRcp.([]map[string]interface{}) + for _, transReceipt := range rcp { + trans := &model.Transaction{} + trans.CumulativeGasUsed = convertDataToUint64P(transReceipt, "cumulativeGasUsed") + trans.InputData = *convertDataToStringP(transReceipt, "data") + trans.EffectiveGasPrice = convertDataToStringP(transReceipt, "effectiveGasPrice") + trans.GasPrice = *convertDataToStringP(transReceipt, "gasPrice") + trans.GasUsed = convertDataToUint64P(transReceipt, "gasUsed") + trans.Hash = *convertDataToStringP(transReceipt, "transactionHash") + trans.Index = convertDataToIntP(transReceipt, "transactionIndex") + trans.Nonce = *convertDataToUint64P(transReceipt, "nonce") + trans.Status = convertDataToUint64P(transReceipt, "status") + trans.Type = convertDataToIntP(transReceipt, "type") + trans.Value = *convertDataToStringP(transReceipt, "value") + trans.Logs = make([]*model.Log, 0) + + trans.From = &model.Account{} + trans.From.Address = strings.ToLower(*convertDataToStringP(transReceipt, "from")) + + trans.To = &model.Account{} + address := convertDataToStringP(transReceipt, "to") + // To address could be nil in case of contract creation + if address != nil { + trans.To.Address = strings.ToLower(*convertDataToStringP(transReceipt, "to")) + } + + block.Transactions = append(block.Transactions, trans) + } } return block, ctx.Err() From 5c541381fd11a928c055cd20734f5d8d801d5a8e Mon Sep 17 00:00:00 2001 From: Alexey Sharp Date: Tue, 28 Mar 2023 19:12:38 +0100 Subject: [PATCH 09/18] Bump version --- params/version.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/params/version.go b/params/version.go index 72b694aa5cc..fc23d0af7d9 100644 --- a/params/version.go +++ b/params/version.go @@ -32,8 +32,8 @@ var ( // see https://calver.org const ( VersionMajor = 2 // Major version component of the current release - VersionMinor = 40 // Minor version component of the current release - VersionMicro = 1 // Patch version component of the current release + VersionMinor = 42 // Minor version component of the current release + VersionMicro = 0 // Patch version component of the current release VersionModifier = "stable" // Modifier component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" From 5d0f778eed2726a8c6269095bbf3f63f81b89f0f Mon Sep 17 00:00:00 2001 From: Andrew Ashikhmin <34320705+yperbasis@users.noreply.github.com> Date: Mon, 20 Mar 2023 13:01:35 +0100 Subject: [PATCH 10/18] Schedule mainnet Shapella. Fix BellatrixForkEpoch (#7145) See https://github.com/ethereum/execution-specs/pull/727. Also, `BellatrixForkEpoch` should be 144896, not 144869: refer to [the spec](https://github.com/ethereum/consensus-specs/blob/dev/specs/bellatrix/fork.md). --- cl/clparams/config.go | 4 +- core/forkid/forkid_test.go | 161 +++++++-------------------------- params/chainspecs/mainnet.json | 1 + 3 files changed, 37 insertions(+), 129 deletions(-) diff --git a/cl/clparams/config.go b/cl/clparams/config.go index 343efceb58e..cf3f13d8604 100644 --- a/cl/clparams/config.go +++ b/cl/clparams/config.go @@ -670,9 +670,9 @@ var MainnetBeaconConfig BeaconChainConfig = BeaconChainConfig{ AltairForkVersion: 0x01000000, AltairForkEpoch: 74240, BellatrixForkVersion: 0x02000000, - BellatrixForkEpoch: 144869, + BellatrixForkEpoch: 144896, CapellaForkVersion: 0x03000000, - CapellaForkEpoch: math.MaxUint64, + CapellaForkEpoch: 194048, DenebForkVersion: 0x04000000, DenebForkEpoch: math.MaxUint64, diff --git a/core/forkid/forkid_test.go b/core/forkid/forkid_test.go index 733e83877bf..a347cc227a4 100644 --- a/core/forkid/forkid_test.go +++ b/core/forkid/forkid_test.go @@ -19,7 +19,6 @@ package forkid import ( "bytes" "math" - "math/big" "testing" "github.com/ledgerwatch/erigon-lib/chain" @@ -32,6 +31,8 @@ import ( // TestCreation tests that different genesis and fork rule combinations result in // the correct fork ID. +// Forks before Shanghai are triggered by the block number, +// while Shanghai and later forks are triggered by the block time. func TestCreation(t *testing.T) { type testcase struct { head uint64 @@ -48,32 +49,34 @@ func TestCreation(t *testing.T) { params.MainnetChainConfig, params.MainnetGenesisHash, []testcase{ - {0, 0, ID{Hash: checksumToBytes(0xfc64ec04), Next: 1150000}}, // Unsynced - {1149999, 0, ID{Hash: checksumToBytes(0xfc64ec04), Next: 1150000}}, // Last Frontier block - {1150000, 0, ID{Hash: checksumToBytes(0x97c2c34c), Next: 1920000}}, // First Homestead block - {1919999, 0, ID{Hash: checksumToBytes(0x97c2c34c), Next: 1920000}}, // Last Homestead block - {1920000, 0, ID{Hash: checksumToBytes(0x91d1f948), Next: 2463000}}, // First DAO block - {2462999, 0, ID{Hash: checksumToBytes(0x91d1f948), Next: 2463000}}, // Last DAO block - {2463000, 0, ID{Hash: checksumToBytes(0x7a64da13), Next: 2675000}}, // First Tangerine block - {2674999, 0, ID{Hash: checksumToBytes(0x7a64da13), Next: 2675000}}, // Last Tangerine block - {2675000, 0, ID{Hash: checksumToBytes(0x3edd5b10), Next: 4370000}}, // First Spurious block - {4369999, 0, ID{Hash: checksumToBytes(0x3edd5b10), Next: 4370000}}, // Last Spurious block - {4370000, 0, ID{Hash: checksumToBytes(0xa00bc324), Next: 7280000}}, // First Byzantium block - {7279999, 0, ID{Hash: checksumToBytes(0xa00bc324), Next: 7280000}}, // Last Byzantium block - {7280000, 0, ID{Hash: checksumToBytes(0x668db0af), Next: 9069000}}, // First and last Constantinople, first Petersburg block - {9068999, 0, ID{Hash: checksumToBytes(0x668db0af), Next: 9069000}}, // Last Petersburg block - {9069000, 0, ID{Hash: checksumToBytes(0x879d6e30), Next: 9200000}}, // First Istanbul block - {9199999, 0, ID{Hash: checksumToBytes(0x879d6e30), Next: 9200000}}, // Last Istanbul block - {9200000, 0, ID{Hash: checksumToBytes(0xe029e991), Next: 12244000}}, // First Muir Glacier block - {12243999, 0, ID{Hash: checksumToBytes(0xe029e991), Next: 12244000}}, // Last Muir Glacier block - {12244000, 0, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // First Berlin block - {12964999, 0, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // Last Berlin block - {12965000, 0, ID{Hash: checksumToBytes(0xb715077d), Next: 13773000}}, // First London block - {13772999, 0, ID{Hash: checksumToBytes(0xb715077d), Next: 13773000}}, // Last London block - {13773000, 0, ID{Hash: checksumToBytes(0x20c327fc), Next: 15050000}}, // First Arrow Glacier block - {15049999, 0, ID{Hash: checksumToBytes(0x20c327fc), Next: 15050000}}, // Last Arrow Glacier block - {15050000, 0, ID{Hash: checksumToBytes(0xf0afd0e3), Next: 0}}, // First Gray Glacier block - {20000000, 0, ID{Hash: checksumToBytes(0xf0afd0e3), Next: 0}}, // Future Gray Glacier block + {0, 0, ID{Hash: checksumToBytes(0xfc64ec04), Next: 1150000}}, // Unsynced + {1149999, 1457981342, ID{Hash: checksumToBytes(0xfc64ec04), Next: 1150000}}, // Last Frontier block + {1150000, 1457981393, ID{Hash: checksumToBytes(0x97c2c34c), Next: 1920000}}, // First Homestead block + {1919999, 1469020838, ID{Hash: checksumToBytes(0x97c2c34c), Next: 1920000}}, // Last Homestead block + {1920000, 1469020840, ID{Hash: checksumToBytes(0x91d1f948), Next: 2463000}}, // First DAO block + {2462999, 1476796747, ID{Hash: checksumToBytes(0x91d1f948), Next: 2463000}}, // Last DAO block + {2463000, 1476796771, ID{Hash: checksumToBytes(0x7a64da13), Next: 2675000}}, // First Tangerine block + {2674999, 1479831337, ID{Hash: checksumToBytes(0x7a64da13), Next: 2675000}}, // Last Tangerine block + {2675000, 1479831344, ID{Hash: checksumToBytes(0x3edd5b10), Next: 4370000}}, // First Spurious block + {4369999, 1508131303, ID{Hash: checksumToBytes(0x3edd5b10), Next: 4370000}}, // Last Spurious block + {4370000, 1508131331, ID{Hash: checksumToBytes(0xa00bc324), Next: 7280000}}, // First Byzantium block + {7279999, 1551383501, ID{Hash: checksumToBytes(0xa00bc324), Next: 7280000}}, // Last Byzantium block + {7280000, 1551383524, ID{Hash: checksumToBytes(0x668db0af), Next: 9069000}}, // First and last Constantinople, first Petersburg block + {9068999, 1575764708, ID{Hash: checksumToBytes(0x668db0af), Next: 9069000}}, // Last Petersburg block + {9069000, 1575764709, ID{Hash: checksumToBytes(0x879d6e30), Next: 9200000}}, // First Istanbul block + {9199999, 1577953806, ID{Hash: checksumToBytes(0x879d6e30), Next: 9200000}}, // Last Istanbul block + {9200000, 1577953849, ID{Hash: checksumToBytes(0xe029e991), Next: 12244000}}, // First Muir Glacier block + {12243999, 1618481214, ID{Hash: checksumToBytes(0xe029e991), Next: 12244000}}, // Last Muir Glacier block + {12244000, 1618481223, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // First Berlin block + {12964999, 1628166812, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // Last Berlin block + {12965000, 1628166822, ID{Hash: checksumToBytes(0xb715077d), Next: 13773000}}, // First London block + {13772999, 1639079715, ID{Hash: checksumToBytes(0xb715077d), Next: 13773000}}, // Last London block + {13773000, 1639079723, ID{Hash: checksumToBytes(0x20c327fc), Next: 15050000}}, // First Arrow Glacier block + {15049999, 1656586434, ID{Hash: checksumToBytes(0x20c327fc), Next: 15050000}}, // Last Arrow Glacier block + {15050000, 1656586444, ID{Hash: checksumToBytes(0xf0afd0e3), Next: 1681338455}}, // First Gray Glacier block + {17037484, 1681338443, ID{Hash: checksumToBytes(0xf0afd0e3), Next: 1681338455}}, // Last pre-Shanghai block (approx) + {17037485, 1681338455, ID{Hash: checksumToBytes(0xdce96c2d), Next: 0}}, // First Shanghai block (approx) + {19000000, 1700000000, ID{Hash: checksumToBytes(0xdce96c2d), Next: 0}}, // Future Shanghai block (mock) }, }, // Rinkeby test cases @@ -112,8 +115,9 @@ func TestCreation(t *testing.T) { {4460644, 1616045391, ID{Hash: checksumToBytes(0x757a1c47), Next: 5062605}}, // First Berlin block {5062604, 1625109564, ID{Hash: checksumToBytes(0x757a1c47), Next: 5062605}}, // Last Berlin block {5062605, 1625109579, ID{Hash: checksumToBytes(0xB8C6299D), Next: 1678832736}}, // First London block - {8671878, 1678832724, ID{Hash: checksumToBytes(0xB8C6299D), Next: 1678832736}}, // Last pre-Shanghai block (approx height) - {8671879, 1678832736, ID{Hash: checksumToBytes(0xf9843abf), Next: 0}}, // First Shanghai block (approx height) + {8656122, 1678832724, ID{Hash: checksumToBytes(0xB8C6299D), Next: 1678832736}}, // Last pre-Shanghai block + {8656123, 1678832784, ID{Hash: checksumToBytes(0xf9843abf), Next: 0}}, // First Shanghai block + {9900000, 1700000000, ID{Hash: checksumToBytes(0xf9843abf), Next: 0}}, // Future Shanghai block (mock) }, }, // Sepolia test cases @@ -126,6 +130,7 @@ func TestCreation(t *testing.T) { {1735371, 1661130108, ID{Hash: checksumToBytes(0xb96cbd13), Next: 1677557088}}, // First MergeNetsplit block {2990907, 1677557076, ID{Hash: checksumToBytes(0xb96cbd13), Next: 1677557088}}, // Last pre-Shanghai block {2990908, 1677557088, ID{Hash: checksumToBytes(0xf7f9bc08), Next: 0}}, // First Shanghai block + {5000000, 1700000000, ID{Hash: checksumToBytes(0xf7f9bc08), Next: 0}}, // Future Shanghai block (mock) }, }, // Gnosis test cases @@ -167,104 +172,6 @@ func TestCreation(t *testing.T) { } } -// TestCreationWithTimestamps tests that different genesis and fork rule combinations result in -// the correct fork ID even for time based forks. -func TestCreationWithTimestamps(t *testing.T) { - mergeConfig := *params.MainnetChainConfig - mergeConfig.MergeNetsplitBlock = big.NewInt(18000000) - - withdrawalConfig := *params.MainnetChainConfig - withdrawalConfig.MergeNetsplitBlock = big.NewInt(18000000) - withdrawalConfig.ShanghaiTime = big.NewInt(1668000000) - type testcase struct { - head uint64 - time uint64 - want ID - } - tests := []struct { - config *chain.Config - genesis libcommon.Hash - cases []testcase - }{ - // Mainnet test cases - { - params.MainnetChainConfig, - params.MainnetGenesisHash, - []testcase{ - {0, 0, ID{Hash: checksumToBytes(0xfc64ec04), Next: 1150000}}, // Unsynced - {1149999, 0, ID{Hash: checksumToBytes(0xfc64ec04), Next: 1150000}}, // Last Frontier block - {1150000, 0, ID{Hash: checksumToBytes(0x97c2c34c), Next: 1920000}}, // First Homestead block - {1919999, 0, ID{Hash: checksumToBytes(0x97c2c34c), Next: 1920000}}, // Last Homestead block - {1920000, 0, ID{Hash: checksumToBytes(0x91d1f948), Next: 2463000}}, // First DAO block - {2462999, 0, ID{Hash: checksumToBytes(0x91d1f948), Next: 2463000}}, // Last DAO block - {2463000, 0, ID{Hash: checksumToBytes(0x7a64da13), Next: 2675000}}, // First Tangerine block - {2674999, 0, ID{Hash: checksumToBytes(0x7a64da13), Next: 2675000}}, // Last Tangerine block - {2675000, 0, ID{Hash: checksumToBytes(0x3edd5b10), Next: 4370000}}, // First Spurious block - {4369999, 0, ID{Hash: checksumToBytes(0x3edd5b10), Next: 4370000}}, // Last Spurious block - {4370000, 0, ID{Hash: checksumToBytes(0xa00bc324), Next: 7280000}}, // First Byzantium block - {7279999, 0, ID{Hash: checksumToBytes(0xa00bc324), Next: 7280000}}, // Last Byzantium block - {7280000, 0, ID{Hash: checksumToBytes(0x668db0af), Next: 9069000}}, // First and last Constantinople, first Petersburg block - {9068999, 0, ID{Hash: checksumToBytes(0x668db0af), Next: 9069000}}, // Last Petersburg block - {9069000, 0, ID{Hash: checksumToBytes(0x879d6e30), Next: 9200000}}, // First Istanbul and first Muir Glacier block - {9199999, 0, ID{Hash: checksumToBytes(0x879d6e30), Next: 9200000}}, // Last Istanbul and first Muir Glacier block - {9200000, 0, ID{Hash: checksumToBytes(0xe029e991), Next: 12244000}}, // First Muir Glacier block - {12243999, 0, ID{Hash: checksumToBytes(0xe029e991), Next: 12244000}}, // Last Muir Glacier block - {12244000, 0, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // First Berlin block - {12964999, 0, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // Last Berlin block - {12965000, 0, ID{Hash: checksumToBytes(0xb715077d), Next: 13773000}}, // First London block - {13772999, 0, ID{Hash: checksumToBytes(0xb715077d), Next: 13773000}}, // Last London block - {13773000, 0, ID{Hash: checksumToBytes(0x20c327fc), Next: 15050000}}, // First Arrow Glacier block - {15049999, 0, ID{Hash: checksumToBytes(0x20c327fc), Next: 15050000}}, // Last Arrow Glacier block - {15050000, 0, ID{Hash: checksumToBytes(0xf0afd0e3), Next: 0}}, // First Gray Glacier block - {20000000, 0, ID{Hash: checksumToBytes(0xf0afd0e3), Next: 0}}, // Future Gray Glacier block - }, - }, - // Withdrawal test cases - { - &withdrawalConfig, - params.MainnetGenesisHash, - []testcase{ - {0, 0, ID{Hash: checksumToBytes(0xfc64ec04), Next: 1150000}}, // Unsynced - {1149999, 0, ID{Hash: checksumToBytes(0xfc64ec04), Next: 1150000}}, // Last Frontier block - {1150000, 0, ID{Hash: checksumToBytes(0x97c2c34c), Next: 1920000}}, // First Homestead block - {1919999, 0, ID{Hash: checksumToBytes(0x97c2c34c), Next: 1920000}}, // Last Homestead block - {1920000, 0, ID{Hash: checksumToBytes(0x91d1f948), Next: 2463000}}, // First DAO block - {2462999, 0, ID{Hash: checksumToBytes(0x91d1f948), Next: 2463000}}, // Last DAO block - {2463000, 0, ID{Hash: checksumToBytes(0x7a64da13), Next: 2675000}}, // First Tangerine block - {2674999, 0, ID{Hash: checksumToBytes(0x7a64da13), Next: 2675000}}, // Last Tangerine block - {2675000, 0, ID{Hash: checksumToBytes(0x3edd5b10), Next: 4370000}}, // First Spurious block - {4369999, 0, ID{Hash: checksumToBytes(0x3edd5b10), Next: 4370000}}, // Last Spurious block - {4370000, 0, ID{Hash: checksumToBytes(0xa00bc324), Next: 7280000}}, // First Byzantium block - {7279999, 0, ID{Hash: checksumToBytes(0xa00bc324), Next: 7280000}}, // Last Byzantium block - {7280000, 0, ID{Hash: checksumToBytes(0x668db0af), Next: 9069000}}, // First and last Constantinople, first Petersburg block - {9068999, 0, ID{Hash: checksumToBytes(0x668db0af), Next: 9069000}}, // Last Petersburg block - {9069000, 0, ID{Hash: checksumToBytes(0x879d6e30), Next: 9200000}}, // First Istanbul and first Muir Glacier block - {9199999, 0, ID{Hash: checksumToBytes(0x879d6e30), Next: 9200000}}, // Last Istanbul and first Muir Glacier block - {9200000, 0, ID{Hash: checksumToBytes(0xe029e991), Next: 12244000}}, // First Muir Glacier block - {12243999, 0, ID{Hash: checksumToBytes(0xe029e991), Next: 12244000}}, // Last Muir Glacier block - {12244000, 0, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // First Berlin block - {12964999, 0, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // Last Berlin block - {12965000, 0, ID{Hash: checksumToBytes(0xb715077d), Next: 13773000}}, // First London block - {13772999, 0, ID{Hash: checksumToBytes(0xb715077d), Next: 13773000}}, // Last London block - {13773000, 0, ID{Hash: checksumToBytes(0x20c327fc), Next: 15050000}}, // First Arrow Glacier block - {15049999, 0, ID{Hash: checksumToBytes(0x20c327fc), Next: 15050000}}, // Last Arrow Glacier block - {15050000, 0, ID{Hash: checksumToBytes(0xf0afd0e3), Next: 18000000}}, // First Gray Glacier block - {18000000, 0, ID{Hash: checksumToBytes(0x4fb8a872), Next: 1668000000}}, // First Merge Start block - {20000000, 0, ID{Hash: checksumToBytes(0x4fb8a872), Next: 1668000000}}, // Last Merge Start block - {20000000, 1668000000, ID{Hash: checksumToBytes(0xc1fdf181), Next: 0}}, // First Merge Start block - {20000000, 2668000000, ID{Hash: checksumToBytes(0xc1fdf181), Next: 0}}, // Future Merge Start block - }, - }, - } - for i, tt := range tests { - for j, ttt := range tt.cases { - if have := NewID(tt.config, tt.genesis, ttt.head, ttt.time); have != ttt.want { - t.Errorf("test %d, case %d: fork ID mismatch: have %x, want %x", i, j, have, ttt.want) - } - } - } -} - // TestValidation tests that a local peer correctly validates and accepts a remote // fork ID. func TestValidation(t *testing.T) { diff --git a/params/chainspecs/mainnet.json b/params/chainspecs/mainnet.json index 53c4920b92e..f8070f1a13d 100644 --- a/params/chainspecs/mainnet.json +++ b/params/chainspecs/mainnet.json @@ -19,5 +19,6 @@ "grayGlacierBlock": 15050000, "terminalTotalDifficulty": 58750000000000000000000, "terminalTotalDifficultyPassed": true, + "shanghaiTime": 1681338455, "ethash": {} } From 8ad487042829fa8d495eacd5c4f7238e6d5bc118 Mon Sep 17 00:00:00 2001 From: Giulio rebuffo Date: Sat, 18 Mar 2023 20:45:53 +0100 Subject: [PATCH 11/18] Banning peers sending bad gossip (#7134) --- cmd/lightclient/lightclient/lightclient.go | 2 +- cmd/lightclient/lightclient/subscriber.go | 41 ++++++++++++++++++---- cmd/sentinel/sentinel/peers/peers.go | 2 +- cmd/sentinel/sentinel/service/notifiers.go | 4 ++- cmd/sentinel/sentinel/service/service.go | 34 ++++++++++++++---- go.mod | 2 +- go.sum | 4 +-- 7 files changed, 69 insertions(+), 20 deletions(-) diff --git a/cmd/lightclient/lightclient/lightclient.go b/cmd/lightclient/lightclient/lightclient.go index e0cc3780ba3..6de12ab87fd 100644 --- a/cmd/lightclient/lightclient/lightclient.go +++ b/cmd/lightclient/lightclient/lightclient.go @@ -145,7 +145,7 @@ func (l *LightClient) Start() { for _, update := range updates { err := l.processLightClientUpdate(update) if err != nil { - log.Warn("Could not validate update", "err", err) + log.Debug("Could not validate update", "err", err) updates = []*cltypes.LightClientUpdate{} break } diff --git a/cmd/lightclient/lightclient/subscriber.go b/cmd/lightclient/lightclient/subscriber.go index 9eb148cb115..f27b90ad9ea 100644 --- a/cmd/lightclient/lightclient/subscriber.go +++ b/cmd/lightclient/lightclient/subscriber.go @@ -5,7 +5,9 @@ import ( "errors" "fmt" "sync" + "time" + "github.com/ledgerwatch/erigon-lib/gointerfaces/grpcutil" "github.com/ledgerwatch/erigon-lib/gointerfaces/sentinel" "github.com/ledgerwatch/erigon/cl/clparams" "github.com/ledgerwatch/erigon/cl/cltypes" @@ -46,24 +48,40 @@ func (c *ChainTipSubscriber) StartLoop() { } log.Info("[LightClient Gossip] Started Gossip") c.started = true + +Retry: + for { + if err := c.subscribeGossip(); err != nil { + if errors.Is(err, context.Canceled) { + return + } + if grpcutil.IsRetryLater(err) || grpcutil.IsEndOfStream(err) { + time.Sleep(3 * time.Second) + continue Retry + } + + log.Debug("[Lightclient] could not read gossip :/", "reason", err) + time.Sleep(time.Second) + } + } +} + +func (c *ChainTipSubscriber) subscribeGossip() error { stream, err := c.sentinel.SubscribeGossip(c.ctx, &sentinel.EmptyMessage{}) if err != nil { - log.Warn("could not start lightclient", "reason", err) - return + return err } defer stream.CloseSend() for { data, err := stream.Recv() if err != nil { - if !errors.Is(err, context.Canceled) { - log.Debug("[Lightclient] could not read gossip :/", "reason", err) - } - continue + return err } if err := c.handleGossipData(data); err != nil { - log.Warn("could not process new gossip", + log.Debug("could not process new gossip", "gossipType", data.Type, "reason", err) + } } } @@ -79,6 +97,9 @@ func (c *ChainTipSubscriber) handleGossipData(data *sentinel.GossipData) error { case sentinel.GossipType_BeaconBlockGossipType: block := &cltypes.SignedBeaconBlock{} if err := block.DecodeSSZWithVersion(data.Data, int(version)); err != nil { + if _, err := c.sentinel.BanPeer(c.ctx, data.Peer); err != nil { + return err + } return fmt.Errorf("could not unmarshall block: %s", err) } @@ -87,6 +108,9 @@ func (c *ChainTipSubscriber) handleGossipData(data *sentinel.GossipData) error { case sentinel.GossipType_LightClientFinalityUpdateGossipType: finalityUpdate := &cltypes.LightClientFinalityUpdate{} if err := finalityUpdate.DecodeSSZWithVersion(data.Data, int(version)); err != nil { + if _, err := c.sentinel.BanPeer(c.ctx, data.Peer); err != nil { + return err + } return fmt.Errorf("could not unmarshall finality update: %s", err) } c.lastUpdate = &cltypes.LightClientUpdate{ @@ -106,6 +130,9 @@ func (c *ChainTipSubscriber) handleGossipData(data *sentinel.GossipData) error { optimisticUpdate := &cltypes.LightClientOptimisticUpdate{} if err := optimisticUpdate.DecodeSSZWithVersion(data.Data, int(version)); err != nil { + if _, err := c.sentinel.BanPeer(c.ctx, data.Peer); err != nil { + return err + } return fmt.Errorf("could not unmarshall optimistic update: %s", err) } c.lastUpdate = &cltypes.LightClientUpdate{ diff --git a/cmd/sentinel/sentinel/peers/peers.go b/cmd/sentinel/sentinel/peers/peers.go index 413bc735430..1e2859b091f 100644 --- a/cmd/sentinel/sentinel/peers/peers.go +++ b/cmd/sentinel/sentinel/peers/peers.go @@ -24,7 +24,7 @@ import ( ) const ( - maxBadPeers = 50 + maxBadPeers = 50000 maxPeerRecordSize = 1000 DefaultMaxPeers = 33 MaxBadResponses = 50 diff --git a/cmd/sentinel/sentinel/service/notifiers.go b/cmd/sentinel/sentinel/service/notifiers.go index 9d0fca70921..594f2609252 100644 --- a/cmd/sentinel/sentinel/service/notifiers.go +++ b/cmd/sentinel/sentinel/service/notifiers.go @@ -14,6 +14,7 @@ const ( type gossipObject struct { data []byte // gossip data t sentinel.GossipType // determine which gossip message we are notifying of + pid string } type gossipNotifier struct { @@ -28,7 +29,7 @@ func newGossipNotifier() *gossipNotifier { } } -func (g *gossipNotifier) notify(t sentinel.GossipType, data []byte) { +func (g *gossipNotifier) notify(t sentinel.GossipType, data []byte, pid string) { g.mu.Lock() defer g.mu.Unlock() @@ -36,6 +37,7 @@ func (g *gossipNotifier) notify(t sentinel.GossipType, data []byte) { ch <- gossipObject{ data: data, t: t, + pid: pid, } } } diff --git a/cmd/sentinel/sentinel/service/service.go b/cmd/sentinel/sentinel/service/service.go index 2d8b3b55809..29dbea812db 100644 --- a/cmd/sentinel/sentinel/service/service.go +++ b/cmd/sentinel/sentinel/service/service.go @@ -14,6 +14,7 @@ import ( "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/communication" "github.com/ledgerwatch/log/v3" pubsub "github.com/libp2p/go-libp2p-pubsub" + "github.com/libp2p/go-libp2p/core/peer" ) type SentinelServer struct { @@ -32,6 +33,17 @@ func NewSentinelServer(ctx context.Context, sentinel *sentinel.Sentinel) *Sentin } } +//BanPeer(context.Context, *Peer) (*EmptyMessage, error) + +func (s *SentinelServer) BanPeer(_ context.Context, p *sentinelrpc.Peer) (*sentinelrpc.EmptyMessage, error) { + var pid peer.ID + if err := pid.UnmarshalText([]byte(p.Pid)); err != nil { + return nil, err + } + s.sentinel.Peers().BanBadPeer(pid) + return &sentinelrpc.EmptyMessage{}, nil +} + func (s *SentinelServer) SubscribeGossip(_ *sentinelrpc.EmptyMessage, stream sentinelrpc.Sentinel_SubscribeGossipServer) error { // first of all subscribe ch, subId, err := s.gossipNotifier.addSubscriber() @@ -49,6 +61,9 @@ func (s *SentinelServer) SubscribeGossip(_ *sentinelrpc.EmptyMessage, stream sen if err := stream.Send(&sentinelrpc.GossipData{ Data: packet.data, Type: packet.t, + Peer: &sentinelrpc.Peer{ + Pid: packet.pid, + }, }); err != nil { log.Warn("[Sentinel] Could not relay gossip packet", "reason", err) } @@ -131,6 +146,7 @@ func (s *SentinelServer) handleGossipPacket(pkt *pubsub.Message) error { var err error log.Trace("[Sentinel Gossip] Received Packet", "topic", pkt.Topic) data := pkt.GetData() + // If we use snappy codec then decompress it accordingly. if strings.Contains(*pkt.Topic, sentinel.SSZSnappyCodec) { data, err = utils.DecompressSnappy(data) @@ -138,21 +154,25 @@ func (s *SentinelServer) handleGossipPacket(pkt *pubsub.Message) error { return err } } + textPid, err := pkt.ReceivedFrom.MarshalText() + if err != nil { + return err + } // Check to which gossip it belongs to. if strings.Contains(*pkt.Topic, string(sentinel.BeaconBlockTopic)) { - s.gossipNotifier.notify(sentinelrpc.GossipType_BeaconBlockGossipType, data) + s.gossipNotifier.notify(sentinelrpc.GossipType_BeaconBlockGossipType, data, string(textPid)) } else if strings.Contains(*pkt.Topic, string(sentinel.BeaconAggregateAndProofTopic)) { - s.gossipNotifier.notify(sentinelrpc.GossipType_AggregateAndProofGossipType, data) + s.gossipNotifier.notify(sentinelrpc.GossipType_AggregateAndProofGossipType, data, string(textPid)) } else if strings.Contains(*pkt.Topic, string(sentinel.VoluntaryExitTopic)) { - s.gossipNotifier.notify(sentinelrpc.GossipType_VoluntaryExitGossipType, data) + s.gossipNotifier.notify(sentinelrpc.GossipType_VoluntaryExitGossipType, data, string(textPid)) } else if strings.Contains(*pkt.Topic, string(sentinel.ProposerSlashingTopic)) { - s.gossipNotifier.notify(sentinelrpc.GossipType_ProposerSlashingGossipType, data) + s.gossipNotifier.notify(sentinelrpc.GossipType_ProposerSlashingGossipType, data, string(textPid)) } else if strings.Contains(*pkt.Topic, string(sentinel.AttesterSlashingTopic)) { - s.gossipNotifier.notify(sentinelrpc.GossipType_AttesterSlashingGossipType, data) + s.gossipNotifier.notify(sentinelrpc.GossipType_AttesterSlashingGossipType, data, string(textPid)) } else if strings.Contains(*pkt.Topic, string(sentinel.LightClientFinalityUpdateTopic)) { - s.gossipNotifier.notify(sentinelrpc.GossipType_LightClientFinalityUpdateGossipType, data) + s.gossipNotifier.notify(sentinelrpc.GossipType_LightClientFinalityUpdateGossipType, data, string(textPid)) } else if strings.Contains(*pkt.Topic, string(sentinel.LightClientOptimisticUpdateTopic)) { - s.gossipNotifier.notify(sentinelrpc.GossipType_LightClientOptimisticUpdateGossipType, data) + s.gossipNotifier.notify(sentinelrpc.GossipType_LightClientOptimisticUpdateGossipType, data, string(textPid)) } return nil } diff --git a/go.mod b/go.mod index 2f39375dfe9..4269870df8e 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/ledgerwatch/erigon go 1.18 require ( - github.com/ledgerwatch/erigon-lib v0.0.0-20230306114514-2c4c92fd1fce + github.com/ledgerwatch/erigon-lib v0.0.0-20230328191829-416af23d9dcd github.com/ledgerwatch/erigon-snapshot v1.1.1-0.20230306083105-1391330d62a3 github.com/ledgerwatch/log/v3 v3.7.0 github.com/ledgerwatch/secp256k1 v1.0.0 diff --git a/go.sum b/go.sum index 10d3cc143ee..24662fefc07 100644 --- a/go.sum +++ b/go.sum @@ -517,8 +517,8 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3PYPwICLl+/9oulQauOuETfgFvhBDffs0= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= -github.com/ledgerwatch/erigon-lib v0.0.0-20230306114514-2c4c92fd1fce h1:KsoGX2RLGvqTc97Et7wAwaRNk1/RDAUbe20B9TM7/70= -github.com/ledgerwatch/erigon-lib v0.0.0-20230306114514-2c4c92fd1fce/go.mod h1:/xzmS14QeWZFjRXDiTdeqcSW4IrrUSYkCXZRfsZ5XbI= +github.com/ledgerwatch/erigon-lib v0.0.0-20230328191829-416af23d9dcd h1:VUp9woJj6sVoZO6lIwOOm4qA5Qe0LRiOpUn84cy3ohw= +github.com/ledgerwatch/erigon-lib v0.0.0-20230328191829-416af23d9dcd/go.mod h1:nyJqfX9uPm1P/poZB1211DFe5DnAKOhYqvkEPyW7dXM= github.com/ledgerwatch/erigon-snapshot v1.1.1-0.20230306083105-1391330d62a3 h1:tfzawK1gIIgRjVZeANXOr0Ziu+kqCIBuKMe0TXfl5Aw= github.com/ledgerwatch/erigon-snapshot v1.1.1-0.20230306083105-1391330d62a3/go.mod h1:3AuPxZc85jkehh/HA9h8gabv5MSi3kb/ddtzBsTVJFo= github.com/ledgerwatch/log/v3 v3.7.0 h1:aFPEZdwZx4jzA3+/Pf8wNDN5tCI0cIolq/kfvgcM+og= From b8eaf78b174151fd98b0d1cc48796c33cefa5ee9 Mon Sep 17 00:00:00 2001 From: Andrew Ashikhmin <34320705+yperbasis@users.noreply.github.com> Date: Tue, 28 Mar 2023 17:27:14 +0200 Subject: [PATCH 12/18] Release transaction in EngineGetPayloadBodiesByRangeV1 (and by hash) (#7199) Should hopefully help with Issue #7172 --- ethdb/privateapi/ethbackend.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ethdb/privateapi/ethbackend.go b/ethdb/privateapi/ethbackend.go index 1f9ae3c7c11..ded53ba96b2 100644 --- a/ethdb/privateapi/ethbackend.go +++ b/ethdb/privateapi/ethbackend.go @@ -713,6 +713,7 @@ func (s *EthBackendServer) EngineGetPayloadBodiesByHashV1(ctx context.Context, r if err != nil { return nil, err } + defer tx.Rollback() bodies := make([]*types2.ExecutionPayloadBodyV1, len(request.Hashes)) @@ -738,6 +739,7 @@ func (s *EthBackendServer) EngineGetPayloadBodiesByRangeV1(ctx context.Context, if err != nil { return nil, err } + defer tx.Rollback() bodies := make([]*types2.ExecutionPayloadBodyV1, 0, request.Count) From beb97784d43ece5acde365a74efe8763692ebdba Mon Sep 17 00:00:00 2001 From: Giulio rebuffo Date: Sat, 18 Mar 2023 18:15:59 +0100 Subject: [PATCH 13/18] Error handling to beacon chain gossip (#7132) --- cl/cltypes/ssz_utils/ssz.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cl/cltypes/ssz_utils/ssz.go b/cl/cltypes/ssz_utils/ssz.go index 80b9999a1d8..91a48b3ac0d 100644 --- a/cl/cltypes/ssz_utils/ssz.go +++ b/cl/cltypes/ssz_utils/ssz.go @@ -99,7 +99,9 @@ func DecodeDynamicList[T Unmarshaler](bytes []byte, start, end, max uint32) ([]T return nil, ErrBadOffset } objs[i] = objs[i].Clone().(T) - objs[i].DecodeSSZ(buf[currentOffset:endOffset]) + if err := objs[i].DecodeSSZ(buf[currentOffset:endOffset]); err != nil { + return nil, err + } currentOffset = endOffset } return objs, nil @@ -121,7 +123,9 @@ func DecodeStaticList[T Unmarshaler](bytes []byte, start, end, bytesPerElement u objs := make([]T, elementsNum) for i := range objs { objs[i] = objs[i].Clone().(T) - objs[i].DecodeSSZ(buf[i*int(bytesPerElement):]) + if err := objs[i].DecodeSSZ(buf[i*int(bytesPerElement):]); err != nil { + return nil, err + } } return objs, nil } From 1cd02faa91a12635b4aceda67038e34511c60dca Mon Sep 17 00:00:00 2001 From: "Temirlan \"Qjawko\" Yermagambet" Date: Thu, 6 Apr 2023 14:27:49 +0600 Subject: [PATCH 14/18] add grpc-health-probe to Dockerfile --- Dockerfile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Dockerfile b/Dockerfile index b056ba02615..68b9af68eae 100644 --- a/Dockerfile +++ b/Dockerfile @@ -38,6 +38,11 @@ FROM docker.io/library/alpine:3.17 RUN apk add --no-cache ca-certificates libstdc++ tzdata RUN apk add --no-cache curl jq bind-tools +WORKDIR /usr/local/bin +RUN wget https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/v0.4.11/grpc_health_probe-linux-amd64 -P /usr/local/bin/ && \ + mv /usr/local/bin/grpc_health_probe-linux-amd64 /usr/local/bin/grpc_health_probe && \ + chmod +x /usr/local/bin/grpc_health_probe + # Setup user and group # # from the perspective of the container, uid=1000, gid=1000 is a sensible choice From 4c0970cd48ddc7e3b2e059c4e3c8f07123b0b2e9 Mon Sep 17 00:00:00 2001 From: "Temirlan \"Qjawko\" Yermagambet" Date: Wed, 26 Apr 2023 14:46:10 +0100 Subject: [PATCH 15/18] luban fork support; light client features; upstream erigon main repo --- Dockerfile | 1 + Dockerfile.debian | 2 +- Makefile | 19 +- README.md | 89 +- accounts/abi/bind/backends/simulated.go | 74 +- accounts/abi/bind/backends/simulated_test.go | 4 +- accounts/abi/bind/bind_test.go | 9 +- cl/clparams/config.go | 25 +- cl/cltypes/attestations.go | 142 +- cl/cltypes/beacon_header.go | 4 + cl/cltypes/checkpoint.go | 18 +- cl/cltypes/clone.go | 16 - cl/cltypes/eth1_block.go | 310 +- cl/cltypes/eth1_data.go | 5 + cl/cltypes/eth1_header.go | 216 + cl/cltypes/fork.go | 8 + cl/cltypes/lightclient.go | 630 --- cl/cltypes/lightclient_test.go | 115 - cl/cltypes/network_test.go | 53 +- cl/cltypes/validator.go | 13 + cl/fork/fork_test.go | 2 +- cl/fork/id.go | 99 - cl/rpc/rpc.go | 115 +- cmd/abigen/main.go | 2 +- cmd/bootnode/main.go | 2 +- cmd/caplin-phase1/caplin1/run.go | 31 + cmd/{lightclient => caplin-phase1}/main.go | 48 +- cmd/devnet/commands/all.go | 4 +- cmd/devnet/commands/block.go | 30 +- cmd/devnet/devnetutils/utils.go | 4 +- cmd/devnet/models/model.go | 2 + cmd/devnet/node/node.go | 6 +- cmd/devnet/requests/block.go | 15 + cmd/devnet/requests/request_generator.go | 5 + cmd/devnet/requests/tx.go | 30 +- cmd/devnet/services/block.go | 29 +- cmd/devnet/services/tx.go | 10 +- cmd/downloader/main.go | 13 +- .../consensus_tests/consensus_tester.go | 8 +- cmd/ef-tests-cl/consensus_tests/fork.go | 54 + cmd/ef-tests-cl/consensus_tests/sanity.go | 14 +- cmd/erigon-cl/core/rawdb/accessors.go | 80 - cmd/erigon-cl/core/rawdb/accessors_test.go | 15 +- cmd/erigon-cl/core/state/accessors.go | 232 +- cmd/erigon-cl/core/state/mutators.go | 12 +- cmd/erigon-cl/core/state/root.go | 4 + cmd/erigon-cl/core/state/setters.go | 100 +- cmd/erigon-cl/core/state/state.go | 227 +- cmd/erigon-cl/core/state/upgrade.go | 95 + cmd/erigon-cl/core/transition/operations.go | 102 +- .../core/transition/operations_test.go | 26 - .../core/transition/process_attestations.go | 2 +- .../core/transition/process_slots.go | 2 +- .../execution_client/execution_engine.go | 148 + cmd/erigon-cl/forkchoice/fork_choice_test.go | 88 + .../forkchoice/fork_graph/fork_graph.go | 284 ++ .../forkchoice/fork_graph/fork_graph_test.go | 49 + cmd/erigon-cl/forkchoice/forkchoice.go | 133 + cmd/erigon-cl/forkchoice/get_head.go | 160 + cmd/erigon-cl/forkchoice/on_attestation.go | 108 + .../forkchoice/on_attester_slashing.go | 48 + cmd/erigon-cl/forkchoice/on_block.go | 78 + cmd/erigon-cl/forkchoice/on_tick.go | 30 + .../test_data/anchor_state.ssz_snappy | Bin 0 -> 173183 bytes ...d7ea3b028a501967747d96e49068cb6.ssz_snappy | Bin 0 -> 183 bytes ...b73695d3dc638bacfb6c8b7bcbee1a9.ssz_snappy | Bin 0 -> 318 bytes ...d155fa8ca1f874df305fa376ce334cf.ssz_snappy | Bin 0 -> 314 bytes ...087e422aace49a7c3816cf59bafb0ad.ssz_snappy | Bin 0 -> 318 bytes cmd/erigon-cl/forkchoice/utils.go | 94 + cmd/erigon-cl/main.go | 41 +- cmd/erigon-cl/network/beacon_downloader.go | 53 +- cmd/erigon-cl/network/gossip_manager.go | 137 +- cmd/erigon-cl/stages/stage_beacon_blocks.go | 183 - cmd/erigon-cl/stages/stage_fork_choice.go | 173 + cmd/erigon-cl/stages/stages.go | 23 +- cmd/erigon-cl/stages/stages_beacon_state.go | 97 +- cmd/erigon-el/backend/backend.go | 29 +- cmd/erigon-el/main.go | 6 +- cmd/erigon/main.go | 7 +- cmd/evm/internal/t8ntool/execution.go | 3 + cmd/evm/internal/t8ntool/flags.go | 2 +- cmd/evm/internal/t8ntool/gen_stenv.go | 12 + cmd/evm/internal/t8ntool/transition.go | 46 +- cmd/evm/main.go | 6 +- cmd/evm/runner.go | 22 +- cmd/evm/staterunner.go | 17 +- cmd/evm/t8n_test.go | 8 + cmd/evm/testdata/26/alloc.json | 8 + cmd/evm/testdata/26/env.json | 17 + cmd/evm/testdata/26/exp.json | 18 + cmd/evm/testdata/26/txs.json | 1 + cmd/hack/hack.go | 2 +- cmd/integration/commands/stages.go | 6 +- cmd/integration/commands/state_domains.go | 762 ++++ cmd/lightclient/LICENSE | 201 - cmd/lightclient/lightclient/checkpoint.go | 63 - cmd/lightclient/lightclient/execution.go | 116 - cmd/lightclient/lightclient/lightclient.go | 268 -- .../lightclient/process_updates.go | 111 - cmd/lightclient/lightclient/request.go | 26 - cmd/lightclient/lightclient/store.go | 65 - cmd/lightclient/lightclient/subscriber.go | 172 - cmd/lightclient/lightclient/verify.go | 110 - cmd/observer/database/db_sqlite.go | 3 +- cmd/p2psim/main.go | 3 +- cmd/prometheus/dashboards/erigon.json | 3689 ++++++++--------- cmd/rpcdaemon/README.md | 2 +- cmd/rpcdaemon/commands/call_traces_test.go | 16 +- cmd/rpcdaemon/commands/daemon.go | 2 +- cmd/rpcdaemon/commands/db_api_deprecated.go | 12 +- cmd/rpcdaemon/commands/debug_api.go | 99 +- cmd/rpcdaemon/commands/engine_api.go | 126 +- cmd/rpcdaemon/commands/eth_accounts.go | 6 +- cmd/rpcdaemon/commands/eth_api.go | 36 +- cmd/rpcdaemon/commands/eth_call.go | 124 +- cmd/rpcdaemon/commands/eth_callMany_test.go | 17 +- cmd/rpcdaemon/commands/eth_call_test.go | 388 +- cmd/rpcdaemon/commands/eth_deprecated.go | 7 +- cmd/rpcdaemon/commands/eth_receipts.go | 6 +- cmd/rpcdaemon/commands/eth_subscribe_test.go | 3 - cmd/rpcdaemon/commands/eth_txs.go | 7 +- cmd/rpcdaemon/commands/gen_traces_test.go | 4 +- cmd/rpcdaemon/commands/otterscan_api.go | 6 +- .../commands/otterscan_generic_tracer.go | 3 +- .../commands/otterscan_search_trace.go | 3 +- .../commands/otterscan_trace_transaction.go | 14 +- .../commands/otterscan_transaction_error.go | 5 +- cmd/rpcdaemon/commands/parity_api.go | 8 +- cmd/rpcdaemon/commands/parity_api_test.go | 11 +- cmd/rpcdaemon/commands/send_transaction.go | 4 +- cmd/rpcdaemon/commands/trace_adhoc.go | 64 +- cmd/rpcdaemon/commands/trace_adhoc_test.go | 4 +- cmd/rpcdaemon/commands/trace_api.go | 12 +- cmd/rpcdaemon/commands/trace_filtering.go | 148 +- cmd/rpcdaemon/commands/trace_types.go | 55 +- cmd/rpcdaemon/commands/tracing.go | 20 +- cmd/rpcdaemon/commands/txpool_api_test.go | 3 - cmd/rpcdaemon/commands/web3_api.go | 7 +- cmd/rpcdaemon/graphql/graph/helpers.go | 5 +- cmd/rpcdaemon/main.go | 4 +- cmd/rpcdaemon/rpcservices/eth_backend.go | 6 + cmd/rpctest/rpctest/bench_tracecallmany.go | 3 +- cmd/rpctest/rpctest/request_generator.go | 14 +- cmd/rpctest/rpctest/type.go | 27 +- cmd/sentinel/cli/cliSettings.go | 10 +- cmd/sentinel/main.go | 190 +- cmd/sentinel/sentinel/discovery.go | 6 +- cmd/sentinel/sentinel/handlers/blocks.go | 4 + cmd/sentinel/sentinel/handlers/handlers.go | 2 - cmd/sentinel/sentinel/handshake/handshake.go | 11 +- cmd/sentinel/sentinel/handshake/rules.go | 44 - cmd/sentinel/sentinel/msg_id.go | 60 + cmd/sentinel/sentinel/msg_id_test.go | 50 + cmd/sentinel/sentinel/peers/peers.go | 16 +- cmd/sentinel/sentinel/pubsub.go | 126 +- cmd/sentinel/sentinel/request.go | 9 +- cmd/sentinel/sentinel/sentinel.go | 97 +- cmd/sentinel/sentinel/service/service.go | 13 +- cmd/sentinel/sentinel/service/start.go | 46 +- cmd/sentinel/sentinel/utils.go | 26 +- cmd/sentinel/sentinel/utils_test.go | 31 - cmd/sentry/main.go | 6 +- cmd/sentry/sentry/eth_handshake.go | 4 +- cmd/sentry/sentry/sentry_grpc_server.go | 18 +- cmd/state/commands/erigon4.go | 14 +- cmd/state/commands/history22.go | 3 +- cmd/state/commands/opcode_tracer.go | 5 +- cmd/state/exec22/txtask.go | 313 +- cmd/state/exec3/state.go | 99 +- cmd/state/exec3/state_recon.go | 97 +- cmd/txpool/main.go | 28 +- cmd/txpool/readme.md | 2 +- cmd/utils/customflags_test.go | 41 - cmd/utils/diskusage_windows.go | 38 - cmd/utils/flags.go | 127 +- cmd/utils/{customflags.go => flags/flags.go} | 186 +- cmd/utils/flags/flags_test.go | 61 + cmd/utils/flags/helpers.go | 200 + common/hexutil/json.go | 45 - common/hexutil/json_example_test.go | 4 +- common/hexutil/json_test.go | 74 - common/math/integer.go | 7 + common/paths/paths.go | 2 - consensus/aura/aura.go | 203 +- consensus/aura/aura_test.go | 193 +- consensus/aura/config.go | 75 +- consensus/aura/config_test.go | 17 +- consensus/aura/consensusconfig/embed.go | 32 - consensus/aura/consensusconfig/kovan.json | 36 - consensus/aura/consensusconfig/poachiado.json | 34 - consensus/aura/consensusconfig/poagnosis.json | 36 - consensus/aura/consensusconfig/poasokol.json | 28 - consensus/aura/consensusconfig/test.json | 28 - consensus/aura/oe-test/authority_round.json | 96 - ...authority_round_block_reward_contract.json | 103 - .../oe-test/authority_round_empty_steps.json | 51 - .../authority_round_randomness_contract.json | 100 - consensus/aura/test/authority_round.json | 96 - ...authority_round_block_reward_contract.json | 14 - .../test/authority_round_empty_steps.json | 51 - .../authority_round_randomness_contract.json | 100 - consensus/aura/test/embed.go | 8 - consensus/aura/validators.go | 12 +- consensus/bor/api.go | 32 +- consensus/bor/bor.go | 6 +- consensus/bor/clerk/clerk.go | 5 +- consensus/bor/snapshot.go | 38 +- consensus/clique/clique.go | 28 +- consensus/clique/snapshot.go | 6 +- consensus/clique/verifier.go | 8 + consensus/consensus.go | 19 +- consensus/db/db.go | 4 +- consensus/ethash/consensus.go | 26 +- consensus/misc/eip4844.go | 84 + consensus/parlia/abi.go | 1602 ++++++- consensus/parlia/lubanFork.go | 37 + consensus/parlia/parlia.go | 542 ++- consensus/parlia/ramanujanfork.go | 6 +- .../{snapshot_test.go => snaoshot_test.go} | 0 consensus/parlia/snapshot.go | 164 +- consensus/parlia/util.go | 83 + consensus/parlia/utils.go | 31 - consensus/serenity/serenity.go | 30 +- core/allocs/bsc.json | 98 +- core/allocs/chapel.json | 98 +- core/allocs/sokol.json | 35 - core/blockchain.go | 139 +- core/chain_makers.go | 6 +- core/evm.go | 32 +- core/forkid/forkid.go | 5 + core/gen_genesis.go | 80 +- core/gen_genesis_account.go | 14 +- core/genesis.go | 645 ++- core/genesis_test.go | 77 +- core/state/database_test.go | 6 +- core/state/dump.go | 20 +- core/state/rw_v3.go | 493 ++- core/state/temporal/kv_temporal.go | 160 +- core/state_processor.go | 8 +- core/state_transition.go | 9 + core/systemcontracts/upgrade.go | 175 +- core/types/accounts/account_proof.go | 24 + core/types/blob_tx_wrapper.go | 439 ++ core/types/block.go | 271 +- core/types/bloom9.go | 3 +- core/types/gen_erigon_log_json.go | 5 +- core/types/gen_header_json.go | 5 +- core/types/gen_log_json.go | 5 +- core/types/gen_receipt_json.go | 5 +- core/types/genesis.go | 165 + core/types/hashing.go | 11 + core/types/log.go | 3 +- core/types/receipt.go | 3 +- core/types/signed_blob_tx.go | 596 +++ core/types/transaction.go | 64 +- core/types/transaction_marshalling.go | 12 +- core/types/vote.go | 91 + core/vm/contracts.go | 122 +- core/vm/contracts_lightclient.go | 146 +- core/vm/contracts_lightclient_test.go | 159 +- core/vm/eips.go | 23 + core/vm/evm.go | 29 +- core/vm/lightclient/v1/ics23_proof.go | 107 + .../lightclient/{ => v1}/multistoreproof.go | 15 +- .../vm/lightclient/{ => v1}/rootmultistore.go | 3 +- core/vm/lightclient/{ => v1}/types.go | 51 +- core/vm/lightclient/{ => v1}/utils.go | 2 +- core/vm/lightclient/{ => v1}/wire.go | 2 +- core/vm/lightclient/v2/lightclient.go | 233 ++ core/vm/lightclient/v2/lightclient_test.go | 174 + crypto/kzg/kzg.go | 113 + crypto/signature_nocgo.go | 68 +- dataflow/states.go | 106 + diagnostics/block_body_download.go | 34 + diagnostics/cmd_line.go | 22 + diagnostics/logs_access.go | 6 + diagnostics/version.go | 25 + docker-compose.yml | 4 +- eth/backend.go | 57 +- eth/ethconfig/config.go | 2 +- eth/ethconfig/estimate/esitmated_ram.go | 30 +- eth/ethconfig/gen_config.go | 28 +- eth/ethconsensusconfig/config.go | 32 +- eth/gasprice/feehistory.go | 78 +- eth/stagedsync/README.md | 60 +- eth/stagedsync/exec3.go | 669 +-- eth/stagedsync/stage_bodies.go | 50 +- eth/stagedsync/stage_cumulative_index.go | 4 +- eth/stagedsync/stage_execute.go | 17 +- eth/stagedsync/stage_headers.go | 22 +- eth/stagedsync/stage_mining_exec.go | 12 +- eth/stagedsync/stage_snapshots.go | 8 +- .../internal/tracetest/calltrace_test.go | 42 +- .../internal/tracetest/prestate_test.go | 12 +- eth/tracers/logger/gen_structlog.go | 10 +- eth/tracers/logger/logger.go | 7 +- eth/tracers/native/call.go | 10 +- eth/tracers/native/gen_account_json.go | 5 +- eth/tracers/native/gen_callframe_json.go | 9 +- eth/tracers/native/prestate.go | 4 +- eth/tracers/tracers_test.go | 15 +- ethdb/privateapi/ethbackend.go | 56 +- go.mod | 134 +- go.sum | 1218 +++++- interfaces.go | 14 +- node/node.go | 6 +- node/node_test.go | 7 +- node/nodecfg/config.go | 3 +- p2p/enode/nodedb.go | 2 +- params/bootnodes.go | 15 +- params/chainspecs/bsc.json | 52 +- params/chainspecs/chapel.json | 5 +- params/chainspecs/chiado.json | 36 +- params/chainspecs/gnosis.json | 38 +- params/chainspecs/rialto.json | 49 +- params/chainspecs/ropsten.json | 17 + params/chainspecs/sokol.json | 19 - params/config.go | 15 - params/mining.go | 5 +- params/networkname/network_name.go | 2 - params/protocol_params.go | 8 +- params/version.go | 8 +- tests/block_test_util.go | 4 +- tests/fuzzers/secp256k1/secp_fuzzer.go | 4 +- tests/gen_btheader.go | 6 +- tests/state_test_util.go | 15 +- tests/statedb_chain_test.go | 38 +- .../statedb_insert_chain_transaction_test.go | 28 +- tests/testdata | 1 - tests/transaction_test_util.go | 9 +- turbo/adapter/ethapi/api.go | 27 +- turbo/app/import.go | 4 +- turbo/app/init.go | 2 +- turbo/app/snapshots.go | 21 +- turbo/app/support.go | 184 +- turbo/cli/default_flags.go | 3 +- turbo/cli/flags.go | 11 +- turbo/debug/flags.go | 7 +- turbo/logging/flags.go | 2 +- turbo/logging/logging.go | 59 +- turbo/node/node.go | 3 +- turbo/rpchelper/interface.go | 1 + turbo/shards/state_change_accumulator.go | 2 +- turbo/snapshotsync/block_reader.go | 1 + turbo/snapshotsync/block_snapshots.go | 20 +- turbo/stages/blockchain_test.go | 28 +- turbo/stages/bodydownload/body_algos.go | 12 + turbo/stages/chain_makers_test.go | 2 +- .../stages/headerdownload/header_algo_test.go | 4 +- turbo/stages/headerdownload/header_algos.go | 54 +- .../headerdownload/header_data_struct.go | 82 +- turbo/stages/mock_sentry.go | 85 +- turbo/transactions/call.go | 11 +- turbo/transactions/tracing.go | 19 +- turbo/trie/gen_struct_step.go | 59 +- turbo/trie/hashbuilder.go | 57 +- turbo/trie/retain_list.go | 171 +- turbo/trie/retain_list_test.go | 106 + turbo/trie/trie_root.go | 148 +- 359 files changed, 17500 insertions(+), 10287 deletions(-) create mode 100644 cl/cltypes/eth1_header.go delete mode 100644 cl/cltypes/lightclient.go delete mode 100644 cl/cltypes/lightclient_test.go delete mode 100644 cl/fork/id.go create mode 100644 cmd/caplin-phase1/caplin1/run.go rename cmd/{lightclient => caplin-phase1}/main.go (66%) create mode 100644 cmd/ef-tests-cl/consensus_tests/fork.go create mode 100644 cmd/erigon-cl/core/state/upgrade.go create mode 100644 cmd/erigon-cl/execution_client/execution_engine.go create mode 100644 cmd/erigon-cl/forkchoice/fork_choice_test.go create mode 100644 cmd/erigon-cl/forkchoice/fork_graph/fork_graph.go create mode 100644 cmd/erigon-cl/forkchoice/fork_graph/fork_graph_test.go create mode 100644 cmd/erigon-cl/forkchoice/forkchoice.go create mode 100644 cmd/erigon-cl/forkchoice/get_head.go create mode 100644 cmd/erigon-cl/forkchoice/on_attestation.go create mode 100644 cmd/erigon-cl/forkchoice/on_attester_slashing.go create mode 100644 cmd/erigon-cl/forkchoice/on_block.go create mode 100644 cmd/erigon-cl/forkchoice/on_tick.go create mode 100644 cmd/erigon-cl/forkchoice/test_data/anchor_state.ssz_snappy create mode 100644 cmd/erigon-cl/forkchoice/test_data/attestation_0xfb924d35b2888d9cd70e6879c1609e6cad7ea3b028a501967747d96e49068cb6.ssz_snappy create mode 100644 cmd/erigon-cl/forkchoice/test_data/block_0x3af8b5b42ca135c75b32abb32b3d71badb73695d3dc638bacfb6c8b7bcbee1a9.ssz_snappy create mode 100644 cmd/erigon-cl/forkchoice/test_data/block_0xc2788d6005ee2b92c3df2eff0aeab0374d155fa8ca1f874df305fa376ce334cf.ssz_snappy create mode 100644 cmd/erigon-cl/forkchoice/test_data/block_0xd4503d46e43df56de4e19acb0f93b3b52087e422aace49a7c3816cf59bafb0ad.ssz_snappy create mode 100644 cmd/erigon-cl/forkchoice/utils.go delete mode 100644 cmd/erigon-cl/stages/stage_beacon_blocks.go create mode 100644 cmd/erigon-cl/stages/stage_fork_choice.go create mode 100644 cmd/evm/testdata/26/alloc.json create mode 100644 cmd/evm/testdata/26/env.json create mode 100644 cmd/evm/testdata/26/exp.json create mode 100644 cmd/evm/testdata/26/txs.json create mode 100644 cmd/integration/commands/state_domains.go delete mode 100644 cmd/lightclient/LICENSE delete mode 100644 cmd/lightclient/lightclient/checkpoint.go delete mode 100644 cmd/lightclient/lightclient/execution.go delete mode 100644 cmd/lightclient/lightclient/lightclient.go delete mode 100644 cmd/lightclient/lightclient/process_updates.go delete mode 100644 cmd/lightclient/lightclient/request.go delete mode 100644 cmd/lightclient/lightclient/store.go delete mode 100644 cmd/lightclient/lightclient/subscriber.go delete mode 100644 cmd/lightclient/lightclient/verify.go delete mode 100644 cmd/sentinel/sentinel/handshake/rules.go create mode 100644 cmd/sentinel/sentinel/msg_id.go create mode 100644 cmd/sentinel/sentinel/msg_id_test.go delete mode 100644 cmd/utils/customflags_test.go delete mode 100644 cmd/utils/diskusage_windows.go rename cmd/utils/{customflags.go => flags/flags.go} (50%) create mode 100644 cmd/utils/flags/flags_test.go create mode 100644 cmd/utils/flags/helpers.go delete mode 100644 consensus/aura/consensusconfig/embed.go delete mode 100644 consensus/aura/consensusconfig/kovan.json delete mode 100644 consensus/aura/consensusconfig/poachiado.json delete mode 100644 consensus/aura/consensusconfig/poagnosis.json delete mode 100644 consensus/aura/consensusconfig/poasokol.json delete mode 100644 consensus/aura/consensusconfig/test.json delete mode 100644 consensus/aura/oe-test/authority_round.json delete mode 100644 consensus/aura/oe-test/authority_round_block_reward_contract.json delete mode 100644 consensus/aura/oe-test/authority_round_empty_steps.json delete mode 100644 consensus/aura/oe-test/authority_round_randomness_contract.json delete mode 100644 consensus/aura/test/authority_round.json delete mode 100644 consensus/aura/test/authority_round_block_reward_contract.json delete mode 100644 consensus/aura/test/authority_round_empty_steps.json delete mode 100644 consensus/aura/test/authority_round_randomness_contract.json delete mode 100644 consensus/aura/test/embed.go create mode 100644 consensus/misc/eip4844.go create mode 100644 consensus/parlia/lubanFork.go rename consensus/parlia/{snapshot_test.go => snaoshot_test.go} (100%) create mode 100644 consensus/parlia/util.go delete mode 100644 consensus/parlia/utils.go delete mode 100644 core/allocs/sokol.json create mode 100644 core/types/accounts/account_proof.go create mode 100644 core/types/blob_tx_wrapper.go create mode 100644 core/types/genesis.go create mode 100644 core/types/signed_blob_tx.go create mode 100644 core/types/vote.go create mode 100644 core/vm/lightclient/v1/ics23_proof.go rename core/vm/lightclient/{ => v1}/multistoreproof.go (87%) rename core/vm/lightclient/{ => v1}/rootmultistore.go (98%) rename core/vm/lightclient/{ => v1}/types.go (85%) rename core/vm/lightclient/{ => v1}/utils.go (99%) rename core/vm/lightclient/{ => v1}/wire.go (92%) create mode 100644 core/vm/lightclient/v2/lightclient.go create mode 100644 core/vm/lightclient/v2/lightclient_test.go create mode 100644 crypto/kzg/kzg.go create mode 100644 dataflow/states.go create mode 100644 diagnostics/block_body_download.go create mode 100644 diagnostics/cmd_line.go create mode 100644 diagnostics/version.go create mode 100644 params/chainspecs/ropsten.json delete mode 100644 params/chainspecs/sokol.json delete mode 160000 tests/testdata create mode 100644 turbo/trie/retain_list_test.go diff --git a/Dockerfile b/Dockerfile index 68b9af68eae..c11b6aeb82f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -81,6 +81,7 @@ COPY --from=builder /app/build/bin/sentry /usr/local/bin/sentry COPY --from=builder /app/build/bin/state /usr/local/bin/state COPY --from=builder /app/build/bin/txpool /usr/local/bin/txpool COPY --from=builder /app/build/bin/verkle /usr/local/bin/verkle +COPY --from=builder /app/build/bin/caplin-phase1 /usr/local/bin/caplin-phase1 diff --git a/Dockerfile.debian b/Dockerfile.debian index 91154739756..7cf40a1e903 100644 --- a/Dockerfile.debian +++ b/Dockerfile.debian @@ -65,7 +65,6 @@ COPY --from=builder /app/build/bin/erigon-cl /usr/local/bin/erigon-cl COPY --from=builder /app/build/bin/evm /usr/local/bin/evm COPY --from=builder /app/build/bin/hack /usr/local/bin/hack COPY --from=builder /app/build/bin/integration /usr/local/bin/integration -COPY --from=builder /app/build/bin/lightclient /usr/local/bin/lightclient COPY --from=builder /app/build/bin/observer /usr/local/bin/observer COPY --from=builder /app/build/bin/pics /usr/local/bin/pics COPY --from=builder /app/build/bin/rpcdaemon /usr/local/bin/rpcdaemon @@ -75,6 +74,7 @@ COPY --from=builder /app/build/bin/sentry /usr/local/bin/sentry COPY --from=builder /app/build/bin/state /usr/local/bin/state COPY --from=builder /app/build/bin/txpool /usr/local/bin/txpool COPY --from=builder /app/build/bin/verkle /usr/local/bin/verkle +COPY --from=builder /app/build/bin/caplin-phase1 /usr/local/bin/caplin-phase1 EXPOSE 8545 \ 8551 \ diff --git a/Makefile b/Makefile index 8a587de4e75..68e1c7ddcc4 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ CGO_CFLAGS += -Wno-error=strict-prototypes # for Clang15, remove it when can htt CGO_CFLAGS := CGO_CFLAGS="$(CGO_CFLAGS)" DBG_CGO_CFLAGS += -DMDBX_DEBUG=1 -BUILD_TAGS = nosqlite,noboltdb +BUILD_TAGS = nosqlite,noboltdb,netgo # about netgo see: https://github.com/golang/go/issues/30310#issuecomment-471669125 PACKAGE = github.com/ledgerwatch/erigon GO_FLAGS += -trimpath -tags $(BUILD_TAGS) -buildvcs=false @@ -42,8 +42,8 @@ default: all ## go-version: print and verify go version go-version: - @if [ $(shell $(GO) version | cut -c 16-17) -lt 18 ]; then \ - echo "minimum required Golang version is 1.18"; \ + @if [ $(shell $(GO) version | cut -c 16-17) -lt 19 ]; then \ + echo "minimum required Golang version is 1.19"; \ exit 1 ;\ fi @@ -120,9 +120,9 @@ COMMANDS += state COMMANDS += txpool COMMANDS += verkle COMMANDS += evm -COMMANDS += lightclient COMMANDS += sentinel -COMMANDS += erigon-el +COMMANDS += erigon-el +COMMANDS += caplin-phase1 # build each command using %.cmd rule $(COMMANDS): %: %.cmd @@ -136,6 +136,7 @@ db-tools: go mod vendor cd vendor/github.com/torquem-ch/mdbx-go && MDBX_BUILD_TIMESTAMP=unknown make tools + mkdir -p $(GOBIN) cd vendor/github.com/torquem-ch/mdbx-go/mdbxdist && cp mdbx_chk $(GOBIN) && cp mdbx_copy $(GOBIN) && cp mdbx_dump $(GOBIN) && cp mdbx_drop $(GOBIN) && cp mdbx_load $(GOBIN) && cp mdbx_stat $(GOBIN) rm -rf vendor @echo "Run \"$(GOBIN)/mdbx_stat -h\" to get info about mdbx db file." @@ -166,7 +167,7 @@ lintci: ## lintci-deps: (re)installs golangci-lint to build/bin/golangci-lint lintci-deps: rm -f ./build/bin/golangci-lint - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b ./build/bin v1.51.1 + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b ./build/bin v1.52.2 ## clean: cleans the go cache, build dir, libmdbx db dir clean: @@ -181,10 +182,10 @@ devtools: # Notice! If you adding new binary - add it also to cmd/hack/binary-deps/main.go file $(GOBUILD) -o $(GOBIN)/go-bindata github.com/kevinburke/go-bindata/go-bindata $(GOBUILD) -o $(GOBIN)/gencodec github.com/fjl/gencodec - $(GOBUILD) -o $(GOBIN)/codecgen github.com/ugorji/go/codec/codecgen $(GOBUILD) -o $(GOBIN)/abigen ./cmd/abigen + $(GOBUILD) -o $(GOBIN)/codecgen github.com/ugorji/go/codec/codecgen PATH=$(GOBIN):$(PATH) go generate ./common - PATH=$(GOBIN):$(PATH) go generate ./core/types +# PATH=$(GOBIN):$(PATH) go generate ./core/types PATH=$(GOBIN):$(PATH) go generate ./consensus/aura/... #PATH=$(GOBIN):$(PATH) go generate ./eth/ethconfig/... @type "npm" 2> /dev/null || echo 'Please install node.js and npm' @@ -214,7 +215,7 @@ git-submodules: @git submodule update --quiet --init --recursive --force || true PACKAGE_NAME := github.com/ledgerwatch/erigon -GOLANG_CROSS_VERSION ?= v1.19.5 +GOLANG_CROSS_VERSION ?= v1.20.2 .PHONY: release-dry-run release-dry-run: git-submodules diff --git a/README.md b/README.md index 0b2f698b8ad..127fc7bb3d5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # Erigon -Erigon is an implementation of Ethereum (execution client with light client for consensus layer), on the efficiency frontier. [Archive Node](https://ethereum.org/en/developers/docs/nodes-and-clients/archive-nodes/#what-is-an-archive-node) by default. +Erigon is an implementation of Ethereum (execution client with light client for consensus layer), on the efficiency +frontier. [Archive Node](https://ethereum.org/en/developers/docs/nodes-and-clients/archive-nodes/#what-is-an-archive-node) +by default. ![Build status](https://github.com/ledgerwatch/erigon/actions/workflows/ci.yml/badge.svg) @@ -24,7 +26,7 @@ Erigon is an implementation of Ethereum (execution client with light client for + [Faster Initial Sync](#faster-initial-sync) + [JSON-RPC daemon](#json-rpc-daemon) + [Run all components by docker-compose](#run-all-components-by-docker-compose) - + [Grafana dashboar god](#grafana-dashboard) + + [Grafana dashboard](#grafana-dashboard) - [Documentation](#documentation) - [FAQ](#faq) - [Getting in touch](#getting-in-touch) @@ -39,7 +41,8 @@ Erigon is an implementation of Ethereum (execution client with light client for **Disclaimer**: this software is currently a tech preview. We will do our best to keep it stable and make no breaking changes but we don't guarantee anything. Things can and will break. -**Important defaults**: Erigon is an Archive Node by default (to remove history see: `--prune` flags in `erigon --help`). We don't allow change this flag after first start. +**Important defaults**: Erigon is an Archive Node by default (to remove history see: `--prune` flags +in `erigon --help`). We don't allow change this flag after first start. In-depth links are marked by the microscope sign (🔬) @@ -54,16 +57,16 @@ System Requirements * Gnosis Chain Archive: 370GB (January 2023). -* BSC Archive: 7TB. BSC Full: 1TB. +* BSC Archive: 7TB. BSC Full: 1TB. (April 2022). -* Polygon Mainnet Archive: 5TB. Polygon Mumbai Archive: 1TB. +* Polygon Mainnet Archive: 5TB. Polygon Mumbai Archive: 1TB. (April 2022). SSD or NVMe. Do not recommend HDD - on HDD Erigon will always stay N blocks behind chain tip, but not fall behind. Bear in mind that SSD performance deteriorates when close to capacity. RAM: >=16GB, 64-bit architecture. -[Golang version >= 1.18](https://golang.org/doc/install); GCC 10+ or Clang; On Linux: kernel > v4 +[Golang version >= 1.19](https://golang.org/doc/install); GCC 10+ or Clang; On Linux: kernel > v4 🔬 more details on disk storage [here](https://erigon.substack.com/p/disk-footprint-changes-in-new-erigon?s=r) and [here](https://ledgerwatch.github.io/turbo_geth_release.html#Disk-space). @@ -94,39 +97,41 @@ make erigon ./build/bin/erigon ``` -Default `--snapshots` for `mainnet`, `goerli`, `gnosis`, `bsc`. Other networks now have default `--snapshots=false`. Increase +Default `--snapshots` for `mainnet`, `goerli`, `gnosis`, `bsc`. Other networks now have default `--snapshots=false`. +Increase download speed by flag `--torrent.download.rate=20mb`. 🔬 See [Downloader docs](./cmd/downloader/readme.md) Use `--datadir` to choose where to store data. -Use `--chain=gnosis` for [Gnosis Chain](https://www.gnosis.io/), `--chain=bor-mainnet` for Polygon Mainnet, and `--chain=mumbai` for Polygon Mumbai. -For Gnosis Chain you need a [Consensus Layer](#beacon-chain-consensus-layer) client alongside Erigon (https://docs.gnosischain.com/node/guide/beacon). +Use `--chain=gnosis` for [Gnosis Chain](https://www.gnosis.io/), `--chain=bor-mainnet` for Polygon Mainnet, +and `--chain=mumbai` for Polygon Mumbai. +For Gnosis Chain you need a [Consensus Layer](#beacon-chain-consensus-layer) client alongside +Erigon (https://docs.gnosischain.com/node/guide/beacon). Running `make help` will list and describe the convenience commands available in the [Makefile](./Makefile). ### Datadir structure -- chaindata: recent blocks, state, recent state history. low-latency disk recommended. +- chaindata: recent blocks, state, recent state history. low-latency disk recommended. - snapshots: old blocks, old state history. can symlink/mount it to cheaper disk. mostly immutable. - temp: can grow to ~100gb, but usually empty. can symlink/mount it to cheaper disk. - txpool: pending transactions. safe to remove. - nodes: p2p peers. safe to remove. - ### Logging -_Flags:_ - - - `verbosity` - - `log.console.verbosity` (overriding alias for `verbosity`) - - `log.json` - - `log.console.json` (alias for `log.json`) - - `log.dir.path` - - `log.dir.verbosity` - - `log.dir.json` +_Flags:_ +- `verbosity` +- `log.console.verbosity` (overriding alias for `verbosity`) +- `log.json` +- `log.console.json` (alias for `log.json`) +- `log.dir.path` +- `log.dir.verbosity` +- `log.dir.json` -In order to log only to the stdout/stderr the `--verbosity` (or `log.console.verbosity`) flag can be used to supply an int value specifying the highest output log level: +In order to log only to the stdout/stderr the `--verbosity` (or `log.console.verbosity`) flag can be used to supply an +int value specifying the highest output log level: ``` LvlCrit = 0 @@ -137,9 +142,12 @@ In order to log only to the stdout/stderr the `--verbosity` (or `log.console.ver LvlTrace = 5 ``` -To set an output dir for logs to be collected on disk, please set `--log.dir.path`. The flag `--log.dir.verbosity` is also available to control the verbosity of this logging, with the same int value as above, or the string value e.g. 'debug' or 'info'. Default verbosity is 'debug' (4), for disk logging. +To set an output dir for logs to be collected on disk, please set `--log.dir.path`. The flag `--log.dir.verbosity` is +also available to control the verbosity of this logging, with the same int value as above, or the string value e.g. ' +debug' or 'info'. Default verbosity is 'debug' (4), for disk logging. -Log format can be set to json by the use of the boolean flags `log.json` or `log.console.json`, or for the disk output `--log.dir.json`. +Log format can be set to json by the use of the boolean flags `log.json` or `log.console.json`, or for the disk +output `--log.dir.json`. ### Modularity @@ -151,9 +159,10 @@ How to start Erigon's services as separated processes, see in [docker-compose.ym ### Embedded Consensus Layer -By default, on Ethereum Mainnet, Görli, and Sepolia, the Engine API is disabled in favour of the Erigon native Embedded Consensus Layer. -If you want to use an external Consensus Layer, run Erigon with flag `--externalcl`. -_Warning:_ Staking (block production) is not possible with the embedded CL – use `--externalcl` instead. +On Ethereum Mainnet, Görli, and Sepolia, the Engine API can be disabled in favour of the Erigon native Embedded +Consensus Layer. +If you want to use the internal Consensus Layer, run Erigon with flag `--internalcl`. +_Warning:_ Staking (block production) is not possible with the embedded CL. ### Testnets @@ -202,7 +211,7 @@ Windows users may run erigon in 3 possible ways: build on windows : * [Git](https://git-scm.com/downloads) for Windows must be installed. If you're cloning this repository is very likely you already have it - * [GO Programming Language](https://golang.org/dl/) must be installed. Minimum required version is 1.18 + * [GO Programming Language](https://golang.org/dl/) must be installed. Minimum required version is 1.19 * GNU CC Compiler at least version 10 (is highly suggested that you install `chocolatey` package manager - see following point) * If you need to build MDBX tools (i.e. `.\wmake.ps1 db-tools`) @@ -369,7 +378,8 @@ Examples of stages are: ### JSON-RPC daemon -Most of Erigon's components (txpool, rpcdaemon, snapshots downloader, sentry, ...) can work inside Erigon and as independent process. +Most of Erigon's components (txpool, rpcdaemon, snapshots downloader, sentry, ...) can work inside Erigon and as +independent process. To enable built-in RPC server: `--http` and `--ws` (sharing same port with http) @@ -492,7 +502,8 @@ Windows support for docker-compose is not ready yet. Please help us with .ps1 po `docker-compose up prometheus grafana`, [detailed docs](./cmd/prometheus/Readme.md). -### +### + old data Disabled by default. To enable see `./build/bin/erigon --help` for flags `--prune` @@ -518,7 +529,7 @@ FAQ Detailed explanation: [./docs/programmers_guide/db_faq.md](./docs/programmers_guide/db_faq.md) -### Default Ports and Protocols / Firewalls? +### Default Ports and Firewalls #### `erigon` ports @@ -558,12 +569,11 @@ Port #### `sentinel` ports -| Port | Protocol | Purpose | Expose | -|:-----:|:---------:|:----------------:|:-------:| -| 4000 | UDP | Peering | Public | -| 4001 | TCP | Peering | Public | -| 7777 | TCP | gRPC Connections | Private | - +| Port | Protocol | Purpose | Expose | +|:----:|:--------:|:----------------:|:-------:| +| 4000 | UDP | Peering | Public | +| 4001 | TCP | Peering | Public | +| 7777 | TCP | gRPC Connections | Private | #### Other ports @@ -577,12 +587,13 @@ you'll have to change one if you want to run both at the same time. use `--help` Reserved for future use: **gRPC ports**: `9092` consensus engine, `9093` snapshot downloader, `9094` TxPool -Hetzner may want strict firewall rules, like: +#### Hetzner expecting strict firewall rules + ``` 0.0.0.0/8 "This" Network RFC 1122, Section 3.2.1.3 10.0.0.0/8 Private-Use Networks RFC 1918 100.64.0.0/10 Carrier-Grade NAT (CGN) RFC 6598, Section 7 -127.0.0.0/8 Loopback RFC 1122, Section 3.2.1.3 +127.16.0.0/12 Private-Use Networks RFC 1918 169.254.0.0/16 Link Local RFC 3927 172.16.0.0/12 Private-Use Networks RFC 1918 192.0.0.0/24 IETF Protocol Assignments RFC 5736 @@ -599,6 +610,8 @@ Hetzner may want strict firewall rules, like: RFC 922, Section 7 ``` +Same in [IpTables syntax](https://ethereum.stackexchange.com/questions/6386/how-to-prevent-being-blacklisted-for-running-an-ethereum-client/13068#13068) + ### How to get diagnostic for bug report? - Get stack trace: `kill -SIGUSR1 `, get trace and stop: `kill -6 ` diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 69a8238f46a..3c401323422 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -32,6 +32,7 @@ import ( "github.com/ledgerwatch/erigon-lib/kv" state2 "github.com/ledgerwatch/erigon-lib/state" types2 "github.com/ledgerwatch/erigon-lib/types" + "github.com/ledgerwatch/erigon/eth/ethconfig" "github.com/ledgerwatch/log/v3" ethereum "github.com/ledgerwatch/erigon" @@ -46,10 +47,8 @@ import ( "github.com/ledgerwatch/erigon/core/state" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/vm" - "github.com/ledgerwatch/erigon/ethdb/olddb" "github.com/ledgerwatch/erigon/event" "github.com/ledgerwatch/erigon/params" - "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/snapshotsync" "github.com/ledgerwatch/erigon/turbo/stages" ) @@ -79,6 +78,7 @@ type SimulatedBackend struct { gasPool *core.GasPool pendingBlock *types.Block // Currently pending block that will be imported on request pendingReader *state.PlainStateReader + pendingReaderTx kv.Tx pendingState *state.IntraBlockState // Currently pending state that will be the active on request rmLogsFeed event.Feed @@ -88,8 +88,8 @@ type SimulatedBackend struct { // NewSimulatedBackend creates a new binding backend using a simulated blockchain // for testing purposes. -func NewSimulatedBackendWithConfig(alloc core.GenesisAlloc, config *chain.Config, gasLimit uint64) *SimulatedBackend { - genesis := core.Genesis{Config: config, GasLimit: gasLimit, Alloc: alloc} +func NewSimulatedBackendWithConfig(alloc types.GenesisAlloc, config *chain.Config, gasLimit uint64) *SimulatedBackend { + genesis := types.Genesis{Config: config, GasLimit: gasLimit, Alloc: alloc} engine := ethash.NewFaker() m := stages.MockWithGenesisEngine(nil, &genesis, engine, false) backend := &SimulatedBackend{ @@ -110,25 +110,15 @@ func NewSimulatedBackendWithConfig(alloc core.GenesisAlloc, config *chain.Config } // A simulated backend always uses chainID 1337. -func NewSimulatedBackend(t *testing.T, alloc core.GenesisAlloc, gasLimit uint64) *SimulatedBackend { +func NewSimulatedBackend(t *testing.T, alloc types.GenesisAlloc, gasLimit uint64) *SimulatedBackend { b := NewSimulatedBackendWithConfig(alloc, params.TestChainConfig, gasLimit) - t.Cleanup(func() { - b.Close() - }) - if b.m.HistoryV3 { - t.Skip("TODO: Fixme") - } + t.Cleanup(b.Close) return b } -func NewTestSimulatedBackendWithConfig(t *testing.T, alloc core.GenesisAlloc, config *chain.Config, gasLimit uint64) *SimulatedBackend { +func NewTestSimulatedBackendWithConfig(t *testing.T, alloc types.GenesisAlloc, config *chain.Config, gasLimit uint64) *SimulatedBackend { b := NewSimulatedBackendWithConfig(alloc, config, gasLimit) - t.Cleanup(func() { - b.Close() - }) - if b.m.HistoryV3 { - t.Skip("TODO: Fixme") - } + t.Cleanup(b.Close) return b } func (b *SimulatedBackend) DB() kv.RwDB { return b.m.DB } @@ -141,6 +131,9 @@ func (b *SimulatedBackend) Engine() consensus.Engine { return b.m.Engine } // Close terminates the underlying blockchain's update loop. func (b *SimulatedBackend) Close() { + if b.pendingReaderTx != nil { + b.pendingReaderTx.Rollback() + } b.m.Close() } @@ -180,18 +173,29 @@ func (b *SimulatedBackend) emptyPendingBlock() { b.pendingReceipts = chain.Receipts[0] b.pendingHeader = chain.Headers[0] b.gasPool = new(core.GasPool).AddGas(b.pendingHeader.GasLimit) - b.pendingReader = state.NewPlainStateReader(olddb.NewObjectDatabase(b.m.DB)) + if b.pendingReaderTx != nil { + b.pendingReaderTx.Rollback() + } + tx, err := b.m.DB.BeginRo(context.Background()) + if err != nil { + panic(err) + } + b.pendingReaderTx = tx + if ethconfig.EnableHistoryV4InTest { + panic("implement me") + //b.pendingReader = state.NewReaderV4(b.pendingReaderTx.(kv.TemporalTx)) + } else { + b.pendingReader = state.NewPlainStateReader(b.pendingReaderTx) + } b.pendingState = state.New(b.pendingReader) } // stateByBlockNumber retrieves a state by a given blocknumber. func (b *SimulatedBackend) stateByBlockNumber(db kv.Tx, blockNumber *big.Int) *state.IntraBlockState { if blockNumber == nil || blockNumber.Cmp(b.pendingBlock.Number()) == 0 { - return state.New(state.NewPlainState(db, b.pendingBlock.NumberU64()+1, nil)) - //return state.New(b.m.NewHistoryStateReader(b.pendingBlock.NumberU64()+1, db)) + return state.New(b.m.NewHistoryStateReader(b.pendingBlock.NumberU64()+1, db)) } - return state.New(state.NewPlainState(db, blockNumber.Uint64()+1, nil)) - //return state.New(b.m.NewHistoryStateReader(blockNumber.Uint64()+1, db)) + return state.New(b.m.NewHistoryStateReader(blockNumber.Uint64()+1, db)) } // CodeAt returns the code associated with a certain account in the blockchain. @@ -570,9 +574,9 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs // Determine the lowest and highest possible gas limits to binary search in between var ( - lo = params.TxGas - 1 - hi uint64 - cap uint64 + lo = params.TxGas - 1 + hi uint64 + gasCap uint64 ) if call.Gas >= params.TxGas { hi = call.Gas @@ -600,7 +604,7 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs hi = allowance.Uint64() } } - cap = hi + gasCap = hi b.pendingState.Prepare(libcommon.Hash{}, libcommon.Hash{}, len(b.pendingBlock.Transactions())) // Create a helper to check if a gas allowance results in an executable transaction @@ -637,7 +641,7 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs } } // Reject the transaction as invalid if it still fails at the highest allowance - if hi == cap { + if hi == gasCap { failed, result, err := executable(hi) if err != nil { return 0, err @@ -650,7 +654,7 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs return 0, result.Err } // Otherwise, the specified gas cap is too low - return 0, fmt.Errorf("gas required exceeds allowance (%d)", cap) + return 0, fmt.Errorf("gas required exceeds allowance (%d)", gasCap) } } return hi, nil @@ -684,7 +688,8 @@ func (b *SimulatedBackend) callContract(_ context.Context, call ethereum.CallMsg txContext := core.NewEVMTxContext(msg) header := block.Header() - evmContext := core.NewEVMBlockContext(header, core.GetHashFn(header, b.getHeader), b.m.Engine, nil) + excessDataGas := header.ParentExcessDataGas(b.getHeader) + evmContext := core.NewEVMBlockContext(header, core.GetHashFn(header, b.getHeader), b.m.Engine, nil, excessDataGas) // Create a new environment which holds all relevant information // about the transaction and calling mechanisms. vmEnv := vm.NewEVM(evmContext, txContext, statedb, b.m.ChainConfig, vm.Config{}) @@ -717,7 +722,8 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx types.Transac &b.pendingHeader.Coinbase, b.gasPool, b.pendingState, state.NewNoopWriter(), b.pendingHeader, tx, - &b.pendingHeader.GasUsed, vm.Config{}); err != nil { + &b.pendingHeader.GasUsed, vm.Config{}, + b.pendingHeader.ParentExcessDataGas(b.getHeader)); err != nil { return err } //fmt.Printf("==== Start producing block %d\n", (b.prependBlock.NumberU64() + 1)) @@ -799,6 +805,11 @@ func (m callMsg) Data() []byte { return m.CallMsg.Data } func (m callMsg) AccessList() types2.AccessList { return m.CallMsg.AccessList } func (m callMsg) IsFree() bool { return false } +func (m callMsg) DataGas() uint64 { return params.DataGasPerBlob * uint64(len(m.CallMsg.DataHashes)) } +func (m callMsg) MaxFeePerDataGas() *uint256.Int { return m.CallMsg.MaxFeePerDataGas } +func (m callMsg) DataHashes() []libcommon.Hash { return m.CallMsg.DataHashes } + +/* // filterBackend implements filters.Backend to support filtering for logs without // taking bloom-bits acceleration structures into account. type filterBackend struct { @@ -895,3 +906,4 @@ func nullSubscription() event.Subscription { return nil }) } +*/ diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go index 2e984e3db71..a42141eb36b 100644 --- a/accounts/abi/bind/backends/simulated_test.go +++ b/accounts/abi/bind/backends/simulated_test.go @@ -36,7 +36,6 @@ import ( "github.com/ledgerwatch/erigon/common/u256" "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/core/rawdb" - "github.com/ledgerwatch/erigon/core/state" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/params" @@ -148,8 +147,7 @@ func TestNewSimulatedBackend(t *testing.T) { t.Fatal(err) } - //statedb := sim.stateByBlockNumber(tx, big.NewInt(int64(num+1))) - statedb := state.New(state.NewPlainState(tx, num+1, nil)) + statedb := sim.stateByBlockNumber(tx, big.NewInt(int64(num+1))) bal := statedb.GetBalance(testAddr) if !bal.Eq(expectedBal) { t.Errorf("expected balance for test address not received. expected: %v actual: %v", expectedBal, bal) diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index c0778687809..4c3f2be0cb4 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -1849,11 +1849,18 @@ func TestGolangBindings(t *testing.T) { t.Fatalf("failed to replace binding test dependency to current source tree: %v\n%s", err, out) } - replacer = exec.Command(gocmd, "mod", "edit", "-x", "-require", "github.com/tendermint/tendermint@v0.0.0", "-replace", "github.com/tendermint/tendermint=github.com/bnb-chain/tendermint@v0.31.12") // Repo root + replacer = exec.Command(gocmd, "mod", "edit", "-x", "-require", "github.com/tendermint/tendermint@v0.0.0", "-replace", "github.com/tendermint/tendermint=github.com/bnb-chain/tendermint@v0.31.15") // Repo root replacer.Dir = pkg if out, err := replacer.CombinedOutput(); err != nil { t.Fatalf("failed to replace tendermint dependency to bnb-chain source: %v\n%s", err, out) } + + replacer = exec.Command(gocmd, "mod", "edit", "-x", "-require", "github.com/cometbft/cometbft@v0.0.0", "-replace", "github.com/cometbft/cometbft=github.com/bnb-chain/greenfield-tendermint@v0.0.0-20230417032003-4cda1f296fb2") // Repo root + replacer.Dir = pkg + if out, err := replacer.CombinedOutput(); err != nil { + t.Fatalf("failed to replace cometbft dependency to bnb-chain source: %v\n%s", err, out) + } + tidier := exec.Command(gocmd, "mod", "tidy") tidier.Dir = pkg if out, err := tidier.CombinedOutput(); err != nil { diff --git a/cl/clparams/config.go b/cl/clparams/config.go index cf3f13d8604..49fed33a99e 100644 --- a/cl/clparams/config.go +++ b/cl/clparams/config.go @@ -68,21 +68,6 @@ var ( "enr:-LK4QA8FfhaAjlb_BXsXxSfiysR7R52Nhi9JBt4F8SPssu8hdE1BXQQEtVDC3qStCW60LSO7hEsVHv5zm8_6Vnjhcn0Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhAN4aBKJc2VjcDI1NmsxoQJerDhsJ-KxZ8sHySMOCmTO6sHM3iCFQ6VMvLTe948MyYN0Y3CCI4yDdWRwgiOM", "enr:-LK4QKWrXTpV9T78hNG6s8AM6IO4XH9kFT91uZtFg1GcsJ6dKovDOr1jtAAFPnS2lvNltkOGA9k29BUN7lFh_sjuc9QBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpC1MD8qAAAAAP__________gmlkgnY0gmlwhANAdd-Jc2VjcDI1NmsxoQLQa6ai7y9PMN5hpLe5HmiJSlYzMuzP7ZhwRiwHvqNXdoN0Y3CCI4yDdWRwgiOM", } - GoerliBootstrapNodes = []string{ - "enr:-Ku4QFmUkNp0g9bsLX2PfVeIyT-9WO-PZlrqZBNtEyofOOfLMScDjaTzGxIb1Ns9Wo5Pm_8nlq-SZwcQfTH2cgO-s88Bh2F0dG5ldHOIAAAAAAAAAACEZXRoMpDkvpOTAAAQIP__________gmlkgnY0gmlwhBLf22SJc2VjcDI1NmsxoQLV_jMOIxKbjHFKgrkFvwDvpexo6Nd58TK5k7ss4Vt0IoN1ZHCCG1g", - "enr:-LK4QH1xnjotgXwg25IDPjrqRGFnH1ScgNHA3dv1Z8xHCp4uP3N3Jjl_aYv_WIxQRdwZvSukzbwspXZ7JjpldyeVDzMCh2F0dG5ldHOIAAAAAAAAAACEZXRoMpB53wQoAAAQIP__________gmlkgnY0gmlwhIe1te-Jc2VjcDI1NmsxoQOkcGXqbCJYbcClZ3z5f6NWhX_1YPFRYRRWQpJjwSHpVIN0Y3CCIyiDdWRwgiMo", - "enr:-Ly4QFPk-cTMxZ3jWTafiNblEZkQIXGF2aVzCIGW0uHp6KaEAvBMoctE8S7YU0qZtuS7By0AA4YMfKoN9ls_GJRccVpFh2F0dG5ldHOI__________-EZXRoMpCC9KcrAgAQIIS2AQAAAAAAgmlkgnY0gmlwhKh3joWJc2VjcDI1NmsxoQKrxz8M1IHwJqRIpDqdVW_U1PeixMW5SfnBD-8idYIQrIhzeW5jbmV0cw-DdGNwgiMog3VkcIIjKA", - "enr:-L64QJmwSDtaHVgGiqIxJWUtxWg6uLCipsms6j-8BdsOJfTWAs7CLF9HJnVqFE728O-JYUDCxzKvRdeMqBSauHVCMdaCAVWHYXR0bmV0c4j__________4RldGgykIL0pysCABAghLYBAAAAAACCaWSCdjSCaXCEQWxOdolzZWNwMjU2azGhA7Qmod9fK86WidPOzLsn5_8QyzL7ZcJ1Reca7RnD54vuiHN5bmNuZXRzD4N0Y3CCIyiDdWRwgiMo", - "enr:-KG4QCIzJZTY_fs_2vqWEatJL9RrtnPwDCv-jRBuO5FQ2qBrfJubWOWazri6s9HsyZdu-fRUfEzkebhf1nvO42_FVzwDhGV0aDKQed8EKAAAECD__________4JpZIJ2NIJpcISHtbYziXNlY3AyNTZrMaED4m9AqVs6F32rSCGsjtYcsyfQE2K8nDiGmocUY_iq-TSDdGNwgiMog3VkcIIjKA", - } - - SepoliaBootstrapNodes = []string{ - // EF boot nodes - "enr:-Iq4QMCTfIMXnow27baRUb35Q8iiFHSIDBJh6hQM5Axohhf4b6Kr_cOCu0htQ5WvVqKvFgY28893DHAg8gnBAXsAVqmGAX53x8JggmlkgnY0gmlwhLKAlv6Jc2VjcDI1NmsxoQK6S-Cii_KmfFdUJL2TANL3ksaKUnNXvTCv1tLwXs0QgIN1ZHCCIyk", - "enr:-KG4QE5OIg5ThTjkzrlVF32WT_-XT14WeJtIz2zoTqLLjQhYAmJlnk4ItSoH41_2x0RX0wTFIe5GgjRzU2u7Q1fN4vADhGV0aDKQqP7o7pAAAHAyAAAAAAAAAIJpZIJ2NIJpcISlFsStiXNlY3AyNTZrMaEC-Rrd_bBZwhKpXzFCrStKp1q_HmGOewxY3KwM8ofAj_ODdGNwgiMog3VkcIIjKA", - // Teku boot node - "enr:-Ly4QFoZTWR8ulxGVsWydTNGdwEESueIdj-wB6UmmjUcm-AOPxnQi7wprzwcdo7-1jBW_JxELlUKJdJES8TDsbl1EdNlh2F0dG5ldHOI__78_v2bsV-EZXRoMpA2-lATkAAAcf__________gmlkgnY0gmlwhBLYJjGJc2VjcDI1NmsxoQI0gujXac9rMAb48NtMqtSTyHIeNYlpjkbYpWJw46PmYYhzeW5jbmV0cw-DdGNwgiMog3VkcIIjKA", - } GnosisBootstrapNodes = []string{ "enr:-Ly4QMU1y81COwm1VZgxGF4_eZ21ub9-GHF6dXZ29aEJ0oZpcV2Rysw-viaEKfpcpu9ZarILJLxFZjcKOjE0Sybs3MQBh2F0dG5ldHOIAAAAAAAAAACEZXRoMpCCS-QxAgAAZP__________gmlkgnY0gmlwhANLnx-Jc2VjcDI1NmsxoQKoaYT8I-wf2I_f_ii6EgoSSXj5T3bhiDyW-7ZLsY3T64hzeW5jbmV0cwCDdGNwgiMog3VkcIIjKA", @@ -174,7 +159,7 @@ var NetworkConfigs map[NetworkType]NetworkConfig = map[NetworkType]NetworkConfig SyncCommsSubnetKey: "syncnets", MinimumPeersInSubnetSearch: 20, ContractDeploymentBlock: 1273020, - BootNodes: SepoliaBootstrapNodes, + BootNodes: MainnetBootstrapNodes, }, GoerliNetwork: { @@ -194,7 +179,7 @@ var NetworkConfigs map[NetworkType]NetworkConfig = map[NetworkType]NetworkConfig SyncCommsSubnetKey: "syncnets", MinimumPeersInSubnetSearch: 20, ContractDeploymentBlock: 4367322, - BootNodes: GoerliBootstrapNodes, + BootNodes: MainnetBootstrapNodes, }, GnosisNetwork: { @@ -266,18 +251,18 @@ var CheckpointSyncEndpoints = map[NetworkType][]string{ MainnetNetwork: { "https://sync.invis.tools/eth/v2/debug/beacon/states/finalized", "https://mainnet-checkpoint-sync.attestant.io/eth/v2/debug/beacon/states/finalized", - "https://mainnet.checkpoint.sigp.io/eth/v2/debug/beacon/states/finalized", + //"https://mainnet.checkpoint.sigp.io/eth/v2/debug/beacon/states/finalized", "https://mainnet-checkpoint-sync.stakely.io/eth/v2/debug/beacon/states/finalized", "https://checkpointz.pietjepuk.net/eth/v2/debug/beacon/states/finalized", }, GoerliNetwork: { "https://goerli.beaconstate.info/eth/v2/debug/beacon/states/finalized", "https://goerli-sync.invis.tools/eth/v2/debug/beacon/states/finalized", - "https://goerli.checkpoint-sync.ethdevops.io/eth/v2/debug/beacon/states/finalized", + "https://goerli.checkpoint-sync.ethpandaops.io/eth/v2/debug/beacon/states/finalized", "https://prater-checkpoint-sync.stakely.io/eth/v2/debug/beacon/states/finalized", }, SepoliaNetwork: { - "https://sepolia.checkpoint-sync.ethdevops.io/eth/v2/debug/beacon/states/finalized", + "https://checkpoint-sync.sepolia.ethpandaops.io/eth/v2/debug/beacon/states/finalized", "https://sepolia.beaconstate.info/eth/v2/debug/beacon/states/finalized", }, GnosisNetwork: { diff --git a/cl/cltypes/attestations.go b/cl/cltypes/attestations.go index 24e11980082..e418197fe57 100644 --- a/cl/cltypes/attestations.go +++ b/cl/cltypes/attestations.go @@ -7,9 +7,8 @@ import ( libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/length" - ssz "github.com/prysmaticlabs/fastssz" - "github.com/ledgerwatch/erigon/cl/cltypes/ssz_utils" + "github.com/ledgerwatch/erigon/cl/cltypes/ssz" "github.com/ledgerwatch/erigon/cl/merkle_tree" "github.com/ledgerwatch/erigon/common" ) @@ -271,7 +270,7 @@ func rebuildAggregationBits(buf []byte) (n int, ret []byte) { // MarshalSSZTo ssz marshals the Attestation object to a target array func (a *Attestation) EncodeSSZ(buf []byte) (dst []byte, err error) { dst = buf - dst = append(dst, ssz_utils.OffsetSSZ(228)...) + dst = append(dst, ssz.OffsetSSZ(228)...) if dst, err = a.Data.EncodeSSZ(dst); err != nil { return @@ -291,7 +290,7 @@ func (a *Attestation) DecodeSSZ(buf []byte) error { var err error size := uint64(len(buf)) if size < 228 { - return ssz_utils.ErrLowBufferSize + return ssz.ErrLowBufferSize } tail := buf @@ -308,16 +307,14 @@ func (a *Attestation) DecodeSSZ(buf []byte) error { copy(a.Signature[:], buf[132:228]) // Field (0) 'AggregationBits' - { - buf = tail[228:] - if err = ssz.ValidateBitlist(buf, 2048); err != nil { - return err - } - if cap(a.AggregationBits) == 0 { - a.AggregationBits = make([]byte, 0, len(buf)) - } - a.AggregationBits = append(a.AggregationBits, buf...) + + buf = tail[228:] + + if cap(a.AggregationBits) == 0 { + a.AggregationBits = make([]byte, 0, len(buf)) } + a.AggregationBits = append(a.AggregationBits, buf...) + return err } @@ -367,7 +364,7 @@ type IndexedAttestation struct { func (i *IndexedAttestation) EncodeSSZ(buf []byte) (dst []byte, err error) { dst = buf // Write indicies offset. - dst = append(dst, ssz_utils.OffsetSSZ(228)...) + dst = append(dst, ssz.OffsetSSZ(228)...) // Process data field. if dst, err = i.Data.EncodeSSZ(dst); err != nil { @@ -381,7 +378,7 @@ func (i *IndexedAttestation) EncodeSSZ(buf []byte) (dst []byte, err error) { return nil, errors.New("too bing attesting indices") } for _, index := range i.AttestingIndices { - dst = append(dst, ssz_utils.Uint64SSZ(index)...) + dst = append(dst, ssz.Uint64SSZ(index)...) } return @@ -392,7 +389,7 @@ func (i *IndexedAttestation) DecodeSSZ(buf []byte) error { var err error size := uint64(len(buf)) if size < 228 { - return ssz_utils.ErrLowBufferSize + return ssz.ErrLowBufferSize } i.Data = new(AttestationData) @@ -404,15 +401,15 @@ func (i *IndexedAttestation) DecodeSSZ(buf []byte) error { bitsBuf := buf[228:] num := len(bitsBuf) / 8 if len(bitsBuf)%8 != 0 { - return ssz_utils.ErrBufferNotRounded + return ssz.ErrBufferNotRounded } if num > 2048 { - return ssz_utils.ErrBadDynamicLength + return ssz.ErrBadDynamicLength } i.AttestingIndices = make([]uint64, num) for index := 0; index < num; index++ { - i.AttestingIndices[index] = ssz_utils.UnmarshalUint64SSZ(bitsBuf[index*8:]) + i.AttestingIndices[index] = ssz.UnmarshalUint64SSZ(bitsBuf[index*8:]) } return nil } @@ -426,7 +423,7 @@ func (i *IndexedAttestation) EncodingSizeSSZ() int { func (i *IndexedAttestation) HashSSZ() ([32]byte, error) { leaves := make([][32]byte, 3) var err error - leaves[0], err = merkle_tree.Uint64ListRootWithLimit(i.AttestingIndices, ssz_utils.CalculateIndiciesLimit(2048, uint64(len(i.AttestingIndices)), 8)) + leaves[0], err = merkle_tree.Uint64ListRootWithLimit(i.AttestingIndices, ssz.CalculateIndiciesLimit(2048, uint64(len(i.AttestingIndices)), 8)) if err != nil { return [32]byte{}, err } @@ -461,8 +458,8 @@ func (a *AttestationData) Equal(other *AttestationData) bool { func (a *AttestationData) EncodeSSZ(dst []byte) ([]byte, error) { buf := dst var err error - buf = append(buf, ssz_utils.Uint64SSZ(a.Slot)...) - buf = append(buf, ssz_utils.Uint64SSZ(a.Index)...) + buf = append(buf, ssz.Uint64SSZ(a.Slot)...) + buf = append(buf, ssz.Uint64SSZ(a.Index)...) buf = append(buf, a.BeaconBlockHash[:]...) if buf, err = a.Source.EncodeSSZ(buf); err != nil { return nil, err @@ -475,11 +472,11 @@ func (a *AttestationData) DecodeSSZ(buf []byte) error { var err error size := uint64(len(buf)) if size != uint64(a.EncodingSizeSSZ()) { - return ssz_utils.ErrLowBufferSize + return ssz.ErrLowBufferSize } - a.Slot = ssz_utils.UnmarshalUint64SSZ(buf) - a.Index = ssz_utils.UnmarshalUint64SSZ(buf[8:]) + a.Slot = ssz.UnmarshalUint64SSZ(buf) + a.Index = ssz.UnmarshalUint64SSZ(buf[8:]) copy(a.BeaconBlockHash[:], buf[16:48]) a.Source = new(Checkpoint) @@ -497,7 +494,7 @@ func (a *AttestationData) DecodeSSZ(buf []byte) error { // EncodingSizeSSZ returns the ssz encoded size in bytes for the AttestationData object func (a *AttestationData) EncodingSizeSSZ() int { - return 2*common.BlockNumberLength + length.Hash + a.Source.EncodingSizeSSZ() + a.Target.EncodingSizeSSZ() + return 2*common.BlockNumberLength + length.Hash + 40 + 40 } // HashSSZ ssz hashes the AttestationData object @@ -518,3 +515,96 @@ func (a *AttestationData) HashSSZ() ([32]byte, error) { targetRoot, }, 8) } + +// Pending attestation. (only in Phase0 state) +type PendingAttestation struct { + AggregationBits []byte + Data *AttestationData + InclusionDelay uint64 + ProposerIndex uint64 +} + +// MarshalSSZTo ssz marshals the Attestation object to a target array +func (a *PendingAttestation) EncodeSSZ(buf []byte) (dst []byte, err error) { + dst = buf + dst = append(dst, ssz.OffsetSSZ(148)...) + if dst, err = a.Data.EncodeSSZ(dst); err != nil { + return + } + dst = append(dst, ssz.Uint64SSZ(a.InclusionDelay)...) + dst = append(dst, ssz.Uint64SSZ(a.ProposerIndex)...) + + if len(a.AggregationBits) > 2048 { + return nil, fmt.Errorf("too many aggregation bits in attestation") + } + dst = append(dst, a.AggregationBits...) + + return +} + +// DecodeSSZ ssz unmarshals the Attestation object +func (a *PendingAttestation) DecodeSSZ(buf []byte) error { + var err error + if len(buf) < a.EncodingSizeSSZ() { + return ssz.ErrLowBufferSize + } + + tail := buf + + // Field (1) 'Data' + if a.Data == nil { + a.Data = new(AttestationData) + } + if err = a.Data.DecodeSSZ(buf[4:132]); err != nil { + return err + } + + a.InclusionDelay = ssz.UnmarshalUint64SSZ(buf[132:]) + a.ProposerIndex = ssz.UnmarshalUint64SSZ(buf[140:]) + + buf = tail[148:] + + if cap(a.AggregationBits) == 0 { + a.AggregationBits = make([]byte, 0, len(buf)) + } + a.AggregationBits = append(a.AggregationBits, buf...) + + return err +} + +func (a *PendingAttestation) DecodeSSZWithVersion(buf []byte, _ int) error { + return a.DecodeSSZ(buf) +} + +// EncodingSizeSSZ returns the ssz encoded size in bytes for the Attestation object +func (a *PendingAttestation) EncodingSizeSSZ() int { + return 148 + len(a.AggregationBits) +} + +// HashSSZ ssz hashes the Attestation object +func (a *PendingAttestation) HashSSZ() ([32]byte, error) { + leaves := make([][32]byte, 4) + var err error + if a.Data == nil { + return [32]byte{}, fmt.Errorf("missing attestation data") + } + leaves[0], err = merkle_tree.BitlistRootWithLimit(a.AggregationBits, 2048) + if err != nil { + return [32]byte{}, err + } + + leaves[1], err = a.Data.HashSSZ() + if err != nil { + return [32]byte{}, err + } + + leaves[2] = merkle_tree.Uint64Root(a.InclusionDelay) + leaves[3] = merkle_tree.Uint64Root(a.ProposerIndex) + + return merkle_tree.ArraysRoot(leaves, 4) +} + +func IsSlashableAttestationData(d1, d2 *AttestationData) bool { + return (!d1.Equal(d2) && d1.Target.Epoch == d2.Target.Epoch) || + (d1.Source.Epoch < d2.Source.Epoch && d2.Target.Epoch < d1.Target.Epoch) +} diff --git a/cl/cltypes/beacon_header.go b/cl/cltypes/beacon_header.go index 67e92b41a8e..5576cd31785 100644 --- a/cl/cltypes/beacon_header.go +++ b/cl/cltypes/beacon_header.go @@ -20,6 +20,10 @@ type BeaconBlockHeader struct { BodyRoot libcommon.Hash } +func (b *BeaconBlockHeader) Copy() *BeaconBlockHeader { + copied := *b + return &copied +} func (b *BeaconBlockHeader) EncodeSSZ(dst []byte) ([]byte, error) { buf := dst buf = append(buf, ssz_utils.Uint64SSZ(b.Slot)...) diff --git a/cl/cltypes/checkpoint.go b/cl/cltypes/checkpoint.go index f5dcde87e51..0f007b8f6f5 100644 --- a/cl/cltypes/checkpoint.go +++ b/cl/cltypes/checkpoint.go @@ -4,7 +4,7 @@ import ( libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/length" - "github.com/ledgerwatch/erigon/cl/cltypes/ssz_utils" + "github.com/ledgerwatch/erigon/cl/cltypes/ssz" "github.com/ledgerwatch/erigon/cl/merkle_tree" ) @@ -13,21 +13,31 @@ type Checkpoint struct { Root libcommon.Hash } +func (c *Checkpoint) DecodeSSZWithVersion(buf []byte, _ int) error { + return c.DecodeSSZ(buf) +} + +func (c *Checkpoint) Copy() *Checkpoint { + copiedCheckpoint := new(Checkpoint) + *copiedCheckpoint = *c + return copiedCheckpoint +} + func (c *Checkpoint) Equal(other *Checkpoint) bool { return c.Epoch == other.Epoch && c.Root == other.Root } func (c *Checkpoint) EncodeSSZ(buf []byte) ([]byte, error) { - return append(buf, append(ssz_utils.Uint64SSZ(c.Epoch), c.Root[:]...)...), nil + return append(buf, append(ssz.Uint64SSZ(c.Epoch), c.Root[:]...)...), nil } func (c *Checkpoint) DecodeSSZ(buf []byte) error { var err error size := uint64(len(buf)) if size < uint64(c.EncodingSizeSSZ()) { - return ssz_utils.ErrLowBufferSize + return ssz.ErrLowBufferSize } - c.Epoch = ssz_utils.UnmarshalUint64SSZ(buf[0:8]) + c.Epoch = ssz.UnmarshalUint64SSZ(buf[0:8]) copy(c.Root[:], buf[8:40]) return err diff --git a/cl/cltypes/clone.go b/cl/cltypes/clone.go index d943b96d70b..50d780b0bd9 100644 --- a/cl/cltypes/clone.go +++ b/cl/cltypes/clone.go @@ -54,14 +54,6 @@ func (*AttesterSlashing) Clone() clonable.Clonable { return &AttesterSlashing{} } -func (*LightClientFinalityUpdate) Clone() clonable.Clonable { - return &LightClientFinalityUpdate{} -} - -func (*LightClientOptimisticUpdate) Clone() clonable.Clonable { - return &LightClientOptimisticUpdate{} -} - func (*Metadata) Clone() clonable.Clonable { return &Metadata{} } @@ -74,14 +66,6 @@ func (*Deposit) Clone() clonable.Clonable { return &Deposit{} } -func (*LightClientBootstrap) Clone() clonable.Clonable { - return &LightClientBootstrap{} -} - func (*BeaconBlock) Clone() clonable.Clonable { return &BeaconBlock{} } - -func (*LightClientUpdate) Clone() clonable.Clonable { - return &LightClientUpdate{} -} diff --git a/cl/cltypes/eth1_block.go b/cl/cltypes/eth1_block.go index 1be3ce582fe..1da0c7d5db6 100644 --- a/cl/cltypes/eth1_block.go +++ b/cl/cltypes/eth1_block.go @@ -2,81 +2,181 @@ package cltypes import ( "fmt" + "math/big" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon/cl/clparams" - "github.com/ledgerwatch/erigon/cl/cltypes/ssz_utils" + "github.com/ledgerwatch/erigon/cl/cltypes/ssz" "github.com/ledgerwatch/erigon/cl/merkle_tree" "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/consensus/serenity" "github.com/ledgerwatch/erigon/core/types" ) // ETH1Block represents a block structure CL-side. type Eth1Block struct { - Header *types.Header - // Transactions can be kept in bytes. - Body *types.RawBody + ParentHash libcommon.Hash + FeeRecipient libcommon.Address + StateRoot libcommon.Hash + ReceiptsRoot libcommon.Hash + LogsBloom types.Bloom + PrevRandao libcommon.Hash + BlockNumber uint64 + GasLimit uint64 + GasUsed uint64 + Time uint64 + Extra []byte + BaseFeePerGas [32]byte + // Extra fields + BlockHash libcommon.Hash + Transactions [][]byte + Withdrawals types.Withdrawals + // internals + version clparams.StateVersion } -func (b *Eth1Block) NumberU64() uint64 { - return b.Header.Number.Uint64() +// NewEth1Block creates a new Eth1Block. +func NewEth1Block(version clparams.StateVersion) *Eth1Block { + return &Eth1Block{version: version} } -func (b *Eth1Block) Withdrawals() types.Withdrawals { - return types.Withdrawals(b.Body.Withdrawals) -} +// NewEth1BlockFromHeaderAndBody with given header/body. +func NewEth1BlockFromHeaderAndBody(header *types.Header, body *types.RawBody) *Eth1Block { + baseFeeBytes := header.BaseFee.Bytes() + for i, j := 0, len(baseFeeBytes)-1; i < j; i, j = i+1, j-1 { + baseFeeBytes[i], baseFeeBytes[j] = baseFeeBytes[j], baseFeeBytes[i] + } + var baseFee32 [32]byte + copy(baseFee32[:], baseFeeBytes) -func (b *Eth1Block) EncodingSizeSSZ(version clparams.StateVersion) (size int) { - size = 508 + block := &Eth1Block{ + ParentHash: header.ParentHash, + FeeRecipient: header.Coinbase, + StateRoot: header.Root, + ReceiptsRoot: header.ReceiptHash, + LogsBloom: header.Bloom, + PrevRandao: header.MixDigest, + BlockNumber: header.Number.Uint64(), + GasLimit: header.GasLimit, + GasUsed: header.GasUsed, + Time: header.Time, + Extra: header.Extra, + BaseFeePerGas: baseFee32, + BlockHash: header.Hash(), + Transactions: body.Transactions, + Withdrawals: body.Withdrawals, + } + if header.WithdrawalsHash == nil { + block.version = clparams.BellatrixVersion + } else { + block.version = clparams.CapellaVersion + } + return block +} - if b.Header == nil { - return +// PayloadHeader returns the equivalent ExecutionPayloadHeader object. +func (b *Eth1Block) PayloadHeader() (*Eth1Header, error) { + var err error + var transactionsRoot, withdrawalsRoot libcommon.Hash + if transactionsRoot, err = merkle_tree.TransactionsListRoot(b.Transactions); err != nil { + return nil, err + } + if b.version >= clparams.CapellaVersion { + withdrawalsRoot, err = b.Withdrawals.HashSSZ(16) + if err != nil { + return nil, err + } } + + return &Eth1Header{ + ParentHash: b.ParentHash, + FeeRecipient: b.FeeRecipient, + StateRoot: b.StateRoot, + ReceiptsRoot: b.ReceiptsRoot, + LogsBloom: b.LogsBloom, + PrevRandao: b.PrevRandao, + BlockNumber: b.BlockNumber, + GasLimit: b.GasLimit, + GasUsed: b.GasUsed, + Time: b.Time, + Extra: b.Extra, + BaseFeePerGas: b.BaseFeePerGas, + BlockHash: b.BlockHash, + TransactionsRoot: transactionsRoot, + WithdrawalsRoot: withdrawalsRoot, + version: b.version, + }, nil +} + +// Return minimum required buffer length to be an acceptable SSZ encoding. +func (b *Eth1Block) EncodingSizeSSZ() (size int) { + size = 508 // Field (10) 'ExtraData' - size += len(b.Header.Extra) + size += len(b.Extra) // Field (13) 'Transactions' - for _, tx := range b.Body.Transactions { + for _, tx := range b.Transactions { size += 4 size += len(tx) } - if version >= clparams.CapellaVersion { - size += len(b.Body.Withdrawals)*44 + 4 + if b.version >= clparams.CapellaVersion { + size += len(b.Withdrawals)*44 + 4 } return } -func (b *Eth1Block) DecodeSSZ(buf []byte, version clparams.StateVersion) error { - if len(buf) < b.EncodingSizeSSZ(clparams.BellatrixVersion) { - return ssz_utils.ErrLowBufferSize - } - b.Header = new(types.Header) +// Need a version +func (b *Eth1Block) DecodeSSZ(buf []byte) error { + panic("stop") +} - pos, extraDataOffset := b.Header.DecodeHeaderMetadataForSSZ(buf) - transactionsOffset := ssz_utils.DecodeOffset(buf[pos:]) +// DecodeSSZWithVersion decodes the block in SSZ format. +func (b *Eth1Block) DecodeSSZWithVersion(buf []byte, version int) error { + b.version = clparams.StateVersion(version) + if len(buf) < b.EncodingSizeSSZ() { + return ssz.ErrLowBufferSize + } + // We can reuse code from eth1-header for partial decoding + payloadHeader := Eth1Header{} + pos, extraDataOffset := payloadHeader.decodeHeaderMetadataForSSZ(buf) + // Set all header shared fields accordingly + b.ParentHash = payloadHeader.ParentHash + b.FeeRecipient = payloadHeader.FeeRecipient + b.StateRoot = payloadHeader.StateRoot + b.ReceiptsRoot = payloadHeader.ReceiptsRoot + b.BlockHash = payloadHeader.BlockHash + b.LogsBloom = payloadHeader.LogsBloom + b.PrevRandao = payloadHeader.PrevRandao + b.BlockNumber = payloadHeader.BlockNumber + b.GasLimit = payloadHeader.GasLimit + b.GasUsed = payloadHeader.GasUsed + b.Time = payloadHeader.Time + b.BaseFeePerGas = payloadHeader.BaseFeePerGas + // Decode the rest + transactionsOffset := ssz.DecodeOffset(buf[pos:]) pos += 4 var withdrawalOffset *uint32 - if version >= clparams.CapellaVersion { + if version >= int(clparams.CapellaVersion) { withdrawalOffset = new(uint32) - *withdrawalOffset = ssz_utils.DecodeOffset(buf[pos:]) + *withdrawalOffset = ssz.DecodeOffset(buf[pos:]) } // Compute extra data. - b.Header.Extra = common.CopyBytes(buf[extraDataOffset:transactionsOffset]) - if len(b.Header.Extra) > 32 { - return fmt.Errorf("Decode(SSZ): Extra data field length should be less or equal to 32, got %d", len(b.Header.Extra)) + b.Extra = common.CopyBytes(buf[extraDataOffset:transactionsOffset]) + if len(b.Extra) > 32 { + return fmt.Errorf("Decode(SSZ): Extra data field length should be less or equal to 32, got %d", len(b.Extra)) } // Compute transactions var transactionsBuffer []byte if withdrawalOffset == nil { if len(transactionsBuffer) > len(buf) { - return ssz_utils.ErrLowBufferSize + return ssz.ErrLowBufferSize } transactionsBuffer = buf[transactionsOffset:] } else { if len(transactionsBuffer) > int(*withdrawalOffset) || int(*withdrawalOffset) > len(buf) { - return ssz_utils.ErrBadOffset + return ssz.ErrBadOffset } transactionsBuffer = buf[transactionsOffset:*withdrawalOffset] } @@ -88,18 +188,17 @@ func (b *Eth1Block) DecodeSSZ(buf []byte, version clparams.StateVersion) error { length = 0 } else { if len(transactionsBuffer) < 4 { - return ssz_utils.ErrLowBufferSize + return ssz.ErrLowBufferSize } - txOffset = ssz_utils.DecodeOffset(transactionsBuffer) + txOffset = ssz.DecodeOffset(transactionsBuffer) length = txOffset / 4 // Retrieve tx length if txOffset%4 != 0 { - return ssz_utils.ErrBadDynamicLength + return ssz.ErrBadDynamicLength } } - b.Body = new(types.RawBody) - b.Body.Transactions = make([][]byte, length) + b.Transactions = make([][]byte, length) txIdx := 0 // Loop through each transaction for length > 0 { @@ -107,109 +206,142 @@ func (b *Eth1Block) DecodeSSZ(buf []byte, version clparams.StateVersion) error { if length == 1 { txEndOffset = uint32(len(transactionsBuffer)) } else { - txEndOffset = ssz_utils.DecodeOffset(transactionsBuffer[transactionsPosition:]) + txEndOffset = ssz.DecodeOffset(transactionsBuffer[transactionsPosition:]) } transactionsPosition += 4 if txOffset > txEndOffset { - return ssz_utils.ErrBadOffset + return ssz.ErrBadOffset } - b.Body.Transactions[txIdx] = transactionsBuffer[txOffset:txEndOffset] + b.Transactions[txIdx] = transactionsBuffer[txOffset:txEndOffset] // Decode RLP and put it in the tx list. // Update parameters for next iteration txOffset = txEndOffset txIdx++ length-- } - // Cache transaction ssz root. - var err error - b.Header.TxHashSSZ, err = merkle_tree.TransactionsListRoot(b.Body.Transactions) - if err != nil { - return err - } - // Cache transaction rlp hash. - b.Header.TxHash = types.DeriveSha(types.BinaryTransactions(b.Body.Transactions)) // If withdrawals are enabled, process them. if withdrawalOffset != nil { - b.Body.Withdrawals, err = ssz_utils.DecodeStaticList[*types.Withdrawal](buf, *withdrawalOffset, uint32(len(buf)), 44, 16) + var err error + b.Withdrawals, err = ssz.DecodeStaticList[*types.Withdrawal](buf, *withdrawalOffset, uint32(len(buf)), 44, 16) if err != nil { return err } - withdrawalRoot, err := b.Withdrawals().HashSSZ(16) - if err != nil { - return err - } - b.Header.WithdrawalsHash = new(libcommon.Hash) - *b.Header.WithdrawalsHash = withdrawalRoot } return nil } -func (b *Eth1Block) EncodeSSZ(dst []byte, version clparams.StateVersion) ([]byte, error) { +// EncodeSSZ encodes the block in SSZ format. +func (b *Eth1Block) EncodeSSZ(dst []byte) ([]byte, error) { buf := dst var err error - currentOffset := ssz_utils.BaseExtraDataSSZOffsetBlock + currentOffset := ssz.BaseExtraDataSSZOffsetBlock - if version >= clparams.CapellaVersion { + if b.version >= clparams.CapellaVersion { currentOffset += 4 } - buf, err = b.Header.EncodeHeaderMetadataForSSZ(buf, currentOffset) + payloadHeader, err := b.PayloadHeader() + if err != nil { + return nil, err + } + buf, err = payloadHeader.encodeHeaderMetadataForSSZ(buf, currentOffset) if err != nil { return nil, err } - currentOffset += len(b.Header.Extra) - // use raw body for encoded txs and offsets. - body := b.Body + currentOffset += len(b.Extra) // Write transaction offset - buf = append(buf, ssz_utils.OffsetSSZ(uint32(currentOffset))...) + buf = append(buf, ssz.OffsetSSZ(uint32(currentOffset))...) - for _, tx := range body.Transactions { + for _, tx := range b.Transactions { currentOffset += len(tx) + 4 } // Write withdrawals offset if exist - if version >= clparams.CapellaVersion { - buf = append(buf, ssz_utils.OffsetSSZ(uint32(currentOffset))...) + if b.version >= clparams.CapellaVersion { + buf = append(buf, ssz.OffsetSSZ(uint32(currentOffset))...) } // Sanity check for extra data then write it. - if len(b.Header.Extra) > 32 { - return nil, fmt.Errorf("Encode(SSZ): Extra data field length should be less or equal to 32, got %d", len(b.Header.Extra)) + if len(b.Extra) > 32 { + return nil, fmt.Errorf("Encode(SSZ): Extra data field length should be less or equal to 32, got %d", len(b.Extra)) } - buf = append(buf, b.Header.Extra...) + buf = append(buf, b.Extra...) // Write all tx offsets - txOffset := len(body.Transactions) * 4 - for _, tx := range body.Transactions { - buf = append(buf, ssz_utils.OffsetSSZ(uint32(txOffset))...) + txOffset := len(b.Transactions) * 4 + for _, tx := range b.Transactions { + buf = append(buf, ssz.OffsetSSZ(uint32(txOffset))...) txOffset += len(tx) } // Write all transactions - for _, tx := range body.Transactions { + for _, tx := range b.Transactions { buf = append(buf, tx...) } - if version >= clparams.CapellaVersion { - // Append all withdrawals SSZ - for _, withdrawal := range body.Withdrawals { - buf = append(buf, withdrawal.EncodeSSZ()...) - } + // Append all withdrawals SSZ + for _, withdrawal := range b.Withdrawals { + buf = append(buf, withdrawal.EncodeSSZ()...) } + return buf, nil } +// HashSSZ calculates the SSZ hash of the Eth1Block's payload header. func (b *Eth1Block) HashSSZ(version clparams.StateVersion) ([32]byte, error) { - var err error - if b.Header.TxHashSSZ, err = merkle_tree.TransactionsListRoot(b.Body.Transactions); err != nil { + // Get the payload header. + header, err := b.PayloadHeader() + if err != nil { return [32]byte{}, err } - if version >= clparams.CapellaVersion { - b.Header.WithdrawalsHash = new(libcommon.Hash) - if *b.Header.WithdrawalsHash, err = types.Withdrawals(b.Body.Withdrawals).HashSSZ(16); err != nil { - return [32]byte{}, err - } - } else { - b.Header.WithdrawalsHash = nil + + // Calculate the SSZ hash of the header and return it. + return header.HashSSZ() +} + +// RlpHeader returns the equivalent types.Header struct with RLP-based fields. +func (b *Eth1Block) RlpHeader() (*types.Header, error) { + // Reverse the order of the bytes in the BaseFeePerGas array and convert it to a big integer. + reversedBaseFeePerGas := libcommon.Copy(b.BaseFeePerGas[:]) + for i, j := 0, len(reversedBaseFeePerGas)-1; i < j; i, j = i+1, j-1 { + reversedBaseFeePerGas[i], reversedBaseFeePerGas[j] = reversedBaseFeePerGas[j], reversedBaseFeePerGas[i] } - return b.Header.HashSSZ() + baseFee := new(big.Int).SetBytes(reversedBaseFeePerGas) + + // If the block version is Capella or later, calculate the withdrawals hash. + var withdrawalsHash *libcommon.Hash + if b.version >= clparams.CapellaVersion { + withdrawalsHash = new(libcommon.Hash) + *withdrawalsHash = types.DeriveSha(b.Withdrawals) + } + + header := &types.Header{ + ParentHash: b.ParentHash, + UncleHash: types.EmptyUncleHash, + Coinbase: b.FeeRecipient, + Root: b.StateRoot, + TxHash: types.DeriveSha(types.BinaryTransactions(b.Transactions)), + ReceiptHash: b.ReceiptsRoot, + Bloom: b.LogsBloom, + Difficulty: serenity.SerenityDifficulty, + Number: big.NewInt(int64(b.BlockNumber)), + GasLimit: b.GasLimit, + GasUsed: b.GasUsed, + Time: b.Time, + Extra: b.Extra, + MixDigest: b.PrevRandao, + Nonce: serenity.SerenityNonce, + BaseFee: baseFee, + WithdrawalsHash: withdrawalsHash, + } + + // If the header hash does not match the block hash, return an error. + if header.Hash() != b.BlockHash { + return nil, fmt.Errorf("cannot derive rlp header: mismatching hash") + } + + return header, nil } -func (b *Eth1Block) Hash() libcommon.Hash { - return b.Header.Hash() +// Body returns the equivalent raw body (only eth1 body section). +func (b *Eth1Block) Body() *types.RawBody { + return &types.RawBody{ + Transactions: b.Transactions, + Withdrawals: b.Withdrawals, + } } diff --git a/cl/cltypes/eth1_data.go b/cl/cltypes/eth1_data.go index b60a1352fcc..4521a650a70 100644 --- a/cl/cltypes/eth1_data.go +++ b/cl/cltypes/eth1_data.go @@ -14,6 +14,11 @@ type Eth1Data struct { DepositCount uint64 } +func (e *Eth1Data) Copy() *Eth1Data { + copied := *e + return &copied +} + func (e *Eth1Data) Equal(b *Eth1Data) bool { return e.BlockHash == b.BlockHash && e.Root == b.Root && b.DepositCount == e.DepositCount } diff --git a/cl/cltypes/eth1_header.go b/cl/cltypes/eth1_header.go new file mode 100644 index 00000000000..7b104adf8ce --- /dev/null +++ b/cl/cltypes/eth1_header.go @@ -0,0 +1,216 @@ +package cltypes + +import ( + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon/cl/clparams" + "github.com/ledgerwatch/erigon/cl/cltypes/ssz" + "github.com/ledgerwatch/erigon/cl/merkle_tree" + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/core/types" +) + +// ETH1Header represents the ethereum 1 header structure CL-side. +type Eth1Header struct { + ParentHash libcommon.Hash + FeeRecipient libcommon.Address + StateRoot libcommon.Hash + ReceiptsRoot libcommon.Hash + LogsBloom types.Bloom + PrevRandao libcommon.Hash + BlockNumber uint64 + GasLimit uint64 + GasUsed uint64 + Time uint64 + Extra []byte + BaseFeePerGas [32]byte + // Extra fields + BlockHash libcommon.Hash + TransactionsRoot libcommon.Hash + WithdrawalsRoot libcommon.Hash + // internals + version clparams.StateVersion +} + +// NewEth1Header creates new header with given version. +func NewEth1Header(version clparams.StateVersion) *Eth1Header { + return &Eth1Header{version: version} +} + +func (e *Eth1Header) Copy() *Eth1Header { + copied := *e + copied.Extra = libcommon.Copy(e.Extra) + return &copied +} + +// Capella converts the header to capella version. +func (e *Eth1Header) Capella() { + e.version = clparams.CapellaVersion + e.WithdrawalsRoot = libcommon.Hash{} +} + +func (e *Eth1Header) IsZero() bool { + return e.ParentHash == libcommon.Hash{} && e.FeeRecipient == libcommon.Address{} && e.StateRoot == libcommon.Hash{} && + e.ReceiptsRoot == libcommon.Hash{} && e.LogsBloom == types.Bloom{} && e.PrevRandao == libcommon.Hash{} && e.BlockNumber == 0 && + e.GasLimit == 0 && e.GasUsed == 0 && e.Time == 0 && len(e.Extra) == 0 && e.BaseFeePerGas == [32]byte{} && e.BlockHash == libcommon.Hash{} && e.TransactionsRoot == libcommon.Hash{} +} + +// Encodes header data partially. used to not dupicate code across Eth1Block and Eth1Header. +func (h *Eth1Header) encodeHeaderMetadataForSSZ(dst []byte, extraDataOffset int) ([]byte, error) { + buf := dst + buf = append(buf, h.ParentHash[:]...) + buf = append(buf, h.FeeRecipient[:]...) + buf = append(buf, h.StateRoot[:]...) + buf = append(buf, h.ReceiptsRoot[:]...) + buf = append(buf, h.LogsBloom[:]...) + buf = append(buf, h.PrevRandao[:]...) + buf = append(buf, ssz.Uint64SSZ(h.BlockNumber)...) + buf = append(buf, ssz.Uint64SSZ(h.GasLimit)...) + buf = append(buf, ssz.Uint64SSZ(h.GasUsed)...) + buf = append(buf, ssz.Uint64SSZ(h.Time)...) + buf = append(buf, ssz.OffsetSSZ(uint32(extraDataOffset))...) + + // Add Base Fee + buf = append(buf, h.BaseFeePerGas[:]...) + buf = append(buf, h.BlockHash[:]...) + return buf, nil +} + +// EncodeSSZ encodes the header in SSZ format. +func (h *Eth1Header) EncodeSSZ(dst []byte) (buf []byte, err error) { + buf = dst + offset := ssz.BaseExtraDataSSZOffsetHeader + + if h.version >= clparams.CapellaVersion { + offset += 32 + } + + buf, err = h.encodeHeaderMetadataForSSZ(buf, offset) + if err != nil { + return nil, err + } + buf = append(buf, h.TransactionsRoot[:]...) + + if h.version >= clparams.CapellaVersion { + buf = append(buf, h.WithdrawalsRoot[:]...) + } + + buf = append(buf, h.Extra...) + return +} + +// Decodes header data partially. used to not dupicate code across Eth1Block and Eth1Header. +func (h *Eth1Header) decodeHeaderMetadataForSSZ(buf []byte) (pos int, extraDataOffset int) { + copy(h.ParentHash[:], buf) + pos = len(h.ParentHash) + + copy(h.FeeRecipient[:], buf[pos:]) + pos += len(h.FeeRecipient) + + copy(h.StateRoot[:], buf[pos:]) + pos += len(h.StateRoot) + + copy(h.ReceiptsRoot[:], buf[pos:]) + pos += len(h.ReceiptsRoot) + + h.LogsBloom.SetBytes(buf[pos : pos+types.BloomByteLength]) + pos += types.BloomByteLength + + copy(h.PrevRandao[:], buf[pos:]) + pos += len(h.PrevRandao) + + h.BlockNumber = ssz.UnmarshalUint64SSZ(buf[pos:]) + h.GasLimit = ssz.UnmarshalUint64SSZ(buf[pos+8:]) + h.GasUsed = ssz.UnmarshalUint64SSZ(buf[pos+16:]) + h.Time = ssz.UnmarshalUint64SSZ(buf[pos+24:]) + pos += 32 + extraDataOffset = int(ssz.DecodeOffset(buf[pos:])) + pos += 4 + // Add Base Fee + copy(h.BaseFeePerGas[:], buf[pos:]) + pos += 32 + copy(h.BlockHash[:], buf[pos:]) + pos += 32 + return +} + +// DecodeSSZWithVersion decodes given SSZ slice. +func (h *Eth1Header) DecodeSSZWithVersion(buf []byte, version int) error { + h.version = clparams.StateVersion(version) + if len(buf) < h.EncodingSizeSSZ() { + return ssz.ErrLowBufferSize + } + pos, _ := h.decodeHeaderMetadataForSSZ(buf) + copy(h.TransactionsRoot[:], buf[pos:]) + pos += len(h.TransactionsRoot) + + if h.version >= clparams.CapellaVersion { + copy(h.WithdrawalsRoot[:], buf[pos:]) + pos += len(h.WithdrawalsRoot) + } + h.Extra = common.CopyBytes(buf[pos:]) + return nil +} + +// EncodingSizeSSZ returns the ssz encoded size in bytes for the Header object +func (h *Eth1Header) EncodingSizeSSZ() int { + size := 536 + + if h.version >= clparams.CapellaVersion { + size += 32 + } + + return size + len(h.Extra) +} + +// HashSSZ encodes the header in SSZ tree format. +func (h *Eth1Header) HashSSZ() ([32]byte, error) { + // Compute coinbase leaf + var coinbase32 [32]byte + copy(coinbase32[:], h.FeeRecipient[:]) + // Compute Bloom leaf + bloomLeaf, err := merkle_tree.ArraysRoot([][32]byte{ + libcommon.BytesToHash(h.LogsBloom[:32]), + libcommon.BytesToHash(h.LogsBloom[32:64]), + libcommon.BytesToHash(h.LogsBloom[64:96]), + libcommon.BytesToHash(h.LogsBloom[96:128]), + libcommon.BytesToHash(h.LogsBloom[128:160]), + libcommon.BytesToHash(h.LogsBloom[160:192]), + libcommon.BytesToHash(h.LogsBloom[192:224]), + libcommon.BytesToHash(h.LogsBloom[224:]), + }, 8) + if err != nil { + return [32]byte{}, err + } + // Compute extra data leaf + var extraLeaf libcommon.Hash + + var baseExtraLeaf [32]byte + copy(baseExtraLeaf[:], h.Extra) + extraLeaf, err = merkle_tree.ArraysRoot([][32]byte{ + baseExtraLeaf, + merkle_tree.Uint64Root(uint64(len(h.Extra)))}, 2) + if err != nil { + return [32]byte{}, err + } + + leaves := [][32]byte{ + h.ParentHash, + coinbase32, + h.StateRoot, + h.ReceiptsRoot, + bloomLeaf, + h.PrevRandao, + merkle_tree.Uint64Root(h.BlockNumber), + merkle_tree.Uint64Root(h.GasLimit), + merkle_tree.Uint64Root(h.GasUsed), + merkle_tree.Uint64Root(h.Time), + extraLeaf, + h.BaseFeePerGas, + h.BlockHash, + h.TransactionsRoot, + } + if h.version >= clparams.CapellaVersion { + leaves = append(leaves, h.WithdrawalsRoot) + } + return merkle_tree.ArraysRoot(leaves, 16) +} diff --git a/cl/cltypes/fork.go b/cl/cltypes/fork.go index af0fb2920c6..3b828378c70 100644 --- a/cl/cltypes/fork.go +++ b/cl/cltypes/fork.go @@ -13,6 +13,14 @@ type Fork struct { Epoch uint64 } +func (f *Fork) Copy() *Fork { + return &Fork{ + PreviousVersion: f.PreviousVersion, + CurrentVersion: f.CurrentVersion, + Epoch: f.Epoch, + } +} + func (f *Fork) EncodeSSZ(dst []byte) ([]byte, error) { buf := dst buf = append(buf, f.PreviousVersion[:]...) diff --git a/cl/cltypes/lightclient.go b/cl/cltypes/lightclient.go deleted file mode 100644 index d752f244903..00000000000 --- a/cl/cltypes/lightclient.go +++ /dev/null @@ -1,630 +0,0 @@ -package cltypes - -import ( - "fmt" - - libcommon "github.com/ledgerwatch/erigon-lib/common" - "github.com/ledgerwatch/erigon-lib/common/length" - "github.com/ledgerwatch/erigon/cl/clparams" - "github.com/ledgerwatch/erigon/cl/cltypes/ssz_utils" - "github.com/ledgerwatch/erigon/cl/utils" - "github.com/ledgerwatch/erigon/core/types" -) - -const ( - SyncCommitteeBranchLength = 5 - FinalityBranchLength = 6 - ExecutionBranchLength = 4 -) - -type LightClientHeader struct { - HeaderEth2 *BeaconBlockHeader - HeaderEth1 *types.Header - ExecutionBranch [ExecutionBranchLength]libcommon.Hash - version clparams.StateVersion -} - -func (l *LightClientHeader) WithVersion(v clparams.StateVersion) *LightClientHeader { - l.version = v - return l -} - -func (l *LightClientHeader) DecodeSSZ([]byte) error { - panic("not implemnted") -} - -func (l *LightClientHeader) DecodeSSZWithVersion(buf []byte, v int) error { - var err error - l.version = clparams.StateVersion(v) - l.HeaderEth2 = new(BeaconBlockHeader) - if err = l.HeaderEth2.DecodeSSZ(buf); err != nil { - return err - } - if l.version <= clparams.BellatrixVersion { - return nil - } - pos := l.HeaderEth2.EncodingSizeSSZ() + 4 // Skip the offset, assume it is at the end. - // Decode branch - for i := range l.ExecutionBranch { - copy(l.ExecutionBranch[i][:], buf[pos:]) - pos += length.Hash - } - l.HeaderEth1 = new(types.Header) - return l.HeaderEth1.DecodeSSZ(buf[pos:], l.version) -} - -func (l *LightClientHeader) EncodeSSZ(buf []byte) ([]byte, error) { - var ( - err error - dst = buf - ) - if dst, err = l.HeaderEth2.EncodeSSZ(dst); err != nil { - return nil, err - } - // Pre-capella is easy, encode only header. - if l.version < clparams.CapellaVersion { - return dst, nil - } - // Post-Capella - offset := uint32(l.HeaderEth2.EncodingSizeSSZ() + len(l.ExecutionBranch)*length.Hash + 4) - dst = append(dst, ssz_utils.OffsetSSZ(offset)...) - for _, root := range l.ExecutionBranch { - dst = append(dst, root[:]...) - } - return l.HeaderEth1.EncodeSSZ(dst) -} - -func (l *LightClientHeader) EncodingSizeSSZ() int { - if l.HeaderEth2 == nil { - l.HeaderEth2 = new(BeaconBlockHeader) - } - size := l.HeaderEth2.EncodingSizeSSZ() - if l.version >= clparams.CapellaVersion { - if l.HeaderEth1 == nil { - l.HeaderEth1 = new(types.Header) - } - size += l.HeaderEth1.EncodingSizeSSZ(l.version) + 4 - size += length.Hash * len(l.ExecutionBranch) - } - return size -} - -// LightClientBootstrap is used to bootstrap the lightclient from checkpoint sync. -type LightClientBootstrap struct { - Header *LightClientHeader - CurrentSyncCommittee *SyncCommittee - CurrentSyncCommitteeBranch []libcommon.Hash - version clparams.StateVersion -} - -func (l *LightClientBootstrap) WithVersion(v clparams.StateVersion) *LightClientBootstrap { - l.version = v - return l -} - -func (l *LightClientBootstrap) DecodeSSZ(buf []byte) error { - panic("AAAAAA") -} - -// EncodeSSZ ssz marshals the LightClientBootstrap object -func (l *LightClientBootstrap) EncodeSSZ(dst []byte) ([]byte, error) { - buf := dst - var err error - offset := l.CurrentSyncCommittee.EncodingSizeSSZ() + len(l.CurrentSyncCommitteeBranch)*length.Hash + 4 - if l.version < clparams.CapellaVersion { - if buf, err = l.Header.EncodeSSZ(buf); err != nil { - return nil, err - } - } else { - buf = append(buf, ssz_utils.OffsetSSZ(uint32(offset))...) - } - - if buf, err = l.CurrentSyncCommittee.EncodeSSZ(buf); err != nil { - return nil, err - } - if len(l.CurrentSyncCommitteeBranch) != SyncCommitteeBranchLength { - return nil, fmt.Errorf("sync committee branch is invalid") - } - for _, leaf := range l.CurrentSyncCommitteeBranch { - buf = append(buf, leaf[:]...) - } - if l.version >= clparams.CapellaVersion { - if buf, err = l.Header.EncodeSSZ(buf); err != nil { - return nil, err - } - } - return buf, nil -} - -// DecodeSSZ ssz unmarshals the LightClientBootstrap object -func (l *LightClientBootstrap) DecodeSSZWithVersion(buf []byte, version int) error { - var err error - l.version = clparams.StateVersion(version) - - if len(buf) < l.EncodingSizeSSZ() { - return ssz_utils.ErrLowBufferSize - } - l.Header = new(LightClientHeader) - l.CurrentSyncCommittee = new(SyncCommittee) - l.CurrentSyncCommitteeBranch = make([]libcommon.Hash, 5) - - pos := 0 - if l.version >= clparams.CapellaVersion { - pos += 4 - } else { - if err = l.Header.DecodeSSZWithVersion(buf[pos:], int(l.version)); err != nil { - return err - } - pos += l.Header.EncodingSizeSSZ() - } - - if err = l.CurrentSyncCommittee.DecodeSSZ(buf[pos:]); err != nil { - return err - } - pos += l.CurrentSyncCommittee.EncodingSizeSSZ() - - for i := range l.CurrentSyncCommitteeBranch { - copy(l.CurrentSyncCommitteeBranch[i][:], buf[pos:pos+32]) - pos += 32 - } - if l.version >= clparams.CapellaVersion { - if err = l.Header.DecodeSSZWithVersion(buf[pos:], int(l.version)); err != nil { - return err - } - } - - return err -} - -// EncodingSizeSSZ returns the ssz encoded size in bytes for the LightClientBootstrap object -func (l *LightClientBootstrap) EncodingSizeSSZ() (size int) { - if l.Header == nil { - l.Header = &LightClientHeader{version: l.version} - } - size = 0 - size += l.Header.EncodingSizeSSZ() - if l.version >= clparams.CapellaVersion { - size += 4 - } - if l.CurrentSyncCommittee == nil { - l.CurrentSyncCommittee = new(SyncCommittee) - l.CurrentSyncCommittee.PubKeys = make([][48]byte, SyncCommitteeSize) - } - - size += l.CurrentSyncCommittee.EncodingSizeSSZ() - - if len(l.CurrentSyncCommitteeBranch) == 0 { - l.CurrentSyncCommitteeBranch = make([]libcommon.Hash, SyncCommitteeBranchLength) - } - size += len(l.CurrentSyncCommitteeBranch) * length.Hash - - return -} - -// LightClientUpdate is used to update the sync committee every 27 hours. -type LightClientUpdate struct { - AttestedHeader *LightClientHeader - NextSyncCommitee *SyncCommittee - NextSyncCommitteeBranch []libcommon.Hash - FinalizedHeader *LightClientHeader - FinalityBranch []libcommon.Hash - SyncAggregate *SyncAggregate - SignatureSlot uint64 - - version clparams.StateVersion -} - -func (l *LightClientUpdate) WithVersion(v clparams.StateVersion) *LightClientUpdate { - l.version = v - return l -} - -func (l *LightClientUpdate) DecodeSSZ(buf []byte) error { - panic("OOOH") -} - -func (l *LightClientUpdate) HasNextSyncCommittee() bool { - return l.NextSyncCommitee != nil -} - -func (l *LightClientUpdate) IsFinalityUpdate() bool { - return l.FinalityBranch != nil -} - -func (l *LightClientUpdate) HasSyncFinality() bool { - return l.FinalizedHeader != nil && - utils.SlotToPeriod(l.AttestedHeader.HeaderEth2.Slot) == utils.SlotToPeriod(l.FinalizedHeader.HeaderEth2.Slot) -} - -// MarshalSSZTo ssz marshals the LightClientUpdate object to a target array -func (l *LightClientUpdate) EncodeSSZ(buf []byte) ([]byte, error) { - dst := buf - var err error - offset := 8 + l.NextSyncCommitee.EncodingSizeSSZ() + len(l.NextSyncCommitteeBranch)*length.Hash + - len(l.FinalityBranch)*length.Hash + l.SyncAggregate.EncodingSizeSSZ() + 8 - - if l.version >= clparams.CapellaVersion { - dst = append(dst, ssz_utils.OffsetSSZ(uint32(offset))...) - offset += l.AttestedHeader.EncodingSizeSSZ() - } else { - // Generic Update Specific - if dst, err = l.AttestedHeader.EncodeSSZ(dst); err != nil { - return nil, err - } - } - - if dst, err = l.NextSyncCommitee.EncodeSSZ(dst); err != nil { - return nil, err - } - - if len(l.NextSyncCommitteeBranch) != SyncCommitteeBranchLength { - return nil, fmt.Errorf("invalid size for nextSyncCommitteeBranch") - } - for _, leaf := range l.NextSyncCommitteeBranch { - dst = append(dst, leaf[:]...) - } - - dst, err = encodeFinalityUpdateSpecificField(dst, l.FinalizedHeader, l.FinalityBranch, uint32(offset)) - if err != nil { - return nil, err - } - - dst = encodeUpdateFooter(dst, l.SyncAggregate, l.SignatureSlot) - if l.version >= clparams.CapellaVersion { - if dst, err = l.AttestedHeader.EncodeSSZ(dst); err != nil { - return nil, err - } - if dst, err = l.FinalizedHeader.EncodeSSZ(dst); err != nil { - return nil, err - } - } - return dst, nil -} - -func encodeFinalityUpdateSpecificField(buf []byte, finalizedHeader *LightClientHeader, finalityBranch []libcommon.Hash, offset uint32) ([]byte, error) { - dst := buf - var err error - if finalizedHeader.version >= clparams.CapellaVersion { - dst = append(dst, ssz_utils.OffsetSSZ(offset)...) - } else { - if dst, err = finalizedHeader.EncodeSSZ(dst); err != nil { - return nil, err - } - } - - if len(finalityBranch) != FinalityBranchLength { - return nil, fmt.Errorf("invalid finality branch length") - } - for _, leaf := range finalityBranch { - dst = append(dst, leaf[:]...) - } - return dst, nil -} - -func encodeUpdateFooter(buf []byte, aggregate *SyncAggregate, signatureSlot uint64) []byte { - dst := buf - dst = aggregate.EncodeSSZ(dst) - return append(dst, ssz_utils.Uint64SSZ(signatureSlot)...) -} - -func decodeFinalityUpdateSpecificField(buf []byte, version clparams.StateVersion) (*LightClientHeader, []libcommon.Hash, uint32, int, error) { - header := &LightClientHeader{} - var offset uint32 - pos := 0 - if version < clparams.CapellaVersion { - if err := header.DecodeSSZWithVersion(buf, int(version)); err != nil { - return nil, nil, 0, 0, err - } - pos += header.EncodingSizeSSZ() - } else { - offset = ssz_utils.DecodeOffset(buf) - pos += 4 - } - - finalityBranch := make([]libcommon.Hash, FinalityBranchLength) - for i := range finalityBranch { - copy(finalityBranch[i][:], buf[pos:]) - pos += length.Hash - } - return header, finalityBranch, offset, pos, nil -} - -func decodeUpdateFooter(buf []byte) (*SyncAggregate, uint64, error) { - aggregate := &SyncAggregate{} - if err := aggregate.DecodeSSZ(buf); err != nil { - return nil, 0, err - } - return aggregate, ssz_utils.UnmarshalUint64SSZ(buf[aggregate.EncodingSizeSSZ():]), nil -} - -// LightClientFinalityUpdate is used to update the sync aggreggate every 6 minutes. -type LightClientFinalityUpdate struct { - AttestedHeader *LightClientHeader - FinalizedHeader *LightClientHeader - FinalityBranch []libcommon.Hash `ssz-size:"6,32"` - SyncAggregate *SyncAggregate - SignatureSlot uint64 - - version clparams.StateVersion -} - -func (l *LightClientFinalityUpdate) WithVersion(v clparams.StateVersion) *LightClientFinalityUpdate { - l.version = v - return l -} - -func (l *LightClientFinalityUpdate) DecodeSSZ(buf []byte) error { - panic("OOOOOOOOOOOOO") -} - -// DecodeSSZ ssz unmarshals the LightClientUpdate object -func (l *LightClientUpdate) DecodeSSZWithVersion(buf []byte, version int) error { - var err error - l.version = clparams.StateVersion(version) - if len(buf) < l.EncodingSizeSSZ() { - return ssz_utils.ErrLowBufferSize - } - - l.AttestedHeader = new(LightClientHeader) - l.NextSyncCommitee = new(SyncCommittee) - l.NextSyncCommitteeBranch = make([]libcommon.Hash, SyncCommitteeBranchLength) - l.FinalizedHeader = new(LightClientHeader) - l.SyncAggregate = new(SyncAggregate) - - var ( - pos int - offsetAttested uint32 - offsetFinalized uint32 - ) - - if l.version >= clparams.CapellaVersion { - offsetAttested = ssz_utils.DecodeOffset(buf) - pos += 4 - } else { - if err = l.AttestedHeader.DecodeSSZWithVersion(buf, version); err != nil { - return err - } - pos += l.AttestedHeader.EncodingSizeSSZ() - } - - if err = l.NextSyncCommitee.DecodeSSZ(buf[pos:]); err != nil { - return err - } - pos += l.NextSyncCommitee.EncodingSizeSSZ() - for i := range l.NextSyncCommitteeBranch { - copy(l.NextSyncCommitteeBranch[i][:], buf[pos:]) - pos += 32 - } - - var written int - l.FinalizedHeader, l.FinalityBranch, offsetFinalized, written, err = decodeFinalityUpdateSpecificField(buf[pos:], l.version) - if err != nil { - return err - } - pos += written - - l.SyncAggregate, l.SignatureSlot, err = decodeUpdateFooter(buf[pos:]) - if l.version >= clparams.CapellaVersion { - if offsetAttested > offsetFinalized || offsetFinalized > uint32(len(buf)) { - return ssz_utils.ErrBadOffset - } - if err = l.AttestedHeader.DecodeSSZWithVersion(buf[offsetAttested:offsetFinalized], version); err != nil { - return err - } - if err = l.FinalizedHeader.DecodeSSZWithVersion(buf[offsetFinalized:], version); err != nil { - return err - } - } - return err -} - -// EncodingSizeSSZ returns the ssz encoded size in bytes for the LightClientUpdate object -func (l *LightClientUpdate) EncodingSizeSSZ() int { - size := 0 - if l.version >= clparams.CapellaVersion { - size += 8 - } - if l.AttestedHeader == nil { - l.AttestedHeader = &LightClientHeader{version: l.version} - } - if l.NextSyncCommitee == nil { - l.NextSyncCommitee = new(SyncCommittee) - l.NextSyncCommitee.PubKeys = make([][48]byte, 512) - } - if l.FinalizedHeader == nil { - l.FinalizedHeader = &LightClientHeader{version: l.version} - } - if l.SyncAggregate == nil { - l.SyncAggregate = new(SyncAggregate) - } - if len(l.NextSyncCommitteeBranch) == 0 { - l.NextSyncCommitteeBranch = make([]libcommon.Hash, SyncCommitteeBranchLength) - } - if len(l.FinalityBranch) == 0 { - l.FinalityBranch = make([]libcommon.Hash, FinalityBranchLength) - } - return size + l.AttestedHeader.EncodingSizeSSZ() + l.FinalizedHeader.EncodingSizeSSZ() + l.SyncAggregate.EncodingSizeSSZ() + - 8 + len(l.FinalityBranch)*length.Hash + len(l.NextSyncCommitteeBranch)*length.Hash + l.NextSyncCommitee.EncodingSizeSSZ() -} - -func (l *LightClientFinalityUpdate) EncodeSSZ(buf []byte) ([]byte, error) { - dst := buf - var err error - offset := 8 + len(l.FinalityBranch)*length.Hash + l.SyncAggregate.EncodingSizeSSZ() + 8 - if l.version >= clparams.CapellaVersion { - dst = append(dst, ssz_utils.OffsetSSZ(uint32(offset))...) - offset += l.AttestedHeader.EncodingSizeSSZ() - } else { - // Generic Update Specific - if dst, err = l.AttestedHeader.EncodeSSZ(dst); err != nil { - return nil, err - } - } - - dst, err = encodeFinalityUpdateSpecificField(dst, l.FinalizedHeader, l.FinalityBranch, uint32(offset)) - if err != nil { - return nil, err - } - dst = encodeUpdateFooter(dst, l.SyncAggregate, l.SignatureSlot) - if l.version >= clparams.CapellaVersion { - if dst, err = l.AttestedHeader.EncodeSSZ(dst); err != nil { - return nil, err - } - if dst, err = l.FinalizedHeader.EncodeSSZ(dst); err != nil { - return nil, err - } - } - return dst, nil -} - -// DecodeSSZ ssz unmarshals the LightClientFinalityUpdate object -func (l *LightClientFinalityUpdate) DecodeSSZWithVersion(buf []byte, version int) error { - var err error - l.version = clparams.StateVersion(version) - if len(buf) < l.EncodingSizeSSZ() { - return ssz_utils.ErrBadOffset - } - - pos := 0 - l.AttestedHeader = new(LightClientHeader) - - var offsetAttested, offsetFinalized uint32 - if l.version < clparams.CapellaVersion { - if err = l.AttestedHeader.DecodeSSZWithVersion(buf, int(l.version)); err != nil { - return err - } - pos += l.AttestedHeader.EncodingSizeSSZ() - } else { - offsetAttested = ssz_utils.DecodeOffset(buf) - pos += 4 - } - - var written int - l.FinalizedHeader, l.FinalityBranch, offsetFinalized, written, err = decodeFinalityUpdateSpecificField(buf[pos:], l.version) - if err != nil { - return err - } - pos += written - - l.SyncAggregate, l.SignatureSlot, err = decodeUpdateFooter(buf[pos:]) - if err != nil { - return err - } - if l.version >= clparams.CapellaVersion { - if offsetAttested > offsetFinalized || offsetFinalized > uint32(len(buf)) { - return ssz_utils.ErrBadOffset - } - if err = l.AttestedHeader.DecodeSSZWithVersion(buf[offsetAttested:offsetFinalized], version); err != nil { - return err - } - if err = l.FinalizedHeader.DecodeSSZWithVersion(buf[offsetFinalized:], version); err != nil { - return err - } - } - return err -} - -func (l *LightClientFinalityUpdate) EncodingSizeSSZ() int { - size := 0 - if l.version >= clparams.CapellaVersion { - size += 8 - } - if l.AttestedHeader == nil { - l.AttestedHeader = &LightClientHeader{version: l.version} - } - if l.FinalizedHeader == nil { - l.FinalizedHeader = &LightClientHeader{version: l.version} - } - if l.SyncAggregate == nil { - l.SyncAggregate = new(SyncAggregate) - } - if len(l.FinalityBranch) == 0 { - l.FinalityBranch = make([]libcommon.Hash, FinalityBranchLength) - } - return size + l.AttestedHeader.EncodingSizeSSZ() + l.FinalizedHeader.EncodingSizeSSZ() + l.SyncAggregate.EncodingSizeSSZ() + - 8 + len(l.FinalityBranch)*length.Hash - -} - -// LightClientOptimisticUpdate is used for verifying N-1 block. -type LightClientOptimisticUpdate struct { - AttestedHeader *LightClientHeader - SyncAggregate *SyncAggregate - SignatureSlot uint64 - - version clparams.StateVersion -} - -func (l *LightClientOptimisticUpdate) WithVersion(v clparams.StateVersion) *LightClientOptimisticUpdate { - l.version = v - return l -} - -func (l *LightClientOptimisticUpdate) EncodeSSZ(buf []byte) ([]byte, error) { - dst := buf - var err error - if l.version >= clparams.CapellaVersion { - dst = append(dst, ssz_utils.OffsetSSZ(uint32(8+l.SyncAggregate.EncodingSizeSSZ()+4))...) - } else { - if dst, err = l.AttestedHeader.EncodeSSZ(dst); err != nil { - return nil, err - } - } - dst = encodeUpdateFooter(dst, l.SyncAggregate, l.SignatureSlot) - if l.version >= clparams.CapellaVersion { - if dst, err = l.AttestedHeader.EncodeSSZ(dst); err != nil { - return nil, err - } - } - return dst, nil -} - -func (l *LightClientOptimisticUpdate) DecodeSSZWithVersion(buf []byte, version int) error { - var err error - l.version = clparams.StateVersion(version) - if len(buf) < l.EncodingSizeSSZ() { - return ssz_utils.ErrBadOffset - } - - pos := 0 - l.AttestedHeader = new(LightClientHeader) - - if l.version < clparams.CapellaVersion { - if err = l.AttestedHeader.DecodeSSZWithVersion(buf, int(l.version)); err != nil { - return err - } - pos += l.AttestedHeader.EncodingSizeSSZ() - } else { - pos += 4 - } - - l.SyncAggregate, l.SignatureSlot, err = decodeUpdateFooter(buf[pos:]) - if err != nil { - return err - } - pos += l.SyncAggregate.EncodingSizeSSZ() + 8 - if l.version >= clparams.CapellaVersion { - if err = l.AttestedHeader.DecodeSSZWithVersion(buf[pos:], version); err != nil { - return err - } - } - return err - -} - -func (l *LightClientOptimisticUpdate) DecodeSSZ([]byte) error { - panic("DJFCF") -} - -func (l *LightClientOptimisticUpdate) EncodingSizeSSZ() (size int) { - if l.version >= clparams.CapellaVersion { - size += 4 - } - if l.AttestedHeader == nil { - l.AttestedHeader = &LightClientHeader{version: l.version} - } - if l.SyncAggregate == nil { - l.SyncAggregate = new(SyncAggregate) - } - return size + l.AttestedHeader.EncodingSizeSSZ() + l.SyncAggregate.EncodingSizeSSZ() + 8 -} diff --git a/cl/cltypes/lightclient_test.go b/cl/cltypes/lightclient_test.go deleted file mode 100644 index b4c98dcb4b3..00000000000 --- a/cl/cltypes/lightclient_test.go +++ /dev/null @@ -1,115 +0,0 @@ -package cltypes_test - -import ( - "testing" - - _ "embed" - - libcommon "github.com/ledgerwatch/erigon-lib/common" - - "github.com/ledgerwatch/erigon/cl/clparams" - "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/cl/utils" - "github.com/ledgerwatch/erigon/common" - "github.com/stretchr/testify/require" -) - -//go:embed tests/light_client_bootstrap.ssz_snappy -var bootstrapTest []byte - -//go:embed tests/light_client_optimistic.ssz_snappy -var optimisticTest []byte - -//go:embed tests/light_client_finality.ssz_snappy -var finalityTest []byte - -//go:embed tests/light_client_update.ssz_snappy -var updateTest []byte - -func TestLightclientBootstrapEncodingDecoding(t *testing.T) { - lc := cltypes.LightClientBootstrap{} - decodedSSZ, err := utils.DecompressSnappy(bootstrapTest) - require.NoError(t, err) - require.NoError(t, lc.DecodeSSZWithVersion(decodedSSZ, int(clparams.CapellaVersion))) - // checking fields - require.Equal(t, lc.Header.HeaderEth2.BodyRoot, libcommon.HexToHash("0x9eb9f39c2e88739dc4274483d1e9072c3685864d5bcbf2f3c072b97f54536a4e")) - require.Equal(t, *lc.Header.HeaderEth1.WithdrawalsHash, libcommon.HexToHash("0xd327e2d43fedf327de8f01ab8bbf4fbdbfececc890c5059ad53cfb37264cc03c")) - require.Equal(t, lc.Header.ExecutionBranch[0], libcommon.HexToHash("0x4138a3e27e9aea5c1c9eb311a7889bfddeb3d2ad3987943d68ee7cc659b6d947")) - require.Equal(t, lc.CurrentSyncCommittee.PubKeys[0][:], common.Hex2Bytes("009c6eacc6e3f29b10763a446fc6a6dfff95b408fb44c92b453e1349572d2b45b77305668349d39360e775752a4faf9a")) - require.Equal(t, lc.CurrentSyncCommittee.PubKeys[len(lc.CurrentSyncCommittee.PubKeys)-1][:], common.Hex2Bytes("dce9afb56fe779662a206c7d1503efacaf9d62fe81fa79d1fbfb9fd8ff03f7a11f263be6e4df633094cdfebcbd50112c")) - require.Equal(t, lc.CurrentSyncCommittee.AggregatePublicKey[:], common.Hex2Bytes("7455aa9ac6113a04b6976796d95dc2e4d7435ca37f47b9463b10fbaa32759db32ff9f7c4920c67d461ac1e4ebca56bb4")) - require.Equal(t, lc.CurrentSyncCommitteeBranch[0], libcommon.HexToHash("0x93a080a9f03a19868f6293f18236b8203f7ade39b78043184ada44b6b363ecfb")) - // encoding it back - dec, err := lc.EncodeSSZ(nil) - require.NoError(t, err) - require.Equal(t, dec, decodedSSZ) -} - -func TestLightclientOptimisticEncodingDecoding(t *testing.T) { - lc := cltypes.LightClientOptimisticUpdate{} - decodedSSZ, err := utils.DecompressSnappy(optimisticTest) - require.NoError(t, err) - require.NoError(t, lc.DecodeSSZWithVersion(decodedSSZ, int(clparams.CapellaVersion))) - // checking fields - require.Equal(t, lc.AttestedHeader.HeaderEth2.BodyRoot, libcommon.HexToHash("0x95e145e5890ccf3bf6c1c3708a51d42d7c602312d0ac2b225a1d54e30649e2f6")) - require.Equal(t, *lc.AttestedHeader.HeaderEth1.WithdrawalsHash, libcommon.HexToHash("0xdc96edf3b75ae19c608c0d5f821c3e71a577f310bf5da42bf51293394205b282")) - require.Equal(t, lc.AttestedHeader.ExecutionBranch[0], libcommon.HexToHash("0x9e29304aab0d41643d772d076861e0c951c5212f92e2c8b7788ee79c7a03c045")) - require.Equal(t, lc.SignatureSlot, uint64(6292665015452153680)) - require.Equal(t, lc.SyncAggregate.SyncCommiteeSignature[:], common.Hex2Bytes("60ac5c67c7a2f460b665a3a5f618d3b8e2356a2338279e2d24134795398e286ac0299cd6367986266f073c3a6b400f7d62a586e9687e7aace3dede4172677c6af2515338ceb3591a86bdae014c3cc057ffbcc1afe4127e8b55ad508ebcead13a")) - // encoding it back - dec, err := lc.EncodeSSZ(nil) - require.NoError(t, err) - require.Equal(t, dec, decodedSSZ) -} - -func TestLightclientFinalityEncodingDecoding(t *testing.T) { - lc := cltypes.LightClientFinalityUpdate{} - decodedSSZ, err := utils.DecompressSnappy(finalityTest) - require.NoError(t, err) - require.NoError(t, lc.DecodeSSZWithVersion(decodedSSZ, int(clparams.CapellaVersion))) - // checking fields - require.Equal(t, lc.AttestedHeader.HeaderEth2.BodyRoot, libcommon.HexToHash("0xcc67d01f9d529e16333170f366defcc0bb8fbd0a9b84bd13d787bbcf86fe3cc5")) - require.Equal(t, *lc.AttestedHeader.HeaderEth1.WithdrawalsHash, libcommon.HexToHash("0x28ce6c427881a19a7aaf0d2f8255e30376ee19193cd0278244141e1a66f3c45b")) - require.Equal(t, lc.AttestedHeader.ExecutionBranch[0], libcommon.HexToHash("0x3e85d631970da85df7a6dab6c62c198d0a291e891d5a897bafc87bcfd2312cf6")) - // Finalized header - require.Equal(t, lc.FinalizedHeader.HeaderEth2.BodyRoot, libcommon.HexToHash("0xbaa18d70c7a36d7e3af79bf0874b902a173d83daad5c56f83ede72788abda4e8")) - require.Equal(t, *lc.FinalizedHeader.HeaderEth1.WithdrawalsHash, libcommon.HexToHash("0x778c759c4dc95d80121cc56338c0e8fa657d3a39b6cfa67eec5ec471de48fa7e")) - require.Equal(t, lc.FinalizedHeader.ExecutionBranch[0], libcommon.HexToHash("0x103bab66f63d57f6158eef6f18c9ffcc6e9b2e2593731a58001fc991c39ac618")) - // Rest - require.Equal(t, lc.FinalityBranch[0], libcommon.HexToHash("838ab6e8d817f3d454a69e79a435cca780df0e5b1e62971df7fec176e57f7f37")) - require.Equal(t, lc.SignatureSlot, uint64(9588297899091073326)) - require.Equal(t, lc.SyncAggregate.SyncCommiteeSignature[:], common.Hex2Bytes("8eb0eb4c085e840235f15086287f62815607f2aac486f07b78a8b41ec6d0baee8b34f664b8efdee877080b44e3104792fe90dce4a211e9e58abeeefcb67b4918c61e01950b927ad25a988ebf52761c6c1d26eae4f501238359aac17361d6c3ae")) - // encoding it back - dec, err := lc.EncodeSSZ(nil) - require.NoError(t, err) - require.Equal(t, dec, decodedSSZ) -} - -func TestLightclientUpdateEncodingDecoding(t *testing.T) { - lc := cltypes.LightClientUpdate{} - decodedSSZ, err := utils.DecompressSnappy(updateTest) - require.NoError(t, err) - require.NoError(t, lc.DecodeSSZWithVersion(decodedSSZ, int(clparams.CapellaVersion))) - // checking fields - require.Equal(t, lc.AttestedHeader.HeaderEth2.BodyRoot, libcommon.HexToHash("0x49f3c74b8874e1595d74d970886245aff4748a11d499a8e4a9459e76e2c8c42f")) - require.Equal(t, *lc.AttestedHeader.HeaderEth1.WithdrawalsHash, libcommon.HexToHash("0xab14e4976e1af2983f637d57360f03fafb3d0586be3efe254ba32d612ebf21ea")) - require.Equal(t, lc.AttestedHeader.ExecutionBranch[0], libcommon.HexToHash("0x1b42aa11e8fb2cfe30f4ce521021426eb22824b1f2934e85c134c8d71795faf7")) - // Finalized header - require.Equal(t, lc.FinalizedHeader.HeaderEth2.BodyRoot, libcommon.HexToHash("0xcb968a1a97415c40e9fffcb2afc34cf97a41f37dabe0a2135f54441652cc9f9d")) - require.Equal(t, *lc.FinalizedHeader.HeaderEth1.WithdrawalsHash, libcommon.HexToHash("0xf9c686992daa952349ec70a44bf14238135b25c788f1286d8c5cb7aa8d43b94b")) - require.Equal(t, lc.FinalizedHeader.ExecutionBranch[0], libcommon.HexToHash("0x0c921fe9c8f7818d508ff6fb77c65ec143f1822ae520a63c4ebf8a80f11d5456")) - // Next sync committee - require.Equal(t, lc.NextSyncCommitee.PubKeys[0][:], common.Hex2Bytes("29a24e45031507af4f61d534c734042b67ce0e36a549f93e8b72644a4e3874e142a438d4e30eaa53d235125dd1cd7853")) - require.Equal(t, lc.NextSyncCommitee.PubKeys[len(lc.NextSyncCommitee.PubKeys)-1][:], common.Hex2Bytes("9dd39a3f44bdcf1b8df92202049b3f9114d59964d75d838bdd0011e161d65c1b320b22df82e78cc1ded097738e44f943")) - require.Equal(t, lc.NextSyncCommitee.AggregatePublicKey[:], common.Hex2Bytes("fa65b9c18cdc09b0378365eef95bc7607f15c27ac655b0d36ab415eec9b86b611f9e4a91fde40ee41f9756e445b7bf60")) - require.Equal(t, lc.NextSyncCommitteeBranch[0], libcommon.HexToHash("dbfa8fa48e3d6ddc4f03f7eaf7a8c972d93874be3dc099f04321d9f0330b4a7a")) - - // Rest - require.Equal(t, lc.FinalityBranch[0], libcommon.HexToHash("4fba794addb5d9a72464494236a7d571d4291bce2e03d64bec942f1fc72ab0df")) - require.Equal(t, lc.SignatureSlot, uint64(10239421204327532221)) - require.Equal(t, lc.SyncAggregate.SyncCommiteeSignature[:], common.Hex2Bytes("7d280e88d4358bcd312e9ccd894fef1dfeaf46e4a081ea07971779238a3dd8ad2ba339954e464df0a4cbbbbbd22258bdf543ad6f51232ec48e2d151527909c084189480dd6e350d5e022621aceeb478ff215b9d0e8fcd4fc7dca8c963f70533a")) - // encoding it back - dec, err := lc.EncodeSSZ(nil) - require.NoError(t, err) - require.Equal(t, dec, decodedSSZ) -} diff --git a/cl/cltypes/network_test.go b/cl/cltypes/network_test.go index 94f89921e02..1ffc3faf6bb 100644 --- a/cl/cltypes/network_test.go +++ b/cl/cltypes/network_test.go @@ -8,7 +8,7 @@ import ( "github.com/ledgerwatch/erigon/cl/clparams" "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/cl/cltypes/ssz_utils" + "github.com/ledgerwatch/erigon/cl/cltypes/ssz" ) var testMetadata = &cltypes.Metadata{ @@ -49,70 +49,23 @@ var testHeader = &cltypes.BeaconBlockHeader{ BodyRoot: libcommon.HexToHash("ad"), } -var testLcHeader = (&cltypes.LightClientHeader{ - HeaderEth1: getTestEth1Block().Header, - HeaderEth2: testHeader, -}).WithVersion(clparams.CapellaVersion) - -var testLcUpdate = (&cltypes.LightClientUpdate{ - AttestedHeader: testLcHeader, - NextSyncCommitee: &cltypes.SyncCommittee{ - PubKeys: make([][48]byte, 512), - }, - NextSyncCommitteeBranch: make([]libcommon.Hash, 5), - FinalizedHeader: testLcHeader, - FinalityBranch: make([]libcommon.Hash, 6), - SyncAggregate: &cltypes.SyncAggregate{}, - SignatureSlot: 294, -}).WithVersion(clparams.CapellaVersion) - -var testLcUpdateFinality = (&cltypes.LightClientFinalityUpdate{ - AttestedHeader: testLcHeader, - FinalizedHeader: testLcHeader, - FinalityBranch: make([]libcommon.Hash, 6), - SyncAggregate: &cltypes.SyncAggregate{}, - SignatureSlot: 294, -}).WithVersion(clparams.CapellaVersion) - -var testLcUpdateOptimistic = (&cltypes.LightClientOptimisticUpdate{ - AttestedHeader: testLcHeader, - SyncAggregate: &cltypes.SyncAggregate{}, - SignatureSlot: 294, -}).WithVersion(clparams.CapellaVersion) - -var testLcBootstrap = (&cltypes.LightClientBootstrap{ - Header: testLcHeader, - CurrentSyncCommittee: &cltypes.SyncCommittee{ - PubKeys: make([][48]byte, 512), - }, - CurrentSyncCommitteeBranch: make([]libcommon.Hash, 5), -}).WithVersion(clparams.CapellaVersion) - func TestMarshalNetworkTypes(t *testing.T) { - cases := []ssz_utils.EncodableSSZ{ + cases := []ssz.EncodableSSZ{ testMetadata, testPing, testSingleRoot, testLcRangeRequest, testBlockRangeRequest, testStatus, - testLcUpdate, - testLcUpdateFinality, - testLcUpdateOptimistic, - testLcBootstrap, } - unmarshalDestinations := []ssz_utils.EncodableSSZ{ + unmarshalDestinations := []ssz.EncodableSSZ{ &cltypes.Metadata{}, &cltypes.Ping{}, &cltypes.SingleRoot{}, &cltypes.LightClientUpdatesByRangeRequest{}, &cltypes.BeaconBlocksByRangeRequest{}, &cltypes.Status{}, - &cltypes.LightClientUpdate{}, - &cltypes.LightClientFinalityUpdate{}, - &cltypes.LightClientOptimisticUpdate{}, - &cltypes.LightClientBootstrap{}, } for i, tc := range cases { marshalledBytes, err := tc.EncodeSSZ(nil) diff --git a/cl/cltypes/validator.go b/cl/cltypes/validator.go index 87c086b42e9..ed2331baf8c 100644 --- a/cl/cltypes/validator.go +++ b/cl/cltypes/validator.go @@ -207,6 +207,14 @@ type SyncCommittee struct { AggregatePublicKey [48]byte `ssz-size:"48"` } +func (s *SyncCommittee) Copy() *SyncCommittee { + copied := new(SyncCommittee) + copied.AggregatePublicKey = s.AggregatePublicKey + copied.PubKeys = make([][48]byte, len(s.PubKeys)) + copy(copied.PubKeys, s.PubKeys) + return copied +} + // MarshalSSZTo ssz marshals the SyncCommittee object to a target array func (s *SyncCommittee) EncodeSSZ(buf []byte) ([]byte, error) { dst := buf @@ -360,3 +368,8 @@ func (v *Validator) HashSSZ() ([32]byte, error) { func (v *Validator) Active(epoch uint64) bool { return v.ActivationEpoch <= epoch && epoch < v.ExitEpoch } + +func (v *Validator) Copy() *Validator { + copied := *v + return &copied +} diff --git a/cl/fork/fork_test.go b/cl/fork/fork_test.go index 30e47f4c4cf..9aaaf4e1de3 100644 --- a/cl/fork/fork_test.go +++ b/cl/fork/fork_test.go @@ -27,5 +27,5 @@ func TestMainnetFork(t *testing.T) { require.NoError(t, err) _, err = ComputeForkId(&beaconCfg, &genesisCfg) require.NoError(t, err) - require.Equal(t, digest, [4]byte{74, 38, 197, 139}) + require.Equal(t, [4]byte{0xbb, 0xa4, 0xda, 0x96}, digest) } diff --git a/cl/fork/id.go b/cl/fork/id.go deleted file mode 100644 index 6f49755bda2..00000000000 --- a/cl/fork/id.go +++ /dev/null @@ -1,99 +0,0 @@ -package fork - -import ( - "github.com/ledgerwatch/erigon/cl/clparams" - "github.com/ledgerwatch/erigon/cl/utils" - pubsubpb "github.com/libp2p/go-libp2p-pubsub/pb" -) - -// MsgID return the id of Gossip message during subscription. -func MsgID(pmsg *pubsubpb.Message, networkConfig *clparams.NetworkConfig, beaconConfig *clparams.BeaconChainConfig, genesisConfig *clparams.GenesisConfig) string { - if pmsg == nil || pmsg.Data == nil || pmsg.Topic == nil { - // Impossible condition that should - // never be hit. - msg := make([]byte, 20) - copy(msg, "invalid") - return string(msg) - } - - fEpoch := getLastForkEpoch(beaconConfig, genesisConfig) - - if fEpoch >= beaconConfig.AltairForkEpoch { - return postAltairMsgID(pmsg, fEpoch, networkConfig, beaconConfig) - } - - decodedData, err := utils.DecompressSnappy(pmsg.Data) - if err != nil { - msg := make([]byte, 20) - copy(msg, "invalid") - return string(msg) - } - - if err != nil { - combinedData := append(networkConfig.MessageDomainInvalidSnappy[:], pmsg.Data...) - h := utils.Keccak256(combinedData) - return string(h[:20]) - } - combinedData := append(networkConfig.MessageDomainValidSnappy[:], decodedData...) - h := utils.Keccak256(combinedData) - return string(h[:20]) -} - -func postAltairMsgID(pmsg *pubsubpb.Message, fEpoch uint64, networkConfig *clparams.NetworkConfig, beaconConfig *clparams.BeaconChainConfig) string { - topic := *pmsg.Topic - topicLen := len(topic) - topicLenBytes := utils.Uint64ToLE(uint64(topicLen)) // topicLen cannot be negative - - // beyond Bellatrix epoch, allow 10 Mib gossip data size - gossipPubSubSize := networkConfig.GossipMaxSize - if fEpoch >= beaconConfig.BellatrixForkEpoch { - gossipPubSubSize = networkConfig.GossipMaxSizeBellatrix - } - - decodedData, err := utils.DecompressSnappy(pmsg.Data) - if err != nil { - totalLength := len(networkConfig.MessageDomainValidSnappy) + len(topicLenBytes) + topicLen + len(pmsg.Data) - if uint64(totalLength) > gossipPubSubSize { - // this should never happen - msg := make([]byte, 20) - copy(msg, "invalid") - return string(msg) - } - combinedData := make([]byte, 0, totalLength) - combinedData = append(combinedData, networkConfig.MessageDomainInvalidSnappy[:]...) - combinedData = append(combinedData, topicLenBytes...) - combinedData = append(combinedData, topic...) - combinedData = append(combinedData, pmsg.Data...) - h := utils.Keccak256(combinedData) - return string(h[:20]) - } - totalLength := len(networkConfig.MessageDomainValidSnappy) + - len(topicLenBytes) + - topicLen + - len(decodedData) - - combinedData := make([]byte, 0, totalLength) - combinedData = append(combinedData, networkConfig.MessageDomainValidSnappy[:]...) - combinedData = append(combinedData, topicLenBytes...) - combinedData = append(combinedData, topic...) - combinedData = append(combinedData, decodedData...) - h := utils.Keccak256(combinedData) - return string(h[:20]) -} - -func getLastForkEpoch( - beaconConfig *clparams.BeaconChainConfig, - genesisConfig *clparams.GenesisConfig, -) uint64 { - currentEpoch := utils.GetCurrentEpoch(genesisConfig.GenesisTime, beaconConfig.SecondsPerSlot, beaconConfig.SlotsPerEpoch) - // Retrieve current fork version. - var currentForkEpoch uint64 - for _, fork := range forkList(beaconConfig.ForkVersionSchedule) { - if currentEpoch >= fork.epoch { - currentForkEpoch = fork.epoch - continue - } - break - } - return currentForkEpoch -} diff --git a/cl/rpc/rpc.go b/cl/rpc/rpc.go index 86f93ddaa40..57adac1ab59 100644 --- a/cl/rpc/rpc.go +++ b/cl/rpc/rpc.go @@ -17,7 +17,6 @@ import ( "github.com/ledgerwatch/erigon/cl/clparams" "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/cl/cltypes/ssz_utils" "github.com/ledgerwatch/erigon/cl/fork" "github.com/ledgerwatch/erigon/cl/utils" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/communication" @@ -50,108 +49,6 @@ func NewBeaconRpcP2P(ctx context.Context, sentinel sentinel.SentinelClient, beac } } -// SendLightClientFinalityUpdateReqV1 sends a request for a LightClientFinalityUpdate message to a beacon chain node. -// It returns a LightClientFinalityUpdate struct or an error if one occurred. -func (b *BeaconRpcP2P) SendLightClientFinaltyUpdateReqV1() (*cltypes.LightClientFinalityUpdate, error) { - responsePacket := &cltypes.LightClientFinalityUpdate{} - - message, err := b.sentinel.SendRequest(b.ctx, &sentinel.RequestData{ - Topic: communication.LightClientFinalityUpdateV1, - }) - if err != nil { - return nil, err - } - if message.Error { - log.Warn("received error", "err", string(message.Data)) - return nil, nil - } - - if err := ssz_snappy.DecodeAndRead(bytes.NewReader(message.Data), responsePacket, b.beaconConfig, b.genesisConfig.GenesisValidatorRoot); err != nil { - return nil, fmt.Errorf("unable to decode packet: %v", err) - } - return responsePacket, nil -} - -// SendLightClientOptimisticUpdateReqV1 sends a request for a LightClientOptimisticUpdate message to a beacon chain node. -// It returns a LightClientOptimisticUpdate struct or an error if one occurred. -func (b *BeaconRpcP2P) SendLightClientOptimisticUpdateReqV1() (*cltypes.LightClientOptimisticUpdate, error) { - responsePacket := &cltypes.LightClientOptimisticUpdate{} - - message, err := b.sentinel.SendRequest(b.ctx, &sentinel.RequestData{ - Topic: communication.LightClientOptimisticUpdateV1, - }) - if err != nil { - return nil, err - } - if message.Error { - log.Warn("received error", "err", string(message.Data)) - return nil, nil - } - - if err := ssz_snappy.DecodeAndRead(bytes.NewReader(message.Data), responsePacket, b.beaconConfig, b.genesisConfig.GenesisValidatorRoot); err != nil { - return nil, fmt.Errorf("unable to decode packet: %v", err) - } - return responsePacket, nil -} - -// SendLightClientBootstrapReqV1 sends a request for a LightClientBootstrap message to a beacon chain node. -// It returns a LightClientBootstrap struct or an error if one occurred. -func (b *BeaconRpcP2P) SendLightClientBootstrapReqV1(root libcommon.Hash) (*cltypes.LightClientBootstrap, error) { - var buffer buffer.Buffer - if err := ssz_snappy.EncodeAndWrite(&buffer, &cltypes.SingleRoot{Root: root}); err != nil { - return nil, err - } - responsePacket := &cltypes.LightClientBootstrap{} - data := common.CopyBytes(buffer.Bytes()) - message, err := b.sentinel.SendRequest(b.ctx, &sentinel.RequestData{ - Data: data, - Topic: communication.LightClientBootstrapV1, - }) - if err != nil { - return nil, err - } - if message.Error { - log.Warn("received error", "err", string(message.Data)) - return nil, nil - } - if err := ssz_snappy.DecodeAndRead(bytes.NewReader(message.Data), responsePacket, b.beaconConfig, b.genesisConfig.GenesisValidatorRoot); err != nil { - return nil, fmt.Errorf("unable to decode packet: %v", err) - } - return responsePacket, nil -} - -// SendLightClientUpdatesReqV1 retrieves one lightclient update. -func (b *BeaconRpcP2P) SendLightClientUpdatesReqV1(period uint64) (*cltypes.LightClientUpdate, error) { - // This is approximately one day worth of data, we dont need to receive more than 1. - req := &cltypes.LightClientUpdatesByRangeRequest{ - Period: period, - Count: 1, - } - var buffer buffer.Buffer - if err := ssz_snappy.EncodeAndWrite(&buffer, req); err != nil { - return nil, err - } - - responsePacket := []ssz_utils.EncodableSSZ{&cltypes.LightClientUpdate{}} - - data := common.CopyBytes(buffer.Bytes()) - message, err := b.sentinel.SendRequest(b.ctx, &sentinel.RequestData{ - Data: data, - Topic: communication.LightClientUpdatesByRangeV1, - }) - if err != nil { - return nil, err - } - if message.Error { - log.Warn("received error", "err", string(message.Data)) - return nil, nil - } - if err := ssz_snappy.DecodeListSSZ(message.Data, 1, responsePacket, b.beaconConfig, b.genesisConfig.GenesisValidatorRoot); err != nil { - return nil, fmt.Errorf("unable to decode packet: %v", err) - } - return responsePacket[0].(*cltypes.LightClientUpdate), nil -} - func (b *BeaconRpcP2P) sendBlocksRequest(topic string, reqData []byte, count uint64) ([]*cltypes.SignedBeaconBlock, error) { // Prepare output slice. responsePacket := []*cltypes.SignedBeaconBlock{} @@ -272,3 +169,15 @@ func (b *BeaconRpcP2P) SetStatus(finalizedRoot libcommon.Hash, finalizedEpoch ui }) return err } + +func (b *BeaconRpcP2P) PropagateBlock(block *cltypes.SignedBeaconBlock) error { + encoded, err := block.EncodeSSZ(nil) + if err != nil { + return err + } + _, err = b.sentinel.PublishGossip(b.ctx, &sentinel.GossipData{ + Data: encoded, + Type: sentinel.GossipType_BeaconBlockGossipType, + }) + return err +} diff --git a/cmd/abigen/main.go b/cmd/abigen/main.go index b6a75323f58..6d361b48388 100644 --- a/cmd/abigen/main.go +++ b/cmd/abigen/main.go @@ -180,7 +180,7 @@ func abigen(c *cli.Context) error { } else { // Generate the list of types to exclude from binding exclude := make(map[string]bool) - for _, kind := range strings.Split(c.String(excFlag.Name), ",") { + for _, kind := range utils.SplitAndTrim(c.String(excFlag.Name)) { exclude[strings.ToLower(kind)] = true } var err error diff --git a/cmd/bootnode/main.go b/cmd/bootnode/main.go index abdbbecd384..b954f536e14 100644 --- a/cmd/bootnode/main.go +++ b/cmd/bootnode/main.go @@ -51,7 +51,7 @@ func main() { ) flag.Parse() - _ = logging.GetLogger("bootnode") + logging.SetupLogger("bootnode") natm, err := nat.Parse(*natdesc) if err != nil { diff --git a/cmd/caplin-phase1/caplin1/run.go b/cmd/caplin-phase1/caplin1/run.go new file mode 100644 index 00000000000..04c7e5074bd --- /dev/null +++ b/cmd/caplin-phase1/caplin1/run.go @@ -0,0 +1,31 @@ +package caplin1 + +import ( + "context" + + "github.com/ledgerwatch/erigon-lib/gointerfaces/sentinel" + "github.com/ledgerwatch/erigon/cl/clparams" + "github.com/ledgerwatch/erigon/cl/rpc" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/state" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/execution_client" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/forkchoice" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/network" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/stages" + "github.com/ledgerwatch/log/v3" + + "github.com/ledgerwatch/erigon/eth/stagedsync" +) + +func RunCaplinPhase1(ctx context.Context, sentinel sentinel.SentinelClient, beaconConfig *clparams.BeaconChainConfig, genesisConfig *clparams.GenesisConfig, engine execution_client.ExecutionEngine, state *state.BeaconState) error { + beaconRpc := rpc.NewBeaconRpcP2P(ctx, sentinel, beaconConfig, genesisConfig) + downloader := network.NewForwardBeaconDownloader(ctx, beaconRpc) + + forkChoice, err := forkchoice.NewForkChoiceStore(state, engine, true) + if err != nil { + log.Error("Could not create forkchoice", "err", err) + return err + } + gossipManager := network.NewGossipReceiver(ctx, sentinel, forkChoice, beaconConfig, genesisConfig) + + return stages.SpawnStageForkChoice(stages.StageForkChoice(nil, downloader, genesisConfig, beaconConfig, state, nil, gossipManager, forkChoice), &stagedsync.StageState{ID: "Caplin"}, nil, ctx) +} diff --git a/cmd/lightclient/main.go b/cmd/caplin-phase1/main.go similarity index 66% rename from cmd/lightclient/main.go rename to cmd/caplin-phase1/main.go index 9a1e1c599e9..262b02c1b5a 100644 --- a/cmd/lightclient/main.go +++ b/cmd/caplin-phase1/main.go @@ -19,27 +19,24 @@ import ( "os" "github.com/ledgerwatch/erigon-lib/gointerfaces/remote" - "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/erigon-lib/kv/mdbx" - "github.com/ledgerwatch/erigon-lib/kv/memdb" "github.com/ledgerwatch/log/v3" "github.com/urfave/cli/v2" "google.golang.org/grpc" "github.com/ledgerwatch/erigon/cl/cltypes" "github.com/ledgerwatch/erigon/cl/fork" + "github.com/ledgerwatch/erigon/cmd/caplin-phase1/caplin1" "github.com/ledgerwatch/erigon/cmd/erigon-cl/core" - "github.com/ledgerwatch/erigon/cmd/lightclient/lightclient" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/execution_client" lcCli "github.com/ledgerwatch/erigon/cmd/sentinel/cli" "github.com/ledgerwatch/erigon/cmd/sentinel/cli/flags" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel" - "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/handshake" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/service" lightclientapp "github.com/ledgerwatch/erigon/turbo/app" ) func main() { - app := lightclientapp.MakeApp(runLightClientNode, flags.LCDefaultFlags) + app := lightclientapp.MakeApp(runCaplinNode, flags.LCDefaultFlags) if err := app.Run(os.Args); err != nil { _, printErr := fmt.Fprintln(os.Stderr, err) if printErr != nil { @@ -49,25 +46,15 @@ func main() { } } -func runLightClientNode(cliCtx *cli.Context) error { +func runCaplinNode(cliCtx *cli.Context) error { ctx := context.Background() cfg, err := lcCli.SetupConsensusClientCfg(cliCtx) if err != nil { - log.Error("[Lightclient] Could not initialize lightclient", "err", err) + log.Error("[Phase1] Could not initialize caplin", "err", err) } log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(cfg.LogLvl), log.StderrHandler)) - log.Info("[LightClient]", "chain", cliCtx.String(flags.Chain.Name)) - log.Info("[LightClient] Running lightclient", "cfg", cfg) - var db kv.RwDB - if cfg.Chaindata == "" { - log.Info("chaindata is in-memory") - db = memdb.New("" /* tmpDir */) - } else { - db, err = mdbx.Open(cfg.Chaindata, log.Root(), false) - if err != nil { - return err - } - } + log.Info("[Phase1]", "chain", cliCtx.String(flags.Chain.Name)) + log.Info("[Phase1] Running Caplin", "cfg", cfg) state, err := core.RetrieveBeaconState(ctx, cfg.BeaconCfg, cfg.GenesisCfg, cfg.CheckpointUri) if err != nil { return err @@ -86,40 +73,31 @@ func runLightClientNode(cliCtx *cli.Context) error { NetworkConfig: cfg.NetworkCfg, BeaconConfig: cfg.BeaconCfg, NoDiscovery: cfg.NoDiscovery, - }, db, &service.ServerConfig{Network: cfg.ServerProtocol, Addr: cfg.ServerAddr}, nil, &cltypes.Status{ + }, nil, &service.ServerConfig{Network: cfg.ServerProtocol, Addr: cfg.ServerAddr}, nil, &cltypes.Status{ ForkDigest: forkDigest, FinalizedRoot: state.FinalizedCheckpoint().Root, FinalizedEpoch: state.FinalizedCheckpoint().Epoch, HeadSlot: state.FinalizedCheckpoint().Epoch * cfg.BeaconCfg.SlotsPerEpoch, HeadRoot: state.FinalizedCheckpoint().Root, - }, handshake.LightClientRule) + }) if err != nil { log.Error("Could not start sentinel", "err", err) } + log.Info("Sentinel started", "addr", cfg.ServerAddr) if err != nil { log.Error("[Checkpoint Sync] Failed", "reason", err) return err } - var execution remote.ETHBACKENDClient + var engine execution_client.ExecutionEngine if cfg.ErigonPrivateApi != "" { cc, err := grpc.Dial(cfg.ErigonPrivateApi, grpc.WithInsecure()) if err != nil { log.Error("could not connect to erigon private api", "err", err) } defer cc.Close() - execution = remote.NewETHBACKENDClient(cc) - } - lc, err := lightclient.NewLightClient(ctx, db, cfg.GenesisCfg, cfg.BeaconCfg, nil, execution, sentinel, 0, true) - if err != nil { - log.Error("Could not make Lightclient", "err", err) - return err - } - if err := lc.BootstrapCheckpoint(ctx, state.FinalizedCheckpoint().Root); err != nil { - log.Error("[Bootstrap] failed to bootstrap", "err", err) - return err + engine = execution_client.NewExecutionEnginePhase1FromClient(ctx, remote.NewETHBACKENDClient(cc)) } - lc.Start() - return nil + return caplin1.RunCaplinPhase1(ctx, sentinel, cfg.BeaconCfg, cfg.GenesisCfg, engine, state) } diff --git a/cmd/devnet/commands/all.go b/cmd/devnet/commands/all.go index e746bd415e2..0236e36af82 100644 --- a/cmd/devnet/commands/all.go +++ b/cmd/devnet/commands/all.go @@ -22,7 +22,7 @@ func ExecuteAllMethods() { // confirm that the txpool is empty fmt.Println("CONFIRMING TXPOOL IS EMPTY BEFORE SENDING TRANSACTION...") - services.CheckTxPoolContent(0, 0) + services.CheckTxPoolContent(0, 0, 0) fmt.Println() /* @@ -39,8 +39,6 @@ func ExecuteAllMethods() { //} //fmt.Println() - // USING DYNAMIC FEE - // send a token from the dev address to the recipient address _, err := callSendTxWithDynamicFee(recipientAddress, models.DevAddress) if err != nil { fmt.Printf("callSendTxWithDynamicFee error: %v\n", err) diff --git a/cmd/devnet/commands/block.go b/cmd/devnet/commands/block.go index 6259557b310..da7cd8c9712 100644 --- a/cmd/devnet/commands/block.go +++ b/cmd/devnet/commands/block.go @@ -2,8 +2,11 @@ package commands import ( "fmt" + "time" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" + "github.com/ledgerwatch/erigon/cmd/devnet/devnetutils" "github.com/ledgerwatch/erigon/cmd/devnet/models" "github.com/ledgerwatch/erigon/cmd/devnet/requests" @@ -40,8 +43,6 @@ func callSendTx(value uint64, toAddr, fromAddr string) (*libcommon.Hash, error) return nil, err } - fmt.Printf("SUCCESS => Tx submitted, adding tx with hash %q to txpool\n", hash) - hashes := map[libcommon.Hash]bool{*hash: true} if _, err = services.SearchReservesForTransactionHash(hashes); err != nil { return nil, fmt.Errorf("failed to call contract tx: %v", err) @@ -58,7 +59,7 @@ func callSendTxWithDynamicFee(toAddr, fromAddr string) ([]*libcommon.Hash, error return nil, err } - lowerThanBaseFeeTxs, higherThanBaseFeeTxs, err := services.CreateManyEIP1559TransactionsRefWithBaseFee(toAddr, &nonce) + lowerThanBaseFeeTxs, higherThanBaseFeeTxs, err := services.CreateManyEIP1559TransactionsRefWithBaseFee2(toAddr, &nonce) if err != nil { fmt.Printf("failed CreateManyEIP1559TransactionsRefWithBaseFee: %s\n", err) return nil, err @@ -76,7 +77,7 @@ func callSendTxWithDynamicFee(toAddr, fromAddr string) ([]*libcommon.Hash, error return nil, err } - services.CheckTxPoolContent(2, 0) + services.CheckTxPoolContent(100, 0, 100) hashmap := make(map[libcommon.Hash]bool) for _, hash := range higherThanBaseFeeHashlist { @@ -87,6 +88,24 @@ func callSendTxWithDynamicFee(toAddr, fromAddr string) ([]*libcommon.Hash, error return nil, fmt.Errorf("failed to call contract tx: %v", err) } + fmt.Println("SUCCESS: All transactions in pending pool mined.") + + for i := 1; i <= 20; i++ { + blockNumber, err := requests.BlockNumber(models.ReqId) + if err != nil { + fmt.Printf("FAILURE => error getting block number: %v\n", err) + } else { + fmt.Printf("Block number: %d\n", blockNumber) + } + pendingSize, queuedSize, baseFeeSize, err := requests.TxpoolContent(models.ReqId) + if err != nil { + fmt.Printf("FAILURE => error getting txpool content: %v\n", err) + } else { + fmt.Printf("Pending %d Queued %d, BaseFee %d\n", pendingSize, queuedSize, baseFeeSize) + } + time.Sleep(5 * time.Second) + } + return append(lowerThanBaseFeeHashlist, higherThanBaseFeeHashlist...), nil } @@ -114,7 +133,6 @@ func callContractTx() (*libcommon.Hash, error) { return nil, err } hashes[*hash] = true - fmt.Printf("SUCCESS => Tx submitted, adding tx with hash %q to txpool\n", hash) fmt.Println() eventHash, err := services.EmitFallbackEvent(subscriptionContract, transactOpts) @@ -137,7 +155,7 @@ func callContractTx() (*libcommon.Hash, error) { } expectedLog := devnetutils.BuildLog(*eventHash, blockNum, address, - devnetutils.GenerateTopic(models.SolContractMethodSignature), hexutil.Bytes{}, hexutil.Uint(1), + devnetutils.GenerateTopic(models.SolContractMethodSignature), hexutility.Bytes{}, hexutil.Uint(1), block.Result.Hash, hexutil.Uint(0), false) if err = requests.GetAndCompareLogs(models.ReqId, 0, 20, expectedLog); err != nil { diff --git a/cmd/devnet/devnetutils/utils.go b/cmd/devnet/devnetutils/utils.go index 5faa8665a82..81e5460acf7 100644 --- a/cmd/devnet/devnetutils/utils.go +++ b/cmd/devnet/devnetutils/utils.go @@ -5,6 +5,8 @@ import ( "encoding/json" "fmt" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" + "github.com/ledgerwatch/erigon/cmd/devnet/models" "github.com/ledgerwatch/erigon/cmd/rpctest/rpctest" "github.com/ledgerwatch/erigon/common/hexutil" @@ -115,7 +117,7 @@ func HashSlicesAreEqual(s1, s2 []libcommon.Hash) bool { return true } -func BuildLog(hash libcommon.Hash, blockNum string, address libcommon.Address, topics []libcommon.Hash, data hexutil.Bytes, txIndex hexutil.Uint, blockHash libcommon.Hash, index hexutil.Uint, removed bool) rpctest.Log { +func BuildLog(hash libcommon.Hash, blockNum string, address libcommon.Address, topics []libcommon.Hash, data hexutility.Bytes, txIndex hexutil.Uint, blockHash libcommon.Hash, index hexutil.Uint, removed bool) rpctest.Log { return rpctest.Log{ Address: address, Topics: topics, diff --git a/cmd/devnet/models/model.go b/cmd/devnet/models/model.go index c864f75329c..e375d80e74f 100644 --- a/cmd/devnet/models/model.go +++ b/cmd/devnet/models/model.go @@ -116,6 +116,8 @@ const ( ETHGetBlock RPCMethod = "eth_getBlock" // ETHGetLogs represents the eth_getLogs method ETHGetLogs RPCMethod = "eth_getLogs" + // ETHBlockNumber represents the eth_blockNumber method + ETHBlockNumber RPCMethod = "eth_blockNumber" // AdminNodeInfo represents the admin_nodeInfo method AdminNodeInfo RPCMethod = "admin_nodeInfo" // TxpoolContent represents the txpool_content method diff --git a/cmd/devnet/node/node.go b/cmd/devnet/node/node.go index 69eafce965d..66b00c10a33 100644 --- a/cmd/devnet/node/node.go +++ b/cmd/devnet/node/node.go @@ -78,15 +78,13 @@ func StartNode(wg *sync.WaitGroup, args []string) { // runNode configures, creates and serves an erigon node func runNode(ctx *cli.Context) error { - logger := log.New() - // Initializing the node and providing the current git commit there - logger.Info("Build info", "git_branch", params.GitBranch, "git_tag", params.GitTag, "git_commit", params.GitCommit) + log.Info("Build info", "git_branch", params.GitBranch, "git_tag", params.GitTag, "git_commit", params.GitCommit) nodeCfg := node.NewNodConfigUrfave(ctx) ethCfg := node.NewEthConfigUrfave(ctx, nodeCfg) - ethNode, err := node.New(nodeCfg, ethCfg, logger) + ethNode, err := node.New(nodeCfg, ethCfg) if err != nil { log.Error("Devnet startup", "err", err) return err diff --git a/cmd/devnet/requests/block.go b/cmd/devnet/requests/block.go index 3fae52c245d..98083c85d02 100644 --- a/cmd/devnet/requests/block.go +++ b/cmd/devnet/requests/block.go @@ -11,6 +11,21 @@ import ( "github.com/ledgerwatch/erigon/core/types" ) +func BlockNumber(reqId int) (uint64, error) { + reqGen := initialiseRequestGenerator(reqId) + var b rpctest.EthBlockNumber + + req := reqGen.BlockNumber() + res := reqGen.Erigon(models.ETHBlockNumber, req, &b) + number := uint64(b.Number) + + if res.Err != nil { + return number, fmt.Errorf("error getting current block number: %v", res.Err) + } + + return number, nil +} + func GetBlockByNumber(reqId int, blockNum uint64, withTxs bool) (rpctest.EthBlockByNumber, error) { reqGen := initialiseRequestGenerator(reqId) var b rpctest.EthBlockByNumber diff --git a/cmd/devnet/requests/request_generator.go b/cmd/devnet/requests/request_generator.go index a7feb87a311..48dbd8e7e0d 100644 --- a/cmd/devnet/requests/request_generator.go +++ b/cmd/devnet/requests/request_generator.go @@ -68,6 +68,11 @@ func (req *RequestGenerator) Erigon(method models.RPCMethod, body string, respon return req.call(models.ErigonUrl, string(method), body, response) } +func (req *RequestGenerator) BlockNumber() string { + const template = `{"jsonrpc":"2.0","method":%q,"id":%d}` + return fmt.Sprintf(template, models.ETHBlockNumber, req.reqID) +} + func (req *RequestGenerator) GetAdminNodeInfo() string { const template = `{"jsonrpc":"2.0","method":%q,"id":%d}` return fmt.Sprintf(template, models.AdminNodeInfo, req.reqID) diff --git a/cmd/devnet/requests/tx.go b/cmd/devnet/requests/tx.go index 407b9b3e9c6..bc254af58d1 100644 --- a/cmd/devnet/requests/tx.go +++ b/cmd/devnet/requests/tx.go @@ -3,37 +3,49 @@ package requests import ( "fmt" - "github.com/ledgerwatch/erigon/cmd/devnet/devnetutils" "github.com/ledgerwatch/erigon/cmd/rpctest/rpctest" ) -func TxpoolContent(reqId int) (int, int, error) { +func TxpoolContent(reqId int) (int, int, int, error) { var ( b rpctest.EthTxPool pending map[string]interface{} queued map[string]interface{} + baseFee map[string]interface{} ) reqGen := initialiseRequestGenerator(reqId) if res := reqGen.Erigon("txpool_content", reqGen.TxpoolContent(), &b); res.Err != nil { - return len(pending), len(queued), fmt.Errorf("failed to fetch txpool content: %v", res.Err) + return len(pending), len(queued), len(baseFee), fmt.Errorf("failed to fetch txpool content: %v", res.Err) } resp := b.Result.(map[string]interface{}) - s, err := devnetutils.ParseResponse(b) - if err != nil { - return len(pending), len(queued), fmt.Errorf("error parsing resonse: %v", err) - } + pendingLen := 0 + queuedLen := 0 + baseFeeLen := 0 if resp["pending"] != nil { pending = resp["pending"].(map[string]interface{}) + for _, txs := range pending { // iterate over senders + pendingLen += len(txs.(map[string]interface{})) + } } + if resp["queue"] != nil { queued = resp["queue"].(map[string]interface{}) + for _, txs := range queued { + queuedLen += len(txs.(map[string]interface{})) + } + } + + if resp["baseFee"] != nil { + baseFee = resp["baseFee"].(map[string]interface{}) + for _, txs := range baseFee { + baseFeeLen += len(txs.(map[string]interface{})) + } } - fmt.Printf("Txpool content: %v\n", s) - return len(pending), len(queued), nil + return pendingLen, queuedLen, baseFeeLen, nil } diff --git a/cmd/devnet/services/block.go b/cmd/devnet/services/block.go index 18f822d7f4f..103069bdc45 100644 --- a/cmd/devnet/services/block.go +++ b/cmd/devnet/services/block.go @@ -44,6 +44,24 @@ func CreateManyEIP1559TransactionsRefWithBaseFee(addr string, startingNonce *uin return lowerBaseFeeTransactions, higherBaseFeeTransactions, nil } +func CreateManyEIP1559TransactionsRefWithBaseFee2(addr string, startingNonce *uint64) ([]*types.Transaction, []*types.Transaction, error) { + toAddress := libcommon.HexToAddress(addr) + + baseFeePerGas, err := BaseFeeFromBlock() + if err != nil { + return nil, nil, fmt.Errorf("failed BaseFeeFromBlock: %v", err) + } + + fmt.Printf("BaseFeePerGas: %v\n", baseFeePerGas) + + lowerBaseFeeTransactions, higherBaseFeeTransactions, err := signEIP1559TxsLowerAndHigherThanBaseFee2(100, 100, baseFeePerGas, startingNonce, toAddress) + if err != nil { + return nil, nil, fmt.Errorf("failed signEIP1559TxsLowerAndHigherThanBaseFee2: %v", err) + } + + return lowerBaseFeeTransactions, higherBaseFeeTransactions, nil +} + // CreateTransaction creates a transaction depending on the type of transaction being passed func CreateTransaction(txType models.TransactionType, addr string, value, nonce uint64) (*types.Transaction, libcommon.Address, *contracts.Subscription, *bind.TransactOpts, error) { switch txType { @@ -77,14 +95,14 @@ func createNonContractTx(addr string, value, nonce uint64) (*types.Transaction, } func signEIP1559TxsLowerAndHigherThanBaseFee2(amountLower, amountHigher int, baseFeePerGas uint64, nonce *uint64, toAddress libcommon.Address) ([]*types.Transaction, []*types.Transaction, error) { - lowerBaseFeeTransactions, err := signEIP1559TxsLowerThanBaseFee(amountLower, baseFeePerGas, nonce, toAddress) + higherBaseFeeTransactions, err := signEIP1559TxsHigherThanBaseFee(amountHigher, baseFeePerGas, nonce, toAddress) if err != nil { - return nil, nil, fmt.Errorf("failed signEIP1559TxsLowerThanBaseFee: %v", err) + return nil, nil, fmt.Errorf("failed signEIP1559TxsHigherThanBaseFee: %v", err) } - higherBaseFeeTransactions, err := signEIP1559TxsHigherThanBaseFee(amountHigher, baseFeePerGas, nonce, toAddress) + lowerBaseFeeTransactions, err := signEIP1559TxsLowerThanBaseFee(amountLower, baseFeePerGas, nonce, toAddress) if err != nil { - return nil, nil, fmt.Errorf("failed signEIP1559TxsHigherThanBaseFee: %v", err) + return nil, nil, fmt.Errorf("failed signEIP1559TxsLowerThanBaseFee: %v", err) } return lowerBaseFeeTransactions, higherBaseFeeTransactions, nil @@ -122,6 +140,7 @@ func signEIP1559TxsLowerThanBaseFee(n int, baseFeePerGas uint64, nonce *uint64, } signedTransactions = append(signedTransactions, &signedTransaction) + *nonce++ } return signedTransactions, nil @@ -256,7 +275,6 @@ func EmitFallbackEvent(subContract *contracts.Subscription, opts *bind.TransactO if err != nil { return nil, fmt.Errorf("failed to send fallback transaction: %v", err) } - fmt.Printf("Tx submitted, adding tx with hash %q to txpool\n", hash) return hash, nil } @@ -287,7 +305,6 @@ func SendManyTransactions(signedTransactions []*types.Transaction) ([]*libcommon fmt.Printf("failed SendTransaction: %s\n", err) return nil, err } - fmt.Printf("SUCCESS => Tx submitted, adding tx with hash %q to txpool\n", hash) hashes[idx] = hash } diff --git a/cmd/devnet/services/tx.go b/cmd/devnet/services/tx.go index 00a76991e2c..837eb98ec89 100644 --- a/cmd/devnet/services/tx.go +++ b/cmd/devnet/services/tx.go @@ -7,8 +7,8 @@ import ( "github.com/ledgerwatch/erigon/cmd/devnet/requests" ) -func CheckTxPoolContent(expectedPendingSize, expectedQueuedSize int) { - pendingSize, queuedSize, err := requests.TxpoolContent(models.ReqId) +func CheckTxPoolContent(expectedPendingSize, expectedQueuedSize, expectedBaseFeeSize int) { + pendingSize, queuedSize, baseFeeSize, err := requests.TxpoolContent(models.ReqId) if err != nil { fmt.Printf("FAILURE => error getting txpool content: %v\n", err) return @@ -24,5 +24,9 @@ func CheckTxPoolContent(expectedPendingSize, expectedQueuedSize int) { return } - fmt.Printf("SUCCESS => %d transaction(s) in the pending pool and %d transaction(s) in the queued pool\n", pendingSize, queuedSize) + if baseFeeSize != expectedBaseFeeSize { + fmt.Printf("FAILURE => %v\n", fmt.Errorf("expected %d transaction(s) in baseFee pool, got %d", expectedBaseFeeSize, baseFeeSize)) + } + + fmt.Printf("SUCCESS => %d transaction(s) in the pending pool, %d transaction(s) in the queued pool and %d transaction(s) in the baseFee pool\n", pendingSize, queuedSize, baseFeeSize) } diff --git a/cmd/downloader/main.go b/cmd/downloader/main.go index 09cbb2cf2b3..457f480cefd 100644 --- a/cmd/downloader/main.go +++ b/cmd/downloader/main.go @@ -24,7 +24,7 @@ import ( "github.com/ledgerwatch/erigon/p2p/nat" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/turbo/debug" - logging2 "github.com/ledgerwatch/erigon/turbo/logging" + "github.com/ledgerwatch/erigon/turbo/logging" "github.com/ledgerwatch/log/v3" "github.com/pelletier/go-toml/v2" "github.com/spf13/cobra" @@ -45,6 +45,7 @@ var ( torrentVerbosity int downloadRateStr, uploadRateStr string torrentDownloadSlots int + staticPeersStr string torrentPort int torrentMaxPeers int torrentConnsPerFile int @@ -54,7 +55,7 @@ var ( ) func init() { - utils.CobraFlags(rootCmd, debug.Flags, utils.MetricFlags, logging2.Flags) + utils.CobraFlags(rootCmd, debug.Flags, utils.MetricFlags, logging.Flags) withDataDir(rootCmd) @@ -67,6 +68,7 @@ func init() { rootCmd.Flags().IntVar(&torrentMaxPeers, "torrent.maxpeers", utils.TorrentMaxPeersFlag.Value, utils.TorrentMaxPeersFlag.Usage) rootCmd.Flags().IntVar(&torrentConnsPerFile, "torrent.conns.perfile", utils.TorrentConnsPerFileFlag.Value, utils.TorrentConnsPerFileFlag.Usage) rootCmd.Flags().IntVar(&torrentDownloadSlots, "torrent.download.slots", utils.TorrentDownloadSlotsFlag.Value, utils.TorrentDownloadSlotsFlag.Usage) + rootCmd.Flags().StringVar(&staticPeersStr, utils.TorrentStaticPeersFlag.Name, utils.TorrentStaticPeersFlag.Value, utils.TorrentStaticPeersFlag.Usage) rootCmd.Flags().BoolVar(&disableIPV6, "downloader.disable.ipv6", utils.DisableIPV6.Value, utils.DisableIPV6.Usage) rootCmd.Flags().BoolVar(&disableIPV4, "downloader.disable.ipv4", utils.DisableIPV4.Value, utils.DisableIPV6.Usage) @@ -111,7 +113,7 @@ var rootCmd = &cobra.Command{ debug.Exit() }, Run: func(cmd *cobra.Command, args []string) { - _ = logging2.GetLoggerCmd("downloader", cmd) + logging.SetupLoggerCmd("downloader", cmd) if err := Downloader(cmd.Context()); err != nil { if !errors.Is(err, context.Canceled) { log.Error(err.Error()) @@ -141,9 +143,10 @@ func Downloader(ctx context.Context) error { if err != nil { return fmt.Errorf("invalid nat option %s: %w", natSetting, err) } + staticPeers := utils.SplitAndTrim(staticPeersStr) version := "erigon: " + params.VersionWithCommit(params.GitCommit) - cfg, err := downloadercfg2.New(dirs.Snap, version, torrentLogLevel, downloadRate, uploadRate, torrentPort, torrentConnsPerFile, torrentDownloadSlots) + cfg, err := downloadercfg2.New(dirs.Snap, version, torrentLogLevel, downloadRate, uploadRate, torrentPort, torrentConnsPerFile, torrentDownloadSlots, staticPeers) if err != nil { return err } @@ -158,7 +161,7 @@ func Downloader(ctx context.Context) error { } defer d.Close() log.Info("[torrent] Start", "my peerID", fmt.Sprintf("%x", d.Torrent().PeerID())) - go downloader.MainLoop(ctx, d, false) + d.MainLoopInBackground(ctx, false) bittorrentServer, err := downloader.NewGrpcServer(d) if err != nil { diff --git a/cmd/ef-tests-cl/consensus_tests/consensus_tester.go b/cmd/ef-tests-cl/consensus_tests/consensus_tester.go index bf9c1ebb75d..026ebcfa7a2 100644 --- a/cmd/ef-tests-cl/consensus_tests/consensus_tester.go +++ b/cmd/ef-tests-cl/consensus_tests/consensus_tester.go @@ -11,7 +11,7 @@ import ( "golang.org/x/exp/slices" ) -var supportedVersions = []string{"altair", "bellatrix"} +var supportedVersions = []string{"phase0", "altair", "bellatrix", "capella"} type ConsensusTester struct { // parameters @@ -70,7 +70,7 @@ func (c *ConsensusTester) iterateOverTests(dir, p string, depth int) { // Depth 1 means that we are setting the version if depth == 1 { if !slices.Contains(supportedVersions, childName) { - return + continue } c.context.version = stringToClVersion(childName) } @@ -81,12 +81,15 @@ func (c *ConsensusTester) iterateOverTests(dir, p string, depth int) { // depth 3 we find the specific c.context.caseName = childName } + // If we found a non-directory then it is a test folder. if !childDir.IsDir() { // Check if it matches case specified. if *c.pattern != "" && !strings.Contains(p, *c.pattern) { return } + log.Debug("Executing", "name", p) + // If yes execute it. if implemented, err := c.executeTest(p); err != nil { log.Warn("Test Failed", "err", err, "test", p) @@ -94,6 +97,7 @@ func (c *ConsensusTester) iterateOverTests(dir, p string, depth int) { } else if implemented { // Mark it as passed only if the test was actually implemented had no errors were found. c.passed++ + log.Debug("Test passed", "name", p) } return diff --git a/cmd/ef-tests-cl/consensus_tests/fork.go b/cmd/ef-tests-cl/consensus_tests/fork.go new file mode 100644 index 00000000000..05670134dab --- /dev/null +++ b/cmd/ef-tests-cl/consensus_tests/fork.go @@ -0,0 +1,54 @@ +package consensustests + +import ( + "fmt" + "os" + + "github.com/ledgerwatch/erigon/cl/clparams" +) + +func forkTest(context testContext) error { + prevContext := context + prevContext.version-- + preState, err := decodeStateFromFile(prevContext, "pre.ssz_snappy") + if err != nil { + return err + } + postState, err := decodeStateFromFile(context, "post.ssz_snappy") + expectedError := os.IsNotExist(err) + if err != nil && !expectedError { + return err + } + + if preState.Version() == clparams.Phase0Version { + if err := preState.UpgradeToAltair(); err != nil { + return err + } + } else if preState.Version() == clparams.AltairVersion { + if err := preState.UpgradeToBellatrix(); err != nil { + return err + } + } else if preState.Version() == clparams.BellatrixVersion { + if err := preState.UpgradeToCapella(); err != nil { + return err + } + } + if expectedError { + return fmt.Errorf("expected error") + } + root, err := preState.HashSSZ() + if err != nil { + return err + } + expectedRoot, err := postState.HashSSZ() + if err != nil { + return err + } + if root != expectedRoot { + return fmt.Errorf("mismatching state roots") + } + if context.version == clparams.AltairVersion { + return nil + } + return nil +} diff --git a/cmd/ef-tests-cl/consensus_tests/sanity.go b/cmd/ef-tests-cl/consensus_tests/sanity.go index 558fce8e8f6..b0c2642cefc 100644 --- a/cmd/ef-tests-cl/consensus_tests/sanity.go +++ b/cmd/ef-tests-cl/consensus_tests/sanity.go @@ -4,6 +4,7 @@ import ( "fmt" "os" + "github.com/ledgerwatch/erigon/cl/cltypes" "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/transition" ) @@ -12,6 +13,7 @@ func testSanityFunction(context testContext) error { if err != nil { return err } + testState.HashSSZ() var expectedError bool expectedState, err := decodeStateFromFile(context, "post.ssz_snappy") if os.IsNotExist(err) { @@ -25,12 +27,16 @@ func testSanityFunction(context testContext) error { if err != nil { return err } - for _, block := range blocks { + startSlot := testState.Slot() + + var block *cltypes.SignedBeaconBlock + for _, block = range blocks { err = transition.TransitionState(testState, block, true) if err != nil { break } } + // Deal with transition error if expectedError && err == nil { return fmt.Errorf("expected error") @@ -39,9 +45,9 @@ func testSanityFunction(context testContext) error { if expectedError { return nil } - return err + return fmt.Errorf("cannot transition state: %s. slot=%d. start_slot=%d", err, block.Block.Slot, startSlot) } - expectedRoot, err := expectedState.HashSSZ() + finalRoot, err := expectedState.HashSSZ() if err != nil { return err } @@ -49,7 +55,7 @@ func testSanityFunction(context testContext) error { if err != nil { return err } - if haveRoot != expectedRoot { + if haveRoot != finalRoot { return fmt.Errorf("mismatching state roots") } return nil diff --git a/cmd/erigon-cl/core/rawdb/accessors.go b/cmd/erigon-cl/core/rawdb/accessors.go index 5b019710ea9..6cb87c1cf01 100644 --- a/cmd/erigon-cl/core/rawdb/accessors.go +++ b/cmd/erigon-cl/core/rawdb/accessors.go @@ -48,86 +48,6 @@ func ReadBeaconState(tx kv.Getter, slot uint64) (*state.BeaconState, error) { return state, nil } -func WriteLightClientUpdate(tx kv.RwTx, update *cltypes.LightClientUpdate) error { - key := make([]byte, 4) - binary.BigEndian.PutUint32(key, uint32(update.SignatureSlot/8192)) - - encoded, err := update.EncodeSSZ(nil) - if err != nil { - return err - } - return tx.Put(kv.LightClientUpdates, key, encoded) -} - -func WriteLightClientFinalityUpdate(tx kv.RwTx, update *cltypes.LightClientFinalityUpdate) error { - encoded, err := update.EncodeSSZ(nil) - if err != nil { - return err - } - return tx.Put(kv.LightClient, kv.LightClientFinalityUpdate, encoded) -} - -func WriteLightClientOptimisticUpdate(tx kv.RwTx, update *cltypes.LightClientOptimisticUpdate) error { - encoded, err := update.EncodeSSZ(nil) - if err != nil { - return err - } - return tx.Put(kv.LightClient, kv.LightClientOptimisticUpdate, encoded) -} - -func ReadLightClientUpdate(tx kv.RwTx, period uint32) (*cltypes.LightClientUpdate, error) { - key := make([]byte, 4) - binary.BigEndian.PutUint32(key, period) - - encoded, err := tx.GetOne(kv.LightClientUpdates, key) - if err != nil { - return nil, err - } - update := &cltypes.LightClientUpdate{} - if err = update.DecodeSSZ(encoded); err != nil { - return nil, err - } - return update, nil -} - -func ReadLightClientFinalityUpdate(tx kv.Tx) (*cltypes.LightClientFinalityUpdate, error) { - encoded, err := tx.GetOne(kv.LightClient, kv.LightClientFinalityUpdate) - if err != nil { - return nil, err - } - if len(encoded) == 0 { - return nil, nil - } - update := &cltypes.LightClientFinalityUpdate{} - if err = update.DecodeSSZ(encoded); err != nil { - return nil, err - } - return update, nil -} - -func ReadLightClientOptimisticUpdate(tx kv.Tx) (*cltypes.LightClientOptimisticUpdate, error) { - encoded, err := tx.GetOne(kv.LightClient, kv.LightClientOptimisticUpdate) - if err != nil { - return nil, err - } - if len(encoded) == 0 { - return nil, nil - } - update := &cltypes.LightClientOptimisticUpdate{} - if err = update.DecodeSSZ(encoded); err != nil { - return nil, err - } - return update, nil -} - -// Bytes2FromLength convert length to 2 bytes repressentation -func Bytes2FromLength(size int) []byte { - return []byte{ - byte(size>>8) & 0xFF, - byte(size>>0) & 0xFF, - } -} - // LengthBytes2 convert length to 2 bytes repressentation func LengthFromBytes2(buf []byte) int { return int(buf[0])*0x100 + int(buf[1]) diff --git a/cmd/erigon-cl/core/rawdb/accessors_test.go b/cmd/erigon-cl/core/rawdb/accessors_test.go index 860908c3ee9..2b57b3d9901 100644 --- a/cmd/erigon-cl/core/rawdb/accessors_test.go +++ b/cmd/erigon-cl/core/rawdb/accessors_test.go @@ -1,28 +1,15 @@ package rawdb_test import ( - "math/big" "testing" "github.com/ledgerwatch/erigon-lib/kv/memdb" "github.com/ledgerwatch/erigon/cl/cltypes" "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/rawdb" - "github.com/ledgerwatch/erigon/core/types" "github.com/stretchr/testify/require" ) -func TestBytes2(t *testing.T) { - len := 1000 - buf := rawdb.Bytes2FromLength(len) - require.Equal(t, len, rawdb.LengthFromBytes2(buf)) -} - -var emptyBlock = &cltypes.Eth1Block{ - Header: &types.Header{ - BaseFee: big.NewInt(0), - Number: big.NewInt(0), - }, -} +var emptyBlock = &cltypes.Eth1Block{} func TestBeaconBlock(t *testing.T) { _, tx := memdb.NewTestTx(t) diff --git a/cmd/erigon-cl/core/state/accessors.go b/cmd/erigon-cl/core/state/accessors.go index 1f9be6b849c..7d6015c9151 100644 --- a/cmd/erigon-cl/core/state/accessors.go +++ b/cmd/erigon-cl/core/state/accessors.go @@ -2,24 +2,31 @@ package state import ( "encoding/binary" + "errors" "fmt" - "math/bits" + "math" "sort" + "github.com/Giulio2002/bls" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon/cl/clparams" "github.com/ledgerwatch/erigon/cl/cltypes" "github.com/ledgerwatch/erigon/cl/fork" "github.com/ledgerwatch/erigon/cl/utils" + "github.com/ledgerwatch/erigon/core/types" eth2_shuffle "github.com/protolambda/eth2-shuffle" ) const PreAllocatedRewardsAndPenalties = 8192 +var ( + ErrGetBlockRootAtSlotFuture = errors.New("GetBlockRootAtSlot: slot in the future") +) + // GetActiveValidatorsIndices returns the list of validator indices active for the given epoch. func (b *BeaconState) GetActiveValidatorsIndices(epoch uint64) (indicies []uint64) { - if cachedIndicies, ok := b.activeValidatorsCache.Get(epoch); ok { - return cachedIndicies.([]uint64) + if cachedIndicies, ok := b.activeValidatorsCache.Get(epoch); ok && len(cachedIndicies) > 0 { + return cachedIndicies } for i, validator := range b.validators { if !validator.Active(epoch) { @@ -63,7 +70,7 @@ func (b *BeaconState) GetUnslashedParticipatingIndices(flagIndex int, epoch uint return nil, fmt.Errorf("getUnslashedParticipatingIndices: only epoch and previous epoch can be used") } // Iterate over all validators and include the active ones that have flag_index enabled and are not slashed. - for i, validator := range b.Validators() { + for i, validator := range b.validators { if !validator.Active(epoch) || !participation[i].HasFlag(flagIndex) || validator.Slashed { @@ -118,7 +125,7 @@ func (b *BeaconState) GetBlockRoot(epoch uint64) (libcommon.Hash, error) { // GetBlockRootAtSlot returns the block root at a given slot func (b *BeaconState) GetBlockRootAtSlot(slot uint64) (libcommon.Hash, error) { if slot >= b.slot { - return libcommon.Hash{}, fmt.Errorf("GetBlockRootAtSlot: slot in the future") + return libcommon.Hash{}, ErrGetBlockRootAtSlotFuture } if b.slot > slot+b.beaconConfig.SlotsPerHistoricalRoot { return libcommon.Hash{}, fmt.Errorf("GetBlockRootAtSlot: slot too much far behind") @@ -185,7 +192,7 @@ func (b *BeaconState) ComputeCommittee(indicies []uint64, seed libcommon.Hash, i end := (lenIndicies * (index + 1)) / count var shuffledIndicies []uint64 if shuffledIndicesInterface, ok := b.shuffledSetsCache.Get(seed); ok { - shuffledIndicies = shuffledIndicesInterface.([]uint64) + shuffledIndicies = shuffledIndicesInterface } else { shuffledIndicies = make([]uint64, lenIndicies) copy(shuffledIndicies, indicies) @@ -221,11 +228,11 @@ func (b *BeaconState) ComputeProposerIndex(indices []uint64, seed [32]byte) (uin input := append(seed[:], buf...) randomByte := uint64(utils.Keccak256(input)[i%32]) - validator, err := b.ValidatorAt(int(candidateIndex)) + validator, err := b.ValidatorForValidatorIndex(int(candidateIndex)) if err != nil { return 0, err } - if validator.EffectiveBalance*maxRandomByte >= clparams.MainnetBeaconConfig.MaxEffectiveBalance*randomByte { + if validator.EffectiveBalance*maxRandomByte >= b.beaconConfig.MaxEffectiveBalance*randomByte { return candidateIndex, nil } i += 1 @@ -267,7 +274,13 @@ func (b *BeaconState) BaseReward(index uint64) (uint64, error) { if index >= uint64(len(b.validators)) { return 0, ErrInvalidValidatorIndex } - return (b.validators[index].EffectiveBalance / b.beaconConfig.EffectiveBalanceIncrement) * b.BaseRewardPerIncrement(), nil + if b.totalActiveBalanceCache == nil { + b._refreshActiveBalances() + } + if b.version != clparams.Phase0Version { + return (b.validators[index].EffectiveBalance / b.beaconConfig.EffectiveBalanceIncrement) * b.BaseRewardPerIncrement(), nil + } + return b.validators[index].EffectiveBalance * b.beaconConfig.BaseRewardFactor / b.totalActiveBalanceRootCache / b.beaconConfig.BaseRewardsPerEpoch, nil } // SyncRewards returns the proposer reward and the sync participant reward given the total active balance in state. @@ -352,7 +365,7 @@ func (b *BeaconState) GetBeaconCommitee(slot, committeeIndex uint64) ([]uint64, binary.BigEndian.PutUint64(cacheKey[:], slot) binary.BigEndian.PutUint64(cacheKey[8:], committeeIndex) if cachedCommittee, ok := b.committeeCache.Get(cacheKey); ok { - return cachedCommittee.([]uint64), nil + return cachedCommittee, nil } epoch := b.GetEpochAtSlot(slot) committeesPerSlot := b.CommitteeCount(epoch) @@ -384,33 +397,16 @@ func (b *BeaconState) GetIndexedAttestation(attestation *cltypes.Attestation, at }, nil } -// getBitlistLength return the amount of bits in given bitlist. -func getBitlistLength(b []byte) int { - if len(b) == 0 { - return 0 - } - // The most significant bit is present in the last byte in the array. - last := b[len(b)-1] - - // Determine the position of the most significant bit. - msb := bits.Len8(last) - if msb == 0 { - return 0 - } - - // The absolute position of the most significant bit will be the number of - // bits in the preceding bytes plus the position of the most significant - // bit. Subtract this value by 1 to determine the length of the bitlist. - return 8*(len(b)-1) + msb - 1 -} - -func (b *BeaconState) GetAttestingIndicies(attestation *cltypes.AttestationData, aggregationBits []byte) ([]uint64, error) { +// GetAttestingIndicies retrieves attesting indicies for a specific attestation. however some tests will not expect the aggregation bits check. +// thus, it is a flag now. +func (b *BeaconState) GetAttestingIndicies(attestation *cltypes.AttestationData, aggregationBits []byte, checkBitsLength bool) ([]uint64, error) { committee, err := b.GetBeaconCommitee(attestation.Slot, attestation.Index) if err != nil { return nil, err } - if getBitlistLength(aggregationBits) != len(committee) { - return nil, fmt.Errorf("GetAttestingIndicies: invalid aggregation bits") + aggregationBitsLen := utils.GetBitlistLength(aggregationBits) + if checkBitsLength && utils.GetBitlistLength(aggregationBits) != len(committee) { + return nil, fmt.Errorf("GetAttestingIndicies: invalid aggregation bits. agg bits size: %d, expect: %d", aggregationBitsLen, len(committee)) } attestingIndices := []uint64{} for i, member := range committee { @@ -439,9 +435,14 @@ func (b *BeaconState) EligibleValidatorsIndicies() (eligibleValidators []uint64) return } +// FinalityDelay determines by how many epochs we are late on finality. +func (b *BeaconState) FinalityDelay() uint64 { + return b.PreviousEpoch() - b.finalizedCheckpoint.Epoch +} + // Implementation of is_in_inactivity_leak. tells us if network is in danger pretty much. defined in ETH 2.0 specs. func (b *BeaconState) InactivityLeaking() bool { - return (b.PreviousEpoch() - b.finalizedCheckpoint.Epoch) > b.beaconConfig.MinEpochsToInactivityPenalty + return b.FinalityDelay() > b.beaconConfig.MinEpochsToInactivityPenalty } func (b *BeaconState) IsUnslashedParticipatingIndex(epoch, index uint64, flagIdx int) bool { @@ -462,21 +463,166 @@ func (b *BeaconState) IsValidatorEligibleForActivation(validator *cltypes.Valida validator.ActivationEpoch == b.beaconConfig.FarFutureEpoch } -// Implementation of get_validator_churn_limit. Specs at: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#get_validator_churn_limit -func (b *BeaconState) ValidatorChurnLimit() (limit uint64) { +// Get the maximum number of validators that can be churned in a single epoch. +// See: https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#get_validator_churn_limit +func (b *BeaconState) ValidatorChurnLimit() uint64 { activeValidatorsCount := uint64(len(b.GetActiveValidatorsIndices(b.Epoch()))) - limit = activeValidatorsCount / b.beaconConfig.ChurnLimitQuotient - if limit < b.beaconConfig.MinPerEpochChurnLimit { - limit = b.beaconConfig.MinPerEpochChurnLimit - } - return - + churnLimit := activeValidatorsCount / b.beaconConfig.ChurnLimitQuotient + return utils.Max64(b.beaconConfig.MinPerEpochChurnLimit, churnLimit) } +// Check whether a merge transition is complete by verifying the presence of a valid execution payload header. func (b *BeaconState) IsMergeTransitionComplete() bool { - return b.latestExecutionPayloadHeader.Root != libcommon.Hash{} + return !b.latestExecutionPayloadHeader.IsZero() } +// Compute the Unix timestamp at the specified slot number. func (b *BeaconState) ComputeTimestampAtSlot(slot uint64) uint64 { return b.genesisTime + (slot-b.beaconConfig.GenesisSlot)*b.beaconConfig.SecondsPerSlot } + +// Check whether a validator is fully withdrawable at the given epoch. +func (b *BeaconState) isFullyWithdrawableValidator(validator *cltypes.Validator, balance uint64, epoch uint64) bool { + return validator.WithdrawalCredentials[0] == b.beaconConfig.ETH1AddressWithdrawalPrefixByte && + validator.WithdrawableEpoch <= epoch && balance > 0 +} + +// Check whether a validator is partially withdrawable. +func (b *BeaconState) isPartiallyWithdrawableValidator(validator *cltypes.Validator, balance uint64) bool { + return validator.WithdrawalCredentials[0] == b.beaconConfig.ETH1AddressWithdrawalPrefixByte && + validator.EffectiveBalance == b.beaconConfig.MaxEffectiveBalance && balance > b.beaconConfig.MaxEffectiveBalance +} + +// ExpectedWithdrawals calculates the expected withdrawals that can be made by validators in the current epoch +func (b *BeaconState) ExpectedWithdrawals() []*types.Withdrawal { + // Get the current epoch, the next withdrawal index, and the next withdrawal validator index + currentEpoch := b.Epoch() + nextWithdrawalIndex := b.nextWithdrawalIndex + nextWithdrawalValidatorIndex := b.nextWithdrawalValidatorIndex + + // Determine the upper bound for the loop and initialize the withdrawals slice with a capacity of bound + maxValidators := uint64(len(b.validators)) + maxValidatorsPerWithdrawalsSweep := b.beaconConfig.MaxValidatorsPerWithdrawalsSweep + bound := utils.Min64(maxValidators, maxValidatorsPerWithdrawalsSweep) + withdrawals := make([]*types.Withdrawal, 0, bound) + + // Loop through the validators to calculate expected withdrawals + for validatorCount := uint64(0); validatorCount < bound && len(withdrawals) != int(b.beaconConfig.MaxWithdrawalsPerPayload); validatorCount++ { + // Get the validator and balance for the current validator index + currentValidator := b.validators[nextWithdrawalValidatorIndex] + currentBalance := b.balances[nextWithdrawalValidatorIndex] + + // Check if the validator is fully withdrawable + if b.isFullyWithdrawableValidator(currentValidator, currentBalance, currentEpoch) { + // Add a new withdrawal with the validator's withdrawal credentials and balance + newWithdrawal := &types.Withdrawal{ + Index: nextWithdrawalIndex, + Validator: nextWithdrawalValidatorIndex, + Address: libcommon.BytesToAddress(currentValidator.WithdrawalCredentials[12:]), + Amount: currentBalance, + } + withdrawals = append(withdrawals, newWithdrawal) + nextWithdrawalIndex++ + } else if b.isPartiallyWithdrawableValidator(currentValidator, currentBalance) { // Check if the validator is partially withdrawable + // Add a new withdrawal with the validator's withdrawal credentials and balance minus the maximum effective balance + newWithdrawal := &types.Withdrawal{ + Index: nextWithdrawalIndex, + Validator: nextWithdrawalValidatorIndex, + Address: libcommon.BytesToAddress(currentValidator.WithdrawalCredentials[12:]), + Amount: currentBalance - b.beaconConfig.MaxEffectiveBalance, + } + withdrawals = append(withdrawals, newWithdrawal) + nextWithdrawalIndex++ + } + + // Increment the validator index, looping back to 0 if necessary + nextWithdrawalValidatorIndex = (nextWithdrawalValidatorIndex + 1) % maxValidators + } + + // Return the withdrawals slice + return withdrawals +} +func (b *BeaconState) ComputeNextSyncCommittee() (*cltypes.SyncCommittee, error) { + beaconConfig := b.beaconConfig + optimizedHashFunc := utils.OptimizedKeccak256() + epoch := b.Epoch() + 1 + //math.MaxUint8 + activeValidatorIndicies := b.GetActiveValidatorsIndices(epoch) + activeValidatorCount := uint64(len(activeValidatorIndicies)) + seed := b.GetSeed(epoch, beaconConfig.DomainSyncCommittee) + i := uint64(0) + syncCommitteePubKeys := make([][48]byte, 0, cltypes.SyncCommitteeSize) + preInputs := b.ComputeShuffledIndexPreInputs(seed) + for len(syncCommitteePubKeys) < cltypes.SyncCommitteeSize { + shuffledIndex, err := b.ComputeShuffledIndex(i%activeValidatorCount, activeValidatorCount, seed, preInputs, optimizedHashFunc) + if err != nil { + return nil, err + } + candidateIndex := activeValidatorIndicies[shuffledIndex] + // Compute random byte. + buf := make([]byte, 8) + binary.LittleEndian.PutUint64(buf, i/32) + input := append(seed[:], buf...) + randomByte := uint64(utils.Keccak256(input)[i%32]) + // retrieve validator. + validator, err := b.ValidatorForValidatorIndex(int(candidateIndex)) + if err != nil { + return nil, err + } + if validator.EffectiveBalance*math.MaxUint8 >= beaconConfig.MaxEffectiveBalance*randomByte { + syncCommitteePubKeys = append(syncCommitteePubKeys, validator.PublicKey) + } + i++ + } + // Format public keys. + formattedKeys := make([][]byte, cltypes.SyncCommitteeSize) + for i := range formattedKeys { + formattedKeys[i] = make([]byte, 48) + copy(formattedKeys[i], syncCommitteePubKeys[i][:]) + } + aggregatePublicKeyBytes, err := bls.AggregatePublickKeys(formattedKeys) + if err != nil { + return nil, err + } + var aggregate [48]byte + copy(aggregate[:], aggregatePublicKeyBytes) + return &cltypes.SyncCommittee{ + PubKeys: syncCommitteePubKeys, + AggregatePublicKey: aggregate, + }, nil +} + +func (b *BeaconState) IsValidIndexedAttestation(att *cltypes.IndexedAttestation) (bool, error) { + inds := att.AttestingIndices + if len(inds) == 0 || !utils.IsSliceSortedSet(inds) { + return false, fmt.Errorf("isValidIndexedAttestation: attesting indices are not sorted or are null") + } + + pks := [][]byte{} + for _, v := range inds { + val, err := b.ValidatorForValidatorIndex(int(v)) + if err != nil { + return false, err + } + pks = append(pks, val.PublicKey[:]) + } + + domain, err := b.GetDomain(b.beaconConfig.DomainBeaconAttester, att.Data.Target.Epoch) + if err != nil { + return false, fmt.Errorf("unable to get the domain: %v", err) + } + + signingRoot, err := fork.ComputeSigningRoot(att.Data, domain) + if err != nil { + return false, fmt.Errorf("unable to get signing root: %v", err) + } + + valid, err := bls.VerifyAggregate(att.Signature[:], signingRoot[:], pks) + if err != nil { + return false, fmt.Errorf("error while validating signature: %v", err) + } + if !valid { + return false, fmt.Errorf("invalid aggregate signature") + } + return true, nil +} diff --git a/cmd/erigon-cl/core/state/mutators.go b/cmd/erigon-cl/core/state/mutators.go index bf0a933cc37..184bba5a2a8 100644 --- a/cmd/erigon-cl/core/state/mutators.go +++ b/cmd/erigon-cl/core/state/mutators.go @@ -60,12 +60,13 @@ func (b *BeaconState) InitiateValidatorExit(index uint64) error { exitQueueEpoch += 1 } - b.validators[index].ExitEpoch = exitQueueEpoch var overflow bool - if b.validators[index].WithdrawableEpoch, overflow = math.SafeAdd(b.validators[index].ExitEpoch, b.beaconConfig.MinValidatorWithdrawabilityDelay); overflow { + var newWithdrawableEpoch uint64 + if newWithdrawableEpoch, overflow = math.SafeAdd(exitQueueEpoch, b.beaconConfig.MinValidatorWithdrawabilityDelay); overflow { return fmt.Errorf("withdrawable epoch is too big") } - b.touchedLeaves[ValidatorsLeafIndex] = true + b.SetExitEpochForValidatorAtIndex(int(index), exitQueueEpoch) + b.SetWithdrawableEpochForValidatorAtIndex(int(index), newWithdrawableEpoch) return nil } @@ -81,12 +82,15 @@ func (b *BeaconState) SlashValidator(slashedInd uint64, whistleblowerInd *uint64 if err := b.InitiateValidatorExit(slashedInd); err != nil { return err } + // Record changes in changeset + slashingsIndex := int(epoch % b.beaconConfig.EpochsPerSlashingsVector) + // Change the validator to be slashed b.validators[slashedInd].Slashed = true b.validators[slashedInd].WithdrawableEpoch = utils.Max64(b.validators[slashedInd].WithdrawableEpoch, epoch+b.beaconConfig.EpochsPerSlashingsVector) b.touchedLeaves[ValidatorsLeafIndex] = true // Update slashings vector - b.slashings[epoch%b.beaconConfig.EpochsPerSlashingsVector] += b.validators[slashedInd].EffectiveBalance + b.slashings[slashingsIndex] += b.validators[slashedInd].EffectiveBalance b.touchedLeaves[SlashingsLeafIndex] = true if err := b.DecreaseBalance(slashedInd, b.validators[slashedInd].EffectiveBalance/b.beaconConfig.GetMinSlashingPenaltyQuotient(b.version)); err != nil { return err diff --git a/cmd/erigon-cl/core/state/root.go b/cmd/erigon-cl/core/state/root.go index 2f979cb4818..929d35f985d 100644 --- a/cmd/erigon-cl/core/state/root.go +++ b/cmd/erigon-cl/core/state/root.go @@ -14,6 +14,10 @@ func (b *BeaconState) HashSSZ() ([32]byte, error) { if err = b.computeDirtyLeaves(); err != nil { return [32]byte{}, err } + /*fmt.Println(b.slot) + for i, val := range b.leaves { + fmt.Println(i, libcommon.Hash(val)) + }*/ // Pad to 32 of length return merkle_tree.MerkleRootFromLeaves(b.leaves[:]) diff --git a/cmd/erigon-cl/core/state/setters.go b/cmd/erigon-cl/core/state/setters.go index 532c1bbfeb1..25d16d5e164 100644 --- a/cmd/erigon-cl/core/state/setters.go +++ b/cmd/erigon-cl/core/state/setters.go @@ -4,27 +4,19 @@ import ( libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/core/types" ) const maxEth1Votes = 2048 // Below are setters. Note that they also dirty the state. -func (b *BeaconState) SetGenesisTime(genesisTime uint64) { - b.touchedLeaves[GenesisTimeLeafIndex] = true - b.genesisTime = genesisTime -} - -func (b *BeaconState) SetGenesisValidatorsRoot(genesisValidatorRoot libcommon.Hash) { - b.touchedLeaves[GenesisValidatorsRootLeafIndex] = true - b.genesisValidatorsRoot = genesisValidatorRoot -} - func (b *BeaconState) SetSlot(slot uint64) { b.touchedLeaves[SlotLeafIndex] = true b.slot = slot b.proposerIndex = nil + if b.slot%b.beaconConfig.SlotsPerEpoch == 0 { + b.totalActiveBalanceCache = nil + } } func (b *BeaconState) SetFork(fork *cltypes.Fork) { @@ -37,11 +29,6 @@ func (b *BeaconState) SetLatestBlockHeader(header *cltypes.BeaconBlockHeader) { b.latestBlockHeader = header } -func (b *BeaconState) SetHistoricalRoots(historicalRoots []libcommon.Hash) { - b.touchedLeaves[HistoricalRootsLeafIndex] = true - b.historicalRoots = historicalRoots -} - func (b *BeaconState) SetBlockRootAt(index int, root libcommon.Hash) { b.touchedLeaves[BlockRootsLeafIndex] = true b.blockRoots[index] = root @@ -57,15 +44,34 @@ func (b *BeaconState) SetHistoricalRootAt(index int, root [32]byte) { b.historicalRoots[index] = root } -func (b *BeaconState) SetValidatorAt(index int, validator *cltypes.Validator) error { - if index >= len(b.validators) { - return ErrInvalidValidatorIndex - } - b.validators[index] = validator +func (b *BeaconState) SetWithdrawalCredentialForValidatorAtIndex(index int, creds libcommon.Hash) { b.touchedLeaves[ValidatorsLeafIndex] = true - // change in validator set means cache purging - b.totalActiveBalanceCache = nil - return nil + b.validators[index].WithdrawalCredentials = creds +} + +func (b *BeaconState) SetExitEpochForValidatorAtIndex(index int, epoch uint64) { + b.touchedLeaves[ValidatorsLeafIndex] = true + b.validators[index].ExitEpoch = epoch +} + +func (b *BeaconState) SetWithdrawableEpochForValidatorAtIndex(index int, epoch uint64) { + b.touchedLeaves[ValidatorsLeafIndex] = true + b.validators[index].WithdrawableEpoch = epoch +} + +func (b *BeaconState) SetEffectiveBalanceForValidatorAtIndex(index int, balance uint64) { + b.touchedLeaves[ValidatorsLeafIndex] = true + b.validators[index].EffectiveBalance = balance +} + +func (b *BeaconState) SetActivationEpochForValidatorAtIndex(index int, epoch uint64) { + b.touchedLeaves[ValidatorsLeafIndex] = true + b.validators[index].ActivationEpoch = epoch +} + +func (b *BeaconState) SetActivationEligibilityEpochForValidatorAtIndex(index int, epoch uint64) { + b.touchedLeaves[ValidatorsLeafIndex] = true + b.validators[index].ActivationEligibilityEpoch = epoch } func (b *BeaconState) SetEth1Data(eth1Data *cltypes.Eth1Data) { @@ -80,7 +86,7 @@ func (b *BeaconState) AddEth1DataVote(vote *cltypes.Eth1Data) { func (b *BeaconState) ResetEth1DataVotes() { b.touchedLeaves[Eth1DataVotesLeafIndex] = true - b.eth1DataVotes = b.eth1DataVotes[:0] + b.eth1DataVotes = nil } func (b *BeaconState) SetEth1DepositIndex(eth1DepositIndex uint64) { @@ -131,14 +137,26 @@ func (b *BeaconState) SetSlashingSegmentAt(index int, segment uint64) { b.slashings[index] = segment } -func (b *BeaconState) SetPreviousEpochParticipation(previousEpochParticipation []cltypes.ParticipationFlags) { +func (b *BeaconState) SetEpochParticipationForValidatorIndex(isCurrentEpoch bool, index int, flags cltypes.ParticipationFlags) { + if isCurrentEpoch { + b.touchedLeaves[CurrentEpochParticipationLeafIndex] = true + b.currentEpochParticipation[index] = flags + return + } b.touchedLeaves[PreviousEpochParticipationLeafIndex] = true - b.previousEpochParticipation = previousEpochParticipation + b.previousEpochParticipation[index] = flags } -func (b *BeaconState) SetCurrentEpochParticipation(currentEpochParticipation []cltypes.ParticipationFlags) { +func (b *BeaconState) SetValidatorAtIndex(index int, validator *cltypes.Validator) { + b.touchedLeaves[ValidatorsLeafIndex] = true + b.validators[index] = validator +} + +func (b *BeaconState) ResetEpochParticipation() { + b.touchedLeaves[PreviousEpochParticipationLeafIndex] = true b.touchedLeaves[CurrentEpochParticipationLeafIndex] = true - b.currentEpochParticipation = currentEpochParticipation + b.previousEpochParticipation = b.currentEpochParticipation + b.currentEpochParticipation = make(cltypes.ParticipationFlagsList, len(b.validators)) } func (b *BeaconState) SetJustificationBits(justificationBits cltypes.JustificationBits) { @@ -171,7 +189,7 @@ func (b *BeaconState) SetNextSyncCommittee(nextSyncCommittee *cltypes.SyncCommit b.nextSyncCommittee = nextSyncCommittee } -func (b *BeaconState) SetLatestExecutionPayloadHeader(header *types.Header) { +func (b *BeaconState) SetLatestExecutionPayloadHeader(header *cltypes.Eth1Header) { b.touchedLeaves[LatestExecutionPayloadHeaderLeafIndex] = true b.latestExecutionPayloadHeader = header } @@ -187,7 +205,7 @@ func (b *BeaconState) SetNextWithdrawalValidatorIndex(index uint64) { } func (b *BeaconState) AddHistoricalSummary(summary *cltypes.HistoricalSummary) { - b.touchedLeaves[HistoricalRootsLeafIndex] = true + b.touchedLeaves[HistoricalSummariesLeafIndex] = true b.historicalSummaries = append(b.historicalSummaries, summary) } @@ -219,3 +237,23 @@ func (b *BeaconState) AddPreviousEpochParticipationFlags(flags cltypes.Participa b.touchedLeaves[PreviousEpochParticipationLeafIndex] = true b.previousEpochParticipation = append(b.previousEpochParticipation, flags) } + +func (b *BeaconState) AddCurrentEpochAtteastation(attestation *cltypes.PendingAttestation) { + b.touchedLeaves[CurrentEpochParticipationLeafIndex] = true + b.currentEpochAttestations = append(b.currentEpochAttestations, attestation) +} + +func (b *BeaconState) AddPreviousEpochAttestation(attestation *cltypes.PendingAttestation) { + b.touchedLeaves[PreviousEpochParticipationLeafIndex] = true + b.previousEpochAttestations = append(b.previousEpochAttestations, attestation) +} + +func (b *BeaconState) ResetCurrentEpochAttestations() { + b.touchedLeaves[CurrentEpochParticipationLeafIndex] = true + b.currentEpochAttestations = nil +} + +func (b *BeaconState) SetPreviousEpochAttestations(attestations []*cltypes.PendingAttestation) { + b.touchedLeaves[PreviousEpochParticipationLeafIndex] = true + b.previousEpochAttestations = attestations +} diff --git a/cmd/erigon-cl/core/state/state.go b/cmd/erigon-cl/core/state/state.go index d8930609edc..74c8f44abc2 100644 --- a/cmd/erigon-cl/core/state/state.go +++ b/cmd/erigon-cl/core/state/state.go @@ -4,13 +4,13 @@ import ( "crypto/sha256" "encoding/binary" - lru "github.com/hashicorp/golang-lru" + lru "github.com/hashicorp/golang-lru/v2" + "github.com/ledgerwatch/erigon-lib/common" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon/cl/clparams" "github.com/ledgerwatch/erigon/cl/cltypes" "github.com/ledgerwatch/erigon/cl/utils" - "github.com/ledgerwatch/erigon/core/types" ) type HashFunc func([]byte) ([32]byte, error) @@ -25,19 +25,19 @@ const ( type BeaconState struct { // State fields genesisTime uint64 - genesisValidatorsRoot libcommon.Hash + genesisValidatorsRoot common.Hash slot uint64 fork *cltypes.Fork latestBlockHeader *cltypes.BeaconBlockHeader - blockRoots [blockRootsLength]libcommon.Hash - stateRoots [stateRootsLength]libcommon.Hash - historicalRoots []libcommon.Hash + blockRoots [blockRootsLength]common.Hash + stateRoots [stateRootsLength]common.Hash + historicalRoots []common.Hash eth1Data *cltypes.Eth1Data eth1DataVotes []*cltypes.Eth1Data eth1DepositIndex uint64 validators []*cltypes.Validator balances []uint64 - randaoMixes [randoMixesLength]libcommon.Hash + randaoMixes [randoMixesLength]common.Hash slashings [slashingsLength]uint64 previousEpochParticipation cltypes.ParticipationFlagsList currentEpochParticipation cltypes.ParticipationFlagsList @@ -50,24 +50,27 @@ type BeaconState struct { currentSyncCommittee *cltypes.SyncCommittee nextSyncCommittee *cltypes.SyncCommittee // Bellatrix - latestExecutionPayloadHeader *types.Header + latestExecutionPayloadHeader *cltypes.Eth1Header // Capella nextWithdrawalIndex uint64 nextWithdrawalValidatorIndex uint64 historicalSummaries []*cltypes.HistoricalSummary + // Phase0: genesis fork. these 2 fields replace participation bits. + previousEpochAttestations []*cltypes.PendingAttestation + currentEpochAttestations []*cltypes.PendingAttestation // Internals version clparams.StateVersion // State version leaves [32][32]byte // Pre-computed leaves. touchedLeaves map[StateLeafIndex]bool // Maps each leaf to whether they were touched or not. publicKeyIndicies map[[48]byte]uint64 // Caches - activeValidatorsCache *lru.Cache - committeeCache *lru.Cache - shuffledSetsCache *lru.Cache + activeValidatorsCache *lru.Cache[uint64, []uint64] + committeeCache *lru.Cache[[16]byte, []uint64] + shuffledSetsCache *lru.Cache[common.Hash, []uint64] totalActiveBalanceCache *uint64 totalActiveBalanceRootCache uint64 proposerIndex *uint64 - previousStateRoot libcommon.Hash + previousStateRoot common.Hash // Configs beaconConfig *clparams.BeaconChainConfig } @@ -80,7 +83,7 @@ func New(cfg *clparams.BeaconChainConfig) *BeaconState { return state } -func preparateRootsForHashing(roots []libcommon.Hash) [][32]byte { +func preparateRootsForHashing(roots []common.Hash) [][32]byte { ret := make([][32]byte, len(roots)) for i := range roots { copy(ret[i][:], roots[i][:]) @@ -126,7 +129,7 @@ func (b *BeaconState) _updateProposerIndex() (err error) { hash := sha256.New() // Input for the seed hash. - input := b.GetSeed(epoch, clparams.MainnetBeaconConfig.DomainBeaconProposer) + input := b.GetSeed(epoch, b.BeaconConfig().DomainBeaconProposer) slotByteArray := make([]byte, 8) binary.LittleEndian.PutUint64(slotByteArray, b.slot) @@ -147,27 +150,205 @@ func (b *BeaconState) _updateProposerIndex() (err error) { return } +// _initializeValidatorsPhase0 initializes the validators matching flags based on previous/current attestations +func (b *BeaconState) _initializeValidatorsPhase0() error { + // Previous Pending attestations + if b.slot == 0 { + return nil + } + previousEpochRoot, err := b.GetBlockRoot(b.PreviousEpoch()) + if err != nil { + return err + } + for _, attestation := range b.previousEpochAttestations { + slotRoot, err := b.GetBlockRootAtSlot(attestation.Data.Slot) + if err != nil { + return err + } + indicies, err := b.GetAttestingIndicies(attestation.Data, attestation.AggregationBits, false) + if err != nil { + return err + } + for _, index := range indicies { + if b.validators[index].MinPreviousInclusionDelayAttestation == nil || b.validators[index].MinPreviousInclusionDelayAttestation.InclusionDelay > attestation.InclusionDelay { + b.validators[index].MinPreviousInclusionDelayAttestation = attestation + } + b.validators[index].IsPreviousMatchingSourceAttester = true + if attestation.Data.Target.Root != previousEpochRoot { + continue + } + b.validators[index].IsPreviousMatchingTargetAttester = true + + if attestation.Data.BeaconBlockHash == slotRoot { + b.validators[index].IsPreviousMatchingHeadAttester = true + } + } + } + + // Current Pending attestations + if len(b.currentEpochAttestations) == 0 { + return nil + } + currentEpochRoot, err := b.GetBlockRoot(b.Epoch()) + if err != nil { + return err + } + for _, attestation := range b.currentEpochAttestations { + slotRoot, err := b.GetBlockRootAtSlot(attestation.Data.Slot) + if err != nil { + return err + } + if err != nil { + return err + } + indicies, err := b.GetAttestingIndicies(attestation.Data, attestation.AggregationBits, false) + if err != nil { + return err + } + for _, index := range indicies { + if b.validators[index].MinCurrentInclusionDelayAttestation == nil || b.validators[index].MinCurrentInclusionDelayAttestation.InclusionDelay > attestation.InclusionDelay { + b.validators[index].MinCurrentInclusionDelayAttestation = attestation + } + b.validators[index].IsCurrentMatchingSourceAttester = true + if attestation.Data.Target.Root == currentEpochRoot { + b.validators[index].IsCurrentMatchingTargetAttester = true + } + if attestation.Data.BeaconBlockHash == slotRoot { + b.validators[index].IsCurrentMatchingHeadAttester = true + } + } + } + return nil +} + +func (b *BeaconState) initCaches() error { + var err error + if b.activeValidatorsCache, err = lru.New[uint64, []uint64](5); err != nil { + return err + } + if b.shuffledSetsCache, err = lru.New[common.Hash, []uint64](5); err != nil { + return err + } + if b.committeeCache, err = lru.New[[16]byte, []uint64](256); err != nil { + return err + } + return nil +} + func (b *BeaconState) initBeaconState() error { + if b.touchedLeaves == nil { b.touchedLeaves = make(map[StateLeafIndex]bool) } + b.publicKeyIndicies = make(map[[48]byte]uint64) b._refreshActiveBalances() for i, validator := range b.validators { b.publicKeyIndicies[validator.PublicKey] = uint64(i) } - var err error - if b.activeValidatorsCache, err = lru.New(5); err != nil { + b.initCaches() + if err := b._updateProposerIndex(); err != nil { return err } - if b.shuffledSetsCache, err = lru.New(25); err != nil { - return err + if b.version >= clparams.Phase0Version { + return b._initializeValidatorsPhase0() } - if b.committeeCache, err = lru.New(256); err != nil { - return err + return nil +} + +func (b *BeaconState) Copy() (*BeaconState, error) { + copied := New(b.beaconConfig) + // Fill all the fields with copies + copied.genesisTime = b.genesisTime + copied.genesisValidatorsRoot = b.genesisValidatorsRoot + copied.slot = b.slot + copied.fork = b.fork.Copy() + copied.latestBlockHeader = b.latestBlockHeader.Copy() + copy(copied.blockRoots[:], b.blockRoots[:]) + copy(copied.stateRoots[:], b.stateRoots[:]) + copied.historicalRoots = make([]libcommon.Hash, len(b.historicalRoots)) + copy(copied.historicalRoots, b.historicalRoots) + copied.eth1Data = b.eth1Data.Copy() + copied.eth1DataVotes = make([]*cltypes.Eth1Data, len(b.eth1DataVotes)) + for i := range b.eth1DataVotes { + copied.eth1DataVotes[i] = b.eth1DataVotes[i].Copy() } - if err := b._updateProposerIndex(); err != nil { - return err + copied.eth1DepositIndex = b.eth1DepositIndex + copied.validators = make([]*cltypes.Validator, len(b.validators)) + for i := range b.validators { + copied.validators[i] = b.validators[i].Copy() } - return nil + copied.balances = make([]uint64, len(b.balances)) + copy(copied.balances, b.balances) + copy(copied.randaoMixes[:], b.randaoMixes[:]) + copy(copied.slashings[:], b.slashings[:]) + copied.previousEpochParticipation = b.previousEpochParticipation.Copy() + copied.currentEpochParticipation = b.currentEpochParticipation.Copy() + copied.finalizedCheckpoint = b.finalizedCheckpoint.Copy() + copied.currentJustifiedCheckpoint = b.currentJustifiedCheckpoint.Copy() + copied.previousJustifiedCheckpoint = b.previousJustifiedCheckpoint.Copy() + if b.version == clparams.Phase0Version { + return copied, copied.initBeaconState() + } + copied.currentSyncCommittee = b.currentSyncCommittee.Copy() + copied.nextSyncCommittee = b.nextSyncCommittee.Copy() + copied.inactivityScores = make([]uint64, len(b.inactivityScores)) + copy(copied.inactivityScores, b.inactivityScores) + copied.justificationBits = b.justificationBits.Copy() + + if b.version >= clparams.BellatrixVersion { + copied.latestExecutionPayloadHeader = b.latestExecutionPayloadHeader.Copy() + } + copied.nextWithdrawalIndex = b.nextWithdrawalIndex + copied.nextWithdrawalValidatorIndex = b.nextWithdrawalValidatorIndex + copied.historicalSummaries = make([]*cltypes.HistoricalSummary, len(b.historicalSummaries)) + for i := range b.historicalSummaries { + copied.historicalSummaries[i] = &cltypes.HistoricalSummary{ + BlockSummaryRoot: b.historicalSummaries[i].BlockSummaryRoot, + StateSummaryRoot: b.historicalSummaries[i].StateSummaryRoot, + } + } + copied.version = b.version + // Now sync internals + copy(copied.leaves[:], b.leaves[:]) + copied.touchedLeaves = make(map[StateLeafIndex]bool) + for leafIndex, touchedVal := range b.touchedLeaves { + copied.touchedLeaves[leafIndex] = touchedVal + } + copied.publicKeyIndicies = make(map[[48]byte]uint64) + for pk, index := range b.publicKeyIndicies { + copied.publicKeyIndicies[pk] = index + } + // Sync caches + if err := copied.initCaches(); err != nil { + return nil, err + } + for _, epoch := range b.activeValidatorsCache.Keys() { + val, has := b.activeValidatorsCache.Get(epoch) + if !has { + continue + } + copied.activeValidatorsCache.Add(epoch, val) + } + for _, key := range b.shuffledSetsCache.Keys() { + val, has := b.shuffledSetsCache.Get(key) + if !has { + continue + } + copied.shuffledSetsCache.Add(key, val) + } + for _, key := range b.committeeCache.Keys() { + val, has := b.committeeCache.Get(key) + if !has { + continue + } + copied.committeeCache.Add(key, val) + } + if b.totalActiveBalanceCache != nil { + copied.totalActiveBalanceCache = new(uint64) + *copied.totalActiveBalanceCache = *b.totalActiveBalanceCache + copied.totalActiveBalanceRootCache = b.totalActiveBalanceRootCache + } + + return copied, nil } diff --git a/cmd/erigon-cl/core/state/upgrade.go b/cmd/erigon-cl/core/state/upgrade.go new file mode 100644 index 00000000000..2ad0a126ae6 --- /dev/null +++ b/cmd/erigon-cl/core/state/upgrade.go @@ -0,0 +1,95 @@ +package state + +import ( + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon/cl/clparams" + "github.com/ledgerwatch/erigon/cl/cltypes" + "github.com/ledgerwatch/erigon/cl/utils" +) + +func (b *BeaconState) UpgradeToAltair() error { + b.previousStateRoot = libcommon.Hash{} + epoch := b.Epoch() + // update version + b.fork.Epoch = epoch + b.fork.CurrentVersion = utils.Uint32ToBytes4(b.beaconConfig.AltairForkVersion) + // Process new fields + b.previousEpochParticipation = make(cltypes.ParticipationFlagsList, len(b.validators)) + b.currentEpochParticipation = make(cltypes.ParticipationFlagsList, len(b.validators)) + b.inactivityScores = make([]uint64, len(b.validators)) + // Change version + b.version = clparams.AltairVersion + // Fill in previous epoch participation from the pre state's pending attestations + for _, attestation := range b.previousEpochAttestations { + flags, err := b.GetAttestationParticipationFlagIndicies(attestation.Data, attestation.InclusionDelay) + if err != nil { + return err + } + indicies, err := b.GetAttestingIndicies(attestation.Data, attestation.AggregationBits, false) + if err != nil { + return err + } + + for _, index := range indicies { + for _, flagIndex := range flags { + b.previousEpochParticipation[index] = b.previousEpochParticipation[index].Add(int(flagIndex)) + } + } + } + b.previousEpochAttestations = nil + // Process sync committees + var err error + if b.currentSyncCommittee, err = b.ComputeNextSyncCommittee(); err != nil { + return err + } + if b.nextSyncCommittee, err = b.ComputeNextSyncCommittee(); err != nil { + return err + } + // Update the state root cache + b.touchedLeaves[ForkLeafIndex] = true + b.touchedLeaves[PreviousEpochParticipationLeafIndex] = true + b.touchedLeaves[CurrentEpochParticipationLeafIndex] = true + b.touchedLeaves[InactivityScoresLeafIndex] = true + b.touchedLeaves[CurrentSyncCommitteeLeafIndex] = true + b.touchedLeaves[NextSyncCommitteeLeafIndex] = true + + return nil +} + +func (b *BeaconState) UpgradeToBellatrix() error { + b.previousStateRoot = libcommon.Hash{} + epoch := b.Epoch() + // update version + b.fork.Epoch = epoch + b.fork.PreviousVersion = b.fork.CurrentVersion + b.fork.CurrentVersion = utils.Uint32ToBytes4(b.beaconConfig.BellatrixForkVersion) + b.latestExecutionPayloadHeader = cltypes.NewEth1Header(clparams.BellatrixVersion) + // Update the state root cache + b.touchedLeaves[ForkLeafIndex] = true + b.touchedLeaves[LatestExecutionPayloadHeaderLeafIndex] = true + b.version = clparams.BellatrixVersion + return nil +} + +func (b *BeaconState) UpgradeToCapella() error { + b.previousStateRoot = libcommon.Hash{} + epoch := b.Epoch() + // update version + b.fork.Epoch = epoch + b.fork.PreviousVersion = b.fork.CurrentVersion + b.fork.CurrentVersion = utils.Uint32ToBytes4(b.beaconConfig.CapellaForkVersion) + // Update the payload header. + b.latestExecutionPayloadHeader.Capella() + // Set new fields + b.nextWithdrawalIndex = 0 + b.nextWithdrawalValidatorIndex = 0 + b.historicalSummaries = nil + // Update the state root cache + b.touchedLeaves[ForkLeafIndex] = true + b.touchedLeaves[LatestExecutionPayloadHeaderLeafIndex] = true + b.touchedLeaves[NextWithdrawalIndexLeafIndex] = true + b.touchedLeaves[NextWithdrawalValidatorIndexLeafIndex] = true + b.touchedLeaves[HistoricalSummariesLeafIndex] = true + b.version = clparams.CapellaVersion + return nil +} diff --git a/cmd/erigon-cl/core/transition/operations.go b/cmd/erigon-cl/core/transition/operations.go index 54e5cd3db03..0b8de4e0e0b 100644 --- a/cmd/erigon-cl/core/transition/operations.go +++ b/cmd/erigon-cl/core/transition/operations.go @@ -5,53 +5,16 @@ import ( "fmt" "github.com/Giulio2002/bls" + "github.com/ledgerwatch/log/v3" + "github.com/ledgerwatch/erigon/cl/clparams" "github.com/ledgerwatch/erigon/cl/cltypes" "github.com/ledgerwatch/erigon/cl/fork" "github.com/ledgerwatch/erigon/cl/utils" "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/state" + "github.com/ledgerwatch/erigon/core/types" ) -func isSlashableAttestationData(d1, d2 *cltypes.AttestationData) bool { - return (!d1.Equal(d2) && d1.Target.Epoch == d2.Target.Epoch) || - (d1.Source.Epoch < d2.Source.Epoch && d2.Target.Epoch < d1.Target.Epoch) -} - -func isValidIndexedAttestation(state *state.BeaconState, att *cltypes.IndexedAttestation) (bool, error) { - inds := att.AttestingIndices - if len(inds) == 0 || !utils.IsSliceSortedSet(inds) { - return false, fmt.Errorf("isValidIndexedAttestation: attesting indices are not sorted or are null") - } - - pks := [][]byte{} - for _, v := range inds { - val, err := state.ValidatorAt(int(v)) - if err != nil { - return false, err - } - pks = append(pks, val.PublicKey[:]) - } - - domain, err := state.GetDomain(state.BeaconConfig().DomainBeaconAttester, att.Data.Target.Epoch) - if err != nil { - return false, fmt.Errorf("unable to get the domain: %v", err) - } - - signingRoot, err := fork.ComputeSigningRoot(att.Data, domain) - if err != nil { - return false, fmt.Errorf("unable to get signing root: %v", err) - } - - valid, err := bls.VerifyAggregate(att.Signature[:], signingRoot[:], pks) - if err != nil { - return false, fmt.Errorf("error while validating signature: %v", err) - } - if !valid { - return false, fmt.Errorf("invalid aggregate signature") - } - return true, nil -} - func ProcessProposerSlashing(state *state.BeaconState, propSlashing *cltypes.ProposerSlashing) error { h1 := propSlashing.Header1.Header h2 := propSlashing.Header2.Header @@ -76,7 +39,7 @@ func ProcessProposerSlashing(state *state.BeaconState, propSlashing *cltypes.Pro return fmt.Errorf("propose slashing headers are the same: %v == %v", h1Root, h2Root) } - proposer, err := state.ValidatorAt(int(h1.ProposerIndex)) + proposer, err := state.ValidatorForValidatorIndex(int(h1.ProposerIndex)) if err != nil { return err } @@ -111,11 +74,11 @@ func ProcessAttesterSlashing(state *state.BeaconState, attSlashing *cltypes.Atte att1 := attSlashing.Attestation_1 att2 := attSlashing.Attestation_2 - if !isSlashableAttestationData(att1.Data, att2.Data) { + if !cltypes.IsSlashableAttestationData(att1.Data, att2.Data) { return fmt.Errorf("attestation data not slashable: %+v; %+v", att1.Data, att2.Data) } - valid, err := isValidIndexedAttestation(state, att1) + valid, err := state.IsValidIndexedAttestation(att1) if err != nil { return fmt.Errorf("error calculating indexed attestation 1 validity: %v", err) } @@ -123,7 +86,7 @@ func ProcessAttesterSlashing(state *state.BeaconState, attSlashing *cltypes.Atte return fmt.Errorf("invalid indexed attestation 1") } - valid, err = isValidIndexedAttestation(state, att2) + valid, err = state.IsValidIndexedAttestation(att2) if err != nil { return fmt.Errorf("error calculating indexed attestation 2 validity: %v", err) } @@ -134,7 +97,7 @@ func ProcessAttesterSlashing(state *state.BeaconState, attSlashing *cltypes.Atte slashedAny := false currentEpoch := state.GetEpochAtSlot(state.Slot()) for _, ind := range utils.IntersectionOfSortedSets(att1.AttestingIndices, att2.AttestingIndices) { - validator, err := state.ValidatorAt(int(ind)) + validator, err := state.ValidatorForValidatorIndex(int(ind)) if err != nil { return err } @@ -195,6 +158,7 @@ func ProcessDeposit(state *state.BeaconState, deposit *cltypes.Deposit, fullVali valid, err := bls.Verify(deposit.Data.Signature[:], signedRoot[:], publicKey[:]) // Literally you can input it trash. if !valid || err != nil { + log.Debug("Validator BLS verification failed", "valid", valid, "err", err) return nil } // Append validator @@ -216,7 +180,7 @@ func ProcessVoluntaryExit(state *state.BeaconState, signedVoluntaryExit *cltypes // Sanity checks so that we know it is good. voluntaryExit := signedVoluntaryExit.VolunaryExit currentEpoch := state.Epoch() - validator, err := state.ValidatorAt(int(voluntaryExit.ValidatorIndex)) + validator, err := state.ValidatorForValidatorIndex(int(voluntaryExit.ValidatorIndex)) if err != nil { return err } @@ -254,3 +218,49 @@ func ProcessVoluntaryExit(state *state.BeaconState, signedVoluntaryExit *cltypes // Do the exit (same process in slashing). return state.InitiateValidatorExit(voluntaryExit.ValidatorIndex) } + +// ProcessWithdrawals processes withdrawals by decreasing the balance of each validator +// and updating the next withdrawal index and validator index. +func ProcessWithdrawals(state *state.BeaconState, withdrawals types.Withdrawals, fullValidation bool) error { + // Get the list of withdrawals, the expected withdrawals (if performing full validation), + // and the beacon configuration. + beaconConfig := state.BeaconConfig() + numValidators := uint64(len(state.Validators())) + + // Check if full validation is required and verify expected withdrawals. + if fullValidation { + expectedWithdrawals := state.ExpectedWithdrawals() + if len(expectedWithdrawals) != len(withdrawals) { + return fmt.Errorf("ProcessWithdrawals: expected %d withdrawals, but got %d", len(expectedWithdrawals), len(withdrawals)) + } + for i, withdrawal := range withdrawals { + if !expectedWithdrawals[i].Equal(withdrawal) { + return fmt.Errorf("ProcessWithdrawals: withdrawal %d does not match expected withdrawal", i) + } + } + } + + // Decrease the balance of each validator for the corresponding withdrawal. + for _, withdrawal := range withdrawals { + if err := state.DecreaseBalance(withdrawal.Validator, withdrawal.Amount); err != nil { + return err + } + } + + // Update next withdrawal index based on number of withdrawals. + if len(withdrawals) > 0 { + lastWithdrawalIndex := withdrawals[len(withdrawals)-1].Index + state.SetNextWithdrawalIndex(lastWithdrawalIndex + 1) + } + + // Update next withdrawal validator index based on number of withdrawals. + if len(withdrawals) == int(beaconConfig.MaxWithdrawalsPerPayload) { + lastWithdrawalValidatorIndex := withdrawals[len(withdrawals)-1].Validator + 1 + state.SetNextWithdrawalValidatorIndex(lastWithdrawalValidatorIndex % numValidators) + } else { + nextIndex := state.NextWithdrawalValidatorIndex() + beaconConfig.MaxValidatorsPerWithdrawalsSweep + state.SetNextWithdrawalValidatorIndex(nextIndex % numValidators) + } + + return nil +} diff --git a/cmd/erigon-cl/core/transition/operations_test.go b/cmd/erigon-cl/core/transition/operations_test.go index 490720ab481..05eb86de165 100644 --- a/cmd/erigon-cl/core/transition/operations_test.go +++ b/cmd/erigon-cl/core/transition/operations_test.go @@ -350,29 +350,3 @@ func TestProcessVoluntaryExits(t *testing.T) { newRegistry := state.Validators() require.Equal(t, newRegistry[0].ExitEpoch, uint64(266)) } - -func TestProcessAttestationAggBitsInvalid(t *testing.T) { - beaconState := state.GetEmptyBeaconState() - beaconState.SetSlot(beaconState.Slot() + clparams.MainnetBeaconConfig.MinAttestationInclusionDelay) - for i := 0; i < 64; i++ { - beaconState.AddValidator(&cltypes.Validator{ - EffectiveBalance: clparams.MainnetBeaconConfig.MaxEffectiveBalance, - ExitEpoch: clparams.MainnetBeaconConfig.FarFutureEpoch, - WithdrawableEpoch: clparams.MainnetBeaconConfig.FarFutureEpoch, - }, clparams.MainnetBeaconConfig.MaxEffectiveBalance) - beaconState.AddCurrentEpochParticipationFlags(cltypes.ParticipationFlags(0)) - } - - aggBits := []byte{7} - r, err := beaconState.GetBlockRootAtSlot(0) - require.NoError(t, err) - att := &cltypes.Attestation{ - Data: &cltypes.AttestationData{ - BeaconBlockHash: r, - Source: &cltypes.Checkpoint{}, - Target: &cltypes.Checkpoint{}, - }, - AggregationBits: aggBits, - } - require.Error(t, ProcessAttestations(beaconState, []*cltypes.Attestation{att}, false)) -} diff --git a/cmd/erigon-cl/core/transition/process_attestations.go b/cmd/erigon-cl/core/transition/process_attestations.go index 8a3d30704af..497da856adc 100644 --- a/cmd/erigon-cl/core/transition/process_attestations.go +++ b/cmd/erigon-cl/core/transition/process_attestations.go @@ -104,7 +104,7 @@ func verifyAttestationWorker(state *state.BeaconState, attestation *cltypes.Atte resultCh <- verifyAttestationWorkersResult{err: err} return } - success, err := isValidIndexedAttestation(state, indexedAttestation) + success, err := state.IsValidIndexedAttestation(indexedAttestation) resultCh <- verifyAttestationWorkersResult{success: success, err: err} } diff --git a/cmd/erigon-cl/core/transition/process_slots.go b/cmd/erigon-cl/core/transition/process_slots.go index d208e7e5a36..43ead92a8ea 100644 --- a/cmd/erigon-cl/core/transition/process_slots.go +++ b/cmd/erigon-cl/core/transition/process_slots.go @@ -97,7 +97,7 @@ func ProcessSlots(state *state.BeaconState, slot uint64) error { if err := ProcessEpoch(state); err != nil { return err } - log.Info("Processed new epoch successfully", "epoch", state.Epoch(), "process_epoch_elpsed", time.Since(start)) + log.Debug("Processed new epoch successfully", "epoch", state.Epoch(), "process_epoch_elpsed", time.Since(start)) } // TODO: add logic to process epoch updates. stateSlot += 1 diff --git a/cmd/erigon-cl/execution_client/execution_engine.go b/cmd/erigon-cl/execution_client/execution_engine.go new file mode 100644 index 00000000000..66cff77eeff --- /dev/null +++ b/cmd/erigon-cl/execution_client/execution_engine.go @@ -0,0 +1,148 @@ +package execution_client + +import ( + "context" + "fmt" + "time" + + "github.com/holiman/uint256" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/gointerfaces" + "github.com/ledgerwatch/erigon-lib/gointerfaces/remote" + "github.com/ledgerwatch/erigon-lib/gointerfaces/types" + "github.com/ledgerwatch/erigon/cl/cltypes" + "github.com/ledgerwatch/erigon/ethdb/privateapi" +) + +var errContextExceeded = "rpc error: code = DeadlineExceeded desc = context deadline exceeded" + +// ExecutionEngine is used only for syncing up very close to chain tip and to stay in sync. +// It pretty much mimics engine API. +type ExecutionEngine interface { + NewPayload(payload *cltypes.Eth1Block) error + ForkChoiceUpdate(finalized libcommon.Hash, head libcommon.Hash) error +} + +// ExecutionEnginePhase1 is just the normal engine api. +type ExecutionEnginePhase1 struct { + // Either execution server or client + executionServer remote.ETHBACKENDServer + executionClient remote.ETHBACKENDClient + + ctx context.Context +} + +// NewExecutionEnginePhase1FromServer use ethbackend server +func NewExecutionEnginePhase1FromServer(ctx context.Context, executionServer remote.ETHBACKENDServer) *ExecutionEnginePhase1 { + return &ExecutionEnginePhase1{ + executionServer: executionServer, + ctx: ctx, + } +} + +// NewExecutionEnginePhase1FromServer use ethbackend client +func NewExecutionEnginePhase1FromClient(ctx context.Context, executionClient remote.ETHBACKENDClient) *ExecutionEnginePhase1 { + return &ExecutionEnginePhase1{ + executionClient: executionClient, + ctx: ctx, + } +} + +func (e *ExecutionEnginePhase1) NewPayload(payload *cltypes.Eth1Block) error { + grpcMessage, err := convertPayloadToGrpc(payload) + if err != nil { + return err + } + ctx, cancel := context.WithTimeout(e.ctx, 3*time.Second) + defer cancel() + + var status *remote.EnginePayloadStatus + if e.executionServer != nil { + status, err = e.executionServer.EngineNewPayload(ctx, grpcMessage) + } else if e.executionClient != nil { + status, err = e.executionClient.EngineNewPayload(ctx, grpcMessage) + } + // Ignore timeouts + if err != nil { + if err.Error() == errContextExceeded { + return nil + } + return err + } + if status.Status == remote.EngineStatus_INVALID { + return fmt.Errorf("invalid block") + } + if status.Status == remote.EngineStatus_INVALID_BLOCK_HASH { + return fmt.Errorf("invalid block hash") + } + return err +} + +func (e *ExecutionEnginePhase1) ForkChoiceUpdate(finalized libcommon.Hash, head libcommon.Hash) error { + grpcMessage := &remote.EngineForkChoiceUpdatedRequest{ + ForkchoiceState: &remote.EngineForkChoiceState{ + HeadBlockHash: gointerfaces.ConvertHashToH256(head), + SafeBlockHash: gointerfaces.ConvertHashToH256(head), + FinalizedBlockHash: gointerfaces.ConvertHashToH256(finalized), + }, + } + var err error + ctx, cancel := context.WithTimeout(e.ctx, 3*time.Second) + defer cancel() + if e.executionClient != nil { + _, err = e.executionClient.EngineForkChoiceUpdated(ctx, grpcMessage) + } else if e.executionServer != nil { + _, err = e.executionServer.EngineForkChoiceUpdated(ctx, grpcMessage) + } + // Ignore timeouts + if err != nil && err.Error() == errContextExceeded { + return nil + } + + return err +} + +// ExecutionEnginePhase2 is "real merge" (TODO). +type ExecutionEnginePhase2 struct { +} + +func convertPayloadToGrpc(e *cltypes.Eth1Block) (*types.ExecutionPayload, error) { + var baseFee *uint256.Int + header, err := e.RlpHeader() + if err != nil { + return nil, err + } + + if header.BaseFee != nil { + var overflow bool + baseFee, overflow = uint256.FromBig(header.BaseFee) + if overflow { + panic("NewPayload BaseFeePerGas overflow") + } + } + + res := &types.ExecutionPayload{ + Version: 1, + ParentHash: gointerfaces.ConvertHashToH256(header.ParentHash), + Coinbase: gointerfaces.ConvertAddressToH160(header.Coinbase), + StateRoot: gointerfaces.ConvertHashToH256(header.Root), + ReceiptRoot: gointerfaces.ConvertHashToH256(header.ReceiptHash), + LogsBloom: gointerfaces.ConvertBytesToH2048(header.Bloom[:]), + PrevRandao: gointerfaces.ConvertHashToH256(header.MixDigest), + BlockNumber: header.Number.Uint64(), + GasLimit: header.GasLimit, + GasUsed: header.GasUsed, + Timestamp: header.Time, + ExtraData: header.Extra, + BaseFeePerGas: gointerfaces.ConvertUint256IntToH256(baseFee), + BlockHash: gointerfaces.ConvertHashToH256(e.BlockHash), + Transactions: e.Transactions, + Withdrawals: privateapi.ConvertWithdrawalsToRpc(e.Withdrawals), + } + if e.Withdrawals != nil { + res.Version = 2 + res.Withdrawals = privateapi.ConvertWithdrawalsToRpc(e.Withdrawals) + } + + return res, nil +} diff --git a/cmd/erigon-cl/forkchoice/fork_choice_test.go b/cmd/erigon-cl/forkchoice/fork_choice_test.go new file mode 100644 index 00000000000..2a73378bad0 --- /dev/null +++ b/cmd/erigon-cl/forkchoice/fork_choice_test.go @@ -0,0 +1,88 @@ +package forkchoice_test + +import ( + _ "embed" + "testing" + + libcommon "github.com/ledgerwatch/erigon-lib/common" + + "github.com/ledgerwatch/erigon/cl/clparams" + "github.com/ledgerwatch/erigon/cl/cltypes" + "github.com/ledgerwatch/erigon/cl/utils" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/state" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/forkchoice" + "github.com/stretchr/testify/require" +) + +//go:embed test_data/anchor_state.ssz_snappy +var anchorStateEncoded []byte + +//go:embed test_data/block_0x3af8b5b42ca135c75b32abb32b3d71badb73695d3dc638bacfb6c8b7bcbee1a9.ssz_snappy +var block3aEncoded []byte + +//go:embed test_data/block_0xc2788d6005ee2b92c3df2eff0aeab0374d155fa8ca1f874df305fa376ce334cf.ssz_snappy +var blockc2Encoded []byte + +//go:embed test_data/block_0xd4503d46e43df56de4e19acb0f93b3b52087e422aace49a7c3816cf59bafb0ad.ssz_snappy +var blockd4Encoded []byte + +//go:embed test_data/attestation_0xfb924d35b2888d9cd70e6879c1609e6cad7ea3b028a501967747d96e49068cb6.ssz_snappy +var attestationEncoded []byte + +// this is consensus spec test altair/forkchoice/ex_ante/ex_ante_attestations_is_greater_than_proposer_boost_with_boost +func TestForkChoiceBasic(t *testing.T) { + expectedCheckpoint := &cltypes.Checkpoint{ + Epoch: 0, + Root: libcommon.HexToHash("0x564d76d91f66c1fb2977484a6184efda2e1c26dd01992e048353230e10f83201"), + } + // Decode test blocks + block0x3a, block0xc2, block0xd4 := &cltypes.SignedBeaconBlock{}, &cltypes.SignedBeaconBlock{}, &cltypes.SignedBeaconBlock{} + require.NoError(t, utils.DecodeSSZSnappyWithVersion(block0x3a, block3aEncoded, int(clparams.AltairVersion))) + require.NoError(t, utils.DecodeSSZSnappyWithVersion(block0xc2, blockc2Encoded, int(clparams.AltairVersion))) + require.NoError(t, utils.DecodeSSZSnappyWithVersion(block0xd4, blockd4Encoded, int(clparams.AltairVersion))) + // decode test attestation + testAttestation := &cltypes.Attestation{} + require.NoError(t, utils.DecodeSSZSnappyWithVersion(testAttestation, attestationEncoded, int(clparams.AltairVersion))) + // Initialize forkchoice store + anchorState := state.New(&clparams.MainnetBeaconConfig) + require.NoError(t, utils.DecodeSSZSnappyWithVersion(anchorState, anchorStateEncoded, int(clparams.AltairVersion))) + store, err := forkchoice.NewForkChoiceStore(anchorState, nil, false) + require.NoError(t, err) + // first steps + store.OnTick(0) + store.OnTick(12) + require.NoError(t, store.OnBlock(block0x3a, true)) + // Check if we get correct status (1) + require.Equal(t, store.Time(), uint64(12)) + require.Equal(t, store.ProposerBoostRoot(), libcommon.HexToHash("0xc9bd7bcb6dfa49dc4e5a67ca75e89062c36b5c300bc25a1b31db4e1a89306071")) + require.Equal(t, store.JustifiedCheckpoint(), expectedCheckpoint) + require.Equal(t, store.FinalizedCheckpoint(), expectedCheckpoint) + headRoot, headSlot, err := store.GetHead() + require.NoError(t, err) + require.Equal(t, headRoot, libcommon.HexToHash("0xc9bd7bcb6dfa49dc4e5a67ca75e89062c36b5c300bc25a1b31db4e1a89306071")) + require.Equal(t, headSlot, uint64(1)) + // process another tick and another block + store.OnTick(36) + require.NoError(t, store.OnBlock(block0xc2, true)) + // Check if we get correct status (2) + require.Equal(t, store.Time(), uint64(36)) + require.Equal(t, store.ProposerBoostRoot(), libcommon.HexToHash("0x744cc484f6503462f0f3a5981d956bf4fcb3e57ab8687ed006467e05049ee033")) + require.Equal(t, store.JustifiedCheckpoint(), expectedCheckpoint) + require.Equal(t, store.FinalizedCheckpoint(), expectedCheckpoint) + headRoot, headSlot, err = store.GetHead() + require.NoError(t, err) + require.Equal(t, headSlot, uint64(3)) + require.Equal(t, headRoot, libcommon.HexToHash("0x744cc484f6503462f0f3a5981d956bf4fcb3e57ab8687ed006467e05049ee033")) + // last block + require.NoError(t, store.OnBlock(block0xd4, true)) + require.Equal(t, store.Time(), uint64(36)) + require.Equal(t, store.ProposerBoostRoot(), libcommon.HexToHash("0x744cc484f6503462f0f3a5981d956bf4fcb3e57ab8687ed006467e05049ee033")) + require.Equal(t, store.JustifiedCheckpoint(), expectedCheckpoint) + require.Equal(t, store.FinalizedCheckpoint(), expectedCheckpoint) + headRoot, headSlot, err = store.GetHead() + require.NoError(t, err) + require.Equal(t, headSlot, uint64(3)) + require.Equal(t, headRoot, libcommon.HexToHash("0x744cc484f6503462f0f3a5981d956bf4fcb3e57ab8687ed006467e05049ee033")) + // lastly do attestation + require.NoError(t, store.OnAttestation(testAttestation, false)) +} diff --git a/cmd/erigon-cl/forkchoice/fork_graph/fork_graph.go b/cmd/erigon-cl/forkchoice/fork_graph/fork_graph.go new file mode 100644 index 00000000000..a342a461d1d --- /dev/null +++ b/cmd/erigon-cl/forkchoice/fork_graph/fork_graph.go @@ -0,0 +1,284 @@ +package fork_graph + +import ( + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon/cl/clparams" + "github.com/ledgerwatch/erigon/cl/cltypes" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/state" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/transition" + "github.com/ledgerwatch/log/v3" + "golang.org/x/exp/slices" +) + +type ChainSegmentInsertionResult uint + +const ( + Success ChainSegmentInsertionResult = 0 + InvalidBlock ChainSegmentInsertionResult = 1 + MissingSegment ChainSegmentInsertionResult = 2 + BelowAnchor ChainSegmentInsertionResult = 3 + LogisticError ChainSegmentInsertionResult = 4 + PreValidated ChainSegmentInsertionResult = 5 +) + +const snapshotStateEverySlot = 64 + +/* +* The state store process is related to graph theory in the sense that the Ethereum blockchain can be thought of as a directed graph, +* where each block represents a node and the links between blocks represent directed edges. +* In this context, rolling back the state of Ethereum to a previous state can be thought of as traversing the graph in reverse, +* from the current state to a previous state. +* The process of reverting the state involves undoing the changes made in the blocks that have been added to the blockchain since the previous state. +* This can be thought of as "reversing the edges" in the graph, effectively undoing the changes made to the state of Ethereum. +* By thinking of the Ethereum blockchain as a graph, we can use graph theory concepts, such as traversal algorithms, +* to analyze and manipulate the state of the blockchain. + */ + +// ForkGraph is our graph for ETH 2.0 consensus forkchoice. Each node is a (block root, changes) pair and +// each edge is the path described as (prevBlockRoot, currBlockRoot). if we want to go forward we use blocks. +type ForkGraph struct { + // Alternate beacon states + currentReferenceState *state.BeaconState + nextReferenceState *state.BeaconState + currentReferenceStateRoot libcommon.Hash + blocks map[libcommon.Hash]*cltypes.SignedBeaconBlock // set of blocks + headers map[libcommon.Hash]*cltypes.BeaconBlockHeader // set of headers + badBlocks map[libcommon.Hash]struct{} // blocks that are invalid and that leads to automatic fail of extension. + // current state data + currentState *state.BeaconState + currentStateBlockRoot libcommon.Hash + // childrens maps each block roots to its children block roots + childrens map[libcommon.Hash][]libcommon.Hash + // for each block root we also keep track of te equivalent current justified and finalized checkpoints for faster head retrieval. + currentJustifiedCheckpoints map[libcommon.Hash]*cltypes.Checkpoint + finalizedCheckpoints map[libcommon.Hash]*cltypes.Checkpoint + // Disable for tests + enabledPruning bool + // configurations + beaconCfg *clparams.BeaconChainConfig + genesisTime uint64 +} + +// Initialize fork graph with a new state +func New(anchorState *state.BeaconState, enabledPruning bool) *ForkGraph { + farthestExtendingPath := make(map[libcommon.Hash]bool) + anchorRoot, err := anchorState.BlockRoot() + if err != nil { + panic(err) + } + headers := make(map[libcommon.Hash]*cltypes.BeaconBlockHeader) + anchorHeader := anchorState.LatestBlockHeader() + if anchorHeader.Root, err = anchorState.HashSSZ(); err != nil { + panic(err) + } + headers[anchorRoot] = &anchorHeader + + farthestExtendingPath[anchorRoot] = true + currentStateReference, err := anchorState.Copy() + if err != nil { + panic(err) + } + return &ForkGraph{ + currentReferenceState: currentStateReference, + nextReferenceState: currentStateReference, + // storage + blocks: make(map[libcommon.Hash]*cltypes.SignedBeaconBlock), + headers: headers, + badBlocks: make(map[libcommon.Hash]struct{}), + // current state data + currentState: anchorState, + currentStateBlockRoot: anchorRoot, + currentReferenceStateRoot: anchorRoot, + // childrens + childrens: make(map[libcommon.Hash][]libcommon.Hash), + // checkpoints trackers + currentJustifiedCheckpoints: make(map[libcommon.Hash]*cltypes.Checkpoint), + finalizedCheckpoints: make(map[libcommon.Hash]*cltypes.Checkpoint), + enabledPruning: enabledPruning, + // configuration + beaconCfg: anchorState.BeaconConfig(), + genesisTime: anchorState.GenesisTime(), + } +} + +// Add a new node and edge to the graph +func (f *ForkGraph) AddChainSegment(signedBlock *cltypes.SignedBeaconBlock, fullValidation bool) (*state.BeaconState, ChainSegmentInsertionResult, error) { + block := signedBlock.Block + blockRoot, err := block.HashSSZ() + if err != nil { + return nil, LogisticError, err + } + + if _, ok := f.blocks[blockRoot]; ok { + return nil, PreValidated, nil + } + // Blocks below anchors are invalid. + if block.Slot <= f.currentReferenceState.Slot() { + log.Debug("block below anchor slot", "slot", block.Slot, "hash", libcommon.Hash(blockRoot)) + f.badBlocks[blockRoot] = struct{}{} + return nil, BelowAnchor, nil + } + // Check if block being process right now was marked as invalid. + if _, ok := f.badBlocks[blockRoot]; ok { + log.Debug("block has invalid parent", "slot", block.Slot, "hash", libcommon.Hash(blockRoot)) + f.badBlocks[blockRoot] = struct{}{} + return nil, InvalidBlock, nil + } + + newState, err := f.GetState(block.ParentRoot, false) + if err != nil { + return nil, InvalidBlock, err + } + if newState == nil { + return nil, MissingSegment, nil + } + // We may just use the current beacon state + prevCurrentStateSlot := f.currentState.Slot() + + // Execute the state + if err := transition.TransitionState(newState, signedBlock, fullValidation); err != nil { + // Add block to list of invalid blocks + log.Debug("Invalid beacon block", "reason", err) + f.badBlocks[blockRoot] = struct{}{} + f.currentState = nil + return nil, InvalidBlock, err + } + + f.blocks[blockRoot] = signedBlock + bodyRoot, err := signedBlock.Block.Body.HashSSZ() + if err != nil { + return nil, LogisticError, err + } + f.headers[blockRoot] = &cltypes.BeaconBlockHeader{ + Slot: block.Slot, + ProposerIndex: block.ProposerIndex, + ParentRoot: block.ParentRoot, + Root: block.StateRoot, + BodyRoot: bodyRoot, + } + // Update the children of the parent + f.updateChildren(block.ParentRoot, blockRoot) + // Lastly add checkpoints to caches as well. + f.currentJustifiedCheckpoints[blockRoot] = newState.CurrentJustifiedCheckpoint().Copy() + f.finalizedCheckpoints[blockRoot] = newState.FinalizedCheckpoint().Copy() + if newState.Slot() > prevCurrentStateSlot { + f.currentState = newState + f.currentStateBlockRoot = blockRoot + if newState.Slot()%snapshotStateEverySlot == 0 && f.enabledPruning { + if err := f.removeOldData(); err != nil { + return nil, LogisticError, err + } + } + } + return newState, Success, nil +} + +func (f *ForkGraph) GenesisTime() uint64 { + return f.genesisTime +} + +func (f *ForkGraph) Config() *clparams.BeaconChainConfig { + return f.beaconCfg +} + +func (f *ForkGraph) GetHeader(blockRoot libcommon.Hash) (*cltypes.BeaconBlockHeader, bool) { + obj, has := f.headers[blockRoot] + return obj, has +} + +func (f *ForkGraph) getBlock(blockRoot libcommon.Hash) (*cltypes.SignedBeaconBlock, bool) { + obj, has := f.blocks[blockRoot] + return obj, has +} + +func (f *ForkGraph) GetState(blockRoot libcommon.Hash, alwaysCopy bool) (*state.BeaconState, error) { + if f.currentStateBlockRoot == blockRoot { + if alwaysCopy { + return f.currentState.Copy() + } + return f.currentState, nil + } + // collect all blocks beetwen greatest extending node path and block. + blocksInTheWay := []*cltypes.SignedBeaconBlock{} + // Use the parent root as a reverse iterator. + currentIteratorRoot := blockRoot + // use the current reference state root as reconnectio + reconnectionRoot, err := f.currentReferenceState.BlockRoot() + if err != nil { + return nil, err + } + // try and find the point of recconection + for currentIteratorRoot != reconnectionRoot { + block, isSegmentPresent := f.getBlock(currentIteratorRoot) + if !isSegmentPresent { + log.Debug("Could not retrieve state: Missing header", "missing", currentIteratorRoot) + return nil, nil + } + blocksInTheWay = append(blocksInTheWay, block) + currentIteratorRoot = block.Block.ParentRoot + } + // Take a copy to the reference state. + copyReferencedState, err := f.currentReferenceState.Copy() + if err != nil { + return nil, err + } + // Traverse the blocks from top to bottom. + for i := len(blocksInTheWay) - 1; i >= 0; i-- { + if err := transition.TransitionState(copyReferencedState, blocksInTheWay[i], false); err != nil { + return nil, err + } + } + return copyReferencedState, nil +} + +// updateChildren adds a new child to the parent node hash. +func (f *ForkGraph) updateChildren(parent, child libcommon.Hash) { + childrens := f.childrens[parent] + if slices.Contains(childrens, child) { + return + } + childrens = append(childrens, child) + f.childrens[parent] = childrens +} + +// GetChildren retrieves the children block root of the given block root. +func (f *ForkGraph) GetChildren(parent libcommon.Hash) []libcommon.Hash { + return f.childrens[parent] +} + +func (f *ForkGraph) GetCurrentJustifiedCheckpoint(blockRoot libcommon.Hash) (*cltypes.Checkpoint, bool) { + obj, has := f.currentJustifiedCheckpoints[blockRoot] + return obj, has +} + +func (f *ForkGraph) GetFinalizedCheckpoint(blockRoot libcommon.Hash) (*cltypes.Checkpoint, bool) { + obj, has := f.finalizedCheckpoints[blockRoot] + return obj, has +} + +func (f *ForkGraph) removeOldData() (err error) { + pruneSlot := f.nextReferenceState.Slot() + log.Debug("Pruning old blocks", "pruneSlot", pruneSlot) + oldRoots := make([]libcommon.Hash, 0, len(f.blocks)) + for hash, signedBlock := range f.blocks { + if signedBlock.Block.Slot >= pruneSlot { + continue + } + oldRoots = append(oldRoots, hash) + } + for _, root := range oldRoots { + delete(f.badBlocks, root) + delete(f.blocks, root) + delete(f.childrens, root) + delete(f.currentJustifiedCheckpoints, root) + delete(f.finalizedCheckpoints, root) + delete(f.headers, root) + } + // Lastly snapshot the state + f.currentReferenceState = f.nextReferenceState + if f.currentReferenceStateRoot, err = f.currentReferenceState.HashSSZ(); err != nil { + return + } + f.nextReferenceState, err = f.currentState.Copy() + return +} diff --git a/cmd/erigon-cl/forkchoice/fork_graph/fork_graph_test.go b/cmd/erigon-cl/forkchoice/fork_graph/fork_graph_test.go new file mode 100644 index 00000000000..78e8eeab938 --- /dev/null +++ b/cmd/erigon-cl/forkchoice/fork_graph/fork_graph_test.go @@ -0,0 +1,49 @@ +package fork_graph_test + +import ( + _ "embed" + "testing" + + "github.com/ledgerwatch/erigon/cl/clparams" + "github.com/ledgerwatch/erigon/cl/cltypes" + "github.com/ledgerwatch/erigon/cl/utils" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/state" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/forkchoice/fork_graph" + "github.com/stretchr/testify/require" +) + +//go:embed test_data/block_0xe2a37a22d208ebe969c50e9d44bb3f1f63c5404787b9c214a5f2f28fb9835feb.ssz_snappy +var block1 []byte + +//go:embed test_data/block_0xbf1a9ba2d349f6b5a5095bff40bd103ae39177e36018fb1f589953b9eeb0ca9d.ssz_snappy +var block2 []byte + +//go:embed test_data/anchor_state.ssz_snappy +var anchor []byte + +func TestForkGraph(t *testing.T) { + blockA, blockB, blockC := &cltypes.SignedBeaconBlock{}, &cltypes.SignedBeaconBlock{}, &cltypes.SignedBeaconBlock{} + anchorState := state.New(&clparams.MainnetBeaconConfig) + require.NoError(t, utils.DecodeSSZSnappyWithVersion(blockA, block1, int(clparams.Phase0Version))) + require.NoError(t, utils.DecodeSSZSnappyWithVersion(blockB, block2, int(clparams.Phase0Version))) + require.NoError(t, utils.DecodeSSZSnappyWithVersion(blockC, block2, int(clparams.Phase0Version))) + require.NoError(t, utils.DecodeSSZSnappyWithVersion(anchorState, anchor, int(clparams.Phase0Version))) + graph := fork_graph.New(anchorState, false) + _, status, err := graph.AddChainSegment(blockA, true) + require.NoError(t, err) + // Save current state hash + require.NoError(t, err) + require.Equal(t, status, fork_graph.Success) + _, status, err = graph.AddChainSegment(blockB, true) + require.NoError(t, err) + require.Equal(t, status, fork_graph.Success) + // Try again with same should yield success + _, status, err = graph.AddChainSegment(blockB, true) + require.NoError(t, err) + require.Equal(t, status, fork_graph.PreValidated) + // Now make blockC a bad block + blockC.Block.ProposerIndex = 81214459 // some invalid thing + _, status, err = graph.AddChainSegment(blockC, true) + require.Error(t, err) + require.Equal(t, status, fork_graph.InvalidBlock) +} diff --git a/cmd/erigon-cl/forkchoice/forkchoice.go b/cmd/erigon-cl/forkchoice/forkchoice.go new file mode 100644 index 00000000000..7a3da411ecd --- /dev/null +++ b/cmd/erigon-cl/forkchoice/forkchoice.go @@ -0,0 +1,133 @@ +package forkchoice + +import ( + "sync" + + lru "github.com/hashicorp/golang-lru/v2" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon/cl/cltypes" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/state" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/execution_client" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/forkchoice/fork_graph" +) + +const ( + checkpointsPerCache = 1024 + allowedCachedStates = 4 +) + +// We cache partial data of each validator instead of storing all checkpoint states +type partialValidator struct { + index uint32 + effectiveBalance uint64 +} + +type ForkChoiceStore struct { + time uint64 + highestSeen uint64 + justifiedCheckpoint *cltypes.Checkpoint + finalizedCheckpoint *cltypes.Checkpoint + unrealizedJustifiedCheckpoint *cltypes.Checkpoint + unrealizedFinalizedCheckpoint *cltypes.Checkpoint + proposerBoostRoot libcommon.Hash + // Use go map because this is actually an unordered set + equivocatingIndicies map[uint64]struct{} + forkGraph *fork_graph.ForkGraph + // I use the cache due to the convenient auto-cleanup feauture. + checkpointStates *lru.Cache[cltypes.Checkpoint, *state.BeaconState] // We keep ssz snappy of it as the full beacon state is full of rendundant data. + latestMessages map[uint64]*LatestMessage + // We keep track of them so that we can forkchoice with EL. + eth2Roots *lru.Cache[libcommon.Hash, libcommon.Hash] // ETH2 root -> ETH1 hash + mu sync.Mutex + // EL + engine execution_client.ExecutionEngine +} + +type LatestMessage struct { + Epoch uint64 + Root libcommon.Hash +} + +// NewForkChoiceStore initialize a new store from the given anchor state, either genesis or checkpoint sync state. +func NewForkChoiceStore(anchorState *state.BeaconState, engine execution_client.ExecutionEngine, enabledPruning bool) (*ForkChoiceStore, error) { + anchorRoot, err := anchorState.BlockRoot() + if err != nil { + return nil, err + } + anchorCheckpoint := &cltypes.Checkpoint{ + Epoch: anchorState.Epoch(), + Root: anchorRoot, + } + checkpointStates, err := lru.New[cltypes.Checkpoint, *state.BeaconState](allowedCachedStates) + if err != nil { + return nil, err + } + eth2Roots, err := lru.New[libcommon.Hash, libcommon.Hash](checkpointsPerCache) + if err != nil { + return nil, err + } + return &ForkChoiceStore{ + highestSeen: anchorState.Slot(), + time: anchorState.GenesisTime() + anchorState.BeaconConfig().SecondsPerSlot*anchorState.Slot(), + justifiedCheckpoint: anchorCheckpoint.Copy(), + finalizedCheckpoint: anchorCheckpoint.Copy(), + unrealizedJustifiedCheckpoint: anchorCheckpoint.Copy(), + unrealizedFinalizedCheckpoint: anchorCheckpoint.Copy(), + forkGraph: fork_graph.New(anchorState, enabledPruning), + equivocatingIndicies: map[uint64]struct{}{}, + latestMessages: map[uint64]*LatestMessage{}, + checkpointStates: checkpointStates, + eth2Roots: eth2Roots, + engine: engine, + }, nil +} + +// Highest seen returns highest seen slot +func (f *ForkChoiceStore) HighestSeen() uint64 { + f.mu.Lock() + defer f.mu.Unlock() + return f.highestSeen +} + +// Time returns current time +func (f *ForkChoiceStore) Time() uint64 { + f.mu.Lock() + defer f.mu.Unlock() + return f.time +} + +// ProposerBoostRoot returns proposer boost root +func (f *ForkChoiceStore) ProposerBoostRoot() libcommon.Hash { + f.mu.Lock() + defer f.mu.Unlock() + return f.proposerBoostRoot +} + +// JustifiedCheckpoint returns justified checkpoint +func (f *ForkChoiceStore) JustifiedCheckpoint() *cltypes.Checkpoint { + f.mu.Lock() + defer f.mu.Unlock() + return f.justifiedCheckpoint +} + +// FinalizedCheckpoint returns justified checkpoint +func (f *ForkChoiceStore) FinalizedCheckpoint() *cltypes.Checkpoint { + f.mu.Lock() + defer f.mu.Unlock() + return f.finalizedCheckpoint +} + +// FinalizedCheckpoint returns justified checkpoint +func (f *ForkChoiceStore) Engine() execution_client.ExecutionEngine { + f.mu.Lock() + defer f.mu.Unlock() + return f.engine +} + +// FinalizedCheckpoint returns justified checkpoint +func (f *ForkChoiceStore) GetEth1Hash(eth2Root libcommon.Hash) libcommon.Hash { + f.mu.Lock() + defer f.mu.Unlock() + ret, _ := f.eth2Roots.Get(eth2Root) + return ret +} diff --git a/cmd/erigon-cl/forkchoice/get_head.go b/cmd/erigon-cl/forkchoice/get_head.go new file mode 100644 index 00000000000..f0d15ab8d11 --- /dev/null +++ b/cmd/erigon-cl/forkchoice/get_head.go @@ -0,0 +1,160 @@ +package forkchoice + +import ( + "bytes" + "fmt" + "sort" + + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon/cl/cltypes" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/state" +) + +// GetHead fetches the current head. +func (f *ForkChoiceStore) GetHead() (libcommon.Hash, uint64, error) { + f.mu.Lock() + defer f.mu.Unlock() + // Retrieve att + head := f.justifiedCheckpoint.Root + blocks := f.getFilteredBlockTree(head) + // See which validators can be used for attestation score + justificationState, err := f.getCheckpointState(*f.justifiedCheckpoint) + if err != nil { + return libcommon.Hash{}, 0, err + } + // Filter all validators deemed as bad + filteredIndicies := f.filterValidatorSetForAttestationScores(justificationState.Validators(), justificationState.Epoch()) + for { + // Filter out current head children. + unfilteredChildren := f.forkGraph.GetChildren(head) + children := []libcommon.Hash{} + for _, child := range unfilteredChildren { + if _, ok := blocks[child]; ok { + children = append(children, child) + } + } + // Stop if we dont have any more children + if len(children) == 0 { + header, hasHeader := f.forkGraph.GetHeader(head) + if !hasHeader { + return libcommon.Hash{}, 0, fmt.Errorf("no slot for head is stored") + } + return head, header.Slot, nil + } + // Average case scenario. + if len(children) == 1 { + head = children[0] + continue + } + // Sort children by lexigographical order + sort.Slice(children, func(i, j int) bool { + childA := children[i] + childB := children[j] + return bytes.Compare(childA[:], childB[:]) < 0 + }) + + // After sorting is done determine best fit. + head = children[0] + maxWeight := f.getWeight(children[0], filteredIndicies, justificationState) + for i := 1; i < len(children); i++ { + weight := f.getWeight(children[i], filteredIndicies, justificationState) + // Lexicographical order is king. + if weight >= maxWeight { + head = children[i] + maxWeight = weight + } + } + } +} + +// filterValidatorSetForAttestationScores preliminarly filter the validator set obliging to consensus rules. +func (f *ForkChoiceStore) filterValidatorSetForAttestationScores(validatorSet []*cltypes.Validator, epoch uint64) []uint64 { + filtered := make([]uint64, 0, len(validatorSet)) + for validatorIndex, validator := range validatorSet { + if !validator.Active(epoch) || validator.Slashed { + continue + } + if _, hasLatestMessage := f.latestMessages[uint64(validatorIndex)]; !hasLatestMessage { + continue + } + if _, isUnequivocating := f.equivocatingIndicies[uint64(validatorIndex)]; isUnequivocating { + continue + } + filtered = append(filtered, uint64(validatorIndex)) + } + return filtered +} + +// getWeight computes weight in head decision of canonical chain. +func (f *ForkChoiceStore) getWeight(root libcommon.Hash, indicies []uint64, state *state.BeaconState) uint64 { + header, has := f.forkGraph.GetHeader(root) + if !has { + return 0 + } + validators := state.Validators() + // Compute attestation score + var attestationScore uint64 + for _, validatorIndex := range indicies { + if f.Ancestor(f.latestMessages[validatorIndex].Root, header.Slot) != root { + continue + } + attestationScore += validators[validatorIndex].EffectiveBalance + } + if f.proposerBoostRoot == (libcommon.Hash{}) { + return attestationScore + } + + // Boost is applied if root is an ancestor of proposer_boost_root + if f.Ancestor(f.proposerBoostRoot, header.Slot) == root { + committeeWeight := state.GetTotalActiveBalance() / state.BeaconConfig().SlotsPerEpoch + attestationScore += (committeeWeight * state.BeaconConfig().ProposerScoreBoost) / 100 + } + return attestationScore +} + +// getFilteredBlockTree filters out dumb blocks. +func (f *ForkChoiceStore) getFilteredBlockTree(base libcommon.Hash) map[libcommon.Hash]*cltypes.BeaconBlockHeader { + blocks := make(map[libcommon.Hash]*cltypes.BeaconBlockHeader) + f.getFilterBlockTree(base, blocks) + return blocks +} + +// getFilterBlockTree recursively traverses the block tree to identify viable blocks. +// It takes a block hash and a map of viable blocks as input parameters, and returns a boolean value indicating +// whether the current block is viable. +func (f *ForkChoiceStore) getFilterBlockTree(blockRoot libcommon.Hash, blocks map[libcommon.Hash]*cltypes.BeaconBlockHeader) bool { + header, has := f.forkGraph.GetHeader(blockRoot) + if !has { + return false + } + children := f.forkGraph.GetChildren(blockRoot) + // If there are children iterate down recursively and see which branches are viable. + if len(children) > 0 { + isAnyViable := false + for _, child := range children { + if f.getFilterBlockTree(child, blocks) { + isAnyViable = true + } + } + if isAnyViable { + blocks[blockRoot] = header + } + return isAnyViable + } + currentJustifiedCheckpoint, has := f.forkGraph.GetCurrentJustifiedCheckpoint(blockRoot) + if !has { + return false + } + finalizedJustifiedCheckpoint, has := f.forkGraph.GetFinalizedCheckpoint(blockRoot) + if !has { + return false + } + + genesisEpoch := f.forkGraph.Config().GenesisEpoch + if (f.justifiedCheckpoint.Epoch == genesisEpoch || currentJustifiedCheckpoint.Equal(f.justifiedCheckpoint)) && + (f.finalizedCheckpoint.Epoch == genesisEpoch || finalizedJustifiedCheckpoint.Equal(f.finalizedCheckpoint)) { + blocks[blockRoot] = header + return true + } + return false +} diff --git a/cmd/erigon-cl/forkchoice/on_attestation.go b/cmd/erigon-cl/forkchoice/on_attestation.go new file mode 100644 index 00000000000..216b7c95f12 --- /dev/null +++ b/cmd/erigon-cl/forkchoice/on_attestation.go @@ -0,0 +1,108 @@ +package forkchoice + +import ( + "fmt" + + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon/cl/cltypes" +) + +// OnAttestation processes incoming attestations. TODO(Giulio2002): finish it with forward changesets. +func (f *ForkChoiceStore) OnAttestation(attestation *cltypes.Attestation, fromBlock bool) error { + f.mu.Lock() + defer f.mu.Unlock() + if err := f.validateOnAttestation(attestation, fromBlock); err != nil { + return err + } + target := attestation.Data.Target + + targetState, err := f.getCheckpointState(*target) + if err != nil { + return nil + } + // Verify attestation signature. + if targetState == nil { + return fmt.Errorf("target state does not exist") + } + attestationIndicies, err := targetState.GetAttestingIndicies(attestation.Data, attestation.AggregationBits, false) + if err != nil { + return err + } + if !fromBlock { + + indexedAttestation, err := targetState.GetIndexedAttestation(attestation, attestationIndicies) + if err != nil { + return err + } + + valid, err := targetState.IsValidIndexedAttestation(indexedAttestation) + if err != nil { + return err + } + if !valid { + return fmt.Errorf("invalid attestation") + } + } + // Lastly update latest messages. + beaconBlockRoot := attestation.Data.BeaconBlockHash + for _, index := range attestationIndicies { + if _, ok := f.equivocatingIndicies[index]; ok { + continue + } + validatorMessage, has := f.latestMessages[index] + if !has || target.Epoch > validatorMessage.Epoch { + f.latestMessages[index] = &LatestMessage{ + Epoch: target.Epoch, + Root: beaconBlockRoot, + } + } + } + return nil +} + +func (f *ForkChoiceStore) validateOnAttestation(attestation *cltypes.Attestation, fromBlock bool) error { + target := attestation.Data.Target + + if !fromBlock { + if err := f.validateTargetEpochAgainstCurrentTime(attestation); err != nil { + return err + } + } + if target.Epoch != f.computeEpochAtSlot(attestation.Data.Slot) { + return fmt.Errorf("mismatching target epoch with slot data") + } + if _, has := f.forkGraph.GetHeader(target.Root); !has { + return fmt.Errorf("target root is missing") + } + if blockHeader, has := f.forkGraph.GetHeader(attestation.Data.BeaconBlockHash); !has || blockHeader.Slot > attestation.Data.Slot { + return fmt.Errorf("bad attestation data") + } + // LMD vote must be consistent with FFG vote target + targetSlot := f.computeStartSlotAtEpoch(target.Epoch) + ancestorRoot := f.Ancestor(attestation.Data.BeaconBlockHash, targetSlot) + if ancestorRoot == (libcommon.Hash{}) { + return fmt.Errorf("could not retrieve ancestor") + } + if ancestorRoot != target.Root { + return fmt.Errorf("ancestor root mismatches with target") + } + if f.Slot() < attestation.Data.Slot+1 { + return fmt.Errorf("future attestation") + } + return nil +} + +func (f *ForkChoiceStore) validateTargetEpochAgainstCurrentTime(attestation *cltypes.Attestation) error { + target := attestation.Data.Target + // Attestations must be from the current or previous epoch + currentEpoch := f.computeEpochAtSlot(f.Slot()) + // Use GENESIS_EPOCH for previous when genesis to avoid underflow + previousEpoch := currentEpoch - 1 + if currentEpoch <= f.forkGraph.Config().GenesisEpoch { + previousEpoch = f.forkGraph.Config().GenesisEpoch + } + if target.Epoch == currentEpoch || target.Epoch == previousEpoch { + return nil + } + return fmt.Errorf("verification of attestation against current time failed") +} diff --git a/cmd/erigon-cl/forkchoice/on_attester_slashing.go b/cmd/erigon-cl/forkchoice/on_attester_slashing.go new file mode 100644 index 00000000000..57a4d5be2ff --- /dev/null +++ b/cmd/erigon-cl/forkchoice/on_attester_slashing.go @@ -0,0 +1,48 @@ +package forkchoice + +import ( + "fmt" + + "github.com/ledgerwatch/erigon/cl/cltypes" + "github.com/ledgerwatch/erigon/cl/utils" +) + +func (f *ForkChoiceStore) OnAttesterSlashing(attesterSlashing *cltypes.AttesterSlashing) error { + f.mu.Lock() + defer f.mu.Unlock() + // Check if these attestation is even slashable. + attestation1 := attesterSlashing.Attestation_1 + attestation2 := attesterSlashing.Attestation_2 + if !cltypes.IsSlashableAttestationData(attestation1.Data, attestation2.Data) { + return fmt.Errorf("attestation data is not slashable") + } + // Retrieve justified state + state, err := f.forkGraph.GetState(f.justifiedCheckpoint.Root, false) + if err != nil { + return err + } + if state == nil { + return fmt.Errorf("justified checkpoint state not accessible") + } + // Verify validity of slashings + valid, err := state.IsValidIndexedAttestation(attestation1) + if err != nil { + return fmt.Errorf("error calculating indexed attestation 1 validity: %v", err) + } + if !valid { + return fmt.Errorf("invalid indexed attestation 1") + } + + valid, err = state.IsValidIndexedAttestation(attestation2) + if err != nil { + return fmt.Errorf("error calculating indexed attestation 2 validity: %v", err) + } + if !valid { + return fmt.Errorf("invalid indexed attestation 2") + } + for _, index := range utils.IntersectionOfSortedSets(attestation1.AttestingIndices, attestation2.AttestingIndices) { + f.equivocatingIndicies[index] = struct{}{} + } + // add attestation indicies to equivocating indicies. + return nil +} diff --git a/cmd/erigon-cl/forkchoice/on_block.go b/cmd/erigon-cl/forkchoice/on_block.go new file mode 100644 index 00000000000..297e32855b1 --- /dev/null +++ b/cmd/erigon-cl/forkchoice/on_block.go @@ -0,0 +1,78 @@ +package forkchoice + +import ( + "fmt" + + "github.com/ledgerwatch/erigon/cl/cltypes" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/transition" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/forkchoice/fork_graph" + "github.com/ledgerwatch/log/v3" +) + +func (f *ForkChoiceStore) OnBlock(block *cltypes.SignedBeaconBlock, fullValidation bool) error { + f.mu.Lock() + defer f.mu.Unlock() + blockRoot, err := block.Block.HashSSZ() + if err != nil { + return err + } + // Check that block is later than the finalized epoch slot (optimization to reduce calls to get_ancestor) + finalizedSlot := f.computeStartSlotAtEpoch(f.finalizedCheckpoint.Epoch) + if block.Block.Slot <= finalizedSlot { + return fmt.Errorf("block is too late compared to finalized") + } + + config := f.forkGraph.Config() + if fullValidation && f.engine != nil { + if err := f.engine.NewPayload(block.Block.Body.ExecutionPayload); err != nil { + log.Warn("newPayload failed", "err", err) + return err + } + } + lastProcessedState, status, err := f.forkGraph.AddChainSegment(block, fullValidation) + if status != fork_graph.Success { + if status != fork_graph.PreValidated { + log.Debug("Could not replay block", "slot", block.Block.Slot, "code", status, "reason", err) + return fmt.Errorf("could not replay block, err: %s, code: %d", err, status) + } + return nil + } + if block.Block.Body.ExecutionPayload != nil { + f.eth2Roots.Add(blockRoot, block.Block.Body.ExecutionPayload.BlockHash) + } + if block.Block.Slot > f.highestSeen { + f.highestSeen = block.Block.Slot + } + // Add proposer score boost if the block is timely + timeIntoSlot := (f.time - f.forkGraph.GenesisTime()) % lastProcessedState.BeaconConfig().SecondsPerSlot + isBeforeAttestingInterval := timeIntoSlot < config.SecondsPerSlot/config.IntervalsPerSlot + if f.Slot() == block.Block.Slot && isBeforeAttestingInterval { + f.proposerBoostRoot = blockRoot + } + // Update checkpoints + f.updateCheckpoints(lastProcessedState.CurrentJustifiedCheckpoint().Copy(), lastProcessedState.FinalizedCheckpoint().Copy()) + // First thing save previous values of the checkpoints (avoid memory copy of all states and ensure easy revert) + var ( + previousJustifiedCheckpoint = lastProcessedState.PreviousJustifiedCheckpoint().Copy() + currentJustifiedCheckpoint = lastProcessedState.CurrentJustifiedCheckpoint().Copy() + finalizedCheckpoint = lastProcessedState.FinalizedCheckpoint().Copy() + justificationBits = lastProcessedState.JustificationBits().Copy() + ) + // Eagerly compute unrealized justification and finality + if err := transition.ProcessJustificationBitsAndFinality(lastProcessedState); err != nil { + return err + } + f.updateUnrealizedCheckpoints(lastProcessedState.CurrentJustifiedCheckpoint().Copy(), lastProcessedState.FinalizedCheckpoint().Copy()) + // Set the changed value pre-simulation + lastProcessedState.SetPreviousJustifiedCheckpoint(previousJustifiedCheckpoint) + lastProcessedState.SetCurrentJustifiedCheckpoint(currentJustifiedCheckpoint) + lastProcessedState.SetFinalizedCheckpoint(finalizedCheckpoint) + lastProcessedState.SetJustificationBits(justificationBits) + // If the block is from a prior epoch, apply the realized values + blockEpoch := f.computeEpochAtSlot(block.Block.Slot) + currentEpoch := f.computeEpochAtSlot(f.Slot()) + if blockEpoch < currentEpoch { + f.updateCheckpoints(lastProcessedState.CurrentJustifiedCheckpoint().Copy(), lastProcessedState.FinalizedCheckpoint().Copy()) + } + return nil +} diff --git a/cmd/erigon-cl/forkchoice/on_tick.go b/cmd/erigon-cl/forkchoice/on_tick.go new file mode 100644 index 00000000000..4f59528d25c --- /dev/null +++ b/cmd/erigon-cl/forkchoice/on_tick.go @@ -0,0 +1,30 @@ +package forkchoice + +import libcommon "github.com/ledgerwatch/erigon-lib/common" + +// OnTick executes on_tick operation for forkchoice. +func (f *ForkChoiceStore) OnTick(time uint64) { + f.mu.Lock() + defer f.mu.Unlock() + tickSlot := (time - f.forkGraph.GenesisTime()) / f.forkGraph.Config().SecondsPerSlot + for f.Slot() < tickSlot { + previousTime := f.forkGraph.GenesisTime() + (f.Slot()+1)*f.forkGraph.Config().SecondsPerSlot + f.onTickPerSlot(previousTime) + } + f.onTickPerSlot(time) +} + +// onTickPerSlot handles ticks +func (f *ForkChoiceStore) onTickPerSlot(time uint64) { + previousSlot := f.Slot() + f.time = time + currentSlot := f.Slot() + if currentSlot <= previousSlot { + return + } + // If this is a new slot, reset store.proposer_boost_root + f.proposerBoostRoot = libcommon.Hash{} + if f.computeSlotsSinceEpochStart(currentSlot) == 0 { + f.updateCheckpoints(f.unrealizedJustifiedCheckpoint.Copy(), f.unrealizedFinalizedCheckpoint.Copy()) + } +} diff --git a/cmd/erigon-cl/forkchoice/test_data/anchor_state.ssz_snappy b/cmd/erigon-cl/forkchoice/test_data/anchor_state.ssz_snappy new file mode 100644 index 0000000000000000000000000000000000000000..974265ff1c9d5a16168c108ff66a99b2101077cf GIT binary patch literal 173183 zcmeF)WmMMfw=epe2I-JcQc@a0Qo1{pZZK#8>F$v3ZjkO2>5%Sjkd!U~5srVJan3qt zue0{rymIqs8BA?C?9Fq`dP0Pm9N|GQum(J zG`*eh?2r*)EPp-qD9|Gml^PBT0tE+u0|j{n1#!`AI3aS78rD^03$zVA$i__ivikM5 z5zjh;n3VzBOkwB74)V$l^81^?7Z3mfKmZ5;0U!VbfB+Bx0{^Z88^6N@c;p8HKmZ5; z0U!VbfB+Bx0zlwT5x4>g;7_^gf7cKTUKbDm0zd!=00AHX1c1Q31V91+T~9y&2mk>f z00e*l5C8%|;7<|&3E)qf00e*l5C8)ImI5FFfCK;pfB+Bx0zd!= z00AHX1pXuekO2Oq+y1uXWX=2Y+z~*5C8%|00;m9 zAOHk_01yBI|IPw@zek16-s@Ki;G2N}5C8%|00;m9AOHk_01)`+3jFIA1Rw$YJ7>Iq z?$0JTIS>E>KmZ5;0U!VbfWY4&0208T)DZS}`~-oTKmZ5;0U!VbfB+Bx0{<)lkN`je z00KY&2mk>f00e*l5C8&yk^o2mf6{ILv(hOzEf4?#KmZ5;0U!VbfWY4&01^O506+i; z00AHX1b_e#00KbZPZ9tL;7_{kzav9}nm_;u00AHX1b_e#00RFk0gwPd0ssO)00;m9 zAOHk_01yBIf06)50DsbL|FhC5I4uwW0zd!=00AHX1c1QbApjBpNB}?p2mk>f00e*l z5C8%|;7<|&3E)qKf|@`82mk>f00e*l5C8)IECG-JKmq^)KmZ5;0U!VbfB+Bx z0)LVKNC1D*ZU3{f00e-*-yr}J07w8p00;m9AOHk_01yBIK;Taj z014nvy6wLsLxP$>00;m9AOHk_01yBI|11HJ06+o&0zd!=00AHX1b_e#00MuK07w9T z(ry2<(kVDC5C8%|00;m9AOHk_z~3PN5&%d5KmZ5;0U!VbfB+Bx0zlwT5&#L{PrB{D zBSV6kKmZ5;0U!VbfB+Bx0{<)lkN`je00KY&2mk>f00e*l5C8&yk^o2mf6{ILv(hOz zEf4?#KmZ5;0U!VbfWY4&01^O506+i;00AHX1b_e#00KbZPZ9tL;7_{kzav9}nm_;u z00AHX1b_e#00RFk0gwPd0ssO)00;m9AOHk_01yBIf06)50DsbL|FhC5I4uwW0zd!= z00AHX1c1QbApjBpNB}?p2mk>f00e*l5C8%|;7<|&3E)qKf|@`82mk>f00e*l z5C8)IECG-JKmq^)KmZ5;0U!VbfB+Bx0)LVKNC1D*ZU3{f00e-* z-yr}J07w8p00;m9AOHk_01yBIK;Taj014nvy6wLsLxP$>00;m9AOHk_01yBI|15$3 zlmNJ)AP~qu>otJW0s$ZZ1b_e#00KY&2mk>fa4&&||M98+cMQNk6QYHj3De%-LT%te zo$~3QiO@o-n#J*o8TbdeF+a)fKjsum+TQf8h_8V3EAwo-iA!I~nz^VGu|OvmLCS*Ln)gDfy)^5Z#I+DwY049DzIB#y**j#$DvS*A8|->4n`ddAja zs6nRX=#|5J`cpY}Mqf&S*@Lu_9beBxSkk9gAkYwrCoIA|JIz)$skw0h!#L7NPax|V zQxp3JO_RbS>@#ZG3DFG6Lre89g07b(k2r@vYLFq`yp6DXZcqPKm zO>{Zax9|?hbY6ba@-dc=iN)nnpN!fmmtiYP(wivln|RF~BvRX%&P1@C=Tw%ZIjM&9 zS?kTN8hxPqci6@LchcC)zWyh-Nt${IKc!%%2*_%3EOod}nP?uz?nAlxrrCrQS~e=~ zHJ+5wVcD^olX!6vORAFZHnF07LECa^!F=KN zG$TBLAd$16Eu3Td>o!+cY4N*dD@JH2Itqd>-IOTNo)!W$Cgh>I-o785S1);1ciB}J z%!U_d@MXGk! zx%&j)wpp57BVzOhZE?hm>r+GnyfVRT^J+^w)l?*{M}gg+8I7`qaW1j z_T|xAFRyqLt6wxX#%(SSigAz&1(z37#!zGLw8$cw9t$|nIb77?@go#CYEFEMn6G$G zszlvgKz*u9TG_yfdh@B8_-dPEjPWJ4ZBHsK7Ds`4O9#JF!Aw#EhxZN>dv^BLY4!z) zudbLP?ZrS}Pf3tlWlWwfw$96UwQ8Sc$R*!Cf>BdIXAnG94dHjc%18G%5zAN$3i|f5 zIJutHv}E*$Kp9D4tq(c(>V^Du9PL4Kr)a3BN<^Vy6;t1v^V+^p1An=PvpYJK23JxA zWA7(vkj=8jr_D=}%~4;o_~nah5&3Byp13^eON}stTr$0n+3Dw=NBT;w&aXxs%CP*l zS>|lG<@?ih4klD`cJY9H^rY{Y^g(XPOeof{tX5iwMc)S&eiSK0LSN3w{cM?yus(C< z6AMc+!!$F+mI*g_Wr!-$9z?KG?`HxT z*HBsMRG9|D&u7kNVbSwt@kb69^4-dLrZpT$+f5Ps?YFw_+`1C%C-Pevxs#o$Az{;` zsxJ<>p;ns@_)57y8uXfc$;dB-p6IY2{e0Sj1bG(557VKmLu}fWsJU8O)TT@u$xqNH zD^f`6twW8;Ay89P1M(Z0bgoIUX%1) zzV~?qnM#PoJ@4VmpLj%KT%Bs*%~2eo|9sSfbJbcHlbsRk_Oje}e93^yw|=Xf0p+=o7ej_h4QywP_iG??-D3PhzC){H&d}CIcRKE-9kP{T16`+ zOIB6C_RpyMD&eq#G4D<{9;p|`Wxq7997Y(*A1L^eQmGV+xG>Jzla2vStiXP;Z9)aU z44Zhuqs6hcq}HOM7s1q7jV3LB$`d}35%Y#D;b@s&dkW2@1hJj2h?uW+l@bxA+~KhY z>_J7bJDCpC)=mB8u1>3}lr|=9rmq(vQbCl3Df*jEc^+0$z>d{p zdh+fED?u-$h&?&uu)4a(iEV>Fx_WGFF5>zIoE7Qvq%jrt&ZEdHbQ_haI#eziQEjiT@qA@r!uzaRb)|AXmhX&vyJq^uH@wbqy!`Wiv8DpuA=`QNqwucnPVAL4 zCoCzniyChWnLrw>myoa@{qGJDj&MAC2rZLH-v!2}w{2%e2JeRMd_d?fw#gqE#UGlZ zPL?HmHZ^OOs>tU@jw7v1NTc-ggNAIdOcFCUwE4zm5^+GrHpwTtR#Y>ml#pUas+!u; zQNrxKdJ06JtYhDcPo>?+^qTZhTZLY)Lk@Jv^zZ|&+DBUkF2yBK;t-Rvi(xnY#%tey zjsN%|Z~Ym}=RK3z{A86Meg>40^93?f(AxzC&ox7an8~3o>Xvr>4K!l(5K{O8FH9Nzc3&oLq5IukXT=|aujD5d2O)Oy=h9VOm!cUQIcA&(e9K-KRa^kq1-c4l1M(L+b4O&9NRZCyAdrW;5-njbCX8f za?qT=?22viw(NyYqvoRU98a`8@0OkxvtVk4x-qtuo1Cr0XN81{A29mKBGwr&Y07k$ z?i}wwS$WGNj@8Nc;N+>P|3ZSc))Y9(oo#Xtf7H{)k0|8vJUae?t`=^|*Eo8Ydd^br9(|Qobw6lY&_{6coEI*G zfrZkfQ#Yw`hkPUS`waO$e2FTJrBkLHA5pTGCtqa{lh?qciiXrt2kWH9I_G?OlN-Dx z@Ob>CFf9I!ifq*+aBRv8^@}sAl95jb}1lmY>4;S+A(ts}^wU z^ExrZW_$Me1{-vbu|Ljl9cDg}up%3n#@rLZC`Mt1-?EnN2+XERUvZYP`!o=yBs09h zUnDy3>DM`kNsUXl>z&*1OksfXOQ7*IH=g_Di({Mk2aa60$Zv5nMo)&A;X895qY}bD z$PQthb*7MTD;54!u58n;xN4!@+0gK^kC7Nk-aFBe(@t)6@%;T4r%p5eV3}lAbd${w zkg*?_p*34!{0{pZbA62t@|k%$ux`*7wm}z$#wW3a*N@5IbY9Yl?ZVh2YNx-$SsuD+ z89U5QaAsI#+RyljIchvO+fznL+9}uU(r9gIX0rLTanfwO2CqMmbN1mfq|lh&5Nv0O1E`;>JB$B!$u z_~FvOEFXR&>NLTL3@YC^F<$F6G#mvfS;fvAsyAApd zybhFaI8T|a9Q%y?PIU(&RBNTq5fKr%k;78$sW&#SLNJtZ%&4-Ctu0S+*=1}ztHRAG z`XeS*?~3T**N63AOEC2oo_Rfjc_q*i_@(oL#@>s=?vvm^Xq3MTnhx^I;=zW}Qf65r zy}~DBbOUZ;+d{jt0nc{wo|grZR~1lt=O@5hboJ)Z^0%gXOh;M1eKjt=0Lz_UPE}yo zSn$=3%G@J@`MtfP&-56aVV;43bf>4?z!gK7w?R^%bA<_0vENNK`eQ*o-ikQ~XCa}~ z7qHr{7e97hwy4pEzpH!h#MQy%5yKbU6aKNLHu;g3!X8f}8Y`TA=EEXiG(7^OD^2C5 z85CPNn3sNh1s3t*2TAV2Z-T4YGo30+2Dke8_HMl8uyA%t%1~RJ+t4QyPgs&+`3y2s zZzpam-Ei|ppfNhad?uZOPA;P1$>S>MtHQDlqs(BUA%=m7XWMo&4$oo=rb`pMpwF9m zF!DaFGzJ+(UAv7&oysIsgs{9Kl)#Udh*VW}lu_~Rv&R_3}iI2q-BzGZw z4(3%vtY3c<9D?$}P&kag@p9}z<$?AwZE;GMO+|qSE^k_#9T)xjaT;-7Kc0I~#Bm_? zSs=&A*!fr35(>lt8b8CDjw-I z6h*oz?Lj(!37z)938EFvUR>nIP=uF^ZJ&M?RgR&1>zvnE#H~zm*uUTJEgI4%I>l`B zlXUR(@~}%(Er)uSs$nLZ(M-l~%&*{N>8zgh(V*k`s?4pw`sOn9=k3ynuEmJLcl<{7 zFNxijGd4a9U+YWYOn)i}c-8($0m+5Fr6)Zta5(|%D^IcmXGJ@&kxtC;i6Zl>L^h{J zX_&)4tWQyKbqT``xf)(SDk8@CXcp8bag3ch{Rv;_jr?IEcIm8acpthtzs%5ltT@mSgCBp>847kK-E5hgU8iEeUr2{I&taBeQMabggk zd*#rNXjb9Z%~ZANWLr?!^xXQj=+bXV1e@~ZmkPtn|Qa2oAR(H zebK5_^C&NVFqyp)r8k23$khy=casW7_0>~xO;sFsLJmD9$|3|Z*^m2)2 zRMng@?c9Lj>cj|asQx9QvD}kbe^iYit@4((rz7)2G+wEQL4Sw}lckw>{OhBhEAhAR zsYjxhMGFc~9tXavix}MHJKeSK6o4;7<9ukgpFWj%)xBhm{u>0+3yF7r_iC(NnRd}V7!|=S&GVWP5w^jjfI1in8=40&mA}Ivfe#zCAa1O zXlRc%{Db!W_O{X7S(tE%B?X#OQUM=lXeAsy=0r`=3U!^6{p&c?N=HrUvumOir_e2> zkfZ}tlY^leCwu+eEhh79C3N4;QP;3%sr^@Q(efimrldA9fs(IBXj5qu<3yBFtg*&8 zy)n5_itCYLuAXz&aikp!vA-%5Ha{|?vt@Zya+=hW)i;Iw80x0s_~Km^mMdDQIsViP z!O{7&2jxKVacO6`DHXJ;lw+De;0!wZ6n}K<5R1$8BT^UD<7bVzaE=rUY(r;Xw%iGr zGX%(N{JEFd*6D?Bie?^u$04$B#%)yeSlRcpqr-y5yuEU%e>H?=plr0AIbjKP5)t6^ zbLtaMXzEWWOu=Mcs5tA8R|m1iM$dkB64&n8m{zmRPDH62Bwu#=i4jv`Jq-Me$*hq%+;Fa2tv?PSEI54L8HW7kL9xwbRsCSFFftju?92x z)iAXh-^7%*2eQAgf7dLS6s_2}Xea77MAfR30KcQ+?F#eg6O#nNC)2>5zR3}zZS@<7 z{ziT+oFCn448x0aq3VZUbY{P8u!hQgkJAYEx+T@D4XQl-*_7^Vj|X?`TxBKksHQ_k zthA5i17zuyG^YKPd3V<62l)EcN$Vowg@7O@W8Z~Zoh!J80&7>}B&5-|HSiZ0PaQ2V zOkduHi2tgUawWI+TiRLJ=%Lv@jCmo zp{Z`aMtAtO4J&N4iUE8SbkQlZ0Y zt3nK^uq3)>xF$nnKaRF?%X?&^^kOk`rt1gzJEeu8#wbH7faZtT%aZoEE$Ug^-$4e72TLQiLfmS(cWS*9Wgx9qLvOl4=xu~Viio5$67gdg z?^D&I3QEH8&}B~C^B{+jSvZu?R?4y2HfDW?@iXz69^{E&F5gUa%L4`1e$PXUDQJV4 z!os&X)_ptSvTwu!5Wjv`$QMP4Bb#H6pn;+k4rh4Ku9i!?8usCH7@><$d*a8JPn*%@ zVn{d;I8&;jXe4T!YMl*dX>BlrUC+@G-SguZ!rTv7_oCL1mEMk%yFB$jd^VuZ9|ldL z)Hm7j&QU)C^85kUdzB?f@9M!O-IHR}$v5Iti_-f8Nd&U!R=D4m#2y%a+R3!u9+`L` zwc{EF=N;`4J{%CdZtqSb=7H?xiJd%Nkh%|dkpv&FnziXNRIsA2oBYuk4fC>*Ut(GS z`ykZ!LrJYs z?Ij~HR0~5 z8)wQ0$sM++C+fF-ymz9u@L&UD$QY z$egKa=;(+A8YwywxVg%-C5`0Gb-^k(j^R&S%uNeoCf|;d*-@1RsHV)t*<77&U2^Ip zc84q=N=0m>^2`N=i|R3V72qsG4M)zU^u&o>Uq2b}$&;G>bS=SW()`YOI-h5jaXbA( zQ5MXlySl#4_?A_ScN`u*h2hWDhq$3{3<~?IwX}?%qSI;6p5tERo}n6Ois1@6WZ*s- zCBQyd%C3VLg;Zn>F1%H=LwFQlhyfdI@G(Bc_?v3zZn8STamzD8{`NDQTH=dGb_zrR zd#RIMq1Y8L74Q%(^NQW8a>Fg0hCX;TYYA=AA_n72uc~*i@kSV#Ti-Qf%&igOHN)n8 z8EXtd%%M?*a-Zm}{6yAYcNYFJcF3?Z$H*F~g=2Mx@YSU;S_^X>)2~6hF+1xSp>LW# zBj2oe4U1?{Muoee7LRNCQLKMH;9cKhksK>}`H?j(SUlgpHf*w|=;#oJd-G91C~Wa7 z!G4tJgy#;5J}qVBj`piG)IyEup6fwQ`OW+91gL9Jm*-HIl@kr8m?rG?0(aLCFGmis z@r=nBcJpK7%CRO%lD2b>P8=R6vTE{QdfGZ6(`Vu(#g4Z0K+7pnq?^mf!H6KUYtDbu zK@?$Z_rTRsP;5s_IURlZzAsB*P@{U;0b^xE+ziP{amq%FIR-^Nq>Fk$ZNQanc>zwl zG_t2LkX(yfo4e>Nx-{-Gwd|1A^7%7P&ev4?Z^Ygx;FvsciW*8HY%0_!xQ7TsQ(avZgFt0>C-jVLMEGBPAW{rKa(6Tui2%Cqk-2IT9JAaw; zTrL6a{J`#-q=Tito0)w9q0TJf=?~;jEo$OTwK7x-Fjc#-y#Xg^=0cs(SOxR#EU%VY0JS7(W#eS>zE`L z8fS0am2rUgQ9t z2@0nBl11u%Vb$IW-i7JDAP-ALi^~NgXV-2i4g^Pe@ab?_&-2Hzu;O8L>|!H&h{MTy zmwM=`WyQ?~3qj*KiHAQPd%U-My}$d;HXy_iO0bq;*X{J)hOGz}&ZFjiz|cr%>pEnj)BnY#Po!dsG5#e-IbLK^ z`!DVU2#)77`+#CtWC8mQ7u2#4>&!Oe*N#W58SMHqn2D7+ek%M@6<$SA{Ij^0qTJFe8Ao zM`4l1BG3HS zxLwzVlP66YDV+8rX8AxDw@`@)G5-qW`9SY_Eta4hE|T$!s{#APmv-jbYXaraC*qWS zp<@;kKNBA#rTFxvzcmlK%#2KA^N$-)Y=1s5n1PhaYZ-%O{@h8u#ylWhBXRn9V zuEUhdJvMOk@5*iluRLFLod}^M(GuR4XpXyaJ5kA%bnMx;5s@%K4PnEQx8&tFHQ_#l zYfwD<=}Gba;-^1!c1JN2`632lyl&L2k(ljX#S%trBw9(InI>e>VIV9!*EWKXx`$aG z{VB9&eSmk4X8BbE>6#E zwcig`=J{`>!s>2G6)Xv7j0Lb-bbLiJ#Y=E^`2D*DcvplVZp7Nz4PCVGtVXp|Y^W%K zCW17iCoruSqdMF1Q4XCKaZiNNu+-3b*1nYmElWT4()f(^V8icltsA#0O~7xP4)(bq zH?|W?<7MPGU*dtwDVhDO$z{VSNb1+Rb=aTGpUzYsB-sCA++6&`zQJnDc~+PNEuB=BSCVk8 zv1=G_M;(~7C|c*8@YMi*>RM&q-kElg-(OBY)5!i9njl`{j}V^)8XfnV=X-v z$PfDV9NfQMIdc%Wz$R8A>?91Fc)S5W>s`TY(A#V)OFQ-$AK++T=PgU$wq z`z+hapUfXy_dj`BRY>TnCI*pTHu5uOXW~ zT5sPmAJ#J{D$6%@CC;j6&S!87ROH#=c(Ycobv4~Jx@AQt@VyIK-g=5T>zqC{`Vw`E z&J!-@#kE-#wBs6DL2B4|6TnF4c8$z|y^6A{*W6^!NR=gtSSe(et5?CXCd1 znzxvWVP?_KUIIz}z2NMkgOyybZ63+YP!G1LlEVz!ocHNTc!(44maH0okKdQFbhgNf5afo4TX?y>k!vOYCY6 zCv=XcX|$_(S<}lSB|h&87GfN-WRvu|f_=wtP6_r~9t~qop;^6q^=&!R+fSaSo~I>0 zulq{SSmvn@Ba9Q$p4kcgvZpr}30?9cyq9HKnN$8ND#Vv02-z!l+5kG2u#pFyw{|2} zp&m!gc~Sgf|Csg4H>E=Msn6BnbH`PvctJt5|Nm@Oq{t1 zudCY=-ovM+i`DV1xEyX1udWG{-r!_n~!vdKEX7(t={RAqxgfuSI{Mj&WK?Rtg2C zUMSY8S9BbAiROmGtX^3MVa{Q#ciscS%QHS#h9yqZ9nXC6b#@e8V&p^E>-{-Wn{NyF zXeXmHkN2GkH3CLTM+ha0sy}*`pp-DC$cmWSAUz>ZAa577mD^W4D41j4PLF&kS{@Yd zG=y9%7XG{sZB?lKhiM8ZwY_!IXj<+<{SEi+LZ-(bwxr4h*jXU|YX`6naA zA#C3>lb7uSGGCkp38PvleML$g-1zXurWMM2Wv$DfxK_qJIEqU+PtBhJ{!uJpg8uQc zsSL$&N3f=HLdo?M-t=|cjz{@riXg{#%Uq{l%65#KRQ{%K!cQF(hH%xPj%-Byzh$!W zyb498GIUDnFzU=Nl0>(7!;M};o#Ke!Vd4*iFhmlIk=Puk?V~(zPtBj$ApZ6H+qSAn ztJ)N!t=w8-)8%%GTX@{!N0L7){HL0!Lpx(1U`CeFUZlWAgs_TykgueXR?hHSv?ePJ zoA@lZ8d9vn6*sWlIpChNn>bqk#AkyK0z2$F7On(} z!F57hl*sR@1=B`PU7?$2{h|wgJ)meZjQtKxo5eLAnh{}IETQo^*z8O1uLfUShvqd! z!z)VbucFGF78c*w6a{vwEK=rfJ5%-)CbB5sxP;F7V0*6ZrDppDR*LN56M99tXBuNh zytN!beioqVm;B8oJ*_Etbgnm})iA6Ry0Cis%ar)V)mcK>IUS)OjyCf?kLA%iQ)|FQx!W>f;Dusvm9|opl(${+!3M@cPGqgTgM)m#UZHk1#O0DJlGnDWZFhQ}c2T-eieHsQ z&s({7Oc(|E$*0}Gm*Uqdx2h4G^a6SpFUWDSucw)6x3-?-Z#``ov}k=fXWwbuSXuw5 zs$`tgZH6-(PU$s`??8>jVyVr>btcA=XR8%oS$^LhWN=7lh=$c!nB5zN`D;1(Gl+a@ zzsIQBjh34UdIK9>RNw=h^!`~RM&}gA<4L_HY2V3STN#OACyZB(9OeQ0HS62d1(MkV zLK#R_S_)Tcdz`E}w4@4_ullitJ~sB*i2LM9begZ|oJ%8EFTVG743q7rZV4G6XVKh8 zl!_-iN!^oqejwVQ;J6sIIV5Sww_}dZT!BJKA5EgKYt|Q9yYQkP9#@OgV0?|ieK?Vm z51Q%Hm04psxoH{pq+KEj{&HrWB^EVh@51*cvDkZ_x#h+XJ+cuaRh6-)qmdOOlE79k;QP ztklVu9GJV@*~9xf{3OQ_Qj5>HY`D}=Lh{bL+-smbBD2yc<}7mc%Xg+c+O$wN1?Li% zhg!%FP1g*47fr-{vt806v30Us{WTmlyh@%(L&l9$%g?jQD9-(wzd{EiG)HpLkz>}2 zmbQ--vY8Oct}Yfm)=hRpEo@_x{mPQvh(_E)T3zdXh&D$p${@h(PL{xuCdOi1aP>&fr;$5m{(k0{eJN=m}Fy&rZNbt3-$Ve6)q72UUIvg!Ezq|V6F zPy5&V$fCB`V+-37WtZt385&V^{0Yas541DOo%0objJRk@TMp_|B*NUh@>*F@USq7; zE)?T2p_&LyQcb?(G8!W_zV8!Bps^q6lRg#Y-4zbj-)Jr>E>n>hptrVi}}iW6$LW!abWBhfO8zW+G>TB%|W8Wi#OwilvCr z%eA|B>uhE9rciHDEa-Wv_|~)u1m5yKuB`l;?7+7Y+``N$iF5VS4{<_<0|M6(?t2rm z%5c6cK~v_{cH^wBIqef~{?=RcEb|%Jiv>EKFK6e(#uIKd`|%&?B=EHoJCkgz8{s;u z?f3`~&2|o|Nprp4)!f^X%J#n+>UAJ5<>YvX5R%Tr>C$#Kq3*Ka3aydu zTK0gmUir&+3;uu@zebvMT2YL~)G*>VoX>CNscq=ERBCDmIEXN^l^Yyi{JI*FSw;Co zz=EcN8DCwgL~5^nEKD0np0T#+=a=ko^qP2l#dPMea0J|$q=b8&bW^%I6h+2Vft)5{ zE|hS@*8AsEi+XOZ3kkWXz2Ql=xW8 z{mgT>5xP3noJY~t+LGY3FB&w5ET^8PF#i-7x08L%VH~2-&AGf1S1W_ADM%TPPP#%Y zPH>)76q2+Vxe<;Jnc;VrwBhNX`w44J+R4Jf{Y3tyQO(Bg=RCgph=L~rwb8Sd1M3<> z?hjedFLmA@lTa z$J%dcexAaF$hwVv5g}XTJ14UG5&hN~t777P+@qHfd~&;{-}KbQ5Y0KySSG_ZPG85_ zw++8O_>p9tt#2}-98}_L3vc}4b&AWfao(wG96Jl-C}v5mRj}Zhtw07`;TqZL_pXx6 zi8C{jS{ugZ90794^I7X$e0tNS+3&t@J_f&&hMftrO++y4W@;fl(69K+Z}`33tB>(j zm`QMQRtXgMrZ=8?s+)6W4$bZdsZ!YBY$w0m5sd3ld-D90cd?jQ`b;DS$1uh- z3VLo211(Z1yXg7Ti;9{p{G^y%Aq~Zw={XT#4ymHp)j< zTkyF)(9Zhk%hIkls!O35CheJ;5VdOSd0_Yii)(YH2t%;N_H-40_onn~pVL`Lw$r1X zRmkKg_&1oLmHm?cqClECr+`WGJ;fvukIz<&@_oDt%n6tJHItHQqLA#nhk1?|QEBb| z7>V(rY*Bnq+YET*^km5iG-1T@EF&if5#$jDpD}E$G#w?d+1tCI)#q<(;X3Gsx>RBN zqV-u4G3>=Fu6fOfe!5vE344hz|3B#e2mSw`{~z@KgZ_We{}1~ALH|GK{|Ej5 zp#LBA|AYR2(Ektm|3Uvh=>G@(|DgXL^#6nYf6)IA`u{=yKj{Al{r{l|3B#e2mSy5=lB2D&W^Rp+iq-Mgs>5KPtTqSPNWfabMWm6eKuHEm-vo+*e>@a zFFw2+PpnFZseot#d|u%H`MkglvmW>Y0zd!={BIM8WY(kjkCgziEe+w2&lxrGa4&Ox zpI6~-oN!Q;4w-+V8uOuWu6!1WF6s~n5m2{5kYjCy-2Pqxb0~k`d3z8Nq&;RWgf|nG zk9p=OPoSQ9P+x2Zg`$kkH+Jb+^Ezib{w{joA!87ec`0Iou@vSKaO>iyPt^Jo2QEIelO8)N4DE=#OqedBSA$XNj?7V0Qa3G z56Plt-x>k5gHzAS!Bk zdi3nQDB!kM`MFVj&Z2A1KdU8|R9&y}16ze&6h)?uAfzc3lGELUc{+bFUAeUtSN|Lwm9P59p}Cu+=T@0 zJ_u=T`#8_&*za8{nu7i)7wZiSF%g>*N+jm@O}XDing2h_dxE?=T_7vWx<@a@&7$S~ z#J`4~`VEs}NUPCc^`#EJf=SSnHoZH^eMg8we8Lc4tc+aV^6@_v!eW=A!P4CMRk^Q# z_w|D~6?ycPF^-C%YjD#siDP2-jFR zj#a}VkukSK5lBX-?CBw*&nKSj-f zijNzoE8VwSepmFqGm{_-m>!B0cA4gN-+KbcV!uy64mdU%7WnL@>~(D*zEX5o^uCK2 zAcBV@gd7CwK2@q_d9Ilc^1k6%_S0g!%%5HjG3ccE-W9#?G!V!#tD;}81*5+_EowN9 zh=H6Myq4IC$g-*(B`nl4AE&#b_Z_(b`NZ!@ubuhRON_9Np8YBjO>$4YQc_tBer0u- zsKn*3f9?03Lko%O?aPIeF7!?G6&k);pn|99v<%v}adc$#dvstwgMN3?`wp9c42(te z{vjq?Mo+ zFvcslzD;4Z5i!w*E&VP^@gGyeWAPeYAYWW!GwP27B0q|BzKhW@>JKSgOGGn-o}&&+ zv|I1HzB|T!2kk@bz4<(TEb_D$9I4u>%VO!tE6zwv)V&Kd{50Gl6{&q!^uF6dP6U$)_)gt z`S0e|@D=AdKzP}YWtEf_%i`w?xS`)Hvmn}a)zQqyu@VmVazBa8b;X2)Hsl7lK-N;& z5v^ranI0K_Q#&EY4vN*0uzD}UdLn@{byJA$k$L?4nfShg`5?59zCF3jAe<|MldGk- z4GT`+gE3x9MU06jHSpaw{p*SAzSCZ z_*Jsx;S`sUd`g?IBK{uA#;-G$iG4`3KEWpIcTti5JS*Rhwe|N?eKK+>;+);>n-lwz zE@uUrn`)DF0VK(BrVj{$Lun>=$GPvC2}mV(Y|olTp7fmDa$kC*Wo>;{X72tYUK!Oi z+2eMj)rK*4bKY<>#vz7$kk_D}R)D`s5-@%pm$4&`B)xemtP5Q!jlE0wt zIdBb5ZEx}T+xQxW4`(fdv{hSXZle#3ZkaAprn z5l=fvx+?G@m|FRq;g?r6uHF^y5z1S0A8=7qR<9o)EBhQqP zcN%SWt#$8;-gn+5gi4=zq+P{D-wo>G75rjF{dI!qs~wIZJ7H=wWc&KRexmO?bQ99r zd@3dq7|g^=p6;DA>Q--Su4Wt|+$?DM=99`&4$EH`bM-!N$=Ye?~2}c92*3;dA>Hyl#QriH+-b3{V?p^O-E#G3?n9L{FD5y z{=ee*eP`Z7FhpvHJe^KN;xuP%#4)6lEOnOl`be;na1r?Zb*y9VPI}+LN)TUvS}cEo z0ztM2d49v*K!!7#m@(*C^^UXQB_#BczaCZYJIx<5G*&qCkXeJRkjBUbO;>TCzBHzUgx(T%{@AeLMZf%P7DnL} z)(P%j+kJ=5L#~6#`(_-bl#m<0e`bre=TGnVq0m`#gtHcy4#IOG{#{hz|94T1$)i3O z$l#cD_YA3l5^Tgt`!> zMen-=7D6|Yb^SxksD`cmu-p9vsZv6JvxlYeV~!i5-uR8S`R}3*|IK0-q2HT=AZwl5 zHyo>b)DpND+RWVFnsx`qgn#z#9SCV=E%4Xf{4Nv!zc^3v30YK-b zZOggYYNTkAwP>x2v7CFCPAImbcQ5t6`>P=HWt$44J5%FYWS1%`nP@mT9|%J$w>QZ1 zqD8tgIE{W6)%!1Z&}tOVJ3u(8UOXE}nj|xCrZn~8o8i^Xd35ayYODIT-KHo)1c)&D=c@-giidDH zx5P&}B*nicr?Dz%ha}wVaR&B%)}`_67Fa$(w4LaKZ|nY@z;9@_uaS#2{7yR4}a-k znqB{y0au<)$VfDtwy8#k*Q<}C_d@bt?=558ZN)BNUUPv|o{3O(Ei#*zy9FE^Y_HNU zA(+^dUce7^2mgeMNB!4(mK6W7Qa!eQ-32n8aXr!REcNj!LeF|;jwAOAl@bJLa3&@1h?6{SHu~-~aNWCbP80PbDI9NbSZMrA0r>#&LVR^Wcs< zDovto%Z|G{-F>&ALiAq@pz|`;V9WVgPlroco9=O!4!_Rhuouo*e3eA;=66w}|9S%Y zE6Xky$R^ME?dkTkW~0aAp6G!Oy60e6><|`SzlAP_P`~59o(XLK=Q~KnXny}^!5!^S z^chXJ;G5GI(YT^7Kl-?)PRz>R5os2EoI4aY{#^w>{KPnxc_KJ-W!nXE!+3!{mG5gr zWGZ0=^$~Yp;pvT~IIPqw4J@?EgP%lq7Wdt}39${=N`FJG%C1-7G4f&xY0&k>q@?-; z&zGmuRZqWsp}Z@4-*MHD85;5q6G5%2BIFqlLYzJZT2?4hq^8ae{372y-{!r$qW9ey z1v%)yk%=@?kaBt8{1yF*c5X+pR8@&gV+l(%gU3y=`L5`F7Y{+YA`8pmzgJB_r5(K< zd#hu$kZd;4TetG||0?dSg5rw0h1-n=5AJ~w+=2uT5Zv7@IDz2q?(XjH?k)+g!8HVe zyL*5?Y5s>(_uO;p>xWyns$YBbT)p<*%jTY=AAeJ&F5qQ!2KVg_K%upE+1BCaP-uxT zWt<6)DF0-PD`vy>Ct#lo8z~9*wOYEOLT0Wa-#e zc)l;|x*#aH9$0{s7Z3`PL2z={+KG8{nH-9Ymg32&@*`+#Y~(}|a}1 z6mt4Sqlxa&tCm=uApJAHQ}C*s@s;wr_wZdC|G&u{bWuwqS(`g>QRpemFRiOl9QN&s z2E{>&D)!90T$sJrT=~iGvEdTb3UECS0KV+NTLzb@#67WyuQH8PsXlE`C+CJ~gWYFn zf-1IBASk%|b0v~;<|I{3l&ya%Ns%9cpXPrEvItU7GMQmWpe7!V? zB0SnW#?*vpIPQe4ak(k3aP)^%>O$c7O2JF>!PM{q$gxcFwTzQ}!%fCKrp?!W9wwD& z-p)CWnNVRXP#c{fD7dwS0kP4e*m5p;hQPr>A8y7wEjtAZ$dR?cnQhwULwO%%5ENWt zC(s4xV#thZvOhCg$!xJF9HhM6Dp<%bZki=;f4;+C071d6!V3gekl3!uPe3@Irz^cv zK0!IDtav&z9=bTN?XVs+#{faWRn-8qECa{NTo(8fL=t+L1r8mQW4cEIy!}pA330Sq z82^?6om&@wS2cqt2b0n72EXw#^_&SQD4JtdALnX(*Q>*MaEv^NZ2;eEYT!f}A!ewg6(eQrbNY8I^v9Rvlp5I?|u%kt3glQ3L%mza^%vLP&v7JEj= zo$g9-cnI{t{!8vaO4uLes>J+zN&I5xg5$%jsVFKan*{R2vy=0sCqy%bS>hkdH|-*5BX5l7bIh)AW(wM#q>^c#2+#FM49~JA3FLIAV5%Xb=g3AxPgD^R~>bl zYTI8y{Xe>~j28VCixn`6er1>R)cwnpIh6(1!3tzcS}49(sFc)^9vve3vHYdZw60Q# zltLQ+kRFH@{XsCwYuspVUuMK|ht@;0AcF#~k%g zzA18cWKOSn67#ePfe>s*W6)U9N!qQsu?InYO>l4)%|9EIF!dh$iw;9V^d%6>n+91r zue4)_wDeA>W+UkJKO)Dn;Y-?bGkVekYpH>MHfx&4`AQRlN1&x1w6VD@xV-NJ64%4% zZf-LFLZhQTIUlnxkF-0><`!u~dqUpYhu#_(T_h6zAs~U#R;Cp>gmQwTVeNJYyh0$L zY4~G1s29KWVy!Tj)FqPGN76tEs^yIG8d&{1qC1uKX3bB-E!cj?sj#DutM%YBVDck$z-n0e&h~(-m~P3_onfcCO2374VR~HJK zrLL`LBZO49HF}#^I2RTt%vh_bm#YR`i3~8X`vbPZ#*hB>2Oggf}8BQO|?SAaDpMMynIXy+YV? z3xQa+NKtD*U5;_v+1sh;W>x-oFT5e-E%W1*;6h|QQJeB9R}fau_H-Hqfq*HPY@JbStC%4?$@M7ee~$j zAw)0dfqmn+Fsxe?%1=0`sh`BViw}bOXdz`qGqZg-MZ)mKOAGfSpR-y@i`&8UvN-k@ zlhWxu36mu1@0Tq@Aw5g(JSo`+j*RN23D*_$FrUY$ly*1++Mc+R4P<9jsjjcamB;>V zd7R3Es|^BJjkBNiom!P#mZyO#Ubd^{jMtB~ek4YXJw|cueE+hIPG!M$a{`lLVac7r zShCw97PmcEx%*>^(*$o`2jd}&S{aKSzT|#^E06~ujwc`D`Dql~f$zb&%m-s)4BE_V zUkMU19IAISvamssf@}E%Y>hVJll^jP4VBP8n9v1ocvv-Bod`uR^tJmXFV-1=px~;A zfy8Qn_xI_5KnoX%fJcq~D;Dd?5=QFGw`m~@Cr4$sAZYbI$7#J$bokI&uo=s842QwrZ^}W{nP50%}Vy7Tf`*oOn-&YbQGn*2wBsqohHy+4TRXKX;%{Z;wDyMV80vBRK z{lLl!Uk5JzU)2^JI55BDOd-z_aLPx7aNO&^UTgw%2m9;H`b?ITYIOQg6bTv#4owDs zg*YK7(xZ`7i_)M-!F4(VBQ?Ut5-NXbp z=*rhZi8se(Ip~d!Ib(DOK?6xK zB^3#&6doKjq{F1r7`Y%Vw(ru2f^+tWi)nk1&0RAhDqJWUo2sS=^N(7{;DB9Y>(I#{ zquF%27QK9A-`-uk&q(k>_SlX(e*BY}FXLW<=BU}Q;!a^z_Aa--Ae#&dIx)Y6E?K?+ zIS)~Wx6-Tgft$s6QR`)Pc-CFp_d4vptoJp1QSU6JAt12TA%@|Lwjj+`$MG6L6Sza@AF&D zCVT@wUF5noTo#Unw_W4bcmUEgVKMSXI#UQ(^Ao=5yI> zKd!bik@RM-z2(d19k^~!fB`xKQ-%^%Ev-@EmZDM;0=752fll{;Oeqw4F~x3f}r5~ z(1Ft-?`n?LOT!Zl85QaS8J|Kv{NU{myG7H3uZf$XG+r)#tISTWC$;lOW|m$94H7LE z-vXY?2gSriJqbBR@3(bqxVol-;{L;YAqMatqhc(8pg7j`pQ>$SQV$~~bS4}O2-+SJ z?p(G^hrWTkmO{8eQfr%3AlR zijU&@YbwXf7LBhdra7y3gQ&XD*IF?=t!SvXI%4zAyDU;wXE?Q}wSw{?beag`oT*%2 zjt;&_;l2jY=$zqIoRD6@*r%(vgd;}yhKjgbE~)@RIL=BxmR`=~i}dv+`+OY7?&+ia z^wUDzYE2m`0-qXQ6Y%Tu)Gj-_2?%6zLx1+Tz1dgpR-=pl3d}~{;C%@F{*?)9|E%LS z%5W!QDeCjDcuhPl@(Csa4^ZgAobD|K@}?YMTYk^kmcJAW1vV=?{I#v!)eV*(s~b5(x8tnz`gxU}`Pz?( z;Eu8W9hRKR=4aVUr**aeL^X;v)aA=#X6R(wrs|Z#$GD=TnHA0vKebZt;P<$z#OL@C zu0aC#1SEYW9+AdKYWMtzU=MX#*X)4TwXQKHfP&X!9_}}<*RX;xb!g5 zz!Y(dT=g`l;s<@^@R}uH$cRM}-HfuLrk~T5hgBCVZpt}r{~1c{ZB*!i^~B2<<)3#R za9dn8fJmoF7q?sH`z7K;n?x5k`2PD;_t>4N7*Y~kT7CuePT)+F&0uo417ObV+FHMf zC?*%AEfGiZ@D7z)S}taNN(22|SL)rt%aJg+)?dK%4hpfsJ~Bo9U2gw_O}Kpat1_~) zE1H<0cP4c?sxR9t;HszrZir2;ZQ6#YVwt${O-BL%M~orQuK!0B0V=2qcrpE{&s( zhxbI8nB+LVUp`3ZrH_7e`U--AD`^KTi=hy9n$-UYAU6}X<#qfi&cghVxd@|tI}e2u z)b?^BUbm9Sd&RZaxWK)M(>H@tay=^2S*kN(zoLE?-M`m|v3})>E`f5}=w~SvLWQmj z0Go$O*%+hLfzf}&dQVeo{8PvZvGIoSw-3gSqhxt%L6L&1GY7IbCNso&%?JE=8V#B* zJV0mNLmK8Y2gro^k5m^)|hfbS@YgFR93XL;Ky-j=;D%?H;54rCTTlI?gc zSC;Gu)-=Bp7=9z9!G7eg)t(_U+{P2O2Wr0WDoS#72>FG}WNj}BBc6^P96w)bovp<5 z`J|mZ@0(z$Fv_Y+$T29zn@qid`if-$1NRV;W6r%^9$scIb z%N@%gD7eN&-~sF8G)%M%8)fL{P{OtbA1>M3{PoMeV^a@EQFU_)5ENW3H4sCy#S&Ug zGI**A|HniYsY=C-`+`R>_-5wrZlM}300afsy$YxVx~f~GK=rqrxhE!g9P(w&-DY%D z1LdD?bvIH3@&cwJ$!LV<)f=;Z zygKr1*yDq#z_N-s0uU73sy;y9Rsv2xUiHvDZhLnyG!{eG9IrFBTbPb!9yMA%GZY9K zN4OkxPElcfX!-im)Bmm58#olz1WdsSZy~gzrigFnd+8nLB0Ni+bDcDcTCW(_fqcFx z0-5`VXlA$Z@3MCJnI@RhJg=%hE~Z`tw#pVxgP?^X@J<<9axUTPO}NpLk5*WlZ~9Cz zV?%4UFF&^W&%<7gb3)RvY&^V2;Asn_gUYk+3r-CmZD{cUw#R>-u&qs zWKO(UaS$p9T6da2`q3pyrb%*de)402H&Q%FkY-<$TbU@lKb+6Q!}*dFi_R9NG0En>yD#ISHs*mCBM1tvsS!X`>(iXkC+e=I zq#)XS9@t1LgrFR1>)_9e5ii^9(7?V~Uv0ZM`VV}P3 zrK7-9U;}>+Pm`Zfhtzx>+8zqzxR;IVwD6OY4wf|u7}AoE#zD})r*pkA&CywN+qRsp z5qUZ{VF(4k<$Zg#xje3#qlXj{&WY-(`DzXN2WB_(sQ49ND9CKWo8S^R+VJn9Ua$M0 z6><9jadw%udot|SbTAPF1y`;Mpa6@D5jh!FW_^C$W-BvYFgTr6t5}T#8)T+aXs#xO z|E7|IIk>r+y8LD`R+)$cBN7UT|GOXyAodgL<=MJS=y`F!bsA-Qf|}OQm>3RHhY!7CqcJW>;Pq0R#kjmvwjZ=K}&|$ zF+h$K?_U;};O__WSPR??X1#pXNVS7jdP{6Ghw~OIG3!i!bi(ko?FV0 zPdNVf9t2oN*4nh@ZVwT!Rzd%1bmSTb_I0T90WDoiD(l(pOP!S{^ zLwE*c*+rFEwaXv1UsThgJASYr_T?lJS0z2{{NM?cYhrQgc?C!zsQ5t&xz_DfWS`uM zjw}dM!I#mJ5n+O$*%q=%P(p}onk$>ya6<3Ddt+efe@Ct7sCu~aaHpMMT)Hyn@*qK9yEYp5fr^4I%aPfJ^`CTt{EoD@)#z| zLrf>C+~x?V$AX~6HHvoM<^OYY7r^ui$|xecW|a^^*eNd>Iw#gs1SP7LM?re2)w@u# z0R*j~M`E?c9xmuUL@--XCV?C$t^-oxDs1n!NOf{c9}{w8W9nZ}Hvu zVvMqT3P$IzP8PY${s@+$7&4mfJ4?n}PwJfL6ueZ9(r?l1YlC~7{XnUP^XpA4jJ`YQ z*Rj^=g9!AmiDb`jsp8*KlFn=FUxJ`Tvi152MXd~~DDb__(5`A9mfh~23d45!2xgQ8 zp>dy-0y+`-d()=B-pVaMrVwrbR03y8rEh2YriM}V8Hl^(+L`_m&VR4*-MQTCxu=t6DDSGE?W>RG5y?`Uv zrnN=aOy$o&#lAct%c{xP5oSTAVYs|HtzgEl|5CM1Wx+M314~H*$x31J-=pVYYc!#J zB;5T`SKbF$Ic_>bR=n3m1VQVc0S9sGc=>ek`i3t-In9G&&g-ZvUbHi@x>1}?zg85Z z2qQm*@GFxmRG|}$6zbzLtDtyJ`dIAm7@t&$lJQ3KiOKq`TD^w9TjwhoBvayq6Oed|CoQ6Gkn0WOxVV zstE$k$GdmoxonvTMx`+0oT|R48QKgB(d+0Pwgo%0GC;)r+>Z^00T@VWNishfWBnPP zlBPqKT6TikZ&rdEg-*%C($@5Qd9kOWXj;CBel&m6!X|mG@O}%A^=_JtO}&%nzMv|M z5Q;}iK{P6ip)2r)$w%PS^`ZzUhq4M#8EqTwtyK`t^^h{7w3xWk+AP$GkDX97To?gG z8dr90kSU(ZR2nN0BV4 zy{&nyW=v{3YCGTn>TMbi)dz7Y6qlZ!;(kQHt$pr?;5cpi1WC8?Tr%`V8T;(BM(NQB zqjQ`Z77-c)IAg+A)Hj42Crq~wIpt4DYVmDy5=t=M$kOG?4d;J2gzV9?Q7TR-%FHE z+ssiRn&-_dSXBN`qGVu$cV5KADF%0&g!vb`7V8k=uhke=ks^+4HIQ z1HWuve}VJ){aT#N%20_HTRFQdMHmVNGeGjqV(>4<$Z7jOdW>p@6#Wy}`2Yru7}I0r z1{MQe1f(%K;^TqOQK?gaKJih){H$)@OFD6x53MjwLe}EQ@T*ukVJ3$7P3@W@^t9l8 zYXUmb0fhBXZV4hEjwJN{ff*wEuy7B+^{QPItBVe44~Tblmr5jF z!jnjP*+oMid3?6@|GR4sUE z%0?7j_j@%$c*o{tku6&m>ecMedw zC1XN86K`9_=M#!yC52JnNyMU)HxbU77s+Mng@C4#Im((c>VYwhczuqoKV+F1`k&O2 z3pk9X8R6}9*I4&{>|sZTXG#7`m_3PviGK-2E29>`OxJbr-PC+~x%WeyJ6b%14ITWOTawU41PB=77RwF8i00Ha z7MQKPdtR|f&;?97m``1q*?U9GJ~9G`G!gnXJeDKcn=^y0)^&ukkWqoJrl2=1;IW@^ zFJF$1>gop5oq5;8x*0jdG4CG&;bx`S0hr$CfTxJx^w(=*RMo!Up4`+m7yOegO#Fne zfO)jt+qWqb9N#Q#W4Z)3oD*90;bF`@Y<2N`AqFycLCvp(`%YU<#M|?m91g0+nZO(R zq_)C~M4Msvspala`@gG~fhg&LR?Y5@4b~3fgBp`4V!Bp5`O-3oy;}4Os7H2eAZXDR zGgRA==~79$(oLW~dF)E5)I8)~X(_8_!~`QL#BKAh!ytW)1l?B|pCYPWnSTZ{@w#D75sF3 z{hqHa+0&}(wqk(7uNh88ZSjj`1SF4*=x!VcTAQi(?1q)VF3)Do222UC*UeEm73_*I zR2cvHFtVyS|L493c@^RcUZ~}kF?HTa9$oz6aupR>j)w7YOZ7jW2y00N4MBo&90aC$)fTL?PCZjhZyx>pGRFh zvCJr!nhM=_HXtVEd6MFoZjZ*KKP2f{O!*QR?h#1GiUO)>9Y_&7c3qDm^7V;joNPE~ z*PN?&WzF5tu<*&eFB7!pE%_@sZ{EIbC!B9OsEKw>vHyEXXF!Opm%YW8ZJ2&(reM~$ z8D-PbVx%+0YpE;(<{QbTD(F8=KvIwBryNro^I%!~3G=xscBnmsREz5~SNTDbj7m8zJ5xT`(KvaG=Bk-z@nBCowL5^rP;QJJ5I@NU+%Q+5lXW-{L5HyL6 z2{=pmrPjk=%52Y<15>s^a(U2SnLB%BPTXYozN>(bRQ!6$wh))jtaIrgz!>l}(j3y- z?3=GaLv~O3v!Fv+`d0AR<^&njX%NC6?`78Ky}PrD9T0p~uJbXAp=@{sNmg#a@H)Tj zmK59JsR!L@Ceu#!dqbm-ilr$JbA#$Spp19Zu7nZ9)s;Fji(ItXN!D(eJoD|kzI>*) zb5JJ&6lpYR+MJ=>iTIggyJ7~CD-8Jqs#DMr2% zB_9FwA{|fbkjLsN6T*Bd_nRfj?&KTg9mzjC2t&WJkZJ)zbBD2PN3;KP_W}@0L=Nwa zrECny!m^fO5&wC&QOB!=OLI4=1ou{pBJAF0yu#Ry@UNEXSYN%%qsZqYXtc6qkn zjjo$#LaOhsSj*o?HX#xFqxxLjevK3hfP2vP!78KCr;!&L(X|+6^cOZ+>tO#|_xQ~R z$VMzmP^7*ZZRiNwfu|b-*!5X_fqS&jto&RUu1xKBv6}%zV|VjX$9Z#W2J=AXVDlFA z10!&`NIU63lnGd3 zVl4SJeWmDO1)yiOM06Vcl3DUDJVIk_242(zKyr#Ov^=ko{zt zxa!#T!eazJMkjYxUb}eBLf5cQhL8M+dPlf!FQ&ts$Q~7={PkZR3Klg{2;vhQ@c-SX P^Di9Y|A)^#1n_?VW-Z|-aGU;M5c?T;wX6ykXNhEc3j2hT;_ zHZA~$0RZrUR!w%M%#}mLEyn39{$}mIw`#0NyBK>Zm(Wds l)Am>pg+Id6$yTF)V+3kMkS9Y}Uw~f4f#R7UnJ{uW4*@w;RDl2h literal 0 HcmV?d00001 diff --git a/cmd/erigon-cl/forkchoice/test_data/block_0x3af8b5b42ca135c75b32abb32b3d71badb73695d3dc638bacfb6c8b7bcbee1a9.ssz_snappy b/cmd/erigon-cl/forkchoice/test_data/block_0x3af8b5b42ca135c75b32abb32b3d71badb73695d3dc638bacfb6c8b7bcbee1a9.ssz_snappy new file mode 100644 index 0000000000000000000000000000000000000000..dc0e77a83a4066c2faf278cebf4ac0d6597e5ae7 GIT binary patch literal 318 zcmV-E0m1&X1n_NS0001u>l%OFfwzDxj2f9kQGr`)y9^AAxT(MO0_zPt5F6vkvv2uh zjDo{NobPjyS$;vg`1LnlMS`Rl1*8?)(gdg z9R{=D^^`6F000000002400{{2s#Z;Q*&k-X`zd!wN@0ZW+AbU>-2s^{1cOr}4iNY< z0k|T!i&s)#bl|ev$&!?ZeGJ%i!9m=Ji;VS7o=?hNNK^m-0FV&;mS@att$+F;DkqT# z)M_Q(I*>QK*;`b=_W1YLHYv;lHlMb?L2smraw_xaNDTOFFcik9kUDI9dXRiy=gF?G zQjDt$V}UbMOfX&II0PE<5&j0`b literal 0 HcmV?d00001 diff --git a/cmd/erigon-cl/forkchoice/test_data/block_0xc2788d6005ee2b92c3df2eff0aeab0374d155fa8ca1f874df305fa376ce334cf.ssz_snappy b/cmd/erigon-cl/forkchoice/test_data/block_0xc2788d6005ee2b92c3df2eff0aeab0374d155fa8ca1f874df305fa376ce334cf.ssz_snappy new file mode 100644 index 0000000000000000000000000000000000000000..a077734003339f7926ada387b3590ee720fd8ba3 GIT binary patch literal 314 zcmV-A0mc5b1n_NS00027ivl(akrzZ2c75$GL$L8U?blJ@D@*E(HNkYsFx9fUy#Kd2u_vf^XJCueb2|#Y zc$LU&Hw0A!000000000c00{{2q{+Q|%We8e+)i3&%5~_FV#8}(Fbl$38!_8X8i_Dq zacFDfS}OP&CM~6)XbA=oB&voIH!s@=>Q3I0cINjt^oiDd;tJL1OWa4 M006-LK>&II086oiPyhe` literal 0 HcmV?d00001 diff --git a/cmd/erigon-cl/forkchoice/test_data/block_0xd4503d46e43df56de4e19acb0f93b3b52087e422aace49a7c3816cf59bafb0ad.ssz_snappy b/cmd/erigon-cl/forkchoice/test_data/block_0xd4503d46e43df56de4e19acb0f93b3b52087e422aace49a7c3816cf59bafb0ad.ssz_snappy new file mode 100644 index 0000000000000000000000000000000000000000..7d02fee497e8fd8c54b24398d06fab658a08ae3e GIT binary patch literal 318 zcmV-E0m1&X1n_NS0001y5BcYQ-?U8g{4Tp8m!hMkE6?kl=>g+T6H!eXH+{>|YaPF9 zP$2j1Nf0&zpznbXd2XkVVkP8V@rCwpLY38V!Y0cfMJ|nQ^}Xs?@}rdPmM1K_=$l!{3%We8e+)i3&%5~_FV#8}(Fbl$38!_8X8i_Dq zaXu;@jnSJwjqVh!FJZ(2`;4^ZrVwbqd;6_~sN|_HK2!hz0IF}i=wLlU2l)Ep{Pc5A zI^NXqX*US2>yVDOT9yj1o$PKT`(grjKf=P&`oy`+RThT&A5T}VnQ~z#f9xJR%F ziT(_ndLyXA+@Ga>iir{1TwL#Bm*c&II07D&+=Kufz literal 0 HcmV?d00001 diff --git a/cmd/erigon-cl/forkchoice/utils.go b/cmd/erigon-cl/forkchoice/utils.go new file mode 100644 index 00000000000..0a6d393dacb --- /dev/null +++ b/cmd/erigon-cl/forkchoice/utils.go @@ -0,0 +1,94 @@ +package forkchoice + +import ( + "fmt" + + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon/cl/cltypes" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/state" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/transition" + "github.com/ledgerwatch/log/v3" +) + +// Slot calculates the current slot number using the time and genesis slot. +func (f *ForkChoiceStore) Slot() uint64 { + return f.forkGraph.Config().GenesisSlot + ((f.time - f.forkGraph.GenesisTime()) / f.forkGraph.Config().SecondsPerSlot) +} + +// updateCheckpoints updates the justified and finalized checkpoints if new checkpoints have higher epochs. +func (f *ForkChoiceStore) updateCheckpoints(justifiedCheckpoint, finalizedCheckpoint *cltypes.Checkpoint) { + if justifiedCheckpoint.Epoch > f.justifiedCheckpoint.Epoch { + f.justifiedCheckpoint = justifiedCheckpoint + } + if finalizedCheckpoint.Epoch > f.finalizedCheckpoint.Epoch { + f.finalizedCheckpoint = finalizedCheckpoint + } +} + +// updateCheckpoints updates the justified and finalized checkpoints if new checkpoints have higher epochs. +func (f *ForkChoiceStore) updateUnrealizedCheckpoints(justifiedCheckpoint, finalizedCheckpoint *cltypes.Checkpoint) { + if justifiedCheckpoint.Epoch > f.unrealizedJustifiedCheckpoint.Epoch { + f.unrealizedJustifiedCheckpoint = justifiedCheckpoint + } + if finalizedCheckpoint.Epoch > f.unrealizedFinalizedCheckpoint.Epoch { + f.unrealizedFinalizedCheckpoint = finalizedCheckpoint + } +} + +// computeEpochAtSlot calculates the epoch at a given slot number. +func (f *ForkChoiceStore) computeEpochAtSlot(slot uint64) uint64 { + return slot / f.forkGraph.Config().SlotsPerEpoch +} + +// computeStartSlotAtEpoch calculates the starting slot of a given epoch. +func (f *ForkChoiceStore) computeStartSlotAtEpoch(epoch uint64) uint64 { + return epoch * f.forkGraph.Config().SlotsPerEpoch +} + +// computeSlotsSinceEpochStart calculates the number of slots since the start of the epoch of a given slot. +func (f *ForkChoiceStore) computeSlotsSinceEpochStart(slot uint64) uint64 { + return slot - f.computeStartSlotAtEpoch(f.computeEpochAtSlot(slot)) +} + +// Ancestor returns the ancestor to the given root. +func (f *ForkChoiceStore) Ancestor(root libcommon.Hash, slot uint64) libcommon.Hash { + header, has := f.forkGraph.GetHeader(root) + if !has { + return libcommon.Hash{} + } + for header.Slot > slot { + root = header.ParentRoot + header, has = f.forkGraph.GetHeader(header.ParentRoot) + if !has { + return libcommon.Hash{} + } + } + return root +} + +// getCheckpointState computes and caches checkpoint states. +func (f *ForkChoiceStore) getCheckpointState(checkpoint cltypes.Checkpoint) (*state.BeaconState, error) { + // check if it can be found in cache. + if state, ok := f.checkpointStates.Get(checkpoint); ok { + return state, nil + } + // If it is not in cache compute it and then put in cache. + baseState, err := f.forkGraph.GetState(checkpoint.Root, true) + if err != nil { + return nil, err + } + if baseState == nil { + return nil, fmt.Errorf("getCheckpointState: baseState not found in graph") + } + // By default use the no change encoding to signal that there is no future epoch here. + if baseState.Slot() < f.computeStartSlotAtEpoch(checkpoint.Epoch) { + log.Debug("Long checkpoint detected") + // If we require to change it then process the future epoch + if err := transition.ProcessSlots(baseState, f.computeStartSlotAtEpoch(checkpoint.Epoch)); err != nil { + return nil, err + } + } + // Cache in memory what we are left with. + f.checkpointStates.Add(checkpoint, baseState) + return baseState, nil +} diff --git a/cmd/erigon-cl/main.go b/cmd/erigon-cl/main.go index 6240a6e2b75..8a78f90c2b7 100644 --- a/cmd/erigon-cl/main.go +++ b/cmd/erigon-cl/main.go @@ -10,6 +10,7 @@ import ( "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv/mdbx" "github.com/ledgerwatch/erigon/cl/clparams" + "github.com/ledgerwatch/erigon/cl/clparams/initial_state" "github.com/ledgerwatch/erigon/cl/cltypes" "github.com/ledgerwatch/erigon/cl/fork" "github.com/ledgerwatch/erigon/cl/rpc" @@ -17,12 +18,13 @@ import ( "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/rawdb" "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/state" "github.com/ledgerwatch/erigon/cmd/erigon-cl/execution_client" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/forkchoice" "github.com/ledgerwatch/erigon/cmd/erigon-cl/network" "github.com/ledgerwatch/erigon/cmd/erigon-cl/stages" lcCli "github.com/ledgerwatch/erigon/cmd/sentinel/cli" + "github.com/ledgerwatch/erigon/cmd/sentinel/cli/flags" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel" - "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/handshake" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/service" sentinelapp "github.com/ledgerwatch/erigon/turbo/app" "github.com/ledgerwatch/log/v3" @@ -58,23 +60,31 @@ func runConsensusLayerNode(cliCtx *cli.Context) error { log.Error("Could load beacon data configuration", "err", err) return err } - // Fetch the checkpoint state. - cpState, err := getCheckpointState(ctx, db, cfg.BeaconCfg, cfg.GenesisCfg, cfg.CheckpointUri) + + tmpdir := "/tmp" + executionClient, err := execution_client.NewExecutionClient(ctx, "127.0.0.1:8989") if err != nil { - log.Error("Could not get checkpoint", "err", err) + log.Warn("Could not connect to execution client", "err", err) return err } - var executionClient *execution_client.ExecutionClient - if cfg.ELEnabled { - executionClient, err = execution_client.NewExecutionClient(ctx, "127.0.0.1:8989") + + if cfg.TransitionChain { + state, err := initial_state.GetGenesisState(cfg.NetworkType) if err != nil { - log.Warn("Could not connect to execution client", "err", err) return err } + // Execute from genesis to whatever we have. + return stages.SpawnStageBeaconState(stages.StageBeaconState(db, cfg.BeaconCfg, state, executionClient), nil, ctx) + } + + // Fetch the checkpoint state. + cpState, err := getCheckpointState(ctx, db, cfg.BeaconCfg, cfg.GenesisCfg, cfg.CheckpointUri) + if err != nil { + log.Error("Could not get checkpoint", "err", err) + return err } log.Info("Starting sync from checkpoint.") - tmpdir := "/tmp" // Start the sentinel service log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(cfg.LogLvl), log.StderrHandler)) log.Info("[Sentinel] running sentinel with configuration", "cfg", cfg) @@ -89,10 +99,13 @@ func runConsensusLayerNode(cliCtx *cli.Context) error { downloader := network.NewForwardBeaconDownloader(ctx, beaconRpc) bdownloader := network.NewBackwardBeaconDownloader(ctx, beaconRpc) - gossipManager := network.NewGossipReceiver(ctx, s) - gossipManager.AddReceiver(sentinelrpc.GossipType_BeaconBlockGossipType, downloader) - go gossipManager.Loop() - stageloop, err := stages.NewConsensusStagedSync(ctx, db, downloader, bdownloader, genesisCfg, beaconConfig, cpState, nil, false, tmpdir, executionClient, cfg.BeaconDataCfg) + forkChoice, err := forkchoice.NewForkChoiceStore(cpState, nil, true) + if err != nil { + log.Error("Could not start forkchoice service", "err", err) + return nil + } + gossipManager := network.NewGossipReceiver(ctx, s, forkChoice, beaconConfig, genesisCfg) + stageloop, err := stages.NewConsensusStagedSync(ctx, db, downloader, bdownloader, genesisCfg, beaconConfig, cpState, tmpdir, executionClient, cfg.BeaconDataCfg, gossipManager, forkChoice) if err != nil { return err } @@ -129,7 +142,7 @@ func startSentinel(cliCtx *cli.Context, cfg lcCli.ConsensusClientCliCfg, beaconS FinalizedEpoch: beaconState.FinalizedCheckpoint().Epoch, HeadSlot: beaconState.FinalizedCheckpoint().Epoch * cfg.BeaconCfg.SlotsPerEpoch, HeadRoot: beaconState.FinalizedCheckpoint().Root, - }, handshake.FullClientRule) + }) if err != nil { log.Error("Could not start sentinel", "err", err) return nil, err diff --git a/cmd/erigon-cl/network/beacon_downloader.go b/cmd/erigon-cl/network/beacon_downloader.go index d5633d58fb4..89a4e8b302c 100644 --- a/cmd/erigon-cl/network/beacon_downloader.go +++ b/cmd/erigon-cl/network/beacon_downloader.go @@ -2,12 +2,12 @@ package network import ( "sync" + "time" libcommon "github.com/ledgerwatch/erigon-lib/common" "golang.org/x/net/context" "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/cl/cltypes/ssz_utils" "github.com/ledgerwatch/erigon/cl/rpc" ) @@ -25,11 +25,8 @@ type ForwardBeaconDownloader struct { ctx context.Context highestSlotProcessed uint64 highestBlockRootProcessed libcommon.Hash - targetSlot uint64 rpc *rpc.BeaconRpcP2P process ProcessFn - isDownloading bool // Should be set to true to set the blocks to download - limitSegmentsLength int // Limit how many blocks we store in the downloader without processing segments []*cltypes.SignedBeaconBlock // Unprocessed downloaded segments mu sync.Mutex @@ -37,42 +34,12 @@ type ForwardBeaconDownloader struct { func NewForwardBeaconDownloader(ctx context.Context, rpc *rpc.BeaconRpcP2P) *ForwardBeaconDownloader { return &ForwardBeaconDownloader{ - ctx: ctx, - segments: []*cltypes.SignedBeaconBlock{}, - rpc: rpc, - isDownloading: false, + ctx: ctx, + segments: []*cltypes.SignedBeaconBlock{}, + rpc: rpc, } } -// Start begins the gossip listening process. -func (f *ForwardBeaconDownloader) ReceiveGossip(obj ssz_utils.Unmarshaler) { - signedBlock := obj.(*cltypes.SignedBeaconBlock) - if signedBlock.Block.ParentRoot == f.highestBlockRootProcessed { - f.addSegment(signedBlock) - } -} - -// SetIsDownloading sets isDownloading -func (f *ForwardBeaconDownloader) SetIsDownloading(isDownloading bool) { - f.mu.Lock() - defer f.mu.Unlock() - f.isDownloading = isDownloading -} - -// SetLimitSegmentsLength sets the segments limiter. -func (f *ForwardBeaconDownloader) SetLimitSegmentsLength(limitSegmentsLength int) { - f.mu.Lock() - defer f.mu.Unlock() - f.limitSegmentsLength = limitSegmentsLength -} - -// SetTargetSlot sets the target slot. -func (f *ForwardBeaconDownloader) SetTargetSlot(targetSlot uint64) { - f.mu.Lock() - defer f.mu.Unlock() - f.targetSlot = targetSlot -} - // SetProcessFunction sets the function used to process segments. func (f *ForwardBeaconDownloader) SetProcessFunction(fn ProcessFn) { f.mu.Lock() @@ -103,10 +70,6 @@ func (f *ForwardBeaconDownloader) HighestProcessedRoot() libcommon.Hash { // addSegment process new block segment. func (f *ForwardBeaconDownloader) addSegment(block *cltypes.SignedBeaconBlock) { - // Skip if it is not downloading or limit was reached - if !f.isDownloading || len(f.segments) >= f.limitSegmentsLength { - return - } f.mu.Lock() defer f.mu.Unlock() // Skip if does continue the segment. @@ -114,10 +77,12 @@ func (f *ForwardBeaconDownloader) addSegment(block *cltypes.SignedBeaconBlock) { } func (f *ForwardBeaconDownloader) RequestMore() { - count := uint64(64) + count := uint64(4) // dont need many responses, err := f.rpc.SendBeaconBlocksByRangeReq(f.highestSlotProcessed+1, count) if err != nil { + // Wait a bit in this case (we do not need to be super performant here). + time.Sleep(time.Second) return } for _, response := range responses { @@ -152,3 +117,7 @@ func (f *ForwardBeaconDownloader) GetHighestProcessedSlot() uint64 { defer f.mu.Unlock() return f.highestSlotProcessed } + +func (f *ForwardBeaconDownloader) Peers() (uint64, error) { + return f.rpc.Peers() +} diff --git a/cmd/erigon-cl/network/gossip_manager.go b/cmd/erigon-cl/network/gossip_manager.go index aadab8daac1..961a7446063 100644 --- a/cmd/erigon-cl/network/gossip_manager.go +++ b/cmd/erigon-cl/network/gossip_manager.go @@ -2,42 +2,42 @@ package network import ( "context" + "runtime" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/dbg" "github.com/ledgerwatch/erigon-lib/gointerfaces/sentinel" "github.com/ledgerwatch/erigon/cl/clparams" "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/cl/cltypes/ssz_utils" + "github.com/ledgerwatch/erigon/cl/cltypes/ssz" + "github.com/ledgerwatch/erigon/cl/utils" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/forkchoice" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/log/v3" ) -type GossipReceiver interface { - ReceiveGossip(ssz_utils.Unmarshaler) -} - +// Gossip manager is sending all messages to fork choice or others type GossipManager struct { ctx context.Context - receivers map[sentinel.GossipType][]GossipReceiver - sentinel sentinel.SentinelClient + forkChoice *forkchoice.ForkChoiceStore + sentinel sentinel.SentinelClient + // configs + beaconConfig *clparams.BeaconChainConfig + genesisConfig *clparams.GenesisConfig } -func NewGossipReceiver(ctx context.Context, s sentinel.SentinelClient) *GossipManager { +func NewGossipReceiver(ctx context.Context, s sentinel.SentinelClient, forkChoice *forkchoice.ForkChoiceStore, beaconConfig *clparams.BeaconChainConfig, genesisConfig *clparams.GenesisConfig) *GossipManager { return &GossipManager{ - sentinel: s, - receivers: make(map[sentinel.GossipType][]GossipReceiver), - ctx: ctx, - } -} - -func (g *GossipManager) AddReceiver(t sentinel.GossipType, receiver GossipReceiver) { - if _, ok := g.receivers[t]; !ok { - g.receivers[t] = make([]GossipReceiver, 0) + sentinel: s, + forkChoice: forkChoice, + ctx: ctx, + beaconConfig: beaconConfig, + genesisConfig: genesisConfig, } - g.receivers[t] = append(g.receivers[t], receiver) } -func (g *GossipManager) Loop() { +func (g *GossipManager) Start() { subscription, err := g.sentinel.SubscribeGossip(g.ctx, &sentinel.EmptyMessage{}) if err != nil { return @@ -46,52 +46,109 @@ func (g *GossipManager) Loop() { for { data, err := subscription.Recv() if err != nil { - log.Warn("[Beacon Gossip] Failure in receiving", "err", err) + log.Debug("[Beacon Gossip] Failure in receiving", "err", err) continue } + + currentEpoch := utils.GetCurrentEpoch(g.genesisConfig.GenesisTime, g.beaconConfig.SecondsPerSlot, g.beaconConfig.SlotsPerEpoch) + version := g.beaconConfig.GetCurrentStateVersion(currentEpoch) + // Depending on the type of the received data, we create an instance of a specific type that implements the ObjectSSZ interface, // then attempts to deserialize the received data into it. - //If the deserialization fails, an error is logged and the loop continues to the next iteration. - //If the deserialization is successful, the object is set to the deserialized value and the loop continues to the next iteration. - receivers := g.receivers[data.Type] - var object ssz_utils.Unmarshaler + // If the deserialization fails, an error is logged and the loop continues to the next iteration. + // If the deserialization is successful, the object is set to the deserialized value and the loop continues to the next iteration. + var object ssz.Unmarshaler switch data.Type { case sentinel.GossipType_BeaconBlockGossipType: object = &cltypes.SignedBeaconBlock{} - if err := object.DecodeSSZWithVersion(common.CopyBytes(data.Data), int(clparams.BellatrixVersion)); err != nil { - log.Warn("[Beacon Gossip] Failure in decoding block", "err", err) + if err := object.DecodeSSZWithVersion(common.CopyBytes(data.Data), int(version)); err != nil { + log.Debug("[Beacon Gossip] Failure in decoding block", "err", err) + g.sentinel.BanPeer(g.ctx, data.Peer) + continue + } + block := object.(*cltypes.SignedBeaconBlock) + + currentSlotByTime := utils.GetCurrentSlot(g.genesisConfig.GenesisTime, g.beaconConfig.SecondsPerSlot) + maxGossipSlotThreshold := uint64(4) + // Skip if slot is too far behind. + if block.Block.Slot+maxGossipSlotThreshold < currentSlotByTime { + continue + } + if block.Block.Slot+maxGossipSlotThreshold == currentSlotByTime { + if _, err := g.sentinel.PublishGossip(g.ctx, data); err != nil { + log.Debug("cannot publish gossip", "err", err) + } + } + + log.Debug("Received block via gossip", "slot", block.Block.Slot) + + if err := g.forkChoice.OnBlock(block, true); err != nil { + log.Debug("[Beacon Gossip] Failure in processing block", "err", err) + continue + } + for _, attestation := range block.Block.Body.Attestations { + if err := g.forkChoice.OnAttestation(attestation, true); err != nil { + log.Debug("[Beacon Gossip] Failure in processing attestation", "err", err) + continue + } + } + + // Now check the head + headRoot, headSlot, err := g.forkChoice.GetHead() + if err != nil { + log.Debug("Could not fetch head data", "err", err) continue } + // Do forkchoice if possible + if g.forkChoice.Engine() != nil { + finalizedCheckpoint := g.forkChoice.FinalizedCheckpoint() + // Run forkchoice + if err := g.forkChoice.Engine().ForkChoiceUpdate( + g.forkChoice.GetEth1Hash(finalizedCheckpoint.Root), + g.forkChoice.GetEth1Hash(headRoot), + ); err != nil { + log.Warn("Could send not forkchoice", "err", err) + return + } + } + var m runtime.MemStats + dbg.ReadMemStats(&m) + // Log final result + log.Debug("New block imported", + "slot", block.Block.Slot, "head", headSlot, "headRoot", headRoot, + "alloc", libcommon.ByteCount(m.Alloc)) case sentinel.GossipType_VoluntaryExitGossipType: object = &cltypes.SignedVoluntaryExit{} - if err := object.DecodeSSZWithVersion(data.Data, int(clparams.BellatrixVersion)); err != nil { - log.Warn("[Beacon Gossip] Failure in decoding exit", "err", err) + if err := object.DecodeSSZWithVersion(data.Data, int(version)); err != nil { + log.Debug("[Beacon Gossip] Failure in decoding exit", "err", err) + g.sentinel.BanPeer(g.ctx, data.Peer) continue } case sentinel.GossipType_ProposerSlashingGossipType: object = &cltypes.ProposerSlashing{} - if err := object.DecodeSSZWithVersion(data.Data, int(clparams.BellatrixVersion)); err != nil { - log.Warn("[Beacon Gossip] Failure in decoding proposer slashing", "err", err) + if err := object.DecodeSSZWithVersion(data.Data, int(version)); err != nil { + log.Debug("[Beacon Gossip] Failure in decoding proposer slashing", "err", err) + g.sentinel.BanPeer(g.ctx, data.Peer) continue } case sentinel.GossipType_AttesterSlashingGossipType: object = &cltypes.AttesterSlashing{} - if err := object.DecodeSSZWithVersion(data.Data, int(clparams.BellatrixVersion)); err != nil { - log.Warn("[Beacon Gossip] Failure in decoding attester slashing", "err", err) + if err := object.DecodeSSZWithVersion(data.Data, int(version)); err != nil { + log.Debug("[Beacon Gossip] Failure in decoding attester slashing", "err", err) + g.sentinel.BanPeer(g.ctx, data.Peer) + continue + } + if err := g.forkChoice.OnAttesterSlashing(object.(*cltypes.AttesterSlashing)); err != nil { + log.Debug("[Beacon Gossip] Failure in processing block", "err", err) continue } case sentinel.GossipType_AggregateAndProofGossipType: object = &cltypes.SignedAggregateAndProof{} - if err := object.DecodeSSZWithVersion(data.Data, int(clparams.BellatrixVersion)); err != nil { - log.Warn("[Beacon Gossip] Failure in decoding proof", "err", err) + if err := object.DecodeSSZWithVersion(data.Data, int(version)); err != nil { + log.Debug("[Beacon Gossip] Failure in decoding proof", "err", err) + g.sentinel.BanPeer(g.ctx, data.Peer) continue } } - // If we received a valid object give it to our receiver - if object != nil { - for _, receiver := range receivers { - receiver.ReceiveGossip(object) - } - } } } diff --git a/cmd/erigon-cl/stages/stage_beacon_blocks.go b/cmd/erigon-cl/stages/stage_beacon_blocks.go deleted file mode 100644 index 3bf5a8bfa36..00000000000 --- a/cmd/erigon-cl/stages/stage_beacon_blocks.go +++ /dev/null @@ -1,183 +0,0 @@ -package stages - -import ( - "context" - "fmt" - "time" - - libcommon "github.com/ledgerwatch/erigon-lib/common" - "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/log/v3" - - "github.com/ledgerwatch/erigon/cl/clparams" - "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/cl/utils" - "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/rawdb" - "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/state" - "github.com/ledgerwatch/erigon/cmd/erigon-cl/execution_client" - "github.com/ledgerwatch/erigon/cmd/erigon-cl/network" - "github.com/ledgerwatch/erigon/eth/stagedsync" -) - -type StageBeaconsBlockCfg struct { - db kv.RwDB - downloader *network.ForwardBeaconDownloader - genesisCfg *clparams.GenesisConfig - beaconCfg *clparams.BeaconChainConfig - executionClient *execution_client.ExecutionClient - state *state.BeaconState -} - -func StageBeaconsBlock(db kv.RwDB, downloader *network.ForwardBeaconDownloader, genesisCfg *clparams.GenesisConfig, - beaconCfg *clparams.BeaconChainConfig, state *state.BeaconState, executionClient *execution_client.ExecutionClient) StageBeaconsBlockCfg { - return StageBeaconsBlockCfg{ - db: db, - downloader: downloader, - genesisCfg: genesisCfg, - beaconCfg: beaconCfg, - state: state, - executionClient: executionClient, - } -} - -// SpawnStageBeaconsForward spawn the beacon forward stage -func SpawnStageBeaconsBlocks(cfg StageBeaconsBlockCfg, s *stagedsync.StageState, tx kv.RwTx, ctx context.Context) error { - useExternalTx := tx != nil - var err error - if !useExternalTx { - tx, err = cfg.db.BeginRw(ctx) - if err != nil { - return err - } - defer tx.Rollback() - } - progress := s.BlockNumber - var lastRoot libcommon.Hash - if progress == 0 { - progress = cfg.state.LatestBlockHeader().Slot - lastRoot, err = cfg.state.BlockRoot() - } else { - lastRoot, err = rawdb.ReadFinalizedBlockRoot(tx, progress) - } - if err != nil { - return err - } - // Initialize payload insertion batch - executionPayloadInsertionBatch := execution_client.NewInsertBatch(cfg.executionClient) - - // We add one so that we wait for Gossiped blocks if we are on chain tip. - targetSlot := utils.GetCurrentSlot(cfg.genesisCfg.GenesisTime, cfg.beaconCfg.SecondsPerSlot) + 1 - - log.Info(fmt.Sprintf("[%s] Started", s.LogPrefix()), "start", progress, "target", targetSlot) - cfg.downloader.SetHighestProcessedSlot(progress) - if cfg.downloader.HighestProcessedRoot() == (libcommon.Hash{}) { - cfg.downloader.SetHighestProcessedRoot(lastRoot) - } - cfg.downloader.SetTargetSlot(targetSlot) - cfg.downloader.SetLimitSegmentsLength(1024) - // On new blocks we just check slot sequencing for now :) - cfg.downloader.SetProcessFunction(func( - highestSlotProcessed uint64, - highestRootProcessed libcommon.Hash, - newBlocks []*cltypes.SignedBeaconBlock) (newHighestSlotProcessed uint64, newHighestBlockRootProcessed libcommon.Hash, err error) { - // Setup - newHighestSlotProcessed = highestSlotProcessed - newHighestBlockRootProcessed = highestRootProcessed - // Skip if segment is empty - if len(newBlocks) == 0 { - return - } - // Retrieve last blocks to do reverse soft checks - var lastRootInSegment libcommon.Hash - lastBlockInSegment := newBlocks[len(newBlocks)-1] - lastSlotInSegment := lastBlockInSegment.Block.Slot - lastRootInSegment, err = lastBlockInSegment.Block.HashSSZ() - parentRoot := lastBlockInSegment.Block.ParentRoot - - if err != nil { - return - } - - for i := len(newBlocks) - 2; i >= 0; i-- { - var blockRoot libcommon.Hash - blockRoot, err = newBlocks[i].Block.HashSSZ() - if err != nil { - return - } - // Check if block root makes sense, if not segment is invalid - if blockRoot != parentRoot { - return - } - // Update the parent root. - parentRoot = newBlocks[i].Block.ParentRoot - if parentRoot == highestRootProcessed { - // We found a connection point? interrupt cycle and move on. - newBlocks = newBlocks[i:] - break - } - } - // If segment is not recconecting then skip. - if parentRoot != highestRootProcessed { - return - } - for _, block := range newBlocks { - if err = rawdb.WriteBeaconBlock(tx, block); err != nil { - return - } - var currentRoot libcommon.Hash - currentRoot, err = block.Block.HashSSZ() - if err != nil { - return - } - // Assume all of them are finalized - if err = rawdb.WriteFinalizedBlockRoot(tx, block.Block.Slot, currentRoot); err != nil { - return - } - if cfg.executionClient != nil && block.Version() >= clparams.BellatrixVersion { - if err = executionPayloadInsertionBatch.WriteExecutionPayload(block.Block.Body.ExecutionPayload); err != nil { - log.Warn("Could not send Execution Payload", "err", err) - } - } - } - - // Checks done, update all internals accordingly - return lastSlotInSegment, lastRootInSegment, nil - }) - cfg.downloader.SetIsDownloading(true) - logInterval := time.NewTicker(30 * time.Second) - defer logInterval.Stop() - triggerInterval := time.NewTicker(150 * time.Millisecond) - defer triggerInterval.Stop() - // Process blocks until we reach our target - for highestProcessed := cfg.downloader.GetHighestProcessedSlot(); targetSlot > highestProcessed; highestProcessed = cfg.downloader.GetHighestProcessedSlot() { - currentSlot := utils.GetCurrentSlot(cfg.genesisCfg.GenesisTime, cfg.beaconCfg.SecondsPerSlot) - // Send request every 50 Millisecond only if not on chain tip - if currentSlot != highestProcessed { - cfg.downloader.RequestMore() - } - - if err := cfg.downloader.ProcessBlocks(); err != nil { - return err - } - select { - case <-logInterval.C: - log.Info(fmt.Sprintf("[%s] Processed and collected blocks", s.LogPrefix()), "slot", cfg.downloader.GetHighestProcessedSlot()) - case <-triggerInterval.C: - } - } - // Flush inserted payloads to execution client - if err := executionPayloadInsertionBatch.Flush(); err != nil { - return err - } - - log.Info(fmt.Sprintf("[%s] Processed and collected blocks", s.LogPrefix()), "count", targetSlot-progress) - if err := s.Update(tx, cfg.downloader.GetHighestProcessedSlot()); err != nil { - return err - } - if !useExternalTx { - if err = tx.Commit(); err != nil { - return err - } - } - return nil -} diff --git a/cmd/erigon-cl/stages/stage_fork_choice.go b/cmd/erigon-cl/stages/stage_fork_choice.go new file mode 100644 index 00000000000..31ffd4cee76 --- /dev/null +++ b/cmd/erigon-cl/stages/stage_fork_choice.go @@ -0,0 +1,173 @@ +package stages + +import ( + "context" + "runtime" + "time" + + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/dbg" + "github.com/ledgerwatch/erigon-lib/kv" + "github.com/ledgerwatch/log/v3" + + "github.com/ledgerwatch/erigon/cl/clparams" + "github.com/ledgerwatch/erigon/cl/cltypes" + "github.com/ledgerwatch/erigon/cl/utils" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/state" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/execution_client" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/forkchoice" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/network" + "github.com/ledgerwatch/erigon/eth/stagedsync" +) + +type StageForkChoiceCfg struct { + db kv.RwDB + downloader *network.ForwardBeaconDownloader + genesisCfg *clparams.GenesisConfig + beaconCfg *clparams.BeaconChainConfig + executionClient *execution_client.ExecutionClient + state *state.BeaconState + gossipManager *network.GossipManager + forkChoice *forkchoice.ForkChoiceStore +} + +func StageForkChoice(db kv.RwDB, downloader *network.ForwardBeaconDownloader, genesisCfg *clparams.GenesisConfig, + beaconCfg *clparams.BeaconChainConfig, state *state.BeaconState, executionClient *execution_client.ExecutionClient, gossipManager *network.GossipManager, forkChoice *forkchoice.ForkChoiceStore) StageForkChoiceCfg { + return StageForkChoiceCfg{ + db: db, + downloader: downloader, + genesisCfg: genesisCfg, + beaconCfg: beaconCfg, + state: state, + executionClient: executionClient, + gossipManager: gossipManager, + forkChoice: forkChoice, + } +} + +// StageForkChoice enables the fork choice state. it is never supposed to exit this stage once it gets in. +func SpawnStageForkChoice(cfg StageForkChoiceCfg, s *stagedsync.StageState, tx kv.RwTx, ctx context.Context) error { + /*useExternalTx := tx != nil + var err error + if !useExternalTx { + tx, err = cfg.db.BeginRw(ctx) + if err != nil { + return err + } + defer tx.Rollback() + }*/ + // Start download service + log.Info("Started Ethereum 2.0 Gossip Service") + // We start gossip management. + go cfg.gossipManager.Start() + go onTickService(ctx, cfg) + go func() { + logIntervalPeers := time.NewTicker(1 * time.Minute) + for { + select { + case <-logIntervalPeers.C: + if peerCount, err := cfg.downloader.Peers(); err == nil { + log.Info("[Caplin] P2P", "peers", peerCount) + + } + case <-ctx.Done(): + return + } + + } + }() + startDownloadService(s, cfg) + /*if !useExternalTx { + if err = tx.Commit(); err != nil { + return err + } + }*/ + return nil +} + +func startDownloadService(s *stagedsync.StageState, cfg StageForkChoiceCfg) { + cfg.downloader.SetHighestProcessedRoot(libcommon.Hash{}) + cfg.downloader.SetHighestProcessedSlot(cfg.state.Slot()) + cfg.downloader.SetProcessFunction(func(highestSlotProcessed uint64, _ libcommon.Hash, newBlocks []*cltypes.SignedBeaconBlock) (uint64, libcommon.Hash, error) { + for _, block := range newBlocks { + sendForckchoice := + utils.GetCurrentSlot(cfg.genesisCfg.GenesisTime, cfg.beaconCfg.SecondsPerSlot) == block.Block.Slot + if err := cfg.forkChoice.OnBlock(block, true); err != nil { + log.Warn("Could not download block", "reason", err) + return highestSlotProcessed, libcommon.Hash{}, nil + } + if sendForckchoice { + // Import the head + headRoot, headSlot, err := cfg.forkChoice.GetHead() + if err != nil { + log.Debug("Could not fetch head data", "err", err) + continue + } + var m runtime.MemStats + dbg.ReadMemStats(&m) + log.Debug("New block imported", + "slot", block.Block.Slot, "head", headSlot, "headRoot", headRoot, + "alloc", libcommon.ByteCount(m.Alloc)) + + // Do forkchoice if possible + if cfg.forkChoice.Engine() != nil { + finalizedCheckpoint := cfg.forkChoice.FinalizedCheckpoint() + // Run forkchoice + if err := cfg.forkChoice.Engine().ForkChoiceUpdate( + cfg.forkChoice.GetEth1Hash(finalizedCheckpoint.Root), + cfg.forkChoice.GetEth1Hash(headRoot), + ); err != nil { + log.Warn("Could send not forkchoice", "err", err) + } + } + } + highestSlotProcessed = utils.Max64(block.Block.Slot, highestSlotProcessed) + } + // Checks done, update all internals accordingly + return highestSlotProcessed, libcommon.Hash{}, nil + }) + maxBlockBehindBeforeDownload := int64(5) + firstTime := true + + for { + targetSlot := utils.GetCurrentSlot(cfg.genesisCfg.GenesisTime, cfg.beaconCfg.SecondsPerSlot) + if targetSlot == cfg.forkChoice.HighestSeen() { + time.Sleep(time.Second) + continue + } + // if not the first time then send back the downloader a little bit. + if !firstTime { + cfg.downloader.SetHighestProcessedRoot(libcommon.Hash{}) + cfg.downloader.SetHighestProcessedSlot(cfg.forkChoice.HighestSeen() - uint64(maxBlockBehindBeforeDownload)) + } + // Wait small time + time.Sleep(100 * time.Millisecond) + firstTime = false + log.Debug("Caplin has missed some slots, started downloading chain") + // Process blocks until we reach our target + for highestProcessed := cfg.downloader.GetHighestProcessedSlot(); utils.GetCurrentSlot(cfg.genesisCfg.GenesisTime, cfg.beaconCfg.SecondsPerSlot) > highestProcessed; highestProcessed = cfg.downloader.GetHighestProcessedSlot() { + currentSlot := utils.GetCurrentSlot(cfg.genesisCfg.GenesisTime, cfg.beaconCfg.SecondsPerSlot) + // Send request every 50 Millisecond only if not on chain tip + if currentSlot != highestProcessed { + cfg.downloader.RequestMore() + } + + if err := cfg.downloader.ProcessBlocks(); err != nil { + log.Warn("Could not download block in processing", "reason", err) + } + } + log.Debug("Finished catching up", "slot", cfg.downloader.GetHighestProcessedSlot()) + } +} + +func onTickService(ctx context.Context, cfg StageForkChoiceCfg) { + tickInterval := time.NewTicker(50 * time.Millisecond) + for { + select { + case <-tickInterval.C: + cfg.forkChoice.OnTick(uint64(time.Now().Unix())) + case <-ctx.Done(): + return + } + } +} diff --git a/cmd/erigon-cl/stages/stages.go b/cmd/erigon-cl/stages/stages.go index b5264b11f54..01356fe1109 100644 --- a/cmd/erigon-cl/stages/stages.go +++ b/cmd/erigon-cl/stages/stages.go @@ -8,13 +8,14 @@ import ( "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/rawdb" "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/state" "github.com/ledgerwatch/erigon/cmd/erigon-cl/execution_client" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/forkchoice" "github.com/ledgerwatch/erigon/cmd/erigon-cl/network" "github.com/ledgerwatch/erigon/eth/stagedsync" "github.com/ledgerwatch/erigon/eth/stagedsync/stages" ) // StateStages are all stages necessary for basic unwind and stage computation, it is primarly used to process side forks and memory execution. -func ConsensusStages(ctx context.Context, historyReconstruction StageHistoryReconstructionCfg, beaconsBlocks StageBeaconsBlockCfg, beaconState StageBeaconStateCfg) []*stagedsync.Stage { +func ConsensusStages(ctx context.Context, historyReconstruction StageHistoryReconstructionCfg, beaconState StageBeaconStateCfg, forkchoice StageForkChoiceCfg) []*stagedsync.Stage { return []*stagedsync.Stage{ { ID: stages.BeaconHistoryReconstruction, @@ -27,20 +28,20 @@ func ConsensusStages(ctx context.Context, historyReconstruction StageHistoryReco }, }, { - ID: stages.BeaconBlocks, - Description: "Download beacon blocks forward.", + ID: stages.BeaconState, + Description: "Execute Consensus Layer transition", Forward: func(firstCycle bool, badBlockUnwind bool, s *stagedsync.StageState, u stagedsync.Unwinder, tx kv.RwTx, quiet bool) error { - return SpawnStageBeaconsBlocks(beaconsBlocks, s, tx, ctx) + return SpawnStageBeaconState(beaconState, tx, ctx) }, Unwind: func(firstCycle bool, u *stagedsync.UnwindState, s *stagedsync.StageState, tx kv.RwTx) error { return nil }, }, { - ID: stages.BeaconState, - Description: "Execute Consensus Layer transition", + ID: stages.BeaconBlocks, + Description: "Download beacon blocks forward.", Forward: func(firstCycle bool, badBlockUnwind bool, s *stagedsync.StageState, u stagedsync.Unwinder, tx kv.RwTx, quiet bool) error { - return SpawnStageBeaconState(beaconState, s, tx, ctx) + return SpawnStageForkChoice(forkchoice, s, tx, ctx) }, Unwind: func(firstCycle bool, u *stagedsync.UnwindState, s *stagedsync.StageState, tx kv.RwTx) error { return nil @@ -66,18 +67,18 @@ func NewConsensusStagedSync(ctx context.Context, genesisCfg *clparams.GenesisConfig, beaconCfg *clparams.BeaconChainConfig, state *state.BeaconState, - triggerExecution triggerExecutionFunc, - clearEth1Data bool, tmpdir string, executionClient *execution_client.ExecutionClient, beaconDBCfg *rawdb.BeaconDataConfig, + gossipManager *network.GossipManager, + forkChoice *forkchoice.ForkChoiceStore, ) (*stagedsync.Sync, error) { return stagedsync.New( ConsensusStages( ctx, StageHistoryReconstruction(db, backwardDownloader, genesisCfg, beaconCfg, beaconDBCfg, state, tmpdir, executionClient), - StageBeaconsBlock(db, forwardDownloader, genesisCfg, beaconCfg, state, executionClient), - StageBeaconState(db, genesisCfg, beaconCfg, state, triggerExecution, clearEth1Data, executionClient), + StageBeaconState(db, beaconCfg, state, executionClient), + StageForkChoice(db, forwardDownloader, genesisCfg, beaconCfg, state, executionClient, gossipManager, forkChoice), ), ConsensusUnwindOrder, ConsensusPruneOrder, diff --git a/cmd/erigon-cl/stages/stages_beacon_state.go b/cmd/erigon-cl/stages/stages_beacon_state.go index 57583401982..a61d6e718ff 100644 --- a/cmd/erigon-cl/stages/stages_beacon_state.go +++ b/cmd/erigon-cl/stages/stages_beacon_state.go @@ -2,51 +2,44 @@ package stages import ( "context" - "fmt" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/erigon-lib/kv/kvcfg" "github.com/ledgerwatch/erigon/cl/clparams" - "github.com/ledgerwatch/erigon/cl/cltypes" "github.com/ledgerwatch/erigon/cl/utils" "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/rawdb" "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/state" "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/transition" "github.com/ledgerwatch/erigon/cmd/erigon-cl/execution_client" - "github.com/ledgerwatch/erigon/eth/stagedsync" "github.com/ledgerwatch/erigon/eth/stagedsync/stages" "github.com/ledgerwatch/log/v3" ) -// This function will trigger block execution, hence: insert + validate + fcu. -type triggerExecutionFunc func(*cltypes.SignedBeaconBlock) error - type StageBeaconStateCfg struct { - db kv.RwDB - genesisCfg *clparams.GenesisConfig - beaconCfg *clparams.BeaconChainConfig - state *state.BeaconState - clearEth1Data bool // Whether we want to discard eth1 data. - triggerExecution triggerExecutionFunc - executionClient *execution_client.ExecutionClient + db kv.RwDB + beaconCfg *clparams.BeaconChainConfig + state *state.BeaconState + executionClient *execution_client.ExecutionClient + enabled bool } -func StageBeaconState(db kv.RwDB, genesisCfg *clparams.GenesisConfig, - beaconCfg *clparams.BeaconChainConfig, state *state.BeaconState, triggerExecution triggerExecutionFunc, clearEth1Data bool, executionClient *execution_client.ExecutionClient) StageBeaconStateCfg { +func StageBeaconState(db kv.RwDB, + beaconCfg *clparams.BeaconChainConfig, state *state.BeaconState, executionClient *execution_client.ExecutionClient) StageBeaconStateCfg { return StageBeaconStateCfg{ - db: db, - genesisCfg: genesisCfg, - beaconCfg: beaconCfg, - state: state, - clearEth1Data: clearEth1Data, - triggerExecution: triggerExecution, - executionClient: executionClient, + db: db, + beaconCfg: beaconCfg, + state: state, + executionClient: executionClient, + enabled: false, } } -// SpawnStageBeaconForward spawn the beacon forward stage -func SpawnStageBeaconState(cfg StageBeaconStateCfg, s *stagedsync.StageState, tx kv.RwTx, ctx context.Context) error { +// SpawnStageBeaconState is used to replay historical states +func SpawnStageBeaconState(cfg StageBeaconStateCfg, tx kv.RwTx, ctx context.Context) error { + if !cfg.enabled { + return nil + } + // This code need to be fixed. useExternalTx := tx != nil var err error if !useExternalTx { @@ -77,59 +70,23 @@ func SpawnStageBeaconState(cfg StageBeaconStateCfg, s *stagedsync.StageState, tx if err != nil { return err } - // TODO: Pass this to state transition with the state - if cfg.executionClient != nil { + + // Query execution engine only if the payload have an hash. + if eth1Hash != (libcommon.Hash{}) { if block.Block.Body.ExecutionPayload, err = cfg.executionClient.ReadExecutionPayload(eth1Number, eth1Hash); err != nil { return err } - // validate fully only in current epoch. - fullValidate := utils.GetCurrentEpoch(cfg.genesisCfg.GenesisTime, cfg.beaconCfg.SecondsPerSlot, cfg.beaconCfg.SlotsPerEpoch) == cfg.state.Epoch() - if err := transition.TransitionState(cfg.state, block, fullValidate); err != nil { - log.Info("Found epoch, so stopping now...", "count", slot-(fromSlot+1), "slot", slot) - return err - } - log.Info("Applied state transition", "from", slot, "to", slot+1) - } - } - // If successful update fork choice - if cfg.executionClient != nil { - finalizedRoot, err := rawdb.ReadFinalizedBlockRoot(tx, endSlot) - if err != nil { - return err - } - _, _, eth1Hash, _, err := rawdb.ReadBeaconBlockForStorage(tx, finalizedRoot, endSlot) - if err != nil { - return err - } - receipt, err := cfg.executionClient.ForkChoiceUpdate(eth1Hash) - if err != nil { - return err - } - log.Info("Forkchoice Status", "outcome", receipt.Success) - } - - // Clear all ETH1 data from CL db - if cfg.clearEth1Data { - if err := tx.ClearBucket(kv.Headers); err != nil { - return err - } - if err := tx.ClearBucket(kv.BlockBody); err != nil { - return err - } - ethTx := kv.EthTx - transactionsV3, _ := kvcfg.TransactionsV3.Enabled(tx) - if transactionsV3 { - ethTx = kv.EthTxV3 - } - if err := tx.ClearBucket(ethTx); err != nil { - return err } - if err := tx.ClearBucket(kv.Sequence); err != nil { + // validate fully only in current epoch. + fullValidate := utils.GetCurrentEpoch(cfg.state.GenesisTime(), cfg.beaconCfg.SecondsPerSlot, cfg.beaconCfg.SlotsPerEpoch) == cfg.state.Epoch() + if err := transition.TransitionState(cfg.state, block, fullValidate); err != nil { + log.Info("Found epoch, so stopping now...", "count", slot-(fromSlot+1), "slot", slot) return err } + log.Info("Applied state transition", "from", slot, "to", slot+1) } - log.Info(fmt.Sprintf("[%s] Finished transitioning state", s.LogPrefix()), "from", fromSlot, "to", endSlot) + log.Info("[BeaconState] Finished transitioning state", "from", fromSlot, "to", endSlot) if !useExternalTx { if err = tx.Commit(); err != nil { return err diff --git a/cmd/erigon-el/backend/backend.go b/cmd/erigon-el/backend/backend.go index 725219be4e2..324cb74e121 100644 --- a/cmd/erigon-el/backend/backend.go +++ b/cmd/erigon-el/backend/backend.go @@ -16,6 +16,12 @@ import ( "github.com/c2h5oh/datasize" "github.com/holiman/uint256" + "github.com/ledgerwatch/log/v3" + "golang.org/x/exp/slices" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + "google.golang.org/protobuf/types/known/emptypb" + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/datadir" @@ -39,18 +45,6 @@ import ( txpool2 "github.com/ledgerwatch/erigon-lib/txpool" "github.com/ledgerwatch/erigon-lib/txpool/txpooluitl" types2 "github.com/ledgerwatch/erigon-lib/types" - "github.com/ledgerwatch/log/v3" - "golang.org/x/exp/slices" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials" - "google.golang.org/protobuf/types/known/emptypb" - - "github.com/ledgerwatch/erigon/core/systemcontracts" - - "github.com/ledgerwatch/erigon/core/state/historyv2read" - "github.com/ledgerwatch/erigon/core/types/accounts" - "github.com/ledgerwatch/erigon/p2p/dnsdisc" - "github.com/ledgerwatch/erigon/p2p/enode" "github.com/ledgerwatch/erigon/cmd/erigon-el/eth1" stages3 "github.com/ledgerwatch/erigon/cmd/erigon-el/stages" @@ -66,8 +60,11 @@ import ( "github.com/ledgerwatch/erigon/consensus/serenity" "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/core/rawdb" + "github.com/ledgerwatch/erigon/core/state/historyv2read" "github.com/ledgerwatch/erigon/core/state/temporal" + "github.com/ledgerwatch/erigon/core/systemcontracts" "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/core/types/accounts" "github.com/ledgerwatch/erigon/core/vm" "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/eth/ethconfig" @@ -80,6 +77,8 @@ import ( "github.com/ledgerwatch/erigon/ethstats" "github.com/ledgerwatch/erigon/node" "github.com/ledgerwatch/erigon/p2p" + "github.com/ledgerwatch/erigon/p2p/dnsdisc" + "github.com/ledgerwatch/erigon/p2p/enode" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/engineapi" @@ -173,7 +172,7 @@ func NewBackend(stack *node.Node, config *ethconfig.Config, logger log.Logger) ( } // Assemble the Ethereum object - chainKv, err := node.OpenDatabase(stack.Config(), logger, kv.ChainDB) + chainKv, err := node.OpenDatabase(stack.Config(), kv.ChainDB) if err != nil { return nil, err } @@ -257,7 +256,6 @@ func NewBackend(stack *node.Node, config *ethconfig.Config, logger log.Logger) ( sentryCtx: ctx, sentryCancel: ctxCancel, config: config, - log: logger, chainDB: chainKv, networkID: config.NetworkID, etherbase: config.Miner.Etherbase, @@ -419,7 +417,6 @@ func NewBackend(stack *node.Node, config *ethconfig.Config, logger log.Logger) ( if chainConfig.Clique != nil { consensusConfig = &config.Clique } else if chainConfig.Aura != nil { - config.Aura.Etherbase = config.Miner.Etherbase consensusConfig = &config.Aura } else if chainConfig.Parlia != nil { consensusConfig = &config.Parlia @@ -428,7 +425,7 @@ func NewBackend(stack *node.Node, config *ethconfig.Config, logger log.Logger) ( } else { consensusConfig = &config.Ethash } - backend.engine = ethconsensusconfig.CreateConsensusEngine(chainConfig, logger, consensusConfig, config.Miner.Notify, config.Miner.Noverify, config.HeimdallgRPCAddress, config.HeimdallURL, config.WithoutHeimdall, stack.DataDir(), allSnapshots, false /* readonly */, backend.chainDB) + backend.engine = ethconsensusconfig.CreateConsensusEngine(chainConfig, consensusConfig, config.Miner.Notify, config.Miner.Noverify, config.HeimdallgRPCAddress, config.HeimdallURL, config.WithoutHeimdall, stack.DataDir(), allSnapshots, false /* readonly */, backend.chainDB) backend.forkValidator = engineapi.NewForkValidator(currentBlockNumber, inMemoryExecution, tmpdir) if err != nil { diff --git a/cmd/erigon-el/main.go b/cmd/erigon-el/main.go index 30b89cb98f4..0c915999100 100644 --- a/cmd/erigon-el/main.go +++ b/cmd/erigon-el/main.go @@ -52,15 +52,15 @@ func runErigon(cliCtx *cli.Context) error { } } - logger := logging.GetLoggerCtx("erigon", cliCtx) + logging.SetupLoggerCtx("erigon", cliCtx) // initializing the node and providing the current git commit there - logger.Info("Build info", "git_branch", params.GitBranch, "git_tag", params.GitTag, "git_commit", params.GitCommit) + log.Info("Build info", "git_branch", params.GitBranch, "git_tag", params.GitTag, "git_commit", params.GitCommit) nodeCfg := node.NewNodConfigUrfave(cliCtx) ethCfg := node.NewEthConfigUrfave(cliCtx, nodeCfg) - ethNode, err := backend.NewNode(nodeCfg, ethCfg, logger) + ethNode, err := backend.NewNode(nodeCfg, ethCfg, log.Root()) if err != nil { log.Error("Erigon startup", "err", err) return err diff --git a/cmd/erigon/main.go b/cmd/erigon/main.go index 6fede0ef395..432bcb0f437 100644 --- a/cmd/erigon/main.go +++ b/cmd/erigon/main.go @@ -18,7 +18,6 @@ import ( "github.com/ledgerwatch/erigon/params" erigonapp "github.com/ledgerwatch/erigon/turbo/app" erigoncli "github.com/ledgerwatch/erigon/turbo/cli" - "github.com/ledgerwatch/erigon/turbo/logging" "github.com/ledgerwatch/erigon/turbo/node" ) @@ -51,15 +50,13 @@ func runErigon(cliCtx *cli.Context) error { } } - logger := logging.GetLoggerCtx("erigon", cliCtx) - // initializing the node and providing the current git commit there - logger.Info("Build info", "git_branch", params.GitBranch, "git_tag", params.GitTag, "git_commit", params.GitCommit) + log.Info("Build info", "git_branch", params.GitBranch, "git_tag", params.GitTag, "git_commit", params.GitCommit) nodeCfg := node.NewNodConfigUrfave(cliCtx) ethCfg := node.NewEthConfigUrfave(cliCtx, nodeCfg) - ethNode, err := node.New(nodeCfg, ethCfg, logger) + ethNode, err := node.New(nodeCfg, ethCfg) if err != nil { log.Error("Erigon startup", "err", err) return err diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index 559fed975ca..c8e0292dab7 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -48,6 +48,7 @@ type stEnv struct { Coinbase libcommon.Address `json:"currentCoinbase" gencodec:"required"` Difficulty *big.Int `json:"currentDifficulty"` Random *big.Int `json:"currentRandom"` + MixDigest libcommon.Hash `json:"mixHash,omitempty"` ParentDifficulty *big.Int `json:"parentDifficulty"` GasLimit uint64 `json:"currentGasLimit" gencodec:"required"` Number uint64 `json:"currentNumber" gencodec:"required"` @@ -57,7 +58,9 @@ type stEnv struct { Ommers []ommer `json:"ommers,omitempty"` BaseFee *big.Int `json:"currentBaseFee,omitempty"` ParentUncleHash libcommon.Hash `json:"parentUncleHash"` + UncleHash libcommon.Hash `json:"uncleHash,omitempty"` Withdrawals []*types.Withdrawal `json:"withdrawals,omitempty"` + WithdrawalsHash *libcommon.Hash `json:"withdrawalsRoot,omitempty"` } type stEnvMarshaling struct { diff --git a/cmd/evm/internal/t8ntool/flags.go b/cmd/evm/internal/t8ntool/flags.go index bcef839dd50..3a42f32e542 100644 --- a/cmd/evm/internal/t8ntool/flags.go +++ b/cmd/evm/internal/t8ntool/flags.go @@ -99,7 +99,7 @@ var ( "\n\tSyntax (+ExtraEip)", strings.Join(tests.AvailableForks(), "\n\t "), strings.Join(vm.ActivateableEips(), ", ")), - Value: "ArrowGlacier", + Value: "Merge", } VerbosityFlag = cli.IntFlag{ Name: "verbosity", diff --git a/cmd/evm/internal/t8ntool/gen_stenv.go b/cmd/evm/internal/t8ntool/gen_stenv.go index bf84cc3c7bf..7f08b6a3735 100644 --- a/cmd/evm/internal/t8ntool/gen_stenv.go +++ b/cmd/evm/internal/t8ntool/gen_stenv.go @@ -11,6 +11,7 @@ import ( "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/math" + "github.com/ledgerwatch/erigon/core/types" ) var _ = (*stEnvMarshaling)(nil) @@ -30,6 +31,8 @@ func (s stEnv) MarshalJSON() ([]byte, error) { Ommers []ommer `json:"ommers,omitempty"` BaseFee *math.HexOrDecimal256 `json:"currentBaseFee,omitempty"` ParentUncleHash libcommon.Hash `json:"parentUncleHash"` + UncleHash libcommon.Hash `json:"uncleHash,omitempty"` + Withdrawals []*types.Withdrawal `json:"withdrawals,omitempty"` } var enc stEnv enc.Coinbase = common.UnprefixedAddress(s.Coinbase) @@ -44,6 +47,8 @@ func (s stEnv) MarshalJSON() ([]byte, error) { enc.Ommers = s.Ommers enc.BaseFee = (*math.HexOrDecimal256)(s.BaseFee) enc.ParentUncleHash = s.ParentUncleHash + enc.UncleHash = s.UncleHash + enc.Withdrawals = s.Withdrawals return json.Marshal(&enc) } @@ -62,6 +67,8 @@ func (s *stEnv) UnmarshalJSON(input []byte) error { Ommers []ommer `json:"ommers,omitempty"` BaseFee *math.HexOrDecimal256 `json:"currentBaseFee,omitempty"` ParentUncleHash *libcommon.Hash `json:"parentUncleHash"` + UncleHash libcommon.Hash `json:"uncleHash,omitempty"` + Withdrawals []*types.Withdrawal `json:"withdrawals,omitempty"` } var dec stEnv if err := json.Unmarshal(input, &dec); err != nil { @@ -107,5 +114,10 @@ func (s *stEnv) UnmarshalJSON(input []byte) error { if dec.ParentUncleHash != nil { s.ParentUncleHash = *dec.ParentUncleHash } + s.UncleHash = dec.UncleHash + if dec.Withdrawals != nil { + s.Withdrawals = dec.Withdrawals + } + return nil } diff --git a/cmd/evm/internal/t8ntool/transition.go b/cmd/evm/internal/t8ntool/transition.go index d0dd21f46bc..16da940872c 100644 --- a/cmd/evm/internal/t8ntool/transition.go +++ b/cmd/evm/internal/t8ntool/transition.go @@ -28,20 +28,22 @@ import ( "path/filepath" "github.com/holiman/uint256" + "github.com/ledgerwatch/log/v3" + "github.com/urfave/cli/v2" + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/common/length" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv/kvcfg" "github.com/ledgerwatch/erigon-lib/kv/memdb" - "github.com/ledgerwatch/log/v3" - "github.com/urfave/cli/v2" "github.com/ledgerwatch/erigon/cmd/rpcdaemon/commands" "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/common/math" "github.com/ledgerwatch/erigon/consensus/ethash" + "github.com/ledgerwatch/erigon/consensus/serenity" "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/core/state" "github.com/ledgerwatch/erigon/core/types" @@ -231,18 +233,28 @@ func Main(ctx *cli.Context) error { if prestate.Env.BaseFee == nil { return NewError(ErrorVMConfig, errors.New("EIP-1559 config but missing 'currentBaseFee' in env section")) } - } - - // Sanity check, to not `panic` in state_transition - if prestate.Env.Random != nil && !eip1559 { - return NewError(ErrorVMConfig, errors.New("can only apply RANDOM on top of London chain rules")) + } else { + prestate.Env.Random = nil } if chainConfig.IsShanghai(prestate.Env.Timestamp) && prestate.Env.Withdrawals == nil { return NewError(ErrorVMConfig, errors.New("Shanghai config but missing 'withdrawals' in env section")) } - if env := prestate.Env; env.Difficulty == nil { + isMerged := chainConfig.TerminalTotalDifficulty != nil && chainConfig.TerminalTotalDifficulty.BitLen() == 0 + env := prestate.Env + if isMerged { + // post-merge: + // - random must be supplied + // - difficulty must be zero + switch { + case env.Random == nil: + return NewError(ErrorVMConfig, errors.New("post-merge requires currentRandom to be defined in env")) + case env.Difficulty != nil && env.Difficulty.BitLen() != 0: + return NewError(ErrorVMConfig, errors.New("post-merge difficulty must be zero (or omitted) in env")) + } + prestate.Env.Difficulty = nil + } else if env.Difficulty == nil { // If difficulty was not provided by caller, we need to calculate it. switch { case env.ParentDifficulty == nil: @@ -282,6 +294,7 @@ func Main(ctx *cli.Context) error { return h } db := memdb.New("" /* tmpDir */) + defer db.Close() tx, err := db.BeginRw(context.Background()) if err != nil { @@ -290,9 +303,11 @@ func Main(ctx *cli.Context) error { defer tx.Rollback() reader, writer := MakePreState(chainConfig.Rules(0, 0), tx, prestate.Pre) - engine := ethash.NewFaker() + // serenity engine can be used for pre-merge blocks as well, as it + // redirects to the ethash engine based on the block number + engine := serenity.New(ðash.FakeEthash{}) - result, err := core.ExecuteBlockEphemerally(chainConfig, &vmConfig, getHash, engine, block, reader, writer, nil, nil, getTracer) + result, err := core.ExecuteBlockEphemerally(chainConfig, &vmConfig, getHash, engine, block, reader, writer, nil, getTracer) if hashError != nil { return NewError(ErrorMissingBlockhash, fmt.Errorf("blockhash error: %v", err)) @@ -525,7 +540,7 @@ func saveFile(baseDir, filename string, data interface{}) error { // dispatchOutput writes the output data to either stderr or stdout, or to the specified // files -func dispatchOutput(ctx *cli.Context, baseDir string, result *core.EphemeralExecResult, alloc Alloc, body hexutil.Bytes) error { +func dispatchOutput(ctx *cli.Context, baseDir string, result *core.EphemeralExecResult, alloc Alloc, body hexutility.Bytes) error { stdOutObject := make(map[string]interface{}) stdErrObject := make(map[string]interface{}) dispatch := func(baseDir, fName, name string, obj interface{}) error { @@ -571,13 +586,16 @@ func dispatchOutput(ctx *cli.Context, baseDir string, result *core.EphemeralExec func NewHeader(env stEnv) *types.Header { var header types.Header - header.UncleHash = env.ParentUncleHash header.Coinbase = env.Coinbase header.Difficulty = env.Difficulty - header.Number = big.NewInt(int64(env.Number)) header.GasLimit = env.GasLimit + header.Number = big.NewInt(int64(env.Number)) header.Time = env.Timestamp header.BaseFee = env.BaseFee + header.MixDigest = env.MixDigest + + header.UncleHash = env.UncleHash + header.WithdrawalsHash = env.WithdrawalsHash return &header } diff --git a/cmd/evm/main.go b/cmd/evm/main.go index f18e30c6d0b..5b95192c089 100644 --- a/cmd/evm/main.go +++ b/cmd/evm/main.go @@ -26,7 +26,7 @@ import ( "github.com/urfave/cli/v2" "github.com/ledgerwatch/erigon/cmd/evm/internal/t8ntool" - "github.com/ledgerwatch/erigon/cmd/utils" + "github.com/ledgerwatch/erigon/cmd/utils/flags" "github.com/ledgerwatch/erigon/params" cli2 "github.com/ledgerwatch/erigon/turbo/cli" ) @@ -63,12 +63,12 @@ var ( Usage: "gas limit for the evm", Value: 10000000000, } - PriceFlag = utils.BigFlag{ + PriceFlag = flags.BigFlag{ Name: "price", Usage: "price set for the evm", Value: new(big.Int), } - ValueFlag = utils.BigFlag{ + ValueFlag = flags.BigFlag{ Name: "value", Usage: "value set for the evm", Value: new(big.Int), diff --git a/cmd/evm/runner.go b/cmd/evm/runner.go index 298b9a61da7..547dd534d8a 100644 --- a/cmd/evm/runner.go +++ b/cmd/evm/runner.go @@ -33,8 +33,11 @@ import ( "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" common2 "github.com/ledgerwatch/erigon-lib/common/dbg" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/kv/kvcfg" "github.com/ledgerwatch/erigon-lib/kv/memdb" + "github.com/ledgerwatch/erigon/cmd/utils/flags" + "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/log/v3" "github.com/urfave/cli/v2" @@ -59,7 +62,7 @@ var runCommand = cli.Command{ // readGenesis will read the given JSON format genesis file and return // the initialized Genesis structure -func readGenesis(genesisPath string) *core.Genesis { +func readGenesis(genesisPath string) *types.Genesis { // Make sure we have a valid genesis JSON //genesisPath := ctx.Args().First() if len(genesisPath) == 0 { @@ -76,7 +79,7 @@ func readGenesis(genesisPath string) *core.Genesis { } }(file) - genesis := new(core.Genesis) + genesis := new(types.Genesis) if err := json.NewDecoder(file).Decode(genesis); err != nil { utils.Fatalf("invalid genesis file: %v", err) } @@ -136,7 +139,7 @@ func runCmd(ctx *cli.Context) error { chainConfig *chain.Config sender = libcommon.BytesToAddress([]byte("sender")) receiver = libcommon.BytesToAddress([]byte("receiver")) - genesisConfig *core.Genesis + genesisConfig *types.Genesis ) if ctx.Bool(MachineFlag.Name) { tracer = logger.NewJSONLogger(logconfig, os.Stdout) @@ -147,13 +150,14 @@ func runCmd(ctx *cli.Context) error { debugLogger = logger.NewStructLogger(logconfig) } db := memdb.New("") + defer db.Close() if ctx.String(GenesisFlag.Name) != "" { gen := readGenesis(ctx.String(GenesisFlag.Name)) - gen.MustCommit(db, "") + core.MustCommitGenesis(gen, db, "") genesisConfig = gen chainConfig = gen.Config } else { - genesisConfig = new(core.Genesis) + genesisConfig = new(types.Genesis) } tx, err := db.BeginRw(context.Background()) if err != nil { @@ -202,7 +206,7 @@ func runCmd(ctx *cli.Context) error { fmt.Printf("Invalid input length for hex data (%d)\n", len(hexcode)) os.Exit(1) } - code = common.FromHex(string(hexcode)) + code = hexutility.MustDecodeHex(string(hexcode)) } else if fn := ctx.Args().First(); len(fn) > 0 { // EASM-file to compile src, err := os.ReadFile(fn) @@ -219,8 +223,8 @@ func runCmd(ctx *cli.Context) error { if genesisConfig.GasLimit != 0 { initialGas = genesisConfig.GasLimit } - value, _ := uint256.FromBig(utils.BigFlagValue(ctx, ValueFlag.Name)) - gasPrice, _ := uint256.FromBig(utils.BigFlagValue(ctx, PriceFlag.Name)) + value, _ := uint256.FromBig(flags.GlobalBig(ctx, ValueFlag.Name)) + gasPrice, _ := uint256.FromBig(flags.GlobalBig(ctx, PriceFlag.Name)) runtimeConfig := runtime.Config{ Origin: sender, State: statedb, @@ -266,7 +270,7 @@ func runCmd(ctx *cli.Context) error { } else { hexInput = []byte(ctx.String(InputFlag.Name)) } - input := common.FromHex(string(bytes.TrimSpace(hexInput))) + input := hexutility.MustDecodeHex(string(bytes.TrimSpace(hexInput))) var execFunc func() ([]byte, uint64, error) if ctx.Bool(CreateFlag.Name) { diff --git a/cmd/evm/staterunner.go b/cmd/evm/staterunner.go index 0bf182b1be5..3c0c332569c 100644 --- a/cmd/evm/staterunner.go +++ b/cmd/evm/staterunner.go @@ -22,10 +22,13 @@ import ( "errors" "fmt" "os" + "path/filepath" + "github.com/c2h5oh/datasize" libcommon "github.com/ledgerwatch/erigon-lib/common" - "github.com/ledgerwatch/erigon-lib/kv/memdb" + "github.com/ledgerwatch/erigon-lib/kv/mdbx" "github.com/ledgerwatch/log/v3" + mdbx2 "github.com/torquem-ch/mdbx-go/mdbx" "github.com/urfave/cli/v2" "github.com/ledgerwatch/erigon/core/state" @@ -114,7 +117,17 @@ func aggregateResultsFromStateTests( Tracer: tracer, Debug: ctx.Bool(DebugFlag.Name) || ctx.Bool(MachineFlag.Name), } - db := memdb.New("") + + //this DB is shared. means: + // - faster sequential tests: don't need create/delete db + // - less parallelism: multiple processes can open same DB but only 1 can create rw-transaction (other will wait when 1-st finish) + db := mdbx.NewMDBX(log.New()). + Path(filepath.Join(os.TempDir(), "erigon-statetest")). + Flags(func(u uint) uint { + return u | mdbx2.UtterlyNoSync | mdbx2.NoMetaSync | mdbx2.LifoReclaim | mdbx2.NoMemInit + }). + GrowthStep(1 * datasize.MB). + MustOpen() defer db.Close() tx, txErr := db.BeginRw(context.Background()) diff --git a/cmd/evm/t8n_test.go b/cmd/evm/t8n_test.go index e5bd4ab19a8..509e93bb6f2 100644 --- a/cmd/evm/t8n_test.go +++ b/cmd/evm/t8n_test.go @@ -188,6 +188,14 @@ func TestT8n(t *testing.T) { expOut: "exp_arrowglacier.json", output: t8nOutput{alloc: true, result: true}, }, + { // eip-4895 + base: "./testdata/26", + input: t8nInput{ + "alloc.json", "txs.json", "env.json", "Shanghai", + }, + expOut: "exp.json", + output: t8nOutput{alloc: true, result: true}, + }, } { args := []string{"t8n"} diff --git a/cmd/evm/testdata/26/alloc.json b/cmd/evm/testdata/26/alloc.json new file mode 100644 index 00000000000..d67655a8a8e --- /dev/null +++ b/cmd/evm/testdata/26/alloc.json @@ -0,0 +1,8 @@ +{ + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "balance": "0x0", + "code": "0x", + "nonce": "0xac", + "storage": {} + } +} diff --git a/cmd/evm/testdata/26/env.json b/cmd/evm/testdata/26/env.json new file mode 100644 index 00000000000..03d817b93bc --- /dev/null +++ b/cmd/evm/testdata/26/env.json @@ -0,0 +1,17 @@ +{ + "currentCoinbase": "0xc94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "currentDifficulty": null, + "currentRandom": "0xdeadc0de", + "currentGasLimit": "0x750a163df65e8a", + "currentBaseFee": "0x500", + "currentNumber": "1", + "currentTimestamp": "1000", + "withdrawals": [ + { + "index": "0x42", + "validatorIndex": "0x42", + "address": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "amount": "0x2a" + } + ] +} diff --git a/cmd/evm/testdata/26/exp.json b/cmd/evm/testdata/26/exp.json new file mode 100644 index 00000000000..86438389cb4 --- /dev/null +++ b/cmd/evm/testdata/26/exp.json @@ -0,0 +1,18 @@ +{ + "alloc": { + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "balance": "0x9c7652400", + "nonce": "0xac" + } + }, + "result": { + "stateRoot": "0x6e061c2f6513af27d267a0e3b07cb9a10f1ba3a0f65ab648d3a17c36e15021d2", + "txRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "receipts": null, + "currentDifficulty": "0x0", + "gasUsed": "0x0" + } + } \ No newline at end of file diff --git a/cmd/evm/testdata/26/txs.json b/cmd/evm/testdata/26/txs.json new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/cmd/evm/testdata/26/txs.json @@ -0,0 +1 @@ +[] diff --git a/cmd/hack/hack.go b/cmd/hack/hack.go index b91a6f0faa1..0a9dcc27925 100644 --- a/cmd/hack/hack.go +++ b/cmd/hack/hack.go @@ -1403,7 +1403,7 @@ func main() { debug.RaiseFdLimit() flag.Parse() - _ = logging.GetLogger("hack") + logging.SetupLogger("hack") if *cpuprofile != "" { f, err := os.Create(*cpuprofile) diff --git a/cmd/integration/commands/stages.go b/cmd/integration/commands/stages.go index 04b429ef266..ae7aca61760 100644 --- a/cmd/integration/commands/stages.go +++ b/cmd/integration/commands/stages.go @@ -815,7 +815,7 @@ func stageTrie(db kv.RwDB, ctx context.Context) error { log.Info("StageExec", "progress", execStage.BlockNumber) log.Info("StageTrie", "progress", s.BlockNumber) - cfg := stagedsync.StageTrieCfg(db, true, true, false, dirs.Tmp, getBlockReader(db), nil, historyV3, agg) + cfg := stagedsync.StageTrieCfg(db, true /* checkRoot */, true /* saveHashesToDb */, false /* badBlockHalt */, dirs.Tmp, getBlockReader(db), nil /* hd */, historyV3, agg) if unwind > 0 { u := sync.NewUnwindState(stages.IntermediateHashes, s.BlockNumber-unwind, s.BlockNumber) if err := stagedsync.UnwindIntermediateHashesStage(u, s, tx, cfg, ctx); err != nil { @@ -1344,7 +1344,6 @@ func overrideStorageMode(db kv.RwDB) error { } func initConsensusEngine(cc *chain2.Config, datadir string, db kv.RwDB) (engine consensus.Engine) { - l := log.New() snapshots, _ := allSnapshots(context.Background(), db) config := ethconfig.Defaults @@ -1353,7 +1352,6 @@ func initConsensusEngine(cc *chain2.Config, datadir string, db kv.RwDB) (engine if cc.Clique != nil { consensusConfig = params.CliqueSnapshot } else if cc.Aura != nil { - config.Aura.Etherbase = config.Miner.Etherbase consensusConfig = &config.Aura } else if cc.Parlia != nil { consensusConfig = &config.Parlia @@ -1362,5 +1360,5 @@ func initConsensusEngine(cc *chain2.Config, datadir string, db kv.RwDB) (engine } else { consensusConfig = &config.Ethash } - return ethconsensusconfig.CreateConsensusEngine(cc, l, consensusConfig, config.Miner.Notify, config.Miner.Noverify, HeimdallgRPCAddress, HeimdallURL, config.WithoutHeimdall, datadir, snapshots, db.ReadOnly(), db) + return ethconsensusconfig.CreateConsensusEngine(cc, consensusConfig, config.Miner.Notify, config.Miner.Noverify, HeimdallgRPCAddress, HeimdallURL, config.WithoutHeimdall, datadir, snapshots, db.ReadOnly(), db) } diff --git a/cmd/integration/commands/state_domains.go b/cmd/integration/commands/state_domains.go new file mode 100644 index 00000000000..9d4047081b7 --- /dev/null +++ b/cmd/integration/commands/state_domains.go @@ -0,0 +1,762 @@ +package commands + +import ( + "bytes" + "context" + "encoding/hex" + "errors" + "fmt" + "os" + "path/filepath" + "runtime" + "strings" + "time" + + "github.com/VictoriaMetrics/metrics" + "github.com/holiman/uint256" + "github.com/ledgerwatch/log/v3" + "github.com/spf13/cobra" + + chain2 "github.com/ledgerwatch/erigon-lib/chain" + "github.com/ledgerwatch/erigon-lib/commitment" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/datadir" + "github.com/ledgerwatch/erigon-lib/common/dbg" + "github.com/ledgerwatch/erigon-lib/common/length" + "github.com/ledgerwatch/erigon-lib/kv" + kv2 "github.com/ledgerwatch/erigon-lib/kv/mdbx" + libstate "github.com/ledgerwatch/erigon-lib/state" + + "github.com/ledgerwatch/erigon/cmd/hack/tool/fromdb" + "github.com/ledgerwatch/erigon/cmd/state/exec3" + "github.com/ledgerwatch/erigon/cmd/utils" + "github.com/ledgerwatch/erigon/consensus" + "github.com/ledgerwatch/erigon/consensus/misc" + "github.com/ledgerwatch/erigon/core" + "github.com/ledgerwatch/erigon/core/state" + "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/core/types/accounts" + "github.com/ledgerwatch/erigon/core/vm" + "github.com/ledgerwatch/erigon/eth/ethconfig" + "github.com/ledgerwatch/erigon/node/nodecfg" + erigoncli "github.com/ledgerwatch/erigon/turbo/cli" + "github.com/ledgerwatch/erigon/turbo/services" +) + +func init() { + withConfig(stateDomains) + withDataDir(stateDomains) + withUnwind(stateDomains) + withUnwindEvery(stateDomains) + withBlock(stateDomains) + withIntegrityChecks(stateDomains) + withChain(stateDomains) + withHeimdall(stateDomains) + withWorkers(stateDomains) + withStartTx(stateDomains) + withCommitment(stateDomains) + withTraceFromTx(stateDomains) + + stateDomains.Flags().Uint64Var(&stepSize, "step-size", ethconfig.HistoryV3AggregationStep, "size of aggregation step, tx") + stateDomains.Flags().Uint64Var(&lastStep, "last-step", 0, "step of last aggregation, step=txnum/step-size, unsigned integers only") + + rootCmd.AddCommand(stateDomains) + + withDataDir(readDomains) + withChain(readDomains) + withHeimdall(readDomains) + withWorkers(readDomains) + withStartTx(readDomains) + + rootCmd.AddCommand(readDomains) +} + +// if trie variant is not hex, we could not have another rootHash with to verify it +var ( + stepSize uint64 + lastStep uint64 + dirtySpaceThreshold = uint64(2 * 1024 * 1024 * 1024) /* threshold of dirty space in MDBX transaction that triggers a commit */ + blockRootMismatchExpected bool + + mxBlockExecutionTimer = metrics.GetOrCreateSummary("chain_execution_seconds") + mxCommitTook = metrics.GetOrCreateHistogram("domain_commit_took") +) + +// write command to just seek and query state by addr and domain from state db and files (if any) +var readDomains = &cobra.Command{ + Use: "read_domains", + Short: `Run block execution and commitment with Domains.`, + Example: "go run ./cmd/integration read_domains --datadir=... --verbosity=3", + ValidArgs: []string{"account", "storage", "code", "commitment"}, + Args: cobra.ArbitraryArgs, + Run: func(cmd *cobra.Command, args []string) { + ctx, _ := libcommon.RootContext() + cfg := &nodecfg.DefaultConfig + utils.SetNodeConfigCobra(cmd, cfg) + ethConfig := ðconfig.Defaults + ethConfig.Genesis = core.GenesisBlockByChainName(chain) + erigoncli.ApplyFlagsForEthConfigCobra(cmd.Flags(), ethConfig) + + var readFromDomain string + var addrs [][]byte + for i := 0; i < len(args); i++ { + if i == 0 { + switch s := strings.ToLower(args[i]); s { + case "account", "storage", "code", "commitment": + readFromDomain = s + default: + log.Error("invalid domain to read from", "arg", args[i]) + return + } + continue + } + addr, err := hex.DecodeString(strings.TrimPrefix(args[i], "0x")) + if err != nil { + log.Warn("invalid address passed", "str", args[i], "at position", i, "err", err) + continue + } + addrs = append(addrs, addr) + } + + dirs := datadir.New(datadirCli) + chainDb := openDB(dbCfg(kv.ChainDB, dirs.Chaindata), true) + defer chainDb.Close() + + stateDb, err := kv2.NewMDBX(log.New()).Path(filepath.Join(dirs.DataDir, "statedb")).WriteMap().Open() + if err != nil { + return + } + defer stateDb.Close() + + if err := requestDomains(chainDb, stateDb, ctx, readFromDomain, addrs); err != nil { + if !errors.Is(err, context.Canceled) { + log.Error(err.Error()) + } + return + } + }, +} + +func requestDomains(chainDb, stateDb kv.RwDB, ctx context.Context, readDomain string, addrs [][]byte) error { + trieVariant := commitment.ParseTrieVariant(commitmentTrie) + if trieVariant != commitment.VariantHexPatriciaTrie { + blockRootMismatchExpected = true + } + mode := libstate.ParseCommitmentMode(commitmentMode) + libstate.COMPARE_INDEXES = true + + _, _, _, agg := newDomains(ctx, chainDb, stepSize, mode, trieVariant) + defer agg.Close() + + histTx, err := chainDb.BeginRo(ctx) + must(err) + defer histTx.Rollback() + + stateTx, err := stateDb.BeginRw(ctx) + must(err) + defer stateTx.Rollback() + + agg.SetTx(stateTx) + defer agg.StartWrites().FinishWrites() + + latestBlock, latestTx, err := agg.SeekCommitment() + if err != nil && startTxNum != 0 { + return fmt.Errorf("failed to seek commitment to tx %d: %w", startTxNum, err) + } + if latestTx < startTxNum { + return fmt.Errorf("latest available tx to start is %d and its less than start tx %d", latestTx, startTxNum) + } + if latestTx > 0 { + log.Info("aggregator files opened", "txn", latestTx, "block", latestBlock) + } + agg.SetTxNum(latestTx) + + r := ReaderWrapper4{ + roTx: histTx, + ac: agg.MakeContext(), + } + + switch readDomain { + case "account": + for _, addr := range addrs { + acc, err := r.ReadAccountData(libcommon.BytesToAddress(addr)) + if err != nil { + log.Error("failed to read account", "addr", addr, "err", err) + continue + } + fmt.Printf("%x: nonce=%d balance=%d code=%x root=%x\n", addr, acc.Nonce, acc.Balance.Uint64(), acc.CodeHash, acc.Root) + } + case "storage": + for _, addr := range addrs { + a, s := libcommon.BytesToAddress(addr[:length.Addr]), libcommon.BytesToHash(addr[length.Addr:]) + st, err := r.ReadAccountStorage(a, 0, &s) + if err != nil { + log.Error("failed to read storage", "addr", a.String(), "key", s.String(), "err", err) + continue + } + fmt.Printf("%s %s -> %x\n", a.String(), s.String(), st) + } + case "code": + for _, addr := range addrs { + code, err := r.ReadAccountCode(libcommon.BytesToAddress(addr), 0, libcommon.Hash{}) + if err != nil { + log.Error("failed to read code", "addr", addr, "err", err) + continue + } + fmt.Printf("%s: %x\n", addr, code) + } + } + return nil +} + +// write command to just seek and query state by addr and domain from state db and files (if any) +var stateDomains = &cobra.Command{ + Use: "state_domains", + Short: `Run block execution and commitment with Domains.`, + Example: "go run ./cmd/integration state_domains --datadir=... --verbosity=3 --unwind=100 --unwind.every=100000 --block=2000000", + Run: func(cmd *cobra.Command, args []string) { + ctx, _ := libcommon.RootContext() + cfg := &nodecfg.DefaultConfig + utils.SetNodeConfigCobra(cmd, cfg) + ethConfig := ðconfig.Defaults + ethConfig.Genesis = core.GenesisBlockByChainName(chain) + erigoncli.ApplyFlagsForEthConfigCobra(cmd.Flags(), ethConfig) + + dirs := datadir.New(datadirCli) + chainDb := openDB(dbCfg(kv.ChainDB, dirs.Chaindata), true) + defer chainDb.Close() + + //stateDB := kv.Label(6) + //stateOpts := dbCfg(stateDB, filepath.Join(dirs.DataDir, "statedb")).WriteMap() + //stateOpts.MapSize(1 * datasize.TB).WriteMap().DirtySpace(dirtySpaceThreshold) + //stateDb := openDB(stateOpts, true) + //defer stateDb.Close() + + stateDb, err := kv2.NewMDBX(log.New()).Path(filepath.Join(dirs.DataDir, "statedb")).WriteMap().Open() + if err != nil { + return + } + defer stateDb.Close() + + if err := loopProcessDomains(chainDb, stateDb, ctx); err != nil { + if !errors.Is(err, context.Canceled) { + log.Error(err.Error()) + } + return + } + }, +} + +func loopProcessDomains(chainDb, stateDb kv.RwDB, ctx context.Context) error { + trieVariant := commitment.ParseTrieVariant(commitmentTrie) + if trieVariant != commitment.VariantHexPatriciaTrie { + blockRootMismatchExpected = true + } + mode := libstate.ParseCommitmentMode(commitmentMode) + + engine, _, _, agg := newDomains(ctx, chainDb, stepSize, mode, trieVariant) + defer agg.Close() + + histTx, err := chainDb.BeginRo(ctx) + must(err) + defer histTx.Rollback() + + stateTx, err := stateDb.BeginRw(ctx) + must(err) + defer stateTx.Rollback() + + agg.SetTx(stateTx) + defer agg.StartWrites().FinishWrites() + + latestBlock, latestTx, err := agg.SeekCommitment() + if err != nil && startTxNum != 0 { + return fmt.Errorf("failed to seek commitment to tx %d: %w", startTxNum, err) + } + if latestTx < startTxNum { + return fmt.Errorf("latest available tx to start is %d and its less than start tx %d", latestTx, startTxNum) + } + if latestTx > 0 { + log.Info("aggregator files opened", "txn", latestTx, "block", latestBlock) + } + + aggWriter, aggReader := WrapAggregator(agg, stateTx) + proc := blockProcessor{ + chainConfig: fromdb.ChainConfig(chainDb), + vmConfig: vm.Config{}, + engine: engine, + reader: aggReader, + writer: aggWriter, + blockReader: getBlockReader(chainDb), + stateTx: stateTx, + stateDb: stateDb, + blockNum: latestBlock, + txNum: latestTx, + startTxNum: latestTx, + histTx: histTx, + agg: agg, + logger: log.New(), + stat: stat4{startedAt: time.Now()}, + } + if proc.txNum > 0 { + proc.txNum-- + } + if proc.blockNum == 0 { + proc.txNum = 2 + } + + mergedRoots := agg.AggregatedRoots() + go proc.PrintStatsLoop(ctx, 30*time.Second) + + if proc.startTxNum == 0 { + genesis := core.GenesisBlockByChainName(chain) + if err := proc.ApplyGenesis(genesis); err != nil { + return err + } + } + + for { + // Check for interrupts + select { + case <-ctx.Done(): + log.Info(fmt.Sprintf("interrupted, please wait for commitment and cleanup, next time start with --tx %d", proc.txNum)) + rh, err := proc.agg.ComputeCommitment(true, false) + if err != nil { + log.Error("failed to compute commitment", "err", err) + } + log.Info("commitment: state root computed", "root", hex.EncodeToString(rh)) + if err := agg.Flush(ctx); err != nil { + log.Error("failed to flush aggregator", "err", err) + } + os.Exit(0) + case <-mergedRoots: // notified with rootHash of latest aggregation + if err := proc.commit(ctx); err != nil { + log.Error("chainDb commit on merge", "err", err) + } + default: + } + + if lastStep > 0 && proc.txNum/stepSize >= lastStep { + log.Info("last step reached") + // Commit transaction only when interrupted or just before computing commitment (so it can be re-done) + break + } + + err := proc.ProcessNext(ctx) + if err != nil { + return err + } + } + return nil +} + +type blockProcessor struct { + engine consensus.Engine + agg *libstate.Aggregator + blockReader services.FullBlockReader + writer *WriterWrapper4 + reader *ReaderWrapper4 + stateDb kv.RwDB + stateTx kv.RwTx + histTx kv.Tx + blockNum uint64 + startTxNum uint64 + txNum uint64 + stat stat4 + trace bool + logger log.Logger + vmConfig vm.Config + chainConfig *chain2.Config +} + +func (b *blockProcessor) getHeader(hash libcommon.Hash, number uint64) *types.Header { + h, err := b.blockReader.Header(context.Background(), b.histTx, hash, number) + if err != nil { + panic(err) + } + return h +} + +func (b *blockProcessor) commit(ctx context.Context) error { + if b.stateDb == nil || b.stateTx == nil { + return fmt.Errorf("commit failed due to invalid chainDb/rwTx") + } + + s := time.Now() + defer mxCommitTook.UpdateDuration(s) + + var spaceDirty uint64 + var err error + if spaceDirty, _, err = b.stateTx.(*kv2.MdbxTx).SpaceDirty(); err != nil { + return fmt.Errorf("retrieving spaceDirty: %w", err) + } + if spaceDirty >= dirtySpaceThreshold { + b.logger.Info("Initiated tx commit", "block", b.blockNum, "space dirty", libcommon.ByteCount(spaceDirty)) + } + + b.logger.Info("database commitment", "block", b.blockNum, "txNum", b.txNum, "uptime", time.Since(b.stat.startedAt)) + if err := b.agg.Flush(ctx); err != nil { + return err + } + if err = b.stateTx.Commit(); err != nil { + return err + } + + if b.stateTx, err = b.stateDb.BeginRw(ctx); err != nil { + return err + } + + b.agg.SetTx(b.stateTx) + b.reader.SetTx(b.stateTx, b.agg.MakeContext()) + + return nil +} + +func (b *blockProcessor) PrintStatsLoop(ctx context.Context, interval time.Duration) { + ticker := time.NewTicker(interval) + defer ticker.Stop() + + for { + select { + case <-ctx.Done(): + return + case <-ticker.C: + b.stat.delta(b.blockNum, b.txNum).print(b.agg.Stats(), b.logger) + } + } +} + +func (b *blockProcessor) ApplyGenesis(genesis *types.Genesis) error { + b.logger.Info("apply genesis", "chain_id", genesis.Config.ChainID) + genBlock, genesisIbs, err := core.GenesisToBlock(genesis, "") + if err != nil { + return err + } + b.agg.SetTxNum(0) + if err = genesisIbs.CommitBlock(&chain2.Rules{}, b.writer); err != nil { + return fmt.Errorf("cannot write state: %w", err) + } + + blockRootHash, err := b.agg.ComputeCommitment(true, false) + if err != nil { + return err + } + if err = b.agg.FinishTx(); err != nil { + return err + } + + genesisRootHash := genBlock.Root() + if !blockRootMismatchExpected && !bytes.Equal(blockRootHash, genesisRootHash[:]) { + return fmt.Errorf("genesis root hash mismatch: expected %x got %x", genesisRootHash, blockRootHash) + } + return nil +} + +func (b *blockProcessor) ProcessNext(ctx context.Context) error { + b.blockNum++ + b.trace = traceFromTx > 0 && b.txNum == traceFromTx + + blockHash, err := b.blockReader.CanonicalHash(ctx, b.histTx, b.blockNum) + if err != nil { + return err + } + + block, _, err := b.blockReader.BlockWithSenders(ctx, b.histTx, blockHash, b.blockNum) + if err != nil { + return err + } + if block == nil { + b.logger.Info("history: block is nil", "block", b.blockNum) + return fmt.Errorf("block %d is nil", b.blockNum) + } + + b.agg.SetTx(b.stateTx) + b.agg.SetTxNum(b.txNum) + b.agg.SetBlockNum(b.blockNum) + + if _, err = b.applyBlock(ctx, block); err != nil { + b.logger.Error("processing error", "block", b.blockNum, "err", err) + return fmt.Errorf("processing block %d: %w", b.blockNum, err) + } + return err +} + +func (b *blockProcessor) applyBlock( + ctx context.Context, + block *types.Block, +) (types.Receipts, error) { + defer mxBlockExecutionTimer.UpdateDuration(time.Now()) + + header := block.Header() + b.vmConfig.Debug = true + gp := new(core.GasPool).AddGas(block.GasLimit()) + usedGas := new(uint64) + var receipts types.Receipts + rules := b.chainConfig.Rules(block.NumberU64(), block.Time()) + + b.blockNum = block.NumberU64() + b.writer.w.SetTxNum(b.txNum) + + daoFork := b.txNum >= b.startTxNum && b.chainConfig.DAOForkBlock != nil && b.chainConfig.DAOForkBlock.Cmp(block.Number()) == 0 + if daoFork { + ibs := state.New(b.reader) + // TODO Actually add tracing to the DAO related accounts + misc.ApplyDAOHardFork(ibs) + if err := ibs.FinalizeTx(rules, b.writer); err != nil { + return nil, err + } + if err := b.writer.w.FinishTx(); err != nil { + return nil, fmt.Errorf("finish daoFork failed: %w", err) + } + } + + b.txNum++ // Pre-block transaction + b.writer.w.SetTxNum(b.txNum) + if err := b.writer.w.FinishTx(); err != nil { + return nil, fmt.Errorf("finish pre-block tx %d (block %d) has failed: %w", b.txNum, block.NumberU64(), err) + } + + getHashFn := core.GetHashFn(header, b.getHeader) + parentHeader := b.getHeader(block.ParentHash(), b.blockNum-1) + for i, tx := range block.Transactions() { + if b.txNum >= b.startTxNum { + ibs := state.New(b.reader) + ibs.Prepare(tx.Hash(), block.Hash(), i) + ct := exec3.NewCallTracer() + b.vmConfig.Tracer = ct + receipt, _, err := core.ApplyTransaction(b.chainConfig, getHashFn, b.engine, nil, gp, ibs, b.writer, header, tx, usedGas, b.vmConfig, parentHeader.ExcessDataGas) + if err != nil { + return nil, fmt.Errorf("could not apply tx %d [%x] failed: %w", i, tx.Hash(), err) + } + for from := range ct.Froms() { + if err := b.writer.w.AddTraceFrom(from[:]); err != nil { + return nil, err + } + } + for to := range ct.Tos() { + if err := b.writer.w.AddTraceTo(to[:]); err != nil { + return nil, err + } + } + receipts = append(receipts, receipt) + for _, log := range receipt.Logs { + if err = b.writer.w.AddLogAddr(log.Address[:]); err != nil { + return nil, fmt.Errorf("adding event log for addr %x: %w", log.Address, err) + } + for _, topic := range log.Topics { + if err = b.writer.w.AddLogTopic(topic[:]); err != nil { + return nil, fmt.Errorf("adding event log for topic %x: %w", topic, err) + } + } + } + if err = b.writer.w.FinishTx(); err != nil { + return nil, fmt.Errorf("finish tx %d [%x] failed: %w", i, tx.Hash(), err) + } + if b.trace { + fmt.Printf("FinishTx called for blockNum=%d, txIndex=%d, txNum=%d txHash=[%x]\n", b.blockNum, i, b.txNum, tx.Hash()) + } + } + b.txNum++ + b.writer.w.SetTxNum(b.txNum) + } + + if b.txNum >= b.startTxNum { + if b.chainConfig.IsByzantium(block.NumberU64()) { + receiptSha := types.DeriveSha(receipts) + if receiptSha != block.ReceiptHash() { + fmt.Printf("mismatched receipt headers for block %d\n", block.NumberU64()) + for j, receipt := range receipts { + fmt.Printf("tx %d, used gas: %d\n", j, receipt.GasUsed) + } + } + } + ibs := state.New(b.reader) + if err := b.writer.w.AddTraceTo(block.Coinbase().Bytes()); err != nil { + return nil, fmt.Errorf("adding coinbase trace: %w", err) + } + for _, uncle := range block.Uncles() { + if err := b.writer.w.AddTraceTo(uncle.Coinbase.Bytes()); err != nil { + return nil, fmt.Errorf("adding uncle trace: %w", err) + } + } + + // Finalize the block, applying any consensus engine specific extras (e.g. block rewards) + if _, _, err := b.engine.Finalize(b.chainConfig, header, ibs, block.Transactions(), block.Uncles(), receipts, block.Withdrawals(), nil, nil); err != nil { + return nil, fmt.Errorf("finalize of block %d failed: %w", block.NumberU64(), err) + } + + if err := ibs.CommitBlock(rules, b.writer); err != nil { + return nil, fmt.Errorf("committing block %d failed: %w", block.NumberU64(), err) + } + + if err := b.writer.w.FinishTx(); err != nil { + return nil, fmt.Errorf("failed to finish tx: %w", err) + } + if b.trace { + fmt.Printf("FinishTx called for %d block %d\n", b.txNum, block.NumberU64()) + } + } + + b.txNum++ // Post-block transaction + b.writer.w.SetTxNum(b.txNum) + if b.txNum >= b.startTxNum { + if block.Number().Uint64()%uint64(commitmentFreq) == 0 { + rootHash, err := b.writer.w.ComputeCommitment(true, b.trace) + if err != nil { + return nil, err + } + if !blockRootMismatchExpected && !bytes.Equal(rootHash, header.Root[:]) { + return nil, fmt.Errorf("invalid root hash for block %d: expected %x got %x", block.NumberU64(), header.Root, rootHash) + } + } + + if err := b.writer.w.FinishTx(); err != nil { + return nil, fmt.Errorf("finish after-block tx %d (block %d) has failed: %w", b.txNum, block.NumberU64(), err) + } + } + + return receipts, nil +} + +// Implements StateReader and StateWriter +type ReaderWrapper4 struct { + roTx kv.Tx + ac *libstate.AggregatorContext +} + +type WriterWrapper4 struct { + w *libstate.Aggregator +} + +func WrapAggregator(agg *libstate.Aggregator, roTx kv.Tx) (*WriterWrapper4, *ReaderWrapper4) { + return &WriterWrapper4{w: agg}, &ReaderWrapper4{ac: agg.MakeContext(), roTx: roTx} +} + +func (rw *ReaderWrapper4) SetTx(roTx kv.Tx, ctx *libstate.AggregatorContext) { + rw.roTx = roTx + rw.ac.Close() + rw.ac = ctx +} + +func (rw *ReaderWrapper4) ReadAccountData(address libcommon.Address) (*accounts.Account, error) { + enc, err := rw.ac.ReadAccountData(address.Bytes(), rw.roTx) + if err != nil { + return nil, err + } + if len(enc) == 0 { + return nil, nil + } + var a accounts.Account + if err := accounts.DeserialiseV3(&a, enc); err != nil { + return nil, err + } + return &a, nil +} + +func (rw *ReaderWrapper4) ReadAccountStorage(address libcommon.Address, incarnation uint64, key *libcommon.Hash) ([]byte, error) { + enc, err := rw.ac.ReadAccountStorage(address.Bytes(), key.Bytes(), rw.roTx) + if err != nil { + return nil, err + } + if enc == nil { + return nil, nil + } + if len(enc) == 1 && enc[0] == 0 { + return nil, nil + } + return enc, nil +} + +func (rw *ReaderWrapper4) ReadAccountCode(address libcommon.Address, incarnation uint64, codeHash libcommon.Hash) ([]byte, error) { + return rw.ac.ReadAccountCode(address.Bytes(), rw.roTx) +} + +func (rw *ReaderWrapper4) ReadAccountCodeSize(address libcommon.Address, incarnation uint64, codeHash libcommon.Hash) (int, error) { + return rw.ac.ReadAccountCodeSize(address.Bytes(), rw.roTx) +} + +func (rw *ReaderWrapper4) ReadAccountIncarnation(address libcommon.Address) (uint64, error) { + return 0, nil +} + +func (ww *WriterWrapper4) UpdateAccountData(address libcommon.Address, original, account *accounts.Account) error { + value := accounts.SerialiseV3(account) + if err := ww.w.UpdateAccountData(address.Bytes(), value); err != nil { + return err + } + return nil +} + +func (ww *WriterWrapper4) UpdateAccountCode(address libcommon.Address, incarnation uint64, codeHash libcommon.Hash, code []byte) error { + if err := ww.w.UpdateAccountCode(address.Bytes(), code); err != nil { + return err + } + return nil +} + +func (ww *WriterWrapper4) DeleteAccount(address libcommon.Address, original *accounts.Account) error { + if err := ww.w.DeleteAccount(address.Bytes()); err != nil { + return err + } + return nil +} + +func (ww *WriterWrapper4) WriteAccountStorage(address libcommon.Address, incarnation uint64, key *libcommon.Hash, original, value *uint256.Int) error { + if err := ww.w.WriteAccountStorage(address.Bytes(), key.Bytes(), value.Bytes()); err != nil { + return err + } + return nil +} + +func (ww *WriterWrapper4) CreateContract(address libcommon.Address) error { + return nil +} + +type stat4 struct { + prevBlock uint64 + blockNum uint64 + hits uint64 + misses uint64 + hitMissRatio float64 + blockSpeed float64 + txSpeed float64 + prevTxNum uint64 + txNum uint64 + prevTime time.Time + mem runtime.MemStats + startedAt time.Time +} + +func (s *stat4) print(aStats libstate.FilesStats, logger log.Logger) { + totalFiles := aStats.FilesCount + totalDatSize := aStats.DataSize + totalIdxSize := aStats.IdxSize + + logger.Info("Progress", "block", s.blockNum, "blk/s", s.blockSpeed, "tx", s.txNum, "txn/s", s.txSpeed, "state files", totalFiles, + "total dat", libcommon.ByteCount(totalDatSize), "total idx", libcommon.ByteCount(totalIdxSize), + "hit ratio", s.hitMissRatio, "hits+misses", s.hits+s.misses, + "alloc", libcommon.ByteCount(s.mem.Alloc), "sys", libcommon.ByteCount(s.mem.Sys), + ) +} + +func (s *stat4) delta(blockNum, txNum uint64) *stat4 { + currentTime := time.Now() + dbg.ReadMemStats(&s.mem) + + interval := currentTime.Sub(s.prevTime).Seconds() + s.blockNum = blockNum + s.blockSpeed = float64(s.blockNum-s.prevBlock) / interval + s.txNum = txNum + s.txSpeed = float64(s.txNum-s.prevTxNum) / interval + s.prevBlock = blockNum + s.prevTxNum = txNum + s.prevTime = currentTime + if s.startedAt.IsZero() { + s.startedAt = currentTime + } + + total := s.hits + s.misses + if total > 0 { + s.hitMissRatio = float64(s.hits) / float64(total) + } + return s +} diff --git a/cmd/lightclient/LICENSE b/cmd/lightclient/LICENSE deleted file mode 100644 index 773fed3c024..00000000000 --- a/cmd/lightclient/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [2022] Erigon-Ligthclient Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/cmd/lightclient/lightclient/checkpoint.go b/cmd/lightclient/lightclient/checkpoint.go deleted file mode 100644 index c4876d6a72c..00000000000 --- a/cmd/lightclient/lightclient/checkpoint.go +++ /dev/null @@ -1,63 +0,0 @@ -package lightclient - -import ( - "context" - "time" - - "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/log/v3" -) - -func (l *LightClient) BootstrapCheckpoint(ctx context.Context, finalized [32]byte) error { - log.Info("[Checkpoint Sync] Retrieving lightclient bootstrap from sentinel", - "root", common.Bytes2Hex(finalized[:])) - retryInterval := time.NewTicker(200 * time.Millisecond) - defer retryInterval.Stop() - - logInterval := time.NewTicker(10 * time.Second) - defer logInterval.Stop() - - doneLogCh := make(chan struct{}) - var ( - b *cltypes.LightClientBootstrap - err error - ) - // Start log go routine. - - go func() { - for { - select { - case <-logInterval.C: - peers, err := l.rpc.Peers() - if err != nil { - continue - } - log.Info("[Checkpoint Sync] P2P", "peers", peers) - case <-doneLogCh: - return - } - } - }() - - b, err = l.rpc.SendLightClientBootstrapReqV1(finalized) - for err != nil || b == nil { - if err != nil { - log.Debug("[lightclient] SendLightClientBootstrapReqV1", "err", err) - } - b, err = l.rpc.SendLightClientBootstrapReqV1(finalized) - } - - doneLogCh <- struct{}{} - s, err := NewLightClientStore(finalized, b) - if err != nil { - log.Warn("[Checkpoint Sync] could not create/validate store", "err", err) - return err - } - - l.store = s - log.Info("Store Initialized successfully", - "slot", l.store.finalizedHeader.Slot, - "root", common.Bytes2Hex(l.store.finalizedHeader.Root[:])) - return nil -} diff --git a/cmd/lightclient/lightclient/execution.go b/cmd/lightclient/lightclient/execution.go deleted file mode 100644 index f71fc22e9e3..00000000000 --- a/cmd/lightclient/lightclient/execution.go +++ /dev/null @@ -1,116 +0,0 @@ -package lightclient - -import ( - "time" - - "github.com/holiman/uint256" - "github.com/ledgerwatch/erigon-lib/gointerfaces" - "github.com/ledgerwatch/erigon-lib/gointerfaces/remote" - "github.com/ledgerwatch/erigon-lib/gointerfaces/types" - - "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/ethdb/privateapi" -) - -func convertLightrpcExecutionPayloadToEthbacked(e *cltypes.Eth1Block) *types.ExecutionPayload { - var baseFee *uint256.Int - var ( - header = e.Header - body = e.Body - ) - - if e.Header.BaseFee != nil { - var overflow bool - baseFee, overflow = uint256.FromBig(header.BaseFee) - if overflow { - panic("NewPayload BaseFeePerGas overflow") - } - } - - res := &types.ExecutionPayload{ - Version: 1, - ParentHash: gointerfaces.ConvertHashToH256(header.ParentHash), - Coinbase: gointerfaces.ConvertAddressToH160(header.Coinbase), - StateRoot: gointerfaces.ConvertHashToH256(header.Root), - ReceiptRoot: gointerfaces.ConvertHashToH256(header.ReceiptHash), - LogsBloom: gointerfaces.ConvertBytesToH2048(header.Bloom[:]), - PrevRandao: gointerfaces.ConvertHashToH256(header.MixDigest), - BlockNumber: header.Number.Uint64(), - GasLimit: header.GasLimit, - GasUsed: header.GasUsed, - Timestamp: header.Time, - ExtraData: header.Extra, - BaseFeePerGas: gointerfaces.ConvertUint256IntToH256(baseFee), - BlockHash: gointerfaces.ConvertHashToH256(header.BlockHashCL), - Transactions: body.Transactions, - Withdrawals: privateapi.ConvertWithdrawalsToRpc(body.Withdrawals), - } - if body.Withdrawals != nil { - res.Version = 2 - res.Withdrawals = privateapi.ConvertWithdrawalsToRpc(body.Withdrawals) - } - - return res -} - -func (l *LightClient) processBeaconBlock(beaconBlock *cltypes.BeaconBlock) error { - if l.execution == nil && l.executionClient == nil { - return nil - } - // If we recently imported the beacon block, skip. - bcRoot, err := beaconBlock.HashSSZ() - if err != nil { - return err - } - if l.recentHashesCache.Contains(bcRoot) { - return nil - } - // Save as recent - l.recentHashesCache.Add(bcRoot, struct{}{}) - - payloadHash := gointerfaces.ConvertHashToH256(beaconBlock.Body.ExecutionPayload.Header.BlockHashCL) - - payload := convertLightrpcExecutionPayloadToEthbacked(beaconBlock.Body.ExecutionPayload) - - if l.execution != nil { - _, err = l.execution.EngineNewPayload(l.ctx, payload) - if err != nil { - return err - } - } - - if l.executionClient != nil { - _, err = l.executionClient.EngineNewPayload(l.ctx, payload) - if err != nil { - return err - } - } - - // Wait a bit - time.Sleep(500 * time.Millisecond) - if l.execution != nil { - _, err = l.execution.EngineForkChoiceUpdated(l.ctx, &remote.EngineForkChoiceUpdatedRequest{ - ForkchoiceState: &remote.EngineForkChoiceState{ - HeadBlockHash: payloadHash, - SafeBlockHash: payloadHash, - FinalizedBlockHash: gointerfaces.ConvertHashToH256(l.finalizedEth1Hash), - }, - }) - if err != nil { - return err - } - } - if l.executionClient != nil { - _, err = l.executionClient.EngineForkChoiceUpdated(l.ctx, &remote.EngineForkChoiceUpdatedRequest{ - ForkchoiceState: &remote.EngineForkChoiceState{ - HeadBlockHash: payloadHash, - SafeBlockHash: payloadHash, - FinalizedBlockHash: gointerfaces.ConvertHashToH256(l.finalizedEth1Hash), - }, - }) - if err != nil { - return err - } - } - return err -} diff --git a/cmd/lightclient/lightclient/lightclient.go b/cmd/lightclient/lightclient/lightclient.go deleted file mode 100644 index 6de12ab87fd..00000000000 --- a/cmd/lightclient/lightclient/lightclient.go +++ /dev/null @@ -1,268 +0,0 @@ -/* - Copyright 2022 Erigon-Lightclient contributors - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package lightclient - -import ( - "context" - "errors" - "runtime" - "time" - - lru "github.com/hashicorp/golang-lru" - common2 "github.com/ledgerwatch/erigon-lib/common" - "github.com/ledgerwatch/erigon-lib/common/dbg" - "github.com/ledgerwatch/erigon-lib/gointerfaces/remote" - "github.com/ledgerwatch/erigon-lib/gointerfaces/sentinel" - "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/log/v3" - - "github.com/ledgerwatch/erigon/cl/clparams" - "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/cl/rpc" - "github.com/ledgerwatch/erigon/cl/utils" - "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/rawdb" -) - -const ( - maxRecentHashes = 5 // 0.16 KB - safetyRange = 16 // 16 block of safety - maxChainExtension = 8 // 8 blocks of chain extension -) - -type LightClient struct { - ctx context.Context - genesisConfig *clparams.GenesisConfig - beaconConfig *clparams.BeaconChainConfig - chainTip *ChainTipSubscriber - - verbose bool - highestSeen uint64 // Highest ETH1 block seen. - highestValidated uint64 // Highest ETH2 slot validated. - highestProcessedRoot common2.Hash // Highest processed ETH2 block root. - lastEth2ParentRoot common2.Hash // Last ETH2 Parent root. - finalizedEth1Hash common2.Hash - recentHashesCache *lru.Cache - db kv.RwDB - rpc *rpc.BeaconRpcP2P - // Either execution server or client - execution remote.ETHBACKENDServer - executionClient remote.ETHBACKENDClient - store *LightClientStore -} - -func NewLightClient(ctx context.Context, db kv.RwDB, genesisConfig *clparams.GenesisConfig, beaconConfig *clparams.BeaconChainConfig, - execution remote.ETHBACKENDServer, executionClient remote.ETHBACKENDClient, sentinel sentinel.SentinelClient, - highestSeen uint64, verbose bool) (*LightClient, error) { - recentHashesCache, err := lru.New(maxRecentHashes) - rpc := rpc.NewBeaconRpcP2P(ctx, sentinel, beaconConfig, genesisConfig) - return &LightClient{ - ctx: ctx, - beaconConfig: beaconConfig, - genesisConfig: genesisConfig, - chainTip: NewChainTipSubscriber(ctx, beaconConfig, genesisConfig, sentinel), - recentHashesCache: recentHashesCache, - rpc: rpc, - execution: execution, - verbose: verbose, - highestSeen: highestSeen, - db: db, - executionClient: executionClient, - }, err -} - -func (l *LightClient) Start() { - if l.store == nil { - log.Error("No trusted setup") - return - } - tx, err := l.db.BeginRw(l.ctx) - if err != nil { - log.Error("Could not open MDBX transaction", "err", err) - return - } - defer tx.Rollback() - logPeers := time.NewTicker(time.Minute) - - go l.chainTip.StartLoop() - for { - start := time.Now() - var ( - updates = []*cltypes.LightClientUpdate{} - finalizedPeriod = utils.SlotToPeriod(l.store.finalizedHeader.Slot) - optimisticPeriod = utils.SlotToPeriod(l.store.optimisticHeader.Slot) - currentSlot = utils.GetCurrentSlot(l.genesisConfig.GenesisTime, l.beaconConfig.SecondsPerSlot) - currentPeriod = utils.SlotToPeriod(currentSlot) - ) - - switch { - // Clause 4 (i): - // if finalized period == optimistic period and the next sync committee is unknown, - // fetch the corresponding lightclient update for this cycle - case finalizedPeriod == optimisticPeriod && l.store.nextSyncCommittee == nil: - update, err := l.FetchUpdate(l.ctx, finalizedPeriod) - if err != nil { - log.Error("[LightClient] Could not fetch lightclient update", "reason", err) - } else { - updates = append(updates, update) - } - // Clause 4 (ii): - // When finalized_period + 1 < current_period, the light client fetches a LightClientUpdate - // for each sync committee period in range [finalized_period + 1, current_period) - case finalizedPeriod+1 < currentPeriod: - for period := finalizedPeriod + 1; period < currentPeriod; period++ { - update, err := l.FetchUpdate(l.ctx, period) - if err != nil { - log.Error("[LightClient] Could not fetch lightclient update, truncating sync session...", - "period", period, "reason", err) - break - } else { - updates = append(updates, update) - } - } - // Clause 4 (iii): - // When finalized_period + 1 >= current_period, the light client keeps observing LightClientFinalityUpdate and LightClientOptimisticUpdate. - // Received objects are passed to process_light_client_update. This ensures that finalized_header and - // optimistic_header reflect the latest blocks. - case finalizedPeriod+1 >= currentPeriod: - newUpdate := l.chainTip.PopLastUpdate() - if newUpdate != nil { - updates = append(updates, newUpdate) - } - } - - // Push updates - for _, update := range updates { - err := l.processLightClientUpdate(update) - if err != nil { - log.Debug("Could not validate update", "err", err) - updates = []*cltypes.LightClientUpdate{} - break - } - } - // log new validated segment - if len(updates) > 0 { - lastValidated := updates[len(updates)-1] - l.highestValidated = lastValidated.AttestedHeader.HeaderEth2.Slot - l.highestProcessedRoot, err = lastValidated.AttestedHeader.HeaderEth2.HashSSZ() - if err != nil { - log.Warn("could not compute root", "err", err) - continue - } - // Save to Database - if lastValidated.HasNextSyncCommittee() { - if err := rawdb.WriteLightClientUpdate(tx, lastValidated); err != nil { - log.Warn("Could not write lightclient update to db", "err", err) - } - } - if lastValidated.IsFinalityUpdate() { - if err := rawdb.WriteLightClientFinalityUpdate(tx, &cltypes.LightClientFinalityUpdate{ - AttestedHeader: lastValidated.AttestedHeader, - FinalizedHeader: lastValidated.FinalizedHeader, - FinalityBranch: lastValidated.FinalityBranch, - SyncAggregate: lastValidated.SyncAggregate, - SignatureSlot: lastValidated.SignatureSlot, - }); err != nil { - log.Warn("Could not write finality lightclient update to db", "err", err) - } - } - if err := rawdb.WriteLightClientOptimisticUpdate(tx, &cltypes.LightClientOptimisticUpdate{ - AttestedHeader: lastValidated.AttestedHeader, - SyncAggregate: lastValidated.SyncAggregate, - SignatureSlot: lastValidated.SignatureSlot, - }); err != nil { - log.Warn("Could not write optimistic lightclient update to db", "err", err) - } - - if err := tx.Commit(); err != nil { - log.Error("[LightClient] could not commit to database", "err", err) - return - } - tx, err = l.db.BeginRw(l.ctx) - if err != nil { - log.Error("[LightClient] could not begin database transaction", "err", err) - return - } - defer tx.Rollback() - - if l.verbose { - var m runtime.MemStats - dbg.ReadMemStats(&m) - log.Info("[LightClient] Validated Chain Segments", - "elapsed", time.Since(start), "from", updates[0].AttestedHeader.HeaderEth2.Slot-1, - "to", lastValidated.AttestedHeader.HeaderEth2.Slot, "alloc", common2.ByteCount(m.Alloc), "sys", common2.ByteCount(m.Sys)) - } - } - l.importBlockIfPossible() - // do not have high CPU load - timer := time.NewTimer(200 * time.Millisecond) - select { - case <-timer.C: - case <-logPeers.C: - peers, err := l.rpc.Peers() - if err != nil { - if errors.Is(err, context.Canceled) { - return - } - log.Warn("could not read peers", "err", err) - continue - } - log.Info("[LightClient] P2P", "peers", peers) - case <-l.ctx.Done(): - return - } - } -} - -func (l *LightClient) importBlockIfPossible() { - var err error - curr := l.chainTip.GetLastBlock() - if curr == nil { - return - } - // Skip if we are too far ahead without validating - if curr.Slot > l.highestValidated+maxChainExtension { - return - } - currentRoot, err := curr.HashSSZ() - if err != nil { - log.Warn("Could not send beacon block to ETH1", "err", err) - return - } - - if (curr.Slot+1)%l.beaconConfig.SlotsPerEpoch == 0 { - l.finalizedEth1Hash = curr.Body.ExecutionPayload.Header.BlockHashCL - } - - if l.lastEth2ParentRoot != l.highestProcessedRoot && l.highestProcessedRoot != curr.ParentRoot { - l.lastEth2ParentRoot = curr.ParentRoot - return - } - l.lastEth2ParentRoot = curr.ParentRoot - l.highestProcessedRoot = currentRoot - - eth1Number := curr.Body.ExecutionPayload.NumberU64() - if l.highestSeen != 0 && (l.highestSeen > safetyRange && eth1Number < l.highestSeen-safetyRange) { - return - } - if l.verbose { - log.Info("Processed block", "slot", curr.Body.ExecutionPayload.NumberU64()) - } - - // If all of the above is gud then do the push - if err := l.processBeaconBlock(curr); err != nil { - log.Warn("Could not send beacon block to ETH1", "err", err) - } else { - l.highestSeen = eth1Number - } -} diff --git a/cmd/lightclient/lightclient/process_updates.go b/cmd/lightclient/lightclient/process_updates.go deleted file mode 100644 index 5167afea910..00000000000 --- a/cmd/lightclient/lightclient/process_updates.go +++ /dev/null @@ -1,111 +0,0 @@ -package lightclient - -import ( - "fmt" - - "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/cl/utils" -) - -func (l *LightClient) isBetterUpdate(oldUpdate *cltypes.LightClientUpdate, newUpdate *cltypes.LightClientUpdate) bool { - var ( - maxActiveParticipants = len(newUpdate.SyncAggregate.SyncCommiteeBits) * 8 // Bits - newActiveParticipants = newUpdate.SyncAggregate.Sum() - oldActiveParticipants = oldUpdate.SyncAggregate.Sum() - newHasSuperMajority = newActiveParticipants*3 >= maxActiveParticipants*2 - oldHasSuperMajority = oldActiveParticipants*3 >= maxActiveParticipants*2 - ) - - // Compare supermajority (> 2/3) sync committee participation - if newHasSuperMajority != oldHasSuperMajority { - return newHasSuperMajority && !oldHasSuperMajority - } - - if !newHasSuperMajority && newActiveParticipants != oldActiveParticipants { - return newActiveParticipants > oldActiveParticipants - } - - // Compare presence of relevant sync committee - isNewUpdateRelevant := newUpdate.HasNextSyncCommittee() && - utils.SlotToPeriod(newUpdate.AttestedHeader.HeaderEth2.Slot) == utils.SlotToPeriod(newUpdate.SignatureSlot) - isOldUpdateRelevant := oldUpdate.HasNextSyncCommittee() && - utils.SlotToPeriod(oldUpdate.AttestedHeader.HeaderEth2.Slot) == utils.SlotToPeriod(oldUpdate.SignatureSlot) - - if isNewUpdateRelevant != isOldUpdateRelevant { - return isNewUpdateRelevant - } - - isNewFinality := newUpdate.IsFinalityUpdate() - isOldFinality := oldUpdate.IsFinalityUpdate() - - if isNewFinality != isOldFinality { - return isNewFinality - } - - // Compare sync committee finality - if isNewFinality && newUpdate.HasSyncFinality() != oldUpdate.HasSyncFinality() { - return newUpdate.HasSyncFinality() - } - - // Tie Breakers - if newActiveParticipants != oldActiveParticipants { - return newActiveParticipants > oldActiveParticipants - } - if newUpdate.AttestedHeader.HeaderEth2.Slot != oldUpdate.AttestedHeader.HeaderEth2.Slot { - return newUpdate.AttestedHeader.HeaderEth2.Slot < oldUpdate.AttestedHeader.HeaderEth2.Slot - } - return newUpdate.SignatureSlot < oldUpdate.SignatureSlot -} - -func (l *LightClient) applyLightClientUpdate(update *cltypes.LightClientUpdate) error { - storePeriod := utils.SlotToPeriod(l.store.finalizedHeader.Slot) - finalizedPeriod := utils.SlotToPeriod(update.FinalizedHeader.HeaderEth2.Slot) - if l.store.nextSyncCommittee == nil { - if storePeriod != finalizedPeriod { - return fmt.Errorf("periods shall be matching") - } - l.store.nextSyncCommittee = update.NextSyncCommitee - } else if finalizedPeriod == storePeriod+1 { - l.store.currentSyncCommittee = l.store.nextSyncCommittee - l.store.nextSyncCommittee = update.NextSyncCommitee - l.store.previousMaxActivePartecipants = l.store.currentMaxActivePartecipants - l.store.currentMaxActivePartecipants = 0 - } - if update.FinalizedHeader.HeaderEth2.Slot > l.store.finalizedHeader.Slot { - l.store.finalizedHeader = update.FinalizedHeader.HeaderEth2 - if update.FinalizedHeader.HeaderEth2.Slot > l.store.optimisticHeader.Slot { - l.store.optimisticHeader = update.FinalizedHeader.HeaderEth2 - } - } - return nil -} - -func (l *LightClient) processLightClientUpdate(update *cltypes.LightClientUpdate) error { - valid, err := l.validateUpdate(update) - if err != nil { - return err - } - if !valid { - return fmt.Errorf("BLS validation failed") - } - - if l.store.bestValidUpdate == nil || l.isBetterUpdate(update, l.store.bestValidUpdate) { - l.store.bestValidUpdate = update - } - updateParticipants := uint64(update.SyncAggregate.Sum()) - if updateParticipants > l.store.currentMaxActivePartecipants { - l.store.currentMaxActivePartecipants = updateParticipants - } - - // Apply lc update (should happen when every 27 hours) - if update.SyncAggregate.Sum()*3 >= len(update.SyncAggregate.SyncCommiteeBits)*16 && - ((update.IsFinalityUpdate() && update.FinalizedHeader.HeaderEth2.Slot > l.store.finalizedHeader.Slot) || - l.store.nextSyncCommittee == nil && update.HasNextSyncCommittee() && - update.IsFinalityUpdate() && update.HasSyncFinality()) { - // Conditions are met so we can make all changes - err = l.applyLightClientUpdate(update) - l.store.bestValidUpdate = nil - } - - return err -} diff --git a/cmd/lightclient/lightclient/request.go b/cmd/lightclient/lightclient/request.go deleted file mode 100644 index 14c6606aefc..00000000000 --- a/cmd/lightclient/lightclient/request.go +++ /dev/null @@ -1,26 +0,0 @@ -package lightclient - -import ( - "context" - - "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/log/v3" -) - -func (l *LightClient) FetchUpdate(ctx context.Context, period uint64) (*cltypes.LightClientUpdate, error) { - log.Info("[Lightclient] Fetching Sync Committee Period", "period", period) - var ( - update *cltypes.LightClientUpdate - err error - ) - for update == nil { - update, err = l.rpc.SendLightClientUpdatesReqV1(period) - if err != nil { - log.Trace("[Checkpoint Sync] could not retrieve bootstrap", "err", err) - return nil, err - } - } - - return update, nil - -} diff --git a/cmd/lightclient/lightclient/store.go b/cmd/lightclient/lightclient/store.go deleted file mode 100644 index efb27b1bb35..00000000000 --- a/cmd/lightclient/lightclient/store.go +++ /dev/null @@ -1,65 +0,0 @@ -package lightclient - -import ( - "fmt" - - "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/cl/utils" -) - -type LightClientStore struct { - // Beacon block header that is finalized - finalizedHeader *cltypes.BeaconBlockHeader - // Most recent available reasonably-safe header - optimisticHeader *cltypes.BeaconBlockHeader - - // Sync committees corresponding to the header - currentSyncCommittee *cltypes.SyncCommittee - nextSyncCommittee *cltypes.SyncCommittee - - // Best available header to switch finalized head to if we see nothing else - bestValidUpdate *cltypes.LightClientUpdate - - // Max number of active participants in a sync committee (used to calculate safety threshold) - previousMaxActivePartecipants uint64 - currentMaxActivePartecipants uint64 -} - -/* - * A light client maintains its state in a store object of type LightClientStore. - * initialize_light_client_store initializes a new store with a - * received LightClientBootstrap derived from a given trusted_block_root. - */ -func NewLightClientStore(trustedRoot [32]byte, bootstrap *cltypes.LightClientBootstrap) (*LightClientStore, error) { - headerRoot, err := bootstrap.Header.HeaderEth2.HashSSZ() - if err != nil { - return nil, err - } - if headerRoot != trustedRoot { - return nil, fmt.Errorf("trusted root is mismatching, headerRoot: %x, trustedRoot: %x", - headerRoot, trustedRoot) - } - - syncCommitteeRoot, err := bootstrap.CurrentSyncCommittee.HashSSZ() - if err != nil { - return nil, err - } - if !utils.IsValidMerkleBranch( - syncCommitteeRoot, - bootstrap.CurrentSyncCommitteeBranch, - 5, // floorlog2(CURRENT_SYNC_COMMITTEE_INDEX) - 22, // get_subtree_index(CURRENT_SYNC_COMMITTEE_INDEX), - bootstrap.Header.HeaderEth2.Root, - ) { - return nil, fmt.Errorf("invalid sync committee") - } - - return &LightClientStore{ - finalizedHeader: bootstrap.Header.HeaderEth2, - currentSyncCommittee: bootstrap.CurrentSyncCommittee, - nextSyncCommittee: nil, - optimisticHeader: bootstrap.Header.HeaderEth2, - previousMaxActivePartecipants: 0, - currentMaxActivePartecipants: 0, - }, nil -} diff --git a/cmd/lightclient/lightclient/subscriber.go b/cmd/lightclient/lightclient/subscriber.go deleted file mode 100644 index f27b90ad9ea..00000000000 --- a/cmd/lightclient/lightclient/subscriber.go +++ /dev/null @@ -1,172 +0,0 @@ -package lightclient - -import ( - "context" - "errors" - "fmt" - "sync" - "time" - - "github.com/ledgerwatch/erigon-lib/gointerfaces/grpcutil" - "github.com/ledgerwatch/erigon-lib/gointerfaces/sentinel" - "github.com/ledgerwatch/erigon/cl/clparams" - "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/cl/utils" - "github.com/ledgerwatch/log/v3" -) - -// ChainTipSubscriber tells us what are the newly received gossip arguments -type ChainTipSubscriber struct { - ctx context.Context - - currBlock *cltypes.BeaconBlock // Most recent gossipped block - - lastUpdate *cltypes.LightClientUpdate - started bool - sentinel sentinel.SentinelClient - beaconConfig *clparams.BeaconChainConfig - genesisConfig *clparams.GenesisConfig - lastReceivedSlot uint64 - - mu sync.Mutex -} - -func NewChainTipSubscriber(ctx context.Context, beaconConfig *clparams.BeaconChainConfig, genesisConfig *clparams.GenesisConfig, sentinel sentinel.SentinelClient) *ChainTipSubscriber { - return &ChainTipSubscriber{ - ctx: ctx, - started: false, - sentinel: sentinel, - genesisConfig: genesisConfig, - beaconConfig: beaconConfig, - } -} - -func (c *ChainTipSubscriber) StartLoop() { - if c.started { - log.Error("Chain tip subscriber already started") - return - } - log.Info("[LightClient Gossip] Started Gossip") - c.started = true - -Retry: - for { - if err := c.subscribeGossip(); err != nil { - if errors.Is(err, context.Canceled) { - return - } - if grpcutil.IsRetryLater(err) || grpcutil.IsEndOfStream(err) { - time.Sleep(3 * time.Second) - continue Retry - } - - log.Debug("[Lightclient] could not read gossip :/", "reason", err) - time.Sleep(time.Second) - } - } -} - -func (c *ChainTipSubscriber) subscribeGossip() error { - stream, err := c.sentinel.SubscribeGossip(c.ctx, &sentinel.EmptyMessage{}) - if err != nil { - return err - } - defer stream.CloseSend() - - for { - data, err := stream.Recv() - if err != nil { - return err - } - if err := c.handleGossipData(data); err != nil { - log.Debug("could not process new gossip", - "gossipType", data.Type, "reason", err) - - } - } -} - -func (c *ChainTipSubscriber) handleGossipData(data *sentinel.GossipData) error { - c.mu.Lock() - defer c.mu.Unlock() - - currentEpoch := utils.GetCurrentEpoch(c.genesisConfig.GenesisTime, c.beaconConfig.SecondsPerSlot, c.beaconConfig.SlotsPerEpoch) - version := c.beaconConfig.GetCurrentStateVersion(currentEpoch) - - switch data.Type { - case sentinel.GossipType_BeaconBlockGossipType: - block := &cltypes.SignedBeaconBlock{} - if err := block.DecodeSSZWithVersion(data.Data, int(version)); err != nil { - if _, err := c.sentinel.BanPeer(c.ctx, data.Peer); err != nil { - return err - } - return fmt.Errorf("could not unmarshall block: %s", err) - } - - c.currBlock = block.Block - c.lastReceivedSlot = block.Block.Slot - case sentinel.GossipType_LightClientFinalityUpdateGossipType: - finalityUpdate := &cltypes.LightClientFinalityUpdate{} - if err := finalityUpdate.DecodeSSZWithVersion(data.Data, int(version)); err != nil { - if _, err := c.sentinel.BanPeer(c.ctx, data.Peer); err != nil { - return err - } - return fmt.Errorf("could not unmarshall finality update: %s", err) - } - c.lastUpdate = &cltypes.LightClientUpdate{ - AttestedHeader: finalityUpdate.AttestedHeader, - NextSyncCommitee: nil, - NextSyncCommitteeBranch: nil, - FinalizedHeader: finalityUpdate.FinalizedHeader, - FinalityBranch: finalityUpdate.FinalityBranch, - SyncAggregate: finalityUpdate.SyncAggregate, - SignatureSlot: finalityUpdate.SignatureSlot, - } - case sentinel.GossipType_LightClientOptimisticUpdateGossipType: - if c.lastUpdate != nil && c.lastUpdate.IsFinalityUpdate() { - // We already have a finality update, we can skip this one - return nil - } - - optimisticUpdate := &cltypes.LightClientOptimisticUpdate{} - if err := optimisticUpdate.DecodeSSZWithVersion(data.Data, int(version)); err != nil { - if _, err := c.sentinel.BanPeer(c.ctx, data.Peer); err != nil { - return err - } - return fmt.Errorf("could not unmarshall optimistic update: %s", err) - } - c.lastUpdate = &cltypes.LightClientUpdate{ - AttestedHeader: optimisticUpdate.AttestedHeader, - NextSyncCommitee: nil, - NextSyncCommitteeBranch: nil, - FinalizedHeader: nil, - FinalityBranch: nil, - SyncAggregate: optimisticUpdate.SyncAggregate, - SignatureSlot: optimisticUpdate.SignatureSlot, - } - default: - } - return nil -} - -func (c *ChainTipSubscriber) PopLastUpdate() *cltypes.LightClientUpdate { - c.mu.Lock() - defer c.mu.Unlock() - update := c.lastUpdate - c.lastUpdate = nil - return update -} - -func (c *ChainTipSubscriber) GetLastBlock() *cltypes.BeaconBlock { - c.mu.Lock() - defer c.mu.Unlock() - // Check if we are up to date - currentSlot := utils.GetCurrentSlot(c.genesisConfig.GenesisTime, c.beaconConfig.SecondsPerSlot) - // Gossip failed use the rpc and attempt to retrieve last block. - if c.lastReceivedSlot != currentSlot { - return nil - } - block := c.currBlock - c.currBlock = nil - return block -} diff --git a/cmd/lightclient/lightclient/verify.go b/cmd/lightclient/lightclient/verify.go deleted file mode 100644 index 46a6abb4bf9..00000000000 --- a/cmd/lightclient/lightclient/verify.go +++ /dev/null @@ -1,110 +0,0 @@ -package lightclient - -import ( - "fmt" - - "github.com/Giulio2002/bls" - "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/cl/fork" - "github.com/ledgerwatch/erigon/cl/utils" - "github.com/ledgerwatch/erigon/common" -) - -const MinSyncCommitteeParticipants = 1 - -var DomainSyncCommittee = common.Hex2Bytes("07000000") - -func (l *LightClient) validateUpdate(update *cltypes.LightClientUpdate) (bool, error) { - if update.SyncAggregate.Sum() < MinSyncCommitteeParticipants { - return false, fmt.Errorf("not enough participants") - } - isNextSyncCommitteeKnown := l.store.nextSyncCommittee != nil - // Check if the timings and slot are valid - current_slot := utils.GetCurrentSlot(l.genesisConfig.GenesisTime, l.beaconConfig.SecondsPerSlot) - if current_slot < update.SignatureSlot || update.SignatureSlot <= update.AttestedHeader.HeaderEth2.Slot || - (update.IsFinalityUpdate() && update.AttestedHeader.HeaderEth2.Slot < update.FinalizedHeader.HeaderEth2.Slot) { - return false, fmt.Errorf("too far in the future") - } - storePeriod := utils.SlotToPeriod(l.store.finalizedHeader.Slot) - updateSignaturePeriod := utils.SlotToPeriod(update.SignatureSlot) - - if !isNextSyncCommitteeKnown && - updateSignaturePeriod != storePeriod && updateSignaturePeriod != storePeriod+1 { - return false, fmt.Errorf("mismatching periods") - } - - // Verify whether update is relevant - attestedPeriod := utils.SlotToPeriod(update.AttestedHeader.HeaderEth2.Slot) - hasNextSyncCommittee := l.store.nextSyncCommittee == nil && - update.HasNextSyncCommittee() && attestedPeriod == storePeriod - - if update.AttestedHeader.HeaderEth2.Slot <= l.store.finalizedHeader.Slot && !hasNextSyncCommittee { - return false, fmt.Errorf("invalid sync committee") - } - - // Verify that the `finality_branch`, if present, confirms `finalized_header` - if update.IsFinalityUpdate() { - finalizedRoot, err := update.FinalizedHeader.HeaderEth2.HashSSZ() - if err != nil { - return false, err - } - if !utils.IsValidMerkleBranch( - finalizedRoot, - update.FinalityBranch, - 6, // floorlog2(FINALIZED_ROOT_INDEX) - 41, // get_subtree_index(FINALIZED_ROOT_INDEX), - update.AttestedHeader.HeaderEth2.Root, - ) { - return false, fmt.Errorf("update is not part of the merkle tree") - } - } - if update.HasNextSyncCommittee() { - if attestedPeriod == storePeriod && isNextSyncCommitteeKnown && - !update.NextSyncCommitee.Equal(l.store.nextSyncCommittee) { - return false, fmt.Errorf("mismatching sync committee") - } - syncRoot, err := update.NextSyncCommitee.HashSSZ() - if err != nil { - return false, err - } - if !utils.IsValidMerkleBranch( - syncRoot, - update.NextSyncCommitteeBranch, - 5, // floorlog2(NEXT_SYNC_COMMITTEE_INDEX) - 23, // get_subtree_index(NEXT_SYNC_COMMITTEE_INDEX), - update.AttestedHeader.HeaderEth2.Root, - ) { - return false, fmt.Errorf("sync committee is not part of the merkle tree") - } - } - var syncCommittee *cltypes.SyncCommittee - if updateSignaturePeriod == storePeriod { - syncCommittee = l.store.currentSyncCommittee - } else { - syncCommittee = l.store.nextSyncCommittee - } - syncAggregateBits := update.SyncAggregate.SyncCommiteeBits - - var pubkeys [][]byte - currPubKeyIndex := 0 - for i := range syncAggregateBits { - for bit := 1; bit <= 128; bit *= 2 { - if syncAggregateBits[i]&byte(bit) > 0 { - pubkeys = append(pubkeys, syncCommittee.PubKeys[currPubKeyIndex][:]) - } - currPubKeyIndex++ - } - } - // Support only post-bellatrix forks - forkVersion := fork.GetLastFork(l.beaconConfig, l.genesisConfig) - domain, err := fork.ComputeDomain(DomainSyncCommittee, forkVersion, l.genesisConfig.GenesisValidatorRoot) - if err != nil { - return false, err - } - // Computing signing root - signingRoot, err := fork.ComputeSigningRoot(update.AttestedHeader.HeaderEth2, domain) - if err != nil { - return false, err - } - return bls.VerifyAggregate(update.SyncAggregate.SyncCommiteeSignature[:], signingRoot[:], pubkeys) -} diff --git a/cmd/observer/database/db_sqlite.go b/cmd/observer/database/db_sqlite.go index 0823b3715ac..ba056fbe8c1 100644 --- a/cmd/observer/database/db_sqlite.go +++ b/cmd/observer/database/db_sqlite.go @@ -9,6 +9,7 @@ import ( "strings" "time" + "github.com/ledgerwatch/erigon/cmd/utils" _ "modernc.org/sqlite" ) @@ -708,7 +709,7 @@ func (db *DBSQLite) FindNeighborBucketKeys(ctx context.Context, id NodeID) ([]st if !keysStr.Valid { return nil, nil } - return strings.Split(keysStr.String, ","), nil + return utils.SplitAndTrim(keysStr.String), nil } func (db *DBSQLite) UpdateSentryCandidatesLastEventTime(ctx context.Context, value time.Time) error { diff --git a/cmd/p2psim/main.go b/cmd/p2psim/main.go index 0dd4e5d8529..b2e83339ed8 100644 --- a/cmd/p2psim/main.go +++ b/cmd/p2psim/main.go @@ -44,6 +44,7 @@ import ( "strings" "text/tabwriter" + "github.com/ledgerwatch/erigon/cmd/utils" "github.com/urfave/cli/v2" "github.com/ledgerwatch/erigon/crypto" @@ -289,7 +290,7 @@ func createNode(ctx *cli.Context) error { config.PrivateKey = privKey } if services := ctx.String("services"); services != "" { - config.Lifecycles = strings.Split(services, ",") + config.Lifecycles = utils.SplitAndTrim(services) } node, err := client.CreateNode(config) if err != nil { diff --git a/cmd/prometheus/dashboards/erigon.json b/cmd/prometheus/dashboards/erigon.json index 37317c6ceea..1995cfe875e 100644 --- a/cmd/prometheus/dashboards/erigon.json +++ b/cmd/prometheus/dashboards/erigon.json @@ -30,8 +30,7 @@ "panels": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "gridPos": { "h": 1, @@ -43,8 +42,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "refId": "A" } @@ -54,8 +52,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -112,7 +109,7 @@ "overrides": [] }, "gridPos": { - "h": 7, + "h": 10, "w": 8, "x": 0, "y": 1 @@ -137,15 +134,16 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, + "editorMode": "code", "exemplar": true, "expr": "sync{instance=~\"$instance\"}", "format": "time_series", "interval": "", "intervalFactor": 1, "legendFormat": "{{ stage }}: {{instance}}", + "range": true, "refId": "A" } ], @@ -154,8 +152,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -236,15 +233,16 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, + "editorMode": "code", "exemplar": true, "expr": "rate(sync{instance=~\"$instance\"}[$rate_interval])", "format": "time_series", "interval": "", "intervalFactor": 1, "legendFormat": "{{ stage }}: {{instance}}", + "range": true, "refId": "A" } ], @@ -253,8 +251,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -305,7 +302,7 @@ } ] }, - "unit": "s" + "unit": "ops" }, "overrides": [] }, @@ -315,6 +312,105 @@ "x": 16, "y": 1 }, + "id": 195, + "links": [], + "options": { + "legend": { + "calcs": [ + "mean" + ], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "8.0.6", + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "editorMode": "code", + "exemplar": true, + "expr": "rate(exec_txs_done{instance=~\"$instance\"}[$rate_interval])", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "txs apply: {{instance}}", + "range": true, + "refId": "A" + } + ], + "title": "Exec v3: txs/s ", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 8, + "x": 8, + "y": 6 + }, "id": 112, "links": [], "options": { @@ -336,8 +432,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "chain_execution_seconds{quantile=\"$quantile\",instance=~\"$instance\"}", @@ -351,25 +446,138 @@ "title": "Block Execution speed ", "type": "timeseries" }, + { + "datasource": { + "type": "prometheus" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": true, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "decimals": 2, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 8, + "x": 16, + "y": 6 + }, + "id": 194, + "links": [], + "options": { + "legend": { + "calcs": [ + "mean" + ], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "8.0.6", + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "editorMode": "code", + "exemplar": true, + "expr": "rate(exec_repeats{instance=~\"$instance\"}[$rate_interval])/rate(exec_txs_done{instance=~\"$instance\"}[$rate_interval])", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "repeats: {{instance}}", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus" + }, + "editorMode": "code", + "exemplar": true, + "expr": "rate(exec_triggers{instance=~\"$instance\"}[$rate_interval])/rate(exec_txs_done{instance=~\"$instance\"}[$rate_interval])", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "triggers: {{instance}}", + "range": true, + "refId": "B" + } + ], + "title": "Exec v3", + "type": "timeseries" + }, { "collapsed": false, "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "gridPos": { "h": 1, "w": 24, "x": 0, - "y": 8 + "y": 11 }, "id": 17, "panels": [], "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "refId": "A" } @@ -379,8 +587,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -439,7 +646,7 @@ "h": 5, "w": 8, "x": 0, - "y": 9 + "y": 12 }, "id": 141, "options": { @@ -458,8 +665,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(db_commit_seconds_count{phase=\"total\",instance=~\"$instance\"}[$rate_interval])", @@ -473,8 +679,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "description": "", "fieldConfig": { @@ -534,7 +739,7 @@ "h": 9, "w": 16, "x": 8, - "y": 9 + "y": 12 }, "id": 166, "options": { @@ -555,8 +760,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -568,8 +772,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -582,8 +785,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -596,8 +798,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -610,8 +811,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -624,8 +824,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -638,8 +837,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -652,8 +850,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -666,8 +863,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -680,8 +876,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -694,8 +889,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -708,8 +902,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -722,8 +915,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -740,8 +932,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -794,60 +985,32 @@ }, "unit": "decbytes" }, - "overrides": [ - { - "__systemRef": "hideSeriesFrom", - "matcher": { - "id": "byNames", - "options": { - "mode": "exclude", - "names": [ - "db_mi_last_pgno: bsc-sn3-2:6061" - ], - "prefix": "All except:", - "readOnly": true - } - }, - "properties": [ - { - "id": "custom.hideFrom", - "value": { - "legend": false, - "tooltip": false, - "viz": true - } - } - ] - } - ] + "overrides": [] }, "gridPos": { "h": 5, "w": 8, "x": 0, - "y": 14 + "y": 17 }, "id": 159, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": [], "displayMode": "list", "placement": "bottom", "showLegend": true }, "tooltip": { - "mode": "single", + "mode": "multi", "sort": "none" } }, - "pluginVersion": "8.0.6", + "pluginVersion": "8.4.7", "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "db_size{instance=~\"$instance\"}", "interval": "", @@ -856,8 +1019,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "expr": "db_mi_last_pgno{instance=~\"$instance\"}", @@ -873,8 +1035,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -888,7 +1049,7 @@ "axisPlacement": "auto", "barAlignment": 0, "drawStyle": "line", - "fillOpacity": 10, + "fillOpacity": 25, "gradientMode": "none", "hideFrom": { "legend": false, @@ -901,11 +1062,11 @@ "scaleDistribution": { "type": "linear" }, - "showPoints": "never", - "spanNulls": true, + "showPoints": "auto", + "spanNulls": false, "stacking": { "group": "A", - "mode": "none" + "mode": "normal" }, "thresholdsStyle": { "mode": "off" @@ -916,36 +1077,34 @@ "mode": "absolute", "steps": [ { - "color": "green" + "color": "green", + "value": null }, { "color": "red", "value": 80 } ] - }, - "unit": "short" + } }, "overrides": [] }, "gridPos": { - "h": 6, + "h": 7, "w": 16, "x": 8, - "y": 18 + "y": 21 }, - "id": 192, + "id": 168, "options": { "legend": { - "calcs": [ - "mean" - ], + "calcs": [], "displayMode": "list", "placement": "bottom", "showLegend": true }, "tooltip": { - "mode": "multi", + "mode": "single", "sort": "none" } }, @@ -953,67 +1112,190 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, - "expr": "db_gc_work_pnl_merge_volume{instance=~\"$instance\"}", + "expr": "rate(db_pgops{phase=\"newly\", instance=~\"$instance\"}[$rate_interval])", + "hide": false, "interval": "", - "legendFormat": "work_pnl_merge_volume: {{instance}}", + "legendFormat": "newly: {{instance}}", "range": true, "refId": "A" }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, - "editorMode": "code", "exemplar": true, - "expr": "db_gc_work_pnl_merge_calls{instance=~\"$instance\"}", + "expr": "rate(db_pgops{phase=\"cow\", instance=~\"$instance\"}[$rate_interval])", "hide": false, "interval": "", - "legendFormat": "work_pnl_merge_calls: {{instance}}", - "range": true, + "legendFormat": "cow: {{instance}}", "refId": "B" }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, - "editorMode": "code", "exemplar": true, - "expr": "db_gc_slef_pnl_merge_volume{instance=~\"$instance\"}", + "expr": "rate(db_pgops{phase=\"clone\", instance=~\"$instance\"}[$rate_interval])", "hide": false, "interval": "", - "legendFormat": "slef_pnl_merge_volume: {{instance}}", - "range": true, + "legendFormat": "clone: {{instance}}", "refId": "C" }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, - "editorMode": "code", "exemplar": true, - "expr": "db_gc_slef_pnl_merge_calls{instance=~\"$instance\"}", + "expr": "rate(db_pgops{phase=\"split\", instance=~\"$instance\"}[$rate_interval])", "hide": false, "interval": "", - "legendFormat": "slef_pnl_merge_calls: {{instance}}", - "range": true, + "legendFormat": "split: {{instance}}", "refId": "D" - } - ], - "title": "pnl_merge", - "type": "timeseries" - }, + }, + { + "datasource": { + "type": "prometheus" + }, + "editorMode": "code", + "exemplar": true, + "expr": "rate(db_pgops{phase=\"merge\", instance=~\"$instance\"}[$rate_interval])", + "hide": false, + "interval": "", + "legendFormat": "merge: {{instance}}", + "range": true, + "refId": "E" + }, + { + "datasource": { + "type": "prometheus" + }, + "exemplar": true, + "expr": "rate(db_pgops{phase=\"spill\", instance=~\"$instance\"}[$rate_interval])", + "hide": false, + "interval": "", + "legendFormat": "spill: {{instance}}", + "refId": "F" + }, + { + "datasource": { + "type": "prometheus" + }, + "exemplar": true, + "expr": "rate(db_pgops{phase=\"wops\", instance=~\"$instance\"}[$rate_interval])", + "hide": false, + "interval": "", + "legendFormat": "wops: {{instance}}", + "refId": "G" + }, + { + "datasource": { + "type": "prometheus" + }, + "exemplar": true, + "expr": "rate(db_pgops{phase=\"unspill\", instance=~\"$instance\"}[$rate_interval])", + "hide": false, + "interval": "", + "legendFormat": "unspill: {{instance}}", + "refId": "H" + }, + { + "datasource": { + "type": "prometheus" + }, + "editorMode": "code", + "exemplar": true, + "expr": "rate(db_pgops{phase=\"gcrloops\", instance=~\"$instance\"}[$rate_interval])", + "hide": false, + "interval": "", + "legendFormat": "gcrloops: {{instance}}", + "range": true, + "refId": "I" + }, + { + "datasource": { + "type": "prometheus" + }, + "editorMode": "code", + "exemplar": true, + "expr": "rate(db_pgops{phase=\"gcwloops\", instance=~\"$instance\"}[$rate_interval])", + "hide": false, + "interval": "", + "legendFormat": "gcwloops: {{instance}}", + "range": true, + "refId": "J" + }, + { + "datasource": { + "type": "prometheus" + }, + "editorMode": "code", + "exemplar": true, + "expr": "rate(db_pgops{phase=\"gcxpages\", instance=~\"$instance\"}[$rate_interval])", + "hide": false, + "interval": "", + "legendFormat": "gcxpages: {{instance}}", + "range": true, + "refId": "K" + }, + { + "datasource": { + "type": "prometheus" + }, + "editorMode": "code", + "exemplar": true, + "expr": "rate(db_pgops{phase=\"msync\", instance=~\"$instance\"}[$rate_interval])", + "hide": false, + "interval": "", + "legendFormat": "msync: {{instance}}", + "range": true, + "refId": "L" + }, + { + "datasource": { + "type": "prometheus" + }, + "editorMode": "code", + "exemplar": true, + "expr": "rate(db_pgops{phase=\"fsync\", instance=~\"$instance\"}[$rate_interval])", + "hide": false, + "interval": "", + "legendFormat": "fsync: {{instance}}", + "range": true, + "refId": "M" + }, + { + "datasource": { + "type": "prometheus" + }, + "exemplar": true, + "expr": "rate(db_pgops{phase=\"minicore\", instance=~\"$instance\"}[$rate_interval])", + "hide": false, + "interval": "", + "legendFormat": "minicore: {{instance}}", + "refId": "N" + }, + { + "datasource": { + "type": "prometheus" + }, + "exemplar": true, + "expr": "rate(db_pgops{phase=\"prefault\", instance=~\"$instance\"}[$rate_interval])", + "hide": false, + "interval": "", + "legendFormat": "prefault: {{instance}}", + "refId": "O" + } + ], + "title": "DB Pages Ops/sec", + "type": "timeseries" + }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -1055,7 +1337,8 @@ "mode": "absolute", "steps": [ { - "color": "green" + "color": "green", + "value": null }, { "color": "red", @@ -1071,7 +1354,7 @@ "h": 6, "w": 8, "x": 0, - "y": 19 + "y": 22 }, "id": 167, "options": { @@ -1092,8 +1375,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "expr": "tx_limit{instance=~\"$instance\"}", @@ -1104,8 +1386,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "expr": "tx_dirty{instance=~\"$instance\"}", @@ -1121,8 +1402,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -1136,7 +1416,7 @@ "axisPlacement": "auto", "barAlignment": 0, "drawStyle": "line", - "fillOpacity": 10, + "fillOpacity": 25, "gradientMode": "none", "hideFrom": { "legend": false, @@ -1149,11 +1429,11 @@ "scaleDistribution": { "type": "linear" }, - "showPoints": "never", - "spanNulls": true, + "showPoints": "auto", + "spanNulls": false, "stacking": { "group": "A", - "mode": "none" + "mode": "normal" }, "thresholdsStyle": { "mode": "off" @@ -1164,61 +1444,34 @@ "mode": "absolute", "steps": [ { - "color": "green" + "color": "green", + "value": null }, { "color": "red", "value": 80 } ] - }, - "unit": "short" - }, - "overrides": [ - { - "__systemRef": "hideSeriesFrom", - "matcher": { - "id": "byNames", - "options": { - "mode": "exclude", - "names": [ - "fsync: mainnet2-2:6061" - ], - "prefix": "All except:", - "readOnly": true - } - }, - "properties": [ - { - "id": "custom.hideFrom", - "value": { - "legend": false, - "tooltip": false, - "viz": true - } - } - ] } - ] + }, + "overrides": [] }, "gridPos": { - "h": 7, - "w": 16, - "x": 8, - "y": 24 + "h": 6, + "w": 8, + "x": 0, + "y": 28 }, - "id": 168, + "id": 169, "options": { "legend": { - "calcs": [ - "mean" - ], + "calcs": [], "displayMode": "list", "placement": "bottom", "showLegend": true }, "tooltip": { - "mode": "multi", + "mode": "single", "sort": "none" } }, @@ -1226,182 +1479,148 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, - "editorMode": "code", "exemplar": true, - "expr": "rate(db_pgops_newly{instance=~\"$instance\"}[$rate_interval])", - "hide": false, + "expr": "db_gc_leaf{instance=~\"$instance\"}", "interval": "", - "legendFormat": "newly: {{instance}}", - "range": true, + "legendFormat": "gc_leaf: {{instance}}", "refId": "A" }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, - "expr": "rate(db_pgops_cow{instance=~\"$instance\"}[$rate_interval])", + "expr": "db_gc_overflow{instance=~\"$instance\"}", "hide": false, "interval": "", - "legendFormat": "cow: {{instance}}", + "legendFormat": "gc_overflow: {{instance}}", "refId": "B" }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, + "editorMode": "code", "exemplar": true, - "expr": "rate(db_pgops_clone{instance=~\"$instance\"}[$rate_interval])", + "expr": "exec_steps_in_db{instance=~\"$instance\"}/100", "hide": false, "interval": "", - "legendFormat": "clone: {{instance}}", - "refId": "C" + "legendFormat": "exec_steps_in_db: {{instance}}", + "range": true, + "refId": "E" + } + ], + "title": "GC and State", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 25, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "normal" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 16, + "x": 8, + "y": 28 + }, + "id": 150, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "8.0.6", + "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, - "expr": "rate(db_pgops_split{instance=~\"$instance\"}[$rate_interval])", - "hide": false, + "expr": "rate(process_minor_pagefaults_total{instance=~\"$instance\"}[$rate_interval])", "interval": "", - "legendFormat": "split: {{instance}}", - "refId": "D" + "legendFormat": "soft: {{instance}}", + "refId": "A" }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, - "editorMode": "code", "exemplar": true, - "expr": "rate(db_pgops_merge{instance=~\"$instance\"}[$rate_interval])", + "expr": "rate(process_major_pagefaults_total{instance=~\"$instance\"}[$rate_interval])", "hide": false, "interval": "", - "legendFormat": "merge: {{instance}}", - "range": true, - "refId": "E" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "rate(db_pgops_spill{instance=~\"$instance\"}[$rate_interval])", - "hide": false, - "interval": "", - "legendFormat": "spill: {{instance}}", - "refId": "F" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "rate(db_pgops_wops{instance=~\"$instance\"}[$rate_interval])", - "hide": false, - "interval": "", - "legendFormat": "wops: {{instance}}", - "refId": "G" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "rate(db_pgops_unspill{instance=~\"$instance\"}[$rate_interval])", - "hide": false, - "interval": "", - "legendFormat": "unspill: {{instance}}", - "refId": "H" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "exemplar": true, - "expr": "rate(db_pgops_gcrloops{instance=~\"$instance\"}[$rate_interval])", - "hide": false, - "interval": "", - "legendFormat": "gcrloops: {{instance}}", - "range": true, - "refId": "I" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "exemplar": true, - "expr": "rate(db_pgops_gcwloops{instance=~\"$instance\"}[$rate_interval])", - "hide": false, - "interval": "", - "legendFormat": "gcwloops: {{instance}}", - "range": true, - "refId": "J" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "exemplar": true, - "expr": "rate(db_pgops_gcxpages{instance=~\"$instance\"}[$rate_interval])", - "hide": false, - "interval": "", - "legendFormat": "gcxpages: {{instance}}", - "range": true, - "refId": "K" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "exemplar": true, - "expr": "rate(db_pgops_msync{instance=~\"$instance\"}[$rate_interval])", - "hide": false, - "interval": "", - "legendFormat": "msync: {{instance}}", - "range": true, - "refId": "L" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "exemplar": true, - "expr": "rate(db_pgops_fsnc{instance=~\"$instance\"}[$rate_interval])", - "hide": false, - "interval": "", - "legendFormat": "fsync: {{instance}}", - "range": true, - "refId": "M" + "legendFormat": "hard: {{instance}}", + "refId": "B" } ], - "title": "DB Pages Ops/sec", + "title": "getrusage: minflt - soft page faults (reclaims), majflt - hard faults", "type": "timeseries" }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -1415,7 +1634,7 @@ "axisPlacement": "auto", "barAlignment": 0, "drawStyle": "line", - "fillOpacity": 10, + "fillOpacity": 0, "gradientMode": "none", "hideFrom": { "legend": false, @@ -1428,8 +1647,8 @@ "scaleDistribution": { "type": "linear" }, - "showPoints": "never", - "spanNulls": true, + "showPoints": "auto", + "spanNulls": false, "stacking": { "group": "A", "mode": "none" @@ -1443,187 +1662,15 @@ "mode": "absolute", "steps": [ { - "color": "green" + "color": "green", + "value": null }, { "color": "red", "value": 80 } ] - }, - "unit": "short" - }, - "overrides": [ - { - "__systemRef": "hideSeriesFrom", - "matcher": { - "id": "byNames", - "options": { - "mode": "exclude", - "names": [ - "gc_overflow: mainnet2-2:6061" - ], - "prefix": "All except:", - "readOnly": true - } - }, - "properties": [ - { - "id": "custom.hideFrom", - "value": { - "legend": false, - "tooltip": false, - "viz": true - } - } - ] } - ] - }, - "gridPos": { - "h": 6, - "w": 8, - "x": 0, - "y": 25 - }, - "id": 169, - "options": { - "legend": { - "calcs": [ - "mean" - ], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "multi", - "sort": "none" - } - }, - "pluginVersion": "8.0.6", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "db_gc_leaf{instance=~\"$instance\"}", - "interval": "", - "legendFormat": "gc_leaf: {{instance}}", - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "db_gc_overflow{instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "gc_overflow: {{instance}}", - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "db_state_leaf{instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "state_leaf: {{instance}}", - "refId": "C" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "exemplar": true, - "expr": "db_state_branch{instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "state_branch: {{instance}}", - "range": true, - "refId": "D" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "editorMode": "code", - "exemplar": true, - "expr": "exec_steps_in_db{instance=~\"$instance\"}/100", - "hide": false, - "interval": "", - "legendFormat": "exec_steps_in_db: {{instance}}", - "range": true, - "refId": "E" - } - ], - "title": "GC and State", - "type": "timeseries" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "points", - "fillOpacity": 10, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 2, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "never", - "spanNulls": true, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "short" }, "overrides": [] }, @@ -1631,20 +1678,18 @@ "h": 8, "w": 16, "x": 8, - "y": 31 + "y": 34 }, "id": 191, "options": { "legend": { - "calcs": [ - "mean" - ], + "calcs": [], "displayMode": "list", "placement": "bottom", "showLegend": true }, "tooltip": { - "mode": "multi", + "mode": "single", "sort": "none" } }, @@ -1652,12 +1697,11 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, - "expr": "db_gc_work_rxpages{instance=~\"$instance\"}", + "expr": "db_gc{phase=\"work_rxpages\", instance=~\"$instance\"}", "hide": false, "interval": "", "legendFormat": "work_rxpages: {{instance}}", @@ -1666,12 +1710,11 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, - "expr": "db_gc_self_rsteps{instance=~\"$instance\"}", + "expr": "db_gc{phase=\"self_rsteps\", instance=~\"$instance\"}", "hide": false, "interval": "", "legendFormat": "self_rsteps: {{instance}}", @@ -1680,12 +1723,11 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, - "expr": "db_gc_wloop{instance=~\"$instance\"}", + "expr": "db_gc{phase=\"wloop\", instance=~\"$instance\"}", "hide": false, "interval": "", "legendFormat": "wloop: {{instance}}", @@ -1694,12 +1736,11 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, - "expr": "db_gc_coalescences{instance=~\"$instance\"}", + "expr": "db_gc{phase=\"coalescences\", instance=~\"$instance\"}", "hide": false, "interval": "", "legendFormat": "coalescences: {{instance}}", @@ -1708,12 +1749,11 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, - "expr": "db_gc_wipes{instance=~\"$instance\"}", + "expr": "db_gc{phase=\"wipes\", instance=~\"$instance\"}", "hide": false, "interval": "", "legendFormat": "wipes: {{instance}}", @@ -1722,12 +1762,11 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, - "expr": "db_gc_flushes{instance=~\"$instance\"}", + "expr": "db_gc{phase=\"flushes\", instance=~\"$instance\"}", "hide": false, "interval": "", "legendFormat": "flushes: {{instance}}", @@ -1736,12 +1775,11 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, - "expr": "db_gc_kicks{instance=~\"$instance\"}", + "expr": "db_gc{phase=\"kicks\", instance=~\"$instance\"}", "hide": false, "interval": "", "legendFormat": "kicks: {{instance}}", @@ -1750,12 +1788,11 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, - "expr": "db_gc_work_rsteps{instance=~\"$instance\"}", + "expr": "db_gc{phase=\"work_rsteps\", instance=~\"$instance\"}", "hide": false, "interval": "", "legendFormat": "gc_work_rsteps: {{instance}}", @@ -1764,12 +1801,11 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, - "expr": "db_gc_self_xpages{instance=~\"$instance\"}", + "expr": "db_gc{phase=\"self_xpages\", instance=~\"$instance\"}", "hide": false, "interval": "", "legendFormat": "self_xpages: {{instance}}", @@ -1778,12 +1814,11 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, - "expr": "db_gc_work_majflt{instance=~\"$instance\"}", + "expr": "db_gc{phase=\"work_majflt\", instance=~\"$instance\"}", "hide": false, "interval": "", "legendFormat": "gc_work_majflt: {{instance}}", @@ -1792,12 +1827,11 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, - "expr": "db_gc_self_majflt{instance=~\"$instance\"}", + "expr": "db_gc{phase=\"self_majflt\", instance=~\"$instance\"}", "hide": false, "interval": "", "legendFormat": "gc_self_majflt: {{instance}}", @@ -1806,12 +1840,11 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, - "expr": "db_gc_self_counter{instance=~\"$instance\"}", + "expr": "db_gc{phase=\"self_counter\", instance=~\"$instance\"}", "hide": false, "interval": "", "legendFormat": "gc_self_counter: {{instance}}", @@ -1820,12 +1853,11 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, - "expr": "db_gc_work_counter{instance=~\"$instance\"}", + "expr": "db_gc{phase=\"work_counter\", instance=~\"$instance\"}", "hide": false, "interval": "", "legendFormat": "gc_work_counter: {{instance}}", @@ -1837,157 +1869,22 @@ "type": "timeseries" }, { + "collapsed": false, "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 10, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "never", - "spanNulls": true, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green" - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "ops" - }, - "overrides": [ - { - "__systemRef": "hideSeriesFrom", - "matcher": { - "id": "byNames", - "options": { - "mode": "exclude", - "names": [ - "hard: mainnet2-2:6061" - ], - "prefix": "All except:", - "readOnly": true - } - }, - "properties": [ - { - "id": "custom.hideFrom", - "value": { - "legend": false, - "tooltip": false, - "viz": true - } - } - ] - } - ] - }, - "gridPos": { - "h": 6, - "w": 16, - "x": 8, - "y": 39 - }, - "id": 150, - "options": { - "legend": { - "calcs": [ - "mean" - ], - "displayMode": "list", - "placement": "bottom", - "showLegend": true - }, - "tooltip": { - "mode": "multi", - "sort": "none" - } - }, - "pluginVersion": "8.0.6", - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "rate(process_minor_pagefaults_total{instance=~\"$instance\"}[$rate_interval])", - "interval": "", - "legendFormat": "soft: {{instance}}", - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "exemplar": true, - "expr": "rate(process_major_pagefaults_total{instance=~\"$instance\"}[$rate_interval])", - "hide": false, - "interval": "", - "legendFormat": "hard: {{instance}}", - "refId": "B" - } - ], - "title": "getrusage: minflt - soft page faults (reclaims), majflt - hard faults", - "type": "timeseries" - }, - { - "collapsed": false, - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "gridPos": { - "h": 1, - "w": 24, - "x": 0, - "y": 45 - }, - "id": 134, - "panels": [], - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 42 + }, + "id": 134, + "panels": [], + "targets": [ + { + "datasource": { + "type": "prometheus" }, "refId": "A" } @@ -1997,8 +1894,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -2018,7 +1914,7 @@ "h": 18, "w": 8, "x": 0, - "y": 46 + "y": 43 }, "id": 165, "options": { @@ -2039,12 +1935,11 @@ }, "textMode": "auto" }, - "pluginVersion": "9.2.3", + "pluginVersion": "9.4.7", "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "ru_inblock{instance=~\"$instance\"}", "interval": "", @@ -2053,8 +1948,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "ru_outblock{instance=~\"$instance\"}", "hide": false, @@ -2064,8 +1958,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "ru_minflt{instance=~\"$instance\"}", "hide": false, @@ -2075,8 +1968,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "ru_majflt{instance=~\"$instance\"}", "hide": false, @@ -2086,8 +1978,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "system_disk_readbytes{instance=~\"$instance\"}", "hide": false, @@ -2097,8 +1988,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "system_disk_writebytes{instance=~\"$instance\"}", "hide": false, @@ -2108,8 +1998,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "db_pgops_newly{instance=~\"$instance\"}", "hide": false, @@ -2119,8 +2008,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "db_pgops_cow{instance=~\"$instance\"}", "hide": false, @@ -2130,8 +2018,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "db_pgops_clone{instance=~\"$instance\"}", "hide": false, @@ -2141,8 +2028,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "db_pgops_split{instance=~\"$instance\"}", "hide": false, @@ -2152,8 +2038,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "db_pgops_merge{instance=~\"$instance\"}", "hide": false, @@ -2163,8 +2048,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "db_pgops_spill{instance=~\"$instance\"}", "hide": false, @@ -2174,8 +2058,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "db_pgops_unspill{instance=~\"$instance\"}", "hide": false, @@ -2185,8 +2068,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "db_pgops_wops{instance=~\"$instance\"}", "hide": false, @@ -2200,8 +2082,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "description": "", "fieldConfig": { @@ -2244,7 +2125,8 @@ "mode": "absolute", "steps": [ { - "color": "green" + "color": "green", + "value": null }, { "color": "red", @@ -2260,7 +2142,7 @@ "h": 6, "w": 8, "x": 8, - "y": 46 + "y": 43 }, "id": 155, "links": [], @@ -2282,8 +2164,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(process_io_write_syscalls_total{instance=~\"$instance\"}[$rate_interval])", @@ -2296,8 +2177,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(process_io_read_syscalls_total{instance=~\"$instance\"}[$rate_interval])", @@ -2314,8 +2194,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "description": "", "fieldConfig": { @@ -2358,7 +2237,8 @@ "mode": "absolute", "steps": [ { - "color": "green" + "color": "green", + "value": null }, { "color": "red", @@ -2374,7 +2254,7 @@ "h": 6, "w": 8, "x": 16, - "y": 46 + "y": 43 }, "id": 153, "options": { @@ -2395,8 +2275,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -2412,8 +2291,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -2421,13 +2299,11 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, "drawStyle": "line", - "fillOpacity": 10, + "fillOpacity": 25, "gradientMode": "none", "hideFrom": { "legend": false, @@ -2440,11 +2316,11 @@ "scaleDistribution": { "type": "linear" }, - "showPoints": "never", - "spanNulls": true, + "showPoints": "auto", + "spanNulls": false, "stacking": { "group": "A", - "mode": "none" + "mode": "normal" }, "thresholdsStyle": { "mode": "off" @@ -2462,55 +2338,27 @@ "value": 80 } ] - }, - "unit": "Bps" - }, - "overrides": [ - { - "__systemRef": "hideSeriesFrom", - "matcher": { - "id": "byNames", - "options": { - "mode": "exclude", - "names": [ - "write: mainnet2-2:6061" - ], - "prefix": "All except:", - "readOnly": true - } - }, - "properties": [ - { - "id": "custom.hideFrom", - "value": { - "legend": false, - "tooltip": false, - "viz": true - } - } - ] } - ] + }, + "overrides": [] }, "gridPos": { "h": 6, "w": 8, "x": 8, - "y": 52 + "y": 49 }, "id": 85, "links": [], "options": { "legend": { - "calcs": [ - "mean" - ], + "calcs": [], "displayMode": "list", "placement": "bottom", "showLegend": true }, "tooltip": { - "mode": "multi", + "mode": "single", "sort": "none" } }, @@ -2518,8 +2366,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(process_io_storage_read_bytes_total{instance=~\"$instance\"}[$rate_interval])", @@ -2531,8 +2378,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(process_io_storage_written_bytes_total{instance=~\"$instance\"}[$rate_interval])", @@ -2548,8 +2394,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -2557,8 +2402,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -2607,7 +2450,7 @@ "h": 6, "w": 8, "x": 16, - "y": 52 + "y": 49 }, "id": 128, "options": { @@ -2626,8 +2469,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "expr": "go_goroutines{instance=~\"$instance\"}", @@ -2638,8 +2480,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "expr": "go_threads{instance=~\"$instance\"}", @@ -2654,8 +2495,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "description": "", "fieldConfig": { @@ -2664,8 +2504,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -2714,7 +2552,7 @@ "h": 6, "w": 8, "x": 8, - "y": 58 + "y": 55 }, "id": 154, "links": [], @@ -2734,8 +2572,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -2749,8 +2586,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -2765,8 +2601,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -2781,8 +2616,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -2797,8 +2631,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -2813,8 +2646,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -2833,8 +2665,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -2842,8 +2673,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -2892,7 +2721,7 @@ "h": 5, "w": 8, "x": 16, - "y": 58 + "y": 55 }, "id": 124, "options": { @@ -2911,8 +2740,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -2928,8 +2756,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "description": "", "fieldConfig": { @@ -2938,8 +2765,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -2988,7 +2813,7 @@ "h": 5, "w": 8, "x": 0, - "y": 64 + "y": 61 }, "id": 148, "options": { @@ -3009,8 +2834,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "process_virtual_memory_bytes{instance=~\"$instance\"}", @@ -3021,8 +2845,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "process_resident_memory_anon_bytes{instance=~\"$instance\"}", @@ -3033,8 +2856,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "process_resident_memory_bytes{instance=~\"$instance\"}", @@ -3045,8 +2867,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "mem_data{instance=~\"$instance\"}", "hide": false, @@ -3056,8 +2877,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "mem_stack{instance=~\"$instance\"}", "hide": false, @@ -3067,8 +2887,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "mem_locked{instance=~\"$instance\"}", "hide": false, @@ -3078,8 +2897,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "mem_swap{instance=~\"$instance\"}", "hide": false, @@ -3093,8 +2911,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "description": "", "fieldConfig": { @@ -3103,8 +2920,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -3153,7 +2968,7 @@ "h": 5, "w": 8, "x": 0, - "y": 69 + "y": 66 }, "id": 86, "links": [], @@ -3173,8 +2988,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -3188,8 +3002,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -3208,8 +3021,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -3217,8 +3029,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -3267,7 +3077,7 @@ "h": 5, "w": 8, "x": 0, - "y": 74 + "y": 71 }, "id": 106, "links": [], @@ -3287,8 +3097,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "increase(process_cpu_seconds_system_total{instance=~\"$instance\"}[1m])", @@ -3300,8 +3109,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "increase(process_cpu_seconds_user_total{instance=~\"$instance\"}[1m])", @@ -3318,22 +3126,20 @@ { "collapsed": false, "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "gridPos": { "h": 1, "w": 24, "x": 0, - "y": 79 + "y": 76 }, "id": 82, "panels": [], "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "refId": "A" } @@ -3343,8 +3149,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "description": "", "fieldConfig": { @@ -3353,8 +3158,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -3403,7 +3206,7 @@ "h": 5, "w": 8, "x": 0, - "y": 80 + "y": 77 }, "id": 157, "links": [], @@ -3425,8 +3228,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "vmem_total{instance=~\"$instance\"}", "format": "time_series", @@ -3437,8 +3239,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "vmem_available{instance=~\"$instance\"}", "format": "time_series", @@ -3450,8 +3251,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "vmem_used{instance=~\"$instance\"}", "format": "time_series", @@ -3463,8 +3263,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "vmem_buffers{instance=~\"$instance\"}", "format": "time_series", @@ -3476,8 +3275,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "vmem_cached{instance=~\"$instance\"}", "format": "time_series", @@ -3489,8 +3287,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "vmem_writeback{instance=~\"$instance\"}", "format": "time_series", @@ -3502,8 +3299,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "vmem_dirty{instance=~\"$instance\"}", "format": "time_series", @@ -3515,8 +3311,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "vmem_shared{instance=~\"$instance\"}", "format": "time_series", @@ -3528,8 +3323,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "vmem_mapped{instance=~\"$instance\"}", "format": "time_series", @@ -3546,22 +3340,20 @@ { "collapsed": false, "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "gridPos": { "h": 1, "w": 24, "x": 0, - "y": 85 + "y": 82 }, "id": 173, "panels": [], "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "refId": "A" } @@ -3571,8 +3363,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -3580,8 +3371,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -3630,7 +3419,7 @@ "h": 8, "w": 12, "x": 0, - "y": 86 + "y": 83 }, "id": 175, "options": { @@ -3651,8 +3440,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "pool_process_remote_txs{quantile=\"$quantile\",instance=~\"$instance\"}", @@ -3662,8 +3450,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "pool_add_remote_txs{quantile=\"$quantile\",instance=~\"$instance\"}", @@ -3674,8 +3461,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "pool_new_block{quantile=\"$quantile\",instance=~\"$instance\"}", @@ -3686,8 +3472,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "pool_write_to_db{quantile=\"$quantile\",instance=~\"$instance\"}", @@ -3698,8 +3483,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "pool_propagate_to_new_peer{quantile=\"$quantile\",instance=~\"$instance\"}", @@ -3710,8 +3494,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "pool_propagate_new_txs{quantile=\"$quantile\",instance=~\"$instance\"}", @@ -3727,8 +3510,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -3736,8 +3518,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -3786,7 +3566,7 @@ "h": 8, "w": 12, "x": 12, - "y": 86 + "y": 83 }, "id": 177, "options": { @@ -3807,8 +3587,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(pool_process_remote_txs_count{instance=~\"$instance\"}[$rate_interval])", @@ -3819,8 +3598,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(pool_add_remote_txs_count{instance=~\"$instance\"}[$rate_interval])", @@ -3831,8 +3609,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(pool_new_block_count{instance=~\"$instance\"}[$rate_interval])", @@ -3843,8 +3620,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(pool_write_to_db_count{instance=~\"$instance\"}[$rate_interval])", @@ -3860,8 +3636,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -3869,8 +3644,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -3918,7 +3691,7 @@ "h": 6, "w": 8, "x": 0, - "y": 94 + "y": 91 }, "id": 176, "options": { @@ -3939,8 +3712,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "sum(delta(cache_total{result=\"hit\",name=\"txpool\",instance=~\"$instance\"}[1m]))/sum(delta(cache_total{name=\"txpool\",instance=~\"$instance\"}[1m])) ", @@ -3955,8 +3727,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -3964,8 +3735,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -4013,7 +3782,7 @@ "h": 6, "w": 8, "x": 8, - "y": 94 + "y": 91 }, "id": 180, "options": { @@ -4034,8 +3803,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(cache_total{name=\"txpool\",instance=~\"$instance\"}[1m])", @@ -4046,8 +3814,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(cache_timeout_total{name=\"txpool\",instance=~\"$instance\"}[1m])", @@ -4062,8 +3829,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -4071,8 +3837,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -4121,7 +3885,7 @@ "h": 6, "w": 8, "x": 16, - "y": 94 + "y": 91 }, "id": 181, "options": { @@ -4142,8 +3906,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "cache_keys_total{name=\"txpool\",instance=~\"$instance\"}", @@ -4154,8 +3917,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "cache_list_total{name=\"txpool\",instance=~\"$instance\"}", @@ -4170,8 +3932,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -4179,8 +3940,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -4229,7 +3988,7 @@ "h": 6, "w": 8, "x": 0, - "y": 100 + "y": 97 }, "id": 178, "options": { @@ -4250,8 +4009,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(pool_write_to_db_bytes{instance=~\"$instance\"}[$rate_interval])", @@ -4267,22 +4025,20 @@ { "collapsed": false, "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "gridPos": { "h": 1, "w": 24, "x": 0, - "y": 106 + "y": 103 }, "id": 183, "panels": [], "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "refId": "A" } @@ -4292,8 +4048,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -4301,8 +4056,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -4351,7 +4104,7 @@ "h": 8, "w": 12, "x": 0, - "y": 107 + "y": 104 }, "id": 185, "options": { @@ -4372,8 +4125,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(rpc_duration_seconds_count{instance=~\"$instance\",success=\"success\"}[1m])", @@ -4383,8 +4135,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(rpc_duration_seconds_count{instance=~\"$instance\",success=\"failure\"}[1m])", @@ -4400,8 +4151,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -4409,8 +4159,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -4459,7 +4207,7 @@ "h": 8, "w": 12, "x": 12, - "y": 107 + "y": 104 }, "id": 186, "options": { @@ -4480,8 +4228,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "db_begin_seconds{quantile=\"$quantile\",instance=~\"$instance\"}", @@ -4496,8 +4243,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -4505,8 +4251,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -4555,7 +4299,7 @@ "h": 8, "w": 12, "x": 0, - "y": 115 + "y": 112 }, "id": 187, "options": { @@ -4576,8 +4320,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rpc_duration_seconds{quantile=\"$quantile\",instance=~\"$instance\"}", @@ -4592,8 +4335,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -4601,8 +4343,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -4651,7 +4391,7 @@ "h": 8, "w": 12, "x": 12, - "y": 115 + "y": 112 }, "id": 188, "options": { @@ -4670,8 +4410,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "go_goroutines{instance=~\"$instance\"}", "instant": false, @@ -4681,8 +4420,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "go_threads{instance=~\"$instance\"}", "instant": false, @@ -4696,8 +4434,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -4705,8 +4442,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -4755,7 +4490,7 @@ "h": 6, "w": 8, "x": 8, - "y": 123 + "y": 120 }, "id": 189, "options": { @@ -4776,8 +4511,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "cache_keys_total{name=\"rpc\",instance=~\"$instance\"}", @@ -4788,8 +4522,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "cache_list_total{name=\"rpc\",instance=~\"$instance\"}", @@ -4800,8 +4533,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "cache_code_keys_total{name=\"rpc\",instance=~\"$instance\"}", @@ -4812,8 +4544,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "cache_code_list_total{name=\"rpc\",instance=~\"$instance\"}", @@ -4828,8 +4559,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -4837,8 +4567,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -4886,7 +4614,7 @@ "h": 6, "w": 8, "x": 16, - "y": 123 + "y": 120 }, "id": 184, "options": { @@ -4907,8 +4635,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "editorMode": "code", "exemplar": true, @@ -4921,8 +4648,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "sum(delta(cache_code_total{result=\"hit\",name=\"rpc\",instance=~\"$instance\"}[1m]))/sum(delta(cache_code_total{name=\"rpc\",instance=~\"$instance\"}[1m])) ", @@ -4936,844 +4662,797 @@ "type": "timeseries" }, { - "collapsed": true, + "collapsed": false, "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "gridPos": { "h": 1, "w": 24, "x": 0, - "y": 129 + "y": 126 }, "id": 146, - "panels": [ - { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 5, - "w": 8, - "x": 0, - "y": 54 - }, - "hiddenSeries": false, - "id": 122, - "legend": { - "alignAsTable": true, - "avg": true, - "current": false, - "hideEmpty": false, - "hideZero": false, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sort": "avg", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "8.0.6", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "trie_subtrieloader_flatdb{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "trie_subtrieloader_flatdb: {{quantile}}, {{instance}}", - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "trie_subtrieloader_witnessdb{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "trie_subtrieloader_witnessdb: {{quantile}}, {{instance}}", - "refId": "C" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "Merkle Root calculation (stage 5)", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "buckets": 6, - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:431", - "format": "ns", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:432", - "format": "short", - "logBase": 1, - "show": false - } - ], - "yaxis": { - "align": false - } + "panels": [], + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "refId": "A" + } + ], + "title": "Hidden", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 8, + "x": 0, + "y": 127 + }, + "hiddenSeries": false, + "id": 122, + "legend": { + "alignAsTable": true, + "avg": true, + "current": false, + "hideEmpty": false, + "hideZero": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.4.7", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "trie_subtrieloader_flatdb{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "trie_subtrieloader_flatdb: {{quantile}}, {{instance}}", + "refId": "B" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "trie_subtrieloader_witnessdb{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "trie_subtrieloader_witnessdb: {{quantile}}, {{instance}}", + "refId": "C" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "Merkle Root calculation (stage 5)", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": 6, + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:431", + "format": "ns", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:432", + "format": "short", + "logBase": 1, + "show": false + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus" + }, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 8, + "x": 8, + "y": 127 + }, + "hiddenSeries": false, + "id": 162, + "legend": { + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.4.7", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "rate(db_op_set_count{instance=~\"$instance\"}[1m])", + "interval": "", + "legendFormat": "", + "refId": "E" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "rate(db_op_set_range_count{instance=~\"$instance\"}[1m])", + "interval": "", + "legendFormat": "", + "refId": "F" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "rate(db_op_get_count{instance=~\"$instance\"}[1m])", + "interval": "", + "legendFormat": "", + "refId": "G" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "rate(db_op_get_both{instance=~\"$instance\"}[1m])", + "hide": false, + "interval": "", + "legendFormat": "", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "rate(db_op_get_both_range_count{instance=~\"$instance\"}[1m])", + "hide": false, + "interval": "", + "legendFormat": "", + "refId": "B" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "db_op_put{quantile=\"$quantile\",instance=~\"$instance\"}", + "hide": false, + "interval": "", + "legendFormat": "", + "refId": "C" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "db_op_put_current{quantile=\"$quantile\",instance=~\"$instance\"}", + "hide": false, + "interval": "", + "legendFormat": "", + "refId": "D" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "db_op_put_no_overwrite{quantile=\"$quantile\",instance=~\"$instance\"}", + "hide": false, + "interval": "", + "legendFormat": "", + "refId": "H" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "AutoDupsort Call/Sec", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:139", + "format": "short", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:140", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 8, + "x": 16, + "y": 127 + }, + "hiddenSeries": false, + "id": 156, + "legend": { + "avg": true, + "current": true, + "max": false, + "min": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.4.7", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "db_get{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "get: {{quantile}}, {{instance}}", + "refId": "A" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "db.Get() latency", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:887", + "format": "ns", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:888", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus" + }, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 8, + "x": 0, + "y": 132 + }, + "hiddenSeries": false, + "id": 143, + "legend": { + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.4.7", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "db_op_set{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "", + "refId": "E" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "db_op_set_range{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "", + "refId": "F" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "db_op_get{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "", + "refId": "G" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "db_op_get_both{quantile=\"$quantile\",instance=~\"$instance\"}", + "hide": false, + "interval": "", + "legendFormat": "", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "db_op_get_both_range{quantile=\"$quantile\",instance=~\"$instance\"}", + "hide": false, + "interval": "", + "legendFormat": "", + "refId": "B" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "db_op_put{quantile=\"$quantile\",instance=~\"$instance\"}", + "hide": false, + "interval": "", + "legendFormat": "", + "refId": "C" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "db_op_put_current{quantile=\"$quantile\",instance=~\"$instance\"}", + "hide": false, + "interval": "", + "legendFormat": "", + "refId": "D" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "db_op_put_no_overwrite{quantile=\"$quantile\",instance=~\"$instance\"}", + "hide": false, + "interval": "", + "legendFormat": "", + "refId": "H" + } + ], + "thresholds": [], + "timeRegions": [], + "title": "AutoDupsort Call/Sec", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:139", + "format": "ns", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:140", + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus" + }, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 5, + "w": 8, + "x": 8, + "y": 132 + }, + "hiddenSeries": false, + "id": 142, + "legend": { + "alignAsTable": false, + "avg": true, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.4.7", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_put_direct{quantile=\"$quantile\",instance=~\"$instance\"}", + "instant": false, + "interval": "", + "legendFormat": "mdbx_put_direct: {{quantile}}, {{instance}}", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_put_direct{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "mdbx_put_direct: {{quantile}}, {{instance}}", + "refId": "C" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_put_both_range{quantile=\"$quantile\",instance=~\"$instance\"}", + "instant": false, + "interval": "", + "legendFormat": "mdbx_put_both_range: {{quantile}}, {{instance}}", + "refId": "B" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_put_both_range{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "mdbx_put_both_range: {{quantile}}, {{instance}}", + "refId": "D" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_seek_exact{quantile=\"$quantile\",instance=~\"$instance\"}", + "hide": false, + "interval": "", + "legendFormat": "mdbx_seek_exact: {{quantile}}, {{instance}}", + "refId": "I" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_seek_exact{quantile=\"$quantile\",instance=~\"$instance\"}", + "hide": false, + "interval": "", + "legendFormat": "mdbx_seek_exact: {{quantile}}, {{instance}}", + "refId": "J" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_put_no_overwrite{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "mdbx_put_no_overwrite: {{quantile}}, {{instance}}", + "refId": "F" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_put_no_overwrite{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "mdbx_put_no_overwrite: {{quantile}}, {{instance}}", + "refId": "E" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_put_upsert{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "mdbx_put_upsert: {{quantile}}, {{instance}}", + "refId": "G" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 5, - "w": 8, - "x": 8, - "y": 54 - }, - "hiddenSeries": false, - "id": 162, - "legend": { - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "8.0.6", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "rate(db_op_set_count{instance=~\"$instance\"}[1m])", - "interval": "", - "legendFormat": "", - "refId": "E" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "rate(db_op_set_range_count{instance=~\"$instance\"}[1m])", - "interval": "", - "legendFormat": "", - "refId": "F" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "rate(db_op_get_count{instance=~\"$instance\"}[1m])", - "interval": "", - "legendFormat": "", - "refId": "G" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "rate(db_op_get_both{instance=~\"$instance\"}[1m])", - "hide": false, - "interval": "", - "legendFormat": "", - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "rate(db_op_get_both_range_count{instance=~\"$instance\"}[1m])", - "hide": false, - "interval": "", - "legendFormat": "", - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "db_op_put{quantile=\"$quantile\",instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "", - "refId": "C" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "db_op_put_current{quantile=\"$quantile\",instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "", - "refId": "D" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "db_op_put_no_overwrite{quantile=\"$quantile\",instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "", - "refId": "H" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "AutoDupsort Call/Sec", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:139", - "format": "short", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:140", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_put_upsert{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "mdbx_put_upsert: {{quantile}}, {{instance}}", + "refId": "H" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 4, - "w": 8, - "x": 16, - "y": 54 - }, - "hiddenSeries": false, - "id": 156, - "legend": { - "avg": true, - "current": true, - "max": false, - "min": false, - "show": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "8.0.6", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "db_get{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "get: {{quantile}}, {{instance}}", - "refId": "A" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "db.Get() latency", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:887", - "format": "ns", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:888", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_put_current2{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "mdbx_put_current2: {{quantile}}, {{instance}}", + "refId": "K" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 5, - "w": 8, - "x": 0, - "y": 59 - }, - "hiddenSeries": false, - "id": 143, - "legend": { - "avg": false, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "8.0.6", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "db_op_set{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "", - "refId": "E" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "db_op_set_range{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "", - "refId": "F" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "db_op_get{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "", - "refId": "G" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "db_op_get_both{quantile=\"$quantile\",instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "", - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "db_op_get_both_range{quantile=\"$quantile\",instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "", - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "db_op_put{quantile=\"$quantile\",instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "", - "refId": "C" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "db_op_put_current{quantile=\"$quantile\",instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "", - "refId": "D" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "db_op_put_no_overwrite{quantile=\"$quantile\",instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "", - "refId": "H" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "AutoDupsort Call/Sec", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:139", - "format": "ns", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:140", - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_put_current2{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "mdbx_put_current2: {{quantile}}, {{instance}}", + "refId": "L" }, { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "description": "", - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 5, - "w": 8, - "x": 8, - "y": 59 - }, - "hiddenSeries": false, - "id": 142, - "legend": { - "alignAsTable": false, - "avg": true, - "current": false, - "hideEmpty": true, - "hideZero": true, - "max": false, - "min": false, - "rightSide": false, - "show": true, - "sort": "avg", - "sortDesc": true, - "total": false, - "values": true - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "8.0.6", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_put_direct{quantile=\"$quantile\",instance=~\"$instance\"}", - "instant": false, - "interval": "", - "legendFormat": "mdbx_put_direct: {{quantile}}, {{instance}}", - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_put_direct{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "mdbx_put_direct: {{quantile}}, {{instance}}", - "refId": "C" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_put_both_range{quantile=\"$quantile\",instance=~\"$instance\"}", - "instant": false, - "interval": "", - "legendFormat": "mdbx_put_both_range: {{quantile}}, {{instance}}", - "refId": "B" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_put_both_range{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "mdbx_put_both_range: {{quantile}}, {{instance}}", - "refId": "D" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_seek_exact{quantile=\"$quantile\",instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "mdbx_seek_exact: {{quantile}}, {{instance}}", - "refId": "I" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_seek_exact{quantile=\"$quantile\",instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "mdbx_seek_exact: {{quantile}}, {{instance}}", - "refId": "J" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_put_no_overwrite{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "mdbx_put_no_overwrite: {{quantile}}, {{instance}}", - "refId": "F" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_put_no_overwrite{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "mdbx_put_no_overwrite: {{quantile}}, {{instance}}", - "refId": "E" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_put_upsert{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "mdbx_put_upsert: {{quantile}}, {{instance}}", - "refId": "G" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_put_upsert{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "mdbx_put_upsert: {{quantile}}, {{instance}}", - "refId": "H" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_put_current2{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "mdbx_put_current2: {{quantile}}, {{instance}}", - "refId": "K" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_put_current2{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "mdbx_put_current2: {{quantile}}, {{instance}}", - "refId": "L" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_put_upsert2{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "mdbx_put_upsert2: {{quantile}}, {{instance}}", - "refId": "M" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_put_upsert2{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "mdbx_put_upsert2: {{quantile}}, {{instance}}", - "refId": "N" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_del_current{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "mdbx_put_current: {{quantile}}, {{instance}}", - "refId": "O" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_del_current{quantile=\"$quantile\",instance=~\"$instance\"}", - "interval": "", - "legendFormat": "mdbx_del_current: {{quantile}}, {{instance}}", - "refId": "P" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_seek_exact2{quantile=\"$quantile\",instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "mdbx_seek_exact2: {{quantile}}, {{instance}}", - "refId": "Q" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "mdbx_seek_exact2{quantile=\"$quantile\",instance=~\"$instance\"}", - "hide": false, - "interval": "", - "legendFormat": "mdbx_seek_exact2: {{quantile}}, {{instance}}", - "refId": "R" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "AutoDupsort Put latency", - "tooltip": { - "shared": true, - "sort": 2, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "$$hashKey": "object:139", - "format": "ns", - "logBase": 1, - "show": true - }, - { - "$$hashKey": "object:140", - "format": "short", - "logBase": 1, - "show": false - } - ], - "yaxis": { - "align": false - } - } - ], - "targets": [ + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_put_upsert2{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "mdbx_put_upsert2: {{quantile}}, {{instance}}", + "refId": "M" + }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, - "refId": "A" + "expr": "mdbx_put_upsert2{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "mdbx_put_upsert2: {{quantile}}, {{instance}}", + "refId": "N" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_del_current{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "mdbx_put_current: {{quantile}}, {{instance}}", + "refId": "O" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_del_current{quantile=\"$quantile\",instance=~\"$instance\"}", + "interval": "", + "legendFormat": "mdbx_del_current: {{quantile}}, {{instance}}", + "refId": "P" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_seek_exact2{quantile=\"$quantile\",instance=~\"$instance\"}", + "hide": false, + "interval": "", + "legendFormat": "mdbx_seek_exact2: {{quantile}}, {{instance}}", + "refId": "Q" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "mdbx_seek_exact2{quantile=\"$quantile\",instance=~\"$instance\"}", + "hide": false, + "interval": "", + "legendFormat": "mdbx_seek_exact2: {{quantile}}, {{instance}}", + "refId": "R" } ], - "title": "Hidden", - "type": "row" + "thresholds": [], + "timeRegions": [], + "title": "AutoDupsort Put latency", + "tooltip": { + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:139", + "format": "ns", + "logBase": 1, + "show": true + }, + { + "$$hashKey": "object:140", + "format": "short", + "logBase": 1, + "show": false + } + ], + "yaxis": { + "align": false + } }, { "collapsed": false, "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "gridPos": { "h": 1, "w": 24, "x": 0, - "y": 130 + "y": 137 }, "id": 75, "panels": [], "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "refId": "A" } @@ -5783,8 +5462,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -5792,8 +5470,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -5842,7 +5518,7 @@ "h": 6, "w": 12, "x": 0, - "y": 131 + "y": 138 }, "id": 96, "links": [], @@ -5867,8 +5543,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(p2p_ingress{instance=~\"$instance\"}[$rate_interval])", @@ -5880,8 +5555,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, "expr": "rate(p2p_egress{instance=~\"$instance\"}[$rate_interval])", @@ -5898,8 +5572,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -5907,8 +5580,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -5957,7 +5628,7 @@ "h": 6, "w": 12, "x": 12, - "y": 131 + "y": 138 }, "id": 77, "links": [], @@ -5982,8 +5653,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "p2p_peers{instance=~\"$instance\"}", "format": "time_series", @@ -5994,8 +5664,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "rate(p2p_dials{instance=~\"$instance\"}[1m])", "format": "time_series", @@ -6006,8 +5675,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "rate(p2p_serves{instance=~\"$instance\"}[1m])", "format": "time_series", @@ -6023,22 +5691,20 @@ { "collapsed": false, "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "gridPos": { "h": 1, "w": 24, "x": 0, - "y": 137 + "y": 144 }, "id": 4, "panels": [], "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "refId": "A" } @@ -6048,8 +5714,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -6084,7 +5749,7 @@ "h": 3, "w": 4, "x": 0, - "y": 138 + "y": 145 }, "id": 108, "links": [], @@ -6109,12 +5774,11 @@ "text": {}, "textMode": "auto" }, - "pluginVersion": "9.2.3", + "pluginVersion": "8.4.7", "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "sync{instance=~\"$instance\",stage=\"headers\"}", "format": "time_series", @@ -6129,8 +5793,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -6165,7 +5828,7 @@ "h": 3, "w": 4, "x": 8, - "y": 138 + "y": 145 }, "id": 109, "links": [], @@ -6190,15 +5853,14 @@ "text": {}, "textMode": "auto" }, - "pluginVersion": "9.2.3", + "pluginVersion": "8.4.7", "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "exemplar": true, - "expr": "stage_headers{instance=~\"$instance\"}", + "expr": "sync{stage=\"headers\", instance=~\"$instance\"}", "format": "time_series", "interval": "", "intervalFactor": 1, @@ -6211,8 +5873,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -6247,7 +5908,7 @@ "h": 3, "w": 4, "x": 12, - "y": 138 + "y": 145 }, "id": 113, "links": [], @@ -6272,12 +5933,11 @@ "text": {}, "textMode": "auto" }, - "pluginVersion": "9.2.3", + "pluginVersion": "8.4.7", "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "txpool_pending{instance=~\"$instance\"}", "format": "time_series", @@ -6292,8 +5952,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -6328,7 +5987,7 @@ "h": 3, "w": 4, "x": 16, - "y": 138 + "y": 145 }, "id": 114, "links": [], @@ -6353,12 +6012,11 @@ "text": {}, "textMode": "auto" }, - "pluginVersion": "9.2.3", + "pluginVersion": "8.4.7", "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "txpool_queued{instance=~\"$instance\"}", "format": "time_series", @@ -6373,8 +6031,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -6409,7 +6066,7 @@ "h": 3, "w": 4, "x": 20, - "y": 138 + "y": 145 }, "id": 115, "links": [], @@ -6434,13 +6091,13 @@ "text": {}, "textMode": "auto" }, - "pluginVersion": "9.2.3", + "pluginVersion": "8.4.7", "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, + "exemplar": true, "expr": "txpool_local{instance=~\"$instance\"}", "format": "time_series", "interval": "", @@ -6454,8 +6111,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -6463,8 +6119,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -6513,7 +6167,7 @@ "h": 6, "w": 12, "x": 0, - "y": 141 + "y": 148 }, "id": 110, "links": [], @@ -6533,8 +6187,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "chain_head_header{instance=~\"$instance\"}", "format": "time_series", @@ -6545,8 +6198,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "chain_head_receipt{instance=~\"$instance\"}", "format": "time_series", @@ -6557,8 +6209,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "chain_head_block{instance=~\"$instance\"}", "format": "time_series", @@ -6573,8 +6224,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -6582,8 +6232,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -6632,7 +6280,7 @@ "h": 6, "w": 12, "x": 12, - "y": 141 + "y": 148 }, "id": 116, "links": [], @@ -6652,8 +6300,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "txpool_pending{instance=~\"$instance\"}", "format": "time_series", @@ -6664,8 +6311,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "txpool_queued{instance=~\"$instance\"}", "format": "time_series", @@ -6676,8 +6322,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "txpool_local{instance=~\"$instance\"}", "format": "time_series", @@ -6692,8 +6337,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "fieldConfig": { "defaults": { @@ -6701,8 +6345,6 @@ "mode": "palette-classic" }, "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", "axisLabel": "", "axisPlacement": "auto", "barAlignment": 0, @@ -6751,7 +6393,7 @@ "h": 7, "w": 24, "x": 0, - "y": 147 + "y": 154 }, "id": 117, "links": [], @@ -6776,8 +6418,7 @@ "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "rate(txpool_valid{instance=~\"$instance\"}[1m])", "format": "time_series", @@ -6788,8 +6429,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "rate(txpool_invalid{instance=~\"$instance\"}[1m])", "format": "time_series", @@ -6800,8 +6440,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "rate(txpool_underpriced{instance=\"$instance\"}[1m])", "format": "time_series", @@ -6813,8 +6452,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "rate(txpool_pending_discard{instance=\"$instance\"}[1m])", "format": "time_series", @@ -6826,8 +6464,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "rate(txpool_pending_replace{instance=\"$instance\"}[1m])", "format": "time_series", @@ -6838,8 +6475,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "rate(txpool_pending_ratelimit{instance=\"$instance\"}[1m])", "format": "time_series", @@ -6850,8 +6486,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "rate(txpool_pending_nofunds{instance=\"$instance\"}[1m])", "format": "time_series", @@ -6862,8 +6497,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "rate(txpool_queued_discard{instance=\"$instance\"}[1m])", "format": "time_series", @@ -6875,8 +6509,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "rate(txpool_queued_replace{instance=\"$instance\"}[1m])", "format": "time_series", @@ -6888,8 +6521,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "rate(txpool_queued_ratelimit{instance=\"$instance\"}[1m])", "format": "time_series", @@ -6901,8 +6533,7 @@ }, { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "expr": "rate(txpool_queued_nofunds{instance=\"$instance\"}[1m])", "format": "time_series", @@ -6917,136 +6548,125 @@ "type": "timeseries" }, { - "collapsed": true, + "collapsed": false, "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "gridPos": { "h": 1, "w": 24, "x": 0, - "y": 154 + "y": 161 }, "id": 138, - "panels": [ + "panels": [], + "targets": [ { - "aliasColors": {}, - "bars": false, - "dashLength": 10, - "dashes": false, "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, - "fieldConfig": { - "defaults": { - "custom": {} - }, - "overrides": [] - }, - "fill": 1, - "fillGradient": 0, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 64 - }, - "hiddenSeries": false, - "id": 136, - "legend": { - "avg": false, - "current": false, - "max": false, - "min": false, - "show": true, - "total": false, - "values": false - }, - "lines": true, - "linewidth": 1, - "nullPointMode": "null", - "options": { - "alertThreshold": true - }, - "percentage": false, - "pluginVersion": "7.4.3", - "pointradius": 2, - "points": false, - "renderer": "flot", - "seriesOverrides": [], - "spaceLength": 10, - "stack": false, - "steppedLine": false, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "sum by (grpc_service, grpc_method, instance) (rate(grpc_server_started_total{instance=~\"$instance\"}[1m]))", - "interval": "", - "legendFormat": "Calls: {{grpc_service}}.{{grpc_method}}, {{instance}}", - "refId": "A" - }, - { - "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" - }, - "expr": "sum by (grpc_service, grpc_method, instance) (rate(grpc_server_handled_total{instance=~\"$instance\",grpc_code!=\"OK\"}[1m])) ", - "interval": "", - "legendFormat": "Errors: {{grpc_service}}.{{grpc_method}}, {{instance}}", - "refId": "B" - } - ], - "thresholds": [], - "timeRegions": [], - "title": "gRPC call, error rates ", - "tooltip": { - "shared": true, - "sort": 0, - "value_type": "individual" - }, - "type": "graph", - "xaxis": { - "mode": "time", - "show": true, - "values": [] - }, - "yaxes": [ - { - "format": "short", - "logBase": 1, - "show": true - }, - { - "format": "short", - "logBase": 1, - "show": true - } - ], - "yaxis": { - "align": false - } + "refId": "A" } ], + "title": "Private api", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": { + "type": "prometheus" + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 162 + }, + "hiddenSeries": false, + "id": 136, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "8.4.7", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, "targets": [ { "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, + "expr": "sum by (grpc_service, grpc_method, instance) (rate(grpc_server_started_total{instance=~\"$instance\"}[1m]))", + "interval": "", + "legendFormat": "Calls: {{grpc_service}}.{{grpc_method}}, {{instance}}", "refId": "A" + }, + { + "datasource": { + "type": "prometheus" + }, + "expr": "sum by (grpc_service, grpc_method, instance) (rate(grpc_server_handled_total{instance=~\"$instance\",grpc_code!=\"OK\"}[1m])) ", + "interval": "", + "legendFormat": "Errors: {{grpc_service}}.{{grpc_method}}, {{instance}}", + "refId": "B" } ], - "title": "Private api", - "type": "row" + "thresholds": [], + "timeRegions": [], + "title": "gRPC call, error rates ", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "mode": "time", + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "logBase": 1, + "show": true + }, + { + "format": "short", + "logBase": 1, + "show": true + } + ], + "yaxis": { + "align": false + } } ], "refresh": "30s", - "schemaVersion": 37, + "revision": 1, + "schemaVersion": 38, "style": "dark", "tags": [], "templating": { @@ -7107,15 +6727,16 @@ "current": { "selected": true, "text": [ - "All" + "mainnet3-2:6061", + "mainnet3-3:6061" ], "value": [ - "$__all" + "mainnet3-2:6061", + "mainnet3-3:6061" ] }, "datasource": { - "type": "prometheus", - "uid": "PBFA97CFB590B2093" + "type": "prometheus" }, "definition": "go_goroutines", "hide": 0, @@ -7142,7 +6763,7 @@ "auto_count": 30, "auto_min": "10s", "current": { - "selected": true, + "selected": false, "text": "1m", "value": "1m" }, @@ -7215,7 +6836,7 @@ ] }, "time": { - "from": "now-1h", + "from": "now-15m", "to": "now" }, "timepicker": { @@ -7245,6 +6866,6 @@ "timezone": "", "title": "Erigon Prometheus", "uid": "FPpjH6Hik", - "version": 89, + "version": 103, "weekStart": "" } \ No newline at end of file diff --git a/cmd/rpcdaemon/README.md b/cmd/rpcdaemon/README.md index e1cbc8262bd..043f3efe73b 100644 --- a/cmd/rpcdaemon/README.md +++ b/cmd/rpcdaemon/README.md @@ -254,7 +254,7 @@ The following table shows the current implementation status of Erigon's RPC daem | eth_signTransaction | - | not yet implemented | | eth_signTypedData | - | ???? | | | | | -| eth_getProof | - | not yet implemented | +| eth_getProof | Yes | Limited to last 1000 blocks | | | | | | eth_mining | Yes | returns true if --mine flag provided | | eth_coinbase | Yes | | diff --git a/cmd/rpcdaemon/commands/call_traces_test.go b/cmd/rpcdaemon/commands/call_traces_test.go index 730410db4ea..7b040bfd5bc 100644 --- a/cmd/rpcdaemon/commands/call_traces_test.go +++ b/cmd/rpcdaemon/commands/call_traces_test.go @@ -75,7 +75,7 @@ func TestCallTraceOneByOne(t *testing.T) { ToBlock: (*hexutil.Uint64)(&toBlock), ToAddress: []*common.Address{&toAddress1}, } - if err = api.Filter(context.Background(), traceReq1, stream); err != nil { + if err = api.Filter(context.Background(), traceReq1, stream, new(bool)); err != nil { t.Fatalf("trace_filter failed: %v", err) } assert.Equal(t, []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, blockNumbersFromTraces(t, stream.Buffer())) @@ -119,7 +119,7 @@ func TestCallTraceUnwind(t *testing.T) { ToBlock: (*hexutil.Uint64)(&toBlock), ToAddress: []*common.Address{&toAddress1}, } - if err = api.Filter(context.Background(), traceReq1, stream); err != nil { + if err = api.Filter(context.Background(), traceReq1, stream, new(bool)); err != nil { t.Fatalf("trace_filter failed: %v", err) } assert.Equal(t, []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, blockNumbersFromTraces(t, stream.Buffer())) @@ -134,7 +134,7 @@ func TestCallTraceUnwind(t *testing.T) { ToBlock: (*hexutil.Uint64)(&toBlock), ToAddress: []*common.Address{&toAddress1}, } - if err = api.Filter(context.Background(), traceReq2, stream); err != nil { + if err = api.Filter(context.Background(), traceReq2, stream, new(bool)); err != nil { t.Fatalf("trace_filter failed: %v", err) } assert.Equal(t, []int{1, 2, 3, 4, 5, 11, 12}, blockNumbersFromTraces(t, stream.Buffer())) @@ -150,7 +150,7 @@ func TestCallTraceUnwind(t *testing.T) { ToBlock: (*hexutil.Uint64)(&toBlock), ToAddress: []*common.Address{&toAddress1}, } - if err = api.Filter(context.Background(), traceReq3, stream); err != nil { + if err = api.Filter(context.Background(), traceReq3, stream, new(bool)); err != nil { t.Fatalf("trace_filter failed: %v", err) } assert.Equal(t, []int{12, 13, 14, 15, 16, 17, 18, 19, 20}, blockNumbersFromTraces(t, stream.Buffer())) @@ -182,7 +182,7 @@ func TestFilterNoAddresses(t *testing.T) { FromBlock: (*hexutil.Uint64)(&fromBlock), ToBlock: (*hexutil.Uint64)(&toBlock), } - if err = api.Filter(context.Background(), traceReq1, stream); err != nil { + if err = api.Filter(context.Background(), traceReq1, stream, new(bool)); err != nil { t.Fatalf("trace_filter failed: %v", err) } assert.Equal(t, []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, blockNumbersFromTraces(t, stream.Buffer())) @@ -233,7 +233,7 @@ func TestFilterAddressIntersection(t *testing.T) { ToAddress: []*common.Address{&m.Address, &toAddress2}, Mode: TraceFilterModeIntersection, } - if err = api.Filter(context.Background(), traceReq1, stream); err != nil { + if err = api.Filter(context.Background(), traceReq1, stream, new(bool)); err != nil { t.Fatalf("trace_filter failed: %v", err) } assert.Equal(t, []int{6, 7, 8, 9, 10}, blockNumbersFromTraces(t, stream.Buffer())) @@ -249,7 +249,7 @@ func TestFilterAddressIntersection(t *testing.T) { ToAddress: []*common.Address{&toAddress1, &m.Address}, Mode: TraceFilterModeIntersection, } - if err = api.Filter(context.Background(), traceReq1, stream); err != nil { + if err = api.Filter(context.Background(), traceReq1, stream, new(bool)); err != nil { t.Fatalf("trace_filter failed: %v", err) } assert.Equal(t, []int{1, 2, 3, 4, 5}, blockNumbersFromTraces(t, stream.Buffer())) @@ -265,7 +265,7 @@ func TestFilterAddressIntersection(t *testing.T) { FromAddress: []*common.Address{&toAddress2, &toAddress1, &other}, Mode: TraceFilterModeIntersection, } - if err = api.Filter(context.Background(), traceReq1, stream); err != nil { + if err = api.Filter(context.Background(), traceReq1, stream, new(bool)); err != nil { t.Fatalf("trace_filter failed: %v", err) } require.Empty(t, blockNumbersFromTraces(t, stream.Buffer())) diff --git a/cmd/rpcdaemon/commands/daemon.go b/cmd/rpcdaemon/commands/daemon.go index 87f30d6c909..12bdec39db8 100644 --- a/cmd/rpcdaemon/commands/daemon.go +++ b/cmd/rpcdaemon/commands/daemon.go @@ -15,7 +15,7 @@ import ( // APIList describes the list of available RPC apis func APIList(db kv.RoDB, borDb kv.RoDB, eth rpchelper.ApiBackend, txPool txpool.TxpoolClient, mining txpool.MiningClient, filters *rpchelper.Filters, stateCache kvcache.Cache, - blockReader services.FullBlockReader, agg *libstate.AggregatorV3, cfg httpcfg.HttpCfg, engine consensus.EngineReader, + blockReader services.FullBlockReader, agg *libstate.AggregatorV3, cfg httpcfg.HttpCfg, engine consensus.Engine, ) (list []rpc.API) { base := NewBaseApi(filters, stateCache, blockReader, agg, cfg.WithDatadir, cfg.EvmCallTimeout, engine) ethImpl := NewEthAPI(base, db, eth, txPool, mining, cfg.Gascap, cfg.ReturnDataLimit) diff --git a/cmd/rpcdaemon/commands/db_api_deprecated.go b/cmd/rpcdaemon/commands/db_api_deprecated.go index 886987e05c1..2ee0700a347 100644 --- a/cmd/rpcdaemon/commands/db_api_deprecated.go +++ b/cmd/rpcdaemon/commands/db_api_deprecated.go @@ -4,15 +4,15 @@ import ( "context" "fmt" - "github.com/ledgerwatch/erigon/common/hexutil" + "github.com/ledgerwatch/erigon-lib/common/hexutility" ) // DBAPI the interface for the db_ RPC commands (deprecated) type DBAPI interface { GetString(_ context.Context, _ string, _ string) (string, error) PutString(_ context.Context, _ string, _ string, _ string) (bool, error) - GetHex(_ context.Context, _ string, _ string) (hexutil.Bytes, error) - PutHex(_ context.Context, _ string, _ string, _ hexutil.Bytes) (bool, error) + GetHex(_ context.Context, _ string, _ string) (hexutility.Bytes, error) + PutHex(_ context.Context, _ string, _ string, _ hexutility.Bytes) (bool, error) } // DBAPIImpl data structure to store things needed for db_ commands @@ -41,12 +41,12 @@ func (api *DBAPIImpl) PutString(_ context.Context, _ string, _ string, _ string) // GetHex implements db_getHex. Returns binary data from the local database. // Deprecated: This function will be removed in the future. -func (api *DBAPIImpl) GetHex(_ context.Context, _ string, _ string) (hexutil.Bytes, error) { - return hexutil.Bytes(""), fmt.Errorf(NotAvailableDeprecated, "db_getHex") +func (api *DBAPIImpl) GetHex(_ context.Context, _ string, _ string) (hexutility.Bytes, error) { + return hexutility.Bytes(""), fmt.Errorf(NotAvailableDeprecated, "db_getHex") } // PutHex implements db_putHex. Stores binary data in the local database. // Deprecated: This function will be removed in the future. -func (api *DBAPIImpl) PutHex(_ context.Context, _ string, _ string, _ hexutil.Bytes) (bool, error) { +func (api *DBAPIImpl) PutHex(_ context.Context, _ string, _ string, _ hexutility.Bytes) (bool, error) { return false, fmt.Errorf(NotAvailableDeprecated, "db_putHex") } diff --git a/cmd/rpcdaemon/commands/debug_api.go b/cmd/rpcdaemon/commands/debug_api.go index 682c6a6e524..b6f72e536d8 100644 --- a/cmd/rpcdaemon/commands/debug_api.go +++ b/cmd/rpcdaemon/commands/debug_api.go @@ -6,19 +6,25 @@ import ( jsoniter "github.com/json-iterator/go" "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv/order" "github.com/ledgerwatch/erigon-lib/kv/rawdbv3" + "github.com/ledgerwatch/erigon/common/changeset" "github.com/ledgerwatch/erigon/common/hexutil" + "github.com/ledgerwatch/erigon/consensus" "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/state" "github.com/ledgerwatch/erigon/core/state/temporal" "github.com/ledgerwatch/erigon/core/types/accounts" + "github.com/ledgerwatch/erigon/eth/stagedsync" "github.com/ledgerwatch/erigon/eth/stagedsync/stages" "github.com/ledgerwatch/erigon/eth/tracers" + "github.com/ledgerwatch/erigon/rlp" "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/adapter/ethapi" + "github.com/ledgerwatch/erigon/turbo/rpchelper" "github.com/ledgerwatch/erigon/turbo/transactions" ) @@ -27,7 +33,7 @@ const AccountRangeMaxResults = 256 // PrivateDebugAPI Exposed RPC endpoints for debugging use type PrivateDebugAPI interface { - StorageRangeAt(ctx context.Context, blockHash common.Hash, txIndex uint64, contractAddress common.Address, keyStart hexutil.Bytes, maxResult int) (StorageRangeResult, error) + StorageRangeAt(ctx context.Context, blockHash common.Hash, txIndex uint64, contractAddress common.Address, keyStart hexutility.Bytes, maxResult int) (StorageRangeResult, error) TraceTransaction(ctx context.Context, hash common.Hash, config *tracers.TraceConfig, stream *jsoniter.Stream) error TraceBlockByHash(ctx context.Context, hash common.Hash, config *tracers.TraceConfig, stream *jsoniter.Stream) error TraceBlockByNumber(ctx context.Context, number rpc.BlockNumber, config *tracers.TraceConfig, stream *jsoniter.Stream) error @@ -36,6 +42,8 @@ type PrivateDebugAPI interface { GetModifiedAccountsByHash(_ context.Context, startHash common.Hash, endHash *common.Hash) ([]common.Address, error) TraceCall(ctx context.Context, args ethapi.CallArgs, blockNrOrHash rpc.BlockNumberOrHash, config *tracers.TraceConfig, stream *jsoniter.Stream) error AccountAt(ctx context.Context, blockHash common.Hash, txIndex uint64, account common.Address) (*AccountResult, error) + GetRawHeader(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (hexutility.Bytes, error) + GetRawBlock(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (hexutility.Bytes, error) } // PrivateDebugAPIImpl is implementation of the PrivateDebugAPI interface based on remote Db access @@ -55,7 +63,7 @@ func NewPrivateDebugAPI(base *BaseAPI, db kv.RoDB, gascap uint64) *PrivateDebugA } // storageRangeAt implements debug_storageRangeAt. Returns information about a range of storage locations (if any) for the given address. -func (api *PrivateDebugAPIImpl) StorageRangeAt(ctx context.Context, blockHash common.Hash, txIndex uint64, contractAddress common.Address, keyStart hexutil.Bytes, maxResult int) (StorageRangeResult, error) { +func (api *PrivateDebugAPIImpl) StorageRangeAt(ctx context.Context, blockHash common.Hash, txIndex uint64, contractAddress common.Address, keyStart hexutility.Bytes, maxResult int) (StorageRangeResult, error) { tx, err := api.db.BeginRo(ctx) if err != nil { return StorageRangeResult{}, err @@ -113,6 +121,45 @@ func (api *PrivateDebugAPIImpl) AccountRange(ctx context.Context, blockNrOrHash if err != nil { return state.IteratorDump{}, fmt.Errorf("last block has not found: %w", err) } + } else if number == rpc.FinalizedBlockNumber { + if posa, isPoSA := api.engine().(consensus.PoSA); isPoSA { + headerNumber, err := stages.GetStageProgress(tx, stages.Execution) + if err != nil { + return state.IteratorDump{}, err + } + headerHash, err := rawdb.ReadCanonicalHash(tx, headerNumber) + if err != nil { + return state.IteratorDump{}, err + } + if headerHash != (common.Hash{}) { + if header := rawdb.ReadHeader(tx, headerHash, headerNumber); header != nil { + if chainConfig, err := api.chainConfig(tx); err == nil { + blockNumber = posa.GetFinalizedHeader(stagedsync.NewChainReaderImpl(chainConfig, tx, nil), header).Number.Uint64() + } + } + } + } + } else if number == rpc.SafeBlockNumber { + if posa, isPoSA := api.engine().(consensus.PoSA); isPoSA { + headerNumber, err := stages.GetStageProgress(tx, stages.Execution) + if err != nil { + return state.IteratorDump{}, err + } + headerHash, err := rawdb.ReadCanonicalHash(tx, headerNumber) + if err != nil { + return state.IteratorDump{}, err + } + if headerHash != (common.Hash{}) { + if header := rawdb.ReadHeader(tx, headerHash, headerNumber); header != nil { + if chainConfig, err := api.chainConfig(tx); err == nil { + blockNumber, _, err = posa.GetJustifiedNumberAndHash(stagedsync.NewChainReaderImpl(chainConfig, tx, nil), header) + if err != nil { + return state.IteratorDump{}, err + } + } + } + } + } } else { blockNumber = uint64(number) } @@ -351,8 +398,48 @@ func (api *PrivateDebugAPIImpl) AccountAt(ctx context.Context, blockHash common. } type AccountResult struct { - Balance hexutil.Big `json:"balance"` - Nonce hexutil.Uint64 `json:"nonce"` - Code hexutil.Bytes `json:"code"` - CodeHash common.Hash `json:"codeHash"` + Balance hexutil.Big `json:"balance"` + Nonce hexutil.Uint64 `json:"nonce"` + Code hexutility.Bytes `json:"code"` + CodeHash common.Hash `json:"codeHash"` +} + +func (api *PrivateDebugAPIImpl) GetRawHeader(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (hexutility.Bytes, error) { + tx, err := api.db.BeginRo(ctx) + if err != nil { + return nil, err + } + defer tx.Rollback() + n, h, _, err := rpchelper.GetBlockNumber(blockNrOrHash, tx, api.filters) + if err != nil { + return nil, err + } + header, err := api._blockReader.Header(context.Background(), tx, h, n) + if err != nil { + return nil, err + } + if header == nil { + return nil, fmt.Errorf("header not found") + } + return rlp.EncodeToBytes(header) +} + +func (api *PrivateDebugAPIImpl) GetRawBlock(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (hexutility.Bytes, error) { + tx, err := api.db.BeginRo(ctx) + if err != nil { + return nil, err + } + defer tx.Rollback() + n, h, _, err := rpchelper.GetBlockNumber(blockNrOrHash, tx, api.filters) + if err != nil { + return nil, err + } + block, err := api.blockWithSenders(tx, h, n) + if err != nil { + return nil, err + } + if block == nil { + return nil, fmt.Errorf("block not found") + } + return rlp.EncodeToBytes(block) } diff --git a/cmd/rpcdaemon/commands/engine_api.go b/cmd/rpcdaemon/commands/engine_api.go index e581bcb54a8..a4080ff700a 100644 --- a/cmd/rpcdaemon/commands/engine_api.go +++ b/cmd/rpcdaemon/commands/engine_api.go @@ -3,6 +3,7 @@ package commands import ( "context" "encoding/binary" + "errors" "fmt" "math/big" @@ -10,6 +11,7 @@ import ( "github.com/ledgerwatch/log/v3" "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/gointerfaces" "github.com/ledgerwatch/erigon-lib/gointerfaces/remote" types2 "github.com/ledgerwatch/erigon-lib/gointerfaces/types" @@ -29,16 +31,16 @@ type ExecutionPayload struct { FeeRecipient common.Address `json:"feeRecipient" gencodec:"required"` StateRoot common.Hash `json:"stateRoot" gencodec:"required"` ReceiptsRoot common.Hash `json:"receiptsRoot" gencodec:"required"` - LogsBloom hexutil.Bytes `json:"logsBloom" gencodec:"required"` + LogsBloom hexutility.Bytes `json:"logsBloom" gencodec:"required"` PrevRandao common.Hash `json:"prevRandao" gencodec:"required"` BlockNumber hexutil.Uint64 `json:"blockNumber" gencodec:"required"` GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"` GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` Timestamp hexutil.Uint64 `json:"timestamp" gencodec:"required"` - ExtraData hexutil.Bytes `json:"extraData" gencodec:"required"` + ExtraData hexutility.Bytes `json:"extraData" gencodec:"required"` BaseFeePerGas *hexutil.Big `json:"baseFeePerGas" gencodec:"required"` BlockHash common.Hash `json:"blockHash" gencodec:"required"` - Transactions []hexutil.Bytes `json:"transactions" gencodec:"required"` + Transactions []hexutility.Bytes `json:"transactions" gencodec:"required"` Withdrawals []*types.Withdrawal `json:"withdrawals"` } @@ -48,6 +50,13 @@ type GetPayloadV2Response struct { BlockValue *hexutil.Big `json:"blockValue" gencodec:"required"` } +// GetPayloadV3Response represents the response of the getPayloadV3 method +type GetPayloadV3Response struct { + ExecutionPayload *ExecutionPayload `json:"executionPayload" gencodec:"required"` + BlockValue *hexutil.Big `json:"blockValue" gencodec:"required"` + BlobsBundle *BlobsBundleV1 `json:"blobsBundle" gencodec:"required"` +} + // PayloadAttributes represent the attributes required to start assembling a payload type ForkChoiceState struct { HeadHash common.Hash `json:"headBlockHash" gencodec:"required"` @@ -70,8 +79,14 @@ type TransitionConfiguration struct { TerminalBlockNumber *hexutil.Big `json:"terminalBlockNumber" gencodec:"required"` } +// BlobsBundleV1 holds the blobs of an execution payload +type BlobsBundleV1 struct { + KZGs []types.KZGCommitment `json:"kzgs" gencodec:"required"` + Blobs []types.Blob `json:"blobs" gencodec:"required"` +} + type ExecutionPayloadBodyV1 struct { - Transactions []hexutil.Bytes `json:"transactions" gencodec:"required"` + Transactions []hexutility.Bytes `json:"transactions" gencodec:"required"` Withdrawals []*types.Withdrawal `json:"withdrawals" gencodec:"required"` } @@ -81,8 +96,9 @@ type EngineAPI interface { NewPayloadV2(context.Context, *ExecutionPayload) (map[string]interface{}, error) ForkchoiceUpdatedV1(ctx context.Context, forkChoiceState *ForkChoiceState, payloadAttributes *PayloadAttributes) (map[string]interface{}, error) ForkchoiceUpdatedV2(ctx context.Context, forkChoiceState *ForkChoiceState, payloadAttributes *PayloadAttributes) (map[string]interface{}, error) - GetPayloadV1(ctx context.Context, payloadID hexutil.Bytes) (*ExecutionPayload, error) - GetPayloadV2(ctx context.Context, payloadID hexutil.Bytes) (*GetPayloadV2Response, error) + GetPayloadV1(ctx context.Context, payloadID hexutility.Bytes) (*ExecutionPayload, error) + GetPayloadV2(ctx context.Context, payloadID hexutility.Bytes) (*GetPayloadV2Response, error) + GetPayloadV3(ctx context.Context, payloadID hexutility.Bytes) (*GetPayloadV3Response, error) ExchangeTransitionConfigurationV1(ctx context.Context, transitionConfiguration *TransitionConfiguration) (*TransitionConfiguration, error) GetPayloadBodiesByHashV1(ctx context.Context, hashes []common.Hash) ([]*ExecutionPayloadBodyV1, error) GetPayloadBodiesByRangeV1(ctx context.Context, start, count hexutil.Uint64) ([]*ExecutionPayloadBodyV1, error) @@ -139,7 +155,7 @@ func addPayloadId(json map[string]interface{}, payloadId uint64) { if payloadId != 0 { encodedPayloadId := make([]byte, 8) binary.BigEndian.PutUint64(encodedPayloadId, payloadId) - json["payloadId"] = hexutil.Bytes(encodedPayloadId) + json["payloadId"] = hexutility.Bytes(encodedPayloadId) } } @@ -151,13 +167,33 @@ func (e *EngineImpl) ForkchoiceUpdatedV2(ctx context.Context, forkChoiceState *F return e.forkchoiceUpdated(2, ctx, forkChoiceState, payloadAttributes) } +// Converts slice of pointers to slice of structs +func withdrawalValues(ptrs []*types.Withdrawal) []types.Withdrawal { + if ptrs == nil { + return nil + } + vals := make([]types.Withdrawal, 0, len(ptrs)) + for _, w := range ptrs { + vals = append(vals, *w) + } + return vals +} + +var errEmbedeedConsensus = errors.New("engine api should not be used, restart without --internalcl") + func (e *EngineImpl) forkchoiceUpdated(version uint32, ctx context.Context, forkChoiceState *ForkChoiceState, payloadAttributes *PayloadAttributes) (map[string]interface{}, error) { if e.internalCL { - log.Error("EXTERNAL CONSENSUS LAYER IS NOT ENABLED, PLEASE RESTART WITH FLAG --externalcl") - return nil, fmt.Errorf("engine api should not be used, restart with --externalcl") + return nil, errEmbedeedConsensus + } + if payloadAttributes == nil { + log.Debug("Received ForkchoiceUpdated", "version", version, + "head", forkChoiceState.HeadHash, "safe", forkChoiceState.SafeBlockHash, "finalized", forkChoiceState.FinalizedBlockHash) + } else { + log.Info("Received ForkchoiceUpdated [build]", "version", version, + "head", forkChoiceState.HeadHash, "safe", forkChoiceState.SafeBlockHash, "finalized", forkChoiceState.FinalizedBlockHash, + "timestamp", payloadAttributes.Timestamp, "prevRandao", payloadAttributes.PrevRandao, "suggestedFeeRecipient", payloadAttributes.SuggestedFeeRecipient, + "withdrawals", withdrawalValues(payloadAttributes.Withdrawals)) } - log.Debug("Received ForkchoiceUpdated", "version", version, "head", forkChoiceState.HeadHash, "safe", forkChoiceState.HeadHash, "finalized", forkChoiceState.FinalizedBlockHash, - "build", payloadAttributes != nil) var attributes *remote.EnginePayloadAttributes if payloadAttributes != nil { @@ -211,8 +247,7 @@ func (e *EngineImpl) NewPayloadV2(ctx context.Context, payload *ExecutionPayload func (e *EngineImpl) newPayload(version uint32, ctx context.Context, payload *ExecutionPayload) (map[string]interface{}, error) { if e.internalCL { - log.Error("EXTERNAL CONSENSUS LAYER IS NOT ENABLED, PLEASE RESTART WITH FLAG --externalcl") - return nil, fmt.Errorf("engine api should not be used, restart with --externalcl") + return nil, errEmbedeedConsensus } log.Debug("Received NewPayload", "version", version, "height", uint64(payload.BlockNumber), "hash", payload.BlockHash) @@ -222,7 +257,7 @@ func (e *EngineImpl) newPayload(version uint32, ctx context.Context, payload *Ex return nil, fmt.Errorf("invalid request") } - // Convert slice of hexutil.Bytes to a slice of slice of bytes + // Convert slice of hexutility.Bytes to a slice of slice of bytes transactions := make([][]byte, len(payload.Transactions)) for i, transaction := range payload.Transactions { transactions[i] = transaction @@ -261,8 +296,8 @@ func convertPayloadFromRpc(payload *types2.ExecutionPayload) *ExecutionPayload { var bloom types.Bloom = gointerfaces.ConvertH2048ToBloom(payload.LogsBloom) baseFee := gointerfaces.ConvertH256ToUint256Int(payload.BaseFeePerGas).ToBig() - // Convert slice of hexutil.Bytes to a slice of slice of bytes - transactions := make([]hexutil.Bytes, len(payload.Transactions)) + // Convert slice of hexutility.Bytes to a slice of slice of bytes + transactions := make([]hexutility.Bytes, len(payload.Transactions)) for i, transaction := range payload.Transactions { transactions[i] = transaction } @@ -290,10 +325,9 @@ func convertPayloadFromRpc(payload *types2.ExecutionPayload) *ExecutionPayload { return res } -func (e *EngineImpl) GetPayloadV1(ctx context.Context, payloadID hexutil.Bytes) (*ExecutionPayload, error) { +func (e *EngineImpl) GetPayloadV1(ctx context.Context, payloadID hexutility.Bytes) (*ExecutionPayload, error) { if e.internalCL { - log.Error("EXTERNAL CONSENSUS LAYER IS NOT ENABLED, PLEASE RESTART WITH FLAG --externalcl") - return nil, fmt.Errorf("engine api should not be used, restart with --externalcl") + return nil, errEmbedeedConsensus } decodedPayloadId := binary.BigEndian.Uint64(payloadID) @@ -307,10 +341,9 @@ func (e *EngineImpl) GetPayloadV1(ctx context.Context, payloadID hexutil.Bytes) return convertPayloadFromRpc(response.ExecutionPayload), nil } -func (e *EngineImpl) GetPayloadV2(ctx context.Context, payloadID hexutil.Bytes) (*GetPayloadV2Response, error) { +func (e *EngineImpl) GetPayloadV2(ctx context.Context, payloadID hexutility.Bytes) (*GetPayloadV2Response, error) { if e.internalCL { - log.Error("EXTERNAL CONSENSUS LAYER IS NOT ENABLED, PLEASE RESTART WITH FLAG --externalcl") - return nil, fmt.Errorf("engine api should not be used, restart with --externalcl") + return nil, errEmbedeedConsensus } decodedPayloadId := binary.BigEndian.Uint64(payloadID) @@ -329,13 +362,56 @@ func (e *EngineImpl) GetPayloadV2(ctx context.Context, payloadID hexutil.Bytes) }, nil } +func (e *EngineImpl) GetPayloadV3(ctx context.Context, payloadID hexutility.Bytes) (*GetPayloadV3Response, error) { + if e.internalCL { // TODO: find out what is the way around it + log.Error("EXTERNAL CONSENSUS LAYER IS NOT ENABLED, PLEASE RESTART WITH FLAG --externalcl") + return nil, fmt.Errorf("engine api should not be used, restart with --externalcl") + } + + decodedPayloadId := binary.BigEndian.Uint64(payloadID) + log.Info("Received GetPayloadV3", "payloadId", decodedPayloadId) + + response, err := e.api.EngineGetPayload(ctx, decodedPayloadId) + if err != nil { + return nil, err + } + + epl := convertPayloadFromRpc(response.ExecutionPayload) + blockValue := gointerfaces.ConvertH256ToUint256Int(response.BlockValue).ToBig() + + ep, err := e.api.EngineGetBlobsBundleV1(ctx, decodedPayloadId) + if err != nil { + return nil, err + } + kzgs := ep.GetKzgs() + blobs := ep.GetBlobs() + if len(kzgs) != len(blobs) { + return nil, fmt.Errorf("should have same number of kzgs and blobs, got %v vs %v", len(kzgs), len(blobs)) + } + replyKzgs := make([]types.KZGCommitment, len(kzgs)) + replyBlobs := make([]types.Blob, len(blobs)) + for i := range kzgs { + copy(replyKzgs[i][:], kzgs[i]) + copy(replyBlobs[i][:], blobs[i]) + } + bb := &BlobsBundleV1{ + KZGs: replyKzgs, + Blobs: replyBlobs, + } + + return &GetPayloadV3Response{ + epl, + (*hexutil.Big)(blockValue), + bb, + }, nil +} + // Receives consensus layer's transition configuration and checks if the execution layer has the correct configuration. // Can also be used to ping the execution layer (heartbeats). // See https://github.com/ethereum/execution-apis/blob/v1.0.0-beta.1/src/engine/specification.md#engine_exchangetransitionconfigurationv1 func (e *EngineImpl) ExchangeTransitionConfigurationV1(ctx context.Context, beaconConfig *TransitionConfiguration) (*TransitionConfiguration, error) { if e.internalCL { - log.Error("EXTERNAL CONSENSUS LAYER IS NOT ENABLED, PLEASE RESTART WITH FLAG --externalcl") - return nil, fmt.Errorf("engine api should not be used, restart with --externalcl") + return nil, errEmbedeedConsensus } tx, err := e.db.BeginRo(ctx) @@ -448,7 +524,7 @@ func convertExecutionPayloadV1(response *remote.EngineGetPayloadBodiesV1Response result[idx] = nil } else { pl := &ExecutionPayloadBodyV1{ - Transactions: make([]hexutil.Bytes, len(body.Transactions)), + Transactions: make([]hexutility.Bytes, len(body.Transactions)), Withdrawals: privateapi.ConvertWithdrawalsFromRpc(body.Withdrawals), } for i := range body.Transactions { diff --git a/cmd/rpcdaemon/commands/eth_accounts.go b/cmd/rpcdaemon/commands/eth_accounts.go index 8594ad60066..40feb36b6da 100644 --- a/cmd/rpcdaemon/commands/eth_accounts.go +++ b/cmd/rpcdaemon/commands/eth_accounts.go @@ -75,7 +75,7 @@ func (api *APIImpl) GetTransactionCount(ctx context.Context, address libcommon.A } // GetCode implements eth_getCode. Returns the byte code at a given address (if it's a smart contract). -func (api *APIImpl) GetCode(ctx context.Context, address libcommon.Address, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) { +func (api *APIImpl) GetCode(ctx context.Context, address libcommon.Address, blockNrOrHash rpc.BlockNumberOrHash) (hexutility.Bytes, error) { tx, err1 := api.db.BeginRo(ctx) if err1 != nil { return nil, fmt.Errorf("getCode cannot open tx: %w", err1) @@ -92,11 +92,11 @@ func (api *APIImpl) GetCode(ctx context.Context, address libcommon.Address, bloc acc, err := reader.ReadAccountData(address) if acc == nil || err != nil { - return hexutil.Bytes(""), nil + return hexutility.Bytes(""), nil } res, _ := reader.ReadAccountCode(address, acc.Incarnation, acc.CodeHash) if res == nil { - return hexutil.Bytes(""), nil + return hexutility.Bytes(""), nil } return res, nil } diff --git a/cmd/rpcdaemon/commands/eth_api.go b/cmd/rpcdaemon/commands/eth_api.go index 97edc621420..ce895102351 100644 --- a/cmd/rpcdaemon/commands/eth_api.go +++ b/cmd/rpcdaemon/commands/eth_api.go @@ -6,14 +6,17 @@ import ( "fmt" "math/big" "sync" + "sync/atomic" "time" lru "github.com/hashicorp/golang-lru/v2" "github.com/holiman/uint256" - "go.uber.org/atomic" + "github.com/ledgerwatch/log/v3" "github.com/ledgerwatch/erigon-lib/chain" "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/datadir" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/gointerfaces/txpool" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv/kvcache" @@ -27,13 +30,13 @@ import ( "github.com/ledgerwatch/erigon/consensus/misc" "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/core/types/accounts" ethFilters "github.com/ledgerwatch/erigon/eth/filters" "github.com/ledgerwatch/erigon/ethdb/prune" "github.com/ledgerwatch/erigon/rpc" ethapi2 "github.com/ledgerwatch/erigon/turbo/adapter/ethapi" "github.com/ledgerwatch/erigon/turbo/rpchelper" "github.com/ledgerwatch/erigon/turbo/services" - "github.com/ledgerwatch/log/v3" ) // EthAPI is a collection of functions that are exposed in the @@ -48,9 +51,9 @@ type EthAPI interface { GetTransactionByHash(ctx context.Context, hash common.Hash) (*RPCTransaction, error) GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, txIndex hexutil.Uint64) (*RPCTransaction, error) GetTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, txIndex hexutil.Uint) (*RPCTransaction, error) - GetRawTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) (hexutil.Bytes, error) - GetRawTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) (hexutil.Bytes, error) - GetRawTransactionByHash(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) + GetRawTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) (hexutility.Bytes, error) + GetRawTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) (hexutility.Bytes, error) + GetRawTransactionByHash(ctx context.Context, hash common.Hash) (hexutility.Bytes, error) // Receipt related (see ./eth_receipts.go) GetTransactionReceipt(ctx context.Context, hash common.Hash) (map[string]interface{}, error) @@ -76,7 +79,7 @@ type EthAPI interface { GetBalance(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Big, error) GetTransactionCount(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (*hexutil.Uint64, error) GetStorageAt(ctx context.Context, address common.Address, index string, blockNrOrHash rpc.BlockNumberOrHash) (string, error) - GetCode(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (hexutil.Bytes, error) + GetCode(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (hexutility.Bytes, error) // System related (see ./eth_system.go) BlockNumber(ctx context.Context) (hexutil.Uint64, error) @@ -86,13 +89,13 @@ type EthAPI interface { GasPrice(_ context.Context) (*hexutil.Big, error) // Sending related (see ./eth_call.go) - Call(ctx context.Context, args ethapi2.CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *ethapi2.StateOverrides) (hexutil.Bytes, error) + Call(ctx context.Context, args ethapi2.CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *ethapi2.StateOverrides) (hexutility.Bytes, error) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs, blockNrOrHash *rpc.BlockNumberOrHash) (hexutil.Uint64, error) - SendRawTransaction(ctx context.Context, encodedTx hexutil.Bytes) (common.Hash, error) + SendRawTransaction(ctx context.Context, encodedTx hexutility.Bytes) (common.Hash, error) SendTransaction(_ context.Context, txObject interface{}) (common.Hash, error) - Sign(ctx context.Context, _ common.Address, _ hexutil.Bytes) (hexutil.Bytes, error) + Sign(ctx context.Context, _ common.Address, _ hexutility.Bytes) (hexutility.Bytes, error) SignTransaction(_ context.Context, txObject interface{}) (common.Hash, error) - GetProof(ctx context.Context, address common.Address, storageKeys []string, blockNr rpc.BlockNumber) (*interface{}, error) + GetProof(ctx context.Context, address common.Address, storageKeys []common.Hash, blockNr rpc.BlockNumberOrHash) (*accounts.AccProofResult, error) CreateAccessList(ctx context.Context, args ethapi2.CallArgs, blockNrOrHash *rpc.BlockNumberOrHash, optimizeGas *bool) (*accessListResult, error) // Mining related (see ./eth_mining.go) @@ -119,9 +122,10 @@ type BaseAPI struct { _engine consensus.EngineReader evmCallTimeout time.Duration + dirs datadir.Dirs } -func NewBaseApi(f *rpchelper.Filters, stateCache kvcache.Cache, blockReader services.FullBlockReader, agg *libstate.AggregatorV3, singleNodeMode bool, evmCallTimeout time.Duration, engine consensus.EngineReader) *BaseAPI { +func NewBaseApi(f *rpchelper.Filters, stateCache kvcache.Cache, blockReader services.FullBlockReader, agg *libstate.AggregatorV3, singleNodeMode bool, evmCallTimeout time.Duration, engine consensus.EngineReader, dirs datadir.Dirs) *BaseAPI { blocksLRUSize := 128 // ~32Mb if !singleNodeMode { blocksLRUSize = 512 @@ -131,7 +135,7 @@ func NewBaseApi(f *rpchelper.Filters, stateCache kvcache.Cache, blockReader serv panic(err) } - return &BaseAPI{filters: f, stateCache: stateCache, blocksLRU: blocksLRU, _blockReader: blockReader, _txnReader: blockReader, _agg: agg, evmCallTimeout: evmCallTimeout, _engine: engine} + return &BaseAPI{filters: f, stateCache: stateCache, blocksLRU: blocksLRU, _blockReader: blockReader, _txnReader: blockReader, _agg: agg, evmCallTimeout: evmCallTimeout, _engine: engine, dirs: dirs} } func (api *BaseAPI) chainConfig(tx kv.Tx) (*chain.Config, error) { @@ -347,7 +351,7 @@ type RPCTransaction struct { Tip *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"` FeeCap *hexutil.Big `json:"maxFeePerGas,omitempty"` Hash common.Hash `json:"hash"` - Input hexutil.Bytes `json:"input"` + Input hexutility.Bytes `json:"input"` Nonce hexutil.Uint64 `json:"nonce"` To *common.Address `json:"to"` TransactionIndex *hexutil.Uint64 `json:"transactionIndex"` @@ -372,7 +376,7 @@ func newRPCTransaction(tx types.Transaction, blockHash common.Hash, blockNumber Type: hexutil.Uint64(tx.Type()), Gas: hexutil.Uint64(tx.GetGas()), Hash: tx.Hash(), - Input: hexutil.Bytes(tx.GetData()), + Input: hexutility.Bytes(tx.GetData()), Nonce: hexutil.Uint64(tx.GetNonce()), To: tx.GetTo(), Value: (*hexutil.Big)(tx.GetValue().ToBig()), @@ -434,7 +438,7 @@ func newRPCBorTransaction(opaqueTx types.Transaction, txHash common.Hash, blockH GasPrice: (*hexutil.Big)(tx.GasPrice.ToBig()), Gas: hexutil.Uint64(tx.GetGas()), Hash: txHash, - Input: hexutil.Bytes(tx.GetData()), + Input: hexutility.Bytes(tx.GetData()), Nonce: hexutil.Uint64(tx.GetNonce()), From: common.Address{}, To: tx.GetTo(), @@ -462,7 +466,7 @@ func newRPCPendingTransaction(tx types.Transaction, current *types.Header, confi } // newRPCRawTransactionFromBlockIndex returns the bytes of a transaction given a block and a transaction index. -func newRPCRawTransactionFromBlockIndex(b *types.Block, index uint64) (hexutil.Bytes, error) { +func newRPCRawTransactionFromBlockIndex(b *types.Block, index uint64) (hexutility.Bytes, error) { txs := b.Transactions() if index >= uint64(len(txs)) { return nil, nil diff --git a/cmd/rpcdaemon/commands/eth_call.go b/cmd/rpcdaemon/commands/eth_call.go index 2e295fc88ac..f9ab76249b4 100644 --- a/cmd/rpcdaemon/commands/eth_call.go +++ b/cmd/rpcdaemon/commands/eth_call.go @@ -7,32 +7,38 @@ import ( "math/big" "github.com/holiman/uint256" + "github.com/ledgerwatch/log/v3" + "google.golang.org/grpc" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/gointerfaces" txpool_proto "github.com/ledgerwatch/erigon-lib/gointerfaces/txpool" "github.com/ledgerwatch/erigon-lib/kv" + "github.com/ledgerwatch/erigon-lib/kv/memdb" types2 "github.com/ledgerwatch/erigon-lib/types" - "github.com/ledgerwatch/log/v3" - "google.golang.org/grpc" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/core/state" "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/core/types/accounts" "github.com/ledgerwatch/erigon/core/vm" "github.com/ledgerwatch/erigon/crypto" + "github.com/ledgerwatch/erigon/eth/stagedsync" "github.com/ledgerwatch/erigon/eth/tracers/logger" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/rpc" ethapi2 "github.com/ledgerwatch/erigon/turbo/adapter/ethapi" "github.com/ledgerwatch/erigon/turbo/rpchelper" "github.com/ledgerwatch/erigon/turbo/transactions" + "github.com/ledgerwatch/erigon/turbo/trie" ) var latestNumOrHash = rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) // Call implements eth_call. Executes a new message call immediately without creating a transaction on the block chain. -func (api *APIImpl) Call(ctx context.Context, args ethapi2.CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *ethapi2.StateOverrides) (hexutil.Bytes, error) { +func (api *APIImpl) Call(ctx context.Context, args ethapi2.CallArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *ethapi2.StateOverrides) (hexutility.Bytes, error) { tx, err := api.db.BeginRo(ctx) if err != nil { return nil, err @@ -72,7 +78,7 @@ func (api *APIImpl) Call(ctx context.Context, args ethapi2.CallArgs, blockNrOrHa } if len(result.ReturnData) > api.ReturnDataLimit { - return nil, fmt.Errorf("call retuned result on length %d exceeding limit %d", len(result.ReturnData), api.ReturnDataLimit) + return nil, fmt.Errorf("call returned result on length %d exceeding --rpc.returndata.limit %d", len(result.ReturnData), api.ReturnDataLimit) } // If the result contains a revert reason, try to unpack and return it. @@ -122,9 +128,9 @@ func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs // Binary search the gas requirement, as it may be higher than the amount used var ( - lo = params.TxGas - 1 - hi uint64 - cap uint64 + lo = params.TxGas - 1 + hi uint64 + gasCap uint64 ) // Use zero address if sender unspecified. if args.From == nil { @@ -212,7 +218,7 @@ func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs log.Warn("Caller gas above allowance, capping", "requested", hi, "cap", api.GasCap) hi = api.GasCap } - cap = hi + gasCap = hi chainConfig, err := api.chainConfig(dbtx) if err != nil { @@ -281,7 +287,7 @@ func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs } // Reject the transaction as invalid if it still fails at the highest allowance - if hi == cap { + if hi == gasCap { failed, result, err := executable(hi) if err != nil { return 0, err @@ -294,16 +300,106 @@ func (api *APIImpl) EstimateGas(ctx context.Context, argsOrNil *ethapi2.CallArgs return 0, result.Err } // Otherwise, the specified gas cap is too low - return 0, fmt.Errorf("gas required exceeds allowance (%d)", cap) + return 0, fmt.Errorf("gas required exceeds allowance (%d)", gasCap) } } return hexutil.Uint64(hi), nil } -// GetProof not implemented -func (api *APIImpl) GetProof(ctx context.Context, address libcommon.Address, storageKeys []string, blockNr rpc.BlockNumber) (*interface{}, error) { - var stub interface{} - return &stub, fmt.Errorf(NotImplemented, "eth_getProof") +// maxGetProofRewindBlockCount limits the number of blocks into the past that +// GetProof will allow computing proofs. Because we must rewind the hash state +// and re-compute the state trie, the further back in time the request, the more +// computationally intensive the operation becomes. The staged sync code +// assumes that if more than 100_000 blocks are skipped, that the entire trie +// should be re-computed. Re-computing the entire trie will currently take ~15 +// minutes on mainnet. The current limit has been chosen arbitrarily as +// 'useful' without likely being overly computationally intense. This parameter +// could possibly be made configurable in the future if needed. +var maxGetProofRewindBlockCount uint64 = 1_000 + +// GetProof is partially implemented; no Storage proofs, and proofs must be for +// blocks within maxGetProofRewindBlockCount blocks of the head. +func (api *APIImpl) GetProof(ctx context.Context, address libcommon.Address, storageKeys []libcommon.Hash, blockNrOrHash rpc.BlockNumberOrHash) (*accounts.AccProofResult, error) { + + tx, err := api.db.BeginRo(ctx) + if err != nil { + return nil, err + } + defer tx.Rollback() + if api.historyV3(tx) { + return nil, fmt.Errorf("not supported by Erigon3") + } + + blockNr, _, _, err := rpchelper.GetBlockNumber(blockNrOrHash, tx, api.filters) + if err != nil { + return nil, err + } + + header, err := api._blockReader.HeaderByNumber(ctx, tx, blockNr) + if err != nil { + return nil, err + } + + latestBlock, err := rpchelper.GetLatestBlockNumber(tx) + if err != nil { + return nil, err + } + + if latestBlock < blockNr { + // shouldn't happen, but check anyway + return nil, fmt.Errorf("block number is in the future latest=%d requested=%d", latestBlock, blockNr) + } + + rl := trie.NewRetainList(0) + var loader *trie.FlatDBTrieLoader + if blockNr < latestBlock { + if latestBlock-blockNr > maxGetProofRewindBlockCount { + return nil, fmt.Errorf("requested block is too old, block must be within %d blocks of the head block number (currently %d)", maxGetProofRewindBlockCount, latestBlock) + } + batch := memdb.NewMemoryBatch(tx, api.dirs.Tmp) + defer batch.Rollback() + + unwindState := &stagedsync.UnwindState{UnwindPoint: blockNr} + stageState := &stagedsync.StageState{BlockNumber: latestBlock} + + hashStageCfg := stagedsync.StageHashStateCfg(nil, api.dirs, api.historyV3(batch), api._agg) + if err := stagedsync.UnwindHashStateStage(unwindState, stageState, batch, hashStageCfg, ctx); err != nil { + return nil, err + } + + interHashStageCfg := stagedsync.StageTrieCfg(nil, false, false, false, api.dirs.Tmp, api._blockReader, nil, api.historyV3(batch), api._agg) + loader, err = stagedsync.UnwindIntermediateHashesForTrieLoader("eth_getProof", rl, unwindState, stageState, batch, interHashStageCfg, nil, nil, ctx.Done()) + if err != nil { + return nil, err + } + tx = batch + } else { + loader = trie.NewFlatDBTrieLoader("eth_getProof", rl, nil, nil, false) + } + + reader, err := rpchelper.CreateStateReader(ctx, tx, blockNrOrHash, 0, api.filters, api.stateCache, api.historyV3(tx), "") + if err != nil { + return nil, err + } + a, err := reader.ReadAccountData(address) + if err != nil { + return nil, err + } + pr, err := trie.NewProofRetainer(address, a, storageKeys, rl) + if err != nil { + return nil, err + } + + loader.SetProofRetainer(pr) + root, err := loader.CalcTrieRoot(tx, nil) + if err != nil { + return nil, err + } + + if root != header.Root { + return nil, fmt.Errorf("mismatch in expected state root computed %v vs %v indicates bug in proof implementation", root, header.Root) + } + return pr.ProofResult() } func (api *APIImpl) tryBlockFromLru(hash libcommon.Hash) *types.Block { diff --git a/cmd/rpcdaemon/commands/eth_callMany_test.go b/cmd/rpcdaemon/commands/eth_callMany_test.go index b86b04cac1a..4dbeb9488a1 100644 --- a/cmd/rpcdaemon/commands/eth_callMany_test.go +++ b/cmd/rpcdaemon/commands/eth_callMany_test.go @@ -8,12 +8,15 @@ import ( "strconv" "testing" + "github.com/ledgerwatch/erigon-lib/common/datadir" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/kv/kvcache" + "github.com/ledgerwatch/erigon/accounts/abi/bind" "github.com/ledgerwatch/erigon/accounts/abi/bind/backends" "github.com/ledgerwatch/erigon/cmd/rpcdaemon/commands/contracts" "github.com/ledgerwatch/erigon/common/hexutil" - "github.com/ledgerwatch/erigon/core" + "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/rpc" @@ -37,9 +40,9 @@ func TestCallMany(t *testing.T) { address = crypto.PubkeyToAddress(key.PublicKey) address1 = crypto.PubkeyToAddress(key1.PublicKey) address2 = crypto.PubkeyToAddress(key2.PublicKey) - gspec = &core.Genesis{ + gspec = &types.Genesis{ Config: params.TestChainConfig, - Alloc: core.GenesisAlloc{ + Alloc: types.GenesisAlloc{ address: {Balance: big.NewInt(9000000000000000000)}, address1: {Balance: big.NewInt(200000000000000000)}, address2: {Balance: big.NewInt(300000000000000000)}, @@ -55,11 +58,11 @@ func TestCallMany(t *testing.T) { ) hexBytes, _ := hex.DecodeString(addr2BalanceCheck) - balanceCallAddr2 := hexutil.Bytes(hexBytes) + balanceCallAddr2 := hexutility.Bytes(hexBytes) hexBytes, _ = hex.DecodeString(addr1BalanceCheck) - balanceCallAddr1 := hexutil.Bytes(hexBytes) + balanceCallAddr1 := hexutility.Bytes(hexBytes) hexBytes, _ = hex.DecodeString(transferAddr2) - transferCallData := hexutil.Bytes(hexBytes) + transferCallData := hexutility.Bytes(hexBytes) //submit 3 Transactions and commit the results transactOpts, _ := bind.NewKeyedTransactorWithChainID(key, chainID) @@ -79,7 +82,7 @@ func TestCallMany(t *testing.T) { db := contractBackend.DB() engine := contractBackend.Engine() - api := NewEthAPI(NewBaseApi(nil, stateCache, contractBackend.BlockReader(), contractBackend.Agg(), false, rpccfg.DefaultEvmCallTimeout, engine), db, nil, nil, nil, 5000000, 100_000) + api := NewEthAPI(NewBaseApi(nil, stateCache, contractBackend.BlockReader(), contractBackend.Agg(), false, rpccfg.DefaultEvmCallTimeout, engine, datadir.New(t.TempDir())), db, nil, nil, nil, 5000000, 100_000) callArgAddr1 := ethapi.CallArgs{From: &address, To: &tokenAddr, Nonce: &nonce, MaxPriorityFeePerGas: (*hexutil.Big)(big.NewInt(1e9)), diff --git a/cmd/rpcdaemon/commands/eth_call_test.go b/cmd/rpcdaemon/commands/eth_call_test.go index e7dcadc5a12..bd7bd99becb 100644 --- a/cmd/rpcdaemon/commands/eth_call_test.go +++ b/cmd/rpcdaemon/commands/eth_call_test.go @@ -7,14 +7,13 @@ import ( "testing" "time" - libcommon "github.com/ledgerwatch/erigon-lib/common" - - "github.com/ledgerwatch/erigon/rpc/rpccfg" - "github.com/ledgerwatch/erigon/turbo/adapter/ethapi" - "github.com/holiman/uint256" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" + "github.com/ledgerwatch/erigon-lib/common/length" "github.com/ledgerwatch/erigon-lib/gointerfaces/txpool" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv/kvcache" @@ -26,12 +25,17 @@ import ( "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/state" "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/core/types/accounts" "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/params" + "github.com/ledgerwatch/erigon/rlp" "github.com/ledgerwatch/erigon/rpc" + "github.com/ledgerwatch/erigon/rpc/rpccfg" + "github.com/ledgerwatch/erigon/turbo/adapter/ethapi" "github.com/ledgerwatch/erigon/turbo/rpchelper" "github.com/ledgerwatch/erigon/turbo/snapshotsync" "github.com/ledgerwatch/erigon/turbo/stages" + "github.com/ledgerwatch/erigon/turbo/trie" ) func TestEstimateGas(t *testing.T) { @@ -42,7 +46,7 @@ func TestEstimateGas(t *testing.T) { ctx, conn := rpcdaemontest.CreateTestGrpcConn(t, stages.Mock(t)) mining := txpool.NewMiningClient(conn) ff := rpchelper.New(ctx, nil, nil, mining, func() {}) - api := NewEthAPI(NewBaseApi(ff, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine), m.DB, nil, nil, nil, 5000000, 100_000) + api := NewEthAPI(NewBaseApi(ff, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine, m.Dirs), m.DB, nil, nil, nil, 5000000, 100_000) var from = libcommon.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7") var to = libcommon.HexToAddress("0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e") if _, err := api.EstimateGas(context.Background(), ðapi.CallArgs{ @@ -58,7 +62,7 @@ func TestEthCallNonCanonical(t *testing.T) { agg := m.HistoryV3Components() br := snapshotsync.NewBlockReaderWithSnapshots(m.BlockSnapshots, m.TransactionsV3) stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine), m.DB, nil, nil, nil, 5000000, 100_000) + api := NewEthAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine, m.Dirs), m.DB, nil, nil, nil, 5000000, 100_000) var from = libcommon.HexToAddress("0x71562b71999873db5b286df957af199ec94617f7") var to = libcommon.HexToAddress("0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e") if _, err := api.Call(context.Background(), ethapi.CallArgs{ @@ -83,10 +87,10 @@ func TestEthCallToPrunedBlock(t *testing.T) { agg := m.HistoryV3Components() stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewEthAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine), m.DB, nil, nil, nil, 5000000, 100_000) + api := NewEthAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine, m.Dirs), m.DB, nil, nil, nil, 5000000, 100_000) callData := hexutil.MustDecode("0x2e64cec1") - callDataBytes := hexutil.Bytes(callData) + callDataBytes := hexutility.Bytes(callData) if _, err := api.Call(context.Background(), ethapi.CallArgs{ From: &bankAddress, @@ -97,6 +101,275 @@ func TestEthCallToPrunedBlock(t *testing.T) { } } +type valueNode []byte +type hashNode libcommon.Hash + +type shortNode struct { + Key trie.Keybytes + Val any +} + +type fullNode struct { + Children [17]any +} + +func decodeRef(t *testing.T, buf []byte) (any, []byte) { + t.Helper() + kind, val, rest, err := rlp.Split(buf) + require.NoError(t, err) + switch { + case kind == rlp.List: + require.Less(t, len(buf)-len(rest), length.Hash, "embedded nodes must be less than hash size") + return decodeNode(t, buf), rest + case kind == rlp.String && len(val) == 0: + return nil, rest + case kind == rlp.String && len(val) == 32: + return hashNode(libcommon.CastToHash(val)), rest + default: + t.Fatalf("invalid RLP string size %d (want 0 through 32)", len(val)) + return nil, rest + } +} + +func decodeFull(t *testing.T, elems []byte) fullNode { + t.Helper() + n := fullNode{} + for i := 0; i < 16; i++ { + n.Children[i], elems = decodeRef(t, elems) + } + val, _, err := rlp.SplitString(elems) + require.NoError(t, err) + if len(val) > 0 { + n.Children[16] = valueNode(val) + } + return n +} + +func decodeShort(t *testing.T, elems []byte) shortNode { + t.Helper() + kbuf, rest, err := rlp.SplitString(elems) + require.NoError(t, err) + kb := trie.CompactToKeybytes(kbuf) + if kb.Terminating { + val, _, err := rlp.SplitString(rest) + require.NoError(t, err) + return shortNode{ + Key: kb, + Val: valueNode(val), + } + } + + val, _ := decodeRef(t, rest) + return shortNode{ + Key: kb, + Val: val, + } +} + +func decodeNode(t *testing.T, encoded []byte) any { + t.Helper() + require.NotEmpty(t, encoded) + elems, _, err := rlp.SplitList(encoded) + require.NoError(t, err) + switch c, _ := rlp.CountValues(elems); c { + case 2: + return decodeShort(t, elems) + case 17: + return decodeFull(t, elems) + default: + t.Fatalf("invalid number of list elements: %v", c) + return nil // unreachable + } +} + +type rawProofElement struct { + index int + value []byte +} + +// proofMap creates a map from hash to proof node +func proofMap(t *testing.T, proof []hexutility.Bytes) (map[libcommon.Hash]any, map[libcommon.Hash]rawProofElement) { + res := map[libcommon.Hash]any{} + raw := map[libcommon.Hash]rawProofElement{} + for i, proofB := range proof { + hash := crypto.Keccak256Hash(proofB) + res[hash] = decodeNode(t, proofB) + raw[hash] = rawProofElement{ + index: i, + value: proofB, + } + } + return res, raw +} + +func verifyProof(t *testing.T, root libcommon.Hash, key []byte, proofs map[libcommon.Hash]any, used map[libcommon.Hash]rawProofElement) []byte { + t.Helper() + nextIndex := 0 + key = (&trie.Keybytes{Data: key}).ToHex() + var node any = hashNode(root) + for { + switch nt := node.(type) { + case fullNode: + require.NotEmpty(t, key, "full nodes should not have values") + node, key = nt.Children[key[0]], key[1:] + case shortNode: + shortHex := nt.Key.ToHex()[:nt.Key.Nibbles()] // There is a trailing 0 on odd otherwise + require.LessOrEqual(t, len(shortHex), len(key)) + require.Equal(t, shortHex, key[:len(shortHex)]) + node, key = nt.Val, key[len(shortHex):] + case hashNode: + var ok bool + node, ok = proofs[libcommon.Hash(nt)] + require.True(t, ok, "missing hash %x", nt) + raw, ok := used[libcommon.Hash(nt)] + require.True(t, ok) + require.Equal(t, nextIndex, raw.index, "proof elements not in expected order") + nextIndex++ + delete(used, libcommon.Hash(nt)) + case valueNode: + require.Len(t, key, 0) + for hash, raw := range used { + require.Failf(t, "not all proof elements were used", "hash=%x index=%d value=%x decoded=%#v", hash, raw.index, raw.value, proofs[hash]) + } + return nt + default: + t.Fatalf("unexpected type: %T", node) + } + } +} + +func verifyAccountProof(t *testing.T, stateRoot libcommon.Hash, proof *accounts.AccProofResult) { + t.Helper() + accountKey := crypto.Keccak256(proof.Address[:]) + pm, used := proofMap(t, proof.AccountProof) + value := verifyProof(t, stateRoot, accountKey, pm, used) + + expected, err := rlp.EncodeToBytes([]any{ + uint64(proof.Nonce), + proof.Balance.ToInt().Bytes(), + proof.StorageHash, + proof.CodeHash, + }) + require.NoError(t, err) + + require.Equal(t, expected, value) +} + +func verifyStorageProof(t *testing.T, storageRoot libcommon.Hash, proof accounts.StorProofResult) { + t.Helper() + + storageKey := crypto.Keccak256(proof.Key[:]) + pm, used := proofMap(t, proof.Proof) + value := verifyProof(t, storageRoot, storageKey, pm, used) + + expected, err := rlp.EncodeToBytes(proof.Value.ToInt().Bytes()) + require.NoError(t, err) + + require.Equal(t, expected, value) +} + +func TestGetProof(t *testing.T) { + maxGetProofRewindBlockCount = 1 // Note, this is unsafe for parallel tests, but, this test is the only consumer for now + + m, bankAddr, contractAddr := chainWithDeployedContract(t) + br := snapshotsync.NewBlockReaderWithSnapshots(m.BlockSnapshots, m.TransactionsV3) + + if m.HistoryV3 { + t.Skip("not supported by Erigon3") + } + agg := m.HistoryV3Components() + + stateCache := kvcache.New(kvcache.DefaultCoherentConfig) + api := NewEthAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine, m.Dirs), m.DB, nil, nil, nil, 5000000, 100_000) + + key := func(b byte) libcommon.Hash { + result := libcommon.Hash{} + result[31] = b + return result + } + + tests := []struct { + name string + blockNum uint64 + addr libcommon.Address + storageKeys []libcommon.Hash + stateVal uint64 + expectedErr string + }{ + { + name: "currentBlockNoState", + addr: contractAddr, + blockNum: 3, + }, + { + name: "currentBlockEOA", + addr: bankAddr, + blockNum: 3, + }, + { + name: "currentBlockWithState", + addr: contractAddr, + blockNum: 3, + storageKeys: []libcommon.Hash{key(0), key(4), key(8), key(10)}, + stateVal: 2, + }, + { + name: "olderBlockWithState", + addr: contractAddr, + blockNum: 2, + storageKeys: []libcommon.Hash{key(1), key(5), key(9), key(13)}, + stateVal: 1, + }, + { + name: "tooOldBlock", + addr: contractAddr, + blockNum: 1, + expectedErr: "requested block is too old, block must be within 1 blocks of the head block number (currently 3)", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + proof, err := api.GetProof( + context.Background(), + tt.addr, + tt.storageKeys, + rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(tt.blockNum)), + ) + if tt.expectedErr != "" { + require.EqualError(t, err, tt.expectedErr) + require.Nil(t, proof) + return + } + require.NoError(t, err) + require.NotNil(t, proof) + + tx, err := m.DB.BeginRo(context.Background()) + assert.NoError(t, err) + defer tx.Rollback() + header, err := api.headerByRPCNumber(rpc.BlockNumber(tt.blockNum), tx) + require.NoError(t, err) + + require.Equal(t, tt.addr, proof.Address) + verifyAccountProof(t, header.Root, proof) + + require.Equal(t, len(tt.storageKeys), len(proof.StorageProof)) + for _, storageKey := range tt.storageKeys { + found := false + for _, storageProof := range proof.StorageProof { + if storageProof.Key != storageKey { + continue + } + found = true + require.Equal(t, uint256.NewInt(tt.stateVal).ToBig(), (*big.Int)(storageProof.Value)) + verifyStorageProof(t, proof.StorageHash, storageProof) + } + require.True(t, found, "did not find storage proof for key=%x", storageKey) + } + }) + } +} + func TestGetBlockByTimestampLatestTime(t *testing.T) { ctx := context.Background() m, _, _ := rpcdaemontest.CreateTestSentry(t) @@ -109,7 +382,7 @@ func TestGetBlockByTimestampLatestTime(t *testing.T) { defer tx.Rollback() stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewErigonAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine), m.DB, nil) + api := NewErigonAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine, m.Dirs), m.DB, nil) latestBlock := rawdb.ReadCurrentBlock(tx) response, err := ethapi.RPCMarshalBlockDeprecated(latestBlock, true, false) @@ -147,7 +420,7 @@ func TestGetBlockByTimestampOldestTime(t *testing.T) { defer tx.Rollback() stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewErigonAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine), m.DB, nil) + api := NewErigonAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine, m.Dirs), m.DB, nil) oldestBlock, err := rawdb.ReadBlockByNumber(tx, 0) if err != nil { @@ -189,7 +462,7 @@ func TestGetBlockByTimeHigherThanLatestBlock(t *testing.T) { defer tx.Rollback() stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewErigonAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine), m.DB, nil) + api := NewErigonAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine, m.Dirs), m.DB, nil) latestBlock := rawdb.ReadCurrentBlock(tx) @@ -228,7 +501,7 @@ func TestGetBlockByTimeMiddle(t *testing.T) { defer tx.Rollback() stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewErigonAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine), m.DB, nil) + api := NewErigonAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine, m.Dirs), m.DB, nil) currentHeader := rawdb.ReadCurrentHeader(tx) oldestHeader, err := api._blockReader.HeaderByNumber(ctx, tx, 0) @@ -262,7 +535,6 @@ func TestGetBlockByTimeMiddle(t *testing.T) { if err != nil { t.Errorf("couldn't retrieve block %v", err) } - if block["timestamp"] != response["timestamp"] || block["hash"] != response["hash"] { t.Errorf("Retrieved the wrong block.\nexpected block hash: %s expected timestamp: %d\nblock hash retrieved: %s timestamp retrieved: %d", response["hash"], response["timestamp"], block["hash"], block["timestamp"]) } @@ -280,7 +552,7 @@ func TestGetBlockByTimestamp(t *testing.T) { defer tx.Rollback() stateCache := kvcache.New(kvcache.DefaultCoherentConfig) - api := NewErigonAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine), m.DB, nil) + api := NewErigonAPI(NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine, m.Dirs), m.DB, nil) highestBlockNumber := rawdb.ReadCurrentHeader(tx).Number pickedBlock, err := rawdb.ReadBlockByNumber(tx, highestBlockNumber.Uint64()/3) @@ -314,16 +586,88 @@ func TestGetBlockByTimestamp(t *testing.T) { } } +// contractHexString is the output of compiling the following solidity contract: +// +// pragma solidity ^0.8.0; +// +// contract Box { +// uint256 private _value0x0; +// uint256 private _value0x1; +// uint256 private _value0x2; +// uint256 private _value0x3; +// uint256 private _value0x4; +// uint256 private _value0x5; +// uint256 private _value0x6; +// uint256 private _value0x7; +// uint256 private _value0x8; +// uint256 private _value0x9; +// uint256 private _value0xa; +// uint256 private _value0xb; +// uint256 private _value0xc; +// uint256 private _value0xd; +// uint256 private _value0xe; +// uint256 private _value0xf; +// uint256 private _value0x10; +// +// // Emitted when the stored value changes +// event ValueChanged(uint256 value); +// +// // Stores a new value in the contract +// function store(uint256 value) public { +// _value0x0 = value; +// _value0x1 = value; +// _value0x2 = value; +// _value0x3 = value; +// _value0x4 = value; +// _value0x5 = value; +// _value0x6 = value; +// _value0x7 = value; +// _value0x8 = value; +// _value0x9 = value; +// _value0xa = value; +// _value0xb = value; +// _value0xc = value; +// _value0xd = value; +// _value0xe = value; +// _value0xf = value; +// _value0x10 = value; +// emit ValueChanged(value); +// } +// +// // Reads the last stored value +// function retrieve() public view returns (uint256) { +// return _value0x0; +// } +// } +// +// You may produce this hex string by saving the contract into a file +// Box.sol and invoking +// +// solc Box.sol --bin --abi --optimize +// +// This contract is a slight modification of Box.sol to use more storage nodes +// and ensure the contract storage will contain at least 1 non-leaf node (by +// storing 17 values). +const contractHexString = "0x608060405234801561001057600080fd5b5061013f806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80632e64cec11461003b5780636057361d14610050575b600080fd5b60005460405190815260200160405180910390f35b61006361005e3660046100f0565b610065565b005b6000819055600181905560028190556003819055600481905560058190556006819055600781905560088190556009819055600a819055600b819055600c819055600d819055600e819055600f81905560108190556040518181527f93fe6d397c74fdf1402a8b72e47b68512f0510d7b98a4bc4cbdf6ac7108b3c599060200160405180910390a150565b60006020828403121561010257600080fd5b503591905056fea2646970667358221220031e17f1bd1d1dcbee088287a905b152410b180064c149763590a0bbc516d95e64736f6c63430008130033" + +var contractFuncSelector = crypto.Keccak256([]byte("store(uint256)"))[:4] + +// contractInvocationData returns data suitable for invoking the 'store' +// function of the contract in contractHexString, note +func contractInvocationData(val byte) []byte { + return hexutil.MustDecode(fmt.Sprintf("0x%x00000000000000000000000000000000000000000000000000000000000000%02x", contractFuncSelector, val)) +} + func chainWithDeployedContract(t *testing.T) (*stages.MockSentry, libcommon.Address, libcommon.Address) { var ( signer = types.LatestSignerForChainID(nil) bankKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") bankAddress = crypto.PubkeyToAddress(bankKey.PublicKey) bankFunds = big.NewInt(1e9) - contract = hexutil.MustDecode("0x608060405234801561001057600080fd5b50610150806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80632e64cec11461003b5780636057361d14610059575b600080fd5b610043610075565b60405161005091906100d9565b60405180910390f35b610073600480360381019061006e919061009d565b61007e565b005b60008054905090565b8060008190555050565b60008135905061009781610103565b92915050565b6000602082840312156100b3576100b26100fe565b5b60006100c184828501610088565b91505092915050565b6100d3816100f4565b82525050565b60006020820190506100ee60008301846100ca565b92915050565b6000819050919050565b600080fd5b61010c816100f4565b811461011757600080fd5b5056fea26469706673582212209a159a4f3847890f10bfb87871a61eba91c5dbf5ee3cf6398207e292eee22a1664736f6c63430008070033") - gspec = &core.Genesis{ + contract = hexutil.MustDecode(contractHexString) + gspec = &types.Genesis{ Config: params.TestChainConfig, - Alloc: core.GenesisAlloc{bankAddress: {Balance: bankFunds}}, + Alloc: types.GenesisAlloc{bankAddress: {Balance: bankFunds}}, } ) m := stages.MockWithGenesis(t, gspec, bankKey, false) @@ -331,7 +675,7 @@ func chainWithDeployedContract(t *testing.T) (*stages.MockSentry, libcommon.Addr var contractAddr libcommon.Address - chain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 2, func(i int, block *core.BlockGen) { + chain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 3, func(i int, block *core.BlockGen) { nonce := block.TxNonce(bankAddress) switch i { case 0: @@ -340,7 +684,11 @@ func chainWithDeployedContract(t *testing.T) (*stages.MockSentry, libcommon.Addr block.AddTx(tx) contractAddr = crypto.CreateAddress(bankAddress, nonce) case 1: - txn, err := types.SignTx(types.NewTransaction(nonce, contractAddr, new(uint256.Int), 90000, new(uint256.Int), nil), *signer, bankKey) + txn, err := types.SignTx(types.NewTransaction(nonce, contractAddr, new(uint256.Int), 900000, new(uint256.Int), contractInvocationData(1)), *signer, bankKey) + assert.NoError(t, err) + block.AddTx(txn) + case 2: + txn, err := types.SignTx(types.NewTransaction(nonce, contractAddr, new(uint256.Int), 900000, new(uint256.Int), contractInvocationData(2)), *signer, bankKey) assert.NoError(t, err) block.AddTx(txn) } diff --git a/cmd/rpcdaemon/commands/eth_deprecated.go b/cmd/rpcdaemon/commands/eth_deprecated.go index 16a8553d27c..6c59ba83e38 100644 --- a/cmd/rpcdaemon/commands/eth_deprecated.go +++ b/cmd/rpcdaemon/commands/eth_deprecated.go @@ -5,8 +5,7 @@ import ( "fmt" "github.com/ledgerwatch/erigon-lib/common" - - "github.com/ledgerwatch/erigon/common/hexutil" + "github.com/ledgerwatch/erigon-lib/common/hexutility" ) // Accounts implements eth_accounts. Returns a list of addresses owned by the client. @@ -17,8 +16,8 @@ func (api *APIImpl) Accounts(ctx context.Context) ([]common.Address, error) { // Sign implements eth_sign. Calculates an Ethereum specific signature with: sign(keccak256('\\x19Ethereum Signed Message:\\n' + len(message) + message))). // Deprecated: This function will be removed in the future. -func (api *APIImpl) Sign(ctx context.Context, _ common.Address, _ hexutil.Bytes) (hexutil.Bytes, error) { - return hexutil.Bytes(""), fmt.Errorf(NotAvailableDeprecated, "eth_sign") +func (api *APIImpl) Sign(ctx context.Context, _ common.Address, _ hexutility.Bytes) (hexutility.Bytes, error) { + return hexutility.Bytes(""), fmt.Errorf(NotAvailableDeprecated, "eth_sign") } // SignTransaction deprecated diff --git a/cmd/rpcdaemon/commands/eth_receipts.go b/cmd/rpcdaemon/commands/eth_receipts.go index 354cd99282f..69c07d81abc 100644 --- a/cmd/rpcdaemon/commands/eth_receipts.go +++ b/cmd/rpcdaemon/commands/eth_receipts.go @@ -61,10 +61,11 @@ func (api *BaseAPI) getReceipts(ctx context.Context, tx kv.Tx, chainConfig *chai } return h } + header := block.Header() + excessDataGas := header.ParentExcessDataGas(getHeader) for i, txn := range block.Transactions() { ibs.Prepare(txn.Hash(), block.Hash(), i) - header := block.Header() - receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), engine, nil, gp, ibs, noopWriter, header, txn, usedGas, vm.Config{}) + receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), engine, nil, gp, ibs, noopWriter, header, txn, usedGas, vm.Config{}, excessDataGas) if err != nil { return nil, err } @@ -482,6 +483,7 @@ func txnExecutor(tx kv.TemporalTx, chainConfig *chain.Config, engine consensus.E stateReader.SetTx(tx) ie := &intraBlockExec{ + tx: tx, engine: engine, chainConfig: chainConfig, br: br, diff --git a/cmd/rpcdaemon/commands/eth_subscribe_test.go b/cmd/rpcdaemon/commands/eth_subscribe_test.go index 17e726edfe7..94c3828facc 100644 --- a/cmd/rpcdaemon/commands/eth_subscribe_test.go +++ b/cmd/rpcdaemon/commands/eth_subscribe_test.go @@ -22,9 +22,6 @@ import ( func TestEthSubscribe(t *testing.T) { m, require := stages.Mock(t), require.New(t) - if m.HistoryV3 { - t.Skip() - } br := snapshotsync.NewBlockReaderWithSnapshots(m.BlockSnapshots, m.TransactionsV3) chain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 7, func(i int, b *core.BlockGen) { b.SetCoinbase(libcommon.Address{1}) diff --git a/cmd/rpcdaemon/commands/eth_txs.go b/cmd/rpcdaemon/commands/eth_txs.go index 527798a36db..21fe98462ac 100644 --- a/cmd/rpcdaemon/commands/eth_txs.go +++ b/cmd/rpcdaemon/commands/eth_txs.go @@ -6,6 +6,7 @@ import ( "math/big" "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/gointerfaces" "github.com/ledgerwatch/erigon-lib/gointerfaces/txpool" "github.com/ledgerwatch/erigon-lib/gointerfaces/types" @@ -117,7 +118,7 @@ func (api *APIImpl) GetTransactionByHash(ctx context.Context, txnHash common.Has } // GetRawTransactionByHash returns the bytes of the transaction for the given hash. -func (api *APIImpl) GetRawTransactionByHash(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) { +func (api *APIImpl) GetRawTransactionByHash(ctx context.Context, hash common.Hash) (hexutility.Bytes, error) { tx, err := api.db.BeginRo(ctx) if err != nil { return nil, err @@ -204,7 +205,7 @@ func (api *APIImpl) GetTransactionByBlockHashAndIndex(ctx context.Context, block } // GetRawTransactionByBlockHashAndIndex returns the bytes of the transaction for the given block hash and index. -func (api *APIImpl) GetRawTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) (hexutil.Bytes, error) { +func (api *APIImpl) GetRawTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) (hexutility.Bytes, error) { tx, err := api.db.BeginRo(ctx) if err != nil { return nil, err @@ -268,7 +269,7 @@ func (api *APIImpl) GetTransactionByBlockNumberAndIndex(ctx context.Context, blo } // GetRawTransactionByBlockNumberAndIndex returns the bytes of the transaction for the given block number and index. -func (api *APIImpl) GetRawTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) (hexutil.Bytes, error) { +func (api *APIImpl) GetRawTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) (hexutility.Bytes, error) { tx, err := api.db.BeginRo(ctx) if err != nil { return nil, err diff --git a/cmd/rpcdaemon/commands/gen_traces_test.go b/cmd/rpcdaemon/commands/gen_traces_test.go index 241acf35d56..1250560ec20 100644 --- a/cmd/rpcdaemon/commands/gen_traces_test.go +++ b/cmd/rpcdaemon/commands/gen_traces_test.go @@ -122,7 +122,7 @@ func TestGeneratedTraceApi(t *testing.T) { stateCache := kvcache.New(kvcache.DefaultCoherentConfig) baseApi := NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine) api := NewTraceAPI(baseApi, m.DB, &httpcfg.HttpCfg{}) - traces, err := api.Block(context.Background(), rpc.BlockNumber(1)) + traces, err := api.Block(context.Background(), rpc.BlockNumber(1), new(bool)) if err != nil { t.Errorf("trace_block %d: %v", 0, err) } @@ -281,7 +281,7 @@ func TestGeneratedTraceApiCollision(t *testing.T) { stateCache := kvcache.New(kvcache.DefaultCoherentConfig) baseApi := NewBaseApi(nil, stateCache, br, agg, false, rpccfg.DefaultEvmCallTimeout, m.Engine) api := NewTraceAPI(baseApi, m.DB, &httpcfg.HttpCfg{}) - traces, err := api.Transaction(context.Background(), common.HexToHash("0xb2b9fa4c999c1c8370ce1fbd1c4315a9ce7f8421fe2ebed8a9051ff2e4e7e3da")) + traces, err := api.Transaction(context.Background(), common.HexToHash("0xb2b9fa4c999c1c8370ce1fbd1c4315a9ce7f8421fe2ebed8a9051ff2e4e7e3da"), new(bool)) if err != nil { t.Errorf("trace_block %d: %v", 0, err) } diff --git a/cmd/rpcdaemon/commands/otterscan_api.go b/cmd/rpcdaemon/commands/otterscan_api.go index 13dd6d32467..b66868f6ccd 100644 --- a/cmd/rpcdaemon/commands/otterscan_api.go +++ b/cmd/rpcdaemon/commands/otterscan_api.go @@ -8,14 +8,16 @@ import ( "sync" "github.com/holiman/uint256" + "github.com/ledgerwatch/log/v3" + "github.com/ledgerwatch/erigon-lib/chain" "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv/iter" "github.com/ledgerwatch/erigon-lib/kv/order" "github.com/ledgerwatch/erigon-lib/kv/rawdbv3" "github.com/ledgerwatch/erigon/core/state/temporal" - "github.com/ledgerwatch/log/v3" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/consensus/ethash" @@ -49,7 +51,7 @@ type OtterscanAPI interface { GetBlockTransactions(ctx context.Context, number rpc.BlockNumber, pageNumber uint8, pageSize uint8) (map[string]interface{}, error) HasCode(ctx context.Context, address common.Address, blockNrOrHash rpc.BlockNumberOrHash) (bool, error) TraceTransaction(ctx context.Context, hash common.Hash) ([]*TraceEntry, error) - GetTransactionError(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) + GetTransactionError(ctx context.Context, hash common.Hash) (hexutility.Bytes, error) GetTransactionBySenderAndNonce(ctx context.Context, addr common.Address, nonce uint64) (*common.Hash, error) GetContractCreator(ctx context.Context, addr common.Address) (*ContractCreatorData, error) } diff --git a/cmd/rpcdaemon/commands/otterscan_generic_tracer.go b/cmd/rpcdaemon/commands/otterscan_generic_tracer.go index 8b46f309fa5..2f0bb9addff 100644 --- a/cmd/rpcdaemon/commands/otterscan_generic_tracer.go +++ b/cmd/rpcdaemon/commands/otterscan_generic_tracer.go @@ -82,13 +82,14 @@ func (api *OtterscanAPIImpl) genericTracer(dbtx kv.Tx, ctx context.Context, bloc } header := block.Header() + excessDataGas := header.ParentExcessDataGas(getHeader) rules := chainConfig.Rules(block.NumberU64(), header.Time) for idx, tx := range block.Transactions() { ibs.Prepare(tx.Hash(), block.Hash(), idx) msg, _ := tx.AsMessage(*signer, header.BaseFee, rules) - BlockContext := core.NewEVMBlockContext(header, core.GetHashFn(header, getHeader), engine, nil) + BlockContext := core.NewEVMBlockContext(header, core.GetHashFn(header, getHeader), engine, nil, excessDataGas) TxContext := core.NewEVMTxContext(msg) vmenv := vm.NewEVM(BlockContext, TxContext, ibs, chainConfig, vm.Config{Debug: true, Tracer: tracer}) diff --git a/cmd/rpcdaemon/commands/otterscan_search_trace.go b/cmd/rpcdaemon/commands/otterscan_search_trace.go index 47924536d66..83174cca030 100644 --- a/cmd/rpcdaemon/commands/otterscan_search_trace.go +++ b/cmd/rpcdaemon/commands/otterscan_search_trace.go @@ -77,6 +77,7 @@ func (api *OtterscanAPIImpl) traceBlock(dbtx kv.Tx, ctx context.Context, blockNu blockReceipts := rawdb.ReadReceipts(dbtx, block, senders) header := block.Header() + excessDataGas := header.ParentExcessDataGas(getHeader) rules := chainConfig.Rules(block.NumberU64(), header.Time) found := false for idx, tx := range block.Transactions() { @@ -85,7 +86,7 @@ func (api *OtterscanAPIImpl) traceBlock(dbtx kv.Tx, ctx context.Context, blockNu msg, _ := tx.AsMessage(*signer, header.BaseFee, rules) tracer := NewTouchTracer(searchAddr) - BlockContext := core.NewEVMBlockContext(header, core.GetHashFn(header, getHeader), engine, nil) + BlockContext := core.NewEVMBlockContext(header, core.GetHashFn(header, getHeader), engine, nil, excessDataGas) TxContext := core.NewEVMTxContext(msg) vmenv := vm.NewEVM(BlockContext, TxContext, ibs, chainConfig, vm.Config{Debug: true, Tracer: tracer}) diff --git a/cmd/rpcdaemon/commands/otterscan_trace_transaction.go b/cmd/rpcdaemon/commands/otterscan_trace_transaction.go index 79767ec5c75..9778c69c908 100644 --- a/cmd/rpcdaemon/commands/otterscan_trace_transaction.go +++ b/cmd/rpcdaemon/commands/otterscan_trace_transaction.go @@ -5,7 +5,9 @@ import ( "math/big" "github.com/holiman/uint256" + "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/core/vm" @@ -27,12 +29,12 @@ func (api *OtterscanAPIImpl) TraceTransaction(ctx context.Context, hash common.H } type TraceEntry struct { - Type string `json:"type"` - Depth int `json:"depth"` - From common.Address `json:"from"` - To common.Address `json:"to"` - Value *hexutil.Big `json:"value"` - Input hexutil.Bytes `json:"input"` + Type string `json:"type"` + Depth int `json:"depth"` + From common.Address `json:"from"` + To common.Address `json:"to"` + Value *hexutil.Big `json:"value"` + Input hexutility.Bytes `json:"input"` } type TransactionTracer struct { diff --git a/cmd/rpcdaemon/commands/otterscan_transaction_error.go b/cmd/rpcdaemon/commands/otterscan_transaction_error.go index 503bfc183d7..c15b4c83b8e 100644 --- a/cmd/rpcdaemon/commands/otterscan_transaction_error.go +++ b/cmd/rpcdaemon/commands/otterscan_transaction_error.go @@ -4,11 +4,10 @@ import ( "context" "github.com/ledgerwatch/erigon-lib/common" - - "github.com/ledgerwatch/erigon/common/hexutil" + "github.com/ledgerwatch/erigon-lib/common/hexutility" ) -func (api *OtterscanAPIImpl) GetTransactionError(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) { +func (api *OtterscanAPIImpl) GetTransactionError(ctx context.Context, hash common.Hash) (hexutility.Bytes, error) { tx, err := api.db.BeginRo(ctx) if err != nil { return nil, err diff --git a/cmd/rpcdaemon/commands/parity_api.go b/cmd/rpcdaemon/commands/parity_api.go index a1ac2e935ec..604b232f03b 100644 --- a/cmd/rpcdaemon/commands/parity_api.go +++ b/cmd/rpcdaemon/commands/parity_api.go @@ -6,10 +6,10 @@ import ( "fmt" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/common/length" "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/core/state" "github.com/ledgerwatch/erigon/rpc" ) @@ -20,7 +20,7 @@ var ErrWrongTag = fmt.Errorf("listStorageKeys wrong block tag or number: must be // ParityAPI the interface for the parity_ RPC commands type ParityAPI interface { - ListStorageKeys(ctx context.Context, account libcommon.Address, quantity int, offset *hexutil.Bytes, blockNumber rpc.BlockNumberOrHash) ([]hexutil.Bytes, error) + ListStorageKeys(ctx context.Context, account libcommon.Address, quantity int, offset *hexutility.Bytes, blockNumber rpc.BlockNumberOrHash) ([]hexutility.Bytes, error) } // ParityAPIImpl data structure to store things needed for parity_ commands @@ -36,7 +36,7 @@ func NewParityAPIImpl(db kv.RoDB) *ParityAPIImpl { } // ListStorageKeys implements parity_listStorageKeys. Returns all storage keys of the given address -func (api *ParityAPIImpl) ListStorageKeys(ctx context.Context, account libcommon.Address, quantity int, offset *hexutil.Bytes, blockNumberOrTag rpc.BlockNumberOrHash) ([]hexutil.Bytes, error) { +func (api *ParityAPIImpl) ListStorageKeys(ctx context.Context, account libcommon.Address, quantity int, offset *hexutility.Bytes, blockNumberOrTag rpc.BlockNumberOrHash) ([]hexutility.Bytes, error) { if err := api.checkBlockNumber(blockNumberOrTag); err != nil { return nil, err } @@ -62,7 +62,7 @@ func (api *ParityAPIImpl) ListStorageKeys(ctx context.Context, account libcommon return nil, err } defer c.Close() - keys := make([]hexutil.Bytes, 0) + keys := make([]hexutility.Bytes, 0) var v []byte var seekVal []byte if offset != nil { diff --git a/cmd/rpcdaemon/commands/parity_api_test.go b/cmd/rpcdaemon/commands/parity_api_test.go index d3728cc7952..1b23060b846 100644 --- a/cmd/rpcdaemon/commands/parity_api_test.go +++ b/cmd/rpcdaemon/commands/parity_api_test.go @@ -5,12 +5,13 @@ import ( "fmt" "testing" - libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/stretchr/testify/assert" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" + "github.com/ledgerwatch/erigon/cmd/rpcdaemon/rpcdaemontest" "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/rpc" ) @@ -51,7 +52,7 @@ func TestParityAPIImpl_ListStorageKeys_WithOffset_ExistingPrefix(t *testing.T) { } addr := libcommon.HexToAddress("0x920fd5070602feaea2e251e9e7238b6c376bcae5") offset := common.Hex2Bytes("29") - b := hexutil.Bytes(offset) + b := hexutility.Bytes(offset) result, err := api.ListStorageKeys(context.Background(), addr, 5, &b, latestBlock) if err != nil { t.Errorf("calling ListStorageKeys: %v", err) @@ -72,7 +73,7 @@ func TestParityAPIImpl_ListStorageKeys_WithOffset_NonExistingPrefix(t *testing.T } addr := libcommon.HexToAddress("0x920fd5070602feaea2e251e9e7238b6c376bcae5") offset := common.Hex2Bytes("30") - b := hexutil.Bytes(offset) + b := hexutility.Bytes(offset) result, err := api.ListStorageKeys(context.Background(), addr, 2, &b, latestBlock) if err != nil { t.Errorf("calling ListStorageKeys: %v", err) @@ -89,7 +90,7 @@ func TestParityAPIImpl_ListStorageKeys_WithOffset_EmptyResponse(t *testing.T) { api := NewParityAPIImpl(m.DB) addr := libcommon.HexToAddress("0x920fd5070602feaea2e251e9e7238b6c376bcae5") offset := common.Hex2Bytes("ff") - b := hexutil.Bytes(offset) + b := hexutility.Bytes(offset) result, err := api.ListStorageKeys(context.Background(), addr, 2, &b, latestBlock) if err != nil { t.Errorf("calling ListStorageKeys: %v", err) diff --git a/cmd/rpcdaemon/commands/send_transaction.go b/cmd/rpcdaemon/commands/send_transaction.go index bd274d19237..700ec0680bb 100644 --- a/cmd/rpcdaemon/commands/send_transaction.go +++ b/cmd/rpcdaemon/commands/send_transaction.go @@ -8,10 +8,10 @@ import ( "math/big" "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" txPoolProto "github.com/ledgerwatch/erigon-lib/gointerfaces/txpool" "github.com/ledgerwatch/log/v3" - "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/crypto" @@ -21,7 +21,7 @@ import ( ) // SendRawTransaction implements eth_sendRawTransaction. Creates new message call transaction or a contract creation for previously-signed transactions. -func (api *APIImpl) SendRawTransaction(ctx context.Context, encodedTx hexutil.Bytes) (common.Hash, error) { +func (api *APIImpl) SendRawTransaction(ctx context.Context, encodedTx hexutility.Bytes) (common.Hash, error) { txn, err := types.DecodeTransaction(rlp.NewStream(bytes.NewReader(encodedTx), uint64(len(encodedTx)))) if err != nil { return common.Hash{}, err diff --git a/cmd/rpcdaemon/commands/trace_adhoc.go b/cmd/rpcdaemon/commands/trace_adhoc.go index 9980745edbc..79988b862fa 100644 --- a/cmd/rpcdaemon/commands/trace_adhoc.go +++ b/cmd/rpcdaemon/commands/trace_adhoc.go @@ -9,10 +9,12 @@ import ( "strings" "github.com/holiman/uint256" + "github.com/ledgerwatch/log/v3" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/kv" types2 "github.com/ledgerwatch/erigon-lib/types" - "github.com/ledgerwatch/log/v3" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/hexutil" @@ -50,8 +52,9 @@ type TraceCallParam struct { GasPrice *hexutil.Big `json:"gasPrice"` MaxPriorityFeePerGas *hexutil.Big `json:"maxPriorityFeePerGas"` MaxFeePerGas *hexutil.Big `json:"maxFeePerGas"` + MaxFeePerDataGas *hexutil.Big `json:"maxFeePerDataGas"` Value *hexutil.Big `json:"value"` - Data hexutil.Bytes `json:"data"` + Data hexutility.Bytes `json:"data"` AccessList *types2.AccessList `json:"accessList"` txHash *libcommon.Hash traceTypes []string @@ -59,7 +62,7 @@ type TraceCallParam struct { // TraceCallResult is the response to `trace_call` method type TraceCallResult struct { - Output hexutil.Bytes `json:"output"` + Output hexutility.Bytes `json:"output"` StateDiff map[libcommon.Address]*StateDiffAccount `json:"stateDiff"` Trace []*ParityTrace `json:"trace"` VmTrace *VmTrace `json:"vmTrace"` @@ -80,8 +83,8 @@ type StateDiffBalance struct { } type StateDiffCode struct { - From hexutil.Bytes `json:"from"` - To hexutil.Bytes `json:"to"` + From hexutility.Bytes `json:"from"` + To hexutility.Bytes `json:"to"` } type StateDiffNonce struct { @@ -96,8 +99,8 @@ type StateDiffStorage struct { // VmTrace is the part of `trace_call` response that is under "vmTrace" tag type VmTrace struct { - Code hexutil.Bytes `json:"code"` - Ops []*VmTraceOp `json:"ops"` + Code hexutility.Bytes `json:"code"` + Ops []*VmTraceOp `json:"ops"` } // VmTraceOp is one element of the vmTrace ops trace @@ -148,9 +151,10 @@ func (args *TraceCallParam) ToMessage(globalGasCap uint64, baseFee *uint256.Int) gas = globalGasCap } var ( - gasPrice *uint256.Int - gasFeeCap *uint256.Int - gasTipCap *uint256.Int + gasPrice *uint256.Int + gasFeeCap *uint256.Int + gasTipCap *uint256.Int + maxFeePerDataGas *uint256.Int ) if baseFee == nil { // If there's no basefee, then it must be a non-1559 execution @@ -198,6 +202,9 @@ func (args *TraceCallParam) ToMessage(globalGasCap uint64, baseFee *uint256.Int) gasFeeCap, gasTipCap = gasPrice, gasPrice } } + if args.MaxFeePerDataGas != nil { + maxFeePerDataGas.SetFromBig(args.MaxFeePerDataGas.ToInt()) + } } value := new(uint256.Int) if args.Value != nil { @@ -214,7 +221,7 @@ func (args *TraceCallParam) ToMessage(globalGasCap uint64, baseFee *uint256.Int) if args.AccessList != nil { accessList = *args.AccessList } - msg := types.NewMessage(addr, args.To, 0, value, gas, gasPrice, gasFeeCap, gasTipCap, data, accessList, false /* checkNonce */, false /* isFree */) + msg := types.NewMessage(addr, args.To, 0, value, gas, gasPrice, gasFeeCap, gasTipCap, data, accessList, false /* checkNonce */, false /* isFree */, maxFeePerDataGas) return msg, nil } @@ -659,7 +666,7 @@ func (sd *StateDiff) CompareStates(initialIbs, ibs *state.IntraBlockState) { accountDiff.Balance = m } { - m := make(map[string]hexutil.Bytes) + m := make(map[string]hexutility.Bytes) m["-"] = initialIbs.GetCode(addr) accountDiff.Code = m } @@ -676,7 +683,7 @@ func (sd *StateDiff) CompareStates(initialIbs, ibs *state.IntraBlockState) { accountDiff.Balance = m } { - m := make(map[string]hexutil.Bytes) + m := make(map[string]hexutility.Bytes) m["+"] = ibs.GetCode(addr) accountDiff.Code = m } @@ -700,7 +707,10 @@ func (sd *StateDiff) CompareStates(initialIbs, ibs *state.IntraBlockState) { } } -func (api *TraceAPIImpl) ReplayTransaction(ctx context.Context, txHash libcommon.Hash, traceTypes []string) (*TraceCallResult, error) { +func (api *TraceAPIImpl) ReplayTransaction(ctx context.Context, txHash libcommon.Hash, traceTypes []string, gasBailOut *bool) (*TraceCallResult, error) { + if gasBailOut == nil { + gasBailOut = new(bool) // false by default + } tx, err := api.kv.BeginRo(ctx) if err != nil { return nil, err @@ -744,15 +754,8 @@ func (api *TraceAPIImpl) ReplayTransaction(ctx context.Context, txHash libcommon } } - bn := hexutil.Uint64(blockNum) - - parentNr := bn - if parentNr > 0 { - parentNr -= 1 - } - // Returns an array of trace arrays, one trace array for each transaction - traces, err := api.callManyTransactions(ctx, tx, block.Transactions(), traceTypes, block.ParentHash(), rpc.BlockNumber(parentNr), block.Header(), int(txnIndex), types.MakeSigner(chainConfig, blockNum), chainConfig.Rules(blockNum, block.Time())) + traces, err := api.callManyTransactions(ctx, tx, block, traceTypes, int(txnIndex), *gasBailOut, types.MakeSigner(chainConfig, blockNum), chainConfig) if err != nil { return nil, err } @@ -792,7 +795,10 @@ func (api *TraceAPIImpl) ReplayTransaction(ctx context.Context, txHash libcommon return result, nil } -func (api *TraceAPIImpl) ReplayBlockTransactions(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash, traceTypes []string) ([]*TraceCallResult, error) { +func (api *TraceAPIImpl) ReplayBlockTransactions(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash, traceTypes []string, gasBailOut *bool) ([]*TraceCallResult, error) { + if gasBailOut == nil { + gasBailOut = new(bool) // false by default + } tx, err := api.kv.BeginRo(ctx) if err != nil { return nil, err @@ -808,10 +814,6 @@ func (api *TraceAPIImpl) ReplayBlockTransactions(ctx context.Context, blockNrOrH return nil, err } - parentNr := blockNumber - if parentNr > 0 { - parentNr -= 1 - } // Extract transactions from block block, bErr := api.blockByNumberWithSenders(tx, blockNumber) if bErr != nil { @@ -835,7 +837,7 @@ func (api *TraceAPIImpl) ReplayBlockTransactions(ctx context.Context, blockNrOrH } // Returns an array of trace arrays, one trace array for each transaction - traces, err := api.callManyTransactions(ctx, tx, block.Transactions(), traceTypes, block.ParentHash(), rpc.BlockNumber(parentNr), block.Header(), -1 /* all tx indices */, types.MakeSigner(chainConfig, blockNumber), chainConfig.Rules(blockNumber, block.Time())) + traces, err := api.callManyTransactions(ctx, tx, block, traceTypes, -1 /* all tx indices */, *gasBailOut, types.MakeSigner(chainConfig, blockNumber), chainConfig) if err != nil { return nil, err } @@ -1060,10 +1062,10 @@ func (api *TraceAPIImpl) CallMany(ctx context.Context, calls json.RawMessage, pa if err != nil { return nil, err } - parentHeader := parentBlock.Header() - if parentHeader == nil { - return nil, fmt.Errorf("parent header %d(%x) not found", blockNumber, hash) + if parentBlock == nil { + return nil, fmt.Errorf("parent block %d(%x) not found", blockNumber, hash) } + parentHeader := parentBlock.Header() if parentHeader != nil && parentHeader.BaseFee != nil { var overflow bool baseFee, overflow = uint256.FromBig(parentHeader.BaseFee) diff --git a/cmd/rpcdaemon/commands/trace_adhoc_test.go b/cmd/rpcdaemon/commands/trace_adhoc_test.go index 92f4aba64de..f03151879ad 100644 --- a/cmd/rpcdaemon/commands/trace_adhoc_test.go +++ b/cmd/rpcdaemon/commands/trace_adhoc_test.go @@ -89,7 +89,7 @@ func TestReplayTransaction(t *testing.T) { } // Call GetTransactionReceipt for transaction which is not in the database - results, err := api.ReplayTransaction(context.Background(), txnHash, []string{"stateDiff"}) + results, err := api.ReplayTransaction(context.Background(), txnHash, []string{"stateDiff"}, new(bool)) if err != nil { t.Errorf("calling ReplayTransaction: %v", err) } @@ -110,7 +110,7 @@ func TestReplayBlockTransactions(t *testing.T) { // Call GetTransactionReceipt for transaction which is not in the database n := rpc.BlockNumber(6) - results, err := api.ReplayBlockTransactions(m.Ctx, rpc.BlockNumberOrHash{BlockNumber: &n}, []string{"stateDiff"}) + results, err := api.ReplayBlockTransactions(m.Ctx, rpc.BlockNumberOrHash{BlockNumber: &n}, []string{"stateDiff"}, new(bool)) if err != nil { t.Errorf("calling ReplayBlockTransactions: %v", err) } diff --git a/cmd/rpcdaemon/commands/trace_api.go b/cmd/rpcdaemon/commands/trace_api.go index 50ac4e652fc..a75daa6105e 100644 --- a/cmd/rpcdaemon/commands/trace_api.go +++ b/cmd/rpcdaemon/commands/trace_api.go @@ -16,17 +16,17 @@ import ( // TraceAPI RPC interface into tracing API type TraceAPI interface { // Ad-hoc (see ./trace_adhoc.go) - ReplayBlockTransactions(ctx context.Context, blockNr rpc.BlockNumberOrHash, traceTypes []string) ([]*TraceCallResult, error) - ReplayTransaction(ctx context.Context, txHash libcommon.Hash, traceTypes []string) (*TraceCallResult, error) + ReplayBlockTransactions(ctx context.Context, blockNr rpc.BlockNumberOrHash, traceTypes []string, gasBailOut *bool) ([]*TraceCallResult, error) + ReplayTransaction(ctx context.Context, txHash libcommon.Hash, traceTypes []string, gasBailOut *bool) (*TraceCallResult, error) Call(ctx context.Context, call TraceCallParam, types []string, blockNr *rpc.BlockNumberOrHash) (*TraceCallResult, error) CallMany(ctx context.Context, calls json.RawMessage, blockNr *rpc.BlockNumberOrHash) ([]*TraceCallResult, error) RawTransaction(ctx context.Context, txHash libcommon.Hash, traceTypes []string) ([]interface{}, error) // Filtering (see ./trace_filtering.go) - Transaction(ctx context.Context, txHash libcommon.Hash) (ParityTraces, error) - Get(ctx context.Context, txHash libcommon.Hash, txIndicies []hexutil.Uint64) (*ParityTrace, error) - Block(ctx context.Context, blockNr rpc.BlockNumber) (ParityTraces, error) - Filter(ctx context.Context, req TraceFilterRequest, stream *jsoniter.Stream) error + Transaction(ctx context.Context, txHash libcommon.Hash, gasBailOut *bool) (ParityTraces, error) + Get(ctx context.Context, txHash libcommon.Hash, txIndicies []hexutil.Uint64, gasBailOut *bool) (*ParityTrace, error) + Block(ctx context.Context, blockNr rpc.BlockNumber, gasBailOut *bool) (ParityTraces, error) + Filter(ctx context.Context, req TraceFilterRequest, stream *jsoniter.Stream, gasBailOut *bool) error } // TraceAPIImpl is implementation of the TraceAPI interface based on remote Db access diff --git a/cmd/rpcdaemon/commands/trace_filtering.go b/cmd/rpcdaemon/commands/trace_filtering.go index 66a39793c05..c96d3c0eeaa 100644 --- a/cmd/rpcdaemon/commands/trace_filtering.go +++ b/cmd/rpcdaemon/commands/trace_filtering.go @@ -15,7 +15,9 @@ import ( "github.com/ledgerwatch/erigon-lib/kv/iter" "github.com/ledgerwatch/erigon-lib/kv/order" "github.com/ledgerwatch/erigon-lib/kv/rawdbv3" + "github.com/ledgerwatch/erigon/common/hexutil" + "github.com/ledgerwatch/erigon/consensus" "github.com/ledgerwatch/erigon/consensus/ethash" "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/core/rawdb" @@ -23,6 +25,7 @@ import ( "github.com/ledgerwatch/erigon/core/state/temporal" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/vm" + "github.com/ledgerwatch/erigon/eth/stagedsync" "github.com/ledgerwatch/erigon/ethdb" "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/rpchelper" @@ -31,7 +34,10 @@ import ( ) // Transaction implements trace_transaction -func (api *TraceAPIImpl) Transaction(ctx context.Context, txHash common.Hash) (ParityTraces, error) { +func (api *TraceAPIImpl) Transaction(ctx context.Context, txHash common.Hash, gasBailOut *bool) (ParityTraces, error) { + if gasBailOut == nil { + gasBailOut = new(bool) // false by default + } tx, err := api.kv.BeginRo(ctx) if err != nil { return nil, err @@ -85,14 +91,10 @@ func (api *TraceAPIImpl) Transaction(ctx context.Context, txHash common.Hash) (P } bn := hexutil.Uint64(blockNumber) - parentNr := bn - if parentNr > 0 { - parentNr -= 1 - } hash := block.Hash() // Returns an array of trace arrays, one trace array for each transaction - traces, err := api.callManyTransactions(ctx, tx, block.Transactions(), []string{TraceTypeTrace}, block.ParentHash(), rpc.BlockNumber(parentNr), block.Header(), txIndex, types.MakeSigner(chainConfig, blockNumber), chainConfig.Rules(blockNumber, block.Time())) + traces, err := api.callManyTransactions(ctx, tx, block, []string{TraceTypeTrace}, txIndex, *gasBailOut, types.MakeSigner(chainConfig, blockNumber), chainConfig) if err != nil { return nil, err } @@ -118,13 +120,12 @@ func (api *TraceAPIImpl) Transaction(ctx context.Context, txHash common.Hash) (P } // Get implements trace_get -func (api *TraceAPIImpl) Get(ctx context.Context, txHash common.Hash, indicies []hexutil.Uint64) (*ParityTrace, error) { +func (api *TraceAPIImpl) Get(ctx context.Context, txHash common.Hash, indicies []hexutil.Uint64, gasBailOut *bool) (*ParityTrace, error) { // Parity fails if it gets more than a single index. It returns nothing in this case. Must we? if len(indicies) > 1 { return nil, nil } - - traces, err := api.Transaction(ctx, txHash) + traces, err := api.Transaction(ctx, txHash, gasBailOut) if err != nil { return nil, err } @@ -140,7 +141,10 @@ func (api *TraceAPIImpl) Get(ctx context.Context, txHash common.Hash, indicies [ } // Block implements trace_block -func (api *TraceAPIImpl) Block(ctx context.Context, blockNr rpc.BlockNumber) (ParityTraces, error) { +func (api *TraceAPIImpl) Block(ctx context.Context, blockNr rpc.BlockNumber, gasBailOut *bool) (ParityTraces, error) { + if gasBailOut == nil { + gasBailOut = new(bool) // false by default + } tx, err := api.kv.BeginRo(ctx) if err != nil { return nil, err @@ -164,16 +168,11 @@ func (api *TraceAPIImpl) Block(ctx context.Context, blockNr rpc.BlockNumber) (Pa return nil, fmt.Errorf("could not find block %d", uint64(bn)) } - parentNr := bn - if parentNr > 0 { - parentNr -= 1 - } - chainConfig, err := api.chainConfig(tx) if err != nil { return nil, err } - traces, err := api.callManyTransactions(ctx, tx, block.Transactions(), []string{TraceTypeTrace}, block.ParentHash(), rpc.BlockNumber(parentNr), block.Header(), -1 /* all tx indices */, types.MakeSigner(chainConfig, blockNum), chainConfig.Rules(blockNum, block.Time())) + traces, err := api.callManyTransactions(ctx, tx, block, []string{TraceTypeTrace}, -1 /* all tx indices */, *gasBailOut /* gasBailOut */, types.MakeSigner(chainConfig, blockNum), chainConfig) if err != nil { return nil, err } @@ -296,33 +295,33 @@ func traceFilterBitmapsV3(tx kv.TemporalTx, req TraceFilterRequest, from, to uin for _, addr := range req.FromAddress { if addr != nil { - it, err := tx.IndexRange(temporal.TracesFromIdx, addr.Bytes(), int(from), int(to), order.Asc, -1) + it, err := tx.IndexRange(temporal.TracesFromIdx, addr.Bytes(), int(from), int(to), order.Asc, kv.Unlim) if errors.Is(err, ethdb.ErrKeyNotFound) { continue } - allBlocks = iter.Union[uint64](allBlocks, it) + allBlocks = iter.Union[uint64](allBlocks, it, order.Asc, -1) fromAddresses[*addr] = struct{}{} } } for _, addr := range req.ToAddress { if addr != nil { - it, err := tx.IndexRange(temporal.TracesToIdx, addr.Bytes(), int(from), int(to), order.Asc, -1) + it, err := tx.IndexRange(temporal.TracesToIdx, addr.Bytes(), int(from), int(to), order.Asc, kv.Unlim) if errors.Is(err, ethdb.ErrKeyNotFound) { continue } - blocksTo = iter.Union[uint64](blocksTo, it) + blocksTo = iter.Union[uint64](blocksTo, it, order.Asc, -1) toAddresses[*addr] = struct{}{} } } switch req.Mode { case TraceFilterModeIntersection: - allBlocks = iter.Intersect[uint64](allBlocks, blocksTo) + allBlocks = iter.Intersect[uint64](allBlocks, blocksTo, -1) case TraceFilterModeUnion: fallthrough default: - allBlocks = iter.Union[uint64](allBlocks, blocksTo) + allBlocks = iter.Union[uint64](allBlocks, blocksTo, order.Asc, -1) } // Special case - if no addresses specified, take all traces @@ -339,7 +338,10 @@ func traceFilterBitmapsV3(tx kv.TemporalTx, req TraceFilterRequest, from, to uin // Filter implements trace_filter // NOTE: We do not store full traces - we just store index for each address // Pull blocks which have txs with matching address -func (api *TraceAPIImpl) Filter(ctx context.Context, req TraceFilterRequest, stream *jsoniter.Stream) error { +func (api *TraceAPIImpl) Filter(ctx context.Context, req TraceFilterRequest, stream *jsoniter.Stream, gasBailOut *bool) error { + if gasBailOut == nil { + gasBailOut = new(bool) // false by default + } dbtx, err1 := api.kv.BeginRo(ctx) if err1 != nil { return fmt.Errorf("traceFilter cannot open tx: %w", err1) @@ -443,7 +445,7 @@ func (api *TraceAPIImpl) Filter(ctx context.Context, req TraceFilterRequest, str isPos = header.Difficulty.Cmp(common.Big0) == 0 || header.Difficulty.Cmp(chainConfig.TerminalTotalDifficulty) >= 0 } txs := block.Transactions() - t, tErr := api.callManyTransactions(ctx, dbtx, txs, []string{TraceTypeTrace}, block.ParentHash(), rpc.BlockNumber(block.NumberU64()-1), block.Header(), -1 /* all tx indices */, types.MakeSigner(chainConfig, b), chainConfig.Rules(b, block.Time())) + t, tErr := api.callManyTransactions(ctx, dbtx, block, []string{TraceTypeTrace}, -1 /* all tx indices */, *gasBailOut, types.MakeSigner(chainConfig, b), chainConfig) if tErr != nil { if first { first = false @@ -455,13 +457,14 @@ func (api *TraceAPIImpl) Filter(ctx context.Context, req TraceFilterRequest, str stream.WriteObjectEnd() continue } + isIntersectionMode := req.Mode == TraceFilterModeIntersection includeAll := len(fromAddresses) == 0 && len(toAddresses) == 0 for i, trace := range t { txPosition := uint64(i) txHash := txs[i].Hash() // Check if transaction concerns any of the addresses we wanted for _, pt := range trace.Trace { - if includeAll || filter_trace(pt, fromAddresses, toAddresses) { + if includeAll || filter_trace(pt, fromAddresses, toAddresses, isIntersectionMode) { nSeen++ pt.BlockHash = &blockHash pt.BlockNumber = &blockNumber @@ -870,8 +873,9 @@ func (api *TraceAPIImpl) filterV3(ctx context.Context, dbtx kv.TemporalTx, fromB stream.WriteObjectEnd() continue } + isIntersectionMode := req.Mode == TraceFilterModeIntersection for _, pt := range traceResult.Trace { - if includeAll || filter_trace(pt, fromAddresses, toAddresses) { + if includeAll || filter_trace(pt, fromAddresses, toAddresses, isIntersectionMode) { nSeen++ pt.BlockHash = &lastBlockHash pt.BlockNumber = &blockNum @@ -905,41 +909,73 @@ func (api *TraceAPIImpl) filterV3(ctx context.Context, dbtx kv.TemporalTx, fromB return stream.Flush() } -func filter_trace(pt *ParityTrace, fromAddresses map[common.Address]struct{}, toAddresses map[common.Address]struct{}) bool { +func filter_trace(pt *ParityTrace, fromAddresses map[common.Address]struct{}, toAddresses map[common.Address]struct{}, isIntersectionMode bool) bool { + f, t := false, false switch action := pt.Action.(type) { case *CallTraceAction: - _, f := fromAddresses[action.From] - _, t := toAddresses[action.To] - - if f || t { - return true - } + _, f = fromAddresses[action.From] + _, t = toAddresses[action.To] case *CreateTraceAction: - _, f := fromAddresses[action.From] - if f { - return true - } + _, f = fromAddresses[action.From] if res, ok := pt.Result.(*CreateTraceResult); ok { if res.Address != nil { - if _, t := toAddresses[*res.Address]; t { - return true - } + _, t = toAddresses[*res.Address] } } case *SuicideTraceAction: - _, f := fromAddresses[action.Address] - _, t := toAddresses[action.RefundAddress] - if f || t { - return true - } + _, f = fromAddresses[action.Address] + _, t = toAddresses[action.RefundAddress] } - return false + if isIntersectionMode { + return f && t + } else { + return f || t + } } -func (api *TraceAPIImpl) callManyTransactions(ctx context.Context, dbtx kv.Tx, txs []types.Transaction, traceTypes []string, parentHash common.Hash, parentNo rpc.BlockNumber, header *types.Header, txIndex int, signer *types.Signer, rules *chain.Rules) ([]*TraceCallResult, error) { +func (api *TraceAPIImpl) callManyTransactions( + ctx context.Context, + dbtx kv.Tx, + block *types.Block, + traceTypes []string, + txIndex int, + gasBailOut bool, + signer *types.Signer, + cfg *chain.Config, +) ([]*TraceCallResult, error) { + blockNumber := block.NumberU64() + pNo := blockNumber + if pNo > 0 { + pNo -= 1 + } + parentNo := rpc.BlockNumber(pNo) + rules := cfg.Rules(blockNumber, block.Time()) + header := block.Header() + var excessDataGas *big.Int + parentBlock, err := api.blockByRPCNumber(parentNo, dbtx) + if err != nil { + return nil, err + } else if parentBlock != nil { + excessDataGas = parentBlock.ExcessDataGas() + } + txs := block.Transactions() callParams := make([]TraceCallParam, 0, len(txs)) + reader, err := rpchelper.CreateHistoryStateReader(dbtx, blockNumber, txIndex, api.historyV3(dbtx), cfg.ChainName) + if err != nil { + return nil, err + } + stateDb := state.New(reader) + if err != nil { + return nil, err + } + engine := api.engine() + consensusHeaderReader := stagedsync.NewChainReaderImpl(cfg, dbtx, nil) + err = core.InitializeBlockExecution(engine.(consensus.Engine), consensusHeaderReader, block.HeaderNoCopy(), block.Transactions(), block.Uncles(), cfg, stateDb, excessDataGas) + if err != nil { + return nil, err + } msgs := make([]types.Message, len(txs)) for i, tx := range txs { hash := tx.Hash() @@ -948,16 +984,30 @@ func (api *TraceAPIImpl) callManyTransactions(ctx context.Context, dbtx kv.Tx, t traceTypes: traceTypes, }) var err error - if msgs[i], err = tx.AsMessage(*signer, header.BaseFee, rules); err != nil { + + msg, err := tx.AsMessage(*signer, header.BaseFee, rules) + if err != nil { return nil, fmt.Errorf("convert tx into msg: %w", err) } + + // gnosis might have a fee free account here + if msg.FeeCap().IsZero() && engine != nil { + syscall := func(contract common.Address, data []byte) ([]byte, error) { + return core.SysCallContract(contract, data, *cfg, stateDb, header, engine, true /* constCall */, excessDataGas) + } + msg.SetIsFree(engine.IsServiceTransaction(msg.From(), syscall)) + } + + msgs[i] = msg } + parentHash := block.ParentHash() + traces, cmErr := api.doCallMany(ctx, dbtx, msgs, callParams, &rpc.BlockNumberOrHash{ BlockNumber: &parentNo, BlockHash: &parentHash, RequireCanonical: true, - }, header, false /* gasBailout */, txIndex) + }, header, gasBailOut /* gasBailout */, txIndex) if cmErr != nil { return nil, cmErr diff --git a/cmd/rpcdaemon/commands/trace_types.go b/cmd/rpcdaemon/commands/trace_types.go index 9ebdbdf58da..a905d3a4c8a 100644 --- a/cmd/rpcdaemon/commands/trace_types.go +++ b/cmd/rpcdaemon/commands/trace_types.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/core/types" @@ -56,34 +57,34 @@ type ParityTraces []ParityTrace // TraceAction A parity formatted trace action type TraceAction struct { // Do not change the ordering of these fields -- allows for easier comparison with other clients - Author string `json:"author,omitempty"` - RewardType string `json:"rewardType,omitempty"` - SelfDestructed string `json:"address,omitempty"` - Balance string `json:"balance,omitempty"` - CallType string `json:"callType,omitempty"` - From common.Address `json:"from"` - Gas hexutil.Big `json:"gas"` - Init hexutil.Bytes `json:"init,omitempty"` - Input hexutil.Bytes `json:"input,omitempty"` - RefundAddress string `json:"refundAddress,omitempty"` - To string `json:"to,omitempty"` - Value string `json:"value,omitempty"` + Author string `json:"author,omitempty"` + RewardType string `json:"rewardType,omitempty"` + SelfDestructed string `json:"address,omitempty"` + Balance string `json:"balance,omitempty"` + CallType string `json:"callType,omitempty"` + From common.Address `json:"from"` + Gas hexutil.Big `json:"gas"` + Init hexutility.Bytes `json:"init,omitempty"` + Input hexutility.Bytes `json:"input,omitempty"` + RefundAddress string `json:"refundAddress,omitempty"` + To string `json:"to,omitempty"` + Value string `json:"value,omitempty"` } type CallTraceAction struct { - From common.Address `json:"from"` - CallType string `json:"callType"` - Gas hexutil.Big `json:"gas"` - Input hexutil.Bytes `json:"input"` - To common.Address `json:"to"` - Value hexutil.Big `json:"value"` + From common.Address `json:"from"` + CallType string `json:"callType"` + Gas hexutil.Big `json:"gas"` + Input hexutility.Bytes `json:"input"` + To common.Address `json:"to"` + Value hexutil.Big `json:"value"` } type CreateTraceAction struct { - From common.Address `json:"from"` - Gas hexutil.Big `json:"gas"` - Init hexutil.Bytes `json:"init"` - Value hexutil.Big `json:"value"` + From common.Address `json:"from"` + Gas hexutil.Big `json:"gas"` + Init hexutility.Bytes `json:"init"` + Value hexutil.Big `json:"value"` } type SuicideTraceAction struct { @@ -100,16 +101,16 @@ type RewardTraceAction struct { type CreateTraceResult struct { // Do not change the ordering of these fields -- allows for easier comparison with other clients - Address *common.Address `json:"address,omitempty"` - Code hexutil.Bytes `json:"code"` - GasUsed *hexutil.Big `json:"gasUsed"` + Address *common.Address `json:"address,omitempty"` + Code hexutility.Bytes `json:"code"` + GasUsed *hexutil.Big `json:"gasUsed"` } // TraceResult A parity formatted trace result type TraceResult struct { // Do not change the ordering of these fields -- allows for easier comparison with other clients - GasUsed *hexutil.Big `json:"gasUsed"` - Output hexutil.Bytes `json:"output"` + GasUsed *hexutil.Big `json:"gasUsed"` + Output hexutility.Bytes `json:"output"` } // Allows for easy printing of a geth trace for debugging diff --git a/cmd/rpcdaemon/commands/tracing.go b/cmd/rpcdaemon/commands/tracing.go index b92fc571eef..3d84f6aadb2 100644 --- a/cmd/rpcdaemon/commands/tracing.go +++ b/cmd/rpcdaemon/commands/tracing.go @@ -79,10 +79,23 @@ func (api *PrivateDebugAPIImpl) traceBlock(ctx context.Context, blockNrOrHash rp return err } + if config == nil { + config = &tracers.TraceConfig{} + } + if config.BorTraceEnabled == nil { config.BorTraceEnabled = newBoolPtr(false) } + var excessDataGas *big.Int + parentBlock, err := api.blockByHashWithSenders(tx, block.ParentHash()) + if err != nil { + stream.WriteNil() + return err + } + if parentBlock != nil { + excessDataGas = parentBlock.ExcessDataGas() + } chainConfig, err := api.chainConfig(tx) if err != nil { stream.WriteNil() @@ -120,7 +133,7 @@ func (api *PrivateDebugAPIImpl) traceBlock(ctx context.Context, blockNrOrHash rp if msg.FeeCap().IsZero() && engine != nil { syscall := func(contract common.Address, data []byte) ([]byte, error) { - return core.SysCallContract(contract, data, *chainConfig, ibs, block.Header(), engine, true /* constCall */) + return core.SysCallContract(contract, data, *chainConfig, ibs, block.Header(), engine, true /* constCall */, excessDataGas) } msg.SetIsFree(engine.IsServiceTransaction(msg.From(), syscall)) } @@ -229,7 +242,6 @@ func (api *PrivateDebugAPIImpl) TraceTransaction(ctx context.Context, hash commo var borTx types.Transaction borTx, _, _, _, err = rawdb.ReadBorTransaction(tx, hash) if err != nil { - stream.WriteNil() return err } @@ -323,6 +335,10 @@ func (api *PrivateDebugAPIImpl) TraceCallMany(ctx context.Context, bundles []Bun baseFee uint256.Int ) + if config == nil { + config = &tracers.TraceConfig{} + } + overrideBlockHash = make(map[uint64]common.Hash) tx, err := api.db.BeginRo(ctx) if err != nil { diff --git a/cmd/rpcdaemon/commands/txpool_api_test.go b/cmd/rpcdaemon/commands/txpool_api_test.go index 9a1b0dd7d11..8bb1e9134e8 100644 --- a/cmd/rpcdaemon/commands/txpool_api_test.go +++ b/cmd/rpcdaemon/commands/txpool_api_test.go @@ -25,9 +25,6 @@ import ( func TestTxPoolContent(t *testing.T) { m, require := stages.MockWithTxPool(t), require.New(t) - if m.HistoryV3 { - t.Skip("HistoryV3: please implement StateStream support") - } chain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 1, func(i int, b *core.BlockGen) { b.SetCoinbase(libcommon.Address{1}) }, false /* intermediateHashes */) diff --git a/cmd/rpcdaemon/commands/web3_api.go b/cmd/rpcdaemon/commands/web3_api.go index c35f62c632e..d66e99da5ed 100644 --- a/cmd/rpcdaemon/commands/web3_api.go +++ b/cmd/rpcdaemon/commands/web3_api.go @@ -3,7 +3,8 @@ package commands import ( "context" - "github.com/ledgerwatch/erigon/common/hexutil" + "github.com/ledgerwatch/erigon-lib/common/hexutility" + "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/turbo/rpchelper" ) @@ -11,7 +12,7 @@ import ( // Web3API provides interfaces for the web3_ RPC commands type Web3API interface { ClientVersion(_ context.Context) (string, error) - Sha3(_ context.Context, input hexutil.Bytes) hexutil.Bytes + Sha3(_ context.Context, input hexutility.Bytes) hexutility.Bytes } type Web3APIImpl struct { @@ -33,6 +34,6 @@ func (api *Web3APIImpl) ClientVersion(ctx context.Context) (string, error) { } // Sha3 implements web3_sha3. Returns Keccak-256 (not the standardized SHA3-256) of the given data. -func (api *Web3APIImpl) Sha3(_ context.Context, input hexutil.Bytes) hexutil.Bytes { +func (api *Web3APIImpl) Sha3(_ context.Context, input hexutility.Bytes) hexutility.Bytes { return crypto.Keccak256(input) } diff --git a/cmd/rpcdaemon/graphql/graph/helpers.go b/cmd/rpcdaemon/graphql/graph/helpers.go index 5d7b8cd9e26..64a76183d41 100644 --- a/cmd/rpcdaemon/graphql/graph/helpers.go +++ b/cmd/rpcdaemon/graphql/graph/helpers.go @@ -7,7 +7,10 @@ import ( "strconv" "github.com/holiman/uint256" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" + "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/core/types" ) @@ -24,7 +27,7 @@ func convertDataToStringP(abstractMap map[string]interface{}, field string) *str result = strconv.FormatInt(v, 10) case *hexutil.Big: result = v.String() - case hexutil.Bytes: + case hexutility.Bytes: result = v.String() case hexutil.Uint: result = v.String() diff --git a/cmd/rpcdaemon/main.go b/cmd/rpcdaemon/main.go index e4d58612d9b..3db874b5106 100644 --- a/cmd/rpcdaemon/main.go +++ b/cmd/rpcdaemon/main.go @@ -17,8 +17,8 @@ func main() { rootCtx, rootCancel := common.RootContext() cmd.RunE = func(cmd *cobra.Command, args []string) error { ctx := cmd.Context() - logger := logging.GetLoggerCmd("rpcdaemon", cmd) - db, borDb, backend, txPool, mining, stateCache, blockReader, ff, agg, err := cli.RemoteServices(ctx, *cfg, logger, rootCancel) + logging.SetupLoggerCmd("rpcdaemon", cmd) + db, borDb, backend, txPool, mining, stateCache, blockReader, ff, agg, err := cli.RemoteServices(ctx, *cfg, log.Root(), rootCancel) if err != nil { log.Error("Could not connect to DB", "err", err) return nil diff --git a/cmd/rpcdaemon/rpcservices/eth_backend.go b/cmd/rpcdaemon/rpcservices/eth_backend.go index bbd0e4f7ac0..4fe9ba8500f 100644 --- a/cmd/rpcdaemon/rpcservices/eth_backend.go +++ b/cmd/rpcdaemon/rpcservices/eth_backend.go @@ -220,6 +220,12 @@ func (back *RemoteBackend) EngineGetPayloadBodiesByRangeV1(ctx context.Context, return back.remoteEthBackend.EngineGetPayloadBodiesByRangeV1(ctx, request) } +func (back *RemoteBackend) EngineGetBlobsBundleV1(ctx context.Context, payloadId uint64) (*types2.BlobsBundleV1, error) { + return back.remoteEthBackend.EngineGetBlobsBundleV1(ctx, &remote.EngineGetBlobsBundleRequest{ + PayloadId: payloadId, + }) +} + func (back *RemoteBackend) NodeInfo(ctx context.Context, limit uint32) ([]p2p.NodeInfo, error) { nodes, err := back.remoteEthBackend.NodeInfo(ctx, &remote.NodesInfoRequest{Limit: limit}) if err != nil { diff --git a/cmd/rpctest/rpctest/bench_tracecallmany.go b/cmd/rpctest/rpctest/bench_tracecallmany.go index 69b86136d6d..a3599af7c0c 100644 --- a/cmd/rpctest/rpctest/bench_tracecallmany.go +++ b/cmd/rpctest/rpctest/bench_tracecallmany.go @@ -8,6 +8,7 @@ import ( "time" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common/hexutil" ) @@ -80,7 +81,7 @@ func BenchTraceCallMany(erigonURL, oeURL string, needCompare bool, blockFrom uin gas := make([]*hexutil.Big, n) gasPrice := make([]*hexutil.Big, n) value := make([]*hexutil.Big, n) - data := make([]hexutil.Bytes, n) + data := make([]hexutility.Bytes, n) for i := 0; i < n; i++ { tx := b.Result.Transactions[i] diff --git a/cmd/rpctest/rpctest/request_generator.go b/cmd/rpctest/rpctest/request_generator.go index 4b5b9aaafb9..b5936b8980a 100644 --- a/cmd/rpctest/rpctest/request_generator.go +++ b/cmd/rpctest/rpctest/request_generator.go @@ -7,9 +7,11 @@ import ( "strings" "time" - libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/valyala/fastjson" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" + "github.com/ledgerwatch/erigon/common/hexutil" ) @@ -97,7 +99,7 @@ func (g *RequestGenerator) getProof(bn uint64, account libcommon.Address, storag return fmt.Sprintf(template, account, strings.Join(storageStr, ","), bn, g.reqID) } -func (g *RequestGenerator) traceCall(from libcommon.Address, to *libcommon.Address, gas *hexutil.Big, gasPrice *hexutil.Big, value *hexutil.Big, data hexutil.Bytes, bn uint64) string { +func (g *RequestGenerator) traceCall(from libcommon.Address, to *libcommon.Address, gas *hexutil.Big, gasPrice *hexutil.Big, value *hexutil.Big, data hexutility.Bytes, bn uint64) string { var sb strings.Builder fmt.Fprintf(&sb, `{ "jsonrpc": "2.0", "method": "trace_call", "params": [{"from":"0x%x"`, from) if to != nil { @@ -120,7 +122,7 @@ func (g *RequestGenerator) traceCall(from libcommon.Address, to *libcommon.Addre return sb.String() } -func (g *RequestGenerator) traceCallMany(from []libcommon.Address, to []*libcommon.Address, gas []*hexutil.Big, gasPrice []*hexutil.Big, value []*hexutil.Big, data []hexutil.Bytes, bn uint64) string { +func (g *RequestGenerator) traceCallMany(from []libcommon.Address, to []*libcommon.Address, gas []*hexutil.Big, gasPrice []*hexutil.Big, value []*hexutil.Big, data []hexutility.Bytes, bn uint64) string { var sb strings.Builder fmt.Fprintf(&sb, `{ "jsonrpc": "2.0", "method": "trace_callMany", "params": [[`) for i, f := range from { @@ -149,7 +151,7 @@ func (g *RequestGenerator) traceCallMany(from []libcommon.Address, to []*libcomm return sb.String() } -func (g *RequestGenerator) debugTraceCall(from libcommon.Address, to *libcommon.Address, gas *hexutil.Big, gasPrice *hexutil.Big, value *hexutil.Big, data hexutil.Bytes, bn uint64) string { +func (g *RequestGenerator) debugTraceCall(from libcommon.Address, to *libcommon.Address, gas *hexutil.Big, gasPrice *hexutil.Big, value *hexutil.Big, data hexutility.Bytes, bn uint64) string { var sb strings.Builder fmt.Fprintf(&sb, `{ "jsonrpc": "2.0", "method": "debug_traceCall", "params": [{"from":"0x%x"`, from) if to != nil { @@ -197,7 +199,7 @@ func (g *RequestGenerator) traceReplayTransaction(hash string) string { return fmt.Sprintf(template, hash, g.reqID) } -func (g *RequestGenerator) ethCall(from libcommon.Address, to *libcommon.Address, gas *hexutil.Big, gasPrice *hexutil.Big, value *hexutil.Big, data hexutil.Bytes, bn uint64) string { +func (g *RequestGenerator) ethCall(from libcommon.Address, to *libcommon.Address, gas *hexutil.Big, gasPrice *hexutil.Big, value *hexutil.Big, data hexutility.Bytes, bn uint64) string { var sb strings.Builder fmt.Fprintf(&sb, `{ "jsonrpc": "2.0", "method": "eth_call", "params": [{"from":"0x%x"`, from) if to != nil { @@ -219,7 +221,7 @@ func (g *RequestGenerator) ethCall(from libcommon.Address, to *libcommon.Address return sb.String() } -func (g *RequestGenerator) ethCallLatest(from libcommon.Address, to *libcommon.Address, gas *hexutil.Big, gasPrice *hexutil.Big, value *hexutil.Big, data hexutil.Bytes) string { +func (g *RequestGenerator) ethCallLatest(from libcommon.Address, to *libcommon.Address, gas *hexutil.Big, gasPrice *hexutil.Big, value *hexutil.Big, data hexutility.Bytes) string { var sb strings.Builder fmt.Fprintf(&sb, `{ "jsonrpc": "2.0", "method": "eth_call", "params": [{"from":"0x%x"`, from) if to != nil { diff --git a/cmd/rpctest/rpctest/type.go b/cmd/rpctest/rpctest/type.go index 64af871d364..134bbbd1b7b 100644 --- a/cmd/rpctest/rpctest/type.go +++ b/cmd/rpctest/rpctest/type.go @@ -4,6 +4,7 @@ import ( "fmt" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/core/state" @@ -39,7 +40,7 @@ type EthTransaction struct { Hash string `json:"hash"` Gas hexutil.Big `json:"gas"` GasPrice hexutil.Big `json:"gasPrice"` - Input hexutil.Bytes `json:"input"` + Input hexutility.Bytes `json:"input"` Value hexutil.Big `json:"value"` } @@ -96,7 +97,7 @@ type TraceCall struct { } type TraceCallResult struct { - Output hexutil.Bytes `json:"output"` + Output hexutility.Bytes `json:"output"` Trace []TraceCallTrace `json:"trace"` StateDiff map[libcommon.Address]TraceCallStateDiff `json:"stateDiff"` } @@ -119,16 +120,16 @@ type TraceCallAction struct { Gas hexutil.Big `json:"gas"` Value hexutil.Big `json:"value"` Balance hexutil.Big `json:"balance"` - Init hexutil.Bytes `json:"init"` - Input hexutil.Bytes `json:"input"` + Init hexutility.Bytes `json:"init"` + Input hexutility.Bytes `json:"input"` CallType string `json:"callType"` } type TraceCallTraceResult struct { GasUsed hexutil.Big `json:"gasUsed"` - Output hexutil.Bytes `json:"output"` + Output hexutility.Bytes `json:"output"` Address libcommon.Address `json:"address"` - Code hexutil.Bytes `json:"code"` + Code hexutility.Bytes `json:"code"` } type TraceCallStateDiff struct { @@ -191,7 +192,7 @@ type Log struct { //nolint // list of topics provided by the contract. Topics []libcommon.Hash `json:"topics" gencodec:"required"` // supplied by the contract, usually ABI-encoded - Data hexutil.Bytes `json:"data" gencodec:"required"` + Data hexutility.Bytes `json:"data" gencodec:"required"` // Derived fields. These fields are filled in by the node // but not secured by consensus. @@ -213,11 +214,11 @@ type Log struct { //nolint type Receipt struct { // Consensus fields - PostState libcommon.Hash `json:"root"` - Status hexutil.Uint64 `json:"status"` - CumulativeGasUsed hexutil.Uint64 `json:"cumulativeGasUsed" gencodec:"required"` - Bloom hexutil.Bytes `json:"logsBloom" gencodec:"required"` - Logs []*Log `json:"logs" gencodec:"required"` + PostState libcommon.Hash `json:"root"` + Status hexutil.Uint64 `json:"status"` + CumulativeGasUsed hexutil.Uint64 `json:"cumulativeGasUsed" gencodec:"required"` + Bloom hexutility.Bytes `json:"logsBloom" gencodec:"required"` + Logs []*Log `json:"logs" gencodec:"required"` // Implementation fields (don't reorder!) TxHash libcommon.Hash `json:"transactionHash" gencodec:"required"` @@ -263,5 +264,5 @@ type StorageResult struct { type ParityListStorageKeysResult struct { CommonResponse - Result []hexutil.Bytes `json:"result"` + Result []hexutility.Bytes `json:"result"` } diff --git a/cmd/sentinel/cli/cliSettings.go b/cmd/sentinel/cli/cliSettings.go index 177f68a178b..2dd22d7140a 100644 --- a/cmd/sentinel/cli/cliSettings.go +++ b/cmd/sentinel/cli/cliSettings.go @@ -2,13 +2,14 @@ package cli import ( "fmt" - "strings" + "github.com/ledgerwatch/erigon/cmd/utils" "github.com/urfave/cli/v2" "github.com/ledgerwatch/erigon/cl/clparams" "github.com/ledgerwatch/erigon/cmd/erigon-cl/core/rawdb" "github.com/ledgerwatch/erigon/cmd/sentinel/cli/flags" + "github.com/ledgerwatch/log/v3" ) type ConsensusClientCliCfg struct { @@ -60,6 +61,9 @@ func SetupConsensusClientCfg(ctx *cli.Context) (*ConsensusClientCliCfg, error) { cfg.Addr = ctx.String(flags.SentinelDiscoveryAddr.Name) cfg.LogLvl = ctx.Uint(flags.Verbosity.Name) + if cfg.LogLvl == uint(log.LvlInfo) { + cfg.LogLvl = uint(log.LvlDebug) + } cfg.NoDiscovery = ctx.Bool(flags.NoDiscovery.Name) if ctx.String(flags.CheckpointSyncUrlFlag.Name) != "" { cfg.CheckpointUri = ctx.String(flags.CheckpointSyncUrlFlag.Name) @@ -71,10 +75,10 @@ func SetupConsensusClientCfg(ctx *cli.Context) (*ConsensusClientCliCfg, error) { cfg.BeaconDataCfg = rawdb.BeaconDataConfigurations[ctx.String(flags.BeaconDBModeFlag.Name)] // Process bootnodes if ctx.String(flags.BootnodesFlag.Name) != "" { - cfg.NetworkCfg.BootNodes = strings.Split(ctx.String(flags.BootnodesFlag.Name), ",") + cfg.NetworkCfg.BootNodes = utils.SplitAndTrim(ctx.String(flags.BootnodesFlag.Name)) } if ctx.String(flags.SentinelStaticPeersFlag.Name) != "" { - cfg.NetworkCfg.StaticPeers = strings.Split(ctx.String(flags.SentinelStaticPeersFlag.Name), ",") + cfg.NetworkCfg.StaticPeers = utils.SplitAndTrim(ctx.String(flags.SentinelStaticPeersFlag.Name)) } return cfg, nil } diff --git a/cmd/sentinel/main.go b/cmd/sentinel/main.go index 601a00be2bd..d06a4d349ff 100644 --- a/cmd/sentinel/main.go +++ b/cmd/sentinel/main.go @@ -15,26 +15,16 @@ package main import ( "context" - "encoding/hex" "fmt" "os" - "time" "github.com/ledgerwatch/log/v3" "github.com/urfave/cli/v2" - "go.uber.org/zap/buffer" - sentinelrpc "github.com/ledgerwatch/erigon-lib/gointerfaces/sentinel" - "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/cl/cltypes/ssz_utils" - "github.com/ledgerwatch/erigon/cl/fork" lcCli "github.com/ledgerwatch/erigon/cmd/sentinel/cli" "github.com/ledgerwatch/erigon/cmd/sentinel/cli/flags" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel" - "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/communication/ssz_snappy" - "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/handshake" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/service" - "github.com/ledgerwatch/erigon/common" sentinelapp "github.com/ledgerwatch/erigon/turbo/app" ) @@ -49,34 +39,8 @@ func main() { } } -func check(err error) { - if err != nil { - panic(err) - } -} - -func constructBodyFreeRequest(t string) *sentinelrpc.RequestData { - return &sentinelrpc.RequestData{ - Topic: t, - } -} - -func constructRequest(t string, reqBody ssz_utils.EncodableSSZ) (*sentinelrpc.RequestData, error) { - var buffer buffer.Buffer - if err := ssz_snappy.EncodeAndWrite(&buffer, reqBody); err != nil { - return nil, fmt.Errorf("unable to encode request body: %v", err) - } - - data := common.CopyBytes(buffer.Bytes()) - return &sentinelrpc.RequestData{ - Data: data, - Topic: t, - }, nil -} - func runSentinelNode(cliCtx *cli.Context) error { cfg, _ := lcCli.SetupConsensusClientCfg(cliCtx) - //ctx := context.Background() log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(cfg.LogLvl), log.StderrHandler)) log.Info("[Sentinel] running sentinel with configuration", "cfg", cfg) @@ -88,163 +52,13 @@ func runSentinelNode(cliCtx *cli.Context) error { NetworkConfig: cfg.NetworkCfg, BeaconConfig: cfg.BeaconCfg, NoDiscovery: cfg.NoDiscovery, - }, nil, &service.ServerConfig{Network: cfg.ServerProtocol, Addr: cfg.ServerAddr}, nil, nil, handshake.NoRule) + }, nil, &service.ServerConfig{Network: cfg.ServerProtocol, Addr: cfg.ServerAddr}, nil, nil) if err != nil { log.Error("[Sentinel] Could not start sentinel", "err", err) return err } log.Info("[Sentinel] Sentinel started", "addr", cfg.ServerAddr) - digest, err := fork.ComputeForkDigest(cfg.BeaconCfg, cfg.GenesisCfg) - if err != nil { - log.Error("[Sentinel] Could not compute fork digeest", "err", err) - return err - } - log.Info("[Sentinel] Fork digest", "data", digest) - - log.Info("[Sentinel] Sending test request") - /* - sendRequest(ctx, s, constructBodyFreeRequest(handlers.LightClientFinalityUpdateV1)) - sendRequest(ctx, s, constructBodyFreeRequest(handlers.MetadataProtocolV1)) - sendRequest(ctx, s, constructBodyFreeRequest(handlers.MetadataProtocolV2)) - sendRequest(ctx, s, constructBodyFreeRequest(handlers.LightClientOptimisticUpdateV1)) - - lcUpdateReq := &cltypes.LightClientUpdatesByRangeRequest{ - Period: 604, - Count: 1, - } - - blocksByRangeReq := &cltypes.BeaconBlocksByRangeRequest{ - StartSlot: 5000005, // arbitrary slot (currently at ~5030000) - Count: 3, - Step: 1, // deprecated, must be set to 1. - } - - roots := make([][32]byte, 3) - rawRoot1, err := hex.DecodeString("57dd8e0ee7ed614283fbf80ca19229752839d4a4e232148efd128e85edee9b12") - check(err) - rawRoot2, err := hex.DecodeString("1d527f21e17897198752838431821558d1b9864654bcaf476232da55458ed5ce") - check(err) - rawRoot3, err := hex.DecodeString("830eab2e3de70cc7ebc80b6c950ebb2a7946d8a6e3bb653f8b6dafd6a402d49b") - check(err) - - copy(roots[0][:], rawRoot1) - copy(roots[1][:], rawRoot2) - copy(roots[2][:], rawRoot3) - - var blocksByRootReq cltypes.BeaconBlocksByRootRequest = roots - - // Getting fork digest into bytes array. - forkDigest := "4a26c58b" - fdSlice, err := hex.DecodeString(forkDigest) - check(err) - var fdArr [4]byte - copy(fdArr[:], fdSlice) - - // Getting CP block root into bytes array. - cpRootRaw := "60ee0f7170ed4984e4a7e735dff36bce28d2fb03a3f698287b73415d70fe7355" - cpRootSlice, err := hex.DecodeString(cpRootRaw) - check(err) - var cpRootArr [32]byte - copy(cpRootArr[:], cpRootSlice) - - // Getting head block root into bytes array. - headRootRaw := "b52fc95e02471414451e6cf465709f53f65145fc5efbb18817252c33e301fa3a" - headRootSlice, err := hex.DecodeString(headRootRaw) - check(err) - var headRootArr [32]byte - copy(headRootArr[:], headRootSlice) - - // USING: https://beaconcha.in/slot/5101760 as the checkpoint & current block. - statusReq := &cltypes.Status{ - ForkDigest: fdArr, - FinalizedRoot: cpRootArr, - FinalizedEpoch: 160285, - HeadRoot: headRootArr, - HeadSlot: 5129184, - } - - blocksByRangeReq := &cltypes.BeaconBlocksByRangeRequest{ - StartSlot: 5142800, - Count: 2, - Step: 1, // deprecated, must be set to 1. - } - req, err := constructRequest(handlers.BeaconBlocksByRangeProtocolV2, blocksByRangeReq) - if err != nil { - log.Error("[Sentinel] could not construct request", "err", err) - } - sendRequest(ctx, s, req) - */ - /*roots := make([][32]byte, 1) - rawRoot1, err := hex.DecodeString("cc85056af7f6e3e4835436cb12a09a9d56e0aac15d08436af82dbe0cd7ae60e0") - check(err) - - copy(roots[0][:], rawRoot1) - - var blocksByRootReq cltypes.BeaconBlocksByRootRequest = roots - req, err := constructRequest(communication.BeaconBlocksByRootProtocolV2, &blocksByRootReq) - if err != nil { - log.Error("[Sentinel] could not construct request", "err", err) - return err - } - sendRequest(ctx, s, req)*/ + <-context.Background().Done() return nil } - -func debugGossip(ctx context.Context, s sentinelrpc.SentinelClient) { - subscription, err := s.SubscribeGossip(ctx, &sentinelrpc.EmptyMessage{}) - if err != nil { - log.Error("[Sentinel] Could not start sentinel", "err", err) - return - } - for { - data, err := subscription.Recv() - if err != nil { - return - } - if data.Type != sentinelrpc.GossipType_AggregateAndProofGossipType { - continue - } - block := &cltypes.SignedAggregateAndProof{} - if err := block.DecodeSSZ(data.Data); err != nil { - log.Error("[Sentinel] Error", "err", err) - continue - } - log.Info("[Sentinel] Received", "msg", block) - } -} - -// Debug function to recieve test packets on the req/resp domain. -func sendRequest(ctx context.Context, s sentinelrpc.SentinelClient, req *sentinelrpc.RequestData) { - newReqTicker := time.NewTicker(100 * time.Millisecond) - for { - select { - case <-ctx.Done(): - case <-newReqTicker.C: - go func() { - log.Info("[Sentinel] Sending request", "data", req) - message, err := s.SendRequest(ctx, req) - if err != nil { - log.Error("[Sentinel] Error returned", "err", err) - return - } - if message.Error { - log.Error("[Sentinel] received error", "err", string(message.Data)) - return - } - - log.Info("[Sentinel] Non-error response received", "data", message.Data) - f, err := os.Create("out") - if err != nil { - panic(fmt.Sprintf("unable to open file: %v\n", err)) - } - _, err = f.WriteString(hex.EncodeToString(message.Data)) - if err != nil { - panic(fmt.Sprintf("unable to write to file: %v\n", err)) - } - log.Info("[Sentinel] Hex representation", "data", hex.EncodeToString(message.Data)) - f.Close() - }() - } - } -} diff --git a/cmd/sentinel/sentinel/discovery.go b/cmd/sentinel/sentinel/discovery.go index 94efb11b900..51d9f355c9a 100644 --- a/cmd/sentinel/sentinel/discovery.go +++ b/cmd/sentinel/sentinel/discovery.go @@ -78,8 +78,8 @@ func (s *Sentinel) listenForPeers() { iterator := s.listener.RandomNodes() defer iterator.Close() for { - - if s.ctx.Err() != nil { + if err := s.ctx.Err(); err != nil { + log.Debug("Stopping Ethereum 2.0 peer discovery", "err", err) break } if s.HasTooManyPeers() { @@ -89,7 +89,7 @@ func (s *Sentinel) listenForPeers() { } exists := iterator.Next() if !exists { - break + continue } node := iterator.Node() peerInfo, _, err := convertToAddrInfo(node) diff --git a/cmd/sentinel/sentinel/handlers/blocks.go b/cmd/sentinel/sentinel/handlers/blocks.go index 107a7477a7b..07525bd1d4f 100644 --- a/cmd/sentinel/sentinel/handlers/blocks.go +++ b/cmd/sentinel/sentinel/handlers/blocks.go @@ -20,8 +20,12 @@ import ( func (c *ConsensusHandlers) blocksByRangeHandler(stream network.Stream) { log.Trace("Got block by range handler call") + stream.Write([]byte{0x3}) + stream.Close() } func (c *ConsensusHandlers) beaconBlocksByRootHandler(stream network.Stream) { log.Trace("Got beacon block by root handler call") + stream.Write([]byte{0x3}) + stream.Close() } diff --git a/cmd/sentinel/sentinel/handlers/handlers.go b/cmd/sentinel/sentinel/handlers/handlers.go index 738636ba401..c0b12a92dd8 100644 --- a/cmd/sentinel/sentinel/handlers/handlers.go +++ b/cmd/sentinel/sentinel/handlers/handlers.go @@ -62,8 +62,6 @@ func NewConsensusHandlers(ctx context.Context, db kv.RoDB, host host.Host, protocol.ID(communication.MetadataProtocolV2): c.metadataV2Handler, protocol.ID(communication.BeaconBlocksByRangeProtocolV1): c.blocksByRangeHandler, protocol.ID(communication.BeaconBlocksByRootProtocolV1): c.beaconBlocksByRootHandler, - protocol.ID(communication.LightClientFinalityUpdateV1): c.lightClientFinalityUpdateHandler, - protocol.ID(communication.LightClientOptimisticUpdateV1): c.lightClientOptimisticUpdateHandler, } return c } diff --git a/cmd/sentinel/sentinel/handshake/handshake.go b/cmd/sentinel/sentinel/handshake/handshake.go index 96a134ab7e7..8d9f9f61c52 100644 --- a/cmd/sentinel/sentinel/handshake/handshake.go +++ b/cmd/sentinel/sentinel/handshake/handshake.go @@ -7,6 +7,7 @@ import ( "github.com/ledgerwatch/erigon/cl/clparams" "github.com/ledgerwatch/erigon/cl/cltypes" + "github.com/ledgerwatch/erigon/cl/fork" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/communication" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/communication/ssz_snappy" "github.com/ledgerwatch/erigon/common" @@ -22,7 +23,6 @@ type HandShaker struct { // Status object to send over. status *cltypes.Status // Contains status object for handshakes set bool - rule RuleFunc // Method that determine if peer is worth connecting to or not. host host.Host genesisConfig *clparams.GenesisConfig beaconConfig *clparams.BeaconChainConfig @@ -30,10 +30,9 @@ type HandShaker struct { mu sync.Mutex } -func New(ctx context.Context, genesisConfig *clparams.GenesisConfig, beaconConfig *clparams.BeaconChainConfig, host host.Host, rule RuleFunc) *HandShaker { +func New(ctx context.Context, genesisConfig *clparams.GenesisConfig, beaconConfig *clparams.BeaconChainConfig, host host.Host) *HandShaker { return &HandShaker{ ctx: ctx, - rule: rule, host: host, genesisConfig: genesisConfig, beaconConfig: beaconConfig, @@ -86,5 +85,9 @@ func (h *HandShaker) ValidatePeer(id peer.ID) bool { if err := ssz_snappy.DecodeAndReadNoForkDigest(bytes.NewReader(response), responseStatus, clparams.Phase0Version); err != nil { return false } - return h.rule(responseStatus, status, h.genesisConfig, h.beaconConfig) + forkDigest, err := fork.ComputeForkDigest(h.beaconConfig, h.genesisConfig) + if err != nil { + return false + } + return responseStatus.ForkDigest == forkDigest } diff --git a/cmd/sentinel/sentinel/handshake/rules.go b/cmd/sentinel/sentinel/handshake/rules.go deleted file mode 100644 index 6a385f041df..00000000000 --- a/cmd/sentinel/sentinel/handshake/rules.go +++ /dev/null @@ -1,44 +0,0 @@ -package handshake - -import ( - "github.com/ledgerwatch/erigon/cl/clparams" - "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/cl/fork" - "github.com/ledgerwatch/erigon/cl/utils" -) - -type RuleFunc func( - status *cltypes.Status, - ourStatus *cltypes.Status, - genesisConfig *clparams.GenesisConfig, - beaconConfig *clparams.BeaconChainConfig, -) bool - -// NoRule no rules in place. -func NoRule(status *cltypes.Status, ourStatus *cltypes.Status, genesisConfig *clparams.GenesisConfig, beaconConfig *clparams.BeaconChainConfig) bool { - return true -} - -// FullClientRule only checks against fork digest. -func FullClientRule(status *cltypes.Status, ourStatus *cltypes.Status, genesisConfig *clparams.GenesisConfig, beaconConfig *clparams.BeaconChainConfig) bool { - forkDigest, err := fork.ComputeForkDigest(beaconConfig, genesisConfig) - if err != nil { - return false - } - - accept := status.ForkDigest == forkDigest - if ourStatus.HeadSlot != utils.GetCurrentSlot(genesisConfig.GenesisTime, beaconConfig.SecondsPerSlot) { - accept = accept && ourStatus.HeadSlot < status.HeadSlot - } - return accept -} - -// LightClientRule checks against fork digest and whether the peer head is on chain tip. -func LightClientRule(status *cltypes.Status, ourStatus *cltypes.Status, genesisConfig *clparams.GenesisConfig, beaconConfig *clparams.BeaconChainConfig) bool { - forkDigest, err := fork.ComputeForkDigest(beaconConfig, genesisConfig) - if err != nil { - return false - } - return status.ForkDigest == forkDigest && - status.HeadSlot == utils.GetCurrentSlot(genesisConfig.GenesisTime, beaconConfig.SecondsPerSlot) -} diff --git a/cmd/sentinel/sentinel/msg_id.go b/cmd/sentinel/sentinel/msg_id.go new file mode 100644 index 00000000000..bf584681d1f --- /dev/null +++ b/cmd/sentinel/sentinel/msg_id.go @@ -0,0 +1,60 @@ +package sentinel + +import ( + "github.com/ledgerwatch/erigon/cl/utils" + pubsubpb "github.com/libp2p/go-libp2p-pubsub/pb" +) + +// Spec:BeaconConfig() +// The derivation of the message-id has changed starting with Altair to incorporate the message topic along with the message data. +// These are fields of the Message Protobuf, and interpreted as empty byte strings if missing. The message-id MUST be the following +// 20 byte value computed from the message: +// +// If message.data has a valid snappy decompression, set message-id to the first 20 bytes of the SHA256 hash of the concatenation of +// the following data: MESSAGE_DOMAIN_VALID_SNAPPY, the length of the topic byte string (encoded as little-endian uint64), the topic +// byte string, and the snappy decompressed message data: i.e. SHA256(MESSAGE_DOMAIN_VALID_SNAPPY + uint_to_bytes(uint64(len(message.topic))) +// + message.topic + snappy_decompress(message.data))[:20]. Otherwise, set message-id to the first 20 bytes of the SHA256 hash of the concatenation +// of the following data: MESSAGE_DOMAIN_INVALID_SNAPPY, the length of the topic byte string (encoded as little-endian uint64), +// the topic byte string, and the raw message data: i.e. SHA256(MESSAGE_DOMAIN_INVALID_SNAPPY + uint_to_bytes(uint64(len(message.topic))) + message.topic + message.data)[:20]. +func (s *Sentinel) msgId(pmsg *pubsubpb.Message) string { + topic := *pmsg.Topic + topicLen := len(topic) + topicLenBytes := utils.Uint64ToLE(uint64(topicLen)) // topicLen cannot be negative + + // beyond Bellatrix epoch, allow 10 Mib gossip data size + gossipPubSubSize := s.cfg.NetworkConfig.GossipMaxSizeBellatrix + + decodedData, err := utils.DecompressSnappy(pmsg.Data) + if err != nil || uint64(len(decodedData)) > gossipPubSubSize { + totalLength := + len(s.cfg.NetworkConfig.MessageDomainValidSnappy) + + len(topicLenBytes) + + topicLen + + len(pmsg.Data) + if uint64(totalLength) > gossipPubSubSize { + // this should never happen + msg := make([]byte, 20) + copy(msg, "invalid") + return string(msg) + } + combinedData := make([]byte, 0, totalLength) + combinedData = append(combinedData, s.cfg.NetworkConfig.MessageDomainInvalidSnappy[:]...) + combinedData = append(combinedData, topicLenBytes...) + combinedData = append(combinedData, topic...) + combinedData = append(combinedData, pmsg.Data...) + h := utils.Keccak256(combinedData) + return string(h[:20]) + } + totalLength := len(s.cfg.NetworkConfig.MessageDomainValidSnappy) + + len(topicLenBytes) + + topicLen + + len(decodedData) + + combinedData := make([]byte, 0, totalLength) + combinedData = append(combinedData, s.cfg.NetworkConfig.MessageDomainValidSnappy[:]...) + combinedData = append(combinedData, topicLenBytes...) + combinedData = append(combinedData, topic...) + combinedData = append(combinedData, decodedData...) + h := utils.Keccak256(combinedData) + return string(h[:20]) +} diff --git a/cmd/sentinel/sentinel/msg_id_test.go b/cmd/sentinel/sentinel/msg_id_test.go new file mode 100644 index 00000000000..d8313aeb8cb --- /dev/null +++ b/cmd/sentinel/sentinel/msg_id_test.go @@ -0,0 +1,50 @@ +package sentinel + +import ( + "context" + "fmt" + "testing" + + "github.com/golang/snappy" + "github.com/ledgerwatch/erigon/cl/clparams" + "github.com/ledgerwatch/erigon/cl/utils" + pubsubpb "github.com/libp2p/go-libp2p-pubsub/pb" + "github.com/stretchr/testify/require" +) + +func TestMsgID(t *testing.T) { + g := clparams.GenesisConfigs[clparams.MainnetNetwork] + n := clparams.NetworkConfigs[clparams.MainnetNetwork] + s := &Sentinel{ + ctx: context.TODO(), + cfg: &SentinelConfig{ + BeaconConfig: &clparams.MainnetBeaconConfig, + GenesisConfig: &g, + NetworkConfig: &n, + }, + } + d := [4]byte{108, 122, 33, 65} + tpc := fmt.Sprintf("/eth2/%x/beacon_block", d) + topicLen := uint64(len(tpc)) + topicLenBytes := utils.Uint64ToLE(topicLen) + invalidSnappy := [32]byte{'J', 'U', 'N', 'K'} + pMsg := &pubsubpb.Message{Data: invalidSnappy[:], Topic: &tpc} + // Create object to hash + combinedObj := append(n.MessageDomainInvalidSnappy[:], topicLenBytes...) + combinedObj = append(combinedObj, tpc...) + combinedObj = append(combinedObj, pMsg.Data...) + hashedData := utils.Keccak256(combinedObj) + msgID := string(hashedData[:20]) + require.Equal(t, msgID, s.msgId(pMsg), "Got incorrect msg id") + + validObj := [32]byte{'v', 'a', 'l', 'i', 'd'} + enc := snappy.Encode(nil, validObj[:]) + nMsg := &pubsubpb.Message{Data: enc, Topic: &tpc} + // Create object to hash + combinedObj = append(n.MessageDomainValidSnappy[:], topicLenBytes...) + combinedObj = append(combinedObj, tpc...) + combinedObj = append(combinedObj, validObj[:]...) + hashedData = utils.Keccak256(combinedObj) + msgID = string(hashedData[:20]) + require.Equal(t, msgID, s.msgId(nMsg), "Got incorrect msg id") +} diff --git a/cmd/sentinel/sentinel/peers/peers.go b/cmd/sentinel/sentinel/peers/peers.go index 1e2859b091f..3c040f8782e 100644 --- a/cmd/sentinel/sentinel/peers/peers.go +++ b/cmd/sentinel/sentinel/peers/peers.go @@ -17,7 +17,7 @@ import ( "sync" "time" - lru2 "github.com/hashicorp/golang-lru/v2" + lru "github.com/hashicorp/golang-lru/v2" "github.com/ledgerwatch/log/v3" "github.com/libp2p/go-libp2p/core/host" "github.com/libp2p/go-libp2p/core/peer" @@ -40,26 +40,26 @@ type Peer struct { } type Peers struct { - badPeers *lru2.Cache[peer.ID, int] // Keep track of bad peers - penalties *lru2.Cache[peer.ID, int] // Keep track on how many penalties a peer accumulated, PeerId => penalties - peerRecord *lru2.Cache[peer.ID, Peer] // Keep track of our peer statuses + badPeers *lru.Cache[peer.ID, int] // Keep track of bad peers + penalties *lru.Cache[peer.ID, int] // Keep track on how many penalties a peer accumulated, PeerId => penalties + peerRecord *lru.Cache[peer.ID, Peer] // Keep track of our peer statuses host host.Host mu sync.Mutex } func New(host host.Host) *Peers { - badPeers, err := lru2.New[peer.ID, int](maxBadPeers) + badPeers, err := lru.New[peer.ID, int](maxBadPeers) if err != nil { panic(err) } - penalties, err := lru2.New[peer.ID, int](maxBadPeers) + penalties, err := lru.New[peer.ID, int](maxBadPeers) if err != nil { panic(err) } - peerRecord, err := lru2.New[peer.ID, Peer](maxPeerRecordSize) + peerRecord, err := lru.New[peer.ID, Peer](maxPeerRecordSize) if err != nil { panic(err) } @@ -87,7 +87,6 @@ func (p *Peers) Penalize(pid peer.ID) { // Drop peer and delete the map element. if penalties > MaxBadResponses { p.DisconnectPeer(pid) - p.penalties.Remove(pid) } } @@ -113,6 +112,7 @@ func (p *Peers) DisconnectPeer(pid peer.ID) { log.Trace("[Sentinel Peers] disconnecting from peer", "peer-id", pid) p.host.Peerstore().RemovePeer(pid) p.host.Network().ClosePeer(pid) + p.penalties.Remove(pid) } // PeerDoRequest signals that the peer is doing a request. diff --git a/cmd/sentinel/sentinel/pubsub.go b/cmd/sentinel/sentinel/pubsub.go index 1dc805a0823..ddd0b51af2c 100644 --- a/cmd/sentinel/sentinel/pubsub.go +++ b/cmd/sentinel/sentinel/pubsub.go @@ -16,40 +16,14 @@ package sentinel import ( "context" "fmt" - "strconv" "strings" "sync" - "time" "github.com/ledgerwatch/erigon/cl/fork" "github.com/ledgerwatch/log/v3" pubsub "github.com/libp2p/go-libp2p-pubsub" ) -const ( - // overlay parameters - gossipSubD = 8 // topic stable mesh target count - gossipSubDlo = 6 // topic stable mesh low watermark - gossipSubDhi = 12 // topic stable mesh high watermark - - // gossip parameters - gossipSubMcacheLen = 6 // number of windows to retain full messages in cache for `IWANT` responses - gossipSubMcacheGossip = 3 // number of windows to gossip about - gossipSubSeenTTL = 550 // number of heartbeat intervals to retain message IDs - - // fanout ttl - gossipSubFanoutTTL = 60000000000 // TTL for fanout maps for topics we are not subscribed to but have published to, in nano seconds - - // heartbeat interval - gossipSubHeartbeatInterval = 700 * time.Millisecond // frequency of heartbeat, milliseconds - - // misc - rSubD = 8 // random gossip target -) - -// Specifies the prefix for any pubsub topic. -const gossipTopicPrefix = "/eth2/" -const blockSubnetTopicFormat = "/eth2/%x/beacon_block" const SSZSnappyCodec = "ssz_snappy" type TopicName string @@ -119,42 +93,12 @@ func (s *GossipManager) Recv() <-chan *pubsub.Message { return s.ch } -// closes a specific topic -func (s *GossipManager) CloseTopic(topic string) { - s.mu.Lock() - defer s.mu.Unlock() - if val, ok := s.subscriptions[topic]; ok { - val.Close() - delete(s.subscriptions, topic) - } -} - -// reset'em -func (s *GossipManager) Reset() { - s.mu.Lock() - defer s.mu.Unlock() - for _, val := range s.subscriptions { - val.Close() // Close all. - } - s.subscriptions = map[string]*GossipSubscription{} -} - -// get a specific topic -func (s *GossipManager) GetSubscription(topic string) (*GossipSubscription, bool) { - s.mu.Lock() - defer s.mu.Unlock() - if val, ok := s.subscriptions[topic]; ok { - return val, true - } - return nil, false -} - func (s *GossipManager) GetMatchingSubscription(match string) *GossipSubscription { s.mu.Lock() defer s.mu.Unlock() var sub *GossipSubscription for topic, currSub := range s.subscriptions { - if strings.Contains(topic, string(BeaconBlockTopic)) { + if strings.Contains(topic, match) { sub = currSub } } @@ -167,79 +111,43 @@ func (s *GossipManager) AddSubscription(topic string, sub *GossipSubscription) { s.subscriptions[topic] = sub } -// starts listening to a specific topic (forwarding its messages to the gossip manager channel) -func (s *GossipManager) ListenTopic(topic string) error { - s.mu.Lock() - defer s.mu.Unlock() - if val, ok := s.subscriptions[topic]; ok { - return val.Listen() - } - return nil -} - -// closes the gossip manager -func (s *GossipManager) Close() { - s.mu.Lock() - defer s.mu.Unlock() - for _, val := range s.subscriptions { - val.Close() - } - close(s.ch) -} - -func (s *GossipManager) String() string { +func (s *GossipManager) unsubscribe(topic string) { s.mu.Lock() defer s.mu.Unlock() - sb := strings.Builder{} - sb.Grow(len(s.subscriptions) * 4) - - for _, v := range s.subscriptions { - sb.Write([]byte(v.topic.String())) - sb.WriteString("=") - sb.WriteString(strconv.Itoa(len(v.topic.ListPeers()))) - sb.WriteString(" ") - } - return sb.String() -} - -func (s *Sentinel) RestartTopics() { - // Reset all topics - s.subManager.Reset() - for _, topic := range s.gossipTopics { - s.SubscribeGossip(topic) + if _, ok := s.subscriptions[topic]; !ok { + return } + s.subscriptions[topic].Close() + delete(s.subscriptions, topic) } func (s *Sentinel) SubscribeGossip(topic GossipTopic, opts ...pubsub.TopicOpt) (sub *GossipSubscription, err error) { + digest, err := fork.ComputeForkDigest(s.cfg.BeaconConfig, s.cfg.GenesisConfig) + if err != nil { + log.Error("[Gossip] Failed to calculate fork choice", "err", err) + } sub = &GossipSubscription{ gossip_topic: topic, ch: s.subManager.ch, host: s.host.ID(), ctx: s.ctx, } - path := s.getTopic(topic) + path := fmt.Sprintf("/eth2/%x/%s/%s", digest, topic.Name, topic.CodecStr) sub.topic, err = s.pubsub.Join(path, opts...) if err != nil { return nil, fmt.Errorf("failed to join topic %s, err=%w", path, err) } s.subManager.AddSubscription(path, sub) - for _, t := range s.gossipTopics { - if t.CodecStr == topic.CodecStr { - return sub, nil - } - } - s.gossipTopics = append(s.gossipTopics, topic) - return sub, nil -} -func (s *Sentinel) LogTopicPeers() { - log.Info("[Gossip] Network Update", "topic peers", s.subManager.String()) + return sub, nil } -func (s *Sentinel) getTopic(topic GossipTopic) string { - o, err := fork.ComputeForkDigest(s.cfg.BeaconConfig, s.cfg.GenesisConfig) +func (s *Sentinel) Unsubscribe(topic GossipTopic, opts ...pubsub.TopicOpt) (err error) { + digest, err := fork.ComputeForkDigest(s.cfg.BeaconConfig, s.cfg.GenesisConfig) if err != nil { log.Error("[Gossip] Failed to calculate fork choice", "err", err) } - return fmt.Sprintf("/eth2/%x/%s/%s", o, topic.Name, topic.CodecStr) + s.subManager.unsubscribe(fmt.Sprintf("/eth2/%x/%s/%s", digest, topic.Name, topic.CodecStr)) + + return nil } diff --git a/cmd/sentinel/sentinel/request.go b/cmd/sentinel/sentinel/request.go index 18d13b2bc78..1b9377dfa1f 100644 --- a/cmd/sentinel/sentinel/request.go +++ b/cmd/sentinel/sentinel/request.go @@ -15,7 +15,6 @@ package sentinel import ( "fmt" - "strings" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/communication" "github.com/libp2p/go-libp2p/core/peer" @@ -43,11 +42,9 @@ func (s *Sentinel) RandomPeer(topic string) (peer.ID, error) { pid peer.ID err error ) - if strings.Contains(topic, "light_client") && !strings.Contains(topic, "bootstrap") { - pid, err = connectToRandomPeer(s, string(LightClientFinalityUpdateTopic)) - } else { - pid, err = connectToRandomPeer(s, string(BeaconBlockTopic)) - } + + pid, err = connectToRandomPeer(s, string(BeaconBlockTopic)) + if err != nil { return peer.ID(""), fmt.Errorf("failed to connect to a random peer err=%s", err) } diff --git a/cmd/sentinel/sentinel/sentinel.go b/cmd/sentinel/sentinel/sentinel.go index d0415af8cd9..f9f4049ecfb 100644 --- a/cmd/sentinel/sentinel/sentinel.go +++ b/cmd/sentinel/sentinel/sentinel.go @@ -19,10 +19,11 @@ import ( "fmt" "net" + "net/http" + "time" + "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/erigon/cl/clparams" "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/cl/fork" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/handlers" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/handshake" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/peers" @@ -33,9 +34,26 @@ import ( "github.com/ledgerwatch/log/v3" "github.com/libp2p/go-libp2p" pubsub "github.com/libp2p/go-libp2p-pubsub" - pubsub_pb "github.com/libp2p/go-libp2p-pubsub/pb" "github.com/libp2p/go-libp2p/core/host" "github.com/libp2p/go-libp2p/core/network" + rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager" + rcmgrObs "github.com/libp2p/go-libp2p/p2p/host/resource-manager/obs" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promhttp" +) + +const ( + // overlay parameters + gossipSubD = 8 // topic stable mesh target count + gossipSubDlo = 6 // topic stable mesh low watermark + gossipSubDhi = 12 // topic stable mesh high watermark + + // gossip parameters + gossipSubMcacheLen = 6 // number of windows to retain full messages in cache for `IWANT` responses + gossipSubMcacheGossip = 3 // number of windows to gossip about + gossipSubSeenTTL = 550 // number of heartbeat intervals to retain message IDs + // heartbeat interval + gossipSubHeartbeatInterval = 700 * time.Millisecond // frequency of heartbeat, milliseconds ) type Sentinel struct { @@ -53,7 +71,7 @@ type Sentinel struct { discoverConfig discover.Config pubsub *pubsub.PubSub subManager *GossipManager - gossipTopics []GossipTopic + metrics bool } func (s *Sentinel) createLocalNode( @@ -147,20 +165,27 @@ func (s *Sentinel) createListener() (*discover.UDPv5, error) { return net, err } +// creates a custom gossipsub parameter set. +func pubsubGossipParam() pubsub.GossipSubParams { + gParams := pubsub.DefaultGossipSubParams() + gParams.Dlo = gossipSubDlo + gParams.D = gossipSubD + gParams.HeartbeatInterval = gossipSubHeartbeatInterval + gParams.HistoryLength = gossipSubMcacheLen + gParams.HistoryGossip = gossipSubMcacheGossip + return gParams +} + func (s *Sentinel) pubsubOptions() []pubsub.Option { pubsubQueueSize := 600 - gsp := pubsub.DefaultGossipSubParams() psOpts := []pubsub.Option{ pubsub.WithMessageSignaturePolicy(pubsub.StrictNoSign), - pubsub.WithMessageSignaturePolicy(pubsub.StrictNoSign), - pubsub.WithMessageIdFn(func(pmsg *pubsub_pb.Message) string { - return fork.MsgID(pmsg, s.cfg.NetworkConfig, s.cfg.BeaconConfig, s.cfg.GenesisConfig) - }), pubsub.WithNoAuthor(), - pubsub.WithSubscriptionFilter(nil), + pubsub.WithMessageIdFn(s.msgId), + pubsub.WithNoAuthor(), pubsub.WithPeerOutboundQueueSize(pubsubQueueSize), pubsub.WithMaxMessageSize(int(s.cfg.NetworkConfig.GossipMaxSize)), pubsub.WithValidateQueueSize(pubsubQueueSize), - pubsub.WithGossipSubParams(gsp), + pubsub.WithGossipSubParams(pubsubGossipParam()), } return psOpts } @@ -170,12 +195,12 @@ func New( ctx context.Context, cfg *SentinelConfig, db kv.RoDB, - rule handshake.RuleFunc, ) (*Sentinel, error) { s := &Sentinel{ ctx: ctx, cfg: cfg, db: db, + // metrics: true, } // Setup discovery @@ -200,16 +225,38 @@ func New( if err != nil { return nil, err } + if s.metrics { + http.Handle("/metrics", promhttp.Handler()) + go func() { + server := &http.Server{ + Addr: ":2112", + ReadHeaderTimeout: time.Hour, + } + if err := server.ListenAndServe(); err != nil { + panic(err) + } + }() + + rcmgrObs.MustRegisterWith(prometheus.DefaultRegisterer) + + str, err := rcmgrObs.NewStatsTraceReporter() + if err != nil { + return nil, err + } + rmgr, err := rcmgr.NewResourceManager(rcmgr.NewFixedLimiter(rcmgr.DefaultLimits.AutoScale()), rcmgr.WithTraceReporter(str)) + if err != nil { + return nil, err + } + opts = append(opts, libp2p.ResourceManager(rmgr)) + } host, err := libp2p.New(opts...) if err != nil { return nil, err } - s.handshaker = handshake.New(ctx, cfg.GenesisConfig, cfg.BeaconConfig, host, rule) + s.handshaker = handshake.New(ctx, cfg.GenesisConfig, cfg.BeaconConfig, host) - // removed IdDelta in recent version of libp2p - host.RemoveStreamHandler("/p2p/id/delta/1.0.0") s.host = host s.peers = peers.New(s.host) @@ -221,10 +268,6 @@ func New( return s, nil } -func (s *Sentinel) ChainConfigs() (clparams.BeaconChainConfig, clparams.GenesisConfig) { - return *s.cfg.BeaconConfig, *s.cfg.GenesisConfig -} - func (s *Sentinel) RecvGossip() <-chan *pubsub.Message { return s.subManager.Recv() } @@ -258,16 +301,18 @@ func (s *Sentinel) String() string { } func (s *Sentinel) HasTooManyPeers() bool { - return s.GetPeersCount() >= peers.DefaultMaxPeers + nPeers, _ := s.GetPeersCount() + return nPeers >= peers.DefaultMaxPeers } -func (s *Sentinel) GetPeersCount() int { - sub := s.subManager.GetMatchingSubscription(string(LightClientFinalityUpdateTopic)) +func (s *Sentinel) GetPeersCount() (int, int) { + sub := s.subManager.GetMatchingSubscription(string(BeaconBlockTopic)) if sub == nil { - return len(s.host.Network().Peers()) + return len(s.host.Network().Peers()), 0 } - return len(sub.topic.ListPeers()) + + return len(s.host.Network().Peers()), len(sub.topic.ListPeers()) } func (s *Sentinel) Host() host.Host { @@ -277,3 +322,7 @@ func (s *Sentinel) Host() host.Host { func (s *Sentinel) Peers() *peers.Peers { return s.peers } + +func (s *Sentinel) GossipManager() *GossipManager { + return s.subManager +} diff --git a/cmd/sentinel/sentinel/service/service.go b/cmd/sentinel/sentinel/service/service.go index 29dbea812db..e2477cc7fc4 100644 --- a/cmd/sentinel/sentinel/service/service.go +++ b/cmd/sentinel/sentinel/service/service.go @@ -72,7 +72,9 @@ func (s *SentinelServer) SubscribeGossip(_ *sentinelrpc.EmptyMessage, stream sen } func (s *SentinelServer) SendRequest(_ context.Context, req *sentinelrpc.RequestData) (*sentinelrpc.ResponseData, error) { - retryReqInterval := time.NewTicker(20 * time.Millisecond) + retryReqInterval := time.NewTicker(200 * time.Millisecond) + defer retryReqInterval.Stop() + timeout := time.NewTimer(1 * time.Second) defer retryReqInterval.Stop() doneCh := make(chan *sentinelrpc.ResponseData) // Try finding the data to our peers @@ -108,6 +110,11 @@ func (s *SentinelServer) SendRequest(_ context.Context, req *sentinelrpc.Request }() case resp := <-doneCh: return resp, nil + case <-timeout.C: + return &sentinelrpc.ResponseData{ + Data: []byte("sentinel timeout"), + Error: true, + }, nil } } } @@ -125,9 +132,11 @@ func (s *SentinelServer) SetStatus(_ context.Context, req *sentinelrpc.Status) ( } func (s *SentinelServer) GetPeers(_ context.Context, _ *sentinelrpc.EmptyMessage) (*sentinelrpc.PeerCount, error) { + nPeers, gPeers := s.sentinel.GetPeersCount() + log.Debug("Gossip", "peers", gPeers) // Send the request and get the data if we get an answer. return &sentinelrpc.PeerCount{ - Amount: uint64(s.sentinel.GetPeersCount()), + Amount: uint64(nPeers), }, nil } diff --git a/cmd/sentinel/sentinel/service/start.go b/cmd/sentinel/sentinel/service/start.go index fcf1008d1c6..e00455420f3 100644 --- a/cmd/sentinel/sentinel/service/start.go +++ b/cmd/sentinel/sentinel/service/start.go @@ -9,9 +9,7 @@ import ( sentinelrpc "github.com/ledgerwatch/erigon-lib/gointerfaces/sentinel" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon/cl/cltypes" - "github.com/ledgerwatch/erigon/cl/fork" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel" - "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/handshake" "github.com/ledgerwatch/log/v3" "google.golang.org/grpc" "google.golang.org/grpc/credentials" @@ -25,34 +23,9 @@ type ServerConfig struct { Addr string } -func hardForkListener(ctx context.Context, s *sentinel.Sentinel) { - tryAgainInterval := time.NewTicker(time.Second) - beaconCfg, genesisCfg := s.ChainConfigs() - currentDigest, err := fork.ComputeForkDigest(&beaconCfg, &genesisCfg) - if err != nil { - log.Error("cannot listen for hard forks", "reasons", err) - return - } - for { - select { - case <-ctx.Done(): - return - case <-tryAgainInterval.C: - newDigest, err := fork.ComputeForkDigest(&beaconCfg, &genesisCfg) - if err != nil { - log.Error("cannot listen for hard forks", "reasons", err) - return - } - if newDigest != currentDigest { - s.RestartTopics() - currentDigest = newDigest - } - } - } -} -func StartSentinelService(cfg *sentinel.SentinelConfig, db kv.RoDB, srvCfg *ServerConfig, creds credentials.TransportCredentials, initialStatus *cltypes.Status, rule handshake.RuleFunc) (sentinelrpc.SentinelClient, error) { +func StartSentinelService(cfg *sentinel.SentinelConfig, db kv.RoDB, srvCfg *ServerConfig, creds credentials.TransportCredentials, initialStatus *cltypes.Status) (sentinelrpc.SentinelClient, error) { ctx := context.Background() - sent, err := sentinel.New(context.Background(), cfg, db, rule) + sent, err := sentinel.New(context.Background(), cfg, db) if err != nil { return nil, err } @@ -63,13 +36,16 @@ func StartSentinelService(cfg *sentinel.SentinelConfig, db kv.RoDB, srvCfg *Serv sentinel.BeaconBlockSsz, // Cause problem due to buggy msg id will uncomment in the future. //sentinel.BeaconAggregateAndProofSsz, - sentinel.VoluntaryExitSsz, - sentinel.ProposerSlashingSsz, - sentinel.AttesterSlashingSsz, - sentinel.LightClientFinalityUpdateSsz, - sentinel.LightClientOptimisticUpdateSsz, + //sentinel.VoluntaryExitSsz, + //sentinel.ProposerSlashingSsz, + //sentinel.AttesterSlashingSsz, } + for _, v := range gossip_topics { + if err := sent.Unsubscribe(v); err != nil { + log.Error("[Sentinel] failed to start sentinel", "err", err) + continue + } // now lets separately connect to the gossip topics. this joins the room subscriber, err := sent.SubscribeGossip(v) if err != nil { @@ -81,7 +57,7 @@ func StartSentinelService(cfg *sentinel.SentinelConfig, db kv.RoDB, srvCfg *Serv log.Error("[Sentinel] failed to start sentinel", "err", err) } } - go hardForkListener(ctx, sent) + log.Info("[Sentinel] Sentinel started", "enr", sent.String()) if initialStatus != nil { sent.SetStatus(initialStatus) diff --git a/cmd/sentinel/sentinel/utils.go b/cmd/sentinel/sentinel/utils.go index 40d336941d8..8c38ffb4671 100644 --- a/cmd/sentinel/sentinel/utils.go +++ b/cmd/sentinel/sentinel/utils.go @@ -34,11 +34,11 @@ func convertToInterfacePubkey(pubkey *ecdsa.PublicKey) (crypto.PubKey, error) { xVal, yVal := new(btcec.FieldVal), new(btcec.FieldVal) overflows := xVal.SetByteSlice(pubkey.X.Bytes()) if overflows { - return nil, fmt.Errorf("X value overflows") + return nil, fmt.Errorf("x value overflows") } overflows = yVal.SetByteSlice(pubkey.Y.Bytes()) if overflows { - return nil, fmt.Errorf("Y value overflows") + return nil, fmt.Errorf("y value overflows") } newKey := crypto.PubKey((*crypto.Secp256k1PublicKey)(btcec.NewPublicKey(xVal, yVal))) // Zero out temporary values. @@ -116,7 +116,8 @@ func connectToRandomPeer(s *Sentinel, topic string) (peerInfo peer.ID, err error return peer.ID(""), fmt.Errorf("no peers") } - validPeerList := sub.topic.ListPeers() + validPeerList := s.Host().Network().Peers() + //validPeerList := sub.topic.ListPeers() if len(validPeerList) == 0 { return peer.ID(""), fmt.Errorf("no peers") } @@ -138,27 +139,12 @@ func connectToRandomPeer(s *Sentinel, topic string) (peerInfo peer.ID, err error index = n.Int64() } - node := validPeerList[index] - if !isPeerWhitelisted(node, validPeerList) { - - continue - } - - if !s.peers.IsPeerAvaiable(node) { + if !s.peers.IsPeerAvaiable(validPeerList[index]) { continue } - return node, nil + return validPeerList[index], nil } return peer.ID(""), fmt.Errorf("failed to connect to peer") - -} -func isPeerWhitelisted(peer peer.ID, whitelist []peer.ID) bool { - for _, currPeer := range whitelist { - if peer == currPeer { - return true - } - } - return false } diff --git a/cmd/sentinel/sentinel/utils_test.go b/cmd/sentinel/sentinel/utils_test.go index 38774a0d07a..10e60588b64 100644 --- a/cmd/sentinel/sentinel/utils_test.go +++ b/cmd/sentinel/sentinel/utils_test.go @@ -12,37 +12,6 @@ import ( var pyRecord, _ = hex.DecodeString("f884b8407098ad865b00a582051940cb9cf36836572411a47278783077011599ed5cd16b76f2635f4e234738f30813a89eb9137e3e3df5266e3a1f11df72ecf1145ccb9c01826964827634826970847f00000189736563703235366b31a103ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd31388375647082765f") -func TestIsPeerWhiteListed(t *testing.T) { - testCases := []struct { - whitelist []peer.ID - peer peer.ID - expectedRes bool - }{ - { - whitelist: []peer.ID{peer.ID("peer1"), peer.ID("peer2"), peer.ID("peer3"), peer.ID("peer4"), peer.ID("peer5")}, - peer: peer.ID("peer1"), - expectedRes: true, - }, - { - whitelist: []peer.ID{peer.ID("peer1"), peer.ID("peer2"), peer.ID("peer4"), peer.ID("peer5"), peer.ID("peer6")}, - peer: peer.ID("peer3"), - expectedRes: false, - }, - { - whitelist: []peer.ID{}, - peer: peer.ID(""), - expectedRes: false, - }, - } - - for _, testCase := range testCases { - got := isPeerWhitelisted(testCase.peer, testCase.whitelist) - if got != testCase.expectedRes { - t.Errorf("expected: %v, got: %v", testCase.expectedRes, got) - } - } -} - func TestMultiAddressBuilderWithID(t *testing.T) { testCases := []struct { ipAddr string diff --git a/cmd/sentry/main.go b/cmd/sentry/main.go index d73089de799..ca1f38f3db7 100644 --- a/cmd/sentry/main.go +++ b/cmd/sentry/main.go @@ -10,7 +10,7 @@ import ( "github.com/ledgerwatch/erigon/cmd/utils" "github.com/ledgerwatch/erigon/common/paths" "github.com/ledgerwatch/erigon/turbo/debug" - logging2 "github.com/ledgerwatch/erigon/turbo/logging" + "github.com/ledgerwatch/erigon/turbo/logging" node2 "github.com/ledgerwatch/erigon/turbo/node" "github.com/spf13/cobra" ) @@ -36,7 +36,7 @@ var ( ) func init() { - utils.CobraFlags(rootCmd, debug.Flags, utils.MetricFlags, logging2.Flags) + utils.CobraFlags(rootCmd, debug.Flags, utils.MetricFlags, logging.Flags) rootCmd.Flags().StringVar(&sentryAddr, "sentry.api.addr", "localhost:9091", "grpc addresses") rootCmd.Flags().StringVar(&datadirCli, utils.DataDirFlag.Name, paths.DefaultDataDir(), utils.DataDirFlag.Usage) @@ -90,7 +90,7 @@ var rootCmd = &cobra.Command{ return err } - _ = logging2.GetLoggerCmd("sentry", cmd) + logging.SetupLoggerCmd("sentry", cmd) return sentry.Sentry(cmd.Context(), dirs, sentryAddr, discoveryDNS, p2pConfig, protocol, healthCheck) }, } diff --git a/cmd/sentry/sentry/eth_handshake.go b/cmd/sentry/sentry/eth_handshake.go index e7c17bc08a5..ee5cbd02551 100644 --- a/cmd/sentry/sentry/eth_handshake.go +++ b/cmd/sentry/sentry/eth_handshake.go @@ -48,6 +48,8 @@ func tryDecodeStatusMessage(msg *p2p.Msg) (*eth.StatusPacket, error) { return &reply, nil } +var NetworkIdMissmatchErr = fmt.Errorf("network id does not match") + func checkPeerStatusCompatibility( reply *eth.StatusPacket, status *proto_sentry.StatusData, @@ -56,7 +58,7 @@ func checkPeerStatusCompatibility( ) error { networkID := status.NetworkId if reply.NetworkID != networkID { - return fmt.Errorf("network id does not match: theirs %d, ours %d", reply.NetworkID, networkID) + return fmt.Errorf("%w: theirs %d, ours %d", NetworkIdMissmatchErr, reply.NetworkID, networkID) } if uint(reply.ProtocolVersion) > version { diff --git a/cmd/sentry/sentry/sentry_grpc_server.go b/cmd/sentry/sentry/sentry_grpc_server.go index 0a30daec43a..6282f8e6f5c 100644 --- a/cmd/sentry/sentry/sentry_grpc_server.go +++ b/cmd/sentry/sentry/sentry_grpc_server.go @@ -579,7 +579,7 @@ func NewGrpcServer(ctx context.Context, dialCandidates func() enode.Iterator, re log.Trace("[p2p] peer already has connection", "peerId", printablePeerID) return nil } - log.Debug("[p2p] start with peer", "peerId", printablePeerID) + log.Trace("[p2p] start with peer", "peerId", printablePeerID) peerInfo := NewPeerInfo(peer, rw) peerInfo.protocol = protocol @@ -592,7 +592,11 @@ func NewGrpcServer(ctx context.Context, dialCandidates func() enode.Iterator, re return ss.startSync(ctx, bestHash, peerID) }) if err != nil { - log.Debug("[p2p] Handshake failure", "peer", printablePeerID, "err", err) + if errors.Is(err, NetworkIdMissmatchErr) || errors.Is(err, io.EOF) || errors.Is(err, p2p.ErrShuttingDown) { + log.Trace("[p2p] Handshake failure", "peer", printablePeerID, "err", err) + } else { + log.Debug("[p2p] Handshake failure", "peer", printablePeerID, "err", err) + } return fmt.Errorf("[p2p]handshake to peer %s: %w", printablePeerID, err) } log.Trace("[p2p] Received status message OK", "peerId", printablePeerID, "name", peer.Name()) @@ -828,7 +832,7 @@ func (ss *GrpcServer) SendMessageByMinBlock(_ context.Context, inreq *proto_sent if inreq.MaxPeers == 1 { peerInfo, found := ss.findPeerByMinBlock(inreq.MinBlock) if found { - ss.writePeer("sendMessageByMinBlock", peerInfo, msgcode, inreq.Data.Data, 30*time.Second) + ss.writePeer("[sentry] sendMessageByMinBlock", peerInfo, msgcode, inreq.Data.Data, 30*time.Second) reply.Peers = []*proto_types.H512{gointerfaces.ConvertHashToH512(peerInfo.ID())} return reply, nil } @@ -836,7 +840,7 @@ func (ss *GrpcServer) SendMessageByMinBlock(_ context.Context, inreq *proto_sent peerInfos := ss.findBestPeersWithPermit(int(inreq.MaxPeers)) reply.Peers = make([]*proto_types.H512, len(peerInfos)) for i, peerInfo := range peerInfos { - ss.writePeer("sendMessageByMinBlock", peerInfo, msgcode, inreq.Data.Data, 15*time.Second) + ss.writePeer("[sentry] sendMessageByMinBlock", peerInfo, msgcode, inreq.Data.Data, 15*time.Second) reply.Peers[i] = gointerfaces.ConvertHashToH512(peerInfo.ID()) } return reply, nil @@ -864,7 +868,7 @@ func (ss *GrpcServer) SendMessageById(_ context.Context, inreq *proto_sentry.Sen return reply, nil } - ss.writePeer("sendMessageById", peerInfo, msgcode, inreq.Data.Data, 0) + ss.writePeer("[sentry] sendMessageById", peerInfo, msgcode, inreq.Data.Data, 0) reply.Peers = []*proto_types.H512{inreq.PeerId} return reply, nil } @@ -898,7 +902,7 @@ func (ss *GrpcServer) SendMessageToRandomPeers(ctx context.Context, req *proto_s var lastErr error // Send the block to a subset of our peers at random for _, peerInfo := range peerInfos[:peersToSendCount] { - ss.writePeer("sendMessageToRandomPeers", peerInfo, msgcode, req.Data.Data, 0) + ss.writePeer("[sentry] sendMessageToRandomPeers", peerInfo, msgcode, req.Data.Data, 0) reply.Peers = append(reply.Peers, gointerfaces.ConvertHashToH512(peerInfo.ID())) } return reply, lastErr @@ -916,7 +920,7 @@ func (ss *GrpcServer) SendMessageToAll(ctx context.Context, req *proto_sentry.Ou var lastErr error ss.rangePeers(func(peerInfo *PeerInfo) bool { - ss.writePeer("SendMessageToAll", peerInfo, msgcode, req.Data, 0) + ss.writePeer("[sentry] SendMessageToAll", peerInfo, msgcode, req.Data, 0) reply.Peers = append(reply.Peers, gointerfaces.ConvertHashToH512(peerInfo.ID())) return true }) diff --git a/cmd/state/commands/erigon4.go b/cmd/state/commands/erigon4.go index d327c0e296e..8335d76e958 100644 --- a/cmd/state/commands/erigon4.go +++ b/cmd/state/commands/erigon4.go @@ -81,8 +81,8 @@ var erigon4Cmd = &cobra.Command{ Use: "erigon4", Short: "Experimental command to re-execute blocks from beginning using erigon2 state representation and history/domain", RunE: func(cmd *cobra.Command, args []string) error { - logger := logging.GetLoggerCmd("erigon4", cmd) - return Erigon4(genesis, chainConfig, logger) + logging.SetupLoggerCmd("erigon4", cmd) + return Erigon4(genesis, chainConfig, log.Root()) }, } @@ -418,14 +418,14 @@ func processBlock23(startTxNum uint64, trace bool, txNumStart uint64, rw *Reader } getHashFn := core.GetHashFn(header, getHeader) - + excessDataGas := header.ParentExcessDataGas(getHeader) for i, tx := range block.Transactions() { if txNum >= startTxNum { ibs := state.New(rw) ibs.Prepare(tx.Hash(), block.Hash(), i) ct := exec3.NewCallTracer() vmConfig.Tracer = ct - receipt, _, err := core.ApplyTransaction(chainConfig, getHashFn, engine, nil, gp, ibs, ww, header, tx, usedGas, vmConfig) + receipt, _, err := core.ApplyTransaction(chainConfig, getHashFn, engine, nil, gp, ibs, ww, header, tx, usedGas, vmConfig, excessDataGas) if err != nil { return 0, nil, fmt.Errorf("could not apply tx %d [%x] failed: %w", i, tx.Hash(), err) } @@ -482,7 +482,7 @@ func processBlock23(startTxNum uint64, trace bool, txNumStart uint64, rw *Reader } // Finalize the block, applying any consensus engine specific extras (e.g. block rewards) - if _, _, err := engine.Finalize(chainConfig, header, ibs, block.Transactions(), block.Uncles(), receipts, block.Withdrawals(), nil, nil, nil); err != nil { + if _, _, err := engine.Finalize(chainConfig, header, ibs, block.Transactions(), block.Uncles(), receipts, block.Withdrawals(), nil, nil); err != nil { return 0, nil, fmt.Errorf("finalize of block %d failed: %w", block.NumberU64(), err) } @@ -690,7 +690,6 @@ func (ww *WriterWrapper23) CreateContract(address libcommon.Address) error { } func initConsensusEngine(cc *chain2.Config, snapshots *snapshotsync.RoSnapshots) (engine consensus.Engine) { - l := log.New() config := ethconfig.Defaults var consensusConfig interface{} @@ -698,7 +697,6 @@ func initConsensusEngine(cc *chain2.Config, snapshots *snapshotsync.RoSnapshots) if cc.Clique != nil { consensusConfig = params.CliqueSnapshot } else if cc.Aura != nil { - config.Aura.Etherbase = config.Miner.Etherbase consensusConfig = &config.Aura } else if cc.Parlia != nil { consensusConfig = &config.Parlia @@ -707,7 +705,7 @@ func initConsensusEngine(cc *chain2.Config, snapshots *snapshotsync.RoSnapshots) } else { consensusConfig = &config.Ethash } - return ethconsensusconfig.CreateConsensusEngine(cc, l, consensusConfig, config.Miner.Notify, config.Miner.Noverify, config.HeimdallgRPCAddress, config.HeimdallURL, config.WithoutHeimdall, datadirCli, snapshots, true /* readonly */) + return ethconsensusconfig.CreateConsensusEngine(cc, consensusConfig, config.Miner.Notify, config.Miner.Noverify, config.HeimdallgRPCAddress, config.HeimdallURL, config.WithoutHeimdall, datadirCli, snapshots, true /* readonly */) } func bytesToUint64(buf []byte) (x uint64) { diff --git a/cmd/state/commands/history22.go b/cmd/state/commands/history22.go index e36c657335b..432e6532ff5 100644 --- a/cmd/state/commands/history22.go +++ b/cmd/state/commands/history22.go @@ -232,6 +232,7 @@ func History22(genesis *core.Genesis, logger log.Logger) error { func runHistory22(trace bool, blockNum, txNumStart uint64, hw *state.HistoryReaderV4, ww state.StateWriter, chainConfig *chain2.Config, getHeader func(hash libcommon.Hash, number uint64) *types.Header, block *types.Block, vmConfig vm.Config) (uint64, types.Receipts, error) { header := block.Header() + excessDataGas := header.ParentExcessDataGas(getHeader) vmConfig.TraceJumpDest = true engine := ethash.NewFullFaker() gp := new(core.GasPool).AddGas(block.GasLimit()) @@ -256,7 +257,7 @@ func runHistory22(trace bool, blockNum, txNumStart uint64, hw *state.HistoryRead hw.SetTxNum(txNum) ibs := state.New(hw) ibs.Prepare(tx.Hash(), block.Hash(), i) - receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), engine, nil, gp, ibs, ww, header, tx, usedGas, vmConfig) + receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), engine, nil, gp, ibs, ww, header, tx, usedGas, vmConfig, excessDataGas) if err != nil { return 0, nil, fmt.Errorf("could not apply tx %d [%x] failed: %w", i, tx.Hash(), err) } diff --git a/cmd/state/commands/opcode_tracer.go b/cmd/state/commands/opcode_tracer.go index ff5a83225e2..e7482e01d94 100644 --- a/cmd/state/commands/opcode_tracer.go +++ b/cmd/state/commands/opcode_tracer.go @@ -703,6 +703,7 @@ func OpcodeTracer(genesis *core.Genesis, blockNum uint64, chaindata string, numB func runBlock(engine consensus.Engine, ibs *state.IntraBlockState, txnWriter state.StateWriter, blockWriter state.StateWriter, chainConfig *chain2.Config, getHeader func(hash libcommon.Hash, number uint64) *types.Header, block *types.Block, vmConfig vm.Config, trace bool) (types.Receipts, error) { header := block.Header() + excessDataGas := header.ParentExcessDataGas(getHeader) vmConfig.TraceJumpDest = true gp := new(core.GasPool).AddGas(block.GasLimit()) usedGas := new(uint64) @@ -714,7 +715,7 @@ func runBlock(engine consensus.Engine, ibs *state.IntraBlockState, txnWriter sta rules := chainConfig.Rules(block.NumberU64(), block.Time()) for i, tx := range block.Transactions() { ibs.Prepare(tx.Hash(), block.Hash(), i) - receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), engine, nil, gp, ibs, txnWriter, header, tx, usedGas, vmConfig) + receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), engine, nil, gp, ibs, txnWriter, header, tx, usedGas, vmConfig, excessDataGas) if err != nil { return nil, fmt.Errorf("could not apply tx %d [%x] failed: %w", i, tx.Hash(), err) } @@ -727,7 +728,7 @@ func runBlock(engine consensus.Engine, ibs *state.IntraBlockState, txnWriter sta if !vmConfig.ReadOnly { // Finalize the block, applying any consensus engine specific extras (e.g. block rewards) tx := block.Transactions() - if _, _, _, err := engine.FinalizeAndAssemble(chainConfig, header, ibs, tx, block.Uncles(), receipts, block.Withdrawals(), nil, nil, nil, nil); err != nil { + if _, _, _, err := engine.FinalizeAndAssemble(chainConfig, header, ibs, tx, block.Uncles(), receipts, block.Withdrawals(), nil, nil, nil); err != nil { return nil, fmt.Errorf("finalize of block %d failed: %w", block.NumberU64(), err) } diff --git a/cmd/state/exec22/txtask.go b/cmd/state/exec22/txtask.go index 3353080e371..4f83e7fe74c 100644 --- a/cmd/state/exec22/txtask.go +++ b/cmd/state/exec22/txtask.go @@ -1,6 +1,10 @@ package exec22 import ( + "container/heap" + "context" + "sync" + "github.com/holiman/uint256" "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" @@ -38,7 +42,6 @@ type TxTask struct { AccountDels map[string]*accounts.Account StoragePrevs map[string][]byte CodePrevs map[string]uint64 - ResultsSize int64 Error error Logs []*types.Log TraceFroms map[libcommon.Address]struct{} @@ -47,11 +50,18 @@ type TxTask struct { UsedGas uint64 } +// TxTaskQueue non-thread-safe priority-queue type TxTaskQueue []*TxTask func (h TxTaskQueue) Len() int { return len(h) } +func LenLocked(h *TxTaskQueue, lock *sync.Mutex) (l int) { + lock.Lock() + l = h.Len() + lock.Unlock() + return l +} func (h TxTaskQueue) Less(i, j int) bool { return h[i].TxNum < h[j].TxNum @@ -92,3 +102,304 @@ func (l *KvList) Swap(i, j int) { l.Keys[i], l.Keys[j] = l.Keys[j], l.Keys[i] l.Vals[i], l.Vals[j] = l.Vals[j], l.Vals[i] } + +// QueueWithRetry is trhead-safe priority-queue of tasks - which attempt to minimize conflict-rate (retry-rate). +// Tasks may conflict and return to queue for re-try/re-exec. +// Tasks added by method `ReTry` have higher priority than tasks added by `Add`. +// Method `Add` expecting already-ordered (by priority) tasks - doesn't do any additional sorting of new tasks. +type QueueWithRetry struct { + closed bool + newTasks chan *TxTask + retires TxTaskQueue + retiresLock sync.Mutex + capacity int +} + +func NewQueueWithRetry(capacity int) *QueueWithRetry { + return &QueueWithRetry{newTasks: make(chan *TxTask, capacity), capacity: capacity} +} + +func (q *QueueWithRetry) NewTasksLen() int { return len(q.newTasks) } +func (q *QueueWithRetry) Capacity() int { return q.capacity } +func (q *QueueWithRetry) RetriesLen() (l int) { + q.retiresLock.Lock() + l = q.retires.Len() + q.retiresLock.Unlock() + return l +} +func (q *QueueWithRetry) RetryTxNumsList() (out []uint64) { + q.retiresLock.Lock() + for _, t := range q.retires { + out = append(out, t.TxNum) + } + q.retiresLock.Unlock() + return out +} +func (q *QueueWithRetry) Len() (l int) { return q.RetriesLen() + len(q.newTasks) } + +// Add "new task" (which was never executed yet). May block internal channel is full. +// Expecting already-ordered tasks. +func (q *QueueWithRetry) Add(ctx context.Context, t *TxTask) { + select { + case q.newTasks <- t: + case <-ctx.Done(): + return + } +} + +// ReTry returns failed (conflicted) task. It's non-blocking method. +// All failed tasks have higher priority than new one. +// No limit on amount of txs added by this method. +func (q *QueueWithRetry) ReTry(t *TxTask) { + q.retiresLock.Lock() + heap.Push(&q.retires, t) + q.retiresLock.Unlock() + if q.closed { + return + } + select { + case q.newTasks <- nil: + default: + } +} + +// Next - blocks until new task available +func (q *QueueWithRetry) Next(ctx context.Context) (*TxTask, bool) { + task, ok := q.popNoWait() + if ok { + return task, true + } + return q.popWait(ctx) +} + +func (q *QueueWithRetry) popWait(ctx context.Context) (task *TxTask, ok bool) { + for { + select { + case inTask, ok := <-q.newTasks: + if !ok { + q.retiresLock.Lock() + if q.retires.Len() > 0 { + task = heap.Pop(&q.retires).(*TxTask) + } + q.retiresLock.Unlock() + return task, task != nil + } + + q.retiresLock.Lock() + if inTask != nil { + heap.Push(&q.retires, inTask) + } + if q.retires.Len() > 0 { + task = heap.Pop(&q.retires).(*TxTask) + } + q.retiresLock.Unlock() + if task != nil { + return task, true + } + case <-ctx.Done(): + return nil, false + } + } +} +func (q *QueueWithRetry) popNoWait() (task *TxTask, ok bool) { + q.retiresLock.Lock() + has := q.retires.Len() > 0 + if has { // means have conflicts to re-exec: it has higher priority than new tasks + task = heap.Pop(&q.retires).(*TxTask) + } + q.retiresLock.Unlock() + + if has { + return task, task != nil + } + + // otherwise get some new task. non-blocking way. without adding to queue. + for task == nil { + select { + case task, ok = <-q.newTasks: + if !ok { + + return nil, false + } + default: + return nil, false + } + } + return task, task != nil +} + +// Close safe to call multiple times +func (q *QueueWithRetry) Close() { + if q.closed { + return + } + q.closed = true + close(q.newTasks) +} + +// ResultsQueue thread-safe priority-queue of execution results +type ResultsQueue struct { + limit int + closed bool + + resultCh chan *TxTask + iter *ResultsQueueIter + + sync.Mutex + results *TxTaskQueue +} + +func NewResultsQueue(newTasksLimit, queueLimit int) *ResultsQueue { + r := &ResultsQueue{ + results: &TxTaskQueue{}, + limit: queueLimit, + resultCh: make(chan *TxTask, newTasksLimit), + } + heap.Init(r.results) + r.iter = &ResultsQueueIter{q: r, results: r.results} + return r +} + +// Add result of execution. May block when internal channel is full +func (q *ResultsQueue) Add(ctx context.Context, task *TxTask) error { + select { + case q.resultCh <- task: // Needs to have outside of the lock + case <-ctx.Done(): + return ctx.Err() + } + return nil +} +func (q *ResultsQueue) drainNoBlock(task *TxTask) { + q.Lock() + defer q.Unlock() + if task != nil { + heap.Push(q.results, task) + } + + for { + select { + case txTask, ok := <-q.resultCh: + if !ok { + return + } + if txTask != nil { + heap.Push(q.results, txTask) + } + default: // we are inside mutex section, can't block here + return + } + } +} + +func (q *ResultsQueue) Iter() *ResultsQueueIter { + q.Lock() + q.iter.needUnlock = true + return q.iter +} +func (q *ResultsQueue) IterLocked() *ResultsQueueIter { + q.iter.needUnlock = false + return q.iter +} + +type ResultsQueueIter struct { + q *ResultsQueue + results *TxTaskQueue //pointer to `q.results` - just to reduce amount of dereferences + needUnlock bool +} + +func (q *ResultsQueueIter) Close() { + if q.needUnlock { + q.q.Unlock() + } +} +func (q *ResultsQueueIter) HasNext(outputTxNum uint64) bool { + return len(*q.results) > 0 && (*q.results)[0].TxNum == outputTxNum +} +func (q *ResultsQueueIter) PopNext() *TxTask { + return heap.Pop(q.results).(*TxTask) +} + +func (q *ResultsQueue) Drain(ctx context.Context) error { + select { + case <-ctx.Done(): + return ctx.Err() + case txTask, ok := <-q.resultCh: + if !ok { + return nil + } + q.drainNoBlock(txTask) + } + return nil +} +func (q *ResultsQueue) DrainNonBlocking() { q.drainNoBlock(nil) } + +func (q *ResultsQueue) DrainLocked() { + var drained bool + for !drained { + select { + case txTask, ok := <-q.resultCh: + if !ok { + return + } + heap.Push(q.results, txTask) + default: + drained = true + } + } +} +func (q *ResultsQueue) DropResults(f func(t *TxTask)) { + q.Lock() + defer q.Unlock() +Loop: + for { + select { + case txTask, ok := <-q.resultCh: + if !ok { + break Loop + } + f(txTask) + default: + break Loop + } + } + + // Drain results queue as well + for q.results.Len() > 0 { + f(heap.Pop(q.results).(*TxTask)) + } +} + +func (q *ResultsQueue) Close() { + if q.closed { + return + } + q.closed = true + close(q.resultCh) +} +func (q *ResultsQueue) ResultChLen() int { return len(q.resultCh) } +func (q *ResultsQueue) ResultChCap() int { return cap(q.resultCh) } +func (q *ResultsQueue) Limit() int { return q.limit } +func (q *ResultsQueue) Len() (l int) { + q.Lock() + l = q.results.Len() + q.Unlock() + return l +} +func (q *ResultsQueue) FirstTxNumLocked() uint64 { return (*q.results)[0].TxNum } +func (q *ResultsQueue) LenLocked() (l int) { return q.results.Len() } +func (q *ResultsQueue) HasLocked() bool { return len(*q.results) > 0 } +func (q *ResultsQueue) PushLocked(t *TxTask) { heap.Push(q.results, t) } +func (q *ResultsQueue) Push(t *TxTask) { + q.Lock() + heap.Push(q.results, t) + q.Unlock() +} +func (q *ResultsQueue) PopLocked() (t *TxTask) { + return heap.Pop(q.results).(*TxTask) +} +func (q *ResultsQueue) Dbg() (t *TxTask) { + if len(*q.results) > 0 { + return (*q.results)[0] + } + return nil +} diff --git a/cmd/state/exec3/state.go b/cmd/state/exec3/state.go index 8c204dec37e..dc50c649acb 100644 --- a/cmd/state/exec3/state.go +++ b/cmd/state/exec3/state.go @@ -5,11 +5,12 @@ import ( "math/big" "sync" + "github.com/ledgerwatch/log/v3" + "golang.org/x/sync/errgroup" + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/log/v3" - "golang.org/x/sync/errgroup" "github.com/ledgerwatch/erigon/cmd/state/exec22" "github.com/ledgerwatch/erigon/consensus" @@ -30,6 +31,7 @@ type Worker struct { chainTx kv.Tx background bool // if true - worker does manage RoTx (begin/rollback) in .ResetTx() blockReader services.FullBlockReader + in *exec22.QueueWithRetry rs *state.StateV3 stateWriter *state.StateWriterV3 stateReader *state.StateReaderV3 @@ -38,10 +40,8 @@ type Worker struct { ctx context.Context engine consensus.Engine - logger log.Logger - genesis *core.Genesis - resultCh chan *exec22.TxTask - epoch EpochReader + genesis *types.Genesis + resultCh *exec22.ResultsQueue chain ChainReader isPoSA bool posa consensus.PoSA @@ -53,10 +53,11 @@ type Worker struct { ibs *state.IntraBlockState } -func NewWorker(lock sync.Locker, ctx context.Context, background bool, chainDb kv.RoDB, rs *state.StateV3, blockReader services.FullBlockReader, chainConfig *chain.Config, logger log.Logger, genesis *core.Genesis, resultCh chan *exec22.TxTask, engine consensus.Engine) *Worker { +func NewWorker(lock sync.Locker, ctx context.Context, background bool, chainDb kv.RoDB, rs *state.StateV3, in *exec22.QueueWithRetry, blockReader services.FullBlockReader, chainConfig *chain.Config, genesis *types.Genesis, results *exec22.ResultsQueue, engine consensus.Engine) *Worker { w := &Worker{ lock: lock, chainDb: chainDb, + in: in, rs: rs, background: background, blockReader: blockReader, @@ -65,9 +66,8 @@ func NewWorker(lock sync.Locker, ctx context.Context, background bool, chainDb k chainConfig: chainConfig, ctx: ctx, - logger: logger, genesis: genesis, - resultCh: resultCh, + resultCh: results, engine: engine, evm: vm.NewEVM(evmtypes.BlockContext{}, evmtypes.TxContext{}, nil, chainConfig, vm.Config{}), @@ -85,6 +85,7 @@ func NewWorker(lock sync.Locker, ctx context.Context, background bool, chainDb k w.ibs = state.New(w.stateReader) w.posa, w.isPoSA = engine.(consensus.PoSA) + return w } @@ -98,18 +99,15 @@ func (rw *Worker) ResetTx(chainTx kv.Tx) { if chainTx != nil { rw.chainTx = chainTx rw.stateReader.SetTx(rw.chainTx) - rw.epoch = EpochReader{tx: rw.chainTx} rw.chain = ChainReader{config: rw.chainConfig, tx: rw.chainTx, blockReader: rw.blockReader} } } func (rw *Worker) Run() error { - for txTask, ok := rw.rs.Schedule(); ok; txTask, ok = rw.rs.Schedule() { + for txTask, ok := rw.in.Next(rw.ctx); ok; txTask, ok = rw.in.Next(rw.ctx) { rw.RunTxTask(txTask) - select { - case rw.resultCh <- txTask: // Needs to have outside of the lock - case <-rw.ctx.Done(): - return rw.ctx.Err() + if err := rw.resultCh.Add(rw.ctx, txTask); err != nil { + return err } } return nil @@ -128,7 +126,6 @@ func (rw *Worker) RunTxTaskNoLock(txTask *exec22.TxTask) { panic(err) } rw.stateReader.SetTx(rw.chainTx) - rw.epoch = EpochReader{tx: rw.chainTx} rw.chain = ChainReader{config: rw.chainConfig, tx: rw.chainTx, blockReader: rw.blockReader} } txTask.Error = nil @@ -140,13 +137,13 @@ func (rw *Worker) RunTxTaskNoLock(txTask *exec22.TxTask) { ibs := rw.ibs rules := txTask.Rules - daoForkTx := rw.chainConfig.DAOForkSupport && rw.chainConfig.DAOForkBlock != nil && rw.chainConfig.DAOForkBlock.Uint64() == txTask.BlockNum && txTask.TxIndex == -1 + daoForkTx := rw.chainConfig.DAOForkBlock != nil && rw.chainConfig.DAOForkBlock.Uint64() == txTask.BlockNum && txTask.TxIndex == -1 var err error header := txTask.Header if txTask.BlockNum == 0 && txTask.TxIndex == -1 { //fmt.Printf("txNum=%d, blockNum=%d, Genesis\n", txTask.TxNum, txTask.BlockNum) // Genesis block - _, ibs, err = rw.genesis.ToBlock("") + _, ibs, err = core.GenesisToBlock(rw.genesis, "") if err != nil { panic(err) } @@ -163,21 +160,23 @@ func (rw *Worker) RunTxTaskNoLock(txTask *exec22.TxTask) { systemcontracts.UpgradeBuildInSystemContract(rw.chainConfig, header.Number, ibs) } syscall := func(contract libcommon.Address, data []byte) ([]byte, error) { - return core.SysCallContract(contract, data, *rw.chainConfig, ibs, header, rw.engine, false /* constCall */) + return core.SysCallContract(contract, data, *rw.chainConfig, ibs, header, rw.engine, false /* constCall */, nil /*excessDataGas*/) } - rw.engine.Initialize(rw.chainConfig, rw.chain, rw.epoch, header, ibs, txTask.Txs, txTask.Uncles, syscall) + rw.engine.Initialize(rw.chainConfig, rw.chain, header, ibs, txTask.Txs, txTask.Uncles, syscall) } else if txTask.Final { if txTask.BlockNum > 0 { //fmt.Printf("txNum=%d, blockNum=%d, finalisation of the block\n", txTask.TxNum, txTask.BlockNum) // End of block transaction in a block syscall := func(contract libcommon.Address, data []byte) ([]byte, error) { - return core.SysCallContract(contract, data, *rw.chainConfig, ibs, header, rw.engine, false /* constCall */) + return core.SysCallContract(contract, data, *rw.chainConfig, ibs, header, rw.engine, false /* constCall */, nil /*excessDataGas*/) } - if _, _, err := rw.engine.Finalize(rw.chainConfig, types.CopyHeader(header), ibs, txTask.Txs, txTask.Uncles, nil /* receipts */, txTask.Withdrawals, rw.epoch, rw.chain, syscall); err != nil { + if _, _, err := rw.engine.Finalize(rw.chainConfig, types.CopyHeader(header), ibs, txTask.Txs, txTask.Uncles, nil, txTask.Withdrawals, rw.chain, syscall); err != nil { //fmt.Printf("error=%v\n", err) txTask.Error = err } else { + //rw.callTracer.AddCoinbase(txTask.Coinbase, txTask.Uncles) + //txTask.TraceTos = rw.callTracer.Tos() txTask.TraceTos = map[libcommon.Address]struct{}{} txTask.TraceTos[txTask.Coinbase] = struct{}{} for _, uncle := range txTask.Uncles { @@ -205,7 +204,7 @@ func (rw *Worker) RunTxTaskNoLock(txTask *exec22.TxTask) { blockContext := txTask.EvmBlockContext if !rw.background { getHashFn := core.GetHashFn(header, rw.getHeader) - blockContext = core.NewEVMBlockContext(header, getHashFn, rw.engine, nil /* author */) + blockContext = core.NewEVMBlockContext(header, getHashFn, rw.engine, nil /* author */, nil /*excessDataGas*/) } rw.evm.ResetBetweenBlocks(blockContext, core.NewEVMTxContext(msg), ibs, vmConfig, rules) vmenv := rw.evm @@ -235,24 +234,6 @@ func (rw *Worker) RunTxTaskNoLock(txTask *exec22.TxTask) { txTask.ReadLists = rw.stateReader.ReadSet() txTask.WriteLists = rw.stateWriter.WriteSet() txTask.AccountPrevs, txTask.AccountDels, txTask.StoragePrevs, txTask.CodePrevs = rw.stateWriter.PrevAndDels() - size := (20 + 32) * len(txTask.BalanceIncreaseSet) - for _, list := range txTask.ReadLists { - for _, b := range list.Keys { - size += len(b) - } - for _, b := range list.Vals { - size += len(b) - } - } - for _, list := range txTask.WriteLists { - for _, b := range list.Keys { - size += len(b) - } - for _, b := range list.Vals { - size += len(b) - } - } - txTask.ResultsSize = int64(size) } } @@ -303,39 +284,18 @@ func (cr ChainReader) GetTd(hash libcommon.Hash, number uint64) *big.Int { return td } -type EpochReader struct { - tx kv.Tx -} - -func NewEpochReader(tx kv.Tx) EpochReader { return EpochReader{tx: tx} } - -func (cr EpochReader) GetEpoch(hash libcommon.Hash, number uint64) ([]byte, error) { - return rawdb.ReadEpoch(cr.tx, number, hash) -} -func (cr EpochReader) PutEpoch(hash libcommon.Hash, number uint64, proof []byte) error { - panic("") -} -func (cr EpochReader) GetPendingEpoch(hash libcommon.Hash, number uint64) ([]byte, error) { - return rawdb.ReadPendingEpoch(cr.tx, number, hash) -} -func (cr EpochReader) PutPendingEpoch(hash libcommon.Hash, number uint64, proof []byte) error { - panic("") -} -func (cr EpochReader) FindBeforeOrEqualNumber(number uint64) (blockNum uint64, blockHash libcommon.Hash, transitionProof []byte, err error) { - return rawdb.FindEpochBeforeOrEqualNumber(cr.tx, number) -} - -func NewWorkersPool(lock sync.Locker, ctx context.Context, background bool, chainDb kv.RoDB, rs *state.StateV3, blockReader services.FullBlockReader, chainConfig *chain.Config, logger log.Logger, genesis *core.Genesis, engine consensus.Engine, workerCount int) (reconWorkers []*Worker, applyWorker *Worker, resultCh chan *exec22.TxTask, clear func(), wait func()) { - queueSize := workerCount * 256 +func NewWorkersPool(lock sync.Locker, ctx context.Context, background bool, chainDb kv.RoDB, rs *state.StateV3, in *exec22.QueueWithRetry, blockReader services.FullBlockReader, chainConfig *chain.Config, genesis *types.Genesis, engine consensus.Engine, workerCount int) (reconWorkers []*Worker, applyWorker *Worker, rws *exec22.ResultsQueue, clear func(), wait func()) { reconWorkers = make([]*Worker, workerCount) - resultCh = make(chan *exec22.TxTask, queueSize) + + resultChSize := workerCount * 8 + rws = exec22.NewResultsQueue(resultChSize, workerCount) // workerCount * 4 { // we all errors in background workers (except ctx.Cancele), because applyLoop will detect this error anyway. // and in applyLoop all errors are critical ctx, cancel := context.WithCancel(ctx) g, ctx := errgroup.WithContext(ctx) for i := 0; i < workerCount; i++ { - reconWorkers[i] = NewWorker(lock, ctx, background, chainDb, rs, blockReader, chainConfig, logger, genesis, resultCh, engine) + reconWorkers[i] = NewWorker(lock, ctx, background, chainDb, rs, in, blockReader, chainConfig, genesis, rws, engine) } if background { for i := 0; i < workerCount; i++ { @@ -359,10 +319,9 @@ func NewWorkersPool(lock sync.Locker, ctx context.Context, background bool, chai w.ResetTx(nil) } //applyWorker.ResetTx(nil) - close(resultCh) } } - applyWorker = NewWorker(lock, ctx, false, chainDb, rs, blockReader, chainConfig, logger, genesis, resultCh, engine) + applyWorker = NewWorker(lock, ctx, false, chainDb, rs, in, blockReader, chainConfig, genesis, rws, engine) - return reconWorkers, applyWorker, resultCh, clear, wait + return reconWorkers, applyWorker, rws, clear, wait } diff --git a/cmd/state/exec3/state_recon.go b/cmd/state/exec3/state_recon.go index 716e86b82f0..5fbc3d18055 100644 --- a/cmd/state/exec3/state_recon.go +++ b/cmd/state/exec3/state_recon.go @@ -7,13 +7,14 @@ import ( "sync" "github.com/RoaringBitmap/roaring/roaring64" + "github.com/ledgerwatch/log/v3" + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/length" "github.com/ledgerwatch/erigon-lib/etl" "github.com/ledgerwatch/erigon-lib/kv" libstate "github.com/ledgerwatch/erigon-lib/state" - "github.com/ledgerwatch/log/v3" "github.com/ledgerwatch/erigon/cmd/state/exec22" "github.com/ledgerwatch/erigon/common" @@ -30,11 +31,10 @@ import ( ) type ScanWorker struct { - txNum uint64 - as *libstate.AggregatorStep - fromKey, toKey []byte - currentKey []byte - bitmap roaring64.Bitmap + txNum uint64 + as *libstate.AggregatorStep + toKey []byte + bitmap roaring64.Bitmap } func NewScanWorker(txNum uint64, as *libstate.AggregatorStep) *ScanWorker { @@ -58,13 +58,13 @@ func NewFillWorker(txNum uint64, as *libstate.AggregatorStep) *FillWorker { return fw } -func (fw *FillWorker) FillAccounts(plainStateCollector *etl.Collector) { +func (fw *FillWorker) FillAccounts(plainStateCollector *etl.Collector) error { it := fw.as.IterateAccountsHistory(fw.txNum) value := make([]byte, 1024) for it.HasNext() { key, val, err := it.Next() if err != nil { - panic(err) + return err } if len(val) > 0 { var a accounts.Account @@ -102,42 +102,44 @@ func (fw *FillWorker) FillAccounts(plainStateCollector *etl.Collector) { value = value[:a.EncodingLengthForStorage()] a.EncodeForStorage(value) if err := plainStateCollector.Collect(key, value); err != nil { - panic(err) + return err } //fmt.Printf("Account [%x]=>{Balance: %d, Nonce: %d, Root: %x, CodeHash: %x}\n", key, &a.Balance, a.Nonce, a.Root, a.CodeHash) } else { if err := plainStateCollector.Collect(key, nil); err != nil { - panic(err) + return err } } } + return nil } -func (fw *FillWorker) FillStorage(plainStateCollector *etl.Collector) { +func (fw *FillWorker) FillStorage(plainStateCollector *etl.Collector) error { it := fw.as.IterateStorageHistory(fw.txNum) var compositeKey = make([]byte, length.Addr+length.Incarnation+length.Hash) binary.BigEndian.PutUint64(compositeKey[20:], state.FirstContractIncarnation) for it.HasNext() { key, val, err := it.Next() if err != nil { - panic(err) + return err } copy(compositeKey[:20], key[:20]) copy(compositeKey[20+8:], key[20:]) if len(val) > 0 { if err := plainStateCollector.Collect(compositeKey, val); err != nil { - panic(err) + return err } //fmt.Printf("Storage [%x] => [%x]\n", compositeKey, val) } else { if err := plainStateCollector.Collect(compositeKey, nil); err != nil { - panic(err) + return err } } } + return nil } -func (fw *FillWorker) FillCode(codeCollector, plainContractCollector *etl.Collector) { +func (fw *FillWorker) FillCode(codeCollector, plainContractCollector *etl.Collector) error { it := fw.as.IterateCodeHistory(fw.txNum) var compositeKey = make([]byte, length.Addr+length.Incarnation) binary.BigEndian.PutUint64(compositeKey[length.Addr:], state.FirstContractIncarnation) @@ -145,28 +147,29 @@ func (fw *FillWorker) FillCode(codeCollector, plainContractCollector *etl.Collec for it.HasNext() { key, val, err := it.Next() if err != nil { - panic(err) + return err } copy(compositeKey, key) if len(val) > 0 { codeHash, err := common.HashData(val) if err != nil { - panic(err) + return err } if err = codeCollector.Collect(codeHash[:], val); err != nil { - panic(err) + return err } if err = plainContractCollector.Collect(compositeKey, codeHash[:]); err != nil { - panic(err) + return err } //fmt.Printf("Code [%x] => %d\n", compositeKey, len(val)) } else { if err := plainContractCollector.Collect(compositeKey, nil); err != nil { - panic(err) + return err } } } + return nil } func (sw *ScanWorker) BitmapAccounts() error { @@ -219,7 +222,6 @@ func (sw *ScanWorker) Bitmap() *roaring64.Bitmap { return &sw.bitmap } type ReconWorker struct { lock sync.Locker - wg *sync.WaitGroup rs *state.ReconState blockReader services.FullBlockReader stateWriter *state.StateReconWriterInc @@ -228,8 +230,7 @@ type ReconWorker struct { engine consensus.Engine chainConfig *chain.Config logger log.Logger - genesis *core.Genesis - epoch EpochReader + genesis *types.Genesis chain ChainReader isPoSA bool posa consensus.PoSA @@ -238,17 +239,16 @@ type ReconWorker struct { ibs *state.IntraBlockState } -func NewReconWorker(lock sync.Locker, wg *sync.WaitGroup, rs *state.ReconState, +func NewReconWorker(lock sync.Locker, ctx context.Context, rs *state.ReconState, as *libstate.AggregatorStep, blockReader services.FullBlockReader, - chainConfig *chain.Config, logger log.Logger, genesis *core.Genesis, engine consensus.Engine, + chainConfig *chain.Config, logger log.Logger, genesis *types.Genesis, engine consensus.Engine, chainTx kv.Tx, ) *ReconWorker { rw := &ReconWorker{ lock: lock, - wg: wg, + ctx: ctx, rs: rs, blockReader: blockReader, - ctx: context.Background(), stateWriter: state.NewStateReconWriterInc(as, rs), stateReader: state.NewHistoryReaderInc(as, rs), chainConfig: chainConfig, @@ -257,7 +257,6 @@ func NewReconWorker(lock sync.Locker, wg *sync.WaitGroup, rs *state.ReconState, engine: engine, evm: vm.NewEVM(evmtypes.BlockContext{}, evmtypes.TxContext{}, nil, chainConfig, vm.Config{}), } - rw.epoch = NewEpochReader(chainTx) rw.chain = NewChainReader(chainConfig, chainTx, blockReader) rw.ibs = state.New(rw.stateReader) rw.posa, rw.isPoSA = engine.(consensus.PoSA) @@ -274,16 +273,21 @@ func (rw *ReconWorker) SetChainTx(chainTx kv.Tx) { rw.stateWriter.SetChainTx(chainTx) } -func (rw *ReconWorker) Run() { - defer rw.wg.Done() - for txTask, ok := rw.rs.Schedule(); ok; txTask, ok = rw.rs.Schedule() { - rw.runTxTask(txTask) +func (rw *ReconWorker) Run() error { + for txTask, ok, err := rw.rs.Schedule(rw.ctx); ok || err != nil; txTask, ok, err = rw.rs.Schedule(rw.ctx) { + if err != nil { + return err + } + if err := rw.runTxTask(txTask); err != nil { + return err + } } + return nil } var noop = state.NewNoopWriter() -func (rw *ReconWorker) runTxTask(txTask *exec22.TxTask) { +func (rw *ReconWorker) runTxTask(txTask *exec22.TxTask) error { rw.lock.Lock() defer rw.lock.Unlock() rw.stateReader.SetTxNum(txTask.TxNum) @@ -292,14 +296,14 @@ func (rw *ReconWorker) runTxTask(txTask *exec22.TxTask) { rw.ibs.Reset() ibs := rw.ibs rules := txTask.Rules - daoForkTx := rw.chainConfig.DAOForkSupport && rw.chainConfig.DAOForkBlock != nil && rw.chainConfig.DAOForkBlock.Uint64() == txTask.BlockNum && txTask.TxIndex == -1 + daoForkTx := rw.chainConfig.DAOForkBlock != nil && rw.chainConfig.DAOForkBlock.Uint64() == txTask.BlockNum && txTask.TxIndex == -1 var err error if txTask.BlockNum == 0 && txTask.TxIndex == -1 { //fmt.Printf("txNum=%d, blockNum=%d, Genesis\n", txTask.TxNum, txTask.BlockNum) // Genesis block - _, ibs, err = rw.genesis.ToBlock("") + _, ibs, err = core.GenesisToBlock(rw.genesis, "") if err != nil { - panic(err) + return err } // For Genesis, rules should be empty, so that empty accounts can be included rules = &chain.Rules{} @@ -312,11 +316,11 @@ func (rw *ReconWorker) runTxTask(txTask *exec22.TxTask) { //fmt.Printf("txNum=%d, blockNum=%d, finalisation of the block\n", txTask.TxNum, txTask.BlockNum) // End of block transaction in a block syscall := func(contract libcommon.Address, data []byte) ([]byte, error) { - return core.SysCallContract(contract, data, *rw.chainConfig, ibs, txTask.Header, rw.engine, false /* constCall */) + return core.SysCallContract(contract, data, *rw.chainConfig, ibs, txTask.Header, rw.engine, false /* constCall */, nil /*excessDataGas*/) } - if _, _, err := rw.engine.Finalize(rw.chainConfig, types.CopyHeader(txTask.Header), ibs, txTask.Txs, txTask.Uncles, nil /* receipts */, txTask.Withdrawals, rw.epoch, rw.chain, syscall); err != nil { + if _, _, err := rw.engine.Finalize(rw.chainConfig, types.CopyHeader(txTask.Header), ibs, txTask.Txs, txTask.Uncles, nil, txTask.Withdrawals, rw.chain, syscall); err != nil { if _, readError := rw.stateReader.ReadError(); !readError { - panic(fmt.Errorf("finalize of block %d failed: %w", txTask.BlockNum, err)) + return fmt.Errorf("finalize of block %d failed: %w", txTask.BlockNum, err) } } } @@ -326,18 +330,18 @@ func (rw *ReconWorker) runTxTask(txTask *exec22.TxTask) { systemcontracts.UpgradeBuildInSystemContract(rw.chainConfig, txTask.Header.Number, ibs) } syscall := func(contract libcommon.Address, data []byte) ([]byte, error) { - return core.SysCallContract(contract, data, *rw.chainConfig, ibs, txTask.Header, rw.engine, false /* constCall */) + return core.SysCallContract(contract, data, *rw.chainConfig, ibs, txTask.Header, rw.engine, false /* constCall */, nil /*excessDataGas*/) } - rw.engine.Initialize(rw.chainConfig, rw.chain, rw.epoch, txTask.Header, ibs, txTask.Txs, txTask.Uncles, syscall) + rw.engine.Initialize(rw.chainConfig, rw.chain, txTask.Header, ibs, txTask.Txs, txTask.Uncles, syscall) } else { if rw.isPoSA { if isSystemTx, err := rw.posa.IsSystemTransaction(txTask.Tx, txTask.Header); err != nil { if _, readError := rw.stateReader.ReadError(); !readError { - panic(err) + return err } } else if isSystemTx { - return + return nil } } gp := new(core.GasPool).AddGas(txTask.Tx.GetGas()) @@ -351,12 +355,12 @@ func (rw *ReconWorker) runTxTask(txTask *exec22.TxTask) { _, err = core.ApplyMessage(vmenv, msg, gp, true /* refunds */, false /* gasBailout */) if err != nil { if _, readError := rw.stateReader.ReadError(); !readError { - panic(fmt.Errorf("could not apply blockNum=%d, txIdx=%d txNum=%d [%x] failed: %w", txTask.BlockNum, txTask.TxIndex, txTask.TxNum, txTask.Tx.Hash(), err)) + return fmt.Errorf("could not apply blockNum=%d, txIdx=%d txNum=%d [%x] failed: %w", txTask.BlockNum, txTask.TxIndex, txTask.TxNum, txTask.Tx.Hash(), err) } } if err = ibs.FinalizeTx(rules, noop); err != nil { if _, readError := rw.stateReader.ReadError(); !readError { - panic(err) + return err } } } @@ -365,9 +369,10 @@ func (rw *ReconWorker) runTxTask(txTask *exec22.TxTask) { rw.rs.RollbackTx(txTask, dependency) } else { if err = ibs.CommitBlock(rules, rw.stateWriter); err != nil { - panic(err) + return err } //fmt.Printf("commit %d\n", txNum) rw.rs.CommitTxNum(txTask.TxNum) } + return nil } diff --git a/cmd/txpool/main.go b/cmd/txpool/main.go index 7ca936f3718..138d871b7c2 100644 --- a/cmd/txpool/main.go +++ b/cmd/txpool/main.go @@ -19,9 +19,11 @@ import ( "github.com/ledgerwatch/erigon-lib/kv/remotedb" "github.com/ledgerwatch/erigon-lib/kv/remotedbserver" "github.com/ledgerwatch/erigon-lib/txpool" + "github.com/ledgerwatch/erigon-lib/txpool/txpoolcfg" "github.com/ledgerwatch/erigon-lib/txpool/txpooluitl" "github.com/ledgerwatch/erigon-lib/types" "github.com/ledgerwatch/erigon/cmd/rpcdaemon/rpcdaemontest" + common2 "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/ethdb/privateapi" "github.com/ledgerwatch/log/v3" "github.com/spf13/cobra" @@ -29,7 +31,7 @@ import ( "github.com/ledgerwatch/erigon/cmd/utils" "github.com/ledgerwatch/erigon/common/paths" "github.com/ledgerwatch/erigon/turbo/debug" - logging2 "github.com/ledgerwatch/erigon/turbo/logging" + "github.com/ledgerwatch/erigon/turbo/logging" ) var ( @@ -50,10 +52,12 @@ var ( priceLimit uint64 accountSlots uint64 priceBump uint64 + + commitEvery time.Duration ) func init() { - utils.CobraFlags(rootCmd, debug.Flags, utils.MetricFlags, logging2.Flags) + utils.CobraFlags(rootCmd, debug.Flags, utils.MetricFlags, logging.Flags) rootCmd.Flags().StringSliceVar(&sentryAddr, "sentry.api.addr", []string{"localhost:9091"}, "comma separated sentry addresses ':,:'") rootCmd.Flags().StringVar(&privateApiAddr, "private.api.addr", "localhost:9090", "execution service :") rootCmd.Flags().StringVar(&txpoolApiAddr, "txpool.api.addr", "localhost:9094", "txpool service :") @@ -65,12 +69,13 @@ func init() { rootCmd.PersistentFlags().StringVar(&TLSKeyFile, "tls.key", "", "key file for client side TLS handshake") rootCmd.PersistentFlags().StringVar(&TLSCACert, "tls.cacert", "", "CA certificate for client side TLS handshake") - rootCmd.PersistentFlags().IntVar(&pendingPoolLimit, "txpool.globalslots", txpool.DefaultConfig.PendingSubPoolLimit, "Maximum number of executable transaction slots for all accounts") - rootCmd.PersistentFlags().IntVar(&baseFeePoolLimit, "txpool.globalbasefeeeslots", txpool.DefaultConfig.BaseFeeSubPoolLimit, "Maximum number of non-executable transactions where only not enough baseFee") - rootCmd.PersistentFlags().IntVar(&queuedPoolLimit, "txpool.globalqueue", txpool.DefaultConfig.QueuedSubPoolLimit, "Maximum number of non-executable transaction slots for all accounts") - rootCmd.PersistentFlags().Uint64Var(&priceLimit, "txpool.pricelimit", txpool.DefaultConfig.MinFeeCap, "Minimum gas price (fee cap) limit to enforce for acceptance into the pool") - rootCmd.PersistentFlags().Uint64Var(&accountSlots, "txpool.accountslots", txpool.DefaultConfig.AccountSlots, "Minimum number of executable transaction slots guaranteed per account") - rootCmd.PersistentFlags().Uint64Var(&priceBump, "txpool.pricebump", txpool.DefaultConfig.PriceBump, "Price bump percentage to replace an already existing transaction") + rootCmd.PersistentFlags().IntVar(&pendingPoolLimit, "txpool.globalslots", txpoolcfg.DefaultConfig.PendingSubPoolLimit, "Maximum number of executable transaction slots for all accounts") + rootCmd.PersistentFlags().IntVar(&baseFeePoolLimit, "txpool.globalbasefeeslots", txpoolcfg.DefaultConfig.BaseFeeSubPoolLimit, "Maximum number of non-executable transactions where only not enough baseFee") + rootCmd.PersistentFlags().IntVar(&queuedPoolLimit, "txpool.globalqueue", txpoolcfg.DefaultConfig.QueuedSubPoolLimit, "Maximum number of non-executable transaction slots for all accounts") + rootCmd.PersistentFlags().Uint64Var(&priceLimit, "txpool.pricelimit", txpoolcfg.DefaultConfig.MinFeeCap, "Minimum gas price (fee cap) limit to enforce for acceptance into the pool") + rootCmd.PersistentFlags().Uint64Var(&accountSlots, "txpool.accountslots", txpoolcfg.DefaultConfig.AccountSlots, "Minimum number of executable transaction slots guaranteed per account") + rootCmd.PersistentFlags().Uint64Var(&priceBump, "txpool.pricebump", txpoolcfg.DefaultConfig.PriceBump, "Price bump percentage to replace an already existing transaction") + rootCmd.PersistentFlags().DurationVar(&commitEvery, utils.TxPoolCommitEveryFlag.Name, utils.TxPoolCommitEveryFlag.Value, utils.TxPoolCommitEveryFlag.Usage) rootCmd.Flags().StringSliceVar(&traceSenders, utils.TxPoolTraceSendersFlag.Name, []string{}, utils.TxPoolTraceSendersFlag.Usage) } @@ -84,7 +89,7 @@ var rootCmd = &cobra.Command{ debug.Exit() }, Run: func(cmd *cobra.Command, args []string) { - _ = logging2.GetLoggerCmd("txpool", cmd) + logging.SetupLoggerCmd("txpool", cmd) if err := doTxpool(cmd.Context()); err != nil { if !errors.Is(err, context.Canceled) { @@ -127,11 +132,12 @@ func doTxpool(ctx context.Context) error { sentryClients[i] = direct.NewSentryClientRemote(proto_sentry.NewSentryClient(sentryConn)) } - cfg := txpool.DefaultConfig + cfg := txpoolcfg.DefaultConfig dirs := datadir.New(datadirCli) cfg.DBDir = dirs.TxPool - cfg.CommitEvery = 30 * time.Second + + cfg.CommitEvery = common2.RandomizeDuration(commitEvery) cfg.PendingSubPoolLimit = pendingPoolLimit cfg.BaseFeeSubPoolLimit = baseFeePoolLimit cfg.QueuedSubPoolLimit = queuedPoolLimit diff --git a/cmd/txpool/readme.md b/cmd/txpool/readme.md index a3077ea7b8d..12b1f2bdaff 100644 --- a/cmd/txpool/readme.md +++ b/cmd/txpool/readme.md @@ -27,7 +27,7 @@ make txpool # --private.api.addr - connect to Erigon's grpc api # --sentry.api.addr - connect to Sentry's grpc api # --txpool.api.addr - other services to connect TxPool's grpc api -# Increase limits flags: --txpool.globalslots, --txpool.globalbasefeeeslots, --txpool.globalqueue +# Increase limits flags: --txpool.globalslots, --txpool.globalbasefeeslots, --txpool.globalqueue # --txpool.trace.senders - print more logs about Txs with senders in this list ./build/bin/txpool --private.api.addr=localhost:9090 --sentry.api.addr=localhost:9091 --txpool.api.addr=localhost:9094 --datadir= diff --git a/cmd/utils/customflags_test.go b/cmd/utils/customflags_test.go deleted file mode 100644 index de39ca36a11..00000000000 --- a/cmd/utils/customflags_test.go +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of go-ethereum. -// -// go-ethereum is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// go-ethereum 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 General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with go-ethereum. If not, see . - -package utils - -import ( - "os" - "os/user" - "testing" -) - -func TestPathExpansion(t *testing.T) { - user, _ := user.Current() - tests := map[string]string{ - "/home/someuser/tmp": "/home/someuser/tmp", - "~/tmp": user.HomeDir + "/tmp", - "~thisOtherUser/b/": "~thisOtherUser/b", - "$DDDXXX/a/b": "/tmp/a/b", - "/a/b/": "/a/b", - } - os.Setenv("DDDXXX", "/tmp") - for test, expected := range tests { - got := expandPath(test) - if got != expected { - t.Errorf("test %s, got %s, expected %s\n", test, got, expected) - } - } -} diff --git a/cmd/utils/diskusage_windows.go b/cmd/utils/diskusage_windows.go deleted file mode 100644 index 75e76500ded..00000000000 --- a/cmd/utils/diskusage_windows.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package utils - -import ( - "fmt" - - "golang.org/x/sys/windows" -) - -func getFreeDiskSpace(path string) (uint64, error) { - - cwd, err := windows.UTF16PtrFromString(path) - if err != nil { - return 0, fmt.Errorf("failed to call UTF16PtrFromString: %w", err) - } - - var freeBytesAvailableToCaller, totalNumberOfBytes, totalNumberOfFreeBytes uint64 - if err := windows.GetDiskFreeSpaceEx(cwd, &freeBytesAvailableToCaller, &totalNumberOfBytes, &totalNumberOfFreeBytes); err != nil { - return 0, fmt.Errorf("failed to call GetDiskFreeSpaceEx: %w", err) - } - - return freeBytesAvailableToCaller, nil -} diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 2d60266b689..3f32428ff1b 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -34,7 +34,11 @@ import ( "github.com/ledgerwatch/erigon-lib/common/metrics" downloadercfg2 "github.com/ledgerwatch/erigon-lib/downloader/downloadercfg" "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/erigon-lib/txpool" + "github.com/ledgerwatch/erigon-lib/txpool/txpoolcfg" + "github.com/ledgerwatch/erigon/cmd/utils/flags" + common2 "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/consensus/ethash/ethashcfg" + "github.com/ledgerwatch/erigon/eth/gasprice/gaspricecfg" "github.com/ledgerwatch/log/v3" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -43,11 +47,9 @@ import ( "github.com/ledgerwatch/erigon/cl/clparams" "github.com/ledgerwatch/erigon/cmd/downloader/downloadernat" "github.com/ledgerwatch/erigon/common/paths" - "github.com/ledgerwatch/erigon/consensus/ethash" "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/eth/ethconfig" - "github.com/ledgerwatch/erigon/eth/gasprice" "github.com/ledgerwatch/erigon/eth/protocols/eth" "github.com/ledgerwatch/erigon/node/nodecfg" "github.com/ledgerwatch/erigon/p2p" @@ -67,17 +69,17 @@ import ( var ( // General settings - DataDirFlag = DirectoryFlag{ + DataDirFlag = flags.DirectoryFlag{ Name: "datadir", Usage: "Data directory for the databases", - Value: DirectoryString(paths.DefaultDataDir()), + Value: flags.DirectoryString(paths.DefaultDataDir()), } - AncientFlag = DirectoryFlag{ + AncientFlag = flags.DirectoryFlag{ Name: "datadir.ancient", Usage: "Data directory for ancient chain segments (default = inside chaindata)", } - MinFreeDiskSpaceFlag = DirectoryFlag{ + MinFreeDiskSpaceFlag = flags.DirectoryFlag{ Name: "datadir.minfreedisk", Usage: "Minimum free disk space in MB, once reached triggers auto shut down (default = --cache.gc converted to MB, 0 = disabled)", } @@ -103,7 +105,7 @@ var ( Name: "whitelist", Usage: "Comma separated block number-to-hash mappings to enforce (=)", } - OverrideShanghaiTime = BigFlag{ + OverrideShanghaiTime = flags.BigFlag{ Name: "override.shanghaiTime", Usage: "Manually specify Shanghai fork time, overriding the bundled setting", } @@ -117,10 +119,10 @@ var ( Name: "ethash.cacheslockmmap", Usage: "Lock memory maps of recent ethash caches", } - EthashDatasetDirFlag = DirectoryFlag{ + EthashDatasetDirFlag = flags.DirectoryFlag{ Name: "ethash.dagdir", Usage: "Directory to store the ethash mining DAGs", - Value: DirectoryString(ethconfig.Defaults.Ethash.DatasetDir), + Value: flags.DirectoryString(ethconfig.Defaults.Ethash.DatasetDir), } EthashDatasetsLockMmapFlag = cli.BoolFlag{ Name: "ethash.dagslockmmap", @@ -131,8 +133,8 @@ var ( Usage: `Default: use snapshots "true" for BSC, Mainnet and Goerli. use snapshots "false" in all other cases`, Value: true, } - ExternalConsensusFlag = cli.BoolFlag{ - Name: "externalcl", + InternalConsensusFlag = cli.BoolFlag{ + Name: "internalcl", Usage: "enables external consensus", } // Transaction pool settings @@ -156,7 +158,7 @@ var ( TxPoolPriceBumpFlag = cli.Uint64Flag{ Name: "txpool.pricebump", Usage: "Price bump percentage to replace an already existing transaction", - Value: txpool.DefaultConfig.PriceBump, + Value: txpoolcfg.DefaultConfig.PriceBump, } TxPoolAccountSlotsFlag = cli.Uint64Flag{ Name: "txpool.accountslots", @@ -193,6 +195,11 @@ var ( Usage: "Comma separared list of addresses, whoes transactions will traced in transaction pool with debug printing", Value: "", } + TxPoolCommitEveryFlag = cli.DurationFlag{ + Name: "txpool.commit.every", + Usage: "How often transactions should be committed to the storage", + Value: txpoolcfg.DefaultConfig.CommitEvery, + } // Miner settings MiningEnabledFlag = cli.BoolFlag{ Name: "mine", @@ -211,7 +218,7 @@ var ( Usage: "Target gas limit for mined blocks", Value: ethconfig.Defaults.Miner.GasLimit, } - MinerGasPriceFlag = BigFlag{ + MinerGasPriceFlag = flags.BigFlag{ Name: "miner.gasprice", Usage: "Minimum gas price for mining a transaction", Value: ethconfig.Defaults.Miner.GasPrice, @@ -272,7 +279,7 @@ var ( Name: "ipcdisable", Usage: "Disable the IPC-RPC server", } - IPCPathFlag = DirectoryFlag{ + IPCPathFlag = flags.DirectoryFlag{ Name: "ipcpath", Usage: "Filename for IPC socket/pipe within the datadir (explicit paths escape it)", } @@ -607,10 +614,6 @@ var ( Usage: "Metrics HTTP server listening port", Value: metrics.DefaultConfig.Port, } - MetricsURLsFlag = cli.StringSliceFlag{ - Name: "metrics.urls", - Usage: "Comma separated list of URLs to the metrics endpoints thats are being diagnosed", - } HistoryV3Flag = cli.BoolFlag{ Name: "experimental.history.v3", Usage: "(also known as Erigon3) Not recommended yet: Can't change this flag after node creation. New DB and Snapshots format of history allows: parallel blocks execution, get state as of given transaction without executing whole block.", @@ -635,7 +638,7 @@ var ( Usage: "number of recent block signatures to keep in memory", Value: 16384, } - CliqueDataDirFlag = DirectoryFlag{ + CliqueDataDirFlag = flags.DirectoryFlag{ Name: "clique.datadir", Usage: "a path to clique db folder", Value: "", @@ -669,6 +672,11 @@ var ( Value: 3, Usage: "amount of files to download in parallel. If network has enough seeders 1-3 slot enough, if network has lack of seeders increase to 5-7 (too big value will slow down everything).", } + TorrentStaticPeersFlag = cli.StringFlag{ + Name: "torrent.staticpeers", + Usage: "Comma separated enode URLs to connect to", + Value: "", + } NoDownloaderFlag = cli.BoolFlag{ Name: "no-downloader", Usage: "to disable downloader component", @@ -705,9 +713,14 @@ var ( } DbPageSizeFlag = cli.StringFlag{ Name: "db.pagesize", - Usage: "set mdbx pagesize on db creation: must be power of 2 and '256b <= pagesize <= 64kb'. default: equal to OperationSystem's pageSize", + Usage: "DB is splitted to 'pages' of fixed size. Can't change DB creation. Must be power of 2 and '256b <= pagesize <= 64kb'. Default: equal to OperationSystem's pageSize. Bigger pageSize causing: 1. More writes to disk during commit 2. Smaller b-tree high 3. Less fragmentation 4. Less overhead on 'free-pages list' maintainance (a bit faster Put/Commit) 5. If expecting DB-size > 8Tb then set pageSize >= 8Kb", Value: datasize.ByteSize(kv.DefaultPageSize()).String(), } + DbSizeLimitFlag = cli.StringFlag{ + Name: "db.size.limit", + Usage: "runtime limit of chandata db size. you can change value of this flag at any time", + Value: (7 * datasize.TB).String(), + } HealthCheckFlag = cli.BoolFlag{ Name: "healthcheck", @@ -763,10 +776,6 @@ var ( Usage: "Port for sentinel", Value: 7777, } - DiagnosticsURLFlag = cli.StringFlag{ - Name: "diagnostics.url", - Usage: "URL of the diagnostics system provided by the support team", - } ) var MetricFlags = []cli.Flag{&MetricsEnabledFlag, &MetricsHTTPFlag, &MetricsPortFlag} @@ -900,6 +909,7 @@ func NewP2PConfig( port uint, protocol uint, allowedPorts []uint, + metricsEnabled bool, ) (*p2p.Config, error) { var enodeDBPath string switch protocol { @@ -930,6 +940,7 @@ func NewP2PConfig( NodeDatabase: enodeDBPath, AllowedPorts: allowedPorts, TmpDir: dirs.Tmp, + MetricsEnabled: metricsEnabled, } if netRestrict != "" { cfg.NetRestrict = new(netutil.Netlist) @@ -1093,6 +1104,10 @@ func SetP2PConfig(ctx *cli.Context, cfg *p2p.Config, nodeName, datadir string) { cfg.DiscoveryV5 = ctx.Bool(DiscoveryV5Flag.Name) } + if ctx.IsSet(MetricsEnabledFlag.Name) { + cfg.MetricsEnabled = ctx.Bool(MetricsEnabledFlag.Name) + } + ethPeers := cfg.MaxPeers cfg.Name = nodeName log.Info("Maximum peer count", "ETH", ethPeers, "total", cfg.MaxPeers) @@ -1144,9 +1159,16 @@ func setDataDir(ctx *cli.Context, cfg *nodecfg.Config) { if err := cfg.MdbxPageSize.UnmarshalText([]byte(ctx.String(DbPageSizeFlag.Name))); err != nil { panic(err) } + if err := cfg.MdbxDBSizeLimit.UnmarshalText([]byte(ctx.String(DbSizeLimitFlag.Name))); err != nil { + panic(err) + } sz := cfg.MdbxPageSize.Bytes() if !isPowerOfTwo(sz) || sz < 256 || sz > 64*1024 { - panic(fmt.Errorf("invalid --db.pagesize: %s=%d, see: %s", ctx.String(DbPageSizeFlag.Name), sz, DbPageSizeFlag.Usage)) + panic(fmt.Errorf("invalid --db.pageSize: %s=%d, see: %s", ctx.String(DbPageSizeFlag.Name), sz, DbPageSizeFlag.Usage)) + } + szLimit := cfg.MdbxDBSizeLimit.Bytes() + if szLimit%sz != 0 || szLimit < 256 { + panic(fmt.Errorf("invalid --db.size.limit: %s=%d, see: %s", ctx.String(DbSizeLimitFlag.Name), szLimit, DbSizeLimitFlag.Usage)) } } @@ -1176,7 +1198,7 @@ func setDataDirCobra(f *pflag.FlagSet, cfg *nodecfg.Config) { cfg.Dirs = datadir.New(cfg.Dirs.DataDir) } -func setGPO(ctx *cli.Context, cfg *gasprice.Config) { +func setGPO(ctx *cli.Context, cfg *gaspricecfg.Config) { if ctx.IsSet(GpoBlocksFlag.Name) { cfg.Blocks = ctx.Int(GpoBlocksFlag.Name) } @@ -1189,7 +1211,7 @@ func setGPO(ctx *cli.Context, cfg *gasprice.Config) { } // nolint -func setGPOCobra(f *pflag.FlagSet, cfg *gasprice.Config) { +func setGPOCobra(f *pflag.FlagSet, cfg *gaspricecfg.Config) { if v := f.Int(GpoBlocksFlag.Name, GpoBlocksFlag.Value, GpoBlocksFlag.Usage); v != nil { cfg.Blocks = *v } @@ -1201,15 +1223,15 @@ func setGPOCobra(f *pflag.FlagSet, cfg *gasprice.Config) { } } -func setTxPool(ctx *cli.Context, cfg *core.TxPoolConfig) { +func setTxPool(ctx *cli.Context, cfg *ethconfig.DeprecatedTxPoolConfig) { if ctx.IsSet(TxPoolDisableFlag.Name) { cfg.Disable = true } if ctx.IsSet(TxPoolLocalsFlag.Name) { - locals := strings.Split(ctx.String(TxPoolLocalsFlag.Name), ",") + locals := SplitAndTrim(ctx.String(TxPoolLocalsFlag.Name)) for _, account := range locals { - if trimmed := strings.TrimSpace(account); !libcommon.IsHexAddress(trimmed) { - Fatalf("Invalid account in --txpool.locals: %s", trimmed) + if !libcommon.IsHexAddress(account) { + Fatalf("Invalid account in --txpool.locals: %s", account) } else { cfg.Locals = append(cfg.Locals, libcommon.HexToAddress(account)) } @@ -1251,6 +1273,8 @@ func setTxPool(ctx *cli.Context, cfg *core.TxPoolConfig) { cfg.TracedSenders[i] = string(sender[:]) } } + + cfg.CommitEvery = common2.RandomizeDuration(ctx.Duration(TxPoolCommitEveryFlag.Name)) } func setEthash(ctx *cli.Context, datadir string, cfg *ethconfig.Config) { @@ -1266,7 +1290,7 @@ func setEthash(ctx *cli.Context, datadir string, cfg *ethconfig.Config) { cfg.Ethash.CachesLockMmap = ctx.Bool(EthashCachesLockMmapFlag.Name) } if ctx.IsSet(FakePoWFlag.Name) { - cfg.Ethash.PowMode = ethash.ModeFake + cfg.Ethash.PowMode = ethashcfg.ModeFake } if ctx.IsSet(EthashDatasetsLockMmapFlag.Name) { cfg.Ethash.DatasetsLockMmap = ctx.Bool(EthashDatasetsLockMmapFlag.Name) @@ -1335,10 +1359,6 @@ func setClique(ctx *cli.Context, cfg *params.ConsensusSnapshotConfig, datadir st } } -func setAuRa(ctx *cli.Context, cfg *chain.AuRaConfig, datadir string) { - cfg.DBPath = filepath.Join(datadir, "aura") -} - func setParlia(ctx *cli.Context, cfg *chain.ParliaConfig, datadir string) { cfg.DBPath = filepath.Join(datadir, "parlia") } @@ -1357,7 +1377,7 @@ func setMiner(ctx *cli.Context, cfg *params.MiningConfig) { panic(fmt.Sprintf("Erigon supports only remote miners. Flag --%s or --%s is required", MinerNotifyFlag.Name, MinerSigningKeyFileFlag.Name)) } if ctx.IsSet(MinerNotifyFlag.Name) { - cfg.Notify = strings.Split(ctx.String(MinerNotifyFlag.Name), ",") + cfg.Notify = SplitAndTrim(ctx.String(MinerNotifyFlag.Name)) } if ctx.IsSet(MinerExtraDataFlag.Name) { cfg.ExtraData = []byte(ctx.String(MinerExtraDataFlag.Name)) @@ -1366,7 +1386,7 @@ func setMiner(ctx *cli.Context, cfg *params.MiningConfig) { cfg.GasLimit = ctx.Uint64(MinerGasLimitFlag.Name) } if ctx.IsSet(MinerGasPriceFlag.Name) { - cfg.GasPrice = BigFlagValue(ctx, MinerGasPriceFlag.Name) + cfg.GasPrice = flags.GlobalBig(ctx, MinerGasPriceFlag.Name) } if ctx.IsSet(MinerRecommitIntervalFlag.Name) { cfg.Recommit = ctx.Duration(MinerRecommitIntervalFlag.Name) @@ -1382,7 +1402,7 @@ func setWhitelist(ctx *cli.Context, cfg *ethconfig.Config) { return } cfg.Whitelist = make(map[uint64]libcommon.Hash) - for _, entry := range strings.Split(whitelist, ",") { + for _, entry := range SplitAndTrim(whitelist) { parts := strings.Split(entry, "=") if len(parts) != 2 { Fatalf("Invalid whitelist entry: %s", entry) @@ -1475,7 +1495,7 @@ func SetEthConfig(ctx *cli.Context, nodeConfig *nodecfg.Config, cfg *ethconfig.C } log.Info("torrent verbosity", "level", lvl.LogString()) version := "erigon: " + params.VersionWithCommit(params.GitCommit) - cfg.Downloader, err = downloadercfg2.New(cfg.Dirs.Snap, version, lvl, downloadRate, uploadRate, ctx.Int(TorrentPortFlag.Name), ctx.Int(TorrentConnsPerFileFlag.Name), ctx.Int(TorrentDownloadSlotsFlag.Name)) + cfg.Downloader, err = downloadercfg2.New(cfg.Dirs.Snap, version, lvl, downloadRate, uploadRate, ctx.Int(TorrentPortFlag.Name), ctx.Int(TorrentConnsPerFileFlag.Name), ctx.Int(TorrentDownloadSlotsFlag.Name), ctx.StringSlice(TorrentDownloadSlotsFlag.Name)) if err != nil { panic(err) } @@ -1492,12 +1512,11 @@ func SetEthConfig(ctx *cli.Context, nodeConfig *nodecfg.Config, cfg *ethconfig.C setGPO(ctx, &cfg.GPO) setTxPool(ctx, &cfg.DeprecatedTxPool) - cfg.TxPool = core.DefaultTxPool2Config(cfg.DeprecatedTxPool) + cfg.TxPool = ethconfig.DefaultTxPool2Config(cfg.DeprecatedTxPool) cfg.TxPool.DBDir = nodeConfig.Dirs.TxPool setEthash(ctx, nodeConfig.Dirs.DataDir, cfg) setClique(ctx, &cfg.Clique, nodeConfig.Dirs.DataDir) - setAuRa(ctx, &cfg.Aura, nodeConfig.Dirs.DataDir) setParlia(ctx, &cfg.Parlia, nodeConfig.Dirs.DataDir) setMiner(ctx, &cfg.Miner) setWhitelist(ctx, cfg) @@ -1537,7 +1556,7 @@ func SetEthConfig(ctx *cli.Context, nodeConfig *nodecfg.Config, cfg *ethconfig.C switch chain { default: - genesis := core.DefaultGenesisBlockByChainName(chain) + genesis := core.GenesisBlockByChainName(chain) genesisHash := params.GenesisHashByChainName(chain) if (genesis == nil) || (genesisHash == nil) { Fatalf("ChainDB name is not recognized: %s", chain) @@ -1573,17 +1592,14 @@ func SetEthConfig(ctx *cli.Context, nodeConfig *nodecfg.Config, cfg *ethconfig.C } if ctx.IsSet(OverrideShanghaiTime.Name) { - cfg.OverrideShanghaiTime = BigFlagValue(ctx, OverrideShanghaiTime.Name) + cfg.OverrideShanghaiTime = flags.GlobalBig(ctx, OverrideShanghaiTime.Name) cfg.TxPool.OverrideShanghaiTime = cfg.OverrideShanghaiTime } - if ctx.IsSet(ExternalConsensusFlag.Name) { - cfg.ExternalCL = ctx.Bool(ExternalConsensusFlag.Name) - } else { - cfg.ExternalCL = !clparams.EmbeddedEnabledByDefault(cfg.NetworkID) + if ctx.IsSet(InternalConsensusFlag.Name) && clparams.EmbeddedEnabledByDefault(cfg.NetworkID) { + cfg.InternalCL = ctx.Bool(InternalConsensusFlag.Name) } - - nodeConfig.Http.InternalCL = !cfg.ExternalCL + nodeConfig.Http.InternalCL = cfg.InternalCL if ctx.IsSet(SentryDropUselessPeers.Name) { cfg.DropUselessPeers = ctx.Bool(SentryDropUselessPeers.Name) @@ -1603,7 +1619,7 @@ func SetDNSDiscoveryDefaults(cfg *ethconfig.Config, genesis libcommon.Hash) { } func SplitTagsFlag(tagsFlag string) map[string]string { - tags := strings.Split(tagsFlag, ",") + tags := SplitAndTrim(tagsFlag) tagsMap := map[string]string{} for _, t := range tags { @@ -1627,12 +1643,7 @@ func MakeConsolePreloads(ctx *cli.Context) []string { return nil } // Otherwise resolve absolute paths and return them - files := strings.Split(ctx.String(PreloadJSFlag.Name), ",") - preloads := make([]string, 0, len(files)) - for _, file := range files { - preloads = append(preloads, strings.TrimSpace(file)) - } - return preloads + return SplitAndTrim(ctx.String(PreloadJSFlag.Name)) } func CobraFlags(cmd *cobra.Command, urfaveCliFlagsLists ...[]cli.Flag) { diff --git a/cmd/utils/customflags.go b/cmd/utils/flags/flags.go similarity index 50% rename from cmd/utils/customflags.go rename to cmd/utils/flags/flags.go index c50a1660293..683a3cd4a41 100644 --- a/cmd/utils/customflags.go +++ b/cmd/utils/flags/flags.go @@ -1,36 +1,36 @@ // Copyright 2015 The go-ethereum Authors -// This file is part of go-ethereum. +// This file is part of the go-ethereum library. // -// go-ethereum is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by +// 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. // -// go-ethereum is distributed in the hope that it will be useful, +// 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 General Public License for more details. +// GNU Lesser General Public License for more details. // -// You should have received a copy of the GNU General Public License -// along with go-ethereum. If not, see . +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . -package utils +package flags import ( + "encoding" "errors" "flag" "math/big" "os" "os/user" - "path" + "path/filepath" "strings" - "github.com/urfave/cli/v2" - "github.com/ledgerwatch/erigon/common/math" + "github.com/urfave/cli/v2" ) -// Custom type which is registered in the flags library which cli uses for +// DirectoryString is custom type which is registered in the flags library which cli uses for // argument parsing. This allows us to expand Value to an absolute path when // the argument is parsed type DirectoryString string @@ -44,7 +44,15 @@ func (s *DirectoryString) Set(value string) error { return nil } -// Custom cli.Flag type which expand the received string to an absolute path. +var ( + _ cli.Flag = (*DirectoryFlag)(nil) + _ cli.RequiredFlag = (*DirectoryFlag)(nil) + _ cli.VisibleFlag = (*DirectoryFlag)(nil) + _ cli.DocGenerationFlag = (*DirectoryFlag)(nil) + _ cli.CategorizableFlag = (*DirectoryFlag)(nil) +) + +// DirectoryFlag is custom cli.Flag type which expand the received string to an absolute path. // e.g. ~/.ethereum -> /home/username/.ethereum type DirectoryFlag struct { Name string @@ -62,11 +70,13 @@ type DirectoryFlag struct { Aliases []string } +// For cli.Flag: + func (f *DirectoryFlag) Names() []string { return append([]string{f.Name}, f.Aliases...) } func (f *DirectoryFlag) IsSet() bool { return f.HasBeenSet } func (f *DirectoryFlag) String() string { return cli.FlagStringer(f) } -// called by cli library, grabs variable from environment (if in env) +// Apply called by cli library, grabs variable from environment (if in env) // and adds variable to flag set for parsing. func (f *DirectoryFlag) Apply(set *flag.FlagSet) error { eachName(f, func(name string) { @@ -75,12 +85,20 @@ func (f *DirectoryFlag) Apply(set *flag.FlagSet) error { return nil } +// For cli.RequiredFlag: + func (f *DirectoryFlag) IsRequired() bool { return f.Required } +// For cli.VisibleFlag: + func (f *DirectoryFlag) IsVisible() bool { return !f.Hidden } +// For cli.CategorizableFlag: + func (f *DirectoryFlag) GetCategory() string { return f.Category } +// For cli.DocGenerationFlag: + func (f *DirectoryFlag) TakesValue() bool { return true } func (f *DirectoryFlag) GetUsage() string { return f.Usage } func (f *DirectoryFlag) GetValue() string { return f.Value.String() } @@ -93,13 +111,116 @@ func (f *DirectoryFlag) GetDefaultText() string { return f.GetValue() } -func eachName(f cli.Flag, fn func(string)) { - for _, name := range f.Names() { - name = strings.Trim(name, " ") - fn(name) +type TextMarshaler interface { + encoding.TextMarshaler + encoding.TextUnmarshaler +} + +// textMarshalerVal turns a TextMarshaler into a flag.Value +type textMarshalerVal struct { + v TextMarshaler +} + +func (v textMarshalerVal) String() string { + if v.v == nil { + return "" + } + text, _ := v.v.MarshalText() + return string(text) +} + +func (v textMarshalerVal) Set(s string) error { + return v.v.UnmarshalText([]byte(s)) +} + +var ( + _ cli.Flag = (*TextMarshalerFlag)(nil) + _ cli.RequiredFlag = (*TextMarshalerFlag)(nil) + _ cli.VisibleFlag = (*TextMarshalerFlag)(nil) + _ cli.DocGenerationFlag = (*TextMarshalerFlag)(nil) + _ cli.CategorizableFlag = (*TextMarshalerFlag)(nil) +) + +// TextMarshalerFlag wraps a TextMarshaler value. +type TextMarshalerFlag struct { + Name string + + Category string + DefaultText string + Usage string + + Required bool + Hidden bool + HasBeenSet bool + + Value TextMarshaler + + Aliases []string +} + +// For cli.Flag: + +func (f *TextMarshalerFlag) Names() []string { return append([]string{f.Name}, f.Aliases...) } +func (f *TextMarshalerFlag) IsSet() bool { return f.HasBeenSet } +func (f *TextMarshalerFlag) String() string { return cli.FlagStringer(f) } + +func (f *TextMarshalerFlag) Apply(set *flag.FlagSet) error { + eachName(f, func(name string) { + set.Var(textMarshalerVal{f.Value}, f.Name, f.Usage) + }) + return nil +} + +// For cli.RequiredFlag: + +func (f *TextMarshalerFlag) IsRequired() bool { return f.Required } + +// For cli.VisibleFlag: + +func (f *TextMarshalerFlag) IsVisible() bool { return !f.Hidden } + +// For cli.CategorizableFlag: + +func (f *TextMarshalerFlag) GetCategory() string { return f.Category } + +// For cli.DocGenerationFlag: + +func (f *TextMarshalerFlag) TakesValue() bool { return true } +func (f *TextMarshalerFlag) GetUsage() string { return f.Usage } +func (f *TextMarshalerFlag) GetEnvVars() []string { return nil } // env not supported + +func (f *TextMarshalerFlag) GetValue() string { + t, err := f.Value.MarshalText() + if err != nil { + return "(ERR: " + err.Error() + ")" + } + return string(t) +} + +func (f *TextMarshalerFlag) GetDefaultText() string { + if f.DefaultText != "" { + return f.DefaultText } + return f.GetValue() } +// GlobalTextMarshaler returns the value of a TextMarshalerFlag from the global flag set. +func GlobalTextMarshaler(ctx *cli.Context, name string) TextMarshaler { + val := ctx.Generic(name) + if val == nil { + return nil + } + return val.(textMarshalerVal).v +} + +var ( + _ cli.Flag = (*BigFlag)(nil) + _ cli.RequiredFlag = (*BigFlag)(nil) + _ cli.VisibleFlag = (*BigFlag)(nil) + _ cli.DocGenerationFlag = (*BigFlag)(nil) + _ cli.CategorizableFlag = (*BigFlag)(nil) +) + // BigFlag is a command line flag that accepts 256 bit big integers in decimal or // hexadecimal syntax. type BigFlag struct { @@ -118,6 +239,8 @@ type BigFlag struct { Aliases []string } +// For cli.Flag: + func (f *BigFlag) Names() []string { return append([]string{f.Name}, f.Aliases...) } func (f *BigFlag) IsSet() bool { return f.HasBeenSet } func (f *BigFlag) String() string { return cli.FlagStringer(f) } @@ -131,12 +254,20 @@ func (f *BigFlag) Apply(set *flag.FlagSet) error { return nil } +// For cli.RequiredFlag: + func (f *BigFlag) IsRequired() bool { return f.Required } +// For cli.VisibleFlag: + func (f *BigFlag) IsVisible() bool { return !f.Hidden } +// For cli.CategorizableFlag: + func (f *BigFlag) GetCategory() string { return f.Category } +// For cli.DocGenerationFlag: + func (f *BigFlag) TakesValue() bool { return true } func (f *BigFlag) GetUsage() string { return f.Usage } func (f *BigFlag) GetValue() string { return f.Value.String() } @@ -164,12 +295,12 @@ func (b *bigValue) Set(s string) error { if !ok { return errors.New("invalid integer syntax") } - *b = bigValue(*intVal) + *b = (bigValue)(*intVal) return nil } -// BigFlagValue returns the value of a BigFlag from the flag set. -func BigFlagValue(ctx *cli.Context, name string) *big.Int { +// GlobalBig returns the value of a BigFlag from the global flag set. +func GlobalBig(ctx *cli.Context, name string) *big.Int { val := ctx.Generic(name) if val == nil { return nil @@ -183,12 +314,16 @@ func BigFlagValue(ctx *cli.Context, name string) *big.Int { // 3. cleans the path, e.g. /a/b/../c -> /a/c // Note, it has limitations, e.g. ~someuser/tmp will not be expanded func expandPath(p string) string { + // Named pipes are not file paths on windows, ignore + if strings.HasPrefix(p, `\\.\pipe`) { + return p + } if strings.HasPrefix(p, "~/") || strings.HasPrefix(p, "~\\") { if home := HomeDir(); home != "" { p = home + p[1:] } } - return path.Clean(os.ExpandEnv(p)) + return filepath.Clean(os.ExpandEnv(p)) } func HomeDir() string { @@ -200,3 +335,10 @@ func HomeDir() string { } return "" } + +func eachName(f cli.Flag, fn func(string)) { + for _, name := range f.Names() { + name = strings.Trim(name, " ") + fn(name) + } +} diff --git a/cmd/utils/flags/flags_test.go b/cmd/utils/flags/flags_test.go new file mode 100644 index 00000000000..681586b46c7 --- /dev/null +++ b/cmd/utils/flags/flags_test.go @@ -0,0 +1,61 @@ +// Copyright 2015 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 flags + +import ( + "os" + "os/user" + "runtime" + "testing" +) + +func TestPathExpansion(t *testing.T) { + user, _ := user.Current() + var tests map[string]string + + if runtime.GOOS == "windows" { + tests = map[string]string{ + `/home/someuser/tmp`: `\home\someuser\tmp`, + `~/tmp`: user.HomeDir + `\tmp`, + `~thisOtherUser/b/`: `~thisOtherUser\b`, + `$DDDXXX/a/b`: `\tmp\a\b`, + `/a/b/`: `\a\b`, + `C:\Documents\Newsletters\`: `C:\Documents\Newsletters`, + `C:\`: `C:\`, + `\\.\pipe\\pipe\geth621383`: `\\.\pipe\\pipe\geth621383`, + } + } else { + tests = map[string]string{ + `/home/someuser/tmp`: `/home/someuser/tmp`, + `~/tmp`: user.HomeDir + `/tmp`, + `~thisOtherUser/b/`: `~thisOtherUser/b`, + `$DDDXXX/a/b`: `/tmp/a/b`, + `/a/b/`: `/a/b`, + `C:\Documents\Newsletters\`: `C:\Documents\Newsletters\`, + `C:\`: `C:\`, + `\\.\pipe\\pipe\geth621383`: `\\.\pipe\\pipe\geth621383`, + } + } + + os.Setenv(`DDDXXX`, `/tmp`) + for test, expected := range tests { + got := expandPath(test) + if got != expected { + t.Errorf(`test %s, got %s, expected %s\n`, test, got, expected) + } + } +} diff --git a/cmd/utils/flags/helpers.go b/cmd/utils/flags/helpers.go new file mode 100644 index 00000000000..51dc2e8274f --- /dev/null +++ b/cmd/utils/flags/helpers.go @@ -0,0 +1,200 @@ +// Copyright 2020 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 flags + +import ( + "fmt" + "strings" + + "github.com/urfave/cli/v2" +) + +// Merge merges the given flag slices. +func Merge(groups ...[]cli.Flag) []cli.Flag { + var ret []cli.Flag + for _, group := range groups { + ret = append(ret, group...) + } + return ret +} + +var migrationApplied = map[*cli.Command]struct{}{} + +// MigrateGlobalFlags makes all global flag values available in the +// context. This should be called as early as possible in app.Before. +// +// Example: +// +// geth account new --keystore /tmp/mykeystore --lightkdf +// +// is equivalent after calling this method with: +// +// geth --keystore /tmp/mykeystore --lightkdf account new +// +// i.e. in the subcommand Action function of 'account new', ctx.Bool("lightkdf) +// will return true even if --lightkdf is set as a global option. +// +// This function may become unnecessary when https://github.com/urfave/cli/pull/1245 is merged. +func MigrateGlobalFlags(ctx *cli.Context) { + var iterate func(cs []*cli.Command, fn func(*cli.Command)) + iterate = func(cs []*cli.Command, fn func(*cli.Command)) { + for _, cmd := range cs { + if _, ok := migrationApplied[cmd]; ok { + continue + } + migrationApplied[cmd] = struct{}{} + fn(cmd) + iterate(cmd.Subcommands, fn) + } + } + + // This iterates over all commands and wraps their action function. + iterate(ctx.App.Commands, func(cmd *cli.Command) { + if cmd.Action == nil { + return + } + + action := cmd.Action + cmd.Action = func(ctx *cli.Context) error { + doMigrateFlags(ctx) + return action(ctx) + } + }) +} + +func doMigrateFlags(ctx *cli.Context) { + // Figure out if there are any aliases of commands. If there are, we want + // to ignore them when iterating over the flags. + var aliases = make(map[string]bool) + for _, fl := range ctx.Command.Flags { + for _, alias := range fl.Names()[1:] { + aliases[alias] = true + } + } + for _, name := range ctx.FlagNames() { + for _, parent := range ctx.Lineage()[1:] { + if parent.IsSet(name) { + // When iterating across the lineage, we will be served both + // the 'canon' and alias formats of all commmands. In most cases, + // it's fine to set it in the ctx multiple times (one for each + // name), however, the Slice-flags are not fine. + // The slice-flags accumulate, so if we set it once as + // "foo" and once as alias "F", then both will be present in the slice. + if _, isAlias := aliases[name]; isAlias { + continue + } + // If it is a string-slice, we need to set it as + // "alfa, beta, gamma" instead of "[alfa beta gamma]", in order + // for the backing StringSlice to parse it properly. + if result := parent.StringSlice(name); len(result) > 0 { + ctx.Set(name, strings.Join(result, ",")) + } else { + ctx.Set(name, parent.String(name)) + } + break + } + } + } +} + +/* +func init() { + cli.FlagStringer = FlagString +} +*/ + +// FlagString prints a single flag in help. +func FlagString(f cli.Flag) string { + df, ok := f.(cli.DocGenerationFlag) + if !ok { + return "" + } + + needsPlaceholder := df.TakesValue() + placeholder := "" + if needsPlaceholder { + placeholder = "value" + } + + namesText := pad(cli.FlagNamePrefixer(df.Names(), placeholder), 30) + + defaultValueString := "" + if s := df.GetDefaultText(); s != "" { + defaultValueString = " (default: " + s + ")" + } + + usage := strings.TrimSpace(df.GetUsage()) + envHint := strings.TrimSpace(cli.FlagEnvHinter(df.GetEnvVars(), "")) + if len(envHint) > 0 { + usage += " " + envHint + } + + usage = wordWrap(usage, 80) + usage = indent(usage, 10) + + return fmt.Sprintf("\n %s%s\n%s", namesText, defaultValueString, usage) +} + +func pad(s string, length int) string { + if len(s) < length { + s += strings.Repeat(" ", length-len(s)) + } + return s +} + +func indent(s string, nspace int) string { + ind := strings.Repeat(" ", nspace) + return ind + strings.ReplaceAll(s, "\n", "\n"+ind) +} + +func wordWrap(s string, width int) string { + var ( + output strings.Builder + lineLength = 0 + ) + + for { + sp := strings.IndexByte(s, ' ') + var word string + if sp == -1 { + word = s + } else { + word = s[:sp] + } + wlen := len(word) + over := lineLength+wlen >= width + if over { + output.WriteByte('\n') + lineLength = 0 + } else { + if lineLength != 0 { + output.WriteByte(' ') + lineLength++ + } + } + + output.WriteString(word) + lineLength += wlen + + if sp == -1 { + break + } + s = s[wlen+1:] + } + + return output.String() +} diff --git a/common/hexutil/json.go b/common/hexutil/json.go index 265e98ed3da..ce1ce9a05d7 100644 --- a/common/hexutil/json.go +++ b/common/hexutil/json.go @@ -23,59 +23,14 @@ import ( "math/big" "reflect" "strconv" - - "github.com/ledgerwatch/erigon-lib/common/hexutility" ) var ( - bytesT = reflect.TypeOf(Bytes(nil)) bigT = reflect.TypeOf((*Big)(nil)) uintT = reflect.TypeOf(Uint(0)) uint64T = reflect.TypeOf(Uint64(0)) ) -// Bytes marshals/unmarshals as a JSON string with 0x prefix. -// The empty slice marshals as "0x". -type Bytes []byte - -const hexPrefix = `0x` - -// MarshalText implements encoding.TextMarshaler -func (b Bytes) MarshalText() ([]byte, error) { - result := make([]byte, len(b)*2+2) - copy(result, hexPrefix) - hex.Encode(result[2:], b) - return result, nil -} - -// UnmarshalJSON implements json.Unmarshaler. -func (b *Bytes) UnmarshalJSON(input []byte) error { - if !isString(input) { - return errNonString(bytesT) - } - return wrapTypeError(b.UnmarshalText(input[1:len(input)-1]), bytesT) -} - -// UnmarshalText implements encoding.TextUnmarshaler. -func (b *Bytes) UnmarshalText(input []byte) error { - raw, err := checkText(input, true) - if err != nil { - return err - } - dec := make([]byte, len(raw)/2) - if _, err = hex.Decode(dec, raw); err != nil { - err = mapError(err) - } else { - *b = dec - } - return err -} - -// String returns the hex encoding of b. -func (b Bytes) String() string { - return hexutility.Encode(b) -} - // UnmarshalFixedUnprefixedText decodes the input as a string with optional 0x prefix. The // length of out determines the required input length. This function is commonly used to // implement the UnmarshalText method for fixed-size types. diff --git a/common/hexutil/json_example_test.go b/common/hexutil/json_example_test.go index b513fba60b5..c256b412e39 100644 --- a/common/hexutil/json_example_test.go +++ b/common/hexutil/json_example_test.go @@ -21,8 +21,6 @@ import ( "fmt" "github.com/ledgerwatch/erigon-lib/common/hexutility" - - "github.com/ledgerwatch/erigon/common/hexutil" ) type MyType [5]byte @@ -32,7 +30,7 @@ func (v *MyType) UnmarshalText(input []byte) error { } func (v MyType) String() string { - return hexutil.Bytes(v[:]).String() + return hexutility.Bytes(v[:]).String() } func ExampleUnmarshalFixedText() { diff --git a/common/hexutil/json_test.go b/common/hexutil/json_test.go index ed7d6fad1a8..21f4a35ce58 100644 --- a/common/hexutil/json_test.go +++ b/common/hexutil/json_test.go @@ -18,7 +18,6 @@ package hexutil import ( "bytes" - "encoding/hex" "encoding/json" "errors" "math/big" @@ -49,81 +48,8 @@ func referenceBig(s string) *big.Int { return b } -func referenceBytes(s string) []byte { - b, err := hex.DecodeString(s) - if err != nil { - panic(err) - } - return b -} - var errJSONEOF = errors.New("unexpected end of JSON input") -var unmarshalBytesTests = []unmarshalTest{ - // invalid encoding - {input: "", wantErr: errJSONEOF}, - {input: "null", wantErr: errNonString(bytesT)}, - {input: "10", wantErr: errNonString(bytesT)}, - {input: `"0"`, wantErr: wrapTypeError(ErrMissingPrefix, bytesT)}, - {input: `"0x0"`, wantErr: wrapTypeError(ErrOddLength, bytesT)}, - {input: `"0xxx"`, wantErr: wrapTypeError(ErrSyntax, bytesT)}, - {input: `"0x01zz01"`, wantErr: wrapTypeError(ErrSyntax, bytesT)}, - - // valid encoding - {input: `""`, want: referenceBytes("")}, - {input: `"0x"`, want: referenceBytes("")}, - {input: `"0x02"`, want: referenceBytes("02")}, - {input: `"0X02"`, want: referenceBytes("02")}, - {input: `"0xffffffffff"`, want: referenceBytes("ffffffffff")}, - { - input: `"0xffffffffffffffffffffffffffffffffffff"`, - want: referenceBytes("ffffffffffffffffffffffffffffffffffff"), - }, -} - -func TestUnmarshalBytes(t *testing.T) { - for _, test := range unmarshalBytesTests { - var v Bytes - err := json.Unmarshal([]byte(test.input), &v) - if !checkError(t, test.input, err, test.wantErr) { - continue - } - if !bytes.Equal(test.want.([]byte), v) { - t.Errorf("input %s: value mismatch: got %x, want %x", test.input, &v, test.want) - continue - } - } -} - -func BenchmarkUnmarshalBytes(b *testing.B) { - input := []byte(`"0x123456789abcdef123456789abcdef"`) - for i := 0; i < b.N; i++ { - var v Bytes - if err := v.UnmarshalJSON(input); err != nil { - b.Fatal(err) - } - } -} - -func TestMarshalBytes(t *testing.T) { - for _, test := range encodeBytesTests { - in := test.input.([]byte) - out, err := json.Marshal(Bytes(in)) - if err != nil { - t.Errorf("%x: %v", in, err) - continue - } - if want := `"` + test.want + `"`; string(out) != want { - t.Errorf("%x: MarshalJSON output mismatch: got %q, want %q", in, out, want) - continue - } - if out := Bytes(in).String(); out != test.want { - t.Errorf("%x: String mismatch: got %q, want %q", in, out, test.want) - continue - } - } -} - var unmarshalBigTests = []unmarshalTest{ // invalid encoding {input: "", wantErr: errJSONEOF}, diff --git a/common/math/integer.go b/common/math/integer.go index 5b306de4295..7f451ca9d40 100644 --- a/common/math/integer.go +++ b/common/math/integer.go @@ -96,3 +96,10 @@ func RandInt64() (int64, error) { } return n.Int64(), nil } + +func CeilDiv(x, y int) int { + if y == 0 { + return 0 + } + return (x + y - 1) / y +} diff --git a/common/paths/paths.go b/common/paths/paths.go index c617c801008..5d1e9916633 100644 --- a/common/paths/paths.go +++ b/common/paths/paths.go @@ -86,8 +86,6 @@ func DataDirForNetwork(datadir string, network string) string { return networkDataDirCheckingLegacy(datadir, "rinkeby") case networkname.GoerliChainName: return networkDataDirCheckingLegacy(datadir, "goerli") - case networkname.SokolChainName: - return networkDataDirCheckingLegacy(datadir, "sokol") case networkname.MumbaiChainName: return networkDataDirCheckingLegacy(datadir, "mumbai") case networkname.BorMainnetChainName: diff --git a/consensus/aura/aura.go b/consensus/aura/aura.go index d706b635656..30a64d1fbc5 100644 --- a/consensus/aura/aura.go +++ b/consensus/aura/aura.go @@ -19,21 +19,22 @@ package aura import ( "bytes" "container/list" - "encoding/json" + "context" "fmt" "math/big" "sort" "sync" + "sync/atomic" "time" - lru "github.com/hashicorp/golang-lru" + lru "github.com/hashicorp/golang-lru/v2" "github.com/holiman/uint256" + "github.com/ledgerwatch/log/v3" + "github.com/ledgerwatch/secp256k1" + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/kv" - "github.com/ledgerwatch/log/v3" - "github.com/ledgerwatch/secp256k1" - "go.uber.org/atomic" "github.com/ledgerwatch/erigon/accounts/abi" "github.com/ledgerwatch/erigon/common" @@ -42,10 +43,10 @@ import ( "github.com/ledgerwatch/erigon/consensus/aura/contracts" "github.com/ledgerwatch/erigon/consensus/clique" "github.com/ledgerwatch/erigon/consensus/ethash" + "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/state" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/crypto" - "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/rlp" "github.com/ledgerwatch/erigon/rpc" ) @@ -97,7 +98,7 @@ type EpochTransition struct { type Step struct { calibrate bool // whether calibration is enabled. - inner *atomic.Uint64 + inner atomic.Uint64 // Planned durations of steps. durations []StepDurationInfo } @@ -138,7 +139,7 @@ func (s *Step) optCalibrate() bool { type PermissionedStep struct { inner *Step - canPropose *atomic.Bool + canPropose atomic.Bool } type ReceivedStepHashes map[uint64]map[libcommon.Address]libcommon.Hash //BTreeMap<(u64, Address), H256> @@ -192,7 +193,7 @@ func (e *EpochManager) noteNewEpoch() { e.force = true } // zoomValidators - Zooms to the epoch after the header with the given hash. Returns true if succeeded, false otherwise. // It's analog of zoom_to_after function in OE, but doesn't require external locking // nolint -func (e *EpochManager) zoomToAfter(chain consensus.ChainHeaderReader, er consensus.EpochReader, validators ValidatorSet, hash libcommon.Hash, call consensus.SystemCall) (*RollingFinality, uint64, bool) { +func (e *EpochManager) zoomToAfter(chain consensus.ChainHeaderReader, er *NonTransactionalEpochReader, validators ValidatorSet, hash libcommon.Hash, call consensus.SystemCall) (*RollingFinality, uint64, bool) { var lastWasParent bool if e.finalityChecker.lastPushed != nil { lastWasParent = *e.finalityChecker.lastPushed == hash @@ -209,7 +210,7 @@ func (e *EpochManager) zoomToAfter(chain consensus.ChainHeaderReader, er consens // forks it will only need to be called for the block directly after // epoch transition, in which case it will be O(1) and require a single // DB lookup. - lastTransition, ok := epochTransitionFor2(chain, er, hash) + lastTransition, ok := epochTransitionFor(chain, er, hash) if !ok { if lastTransition.BlockNumber > DEBUG_LOG_FROM { fmt.Printf("zoom1: %d\n", lastTransition.BlockNumber) @@ -255,7 +256,7 @@ func (e *EpochManager) zoomToAfter(chain consensus.ChainHeaderReader, er consens // / // / The block corresponding the the parent hash must be stored already. // nolint -func epochTransitionFor2(chain consensus.ChainHeaderReader, e consensus.EpochReader, parentHash libcommon.Hash) (transition EpochTransition, ok bool) { +func epochTransitionFor(chain consensus.ChainHeaderReader, e *NonTransactionalEpochReader, parentHash libcommon.Hash) (transition EpochTransition, ok bool) { //TODO: probably this version of func doesn't support non-canonical epoch transitions h := chain.GetHeaderByHash(parentHash) if h == nil { @@ -271,62 +272,10 @@ func epochTransitionFor2(chain consensus.ChainHeaderReader, e consensus.EpochRea return EpochTransition{BlockNumber: num, BlockHash: hash, ProofRlp: transitionProof}, true } -// nolint -func epochTransitionFor(chain consensus.ChainHeaderReader, e consensus.EpochReader, parentHash libcommon.Hash) (transition EpochTransition, ok bool) { - // slow path: loop back block by block - for { - h := chain.GetHeaderByHash(parentHash) - if h == nil { - return transition, false - } - - // look for transition in database. - transitionProof, err := e.GetEpoch(h.Hash(), h.Number.Uint64()) - if err != nil { - panic(err) - } - - if transitionProof != nil { - return EpochTransition{ - BlockNumber: h.Number.Uint64(), - BlockHash: h.Hash(), - ProofRlp: transitionProof, - }, true - } - - // canonical hash -> fast breakout: - // get the last epoch transition up to this block. - // - // if `block_hash` is canonical it will only return transitions up to - // the parent. - canonical := chain.GetHeaderByNumber(h.Number.Uint64()) - if canonical == nil { - return transition, false - } - //nolint - if canonical.Hash() == parentHash { - return EpochTransition{ - BlockNumber: 0, - BlockHash: libcommon.HexToHash("0x5b28c1bfd3a15230c9a46b399cd0f9a6920d432e85381cc6a140b06e8410112f"), - ProofRlp: params.SokolGenesisEpochProof, - }, true - /* TODO: - return self - .epoch_transitions() - .map(|(_, t)| t) - .take_while(|t| t.block_number <= details.number) - .last(); - */ - } - - parentHash = h.Hash() - } -} - // AuRa // nolint type AuRa struct { - db kv.RwDB // Database to store and retrieve snapshot checkpoints + e *NonTransactionalEpochReader exitCh chan struct{} lock sync.RWMutex // Protects the signer fields @@ -334,24 +283,23 @@ type AuRa struct { // History of step hashes recently received from peers. receivedStepHashes ReceivedStepHashes - OurSigningAddress libcommon.Address // Same as Etherbase in Mining - cfg AuthorityRoundParams - EmptyStepsSet *EmptyStepSet - EpochManager *EpochManager // Mutex, + cfg AuthorityRoundParams + EmptyStepsSet *EmptyStepSet + EpochManager *EpochManager // Mutex, certifier *libcommon.Address // certifies service transactions certifierLock sync.RWMutex } type GasLimitOverride struct { - cache *lru.Cache + cache *lru.Cache[libcommon.Hash, *uint256.Int] } func NewGasLimitOverride() *GasLimitOverride { // The number of recent block hashes for which the gas limit override is memoized. const GasLimitOverrideCacheCapacity = 10 - cache, err := lru.New(GasLimitOverrideCacheCapacity) + cache, err := lru.New[libcommon.Hash, *uint256.Int](GasLimitOverrideCacheCapacity) if err != nil { panic("error creating prefetching cache for blocks") } @@ -361,9 +309,7 @@ func NewGasLimitOverride() *GasLimitOverride { func (pb *GasLimitOverride) Pop(hash libcommon.Hash) *uint256.Int { if val, ok := pb.cache.Get(hash); ok && val != nil { pb.cache.Remove(hash) - if v, ok := val.(*uint256.Int); ok { - return v - } + return val } return nil } @@ -375,12 +321,7 @@ func (pb *GasLimitOverride) Add(hash libcommon.Hash, b *uint256.Int) { pb.cache.ContainsOrAdd(hash, b) } -func NewAuRa(config *chain.AuRaConfig, db kv.RwDB, ourSigningAddress libcommon.Address, engineParamsJson []byte) (*AuRa, error) { - spec := JsonSpec{} - err := json.Unmarshal(engineParamsJson, &spec) - if err != nil { - return nil, err - } +func NewAuRa(spec *chain.AuRaConfig, db kv.RwDB) (*AuRa, error) { auraParams, err := FromJson(spec) if err != nil { return nil, err @@ -420,10 +361,10 @@ func NewAuRa(config *chain.AuRaConfig, db kv.RwDB, ourSigningAddress libcommon.A durations = append(durations, durInfo) } step := &Step{ - inner: atomic.NewUint64(initialStep), calibrate: auraParams.StartStep == nil, durations: durations, } + step.inner.Store(initialStep) step.doCalibrate() /* @@ -447,19 +388,66 @@ func NewAuRa(config *chain.AuRaConfig, db kv.RwDB, ourSigningAddress libcommon.A exitCh := make(chan struct{}) c := &AuRa{ - db: db, + e: newEpochReader(db), exitCh: exitCh, - step: PermissionedStep{inner: step, canPropose: atomic.NewBool(true)}, - OurSigningAddress: ourSigningAddress, + step: PermissionedStep{inner: step}, cfg: auraParams, receivedStepHashes: ReceivedStepHashes{}, EpochManager: NewEpochManager(), } - _ = config + c.step.canPropose.Store(true) return c, nil } +type epochReader interface { + GetEpoch(blockHash libcommon.Hash, blockN uint64) (transitionProof []byte, err error) + GetPendingEpoch(blockHash libcommon.Hash, blockN uint64) (transitionProof []byte, err error) + FindBeforeOrEqualNumber(number uint64) (blockNum uint64, blockHash libcommon.Hash, transitionProof []byte, err error) +} +type epochWriter interface { + epochReader + PutEpoch(blockHash libcommon.Hash, blockN uint64, transitionProof []byte) (err error) + PutPendingEpoch(blockHash libcommon.Hash, blockN uint64, transitionProof []byte) (err error) +} + +type NonTransactionalEpochReader struct { + db kv.RwDB +} + +func newEpochReader(db kv.RwDB) *NonTransactionalEpochReader { + return &NonTransactionalEpochReader{db: db} +} + +func (cr *NonTransactionalEpochReader) GetEpoch(hash libcommon.Hash, number uint64) (v []byte, err error) { + return v, cr.db.View(context.Background(), func(tx kv.Tx) error { + v, err = rawdb.ReadEpoch(tx, number, hash) + return err + }) +} +func (cr *NonTransactionalEpochReader) PutEpoch(hash libcommon.Hash, number uint64, proof []byte) error { + return cr.db.UpdateNosync(context.Background(), func(tx kv.RwTx) error { + return rawdb.WriteEpoch(tx, number, hash, proof) + }) +} +func (cr *NonTransactionalEpochReader) GetPendingEpoch(hash libcommon.Hash, number uint64) (v []byte, err error) { + return v, cr.db.View(context.Background(), func(tx kv.Tx) error { + v, err = rawdb.ReadPendingEpoch(tx, number, hash) + return err + }) +} +func (cr *NonTransactionalEpochReader) PutPendingEpoch(hash libcommon.Hash, number uint64, proof []byte) error { + return cr.db.UpdateNosync(context.Background(), func(tx kv.RwTx) error { + return rawdb.WritePendingEpoch(tx, number, hash, proof) + }) +} +func (cr *NonTransactionalEpochReader) FindBeforeOrEqualNumber(number uint64) (blockNum uint64, blockHash libcommon.Hash, transitionProof []byte, err error) { + return blockNum, blockHash, transitionProof, cr.db.View(context.Background(), func(tx kv.Tx) error { + blockNum, blockHash, transitionProof, err = rawdb.FindEpochBeforeOrEqualNumber(tx, number) + return err + }) +} + // A helper accumulator function mapping a step duration and a step duration transition timestamp // to the corresponding step number and the correct starting second of the step. func nextStepTimeDuration(info StepDurationInfo, time uint64) (uint64, uint64, bool) { @@ -530,7 +518,7 @@ func (c *AuRa) insertReceivedStepHashes(step uint64, author libcommon.Address, n } // nolint -func (c *AuRa) verifyFamily(chain consensus.ChainHeaderReader, e consensus.EpochReader, header *types.Header, call consensus.Call, syscall consensus.SystemCall) error { +func (c *AuRa) verifyFamily(chain consensus.ChainHeaderReader, e *NonTransactionalEpochReader, header *types.Header, call consensus.Call, syscall consensus.SystemCall) error { // TODO: I call it from Initialize - because looks like no much reason to have separated "verifyFamily" call step := header.AuRaStep @@ -771,9 +759,7 @@ func (c *AuRa) Prepare(chain consensus.ChainHeaderReader, header *types.Header, //return nil } -func (c *AuRa) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, e consensus.EpochReader, header *types.Header, - state *state.IntraBlockState, txs []types.Transaction, uncles []*types.Header, syscall consensus.SystemCall, -) { +func (c *AuRa) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, header *types.Header, state *state.IntraBlockState, txs []types.Transaction, uncles []*types.Header, syscall consensus.SystemCall) { blockNum := header.Number.Uint64() for address, rewrittenCode := range c.cfg.RewriteBytecode[blockNum] { state.SetCode(address, rewrittenCode) @@ -790,7 +776,7 @@ func (c *AuRa) Initialize(config *chain.Config, chain consensus.ChainHeaderReade if err != nil { panic(err) } - err = e.PutEpoch(header.ParentHash, 0, proof) //TODO: block 0 hardcoded - need fix it inside validators + err = c.e.PutEpoch(header.ParentHash, 0, proof) //TODO: block 0 hardcoded - need fix it inside validators if err != nil { panic(err) } @@ -802,12 +788,7 @@ func (c *AuRa) Initialize(config *chain.Config, chain consensus.ChainHeaderReade // check_and_lock_block -> check_epoch_end_signal - if e == nil { - // for tracing, we pass e that is `nil` - return - } - - epoch, err := e.GetEpoch(header.ParentHash, blockNum-1) + epoch, err := c.e.GetEpoch(header.ParentHash, blockNum-1) if err != nil { log.Warn("[aura] initialize block: on epoch begin", "err", err) return @@ -838,10 +819,7 @@ func (c *AuRa) ApplyRewards(header *types.Header, state *state.IntraBlockState, } // word `signal epoch` == word `pending epoch` -func (c *AuRa) Finalize(config *chain.Config, header *types.Header, state *state.IntraBlockState, - txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, - e consensus.EpochReader, chain consensus.ChainHeaderReader, syscall consensus.SystemCall, -) (types.Transactions, types.Receipts, error) { +func (c *AuRa) Finalize(config *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, chain consensus.ChainHeaderReader, syscall consensus.SystemCall) (types.Transactions, types.Receipts, error) { if err := c.ApplyRewards(header, state, syscall); err != nil { return nil, nil, err } @@ -858,22 +836,22 @@ func (c *AuRa) Finalize(config *chain.Config, header *types.Header, state *state if header.Number.Uint64() >= DEBUG_LOG_FROM { fmt.Printf("insert_pending_transition: %d,receipts=%d, lenProof=%d\n", header.Number.Uint64(), len(receipts), len(pendingTransitionProof)) } - if err = e.PutPendingEpoch(header.Hash(), header.Number.Uint64(), pendingTransitionProof); err != nil { + if err = c.e.PutPendingEpoch(header.Hash(), header.Number.Uint64(), pendingTransitionProof); err != nil { return nil, nil, err } } // check_and_lock_block -> check_epoch_end_signal END - finalized := buildFinality(c.EpochManager, chain, e, c.cfg.Validators, header, syscall) + finalized := buildFinality(c.EpochManager, chain, c.e, c.cfg.Validators, header, syscall) c.EpochManager.finalityChecker.print(header.Number.Uint64()) - epochEndProof, err := isEpochEnd(chain, e, finalized, header) + epochEndProof, err := isEpochEnd(chain, c.e, finalized, header) if err != nil { return nil, nil, err } if epochEndProof != nil { c.EpochManager.noteNewEpoch() log.Info("[aura] epoch transition", "block_num", header.Number.Uint64()) - if err := e.PutEpoch(header.Hash(), header.Number.Uint64(), epochEndProof); err != nil { + if err := c.e.PutEpoch(header.Hash(), header.Number.Uint64(), epochEndProof); err != nil { return nil, nil, err } } @@ -881,7 +859,7 @@ func (c *AuRa) Finalize(config *chain.Config, header *types.Header, state *state return txs, receipts, nil } -func buildFinality(e *EpochManager, chain consensus.ChainHeaderReader, er consensus.EpochReader, validators ValidatorSet, header *types.Header, syscall consensus.SystemCall) []unAssembledHeader { +func buildFinality(e *EpochManager, chain consensus.ChainHeaderReader, er *NonTransactionalEpochReader, validators ValidatorSet, header *types.Header, syscall consensus.SystemCall) []unAssembledHeader { // commit_block -> aura.build_finality _, _, ok := e.zoomToAfter(chain, er, validators, header.ParentHash, syscall) if !ok { @@ -908,7 +886,7 @@ func buildFinality(e *EpochManager, chain consensus.ChainHeaderReader, er consen return res } -func isEpochEnd(chain consensus.ChainHeaderReader, e consensus.EpochReader, finalized []unAssembledHeader, header *types.Header) ([]byte, error) { +func isEpochEnd(chain consensus.ChainHeaderReader, e *NonTransactionalEpochReader, finalized []unAssembledHeader, header *types.Header) ([]byte, error) { // commit_block -> aura.is_epoch_end for i := range finalized { pendingTransitionProof, err := e.GetPendingEpoch(finalized[i].hash, finalized[i].number) @@ -978,11 +956,8 @@ func allHeadersUntil(chain consensus.ChainHeaderReader, from *types.Header, to l //} // FinalizeAndAssemble implements consensus.Engine -func (c *AuRa) FinalizeAndAssemble(chainConfig *chain.Config, header *types.Header, state *state.IntraBlockState, - txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, - e consensus.EpochReader, chain consensus.ChainHeaderReader, syscall consensus.SystemCall, call consensus.Call, -) (*types.Block, types.Transactions, types.Receipts, error) { - outTxs, outReceipts, err := c.Finalize(chainConfig, header, state, txs, uncles, receipts, withdrawals, e, chain, syscall) +func (c *AuRa) FinalizeAndAssemble(config *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, chain consensus.ChainHeaderReader, syscall consensus.SystemCall, call consensus.Call) (*types.Block, types.Transactions, types.Receipts, error) { + outTxs, outReceipts, err := c.Finalize(config, header, state, txs, uncles, receipts, withdrawals, chain, syscall) if err != nil { return nil, nil, nil, err } @@ -1188,7 +1163,7 @@ func (c *AuRa) GenerateSeal(chain consensus.ChainHeaderReader, current, parent * // epochSet fetch correct validator set for epoch at header, taking into account // finality of previous transitions. -func (c *AuRa) epochSet(chain consensus.ChainHeaderReader, e consensus.EpochReader, h *types.Header, call consensus.SystemCall) (ValidatorSet, uint64, error) { +func (c *AuRa) epochSet(chain consensus.ChainHeaderReader, e *NonTransactionalEpochReader, h *types.Header, call consensus.SystemCall) (ValidatorSet, uint64, error) { if c.cfg.ImmediateTransitions { return c.cfg.Validators, h.Number.Uint64(), nil } @@ -1421,6 +1396,7 @@ func (c *AuRa) ExecuteSystemWithdrawals(withdrawals []*types.Withdrawal, syscall return nil } + maxFailedWithdrawalsToProcess := big.NewInt(4) amounts := make([]uint64, 0, len(withdrawals)) addresses := make([]libcommon.Address, 0, len(withdrawals)) for _, w := range withdrawals { @@ -1428,12 +1404,15 @@ func (c *AuRa) ExecuteSystemWithdrawals(withdrawals []*types.Withdrawal, syscall addresses = append(addresses, w.Address) } - packed, err := withdrawalAbi().Pack("executeSystemWithdrawals", amounts, addresses) + packed, err := withdrawalAbi().Pack("executeSystemWithdrawals", maxFailedWithdrawalsToProcess, amounts, addresses) if err != nil { return err } _, err = syscall(*c.cfg.WithdrawalContractAddress, packed) + if err != nil { + log.Warn("ExecuteSystemWithdrawals", "err", err) + } return err } diff --git a/consensus/aura/aura_test.go b/consensus/aura/aura_test.go index 6cf88e6b5eb..d3c9da5c6c9 100644 --- a/consensus/aura/aura_test.go +++ b/consensus/aura/aura_test.go @@ -1,216 +1,33 @@ package aura_test import ( - "context" - "fmt" "testing" + "github.com/stretchr/testify/require" + libcommon "github.com/ledgerwatch/erigon-lib/common" - "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv/memdb" - "github.com/stretchr/testify/require" "github.com/ledgerwatch/erigon/consensus/aura" - "github.com/ledgerwatch/erigon/consensus/aura/consensusconfig" - "github.com/ledgerwatch/erigon/consensus/aura/test" "github.com/ledgerwatch/erigon/core" - "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/types" - "github.com/ledgerwatch/erigon/core/types/accounts" - "github.com/ledgerwatch/erigon/eth/ethconfig" "github.com/ledgerwatch/erigon/turbo/stages" "github.com/ledgerwatch/erigon/turbo/trie" ) -/* -#[test] - - fn block_reward_contract() { - let spec = Spec::new_test_round_block_reward_contract(); - let tap = Arc::new(AccountProvider::transient_provider()); - - let addr1 = tap.insert_account(keccak("1").into(), &"1".into()).unwrap(); - - let engine = &*spec.engine; - let genesis_header = spec.genesis_header(); - let db1 = spec - .ensure_db_good(get_temp_state_db(), &Default::default()) - .unwrap(); - let db2 = spec - .ensure_db_good(get_temp_state_db(), &Default::default()) - .unwrap(); - - let last_hashes = Arc::new(vec![genesis_header.hash()]); - - let client = generate_dummy_client_with_spec(Spec::new_test_round_block_reward_contract); - engine.register_client(Arc::downgrade(&client) as _); - - // step 2 - let b1 = OpenBlock::new( - engine, - Default::default(), - false, - db1, - &genesis_header, - last_hashes.clone(), - addr1, - (3141562.into(), 31415620.into()), - vec![], - false, - None, - ) - .unwrap(); - let b1 = b1.close_and_lock().unwrap(); - - // since the block is empty it isn't sealed and we generate empty steps - engine.set_signer(Some(Box::new((tap.clone(), addr1, "1".into())))); - assert_eq!(engine.generate_seal(&b1, &genesis_header), Seal::None); - engine.step(); - - // step 3 - // the signer of the accumulated empty step message should be rewarded - let b2 = OpenBlock::new( - engine, - Default::default(), - false, - db2, - &genesis_header, - last_hashes.clone(), - addr1, - (3141562.into(), 31415620.into()), - vec![], - false, - None, - ) - .unwrap(); - let addr1_balance = b2.state.balance(&addr1).unwrap(); - - // after closing the block `addr1` should be reward twice, one for the included empty step - // message and another for block creation - let b2 = b2.close_and_lock().unwrap(); - - // the contract rewards (1000 + kind) for each benefactor/reward kind - assert_eq!( - b2.state.balance(&addr1).unwrap(), - addr1_balance + (1000 + 0) + (1000 + 2), - ) - } -*/ -func TestRewardContract(t *testing.T) { - t.Skip("not ready yet") - auraDB, require := memdb.NewTestDB(t), require.New(t) - engine, err := aura.NewAuRa(nil, auraDB, libcommon.Address{}, test.AuthorityRoundBlockRewardContract) - require.NoError(err) - m := stages.MockWithGenesisEngine(t, core.DefaultSokolGenesisBlock(), engine, false) - m.EnableLogs() - - var accBefore *accounts.Account - err = auraDB.View(context.Background(), func(tx kv.Tx) (err error) { _, err = rawdb.ReadAccount(tx, m.Address, accBefore); return err }) - require.NoError(err) - - chain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 2, func(i int, gen *core.BlockGen) { - gen.SetCoinbase(m.Address) - }, false /* intermediateHashes */) - require.NoError(err) - - err = m.InsertChain(chain) - require.NoError(err) - - var accAfter *accounts.Account - err = auraDB.View(context.Background(), func(tx kv.Tx) (err error) { _, err = rawdb.ReadAccount(tx, m.Address, accAfter); return err }) - require.NoError(err) - - fmt.Printf("balance: %d\n", accAfter.Balance.Uint64()) - /* - - let spec = Spec::new_test_round_block_reward_contract(); - let tap = Arc::new(AccountProvider::transient_provider()); - - let addr1 = tap.insert_account(keccak("1").into(), &"1".into()).unwrap(); - - let engine = &*spec.engine; - let genesis_header = spec.genesis_header(); - let db1 = spec - .ensure_db_good(get_temp_state_db(), &Default::default()) - .unwrap(); - let db2 = spec - .ensure_db_good(get_temp_state_db(), &Default::default()) - .unwrap(); - - let last_hashes = Arc::new(vec![genesis_header.hash()]); - - let client = generate_dummy_client_with_spec(Spec::new_test_round_block_reward_contract); - engine.register_client(Arc::downgrade(&client) as _); - - // step 2 - let b1 = OpenBlock::new( - engine, - Default::default(), - false, - db1, - &genesis_header, - last_hashes.clone(), - addr1, - (3141562.into(), 31415620.into()), - vec![], - false, - None, - ) - .unwrap(); - let b1 = b1.close_and_lock().unwrap(); - - // since the block is empty it isn't sealed and we generate empty steps - engine.set_signer(Some(Box::new((tap.clone(), addr1, "1".into())))); - assert_eq!(engine.generate_seal(&b1, &genesis_header), Seal::None); - engine.step(); - - // step 3 - // the signer of the accumulated empty step message should be rewarded - let b2 = OpenBlock::new( - engine, - Default::default(), - false, - db2, - &genesis_header, - last_hashes.clone(), - addr1, - (3141562.into(), 31415620.into()), - vec![], - false, - None, - ) - .unwrap(); - let addr1_balance = b2.state.balance(&addr1).unwrap(); - - // after closing the block `addr1` should be reward twice, one for the included empty step - // message and another for block creation - let b2 = b2.close_and_lock().unwrap(); - - // the contract rewards (1000 + kind) for each benefactor/reward kind - assert_eq!( - b2.state.balance(&addr1).unwrap(), - addr1_balance + (1000 + 0) + (1000 + 2), - ) - */ -} - // Check that the first block of Gnosis Chain, which doesn't have any transactions, // does not change the state root. func TestEmptyBlock(t *testing.T) { - if ethconfig.EnableHistoryV3InTest { - t.Skip("") - } - require := require.New(t) - genesis := core.DefaultGnosisGenesisBlock() - genesisBlock, _, err := genesis.ToBlock("") + genesis := core.GnosisGenesisBlock() + genesisBlock, _, err := core.GenesisToBlock(genesis, "") require.NoError(err) genesis.Config.TerminalTotalDifficultyPassed = false chainConfig := genesis.Config auraDB := memdb.NewTestDB(t) - engine, err := aura.NewAuRa(chainConfig.Aura, auraDB, chainConfig.Aura.Etherbase, consensusconfig.GetConfigByChain(chainConfig.ChainName)) + engine, err := aura.NewAuRa(chainConfig.Aura, auraDB) require.NoError(err) m := stages.MockWithGenesisEngine(t, genesis, engine, false) diff --git a/consensus/aura/config.go b/consensus/aura/config.go index 94ec56b8f73..00c12b4da27 100644 --- a/consensus/aura/config.go +++ b/consensus/aura/config.go @@ -22,9 +22,10 @@ import ( "sort" "github.com/holiman/uint256" + + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" - "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/common/u256" "github.com/ledgerwatch/erigon/consensus" ) @@ -38,19 +39,7 @@ func GetFromValidatorSet(set ValidatorSet, parent libcommon.Hash, nonce uint, ca return set.getWithCaller(parent, nonce, call) } -// Different ways of specifying validators. -type ValidatorSetJson struct { - // A simple list of authorities. - List []libcommon.Address `json:"list"` - // Address of a contract that indicates the list of authorities. - SafeContract *libcommon.Address `json:"safeContract"` - // Address of a contract that indicates the list of authorities and enables reporting of their misbehaviour using transactions. - Contract *libcommon.Address `json:"contract"` - // A map of starting blocks for each validator set. - Multi map[uint64]*ValidatorSetJson `json:"multi"` -} - -func newValidatorSetFromJson(j *ValidatorSetJson, posdaoTransition *uint64) ValidatorSet { +func newValidatorSetFromJson(j *chain.ValidatorSetJson, posdaoTransition *uint64) ValidatorSet { if j.List != nil { return &SimpleList{validators: j.List} } @@ -75,60 +64,6 @@ func newValidatorSetFromJson(j *ValidatorSetJson, posdaoTransition *uint64) Vali return nil } -// TODO: StepDuration and BlockReward - now are uint64, but it can be an object in non-sokol consensus -type JsonSpec struct { - StepDuration *uint64 `json:"stepDuration"` // Block duration, in seconds. - Validators *ValidatorSetJson `json:"validators"` // Valid authorities - - // Starting step. Determined automatically if not specified. - // To be used for testing only. - StartStep *uint64 `json:"startStep"` - ValidateScoreTransition *uint64 `json:"validateScoreTransition"` // Block at which score validation should start. - ValidateStepTransition *uint64 `json:"validateStepTransition"` // Block from which monotonic steps start. - ImmediateTransitions *bool `json:"immediateTransitions"` // Whether transitions should be immediate. - BlockReward *hexutil.Uint64 `json:"blockReward"` // Reward per block in wei. - // Block at which the block reward contract should start being used. This option allows one to - // add a single block reward contract transition and is compatible with the multiple address - // option `block_reward_contract_transitions` below. - BlockRewardContractTransition *uint64 `json:"blockRewardContractTransition"` - /// Block reward contract address which overrides the `block_reward` setting. This option allows - /// one to add a single block reward contract address and is compatible with the multiple - /// address option `block_reward_contract_transitions` below. - BlockRewardContractAddress *libcommon.Address `json:"blockRewardContractAddress"` - // Block reward contract addresses with their associated starting block numbers. - // - // Setting the block reward contract overrides `block_reward`. If the single block reward - // contract address is also present then it is added into the map at the block number stored in - // `block_reward_contract_transition` or 0 if that block number is not provided. Therefore both - // a single block reward contract transition and a map of reward contract transitions can be - // used simultaneously in the same configuration. In such a case the code requires that the - // block number of the single transition is strictly less than any of the block numbers in the - // map. - BlockRewardContractTransitions map[uint]libcommon.Address `json:"blockRewardContractTransitions"` - // Block at which maximum uncle count should be considered. - MaximumUncleCountTransition *uint64 `json:"maximumUncleCountTransition"` - // Maximum number of accepted uncles. - MaximumUncleCount *uint `json:"maximumUncleCount"` - // Strict validation of empty steps transition block. - StrictEmptyStepsTransition *uint `json:"strictEmptyStepsTransition"` - // The random number contract's address, or a map of contract transitions. - RandomnessContractAddress map[uint64]libcommon.Address `json:"randomnessContractAddress"` - // The addresses of contracts that determine the block gas limit starting from the block number - // associated with each of those contracts. - BlockGasLimitContractTransitions map[uint64]libcommon.Address `json:"blockGasLimitContractTransitions"` - // The block number at which the consensus engine switches from AuRa to AuRa with POSDAO - // modifications. - PosdaoTransition *uint64 `json:"PosdaoTransition"` - // Stores human-readable keys associated with addresses, like DNS information. - // This contract is primarily required to store the address of the Certifier contract. - Registrar *libcommon.Address `json:"registrar"` - - // See https://github.com/gnosischain/specs/blob/master/execution/withdrawals.md - WithdrawalContractAddress *libcommon.Address `json:"withdrawalContractAddress"` - - RewriteBytecode map[uint64]map[libcommon.Address]hexutil.Bytes `json:"rewriteBytecode"` -} - type Code struct { Code []byte CodeHash libcommon.Hash @@ -206,7 +141,7 @@ type AuthorityRoundParams struct { RewriteBytecode map[uint64]map[libcommon.Address][]byte } -func FromJson(jsonParams JsonSpec) (AuthorityRoundParams, error) { +func FromJson(jsonParams *chain.AuRaConfig) (AuthorityRoundParams, error) { params := AuthorityRoundParams{ Validators: newValidatorSetFromJson(jsonParams.Validators, jsonParams.PosdaoTransition), StartStep: jsonParams.StartStep, @@ -257,7 +192,7 @@ func FromJson(jsonParams JsonSpec) (AuthorityRoundParams, error) { params.BlockReward = append(params.BlockReward, BlockReward{blockNum: 0, amount: u256.Num0}) } else { if jsonParams.BlockReward != nil { - params.BlockReward = append(params.BlockReward, BlockReward{blockNum: 0, amount: uint256.NewInt(uint64(*jsonParams.BlockReward))}) + params.BlockReward = append(params.BlockReward, BlockReward{blockNum: 0, amount: uint256.NewInt(*jsonParams.BlockReward)}) } } sort.Sort(params.BlockReward) diff --git a/consensus/aura/config_test.go b/consensus/aura/config_test.go index c68eb17cf2d..a910625fd9a 100644 --- a/consensus/aura/config_test.go +++ b/consensus/aura/config_test.go @@ -1,21 +1,18 @@ package aura import ( - "encoding/json" "testing" - libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/ledgerwatch/erigon/consensus/aura/consensusconfig" - "github.com/ledgerwatch/erigon/params/networkname" + libcommon "github.com/ledgerwatch/erigon-lib/common" + + "github.com/ledgerwatch/erigon/params" ) func TestGnosisBlockRewardContractTransitions(t *testing.T) { - config := consensusconfig.GetConfigByChain(networkname.GnosisChainName) - spec := JsonSpec{} - require.NoError(t, json.Unmarshal(config, &spec)) + spec := params.GnosisChainConfig.Aura param, err := FromJson(spec) require.NoError(t, err) @@ -28,14 +25,12 @@ func TestGnosisBlockRewardContractTransitions(t *testing.T) { } func TestInvalidBlockRewardContractTransition(t *testing.T) { - config := consensusconfig.GetConfigByChain(networkname.GnosisChainName) - spec := JsonSpec{} - require.NoError(t, json.Unmarshal(config, &spec)) + spec := *(params.GnosisChainConfig.Aura) // blockRewardContractTransition should be smaller than any block number in blockRewardContractTransitions invalidTransition := uint64(10_000_000) spec.BlockRewardContractTransition = &invalidTransition - _, err := FromJson(spec) + _, err := FromJson(&spec) assert.Error(t, err) } diff --git a/consensus/aura/consensusconfig/embed.go b/consensus/aura/consensusconfig/embed.go deleted file mode 100644 index ff58ed20216..00000000000 --- a/consensus/aura/consensusconfig/embed.go +++ /dev/null @@ -1,32 +0,0 @@ -package consensusconfig - -import ( - _ "embed" - - "github.com/ledgerwatch/erigon/params/networkname" -) - -//go:embed poasokol.json -var Sokol []byte - -//go:embed poagnosis.json -var Gnosis []byte - -//go:embed poachiado.json -var Chiado []byte - -//go:embed test.json -var Test []byte - -func GetConfigByChain(chainName string) []byte { - switch chainName { - case networkname.SokolChainName: - return Sokol - case networkname.GnosisChainName: - return Gnosis - case networkname.ChiadoChainName: - return Chiado - default: - return Test - } -} diff --git a/consensus/aura/consensusconfig/kovan.json b/consensus/aura/consensusconfig/kovan.json deleted file mode 100644 index 603a5fbdd31..00000000000 --- a/consensus/aura/consensusconfig/kovan.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "stepDuration": 4, - "blockReward": "0x4563918244F40000", - "validators": { - "multi": { - "0": { - "list": [ - "0x00D6Cc1BA9cf89BD2e58009741f4F7325BAdc0ED", - "0x00427feae2419c15b89d1c21af10d1b6650a4d3d", - "0x4Ed9B08e6354C70fE6F8CB0411b0d3246b424d6c", - "0x0020ee4Be0e2027d76603cB751eE069519bA81A1", - "0x0010f94b296a852aaac52ea6c5ac72e03afd032d", - "0x007733a1FE69CF3f2CF989F81C7b4cAc1693387A", - "0x00E6d2b931F55a3f1701c7389d592a7778897879", - "0x00e4a10650e5a6D6001C38ff8E64F97016a1645c", - "0x00a0a24b9f0e5ec7aa4c7389b8302fd0123194de" - ] - }, - "10960440": { - "list": [ - "0x00D6Cc1BA9cf89BD2e58009741f4F7325BAdc0ED", - "0x0010f94b296a852aaac52ea6c5ac72e03afd032d", - "0x00a0a24b9f0e5ec7aa4c7389b8302fd0123194de" - ] - }, - "10960500": { - "safeContract": "0xaE71807C1B0a093cB1547b682DC78316D945c9B8" - } - } - }, - "validateScoreTransition": 4301764, - "validateStepTransition": 1500000, - "maximumUncleCountTransition": 5067000, - "maximumUncleCount": 0 -} - diff --git a/consensus/aura/consensusconfig/poachiado.json b/consensus/aura/consensusconfig/poachiado.json deleted file mode 100644 index f64e714cb11..00000000000 --- a/consensus/aura/consensusconfig/poachiado.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "stepDuration": 5, - "blockReward": "0x0", - "maximumUncleCountTransition": 0, - "maximumUncleCount": 0, - "validators": { - "multi": { - "0": { - "list": ["0x14747a698Ec1227e6753026C08B29b4d5D3bC484"] - }, - "67334": { - "list": [ - "0x14747a698Ec1227e6753026C08B29b4d5D3bC484", - "0x56D421c0AC39976E89fa400d34ca6579417B84cA", - "0x5CD99ac2F0F8C25a1e670F6BaB19D52Aad69D875", - "0x60F1CF46B42Df059b98Acf67C1dD7771b100e124", - "0x655e97bA0f63A56c2b56EB3e84f7bf42b20Bae14", - "0x755B6259938D140626301c0B6026c1C00C9eD5d9", - "0xa8010da9Cb0AC018C86A06301963853CC371a18c" - ] - } - } - }, - "blockRewardContractAddress": "0x2000000000000000000000000000000000000001", - "blockRewardContractTransition": 0, - "randomnessContractAddress": { - "0": "0x3000000000000000000000000000000000000001" - }, - "posdaoTransition": 0, - "blockGasLimitContractTransitions": { - "0": "0x4000000000000000000000000000000000000001" - }, - "registrar": "0x6000000000000000000000000000000000000000" -} diff --git a/consensus/aura/consensusconfig/poagnosis.json b/consensus/aura/consensusconfig/poagnosis.json deleted file mode 100644 index e9fc20cb9b2..00000000000 --- a/consensus/aura/consensusconfig/poagnosis.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "stepDuration": 5, - "blockReward": "0x0", - "maximumUncleCountTransition": 0, - "maximumUncleCount": 0, - "validators": { - "multi": { - "0": { - "list": [ - "0xcace5b3c29211740e595850e80478416ee77ca21" - ] - }, - "1300": { - "safeContract": "0x22e1229a2c5b95a60983b5577f745a603284f535" - }, - "9186425": { - "contract": "0xB87BE9f7196F2AE084Ca1DE6af5264292976e013" - } - } - }, - "blockRewardContractAddress": "0x867305d19606aadba405ce534e303d0e225f9556", - "blockRewardContractTransition": 1310, - "blockRewardContractTransitions": { - "9186425": "0x481c034c6d9441db23ea48de68bcae812c5d39ba" - }, - "randomnessContractAddress": { - "9186425": "0x5870b0527DeDB1cFBD9534343Feda1a41Ce47766" - }, - "posdaoTransition": 9186425, - "registrar": "0x6B53721D4f2Fb9514B85f5C49b197D857e36Cf03", - "rewriteBytecode": { - "21735000": { - "0xf8D1677c8a0c961938bf2f9aDc3F3CFDA759A9d9": "0x6080604052600436106101b35763ffffffff60e060020a60003504166305d2035b81146101b857806306fdde03146101e1578063095ea7b31461026b5780630b26cf661461028f57806318160ddd146102b257806323b872dd146102d957806330adf81f14610303578063313ce567146103185780633644e5151461034357806339509351146103585780634000aea01461037c57806340c10f19146103ad57806342966c68146103d157806354fd4d50146103e957806366188463146103fe57806369ffa08a1461042257806370a0823114610449578063715018a61461046a578063726600ce1461047f5780637d64bcb4146104a05780637ecebe00146104b5578063859ba28c146104d65780638da5cb5b146105175780638fcbaf0c1461054857806395d89b4114610586578063a457c2d71461059b578063a9059cbb146105bf578063b753a98c146105e3578063bb35783b14610607578063c6a1dedf14610631578063cd59658314610646578063d505accf1461065b578063d73dd62314610694578063dd62ed3e146106b8578063f2d5d56b146106df578063f2fde38b14610703578063ff9e884d14610724575b600080fd5b3480156101c457600080fd5b506101cd61074b565b604080519115158252519081900360200190f35b3480156101ed57600080fd5b506101f661076c565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610230578181015183820152602001610218565b50505050905090810190601f16801561025d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561027757600080fd5b506101cd600160a060020a03600435166024356107fa565b34801561029b57600080fd5b506102b0600160a060020a0360043516610810565b005b3480156102be57600080fd5b506102c761086a565b60408051918252519081900360200190f35b3480156102e557600080fd5b506101cd600160a060020a0360043581169060243516604435610870565b34801561030f57600080fd5b506102c7610a38565b34801561032457600080fd5b5061032d610a5c565b6040805160ff9092168252519081900360200190f35b34801561034f57600080fd5b506102c7610a65565b34801561036457600080fd5b506101cd600160a060020a0360043516602435610a6b565b34801561038857600080fd5b506101cd60048035600160a060020a0316906024803591604435918201910135610aac565b3480156103b957600080fd5b506101cd600160a060020a0360043516602435610bbd565b3480156103dd57600080fd5b506102b0600435610cc8565b3480156103f557600080fd5b506101f6610cd5565b34801561040a57600080fd5b506101cd600160a060020a0360043516602435610d0c565b34801561042e57600080fd5b506102b0600160a060020a0360043581169060243516610de9565b34801561045557600080fd5b506102c7600160a060020a0360043516610e0e565b34801561047657600080fd5b506102b0610e29565b34801561048b57600080fd5b506101cd600160a060020a0360043516610e40565b3480156104ac57600080fd5b506101cd610e54565b3480156104c157600080fd5b506102c7600160a060020a0360043516610e5b565b3480156104e257600080fd5b506104eb610e6d565b6040805167ffffffffffffffff9485168152928416602084015292168183015290519081900360600190f35b34801561052357600080fd5b5061052c610e78565b60408051600160a060020a039092168252519081900360200190f35b34801561055457600080fd5b506102b0600160a060020a0360043581169060243516604435606435608435151560ff60a4351660c43560e435610e87565b34801561059257600080fd5b506101f6610fc5565b3480156105a757600080fd5b506101cd600160a060020a036004351660243561101f565b3480156105cb57600080fd5b506101cd600160a060020a0360043516602435611032565b3480156105ef57600080fd5b506102b0600160a060020a0360043516602435611054565b34801561061357600080fd5b506102b0600160a060020a0360043581169060243516604435611064565b34801561063d57600080fd5b506102c7611075565b34801561065257600080fd5b5061052c611099565b34801561066757600080fd5b506102b0600160a060020a036004358116906024351660443560643560ff6084351660a43560c4356110a8565b3480156106a057600080fd5b506101cd600160a060020a0360043516602435611184565b3480156106c457600080fd5b506102c7600160a060020a036004358116906024351661120b565b3480156106eb57600080fd5b506102b0600160a060020a0360043516602435611236565b34801561070f57600080fd5b506102b0600160a060020a0360043516611241565b34801561073057600080fd5b506102c7600160a060020a0360043581169060243516611261565b60065474010000000000000000000000000000000000000000900460ff1681565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156107f25780601f106107c7576101008083540402835291602001916107f2565b820191906000526020600020905b8154815290600101906020018083116107d557829003601f168201915b505050505081565b600061080733848461127e565b50600192915050565b600654600160a060020a0316331461082757600080fd5b610830816112c0565b151561083b57600080fd5b6007805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b60045490565b600080600160a060020a038516151561088857600080fd5b600160a060020a038416151561089d57600080fd5b600160a060020a0385166000908152600360205260409020546108c6908463ffffffff6112c816565b600160a060020a0380871660009081526003602052604080822093909355908616815220546108fb908463ffffffff6112da16565b600160a060020a038086166000818152600360209081526040918290209490945580518781529051919392891692600080516020611d7283398151915292918290030190a3600160a060020a0385163314610a225761095a853361120b565b905060001981146109c457610975818463ffffffff6112c816565b600160a060020a038616600081815260056020908152604080832033808552908352928190208590558051948552519193600080516020611d92833981519152929081900390910190a3610a22565b600160a060020a0385166000908152600a602090815260408083203384529091529020541580610a175750600160a060020a0385166000908152600a602090815260408083203384529091529020544211155b1515610a2257600080fd5b610a2d8585856112ed565b506001949350505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60025460ff1681565b60085481565b336000818152600560209081526040808320600160a060020a03871684529091528120549091610807918590610aa7908663ffffffff6112da16565b61127e565b600084600160a060020a03811615801590610ad05750600160a060020a0381163014155b1515610adb57600080fd5b610ae58686611324565b1515610af057600080fd5b85600160a060020a031633600160a060020a03167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16878787604051808481526020018060200182810382528484828181526020019250808284376040519201829003965090945050505050a3610b65866112c0565b15610bb157610ba633878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843750611330945050505050565b1515610bb157600080fd5b50600195945050505050565b600654600090600160a060020a03163314610bd757600080fd5b60065474010000000000000000000000000000000000000000900460ff1615610bff57600080fd5b600454610c12908363ffffffff6112da16565b600455600160a060020a038316600090815260036020526040902054610c3e908363ffffffff6112da16565b600160a060020a038416600081815260036020908152604091829020939093558051858152905191927f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688592918290030190a2604080518381529051600160a060020a03851691600091600080516020611d728339815191529181900360200190a350600192915050565b610cd233826114ad565b50565b60408051808201909152600181527f3100000000000000000000000000000000000000000000000000000000000000602082015281565b336000908152600560209081526040808320600160a060020a0386168452909152812054808310610d6057336000908152600560209081526040808320600160a060020a0388168452909152812055610d95565b610d70818463ffffffff6112c816565b336000908152600560209081526040808320600160a060020a03891684529091529020555b336000818152600560209081526040808320600160a060020a038916808552908352928190205481519081529051929392600080516020611d92833981519152929181900390910190a35060019392505050565b600654600160a060020a03163314610e0057600080fd5b610e0a828261159c565b5050565b600160a060020a031660009081526003602052604090205490565b600654600160a060020a031633146101b357600080fd5b600754600160a060020a0390811691161490565b6000806000fd5b60096020526000908152604090205481565b600260056000909192565b600654600160a060020a031681565b600080861580610e975750864211155b1515610ea257600080fd5b604080517fea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb6020820152600160a060020a03808d16828401528b166060820152608081018a905260a0810189905287151560c0808301919091528251808303909101815260e0909101909152610f17906115da565b9150610f25828686866116e1565b600160a060020a038b8116911614610f3c57600080fd5b600160a060020a038a1660009081526009602052604090208054600181019091558814610f6857600080fd5b85610f74576000610f78565b6000195b905085610f86576000610f88565b865b600160a060020a03808c166000908152600a60209081526040808320938e1683529290522055610fb98a8a836118e3565b50505050505050505050565b60018054604080516020600284861615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156107f25780601f106107c7576101008083540402835291602001916107f2565b600061102b8383610d0c565b9392505050565b600061103e8383611324565b151561104957600080fd5b6108073384846112ed565b61105f338383610870565b505050565b61106f838383610870565b50505050565b7fea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb81565b600754600160a060020a031690565b600080428610156110b857600080fd5b600160a060020a03808a1660008181526009602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c99281019290925281830193909352928b166060840152608083018a905260a0830182905260c08084018a90528151808503909101815260e090930190529250611149906115da565b9050611157818686866116e1565b600160a060020a038a811691161461116e57600080fd5b61117989898961127e565b505050505050505050565b336000908152600560209081526040808320600160a060020a03861684529091528120546111b8908363ffffffff6112da16565b336000818152600560209081526040808320600160a060020a038916808552908352928190208590558051948552519193600080516020611d92833981519152929081900390910190a350600192915050565b600160a060020a03918216600090815260056020908152604080832093909416825291909152205490565b61105f823383610870565b600654600160a060020a0316331461125857600080fd5b610cd281611a3e565b600a60209081526000928352604080842090915290825290205481565b6112898383836118e3565b60001981141561105f57600160a060020a038084166000908152600a60209081526040808320938616835292905290812055505050565b6000903b1190565b6000828211156112d457fe5b50900390565b818101828110156112e757fe5b92915050565b6112f682610e40565b1561105f5760408051600081526020810190915261131990849084908490611330565b151561105f57600080fd5b600061102b8383611abc565b600083600160a060020a031663a4c0ed3660e060020a028685856040516024018084600160a060020a0316600160a060020a0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156113a8578181015183820152602001611390565b50505050905090810190601f1680156113d55780820380516001836020036101000a031916815260200191505b5060408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909916989098178852518151919790965086955093509150819050838360005b8381101561146357818101518382015260200161144b565b50505050905090810190601f1680156114905780820380516001836020036101000a031916815260200191505b509150506000604051808303816000865af1979650505050505050565b600160a060020a0382166000908152600360205260409020548111156114d257600080fd5b600160a060020a0382166000908152600360205260409020546114fb908263ffffffff6112c816565b600160a060020a038316600090815260036020526040902055600454611527908263ffffffff6112c816565b600455604080518281529051600160a060020a038416917fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5919081900360200190a2604080518281529051600091600160a060020a03851691600080516020611d728339815191529181900360200190a35050565b80600160a060020a03811615156115b257600080fd5b600160a060020a03831615156115d0576115cb82611b8b565b61105f565b61105f8383611b97565b6000600854826040518082805190602001908083835b6020831061160f5780518252601f1990920191602091820191016115f0565b51815160209384036101000a6000190180199092169116179052604080519290940182900382207f190100000000000000000000000000000000000000000000000000000000000083830152602283019790975260428083019790975283518083039097018752606290910192839052855192945084935085019190508083835b602083106116af5780518252601f199092019160209182019101611690565b5181516020939093036101000a6000190180199091169216919091179052604051920182900390912095945050505050565b6000808460ff16601b14806116f957508460ff16601c145b1515611775576040805160e560020a62461bcd02815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611813576040805160e560020a62461bcd02815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60408051600080825260208083018085528a905260ff8916838501526060830188905260808301879052925160019360a0808501949193601f19840193928390039091019190865af115801561186d573d6000803e3d6000fd5b5050604051601f190151915050600160a060020a03811615156118da576040805160e560020a62461bcd02815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015290519081900360640190fd5b95945050505050565b600160a060020a0383161515611968576040805160e560020a62461bcd028152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a03821615156119ee576040805160e560020a62461bcd02815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a0380841660008181526005602090815260408083209487168084529482529182902085905581518581529151600080516020611d928339815191529281900390910190a3505050565b600160a060020a0381161515611a5357600080fd5b600654604051600160a060020a038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a36006805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b33600090815260036020526040812054821115611ad857600080fd5b600160a060020a0383161515611aed57600080fd5b33600090815260036020526040902054611b0d908363ffffffff6112c816565b3360009081526003602052604080822092909255600160a060020a03851681522054611b3f908363ffffffff6112da16565b600160a060020a038416600081815260036020908152604091829020939093558051858152905191923392600080516020611d728339815191529281900390910190a350600192915050565b3031610e0a8282611c44565b604080517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290518391600091600160a060020a038416916370a0823191602480830192602092919082900301818787803b158015611bfc57600080fd5b505af1158015611c10573d6000803e3d6000fd5b505050506040513d6020811015611c2657600080fd5b5051905061106f600160a060020a038516848363ffffffff611cac16565b604051600160a060020a0383169082156108fc029083906000818181858888f193505050501515610e0a578082611c79611d41565b600160a060020a039091168152604051908190036020019082f080158015611ca5573d6000803e3d6000fd5b5050505050565b82600160a060020a031663a9059cbb83836040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a0316815260200182815260200192505050600060405180830381600087803b158015611d0f57600080fd5b505af1158015611d23573d6000803e3d6000fd5b505050503d1561105f5760206000803e600051151561105f57600080fd5b604051602180611d51833901905600608060405260405160208060218339810160405251600160a060020a038116ff00ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925a165627a7a72305820b96bb0733a3e45fdddafa592f51114d0cf16cad047ad60b9b91ae91eb772c6940029" - } - } -} diff --git a/consensus/aura/consensusconfig/poasokol.json b/consensus/aura/consensusconfig/poasokol.json deleted file mode 100644 index 0c8775312a4..00000000000 --- a/consensus/aura/consensusconfig/poasokol.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "stepDuration": 5, - "blockReward": "0xDE0B6B3A7640000", - "maximumUncleCountTransition": 0, - "maximumUncleCount": 0, - "validators": { - "multi": { - "0": { - "safeContract": "0x8bf38d4764929064f2d4d3a56520a76ab3df415b" - }, - "362296": { - "safeContract": "0xf5cE3f5D0366D6ec551C74CCb1F67e91c56F2e34" - }, - "509355": { - "safeContract": "0x03048F666359CFD3C74a1A5b9a97848BF71d5038" - }, - "4622420": { - "safeContract": "0x4c6a159659CCcb033F4b2e2Be0C16ACC62b89DDB" - } - } - }, - "blockRewardContractAddress": "0x3145197AD50D7083D0222DE4fCCf67d9BD05C30D", - "blockRewardContractTransition": 4639000, - "randomnessContractAddress": { - "13391641": "0x8f2b78169B0970F11a762e56659Db52B59CBCf1B" - } -} - diff --git a/consensus/aura/consensusconfig/test.json b/consensus/aura/consensusconfig/test.json deleted file mode 100644 index 07cbe9760b5..00000000000 --- a/consensus/aura/consensusconfig/test.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "stepDuration": 5, - "blockReward": "0x0", - "maximumUncleCountTransition": 0, - "maximumUncleCount": 0, - "validators": { - "multi": { - "0": { - "safeContract": "0x8bf38d4764929064f2d4d3a56520a76ab3df415b" - }, - "362296": { - "safeContract": "0xf5cE3f5D0366D6ec551C74CCb1F67e91c56F2e34" - }, - "509355": { - "safeContract": "0x03048F666359CFD3C74a1A5b9a97848BF71d5038" - }, - "4622420": { - "safeContract": "0x4c6a159659CCcb033F4b2e2Be0C16ACC62b89DDB" - } - } - }, - "blockRewardContractAddress": "0x3145197AD50D7083D0222DE4fCCf67d9BD05C30D", - "blockRewardContractTransition": 4639000, - "randomnessContractAddress": { - "13391641": "0x8f2b78169B0970F11a762e56659Db52B59CBCf1B" - } -} - diff --git a/consensus/aura/oe-test/authority_round.json b/consensus/aura/oe-test/authority_round.json deleted file mode 100644 index 292760444d6..00000000000 --- a/consensus/aura/oe-test/authority_round.json +++ /dev/null @@ -1,96 +0,0 @@ -{ - "name": "TestAuthorityRound", - "engine": { - "authorityRound": { - "params": { - "stepDuration": 1, - "startStep": 2, - "validators": { - "list": [ - "0x7d577a597b2742b498cb5cf0c26cdcd726d39e6e", - "0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1" - ] - }, - "immediateTransitions": true - } - } - }, - "params": { - "gasLimitBoundDivisor": "0x0400", - "accountStartNonce": "0x0", - "maximumExtraDataSize": "0x20", - "minGasLimit": "0x1388", - "networkID" : "0x69", - "eip140Transition": "0x0", - "eip211Transition": "0x0", - "eip214Transition": "0x0", - "eip658Transition": "0x0" - }, - "genesis": { - "seal": { - "authorityRound": { - "step": "0x0", - "signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - } - }, - "difficulty": "0x20000", - "author": "0x0000000000000000000000000000000000000000", - "timestamp": "0x00", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "extraData": "0x", - "gasLimit": "0x222222" - }, - "accounts": { - "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, - "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, - "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, - "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, - "0000000000000000000000000000000000000005": { "balance": "1", "builtin": { "name": "modexp", "activate_at": 0, "pricing": { "modexp": { "divisor": 20 } } } }, - "0000000000000000000000000000000000000006": { - "balance": "1", - "builtin": { - "name": "alt_bn128_add", - "pricing": { - "0": { - "price": { "alt_bn128_const_operations": { "price": 500 }} - }, - "0x7fffffffffffff": { - "info": "EIP 1108 transition", - "price": { "alt_bn128_const_operations": { "price": 150 }} - } - } - } - }, - "0000000000000000000000000000000000000007": { - "balance": "1", - "builtin": { - "name": "alt_bn128_mul", - "pricing": { - "0": { - "price": { "alt_bn128_const_operations": { "price": 40000 }} - }, - "0x7fffffffffffff": { - "info": "EIP 1108 transition", - "price": { "alt_bn128_const_operations": { "price": 6000 }} - } - } - } - }, - "0000000000000000000000000000000000000008": { - "balance": "1", - "builtin": { - "name": "alt_bn128_pairing", - "pricing": { - "0": { - "price": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 }} - }, - "0x7fffffffffffff": { - "info": "EIP 1108 transition", - "price": { "alt_bn128_pairing": { "base": 45000, "pair": 34000 }} - } - } - } - }, - "9cce34f7ab185c7aba1b7c8140d620b4bda941d6": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" } - } -} diff --git a/consensus/aura/oe-test/authority_round_block_reward_contract.json b/consensus/aura/oe-test/authority_round_block_reward_contract.json deleted file mode 100644 index 4adb9a8d43c..00000000000 --- a/consensus/aura/oe-test/authority_round_block_reward_contract.json +++ /dev/null @@ -1,103 +0,0 @@ -{ - "name": "TestAuthorityRoundBlockRewardContract", - "engine": { - "authorityRound": { - "params": { - "stepDuration": 1, - "startStep": 2, - "validators": { - "list": [ - "0x7d577a597b2742b498cb5cf0c26cdcd726d39e6e", - "0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1" - ] - }, - "immediateTransitions": true, - "emptyStepsTransition": "1", - "maximumEmptySteps": "2", - "blockRewardContractAddress": "0x0000000000000000000000000000000000000042" - } - } - }, - "params": { - "gasLimitBoundDivisor": "0x0400", - "accountStartNonce": "0x0", - "maximumExtraDataSize": "0x20", - "minGasLimit": "0x1388", - "networkID" : "0x69", - "eip140Transition": "0x0", - "eip211Transition": "0x0", - "eip214Transition": "0x0", - "eip658Transition": "0x0" - }, - "genesis": { - "seal": { - "authorityRound": { - "step": "0x0", - "signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - } - }, - "difficulty": "0x20000", - "author": "0x0000000000000000000000000000000000000000", - "timestamp": "0x00", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "extraData": "0x", - "gasLimit": "0x222222" - }, - "accounts": { - "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, - "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, - "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, - "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, - "0000000000000000000000000000000000000005": { "balance": "1", "builtin": { "name": "modexp", "activate_at": 0, "pricing": { "modexp": { "divisor": 20 } } } }, - "0000000000000000000000000000000000000006": { - "balance": "1", - "builtin": { - "name": "alt_bn128_add", - "pricing": { - "0": { - "price": { "alt_bn128_const_operations": { "price": 500 }} - }, - "0x7fffffffffffff": { - "info": "EIP 1108 transition", - "price": { "alt_bn128_const_operations": { "price": 150 }} - } - } - } - }, - "0000000000000000000000000000000000000007": { - "balance": "1", - "builtin": { - "name": "alt_bn128_mul", - "pricing": { - "0": { - "price": { "alt_bn128_const_operations": { "price": 40000 }} - }, - "0x7fffffffffffff": { - "info": "EIP 1108 transition", - "price": { "alt_bn128_const_operations": { "price": 6000 }} - } - } - } - }, - "0000000000000000000000000000000000000008": { - "balance": "1", - "builtin": { - "name": "alt_bn128_pairing", - "pricing": { - "0": { - "price": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 }} - }, - "0x7fffffffffffff": { - "info": "EIP 1108 transition", - "price": { "alt_bn128_pairing": { "base": 45000, "pair": 34000 }} - } - } - } - }, - "9cce34f7ab185c7aba1b7c8140d620b4bda941d6": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" }, - "0000000000000000000000000000000000000042": { - "balance": "1", - "constructor": "6060604052341561000f57600080fd5b6102b88061001e6000396000f300606060405260043610610041576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063f91c289814610046575b600080fd5b341561005157600080fd5b610086600480803590602001908201803590602001919091929080359060200190820180359060200191909192905050610125565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156100cd5780820151818401526020810190506100b2565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561010f5780820151818401526020810190506100f4565b5050505090500194505050505060405180910390f35b61012d610264565b610135610278565b61013d610278565b600073fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561018d57600080fd5b85859050888890501415156101a157600080fd5b878790506040518059106101b25750595b90808252806020026020018201604052509150600090505b815181101561021d5785858281811015156101e157fe5b9050602002013561ffff166103e80161ffff16828281518110151561020257fe5b906020019060200201818152505080806001019150506101ca565b878783828280806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050915090915093509350505094509492505050565b602060405190810160405280600081525090565b6020604051908101604052806000815250905600a165627a7a723058201da0f164e75517fb8baf51f030b904032cb748334938e7386f63025bfb23f3de0029" - } - } -} diff --git a/consensus/aura/oe-test/authority_round_empty_steps.json b/consensus/aura/oe-test/authority_round_empty_steps.json deleted file mode 100644 index b884e8e15a3..00000000000 --- a/consensus/aura/oe-test/authority_round_empty_steps.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "TestAuthorityRoundEmptySteps", - "engine": { - "authorityRound": { - "params": { - "stepDuration": 1, - "startStep": 2, - "validators": { - "list": [ - "0x7d577a597b2742b498cb5cf0c26cdcd726d39e6e", - "0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1" - ] - }, - "blockReward": "10", - "immediateTransitions": true, - "emptyStepsTransition": "1", - "maximumEmptySteps": "2" - } - } - }, - "params": { - "gasLimitBoundDivisor": "0x0400", - "accountStartNonce": "0x0", - "maximumExtraDataSize": "0x20", - "minGasLimit": "0x1388", - "networkID" : "0x69" - }, - "genesis": { - "seal": { - "authorityRound": { - "step": "0x0", - "signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - } - }, - "difficulty": "0x20000", - "author": "0x0000000000000000000000000000000000000000", - "timestamp": "0x00", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "extraData": "0x", - "gasLimit": "0x222222" - }, - "accounts": { - "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, - "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, - "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, - "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, - "9cce34f7ab185c7aba1b7c8140d620b4bda941d6": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" }, - "7d577a597b2742b498cb5cf0c26cdcd726d39e6e": { "balance": "1000000000" }, - "82a978b3f5962a5b0957d9ee9eef472ee55b42f1": { "balance": "1000000000" } - } -} diff --git a/consensus/aura/oe-test/authority_round_randomness_contract.json b/consensus/aura/oe-test/authority_round_randomness_contract.json deleted file mode 100644 index 2c820ee7712..00000000000 --- a/consensus/aura/oe-test/authority_round_randomness_contract.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "name": "TestAuthorityRoundRandomnessContract", - "engine": { - "authorityRound": { - "params": { - "stepDuration": 1, - "startStep": 2, - "validators": { - "list": [ - "0x7d577a597b2742b498cb5cf0c26cdcd726d39e6e" - ] - }, - "immediateTransitions": true, - "maximumEmptySteps": "2", - "randomnessContractAddress": { - "0": "0x0000000000000000000000000000000000000042" - } - } - } - }, - "params": { - "gasLimitBoundDivisor": "0x0400", - "accountStartNonce": "0x0", - "maximumExtraDataSize": "0x20", - "minGasLimit": "0x1388", - "networkID" : "0x69", - "eip140Transition": "0x0", - "eip211Transition": "0x0", - "eip214Transition": "0x0", - "eip658Transition": "0x0" - }, - "genesis": { - "seal": { - "authorityRound": { - "step": "0x0", - "signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - } - }, - "difficulty": "0x20000", - "author": "0x0000000000000000000000000000000000000000", - "timestamp": "0x00", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "extraData": "0x", - "gasLimit": "0x222222" - }, - "accounts": { - "0x7d577a597b2742b498cb5cf0c26cdcd726d39e6e": { "balance": "100000000000" }, - "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, - "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, - "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, - "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, - "0000000000000000000000000000000000000005": { "balance": "1", "builtin": { "name": "modexp", "activate_at": 0, "pricing": { "modexp": { "divisor": 20 } } } }, - "0000000000000000000000000000000000000006": { - "balance": "1", - "builtin": { - "name": "alt_bn128_add", - "pricing": { - "0x0": { - "price": { "linear": { "base": 500, "word": 0 }} - }, - "0x7fffffffffffff": { - "price": { "linear": { "base": 150, "word": 0 }} - } - } - } - }, - "0000000000000000000000000000000000000007": { - "balance": "1", - "builtin": { - "name": "alt_bn128_mul", - "pricing": { - "0x0": { - "price": { "linear": { "base": 40000, "word": 0 }} - }, - "0x7fffffffffffff": { - "price": { "linear": { "base": 6000, "word": 0 }} - } - } - } - }, - "0000000000000000000000000000000000000008": { - "balance": "1", - "builtin": { - "name": "alt_bn128_pairing", - "pricing": { - "0x0": { - "price": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 }} - }, - "0x7fffffffffffff": { - "price": { "alt_bn128_pairing": { "base": 45000, "pair": 34000 }} - } - } - } - }, - "0000000000000000000000000000000000000042": { - "balance": "1", - "constructor": "608060405234801561001057600080fd5b50610820806100206000396000f3fe608060405234801561001057600080fd5b50600436106100ec576000357c01000000000000000000000000000000000000000000000000000000009004806363f160e6116100a95780637a3e286b116100835780637a3e286b14610378578063baf11cab14610380578063c358ced0146103ac578063fe7d567d146103b4576100ec565b806363f160e614610285578063695e89f6146102c557806374ce906714610370576100ec565b806304fdb016146100f15780630b61ba8514610192578063209652551461020b5780632e8a8dd5146102255780633fa4f245146102515780635580e58b14610259575b600080fd5b61011d6004803603604081101561010757600080fd5b5080359060200135600160a060020a03166103d1565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015757818101518382015260200161013f565b50505050905090810190601f1680156101845780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610209600480360360408110156101a857600080fd5b813591908101906040810160208201356401000000008111156101ca57600080fd5b8201836020820111156101dc57600080fd5b803590602001918460018302840111640100000000831117156101fe57600080fd5b509092509050610475565b005b6102136104fa565b60408051918252519081900360200190f35b6102136004803603604081101561023b57600080fd5b5080359060200135600160a060020a0316610501565b61021361051b565b6102136004803603604081101561026f57600080fd5b5080359060200135600160a060020a0316610521565b6102b16004803603604081101561029b57600080fd5b5080359060200135600160a060020a031661053e565b604080519115158252519081900360200190f35b6102f1600480360360408110156102db57600080fd5b5080359060200135600160a060020a0316610568565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561033457818101518382015260200161031c565b50505050905090810190601f1680156103615780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b6102b1610639565b610213610649565b6102b16004803603604081101561039657600080fd5b5080359060200135600160a060020a0316610654565b6102b161067c565b610209600480360360208110156103ca57600080fd5b5035610687565b600160208181526000938452604080852082529284529282902080548351600293821615610100026000190190911692909204601f8101859004850283018501909352828252909290919083018282801561046d5780601f106104425761010080835404028352916020019161046d565b820191906000526020600020905b81548152906001019060200180831161045057829003601f168201915b505050505081565b41331461048157600080fd5b61048d60014303610735565b61049657600080fd5b60006104a460014303610740565b90506104b08133610654565b156104ba57600080fd5b600081815260208181526040808320338085529083528184208890558484526001835281842090845290915290206104f3908484610753565b5050505050565b6003545b90565b600060208181529281526040808220909352908152205481565b60035481565b600260209081526000928352604080842090915290825290205481565b6000918252600260209081526040808420600160a060020a03939093168452919052902054151590565b600082815260208181526040808320600160a060020a03851680855290835281842054868552600180855283862092865291845282852080548451600294821615610100026000190190911693909304601f810186900486028401860190945283835260609491939092918391908301828280156106275780601f106105fc57610100808354040283529160200191610627565b820191906000526020600020905b81548152906001019060200180831161060a57829003601f168201915b50505050509050915091509250929050565b600061064443610735565b905090565b600061064443610740565b600091825260208281526040808420600160a060020a03939093168452919052902054151590565b600061064443610747565b41331461069357600080fd5b61069f60014303610747565b6106a857600080fd5b60006106b660014303610740565b90506106c2813361053e565b156106cc57600080fd5b60408051602080820185905282518083038201815291830183528151918101919091206000848152808352838120338252909252919020541461070e57600080fd5b60009081526002602090815260408083203384529091529020819055600380549091189055565b600360069091061090565b6006900490565b60036006909106101590565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106107945782800160ff198235161785556107c1565b828001600101855582156107c1579182015b828111156107c15782358255916020019190600101906107a6565b506107cd9291506107d1565b5090565b6104fe91905b808211156107cd57600081556001016107d756fea265627a7a7230582008bb7311af9026bd70ddb998741333d414a366275b9b433a2943bbd6bedc27ae64736f6c634300050a0032" - } - } -} \ No newline at end of file diff --git a/consensus/aura/test/authority_round.json b/consensus/aura/test/authority_round.json deleted file mode 100644 index 292760444d6..00000000000 --- a/consensus/aura/test/authority_round.json +++ /dev/null @@ -1,96 +0,0 @@ -{ - "name": "TestAuthorityRound", - "engine": { - "authorityRound": { - "params": { - "stepDuration": 1, - "startStep": 2, - "validators": { - "list": [ - "0x7d577a597b2742b498cb5cf0c26cdcd726d39e6e", - "0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1" - ] - }, - "immediateTransitions": true - } - } - }, - "params": { - "gasLimitBoundDivisor": "0x0400", - "accountStartNonce": "0x0", - "maximumExtraDataSize": "0x20", - "minGasLimit": "0x1388", - "networkID" : "0x69", - "eip140Transition": "0x0", - "eip211Transition": "0x0", - "eip214Transition": "0x0", - "eip658Transition": "0x0" - }, - "genesis": { - "seal": { - "authorityRound": { - "step": "0x0", - "signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - } - }, - "difficulty": "0x20000", - "author": "0x0000000000000000000000000000000000000000", - "timestamp": "0x00", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "extraData": "0x", - "gasLimit": "0x222222" - }, - "accounts": { - "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, - "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, - "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, - "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, - "0000000000000000000000000000000000000005": { "balance": "1", "builtin": { "name": "modexp", "activate_at": 0, "pricing": { "modexp": { "divisor": 20 } } } }, - "0000000000000000000000000000000000000006": { - "balance": "1", - "builtin": { - "name": "alt_bn128_add", - "pricing": { - "0": { - "price": { "alt_bn128_const_operations": { "price": 500 }} - }, - "0x7fffffffffffff": { - "info": "EIP 1108 transition", - "price": { "alt_bn128_const_operations": { "price": 150 }} - } - } - } - }, - "0000000000000000000000000000000000000007": { - "balance": "1", - "builtin": { - "name": "alt_bn128_mul", - "pricing": { - "0": { - "price": { "alt_bn128_const_operations": { "price": 40000 }} - }, - "0x7fffffffffffff": { - "info": "EIP 1108 transition", - "price": { "alt_bn128_const_operations": { "price": 6000 }} - } - } - } - }, - "0000000000000000000000000000000000000008": { - "balance": "1", - "builtin": { - "name": "alt_bn128_pairing", - "pricing": { - "0": { - "price": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 }} - }, - "0x7fffffffffffff": { - "info": "EIP 1108 transition", - "price": { "alt_bn128_pairing": { "base": 45000, "pair": 34000 }} - } - } - } - }, - "9cce34f7ab185c7aba1b7c8140d620b4bda941d6": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" } - } -} diff --git a/consensus/aura/test/authority_round_block_reward_contract.json b/consensus/aura/test/authority_round_block_reward_contract.json deleted file mode 100644 index d3b62b76d54..00000000000 --- a/consensus/aura/test/authority_round_block_reward_contract.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "stepDuration": 1, - "startStep": 2, - "validators": { - "list": [ - "0x7d577a597b2742b498cb5cf0c26cdcd726d39e6e", - "0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1" - ] - }, - "immediateTransitions": true, - "emptyStepsTransition": 1, - "maximumEmptySteps": 2, - "blockRewardContractAddress": "0x0000000000000000000000000000000000000042" -} \ No newline at end of file diff --git a/consensus/aura/test/authority_round_empty_steps.json b/consensus/aura/test/authority_round_empty_steps.json deleted file mode 100644 index b884e8e15a3..00000000000 --- a/consensus/aura/test/authority_round_empty_steps.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "TestAuthorityRoundEmptySteps", - "engine": { - "authorityRound": { - "params": { - "stepDuration": 1, - "startStep": 2, - "validators": { - "list": [ - "0x7d577a597b2742b498cb5cf0c26cdcd726d39e6e", - "0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1" - ] - }, - "blockReward": "10", - "immediateTransitions": true, - "emptyStepsTransition": "1", - "maximumEmptySteps": "2" - } - } - }, - "params": { - "gasLimitBoundDivisor": "0x0400", - "accountStartNonce": "0x0", - "maximumExtraDataSize": "0x20", - "minGasLimit": "0x1388", - "networkID" : "0x69" - }, - "genesis": { - "seal": { - "authorityRound": { - "step": "0x0", - "signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - } - }, - "difficulty": "0x20000", - "author": "0x0000000000000000000000000000000000000000", - "timestamp": "0x00", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "extraData": "0x", - "gasLimit": "0x222222" - }, - "accounts": { - "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, - "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, - "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, - "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, - "9cce34f7ab185c7aba1b7c8140d620b4bda941d6": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" }, - "7d577a597b2742b498cb5cf0c26cdcd726d39e6e": { "balance": "1000000000" }, - "82a978b3f5962a5b0957d9ee9eef472ee55b42f1": { "balance": "1000000000" } - } -} diff --git a/consensus/aura/test/authority_round_randomness_contract.json b/consensus/aura/test/authority_round_randomness_contract.json deleted file mode 100644 index 2c820ee7712..00000000000 --- a/consensus/aura/test/authority_round_randomness_contract.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "name": "TestAuthorityRoundRandomnessContract", - "engine": { - "authorityRound": { - "params": { - "stepDuration": 1, - "startStep": 2, - "validators": { - "list": [ - "0x7d577a597b2742b498cb5cf0c26cdcd726d39e6e" - ] - }, - "immediateTransitions": true, - "maximumEmptySteps": "2", - "randomnessContractAddress": { - "0": "0x0000000000000000000000000000000000000042" - } - } - } - }, - "params": { - "gasLimitBoundDivisor": "0x0400", - "accountStartNonce": "0x0", - "maximumExtraDataSize": "0x20", - "minGasLimit": "0x1388", - "networkID" : "0x69", - "eip140Transition": "0x0", - "eip211Transition": "0x0", - "eip214Transition": "0x0", - "eip658Transition": "0x0" - }, - "genesis": { - "seal": { - "authorityRound": { - "step": "0x0", - "signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - } - }, - "difficulty": "0x20000", - "author": "0x0000000000000000000000000000000000000000", - "timestamp": "0x00", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "extraData": "0x", - "gasLimit": "0x222222" - }, - "accounts": { - "0x7d577a597b2742b498cb5cf0c26cdcd726d39e6e": { "balance": "100000000000" }, - "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, - "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, - "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, - "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, - "0000000000000000000000000000000000000005": { "balance": "1", "builtin": { "name": "modexp", "activate_at": 0, "pricing": { "modexp": { "divisor": 20 } } } }, - "0000000000000000000000000000000000000006": { - "balance": "1", - "builtin": { - "name": "alt_bn128_add", - "pricing": { - "0x0": { - "price": { "linear": { "base": 500, "word": 0 }} - }, - "0x7fffffffffffff": { - "price": { "linear": { "base": 150, "word": 0 }} - } - } - } - }, - "0000000000000000000000000000000000000007": { - "balance": "1", - "builtin": { - "name": "alt_bn128_mul", - "pricing": { - "0x0": { - "price": { "linear": { "base": 40000, "word": 0 }} - }, - "0x7fffffffffffff": { - "price": { "linear": { "base": 6000, "word": 0 }} - } - } - } - }, - "0000000000000000000000000000000000000008": { - "balance": "1", - "builtin": { - "name": "alt_bn128_pairing", - "pricing": { - "0x0": { - "price": { "alt_bn128_pairing": { "base": 100000, "pair": 80000 }} - }, - "0x7fffffffffffff": { - "price": { "alt_bn128_pairing": { "base": 45000, "pair": 34000 }} - } - } - } - }, - "0000000000000000000000000000000000000042": { - "balance": "1", - "constructor": "608060405234801561001057600080fd5b50610820806100206000396000f3fe608060405234801561001057600080fd5b50600436106100ec576000357c01000000000000000000000000000000000000000000000000000000009004806363f160e6116100a95780637a3e286b116100835780637a3e286b14610378578063baf11cab14610380578063c358ced0146103ac578063fe7d567d146103b4576100ec565b806363f160e614610285578063695e89f6146102c557806374ce906714610370576100ec565b806304fdb016146100f15780630b61ba8514610192578063209652551461020b5780632e8a8dd5146102255780633fa4f245146102515780635580e58b14610259575b600080fd5b61011d6004803603604081101561010757600080fd5b5080359060200135600160a060020a03166103d1565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015757818101518382015260200161013f565b50505050905090810190601f1680156101845780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610209600480360360408110156101a857600080fd5b813591908101906040810160208201356401000000008111156101ca57600080fd5b8201836020820111156101dc57600080fd5b803590602001918460018302840111640100000000831117156101fe57600080fd5b509092509050610475565b005b6102136104fa565b60408051918252519081900360200190f35b6102136004803603604081101561023b57600080fd5b5080359060200135600160a060020a0316610501565b61021361051b565b6102136004803603604081101561026f57600080fd5b5080359060200135600160a060020a0316610521565b6102b16004803603604081101561029b57600080fd5b5080359060200135600160a060020a031661053e565b604080519115158252519081900360200190f35b6102f1600480360360408110156102db57600080fd5b5080359060200135600160a060020a0316610568565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561033457818101518382015260200161031c565b50505050905090810190601f1680156103615780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b6102b1610639565b610213610649565b6102b16004803603604081101561039657600080fd5b5080359060200135600160a060020a0316610654565b6102b161067c565b610209600480360360208110156103ca57600080fd5b5035610687565b600160208181526000938452604080852082529284529282902080548351600293821615610100026000190190911692909204601f8101859004850283018501909352828252909290919083018282801561046d5780601f106104425761010080835404028352916020019161046d565b820191906000526020600020905b81548152906001019060200180831161045057829003601f168201915b505050505081565b41331461048157600080fd5b61048d60014303610735565b61049657600080fd5b60006104a460014303610740565b90506104b08133610654565b156104ba57600080fd5b600081815260208181526040808320338085529083528184208890558484526001835281842090845290915290206104f3908484610753565b5050505050565b6003545b90565b600060208181529281526040808220909352908152205481565b60035481565b600260209081526000928352604080842090915290825290205481565b6000918252600260209081526040808420600160a060020a03939093168452919052902054151590565b600082815260208181526040808320600160a060020a03851680855290835281842054868552600180855283862092865291845282852080548451600294821615610100026000190190911693909304601f810186900486028401860190945283835260609491939092918391908301828280156106275780601f106105fc57610100808354040283529160200191610627565b820191906000526020600020905b81548152906001019060200180831161060a57829003601f168201915b50505050509050915091509250929050565b600061064443610735565b905090565b600061064443610740565b600091825260208281526040808420600160a060020a03939093168452919052902054151590565b600061064443610747565b41331461069357600080fd5b61069f60014303610747565b6106a857600080fd5b60006106b660014303610740565b90506106c2813361053e565b156106cc57600080fd5b60408051602080820185905282518083038201815291830183528151918101919091206000848152808352838120338252909252919020541461070e57600080fd5b60009081526002602090815260408083203384529091529020819055600380549091189055565b600360069091061090565b6006900490565b60036006909106101590565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106107945782800160ff198235161785556107c1565b828001600101855582156107c1579182015b828111156107c15782358255916020019190600101906107a6565b506107cd9291506107d1565b5090565b6104fe91905b808211156107cd57600081556001016107d756fea265627a7a7230582008bb7311af9026bd70ddb998741333d414a366275b9b433a2943bbd6bedc27ae64736f6c634300050a0032" - } - } -} \ No newline at end of file diff --git a/consensus/aura/test/embed.go b/consensus/aura/test/embed.go deleted file mode 100644 index 8d9a4bc5e80..00000000000 --- a/consensus/aura/test/embed.go +++ /dev/null @@ -1,8 +0,0 @@ -package test - -import ( - _ "embed" -) - -//go:embed authority_round_block_reward_contract.json -var AuthorityRoundBlockRewardContract []byte diff --git a/consensus/aura/validators.go b/consensus/aura/validators.go index 57de94dc0db..0e2b8ea0235 100644 --- a/consensus/aura/validators.go +++ b/consensus/aura/validators.go @@ -8,7 +8,7 @@ import ( "strings" "sync" - lru "github.com/hashicorp/golang-lru" + "github.com/hashicorp/golang-lru/v2" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/log/v3" "go.uber.org/atomic" @@ -412,8 +412,8 @@ func (q *ReportQueue) truncate() { // nolint type ValidatorSafeContract struct { contractAddress libcommon.Address - validators *lru.Cache // RwLock>, - reportQueue ReportQueue //Mutex, + validators *lru.Cache[libcommon.Hash, *SimpleList] // RwLock>, + reportQueue ReportQueue //Mutex, // The block number where we resent the queued reports last time. resentReportsInBlock atomic.Uint64 // If set, this is the block number at which the consensus engine switches from AuRa to AuRa @@ -426,7 +426,7 @@ type ValidatorSafeContract struct { func NewValidatorSafeContract(contractAddress libcommon.Address, posdaoTransition *uint64, client client) *ValidatorSafeContract { const MemoizeCapacity = 500 - c, err := lru.New(MemoizeCapacity) + c, err := lru.New[libcommon.Hash, *SimpleList](MemoizeCapacity) if err != nil { panic("error creating ValidatorSafeContract cache") } @@ -592,7 +592,7 @@ func (s *ValidatorSafeContract) defaultCaller(blockHash libcommon.Hash) (Call, e func (s *ValidatorSafeContract) getWithCaller(blockHash libcommon.Hash, nonce uint, caller consensus.Call) (libcommon.Address, error) { set, ok := s.validators.Get(blockHash) if ok { - return get(set.(ValidatorSet), blockHash, nonce, caller) + return get(set, blockHash, nonce, caller) } list, ok := s.getList(caller) @@ -605,7 +605,7 @@ func (s *ValidatorSafeContract) getWithCaller(blockHash libcommon.Hash, nonce ui func (s *ValidatorSafeContract) countWithCaller(parentHash libcommon.Hash, caller consensus.Call) (uint64, error) { set, ok := s.validators.Get(parentHash) if ok { - return count(set.(ValidatorSet), parentHash, caller) + return count(set, parentHash, caller) } list, ok := s.getList(caller) if !ok { diff --git a/consensus/bor/api.go b/consensus/bor/api.go index c8b5284bdb1..ca78de76494 100644 --- a/consensus/bor/api.go +++ b/consensus/bor/api.go @@ -8,8 +8,8 @@ import ( "strconv" "sync" - lru2 "github.com/hashicorp/golang-lru/v2" - libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/hashicorp/golang-lru/v2" + "github.com/ledgerwatch/erigon-lib/common" "github.com/xsleonard/go-merkle" "golang.org/x/crypto/sha3" @@ -30,7 +30,7 @@ var ( type API struct { chain consensus.ChainHeaderReader bor *Bor - rootHashCache *lru2.ARCCache[string, string] + rootHashCache *lru.ARCCache[string, string] } // GetSnapshot retrieves the state snapshot at a given block. @@ -53,15 +53,15 @@ func (api *API) GetSnapshot(number *rpc.BlockNumber) (*Snapshot, error) { type BlockSigners struct { Signers []difficultiesKV Diff int - Author libcommon.Address + Author common.Address } type difficultiesKV struct { - Signer libcommon.Address + Signer common.Address Difficulty uint64 } -func rankMapDifficulties(values map[libcommon.Address]uint64) []difficultiesKV { +func rankMapDifficulties(values map[common.Address]uint64) []difficultiesKV { ss := make([]difficultiesKV, 0, len(values)) for k, v := range values { ss = append(ss, difficultiesKV{k, v}) @@ -78,7 +78,7 @@ func rankMapDifficulties(values map[libcommon.Address]uint64) []difficultiesKV { func (api *API) GetSnapshotProposerSequence(number *rpc.BlockNumber) (BlockSigners, error) { snapNumber := *number - 1 - var difficulties = make(map[libcommon.Address]uint64) + var difficulties = make(map[common.Address]uint64) snap, err := api.GetSnapshot(&snapNumber) @@ -117,19 +117,19 @@ func (api *API) GetSnapshotProposerSequence(number *rpc.BlockNumber) (BlockSigne } // GetSnapshotProposer retrieves the in-turn signer at a given block. -func (api *API) GetSnapshotProposer(number *rpc.BlockNumber) (libcommon.Address, error) { +func (api *API) GetSnapshotProposer(number *rpc.BlockNumber) (common.Address, error) { *number -= 1 snap, err := api.GetSnapshot(number) if err != nil { - return libcommon.Address{}, err + return common.Address{}, err } return snap.ValidatorSet.GetProposer().Address, nil } // GetAuthor retrieves the author a block. -func (api *API) GetAuthor(number *rpc.BlockNumber) (*libcommon.Address, error) { +func (api *API) GetAuthor(number *rpc.BlockNumber) (*common.Address, error) { // Retrieve the requested block number (or current if none requested) var header *types.Header if number == nil || *number == rpc.LatestBlockNumber { @@ -148,7 +148,7 @@ func (api *API) GetAuthor(number *rpc.BlockNumber) (*libcommon.Address, error) { } // GetSnapshotAtHash retrieves the state snapshot at a given block. -func (api *API) GetSnapshotAtHash(hash libcommon.Hash) (*Snapshot, error) { +func (api *API) GetSnapshotAtHash(hash common.Hash) (*Snapshot, error) { header := api.chain.GetHeaderByHash(hash) if header == nil { return nil, errUnknownBlock @@ -158,7 +158,7 @@ func (api *API) GetSnapshotAtHash(hash libcommon.Hash) (*Snapshot, error) { } // GetSigners retrieves the list of authorized signers at the specified block. -func (api *API) GetSigners(number *rpc.BlockNumber) ([]libcommon.Address, error) { +func (api *API) GetSigners(number *rpc.BlockNumber) ([]common.Address, error) { // Retrieve the requested block number (or current if none requested) var header *types.Header if number == nil || *number == rpc.LatestBlockNumber { @@ -181,7 +181,7 @@ func (api *API) GetSigners(number *rpc.BlockNumber) ([]libcommon.Address, error) } // GetSignersAtHash retrieves the list of authorized signers at the specified block. -func (api *API) GetSignersAtHash(hash libcommon.Hash) ([]libcommon.Address, error) { +func (api *API) GetSignersAtHash(hash common.Hash) ([]common.Address, error) { header := api.chain.GetHeaderByHash(hash) if header == nil { return nil, errUnknownBlock @@ -197,10 +197,10 @@ func (api *API) GetSignersAtHash(hash libcommon.Hash) ([]libcommon.Address, erro } // GetCurrentProposer gets the current proposer -func (api *API) GetCurrentProposer() (libcommon.Address, error) { +func (api *API) GetCurrentProposer() (common.Address, error) { snap, err := api.GetSnapshot(nil) if err != nil { - return libcommon.Address{}, err + return common.Address{}, err } return snap.ValidatorSet.GetProposer().Address, nil @@ -289,7 +289,7 @@ func (api *API) GetRootHash(start uint64, end uint64) (string, error) { func (api *API) initializeRootHashCache() error { var err error if api.rootHashCache == nil { - api.rootHashCache, err = lru2.NewARC[string, string](10) + api.rootHashCache, err = lru.NewARC[string, string](10) } return err diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 583811953ac..c4759484fdd 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -760,7 +760,7 @@ func (c *Bor) Prepare(chain consensus.ChainHeaderReader, header *types.Header, s // rewards given. func (c *Bor) Finalize(config *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions, uncles []*types.Header, r types.Receipts, withdrawals []*types.Withdrawal, - e consensus.EpochReader, chain consensus.ChainHeaderReader, syscall consensus.SystemCall, + chain consensus.ChainHeaderReader, syscall consensus.SystemCall, ) (types.Transactions, types.Receipts, error) { var err error @@ -836,7 +836,7 @@ func (c *Bor) changeContractCodeIfNeeded(headerNumber uint64, state *state.Intra // nor block rewards given, and returns the final block. func (c *Bor) FinalizeAndAssemble(chainConfig *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, - e consensus.EpochReader, chain consensus.ChainHeaderReader, syscall consensus.SystemCall, call consensus.Call, + chain consensus.ChainHeaderReader, syscall consensus.SystemCall, call consensus.Call, ) (*types.Block, types.Transactions, types.Receipts, error) { // stateSyncData := []*types.StateSyncData{} @@ -885,7 +885,7 @@ func (c *Bor) GenerateSeal(chain consensus.ChainHeaderReader, currnt, parent *ty return nil } -func (c *Bor) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, e consensus.EpochReader, header *types.Header, +func (c *Bor) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, header *types.Header, state *state.IntraBlockState, txs []types.Transaction, uncles []*types.Header, syscall consensus.SystemCall) { } diff --git a/consensus/bor/clerk/clerk.go b/consensus/bor/clerk/clerk.go index 1069ce8d9a4..fa796213909 100644 --- a/consensus/bor/clerk/clerk.go +++ b/consensus/bor/clerk/clerk.go @@ -5,15 +5,14 @@ import ( "time" libcommon "github.com/ledgerwatch/erigon-lib/common" - - "github.com/ledgerwatch/erigon/common/hexutil" + "github.com/ledgerwatch/erigon-lib/common/hexutility" ) // EventRecord represents state record type EventRecord struct { ID uint64 `json:"id" yaml:"id"` Contract libcommon.Address `json:"contract" yaml:"contract"` - Data hexutil.Bytes `json:"data" yaml:"data"` + Data hexutility.Bytes `json:"data" yaml:"data"` TxHash libcommon.Hash `json:"tx_hash" yaml:"tx_hash"` LogIndex uint64 `json:"log_index" yaml:"log_index"` ChainID string `json:"bor_chain_id" yaml:"bor_chain_id"` diff --git a/consensus/bor/snapshot.go b/consensus/bor/snapshot.go index 1ebcb56b808..31f361d7276 100644 --- a/consensus/bor/snapshot.go +++ b/consensus/bor/snapshot.go @@ -5,9 +5,9 @@ import ( "context" "encoding/json" - lru2 "github.com/hashicorp/golang-lru/v2" + "github.com/hashicorp/golang-lru/v2" "github.com/ledgerwatch/erigon-lib/chain" - libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon/consensus/bor/valset" "github.com/ledgerwatch/erigon/core/types" @@ -15,19 +15,19 @@ import ( // Snapshot is the state of the authorization voting at a given point in time. type Snapshot struct { - config *chain.BorConfig // Consensus engine parameters to fine tune behavior - sigcache *lru2.ARCCache[libcommon.Hash, libcommon.Address] // Cache of recent block signatures to speed up ecrecover + config *chain.BorConfig // Consensus engine parameters to fine tune behavior + sigcache *lru.ARCCache[common.Hash, common.Address] // Cache of recent block signatures to speed up ecrecover - Number uint64 `json:"number"` // Block number where the snapshot was created - Hash libcommon.Hash `json:"hash"` // Block hash where the snapshot was created - ValidatorSet *valset.ValidatorSet `json:"validatorSet"` // Validator set at this moment - Recents map[uint64]libcommon.Address `json:"recents"` // Set of recent signers for spam protections + Number uint64 `json:"number"` // Block number where the snapshot was created + Hash common.Hash `json:"hash"` // Block hash where the snapshot was created + ValidatorSet *valset.ValidatorSet `json:"validatorSet"` // Validator set at this moment + Recents map[uint64]common.Address `json:"recents"` // Set of recent signers for spam protections } const BorSeparate = "BorSeparate" // signersAscending implements the sort interface to allow sorting a list of addresses -// type signersAscending []libcommon.Address +// type signersAscending []common.Address // func (s signersAscending) Len() int { return len(s) } // func (s signersAscending) Less(i, j int) bool { return bytes.Compare(s[i][:], s[j][:]) < 0 } @@ -38,9 +38,9 @@ const BorSeparate = "BorSeparate" // the genesis block. func newSnapshot( config *chain.BorConfig, - sigcache *lru2.ARCCache[libcommon.Hash, libcommon.Address], + sigcache *lru.ARCCache[common.Hash, common.Address], number uint64, - hash libcommon.Hash, + hash common.Hash, validators []*valset.Validator, ) *Snapshot { snap := &Snapshot{ @@ -49,13 +49,13 @@ func newSnapshot( Number: number, Hash: hash, ValidatorSet: valset.NewValidatorSet(validators), - Recents: make(map[uint64]libcommon.Address), + Recents: make(map[uint64]common.Address), } return snap } // loadSnapshot loads an existing snapshot from the database. -func loadSnapshot(config *chain.BorConfig, sigcache *lru2.ARCCache[libcommon.Hash, libcommon.Address], db kv.RwDB, hash libcommon.Hash) (*Snapshot, error) { +func loadSnapshot(config *chain.BorConfig, sigcache *lru.ARCCache[common.Hash, common.Address], db kv.RwDB, hash common.Hash) (*Snapshot, error) { tx, err := db.BeginRo(context.Background()) if err != nil { return nil, err @@ -107,7 +107,7 @@ func (s *Snapshot) copy() *Snapshot { Number: s.Number, Hash: s.Hash, ValidatorSet: s.ValidatorSet.Copy(), - Recents: make(map[uint64]libcommon.Address), + Recents: make(map[uint64]common.Address), } for block, signer := range s.Recents { cpy.Recents[block] = signer @@ -183,7 +183,7 @@ func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) { } // GetSignerSuccessionNumber returns the relative position of signer in terms of the in-turn proposer -func (s *Snapshot) GetSignerSuccessionNumber(signer libcommon.Address) (int, error) { +func (s *Snapshot) GetSignerSuccessionNumber(signer common.Address) (int, error) { validators := s.ValidatorSet.Validators proposer := s.ValidatorSet.GetProposer().Address proposerIndex, _ := s.ValidatorSet.GetByAddress(proposer) @@ -209,8 +209,8 @@ func (s *Snapshot) GetSignerSuccessionNumber(signer libcommon.Address) (int, err } // signers retrieves the list of authorized signers in ascending order. -func (s *Snapshot) signers() []libcommon.Address { - sigs := make([]libcommon.Address, 0, len(s.ValidatorSet.Validators)) +func (s *Snapshot) signers() []common.Address { + sigs := make([]common.Address, 0, len(s.ValidatorSet.Validators)) for _, sig := range s.ValidatorSet.Validators { sigs = append(sigs, sig.Address) } @@ -219,9 +219,9 @@ func (s *Snapshot) signers() []libcommon.Address { } // Difficulty returns the difficulty for a particular signer at the current snapshot number -func (s *Snapshot) Difficulty(signer libcommon.Address) uint64 { +func (s *Snapshot) Difficulty(signer common.Address) uint64 { // if signer is empty - if bytes.Equal(signer.Bytes(), libcommon.Address{}.Bytes()) { + if bytes.Equal(signer.Bytes(), common.Address{}.Bytes()) { return 1 } diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index dab221f122c..19dd62b6f4c 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -29,7 +29,7 @@ import ( "time" "github.com/goccy/go-json" - lru "github.com/hashicorp/golang-lru" + lru "github.com/hashicorp/golang-lru/v2" "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/kv" @@ -40,6 +40,7 @@ import ( "github.com/ledgerwatch/erigon/common/debug" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/consensus" + "github.com/ledgerwatch/erigon/consensus/misc" "github.com/ledgerwatch/erigon/core/state" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/types/accounts" @@ -144,13 +145,13 @@ var ( type SignerFn func(signer libcommon.Address, mimeType string, message []byte) ([]byte, error) // ecrecover extracts the Ethereum account address from a signed header. -func ecrecover(header *types.Header, sigcache *lru.ARCCache) (libcommon.Address, error) { +func ecrecover(header *types.Header, sigcache *lru.ARCCache[libcommon.Hash, libcommon.Address]) (libcommon.Address, error) { // If the signature's already cached, return that hash := header.Hash() // hitrate while straight-forward sync is from 0.5 to 0.65 if address, known := sigcache.Peek(hash); known { - return address.(libcommon.Address), nil + return address, nil } // Retrieve the signature from the header extra-data @@ -180,8 +181,8 @@ type Clique struct { snapshotConfig *params.ConsensusSnapshotConfig // Consensus engine configuration parameters db kv.RwDB // Database to store and retrieve snapshot checkpoints - signatures *lru.ARCCache // Signatures of recent blocks to speed up mining - recents *lru.ARCCache // Snapshots for recent block to speed up reorgs + signatures *lru.ARCCache[libcommon.Hash, libcommon.Address] // Signatures of recent blocks to speed up mining + recents *lru.ARCCache[libcommon.Hash, *Snapshot] // Snapshots for recent block to speed up reorgs proposals map[libcommon.Address]bool // Current list of proposals we are pushing @@ -206,8 +207,8 @@ func New(cfg *chain.Config, snapshotConfig *params.ConsensusSnapshotConfig, cliq conf.Epoch = epochLength } // Allocate the snapshot caches and create the engine - recents, _ := lru.NewARC(snapshotConfig.InmemorySnapshots) - signatures, _ := lru.NewARC(snapshotConfig.InmemorySignatures) + recents, _ := lru.NewARC[libcommon.Hash, *Snapshot](snapshotConfig.InmemorySnapshots) + signatures, _ := lru.NewARC[libcommon.Hash, libcommon.Address](snapshotConfig.InmemorySignatures) exitCh := make(chan struct{}) @@ -361,7 +362,7 @@ func (c *Clique) Prepare(chain consensus.ChainHeaderReader, header *types.Header return nil } -func (c *Clique) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, e consensus.EpochReader, header *types.Header, +func (c *Clique) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, header *types.Header, state *state.IntraBlockState, txs []types.Transaction, uncles []*types.Header, syscall consensus.SystemCall) { } @@ -369,10 +370,17 @@ func (c *Clique) Initialize(config *chain.Config, chain consensus.ChainHeaderRea // rewards given. func (c *Clique) Finalize(config *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions, uncles []*types.Header, r types.Receipts, withdrawals []*types.Withdrawal, - e consensus.EpochReader, chain consensus.ChainHeaderReader, syscall consensus.SystemCall, + chain consensus.ChainHeaderReader, syscall consensus.SystemCall, ) (types.Transactions, types.Receipts, error) { // No block rewards in PoA, so the state remains as is and uncles are dropped header.UncleHash = types.CalcUncleHash(nil) + if config.IsCancun(header.Time) { + if parent := chain.GetHeaderByHash(header.ParentHash); parent != nil { + header.SetExcessDataGas(misc.CalcExcessDataGas(parent.ExcessDataGas, misc.CountBlobs(txs))) + } else { + header.SetExcessDataGas(new(big.Int)) + } + } return txs, r, nil } @@ -380,7 +388,7 @@ func (c *Clique) Finalize(config *chain.Config, header *types.Header, state *sta // nor block rewards given, and returns the final block. func (c *Clique) FinalizeAndAssemble(chainConfig *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, - e consensus.EpochReader, chain consensus.ChainHeaderReader, syscall consensus.SystemCall, call consensus.Call, + chain consensus.ChainHeaderReader, syscall consensus.SystemCall, call consensus.Call, ) (*types.Block, types.Transactions, types.Receipts, error) { // No block rewards in PoA, so the state remains as is and uncles are dropped header.UncleHash = types.CalcUncleHash(nil) diff --git a/consensus/clique/snapshot.go b/consensus/clique/snapshot.go index 43637c73b80..db588c41f5f 100644 --- a/consensus/clique/snapshot.go +++ b/consensus/clique/snapshot.go @@ -25,7 +25,7 @@ import ( "time" "github.com/goccy/go-json" - lru "github.com/hashicorp/golang-lru" + "github.com/hashicorp/golang-lru/v2" "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/kv" @@ -124,7 +124,7 @@ func lastSnapshot(db kv.RwDB) (uint64, error) { lastEnc, err := tx.GetOne(kv.CliqueLastSnapshot, LastSnapshotKey()) if err != nil { - return 0, fmt.Errorf("failed check last clique snapshot: %d", err) + return 0, fmt.Errorf("failed check last clique snapshot: %w", err) } if len(lastEnc) == 0 { return 0, ErrNotFound @@ -196,7 +196,7 @@ func (s *Snapshot) uncast(address libcommon.Address, authorize bool) bool { // apply creates a new authorization snapshot by applying the given headers to // the original one. -func (s *Snapshot) apply(sigcache *lru.ARCCache, headers ...*types.Header) (*Snapshot, error) { +func (s *Snapshot) apply(sigcache *lru.ARCCache[libcommon.Hash, libcommon.Address], headers ...*types.Header) (*Snapshot, error) { // Allow passing in no headers for cleaner code if len(headers) == 0 { return s, nil diff --git a/consensus/clique/verifier.go b/consensus/clique/verifier.go index 4802d5dfb1e..8955e28fb8f 100644 --- a/consensus/clique/verifier.go +++ b/consensus/clique/verifier.go @@ -135,6 +135,14 @@ func (c *Clique) verifyCascadingFields(chain consensus.ChainHeaderReader, header // Verify the header's EIP-1559 attributes. return err } + if !chain.Config().IsCancun(header.Time) { + if header.ExcessDataGas != nil { + return fmt.Errorf("invalid excessDataGas before fork: have %v, expected 'nil'", header.ExcessDataGas) + } + } else if err := misc.VerifyEip4844Header(chain.Config(), parent, header); err != nil { + // Verify the header's EIP-4844 attributes. + return err + } // Retrieve the snapshot needed to verify this header and cache it snap, err := c.Snapshot(chain, number-1, header.ParentHash, parents) diff --git a/consensus/consensus.go b/consensus/consensus.go index 05500de6fe8..c4cd265496d 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -63,14 +63,6 @@ type ChainReader interface { HasBlock(hash libcommon.Hash, number uint64) bool } -type EpochReader interface { - GetEpoch(blockHash libcommon.Hash, blockN uint64) (transitionProof []byte, err error) - PutEpoch(blockHash libcommon.Hash, blockN uint64, transitionProof []byte) (err error) - GetPendingEpoch(blockHash libcommon.Hash, blockN uint64) (transitionProof []byte, err error) - PutPendingEpoch(blockHash libcommon.Hash, blockN uint64, transitionProof []byte) (err error) - FindBeforeOrEqualNumber(number uint64) (blockNum uint64, blockHash libcommon.Hash, transitionProof []byte, err error) -} - type SystemCall func(contract libcommon.Address, data []byte) ([]byte, error) type Call func(contract libcommon.Address, data []byte) ([]byte, error) @@ -110,7 +102,7 @@ type EngineWriter interface { Prepare(chain ChainHeaderReader, header *types.Header, state *state.IntraBlockState) error // Initialize runs any pre-transaction state modifications (e.g. epoch start) - Initialize(config *chain.Config, chain ChainHeaderReader, e EpochReader, header *types.Header, + Initialize(config *chain.Config, chain ChainHeaderReader, header *types.Header, state *state.IntraBlockState, txs []types.Transaction, uncles []*types.Header, syscall SystemCall) // Finalize runs any post-transaction state modifications (e.g. block rewards) @@ -120,7 +112,7 @@ type EngineWriter interface { // consensus rules that happen at finalization (e.g. block rewards). Finalize(config *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, - e EpochReader, chain ChainHeaderReader, syscall SystemCall, + chain ChainHeaderReader, syscall SystemCall, ) (types.Transactions, types.Receipts, error) // FinalizeAndAssemble runs any post-transaction state modifications (e.g. block @@ -128,10 +120,7 @@ type EngineWriter interface { // // Note: The block header and state database might be updated to reflect any // consensus rules that happen at finalization (e.g. block rewards). - FinalizeAndAssemble(config *chain.Config, header *types.Header, state *state.IntraBlockState, - txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, - e EpochReader, chain ChainHeaderReader, syscall SystemCall, call Call, - ) (*types.Block, types.Transactions, types.Receipts, error) + FinalizeAndAssemble(config *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, chain ChainHeaderReader, syscall SystemCall, call Call) (*types.Block, types.Transactions, types.Receipts, error) // Seal generates a new sealing request for the given input block and pushes // the result into the given channel. @@ -176,6 +165,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, libcommon.Hash, error) + GetFinalizedHeader(chain ChainHeaderReader, header *types.Header) *types.Header } type AsyncEngine interface { diff --git a/consensus/db/db.go b/consensus/db/db.go index c65ecc12c9d..118770100d7 100644 --- a/consensus/db/db.go +++ b/consensus/db/db.go @@ -6,8 +6,8 @@ import ( "github.com/ledgerwatch/log/v3" ) -func OpenDatabase(path string, logger log.Logger, inMem bool, readonly bool) kv.RwDB { - opts := mdbx.NewMDBX(logger).Label(kv.ConsensusDB) +func OpenDatabase(path string, inMem bool, readonly bool) kv.RwDB { + opts := mdbx.NewMDBX(log.Root()).Label(kv.ConsensusDB) if readonly { opts = opts.Readonly() } diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index 955cae04753..5469588deea 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -238,6 +238,14 @@ func VerifyHeaderBasics(chain consensus.ChainHeaderReader, header, parent *types // Verify the header's EIP-1559 attributes. return err } + if !chain.Config().IsCancun(header.Time) { + if header.ExcessDataGas != nil { + return fmt.Errorf("invalid excessDataGas before fork: have %v, expected 'nil'", header.ExcessDataGas) + } + } else if err := misc.VerifyEip4844Header(chain.Config(), parent, header); err != nil { + // Verify the header's EIP-4844 attributes. + return err + } // Verify that the block number is parent's +1 if diff := new(big.Int).Sub(header.Number, parent.Number); diff.Cmp(big.NewInt(1)) != 0 { @@ -551,7 +559,7 @@ func (ethash *Ethash) Prepare(chain consensus.ChainHeaderReader, header *types.H return nil } -func (ethash *Ethash) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, e consensus.EpochReader, header *types.Header, +func (ethash *Ethash) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, header *types.Header, state *state.IntraBlockState, txs []types.Transaction, uncles []*types.Header, syscall consensus.SystemCall) { } @@ -559,10 +567,17 @@ func (ethash *Ethash) Initialize(config *chain.Config, chain consensus.ChainHead // setting the final state on the header func (ethash *Ethash) Finalize(config *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions, uncles []*types.Header, r types.Receipts, withdrawals []*types.Withdrawal, - e consensus.EpochReader, chain consensus.ChainHeaderReader, syscall consensus.SystemCall, + chain consensus.ChainHeaderReader, syscall consensus.SystemCall, ) (types.Transactions, types.Receipts, error) { // Accumulate any block and uncle rewards and commit the final state root accumulateRewards(config, state, header, uncles) + if config.IsCancun(header.Time) { + if parent := chain.GetHeaderByHash(header.ParentHash); parent != nil { + header.SetExcessDataGas(misc.CalcExcessDataGas(parent.ExcessDataGas, misc.CountBlobs(txs))) + } else { + header.SetExcessDataGas(new(big.Int)) + } + } return txs, r, nil } @@ -570,11 +585,11 @@ func (ethash *Ethash) Finalize(config *chain.Config, header *types.Header, state // uncle rewards, setting the final state and assembling the block. func (ethash *Ethash) FinalizeAndAssemble(chainConfig *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions, uncles []*types.Header, r types.Receipts, withdrawals []*types.Withdrawal, - e consensus.EpochReader, chain consensus.ChainHeaderReader, syscall consensus.SystemCall, call consensus.Call, + chain consensus.ChainHeaderReader, syscall consensus.SystemCall, call consensus.Call, ) (*types.Block, types.Transactions, types.Receipts, error) { // Finalize block - outTxs, outR, err := ethash.Finalize(chainConfig, header, state, txs, uncles, r, withdrawals, e, chain, syscall) + outTxs, outR, err := ethash.Finalize(chainConfig, header, state, txs, uncles, r, withdrawals, chain, syscall) if err != nil { return nil, nil, nil, err } @@ -604,6 +619,9 @@ func (ethash *Ethash) SealHash(header *types.Header) (hash libcommon.Hash) { if header.BaseFee != nil { enc = append(enc, header.BaseFee) } + if header.ExcessDataGas != nil { + enc = append(enc, header.ExcessDataGas) + } rlp.Encode(hasher, enc) hasher.Sum(hash[:0]) return hash diff --git a/consensus/misc/eip4844.go b/consensus/misc/eip4844.go new file mode 100644 index 00000000000..84a649ff88d --- /dev/null +++ b/consensus/misc/eip4844.go @@ -0,0 +1,84 @@ +// Copyright 2021 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package misc + +import ( + "fmt" + "math/big" + + "github.com/ledgerwatch/erigon-lib/chain" + + "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/params" +) + +// CalcExcessDataGas implements calc_excess_data_gas from EIP-4844 +func CalcExcessDataGas(parentExcessDataGas *big.Int, newBlobs int) *big.Int { + excessDataGas := new(big.Int) + if parentExcessDataGas != nil { + excessDataGas.Set(parentExcessDataGas) + } + consumedGas := big.NewInt(params.DataGasPerBlob) + consumedGas.Mul(consumedGas, big.NewInt(int64(newBlobs))) + + excessDataGas.Add(excessDataGas, consumedGas) + targetGas := big.NewInt(params.TargetDataGasPerBlock) + if excessDataGas.Cmp(targetGas) < 0 { + return new(big.Int) + } + return new(big.Int).Set(excessDataGas.Sub(excessDataGas, targetGas)) +} + +// FakeExponential approximates factor * e ** (num / denom) using a taylor expansion +// as described in the EIP-4844 spec. +func FakeExponential(factor, num, denom *big.Int) *big.Int { + output := new(big.Int) + numAccum := new(big.Int).Mul(factor, denom) + for i := 1; numAccum.Sign() > 0; i++ { + output.Add(output, numAccum) + numAccum.Mul(numAccum, num) + iBig := big.NewInt(int64(i)) + numAccum.Div(numAccum, iBig.Mul(iBig, denom)) + } + return output.Div(output, denom) +} + +// CountBlobs returns the number of blob transactions in txs +func CountBlobs(txs []types.Transaction) int { + var count int + for _, tx := range txs { + count += len(tx.GetDataHashes()) + } + return count +} + +// VerifyEip4844Header verifies that the header is not malformed +func VerifyEip4844Header(config *chain.Config, parent, header *types.Header) error { + if header.ExcessDataGas == nil { + return fmt.Errorf("header is missing excessDataGas") + } + return nil +} + +// GetDataGasPrice implements get_data_gas_price from EIP-4844 +func GetDataGasPrice(excessDataGas *big.Int) *big.Int { + return FakeExponential(big.NewInt(params.MinDataGasPrice), excessDataGas, big.NewInt(params.DataGasPriceUpdateFraction)) +} + +func GetDataGasUsed(numBlobs int) uint64 { + return uint64(numBlobs) * params.DataGasPerBlob +} diff --git a/consensus/parlia/abi.go b/consensus/parlia/abi.go index e841eb5cd5c..ffe97a45ce4 100644 --- a/consensus/parlia/abi.go +++ b/consensus/parlia/abi.go @@ -1,6 +1,6 @@ package parlia -const validatorSetABI = ` +const validatorSetABIBeforeLuban = ` [ { "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/lubanFork.go b/consensus/parlia/lubanFork.go new file mode 100644 index 00000000000..b27ce7817ee --- /dev/null +++ b/consensus/parlia/lubanFork.go @@ -0,0 +1,37 @@ +package parlia + +import ( + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon/common/u256" + "github.com/ledgerwatch/erigon/core/state" + "github.com/ledgerwatch/erigon/core/systemcontracts" + "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/log/v3" +) + +type Bytes []byte + +func (p *Parlia) getCurrentValidatorsBeforeLuban(header *types.Header, ibs *state.IntraBlockState) ([]libcommon.Address, error) { + + // prepare different method + method := "getValidators" + if p.chainConfig.IsEuler(header.Number) { + method = "getMiningValidators" + } + + data, err := p.validatorSetABIBeforeLuban.Pack(method) + if err != nil { + log.Error("Unable to pack tx for getValidators", "error", err) + return nil, err + } + // do smart contract call + msgData := Bytes(data) + _, returnData, err := p.systemCall(header.Coinbase, systemcontracts.ValidatorContract, msgData[:], ibs, header, u256.Num0) + if err != nil { + return nil, err + } + + var valSet []libcommon.Address + err = p.validatorSetABIBeforeLuban.UnpackIntoInterface(&valSet, method, returnData) + return valSet, err +} diff --git a/consensus/parlia/parlia.go b/consensus/parlia/parlia.go index 370b7e780a6..d936830bf11 100644 --- a/consensus/parlia/parlia.go +++ b/consensus/parlia/parlia.go @@ -13,22 +13,26 @@ import ( "sync" "time" + lru "github.com/hashicorp/golang-lru/v2" "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/length" + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/common/math" + "github.com/prysmaticlabs/prysm/v4/crypto/bls" + "github.com/willf/bitset" "github.com/ledgerwatch/erigon/core/rawdb" + "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/crypto/cryptopool" - lru "github.com/hashicorp/golang-lru" "github.com/holiman/uint256" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/log/v3" "golang.org/x/exp/slices" "github.com/ledgerwatch/erigon/accounts/abi" - "github.com/ledgerwatch/erigon/common/hexutil" - "github.com/ledgerwatch/erigon/common/math" "github.com/ledgerwatch/erigon/common/u256" "github.com/ledgerwatch/erigon/consensus" "github.com/ledgerwatch/erigon/consensus/misc" @@ -36,7 +40,6 @@ import ( "github.com/ledgerwatch/erigon/core/forkid" "github.com/ledgerwatch/erigon/core/state" "github.com/ledgerwatch/erigon/core/systemcontracts" - "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/vm" "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/params" @@ -56,12 +59,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 = length.Addr - wiggleTime = uint64(1) // second, Random delay (per signer) to allow concurrent signers - initialBackOffTime = uint64(1) // second - processBackOffTime = uint64(1) // second + validatorBytesLengthBeforeLuban = length.Addr + validatorBytesLength = length.Addr + types.BLSPublicKeyLength + validatorNumberSize = 1 // Fixed number of extra prefix bytes reserved for validator number after Luban + + 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 ( @@ -150,11 +158,11 @@ var ( type SignFn func(validator libcommon.Address, payload []byte, chainId *big.Int) ([]byte, error) // ecrecover extracts the Ethereum account address from a signed header. -func ecrecover(header *types.Header, sigCache *lru.ARCCache, chainId *big.Int) (libcommon.Address, error) { +func ecrecover(header *types.Header, sigCache *lru.ARCCache[libcommon.Hash, libcommon.Address], chainId *big.Int) (libcommon.Address, error) { // If the signature's already cached, return that hash := header.Hash() if address, known := sigCache.Get(hash); known { - return address.(libcommon.Address), nil + return address, nil } // Retrieve the signature from the header extra-data if len(header.Extra) < extraSeal { @@ -228,8 +236,8 @@ type Parlia struct { db kv.RwDB // Database to store and retrieve snapshot checkpoints chainDb kv.RwDB - recentSnaps *lru.ARCCache // Snapshots for recent block to speed up - signatures *lru.ARCCache // Signatures of recent blocks to speed up mining + recentSnaps *lru.ARCCache[libcommon.Hash, *Snapshot] // Snapshots for recent block to speed up + signatures *lru.ARCCache[libcommon.Hash, libcommon.Address] // Signatures of recent blocks to speed up mining signer *types.Signer @@ -240,8 +248,9 @@ type Parlia struct { snapLock sync.RWMutex // Protects snapshots creation - validatorSetABI abi.ABI - slashABI abi.ABI + validatorSetABIBeforeLuban abi.ABI + validatorSetABI abi.ABI + slashABI abi.ABI // The fields below are for testing only fakeDiff bool // Skip difficulty verifications @@ -265,11 +274,15 @@ func New( } // Allocate the snapshot caches and create the engine - recentSnaps, err := lru.NewARC(inMemorySnapshots) + recentSnaps, err := lru.NewARC[libcommon.Hash, *Snapshot](inMemorySnapshots) if err != nil { panic(err) } - signatures, err := lru.NewARC(inMemorySignatures) + signatures, err := lru.NewARC[libcommon.Hash, libcommon.Address](inMemorySignatures) + if err != nil { + panic(err) + } + vABIBeforeLuban, err := abi.JSON(strings.NewReader(validatorSetABIBeforeLuban)) if err != nil { panic(err) } @@ -282,16 +295,17 @@ func New( panic(err) } c := &Parlia{ - chainConfig: chainConfig, - config: parliaConfig, - db: db, - chainDb: chainDb, - recentSnaps: recentSnaps, - signatures: signatures, - validatorSetABI: vABI, - slashABI: sABI, - signer: types.LatestSigner(chainConfig), - snapshots: snapshots, + chainConfig: chainConfig, + config: parliaConfig, + db: db, + chainDb: chainDb, + recentSnaps: recentSnaps, + signatures: signatures, + validatorSetABIBeforeLuban: vABIBeforeLuban, + validatorSetABI: vABI, + slashABI: sABI, + signer: types.LatestSigner(chainConfig), + snapshots: snapshots, } c.heightForks, c.timeForks = forkid.GatherForks(chainConfig) @@ -332,6 +346,160 @@ func (p *Parlia) VerifyHeaders(chain consensus.ChainHeaderReader, headers []*typ return nil } +// 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 Luban fork, we introduce vote attestation into the header's extra field, so extra format is different from before. +// Before Luban fork: |---Extra Vanity---|---Validators Bytes (or Empty)---|---Extra Seal---| +// After Luban fork: |---Extra Vanity---|---Validators Number and Validators Bytes (or Empty)---|---Vote Attestation (or Empty)---|---Extra Seal---| +func getValidatorBytesFromHeader(header *types.Header, chainConfig *chain.Config, parliaConfig *chain.ParliaConfig) []byte { + if len(header.Extra) <= extraVanity+extraSeal { + return nil + } + + if !chainConfig.IsLuban(header.Number.Uint64()) { + if header.Number.Uint64()%parliaConfig.Epoch == 0 && (len(header.Extra)-extraSeal-extraVanity)%validatorBytesLengthBeforeLuban != 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 *chain.Config, parliaConfig *chain.ParliaConfig) (*types.VoteAttestation, error) { + if len(header.Extra) <= extraVanity+extraSeal { + return nil, nil + } + + if !chainConfig.IsLuban(header.Number.Uint64()) { + 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, true) + 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) < math.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 @@ -340,7 +508,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()) { @@ -353,16 +520,18 @@ 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 } @@ -446,6 +615,15 @@ 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().IsPlato(header.Number.Uint64()) { + 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) } @@ -503,7 +681,36 @@ func (p *Parlia) verifySeal(chain consensus.ChainHeaderReader, header *types.Hea return nil } +func (p *Parlia) prepareValidators(header *types.Header, chain consensus.ChainHeaderReader, ibs *state.IntraBlockState) error { + if header.Number.Uint64()%p.config.Epoch != 0 { + return nil + } + parentHeader := chain.GetHeader(header.ParentHash, header.Number.Uint64()) + + newValidators, voteAddressMap, err := p.getCurrentValidators(parentHeader, ibs) + if err != nil { + return err + } + // sort validator by address + sort.Sort(validatorsAscending(newValidators)) + if !p.chainConfig.IsLuban(header.Number.Uint64()) { + 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 +} + // 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 libcommon.Hash, parents []*types.Header, verify bool) (*Snapshot, error) { // Search for a snapshot in memory or on disk for checkpoints var ( @@ -513,7 +720,7 @@ func (p *Parlia) snapshot(chain consensus.ChainHeaderReader, number uint64, hash ) if s, ok := p.recentSnaps.Get(hash); ok { - snap = s.(*Snapshot) + snap = s } else { p.snapLock.Lock() defer p.snapLock.Unlock() @@ -523,7 +730,7 @@ func (p *Parlia) snapshot(chain consensus.ChainHeaderReader, number uint64, hash for snap == nil { // If an in-memory snapshot was found, use that if s, ok := p.recentSnaps.Get(hash); ok { - snap = s.(*Snapshot) + snap = s break } @@ -537,18 +744,17 @@ func (p *Parlia) snapshot(chain consensus.ChainHeaderReader, number uint64, hash } } } - if number == 0 { + if number == 0 || (number%p.config.Epoch == 0 && (len(headers) > params.FullImmutabilityThreshold)) { // Headers included into the snapshots have to be trusted as checkpoints checkpoint := chain.GetHeader(hash, number) if checkpoint != nil { - 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 snapshot - snap = newSnapshot(p.config, p.signatures, number, hash, validators) + snap = newSnapshot(p.config, p.signatures, number, hash, validators, voteAddrs) if err := snap.store(p.db); err != nil { return nil, err } @@ -588,7 +794,16 @@ func (p *Parlia) snapshot(chain consensus.ChainHeaderReader, number uint64, hash for i := 0; i < len(headers)/2; i++ { headers[i], headers[len(headers)-1-i] = headers[len(headers)-1-i], headers[i] } - snap, err := snap.apply(headers, chain, parents, p.chainConfig.ChainID, doLog) + + verifiedAttestations := make(map[libcommon.Hash]struct{}, len(headers)) + for index, header := range headers { + // vote attestation should be checked here to decide whether to update attestation of snapshot between [Luban,Plato) + // because err of verifyVoteAttestation is ignored when importing blocks and headers before Plato. + if p.chainConfig.IsLuban(header.Number.Uint64()) && !p.chainConfig.IsPlato(header.Number.Uint64()) && p.verifyVoteAttestation(chain, header, headers[:index]) == nil { + verifiedAttestations[header.Hash()] = struct{}{} + } + } + snap, err := snap.apply(headers, chain, parents, p.chainConfig, verifiedAttestations, doLog) if err != nil { return nil, err } @@ -647,16 +862,8 @@ func (p *Parlia) Prepare(chain consensus.ChainHeaderReader, header *types.Header nextForkHash := forkid.NextForkHashFromForks(p.heightForks, p.timeForks, p.genesisHash, number, header.Time) header.Extra = append(header.Extra, nextForkHash[:]...) - if number%p.config.Epoch == 0 { - newValidators, err := p.getCurrentValidators(parent, ibs) - 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, chain, ibs); err != nil { + return err } // add extra seal space @@ -668,8 +875,42 @@ func (p *Parlia) Prepare(chain consensus.ChainHeaderReader, header *types.Header return nil } +func (p *Parlia) verifyValidators(header, parentHeader *types.Header, state *state.IntraBlockState) error { + if header.Number.Uint64()%p.config.Epoch != 0 { + return nil + } + + newValidators, voteAddressMap, err := p.getCurrentValidators(parentHeader, state) + if err != nil { + return err + } + // sort validator by address + sort.Sort(validatorsAscending(newValidators)) + var validatorsBytes []byte + validatorsNumber := len(newValidators) + if !p.chainConfig.IsLuban(header.Number.Uint64()) { + validatorsBytes = make([]byte, validatorsNumber*validatorBytesLengthBeforeLuban) + for i, validator := range newValidators { + copy(validatorsBytes[i*validatorBytesLengthBeforeLuban:], 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+length.Addr:], voteAddressMap[validator].Bytes()) + } + } + if !bytes.Equal(getValidatorBytesFromHeader(header, p.chainConfig, p.config), validatorsBytes) { + return errMismatchingEpochValidators + } + return nil +} + // Initialize runs any pre-transaction state modifications (e.g. epoch start) -func (p *Parlia) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, e consensus.EpochReader, header *types.Header, +func (p *Parlia) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, header *types.Header, state *state.IntraBlockState, txs []types.Transaction, uncles []*types.Header, syscall consensus.SystemCall) { } @@ -698,7 +939,7 @@ func (p *Parlia) splitTxs(txs types.Transactions, header *types.Header) (userTxs // consensus rules that happen at finalization (e.g. block rewards). func (p *Parlia) Finalize(_ *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions, _ []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, - e consensus.EpochReader, chain consensus.ChainHeaderReader, syscall consensus.SystemCall, + chain consensus.ChainHeaderReader, syscall consensus.SystemCall, ) (types.Transactions, types.Receipts, error) { return p.finalize(header, state, txs, receipts, chain, false) } @@ -726,23 +967,9 @@ func (p *Parlia) finalize(header *types.Header, state *state.IntraBlockState, tx */ // 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 number%p.config.Epoch == 0 { - parentHeader := chain.GetHeader(header.ParentHash, number-1) - newValidators, err := p.getCurrentValidators(parentHeader, state) - if err != nil { - return nil, nil, 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 nil, nil, errMismatchingEpochValidators - } + parentHeader := chain.GetHeader(header.ParentHash, number-1) + if err := p.verifyValidators(header, parentHeader, state); err != nil { + return nil, nil, err } // No block rewards in PoA, so the state remains as is and uncles are dropped if number == 1 { @@ -779,6 +1006,12 @@ func (p *Parlia) finalize(header *types.Header, state *state.IntraBlockState, tx //log.Error("distributeIncoming", "block hash", header.Hash(), "error", err, "systemTxs", len(systemTxs)) return nil, nil, err } + + if p.chainConfig.IsPlato(header.Number.Uint64()) { + if _, _, _, err := p.distributeFinalityReward(chain, state, header, txs, systemTxs, &header.GasUsed, false); err != nil { + return nil, nil, err + } + } //log.Debug("distribute successful", "txns", txs.Len(), "receipts", len(receipts), "gasUsed", header.GasUsed) if len(systemTxs) > 0 { return nil, nil, fmt.Errorf("the length of systemTxs is still %d", len(systemTxs)) @@ -788,6 +1021,79 @@ func (p *Parlia) finalize(header *types.Header, state *state.IntraBlockState, tx return txs, receipts, nil } +func (p *Parlia) distributeFinalityReward(chain consensus.ChainHeaderReader, state *state.IntraBlockState, header *types.Header, txs types.Transactions, systemTxs types.Transactions, + usedGas *uint64, mining bool) (types.Transactions, types.Transaction, *types.Receipt, error) { + currentHeight := header.Number.Uint64() + epoch := p.config.Epoch + chainConfig := chain.Config() + if currentHeight%epoch != 0 { + return nil, nil, nil, nil + } + + head := header + accumulatedWeights := make(map[libcommon.Address]uint64) + for height := currentHeight - 1; height+epoch >= currentHeight && height >= 1; height-- { + head = chain.GetHeaderByHash(head.ParentHash) + if head == nil { + return nil, nil, nil, fmt.Errorf("header is nil at height %d", height) + } + voteAttestation, err := getVoteAttestationFromHeader(head, chainConfig, p.config) + if err != nil { + return nil, nil, nil, 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, true) + if err != nil { + return nil, nil, nil, 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 := math.CeilDiv(len(snap.Validators)*2, 3) + if validVoteCount > quorum { + accumulatedWeights[head.Coinbase] += uint64(float64(validVoteCount-quorum) * collectAdditionalVotesRewardRatio) + } + } + + validators := make([]libcommon.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 nil, nil, nil, err + } + return p.applyTransaction(header.Coinbase, systemcontracts.ValidatorContract, u256.Num0, data, state, header, + len(txs), systemTxs, usedGas, mining) +} + // FinalizeAndAssemble runs any post-transaction state modifications (e.g. block // rewards) and assembles the final block. // @@ -795,7 +1101,7 @@ func (p *Parlia) finalize(header *types.Header, state *state.IntraBlockState, tx // consensus rules that happen at finalization (e.g. block rewards). func (p *Parlia) FinalizeAndAssemble(_ *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions, _ []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, - e consensus.EpochReader, chain consensus.ChainHeaderReader, syscall consensus.SystemCall, call consensus.Call, + chain consensus.ChainHeaderReader, syscall consensus.SystemCall, call consensus.Call, ) (*types.Block, types.Transactions, types.Receipts, error) { outTxs, outReceipts, err := p.finalize(header, state, txs, receipts, chain, true) if err != nil { @@ -1024,36 +1330,42 @@ func (p *Parlia) Close() error { // ========================== interaction with contract/account ========= // getCurrentValidators get current validators -func (p *Parlia) getCurrentValidators(header *types.Header, ibs *state.IntraBlockState) ([]libcommon.Address, error) { - // method - var method string - if p.chainConfig.IsEuler(header.Number) { - method = "getMiningValidators" - } else { - method = "getValidators" +func (p *Parlia) getCurrentValidators(header *types.Header, ibs *state.IntraBlockState) ([]libcommon.Address, map[libcommon.Address]*types.BLSPublicKey, error) { + // This is actually the parentNumber + if !p.chainConfig.IsLuban(header.Number.Uint64()) { + validators, err := p.getCurrentValidatorsBeforeLuban(header, ibs) + return validators, nil, err } + + // method + method := "getMiningValidators" + data, err := p.validatorSetABI.Pack(method) if err != nil { - log.Error("Unable to pack tx for getValidators", "err", err) - return nil, err + log.Error("Unable to pack tx for getMiningValidators", "err", err) + return nil, nil, err } // call - msgData := hexutil.Bytes(data) + msgData := hexutility.Bytes(data) _, returnData, err := p.systemCall(header.Coinbase, systemcontracts.ValidatorContract, msgData[:], ibs, header, u256.Num0) if err != nil { - return nil, err + return nil, nil, err } - var ret0 = new([]libcommon.Address) - out := ret0 - if err := p.validatorSetABI.UnpackIntoInterface(out, method, returnData); err != nil { - return nil, err + var valSet []libcommon.Address + var voteAddrSet []types.BLSPublicKey + + if err := p.validatorSetABI.UnpackIntoInterface(&[]interface{}{&valSet, &voteAddrSet}, method, returnData); err != nil { + return nil, nil, err + } + + voteAddrmap := make(map[libcommon.Address]*types.BLSPublicKey, len(valSet)) + for i := 0; i < len(valSet); i++ { + voteAddrmap[valSet[i]] = &(voteAddrSet)[i] } - valz := make([]libcommon.Address, len(*ret0)) - copy(valz, *ret0) //for i, a := range *ret0 { // valz[i] = a //} - return valz, nil + return valSet, voteAddrmap, nil } // slash spoiled validators @@ -1263,6 +1575,7 @@ func (p *Parlia) systemCall(from, contract libcommon.Address, data []byte, ibs * nil, nil, data, nil, false, true, // isFree + nil, ) vmConfig := vm.Config{NoReceipts: true} // Create a new context to be used in the EVM environment @@ -1281,3 +1594,62 @@ func (p *Parlia) systemCall(from, contract libcommon.Address, data []byte, ibs * } return msg.Gas() - leftOverGas, ret, 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, libcommon.Hash, error) { + if chain == nil || header == nil { + return 0, libcommon.Hash{}, fmt.Errorf("illegal chain or header") + } + snap, err := p.snapshot(chain, header.Number.Uint64(), header.Hash(), nil, true) + if err != nil { + log.Error("Unexpected error when getting snapshot", + "error", err, "blockNumber", header.Number.Uint64(), "blockHash", header.Hash()) + return 0, libcommon.Hash{}, err + } + + if snap.Attestation == nil { + if p.chainConfig.IsLuban(header.Number.Uint64()) { + 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().IsPlato(header.Number.Uint64()) { + return chain.GetHeaderByNumber(0) + } + if header.Number.Uint64() < backward { + backward = header.Number.Uint64() + } + + snap, err := p.snapshot(chain, header.Number.Uint64(), header.Hash(), nil, true) + 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, true) + 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) +} diff --git a/consensus/parlia/ramanujanfork.go b/consensus/parlia/ramanujanfork.go index fbc77b9e468..305358e8fa2 100644 --- a/consensus/parlia/ramanujanfork.go +++ b/consensus/parlia/ramanujanfork.go @@ -30,15 +30,15 @@ func (p *Parlia) delayForRamanujanFork(snap *Snapshot, header *types.Header) tim func (p *Parlia) blockTimeForRamanujanFork(snap *Snapshot, header, parent *types.Header) uint64 { blockTime := parent.Time + p.config.Period if p.chainConfig.IsRamanujan(header.Number.Uint64()) { - blockTime = blockTime + backOffTime(snap, p.val) + blockTime = blockTime + backOffTime(snap, header, p.val, p.chainConfig) } return blockTime } func (p *Parlia) blockTimeVerifyForRamanujanFork(snap *Snapshot, header, parent *types.Header) error { if p.chainConfig.IsRamanujan(header.Number.Uint64()) { - if header.Time < parent.Time+p.config.Period+backOffTime(snap, header.Coinbase) { - return fmt.Errorf("header %d, time %d, now %d, period: %d, backof: %d, %w", header.Number.Uint64(), header.Time, time.Now().Unix(), p.config.Period, backOffTime(snap, header.Coinbase), consensus.ErrFutureBlock) + if header.Time < parent.Time+p.config.Period+backOffTime(snap, header, header.Coinbase, p.chainConfig) { + return fmt.Errorf("header %d, time %d, now %d, period: %d, backof: %d, %w", header.Number.Uint64(), header.Time, time.Now().Unix(), p.config.Period, backOffTime(snap, header, header.Coinbase, p.chainConfig), consensus.ErrFutureBlock) } } return nil diff --git a/consensus/parlia/snapshot_test.go b/consensus/parlia/snaoshot_test.go similarity index 100% rename from consensus/parlia/snapshot_test.go rename to consensus/parlia/snaoshot_test.go diff --git a/consensus/parlia/snapshot.go b/consensus/parlia/snapshot.go index a73d8db5c31..f1ce5bc4764 100644 --- a/consensus/parlia/snapshot.go +++ b/consensus/parlia/snapshot.go @@ -23,13 +23,14 @@ import ( "encoding/json" "errors" "fmt" - "math/big" "sort" - lru "github.com/hashicorp/golang-lru" + lru "github.com/hashicorp/golang-lru/v2" "github.com/ledgerwatch/erigon-lib/chain" + "github.com/ledgerwatch/erigon-lib/common" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/hexutility" + "github.com/ledgerwatch/erigon-lib/common/length" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/log/v3" @@ -39,14 +40,20 @@ import ( // Snapshot is the state of the validatorSet at a given point. type Snapshot struct { - config *chain.ParliaConfig // Consensus engine parameters to fine tune behavior - sigCache *lru.ARCCache // Cache of recent block signatures to speed up ecrecover - - Number uint64 `json:"number"` // Block number where the snapshot was created - Hash libcommon.Hash `json:"hash"` // Block hash where the snapshot was created - Validators map[libcommon.Address]struct{} `json:"validators"` // Set of authorized validators at this moment - Recents map[uint64]libcommon.Address `json:"recents"` // Set of recent validators for spam protections - RecentForkHashes map[uint64]string `json:"recent_fork_hashes"` // Set of recent forkHash + config *chain.ParliaConfig // Consensus engine parameters to fine tune behavior + sigCache *lru.ARCCache[common.Hash, common.Address] // Cache of recent block signatures to speed up ecrecover + + Number uint64 `json:"number"` // Block number where the snapshot was created + Hash libcommon.Hash `json:"hash"` // Block hash where the snapshot was created + Validators map[libcommon.Address]*ValidatorInfo `json:"validators"` // Set of authorized validators at this moment + Recents map[uint64]libcommon.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 @@ -54,42 +61,59 @@ type Snapshot struct { // the genesis block. func newSnapshot( config *chain.ParliaConfig, - sigCache *lru.ARCCache, + sigCache *lru.ARCCache[common.Hash, common.Address], number uint64, hash libcommon.Hash, validators []libcommon.Address, + voteAddrs []types.BLSPublicKey, ) *Snapshot { snap := &Snapshot{ config: config, sigCache: sigCache, Number: number, Hash: hash, - Recents: make(map[uint64]libcommon.Address), + Recents: make(map[uint64]common.Address), RecentForkHashes: make(map[uint64]string), - Validators: make(map[libcommon.Address]struct{}), + Validators: make(map[libcommon.Address]*ValidatorInfo), + } + + for idx, v := range validators { + // The luban fork from the genesis block + if len(voteAddrs) == len(validators) { + snap.Validators[v] = &ValidatorInfo{ + VoteAddress: voteAddrs[idx], + } + } else { + snap.Validators[v] = &ValidatorInfo{} + } } - for _, v := range validators { - snap.Validators[v] = struct{}{} + + // The luban 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 } // validatorsAscending implements the sort interface to allow sorting a list of addresses -type validatorsAscending []libcommon.Address +type validatorsAscending []common.Address func (s validatorsAscending) Len() int { return len(s) } func (s validatorsAscending) Less(i, j int) bool { return bytes.Compare(s[i][:], s[j][:]) < 0 } func (s validatorsAscending) Swap(i, j int) { s[i], s[j] = s[j], s[i] } // SnapshotFullKey = SnapshotBucket + num (uint64 big endian) + hash -func SnapshotFullKey(number uint64, hash libcommon.Hash) []byte { +func SnapshotFullKey(number uint64, hash common.Hash) []byte { return append(hexutility.EncodeTs(number), hash.Bytes()...) } var ErrNoSnapsnot = fmt.Errorf("no parlia snapshot") // loadSnapshot loads an existing snapshot from the database. -func loadSnapshot(config *chain.ParliaConfig, sigCache *lru.ARCCache, db kv.RwDB, num uint64, hash libcommon.Hash) (*Snapshot, error) { +func loadSnapshot(config *chain.ParliaConfig, sigCache *lru.ARCCache[common.Hash, common.Address], db kv.RwDB, num uint64, hash common.Hash) (*Snapshot, error) { tx, err := db.BeginRo(context.Background()) if err != nil { return nil, err @@ -130,13 +154,16 @@ func (s *Snapshot) copy() *Snapshot { sigCache: s.sigCache, Number: s.Number, Hash: s.Hash, - Validators: make(map[libcommon.Address]struct{}), + Validators: make(map[libcommon.Address]*ValidatorInfo), Recents: make(map[uint64]libcommon.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 @@ -144,6 +171,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 } @@ -158,7 +193,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, doLog bool) (*Snapshot, error) { +func (s *Snapshot) updateAttestation(header *types.Header, chainConfig *chain.Config, parliaConfig *chain.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 *chain.Config, verifiedAttestations map[libcommon.Hash]struct{}, doLog bool) (*Snapshot, error) { // Allow passing in no headers for cleaner code if len(headers) == 0 { return s, nil @@ -194,7 +245,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 } @@ -218,15 +269,21 @@ 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[libcommon.Address]struct{}, len(newValArr)) - for _, val := range newValArr { - newVals[val] = struct{}{} + + newVals := make(map[libcommon.Address]*ValidatorInfo, len(newValArr)) + for idx, val := range newValArr { + if !chainConfig.IsLuban(header.Number.Uint64()) { + newVals[val] = &ValidatorInfo{} + } else { + newVals[val] = &ValidatorInfo{ + VoteAddress: voteAddrs[idx], + } + } } oldLimit := len(snap.Validators)/2 + 1 newLimit := len(newVals)/2 + 1 @@ -243,7 +300,19 @@ func (s *Snapshot) apply(headers []*types.Header, chain consensus.ChainHeaderRea } } snap.Validators = newVals + if chainConfig.IsLuban(header.Number.Uint64()) { + validators := snap.validators() + for idx, val := range validators { + snap.Validators[val].Index = idx + 1 // offset by 1 + } + } + } + + _, voteAssestationNoErr := verifiedAttestations[header.Hash()] + if chainConfig.IsPlato(header.Number.Uint64()) || (chainConfig.IsLuban(header.Number.Uint64()) && voteAssestationNoErr) { + snap.updateAttestation(header, chainConfig, s.config) } + snap.RecentForkHashes[number] = hex.EncodeToString(header.Extra[extraVanity-nextForkHashSize : extraVanity]) } snap.Number += uint64(len(headers)) @@ -252,8 +321,8 @@ func (s *Snapshot) apply(headers []*types.Header, chain consensus.ChainHeaderRea } // validators retrieves the list of validators in ascending order. -func (s *Snapshot) validators() []libcommon.Address { - validators := make([]libcommon.Address, 0, len(s.Validators)) +func (s *Snapshot) validators() []common.Address { + validators := make([]common.Address, 0, len(s.Validators)) for v := range s.Validators { validators = append(validators, v) } @@ -262,13 +331,13 @@ func (s *Snapshot) validators() []libcommon.Address { } // inturn returns if a validator at a given block height is in-turn or not. -func (s *Snapshot) inturn(validator libcommon.Address) bool { +func (s *Snapshot) inturn(validator common.Address) bool { validators := s.validators() offset := (s.Number + 1) % uint64(len(validators)) return validators[offset] == validator } -func (s *Snapshot) enoughDistance(validator libcommon.Address, header *types.Header) bool { +func (s *Snapshot) enoughDistance(validator common.Address, header *types.Header) bool { idx := s.indexOfVal(validator) if idx < 0 { return true @@ -289,6 +358,10 @@ func (s *Snapshot) enoughDistance(validator libcommon.Address, header *types.Hea } func (s *Snapshot) indexOfVal(validator libcommon.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 { @@ -298,24 +371,35 @@ func (s *Snapshot) indexOfVal(validator libcommon.Address) int { return -1 } -func (s *Snapshot) supposeValidator() libcommon.Address { +func (s *Snapshot) supposeValidator() common.Address { validators := s.validators() index := (s.Number + 1) % uint64(len(validators)) return validators[index] } -func ParseValidators(validatorsBytes []byte) ([]libcommon.Address, error) { - if len(validatorsBytes)%validatorBytesLength != 0 { - return nil, errors.New("invalid validators bytes") +func parseValidators(header *types.Header, chainConfig *chain.Config, parliaConfig *chain.ParliaConfig) ([]libcommon.Address, []types.BLSPublicKey, error) { + validatorsBytes := getValidatorBytesFromHeader(header, chainConfig, parliaConfig) + if len(validatorsBytes) == 0 { + return nil, nil, errors.New("invalid validators bytes") } + + if !chainConfig.IsLuban(header.Number.Uint64()) { + n := len(validatorsBytes) / validatorBytesLengthBeforeLuban + result := make([]libcommon.Address, n) + for i := 0; i < n; i++ { + result[i] = libcommon.BytesToAddress(validatorsBytes[i*validatorBytesLengthBeforeLuban : (i+1)*validatorBytesLengthBeforeLuban]) + } + return result, nil, nil + } + n := len(validatorsBytes) / validatorBytesLength - result := make([]libcommon.Address, n) + cnsAddrs := make([]libcommon.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] = libcommon.BytesToAddress(address) + cnsAddrs[i] = libcommon.BytesToAddress(validatorsBytes[i*validatorBytesLength : i*validatorBytesLength+length.Addr]) + copy(voteAddrs[i][:], validatorsBytes[i*validatorBytesLength+length.Addr:(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/consensus/parlia/util.go b/consensus/parlia/util.go new file mode 100644 index 00000000000..650106cd926 --- /dev/null +++ b/consensus/parlia/util.go @@ -0,0 +1,83 @@ +package parlia + +import ( + "math/rand" + + "github.com/ledgerwatch/erigon-lib/chain" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/log/v3" +) + +func backOffTime(snap *Snapshot, header *types.Header, val libcommon.Address, chainConfig *chain.Config) uint64 { + if snap.inturn(val) { + return 0 + } else { + delay := initialBackOffTime + validators := snap.validators() + if chainConfig.IsPlanck(header.Number.Uint64()) { + // reverse the key/value of snap.Recents to get recentsMap + recentsMap := make(map[libcommon.Address]uint64, len(snap.Recents)) + bound := uint64(0) + if n, limit := header.Number.Uint64(), uint64(len(validators)/2+1); n > limit { + bound = n - limit + } + for seen, recent := range snap.Recents { + if seen <= bound { + continue + } + recentsMap[recent] = seen + } + + // The backOffTime does not matter when a validator has signed recently. + if _, ok := recentsMap[val]; ok { + return 0 + } + + inTurnAddr := validators[(snap.Number+1)%uint64(len(validators))] + if _, ok := recentsMap[inTurnAddr]; ok { + log.Debug("in turn validator has recently signed, skip initialBackOffTime", + "inTurnAddr", inTurnAddr) + delay = 0 + } + + // Exclude the recently signed validators + temp := make([]libcommon.Address, 0, len(validators)) + for _, addr := range validators { + if _, ok := recentsMap[addr]; ok { + continue + } + temp = append(temp, addr) + } + validators = temp + } + + // get the index of current validator and its shuffled backoff time. + idx := -1 + for index, itemAddr := range validators { + if val == itemAddr { + idx = index + } + } + if idx < 0 { + log.Info("The validator is not authorized", "addr", val) + return 0 + } + + s := rand.NewSource(int64(snap.Number)) + r := rand.New(s) // nolint:gosec + n := len(validators) + backOffSteps := make([]uint64, 0, n) + + for i := uint64(0); i < uint64(n); i++ { + backOffSteps = append(backOffSteps, i) + } + + r.Shuffle(n, func(i, j int) { + backOffSteps[i], backOffSteps[j] = backOffSteps[j], backOffSteps[i] + }) + + delay += backOffSteps[idx] * wiggleTime + return delay + } +} diff --git a/consensus/parlia/utils.go b/consensus/parlia/utils.go deleted file mode 100644 index 6740131d071..00000000000 --- a/consensus/parlia/utils.go +++ /dev/null @@ -1,31 +0,0 @@ -package parlia - -import ( - "math/rand" - - libcommon "github.com/ledgerwatch/erigon-lib/common" -) - -func backOffTime(snap *Snapshot, val libcommon.Address) uint64 { - if snap.inturn(val) { - return 0 - } else { - idx := snap.indexOfVal(val) - if idx < 0 { - // The backOffTime does not matter when a validator is not authorized. - return 0 - } - s := rand.NewSource(int64(snap.Number)) - r := rand.New(s) // nolint: gosec - n := len(snap.Validators) - backOffSteps := make([]uint64, 0, n) - for idx := uint64(0); idx < uint64(n); idx++ { - backOffSteps = append(backOffSteps, idx) - } - r.Shuffle(n, func(i, j int) { - backOffSteps[i], backOffSteps[j] = backOffSteps[j], backOffSteps[i] - }) - delay := initialBackOffTime + backOffSteps[idx]*wiggleTime - return delay - } -} diff --git a/consensus/serenity/serenity.go b/consensus/serenity/serenity.go index 86756129da0..ab5b149aee8 100644 --- a/consensus/serenity/serenity.go +++ b/consensus/serenity/serenity.go @@ -125,10 +125,10 @@ func (s *Serenity) Prepare(chain consensus.ChainHeaderReader, header *types.Head func (s *Serenity) Finalize(config *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions, uncles []*types.Header, r types.Receipts, withdrawals []*types.Withdrawal, - e consensus.EpochReader, chain consensus.ChainHeaderReader, syscall consensus.SystemCall, + chain consensus.ChainHeaderReader, syscall consensus.SystemCall, ) (types.Transactions, types.Receipts, error) { if !IsPoSHeader(header) { - return s.eth1Engine.Finalize(config, header, state, txs, uncles, r, withdrawals, e, chain, syscall) + return s.eth1Engine.Finalize(config, header, state, txs, uncles, r, withdrawals, chain, syscall) } if auraEngine, ok := s.eth1Engine.(*aura.AuRa); ok { if err := auraEngine.ApplyRewards(header, state, syscall); err != nil { @@ -143,17 +143,24 @@ func (s *Serenity) Finalize(config *chain.Config, header *types.Header, state *s state.AddBalance(w.Address, amountInWei) } } + if config.IsCancun(header.Time) { + parent := chain.GetHeaderByHash(header.ParentHash) + if parent == nil { + return nil, nil, fmt.Errorf("Could not find the parent of block %v to get excess data gas", header.Number.Uint64()) + } + header.SetExcessDataGas(misc.CalcExcessDataGas(parent.ExcessDataGas, misc.CountBlobs(txs))) + } return txs, r, nil } func (s *Serenity) FinalizeAndAssemble(config *chain.Config, header *types.Header, state *state.IntraBlockState, txs types.Transactions, uncles []*types.Header, receipts types.Receipts, withdrawals []*types.Withdrawal, - e consensus.EpochReader, chain consensus.ChainHeaderReader, syscall consensus.SystemCall, call consensus.Call, + chain consensus.ChainHeaderReader, syscall consensus.SystemCall, call consensus.Call, ) (*types.Block, types.Transactions, types.Receipts, error) { if !IsPoSHeader(header) { - return s.eth1Engine.FinalizeAndAssemble(config, header, state, txs, uncles, receipts, withdrawals, e, chain, syscall, call) + return s.eth1Engine.FinalizeAndAssemble(config, header, state, txs, uncles, receipts, withdrawals, chain, syscall, call) } - outTxs, outReceipts, err := s.Finalize(config, header, state, txs, uncles, receipts, withdrawals, e, chain, syscall) + outTxs, outReceipts, err := s.Finalize(config, header, state, txs, uncles, receipts, withdrawals, chain, syscall) if err != nil { return nil, nil, nil, err } @@ -225,6 +232,15 @@ func (s *Serenity) verifyHeader(chain consensus.ChainHeaderReader, header, paren if !shanghai && header.WithdrawalsHash != nil { return consensus.ErrUnexpectedWithdrawals } + + if !chain.Config().IsCancun(header.Time) { + if header.ExcessDataGas != nil { + return fmt.Errorf("invalid excessDataGas before fork: have %v, expected 'nil'", header.ExcessDataGas) + } + } else if err := misc.VerifyEip4844Header(chain.Config(), parent, header); err != nil { + // Verify the header's EIP-4844 attributes. + return err + } return nil } @@ -243,8 +259,8 @@ func (s *Serenity) IsServiceTransaction(sender libcommon.Address, syscall consen return s.eth1Engine.IsServiceTransaction(sender, syscall) } -func (s *Serenity) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, e consensus.EpochReader, header *types.Header, state *state.IntraBlockState, txs []types.Transaction, uncles []*types.Header, syscall consensus.SystemCall) { - s.eth1Engine.Initialize(config, chain, e, header, state, txs, uncles, syscall) +func (s *Serenity) Initialize(config *chain.Config, chain consensus.ChainHeaderReader, header *types.Header, state *state.IntraBlockState, txs []types.Transaction, uncles []*types.Header, syscall consensus.SystemCall) { + s.eth1Engine.Initialize(config, chain, header, state, txs, uncles, syscall) } func (s *Serenity) APIs(chain consensus.ChainHeaderReader) []rpc.API { diff --git a/core/allocs/bsc.json b/core/allocs/bsc.json index 2ffe140b9e6..fdfe10775e2 100644 --- a/core/allocs/bsc.json +++ b/core/allocs/bsc.json @@ -1,51 +1,51 @@ { - "0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE": { - "balance": "0x0" - }, - "0x0000000000000000000000000000000000001000": { - "balance": "0x0", - "code": "0x60806040526004361061027d5760003560e01c80639dc092621161014f578063c8509d81116100c1578063eb57e2021161007a578063eb57e20214610940578063eda5868c14610973578063f340fa0114610988578063f9a2bbc7146109ae578063fc3e5908146109c3578063fd6a6879146109d85761027d565b8063c8509d8114610609578063d86222d5146108d7578063daacdb66146108ec578063dc927faf14610901578063e086c7b114610916578063e1c7392a1461092b5761027d565b8063ab51bb9611610113578063ab51bb961461074a578063ac4317511461075f578063ad3c9da61461082a578063b7ab4db51461085d578063bf9f49951461041b578063c81b1662146108c25761027d565b80639dc09262146106cd578063a1a11bf5146106e2578063a5422d5c146106f7578063a78abc161461070c578063aaf5eb68146107355761027d565b80635667515a116101f35780637942fd05116101ac5780637942fd05146105df57806381650b62146105f4578063831d65d114610609578063853230aa1461068e57806386249882146106a357806396713da9146106b85761027d565b80635667515a146105005780635d77156c146105155780636969a25c1461052a5780636e47b482146105a057806370fd5bad146105b557806375d47a0a146105ca5761027d565b80633dffc387116102455780633dffc3871461041b57806343756e5c14610446578063493279b1146104775780634bf6c882146104a357806351e80672146104b8578063565c56b3146104cd5761027d565b80630bee7a67146102825780631182b875146102b05780631ff18069146103aa578063219f22d5146103d157806335409f7f146103e6575b600080fd5b34801561028e57600080fd5b506102976109ed565b6040805163ffffffff9092168252519081900360200190f35b3480156102bc57600080fd5b50610335600480360360408110156102d357600080fd5b60ff8235169190810190604081016020820135600160201b8111156102f757600080fd5b82018360208201111561030957600080fd5b803590602001918460018302840111600160201b8311171561032a57600080fd5b5090925090506109f2565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561036f578181015183820152602001610357565b50505050905090810190601f16801561039c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103b657600080fd5b506103bf610bdf565b60408051918252519081900360200190f35b3480156103dd57600080fd5b50610297610be5565b3480156103f257600080fd5b506104196004803603602081101561040957600080fd5b50356001600160a01b0316610bea565b005b34801561042757600080fd5b50610430610efe565b6040805160ff9092168252519081900360200190f35b34801561045257600080fd5b5061045b610f03565b604080516001600160a01b039092168252519081900360200190f35b34801561048357600080fd5b5061048c610f09565b6040805161ffff9092168252519081900360200190f35b3480156104af57600080fd5b50610430610f0e565b3480156104c457600080fd5b5061045b610f13565b3480156104d957600080fd5b506103bf600480360360208110156104f057600080fd5b50356001600160a01b0316610f19565b34801561050c57600080fd5b50610430610f6b565b34801561052157600080fd5b50610297610f70565b34801561053657600080fd5b506105546004803603602081101561054d57600080fd5b5035610f75565b604080516001600160a01b039788168152958716602087015293909516848401526001600160401b0390911660608401521515608083015260a082019290925290519081900360c00190f35b3480156105ac57600080fd5b5061045b610fd9565b3480156105c157600080fd5b50610430610fdf565b3480156105d657600080fd5b5061045b610fe4565b3480156105eb57600080fd5b50610430610fea565b34801561060057600080fd5b50610297610fef565b34801561061557600080fd5b506104196004803603604081101561062c57600080fd5b60ff8235169190810190604081016020820135600160201b81111561065057600080fd5b82018360208201111561066257600080fd5b803590602001918460018302840111600160201b8311171561068357600080fd5b509092509050610ff4565b34801561069a57600080fd5b506103bf6110a7565b3480156106af57600080fd5b506103bf6110ad565b3480156106c457600080fd5b506104306110b3565b3480156106d957600080fd5b5061045b6110b8565b3480156106ee57600080fd5b5061045b6110be565b34801561070357600080fd5b506103356110c4565b34801561071857600080fd5b506107216110e3565b604080519115158252519081900360200190f35b34801561074157600080fd5b506103bf6110ec565b34801561075657600080fd5b50610297610f6b565b34801561076b57600080fd5b506104196004803603604081101561078257600080fd5b810190602081018135600160201b81111561079c57600080fd5b8201836020820111156107ae57600080fd5b803590602001918460018302840111600160201b831117156107cf57600080fd5b919390929091602081019035600160201b8111156107ec57600080fd5b8201836020820111156107fe57600080fd5b803590602001918460018302840111600160201b8311171561081f57600080fd5b5090925090506110f5565b34801561083657600080fd5b506103bf6004803603602081101561084d57600080fd5b50356001600160a01b031661139c565b34801561086957600080fd5b506108726113ae565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156108ae578181015183820152602001610896565b505050509050019250505060405180910390f35b3480156108ce57600080fd5b5061045b6114d4565b3480156108e357600080fd5b506103bf6114da565b3480156108f857600080fd5b506103bf6114e6565b34801561090d57600080fd5b5061045b6114ec565b34801561092257600080fd5b506103bf6114f2565b34801561093757600080fd5b506104196114f7565b34801561094c57600080fd5b506104196004803603602081101561096357600080fd5b50356001600160a01b03166116fa565b34801561097f57600080fd5b506102976118c9565b6104196004803603602081101561099e57600080fd5b50356001600160a01b03166118ce565b3480156109ba57600080fd5b5061045b611b04565b3480156109cf57600080fd5b50610430611b0a565b3480156109e457600080fd5b5061045b611b0f565b606481565b60005460609060ff16610a48576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b3361200014610a885760405162461bcd60e51b815260040180806020018281038252602f815260200180614516602f913960400191505060405180910390fd5b610a90613d69565b6000610ad185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611b1592505050565b9150915080610aed57610ae46064611c6e565b92505050610bd8565b815160009060ff16610b0d57610b068360200151611ccf565b9050610ba4565b825160ff1660011415610ba057826020015151600114610b7a577f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2604051808060200182810382526025815260200180613e6c6025913960400191505060405180910390a1506067610b9b565b610b068360200151600081518110610b8e57fe5b6020026020010151612ad5565b610ba4565b5060655b63ffffffff8116610bc95750506040805160008152602081019091529150610bd89050565b610bd281611c6e565b93505050505b9392505050565b60035481565b606881565b3361100114610c2a5760405162461bcd60e51b81526004018080602001828103825260298152602001806145726029913960400191505060405180910390fd5b6001600160a01b03811660009081526004602052604090205480610c4e5750610efb565b600181039050600060018281548110610c6357fe5b60009182526020909120600360049092020101546001549091506000190180610cb257600060018481548110610c9557fe5b906000526020600020906004020160030181905550505050610efb565b6040805183815290516001600160a01b038616917f3b6f9ef90462b512a1293ecec018670bf7b7f1876fb727590a8a6d7643130a70919081900360200190a26001600160a01b038416600090815260046020526040812055600154600019018314610e3457600180546000198101908110610d2957fe5b906000526020600020906004020160018481548110610d4457fe5b6000918252602082208354600492830290910180546001600160a01b03199081166001600160a01b0393841617825560018087015481840180548416918616919091179055600280880180549185018054909416919095161780835584546001600160401b03600160a01b91829004160267ffffffffffffffff60a01b1990911617808355935460ff600160e01b918290041615150260ff60e01b199094169390931790556003948501549401939093558254868401939192919087908110610e0957fe5b600091825260208083206004909202909101546001600160a01b031683528201929092526040019020555b6001805480610e3f57fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b03191690556003018190559155818381610e9257fe5b0490508015610ef65760015460005b81811015610ef3578260018281548110610eb757fe5b9060005260206000209060040201600301540160018281548110610ed757fe5b6000918252602090912060036004909202010155600101610ea1565b50505b505050505b50565b600181565b61100181565b603881565b600881565b61200081565b6001600160a01b03811660009081526004602052604081205480610f41576000915050610f66565b600180820381548110610f5057fe5b9060005260206000209060040201600301549150505b919050565b600081565b606781565b60018181548110610f8257fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b0392831694509082169291821691600160a01b81046001600160401b031691600160e01b90910460ff169086565b61100581565b600281565b61100881565b600b81565b606681565b33612000146110345760405162461bcd60e51b815260040180806020018281038252602f815260200180614516602f913960400191505060405180910390fd5b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a1505050565b6103e881565b60025481565b600981565b61100781565b61100681565b6040518061062001604052806105ef8152602001613f276105ef913981565b60005460ff1681565b6402540be40081565b60005460ff16611148576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b33611007146111885760405162461bcd60e51b815260040180806020018281038252602e815260200180613e91602e913960400191505060405180910390fd5b6111f284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526013815272065787069726554696d655365636f6e6447617606c1b60208201529150612c4c9050565b156112cd57602081146112365760405162461bcd60e51b8152600401808060200182810382526026815260200180613ee06026913960400191505060405180910390fd5b604080516020601f840181900481028201810190925282815260009161127491858580838501838280828437600092019190915250612d3492505050565b90506064811015801561128a5750620186a08111155b6112c55760405162461bcd60e51b8152600401808060200182810382526027815260200180613e456027913960400191505060405180910390fd5b60025561130a565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b60046020526000908152604090205481565b6001546060906000805b828110156113ff57600181815481106113cd57fe5b9060005260206000209060040201600201601c9054906101000a900460ff166113f7576001909101905b6001016113b8565b5060608160405190808252806020026020018201604052801561142c578160200160208202803683370190505b50600092509050815b838110156114cc576001818154811061144a57fe5b9060005260206000209060040201600201601c9054906101000a900460ff166114c4576001818154811061147a57fe5b600091825260209091206004909102015482516001600160a01b03909116908390859081106114a557fe5b6001600160a01b03909216602092830291909101909101526001909201915b600101611435565b509250505090565b61100281565b67016345785d8a000081565b60055481565b61100381565b602981565b60005460ff161561154f576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b611557613d69565b600061157d6040518061062001604052806105ef8152602001613f276105ef9139611b15565b91509150806115bd5760405162461bcd60e51b8152600401808060200182810382526021815260200180613f066021913960400191505060405180910390fd5b60005b8260200151518110156116e2576001836020015182815181106115df57fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782558587015182850180549185169183169190911790556040860151600283018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590981692909516919091179290921694909417161790915560a0909301516003909301929092559186015180519185019391859081106116b557fe5b602090810291909101810151516001600160a01b03168252810191909152604001600020556001016115c0565b50506103e8600255506000805460ff19166001179055565b336110011461173a5760405162461bcd60e51b81526004018080602001828103825260298152602001806145726029913960400191505060405180910390fd5b6001600160a01b0381166000908152600460205260409020548061175e5750610efb565b60018103905060006001828154811061177357fe5b906000526020600020906004020160030154905060006001838154811061179657fe5b906000526020600020906004020160030181905550600060018080549050039050836001600160a01b03167f8cd4e147d8af98a9e3b6724021b8bf6aed2e5dac71c38f2dce8161b82585b25d836040518082815260200191505060405180910390a28061180557505050610efb565b600081838161181057fe5b0490508015610ef65760005b8481101561186e57816001828154811061183257fe5b906000526020600020906004020160030154016001828154811061185257fe5b600091825260209091206003600490920201015560010161181c565b50600180549085015b81811015610ef357826001828154811061188d57fe5b90600052602060002090600402016003015401600182815481106118ad57fe5b6000918252602090912060036004909202010155600101611877565b606581565b33411461190c5760405162461bcd60e51b815260040180806020018281038252602d815260200180614545602d913960400191505060405180910390fd5b60005460ff1661195f576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b600034116119ac576040805162461bcd60e51b81526020600482015260156024820152746465706f7369742076616c7565206973207a65726f60581b604482015290519081900360640190fd5b6001600160a01b03811660009081526004602052604090205434908015611abf5760006001808303815481106119de57fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff1615611a49576040805184815290516001600160a01b038616917ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b4919081900360200190a2611ab9565b600354611a5c908463ffffffff612d3916565b6003908155810154611a74908463ffffffff612d3916565b60038201556040805184815290516001600160a01b038616917f93a090ecc682c002995fad3c85b30c5651d7fd29b0be5da9d784a3302aedc055919081900360200190a25b50611aff565b6040805183815290516001600160a01b038516917ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b4919081900360200190a25b505050565b61100081565b600381565b61100481565b611b1d613d69565b6000611b27613d69565b611b2f613d81565b611b40611b3b86612d93565b612db8565b90506000805b611b4f83612e02565b15611c605780611b7457611b6a611b6584612e23565b612e71565b60ff168452611c58565b8060011415611c53576060611b90611b8b85612e23565b612f28565b90508051604051908082528060200260200182016040528015611bcd57816020015b611bba613da1565b815260200190600190039081611bb25790505b50602086015260005b8151811015611c4857611be7613da1565b6000611c05848481518110611bf857fe5b6020026020010151612ff9565b9150915080611c2257876000995099505050505050505050611c69565b8188602001518481518110611c3357fe5b60209081029190910101525050600101611bd6565b506001925050611c58565b611c60565b600101611b46565b50919350909150505b915091565b604080516001808252818301909252606091829190816020015b6060815260200190600190039081611c88579050509050611cae8363ffffffff166130d6565b81600081518110611cbb57fe5b6020026020010181905250610bd8816130e9565b6000806060611cdd84613173565b9150915081611d8a577f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2816040518080602001828103825283818151815260200191508051906020019080838360005b83811015611d45578181015183820152602001611d2d565b50505050905090810190601f168015611d725780820380516001836020036101000a031916815260200191505b509250505060405180910390a1606692505050610f66565b600080805b600154811015611e075767016345785d8a000060018281548110611daf57fe5b90600052602060002090600402016003015410611dd157600190920191611dff565b600060018281548110611de057fe5b9060005260206000209060040201600301541115611dff576001909101905b600101611d8f565b50606082604051908082528060200260200182016040528015611e34578160200160208202803683370190505b509050606083604051908082528060200260200182016040528015611e63578160200160208202803683370190505b509050606084604051908082528060200260200182016040528015611e92578160200160208202803683370190505b509050606085604051908082528060200260200182016040528015611ec1578160200160208202803683370190505b5090506000606086604051908082528060200260200182016040528015611ef2578160200160208202803683370190505b509050606087604051908082528060200260200182016040528015611f21578160200160208202803683370190505b509050600098506000975060608d905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b158015611f6e57600080fd5b505afa158015611f82573d6000803e3d6000fd5b505050506040513d6020811015611f9857600080fd5b5051905067016345785d8a000081111561200d577f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2604051808060200182810382526021815260200180613ebf6021913960400191505060405180910390a160689d5050505050505050505050505050610f66565b60005b6001548110156122805767016345785d8a00006001828154811061203057fe5b906000526020600020906004020160030154106121b6576001818154811061205457fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b03168a8d8151811061208557fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060006402540be400600183815481106120ba57fe5b906000526020600020906004020160030154816120d357fe5b06600183815481106120e157fe5b906000526020600020906004020160030154039050612109838261325590919063ffffffff16565b8a8e8151811061211557fe5b6020026020010181815250506001828154811061212e57fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316888e8151811061215f57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505081898e8151811061218c57fe5b60209081029190910101526121a7878263ffffffff612d3916565b6001909d019c96506122789050565b6000600182815481106121c557fe5b906000526020600020906004020160030154111561227857600181815481106121ea57fe5b906000526020600020906004020160010160009054906101000a90046001600160a01b0316858c8151811061221b57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506001818154811061224857fe5b906000526020600020906004020160030154848c8151811061226657fe5b60209081029190910101526001909a01995b600101612010565b50600085156126be576110046001600160a01b0316636e056520878c8c8b60025442016040518663ffffffff1660e01b815260040180806020018060200180602001856001600160401b03166001600160401b03168152602001848103845288818151815260200191508051906020019060200280838360005b838110156123125781810151838201526020016122fa565b50505050905001848103835287818151815260200191508051906020019060200280838360005b83811015612351578181015183820152602001612339565b50505050905001848103825286818151815260200191508051906020019060200280838360005b83811015612390578181015183820152602001612378565b505050509050019750505050505050506020604051808303818588803b1580156123b957600080fd5b505af1935050505080156123df57506040513d60208110156123da57600080fd5b505160015b61261a576040516000815260443d10156123fb57506000612496565b60046000803e60005160e01c6308c379a0811461241c576000915050612496565b60043d036004833e81513d60248201116001600160401b038211171561244757600092505050612496565b80830180516001600160401b03811115612468576000945050505050612496565b8060208301013d860181111561248657600095505050505050612496565b601f01601f191660405250925050505b806124a15750612545565b60019150867fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf280826040518080602001828103825283818151815260200191508051906020019080838360005b838110156125055781810151838201526020016124ed565b50505050905090810190601f1680156125325780820380516001836020036101000a031916815260200191505b509250505060405180910390a250612615565b3d80801561256f576040519150601f19603f3d011682016040523d82523d6000602084013e612574565b606091505b5060019150867fbfa884552dd8921b6ce90bfe906952ae5b3b29be0cc1a951d4f62697635a3a45826040518080602001828103825283818151815260200191508051906020019080838360005b838110156125d95781810151838201526020016125c1565b50505050905090810190601f1680156126065780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b6126be565b8015612658576040805188815290517fa217d08e65f80c73121cd9db834d81652d544bfbf452f6d04922b16c90a37b709181900360200190a16126bc565b604080516020808252601b908201527f6261746368207472616e736665722072657475726e2066616c7365000000000081830152905188917fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf280919081900360600190a25b505b80156128745760005b88518110156128725760008982815181106126de57fe5b602002602001015190506000600182815481106126f757fe5b60009182526020909120600160049092020181015481546001600160a01b03909116916108fc918590811061272857fe5b9060005260206000209060040201600301549081150290604051600060405180830381858888f19350505050905080156127e4576001828154811061276957fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d91859081106127b857fe5b9060005260206000209060040201600301546040518082815260200191505060405180910390a2612868565b600182815481106127f157fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d918590811061284057fe5b9060005260206000209060040201600301546040518082815260200191505060405180910390a25b50506001016126c7565b505b8451156129be5760005b85518110156129bc57600086828151811061289557fe5b60200260200101516001600160a01b03166108fc8784815181106128b557fe5b60200260200101519081150290604051600060405180830381858888f193505050509050801561294b578682815181106128eb57fe5b60200260200101516001600160a01b03167f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d87848151811061292957fe5b60200260200101516040518082815260200191505060405180910390a26129b3565b86828151811061295757fe5b60200260200101516001600160a01b03167f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d87848151811061299557fe5b60200260200101516040518082815260200191505060405180910390a25b5060010161287e565b505b4715612a27576040805147815290517f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d9181900360200190a1604051611002904780156108fc02916000818181858888f19350505050158015612a25573d6000803e3d6000fd5b505b60006003819055600555825115612a4157612a4183613297565b6110016001600160a01b031663fc4333cd6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612a7e57600080fd5b505af1158015612a92573d6000803e3d6000fd5b50506040517fedd8d7296956dd970ab4de3f2fc03be2b0ffc615d20cd4c72c6e44f928630ebf925060009150a15060009f9e505050505050505050505050505050565b80516001600160a01b0316600090815260046020526040812054801580612b265750600180820381548110612b0657fe5b9060005260206000209060040201600201601c9054906101000a900460ff165b15612b6c5782516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a26000915050610f66565b600154600554600019820111801590612bc25784516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a260009350505050610f66565b600580546001908101909155805481906000198601908110612be057fe5b6000918252602082206002600490920201018054921515600160e01b0260ff60e01b199093169290921790915585516040516001600160a01b03909116917ff226e7d8f547ff903d9d419cf5f54e0d7d07efa9584135a53a057c5f1f27f49a91a2506000949350505050565b6000816040516020018082805190602001908083835b60208310612c815780518252601f199092019160209182019101612c62565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310612cef5780518252601f199092019160209182019101612cd0565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490505b92915050565b015190565b600082820183811015610bd8576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b612d9b613dd6565b506040805180820190915281518152602082810190820152919050565b612dc0613d81565b612dc98261375e565b612dd257600080fd5b6000612de18360200151613798565b60208085015160408051808201909152868152920190820152915050919050565b6000612e0c613dd6565b505080518051602091820151919092015191011190565b612e2b613dd6565b612e3482612e02565b612e3d57600080fd5b60208201516000612e4d826137fb565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590612e8657508151602110155b612e8f57600080fd5b6000612e9e8360200151613798565b90508083600001511015612ef9576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b825160208085015183018051928490039291831015612f1f57826020036101000a820491505b50949350505050565b6060612f338261375e565b612f3c57600080fd5b6000612f478361392e565b9050606081604051908082528060200260200182016040528015612f8557816020015b612f72613dd6565b815260200190600190039081612f6a5790505b5090506000612f978560200151613798565b60208601510190506000805b84811015612fee57612fb4836137fb565b9150604051806040016040528083815260200184815250848281518110612fd757fe5b602090810291909101015291810191600101612fa3565b509195945050505050565b613001613da1565b600061300b613da1565b613013613d81565b61301c85612db8565b90506000805b61302b83612e02565b15611c6057806130565761304661304184612e23565b61398a565b6001600160a01b031684526130ce565b806001141561307e5761306b61304184612e23565b6001600160a01b031660208501526130ce565b80600214156130a65761309361304184612e23565b6001600160a01b031660408501526130ce565b8060031415611c53576130bb611b6584612e23565b6001600160401b03166060850152600191505b600101613022565b6060612d2e6130e4836139a4565b613a8a565b606081516000141561310a5750604080516000815260208101909152610f66565b60608260008151811061311957fe5b602002602001015190506000600190505b835181101561315a576131508285838151811061314357fe5b6020026020010151613adc565b915060010161312a565b50610bd861316d825160c060ff16613b59565b82613adc565b600060606029835111156131a5576000604051806060016040528060298152602001613df16029913991509150611c69565b60005b835181101561323b5760005b81811015613232578481815181106131c857fe5b6020026020010151600001516001600160a01b03168583815181106131e957fe5b6020026020010151600001516001600160a01b0316141561322a5760006040518060600160405280602b8152602001613e1a602b9139935093505050611c69565b6001016131b4565b506001016131a8565b505060408051602081019091526000815260019150915091565b6000610bd883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613c51565b600154815160005b828110156133b45760016132b1613da1565b600183815481106132be57fe5b600091825260208083206040805160c08101825260049490940290910180546001600160a01b0390811685526001820154811693850193909352600281015492831691840191909152600160a01b82046001600160401b03166060840152600160e01b90910460ff16151560808301526003015460a082015291505b848110156133885786818151811061334e57fe5b6020026020010151600001516001600160a01b031682600001516001600160a01b031614156133805760009250613388565b60010161333a565b5081156133aa5780516001600160a01b03166000908152600460205260408120555b505060010161329f565b508082111561342957805b828110156134275760018054806133d257fe5b60008281526020812060046000199093019283020180546001600160a01b03199081168255600182810180549092169091556002820180546001600160e81b03191690556003909101919091559155016133bf565b505b6000818310613438578161343a565b825b905060005b81811015613634576134ec85828151811061345657fe5b60200260200101516001838154811061346b57fe5b60009182526020918290206040805160c08101825260049390930290910180546001600160a01b0390811684526001820154811694840194909452600281015493841691830191909152600160a01b83046001600160401b03166060830152600160e01b90920460ff161515608082015260039091015460a0820152613ce8565b61360757806001016004600087848151811061350457fe5b6020026020010151600001516001600160a01b03166001600160a01b031681526020019081526020016000208190555084818151811061354057fe5b60200260200101516001828154811061355557fe5b6000918252602091829020835160049092020180546001600160a01b039283166001600160a01b0319918216178255928401516001820180549184169185169190911790556040840151600282018054606087015160808801511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909716929097169190911792909216939093171692909217905560a09091015160039091015561362c565b60006001828154811061361657fe5b9060005260206000209060040201600301819055505b60010161343f565b508282111561375857825b82811015610ef657600185828151811061365557fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782559585015181840180549184169188169190911790556040850151600282018054606088015160808901511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590971692909a169190911792909216939093171695909517905560a0909201516003909301929092558751908401929088908590811061372b57fe5b602090810291909101810151516001600160a01b031682528101919091526040016000205560010161363f565b50505050565b805160009061376f57506000610f66565b6020820151805160001a9060c082101561378e57600092505050610f66565b5060019392505050565b8051600090811a60808110156137b2576000915050610f66565b60b88110806137cd575060c081108015906137cd575060f881105b156137dc576001915050610f66565b60c08110156137f05760b519019050610f66565b60f519019050610f66565b80516000908190811a60808110156138165760019150613927565b60b881101561382b57607e1981019150613927565b60c08110156138a557600060b78203600186019550806020036101000a86510491506001810182019350508083101561389f576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b50613927565b60f88110156138ba5760be1981019150613927565b600060f78203600186019550806020036101000a865104915060018101820193505080831015613925576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b805160009061393f57506000610f66565b600080905060006139538460200151613798565b602085015185519181019250015b8082101561398157613972826137fb565b60019093019290910190613961565b50909392505050565b805160009060151461399b57600080fd5b612d2e82612e71565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166139e857506018613a0c565b6fffffffffffffffffffffffffffffffff198416613a0857506010613a0c565b5060005b6020811015613a4257818181518110613a2157fe5b01602001516001600160f81b03191615613a3a57613a42565b600101613a0c565b60008160200390506060816040519080825280601f01601f191660200182016040528015613a77576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015613abc5750607f60f81b82600081518110613aaa57fe5b01602001516001600160f81b03191611155b15613ac8575080610f66565b612d2e613ada8351608060ff16613b59565b835b6060806040519050835180825260208201818101602087015b81831015613b0d578051835260209283019201613af5565b50855184518101855292509050808201602086015b81831015613b3a578051835260209283019201613b22565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310613ba9576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411613c035782840160f81b81600081518110613be557fe5b60200101906001600160f81b031916908160001a9053509050612d2e565b6060613c0e856139a4565b90508381510160370160f81b82600081518110613c2757fe5b60200101906001600160f81b031916908160001a905350613c488282613adc565b95945050505050565b60008184841115613ce05760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613ca5578181015183820152602001613c8d565b50505050905090810190601f168015613cd25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b805182516000916001600160a01b039182169116148015613d22575081602001516001600160a01b031683602001516001600160a01b0316145b8015613d47575081604001516001600160a01b031683604001516001600160a01b0316145b8015610bd85750506060908101519101516001600160401b0390811691161490565b60408051808201909152600081526060602082015290565b6040518060400160405280613d94613dd6565b8152602001600081525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b60405180604001604052806000815260200160008152509056fe746865206e756d626572206f662076616c696461746f72732065786365656420746865206c696d69746475706c696361746520636f6e73656e7375732061646472657373206f662076616c696461746f725365747468652065787069726554696d655365636f6e64476170206973206f7574206f662072616e67656c656e677468206f66206a61696c2076616c696461746f7273206d757374206265206f6e65746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374666565206973206c6172676572207468616e2044555354595f494e434f4d494e476c656e677468206f662065787069726554696d655365636f6e64476170206d69736d617463686661696c656420746f20706172736520696e69742076616c696461746f72536574f905ec80f905e8f846942a7cdd959bfe8d9487b2a43b33565295a698f7e294b6a7edd747c0554875d3fc531d19ba1497992c5e941ff80f3f7f110ffd8920a3ac38fdef318fe94a3f86048c27395000f846946488aa4d1955ee33403f8ccb1d4de5fb97c7ade294220f003d8bdfaadf52aa1e55ae4cc485e6794875941a87e90e440a39c99aa9cb5cea0ad6a3f0b2407b86048c27395000f846949ef9f4360c606c7ab4db26b016007d3ad0ab86a0946103af86a874b705854033438383c82575f25bc29418e2db06cbff3e3c5f856410a1838649e760175786048c27395000f84694ee01c3b1283aa067c58eab4709f85e99d46de5fe94ee4b9bfb1871c64e2bcabb1dc382dc8b7c4218a29415904ab26ab0e99d70b51c220ccdcccabee6e29786048c27395000f84694685b1ded8013785d6623cc18d214320b6bb6475994a20ef4e5e4e7e36258dbf51f4d905114cb1b34bc9413e39085dc88704f4394d35209a02b1a9520320c86048c27395000f8469478f3adfc719c99674c072166708589033e2d9afe9448a30d5eaa7b64492a160f139e2da2800ec3834e94055838358c29edf4dcc1ba1985ad58aedbb6be2b86048c27395000f84694c2be4ec20253b8642161bc3f444f53679c1f3d479466f50c616d737e60d7ca6311ff0d9c434197898a94d1d678a2506eeaa365056fe565df8bc8659f28b086048c27395000f846942f7be8361c80a4c1e7e9aaf001d0877f1cfde218945f93992ac37f3e61db2ef8a587a436a161fd210b94ecbc4fb1a97861344dad0867ca3cba2b860411f086048c27395000f84694ce2fd7544e0b2cc94692d4a704debef7bcb613289444abc67b4b2fba283c582387f54c9cba7c34bafa948acc2ab395ded08bb75ce85bf0f95ad2abc51ad586048c27395000f84694b8f7166496996a7da21cf1f1b04d9b3e26a3d077946770572763289aac606e4f327c2f6cc1aa3b3e3b94882d745ed97d4422ca8da1c22ec49d880c4c097286048c27395000f846942d4c407bbe49438ed859fe965b140dcf1aab71a9943ad0939e120f33518fbba04631afe7a3ed6327b194b2bbb170ca4e499a2b0f3cc85ebfa6e8c4dfcbea86048c27395000f846946bbad7cf34b5fa511d8e963dbba288b1960e75d694853b0f6c324d1f4e76c8266942337ac1b0af1a229442498946a51ca5924552ead6fc2af08b94fcba648601d1a94a2000f846944430b3230294d12c6ab2aac5c2cd68e80b16b581947b107f4976a252a6939b771202c28e64e03f52d694795811a7f214084116949fc4f53cedbf189eeab28601d1a94a2000f84694ea0a6e3c511bbd10f4519ece37dc24887e11b55d946811ca77acfb221a49393c193f3a22db829fcc8e9464feb7c04830dd9ace164fc5c52b3f5a29e5018a8601d1a94a2000f846947ae2f5b9e386cd1b50a4550696d957cb4900f03a94e83bcc5077e6b873995c24bac871b5ad856047e19464e48d4057a90b233e026c1041e6012ada897fe88601d1a94a2000f8469482012708dafc9e1b880fd083b32182b869be8e09948e5adc73a2d233a1b496ed3115464dd6c7b887509428b383d324bc9a37f4e276190796ba5a8947f5ed8601d1a94a2000f8469422b81f8e175ffde54d797fe11eb03f9e3bf75f1d94a1c3ef7ca38d8ba80cce3bfc53ebd2903ed21658942767f7447f7b9b70313d4147b795414aecea54718601d1a94a2000f8469468bf0b8b6fb4e317a0f9d6f03eaf8ce6675bc60d94675cfe570b7902623f47e7f59c9664b5f5065dcf94d84f0d2e50bcf00f2fc476e1c57f5ca2d57f625b8601d1a94a2000f846948c4d90829ce8f72d0163c1d5cf348a862d5506309485c42a7b34309bee2ed6a235f86d16f059deec5894cc2cedc53f0fa6d376336efb67e43d167169f3b78601d1a94a2000f8469435e7a025f4da968de7e4d7e4004197917f4070f194b1182abaeeb3b4d8eba7e6a4162eac7ace23d57394c4fd0d870da52e73de2dd8ded19fe3d26f43a1138601d1a94a2000f84694d6caa02bbebaebb5d7e581e4b66559e635f805ff94c07335cf083c1c46a487f0325769d88e163b653694efaff03b42e41f953a925fc43720e45fb61a19938601d1a94a2000746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d6573736167652073656e646572206d7573742062652074686520626c6f636b2070726f6475636572746865206d6573736167652073656e646572206d75737420626520736c61736820636f6e7472616374a2646970667358221220f4016eb3755efa2abde797b21f8695280d971b0fea37198122d2e5867516da0464736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001001": { - "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b50600436106102275760003560e01c8063831d65d111610130578063c80d4b8f116100b8578063e1c7392a1161007c578063e1c7392a146106d9578063f9a2bbc7146106e1578063fc3e5908146106e9578063fc4333cd146106f1578063fd6a6879146106f957610227565b8063c80d4b8f14610623578063c81b16621461062b578063c8509d8114610633578063c96be4cb146106ab578063dc927faf146106d157610227565b8063a1a11bf5116100ff578063a1a11bf514610531578063a78abc1614610539578063ab51bb9614610555578063ac0af6291461055d578063ac4317511461056557610227565b8063831d65d11461049f57806396713da9146105195780639bc8e4f2146105215780639dc092621461052957610227565b80634bf6c882116101b35780636e47b482116101825780636e47b4821461047757806370fd5bad1461047f57806375d47a0a146104875780637912a65d1461048f5780637942fd051461049757610227565b80634bf6c8821461045757806351e806721461045f578063567a372d1461046757806362b72cf51461046f57610227565b806337c8dab9116101fa57806337c8dab9146103b9578063389f4f71146103f85780633dffc3871461041257806343756e5c14610430578063493279b11461043857610227565b80630bee7a671461022c5780631182b8751461024d57806323bac5a21461033a57806335aa2e4414610380575b600080fd5b610234610701565b6040805163ffffffff9092168252519081900360200190f35b6102c56004803603604081101561026357600080fd5b60ff8235169190810190604081016020820135600160201b81111561028757600080fd5b82018360208201111561029957600080fd5b803590602001918460018302840111600160201b831117156102ba57600080fd5b509092509050610706565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102ff5781810151838201526020016102e7565b50505050905090810190601f16801561032c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103606004803603602081101561035057600080fd5b50356001600160a01b03166107da565b604080519384526020840192909252151582820152519081900360600190f35b61039d6004803603602081101561039657600080fd5b50356107fd565b604080516001600160a01b039092168252519081900360200190f35b6103df600480360360208110156103cf57600080fd5b50356001600160a01b0316610824565b6040805192835260208301919091528051918290030190f35b61040061087b565b60408051918252519081900360200190f35b61041a610881565b6040805160ff9092168252519081900360200190f35b61039d610886565b61044061088c565b6040805161ffff9092168252519081900360200190f35b61041a610891565b61039d610896565b61040061089c565b6104006108a2565b61039d6108a8565b61041a6108ae565b61039d6108b3565b6104006108b9565b61041a6108be565b610517600480360360408110156104b557600080fd5b60ff8235169190810190604081016020820135600160201b8111156104d957600080fd5b8201836020820111156104eb57600080fd5b803590602001918460018302840111600160201b8311171561050c57600080fd5b5090925090506108c3565b005b61041a610a1e565b610400610a23565b61039d610a2e565b61039d610a34565b610541610a3a565b604080519115158252519081900360200190f35b610234610a43565b610400610a48565b6105176004803603604081101561057b57600080fd5b810190602081018135600160201b81111561059557600080fd5b8201836020820111156105a757600080fd5b803590602001918460018302840111600160201b831117156105c857600080fd5b919390929091602081019035600160201b8111156105e557600080fd5b8201836020820111156105f757600080fd5b803590602001918460018302840111600160201b8311171561061857600080fd5b509092509050610a4d565b610400610e3b565b61039d610e40565b6105176004803603604081101561064957600080fd5b60ff8235169190810190604081016020820135600160201b81111561066d57600080fd5b82018360208201111561067f57600080fd5b803590602001918460018302840111600160201b831117156106a057600080fd5b509092509050610e46565b610517600480360360208110156106c157600080fd5b50356001600160a01b0316610ef9565b61039d61131e565b610517611324565b61039d611395565b61041a61139b565b6105176113a0565b61039d61182b565b606481565b606033612000146107485760405162461bcd60e51b815260040180806020018281038252602f815260200180612282602f913960400191505060405180910390fd5b60005460ff1661078d576040805162461bcd60e51b815260206004820152601960248201526000805160206122de833981519152604482015290519081900360640190fd5b6040805162461bcd60e51b815260206004820152601e60248201527f7265636569766520756e65787065637465642073796e207061636b6167650000604482015290519081900360640190fd5b600260208190526000918252604090912080546001820154919092015460ff1683565b6001818154811061080a57fe5b6000918252602090912001546001600160a01b0316905081565b60008061082f612146565b5050506001600160a01b0316600090815260026020818152604092839020835160608101855281548082526001830154938201849052919093015460ff16151592909301919091529091565b60055481565b600181565b61100181565b603881565b600881565b61200081565b60045481565b60035481565b61100581565b600281565b61100881565b603281565b600b81565b33612000146109035760405162461bcd60e51b815260040180806020018281038252602f815260200180612282602f913960400191505060405180910390fd5b60005460ff16610948576040805162461bcd60e51b815260206004820152601960248201526000805160206122de833981519152604482015290519081900360640190fd5b610950612169565b600061099184848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061183192505050565b9150915080156109db5781516040805163ffffffff9092168252517f7f0956d47419b9525356e7111652b653b530ec6f5096dccc04589bc38e6299679181900360200190a1610a17565b81516040805163ffffffff9092168252517f7d45f62d17443dd4547bca8a8112c60e2385669318dc300ec61a5d2492f262e79181900360200190a15b5050505050565b600981565b662386f26fc1000081565b61100781565b61100681565b60005460ff1681565b600081565b600481565b60005460ff16610a92576040805162461bcd60e51b815260206004820152601960248201526000805160206122de833981519152604482015290519081900360640190fd5b3361100714610ad25760405162461bcd60e51b815260040180806020018281038252602e81526020018061220d602e913960400191505060405180910390fd5b610b3d84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260148152731b5a5cd9195b59585b9bdc951a1c995cda1bdb1960621b602082015291506118b19050565b15610c165760208114610b815760405162461bcd60e51b81526004018080602001828103825260278152602001806121b66027913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610bbf9185858083850183828082843760009201919091525061199992505050565b905060018110158015610bd3575060055481105b610c0e5760405162461bcd60e51b815260040180806020018281038252602581526020018061225d6025913960400191505060405180910390fd5b600455610da9565b610c7c84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e19995b1bdb9e551a1c995cda1bdb19608a1b602082015291506118b19050565b15610d6c5760208114610cc05760405162461bcd60e51b815260040180806020018281038252602281526020018061223b6022913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610cfe9185858083850183828082843760009201919091525061199992505050565b90506103e88111158015610d13575060045481115b610d64576040805162461bcd60e51b815260206004820181905260248201527f7468652066656c6f6e795468726573686f6c64206f7574206f662072616e6765604482015290519081900360640190fd5b600555610da9565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b609681565b61100281565b3361200014610e865760405162461bcd60e51b815260040180806020018281038252602f815260200180612282602f913960400191505060405180910390fd5b60005460ff16610ecb576040805162461bcd60e51b815260206004820152601960248201526000805160206122de833981519152604482015290519081900360640190fd5b6040517f07db600eebe2ac176be8dcebad61858c245a4961bb32ca2aa3d159b09aa0810e90600090a1505050565b334114610f375760405162461bcd60e51b815260040180806020018281038252602d8152602001806122b1602d913960400191505060405180910390fd5b60005460ff16610f7c576040805162461bcd60e51b815260206004820152601960248201526000805160206122de833981519152604482015290519081900360640190fd5b6003544311610fd2576040805162461bcd60e51b815260206004820181905260248201527f63616e206e6f7420736c61736820747769636520696e206f6e6520626c6f636b604482015290519081900360640190fd5b3a1561101c576040805162461bcd60e51b81526020600482015260146024820152736761737072696365206973206e6f74207a65726f60601b604482015290519081900360640190fd5b611024612146565b506001600160a01b0381166000908152600260208181526040928390208351606081018552815481526001820154928101929092529091015460ff16158015928201929092529061107f5760208101805160010190526110d8565b60016040820181905260208201819052805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0384161790555b4381526005546020820151816110ea57fe5b0661123c57600060208201819052604080516335409f7f60e01b81526001600160a01b03851660048201529051611000926335409f7f926024808201939182900301818387803b15801561113d57600080fd5b505af1158015611151573d6000803e3d6000fd5b505050506120006001600160a01b031663f7a251d7600b6111718561199e565b60006040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156111d15781810151838201526020016111b9565b50505050905090810190601f1680156111fe5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561121f57600080fd5b505af1158015611233573d6000803e3d6000fd5b505050506112b2565b60045481602001518161124b57fe5b066112b257604080516375abf10160e11b81526001600160a01b038416600482015290516110009163eb57e20291602480830192600092919082900301818387803b15801561129957600080fd5b505af11580156112ad573d6000803e3d6000fd5b505050505b6001600160a01b0382166000818152600260208181526040808420865181559186015160018301558581015191909201805460ff1916911515919091179055517fddb6012116e51abf5436d956a4f0ebd927e92c576ff96d7918290c8782291e3e9190a2505043600355565b61100381565b60005460ff161561137c576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b603260045560966005556000805460ff19166001179055565b61100081565b600381565b33611000146113e05760405162461bcd60e51b81526004018080602001828103825260308152602001806121dd6030913960400191505060405180910390fd5b60005460ff16611425576040805162461bcd60e51b815260206004820152601960248201526000805160206122de833981519152604482015290519081900360640190fd5b60015461143157611829565b600154600090600019015b8082116117fd576000805b8284101561156057611457612146565b600260006001878154811061146857fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff16151590820152600554909150600490048160200151111561154a576004600554816114d557fe5b048160200151038160200181815250508060026000600188815481106114f757fe5b6000918252602080832091909101546001600160a01b0316835282810193909352604091820190208351815591830151600183015591909101516002909101805460ff1916911515919091179055611554565b6001925050611560565b50600190930192611447565b8284116116f75761156f612146565b600260006001868154811061158057fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff161515908201526005549091506004900481602001511115611668576004600554816115ed57fe5b0481602001510381602001818152505080600260006001878154811061160f57fe5b6000918252602080832091909101546001600160a01b03168352828101939093526040918201902083518155918301516001808401919091559201516002909101805460ff191691151591909117905591506116f79050565b600260006001868154811061167957fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff191690558054806116bd57fe5b600082815260209020810160001990810180546001600160a01b0319169055019055836116ea57506116f7565b5060001990920191611560565b8180156117015750805b156117e057600260006001868154811061171757fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff1916905580548490811061175e57fe5b600091825260209091200154600180546001600160a01b03909216918690811061178457fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060018054806117bd57fe5b600082815260209020810160001990810180546001600160a01b03191690550190555b826117ec5750506117fd565b50506001909101906000190161143c565b6040517fcfdb3b6ccaeccbdc68be3c59c840e3b3c90f0a7c491f5fff1cf56cfda200dd9c90600090a150505b565b61100481565b611839612169565b6000611843612169565b61184b61217b565b61185c61185786611a70565b611a95565b90506000805b61186b83611adf565b156118a457806118975761188661188184611b00565b611b4e565b63ffffffff1684526001915061189c565b6118a4565b600101611862565b5091935090915050915091565b6000816040516020018082805190602001908083835b602083106118e65780518252601f1990920191602091820191016118c7565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106119545780518252601f199092019160209182019101611935565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490505b92915050565b015190565b60408051600480825260a08201909252606091829190816020015b60608152602001906001900390816119b95790505090506119e2836001600160a01b0316611c05565b816000815181106119ef57fe5b6020026020010181905250611a0343611c28565b81600181518110611a1057fe5b6020908102919091010152611a256038611c28565b81600281518110611a3257fe5b6020026020010181905250611a4642611c28565b81600381518110611a5357fe5b6020026020010181905250611a6781611c3b565b9150505b919050565b611a7861219b565b506040805180820190915281518152602082810190820152919050565b611a9d61217b565b611aa682611cc5565b611aaf57600080fd5b6000611abe8360200151611cff565b60208085015160408051808201909152868152920190820152915050919050565b6000611ae961219b565b505080518051602091820151919092015191011190565b611b0861219b565b611b1182611adf565b611b1a57600080fd5b60208201516000611b2a82611d62565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590611b6357508151602110155b611b6c57600080fd5b6000611b7b8360200151611cff565b90508083600001511015611bd6576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b825160208085015183018051928490039291831015611bfc57826020036101000a820491505b50949350505050565b60408051600560a21b8318601482015260348101909152606090611a6781611e95565b6060611993611c3683611eeb565b611e95565b6060815160001415611c5c5750604080516000815260208101909152611a6b565b606082600081518110611c6b57fe5b602002602001015190506000600190505b8351811015611cac57611ca282858381518110611c9557fe5b6020026020010151611fd1565b9150600101611c7c565b50611a67611cbf825160c060ff1661204e565b82611fd1565b8051600090611cd657506000611a6b565b6020820151805160001a9060c0821015611cf557600092505050611a6b565b5060019392505050565b8051600090811a6080811015611d19576000915050611a6b565b60b8811080611d34575060c08110801590611d34575060f881105b15611d43576001915050611a6b565b60c0811015611d575760b519019050611a6b565b60f519019050611a6b565b80516000908190811a6080811015611d7d5760019150611e8e565b60b8811015611d9257607e1981019150611e8e565b60c0811015611e0c57600060b78203600186019550806020036101000a865104915060018101820193505080831015611e06576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b50611e8e565b60f8811015611e215760be1981019150611e8e565b600060f78203600186019550806020036101000a865104915060018101820193505080831015611e8c576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b606081516001148015611ec75750607f60f81b82600081518110611eb557fe5b01602001516001600160f81b03191611155b15611ed3575080611a6b565b611993611ee58351608060ff1661204e565b83611fd1565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416611f2f57506018611f53565b6fffffffffffffffffffffffffffffffff198416611f4f57506010611f53565b5060005b6020811015611f8957818181518110611f6857fe5b01602001516001600160f81b03191615611f8157611f89565b600101611f53565b60008160200390506060816040519080825280601f01601f191660200182016040528015611fbe576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b81831015612002578051835260209283019201611fea565b50855184518101855292509050808201602086015b8183101561202f578051835260209283019201612017565b508651929092011591909101601f01601f191660405250905092915050565b606068010000000000000000831061209e576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b604080516001808252818301909252606091602082018180368337019050509050603784116120f85782840160f81b816000815181106120da57fe5b60200101906001600160f81b031916908160001a9053509050611993565b606061210385611eeb565b90508381510160370160f81b8260008151811061211c57fe5b60200101906001600160f81b031916908160001a90535061213d8282611fd1565b95945050505050565b604051806060016040528060008152602001600081526020016000151581525090565b60408051602081019091526000815290565b604051806040016040528061218e61219b565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe6c656e677468206f66206d697364656d65616e6f725468726573686f6c64206d69736d61746368746865206d6573736167652073656e646572206d7573742062652076616c696461746f7253657420636f6e7472616374746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662066656c6f6e795468726573686f6c64206d69736d61746368746865206d697364656d65616e6f725468726573686f6c64206f7574206f662072616e6765746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d6573736167652073656e646572206d7573742062652074686520626c6f636b2070726f647563657274686520636f6e7472616374206e6f7420696e69742079657400000000000000a2646970667358221220978db7b9b4e7fb0a1f9436afd2b57418fb3ba1969a491794d2da96ee68de87d064736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001002": { - "balance": "0x0", - "code": "0x60806040526004361061014f5760003560e01c806396713da9116100b6578063c81b16621161006f578063c81b1662146103dc578063dc927faf146103f1578063f9a2bbc714610406578063fb5478b31461041b578063fc3e590814610430578063fd6a68791461044557610193565b806396713da91461033a5780639a99b4f01461034f5780639dc0926214610388578063a1a11bf51461039d578063a78abc16146103b2578063ab51bb96146103c757610193565b806351e806721161010857806351e806721461028a5780636d70f7ae1461029f5780636e47b482146102e657806370fd5bad146102fb57806375d47a0a146103105780637942fd051461032557610193565b80630bee7a67146101985780633a0b0eff146101c65780633dffc387146101ed57806343756e5c14610218578063493279b1146102495780634bf6c8821461027557610193565b366101935734156101915760408051348152905133917f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db919081900360200190a25b005b600080fd5b3480156101a457600080fd5b506101ad61045a565b6040805163ffffffff9092168252519081900360200190f35b3480156101d257600080fd5b506101db61045f565b60408051918252519081900360200190f35b3480156101f957600080fd5b50610202610465565b6040805160ff9092168252519081900360200190f35b34801561022457600080fd5b5061022d61046a565b604080516001600160a01b039092168252519081900360200190f35b34801561025557600080fd5b5061025e610470565b6040805161ffff9092168252519081900360200190f35b34801561028157600080fd5b50610202610475565b34801561029657600080fd5b5061022d61047a565b3480156102ab57600080fd5b506102d2600480360360208110156102c257600080fd5b50356001600160a01b0316610480565b604080519115158252519081900360200190f35b3480156102f257600080fd5b5061022d61049e565b34801561030757600080fd5b506102026104a4565b34801561031c57600080fd5b5061022d6104a9565b34801561033157600080fd5b506102026104af565b34801561034657600080fd5b506102026104b4565b34801561035b57600080fd5b506101db6004803603604081101561037257600080fd5b506001600160a01b0381351690602001356104b9565b34801561039457600080fd5b5061022d610664565b3480156103a957600080fd5b5061022d61066a565b3480156103be57600080fd5b506102d2610670565b3480156103d357600080fd5b506101ad610679565b3480156103e857600080fd5b5061022d61067e565b3480156103fd57600080fd5b5061022d610684565b34801561041257600080fd5b5061022d61068a565b34801561042757600080fd5b506101db610690565b34801561043c57600080fd5b5061020261069c565b34801561045157600080fd5b5061022d6106a1565b606481565b60015481565b600181565b61100181565b603881565b600881565b61200081565b6001600160a01b031660009081526002602052604090205460ff1690565b61100581565b600281565b61100881565b600b81565b600981565b6000805460ff1661053657600260208190527fe57bda0a954a7c7381b17b2c763e646ba2c60f67292d287ba583603e2c1c41668054600160ff19918216811790925561100560009081527fe25235fc0de9d7165652bef0846fefda506174abb9a190f03d0f7bcc6146dbce80548316841790559282558254161790555b3360009081526002602052604090205460ff166105845760405162461bcd60e51b815260040180806020018281038252602b8152602001806106a8602b913960400191505060405180910390fd5b60004783106105935747610595565b825b9050670de0b6b3a76400008111156105b25750670de0b6b3a76400005b8015610633576040516001600160a01b0385169082156108fc029083906000818181858888f193505050501580156105ee573d6000803e3d6000fd5b506040805182815290516001600160a01b038616917ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0919081900360200190a261065d565b6040517fe589651933c2457488cc0d8e0941518abf748e799435e4e396d9c4d0b2db2d4d90600090a15b9392505050565b61100781565b61100681565b60005460ff1681565b600081565b61100281565b61100381565b61100081565b670de0b6b3a764000081565b600381565b6110048156fe6f6e6c79206f70657261746f7220697320616c6c6f77656420746f2063616c6c20746865206d6574686f64a2646970667358221220c09e2c37549a0aef291c4f977743d3cea839c669624a8cfae895b3979a32800764736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001003": { - "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b50600436106102115760003560e01c8063a78abc1611610125578063dda83148116100ad578063e405bbc31161007c578063e405bbc314610681578063ea54b2aa14610689578063f9a2bbc714610691578063fc3e590814610699578063fd6a6879146106a157610211565b8063dda8314814610609578063df5fe7041461062f578063e1c7392a14610655578063e2761af01461065d57610211565b8063c81b1662116100f4578063c81b166214610534578063cba510a91461053c578063d816987914610562578063da8d08f0146105db578063dc927faf1461060157610211565b8063a78abc1614610444578063ab51bb9614610460578063ac43175114610468578063adc879e91461052c57610211565b8063564b81ef116101a857806375d47a0a1161017757806375d47a0a1461041c5780637942fd051461042457806396713da91461042c5780639dc0926214610434578063a1a11bf51461043c57610211565b8063564b81ef146102ca5780635c5ae8db146103475780636e47b4821461040c57806370fd5bad1461041457610211565b806343756e5c116101e457806343756e5c14610277578063493279b11461029b5780634bf6c882146102ba57806351e80672146102c257610211565b80630bee7a67146102165780632657e9b61461023757806333f7798d146102515780633dffc38714610259575b600080fd5b61021e6106a9565b6040805163ffffffff9092168252519081900360200190f35b61023f6106ae565b60408051918252519081900360200190f35b61023f6106b9565b6102616106bf565b6040805160ff9092168252519081900360200190f35b61027f6106c4565b604080516001600160a01b039092168252519081900360200190f35b6102a36106ca565b6040805161ffff9092168252519081900360200190f35b6102616106cf565b61027f6106d4565b6102d26106da565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561030c5781810151838201526020016102f4565b50505050905090810190601f1680156103395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61036d6004803603602081101561035d57600080fd5b50356001600160401b03166107e6565b60405180856001600160401b03166001600160401b0316815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156103ce5781810151838201526020016103b6565b50505050905090810190601f1680156103fb5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b61027f6108a1565b6102616108a7565b61027f6108ac565b6102616108b2565b6102616108b7565b61027f6108bc565b61027f6108c2565b61044c6108c8565b604080519115158252519081900360200190f35b61021e6108d1565b61052a6004803603604081101561047e57600080fd5b81019060208101813564010000000081111561049957600080fd5b8201836020820111156104ab57600080fd5b803590602001918460018302840111640100000000831117156104cd57600080fd5b9193909290916020810190356401000000008111156104eb57600080fd5b8201836020820111156104fd57600080fd5b8035906020019184600183028401116401000000008311171561051f57600080fd5b5090925090506108d6565b005b61023f610b8f565b61027f610b95565b61023f6004803603602081101561055257600080fd5b50356001600160401b0316610b9b565b61044c6004803603604081101561057857600080fd5b81019060208101813564010000000081111561059357600080fd5b8201836020820111156105a557600080fd5b803590602001918460018302840111640100000000831117156105c757600080fd5b9193509150356001600160401b0316610bba565b61027f600480360360208110156105f157600080fd5b50356001600160401b031661139b565b61027f6113b6565b61027f6004803603602081101561061f57600080fd5b50356001600160401b03166113bc565b61044c6004803603602081101561064557600080fd5b50356001600160401b03166113e0565b61052a611422565b6106656115c9565b604080516001600160401b039092168252519081900360200190f35b6106656115d8565b6102d26115ee565b61027f61160d565b610261611613565b61027f611618565b606481565b662386f26fc1000081565b60055481565b600181565b61100181565b603881565b600881565b61200081565b604080516020808252818301909252606091829190602082018180368337505060045460208301525090506000805b60208160ff16101561075057828160ff168151811061072457fe5b01602001516001600160f81b0319161561074357600190910190610748565b610750565b600101610709565b5060608160ff166040519080825280601f01601f191660200182016040528015610781576020820181803683370190505b50905060005b8260ff168160ff1610156107dd57838160ff16815181106107a457fe5b602001015160f81c60f81b828260ff16815181106107be57fe5b60200101906001600160f81b031916908160001a905350600101610787565b50925050505b90565b60016020818152600092835260409283902080548184015460028084015460038501805489516101009982161599909902600019011692909204601f81018790048702880187019098528787526001600160401b0390931696919592949091908301828280156108975780601f1061086c57610100808354040283529160200191610897565b820191906000526020600020905b81548152906001019060200180831161087a57829003601f168201915b5050505050905084565b61100581565b600281565b61100881565b600b81565b600981565b61100781565b61100681565b60005460ff1681565b600081565b60005460ff1661092d576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604482015290519081900360640190fd5b336110071461096d5760405162461bcd60e51b815260040180806020018281038252602e8152602001806119ea602e913960400191505060405180910390fd5b6109e184848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601b81527f726577617264466f7256616c696461746f725365744368616e676500000000006020820152915061161e9050565b15610ac05760208114610a255760405162461bcd60e51b815260040180806020018281038252602e815260200180611989602e913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610a639185858083850183828082843760009201919091525061170592505050565b9050600081118015610a7d5750670de0b6b3a76400008111155b610ab85760405162461bcd60e51b815260040180806020018281038252602f815260200180611a18602f913960400191505060405180910390fd5b600555610afd565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b60045481565b61100281565b6001600160401b03166000908152600160208190526040909120015490565b60408051630a83aaa960e31b815233600482015290516000916110069163541d554891602480820192602092909190829003018186803b158015610bfd57600080fd5b505afa158015610c11573d6000803e3d6000fd5b505050506040513d6020811015610c2757600080fd5b5051610c7a576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b6001600160401b0382166000908152600260205260409020546001600160a01b031615610cee576040805162461bcd60e51b815260206004820152601c60248201527f63616e27742073796e63206475706c6963617465642068656164657200000000604482015290519081900360640190fd5b6003546001600160401b0390811690831611610d3b5760405162461bcd60e51b8152600401808060200182810382526026815260200180611a476026913960400191505060405180910390fd5b600354600160401b90046001600160401b0316610d56611867565b6001600160401b0382811660009081526001602081815260409283902083516080810185528154909516855280830154858301526002808201548686015260038201805486516101009682161596909602600019011691909104601f81018490048402850184019095528484529093606086019392830182828015610e1c5780601f10610df157610100808354040283529160200191610e1c565b820191906000526020600020905b815481529060010190602001808311610dff57829003601f168201915b50505050508152505090505b836001600160401b0316826001600160401b031610158015610e5957506003546001600160401b0390811690831610155b15610f3a5780516001600160401b0380821660009081526001602081815260409283902083516080810185528154909516855280830154858301526002808201548686015260038201805486516101009682161596909602600019011691909104601f8101849004840285018401909552848452959750939460608601939091830182828015610f2a5780601f10610eff57610100808354040283529160200191610f2a565b820191906000526020600020905b815481529060010190602001808311610f0d57829003601f168201915b5050505050815250509050610e28565b6060810151516110315780516001600160401b03811660009081526001602081815260409283902060030180548451600294821615610100026000190190911693909304601f810183900483028401830190945283835293955090929190830182828015610fe95780601f10610fbe57610100808354040283529160200191610fe9565b820191906000526020600020905b815481529060010190602001808311610fcc57829003601f168201915b505050506060830182905250516110315760405162461bcd60e51b81526004018080602001828103825260218152602001806119686021913960400191505060405180910390fd5b6000816060015151608801905060608787905082016040519080825280601f01601f191660200182016040528015611070576020820181803683370190505b509050600061107e8261170a565b905061108c84868386611710565b6110c75760405162461bcd60e51b81526004018080602001828103825260238152602001806119456023913960400191505060405180910390fd5b6000838201915061110d8a8a8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061177c92505050565b9450905061111c818386611786565b8251602001935061112b61188d565b6110008186866064600019fa61114057600080fd5b805194506000600160f81b8616156111cf5750600554604080516309a99b4f60e41b815233600482015260248101929092525160019161100291639a99b4f0916044808201926020929091908290030181600087803b1580156111a257600080fd5b505af11580156111b6573d6000803e3d6000fd5b505050506040513d60208110156111cc57600080fd5b50505b856001600160401b0316955060208201935060006111ef858884156117c7565b90985090506001600160401b03808216908c161461123e5760405162461bcd60e51b81526004018080602001828103825260338152602001806119b76033913960400191505060405180910390fd5b6001600160401b03808c16600081815260026020818152604080842080546001600160a01b031916331790558e86168e529383526001808252928490208d518154961667ffffffffffffffff199096169590951785558c81015192850192909255918b01519183019190915560608a015180518b93926112c59260038501929101906118ac565b50506003546001600160401b03600160401b9091048116908d161115905061130d576003805467ffffffffffffffff60401b1916600160401b6001600160401b038e16021790555b7f4042c1020a8f410fb1c8859d276ab436aeb2c3074960e48467299cf1c966d3b48b8a8a602001518560405180856001600160401b03166001600160401b03168152602001846001600160401b03166001600160401b031681526020018381526020018215151515815260200194505050505060405180910390a15060019c9b505050505050505050505050565b6002602052600090815260409020546001600160a01b031681565b61100381565b6001600160401b03166000908152600260205260409020546001600160a01b031690565b6001600160401b0381166000908152600260205260408120546001600160a01b031615158061141c57506003546001600160401b038381169116145b92915050565b60005460ff161561147a576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b6000806114a16040518061024001604052806102208152602001611a6d610220913961177c565b815160045590925090506114b3611867565b60006114c1848460006117c7565b60008083526001600160401b038281168252600160208181526040938490208651815467ffffffffffffffff191694169390931783558086015191830191909155918401516002820155606084015180519496509294508593909261152d9260038501929101906118ac565b50506003805467ffffffffffffffff19166001600160401b0384811691821767ffffffffffffffff60401b1916600160401b9290920291909117918290556000805460ff19166001179055662386f26fc10000600555602085810151604080519490931684529083015280517f5ac9b37d571677b80957ca05693f371526c602fd08042b416a29fdab7efefa499350918290030190a150505050565b6003546001600160401b031681565b600354600160401b90046001600160401b031681565b6040518061024001604052806102208152602001611a6d610220913981565b61100081565b600381565b61100481565b6000816040516020018082805190602001908083835b602083106116535780518252601f199092019160209182019101611634565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106116c15780518252601f1990920191602091820191016116a2565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b60200190565b600084606001515182840103925060008061172e876060015161177c565b909250905061173e828683611786565b5050506040840151601f1983810191909152602090940151603f19830152605f19820192909252600454606719820152910160871990910152600190565b8051602090910191565b5b602081106117a6578251825260209283019290910190601f1901611787565b915181516020939093036101000a6000190180199091169216919091179052565b6117cf611867565b60088401516028850151604890950180519095600092916117ee611867565b6020810183905260408101829052866118595760008060688a036040519080825280601f01601f191660200182016040528015611832576020820181803683370190505b50606084018190526118439061177c565b909250905061185660208c018383611786565b50505b989297509195505050505050565b604080516080810182526000808252602082018190529181019190915260608082015290565b6040518061100001604052806080906020820280368337509192915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106118ed57805160ff191683800117855561191a565b8280016001018555821561191a579182015b8281111561191a5782518255916020019190600101906118ff565b5061192692915061192a565b5090565b6107e391905b80821115611926576000815560010161193056fe6661696c656420746f2073657269616c697a6520636f6e73656e7375732073746174656661696c656420746f206c6f61642076616c696461746f722073657420646174616c656e677468206f6620726577617264466f7256616c696461746f725365744368616e6765206d69736d617463686865616465722068656967687420646f65736e277420657175616c20746f207468652073706563696669656420686569676874746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374746865206e6577526577617264466f7256616c696461746f725365744368616e6765206f7574206f662072616e676563616e27742073796e6320686561646572206265666f726520696e697469616c48656967687442696e616e63652d436861696e2d5469677269730000000000000000000000000000000006915167cedaf7bbf7df47d932fdda630527ee648562cf3e52c5e5f46156a3a971a4ceb443c53a50d8653ef8cf1e5716da68120fb51b636dc6d111ec3277b098ecd42d49d3769d8a1f78b4c17a965f7a30d4181fabbd1f969f46d3c8e83b5ad4845421d8000000e8d4a510002ba4e81542f437b7ae1f8a35ddb233c789a8dc22734377d9b6d63af1ca403b61000000e8d4a51000df8da8c5abfdb38595391308bb71e5a1e0aabdc1d0cf38315d50d6be939b2606000000e8d4a51000b6619edca4143484800281d698b70c935e9152ad57b31d85c05f2f79f64b39f3000000e8d4a510009446d14ad86c8d2d74780b0847110001a1c2e252eedfea4753ebbbfce3a22f52000000e8d4a510000353c639f80cc8015944436dab1032245d44f912edc31ef668ff9f4a45cd0599000000e8d4a51000e81d3797e0544c3a718e1f05f0fb782212e248e784c1a851be87e77ae0db230e000000e8d4a510005e3fcda30bd19d45c4b73688da35e7da1fce7c6859b2c1f20ed5202d24144e3e000000e8d4a51000b06a59a2d75bf5d014fce7c999b5e71e7a960870f725847d4ba3235baeaa08ef000000e8d4a510000c910e2fe650e4e01406b3310b489fb60a84bc3ff5c5bee3a56d5898b6a8af32000000e8d4a5100071f2d7b8ec1c8b99a653429b0118cd201f794f409d0fea4d65b1b662f2b00063000000e8d4a51000a264697066735822122032fc162aed7c2a4fe0f40397d327efc38d8aaf5dbdd1720f7f5d8101877da61d64736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001004": { - "balance": "176405560900000000000000000", - "code": "0x60806040526004361061031e5760003560e01c80639a99b4f0116101ab578063bd466461116100f7578063f014847211610095578063fc1a598f1161006f578063fc1a598f14610cb3578063fc3e590814610686578063fd6a687914610ce6578063ff9c0027146107dc57610366565b8063f014847214610c74578063f9a2bbc714610c89578063fa9e915914610c9e57610366565b8063d9e6dae9116100d1578063d9e6dae914610608578063dc927faf14610c35578063e1c7392a14610c4a578063ebf71d5314610c5f57610366565b8063bd46646114610b68578063c81b166214610b9b578063c8509d8114610bb057610366565b8063aa7415f511610164578063b99328c51161013e578063b99328c514610ad2578063b9fd21e314610b0b578063ba35ead614610b20578063bbface1f14610b3557610366565b8063aa7415f5146109ab578063ab51bb96146109f2578063ac43175114610a0757610366565b80639a99b4f01461091e5780639dc0926214610957578063a1a11bf51461096c578063a496fba214610981578063a78abc1614610996578063a7c9f02d1461068657610366565b8063613684751161026a57806375d47a0a116102235780638b87b21f116101fd5780638b87b21f146105875780638eff336c146108b557806396713da9146108f45780639a854bbd1461090957610366565b806375d47a0a146108065780637942fd051461081b578063831d65d11461083057610366565b8063613684751461060857806366dea52a146106865780636e0565201461069b5780636e47b482146107c757806370fd5bad146107dc57806371d30863146107f157610366565b806343a368b9116102d757806350432d32116102b157806350432d321461061d57806351e806721461063257806359b92789146106475780635d499b1b1461067157610366565b806343a368b9146105c7578063493279b1146105dc5780634bf6c8821461060857610366565b80630bee7a671461036b5780631182b87514610399578063149d14d9146104935780633d713223146104ba5780633dffc3871461058757806343756e5c146105b257610366565b36610366573415610364576040805133815234602082015281517f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db929181900390910190a15b005b600080fd5b34801561037757600080fd5b50610380610cfb565b6040805163ffffffff9092168252519081900360200190f35b3480156103a557600080fd5b5061041e600480360360408110156103bc57600080fd5b60ff8235169190810190604081016020820135600160201b8111156103e057600080fd5b8201836020820111156103f257600080fd5b803590602001918460018302840111600160201b8311171561041357600080fd5b509092509050610d00565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610458578181015183820152602001610440565b50505050905090810190601f1680156104855780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561049f57600080fd5b506104a8610e2e565b60408051918252519081900360200190f35b3480156104c657600080fd5b5061056b600480360360208110156104dd57600080fd5b810190602081018135600160201b8111156104f757600080fd5b82018360208201111561050957600080fd5b803590602001918460018302840111600160201b8311171561052a57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610e34945050505050565b604080516001600160a01b039092168252519081900360200190f35b34801561059357600080fd5b5061059c610e58565b6040805160ff9092168252519081900360200190f35b3480156105be57600080fd5b5061056b610e5d565b3480156105d357600080fd5b506104a8610e63565b3480156105e857600080fd5b506105f1610e6f565b6040805161ffff9092168252519081900360200190f35b34801561061457600080fd5b5061059c610e74565b34801561062957600080fd5b506104a8610e79565b34801561063e57600080fd5b5061056b610e84565b34801561065357600080fd5b5061056b6004803603602081101561066a57600080fd5b5035610e8a565b34801561067d57600080fd5b506104a8610ea5565b34801561069257600080fd5b5061059c610eae565b6107b3600480360360808110156106b157600080fd5b810190602081018135600160201b8111156106cb57600080fd5b8201836020820111156106dd57600080fd5b803590602001918460208302840111600160201b831117156106fe57600080fd5b919390929091602081019035600160201b81111561071b57600080fd5b82018360208201111561072d57600080fd5b803590602001918460208302840111600160201b8311171561074e57600080fd5b919390929091602081019035600160201b81111561076b57600080fd5b82018360208201111561077d57600080fd5b803590602001918460208302840111600160201b8311171561079e57600080fd5b91935091503567ffffffffffffffff16610eb3565b604080519115158252519081900360200190f35b3480156107d357600080fd5b5061056b611388565b3480156107e857600080fd5b5061059c61138e565b3480156107fd57600080fd5b506104a8611393565b34801561081257600080fd5b5061056b611399565b34801561082757600080fd5b5061059c61139f565b34801561083c57600080fd5b506103646004803603604081101561085357600080fd5b60ff8235169190810190604081016020820135600160201b81111561087757600080fd5b82018360208201111561088957600080fd5b803590602001918460018302840111600160201b831117156108aa57600080fd5b5090925090506113a4565b3480156108c157600080fd5b50610364600480360360608110156108d857600080fd5b508035906001600160a01b0360208201351690604001356114ed565b34801561090057600080fd5b5061059c611573565b34801561091557600080fd5b506104a8611578565b34801561092a57600080fd5b506104a86004803603604081101561094157600080fd5b506001600160a01b038135169060200135611584565b34801561096357600080fd5b5061056b6116c2565b34801561097857600080fd5b5061056b6116c8565b34801561098d57600080fd5b5061059c6116ce565b3480156109a257600080fd5b506107b36116d3565b6107b3600480360360808110156109c157600080fd5b5080356001600160a01b03908116916020810135909116906040810135906060013567ffffffffffffffff166116dc565b3480156109fe57600080fd5b506103806116ce565b348015610a1357600080fd5b5061036460048036036040811015610a2a57600080fd5b810190602081018135600160201b811115610a4457600080fd5b820183602082011115610a5657600080fd5b803590602001918460018302840111600160201b83111715610a7757600080fd5b919390929091602081019035600160201b811115610a9457600080fd5b820183602082011115610aa657600080fd5b803590602001918460018302840111600160201b83111715610ac757600080fd5b509092509050611d9d565b348015610ade57600080fd5b5061036460048036036040811015610af557600080fd5b50803590602001356001600160a01b031661200c565b348015610b1757600080fd5b506104a8612082565b348015610b2c57600080fd5b506104a861208c565b348015610b4157600080fd5b506104a860048036036020811015610b5857600080fd5b50356001600160a01b0316612092565b348015610b7457600080fd5b506104a860048036036020811015610b8b57600080fd5b50356001600160a01b03166120a4565b348015610ba757600080fd5b5061056b6120bf565b348015610bbc57600080fd5b5061036460048036036040811015610bd357600080fd5b60ff8235169190810190604081016020820135600160201b811115610bf757600080fd5b820183602082011115610c0957600080fd5b803590602001918460018302840111600160201b83111715610c2a57600080fd5b5090925090506120c5565b348015610c4157600080fd5b5061056b612195565b348015610c5657600080fd5b5061036461219b565b348015610c6b57600080fd5b5061059c61223b565b348015610c8057600080fd5b5061059c612240565b348015610c9557600080fd5b5061056b612245565b348015610caa57600080fd5b506104a861224b565b348015610cbf57600080fd5b5061041e60048036036020811015610cd657600080fd5b50356001600160a01b0316612251565b348015610cf257600080fd5b5061056b612378565b606481565b60005460609060ff16610d48576040805162461bcd60e51b815260206004820152601960248201526000805160206147bf833981519152604482015290519081900360640190fd5b3361200014610d885760405162461bcd60e51b815260040180806020018281038252602f81526020018061476d602f913960400191505060405180910390fd5b60ff841660021415610dda57610dd383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061237e92505050565b9050610e27565b6040805162461bcd60e51b815260206004820152601860248201527f756e7265636f676e697a65642073796e207061636b6167650000000000000000604482015290519081900360640190fd5b9392505050565b60015490565b6020818101516000908152600490915260409020546001600160a01b03165b919050565b600181565b61100181565b670de0b6b3a764000081565b603881565b600881565b66071afd498d000081565b61200081565b6000908152600460205260409020546001600160a01b031690565b6402540be40081565b600381565b6000805460ff16610ef9576040805162461bcd60e51b815260206004820152601960248201526000805160206147bf833981519152604482015290519081900360640190fd5b868514610f375760405162461bcd60e51b815260040180806020018281038252603b815260200180614732603b913960400191505060405180910390fd5b868314610f755760405162461bcd60e51b815260040180806020018281038252603f815260200180614605603f913960400191505060405180910390fd5b426078018267ffffffffffffffff161015610fc15760405162461bcd60e51b81526004018080602001828103825260248152602001806144f56024913960400191505060405180910390fd5b6402540be4003406156110055760405162461bcd60e51b81526004018080602001828103825260408152602001806148356040913960400191505060405180910390fd5b60408051868152602080880282010190915285906000908190606090848015611038578160200160208202803683370190505b50905060005b84811015611113576402540be4008b8b8381811061105857fe5b905060200201358161106657fe5b06156110a35760405162461bcd60e51b815260040180806020018281038252603c815260200180614644603c913960400191505060405180910390fd5b6110c88b8b838181106110b257fe5b90506020020135856124a290919063ffffffff16565b93506110f46402540be4008c8c848181106110df57fe5b905060200201356124fc90919063ffffffff16565b82828151811061110057fe5b602090810291909101015260010161103e565b506001546111389061112b908663ffffffff61253e16565b849063ffffffff6124a216565b3410156111765760405162461bcd60e51b81526004018080602001828103825260568152602001806147df6056913960600191505060405180910390fd5b611186348463ffffffff61259716565b915061119061434e565b6040518060c001604052806221272160e91b60001b815260200160006001600160a01b031681526020018381526020018e8e808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050908252506040805160208c810282810182019093528c82529283019290918d918d91829185019084908082843760009201919091525050509082525067ffffffffffffffff8916602090910152905061200063f7a251d76003611254846125d9565b611269876402540be40063ffffffff6124fc16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156112c75781810151838201526020016112af565b50505050905090810190601f1680156112f45780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561131557600080fd5b505af1158015611329573d6000803e3d6000fd5b505060408051600081523360208201528082018890526060810187905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9350908190036080019150a15060019c9b505050505050505050505050565b61100581565b600281565b60015481565b61100881565b600b81565b60005460ff166113e9576040805162461bcd60e51b815260206004820152601960248201526000805160206147bf833981519152604482015290519081900360640190fd5b33612000146114295760405162461bcd60e51b815260040180806020018281038252602f81526020018061476d602f913960400191505060405180910390fd5b60ff8316600314156114795761147482828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061289492505050565b6114e8565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a15b505050565b336110081461152d5760405162461bcd60e51b815260040180806020018281038252602381526020018061479c6023913960400191505060405180910390fd5b600083815260046020908152604080832080546001600160a01b039096166001600160a01b03199096168617905593825260038152838220949094556002909352912055565b600981565b677ce66c50e284000081565b6000805460ff166115ca576040805162461bcd60e51b815260206004820152601960248201526000805160206147bf833981519152604482015290519081900360640190fd5b336110051461160a5760405162461bcd60e51b815260040180806020018281038252602f815260200180614468602f913960400191505060405180910390fd5b6000478310611619574761161b565b825b9050670de0b6b3a76400008111156116375760009150506116bc565b80156116b9576040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015611673573d6000803e3d6000fd5b50604080516001600160a01b03861681526020810183905281517ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0929181900390910190a15b90505b92915050565b61100781565b61100681565b600081565b60005460ff1681565b6000805460ff16611722576040805162461bcd60e51b815260206004820152601960248201526000805160206147bf833981519152604482015290519081900360640190fd5b426078018267ffffffffffffffff16101561176e5760405162461bcd60e51b81526004018080602001828103825260248152602001806144f56024913960400191505060405180910390fd5b6402540be4003406156117b25760405162461bcd60e51b81526004018080602001828103825260408152602001806148356040913960400191505060405180910390fd5b600080806001600160a01b038816611891576001546117d890879063ffffffff6124a216565b3410156118165760405162461bcd60e51b815260040180806020018281038252606181526020018061457f6061913960800191505060405180910390fd5b6402540be40086061561185a5760405162461bcd60e51b815260040180806020018281038252603c815260200180614644603c913960400191505060405180910390fd5b61186a348763ffffffff61259716565b9050611881866402540be40063ffffffff6124fc16565b6221272160e91b93509150611b34565b6001600160a01b0388166000908152600360205260409020549250826118e85760405162461bcd60e51b815260040180806020018281038252603181526020018061454e6031913960400191505060405180910390fd5b6001543410156119295760405162461bcd60e51b815260040180806020018281038252603f8152602001806146a1603f913960400191505060405180910390fd5b506001600160a01b038716600090815260026020526040902054349060088111158061197457506008811180156119745750611972876007198301600a0a63ffffffff6128f016565b155b6119af5760405162461bcd60e51b815260040180806020018281038252603c815260200180614644603c913960400191505060405180910390fd5b6119b98782612932565b92506119c484612972565b15611a0c576305f5e100831015611a0c5760405162461bcd60e51b815260040180806020018281038252603a815260200180614497603a913960400191505060405180910390fd5b600881101580611a265750600881108015611a2657508683115b611a615760405162461bcd60e51b81526004018080602001828103825260258152602001806145e06025913960400191505060405180910390fd5b677ce66c50e2840000831115611aa85760405162461bcd60e51b81526004018080602001828103825260358152602001806145196035913960400191505060405180910390fd5b604080516323b872dd60e01b81523360048201523060248201526044810189905290516001600160a01b038b16916323b872dd9160648083019260209291908290030181600087803b158015611afd57600080fd5b505af1158015611b11573d6000803e3d6000fd5b505050506040513d6020811015611b2757600080fd5b5051611b3257600080fd5b505b611b3c61434e565b6040805160c0810182528581526001600160a01b038b166020820152815160018082528184018452919283019181602001602082028036833750505081526040805160018082528183019092526020928301929091908083019080368337505050815260408051600180825281830190925260209283019290919080830190803683370190505081526020018767ffffffffffffffff168152509050828160400151600081518110611bea57fe5b602002602001018181525050878160600151600081518110611c0857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050338160800151600081518110611c3a57fe5b6001600160a01b039092166020928302919091019091015261200063f7a251d76003611c65846125d9565b611c7a866402540be40063ffffffff6124fc16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611cd8578181015183820152602001611cc0565b50505050905090810190601f168015611d055780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015611d2657600080fd5b505af1158015611d3a573d6000803e3d6000fd5b5050604080516001600160a01b038d1681523360208201528082018b90526060810186905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9350908190036080019150a150600198975050505050505050565b3361100714611ddd5760405162461bcd60e51b815260040180806020018281038252602e8152602001806146e0602e913960400191505060405180910390fd5b60208114611e32576040805162461bcd60e51b815260206004820152601b60248201527f65787065637465642076616c7565206c656e6774682069732033320000000000604482015290519081900360640190fd5b606084848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8801819004810282018101909252868152939450606093925086915085908190840183828082843760009201919091525050505060208301519091506772656c617946656560c01b811415611f3a576020820151670de0b6b3a76400008111801590611ee157506402540be4008106155b611f32576040805162461bcd60e51b815260206004820152601960248201527f7468652072656c6179466565206f7574206f662072616e676500000000000000604482015290519081900360640190fd5b600155611f77565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a878787876040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050505050565b336110081461204c5760405162461bcd60e51b815260040180806020018281038252602381526020018061479c6023913960400191505060405180910390fd5b600091825260046020908152604080842080546001600160a01b03191690556001600160a01b0392909216835260039052812055565b6221272160e91b81565b61c35081565b60026020526000908152604090205481565b6001600160a01b031660009081526003602052604090205490565b61100281565b60005460ff1661210a576040805162461bcd60e51b815260206004820152601960248201526000805160206147bf833981519152604482015290519081900360640190fd5b336120001461214a5760405162461bcd60e51b815260040180806020018281038252602f81526020018061476d602f913960400191505060405180910390fd5b60ff8316600314156114795761147482828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612a7892505050565b61100381565b60005460ff16156121f3576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b66071afd498d000060019081556000808052600260205260127fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b55805460ff19169091179055565b600481565b600581565b61100081565b61271081565b6001600160a01b03811660009081526003602090815260409182902054825182815280840190935260609290918391906020820181803683375050506020810183905290506000805b60208160ff1610156122e157828160ff16815181106122b557fe5b01602001516001600160f81b031916156122d4576001909101906122d9565b6122e1565b60010161229a565b5060608160ff166040519080825280601f01601f191660200182016040528015612312576020820181803683370190505b50905060005b8260ff168160ff16101561236e57838160ff168151811061233557fe5b602001015160f81c60f81b828260ff168151811061234f57fe5b60200101906001600160f81b031916908160001a905350600101612318565b5095945050505050565b61100481565b606061238861439a565b600061239384612b76565b91509150806123e9576040805162461bcd60e51b815260206004820152601f60248201527f756e7265636f676e697a6564207472616e73666572496e207061636b61676500604482015290519081900360640190fd5b60006123f483612cb5565b905063ffffffff811615612488576040808401516020808601516001600160a01b0316600090815260029091529182205461242f9190612932565b90506124396143cf565b60405180608001604052808660000151815260200183815260200186608001516001600160a01b031681526020018463ffffffff16815250905061247c81613002565b95505050505050610e53565b50506040805160008152602081019091529150610e539050565b6000828201838110156116b9576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60006116b983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506130de565b60008261254d575060006116bc565b8282028284828161255a57fe5b04146116b95760405162461bcd60e51b81526004018080602001828103825260218152602001806146806021913960400191505060405180910390fd5b60006116b983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613180565b60408051600680825260e08201909252606091829190816020015b60608152602001906001900390816125f45750508351909150612616906131da565b8160008151811061262357fe5b602002602001018190525061264483602001516001600160a01b03166131ed565b8160018151811061265157fe5b60200260200101819052506000836040015151905060608160405190808252806020026020018201604052801561269c57816020015b60608152602001906001900390816126875790505b50905060005b828110156126e9576126ca866040015182815181106126bd57fe5b60200260200101516131da565b8282815181106126d657fe5b60209081029190910101526001016126a2565b506126f381613210565b8360028151811061270057fe5b602002602001018190525060608260405190808252806020026020018201604052801561274157816020015b606081526020019060019003908161272c5790505b50905060005b83811015612797576127788760600151828151811061276257fe5b60200260200101516001600160a01b03166131ed565b82828151811061278457fe5b6020908102919091010152600101612747565b506127a181613210565b846003815181106127ae57fe5b60200260200101819052506060836040519080825280602002602001820160405280156127ef57816020015b60608152602001906001900390816127da5790505b50905060005b8481101561282f576128108860800151828151811061276257fe5b82828151811061281c57fe5b60209081029190910101526001016127f5565b5061283981613210565b8560048151811061284657fe5b60200260200101819052506128688760a0015167ffffffffffffffff166131da565b8560058151811061287557fe5b602002602001018190525061288985613210565b979650505050505050565b61289c6143f6565b60006128a78361329a565b91509150806128e75760405162461bcd60e51b815260040180806020018281038252602481526020018061470e6024913960400191505060405180910390fd5b6114e882613465565b60006116b983836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f00000000000000008152506138e9565b6000600882111561295b57612954836007198401600a0a63ffffffff6124fc16565b90506116bc565b6116b9836008849003600a0a63ffffffff61253e16565b604080516020808252818301909252600091606091906020820181803683375050506020810184905290506000805b60208160ff1610156129e857828160ff16815181106129bc57fe5b01602001516001600160f81b031916156129db576001909101906129e0565b6129e8565b6001016129a1565b50600860ff82161015612a0057600092505050610e53565b816005820360ff1681518110612a1257fe5b6020910101516001600160f81b031916602d60f81b14612a3757600092505050610e53565b816001820360ff1681518110612a4957fe5b6020910101516001600160f81b031916604d60f81b14612a6e57600092505050610e53565b5060019392505050565b612a8061434e565b6000612a8b8361394b565b9150915080612acb5760405162461bcd60e51b81526004018080602001828103825260248152602001806144d16024913960400191505060405180910390fd5b612ad36143f6565b602080840180516001600160a01b0390811684526040808701518585015291511660009081526002909252812054905b846040015151811015612b5457612b3185604001518281518110612b2357fe5b602002602001015183613bc6565b85604001518281518110612b4157fe5b6020908102919091010152600101612b03565b506080840151604083015260056060830152612b6f82613465565b5050505050565b612b7e61439a565b6000612b8861439a565b612b9061442d565b612ba1612b9c86613bff565b613c24565b90506000805b612bb083613c6e565b15612ca85780612bd257612bcb612bc684613c8f565b613cdd565b8452612ca0565b8060011415612bff57612bec612be784613c8f565b613d94565b6001600160a01b03166020850152612ca0565b8060021415612c1e57612c14612bc684613c8f565b6040850152612ca0565b8060031415612c4657612c33612be784613c8f565b6001600160a01b03166060850152612ca0565b8060041415612c6e57612c5b612be784613c8f565b6001600160a01b03166080850152612ca0565b8060051415612c9b57612c83612bc684613c8f565b67ffffffffffffffff1660a085015260019150612ca0565b612ca8565b600101612ba7565b5091935090915050915091565b60208101516000906001600160a01b0316612dec578160a0015167ffffffffffffffff16421115612ce857506001610e53565b8160400151471015612cfc57506003610e53565b606082015160408084015190516000926001600160a01b0316916127109184818181858888f193505050503d8060008114612d53576040519150601f19603f3d011682016040523d82523d6000602084013e612d58565b606091505b5050905080612d6b575060049050610e53565b7f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5983602001518460600151856040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a15060009050610e53565b8160a0015167ffffffffffffffff16421115612e0a57506001610e53565b81516020808401516001600160a01b031660009081526003909152604090205414612e3757506002610e53565b602080830151604080516370a0823160e01b815230600482015290516000936001600160a01b03909316926370a082319261c3509260248083019392829003018187803b158015612e8757600080fd5b5086fa158015612e9b573d6000803e3d6000fd5b50505050506040513d6020811015612eb257600080fd5b50516040840151909150811015612ecd575060039050610e53565b600083602001516001600160a01b031663a9059cbb61c350866060015187604001516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b158015612f3e57600080fd5b5087f1158015612f52573d6000803e3d6000fd5b50505050506040513d6020811015612f6957600080fd5b505190508015612ff6577f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5984602001518560600151866040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a15060009150610e539050565b5060059150610e539050565b60408051600480825260a08201909252606091829190816020015b606081526020019060019003908161301d575050835190915061303f906131da565b8160008151811061304c57fe5b602002602001018190525061306483602001516131da565b8160018151811061307157fe5b602002602001018190525061309283604001516001600160a01b03166131ed565b8160028151811061309f57fe5b60200260200101819052506130bd836060015163ffffffff166131da565b816003815181106130ca57fe5b6020026020010181905250610e2781613210565b6000818361316a5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561312f578181015183820152602001613117565b50505050905090810190601f16801561315c5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161317657fe5b0495945050505050565b600081848411156131d25760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561312f578181015183820152602001613117565b505050900390565b60606116bc6131e883613dae565b613e94565b60408051600560a21b8318601482015260348101909152606090610e2781613e94565b60608151600014156132315750604080516000815260208101909152610e53565b60608260008151811061324057fe5b602002602001015190506000600190505b8351811015613281576132778285838151811061326a57fe5b6020026020010151613ee6565b9150600101613251565b50610e27613294825160c060ff16613f63565b82613ee6565b6132a26143f6565b60006132ac6143f6565b6132b461442d565b6132c0612b9c86613bff565b90506000805b6132cf83613c6e565b15612ca857806132f5576132e5612be784613c8f565b6001600160a01b0316845261345d565b806001141561339657606061331161330c85613c8f565b61405b565b9050805160405190808252806020026020018201604052801561333e578160200160208202803683370190505b50602086015260005b815181101561338f5761336c82828151811061335f57fe5b6020026020010151613cdd565b8660200151828151811061337c57fe5b6020908102919091010152600101613347565b505061345d565b80600214156134385760606133ad61330c85613c8f565b905080516040519080825280602002602001820160405280156133da578160200160208202803683370190505b50604086015260005b815181101561338f576134088282815181106133fb57fe5b6020026020010151613d94565b8660400151828151811061341857fe5b6001600160a01b03909216602092830291909101909101526001016133e3565b8060031415612c9b5761344d612bc684613c8f565b63ffffffff166060850152600191505b6001016132c6565b80516001600160a01b031661368f5760005b8160200151518110156136895760008260400151828151811061349657fe5b60200260200101516001600160a01b0316612710846020015184815181106134ba57fe5b60209081029190910101516040516000818181858888f193505050503d8060008114613502576040519150601f19603f3d011682016040523d82523d6000602084013e613507565b606091505b50509050806135ca577f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e83600001518460400151848151811061354657fe5b60200260200101518560200151858151811061355e57fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a1613680565b7fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a83600001518460400151848151811061360057fe5b60200260200101518560200151858151811061361857fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b50600101613477565b506138e6565b60005b8160200151518110156138e457600082600001516001600160a01b031663a9059cbb61c350856040015185815181106136c757fe5b6020026020010151866020015186815181106136df57fe5b60200260200101516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b15801561373657600080fd5b5087f115801561374a573d6000803e3d6000fd5b50505050506040513d602081101561376157600080fd5b505190508015613825577fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a8360000151846040015184815181106137a157fe5b6020026020010151856020015185815181106137b957fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a16138db565b7f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e83600001518460400151848151811061385b57fe5b60200260200101518560200151858151811061387357fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b50600101613692565b505b50565b600081836139385760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561312f578181015183820152602001613117565b5082848161394257fe5b06949350505050565b61395361434e565b600061395d61434e565b61396561442d565b613971612b9c86613bff565b90506000805b61398083613c6e565b15613bb8578061399d57613996612bc684613c8f565b8452613bb0565b80600114156139c5576139b2612be784613c8f565b6001600160a01b03166020850152613bb0565b8060021415613a545760606139dc61330c85613c8f565b90508051604051908082528060200260200182016040528015613a09578160200160208202803683370190505b50604086015260005b8151811015613a4d57613a2a82828151811061335f57fe5b86604001518281518110613a3a57fe5b6020908102919091010152600101613a12565b5050613bb0565b8060031415613ae9576060613a6b61330c85613c8f565b90508051604051908082528060200260200182016040528015613a98578160200160208202803683370190505b50606086015260005b8151811015613a4d57613ab98282815181106133fb57fe5b86606001518281518110613ac957fe5b6001600160a01b0390921660209283029190910190910152600101613aa1565b8060041415613b7e576060613b0061330c85613c8f565b90508051604051908082528060200260200182016040528015613b2d578160200160208202803683370190505b50608086015260005b8151811015613a4d57613b4e8282815181106133fb57fe5b86608001518281518110613b5e57fe5b6001600160a01b0390921660209283029190910190910152600101613b36565b8060051415613bab57613b93612bc684613c8f565b67ffffffffffffffff1660a085015260019150613bb0565b613bb8565b600101613977565b509195600195509350505050565b60006008821115613be857612954836007198401600a0a63ffffffff61253e16565b6116b9836008849003600a0a63ffffffff6124fc16565b613c0761444d565b506040805180820190915281518152602082810190820152919050565b613c2c61442d565b613c358261412c565b613c3e57600080fd5b6000613c4d836020015161415c565b60208085015160408051808201909152868152920190820152915050919050565b6000613c7861444d565b505080518051602091820151919092015191011190565b613c9761444d565b613ca082613c6e565b613ca957600080fd5b60208201516000613cb9826141bf565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590613cf257508151602110155b613cfb57600080fd5b6000613d0a836020015161415c565b90508083600001511015613d65576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b825160208085015183018051928490039291831015613d8b57826020036101000a820491505b50949350505050565b8051600090601514613da557600080fd5b6116bc82613cdd565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416613df257506018613e16565b6fffffffffffffffffffffffffffffffff198416613e1257506010613e16565b5060005b6020811015613e4c57818181518110613e2b57fe5b01602001516001600160f81b03191615613e4457613e4c565b600101613e16565b60008160200390506060816040519080825280601f01601f191660200182016040528015613e81576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015613ec65750607f60f81b82600081518110613eb457fe5b01602001516001600160f81b03191611155b15613ed2575080610e53565b6116bc613ee48351608060ff16613f63565b835b6060806040519050835180825260208201818101602087015b81831015613f17578051835260209283019201613eff565b50855184518101855292509050808201602086015b81831015613f44578051835260209283019201613f2c565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310613fb3576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b6040805160018082528183019092526060916020820181803683370190505090506037841161400d5782840160f81b81600081518110613fef57fe5b60200101906001600160f81b031916908160001a90535090506116bc565b606061401885613dae565b90508381510160370160f81b8260008151811061403157fe5b60200101906001600160f81b031916908160001a9053506140528282613ee6565b95945050505050565b60606140668261412c565b61406f57600080fd5b600061407a836142f2565b90506060816040519080825280602002602001820160405280156140b857816020015b6140a561444d565b81526020019060019003908161409d5790505b50905060006140ca856020015161415c565b60208601510190506000805b84811015614121576140e7836141bf565b915060405180604001604052808381526020018481525084828151811061410a57fe5b6020908102919091010152918101916001016140d6565b509195945050505050565b805160009061413d57506000610e53565b6020820151805160001a9060c0821015612a6e57600092505050610e53565b8051600090811a6080811015614176576000915050610e53565b60b8811080614191575060c08110801590614191575060f881105b156141a0576001915050610e53565b60c08110156141b45760b519019050610e53565b60f519019050610e53565b80516000908190811a60808110156141da57600191506142eb565b60b88110156141ef57607e19810191506142eb565b60c081101561426957600060b78203600186019550806020036101000a865104915060018101820193505080831015614263576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b506142eb565b60f881101561427e5760be19810191506142eb565b600060f78203600186019550806020036101000a8651049150600181018201935050808310156142e9576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b805160009061430357506000610e53565b60008090506000614317846020015161415c565b602085015185519181019250015b8082101561434557614336826141bf565b60019093019290910190614325565b50909392505050565b6040518060c001604052806000801916815260200160006001600160a01b03168152602001606081526020016060815260200160608152602001600067ffffffffffffffff1681525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b60408051608081018252600080825260208201819052918101829052606081019190915290565b604051806080016040528060006001600160a01b031681526020016060815260200160608152602001600063ffffffff1681525090565b604051806040016040528061444061444d565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe746865206d6573736167652073656e646572206d75737420626520696e63656e746976697a6520636f6e7472616374466f72206d696e69546f6b656e2c20746865207472616e7366657220616d6f756e74206d757374206e6f74206265206c657373207468616e2031756e7265636f676e697a6564207472616e736665724f75742073796e207061636b61676565787069726554696d65206d7573742062652074776f206d696e75746573206c61746572616d6f756e7420697320746f6f206c617267652c20657863656564206d6178696d756d206265703220746f6b656e20616d6f756e7474686520636f6e747261637420686173206e6f74206265656e20626f756e6420746f20616e79206265703220746f6b656e726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e736665724f757420424e4220616d6f756e7420616e64206d696e696d756d2072656c6179466565616d6f756e7420697320746f6f206c617267652c2075696e74323536206f766572666c6f774c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620726566756e644164647273696e76616c6964207472616e7366657220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e20746865206d696e696d756d2072656c6179466565746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374756e7265636f676e697a6564207472616e736665724f75742061636b207061636b6167654c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620616d6f756e7473746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d73672073656e646572206d75737420626520746f6b656e4d616e6167657274686520636f6e7472616374206e6f7420696e69742079657400000000000000726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e7366657220424e4220616d6f756e7420616e642072656c6179466565696e76616c696420726563656976656420424e4220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6ea26469706673582212200ed3b493edce71fd9235e1f674e51718f846ead6af3ed00debad31d4e3d4dc5f64736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001005": { - "balance": "0x0", - "code": "0x6080604052600436106102765760003560e01c80637e146cc51161014f578063af400681116100c1578063e75d72c71161007a578063e75d72c714610795578063e89a3020146107c8578063f9a2bbc7146107f2578063fc3e590814610807578063fd6a68791461081c578063fdd31fcd146108315761027d565b8063af400681146106ed578063bd4cc83014610717578063c81b166214610741578063dc927faf14610756578063dcae76ab1461076b578063e1c7392a146107805761027d565b8063a3c3c0ad11610113578063a3c3c0ad146105b3578063a78abc16146105c8578063a7c6a59d146105dd578063ab51bb96146105f2578063ac43175114610607578063ace9fcc2146106d85761027d565b80637e146cc51461052c578063930e1b091461054157806396713da9146105745780639dc0926214610589578063a1a11bf51461059e5761027d565b806343756e5c116101e85780636e47b482116101ac5780636e47b482146104645780636f93d2e61461047957806370fd5bad146104d857806374f2272d146104ed57806375d47a0a146105025780637942fd05146105175761027d565b806343756e5c146103e4578063493279b1146103f95780634bf6c8821461042557806351e806721461043a578063541333071461044f5761027d565b806312950c461161023a57806312950c46146103165780631b20087c1461032b5780631c643312146103405780633a975612146102825780633dffc3871461038657806340bb43c0146103b15761027d565b8063081e9d131461028257806308f2ec06146102a9578063093f2fc4146102be5780630bee7a67146102d357806310e06a76146103015761027d565b3661027d57005b600080fd5b34801561028e57600080fd5b50610297610864565b60408051918252519081900360200190f35b3480156102b557600080fd5b50610297610869565b3480156102ca57600080fd5b5061029761086e565b3480156102df57600080fd5b506102e8610873565b6040805163ffffffff9092168252519081900360200190f35b34801561030d57600080fd5b50610297610878565b34801561032257600080fd5b5061029761087e565b34801561033757600080fd5b50610297610884565b34801561034c57600080fd5b5061036a6004803603602081101561036357600080fd5b503561088a565b604080516001600160a01b039092168252519081900360200190f35b34801561039257600080fd5b5061039b610864565b6040805160ff9092168252519081900360200190f35b3480156103bd57600080fd5b50610297600480360360208110156103d457600080fd5b50356001600160a01b03166108b1565b3480156103f057600080fd5b5061036a6108c3565b34801561040557600080fd5b5061040e6108c9565b6040805161ffff9092168252519081900360200190f35b34801561043157600080fd5b5061039b6108ce565b34801561044657600080fd5b5061036a6108d3565b34801561045b57600080fd5b50610297610873565b34801561047057600080fd5b5061036a6108d9565b34801561048557600080fd5b506104c46004803603608081101561049c57600080fd5b506001600160a01b0381358116916020810135909116906040810135906060013515156108df565b604080519115158252519081900360200190f35b3480156104e457600080fd5b5061039b610cad565b3480156104f957600080fd5b50610297610cb2565b34801561050e57600080fd5b5061036a610cb8565b34801561052357600080fd5b5061039b610cbe565b34801561053857600080fd5b50610297610cc3565b34801561054d57600080fd5b506102976004803603602081101561056457600080fd5b50356001600160a01b0316610cc8565b34801561058057600080fd5b5061039b610cda565b34801561059557600080fd5b5061036a610cdf565b3480156105aa57600080fd5b5061036a610ce5565b3480156105bf57600080fd5b50610297610ceb565b3480156105d457600080fd5b506104c4610cf1565b3480156105e957600080fd5b50610297610cfa565b3480156105fe57600080fd5b506102e8610d00565b34801561061357600080fd5b506106d66004803603604081101561062a57600080fd5b81019060208101813564010000000081111561064557600080fd5b82018360208201111561065757600080fd5b8035906020019184600183028401116401000000008311171561067957600080fd5b91939092909160208101903564010000000081111561069757600080fd5b8201836020820111156106a957600080fd5b803590602001918460018302840111640100000000831117156106cb57600080fd5b509092509050610d05565b005b3480156106e457600080fd5b50610297611354565b3480156106f957600080fd5b506102976004803603602081101561071057600080fd5b503561135a565b34801561072357600080fd5b506102976004803603602081101561073a57600080fd5b50356113b5565b34801561074d57600080fd5b5061036a6113ce565b34801561076257600080fd5b5061036a6113d4565b34801561077757600080fd5b506102976113da565b34801561078c57600080fd5b506106d66113e0565b3480156107a157600080fd5b506106d6600480360360208110156107b857600080fd5b50356001600160a01b03166114a9565b3480156107d457600080fd5b5061036a600480360360208110156107eb57600080fd5b5035611602565b3480156107fe57600080fd5b5061036a61160f565b34801561081357600080fd5b5061039b611615565b34801561082857600080fd5b5061036a61161a565b34801561083d57600080fd5b506102976004803603602081101561085457600080fd5b50356001600160a01b0316611620565b600181565b602881565b605081565b606481565b600b5481565b60015481565b600c5481565b6006818154811061089757fe5b6000918252602090912001546001600160a01b0316905081565b60076020526000908152604090205481565b61100181565b603881565b600881565b61200081565b61100581565b6000805460ff16610937576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604482015290519081900360640190fd5b33612000146109775760405162461bcd60e51b815260040180806020018281038252602f815260200180612164602f913960400191505060405180910390fd5b600082156109fc57604080516309a99b4f60e41b8152611005600482015260248101869052905161100291639a99b4f09160448083019260209291908290030181600087803b1580156109c957600080fd5b505af11580156109dd573d6000803e3d6000fd5b505050506040513d60208110156109f357600080fd5b50519050610a75565b604080516309a99b4f60e41b8152611005600482015260248101869052905161100491639a99b4f09160448083019260209291908290030181600087803b158015610a4657600080fd5b505af1158015610a5a573d6000803e3d6000fd5b505050506040513d6020811015610a7057600080fd5b505190505b600c805460010190556000610a8982611632565b600954909150610a9f908263ffffffff61166116565b600955600a54610ac7908290610abb908563ffffffff61166116565b9063ffffffff6116c216565b600a556001600160a01b038716600090815260056020526040902054610b3357600680546001810182556000919091527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0180546001600160a01b0319166001600160a01b0389161790555b6001600160a01b038088166000908152600560209081526040808320805460010190559289168252600790522054610bb157600880546001810182556000919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30180546001600160a01b0319166001600160a01b0388161790555b6001600160a01b038616600090815260076020526040902080546001019055600c54606411610ca057600b54600954600a5460408051938452602084019290925282820152517f2649b1b772a1a74bd332a67695e285317dd722941166595741c60a00fa65bb759181900360600190a16000610c2b611704565b90506000610c376119e8565b6001600160a01b0389166000908152600d6020526040902054909150610c75908290610c69908563ffffffff61166116565b9063ffffffff61166116565b6001600160a01b0389166000908152600d6020526040812091909155600b80546001019055600c5550505b5060019695505050505050565b600281565b60035481565b61100881565b600b81565b600581565b60056020526000908152604090205481565b600981565b61100781565b61100681565b600a5481565b60005460ff1681565b60045481565b600081565b3361100714610d455760405162461bcd60e51b815260040180806020018281038252602e8152602001806120a9602e913960400191505060405180910390fd5b60005460ff16610d865760405162461bcd60e51b81526004018080602001828103825260218152602001806120d76021913960400191505060405180910390fd5b610dfa84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601f81527f68656164657252656c61796572526577617264526174654d6f6c6563756c650060208201529150611c669050565b15610ec75760208114610e3e5760405162461bcd60e51b81526004018080602001828103825260328152602001806121936032913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610e7c91858580838501838280828437600092019190915250611d4d92505050565b9050600254811115610ebf5760405162461bcd60e51b8152600401808060200182810382526060815260200180611f826060913960600191505060405180910390fd5b6001556112c2565b610f2084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805160608101909152602280825290925090506120876020830139611c66565b15610ff85760208114610f645760405162461bcd60e51b815260040180806020018281038252602e815260200180612038602e913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610fa291858580838501838280828437600092019190915250611d4d92505050565b90508015801590610fb557506001548110155b610ff05760405162461bcd60e51b815260040180806020018281038252606c8152602001806120f8606c913960800191505060405180910390fd5b6002556112c2565b61106c84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601a81527f63616c6c6572436f6d70656e736174696f6e4d6f6c6563756c6500000000000060208201529150611c669050565b1561113957602081146110b05760405162461bcd60e51b815260040180806020018281038252602e815260200180612038602e913960400191505060405180910390fd5b604080516020601f84018190048102820181019092528281526000916110ee91858580838501838280828437600092019190915250611d4d92505050565b90506004548111156111315760405162461bcd60e51b8152600401808060200182810382526056815260200180611fe26056913960600191505060405180910390fd5b6003556112c2565b6111ad84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601d81527f63616c6c6572436f6d70656e736174696f6e44656e6f6d696e61746f7200000060208201529150611c669050565b1561128557602081146111f15760405162461bcd60e51b815260040180806020018281038252602e815260200180612038602e913960400191505060405180910390fd5b604080516020601f840181900481028201810190925282815260009161122f91858580838501838280828437600092019190915250611d4d92505050565b9050801580159061124257506003548110155b61127d5760405162461bcd60e51b8152600401808060200182810382526061815260200180611f216061913960800191505060405180910390fd5b6004556112c2565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b60025481565b60006028821161136b5750806113b0565b81602810801561137c575060508211155b15611389575060286113b0565b60508211801561139a5750606e8211155b156113aa575060788190036113b0565b50600481045b919050565b6000602882116113c65750806113b0565b5060286113b0565b61100281565b61100381565b60095481565b60005460ff1615611438576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b60005460ff1615611486576040805162461bcd60e51b8152602060048201526013602482015272185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604482015290519081900360640190fd5b60018080556005600255600381905560506004556000805460ff19169091179055565b6001600160a01b0381166000908152600d602052604090205480611508576040805162461bcd60e51b81526020600482015260116024820152701b9bc81c995b185e595c881c995dd85c99607a1b604482015290519081900360640190fd5b6001600160a01b0382166000818152600d60205260408082208290555184929184156108fc02918591818181858888f193505050506115b85760405161100290819084156108fc029085906000818181858888f19350505050158015611572573d6000803e3d6000fd5b506040805161100281526020810185905281517f24502838a334c8f2bb2ee1f8262a4fa7183e4489a717e96cc824e325f8b39e11929181900390910190a15050506115ff565b604080516001600160a01b03851681526020810184905281517f24502838a334c8f2bb2ee1f8262a4fa7183e4489a717e96cc824e325f8b39e11929181900390910190a150505b50565b6008818154811061089757fe5b61100081565b600381565b61100481565b600d6020526000908152604090205481565b600061165b60025461164f60015485611d5290919063ffffffff16565b9063ffffffff611dab16565b92915050565b6000828201838110156116bb576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b60006116bb83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611ded565b600954600680546040805160208084028201810190925282815260009493859360609383018282801561176057602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611742575b5050505050905060608151604051908082528060200260200182016040528015611794578160200160208202803683370190505b50905060005b82518110156118215760008382815181106117b157fe5b6020026020010151905060006117eb60056000846001600160a01b03166001600160a01b03168152602001908152602001600020546113b5565b9050808484815181106117fa57fe5b6020908102919091010152611815868263ffffffff61166116565b9550505060010161179a565b50600061183f60045461164f60035488611d5290919063ffffffff16565b9050611851858263ffffffff6116c216565b94508460015b845181101561192857600061188c8761164f8a88868151811061187657fe5b6020026020010151611d5290919063ffffffff16565b90506118d981600d60008986815181106118a257fe5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000205461166190919063ffffffff16565b600d60008885815181106118e957fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205561191d838263ffffffff6116c216565b925050600101611857565b5061193e81600d6000876000815181106118a257fe5b600d60008660008151811061194f57fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002081905550600060098190555060008090505b84518110156119d057600560008683815181106119a257fe5b6020908102919091018101516001600160a01b03168252810191909152604001600090812055600101611989565b506119dd60066000611ee9565b509450505050505b90565b600a546008805460408051602080840282018101909252828152600094938593606093830182828015611a4457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611a26575b5050505050905060608151604051908082528060200260200182016040528015611a78578160200160208202803683370190505b50905060005b8251811015611af7576000838281518110611a9557fe5b602002602001015190506000611acf60076000846001600160a01b03166001600160a01b031681526020019081526020016000205461135a565b905080848481518110611ade57fe5b6020908102919091010152949094019350600101611a7e565b506000611b1560045461164f60035488611d5290919063ffffffff16565b9050611b27858263ffffffff6116c216565b94508460015b8451811015611bb1576000611b4c8761164f8a88868151811061187657fe5b9050611b6281600d60008986815181106118a257fe5b600d6000888581518110611b7257fe5b6020908102919091018101516001600160a01b0316825281019190915260400160002055611ba6838263ffffffff6116c216565b925050600101611b2d565b50611bc781600d6000876000815181106118a257fe5b600d600086600081518110611bd857fe5b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055506000600a8190555060008090505b8451811015611c595760076000868381518110611c2b57fe5b6020908102919091018101516001600160a01b03168252810191909152604001600090812055600101611c12565b506119dd60086000611ee9565b6000816040516020018082805190602001908083835b60208310611c9b5780518252601f199092019160209182019101611c7c565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310611d095780518252601f199092019160209182019101611cea565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b600082611d615750600061165b565b82820282848281611d6e57fe5b04146116bb5760405162461bcd60e51b81526004018080602001828103825260218152602001806120666021913960400191505060405180910390fd5b60006116bb83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611e84565b60008184841115611e7c5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611e41578181015183820152602001611e29565b50505050905090810190601f168015611e6e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008183611ed35760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315611e41578181015183820152602001611e29565b506000838581611edf57fe5b0495945050505050565b50805460008255906000526020600020908101906115ff91906119e591905b80821115611f1c5760008155600101611f08565b509056fe746865206e657743616c6c6572436f6d70656e736174696f6e44656e6f6d696e61746f72206d757374206e6f74206265207a65726f20616e64206e6f206c657373207468616e2063616c6c6572436f6d70656e736174696f6e4d6f6c6563756c656e65772068656164657252656c61796572526577617264526174654d6f6c6563756c652073686f756c646e27742062652067726561746572207468616e2068656164657252656c617965725265776172645261746544656e6f6d696e61746f726e65772063616c6c6572436f6d70656e736174696f6e4d6f6c6563756c652073686f756c646e27742062652067726561746572207468616e2063616c6c6572436f6d70656e736174696f6e44656e6f6d696e61746f726c656e677468206f6620726577617264466f7256616c696461746f725365744368616e6765206d69736d61746368536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7768656164657252656c617965725265776172645261746544656e6f6d696e61746f72746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374636f6e747261637420686173206e6f74206265656e20696e697469616c697a6564746865206e65772068656164657252656c617965725265776172645261746544656e6f6d696e61746f72206d757374206e6f74206265207a65726f20616e64206e6f206c657373207468616e2068656164657252656c61796572526577617264526174654d6f6c6563756c65746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e74726163746c656e677468206f662068656164657252656c61796572526577617264526174654d6f6c6563756c65206d69736d61746368a2646970667358221220cd7c1ec8296551de0c54d97959872d6570445d6b1250fde9150f66f3ae10dc7164736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001006": { - "balance": "0x0", - "code": "0x6080604052600436106101c25760003560e01c806395468d26116100f7578063c81b166211610095578063f9a2bbc711610064578063f9a2bbc714610529578063fb7cfdd71461053e578063fc3e590814610553578063fd6a687914610568576101c2565b8063c81b1662146104d5578063dc927faf146104ea578063e1c7392a146104ff578063e79a198f14610514576101c2565b8063a1a11bf5116100d1578063a1a11bf5146103c7578063a78abc16146103dc578063ab51bb96146103f1578063ac43175114610406576101c2565b806395468d261461038857806396713da91461039d5780639dc09262146103b2576101c2565b8063541d55481161016457806370fd5bad1161013e57806370fd5bad1461033457806375d47a0a146103495780637942fd051461035e5780637ae2308814610373576101c2565b8063541d5548146102b15780636a87d780146102f85780636e47b4821461031f576101c2565b806343756e5c116101a057806343756e5c1461022a578063493279b11461025b5780634bf6c8821461028757806351e806721461029c576101c2565b80630bee7a67146101c75780631aa3a008146101f55780633dffc387146101ff575b600080fd5b3480156101d357600080fd5b506101dc61057d565b6040805163ffffffff9092168252519081900360200190f35b6101fd610582565b005b34801561020b57600080fd5b5061021461077d565b6040805160ff9092168252519081900360200190f35b34801561023657600080fd5b5061023f610782565b604080516001600160a01b039092168252519081900360200190f35b34801561026757600080fd5b50610270610788565b6040805161ffff9092168252519081900360200190f35b34801561029357600080fd5b5061021461078d565b3480156102a857600080fd5b5061023f610792565b3480156102bd57600080fd5b506102e4600480360360208110156102d457600080fd5b50356001600160a01b0316610798565b604080519115158252519081900360200190f35b34801561030457600080fd5b5061030d6107b6565b60408051918252519081900360200190f35b34801561032b57600080fd5b5061023f6107bc565b34801561034057600080fd5b506102146107c2565b34801561035557600080fd5b5061023f6107c7565b34801561036a57600080fd5b506102146107cd565b34801561037f57600080fd5b5061030d6107d2565b34801561039457600080fd5b5061030d6107df565b3480156103a957600080fd5b506102146107eb565b3480156103be57600080fd5b5061023f6107f0565b3480156103d357600080fd5b5061023f6107f6565b3480156103e857600080fd5b506102e46107fc565b3480156103fd57600080fd5b506101dc610805565b34801561041257600080fd5b506101fd6004803603604081101561042957600080fd5b81019060208101813564010000000081111561044457600080fd5b82018360208201111561045657600080fd5b8035906020019184600183028401116401000000008311171561047857600080fd5b91939092909160208101903564010000000081111561049657600080fd5b8201836020820111156104a857600080fd5b803590602001918460018302840111640100000000831117156104ca57600080fd5b50909250905061080a565b3480156104e157600080fd5b5061023f610c2c565b3480156104f657600080fd5b5061023f610c32565b34801561050b57600080fd5b506101fd610c38565b34801561052057600080fd5b506101fd610cba565b34801561053557600080fd5b5061023f610e73565b34801561054a57600080fd5b5061030d610e79565b34801561055f57600080fd5b50610214610e7f565b34801561057457600080fd5b5061023f610e84565b606481565b3360009081526004602052604090205460ff16156105df576040805162461bcd60e51b81526020600482015260156024820152741c995b185e595c88185b1c9958591e48195e1a5cdd605a1b604482015290519081900360640190fd5b60005460ff16610632576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b61063b33610e8a565b156106775760405162461bcd60e51b815260040180806020018281038252602781526020018061109c6027913960400191505060405180910390fd5b3332146106c1576040805162461bcd60e51b81526020600482015260136024820152721b9bc81c1c9bde1e481a5cc8185b1b1bddd959606a1b604482015290519081900360640190fd5b60015434146107015760405162461bcd60e51b81526004018080602001828103825260258152602001806110776025913960400191505060405180910390fd5b604080518082018252600180548252600254602080840191825233600081815260038352868120955186559251948401949094556004815290849020805460ff1916909217909155825191825291517fdb33a09d38b59a8fa8b7d92a1d82c8015e99f05f67ae9c9ae623157767959496929181900390910190a1565b600181565b61100181565b603881565b600881565b61200081565b6001600160a01b031660009081526004602052604090205460ff1690565b60025481565b61100581565b600281565b61100881565b600b81565b68056bc75e2d6310000081565b67016345785d8a000081565b600981565b61100781565b61100681565b60005460ff1681565b600081565b60005460ff1661085d576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b336110071461089d5760405162461bcd60e51b815260040180806020018281038252602e8152602001806110c3602e913960400191505060405180910390fd5b61090384848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e1c995c5d5a5c995911195c1bdcda5d608a1b60208201529150610e909050565b15610a0657602081146109475760405162461bcd60e51b81526004018080602001828103825260228152602001806110f16022913960400191505060405180910390fd5b604080516020601f840181900481028201810190925282815260009161098591858580838501838280828437600092019190915250610f7792505050565b90506001811180156109a05750683635c9adc5dea000008111155b80156109ad575060025481115b6109fe576040805162461bcd60e51b815260206004820181905260248201527f7468652072657175697265644465706f736974206f7574206f662072616e6765604482015290519081900360640190fd5b600155610b9a565b610a6184848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260048152636475657360e01b60208201529150610e909050565b15610b5d5760208114610abb576040805162461bcd60e51b815260206004820152601760248201527f6c656e677468206f662064756573206d69736d61746368000000000000000000604482015290519081900360640190fd5b604080516020601f8401819004810282018101909252828152600091610af991858580838501838280828437600092019190915250610f7792505050565b9050600081118015610b0c575060015481105b610b55576040805162461bcd60e51b81526020600482015260156024820152747468652064756573206f7574206f662072616e676560581b604482015290519081900360640190fd5b600255610b9a565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b60005460ff1615610c90576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b68056bc75e2d63100000600190815567016345785d8a00006002556000805460ff19169091179055565b3360009081526004602052604090205460ff16610d15576040805162461bcd60e51b81526020600482015260146024820152731c995b185e595c88191bc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b60005460ff16610d68576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b610d7061105c565b5033600081815260036020908152604091829020825180840190935280548084526001909101549183018290529192916108fc91610db4919063ffffffff610f7c16565b6040518115909202916000818181858888f19350505050158015610ddc573d6000803e3d6000fd5b50602081015160405161100291829181156108fc0291906000818181858888f19350505050158015610e12573d6000803e3d6000fd5b50336000818152600460209081526040808320805460ff191690556003825280832083815560010192909255815192835290517fd17202129b83db7880d6b9f25df81c58ad46f7e0e2c92236b1aa10663a4876679281900390910190a15050565b61100081565b60015481565b600381565b61100481565b3b151590565b6000816040516020018082805190602001908083835b60208310610ec55780518252601f199092019160209182019101610ea6565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310610f335780518252601f199092019160209182019101610f14565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b6000610fbe83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610fc5565b9392505050565b600081848411156110545760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611019578181015183820152602001611001565b50505050905090810190601f1680156110465780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60405180604001604052806000815260200160008152509056fe6465706f7369742076616c7565206973206e6f742065786163746c79207468652073616d65636f6e7472616374206973206e6f7420616c6c6f77656420746f20626520612072656c61796572746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662072657175697265644465706f736974206d69736d61746368a2646970667358221220449507f2557413401b33bd1aa888e40f31523a5d010a891cf7383c0090d7f49a64736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001007": { - "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b506004361061018e5760003560e01c8063831d65d1116100de578063ab51bb9611610097578063dc927faf11610071578063dc927faf14610486578063f9a2bbc71461048e578063fc3e590814610496578063fd6a68791461049e5761018e565b8063ab51bb96146103fc578063c81b166214610404578063c8509d811461040c5761018e565b8063831d65d11461034457806396713da9146103c05780639ab1a373146103c85780639dc09262146103d0578063a1a11bf5146103d8578063a78abc16146103e05761018e565b8063493279b11161014b5780636e47b482116101255780636e47b4821461032457806370fd5bad1461032c57806375d47a0a146103345780637942fd051461033c5761018e565b8063493279b1146102f55780634bf6c8821461031457806351e806721461031c5761018e565b80630bee7a67146101935780631182b875146101b45780633a21baae146102a35780633dffc387146102ab57806343756e5c146102c95780634900c4ea146102ed575b600080fd5b61019b6104a6565b6040805163ffffffff9092168252519081900360200190f35b61022e600480360360408110156101ca57600080fd5b60ff82351691908101906040810160208201356401000000008111156101ef57600080fd5b82018360208201111561020157600080fd5b8035906020019184600183028401116401000000008311171561022357600080fd5b5090925090506104ab565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610268578181015183820152602001610250565b50505050905090810190601f1680156102955780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61019b61059a565b6102b361059f565b6040805160ff9092168252519081900360200190f35b6102d16105a4565b604080516001600160a01b039092168252519081900360200190f35b6102b36105aa565b6102fd6105af565b6040805161ffff9092168252519081900360200190f35b6102b36105b4565b6102d16105b9565b6102d16105bf565b6102b36105c5565b6102d16105ca565b6102b36105d0565b6103be6004803603604081101561035a57600080fd5b60ff823516919081019060408101602082013564010000000081111561037f57600080fd5b82018360208201111561039157600080fd5b803590602001918460018302840111640100000000831117156103b357600080fd5b5090925090506105d5565b005b6102b3610667565b61019b61066c565b6102d1610671565b6102d1610677565b6103e861067d565b604080519115158252519081900360200190f35b61019b6105aa565b6102d1610686565b6103be6004803603604081101561042257600080fd5b60ff823516919081019060408101602082013564010000000081111561044757600080fd5b82018360208201111561045957600080fd5b8035906020019184600183028401116401000000008311171561047b57600080fd5b50909250905061068c565b6102d1610703565b6102d1610709565b6102b361070f565b6102d1610714565b606481565b606033612000146104ed5760405162461bcd60e51b815260040180806020018281038252602f8152602001806113e7602f913960400191505060405180910390fd5b6104f5611382565b600061053685858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061071a92505050565b91509150806105525761054960646107e0565b92505050610593565b600061055d8361084a565b905063ffffffff811661058457505060408051600081526020810190915291506105939050565b61058d816107e0565b93505050505b9392505050565b606681565b600181565b61100181565b600081565b603881565b600881565b61200081565b61100581565b600281565b61100881565b600b81565b33612000146106155760405162461bcd60e51b815260040180806020018281038252602f8152602001806113e7602f913960400191505060405180910390fd5b6040805162461bcd60e51b815260206004820152601e60248201527f7265636569766520756e65787065637465642061636b207061636b6167650000604482015290519081900360640190fd5b505050565b600981565b606581565b61100781565b61100681565b60005460ff1681565b61100281565b33612000146106cc5760405162461bcd60e51b815260040180806020018281038252602f8152602001806113e7602f913960400191505060405180910390fd5b60405162461bcd60e51b81526004018080602001828103825260238152602001806114166023913960400191505060405180910390fd5b61100381565b61100081565b600381565b61100481565b610722611382565b600061072c611382565b6107346113ac565b61074561074086610beb565b610c10565b90506000805b61075483610c5a565b156107d357806107765761076f61076a84610c7b565b610cc9565b84526107cb565b80600114156107955761078b61076a84610c7b565b60208501526107cb565b80600214156107c6576107af6107aa84610c7b565b610d42565b6001600160a01b03166040850152600191506107cb565b6107d3565b60010161074b565b5091935090915050915091565b604080516001808252818301909252606091829190816020015b60608152602001906001900390816107fa5790505090506108208363ffffffff16610d62565b8160008151811061082d57fe5b602002602001018190525061084181610d75565b9150505b919050565b60006108598260400151610dff565b6108c557604080516020808252601c908201527f74686520746172676574206973206e6f74206120636f6e7472616374000000008183015290517f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb29181900360600190a1506065610845565b81604001516001600160a01b031663ac431751836000015184602001516040518363ffffffff1660e01b8152600401808060200180602001838103835285818151815260200191508051906020019080838360005b8381101561093257818101518382015260200161091a565b50505050905090810190601f16801561095f5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b8381101561099257818101518382015260200161097a565b50505050905090810190601f1680156109bf5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156109e057600080fd5b505af19250505080156109f1575060015b610be3576040516000815260443d1015610a0d57506000610aaa565b60046000803e60005160e01c6308c379a08114610a2e576000915050610aaa565b60043d036004833e81513d602482011167ffffffffffffffff82111715610a5a57600092505050610aaa565b808301805167ffffffffffffffff811115610a7c576000945050505050610aaa565b8060208301013d8601811115610a9a57600095505050505050610aaa565b601f01601f191660405250925050505b80610ab55750610b58565b7f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2816040518080602001828103825283818151815260200191508051906020019080838360005b83811015610b14578181015183820152602001610afc565b50505050905090810190601f168015610b415780820380516001836020036101000a031916815260200191505b509250505060405180910390a16066915050610845565b3d808015610b82576040519150601f19603f3d011682016040523d82523d6000602084013e610b87565b606091505b5060408051602080825283518183015283517f1279f84165b4fd69c35e1f338ff107231b036c655cd1688851e011ce617c4e8d938593928392918301919085019080838360008315610b14578181015183820152602001610afc565b506000919050565b610bf36113cc565b506040805180820190915281518152602082810190820152919050565b610c186113ac565b610c2182610e05565b610c2a57600080fd5b6000610c398360200151610e3f565b60208085015160408051808201909152868152920190820152915050919050565b6000610c646113cc565b505080518051602091820151919092015191011190565b610c836113cc565b610c8c82610c5a565b610c9557600080fd5b60208201516000610ca582610ea2565b80830160209586015260408051808201909152908152938401919091525090919050565b8051606090610cd757600080fd5b6000610ce68360200151610e3f565b83516040805191839003808352601f19601f8201168301602001909152919250606090828015610d1d576020820181803683370190505b5090506000816020019050610d39848760200151018285610fd5565b50949350505050565b8051600090601514610d5357600080fd5b610d5c82611020565b92915050565b6060610d5c610d70836110d5565b6111bb565b6060815160001415610d965750604080516000815260208101909152610845565b606082600081518110610da557fe5b602002602001015190506000600190505b8351811015610de657610ddc82858381518110610dcf57fe5b602002602001015161120d565b9150600101610db6565b50610841610df9825160c060ff1661128a565b8261120d565b3b151590565b8051600090610e1657506000610845565b6020820151805160001a9060c0821015610e3557600092505050610845565b5060019392505050565b8051600090811a6080811015610e59576000915050610845565b60b8811080610e74575060c08110801590610e74575060f881105b15610e83576001915050610845565b60c0811015610e975760b519019050610845565b60f519019050610845565b80516000908190811a6080811015610ebd5760019150610fce565b60b8811015610ed257607e1981019150610fce565b60c0811015610f4c57600060b78203600186019550806020036101000a865104915060018101820193505080831015610f46576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b50610fce565b60f8811015610f615760be1981019150610fce565b600060f78203600186019550806020036101000a865104915060018101820193505080831015610fcc576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b80610fdf57610662565b5b60208110610fff578251825260209283019290910190601f1901610fe0565b915181516020939093036101000a6000190180199091169216919091179052565b80516000901580159061103557508151602110155b61103e57600080fd5b600061104d8360200151610e3f565b905080836000015110156110a8576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b825160208085015183018051928490039291831015610d3957506020919091036101000a90049392505050565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166111195750601861113d565b6fffffffffffffffffffffffffffffffff1984166111395750601061113d565b5060005b60208110156111735781818151811061115257fe5b01602001516001600160f81b0319161561116b57611173565b60010161113d565b60008160200390506060816040519080825280601f01601f1916602001820160405280156111a8576020820181803683370190505b5080830196909652508452509192915050565b6060815160011480156111ed5750607f60f81b826000815181106111db57fe5b01602001516001600160f81b03191611155b156111f9575080610845565b610d5c61120b8351608060ff1661128a565b835b6060806040519050835180825260208201818101602087015b8183101561123e578051835260209283019201611226565b50855184518101855292509050808201602086015b8183101561126b578051835260209283019201611253565b508651929092011591909101601f01601f191660405250905092915050565b60606801000000000000000083106112da576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b604080516001808252818301909252606091602082018180368337019050509050603784116113345782840160f81b8160008151811061131657fe5b60200101906001600160f81b031916908160001a9053509050610d5c565b606061133f856110d5565b90508381510160370160f81b8260008151811061135857fe5b60200101906001600160f81b031916908160001a905350611379828261120d565b95945050505050565b6040518060600160405280606081526020016060815260200160006001600160a01b031681525090565b60405180604001604052806113bf6113cc565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e74726163747265636569766520756e6578706563746564206661696c2061636b207061636b616765a2646970667358221220a5eefec118f5b467b996b871e3b96c20aa4fe4192a6c4b34c6afc795161d4a9a64736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001008": { - "balance": "0x0", - "code": "0x6080604052600436106102465760003560e01c806375d47a0a11610139578063ab51bb96116100b6578063d9e6dae91161007a578063d9e6dae914610512578063dc927faf14610975578063f9a2bbc71461098a578063fc3e590814610566578063fd6a68791461099f578063fe3a2af5146104e857610246565b8063ab51bb96146108ca578063c81b1662146108df578063c8509d81146107da578063c8e704a414610566578063d117a110146108f457610246565b806395b9ad26116100fd57806395b9ad261461086157806396713da9146108765780639dc092621461088b578063a1a11bf5146108a0578063a78abc16146108b557610246565b806375d47a0a146106fc57806377d9dae8146107115780637942fd05146107c55780637d078e13146103b3578063831d65d1146107da57610246565b80634bc81c00116101c757806366dea52a1161018b57806366dea52a146105665780636b3f13071461057b5780636e47b4821461064357806370fd5bad1461055157806372c4e0861461065857610246565b80634bc81c00146104fd5780634bf6c8821461051257806351e80672146105275780635d499b1b1461053c5780635f558f861461055157610246565b80633dffc3871161020e5780633dffc387146103b357806343756e5c146103c8578063445fcefe146103f9578063493279b1146104bc5780634a688818146104e857610246565b80630bee7a671461024b5780630f212b1b146102795780631182b875146102a45780631f91600b1461039e57806323996b53146103b3575b600080fd5b34801561025757600080fd5b506102606109b4565b6040805163ffffffff9092168252519081900360200190f35b34801561028557600080fd5b5061028e6109b9565b6040805160ff9092168252519081900360200190f35b3480156102b057600080fd5b50610329600480360360408110156102c757600080fd5b60ff8235169190810190604081016020820135600160201b8111156102eb57600080fd5b8201836020820111156102fd57600080fd5b803590602001918460018302840111600160201b8311171561031e57600080fd5b5090925090506109be565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561036357818101518382015260200161034b565b50505050905090810190601f1680156103905780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103aa57600080fd5b5061028e610a47565b3480156103bf57600080fd5b5061028e610a4c565b3480156103d457600080fd5b506103dd610a51565b604080516001600160a01b039092168252519081900360200190f35b34801561040557600080fd5b506104aa6004803603602081101561041c57600080fd5b810190602081018135600160201b81111561043657600080fd5b82018360208201111561044857600080fd5b803590602001918460018302840111600160201b8311171561046957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610a57945050505050565b60408051918252519081900360200190f35b3480156104c857600080fd5b506104d1610bb6565b6040805161ffff9092168252519081900360200190f35b3480156104f457600080fd5b5061028e610bbb565b34801561050957600080fd5b5061028e610bc0565b34801561051e57600080fd5b5061028e610bc5565b34801561053357600080fd5b506103dd610bca565b34801561054857600080fd5b506104aa610bd0565b34801561055d57600080fd5b5061028e610bd9565b34801561057257600080fd5b5061028e610bde565b61062f6004803603604081101561059157600080fd5b6001600160a01b038235169190810190604081016020820135600160201b8111156105bb57600080fd5b8201836020820111156105cd57600080fd5b803590602001918460018302840111600160201b831117156105ee57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610be3945050505050565b604080519115158252519081900360200190f35b34801561064f57600080fd5b506103dd611465565b61062f6004803603602081101561066e57600080fd5b810190602081018135600160201b81111561068857600080fd5b82018360208201111561069a57600080fd5b803590602001918460018302840111600160201b831117156106bb57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061146b945050505050565b34801561070857600080fd5b506103dd6118b9565b61062f6004803603604081101561072757600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561075157600080fd5b82018360208201111561076357600080fd5b803590602001918460018302840111600160201b8311171561078457600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506118bf945050505050565b3480156107d157600080fd5b5061028e611dc6565b3480156107e657600080fd5b5061085f600480360360408110156107fd57600080fd5b60ff8235169190810190604081016020820135600160201b81111561082157600080fd5b82018360208201111561083357600080fd5b803590602001918460018302840111600160201b8311171561085457600080fd5b509092509050611dcb565b005b34801561086d57600080fd5b5061028e611e7e565b34801561088257600080fd5b5061028e611e83565b34801561089757600080fd5b506103dd611e88565b3480156108ac57600080fd5b506103dd611e8e565b3480156108c157600080fd5b5061062f611e94565b3480156108d657600080fd5b50610260610bbb565b3480156108eb57600080fd5b506103dd611e9d565b34801561090057600080fd5b5061091e6004803603602081101561091757600080fd5b5035611ea3565b6040805160ff988916815260208101979097526001600160a01b03909516868601526060860193909352608085019190915290931660a083015267ffffffffffffffff90921660c082015290519081900360e00190f35b34801561098157600080fd5b506103dd611efb565b34801561099657600080fd5b506103dd611f01565b3480156109ab57600080fd5b506103dd611f07565b606481565b600681565b60603361200014610a005760405162461bcd60e51b815260040180806020018281038252602f8152602001806132a0602f913960400191505060405180910390fd5b610a3f83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611f0d92505050565b949350505050565b600481565b600181565b61100181565b6020810151600090610a67613168565b50600081815260016020818152604092839020835160e081018552815460ff9081168252938201549281019290925260028101546001600160a01b031693820184905260038101546060830152600481015460808301526005015491821660a082015261010090910467ffffffffffffffff1660c082015290610aef57600092505050610bb1565b600081604001516001600160a01b03166370a082316110046040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610b4d57600080fd5b505afa158015610b61573d6000803e3d6000fd5b505050506040513d6020811015610b7757600080fd5b505160808301516060840151919250600091610b989163ffffffff61219e16565b9050610baa818363ffffffff61219e16565b9450505050505b919050565b603881565b600081565b600581565b600881565b61200081565b6402540be40081565b600281565b600381565b600080610bef836121e7565b9050610bf9613168565b50600081815260016020818152604092839020835160e081018552815460ff90811682529382015492810183905260028201546001600160a01b03169481019490945260038101546060850152600481015460808501526005015491821660a084015261010090910467ffffffffffffffff1660c0830152610cbf576040805162461bcd60e51b815260206004820152601a602482015279189a5b99081c995c5d595cdd08191bd95cdb89dd08195e1a5cdd60321b604482015290519081900360640190fd5b6000610cdc8260800151836060015161219e90919063ffffffff16565b905081604001516001600160a01b0316866001600160a01b031614610d325760405162461bcd60e51b815260040180806020018281038252604581526020018061325b6045913960600191505060405180910390fd5b336001600160a01b0316866001600160a01b031663893d20e86040518163ffffffff1660e01b815260040160206040518083038186803b158015610d7557600080fd5b505afa158015610d89573d6000803e3d6000fd5b505050506040513d6020811015610d9f57600080fd5b50516001600160a01b031614610de65760405162461bcd60e51b815260040180806020018281038252602e8152602001806131f6602e913960400191505060405180910390fd5b604080516370a0823160e01b8152611004600482015290516000916001600160a01b038916916370a0823191602480820192602092909190829003018186803b158015610e3257600080fd5b505afa158015610e46573d6000803e3d6000fd5b505050506040513d6020811015610e5c57600080fd5b505160408051636eb1769f60e11b815233600482015230602482015290519192508391610eed9184916001600160a01b038c169163dd62ed3e916044808301926020929190829003018186803b158015610eb557600080fd5b505afa158015610ec9573d6000803e3d6000fd5b505050506040513d6020811015610edf57600080fd5b50519063ffffffff6121ee16565b1015610f40576040805162461bcd60e51b815260206004820152601760248201527f616c6c6f77616e6365206973206e6f7420656e6f756768000000000000000000604482015290519081900360640190fd5b600034905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b158015610f8257600080fd5b505afa158015610f96573d6000803e3d6000fd5b505050506040513d6020811015610fac57600080fd5b50519050808210801590610fc557506402540be4008206155b6110005760405162461bcd60e51b81526004018080602001828103825260378152602001806132246037913960400191505060405180910390fd5b600061100c868b612248565b905063ffffffff811661120b576001600160a01b038a166323b872dd3361100461103c898963ffffffff61219e16565b6040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050602060405180830381600087803b1580156110a457600080fd5b505af11580156110b8573d6000803e3d6000fd5b505050506040513d60208110156110ce57600080fd5b5050602086015160408088015160a089015182516323bfccdb60e21b815260048101949094526001600160a01b03909116602484015260ff1660448301525161100491638eff336c91606480830192600092919082900301818387803b15801561113757600080fd5b505af115801561114b573d6000803e3d6000fd5b50505050896001600160a01b03167f78e7dd9aefcdbf795c4936a66f7dc6d41bb56637b54f561a6bf7829dca3348a88a8860600151886040518080602001848152602001838152602001828103825285818151815260200191508051906020019080838360005b838110156111ca5781810151838201526020016111b2565b50505050905090810190601f1680156111f75780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a26112c3565b896001600160a01b03167f831c0ef4d93bda3bce08b69ae3f29ef1a6e052b833200988554158494405a1078a8360405180806020018363ffffffff1663ffffffff168152602001828103825284818151815260200191508051906020019080838360005b8381101561128757818101518382015260200161126f565b50505050905090810190601f1680156112b45780820380516001836020036101000a031916815260200191505b50935050505060405180910390a25b60008781526001602081905260408220805460ff191681559081018290556002810180546001600160a01b0319169055600381018290556004810191909155600501805468ffffffffffffffffff1916905561131d6131a4565b5060408051808201825263ffffffff831681526020810189905290516110049085156108fc029086906000818181858888f19350505050158015611365573d6000803e3d6000fd5b5061200063f7a251d760016113798461269f565b61138e886402540be40063ffffffff61272916565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156113ec5781810151838201526020016113d4565b50505050905090810190601f1680156114195780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561143a57600080fd5b505af115801561144e573d6000803e3d6000fd5b505050506001985050505050505050505b92915050565b61100581565b600080611477836121e7565b9050611481613168565b50600081815260016020818152604092839020835160e081018552815460ff90811682529382015492810183905260028201546001600160a01b03169481019490945260038101546060850152600481015460808501526005015491821660a084015261010090910467ffffffffffffffff1660c0830152611547576040805162461bcd60e51b815260206004820152601a602482015279189a5b99081c995c5d595cdd08191bd95cdb89dd08195e1a5cdd60321b604482015290519081900360640190fd5b428160c0015167ffffffffffffffff16106115a9576040805162461bcd60e51b815260206004820152601b60248201527f62696e642072657175657374206973206e6f7420657870697265640000000000604482015290519081900360640190fd5b600034905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b1580156115eb57600080fd5b505afa1580156115ff573d6000803e3d6000fd5b505050506040513d602081101561161557600080fd5b5051905080821080159061162e57506402540be4008206155b6116695760405162461bcd60e51b81526004018080602001828103825260378152602001806132246037913960400191505060405180910390fd5b60008481526001602081905260408220805460ff191681559081018290556002810180546001600160a01b0319169055600381018290556004810191909155600501805468ffffffffffffffffff191690556116c36131a4565b50604080518082018252600181526020810186905290516110049084156108fc029085906000818181858888f19350505050158015611706573d6000803e3d6000fd5b5061200063f7a251d7600161171a8461269f565b61172f876402540be40063ffffffff61272916565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561178d578181015183820152602001611775565b50505050905090810190601f1680156117ba5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156117db57600080fd5b505af11580156117ef573d6000803e3d6000fd5b5050505083604001516001600160a01b03167f831c0ef4d93bda3bce08b69ae3f29ef1a6e052b833200988554158494405a10788600160405180806020018360ff1663ffffffff168152602001828103825284818151815260200191508051906020019080838360005b83811015611871578181015183820152602001611859565b50505050905090810190601f16801561189e5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a25060019695505050505050565b61100881565b6000806118cb836121e7565b90506118d5613168565b50600081815260016020818152604092839020835160e081018552815460ff90811682529382015492810183905260028201546001600160a01b03169481019490945260038101546060850152600481015460808501526005015491821660a084015261010090910467ffffffffffffffff1660c083015261199b576040805162461bcd60e51b815260206004820152601a602482015279189a5b99081c995c5d595cdd08191bd95cdb89dd08195e1a5cdd60321b604482015290519081900360640190fd5b80604001516001600160a01b0316856001600160a01b0316146119ef5760405162461bcd60e51b815260040180806020018281038252604581526020018061325b6045913960600191505060405180910390fd5b336001600160a01b0316856001600160a01b031663893d20e86040518163ffffffff1660e01b815260040160206040518083038186803b158015611a3257600080fd5b505afa158015611a46573d6000803e3d6000fd5b505050506040513d6020811015611a5c57600080fd5b50516001600160a01b031614611ab9576040805162461bcd60e51b815260206004820152601b60248201527f6f6e6c79206265703230206f776e65722063616e2072656a6563740000000000604482015290519081900360640190fd5b600034905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b158015611afb57600080fd5b505afa158015611b0f573d6000803e3d6000fd5b505050506040513d6020811015611b2557600080fd5b50519050808210801590611b3e57506402540be4008206155b611b795760405162461bcd60e51b81526004018080602001828103825260378152602001806132246037913960400191505060405180910390fd5b60008481526001602081905260408220805460ff191681559081018290556002810180546001600160a01b0319169055600381018290556004810191909155600501805468ffffffffffffffffff19169055611bd36131a4565b50604080518082018252600781526020810186905290516110049084156108fc029085906000818181858888f19350505050158015611c16573d6000803e3d6000fd5b5061200063f7a251d76001611c2a8461269f565b611c3f876402540be40063ffffffff61272916565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611c9d578181015183820152602001611c85565b50505050905090810190601f168015611cca5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015611ceb57600080fd5b505af1158015611cff573d6000803e3d6000fd5b50505050876001600160a01b03167f831c0ef4d93bda3bce08b69ae3f29ef1a6e052b833200988554158494405a10788600760405180806020018360ff1663ffffffff168152602001828103825284818151815260200191508051906020019080838360005b83811015611d7d578181015183820152602001611d65565b50505050905090810190601f168015611daa5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a2506001979650505050505050565b600b81565b3361200014611e0b5760405162461bcd60e51b815260040180806020018281038252602f8152602001806132a0602f913960400191505060405180910390fd5b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a1505050565b600781565b600981565b61100781565b61100681565b60005460ff1681565b61100281565b600160208190526000918252604090912080549181015460028201546003830154600484015460059094015460ff9586169593946001600160a01b0390931693919291811690610100900467ffffffffffffffff1687565b61100381565b61100081565b61100481565b6060611f17613168565b6000611f228461276b565b9150915080611f78576040805162461bcd60e51b815260206004820152601f60248201527f756e7265636f676e697a6564207472616e73666572496e207061636b61676500604482015290519081900360640190fd5b815160ff1661202c576020828101805160009081526001928390526040908190208551815460ff1990811660ff928316178355935194820194909455908501516002820180546001600160a01b0319166001600160a01b03909216919091179055606085015160038201556080850151600482015560a08501516005909101805460c08701519316919093161768ffffffffffffffff00191661010067ffffffffffffffff90921691909102179055612183565b815160ff16600114156121365760006110046001600160a01b03166359b9278984602001516040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561208557600080fd5b505afa158015612099573d6000803e3d6000fd5b505050506040513d60208110156120af57600080fd5b505190506001600160a01b038116156121305760208301516040805163b99328c560e01b815260048101929092526001600160a01b0383166024830152516110049163b99328c591604480830192600092919082900301818387803b15801561211757600080fd5b505af115801561212b573d6000803e3d6000fd5b505050505b50612183565b6040805162461bcd60e51b815260206004820152601960248201527f756e7265636f676e697a65642062696e64207061636b61676500000000000000604482015290519081900360640190fd5b60408051600080825260208201909252905b50949350505050565b60006121e083836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506128bd565b9392505050565b6020015190565b6000828201838110156121e0576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600080826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561228457600080fd5b505afa158015612298573d6000803e3d6000fd5b505050506040513d60208110156122ae57600080fd5b5051604080516395d89b4160e01b815290519192506060916001600160a01b038616916395d89b41916004808301926000929190829003018186803b1580156122f657600080fd5b505afa15801561230a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561233357600080fd5b8101908080516040519392919084600160201b82111561235257600080fd5b90830190602082018581111561236757600080fd5b8251600160201b81118282018810171561238057600080fd5b82525081516020918201929091019080838360005b838110156123ad578181015183820152602001612395565b50505050905090810190601f1680156123da5780820380516001836020036101000a031916815260200191505b5060408181526370a0823160e01b82526110046004830152519495506000946001600160a01b038a1694506370a08231935060248083019350602092829003018186803b15801561242a57600080fd5b505afa15801561243e573d6000803e3d6000fd5b505050506040513d602081101561245457600080fd5b5051608087015160608801519192506000916124759163ffffffff61219e16565b9050428760c0015167ffffffffffffffff16101561249b57506001935061145f92505050565b6124a9838860200151612954565b6124bb57506002935061145f92505050565b808211156124d157506003935061145f92505050565b866060015187604001516001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561251357600080fd5b505afa158015612527573d6000803e3d6000fd5b505050506040513d602081101561253d57600080fd5b50511461255257506004935061145f92505050565b8660a0015160ff16841461256e57506005935061145f92505050565b602080880151604080516359b9278960e01b8152600481019290925251600092611004926359b927899260248083019392829003018186803b1580156125b357600080fd5b505afa1580156125c7573d6000803e3d6000fd5b505050506040513d60208110156125dd57600080fd5b50516001600160a01b031614158061267f57506000801b6110046001600160a01b031663bd46646189604001516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561265057600080fd5b505afa158015612664573d6000803e3d6000fd5b505050506040513d602081101561267a57600080fd5b505114155b1561269257506006935061145f92505050565b5060009695505050505050565b6040805160028082526060828101909352829190816020015b60608152602001906001900390816126b857505083519091506126e09063ffffffff16612a3c565b816000815181106126ed57fe5b6020026020010181905250612708836020015160001c612a3c565b8160018151811061271557fe5b60200260200101819052506121e081612a4f565b60006121e083836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612ad9565b612773613168565b600061277d613168565b6127856131bb565b61279661279186612b3e565b612b63565b90506000805b6127a583612bad565b156128b057806127ca576127c06127bb84612bce565b612c1c565b60ff1684526128a8565b80600114156127e9576127df6127bb84612bce565b60208501526128a8565b8060021415612816576128036127fe84612bce565b612cd1565b6001600160a01b031660408501526128a8565b80600314156128355761282b6127bb84612bce565b60608501526128a8565b80600414156128545761284a6127bb84612bce565b60808501526128a8565b8060051415612876576128696127bb84612bce565b60ff1660a08501526128a8565b80600614156128a35761288b6127bb84612bce565b67ffffffffffffffff1660c0850152600191506128a8565b6128b0565b60010161279c565b5091935090915050915091565b6000818484111561294c5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156129115781810151838201526020016128f9565b50505050905090810190601f16801561293e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b815160009083906008108061296a575080516003115b1561297957600091505061145f565b604080516020808252818301909252606091602082018180368337019050509050836020820152808251815181106129ad57fe5b6020910101516001600160f81b031916602d60f81b146129d25760009250505061145f565b600160005b8351811015612a32578281815181106129ec57fe5b602001015160f81c60f81b6001600160f81b031916848281518110612a0d57fe5b01602001516001600160f81b03191614612a2a5760009150612a32565b6001016129d7565b5095945050505050565b606061145f612a4a83612ceb565b612dd1565b6060815160001415612a705750604080516000815260208101909152610bb1565b606082600081518110612a7f57fe5b602002602001015190506000600190505b8351811015612ac057612ab682858381518110612aa957fe5b6020026020010151612e23565b9150600101612a90565b506121e0612ad3825160c060ff16612ea0565b82612e23565b60008183612b285760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156129115781810151838201526020016128f9565b506000838581612b3457fe5b0495945050505050565b612b466131db565b506040805180820190915281518152602082810190820152919050565b612b6b6131bb565b612b7482612f98565b612b7d57600080fd5b6000612b8c8360200151612fd2565b60208085015160408051808201909152868152920190820152915050919050565b6000612bb76131db565b505080518051602091820151919092015191011190565b612bd66131db565b612bdf82612bad565b612be857600080fd5b60208201516000612bf882613035565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590612c3157508151602110155b612c3a57600080fd5b6000612c498360200151612fd2565b90508083600001511015612ca4576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b82516020808501518301805192849003929183101561219557506020919091036101000a90049392505050565b8051600090601514612ce257600080fd5b61145f82612c1c565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416612d2f57506018612d53565b6fffffffffffffffffffffffffffffffff198416612d4f57506010612d53565b5060005b6020811015612d8957818181518110612d6857fe5b01602001516001600160f81b03191615612d8157612d89565b600101612d53565b60008160200390506060816040519080825280601f01601f191660200182016040528015612dbe576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015612e035750607f60f81b82600081518110612df157fe5b01602001516001600160f81b03191611155b15612e0f575080610bb1565b61145f612e218351608060ff16612ea0565b835b6060806040519050835180825260208201818101602087015b81831015612e54578051835260209283019201612e3c565b50855184518101855292509050808201602086015b81831015612e81578051835260209283019201612e69565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310612ef0576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411612f4a5782840160f81b81600081518110612f2c57fe5b60200101906001600160f81b031916908160001a905350905061145f565b6060612f5585612ceb565b90508381510160370160f81b82600081518110612f6e57fe5b60200101906001600160f81b031916908160001a905350612f8f8282612e23565b95945050505050565b8051600090612fa957506000610bb1565b6020820151805160001a9060c0821015612fc857600092505050610bb1565b5060019392505050565b8051600090811a6080811015612fec576000915050610bb1565b60b8811080613007575060c08110801590613007575060f881105b15613016576001915050610bb1565b60c081101561302a5760b519019050610bb1565b60f519019050610bb1565b80516000908190811a60808110156130505760019150613161565b60b881101561306557607e1981019150613161565b60c08110156130df57600060b78203600186019550806020036101000a8651049150600181018201935050808310156130d9576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b50613161565b60f88110156130f45760be1981019150613161565b600060f78203600186019550806020036101000a86510491506001810182019350508083101561315f576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915290565b604080518082019091526000808252602082015290565b60405180604001604052806131ce6131db565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe6f6e6c79206265703230206f776e65722063616e20617070726f766520746869732062696e64207265717565737472656c6179466565206d757374206265204e202a203165313020616e642067726561746572207468616e206d696e6952656c6179466565636f6e74616374206164647265737320646f65736e277420657175616c20746f2074686520636f6e7472616374206164647265737320696e2062696e642072657175657374746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374a264697066735822122030cc6c250f37ad9452c0933399bf3f460a19215bce5c10c377f100761098776a64736f6c63430006040033" - }, - "0x0000000000000000000000000000000000002000": { - "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b50600436106102485760003560e01c8063863fe4ab1161013b578063c81b1662116100b8578063e3b048051161007c578063e3b048051461072c578063f7a251d71461074c578063f9a2bbc7146107c4578063fc3e5908146107cc578063fd6a6879146107d457610248565b8063c81b1662146106dd578063d31f968d146106e5578063d76a867514610714578063dc927faf1461071c578063e1c7392a1461072457610248565b8063a78abc16116100ff578063a78abc16146105d3578063ab51bb96146105db578063ac431751146105e3578063b0355f5b146103ff578063c27cdcfb146106a157610248565b8063863fe4ab146105b35780638cc8f561146104b657806396713da9146105bb5780639dc09262146105c3578063a1a11bf5146105cb57610248565b8063493279b1116101c957806370fd5bad1161018d57806370fd5bad146104b657806374f079b8146104be57806375d47a0a146104c65780637942fd05146104ce57806384013b6a146104d657610248565b8063493279b11461045f5780634bf6c8821461047e57806351e80672146104865780636e47a51a1461048e5780636e47b482146104ae57610248565b8063308325f411610210578063308325f4146102cf5780633bdc47a6146102d75780633dffc387146103ff578063422f90501461040757806343756e5c1461043b57610248565b806305e682581461024d5780630bee7a671461026b57806314b3023b1461028c57806322556cdc146102a65780632ff32aea146102ae575b600080fd5b6102556107dc565b6040805160ff9092168252519081900360200190f35b6102736107e1565b6040805163ffffffff9092168252519081900360200190f35b6102946107e6565b60408051918252519081900360200190f35b6102946107ec565b6102b66107f1565b60408051600792830b90920b8252519081900360200190f35b6102946107fa565b61038a600480360360608110156102ed57600080fd5b60ff82351691602081013591810190606081016040820135600160201b81111561031657600080fd5b82018360208201111561032857600080fd5b803590602001918460018302840111600160201b8311171561034957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610800945050505050565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103c45781810151838201526020016103ac565b50505050905090810190601f1680156103f15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610255610876565b6104276004803603602081101561041d57600080fd5b503560ff1661087b565b604080519115158252519081900360200190f35b610443610890565b604080516001600160a01b039092168252519081900360200190f35b610467610896565b6040805161ffff9092168252519081900360200190f35b61025561089b565b6104436108a0565b610443600480360360208110156104a457600080fd5b503560ff166108a6565b6104436108c1565b6102556108c7565b6102946108cc565b6104436108d2565b6102556108d8565b6105b1600480360360a08110156104ec57600080fd5b810190602081018135600160201b81111561050657600080fd5b82018360208201111561051857600080fd5b803590602001918460018302840111600160201b8311171561053957600080fd5b919390929091602081019035600160201b81111561055657600080fd5b82018360208201111561056857600080fd5b803590602001918460018302840111600160201b8311171561058957600080fd5b919350915080356001600160401b03908116916020810135909116906040013560ff166108dd565b005b610294611a8d565b610255611a95565b610443611a9a565b610443611aa0565b610427611aa6565b6102736107dc565b6105b1600480360360408110156105f957600080fd5b810190602081018135600160201b81111561061357600080fd5b82018360208201111561062557600080fd5b803590602001918460018302840111600160201b8311171561064657600080fd5b919390929091602081019035600160201b81111561066357600080fd5b82018360208201111561067557600080fd5b803590602001918460018302840111600160201b8311171561069657600080fd5b509092509050611aaf565b6106c1600480360360208110156106b757600080fd5b503560ff16612051565b604080516001600160401b039092168252519081900360200190f35b61044361206c565b610427600480360360408110156106fb57600080fd5b5080356001600160a01b0316906020013560ff16612072565b61038a612092565b6104436120b1565b6105b16120b7565b6106c16004803603602081101561074257600080fd5b503560ff1661246e565b6105b16004803603606081101561076257600080fd5b60ff8235169190810190604081016020820135600160201b81111561078657600080fd5b82018360208201111561079857600080fd5b803590602001918460018302840111600160201b831117156107b957600080fd5b919350915035612489565b6104436125da565b6102556125e0565b6104436125e5565b600081565b606481565b60015481565b603281565b60045460070b81565b60025481565b60606000825160210190506060816040519080825280601f01601f191660200182016040528015610838576020820181803683370190505b506021810186905260018101879052828152905060418101600061085b866125eb565b50905061086a818388516125f5565b50909695505050505050565b600181565b60096020526000908152604090205460ff1681565b61100181565b603881565b600881565b61200081565b6005602052600090815260409020546001600160a01b031681565b61100581565b600281565b60035481565b61100881565b600b81565b60005460ff16610930576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b60408051630a83aaa960e31b815233600482015290516110069163541d5548916024808301926020929190829003018186803b15801561096f57600080fd5b505afa158015610983573d6000803e3d6000fd5b505050506040513d602081101561099957600080fd5b50516109ec576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b60ff8116600090815260086020526040902054829082906001600160401b039081169083168114610a5c576040805162461bcd60e51b815260206004820152601560248201527439b2b8bab2b731b2903737ba1034b71037b93232b960591b604482015290519081900360640190fd5b60ff8216600090815260086020908152604091829020805467ffffffffffffffff1916600185016001600160401b039081169190911790915582516337d7f9c160e21b81529089166004820152915188926110039263df5fe70492602480840193829003018186803b158015610ad157600080fd5b505afa158015610ae5573d6000803e3d6000fd5b505050506040513d6020811015610afb57600080fd5b5051610b385760405162461bcd60e51b8152600401808060200182810382526023815260200180612bcc6023913960400191505060405180910390fd5b60ff851660009081526005602052604090205485906001600160a01b0316610ba7576040805162461bcd60e51b815260206004820152601860248201527f6368616e6e656c206973206e6f7420737570706f727465640000000000000000604482015290519081900360640190fd5b60608c8c8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805163cba510a960e01b81526001600160401b038f1660048201529051939450610cce93611003935063cba510a992506024808301926020929190829003018186803b158015610c7757600080fd5b505afa158015610c8b573d6000803e3d6000fd5b505050506040513d6020811015610ca157600080fd5b505160408051808201909152600381526269626360e81b6020820152610cc78c8c612636565b858561267d565b610d16576040805162461bcd60e51b815260206004820152601460248201527334b73b30b634b21036b2b935b63290383937b7b360611b604482015290519081900360640190fd5b60408051631bb5062960e31b81526001600160401b038c16600482015290516000916110039163dda8314891602480820192602092909190829003018186803b158015610d6257600080fd5b505afa158015610d76573d6000803e3d6000fd5b505050506040513d6020811015610d8c57600080fd5b5051905088600080806060610da08861277a565b935093509350935083610e61578460ff168f6001600160401b03167ff7b2e42d694eb1100184aae86d4245d9e46966100b1dc7e723275b98326854ac8a6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610e1a578181015183820152602001610e02565b50505050905090810190601f168015610e475780820380516001836020036101000a031916815260200191505b509250505060405180910390a35050505050505050611a7f565b8460ff168f6001600160401b03167f36afdaf439a8f43fe72135135d804ae620b37a474f0943b5b85f6788312cad4085604051808260ff1660ff16815260200191505060405180910390a360ff83166113ea5760ff85166000818152600560209081526040808320548151631182b87560e01b815260048101958652602481019283528651604482015286516001600160a01b03909216958695631182b875958d958a9593949093606490910192918601918190849084905b83811015610f32578181015183820152602001610f1a565b50505050905090810190601f168015610f5f5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015610f7f57600080fd5b505af192505050801561106357506040513d6000823e601f3d908101601f191682016040526020811015610fb257600080fd5b8101908080516040519392919084600160201b821115610fd157600080fd5b908301906020820185811115610fe657600080fd5b8251600160201b811182820188101715610fff57600080fd5b82525081516020918201929091019080838360005b8381101561102c578181015183820152602001611014565b50505050905090810190601f1680156110595780820380516001836020036101000a031916815260200191505b5060405250505060015b611375576040516000815260443d101561107f5750600061111a565b60046000803e60005160e01c6308c379a081146110a057600091505061111a565b60043d036004833e81513d60248201116001600160401b03821117156110cb5760009250505061111a565b80830180516001600160401b038111156110ec57600094505050505061111a565b8060208301013d860181111561110a5760009550505050505061111a565b601f01601f191660405250925050505b806111255750611237565b60ff871660009081526007602052604081205461115c916001600160401b039091169089906111579060029088610800565b61282a565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf948794849390840192918601918190849084905b838110156111f75781810151838201526020016111df565b50505050905090810190601f1680156112245780820380516001836020036101000a031916815260200191505b509250505060405180910390a250611370565b3d808015611261576040519150601f19603f3d011682016040523d82523d6000602084013e611266565b606091505b5060ff8716600090815260076020526040812054611299916001600160401b039091169089906111579060029088610800565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351948794849390840192918601918190849084905b8381101561133457818101518382015260200161131c565b50505050905090810190601f1680156113615780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b6113e4565b8051156113e25760ff87166000908152600760205260408120546113ae916001600160401b039091169089906111579060019086610800565b60ff8716600090815260076020526040902080546001600160401b038082166001011667ffffffffffffffff199091161790555b505b506119b8565b60ff83166001141561168e5760ff8516600081815260056020908152604080832054815163831d65d160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563831d65d1958d958a9593949093606490910192918601918190849084905b8381101561147457818101518382015260200161145c565b50505050905090810190601f1680156114a15780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156114c157600080fd5b505af19250505080156114d2575060015b6113e4576040516000815260443d10156114ee57506000611589565b60046000803e60005160e01c6308c379a0811461150f576000915050611589565b60043d036004833e81513d60248201116001600160401b038211171561153a57600092505050611589565b80830180516001600160401b0381111561155b576000945050505050611589565b8060208301013d860181111561157957600095505050505050611589565b601f01601f191660405250925050505b8061159457506115f9565b60408051602080825283518183015283516001600160a01b038616937ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf93869390928392830191850190808383600083156111f75781810151838201526020016111df565b3d808015611623576040519150601f19603f3d011682016040523d82523d6000602084013e611628565b606091505b5060408051602080825283518183015283516001600160a01b038616937f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351938693909283928301918501908083836000831561133457818101518382015260200161131c565b60ff8316600214156119b85760ff8516600081815260056020908152604080832054815163c8509d8160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563c8509d81958d958a9593949093606490910192918601918190849084905b83811015611718578181015183820152602001611700565b50505050905090810190601f1680156117455780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561176557600080fd5b505af1925050508015611776575060015b6119b6576040516000815260443d10156117925750600061182d565b60046000803e60005160e01c6308c379a081146117b357600091505061182d565b60043d036004833e81513d60248201116001600160401b03821117156117de5760009250505061182d565b80830180516001600160401b038111156117ff57600094505050505061182d565b8060208301013d860181111561181d5760009550505050505061182d565b601f01601f191660405250925050505b8061183857506118e1565b816001600160a01b03167ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf826040518080602001828103825283818151815260200191508051906020019080838360005b838110156118a1578181015183820152602001611889565b50505050905090810190601f1680156118ce5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2506119b6565b3d80801561190b576040519150601f19603f3d011682016040523d82523d6000602084013e611910565b606091505b50816001600160a01b03167f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351826040518080602001828103825283818151815260200191508051906020019080838360005b8381101561197a578181015183820152602001611962565b50505050905090810190601f1680156119a75780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b505b60ff80861660009081526009602052604090205461100591636f93d2e69189913391879116806119ea575060ff881615155b604080516001600160e01b031960e088901b1681526001600160a01b039586166004820152939094166024840152604483019190915215156064820152905160848083019260209291908290030181600087803b158015611a4a57600080fd5b505af1158015611a5e573d6000803e3d6000fd5b505050506040513d6020811015611a7457600080fd5b505050505050505050505b505050505050505050505050565b630100380081565b600981565b61100781565b61100681565b60005460ff1681565b3361100714611aef5760405162461bcd60e51b815260040180806020018281038252602e815260200180612b22602e913960400191505060405180910390fd5b611b5884848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526012815271626174636853697a65466f724f7261636c6560701b602082015291506129809050565b15611bf357604080516020601f8401819004810282018101909252828152600091611b9b91858580838501838280828437600092019190915250612a6792505050565b90506127108111158015611bb05750600a8110155b611beb5760405162461bcd60e51b8152600401808060200182810382526032815260200180612b9a6032913960400191505060405180910390fd5b600155611fbf565b611c5c84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601281527118591913dc955c19185d1950da185b9b995b60721b602082015291506129809050565b15611de457606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060169091149050611cdf5760405162461bcd60e51b815260040180806020018281038252605a815260200180612ac8605a913960600191505060405180910390fd5b60018101516002820151601683015160ff82161590611cfd81612a6c565b611d4e576040805162461bcd60e51b815260206004820152601960248201527f61646472657373206973206e6f74206120636f6e747261637400000000000000604482015290519081900360640190fd5b60ff8416600081815260056020908152604080832080546001600160a01b0319166001600160a01b038716908117909155808452600683528184208585528352818420805460ff199081166001179091556009909352818420805490931687151517909255519092917f7e3b6af43092577ee20e60eaa1d9b114a7031305c895ee7dd3ffe17196d2e1e091a35050505050611fbf565b611e5184848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526016815275195b98589b1953dc911a5cd8589b1950da185b9b995b60521b602082015291506129809050565b15611f8257606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060029091149050611ed45760405162461bcd60e51b815260040180806020018281038252604a815260200180612b50604a913960600191505060405180910390fd5b600181810151600283015160ff80831660009081526005602052604090205492939192908316909114906001600160a01b03168015611f78576001600160a01b038116600090815260066020908152604080832060ff881680855290835292819020805460ff1916861515908117909155815190815290517fa3132e3f9819fbddc7f0ed6d38d7feef59aa95112090b7c592f5cb5bc4aa4adc929181900390910190a25b5050505050611fbf565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b6008602052600090815260409020546001600160401b031681565b61100281565b600660209081526000928352604080842090915290825290205460ff1681565b6040518060400160405280600381526020016269626360e81b81525081565b61100381565b60005460ff161561210f576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b7f1471eb6eb2c5e789fc3de43f8ce62938c7d1836ec861730447e2ada8fd81017b80546001600160a01b0319908116611008179091557f92e85d02570a8092d09a6e3a57665bc3815a2699a4074001bf1ccabf660f5a36805460ff199081169091557fd8af288fc1c8680b4f4706064cf021e264efb6828fcaf7eb5ca36818eb365bcc8054821660019081179091557f89832631fb3c3307a103ba2c84ab569c64d6182a18893dcd163f0f1c2090733a805484166110049081179091557f6cde3cea4b3a3fb2488b2808bae7556f4a405e50f65e1794383bc026131b13c38054841690557f72e4efa1513b071517c6c74dba31b5934a81aa83cddd400e7081df5529c9943680548416831790557fa9bc9a3a348c357ba16b37005d7e6b3236198c0e939f4af8c5f19b8deeb8ebc08054851690911790557fc575c31fea594a6eb97c8e9d3f9caee4c16218c6ef37e923234c0fe9014a61e78054831690557f4e523af77f034e9810f1c94057f5e931fb3d16a51511a4c3add793617d18610580548316821790557ffb33122aa9f93cc639ebe80a7bc4784c11e6053dde89c6f4f7e268c6a623da1e805484166110001790557fc7694af312c4f286114180fd0ba6a52461fcee8a381636770b19a343af92538a80548316821790557f01112dd68e482ba8d68a7e828cff8b3abcea08eab88941953c180a7e650e9cd480548316821790557fc0a4a8be475dfebc377ebef2d7c4ff47656f572a08dd92b81017efcdba0febe1805484166110071790557f87e8a52529e8ece4ef759037313542a6429ff494a9fab9027fb79db90124eba680548316821790557f4c7666bbcb22d46469f7cc282f70764a7012dca2cce630ff8d83db9a9cdd48f080548316821790557f40f28f99a40bc9f6beea1013afdbc3cdcc689eb76b82c4de06c0acf1e1932ed58054909316611001179092557f0d9cf2cd531699eed8dd34e40ff2884a14a698c4898184fba85194e6f6772d248054821683179055600b60009081527f23f68c9bd22b8a93d06adabe17481c87c016bcbd20adc8bfd707a4d813a572176020527fdf0d5d05428057f5455c2dc8e810dd86d1e9350faa72f16bda8a45443c5b39328054831684179055603283556004805467ffffffffffffffff19166001600160401b031790556002819055600381905580549091169091179055565b6007602052600090815260409020546001600160401b031681565b60005460ff166124dc576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b33600090815260066020908152604080832060ff80891685529252909120548591166125395760405162461bcd60e51b8152600401808060200182810382526031815260200180612a976031913960400191505060405180910390fd5b60ff85166000908152600760209081526040808320548151601f88018490048402810184019092528682526001600160401b03169261259e9284928a9261115792909189918c908c908190840183828082843760009201919091525061080092505050565b60ff959095166000908152600760205260409020805467ffffffffffffffff191660019096016001600160401b03169590951790945550505050565b61100081565b600381565b61100481565b8051602090910191565b5b60208110612615578251825260209283019290910190601f19016125f6565b915181516020939093036101000a6000190180199091169216919091179052565b60408051600e808252818301909252606091630100380060ff851617918391602082018180368337505050600e818101969096526006810192909252509283525090919050565b60008561268c57506000612771565b606082518451865160800101016040519080825280601f01601f1916602001820160405280156126c3576020820181803683370190505b50905060006126d182612a72565b6020808901518252019050866000806126e9896125eb565b80865260209095019490925090506127028285836125f5565b9283019261270f886125eb565b80865260209095019490925090506127288285836125f5565b9283018a81526020019261273b876125eb565b909250905061274b8285836125f5565b508351602001612759612a78565b60208183886065600019fa5051600114955050505050505b95945050505050565b600080600060606021855110156127aa575050604080516000808252602082019092529092508291508190612823565b600185015160218601518651604080516020198301808252601f19600119909401939093168101602001909152604189019392916060919080156127f5576020820181803683370190505b5090506000612803826125eb565b509050612815858260218d51036125f5565b506001975091955093509150505b9193509193565b600254431115612869576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b1617909155600355436002556128aa565b600380546001908101918290555410156128aa576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003555b8160ff16836001600160401b0316600460009054906101000a900460070b6001600160401b03167f3a6e0fc61675aa2a100bcba0568368bb92bcec91c97673391074f11138f0cffe603885604051808361ffff1661ffff16815260200180602001828103825283818151815260200191508051906020019080838360005b83811015612940578181015183820152602001612928565b50505050905090810190601f16801561296d5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a4505050565b6000816040516020018082805190602001908083835b602083106129b55780518252601f199092019160209182019101612996565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310612a235780518252601f199092019160209182019101612a04565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b3b151590565b60200190565b6040518060200160405280600190602082028036833750919291505056fe74686520636f6e747261637420616e64206368616e6e656c2068617665206e6f74206265656e20726567697374657265646c656e677468206f662076616c756520666f72206164644f725570646174654368616e6e656c2073686f756c642062652032322c206368616e6e656c49643a697346726f6d53797374656d3a68616e646c657241646472657373746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f7220656e61626c654f7244697361626c654368616e6e656c2073686f756c6420626520322c206368616e6e656c49643a6973456e61626c65746865206e6577426174636853697a65466f724f7261636c652073686f756c6420626520696e205b31302c2031303030305d6c6967687420636c69656e74206e6f742073796e632074686520626c6f636b20796574a264697066735822122083f6194f9a326fa5963aa39ffe11dcd28d1421a9f74fbe97a97f4853026e29ff64736f6c63430006040033" - }, - "b005741528b86F5952469d80A8614591E3c5B632": { - "balance": "0x1b1ae4d6e2ef500000" - }, - "446AA6E0DC65690403dF3F127750da1322941F3e": { - "balance": "0x1b1ae4d6e2ef500000" - } + "0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE": { + "balance": "0x0" + }, + "0x0000000000000000000000000000000000001000": { + "balance": "0x0", + "code": "0x60806040526004361061027d5760003560e01c80639dc092621161014f578063c8509d81116100c1578063eb57e2021161007a578063eb57e20214610940578063eda5868c14610973578063f340fa0114610988578063f9a2bbc7146109ae578063fc3e5908146109c3578063fd6a6879146109d85761027d565b8063c8509d8114610609578063d86222d5146108d7578063daacdb66146108ec578063dc927faf14610901578063e086c7b114610916578063e1c7392a1461092b5761027d565b8063ab51bb9611610113578063ab51bb961461074a578063ac4317511461075f578063ad3c9da61461082a578063b7ab4db51461085d578063bf9f49951461041b578063c81b1662146108c25761027d565b80639dc09262146106cd578063a1a11bf5146106e2578063a5422d5c146106f7578063a78abc161461070c578063aaf5eb68146107355761027d565b80635667515a116101f35780637942fd05116101ac5780637942fd05146105df57806381650b62146105f4578063831d65d114610609578063853230aa1461068e57806386249882146106a357806396713da9146106b85761027d565b80635667515a146105005780635d77156c146105155780636969a25c1461052a5780636e47b482146105a057806370fd5bad146105b557806375d47a0a146105ca5761027d565b80633dffc387116102455780633dffc3871461041b57806343756e5c14610446578063493279b1146104775780634bf6c882146104a357806351e80672146104b8578063565c56b3146104cd5761027d565b80630bee7a67146102825780631182b875146102b05780631ff18069146103aa578063219f22d5146103d157806335409f7f146103e6575b600080fd5b34801561028e57600080fd5b506102976109ed565b6040805163ffffffff9092168252519081900360200190f35b3480156102bc57600080fd5b50610335600480360360408110156102d357600080fd5b60ff8235169190810190604081016020820135600160201b8111156102f757600080fd5b82018360208201111561030957600080fd5b803590602001918460018302840111600160201b8311171561032a57600080fd5b5090925090506109f2565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561036f578181015183820152602001610357565b50505050905090810190601f16801561039c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103b657600080fd5b506103bf610bdf565b60408051918252519081900360200190f35b3480156103dd57600080fd5b50610297610be5565b3480156103f257600080fd5b506104196004803603602081101561040957600080fd5b50356001600160a01b0316610bea565b005b34801561042757600080fd5b50610430610efe565b6040805160ff9092168252519081900360200190f35b34801561045257600080fd5b5061045b610f03565b604080516001600160a01b039092168252519081900360200190f35b34801561048357600080fd5b5061048c610f09565b6040805161ffff9092168252519081900360200190f35b3480156104af57600080fd5b50610430610f0e565b3480156104c457600080fd5b5061045b610f13565b3480156104d957600080fd5b506103bf600480360360208110156104f057600080fd5b50356001600160a01b0316610f19565b34801561050c57600080fd5b50610430610f6b565b34801561052157600080fd5b50610297610f70565b34801561053657600080fd5b506105546004803603602081101561054d57600080fd5b5035610f75565b604080516001600160a01b039788168152958716602087015293909516848401526001600160401b0390911660608401521515608083015260a082019290925290519081900360c00190f35b3480156105ac57600080fd5b5061045b610fd9565b3480156105c157600080fd5b50610430610fdf565b3480156105d657600080fd5b5061045b610fe4565b3480156105eb57600080fd5b50610430610fea565b34801561060057600080fd5b50610297610fef565b34801561061557600080fd5b506104196004803603604081101561062c57600080fd5b60ff8235169190810190604081016020820135600160201b81111561065057600080fd5b82018360208201111561066257600080fd5b803590602001918460018302840111600160201b8311171561068357600080fd5b509092509050610ff4565b34801561069a57600080fd5b506103bf6110a7565b3480156106af57600080fd5b506103bf6110ad565b3480156106c457600080fd5b506104306110b3565b3480156106d957600080fd5b5061045b6110b8565b3480156106ee57600080fd5b5061045b6110be565b34801561070357600080fd5b506103356110c4565b34801561071857600080fd5b506107216110e3565b604080519115158252519081900360200190f35b34801561074157600080fd5b506103bf6110ec565b34801561075657600080fd5b50610297610f6b565b34801561076b57600080fd5b506104196004803603604081101561078257600080fd5b810190602081018135600160201b81111561079c57600080fd5b8201836020820111156107ae57600080fd5b803590602001918460018302840111600160201b831117156107cf57600080fd5b919390929091602081019035600160201b8111156107ec57600080fd5b8201836020820111156107fe57600080fd5b803590602001918460018302840111600160201b8311171561081f57600080fd5b5090925090506110f5565b34801561083657600080fd5b506103bf6004803603602081101561084d57600080fd5b50356001600160a01b031661139c565b34801561086957600080fd5b506108726113ae565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156108ae578181015183820152602001610896565b505050509050019250505060405180910390f35b3480156108ce57600080fd5b5061045b6114d4565b3480156108e357600080fd5b506103bf6114da565b3480156108f857600080fd5b506103bf6114e6565b34801561090d57600080fd5b5061045b6114ec565b34801561092257600080fd5b506103bf6114f2565b34801561093757600080fd5b506104196114f7565b34801561094c57600080fd5b506104196004803603602081101561096357600080fd5b50356001600160a01b03166116fa565b34801561097f57600080fd5b506102976118c9565b6104196004803603602081101561099e57600080fd5b50356001600160a01b03166118ce565b3480156109ba57600080fd5b5061045b611b04565b3480156109cf57600080fd5b50610430611b0a565b3480156109e457600080fd5b5061045b611b0f565b606481565b60005460609060ff16610a48576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b3361200014610a885760405162461bcd60e51b815260040180806020018281038252602f815260200180614516602f913960400191505060405180910390fd5b610a90613d69565b6000610ad185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611b1592505050565b9150915080610aed57610ae46064611c6e565b92505050610bd8565b815160009060ff16610b0d57610b068360200151611ccf565b9050610ba4565b825160ff1660011415610ba057826020015151600114610b7a577f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2604051808060200182810382526025815260200180613e6c6025913960400191505060405180910390a1506067610b9b565b610b068360200151600081518110610b8e57fe5b6020026020010151612ad5565b610ba4565b5060655b63ffffffff8116610bc95750506040805160008152602081019091529150610bd89050565b610bd281611c6e565b93505050505b9392505050565b60035481565b606881565b3361100114610c2a5760405162461bcd60e51b81526004018080602001828103825260298152602001806145726029913960400191505060405180910390fd5b6001600160a01b03811660009081526004602052604090205480610c4e5750610efb565b600181039050600060018281548110610c6357fe5b60009182526020909120600360049092020101546001549091506000190180610cb257600060018481548110610c9557fe5b906000526020600020906004020160030181905550505050610efb565b6040805183815290516001600160a01b038616917f3b6f9ef90462b512a1293ecec018670bf7b7f1876fb727590a8a6d7643130a70919081900360200190a26001600160a01b038416600090815260046020526040812055600154600019018314610e3457600180546000198101908110610d2957fe5b906000526020600020906004020160018481548110610d4457fe5b6000918252602082208354600492830290910180546001600160a01b03199081166001600160a01b0393841617825560018087015481840180548416918616919091179055600280880180549185018054909416919095161780835584546001600160401b03600160a01b91829004160267ffffffffffffffff60a01b1990911617808355935460ff600160e01b918290041615150260ff60e01b199094169390931790556003948501549401939093558254868401939192919087908110610e0957fe5b600091825260208083206004909202909101546001600160a01b031683528201929092526040019020555b6001805480610e3f57fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b03191690556003018190559155818381610e9257fe5b0490508015610ef65760015460005b81811015610ef3578260018281548110610eb757fe5b9060005260206000209060040201600301540160018281548110610ed757fe5b6000918252602090912060036004909202010155600101610ea1565b50505b505050505b50565b600181565b61100181565b603881565b600881565b61200081565b6001600160a01b03811660009081526004602052604081205480610f41576000915050610f66565b600180820381548110610f5057fe5b9060005260206000209060040201600301549150505b919050565b600081565b606781565b60018181548110610f8257fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b0392831694509082169291821691600160a01b81046001600160401b031691600160e01b90910460ff169086565b61100581565b600281565b61100881565b600b81565b606681565b33612000146110345760405162461bcd60e51b815260040180806020018281038252602f815260200180614516602f913960400191505060405180910390fd5b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a1505050565b6103e881565b60025481565b600981565b61100781565b61100681565b6040518061062001604052806105ef8152602001613f276105ef913981565b60005460ff1681565b6402540be40081565b60005460ff16611148576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b33611007146111885760405162461bcd60e51b815260040180806020018281038252602e815260200180613e91602e913960400191505060405180910390fd5b6111f284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526013815272065787069726554696d655365636f6e6447617606c1b60208201529150612c4c9050565b156112cd57602081146112365760405162461bcd60e51b8152600401808060200182810382526026815260200180613ee06026913960400191505060405180910390fd5b604080516020601f840181900481028201810190925282815260009161127491858580838501838280828437600092019190915250612d3492505050565b90506064811015801561128a5750620186a08111155b6112c55760405162461bcd60e51b8152600401808060200182810382526027815260200180613e456027913960400191505060405180910390fd5b60025561130a565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b60046020526000908152604090205481565b6001546060906000805b828110156113ff57600181815481106113cd57fe5b9060005260206000209060040201600201601c9054906101000a900460ff166113f7576001909101905b6001016113b8565b5060608160405190808252806020026020018201604052801561142c578160200160208202803683370190505b50600092509050815b838110156114cc576001818154811061144a57fe5b9060005260206000209060040201600201601c9054906101000a900460ff166114c4576001818154811061147a57fe5b600091825260209091206004909102015482516001600160a01b03909116908390859081106114a557fe5b6001600160a01b03909216602092830291909101909101526001909201915b600101611435565b509250505090565b61100281565b67016345785d8a000081565b60055481565b61100381565b602981565b60005460ff161561154f576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b611557613d69565b600061157d6040518061062001604052806105ef8152602001613f276105ef9139611b15565b91509150806115bd5760405162461bcd60e51b8152600401808060200182810382526021815260200180613f066021913960400191505060405180910390fd5b60005b8260200151518110156116e2576001836020015182815181106115df57fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782558587015182850180549185169183169190911790556040860151600283018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590981692909516919091179290921694909417161790915560a0909301516003909301929092559186015180519185019391859081106116b557fe5b602090810291909101810151516001600160a01b03168252810191909152604001600020556001016115c0565b50506103e8600255506000805460ff19166001179055565b336110011461173a5760405162461bcd60e51b81526004018080602001828103825260298152602001806145726029913960400191505060405180910390fd5b6001600160a01b0381166000908152600460205260409020548061175e5750610efb565b60018103905060006001828154811061177357fe5b906000526020600020906004020160030154905060006001838154811061179657fe5b906000526020600020906004020160030181905550600060018080549050039050836001600160a01b03167f8cd4e147d8af98a9e3b6724021b8bf6aed2e5dac71c38f2dce8161b82585b25d836040518082815260200191505060405180910390a28061180557505050610efb565b600081838161181057fe5b0490508015610ef65760005b8481101561186e57816001828154811061183257fe5b906000526020600020906004020160030154016001828154811061185257fe5b600091825260209091206003600490920201015560010161181c565b50600180549085015b81811015610ef357826001828154811061188d57fe5b90600052602060002090600402016003015401600182815481106118ad57fe5b6000918252602090912060036004909202010155600101611877565b606581565b33411461190c5760405162461bcd60e51b815260040180806020018281038252602d815260200180614545602d913960400191505060405180910390fd5b60005460ff1661195f576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b600034116119ac576040805162461bcd60e51b81526020600482015260156024820152746465706f7369742076616c7565206973207a65726f60581b604482015290519081900360640190fd5b6001600160a01b03811660009081526004602052604090205434908015611abf5760006001808303815481106119de57fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff1615611a49576040805184815290516001600160a01b038616917ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b4919081900360200190a2611ab9565b600354611a5c908463ffffffff612d3916565b6003908155810154611a74908463ffffffff612d3916565b60038201556040805184815290516001600160a01b038616917f93a090ecc682c002995fad3c85b30c5651d7fd29b0be5da9d784a3302aedc055919081900360200190a25b50611aff565b6040805183815290516001600160a01b038516917ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b4919081900360200190a25b505050565b61100081565b600381565b61100481565b611b1d613d69565b6000611b27613d69565b611b2f613d81565b611b40611b3b86612d93565b612db8565b90506000805b611b4f83612e02565b15611c605780611b7457611b6a611b6584612e23565b612e71565b60ff168452611c58565b8060011415611c53576060611b90611b8b85612e23565b612f28565b90508051604051908082528060200260200182016040528015611bcd57816020015b611bba613da1565b815260200190600190039081611bb25790505b50602086015260005b8151811015611c4857611be7613da1565b6000611c05848481518110611bf857fe5b6020026020010151612ff9565b9150915080611c2257876000995099505050505050505050611c69565b8188602001518481518110611c3357fe5b60209081029190910101525050600101611bd6565b506001925050611c58565b611c60565b600101611b46565b50919350909150505b915091565b604080516001808252818301909252606091829190816020015b6060815260200190600190039081611c88579050509050611cae8363ffffffff166130d6565b81600081518110611cbb57fe5b6020026020010181905250610bd8816130e9565b6000806060611cdd84613173565b9150915081611d8a577f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2816040518080602001828103825283818151815260200191508051906020019080838360005b83811015611d45578181015183820152602001611d2d565b50505050905090810190601f168015611d725780820380516001836020036101000a031916815260200191505b509250505060405180910390a1606692505050610f66565b600080805b600154811015611e075767016345785d8a000060018281548110611daf57fe5b90600052602060002090600402016003015410611dd157600190920191611dff565b600060018281548110611de057fe5b9060005260206000209060040201600301541115611dff576001909101905b600101611d8f565b50606082604051908082528060200260200182016040528015611e34578160200160208202803683370190505b509050606083604051908082528060200260200182016040528015611e63578160200160208202803683370190505b509050606084604051908082528060200260200182016040528015611e92578160200160208202803683370190505b509050606085604051908082528060200260200182016040528015611ec1578160200160208202803683370190505b5090506000606086604051908082528060200260200182016040528015611ef2578160200160208202803683370190505b509050606087604051908082528060200260200182016040528015611f21578160200160208202803683370190505b509050600098506000975060608d905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b158015611f6e57600080fd5b505afa158015611f82573d6000803e3d6000fd5b505050506040513d6020811015611f9857600080fd5b5051905067016345785d8a000081111561200d577f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2604051808060200182810382526021815260200180613ebf6021913960400191505060405180910390a160689d5050505050505050505050505050610f66565b60005b6001548110156122805767016345785d8a00006001828154811061203057fe5b906000526020600020906004020160030154106121b6576001818154811061205457fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b03168a8d8151811061208557fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060006402540be400600183815481106120ba57fe5b906000526020600020906004020160030154816120d357fe5b06600183815481106120e157fe5b906000526020600020906004020160030154039050612109838261325590919063ffffffff16565b8a8e8151811061211557fe5b6020026020010181815250506001828154811061212e57fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316888e8151811061215f57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505081898e8151811061218c57fe5b60209081029190910101526121a7878263ffffffff612d3916565b6001909d019c96506122789050565b6000600182815481106121c557fe5b906000526020600020906004020160030154111561227857600181815481106121ea57fe5b906000526020600020906004020160010160009054906101000a90046001600160a01b0316858c8151811061221b57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506001818154811061224857fe5b906000526020600020906004020160030154848c8151811061226657fe5b60209081029190910101526001909a01995b600101612010565b50600085156126be576110046001600160a01b0316636e056520878c8c8b60025442016040518663ffffffff1660e01b815260040180806020018060200180602001856001600160401b03166001600160401b03168152602001848103845288818151815260200191508051906020019060200280838360005b838110156123125781810151838201526020016122fa565b50505050905001848103835287818151815260200191508051906020019060200280838360005b83811015612351578181015183820152602001612339565b50505050905001848103825286818151815260200191508051906020019060200280838360005b83811015612390578181015183820152602001612378565b505050509050019750505050505050506020604051808303818588803b1580156123b957600080fd5b505af1935050505080156123df57506040513d60208110156123da57600080fd5b505160015b61261a576040516000815260443d10156123fb57506000612496565b60046000803e60005160e01c6308c379a0811461241c576000915050612496565b60043d036004833e81513d60248201116001600160401b038211171561244757600092505050612496565b80830180516001600160401b03811115612468576000945050505050612496565b8060208301013d860181111561248657600095505050505050612496565b601f01601f191660405250925050505b806124a15750612545565b60019150867fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf280826040518080602001828103825283818151815260200191508051906020019080838360005b838110156125055781810151838201526020016124ed565b50505050905090810190601f1680156125325780820380516001836020036101000a031916815260200191505b509250505060405180910390a250612615565b3d80801561256f576040519150601f19603f3d011682016040523d82523d6000602084013e612574565b606091505b5060019150867fbfa884552dd8921b6ce90bfe906952ae5b3b29be0cc1a951d4f62697635a3a45826040518080602001828103825283818151815260200191508051906020019080838360005b838110156125d95781810151838201526020016125c1565b50505050905090810190601f1680156126065780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b6126be565b8015612658576040805188815290517fa217d08e65f80c73121cd9db834d81652d544bfbf452f6d04922b16c90a37b709181900360200190a16126bc565b604080516020808252601b908201527f6261746368207472616e736665722072657475726e2066616c7365000000000081830152905188917fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf280919081900360600190a25b505b80156128745760005b88518110156128725760008982815181106126de57fe5b602002602001015190506000600182815481106126f757fe5b60009182526020909120600160049092020181015481546001600160a01b03909116916108fc918590811061272857fe5b9060005260206000209060040201600301549081150290604051600060405180830381858888f19350505050905080156127e4576001828154811061276957fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d91859081106127b857fe5b9060005260206000209060040201600301546040518082815260200191505060405180910390a2612868565b600182815481106127f157fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d918590811061284057fe5b9060005260206000209060040201600301546040518082815260200191505060405180910390a25b50506001016126c7565b505b8451156129be5760005b85518110156129bc57600086828151811061289557fe5b60200260200101516001600160a01b03166108fc8784815181106128b557fe5b60200260200101519081150290604051600060405180830381858888f193505050509050801561294b578682815181106128eb57fe5b60200260200101516001600160a01b03167f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d87848151811061292957fe5b60200260200101516040518082815260200191505060405180910390a26129b3565b86828151811061295757fe5b60200260200101516001600160a01b03167f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d87848151811061299557fe5b60200260200101516040518082815260200191505060405180910390a25b5060010161287e565b505b4715612a27576040805147815290517f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d9181900360200190a1604051611002904780156108fc02916000818181858888f19350505050158015612a25573d6000803e3d6000fd5b505b60006003819055600555825115612a4157612a4183613297565b6110016001600160a01b031663fc4333cd6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612a7e57600080fd5b505af1158015612a92573d6000803e3d6000fd5b50506040517fedd8d7296956dd970ab4de3f2fc03be2b0ffc615d20cd4c72c6e44f928630ebf925060009150a15060009f9e505050505050505050505050505050565b80516001600160a01b0316600090815260046020526040812054801580612b265750600180820381548110612b0657fe5b9060005260206000209060040201600201601c9054906101000a900460ff165b15612b6c5782516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a26000915050610f66565b600154600554600019820111801590612bc25784516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a260009350505050610f66565b600580546001908101909155805481906000198601908110612be057fe5b6000918252602082206002600490920201018054921515600160e01b0260ff60e01b199093169290921790915585516040516001600160a01b03909116917ff226e7d8f547ff903d9d419cf5f54e0d7d07efa9584135a53a057c5f1f27f49a91a2506000949350505050565b6000816040516020018082805190602001908083835b60208310612c815780518252601f199092019160209182019101612c62565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310612cef5780518252601f199092019160209182019101612cd0565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490505b92915050565b015190565b600082820183811015610bd8576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b612d9b613dd6565b506040805180820190915281518152602082810190820152919050565b612dc0613d81565b612dc98261375e565b612dd257600080fd5b6000612de18360200151613798565b60208085015160408051808201909152868152920190820152915050919050565b6000612e0c613dd6565b505080518051602091820151919092015191011190565b612e2b613dd6565b612e3482612e02565b612e3d57600080fd5b60208201516000612e4d826137fb565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590612e8657508151602110155b612e8f57600080fd5b6000612e9e8360200151613798565b90508083600001511015612ef9576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b825160208085015183018051928490039291831015612f1f57826020036101000a820491505b50949350505050565b6060612f338261375e565b612f3c57600080fd5b6000612f478361392e565b9050606081604051908082528060200260200182016040528015612f8557816020015b612f72613dd6565b815260200190600190039081612f6a5790505b5090506000612f978560200151613798565b60208601510190506000805b84811015612fee57612fb4836137fb565b9150604051806040016040528083815260200184815250848281518110612fd757fe5b602090810291909101015291810191600101612fa3565b509195945050505050565b613001613da1565b600061300b613da1565b613013613d81565b61301c85612db8565b90506000805b61302b83612e02565b15611c6057806130565761304661304184612e23565b61398a565b6001600160a01b031684526130ce565b806001141561307e5761306b61304184612e23565b6001600160a01b031660208501526130ce565b80600214156130a65761309361304184612e23565b6001600160a01b031660408501526130ce565b8060031415611c53576130bb611b6584612e23565b6001600160401b03166060850152600191505b600101613022565b6060612d2e6130e4836139a4565b613a8a565b606081516000141561310a5750604080516000815260208101909152610f66565b60608260008151811061311957fe5b602002602001015190506000600190505b835181101561315a576131508285838151811061314357fe5b6020026020010151613adc565b915060010161312a565b50610bd861316d825160c060ff16613b59565b82613adc565b600060606029835111156131a5576000604051806060016040528060298152602001613df16029913991509150611c69565b60005b835181101561323b5760005b81811015613232578481815181106131c857fe5b6020026020010151600001516001600160a01b03168583815181106131e957fe5b6020026020010151600001516001600160a01b0316141561322a5760006040518060600160405280602b8152602001613e1a602b9139935093505050611c69565b6001016131b4565b506001016131a8565b505060408051602081019091526000815260019150915091565b6000610bd883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613c51565b600154815160005b828110156133b45760016132b1613da1565b600183815481106132be57fe5b600091825260208083206040805160c08101825260049490940290910180546001600160a01b0390811685526001820154811693850193909352600281015492831691840191909152600160a01b82046001600160401b03166060840152600160e01b90910460ff16151560808301526003015460a082015291505b848110156133885786818151811061334e57fe5b6020026020010151600001516001600160a01b031682600001516001600160a01b031614156133805760009250613388565b60010161333a565b5081156133aa5780516001600160a01b03166000908152600460205260408120555b505060010161329f565b508082111561342957805b828110156134275760018054806133d257fe5b60008281526020812060046000199093019283020180546001600160a01b03199081168255600182810180549092169091556002820180546001600160e81b03191690556003909101919091559155016133bf565b505b6000818310613438578161343a565b825b905060005b81811015613634576134ec85828151811061345657fe5b60200260200101516001838154811061346b57fe5b60009182526020918290206040805160c08101825260049390930290910180546001600160a01b0390811684526001820154811694840194909452600281015493841691830191909152600160a01b83046001600160401b03166060830152600160e01b90920460ff161515608082015260039091015460a0820152613ce8565b61360757806001016004600087848151811061350457fe5b6020026020010151600001516001600160a01b03166001600160a01b031681526020019081526020016000208190555084818151811061354057fe5b60200260200101516001828154811061355557fe5b6000918252602091829020835160049092020180546001600160a01b039283166001600160a01b0319918216178255928401516001820180549184169185169190911790556040840151600282018054606087015160808801511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909716929097169190911792909216939093171692909217905560a09091015160039091015561362c565b60006001828154811061361657fe5b9060005260206000209060040201600301819055505b60010161343f565b508282111561375857825b82811015610ef657600185828151811061365557fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782559585015181840180549184169188169190911790556040850151600282018054606088015160808901511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590971692909a169190911792909216939093171695909517905560a0909201516003909301929092558751908401929088908590811061372b57fe5b602090810291909101810151516001600160a01b031682528101919091526040016000205560010161363f565b50505050565b805160009061376f57506000610f66565b6020820151805160001a9060c082101561378e57600092505050610f66565b5060019392505050565b8051600090811a60808110156137b2576000915050610f66565b60b88110806137cd575060c081108015906137cd575060f881105b156137dc576001915050610f66565b60c08110156137f05760b519019050610f66565b60f519019050610f66565b80516000908190811a60808110156138165760019150613927565b60b881101561382b57607e1981019150613927565b60c08110156138a557600060b78203600186019550806020036101000a86510491506001810182019350508083101561389f576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b50613927565b60f88110156138ba5760be1981019150613927565b600060f78203600186019550806020036101000a865104915060018101820193505080831015613925576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b805160009061393f57506000610f66565b600080905060006139538460200151613798565b602085015185519181019250015b8082101561398157613972826137fb565b60019093019290910190613961565b50909392505050565b805160009060151461399b57600080fd5b612d2e82612e71565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166139e857506018613a0c565b6fffffffffffffffffffffffffffffffff198416613a0857506010613a0c565b5060005b6020811015613a4257818181518110613a2157fe5b01602001516001600160f81b03191615613a3a57613a42565b600101613a0c565b60008160200390506060816040519080825280601f01601f191660200182016040528015613a77576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015613abc5750607f60f81b82600081518110613aaa57fe5b01602001516001600160f81b03191611155b15613ac8575080610f66565b612d2e613ada8351608060ff16613b59565b835b6060806040519050835180825260208201818101602087015b81831015613b0d578051835260209283019201613af5565b50855184518101855292509050808201602086015b81831015613b3a578051835260209283019201613b22565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310613ba9576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411613c035782840160f81b81600081518110613be557fe5b60200101906001600160f81b031916908160001a9053509050612d2e565b6060613c0e856139a4565b90508381510160370160f81b82600081518110613c2757fe5b60200101906001600160f81b031916908160001a905350613c488282613adc565b95945050505050565b60008184841115613ce05760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613ca5578181015183820152602001613c8d565b50505050905090810190601f168015613cd25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b805182516000916001600160a01b039182169116148015613d22575081602001516001600160a01b031683602001516001600160a01b0316145b8015613d47575081604001516001600160a01b031683604001516001600160a01b0316145b8015610bd85750506060908101519101516001600160401b0390811691161490565b60408051808201909152600081526060602082015290565b6040518060400160405280613d94613dd6565b8152602001600081525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b60405180604001604052806000815260200160008152509056fe746865206e756d626572206f662076616c696461746f72732065786365656420746865206c696d69746475706c696361746520636f6e73656e7375732061646472657373206f662076616c696461746f725365747468652065787069726554696d655365636f6e64476170206973206f7574206f662072616e67656c656e677468206f66206a61696c2076616c696461746f7273206d757374206265206f6e65746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374666565206973206c6172676572207468616e2044555354595f494e434f4d494e476c656e677468206f662065787069726554696d655365636f6e64476170206d69736d617463686661696c656420746f20706172736520696e69742076616c696461746f72536574f905ec80f905e8f846942a7cdd959bfe8d9487b2a43b33565295a698f7e294b6a7edd747c0554875d3fc531d19ba1497992c5e941ff80f3f7f110ffd8920a3ac38fdef318fe94a3f86048c27395000f846946488aa4d1955ee33403f8ccb1d4de5fb97c7ade294220f003d8bdfaadf52aa1e55ae4cc485e6794875941a87e90e440a39c99aa9cb5cea0ad6a3f0b2407b86048c27395000f846949ef9f4360c606c7ab4db26b016007d3ad0ab86a0946103af86a874b705854033438383c82575f25bc29418e2db06cbff3e3c5f856410a1838649e760175786048c27395000f84694ee01c3b1283aa067c58eab4709f85e99d46de5fe94ee4b9bfb1871c64e2bcabb1dc382dc8b7c4218a29415904ab26ab0e99d70b51c220ccdcccabee6e29786048c27395000f84694685b1ded8013785d6623cc18d214320b6bb6475994a20ef4e5e4e7e36258dbf51f4d905114cb1b34bc9413e39085dc88704f4394d35209a02b1a9520320c86048c27395000f8469478f3adfc719c99674c072166708589033e2d9afe9448a30d5eaa7b64492a160f139e2da2800ec3834e94055838358c29edf4dcc1ba1985ad58aedbb6be2b86048c27395000f84694c2be4ec20253b8642161bc3f444f53679c1f3d479466f50c616d737e60d7ca6311ff0d9c434197898a94d1d678a2506eeaa365056fe565df8bc8659f28b086048c27395000f846942f7be8361c80a4c1e7e9aaf001d0877f1cfde218945f93992ac37f3e61db2ef8a587a436a161fd210b94ecbc4fb1a97861344dad0867ca3cba2b860411f086048c27395000f84694ce2fd7544e0b2cc94692d4a704debef7bcb613289444abc67b4b2fba283c582387f54c9cba7c34bafa948acc2ab395ded08bb75ce85bf0f95ad2abc51ad586048c27395000f84694b8f7166496996a7da21cf1f1b04d9b3e26a3d077946770572763289aac606e4f327c2f6cc1aa3b3e3b94882d745ed97d4422ca8da1c22ec49d880c4c097286048c27395000f846942d4c407bbe49438ed859fe965b140dcf1aab71a9943ad0939e120f33518fbba04631afe7a3ed6327b194b2bbb170ca4e499a2b0f3cc85ebfa6e8c4dfcbea86048c27395000f846946bbad7cf34b5fa511d8e963dbba288b1960e75d694853b0f6c324d1f4e76c8266942337ac1b0af1a229442498946a51ca5924552ead6fc2af08b94fcba648601d1a94a2000f846944430b3230294d12c6ab2aac5c2cd68e80b16b581947b107f4976a252a6939b771202c28e64e03f52d694795811a7f214084116949fc4f53cedbf189eeab28601d1a94a2000f84694ea0a6e3c511bbd10f4519ece37dc24887e11b55d946811ca77acfb221a49393c193f3a22db829fcc8e9464feb7c04830dd9ace164fc5c52b3f5a29e5018a8601d1a94a2000f846947ae2f5b9e386cd1b50a4550696d957cb4900f03a94e83bcc5077e6b873995c24bac871b5ad856047e19464e48d4057a90b233e026c1041e6012ada897fe88601d1a94a2000f8469482012708dafc9e1b880fd083b32182b869be8e09948e5adc73a2d233a1b496ed3115464dd6c7b887509428b383d324bc9a37f4e276190796ba5a8947f5ed8601d1a94a2000f8469422b81f8e175ffde54d797fe11eb03f9e3bf75f1d94a1c3ef7ca38d8ba80cce3bfc53ebd2903ed21658942767f7447f7b9b70313d4147b795414aecea54718601d1a94a2000f8469468bf0b8b6fb4e317a0f9d6f03eaf8ce6675bc60d94675cfe570b7902623f47e7f59c9664b5f5065dcf94d84f0d2e50bcf00f2fc476e1c57f5ca2d57f625b8601d1a94a2000f846948c4d90829ce8f72d0163c1d5cf348a862d5506309485c42a7b34309bee2ed6a235f86d16f059deec5894cc2cedc53f0fa6d376336efb67e43d167169f3b78601d1a94a2000f8469435e7a025f4da968de7e4d7e4004197917f4070f194b1182abaeeb3b4d8eba7e6a4162eac7ace23d57394c4fd0d870da52e73de2dd8ded19fe3d26f43a1138601d1a94a2000f84694d6caa02bbebaebb5d7e581e4b66559e635f805ff94c07335cf083c1c46a487f0325769d88e163b653694efaff03b42e41f953a925fc43720e45fb61a19938601d1a94a2000746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d6573736167652073656e646572206d7573742062652074686520626c6f636b2070726f6475636572746865206d6573736167652073656e646572206d75737420626520736c61736820636f6e7472616374a2646970667358221220f4016eb3755efa2abde797b21f8695280d971b0fea37198122d2e5867516da0464736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001001": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106102275760003560e01c8063831d65d111610130578063c80d4b8f116100b8578063e1c7392a1161007c578063e1c7392a146106d9578063f9a2bbc7146106e1578063fc3e5908146106e9578063fc4333cd146106f1578063fd6a6879146106f957610227565b8063c80d4b8f14610623578063c81b16621461062b578063c8509d8114610633578063c96be4cb146106ab578063dc927faf146106d157610227565b8063a1a11bf5116100ff578063a1a11bf514610531578063a78abc1614610539578063ab51bb9614610555578063ac0af6291461055d578063ac4317511461056557610227565b8063831d65d11461049f57806396713da9146105195780639bc8e4f2146105215780639dc092621461052957610227565b80634bf6c882116101b35780636e47b482116101825780636e47b4821461047757806370fd5bad1461047f57806375d47a0a146104875780637912a65d1461048f5780637942fd051461049757610227565b80634bf6c8821461045757806351e806721461045f578063567a372d1461046757806362b72cf51461046f57610227565b806337c8dab9116101fa57806337c8dab9146103b9578063389f4f71146103f85780633dffc3871461041257806343756e5c14610430578063493279b11461043857610227565b80630bee7a671461022c5780631182b8751461024d57806323bac5a21461033a57806335aa2e4414610380575b600080fd5b610234610701565b6040805163ffffffff9092168252519081900360200190f35b6102c56004803603604081101561026357600080fd5b60ff8235169190810190604081016020820135600160201b81111561028757600080fd5b82018360208201111561029957600080fd5b803590602001918460018302840111600160201b831117156102ba57600080fd5b509092509050610706565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102ff5781810151838201526020016102e7565b50505050905090810190601f16801561032c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103606004803603602081101561035057600080fd5b50356001600160a01b03166107da565b604080519384526020840192909252151582820152519081900360600190f35b61039d6004803603602081101561039657600080fd5b50356107fd565b604080516001600160a01b039092168252519081900360200190f35b6103df600480360360208110156103cf57600080fd5b50356001600160a01b0316610824565b6040805192835260208301919091528051918290030190f35b61040061087b565b60408051918252519081900360200190f35b61041a610881565b6040805160ff9092168252519081900360200190f35b61039d610886565b61044061088c565b6040805161ffff9092168252519081900360200190f35b61041a610891565b61039d610896565b61040061089c565b6104006108a2565b61039d6108a8565b61041a6108ae565b61039d6108b3565b6104006108b9565b61041a6108be565b610517600480360360408110156104b557600080fd5b60ff8235169190810190604081016020820135600160201b8111156104d957600080fd5b8201836020820111156104eb57600080fd5b803590602001918460018302840111600160201b8311171561050c57600080fd5b5090925090506108c3565b005b61041a610a1e565b610400610a23565b61039d610a2e565b61039d610a34565b610541610a3a565b604080519115158252519081900360200190f35b610234610a43565b610400610a48565b6105176004803603604081101561057b57600080fd5b810190602081018135600160201b81111561059557600080fd5b8201836020820111156105a757600080fd5b803590602001918460018302840111600160201b831117156105c857600080fd5b919390929091602081019035600160201b8111156105e557600080fd5b8201836020820111156105f757600080fd5b803590602001918460018302840111600160201b8311171561061857600080fd5b509092509050610a4d565b610400610e3b565b61039d610e40565b6105176004803603604081101561064957600080fd5b60ff8235169190810190604081016020820135600160201b81111561066d57600080fd5b82018360208201111561067f57600080fd5b803590602001918460018302840111600160201b831117156106a057600080fd5b509092509050610e46565b610517600480360360208110156106c157600080fd5b50356001600160a01b0316610ef9565b61039d61131e565b610517611324565b61039d611395565b61041a61139b565b6105176113a0565b61039d61182b565b606481565b606033612000146107485760405162461bcd60e51b815260040180806020018281038252602f815260200180612282602f913960400191505060405180910390fd5b60005460ff1661078d576040805162461bcd60e51b815260206004820152601960248201526000805160206122de833981519152604482015290519081900360640190fd5b6040805162461bcd60e51b815260206004820152601e60248201527f7265636569766520756e65787065637465642073796e207061636b6167650000604482015290519081900360640190fd5b600260208190526000918252604090912080546001820154919092015460ff1683565b6001818154811061080a57fe5b6000918252602090912001546001600160a01b0316905081565b60008061082f612146565b5050506001600160a01b0316600090815260026020818152604092839020835160608101855281548082526001830154938201849052919093015460ff16151592909301919091529091565b60055481565b600181565b61100181565b603881565b600881565b61200081565b60045481565b60035481565b61100581565b600281565b61100881565b603281565b600b81565b33612000146109035760405162461bcd60e51b815260040180806020018281038252602f815260200180612282602f913960400191505060405180910390fd5b60005460ff16610948576040805162461bcd60e51b815260206004820152601960248201526000805160206122de833981519152604482015290519081900360640190fd5b610950612169565b600061099184848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061183192505050565b9150915080156109db5781516040805163ffffffff9092168252517f7f0956d47419b9525356e7111652b653b530ec6f5096dccc04589bc38e6299679181900360200190a1610a17565b81516040805163ffffffff9092168252517f7d45f62d17443dd4547bca8a8112c60e2385669318dc300ec61a5d2492f262e79181900360200190a15b5050505050565b600981565b662386f26fc1000081565b61100781565b61100681565b60005460ff1681565b600081565b600481565b60005460ff16610a92576040805162461bcd60e51b815260206004820152601960248201526000805160206122de833981519152604482015290519081900360640190fd5b3361100714610ad25760405162461bcd60e51b815260040180806020018281038252602e81526020018061220d602e913960400191505060405180910390fd5b610b3d84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260148152731b5a5cd9195b59585b9bdc951a1c995cda1bdb1960621b602082015291506118b19050565b15610c165760208114610b815760405162461bcd60e51b81526004018080602001828103825260278152602001806121b66027913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610bbf9185858083850183828082843760009201919091525061199992505050565b905060018110158015610bd3575060055481105b610c0e5760405162461bcd60e51b815260040180806020018281038252602581526020018061225d6025913960400191505060405180910390fd5b600455610da9565b610c7c84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e19995b1bdb9e551a1c995cda1bdb19608a1b602082015291506118b19050565b15610d6c5760208114610cc05760405162461bcd60e51b815260040180806020018281038252602281526020018061223b6022913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610cfe9185858083850183828082843760009201919091525061199992505050565b90506103e88111158015610d13575060045481115b610d64576040805162461bcd60e51b815260206004820181905260248201527f7468652066656c6f6e795468726573686f6c64206f7574206f662072616e6765604482015290519081900360640190fd5b600555610da9565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b609681565b61100281565b3361200014610e865760405162461bcd60e51b815260040180806020018281038252602f815260200180612282602f913960400191505060405180910390fd5b60005460ff16610ecb576040805162461bcd60e51b815260206004820152601960248201526000805160206122de833981519152604482015290519081900360640190fd5b6040517f07db600eebe2ac176be8dcebad61858c245a4961bb32ca2aa3d159b09aa0810e90600090a1505050565b334114610f375760405162461bcd60e51b815260040180806020018281038252602d8152602001806122b1602d913960400191505060405180910390fd5b60005460ff16610f7c576040805162461bcd60e51b815260206004820152601960248201526000805160206122de833981519152604482015290519081900360640190fd5b6003544311610fd2576040805162461bcd60e51b815260206004820181905260248201527f63616e206e6f7420736c61736820747769636520696e206f6e6520626c6f636b604482015290519081900360640190fd5b3a1561101c576040805162461bcd60e51b81526020600482015260146024820152736761737072696365206973206e6f74207a65726f60601b604482015290519081900360640190fd5b611024612146565b506001600160a01b0381166000908152600260208181526040928390208351606081018552815481526001820154928101929092529091015460ff16158015928201929092529061107f5760208101805160010190526110d8565b60016040820181905260208201819052805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0384161790555b4381526005546020820151816110ea57fe5b0661123c57600060208201819052604080516335409f7f60e01b81526001600160a01b03851660048201529051611000926335409f7f926024808201939182900301818387803b15801561113d57600080fd5b505af1158015611151573d6000803e3d6000fd5b505050506120006001600160a01b031663f7a251d7600b6111718561199e565b60006040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156111d15781810151838201526020016111b9565b50505050905090810190601f1680156111fe5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561121f57600080fd5b505af1158015611233573d6000803e3d6000fd5b505050506112b2565b60045481602001518161124b57fe5b066112b257604080516375abf10160e11b81526001600160a01b038416600482015290516110009163eb57e20291602480830192600092919082900301818387803b15801561129957600080fd5b505af11580156112ad573d6000803e3d6000fd5b505050505b6001600160a01b0382166000818152600260208181526040808420865181559186015160018301558581015191909201805460ff1916911515919091179055517fddb6012116e51abf5436d956a4f0ebd927e92c576ff96d7918290c8782291e3e9190a2505043600355565b61100381565b60005460ff161561137c576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b603260045560966005556000805460ff19166001179055565b61100081565b600381565b33611000146113e05760405162461bcd60e51b81526004018080602001828103825260308152602001806121dd6030913960400191505060405180910390fd5b60005460ff16611425576040805162461bcd60e51b815260206004820152601960248201526000805160206122de833981519152604482015290519081900360640190fd5b60015461143157611829565b600154600090600019015b8082116117fd576000805b8284101561156057611457612146565b600260006001878154811061146857fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff16151590820152600554909150600490048160200151111561154a576004600554816114d557fe5b048160200151038160200181815250508060026000600188815481106114f757fe5b6000918252602080832091909101546001600160a01b0316835282810193909352604091820190208351815591830151600183015591909101516002909101805460ff1916911515919091179055611554565b6001925050611560565b50600190930192611447565b8284116116f75761156f612146565b600260006001868154811061158057fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff161515908201526005549091506004900481602001511115611668576004600554816115ed57fe5b0481602001510381602001818152505080600260006001878154811061160f57fe5b6000918252602080832091909101546001600160a01b03168352828101939093526040918201902083518155918301516001808401919091559201516002909101805460ff191691151591909117905591506116f79050565b600260006001868154811061167957fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff191690558054806116bd57fe5b600082815260209020810160001990810180546001600160a01b0319169055019055836116ea57506116f7565b5060001990920191611560565b8180156117015750805b156117e057600260006001868154811061171757fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff1916905580548490811061175e57fe5b600091825260209091200154600180546001600160a01b03909216918690811061178457fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060018054806117bd57fe5b600082815260209020810160001990810180546001600160a01b03191690550190555b826117ec5750506117fd565b50506001909101906000190161143c565b6040517fcfdb3b6ccaeccbdc68be3c59c840e3b3c90f0a7c491f5fff1cf56cfda200dd9c90600090a150505b565b61100481565b611839612169565b6000611843612169565b61184b61217b565b61185c61185786611a70565b611a95565b90506000805b61186b83611adf565b156118a457806118975761188661188184611b00565b611b4e565b63ffffffff1684526001915061189c565b6118a4565b600101611862565b5091935090915050915091565b6000816040516020018082805190602001908083835b602083106118e65780518252601f1990920191602091820191016118c7565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106119545780518252601f199092019160209182019101611935565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490505b92915050565b015190565b60408051600480825260a08201909252606091829190816020015b60608152602001906001900390816119b95790505090506119e2836001600160a01b0316611c05565b816000815181106119ef57fe5b6020026020010181905250611a0343611c28565b81600181518110611a1057fe5b6020908102919091010152611a256038611c28565b81600281518110611a3257fe5b6020026020010181905250611a4642611c28565b81600381518110611a5357fe5b6020026020010181905250611a6781611c3b565b9150505b919050565b611a7861219b565b506040805180820190915281518152602082810190820152919050565b611a9d61217b565b611aa682611cc5565b611aaf57600080fd5b6000611abe8360200151611cff565b60208085015160408051808201909152868152920190820152915050919050565b6000611ae961219b565b505080518051602091820151919092015191011190565b611b0861219b565b611b1182611adf565b611b1a57600080fd5b60208201516000611b2a82611d62565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590611b6357508151602110155b611b6c57600080fd5b6000611b7b8360200151611cff565b90508083600001511015611bd6576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b825160208085015183018051928490039291831015611bfc57826020036101000a820491505b50949350505050565b60408051600560a21b8318601482015260348101909152606090611a6781611e95565b6060611993611c3683611eeb565b611e95565b6060815160001415611c5c5750604080516000815260208101909152611a6b565b606082600081518110611c6b57fe5b602002602001015190506000600190505b8351811015611cac57611ca282858381518110611c9557fe5b6020026020010151611fd1565b9150600101611c7c565b50611a67611cbf825160c060ff1661204e565b82611fd1565b8051600090611cd657506000611a6b565b6020820151805160001a9060c0821015611cf557600092505050611a6b565b5060019392505050565b8051600090811a6080811015611d19576000915050611a6b565b60b8811080611d34575060c08110801590611d34575060f881105b15611d43576001915050611a6b565b60c0811015611d575760b519019050611a6b565b60f519019050611a6b565b80516000908190811a6080811015611d7d5760019150611e8e565b60b8811015611d9257607e1981019150611e8e565b60c0811015611e0c57600060b78203600186019550806020036101000a865104915060018101820193505080831015611e06576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b50611e8e565b60f8811015611e215760be1981019150611e8e565b600060f78203600186019550806020036101000a865104915060018101820193505080831015611e8c576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b606081516001148015611ec75750607f60f81b82600081518110611eb557fe5b01602001516001600160f81b03191611155b15611ed3575080611a6b565b611993611ee58351608060ff1661204e565b83611fd1565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416611f2f57506018611f53565b6fffffffffffffffffffffffffffffffff198416611f4f57506010611f53565b5060005b6020811015611f8957818181518110611f6857fe5b01602001516001600160f81b03191615611f8157611f89565b600101611f53565b60008160200390506060816040519080825280601f01601f191660200182016040528015611fbe576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b81831015612002578051835260209283019201611fea565b50855184518101855292509050808201602086015b8183101561202f578051835260209283019201612017565b508651929092011591909101601f01601f191660405250905092915050565b606068010000000000000000831061209e576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b604080516001808252818301909252606091602082018180368337019050509050603784116120f85782840160f81b816000815181106120da57fe5b60200101906001600160f81b031916908160001a9053509050611993565b606061210385611eeb565b90508381510160370160f81b8260008151811061211c57fe5b60200101906001600160f81b031916908160001a90535061213d8282611fd1565b95945050505050565b604051806060016040528060008152602001600081526020016000151581525090565b60408051602081019091526000815290565b604051806040016040528061218e61219b565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe6c656e677468206f66206d697364656d65616e6f725468726573686f6c64206d69736d61746368746865206d6573736167652073656e646572206d7573742062652076616c696461746f7253657420636f6e7472616374746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662066656c6f6e795468726573686f6c64206d69736d61746368746865206d697364656d65616e6f725468726573686f6c64206f7574206f662072616e6765746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d6573736167652073656e646572206d7573742062652074686520626c6f636b2070726f647563657274686520636f6e7472616374206e6f7420696e69742079657400000000000000a2646970667358221220978db7b9b4e7fb0a1f9436afd2b57418fb3ba1969a491794d2da96ee68de87d064736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001002": { + "balance": "0x0", + "code": "0x60806040526004361061014f5760003560e01c806396713da9116100b6578063c81b16621161006f578063c81b1662146103dc578063dc927faf146103f1578063f9a2bbc714610406578063fb5478b31461041b578063fc3e590814610430578063fd6a68791461044557610193565b806396713da91461033a5780639a99b4f01461034f5780639dc0926214610388578063a1a11bf51461039d578063a78abc16146103b2578063ab51bb96146103c757610193565b806351e806721161010857806351e806721461028a5780636d70f7ae1461029f5780636e47b482146102e657806370fd5bad146102fb57806375d47a0a146103105780637942fd051461032557610193565b80630bee7a67146101985780633a0b0eff146101c65780633dffc387146101ed57806343756e5c14610218578063493279b1146102495780634bf6c8821461027557610193565b366101935734156101915760408051348152905133917f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db919081900360200190a25b005b600080fd5b3480156101a457600080fd5b506101ad61045a565b6040805163ffffffff9092168252519081900360200190f35b3480156101d257600080fd5b506101db61045f565b60408051918252519081900360200190f35b3480156101f957600080fd5b50610202610465565b6040805160ff9092168252519081900360200190f35b34801561022457600080fd5b5061022d61046a565b604080516001600160a01b039092168252519081900360200190f35b34801561025557600080fd5b5061025e610470565b6040805161ffff9092168252519081900360200190f35b34801561028157600080fd5b50610202610475565b34801561029657600080fd5b5061022d61047a565b3480156102ab57600080fd5b506102d2600480360360208110156102c257600080fd5b50356001600160a01b0316610480565b604080519115158252519081900360200190f35b3480156102f257600080fd5b5061022d61049e565b34801561030757600080fd5b506102026104a4565b34801561031c57600080fd5b5061022d6104a9565b34801561033157600080fd5b506102026104af565b34801561034657600080fd5b506102026104b4565b34801561035b57600080fd5b506101db6004803603604081101561037257600080fd5b506001600160a01b0381351690602001356104b9565b34801561039457600080fd5b5061022d610664565b3480156103a957600080fd5b5061022d61066a565b3480156103be57600080fd5b506102d2610670565b3480156103d357600080fd5b506101ad610679565b3480156103e857600080fd5b5061022d61067e565b3480156103fd57600080fd5b5061022d610684565b34801561041257600080fd5b5061022d61068a565b34801561042757600080fd5b506101db610690565b34801561043c57600080fd5b5061020261069c565b34801561045157600080fd5b5061022d6106a1565b606481565b60015481565b600181565b61100181565b603881565b600881565b61200081565b6001600160a01b031660009081526002602052604090205460ff1690565b61100581565b600281565b61100881565b600b81565b600981565b6000805460ff1661053657600260208190527fe57bda0a954a7c7381b17b2c763e646ba2c60f67292d287ba583603e2c1c41668054600160ff19918216811790925561100560009081527fe25235fc0de9d7165652bef0846fefda506174abb9a190f03d0f7bcc6146dbce80548316841790559282558254161790555b3360009081526002602052604090205460ff166105845760405162461bcd60e51b815260040180806020018281038252602b8152602001806106a8602b913960400191505060405180910390fd5b60004783106105935747610595565b825b9050670de0b6b3a76400008111156105b25750670de0b6b3a76400005b8015610633576040516001600160a01b0385169082156108fc029083906000818181858888f193505050501580156105ee573d6000803e3d6000fd5b506040805182815290516001600160a01b038616917ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0919081900360200190a261065d565b6040517fe589651933c2457488cc0d8e0941518abf748e799435e4e396d9c4d0b2db2d4d90600090a15b9392505050565b61100781565b61100681565b60005460ff1681565b600081565b61100281565b61100381565b61100081565b670de0b6b3a764000081565b600381565b6110048156fe6f6e6c79206f70657261746f7220697320616c6c6f77656420746f2063616c6c20746865206d6574686f64a2646970667358221220c09e2c37549a0aef291c4f977743d3cea839c669624a8cfae895b3979a32800764736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001003": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106102115760003560e01c8063a78abc1611610125578063dda83148116100ad578063e405bbc31161007c578063e405bbc314610681578063ea54b2aa14610689578063f9a2bbc714610691578063fc3e590814610699578063fd6a6879146106a157610211565b8063dda8314814610609578063df5fe7041461062f578063e1c7392a14610655578063e2761af01461065d57610211565b8063c81b1662116100f4578063c81b166214610534578063cba510a91461053c578063d816987914610562578063da8d08f0146105db578063dc927faf1461060157610211565b8063a78abc1614610444578063ab51bb9614610460578063ac43175114610468578063adc879e91461052c57610211565b8063564b81ef116101a857806375d47a0a1161017757806375d47a0a1461041c5780637942fd051461042457806396713da91461042c5780639dc0926214610434578063a1a11bf51461043c57610211565b8063564b81ef146102ca5780635c5ae8db146103475780636e47b4821461040c57806370fd5bad1461041457610211565b806343756e5c116101e457806343756e5c14610277578063493279b11461029b5780634bf6c882146102ba57806351e80672146102c257610211565b80630bee7a67146102165780632657e9b61461023757806333f7798d146102515780633dffc38714610259575b600080fd5b61021e6106a9565b6040805163ffffffff9092168252519081900360200190f35b61023f6106ae565b60408051918252519081900360200190f35b61023f6106b9565b6102616106bf565b6040805160ff9092168252519081900360200190f35b61027f6106c4565b604080516001600160a01b039092168252519081900360200190f35b6102a36106ca565b6040805161ffff9092168252519081900360200190f35b6102616106cf565b61027f6106d4565b6102d26106da565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561030c5781810151838201526020016102f4565b50505050905090810190601f1680156103395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61036d6004803603602081101561035d57600080fd5b50356001600160401b03166107e6565b60405180856001600160401b03166001600160401b0316815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156103ce5781810151838201526020016103b6565b50505050905090810190601f1680156103fb5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b61027f6108a1565b6102616108a7565b61027f6108ac565b6102616108b2565b6102616108b7565b61027f6108bc565b61027f6108c2565b61044c6108c8565b604080519115158252519081900360200190f35b61021e6108d1565b61052a6004803603604081101561047e57600080fd5b81019060208101813564010000000081111561049957600080fd5b8201836020820111156104ab57600080fd5b803590602001918460018302840111640100000000831117156104cd57600080fd5b9193909290916020810190356401000000008111156104eb57600080fd5b8201836020820111156104fd57600080fd5b8035906020019184600183028401116401000000008311171561051f57600080fd5b5090925090506108d6565b005b61023f610b8f565b61027f610b95565b61023f6004803603602081101561055257600080fd5b50356001600160401b0316610b9b565b61044c6004803603604081101561057857600080fd5b81019060208101813564010000000081111561059357600080fd5b8201836020820111156105a557600080fd5b803590602001918460018302840111640100000000831117156105c757600080fd5b9193509150356001600160401b0316610bba565b61027f600480360360208110156105f157600080fd5b50356001600160401b031661139b565b61027f6113b6565b61027f6004803603602081101561061f57600080fd5b50356001600160401b03166113bc565b61044c6004803603602081101561064557600080fd5b50356001600160401b03166113e0565b61052a611422565b6106656115c9565b604080516001600160401b039092168252519081900360200190f35b6106656115d8565b6102d26115ee565b61027f61160d565b610261611613565b61027f611618565b606481565b662386f26fc1000081565b60055481565b600181565b61100181565b603881565b600881565b61200081565b604080516020808252818301909252606091829190602082018180368337505060045460208301525090506000805b60208160ff16101561075057828160ff168151811061072457fe5b01602001516001600160f81b0319161561074357600190910190610748565b610750565b600101610709565b5060608160ff166040519080825280601f01601f191660200182016040528015610781576020820181803683370190505b50905060005b8260ff168160ff1610156107dd57838160ff16815181106107a457fe5b602001015160f81c60f81b828260ff16815181106107be57fe5b60200101906001600160f81b031916908160001a905350600101610787565b50925050505b90565b60016020818152600092835260409283902080548184015460028084015460038501805489516101009982161599909902600019011692909204601f81018790048702880187019098528787526001600160401b0390931696919592949091908301828280156108975780601f1061086c57610100808354040283529160200191610897565b820191906000526020600020905b81548152906001019060200180831161087a57829003601f168201915b5050505050905084565b61100581565b600281565b61100881565b600b81565b600981565b61100781565b61100681565b60005460ff1681565b600081565b60005460ff1661092d576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604482015290519081900360640190fd5b336110071461096d5760405162461bcd60e51b815260040180806020018281038252602e8152602001806119ea602e913960400191505060405180910390fd5b6109e184848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601b81527f726577617264466f7256616c696461746f725365744368616e676500000000006020820152915061161e9050565b15610ac05760208114610a255760405162461bcd60e51b815260040180806020018281038252602e815260200180611989602e913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610a639185858083850183828082843760009201919091525061170592505050565b9050600081118015610a7d5750670de0b6b3a76400008111155b610ab85760405162461bcd60e51b815260040180806020018281038252602f815260200180611a18602f913960400191505060405180910390fd5b600555610afd565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b60045481565b61100281565b6001600160401b03166000908152600160208190526040909120015490565b60408051630a83aaa960e31b815233600482015290516000916110069163541d554891602480820192602092909190829003018186803b158015610bfd57600080fd5b505afa158015610c11573d6000803e3d6000fd5b505050506040513d6020811015610c2757600080fd5b5051610c7a576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b6001600160401b0382166000908152600260205260409020546001600160a01b031615610cee576040805162461bcd60e51b815260206004820152601c60248201527f63616e27742073796e63206475706c6963617465642068656164657200000000604482015290519081900360640190fd5b6003546001600160401b0390811690831611610d3b5760405162461bcd60e51b8152600401808060200182810382526026815260200180611a476026913960400191505060405180910390fd5b600354600160401b90046001600160401b0316610d56611867565b6001600160401b0382811660009081526001602081815260409283902083516080810185528154909516855280830154858301526002808201548686015260038201805486516101009682161596909602600019011691909104601f81018490048402850184019095528484529093606086019392830182828015610e1c5780601f10610df157610100808354040283529160200191610e1c565b820191906000526020600020905b815481529060010190602001808311610dff57829003601f168201915b50505050508152505090505b836001600160401b0316826001600160401b031610158015610e5957506003546001600160401b0390811690831610155b15610f3a5780516001600160401b0380821660009081526001602081815260409283902083516080810185528154909516855280830154858301526002808201548686015260038201805486516101009682161596909602600019011691909104601f8101849004840285018401909552848452959750939460608601939091830182828015610f2a5780601f10610eff57610100808354040283529160200191610f2a565b820191906000526020600020905b815481529060010190602001808311610f0d57829003601f168201915b5050505050815250509050610e28565b6060810151516110315780516001600160401b03811660009081526001602081815260409283902060030180548451600294821615610100026000190190911693909304601f810183900483028401830190945283835293955090929190830182828015610fe95780601f10610fbe57610100808354040283529160200191610fe9565b820191906000526020600020905b815481529060010190602001808311610fcc57829003601f168201915b505050506060830182905250516110315760405162461bcd60e51b81526004018080602001828103825260218152602001806119686021913960400191505060405180910390fd5b6000816060015151608801905060608787905082016040519080825280601f01601f191660200182016040528015611070576020820181803683370190505b509050600061107e8261170a565b905061108c84868386611710565b6110c75760405162461bcd60e51b81526004018080602001828103825260238152602001806119456023913960400191505060405180910390fd5b6000838201915061110d8a8a8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061177c92505050565b9450905061111c818386611786565b8251602001935061112b61188d565b6110008186866064600019fa61114057600080fd5b805194506000600160f81b8616156111cf5750600554604080516309a99b4f60e41b815233600482015260248101929092525160019161100291639a99b4f0916044808201926020929091908290030181600087803b1580156111a257600080fd5b505af11580156111b6573d6000803e3d6000fd5b505050506040513d60208110156111cc57600080fd5b50505b856001600160401b0316955060208201935060006111ef858884156117c7565b90985090506001600160401b03808216908c161461123e5760405162461bcd60e51b81526004018080602001828103825260338152602001806119b76033913960400191505060405180910390fd5b6001600160401b03808c16600081815260026020818152604080842080546001600160a01b031916331790558e86168e529383526001808252928490208d518154961667ffffffffffffffff199096169590951785558c81015192850192909255918b01519183019190915560608a015180518b93926112c59260038501929101906118ac565b50506003546001600160401b03600160401b9091048116908d161115905061130d576003805467ffffffffffffffff60401b1916600160401b6001600160401b038e16021790555b7f4042c1020a8f410fb1c8859d276ab436aeb2c3074960e48467299cf1c966d3b48b8a8a602001518560405180856001600160401b03166001600160401b03168152602001846001600160401b03166001600160401b031681526020018381526020018215151515815260200194505050505060405180910390a15060019c9b505050505050505050505050565b6002602052600090815260409020546001600160a01b031681565b61100381565b6001600160401b03166000908152600260205260409020546001600160a01b031690565b6001600160401b0381166000908152600260205260408120546001600160a01b031615158061141c57506003546001600160401b038381169116145b92915050565b60005460ff161561147a576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b6000806114a16040518061024001604052806102208152602001611a6d610220913961177c565b815160045590925090506114b3611867565b60006114c1848460006117c7565b60008083526001600160401b038281168252600160208181526040938490208651815467ffffffffffffffff191694169390931783558086015191830191909155918401516002820155606084015180519496509294508593909261152d9260038501929101906118ac565b50506003805467ffffffffffffffff19166001600160401b0384811691821767ffffffffffffffff60401b1916600160401b9290920291909117918290556000805460ff19166001179055662386f26fc10000600555602085810151604080519490931684529083015280517f5ac9b37d571677b80957ca05693f371526c602fd08042b416a29fdab7efefa499350918290030190a150505050565b6003546001600160401b031681565b600354600160401b90046001600160401b031681565b6040518061024001604052806102208152602001611a6d610220913981565b61100081565b600381565b61100481565b6000816040516020018082805190602001908083835b602083106116535780518252601f199092019160209182019101611634565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106116c15780518252601f1990920191602091820191016116a2565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b60200190565b600084606001515182840103925060008061172e876060015161177c565b909250905061173e828683611786565b5050506040840151601f1983810191909152602090940151603f19830152605f19820192909252600454606719820152910160871990910152600190565b8051602090910191565b5b602081106117a6578251825260209283019290910190601f1901611787565b915181516020939093036101000a6000190180199091169216919091179052565b6117cf611867565b60088401516028850151604890950180519095600092916117ee611867565b6020810183905260408101829052866118595760008060688a036040519080825280601f01601f191660200182016040528015611832576020820181803683370190505b50606084018190526118439061177c565b909250905061185660208c018383611786565b50505b989297509195505050505050565b604080516080810182526000808252602082018190529181019190915260608082015290565b6040518061100001604052806080906020820280368337509192915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106118ed57805160ff191683800117855561191a565b8280016001018555821561191a579182015b8281111561191a5782518255916020019190600101906118ff565b5061192692915061192a565b5090565b6107e391905b80821115611926576000815560010161193056fe6661696c656420746f2073657269616c697a6520636f6e73656e7375732073746174656661696c656420746f206c6f61642076616c696461746f722073657420646174616c656e677468206f6620726577617264466f7256616c696461746f725365744368616e6765206d69736d617463686865616465722068656967687420646f65736e277420657175616c20746f207468652073706563696669656420686569676874746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374746865206e6577526577617264466f7256616c696461746f725365744368616e6765206f7574206f662072616e676563616e27742073796e6320686561646572206265666f726520696e697469616c48656967687442696e616e63652d436861696e2d5469677269730000000000000000000000000000000006915167cedaf7bbf7df47d932fdda630527ee648562cf3e52c5e5f46156a3a971a4ceb443c53a50d8653ef8cf1e5716da68120fb51b636dc6d111ec3277b098ecd42d49d3769d8a1f78b4c17a965f7a30d4181fabbd1f969f46d3c8e83b5ad4845421d8000000e8d4a510002ba4e81542f437b7ae1f8a35ddb233c789a8dc22734377d9b6d63af1ca403b61000000e8d4a51000df8da8c5abfdb38595391308bb71e5a1e0aabdc1d0cf38315d50d6be939b2606000000e8d4a51000b6619edca4143484800281d698b70c935e9152ad57b31d85c05f2f79f64b39f3000000e8d4a510009446d14ad86c8d2d74780b0847110001a1c2e252eedfea4753ebbbfce3a22f52000000e8d4a510000353c639f80cc8015944436dab1032245d44f912edc31ef668ff9f4a45cd0599000000e8d4a51000e81d3797e0544c3a718e1f05f0fb782212e248e784c1a851be87e77ae0db230e000000e8d4a510005e3fcda30bd19d45c4b73688da35e7da1fce7c6859b2c1f20ed5202d24144e3e000000e8d4a51000b06a59a2d75bf5d014fce7c999b5e71e7a960870f725847d4ba3235baeaa08ef000000e8d4a510000c910e2fe650e4e01406b3310b489fb60a84bc3ff5c5bee3a56d5898b6a8af32000000e8d4a5100071f2d7b8ec1c8b99a653429b0118cd201f794f409d0fea4d65b1b662f2b00063000000e8d4a51000a264697066735822122032fc162aed7c2a4fe0f40397d327efc38d8aaf5dbdd1720f7f5d8101877da61d64736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001004": { + "balance": "176405560900000000000000000", + "code": "0x60806040526004361061031e5760003560e01c80639a99b4f0116101ab578063bd466461116100f7578063f014847211610095578063fc1a598f1161006f578063fc1a598f14610cb3578063fc3e590814610686578063fd6a687914610ce6578063ff9c0027146107dc57610366565b8063f014847214610c74578063f9a2bbc714610c89578063fa9e915914610c9e57610366565b8063d9e6dae9116100d1578063d9e6dae914610608578063dc927faf14610c35578063e1c7392a14610c4a578063ebf71d5314610c5f57610366565b8063bd46646114610b68578063c81b166214610b9b578063c8509d8114610bb057610366565b8063aa7415f511610164578063b99328c51161013e578063b99328c514610ad2578063b9fd21e314610b0b578063ba35ead614610b20578063bbface1f14610b3557610366565b8063aa7415f5146109ab578063ab51bb96146109f2578063ac43175114610a0757610366565b80639a99b4f01461091e5780639dc0926214610957578063a1a11bf51461096c578063a496fba214610981578063a78abc1614610996578063a7c9f02d1461068657610366565b8063613684751161026a57806375d47a0a116102235780638b87b21f116101fd5780638b87b21f146105875780638eff336c146108b557806396713da9146108f45780639a854bbd1461090957610366565b806375d47a0a146108065780637942fd051461081b578063831d65d11461083057610366565b8063613684751461060857806366dea52a146106865780636e0565201461069b5780636e47b482146107c757806370fd5bad146107dc57806371d30863146107f157610366565b806343a368b9116102d757806350432d32116102b157806350432d321461061d57806351e806721461063257806359b92789146106475780635d499b1b1461067157610366565b806343a368b9146105c7578063493279b1146105dc5780634bf6c8821461060857610366565b80630bee7a671461036b5780631182b87514610399578063149d14d9146104935780633d713223146104ba5780633dffc3871461058757806343756e5c146105b257610366565b36610366573415610364576040805133815234602082015281517f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db929181900390910190a15b005b600080fd5b34801561037757600080fd5b50610380610cfb565b6040805163ffffffff9092168252519081900360200190f35b3480156103a557600080fd5b5061041e600480360360408110156103bc57600080fd5b60ff8235169190810190604081016020820135600160201b8111156103e057600080fd5b8201836020820111156103f257600080fd5b803590602001918460018302840111600160201b8311171561041357600080fd5b509092509050610d00565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610458578181015183820152602001610440565b50505050905090810190601f1680156104855780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561049f57600080fd5b506104a8610e2e565b60408051918252519081900360200190f35b3480156104c657600080fd5b5061056b600480360360208110156104dd57600080fd5b810190602081018135600160201b8111156104f757600080fd5b82018360208201111561050957600080fd5b803590602001918460018302840111600160201b8311171561052a57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610e34945050505050565b604080516001600160a01b039092168252519081900360200190f35b34801561059357600080fd5b5061059c610e58565b6040805160ff9092168252519081900360200190f35b3480156105be57600080fd5b5061056b610e5d565b3480156105d357600080fd5b506104a8610e63565b3480156105e857600080fd5b506105f1610e6f565b6040805161ffff9092168252519081900360200190f35b34801561061457600080fd5b5061059c610e74565b34801561062957600080fd5b506104a8610e79565b34801561063e57600080fd5b5061056b610e84565b34801561065357600080fd5b5061056b6004803603602081101561066a57600080fd5b5035610e8a565b34801561067d57600080fd5b506104a8610ea5565b34801561069257600080fd5b5061059c610eae565b6107b3600480360360808110156106b157600080fd5b810190602081018135600160201b8111156106cb57600080fd5b8201836020820111156106dd57600080fd5b803590602001918460208302840111600160201b831117156106fe57600080fd5b919390929091602081019035600160201b81111561071b57600080fd5b82018360208201111561072d57600080fd5b803590602001918460208302840111600160201b8311171561074e57600080fd5b919390929091602081019035600160201b81111561076b57600080fd5b82018360208201111561077d57600080fd5b803590602001918460208302840111600160201b8311171561079e57600080fd5b91935091503567ffffffffffffffff16610eb3565b604080519115158252519081900360200190f35b3480156107d357600080fd5b5061056b611388565b3480156107e857600080fd5b5061059c61138e565b3480156107fd57600080fd5b506104a8611393565b34801561081257600080fd5b5061056b611399565b34801561082757600080fd5b5061059c61139f565b34801561083c57600080fd5b506103646004803603604081101561085357600080fd5b60ff8235169190810190604081016020820135600160201b81111561087757600080fd5b82018360208201111561088957600080fd5b803590602001918460018302840111600160201b831117156108aa57600080fd5b5090925090506113a4565b3480156108c157600080fd5b50610364600480360360608110156108d857600080fd5b508035906001600160a01b0360208201351690604001356114ed565b34801561090057600080fd5b5061059c611573565b34801561091557600080fd5b506104a8611578565b34801561092a57600080fd5b506104a86004803603604081101561094157600080fd5b506001600160a01b038135169060200135611584565b34801561096357600080fd5b5061056b6116c2565b34801561097857600080fd5b5061056b6116c8565b34801561098d57600080fd5b5061059c6116ce565b3480156109a257600080fd5b506107b36116d3565b6107b3600480360360808110156109c157600080fd5b5080356001600160a01b03908116916020810135909116906040810135906060013567ffffffffffffffff166116dc565b3480156109fe57600080fd5b506103806116ce565b348015610a1357600080fd5b5061036460048036036040811015610a2a57600080fd5b810190602081018135600160201b811115610a4457600080fd5b820183602082011115610a5657600080fd5b803590602001918460018302840111600160201b83111715610a7757600080fd5b919390929091602081019035600160201b811115610a9457600080fd5b820183602082011115610aa657600080fd5b803590602001918460018302840111600160201b83111715610ac757600080fd5b509092509050611d9d565b348015610ade57600080fd5b5061036460048036036040811015610af557600080fd5b50803590602001356001600160a01b031661200c565b348015610b1757600080fd5b506104a8612082565b348015610b2c57600080fd5b506104a861208c565b348015610b4157600080fd5b506104a860048036036020811015610b5857600080fd5b50356001600160a01b0316612092565b348015610b7457600080fd5b506104a860048036036020811015610b8b57600080fd5b50356001600160a01b03166120a4565b348015610ba757600080fd5b5061056b6120bf565b348015610bbc57600080fd5b5061036460048036036040811015610bd357600080fd5b60ff8235169190810190604081016020820135600160201b811115610bf757600080fd5b820183602082011115610c0957600080fd5b803590602001918460018302840111600160201b83111715610c2a57600080fd5b5090925090506120c5565b348015610c4157600080fd5b5061056b612195565b348015610c5657600080fd5b5061036461219b565b348015610c6b57600080fd5b5061059c61223b565b348015610c8057600080fd5b5061059c612240565b348015610c9557600080fd5b5061056b612245565b348015610caa57600080fd5b506104a861224b565b348015610cbf57600080fd5b5061041e60048036036020811015610cd657600080fd5b50356001600160a01b0316612251565b348015610cf257600080fd5b5061056b612378565b606481565b60005460609060ff16610d48576040805162461bcd60e51b815260206004820152601960248201526000805160206147bf833981519152604482015290519081900360640190fd5b3361200014610d885760405162461bcd60e51b815260040180806020018281038252602f81526020018061476d602f913960400191505060405180910390fd5b60ff841660021415610dda57610dd383838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061237e92505050565b9050610e27565b6040805162461bcd60e51b815260206004820152601860248201527f756e7265636f676e697a65642073796e207061636b6167650000000000000000604482015290519081900360640190fd5b9392505050565b60015490565b6020818101516000908152600490915260409020546001600160a01b03165b919050565b600181565b61100181565b670de0b6b3a764000081565b603881565b600881565b66071afd498d000081565b61200081565b6000908152600460205260409020546001600160a01b031690565b6402540be40081565b600381565b6000805460ff16610ef9576040805162461bcd60e51b815260206004820152601960248201526000805160206147bf833981519152604482015290519081900360640190fd5b868514610f375760405162461bcd60e51b815260040180806020018281038252603b815260200180614732603b913960400191505060405180910390fd5b868314610f755760405162461bcd60e51b815260040180806020018281038252603f815260200180614605603f913960400191505060405180910390fd5b426078018267ffffffffffffffff161015610fc15760405162461bcd60e51b81526004018080602001828103825260248152602001806144f56024913960400191505060405180910390fd5b6402540be4003406156110055760405162461bcd60e51b81526004018080602001828103825260408152602001806148356040913960400191505060405180910390fd5b60408051868152602080880282010190915285906000908190606090848015611038578160200160208202803683370190505b50905060005b84811015611113576402540be4008b8b8381811061105857fe5b905060200201358161106657fe5b06156110a35760405162461bcd60e51b815260040180806020018281038252603c815260200180614644603c913960400191505060405180910390fd5b6110c88b8b838181106110b257fe5b90506020020135856124a290919063ffffffff16565b93506110f46402540be4008c8c848181106110df57fe5b905060200201356124fc90919063ffffffff16565b82828151811061110057fe5b602090810291909101015260010161103e565b506001546111389061112b908663ffffffff61253e16565b849063ffffffff6124a216565b3410156111765760405162461bcd60e51b81526004018080602001828103825260568152602001806147df6056913960600191505060405180910390fd5b611186348463ffffffff61259716565b915061119061434e565b6040518060c001604052806221272160e91b60001b815260200160006001600160a01b031681526020018381526020018e8e808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050908252506040805160208c810282810182019093528c82529283019290918d918d91829185019084908082843760009201919091525050509082525067ffffffffffffffff8916602090910152905061200063f7a251d76003611254846125d9565b611269876402540be40063ffffffff6124fc16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156112c75781810151838201526020016112af565b50505050905090810190601f1680156112f45780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561131557600080fd5b505af1158015611329573d6000803e3d6000fd5b505060408051600081523360208201528082018890526060810187905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9350908190036080019150a15060019c9b505050505050505050505050565b61100581565b600281565b60015481565b61100881565b600b81565b60005460ff166113e9576040805162461bcd60e51b815260206004820152601960248201526000805160206147bf833981519152604482015290519081900360640190fd5b33612000146114295760405162461bcd60e51b815260040180806020018281038252602f81526020018061476d602f913960400191505060405180910390fd5b60ff8316600314156114795761147482828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061289492505050565b6114e8565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a15b505050565b336110081461152d5760405162461bcd60e51b815260040180806020018281038252602381526020018061479c6023913960400191505060405180910390fd5b600083815260046020908152604080832080546001600160a01b039096166001600160a01b03199096168617905593825260038152838220949094556002909352912055565b600981565b677ce66c50e284000081565b6000805460ff166115ca576040805162461bcd60e51b815260206004820152601960248201526000805160206147bf833981519152604482015290519081900360640190fd5b336110051461160a5760405162461bcd60e51b815260040180806020018281038252602f815260200180614468602f913960400191505060405180910390fd5b6000478310611619574761161b565b825b9050670de0b6b3a76400008111156116375760009150506116bc565b80156116b9576040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015611673573d6000803e3d6000fd5b50604080516001600160a01b03861681526020810183905281517ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0929181900390910190a15b90505b92915050565b61100781565b61100681565b600081565b60005460ff1681565b6000805460ff16611722576040805162461bcd60e51b815260206004820152601960248201526000805160206147bf833981519152604482015290519081900360640190fd5b426078018267ffffffffffffffff16101561176e5760405162461bcd60e51b81526004018080602001828103825260248152602001806144f56024913960400191505060405180910390fd5b6402540be4003406156117b25760405162461bcd60e51b81526004018080602001828103825260408152602001806148356040913960400191505060405180910390fd5b600080806001600160a01b038816611891576001546117d890879063ffffffff6124a216565b3410156118165760405162461bcd60e51b815260040180806020018281038252606181526020018061457f6061913960800191505060405180910390fd5b6402540be40086061561185a5760405162461bcd60e51b815260040180806020018281038252603c815260200180614644603c913960400191505060405180910390fd5b61186a348763ffffffff61259716565b9050611881866402540be40063ffffffff6124fc16565b6221272160e91b93509150611b34565b6001600160a01b0388166000908152600360205260409020549250826118e85760405162461bcd60e51b815260040180806020018281038252603181526020018061454e6031913960400191505060405180910390fd5b6001543410156119295760405162461bcd60e51b815260040180806020018281038252603f8152602001806146a1603f913960400191505060405180910390fd5b506001600160a01b038716600090815260026020526040902054349060088111158061197457506008811180156119745750611972876007198301600a0a63ffffffff6128f016565b155b6119af5760405162461bcd60e51b815260040180806020018281038252603c815260200180614644603c913960400191505060405180910390fd5b6119b98782612932565b92506119c484612972565b15611a0c576305f5e100831015611a0c5760405162461bcd60e51b815260040180806020018281038252603a815260200180614497603a913960400191505060405180910390fd5b600881101580611a265750600881108015611a2657508683115b611a615760405162461bcd60e51b81526004018080602001828103825260258152602001806145e06025913960400191505060405180910390fd5b677ce66c50e2840000831115611aa85760405162461bcd60e51b81526004018080602001828103825260358152602001806145196035913960400191505060405180910390fd5b604080516323b872dd60e01b81523360048201523060248201526044810189905290516001600160a01b038b16916323b872dd9160648083019260209291908290030181600087803b158015611afd57600080fd5b505af1158015611b11573d6000803e3d6000fd5b505050506040513d6020811015611b2757600080fd5b5051611b3257600080fd5b505b611b3c61434e565b6040805160c0810182528581526001600160a01b038b166020820152815160018082528184018452919283019181602001602082028036833750505081526040805160018082528183019092526020928301929091908083019080368337505050815260408051600180825281830190925260209283019290919080830190803683370190505081526020018767ffffffffffffffff168152509050828160400151600081518110611bea57fe5b602002602001018181525050878160600151600081518110611c0857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050338160800151600081518110611c3a57fe5b6001600160a01b039092166020928302919091019091015261200063f7a251d76003611c65846125d9565b611c7a866402540be40063ffffffff6124fc16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611cd8578181015183820152602001611cc0565b50505050905090810190601f168015611d055780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015611d2657600080fd5b505af1158015611d3a573d6000803e3d6000fd5b5050604080516001600160a01b038d1681523360208201528082018b90526060810186905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9350908190036080019150a150600198975050505050505050565b3361100714611ddd5760405162461bcd60e51b815260040180806020018281038252602e8152602001806146e0602e913960400191505060405180910390fd5b60208114611e32576040805162461bcd60e51b815260206004820152601b60248201527f65787065637465642076616c7565206c656e6774682069732033320000000000604482015290519081900360640190fd5b606084848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8801819004810282018101909252868152939450606093925086915085908190840183828082843760009201919091525050505060208301519091506772656c617946656560c01b811415611f3a576020820151670de0b6b3a76400008111801590611ee157506402540be4008106155b611f32576040805162461bcd60e51b815260206004820152601960248201527f7468652072656c6179466565206f7574206f662072616e676500000000000000604482015290519081900360640190fd5b600155611f77565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a878787876040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050505050565b336110081461204c5760405162461bcd60e51b815260040180806020018281038252602381526020018061479c6023913960400191505060405180910390fd5b600091825260046020908152604080842080546001600160a01b03191690556001600160a01b0392909216835260039052812055565b6221272160e91b81565b61c35081565b60026020526000908152604090205481565b6001600160a01b031660009081526003602052604090205490565b61100281565b60005460ff1661210a576040805162461bcd60e51b815260206004820152601960248201526000805160206147bf833981519152604482015290519081900360640190fd5b336120001461214a5760405162461bcd60e51b815260040180806020018281038252602f81526020018061476d602f913960400191505060405180910390fd5b60ff8316600314156114795761147482828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612a7892505050565b61100381565b60005460ff16156121f3576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b66071afd498d000060019081556000808052600260205260127fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b55805460ff19169091179055565b600481565b600581565b61100081565b61271081565b6001600160a01b03811660009081526003602090815260409182902054825182815280840190935260609290918391906020820181803683375050506020810183905290506000805b60208160ff1610156122e157828160ff16815181106122b557fe5b01602001516001600160f81b031916156122d4576001909101906122d9565b6122e1565b60010161229a565b5060608160ff166040519080825280601f01601f191660200182016040528015612312576020820181803683370190505b50905060005b8260ff168160ff16101561236e57838160ff168151811061233557fe5b602001015160f81c60f81b828260ff168151811061234f57fe5b60200101906001600160f81b031916908160001a905350600101612318565b5095945050505050565b61100481565b606061238861439a565b600061239384612b76565b91509150806123e9576040805162461bcd60e51b815260206004820152601f60248201527f756e7265636f676e697a6564207472616e73666572496e207061636b61676500604482015290519081900360640190fd5b60006123f483612cb5565b905063ffffffff811615612488576040808401516020808601516001600160a01b0316600090815260029091529182205461242f9190612932565b90506124396143cf565b60405180608001604052808660000151815260200183815260200186608001516001600160a01b031681526020018463ffffffff16815250905061247c81613002565b95505050505050610e53565b50506040805160008152602081019091529150610e539050565b6000828201838110156116b9576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60006116b983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506130de565b60008261254d575060006116bc565b8282028284828161255a57fe5b04146116b95760405162461bcd60e51b81526004018080602001828103825260218152602001806146806021913960400191505060405180910390fd5b60006116b983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613180565b60408051600680825260e08201909252606091829190816020015b60608152602001906001900390816125f45750508351909150612616906131da565b8160008151811061262357fe5b602002602001018190525061264483602001516001600160a01b03166131ed565b8160018151811061265157fe5b60200260200101819052506000836040015151905060608160405190808252806020026020018201604052801561269c57816020015b60608152602001906001900390816126875790505b50905060005b828110156126e9576126ca866040015182815181106126bd57fe5b60200260200101516131da565b8282815181106126d657fe5b60209081029190910101526001016126a2565b506126f381613210565b8360028151811061270057fe5b602002602001018190525060608260405190808252806020026020018201604052801561274157816020015b606081526020019060019003908161272c5790505b50905060005b83811015612797576127788760600151828151811061276257fe5b60200260200101516001600160a01b03166131ed565b82828151811061278457fe5b6020908102919091010152600101612747565b506127a181613210565b846003815181106127ae57fe5b60200260200101819052506060836040519080825280602002602001820160405280156127ef57816020015b60608152602001906001900390816127da5790505b50905060005b8481101561282f576128108860800151828151811061276257fe5b82828151811061281c57fe5b60209081029190910101526001016127f5565b5061283981613210565b8560048151811061284657fe5b60200260200101819052506128688760a0015167ffffffffffffffff166131da565b8560058151811061287557fe5b602002602001018190525061288985613210565b979650505050505050565b61289c6143f6565b60006128a78361329a565b91509150806128e75760405162461bcd60e51b815260040180806020018281038252602481526020018061470e6024913960400191505060405180910390fd5b6114e882613465565b60006116b983836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f00000000000000008152506138e9565b6000600882111561295b57612954836007198401600a0a63ffffffff6124fc16565b90506116bc565b6116b9836008849003600a0a63ffffffff61253e16565b604080516020808252818301909252600091606091906020820181803683375050506020810184905290506000805b60208160ff1610156129e857828160ff16815181106129bc57fe5b01602001516001600160f81b031916156129db576001909101906129e0565b6129e8565b6001016129a1565b50600860ff82161015612a0057600092505050610e53565b816005820360ff1681518110612a1257fe5b6020910101516001600160f81b031916602d60f81b14612a3757600092505050610e53565b816001820360ff1681518110612a4957fe5b6020910101516001600160f81b031916604d60f81b14612a6e57600092505050610e53565b5060019392505050565b612a8061434e565b6000612a8b8361394b565b9150915080612acb5760405162461bcd60e51b81526004018080602001828103825260248152602001806144d16024913960400191505060405180910390fd5b612ad36143f6565b602080840180516001600160a01b0390811684526040808701518585015291511660009081526002909252812054905b846040015151811015612b5457612b3185604001518281518110612b2357fe5b602002602001015183613bc6565b85604001518281518110612b4157fe5b6020908102919091010152600101612b03565b506080840151604083015260056060830152612b6f82613465565b5050505050565b612b7e61439a565b6000612b8861439a565b612b9061442d565b612ba1612b9c86613bff565b613c24565b90506000805b612bb083613c6e565b15612ca85780612bd257612bcb612bc684613c8f565b613cdd565b8452612ca0565b8060011415612bff57612bec612be784613c8f565b613d94565b6001600160a01b03166020850152612ca0565b8060021415612c1e57612c14612bc684613c8f565b6040850152612ca0565b8060031415612c4657612c33612be784613c8f565b6001600160a01b03166060850152612ca0565b8060041415612c6e57612c5b612be784613c8f565b6001600160a01b03166080850152612ca0565b8060051415612c9b57612c83612bc684613c8f565b67ffffffffffffffff1660a085015260019150612ca0565b612ca8565b600101612ba7565b5091935090915050915091565b60208101516000906001600160a01b0316612dec578160a0015167ffffffffffffffff16421115612ce857506001610e53565b8160400151471015612cfc57506003610e53565b606082015160408084015190516000926001600160a01b0316916127109184818181858888f193505050503d8060008114612d53576040519150601f19603f3d011682016040523d82523d6000602084013e612d58565b606091505b5050905080612d6b575060049050610e53565b7f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5983602001518460600151856040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a15060009050610e53565b8160a0015167ffffffffffffffff16421115612e0a57506001610e53565b81516020808401516001600160a01b031660009081526003909152604090205414612e3757506002610e53565b602080830151604080516370a0823160e01b815230600482015290516000936001600160a01b03909316926370a082319261c3509260248083019392829003018187803b158015612e8757600080fd5b5086fa158015612e9b573d6000803e3d6000fd5b50505050506040513d6020811015612eb257600080fd5b50516040840151909150811015612ecd575060039050610e53565b600083602001516001600160a01b031663a9059cbb61c350866060015187604001516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b158015612f3e57600080fd5b5087f1158015612f52573d6000803e3d6000fd5b50505050506040513d6020811015612f6957600080fd5b505190508015612ff6577f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5984602001518560600151866040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a15060009150610e539050565b5060059150610e539050565b60408051600480825260a08201909252606091829190816020015b606081526020019060019003908161301d575050835190915061303f906131da565b8160008151811061304c57fe5b602002602001018190525061306483602001516131da565b8160018151811061307157fe5b602002602001018190525061309283604001516001600160a01b03166131ed565b8160028151811061309f57fe5b60200260200101819052506130bd836060015163ffffffff166131da565b816003815181106130ca57fe5b6020026020010181905250610e2781613210565b6000818361316a5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561312f578181015183820152602001613117565b50505050905090810190601f16801561315c5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161317657fe5b0495945050505050565b600081848411156131d25760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561312f578181015183820152602001613117565b505050900390565b60606116bc6131e883613dae565b613e94565b60408051600560a21b8318601482015260348101909152606090610e2781613e94565b60608151600014156132315750604080516000815260208101909152610e53565b60608260008151811061324057fe5b602002602001015190506000600190505b8351811015613281576132778285838151811061326a57fe5b6020026020010151613ee6565b9150600101613251565b50610e27613294825160c060ff16613f63565b82613ee6565b6132a26143f6565b60006132ac6143f6565b6132b461442d565b6132c0612b9c86613bff565b90506000805b6132cf83613c6e565b15612ca857806132f5576132e5612be784613c8f565b6001600160a01b0316845261345d565b806001141561339657606061331161330c85613c8f565b61405b565b9050805160405190808252806020026020018201604052801561333e578160200160208202803683370190505b50602086015260005b815181101561338f5761336c82828151811061335f57fe5b6020026020010151613cdd565b8660200151828151811061337c57fe5b6020908102919091010152600101613347565b505061345d565b80600214156134385760606133ad61330c85613c8f565b905080516040519080825280602002602001820160405280156133da578160200160208202803683370190505b50604086015260005b815181101561338f576134088282815181106133fb57fe5b6020026020010151613d94565b8660400151828151811061341857fe5b6001600160a01b03909216602092830291909101909101526001016133e3565b8060031415612c9b5761344d612bc684613c8f565b63ffffffff166060850152600191505b6001016132c6565b80516001600160a01b031661368f5760005b8160200151518110156136895760008260400151828151811061349657fe5b60200260200101516001600160a01b0316612710846020015184815181106134ba57fe5b60209081029190910101516040516000818181858888f193505050503d8060008114613502576040519150601f19603f3d011682016040523d82523d6000602084013e613507565b606091505b50509050806135ca577f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e83600001518460400151848151811061354657fe5b60200260200101518560200151858151811061355e57fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a1613680565b7fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a83600001518460400151848151811061360057fe5b60200260200101518560200151858151811061361857fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b50600101613477565b506138e6565b60005b8160200151518110156138e457600082600001516001600160a01b031663a9059cbb61c350856040015185815181106136c757fe5b6020026020010151866020015186815181106136df57fe5b60200260200101516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b15801561373657600080fd5b5087f115801561374a573d6000803e3d6000fd5b50505050506040513d602081101561376157600080fd5b505190508015613825577fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a8360000151846040015184815181106137a157fe5b6020026020010151856020015185815181106137b957fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a16138db565b7f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e83600001518460400151848151811061385b57fe5b60200260200101518560200151858151811061387357fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b50600101613692565b505b50565b600081836139385760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561312f578181015183820152602001613117565b5082848161394257fe5b06949350505050565b61395361434e565b600061395d61434e565b61396561442d565b613971612b9c86613bff565b90506000805b61398083613c6e565b15613bb8578061399d57613996612bc684613c8f565b8452613bb0565b80600114156139c5576139b2612be784613c8f565b6001600160a01b03166020850152613bb0565b8060021415613a545760606139dc61330c85613c8f565b90508051604051908082528060200260200182016040528015613a09578160200160208202803683370190505b50604086015260005b8151811015613a4d57613a2a82828151811061335f57fe5b86604001518281518110613a3a57fe5b6020908102919091010152600101613a12565b5050613bb0565b8060031415613ae9576060613a6b61330c85613c8f565b90508051604051908082528060200260200182016040528015613a98578160200160208202803683370190505b50606086015260005b8151811015613a4d57613ab98282815181106133fb57fe5b86606001518281518110613ac957fe5b6001600160a01b0390921660209283029190910190910152600101613aa1565b8060041415613b7e576060613b0061330c85613c8f565b90508051604051908082528060200260200182016040528015613b2d578160200160208202803683370190505b50608086015260005b8151811015613a4d57613b4e8282815181106133fb57fe5b86608001518281518110613b5e57fe5b6001600160a01b0390921660209283029190910190910152600101613b36565b8060051415613bab57613b93612bc684613c8f565b67ffffffffffffffff1660a085015260019150613bb0565b613bb8565b600101613977565b509195600195509350505050565b60006008821115613be857612954836007198401600a0a63ffffffff61253e16565b6116b9836008849003600a0a63ffffffff6124fc16565b613c0761444d565b506040805180820190915281518152602082810190820152919050565b613c2c61442d565b613c358261412c565b613c3e57600080fd5b6000613c4d836020015161415c565b60208085015160408051808201909152868152920190820152915050919050565b6000613c7861444d565b505080518051602091820151919092015191011190565b613c9761444d565b613ca082613c6e565b613ca957600080fd5b60208201516000613cb9826141bf565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590613cf257508151602110155b613cfb57600080fd5b6000613d0a836020015161415c565b90508083600001511015613d65576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b825160208085015183018051928490039291831015613d8b57826020036101000a820491505b50949350505050565b8051600090601514613da557600080fd5b6116bc82613cdd565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416613df257506018613e16565b6fffffffffffffffffffffffffffffffff198416613e1257506010613e16565b5060005b6020811015613e4c57818181518110613e2b57fe5b01602001516001600160f81b03191615613e4457613e4c565b600101613e16565b60008160200390506060816040519080825280601f01601f191660200182016040528015613e81576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015613ec65750607f60f81b82600081518110613eb457fe5b01602001516001600160f81b03191611155b15613ed2575080610e53565b6116bc613ee48351608060ff16613f63565b835b6060806040519050835180825260208201818101602087015b81831015613f17578051835260209283019201613eff565b50855184518101855292509050808201602086015b81831015613f44578051835260209283019201613f2c565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310613fb3576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b6040805160018082528183019092526060916020820181803683370190505090506037841161400d5782840160f81b81600081518110613fef57fe5b60200101906001600160f81b031916908160001a90535090506116bc565b606061401885613dae565b90508381510160370160f81b8260008151811061403157fe5b60200101906001600160f81b031916908160001a9053506140528282613ee6565b95945050505050565b60606140668261412c565b61406f57600080fd5b600061407a836142f2565b90506060816040519080825280602002602001820160405280156140b857816020015b6140a561444d565b81526020019060019003908161409d5790505b50905060006140ca856020015161415c565b60208601510190506000805b84811015614121576140e7836141bf565b915060405180604001604052808381526020018481525084828151811061410a57fe5b6020908102919091010152918101916001016140d6565b509195945050505050565b805160009061413d57506000610e53565b6020820151805160001a9060c0821015612a6e57600092505050610e53565b8051600090811a6080811015614176576000915050610e53565b60b8811080614191575060c08110801590614191575060f881105b156141a0576001915050610e53565b60c08110156141b45760b519019050610e53565b60f519019050610e53565b80516000908190811a60808110156141da57600191506142eb565b60b88110156141ef57607e19810191506142eb565b60c081101561426957600060b78203600186019550806020036101000a865104915060018101820193505080831015614263576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b506142eb565b60f881101561427e5760be19810191506142eb565b600060f78203600186019550806020036101000a8651049150600181018201935050808310156142e9576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b805160009061430357506000610e53565b60008090506000614317846020015161415c565b602085015185519181019250015b8082101561434557614336826141bf565b60019093019290910190614325565b50909392505050565b6040518060c001604052806000801916815260200160006001600160a01b03168152602001606081526020016060815260200160608152602001600067ffffffffffffffff1681525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b60408051608081018252600080825260208201819052918101829052606081019190915290565b604051806080016040528060006001600160a01b031681526020016060815260200160608152602001600063ffffffff1681525090565b604051806040016040528061444061444d565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe746865206d6573736167652073656e646572206d75737420626520696e63656e746976697a6520636f6e7472616374466f72206d696e69546f6b656e2c20746865207472616e7366657220616d6f756e74206d757374206e6f74206265206c657373207468616e2031756e7265636f676e697a6564207472616e736665724f75742073796e207061636b61676565787069726554696d65206d7573742062652074776f206d696e75746573206c61746572616d6f756e7420697320746f6f206c617267652c20657863656564206d6178696d756d206265703220746f6b656e20616d6f756e7474686520636f6e747261637420686173206e6f74206265656e20626f756e6420746f20616e79206265703220746f6b656e726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e736665724f757420424e4220616d6f756e7420616e64206d696e696d756d2072656c6179466565616d6f756e7420697320746f6f206c617267652c2075696e74323536206f766572666c6f774c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620726566756e644164647273696e76616c6964207472616e7366657220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e20746865206d696e696d756d2072656c6179466565746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374756e7265636f676e697a6564207472616e736665724f75742061636b207061636b6167654c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620616d6f756e7473746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d73672073656e646572206d75737420626520746f6b656e4d616e6167657274686520636f6e7472616374206e6f7420696e69742079657400000000000000726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e7366657220424e4220616d6f756e7420616e642072656c6179466565696e76616c696420726563656976656420424e4220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6ea26469706673582212200ed3b493edce71fd9235e1f674e51718f846ead6af3ed00debad31d4e3d4dc5f64736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001005": { + "balance": "0x0", + "code": "0x6080604052600436106102765760003560e01c80637e146cc51161014f578063af400681116100c1578063e75d72c71161007a578063e75d72c714610795578063e89a3020146107c8578063f9a2bbc7146107f2578063fc3e590814610807578063fd6a68791461081c578063fdd31fcd146108315761027d565b8063af400681146106ed578063bd4cc83014610717578063c81b166214610741578063dc927faf14610756578063dcae76ab1461076b578063e1c7392a146107805761027d565b8063a3c3c0ad11610113578063a3c3c0ad146105b3578063a78abc16146105c8578063a7c6a59d146105dd578063ab51bb96146105f2578063ac43175114610607578063ace9fcc2146106d85761027d565b80637e146cc51461052c578063930e1b091461054157806396713da9146105745780639dc0926214610589578063a1a11bf51461059e5761027d565b806343756e5c116101e85780636e47b482116101ac5780636e47b482146104645780636f93d2e61461047957806370fd5bad146104d857806374f2272d146104ed57806375d47a0a146105025780637942fd05146105175761027d565b806343756e5c146103e4578063493279b1146103f95780634bf6c8821461042557806351e806721461043a578063541333071461044f5761027d565b806312950c461161023a57806312950c46146103165780631b20087c1461032b5780631c643312146103405780633a975612146102825780633dffc3871461038657806340bb43c0146103b15761027d565b8063081e9d131461028257806308f2ec06146102a9578063093f2fc4146102be5780630bee7a67146102d357806310e06a76146103015761027d565b3661027d57005b600080fd5b34801561028e57600080fd5b50610297610864565b60408051918252519081900360200190f35b3480156102b557600080fd5b50610297610869565b3480156102ca57600080fd5b5061029761086e565b3480156102df57600080fd5b506102e8610873565b6040805163ffffffff9092168252519081900360200190f35b34801561030d57600080fd5b50610297610878565b34801561032257600080fd5b5061029761087e565b34801561033757600080fd5b50610297610884565b34801561034c57600080fd5b5061036a6004803603602081101561036357600080fd5b503561088a565b604080516001600160a01b039092168252519081900360200190f35b34801561039257600080fd5b5061039b610864565b6040805160ff9092168252519081900360200190f35b3480156103bd57600080fd5b50610297600480360360208110156103d457600080fd5b50356001600160a01b03166108b1565b3480156103f057600080fd5b5061036a6108c3565b34801561040557600080fd5b5061040e6108c9565b6040805161ffff9092168252519081900360200190f35b34801561043157600080fd5b5061039b6108ce565b34801561044657600080fd5b5061036a6108d3565b34801561045b57600080fd5b50610297610873565b34801561047057600080fd5b5061036a6108d9565b34801561048557600080fd5b506104c46004803603608081101561049c57600080fd5b506001600160a01b0381358116916020810135909116906040810135906060013515156108df565b604080519115158252519081900360200190f35b3480156104e457600080fd5b5061039b610cad565b3480156104f957600080fd5b50610297610cb2565b34801561050e57600080fd5b5061036a610cb8565b34801561052357600080fd5b5061039b610cbe565b34801561053857600080fd5b50610297610cc3565b34801561054d57600080fd5b506102976004803603602081101561056457600080fd5b50356001600160a01b0316610cc8565b34801561058057600080fd5b5061039b610cda565b34801561059557600080fd5b5061036a610cdf565b3480156105aa57600080fd5b5061036a610ce5565b3480156105bf57600080fd5b50610297610ceb565b3480156105d457600080fd5b506104c4610cf1565b3480156105e957600080fd5b50610297610cfa565b3480156105fe57600080fd5b506102e8610d00565b34801561061357600080fd5b506106d66004803603604081101561062a57600080fd5b81019060208101813564010000000081111561064557600080fd5b82018360208201111561065757600080fd5b8035906020019184600183028401116401000000008311171561067957600080fd5b91939092909160208101903564010000000081111561069757600080fd5b8201836020820111156106a957600080fd5b803590602001918460018302840111640100000000831117156106cb57600080fd5b509092509050610d05565b005b3480156106e457600080fd5b50610297611354565b3480156106f957600080fd5b506102976004803603602081101561071057600080fd5b503561135a565b34801561072357600080fd5b506102976004803603602081101561073a57600080fd5b50356113b5565b34801561074d57600080fd5b5061036a6113ce565b34801561076257600080fd5b5061036a6113d4565b34801561077757600080fd5b506102976113da565b34801561078c57600080fd5b506106d66113e0565b3480156107a157600080fd5b506106d6600480360360208110156107b857600080fd5b50356001600160a01b03166114a9565b3480156107d457600080fd5b5061036a600480360360208110156107eb57600080fd5b5035611602565b3480156107fe57600080fd5b5061036a61160f565b34801561081357600080fd5b5061039b611615565b34801561082857600080fd5b5061036a61161a565b34801561083d57600080fd5b506102976004803603602081101561085457600080fd5b50356001600160a01b0316611620565b600181565b602881565b605081565b606481565b600b5481565b60015481565b600c5481565b6006818154811061089757fe5b6000918252602090912001546001600160a01b0316905081565b60076020526000908152604090205481565b61100181565b603881565b600881565b61200081565b61100581565b6000805460ff16610937576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604482015290519081900360640190fd5b33612000146109775760405162461bcd60e51b815260040180806020018281038252602f815260200180612164602f913960400191505060405180910390fd5b600082156109fc57604080516309a99b4f60e41b8152611005600482015260248101869052905161100291639a99b4f09160448083019260209291908290030181600087803b1580156109c957600080fd5b505af11580156109dd573d6000803e3d6000fd5b505050506040513d60208110156109f357600080fd5b50519050610a75565b604080516309a99b4f60e41b8152611005600482015260248101869052905161100491639a99b4f09160448083019260209291908290030181600087803b158015610a4657600080fd5b505af1158015610a5a573d6000803e3d6000fd5b505050506040513d6020811015610a7057600080fd5b505190505b600c805460010190556000610a8982611632565b600954909150610a9f908263ffffffff61166116565b600955600a54610ac7908290610abb908563ffffffff61166116565b9063ffffffff6116c216565b600a556001600160a01b038716600090815260056020526040902054610b3357600680546001810182556000919091527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0180546001600160a01b0319166001600160a01b0389161790555b6001600160a01b038088166000908152600560209081526040808320805460010190559289168252600790522054610bb157600880546001810182556000919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30180546001600160a01b0319166001600160a01b0388161790555b6001600160a01b038616600090815260076020526040902080546001019055600c54606411610ca057600b54600954600a5460408051938452602084019290925282820152517f2649b1b772a1a74bd332a67695e285317dd722941166595741c60a00fa65bb759181900360600190a16000610c2b611704565b90506000610c376119e8565b6001600160a01b0389166000908152600d6020526040902054909150610c75908290610c69908563ffffffff61166116565b9063ffffffff61166116565b6001600160a01b0389166000908152600d6020526040812091909155600b80546001019055600c5550505b5060019695505050505050565b600281565b60035481565b61100881565b600b81565b600581565b60056020526000908152604090205481565b600981565b61100781565b61100681565b600a5481565b60005460ff1681565b60045481565b600081565b3361100714610d455760405162461bcd60e51b815260040180806020018281038252602e8152602001806120a9602e913960400191505060405180910390fd5b60005460ff16610d865760405162461bcd60e51b81526004018080602001828103825260218152602001806120d76021913960400191505060405180910390fd5b610dfa84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601f81527f68656164657252656c61796572526577617264526174654d6f6c6563756c650060208201529150611c669050565b15610ec75760208114610e3e5760405162461bcd60e51b81526004018080602001828103825260328152602001806121936032913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610e7c91858580838501838280828437600092019190915250611d4d92505050565b9050600254811115610ebf5760405162461bcd60e51b8152600401808060200182810382526060815260200180611f826060913960600191505060405180910390fd5b6001556112c2565b610f2084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805160608101909152602280825290925090506120876020830139611c66565b15610ff85760208114610f645760405162461bcd60e51b815260040180806020018281038252602e815260200180612038602e913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610fa291858580838501838280828437600092019190915250611d4d92505050565b90508015801590610fb557506001548110155b610ff05760405162461bcd60e51b815260040180806020018281038252606c8152602001806120f8606c913960800191505060405180910390fd5b6002556112c2565b61106c84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601a81527f63616c6c6572436f6d70656e736174696f6e4d6f6c6563756c6500000000000060208201529150611c669050565b1561113957602081146110b05760405162461bcd60e51b815260040180806020018281038252602e815260200180612038602e913960400191505060405180910390fd5b604080516020601f84018190048102820181019092528281526000916110ee91858580838501838280828437600092019190915250611d4d92505050565b90506004548111156111315760405162461bcd60e51b8152600401808060200182810382526056815260200180611fe26056913960600191505060405180910390fd5b6003556112c2565b6111ad84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601d81527f63616c6c6572436f6d70656e736174696f6e44656e6f6d696e61746f7200000060208201529150611c669050565b1561128557602081146111f15760405162461bcd60e51b815260040180806020018281038252602e815260200180612038602e913960400191505060405180910390fd5b604080516020601f840181900481028201810190925282815260009161122f91858580838501838280828437600092019190915250611d4d92505050565b9050801580159061124257506003548110155b61127d5760405162461bcd60e51b8152600401808060200182810382526061815260200180611f216061913960800191505060405180910390fd5b6004556112c2565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b60025481565b60006028821161136b5750806113b0565b81602810801561137c575060508211155b15611389575060286113b0565b60508211801561139a5750606e8211155b156113aa575060788190036113b0565b50600481045b919050565b6000602882116113c65750806113b0565b5060286113b0565b61100281565b61100381565b60095481565b60005460ff1615611438576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b60005460ff1615611486576040805162461bcd60e51b8152602060048201526013602482015272185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604482015290519081900360640190fd5b60018080556005600255600381905560506004556000805460ff19169091179055565b6001600160a01b0381166000908152600d602052604090205480611508576040805162461bcd60e51b81526020600482015260116024820152701b9bc81c995b185e595c881c995dd85c99607a1b604482015290519081900360640190fd5b6001600160a01b0382166000818152600d60205260408082208290555184929184156108fc02918591818181858888f193505050506115b85760405161100290819084156108fc029085906000818181858888f19350505050158015611572573d6000803e3d6000fd5b506040805161100281526020810185905281517f24502838a334c8f2bb2ee1f8262a4fa7183e4489a717e96cc824e325f8b39e11929181900390910190a15050506115ff565b604080516001600160a01b03851681526020810184905281517f24502838a334c8f2bb2ee1f8262a4fa7183e4489a717e96cc824e325f8b39e11929181900390910190a150505b50565b6008818154811061089757fe5b61100081565b600381565b61100481565b600d6020526000908152604090205481565b600061165b60025461164f60015485611d5290919063ffffffff16565b9063ffffffff611dab16565b92915050565b6000828201838110156116bb576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b60006116bb83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611ded565b600954600680546040805160208084028201810190925282815260009493859360609383018282801561176057602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611742575b5050505050905060608151604051908082528060200260200182016040528015611794578160200160208202803683370190505b50905060005b82518110156118215760008382815181106117b157fe5b6020026020010151905060006117eb60056000846001600160a01b03166001600160a01b03168152602001908152602001600020546113b5565b9050808484815181106117fa57fe5b6020908102919091010152611815868263ffffffff61166116565b9550505060010161179a565b50600061183f60045461164f60035488611d5290919063ffffffff16565b9050611851858263ffffffff6116c216565b94508460015b845181101561192857600061188c8761164f8a88868151811061187657fe5b6020026020010151611d5290919063ffffffff16565b90506118d981600d60008986815181106118a257fe5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000205461166190919063ffffffff16565b600d60008885815181106118e957fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205561191d838263ffffffff6116c216565b925050600101611857565b5061193e81600d6000876000815181106118a257fe5b600d60008660008151811061194f57fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002081905550600060098190555060008090505b84518110156119d057600560008683815181106119a257fe5b6020908102919091018101516001600160a01b03168252810191909152604001600090812055600101611989565b506119dd60066000611ee9565b509450505050505b90565b600a546008805460408051602080840282018101909252828152600094938593606093830182828015611a4457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611a26575b5050505050905060608151604051908082528060200260200182016040528015611a78578160200160208202803683370190505b50905060005b8251811015611af7576000838281518110611a9557fe5b602002602001015190506000611acf60076000846001600160a01b03166001600160a01b031681526020019081526020016000205461135a565b905080848481518110611ade57fe5b6020908102919091010152949094019350600101611a7e565b506000611b1560045461164f60035488611d5290919063ffffffff16565b9050611b27858263ffffffff6116c216565b94508460015b8451811015611bb1576000611b4c8761164f8a88868151811061187657fe5b9050611b6281600d60008986815181106118a257fe5b600d6000888581518110611b7257fe5b6020908102919091018101516001600160a01b0316825281019190915260400160002055611ba6838263ffffffff6116c216565b925050600101611b2d565b50611bc781600d6000876000815181106118a257fe5b600d600086600081518110611bd857fe5b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055506000600a8190555060008090505b8451811015611c595760076000868381518110611c2b57fe5b6020908102919091018101516001600160a01b03168252810191909152604001600090812055600101611c12565b506119dd60086000611ee9565b6000816040516020018082805190602001908083835b60208310611c9b5780518252601f199092019160209182019101611c7c565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310611d095780518252601f199092019160209182019101611cea565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b600082611d615750600061165b565b82820282848281611d6e57fe5b04146116bb5760405162461bcd60e51b81526004018080602001828103825260218152602001806120666021913960400191505060405180910390fd5b60006116bb83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611e84565b60008184841115611e7c5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611e41578181015183820152602001611e29565b50505050905090810190601f168015611e6e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008183611ed35760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315611e41578181015183820152602001611e29565b506000838581611edf57fe5b0495945050505050565b50805460008255906000526020600020908101906115ff91906119e591905b80821115611f1c5760008155600101611f08565b509056fe746865206e657743616c6c6572436f6d70656e736174696f6e44656e6f6d696e61746f72206d757374206e6f74206265207a65726f20616e64206e6f206c657373207468616e2063616c6c6572436f6d70656e736174696f6e4d6f6c6563756c656e65772068656164657252656c61796572526577617264526174654d6f6c6563756c652073686f756c646e27742062652067726561746572207468616e2068656164657252656c617965725265776172645261746544656e6f6d696e61746f726e65772063616c6c6572436f6d70656e736174696f6e4d6f6c6563756c652073686f756c646e27742062652067726561746572207468616e2063616c6c6572436f6d70656e736174696f6e44656e6f6d696e61746f726c656e677468206f6620726577617264466f7256616c696461746f725365744368616e6765206d69736d61746368536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7768656164657252656c617965725265776172645261746544656e6f6d696e61746f72746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374636f6e747261637420686173206e6f74206265656e20696e697469616c697a6564746865206e65772068656164657252656c617965725265776172645261746544656e6f6d696e61746f72206d757374206e6f74206265207a65726f20616e64206e6f206c657373207468616e2068656164657252656c61796572526577617264526174654d6f6c6563756c65746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e74726163746c656e677468206f662068656164657252656c61796572526577617264526174654d6f6c6563756c65206d69736d61746368a2646970667358221220cd7c1ec8296551de0c54d97959872d6570445d6b1250fde9150f66f3ae10dc7164736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001006": { + "balance": "0x0", + "code": "0x6080604052600436106101c25760003560e01c806395468d26116100f7578063c81b166211610095578063f9a2bbc711610064578063f9a2bbc714610529578063fb7cfdd71461053e578063fc3e590814610553578063fd6a687914610568576101c2565b8063c81b1662146104d5578063dc927faf146104ea578063e1c7392a146104ff578063e79a198f14610514576101c2565b8063a1a11bf5116100d1578063a1a11bf5146103c7578063a78abc16146103dc578063ab51bb96146103f1578063ac43175114610406576101c2565b806395468d261461038857806396713da91461039d5780639dc09262146103b2576101c2565b8063541d55481161016457806370fd5bad1161013e57806370fd5bad1461033457806375d47a0a146103495780637942fd051461035e5780637ae2308814610373576101c2565b8063541d5548146102b15780636a87d780146102f85780636e47b4821461031f576101c2565b806343756e5c116101a057806343756e5c1461022a578063493279b11461025b5780634bf6c8821461028757806351e806721461029c576101c2565b80630bee7a67146101c75780631aa3a008146101f55780633dffc387146101ff575b600080fd5b3480156101d357600080fd5b506101dc61057d565b6040805163ffffffff9092168252519081900360200190f35b6101fd610582565b005b34801561020b57600080fd5b5061021461077d565b6040805160ff9092168252519081900360200190f35b34801561023657600080fd5b5061023f610782565b604080516001600160a01b039092168252519081900360200190f35b34801561026757600080fd5b50610270610788565b6040805161ffff9092168252519081900360200190f35b34801561029357600080fd5b5061021461078d565b3480156102a857600080fd5b5061023f610792565b3480156102bd57600080fd5b506102e4600480360360208110156102d457600080fd5b50356001600160a01b0316610798565b604080519115158252519081900360200190f35b34801561030457600080fd5b5061030d6107b6565b60408051918252519081900360200190f35b34801561032b57600080fd5b5061023f6107bc565b34801561034057600080fd5b506102146107c2565b34801561035557600080fd5b5061023f6107c7565b34801561036a57600080fd5b506102146107cd565b34801561037f57600080fd5b5061030d6107d2565b34801561039457600080fd5b5061030d6107df565b3480156103a957600080fd5b506102146107eb565b3480156103be57600080fd5b5061023f6107f0565b3480156103d357600080fd5b5061023f6107f6565b3480156103e857600080fd5b506102e46107fc565b3480156103fd57600080fd5b506101dc610805565b34801561041257600080fd5b506101fd6004803603604081101561042957600080fd5b81019060208101813564010000000081111561044457600080fd5b82018360208201111561045657600080fd5b8035906020019184600183028401116401000000008311171561047857600080fd5b91939092909160208101903564010000000081111561049657600080fd5b8201836020820111156104a857600080fd5b803590602001918460018302840111640100000000831117156104ca57600080fd5b50909250905061080a565b3480156104e157600080fd5b5061023f610c2c565b3480156104f657600080fd5b5061023f610c32565b34801561050b57600080fd5b506101fd610c38565b34801561052057600080fd5b506101fd610cba565b34801561053557600080fd5b5061023f610e73565b34801561054a57600080fd5b5061030d610e79565b34801561055f57600080fd5b50610214610e7f565b34801561057457600080fd5b5061023f610e84565b606481565b3360009081526004602052604090205460ff16156105df576040805162461bcd60e51b81526020600482015260156024820152741c995b185e595c88185b1c9958591e48195e1a5cdd605a1b604482015290519081900360640190fd5b60005460ff16610632576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b61063b33610e8a565b156106775760405162461bcd60e51b815260040180806020018281038252602781526020018061109c6027913960400191505060405180910390fd5b3332146106c1576040805162461bcd60e51b81526020600482015260136024820152721b9bc81c1c9bde1e481a5cc8185b1b1bddd959606a1b604482015290519081900360640190fd5b60015434146107015760405162461bcd60e51b81526004018080602001828103825260258152602001806110776025913960400191505060405180910390fd5b604080518082018252600180548252600254602080840191825233600081815260038352868120955186559251948401949094556004815290849020805460ff1916909217909155825191825291517fdb33a09d38b59a8fa8b7d92a1d82c8015e99f05f67ae9c9ae623157767959496929181900390910190a1565b600181565b61100181565b603881565b600881565b61200081565b6001600160a01b031660009081526004602052604090205460ff1690565b60025481565b61100581565b600281565b61100881565b600b81565b68056bc75e2d6310000081565b67016345785d8a000081565b600981565b61100781565b61100681565b60005460ff1681565b600081565b60005460ff1661085d576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b336110071461089d5760405162461bcd60e51b815260040180806020018281038252602e8152602001806110c3602e913960400191505060405180910390fd5b61090384848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e1c995c5d5a5c995911195c1bdcda5d608a1b60208201529150610e909050565b15610a0657602081146109475760405162461bcd60e51b81526004018080602001828103825260228152602001806110f16022913960400191505060405180910390fd5b604080516020601f840181900481028201810190925282815260009161098591858580838501838280828437600092019190915250610f7792505050565b90506001811180156109a05750683635c9adc5dea000008111155b80156109ad575060025481115b6109fe576040805162461bcd60e51b815260206004820181905260248201527f7468652072657175697265644465706f736974206f7574206f662072616e6765604482015290519081900360640190fd5b600155610b9a565b610a6184848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260048152636475657360e01b60208201529150610e909050565b15610b5d5760208114610abb576040805162461bcd60e51b815260206004820152601760248201527f6c656e677468206f662064756573206d69736d61746368000000000000000000604482015290519081900360640190fd5b604080516020601f8401819004810282018101909252828152600091610af991858580838501838280828437600092019190915250610f7792505050565b9050600081118015610b0c575060015481105b610b55576040805162461bcd60e51b81526020600482015260156024820152747468652064756573206f7574206f662072616e676560581b604482015290519081900360640190fd5b600255610b9a565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b60005460ff1615610c90576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b68056bc75e2d63100000600190815567016345785d8a00006002556000805460ff19169091179055565b3360009081526004602052604090205460ff16610d15576040805162461bcd60e51b81526020600482015260146024820152731c995b185e595c88191bc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b60005460ff16610d68576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b610d7061105c565b5033600081815260036020908152604091829020825180840190935280548084526001909101549183018290529192916108fc91610db4919063ffffffff610f7c16565b6040518115909202916000818181858888f19350505050158015610ddc573d6000803e3d6000fd5b50602081015160405161100291829181156108fc0291906000818181858888f19350505050158015610e12573d6000803e3d6000fd5b50336000818152600460209081526040808320805460ff191690556003825280832083815560010192909255815192835290517fd17202129b83db7880d6b9f25df81c58ad46f7e0e2c92236b1aa10663a4876679281900390910190a15050565b61100081565b60015481565b600381565b61100481565b3b151590565b6000816040516020018082805190602001908083835b60208310610ec55780518252601f199092019160209182019101610ea6565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310610f335780518252601f199092019160209182019101610f14565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b6000610fbe83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610fc5565b9392505050565b600081848411156110545760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611019578181015183820152602001611001565b50505050905090810190601f1680156110465780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60405180604001604052806000815260200160008152509056fe6465706f7369742076616c7565206973206e6f742065786163746c79207468652073616d65636f6e7472616374206973206e6f7420616c6c6f77656420746f20626520612072656c61796572746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662072657175697265644465706f736974206d69736d61746368a2646970667358221220449507f2557413401b33bd1aa888e40f31523a5d010a891cf7383c0090d7f49a64736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001007": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b506004361061018e5760003560e01c8063831d65d1116100de578063ab51bb9611610097578063dc927faf11610071578063dc927faf14610486578063f9a2bbc71461048e578063fc3e590814610496578063fd6a68791461049e5761018e565b8063ab51bb96146103fc578063c81b166214610404578063c8509d811461040c5761018e565b8063831d65d11461034457806396713da9146103c05780639ab1a373146103c85780639dc09262146103d0578063a1a11bf5146103d8578063a78abc16146103e05761018e565b8063493279b11161014b5780636e47b482116101255780636e47b4821461032457806370fd5bad1461032c57806375d47a0a146103345780637942fd051461033c5761018e565b8063493279b1146102f55780634bf6c8821461031457806351e806721461031c5761018e565b80630bee7a67146101935780631182b875146101b45780633a21baae146102a35780633dffc387146102ab57806343756e5c146102c95780634900c4ea146102ed575b600080fd5b61019b6104a6565b6040805163ffffffff9092168252519081900360200190f35b61022e600480360360408110156101ca57600080fd5b60ff82351691908101906040810160208201356401000000008111156101ef57600080fd5b82018360208201111561020157600080fd5b8035906020019184600183028401116401000000008311171561022357600080fd5b5090925090506104ab565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610268578181015183820152602001610250565b50505050905090810190601f1680156102955780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61019b61059a565b6102b361059f565b6040805160ff9092168252519081900360200190f35b6102d16105a4565b604080516001600160a01b039092168252519081900360200190f35b6102b36105aa565b6102fd6105af565b6040805161ffff9092168252519081900360200190f35b6102b36105b4565b6102d16105b9565b6102d16105bf565b6102b36105c5565b6102d16105ca565b6102b36105d0565b6103be6004803603604081101561035a57600080fd5b60ff823516919081019060408101602082013564010000000081111561037f57600080fd5b82018360208201111561039157600080fd5b803590602001918460018302840111640100000000831117156103b357600080fd5b5090925090506105d5565b005b6102b3610667565b61019b61066c565b6102d1610671565b6102d1610677565b6103e861067d565b604080519115158252519081900360200190f35b61019b6105aa565b6102d1610686565b6103be6004803603604081101561042257600080fd5b60ff823516919081019060408101602082013564010000000081111561044757600080fd5b82018360208201111561045957600080fd5b8035906020019184600183028401116401000000008311171561047b57600080fd5b50909250905061068c565b6102d1610703565b6102d1610709565b6102b361070f565b6102d1610714565b606481565b606033612000146104ed5760405162461bcd60e51b815260040180806020018281038252602f8152602001806113e7602f913960400191505060405180910390fd5b6104f5611382565b600061053685858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061071a92505050565b91509150806105525761054960646107e0565b92505050610593565b600061055d8361084a565b905063ffffffff811661058457505060408051600081526020810190915291506105939050565b61058d816107e0565b93505050505b9392505050565b606681565b600181565b61100181565b600081565b603881565b600881565b61200081565b61100581565b600281565b61100881565b600b81565b33612000146106155760405162461bcd60e51b815260040180806020018281038252602f8152602001806113e7602f913960400191505060405180910390fd5b6040805162461bcd60e51b815260206004820152601e60248201527f7265636569766520756e65787065637465642061636b207061636b6167650000604482015290519081900360640190fd5b505050565b600981565b606581565b61100781565b61100681565b60005460ff1681565b61100281565b33612000146106cc5760405162461bcd60e51b815260040180806020018281038252602f8152602001806113e7602f913960400191505060405180910390fd5b60405162461bcd60e51b81526004018080602001828103825260238152602001806114166023913960400191505060405180910390fd5b61100381565b61100081565b600381565b61100481565b610722611382565b600061072c611382565b6107346113ac565b61074561074086610beb565b610c10565b90506000805b61075483610c5a565b156107d357806107765761076f61076a84610c7b565b610cc9565b84526107cb565b80600114156107955761078b61076a84610c7b565b60208501526107cb565b80600214156107c6576107af6107aa84610c7b565b610d42565b6001600160a01b03166040850152600191506107cb565b6107d3565b60010161074b565b5091935090915050915091565b604080516001808252818301909252606091829190816020015b60608152602001906001900390816107fa5790505090506108208363ffffffff16610d62565b8160008151811061082d57fe5b602002602001018190525061084181610d75565b9150505b919050565b60006108598260400151610dff565b6108c557604080516020808252601c908201527f74686520746172676574206973206e6f74206120636f6e7472616374000000008183015290517f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb29181900360600190a1506065610845565b81604001516001600160a01b031663ac431751836000015184602001516040518363ffffffff1660e01b8152600401808060200180602001838103835285818151815260200191508051906020019080838360005b8381101561093257818101518382015260200161091a565b50505050905090810190601f16801561095f5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b8381101561099257818101518382015260200161097a565b50505050905090810190601f1680156109bf5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156109e057600080fd5b505af19250505080156109f1575060015b610be3576040516000815260443d1015610a0d57506000610aaa565b60046000803e60005160e01c6308c379a08114610a2e576000915050610aaa565b60043d036004833e81513d602482011167ffffffffffffffff82111715610a5a57600092505050610aaa565b808301805167ffffffffffffffff811115610a7c576000945050505050610aaa565b8060208301013d8601811115610a9a57600095505050505050610aaa565b601f01601f191660405250925050505b80610ab55750610b58565b7f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2816040518080602001828103825283818151815260200191508051906020019080838360005b83811015610b14578181015183820152602001610afc565b50505050905090810190601f168015610b415780820380516001836020036101000a031916815260200191505b509250505060405180910390a16066915050610845565b3d808015610b82576040519150601f19603f3d011682016040523d82523d6000602084013e610b87565b606091505b5060408051602080825283518183015283517f1279f84165b4fd69c35e1f338ff107231b036c655cd1688851e011ce617c4e8d938593928392918301919085019080838360008315610b14578181015183820152602001610afc565b506000919050565b610bf36113cc565b506040805180820190915281518152602082810190820152919050565b610c186113ac565b610c2182610e05565b610c2a57600080fd5b6000610c398360200151610e3f565b60208085015160408051808201909152868152920190820152915050919050565b6000610c646113cc565b505080518051602091820151919092015191011190565b610c836113cc565b610c8c82610c5a565b610c9557600080fd5b60208201516000610ca582610ea2565b80830160209586015260408051808201909152908152938401919091525090919050565b8051606090610cd757600080fd5b6000610ce68360200151610e3f565b83516040805191839003808352601f19601f8201168301602001909152919250606090828015610d1d576020820181803683370190505b5090506000816020019050610d39848760200151018285610fd5565b50949350505050565b8051600090601514610d5357600080fd5b610d5c82611020565b92915050565b6060610d5c610d70836110d5565b6111bb565b6060815160001415610d965750604080516000815260208101909152610845565b606082600081518110610da557fe5b602002602001015190506000600190505b8351811015610de657610ddc82858381518110610dcf57fe5b602002602001015161120d565b9150600101610db6565b50610841610df9825160c060ff1661128a565b8261120d565b3b151590565b8051600090610e1657506000610845565b6020820151805160001a9060c0821015610e3557600092505050610845565b5060019392505050565b8051600090811a6080811015610e59576000915050610845565b60b8811080610e74575060c08110801590610e74575060f881105b15610e83576001915050610845565b60c0811015610e975760b519019050610845565b60f519019050610845565b80516000908190811a6080811015610ebd5760019150610fce565b60b8811015610ed257607e1981019150610fce565b60c0811015610f4c57600060b78203600186019550806020036101000a865104915060018101820193505080831015610f46576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b50610fce565b60f8811015610f615760be1981019150610fce565b600060f78203600186019550806020036101000a865104915060018101820193505080831015610fcc576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b80610fdf57610662565b5b60208110610fff578251825260209283019290910190601f1901610fe0565b915181516020939093036101000a6000190180199091169216919091179052565b80516000901580159061103557508151602110155b61103e57600080fd5b600061104d8360200151610e3f565b905080836000015110156110a8576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b825160208085015183018051928490039291831015610d3957506020919091036101000a90049392505050565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166111195750601861113d565b6fffffffffffffffffffffffffffffffff1984166111395750601061113d565b5060005b60208110156111735781818151811061115257fe5b01602001516001600160f81b0319161561116b57611173565b60010161113d565b60008160200390506060816040519080825280601f01601f1916602001820160405280156111a8576020820181803683370190505b5080830196909652508452509192915050565b6060815160011480156111ed5750607f60f81b826000815181106111db57fe5b01602001516001600160f81b03191611155b156111f9575080610845565b610d5c61120b8351608060ff1661128a565b835b6060806040519050835180825260208201818101602087015b8183101561123e578051835260209283019201611226565b50855184518101855292509050808201602086015b8183101561126b578051835260209283019201611253565b508651929092011591909101601f01601f191660405250905092915050565b60606801000000000000000083106112da576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b604080516001808252818301909252606091602082018180368337019050509050603784116113345782840160f81b8160008151811061131657fe5b60200101906001600160f81b031916908160001a9053509050610d5c565b606061133f856110d5565b90508381510160370160f81b8260008151811061135857fe5b60200101906001600160f81b031916908160001a905350611379828261120d565b95945050505050565b6040518060600160405280606081526020016060815260200160006001600160a01b031681525090565b60405180604001604052806113bf6113cc565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e74726163747265636569766520756e6578706563746564206661696c2061636b207061636b616765a2646970667358221220a5eefec118f5b467b996b871e3b96c20aa4fe4192a6c4b34c6afc795161d4a9a64736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001008": { + "balance": "0x0", + "code": "0x6080604052600436106102465760003560e01c806375d47a0a11610139578063ab51bb96116100b6578063d9e6dae91161007a578063d9e6dae914610512578063dc927faf14610975578063f9a2bbc71461098a578063fc3e590814610566578063fd6a68791461099f578063fe3a2af5146104e857610246565b8063ab51bb96146108ca578063c81b1662146108df578063c8509d81146107da578063c8e704a414610566578063d117a110146108f457610246565b806395b9ad26116100fd57806395b9ad261461086157806396713da9146108765780639dc092621461088b578063a1a11bf5146108a0578063a78abc16146108b557610246565b806375d47a0a146106fc57806377d9dae8146107115780637942fd05146107c55780637d078e13146103b3578063831d65d1146107da57610246565b80634bc81c00116101c757806366dea52a1161018b57806366dea52a146105665780636b3f13071461057b5780636e47b4821461064357806370fd5bad1461055157806372c4e0861461065857610246565b80634bc81c00146104fd5780634bf6c8821461051257806351e80672146105275780635d499b1b1461053c5780635f558f861461055157610246565b80633dffc3871161020e5780633dffc387146103b357806343756e5c146103c8578063445fcefe146103f9578063493279b1146104bc5780634a688818146104e857610246565b80630bee7a671461024b5780630f212b1b146102795780631182b875146102a45780631f91600b1461039e57806323996b53146103b3575b600080fd5b34801561025757600080fd5b506102606109b4565b6040805163ffffffff9092168252519081900360200190f35b34801561028557600080fd5b5061028e6109b9565b6040805160ff9092168252519081900360200190f35b3480156102b057600080fd5b50610329600480360360408110156102c757600080fd5b60ff8235169190810190604081016020820135600160201b8111156102eb57600080fd5b8201836020820111156102fd57600080fd5b803590602001918460018302840111600160201b8311171561031e57600080fd5b5090925090506109be565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561036357818101518382015260200161034b565b50505050905090810190601f1680156103905780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103aa57600080fd5b5061028e610a47565b3480156103bf57600080fd5b5061028e610a4c565b3480156103d457600080fd5b506103dd610a51565b604080516001600160a01b039092168252519081900360200190f35b34801561040557600080fd5b506104aa6004803603602081101561041c57600080fd5b810190602081018135600160201b81111561043657600080fd5b82018360208201111561044857600080fd5b803590602001918460018302840111600160201b8311171561046957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610a57945050505050565b60408051918252519081900360200190f35b3480156104c857600080fd5b506104d1610bb6565b6040805161ffff9092168252519081900360200190f35b3480156104f457600080fd5b5061028e610bbb565b34801561050957600080fd5b5061028e610bc0565b34801561051e57600080fd5b5061028e610bc5565b34801561053357600080fd5b506103dd610bca565b34801561054857600080fd5b506104aa610bd0565b34801561055d57600080fd5b5061028e610bd9565b34801561057257600080fd5b5061028e610bde565b61062f6004803603604081101561059157600080fd5b6001600160a01b038235169190810190604081016020820135600160201b8111156105bb57600080fd5b8201836020820111156105cd57600080fd5b803590602001918460018302840111600160201b831117156105ee57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610be3945050505050565b604080519115158252519081900360200190f35b34801561064f57600080fd5b506103dd611465565b61062f6004803603602081101561066e57600080fd5b810190602081018135600160201b81111561068857600080fd5b82018360208201111561069a57600080fd5b803590602001918460018302840111600160201b831117156106bb57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061146b945050505050565b34801561070857600080fd5b506103dd6118b9565b61062f6004803603604081101561072757600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561075157600080fd5b82018360208201111561076357600080fd5b803590602001918460018302840111600160201b8311171561078457600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506118bf945050505050565b3480156107d157600080fd5b5061028e611dc6565b3480156107e657600080fd5b5061085f600480360360408110156107fd57600080fd5b60ff8235169190810190604081016020820135600160201b81111561082157600080fd5b82018360208201111561083357600080fd5b803590602001918460018302840111600160201b8311171561085457600080fd5b509092509050611dcb565b005b34801561086d57600080fd5b5061028e611e7e565b34801561088257600080fd5b5061028e611e83565b34801561089757600080fd5b506103dd611e88565b3480156108ac57600080fd5b506103dd611e8e565b3480156108c157600080fd5b5061062f611e94565b3480156108d657600080fd5b50610260610bbb565b3480156108eb57600080fd5b506103dd611e9d565b34801561090057600080fd5b5061091e6004803603602081101561091757600080fd5b5035611ea3565b6040805160ff988916815260208101979097526001600160a01b03909516868601526060860193909352608085019190915290931660a083015267ffffffffffffffff90921660c082015290519081900360e00190f35b34801561098157600080fd5b506103dd611efb565b34801561099657600080fd5b506103dd611f01565b3480156109ab57600080fd5b506103dd611f07565b606481565b600681565b60603361200014610a005760405162461bcd60e51b815260040180806020018281038252602f8152602001806132a0602f913960400191505060405180910390fd5b610a3f83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611f0d92505050565b949350505050565b600481565b600181565b61100181565b6020810151600090610a67613168565b50600081815260016020818152604092839020835160e081018552815460ff9081168252938201549281019290925260028101546001600160a01b031693820184905260038101546060830152600481015460808301526005015491821660a082015261010090910467ffffffffffffffff1660c082015290610aef57600092505050610bb1565b600081604001516001600160a01b03166370a082316110046040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b158015610b4d57600080fd5b505afa158015610b61573d6000803e3d6000fd5b505050506040513d6020811015610b7757600080fd5b505160808301516060840151919250600091610b989163ffffffff61219e16565b9050610baa818363ffffffff61219e16565b9450505050505b919050565b603881565b600081565b600581565b600881565b61200081565b6402540be40081565b600281565b600381565b600080610bef836121e7565b9050610bf9613168565b50600081815260016020818152604092839020835160e081018552815460ff90811682529382015492810183905260028201546001600160a01b03169481019490945260038101546060850152600481015460808501526005015491821660a084015261010090910467ffffffffffffffff1660c0830152610cbf576040805162461bcd60e51b815260206004820152601a602482015279189a5b99081c995c5d595cdd08191bd95cdb89dd08195e1a5cdd60321b604482015290519081900360640190fd5b6000610cdc8260800151836060015161219e90919063ffffffff16565b905081604001516001600160a01b0316866001600160a01b031614610d325760405162461bcd60e51b815260040180806020018281038252604581526020018061325b6045913960600191505060405180910390fd5b336001600160a01b0316866001600160a01b031663893d20e86040518163ffffffff1660e01b815260040160206040518083038186803b158015610d7557600080fd5b505afa158015610d89573d6000803e3d6000fd5b505050506040513d6020811015610d9f57600080fd5b50516001600160a01b031614610de65760405162461bcd60e51b815260040180806020018281038252602e8152602001806131f6602e913960400191505060405180910390fd5b604080516370a0823160e01b8152611004600482015290516000916001600160a01b038916916370a0823191602480820192602092909190829003018186803b158015610e3257600080fd5b505afa158015610e46573d6000803e3d6000fd5b505050506040513d6020811015610e5c57600080fd5b505160408051636eb1769f60e11b815233600482015230602482015290519192508391610eed9184916001600160a01b038c169163dd62ed3e916044808301926020929190829003018186803b158015610eb557600080fd5b505afa158015610ec9573d6000803e3d6000fd5b505050506040513d6020811015610edf57600080fd5b50519063ffffffff6121ee16565b1015610f40576040805162461bcd60e51b815260206004820152601760248201527f616c6c6f77616e6365206973206e6f7420656e6f756768000000000000000000604482015290519081900360640190fd5b600034905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b158015610f8257600080fd5b505afa158015610f96573d6000803e3d6000fd5b505050506040513d6020811015610fac57600080fd5b50519050808210801590610fc557506402540be4008206155b6110005760405162461bcd60e51b81526004018080602001828103825260378152602001806132246037913960400191505060405180910390fd5b600061100c868b612248565b905063ffffffff811661120b576001600160a01b038a166323b872dd3361100461103c898963ffffffff61219e16565b6040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050602060405180830381600087803b1580156110a457600080fd5b505af11580156110b8573d6000803e3d6000fd5b505050506040513d60208110156110ce57600080fd5b5050602086015160408088015160a089015182516323bfccdb60e21b815260048101949094526001600160a01b03909116602484015260ff1660448301525161100491638eff336c91606480830192600092919082900301818387803b15801561113757600080fd5b505af115801561114b573d6000803e3d6000fd5b50505050896001600160a01b03167f78e7dd9aefcdbf795c4936a66f7dc6d41bb56637b54f561a6bf7829dca3348a88a8860600151886040518080602001848152602001838152602001828103825285818151815260200191508051906020019080838360005b838110156111ca5781810151838201526020016111b2565b50505050905090810190601f1680156111f75780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a26112c3565b896001600160a01b03167f831c0ef4d93bda3bce08b69ae3f29ef1a6e052b833200988554158494405a1078a8360405180806020018363ffffffff1663ffffffff168152602001828103825284818151815260200191508051906020019080838360005b8381101561128757818101518382015260200161126f565b50505050905090810190601f1680156112b45780820380516001836020036101000a031916815260200191505b50935050505060405180910390a25b60008781526001602081905260408220805460ff191681559081018290556002810180546001600160a01b0319169055600381018290556004810191909155600501805468ffffffffffffffffff1916905561131d6131a4565b5060408051808201825263ffffffff831681526020810189905290516110049085156108fc029086906000818181858888f19350505050158015611365573d6000803e3d6000fd5b5061200063f7a251d760016113798461269f565b61138e886402540be40063ffffffff61272916565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156113ec5781810151838201526020016113d4565b50505050905090810190601f1680156114195780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561143a57600080fd5b505af115801561144e573d6000803e3d6000fd5b505050506001985050505050505050505b92915050565b61100581565b600080611477836121e7565b9050611481613168565b50600081815260016020818152604092839020835160e081018552815460ff90811682529382015492810183905260028201546001600160a01b03169481019490945260038101546060850152600481015460808501526005015491821660a084015261010090910467ffffffffffffffff1660c0830152611547576040805162461bcd60e51b815260206004820152601a602482015279189a5b99081c995c5d595cdd08191bd95cdb89dd08195e1a5cdd60321b604482015290519081900360640190fd5b428160c0015167ffffffffffffffff16106115a9576040805162461bcd60e51b815260206004820152601b60248201527f62696e642072657175657374206973206e6f7420657870697265640000000000604482015290519081900360640190fd5b600034905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b1580156115eb57600080fd5b505afa1580156115ff573d6000803e3d6000fd5b505050506040513d602081101561161557600080fd5b5051905080821080159061162e57506402540be4008206155b6116695760405162461bcd60e51b81526004018080602001828103825260378152602001806132246037913960400191505060405180910390fd5b60008481526001602081905260408220805460ff191681559081018290556002810180546001600160a01b0319169055600381018290556004810191909155600501805468ffffffffffffffffff191690556116c36131a4565b50604080518082018252600181526020810186905290516110049084156108fc029085906000818181858888f19350505050158015611706573d6000803e3d6000fd5b5061200063f7a251d7600161171a8461269f565b61172f876402540be40063ffffffff61272916565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561178d578181015183820152602001611775565b50505050905090810190601f1680156117ba5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156117db57600080fd5b505af11580156117ef573d6000803e3d6000fd5b5050505083604001516001600160a01b03167f831c0ef4d93bda3bce08b69ae3f29ef1a6e052b833200988554158494405a10788600160405180806020018360ff1663ffffffff168152602001828103825284818151815260200191508051906020019080838360005b83811015611871578181015183820152602001611859565b50505050905090810190601f16801561189e5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a25060019695505050505050565b61100881565b6000806118cb836121e7565b90506118d5613168565b50600081815260016020818152604092839020835160e081018552815460ff90811682529382015492810183905260028201546001600160a01b03169481019490945260038101546060850152600481015460808501526005015491821660a084015261010090910467ffffffffffffffff1660c083015261199b576040805162461bcd60e51b815260206004820152601a602482015279189a5b99081c995c5d595cdd08191bd95cdb89dd08195e1a5cdd60321b604482015290519081900360640190fd5b80604001516001600160a01b0316856001600160a01b0316146119ef5760405162461bcd60e51b815260040180806020018281038252604581526020018061325b6045913960600191505060405180910390fd5b336001600160a01b0316856001600160a01b031663893d20e86040518163ffffffff1660e01b815260040160206040518083038186803b158015611a3257600080fd5b505afa158015611a46573d6000803e3d6000fd5b505050506040513d6020811015611a5c57600080fd5b50516001600160a01b031614611ab9576040805162461bcd60e51b815260206004820152601b60248201527f6f6e6c79206265703230206f776e65722063616e2072656a6563740000000000604482015290519081900360640190fd5b600034905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b158015611afb57600080fd5b505afa158015611b0f573d6000803e3d6000fd5b505050506040513d6020811015611b2557600080fd5b50519050808210801590611b3e57506402540be4008206155b611b795760405162461bcd60e51b81526004018080602001828103825260378152602001806132246037913960400191505060405180910390fd5b60008481526001602081905260408220805460ff191681559081018290556002810180546001600160a01b0319169055600381018290556004810191909155600501805468ffffffffffffffffff19169055611bd36131a4565b50604080518082018252600781526020810186905290516110049084156108fc029085906000818181858888f19350505050158015611c16573d6000803e3d6000fd5b5061200063f7a251d76001611c2a8461269f565b611c3f876402540be40063ffffffff61272916565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611c9d578181015183820152602001611c85565b50505050905090810190601f168015611cca5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015611ceb57600080fd5b505af1158015611cff573d6000803e3d6000fd5b50505050876001600160a01b03167f831c0ef4d93bda3bce08b69ae3f29ef1a6e052b833200988554158494405a10788600760405180806020018360ff1663ffffffff168152602001828103825284818151815260200191508051906020019080838360005b83811015611d7d578181015183820152602001611d65565b50505050905090810190601f168015611daa5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a2506001979650505050505050565b600b81565b3361200014611e0b5760405162461bcd60e51b815260040180806020018281038252602f8152602001806132a0602f913960400191505060405180910390fd5b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a1505050565b600781565b600981565b61100781565b61100681565b60005460ff1681565b61100281565b600160208190526000918252604090912080549181015460028201546003830154600484015460059094015460ff9586169593946001600160a01b0390931693919291811690610100900467ffffffffffffffff1687565b61100381565b61100081565b61100481565b6060611f17613168565b6000611f228461276b565b9150915080611f78576040805162461bcd60e51b815260206004820152601f60248201527f756e7265636f676e697a6564207472616e73666572496e207061636b61676500604482015290519081900360640190fd5b815160ff1661202c576020828101805160009081526001928390526040908190208551815460ff1990811660ff928316178355935194820194909455908501516002820180546001600160a01b0319166001600160a01b03909216919091179055606085015160038201556080850151600482015560a08501516005909101805460c08701519316919093161768ffffffffffffffff00191661010067ffffffffffffffff90921691909102179055612183565b815160ff16600114156121365760006110046001600160a01b03166359b9278984602001516040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561208557600080fd5b505afa158015612099573d6000803e3d6000fd5b505050506040513d60208110156120af57600080fd5b505190506001600160a01b038116156121305760208301516040805163b99328c560e01b815260048101929092526001600160a01b0383166024830152516110049163b99328c591604480830192600092919082900301818387803b15801561211757600080fd5b505af115801561212b573d6000803e3d6000fd5b505050505b50612183565b6040805162461bcd60e51b815260206004820152601960248201527f756e7265636f676e697a65642062696e64207061636b61676500000000000000604482015290519081900360640190fd5b60408051600080825260208201909252905b50949350505050565b60006121e083836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506128bd565b9392505050565b6020015190565b6000828201838110156121e0576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600080826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561228457600080fd5b505afa158015612298573d6000803e3d6000fd5b505050506040513d60208110156122ae57600080fd5b5051604080516395d89b4160e01b815290519192506060916001600160a01b038616916395d89b41916004808301926000929190829003018186803b1580156122f657600080fd5b505afa15801561230a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561233357600080fd5b8101908080516040519392919084600160201b82111561235257600080fd5b90830190602082018581111561236757600080fd5b8251600160201b81118282018810171561238057600080fd5b82525081516020918201929091019080838360005b838110156123ad578181015183820152602001612395565b50505050905090810190601f1680156123da5780820380516001836020036101000a031916815260200191505b5060408181526370a0823160e01b82526110046004830152519495506000946001600160a01b038a1694506370a08231935060248083019350602092829003018186803b15801561242a57600080fd5b505afa15801561243e573d6000803e3d6000fd5b505050506040513d602081101561245457600080fd5b5051608087015160608801519192506000916124759163ffffffff61219e16565b9050428760c0015167ffffffffffffffff16101561249b57506001935061145f92505050565b6124a9838860200151612954565b6124bb57506002935061145f92505050565b808211156124d157506003935061145f92505050565b866060015187604001516001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561251357600080fd5b505afa158015612527573d6000803e3d6000fd5b505050506040513d602081101561253d57600080fd5b50511461255257506004935061145f92505050565b8660a0015160ff16841461256e57506005935061145f92505050565b602080880151604080516359b9278960e01b8152600481019290925251600092611004926359b927899260248083019392829003018186803b1580156125b357600080fd5b505afa1580156125c7573d6000803e3d6000fd5b505050506040513d60208110156125dd57600080fd5b50516001600160a01b031614158061267f57506000801b6110046001600160a01b031663bd46646189604001516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561265057600080fd5b505afa158015612664573d6000803e3d6000fd5b505050506040513d602081101561267a57600080fd5b505114155b1561269257506006935061145f92505050565b5060009695505050505050565b6040805160028082526060828101909352829190816020015b60608152602001906001900390816126b857505083519091506126e09063ffffffff16612a3c565b816000815181106126ed57fe5b6020026020010181905250612708836020015160001c612a3c565b8160018151811061271557fe5b60200260200101819052506121e081612a4f565b60006121e083836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612ad9565b612773613168565b600061277d613168565b6127856131bb565b61279661279186612b3e565b612b63565b90506000805b6127a583612bad565b156128b057806127ca576127c06127bb84612bce565b612c1c565b60ff1684526128a8565b80600114156127e9576127df6127bb84612bce565b60208501526128a8565b8060021415612816576128036127fe84612bce565b612cd1565b6001600160a01b031660408501526128a8565b80600314156128355761282b6127bb84612bce565b60608501526128a8565b80600414156128545761284a6127bb84612bce565b60808501526128a8565b8060051415612876576128696127bb84612bce565b60ff1660a08501526128a8565b80600614156128a35761288b6127bb84612bce565b67ffffffffffffffff1660c0850152600191506128a8565b6128b0565b60010161279c565b5091935090915050915091565b6000818484111561294c5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156129115781810151838201526020016128f9565b50505050905090810190601f16801561293e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b815160009083906008108061296a575080516003115b1561297957600091505061145f565b604080516020808252818301909252606091602082018180368337019050509050836020820152808251815181106129ad57fe5b6020910101516001600160f81b031916602d60f81b146129d25760009250505061145f565b600160005b8351811015612a32578281815181106129ec57fe5b602001015160f81c60f81b6001600160f81b031916848281518110612a0d57fe5b01602001516001600160f81b03191614612a2a5760009150612a32565b6001016129d7565b5095945050505050565b606061145f612a4a83612ceb565b612dd1565b6060815160001415612a705750604080516000815260208101909152610bb1565b606082600081518110612a7f57fe5b602002602001015190506000600190505b8351811015612ac057612ab682858381518110612aa957fe5b6020026020010151612e23565b9150600101612a90565b506121e0612ad3825160c060ff16612ea0565b82612e23565b60008183612b285760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156129115781810151838201526020016128f9565b506000838581612b3457fe5b0495945050505050565b612b466131db565b506040805180820190915281518152602082810190820152919050565b612b6b6131bb565b612b7482612f98565b612b7d57600080fd5b6000612b8c8360200151612fd2565b60208085015160408051808201909152868152920190820152915050919050565b6000612bb76131db565b505080518051602091820151919092015191011190565b612bd66131db565b612bdf82612bad565b612be857600080fd5b60208201516000612bf882613035565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590612c3157508151602110155b612c3a57600080fd5b6000612c498360200151612fd2565b90508083600001511015612ca4576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b82516020808501518301805192849003929183101561219557506020919091036101000a90049392505050565b8051600090601514612ce257600080fd5b61145f82612c1c565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416612d2f57506018612d53565b6fffffffffffffffffffffffffffffffff198416612d4f57506010612d53565b5060005b6020811015612d8957818181518110612d6857fe5b01602001516001600160f81b03191615612d8157612d89565b600101612d53565b60008160200390506060816040519080825280601f01601f191660200182016040528015612dbe576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015612e035750607f60f81b82600081518110612df157fe5b01602001516001600160f81b03191611155b15612e0f575080610bb1565b61145f612e218351608060ff16612ea0565b835b6060806040519050835180825260208201818101602087015b81831015612e54578051835260209283019201612e3c565b50855184518101855292509050808201602086015b81831015612e81578051835260209283019201612e69565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310612ef0576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411612f4a5782840160f81b81600081518110612f2c57fe5b60200101906001600160f81b031916908160001a905350905061145f565b6060612f5585612ceb565b90508381510160370160f81b82600081518110612f6e57fe5b60200101906001600160f81b031916908160001a905350612f8f8282612e23565b95945050505050565b8051600090612fa957506000610bb1565b6020820151805160001a9060c0821015612fc857600092505050610bb1565b5060019392505050565b8051600090811a6080811015612fec576000915050610bb1565b60b8811080613007575060c08110801590613007575060f881105b15613016576001915050610bb1565b60c081101561302a5760b519019050610bb1565b60f519019050610bb1565b80516000908190811a60808110156130505760019150613161565b60b881101561306557607e1981019150613161565b60c08110156130df57600060b78203600186019550806020036101000a8651049150600181018201935050808310156130d9576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b50613161565b60f88110156130f45760be1981019150613161565b600060f78203600186019550806020036101000a86510491506001810182019350508083101561315f576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915290565b604080518082019091526000808252602082015290565b60405180604001604052806131ce6131db565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe6f6e6c79206265703230206f776e65722063616e20617070726f766520746869732062696e64207265717565737472656c6179466565206d757374206265204e202a203165313020616e642067726561746572207468616e206d696e6952656c6179466565636f6e74616374206164647265737320646f65736e277420657175616c20746f2074686520636f6e7472616374206164647265737320696e2062696e642072657175657374746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374a264697066735822122030cc6c250f37ad9452c0933399bf3f460a19215bce5c10c377f100761098776a64736f6c63430006040033" + }, + "0x0000000000000000000000000000000000002000": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106102485760003560e01c8063863fe4ab1161013b578063c81b1662116100b8578063e3b048051161007c578063e3b048051461072c578063f7a251d71461074c578063f9a2bbc7146107c4578063fc3e5908146107cc578063fd6a6879146107d457610248565b8063c81b1662146106dd578063d31f968d146106e5578063d76a867514610714578063dc927faf1461071c578063e1c7392a1461072457610248565b8063a78abc16116100ff578063a78abc16146105d3578063ab51bb96146105db578063ac431751146105e3578063b0355f5b146103ff578063c27cdcfb146106a157610248565b8063863fe4ab146105b35780638cc8f561146104b657806396713da9146105bb5780639dc09262146105c3578063a1a11bf5146105cb57610248565b8063493279b1116101c957806370fd5bad1161018d57806370fd5bad146104b657806374f079b8146104be57806375d47a0a146104c65780637942fd05146104ce57806384013b6a146104d657610248565b8063493279b11461045f5780634bf6c8821461047e57806351e80672146104865780636e47a51a1461048e5780636e47b482146104ae57610248565b8063308325f411610210578063308325f4146102cf5780633bdc47a6146102d75780633dffc387146103ff578063422f90501461040757806343756e5c1461043b57610248565b806305e682581461024d5780630bee7a671461026b57806314b3023b1461028c57806322556cdc146102a65780632ff32aea146102ae575b600080fd5b6102556107dc565b6040805160ff9092168252519081900360200190f35b6102736107e1565b6040805163ffffffff9092168252519081900360200190f35b6102946107e6565b60408051918252519081900360200190f35b6102946107ec565b6102b66107f1565b60408051600792830b90920b8252519081900360200190f35b6102946107fa565b61038a600480360360608110156102ed57600080fd5b60ff82351691602081013591810190606081016040820135600160201b81111561031657600080fd5b82018360208201111561032857600080fd5b803590602001918460018302840111600160201b8311171561034957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610800945050505050565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103c45781810151838201526020016103ac565b50505050905090810190601f1680156103f15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610255610876565b6104276004803603602081101561041d57600080fd5b503560ff1661087b565b604080519115158252519081900360200190f35b610443610890565b604080516001600160a01b039092168252519081900360200190f35b610467610896565b6040805161ffff9092168252519081900360200190f35b61025561089b565b6104436108a0565b610443600480360360208110156104a457600080fd5b503560ff166108a6565b6104436108c1565b6102556108c7565b6102946108cc565b6104436108d2565b6102556108d8565b6105b1600480360360a08110156104ec57600080fd5b810190602081018135600160201b81111561050657600080fd5b82018360208201111561051857600080fd5b803590602001918460018302840111600160201b8311171561053957600080fd5b919390929091602081019035600160201b81111561055657600080fd5b82018360208201111561056857600080fd5b803590602001918460018302840111600160201b8311171561058957600080fd5b919350915080356001600160401b03908116916020810135909116906040013560ff166108dd565b005b610294611a8d565b610255611a95565b610443611a9a565b610443611aa0565b610427611aa6565b6102736107dc565b6105b1600480360360408110156105f957600080fd5b810190602081018135600160201b81111561061357600080fd5b82018360208201111561062557600080fd5b803590602001918460018302840111600160201b8311171561064657600080fd5b919390929091602081019035600160201b81111561066357600080fd5b82018360208201111561067557600080fd5b803590602001918460018302840111600160201b8311171561069657600080fd5b509092509050611aaf565b6106c1600480360360208110156106b757600080fd5b503560ff16612051565b604080516001600160401b039092168252519081900360200190f35b61044361206c565b610427600480360360408110156106fb57600080fd5b5080356001600160a01b0316906020013560ff16612072565b61038a612092565b6104436120b1565b6105b16120b7565b6106c16004803603602081101561074257600080fd5b503560ff1661246e565b6105b16004803603606081101561076257600080fd5b60ff8235169190810190604081016020820135600160201b81111561078657600080fd5b82018360208201111561079857600080fd5b803590602001918460018302840111600160201b831117156107b957600080fd5b919350915035612489565b6104436125da565b6102556125e0565b6104436125e5565b600081565b606481565b60015481565b603281565b60045460070b81565b60025481565b60606000825160210190506060816040519080825280601f01601f191660200182016040528015610838576020820181803683370190505b506021810186905260018101879052828152905060418101600061085b866125eb565b50905061086a818388516125f5565b50909695505050505050565b600181565b60096020526000908152604090205460ff1681565b61100181565b603881565b600881565b61200081565b6005602052600090815260409020546001600160a01b031681565b61100581565b600281565b60035481565b61100881565b600b81565b60005460ff16610930576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b60408051630a83aaa960e31b815233600482015290516110069163541d5548916024808301926020929190829003018186803b15801561096f57600080fd5b505afa158015610983573d6000803e3d6000fd5b505050506040513d602081101561099957600080fd5b50516109ec576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b60ff8116600090815260086020526040902054829082906001600160401b039081169083168114610a5c576040805162461bcd60e51b815260206004820152601560248201527439b2b8bab2b731b2903737ba1034b71037b93232b960591b604482015290519081900360640190fd5b60ff8216600090815260086020908152604091829020805467ffffffffffffffff1916600185016001600160401b039081169190911790915582516337d7f9c160e21b81529089166004820152915188926110039263df5fe70492602480840193829003018186803b158015610ad157600080fd5b505afa158015610ae5573d6000803e3d6000fd5b505050506040513d6020811015610afb57600080fd5b5051610b385760405162461bcd60e51b8152600401808060200182810382526023815260200180612bcc6023913960400191505060405180910390fd5b60ff851660009081526005602052604090205485906001600160a01b0316610ba7576040805162461bcd60e51b815260206004820152601860248201527f6368616e6e656c206973206e6f7420737570706f727465640000000000000000604482015290519081900360640190fd5b60608c8c8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805163cba510a960e01b81526001600160401b038f1660048201529051939450610cce93611003935063cba510a992506024808301926020929190829003018186803b158015610c7757600080fd5b505afa158015610c8b573d6000803e3d6000fd5b505050506040513d6020811015610ca157600080fd5b505160408051808201909152600381526269626360e81b6020820152610cc78c8c612636565b858561267d565b610d16576040805162461bcd60e51b815260206004820152601460248201527334b73b30b634b21036b2b935b63290383937b7b360611b604482015290519081900360640190fd5b60408051631bb5062960e31b81526001600160401b038c16600482015290516000916110039163dda8314891602480820192602092909190829003018186803b158015610d6257600080fd5b505afa158015610d76573d6000803e3d6000fd5b505050506040513d6020811015610d8c57600080fd5b5051905088600080806060610da08861277a565b935093509350935083610e61578460ff168f6001600160401b03167ff7b2e42d694eb1100184aae86d4245d9e46966100b1dc7e723275b98326854ac8a6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610e1a578181015183820152602001610e02565b50505050905090810190601f168015610e475780820380516001836020036101000a031916815260200191505b509250505060405180910390a35050505050505050611a7f565b8460ff168f6001600160401b03167f36afdaf439a8f43fe72135135d804ae620b37a474f0943b5b85f6788312cad4085604051808260ff1660ff16815260200191505060405180910390a360ff83166113ea5760ff85166000818152600560209081526040808320548151631182b87560e01b815260048101958652602481019283528651604482015286516001600160a01b03909216958695631182b875958d958a9593949093606490910192918601918190849084905b83811015610f32578181015183820152602001610f1a565b50505050905090810190601f168015610f5f5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015610f7f57600080fd5b505af192505050801561106357506040513d6000823e601f3d908101601f191682016040526020811015610fb257600080fd5b8101908080516040519392919084600160201b821115610fd157600080fd5b908301906020820185811115610fe657600080fd5b8251600160201b811182820188101715610fff57600080fd5b82525081516020918201929091019080838360005b8381101561102c578181015183820152602001611014565b50505050905090810190601f1680156110595780820380516001836020036101000a031916815260200191505b5060405250505060015b611375576040516000815260443d101561107f5750600061111a565b60046000803e60005160e01c6308c379a081146110a057600091505061111a565b60043d036004833e81513d60248201116001600160401b03821117156110cb5760009250505061111a565b80830180516001600160401b038111156110ec57600094505050505061111a565b8060208301013d860181111561110a5760009550505050505061111a565b601f01601f191660405250925050505b806111255750611237565b60ff871660009081526007602052604081205461115c916001600160401b039091169089906111579060029088610800565b61282a565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf948794849390840192918601918190849084905b838110156111f75781810151838201526020016111df565b50505050905090810190601f1680156112245780820380516001836020036101000a031916815260200191505b509250505060405180910390a250611370565b3d808015611261576040519150601f19603f3d011682016040523d82523d6000602084013e611266565b606091505b5060ff8716600090815260076020526040812054611299916001600160401b039091169089906111579060029088610800565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351948794849390840192918601918190849084905b8381101561133457818101518382015260200161131c565b50505050905090810190601f1680156113615780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b6113e4565b8051156113e25760ff87166000908152600760205260408120546113ae916001600160401b039091169089906111579060019086610800565b60ff8716600090815260076020526040902080546001600160401b038082166001011667ffffffffffffffff199091161790555b505b506119b8565b60ff83166001141561168e5760ff8516600081815260056020908152604080832054815163831d65d160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563831d65d1958d958a9593949093606490910192918601918190849084905b8381101561147457818101518382015260200161145c565b50505050905090810190601f1680156114a15780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156114c157600080fd5b505af19250505080156114d2575060015b6113e4576040516000815260443d10156114ee57506000611589565b60046000803e60005160e01c6308c379a0811461150f576000915050611589565b60043d036004833e81513d60248201116001600160401b038211171561153a57600092505050611589565b80830180516001600160401b0381111561155b576000945050505050611589565b8060208301013d860181111561157957600095505050505050611589565b601f01601f191660405250925050505b8061159457506115f9565b60408051602080825283518183015283516001600160a01b038616937ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf93869390928392830191850190808383600083156111f75781810151838201526020016111df565b3d808015611623576040519150601f19603f3d011682016040523d82523d6000602084013e611628565b606091505b5060408051602080825283518183015283516001600160a01b038616937f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351938693909283928301918501908083836000831561133457818101518382015260200161131c565b60ff8316600214156119b85760ff8516600081815260056020908152604080832054815163c8509d8160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563c8509d81958d958a9593949093606490910192918601918190849084905b83811015611718578181015183820152602001611700565b50505050905090810190601f1680156117455780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561176557600080fd5b505af1925050508015611776575060015b6119b6576040516000815260443d10156117925750600061182d565b60046000803e60005160e01c6308c379a081146117b357600091505061182d565b60043d036004833e81513d60248201116001600160401b03821117156117de5760009250505061182d565b80830180516001600160401b038111156117ff57600094505050505061182d565b8060208301013d860181111561181d5760009550505050505061182d565b601f01601f191660405250925050505b8061183857506118e1565b816001600160a01b03167ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf826040518080602001828103825283818151815260200191508051906020019080838360005b838110156118a1578181015183820152602001611889565b50505050905090810190601f1680156118ce5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2506119b6565b3d80801561190b576040519150601f19603f3d011682016040523d82523d6000602084013e611910565b606091505b50816001600160a01b03167f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351826040518080602001828103825283818151815260200191508051906020019080838360005b8381101561197a578181015183820152602001611962565b50505050905090810190601f1680156119a75780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b505b60ff80861660009081526009602052604090205461100591636f93d2e69189913391879116806119ea575060ff881615155b604080516001600160e01b031960e088901b1681526001600160a01b039586166004820152939094166024840152604483019190915215156064820152905160848083019260209291908290030181600087803b158015611a4a57600080fd5b505af1158015611a5e573d6000803e3d6000fd5b505050506040513d6020811015611a7457600080fd5b505050505050505050505b505050505050505050505050565b630100380081565b600981565b61100781565b61100681565b60005460ff1681565b3361100714611aef5760405162461bcd60e51b815260040180806020018281038252602e815260200180612b22602e913960400191505060405180910390fd5b611b5884848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526012815271626174636853697a65466f724f7261636c6560701b602082015291506129809050565b15611bf357604080516020601f8401819004810282018101909252828152600091611b9b91858580838501838280828437600092019190915250612a6792505050565b90506127108111158015611bb05750600a8110155b611beb5760405162461bcd60e51b8152600401808060200182810382526032815260200180612b9a6032913960400191505060405180910390fd5b600155611fbf565b611c5c84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601281527118591913dc955c19185d1950da185b9b995b60721b602082015291506129809050565b15611de457606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060169091149050611cdf5760405162461bcd60e51b815260040180806020018281038252605a815260200180612ac8605a913960600191505060405180910390fd5b60018101516002820151601683015160ff82161590611cfd81612a6c565b611d4e576040805162461bcd60e51b815260206004820152601960248201527f61646472657373206973206e6f74206120636f6e747261637400000000000000604482015290519081900360640190fd5b60ff8416600081815260056020908152604080832080546001600160a01b0319166001600160a01b038716908117909155808452600683528184208585528352818420805460ff199081166001179091556009909352818420805490931687151517909255519092917f7e3b6af43092577ee20e60eaa1d9b114a7031305c895ee7dd3ffe17196d2e1e091a35050505050611fbf565b611e5184848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526016815275195b98589b1953dc911a5cd8589b1950da185b9b995b60521b602082015291506129809050565b15611f8257606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060029091149050611ed45760405162461bcd60e51b815260040180806020018281038252604a815260200180612b50604a913960600191505060405180910390fd5b600181810151600283015160ff80831660009081526005602052604090205492939192908316909114906001600160a01b03168015611f78576001600160a01b038116600090815260066020908152604080832060ff881680855290835292819020805460ff1916861515908117909155815190815290517fa3132e3f9819fbddc7f0ed6d38d7feef59aa95112090b7c592f5cb5bc4aa4adc929181900390910190a25b5050505050611fbf565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b6008602052600090815260409020546001600160401b031681565b61100281565b600660209081526000928352604080842090915290825290205460ff1681565b6040518060400160405280600381526020016269626360e81b81525081565b61100381565b60005460ff161561210f576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b7f1471eb6eb2c5e789fc3de43f8ce62938c7d1836ec861730447e2ada8fd81017b80546001600160a01b0319908116611008179091557f92e85d02570a8092d09a6e3a57665bc3815a2699a4074001bf1ccabf660f5a36805460ff199081169091557fd8af288fc1c8680b4f4706064cf021e264efb6828fcaf7eb5ca36818eb365bcc8054821660019081179091557f89832631fb3c3307a103ba2c84ab569c64d6182a18893dcd163f0f1c2090733a805484166110049081179091557f6cde3cea4b3a3fb2488b2808bae7556f4a405e50f65e1794383bc026131b13c38054841690557f72e4efa1513b071517c6c74dba31b5934a81aa83cddd400e7081df5529c9943680548416831790557fa9bc9a3a348c357ba16b37005d7e6b3236198c0e939f4af8c5f19b8deeb8ebc08054851690911790557fc575c31fea594a6eb97c8e9d3f9caee4c16218c6ef37e923234c0fe9014a61e78054831690557f4e523af77f034e9810f1c94057f5e931fb3d16a51511a4c3add793617d18610580548316821790557ffb33122aa9f93cc639ebe80a7bc4784c11e6053dde89c6f4f7e268c6a623da1e805484166110001790557fc7694af312c4f286114180fd0ba6a52461fcee8a381636770b19a343af92538a80548316821790557f01112dd68e482ba8d68a7e828cff8b3abcea08eab88941953c180a7e650e9cd480548316821790557fc0a4a8be475dfebc377ebef2d7c4ff47656f572a08dd92b81017efcdba0febe1805484166110071790557f87e8a52529e8ece4ef759037313542a6429ff494a9fab9027fb79db90124eba680548316821790557f4c7666bbcb22d46469f7cc282f70764a7012dca2cce630ff8d83db9a9cdd48f080548316821790557f40f28f99a40bc9f6beea1013afdbc3cdcc689eb76b82c4de06c0acf1e1932ed58054909316611001179092557f0d9cf2cd531699eed8dd34e40ff2884a14a698c4898184fba85194e6f6772d248054821683179055600b60009081527f23f68c9bd22b8a93d06adabe17481c87c016bcbd20adc8bfd707a4d813a572176020527fdf0d5d05428057f5455c2dc8e810dd86d1e9350faa72f16bda8a45443c5b39328054831684179055603283556004805467ffffffffffffffff19166001600160401b031790556002819055600381905580549091169091179055565b6007602052600090815260409020546001600160401b031681565b60005460ff166124dc576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b33600090815260066020908152604080832060ff80891685529252909120548591166125395760405162461bcd60e51b8152600401808060200182810382526031815260200180612a976031913960400191505060405180910390fd5b60ff85166000908152600760209081526040808320548151601f88018490048402810184019092528682526001600160401b03169261259e9284928a9261115792909189918c908c908190840183828082843760009201919091525061080092505050565b60ff959095166000908152600760205260409020805467ffffffffffffffff191660019096016001600160401b03169590951790945550505050565b61100081565b600381565b61100481565b8051602090910191565b5b60208110612615578251825260209283019290910190601f19016125f6565b915181516020939093036101000a6000190180199091169216919091179052565b60408051600e808252818301909252606091630100380060ff851617918391602082018180368337505050600e818101969096526006810192909252509283525090919050565b60008561268c57506000612771565b606082518451865160800101016040519080825280601f01601f1916602001820160405280156126c3576020820181803683370190505b50905060006126d182612a72565b6020808901518252019050866000806126e9896125eb565b80865260209095019490925090506127028285836125f5565b9283019261270f886125eb565b80865260209095019490925090506127288285836125f5565b9283018a81526020019261273b876125eb565b909250905061274b8285836125f5565b508351602001612759612a78565b60208183886065600019fa5051600114955050505050505b95945050505050565b600080600060606021855110156127aa575050604080516000808252602082019092529092508291508190612823565b600185015160218601518651604080516020198301808252601f19600119909401939093168101602001909152604189019392916060919080156127f5576020820181803683370190505b5090506000612803826125eb565b509050612815858260218d51036125f5565b506001975091955093509150505b9193509193565b600254431115612869576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b1617909155600355436002556128aa565b600380546001908101918290555410156128aa576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003555b8160ff16836001600160401b0316600460009054906101000a900460070b6001600160401b03167f3a6e0fc61675aa2a100bcba0568368bb92bcec91c97673391074f11138f0cffe603885604051808361ffff1661ffff16815260200180602001828103825283818151815260200191508051906020019080838360005b83811015612940578181015183820152602001612928565b50505050905090810190601f16801561296d5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a4505050565b6000816040516020018082805190602001908083835b602083106129b55780518252601f199092019160209182019101612996565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310612a235780518252601f199092019160209182019101612a04565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b3b151590565b60200190565b6040518060200160405280600190602082028036833750919291505056fe74686520636f6e747261637420616e64206368616e6e656c2068617665206e6f74206265656e20726567697374657265646c656e677468206f662076616c756520666f72206164644f725570646174654368616e6e656c2073686f756c642062652032322c206368616e6e656c49643a697346726f6d53797374656d3a68616e646c657241646472657373746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f7220656e61626c654f7244697361626c654368616e6e656c2073686f756c6420626520322c206368616e6e656c49643a6973456e61626c65746865206e6577426174636853697a65466f724f7261636c652073686f756c6420626520696e205b31302c2031303030305d6c6967687420636c69656e74206e6f742073796e632074686520626c6f636b20796574a264697066735822122083f6194f9a326fa5963aa39ffe11dcd28d1421a9f74fbe97a97f4853026e29ff64736f6c63430006040033" + }, + "b005741528b86F5952469d80A8614591E3c5B632": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "446AA6E0DC65690403dF3F127750da1322941F3e": { + "balance": "0x1b1ae4d6e2ef500000" + } } \ No newline at end of file diff --git a/core/allocs/chapel.json b/core/allocs/chapel.json index 32990606d7e..1fc33004b6c 100644 --- a/core/allocs/chapel.json +++ b/core/allocs/chapel.json @@ -1,51 +1,51 @@ { - "0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE": { - "balance": "0x0" - }, - "0x0000000000000000000000000000000000001000": { - "balance": "0x0", - "code": "0x6080604052600436106102675760003560e01c806396713da911610144578063c81b1662116100b6578063eb57e2021161007a578063eb57e20214610900578063eda5868c14610933578063f340fa0114610948578063f9a2bbc71461096e578063fc3e590814610983578063fd6a68791461099857610267565b8063c81b1662146108ac578063c8509d81146105f3578063d86222d5146108c1578063dc927faf146108d6578063e1c7392a146108eb57610267565b8063aaf5eb6811610108578063aaf5eb681461071f578063ab51bb9614610734578063ac43175114610749578063ad3c9da614610814578063b7ab4db514610847578063bf9f49951461040557610267565b806396713da9146106a25780639dc09262146106b7578063a1a11bf5146106cc578063a5422d5c146106e1578063a78abc16146106f657610267565b80635667515a116101dd57806375d47a0a116101a157806375d47a0a146105b45780637942fd05146105c957806381650b62146105de578063831d65d1146105f3578063853230aa14610678578063862498821461068d57610267565b80635667515a146104ea5780635d77156c146104ff5780636969a25c146105145780636e47b4821461058a57806370fd5bad1461059f57610267565b80633dffc3871161022f5780633dffc3871461040557806343756e5c14610430578063493279b1146104615780634bf6c8821461048d57806351e80672146104a2578063565c56b3146104b757610267565b80630bee7a671461026c5780631182b8751461029a5780631ff1806914610394578063219f22d5146103bb57806335409f7f146103d0575b600080fd5b34801561027857600080fd5b506102816109ad565b6040805163ffffffff9092168252519081900360200190f35b3480156102a657600080fd5b5061031f600480360360408110156102bd57600080fd5b60ff8235169190810190604081016020820135600160201b8111156102e157600080fd5b8201836020820111156102f357600080fd5b803590602001918460018302840111600160201b8311171561031457600080fd5b5090925090506109b2565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610359578181015183820152602001610341565b50505050905090810190601f1680156103865780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103a057600080fd5b506103a9610b26565b60408051918252519081900360200190f35b3480156103c757600080fd5b50610281610b2c565b3480156103dc57600080fd5b50610403600480360360208110156103f357600080fd5b50356001600160a01b0316610b31565b005b34801561041157600080fd5b5061041a610e45565b6040805160ff9092168252519081900360200190f35b34801561043c57600080fd5b50610445610e4a565b604080516001600160a01b039092168252519081900360200190f35b34801561046d57600080fd5b50610476610e50565b6040805161ffff9092168252519081900360200190f35b34801561049957600080fd5b5061041a610e55565b3480156104ae57600080fd5b50610445610e5a565b3480156104c357600080fd5b506103a9600480360360208110156104da57600080fd5b50356001600160a01b0316610e60565b3480156104f657600080fd5b5061041a610eb2565b34801561050b57600080fd5b50610281610eb7565b34801561052057600080fd5b5061053e6004803603602081101561053757600080fd5b5035610ebc565b604080516001600160a01b039788168152958716602087015293909516848401526001600160401b0390911660608401521515608083015260a082019290925290519081900360c00190f35b34801561059657600080fd5b50610445610f20565b3480156105ab57600080fd5b5061041a610f26565b3480156105c057600080fd5b50610445610f2b565b3480156105d557600080fd5b5061041a610f31565b3480156105ea57600080fd5b50610281610f36565b3480156105ff57600080fd5b506104036004803603604081101561061657600080fd5b60ff8235169190810190604081016020820135600160201b81111561063a57600080fd5b82018360208201111561064c57600080fd5b803590602001918460018302840111600160201b8311171561066d57600080fd5b509092509050610f3b565b34801561068457600080fd5b506103a9610fee565b34801561069957600080fd5b506103a9610ff4565b3480156106ae57600080fd5b5061041a610ffa565b3480156106c357600080fd5b50610445610fff565b3480156106d857600080fd5b50610445611005565b3480156106ed57600080fd5b5061031f61100b565b34801561070257600080fd5b5061070b61102a565b604080519115158252519081900360200190f35b34801561072b57600080fd5b506103a9611033565b34801561074057600080fd5b50610281610eb2565b34801561075557600080fd5b506104036004803603604081101561076c57600080fd5b810190602081018135600160201b81111561078657600080fd5b82018360208201111561079857600080fd5b803590602001918460018302840111600160201b831117156107b957600080fd5b919390929091602081019035600160201b8111156107d657600080fd5b8201836020820111156107e857600080fd5b803590602001918460018302840111600160201b8311171561080957600080fd5b50909250905061103c565b34801561082057600080fd5b506103a96004803603602081101561083757600080fd5b50356001600160a01b03166112e3565b34801561085357600080fd5b5061085c6112f5565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610898578181015183820152602001610880565b505050509050019250505060405180910390f35b3480156108b857600080fd5b5061044561141b565b3480156108cd57600080fd5b506103a9611421565b3480156108e257600080fd5b5061044561142d565b3480156108f757600080fd5b50610403611433565b34801561090c57600080fd5b506104036004803603602081101561092357600080fd5b50356001600160a01b0316611636565b34801561093f57600080fd5b50610281611805565b6104036004803603602081101561095e57600080fd5b50356001600160a01b031661180a565b34801561097a57600080fd5b50610445611a20565b34801561098f57600080fd5b5061041a611a26565b3480156109a457600080fd5b50610445611a2b565b606481565b60005460609060ff16610a08576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b3361200014610a485760405162461bcd60e51b815260040180806020018281038252602f815260200180613f73602f913960400191505060405180910390fd5b610a50613c27565b6000610a9185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a3192505050565b9150915080610aad57610aa46064611b8a565b92505050610b1f565b815160009060ff16610acd57610ac68360200151611beb565b9050610aeb565b825160ff1660011415610ae757610ac683602001516129ec565b5060655b63ffffffff8116610b105750506040805160008152602081019091529150610b1f9050565b610b1981611b8a565b93505050505b9392505050565b60035481565b606881565b3361100114610b715760405162461bcd60e51b8152600401808060200182810382526029815260200180613fcf6029913960400191505060405180910390fd5b6001600160a01b03811660009081526004602052604090205480610b955750610e42565b600181039050600060018281548110610baa57fe5b60009182526020909120600360049092020101546001549091506000190180610bf957600060018481548110610bdc57fe5b906000526020600020906004020160030181905550505050610e42565b6040805183815290516001600160a01b038616917f3b6f9ef90462b512a1293ecec018670bf7b7f1876fb727590a8a6d7643130a70919081900360200190a26001600160a01b038416600090815260046020526040812055600154600019018314610d7b57600180546000198101908110610c7057fe5b906000526020600020906004020160018481548110610c8b57fe5b6000918252602082208354600492830290910180546001600160a01b03199081166001600160a01b0393841617825560018087015481840180548416918616919091179055600280880180549185018054909416919095161780835584546001600160401b03600160a01b91829004160267ffffffffffffffff60a01b1990911617808355935460ff600160e01b918290041615150260ff60e01b199094169390931790556003948501549401939093558254868401939192919087908110610d5057fe5b600091825260208083206004909202909101546001600160a01b031683528201929092526040019020555b6001805480610d8657fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b03191690556003018190559155818381610dd957fe5b0490508015610e3d5760015460005b81811015610e3a578260018281548110610dfe57fe5b9060005260206000209060040201600301540160018281548110610e1e57fe5b6000918252602090912060036004909202010155600101610de8565b50505b505050505b50565b600181565b61100181565b606181565b600881565b61200081565b6001600160a01b03811660009081526004602052604081205480610e88576000915050610ead565b600180820381548110610e9757fe5b9060005260206000209060040201600301549150505b919050565b600081565b606781565b60018181548110610ec957fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b0392831694509082169291821691600160a01b81046001600160401b031691600160e01b90910460ff169086565b61100581565b600281565b61100881565b600b81565b606681565b3361200014610f7b5760405162461bcd60e51b815260040180806020018281038252602f815260200180613f73602f913960400191505060405180910390fd5b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a1505050565b6103e881565b60025481565b600981565b61100781565b61100681565b604051806101e001604052806101b78152602001613d9b6101b7913981565b60005460ff1681565b6402540be40081565b60005460ff1661108f576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b33611007146110cf5760405162461bcd60e51b815260040180806020018281038252602e815260200180613d26602e913960400191505060405180910390fd5b61113984848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526013815272065787069726554696d655365636f6e6447617606c1b60208201529150612c2a9050565b15611214576020811461117d5760405162461bcd60e51b8152600401808060200182810382526026815260200180613d756026913960400191505060405180910390fd5b604080516020601f84018190048102820181019092528281526000916111bb91858580838501838280828437600092019190915250612d1292505050565b9050606481101580156111d15750620186a08111155b61120c5760405162461bcd60e51b8152600401808060200182810382526027815260200180613cda6027913960400191505060405180910390fd5b600255611251565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b60046020526000908152604090205481565b6001546060906000805b82811015611346576001818154811061131457fe5b9060005260206000209060040201600201601c9054906101000a900460ff1661133e576001909101905b6001016112ff565b50606081604051908082528060200260200182016040528015611373578160200160208202803683370190505b50600092509050815b83811015611413576001818154811061139157fe5b9060005260206000209060040201600201601c9054906101000a900460ff1661140b57600181815481106113c157fe5b600091825260209091206004909102015482516001600160a01b03909116908390859081106113ec57fe5b6001600160a01b03909216602092830291909101909101526001909201915b60010161137c565b509250505090565b61100281565b67016345785d8a000081565b61100381565b60005460ff161561148b576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b611493613c27565b60006114b9604051806101e001604052806101b78152602001613d9b6101b79139611a31565b91509150806114f95760405162461bcd60e51b8152600401808060200182810382526021815260200180613f526021913960400191505060405180910390fd5b60005b82602001515181101561161e5760018360200151828151811061151b57fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782558587015182850180549185169183169190911790556040860151600283018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590981692909516919091179290921694909417161790915560a0909301516003909301929092559186015180519185019391859081106115f157fe5b602090810291909101810151516001600160a01b03168252810191909152604001600020556001016114fc565b50506103e8600255506000805460ff19166001179055565b33611001146116765760405162461bcd60e51b8152600401808060200182810382526029815260200180613fcf6029913960400191505060405180910390fd5b6001600160a01b0381166000908152600460205260409020548061169a5750610e42565b6001810390506000600182815481106116af57fe5b90600052602060002090600402016003015490506000600183815481106116d257fe5b906000526020600020906004020160030181905550600060018080549050039050836001600160a01b03167f8cd4e147d8af98a9e3b6724021b8bf6aed2e5dac71c38f2dce8161b82585b25d836040518082815260200191505060405180910390a28061174157505050610e42565b600081838161174c57fe5b0490508015610e3d5760005b848110156117aa57816001828154811061176e57fe5b906000526020600020906004020160030154016001828154811061178e57fe5b6000918252602090912060036004909202010155600101611758565b50600180549085015b81811015610e3a5782600182815481106117c957fe5b90600052602060002090600402016003015401600182815481106117e957fe5b60009182526020909120600360049092020101556001016117b3565b606581565b3341146118485760405162461bcd60e51b815260040180806020018281038252602d815260200180613fa2602d913960400191505060405180910390fd5b60005460ff1661189b576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b600034116118e8576040805162461bcd60e51b81526020600482015260156024820152746465706f7369742076616c7565206973207a65726f60581b604482015290519081900360640190fd5b6001600160a01b038116600090815260046020526040902054349080156119db57600060018083038154811061191a57fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff1615611985576040805184815290516001600160a01b038616917ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b4919081900360200190a26119d5565b600380548401815581018054840190556040805184815290516001600160a01b038616917f93a090ecc682c002995fad3c85b30c5651d7fd29b0be5da9d784a3302aedc055919081900360200190a25b50611a1b565b6040805183815290516001600160a01b038516917ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b4919081900360200190a25b505050565b61100081565b600381565b61100481565b611a39613c27565b6000611a43613c27565b611a4b613c3f565b611a5c611a5786612d17565b612d3c565b90506000805b611a6b83612d86565b15611b7c5780611a9057611a86611a8184612da7565b612df5565b60ff168452611b74565b8060011415611b6f576060611aac611aa785612da7565b612e55565b90508051604051908082528060200260200182016040528015611ae957816020015b611ad6613c5f565b815260200190600190039081611ace5790505b50602086015260005b8151811015611b6457611b03613c5f565b6000611b21848481518110611b1457fe5b6020026020010151612f26565b9150915080611b3e57876000995099505050505050505050611b85565b8188602001518481518110611b4f57fe5b60209081029190910101525050600101611af2565b506001925050611b74565b611b7c565b600101611a62565b50919350909150505b915091565b604080516001808252818301909252606091829190816020015b6060815260200190600190039081611ba4579050509050611bca8363ffffffff16613003565b81600081518110611bd757fe5b6020026020010181905250610b1f81613016565b6000806060611bf9846130a0565b9150915081611ca6577f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2816040518080602001828103825283818151815260200191508051906020019080838360005b83811015611c61578181015183820152602001611c49565b50505050905090810190601f168015611c8e5780820380516001836020036101000a031916815260200191505b509250505060405180910390a1606692505050610ead565b600080805b600154811015611d235767016345785d8a000060018281548110611ccb57fe5b90600052602060002090600402016003015410611ced57600190920191611d1b565b600060018281548110611cfc57fe5b9060005260206000209060040201600301541115611d1b576001909101905b600101611cab565b50606082604051908082528060200260200182016040528015611d50578160200160208202803683370190505b509050606083604051908082528060200260200182016040528015611d7f578160200160208202803683370190505b509050606084604051908082528060200260200182016040528015611dae578160200160208202803683370190505b509050606085604051908082528060200260200182016040528015611ddd578160200160208202803683370190505b5090506000606086604051908082528060200260200182016040528015611e0e578160200160208202803683370190505b509050606087604051908082528060200260200182016040528015611e3d578160200160208202803683370190505b509050600098506000975060608d905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b158015611e8a57600080fd5b505afa158015611e9e573d6000803e3d6000fd5b505050506040513d6020811015611eb457600080fd5b5051905067016345785d8a0000811115611f29577f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2604051808060200182810382526021815260200180613d546021913960400191505060405180910390a160689d5050505050505050505050505050610ead565b60005b60015481101561219c5767016345785d8a000060018281548110611f4c57fe5b906000526020600020906004020160030154106120d25760018181548110611f7057fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b03168a8d81518110611fa157fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060006402540be40060018381548110611fd657fe5b90600052602060002090600402016003015481611fef57fe5b0660018381548110611ffd57fe5b906000526020600020906004020160030154039050612025838261315390919063ffffffff16565b8a8e8151811061203157fe5b6020026020010181815250506001828154811061204a57fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316888e8151811061207b57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505081898e815181106120a857fe5b60209081029190910101526120c3878263ffffffff61319516565b6001909d019c96506121949050565b6000600182815481106120e157fe5b9060005260206000209060040201600301541115612194576001818154811061210657fe5b906000526020600020906004020160010160009054906101000a90046001600160a01b0316858c8151811061213757fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506001818154811061216457fe5b906000526020600020906004020160030154848c8151811061218257fe5b60209081029190910101526001909a01995b600101611f2c565b50600085156125da576110046001600160a01b0316636e056520878c8c8b60025442016040518663ffffffff1660e01b815260040180806020018060200180602001856001600160401b03166001600160401b03168152602001848103845288818151815260200191508051906020019060200280838360005b8381101561222e578181015183820152602001612216565b50505050905001848103835287818151815260200191508051906020019060200280838360005b8381101561226d578181015183820152602001612255565b50505050905001848103825286818151815260200191508051906020019060200280838360005b838110156122ac578181015183820152602001612294565b505050509050019750505050505050506020604051808303818588803b1580156122d557600080fd5b505af1935050505080156122fb57506040513d60208110156122f657600080fd5b505160015b612536576040516000815260443d1015612317575060006123b2565b60046000803e60005160e01c6308c379a081146123385760009150506123b2565b60043d036004833e81513d60248201116001600160401b0382111715612363576000925050506123b2565b80830180516001600160401b038111156123845760009450505050506123b2565b8060208301013d86018111156123a2576000955050505050506123b2565b601f01601f191660405250925050505b806123bd5750612461565b60019150867fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf280826040518080602001828103825283818151815260200191508051906020019080838360005b83811015612421578181015183820152602001612409565b50505050905090810190601f16801561244e5780820380516001836020036101000a031916815260200191505b509250505060405180910390a250612531565b3d80801561248b576040519150601f19603f3d011682016040523d82523d6000602084013e612490565b606091505b5060019150867fbfa884552dd8921b6ce90bfe906952ae5b3b29be0cc1a951d4f62697635a3a45826040518080602001828103825283818151815260200191508051906020019080838360005b838110156124f55781810151838201526020016124dd565b50505050905090810190601f1680156125225780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b6125da565b8015612574576040805188815290517fa217d08e65f80c73121cd9db834d81652d544bfbf452f6d04922b16c90a37b709181900360200190a16125d8565b604080516020808252601b908201527f6261746368207472616e736665722072657475726e2066616c7365000000000081830152905188917fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf280919081900360600190a25b505b80156127905760005b885181101561278e5760008982815181106125fa57fe5b6020026020010151905060006001828154811061261357fe5b60009182526020909120600160049092020181015481546001600160a01b03909116916108fc918590811061264457fe5b9060005260206000209060040201600301549081150290604051600060405180830381858888f1935050505090508015612700576001828154811061268557fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d91859081106126d457fe5b9060005260206000209060040201600301546040518082815260200191505060405180910390a2612784565b6001828154811061270d57fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d918590811061275c57fe5b9060005260206000209060040201600301546040518082815260200191505060405180910390a25b50506001016125e3565b505b8451156128da5760005b85518110156128d85760008682815181106127b157fe5b60200260200101516001600160a01b03166108fc8784815181106127d157fe5b60200260200101519081150290604051600060405180830381858888f19350505050905080156128675786828151811061280757fe5b60200260200101516001600160a01b03167f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d87848151811061284557fe5b60200260200101516040518082815260200191505060405180910390a26128cf565b86828151811061287357fe5b60200260200101516001600160a01b03167f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d8784815181106128b157fe5b60200260200101516040518082815260200191505060405180910390a25b5060010161279a565b505b4715612943576040805147815290517f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d9181900360200190a1604051611002904780156108fc02916000818181858888f19350505050158015612941573d6000803e3d6000fd5b505b600060035582511561295857612958836131ef565b6110016001600160a01b031663fc4333cd6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561299557600080fd5b505af11580156129a9573d6000803e3d6000fd5b50506040517fedd8d7296956dd970ab4de3f2fc03be2b0ffc615d20cd4c72c6e44f928630ebf925060009150a15060009f9e505050505050505050505050505050565b60008151600114612a4a577f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2604051808060200182810382526025815260200180613d016025913960400191505060405180910390a1506067610ead565b612a52613c5f565b82600081518110612a5f57fe5b60209081029190910181015180516001600160a01b03166000908152600490925260409091205490915080612ad05781516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a2600092505050610ead565b600154600090815b81811015612b625760018181548110612aed57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16158015612b4c575084600001516001600160a01b031660018281548110612b2f57fe5b60009182526020909120600490910201546001600160a01b031614155b15612b5a5760019250612b62565b600101612ad8565b5081612bac5783516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a26000945050505050610ead565b6001806001850381548110612bbd57fe5b6000918252602082206002600490920201018054921515600160e01b0260ff60e01b199093169290921790915584516040516001600160a01b03909116917ff226e7d8f547ff903d9d419cf5f54e0d7d07efa9584135a53a057c5f1f27f49a91a250600095945050505050565b6000816040516020018082805190602001908083835b60208310612c5f5780518252601f199092019160209182019101612c40565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310612ccd5780518252601f199092019160209182019101612cae565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490505b92915050565b015190565b612d1f613c94565b506040805180820190915281518152602082810190820152919050565b612d44613c3f565b612d4d826136b6565b612d5657600080fd5b6000612d6583602001516136f0565b60208085015160408051808201909152868152920190820152915050919050565b6000612d90613c94565b505080518051602091820151919092015191011190565b612daf613c94565b612db882612d86565b612dc157600080fd5b60208201516000612dd182613753565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590612e0a57508151602110155b612e1357600080fd5b6000612e2283602001516136f0565b83516020808601518301805193945091849003929190831015612e4c57826020036101000a820491505b50949350505050565b6060612e60826136b6565b612e6957600080fd5b6000612e74836137ec565b9050606081604051908082528060200260200182016040528015612eb257816020015b612e9f613c94565b815260200190600190039081612e975790505b5090506000612ec485602001516136f0565b60208601510190506000805b84811015612f1b57612ee183613753565b9150604051806040016040528083815260200184815250848281518110612f0457fe5b602090810291909101015291810191600101612ed0565b509195945050505050565b612f2e613c5f565b6000612f38613c5f565b612f40613c3f565b612f4985612d3c565b90506000805b612f5883612d86565b15611b7c5780612f8357612f73612f6e84612da7565b613848565b6001600160a01b03168452612ffb565b8060011415612fab57612f98612f6e84612da7565b6001600160a01b03166020850152612ffb565b8060021415612fd357612fc0612f6e84612da7565b6001600160a01b03166040850152612ffb565b8060031415611b6f57612fe8611a8184612da7565b6001600160401b03166060850152600191505b600101612f4f565b6060612d0c61301183613862565b613948565b60608151600014156130375750604080516000815260208101909152610ead565b60608260008151811061304657fe5b602002602001015190506000600190505b83518110156130875761307d8285838151811061307057fe5b602002602001015161399a565b9150600101613057565b50610b1f61309a825160c060ff16613a17565b8261399a565b60006060815b83518110156131395760005b81811015613130578481815181106130c657fe5b6020026020010151600001516001600160a01b03168583815181106130e757fe5b6020026020010151600001516001600160a01b031614156131285760006040518060600160405280602b8152602001613caf602b9139935093505050611b85565b6001016130b2565b506001016130a6565b505060408051602081019091526000815260019150915091565b6000610b1f83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613b0f565b600082820183811015610b1f576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600154815160005b8281101561330c576001613209613c5f565b6001838154811061321657fe5b600091825260208083206040805160c08101825260049490940290910180546001600160a01b0390811685526001820154811693850193909352600281015492831691840191909152600160a01b82046001600160401b03166060840152600160e01b90910460ff16151560808301526003015460a082015291505b848110156132e0578681815181106132a657fe5b6020026020010151600001516001600160a01b031682600001516001600160a01b031614156132d857600092506132e0565b600101613292565b5081156133025780516001600160a01b03166000908152600460205260408120555b50506001016131f7565b508082111561338157805b8281101561337f57600180548061332a57fe5b60008281526020812060046000199093019283020180546001600160a01b03199081168255600182810180549092169091556002820180546001600160e81b0319169055600390910191909155915501613317565b505b60008183106133905781613392565b825b905060005b8181101561358c576134448582815181106133ae57fe5b6020026020010151600183815481106133c357fe5b60009182526020918290206040805160c08101825260049390930290910180546001600160a01b0390811684526001820154811694840194909452600281015493841691830191909152600160a01b83046001600160401b03166060830152600160e01b90920460ff161515608082015260039091015460a0820152613ba6565b61355f57806001016004600087848151811061345c57fe5b6020026020010151600001516001600160a01b03166001600160a01b031681526020019081526020016000208190555084818151811061349857fe5b6020026020010151600182815481106134ad57fe5b6000918252602091829020835160049092020180546001600160a01b039283166001600160a01b0319918216178255928401516001820180549184169185169190911790556040840151600282018054606087015160808801511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909716929097169190911792909216939093171692909217905560a090910151600390910155613584565b60006001828154811061356e57fe5b9060005260206000209060040201600301819055505b600101613397565b50828211156136b057825b82811015610e3d5760018582815181106135ad57fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782559585015181840180549184169188169190911790556040850151600282018054606088015160808901511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590971692909a169190911792909216939093171695909517905560a0909201516003909301929092558751908401929088908590811061368357fe5b602090810291909101810151516001600160a01b0316825281019190915260400160002055600101613597565b50505050565b80516000906136c757506000610ead565b6020820151805160001a9060c08210156136e657600092505050610ead565b5060019392505050565b8051600090811a608081101561370a576000915050610ead565b60b8811080613725575060c08110801590613725575060f881105b15613734576001915050610ead565b60c08110156137485760b519019050610ead565b60f519019050610ead565b80516000908190811a608081101561376e57600191506137e5565b60b881101561378357607e19810191506137e5565b60c08110156137b05760b78103600185019450806020036101000a855104600182018101935050506137e5565b60f88110156137c55760be19810191506137e5565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b80516000906137fd57506000610ead565b6000809050600061381184602001516136f0565b602085015185519181019250015b8082101561383f5761383082613753565b6001909301929091019061381f565b50909392505050565b805160009060151461385957600080fd5b612d0c82612df5565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166138a6575060186138ca565b6fffffffffffffffffffffffffffffffff1984166138c6575060106138ca565b5060005b6020811015613900578181815181106138df57fe5b01602001516001600160f81b031916156138f857613900565b6001016138ca565b60008160200390506060816040519080825280601f01601f191660200182016040528015613935576020820181803683370190505b5080830196909652508452509192915050565b60608151600114801561397a5750607f60f81b8260008151811061396857fe5b01602001516001600160f81b03191611155b15613986575080610ead565b612d0c6139988351608060ff16613a17565b835b6060806040519050835180825260208201818101602087015b818310156139cb5780518352602092830192016139b3565b50855184518101855292509050808201602086015b818310156139f85780518352602092830192016139e0565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310613a67576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411613ac15782840160f81b81600081518110613aa357fe5b60200101906001600160f81b031916908160001a9053509050612d0c565b6060613acc85613862565b90508381510160370160f81b82600081518110613ae557fe5b60200101906001600160f81b031916908160001a905350613b06828261399a565b95945050505050565b60008184841115613b9e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613b63578181015183820152602001613b4b565b50505050905090810190601f168015613b905780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b805182516000916001600160a01b039182169116148015613be0575081602001516001600160a01b031683602001516001600160a01b0316145b8015613c05575081604001516001600160a01b031683604001516001600160a01b0316145b8015610b1f5750506060908101519101516001600160401b0390811691161490565b60408051808201909152600081526060602082015290565b6040518060400160405280613c52613c94565b8152602001600081525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b60405180604001604052806000815260200160008152509056fe6475706c696361746520636f6e73656e7375732061646472657373206f662076616c696461746f725365747468652065787069726554696d655365636f6e64476170206973206f7574206f662072616e67656c656e677468206f66206a61696c2076616c696461746f7273206d757374206265206f6e65746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374666565206973206c6172676572207468616e2044555354595f494e434f4d494e476c656e677468206f662065787069726554696d655365636f6e64476170206d69736d61746368f901b480f901b0f846941284214b9b9c85549ab3d2b972df0deef66ac2c99477f066f3fb515bb97015e4b4afddbcb25c94286b946ddf42a51534fc98d0c0a3b42c963cace8441ddf86048c27395000f84694b71b214cb885500844365e95cd9942c7276e7fd894748c284f46ab87fd492326f1e2fe731d22ad2db394d22ca3ba2141d23adab65ce4940eb7665ea2b6a786048c27395000f84694a2959d3f95eae5dc7d70144ce1b73b403b7eb6e0940ce09b38374887cb564b7efa60be130d99ed5f95948081ef03f1d9e0bb4a5bf38f16285c879299f07f86048c27395000f84694980a75ecd1309ea12fa2ed87a8744fbfc9b863d59407eecf36cf0901fefe4bc505d6ba03c7480c7b5794cc6ac05c95a99c1f7b5f88de0e3486c82293b27086048c27395000f8469435552c16704d214347f29fa77f77da6d75d7c75294f57d36e129881a3a13a024fe8072507e5b2e70f894dc4973e838e3949c77aced16ac2315dc2d7ab11186048c27395000f84694f474cf03cceff28abc65c9cbae594f725c80e12d94ddfcaedf9bb451098c9917a45f02bd61342cca6694e61a183325a18a173319dd8e19c8d069459e217586048c273950006661696c656420746f20706172736520696e69742076616c696461746f72536574746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d6573736167652073656e646572206d7573742062652074686520626c6f636b2070726f6475636572746865206d6573736167652073656e646572206d75737420626520736c61736820636f6e7472616374a26469706673582212201a362ffe5872c7b034fe0bdf76cb3980b7a822a1eb1f36e261d39b52df28597164736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001001": { - "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b50600436106102065760003560e01c806396713da91161011a578063c81b1662116100ad578063e1c7392a1161007c578063e1c7392a1461064d578063f9a2bbc714610655578063fc3e59081461065d578063fc4333cd14610665578063fd6a68791461066d57610206565b8063c81b16621461059f578063c8509d81146105a7578063c96be4cb1461061f578063dc927faf1461064557610206565b8063a78abc16116100e9578063a78abc16146104b5578063ab51bb96146104d1578063ac431751146104d9578063c80d4b8f1461059757610206565b806396713da9146104955780639bc8e4f21461049d5780639dc09262146104a5578063a1a11bf5146104ad57610206565b806351e806721161019d57806370fd5bad1161016c57806370fd5bad146103fb57806375d47a0a146104035780637912a65d1461040b5780637942fd0514610413578063831d65d11461041b57610206565b806351e80672146103db578063567a372d146103e357806362b72cf5146103eb5780636e47b482146103f357610206565b80633dffc387116101d95780633dffc3871461037257806343756e5c14610390578063493279b1146103b45780634bf6c882146103d357610206565b80630bee7a671461020b5780631182b8751461022c57806337c8dab914610319578063389f4f7114610358575b600080fd5b610213610675565b6040805163ffffffff9092168252519081900360200190f35b6102a46004803603604081101561024257600080fd5b60ff8235169190810190604081016020820135600160201b81111561026657600080fd5b82018360208201111561027857600080fd5b803590602001918460018302840111600160201b8311171561029957600080fd5b50909250905061067a565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102de5781810151838201526020016102c6565b50505050905090810190601f16801561030b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61033f6004803603602081101561032f57600080fd5b50356001600160a01b0316610709565b6040805192835260208301919091528051918290030190f35b610360610760565b60408051918252519081900360200190f35b61037a610766565b6040805160ff9092168252519081900360200190f35b61039861076b565b604080516001600160a01b039092168252519081900360200190f35b6103bc610771565b6040805161ffff9092168252519081900360200190f35b61037a610776565b61039861077b565b610360610781565b610360610787565b61039861078d565b61037a610793565b610398610798565b61036061079e565b61037a6107a3565b6104936004803603604081101561043157600080fd5b60ff8235169190810190604081016020820135600160201b81111561045557600080fd5b82018360208201111561046757600080fd5b803590602001918460018302840111600160201b8311171561048857600080fd5b5090925090506107a8565b005b61037a61087e565b610360610883565b61039861088e565b610398610894565b6104bd61089a565b604080519115158252519081900360200190f35b6102136108a3565b610493600480360360408110156104ef57600080fd5b810190602081018135600160201b81111561050957600080fd5b82018360208201111561051b57600080fd5b803590602001918460018302840111600160201b8311171561053c57600080fd5b919390929091602081019035600160201b81111561055957600080fd5b82018360208201111561056b57600080fd5b803590602001918460018302840111600160201b8311171561058c57600080fd5b5090925090506108a8565b610360610ca3565b610398610ca8565b610493600480360360408110156105bd57600080fd5b60ff8235169190810190604081016020820135600160201b8111156105e157600080fd5b8201836020820111156105f357600080fd5b803590602001918460018302840111600160201b8311171561061457600080fd5b509092509050610cae565b6104936004803603602081101561063557600080fd5b50356001600160a01b0316610cdc565b6103986110e1565b6104936110e7565b610398611158565b61037a61115e565b610493611163565b6103986112b4565b606481565b606033612000146106bc5760405162461bcd60e51b815260040180806020018281038252602f815260200180611c1a602f913960400191505060405180910390fd5b6040805162461bcd60e51b815260206004820152601e60248201527f7265636569766520756e65787065637465642073796e207061636b6167650000604482015290519081900360640190fd5b600080610714611ade565b5050506001600160a01b0316600090815260026020818152604092839020835160608101855281548082526001830154938201849052919093015460ff16151592909301919091529091565b60055481565b600181565b61100181565b606181565b600881565b61200081565b60045481565b60035481565b61100581565b600281565b61100881565b603281565b600b81565b6107b0611b01565b60006107f184848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506112ba92505050565b91509150801561083b5781516040805163ffffffff9092168252517f7f0956d47419b9525356e7111652b653b530ec6f5096dccc04589bc38e6299679181900360200190a1610877565b81516040805163ffffffff9092168252517f7d45f62d17443dd4547bca8a8112c60e2385669318dc300ec61a5d2492f262e79181900360200190a15b5050505050565b600981565b662386f26fc1000081565b61100781565b61100681565b60005460ff1681565b600081565b60005460ff166108fb576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b336110071461093b5760405162461bcd60e51b815260040180806020018281038252602e815260200180611ba5602e913960400191505060405180910390fd5b6109a684848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260148152731b5a5cd9195b59585b9bdc951a1c995cda1bdb1960621b6020820152915061133a9050565b15610a7f57602081146109ea5760405162461bcd60e51b8152600401808060200182810382526027815260200180611b4e6027913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610a289185858083850183828082843760009201919091525061142292505050565b9050600a8110158015610a3c575060055481105b610a775760405162461bcd60e51b8152600401808060200182810382526025815260200180611bf56025913960400191505060405180910390fd5b600455610c11565b610ae584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e19995b1bdb9e551a1c995cda1bdb19608a1b6020820152915061133a9050565b15610bd45760208114610b295760405162461bcd60e51b8152600401808060200182810382526022815260200180611bd36022913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610b679185858083850183828082843760009201919091525061142292505050565b9050601481118015610b7b57506103e88111155b610bcc576040805162461bcd60e51b815260206004820181905260248201527f7468652066656c6f6e795468726573686f6c64206f7574206f662072616e6765604482015290519081900360640190fd5b600555610c11565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b609681565b61100281565b6040517f07db600eebe2ac176be8dcebad61858c245a4961bb32ca2aa3d159b09aa0810e90600090a1505050565b334114610d1a5760405162461bcd60e51b815260040180806020018281038252602d815260200180611c49602d913960400191505060405180910390fd5b60005460ff16610d6d576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b6003544311610dc3576040805162461bcd60e51b815260206004820181905260248201527f63616e206e6f7420736c61736820747769636520696e206f6e6520626c6f636b604482015290519081900360640190fd5b610dcb611ade565b506001600160a01b0381166000908152600260208181526040928390208351606081018552815481526001820154928101929092529091015460ff161580159282019290925290610e26576020810180516001019052610e7f565b60016040820181905260208201819052805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0384161790555b4381526001600160a01b038216600090815260026020818152604092839020845181559084015160018201819055928401519101805460ff19169115159190911790556005549081610ecd57fe5b0661102f57604080516335409f7f60e01b81526001600160a01b03841660048201529051611000916335409f7f91602480830192600092919082900301818387803b158015610f1b57600080fd5b505af1158015610f2f573d6000803e3d6000fd5b505050506120006001600160a01b031663f7a251d7600b610f4f85611427565b60006040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015610faf578181015183820152602001610f97565b50505050905090810190601f168015610fdc5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b158015610ffd57600080fd5b505af1158015611011573d6000803e3d6000fd5b505050506040513d602081101561102757600080fd5b506110a59050565b60045481602001518161103e57fe5b066110a557604080516375abf10160e11b81526001600160a01b038416600482015290516110009163eb57e20291602480830192600092919082900301818387803b15801561108c57600080fd5b505af11580156110a0573d6000803e3d6000fd5b505050505b6040516001600160a01b038316907fddb6012116e51abf5436d956a4f0ebd927e92c576ff96d7918290c8782291e3e90600090a2505043600355565b61100381565b60005460ff161561113f576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b603260045560966005556000805460ff19166001179055565b61100081565b600381565b33611000146111a35760405162461bcd60e51b8152600401808060200182810382526030815260200180611b756030913960400191505060405180910390fd5b60005460ff166111f6576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b60015460005b818110156112875760026000600180848603038154811061121957fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff1916905580548061125d57fe5b600082815260209020810160001990810180546001600160a01b03191690550190556001016111fc565b506040517fcfdb3b6ccaeccbdc68be3c59c840e3b3c90f0a7c491f5fff1cf56cfda200dd9c90600090a150565b61100481565b6112c2611b01565b60006112cc611b01565b6112d4611b13565b6112e56112e0866114f9565b61151e565b90506000805b6112f483611568565b1561132d57806113205761130f61130a84611589565b6115d7565b63ffffffff16845260019150611325565b61132d565b6001016112eb565b5091935090915050915091565b6000816040516020018082805190602001908083835b6020831061136f5780518252601f199092019160209182019101611350565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106113dd5780518252601f1990920191602091820191016113be565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490505b92915050565b015190565b60408051600480825260a08201909252606091829190816020015b606081526020019060019003908161144257905050905061146b836001600160a01b0316611637565b8160008151811061147857fe5b602002602001018190525061148c4361165a565b8160018151811061149957fe5b60209081029190910101526114ae606161165a565b816002815181106114bb57fe5b60200260200101819052506114cf4261165a565b816003815181106114dc57fe5b60200260200101819052506114f08161166d565b9150505b919050565b611501611b33565b506040805180820190915281518152602082810190820152919050565b611526611b13565b61152f826116f7565b61153857600080fd5b60006115478360200151611731565b60208085015160408051808201909152868152920190820152915050919050565b6000611572611b33565b505080518051602091820151919092015191011190565b611591611b33565b61159a82611568565b6115a357600080fd5b602082015160006115b382611794565b80830160209586015260408051808201909152908152938401919091525090919050565b8051600090158015906115ec57508151602110155b6115f557600080fd5b60006116048360200151611731565b8351602080860151830180519394509184900392919083101561162e57826020036101000a820491505b50949350505050565b60408051600560a21b83186014820152603481019091526060906114f08161182d565b606061141c61166883611883565b61182d565b606081516000141561168e57506040805160008152602081019091526114f4565b60608260008151811061169d57fe5b602002602001015190506000600190505b83518110156116de576116d4828583815181106116c757fe5b6020026020010151611969565b91506001016116ae565b506114f06116f1825160c060ff166119e6565b82611969565b8051600090611708575060006114f4565b6020820151805160001a9060c0821015611727576000925050506114f4565b5060019392505050565b8051600090811a608081101561174b5760009150506114f4565b60b8811080611766575060c08110801590611766575060f881105b156117755760019150506114f4565b60c08110156117895760b5190190506114f4565b60f5190190506114f4565b80516000908190811a60808110156117af5760019150611826565b60b88110156117c457607e1981019150611826565b60c08110156117f15760b78103600185019450806020036101000a85510460018201810193505050611826565b60f88110156118065760be1981019150611826565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b60608151600114801561185f5750607f60f81b8260008151811061184d57fe5b01602001516001600160f81b03191611155b1561186b5750806114f4565b61141c61187d8351608060ff166119e6565b83611969565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166118c7575060186118eb565b6fffffffffffffffffffffffffffffffff1984166118e7575060106118eb565b5060005b60208110156119215781818151811061190057fe5b01602001516001600160f81b0319161561191957611921565b6001016118eb565b60008160200390506060816040519080825280601f01601f191660200182016040528015611956576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b8183101561199a578051835260209283019201611982565b50855184518101855292509050808201602086015b818310156119c75780518352602092830192016119af565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310611a36576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411611a905782840160f81b81600081518110611a7257fe5b60200101906001600160f81b031916908160001a905350905061141c565b6060611a9b85611883565b90508381510160370160f81b82600081518110611ab457fe5b60200101906001600160f81b031916908160001a905350611ad58282611969565b95945050505050565b604051806060016040528060008152602001600081526020016000151581525090565b60408051602081019091526000815290565b6040518060400160405280611b26611b33565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe6c656e677468206f66206d697364656d65616e6f725468726573686f6c64206d69736d61746368746865206d6573736167652073656e646572206d7573742062652076616c696461746f7253657420636f6e7472616374746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662066656c6f6e795468726573686f6c64206d69736d61746368746865206d697364656d65616e6f725468726573686f6c64206f7574206f662072616e6765746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d6573736167652073656e646572206d7573742062652074686520626c6f636b2070726f6475636572a26469706673582212203c75feabfa95d80f8670bc9249ad2a813867311d79e6a0c9e3a1233d3c2c953964736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001002": { - "balance": "0x0", - "code": "0x60806040526004361061014f5760003560e01c806396713da9116100b6578063c81b16621161006f578063c81b1662146103dc578063dc927faf146103f1578063f9a2bbc714610406578063fb5478b31461041b578063fc3e590814610430578063fd6a68791461044557610193565b806396713da91461033a5780639a99b4f01461034f5780639dc0926214610388578063a1a11bf51461039d578063a78abc16146103b2578063ab51bb96146103c757610193565b806351e806721161010857806351e806721461028a5780636d70f7ae1461029f5780636e47b482146102e657806370fd5bad146102fb57806375d47a0a146103105780637942fd051461032557610193565b80630bee7a67146101985780633a0b0eff146101c65780633dffc387146101ed57806343756e5c14610218578063493279b1146102495780634bf6c8821461027557610193565b366101935734156101915760408051348152905133917f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db919081900360200190a25b005b600080fd5b3480156101a457600080fd5b506101ad61045a565b6040805163ffffffff9092168252519081900360200190f35b3480156101d257600080fd5b506101db61045f565b60408051918252519081900360200190f35b3480156101f957600080fd5b50610202610465565b6040805160ff9092168252519081900360200190f35b34801561022457600080fd5b5061022d61046a565b604080516001600160a01b039092168252519081900360200190f35b34801561025557600080fd5b5061025e610470565b6040805161ffff9092168252519081900360200190f35b34801561028157600080fd5b50610202610475565b34801561029657600080fd5b5061022d61047a565b3480156102ab57600080fd5b506102d2600480360360208110156102c257600080fd5b50356001600160a01b0316610480565b604080519115158252519081900360200190f35b3480156102f257600080fd5b5061022d61049e565b34801561030757600080fd5b506102026104a4565b34801561031c57600080fd5b5061022d6104a9565b34801561033157600080fd5b506102026104af565b34801561034657600080fd5b506102026104b4565b34801561035b57600080fd5b506101db6004803603604081101561037257600080fd5b506001600160a01b0381351690602001356104b9565b34801561039457600080fd5b5061022d610664565b3480156103a957600080fd5b5061022d61066a565b3480156103be57600080fd5b506102d2610670565b3480156103d357600080fd5b506101ad610679565b3480156103e857600080fd5b5061022d61067e565b3480156103fd57600080fd5b5061022d610684565b34801561041257600080fd5b5061022d61068a565b34801561042757600080fd5b506101db610690565b34801561043c57600080fd5b5061020261069c565b34801561045157600080fd5b5061022d6106a1565b606481565b60015481565b600181565b61100181565b606181565b600881565b61200081565b6001600160a01b031660009081526002602052604090205460ff1690565b61100581565b600281565b61100881565b600b81565b600981565b6000805460ff1661053657600260208190527fe57bda0a954a7c7381b17b2c763e646ba2c60f67292d287ba583603e2c1c41668054600160ff19918216811790925561100560009081527fe25235fc0de9d7165652bef0846fefda506174abb9a190f03d0f7bcc6146dbce80548316841790559282558254161790555b3360009081526002602052604090205460ff166105845760405162461bcd60e51b815260040180806020018281038252602d8152602001806106a8602d913960400191505060405180910390fd5b60004783106105935747610595565b825b9050670de0b6b3a76400008111156105b25750670de0b6b3a76400005b8015610633576040516001600160a01b0385169082156108fc029083906000818181858888f193505050501580156105ee573d6000803e3d6000fd5b506040805182815290516001600160a01b038616917ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0919081900360200190a261065d565b6040517fe589651933c2457488cc0d8e0941518abf748e799435e4e396d9c4d0b2db2d4d90600090a15b9392505050565b61100781565b61100681565b60005460ff1681565b600081565b61100281565b61100381565b61100081565b670de0b6b3a764000081565b600381565b6110048156fe6f6e6c79206f70657261746f7220697320617661696c61626c6520746f2063616c6c20746865206d6574686f64a26469706673582212206e40023fb74e48dfc701bcc667e0729a8491ff7ddabd668e2c6383a508bb167764736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001003": { - "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b50600436106102115760003560e01c8063a78abc1611610125578063dda83148116100ad578063e405bbc31161007c578063e405bbc314610681578063ea54b2aa14610689578063f9a2bbc714610691578063fc3e590814610699578063fd6a6879146106a157610211565b8063dda8314814610609578063df5fe7041461062f578063e1c7392a14610655578063e2761af01461065d57610211565b8063c81b1662116100f4578063c81b166214610534578063cba510a91461053c578063d816987914610562578063da8d08f0146105db578063dc927faf1461060157610211565b8063a78abc1614610444578063ab51bb9614610460578063ac43175114610468578063adc879e91461052c57610211565b8063564b81ef116101a857806375d47a0a1161017757806375d47a0a1461041c5780637942fd051461042457806396713da91461042c5780639dc0926214610434578063a1a11bf51461043c57610211565b8063564b81ef146102ca5780635c5ae8db146103475780636e47b4821461040c57806370fd5bad1461041457610211565b806343756e5c116101e457806343756e5c14610277578063493279b11461029b5780634bf6c882146102ba57806351e80672146102c257610211565b80630bee7a67146102165780632657e9b61461023757806333f7798d146102515780633dffc38714610259575b600080fd5b61021e6106a9565b6040805163ffffffff9092168252519081900360200190f35b61023f6106ae565b60408051918252519081900360200190f35b61023f6106b9565b6102616106bf565b6040805160ff9092168252519081900360200190f35b61027f6106c4565b604080516001600160a01b039092168252519081900360200190f35b6102a36106ca565b6040805161ffff9092168252519081900360200190f35b6102616106cf565b61027f6106d4565b6102d26106da565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561030c5781810151838201526020016102f4565b50505050905090810190601f1680156103395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61036d6004803603602081101561035d57600080fd5b50356001600160401b03166107e6565b60405180856001600160401b03166001600160401b0316815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156103ce5781810151838201526020016103b6565b50505050905090810190601f1680156103fb5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b61027f6108a1565b6102616108a7565b61027f6108ac565b6102616108b2565b6102616108b7565b61027f6108bc565b61027f6108c2565b61044c6108c8565b604080519115158252519081900360200190f35b61021e6108d1565b61052a6004803603604081101561047e57600080fd5b81019060208101813564010000000081111561049957600080fd5b8201836020820111156104ab57600080fd5b803590602001918460018302840111640100000000831117156104cd57600080fd5b9193909290916020810190356401000000008111156104eb57600080fd5b8201836020820111156104fd57600080fd5b8035906020019184600183028401116401000000008311171561051f57600080fd5b5090925090506108d6565b005b61023f610b8f565b61027f610b95565b61023f6004803603602081101561055257600080fd5b50356001600160401b0316610b9b565b61044c6004803603604081101561057857600080fd5b81019060208101813564010000000081111561059357600080fd5b8201836020820111156105a557600080fd5b803590602001918460018302840111640100000000831117156105c757600080fd5b9193509150356001600160401b0316610bba565b61027f600480360360208110156105f157600080fd5b50356001600160401b031661139a565b61027f6113b5565b61027f6004803603602081101561061f57600080fd5b50356001600160401b03166113bb565b61044c6004803603602081101561064557600080fd5b50356001600160401b03166113df565b61052a611421565b6106656115c6565b604080516001600160401b039092168252519081900360200190f35b6106656115d5565b6102d26115eb565b61027f611608565b61026161160e565b61027f611613565b606481565b662386f26fc1000081565b60055481565b600181565b61100181565b606181565b600881565b61200081565b604080516020808252818301909252606091829190602082018180368337505060045460208301525090506000805b60208160ff16101561075057828160ff168151811061072457fe5b01602001516001600160f81b0319161561074357600190910190610748565b610750565b600101610709565b5060608160ff166040519080825280601f01601f191660200182016040528015610781576020820181803683370190505b50905060005b8260ff168160ff1610156107dd57838160ff16815181106107a457fe5b602001015160f81c60f81b828260ff16815181106107be57fe5b60200101906001600160f81b031916908160001a905350600101610787565b50925050505b90565b60016020818152600092835260409283902080548184015460028084015460038501805489516101009982161599909902600019011692909204601f81018790048702880187019098528787526001600160401b0390931696919592949091908301828280156108975780601f1061086c57610100808354040283529160200191610897565b820191906000526020600020905b81548152906001019060200180831161087a57829003601f168201915b5050505050905084565b61100581565b600281565b61100881565b600b81565b600981565b61100781565b61100681565b60005460ff1681565b600081565b60005460ff1661092d576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604482015290519081900360640190fd5b336110071461096d5760405162461bcd60e51b815260040180806020018281038252602e815260200180611ac5602e913960400191505060405180910390fd5b6109e184848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601b81527f726577617264466f7256616c696461746f725365744368616e67650000000000602082015291506116199050565b15610ac05760208114610a255760405162461bcd60e51b815260040180806020018281038252602e815260200180611a64602e913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610a639185858083850183828082843760009201919091525061170092505050565b9050600081118015610a7d5750670de0b6b3a76400008111155b610ab85760405162461bcd60e51b815260040180806020018281038252602f815260200180611af3602f913960400191505060405180910390fd5b600555610afd565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b60045481565b61100281565b6001600160401b03166000908152600160208190526040909120015490565b60408051630a83aaa960e31b815233600482015290516000916110069163541d554891602480820192602092909190829003018186803b158015610bfd57600080fd5b505afa158015610c11573d6000803e3d6000fd5b505050506040513d6020811015610c2757600080fd5b5051610c7a576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b6001600160401b0382166000908152600260205260409020546001600160a01b031615610cee576040805162461bcd60e51b815260206004820152601c60248201527f63616e27742073796e63206475706c6963617465642068656164657200000000604482015290519081900360640190fd5b6003546001600160401b0390811690831611610d3b5760405162461bcd60e51b8152600401808060200182810382526026815260200180611b226026913960400191505060405180910390fd5b600354600160401b90046001600160401b0316610d56611862565b6001600160401b0382811660009081526001602081815260409283902083516080810185528154909516855280830154858301526002808201548686015260038201805486516101009682161596909602600019011691909104601f81018490048402850184019095528484529093606086019392830182828015610e1c5780601f10610df157610100808354040283529160200191610e1c565b820191906000526020600020905b815481529060010190602001808311610dff57829003601f168201915b50505050508152505090505b6003546001600160401b0390811690831610610f3957836001600160401b0316826001600160401b03161015610e5d57610f39565b80516001600160401b0380821660009081526001602081815260409283902083516080810185528154909516855280830154858301526002808201548686015260038201805486516101009682161596909602600019011691909104601f8101849004840285018401909552848452959750939460608601939091830182828015610f295780601f10610efe57610100808354040283529160200191610f29565b820191906000526020600020905b815481529060010190602001808311610f0c57829003601f168201915b5050505050815250509050610e28565b6060810151516110305780516001600160401b03811660009081526001602081815260409283902060030180548451600294821615610100026000190190911693909304601f810183900483028401830190945283835293955090929190830182828015610fe85780601f10610fbd57610100808354040283529160200191610fe8565b820191906000526020600020905b815481529060010190602001808311610fcb57829003601f168201915b505050506060830182905250516110305760405162461bcd60e51b8152600401808060200182810382526021815260200180611a436021913960400191505060405180910390fd5b6000816060015151608801905060608787905082016040519080825280601f01601f19166020018201604052801561106f576020820181803683370190505b509050600061107d82611705565b905061108b8486838661170b565b6110c65760405162461bcd60e51b81526004018080602001828103825260238152602001806119406023913960400191505060405180910390fd5b6000838201915061110c8a8a8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061177792505050565b9450905061111b818386611781565b8251602001935061112a611888565b6110008186866064600019fa61113f57600080fd5b805194506000600160f81b8616156111ce5750600554604080516309a99b4f60e41b815233600482015260248101929092525160019161100291639a99b4f0916044808201926020929091908290030181600087803b1580156111a157600080fd5b505af11580156111b5573d6000803e3d6000fd5b505050506040513d60208110156111cb57600080fd5b50505b856001600160401b0316955060208201935060006111ee858884156117c2565b90985090506001600160401b03808216908c161461123d5760405162461bcd60e51b8152600401808060200182810382526033815260200180611a926033913960400191505060405180910390fd5b6001600160401b03808c16600081815260026020818152604080842080546001600160a01b031916331790558e86168e529383526001808252928490208d518154961667ffffffffffffffff199096169590951785558c81015192850192909255918b01519183019190915560608a015180518b93926112c49260038501929101906118a7565b50506003546001600160401b03600160401b9091048116908d161115905061130c576003805467ffffffffffffffff60401b1916600160401b6001600160401b038e16021790555b7f4042c1020a8f410fb1c8859d276ab436aeb2c3074960e48467299cf1c966d3b48b8a8a602001518560405180856001600160401b03166001600160401b03168152602001846001600160401b03166001600160401b031681526020018381526020018215151515815260200194505050505060405180910390a15060019c9b505050505050505050505050565b6002602052600090815260409020546001600160a01b031681565b61100381565b6001600160401b03166000908152600260205260409020546001600160a01b031690565b6001600160401b0381166000908152600260205260408120546001600160a01b031615158061141b57506003546001600160401b038381169116145b92915050565b60005460ff1615611479576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b60008061149e60405180610100016040528060e0815260200161196360e09139611777565b815160045590925090506114b0611862565b60006114be848460006117c2565b60008083526001600160401b038281168252600160208181526040938490208651815467ffffffffffffffff191694169390931783558086015191830191909155918401516002820155606084015180519496509294508593909261152a9260038501929101906118a7565b50506003805467ffffffffffffffff19166001600160401b0384811691821767ffffffffffffffff60401b1916600160401b9290920291909117918290556000805460ff19166001179055662386f26fc10000600555602085810151604080519490931684529083015280517f5ac9b37d571677b80957ca05693f371526c602fd08042b416a29fdab7efefa499350918290030190a150505050565b6003546001600160401b031681565b600354600160401b90046001600160401b031681565b60405180610100016040528060e0815260200161196360e0913981565b61100081565b600381565b61100481565b6000816040516020018082805190602001908083835b6020831061164e5780518252601f19909201916020918201910161162f565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106116bc5780518252601f19909201916020918201910161169d565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b60200190565b60008460600151518284010392506000806117298760600151611777565b9092509050611739828683611781565b5050506040840151601f1983810191909152602090940151603f19830152605f19820192909252600454606719820152910160871990910152600190565b8051602090910191565b5b602081106117a1578251825260209283019290910190601f1901611782565b915181516020939093036101000a6000190180199091169216919091179052565b6117ca611862565b60088401516028850151604890950180519095600092916117e9611862565b6020810183905260408101829052866118545760008060688a036040519080825280601f01601f19166020018201604052801561182d576020820181803683370190505b506060840181905261183e90611777565b909250905061185160208c018383611781565b50505b989297509195505050505050565b604080516080810182526000808252602082018190529181019190915260608082015290565b6040518061100001604052806080906020820280368337509192915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106118e857805160ff1916838001178555611915565b82800160010185558215611915579182015b828111156119155782518255916020019190600101906118fa565b50611921929150611925565b5090565b6107e391905b80821115611921576000815560010161192b56fe6661696c656420746f2073657269616c697a6520636f6e73656e73757320737461746542696e616e63652d436861696e2d47616e67657300000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000aea1ac326886b992a991d21a6eb155f41b77867cbf659e78f31d89d8205122a84d1be64f0e9a466c2e66a53433928192783e29f8fa21beb2133499b5ef770f60000000e8d4a5100099308aa365c40554bc89982af505d85da95251445d5dd4a9bb37dd2584fd92d3000000e8d4a5100001776920ff0b0f38d78cf95c033c21adf7045785114e392a7544179652e0a612000000e8d4a510006661696c656420746f206c6f61642076616c696461746f722073657420646174616c656e677468206f6620726577617264466f7256616c696461746f725365744368616e6765206d69736d617463686865616465722068656967687420646f65736e277420657175616c20746f207468652073706563696669656420686569676874746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374746865206e6577526577617264466f7256616c696461746f725365744368616e6765206f7574206f662072616e676563616e27742073796e6320686561646572206265666f726520696e697469616c486569676874a264697066735822122054f539d4f9624b5b87ea3b4d66b04e31a6fa9de3789af1872d4cddc7acc2a79364736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001004": { - "balance": "180000000000000000000000000", - "code": "0x6080604052600436106102cd5760003560e01c80639dc0926211610175578063bd466461116100dc578063ebf71d5311610095578063fc1a598f1161006f578063fc1a598f14610c23578063fc3e59081461094e578063fd6a687914610c56578063ff9c00271461074c57610315565b8063ebf71d5314610be4578063f014847214610bf9578063f9a2bbc714610c0e57610315565b8063bd46646114610aed578063c81b166214610b20578063c8509d8114610b35578063dc6f5e901461094e578063dc927faf14610bba578063e1c7392a14610bcf57610315565b8063aa7415f51161012e578063aa7415f514610963578063ab51bb96146109aa578063ac431751146109bf578063b770186114610a8a578063b99328c514610a9f578063b9fd21e314610ad857610315565b80639dc09262146108c7578063a1a11bf5146108dc578063a496fba2146108f1578063a5cd588b14610906578063a78abc1614610939578063a7c9f02d1461094e57610315565b806361368475116102345780637942fd05116101ed5780638eff336c116101c75780638eff336c1461082557806396713da9146108645780639a854bbd146108795780639a99b4f01461088e57610315565b80637942fd051461078b578063831d65d1146107a05780638b87b21f1461056157610315565b8063613684751461031a5780636e0565201461060b5780636e47b4821461073757806370fd5bad1461074c57806371d308631461076157806375d47a0a1461077657610315565b806343756e5c1161028657806343756e5c14610576578063493279b11461058b5780634bf6c8821461031a57806350432d32146105b757806351e80672146105cc57806359b92789146105e157610315565b8063077b8f351461031a5780630bee7a67146103455780631182b87514610373578063149d14d91461046d5780633d713223146104945780633dffc3871461056157610315565b36610315573415610313576040805133815234602082015281517f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db929181900390910190a15b005b600080fd5b34801561032657600080fd5b5061032f610c6b565b6040805160ff9092168252519081900360200190f35b34801561035157600080fd5b5061035a610c70565b6040805163ffffffff9092168252519081900360200190f35b34801561037f57600080fd5b506103f86004803603604081101561039657600080fd5b60ff8235169190810190604081016020820135600160201b8111156103ba57600080fd5b8201836020820111156103cc57600080fd5b803590602001918460018302840111600160201b831117156103ed57600080fd5b509092509050610c75565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561043257818101518382015260200161041a565b50505050905090810190601f16801561045f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561047957600080fd5b50610482610da3565b60408051918252519081900360200190f35b3480156104a057600080fd5b50610545600480360360208110156104b757600080fd5b810190602081018135600160201b8111156104d157600080fd5b8201836020820111156104e357600080fd5b803590602001918460018302840111600160201b8311171561050457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610da9945050505050565b604080516001600160a01b039092168252519081900360200190f35b34801561056d57600080fd5b5061032f610dcd565b34801561058257600080fd5b50610545610dd2565b34801561059757600080fd5b506105a0610dd8565b6040805161ffff9092168252519081900360200190f35b3480156105c357600080fd5b50610482610ddd565b3480156105d857600080fd5b50610545610de8565b3480156105ed57600080fd5b506105456004803603602081101561060457600080fd5b5035610dee565b6107236004803603608081101561062157600080fd5b810190602081018135600160201b81111561063b57600080fd5b82018360208201111561064d57600080fd5b803590602001918460208302840111600160201b8311171561066e57600080fd5b919390929091602081019035600160201b81111561068b57600080fd5b82018360208201111561069d57600080fd5b803590602001918460208302840111600160201b831117156106be57600080fd5b919390929091602081019035600160201b8111156106db57600080fd5b8201836020820111156106ed57600080fd5b803590602001918460208302840111600160201b8311171561070e57600080fd5b91935091503567ffffffffffffffff16610e09565b604080519115158252519081900360200190f35b34801561074357600080fd5b506105456112f1565b34801561075857600080fd5b5061032f6112f7565b34801561076d57600080fd5b506104826112fc565b34801561078257600080fd5b50610545611302565b34801561079757600080fd5b5061032f611308565b3480156107ac57600080fd5b50610313600480360360408110156107c357600080fd5b60ff8235169190810190604081016020820135600160201b8111156107e757600080fd5b8201836020820111156107f957600080fd5b803590602001918460018302840111600160201b8311171561081a57600080fd5b50909250905061130d565b34801561083157600080fd5b506103136004803603606081101561084857600080fd5b508035906001600160a01b036020820135169060400135611456565b34801561087057600080fd5b5061032f6114dc565b34801561088557600080fd5b506104826114e1565b34801561089a57600080fd5b50610482600480360360408110156108b157600080fd5b506001600160a01b0381351690602001356114ed565b3480156108d357600080fd5b50610545611611565b3480156108e857600080fd5b50610545611617565b3480156108fd57600080fd5b5061032f61161d565b34801561091257600080fd5b506104826004803603602081101561092957600080fd5b50356001600160a01b0316611622565b34801561094557600080fd5b50610723611634565b34801561095a57600080fd5b5061032f61163d565b6107236004803603608081101561097957600080fd5b5080356001600160a01b03908116916020810135909116906040810135906060013567ffffffffffffffff16611642565b3480156109b657600080fd5b5061035a61161d565b3480156109cb57600080fd5b50610313600480360360408110156109e257600080fd5b810190602081018135600160201b8111156109fc57600080fd5b820183602082011115610a0e57600080fd5b803590602001918460018302840111600160201b83111715610a2f57600080fd5b919390929091602081019035600160201b811115610a4c57600080fd5b820183602082011115610a5e57600080fd5b803590602001918460018302840111600160201b83111715610a7f57600080fd5b509092509050611d16565b348015610a9657600080fd5b50610482611f85565b348015610aab57600080fd5b5061031360048036036040811015610ac257600080fd5b50803590602001356001600160a01b0316611f8b565b348015610ae457600080fd5b50610482612001565b348015610af957600080fd5b5061048260048036036020811015610b1057600080fd5b50356001600160a01b031661200b565b348015610b2c57600080fd5b50610545612026565b348015610b4157600080fd5b5061031360048036036040811015610b5857600080fd5b60ff8235169190810190604081016020820135600160201b811115610b7c57600080fd5b820183602082011115610b8e57600080fd5b803590602001918460018302840111600160201b83111715610baf57600080fd5b50909250905061202c565b348015610bc657600080fd5b506105456120fc565b348015610bdb57600080fd5b50610313612102565b348015610bf057600080fd5b5061032f6121a2565b348015610c0557600080fd5b5061032f6121a7565b348015610c1a57600080fd5b506105456121ac565b348015610c2f57600080fd5b506103f860048036036020811015610c4657600080fd5b50356001600160a01b03166121b2565b348015610c6257600080fd5b506105456122d9565b600881565b606481565b60005460609060ff16610cbd576040805162461bcd60e51b815260206004820152601960248201526000805160206145c7833981519152604482015290519081900360640190fd5b3361200014610cfd5760405162461bcd60e51b815260040180806020018281038252602f815260200180614575602f913960400191505060405180910390fd5b60ff841660021415610d4f57610d4883838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506122df92505050565b9050610d9c565b6040805162461bcd60e51b815260206004820152601860248201527f756e7265636f676e697a65642073796e207061636b6167650000000000000000604482015290519081900360640190fd5b9392505050565b60015490565b6020818101516000908152600490915260409020546001600160a01b03165b919050565b600181565b61100181565b606181565b662386f26fc1000081565b61200081565b6000908152600460205260409020546001600160a01b031690565b6000805460ff16610e4f576040805162461bcd60e51b815260206004820152601960248201526000805160206145c7833981519152604482015290519081900360640190fd5b868514610e8d5760405162461bcd60e51b815260040180806020018281038252603b81526020018061453a603b913960400191505060405180910390fd5b868314610ecb5760405162461bcd60e51b815260040180806020018281038252603f81526020018061440d603f913960400191505060405180910390fd5b426078018267ffffffffffffffff161015610f175760405162461bcd60e51b81526004018080602001828103825260248152602001806142fd6024913960400191505060405180910390fd5b6402540be400340615610f5b5760405162461bcd60e51b815260040180806020018281038252604081526020018061463d6040913960400191505060405180910390fd5b60408051868152602080880282010190915285906000908190606090848015610f8e578160200160208202803683370190505b50905060005b84811015611069576402540be4008b8b83818110610fae57fe5b9050602002013581610fbc57fe5b0615610ff95760405162461bcd60e51b815260040180806020018281038252603c81526020018061444c603c913960400191505060405180910390fd5b61101e8b8b8381811061100857fe5b905060200201358561240390919063ffffffff16565b935061104a6402540be4008c8c8481811061103557fe5b9050602002013561245d90919063ffffffff16565b82828151811061105657fe5b6020908102919091010152600101610f94565b5060015461108e90611081908663ffffffff61249f16565b849063ffffffff61240316565b3410156110cc5760405162461bcd60e51b81526004018080602001828103825260568152602001806145e76056913960600191505060405180910390fd5b6110dc348463ffffffff6124f816565b91506110e6614156565b6040518060c001604052806221272160e91b60001b815260200160006001600160a01b031681526020018381526020018e8e808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050908252506040805160208c810282810182019093528c82529283019290918d918d91829185019084908082843760009201919091525050509082525067ffffffffffffffff8916602090910152905061200063f7a251d760036111aa8461253a565b6111bf876402540be40063ffffffff61245d16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561121d578181015183820152602001611205565b50505050905090810190601f16801561124a5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b15801561126b57600080fd5b505af115801561127f573d6000803e3d6000fd5b505050506040513d602081101561129557600080fd5b505060408051600081523360208201528082018690526060810185905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9181900360800190a15060019c9b505050505050505050505050565b61100581565b600281565b60015481565b61100881565b600b81565b60005460ff16611352576040805162461bcd60e51b815260206004820152601960248201526000805160206145c7833981519152604482015290519081900360640190fd5b33612000146113925760405162461bcd60e51b815260040180806020018281038252602f815260200180614575602f913960400191505060405180910390fd5b60ff8316600314156113e2576113dd82828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506127f592505050565b611451565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a15b505050565b33611008146114965760405162461bcd60e51b81526004018080602001828103825260238152602001806145a46023913960400191505060405180910390fd5b600083815260046020908152604080832080546001600160a01b039096166001600160a01b03199096168617905593825260038152838220949094556002909352912055565b600981565b677ce66c50e284000081565b6000805460ff16611533576040805162461bcd60e51b815260206004820152601960248201526000805160206145c7833981519152604482015290519081900360640190fd5b33611005146115735760405162461bcd60e51b815260040180806020018281038252602f815260200180614270602f913960400191505060405180910390fd5b60004783106115825747611584565b825b90508015611608576040516001600160a01b0385169082156108fc029083906000818181858888f193505050501580156115c2573d6000803e3d6000fd5b50604080516001600160a01b03861681526020810183905281517ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0929181900390910190a15b90505b92915050565b61100781565b61100681565b600081565b60026020526000908152604090205481565b60005460ff1681565b600381565b6000805460ff16611688576040805162461bcd60e51b815260206004820152601960248201526000805160206145c7833981519152604482015290519081900360640190fd5b426078018267ffffffffffffffff1610156116d45760405162461bcd60e51b81526004018080602001828103825260248152602001806142fd6024913960400191505060405180910390fd5b6402540be4003406156117185760405162461bcd60e51b815260040180806020018281038252604081526020018061463d6040913960400191505060405180910390fd5b600080806001600160a01b0388166117f75760015461173e90879063ffffffff61240316565b34101561177c5760405162461bcd60e51b81526004018080602001828103825260618152602001806143876061913960800191505060405180910390fd5b6402540be4008606156117c05760405162461bcd60e51b815260040180806020018281038252603c81526020018061444c603c913960400191505060405180910390fd5b6117d0348763ffffffff6124f816565b90506117e7866402540be40063ffffffff61245d16565b6221272160e91b93509150611a9a565b6001600160a01b03881660009081526003602052604090205492508261184e5760405162461bcd60e51b81526004018080602001828103825260318152602001806143566031913960400191505060405180910390fd5b60015434101561188f5760405162461bcd60e51b815260040180806020018281038252603f8152602001806144a9603f913960400191505060405180910390fd5b506001600160a01b03871660009081526002602052604090205434906008811115806118da57506008811180156118da57506118d8876007198301600a0a63ffffffff61285116565b155b6119155760405162461bcd60e51b815260040180806020018281038252603c81526020018061444c603c913960400191505060405180910390fd5b61191f8782612893565b925061192a846128d3565b15611972576305f5e1008310156119725760405162461bcd60e51b815260040180806020018281038252603a81526020018061429f603a913960400191505060405180910390fd5b60088110158061198c575060088110801561198c57508683115b6119c75760405162461bcd60e51b81526004018080602001828103825260258152602001806143e86025913960400191505060405180910390fd5b677ce66c50e2840000831115611a0e5760405162461bcd60e51b81526004018080602001828103825260358152602001806143216035913960400191505060405180910390fd5b604080516323b872dd60e01b81523360048201523060248201526044810189905290516001600160a01b038b16916323b872dd9160648083019260209291908290030181600087803b158015611a6357600080fd5b505af1158015611a77573d6000803e3d6000fd5b505050506040513d6020811015611a8d57600080fd5b5051611a9857600080fd5b505b611aa2614156565b6040805160c0810182528581526001600160a01b038b166020820152815160018082528184018452919283019181602001602082028036833750505081526040805160018082528183019092526020928301929091908083019080368337505050815260408051600180825281830190925260209283019290919080830190803683370190505081526020018767ffffffffffffffff168152509050828160400151600081518110611b5057fe5b602002602001018181525050878160600151600081518110611b6e57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050338160800151600081518110611ba057fe5b6001600160a01b039092166020928302919091019091015261200063f7a251d76003611bcb8461253a565b611be0866402540be40063ffffffff61245d16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611c3e578181015183820152602001611c26565b50505050905090810190601f168015611c6b5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b158015611c8c57600080fd5b505af1158015611ca0573d6000803e3d6000fd5b505050506040513d6020811015611cb657600080fd5b5050604080516001600160a01b038b1681523360208201528082018990526060810184905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9181900360800190a150600198975050505050505050565b3361100714611d565760405162461bcd60e51b815260040180806020018281038252602e8152602001806144e8602e913960400191505060405180910390fd5b60208114611dab576040805162461bcd60e51b815260206004820152601b60248201527f65787065637465642076616c7565206c656e6774682069732033320000000000604482015290519081900360640190fd5b606084848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8801819004810282018101909252868152939450606093925086915085908190840183828082843760009201919091525050505060208301519091506772656c617946656560c01b811415611eb3576020820151670de0b6b3a76400008111158015611e5a57506402540be4008106155b611eab576040805162461bcd60e51b815260206004820152601960248201527f7468652072656c6179466565206f7574206f662072616e676500000000000000604482015290519081900360640190fd5b600155611ef0565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a878787876040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050505050565b61c35081565b3361100814611fcb5760405162461bcd60e51b81526004018080602001828103825260238152602001806145a46023913960400191505060405180910390fd5b600091825260046020908152604080842080546001600160a01b03191690556001600160a01b0392909216835260039052812055565b6221272160e91b81565b6001600160a01b031660009081526003602052604090205490565b61100281565b60005460ff16612071576040805162461bcd60e51b815260206004820152601960248201526000805160206145c7833981519152604482015290519081900360640190fd5b33612000146120b15760405162461bcd60e51b815260040180806020018281038252602f815260200180614575602f913960400191505060405180910390fd5b60ff8316600314156113e2576113dd82828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506129d992505050565b61100381565b60005460ff161561215a576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b662386f26fc1000060019081556000808052600260205260127fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b55805460ff19169091179055565b600481565b600581565b61100081565b6001600160a01b03811660009081526003602090815260409182902054825182815280840190935260609290918391906020820181803683375050506020810183905290506000805b60208160ff16101561224257828160ff168151811061221657fe5b01602001516001600160f81b031916156122355760019091019061223a565b612242565b6001016121fb565b5060608160ff166040519080825280601f01601f191660200182016040528015612273576020820181803683370190505b50905060005b8260ff168160ff1610156122cf57838160ff168151811061229657fe5b602001015160f81c60f81b828260ff16815181106122b057fe5b60200101906001600160f81b031916908160001a905350600101612279565b5095945050505050565b61100481565b60606122e96141a2565b60006122f484612ad7565b915091508061234a576040805162461bcd60e51b815260206004820152601f60248201527f756e7265636f676e697a6564207472616e73666572496e207061636b61676500604482015290519081900360640190fd5b600061235583612c16565b905063ffffffff8116156123e9576040808401516020808601516001600160a01b031660009081526002909152918220546123909190612893565b905061239a6141d7565b60405180608001604052808660000151815260200183815260200186608001516001600160a01b031681526020018463ffffffff1681525090506123dd81612f2e565b95505050505050610dc8565b50506040805160008152602081019091529150610dc89050565b600082820183811015611608576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600061160883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061300a565b6000826124ae5750600061160b565b828202828482816124bb57fe5b04146116085760405162461bcd60e51b81526004018080602001828103825260218152602001806144886021913960400191505060405180910390fd5b600061160883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506130ac565b60408051600680825260e08201909252606091829190816020015b6060815260200190600190039081612555575050835190915061257790613106565b8160008151811061258457fe5b60200260200101819052506125a583602001516001600160a01b0316613119565b816001815181106125b257fe5b6020026020010181905250600083604001515190506060816040519080825280602002602001820160405280156125fd57816020015b60608152602001906001900390816125e85790505b50905060005b8281101561264a5761262b8660400151828151811061261e57fe5b6020026020010151613106565b82828151811061263757fe5b6020908102919091010152600101612603565b506126548161313c565b8360028151811061266157fe5b60200260200101819052506060826040519080825280602002602001820160405280156126a257816020015b606081526020019060019003908161268d5790505b50905060005b838110156126f8576126d9876060015182815181106126c357fe5b60200260200101516001600160a01b0316613119565b8282815181106126e557fe5b60209081029190910101526001016126a8565b506127028161313c565b8460038151811061270f57fe5b602002602001018190525060608360405190808252806020026020018201604052801561275057816020015b606081526020019060019003908161273b5790505b50905060005b8481101561279057612771886080015182815181106126c357fe5b82828151811061277d57fe5b6020908102919091010152600101612756565b5061279a8161313c565b856004815181106127a757fe5b60200260200101819052506127c98760a0015167ffffffffffffffff16613106565b856005815181106127d657fe5b60200260200101819052506127ea8561313c565b979650505050505050565b6127fd6141fe565b6000612808836131c6565b91509150806128485760405162461bcd60e51b81526004018080602001828103825260248152602001806145166024913960400191505060405180910390fd5b61145182613391565b600061160883836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f00000000000000008152506137e2565b600060088211156128bc576128b5836007198401600a0a63ffffffff61245d16565b905061160b565b611608836008849003600a0a63ffffffff61249f16565b604080516020808252818301909252600091606091906020820181803683375050506020810184905290506000805b60208160ff16101561294957828160ff168151811061291d57fe5b01602001516001600160f81b0319161561293c57600190910190612941565b612949565b600101612902565b50600860ff8216101561296157600092505050610dc8565b816005820360ff168151811061297357fe5b6020910101516001600160f81b031916602d60f81b1461299857600092505050610dc8565b816001820360ff16815181106129aa57fe5b6020910101516001600160f81b031916604d60f81b146129cf57600092505050610dc8565b5060019392505050565b6129e1614156565b60006129ec83613844565b9150915080612a2c5760405162461bcd60e51b81526004018080602001828103825260248152602001806142d96024913960400191505060405180910390fd5b612a346141fe565b602080840180516001600160a01b0390811684526040808701518585015291511660009081526002909252812054905b846040015151811015612ab557612a9285604001518281518110612a8457fe5b602002602001015183613abf565b85604001518281518110612aa257fe5b6020908102919091010152600101612a64565b506080840151604083015260056060830152612ad082613391565b5050505050565b612adf6141a2565b6000612ae96141a2565b612af1614235565b612b02612afd86613af8565b613b1d565b90506000805b612b1183613b67565b15612c095780612b3357612b2c612b2784613b88565b613bd6565b8452612c01565b8060011415612b6057612b4d612b4884613b88565b613c36565b6001600160a01b03166020850152612c01565b8060021415612b7f57612b75612b2784613b88565b6040850152612c01565b8060031415612ba757612b94612b4884613b88565b6001600160a01b03166060850152612c01565b8060041415612bcf57612bbc612b4884613b88565b6001600160a01b03166080850152612c01565b8060051415612bfc57612be4612b2784613b88565b67ffffffffffffffff1660a085015260019150612c01565b612c09565b600101612b08565b5091935090915050915091565b60208101516000906001600160a01b0316612d18578160a0015167ffffffffffffffff16421115612c4957506001610dc8565b8160400151471015612c5d57506003610dc8565b81606001516001600160a01b03166108fc83604001519081150290604051600060405180830381858888f19350505050612c9957506004610dc8565b7f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5982602001518360600151846040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a1506000610dc8565b8160a0015167ffffffffffffffff16421115612d3657506001610dc8565b81516020808401516001600160a01b031660009081526003909152604090205414612d6357506002610dc8565b602080830151604080516370a0823160e01b815230600482015290516000936001600160a01b03909316926370a082319261c3509260248083019392829003018187803b158015612db357600080fd5b5086fa158015612dc7573d6000803e3d6000fd5b50505050506040513d6020811015612dde57600080fd5b50516040840151909150811015612df9575060039050610dc8565b600083602001516001600160a01b031663a9059cbb61c350866060015187604001516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b158015612e6a57600080fd5b5087f1158015612e7e573d6000803e3d6000fd5b50505050506040513d6020811015612e9557600080fd5b505190508015612f22577f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5984602001518560600151866040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a15060009150610dc89050565b5060059150610dc89050565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081612f495750508351909150612f6b90613106565b81600081518110612f7857fe5b6020026020010181905250612f908360200151613106565b81600181518110612f9d57fe5b6020026020010181905250612fbe83604001516001600160a01b0316613119565b81600281518110612fcb57fe5b6020026020010181905250612fe9836060015163ffffffff16613106565b81600381518110612ff657fe5b6020026020010181905250610d9c8161313c565b600081836130965760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561305b578181015183820152602001613043565b50505050905090810190601f1680156130885780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816130a257fe5b0495945050505050565b600081848411156130fe5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561305b578181015183820152602001613043565b505050900390565b606061160b61311483613c50565b613d36565b60408051600560a21b8318601482015260348101909152606090610d9c81613d36565b606081516000141561315d5750604080516000815260208101909152610dc8565b60608260008151811061316c57fe5b602002602001015190506000600190505b83518110156131ad576131a38285838151811061319657fe5b6020026020010151613d88565b915060010161317d565b50610d9c6131c0825160c060ff16613e05565b82613d88565b6131ce6141fe565b60006131d86141fe565b6131e0614235565b6131ec612afd86613af8565b90506000805b6131fb83613b67565b15612c09578061322157613211612b4884613b88565b6001600160a01b03168452613389565b80600114156132c257606061323d61323885613b88565b613efd565b9050805160405190808252806020026020018201604052801561326a578160200160208202803683370190505b50602086015260005b81518110156132bb5761329882828151811061328b57fe5b6020026020010151613bd6565b866020015182815181106132a857fe5b6020908102919091010152600101613273565b5050613389565b80600214156133645760606132d961323885613b88565b90508051604051908082528060200260200182016040528015613306578160200160208202803683370190505b50604086015260005b81518110156132bb5761333482828151811061332757fe5b6020026020010151613c36565b8660400151828151811061334457fe5b6001600160a01b039092166020928302919091019091015260010161330f565b8060031415612bfc57613379612b2784613b88565b63ffffffff166060850152600191505b6001016131f2565b80516001600160a01b03166135885760005b81602001515181101561358257816040015181815181106133c057fe5b60200260200101516001600160a01b03166108fc836020015183815181106133e457fe5b60200260200101519081150290604051600060405180830381858888f193505050506134c4577f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e82600001518360400151838151811061344057fe5b60200260200101518460200151848151811061345857fe5b6020026020010151856060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a161357a565b7fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a8260000151836040015183815181106134fa57fe5b60200260200101518460200151848151811061351257fe5b6020026020010151856060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b6001016133a3565b506137df565b60005b8160200151518110156137dd57600082600001516001600160a01b031663a9059cbb61c350856040015185815181106135c057fe5b6020026020010151866020015186815181106135d857fe5b60200260200101516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b15801561362f57600080fd5b5087f1158015613643573d6000803e3d6000fd5b50505050506040513d602081101561365a57600080fd5b50519050801561371e577fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a83600001518460400151848151811061369a57fe5b6020026020010151856020015185815181106136b257fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a16137d4565b7f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e83600001518460400151848151811061375457fe5b60200260200101518560200151858151811061376c57fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b5060010161358b565b505b50565b600081836138315760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561305b578181015183820152602001613043565b5082848161383b57fe5b06949350505050565b61384c614156565b6000613856614156565b61385e614235565b61386a612afd86613af8565b90506000805b61387983613b67565b15613ab157806138965761388f612b2784613b88565b8452613aa9565b80600114156138be576138ab612b4884613b88565b6001600160a01b03166020850152613aa9565b806002141561394d5760606138d561323885613b88565b90508051604051908082528060200260200182016040528015613902578160200160208202803683370190505b50604086015260005b81518110156139465761392382828151811061328b57fe5b8660400151828151811061393357fe5b602090810291909101015260010161390b565b5050613aa9565b80600314156139e257606061396461323885613b88565b90508051604051908082528060200260200182016040528015613991578160200160208202803683370190505b50606086015260005b8151811015613946576139b282828151811061332757fe5b866060015182815181106139c257fe5b6001600160a01b039092166020928302919091019091015260010161399a565b8060041415613a775760606139f961323885613b88565b90508051604051908082528060200260200182016040528015613a26578160200160208202803683370190505b50608086015260005b815181101561394657613a4782828151811061332757fe5b86608001518281518110613a5757fe5b6001600160a01b0390921660209283029190910190910152600101613a2f565b8060051415613aa457613a8c612b2784613b88565b67ffffffffffffffff1660a085015260019150613aa9565b613ab1565b600101613870565b509195600195509350505050565b60006008821115613ae1576128b5836007198401600a0a63ffffffff61249f16565b611608836008849003600a0a63ffffffff61245d16565b613b00614255565b506040805180820190915281518152602082810190820152919050565b613b25614235565b613b2e82613fce565b613b3757600080fd5b6000613b468360200151613ffe565b60208085015160408051808201909152868152920190820152915050919050565b6000613b71614255565b505080518051602091820151919092015191011190565b613b90614255565b613b9982613b67565b613ba257600080fd5b60208201516000613bb282614061565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590613beb57508151602110155b613bf457600080fd5b6000613c038360200151613ffe565b83516020808601518301805193945091849003929190831015613c2d57826020036101000a820491505b50949350505050565b8051600090601514613c4757600080fd5b61160b82613bd6565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416613c9457506018613cb8565b6fffffffffffffffffffffffffffffffff198416613cb457506010613cb8565b5060005b6020811015613cee57818181518110613ccd57fe5b01602001516001600160f81b03191615613ce657613cee565b600101613cb8565b60008160200390506060816040519080825280601f01601f191660200182016040528015613d23576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015613d685750607f60f81b82600081518110613d5657fe5b01602001516001600160f81b03191611155b15613d74575080610dc8565b61160b613d868351608060ff16613e05565b835b6060806040519050835180825260208201818101602087015b81831015613db9578051835260209283019201613da1565b50855184518101855292509050808201602086015b81831015613de6578051835260209283019201613dce565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310613e55576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411613eaf5782840160f81b81600081518110613e9157fe5b60200101906001600160f81b031916908160001a905350905061160b565b6060613eba85613c50565b90508381510160370160f81b82600081518110613ed357fe5b60200101906001600160f81b031916908160001a905350613ef48282613d88565b95945050505050565b6060613f0882613fce565b613f1157600080fd5b6000613f1c836140fa565b9050606081604051908082528060200260200182016040528015613f5a57816020015b613f47614255565b815260200190600190039081613f3f5790505b5090506000613f6c8560200151613ffe565b60208601510190506000805b84811015613fc357613f8983614061565b9150604051806040016040528083815260200184815250848281518110613fac57fe5b602090810291909101015291810191600101613f78565b509195945050505050565b8051600090613fdf57506000610dc8565b6020820151805160001a9060c08210156129cf57600092505050610dc8565b8051600090811a6080811015614018576000915050610dc8565b60b8811080614033575060c08110801590614033575060f881105b15614042576001915050610dc8565b60c08110156140565760b519019050610dc8565b60f519019050610dc8565b80516000908190811a608081101561407c57600191506140f3565b60b881101561409157607e19810191506140f3565b60c08110156140be5760b78103600185019450806020036101000a855104600182018101935050506140f3565b60f88110156140d35760be19810191506140f3565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b805160009061410b57506000610dc8565b6000809050600061411f8460200151613ffe565b602085015185519181019250015b8082101561414d5761413e82614061565b6001909301929091019061412d565b50909392505050565b6040518060c001604052806000801916815260200160006001600160a01b03168152602001606081526020016060815260200160608152602001600067ffffffffffffffff1681525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b60408051608081018252600080825260208201819052918101829052606081019190915290565b604051806080016040528060006001600160a01b031681526020016060815260200160608152602001600063ffffffff1681525090565b6040518060400160405280614248614255565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe746865206d6573736167652073656e646572206d75737420626520696e63656e746976697a6520636f6e7472616374466f72206d696e69546f6b656e2c20746865207472616e7366657220616d6f756e74206d757374206e6f74206265206c657373207468616e2031756e7265636f676e697a6564207472616e736665724f75742073796e207061636b61676565787069726554696d65206d7573742062652074776f206d696e75746573206c61746572616d6f756e7420697320746f6f206c617267652c20657863656564206d6178696d756d206265703220746f6b656e20616d6f756e7474686520636f6e747261637420686173206e6f74206265656e20626f756e6420746f20616e79206265703220746f6b656e726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e736665724f757420424e4220616d6f756e7420616e64206d696e696d756d2072656c6179466565616d6f756e7420697320746f6f206c617267652c2075696e74323536206f766572666c6f774c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620726566756e644164647273696e76616c6964207472616e7366657220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e20746865206d696e696d756d2072656c6179466565746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374756e7265636f676e697a6564207472616e736665724f75742061636b207061636b6167654c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620616d6f756e7473746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d73672073656e646572206d75737420626520746f6b656e4d616e6167657274686520636f6e7472616374206e6f7420696e69742079657400000000000000726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e7366657220424e4220616d6f756e7420616e642072656c6179466565696e76616c696420726563656976656420424e4220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6ea2646970667358221220ee0772c728608488e6a5f5dfa5f29f8c4467aea7333c447ace15be38f4600ff464736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001005": { - "balance": "0x0", - "code": "0x6080604052600436106102605760003560e01c80637942fd0511610144578063ac431751116100b6578063dc927faf1161007a578063dc927faf1461076a578063dcae76ab1461077f578063e1c7392a14610794578063f9a2bbc7146107a9578063fc3e5908146107be578063fd6a6879146107d357610267565b8063ac43175114610630578063af40068114610701578063bd4cc8301461072b578063c7d2b028146102eb578063c81b16621461075557610267565b8063a1a11bf511610108578063a1a11bf5146105b2578063a3c3c0ad146105c7578063a413aff6146105dc578063a60d770b146105f1578063a78abc1614610606578063ab51bb961461061b57610267565b80637942fd051461052b57806387c1830a14610540578063930e1b091461055557806396713da9146105885780639dc092621461059d57610267565b806343756e5c116101dd57806354133307116101a15780635413330714610445578063572120951461045a5780636e47b4821461048d5780636f93d2e6146104a257806370fd5bad1461050157806375d47a0a1461051657610267565b806343756e5c146103b0578063490dfdf7146103c5578063493279b1146103ef5780634bf6c8821461041b57806351e806721461043057610267565b8063189d817211610224578063189d8172146103005780631b20087c146103155780631c6433121461032a5780633dffc3871461037057806341b5f4e51461039b57610267565b806308f2ec061461026c5780630bee7a67146102935780630c732068146102c157806310e06a76146102d6578063117048d8146102eb57610267565b3661026757005b600080fd5b34801561027857600080fd5b506102816107e8565b60408051918252519081900360200190f35b34801561029f57600080fd5b506102a86107ee565b6040805163ffffffff9092168252519081900360200190f35b3480156102cd57600080fd5b506102816107f3565b3480156102e257600080fd5b506102816107f9565b3480156102f757600080fd5b506102816107ff565b34801561030c57600080fd5b50610281610804565b34801561032157600080fd5b5061028161080a565b34801561033657600080fd5b506103546004803603602081101561034d57600080fd5b5035610810565b604080516001600160a01b039092168252519081900360200190f35b34801561037c57600080fd5b506103856107ff565b6040805160ff9092168252519081900360200190f35b3480156103a757600080fd5b50610281610837565b3480156103bc57600080fd5b5061035461083c565b3480156103d157600080fd5b50610354600480360360208110156103e857600080fd5b5035610842565b3480156103fb57600080fd5b5061040461084f565b6040805161ffff9092168252519081900360200190f35b34801561042757600080fd5b50610385610854565b34801561043c57600080fd5b50610354610859565b34801561045157600080fd5b5061028161085f565b34801561046657600080fd5b506102816004803603602081101561047d57600080fd5b50356001600160a01b0316610865565b34801561049957600080fd5b50610354610877565b3480156104ae57600080fd5b506104ed600480360360808110156104c557600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135151561087d565b604080519115158252519081900360200190f35b34801561050d57600080fd5b50610385610c21565b34801561052257600080fd5b50610354610c26565b34801561053757600080fd5b50610385610c2c565b34801561054c57600080fd5b50610281610c31565b34801561056157600080fd5b506102816004803603602081101561057857600080fd5b50356001600160a01b0316610c37565b34801561059457600080fd5b50610385610c49565b3480156105a957600080fd5b50610354610c4e565b3480156105be57600080fd5b50610354610c54565b3480156105d357600080fd5b50610281610c5a565b3480156105e857600080fd5b50610281610c60565b3480156105fd57600080fd5b50610281610c66565b34801561061257600080fd5b506104ed610c6b565b34801561062757600080fd5b506102a8610c74565b34801561063c57600080fd5b506106ff6004803603604081101561065357600080fd5b81019060208101813564010000000081111561066e57600080fd5b82018360208201111561068057600080fd5b803590602001918460018302840111640100000000831117156106a257600080fd5b9193909290916020810190356401000000008111156106c057600080fd5b8201836020820111156106d257600080fd5b803590602001918460018302840111640100000000831117156106f457600080fd5b509092509050610c79565b005b34801561070d57600080fd5b506102816004803603602081101561072457600080fd5b5035611237565b34801561073757600080fd5b506102816004803603602081101561074e57600080fd5b5035611299565b34801561076157600080fd5b506103546112b4565b34801561077657600080fd5b506103546112ba565b34801561078b57600080fd5b506102816112c0565b3480156107a057600080fd5b506106ff6112c6565b3480156107b557600080fd5b5061035461138f565b3480156107ca57600080fd5b50610385611395565b3480156107df57600080fd5b5061035461139a565b61019081565b606481565b60035481565b600b5481565b600181565b60045481565b600c5481565b6006818154811061081d57fe5b6000918252602090912001546001600160a01b0316905081565b605081565b61100181565b6008818154811061081d57fe5b606181565b600881565b61200081565b6103e881565b60076020526000908152604090205481565b61100581565b6000805460ff166108d5576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604482015290519081900360640190fd5b33612000146109155760405162461bcd60e51b815260040180806020018281038252602f815260200180611d2b602f913960400191505060405180910390fd5b6000821561099a57604080516309a99b4f60e41b8152611005600482015260248101869052905161100291639a99b4f09160448083019260209291908290030181600087803b15801561096757600080fd5b505af115801561097b573d6000803e3d6000fd5b505050506040513d602081101561099157600080fd5b50519050610a13565b604080516309a99b4f60e41b8152611005600482015260248101869052905161100491639a99b4f09160448083019260209291908290030181600087803b1580156109e457600080fd5b505af11580156109f8573d6000803e3d6000fd5b505050506040513d6020811015610a0e57600080fd5b505190505b600c805460010190556000610a27826113a0565b600954909150610a3d908263ffffffff6113cf16565b600955600a54610a65908290610a59908563ffffffff6113cf16565b9063ffffffff61143016565b600a556001600160a01b038716600090815260056020526040902054610ad157600680546001810182556000919091527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0180546001600160a01b0319166001600160a01b0389161790555b6001600160a01b038088166000908152600560209081526040808320805460010190559289168252600790522054610b4f57600880546001810182556000919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30180546001600160a01b0319166001600160a01b0388161790555b6001600160a01b038616600090815260076020526040902080546001019055600c546103e81415610c1457600b54600954600a5460408051938452602084019290925282820152517f127fd0fd1fcf84c71c5c649625ef186be105a71ecc80c7cb3f96cd99ccae1e0f9181900360600190a1610bca86611472565b610bd38661171f565b6040516110029081904780156108fc02916000818181858888f19350505050158015610c03573d6000803e3d6000fd5b5050600b805460010190556000600c555b5060019695505050505050565b600281565b61100881565b600b81565b60015481565b60056020526000908152604090205481565b600981565b61100781565b61100681565b600a5481565b60025481565b600581565b60005460ff1681565b600081565b3361100714610cb95760405162461bcd60e51b815260040180806020018281038252602e815260200180611cdc602e913960400191505060405180910390fd5b60005460ff16610cfa5760405162461bcd60e51b8152600401808060200182810382526021815260200180611d0a6021913960400191505060405180910390fd5b610d6684848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601581527436b7b632b1bab632a432b0b232b92932b630bcb2b960591b6020820152915061199f9050565b15610df15760208114610daa5760405162461bcd60e51b8152600401808060200182810382526028815260200180611c656028913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610de891858580838501838280828437600092019190915250611a8692505050565b600155506111a5565b610e6584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601881527f64656e6f6d696e61746f7248656164657252656c6179657200000000000000006020820152915061199f9050565b15610f2d5760208114610ea95760405162461bcd60e51b815260040180806020018281038252602e815260200180611c8d602e913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610ee791858580838501838280828437600092019190915250611a8692505050565b905080610f255760405162461bcd60e51b8152600401808060200182810382526030815260200180611d5a6030913960400191505060405180910390fd5b6002556111a5565b610fa184848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601a81527f6d6f6c6563756c6543616c6c6572436f6d70656e736174696f6e0000000000006020820152915061199f9050565b1561102c5760208114610fe55760405162461bcd60e51b815260040180806020018281038252602e815260200180611c8d602e913960400191505060405180910390fd5b604080516020601f840181900481028201810190925282815260009161102391858580838501838280828437600092019190915250611a8692505050565b600355506111a5565b6110a084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601d81527f64656e6f6d696e61746f7243616c6c6572436f6d70656e736174696f6e0000006020820152915061199f9050565b1561116857602081146110e45760405162461bcd60e51b815260040180806020018281038252602e815260200180611c8d602e913960400191505060405180910390fd5b604080516020601f840181900481028201810190925282815260009161112291858580838501838280828437600092019190915250611a8692505050565b9050806111605760405162461bcd60e51b8152600401808060200182810382526035815260200180611d8a6035913960400191505060405180910390fd5b6004556111a5565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b60006101908211611249575080611294565b8161019010801561125c57506103208211155b1561126a5750610190611294565b6103208211801561127d575061044c8211155b1561128e57506104b0819003611294565b50600481045b919050565b600061019082116112ab575080611294565b50610190611294565b61100281565b61100381565b60095481565b60005460ff161561131e576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b60005460ff161561136c576040805162461bcd60e51b8152602060048201526013602482015272185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604482015290519081900360640190fd5b60018080556005600255600381905560506004556000805460ff19169091179055565b61100081565b600381565b61100481565b60006113c96002546113bd60015485611a8b90919063ffffffff16565b9063ffffffff611ae416565b92915050565b600082820183811015611429576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b600061142983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611b26565b600954600680546040805160208084028201810190925282815260009360609391929091908301828280156114d057602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116114b2575b5050505050905060608151604051908082528060200260200182016040528015611504578160200160208202803683370190505b50905060005b825181101561159157600083828151811061152157fe5b60200260200101519050600061155b60056000846001600160a01b03166001600160a01b0316815260200190815260200160002054611299565b90508084848151811061156a57fe5b6020908102919091010152611585868263ffffffff6113cf16565b9550505060010161150a565b5060006115af6004546113bd60035488611a8b90919063ffffffff16565b90506115c1858263ffffffff61143016565b94508460015b84518110156116575760006115fc876113bd8a8886815181106115e657fe5b6020026020010151611a8b90919063ffffffff16565b905085828151811061160a57fe5b60200260200101516001600160a01b03166108fc829081150290604051600060405180830381858888f15061164c93508692508491505063ffffffff61143016565b9250506001016115c7565b508360008151811061166557fe5b60200260200101516001600160a01b03166108fc829081150290604051600060405180830381858888f150506040516001600160a01b038b16935085156108fc0292508591506000818181858888f1505060006009819055925050505b845181101561170957600560008683815181106116db57fe5b6020908102919091018101516001600160a01b031682528101919091526040016000908120556001016116c2565b5061171660066000611c22565b50505050505050565b600a546008805460408051602080840282018101909252828152600093606093919290919083018282801561177d57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161175f575b50505050509050606081516040519080825280602002602001820160405280156117b1578160200160208202803683370190505b50905060005b82518110156118305760008382815181106117ce57fe5b60200260200101519050600061180860076000846001600160a01b03166001600160a01b0316815260200190815260200160002054611237565b90508084848151811061181757fe5b60209081029190910101529490940193506001016117b7565b50600061184e6004546113bd60035488611a8b90919063ffffffff16565b9050611860858263ffffffff61143016565b94508460015b84518110156118e0576000611885876113bd8a8886815181106115e657fe5b905085828151811061189357fe5b60200260200101516001600160a01b03166108fc829081150290604051600060405180830381858888f1506118d593508692508491505063ffffffff61143016565b925050600101611866565b50836000815181106118ee57fe5b60200260200101516001600160a01b03166108fc829081150290604051600060405180830381858888f150506040516001600160a01b038b16935085156108fc0292508591506000818181858888f150506000600a819055925050505b8451811015611992576007600086838151811061196457fe5b6020908102919091018101516001600160a01b0316825281019190915260400160009081205560010161194b565b5061171660086000611c22565b6000816040516020018082805190602001908083835b602083106119d45780518252601f1990920191602091820191016119b5565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310611a425780518252601f199092019160209182019101611a23565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b600082611a9a575060006113c9565b82820282848281611aa757fe5b04146114295760405162461bcd60e51b8152600401808060200182810382526021815260200180611cbb6021913960400191505060405180910390fd5b600061142983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611bbd565b60008184841115611bb55760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611b7a578181015183820152602001611b62565b50505050905090810190601f168015611ba75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008183611c0c5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315611b7a578181015183820152602001611b62565b506000838581611c1857fe5b0495945050505050565b5080546000825590600052602060002090810190611c409190611c43565b50565b611c6191905b80821115611c5d5760008155600101611c49565b5090565b9056fe6c656e677468206f66206d6f6c6563756c6548656164657252656c61796572206d69736d617463686c656e677468206f6620726577617264466f7256616c696461746f725365744368616e6765206d69736d61746368536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374636f6e747261637420686173206e6f74206265656e20696e697469616c697a6564746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206e657744656e6f6d696e61746f7248656164657252656c61796572206d757374206e6f74206265207a65726f746865206e657744656e6f6d696e61746f7243616c6c6572436f6d70656e736174696f6e206d757374206e6f74206265207a65726fa26469706673582212202548a56b68ed51ad6e9a1aa43899b24ae5df4a24a9f594232fc5392c443544fb64736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001006": { - "balance": "0x0", - "code": "0x6080604052600436106101c25760003560e01c806395468d26116100f7578063c81b166211610095578063f9a2bbc711610064578063f9a2bbc714610529578063fb7cfdd71461053e578063fc3e590814610553578063fd6a687914610568576101c2565b8063c81b1662146104d5578063dc927faf146104ea578063e1c7392a146104ff578063e79a198f14610514576101c2565b8063a1a11bf5116100d1578063a1a11bf5146103c7578063a78abc16146103dc578063ab51bb96146103f1578063ac43175114610406576101c2565b806395468d261461038857806396713da91461039d5780639dc09262146103b2576101c2565b8063541d55481161016457806370fd5bad1161013e57806370fd5bad1461033457806375d47a0a146103495780637942fd051461035e5780637ae2308814610373576101c2565b8063541d5548146102b15780636a87d780146102f85780636e47b4821461031f576101c2565b806343756e5c116101a057806343756e5c1461022a578063493279b11461025b5780634bf6c8821461028757806351e806721461029c576101c2565b80630bee7a67146101c75780631aa3a008146101f55780633dffc387146101ff575b600080fd5b3480156101d357600080fd5b506101dc61057d565b6040805163ffffffff9092168252519081900360200190f35b6101fd610582565b005b34801561020b57600080fd5b50610214610733565b6040805160ff9092168252519081900360200190f35b34801561023657600080fd5b5061023f610738565b604080516001600160a01b039092168252519081900360200190f35b34801561026757600080fd5b5061027061073e565b6040805161ffff9092168252519081900360200190f35b34801561029357600080fd5b50610214610743565b3480156102a857600080fd5b5061023f610748565b3480156102bd57600080fd5b506102e4600480360360208110156102d457600080fd5b50356001600160a01b031661074e565b604080519115158252519081900360200190f35b34801561030457600080fd5b5061030d61076c565b60408051918252519081900360200190f35b34801561032b57600080fd5b5061023f610772565b34801561034057600080fd5b50610214610778565b34801561035557600080fd5b5061023f61077d565b34801561036a57600080fd5b50610214610783565b34801561037f57600080fd5b5061030d610788565b34801561039457600080fd5b5061030d610795565b3480156103a957600080fd5b506102146107a1565b3480156103be57600080fd5b5061023f6107a6565b3480156103d357600080fd5b5061023f6107ac565b3480156103e857600080fd5b506102e46107b2565b3480156103fd57600080fd5b506101dc6107bb565b34801561041257600080fd5b506101fd6004803603604081101561042957600080fd5b81019060208101813564010000000081111561044457600080fd5b82018360208201111561045657600080fd5b8035906020019184600183028401116401000000008311171561047857600080fd5b91939092909160208101903564010000000081111561049657600080fd5b8201836020820111156104a857600080fd5b803590602001918460018302840111640100000000831117156104ca57600080fd5b5090925090506107c0565b3480156104e157600080fd5b5061023f610bd6565b3480156104f657600080fd5b5061023f610bdc565b34801561050b57600080fd5b506101fd610be2565b34801561052057600080fd5b506101fd610c64565b34801561053557600080fd5b5061023f610e0b565b34801561054a57600080fd5b5061030d610e11565b34801561055f57600080fd5b50610214610e17565b34801561057457600080fd5b5061023f610e1c565b606481565b3360009081526004602052604090205460ff16156105df576040805162461bcd60e51b81526020600482015260156024820152741c995b185e595c88185b1c9958591e48195e1a5cdd605a1b604482015290519081900360640190fd5b60005460ff16610632576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b61063b33610e22565b156106775760405162461bcd60e51b8152600401808060200182810382526027815260200180610f546027913960400191505060405180910390fd5b60015434146106b75760405162461bcd60e51b8152600401808060200182810382526025815260200180610f2f6025913960400191505060405180910390fd5b604080518082018252600180548252600254602080840191825233600081815260038352868120955186559251948401949094556004815290849020805460ff1916909217909155825191825291517fdb33a09d38b59a8fa8b7d92a1d82c8015e99f05f67ae9c9ae623157767959496929181900390910190a1565b600181565b61100181565b606181565b600881565b61200081565b6001600160a01b031660009081526004602052604090205460ff1690565b60025481565b61100581565b600281565b61100881565b600b81565b68056bc75e2d6310000081565b67016345785d8a000081565b600981565b61100781565b61100681565b60005460ff1681565b600081565b60005460ff16610813576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b33611007146108535760405162461bcd60e51b815260040180806020018281038252602e815260200180610f7b602e913960400191505060405180910390fd5b6108b984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e1c995c5d5a5c995911195c1bdcda5d608a1b60208201529150610e289050565b156109b057602081146108fd5760405162461bcd60e51b8152600401808060200182810382526022815260200180610fa96022913960400191505060405180910390fd5b604080516020601f840181900481028201810190925282815260009161093b91858580838501838280828437600092019190915250610f0f92505050565b9050600181101580156109575750683635c9adc5dea000008111155b6109a8576040805162461bcd60e51b815260206004820181905260248201527f7468652072657175697265644465706f736974206f7574206f662072616e6765604482015290519081900360640190fd5b600155610b44565b610a0b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260048152636475657360e01b60208201529150610e289050565b15610b075760208114610a65576040805162461bcd60e51b815260206004820152601760248201527f6c656e677468206f662064756573206d69736d61746368000000000000000000604482015290519081900360640190fd5b604080516020601f8401819004810282018101909252828152600091610aa391858580838501838280828437600092019190915250610f0f92505050565b9050600081118015610ab6575060015481105b610aff576040805162461bcd60e51b81526020600482015260156024820152747468652064756573206f7574206f662072616e676560581b604482015290519081900360640190fd5b600255610b44565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b60005460ff1615610c3a576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b68056bc75e2d63100000600190815567016345785d8a00006002556000805460ff19169091179055565b3360009081526004602052604090205460ff16610cbf576040805162461bcd60e51b81526020600482015260146024820152731c995b185e595c88191bc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b60005460ff16610d12576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b610d1a610f14565b50336000818152600360209081526040808320815180830183528154808252600190920154938101849052915191949392900380156108fc0292909190818181858888f19350505050158015610d74573d6000803e3d6000fd5b50602081015160405161100291829181156108fc0291906000818181858888f19350505050158015610daa573d6000803e3d6000fd5b50336000818152600460209081526040808320805460ff191690556003825280832083815560010192909255815192835290517fd17202129b83db7880d6b9f25df81c58ad46f7e0e2c92236b1aa10663a4876679281900390910190a15050565b61100081565b60015481565b600381565b61100481565b3b151590565b6000816040516020018082805190602001908083835b60208310610e5d5780518252601f199092019160209182019101610e3e565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310610ecb5780518252601f199092019160209182019101610eac565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b60405180604001604052806000815260200160008152509056fe6465706f7369742076616c7565206973206e6f742065786163746c79207468652073616d65636f6e7472616374206973206e6f7420616c6c6f77656420746f20626520612072656c61796572746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662072657175697265644465706f736974206d69736d61746368a2646970667358221220fb9552ef120a66e5db5b423b7f53133dfd781b3274938e279792aad5d583b27564736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001007": { - "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b506004361061018e5760003560e01c8063831d65d1116100de578063ab51bb9611610097578063dc927faf11610071578063dc927faf14610486578063f9a2bbc71461048e578063fc3e590814610496578063fd6a68791461049e5761018e565b8063ab51bb96146103fc578063c81b166214610404578063c8509d811461040c5761018e565b8063831d65d11461034457806396713da9146103c05780639ab1a373146103c85780639dc09262146103d0578063a1a11bf5146103d8578063a78abc16146103e05761018e565b8063493279b11161014b5780636e47b482116101255780636e47b4821461032457806370fd5bad1461032c57806375d47a0a146103345780637942fd051461033c5761018e565b8063493279b1146102f55780634bf6c8821461031457806351e806721461031c5761018e565b80630bee7a67146101935780631182b875146101b45780633a21baae146102a35780633dffc387146102ab57806343756e5c146102c95780634900c4ea146102ed575b600080fd5b61019b6104a6565b6040805163ffffffff9092168252519081900360200190f35b61022e600480360360408110156101ca57600080fd5b60ff82351691908101906040810160208201356401000000008111156101ef57600080fd5b82018360208201111561020157600080fd5b8035906020019184600183028401116401000000008311171561022357600080fd5b5090925090506104ab565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610268578181015183820152602001610250565b50505050905090810190601f1680156102955780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61019b61059a565b6102b361059f565b6040805160ff9092168252519081900360200190f35b6102d16105a4565b604080516001600160a01b039092168252519081900360200190f35b6102b36105aa565b6102fd6105af565b6040805161ffff9092168252519081900360200190f35b6102b36105b4565b6102d16105b9565b6102d16105bf565b6102b36105c5565b6102d16105ca565b6102b36105d0565b6103be6004803603604081101561035a57600080fd5b60ff823516919081019060408101602082013564010000000081111561037f57600080fd5b82018360208201111561039157600080fd5b803590602001918460018302840111640100000000831117156103b357600080fd5b5090925090506105d5565b005b6102b3610627565b61019b61062c565b6102d1610631565b6102d1610637565b6103e861063d565b604080519115158252519081900360200190f35b61019b6105aa565b6102d1610646565b6103be6004803603604081101561042257600080fd5b60ff823516919081019060408101602082013564010000000081111561044757600080fd5b82018360208201111561045957600080fd5b8035906020019184600183028401116401000000008311171561047b57600080fd5b50909250905061064c565b6102d1610683565b6102d1610689565b6102b361068f565b6102d1610694565b606481565b606033612000146104ed5760405162461bcd60e51b815260040180806020018281038252602f815260200180611276602f913960400191505060405180910390fd5b6104f5611211565b600061053685858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061069a92505050565b9150915080610552576105496064610760565b92505050610593565b600061055d836107ca565b905063ffffffff811661058457505060408051600081526020810190915291506105939050565b61058d81610760565b93505050505b9392505050565b606681565b600181565b61100181565b600081565b606181565b600881565b61200081565b61100581565b600281565b61100881565b600b81565b6040805162461bcd60e51b815260206004820152601e60248201527f7265636569766520756e65787065637465642061636b207061636b6167650000604482015290519081900360640190fd5b505050565b600981565b606581565b61100781565b61100681565b60005460ff1681565b61100281565b60405162461bcd60e51b81526004018080602001828103825260238152602001806112a56023913960400191505060405180910390fd5b61100381565b61100081565b600381565b61100481565b6106a2611211565b60006106ac611211565b6106b461123b565b6106c56106c086610b6b565b610b90565b90506000805b6106d483610bda565b1561075357806106f6576106ef6106ea84610bfb565b610c49565b845261074b565b80600114156107155761070b6106ea84610bfb565b602085015261074b565b80600214156107465761072f61072a84610bfb565b610cc2565b6001600160a01b031660408501526001915061074b565b610753565b6001016106cb565b5091935090915050915091565b604080516001808252818301909252606091829190816020015b606081526020019060019003908161077a5790505090506107a08363ffffffff16610ce2565b816000815181106107ad57fe5b60200260200101819052506107c181610cf5565b9150505b919050565b60006107d98260400151610d7f565b61084557604080516020808252601c908201527f74686520746172676574206973206e6f74206120636f6e7472616374000000008183015290517f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb29181900360600190a15060656107c5565b81604001516001600160a01b031663ac431751836000015184602001516040518363ffffffff1660e01b8152600401808060200180602001838103835285818151815260200191508051906020019080838360005b838110156108b257818101518382015260200161089a565b50505050905090810190601f1680156108df5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b838110156109125781810151838201526020016108fa565b50505050905090810190601f16801561093f5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561096057600080fd5b505af1925050508015610971575060015b610b63576040516000815260443d101561098d57506000610a2a565b60046000803e60005160e01c6308c379a081146109ae576000915050610a2a565b60043d036004833e81513d602482011167ffffffffffffffff821117156109da57600092505050610a2a565b808301805167ffffffffffffffff8111156109fc576000945050505050610a2a565b8060208301013d8601811115610a1a57600095505050505050610a2a565b601f01601f191660405250925050505b80610a355750610ad8565b7f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2816040518080602001828103825283818151815260200191508051906020019080838360005b83811015610a94578181015183820152602001610a7c565b50505050905090810190601f168015610ac15780820380516001836020036101000a031916815260200191505b509250505060405180910390a160669150506107c5565b3d808015610b02576040519150601f19603f3d011682016040523d82523d6000602084013e610b07565b606091505b5060408051602080825283518183015283517f1279f84165b4fd69c35e1f338ff107231b036c655cd1688851e011ce617c4e8d938593928392918301919085019080838360008315610a94578181015183820152602001610a7c565b506000919050565b610b7361125b565b506040805180820190915281518152602082810190820152919050565b610b9861123b565b610ba182610d85565b610baa57600080fd5b6000610bb98360200151610dbf565b60208085015160408051808201909152868152920190820152915050919050565b6000610be461125b565b505080518051602091820151919092015191011190565b610c0361125b565b610c0c82610bda565b610c1557600080fd5b60208201516000610c2582610e22565b80830160209586015260408051808201909152908152938401919091525090919050565b8051606090610c5757600080fd5b6000610c668360200151610dbf565b83516040805191839003808352601f19601f8201168301602001909152919250606090828015610c9d576020820181803683370190505b5090506000816020019050610cb9848760200151018285610ebb565b50949350505050565b8051600090601514610cd357600080fd5b610cdc82610f06565b92915050565b6060610cdc610cf083610f64565b61104a565b6060815160001415610d1657506040805160008152602081019091526107c5565b606082600081518110610d2557fe5b602002602001015190506000600190505b8351811015610d6657610d5c82858381518110610d4f57fe5b602002602001015161109c565b9150600101610d36565b506107c1610d79825160c060ff16611119565b8261109c565b3b151590565b8051600090610d96575060006107c5565b6020820151805160001a9060c0821015610db5576000925050506107c5565b5060019392505050565b8051600090811a6080811015610dd95760009150506107c5565b60b8811080610df4575060c08110801590610df4575060f881105b15610e035760019150506107c5565b60c0811015610e175760b5190190506107c5565b60f5190190506107c5565b80516000908190811a6080811015610e3d5760019150610eb4565b60b8811015610e5257607e1981019150610eb4565b60c0811015610e7f5760b78103600185019450806020036101000a85510460018201810193505050610eb4565b60f8811015610e945760be1981019150610eb4565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b80610ec557610622565b5b60208110610ee5578251825260209283019290910190601f1901610ec6565b915181516020939093036101000a6000190180199091169216919091179052565b805160009015801590610f1b57508151602110155b610f2457600080fd5b6000610f338360200151610dbf565b83516020808601518301805193945091849003929190831015610cb957506020919091036101000a90049392505050565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416610fa857506018610fcc565b6fffffffffffffffffffffffffffffffff198416610fc857506010610fcc565b5060005b602081101561100257818181518110610fe157fe5b01602001516001600160f81b03191615610ffa57611002565b600101610fcc565b60008160200390506060816040519080825280601f01601f191660200182016040528015611037576020820181803683370190505b5080830196909652508452509192915050565b60608151600114801561107c5750607f60f81b8260008151811061106a57fe5b01602001516001600160f81b03191611155b156110885750806107c5565b610cdc61109a8351608060ff16611119565b835b6060806040519050835180825260208201818101602087015b818310156110cd5780518352602092830192016110b5565b50855184518101855292509050808201602086015b818310156110fa5780518352602092830192016110e2565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310611169576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b604080516001808252818301909252606091602082018180368337019050509050603784116111c35782840160f81b816000815181106111a557fe5b60200101906001600160f81b031916908160001a9053509050610cdc565b60606111ce85610f64565b90508381510160370160f81b826000815181106111e757fe5b60200101906001600160f81b031916908160001a905350611208828261109c565b95945050505050565b6040518060600160405280606081526020016060815260200160006001600160a01b031681525090565b604051806040016040528061124e61125b565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e74726163747265636569766520756e6578706563746564206661696c2061636b207061636b616765a264697066735822122019628d70dd9ac62a7a85eb3f845d01808a095ab280a95e6dd5609e52788b4c5e64736f6c63430006040033" - }, - "0x0000000000000000000000000000000000001008": { - "balance": "0x0", - "code": "0x6080604052600436106102305760003560e01c806377d9dae81161012e578063c81b1662116100ab578063dc927faf1161006f578063dc927faf14610887578063f9a2bbc71461089c578063fc3e5908146107f1578063fd6a6879146108b1578063fe3a2af51461042457610230565b8063c81b1662146107dc578063c8509d81146106d7578063c8e704a4146107f1578063d117a11014610806578063dc6f5e90146107f157610230565b806396713da9116100f257806396713da9146107735780639dc0926214610788578063a1a11bf51461079d578063a78abc16146107b2578063ab51bb96146107c757610230565b806377d9dae81461060e5780637942fd05146106c25780637d078e13146103b2578063831d65d1146106d757806395b9ad261461075e57610230565b80634a688818116101bc5780636b3f1307116101805780636b3f1307146104785780636e47b4821461054057806370fd5bad1461046357806372c4e0861461055557806375d47a0a146105f957610230565b80634a688818146104245780634bc81c00146104395780634bf6c8821461023557806351e806721461044e5780635f558f861461046357610230565b80631f91600b116102035780631f91600b1461039d57806323996b53146103b25780633dffc387146103b257806343756e5c146103c7578063493279b1146103f857610230565b8063077b8f35146102355780630bee7a67146102605780630f212b1b1461028e5780631182b875146102a3575b600080fd5b34801561024157600080fd5b5061024a6108c6565b6040805160ff9092168252519081900360200190f35b34801561026c57600080fd5b506102756108cb565b6040805163ffffffff9092168252519081900360200190f35b34801561029a57600080fd5b5061024a6108d0565b3480156102af57600080fd5b50610328600480360360408110156102c657600080fd5b60ff8235169190810190604081016020820135600160201b8111156102ea57600080fd5b8201836020820111156102fc57600080fd5b803590602001918460018302840111600160201b8311171561031d57600080fd5b5090925090506108d5565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561036257818101518382015260200161034a565b50505050905090810190601f16801561038f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103a957600080fd5b5061024a61095e565b3480156103be57600080fd5b5061024a610963565b3480156103d357600080fd5b506103dc610968565b604080516001600160a01b039092168252519081900360200190f35b34801561040457600080fd5b5061040d61096e565b6040805161ffff9092168252519081900360200190f35b34801561043057600080fd5b5061024a610973565b34801561044557600080fd5b5061024a610978565b34801561045a57600080fd5b506103dc61097d565b34801561046f57600080fd5b5061024a610983565b61052c6004803603604081101561048e57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b8111156104b857600080fd5b8201836020820111156104ca57600080fd5b803590602001918460018302840111600160201b831117156104eb57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610988945050505050565b604080519115158252519081900360200190f35b34801561054c57600080fd5b506103dc61121e565b61052c6004803603602081101561056b57600080fd5b810190602081018135600160201b81111561058557600080fd5b82018360208201111561059757600080fd5b803590602001918460018302840111600160201b831117156105b857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611224945050505050565b34801561060557600080fd5b506103dc611683565b61052c6004803603604081101561062457600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561064e57600080fd5b82018360208201111561066057600080fd5b803590602001918460018302840111600160201b8311171561068157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611689945050505050565b3480156106ce57600080fd5b5061024a611ba0565b3480156106e357600080fd5b5061075c600480360360408110156106fa57600080fd5b60ff8235169190810190604081016020820135600160201b81111561071e57600080fd5b82018360208201111561073057600080fd5b803590602001918460018302840111600160201b8311171561075157600080fd5b509092509050611ba5565b005b34801561076a57600080fd5b5061024a611c58565b34801561077f57600080fd5b5061024a611c5d565b34801561079457600080fd5b506103dc611c62565b3480156107a957600080fd5b506103dc611c68565b3480156107be57600080fd5b5061052c611c6e565b3480156107d357600080fd5b50610275610973565b3480156107e857600080fd5b506103dc611c77565b3480156107fd57600080fd5b5061024a611c7d565b34801561081257600080fd5b506108306004803603602081101561082957600080fd5b5035611c82565b6040805160ff988916815260208101979097526001600160a01b03909516868601526060860193909352608085019190915290931660a083015267ffffffffffffffff90921660c082015290519081900360e00190f35b34801561089357600080fd5b506103dc611cda565b3480156108a857600080fd5b506103dc611ce0565b3480156108bd57600080fd5b506103dc611ce6565b600881565b606481565b600681565b606033612000146109175760405162461bcd60e51b815260040180806020018281038252602f815260200180612f8e602f913960400191505060405180910390fd5b61095683838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611cec92505050565b949350505050565b600481565b600181565b61100181565b606181565b600081565b600581565b61200081565b600281565b60008061099483611f7d565b905061099e612e56565b50600081815260016020818152604092839020835160e081018552815460ff90811682529382015492810183905260028201546001600160a01b03169481019490945260038101546060850152600481015460808501526005015491821660a084015261010090910467ffffffffffffffff1660c0830152610a64576040805162461bcd60e51b815260206004820152601a602482015279189a5b99081c995c5d595cdd08191bd95cdb89dd08195e1a5cdd60321b604482015290519081900360640190fd5b6000610a8182608001518360600151611f8490919063ffffffff16565b905081604001516001600160a01b0316866001600160a01b031614610ad75760405162461bcd60e51b8152600401808060200182810382526045815260200180612f1b6045913960600191505060405180910390fd5b336001600160a01b0316866001600160a01b031663893d20e86040518163ffffffff1660e01b815260040160206040518083038186803b158015610b1a57600080fd5b505afa158015610b2e573d6000803e3d6000fd5b505050506040513d6020811015610b4457600080fd5b50516001600160a01b031614610b8b5760405162461bcd60e51b815260040180806020018281038252602e815260200180612f60602e913960400191505060405180910390fd5b604080516370a0823160e01b8152611004600482015290516000916001600160a01b038916916370a0823191602480820192602092909190829003018186803b158015610bd757600080fd5b505afa158015610beb573d6000803e3d6000fd5b505050506040513d6020811015610c0157600080fd5b505160408051636eb1769f60e11b815233600482015230602482015290519192508391610c929184916001600160a01b038c169163dd62ed3e916044808301926020929190829003018186803b158015610c5a57600080fd5b505afa158015610c6e573d6000803e3d6000fd5b505050506040513d6020811015610c8457600080fd5b50519063ffffffff611fcd16565b1015610ce5576040805162461bcd60e51b815260206004820152601760248201527f616c6c6f77616e6365206973206e6f7420656e6f756768000000000000000000604482015290519081900360640190fd5b600034905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b158015610d2757600080fd5b505afa158015610d3b573d6000803e3d6000fd5b505050506040513d6020811015610d5157600080fd5b50519050808210801590610d6a57506402540be4008206155b610da55760405162461bcd60e51b8152600401808060200182810382526037815260200180612ee46037913960400191505060405180910390fd5b6000610db1868b612027565b905063ffffffff8116610fb0576001600160a01b038a166323b872dd33611004610de1898963ffffffff611f8416565b6040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050602060405180830381600087803b158015610e4957600080fd5b505af1158015610e5d573d6000803e3d6000fd5b505050506040513d6020811015610e7357600080fd5b5050602086015160408088015160a089015182516323bfccdb60e21b815260048101949094526001600160a01b03909116602484015260ff1660448301525161100491638eff336c91606480830192600092919082900301818387803b158015610edc57600080fd5b505af1158015610ef0573d6000803e3d6000fd5b50505050896001600160a01b03167f78e7dd9aefcdbf795c4936a66f7dc6d41bb56637b54f561a6bf7829dca3348a88a8860600151886040518080602001848152602001838152602001828103825285818151815260200191508051906020019080838360005b83811015610f6f578181015183820152602001610f57565b50505050905090810190601f168015610f9c5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a2611068565b896001600160a01b03167f831c0ef4d93bda3bce08b69ae3f29ef1a6e052b833200988554158494405a1078a8360405180806020018363ffffffff1663ffffffff168152602001828103825284818151815260200191508051906020019080838360005b8381101561102c578181015183820152602001611014565b50505050905090810190601f1680156110595780820380516001836020036101000a031916815260200191505b50935050505060405180910390a25b60008781526001602081905260408220805460ff191681559081018290556002810180546001600160a01b0319169055600381018290556004810191909155600501805468ffffffffffffffffff191690556110c2612e92565b5060408051808201825263ffffffff831681526020810189905290516110049085156108fc029086906000818181858888f1935050505015801561110a573d6000803e3d6000fd5b5061200063f7a251d7600161111e8461247e565b611133886402540be40063ffffffff61250816565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611191578181015183820152602001611179565b50505050905090810190601f1680156111be5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b1580156111df57600080fd5b505af11580156111f3573d6000803e3d6000fd5b505050506040513d602081101561120957600080fd5b50600199505050505050505050505b92915050565b61100581565b60008061123083611f7d565b905061123a612e56565b50600081815260016020818152604092839020835160e081018552815460ff90811682529382015492810183905260028201546001600160a01b03169481019490945260038101546060850152600481015460808501526005015491821660a084015261010090910467ffffffffffffffff1660c0830152611300576040805162461bcd60e51b815260206004820152601a602482015279189a5b99081c995c5d595cdd08191bd95cdb89dd08195e1a5cdd60321b604482015290519081900360640190fd5b428160c0015167ffffffffffffffff1610611362576040805162461bcd60e51b815260206004820152601b60248201527f62696e642072657175657374206973206e6f7420657870697265640000000000604482015290519081900360640190fd5b600034905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b1580156113a457600080fd5b505afa1580156113b8573d6000803e3d6000fd5b505050506040513d60208110156113ce57600080fd5b505190508082108015906113e757506402540be4008206155b6114225760405162461bcd60e51b8152600401808060200182810382526037815260200180612ee46037913960400191505060405180910390fd5b60008481526001602081905260408220805460ff191681559081018290556002810180546001600160a01b0319169055600381018290556004810191909155600501805468ffffffffffffffffff1916905561147c612e92565b50604080518082018252600181526020810186905290516110049084156108fc029085906000818181858888f193505050501580156114bf573d6000803e3d6000fd5b5061200063f7a251d760016114d38461247e565b6114e8876402540be40063ffffffff61250816565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561154657818101518382015260200161152e565b50505050905090810190601f1680156115735780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b15801561159457600080fd5b505af11580156115a8573d6000803e3d6000fd5b505050506040513d60208110156115be57600080fd5b50506040808501518151600160208281018290528483528b51948301949094528a516001600160a01b03909316937f831c0ef4d93bda3bce08b69ae3f29ef1a6e052b833200988554158494405a107938c93918291606083019186019080838360005b83811015611639578181015183820152602001611621565b50505050905090810190601f1680156116665780820380516001836020036101000a031916815260200191505b50935050505060405180910390a26001955050505050505b919050565b61100881565b60008061169583611f7d565b905061169f612e56565b50600081815260016020818152604092839020835160e081018552815460ff90811682529382015492810183905260028201546001600160a01b03169481019490945260038101546060850152600481015460808501526005015491821660a084015261010090910467ffffffffffffffff1660c0830152611765576040805162461bcd60e51b815260206004820152601a602482015279189a5b99081c995c5d595cdd08191bd95cdb89dd08195e1a5cdd60321b604482015290519081900360640190fd5b80604001516001600160a01b0316856001600160a01b0316146117b95760405162461bcd60e51b8152600401808060200182810382526045815260200180612f1b6045913960600191505060405180910390fd5b336001600160a01b0316856001600160a01b031663893d20e86040518163ffffffff1660e01b815260040160206040518083038186803b1580156117fc57600080fd5b505afa158015611810573d6000803e3d6000fd5b505050506040513d602081101561182657600080fd5b50516001600160a01b031614611883576040805162461bcd60e51b815260206004820152601b60248201527f6f6e6c79206265703265206f776e65722063616e2072656a6563740000000000604482015290519081900360640190fd5b600034905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b1580156118c557600080fd5b505afa1580156118d9573d6000803e3d6000fd5b505050506040513d60208110156118ef57600080fd5b5051905080821080159061190857506402540be4008206155b6119435760405162461bcd60e51b8152600401808060200182810382526037815260200180612ee46037913960400191505060405180910390fd5b60008481526001602081905260408220805460ff191681559081018290556002810180546001600160a01b0319169055600381018290556004810191909155600501805468ffffffffffffffffff1916905561199d612e92565b50604080518082018252600781526020810186905290516110049084156108fc029085906000818181858888f193505050501580156119e0573d6000803e3d6000fd5b5061200063f7a251d760016119f48461247e565b611a09876402540be40063ffffffff61250816565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611a67578181015183820152602001611a4f565b50505050905090810190601f168015611a945780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b158015611ab557600080fd5b505af1158015611ac9573d6000803e3d6000fd5b505050506040513d6020811015611adf57600080fd5b505060408051600760208281018290528383528a519383019390935289516001600160a01b038c16937f831c0ef4d93bda3bce08b69ae3f29ef1a6e052b833200988554158494405a107938c939290918291606083019186019080838360005b83811015611b57578181015183820152602001611b3f565b50505050905090810190601f168015611b845780820380516001836020036101000a031916815260200191505b50935050505060405180910390a2506001979650505050505050565b600b81565b3361200014611be55760405162461bcd60e51b815260040180806020018281038252602f815260200180612f8e602f913960400191505060405180910390fd5b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a1505050565b600781565b600981565b61100781565b61100681565b60005460ff1681565b61100281565b600381565b600160208190526000918252604090912080549181015460028201546003830154600484015460059094015460ff9586169593946001600160a01b0390931693919291811690610100900467ffffffffffffffff1687565b61100381565b61100081565b61100481565b6060611cf6612e56565b6000611d018461254a565b9150915080611d57576040805162461bcd60e51b815260206004820152601f60248201527f756e7265636f676e697a6564207472616e73666572496e207061636b61676500604482015290519081900360640190fd5b815160ff16611e0b576020828101805160009081526001928390526040908190208551815460ff1990811660ff928316178355935194820194909455908501516002820180546001600160a01b0319166001600160a01b03909216919091179055606085015160038201556080850151600482015560a08501516005909101805460c08701519316919093161768ffffffffffffffff00191661010067ffffffffffffffff90921691909102179055611f62565b815160ff1660011415611f155760006110046001600160a01b03166359b9278984602001516040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611e6457600080fd5b505afa158015611e78573d6000803e3d6000fd5b505050506040513d6020811015611e8e57600080fd5b505190506001600160a01b03811615611f0f5760208301516040805163b99328c560e01b815260048101929092526001600160a01b0383166024830152516110049163b99328c591604480830192600092919082900301818387803b158015611ef657600080fd5b505af1158015611f0a573d6000803e3d6000fd5b505050505b50611f62565b6040805162461bcd60e51b815260206004820152601960248201527f756e7265636f676e697a65642062696e64207061636b61676500000000000000604482015290519081900360640190fd5b60408051600080825260208201909252905b50949350505050565b6020015190565b6000611fc683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061269c565b9392505050565b600082820183811015611fc6576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600080826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561206357600080fd5b505afa158015612077573d6000803e3d6000fd5b505050506040513d602081101561208d57600080fd5b5051604080516395d89b4160e01b815290519192506060916001600160a01b038616916395d89b41916004808301926000929190829003018186803b1580156120d557600080fd5b505afa1580156120e9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561211257600080fd5b8101908080516040519392919084600160201b82111561213157600080fd5b90830190602082018581111561214657600080fd5b8251600160201b81118282018810171561215f57600080fd5b82525081516020918201929091019080838360005b8381101561218c578181015183820152602001612174565b50505050905090810190601f1680156121b95780820380516001836020036101000a031916815260200191505b5060408181526370a0823160e01b82526110046004830152519495506000946001600160a01b038a1694506370a08231935060248083019350602092829003018186803b15801561220957600080fd5b505afa15801561221d573d6000803e3d6000fd5b505050506040513d602081101561223357600080fd5b5051608087015160608801519192506000916122549163ffffffff611f8416565b9050428760c0015167ffffffffffffffff16101561227a57506001935061121892505050565b612288838860200151612733565b61229a57506002935061121892505050565b808211156122b057506003935061121892505050565b866060015187604001516001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156122f257600080fd5b505afa158015612306573d6000803e3d6000fd5b505050506040513d602081101561231c57600080fd5b50511461233157506004935061121892505050565b8660a0015160ff16841461234d57506005935061121892505050565b602080880151604080516359b9278960e01b8152600481019290925251600092611004926359b927899260248083019392829003018186803b15801561239257600080fd5b505afa1580156123a6573d6000803e3d6000fd5b505050506040513d60208110156123bc57600080fd5b50516001600160a01b031614158061245e57506000801b6110046001600160a01b031663bd46646189604001516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561242f57600080fd5b505afa158015612443573d6000803e3d6000fd5b505050506040513d602081101561245957600080fd5b505114155b1561247157506006935061121892505050565b5060009695505050505050565b6040805160028082526060828101909352829190816020015b606081526020019060019003908161249757505083519091506124bf9063ffffffff1661281b565b816000815181106124cc57fe5b60200260200101819052506124e7836020015160001c61281b565b816001815181106124f457fe5b6020026020010181905250611fc68161282e565b6000611fc683836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506128b8565b612552612e56565b600061255c612e56565b612564612ea9565b6125756125708661291d565b612942565b90506000805b6125848361298c565b1561268f57806125a95761259f61259a846129ad565b6129fb565b60ff168452612687565b80600114156125c8576125be61259a846129ad565b6020850152612687565b80600214156125f5576125e26125dd846129ad565b612a59565b6001600160a01b03166040850152612687565b80600314156126145761260a61259a846129ad565b6060850152612687565b80600414156126335761262961259a846129ad565b6080850152612687565b80600514156126555761264861259a846129ad565b60ff1660a0850152612687565b80600614156126825761266a61259a846129ad565b67ffffffffffffffff1660c085015260019150612687565b61268f565b60010161257b565b5091935090915050915091565b6000818484111561272b5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156126f05781810151838201526020016126d8565b50505050905090810190601f16801561271d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b8151600090839060081080612749575080516003115b15612758576000915050611218565b6040805160208082528183019092526060916020820181803683370190505090508360208201528082518151811061278c57fe5b6020910101516001600160f81b031916602d60f81b146127b157600092505050611218565b600160005b8351811015612811578281815181106127cb57fe5b602001015160f81c60f81b6001600160f81b0319168482815181106127ec57fe5b01602001516001600160f81b031916146128095760009150612811565b6001016127b6565b5095945050505050565b606061121861282983612a73565b612b59565b606081516000141561284f575060408051600081526020810190915261167e565b60608260008151811061285e57fe5b602002602001015190506000600190505b835181101561289f576128958285838151811061288857fe5b6020026020010151612bab565b915060010161286f565b50611fc66128b2825160c060ff16612c28565b82612bab565b600081836129075760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156126f05781810151838201526020016126d8565b50600083858161291357fe5b0495945050505050565b612925612ec9565b506040805180820190915281518152602082810190820152919050565b61294a612ea9565b61295382612d20565b61295c57600080fd5b600061296b8360200151612d5a565b60208085015160408051808201909152868152920190820152915050919050565b6000612996612ec9565b505080518051602091820151919092015191011190565b6129b5612ec9565b6129be8261298c565b6129c757600080fd5b602082015160006129d782612dbd565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590612a1057508151602110155b612a1957600080fd5b6000612a288360200151612d5a565b83516020808601518301805193945091849003929190831015611f7457506020919091036101000a90049392505050565b8051600090601514612a6a57600080fd5b611218826129fb565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416612ab757506018612adb565b6fffffffffffffffffffffffffffffffff198416612ad757506010612adb565b5060005b6020811015612b1157818181518110612af057fe5b01602001516001600160f81b03191615612b0957612b11565b600101612adb565b60008160200390506060816040519080825280601f01601f191660200182016040528015612b46576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015612b8b5750607f60f81b82600081518110612b7957fe5b01602001516001600160f81b03191611155b15612b9757508061167e565b611218612ba98351608060ff16612c28565b835b6060806040519050835180825260208201818101602087015b81831015612bdc578051835260209283019201612bc4565b50855184518101855292509050808201602086015b81831015612c09578051835260209283019201612bf1565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310612c78576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411612cd25782840160f81b81600081518110612cb457fe5b60200101906001600160f81b031916908160001a9053509050611218565b6060612cdd85612a73565b90508381510160370160f81b82600081518110612cf657fe5b60200101906001600160f81b031916908160001a905350612d178282612bab565b95945050505050565b8051600090612d315750600061167e565b6020820151805160001a9060c0821015612d505760009250505061167e565b5060019392505050565b8051600090811a6080811015612d7457600091505061167e565b60b8811080612d8f575060c08110801590612d8f575060f881105b15612d9e57600191505061167e565b60c0811015612db25760b51901905061167e565b60f51901905061167e565b80516000908190811a6080811015612dd85760019150612e4f565b60b8811015612ded57607e1981019150612e4f565b60c0811015612e1a5760b78103600185019450806020036101000a85510460018201810193505050612e4f565b60f8811015612e2f5760be1981019150612e4f565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915290565b604080518082019091526000808252602082015290565b6040518060400160405280612ebc612ec9565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe72656c6179466565206d757374206265204e202a203165313020616e642067726561746572207468616e206d696e6952656c6179466565636f6e74616374206164647265737320646f65736e277420657175616c20746f2074686520636f6e7472616374206164647265737320696e2062696e6420726571756573746f6e6c79206265703265206f776e65722063616e20617070726f766520746869732062696e642072657175657374746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374a26469706673582212208d24722e295c34fcc944dfda2183ee07fab7234ce8b7001a715c221bd92ef86e64736f6c63430006040033" - }, - "0x0000000000000000000000000000000000002000": { - "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b50600436106102485760003560e01c8063863fe4ab1161013b578063c81b1662116100b8578063e3b048051161007c578063e3b048051461072c578063f7a251d71461074c578063f9a2bbc7146107c4578063fc3e5908146107cc578063fd6a6879146107d457610248565b8063c81b1662146106dd578063d31f968d146106e5578063d76a867514610714578063dc927faf1461071c578063e1c7392a1461072457610248565b8063a78abc16116100ff578063a78abc16146105d3578063ab51bb96146105db578063ac431751146105e3578063b0355f5b146103ff578063c27cdcfb146106a157610248565b8063863fe4ab146105b35780638cc8f561146104b657806396713da9146105bb5780639dc09262146105c3578063a1a11bf5146105cb57610248565b8063493279b1116101c957806370fd5bad1161018d57806370fd5bad146104b657806374f079b8146104be57806375d47a0a146104c65780637942fd05146104ce57806384013b6a146104d657610248565b8063493279b11461045f5780634bf6c8821461047e57806351e80672146104865780636e47a51a1461048e5780636e47b482146104ae57610248565b8063308325f411610210578063308325f4146102cf5780633bdc47a6146102d75780633dffc387146103ff578063422f90501461040757806343756e5c1461043b57610248565b806305e682581461024d5780630bee7a671461026b57806314b3023b1461028c57806322556cdc146102a65780632ff32aea146102ae575b600080fd5b6102556107dc565b6040805160ff9092168252519081900360200190f35b6102736107e1565b6040805163ffffffff9092168252519081900360200190f35b6102946107e6565b60408051918252519081900360200190f35b6102946107ec565b6102b66107f1565b60408051600792830b90920b8252519081900360200190f35b6102946107fa565b61038a600480360360608110156102ed57600080fd5b60ff82351691602081013591810190606081016040820135600160201b81111561031657600080fd5b82018360208201111561032857600080fd5b803590602001918460018302840111600160201b8311171561034957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610800945050505050565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103c45781810151838201526020016103ac565b50505050905090810190601f1680156103f15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610255610876565b6104276004803603602081101561041d57600080fd5b503560ff1661087b565b604080519115158252519081900360200190f35b610443610890565b604080516001600160a01b039092168252519081900360200190f35b610467610896565b6040805161ffff9092168252519081900360200190f35b61025561089b565b6104436108a0565b610443600480360360208110156104a457600080fd5b503560ff166108a6565b6104436108c1565b6102556108c7565b6102946108cc565b6104436108d2565b6102556108d8565b6105b1600480360360a08110156104ec57600080fd5b810190602081018135600160201b81111561050657600080fd5b82018360208201111561051857600080fd5b803590602001918460018302840111600160201b8311171561053957600080fd5b919390929091602081019035600160201b81111561055657600080fd5b82018360208201111561056857600080fd5b803590602001918460018302840111600160201b8311171561058957600080fd5b919350915080356001600160401b03908116916020810135909116906040013560ff166108dd565b005b610294611a8d565b610255611a95565b610443611a9a565b610443611aa0565b610427611aa6565b6102736107dc565b6105b1600480360360408110156105f957600080fd5b810190602081018135600160201b81111561061357600080fd5b82018360208201111561062557600080fd5b803590602001918460018302840111600160201b8311171561064657600080fd5b919390929091602081019035600160201b81111561066357600080fd5b82018360208201111561067557600080fd5b803590602001918460018302840111600160201b8311171561069657600080fd5b509092509050611aaf565b6106c1600480360360208110156106b757600080fd5b503560ff16612046565b604080516001600160401b039092168252519081900360200190f35b610443612061565b610427600480360360408110156106fb57600080fd5b5080356001600160a01b0316906020013560ff16612067565b61038a612087565b6104436120a6565b6105b16120ac565b6106c16004803603602081101561074257600080fd5b503560ff16612463565b6104276004803603606081101561076257600080fd5b60ff8235169190810190604081016020820135600160201b81111561078657600080fd5b82018360208201111561079857600080fd5b803590602001918460018302840111600160201b831117156107b957600080fd5b91935091503561247e565b6104436125d0565b6102556125d6565b6104436125db565b600081565b606481565b60015481565b603281565b60045460070b81565b60025481565b60606000825160210190506060816040519080825280601f01601f191660200182016040528015610838576020820181803683370190505b506021810186905260018101879052828152905060418101600061085b866125e1565b50905061086a818388516125eb565b50909695505050505050565b600181565b60096020526000908152604090205460ff1681565b61100181565b606181565b600881565b61200081565b6005602052600090815260409020546001600160a01b031681565b61100581565b600281565b60035481565b61100881565b600b81565b60005460ff16610930576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b60408051630a83aaa960e31b815233600482015290516110069163541d5548916024808301926020929190829003018186803b15801561096f57600080fd5b505afa158015610983573d6000803e3d6000fd5b505050506040513d602081101561099957600080fd5b50516109ec576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b60ff8116600090815260086020526040902054829082906001600160401b039081169083168114610a5c576040805162461bcd60e51b815260206004820152601560248201527439b2b8bab2b731b2903737ba1034b71037b93232b960591b604482015290519081900360640190fd5b60ff8216600090815260086020908152604091829020805467ffffffffffffffff1916600185016001600160401b039081169190911790915582516337d7f9c160e21b81529089166004820152915188926110039263df5fe70492602480840193829003018186803b158015610ad157600080fd5b505afa158015610ae5573d6000803e3d6000fd5b505050506040513d6020811015610afb57600080fd5b5051610b385760405162461bcd60e51b8152600401808060200182810382526023815260200180612b686023913960400191505060405180910390fd5b60ff851660009081526005602052604090205485906001600160a01b0316610ba7576040805162461bcd60e51b815260206004820152601860248201527f6368616e6e656c206973206e6f7420737570706f727465640000000000000000604482015290519081900360640190fd5b60608c8c8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805163cba510a960e01b81526001600160401b038f1660048201529051939450610cce93611003935063cba510a992506024808301926020929190829003018186803b158015610c7757600080fd5b505afa158015610c8b573d6000803e3d6000fd5b505050506040513d6020811015610ca157600080fd5b505160408051808201909152600381526269626360e81b6020820152610cc78c8c61262c565b8585612673565b610d16576040805162461bcd60e51b815260206004820152601460248201527334b73b30b634b21036b2b935b63290383937b7b360611b604482015290519081900360640190fd5b60408051631bb5062960e31b81526001600160401b038c16600482015290516000916110039163dda8314891602480820192602092909190829003018186803b158015610d6257600080fd5b505afa158015610d76573d6000803e3d6000fd5b505050506040513d6020811015610d8c57600080fd5b5051905088600080806060610da088612770565b935093509350935083610e61578460ff168f6001600160401b03167ff7b2e42d694eb1100184aae86d4245d9e46966100b1dc7e723275b98326854ac8a6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610e1a578181015183820152602001610e02565b50505050905090810190601f168015610e475780820380516001836020036101000a031916815260200191505b509250505060405180910390a35050505050505050611a7f565b8460ff168f6001600160401b03167f36afdaf439a8f43fe72135135d804ae620b37a474f0943b5b85f6788312cad4085604051808260ff1660ff16815260200191505060405180910390a360ff83166113ea5760ff85166000818152600560209081526040808320548151631182b87560e01b815260048101958652602481019283528651604482015286516001600160a01b03909216958695631182b875958d958a9593949093606490910192918601918190849084905b83811015610f32578181015183820152602001610f1a565b50505050905090810190601f168015610f5f5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015610f7f57600080fd5b505af192505050801561106357506040513d6000823e601f3d908101601f191682016040526020811015610fb257600080fd5b8101908080516040519392919084600160201b821115610fd157600080fd5b908301906020820185811115610fe657600080fd5b8251600160201b811182820188101715610fff57600080fd5b82525081516020918201929091019080838360005b8381101561102c578181015183820152602001611014565b50505050905090810190601f1680156110595780820380516001836020036101000a031916815260200191505b5060405250505060015b611375576040516000815260443d101561107f5750600061111a565b60046000803e60005160e01c6308c379a081146110a057600091505061111a565b60043d036004833e81513d60248201116001600160401b03821117156110cb5760009250505061111a565b80830180516001600160401b038111156110ec57600094505050505061111a565b8060208301013d860181111561110a5760009550505050505061111a565b601f01601f191660405250925050505b806111255750611237565b60ff871660009081526007602052604081205461115c916001600160401b039091169089906111579060029088610800565b612820565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf948794849390840192918601918190849084905b838110156111f75781810151838201526020016111df565b50505050905090810190601f1680156112245780820380516001836020036101000a031916815260200191505b509250505060405180910390a250611370565b3d808015611261576040519150601f19603f3d011682016040523d82523d6000602084013e611266565b606091505b5060ff8716600090815260076020526040812054611299916001600160401b039091169089906111579060029088610800565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351948794849390840192918601918190849084905b8381101561133457818101518382015260200161131c565b50505050905090810190601f1680156113615780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b6113e4565b8051156113e25760ff87166000908152600760205260408120546113ae916001600160401b039091169089906111579060019086610800565b60ff8716600090815260076020526040902080546001600160401b038082166001011667ffffffffffffffff199091161790555b505b506119b8565b60ff83166001141561168e5760ff8516600081815260056020908152604080832054815163831d65d160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563831d65d1958d958a9593949093606490910192918601918190849084905b8381101561147457818101518382015260200161145c565b50505050905090810190601f1680156114a15780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156114c157600080fd5b505af19250505080156114d2575060015b6113e4576040516000815260443d10156114ee57506000611589565b60046000803e60005160e01c6308c379a0811461150f576000915050611589565b60043d036004833e81513d60248201116001600160401b038211171561153a57600092505050611589565b80830180516001600160401b0381111561155b576000945050505050611589565b8060208301013d860181111561157957600095505050505050611589565b601f01601f191660405250925050505b8061159457506115f9565b60408051602080825283518183015283516001600160a01b038616937ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf93869390928392830191850190808383600083156111f75781810151838201526020016111df565b3d808015611623576040519150601f19603f3d011682016040523d82523d6000602084013e611628565b606091505b5060408051602080825283518183015283516001600160a01b038616937f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351938693909283928301918501908083836000831561133457818101518382015260200161131c565b60ff8316600214156119b85760ff8516600081815260056020908152604080832054815163c8509d8160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563c8509d81958d958a9593949093606490910192918601918190849084905b83811015611718578181015183820152602001611700565b50505050905090810190601f1680156117455780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561176557600080fd5b505af1925050508015611776575060015b6119b6576040516000815260443d10156117925750600061182d565b60046000803e60005160e01c6308c379a081146117b357600091505061182d565b60043d036004833e81513d60248201116001600160401b03821117156117de5760009250505061182d565b80830180516001600160401b038111156117ff57600094505050505061182d565b8060208301013d860181111561181d5760009550505050505061182d565b601f01601f191660405250925050505b8061183857506118e1565b816001600160a01b03167ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf826040518080602001828103825283818151815260200191508051906020019080838360005b838110156118a1578181015183820152602001611889565b50505050905090810190601f1680156118ce5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2506119b6565b3d80801561190b576040519150601f19603f3d011682016040523d82523d6000602084013e611910565b606091505b50816001600160a01b03167f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351826040518080602001828103825283818151815260200191508051906020019080838360005b8381101561197a578181015183820152602001611962565b50505050905090810190601f1680156119a75780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b505b60ff80861660009081526009602052604090205461100591636f93d2e69189913391879116806119ea575060ff881615155b604080516001600160e01b031960e088901b1681526001600160a01b039586166004820152939094166024840152604483019190915215156064820152905160848083019260209291908290030181600087803b158015611a4a57600080fd5b505af1158015611a5e573d6000803e3d6000fd5b505050506040513d6020811015611a7457600080fd5b505050505050505050505b505050505050505050505050565b630100610081565b600981565b61100781565b61100681565b60005460ff1681565b3361100714611aef5760405162461bcd60e51b815260040180806020018281038252602e815260200180612abe602e913960400191505060405180910390fd5b611b5884848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526012815271626174636853697a65466f724f7261636c6560701b602082015291506129769050565b15611bf357604080516020601f8401819004810282018101909252828152600091611b9b91858580838501838280828437600092019190915250612a5d92505050565b90506127108111158015611bb05750600a8110155b611beb5760405162461bcd60e51b8152600401808060200182810382526032815260200180612b366032913960400191505060405180910390fd5b600155611fb4565b611c5484848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600a81526918591910da185b9b995b60b21b602082015291506129769050565b15611dd957606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060169091149050611cd75760405162461bcd60e51b8152600401808060200182810382526052815260200180612b8b6052913960600191505060405180910390fd5b600181015160028201516016830151611cef81612a62565b611d40576040805162461bcd60e51b815260206004820152601960248201527f61646472657373206973206e6f74206120636f6e747261637400000000000000604482015290519081900360640190fd5b60ff808416600081815260056020908152604080832080546001600160a01b0388166001600160a01b03199091168117909155808452600683528184208585528352818420805460ff19908116600117909155600990935281842080549093169588161595909517909155517f7e3b6af43092577ee20e60eaa1d9b114a7031305c895ee7dd3ffe17196d2e1e09190a350505050611fb4565b611e4684848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526016815275195b98589b1953dc911a5cd8589b1950da185b9b995b60521b602082015291506129769050565b15611f7757606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060029091149050611ec95760405162461bcd60e51b815260040180806020018281038252604a815260200180612aec604a913960600191505060405180910390fd5b600181810151600283015160ff80831660009081526005602052604090205492939192908316909114906001600160a01b03168015611f6d576001600160a01b038116600090815260066020908152604080832060ff881680855290835292819020805460ff1916861515908117909155815190815290517fa3132e3f9819fbddc7f0ed6d38d7feef59aa95112090b7c592f5cb5bc4aa4adc929181900390910190a25b5050505050611fb4565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b6008602052600090815260409020546001600160401b031681565b61100281565b600660209081526000928352604080842090915290825290205460ff1681565b6040518060400160405280600381526020016269626360e81b81525081565b61100381565b60005460ff1615612104576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b7f1471eb6eb2c5e789fc3de43f8ce62938c7d1836ec861730447e2ada8fd81017b80546001600160a01b0319908116611008179091557f92e85d02570a8092d09a6e3a57665bc3815a2699a4074001bf1ccabf660f5a36805460ff199081169091557fd8af288fc1c8680b4f4706064cf021e264efb6828fcaf7eb5ca36818eb365bcc8054821660019081179091557f89832631fb3c3307a103ba2c84ab569c64d6182a18893dcd163f0f1c2090733a805484166110049081179091557f6cde3cea4b3a3fb2488b2808bae7556f4a405e50f65e1794383bc026131b13c38054841690557f72e4efa1513b071517c6c74dba31b5934a81aa83cddd400e7081df5529c9943680548416831790557fa9bc9a3a348c357ba16b37005d7e6b3236198c0e939f4af8c5f19b8deeb8ebc08054851690911790557fc575c31fea594a6eb97c8e9d3f9caee4c16218c6ef37e923234c0fe9014a61e78054831690557f4e523af77f034e9810f1c94057f5e931fb3d16a51511a4c3add793617d18610580548316821790557ffb33122aa9f93cc639ebe80a7bc4784c11e6053dde89c6f4f7e268c6a623da1e805484166110001790557fc7694af312c4f286114180fd0ba6a52461fcee8a381636770b19a343af92538a80548316821790557f01112dd68e482ba8d68a7e828cff8b3abcea08eab88941953c180a7e650e9cd480548316821790557fc0a4a8be475dfebc377ebef2d7c4ff47656f572a08dd92b81017efcdba0febe1805484166110071790557f87e8a52529e8ece4ef759037313542a6429ff494a9fab9027fb79db90124eba680548316821790557f4c7666bbcb22d46469f7cc282f70764a7012dca2cce630ff8d83db9a9cdd48f080548316821790557f40f28f99a40bc9f6beea1013afdbc3cdcc689eb76b82c4de06c0acf1e1932ed58054909316611001179092557f0d9cf2cd531699eed8dd34e40ff2884a14a698c4898184fba85194e6f6772d248054821683179055600b60009081527f23f68c9bd22b8a93d06adabe17481c87c016bcbd20adc8bfd707a4d813a572176020527fdf0d5d05428057f5455c2dc8e810dd86d1e9350faa72f16bda8a45443c5b39328054831684179055603283556004805467ffffffffffffffff19166001600160401b031790556002819055600381905580549091169091179055565b6007602052600090815260409020546001600160401b031681565b6000805460ff166124d2576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b33600090815260066020908152604080832060ff808a16855292529091205486911661252f5760405162461bcd60e51b8152600401808060200182810382526031815260200180612a8d6031913960400191505060405180910390fd5b60ff86166000908152600760209081526040808320548151601f89018490048402810184019092528782526001600160401b0316926125949284928b926111579290918a918d908d908190840183828082843760009201919091525061080092505050565b60ff969096166000908152600760205260409020805467ffffffffffffffff191660019788016001600160401b03161790555093949350505050565b61100081565b600381565b61100481565b8051602090910191565b5b6020811061260b578251825260209283019290910190601f19016125ec565b915181516020939093036101000a6000190180199091169216919091179052565b60408051600e808252818301909252606091630100610060ff851617918391602082018180368337505050600e818101969096526006810192909252509283525090919050565b60008561268257506000612767565b606082518451865160800101016040519080825280601f01601f1916602001820160405280156126b9576020820181803683370190505b50905060006126c782612a68565b6020808901518252019050866000806126df896125e1565b80865260209095019490925090506126f88285836125eb565b92830192612705886125e1565b808652602090950194909250905061271e8285836125eb565b9283018a815260200192612731876125e1565b90925090506127418285836125eb565b50835160200161274f612a6e565b60208183886065600019fa5051600114955050505050505b95945050505050565b600080600060606021855110156127a0575050604080516000808252602082019092529092508291508190612819565b600185015160218601518651604080516020198301808252601f19600119909401939093168101602001909152604189019392916060919080156127eb576020820181803683370190505b50905060006127f9826125e1565b50905061280b858260218d51036125eb565b506001975091955093509150505b9193509193565b60025443111561285f576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b1617909155600355436002556128a0565b600380546001908101918290555410156128a0576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003555b8160ff16836001600160401b0316600460009054906101000a900460070b6001600160401b03167f3a6e0fc61675aa2a100bcba0568368bb92bcec91c97673391074f11138f0cffe606185604051808361ffff1661ffff16815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561293657818101518382015260200161291e565b50505050905090810190601f1680156129635780820380516001836020036101000a031916815260200191505b50935050505060405180910390a4505050565b6000816040516020018082805190602001908083835b602083106129ab5780518252601f19909201916020918201910161298c565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310612a195780518252601f1990920191602091820191016129fa565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b3b151590565b60200190565b6040518060200160405280600190602082028036833750919291505056fe74686520636f6e747261637420616e64206368616e6e656c2068617665206e6f74206265656e2072656769737465726564746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f7220656e61626c654f7244697361626c654368616e6e656c2073686f756c6420626520322c206368616e6e656c49643a6973456e61626c65746865206e6577426174636853697a65466f724f7261636c652073686f756c6420626520696e205b31302c2031303030305d6c6967687420636c69656e74206e6f742073796e632074686520626c6f636b207965746c656e677468206f662076616c756520666f72206164644368616e6e656c2073686f756c642062652032322c206368616e6e656c49643a697346726f6d53797374656d3a68616e646c657241646472657373a2646970667358221220230d7e9288613f5afb55ab3692ab4b25169e86ce53da4ef6333e3703c1351f7864736f6c63430006040033" - }, - "9fB29AAc15b9A4B7F17c3385939b007540f4d791": { - "balance": "0x84595161401484a000000" - }, - "37B8516a0F88E65D677229b402ec6C1e0E333004": { - "balance": "0x84595161401484a000000" - } + "0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE": { + "balance": "0x0" + }, + "0x0000000000000000000000000000000000001000": { + "balance": "0x0", + "code": "0x6080604052600436106102675760003560e01c806396713da911610144578063c81b1662116100b6578063eb57e2021161007a578063eb57e20214610900578063eda5868c14610933578063f340fa0114610948578063f9a2bbc71461096e578063fc3e590814610983578063fd6a68791461099857610267565b8063c81b1662146108ac578063c8509d81146105f3578063d86222d5146108c1578063dc927faf146108d6578063e1c7392a146108eb57610267565b8063aaf5eb6811610108578063aaf5eb681461071f578063ab51bb9614610734578063ac43175114610749578063ad3c9da614610814578063b7ab4db514610847578063bf9f49951461040557610267565b806396713da9146106a25780639dc09262146106b7578063a1a11bf5146106cc578063a5422d5c146106e1578063a78abc16146106f657610267565b80635667515a116101dd57806375d47a0a116101a157806375d47a0a146105b45780637942fd05146105c957806381650b62146105de578063831d65d1146105f3578063853230aa14610678578063862498821461068d57610267565b80635667515a146104ea5780635d77156c146104ff5780636969a25c146105145780636e47b4821461058a57806370fd5bad1461059f57610267565b80633dffc3871161022f5780633dffc3871461040557806343756e5c14610430578063493279b1146104615780634bf6c8821461048d57806351e80672146104a2578063565c56b3146104b757610267565b80630bee7a671461026c5780631182b8751461029a5780631ff1806914610394578063219f22d5146103bb57806335409f7f146103d0575b600080fd5b34801561027857600080fd5b506102816109ad565b6040805163ffffffff9092168252519081900360200190f35b3480156102a657600080fd5b5061031f600480360360408110156102bd57600080fd5b60ff8235169190810190604081016020820135600160201b8111156102e157600080fd5b8201836020820111156102f357600080fd5b803590602001918460018302840111600160201b8311171561031457600080fd5b5090925090506109b2565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610359578181015183820152602001610341565b50505050905090810190601f1680156103865780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103a057600080fd5b506103a9610b26565b60408051918252519081900360200190f35b3480156103c757600080fd5b50610281610b2c565b3480156103dc57600080fd5b50610403600480360360208110156103f357600080fd5b50356001600160a01b0316610b31565b005b34801561041157600080fd5b5061041a610e45565b6040805160ff9092168252519081900360200190f35b34801561043c57600080fd5b50610445610e4a565b604080516001600160a01b039092168252519081900360200190f35b34801561046d57600080fd5b50610476610e50565b6040805161ffff9092168252519081900360200190f35b34801561049957600080fd5b5061041a610e55565b3480156104ae57600080fd5b50610445610e5a565b3480156104c357600080fd5b506103a9600480360360208110156104da57600080fd5b50356001600160a01b0316610e60565b3480156104f657600080fd5b5061041a610eb2565b34801561050b57600080fd5b50610281610eb7565b34801561052057600080fd5b5061053e6004803603602081101561053757600080fd5b5035610ebc565b604080516001600160a01b039788168152958716602087015293909516848401526001600160401b0390911660608401521515608083015260a082019290925290519081900360c00190f35b34801561059657600080fd5b50610445610f20565b3480156105ab57600080fd5b5061041a610f26565b3480156105c057600080fd5b50610445610f2b565b3480156105d557600080fd5b5061041a610f31565b3480156105ea57600080fd5b50610281610f36565b3480156105ff57600080fd5b506104036004803603604081101561061657600080fd5b60ff8235169190810190604081016020820135600160201b81111561063a57600080fd5b82018360208201111561064c57600080fd5b803590602001918460018302840111600160201b8311171561066d57600080fd5b509092509050610f3b565b34801561068457600080fd5b506103a9610fee565b34801561069957600080fd5b506103a9610ff4565b3480156106ae57600080fd5b5061041a610ffa565b3480156106c357600080fd5b50610445610fff565b3480156106d857600080fd5b50610445611005565b3480156106ed57600080fd5b5061031f61100b565b34801561070257600080fd5b5061070b61102a565b604080519115158252519081900360200190f35b34801561072b57600080fd5b506103a9611033565b34801561074057600080fd5b50610281610eb2565b34801561075557600080fd5b506104036004803603604081101561076c57600080fd5b810190602081018135600160201b81111561078657600080fd5b82018360208201111561079857600080fd5b803590602001918460018302840111600160201b831117156107b957600080fd5b919390929091602081019035600160201b8111156107d657600080fd5b8201836020820111156107e857600080fd5b803590602001918460018302840111600160201b8311171561080957600080fd5b50909250905061103c565b34801561082057600080fd5b506103a96004803603602081101561083757600080fd5b50356001600160a01b03166112e3565b34801561085357600080fd5b5061085c6112f5565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610898578181015183820152602001610880565b505050509050019250505060405180910390f35b3480156108b857600080fd5b5061044561141b565b3480156108cd57600080fd5b506103a9611421565b3480156108e257600080fd5b5061044561142d565b3480156108f757600080fd5b50610403611433565b34801561090c57600080fd5b506104036004803603602081101561092357600080fd5b50356001600160a01b0316611636565b34801561093f57600080fd5b50610281611805565b6104036004803603602081101561095e57600080fd5b50356001600160a01b031661180a565b34801561097a57600080fd5b50610445611a20565b34801561098f57600080fd5b5061041a611a26565b3480156109a457600080fd5b50610445611a2b565b606481565b60005460609060ff16610a08576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b3361200014610a485760405162461bcd60e51b815260040180806020018281038252602f815260200180613f73602f913960400191505060405180910390fd5b610a50613c27565b6000610a9185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a3192505050565b9150915080610aad57610aa46064611b8a565b92505050610b1f565b815160009060ff16610acd57610ac68360200151611beb565b9050610aeb565b825160ff1660011415610ae757610ac683602001516129ec565b5060655b63ffffffff8116610b105750506040805160008152602081019091529150610b1f9050565b610b1981611b8a565b93505050505b9392505050565b60035481565b606881565b3361100114610b715760405162461bcd60e51b8152600401808060200182810382526029815260200180613fcf6029913960400191505060405180910390fd5b6001600160a01b03811660009081526004602052604090205480610b955750610e42565b600181039050600060018281548110610baa57fe5b60009182526020909120600360049092020101546001549091506000190180610bf957600060018481548110610bdc57fe5b906000526020600020906004020160030181905550505050610e42565b6040805183815290516001600160a01b038616917f3b6f9ef90462b512a1293ecec018670bf7b7f1876fb727590a8a6d7643130a70919081900360200190a26001600160a01b038416600090815260046020526040812055600154600019018314610d7b57600180546000198101908110610c7057fe5b906000526020600020906004020160018481548110610c8b57fe5b6000918252602082208354600492830290910180546001600160a01b03199081166001600160a01b0393841617825560018087015481840180548416918616919091179055600280880180549185018054909416919095161780835584546001600160401b03600160a01b91829004160267ffffffffffffffff60a01b1990911617808355935460ff600160e01b918290041615150260ff60e01b199094169390931790556003948501549401939093558254868401939192919087908110610d5057fe5b600091825260208083206004909202909101546001600160a01b031683528201929092526040019020555b6001805480610d8657fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b03191690556003018190559155818381610dd957fe5b0490508015610e3d5760015460005b81811015610e3a578260018281548110610dfe57fe5b9060005260206000209060040201600301540160018281548110610e1e57fe5b6000918252602090912060036004909202010155600101610de8565b50505b505050505b50565b600181565b61100181565b606181565b600881565b61200081565b6001600160a01b03811660009081526004602052604081205480610e88576000915050610ead565b600180820381548110610e9757fe5b9060005260206000209060040201600301549150505b919050565b600081565b606781565b60018181548110610ec957fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b0392831694509082169291821691600160a01b81046001600160401b031691600160e01b90910460ff169086565b61100581565b600281565b61100881565b600b81565b606681565b3361200014610f7b5760405162461bcd60e51b815260040180806020018281038252602f815260200180613f73602f913960400191505060405180910390fd5b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a1505050565b6103e881565b60025481565b600981565b61100781565b61100681565b604051806101e001604052806101b78152602001613d9b6101b7913981565b60005460ff1681565b6402540be40081565b60005460ff1661108f576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b33611007146110cf5760405162461bcd60e51b815260040180806020018281038252602e815260200180613d26602e913960400191505060405180910390fd5b61113984848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526013815272065787069726554696d655365636f6e6447617606c1b60208201529150612c2a9050565b15611214576020811461117d5760405162461bcd60e51b8152600401808060200182810382526026815260200180613d756026913960400191505060405180910390fd5b604080516020601f84018190048102820181019092528281526000916111bb91858580838501838280828437600092019190915250612d1292505050565b9050606481101580156111d15750620186a08111155b61120c5760405162461bcd60e51b8152600401808060200182810382526027815260200180613cda6027913960400191505060405180910390fd5b600255611251565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b60046020526000908152604090205481565b6001546060906000805b82811015611346576001818154811061131457fe5b9060005260206000209060040201600201601c9054906101000a900460ff1661133e576001909101905b6001016112ff565b50606081604051908082528060200260200182016040528015611373578160200160208202803683370190505b50600092509050815b83811015611413576001818154811061139157fe5b9060005260206000209060040201600201601c9054906101000a900460ff1661140b57600181815481106113c157fe5b600091825260209091206004909102015482516001600160a01b03909116908390859081106113ec57fe5b6001600160a01b03909216602092830291909101909101526001909201915b60010161137c565b509250505090565b61100281565b67016345785d8a000081565b61100381565b60005460ff161561148b576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b611493613c27565b60006114b9604051806101e001604052806101b78152602001613d9b6101b79139611a31565b91509150806114f95760405162461bcd60e51b8152600401808060200182810382526021815260200180613f526021913960400191505060405180910390fd5b60005b82602001515181101561161e5760018360200151828151811061151b57fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782558587015182850180549185169183169190911790556040860151600283018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590981692909516919091179290921694909417161790915560a0909301516003909301929092559186015180519185019391859081106115f157fe5b602090810291909101810151516001600160a01b03168252810191909152604001600020556001016114fc565b50506103e8600255506000805460ff19166001179055565b33611001146116765760405162461bcd60e51b8152600401808060200182810382526029815260200180613fcf6029913960400191505060405180910390fd5b6001600160a01b0381166000908152600460205260409020548061169a5750610e42565b6001810390506000600182815481106116af57fe5b90600052602060002090600402016003015490506000600183815481106116d257fe5b906000526020600020906004020160030181905550600060018080549050039050836001600160a01b03167f8cd4e147d8af98a9e3b6724021b8bf6aed2e5dac71c38f2dce8161b82585b25d836040518082815260200191505060405180910390a28061174157505050610e42565b600081838161174c57fe5b0490508015610e3d5760005b848110156117aa57816001828154811061176e57fe5b906000526020600020906004020160030154016001828154811061178e57fe5b6000918252602090912060036004909202010155600101611758565b50600180549085015b81811015610e3a5782600182815481106117c957fe5b90600052602060002090600402016003015401600182815481106117e957fe5b60009182526020909120600360049092020101556001016117b3565b606581565b3341146118485760405162461bcd60e51b815260040180806020018281038252602d815260200180613fa2602d913960400191505060405180910390fd5b60005460ff1661189b576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b600034116118e8576040805162461bcd60e51b81526020600482015260156024820152746465706f7369742076616c7565206973207a65726f60581b604482015290519081900360640190fd5b6001600160a01b038116600090815260046020526040902054349080156119db57600060018083038154811061191a57fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff1615611985576040805184815290516001600160a01b038616917ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b4919081900360200190a26119d5565b600380548401815581018054840190556040805184815290516001600160a01b038616917f93a090ecc682c002995fad3c85b30c5651d7fd29b0be5da9d784a3302aedc055919081900360200190a25b50611a1b565b6040805183815290516001600160a01b038516917ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b4919081900360200190a25b505050565b61100081565b600381565b61100481565b611a39613c27565b6000611a43613c27565b611a4b613c3f565b611a5c611a5786612d17565b612d3c565b90506000805b611a6b83612d86565b15611b7c5780611a9057611a86611a8184612da7565b612df5565b60ff168452611b74565b8060011415611b6f576060611aac611aa785612da7565b612e55565b90508051604051908082528060200260200182016040528015611ae957816020015b611ad6613c5f565b815260200190600190039081611ace5790505b50602086015260005b8151811015611b6457611b03613c5f565b6000611b21848481518110611b1457fe5b6020026020010151612f26565b9150915080611b3e57876000995099505050505050505050611b85565b8188602001518481518110611b4f57fe5b60209081029190910101525050600101611af2565b506001925050611b74565b611b7c565b600101611a62565b50919350909150505b915091565b604080516001808252818301909252606091829190816020015b6060815260200190600190039081611ba4579050509050611bca8363ffffffff16613003565b81600081518110611bd757fe5b6020026020010181905250610b1f81613016565b6000806060611bf9846130a0565b9150915081611ca6577f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2816040518080602001828103825283818151815260200191508051906020019080838360005b83811015611c61578181015183820152602001611c49565b50505050905090810190601f168015611c8e5780820380516001836020036101000a031916815260200191505b509250505060405180910390a1606692505050610ead565b600080805b600154811015611d235767016345785d8a000060018281548110611ccb57fe5b90600052602060002090600402016003015410611ced57600190920191611d1b565b600060018281548110611cfc57fe5b9060005260206000209060040201600301541115611d1b576001909101905b600101611cab565b50606082604051908082528060200260200182016040528015611d50578160200160208202803683370190505b509050606083604051908082528060200260200182016040528015611d7f578160200160208202803683370190505b509050606084604051908082528060200260200182016040528015611dae578160200160208202803683370190505b509050606085604051908082528060200260200182016040528015611ddd578160200160208202803683370190505b5090506000606086604051908082528060200260200182016040528015611e0e578160200160208202803683370190505b509050606087604051908082528060200260200182016040528015611e3d578160200160208202803683370190505b509050600098506000975060608d905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b158015611e8a57600080fd5b505afa158015611e9e573d6000803e3d6000fd5b505050506040513d6020811015611eb457600080fd5b5051905067016345785d8a0000811115611f29577f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2604051808060200182810382526021815260200180613d546021913960400191505060405180910390a160689d5050505050505050505050505050610ead565b60005b60015481101561219c5767016345785d8a000060018281548110611f4c57fe5b906000526020600020906004020160030154106120d25760018181548110611f7057fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b03168a8d81518110611fa157fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060006402540be40060018381548110611fd657fe5b90600052602060002090600402016003015481611fef57fe5b0660018381548110611ffd57fe5b906000526020600020906004020160030154039050612025838261315390919063ffffffff16565b8a8e8151811061203157fe5b6020026020010181815250506001828154811061204a57fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316888e8151811061207b57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505081898e815181106120a857fe5b60209081029190910101526120c3878263ffffffff61319516565b6001909d019c96506121949050565b6000600182815481106120e157fe5b9060005260206000209060040201600301541115612194576001818154811061210657fe5b906000526020600020906004020160010160009054906101000a90046001600160a01b0316858c8151811061213757fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506001818154811061216457fe5b906000526020600020906004020160030154848c8151811061218257fe5b60209081029190910101526001909a01995b600101611f2c565b50600085156125da576110046001600160a01b0316636e056520878c8c8b60025442016040518663ffffffff1660e01b815260040180806020018060200180602001856001600160401b03166001600160401b03168152602001848103845288818151815260200191508051906020019060200280838360005b8381101561222e578181015183820152602001612216565b50505050905001848103835287818151815260200191508051906020019060200280838360005b8381101561226d578181015183820152602001612255565b50505050905001848103825286818151815260200191508051906020019060200280838360005b838110156122ac578181015183820152602001612294565b505050509050019750505050505050506020604051808303818588803b1580156122d557600080fd5b505af1935050505080156122fb57506040513d60208110156122f657600080fd5b505160015b612536576040516000815260443d1015612317575060006123b2565b60046000803e60005160e01c6308c379a081146123385760009150506123b2565b60043d036004833e81513d60248201116001600160401b0382111715612363576000925050506123b2565b80830180516001600160401b038111156123845760009450505050506123b2565b8060208301013d86018111156123a2576000955050505050506123b2565b601f01601f191660405250925050505b806123bd5750612461565b60019150867fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf280826040518080602001828103825283818151815260200191508051906020019080838360005b83811015612421578181015183820152602001612409565b50505050905090810190601f16801561244e5780820380516001836020036101000a031916815260200191505b509250505060405180910390a250612531565b3d80801561248b576040519150601f19603f3d011682016040523d82523d6000602084013e612490565b606091505b5060019150867fbfa884552dd8921b6ce90bfe906952ae5b3b29be0cc1a951d4f62697635a3a45826040518080602001828103825283818151815260200191508051906020019080838360005b838110156124f55781810151838201526020016124dd565b50505050905090810190601f1680156125225780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b6125da565b8015612574576040805188815290517fa217d08e65f80c73121cd9db834d81652d544bfbf452f6d04922b16c90a37b709181900360200190a16125d8565b604080516020808252601b908201527f6261746368207472616e736665722072657475726e2066616c7365000000000081830152905188917fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf280919081900360600190a25b505b80156127905760005b885181101561278e5760008982815181106125fa57fe5b6020026020010151905060006001828154811061261357fe5b60009182526020909120600160049092020181015481546001600160a01b03909116916108fc918590811061264457fe5b9060005260206000209060040201600301549081150290604051600060405180830381858888f1935050505090508015612700576001828154811061268557fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d91859081106126d457fe5b9060005260206000209060040201600301546040518082815260200191505060405180910390a2612784565b6001828154811061270d57fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d918590811061275c57fe5b9060005260206000209060040201600301546040518082815260200191505060405180910390a25b50506001016125e3565b505b8451156128da5760005b85518110156128d85760008682815181106127b157fe5b60200260200101516001600160a01b03166108fc8784815181106127d157fe5b60200260200101519081150290604051600060405180830381858888f19350505050905080156128675786828151811061280757fe5b60200260200101516001600160a01b03167f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d87848151811061284557fe5b60200260200101516040518082815260200191505060405180910390a26128cf565b86828151811061287357fe5b60200260200101516001600160a01b03167f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d8784815181106128b157fe5b60200260200101516040518082815260200191505060405180910390a25b5060010161279a565b505b4715612943576040805147815290517f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d9181900360200190a1604051611002904780156108fc02916000818181858888f19350505050158015612941573d6000803e3d6000fd5b505b600060035582511561295857612958836131ef565b6110016001600160a01b031663fc4333cd6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561299557600080fd5b505af11580156129a9573d6000803e3d6000fd5b50506040517fedd8d7296956dd970ab4de3f2fc03be2b0ffc615d20cd4c72c6e44f928630ebf925060009150a15060009f9e505050505050505050505050505050565b60008151600114612a4a577f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2604051808060200182810382526025815260200180613d016025913960400191505060405180910390a1506067610ead565b612a52613c5f565b82600081518110612a5f57fe5b60209081029190910181015180516001600160a01b03166000908152600490925260409091205490915080612ad05781516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a2600092505050610ead565b600154600090815b81811015612b625760018181548110612aed57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16158015612b4c575084600001516001600160a01b031660018281548110612b2f57fe5b60009182526020909120600490910201546001600160a01b031614155b15612b5a5760019250612b62565b600101612ad8565b5081612bac5783516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a26000945050505050610ead565b6001806001850381548110612bbd57fe5b6000918252602082206002600490920201018054921515600160e01b0260ff60e01b199093169290921790915584516040516001600160a01b03909116917ff226e7d8f547ff903d9d419cf5f54e0d7d07efa9584135a53a057c5f1f27f49a91a250600095945050505050565b6000816040516020018082805190602001908083835b60208310612c5f5780518252601f199092019160209182019101612c40565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310612ccd5780518252601f199092019160209182019101612cae565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490505b92915050565b015190565b612d1f613c94565b506040805180820190915281518152602082810190820152919050565b612d44613c3f565b612d4d826136b6565b612d5657600080fd5b6000612d6583602001516136f0565b60208085015160408051808201909152868152920190820152915050919050565b6000612d90613c94565b505080518051602091820151919092015191011190565b612daf613c94565b612db882612d86565b612dc157600080fd5b60208201516000612dd182613753565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590612e0a57508151602110155b612e1357600080fd5b6000612e2283602001516136f0565b83516020808601518301805193945091849003929190831015612e4c57826020036101000a820491505b50949350505050565b6060612e60826136b6565b612e6957600080fd5b6000612e74836137ec565b9050606081604051908082528060200260200182016040528015612eb257816020015b612e9f613c94565b815260200190600190039081612e975790505b5090506000612ec485602001516136f0565b60208601510190506000805b84811015612f1b57612ee183613753565b9150604051806040016040528083815260200184815250848281518110612f0457fe5b602090810291909101015291810191600101612ed0565b509195945050505050565b612f2e613c5f565b6000612f38613c5f565b612f40613c3f565b612f4985612d3c565b90506000805b612f5883612d86565b15611b7c5780612f8357612f73612f6e84612da7565b613848565b6001600160a01b03168452612ffb565b8060011415612fab57612f98612f6e84612da7565b6001600160a01b03166020850152612ffb565b8060021415612fd357612fc0612f6e84612da7565b6001600160a01b03166040850152612ffb565b8060031415611b6f57612fe8611a8184612da7565b6001600160401b03166060850152600191505b600101612f4f565b6060612d0c61301183613862565b613948565b60608151600014156130375750604080516000815260208101909152610ead565b60608260008151811061304657fe5b602002602001015190506000600190505b83518110156130875761307d8285838151811061307057fe5b602002602001015161399a565b9150600101613057565b50610b1f61309a825160c060ff16613a17565b8261399a565b60006060815b83518110156131395760005b81811015613130578481815181106130c657fe5b6020026020010151600001516001600160a01b03168583815181106130e757fe5b6020026020010151600001516001600160a01b031614156131285760006040518060600160405280602b8152602001613caf602b9139935093505050611b85565b6001016130b2565b506001016130a6565b505060408051602081019091526000815260019150915091565b6000610b1f83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613b0f565b600082820183811015610b1f576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600154815160005b8281101561330c576001613209613c5f565b6001838154811061321657fe5b600091825260208083206040805160c08101825260049490940290910180546001600160a01b0390811685526001820154811693850193909352600281015492831691840191909152600160a01b82046001600160401b03166060840152600160e01b90910460ff16151560808301526003015460a082015291505b848110156132e0578681815181106132a657fe5b6020026020010151600001516001600160a01b031682600001516001600160a01b031614156132d857600092506132e0565b600101613292565b5081156133025780516001600160a01b03166000908152600460205260408120555b50506001016131f7565b508082111561338157805b8281101561337f57600180548061332a57fe5b60008281526020812060046000199093019283020180546001600160a01b03199081168255600182810180549092169091556002820180546001600160e81b0319169055600390910191909155915501613317565b505b60008183106133905781613392565b825b905060005b8181101561358c576134448582815181106133ae57fe5b6020026020010151600183815481106133c357fe5b60009182526020918290206040805160c08101825260049390930290910180546001600160a01b0390811684526001820154811694840194909452600281015493841691830191909152600160a01b83046001600160401b03166060830152600160e01b90920460ff161515608082015260039091015460a0820152613ba6565b61355f57806001016004600087848151811061345c57fe5b6020026020010151600001516001600160a01b03166001600160a01b031681526020019081526020016000208190555084818151811061349857fe5b6020026020010151600182815481106134ad57fe5b6000918252602091829020835160049092020180546001600160a01b039283166001600160a01b0319918216178255928401516001820180549184169185169190911790556040840151600282018054606087015160808801511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909716929097169190911792909216939093171692909217905560a090910151600390910155613584565b60006001828154811061356e57fe5b9060005260206000209060040201600301819055505b600101613397565b50828211156136b057825b82811015610e3d5760018582815181106135ad57fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782559585015181840180549184169188169190911790556040850151600282018054606088015160808901511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590971692909a169190911792909216939093171695909517905560a0909201516003909301929092558751908401929088908590811061368357fe5b602090810291909101810151516001600160a01b0316825281019190915260400160002055600101613597565b50505050565b80516000906136c757506000610ead565b6020820151805160001a9060c08210156136e657600092505050610ead565b5060019392505050565b8051600090811a608081101561370a576000915050610ead565b60b8811080613725575060c08110801590613725575060f881105b15613734576001915050610ead565b60c08110156137485760b519019050610ead565b60f519019050610ead565b80516000908190811a608081101561376e57600191506137e5565b60b881101561378357607e19810191506137e5565b60c08110156137b05760b78103600185019450806020036101000a855104600182018101935050506137e5565b60f88110156137c55760be19810191506137e5565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b80516000906137fd57506000610ead565b6000809050600061381184602001516136f0565b602085015185519181019250015b8082101561383f5761383082613753565b6001909301929091019061381f565b50909392505050565b805160009060151461385957600080fd5b612d0c82612df5565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166138a6575060186138ca565b6fffffffffffffffffffffffffffffffff1984166138c6575060106138ca565b5060005b6020811015613900578181815181106138df57fe5b01602001516001600160f81b031916156138f857613900565b6001016138ca565b60008160200390506060816040519080825280601f01601f191660200182016040528015613935576020820181803683370190505b5080830196909652508452509192915050565b60608151600114801561397a5750607f60f81b8260008151811061396857fe5b01602001516001600160f81b03191611155b15613986575080610ead565b612d0c6139988351608060ff16613a17565b835b6060806040519050835180825260208201818101602087015b818310156139cb5780518352602092830192016139b3565b50855184518101855292509050808201602086015b818310156139f85780518352602092830192016139e0565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310613a67576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411613ac15782840160f81b81600081518110613aa357fe5b60200101906001600160f81b031916908160001a9053509050612d0c565b6060613acc85613862565b90508381510160370160f81b82600081518110613ae557fe5b60200101906001600160f81b031916908160001a905350613b06828261399a565b95945050505050565b60008184841115613b9e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613b63578181015183820152602001613b4b565b50505050905090810190601f168015613b905780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b805182516000916001600160a01b039182169116148015613be0575081602001516001600160a01b031683602001516001600160a01b0316145b8015613c05575081604001516001600160a01b031683604001516001600160a01b0316145b8015610b1f5750506060908101519101516001600160401b0390811691161490565b60408051808201909152600081526060602082015290565b6040518060400160405280613c52613c94565b8152602001600081525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b60405180604001604052806000815260200160008152509056fe6475706c696361746520636f6e73656e7375732061646472657373206f662076616c696461746f725365747468652065787069726554696d655365636f6e64476170206973206f7574206f662072616e67656c656e677468206f66206a61696c2076616c696461746f7273206d757374206265206f6e65746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374666565206973206c6172676572207468616e2044555354595f494e434f4d494e476c656e677468206f662065787069726554696d655365636f6e64476170206d69736d61746368f901b480f901b0f846941284214b9b9c85549ab3d2b972df0deef66ac2c99477f066f3fb515bb97015e4b4afddbcb25c94286b946ddf42a51534fc98d0c0a3b42c963cace8441ddf86048c27395000f84694b71b214cb885500844365e95cd9942c7276e7fd894748c284f46ab87fd492326f1e2fe731d22ad2db394d22ca3ba2141d23adab65ce4940eb7665ea2b6a786048c27395000f84694a2959d3f95eae5dc7d70144ce1b73b403b7eb6e0940ce09b38374887cb564b7efa60be130d99ed5f95948081ef03f1d9e0bb4a5bf38f16285c879299f07f86048c27395000f84694980a75ecd1309ea12fa2ed87a8744fbfc9b863d59407eecf36cf0901fefe4bc505d6ba03c7480c7b5794cc6ac05c95a99c1f7b5f88de0e3486c82293b27086048c27395000f8469435552c16704d214347f29fa77f77da6d75d7c75294f57d36e129881a3a13a024fe8072507e5b2e70f894dc4973e838e3949c77aced16ac2315dc2d7ab11186048c27395000f84694f474cf03cceff28abc65c9cbae594f725c80e12d94ddfcaedf9bb451098c9917a45f02bd61342cca6694e61a183325a18a173319dd8e19c8d069459e217586048c273950006661696c656420746f20706172736520696e69742076616c696461746f72536574746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d6573736167652073656e646572206d7573742062652074686520626c6f636b2070726f6475636572746865206d6573736167652073656e646572206d75737420626520736c61736820636f6e7472616374a26469706673582212201a362ffe5872c7b034fe0bdf76cb3980b7a822a1eb1f36e261d39b52df28597164736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001001": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106102065760003560e01c806396713da91161011a578063c81b1662116100ad578063e1c7392a1161007c578063e1c7392a1461064d578063f9a2bbc714610655578063fc3e59081461065d578063fc4333cd14610665578063fd6a68791461066d57610206565b8063c81b16621461059f578063c8509d81146105a7578063c96be4cb1461061f578063dc927faf1461064557610206565b8063a78abc16116100e9578063a78abc16146104b5578063ab51bb96146104d1578063ac431751146104d9578063c80d4b8f1461059757610206565b806396713da9146104955780639bc8e4f21461049d5780639dc09262146104a5578063a1a11bf5146104ad57610206565b806351e806721161019d57806370fd5bad1161016c57806370fd5bad146103fb57806375d47a0a146104035780637912a65d1461040b5780637942fd0514610413578063831d65d11461041b57610206565b806351e80672146103db578063567a372d146103e357806362b72cf5146103eb5780636e47b482146103f357610206565b80633dffc387116101d95780633dffc3871461037257806343756e5c14610390578063493279b1146103b45780634bf6c882146103d357610206565b80630bee7a671461020b5780631182b8751461022c57806337c8dab914610319578063389f4f7114610358575b600080fd5b610213610675565b6040805163ffffffff9092168252519081900360200190f35b6102a46004803603604081101561024257600080fd5b60ff8235169190810190604081016020820135600160201b81111561026657600080fd5b82018360208201111561027857600080fd5b803590602001918460018302840111600160201b8311171561029957600080fd5b50909250905061067a565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102de5781810151838201526020016102c6565b50505050905090810190601f16801561030b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61033f6004803603602081101561032f57600080fd5b50356001600160a01b0316610709565b6040805192835260208301919091528051918290030190f35b610360610760565b60408051918252519081900360200190f35b61037a610766565b6040805160ff9092168252519081900360200190f35b61039861076b565b604080516001600160a01b039092168252519081900360200190f35b6103bc610771565b6040805161ffff9092168252519081900360200190f35b61037a610776565b61039861077b565b610360610781565b610360610787565b61039861078d565b61037a610793565b610398610798565b61036061079e565b61037a6107a3565b6104936004803603604081101561043157600080fd5b60ff8235169190810190604081016020820135600160201b81111561045557600080fd5b82018360208201111561046757600080fd5b803590602001918460018302840111600160201b8311171561048857600080fd5b5090925090506107a8565b005b61037a61087e565b610360610883565b61039861088e565b610398610894565b6104bd61089a565b604080519115158252519081900360200190f35b6102136108a3565b610493600480360360408110156104ef57600080fd5b810190602081018135600160201b81111561050957600080fd5b82018360208201111561051b57600080fd5b803590602001918460018302840111600160201b8311171561053c57600080fd5b919390929091602081019035600160201b81111561055957600080fd5b82018360208201111561056b57600080fd5b803590602001918460018302840111600160201b8311171561058c57600080fd5b5090925090506108a8565b610360610ca3565b610398610ca8565b610493600480360360408110156105bd57600080fd5b60ff8235169190810190604081016020820135600160201b8111156105e157600080fd5b8201836020820111156105f357600080fd5b803590602001918460018302840111600160201b8311171561061457600080fd5b509092509050610cae565b6104936004803603602081101561063557600080fd5b50356001600160a01b0316610cdc565b6103986110e1565b6104936110e7565b610398611158565b61037a61115e565b610493611163565b6103986112b4565b606481565b606033612000146106bc5760405162461bcd60e51b815260040180806020018281038252602f815260200180611c1a602f913960400191505060405180910390fd5b6040805162461bcd60e51b815260206004820152601e60248201527f7265636569766520756e65787065637465642073796e207061636b6167650000604482015290519081900360640190fd5b600080610714611ade565b5050506001600160a01b0316600090815260026020818152604092839020835160608101855281548082526001830154938201849052919093015460ff16151592909301919091529091565b60055481565b600181565b61100181565b606181565b600881565b61200081565b60045481565b60035481565b61100581565b600281565b61100881565b603281565b600b81565b6107b0611b01565b60006107f184848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506112ba92505050565b91509150801561083b5781516040805163ffffffff9092168252517f7f0956d47419b9525356e7111652b653b530ec6f5096dccc04589bc38e6299679181900360200190a1610877565b81516040805163ffffffff9092168252517f7d45f62d17443dd4547bca8a8112c60e2385669318dc300ec61a5d2492f262e79181900360200190a15b5050505050565b600981565b662386f26fc1000081565b61100781565b61100681565b60005460ff1681565b600081565b60005460ff166108fb576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b336110071461093b5760405162461bcd60e51b815260040180806020018281038252602e815260200180611ba5602e913960400191505060405180910390fd5b6109a684848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260148152731b5a5cd9195b59585b9bdc951a1c995cda1bdb1960621b6020820152915061133a9050565b15610a7f57602081146109ea5760405162461bcd60e51b8152600401808060200182810382526027815260200180611b4e6027913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610a289185858083850183828082843760009201919091525061142292505050565b9050600a8110158015610a3c575060055481105b610a775760405162461bcd60e51b8152600401808060200182810382526025815260200180611bf56025913960400191505060405180910390fd5b600455610c11565b610ae584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e19995b1bdb9e551a1c995cda1bdb19608a1b6020820152915061133a9050565b15610bd45760208114610b295760405162461bcd60e51b8152600401808060200182810382526022815260200180611bd36022913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610b679185858083850183828082843760009201919091525061142292505050565b9050601481118015610b7b57506103e88111155b610bcc576040805162461bcd60e51b815260206004820181905260248201527f7468652066656c6f6e795468726573686f6c64206f7574206f662072616e6765604482015290519081900360640190fd5b600555610c11565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b609681565b61100281565b6040517f07db600eebe2ac176be8dcebad61858c245a4961bb32ca2aa3d159b09aa0810e90600090a1505050565b334114610d1a5760405162461bcd60e51b815260040180806020018281038252602d815260200180611c49602d913960400191505060405180910390fd5b60005460ff16610d6d576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b6003544311610dc3576040805162461bcd60e51b815260206004820181905260248201527f63616e206e6f7420736c61736820747769636520696e206f6e6520626c6f636b604482015290519081900360640190fd5b610dcb611ade565b506001600160a01b0381166000908152600260208181526040928390208351606081018552815481526001820154928101929092529091015460ff161580159282019290925290610e26576020810180516001019052610e7f565b60016040820181905260208201819052805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0384161790555b4381526001600160a01b038216600090815260026020818152604092839020845181559084015160018201819055928401519101805460ff19169115159190911790556005549081610ecd57fe5b0661102f57604080516335409f7f60e01b81526001600160a01b03841660048201529051611000916335409f7f91602480830192600092919082900301818387803b158015610f1b57600080fd5b505af1158015610f2f573d6000803e3d6000fd5b505050506120006001600160a01b031663f7a251d7600b610f4f85611427565b60006040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015610faf578181015183820152602001610f97565b50505050905090810190601f168015610fdc5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b158015610ffd57600080fd5b505af1158015611011573d6000803e3d6000fd5b505050506040513d602081101561102757600080fd5b506110a59050565b60045481602001518161103e57fe5b066110a557604080516375abf10160e11b81526001600160a01b038416600482015290516110009163eb57e20291602480830192600092919082900301818387803b15801561108c57600080fd5b505af11580156110a0573d6000803e3d6000fd5b505050505b6040516001600160a01b038316907fddb6012116e51abf5436d956a4f0ebd927e92c576ff96d7918290c8782291e3e90600090a2505043600355565b61100381565b60005460ff161561113f576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b603260045560966005556000805460ff19166001179055565b61100081565b600381565b33611000146111a35760405162461bcd60e51b8152600401808060200182810382526030815260200180611b756030913960400191505060405180910390fd5b60005460ff166111f6576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b60015460005b818110156112875760026000600180848603038154811061121957fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff1916905580548061125d57fe5b600082815260209020810160001990810180546001600160a01b03191690550190556001016111fc565b506040517fcfdb3b6ccaeccbdc68be3c59c840e3b3c90f0a7c491f5fff1cf56cfda200dd9c90600090a150565b61100481565b6112c2611b01565b60006112cc611b01565b6112d4611b13565b6112e56112e0866114f9565b61151e565b90506000805b6112f483611568565b1561132d57806113205761130f61130a84611589565b6115d7565b63ffffffff16845260019150611325565b61132d565b6001016112eb565b5091935090915050915091565b6000816040516020018082805190602001908083835b6020831061136f5780518252601f199092019160209182019101611350565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106113dd5780518252601f1990920191602091820191016113be565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490505b92915050565b015190565b60408051600480825260a08201909252606091829190816020015b606081526020019060019003908161144257905050905061146b836001600160a01b0316611637565b8160008151811061147857fe5b602002602001018190525061148c4361165a565b8160018151811061149957fe5b60209081029190910101526114ae606161165a565b816002815181106114bb57fe5b60200260200101819052506114cf4261165a565b816003815181106114dc57fe5b60200260200101819052506114f08161166d565b9150505b919050565b611501611b33565b506040805180820190915281518152602082810190820152919050565b611526611b13565b61152f826116f7565b61153857600080fd5b60006115478360200151611731565b60208085015160408051808201909152868152920190820152915050919050565b6000611572611b33565b505080518051602091820151919092015191011190565b611591611b33565b61159a82611568565b6115a357600080fd5b602082015160006115b382611794565b80830160209586015260408051808201909152908152938401919091525090919050565b8051600090158015906115ec57508151602110155b6115f557600080fd5b60006116048360200151611731565b8351602080860151830180519394509184900392919083101561162e57826020036101000a820491505b50949350505050565b60408051600560a21b83186014820152603481019091526060906114f08161182d565b606061141c61166883611883565b61182d565b606081516000141561168e57506040805160008152602081019091526114f4565b60608260008151811061169d57fe5b602002602001015190506000600190505b83518110156116de576116d4828583815181106116c757fe5b6020026020010151611969565b91506001016116ae565b506114f06116f1825160c060ff166119e6565b82611969565b8051600090611708575060006114f4565b6020820151805160001a9060c0821015611727576000925050506114f4565b5060019392505050565b8051600090811a608081101561174b5760009150506114f4565b60b8811080611766575060c08110801590611766575060f881105b156117755760019150506114f4565b60c08110156117895760b5190190506114f4565b60f5190190506114f4565b80516000908190811a60808110156117af5760019150611826565b60b88110156117c457607e1981019150611826565b60c08110156117f15760b78103600185019450806020036101000a85510460018201810193505050611826565b60f88110156118065760be1981019150611826565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b60608151600114801561185f5750607f60f81b8260008151811061184d57fe5b01602001516001600160f81b03191611155b1561186b5750806114f4565b61141c61187d8351608060ff166119e6565b83611969565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166118c7575060186118eb565b6fffffffffffffffffffffffffffffffff1984166118e7575060106118eb565b5060005b60208110156119215781818151811061190057fe5b01602001516001600160f81b0319161561191957611921565b6001016118eb565b60008160200390506060816040519080825280601f01601f191660200182016040528015611956576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b8183101561199a578051835260209283019201611982565b50855184518101855292509050808201602086015b818310156119c75780518352602092830192016119af565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310611a36576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411611a905782840160f81b81600081518110611a7257fe5b60200101906001600160f81b031916908160001a905350905061141c565b6060611a9b85611883565b90508381510160370160f81b82600081518110611ab457fe5b60200101906001600160f81b031916908160001a905350611ad58282611969565b95945050505050565b604051806060016040528060008152602001600081526020016000151581525090565b60408051602081019091526000815290565b6040518060400160405280611b26611b33565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe6c656e677468206f66206d697364656d65616e6f725468726573686f6c64206d69736d61746368746865206d6573736167652073656e646572206d7573742062652076616c696461746f7253657420636f6e7472616374746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662066656c6f6e795468726573686f6c64206d69736d61746368746865206d697364656d65616e6f725468726573686f6c64206f7574206f662072616e6765746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d6573736167652073656e646572206d7573742062652074686520626c6f636b2070726f6475636572a26469706673582212203c75feabfa95d80f8670bc9249ad2a813867311d79e6a0c9e3a1233d3c2c953964736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001002": { + "balance": "0x0", + "code": "0x60806040526004361061014f5760003560e01c806396713da9116100b6578063c81b16621161006f578063c81b1662146103dc578063dc927faf146103f1578063f9a2bbc714610406578063fb5478b31461041b578063fc3e590814610430578063fd6a68791461044557610193565b806396713da91461033a5780639a99b4f01461034f5780639dc0926214610388578063a1a11bf51461039d578063a78abc16146103b2578063ab51bb96146103c757610193565b806351e806721161010857806351e806721461028a5780636d70f7ae1461029f5780636e47b482146102e657806370fd5bad146102fb57806375d47a0a146103105780637942fd051461032557610193565b80630bee7a67146101985780633a0b0eff146101c65780633dffc387146101ed57806343756e5c14610218578063493279b1146102495780634bf6c8821461027557610193565b366101935734156101915760408051348152905133917f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db919081900360200190a25b005b600080fd5b3480156101a457600080fd5b506101ad61045a565b6040805163ffffffff9092168252519081900360200190f35b3480156101d257600080fd5b506101db61045f565b60408051918252519081900360200190f35b3480156101f957600080fd5b50610202610465565b6040805160ff9092168252519081900360200190f35b34801561022457600080fd5b5061022d61046a565b604080516001600160a01b039092168252519081900360200190f35b34801561025557600080fd5b5061025e610470565b6040805161ffff9092168252519081900360200190f35b34801561028157600080fd5b50610202610475565b34801561029657600080fd5b5061022d61047a565b3480156102ab57600080fd5b506102d2600480360360208110156102c257600080fd5b50356001600160a01b0316610480565b604080519115158252519081900360200190f35b3480156102f257600080fd5b5061022d61049e565b34801561030757600080fd5b506102026104a4565b34801561031c57600080fd5b5061022d6104a9565b34801561033157600080fd5b506102026104af565b34801561034657600080fd5b506102026104b4565b34801561035b57600080fd5b506101db6004803603604081101561037257600080fd5b506001600160a01b0381351690602001356104b9565b34801561039457600080fd5b5061022d610664565b3480156103a957600080fd5b5061022d61066a565b3480156103be57600080fd5b506102d2610670565b3480156103d357600080fd5b506101ad610679565b3480156103e857600080fd5b5061022d61067e565b3480156103fd57600080fd5b5061022d610684565b34801561041257600080fd5b5061022d61068a565b34801561042757600080fd5b506101db610690565b34801561043c57600080fd5b5061020261069c565b34801561045157600080fd5b5061022d6106a1565b606481565b60015481565b600181565b61100181565b606181565b600881565b61200081565b6001600160a01b031660009081526002602052604090205460ff1690565b61100581565b600281565b61100881565b600b81565b600981565b6000805460ff1661053657600260208190527fe57bda0a954a7c7381b17b2c763e646ba2c60f67292d287ba583603e2c1c41668054600160ff19918216811790925561100560009081527fe25235fc0de9d7165652bef0846fefda506174abb9a190f03d0f7bcc6146dbce80548316841790559282558254161790555b3360009081526002602052604090205460ff166105845760405162461bcd60e51b815260040180806020018281038252602d8152602001806106a8602d913960400191505060405180910390fd5b60004783106105935747610595565b825b9050670de0b6b3a76400008111156105b25750670de0b6b3a76400005b8015610633576040516001600160a01b0385169082156108fc029083906000818181858888f193505050501580156105ee573d6000803e3d6000fd5b506040805182815290516001600160a01b038616917ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0919081900360200190a261065d565b6040517fe589651933c2457488cc0d8e0941518abf748e799435e4e396d9c4d0b2db2d4d90600090a15b9392505050565b61100781565b61100681565b60005460ff1681565b600081565b61100281565b61100381565b61100081565b670de0b6b3a764000081565b600381565b6110048156fe6f6e6c79206f70657261746f7220697320617661696c61626c6520746f2063616c6c20746865206d6574686f64a26469706673582212206e40023fb74e48dfc701bcc667e0729a8491ff7ddabd668e2c6383a508bb167764736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001003": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106102115760003560e01c8063a78abc1611610125578063dda83148116100ad578063e405bbc31161007c578063e405bbc314610681578063ea54b2aa14610689578063f9a2bbc714610691578063fc3e590814610699578063fd6a6879146106a157610211565b8063dda8314814610609578063df5fe7041461062f578063e1c7392a14610655578063e2761af01461065d57610211565b8063c81b1662116100f4578063c81b166214610534578063cba510a91461053c578063d816987914610562578063da8d08f0146105db578063dc927faf1461060157610211565b8063a78abc1614610444578063ab51bb9614610460578063ac43175114610468578063adc879e91461052c57610211565b8063564b81ef116101a857806375d47a0a1161017757806375d47a0a1461041c5780637942fd051461042457806396713da91461042c5780639dc0926214610434578063a1a11bf51461043c57610211565b8063564b81ef146102ca5780635c5ae8db146103475780636e47b4821461040c57806370fd5bad1461041457610211565b806343756e5c116101e457806343756e5c14610277578063493279b11461029b5780634bf6c882146102ba57806351e80672146102c257610211565b80630bee7a67146102165780632657e9b61461023757806333f7798d146102515780633dffc38714610259575b600080fd5b61021e6106a9565b6040805163ffffffff9092168252519081900360200190f35b61023f6106ae565b60408051918252519081900360200190f35b61023f6106b9565b6102616106bf565b6040805160ff9092168252519081900360200190f35b61027f6106c4565b604080516001600160a01b039092168252519081900360200190f35b6102a36106ca565b6040805161ffff9092168252519081900360200190f35b6102616106cf565b61027f6106d4565b6102d26106da565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561030c5781810151838201526020016102f4565b50505050905090810190601f1680156103395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61036d6004803603602081101561035d57600080fd5b50356001600160401b03166107e6565b60405180856001600160401b03166001600160401b0316815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156103ce5781810151838201526020016103b6565b50505050905090810190601f1680156103fb5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b61027f6108a1565b6102616108a7565b61027f6108ac565b6102616108b2565b6102616108b7565b61027f6108bc565b61027f6108c2565b61044c6108c8565b604080519115158252519081900360200190f35b61021e6108d1565b61052a6004803603604081101561047e57600080fd5b81019060208101813564010000000081111561049957600080fd5b8201836020820111156104ab57600080fd5b803590602001918460018302840111640100000000831117156104cd57600080fd5b9193909290916020810190356401000000008111156104eb57600080fd5b8201836020820111156104fd57600080fd5b8035906020019184600183028401116401000000008311171561051f57600080fd5b5090925090506108d6565b005b61023f610b8f565b61027f610b95565b61023f6004803603602081101561055257600080fd5b50356001600160401b0316610b9b565b61044c6004803603604081101561057857600080fd5b81019060208101813564010000000081111561059357600080fd5b8201836020820111156105a557600080fd5b803590602001918460018302840111640100000000831117156105c757600080fd5b9193509150356001600160401b0316610bba565b61027f600480360360208110156105f157600080fd5b50356001600160401b031661139a565b61027f6113b5565b61027f6004803603602081101561061f57600080fd5b50356001600160401b03166113bb565b61044c6004803603602081101561064557600080fd5b50356001600160401b03166113df565b61052a611421565b6106656115c6565b604080516001600160401b039092168252519081900360200190f35b6106656115d5565b6102d26115eb565b61027f611608565b61026161160e565b61027f611613565b606481565b662386f26fc1000081565b60055481565b600181565b61100181565b606181565b600881565b61200081565b604080516020808252818301909252606091829190602082018180368337505060045460208301525090506000805b60208160ff16101561075057828160ff168151811061072457fe5b01602001516001600160f81b0319161561074357600190910190610748565b610750565b600101610709565b5060608160ff166040519080825280601f01601f191660200182016040528015610781576020820181803683370190505b50905060005b8260ff168160ff1610156107dd57838160ff16815181106107a457fe5b602001015160f81c60f81b828260ff16815181106107be57fe5b60200101906001600160f81b031916908160001a905350600101610787565b50925050505b90565b60016020818152600092835260409283902080548184015460028084015460038501805489516101009982161599909902600019011692909204601f81018790048702880187019098528787526001600160401b0390931696919592949091908301828280156108975780601f1061086c57610100808354040283529160200191610897565b820191906000526020600020905b81548152906001019060200180831161087a57829003601f168201915b5050505050905084565b61100581565b600281565b61100881565b600b81565b600981565b61100781565b61100681565b60005460ff1681565b600081565b60005460ff1661092d576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604482015290519081900360640190fd5b336110071461096d5760405162461bcd60e51b815260040180806020018281038252602e815260200180611ac5602e913960400191505060405180910390fd5b6109e184848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601b81527f726577617264466f7256616c696461746f725365744368616e67650000000000602082015291506116199050565b15610ac05760208114610a255760405162461bcd60e51b815260040180806020018281038252602e815260200180611a64602e913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610a639185858083850183828082843760009201919091525061170092505050565b9050600081118015610a7d5750670de0b6b3a76400008111155b610ab85760405162461bcd60e51b815260040180806020018281038252602f815260200180611af3602f913960400191505060405180910390fd5b600555610afd565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b60045481565b61100281565b6001600160401b03166000908152600160208190526040909120015490565b60408051630a83aaa960e31b815233600482015290516000916110069163541d554891602480820192602092909190829003018186803b158015610bfd57600080fd5b505afa158015610c11573d6000803e3d6000fd5b505050506040513d6020811015610c2757600080fd5b5051610c7a576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b6001600160401b0382166000908152600260205260409020546001600160a01b031615610cee576040805162461bcd60e51b815260206004820152601c60248201527f63616e27742073796e63206475706c6963617465642068656164657200000000604482015290519081900360640190fd5b6003546001600160401b0390811690831611610d3b5760405162461bcd60e51b8152600401808060200182810382526026815260200180611b226026913960400191505060405180910390fd5b600354600160401b90046001600160401b0316610d56611862565b6001600160401b0382811660009081526001602081815260409283902083516080810185528154909516855280830154858301526002808201548686015260038201805486516101009682161596909602600019011691909104601f81018490048402850184019095528484529093606086019392830182828015610e1c5780601f10610df157610100808354040283529160200191610e1c565b820191906000526020600020905b815481529060010190602001808311610dff57829003601f168201915b50505050508152505090505b6003546001600160401b0390811690831610610f3957836001600160401b0316826001600160401b03161015610e5d57610f39565b80516001600160401b0380821660009081526001602081815260409283902083516080810185528154909516855280830154858301526002808201548686015260038201805486516101009682161596909602600019011691909104601f8101849004840285018401909552848452959750939460608601939091830182828015610f295780601f10610efe57610100808354040283529160200191610f29565b820191906000526020600020905b815481529060010190602001808311610f0c57829003601f168201915b5050505050815250509050610e28565b6060810151516110305780516001600160401b03811660009081526001602081815260409283902060030180548451600294821615610100026000190190911693909304601f810183900483028401830190945283835293955090929190830182828015610fe85780601f10610fbd57610100808354040283529160200191610fe8565b820191906000526020600020905b815481529060010190602001808311610fcb57829003601f168201915b505050506060830182905250516110305760405162461bcd60e51b8152600401808060200182810382526021815260200180611a436021913960400191505060405180910390fd5b6000816060015151608801905060608787905082016040519080825280601f01601f19166020018201604052801561106f576020820181803683370190505b509050600061107d82611705565b905061108b8486838661170b565b6110c65760405162461bcd60e51b81526004018080602001828103825260238152602001806119406023913960400191505060405180910390fd5b6000838201915061110c8a8a8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061177792505050565b9450905061111b818386611781565b8251602001935061112a611888565b6110008186866064600019fa61113f57600080fd5b805194506000600160f81b8616156111ce5750600554604080516309a99b4f60e41b815233600482015260248101929092525160019161100291639a99b4f0916044808201926020929091908290030181600087803b1580156111a157600080fd5b505af11580156111b5573d6000803e3d6000fd5b505050506040513d60208110156111cb57600080fd5b50505b856001600160401b0316955060208201935060006111ee858884156117c2565b90985090506001600160401b03808216908c161461123d5760405162461bcd60e51b8152600401808060200182810382526033815260200180611a926033913960400191505060405180910390fd5b6001600160401b03808c16600081815260026020818152604080842080546001600160a01b031916331790558e86168e529383526001808252928490208d518154961667ffffffffffffffff199096169590951785558c81015192850192909255918b01519183019190915560608a015180518b93926112c49260038501929101906118a7565b50506003546001600160401b03600160401b9091048116908d161115905061130c576003805467ffffffffffffffff60401b1916600160401b6001600160401b038e16021790555b7f4042c1020a8f410fb1c8859d276ab436aeb2c3074960e48467299cf1c966d3b48b8a8a602001518560405180856001600160401b03166001600160401b03168152602001846001600160401b03166001600160401b031681526020018381526020018215151515815260200194505050505060405180910390a15060019c9b505050505050505050505050565b6002602052600090815260409020546001600160a01b031681565b61100381565b6001600160401b03166000908152600260205260409020546001600160a01b031690565b6001600160401b0381166000908152600260205260408120546001600160a01b031615158061141b57506003546001600160401b038381169116145b92915050565b60005460ff1615611479576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b60008061149e60405180610100016040528060e0815260200161196360e09139611777565b815160045590925090506114b0611862565b60006114be848460006117c2565b60008083526001600160401b038281168252600160208181526040938490208651815467ffffffffffffffff191694169390931783558086015191830191909155918401516002820155606084015180519496509294508593909261152a9260038501929101906118a7565b50506003805467ffffffffffffffff19166001600160401b0384811691821767ffffffffffffffff60401b1916600160401b9290920291909117918290556000805460ff19166001179055662386f26fc10000600555602085810151604080519490931684529083015280517f5ac9b37d571677b80957ca05693f371526c602fd08042b416a29fdab7efefa499350918290030190a150505050565b6003546001600160401b031681565b600354600160401b90046001600160401b031681565b60405180610100016040528060e0815260200161196360e0913981565b61100081565b600381565b61100481565b6000816040516020018082805190602001908083835b6020831061164e5780518252601f19909201916020918201910161162f565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106116bc5780518252601f19909201916020918201910161169d565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b60200190565b60008460600151518284010392506000806117298760600151611777565b9092509050611739828683611781565b5050506040840151601f1983810191909152602090940151603f19830152605f19820192909252600454606719820152910160871990910152600190565b8051602090910191565b5b602081106117a1578251825260209283019290910190601f1901611782565b915181516020939093036101000a6000190180199091169216919091179052565b6117ca611862565b60088401516028850151604890950180519095600092916117e9611862565b6020810183905260408101829052866118545760008060688a036040519080825280601f01601f19166020018201604052801561182d576020820181803683370190505b506060840181905261183e90611777565b909250905061185160208c018383611781565b50505b989297509195505050505050565b604080516080810182526000808252602082018190529181019190915260608082015290565b6040518061100001604052806080906020820280368337509192915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106118e857805160ff1916838001178555611915565b82800160010185558215611915579182015b828111156119155782518255916020019190600101906118fa565b50611921929150611925565b5090565b6107e391905b80821115611921576000815560010161192b56fe6661696c656420746f2073657269616c697a6520636f6e73656e73757320737461746542696e616e63652d436861696e2d47616e67657300000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000aea1ac326886b992a991d21a6eb155f41b77867cbf659e78f31d89d8205122a84d1be64f0e9a466c2e66a53433928192783e29f8fa21beb2133499b5ef770f60000000e8d4a5100099308aa365c40554bc89982af505d85da95251445d5dd4a9bb37dd2584fd92d3000000e8d4a5100001776920ff0b0f38d78cf95c033c21adf7045785114e392a7544179652e0a612000000e8d4a510006661696c656420746f206c6f61642076616c696461746f722073657420646174616c656e677468206f6620726577617264466f7256616c696461746f725365744368616e6765206d69736d617463686865616465722068656967687420646f65736e277420657175616c20746f207468652073706563696669656420686569676874746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374746865206e6577526577617264466f7256616c696461746f725365744368616e6765206f7574206f662072616e676563616e27742073796e6320686561646572206265666f726520696e697469616c486569676874a264697066735822122054f539d4f9624b5b87ea3b4d66b04e31a6fa9de3789af1872d4cddc7acc2a79364736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001004": { + "balance": "180000000000000000000000000", + "code": "0x6080604052600436106102cd5760003560e01c80639dc0926211610175578063bd466461116100dc578063ebf71d5311610095578063fc1a598f1161006f578063fc1a598f14610c23578063fc3e59081461094e578063fd6a687914610c56578063ff9c00271461074c57610315565b8063ebf71d5314610be4578063f014847214610bf9578063f9a2bbc714610c0e57610315565b8063bd46646114610aed578063c81b166214610b20578063c8509d8114610b35578063dc6f5e901461094e578063dc927faf14610bba578063e1c7392a14610bcf57610315565b8063aa7415f51161012e578063aa7415f514610963578063ab51bb96146109aa578063ac431751146109bf578063b770186114610a8a578063b99328c514610a9f578063b9fd21e314610ad857610315565b80639dc09262146108c7578063a1a11bf5146108dc578063a496fba2146108f1578063a5cd588b14610906578063a78abc1614610939578063a7c9f02d1461094e57610315565b806361368475116102345780637942fd05116101ed5780638eff336c116101c75780638eff336c1461082557806396713da9146108645780639a854bbd146108795780639a99b4f01461088e57610315565b80637942fd051461078b578063831d65d1146107a05780638b87b21f1461056157610315565b8063613684751461031a5780636e0565201461060b5780636e47b4821461073757806370fd5bad1461074c57806371d308631461076157806375d47a0a1461077657610315565b806343756e5c1161028657806343756e5c14610576578063493279b11461058b5780634bf6c8821461031a57806350432d32146105b757806351e80672146105cc57806359b92789146105e157610315565b8063077b8f351461031a5780630bee7a67146103455780631182b87514610373578063149d14d91461046d5780633d713223146104945780633dffc3871461056157610315565b36610315573415610313576040805133815234602082015281517f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db929181900390910190a15b005b600080fd5b34801561032657600080fd5b5061032f610c6b565b6040805160ff9092168252519081900360200190f35b34801561035157600080fd5b5061035a610c70565b6040805163ffffffff9092168252519081900360200190f35b34801561037f57600080fd5b506103f86004803603604081101561039657600080fd5b60ff8235169190810190604081016020820135600160201b8111156103ba57600080fd5b8201836020820111156103cc57600080fd5b803590602001918460018302840111600160201b831117156103ed57600080fd5b509092509050610c75565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561043257818101518382015260200161041a565b50505050905090810190601f16801561045f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561047957600080fd5b50610482610da3565b60408051918252519081900360200190f35b3480156104a057600080fd5b50610545600480360360208110156104b757600080fd5b810190602081018135600160201b8111156104d157600080fd5b8201836020820111156104e357600080fd5b803590602001918460018302840111600160201b8311171561050457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610da9945050505050565b604080516001600160a01b039092168252519081900360200190f35b34801561056d57600080fd5b5061032f610dcd565b34801561058257600080fd5b50610545610dd2565b34801561059757600080fd5b506105a0610dd8565b6040805161ffff9092168252519081900360200190f35b3480156105c357600080fd5b50610482610ddd565b3480156105d857600080fd5b50610545610de8565b3480156105ed57600080fd5b506105456004803603602081101561060457600080fd5b5035610dee565b6107236004803603608081101561062157600080fd5b810190602081018135600160201b81111561063b57600080fd5b82018360208201111561064d57600080fd5b803590602001918460208302840111600160201b8311171561066e57600080fd5b919390929091602081019035600160201b81111561068b57600080fd5b82018360208201111561069d57600080fd5b803590602001918460208302840111600160201b831117156106be57600080fd5b919390929091602081019035600160201b8111156106db57600080fd5b8201836020820111156106ed57600080fd5b803590602001918460208302840111600160201b8311171561070e57600080fd5b91935091503567ffffffffffffffff16610e09565b604080519115158252519081900360200190f35b34801561074357600080fd5b506105456112f1565b34801561075857600080fd5b5061032f6112f7565b34801561076d57600080fd5b506104826112fc565b34801561078257600080fd5b50610545611302565b34801561079757600080fd5b5061032f611308565b3480156107ac57600080fd5b50610313600480360360408110156107c357600080fd5b60ff8235169190810190604081016020820135600160201b8111156107e757600080fd5b8201836020820111156107f957600080fd5b803590602001918460018302840111600160201b8311171561081a57600080fd5b50909250905061130d565b34801561083157600080fd5b506103136004803603606081101561084857600080fd5b508035906001600160a01b036020820135169060400135611456565b34801561087057600080fd5b5061032f6114dc565b34801561088557600080fd5b506104826114e1565b34801561089a57600080fd5b50610482600480360360408110156108b157600080fd5b506001600160a01b0381351690602001356114ed565b3480156108d357600080fd5b50610545611611565b3480156108e857600080fd5b50610545611617565b3480156108fd57600080fd5b5061032f61161d565b34801561091257600080fd5b506104826004803603602081101561092957600080fd5b50356001600160a01b0316611622565b34801561094557600080fd5b50610723611634565b34801561095a57600080fd5b5061032f61163d565b6107236004803603608081101561097957600080fd5b5080356001600160a01b03908116916020810135909116906040810135906060013567ffffffffffffffff16611642565b3480156109b657600080fd5b5061035a61161d565b3480156109cb57600080fd5b50610313600480360360408110156109e257600080fd5b810190602081018135600160201b8111156109fc57600080fd5b820183602082011115610a0e57600080fd5b803590602001918460018302840111600160201b83111715610a2f57600080fd5b919390929091602081019035600160201b811115610a4c57600080fd5b820183602082011115610a5e57600080fd5b803590602001918460018302840111600160201b83111715610a7f57600080fd5b509092509050611d16565b348015610a9657600080fd5b50610482611f85565b348015610aab57600080fd5b5061031360048036036040811015610ac257600080fd5b50803590602001356001600160a01b0316611f8b565b348015610ae457600080fd5b50610482612001565b348015610af957600080fd5b5061048260048036036020811015610b1057600080fd5b50356001600160a01b031661200b565b348015610b2c57600080fd5b50610545612026565b348015610b4157600080fd5b5061031360048036036040811015610b5857600080fd5b60ff8235169190810190604081016020820135600160201b811115610b7c57600080fd5b820183602082011115610b8e57600080fd5b803590602001918460018302840111600160201b83111715610baf57600080fd5b50909250905061202c565b348015610bc657600080fd5b506105456120fc565b348015610bdb57600080fd5b50610313612102565b348015610bf057600080fd5b5061032f6121a2565b348015610c0557600080fd5b5061032f6121a7565b348015610c1a57600080fd5b506105456121ac565b348015610c2f57600080fd5b506103f860048036036020811015610c4657600080fd5b50356001600160a01b03166121b2565b348015610c6257600080fd5b506105456122d9565b600881565b606481565b60005460609060ff16610cbd576040805162461bcd60e51b815260206004820152601960248201526000805160206145c7833981519152604482015290519081900360640190fd5b3361200014610cfd5760405162461bcd60e51b815260040180806020018281038252602f815260200180614575602f913960400191505060405180910390fd5b60ff841660021415610d4f57610d4883838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506122df92505050565b9050610d9c565b6040805162461bcd60e51b815260206004820152601860248201527f756e7265636f676e697a65642073796e207061636b6167650000000000000000604482015290519081900360640190fd5b9392505050565b60015490565b6020818101516000908152600490915260409020546001600160a01b03165b919050565b600181565b61100181565b606181565b662386f26fc1000081565b61200081565b6000908152600460205260409020546001600160a01b031690565b6000805460ff16610e4f576040805162461bcd60e51b815260206004820152601960248201526000805160206145c7833981519152604482015290519081900360640190fd5b868514610e8d5760405162461bcd60e51b815260040180806020018281038252603b81526020018061453a603b913960400191505060405180910390fd5b868314610ecb5760405162461bcd60e51b815260040180806020018281038252603f81526020018061440d603f913960400191505060405180910390fd5b426078018267ffffffffffffffff161015610f175760405162461bcd60e51b81526004018080602001828103825260248152602001806142fd6024913960400191505060405180910390fd5b6402540be400340615610f5b5760405162461bcd60e51b815260040180806020018281038252604081526020018061463d6040913960400191505060405180910390fd5b60408051868152602080880282010190915285906000908190606090848015610f8e578160200160208202803683370190505b50905060005b84811015611069576402540be4008b8b83818110610fae57fe5b9050602002013581610fbc57fe5b0615610ff95760405162461bcd60e51b815260040180806020018281038252603c81526020018061444c603c913960400191505060405180910390fd5b61101e8b8b8381811061100857fe5b905060200201358561240390919063ffffffff16565b935061104a6402540be4008c8c8481811061103557fe5b9050602002013561245d90919063ffffffff16565b82828151811061105657fe5b6020908102919091010152600101610f94565b5060015461108e90611081908663ffffffff61249f16565b849063ffffffff61240316565b3410156110cc5760405162461bcd60e51b81526004018080602001828103825260568152602001806145e76056913960600191505060405180910390fd5b6110dc348463ffffffff6124f816565b91506110e6614156565b6040518060c001604052806221272160e91b60001b815260200160006001600160a01b031681526020018381526020018e8e808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050908252506040805160208c810282810182019093528c82529283019290918d918d91829185019084908082843760009201919091525050509082525067ffffffffffffffff8916602090910152905061200063f7a251d760036111aa8461253a565b6111bf876402540be40063ffffffff61245d16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561121d578181015183820152602001611205565b50505050905090810190601f16801561124a5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b15801561126b57600080fd5b505af115801561127f573d6000803e3d6000fd5b505050506040513d602081101561129557600080fd5b505060408051600081523360208201528082018690526060810185905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9181900360800190a15060019c9b505050505050505050505050565b61100581565b600281565b60015481565b61100881565b600b81565b60005460ff16611352576040805162461bcd60e51b815260206004820152601960248201526000805160206145c7833981519152604482015290519081900360640190fd5b33612000146113925760405162461bcd60e51b815260040180806020018281038252602f815260200180614575602f913960400191505060405180910390fd5b60ff8316600314156113e2576113dd82828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506127f592505050565b611451565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a15b505050565b33611008146114965760405162461bcd60e51b81526004018080602001828103825260238152602001806145a46023913960400191505060405180910390fd5b600083815260046020908152604080832080546001600160a01b039096166001600160a01b03199096168617905593825260038152838220949094556002909352912055565b600981565b677ce66c50e284000081565b6000805460ff16611533576040805162461bcd60e51b815260206004820152601960248201526000805160206145c7833981519152604482015290519081900360640190fd5b33611005146115735760405162461bcd60e51b815260040180806020018281038252602f815260200180614270602f913960400191505060405180910390fd5b60004783106115825747611584565b825b90508015611608576040516001600160a01b0385169082156108fc029083906000818181858888f193505050501580156115c2573d6000803e3d6000fd5b50604080516001600160a01b03861681526020810183905281517ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0929181900390910190a15b90505b92915050565b61100781565b61100681565b600081565b60026020526000908152604090205481565b60005460ff1681565b600381565b6000805460ff16611688576040805162461bcd60e51b815260206004820152601960248201526000805160206145c7833981519152604482015290519081900360640190fd5b426078018267ffffffffffffffff1610156116d45760405162461bcd60e51b81526004018080602001828103825260248152602001806142fd6024913960400191505060405180910390fd5b6402540be4003406156117185760405162461bcd60e51b815260040180806020018281038252604081526020018061463d6040913960400191505060405180910390fd5b600080806001600160a01b0388166117f75760015461173e90879063ffffffff61240316565b34101561177c5760405162461bcd60e51b81526004018080602001828103825260618152602001806143876061913960800191505060405180910390fd5b6402540be4008606156117c05760405162461bcd60e51b815260040180806020018281038252603c81526020018061444c603c913960400191505060405180910390fd5b6117d0348763ffffffff6124f816565b90506117e7866402540be40063ffffffff61245d16565b6221272160e91b93509150611a9a565b6001600160a01b03881660009081526003602052604090205492508261184e5760405162461bcd60e51b81526004018080602001828103825260318152602001806143566031913960400191505060405180910390fd5b60015434101561188f5760405162461bcd60e51b815260040180806020018281038252603f8152602001806144a9603f913960400191505060405180910390fd5b506001600160a01b03871660009081526002602052604090205434906008811115806118da57506008811180156118da57506118d8876007198301600a0a63ffffffff61285116565b155b6119155760405162461bcd60e51b815260040180806020018281038252603c81526020018061444c603c913960400191505060405180910390fd5b61191f8782612893565b925061192a846128d3565b15611972576305f5e1008310156119725760405162461bcd60e51b815260040180806020018281038252603a81526020018061429f603a913960400191505060405180910390fd5b60088110158061198c575060088110801561198c57508683115b6119c75760405162461bcd60e51b81526004018080602001828103825260258152602001806143e86025913960400191505060405180910390fd5b677ce66c50e2840000831115611a0e5760405162461bcd60e51b81526004018080602001828103825260358152602001806143216035913960400191505060405180910390fd5b604080516323b872dd60e01b81523360048201523060248201526044810189905290516001600160a01b038b16916323b872dd9160648083019260209291908290030181600087803b158015611a6357600080fd5b505af1158015611a77573d6000803e3d6000fd5b505050506040513d6020811015611a8d57600080fd5b5051611a9857600080fd5b505b611aa2614156565b6040805160c0810182528581526001600160a01b038b166020820152815160018082528184018452919283019181602001602082028036833750505081526040805160018082528183019092526020928301929091908083019080368337505050815260408051600180825281830190925260209283019290919080830190803683370190505081526020018767ffffffffffffffff168152509050828160400151600081518110611b5057fe5b602002602001018181525050878160600151600081518110611b6e57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050338160800151600081518110611ba057fe5b6001600160a01b039092166020928302919091019091015261200063f7a251d76003611bcb8461253a565b611be0866402540be40063ffffffff61245d16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611c3e578181015183820152602001611c26565b50505050905090810190601f168015611c6b5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b158015611c8c57600080fd5b505af1158015611ca0573d6000803e3d6000fd5b505050506040513d6020811015611cb657600080fd5b5050604080516001600160a01b038b1681523360208201528082018990526060810184905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9181900360800190a150600198975050505050505050565b3361100714611d565760405162461bcd60e51b815260040180806020018281038252602e8152602001806144e8602e913960400191505060405180910390fd5b60208114611dab576040805162461bcd60e51b815260206004820152601b60248201527f65787065637465642076616c7565206c656e6774682069732033320000000000604482015290519081900360640190fd5b606084848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8801819004810282018101909252868152939450606093925086915085908190840183828082843760009201919091525050505060208301519091506772656c617946656560c01b811415611eb3576020820151670de0b6b3a76400008111158015611e5a57506402540be4008106155b611eab576040805162461bcd60e51b815260206004820152601960248201527f7468652072656c6179466565206f7574206f662072616e676500000000000000604482015290519081900360640190fd5b600155611ef0565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a878787876040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050505050565b61c35081565b3361100814611fcb5760405162461bcd60e51b81526004018080602001828103825260238152602001806145a46023913960400191505060405180910390fd5b600091825260046020908152604080842080546001600160a01b03191690556001600160a01b0392909216835260039052812055565b6221272160e91b81565b6001600160a01b031660009081526003602052604090205490565b61100281565b60005460ff16612071576040805162461bcd60e51b815260206004820152601960248201526000805160206145c7833981519152604482015290519081900360640190fd5b33612000146120b15760405162461bcd60e51b815260040180806020018281038252602f815260200180614575602f913960400191505060405180910390fd5b60ff8316600314156113e2576113dd82828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506129d992505050565b61100381565b60005460ff161561215a576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b662386f26fc1000060019081556000808052600260205260127fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b55805460ff19169091179055565b600481565b600581565b61100081565b6001600160a01b03811660009081526003602090815260409182902054825182815280840190935260609290918391906020820181803683375050506020810183905290506000805b60208160ff16101561224257828160ff168151811061221657fe5b01602001516001600160f81b031916156122355760019091019061223a565b612242565b6001016121fb565b5060608160ff166040519080825280601f01601f191660200182016040528015612273576020820181803683370190505b50905060005b8260ff168160ff1610156122cf57838160ff168151811061229657fe5b602001015160f81c60f81b828260ff16815181106122b057fe5b60200101906001600160f81b031916908160001a905350600101612279565b5095945050505050565b61100481565b60606122e96141a2565b60006122f484612ad7565b915091508061234a576040805162461bcd60e51b815260206004820152601f60248201527f756e7265636f676e697a6564207472616e73666572496e207061636b61676500604482015290519081900360640190fd5b600061235583612c16565b905063ffffffff8116156123e9576040808401516020808601516001600160a01b031660009081526002909152918220546123909190612893565b905061239a6141d7565b60405180608001604052808660000151815260200183815260200186608001516001600160a01b031681526020018463ffffffff1681525090506123dd81612f2e565b95505050505050610dc8565b50506040805160008152602081019091529150610dc89050565b600082820183811015611608576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600061160883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061300a565b6000826124ae5750600061160b565b828202828482816124bb57fe5b04146116085760405162461bcd60e51b81526004018080602001828103825260218152602001806144886021913960400191505060405180910390fd5b600061160883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506130ac565b60408051600680825260e08201909252606091829190816020015b6060815260200190600190039081612555575050835190915061257790613106565b8160008151811061258457fe5b60200260200101819052506125a583602001516001600160a01b0316613119565b816001815181106125b257fe5b6020026020010181905250600083604001515190506060816040519080825280602002602001820160405280156125fd57816020015b60608152602001906001900390816125e85790505b50905060005b8281101561264a5761262b8660400151828151811061261e57fe5b6020026020010151613106565b82828151811061263757fe5b6020908102919091010152600101612603565b506126548161313c565b8360028151811061266157fe5b60200260200101819052506060826040519080825280602002602001820160405280156126a257816020015b606081526020019060019003908161268d5790505b50905060005b838110156126f8576126d9876060015182815181106126c357fe5b60200260200101516001600160a01b0316613119565b8282815181106126e557fe5b60209081029190910101526001016126a8565b506127028161313c565b8460038151811061270f57fe5b602002602001018190525060608360405190808252806020026020018201604052801561275057816020015b606081526020019060019003908161273b5790505b50905060005b8481101561279057612771886080015182815181106126c357fe5b82828151811061277d57fe5b6020908102919091010152600101612756565b5061279a8161313c565b856004815181106127a757fe5b60200260200101819052506127c98760a0015167ffffffffffffffff16613106565b856005815181106127d657fe5b60200260200101819052506127ea8561313c565b979650505050505050565b6127fd6141fe565b6000612808836131c6565b91509150806128485760405162461bcd60e51b81526004018080602001828103825260248152602001806145166024913960400191505060405180910390fd5b61145182613391565b600061160883836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f00000000000000008152506137e2565b600060088211156128bc576128b5836007198401600a0a63ffffffff61245d16565b905061160b565b611608836008849003600a0a63ffffffff61249f16565b604080516020808252818301909252600091606091906020820181803683375050506020810184905290506000805b60208160ff16101561294957828160ff168151811061291d57fe5b01602001516001600160f81b0319161561293c57600190910190612941565b612949565b600101612902565b50600860ff8216101561296157600092505050610dc8565b816005820360ff168151811061297357fe5b6020910101516001600160f81b031916602d60f81b1461299857600092505050610dc8565b816001820360ff16815181106129aa57fe5b6020910101516001600160f81b031916604d60f81b146129cf57600092505050610dc8565b5060019392505050565b6129e1614156565b60006129ec83613844565b9150915080612a2c5760405162461bcd60e51b81526004018080602001828103825260248152602001806142d96024913960400191505060405180910390fd5b612a346141fe565b602080840180516001600160a01b0390811684526040808701518585015291511660009081526002909252812054905b846040015151811015612ab557612a9285604001518281518110612a8457fe5b602002602001015183613abf565b85604001518281518110612aa257fe5b6020908102919091010152600101612a64565b506080840151604083015260056060830152612ad082613391565b5050505050565b612adf6141a2565b6000612ae96141a2565b612af1614235565b612b02612afd86613af8565b613b1d565b90506000805b612b1183613b67565b15612c095780612b3357612b2c612b2784613b88565b613bd6565b8452612c01565b8060011415612b6057612b4d612b4884613b88565b613c36565b6001600160a01b03166020850152612c01565b8060021415612b7f57612b75612b2784613b88565b6040850152612c01565b8060031415612ba757612b94612b4884613b88565b6001600160a01b03166060850152612c01565b8060041415612bcf57612bbc612b4884613b88565b6001600160a01b03166080850152612c01565b8060051415612bfc57612be4612b2784613b88565b67ffffffffffffffff1660a085015260019150612c01565b612c09565b600101612b08565b5091935090915050915091565b60208101516000906001600160a01b0316612d18578160a0015167ffffffffffffffff16421115612c4957506001610dc8565b8160400151471015612c5d57506003610dc8565b81606001516001600160a01b03166108fc83604001519081150290604051600060405180830381858888f19350505050612c9957506004610dc8565b7f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5982602001518360600151846040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a1506000610dc8565b8160a0015167ffffffffffffffff16421115612d3657506001610dc8565b81516020808401516001600160a01b031660009081526003909152604090205414612d6357506002610dc8565b602080830151604080516370a0823160e01b815230600482015290516000936001600160a01b03909316926370a082319261c3509260248083019392829003018187803b158015612db357600080fd5b5086fa158015612dc7573d6000803e3d6000fd5b50505050506040513d6020811015612dde57600080fd5b50516040840151909150811015612df9575060039050610dc8565b600083602001516001600160a01b031663a9059cbb61c350866060015187604001516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b158015612e6a57600080fd5b5087f1158015612e7e573d6000803e3d6000fd5b50505050506040513d6020811015612e9557600080fd5b505190508015612f22577f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5984602001518560600151866040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a15060009150610dc89050565b5060059150610dc89050565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081612f495750508351909150612f6b90613106565b81600081518110612f7857fe5b6020026020010181905250612f908360200151613106565b81600181518110612f9d57fe5b6020026020010181905250612fbe83604001516001600160a01b0316613119565b81600281518110612fcb57fe5b6020026020010181905250612fe9836060015163ffffffff16613106565b81600381518110612ff657fe5b6020026020010181905250610d9c8161313c565b600081836130965760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561305b578181015183820152602001613043565b50505050905090810190601f1680156130885780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816130a257fe5b0495945050505050565b600081848411156130fe5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561305b578181015183820152602001613043565b505050900390565b606061160b61311483613c50565b613d36565b60408051600560a21b8318601482015260348101909152606090610d9c81613d36565b606081516000141561315d5750604080516000815260208101909152610dc8565b60608260008151811061316c57fe5b602002602001015190506000600190505b83518110156131ad576131a38285838151811061319657fe5b6020026020010151613d88565b915060010161317d565b50610d9c6131c0825160c060ff16613e05565b82613d88565b6131ce6141fe565b60006131d86141fe565b6131e0614235565b6131ec612afd86613af8565b90506000805b6131fb83613b67565b15612c09578061322157613211612b4884613b88565b6001600160a01b03168452613389565b80600114156132c257606061323d61323885613b88565b613efd565b9050805160405190808252806020026020018201604052801561326a578160200160208202803683370190505b50602086015260005b81518110156132bb5761329882828151811061328b57fe5b6020026020010151613bd6565b866020015182815181106132a857fe5b6020908102919091010152600101613273565b5050613389565b80600214156133645760606132d961323885613b88565b90508051604051908082528060200260200182016040528015613306578160200160208202803683370190505b50604086015260005b81518110156132bb5761333482828151811061332757fe5b6020026020010151613c36565b8660400151828151811061334457fe5b6001600160a01b039092166020928302919091019091015260010161330f565b8060031415612bfc57613379612b2784613b88565b63ffffffff166060850152600191505b6001016131f2565b80516001600160a01b03166135885760005b81602001515181101561358257816040015181815181106133c057fe5b60200260200101516001600160a01b03166108fc836020015183815181106133e457fe5b60200260200101519081150290604051600060405180830381858888f193505050506134c4577f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e82600001518360400151838151811061344057fe5b60200260200101518460200151848151811061345857fe5b6020026020010151856060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a161357a565b7fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a8260000151836040015183815181106134fa57fe5b60200260200101518460200151848151811061351257fe5b6020026020010151856060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b6001016133a3565b506137df565b60005b8160200151518110156137dd57600082600001516001600160a01b031663a9059cbb61c350856040015185815181106135c057fe5b6020026020010151866020015186815181106135d857fe5b60200260200101516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b15801561362f57600080fd5b5087f1158015613643573d6000803e3d6000fd5b50505050506040513d602081101561365a57600080fd5b50519050801561371e577fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a83600001518460400151848151811061369a57fe5b6020026020010151856020015185815181106136b257fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a16137d4565b7f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e83600001518460400151848151811061375457fe5b60200260200101518560200151858151811061376c57fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b5060010161358b565b505b50565b600081836138315760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561305b578181015183820152602001613043565b5082848161383b57fe5b06949350505050565b61384c614156565b6000613856614156565b61385e614235565b61386a612afd86613af8565b90506000805b61387983613b67565b15613ab157806138965761388f612b2784613b88565b8452613aa9565b80600114156138be576138ab612b4884613b88565b6001600160a01b03166020850152613aa9565b806002141561394d5760606138d561323885613b88565b90508051604051908082528060200260200182016040528015613902578160200160208202803683370190505b50604086015260005b81518110156139465761392382828151811061328b57fe5b8660400151828151811061393357fe5b602090810291909101015260010161390b565b5050613aa9565b80600314156139e257606061396461323885613b88565b90508051604051908082528060200260200182016040528015613991578160200160208202803683370190505b50606086015260005b8151811015613946576139b282828151811061332757fe5b866060015182815181106139c257fe5b6001600160a01b039092166020928302919091019091015260010161399a565b8060041415613a775760606139f961323885613b88565b90508051604051908082528060200260200182016040528015613a26578160200160208202803683370190505b50608086015260005b815181101561394657613a4782828151811061332757fe5b86608001518281518110613a5757fe5b6001600160a01b0390921660209283029190910190910152600101613a2f565b8060051415613aa457613a8c612b2784613b88565b67ffffffffffffffff1660a085015260019150613aa9565b613ab1565b600101613870565b509195600195509350505050565b60006008821115613ae1576128b5836007198401600a0a63ffffffff61249f16565b611608836008849003600a0a63ffffffff61245d16565b613b00614255565b506040805180820190915281518152602082810190820152919050565b613b25614235565b613b2e82613fce565b613b3757600080fd5b6000613b468360200151613ffe565b60208085015160408051808201909152868152920190820152915050919050565b6000613b71614255565b505080518051602091820151919092015191011190565b613b90614255565b613b9982613b67565b613ba257600080fd5b60208201516000613bb282614061565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590613beb57508151602110155b613bf457600080fd5b6000613c038360200151613ffe565b83516020808601518301805193945091849003929190831015613c2d57826020036101000a820491505b50949350505050565b8051600090601514613c4757600080fd5b61160b82613bd6565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416613c9457506018613cb8565b6fffffffffffffffffffffffffffffffff198416613cb457506010613cb8565b5060005b6020811015613cee57818181518110613ccd57fe5b01602001516001600160f81b03191615613ce657613cee565b600101613cb8565b60008160200390506060816040519080825280601f01601f191660200182016040528015613d23576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015613d685750607f60f81b82600081518110613d5657fe5b01602001516001600160f81b03191611155b15613d74575080610dc8565b61160b613d868351608060ff16613e05565b835b6060806040519050835180825260208201818101602087015b81831015613db9578051835260209283019201613da1565b50855184518101855292509050808201602086015b81831015613de6578051835260209283019201613dce565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310613e55576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411613eaf5782840160f81b81600081518110613e9157fe5b60200101906001600160f81b031916908160001a905350905061160b565b6060613eba85613c50565b90508381510160370160f81b82600081518110613ed357fe5b60200101906001600160f81b031916908160001a905350613ef48282613d88565b95945050505050565b6060613f0882613fce565b613f1157600080fd5b6000613f1c836140fa565b9050606081604051908082528060200260200182016040528015613f5a57816020015b613f47614255565b815260200190600190039081613f3f5790505b5090506000613f6c8560200151613ffe565b60208601510190506000805b84811015613fc357613f8983614061565b9150604051806040016040528083815260200184815250848281518110613fac57fe5b602090810291909101015291810191600101613f78565b509195945050505050565b8051600090613fdf57506000610dc8565b6020820151805160001a9060c08210156129cf57600092505050610dc8565b8051600090811a6080811015614018576000915050610dc8565b60b8811080614033575060c08110801590614033575060f881105b15614042576001915050610dc8565b60c08110156140565760b519019050610dc8565b60f519019050610dc8565b80516000908190811a608081101561407c57600191506140f3565b60b881101561409157607e19810191506140f3565b60c08110156140be5760b78103600185019450806020036101000a855104600182018101935050506140f3565b60f88110156140d35760be19810191506140f3565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b805160009061410b57506000610dc8565b6000809050600061411f8460200151613ffe565b602085015185519181019250015b8082101561414d5761413e82614061565b6001909301929091019061412d565b50909392505050565b6040518060c001604052806000801916815260200160006001600160a01b03168152602001606081526020016060815260200160608152602001600067ffffffffffffffff1681525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b60408051608081018252600080825260208201819052918101829052606081019190915290565b604051806080016040528060006001600160a01b031681526020016060815260200160608152602001600063ffffffff1681525090565b6040518060400160405280614248614255565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe746865206d6573736167652073656e646572206d75737420626520696e63656e746976697a6520636f6e7472616374466f72206d696e69546f6b656e2c20746865207472616e7366657220616d6f756e74206d757374206e6f74206265206c657373207468616e2031756e7265636f676e697a6564207472616e736665724f75742073796e207061636b61676565787069726554696d65206d7573742062652074776f206d696e75746573206c61746572616d6f756e7420697320746f6f206c617267652c20657863656564206d6178696d756d206265703220746f6b656e20616d6f756e7474686520636f6e747261637420686173206e6f74206265656e20626f756e6420746f20616e79206265703220746f6b656e726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e736665724f757420424e4220616d6f756e7420616e64206d696e696d756d2072656c6179466565616d6f756e7420697320746f6f206c617267652c2075696e74323536206f766572666c6f774c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620726566756e644164647273696e76616c6964207472616e7366657220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e20746865206d696e696d756d2072656c6179466565746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374756e7265636f676e697a6564207472616e736665724f75742061636b207061636b6167654c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620616d6f756e7473746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d73672073656e646572206d75737420626520746f6b656e4d616e6167657274686520636f6e7472616374206e6f7420696e69742079657400000000000000726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e7366657220424e4220616d6f756e7420616e642072656c6179466565696e76616c696420726563656976656420424e4220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6ea2646970667358221220ee0772c728608488e6a5f5dfa5f29f8c4467aea7333c447ace15be38f4600ff464736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001005": { + "balance": "0x0", + "code": "0x6080604052600436106102605760003560e01c80637942fd0511610144578063ac431751116100b6578063dc927faf1161007a578063dc927faf1461076a578063dcae76ab1461077f578063e1c7392a14610794578063f9a2bbc7146107a9578063fc3e5908146107be578063fd6a6879146107d357610267565b8063ac43175114610630578063af40068114610701578063bd4cc8301461072b578063c7d2b028146102eb578063c81b16621461075557610267565b8063a1a11bf511610108578063a1a11bf5146105b2578063a3c3c0ad146105c7578063a413aff6146105dc578063a60d770b146105f1578063a78abc1614610606578063ab51bb961461061b57610267565b80637942fd051461052b57806387c1830a14610540578063930e1b091461055557806396713da9146105885780639dc092621461059d57610267565b806343756e5c116101dd57806354133307116101a15780635413330714610445578063572120951461045a5780636e47b4821461048d5780636f93d2e6146104a257806370fd5bad1461050157806375d47a0a1461051657610267565b806343756e5c146103b0578063490dfdf7146103c5578063493279b1146103ef5780634bf6c8821461041b57806351e806721461043057610267565b8063189d817211610224578063189d8172146103005780631b20087c146103155780631c6433121461032a5780633dffc3871461037057806341b5f4e51461039b57610267565b806308f2ec061461026c5780630bee7a67146102935780630c732068146102c157806310e06a76146102d6578063117048d8146102eb57610267565b3661026757005b600080fd5b34801561027857600080fd5b506102816107e8565b60408051918252519081900360200190f35b34801561029f57600080fd5b506102a86107ee565b6040805163ffffffff9092168252519081900360200190f35b3480156102cd57600080fd5b506102816107f3565b3480156102e257600080fd5b506102816107f9565b3480156102f757600080fd5b506102816107ff565b34801561030c57600080fd5b50610281610804565b34801561032157600080fd5b5061028161080a565b34801561033657600080fd5b506103546004803603602081101561034d57600080fd5b5035610810565b604080516001600160a01b039092168252519081900360200190f35b34801561037c57600080fd5b506103856107ff565b6040805160ff9092168252519081900360200190f35b3480156103a757600080fd5b50610281610837565b3480156103bc57600080fd5b5061035461083c565b3480156103d157600080fd5b50610354600480360360208110156103e857600080fd5b5035610842565b3480156103fb57600080fd5b5061040461084f565b6040805161ffff9092168252519081900360200190f35b34801561042757600080fd5b50610385610854565b34801561043c57600080fd5b50610354610859565b34801561045157600080fd5b5061028161085f565b34801561046657600080fd5b506102816004803603602081101561047d57600080fd5b50356001600160a01b0316610865565b34801561049957600080fd5b50610354610877565b3480156104ae57600080fd5b506104ed600480360360808110156104c557600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135151561087d565b604080519115158252519081900360200190f35b34801561050d57600080fd5b50610385610c21565b34801561052257600080fd5b50610354610c26565b34801561053757600080fd5b50610385610c2c565b34801561054c57600080fd5b50610281610c31565b34801561056157600080fd5b506102816004803603602081101561057857600080fd5b50356001600160a01b0316610c37565b34801561059457600080fd5b50610385610c49565b3480156105a957600080fd5b50610354610c4e565b3480156105be57600080fd5b50610354610c54565b3480156105d357600080fd5b50610281610c5a565b3480156105e857600080fd5b50610281610c60565b3480156105fd57600080fd5b50610281610c66565b34801561061257600080fd5b506104ed610c6b565b34801561062757600080fd5b506102a8610c74565b34801561063c57600080fd5b506106ff6004803603604081101561065357600080fd5b81019060208101813564010000000081111561066e57600080fd5b82018360208201111561068057600080fd5b803590602001918460018302840111640100000000831117156106a257600080fd5b9193909290916020810190356401000000008111156106c057600080fd5b8201836020820111156106d257600080fd5b803590602001918460018302840111640100000000831117156106f457600080fd5b509092509050610c79565b005b34801561070d57600080fd5b506102816004803603602081101561072457600080fd5b5035611237565b34801561073757600080fd5b506102816004803603602081101561074e57600080fd5b5035611299565b34801561076157600080fd5b506103546112b4565b34801561077657600080fd5b506103546112ba565b34801561078b57600080fd5b506102816112c0565b3480156107a057600080fd5b506106ff6112c6565b3480156107b557600080fd5b5061035461138f565b3480156107ca57600080fd5b50610385611395565b3480156107df57600080fd5b5061035461139a565b61019081565b606481565b60035481565b600b5481565b600181565b60045481565b600c5481565b6006818154811061081d57fe5b6000918252602090912001546001600160a01b0316905081565b605081565b61100181565b6008818154811061081d57fe5b606181565b600881565b61200081565b6103e881565b60076020526000908152604090205481565b61100581565b6000805460ff166108d5576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604482015290519081900360640190fd5b33612000146109155760405162461bcd60e51b815260040180806020018281038252602f815260200180611d2b602f913960400191505060405180910390fd5b6000821561099a57604080516309a99b4f60e41b8152611005600482015260248101869052905161100291639a99b4f09160448083019260209291908290030181600087803b15801561096757600080fd5b505af115801561097b573d6000803e3d6000fd5b505050506040513d602081101561099157600080fd5b50519050610a13565b604080516309a99b4f60e41b8152611005600482015260248101869052905161100491639a99b4f09160448083019260209291908290030181600087803b1580156109e457600080fd5b505af11580156109f8573d6000803e3d6000fd5b505050506040513d6020811015610a0e57600080fd5b505190505b600c805460010190556000610a27826113a0565b600954909150610a3d908263ffffffff6113cf16565b600955600a54610a65908290610a59908563ffffffff6113cf16565b9063ffffffff61143016565b600a556001600160a01b038716600090815260056020526040902054610ad157600680546001810182556000919091527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0180546001600160a01b0319166001600160a01b0389161790555b6001600160a01b038088166000908152600560209081526040808320805460010190559289168252600790522054610b4f57600880546001810182556000919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30180546001600160a01b0319166001600160a01b0388161790555b6001600160a01b038616600090815260076020526040902080546001019055600c546103e81415610c1457600b54600954600a5460408051938452602084019290925282820152517f127fd0fd1fcf84c71c5c649625ef186be105a71ecc80c7cb3f96cd99ccae1e0f9181900360600190a1610bca86611472565b610bd38661171f565b6040516110029081904780156108fc02916000818181858888f19350505050158015610c03573d6000803e3d6000fd5b5050600b805460010190556000600c555b5060019695505050505050565b600281565b61100881565b600b81565b60015481565b60056020526000908152604090205481565b600981565b61100781565b61100681565b600a5481565b60025481565b600581565b60005460ff1681565b600081565b3361100714610cb95760405162461bcd60e51b815260040180806020018281038252602e815260200180611cdc602e913960400191505060405180910390fd5b60005460ff16610cfa5760405162461bcd60e51b8152600401808060200182810382526021815260200180611d0a6021913960400191505060405180910390fd5b610d6684848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601581527436b7b632b1bab632a432b0b232b92932b630bcb2b960591b6020820152915061199f9050565b15610df15760208114610daa5760405162461bcd60e51b8152600401808060200182810382526028815260200180611c656028913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610de891858580838501838280828437600092019190915250611a8692505050565b600155506111a5565b610e6584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601881527f64656e6f6d696e61746f7248656164657252656c6179657200000000000000006020820152915061199f9050565b15610f2d5760208114610ea95760405162461bcd60e51b815260040180806020018281038252602e815260200180611c8d602e913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610ee791858580838501838280828437600092019190915250611a8692505050565b905080610f255760405162461bcd60e51b8152600401808060200182810382526030815260200180611d5a6030913960400191505060405180910390fd5b6002556111a5565b610fa184848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601a81527f6d6f6c6563756c6543616c6c6572436f6d70656e736174696f6e0000000000006020820152915061199f9050565b1561102c5760208114610fe55760405162461bcd60e51b815260040180806020018281038252602e815260200180611c8d602e913960400191505060405180910390fd5b604080516020601f840181900481028201810190925282815260009161102391858580838501838280828437600092019190915250611a8692505050565b600355506111a5565b6110a084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601d81527f64656e6f6d696e61746f7243616c6c6572436f6d70656e736174696f6e0000006020820152915061199f9050565b1561116857602081146110e45760405162461bcd60e51b815260040180806020018281038252602e815260200180611c8d602e913960400191505060405180910390fd5b604080516020601f840181900481028201810190925282815260009161112291858580838501838280828437600092019190915250611a8692505050565b9050806111605760405162461bcd60e51b8152600401808060200182810382526035815260200180611d8a6035913960400191505060405180910390fd5b6004556111a5565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b60006101908211611249575080611294565b8161019010801561125c57506103208211155b1561126a5750610190611294565b6103208211801561127d575061044c8211155b1561128e57506104b0819003611294565b50600481045b919050565b600061019082116112ab575080611294565b50610190611294565b61100281565b61100381565b60095481565b60005460ff161561131e576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b60005460ff161561136c576040805162461bcd60e51b8152602060048201526013602482015272185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604482015290519081900360640190fd5b60018080556005600255600381905560506004556000805460ff19169091179055565b61100081565b600381565b61100481565b60006113c96002546113bd60015485611a8b90919063ffffffff16565b9063ffffffff611ae416565b92915050565b600082820183811015611429576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b600061142983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611b26565b600954600680546040805160208084028201810190925282815260009360609391929091908301828280156114d057602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116114b2575b5050505050905060608151604051908082528060200260200182016040528015611504578160200160208202803683370190505b50905060005b825181101561159157600083828151811061152157fe5b60200260200101519050600061155b60056000846001600160a01b03166001600160a01b0316815260200190815260200160002054611299565b90508084848151811061156a57fe5b6020908102919091010152611585868263ffffffff6113cf16565b9550505060010161150a565b5060006115af6004546113bd60035488611a8b90919063ffffffff16565b90506115c1858263ffffffff61143016565b94508460015b84518110156116575760006115fc876113bd8a8886815181106115e657fe5b6020026020010151611a8b90919063ffffffff16565b905085828151811061160a57fe5b60200260200101516001600160a01b03166108fc829081150290604051600060405180830381858888f15061164c93508692508491505063ffffffff61143016565b9250506001016115c7565b508360008151811061166557fe5b60200260200101516001600160a01b03166108fc829081150290604051600060405180830381858888f150506040516001600160a01b038b16935085156108fc0292508591506000818181858888f1505060006009819055925050505b845181101561170957600560008683815181106116db57fe5b6020908102919091018101516001600160a01b031682528101919091526040016000908120556001016116c2565b5061171660066000611c22565b50505050505050565b600a546008805460408051602080840282018101909252828152600093606093919290919083018282801561177d57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161175f575b50505050509050606081516040519080825280602002602001820160405280156117b1578160200160208202803683370190505b50905060005b82518110156118305760008382815181106117ce57fe5b60200260200101519050600061180860076000846001600160a01b03166001600160a01b0316815260200190815260200160002054611237565b90508084848151811061181757fe5b60209081029190910101529490940193506001016117b7565b50600061184e6004546113bd60035488611a8b90919063ffffffff16565b9050611860858263ffffffff61143016565b94508460015b84518110156118e0576000611885876113bd8a8886815181106115e657fe5b905085828151811061189357fe5b60200260200101516001600160a01b03166108fc829081150290604051600060405180830381858888f1506118d593508692508491505063ffffffff61143016565b925050600101611866565b50836000815181106118ee57fe5b60200260200101516001600160a01b03166108fc829081150290604051600060405180830381858888f150506040516001600160a01b038b16935085156108fc0292508591506000818181858888f150506000600a819055925050505b8451811015611992576007600086838151811061196457fe5b6020908102919091018101516001600160a01b0316825281019190915260400160009081205560010161194b565b5061171660086000611c22565b6000816040516020018082805190602001908083835b602083106119d45780518252601f1990920191602091820191016119b5565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310611a425780518252601f199092019160209182019101611a23565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b600082611a9a575060006113c9565b82820282848281611aa757fe5b04146114295760405162461bcd60e51b8152600401808060200182810382526021815260200180611cbb6021913960400191505060405180910390fd5b600061142983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611bbd565b60008184841115611bb55760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611b7a578181015183820152602001611b62565b50505050905090810190601f168015611ba75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008183611c0c5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315611b7a578181015183820152602001611b62565b506000838581611c1857fe5b0495945050505050565b5080546000825590600052602060002090810190611c409190611c43565b50565b611c6191905b80821115611c5d5760008155600101611c49565b5090565b9056fe6c656e677468206f66206d6f6c6563756c6548656164657252656c61796572206d69736d617463686c656e677468206f6620726577617264466f7256616c696461746f725365744368616e6765206d69736d61746368536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374636f6e747261637420686173206e6f74206265656e20696e697469616c697a6564746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206e657744656e6f6d696e61746f7248656164657252656c61796572206d757374206e6f74206265207a65726f746865206e657744656e6f6d696e61746f7243616c6c6572436f6d70656e736174696f6e206d757374206e6f74206265207a65726fa26469706673582212202548a56b68ed51ad6e9a1aa43899b24ae5df4a24a9f594232fc5392c443544fb64736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001006": { + "balance": "0x0", + "code": "0x6080604052600436106101c25760003560e01c806395468d26116100f7578063c81b166211610095578063f9a2bbc711610064578063f9a2bbc714610529578063fb7cfdd71461053e578063fc3e590814610553578063fd6a687914610568576101c2565b8063c81b1662146104d5578063dc927faf146104ea578063e1c7392a146104ff578063e79a198f14610514576101c2565b8063a1a11bf5116100d1578063a1a11bf5146103c7578063a78abc16146103dc578063ab51bb96146103f1578063ac43175114610406576101c2565b806395468d261461038857806396713da91461039d5780639dc09262146103b2576101c2565b8063541d55481161016457806370fd5bad1161013e57806370fd5bad1461033457806375d47a0a146103495780637942fd051461035e5780637ae2308814610373576101c2565b8063541d5548146102b15780636a87d780146102f85780636e47b4821461031f576101c2565b806343756e5c116101a057806343756e5c1461022a578063493279b11461025b5780634bf6c8821461028757806351e806721461029c576101c2565b80630bee7a67146101c75780631aa3a008146101f55780633dffc387146101ff575b600080fd5b3480156101d357600080fd5b506101dc61057d565b6040805163ffffffff9092168252519081900360200190f35b6101fd610582565b005b34801561020b57600080fd5b50610214610733565b6040805160ff9092168252519081900360200190f35b34801561023657600080fd5b5061023f610738565b604080516001600160a01b039092168252519081900360200190f35b34801561026757600080fd5b5061027061073e565b6040805161ffff9092168252519081900360200190f35b34801561029357600080fd5b50610214610743565b3480156102a857600080fd5b5061023f610748565b3480156102bd57600080fd5b506102e4600480360360208110156102d457600080fd5b50356001600160a01b031661074e565b604080519115158252519081900360200190f35b34801561030457600080fd5b5061030d61076c565b60408051918252519081900360200190f35b34801561032b57600080fd5b5061023f610772565b34801561034057600080fd5b50610214610778565b34801561035557600080fd5b5061023f61077d565b34801561036a57600080fd5b50610214610783565b34801561037f57600080fd5b5061030d610788565b34801561039457600080fd5b5061030d610795565b3480156103a957600080fd5b506102146107a1565b3480156103be57600080fd5b5061023f6107a6565b3480156103d357600080fd5b5061023f6107ac565b3480156103e857600080fd5b506102e46107b2565b3480156103fd57600080fd5b506101dc6107bb565b34801561041257600080fd5b506101fd6004803603604081101561042957600080fd5b81019060208101813564010000000081111561044457600080fd5b82018360208201111561045657600080fd5b8035906020019184600183028401116401000000008311171561047857600080fd5b91939092909160208101903564010000000081111561049657600080fd5b8201836020820111156104a857600080fd5b803590602001918460018302840111640100000000831117156104ca57600080fd5b5090925090506107c0565b3480156104e157600080fd5b5061023f610bd6565b3480156104f657600080fd5b5061023f610bdc565b34801561050b57600080fd5b506101fd610be2565b34801561052057600080fd5b506101fd610c64565b34801561053557600080fd5b5061023f610e0b565b34801561054a57600080fd5b5061030d610e11565b34801561055f57600080fd5b50610214610e17565b34801561057457600080fd5b5061023f610e1c565b606481565b3360009081526004602052604090205460ff16156105df576040805162461bcd60e51b81526020600482015260156024820152741c995b185e595c88185b1c9958591e48195e1a5cdd605a1b604482015290519081900360640190fd5b60005460ff16610632576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b61063b33610e22565b156106775760405162461bcd60e51b8152600401808060200182810382526027815260200180610f546027913960400191505060405180910390fd5b60015434146106b75760405162461bcd60e51b8152600401808060200182810382526025815260200180610f2f6025913960400191505060405180910390fd5b604080518082018252600180548252600254602080840191825233600081815260038352868120955186559251948401949094556004815290849020805460ff1916909217909155825191825291517fdb33a09d38b59a8fa8b7d92a1d82c8015e99f05f67ae9c9ae623157767959496929181900390910190a1565b600181565b61100181565b606181565b600881565b61200081565b6001600160a01b031660009081526004602052604090205460ff1690565b60025481565b61100581565b600281565b61100881565b600b81565b68056bc75e2d6310000081565b67016345785d8a000081565b600981565b61100781565b61100681565b60005460ff1681565b600081565b60005460ff16610813576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b33611007146108535760405162461bcd60e51b815260040180806020018281038252602e815260200180610f7b602e913960400191505060405180910390fd5b6108b984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e1c995c5d5a5c995911195c1bdcda5d608a1b60208201529150610e289050565b156109b057602081146108fd5760405162461bcd60e51b8152600401808060200182810382526022815260200180610fa96022913960400191505060405180910390fd5b604080516020601f840181900481028201810190925282815260009161093b91858580838501838280828437600092019190915250610f0f92505050565b9050600181101580156109575750683635c9adc5dea000008111155b6109a8576040805162461bcd60e51b815260206004820181905260248201527f7468652072657175697265644465706f736974206f7574206f662072616e6765604482015290519081900360640190fd5b600155610b44565b610a0b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260048152636475657360e01b60208201529150610e289050565b15610b075760208114610a65576040805162461bcd60e51b815260206004820152601760248201527f6c656e677468206f662064756573206d69736d61746368000000000000000000604482015290519081900360640190fd5b604080516020601f8401819004810282018101909252828152600091610aa391858580838501838280828437600092019190915250610f0f92505050565b9050600081118015610ab6575060015481105b610aff576040805162461bcd60e51b81526020600482015260156024820152747468652064756573206f7574206f662072616e676560581b604482015290519081900360640190fd5b600255610b44565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b60005460ff1615610c3a576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b68056bc75e2d63100000600190815567016345785d8a00006002556000805460ff19169091179055565b3360009081526004602052604090205460ff16610cbf576040805162461bcd60e51b81526020600482015260146024820152731c995b185e595c88191bc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b60005460ff16610d12576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b610d1a610f14565b50336000818152600360209081526040808320815180830183528154808252600190920154938101849052915191949392900380156108fc0292909190818181858888f19350505050158015610d74573d6000803e3d6000fd5b50602081015160405161100291829181156108fc0291906000818181858888f19350505050158015610daa573d6000803e3d6000fd5b50336000818152600460209081526040808320805460ff191690556003825280832083815560010192909255815192835290517fd17202129b83db7880d6b9f25df81c58ad46f7e0e2c92236b1aa10663a4876679281900390910190a15050565b61100081565b60015481565b600381565b61100481565b3b151590565b6000816040516020018082805190602001908083835b60208310610e5d5780518252601f199092019160209182019101610e3e565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310610ecb5780518252601f199092019160209182019101610eac565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b60405180604001604052806000815260200160008152509056fe6465706f7369742076616c7565206973206e6f742065786163746c79207468652073616d65636f6e7472616374206973206e6f7420616c6c6f77656420746f20626520612072656c61796572746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662072657175697265644465706f736974206d69736d61746368a2646970667358221220fb9552ef120a66e5db5b423b7f53133dfd781b3274938e279792aad5d583b27564736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001007": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b506004361061018e5760003560e01c8063831d65d1116100de578063ab51bb9611610097578063dc927faf11610071578063dc927faf14610486578063f9a2bbc71461048e578063fc3e590814610496578063fd6a68791461049e5761018e565b8063ab51bb96146103fc578063c81b166214610404578063c8509d811461040c5761018e565b8063831d65d11461034457806396713da9146103c05780639ab1a373146103c85780639dc09262146103d0578063a1a11bf5146103d8578063a78abc16146103e05761018e565b8063493279b11161014b5780636e47b482116101255780636e47b4821461032457806370fd5bad1461032c57806375d47a0a146103345780637942fd051461033c5761018e565b8063493279b1146102f55780634bf6c8821461031457806351e806721461031c5761018e565b80630bee7a67146101935780631182b875146101b45780633a21baae146102a35780633dffc387146102ab57806343756e5c146102c95780634900c4ea146102ed575b600080fd5b61019b6104a6565b6040805163ffffffff9092168252519081900360200190f35b61022e600480360360408110156101ca57600080fd5b60ff82351691908101906040810160208201356401000000008111156101ef57600080fd5b82018360208201111561020157600080fd5b8035906020019184600183028401116401000000008311171561022357600080fd5b5090925090506104ab565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610268578181015183820152602001610250565b50505050905090810190601f1680156102955780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61019b61059a565b6102b361059f565b6040805160ff9092168252519081900360200190f35b6102d16105a4565b604080516001600160a01b039092168252519081900360200190f35b6102b36105aa565b6102fd6105af565b6040805161ffff9092168252519081900360200190f35b6102b36105b4565b6102d16105b9565b6102d16105bf565b6102b36105c5565b6102d16105ca565b6102b36105d0565b6103be6004803603604081101561035a57600080fd5b60ff823516919081019060408101602082013564010000000081111561037f57600080fd5b82018360208201111561039157600080fd5b803590602001918460018302840111640100000000831117156103b357600080fd5b5090925090506105d5565b005b6102b3610627565b61019b61062c565b6102d1610631565b6102d1610637565b6103e861063d565b604080519115158252519081900360200190f35b61019b6105aa565b6102d1610646565b6103be6004803603604081101561042257600080fd5b60ff823516919081019060408101602082013564010000000081111561044757600080fd5b82018360208201111561045957600080fd5b8035906020019184600183028401116401000000008311171561047b57600080fd5b50909250905061064c565b6102d1610683565b6102d1610689565b6102b361068f565b6102d1610694565b606481565b606033612000146104ed5760405162461bcd60e51b815260040180806020018281038252602f815260200180611276602f913960400191505060405180910390fd5b6104f5611211565b600061053685858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061069a92505050565b9150915080610552576105496064610760565b92505050610593565b600061055d836107ca565b905063ffffffff811661058457505060408051600081526020810190915291506105939050565b61058d81610760565b93505050505b9392505050565b606681565b600181565b61100181565b600081565b606181565b600881565b61200081565b61100581565b600281565b61100881565b600b81565b6040805162461bcd60e51b815260206004820152601e60248201527f7265636569766520756e65787065637465642061636b207061636b6167650000604482015290519081900360640190fd5b505050565b600981565b606581565b61100781565b61100681565b60005460ff1681565b61100281565b60405162461bcd60e51b81526004018080602001828103825260238152602001806112a56023913960400191505060405180910390fd5b61100381565b61100081565b600381565b61100481565b6106a2611211565b60006106ac611211565b6106b461123b565b6106c56106c086610b6b565b610b90565b90506000805b6106d483610bda565b1561075357806106f6576106ef6106ea84610bfb565b610c49565b845261074b565b80600114156107155761070b6106ea84610bfb565b602085015261074b565b80600214156107465761072f61072a84610bfb565b610cc2565b6001600160a01b031660408501526001915061074b565b610753565b6001016106cb565b5091935090915050915091565b604080516001808252818301909252606091829190816020015b606081526020019060019003908161077a5790505090506107a08363ffffffff16610ce2565b816000815181106107ad57fe5b60200260200101819052506107c181610cf5565b9150505b919050565b60006107d98260400151610d7f565b61084557604080516020808252601c908201527f74686520746172676574206973206e6f74206120636f6e7472616374000000008183015290517f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb29181900360600190a15060656107c5565b81604001516001600160a01b031663ac431751836000015184602001516040518363ffffffff1660e01b8152600401808060200180602001838103835285818151815260200191508051906020019080838360005b838110156108b257818101518382015260200161089a565b50505050905090810190601f1680156108df5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b838110156109125781810151838201526020016108fa565b50505050905090810190601f16801561093f5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561096057600080fd5b505af1925050508015610971575060015b610b63576040516000815260443d101561098d57506000610a2a565b60046000803e60005160e01c6308c379a081146109ae576000915050610a2a565b60043d036004833e81513d602482011167ffffffffffffffff821117156109da57600092505050610a2a565b808301805167ffffffffffffffff8111156109fc576000945050505050610a2a565b8060208301013d8601811115610a1a57600095505050505050610a2a565b601f01601f191660405250925050505b80610a355750610ad8565b7f70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb2816040518080602001828103825283818151815260200191508051906020019080838360005b83811015610a94578181015183820152602001610a7c565b50505050905090810190601f168015610ac15780820380516001836020036101000a031916815260200191505b509250505060405180910390a160669150506107c5565b3d808015610b02576040519150601f19603f3d011682016040523d82523d6000602084013e610b07565b606091505b5060408051602080825283518183015283517f1279f84165b4fd69c35e1f338ff107231b036c655cd1688851e011ce617c4e8d938593928392918301919085019080838360008315610a94578181015183820152602001610a7c565b506000919050565b610b7361125b565b506040805180820190915281518152602082810190820152919050565b610b9861123b565b610ba182610d85565b610baa57600080fd5b6000610bb98360200151610dbf565b60208085015160408051808201909152868152920190820152915050919050565b6000610be461125b565b505080518051602091820151919092015191011190565b610c0361125b565b610c0c82610bda565b610c1557600080fd5b60208201516000610c2582610e22565b80830160209586015260408051808201909152908152938401919091525090919050565b8051606090610c5757600080fd5b6000610c668360200151610dbf565b83516040805191839003808352601f19601f8201168301602001909152919250606090828015610c9d576020820181803683370190505b5090506000816020019050610cb9848760200151018285610ebb565b50949350505050565b8051600090601514610cd357600080fd5b610cdc82610f06565b92915050565b6060610cdc610cf083610f64565b61104a565b6060815160001415610d1657506040805160008152602081019091526107c5565b606082600081518110610d2557fe5b602002602001015190506000600190505b8351811015610d6657610d5c82858381518110610d4f57fe5b602002602001015161109c565b9150600101610d36565b506107c1610d79825160c060ff16611119565b8261109c565b3b151590565b8051600090610d96575060006107c5565b6020820151805160001a9060c0821015610db5576000925050506107c5565b5060019392505050565b8051600090811a6080811015610dd95760009150506107c5565b60b8811080610df4575060c08110801590610df4575060f881105b15610e035760019150506107c5565b60c0811015610e175760b5190190506107c5565b60f5190190506107c5565b80516000908190811a6080811015610e3d5760019150610eb4565b60b8811015610e5257607e1981019150610eb4565b60c0811015610e7f5760b78103600185019450806020036101000a85510460018201810193505050610eb4565b60f8811015610e945760be1981019150610eb4565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b80610ec557610622565b5b60208110610ee5578251825260209283019290910190601f1901610ec6565b915181516020939093036101000a6000190180199091169216919091179052565b805160009015801590610f1b57508151602110155b610f2457600080fd5b6000610f338360200151610dbf565b83516020808601518301805193945091849003929190831015610cb957506020919091036101000a90049392505050565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416610fa857506018610fcc565b6fffffffffffffffffffffffffffffffff198416610fc857506010610fcc565b5060005b602081101561100257818181518110610fe157fe5b01602001516001600160f81b03191615610ffa57611002565b600101610fcc565b60008160200390506060816040519080825280601f01601f191660200182016040528015611037576020820181803683370190505b5080830196909652508452509192915050565b60608151600114801561107c5750607f60f81b8260008151811061106a57fe5b01602001516001600160f81b03191611155b156110885750806107c5565b610cdc61109a8351608060ff16611119565b835b6060806040519050835180825260208201818101602087015b818310156110cd5780518352602092830192016110b5565b50855184518101855292509050808201602086015b818310156110fa5780518352602092830192016110e2565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310611169576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b604080516001808252818301909252606091602082018180368337019050509050603784116111c35782840160f81b816000815181106111a557fe5b60200101906001600160f81b031916908160001a9053509050610cdc565b60606111ce85610f64565b90508381510160370160f81b826000815181106111e757fe5b60200101906001600160f81b031916908160001a905350611208828261109c565b95945050505050565b6040518060600160405280606081526020016060815260200160006001600160a01b031681525090565b604051806040016040528061124e61125b565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e74726163747265636569766520756e6578706563746564206661696c2061636b207061636b616765a264697066735822122019628d70dd9ac62a7a85eb3f845d01808a095ab280a95e6dd5609e52788b4c5e64736f6c63430006040033" + }, + "0x0000000000000000000000000000000000001008": { + "balance": "0x0", + "code": "0x6080604052600436106102305760003560e01c806377d9dae81161012e578063c81b1662116100ab578063dc927faf1161006f578063dc927faf14610887578063f9a2bbc71461089c578063fc3e5908146107f1578063fd6a6879146108b1578063fe3a2af51461042457610230565b8063c81b1662146107dc578063c8509d81146106d7578063c8e704a4146107f1578063d117a11014610806578063dc6f5e90146107f157610230565b806396713da9116100f257806396713da9146107735780639dc0926214610788578063a1a11bf51461079d578063a78abc16146107b2578063ab51bb96146107c757610230565b806377d9dae81461060e5780637942fd05146106c25780637d078e13146103b2578063831d65d1146106d757806395b9ad261461075e57610230565b80634a688818116101bc5780636b3f1307116101805780636b3f1307146104785780636e47b4821461054057806370fd5bad1461046357806372c4e0861461055557806375d47a0a146105f957610230565b80634a688818146104245780634bc81c00146104395780634bf6c8821461023557806351e806721461044e5780635f558f861461046357610230565b80631f91600b116102035780631f91600b1461039d57806323996b53146103b25780633dffc387146103b257806343756e5c146103c7578063493279b1146103f857610230565b8063077b8f35146102355780630bee7a67146102605780630f212b1b1461028e5780631182b875146102a3575b600080fd5b34801561024157600080fd5b5061024a6108c6565b6040805160ff9092168252519081900360200190f35b34801561026c57600080fd5b506102756108cb565b6040805163ffffffff9092168252519081900360200190f35b34801561029a57600080fd5b5061024a6108d0565b3480156102af57600080fd5b50610328600480360360408110156102c657600080fd5b60ff8235169190810190604081016020820135600160201b8111156102ea57600080fd5b8201836020820111156102fc57600080fd5b803590602001918460018302840111600160201b8311171561031d57600080fd5b5090925090506108d5565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561036257818101518382015260200161034a565b50505050905090810190601f16801561038f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103a957600080fd5b5061024a61095e565b3480156103be57600080fd5b5061024a610963565b3480156103d357600080fd5b506103dc610968565b604080516001600160a01b039092168252519081900360200190f35b34801561040457600080fd5b5061040d61096e565b6040805161ffff9092168252519081900360200190f35b34801561043057600080fd5b5061024a610973565b34801561044557600080fd5b5061024a610978565b34801561045a57600080fd5b506103dc61097d565b34801561046f57600080fd5b5061024a610983565b61052c6004803603604081101561048e57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b8111156104b857600080fd5b8201836020820111156104ca57600080fd5b803590602001918460018302840111600160201b831117156104eb57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610988945050505050565b604080519115158252519081900360200190f35b34801561054c57600080fd5b506103dc61121e565b61052c6004803603602081101561056b57600080fd5b810190602081018135600160201b81111561058557600080fd5b82018360208201111561059757600080fd5b803590602001918460018302840111600160201b831117156105b857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611224945050505050565b34801561060557600080fd5b506103dc611683565b61052c6004803603604081101561062457600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561064e57600080fd5b82018360208201111561066057600080fd5b803590602001918460018302840111600160201b8311171561068157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611689945050505050565b3480156106ce57600080fd5b5061024a611ba0565b3480156106e357600080fd5b5061075c600480360360408110156106fa57600080fd5b60ff8235169190810190604081016020820135600160201b81111561071e57600080fd5b82018360208201111561073057600080fd5b803590602001918460018302840111600160201b8311171561075157600080fd5b509092509050611ba5565b005b34801561076a57600080fd5b5061024a611c58565b34801561077f57600080fd5b5061024a611c5d565b34801561079457600080fd5b506103dc611c62565b3480156107a957600080fd5b506103dc611c68565b3480156107be57600080fd5b5061052c611c6e565b3480156107d357600080fd5b50610275610973565b3480156107e857600080fd5b506103dc611c77565b3480156107fd57600080fd5b5061024a611c7d565b34801561081257600080fd5b506108306004803603602081101561082957600080fd5b5035611c82565b6040805160ff988916815260208101979097526001600160a01b03909516868601526060860193909352608085019190915290931660a083015267ffffffffffffffff90921660c082015290519081900360e00190f35b34801561089357600080fd5b506103dc611cda565b3480156108a857600080fd5b506103dc611ce0565b3480156108bd57600080fd5b506103dc611ce6565b600881565b606481565b600681565b606033612000146109175760405162461bcd60e51b815260040180806020018281038252602f815260200180612f8e602f913960400191505060405180910390fd5b61095683838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611cec92505050565b949350505050565b600481565b600181565b61100181565b606181565b600081565b600581565b61200081565b600281565b60008061099483611f7d565b905061099e612e56565b50600081815260016020818152604092839020835160e081018552815460ff90811682529382015492810183905260028201546001600160a01b03169481019490945260038101546060850152600481015460808501526005015491821660a084015261010090910467ffffffffffffffff1660c0830152610a64576040805162461bcd60e51b815260206004820152601a602482015279189a5b99081c995c5d595cdd08191bd95cdb89dd08195e1a5cdd60321b604482015290519081900360640190fd5b6000610a8182608001518360600151611f8490919063ffffffff16565b905081604001516001600160a01b0316866001600160a01b031614610ad75760405162461bcd60e51b8152600401808060200182810382526045815260200180612f1b6045913960600191505060405180910390fd5b336001600160a01b0316866001600160a01b031663893d20e86040518163ffffffff1660e01b815260040160206040518083038186803b158015610b1a57600080fd5b505afa158015610b2e573d6000803e3d6000fd5b505050506040513d6020811015610b4457600080fd5b50516001600160a01b031614610b8b5760405162461bcd60e51b815260040180806020018281038252602e815260200180612f60602e913960400191505060405180910390fd5b604080516370a0823160e01b8152611004600482015290516000916001600160a01b038916916370a0823191602480820192602092909190829003018186803b158015610bd757600080fd5b505afa158015610beb573d6000803e3d6000fd5b505050506040513d6020811015610c0157600080fd5b505160408051636eb1769f60e11b815233600482015230602482015290519192508391610c929184916001600160a01b038c169163dd62ed3e916044808301926020929190829003018186803b158015610c5a57600080fd5b505afa158015610c6e573d6000803e3d6000fd5b505050506040513d6020811015610c8457600080fd5b50519063ffffffff611fcd16565b1015610ce5576040805162461bcd60e51b815260206004820152601760248201527f616c6c6f77616e6365206973206e6f7420656e6f756768000000000000000000604482015290519081900360640190fd5b600034905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b158015610d2757600080fd5b505afa158015610d3b573d6000803e3d6000fd5b505050506040513d6020811015610d5157600080fd5b50519050808210801590610d6a57506402540be4008206155b610da55760405162461bcd60e51b8152600401808060200182810382526037815260200180612ee46037913960400191505060405180910390fd5b6000610db1868b612027565b905063ffffffff8116610fb0576001600160a01b038a166323b872dd33611004610de1898963ffffffff611f8416565b6040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050602060405180830381600087803b158015610e4957600080fd5b505af1158015610e5d573d6000803e3d6000fd5b505050506040513d6020811015610e7357600080fd5b5050602086015160408088015160a089015182516323bfccdb60e21b815260048101949094526001600160a01b03909116602484015260ff1660448301525161100491638eff336c91606480830192600092919082900301818387803b158015610edc57600080fd5b505af1158015610ef0573d6000803e3d6000fd5b50505050896001600160a01b03167f78e7dd9aefcdbf795c4936a66f7dc6d41bb56637b54f561a6bf7829dca3348a88a8860600151886040518080602001848152602001838152602001828103825285818151815260200191508051906020019080838360005b83811015610f6f578181015183820152602001610f57565b50505050905090810190601f168015610f9c5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a2611068565b896001600160a01b03167f831c0ef4d93bda3bce08b69ae3f29ef1a6e052b833200988554158494405a1078a8360405180806020018363ffffffff1663ffffffff168152602001828103825284818151815260200191508051906020019080838360005b8381101561102c578181015183820152602001611014565b50505050905090810190601f1680156110595780820380516001836020036101000a031916815260200191505b50935050505060405180910390a25b60008781526001602081905260408220805460ff191681559081018290556002810180546001600160a01b0319169055600381018290556004810191909155600501805468ffffffffffffffffff191690556110c2612e92565b5060408051808201825263ffffffff831681526020810189905290516110049085156108fc029086906000818181858888f1935050505015801561110a573d6000803e3d6000fd5b5061200063f7a251d7600161111e8461247e565b611133886402540be40063ffffffff61250816565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611191578181015183820152602001611179565b50505050905090810190601f1680156111be5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b1580156111df57600080fd5b505af11580156111f3573d6000803e3d6000fd5b505050506040513d602081101561120957600080fd5b50600199505050505050505050505b92915050565b61100581565b60008061123083611f7d565b905061123a612e56565b50600081815260016020818152604092839020835160e081018552815460ff90811682529382015492810183905260028201546001600160a01b03169481019490945260038101546060850152600481015460808501526005015491821660a084015261010090910467ffffffffffffffff1660c0830152611300576040805162461bcd60e51b815260206004820152601a602482015279189a5b99081c995c5d595cdd08191bd95cdb89dd08195e1a5cdd60321b604482015290519081900360640190fd5b428160c0015167ffffffffffffffff1610611362576040805162461bcd60e51b815260206004820152601b60248201527f62696e642072657175657374206973206e6f7420657870697265640000000000604482015290519081900360640190fd5b600034905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b1580156113a457600080fd5b505afa1580156113b8573d6000803e3d6000fd5b505050506040513d60208110156113ce57600080fd5b505190508082108015906113e757506402540be4008206155b6114225760405162461bcd60e51b8152600401808060200182810382526037815260200180612ee46037913960400191505060405180910390fd5b60008481526001602081905260408220805460ff191681559081018290556002810180546001600160a01b0319169055600381018290556004810191909155600501805468ffffffffffffffffff1916905561147c612e92565b50604080518082018252600181526020810186905290516110049084156108fc029085906000818181858888f193505050501580156114bf573d6000803e3d6000fd5b5061200063f7a251d760016114d38461247e565b6114e8876402540be40063ffffffff61250816565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561154657818101518382015260200161152e565b50505050905090810190601f1680156115735780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b15801561159457600080fd5b505af11580156115a8573d6000803e3d6000fd5b505050506040513d60208110156115be57600080fd5b50506040808501518151600160208281018290528483528b51948301949094528a516001600160a01b03909316937f831c0ef4d93bda3bce08b69ae3f29ef1a6e052b833200988554158494405a107938c93918291606083019186019080838360005b83811015611639578181015183820152602001611621565b50505050905090810190601f1680156116665780820380516001836020036101000a031916815260200191505b50935050505060405180910390a26001955050505050505b919050565b61100881565b60008061169583611f7d565b905061169f612e56565b50600081815260016020818152604092839020835160e081018552815460ff90811682529382015492810183905260028201546001600160a01b03169481019490945260038101546060850152600481015460808501526005015491821660a084015261010090910467ffffffffffffffff1660c0830152611765576040805162461bcd60e51b815260206004820152601a602482015279189a5b99081c995c5d595cdd08191bd95cdb89dd08195e1a5cdd60321b604482015290519081900360640190fd5b80604001516001600160a01b0316856001600160a01b0316146117b95760405162461bcd60e51b8152600401808060200182810382526045815260200180612f1b6045913960600191505060405180910390fd5b336001600160a01b0316856001600160a01b031663893d20e86040518163ffffffff1660e01b815260040160206040518083038186803b1580156117fc57600080fd5b505afa158015611810573d6000803e3d6000fd5b505050506040513d602081101561182657600080fd5b50516001600160a01b031614611883576040805162461bcd60e51b815260206004820152601b60248201527f6f6e6c79206265703265206f776e65722063616e2072656a6563740000000000604482015290519081900360640190fd5b600034905060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b1580156118c557600080fd5b505afa1580156118d9573d6000803e3d6000fd5b505050506040513d60208110156118ef57600080fd5b5051905080821080159061190857506402540be4008206155b6119435760405162461bcd60e51b8152600401808060200182810382526037815260200180612ee46037913960400191505060405180910390fd5b60008481526001602081905260408220805460ff191681559081018290556002810180546001600160a01b0319169055600381018290556004810191909155600501805468ffffffffffffffffff1916905561199d612e92565b50604080518082018252600781526020810186905290516110049084156108fc029085906000818181858888f193505050501580156119e0573d6000803e3d6000fd5b5061200063f7a251d760016119f48461247e565b611a09876402540be40063ffffffff61250816565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611a67578181015183820152602001611a4f565b50505050905090810190601f168015611a945780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b158015611ab557600080fd5b505af1158015611ac9573d6000803e3d6000fd5b505050506040513d6020811015611adf57600080fd5b505060408051600760208281018290528383528a519383019390935289516001600160a01b038c16937f831c0ef4d93bda3bce08b69ae3f29ef1a6e052b833200988554158494405a107938c939290918291606083019186019080838360005b83811015611b57578181015183820152602001611b3f565b50505050905090810190601f168015611b845780820380516001836020036101000a031916815260200191505b50935050505060405180910390a2506001979650505050505050565b600b81565b3361200014611be55760405162461bcd60e51b815260040180806020018281038252602f815260200180612f8e602f913960400191505060405180910390fd5b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a1505050565b600781565b600981565b61100781565b61100681565b60005460ff1681565b61100281565b600381565b600160208190526000918252604090912080549181015460028201546003830154600484015460059094015460ff9586169593946001600160a01b0390931693919291811690610100900467ffffffffffffffff1687565b61100381565b61100081565b61100481565b6060611cf6612e56565b6000611d018461254a565b9150915080611d57576040805162461bcd60e51b815260206004820152601f60248201527f756e7265636f676e697a6564207472616e73666572496e207061636b61676500604482015290519081900360640190fd5b815160ff16611e0b576020828101805160009081526001928390526040908190208551815460ff1990811660ff928316178355935194820194909455908501516002820180546001600160a01b0319166001600160a01b03909216919091179055606085015160038201556080850151600482015560a08501516005909101805460c08701519316919093161768ffffffffffffffff00191661010067ffffffffffffffff90921691909102179055611f62565b815160ff1660011415611f155760006110046001600160a01b03166359b9278984602001516040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611e6457600080fd5b505afa158015611e78573d6000803e3d6000fd5b505050506040513d6020811015611e8e57600080fd5b505190506001600160a01b03811615611f0f5760208301516040805163b99328c560e01b815260048101929092526001600160a01b0383166024830152516110049163b99328c591604480830192600092919082900301818387803b158015611ef657600080fd5b505af1158015611f0a573d6000803e3d6000fd5b505050505b50611f62565b6040805162461bcd60e51b815260206004820152601960248201527f756e7265636f676e697a65642062696e64207061636b61676500000000000000604482015290519081900360640190fd5b60408051600080825260208201909252905b50949350505050565b6020015190565b6000611fc683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061269c565b9392505050565b600082820183811015611fc6576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600080826001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561206357600080fd5b505afa158015612077573d6000803e3d6000fd5b505050506040513d602081101561208d57600080fd5b5051604080516395d89b4160e01b815290519192506060916001600160a01b038616916395d89b41916004808301926000929190829003018186803b1580156120d557600080fd5b505afa1580156120e9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561211257600080fd5b8101908080516040519392919084600160201b82111561213157600080fd5b90830190602082018581111561214657600080fd5b8251600160201b81118282018810171561215f57600080fd5b82525081516020918201929091019080838360005b8381101561218c578181015183820152602001612174565b50505050905090810190601f1680156121b95780820380516001836020036101000a031916815260200191505b5060408181526370a0823160e01b82526110046004830152519495506000946001600160a01b038a1694506370a08231935060248083019350602092829003018186803b15801561220957600080fd5b505afa15801561221d573d6000803e3d6000fd5b505050506040513d602081101561223357600080fd5b5051608087015160608801519192506000916122549163ffffffff611f8416565b9050428760c0015167ffffffffffffffff16101561227a57506001935061121892505050565b612288838860200151612733565b61229a57506002935061121892505050565b808211156122b057506003935061121892505050565b866060015187604001516001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156122f257600080fd5b505afa158015612306573d6000803e3d6000fd5b505050506040513d602081101561231c57600080fd5b50511461233157506004935061121892505050565b8660a0015160ff16841461234d57506005935061121892505050565b602080880151604080516359b9278960e01b8152600481019290925251600092611004926359b927899260248083019392829003018186803b15801561239257600080fd5b505afa1580156123a6573d6000803e3d6000fd5b505050506040513d60208110156123bc57600080fd5b50516001600160a01b031614158061245e57506000801b6110046001600160a01b031663bd46646189604001516040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561242f57600080fd5b505afa158015612443573d6000803e3d6000fd5b505050506040513d602081101561245957600080fd5b505114155b1561247157506006935061121892505050565b5060009695505050505050565b6040805160028082526060828101909352829190816020015b606081526020019060019003908161249757505083519091506124bf9063ffffffff1661281b565b816000815181106124cc57fe5b60200260200101819052506124e7836020015160001c61281b565b816001815181106124f457fe5b6020026020010181905250611fc68161282e565b6000611fc683836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506128b8565b612552612e56565b600061255c612e56565b612564612ea9565b6125756125708661291d565b612942565b90506000805b6125848361298c565b1561268f57806125a95761259f61259a846129ad565b6129fb565b60ff168452612687565b80600114156125c8576125be61259a846129ad565b6020850152612687565b80600214156125f5576125e26125dd846129ad565b612a59565b6001600160a01b03166040850152612687565b80600314156126145761260a61259a846129ad565b6060850152612687565b80600414156126335761262961259a846129ad565b6080850152612687565b80600514156126555761264861259a846129ad565b60ff1660a0850152612687565b80600614156126825761266a61259a846129ad565b67ffffffffffffffff1660c085015260019150612687565b61268f565b60010161257b565b5091935090915050915091565b6000818484111561272b5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156126f05781810151838201526020016126d8565b50505050905090810190601f16801561271d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b8151600090839060081080612749575080516003115b15612758576000915050611218565b6040805160208082528183019092526060916020820181803683370190505090508360208201528082518151811061278c57fe5b6020910101516001600160f81b031916602d60f81b146127b157600092505050611218565b600160005b8351811015612811578281815181106127cb57fe5b602001015160f81c60f81b6001600160f81b0319168482815181106127ec57fe5b01602001516001600160f81b031916146128095760009150612811565b6001016127b6565b5095945050505050565b606061121861282983612a73565b612b59565b606081516000141561284f575060408051600081526020810190915261167e565b60608260008151811061285e57fe5b602002602001015190506000600190505b835181101561289f576128958285838151811061288857fe5b6020026020010151612bab565b915060010161286f565b50611fc66128b2825160c060ff16612c28565b82612bab565b600081836129075760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156126f05781810151838201526020016126d8565b50600083858161291357fe5b0495945050505050565b612925612ec9565b506040805180820190915281518152602082810190820152919050565b61294a612ea9565b61295382612d20565b61295c57600080fd5b600061296b8360200151612d5a565b60208085015160408051808201909152868152920190820152915050919050565b6000612996612ec9565b505080518051602091820151919092015191011190565b6129b5612ec9565b6129be8261298c565b6129c757600080fd5b602082015160006129d782612dbd565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590612a1057508151602110155b612a1957600080fd5b6000612a288360200151612d5a565b83516020808601518301805193945091849003929190831015611f7457506020919091036101000a90049392505050565b8051600090601514612a6a57600080fd5b611218826129fb565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416612ab757506018612adb565b6fffffffffffffffffffffffffffffffff198416612ad757506010612adb565b5060005b6020811015612b1157818181518110612af057fe5b01602001516001600160f81b03191615612b0957612b11565b600101612adb565b60008160200390506060816040519080825280601f01601f191660200182016040528015612b46576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015612b8b5750607f60f81b82600081518110612b7957fe5b01602001516001600160f81b03191611155b15612b9757508061167e565b611218612ba98351608060ff16612c28565b835b6060806040519050835180825260208201818101602087015b81831015612bdc578051835260209283019201612bc4565b50855184518101855292509050808201602086015b81831015612c09578051835260209283019201612bf1565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310612c78576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411612cd25782840160f81b81600081518110612cb457fe5b60200101906001600160f81b031916908160001a9053509050611218565b6060612cdd85612a73565b90508381510160370160f81b82600081518110612cf657fe5b60200101906001600160f81b031916908160001a905350612d178282612bab565b95945050505050565b8051600090612d315750600061167e565b6020820151805160001a9060c0821015612d505760009250505061167e565b5060019392505050565b8051600090811a6080811015612d7457600091505061167e565b60b8811080612d8f575060c08110801590612d8f575060f881105b15612d9e57600191505061167e565b60c0811015612db25760b51901905061167e565b60f51901905061167e565b80516000908190811a6080811015612dd85760019150612e4f565b60b8811015612ded57607e1981019150612e4f565b60c0811015612e1a5760b78103600185019450806020036101000a85510460018201810193505050612e4f565b60f8811015612e2f5760be1981019150612e4f565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915290565b604080518082019091526000808252602082015290565b6040518060400160405280612ebc612ec9565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe72656c6179466565206d757374206265204e202a203165313020616e642067726561746572207468616e206d696e6952656c6179466565636f6e74616374206164647265737320646f65736e277420657175616c20746f2074686520636f6e7472616374206164647265737320696e2062696e6420726571756573746f6e6c79206265703265206f776e65722063616e20617070726f766520746869732062696e642072657175657374746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374a26469706673582212208d24722e295c34fcc944dfda2183ee07fab7234ce8b7001a715c221bd92ef86e64736f6c63430006040033" + }, + "0x0000000000000000000000000000000000002000": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106102485760003560e01c8063863fe4ab1161013b578063c81b1662116100b8578063e3b048051161007c578063e3b048051461072c578063f7a251d71461074c578063f9a2bbc7146107c4578063fc3e5908146107cc578063fd6a6879146107d457610248565b8063c81b1662146106dd578063d31f968d146106e5578063d76a867514610714578063dc927faf1461071c578063e1c7392a1461072457610248565b8063a78abc16116100ff578063a78abc16146105d3578063ab51bb96146105db578063ac431751146105e3578063b0355f5b146103ff578063c27cdcfb146106a157610248565b8063863fe4ab146105b35780638cc8f561146104b657806396713da9146105bb5780639dc09262146105c3578063a1a11bf5146105cb57610248565b8063493279b1116101c957806370fd5bad1161018d57806370fd5bad146104b657806374f079b8146104be57806375d47a0a146104c65780637942fd05146104ce57806384013b6a146104d657610248565b8063493279b11461045f5780634bf6c8821461047e57806351e80672146104865780636e47a51a1461048e5780636e47b482146104ae57610248565b8063308325f411610210578063308325f4146102cf5780633bdc47a6146102d75780633dffc387146103ff578063422f90501461040757806343756e5c1461043b57610248565b806305e682581461024d5780630bee7a671461026b57806314b3023b1461028c57806322556cdc146102a65780632ff32aea146102ae575b600080fd5b6102556107dc565b6040805160ff9092168252519081900360200190f35b6102736107e1565b6040805163ffffffff9092168252519081900360200190f35b6102946107e6565b60408051918252519081900360200190f35b6102946107ec565b6102b66107f1565b60408051600792830b90920b8252519081900360200190f35b6102946107fa565b61038a600480360360608110156102ed57600080fd5b60ff82351691602081013591810190606081016040820135600160201b81111561031657600080fd5b82018360208201111561032857600080fd5b803590602001918460018302840111600160201b8311171561034957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610800945050505050565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103c45781810151838201526020016103ac565b50505050905090810190601f1680156103f15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610255610876565b6104276004803603602081101561041d57600080fd5b503560ff1661087b565b604080519115158252519081900360200190f35b610443610890565b604080516001600160a01b039092168252519081900360200190f35b610467610896565b6040805161ffff9092168252519081900360200190f35b61025561089b565b6104436108a0565b610443600480360360208110156104a457600080fd5b503560ff166108a6565b6104436108c1565b6102556108c7565b6102946108cc565b6104436108d2565b6102556108d8565b6105b1600480360360a08110156104ec57600080fd5b810190602081018135600160201b81111561050657600080fd5b82018360208201111561051857600080fd5b803590602001918460018302840111600160201b8311171561053957600080fd5b919390929091602081019035600160201b81111561055657600080fd5b82018360208201111561056857600080fd5b803590602001918460018302840111600160201b8311171561058957600080fd5b919350915080356001600160401b03908116916020810135909116906040013560ff166108dd565b005b610294611a8d565b610255611a95565b610443611a9a565b610443611aa0565b610427611aa6565b6102736107dc565b6105b1600480360360408110156105f957600080fd5b810190602081018135600160201b81111561061357600080fd5b82018360208201111561062557600080fd5b803590602001918460018302840111600160201b8311171561064657600080fd5b919390929091602081019035600160201b81111561066357600080fd5b82018360208201111561067557600080fd5b803590602001918460018302840111600160201b8311171561069657600080fd5b509092509050611aaf565b6106c1600480360360208110156106b757600080fd5b503560ff16612046565b604080516001600160401b039092168252519081900360200190f35b610443612061565b610427600480360360408110156106fb57600080fd5b5080356001600160a01b0316906020013560ff16612067565b61038a612087565b6104436120a6565b6105b16120ac565b6106c16004803603602081101561074257600080fd5b503560ff16612463565b6104276004803603606081101561076257600080fd5b60ff8235169190810190604081016020820135600160201b81111561078657600080fd5b82018360208201111561079857600080fd5b803590602001918460018302840111600160201b831117156107b957600080fd5b91935091503561247e565b6104436125d0565b6102556125d6565b6104436125db565b600081565b606481565b60015481565b603281565b60045460070b81565b60025481565b60606000825160210190506060816040519080825280601f01601f191660200182016040528015610838576020820181803683370190505b506021810186905260018101879052828152905060418101600061085b866125e1565b50905061086a818388516125eb565b50909695505050505050565b600181565b60096020526000908152604090205460ff1681565b61100181565b606181565b600881565b61200081565b6005602052600090815260409020546001600160a01b031681565b61100581565b600281565b60035481565b61100881565b600b81565b60005460ff16610930576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b60408051630a83aaa960e31b815233600482015290516110069163541d5548916024808301926020929190829003018186803b15801561096f57600080fd5b505afa158015610983573d6000803e3d6000fd5b505050506040513d602081101561099957600080fd5b50516109ec576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b60ff8116600090815260086020526040902054829082906001600160401b039081169083168114610a5c576040805162461bcd60e51b815260206004820152601560248201527439b2b8bab2b731b2903737ba1034b71037b93232b960591b604482015290519081900360640190fd5b60ff8216600090815260086020908152604091829020805467ffffffffffffffff1916600185016001600160401b039081169190911790915582516337d7f9c160e21b81529089166004820152915188926110039263df5fe70492602480840193829003018186803b158015610ad157600080fd5b505afa158015610ae5573d6000803e3d6000fd5b505050506040513d6020811015610afb57600080fd5b5051610b385760405162461bcd60e51b8152600401808060200182810382526023815260200180612b686023913960400191505060405180910390fd5b60ff851660009081526005602052604090205485906001600160a01b0316610ba7576040805162461bcd60e51b815260206004820152601860248201527f6368616e6e656c206973206e6f7420737570706f727465640000000000000000604482015290519081900360640190fd5b60608c8c8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608b8b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805163cba510a960e01b81526001600160401b038f1660048201529051939450610cce93611003935063cba510a992506024808301926020929190829003018186803b158015610c7757600080fd5b505afa158015610c8b573d6000803e3d6000fd5b505050506040513d6020811015610ca157600080fd5b505160408051808201909152600381526269626360e81b6020820152610cc78c8c61262c565b8585612673565b610d16576040805162461bcd60e51b815260206004820152601460248201527334b73b30b634b21036b2b935b63290383937b7b360611b604482015290519081900360640190fd5b60408051631bb5062960e31b81526001600160401b038c16600482015290516000916110039163dda8314891602480820192602092909190829003018186803b158015610d6257600080fd5b505afa158015610d76573d6000803e3d6000fd5b505050506040513d6020811015610d8c57600080fd5b5051905088600080806060610da088612770565b935093509350935083610e61578460ff168f6001600160401b03167ff7b2e42d694eb1100184aae86d4245d9e46966100b1dc7e723275b98326854ac8a6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610e1a578181015183820152602001610e02565b50505050905090810190601f168015610e475780820380516001836020036101000a031916815260200191505b509250505060405180910390a35050505050505050611a7f565b8460ff168f6001600160401b03167f36afdaf439a8f43fe72135135d804ae620b37a474f0943b5b85f6788312cad4085604051808260ff1660ff16815260200191505060405180910390a360ff83166113ea5760ff85166000818152600560209081526040808320548151631182b87560e01b815260048101958652602481019283528651604482015286516001600160a01b03909216958695631182b875958d958a9593949093606490910192918601918190849084905b83811015610f32578181015183820152602001610f1a565b50505050905090810190601f168015610f5f5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015610f7f57600080fd5b505af192505050801561106357506040513d6000823e601f3d908101601f191682016040526020811015610fb257600080fd5b8101908080516040519392919084600160201b821115610fd157600080fd5b908301906020820185811115610fe657600080fd5b8251600160201b811182820188101715610fff57600080fd5b82525081516020918201929091019080838360005b8381101561102c578181015183820152602001611014565b50505050905090810190601f1680156110595780820380516001836020036101000a031916815260200191505b5060405250505060015b611375576040516000815260443d101561107f5750600061111a565b60046000803e60005160e01c6308c379a081146110a057600091505061111a565b60043d036004833e81513d60248201116001600160401b03821117156110cb5760009250505061111a565b80830180516001600160401b038111156110ec57600094505050505061111a565b8060208301013d860181111561110a5760009550505050505061111a565b601f01601f191660405250925050505b806111255750611237565b60ff871660009081526007602052604081205461115c916001600160401b039091169089906111579060029088610800565b612820565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf948794849390840192918601918190849084905b838110156111f75781810151838201526020016111df565b50505050905090810190601f1680156112245780820380516001836020036101000a031916815260200191505b509250505060405180910390a250611370565b3d808015611261576040519150601f19603f3d011682016040523d82523d6000602084013e611266565b606091505b5060ff8716600090815260076020526040812054611299916001600160401b039091169089906111579060029088610800565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351948794849390840192918601918190849084905b8381101561133457818101518382015260200161131c565b50505050905090810190601f1680156113615780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b6113e4565b8051156113e25760ff87166000908152600760205260408120546113ae916001600160401b039091169089906111579060019086610800565b60ff8716600090815260076020526040902080546001600160401b038082166001011667ffffffffffffffff199091161790555b505b506119b8565b60ff83166001141561168e5760ff8516600081815260056020908152604080832054815163831d65d160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563831d65d1958d958a9593949093606490910192918601918190849084905b8381101561147457818101518382015260200161145c565b50505050905090810190601f1680156114a15780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156114c157600080fd5b505af19250505080156114d2575060015b6113e4576040516000815260443d10156114ee57506000611589565b60046000803e60005160e01c6308c379a0811461150f576000915050611589565b60043d036004833e81513d60248201116001600160401b038211171561153a57600092505050611589565b80830180516001600160401b0381111561155b576000945050505050611589565b8060208301013d860181111561157957600095505050505050611589565b601f01601f191660405250925050505b8061159457506115f9565b60408051602080825283518183015283516001600160a01b038616937ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf93869390928392830191850190808383600083156111f75781810151838201526020016111df565b3d808015611623576040519150601f19603f3d011682016040523d82523d6000602084013e611628565b606091505b5060408051602080825283518183015283516001600160a01b038616937f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351938693909283928301918501908083836000831561133457818101518382015260200161131c565b60ff8316600214156119b85760ff8516600081815260056020908152604080832054815163c8509d8160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563c8509d81958d958a9593949093606490910192918601918190849084905b83811015611718578181015183820152602001611700565b50505050905090810190601f1680156117455780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561176557600080fd5b505af1925050508015611776575060015b6119b6576040516000815260443d10156117925750600061182d565b60046000803e60005160e01c6308c379a081146117b357600091505061182d565b60043d036004833e81513d60248201116001600160401b03821117156117de5760009250505061182d565b80830180516001600160401b038111156117ff57600094505050505061182d565b8060208301013d860181111561181d5760009550505050505061182d565b601f01601f191660405250925050505b8061183857506118e1565b816001600160a01b03167ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf826040518080602001828103825283818151815260200191508051906020019080838360005b838110156118a1578181015183820152602001611889565b50505050905090810190601f1680156118ce5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2506119b6565b3d80801561190b576040519150601f19603f3d011682016040523d82523d6000602084013e611910565b606091505b50816001600160a01b03167f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351826040518080602001828103825283818151815260200191508051906020019080838360005b8381101561197a578181015183820152602001611962565b50505050905090810190601f1680156119a75780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b505b60ff80861660009081526009602052604090205461100591636f93d2e69189913391879116806119ea575060ff881615155b604080516001600160e01b031960e088901b1681526001600160a01b039586166004820152939094166024840152604483019190915215156064820152905160848083019260209291908290030181600087803b158015611a4a57600080fd5b505af1158015611a5e573d6000803e3d6000fd5b505050506040513d6020811015611a7457600080fd5b505050505050505050505b505050505050505050505050565b630100610081565b600981565b61100781565b61100681565b60005460ff1681565b3361100714611aef5760405162461bcd60e51b815260040180806020018281038252602e815260200180612abe602e913960400191505060405180910390fd5b611b5884848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526012815271626174636853697a65466f724f7261636c6560701b602082015291506129769050565b15611bf357604080516020601f8401819004810282018101909252828152600091611b9b91858580838501838280828437600092019190915250612a5d92505050565b90506127108111158015611bb05750600a8110155b611beb5760405162461bcd60e51b8152600401808060200182810382526032815260200180612b366032913960400191505060405180910390fd5b600155611fb4565b611c5484848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600a81526918591910da185b9b995b60b21b602082015291506129769050565b15611dd957606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060169091149050611cd75760405162461bcd60e51b8152600401808060200182810382526052815260200180612b8b6052913960600191505060405180910390fd5b600181015160028201516016830151611cef81612a62565b611d40576040805162461bcd60e51b815260206004820152601960248201527f61646472657373206973206e6f74206120636f6e747261637400000000000000604482015290519081900360640190fd5b60ff808416600081815260056020908152604080832080546001600160a01b0388166001600160a01b03199091168117909155808452600683528184208585528352818420805460ff19908116600117909155600990935281842080549093169588161595909517909155517f7e3b6af43092577ee20e60eaa1d9b114a7031305c895ee7dd3ffe17196d2e1e09190a350505050611fb4565b611e4684848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526016815275195b98589b1953dc911a5cd8589b1950da185b9b995b60521b602082015291506129769050565b15611f7757606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060029091149050611ec95760405162461bcd60e51b815260040180806020018281038252604a815260200180612aec604a913960600191505060405180910390fd5b600181810151600283015160ff80831660009081526005602052604090205492939192908316909114906001600160a01b03168015611f6d576001600160a01b038116600090815260066020908152604080832060ff881680855290835292819020805460ff1916861515908117909155815190815290517fa3132e3f9819fbddc7f0ed6d38d7feef59aa95112090b7c592f5cb5bc4aa4adc929181900390910190a25b5050505050611fb4565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b6008602052600090815260409020546001600160401b031681565b61100281565b600660209081526000928352604080842090915290825290205460ff1681565b6040518060400160405280600381526020016269626360e81b81525081565b61100381565b60005460ff1615612104576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b7f1471eb6eb2c5e789fc3de43f8ce62938c7d1836ec861730447e2ada8fd81017b80546001600160a01b0319908116611008179091557f92e85d02570a8092d09a6e3a57665bc3815a2699a4074001bf1ccabf660f5a36805460ff199081169091557fd8af288fc1c8680b4f4706064cf021e264efb6828fcaf7eb5ca36818eb365bcc8054821660019081179091557f89832631fb3c3307a103ba2c84ab569c64d6182a18893dcd163f0f1c2090733a805484166110049081179091557f6cde3cea4b3a3fb2488b2808bae7556f4a405e50f65e1794383bc026131b13c38054841690557f72e4efa1513b071517c6c74dba31b5934a81aa83cddd400e7081df5529c9943680548416831790557fa9bc9a3a348c357ba16b37005d7e6b3236198c0e939f4af8c5f19b8deeb8ebc08054851690911790557fc575c31fea594a6eb97c8e9d3f9caee4c16218c6ef37e923234c0fe9014a61e78054831690557f4e523af77f034e9810f1c94057f5e931fb3d16a51511a4c3add793617d18610580548316821790557ffb33122aa9f93cc639ebe80a7bc4784c11e6053dde89c6f4f7e268c6a623da1e805484166110001790557fc7694af312c4f286114180fd0ba6a52461fcee8a381636770b19a343af92538a80548316821790557f01112dd68e482ba8d68a7e828cff8b3abcea08eab88941953c180a7e650e9cd480548316821790557fc0a4a8be475dfebc377ebef2d7c4ff47656f572a08dd92b81017efcdba0febe1805484166110071790557f87e8a52529e8ece4ef759037313542a6429ff494a9fab9027fb79db90124eba680548316821790557f4c7666bbcb22d46469f7cc282f70764a7012dca2cce630ff8d83db9a9cdd48f080548316821790557f40f28f99a40bc9f6beea1013afdbc3cdcc689eb76b82c4de06c0acf1e1932ed58054909316611001179092557f0d9cf2cd531699eed8dd34e40ff2884a14a698c4898184fba85194e6f6772d248054821683179055600b60009081527f23f68c9bd22b8a93d06adabe17481c87c016bcbd20adc8bfd707a4d813a572176020527fdf0d5d05428057f5455c2dc8e810dd86d1e9350faa72f16bda8a45443c5b39328054831684179055603283556004805467ffffffffffffffff19166001600160401b031790556002819055600381905580549091169091179055565b6007602052600090815260409020546001600160401b031681565b6000805460ff166124d2576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b33600090815260066020908152604080832060ff808a16855292529091205486911661252f5760405162461bcd60e51b8152600401808060200182810382526031815260200180612a8d6031913960400191505060405180910390fd5b60ff86166000908152600760209081526040808320548151601f89018490048402810184019092528782526001600160401b0316926125949284928b926111579290918a918d908d908190840183828082843760009201919091525061080092505050565b60ff969096166000908152600760205260409020805467ffffffffffffffff191660019788016001600160401b03161790555093949350505050565b61100081565b600381565b61100481565b8051602090910191565b5b6020811061260b578251825260209283019290910190601f19016125ec565b915181516020939093036101000a6000190180199091169216919091179052565b60408051600e808252818301909252606091630100610060ff851617918391602082018180368337505050600e818101969096526006810192909252509283525090919050565b60008561268257506000612767565b606082518451865160800101016040519080825280601f01601f1916602001820160405280156126b9576020820181803683370190505b50905060006126c782612a68565b6020808901518252019050866000806126df896125e1565b80865260209095019490925090506126f88285836125eb565b92830192612705886125e1565b808652602090950194909250905061271e8285836125eb565b9283018a815260200192612731876125e1565b90925090506127418285836125eb565b50835160200161274f612a6e565b60208183886065600019fa5051600114955050505050505b95945050505050565b600080600060606021855110156127a0575050604080516000808252602082019092529092508291508190612819565b600185015160218601518651604080516020198301808252601f19600119909401939093168101602001909152604189019392916060919080156127eb576020820181803683370190505b50905060006127f9826125e1565b50905061280b858260218d51036125eb565b506001975091955093509150505b9193509193565b60025443111561285f576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b1617909155600355436002556128a0565b600380546001908101918290555410156128a0576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003555b8160ff16836001600160401b0316600460009054906101000a900460070b6001600160401b03167f3a6e0fc61675aa2a100bcba0568368bb92bcec91c97673391074f11138f0cffe606185604051808361ffff1661ffff16815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561293657818101518382015260200161291e565b50505050905090810190601f1680156129635780820380516001836020036101000a031916815260200191505b50935050505060405180910390a4505050565b6000816040516020018082805190602001908083835b602083106129ab5780518252601f19909201916020918201910161298c565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310612a195780518252601f1990920191602091820191016129fa565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b3b151590565b60200190565b6040518060200160405280600190602082028036833750919291505056fe74686520636f6e747261637420616e64206368616e6e656c2068617665206e6f74206265656e2072656769737465726564746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f7220656e61626c654f7244697361626c654368616e6e656c2073686f756c6420626520322c206368616e6e656c49643a6973456e61626c65746865206e6577426174636853697a65466f724f7261636c652073686f756c6420626520696e205b31302c2031303030305d6c6967687420636c69656e74206e6f742073796e632074686520626c6f636b207965746c656e677468206f662076616c756520666f72206164644368616e6e656c2073686f756c642062652032322c206368616e6e656c49643a697346726f6d53797374656d3a68616e646c657241646472657373a2646970667358221220230d7e9288613f5afb55ab3692ab4b25169e86ce53da4ef6333e3703c1351f7864736f6c63430006040033" + }, + "9fB29AAc15b9A4B7F17c3385939b007540f4d791": { + "balance": "0x84595161401484a000000" + }, + "37B8516a0F88E65D677229b402ec6C1e0E333004": { + "balance": "0x84595161401484a000000" + } } \ No newline at end of file diff --git a/core/allocs/sokol.json b/core/allocs/sokol.json deleted file mode 100644 index c09cf14041a..00000000000 --- a/core/allocs/sokol.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "0x0000000000000000000000000000000000000000": { - "balance": "0x0" - }, - "0x0000000000000000000000000000000000000001": { - "balance": "0x1" - }, - "0x0000000000000000000000000000000000000002": { - "balance": "0x1" - }, - "0x0000000000000000000000000000000000000003": { - "balance": "0x1" - }, - "0x0000000000000000000000000000000000000004": { - "balance": "0x1" - }, - "0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca": { - "balance": "252460800000000000000000000" - }, - "0x8bf38d4764929064f2d4d3a56520a76ab3df415b": { - "balance": "1", - "nonce": "1", - "code": "0x6060604052600436106100fc576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806303aca79214610101578063108552691461016457806340a141ff1461019d57806340c9cdeb146101d65780634110a489146101ff57806345199e0a1461025757806349285b58146102c15780634d238c8e14610316578063752862111461034f578063900eb5a8146103645780639a573786146103c7578063a26a47d21461041c578063ae4b1b5b14610449578063b3f05b971461049e578063b7ab4db5146104cb578063d3e848f114610535578063fa81b2001461058a578063facd743b146105df575b600080fd5b341561010c57600080fd5b6101226004808035906020019091905050610630565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561016f57600080fd5b61019b600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061066f565b005b34156101a857600080fd5b6101d4600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610807565b005b34156101e157600080fd5b6101e9610bb7565b6040518082815260200191505060405180910390f35b341561020a57600080fd5b610236600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610bbd565b60405180831515151581526020018281526020019250505060405180910390f35b341561026257600080fd5b61026a610bee565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156102ad578082015181840152602081019050610292565b505050509050019250505060405180910390f35b34156102cc57600080fd5b6102d4610c82565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561032157600080fd5b61034d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610d32565b005b341561035a57600080fd5b610362610fcc565b005b341561036f57600080fd5b61038560048080359060200190919050506110fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156103d257600080fd5b6103da61113b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561042757600080fd5b61042f6111eb565b604051808215151515815260200191505060405180910390f35b341561045457600080fd5b61045c6111fe565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156104a957600080fd5b6104b1611224565b604051808215151515815260200191505060405180910390f35b34156104d657600080fd5b6104de611237565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610521578082015181840152602081019050610506565b505050509050019250505060405180910390f35b341561054057600080fd5b6105486112cb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561059557600080fd5b61059d6112f1565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156105ea57600080fd5b610616600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611317565b604051808215151515815260200191505060405180910390f35b60078181548110151561063f57fe5b90600052602060002090016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156106cb57600080fd5b600460019054906101000a900460ff161515156106e757600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561072357600080fd5b80600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600460016101000a81548160ff0219169083151502179055507f600bcf04a13e752d1e3670a5a9f1c21177ca2a93c6f5391d4f1298d098097c22600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b600080600061081461113b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561084d57600080fd5b83600960008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff1615156108a957600080fd5b600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101549350600160078054905003925060078381548110151561090857fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691508160078581548110151561094657fe5b906000526020600020900160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506007838154811015156109e557fe5b906000526020600020900160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600780549050111515610a2757600080fd5b6007805480919060019003610a3c9190611370565b506000600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506000600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff0219169083151502179055506000600460006101000a81548160ff0219169083151502179055506001430340600019167f55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89600760405180806020018281038252838181548152602001915080548015610ba257602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610b58575b50509250505060405180910390a25050505050565b60085481565b60096020528060005260406000206000915090508060000160009054906101000a900460ff16908060010154905082565b610bf661139c565b6007805480602002602001604051908101604052809291908181526020018280548015610c7857602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610c2e575b5050505050905090565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166349285b586000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1515610d1257600080fd5b6102c65a03f11515610d2357600080fd5b50505060405180519050905090565b610d3a61113b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610d7357600080fd5b80600960008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16151515610dd057600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614151515610e0c57600080fd5b6040805190810160405280600115158152602001600780549050815250600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015590505060078054806001018281610ea991906113b0565b9160005260206000209001600084909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506000600460006101000a81548160ff0219169083151502179055506001430340600019167f55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89600760405180806020018281038252838181548152602001915080548015610fba57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610f70575b50509250505060405180910390a25050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480156110365750600460009054906101000a900460ff16155b151561104157600080fd5b6001600460006101000a81548160ff0219169083151502179055506007600690805461106e9291906113dc565b506006805490506008819055507f8564cd629b15f47dc310d45bcbfc9bcf5420b0d51bf0659a16c67f91d27632536110a4611237565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156110e75780820151818401526020810190506110cc565b505050509050019250505060405180910390a1565b60068181548110151561110b57fe5b90600052602060002090016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639a5737866000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15156111cb57600080fd5b6102c65a03f115156111dc57600080fd5b50505060405180519050905090565b600460019054906101000a900460ff1681565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900460ff1681565b61123f61139c565b60068054806020026020016040519081016040528092919081815260200182805480156112c157602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311611277575b5050505050905090565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff169050919050565b81548183558181151161139757818360005260206000209182019101611396919061142e565b5b505050565b602060405190810160405280600081525090565b8154818355818115116113d7578183600052602060002091820191016113d6919061142e565b5b505050565b82805482825590600052602060002090810192821561141d5760005260206000209182015b8281111561141c578254825591600101919060010190611401565b5b50905061142a9190611453565b5090565b61145091905b8082111561144c576000816000905550600101611434565b5090565b90565b61149391905b8082111561148f57600081816101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550600101611459565b5090565b905600a165627a7a7230582036ea35935c8246b68074adece2eab70c40e69a0193c08a6277ce06e5b25188510029", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000005": "0x000000000000000000000000fffffffffffffffffffffffffffffffffffffffe", - "0x0000000000000000000000000000000000000000000000000000000000000008": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f": "0x000000000000000000000000e8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca", - "0x4fcf3d5c1e81dc8f954cd15323063057ac2aee4dd974ed40298bac1fcd864d63": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000007": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000004": "0x00000000000000000000e8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca0000", - "0x0000000000000000000000000000000000000000000000000000000000000006": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688": "0x000000000000000000000000e8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca" - } - } -} \ No newline at end of file diff --git a/core/blockchain.go b/core/blockchain.go index 3487283363d..3bd5b6f07d1 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -19,26 +19,26 @@ package core import ( "fmt" + "math/big" "time" - "github.com/ledgerwatch/erigon-lib/chain" - libcommon "github.com/ledgerwatch/erigon-lib/common" + metrics2 "github.com/VictoriaMetrics/metrics" "golang.org/x/crypto/sha3" "golang.org/x/exp/slices" - "github.com/ledgerwatch/erigon/core/systemcontracts" - "github.com/ledgerwatch/erigon/core/vm/evmtypes" - "github.com/ledgerwatch/erigon/rlp" - - metrics2 "github.com/VictoriaMetrics/metrics" + "github.com/ledgerwatch/erigon-lib/chain" + libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon/common/math" "github.com/ledgerwatch/erigon/common/u256" "github.com/ledgerwatch/erigon/consensus" "github.com/ledgerwatch/erigon/consensus/misc" "github.com/ledgerwatch/erigon/core/state" + "github.com/ledgerwatch/erigon/core/systemcontracts" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/vm" + "github.com/ledgerwatch/erigon/core/vm/evmtypes" + "github.com/ledgerwatch/erigon/rlp" ) var ( @@ -75,13 +75,9 @@ func ExecuteBlockEphemerallyForBSC( chainConfig *chain.Config, vmConfig *vm.Config, blockHashFunc func(n uint64) libcommon.Hash, - engine consensus.Engine, - block *types.Block, - stateReader state.StateReader, - stateWriter state.WriterWithChangeSets, - epochReader consensus.EpochReader, - chainReader consensus.ChainHeaderReader, - getTracer func(txIndex int, txHash libcommon.Hash) (vm.EVMLogger, error), + engine consensus.Engine, block *types.Block, + stateReader state.StateReader, stateWriter state.WriterWithChangeSets, + chainReader consensus.ChainHeaderReader, getTracer func(txIndex int, txHash libcommon.Hash) (vm.EVMLogger, error), ) (*EphemeralExecResult, error) { defer BlockExecutionTimer.UpdateDuration(time.Now()) block.Uncles() @@ -97,13 +93,18 @@ func ExecuteBlockEphemerallyForBSC( receipts types.Receipts ) + var excessDataGas *big.Int + ph := chainReader.GetHeaderByHash(block.ParentHash()) + if ph != nil { + excessDataGas = ph.ExcessDataGas + } if !vmConfig.ReadOnly { - if err := InitializeBlockExecution(engine, chainReader, epochReader, block.Header(), block.Transactions(), block.Uncles(), chainConfig, ibs); err != nil { + if err := InitializeBlockExecution(engine, chainReader, block.Header(), block.Transactions(), block.Uncles(), chainConfig, ibs, nil); err != nil { return nil, err } } - if chainConfig.DAOForkSupport && chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(block.Number()) == 0 { + if chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(block.Number()) == 0 { misc.ApplyDAOHardFork(ibs) } systemcontracts.UpgradeBuildInSystemContract(chainConfig, header.Number, ibs) @@ -129,7 +130,7 @@ func ExecuteBlockEphemerallyForBSC( writeTrace = true } - receipt, _, err := ApplyTransaction(chainConfig, blockHashFunc, engine, nil, gp, ibs, noop, header, tx, usedGas, *vmConfig) + receipt, _, err := ApplyTransaction(chainConfig, blockHashFunc, engine, nil, gp, ibs, noop, header, tx, usedGas, *vmConfig, excessDataGas) if writeTrace { if ftracer, ok := vmConfig.Tracer.(vm.FlushableTracer); ok { ftracer.Flush(tx) @@ -161,9 +162,9 @@ func ExecuteBlockEphemerallyForBSC( // otherwise it causes block verification error. header.GasUsed = *usedGas syscall := func(contract libcommon.Address, data []byte) ([]byte, error) { - return SysCallContract(contract, data, *chainConfig, ibs, header, engine, false /* constCall */) + return SysCallContract(contract, data, *chainConfig, ibs, header, engine, false /* constCall */, excessDataGas) } - outTxs, outReceipts, err := engine.Finalize(chainConfig, header, ibs, block.Transactions(), block.Uncles(), receipts, block.Withdrawals(), epochReader, chainReader, syscall) + outTxs, outReceipts, err := engine.Finalize(chainConfig, header, ibs, block.Transactions(), block.Uncles(), receipts, block.Withdrawals(), chainReader, syscall) if err != nil { return nil, err } @@ -221,16 +222,11 @@ func ExecuteBlockEphemerallyForBSC( // ExecuteBlockEphemerally runs a block from provided stateReader and // writes the result to the provided stateWriter func ExecuteBlockEphemerally( - chainConfig *chain.Config, - vmConfig *vm.Config, + chainConfig *chain.Config, vmConfig *vm.Config, blockHashFunc func(n uint64) libcommon.Hash, - engine consensus.Engine, - block *types.Block, - stateReader state.StateReader, - stateWriter state.WriterWithChangeSets, - epochReader consensus.EpochReader, - chainReader consensus.ChainHeaderReader, - getTracer func(txIndex int, txHash libcommon.Hash) (vm.EVMLogger, error), + engine consensus.Engine, block *types.Block, + stateReader state.StateReader, stateWriter state.WriterWithChangeSets, + chainReader consensus.ChainHeaderReader, getTracer func(txIndex int, txHash libcommon.Hash) (vm.EVMLogger, error), ) (*EphemeralExecResult, error) { defer BlockExecutionTimer.UpdateDuration(time.Now()) @@ -248,13 +244,21 @@ func ExecuteBlockEphemerally( receipts types.Receipts ) + var excessDataGas *big.Int + if chainReader != nil { + // TODO(eip-4844): understand why chainReader is sometimes nil (e.g. certain test cases) + ph := chainReader.GetHeaderByHash(block.ParentHash()) + if ph != nil { + excessDataGas = ph.ExcessDataGas + } + } if !vmConfig.ReadOnly { - if err := InitializeBlockExecution(engine, chainReader, epochReader, block.Header(), block.Transactions(), block.Uncles(), chainConfig, ibs); err != nil { + if err := InitializeBlockExecution(engine, chainReader, block.Header(), block.Transactions(), block.Uncles(), chainConfig, ibs, excessDataGas); err != nil { return nil, err } } - if chainConfig.DAOForkSupport && chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(block.Number()) == 0 { + if chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(block.Number()) == 0 { misc.ApplyDAOHardFork(ibs) } noop := state.NewNoopWriter() @@ -271,7 +275,7 @@ func ExecuteBlockEphemerally( writeTrace = true } - receipt, _, err := ApplyTransaction(chainConfig, blockHashFunc, engine, nil, gp, ibs, noop, header, tx, usedGas, *vmConfig) + receipt, _, err := ApplyTransaction(chainConfig, blockHashFunc, engine, nil, gp, ibs, noop, header, tx, usedGas, *vmConfig, excessDataGas) if writeTrace { if ftracer, ok := vmConfig.Tracer.(vm.FlushableTracer); ok { ftracer.Flush(tx) @@ -310,7 +314,7 @@ func ExecuteBlockEphemerally( } if !vmConfig.ReadOnly { txs := block.Transactions() - if _, _, _, err := FinalizeBlockExecution(engine, stateReader, block.Header(), txs, block.Uncles(), stateWriter, chainConfig, ibs, receipts, block.Withdrawals(), epochReader, chainReader, false); err != nil { + if _, _, _, err := FinalizeBlockExecution(engine, stateReader, block.Header(), txs, block.Uncles(), stateWriter, chainConfig, ibs, receipts, block.Withdrawals(), chainReader, false, excessDataGas); err != nil { return nil, err } } @@ -332,16 +336,11 @@ func ExecuteBlockEphemerally( // ExecuteBlockEphemerallyBor runs a block from provided stateReader and // writes the result to the provided stateWriter func ExecuteBlockEphemerallyBor( - chainConfig *chain.Config, - vmConfig *vm.Config, + chainConfig *chain.Config, vmConfig *vm.Config, blockHashFunc func(n uint64) libcommon.Hash, - engine consensus.Engine, - block *types.Block, - stateReader state.StateReader, - stateWriter state.WriterWithChangeSets, - epochReader consensus.EpochReader, - chainReader consensus.ChainHeaderReader, - getTracer func(txIndex int, txHash libcommon.Hash) (vm.EVMLogger, error), + engine consensus.Engine, block *types.Block, + stateReader state.StateReader, stateWriter state.WriterWithChangeSets, + chainReader consensus.ChainHeaderReader, getTracer func(txIndex int, txHash libcommon.Hash) (vm.EVMLogger, error), ) (*EphemeralExecResult, error) { defer BlockExecutionTimer.UpdateDuration(time.Now()) @@ -359,13 +358,18 @@ func ExecuteBlockEphemerallyBor( receipts types.Receipts ) + var excessDataGas *big.Int + ph := chainReader.GetHeaderByHash(block.ParentHash()) + if ph != nil { + excessDataGas = ph.ExcessDataGas + } if !vmConfig.ReadOnly { - if err := InitializeBlockExecution(engine, chainReader, epochReader, block.Header(), block.Transactions(), block.Uncles(), chainConfig, ibs); err != nil { + if err := InitializeBlockExecution(engine, chainReader, block.Header(), block.Transactions(), block.Uncles(), chainConfig, ibs, excessDataGas); err != nil { return nil, err } } - if chainConfig.DAOForkSupport && chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(block.Number()) == 0 { + if chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(block.Number()) == 0 { misc.ApplyDAOHardFork(ibs) } noop := state.NewNoopWriter() @@ -382,7 +386,7 @@ func ExecuteBlockEphemerallyBor( writeTrace = true } - receipt, _, err := ApplyTransaction(chainConfig, blockHashFunc, engine, nil, gp, ibs, noop, header, tx, usedGas, *vmConfig) + receipt, _, err := ApplyTransaction(chainConfig, blockHashFunc, engine, nil, gp, ibs, noop, header, tx, usedGas, *vmConfig, excessDataGas) if writeTrace { if ftracer, ok := vmConfig.Tracer.(vm.FlushableTracer); ok { ftracer.Flush(tx) @@ -421,7 +425,7 @@ func ExecuteBlockEphemerallyBor( } if !vmConfig.ReadOnly { txs := block.Transactions() - if _, _, _, err := FinalizeBlockExecution(engine, stateReader, block.Header(), txs, block.Uncles(), stateWriter, chainConfig, ibs, receipts, block.Withdrawals(), epochReader, chainReader, false); err != nil { + if _, _, _, err := FinalizeBlockExecution(engine, stateReader, block.Header(), txs, block.Uncles(), stateWriter, chainConfig, ibs, receipts, block.Withdrawals(), chainReader, false, excessDataGas); err != nil { return nil, err } } @@ -467,11 +471,10 @@ func rlpHash(x interface{}) (h libcommon.Hash) { return h } -func SysCallContract(contract libcommon.Address, data []byte, chainConfig chain.Config, ibs *state.IntraBlockState, header *types.Header, engine consensus.EngineReader, constCall bool) (result []byte, err error) { - if chainConfig.DAOForkSupport && chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(header.Number) == 0 { +func SysCallContract(contract libcommon.Address, data []byte, chainConfig chain.Config, ibs *state.IntraBlockState, header *types.Header, engine consensus.EngineReader, constCall bool, excessDataGas *big.Int) (result []byte, err error) { + if chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(header.Number) == 0 { misc.ApplyDAOHardFork(ibs) } - msg := types.NewMessage( state.SystemAddress, &contract, @@ -480,6 +483,7 @@ func SysCallContract(contract libcommon.Address, data []byte, chainConfig chain. nil, nil, data, nil, false, true, // isFree + nil, // maxFeePerDataGas ) vmConfig := vm.Config{NoReceipts: true, RestoreState: constCall} // Create a new context to be used in the EVM environment @@ -493,7 +497,7 @@ func SysCallContract(contract libcommon.Address, data []byte, chainConfig chain. author = &state.SystemAddress txContext = NewEVMTxContext(msg) } - blockContext := NewEVMBlockContext(header, GetHashFn(header, nil), engine, author) + blockContext := NewEVMBlockContext(header, GetHashFn(header, nil), engine, author, excessDataGas) evm := vm.NewEVM(blockContext, txContext, ibs, &chainConfig, vmConfig) ret, _, err := evm.Call( @@ -511,11 +515,10 @@ func SysCallContract(contract libcommon.Address, data []byte, chainConfig chain. } // SysCreate is a special (system) contract creation methods for genesis constructors. -func SysCreate(contract libcommon.Address, data []byte, chainConfig chain.Config, ibs *state.IntraBlockState, header *types.Header) (result []byte, err error) { - if chainConfig.DAOForkSupport && chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(header.Number) == 0 { +func SysCreate(contract libcommon.Address, data []byte, chainConfig chain.Config, ibs *state.IntraBlockState, header *types.Header, excessDataGas *big.Int) (result []byte, err error) { + if chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(header.Number) == 0 { misc.ApplyDAOHardFork(ibs) } - msg := types.NewMessage( contract, nil, // to @@ -524,12 +527,13 @@ func SysCreate(contract libcommon.Address, data []byte, chainConfig chain.Config nil, nil, data, nil, false, true, // isFree + nil, // maxFeePerDataGas ) vmConfig := vm.Config{NoReceipts: true} // Create a new context to be used in the EVM environment author := &contract txContext := NewEVMTxContext(msg) - blockContext := NewEVMBlockContext(header, GetHashFn(header, nil), nil, author) + blockContext := NewEVMBlockContext(header, GetHashFn(header, nil), nil, author, excessDataGas) evm := vm.NewEVM(blockContext, txContext, ibs, &chainConfig, vmConfig) ret, _, err := evm.SysCreate( @@ -542,12 +546,11 @@ func SysCreate(contract libcommon.Address, data []byte, chainConfig chain.Config return ret, err } -func CallContract(contract libcommon.Address, data []byte, chainConfig chain.Config, ibs *state.IntraBlockState, header *types.Header, engine consensus.Engine) (result []byte, err error) { +func CallContract(contract libcommon.Address, data []byte, chainConfig chain.Config, ibs *state.IntraBlockState, header *types.Header, engine consensus.Engine, excessDataGas *big.Int) (result []byte, err error) { gp := new(GasPool) gp.AddGas(50_000_000) var gasUsed uint64 - - if chainConfig.DAOForkSupport && chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(header.Number) == 0 { + if chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(header.Number) == 0 { misc.ApplyDAOHardFork(ibs) } noop := state.NewNoopWriter() @@ -556,7 +559,7 @@ func CallContract(contract libcommon.Address, data []byte, chainConfig chain.Con return nil, fmt.Errorf("SysCallContract: %w ", err) } vmConfig := vm.Config{NoReceipts: true} - _, result, err = ApplyTransaction(&chainConfig, GetHashFn(header, nil), engine, &state.SystemAddress, gp, ibs, noop, header, tx, &gasUsed, vmConfig) + _, result, err = ApplyTransaction(&chainConfig, GetHashFn(header, nil), engine, &state.SystemAddress, gp, ibs, noop, header, tx, &gasUsed, vmConfig, excessDataGas) if err != nil { return result, fmt.Errorf("SysCallContract: %w ", err) } @@ -571,17 +574,21 @@ func CallContractTx(contract libcommon.Address, data []byte, ibs *state.IntraBlo return tx.FakeSign(from) } -func FinalizeBlockExecution(engine consensus.Engine, stateReader state.StateReader, header *types.Header, - txs types.Transactions, uncles []*types.Header, stateWriter state.WriterWithChangeSets, cc *chain.Config, ibs *state.IntraBlockState, - receipts types.Receipts, withdrawals []*types.Withdrawal, e consensus.EpochReader, headerReader consensus.ChainHeaderReader, isMining bool, +func FinalizeBlockExecution( + engine consensus.Engine, stateReader state.StateReader, + header *types.Header, txs types.Transactions, uncles []*types.Header, + stateWriter state.WriterWithChangeSets, cc *chain.Config, + ibs *state.IntraBlockState, receipts types.Receipts, + withdrawals []*types.Withdrawal, headerReader consensus.ChainHeaderReader, + isMining bool, excessDataGas *big.Int, ) (newBlock *types.Block, newTxs types.Transactions, newReceipt types.Receipts, err error) { syscall := func(contract libcommon.Address, data []byte) ([]byte, error) { - return SysCallContract(contract, data, *cc, ibs, header, engine, false /* constCall */) + return SysCallContract(contract, data, *cc, ibs, header, engine, false /* constCall */, excessDataGas) } if isMining { - newBlock, newTxs, newReceipt, err = engine.FinalizeAndAssemble(cc, header, ibs, txs, uncles, receipts, withdrawals, e, headerReader, syscall, nil) + newBlock, newTxs, newReceipt, err = engine.FinalizeAndAssemble(cc, header, ibs, txs, uncles, receipts, withdrawals, headerReader, syscall, nil) } else { - _, _, err = engine.Finalize(cc, header, ibs, txs, uncles, receipts, withdrawals, e, headerReader, syscall) + _, _, err = engine.Finalize(cc, header, ibs, txs, uncles, receipts, withdrawals, headerReader, syscall) } if err != nil { return nil, nil, nil, err @@ -597,9 +604,9 @@ func FinalizeBlockExecution(engine consensus.Engine, stateReader state.StateRead return newBlock, newTxs, newReceipt, nil } -func InitializeBlockExecution(engine consensus.Engine, chain consensus.ChainHeaderReader, epochReader consensus.EpochReader, header *types.Header, txs types.Transactions, uncles []*types.Header, cc *chain.Config, ibs *state.IntraBlockState) error { - engine.Initialize(cc, chain, epochReader, header, ibs, txs, uncles, func(contract libcommon.Address, data []byte) ([]byte, error) { - return SysCallContract(contract, data, *cc, ibs, header, engine, false /* constCall */) +func InitializeBlockExecution(engine consensus.Engine, chain consensus.ChainHeaderReader, header *types.Header, txs types.Transactions, uncles []*types.Header, cc *chain.Config, ibs *state.IntraBlockState, excessDataGas *big.Int) error { + engine.Initialize(cc, chain, header, ibs, txs, uncles, func(contract libcommon.Address, data []byte) ([]byte, error) { + return SysCallContract(contract, data, *cc, ibs, header, engine, false /* constCall */, excessDataGas) }) noop := state.NewNoopWriter() ibs.FinalizeTx(cc.Rules(header.Number.Uint64(), header.Time), noop) diff --git a/core/chain_makers.go b/core/chain_makers.go index 2899758f660..302d3ab7cd6 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -117,7 +117,7 @@ func (b *BlockGen) AddTxWithChain(getHeader func(hash libcommon.Hash, number uin b.SetCoinbase(libcommon.Address{}) } b.ibs.Prepare(tx.Hash(), libcommon.Hash{}, len(b.txs)) - receipt, _, err := ApplyTransaction(b.config, GetHashFn(b.header, getHeader), engine, &b.header.Coinbase, b.gasPool, b.ibs, state.NewNoopWriter(), b.header, tx, &b.header.GasUsed, vm.Config{}) + receipt, _, err := ApplyTransaction(b.config, GetHashFn(b.header, getHeader), engine, &b.header.Coinbase, b.gasPool, b.ibs, state.NewNoopWriter(), b.header, tx, &b.header.GasUsed, vm.Config{}, b.parent.ExcessDataGas()) if err != nil { panic(err) } @@ -130,7 +130,7 @@ func (b *BlockGen) AddFailedTxWithChain(getHeader func(hash libcommon.Hash, numb b.SetCoinbase(libcommon.Address{}) } b.ibs.Prepare(tx.Hash(), libcommon.Hash{}, len(b.txs)) - receipt, _, err := ApplyTransaction(b.config, GetHashFn(b.header, getHeader), engine, &b.header.Coinbase, b.gasPool, b.ibs, state.NewNoopWriter(), b.header, tx, &b.header.GasUsed, vm.Config{}) + receipt, _, err := ApplyTransaction(b.config, GetHashFn(b.header, getHeader), engine, &b.header.Coinbase, b.gasPool, b.ibs, state.NewNoopWriter(), b.header, tx, &b.header.GasUsed, vm.Config{}, b.parent.ExcessDataGas()) _ = err // accept failed transactions b.txs = append(b.txs, tx) b.receipts = append(b.receipts, receipt) @@ -333,7 +333,7 @@ func GenerateChain(config *chain.Config, parent *types.Block, engine consensus.E } if b.engine != nil { // Finalize and seal the block - if _, _, _, err := b.engine.FinalizeAndAssemble(config, b.header, ibs, b.txs, b.uncles, b.receipts, nil /* withdrawals */, nil, nil, nil, nil); err != nil { + if _, _, _, err := b.engine.FinalizeAndAssemble(config, b.header, ibs, b.txs, b.uncles, b.receipts, nil, nil, nil, nil); err != nil { return nil, nil, fmt.Errorf("call to FinaliseAndAssemble: %w", err) } // Write state changes to db diff --git a/core/evm.go b/core/evm.go index 7c03d5c43f5..1e023f68270 100644 --- a/core/evm.go +++ b/core/evm.go @@ -31,7 +31,9 @@ import ( ) // NewEVMBlockContext creates a new context for use in the EVM. -func NewEVMBlockContext(header *types.Header, blockHashFunc func(n uint64) libcommon.Hash, engine consensus.EngineReader, author *libcommon.Address) evmtypes.BlockContext { +// excessDataGas must be set to the excessDataGas value from the *parent* block header, and can be +// nil if the parent block is not of EIP-4844 type. It is read only. +func NewEVMBlockContext(header *types.Header, blockHashFunc func(n uint64) libcommon.Hash, engine consensus.EngineReader, author *libcommon.Address, excessDataGas *big.Int) evmtypes.BlockContext { // If we don't have an explicit author (i.e. not mining), extract from the header var beneficiary libcommon.Address if author == nil { @@ -59,18 +61,24 @@ func NewEVMBlockContext(header *types.Header, blockHashFunc func(n uint64) libco } else { transferFunc = Transfer } - + // In the event excessDataGas is nil (which happens if the parent block is pre-sharding), + // we bootstrap BlockContext.ExcessDataGas with the zero value. + edg := new(big.Int) + if excessDataGas != nil { + edg.Set(excessDataGas) + } return evmtypes.BlockContext{ - CanTransfer: CanTransfer, - Transfer: transferFunc, - GetHash: blockHashFunc, - Coinbase: beneficiary, - BlockNumber: header.Number.Uint64(), - Time: header.Time, - Difficulty: new(big.Int).Set(header.Difficulty), - BaseFee: &baseFee, - GasLimit: header.GasLimit, - PrevRanDao: prevRandDao, + CanTransfer: CanTransfer, + Transfer: transferFunc, + GetHash: blockHashFunc, + Coinbase: beneficiary, + BlockNumber: header.Number.Uint64(), + Time: header.Time, + Difficulty: new(big.Int).Set(header.Difficulty), + BaseFee: &baseFee, + GasLimit: header.GasLimit, + PrevRanDao: prevRandDao, + ExcessDataGas: edg, } } diff --git a/core/forkid/forkid.go b/core/forkid/forkid.go index ddb4ae2b839..f137c4815f6 100644 --- a/core/forkid/forkid.go +++ b/core/forkid/forkid.go @@ -243,6 +243,11 @@ func GatherForks(config *chain.Config) (heightForks []uint64, timeForks []uint64 } } } + + if config.Aura != nil && config.Aura.PosdaoTransition != nil { + heightForks = append(heightForks, *config.Aura.PosdaoTransition) + } + // Sort the fork block numbers & times to permit chronological XOR slices.Sort(heightForks) slices.Sort(timeForks) diff --git a/core/gen_genesis.go b/core/gen_genesis.go index 2a51c5d45f6..cf933fe6a1b 100644 --- a/core/gen_genesis.go +++ b/core/gen_genesis.go @@ -9,9 +9,9 @@ import ( "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/common/math" ) @@ -20,19 +20,22 @@ var _ = (*genesisSpecMarshaling)(nil) // MarshalJSON marshals as JSON. func (g Genesis) MarshalJSON() ([]byte, error) { type Genesis struct { - Config *chain.Config `json:"config"` - Nonce math.HexOrDecimal64 `json:"nonce"` - Timestamp math.HexOrDecimal64 `json:"timestamp"` - ExtraData hexutil.Bytes `json:"extraData"` - GasLimit math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"` - Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"` - Mixhash libcommon.Hash `json:"mixHash"` - Coinbase libcommon.Address `json:"coinbase"` - Alloc map[common.UnprefixedAddress]GenesisAccount `json:"alloc" gencodec:"required"` - Number math.HexOrDecimal64 `json:"number"` - GasUsed math.HexOrDecimal64 `json:"gasUsed"` - ParentHash libcommon.Hash `json:"parentHash"` - BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"` + Config *chain.Config `json:"config"` + Nonce math.HexOrDecimal64 `json:"nonce"` + Timestamp math.HexOrDecimal64 `json:"timestamp"` + ExtraData hexutility.Bytes `json:"extraData"` + GasLimit math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"` + Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"` + Mixhash libcommon.Hash `json:"mixHash"` + Coinbase libcommon.Address `json:"coinbase"` + BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"` + ExcessDataGas *math.HexOrDecimal256 `json:"excessDataGas"` + Alloc map[common.UnprefixedAddress]GenesisAccount `json:"alloc" gencodec:"required"` + AuRaStep math.HexOrDecimal64 `json:"auRaStep"` + AuRaSeal hexutility.Bytes `json:"auRaSeal"` + Number math.HexOrDecimal64 `json:"number"` + GasUsed math.HexOrDecimal64 `json:"gasUsed"` + ParentHash libcommon.Hash `json:"parentHash"` } var enc Genesis enc.Config = g.Config @@ -43,35 +46,41 @@ func (g Genesis) MarshalJSON() ([]byte, error) { enc.Difficulty = (*math.HexOrDecimal256)(g.Difficulty) enc.Mixhash = g.Mixhash enc.Coinbase = g.Coinbase + enc.BaseFee = (*math.HexOrDecimal256)(g.BaseFee) + enc.ExcessDataGas = (*math.HexOrDecimal256)(g.ExcessDataGas) if g.Alloc != nil { enc.Alloc = make(map[common.UnprefixedAddress]GenesisAccount, len(g.Alloc)) for k, v := range g.Alloc { enc.Alloc[common.UnprefixedAddress(k)] = v } } + enc.AuRaStep = math.HexOrDecimal64(g.AuRaStep) + enc.AuRaSeal = g.AuRaSeal enc.Number = math.HexOrDecimal64(g.Number) enc.GasUsed = math.HexOrDecimal64(g.GasUsed) enc.ParentHash = g.ParentHash - enc.BaseFee = (*math.HexOrDecimal256)(g.BaseFee) return json.Marshal(&enc) } // UnmarshalJSON unmarshals from JSON. func (g *Genesis) UnmarshalJSON(input []byte) error { type Genesis struct { - Config *chain.Config `json:"config"` - Nonce *math.HexOrDecimal64 `json:"nonce"` - Timestamp *math.HexOrDecimal64 `json:"timestamp"` - ExtraData *hexutil.Bytes `json:"extraData"` - GasLimit *math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"` - Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"` - Mixhash *libcommon.Hash `json:"mixHash"` - Coinbase *libcommon.Address `json:"coinbase"` - Alloc map[common.UnprefixedAddress]GenesisAccount `json:"alloc" gencodec:"required"` - Number *math.HexOrDecimal64 `json:"number"` - GasUsed *math.HexOrDecimal64 `json:"gasUsed"` - ParentHash *libcommon.Hash `json:"parentHash"` - BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"` + Config *chain.Config `json:"config"` + Nonce *math.HexOrDecimal64 `json:"nonce"` + Timestamp *math.HexOrDecimal64 `json:"timestamp"` + ExtraData *hexutility.Bytes `json:"extraData"` + GasLimit *math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"` + Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"` + Mixhash *libcommon.Hash `json:"mixHash"` + Coinbase *libcommon.Address `json:"coinbase"` + BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"` + ExcessDataGas *math.HexOrDecimal256 `json:"excessDataGas"` + Alloc map[common.UnprefixedAddress]GenesisAccount `json:"alloc" gencodec:"required"` + AuRaStep *math.HexOrDecimal64 `json:"auRaStep"` + AuRaSeal *hexutility.Bytes `json:"auRaSeal"` + Number *math.HexOrDecimal64 `json:"number"` + GasUsed *math.HexOrDecimal64 `json:"gasUsed"` + ParentHash *libcommon.Hash `json:"parentHash"` } var dec Genesis if err := json.Unmarshal(input, &dec); err != nil { @@ -103,6 +112,12 @@ func (g *Genesis) UnmarshalJSON(input []byte) error { if dec.Coinbase != nil { g.Coinbase = *dec.Coinbase } + if dec.BaseFee != nil { + g.BaseFee = (*big.Int)(dec.BaseFee) + } + if dec.ExcessDataGas != nil { + g.ExcessDataGas = (*big.Int)(dec.ExcessDataGas) + } if dec.Alloc == nil { return errors.New("missing required field 'alloc' for Genesis") } @@ -110,6 +125,12 @@ func (g *Genesis) UnmarshalJSON(input []byte) error { for k, v := range dec.Alloc { g.Alloc[libcommon.Address(k)] = v } + if dec.AuRaStep != nil { + g.AuRaStep = uint64(*dec.AuRaStep) + } + if dec.AuRaSeal != nil { + g.AuRaSeal = *dec.AuRaSeal + } if dec.Number != nil { g.Number = uint64(*dec.Number) } @@ -119,8 +140,5 @@ func (g *Genesis) UnmarshalJSON(input []byte) error { if dec.ParentHash != nil { g.ParentHash = *dec.ParentHash } - if dec.BaseFee != nil { - g.BaseFee = (*big.Int)(dec.BaseFee) - } return nil } diff --git a/core/gen_genesis_account.go b/core/gen_genesis_account.go index 49abcea1cba..c9422b403a2 100644 --- a/core/gen_genesis_account.go +++ b/core/gen_genesis_account.go @@ -8,8 +8,8 @@ import ( "math/big" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" - "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/common/math" ) @@ -18,12 +18,12 @@ var _ = (*genesisAccountMarshaling)(nil) // MarshalJSON marshals as JSON. func (g GenesisAccount) MarshalJSON() ([]byte, error) { type GenesisAccount struct { - Constructor hexutil.Bytes `json:"constructor,omitempty"` - Code hexutil.Bytes `json:"code,omitempty"` + Constructor hexutility.Bytes `json:"constructor,omitempty"` + Code hexutility.Bytes `json:"code,omitempty"` Storage map[storageJSON]storageJSON `json:"storage,omitempty"` Balance *math.HexOrDecimal256 `json:"balance" gencodec:"required"` Nonce math.HexOrDecimal64 `json:"nonce,omitempty"` - PrivateKey hexutil.Bytes `json:"secretKey,omitempty"` + PrivateKey hexutility.Bytes `json:"secretKey,omitempty"` } var enc GenesisAccount enc.Constructor = g.Constructor @@ -43,12 +43,12 @@ func (g GenesisAccount) MarshalJSON() ([]byte, error) { // UnmarshalJSON unmarshals from JSON. func (g *GenesisAccount) UnmarshalJSON(input []byte) error { type GenesisAccount struct { - Constructor *hexutil.Bytes `json:"constructor,omitempty"` - Code *hexutil.Bytes `json:"code,omitempty"` + Constructor *hexutility.Bytes `json:"constructor,omitempty"` + Code *hexutility.Bytes `json:"code,omitempty"` Storage map[storageJSON]storageJSON `json:"storage,omitempty"` Balance *math.HexOrDecimal256 `json:"balance" gencodec:"required"` Nonce *math.HexOrDecimal64 `json:"nonce,omitempty"` - PrivateKey *hexutil.Bytes `json:"secretKey,omitempty"` + PrivateKey *hexutility.Bytes `json:"secretKey,omitempty"` } var dec GenesisAccount if err := json.Unmarshal(input, &dec); err != nil { diff --git a/core/genesis.go b/core/genesis.go index 3aa8bb9628c..660ab28fe36 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -17,13 +17,10 @@ package core import ( - "bytes" "context" "embed" "encoding/binary" - "encoding/hex" "encoding/json" - "errors" "fmt" "math/big" "sync" @@ -37,13 +34,13 @@ import ( "github.com/ledgerwatch/erigon-lib/kv/rawdbv3" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/hexutil" - "github.com/ledgerwatch/erigon/common/math" "github.com/ledgerwatch/erigon/consensus/ethash" "github.com/ledgerwatch/erigon/consensus/serenity" "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/state" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/crypto" + "github.com/ledgerwatch/erigon/eth/ethconfig" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/params/networkname" "github.com/ledgerwatch/erigon/turbo/trie" @@ -51,135 +48,12 @@ import ( "golang.org/x/exp/slices" ) -//go:generate gencodec -type Genesis -field-override genesisSpecMarshaling -out gen_genesis.go -//go:generate gencodec -type GenesisAccount -field-override genesisAccountMarshaling -out gen_genesis_account.go - -//go:embed allocs -var allocs embed.FS - -var ErrGenesisNoConfig = errors.New("genesis has no chain configuration") - -// Genesis specifies the header fields, state of a genesis block. It also defines hard -// fork switch-over blocks through the chain configuration. -type Genesis struct { - Config *chain.Config `json:"config"` - Nonce uint64 `json:"nonce"` - Timestamp uint64 `json:"timestamp"` - ExtraData []byte `json:"extraData"` - GasLimit uint64 `json:"gasLimit" gencodec:"required"` - Difficulty *big.Int `json:"difficulty" gencodec:"required"` - Mixhash libcommon.Hash `json:"mixHash"` - Coinbase libcommon.Address `json:"coinbase"` - Alloc GenesisAlloc `json:"alloc" gencodec:"required"` - AuRaStep uint64 `json:"auRaStep"` - AuRaSeal []byte `json:"auRaSeal"` - - // These fields are used for consensus tests. Please don't use them - // in actual genesis blocks. - Number uint64 `json:"number"` - GasUsed uint64 `json:"gasUsed"` - ParentHash libcommon.Hash `json:"parentHash"` - BaseFee *big.Int `json:"baseFeePerGas"` -} - -// GenesisAlloc specifies the initial state that is part of the genesis block. -type GenesisAlloc map[libcommon.Address]GenesisAccount - -type AuthorityRoundSeal struct { - /// Seal step. - Step uint64 `json:"step"` - /// Seal signature. - Signature libcommon.Hash `json:"signature"` -} - -var genesisTmpDB kv.RwDB -var genesisDBLock sync.Mutex - -func (ga *GenesisAlloc) UnmarshalJSON(data []byte) error { - m := make(map[common.UnprefixedAddress]GenesisAccount) - if err := json.Unmarshal(data, &m); err != nil { - return err - } - *ga = make(GenesisAlloc) - for addr, a := range m { - (*ga)[libcommon.Address(addr)] = a - } - return nil -} - -// GenesisAccount is an account in the state of the genesis block. -// Either use "constructor" for deployment code or "code" directly for the final code. -type GenesisAccount struct { - Constructor []byte `json:"constructor,omitempty"` // deployment code - Code []byte `json:"code,omitempty"` // final contract code - Storage map[libcommon.Hash]libcommon.Hash `json:"storage,omitempty"` - Balance *big.Int `json:"balance" gencodec:"required"` - Nonce uint64 `json:"nonce,omitempty"` - PrivateKey []byte `json:"secretKey,omitempty"` // for tests -} - -// field type overrides for gencodec -type genesisSpecMarshaling struct { - Nonce math.HexOrDecimal64 - Timestamp math.HexOrDecimal64 - ExtraData hexutil.Bytes - GasLimit math.HexOrDecimal64 - GasUsed math.HexOrDecimal64 - Number math.HexOrDecimal64 - Difficulty *math.HexOrDecimal256 - BaseFee *math.HexOrDecimal256 - Alloc map[common.UnprefixedAddress]GenesisAccount -} - -type genesisAccountMarshaling struct { - Constructor hexutil.Bytes - Code hexutil.Bytes - Balance *math.HexOrDecimal256 - Nonce math.HexOrDecimal64 - Storage map[storageJSON]storageJSON - PrivateKey hexutil.Bytes -} - -// storageJSON represents a 256 bit byte array, but allows less than 256 bits when -// unmarshaling from hex. -type storageJSON libcommon.Hash - -func (h *storageJSON) UnmarshalText(text []byte) error { - text = bytes.TrimPrefix(text, []byte("0x")) - if len(text) > 64 { - return fmt.Errorf("too many hex characters in storage key/value %q", text) - } - offset := len(h) - len(text)/2 // pad on the left - if _, err := hex.Decode(h[offset:], text); err != nil { - return fmt.Errorf("invalid hex storage key/value %q", text) - } - return nil -} - -func (h storageJSON) MarshalText() ([]byte, error) { - return hexutil.Bytes(h[:]).MarshalText() -} - -// GenesisMismatchError is raised when trying to overwrite an existing -// genesis block with an incompatible one. -type GenesisMismatchError struct { - Stored, New libcommon.Hash -} - -func (e *GenesisMismatchError) Error() string { - config := params.ChainConfigByGenesisHash(e.Stored) - if config == nil { - return fmt.Sprintf("database contains incompatible genesis (have %x, new %x)", e.Stored, e.New) - } - return fmt.Sprintf("database contains incompatible genesis (try with --chain=%s)", config.ChainName) -} - // CommitGenesisBlock writes or updates the genesis block in db. // The block that will be used is: // // genesis == nil genesis != nil // +------------------------------------------ -// db has no genesis | main-net default | genesis +// db has no genesis | main-net | genesis // db has genesis | from DB | genesis (if compatible) // // The stored chain configuration will be updated if it is compatible (i.e. does not @@ -187,11 +61,11 @@ func (e *GenesisMismatchError) Error() string { // error is a *params.ConfigCompatError and the new, unwritten config is returned. // // The returned chain configuration is never nil. -func CommitGenesisBlock(db kv.RwDB, genesis *Genesis, tmpDir string) (*chain.Config, *types.Block, error) { +func CommitGenesisBlock(db kv.RwDB, genesis *types.Genesis, tmpDir string) (*chain.Config, *types.Block, error) { return CommitGenesisBlockWithOverride(db, genesis, nil, tmpDir) } -func CommitGenesisBlockWithOverride(db kv.RwDB, genesis *Genesis, overrideShanghaiTime *big.Int, tmpDir string) (*chain.Config, *types.Block, error) { +func CommitGenesisBlockWithOverride(db kv.RwDB, genesis *types.Genesis, overrideShanghaiTime *big.Int, tmpDir string) (*chain.Config, *types.Block, error) { tx, err := db.BeginRw(context.Background()) if err != nil { return nil, nil, err @@ -208,20 +82,12 @@ func CommitGenesisBlockWithOverride(db kv.RwDB, genesis *Genesis, overrideShangh return c, b, nil } -func MustCommitGenesisBlock(db kv.RwDB, genesis *Genesis, tmpDir string) (*chain.Config, *types.Block) { - c, b, err := CommitGenesisBlock(db, genesis, tmpDir) - if err != nil { - panic(err) - } - return c, b -} - -func WriteGenesisBlock(db kv.RwTx, genesis *Genesis, overrideShanghaiTime *big.Int, tmpDir string) (*chain.Config, *types.Block, error) { +func WriteGenesisBlock(tx kv.RwTx, genesis *types.Genesis, overrideShanghaiTime *big.Int, tmpDir string) (*chain.Config, *types.Block, error) { if genesis != nil && genesis.Config == nil { - return params.AllProtocolChanges, nil, ErrGenesisNoConfig + return params.AllProtocolChanges, nil, types.ErrGenesisNoConfig } // Just commit the new block if there is no stored genesis block. - storedHash, storedErr := rawdb.ReadCanonicalHash(db, 0) + storedHash, storedErr := rawdb.ReadCanonicalHash(tx, 0) if storedErr != nil { return nil, nil, storedErr } @@ -235,12 +101,12 @@ func WriteGenesisBlock(db kv.RwTx, genesis *Genesis, overrideShanghaiTime *big.I if (storedHash == libcommon.Hash{}) { custom := true if genesis == nil { - log.Info("Writing default main-net genesis block") - genesis = DefaultGenesisBlock() + log.Info("Writing main-net genesis block") + genesis = MainnetGenesisBlock() custom = false } applyOverrides(genesis.Config) - block, _, err1 := genesis.Write(db, tmpDir) + block, _, err1 := write(tx, genesis, tmpDir) if err1 != nil { return genesis.Config, nil, err1 } @@ -252,32 +118,32 @@ func WriteGenesisBlock(db kv.RwTx, genesis *Genesis, overrideShanghaiTime *big.I // Check whether the genesis block is already written. if genesis != nil { - block, _, err1 := genesis.ToBlock(tmpDir) + block, _, err1 := GenesisToBlock(genesis, tmpDir) if err1 != nil { return genesis.Config, nil, err1 } hash := block.Hash() if hash != storedHash { - return genesis.Config, block, &GenesisMismatchError{storedHash, hash} + return genesis.Config, block, &types.GenesisMismatchError{Stored: storedHash, New: hash} } } - storedBlock, err := rawdb.ReadBlockByHash(db, storedHash) + storedBlock, err := rawdb.ReadBlockByHash(tx, storedHash) if err != nil { return genesis.Config, nil, err } // Get the existing chain configuration. - newCfg := genesis.configOrDefault(storedHash) + newCfg := genesis.ConfigOrDefault(storedHash) applyOverrides(newCfg) if err := newCfg.CheckConfigForkOrder(); err != nil { return newCfg, nil, err } - storedCfg, storedErr := rawdb.ReadChainConfig(db, storedHash) + storedCfg, storedErr := rawdb.ReadChainConfig(tx, storedHash) if storedErr != nil && newCfg.Bor == nil { return newCfg, nil, storedErr } if storedCfg == nil { log.Warn("Found genesis block without chain config") - err1 := rawdb.WriteChainConfig(db, storedHash, newCfg) + err1 := rawdb.WriteChainConfig(tx, storedHash, newCfg) if err1 != nil { return newCfg, nil, err1 } @@ -292,206 +158,82 @@ func WriteGenesisBlock(db kv.RwTx, genesis *Genesis, overrideShanghaiTime *big.I } // Check config compatibility and write the config. Compatibility errors // are returned to the caller unless we're already at block zero. - height := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db)) + height := rawdb.ReadHeaderNumber(tx, rawdb.ReadHeadHeaderHash(tx)) if height != nil { compatibilityErr := storedCfg.CheckCompatible(newCfg, *height) if compatibilityErr != nil && *height != 0 && compatibilityErr.RewindTo != 0 { return newCfg, storedBlock, compatibilityErr } } - if err := rawdb.WriteChainConfig(db, storedHash, newCfg); err != nil { + if err := rawdb.WriteChainConfig(tx, storedHash, newCfg); err != nil { return newCfg, nil, err } return newCfg, storedBlock, nil } -func (g *Genesis) configOrDefault(genesisHash libcommon.Hash) *chain.Config { - if g != nil { - return g.Config - } - - config := params.ChainConfigByGenesisHash(genesisHash) - if config != nil { - return config - } else { - return params.AllProtocolChanges - } -} - -func sortedAllocKeys(m GenesisAlloc) []string { - keys := make([]string, len(m)) - i := 0 - for k := range m { - keys[i] = string(k.Bytes()) - i++ - } - slices.Sort(keys) - return keys -} - -// ToBlock creates the genesis block and writes state of a genesis specification -// to the given database (or discards it if nil). -func (g *Genesis) ToBlock(tmpDir string) (*types.Block, *state.IntraBlockState, error) { - _ = g.Alloc //nil-check - - head := &types.Header{ - Number: new(big.Int).SetUint64(g.Number), - Nonce: types.EncodeNonce(g.Nonce), - Time: g.Timestamp, - ParentHash: g.ParentHash, - Extra: g.ExtraData, - GasLimit: g.GasLimit, - GasUsed: g.GasUsed, - Difficulty: g.Difficulty, - MixDigest: g.Mixhash, - Coinbase: g.Coinbase, - BaseFee: g.BaseFee, - AuRaStep: g.AuRaStep, - AuRaSeal: g.AuRaSeal, - } - if g.GasLimit == 0 { - head.GasLimit = params.GenesisGasLimit - } - if g.Difficulty == nil { - head.Difficulty = params.GenesisDifficulty - } - if g.Config != nil && (g.Config.IsLondon(0)) { - if g.BaseFee != nil { - head.BaseFee = g.BaseFee - } else { - head.BaseFee = new(big.Int).SetUint64(params.InitialBaseFee) - } - } - - var withdrawals []*types.Withdrawal - if g.Config != nil && (g.Config.IsShanghai(g.Timestamp)) { - withdrawals = []*types.Withdrawal{} - } - - var root libcommon.Hash - var statedb *state.IntraBlockState - wg := sync.WaitGroup{} - wg.Add(1) - var err error - go func() { // we may run inside write tx, can't open 2nd write tx in same goroutine - // TODO(yperbasis): use memdb.MemoryMutation instead - defer wg.Done() - genesisDBLock.Lock() - defer genesisDBLock.Unlock() - if genesisTmpDB == nil { - genesisTmpDB = mdbx.NewMDBX(log.New()).InMem(tmpDir).MapSize(2 * datasize.GB).PageSize(2 * 4096).MustOpen() - } - var tx kv.RwTx - if tx, err = genesisTmpDB.BeginRw(context.Background()); err != nil { - return - } - defer tx.Rollback() - r, w := state.NewDbStateReader(tx), state.NewDbStateWriter(tx, 0) - statedb = state.New(r) - - hasConstructorAllocation := false - for _, account := range g.Alloc { - if len(account.Constructor) > 0 { - hasConstructorAllocation = true - break - } - } - // See https://github.com/NethermindEth/nethermind/blob/master/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/LoadGenesisBlockAuRa.cs - if hasConstructorAllocation && g.Config.Aura != nil { - statedb.CreateAccount(libcommon.Address{}, false) - } - - keys := sortedAllocKeys(g.Alloc) - for _, key := range keys { - addr := libcommon.BytesToAddress([]byte(key)) - account := g.Alloc[addr] - - balance, overflow := uint256.FromBig(account.Balance) - if overflow { - panic("overflow at genesis allocs") - } - statedb.AddBalance(addr, balance) - statedb.SetCode(addr, account.Code) - statedb.SetNonce(addr, account.Nonce) - for key, value := range account.Storage { - key := key - val := uint256.NewInt(0).SetBytes(value.Bytes()) - statedb.SetState(addr, &key, *val) - } - - if len(account.Constructor) > 0 { - if _, err = SysCreate(addr, account.Constructor, *g.Config, statedb, head); err != nil { - return - } - } - - if len(account.Code) > 0 || len(account.Storage) > 0 || len(account.Constructor) > 0 { - statedb.SetIncarnation(addr, state.FirstContractIncarnation) - } - } - if err = statedb.FinalizeTx(&chain.Rules{}, w); err != nil { - return - } - if root, err = trie.CalcRoot("genesis", tx); err != nil { - return - } - }() - wg.Wait() +func WriteGenesisState(g *types.Genesis, tx kv.RwTx, tmpDir string) (*types.Block, *state.IntraBlockState, error) { + block, statedb, err := GenesisToBlock(g, tmpDir) if err != nil { return nil, nil, err } - - head.Root = root - - return types.NewBlock(head, nil, nil, nil, withdrawals), statedb, nil -} - -func (g *Genesis) WriteGenesisState(tx kv.RwTx, tmpDir string) (*types.Block, *state.IntraBlockState, error) { - block, statedb, err := g.ToBlock(tmpDir) - if err != nil { - return nil, nil, err - } - for addr, account := range g.Alloc { - if len(account.Code) > 0 || len(account.Storage) > 0 { - // Special case for weird tests - inaccessible storage - var b [8]byte - binary.BigEndian.PutUint64(b[:], state.FirstContractIncarnation) - if err := tx.Put(kv.IncarnationMap, addr[:], b[:]); err != nil { - return nil, nil, err + var stateWriter state.StateWriter + if ethconfig.EnableHistoryV4InTest { + panic("implement me") + //tx.(*temporal.Tx).Agg().SetTxNum(0) + //stateWriter = state.NewWriterV4(tx.(kv.TemporalTx)) + //defer tx.(*temporal.Tx).Agg().StartUnbufferedWrites().FinishWrites() + } else { + for addr, account := range g.Alloc { + if len(account.Code) > 0 || len(account.Storage) > 0 { + // Special case for weird tests - inaccessible storage + var b [8]byte + binary.BigEndian.PutUint64(b[:], state.FirstContractIncarnation) + if err := tx.Put(kv.IncarnationMap, addr[:], b[:]); err != nil { + return nil, nil, err + } } } + stateWriter = state.NewPlainStateWriter(tx, tx, 0) } if block.Number().Sign() != 0 { return nil, statedb, fmt.Errorf("can't commit genesis block with number > 0") } - blockWriter := state.NewPlainStateWriter(tx, tx, 0) - - if err := statedb.CommitBlock(&chain.Rules{}, blockWriter); err != nil { + if err := statedb.CommitBlock(&chain.Rules{}, stateWriter); err != nil { return nil, statedb, fmt.Errorf("cannot write state: %w", err) } - if err := blockWriter.WriteChangeSets(); err != nil { - return nil, statedb, fmt.Errorf("cannot write change sets: %w", err) - } - if err := blockWriter.WriteHistory(); err != nil { - return nil, statedb, fmt.Errorf("cannot write history: %w", err) + if csw, ok := stateWriter.(state.WriterWithChangeSets); ok { + if err := csw.WriteChangeSets(); err != nil { + return nil, statedb, fmt.Errorf("cannot write change sets: %w", err) + } + if err := csw.WriteHistory(); err != nil { + return nil, statedb, fmt.Errorf("cannot write history: %w", err) + } } return block, statedb, nil } - -func (g *Genesis) MustWrite(tx kv.RwTx, tmpDir string, history bool) (*types.Block, *state.IntraBlockState) { - b, s, err := g.Write(tx, tmpDir) +func MustCommitGenesis(g *types.Genesis, db kv.RwDB, tmpDir string) *types.Block { + tx, err := db.BeginRw(context.Background()) if err != nil { panic(err) } - return b, s + defer tx.Rollback() + block, _, err := write(tx, g, tmpDir) + if err != nil { + panic(err) + } + err = tx.Commit() + if err != nil { + panic(err) + } + return block } // Write writes the block and state of a genesis specification to the database. // The block is committed as the canonical head block. -func (g *Genesis) Write(tx kv.RwTx, tmpDir string) (*types.Block, *state.IntraBlockState, error) { - block, statedb, err2 := g.WriteGenesisState(tx, tmpDir) +func write(tx kv.RwTx, g *types.Genesis, tmpDir string) (*types.Block, *state.IntraBlockState, error) { + block, statedb, err2 := WriteGenesisState(g, tx, tmpDir) if err2 != nil { return block, statedb, err2 } @@ -551,26 +293,10 @@ func (g *Genesis) Write(tx kv.RwTx, tmpDir string) (*types.Block, *state.IntraBl return block, statedb, rawdb.WriteTotalBurnt(tx, 0, libcommon.Big0) } -// MustCommit writes the genesis block and state to db, panicking on error. -// The block is committed as the canonical head block. -func (g *Genesis) MustCommit(db kv.RwDB, tmpDir string) *types.Block { - tx, err := db.BeginRw(context.Background()) - if err != nil { - panic(err) - } - defer tx.Rollback() - block, _ := g.MustWrite(tx, tmpDir, true) - err = tx.Commit() - if err != nil { - panic(err) - } - return block -} - // GenesisBlockForTesting creates and writes a block in which addr has the given wei balance. func GenesisBlockForTesting(db kv.RwDB, addr libcommon.Address, balance *big.Int, tmpDir string) *types.Block { - g := Genesis{Alloc: GenesisAlloc{addr: {Balance: balance}}, Config: params.TestChainConfig} - block := g.MustCommit(db, tmpDir) + g := types.Genesis{Alloc: types.GenesisAlloc{addr: {Balance: balance}}, Config: params.TestChainConfig} + block := MustCommitGenesis(&g, db, tmpDir) return block } @@ -580,19 +306,19 @@ type GenAccount struct { } func GenesisWithAccounts(db kv.RwDB, accs []GenAccount, tmpDir string) *types.Block { - g := Genesis{Config: params.TestChainConfig} - allocs := make(map[libcommon.Address]GenesisAccount) + g := types.Genesis{Config: params.TestChainConfig} + allocs := make(map[libcommon.Address]types.GenesisAccount) for _, acc := range accs { - allocs[acc.Addr] = GenesisAccount{Balance: acc.Balance} + allocs[acc.Addr] = types.GenesisAccount{Balance: acc.Balance} } g.Alloc = allocs - block := g.MustCommit(db, tmpDir) + block := MustCommitGenesis(&g, db, tmpDir) return block } -// DefaultGenesisBlock returns the Ethereum main net genesis block. -func DefaultGenesisBlock() *Genesis { - return &Genesis{ +// MainnetGenesisBlock returns the Ethereum main net genesis block. +func MainnetGenesisBlock() *types.Genesis { + return &types.Genesis{ Config: params.MainnetChainConfig, Nonce: 66, ExtraData: hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"), @@ -602,9 +328,9 @@ func DefaultGenesisBlock() *Genesis { } } -// DefaultSepoliaGenesisBlock returns the Sepolia network genesis block. -func DefaultSepoliaGenesisBlock() *Genesis { - return &Genesis{ +// SepoliaGenesisBlock returns the Sepolia network genesis block. +func SepoliaGenesisBlock() *types.Genesis { + return &types.Genesis{ Config: params.SepoliaChainConfig, Nonce: 0, ExtraData: []byte("Sepolia, Athens, Attica, Greece!"), @@ -615,9 +341,9 @@ func DefaultSepoliaGenesisBlock() *Genesis { } } -// DefaultRinkebyGenesisBlock returns the Rinkeby network genesis block. -func DefaultRinkebyGenesisBlock() *Genesis { - return &Genesis{ +// RinkebyGenesisBlock returns the Rinkeby network genesis block. +func RinkebyGenesisBlock() *types.Genesis { + return &types.Genesis{ Config: params.RinkebyChainConfig, Timestamp: 1492009146, ExtraData: hexutil.MustDecode("0x52657370656374206d7920617574686f7269746168207e452e436172746d616e42eb768f2244c8811c63729a21a3569731535f067ffc57839b00206d1ad20c69a1981b489f772031b279182d99e65703f0076e4812653aab85fca0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), @@ -627,9 +353,9 @@ func DefaultRinkebyGenesisBlock() *Genesis { } } -// DefaultGoerliGenesisBlock returns the Görli network genesis block. -func DefaultGoerliGenesisBlock() *Genesis { - return &Genesis{ +// GoerliGenesisBlock returns the Görli network genesis block. +func GoerliGenesisBlock() *types.Genesis { + return &types.Genesis{ Config: params.GoerliChainConfig, Timestamp: 1548854791, ExtraData: hexutil.MustDecode("0x22466c6578692069732061207468696e6722202d204166726900000000000000e0a2bd4258d2768837baa26a28fe71dc079f84c70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), @@ -639,22 +365,8 @@ func DefaultGoerliGenesisBlock() *Genesis { } } -func DefaultSokolGenesisBlock() *Genesis { - /* - header rlp: f9020da00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0fad4af258fd11939fae0c6c6eec9d340b1caac0b0196fd9a1bc3f489c5bf00b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200008083663be080808080b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 - */ - return &Genesis{ - Config: params.SokolChainConfig, - Timestamp: 0x0, - AuRaSeal: common.FromHex("0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), - GasLimit: 0x663BE0, - Difficulty: big.NewInt(0x20000), - Alloc: readPrealloc("allocs/sokol.json"), - } -} - -func DefaultBSCGenesisBlock() *Genesis { - return &Genesis{ +func BSCGenesisBlock() *types.Genesis { + return &types.Genesis{ Config: params.BSCChainConfig, Nonce: 0x00, Timestamp: 0x5e9da7ce, @@ -669,8 +381,8 @@ func DefaultBSCGenesisBlock() *Genesis { } } -func DefaultChapelGenesisBlock() *Genesis { - return &Genesis{ +func ChapelGenesisBlock() *types.Genesis { + return &types.Genesis{ Config: params.ChapelChainConfig, Nonce: 0x00, Timestamp: 0x5e9da7ce, @@ -685,8 +397,8 @@ func DefaultChapelGenesisBlock() *Genesis { } } -func DefaultRialtoGenesisBlock() *Genesis { - return &Genesis{ +func RialtoGenesisBlock() *types.Genesis { + return &types.Genesis{ Config: params.RialtoChainConfig, Nonce: 0x00, Timestamp: 0x5e9da7ce, @@ -701,8 +413,8 @@ func DefaultRialtoGenesisBlock() *Genesis { } } -func DefaultMumbaiGenesisBlock() *Genesis { - return &Genesis{ +func MumbaiGenesisBlock() *types.Genesis { + return &types.Genesis{ Config: params.MumbaiChainConfig, Nonce: 0, Timestamp: 1558348305, @@ -714,9 +426,9 @@ func DefaultMumbaiGenesisBlock() *Genesis { } } -// DefaultBorMainnet returns the Bor Mainnet network gensis block. -func DefaultBorMainnetGenesisBlock() *Genesis { - return &Genesis{ +// BorMainnetGenesisBlock returns the Bor Mainnet network genesis block. +func BorMainnetGenesisBlock() *types.Genesis { + return &types.Genesis{ Config: params.BorMainnetChainConfig, Nonce: 0, Timestamp: 1590824836, @@ -728,8 +440,8 @@ func DefaultBorMainnetGenesisBlock() *Genesis { } } -func DefaultBorDevnetGenesisBlock() *Genesis { - return &Genesis{ +func BorDevnetGenesisBlock() *types.Genesis { + return &types.Genesis{ Config: params.BorDevnetChainConfig, Nonce: 0, Timestamp: 1558348305, @@ -741,8 +453,8 @@ func DefaultBorDevnetGenesisBlock() *Genesis { } } -func DefaultGnosisGenesisBlock() *Genesis { - return &Genesis{ +func GnosisGenesisBlock() *types.Genesis { + return &types.Genesis{ Config: params.GnosisChainConfig, Timestamp: 0, AuRaSeal: common.FromHex("0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), @@ -752,8 +464,8 @@ func DefaultGnosisGenesisBlock() *Genesis { } } -func DefaultChiadoGenesisBlock() *Genesis { - return &Genesis{ +func ChiadoGenesisBlock() *types.Genesis { + return &types.Genesis{ Config: params.ChiadoChainConfig, Timestamp: 0, AuRaSeal: common.FromHex("0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), @@ -771,13 +483,13 @@ var DevnetSignPrivateKey, _ = crypto.HexToECDSA("26e86e45f6fc45ec6e2ecd128cec80f var DevnetEtherbase = libcommon.HexToAddress("67b1d87101671b127f5f8714789c7192f7ad340e") // DeveloperGenesisBlock returns the 'geth --dev' genesis block. -func DeveloperGenesisBlock(period uint64, faucet libcommon.Address) *Genesis { +func DeveloperGenesisBlock(period uint64, faucet libcommon.Address) *types.Genesis { // Override the default period to the user requested one config := *params.AllCliqueProtocolChanges config.Clique.Period = period // Assemble and return the genesis with the precompiles and faucet pre-funded - return &Genesis{ + return &types.Genesis{ Config: &config, ExtraData: append(append(make([]byte, 32), faucet[:]...), make([]byte, crypto.SignatureLength)...), GasLimit: 11500000, @@ -786,14 +498,149 @@ func DeveloperGenesisBlock(period uint64, faucet libcommon.Address) *Genesis { } } -func readPrealloc(filename string) GenesisAlloc { +var genesisTmpDB kv.RwDB +var genesisDBLock sync.Mutex + +// ToBlock creates the genesis block and writes state of a genesis specification +// to the given database (or discards it if nil). +func GenesisToBlock(g *types.Genesis, tmpDir string) (*types.Block, *state.IntraBlockState, error) { + _ = g.Alloc //nil-check + + head := &types.Header{ + Number: new(big.Int).SetUint64(g.Number), + Nonce: types.EncodeNonce(g.Nonce), + Time: g.Timestamp, + ParentHash: g.ParentHash, + Extra: g.ExtraData, + GasLimit: g.GasLimit, + GasUsed: g.GasUsed, + Difficulty: g.Difficulty, + MixDigest: g.Mixhash, + Coinbase: g.Coinbase, + BaseFee: g.BaseFee, + ExcessDataGas: g.ExcessDataGas, + AuRaStep: g.AuRaStep, + AuRaSeal: g.AuRaSeal, + } + if g.GasLimit == 0 { + head.GasLimit = params.GenesisGasLimit + } + if g.Difficulty == nil { + head.Difficulty = params.GenesisDifficulty + } + if g.Config != nil && (g.Config.IsLondon(0)) { + if g.BaseFee != nil { + head.BaseFee = g.BaseFee + } else { + head.BaseFee = new(big.Int).SetUint64(params.InitialBaseFee) + } + } + + var withdrawals []*types.Withdrawal + if g.Config != nil && (g.Config.IsShanghai(g.Timestamp)) { + withdrawals = []*types.Withdrawal{} + } + + var root libcommon.Hash + var statedb *state.IntraBlockState + wg := sync.WaitGroup{} + wg.Add(1) + var err error + go func() { // we may run inside write tx, can't open 2nd write tx in same goroutine + // TODO(yperbasis): use memdb.MemoryMutation instead + defer wg.Done() + genesisDBLock.Lock() + defer genesisDBLock.Unlock() + if genesisTmpDB == nil { + genesisTmpDB = mdbx.NewMDBX(log.New()).InMem(tmpDir).MapSize(2 * datasize.GB).MustOpen() + } + var tx kv.RwTx + if tx, err = genesisTmpDB.BeginRw(context.Background()); err != nil { + return + } + defer tx.Rollback() + r, w := state.NewDbStateReader(tx), state.NewDbStateWriter(tx, 0) + statedb = state.New(r) + + hasConstructorAllocation := false + for _, account := range g.Alloc { + if len(account.Constructor) > 0 { + hasConstructorAllocation = true + break + } + } + // See https://github.com/NethermindEth/nethermind/blob/master/src/Nethermind/Nethermind.Consensus.AuRa/InitializationSteps/LoadGenesisBlockAuRa.cs + if hasConstructorAllocation && g.Config.Aura != nil { + statedb.CreateAccount(libcommon.Address{}, false) + } + + keys := sortedAllocKeys(g.Alloc) + for _, key := range keys { + addr := libcommon.BytesToAddress([]byte(key)) + account := g.Alloc[addr] + + balance, overflow := uint256.FromBig(account.Balance) + if overflow { + panic("overflow at genesis allocs") + } + statedb.AddBalance(addr, balance) + statedb.SetCode(addr, account.Code) + statedb.SetNonce(addr, account.Nonce) + for key, value := range account.Storage { + key := key + val := uint256.NewInt(0).SetBytes(value.Bytes()) + statedb.SetState(addr, &key, *val) + } + + if len(account.Constructor) > 0 { + if _, err = SysCreate(addr, account.Constructor, *g.Config, statedb, head, g.ExcessDataGas); err != nil { + return + } + } + + if len(account.Code) > 0 || len(account.Storage) > 0 || len(account.Constructor) > 0 { + statedb.SetIncarnation(addr, state.FirstContractIncarnation) + } + } + if err = statedb.FinalizeTx(&chain.Rules{}, w); err != nil { + return + } + if root, err = trie.CalcRoot("genesis", tx); err != nil { + return + } + }() + wg.Wait() + if err != nil { + return nil, nil, err + } + + head.Root = root + + return types.NewBlock(head, nil, nil, nil, withdrawals), statedb, nil +} + +func sortedAllocKeys(m types.GenesisAlloc) []string { + keys := make([]string, len(m)) + i := 0 + for k := range m { + keys[i] = string(k.Bytes()) + i++ + } + slices.Sort(keys) + return keys +} + +//go:embed allocs +var allocs embed.FS + +func readPrealloc(filename string) types.GenesisAlloc { f, err := allocs.Open(filename) if err != nil { panic(fmt.Sprintf("Could not open genesis preallocation for %s: %v", filename, err)) } defer f.Close() decoder := json.NewDecoder(f) - ga := make(GenesisAlloc) + ga := make(types.GenesisAlloc) err = decoder.Decode(&ga) if err != nil { panic(fmt.Sprintf("Could not parse genesis preallocation for %s: %v", filename, err)) @@ -801,34 +648,32 @@ func readPrealloc(filename string) GenesisAlloc { return ga } -func DefaultGenesisBlockByChainName(chain string) *Genesis { +func GenesisBlockByChainName(chain string) *types.Genesis { switch chain { case networkname.MainnetChainName: - return DefaultGenesisBlock() + return MainnetGenesisBlock() case networkname.SepoliaChainName: - return DefaultSepoliaGenesisBlock() + return SepoliaGenesisBlock() case networkname.RinkebyChainName: - return DefaultRinkebyGenesisBlock() + return RinkebyGenesisBlock() case networkname.GoerliChainName: - return DefaultGoerliGenesisBlock() - case networkname.SokolChainName: - return DefaultSokolGenesisBlock() + return GoerliGenesisBlock() case networkname.BSCChainName: - return DefaultBSCGenesisBlock() + return BSCGenesisBlock() case networkname.ChapelChainName: - return DefaultChapelGenesisBlock() + return ChapelGenesisBlock() case networkname.RialtoChainName: - return DefaultRialtoGenesisBlock() + return RialtoGenesisBlock() case networkname.MumbaiChainName: - return DefaultMumbaiGenesisBlock() + return MumbaiGenesisBlock() case networkname.BorMainnetChainName: - return DefaultBorMainnetGenesisBlock() + return BorMainnetGenesisBlock() case networkname.BorDevnetChainName: - return DefaultBorDevnetGenesisBlock() + return BorDevnetGenesisBlock() case networkname.GnosisChainName: - return DefaultGnosisGenesisBlock() + return GnosisGenesisBlock() case networkname.ChiadoChainName: - return DefaultChiadoGenesisBlock() + return ChiadoGenesisBlock() default: return nil } diff --git a/core/genesis_test.go b/core/genesis_test.go index 2bfb531674c..bd714cd82f4 100644 --- a/core/genesis_test.go +++ b/core/genesis_test.go @@ -19,13 +19,12 @@ import ( "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/params/networkname" - "github.com/ledgerwatch/erigon/rlp" ) -func TestDefaultGenesisBlockHashes(t *testing.T) { +func TestGenesisBlockHashes(t *testing.T) { db := memdb.NewTestDB(t) check := func(network string) { - genesis := core.DefaultGenesisBlockByChainName(network) + genesis := core.GenesisBlockByChainName(network) tx, err := db.BeginRw(context.Background()) if err != nil { t.Fatal(err) @@ -42,25 +41,16 @@ func TestDefaultGenesisBlockHashes(t *testing.T) { } } -func TestDefaultGenesisBlockRoots(t *testing.T) { +func TestGenesisBlockRoots(t *testing.T) { require := require.New(t) var err error - block, _, _ := core.DefaultGenesisBlock().ToBlock("") + block, _, _ := core.GenesisToBlock(core.MainnetGenesisBlock(), "") if block.Hash() != params.MainnetGenesisHash { t.Errorf("wrong mainnet genesis hash, got %v, want %v", block.Hash(), params.MainnetGenesisHash) } - block, _, err = core.DefaultSokolGenesisBlock().ToBlock("") - require.NoError(err) - if block.Root() != params.SokolGenesisStateRoot { - t.Errorf("wrong Sokol genesis state root, got %v, want %v", block.Root(), params.SokolGenesisStateRoot) - } - if block.Hash() != params.SokolGenesisHash { - t.Errorf("wrong Sokol genesis hash, got %v, want %v", block.Hash(), params.SokolGenesisHash) - } - - block, _, err = core.DefaultGnosisGenesisBlock().ToBlock("") + block, _, err = core.GenesisToBlock(core.GnosisGenesisBlock(), "") require.NoError(err) if block.Root() != params.GnosisGenesisStateRoot { t.Errorf("wrong Gnosis Chain genesis state root, got %v, want %v", block.Root(), params.GnosisGenesisStateRoot) @@ -69,7 +59,7 @@ func TestDefaultGenesisBlockRoots(t *testing.T) { t.Errorf("wrong Gnosis Chain genesis hash, got %v, want %v", block.Hash(), params.GnosisGenesisHash) } - block, _, err = core.DefaultChiadoGenesisBlock().ToBlock("") + block, _, err = core.GenesisToBlock(core.ChiadoGenesisBlock(), "") require.NoError(err) if block.Root() != params.ChiadoGenesisStateRoot { t.Errorf("wrong Chiado genesis state root, got %v, want %v", block.Root(), params.ChiadoGenesisStateRoot) @@ -81,7 +71,7 @@ func TestDefaultGenesisBlockRoots(t *testing.T) { func TestCommitGenesisIdempotency(t *testing.T) { _, tx := memdb.NewTestTx(t) - genesis := core.DefaultGenesisBlockByChainName(networkname.MainnetChainName) + genesis := core.GenesisBlockByChainName(networkname.MainnetChainName) _, _, err := core.WriteGenesisBlock(tx, genesis, nil, "") require.NoError(t, err) seq, err := tx.ReadSequence(kv.EthTx) @@ -95,55 +85,6 @@ func TestCommitGenesisIdempotency(t *testing.T) { require.Equal(t, uint64(2), seq) } -func TestSokolHeaderRLP(t *testing.T) { - require := require.New(t) - { //sokol - expect := common.FromHex("f9020da00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0fad4af258fd11939fae0c6c6eec9d340b1caac0b0196fd9a1bc3f489c5bf00b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200008083663be080808080b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") - block, _, err := core.DefaultSokolGenesisBlock().ToBlock("") - require.NoError(err) - b, err := rlp.EncodeToBytes(block.Header()) - require.NoError(err) - require.Equal(expect, b) - h := &types.Header{} - err = rlp.DecodeBytes(expect, h) - require.NoError(err) - - expectSeal := common.FromHex("0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") - require.Equal(uint64(0), h.AuRaStep) - require.Equal(expectSeal, h.AuRaSeal) - - enc, err := rlp.EncodeToBytes(h) - require.NoError(err) - require.Equal(expect, enc) - } - - { // sokol, more seals - h := &types.Header{} - enc := common.FromHex("f9020da00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0fad4af258fd11939fae0c6c6eec9d340b1caac0b0196fd9a1bc3f489c5bf00b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200008083663be080808002b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001") - err := rlp.DecodeBytes(enc, h) - require.NoError(err) - require.Equal(uint64(2), h.AuRaStep) - - expectSeal := common.FromHex("0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001") - require.Equal(expectSeal, h.AuRaSeal) - - res, err := rlp.EncodeToBytes(h) // after encode getting source bytes - require.NoError(err) - require.Equal(enc, res) - } - - { // ethash - expect := common.FromHex("f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23") - h := &types.Header{} - err := rlp.DecodeBytes(expect, h) - require.NoError(err) - - res, err := rlp.EncodeToBytes(h) // after encode getting source bytes - require.NoError(err) - require.Equal(expect, res) - } -} - func TestAllocConstructor(t *testing.T) { require := require.New(t) assert := assert.New(t) @@ -154,9 +95,9 @@ func TestAllocConstructor(t *testing.T) { funds := big.NewInt(1000000000) address := libcommon.HexToAddress("0x1000000000000000000000000000000000000001") - genSpec := &core.Genesis{ + genSpec := &types.Genesis{ Config: params.AllProtocolChanges, - Alloc: core.GenesisAlloc{ + Alloc: types.GenesisAlloc{ address: {Constructor: deploymentCode, Balance: funds}, }, } diff --git a/core/state/database_test.go b/core/state/database_test.go index e498b97fecf..086955691eb 100644 --- a/core/state/database_test.go +++ b/core/state/database_test.go @@ -31,11 +31,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/ledgerwatch/erigon/turbo/stages" - "github.com/ledgerwatch/erigon/turbo/trie" - "github.com/ledgerwatch/erigon/accounts/abi/bind" "github.com/ledgerwatch/erigon/accounts/abi/bind/backends" + "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/core/rawdb" @@ -45,6 +43,8 @@ import ( "github.com/ledgerwatch/erigon/core/types/accounts" "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/params" + "github.com/ledgerwatch/erigon/turbo/stages" + "github.com/ledgerwatch/erigon/turbo/trie" ) // Create revival problem diff --git a/core/state/dump.go b/core/state/dump.go index 6eaaa5fc9b0..d2ccec5c174 100644 --- a/core/state/dump.go +++ b/core/state/dump.go @@ -22,14 +22,14 @@ import ( "fmt" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv/order" "github.com/ledgerwatch/erigon-lib/kv/rawdbv3" - "github.com/ledgerwatch/erigon/core/state/temporal" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/dbutils" - "github.com/ledgerwatch/erigon/common/hexutil" + "github.com/ledgerwatch/erigon/core/state/temporal" "github.com/ledgerwatch/erigon/core/types/accounts" "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/turbo/trie" @@ -46,12 +46,12 @@ type Dumper struct { type DumpAccount struct { Balance string `json:"balance"` Nonce uint64 `json:"nonce"` - Root hexutil.Bytes `json:"root"` - CodeHash hexutil.Bytes `json:"codeHash"` - Code hexutil.Bytes `json:"code,omitempty"` + Root hexutility.Bytes `json:"root"` + CodeHash hexutility.Bytes `json:"codeHash"` + Code hexutility.Bytes `json:"code,omitempty"` Storage map[string]string `json:"storage,omitempty"` Address *libcommon.Address `json:"address,omitempty"` // Address only present in iterative (line-by-line) mode - SecureKey *hexutil.Bytes `json:"key,omitempty"` // If we don't have address, we can output the key + SecureKey *hexutility.Bytes `json:"key,omitempty"` // If we don't have address, we can output the key } // Dump represents the full dump in a collected format, as one large map. @@ -190,8 +190,8 @@ func (d *Dumper) DumpToCollector(c DumpCollector, excludeCode, excludeStorage bo account := DumpAccount{ Balance: acc.Balance.ToBig().String(), Nonce: acc.Nonce, - Root: hexutil.Bytes(emptyHash[:]), // We cannot provide historical storage hash - CodeHash: hexutil.Bytes(emptyCodeHash[:]), + Root: hexutility.Bytes(emptyHash[:]), // We cannot provide historical storage hash + CodeHash: hexutility.Bytes(emptyCodeHash[:]), Storage: make(map[string]string), } accountList = append(accountList, &account) @@ -219,8 +219,8 @@ func (d *Dumper) DumpToCollector(c DumpCollector, excludeCode, excludeStorage bo account := DumpAccount{ Balance: acc.Balance.ToBig().String(), Nonce: acc.Nonce, - Root: hexutil.Bytes(emptyHash[:]), // We cannot provide historical storage hash - CodeHash: hexutil.Bytes(emptyCodeHash[:]), + Root: hexutility.Bytes(emptyHash[:]), // We cannot provide historical storage hash + CodeHash: hexutility.Bytes(emptyCodeHash[:]), Storage: make(map[string]string), } accountList = append(accountList, &account) diff --git a/core/state/rw_v3.go b/core/state/rw_v3.go index e81aac9718f..b89fa3bba8f 100644 --- a/core/state/rw_v3.go +++ b/core/state/rw_v3.go @@ -2,7 +2,6 @@ package state import ( "bytes" - "container/heap" "context" "encoding/binary" "encoding/hex" @@ -11,6 +10,7 @@ import ( "time" "unsafe" + "github.com/VictoriaMetrics/metrics" "github.com/holiman/uint256" "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/dbg" @@ -24,130 +24,227 @@ import ( "github.com/ledgerwatch/erigon/turbo/shards" "github.com/ledgerwatch/log/v3" btree2 "github.com/tidwall/btree" - atomic2 "go.uber.org/atomic" ) const CodeSizeTable = "CodeSize" +const StorageTable = "Storage" + +var ExecTxsDone = metrics.NewCounter(`exec_txs_done`) type StateV3 struct { - lock sync.RWMutex - receiveWork *sync.Cond + lock sync.RWMutex + sizeEstimate int + chCode map[string][]byte + chAccs map[string][]byte + chStorage *btree2.Map[string, []byte] + chIncs map[string][]byte + chContractCode map[string][]byte + triggers map[uint64]*exec22.TxTask senderTxNums map[common.Address]uint64 triggerLock sync.Mutex - queue exec22.TxTaskQueue - queueLock sync.Mutex - changes map[string]*btree2.Map[string, []byte] - sizeEstimate int - txsDone *atomic2.Uint64 - finished atomic2.Bool + + tmpdir string + applyPrevAccountBuf []byte // buffer for ApplyState. Doesn't need mutex because Apply is single-threaded + addrIncBuf []byte // buffer for ApplyState. Doesn't need mutex because Apply is single-threaded } -func NewStateV3() *StateV3 { +func NewStateV3(tmpdir string) *StateV3 { rs := &StateV3{ - triggers: map[uint64]*exec22.TxTask{}, - senderTxNums: map[common.Address]uint64{}, - changes: map[string]*btree2.Map[string, []byte]{ - kv.PlainState: btree2.NewMap[string, []byte](128), - kv.Code: btree2.NewMap[string, []byte](128), - kv.IncarnationMap: btree2.NewMap[string, []byte](128), - kv.PlainContractCode: btree2.NewMap[string, []byte](128), - }, - txsDone: atomic2.NewUint64(0), - } - rs.receiveWork = sync.NewCond(&rs.queueLock) + tmpdir: tmpdir, + triggers: map[uint64]*exec22.TxTask{}, + senderTxNums: map[common.Address]uint64{}, + chCode: map[string][]byte{}, + chAccs: map[string][]byte{}, + chStorage: btree2.NewMap[string, []byte](128), + chIncs: map[string][]byte{}, + chContractCode: map[string][]byte{}, + + applyPrevAccountBuf: make([]byte, 256), + addrIncBuf: make([]byte, 20+8), + } return rs } func (rs *StateV3) put(table string, key, val []byte) { - old, ok := rs.changes[table].Set(string(key), val) - if ok { - rs.sizeEstimate += len(val) - len(old) - } else { - rs.sizeEstimate += len(key) + len(val) - } + rs.puts(table, string(key), val) } func (rs *StateV3) puts(table string, key string, val []byte) { - old, ok := rs.changes[table].Set(key, val) - if ok { - rs.sizeEstimate += len(val) - len(old) - } else { - rs.sizeEstimate += len(key) + len(val) + switch table { + case StorageTable: + if old, ok := rs.chStorage.Set(key, val); ok { + rs.sizeEstimate += len(val) - len(old) + } else { + rs.sizeEstimate += len(key) + len(val) + } + case kv.PlainState: + if old, ok := rs.chAccs[key]; ok { + rs.sizeEstimate += len(val) - len(old) + } else { + rs.sizeEstimate += len(key) + len(val) + } + rs.chAccs[key] = val + case kv.Code: + if old, ok := rs.chCode[key]; ok { + rs.sizeEstimate += len(val) - len(old) + } else { + rs.sizeEstimate += len(key) + len(val) + } + rs.chCode[key] = val + case kv.IncarnationMap: + if old, ok := rs.chIncs[key]; ok { + rs.sizeEstimate += len(val) - len(old) + } else { + rs.sizeEstimate += len(key) + len(val) + } + rs.chIncs[key] = val + case kv.PlainContractCode: + if old, ok := rs.chContractCode[key]; ok { + rs.sizeEstimate += len(val) - len(old) + } else { + rs.sizeEstimate += len(key) + len(val) + } + rs.chContractCode[key] = val + default: + panic(table) } } -func (rs *StateV3) Get(table string, key []byte) []byte { +func (rs *StateV3) Get(table string, key []byte) (v []byte, ok bool) { rs.lock.RLock() - v := rs.get(table, key) + v, ok = rs.get(table, key) rs.lock.RUnlock() - return v + return v, ok +} + +func (rs *StateV3) get(table string, key []byte) (v []byte, ok bool) { + keyS := *(*string)(unsafe.Pointer(&key)) + switch table { + case StorageTable: + v, ok = rs.chStorage.Get(keyS) + case kv.PlainState: + v, ok = rs.chAccs[keyS] + case kv.Code: + v, ok = rs.chCode[keyS] + case kv.IncarnationMap: + v, ok = rs.chIncs[keyS] + case kv.PlainContractCode: + v, ok = rs.chContractCode[keyS] + default: + panic(table) + } + return v, ok +} + +func (rs *StateV3) flushMap(ctx context.Context, rwTx kv.RwTx, table string, m map[string][]byte, logPrefix string, logEvery *time.Ticker) error { + collector := etl.NewCollector(logPrefix, "", etl.NewSortableBuffer(etl.BufferOptimalSize)) + defer collector.Close() + + var count int + total := len(m) + for k, v := range m { + if err := collector.Collect([]byte(k), v); err != nil { + return err + } + count++ + select { + default: + case <-logEvery.C: + progress := fmt.Sprintf("%.1fM/%.1fM", float64(count)/1_000_000, float64(total)/1_000_000) + log.Info("Write to db", "progress", progress, "current table", table) + rwTx.CollectMetrics() + } + } + if err := collector.Load(rwTx, table, etl.IdentityLoadFunc, etl.TransformArgs{Quit: ctx.Done()}); err != nil { + return err + } + return nil } +func (rs *StateV3) flushBtree(ctx context.Context, rwTx kv.RwTx, table string, m *btree2.Map[string, []byte], logPrefix string, logEvery *time.Ticker) error { + c, err := rwTx.RwCursor(table) + if err != nil { + return err + } + defer c.Close() + iter := m.Iter() + for ok := iter.First(); ok; ok = iter.Next() { + if len(iter.Value()) == 0 { + if err = c.Delete([]byte(iter.Key())); err != nil { + return err + } + } else { + if err = c.Put([]byte(iter.Key()), iter.Value()); err != nil { + return err + } + } -func (rs *StateV3) get(table string, key []byte) (v []byte) { - v, _ = rs.changes[table].Get(*(*string)(unsafe.Pointer(&key))) - return v + select { + case <-logEvery.C: + log.Info(fmt.Sprintf("[%s] Flush", logPrefix), "table", table, "current_prefix", hex.EncodeToString([]byte(iter.Key())[:4])) + case <-ctx.Done(): + return ctx.Err() + default: + } + } + return nil } func (rs *StateV3) Flush(ctx context.Context, rwTx kv.RwTx, logPrefix string, logEvery *time.Ticker) error { rs.lock.Lock() defer rs.lock.Unlock() - for table, t := range rs.changes { - c, err := rwTx.RwCursor(table) - if err != nil { - return err - } - - iter := t.Iter() - for ok := iter.First(); ok; ok = iter.Next() { - if len(iter.Value()) == 0 { - if err = c.Delete([]byte(iter.Key())); err != nil { - return err - } - //fmt.Printf("Flush [%x]=>\n", item.key) - } else { - if err = c.Put([]byte(iter.Key()), iter.Value()); err != nil { - return err - } - //fmt.Printf("Flush [%x]=>[%x]\n", item.key, item.val) - } - select { - case <-logEvery.C: - log.Info(fmt.Sprintf("[%s] Flush", logPrefix), "table", table, "current_prefix", hex.EncodeToString([]byte(iter.Key())[:4])) - case <-ctx.Done(): - return ctx.Err() - default: - } - } - if err != nil { - return err - } - t.Clear() + if err := rs.flushMap(ctx, rwTx, kv.PlainState, rs.chAccs, logPrefix, logEvery); err != nil { + return err + } + rs.chAccs = map[string][]byte{} + if err := rs.flushBtree(ctx, rwTx, kv.PlainState, rs.chStorage, logPrefix, logEvery); err != nil { + return err } + rs.chStorage.Clear() + if err := rs.flushMap(ctx, rwTx, kv.Code, rs.chCode, logPrefix, logEvery); err != nil { + return err + } + rs.chCode = map[string][]byte{} + if err := rs.flushMap(ctx, rwTx, kv.PlainContractCode, rs.chContractCode, logPrefix, logEvery); err != nil { + return err + } + rs.chContractCode = map[string][]byte{} + if err := rs.flushMap(ctx, rwTx, kv.IncarnationMap, rs.chIncs, logPrefix, logEvery); err != nil { + return err + } + rs.chIncs = map[string][]byte{} + rs.sizeEstimate = 0 return nil } -func (rs *StateV3) QueueLen() int { - rs.queueLock.Lock() - defer rs.queueLock.Unlock() - return rs.queue.Len() +func (rs *StateV3) ReTry(txTask *exec22.TxTask, in *exec22.QueueWithRetry) { + rs.resetTxTask(txTask) + in.ReTry(txTask) } +func (rs *StateV3) AddWork(ctx context.Context, txTask *exec22.TxTask, in *exec22.QueueWithRetry) { + rs.resetTxTask(txTask) + in.Add(ctx, txTask) +} +func (rs *StateV3) resetTxTask(txTask *exec22.TxTask) { + txTask.BalanceIncreaseSet = nil + returnReadList(txTask.ReadLists) + txTask.ReadLists = nil + returnWriteList(txTask.WriteLists) + txTask.WriteLists = nil + txTask.Logs = nil + txTask.TraceFroms = nil + txTask.TraceTos = nil -func (rs *StateV3) Schedule() (*exec22.TxTask, bool) { - rs.queueLock.Lock() - defer rs.queueLock.Unlock() - for !rs.finished.Load() && rs.queue.Len() == 0 { - rs.receiveWork.Wait() - } - if rs.finished.Load() { - return nil, false - } - if rs.queue.Len() > 0 { - return heap.Pop(&rs.queue).(*exec22.TxTask), true - } - return nil, false + /* + txTask.ReadLists = nil + txTask.WriteLists = nil + txTask.AccountPrevs = nil + txTask.AccountDels = nil + txTask.StoragePrevs = nil + txTask.CodePrevs = nil + */ } func (rs *StateV3) RegisterSender(txTask *exec22.TxTask) bool { @@ -172,15 +269,13 @@ func (rs *StateV3) RegisterSender(txTask *exec22.TxTask) bool { return !deferral } -func (rs *StateV3) CommitTxNum(sender *common.Address, txNum uint64) uint64 { - rs.txsDone.Add(1) +func (rs *StateV3) CommitTxNum(sender *common.Address, txNum uint64, in *exec22.QueueWithRetry) (count int) { + ExecTxsDone.Inc() rs.triggerLock.Lock() defer rs.triggerLock.Unlock() - count := uint64(0) if triggered, ok := rs.triggers[txNum]; ok { - rs.queuePush(triggered) - rs.receiveWork.Signal() + in.ReTry(triggered) count++ delete(rs.triggers, txNum) } @@ -193,44 +288,7 @@ func (rs *StateV3) CommitTxNum(sender *common.Address, txNum uint64) uint64 { return count } -func (rs *StateV3) queuePush(t *exec22.TxTask) int { - rs.queueLock.Lock() - heap.Push(&rs.queue, t) - l := len(rs.queue) - rs.queueLock.Unlock() - return l -} - -func (rs *StateV3) AddWork(txTask *exec22.TxTask) (queueLen int) { - txTask.BalanceIncreaseSet = nil - returnReadList(txTask.ReadLists) - txTask.ReadLists = nil - returnWriteList(txTask.WriteLists) - txTask.WriteLists = nil - txTask.ResultsSize = 0 - txTask.Logs = nil - txTask.TraceFroms = nil - txTask.TraceTos = nil - - /* - txTask.ReadLists = nil - txTask.WriteLists = nil - txTask.AccountPrevs = nil - txTask.AccountDels = nil - txTask.StoragePrevs = nil - txTask.CodePrevs = nil - */ - queueLen = rs.queuePush(txTask) - rs.receiveWork.Signal() - return queueLen -} - -func (rs *StateV3) Finish() { - rs.finished.Store(true) - rs.receiveWork.Broadcast() -} - -func (rs *StateV3) appplyState1(roTx kv.Tx, txTask *exec22.TxTask, agg *libstate.AggregatorV3) error { +func (rs *StateV3) writeStateHistory(roTx kv.Tx, txTask *exec22.TxTask, agg *libstate.AggregatorV3) error { rs.lock.RLock() defer rs.lock.RUnlock() @@ -240,20 +298,20 @@ func (rs *StateV3) appplyState1(roTx kv.Tx, txTask *exec22.TxTask, agg *libstate return err } defer cursor.Close() - addr1 := make([]byte, 20+8) - psChanges := rs.changes[kv.PlainState] + addr1 := rs.addrIncBuf for addrS, original := range txTask.AccountDels { addr := []byte(addrS) copy(addr1, addr) binary.BigEndian.PutUint64(addr1[len(addr):], original.Incarnation) - prev := accounts.SerialiseV3(original) + prev := rs.applyPrevAccountBuf[:accounts.SerialiseV3Len(original)] + accounts.SerialiseV3To(original, prev) if err := agg.AddAccountPrev(addr, prev); err != nil { return err } codeHashBytes := original.CodeHash.Bytes() - codePrev := rs.get(kv.Code, codeHashBytes) - if codePrev == nil { + codePrev, ok := rs.get(kv.Code, codeHashBytes) + if !ok || codePrev == nil { var err error codePrev, err = roTx.GetOne(kv.Code, codeHashBytes) if err != nil { @@ -273,28 +331,26 @@ func (rs *StateV3) appplyState1(roTx kv.Tx, txTask *exec22.TxTask, agg *libstate if !bytes.HasPrefix(k, addr1) { k = nil } - if psChanges != nil { - //TODO: try full-scan, then can replace btree by map - iter := psChanges.Iter() - for ok := iter.Seek(string(addr1)); ok; ok = iter.Next() { - key := []byte(iter.Key()) - if !bytes.HasPrefix(key, addr1) { - break - } - for ; e == nil && k != nil && bytes.HasPrefix(k, addr1) && bytes.Compare(k, key) <= 0; k, v, e = cursor.Next() { - if !bytes.Equal(k, key) { - // Skip the cursor item when the key is equal, i.e. prefer the item from the changes tree - if e = agg.AddStoragePrev(addr, k[28:], v); e != nil { - return e - } + //TODO: try full-scan, then can replace btree by map + iter := rs.chStorage.Iter() + for ok := iter.Seek(string(addr1)); ok; ok = iter.Next() { + key := []byte(iter.Key()) + if !bytes.HasPrefix(key, addr1) { + break + } + for ; e == nil && k != nil && bytes.HasPrefix(k, addr1) && bytes.Compare(k, key) <= 0; k, v, e = cursor.Next() { + if !bytes.Equal(k, key) { + // Skip the cursor item when the key is equal, i.e. prefer the item from the changes tree + if e = agg.AddStoragePrev(addr, k[28:], v); e != nil { + return e } } - if e != nil { - return e - } - if e = agg.AddStoragePrev(addr, key[28:], iter.Value()); e != nil { - break - } + } + if e != nil { + return e + } + if e = agg.AddStoragePrev(addr, key[28:], iter.Value()); e != nil { + break } } for ; e == nil && k != nil && bytes.HasPrefix(k, addr1); k, v, e = cursor.Next() { @@ -308,14 +364,14 @@ func (rs *StateV3) appplyState1(roTx kv.Tx, txTask *exec22.TxTask, agg *libstate } } - k := make([]byte, 20+8) + k := rs.addrIncBuf for addrS, incarnation := range txTask.CodePrevs { addr := []byte(addrS) copy(k, addr) binary.BigEndian.PutUint64(k[20:], incarnation) - codeHash := rs.get(kv.PlainContractCode, k) - if codeHash == nil { + codeHash, ok := rs.get(kv.PlainContractCode, k) + if !ok || codeHash == nil { var err error codeHash, err = roTx.GetOne(kv.PlainContractCode, k) if err != nil { @@ -324,8 +380,8 @@ func (rs *StateV3) appplyState1(roTx kv.Tx, txTask *exec22.TxTask, agg *libstate } var codePrev []byte if codeHash != nil { - codePrev = rs.get(kv.Code, codeHash) - if codePrev == nil { + codePrev, ok = rs.get(kv.Code, codeHash) + if !ok || codePrev == nil { var err error codePrev, err = roTx.GetOne(kv.Code, codeHash) if err != nil { @@ -340,7 +396,7 @@ func (rs *StateV3) appplyState1(roTx kv.Tx, txTask *exec22.TxTask, agg *libstate return nil } -func (rs *StateV3) appplyState(roTx kv.Tx, txTask *exec22.TxTask, agg *libstate.AggregatorV3) error { +func (rs *StateV3) applyState(roTx kv.Tx, txTask *exec22.TxTask, agg *libstate.AggregatorV3) error { emptyRemoval := txTask.Rules.IsSpuriousDragon rs.lock.Lock() defer rs.lock.Unlock() @@ -348,8 +404,8 @@ func (rs *StateV3) appplyState(roTx kv.Tx, txTask *exec22.TxTask, agg *libstate. for addr, increase := range txTask.BalanceIncreaseSet { increase := increase addrBytes := addr.Bytes() - enc0 := rs.get(kv.PlainState, addrBytes) - if enc0 == nil { + enc0, ok := rs.get(kv.PlainState, addrBytes) + if !ok { var err error enc0, err = roTx.GetOne(kv.PlainState, addrBytes) if err != nil { @@ -367,7 +423,7 @@ func (rs *StateV3) appplyState(roTx kv.Tx, txTask *exec22.TxTask, agg *libstate. a.Balance.Add(&a.Balance, &increase) var enc1 []byte if emptyRemoval && a.Nonce == 0 && a.Balance.IsZero() && a.IsEmptyCodeHash() { - enc1 = []byte{} + enc1 = nil } else { enc1 = make([]byte, a.EncodingLengthForStorage()) a.EncodeForStorage(enc1) @@ -392,10 +448,10 @@ func (rs *StateV3) ApplyState(roTx kv.Tx, txTask *exec22.TxTask, agg *libstate.A defer agg.BatchHistoryWriteStart().BatchHistoryWriteEnd() agg.SetTxNum(txTask.TxNum) - if err := rs.appplyState1(roTx, txTask, agg); err != nil { + if err := rs.writeStateHistory(roTx, txTask, agg); err != nil { return err } - if err := rs.appplyState(roTx, txTask, agg); err != nil { + if err := rs.applyState(roTx, txTask, agg); err != nil { return err } @@ -545,39 +601,59 @@ func (rs *StateV3) Unwind(ctx context.Context, tx kv.RwTx, txUnwindTo uint64, ag return nil } -func (rs *StateV3) DoneCount() uint64 { return rs.txsDone.Load() } +func (rs *StateV3) DoneCount() uint64 { return ExecTxsDone.Get() } -func (rs *StateV3) SizeEstimate() uint64 { +func (rs *StateV3) SizeEstimate() (r uint64) { rs.lock.RLock() - r := rs.sizeEstimate + r = uint64(rs.sizeEstimate) rs.lock.RUnlock() - return uint64(r) + return r * 2 // multiply 2 here, to cover data-structures overhead. more precise accounting - expensive. } func (rs *StateV3) ReadsValid(readLists map[string]*exec22.KvList) bool { - var t *btree2.Map[string, []byte] - rs.lock.RLock() defer rs.lock.RUnlock() - //fmt.Printf("ValidReads\n") for table, list := range readLists { - //fmt.Printf("Table %s\n", table) - var ok bool - if table == CodeSizeTable { - t, ok = rs.changes[kv.Code] - } else { - t, ok = rs.changes[table] + switch table { + case kv.PlainState: + if !rs.readsValidMap(table, list, rs.chAccs) { + return false + } + case CodeSizeTable: + if !rs.readsValidMap(table, list, rs.chCode) { + return false + } + case StorageTable: + if !rs.readsValidBtree(table, list, rs.chStorage) { + return false + } + case kv.Code: + if !rs.readsValidMap(table, list, rs.chCode) { + return false + } + case kv.IncarnationMap: + if !rs.readsValidMap(table, list, rs.chIncs) { + return false + } } - if !ok { - continue + } + return true +} + +func (rs *StateV3) readsValidMap(table string, list *exec22.KvList, m map[string][]byte) bool { + switch table { + case CodeSizeTable: + for i, key := range list.Keys { + if val, ok := m[key]; ok { + if binary.BigEndian.Uint64(list.Vals[i]) != uint64(len(val)) { + return false + } + } } + default: for i, key := range list.Keys { - if val, ok := t.Get(key); ok { - if table == CodeSizeTable { - if binary.BigEndian.Uint64(list.Vals[i]) != uint64(len(val)) { - return false - } - } else if !bytes.Equal(list.Vals[i], val) { + if val, ok := m[key]; ok { + if !bytes.Equal(list.Vals[i], val) { return false } } @@ -586,6 +662,17 @@ func (rs *StateV3) ReadsValid(readLists map[string]*exec22.KvList) bool { return true } +func (rs *StateV3) readsValidBtree(table string, list *exec22.KvList, m *btree2.Map[string, []byte]) bool { + for i, key := range list.Keys { + if val, ok := m.Get(key); ok { + if !bytes.Equal(list.Vals[i], val) { + return false + } + } + } + return true +} + type StateWriterV3 struct { rs *StateV3 txNum uint64 @@ -661,7 +748,7 @@ func (w *StateWriterV3) UpdateAccountCode(address common.Address, incarnation ui func (w *StateWriterV3) DeleteAccount(address common.Address, original *accounts.Account) error { addressBytes := address.Bytes() w.writeLists[kv.PlainState].Keys = append(w.writeLists[kv.PlainState].Keys, string(addressBytes)) - w.writeLists[kv.PlainState].Vals = append(w.writeLists[kv.PlainState].Vals, []byte{}) + w.writeLists[kv.PlainState].Vals = append(w.writeLists[kv.PlainState].Vals, nil) if original.Incarnation > 0 { var b [8]byte binary.BigEndian.PutUint64(b[:], original.Incarnation) @@ -683,8 +770,8 @@ func (w *StateWriterV3) WriteAccountStorage(address common.Address, incarnation } composite := dbutils.PlainGenerateCompositeStorageKey(address[:], incarnation, key.Bytes()) cmpositeS := string(composite) - w.writeLists[kv.PlainState].Keys = append(w.writeLists[kv.PlainState].Keys, cmpositeS) - w.writeLists[kv.PlainState].Vals = append(w.writeLists[kv.PlainState].Vals, value.Bytes()) + w.writeLists[StorageTable].Keys = append(w.writeLists[StorageTable].Keys, cmpositeS) + w.writeLists[StorageTable].Vals = append(w.writeLists[StorageTable].Vals, value.Bytes()) //fmt.Printf("storage [%x] [%x] => [%x], txNum: %d\n", address, *key, v, w.txNum) if w.storagePrevs == nil { w.storagePrevs = map[string][]byte{} @@ -724,8 +811,8 @@ func (r *StateReaderV3) ResetReadSet() { r.readLists = newR func (r *StateReaderV3) ReadAccountData(address common.Address) (*accounts.Account, error) { addr := address.Bytes() - enc := r.rs.Get(kv.PlainState, addr) - if enc == nil { + enc, ok := r.rs.Get(kv.PlainState, addr) + if !ok { var err error enc, err = r.tx.GetOne(kv.PlainState, addr) if err != nil { @@ -752,8 +839,8 @@ func (r *StateReaderV3) ReadAccountData(address common.Address) (*accounts.Accou func (r *StateReaderV3) ReadAccountStorage(address common.Address, incarnation uint64, key *common.Hash) ([]byte, error) { composite := dbutils.PlainGenerateCompositeStorageKey(address.Bytes(), incarnation, key.Bytes()) - enc := r.rs.Get(kv.PlainState, composite) - if enc == nil { + enc, ok := r.rs.Get(StorageTable, composite) + if !ok || enc == nil { var err error enc, err = r.tx.GetOne(kv.PlainState, composite) if err != nil { @@ -761,8 +848,8 @@ func (r *StateReaderV3) ReadAccountStorage(address common.Address, incarnation u } } if !r.discardReadList { - r.readLists[kv.PlainState].Keys = append(r.readLists[kv.PlainState].Keys, string(composite)) - r.readLists[kv.PlainState].Vals = append(r.readLists[kv.PlainState].Vals, enc) + r.readLists[StorageTable].Keys = append(r.readLists[StorageTable].Keys, string(composite)) + r.readLists[StorageTable].Vals = append(r.readLists[StorageTable].Vals, enc) } if r.trace { if enc == nil { @@ -779,8 +866,8 @@ func (r *StateReaderV3) ReadAccountStorage(address common.Address, incarnation u func (r *StateReaderV3) ReadAccountCode(address common.Address, incarnation uint64, codeHash common.Hash) ([]byte, error) { addr, codeHashBytes := address.Bytes(), codeHash.Bytes() - enc := r.rs.Get(kv.Code, codeHashBytes) - if enc == nil { + enc, ok := r.rs.Get(kv.Code, codeHashBytes) + if !ok || enc == nil { var err error enc, err = r.tx.GetOne(kv.Code, codeHashBytes) if err != nil { @@ -799,8 +886,8 @@ func (r *StateReaderV3) ReadAccountCode(address common.Address, incarnation uint func (r *StateReaderV3) ReadAccountCodeSize(address common.Address, incarnation uint64, codeHash common.Hash) (int, error) { codeHashBytes := codeHash.Bytes() - enc := r.rs.Get(kv.Code, codeHashBytes) - if enc == nil { + enc, ok := r.rs.Get(kv.Code, codeHashBytes) + if !ok || enc == nil { var err error enc, err = r.tx.GetOne(kv.Code, codeHashBytes) if err != nil { @@ -822,8 +909,8 @@ func (r *StateReaderV3) ReadAccountCodeSize(address common.Address, incarnation func (r *StateReaderV3) ReadAccountIncarnation(address common.Address) (uint64, error) { addrBytes := address[:] - enc := r.rs.Get(kv.IncarnationMap, addrBytes) - if enc == nil { + enc, ok := r.rs.Get(kv.IncarnationMap, addrBytes) + if !ok || enc == nil { var err error enc, err = r.tx.GetOne(kv.IncarnationMap, addrBytes) if err != nil { @@ -844,6 +931,7 @@ var writeListPool = sync.Pool{ New: func() any { return map[string]*exec22.KvList{ kv.PlainState: {}, + StorageTable: {}, kv.Code: {}, kv.PlainContractCode: {}, kv.IncarnationMap: {}, @@ -871,6 +959,7 @@ var readListPool = sync.Pool{ kv.PlainState: {}, kv.Code: {}, CodeSizeTable: {}, + StorageTable: {}, kv.IncarnationMap: {}, } }, diff --git a/core/state/temporal/kv_temporal.go b/core/state/temporal/kv_temporal.go index 38cad43c2e5..feb35cc428c 100644 --- a/core/state/temporal/kv_temporal.go +++ b/core/state/temporal/kv_temporal.go @@ -11,9 +11,11 @@ import ( "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv/iter" "github.com/ledgerwatch/erigon-lib/kv/kvcfg" + "github.com/ledgerwatch/erigon-lib/kv/mdbx" "github.com/ledgerwatch/erigon-lib/kv/order" "github.com/ledgerwatch/erigon-lib/kv/rawdbv3" "github.com/ledgerwatch/erigon-lib/state" + "github.com/ledgerwatch/erigon/eth/ethconfig" ) //Variables Naming: @@ -69,12 +71,15 @@ func New(db kv.RwDB, agg *state.AggregatorV3, cb1 tConvertV3toV2, cb2 tRestoreCo return &DB{RwDB: db, agg: agg, convertV3toV2: cb1, restoreCodeHash: cb2, parseInc: cb3, systemContractLookup: systemContractLookup}, nil } +func (db *DB) Agg() *state.AggregatorV3 { return db.agg } +func (db *DB) InternalDB() kv.RwDB { return db.RwDB } + func (db *DB) BeginTemporalRo(ctx context.Context) (kv.TemporalTx, error) { kvTx, err := db.RwDB.BeginRo(ctx) if err != nil { return nil, err } - tx := &Tx{Tx: kvTx, db: db} + tx := &Tx{MdbxTx: kvTx.(*mdbx.MdbxTx), db: db} tx.agg = db.agg.MakeContext() return tx, nil @@ -101,13 +106,65 @@ func (db *DB) View(ctx context.Context, f func(tx kv.Tx) error) error { return f(tx) } +//func (db *DB) BeginTemporalRw(ctx context.Context) (kv.RwTx, error) { +// kvTx, err := db.RwDB.BeginRw(ctx) //nolint:gocritic +// if err != nil { +// return nil, err +// } +// tx := &Tx{MdbxTx: kvTx.(*mdbx.MdbxTx), db: db} +// +// //tx.agg = db.agg.MakeContext() +// return tx, nil +//} +//func (db *DB) BeginRw(ctx context.Context) (kv.RwTx, error) { +// return db.BeginTemporalRw(ctx) +//} +//func (db *DB) Update(ctx context.Context, f func(tx kv.RwTx) error) error { +// tx, err := db.BeginTemporalRw(ctx) +// if err != nil { +// return err +// } +// defer tx.Rollback() +// if err = f(tx); err != nil { +// return err +// } +// return tx.Commit() +//} + +//func (db *DB) BeginTemporalRwNosync(ctx context.Context) (kv.RwTx, error) { +// kvTx, err := db.RwDB.BeginRwNosync(ctx) //nolint:gocritic +// if err != nil { +// return nil, err +// } +// tx := &Tx{MdbxTx: kvTx.(*mdbx.MdbxTx), db: db} +// +// //tx.agg = db.agg.MakeContext() +// return tx, nil +//} +//func (db *DB) BeginRwNosync(ctx context.Context) (kv.RwTx, error) { +// return db.BeginTemporalRwNosync(ctx) //nolint:gocritic +//} +//func (db *DB) UpdateNosync(ctx context.Context, f func(tx kv.RwTx) error) error { +// tx, err := db.BeginTemporalRwNosync(ctx) +// if err != nil { +// return err +// } +// defer tx.Rollback() +// if err = f(tx); err != nil { +// return err +// } +// return tx.Commit() +//} + type Tx struct { - kv.Tx + *mdbx.MdbxTx db *DB agg *state.AggregatorV3Context resourcesToClose []kv.Closer } +func (tx *Tx) AggCtx() *state.AggregatorV3Context { return tx.agg } +func (tx *Tx) Agg() *state.AggregatorV3 { return tx.db.agg } func (tx *Tx) Rollback() { for _, closer := range tx.resourcesToClose { closer.Close() @@ -115,14 +172,14 @@ func (tx *Tx) Rollback() { if tx.agg != nil { tx.agg.Close() } - tx.Tx.Rollback() + tx.MdbxTx.Rollback() } func (tx *Tx) Commit() error { for _, closer := range tx.resourcesToClose { closer.Close() } - return tx.Tx.Commit() + return tx.MdbxTx.Commit() } const ( @@ -148,13 +205,13 @@ const ( TracesToIdx kv.InvertedIdx = "TracesToIdx" ) -func (tx *Tx) DomainRange(name kv.Domain, k1, k2 []byte, asOfTs uint64, asc order.By, limit int) (it iter.KV, err error) { +func (tx *Tx) DomainRange(name kv.Domain, fromKey, toKey []byte, asOfTs uint64, asc order.By, limit int) (it iter.KV, err error) { if asc == order.Desc { panic("not supported yet") } switch name { case AccountsDomain: - histStateIt := tx.agg.AccountHistoricalStateRange(asOfTs, k1, nil, -1, tx) + histStateIt := tx.agg.AccountHistoricalStateRange(asOfTs, fromKey, toKey, limit, tx) // TODO: somehow avoid common.Copy(k) - WalkAsOfIter is not zero-copy // Is histStateIt possible to increase keys lifetime to: 2 .Next() calls?? histStateIt2 := iter.TransformKV(histStateIt, func(k, v []byte) ([]byte, []byte, error) { @@ -175,13 +232,13 @@ func (tx *Tx) DomainRange(name kv.Domain, k1, k2 []byte, asOfTs uint64, asc orde force = &hash } } - v, err = tx.db.restoreCodeHash(tx.Tx, k, v, force) + v, err = tx.db.restoreCodeHash(tx.MdbxTx, k, v, force) if err != nil { return nil, nil, err } return k[:20], v, nil }) - lastestStateIt, err := tx.RangeAscend(kv.PlainState, k1, nil, -1) + lastestStateIt, err := tx.RangeAscend(kv.PlainState, fromKey, toKey, -1) // don't apply limit, because need filter if err != nil { return nil, err } @@ -189,17 +246,14 @@ func (tx *Tx) DomainRange(name kv.Domain, k1, k2 []byte, asOfTs uint64, asc orde latestStateIt2 := iter.FilterKV(lastestStateIt, func(k, v []byte) bool { return len(k) == 20 }) - //TODO: seems UnionKV can't handle "amount" request - return iter.UnionKV(histStateIt2, latestStateIt2), nil + it = iter.UnionKV(histStateIt2, latestStateIt2, limit) case StorageDomain: - toKey, _ := kv.NextSubtree(k1) - fromKey2 := append(common.Copy(k1), k2...) - it := tx.agg.StorageHistoricalStateRange(asOfTs, fromKey2, toKey, limit, tx) - it11 := iter.TransformKV(it, func(k, v []byte) ([]byte, []byte, error) { + storageIt := tx.agg.StorageHistoricalStateRange(asOfTs, fromKey, toKey, limit, tx) + storageIt1 := iter.TransformKV(storageIt, func(k, v []byte) ([]byte, []byte, error) { return k, v, nil }) - accData, err := tx.GetOne(kv.PlainState, k1) + accData, err := tx.GetOne(kv.PlainState, fromKey[:20]) if err != nil { return nil, err } @@ -208,12 +262,12 @@ func (tx *Tx) DomainRange(name kv.Domain, k1, k2 []byte, asOfTs uint64, asc orde return nil, err } startkey := make([]byte, length.Addr+length.Incarnation+length.Hash) - copy(startkey, k1) + copy(startkey, fromKey[:20]) binary.BigEndian.PutUint64(startkey[length.Addr:], inc) - copy(startkey[length.Addr+length.Incarnation:], k2) + copy(startkey[length.Addr+length.Incarnation:], fromKey[20:]) toPrefix := make([]byte, length.Addr+length.Incarnation) - copy(toPrefix, k1) + copy(toPrefix, fromKey[:20]) binary.BigEndian.PutUint64(toPrefix[length.Addr:], inc+1) it2, err := tx.RangeAscend(kv.PlainState, startkey, toPrefix, limit) @@ -223,15 +277,41 @@ func (tx *Tx) DomainRange(name kv.Domain, k1, k2 []byte, asOfTs uint64, asc orde it3 := iter.TransformKV(it2, func(k, v []byte) ([]byte, []byte, error) { return append(append([]byte{}, k[:20]...), k[28:]...), v, nil }) - //TODO: seems MergePairs can't handle "amount" request - return iter.UnionKV(it11, it3), nil + it = iter.UnionKV(storageIt1, it3, limit) case CodeDomain: panic("not implemented yet") default: panic(fmt.Sprintf("unexpected: %s", name)) } + + if closer, ok := it.(kv.Closer); ok { + tx.resourcesToClose = append(tx.resourcesToClose, closer) + } + + return it, nil } -func (tx *Tx) DomainGet(name kv.Domain, key, key2 []byte, ts uint64) (v []byte, ok bool, err error) { +func (tx *Tx) DomainGet(name kv.Domain, key, key2 []byte) (v []byte, ok bool, err error) { + if ethconfig.EnableHistoryV4InTest { + panic("implement me") + } + switch name { + case AccountsDomain: + v, err = tx.GetOne(kv.PlainState, key) + return v, v != nil, err + case StorageDomain: + v, err = tx.GetOne(kv.PlainState, append(common.Copy(key), key2...)) + return v, v != nil, err + case CodeDomain: + v, err = tx.GetOne(kv.Code, key2) + return v, v != nil, err + default: + panic(fmt.Sprintf("unexpected: %s", name)) + } +} +func (tx *Tx) DomainGetAsOf(name kv.Domain, key, key2 []byte, ts uint64) (v []byte, ok bool, err error) { + if ethconfig.EnableHistoryV4InTest { + panic("implement me") + } switch name { case AccountsDomain: v, ok, err = tx.HistoryGet(AccountsHistory, key, ts) @@ -271,7 +351,7 @@ func (tx *Tx) DomainGet(name kv.Domain, key, key2 []byte, ts uint64) (v []byte, func (tx *Tx) HistoryGet(name kv.History, key []byte, ts uint64) (v []byte, ok bool, err error) { switch name { case AccountsHistory: - v, ok, err = tx.agg.ReadAccountDataNoStateWithRecent(key, ts, tx.Tx) + v, ok, err = tx.agg.ReadAccountDataNoStateWithRecent(key, ts, tx.MdbxTx) if err != nil { return nil, false, err } @@ -292,15 +372,15 @@ func (tx *Tx) HistoryGet(name kv.History, key []byte, ts uint64) (v []byte, ok b force = &hash } } - v, err = tx.db.restoreCodeHash(tx.Tx, key, v, force) + v, err = tx.db.restoreCodeHash(tx.MdbxTx, key, v, force) if err != nil { return nil, false, err } return v, true, nil case StorageHistory: - return tx.agg.ReadAccountStorageNoStateWithRecent2(key, ts, tx.Tx) + return tx.agg.ReadAccountStorageNoStateWithRecent2(key, ts, tx.MdbxTx) case CodeHistory: - return tx.agg.ReadAccountCodeNoStateWithRecent(key, ts, tx.Tx) + return tx.agg.ReadAccountCodeNoStateWithRecent(key, ts, tx.MdbxTx) default: panic(fmt.Sprintf("unexpected: %s", name)) } @@ -309,19 +389,19 @@ func (tx *Tx) HistoryGet(name kv.History, key []byte, ts uint64) (v []byte, ok b func (tx *Tx) IndexRange(name kv.InvertedIdx, k []byte, fromTs, toTs int, asc order.By, limit int) (timestamps iter.U64, err error) { switch name { case AccountsHistoryIdx: - timestamps, err = tx.agg.AccountHistoyIdxIterator(k, fromTs, toTs, asc, limit, tx) + timestamps, err = tx.agg.AccountHistoyIdxRange(k, fromTs, toTs, asc, limit, tx) case StorageHistoryIdx: - timestamps, err = tx.agg.StorageHistoyIdxIterator(k, fromTs, toTs, asc, limit, tx) + timestamps, err = tx.agg.StorageHistoyIdxRange(k, fromTs, toTs, asc, limit, tx) case CodeHistoryIdx: - timestamps, err = tx.agg.CodeHistoyIdxIterator(k, fromTs, toTs, asc, limit, tx) + timestamps, err = tx.agg.CodeHistoyIdxRange(k, fromTs, toTs, asc, limit, tx) case LogTopicIdx: - timestamps, err = tx.agg.LogTopicIterator(k, fromTs, toTs, asc, limit, tx) + timestamps, err = tx.agg.LogTopicRange(k, fromTs, toTs, asc, limit, tx) case LogAddrIdx: - timestamps, err = tx.agg.LogAddrIterator(k, fromTs, toTs, asc, limit, tx) + timestamps, err = tx.agg.LogAddrRange(k, fromTs, toTs, asc, limit, tx) case TracesFromIdx: - timestamps, err = tx.agg.TraceFromIterator(k, fromTs, toTs, asc, limit, tx) + timestamps, err = tx.agg.TraceFromRange(k, fromTs, toTs, asc, limit, tx) case TracesToIdx: - timestamps, err = tx.agg.TraceToIterator(k, fromTs, toTs, asc, limit, tx) + timestamps, err = tx.agg.TraceToRange(k, fromTs, toTs, asc, limit, tx) default: return nil, fmt.Errorf("unexpected history name: %s", name) } @@ -343,15 +423,19 @@ func (tx *Tx) HistoryRange(name kv.History, fromTs, toTs int, asc order.By, limi } switch name { case AccountsHistory: - it = tx.agg.AccountHistoryIterateChanged(fromTs, toTs, asc, limit, tx) - return it, nil + it, err = tx.agg.AccountHistoryRange(fromTs, toTs, asc, limit, tx) case StorageHistory: - it = tx.agg.StorageHistoryIterateChanged(fromTs, toTs, asc, limit, tx) - return it, nil + it, err = tx.agg.StorageHistoryRange(fromTs, toTs, asc, limit, tx) case CodeHistory: - it = tx.agg.CodeHistoryIterateChanged(fromTs, toTs, asc, limit, tx) - return it, nil + it, err = tx.agg.CodeHistoryRange(fromTs, toTs, asc, limit, tx) default: return nil, fmt.Errorf("unexpected history name: %s", name) } + if err != nil { + return nil, err + } + if closer, ok := it.(kv.Closer); ok { + tx.resourcesToClose = append(tx.resourcesToClose, closer) + } + return it, err } diff --git a/core/state_processor.go b/core/state_processor.go index 37497315eeb..8faa4e37074 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -17,6 +17,8 @@ package core import ( + "math/big" + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" @@ -43,7 +45,7 @@ func applyTransaction(config *chain.Config, engine consensus.EngineReader, gp *G if msg.FeeCap().IsZero() && engine != nil { // Only zero-gas transactions may be service ones syscall := func(contract libcommon.Address, data []byte) ([]byte, error) { - return SysCallContract(contract, data, *config, ibs, header, engine, true /* constCall */) + return SysCallContract(contract, data, *config, ibs, header, engine, true /* constCall */, nil /*excessDataGas*/) } msg.SetIsFree(engine.IsServiceTransaction(msg.From(), syscall)) } @@ -97,14 +99,14 @@ func applyTransaction(config *chain.Config, engine consensus.EngineReader, gp *G // and uses the input parameters for its environment. It returns the receipt // for the transaction, gas used and an error if the transaction failed, // indicating the block was invalid. -func ApplyTransaction(config *chain.Config, blockHashFunc func(n uint64) libcommon.Hash, engine consensus.EngineReader, author *libcommon.Address, gp *GasPool, ibs *state.IntraBlockState, stateWriter state.StateWriter, header *types.Header, tx types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, []byte, error) { +func ApplyTransaction(config *chain.Config, blockHashFunc func(n uint64) libcommon.Hash, engine consensus.EngineReader, author *libcommon.Address, gp *GasPool, ibs *state.IntraBlockState, stateWriter state.StateWriter, header *types.Header, tx types.Transaction, usedGas *uint64, cfg vm.Config, excessDataGas *big.Int) (*types.Receipt, []byte, error) { // Create a new context to be used in the EVM environment // Add addresses to access list if applicable // about the transaction and calling mechanisms. cfg.SkipAnalysis = SkipAnalysis(config, header.Number.Uint64()) - blockContext := NewEVMBlockContext(header, blockHashFunc, engine, author) + blockContext := NewEVMBlockContext(header, blockHashFunc, engine, author, excessDataGas) vmenv := vm.NewEVM(blockContext, evmtypes.TxContext{}, ibs, config, cfg) return applyTransaction(config, engine, gp, ibs, stateWriter, header, tx, usedGas, vmenv, cfg) diff --git a/core/state_transition.go b/core/state_transition.go index 30c78260df7..35f4e791527 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -20,6 +20,7 @@ import ( "fmt" "github.com/holiman/uint256" + libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/txpool" types2 "github.com/ledgerwatch/erigon-lib/types" @@ -28,6 +29,7 @@ import ( cmath "github.com/ledgerwatch/erigon/common/math" "github.com/ledgerwatch/erigon/common/u256" "github.com/ledgerwatch/erigon/consensus" + "github.com/ledgerwatch/erigon/consensus/misc" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/vm" "github.com/ledgerwatch/erigon/core/vm/evmtypes" @@ -86,12 +88,15 @@ type Message interface { FeeCap() *uint256.Int Tip() *uint256.Int Gas() uint64 + DataGas() uint64 + MaxFeePerDataGas() *uint256.Int Value() *uint256.Int Nonce() uint64 CheckNonce() bool Data() []byte AccessList() types2.AccessList + DataHashes() []libcommon.Hash IsFree() bool } @@ -474,3 +479,7 @@ func (st *StateTransition) refundGas(refundQuotient uint64) { func (st *StateTransition) gasUsed() uint64 { return st.initialGas - st.gas } + +func (st *StateTransition) dataGasUsed() uint64 { + return misc.GetDataGasUsed(len(st.msg.DataHashes())) +} diff --git a/core/systemcontracts/upgrade.go b/core/systemcontracts/upgrade.go index d89533b3052..a464e021b79 100644 --- a/core/systemcontracts/upgrade.go +++ b/core/systemcontracts/upgrade.go @@ -44,6 +44,10 @@ var ( MoranUpgrade = make(map[string]*Upgrade) + PlanckUpgrade = make(map[string]*Upgrade) + + LubanUpgrade = make(map[string]*Upgrade) + CalcuttaUpgrade = make(map[string]*Upgrade) // SystemContractCodeLookup is used to address a flaw in the upgrade logic of the system contracts. Since they are updated directly, without first being self-destructed @@ -463,7 +467,7 @@ func init() { { ContractAddr: RelayerHubContract, CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/c184a00160b6a2d884b4d6efebe1358a047e9e57", - Code: "6080604052600436106101d85760003560e01c80637ae2308811610102578063c81b166211610095578063f9a2bbc711610064578063f9a2bbc714610569578063fb7cfdd71461057e578063fc3e590814610593578063fd6a6879146105a8576101d8565b8063c81b166214610515578063dc927faf1461052a578063e1c7392a1461053f578063e79a198f14610554576101d8565b8063a1a11bf5116100d1578063a1a11bf514610407578063a78abc161461041c578063ab51bb9614610431578063ac43175114610446576101d8565b80637ae23088146103b357806395468d26146103c857806396713da9146103dd5780639dc09262146103f2576101d8565b806351e806721161017a57806370fd5bad1161014957806370fd5bad1461035f578063718a8aa81461037457806375d47a0a146103895780637942fd051461039e576101d8565b806351e80672146102c7578063541d5548146102dc5780636a87d780146103235780636e47b4821461034a576101d8565b80633dffc387116101b65780633dffc3871461024657806343756e5c14610271578063493279b1146102865780634bf6c882146102b2576101d8565b80630bee7a67146101dd5780630e2374a51461020b5780631aa3a0081461023c575b600080fd5b3480156101e957600080fd5b506101f26105bd565b6040805163ffffffff9092168252519081900360200190f35b34801561021757600080fd5b506102206105c2565b604080516001600160a01b039092168252519081900360200190f35b6102446105c8565b005b34801561025257600080fd5b5061025b610749565b6040805160ff9092168252519081900360200190f35b34801561027d57600080fd5b5061022061074e565b34801561029257600080fd5b5061029b610754565b6040805161ffff9092168252519081900360200190f35b3480156102be57600080fd5b5061025b61075a565b3480156102d357600080fd5b5061022061075f565b3480156102e857600080fd5b5061030f600480360360208110156102ff57600080fd5b50356001600160a01b0316610765565b604080519115158252519081900360200190f35b34801561032f57600080fd5b50610338610783565b60408051918252519081900360200190f35b34801561035657600080fd5b50610220610789565b34801561036b57600080fd5b5061025b61078f565b34801561038057600080fd5b5061025b610794565b34801561039557600080fd5b50610220610799565b3480156103aa57600080fd5b5061025b61079f565b3480156103bf57600080fd5b506103386107a4565b3480156103d457600080fd5b506103386107b1565b3480156103e957600080fd5b5061025b6107bd565b3480156103fe57600080fd5b506102206107c2565b34801561041357600080fd5b506102206107c8565b34801561042857600080fd5b5061030f6107ce565b34801561043d57600080fd5b506101f26107d7565b34801561045257600080fd5b506102446004803603604081101561046957600080fd5b81019060208101813564010000000081111561048457600080fd5b82018360208201111561049657600080fd5b803590602001918460018302840111640100000000831117156104b857600080fd5b9193909290916020810190356401000000008111156104d657600080fd5b8201836020820111156104e857600080fd5b8035906020019184600183028401116401000000008311171561050a57600080fd5b5090925090506107dc565b34801561052157600080fd5b50610220610bfe565b34801561053657600080fd5b50610220610c04565b34801561054b57600080fd5b50610244610c0a565b34801561056057600080fd5b50610244610c8c565b34801561057557600080fd5b50610220610e45565b34801561058a57600080fd5b50610338610e4b565b34801561059f57600080fd5b5061025b610e51565b3480156105b457600080fd5b50610220610e56565b606481565b61200181565b3360009081526004602052604090205460ff1615610625576040805162461bcd60e51b81526020600482015260156024820152741c995b185e595c88185b1c9958591e48195e1a5cdd605a1b604482015290519081900360640190fd5b60005460ff16610678576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b61068133610e5c565b156106bd5760405162461bcd60e51b81526004018080602001828103825260278152602001806110496027913960400191505060405180910390fd5b333214610707576040805162461bcd60e51b81526020600482015260136024820152721b9bc81c1c9bde1e481a5cc8185b1b1bddd959606a1b604482015290519081900360640190fd5b6040805162461bcd60e51b81526020600482015260126024820152711c9959da5cdd195c881cdd5cdc195b99195960721b604482015290519081900360640190fd5b600181565b61100181565b6102ca81565b600881565b61200081565b6001600160a01b031660009081526004602052604090205460ff1690565b60025481565b61100581565b600281565b601081565b61100881565b600b81565b68056bc75e2d6310000081565b67016345785d8a000081565b600981565b61100781565b61100681565b60005460ff1681565b600081565b60005460ff1661082f576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b336110071461086f5760405162461bcd60e51b815260040180806020018281038252602e815260200180611070602e913960400191505060405180910390fd5b6108d584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e1c995c5d5a5c995911195c1bdcda5d608a1b60208201529150610e629050565b156109d857602081146109195760405162461bcd60e51b815260040180806020018281038252602281526020018061109e6022913960400191505060405180910390fd5b604080516020601f840181900481028201810190925282815260009161095791858580838501838280828437600092019190915250610f4992505050565b90506001811180156109725750683635c9adc5dea000008111155b801561097f575060025481115b6109d0576040805162461bcd60e51b815260206004820181905260248201527f7468652072657175697265644465706f736974206f7574206f662072616e6765604482015290519081900360640190fd5b600155610b6c565b610a3384848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260048152636475657360e01b60208201529150610e629050565b15610b2f5760208114610a8d576040805162461bcd60e51b815260206004820152601760248201527f6c656e677468206f662064756573206d69736d61746368000000000000000000604482015290519081900360640190fd5b604080516020601f8401819004810282018101909252828152600091610acb91858580838501838280828437600092019190915250610f4992505050565b9050600081118015610ade575060015481105b610b27576040805162461bcd60e51b81526020600482015260156024820152747468652064756573206f7574206f662072616e676560581b604482015290519081900360640190fd5b600255610b6c565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b60005460ff1615610c62576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b68056bc75e2d63100000600190815567016345785d8a00006002556000805460ff19169091179055565b3360009081526004602052604090205460ff16610ce7576040805162461bcd60e51b81526020600482015260146024820152731c995b185e595c88191bc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b60005460ff16610d3a576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b610d4261102e565b5033600081815260036020908152604091829020825180840190935280548084526001909101549183018290529192916108fc91610d86919063ffffffff610f4e16565b6040518115909202916000818181858888f19350505050158015610dae573d6000803e3d6000fd5b50602081015160405161100291829181156108fc0291906000818181858888f19350505050158015610de4573d6000803e3d6000fd5b50336000818152600460209081526040808320805460ff191690556003825280832083815560010192909255815192835290517fd17202129b83db7880d6b9f25df81c58ad46f7e0e2c92236b1aa10663a4876679281900390910190a15050565b61100081565b60015481565b600381565b61100481565b3b151590565b6000816040516020018082805190602001908083835b60208310610e975780518252601f199092019160209182019101610e78565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310610f055780518252601f199092019160209182019101610ee6565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b6000610f9083836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610f97565b9392505050565b600081848411156110265760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610feb578181015183820152602001610fd3565b50505050905090810190601f1680156110185780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60405180604001604052806000815260200160008152509056fe636f6e7472616374206973206e6f7420616c6c6f77656420746f20626520612072656c61796572746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662072657175697265644465706f736974206d69736d61746368a2646970667358221220e7298bdd332800983f84daa6af4f7dfac92b01db35dc27e899b3d13982f2ccbd64736f6c63430006040033", + Code: "6080604052600436106101d85760003560e01c80637ae2308811610102578063c81b166211610095578063f9a2bbc711610064578063f9a2bbc714610569578063fb7cfdd71461057e578063fc3e590814610593578063fd6a6879146105a8576101d8565b8063c81b166214610515578063dc927faf1461052a578063e1c7392a1461053f578063e79a198f14610554576101d8565b8063a1a11bf5116100d1578063a1a11bf514610407578063a78abc161461041c578063ab51bb9614610431578063ac43175114610446576101d8565b80637ae23088146103b357806395468d26146103c857806396713da9146103dd5780639dc09262146103f2576101d8565b806351e806721161017a57806370fd5bad1161014957806370fd5bad1461035f578063718a8aa81461037457806375d47a0a146103895780637942fd051461039e576101d8565b806351e80672146102c7578063541d5548146102dc5780636a87d780146103235780636e47b4821461034a576101d8565b80633dffc387116101b65780633dffc3871461024657806343756e5c14610271578063493279b1146102865780634bf6c882146102b2576101d8565b80630bee7a67146101dd5780630e2374a51461020b5780631aa3a0081461023c575b600080fd5b3480156101e957600080fd5b506101f26105bd565b6040805163ffffffff9092168252519081900360200190f35b34801561021757600080fd5b506102206105c2565b604080516001600160a01b039092168252519081900360200190f35b6102446105c8565b005b34801561025257600080fd5b5061025b610749565b6040805160ff9092168252519081900360200190f35b34801561027d57600080fd5b5061022061074e565b34801561029257600080fd5b5061029b610754565b6040805161ffff9092168252519081900360200190f35b3480156102be57600080fd5b5061025b61075a565b3480156102d357600080fd5b5061022061075f565b3480156102e857600080fd5b5061030f600480360360208110156102ff57600080fd5b50356001600160a01b0316610765565b604080519115158252519081900360200190f35b34801561032f57600080fd5b50610338610783565b60408051918252519081900360200190f35b34801561035657600080fd5b50610220610789565b34801561036b57600080fd5b5061025b61078f565b34801561038057600080fd5b5061025b610794565b34801561039557600080fd5b50610220610799565b3480156103aa57600080fd5b5061025b61079f565b3480156103bf57600080fd5b506103386107a4565b3480156103d457600080fd5b506103386107b1565b3480156103e957600080fd5b5061025b6107bd565b3480156103fe57600080fd5b506102206107c2565b34801561041357600080fd5b506102206107c8565b34801561042857600080fd5b5061030f6107ce565b34801561043d57600080fd5b506101f26107d7565b34801561045257600080fd5b506102446004803603604081101561046957600080fd5b81019060208101813564010000000081111561048457600080fd5b82018360208201111561049657600080fd5b803590602001918460018302840111640100000000831117156104b857600080fd5b9193909290916020810190356401000000008111156104d657600080fd5b8201836020820111156104e857600080fd5b8035906020019184600183028401116401000000008311171561050a57600080fd5b5090925090506107dc565b34801561052157600080fd5b50610220610bfe565b34801561053657600080fd5b50610220610c04565b34801561054b57600080fd5b50610244610c0a565b34801561056057600080fd5b50610244610c8c565b34801561057557600080fd5b50610220610e45565b34801561058a57600080fd5b50610338610e4b565b34801561059f57600080fd5b5061025b610e51565b3480156105b457600080fd5b50610220610e56565b606481565b61200181565b3360009081526004602052604090205460ff1615610625576040805162461bcd60e51b81526020600482015260156024820152741c995b185e595c88185b1c9958591e48195e1a5cdd605a1b604482015290519081900360640190fd5b60005460ff16610678576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b61068133610e5c565b156106bd5760405162461bcd60e51b81526004018080602001828103825260278152602001806110496027913960400191505060405180910390fd5b333214610707576040805162461bcd60e51b81526020600482015260136024820152721b9bc81c1c9bde1e481a5cc8185b1b1bddd959606a1b604482015290519081900360640190fd5b6040805162461bcd60e51b81526020600482015260126024820152711c9959da5cdd195c881cdd5cdc195b99195960721b604482015290519081900360640190fd5b600181565b61100181565b6102ca81565b600881565b61200081565b6001600160a01b031660009081526004602052604090205460ff1690565b60025481565b61100581565b600281565b601081565b61100881565b600b81565b68056bc75e2d6310000081565b67016345785d8a000081565b600981565b61100781565b61100681565b60005460ff1681565b600081565b60005460ff1661082f576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b336110071461086f5760405162461bcd60e51b815260040180806020018281038252602e815260200180611070602e913960400191505060405180910390fd5b6108d584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e1c995c5d5a5c995911195c1bdcda5d608a1b60208201529150610e629050565b156109d857602081146109195760405162461bcd60e51b815260040180806020018281038252602281526020018061109e6022913960400191505060405180910390fd5b604080516020601f840181900481028201810190925282815260009161095791858580838501838280828437600092019190915250610f4992505050565b9f0506001811180156109725750683635c9adc5dea000008111155b801561097f575060025481115b6109d0576040805162461bcd60e51b815260206004820181905260248201527f7468652072657175697265644465706f736974206f7574206f662072616e6765604482015290519081900360640190fd5b600155610b6c565b610a3384848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260048152636475657360e01b60208201529150610e629050565b15610b2f5760208114610a8d576040805162461bcd60e51b815260206004820152601760248201527f6c656e677468206f662064756573206d69736d61746368000000000000000000604482015290519081900360640190fd5b604080516020601f8401819004810282018101909252828152600091610acb91858580838501838280828437600092019190915250610f4992505050565b9050600081118015610ade575060015481105b610b27576040805162461bcd60e51b81526020600482015260156024820152747468652064756573206f7574206f662072616e676560581b604482015290519081900360640190fd5b600255610b6c565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b60005460ff1615610c62576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b68056bc75e2d63100000600190815567016345785d8a00006002556000805460ff19169091179055565b3360009081526004602052604090205460ff16610ce7576040805162461bcd60e51b81526020600482015260146024820152731c995b185e595c88191bc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b60005460ff16610d3a576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b610d4261102e565b5033600081815260036020908152604091829020825180840190935280548084526001909101549183018290529192916108fc91610d86919063ffffffff610f4e16565b6040518115909202916000818181858888f19350505050158015610dae573d6000803e3d6000fd5b50602081015160405161100291829181156108fc0291906000818181858888f19350505050158015610de4573d6000803e3d6000fd5b50336000818152600460209081526040808320805460ff191690556003825280832083815560010192909255815192835290517fd17202129b83db7880d6b9f25df81c58ad46f7e0e2c92236b1aa10663a4876679281900390910190a15050565b61100081565b60015481565b600381565b61100481565b3b151590565b6000816040516020018082805190602001908083835b60208310610e975780518252601f199092019160209182019101610e78565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310610f055780518252601f199092019160209182019101610ee6565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b6000610f9083836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610f97565b9392505050565b600081848411156110265760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610feb578181015183820152602001610fd3565b50505050905090810190601f1680156110185780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60405180604001604052806000815260200160008152509056fe636f6e7472616374206973206e6f7420616c6c6f77656420746f20626520612072656c61796572746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662072657175697265644465706f736974206d69736d61746368a2646970667358221220e7298bdd332800983f84daa6af4f7dfac92b01db35dc27e899b3d13982f2ccbd64736f6c63430006040033", }, { ContractAddr: LightClientContract, @@ -478,6 +482,74 @@ func init() { }, } + PlanckUpgrade[networkname.BSCChainName] = &Upgrade{ + UpgradeName: "planck", + Configs: []*UpgradeConfig{ + { + ContractAddr: SlashContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/78e13b1d3a5a1b08c9208af94a9b14fc1efda213", + Code: "608060405234801561001057600080fd5b50600436106102535760003560e01c80637942fd0511610146578063ac431751116100c3578063dc927faf11610087578063dc927faf1461073b578063e1c7392a14610743578063f9a2bbc71461074b578063fc3e590814610753578063fc4333cd1461075b578063fd6a68791461076357610253565b8063ac431751146105cf578063c80d4b8f1461068d578063c81b166214610695578063c8509d811461069d578063c96be4cb1461071557610253565b80639dc092621161010a5780639dc0926214610593578063a1a11bf51461059b578063a78abc16146105a3578063ab51bb96146105bf578063ac0af629146105c757610253565b80637942fd05146104fb5780638256ace614610503578063831d65d11461050b57806396713da9146105835780639bc8e4f21461058b57610253565b80634bf6c882116101d45780636e47b482116101985780636e47b482146104d357806370fd5bad146104db578063718a8aa8146104e357806375d47a0a146104eb5780637912a65d146104f357610253565b80634bf6c8821461048b57806351e8067214610493578063567a372d1461049b5780635bfb4990146104a357806362b72cf5146104cb57610253565b806337c8dab91161021b57806337c8dab9146103ed578063389f4f711461042c5780633dffc3871461044657806343756e5c14610464578063493279b11461046c57610253565b80630bee7a67146102585780630e2374a5146102795780631182b8751461029d57806323bac5a21461038a57806335aa2e44146103d0575b600080fd5b61026061076b565b6040805163ffffffff9092168252519081900360200190f35b610281610770565b604080516001600160a01b039092168252519081900360200190f35b610315600480360360408110156102b357600080fd5b60ff8235169190810190604081016020820135600160201b8111156102d757600080fd5b8201836020820111156102e957600080fd5b803590602001918460018302840111600160201b8311171561030a57600080fd5b509092509050610776565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561034f578181015183820152602001610337565b50505050905090810190601f16801561037c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103b0600480360360208110156103a057600080fd5b50356001600160a01b031661084a565b604080519384526020840192909252151582820152519081900360600190f35b610281600480360360208110156103e657600080fd5b503561086d565b6104136004803603602081101561040357600080fd5b50356001600160a01b0316610894565b6040805192835260208301919091528051918290030190f35b6104346108eb565b60408051918252519081900360200190f35b61044e6108f1565b6040805160ff9092168252519081900360200190f35b6102816108f6565b6104746108fc565b6040805161ffff9092168252519081900360200190f35b61044e610901565b610281610906565b61043461090c565b6104c9600480360360208110156104b957600080fd5b50356001600160a01b0316610912565b005b610434610a73565b610281610a79565b61044e610a7f565b61044e610a84565b610281610a89565b610434610a8f565b61044e610a94565b610413610a99565b6104c96004803603604081101561052157600080fd5b60ff8235169190810190604081016020820135600160201b81111561054557600080fd5b82018360208201111561055757600080fd5b803590602001918460018302840111600160201b8311171561057857600080fd5b509092509050610aa3565b61044e610bfd565b610434610c02565b610281610c0d565b610281610c13565b6105ab610c19565b604080519115158252519081900360200190f35b610260610c22565b610434610c27565b6104c9600480360360408110156105e557600080fd5b810190602081018135600160201b8111156105ff57600080fd5b82018360208201111561061157600080fd5b803590602001918460018302840111600160201b8311171561063257600080fd5b919390929091602081019035600160201b81111561064f57600080fd5b82018360208201111561066157600080fd5b803590602001918460018302840111600160201b8311171561068257600080fd5b509092509050610c2c565b61043461101a565b61028161101f565b6104c9600480360360408110156106b357600080fd5b60ff8235169190810190604081016020820135600160201b8111156106d757600080fd5b8201836020820111156106e957600080fd5b803590602001918460018302840111600160201b8311171561070a57600080fd5b509092509050611025565b6104c96004803603602081101561072b57600080fd5b50356001600160a01b03166110d8565b610281611659565b6104c961165f565b6102816116d0565b61044e6116d6565b6104c96116db565b610281611b66565b606481565b61200181565b606033612000146107b85760405162461bcd60e51b815260040180806020018281038252602f8152602001806125bd602f913960400191505060405180910390fd5b60005460ff166107fd576040805162461bcd60e51b81526020600482015260196024820152600080516020612619833981519152604482015290519081900360640190fd5b6040805162461bcd60e51b815260206004820152601e60248201527f7265636569766520756e65787065637465642073796e207061636b6167650000604482015290519081900360640190fd5b600260208190526000918252604090912080546001820154919092015460ff1683565b6001818154811061087a57fe5b6000918252602090912001546001600160a01b0316905081565b60008061089f612481565b5050506001600160a01b0316600090815260026020818152604092839020835160608101855281548082526001830154938201849052919093015460ff16151592909301919091529091565b60055481565b600181565b61100181565b603881565b600881565b61200081565b60045481565b33611000146109525760405162461bcd60e51b81526004018080602001828103825260308152602001806125186030913960400191505060405180910390fd5b60005460ff16610997576040805162461bcd60e51b81526020600482015260196024820152600080516020612619833981519152604482015290519081900360640190fd5b61200063f7a251d7600b6109aa84611b6c565b60006040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015610a0a5781810151838201526020016109f2565b50505050905090810190601f168015610a375780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015610a5857600080fd5b505af1158015610a6c573d6000803e3d6000fd5b5050505050565b60035481565b61100581565b600281565b601081565b61100881565b603281565b600b81565b6004546005549091565b3361200014610ae35760405162461bcd60e51b815260040180806020018281038252602f8152602001806125bd602f913960400191505060405180910390fd5b60005460ff16610b28576040805162461bcd60e51b81526020600482015260196024820152600080516020612619833981519152604482015290519081900360640190fd5b610b306124a4565b6000610b7184848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c3e92505050565b915091508015610bbb5781516040805163ffffffff9092168252517f7f0956d47419b9525356e7111652b653b530ec6f5096dccc04589bc38e6299679181900360200190a1610a6c565b81516040805163ffffffff9092168252517f7d45f62d17443dd4547bca8a8112c60e2385669318dc300ec61a5d2492f262e79181900360200190a15050505050565b600981565b662386f26fc1000081565b61100781565b61100681565b60005460ff1681565b600081565b600481565b60005460ff16610c71576040805162461bcd60e51b81526020600482015260196024820152600080516020612619833981519152604482015290519081900360640190fd5b3361100714610cb15760405162461bcd60e51b815260040180806020018281038252602e815260200180612548602e913960400191505060405180910390fd5b610d1c84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260148152731b5a5cd9195b59585b9bdc951a1c995cda1bdb1960621b60208201529150611cbe9050565b15610df55760208114610d605760405162461bcd60e51b81526004018080602001828103825260278152602001806124f16027913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610d9e91858580838501838280828437600092019190915250611da692505050565b905060018110158015610db2575060055481105b610ded5760405162461bcd60e51b81526004018080602001828103825260258152602001806125986025913960400191505060405180910390fd5b600455610f88565b610e5b84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e19995b1bdb9e551a1c995cda1bdb19608a1b60208201529150611cbe9050565b15610f4b5760208114610e9f5760405162461bcd60e51b81526004018080602001828103825260228152602001806125766022913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610edd91858580838501838280828437600092019190915250611da692505050565b90506103e88111158015610ef2575060045481115b610f43576040805162461bcd60e51b815260206004820181905260248201527f7468652066656c6f6e795468726573686f6c64206f7574206f662072616e6765604482015290519081900360640190fd5b600555610f88565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b609681565b61100281565b33612000146110655760405162461bcd60e51b815260040180806020018281038252602f8152602001806125bd602f913960400191505060405180910390fd5b60005460ff166110aa576040805162461bcd60e51b81526020600482015260196024820152600080516020612619833981519152604482015290519081900360640190fd5b6040517f07db600eebe2ac176be8dcebad61858c245a4961bb32ca2aa3d159b09aa0810e90600090a1505050565b3341146111165760405162461bcd60e51b815260040180806020018281038252602d8152602001806125ec602d913960400191505060405180910390fd5b60005460ff1661115b576040805162461bcd60e51b81526020600482015260196024820152600080516020612619833981519152604482015290519081900360640190fd5b60035443116111b1576040805162461bcd60e51b815260206004820181905260248201527f63616e206e6f7420736c61736820747769636520696e206f6e6520626c6f636b604482015290519081900360640190fd5b3a156111fb576040805162461bcd60e51b81526020600482015260146024820152736761737072696365206973206e6f74207a65726f60601b604482015290519081900360640190fd5b6040805163155853f360e21b81526001600160a01b03831660048201529051611000916355614fcc916024808301926020929190829003018186803b15801561124357600080fd5b505afa158015611257573d6000803e3d6000fd5b505050506040513d602081101561126d57600080fd5b505161127857611652565b611280612481565b506001600160a01b0381166000908152600260208181526040928390208351606081018552815481526001820154928101929092529091015460ff1615801592820192909252906112db576020810180516001019052611334565b60016040820181905260208201819052805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0384161790555b43815260055460208201518161134657fe5b0661157657600060208201819052604080516335409f7f60e01b81526001600160a01b03851660048201529051611000926335409f7f926024808201939182900301818387803b15801561139957600080fd5b505af11580156113ad573d6000803e3d6000fd5b505050506120006001600160a01b031663f7a251d7600b6113cd85611b6c565b60006040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561142d578181015183820152602001611415565b50505050905090810190601f16801561145a5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561147b57600080fd5b505af192505050801561148c575060015b611571573d8080156114ba576040519150601f19603f3d011682016040523d82523d6000602084013e6114bf565b606091505b50826001600160a01b03167fd7bc86ff5d08c8ab043edec743302aba2520e6635172a428bc956721db9e2d1c8360200151836040518083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561153457818101518382015260200161151c565b50505050905090810190601f1680156115615780820380516001836020036101000a031916815260200191505b50935050505060405180910390a2505b6115ec565b60045481602001518161158557fe5b066115ec57604080516375abf10160e11b81526001600160a01b038416600482015290516110009163eb57e20291602480830192600092919082900301818387803b1580156115d357600080fd5b505af11580156115e7573d6000803e3d6000fd5b505050505b6001600160a01b0382166000818152600260208181526040808420865181559186015160018301558581015191909201805460ff1916911515919091179055517fddb6012116e51abf5436d956a4f0ebd927e92c576ff96d7918290c8782291e3e9190a2505b5043600355565b61100381565b60005460ff16156116b7576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b603260045560966005556000805460ff19166001179055565b61100081565b600381565b336110001461171b5760405162461bcd60e51b81526004018080602001828103825260308152602001806125186030913960400191505060405180910390fd5b60005460ff16611760576040805162461bcd60e51b81526020600482015260196024820152600080516020612619833981519152604482015290519081900360640190fd5b60015461176c57611b64565b600154600090600019015b808211611b38576000805b8284101561189b57611792612481565b60026000600187815481106117a357fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff1615159082015260055490915060049004816020015111156118855760046005548161181057fe5b0481602001510381602001818152505080600260006001888154811061183257fe5b6000918252602080832091909101546001600160a01b0316835282810193909352604091820190208351815591830151600183015591909101516002909101805460ff191691151591909117905561188f565b600192505061189b565b50600190930192611782565b828411611a32576118aa612481565b60026000600186815481106118bb57fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff1615159082015260055490915060049004816020015111156119a35760046005548161192857fe5b0481602001510381602001818152505080600260006001878154811061194a57fe5b6000918252602080832091909101546001600160a01b03168352828101939093526040918201902083518155918301516001808401919091559201516002909101805460ff19169115159190911790559150611a329050565b60026000600186815481106119b457fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff191690558054806119f857fe5b600082815260209020810160001990810180546001600160a01b031916905501905583611a255750611a32565b506000199092019161189b565b818015611a3c5750805b15611b1b576002600060018681548110611a5257fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff19169055805484908110611a9957fe5b600091825260209091200154600180546001600160a01b039092169186908110611abf57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506001805480611af857fe5b600082815260209020810160001990810180546001600160a01b03191690550190555b82611b27575050611b38565b505060019091019060001901611777565b6040517fcfdb3b6ccaeccbdc68be3c59c840e3b3c90f0a7c491f5fff1cf56cfda200dd9c90600090a150505b565b61100481565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081611b87579050509050611bb0836001600160a01b0316611dab565b81600081518110611bbd57fe5b6020026020010181905250611bd143611dce565b81600181518110611bde57fe5b6020908102919091010152611bf36038611dce565b81600281518110611c0057fe5b6020026020010181905250611c1442611dce565b81600381518110611c2157fe5b6020026020010181905250611c3581611de1565b9150505b919050565b611c466124a4565b6000611c506124a4565b611c586124b6565b611c69611c6486611e6b565b611e90565b90506000805b611c7883611eda565b15611cb15780611ca457611c93611c8e84611efb565b611f49565b63ffffffff16845260019150611ca9565b611cb1565b600101611c6f565b5091935090915050915091565b6000816040516020018082805190602001908083835b60208310611cf35780518252601f199092019160209182019101611cd4565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310611d615780518252601f199092019160209182019101611d42565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490505b92915050565b015190565b60408051600560a21b8318601482015260348101909152606090611c3581612000565b6060611da0611ddc83612056565b612000565b6060815160001415611e025750604080516000815260208101909152611c39565b606082600081518110611e1157fe5b602002602001015190506000600190505b8351811015611e5257611e4882858381518110611e3b57fe5b602002602001015161213c565b9150600101611e22565b50611c35611e65825160c060ff166121b9565b8261213c565b611e736124d6565b506040805180820190915281518152602082810190820152919050565b611e986124b6565b611ea1826122b1565b611eaa57600080fd5b6000611eb983602001516122eb565b60208085015160408051808201909152868152920190820152915050919050565b6000611ee46124d6565b505080518051602091820151919092015191011190565b611f036124d6565b611f0c82611eda565b611f1557600080fd5b60208201516000611f258261234e565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590611f5e57508151602110155b611f6757600080fd5b6000611f7683602001516122eb565b90508083600001511015611fd1576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b825160208085015183018051928490039291831015611ff757826020036101000a820491505b50949350505050565b6060815160011480156120325750607f60f81b8260008151811061202057fe5b01602001516001600160f81b03191611155b1561203e575080611c39565b611da06120508351608060ff166121b9565b8361213c565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff19841661209a575060186120be565b6fffffffffffffffffffffffffffffffff1984166120ba575060106120be565b5060005b60208110156120f4578181815181106120d357fe5b01602001516001600160f81b031916156120ec576120f4565b6001016120be565b60008160200390506060816040519080825280601f01601f191660200182016040528015612129576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b8183101561216d578051835260209283019201612155565b50855184518101855292509050808201602086015b8183101561219a578051835260209283019201612182565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310612209576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b604080516001808252818301909252606091602082018180368337019050509050603784116122635782840160f81b8160008151811061224557fe5b60200101906001600160f81b031916908160001a9053509050611da0565b606061226e85612056565b90508381510160370160f81b8260008151811061228757fe5b60200101906001600160f81b031916908160001a9053506122a8828261213c565b95945050505050565b80516000906122c257506000611c39565b6020820151805160001a9060c08210156122e157600092505050611c39565b5060019392505050565b8051600090811a6080811015612305576000915050611c39565b60b8811080612320575060c08110801590612320575060f881105b1561232f576001915050611c39565b60c08110156123435760b519019050611c39565b60f519019050611c39565b80516000908190811a6080811015612369576001915061247a565b60b881101561237e57607e198101915061247a565b60c08110156123f857600060b78203600186019550806020036101000a8651049150600181018201935050808310156123f2576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b5061247a565b60f881101561240d5760be198101915061247a565b600060f78203600186019550806020036101000a865104915060018101820193505080831015612478576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b604051806060016040528060008152602001600081526020016000151581525090565b60408051602081019091526000815290565b60405180604001604052806124c96124d6565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe6c656e677468206f66206d697364656d65616e6f725468726573686f6c64206d69736d61746368746865206d6573736167652073656e646572206d7573742062652076616c696461746f7253657420636f6e7472616374746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662066656c6f6e795468726573686f6c64206d69736d61746368746865206d697364656d65616e6f725468726573686f6c64206f7574206f662072616e6765746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d6573736167652073656e646572206d7573742062652074686520626c6f636b2070726f647563657274686520636f6e7472616374206e6f7420696e69742079657400000000000000a2646970667358221220638a87b280b96494e110d626ea9527bb15cb9cf42454fbab93839017affa9a8564736f6c63430006040033", + }, + { + ContractAddr: TokenHubContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/78e13b1d3a5a1b08c9208af94a9b14fc1efda213", + Code: "6080604052600436106103c75760003560e01c806396713da9116101f2578063c81b16621161010d578063f0148472116100a0578063fc1a598f1161006f578063fc1a598f14610f25578063fc3e590814610b85578063fd6a687914610f58578063ff9c0027146107fd5761040f565b8063f014847214610ed1578063f9a2bbc714610ee6578063fa9e915914610efb578063fb063e8f14610f105761040f565b8063dc927faf116100dc578063dc927faf14610e5f578063e1c7392a14610e74578063e8f35cea14610e89578063ebf71d5314610ebc5761040f565b8063c81b166214610d8a578063c8509d8114610d9f578063cf41984414610e24578063d9e6dae91461077f5761040f565b8063aa7415f511610185578063b9fd21e311610154578063b9fd21e314610cfa578063ba35ead614610d0f578063bbface1f14610d24578063bd46646114610d575761040f565b8063aa7415f514610b9a578063ab51bb9614610be1578063ac43175114610bf6578063b99328c514610cc15761040f565b8063a1a11bf5116101c1578063a1a11bf514610b46578063a496fba214610b5b578063a78abc1614610b70578063a7c9f02d14610b855761040f565b806396713da914610ace5780639a854bbd14610ae35780639a99b4f014610af85780639dc0926214610b315761040f565b806359b92789116102e257806371d3086311610275578063831d65d111610244578063831d65d1146109d15780638b87b21f146106d45780638eff336c14610a565780639509b98014610a955761040f565b806371d3086314610968578063727be1f81461097d57806375d47a0a146109a75780637942fd05146109bc5761040f565b80636e056520116102b15780636e056520146108125780636e47b4821461093e57806370fd5bad146107fd578063718a8aa8146109535761040f565b806359b92789146107be5780635d499b1b146107e8578063613684751461077f57806366dea52a146107fd5761040f565b80633fd8b02f1161035a5780634a3acdf4116103295780634a3acdf41461076a5780634bf6c8821461077f57806350432d321461079457806351e80672146107a95761040f565b80633fd8b02f146106ff57806343756e5c1461071457806343a368b914610729578063493279b11461073e5761040f565b8063149d14d911610396578063149d14d9146105a85780632ae45483146105cf5780633d713223146106235780633dffc387146106d45761040f565b80630bee7a67146104145780630e2374a5146104425780631182b87514610473578063122345821461056d5761040f565b3661040f57341561040d576040805133815234602082015281517f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db929181900390910190a15b005b600080fd5b34801561042057600080fd5b50610429610f6d565b6040805163ffffffff9092168252519081900360200190f35b34801561044e57600080fd5b50610457610f72565b604080516001600160a01b039092168252519081900360200190f35b34801561047f57600080fd5b506104f86004803603604081101561049657600080fd5b60ff8235169190810190604081016020820135600160201b8111156104ba57600080fd5b8201836020820111156104cc57600080fd5b803590602001918460018302840111600160201b831117156104ed57600080fd5b509092509050610f78565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561053257818101518382015260200161051a565b50505050905090810190601f16801561055f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561057957600080fd5b5061040d6004803603604081101561059057600080fd5b506001600160a01b03813581169160200135166110a6565b3480156105b457600080fd5b506105bd6111a0565b60408051918252519081900360200190f35b3480156105db57600080fd5b5061060a600480360360408110156105f257600080fd5b506001600160a01b03813581169160200135166111a6565b6040805192835260208301919091528051918290030190f35b34801561062f57600080fd5b506104576004803603602081101561064657600080fd5b810190602081018135600160201b81111561066057600080fd5b82018360208201111561067257600080fd5b803590602001918460018302840111600160201b8311171561069357600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506111ca945050505050565b3480156106e057600080fd5b506106e96111ee565b6040805160ff9092168252519081900360200190f35b34801561070b57600080fd5b506105bd6111f3565b34801561072057600080fd5b506104576111f9565b34801561073557600080fd5b506105bd6111ff565b34801561074a57600080fd5b5061075361120b565b6040805161ffff9092168252519081900360200190f35b34801561077657600080fd5b506105bd611210565b34801561078b57600080fd5b506106e9611216565b3480156107a057600080fd5b506105bd61121b565b3480156107b557600080fd5b50610457611226565b3480156107ca57600080fd5b50610457600480360360208110156107e157600080fd5b503561122c565b3480156107f457600080fd5b506105bd611247565b34801561080957600080fd5b506106e9611250565b61092a6004803603608081101561082857600080fd5b810190602081018135600160201b81111561084257600080fd5b82018360208201111561085457600080fd5b803590602001918460208302840111600160201b8311171561087557600080fd5b919390929091602081019035600160201b81111561089257600080fd5b8201836020820111156108a457600080fd5b803590602001918460208302840111600160201b831117156108c557600080fd5b919390929091602081019035600160201b8111156108e257600080fd5b8201836020820111156108f457600080fd5b803590602001918460208302840111600160201b8311171561091557600080fd5b91935091503567ffffffffffffffff16611255565b604080519115158252519081900360200190f35b34801561094a57600080fd5b5061045761172a565b34801561095f57600080fd5b506106e9611730565b34801561097457600080fd5b506105bd611735565b34801561098957600080fd5b5061092a600480360360208110156109a057600080fd5b503561173b565b3480156109b357600080fd5b506104576117bc565b3480156109c857600080fd5b506106e96117c2565b3480156109dd57600080fd5b5061040d600480360360408110156109f457600080fd5b60ff8235169190810190604081016020820135600160201b811115610a1857600080fd5b820183602082011115610a2a57600080fd5b803590602001918460018302840111600160201b83111715610a4b57600080fd5b5090925090506117c7565b348015610a6257600080fd5b5061040d60048036036060811015610a7957600080fd5b508035906001600160a01b036020820135169060400135611910565b348015610aa157600080fd5b5061040d60048036036040811015610ab857600080fd5b506001600160a01b038135169060200135611996565b348015610ada57600080fd5b506106e9611b53565b348015610aef57600080fd5b506105bd611b58565b348015610b0457600080fd5b506105bd60048036036040811015610b1b57600080fd5b506001600160a01b038135169060200135611b64565b348015610b3d57600080fd5b50610457611ca2565b348015610b5257600080fd5b50610457611ca8565b348015610b6757600080fd5b506106e9611cae565b348015610b7c57600080fd5b5061092a611cb3565b348015610b9157600080fd5b506106e9611cbc565b61092a60048036036080811015610bb057600080fd5b5080356001600160a01b03908116916020810135909116906040810135906060013567ffffffffffffffff16611cc1565b348015610bed57600080fd5b50610429611cae565b348015610c0257600080fd5b5061040d60048036036040811015610c1957600080fd5b810190602081018135600160201b811115610c3357600080fd5b820183602082011115610c4557600080fd5b803590602001918460018302840111600160201b83111715610c6657600080fd5b919390929091602081019035600160201b811115610c8357600080fd5b820183602082011115610c9557600080fd5b803590602001918460018302840111600160201b83111715610cb657600080fd5b509092509050612382565b348015610ccd57600080fd5b5061040d60048036036040811015610ce457600080fd5b50803590602001356001600160a01b031661282a565b348015610d0657600080fd5b506105bd6128a0565b348015610d1b57600080fd5b506105bd6128aa565b348015610d3057600080fd5b506105bd60048036036020811015610d4757600080fd5b50356001600160a01b03166128b0565b348015610d6357600080fd5b506105bd60048036036020811015610d7a57600080fd5b50356001600160a01b03166128c2565b348015610d9657600080fd5b506104576128dd565b348015610dab57600080fd5b5061040d60048036036040811015610dc257600080fd5b60ff8235169190810190604081016020820135600160201b811115610de657600080fd5b820183602082011115610df857600080fd5b803590602001918460018302840111600160201b83111715610e1957600080fd5b5090925090506128e3565b348015610e3057600080fd5b5061040d60048036036040811015610e4757600080fd5b506001600160a01b03813581169160200135166129b3565b348015610e6b57600080fd5b50610457612c87565b348015610e8057600080fd5b5061040d612c8d565b348015610e9557600080fd5b506105bd60048036036020811015610eac57600080fd5b50356001600160a01b0316612d2d565b348015610ec857600080fd5b506106e9612d3f565b348015610edd57600080fd5b506106e9612d44565b348015610ef257600080fd5b50610457612d49565b348015610f0757600080fd5b506105bd612d4f565b348015610f1c57600080fd5b506105bd612d55565b348015610f3157600080fd5b506104f860048036036020811015610f4857600080fd5b50356001600160a01b0316612d63565b348015610f6457600080fd5b50610457612e8a565b606481565b61200181565b60005460609060ff16610fc0576040805162461bcd60e51b81526020600482015260196024820152600080516020615582833981519152604482015290519081900360640190fd5b33612000146110005760405162461bcd60e51b815260040180806020018281038252602f815260200180615530602f913960400191505060405180910390fd5b60ff8416600214156110525761104b83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612e9092505050565b905061109f565b6040805162461bcd60e51b815260206004820152601860248201527f756e7265636f676e697a65642073796e207061636b6167650000000000000000604482015290519081900360640190fd5b9392505050565b33612000146110e65760405162461bcd60e51b815260040180806020018281038252602f815260200180615530602f913960400191505060405180910390fd5b6001600160a01b0380831660009081526007602090815260408083209385168352929052208054611151576040805162461bcd60e51b815260206004820152601060248201526f1b9bc81b1bd8dad95908185b5bdd5b9d60821b604482015290519081900360640190fd5b8054600082556040805182815290516001600160a01b0380861692908716917f152fb15aa5d80f843e1e4bd5f2fc9161714f169945024decec7e84fb910fdd519181900360200190a350505050565b60015490565b60076020908152600092835260408084209091529082529020805460019091015482565b6020818101516000908152600490915260409020546001600160a01b03165b919050565b600181565b60055481565b61100181565b670de0b6b3a764000081565b603881565b61a8c081565b600881565b66071afd498d000081565b61200081565b6000908152600460205260409020546001600160a01b031690565b6402540be40081565b600281565b6000805460ff1661129b576040805162461bcd60e51b81526020600482015260196024820152600080516020615582833981519152604482015290519081900360640190fd5b8685146112d95760405162461bcd60e51b815260040180806020018281038252603b8152602001806154f5603b913960400191505060405180910390fd5b8683146113175760405162461bcd60e51b815260040180806020018281038252603f8152602001806153c8603f913960400191505060405180910390fd5b426078018267ffffffffffffffff1610156113635760405162461bcd60e51b81526004018080602001828103825260248152602001806152b86024913960400191505060405180910390fd5b6402540be4003406156113a75760405162461bcd60e51b81526004018080602001828103825260408152602001806155f86040913960400191505060405180910390fd5b604080518681526020808802820101909152859060009081906060908480156113da578160200160208202803683370190505b50905060005b848110156114b5576402540be4008b8b838181106113fa57fe5b905060200201358161140857fe5b06156114455760405162461bcd60e51b815260040180806020018281038252603c815260200180615407603c913960400191505060405180910390fd5b61146a8b8b8381811061145457fe5b9050602002013585612fb490919063ffffffff16565b93506114966402540be4008c8c8481811061148157fe5b9050602002013561300e90919063ffffffff16565b8282815181106114a257fe5b60209081029190910101526001016113e0565b506001546114da906114cd908663ffffffff61305016565b849063ffffffff612fb416565b3410156115185760405162461bcd60e51b81526004018080602001828103825260568152602001806155a26056913960600191505060405180910390fd5b611528348463ffffffff6130a916565b91506115326150bc565b6040518060c001604052806221272160e91b60001b815260200160006001600160a01b031681526020018381526020018e8e808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050908252506040805160208c810282810182019093528c82529283019290918d918d91829185019084908082843760009201919091525050509082525067ffffffffffffffff8916602090910152905061200063f7a251d760036115f6846130eb565b61160b876402540be40063ffffffff61300e16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611669578181015183820152602001611651565b50505050905090810190601f1680156116965780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156116b757600080fd5b505af11580156116cb573d6000803e3d6000fd5b505060408051600081523360208201528082018890526060810187905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9350908190036080019150a15060019c9b505050505050505050505050565b61100581565b601081565b60015481565b6000336120011461177d5760405162461bcd60e51b81526004018080602001828103825260338152602001806151d66033913960400191505060405180910390fd5b81156117b4576040516120019083156108fc029084906000818181858888f193505050501580156117b2573d6000803e3d6000fd5b505b506001919050565b61100881565b600b81565b60005460ff1661180c576040805162461bcd60e51b81526020600482015260196024820152600080516020615582833981519152604482015290519081900360640190fd5b336120001461184c5760405162461bcd60e51b815260040180806020018281038252602f815260200180615530602f913960400191505060405180910390fd5b60ff83166003141561189c5761189782828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506133a692505050565b61190b565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a15b505050565b33611008146119505760405162461bcd60e51b815260040180806020018281038252602381526020018061555f6023913960400191505060405180910390fd5b600083815260046020908152604080832080546001600160a01b039096166001600160a01b03199096168617905593825260038152838220949094556002909352912055565b81806001600160a01b031663893d20e86040518163ffffffff1660e01b815260040160206040518083038186803b1580156119d057600080fd5b505afa1580156119e4573d6000803e3d6000fd5b505050506040513d60208110156119fa57600080fd5b50516001600160a01b03163314611a58576040805162461bcd60e51b815260206004820152601860248201527f6e6f74206f776e6572206f6620424550323020746f6b656e0000000000000000604482015290519081900360640190fd5b60008211611aa6576040805162461bcd60e51b81526020600482015260166024820152751e995c9bc81b1a5b5a5d081b9bdd08185b1b1bddd95960521b604482015290519081900360640190fd5b6001600160a01b038316600090815260036020526040902054611afc576040805162461bcd60e51b81526020600482015260096024820152681b9bdd08189bdd5b9960ba1b604482015290519081900360640190fd5b6001600160a01b038316600081815260066020908152604091829020859055815185815291513393927f9df3a90730dbf23b5cc18dbbd5f4af3fa94a0dffb6ff6841f98a9a9a6ac626a892908290030190a3505050565b600981565b677ce66c50e284000081565b6000805460ff16611baa576040805162461bcd60e51b81526020600482015260196024820152600080516020615582833981519152604482015290519081900360640190fd5b3361100514611bea5760405162461bcd60e51b815260040180806020018281038252602f815260200180615209602f913960400191505060405180910390fd5b6000478310611bf95747611bfb565b825b9050670de0b6b3a7640000811115611c17576000915050611c9c565b8015611c99576040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015611c53573d6000803e3d6000fd5b50604080516001600160a01b03861681526020810183905281517ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0929181900390910190a15b90505b92915050565b61100781565b61100681565b600081565b60005460ff1681565b600381565b6000805460ff16611d07576040805162461bcd60e51b81526020600482015260196024820152600080516020615582833981519152604482015290519081900360640190fd5b426078018267ffffffffffffffff161015611d535760405162461bcd60e51b81526004018080602001828103825260248152602001806152b86024913960400191505060405180910390fd5b6402540be400340615611d975760405162461bcd60e51b81526004018080602001828103825260408152602001806155f86040913960400191505060405180910390fd5b600080806001600160a01b038816611e7657600154611dbd90879063ffffffff612fb416565b341015611dfb5760405162461bcd60e51b81526004018080602001828103825260618152602001806153426061913960800191505060405180910390fd5b6402540be400860615611e3f5760405162461bcd60e51b815260040180806020018281038252603c815260200180615407603c913960400191505060405180910390fd5b611e4f348763ffffffff6130a916565b9050611e66866402540be40063ffffffff61300e16565b6221272160e91b93509150612119565b6001600160a01b038816600090815260036020526040902054925082611ecd5760405162461bcd60e51b81526004018080602001828103825260318152602001806153116031913960400191505060405180910390fd5b600154341015611f0e5760405162461bcd60e51b815260040180806020018281038252603f815260200180615464603f913960400191505060405180910390fd5b506001600160a01b0387166000908152600260205260409020543490600881111580611f595750600881118015611f595750611f57876007198301600a0a63ffffffff61340216565b155b611f945760405162461bcd60e51b815260040180806020018281038252603c815260200180615407603c913960400191505060405180910390fd5b611f9e8782613444565b9250611fa984613484565b15611ff1576305f5e100831015611ff15760405162461bcd60e51b815260040180806020018281038252603a81526020018061525a603a913960400191505060405180910390fd5b60088110158061200b575060088110801561200b57508683115b6120465760405162461bcd60e51b81526004018080602001828103825260258152602001806153a36025913960400191505060405180910390fd5b677ce66c50e284000083111561208d5760405162461bcd60e51b81526004018080602001828103825260358152602001806152dc6035913960400191505060405180910390fd5b604080516323b872dd60e01b81523360048201523060248201526044810189905290516001600160a01b038b16916323b872dd9160648083019260209291908290030181600087803b1580156120e257600080fd5b505af11580156120f6573d6000803e3d6000fd5b505050506040513d602081101561210c57600080fd5b505161211757600080fd5b505b6121216150bc565b6040805160c0810182528581526001600160a01b038b166020820152815160018082528184018452919283019181602001602082028036833750505081526040805160018082528183019092526020928301929091908083019080368337505050815260408051600180825281830190925260209283019290919080830190803683370190505081526020018767ffffffffffffffff1681525090508281604001516000815181106121cf57fe5b6020026020010181815250508781606001516000815181106121ed57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505033816080015160008151811061221f57fe5b6001600160a01b039092166020928302919091019091015261200063f7a251d7600361224a846130eb565b61225f866402540be40063ffffffff61300e16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156122bd5781810151838201526020016122a5565b50505050905090810190601f1680156122ea5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561230b57600080fd5b505af115801561231f573d6000803e3d6000fd5b5050604080516001600160a01b038d1681523360208201528082018b90526060810186905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9350908190036080019150a150600198975050505050505050565b33611007146123c25760405162461bcd60e51b815260040180806020018281038252602e8152602001806154a3602e913960400191505060405180910390fd5b60208114612417576040805162461bcd60e51b815260206004820152601b60248201527f65787065637465642076616c7565206c656e6774682069732033320000000000604482015290519081900360640190fd5b606084848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8801819004810282018101909252868152939450606093925086915085908190840183828082843760009201919091525050505060208301519091506772656c617946656560c01b81141561251f576020820151670de0b6b3a764000081118015906124c657506402540be4008106155b612517576040805162461bcd60e51b815260206004820152601960248201527f7468652072656c6179466565206f7574206f662072616e676500000000000000604482015290519081900360640190fd5b600155612795565b61259387878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601781527f6c617267655472616e736665724c6f636b506572696f640000000000000000006020820152915061358a9050565b1561262f57604080516020601f87018190048102820181019092528581526000916125d69188888083850183828082843760009201919091525061367192505050565b905062093a80811115612627576040805162461bcd60e51b81526020600482015260146024820152736c6f636b20706572696f6420746f6f206c6f6e6760601b604482015290519081900360640190fd5b600555612795565b61269b87878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526015815274189b9893185c99d9551c985b9cd9995c931a5b5a5d605a1b6020820152915061358a9050565b1561275857604080516020601f87018190048102820181019092528581526000916126de9188888083850183828082843760009201919091525061367192505050565b905068056bc75e2d631000008110156127285760405162461bcd60e51b81526004018080602001828103825260228152602001806152386022913960400191505060405180910390fd5b6000805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f855612795565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a878787876040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050505050565b336110081461286a5760405162461bcd60e51b815260040180806020018281038252602381526020018061555f6023913960400191505060405180910390fd5b600091825260046020908152604080842080546001600160a01b03191690556001600160a01b0392909216835260039052812055565b6221272160e91b81565b61c35081565b60026020526000908152604090205481565b6001600160a01b031660009081526003602052604090205490565b61100281565b60005460ff16612928576040805162461bcd60e51b81526020600482015260196024820152600080516020615582833981519152604482015290519081900360640190fd5b33612000146129685760405162461bcd60e51b815260040180806020018281038252602f815260200180615530602f913960400191505060405180910390fd5b60ff83166003141561189c5761189782828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061367692505050565b60085460ff16600214156129ff576040805162461bcd60e51b815260206004820152600e60248201526d4e6f2072652d656e7472616e637960901b604482015290519081900360640190fd5b6008805460ff191660021790556001600160a01b0380831660009081526007602090815260408083209385168352929052208054612a77576040805162461bcd60e51b815260206004820152601060248201526f1b9bc81b1bd8dad95908185b5bdd5b9d60821b604482015290519081900360640190fd5b8060010154421015612ad0576040805162461bcd60e51b815260206004820152601760248201527f7374696c6c206f6e206c6f636b696e6720706572696f64000000000000000000604482015290519081900360640190fd5b805460008083556001600160a01b038516612b43576040516001600160a01b038516906127109084906000818181858888f193505050503d8060008114612b33576040519150601f19603f3d011682016040523d82523d6000602084013e612b38565b606091505b505080915050612bd6565b846001600160a01b031663a9059cbb61c35086856040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b158015612ba657600080fd5b5087f1158015612bba573d6000803e3d6000fd5b50505050506040513d6020811015612bd157600080fd5b505190505b80612c28576040805162461bcd60e51b815260206004820152601e60248201527f776974686472617720756e6c6f636b656420746f6b656e206661696c65640000604482015290519081900360640190fd5b836001600160a01b0316856001600160a01b03167f832fc3e25f2b3e6fb0eb59419a73cba405f2a249fce75f7e31ea5a457a0323f1846040518082815260200191505060405180910390a350506008805460ff19166001179055505050565b61100381565b60005460ff1615612ce5576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b66071afd498d000060019081556000808052600260205260127fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b55805460ff19169091179055565b60066020526000908152604090205481565b600481565b600581565b61100081565b61271081565b69021e19e0c9bab240000081565b6001600160a01b03811660009081526003602090815260409182902054825182815280840190935260609290918391906020820181803683375050506020810183905290506000805b60208160ff161015612df357828160ff1681518110612dc757fe5b01602001516001600160f81b03191615612de657600190910190612deb565b612df3565b600101612dac565b5060608160ff166040519080825280601f01601f191660200182016040528015612e24576020820181803683370190505b50905060005b8260ff168160ff161015612e8057838160ff1681518110612e4757fe5b602001015160f81c60f81b828260ff1681518110612e6157fe5b60200101906001600160f81b031916908160001a905350600101612e2a565b5095945050505050565b61100481565b6060612e9a615108565b6000612ea584613774565b9150915080612efb576040805162461bcd60e51b815260206004820152601f60248201527f756e7265636f676e697a6564207472616e73666572496e207061636b61676500604482015290519081900360640190fd5b6000612f06836138b3565b905063ffffffff811615612f9a576040808401516020808601516001600160a01b03166000908152600290915291822054612f419190613444565b9050612f4b61513d565b60405180608001604052808660000151815260200183815260200186608001516001600160a01b031681526020018463ffffffff168152509050612f8e81613c19565b955050505050506111e9565b505060408051600081526020810190915291506111e99050565b600082820183811015611c99576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000611c9983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613cf5565b60008261305f57506000611c9c565b8282028284828161306c57fe5b0414611c995760405162461bcd60e51b81526004018080602001828103825260218152602001806154436021913960400191505060405180910390fd5b6000611c9983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613d97565b60408051600680825260e08201909252606091829190816020015b6060815260200190600190039081613106575050835190915061312890613df1565b8160008151811061313557fe5b602002602001018190525061315683602001516001600160a01b0316613e04565b8160018151811061316357fe5b6020026020010181905250600083604001515190506060816040519080825280602002602001820160405280156131ae57816020015b60608152602001906001900390816131995790505b50905060005b828110156131fb576131dc866040015182815181106131cf57fe5b6020026020010151613df1565b8282815181106131e857fe5b60209081029190910101526001016131b4565b5061320581613e27565b8360028151811061321257fe5b602002602001018190525060608260405190808252806020026020018201604052801561325357816020015b606081526020019060019003908161323e5790505b50905060005b838110156132a95761328a8760600151828151811061327457fe5b60200260200101516001600160a01b0316613e04565b82828151811061329657fe5b6020908102919091010152600101613259565b506132b381613e27565b846003815181106132c057fe5b602002602001018190525060608360405190808252806020026020018201604052801561330157816020015b60608152602001906001900390816132ec5790505b50905060005b84811015613341576133228860800151828151811061327457fe5b82828151811061332e57fe5b6020908102919091010152600101613307565b5061334b81613e27565b8560048151811061335857fe5b602002602001018190525061337a8760a0015167ffffffffffffffff16613df1565b8560058151811061338757fe5b602002602001018190525061339b85613e27565b979650505050505050565b6133ae615164565b60006133b983613eb1565b91509150806133f95760405162461bcd60e51b81526004018080602001828103825260248152602001806154d16024913960400191505060405180910390fd5b61190b8261407c565b6000611c9983836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815250614500565b6000600882111561346d57613466836007198401600a0a63ffffffff61300e16565b9050611c9c565b611c99836008849003600a0a63ffffffff61305016565b604080516020808252818301909252600091606091906020820181803683375050506020810184905290506000805b60208160ff1610156134fa57828160ff16815181106134ce57fe5b01602001516001600160f81b031916156134ed576001909101906134f2565b6134fa565b6001016134b3565b50600760ff82161015613512576000925050506111e9565b816005820360ff168151811061352457fe5b6020910101516001600160f81b031916602d60f81b14613549576000925050506111e9565b816001820360ff168151811061355b57fe5b6020910101516001600160f81b031916604d60f81b14613580576000925050506111e9565b5060019392505050565b6000816040516020018082805190602001908083835b602083106135bf5780518252601f1990920191602091820191016135a0565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b6020831061362d5780518252601f19909201916020918201910161360e565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b61367e6150bc565b600061368983614562565b91509150806136c95760405162461bcd60e51b81526004018080602001828103825260248152602001806152946024913960400191505060405180910390fd5b6136d1615164565b602080840180516001600160a01b0390811684526040808701518585015291511660009081526002909252812054905b8460400151518110156137525761372f8560400151828151811061372157fe5b6020026020010151836147c6565b8560400151828151811061373f57fe5b6020908102919091010152600101613701565b50608084015160408301526005606083015261376d8261407c565b5050505050565b61377c615108565b6000613786615108565b61378e61519b565b61379f61379a866147ff565b614824565b90506000805b6137ae8361486e565b156138a657806137d0576137c96137c48461488f565b6148dd565b845261389e565b80600114156137fd576137ea6137e58461488f565b614994565b6001600160a01b0316602085015261389e565b806002141561381c576138126137c48461488f565b604085015261389e565b8060031415613844576138316137e58461488f565b6001600160a01b0316606085015261389e565b806004141561386c576138596137e58461488f565b6001600160a01b0316608085015261389e565b8060051415613899576138816137c48461488f565b67ffffffffffffffff1660a08501526001915061389e565b6138a6565b6001016137a5565b5091935090915050915091565b60208101516000906001600160a01b03166139f7578160a0015167ffffffffffffffff164211156138e6575060016111e9565b81604001514710156138fa575060036111e9565b613903826149ae565b61397857606082015160408084015190516000926001600160a01b0316916127109184818181858888f193505050503d806000811461395e576040519150601f19603f3d011682016040523d82523d6000602084013e613963565b606091505b50509050806139765750600490506111e9565b505b7f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5982602001518360600151846040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a15060006111e9565b8160a0015167ffffffffffffffff16421115613a15575060016111e9565b81516020808401516001600160a01b031660009081526003909152604090205414613a42575060026111e9565b602080830151604080516370a0823160e01b815230600482015290516000936001600160a01b03909316926370a082319261c3509260248083019392829003018187803b158015613a9257600080fd5b5086fa158015613aa6573d6000803e3d6000fd5b50505050506040513d6020811015613abd57600080fd5b50516040840151909150811015613ad85750600390506111e9565b613ae1836149ae565b613b9857600083602001516001600160a01b031663a9059cbb61c350866060015187604001516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b158015613b5657600080fd5b5087f1158015613b6a573d6000803e3d6000fd5b50505050506040513d6020811015613b8157600080fd5b5051905080613b965750600591506111e99050565b505b7f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5983602001518460600151856040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a150600090506111e9565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081613c345750508351909150613c5690613df1565b81600081518110613c6357fe5b6020026020010181905250613c7b8360200151613df1565b81600181518110613c8857fe5b6020026020010181905250613ca983604001516001600160a01b0316613e04565b81600281518110613cb657fe5b6020026020010181905250613cd4836060015163ffffffff16613df1565b81600381518110613ce157fe5b602002602001018190525061109f81613e27565b60008183613d815760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613d46578181015183820152602001613d2e565b50505050905090810190601f168015613d735780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581613d8d57fe5b0495945050505050565b60008184841115613de95760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613d46578181015183820152602001613d2e565b505050900390565b6060611c9c613dff83614b1c565b614c02565b60408051600560a21b831860148201526034810190915260609061109f81614c02565b6060815160001415613e4857506040805160008152602081019091526111e9565b606082600081518110613e5757fe5b602002602001015190506000600190505b8351811015613e9857613e8e82858381518110613e8157fe5b6020026020010151614c54565b9150600101613e68565b5061109f613eab825160c060ff16614cd1565b82614c54565b613eb9615164565b6000613ec3615164565b613ecb61519b565b613ed761379a866147ff565b90506000805b613ee68361486e565b156138a65780613f0c57613efc6137e58461488f565b6001600160a01b03168452614074565b8060011415613fad576060613f28613f238561488f565b614dc9565b90508051604051908082528060200260200182016040528015613f55578160200160208202803683370190505b50602086015260005b8151811015613fa657613f83828281518110613f7657fe5b60200260200101516148dd565b86602001518281518110613f9357fe5b6020908102919091010152600101613f5e565b5050614074565b806002141561404f576060613fc4613f238561488f565b90508051604051908082528060200260200182016040528015613ff1578160200160208202803683370190505b50604086015260005b8151811015613fa65761401f82828151811061401257fe5b6020026020010151614994565b8660400151828151811061402f57fe5b6001600160a01b0390921660209283029190910190910152600101613ffa565b8060031415613899576140646137c48461488f565b63ffffffff166060850152600191505b600101613edd565b80516001600160a01b03166142a65760005b8160200151518110156142a0576000826040015182815181106140ad57fe5b60200260200101516001600160a01b0316612710846020015184815181106140d157fe5b60209081029190910101516040516000818181858888f193505050503d8060008114614119576040519150601f19603f3d011682016040523d82523d6000602084013e61411e565b606091505b50509050806141e1577f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e83600001518460400151848151811061415d57fe5b60200260200101518560200151858151811061417557fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a1614297565b7fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a83600001518460400151848151811061421757fe5b60200260200101518560200151858151811061422f57fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b5060010161408e565b506144fd565b60005b8160200151518110156144fb57600082600001516001600160a01b031663a9059cbb61c350856040015185815181106142de57fe5b6020026020010151866020015186815181106142f657fe5b60200260200101516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b15801561434d57600080fd5b5087f1158015614361573d6000803e3d6000fd5b50505050506040513d602081101561437857600080fd5b50519050801561443c577fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a8360000151846040015184815181106143b857fe5b6020026020010151856020015185815181106143d057fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a16144f2565b7f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e83600001518460400151848151811061447257fe5b60200260200101518560200151858151811061448a57fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b506001016142a9565b505b50565b6000818361454f5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613d46578181015183820152602001613d2e565b5082848161455957fe5b06949350505050565b61456a6150bc565b60006145746150bc565b61457c61519b565b61458861379a866147ff565b90506000805b6145978361486e565b156138a657806145b4576145ad6137c48461488f565b84526147be565b80600114156145dc576145c96137e58461488f565b6001600160a01b031660208501526147be565b806002141561466b5760606145f3613f238561488f565b90508051604051908082528060200260200182016040528015614620578160200160208202803683370190505b50604086015260005b815181101561466457614641828281518110613f7657fe5b8660400151828151811061465157fe5b6020908102919091010152600101614629565b50506147be565b8060031415614700576060614682613f238561488f565b905080516040519080825280602002602001820160405280156146af578160200160208202803683370190505b50606086015260005b8151811015614664576146d082828151811061401257fe5b866060015182815181106146e057fe5b6001600160a01b03909216602092830291909101909101526001016146b8565b8060041415614795576060614717613f238561488f565b90508051604051908082528060200260200182016040528015614744578160200160208202803683370190505b50608086015260005b81518110156146645761476582828151811061401257fe5b8660800151828151811061477557fe5b6001600160a01b039092166020928302919091019091015260010161474d565b8060051415613899576147aa6137c48461488f565b67ffffffffffffffff1660a0850152600191505b60010161458e565b600060088211156147e857613466836007198401600a0a63ffffffff61305016565b611c99836008849003600a0a63ffffffff61300e16565b6148076151bb565b506040805180820190915281518152602082810190820152919050565b61482c61519b565b61483582614e9a565b61483e57600080fd5b600061484d8360200151614eca565b60208085015160408051808201909152868152920190820152915050919050565b60006148786151bb565b505080518051602091820151919092015191011190565b6148976151bb565b6148a08261486e565b6148a957600080fd5b602082015160006148b982614f2d565b80830160209586015260408051808201909152908152938401919091525090919050565b8051600090158015906148f257508151602110155b6148fb57600080fd5b600061490a8360200151614eca565b90508083600001511015614965576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b82516020808501518301805192849003929183101561498b57826020036101000a820491505b50949350505050565b80516000906015146149a557600080fd5b611c9c826148dd565b600080805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f8541580156149e75750600554155b15614a295760008052600660205269021e19e0c9bab24000007f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f85561a8c06005555b6020808301516001600160a01b0316600090815260069091526040902054801580614a575750808360400151105b15614a665760009150506111e9565b6020808401516001600160a01b039081166000908152600783526040808220606088015190931682529190925290819020908401518154614aac9163ffffffff612fb416565b8155600554420160018201819055606085015160208087015160408089015181519081529283019490945283516001600160a01b039384169493909116927f3fb83143cd331170da18fb1e8564d97e8ec39264b6ecb1ba248ea7596ab07258928290030190a35060019392505050565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416614b6057506018614b84565b6fffffffffffffffffffffffffffffffff198416614b8057506010614b84565b5060005b6020811015614bba57818181518110614b9957fe5b01602001516001600160f81b03191615614bb257614bba565b600101614b84565b60008160200390506060816040519080825280601f01601f191660200182016040528015614bef576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015614c345750607f60f81b82600081518110614c2257fe5b01602001516001600160f81b03191611155b15614c405750806111e9565b611c9c614c528351608060ff16614cd1565b835b6060806040519050835180825260208201818101602087015b81831015614c85578051835260209283019201614c6d565b50855184518101855292509050808201602086015b81831015614cb2578051835260209283019201614c9a565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310614d21576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411614d7b5782840160f81b81600081518110614d5d57fe5b60200101906001600160f81b031916908160001a9053509050611c9c565b6060614d8685614b1c565b90508381510160370160f81b82600081518110614d9f57fe5b60200101906001600160f81b031916908160001a905350614dc08282614c54565b95945050505050565b6060614dd482614e9a565b614ddd57600080fd5b6000614de883615060565b9050606081604051908082528060200260200182016040528015614e2657816020015b614e136151bb565b815260200190600190039081614e0b5790505b5090506000614e388560200151614eca565b60208601510190506000805b84811015614e8f57614e5583614f2d565b9150604051806040016040528083815260200184815250848281518110614e7857fe5b602090810291909101015291810191600101614e44565b509195945050505050565b8051600090614eab575060006111e9565b6020820151805160001a9060c0821015613580576000925050506111e9565b8051600090811a6080811015614ee45760009150506111e9565b60b8811080614eff575060c08110801590614eff575060f881105b15614f0e5760019150506111e9565b60c0811015614f225760b5190190506111e9565b60f5190190506111e9565b80516000908190811a6080811015614f485760019150615059565b60b8811015614f5d57607e1981019150615059565b60c0811015614fd757600060b78203600186019550806020036101000a865104915060018101820193505080831015614fd1576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b50615059565b60f8811015614fec5760be1981019150615059565b600060f78203600186019550806020036101000a865104915060018101820193505080831015615057576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b8051600090615071575060006111e9565b600080905060006150858460200151614eca565b602085015185519181019250015b808210156150b3576150a482614f2d565b60019093019290910190615093565b50909392505050565b6040518060c001604052806000801916815260200160006001600160a01b03168152602001606081526020016060815260200160608152602001600067ffffffffffffffff1681525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b60408051608081018252600080825260208201819052918101829052606081019190915290565b604051806080016040528060006001600160a01b031681526020016060815260200160608152602001600063ffffffff1681525090565b60405180604001604052806151ae6151bb565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe6f6e6c79207374616b696e672073797374656d20636f6e74726163742063616e2063616c6c20746869732066756e6374696f6e746865206d6573736167652073656e646572206d75737420626520696e63656e746976697a6520636f6e7472616374626e62206c61726765207472616e73666572206c696d697420746f6f20736d616c6c466f72206d696e69546f6b656e2c20746865207472616e7366657220616d6f756e74206d757374206e6f74206265206c657373207468616e2031756e7265636f676e697a6564207472616e736665724f75742073796e207061636b61676565787069726554696d65206d7573742062652074776f206d696e75746573206c61746572616d6f756e7420697320746f6f206c617267652c20657863656564206d6178696d756d206265703220746f6b656e20616d6f756e7474686520636f6e747261637420686173206e6f74206265656e20626f756e6420746f20616e79206265703220746f6b656e726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e736665724f757420424e4220616d6f756e7420616e64206d696e696d756d2072656c6179466565616d6f756e7420697320746f6f206c617267652c2075696e74323536206f766572666c6f774c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620726566756e644164647273696e76616c6964207472616e7366657220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e20746865206d696e696d756d2072656c6179466565746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374756e7265636f676e697a6564207472616e736665724f75742061636b207061636b6167654c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620616d6f756e7473746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d73672073656e646572206d75737420626520746f6b656e4d616e6167657274686520636f6e7472616374206e6f7420696e69742079657400000000000000726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e7366657220424e4220616d6f756e7420616e642072656c6179466565696e76616c696420726563656976656420424e4220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6ea2646970667358221220b559cd4e3125714f2f5ec5e81bc7a26f9ea28156afc15d661cb954c3ea9a53d864736f6c63430006040033", + }, + { + ContractAddr: CrossChainContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/78e13b1d3a5a1b08c9208af94a9b14fc1efda213", + Code: "608060405234801561001057600080fd5b50600436106103995760003560e01c8063718a8aa8116101e9578063c27cdcfb1161010f578063dc927faf116100ad578063f7a251d71161007c578063f7a251d714610b2f578063f9a2bbc714610ba7578063fc3e590814610baf578063fd6a687914610bb757610399565b8063dc927faf14610af7578063e1c7392a14610aff578063e3b0480514610b07578063e6400bbe14610b2757610399565b8063ccc108d7116100e9578063ccc108d714610ab0578063d31f968d14610ab8578063d76a867514610ae7578063dc40433114610aef57610399565b8063c27cdcfb14610a80578063c780e9de14610aa0578063c81b166214610aa857610399565b80638cc8f56111610187578063a78abc1611610156578063a78abc16146109b2578063ab51bb96146109ba578063ac431751146109c2578063b0355f5b1461078157610399565b80638cc8f5611461088757806396713da91461099a5780639dc09262146109a2578063a1a11bf5146109aa57610399565b806375d47a0a116101c357806375d47a0a146108a75780637942fd05146108af57806384013b6a146108b7578063863fe4ab1461099257610399565b8063718a8aa81461088f578063719482d51461089757806374f079b81461089f57610399565b8063422f9050116102ce57806363e1394e1161026c5780636de380bd1161023b5780636de380bd146108575780636e47a51a1461085f5780636e47b4821461087f57806370fd5bad1461088757610399565b806363e1394e146107ff5780636a3cb34d146108075780636bacff2c1461080f5780636c46aa681461080757610399565b80634bf6c882116102a85780634bf6c882146107b957806351e80672146107c15780635692ddd3146107c95780635f832177146107d157610399565b8063422f90501461078957806343756e5c146107a9578063493279b1146107b157610399565b8063299b533d1161033b578063308325f411610315578063308325f4146106155780633a648b151461061d5780633bdc47a6146106595780633dffc3871461078157610399565b8063299b533d146105a35780632af6f399146105d75780632ff32aea146105f457610399565b806314b3023b1161037757806314b3023b146104015780631d1309351461041b5780631e275ae11461043757806322556cdc1461059b57610399565b806305e682581461039e5780630bee7a67146103bc5780630e2374a5146103dd575b600080fd5b6103a6610bbf565b6040805160ff9092168252519081900360200190f35b6103c4610bc4565b6040805163ffffffff9092168252519081900360200190f35b6103e5610bc9565b604080516001600160a01b039092168252519081900360200190f35b610409610bcf565b60408051918252519081900360200190f35b610423610bd5565b604080519115158252519081900360200190f35b610599600480360361010081101561044e57600080fd5b81018160a081016080820135600160201b81111561046b57600080fd5b82018360208201111561047d57600080fd5b803590602001918460018302840111600160201b8311171561049e57600080fd5b919390929091602081019035600160201b8111156104bb57600080fd5b8201836020820111156104cd57600080fd5b803590602001918460018302840111600160201b831117156104ee57600080fd5b919390929091602081019035600160201b81111561050b57600080fd5b82018360208201111561051d57600080fd5b803590602001918460018302840111600160201b8311171561053e57600080fd5b919390929091602081019035600160201b81111561055b57600080fd5b82018360208201111561056d57600080fd5b803590602001918460018302840111600160201b8311171561058e57600080fd5b509092509050610bde565b005b6104096112c2565b6105c0600480360360208110156105b957600080fd5b50356112c7565b6040805161ffff9092168252519081900360200190f35b610423600480360360208110156105ed57600080fd5b50356112dd565b6105fc6112f2565b60408051600792830b90920b8252519081900360200190f35b6104096112fb565b61063d6004803603602081101561063357600080fd5b503560ff16611301565b604080516001600160401b039092168252519081900360200190f35b61070c6004803603606081101561066f57600080fd5b60ff82351691602081013591810190606081016040820135600160201b81111561069857600080fd5b8201836020820111156106aa57600080fd5b803590602001918460018302840111600160201b831117156106cb57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061131c945050505050565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561074657818101518382015260200161072e565b50505050905090810190601f1680156107735780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103a6611392565b6104236004803603602081101561079f57600080fd5b503560ff16611397565b6103e56113ac565b6105c06113b2565b6103a66113b7565b6103e56113bc565b6104096113c2565b610599600480360360408110156107e757600080fd5b506001600160a01b03813581169160200135166113f2565b610409611652565b6105c061167a565b61082c6004803603602081101561082557600080fd5b503561167f565b6040805161ffff90941684526001600160801b03909216602084015282820152519081900360600190f35b6104096116ae565b6103e56004803603602081101561087557600080fd5b503560ff166116d5565b6103e56116f0565b6103a661167a565b6103a66116f6565b6105c0611392565b6104096116fb565b6103e5611701565b6103a6611707565b610599600480360360a08110156108cd57600080fd5b810190602081018135600160201b8111156108e757600080fd5b8201836020820111156108f957600080fd5b803590602001918460018302840111600160201b8311171561091a57600080fd5b919390929091602081019035600160201b81111561093757600080fd5b82018360208201111561094957600080fd5b803590602001918460018302840111600160201b8311171561096a57600080fd5b919350915080356001600160401b03908116916020810135909116906040013560ff1661170c565b610409612a36565b6103a6612a3e565b6103e5612a43565b6103e5612a49565b610423612a4f565b6103c4610bbf565b610599600480360360408110156109d857600080fd5b810190602081018135600160201b8111156109f257600080fd5b820183602082011115610a0457600080fd5b803590602001918460018302840111600160201b83111715610a2557600080fd5b919390929091602081019035600160201b811115610a4257600080fd5b820183602082011115610a5457600080fd5b803590602001918460018302840111600160201b83111715610a7557600080fd5b509092509050612a58565b61063d60048036036020811015610a9657600080fd5b503560ff1661351c565b610409613537565b6103e561355b565b610599613561565b61042360048036036040811015610ace57600080fd5b5080356001600160a01b0316906020013560ff166137b5565b61070c6137d5565b6104096137f4565b6103e56137fa565b610599613800565b61063d60048036036020811015610b1d57600080fd5b503560ff16613bb7565b610599613bd2565b61059960048036036060811015610b4557600080fd5b60ff8235169190810190604081016020820135600160201b811115610b6957600080fd5b820183602082011115610b7b57600080fd5b803590602001918460018302840111600160201b83111715610b9c57600080fd5b919350915035613df1565b6103e5613f34565b6103a6613f3a565b6103e5613f3f565b600081565b606481565b61200181565b60015481565b600b5460ff1681565b60005460ff16610c23576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4c833981519152604482015290519081900360640190fd5b604080516337d7f9c160e21b81526001600160401b038b35166004820181905291516110039163df5fe704916024808301926020929190829003018186803b158015610c6e57600080fd5b505afa158015610c82573d6000803e3d6000fd5b505050506040513d6020811015610c9857600080fd5b5051610cd55760405162461bcd60e51b8152600401808060200182810382526023815260200180614a6c6023913960400191505060405180910390fd5b604080516337d7f9c160e21b815260208c8101356001600160401b03166004830181905292516110039263df5fe704926024808301939192829003018186803b158015610d2157600080fd5b505afa158015610d35573d6000803e3d6000fd5b505050506040513d6020811015610d4b57600080fd5b5051610d885760405162461bcd60e51b8152600401808060200182810382526023815260200180614a6c6023913960400191505060405180910390fd5b60608b013560ff81166000908152600560205260409020546001600160401b03909116906001600160a01b0316610e01576040805162461bcd60e51b815260206004820152601860248201527718da185b9b995b081a5cc81b9bdd081cdd5c1c1bdc9d195960421b604482015290519081900360640190fd5b600b5460ff1615610e45576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b8888604051808383808284376040519201829003822094508f93508e9250819050838380828437808301925050509250505060405180910390201415610ec1576040805162461bcd60e51b815260206004820152600c60248201526b1cd85b59481c185e5b1bd85960a21b604482015290519081900360640190fd5b60606001600160401b0360408e01358116908e83013516610ee28282613f45565b80516020808301919091206000818152600e9092526040909120549194509060ff1615610f4b576040805162461bcd60e51b8152602060048201526012602482015271185b1c9958591e4818da185b1b195b99d95960721b604482015290519081900360640190fd5b6000908152600e60205260408120805460ff191660011790558f8160200201356001600160401b0316905060608f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040805163cba510a960e01b81526001600160401b038a16600482015290519596509094611003945063cba510a9935060248083019350602092829003018186803b15801561104157600080fd5b505afa158015611055573d6000803e3d6000fd5b505050506040513d602081101561106b57600080fd5b505160408051808201909152600381526269626360e81b6020820152909150611098908290898686613f8d565b6110e1576040805162461bcd60e51b81526020600482015260156024820152740696e76616c6964206d65726b6c652070726f6f663605c1b604482015290519081900360640190fd5b5050505060008f6001600481106110f457fe5b60200201356001600160401b0316905060608d8d8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8f018190048102820181019092528d815293945060609392508d91508c908190840183828082843760009201829052506040805163cba510a960e01b81526001600160401b038a16600482015290519596509094611003945063cba510a9935060248083019350602092829003018186803b1580156111c057600080fd5b505afa1580156111d4573d6000803e3d6000fd5b505050506040513d60208110156111ea57600080fd5b505160408051808201909152600381526269626360e81b6020820152909150611217908290898686613f8d565b611260576040805162461bcd60e51b8152602060048201526015602482015274696e76616c6964206d65726b6c652070726f6f663160581b604482015290519081900360640190fd5b5050505061126c61408a565b604080516001600160401b038416815260ff83166020820152815133927f039eb91179ffd7d3b6e97f8ea106e748e827f910b872375dbc9c14a362319c3c928290030190a2505050505050505050505050505050565b603281565b600d6020526000908152604090205461ffff1681565b600e6020526000908152604090205460ff1681565b60045460070b81565b60025481565b600a602052600090815260409020546001600160401b031681565b60606000825160210190506060816040519080825280601f01601f191660200182016040528015611354576020820181803683370190505b506021810186905260018101879052828152905060418101600061137786614108565b50905061138681838851614112565b50909695505050505050565b600181565b60096020526000908152604090205460ff1681565b61100181565b603881565b600881565b61200081565b604080517710d05390d15317d514905394d1915497d41493d413d4d05360421b8152905190819003601801902081565b60005460ff16611437576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4c833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b15801561147a57600080fd5b505afa15801561148e573d6000803e3d6000fd5b505050506040513d60208110156114a457600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b1580156114e557600080fd5b505afa1580156114f9573d6000803e3d6000fd5b505050506040513d602081101561150f57600080fd5b505190508061151c575060155b60008211801561152c5750808211155b61156b576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b604080516001600160a01b038087166020808401919091529086168284015282518083038401815260608301808552815191909201207710d05390d15317d514905394d1915497d41493d413d4d05360421b90915291519081900360780190206000906115d89083614153565b9050801561164a5760408051630911a2c160e11b81526001600160a01b03888116600483015287166024820152905161100491631223458291604480830192600092919082900301818387803b15801561163157600080fd5b505af1158015611645573d6000803e3d6000fd5b505050505b505050505050565b604080516f14d554d411539117d41493d413d4d05360821b8152905190819003601001902081565b600281565b600c602052600090815260409020805460019091015461ffff8216916201000090046001600160801b03169083565b604080516e149153d4115397d41493d413d4d053608a1b8152905190819003600f01902081565b6005602052600090815260409020546001600160a01b031681565b61100581565b601081565b60035481565b61100881565b600b81565b60005460ff16611751576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4c833981519152604482015290519081900360640190fd5b60408051630a83aaa960e31b815233600482015290516110069163541d5548916024808301926020929190829003018186803b15801561179057600080fd5b505afa1580156117a4573d6000803e3d6000fd5b505050506040513d60208110156117ba57600080fd5b505161180d576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b73b005741528b86f5952469d80a8614591e3c5b632331480611842575073446aa6e0dc65690403df3f127750da1322941f3e33145b61187d5760405162461bcd60e51b815260040180806020018281038252602a8152602001806149f0602a913960400191505060405180910390fd5b60ff8116600090815260086020526040902054829082906001600160401b0390811690831681146118ed576040805162461bcd60e51b815260206004820152601560248201527439b2b8bab2b731b2903737ba1034b71037b93232b960591b604482015290519081900360640190fd5b60ff8216600090815260086020908152604091829020805467ffffffffffffffff1916600185016001600160401b039081169190911790915582516337d7f9c160e21b81529089166004820152915188926110039263df5fe70492602480840193829003018186803b15801561196257600080fd5b505afa158015611976573d6000803e3d6000fd5b505050506040513d602081101561198c57600080fd5b50516119c95760405162461bcd60e51b8152600401808060200182810382526023815260200180614a6c6023913960400191505060405180910390fd5b60ff851660009081526005602052604090205485906001600160a01b0316611a33576040805162461bcd60e51b815260206004820152601860248201527718da185b9b995b081a5cc81b9bdd081cdd5c1c1bdc9d195960421b604482015290519081900360640190fd5b60ff86166000908152600a6020526040902054889087906001600160401b039081169083161015611a9c576040805162461bcd60e51b815260206004820152600e60248201526d3a37b79037b632103432b0b232b960911b604482015290519081900360640190fd5b60ff81166000908152600a60205260409020546001600160401b03838116911614611aee5760ff81166000908152600a60205260409020805467ffffffffffffffff19166001600160401b0384161790555b600b5460ff1615611b32576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b60608e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509050611c766110036001600160a01b031663cba510a98e6040518263ffffffff1660e01b815260040180826001600160401b03166001600160401b0316815260200191505060206040518083038186803b158015611c1f57600080fd5b505afa158015611c33573d6000803e3d6000fd5b505050506040513d6020811015611c4957600080fd5b505160408051808201909152600381526269626360e81b6020820152611c6f8e8e613f45565b8585613f8d565b611cbe576040805162461bcd60e51b815260206004820152601460248201527334b73b30b634b21036b2b935b63290383937b7b360611b604482015290519081900360640190fd5b60408051631bb5062960e31b81526001600160401b038e16600482015290516000916110039163dda8314891602480820192602092909190829003018186803b158015611d0a57600080fd5b505afa158015611d1e573d6000803e3d6000fd5b505050506040513d6020811015611d3457600080fd5b505190508b8b600080806060611d4989614438565b935093509350935083611e0b578460ff16866001600160401b03167ff7b2e42d694eb1100184aae86d4245d9e46966100b1dc7e723275b98326854ac8b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611dc3578181015183820152602001611dab565b50505050905090810190601f168015611df05780820380516001836020036101000a031916815260200191505b509250505060405180910390a3505050505050505050612a26565b6040805160ff85811682529151918716916001600160401b038916917f36afdaf439a8f43fe72135135d804ae620b37a474f0943b5b85f6788312cad40919081900360200190a360ff83166123905760ff85166000818152600560209081526040808320548151631182b87560e01b815260048101958652602481019283528651604482015286516001600160a01b03909216958695631182b875958d958a9593949093606490910192918601918190849084905b83811015611ed8578181015183820152602001611ec0565b50505050905090810190601f168015611f055780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015611f2557600080fd5b505af192505050801561200957506040513d6000823e601f3d908101601f191682016040526020811015611f5857600080fd5b8101908080516040519392919084600160201b821115611f7757600080fd5b908301906020820185811115611f8c57600080fd5b8251600160201b811182820188101715611fa557600080fd5b82525081516020918201929091019080838360005b83811015611fd2578181015183820152602001611fba565b50505050905090810190601f168015611fff5780820380516001836020036101000a031916815260200191505b5060405250505060015b61231b576040516000815260443d1015612025575060006120c0565b60046000803e60005160e01c6308c379a081146120465760009150506120c0565b60043d036004833e81513d60248201116001600160401b0382111715612071576000925050506120c0565b80830180516001600160401b038111156120925760009450505050506120c0565b8060208301013d86018111156120b0576000955050505050506120c0565b601f01601f191660405250925050505b806120cb57506121dd565b60ff8716600090815260076020526040812054612102916001600160401b039091169089906120fd906002908861131c565b6144e8565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf948794849390840192918601918190849084905b8381101561219d578181015183820152602001612185565b50505050905090810190601f1680156121ca5780820380516001836020036101000a031916815260200191505b509250505060405180910390a250612316565b3d808015612207576040519150601f19603f3d011682016040523d82523d6000602084013e61220c565b606091505b5060ff871660009081526007602052604081205461223f916001600160401b039091169089906120fd906002908861131c565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351948794849390840192918601918190849084905b838110156122da5781810151838201526020016122c2565b50505050905090810190601f1680156123075780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b61238a565b8051156123885760ff8716600090815260076020526040812054612354916001600160401b039091169089906120fd906001908661131c565b60ff8716600090815260076020526040902080546001600160401b038082166001011667ffffffffffffffff199091161790555b505b5061295e565b60ff8316600114156126345760ff8516600081815260056020908152604080832054815163831d65d160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563831d65d1958d958a9593949093606490910192918601918190849084905b8381101561241a578181015183820152602001612402565b50505050905090810190601f1680156124475780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561246757600080fd5b505af1925050508015612478575060015b61238a576040516000815260443d10156124945750600061252f565b60046000803e60005160e01c6308c379a081146124b557600091505061252f565b60043d036004833e81513d60248201116001600160401b03821117156124e05760009250505061252f565b80830180516001600160401b0381111561250157600094505050505061252f565b8060208301013d860181111561251f5760009550505050505061252f565b601f01601f191660405250925050505b8061253a575061259f565b60408051602080825283518183015283516001600160a01b038616937ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf938693909283928301918501908083836000831561219d578181015183820152602001612185565b3d8080156125c9576040519150601f19603f3d011682016040523d82523d6000602084013e6125ce565b606091505b5060408051602080825283518183015283516001600160a01b038616937f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd297735193869390928392830191850190808383600083156122da5781810151838201526020016122c2565b60ff83166002141561295e5760ff8516600081815260056020908152604080832054815163c8509d8160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563c8509d81958d958a9593949093606490910192918601918190849084905b838110156126be5781810151838201526020016126a6565b50505050905090810190601f1680156126eb5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561270b57600080fd5b505af192505050801561271c575060015b61295c576040516000815260443d1015612738575060006127d3565b60046000803e60005160e01c6308c379a081146127595760009150506127d3565b60043d036004833e81513d60248201116001600160401b0382111715612784576000925050506127d3565b80830180516001600160401b038111156127a55760009450505050506127d3565b8060208301013d86018111156127c3576000955050505050506127d3565b601f01601f191660405250925050505b806127de5750612887565b816001600160a01b03167ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf826040518080602001828103825283818151815260200191508051906020019080838360005b8381101561284757818101518382015260200161282f565b50505050905090810190601f1680156128745780820380516001836020036101000a031916815260200191505b509250505060405180910390a25061295c565b3d8080156128b1576040519150601f19603f3d011682016040523d82523d6000602084013e6128b6565b606091505b50816001600160a01b03167f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351826040518080602001828103825283818151815260200191508051906020019080838360005b83811015612920578181015183820152602001612908565b50505050905090810190601f16801561294d5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b505b60ff80861660009081526009602052604090205461100591636f93d2e6918a91339187911680612990575060ff881615155b604080516001600160e01b031960e088901b1681526001600160a01b039586166004820152939094166024840152604483019190915215156064820152905160848083019260209291908290030181600087803b1580156129f057600080fd5b505af1158015612a04573d6000803e3d6000fd5b505050506040513d6020811015612a1a57600080fd5b50505050505050505050505b5050505050505050505050505050565b630100380081565b600981565b61100781565b61100681565b60005460ff1681565b3361100714612a985760405162461bcd60e51b815260040180806020018281038252602e815260200180614978602e913960400191505060405180910390fd5b600b5460ff1615612adc576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b612b4584848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526012815271626174636853697a65466f724f7261636c6560701b602082015291506146829050565b15612be057604080516020601f8401819004810282018101909252828152600091612b889185858083850183828082843760009201919091525061476992505050565b90506127108111158015612b9d5750600a8110155b612bd85760405162461bcd60e51b8152600401808060200182810382526032815260200180614a1a6032913960400191505060405180910390fd5b60015561348a565b612c4984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601281527118591913dc955c19185d1950da185b9b995b60721b602082015291506146829050565b15612dd157606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060169091149050612ccc5760405162461bcd60e51b815260040180806020018281038252605a815260200180614891605a913960600191505060405180910390fd5b60018101516002820151601683015160ff82161590612cea8161476e565b612d3b576040805162461bcd60e51b815260206004820152601960248201527f61646472657373206973206e6f74206120636f6e747261637400000000000000604482015290519081900360640190fd5b60ff8416600081815260056020908152604080832080546001600160a01b0319166001600160a01b038716908117909155808452600683528184208585528352818420805460ff199081166001179091556009909352818420805490931687151517909255519092917f7e3b6af43092577ee20e60eaa1d9b114a7031305c895ee7dd3ffe17196d2e1e091a3505050505061348a565b612e3e84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526016815275195b98589b1953dc911a5cd8589b1950da185b9b995b60521b602082015291506146829050565b15612f6f57606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060029091149050612ec15760405162461bcd60e51b815260040180806020018281038252604a8152602001806149a6604a913960600191505060405180910390fd5b600181810151600283015160ff80831660009081526005602052604090205492939192908316909114906001600160a01b03168015612f65576001600160a01b038116600090815260066020908152604080832060ff881680855290835292819020805460ff1916861515908117909155815190815290517fa3132e3f9819fbddc7f0ed6d38d7feef59aa95112090b7c592f5cb5bc4aa4adc929181900390910190a25b505050505061348a565b612fd384848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c73757370656e6451756f72756d60981b602082015291506146829050565b1561310857600281146130175760405162461bcd60e51b815260040180806020018281038252602d81526020018061491f602d913960400191505060405180910390fd5b600061305a600284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061476992505050565b905060008161ffff16118015613074575060648161ffff16105b6130be576040805162461bcd60e51b8152602060048201526016602482015275696e76616c69642073757370656e642071756f72756d60501b604482015290519081900360640190fd5b604080516f14d554d411539117d41493d413d4d05360821b815281519081900360100190206000908152600d60205220805461ffff90921661ffff1990921691909117905561348a565b61316b84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600c81526b72656f70656e51756f72756d60a01b602082015291506146829050565b1561329e57600281146131af5760405162461bcd60e51b815260040180806020018281038252602c81526020018061494c602c913960400191505060405180910390fd5b60006131f2600284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061476992505050565b905060008161ffff1611801561320c575060648161ffff16105b613255576040805162461bcd60e51b8152602060048201526015602482015274696e76616c69642072656f70656e2071756f72756d60581b604482015290519081900360640190fd5b604080516e149153d4115397d41493d413d4d053608a1b8152815190819003600f0190206000908152600d60205220805461ffff90921661ffff1990921691909117905561348a565b61330984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601481527363616e63656c5472616e7366657251756f72756d60601b602082015291506146829050565b1561344d576002811461334d5760405162461bcd60e51b81526004018080602001828103825260348152602001806148eb6034913960400191505060405180910390fd5b6000613390600284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061476992505050565b905060008161ffff161180156133aa575060648161ffff16105b6133fb576040805162461bcd60e51b815260206004820152601e60248201527f696e76616c69642063616e63656c207472616e736665722071756f72756d0000604482015290519081900360640190fd5b604080517710d05390d15317d514905394d1915497d41493d413d4d05360421b815281519081900360180190206000908152600d60205220805461ffff90921661ffff1990921691909117905561348a565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b6008602052600090815260409020546001600160401b031681565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081565b61100281565b60005460ff166135a6576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4c833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b1580156135e957600080fd5b505afa1580156135fd573d6000803e3d6000fd5b505050506040513d602081101561361357600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b15801561365457600080fd5b505afa158015613668573d6000803e3d6000fd5b505050506040513d602081101561367e57600080fd5b505190508061368b575060155b60008211801561369b5750808211155b6136da576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b600b5460ff16613721576040805162461bcd60e51b815260206004820152600d60248201526c1b9bdd081cdd5cdc195b991959609a1b604482015290519081900360640190fd5b604080516e149153d4115397d41493d413d4d053608a1b8152905190819003600f019020600090613772907fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470614153565b905080156137b057600b805460ff1916905560405133907f899fe8c37dc61708a3aaa99c4bf143346c1d1da69af79be9e8920c0a6785b75290600090a25b505050565b600660209081526000928352604080842090915290825290205460ff1681565b6040518060400160405280600381526020016269626360e81b81525081565b610e1081565b61100381565b60005460ff1615613858576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b7f1471eb6eb2c5e789fc3de43f8ce62938c7d1836ec861730447e2ada8fd81017b80546001600160a01b0319908116611008179091557f92e85d02570a8092d09a6e3a57665bc3815a2699a4074001bf1ccabf660f5a36805460ff199081169091557fd8af288fc1c8680b4f4706064cf021e264efb6828fcaf7eb5ca36818eb365bcc8054821660019081179091557f89832631fb3c3307a103ba2c84ab569c64d6182a18893dcd163f0f1c2090733a805484166110049081179091557f6cde3cea4b3a3fb2488b2808bae7556f4a405e50f65e1794383bc026131b13c38054841690557f72e4efa1513b071517c6c74dba31b5934a81aa83cddd400e7081df5529c9943680548416831790557fa9bc9a3a348c357ba16b37005d7e6b3236198c0e939f4af8c5f19b8deeb8ebc08054851690911790557fc575c31fea594a6eb97c8e9d3f9caee4c16218c6ef37e923234c0fe9014a61e78054831690557f4e523af77f034e9810f1c94057f5e931fb3d16a51511a4c3add793617d18610580548316821790557ffb33122aa9f93cc639ebe80a7bc4784c11e6053dde89c6f4f7e268c6a623da1e805484166110001790557fc7694af312c4f286114180fd0ba6a52461fcee8a381636770b19a343af92538a80548316821790557f01112dd68e482ba8d68a7e828cff8b3abcea08eab88941953c180a7e650e9cd480548316821790557fc0a4a8be475dfebc377ebef2d7c4ff47656f572a08dd92b81017efcdba0febe1805484166110071790557f87e8a52529e8ece4ef759037313542a6429ff494a9fab9027fb79db90124eba680548316821790557f4c7666bbcb22d46469f7cc282f70764a7012dca2cce630ff8d83db9a9cdd48f080548316821790557f40f28f99a40bc9f6beea1013afdbc3cdcc689eb76b82c4de06c0acf1e1932ed58054909316611001179092557f0d9cf2cd531699eed8dd34e40ff2884a14a698c4898184fba85194e6f6772d248054821683179055600b60009081527f23f68c9bd22b8a93d06adabe17481c87c016bcbd20adc8bfd707a4d813a572176020527fdf0d5d05428057f5455c2dc8e810dd86d1e9350faa72f16bda8a45443c5b39328054831684179055603283556004805467ffffffffffffffff19166001600160401b031790556002819055600381905580549091169091179055565b6007602052600090815260409020546001600160401b031681565b60005460ff16613c17576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4c833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b158015613c5a57600080fd5b505afa158015613c6e573d6000803e3d6000fd5b505050506040513d6020811015613c8457600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b158015613cc557600080fd5b505afa158015613cd9573d6000803e3d6000fd5b505050506040513d6020811015613cef57600080fd5b5051905080613cfc575060155b600082118015613d0c5750808211155b613d4b576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b600b5460ff1615613d8f576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b604080516f14d554d411539117d41493d413d4d05360821b81529051908190036010019020600090613de1907fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470614153565b905080156137b0576137b061408a565b60005460ff16613e36576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4c833981519152604482015290519081900360640190fd5b33600090815260066020908152604080832060ff8089168552925290912054859116613e935760405162461bcd60e51b81526004018080602001828103825260318152602001806148606031913960400191505060405180910390fd5b60ff85166000908152600760209081526040808320548151601f88018490048402810184019092528682526001600160401b031692613ef89284928a926120fd92909189918c908c908190840183828082843760009201919091525061131c92505050565b60ff959095166000908152600760205260409020805467ffffffffffffffff191660019096016001600160401b03169590951790945550505050565b61100081565b600381565b61100481565b60408051600e808252818301909252606091630100380060ff851617918391602082018180368337505050600e81810187905260068201939093529182525090505b92915050565b600085613f9c57506000614081565b606082518451865160800101016040519080825280601f01601f191660200182016040528015613fd3576020820181803683370190505b5090506000613fe182614774565b602080890151825201905086600080613ff989614108565b8086526020909501949092509050614012828583614112565b9283019261401f88614108565b8086526020909501949092509050614038828583614112565b9283018a81526020019261404b87614108565b909250905061405b828583614112565b50835160200161406961477a565b60208183886065600019fa5051600114955050505050505b95945050505050565b600b5460ff16156140ce576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b600b805460ff1916600117905560405133907f6f123d3d54c84a7960a573b31c221dcd86e13fd849c5adb0c6ca851468cc1ae490600090a2565b8051602090910191565b5b60208110614132578251825260209283019290910190601f1901614113565b915181516020939093036101000a6000190180199091169216919091179052565b6000828152600d602052604081205461ffff1661421c57604080516f14d554d411539117d41493d413d4d05360821b815281519081900360100181206000908152600d6020818152848320805461ffff199081166001179091556e149153d4115397d41493d413d4d053608a1b8552855194859003600f01852084528282528584208054821660029081179091557710d05390d15317d514905394d1915497d41493d413d4d05360421b8652865195869003601801909520845291905292902080549092161790555b6000838152600c6020526040902080546201000090046001600160801b03164210158061424d575082816001015414155b15614320576000848152600d602090815260409182902054835461ffff90911661ffff199091161771ffffffffffffffffffffffffffffffff0000191662010000610e1042016001600160801b031602178355600180840186905582519182019092523381526142c291600284019190614798565b5080546040805161ffff83168152620100009092046001600160801b0316602083015281810185905251339186917f9e109f0e55ef32e99e4880be2ec357f1ddb3469c79d0747ef4762da6e89fabe5916060908290030190a36143d4565b60005b60028201548110156143ab57336001600160a01b031682600201828154811061434857fe5b6000918252602090912001546001600160a01b031614156143a3576040805162461bcd60e51b815260206004820152601060248201526f185b1c9958591e48185c1c1c9bdd995960821b604482015290519081900360640190fd5b600101614323565b50600281018054600181018255600091825260209091200180546001600160a01b031916331790555b8054600282015461ffff9091161161442e576000848152600c60205260408120805471ffffffffffffffffffffffffffffffffffff19168155600181018290559061442260028301826147fd565b50506001915050613f87565b5060009392505050565b600080600060606021855110156144685750506040805160008082526020820190925290925082915081906144e1565b600185015160218601518651604080516020198301808252601f19600119909401939093168101602001909152604189019392916060919080156144b3576020820181803683370190505b50905060006144c182614108565b5090506144d3858260218d5103614112565b506001975091955093509150505b9193509193565b600b5460ff161561452c576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b60025443111561456b576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b1617909155600355436002556145ac565b600380546001908101918290555410156145ac576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003555b8160ff16836001600160401b0316600460009054906101000a900460070b6001600160401b03167f3a6e0fc61675aa2a100bcba0568368bb92bcec91c97673391074f11138f0cffe603885604051808361ffff1661ffff16815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561464257818101518382015260200161462a565b50505050905090810190601f16801561466f5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a4505050565b6000816040516020018082805190602001908083835b602083106146b75780518252601f199092019160209182019101614698565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106147255780518252601f199092019160209182019101614706565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b3b151590565b60200190565b60405180602001604052806001906020820280368337509192915050565b8280548282559060005260206000209081019282156147ed579160200282015b828111156147ed57825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906147b8565b506147f992915061481e565b5090565b508054600082559060005260206000209081019061481b9190614845565b50565b61484291905b808211156147f95780546001600160a01b0319168155600101614824565b90565b61484291905b808211156147f9576000815560010161484b56fe74686520636f6e747261637420616e64206368616e6e656c2068617665206e6f74206265656e20726567697374657265646c656e677468206f662076616c756520666f72206164644f725570646174654368616e6e656c2073686f756c642062652032322c206368616e6e656c49643a697346726f6d53797374656d3a68616e646c6572416464726573736c656e677468206f662076616c756520666f722063616e63656c5472616e7366657251756f72756d2073686f756c6420626520326c656e677468206f662076616c756520666f722073757370656e6451756f72756d2073686f756c6420626520326c656e677468206f662076616c756520666f722072656f70656e51756f72756d2073686f756c642062652032746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f7220656e61626c654f7244697361626c654368616e6e656c2073686f756c6420626520322c206368616e6e656c49643a6973456e61626c65746865206d73672073656e646572206973206e6f7420612077686974656c6162656c2072656c61796572746865206e6577426174636853697a65466f724f7261636c652073686f756c6420626520696e205b31302c2031303030305d74686520636f6e7472616374206e6f7420696e697420796574000000000000006c6967687420636c69656e74206e6f742073796e632074686520626c6f636b20796574a264697066735822122041ff13fe956e0a3b951862bdc1d377a102e361a8960c89b2a595749204aba3ed64736f6c63430006040033", + }, + }, + } + + PlanckUpgrade[networkname.ChapelChainName] = &Upgrade{ + UpgradeName: "planck", + Configs: []*UpgradeConfig{ + { + ContractAddr: SlashContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/78e13b1d3a5a1b08c9208af94a9b14fc1efda213", + Code: "608060405234801561001057600080fd5b50600436106102535760003560e01c80637942fd0511610146578063ac431751116100c3578063dc927faf11610087578063dc927faf1461073b578063e1c7392a14610743578063f9a2bbc71461074b578063fc3e590814610753578063fc4333cd1461075b578063fd6a68791461076357610253565b8063ac431751146105cf578063c80d4b8f1461068d578063c81b166214610695578063c8509d811461069d578063c96be4cb1461071557610253565b80639dc092621161010a5780639dc0926214610593578063a1a11bf51461059b578063a78abc16146105a3578063ab51bb96146105bf578063ac0af629146105c757610253565b80637942fd05146104fb5780638256ace614610503578063831d65d11461050b57806396713da9146105835780639bc8e4f21461058b57610253565b80634bf6c882116101d45780636e47b482116101985780636e47b482146104d357806370fd5bad146104db578063718a8aa8146104e357806375d47a0a146104eb5780637912a65d146104f357610253565b80634bf6c8821461048b57806351e8067214610493578063567a372d1461049b5780635bfb4990146104a357806362b72cf5146104cb57610253565b806337c8dab91161021b57806337c8dab9146103ed578063389f4f711461042c5780633dffc3871461044657806343756e5c14610464578063493279b11461046c57610253565b80630bee7a67146102585780630e2374a5146102795780631182b8751461029d57806323bac5a21461038a57806335aa2e44146103d0575b600080fd5b61026061076b565b6040805163ffffffff9092168252519081900360200190f35b610281610770565b604080516001600160a01b039092168252519081900360200190f35b610315600480360360408110156102b357600080fd5b60ff8235169190810190604081016020820135600160201b8111156102d757600080fd5b8201836020820111156102e957600080fd5b803590602001918460018302840111600160201b8311171561030a57600080fd5b509092509050610776565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561034f578181015183820152602001610337565b50505050905090810190601f16801561037c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103b0600480360360208110156103a057600080fd5b50356001600160a01b031661084a565b604080519384526020840192909252151582820152519081900360600190f35b610281600480360360208110156103e657600080fd5b503561086d565b6104136004803603602081101561040357600080fd5b50356001600160a01b0316610894565b6040805192835260208301919091528051918290030190f35b6104346108eb565b60408051918252519081900360200190f35b61044e6108f1565b6040805160ff9092168252519081900360200190f35b6102816108f6565b6104746108fc565b6040805161ffff9092168252519081900360200190f35b61044e610901565b610281610906565b61043461090c565b6104c9600480360360208110156104b957600080fd5b50356001600160a01b0316610912565b005b610434610a73565b610281610a79565b61044e610a7f565b61044e610a84565b610281610a89565b610434610a8f565b61044e610a94565b610413610a99565b6104c96004803603604081101561052157600080fd5b60ff8235169190810190604081016020820135600160201b81111561054557600080fd5b82018360208201111561055757600080fd5b803590602001918460018302840111600160201b8311171561057857600080fd5b509092509050610aa3565b61044e610bfd565b610434610c02565b610281610c0d565b610281610c13565b6105ab610c19565b604080519115158252519081900360200190f35b610260610c22565b610434610c27565b6104c9600480360360408110156105e557600080fd5b810190602081018135600160201b8111156105ff57600080fd5b82018360208201111561061157600080fd5b803590602001918460018302840111600160201b8311171561063257600080fd5b919390929091602081019035600160201b81111561064f57600080fd5b82018360208201111561066157600080fd5b803590602001918460018302840111600160201b8311171561068257600080fd5b509092509050610c2c565b61043461101a565b61028161101f565b6104c9600480360360408110156106b357600080fd5b60ff8235169190810190604081016020820135600160201b8111156106d757600080fd5b8201836020820111156106e957600080fd5b803590602001918460018302840111600160201b8311171561070a57600080fd5b509092509050611025565b6104c96004803603602081101561072b57600080fd5b50356001600160a01b03166110d8565b610281611659565b6104c961165f565b6102816116d0565b61044e6116d6565b6104c96116db565b610281611b66565b606481565b61200181565b606033612000146107b85760405162461bcd60e51b815260040180806020018281038252602f8152602001806125bd602f913960400191505060405180910390fd5b60005460ff166107fd576040805162461bcd60e51b81526020600482015260196024820152600080516020612619833981519152604482015290519081900360640190fd5b6040805162461bcd60e51b815260206004820152601e60248201527f7265636569766520756e65787065637465642073796e207061636b6167650000604482015290519081900360640190fd5b600260208190526000918252604090912080546001820154919092015460ff1683565b6001818154811061087a57fe5b6000918252602090912001546001600160a01b0316905081565b60008061089f612481565b5050506001600160a01b0316600090815260026020818152604092839020835160608101855281548082526001830154938201849052919093015460ff16151592909301919091529091565b60055481565b600181565b61100181565b606181565b600881565b61200081565b60045481565b33611000146109525760405162461bcd60e51b81526004018080602001828103825260308152602001806125186030913960400191505060405180910390fd5b60005460ff16610997576040805162461bcd60e51b81526020600482015260196024820152600080516020612619833981519152604482015290519081900360640190fd5b61200063f7a251d7600b6109aa84611b6c565b60006040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015610a0a5781810151838201526020016109f2565b50505050905090810190601f168015610a375780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015610a5857600080fd5b505af1158015610a6c573d6000803e3d6000fd5b5050505050565b60035481565b61100581565b600281565b601081565b61100881565b603281565b600b81565b6004546005549091565b3361200014610ae35760405162461bcd60e51b815260040180806020018281038252602f8152602001806125bd602f913960400191505060405180910390fd5b60005460ff16610b28576040805162461bcd60e51b81526020600482015260196024820152600080516020612619833981519152604482015290519081900360640190fd5b610b306124a4565b6000610b7184848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c3e92505050565b915091508015610bbb5781516040805163ffffffff9092168252517f7f0956d47419b9525356e7111652b653b530ec6f5096dccc04589bc38e6299679181900360200190a1610a6c565b81516040805163ffffffff9092168252517f7d45f62d17443dd4547bca8a8112c60e2385669318dc300ec61a5d2492f262e79181900360200190a15050505050565b600981565b662386f26fc1000081565b61100781565b61100681565b60005460ff1681565b600081565b600481565b60005460ff16610c71576040805162461bcd60e51b81526020600482015260196024820152600080516020612619833981519152604482015290519081900360640190fd5b3361100714610cb15760405162461bcd60e51b815260040180806020018281038252602e815260200180612548602e913960400191505060405180910390fd5b610d1c84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260148152731b5a5cd9195b59585b9bdc951a1c995cda1bdb1960621b60208201529150611cbe9050565b15610df55760208114610d605760405162461bcd60e51b81526004018080602001828103825260278152602001806124f16027913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610d9e91858580838501838280828437600092019190915250611da692505050565b905060018110158015610db2575060055481105b610ded5760405162461bcd60e51b81526004018080602001828103825260258152602001806125986025913960400191505060405180910390fd5b600455610f88565b610e5b84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e19995b1bdb9e551a1c995cda1bdb19608a1b60208201529150611cbe9050565b15610f4b5760208114610e9f5760405162461bcd60e51b81526004018080602001828103825260228152602001806125766022913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610edd91858580838501838280828437600092019190915250611da692505050565b90506103e88111158015610ef2575060045481115b610f43576040805162461bcd60e51b815260206004820181905260248201527f7468652066656c6f6e795468726573686f6c64206f7574206f662072616e6765604482015290519081900360640190fd5b600555610f88565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b609681565b61100281565b33612000146110655760405162461bcd60e51b815260040180806020018281038252602f8152602001806125bd602f913960400191505060405180910390fd5b60005460ff166110aa576040805162461bcd60e51b81526020600482015260196024820152600080516020612619833981519152604482015290519081900360640190fd5b6040517f07db600eebe2ac176be8dcebad61858c245a4961bb32ca2aa3d159b09aa0810e90600090a1505050565b3341146111165760405162461bcd60e51b815260040180806020018281038252602d8152602001806125ec602d913960400191505060405180910390fd5b60005460ff1661115b576040805162461bcd60e51b81526020600482015260196024820152600080516020612619833981519152604482015290519081900360640190fd5b60035443116111b1576040805162461bcd60e51b815260206004820181905260248201527f63616e206e6f7420736c61736820747769636520696e206f6e6520626c6f636b604482015290519081900360640190fd5b3a156111fb576040805162461bcd60e51b81526020600482015260146024820152736761737072696365206973206e6f74207a65726f60601b604482015290519081900360640190fd5b6040805163155853f360e21b81526001600160a01b03831660048201529051611000916355614fcc916024808301926020929190829003018186803b15801561124357600080fd5b505afa158015611257573d6000803e3d6000fd5b505050506040513d602081101561126d57600080fd5b505161127857611652565b611280612481565b506001600160a01b0381166000908152600260208181526040928390208351606081018552815481526001820154928101929092529091015460ff1615801592820192909252906112db576020810180516001019052611334565b60016040820181905260208201819052805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0384161790555b43815260055460208201518161134657fe5b0661157657600060208201819052604080516335409f7f60e01b81526001600160a01b03851660048201529051611000926335409f7f926024808201939182900301818387803b15801561139957600080fd5b505af11580156113ad573d6000803e3d6000fd5b505050506120006001600160a01b031663f7a251d7600b6113cd85611b6c565b60006040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561142d578181015183820152602001611415565b50505050905090810190601f16801561145a5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561147b57600080fd5b505af192505050801561148c575060015b611571573d8080156114ba576040519150601f19603f3d011682016040523d82523d6000602084013e6114bf565b606091505b50826001600160a01b03167fd7bc86ff5d08c8ab043edec743302aba2520e6635172a428bc956721db9e2d1c8360200151836040518083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561153457818101518382015260200161151c565b50505050905090810190601f1680156115615780820380516001836020036101000a031916815260200191505b50935050505060405180910390a2505b6115ec565b60045481602001518161158557fe5b066115ec57604080516375abf10160e11b81526001600160a01b038416600482015290516110009163eb57e20291602480830192600092919082900301818387803b1580156115d357600080fd5b505af11580156115e7573d6000803e3d6000fd5b505050505b6001600160a01b0382166000818152600260208181526040808420865181559186015160018301558581015191909201805460ff1916911515919091179055517fddb6012116e51abf5436d956a4f0ebd927e92c576ff96d7918290c8782291e3e9190a2505b5043600355565b61100381565b60005460ff16156116b7576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b603260045560966005556000805460ff19166001179055565b61100081565b600381565b336110001461171b5760405162461bcd60e51b81526004018080602001828103825260308152602001806125186030913960400191505060405180910390fd5b60005460ff16611760576040805162461bcd60e51b81526020600482015260196024820152600080516020612619833981519152604482015290519081900360640190fd5b60015461176c57611b64565b600154600090600019015b808211611b38576000805b8284101561189b57611792612481565b60026000600187815481106117a357fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff1615159082015260055490915060049004816020015111156118855760046005548161181057fe5b0481602001510381602001818152505080600260006001888154811061183257fe5b6000918252602080832091909101546001600160a01b0316835282810193909352604091820190208351815591830151600183015591909101516002909101805460ff191691151591909117905561188f565b600192505061189b565b50600190930192611782565b828411611a32576118aa612481565b60026000600186815481106118bb57fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff1615159082015260055490915060049004816020015111156119a35760046005548161192857fe5b0481602001510381602001818152505080600260006001878154811061194a57fe5b6000918252602080832091909101546001600160a01b03168352828101939093526040918201902083518155918301516001808401919091559201516002909101805460ff19169115159190911790559150611a329050565b60026000600186815481106119b457fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff191690558054806119f857fe5b600082815260209020810160001990810180546001600160a01b031916905501905583611a255750611a32565b506000199092019161189b565b818015611a3c5750805b15611b1b576002600060018681548110611a5257fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff19169055805484908110611a9957fe5b600091825260209091200154600180546001600160a01b039092169186908110611abf57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506001805480611af857fe5b600082815260209020810160001990810180546001600160a01b03191690550190555b82611b27575050611b38565b505060019091019060001901611777565b6040517fcfdb3b6ccaeccbdc68be3c59c840e3b3c90f0a7c491f5fff1cf56cfda200dd9c90600090a150505b565b61100481565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081611b87579050509050611bb0836001600160a01b0316611dab565b81600081518110611bbd57fe5b6020026020010181905250611bd143611dce565b81600181518110611bde57fe5b6020908102919091010152611bf36061611dce565b81600281518110611c0057fe5b6020026020010181905250611c1442611dce565b81600381518110611c2157fe5b6020026020010181905250611c3581611de1565b9150505b919050565b611c466124a4565b6000611c506124a4565b611c586124b6565b611c69611c6486611e6b565b611e90565b90506000805b611c7883611eda565b15611cb15780611ca457611c93611c8e84611efb565b611f49565b63ffffffff16845260019150611ca9565b611cb1565b600101611c6f565b5091935090915050915091565b6000816040516020018082805190602001908083835b60208310611cf35780518252601f199092019160209182019101611cd4565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310611d615780518252601f199092019160209182019101611d42565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490505b92915050565b015190565b60408051600560a21b8318601482015260348101909152606090611c3581612000565b6060611da0611ddc83612056565b612000565b6060815160001415611e025750604080516000815260208101909152611c39565b606082600081518110611e1157fe5b602002602001015190506000600190505b8351811015611e5257611e4882858381518110611e3b57fe5b602002602001015161213c565b9150600101611e22565b50611c35611e65825160c060ff166121b9565b8261213c565b611e736124d6565b506040805180820190915281518152602082810190820152919050565b611e986124b6565b611ea1826122b1565b611eaa57600080fd5b6000611eb983602001516122eb565b60208085015160408051808201909152868152920190820152915050919050565b6000611ee46124d6565b505080518051602091820151919092015191011190565b611f036124d6565b611f0c82611eda565b611f1557600080fd5b60208201516000611f258261234e565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590611f5e57508151602110155b611f6757600080fd5b6000611f7683602001516122eb565b90508083600001511015611fd1576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b825160208085015183018051928490039291831015611ff757826020036101000a820491505b50949350505050565b6060815160011480156120325750607f60f81b8260008151811061202057fe5b01602001516001600160f81b03191611155b1561203e575080611c39565b611da06120508351608060ff166121b9565b8361213c565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff19841661209a575060186120be565b6fffffffffffffffffffffffffffffffff1984166120ba575060106120be565b5060005b60208110156120f4578181815181106120d357fe5b01602001516001600160f81b031916156120ec576120f4565b6001016120be565b60008160200390506060816040519080825280601f01601f191660200182016040528015612129576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b8183101561216d578051835260209283019201612155565b50855184518101855292509050808201602086015b8183101561219a578051835260209283019201612182565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310612209576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b604080516001808252818301909252606091602082018180368337019050509050603784116122635782840160f81b8160008151811061224557fe5b60200101906001600160f81b031916908160001a9053509050611da0565b606061226e85612056565b90508381510160370160f81b8260008151811061228757fe5b60200101906001600160f81b031916908160001a9053506122a8828261213c565b95945050505050565b80516000906122c257506000611c39565b6020820151805160001a9060c08210156122e157600092505050611c39565b5060019392505050565b8051600090811a6080811015612305576000915050611c39565b60b8811080612320575060c08110801590612320575060f881105b1561232f576001915050611c39565b60c08110156123435760b519019050611c39565b60f519019050611c39565b80516000908190811a6080811015612369576001915061247a565b60b881101561237e57607e198101915061247a565b60c08110156123f857600060b78203600186019550806020036101000a8651049150600181018201935050808310156123f2576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b5061247a565b60f881101561240d5760be198101915061247a565b600060f78203600186019550806020036101000a865104915060018101820193505080831015612478576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b604051806060016040528060008152602001600081526020016000151581525090565b60408051602081019091526000815290565b60405180604001604052806124c96124d6565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe6c656e677468206f66206d697364656d65616e6f725468726573686f6c64206d69736d61746368746865206d6573736167652073656e646572206d7573742062652076616c696461746f7253657420636f6e7472616374746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662066656c6f6e795468726573686f6c64206d69736d61746368746865206d697364656d65616e6f725468726573686f6c64206f7574206f662072616e6765746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d6573736167652073656e646572206d7573742062652074686520626c6f636b2070726f647563657274686520636f6e7472616374206e6f7420696e69742079657400000000000000a264697066735822122073e63503ac4253c326fb17904c6564f8471e21693509513fe7dc5277fcd239a364736f6c63430006040033", + }, + { + ContractAddr: TokenHubContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/78e13b1d3a5a1b08c9208af94a9b14fc1efda213", + Code: "6080604052600436106103c75760003560e01c806396713da9116101f2578063c81b16621161010d578063f0148472116100a0578063fc1a598f1161006f578063fc1a598f14610f25578063fc3e590814610b85578063fd6a687914610f58578063ff9c0027146107fd5761040f565b8063f014847214610ed1578063f9a2bbc714610ee6578063fa9e915914610efb578063fb063e8f14610f105761040f565b8063dc927faf116100dc578063dc927faf14610e5f578063e1c7392a14610e74578063e8f35cea14610e89578063ebf71d5314610ebc5761040f565b8063c81b166214610d8a578063c8509d8114610d9f578063cf41984414610e24578063d9e6dae91461077f5761040f565b8063aa7415f511610185578063b9fd21e311610154578063b9fd21e314610cfa578063ba35ead614610d0f578063bbface1f14610d24578063bd46646114610d575761040f565b8063aa7415f514610b9a578063ab51bb9614610be1578063ac43175114610bf6578063b99328c514610cc15761040f565b8063a1a11bf5116101c1578063a1a11bf514610b46578063a496fba214610b5b578063a78abc1614610b70578063a7c9f02d14610b855761040f565b806396713da914610ace5780639a854bbd14610ae35780639a99b4f014610af85780639dc0926214610b315761040f565b806359b92789116102e257806371d3086311610275578063831d65d111610244578063831d65d1146109d15780638b87b21f146106d45780638eff336c14610a565780639509b98014610a955761040f565b806371d3086314610968578063727be1f81461097d57806375d47a0a146109a75780637942fd05146109bc5761040f565b80636e056520116102b15780636e056520146108125780636e47b4821461093e57806370fd5bad146107fd578063718a8aa8146109535761040f565b806359b92789146107be5780635d499b1b146107e8578063613684751461077f57806366dea52a146107fd5761040f565b80633fd8b02f1161035a5780634a3acdf4116103295780634a3acdf41461076a5780634bf6c8821461077f57806350432d321461079457806351e80672146107a95761040f565b80633fd8b02f146106ff57806343756e5c1461071457806343a368b914610729578063493279b11461073e5761040f565b8063149d14d911610396578063149d14d9146105a85780632ae45483146105cf5780633d713223146106235780633dffc387146106d45761040f565b80630bee7a67146104145780630e2374a5146104425780631182b87514610473578063122345821461056d5761040f565b3661040f57341561040d576040805133815234602082015281517f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db929181900390910190a15b005b600080fd5b34801561042057600080fd5b50610429610f6d565b6040805163ffffffff9092168252519081900360200190f35b34801561044e57600080fd5b50610457610f72565b604080516001600160a01b039092168252519081900360200190f35b34801561047f57600080fd5b506104f86004803603604081101561049657600080fd5b60ff8235169190810190604081016020820135600160201b8111156104ba57600080fd5b8201836020820111156104cc57600080fd5b803590602001918460018302840111600160201b831117156104ed57600080fd5b509092509050610f78565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561053257818101518382015260200161051a565b50505050905090810190601f16801561055f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561057957600080fd5b5061040d6004803603604081101561059057600080fd5b506001600160a01b03813581169160200135166110a6565b3480156105b457600080fd5b506105bd6111a0565b60408051918252519081900360200190f35b3480156105db57600080fd5b5061060a600480360360408110156105f257600080fd5b506001600160a01b03813581169160200135166111a6565b6040805192835260208301919091528051918290030190f35b34801561062f57600080fd5b506104576004803603602081101561064657600080fd5b810190602081018135600160201b81111561066057600080fd5b82018360208201111561067257600080fd5b803590602001918460018302840111600160201b8311171561069357600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506111ca945050505050565b3480156106e057600080fd5b506106e96111ee565b6040805160ff9092168252519081900360200190f35b34801561070b57600080fd5b506105bd6111f3565b34801561072057600080fd5b506104576111f9565b34801561073557600080fd5b506105bd6111ff565b34801561074a57600080fd5b5061075361120b565b6040805161ffff9092168252519081900360200190f35b34801561077657600080fd5b506105bd611210565b34801561078b57600080fd5b506106e9611216565b3480156107a057600080fd5b506105bd61121b565b3480156107b557600080fd5b50610457611226565b3480156107ca57600080fd5b50610457600480360360208110156107e157600080fd5b503561122c565b3480156107f457600080fd5b506105bd611247565b34801561080957600080fd5b506106e9611250565b61092a6004803603608081101561082857600080fd5b810190602081018135600160201b81111561084257600080fd5b82018360208201111561085457600080fd5b803590602001918460208302840111600160201b8311171561087557600080fd5b919390929091602081019035600160201b81111561089257600080fd5b8201836020820111156108a457600080fd5b803590602001918460208302840111600160201b831117156108c557600080fd5b919390929091602081019035600160201b8111156108e257600080fd5b8201836020820111156108f457600080fd5b803590602001918460208302840111600160201b8311171561091557600080fd5b91935091503567ffffffffffffffff16611255565b604080519115158252519081900360200190f35b34801561094a57600080fd5b5061045761172a565b34801561095f57600080fd5b506106e9611730565b34801561097457600080fd5b506105bd611735565b34801561098957600080fd5b5061092a600480360360208110156109a057600080fd5b503561173b565b3480156109b357600080fd5b506104576117bc565b3480156109c857600080fd5b506106e96117c2565b3480156109dd57600080fd5b5061040d600480360360408110156109f457600080fd5b60ff8235169190810190604081016020820135600160201b811115610a1857600080fd5b820183602082011115610a2a57600080fd5b803590602001918460018302840111600160201b83111715610a4b57600080fd5b5090925090506117c7565b348015610a6257600080fd5b5061040d60048036036060811015610a7957600080fd5b508035906001600160a01b036020820135169060400135611910565b348015610aa157600080fd5b5061040d60048036036040811015610ab857600080fd5b506001600160a01b038135169060200135611996565b348015610ada57600080fd5b506106e9611b53565b348015610aef57600080fd5b506105bd611b58565b348015610b0457600080fd5b506105bd60048036036040811015610b1b57600080fd5b506001600160a01b038135169060200135611b64565b348015610b3d57600080fd5b50610457611ca2565b348015610b5257600080fd5b50610457611ca8565b348015610b6757600080fd5b506106e9611cae565b348015610b7c57600080fd5b5061092a611cb3565b348015610b9157600080fd5b506106e9611cbc565b61092a60048036036080811015610bb057600080fd5b5080356001600160a01b03908116916020810135909116906040810135906060013567ffffffffffffffff16611cc1565b348015610bed57600080fd5b50610429611cae565b348015610c0257600080fd5b5061040d60048036036040811015610c1957600080fd5b810190602081018135600160201b811115610c3357600080fd5b820183602082011115610c4557600080fd5b803590602001918460018302840111600160201b83111715610c6657600080fd5b919390929091602081019035600160201b811115610c8357600080fd5b820183602082011115610c9557600080fd5b803590602001918460018302840111600160201b83111715610cb657600080fd5b509092509050612382565b348015610ccd57600080fd5b5061040d60048036036040811015610ce457600080fd5b50803590602001356001600160a01b031661282a565b348015610d0657600080fd5b506105bd6128a0565b348015610d1b57600080fd5b506105bd6128aa565b348015610d3057600080fd5b506105bd60048036036020811015610d4757600080fd5b50356001600160a01b03166128b0565b348015610d6357600080fd5b506105bd60048036036020811015610d7a57600080fd5b50356001600160a01b03166128c2565b348015610d9657600080fd5b506104576128dd565b348015610dab57600080fd5b5061040d60048036036040811015610dc257600080fd5b60ff8235169190810190604081016020820135600160201b811115610de657600080fd5b820183602082011115610df857600080fd5b803590602001918460018302840111600160201b83111715610e1957600080fd5b5090925090506128e3565b348015610e3057600080fd5b5061040d60048036036040811015610e4757600080fd5b506001600160a01b03813581169160200135166129b3565b348015610e6b57600080fd5b50610457612c87565b348015610e8057600080fd5b5061040d612c8d565b348015610e9557600080fd5b506105bd60048036036020811015610eac57600080fd5b50356001600160a01b0316612d2d565b348015610ec857600080fd5b506106e9612d3f565b348015610edd57600080fd5b506106e9612d44565b348015610ef257600080fd5b50610457612d49565b348015610f0757600080fd5b506105bd612d4f565b348015610f1c57600080fd5b506105bd612d55565b348015610f3157600080fd5b506104f860048036036020811015610f4857600080fd5b50356001600160a01b0316612d63565b348015610f6457600080fd5b50610457612e8a565b606481565b61200181565b60005460609060ff16610fc0576040805162461bcd60e51b81526020600482015260196024820152600080516020615582833981519152604482015290519081900360640190fd5b33612000146110005760405162461bcd60e51b815260040180806020018281038252602f815260200180615530602f913960400191505060405180910390fd5b60ff8416600214156110525761104b83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612e9092505050565b905061109f565b6040805162461bcd60e51b815260206004820152601860248201527f756e7265636f676e697a65642073796e207061636b6167650000000000000000604482015290519081900360640190fd5b9392505050565b33612000146110e65760405162461bcd60e51b815260040180806020018281038252602f815260200180615530602f913960400191505060405180910390fd5b6001600160a01b0380831660009081526007602090815260408083209385168352929052208054611151576040805162461bcd60e51b815260206004820152601060248201526f1b9bc81b1bd8dad95908185b5bdd5b9d60821b604482015290519081900360640190fd5b8054600082556040805182815290516001600160a01b0380861692908716917f152fb15aa5d80f843e1e4bd5f2fc9161714f169945024decec7e84fb910fdd519181900360200190a350505050565b60015490565b60076020908152600092835260408084209091529082529020805460019091015482565b6020818101516000908152600490915260409020546001600160a01b03165b919050565b600181565b60055481565b61100181565b670de0b6b3a764000081565b606181565b61a8c081565b600881565b66071afd498d000081565b61200081565b6000908152600460205260409020546001600160a01b031690565b6402540be40081565b600281565b6000805460ff1661129b576040805162461bcd60e51b81526020600482015260196024820152600080516020615582833981519152604482015290519081900360640190fd5b8685146112d95760405162461bcd60e51b815260040180806020018281038252603b8152602001806154f5603b913960400191505060405180910390fd5b8683146113175760405162461bcd60e51b815260040180806020018281038252603f8152602001806153c8603f913960400191505060405180910390fd5b426078018267ffffffffffffffff1610156113635760405162461bcd60e51b81526004018080602001828103825260248152602001806152b86024913960400191505060405180910390fd5b6402540be4003406156113a75760405162461bcd60e51b81526004018080602001828103825260408152602001806155f86040913960400191505060405180910390fd5b604080518681526020808802820101909152859060009081906060908480156113da578160200160208202803683370190505b50905060005b848110156114b5576402540be4008b8b838181106113fa57fe5b905060200201358161140857fe5b06156114455760405162461bcd60e51b815260040180806020018281038252603c815260200180615407603c913960400191505060405180910390fd5b61146a8b8b8381811061145457fe5b9050602002013585612fb490919063ffffffff16565b93506114966402540be4008c8c8481811061148157fe5b9050602002013561300e90919063ffffffff16565b8282815181106114a257fe5b60209081029190910101526001016113e0565b506001546114da906114cd908663ffffffff61305016565b849063ffffffff612fb416565b3410156115185760405162461bcd60e51b81526004018080602001828103825260568152602001806155a26056913960600191505060405180910390fd5b611528348463ffffffff6130a916565b91506115326150bc565b6040518060c001604052806221272160e91b60001b815260200160006001600160a01b031681526020018381526020018e8e808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050908252506040805160208c810282810182019093528c82529283019290918d918d91829185019084908082843760009201919091525050509082525067ffffffffffffffff8916602090910152905061200063f7a251d760036115f6846130eb565b61160b876402540be40063ffffffff61300e16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611669578181015183820152602001611651565b50505050905090810190601f1680156116965780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156116b757600080fd5b505af11580156116cb573d6000803e3d6000fd5b505060408051600081523360208201528082018890526060810187905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9350908190036080019150a15060019c9b505050505050505050505050565b61100581565b601081565b60015481565b6000336120011461177d5760405162461bcd60e51b81526004018080602001828103825260338152602001806151d66033913960400191505060405180910390fd5b81156117b4576040516120019083156108fc029084906000818181858888f193505050501580156117b2573d6000803e3d6000fd5b505b506001919050565b61100881565b600b81565b60005460ff1661180c576040805162461bcd60e51b81526020600482015260196024820152600080516020615582833981519152604482015290519081900360640190fd5b336120001461184c5760405162461bcd60e51b815260040180806020018281038252602f815260200180615530602f913960400191505060405180910390fd5b60ff83166003141561189c5761189782828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506133a692505050565b61190b565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a15b505050565b33611008146119505760405162461bcd60e51b815260040180806020018281038252602381526020018061555f6023913960400191505060405180910390fd5b600083815260046020908152604080832080546001600160a01b039096166001600160a01b03199096168617905593825260038152838220949094556002909352912055565b81806001600160a01b031663893d20e86040518163ffffffff1660e01b815260040160206040518083038186803b1580156119d057600080fd5b505afa1580156119e4573d6000803e3d6000fd5b505050506040513d60208110156119fa57600080fd5b50516001600160a01b03163314611a58576040805162461bcd60e51b815260206004820152601860248201527f6e6f74206f776e6572206f6620424550323020746f6b656e0000000000000000604482015290519081900360640190fd5b60008211611aa6576040805162461bcd60e51b81526020600482015260166024820152751e995c9bc81b1a5b5a5d081b9bdd08185b1b1bddd95960521b604482015290519081900360640190fd5b6001600160a01b038316600090815260036020526040902054611afc576040805162461bcd60e51b81526020600482015260096024820152681b9bdd08189bdd5b9960ba1b604482015290519081900360640190fd5b6001600160a01b038316600081815260066020908152604091829020859055815185815291513393927f9df3a90730dbf23b5cc18dbbd5f4af3fa94a0dffb6ff6841f98a9a9a6ac626a892908290030190a3505050565b600981565b677ce66c50e284000081565b6000805460ff16611baa576040805162461bcd60e51b81526020600482015260196024820152600080516020615582833981519152604482015290519081900360640190fd5b3361100514611bea5760405162461bcd60e51b815260040180806020018281038252602f815260200180615209602f913960400191505060405180910390fd5b6000478310611bf95747611bfb565b825b9050670de0b6b3a7640000811115611c17576000915050611c9c565b8015611c99576040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015611c53573d6000803e3d6000fd5b50604080516001600160a01b03861681526020810183905281517ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0929181900390910190a15b90505b92915050565b61100781565b61100681565b600081565b60005460ff1681565b600381565b6000805460ff16611d07576040805162461bcd60e51b81526020600482015260196024820152600080516020615582833981519152604482015290519081900360640190fd5b426078018267ffffffffffffffff161015611d535760405162461bcd60e51b81526004018080602001828103825260248152602001806152b86024913960400191505060405180910390fd5b6402540be400340615611d975760405162461bcd60e51b81526004018080602001828103825260408152602001806155f86040913960400191505060405180910390fd5b600080806001600160a01b038816611e7657600154611dbd90879063ffffffff612fb416565b341015611dfb5760405162461bcd60e51b81526004018080602001828103825260618152602001806153426061913960800191505060405180910390fd5b6402540be400860615611e3f5760405162461bcd60e51b815260040180806020018281038252603c815260200180615407603c913960400191505060405180910390fd5b611e4f348763ffffffff6130a916565b9050611e66866402540be40063ffffffff61300e16565b6221272160e91b93509150612119565b6001600160a01b038816600090815260036020526040902054925082611ecd5760405162461bcd60e51b81526004018080602001828103825260318152602001806153116031913960400191505060405180910390fd5b600154341015611f0e5760405162461bcd60e51b815260040180806020018281038252603f815260200180615464603f913960400191505060405180910390fd5b506001600160a01b0387166000908152600260205260409020543490600881111580611f595750600881118015611f595750611f57876007198301600a0a63ffffffff61340216565b155b611f945760405162461bcd60e51b815260040180806020018281038252603c815260200180615407603c913960400191505060405180910390fd5b611f9e8782613444565b9250611fa984613484565b15611ff1576305f5e100831015611ff15760405162461bcd60e51b815260040180806020018281038252603a81526020018061525a603a913960400191505060405180910390fd5b60088110158061200b575060088110801561200b57508683115b6120465760405162461bcd60e51b81526004018080602001828103825260258152602001806153a36025913960400191505060405180910390fd5b677ce66c50e284000083111561208d5760405162461bcd60e51b81526004018080602001828103825260358152602001806152dc6035913960400191505060405180910390fd5b604080516323b872dd60e01b81523360048201523060248201526044810189905290516001600160a01b038b16916323b872dd9160648083019260209291908290030181600087803b1580156120e257600080fd5b505af11580156120f6573d6000803e3d6000fd5b505050506040513d602081101561210c57600080fd5b505161211757600080fd5b505b6121216150bc565b6040805160c0810182528581526001600160a01b038b166020820152815160018082528184018452919283019181602001602082028036833750505081526040805160018082528183019092526020928301929091908083019080368337505050815260408051600180825281830190925260209283019290919080830190803683370190505081526020018767ffffffffffffffff1681525090508281604001516000815181106121cf57fe5b6020026020010181815250508781606001516000815181106121ed57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505033816080015160008151811061221f57fe5b6001600160a01b039092166020928302919091019091015261200063f7a251d7600361224a846130eb565b61225f866402540be40063ffffffff61300e16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156122bd5781810151838201526020016122a5565b50505050905090810190601f1680156122ea5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561230b57600080fd5b505af115801561231f573d6000803e3d6000fd5b5050604080516001600160a01b038d1681523360208201528082018b90526060810186905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9350908190036080019150a150600198975050505050505050565b33611007146123c25760405162461bcd60e51b815260040180806020018281038252602e8152602001806154a3602e913960400191505060405180910390fd5b60208114612417576040805162461bcd60e51b815260206004820152601b60248201527f65787065637465642076616c7565206c656e6774682069732033320000000000604482015290519081900360640190fd5b606084848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8801819004810282018101909252868152939450606093925086915085908190840183828082843760009201919091525050505060208301519091506772656c617946656560c01b81141561251f576020820151670de0b6b3a764000081118015906124c657506402540be4008106155b612517576040805162461bcd60e51b815260206004820152601960248201527f7468652072656c6179466565206f7574206f662072616e676500000000000000604482015290519081900360640190fd5b600155612795565b61259387878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601781527f6c617267655472616e736665724c6f636b506572696f640000000000000000006020820152915061358a9050565b1561262f57604080516020601f87018190048102820181019092528581526000916125d69188888083850183828082843760009201919091525061367192505050565b905062093a80811115612627576040805162461bcd60e51b81526020600482015260146024820152736c6f636b20706572696f6420746f6f206c6f6e6760601b604482015290519081900360640190fd5b600555612795565b61269b87878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526015815274189b9893185c99d9551c985b9cd9995c931a5b5a5d605a1b6020820152915061358a9050565b1561275857604080516020601f87018190048102820181019092528581526000916126de9188888083850183828082843760009201919091525061367192505050565b905068056bc75e2d631000008110156127285760405162461bcd60e51b81526004018080602001828103825260228152602001806152386022913960400191505060405180910390fd5b6000805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f855612795565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a878787876040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050505050565b336110081461286a5760405162461bcd60e51b815260040180806020018281038252602381526020018061555f6023913960400191505060405180910390fd5b600091825260046020908152604080842080546001600160a01b03191690556001600160a01b0392909216835260039052812055565b6221272160e91b81565b61c35081565b60026020526000908152604090205481565b6001600160a01b031660009081526003602052604090205490565b61100281565b60005460ff16612928576040805162461bcd60e51b81526020600482015260196024820152600080516020615582833981519152604482015290519081900360640190fd5b33612000146129685760405162461bcd60e51b815260040180806020018281038252602f815260200180615530602f913960400191505060405180910390fd5b60ff83166003141561189c5761189782828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061367692505050565b60085460ff16600214156129ff576040805162461bcd60e51b815260206004820152600e60248201526d4e6f2072652d656e7472616e637960901b604482015290519081900360640190fd5b6008805460ff191660021790556001600160a01b0380831660009081526007602090815260408083209385168352929052208054612a77576040805162461bcd60e51b815260206004820152601060248201526f1b9bc81b1bd8dad95908185b5bdd5b9d60821b604482015290519081900360640190fd5b8060010154421015612ad0576040805162461bcd60e51b815260206004820152601760248201527f7374696c6c206f6e206c6f636b696e6720706572696f64000000000000000000604482015290519081900360640190fd5b805460008083556001600160a01b038516612b43576040516001600160a01b038516906127109084906000818181858888f193505050503d8060008114612b33576040519150601f19603f3d011682016040523d82523d6000602084013e612b38565b606091505b505080915050612bd6565b846001600160a01b031663a9059cbb61c35086856040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b158015612ba657600080fd5b5087f1158015612bba573d6000803e3d6000fd5b50505050506040513d6020811015612bd157600080fd5b505190505b80612c28576040805162461bcd60e51b815260206004820152601e60248201527f776974686472617720756e6c6f636b656420746f6b656e206661696c65640000604482015290519081900360640190fd5b836001600160a01b0316856001600160a01b03167f832fc3e25f2b3e6fb0eb59419a73cba405f2a249fce75f7e31ea5a457a0323f1846040518082815260200191505060405180910390a350506008805460ff19166001179055505050565b61100381565b60005460ff1615612ce5576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b66071afd498d000060019081556000808052600260205260127fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b55805460ff19169091179055565b60066020526000908152604090205481565b600481565b600581565b61100081565b61271081565b69021e19e0c9bab240000081565b6001600160a01b03811660009081526003602090815260409182902054825182815280840190935260609290918391906020820181803683375050506020810183905290506000805b60208160ff161015612df357828160ff1681518110612dc757fe5b01602001516001600160f81b03191615612de657600190910190612deb565b612df3565b600101612dac565b5060608160ff166040519080825280601f01601f191660200182016040528015612e24576020820181803683370190505b50905060005b8260ff168160ff161015612e8057838160ff1681518110612e4757fe5b602001015160f81c60f81b828260ff1681518110612e6157fe5b60200101906001600160f81b031916908160001a905350600101612e2a565b5095945050505050565b61100481565b6060612e9a615108565b6000612ea584613774565b9150915080612efb576040805162461bcd60e51b815260206004820152601f60248201527f756e7265636f676e697a6564207472616e73666572496e207061636b61676500604482015290519081900360640190fd5b6000612f06836138b3565b905063ffffffff811615612f9a576040808401516020808601516001600160a01b03166000908152600290915291822054612f419190613444565b9050612f4b61513d565b60405180608001604052808660000151815260200183815260200186608001516001600160a01b031681526020018463ffffffff168152509050612f8e81613c19565b955050505050506111e9565b505060408051600081526020810190915291506111e99050565b600082820183811015611c99576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000611c9983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613cf5565b60008261305f57506000611c9c565b8282028284828161306c57fe5b0414611c995760405162461bcd60e51b81526004018080602001828103825260218152602001806154436021913960400191505060405180910390fd5b6000611c9983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613d97565b60408051600680825260e08201909252606091829190816020015b6060815260200190600190039081613106575050835190915061312890613df1565b8160008151811061313557fe5b602002602001018190525061315683602001516001600160a01b0316613e04565b8160018151811061316357fe5b6020026020010181905250600083604001515190506060816040519080825280602002602001820160405280156131ae57816020015b60608152602001906001900390816131995790505b50905060005b828110156131fb576131dc866040015182815181106131cf57fe5b6020026020010151613df1565b8282815181106131e857fe5b60209081029190910101526001016131b4565b5061320581613e27565b8360028151811061321257fe5b602002602001018190525060608260405190808252806020026020018201604052801561325357816020015b606081526020019060019003908161323e5790505b50905060005b838110156132a95761328a8760600151828151811061327457fe5b60200260200101516001600160a01b0316613e04565b82828151811061329657fe5b6020908102919091010152600101613259565b506132b381613e27565b846003815181106132c057fe5b602002602001018190525060608360405190808252806020026020018201604052801561330157816020015b60608152602001906001900390816132ec5790505b50905060005b84811015613341576133228860800151828151811061327457fe5b82828151811061332e57fe5b6020908102919091010152600101613307565b5061334b81613e27565b8560048151811061335857fe5b602002602001018190525061337a8760a0015167ffffffffffffffff16613df1565b8560058151811061338757fe5b602002602001018190525061339b85613e27565b979650505050505050565b6133ae615164565b60006133b983613eb1565b91509150806133f95760405162461bcd60e51b81526004018080602001828103825260248152602001806154d16024913960400191505060405180910390fd5b61190b8261407c565b6000611c9983836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815250614500565b6000600882111561346d57613466836007198401600a0a63ffffffff61300e16565b9050611c9c565b611c99836008849003600a0a63ffffffff61305016565b604080516020808252818301909252600091606091906020820181803683375050506020810184905290506000805b60208160ff1610156134fa57828160ff16815181106134ce57fe5b01602001516001600160f81b031916156134ed576001909101906134f2565b6134fa565b6001016134b3565b50600760ff82161015613512576000925050506111e9565b816005820360ff168151811061352457fe5b6020910101516001600160f81b031916602d60f81b14613549576000925050506111e9565b816001820360ff168151811061355b57fe5b6020910101516001600160f81b031916604d60f81b14613580576000925050506111e9565b5060019392505050565b6000816040516020018082805190602001908083835b602083106135bf5780518252601f1990920191602091820191016135a0565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b6020831061362d5780518252601f19909201916020918201910161360e565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b61367e6150bc565b600061368983614562565b91509150806136c95760405162461bcd60e51b81526004018080602001828103825260248152602001806152946024913960400191505060405180910390fd5b6136d1615164565b602080840180516001600160a01b0390811684526040808701518585015291511660009081526002909252812054905b8460400151518110156137525761372f8560400151828151811061372157fe5b6020026020010151836147c6565b8560400151828151811061373f57fe5b6020908102919091010152600101613701565b50608084015160408301526005606083015261376d8261407c565b5050505050565b61377c615108565b6000613786615108565b61378e61519b565b61379f61379a866147ff565b614824565b90506000805b6137ae8361486e565b156138a657806137d0576137c96137c48461488f565b6148dd565b845261389e565b80600114156137fd576137ea6137e58461488f565b614994565b6001600160a01b0316602085015261389e565b806002141561381c576138126137c48461488f565b604085015261389e565b8060031415613844576138316137e58461488f565b6001600160a01b0316606085015261389e565b806004141561386c576138596137e58461488f565b6001600160a01b0316608085015261389e565b8060051415613899576138816137c48461488f565b67ffffffffffffffff1660a08501526001915061389e565b6138a6565b6001016137a5565b5091935090915050915091565b60208101516000906001600160a01b03166139f7578160a0015167ffffffffffffffff164211156138e6575060016111e9565b81604001514710156138fa575060036111e9565b613903826149ae565b61397857606082015160408084015190516000926001600160a01b0316916127109184818181858888f193505050503d806000811461395e576040519150601f19603f3d011682016040523d82523d6000602084013e613963565b606091505b50509050806139765750600490506111e9565b505b7f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5982602001518360600151846040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a15060006111e9565b8160a0015167ffffffffffffffff16421115613a15575060016111e9565b81516020808401516001600160a01b031660009081526003909152604090205414613a42575060026111e9565b602080830151604080516370a0823160e01b815230600482015290516000936001600160a01b03909316926370a082319261c3509260248083019392829003018187803b158015613a9257600080fd5b5086fa158015613aa6573d6000803e3d6000fd5b50505050506040513d6020811015613abd57600080fd5b50516040840151909150811015613ad85750600390506111e9565b613ae1836149ae565b613b9857600083602001516001600160a01b031663a9059cbb61c350866060015187604001516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b158015613b5657600080fd5b5087f1158015613b6a573d6000803e3d6000fd5b50505050506040513d6020811015613b8157600080fd5b5051905080613b965750600591506111e99050565b505b7f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5983602001518460600151856040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a150600090506111e9565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081613c345750508351909150613c5690613df1565b81600081518110613c6357fe5b6020026020010181905250613c7b8360200151613df1565b81600181518110613c8857fe5b6020026020010181905250613ca983604001516001600160a01b0316613e04565b81600281518110613cb657fe5b6020026020010181905250613cd4836060015163ffffffff16613df1565b81600381518110613ce157fe5b602002602001018190525061109f81613e27565b60008183613d815760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613d46578181015183820152602001613d2e565b50505050905090810190601f168015613d735780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581613d8d57fe5b0495945050505050565b60008184841115613de95760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613d46578181015183820152602001613d2e565b505050900390565b6060611c9c613dff83614b1c565b614c02565b60408051600560a21b831860148201526034810190915260609061109f81614c02565b6060815160001415613e4857506040805160008152602081019091526111e9565b606082600081518110613e5757fe5b602002602001015190506000600190505b8351811015613e9857613e8e82858381518110613e8157fe5b6020026020010151614c54565b9150600101613e68565b5061109f613eab825160c060ff16614cd1565b82614c54565b613eb9615164565b6000613ec3615164565b613ecb61519b565b613ed761379a866147ff565b90506000805b613ee68361486e565b156138a65780613f0c57613efc6137e58461488f565b6001600160a01b03168452614074565b8060011415613fad576060613f28613f238561488f565b614dc9565b90508051604051908082528060200260200182016040528015613f55578160200160208202803683370190505b50602086015260005b8151811015613fa657613f83828281518110613f7657fe5b60200260200101516148dd565b86602001518281518110613f9357fe5b6020908102919091010152600101613f5e565b5050614074565b806002141561404f576060613fc4613f238561488f565b90508051604051908082528060200260200182016040528015613ff1578160200160208202803683370190505b50604086015260005b8151811015613fa65761401f82828151811061401257fe5b6020026020010151614994565b8660400151828151811061402f57fe5b6001600160a01b0390921660209283029190910190910152600101613ffa565b8060031415613899576140646137c48461488f565b63ffffffff166060850152600191505b600101613edd565b80516001600160a01b03166142a65760005b8160200151518110156142a0576000826040015182815181106140ad57fe5b60200260200101516001600160a01b0316612710846020015184815181106140d157fe5b60209081029190910101516040516000818181858888f193505050503d8060008114614119576040519150601f19603f3d011682016040523d82523d6000602084013e61411e565b606091505b50509050806141e1577f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e83600001518460400151848151811061415d57fe5b60200260200101518560200151858151811061417557fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a1614297565b7fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a83600001518460400151848151811061421757fe5b60200260200101518560200151858151811061422f57fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b5060010161408e565b506144fd565b60005b8160200151518110156144fb57600082600001516001600160a01b031663a9059cbb61c350856040015185815181106142de57fe5b6020026020010151866020015186815181106142f657fe5b60200260200101516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b15801561434d57600080fd5b5087f1158015614361573d6000803e3d6000fd5b50505050506040513d602081101561437857600080fd5b50519050801561443c577fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a8360000151846040015184815181106143b857fe5b6020026020010151856020015185815181106143d057fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a16144f2565b7f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e83600001518460400151848151811061447257fe5b60200260200101518560200151858151811061448a57fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b506001016142a9565b505b50565b6000818361454f5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613d46578181015183820152602001613d2e565b5082848161455957fe5b06949350505050565b61456a6150bc565b60006145746150bc565b61457c61519b565b61458861379a866147ff565b90506000805b6145978361486e565b156138a657806145b4576145ad6137c48461488f565b84526147be565b80600114156145dc576145c96137e58461488f565b6001600160a01b031660208501526147be565b806002141561466b5760606145f3613f238561488f565b90508051604051908082528060200260200182016040528015614620578160200160208202803683370190505b50604086015260005b815181101561466457614641828281518110613f7657fe5b8660400151828151811061465157fe5b6020908102919091010152600101614629565b50506147be565b8060031415614700576060614682613f238561488f565b905080516040519080825280602002602001820160405280156146af578160200160208202803683370190505b50606086015260005b8151811015614664576146d082828151811061401257fe5b866060015182815181106146e057fe5b6001600160a01b03909216602092830291909101909101526001016146b8565b8060041415614795576060614717613f238561488f565b90508051604051908082528060200260200182016040528015614744578160200160208202803683370190505b50608086015260005b81518110156146645761476582828151811061401257fe5b8660800151828151811061477557fe5b6001600160a01b039092166020928302919091019091015260010161474d565b8060051415613899576147aa6137c48461488f565b67ffffffffffffffff1660a0850152600191505b60010161458e565b600060088211156147e857613466836007198401600a0a63ffffffff61305016565b611c99836008849003600a0a63ffffffff61300e16565b6148076151bb565b506040805180820190915281518152602082810190820152919050565b61482c61519b565b61483582614e9a565b61483e57600080fd5b600061484d8360200151614eca565b60208085015160408051808201909152868152920190820152915050919050565b60006148786151bb565b505080518051602091820151919092015191011190565b6148976151bb565b6148a08261486e565b6148a957600080fd5b602082015160006148b982614f2d565b80830160209586015260408051808201909152908152938401919091525090919050565b8051600090158015906148f257508151602110155b6148fb57600080fd5b600061490a8360200151614eca565b90508083600001511015614965576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b82516020808501518301805192849003929183101561498b57826020036101000a820491505b50949350505050565b80516000906015146149a557600080fd5b611c9c826148dd565b600080805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f8541580156149e75750600554155b15614a295760008052600660205269021e19e0c9bab24000007f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f85561a8c06005555b6020808301516001600160a01b0316600090815260069091526040902054801580614a575750808360400151105b15614a665760009150506111e9565b6020808401516001600160a01b039081166000908152600783526040808220606088015190931682529190925290819020908401518154614aac9163ffffffff612fb416565b8155600554420160018201819055606085015160208087015160408089015181519081529283019490945283516001600160a01b039384169493909116927f3fb83143cd331170da18fb1e8564d97e8ec39264b6ecb1ba248ea7596ab07258928290030190a35060019392505050565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416614b6057506018614b84565b6fffffffffffffffffffffffffffffffff198416614b8057506010614b84565b5060005b6020811015614bba57818181518110614b9957fe5b01602001516001600160f81b03191615614bb257614bba565b600101614b84565b60008160200390506060816040519080825280601f01601f191660200182016040528015614bef576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015614c345750607f60f81b82600081518110614c2257fe5b01602001516001600160f81b03191611155b15614c405750806111e9565b611c9c614c528351608060ff16614cd1565b835b6060806040519050835180825260208201818101602087015b81831015614c85578051835260209283019201614c6d565b50855184518101855292509050808201602086015b81831015614cb2578051835260209283019201614c9a565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310614d21576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411614d7b5782840160f81b81600081518110614d5d57fe5b60200101906001600160f81b031916908160001a9053509050611c9c565b6060614d8685614b1c565b90508381510160370160f81b82600081518110614d9f57fe5b60200101906001600160f81b031916908160001a905350614dc08282614c54565b95945050505050565b6060614dd482614e9a565b614ddd57600080fd5b6000614de883615060565b9050606081604051908082528060200260200182016040528015614e2657816020015b614e136151bb565b815260200190600190039081614e0b5790505b5090506000614e388560200151614eca565b60208601510190506000805b84811015614e8f57614e5583614f2d565b9150604051806040016040528083815260200184815250848281518110614e7857fe5b602090810291909101015291810191600101614e44565b509195945050505050565b8051600090614eab575060006111e9565b6020820151805160001a9060c0821015613580576000925050506111e9565b8051600090811a6080811015614ee45760009150506111e9565b60b8811080614eff575060c08110801590614eff575060f881105b15614f0e5760019150506111e9565b60c0811015614f225760b5190190506111e9565b60f5190190506111e9565b80516000908190811a6080811015614f485760019150615059565b60b8811015614f5d57607e1981019150615059565b60c0811015614fd757600060b78203600186019550806020036101000a865104915060018101820193505080831015614fd1576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b50615059565b60f8811015614fec5760be1981019150615059565b600060f78203600186019550806020036101000a865104915060018101820193505080831015615057576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b8051600090615071575060006111e9565b600080905060006150858460200151614eca565b602085015185519181019250015b808210156150b3576150a482614f2d565b60019093019290910190615093565b50909392505050565b6040518060c001604052806000801916815260200160006001600160a01b03168152602001606081526020016060815260200160608152602001600067ffffffffffffffff1681525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b60408051608081018252600080825260208201819052918101829052606081019190915290565b604051806080016040528060006001600160a01b031681526020016060815260200160608152602001600063ffffffff1681525090565b60405180604001604052806151ae6151bb565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe6f6e6c79207374616b696e672073797374656d20636f6e74726163742063616e2063616c6c20746869732066756e6374696f6e746865206d6573736167652073656e646572206d75737420626520696e63656e746976697a6520636f6e7472616374626e62206c61726765207472616e73666572206c696d697420746f6f20736d616c6c466f72206d696e69546f6b656e2c20746865207472616e7366657220616d6f756e74206d757374206e6f74206265206c657373207468616e2031756e7265636f676e697a6564207472616e736665724f75742073796e207061636b61676565787069726554696d65206d7573742062652074776f206d696e75746573206c61746572616d6f756e7420697320746f6f206c617267652c20657863656564206d6178696d756d206265703220746f6b656e20616d6f756e7474686520636f6e747261637420686173206e6f74206265656e20626f756e6420746f20616e79206265703220746f6b656e726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e736665724f757420424e4220616d6f756e7420616e64206d696e696d756d2072656c6179466565616d6f756e7420697320746f6f206c617267652c2075696e74323536206f766572666c6f774c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620726566756e644164647273696e76616c6964207472616e7366657220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e20746865206d696e696d756d2072656c6179466565746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374756e7265636f676e697a6564207472616e736665724f75742061636b207061636b6167654c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620616d6f756e7473746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d73672073656e646572206d75737420626520746f6b656e4d616e6167657274686520636f6e7472616374206e6f7420696e69742079657400000000000000726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e7366657220424e4220616d6f756e7420616e642072656c6179466565696e76616c696420726563656976656420424e4220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6ea2646970667358221220ef72e8713245ba000d1e9efd85d005317b64710a26d7b67a7649bda481a927d064736f6c63430006040033", + }, + { + ContractAddr: CrossChainContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/78e13b1d3a5a1b08c9208af94a9b14fc1efda213", + Code: "608060405234801561001057600080fd5b50600436106103995760003560e01c8063718a8aa8116101e9578063c27cdcfb1161010f578063dc927faf116100ad578063f7a251d71161007c578063f7a251d714610b2f578063f9a2bbc714610ba7578063fc3e590814610baf578063fd6a687914610bb757610399565b8063dc927faf14610af7578063e1c7392a14610aff578063e3b0480514610b07578063e6400bbe14610b2757610399565b8063ccc108d7116100e9578063ccc108d714610ab0578063d31f968d14610ab8578063d76a867514610ae7578063dc40433114610aef57610399565b8063c27cdcfb14610a80578063c780e9de14610aa0578063c81b166214610aa857610399565b80638cc8f56111610187578063a78abc1611610156578063a78abc16146109b2578063ab51bb96146109ba578063ac431751146109c2578063b0355f5b1461078157610399565b80638cc8f5611461088757806396713da91461099a5780639dc09262146109a2578063a1a11bf5146109aa57610399565b806375d47a0a116101c357806375d47a0a146108a75780637942fd05146108af57806384013b6a146108b7578063863fe4ab1461099257610399565b8063718a8aa81461088f578063719482d51461089757806374f079b81461089f57610399565b8063422f9050116102ce57806363e1394e1161026c5780636de380bd1161023b5780636de380bd146108575780636e47a51a1461085f5780636e47b4821461087f57806370fd5bad1461088757610399565b806363e1394e146107ff5780636a3cb34d146108075780636bacff2c1461080f5780636c46aa681461080757610399565b80634bf6c882116102a85780634bf6c882146107b957806351e80672146107c15780635692ddd3146107c95780635f832177146107d157610399565b8063422f90501461078957806343756e5c146107a9578063493279b1146107b157610399565b8063299b533d1161033b578063308325f411610315578063308325f4146106155780633a648b151461061d5780633bdc47a6146106595780633dffc3871461078157610399565b8063299b533d146105a35780632af6f399146105d75780632ff32aea146105f457610399565b806314b3023b1161037757806314b3023b146104015780631d1309351461041b5780631e275ae11461043757806322556cdc1461059b57610399565b806305e682581461039e5780630bee7a67146103bc5780630e2374a5146103dd575b600080fd5b6103a6610bbf565b6040805160ff9092168252519081900360200190f35b6103c4610bc4565b6040805163ffffffff9092168252519081900360200190f35b6103e5610bc9565b604080516001600160a01b039092168252519081900360200190f35b610409610bcf565b60408051918252519081900360200190f35b610423610bd5565b604080519115158252519081900360200190f35b610599600480360361010081101561044e57600080fd5b81018160a081016080820135600160201b81111561046b57600080fd5b82018360208201111561047d57600080fd5b803590602001918460018302840111600160201b8311171561049e57600080fd5b919390929091602081019035600160201b8111156104bb57600080fd5b8201836020820111156104cd57600080fd5b803590602001918460018302840111600160201b831117156104ee57600080fd5b919390929091602081019035600160201b81111561050b57600080fd5b82018360208201111561051d57600080fd5b803590602001918460018302840111600160201b8311171561053e57600080fd5b919390929091602081019035600160201b81111561055b57600080fd5b82018360208201111561056d57600080fd5b803590602001918460018302840111600160201b8311171561058e57600080fd5b509092509050610bde565b005b6104096112c2565b6105c0600480360360208110156105b957600080fd5b50356112c7565b6040805161ffff9092168252519081900360200190f35b610423600480360360208110156105ed57600080fd5b50356112dd565b6105fc6112f2565b60408051600792830b90920b8252519081900360200190f35b6104096112fb565b61063d6004803603602081101561063357600080fd5b503560ff16611301565b604080516001600160401b039092168252519081900360200190f35b61070c6004803603606081101561066f57600080fd5b60ff82351691602081013591810190606081016040820135600160201b81111561069857600080fd5b8201836020820111156106aa57600080fd5b803590602001918460018302840111600160201b831117156106cb57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061131c945050505050565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561074657818101518382015260200161072e565b50505050905090810190601f1680156107735780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103a6611392565b6104236004803603602081101561079f57600080fd5b503560ff16611397565b6103e56113ac565b6105c06113b2565b6103a66113b7565b6103e56113bc565b6104096113c2565b610599600480360360408110156107e757600080fd5b506001600160a01b03813581169160200135166113f2565b610409611652565b6105c061167a565b61082c6004803603602081101561082557600080fd5b503561167f565b6040805161ffff90941684526001600160801b03909216602084015282820152519081900360600190f35b6104096116ae565b6103e56004803603602081101561087557600080fd5b503560ff166116d5565b6103e56116f0565b6103a661167a565b6103a66116f6565b6105c0611392565b6104096116fb565b6103e5611701565b6103a6611707565b610599600480360360a08110156108cd57600080fd5b810190602081018135600160201b8111156108e757600080fd5b8201836020820111156108f957600080fd5b803590602001918460018302840111600160201b8311171561091a57600080fd5b919390929091602081019035600160201b81111561093757600080fd5b82018360208201111561094957600080fd5b803590602001918460018302840111600160201b8311171561096a57600080fd5b919350915080356001600160401b03908116916020810135909116906040013560ff1661170c565b610409612a36565b6103a6612a3e565b6103e5612a43565b6103e5612a49565b610423612a4f565b6103c4610bbf565b610599600480360360408110156109d857600080fd5b810190602081018135600160201b8111156109f257600080fd5b820183602082011115610a0457600080fd5b803590602001918460018302840111600160201b83111715610a2557600080fd5b919390929091602081019035600160201b811115610a4257600080fd5b820183602082011115610a5457600080fd5b803590602001918460018302840111600160201b83111715610a7557600080fd5b509092509050612a58565b61063d60048036036020811015610a9657600080fd5b503560ff1661351c565b610409613537565b6103e561355b565b610599613561565b61042360048036036040811015610ace57600080fd5b5080356001600160a01b0316906020013560ff166137b5565b61070c6137d5565b6104096137f4565b6103e56137fa565b610599613800565b61063d60048036036020811015610b1d57600080fd5b503560ff16613bb7565b610599613bd2565b61059960048036036060811015610b4557600080fd5b60ff8235169190810190604081016020820135600160201b811115610b6957600080fd5b820183602082011115610b7b57600080fd5b803590602001918460018302840111600160201b83111715610b9c57600080fd5b919350915035613df1565b6103e5613f34565b6103a6613f3a565b6103e5613f3f565b600081565b606481565b61200181565b60015481565b600b5460ff1681565b60005460ff16610c23576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4c833981519152604482015290519081900360640190fd5b604080516337d7f9c160e21b81526001600160401b038b35166004820181905291516110039163df5fe704916024808301926020929190829003018186803b158015610c6e57600080fd5b505afa158015610c82573d6000803e3d6000fd5b505050506040513d6020811015610c9857600080fd5b5051610cd55760405162461bcd60e51b8152600401808060200182810382526023815260200180614a6c6023913960400191505060405180910390fd5b604080516337d7f9c160e21b815260208c8101356001600160401b03166004830181905292516110039263df5fe704926024808301939192829003018186803b158015610d2157600080fd5b505afa158015610d35573d6000803e3d6000fd5b505050506040513d6020811015610d4b57600080fd5b5051610d885760405162461bcd60e51b8152600401808060200182810382526023815260200180614a6c6023913960400191505060405180910390fd5b60608b013560ff81166000908152600560205260409020546001600160401b03909116906001600160a01b0316610e01576040805162461bcd60e51b815260206004820152601860248201527718da185b9b995b081a5cc81b9bdd081cdd5c1c1bdc9d195960421b604482015290519081900360640190fd5b600b5460ff1615610e45576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b8888604051808383808284376040519201829003822094508f93508e9250819050838380828437808301925050509250505060405180910390201415610ec1576040805162461bcd60e51b815260206004820152600c60248201526b1cd85b59481c185e5b1bd85960a21b604482015290519081900360640190fd5b60606001600160401b0360408e01358116908e83013516610ee28282613f45565b80516020808301919091206000818152600e9092526040909120549194509060ff1615610f4b576040805162461bcd60e51b8152602060048201526012602482015271185b1c9958591e4818da185b1b195b99d95960721b604482015290519081900360640190fd5b6000908152600e60205260408120805460ff191660011790558f8160200201356001600160401b0316905060608f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040805163cba510a960e01b81526001600160401b038a16600482015290519596509094611003945063cba510a9935060248083019350602092829003018186803b15801561104157600080fd5b505afa158015611055573d6000803e3d6000fd5b505050506040513d602081101561106b57600080fd5b505160408051808201909152600381526269626360e81b6020820152909150611098908290898686613f8d565b6110e1576040805162461bcd60e51b81526020600482015260156024820152740696e76616c6964206d65726b6c652070726f6f663605c1b604482015290519081900360640190fd5b5050505060008f6001600481106110f457fe5b60200201356001600160401b0316905060608d8d8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8f018190048102820181019092528d815293945060609392508d91508c908190840183828082843760009201829052506040805163cba510a960e01b81526001600160401b038a16600482015290519596509094611003945063cba510a9935060248083019350602092829003018186803b1580156111c057600080fd5b505afa1580156111d4573d6000803e3d6000fd5b505050506040513d60208110156111ea57600080fd5b505160408051808201909152600381526269626360e81b6020820152909150611217908290898686613f8d565b611260576040805162461bcd60e51b8152602060048201526015602482015274696e76616c6964206d65726b6c652070726f6f663160581b604482015290519081900360640190fd5b5050505061126c61408a565b604080516001600160401b038416815260ff83166020820152815133927f039eb91179ffd7d3b6e97f8ea106e748e827f910b872375dbc9c14a362319c3c928290030190a2505050505050505050505050505050565b603281565b600d6020526000908152604090205461ffff1681565b600e6020526000908152604090205460ff1681565b60045460070b81565b60025481565b600a602052600090815260409020546001600160401b031681565b60606000825160210190506060816040519080825280601f01601f191660200182016040528015611354576020820181803683370190505b506021810186905260018101879052828152905060418101600061137786614108565b50905061138681838851614112565b50909695505050505050565b600181565b60096020526000908152604090205460ff1681565b61100181565b606181565b600881565b61200081565b604080517710d05390d15317d514905394d1915497d41493d413d4d05360421b8152905190819003601801902081565b60005460ff16611437576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4c833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b15801561147a57600080fd5b505afa15801561148e573d6000803e3d6000fd5b505050506040513d60208110156114a457600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b1580156114e557600080fd5b505afa1580156114f9573d6000803e3d6000fd5b505050506040513d602081101561150f57600080fd5b505190508061151c575060155b60008211801561152c5750808211155b61156b576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b604080516001600160a01b038087166020808401919091529086168284015282518083038401815260608301808552815191909201207710d05390d15317d514905394d1915497d41493d413d4d05360421b90915291519081900360780190206000906115d89083614153565b9050801561164a5760408051630911a2c160e11b81526001600160a01b03888116600483015287166024820152905161100491631223458291604480830192600092919082900301818387803b15801561163157600080fd5b505af1158015611645573d6000803e3d6000fd5b505050505b505050505050565b604080516f14d554d411539117d41493d413d4d05360821b8152905190819003601001902081565b600281565b600c602052600090815260409020805460019091015461ffff8216916201000090046001600160801b03169083565b604080516e149153d4115397d41493d413d4d053608a1b8152905190819003600f01902081565b6005602052600090815260409020546001600160a01b031681565b61100581565b601081565b60035481565b61100881565b600b81565b60005460ff16611751576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4c833981519152604482015290519081900360640190fd5b60408051630a83aaa960e31b815233600482015290516110069163541d5548916024808301926020929190829003018186803b15801561179057600080fd5b505afa1580156117a4573d6000803e3d6000fd5b505050506040513d60208110156117ba57600080fd5b505161180d576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b739fb29aac15b9a4b7f17c3385939b007540f4d79133148061184257507337b8516a0f88e65d677229b402ec6c1e0e33300433145b61187d5760405162461bcd60e51b815260040180806020018281038252602a8152602001806149f0602a913960400191505060405180910390fd5b60ff8116600090815260086020526040902054829082906001600160401b0390811690831681146118ed576040805162461bcd60e51b815260206004820152601560248201527439b2b8bab2b731b2903737ba1034b71037b93232b960591b604482015290519081900360640190fd5b60ff8216600090815260086020908152604091829020805467ffffffffffffffff1916600185016001600160401b039081169190911790915582516337d7f9c160e21b81529089166004820152915188926110039263df5fe70492602480840193829003018186803b15801561196257600080fd5b505afa158015611976573d6000803e3d6000fd5b505050506040513d602081101561198c57600080fd5b50516119c95760405162461bcd60e51b8152600401808060200182810382526023815260200180614a6c6023913960400191505060405180910390fd5b60ff851660009081526005602052604090205485906001600160a01b0316611a33576040805162461bcd60e51b815260206004820152601860248201527718da185b9b995b081a5cc81b9bdd081cdd5c1c1bdc9d195960421b604482015290519081900360640190fd5b60ff86166000908152600a6020526040902054889087906001600160401b039081169083161015611a9c576040805162461bcd60e51b815260206004820152600e60248201526d3a37b79037b632103432b0b232b960911b604482015290519081900360640190fd5b60ff81166000908152600a60205260409020546001600160401b03838116911614611aee5760ff81166000908152600a60205260409020805467ffffffffffffffff19166001600160401b0384161790555b600b5460ff1615611b32576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b60608e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509050611c766110036001600160a01b031663cba510a98e6040518263ffffffff1660e01b815260040180826001600160401b03166001600160401b0316815260200191505060206040518083038186803b158015611c1f57600080fd5b505afa158015611c33573d6000803e3d6000fd5b505050506040513d6020811015611c4957600080fd5b505160408051808201909152600381526269626360e81b6020820152611c6f8e8e613f45565b8585613f8d565b611cbe576040805162461bcd60e51b815260206004820152601460248201527334b73b30b634b21036b2b935b63290383937b7b360611b604482015290519081900360640190fd5b60408051631bb5062960e31b81526001600160401b038e16600482015290516000916110039163dda8314891602480820192602092909190829003018186803b158015611d0a57600080fd5b505afa158015611d1e573d6000803e3d6000fd5b505050506040513d6020811015611d3457600080fd5b505190508b8b600080806060611d4989614438565b935093509350935083611e0b578460ff16866001600160401b03167ff7b2e42d694eb1100184aae86d4245d9e46966100b1dc7e723275b98326854ac8b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611dc3578181015183820152602001611dab565b50505050905090810190601f168015611df05780820380516001836020036101000a031916815260200191505b509250505060405180910390a3505050505050505050612a26565b6040805160ff85811682529151918716916001600160401b038916917f36afdaf439a8f43fe72135135d804ae620b37a474f0943b5b85f6788312cad40919081900360200190a360ff83166123905760ff85166000818152600560209081526040808320548151631182b87560e01b815260048101958652602481019283528651604482015286516001600160a01b03909216958695631182b875958d958a9593949093606490910192918601918190849084905b83811015611ed8578181015183820152602001611ec0565b50505050905090810190601f168015611f055780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015611f2557600080fd5b505af192505050801561200957506040513d6000823e601f3d908101601f191682016040526020811015611f5857600080fd5b8101908080516040519392919084600160201b821115611f7757600080fd5b908301906020820185811115611f8c57600080fd5b8251600160201b811182820188101715611fa557600080fd5b82525081516020918201929091019080838360005b83811015611fd2578181015183820152602001611fba565b50505050905090810190601f168015611fff5780820380516001836020036101000a031916815260200191505b5060405250505060015b61231b576040516000815260443d1015612025575060006120c0565b60046000803e60005160e01c6308c379a081146120465760009150506120c0565b60043d036004833e81513d60248201116001600160401b0382111715612071576000925050506120c0565b80830180516001600160401b038111156120925760009450505050506120c0565b8060208301013d86018111156120b0576000955050505050506120c0565b601f01601f191660405250925050505b806120cb57506121dd565b60ff8716600090815260076020526040812054612102916001600160401b039091169089906120fd906002908861131c565b6144e8565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf948794849390840192918601918190849084905b8381101561219d578181015183820152602001612185565b50505050905090810190601f1680156121ca5780820380516001836020036101000a031916815260200191505b509250505060405180910390a250612316565b3d808015612207576040519150601f19603f3d011682016040523d82523d6000602084013e61220c565b606091505b5060ff871660009081526007602052604081205461223f916001600160401b039091169089906120fd906002908861131c565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351948794849390840192918601918190849084905b838110156122da5781810151838201526020016122c2565b50505050905090810190601f1680156123075780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b61238a565b8051156123885760ff8716600090815260076020526040812054612354916001600160401b039091169089906120fd906001908661131c565b60ff8716600090815260076020526040902080546001600160401b038082166001011667ffffffffffffffff199091161790555b505b5061295e565b60ff8316600114156126345760ff8516600081815260056020908152604080832054815163831d65d160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563831d65d1958d958a9593949093606490910192918601918190849084905b8381101561241a578181015183820152602001612402565b50505050905090810190601f1680156124475780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561246757600080fd5b505af1925050508015612478575060015b61238a576040516000815260443d10156124945750600061252f565b60046000803e60005160e01c6308c379a081146124b557600091505061252f565b60043d036004833e81513d60248201116001600160401b03821117156124e05760009250505061252f565b80830180516001600160401b0381111561250157600094505050505061252f565b8060208301013d860181111561251f5760009550505050505061252f565b601f01601f191660405250925050505b8061253a575061259f565b60408051602080825283518183015283516001600160a01b038616937ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf938693909283928301918501908083836000831561219d578181015183820152602001612185565b3d8080156125c9576040519150601f19603f3d011682016040523d82523d6000602084013e6125ce565b606091505b5060408051602080825283518183015283516001600160a01b038616937f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd297735193869390928392830191850190808383600083156122da5781810151838201526020016122c2565b60ff83166002141561295e5760ff8516600081815260056020908152604080832054815163c8509d8160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563c8509d81958d958a9593949093606490910192918601918190849084905b838110156126be5781810151838201526020016126a6565b50505050905090810190601f1680156126eb5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561270b57600080fd5b505af192505050801561271c575060015b61295c576040516000815260443d1015612738575060006127d3565b60046000803e60005160e01c6308c379a081146127595760009150506127d3565b60043d036004833e81513d60248201116001600160401b0382111715612784576000925050506127d3565b80830180516001600160401b038111156127a55760009450505050506127d3565b8060208301013d86018111156127c3576000955050505050506127d3565b601f01601f191660405250925050505b806127de5750612887565b816001600160a01b03167ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf826040518080602001828103825283818151815260200191508051906020019080838360005b8381101561284757818101518382015260200161282f565b50505050905090810190601f1680156128745780820380516001836020036101000a031916815260200191505b509250505060405180910390a25061295c565b3d8080156128b1576040519150601f19603f3d011682016040523d82523d6000602084013e6128b6565b606091505b50816001600160a01b03167f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351826040518080602001828103825283818151815260200191508051906020019080838360005b83811015612920578181015183820152602001612908565b50505050905090810190601f16801561294d5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b505b60ff80861660009081526009602052604090205461100591636f93d2e6918a91339187911680612990575060ff881615155b604080516001600160e01b031960e088901b1681526001600160a01b039586166004820152939094166024840152604483019190915215156064820152905160848083019260209291908290030181600087803b1580156129f057600080fd5b505af1158015612a04573d6000803e3d6000fd5b505050506040513d6020811015612a1a57600080fd5b50505050505050505050505b5050505050505050505050505050565b630100610081565b600981565b61100781565b61100681565b60005460ff1681565b3361100714612a985760405162461bcd60e51b815260040180806020018281038252602e815260200180614978602e913960400191505060405180910390fd5b600b5460ff1615612adc576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b612b4584848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526012815271626174636853697a65466f724f7261636c6560701b602082015291506146829050565b15612be057604080516020601f8401819004810282018101909252828152600091612b889185858083850183828082843760009201919091525061476992505050565b90506127108111158015612b9d5750600a8110155b612bd85760405162461bcd60e51b8152600401808060200182810382526032815260200180614a1a6032913960400191505060405180910390fd5b60015561348a565b612c4984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601281527118591913dc955c19185d1950da185b9b995b60721b602082015291506146829050565b15612dd157606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060169091149050612ccc5760405162461bcd60e51b815260040180806020018281038252605a815260200180614891605a913960600191505060405180910390fd5b60018101516002820151601683015160ff82161590612cea8161476e565b612d3b576040805162461bcd60e51b815260206004820152601960248201527f61646472657373206973206e6f74206120636f6e747261637400000000000000604482015290519081900360640190fd5b60ff8416600081815260056020908152604080832080546001600160a01b0319166001600160a01b038716908117909155808452600683528184208585528352818420805460ff199081166001179091556009909352818420805490931687151517909255519092917f7e3b6af43092577ee20e60eaa1d9b114a7031305c895ee7dd3ffe17196d2e1e091a3505050505061348a565b612e3e84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526016815275195b98589b1953dc911a5cd8589b1950da185b9b995b60521b602082015291506146829050565b15612f6f57606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060029091149050612ec15760405162461bcd60e51b815260040180806020018281038252604a8152602001806149a6604a913960600191505060405180910390fd5b600181810151600283015160ff80831660009081526005602052604090205492939192908316909114906001600160a01b03168015612f65576001600160a01b038116600090815260066020908152604080832060ff881680855290835292819020805460ff1916861515908117909155815190815290517fa3132e3f9819fbddc7f0ed6d38d7feef59aa95112090b7c592f5cb5bc4aa4adc929181900390910190a25b505050505061348a565b612fd384848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c73757370656e6451756f72756d60981b602082015291506146829050565b1561310857600281146130175760405162461bcd60e51b815260040180806020018281038252602d81526020018061491f602d913960400191505060405180910390fd5b600061305a600284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061476992505050565b905060008161ffff16118015613074575060648161ffff16105b6130be576040805162461bcd60e51b8152602060048201526016602482015275696e76616c69642073757370656e642071756f72756d60501b604482015290519081900360640190fd5b604080516f14d554d411539117d41493d413d4d05360821b815281519081900360100190206000908152600d60205220805461ffff90921661ffff1990921691909117905561348a565b61316b84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600c81526b72656f70656e51756f72756d60a01b602082015291506146829050565b1561329e57600281146131af5760405162461bcd60e51b815260040180806020018281038252602c81526020018061494c602c913960400191505060405180910390fd5b60006131f2600284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061476992505050565b905060008161ffff1611801561320c575060648161ffff16105b613255576040805162461bcd60e51b8152602060048201526015602482015274696e76616c69642072656f70656e2071756f72756d60581b604482015290519081900360640190fd5b604080516e149153d4115397d41493d413d4d053608a1b8152815190819003600f0190206000908152600d60205220805461ffff90921661ffff1990921691909117905561348a565b61330984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601481527363616e63656c5472616e7366657251756f72756d60601b602082015291506146829050565b1561344d576002811461334d5760405162461bcd60e51b81526004018080602001828103825260348152602001806148eb6034913960400191505060405180910390fd5b6000613390600284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061476992505050565b905060008161ffff161180156133aa575060648161ffff16105b6133fb576040805162461bcd60e51b815260206004820152601e60248201527f696e76616c69642063616e63656c207472616e736665722071756f72756d0000604482015290519081900360640190fd5b604080517710d05390d15317d514905394d1915497d41493d413d4d05360421b815281519081900360180190206000908152600d60205220805461ffff90921661ffff1990921691909117905561348a565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b6008602052600090815260409020546001600160401b031681565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081565b61100281565b60005460ff166135a6576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4c833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b1580156135e957600080fd5b505afa1580156135fd573d6000803e3d6000fd5b505050506040513d602081101561361357600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b15801561365457600080fd5b505afa158015613668573d6000803e3d6000fd5b505050506040513d602081101561367e57600080fd5b505190508061368b575060155b60008211801561369b5750808211155b6136da576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b600b5460ff16613721576040805162461bcd60e51b815260206004820152600d60248201526c1b9bdd081cdd5cdc195b991959609a1b604482015290519081900360640190fd5b604080516e149153d4115397d41493d413d4d053608a1b8152905190819003600f019020600090613772907fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470614153565b905080156137b057600b805460ff1916905560405133907f899fe8c37dc61708a3aaa99c4bf143346c1d1da69af79be9e8920c0a6785b75290600090a25b505050565b600660209081526000928352604080842090915290825290205460ff1681565b6040518060400160405280600381526020016269626360e81b81525081565b610e1081565b61100381565b60005460ff1615613858576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b7f1471eb6eb2c5e789fc3de43f8ce62938c7d1836ec861730447e2ada8fd81017b80546001600160a01b0319908116611008179091557f92e85d02570a8092d09a6e3a57665bc3815a2699a4074001bf1ccabf660f5a36805460ff199081169091557fd8af288fc1c8680b4f4706064cf021e264efb6828fcaf7eb5ca36818eb365bcc8054821660019081179091557f89832631fb3c3307a103ba2c84ab569c64d6182a18893dcd163f0f1c2090733a805484166110049081179091557f6cde3cea4b3a3fb2488b2808bae7556f4a405e50f65e1794383bc026131b13c38054841690557f72e4efa1513b071517c6c74dba31b5934a81aa83cddd400e7081df5529c9943680548416831790557fa9bc9a3a348c357ba16b37005d7e6b3236198c0e939f4af8c5f19b8deeb8ebc08054851690911790557fc575c31fea594a6eb97c8e9d3f9caee4c16218c6ef37e923234c0fe9014a61e78054831690557f4e523af77f034e9810f1c94057f5e931fb3d16a51511a4c3add793617d18610580548316821790557ffb33122aa9f93cc639ebe80a7bc4784c11e6053dde89c6f4f7e268c6a623da1e805484166110001790557fc7694af312c4f286114180fd0ba6a52461fcee8a381636770b19a343af92538a80548316821790557f01112dd68e482ba8d68a7e828cff8b3abcea08eab88941953c180a7e650e9cd480548316821790557fc0a4a8be475dfebc377ebef2d7c4ff47656f572a08dd92b81017efcdba0febe1805484166110071790557f87e8a52529e8ece4ef759037313542a6429ff494a9fab9027fb79db90124eba680548316821790557f4c7666bbcb22d46469f7cc282f70764a7012dca2cce630ff8d83db9a9cdd48f080548316821790557f40f28f99a40bc9f6beea1013afdbc3cdcc689eb76b82c4de06c0acf1e1932ed58054909316611001179092557f0d9cf2cd531699eed8dd34e40ff2884a14a698c4898184fba85194e6f6772d248054821683179055600b60009081527f23f68c9bd22b8a93d06adabe17481c87c016bcbd20adc8bfd707a4d813a572176020527fdf0d5d05428057f5455c2dc8e810dd86d1e9350faa72f16bda8a45443c5b39328054831684179055603283556004805467ffffffffffffffff19166001600160401b031790556002819055600381905580549091169091179055565b6007602052600090815260409020546001600160401b031681565b60005460ff16613c17576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4c833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b158015613c5a57600080fd5b505afa158015613c6e573d6000803e3d6000fd5b505050506040513d6020811015613c8457600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b158015613cc557600080fd5b505afa158015613cd9573d6000803e3d6000fd5b505050506040513d6020811015613cef57600080fd5b5051905080613cfc575060155b600082118015613d0c5750808211155b613d4b576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b600b5460ff1615613d8f576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b604080516f14d554d411539117d41493d413d4d05360821b81529051908190036010019020600090613de1907fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470614153565b905080156137b0576137b061408a565b60005460ff16613e36576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4c833981519152604482015290519081900360640190fd5b33600090815260066020908152604080832060ff8089168552925290912054859116613e935760405162461bcd60e51b81526004018080602001828103825260318152602001806148606031913960400191505060405180910390fd5b60ff85166000908152600760209081526040808320548151601f88018490048402810184019092528682526001600160401b031692613ef89284928a926120fd92909189918c908c908190840183828082843760009201919091525061131c92505050565b60ff959095166000908152600760205260409020805467ffffffffffffffff191660019096016001600160401b03169590951790945550505050565b61100081565b600381565b61100481565b60408051600e808252818301909252606091630100610060ff851617918391602082018180368337505050600e81810187905260068201939093529182525090505b92915050565b600085613f9c57506000614081565b606082518451865160800101016040519080825280601f01601f191660200182016040528015613fd3576020820181803683370190505b5090506000613fe182614774565b602080890151825201905086600080613ff989614108565b8086526020909501949092509050614012828583614112565b9283019261401f88614108565b8086526020909501949092509050614038828583614112565b9283018a81526020019261404b87614108565b909250905061405b828583614112565b50835160200161406961477a565b60208183886065600019fa5051600114955050505050505b95945050505050565b600b5460ff16156140ce576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b600b805460ff1916600117905560405133907f6f123d3d54c84a7960a573b31c221dcd86e13fd849c5adb0c6ca851468cc1ae490600090a2565b8051602090910191565b5b60208110614132578251825260209283019290910190601f1901614113565b915181516020939093036101000a6000190180199091169216919091179052565b6000828152600d602052604081205461ffff1661421c57604080516f14d554d411539117d41493d413d4d05360821b815281519081900360100181206000908152600d6020818152848320805461ffff199081166001179091556e149153d4115397d41493d413d4d053608a1b8552855194859003600f01852084528282528584208054821660029081179091557710d05390d15317d514905394d1915497d41493d413d4d05360421b8652865195869003601801909520845291905292902080549092161790555b6000838152600c6020526040902080546201000090046001600160801b03164210158061424d575082816001015414155b15614320576000848152600d602090815260409182902054835461ffff90911661ffff199091161771ffffffffffffffffffffffffffffffff0000191662010000610e1042016001600160801b031602178355600180840186905582519182019092523381526142c291600284019190614798565b5080546040805161ffff83168152620100009092046001600160801b0316602083015281810185905251339186917f9e109f0e55ef32e99e4880be2ec357f1ddb3469c79d0747ef4762da6e89fabe5916060908290030190a36143d4565b60005b60028201548110156143ab57336001600160a01b031682600201828154811061434857fe5b6000918252602090912001546001600160a01b031614156143a3576040805162461bcd60e51b815260206004820152601060248201526f185b1c9958591e48185c1c1c9bdd995960821b604482015290519081900360640190fd5b600101614323565b50600281018054600181018255600091825260209091200180546001600160a01b031916331790555b8054600282015461ffff9091161161442e576000848152600c60205260408120805471ffffffffffffffffffffffffffffffffffff19168155600181018290559061442260028301826147fd565b50506001915050613f87565b5060009392505050565b600080600060606021855110156144685750506040805160008082526020820190925290925082915081906144e1565b600185015160218601518651604080516020198301808252601f19600119909401939093168101602001909152604189019392916060919080156144b3576020820181803683370190505b50905060006144c182614108565b5090506144d3858260218d5103614112565b506001975091955093509150505b9193509193565b600b5460ff161561452c576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b60025443111561456b576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b1617909155600355436002556145ac565b600380546001908101918290555410156145ac576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003555b8160ff16836001600160401b0316600460009054906101000a900460070b6001600160401b03167f3a6e0fc61675aa2a100bcba0568368bb92bcec91c97673391074f11138f0cffe606185604051808361ffff1661ffff16815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561464257818101518382015260200161462a565b50505050905090810190601f16801561466f5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a4505050565b6000816040516020018082805190602001908083835b602083106146b75780518252601f199092019160209182019101614698565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106147255780518252601f199092019160209182019101614706565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b3b151590565b60200190565b60405180602001604052806001906020820280368337509192915050565b8280548282559060005260206000209081019282156147ed579160200282015b828111156147ed57825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906147b8565b506147f992915061481e565b5090565b508054600082559060005260206000209081019061481b9190614845565b50565b61484291905b808211156147f95780546001600160a01b0319168155600101614824565b90565b61484291905b808211156147f9576000815560010161484b56fe74686520636f6e747261637420616e64206368616e6e656c2068617665206e6f74206265656e20726567697374657265646c656e677468206f662076616c756520666f72206164644f725570646174654368616e6e656c2073686f756c642062652032322c206368616e6e656c49643a697346726f6d53797374656d3a68616e646c6572416464726573736c656e677468206f662076616c756520666f722063616e63656c5472616e7366657251756f72756d2073686f756c6420626520326c656e677468206f662076616c756520666f722073757370656e6451756f72756d2073686f756c6420626520326c656e677468206f662076616c756520666f722072656f70656e51756f72756d2073686f756c642062652032746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f7220656e61626c654f7244697361626c654368616e6e656c2073686f756c6420626520322c206368616e6e656c49643a6973456e61626c65746865206d73672073656e646572206973206e6f7420612077686974656c6162656c2072656c61796572746865206e6577426174636853697a65466f724f7261636c652073686f756c6420626520696e205b31302c2031303030305d74686520636f6e7472616374206e6f7420696e697420796574000000000000006c6967687420636c69656e74206e6f742073796e632074686520626c6f636b20796574a264697066735822122026f49f5b5d33882588ea53bac8a0f154c6a6d2ff32bdfdb114fc8cfcf13f710f64736f6c63430006040033", + }, + { + ContractAddr: StakingContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/78e13b1d3a5a1b08c9208af94a9b14fc1efda213", + Code: "6080604052600436106103855760003560e01c806370fd5bad116101d1578063b88a802f11610102578063d7ecfcb6116100a0578063f9a2bbc71161006f578063f9a2bbc714610c40578063fa03f79714610c55578063fc3e590814610671578063fd6a687914610c6a5761038c565b8063d7ecfcb614610819578063dc927faf14610bd1578063edc1a5b014610be6578063f45fd80b14610bfb5761038c565b8063c2117d82116100dc578063c2117d8214610ae7578063c81b166214610afc578063c8509d8114610b11578063d61b9b9314610b965761038c565b8063b88a802f14610a82578063baaafd3b14610a97578063bf8546ca14610aac5761038c565b806396713da91161016f578063a78abc1611610149578063a78abc1614610964578063ab51bb961461098d578063ac431751146109a2578063b14315df14610a6d5761038c565b806396713da9146109255780639dc092621461093a578063a1a11bf51461094f5761038c565b806375d47a0a116101ab57806375d47a0a146108765780637942fd051461088b578063831d65d1146108a057806392b888a41461061d5761038c565b806370fd5bad14610819578063718a8aa81461082e57806375aca593146108435761038c565b80633fdfa7e4116102b6578063552aaf931161025457806369b635b61161022357806369b635b6146107865780636bd8f8041461079b5780636e47b482146107d15780636fb7f7eb146107e65761038c565b8063552aaf93146107325780635d17c8bd146107475780635d499b1b1461075c57806362b171d2146107715761038c565b8063493279b111610290578063493279b1146106b05780634bf6c882146106dc5780634d99dd16146106f157806351e806721461071d5761038c565b80633fdfa7e414610671578063413d9c3a1461068657806343756e5c1461069b5761038c565b806311fe9ec6116103235780632fdeb111116102fd5780632fdeb11114610632578063333ad3e71461064757806334c433541461065c5780633dffc3871461061d5761038c565b806311fe9ec6146105bf578063151817e3146105f257806317c9efb01461061d5761038c565b80630bee7a671161035f5780630bee7a67146104515780630c7957151461047f5780630e2374a5146104945780631182b875146104c55761038c565b8063026e402b1461039157806302985992146103bf578063047636d1146103e65761038c565b3661038c57005b600080fd5b6103bd600480360360408110156103a757600080fd5b506001600160a01b038135169060200135610c7f565b005b3480156103cb57600080fd5b506103d46111bc565b60408051918252519081900360200190f35b3480156103f257600080fd5b506104196004803603602081101561040957600080fd5b50356001600160a01b03166111c2565b6040518082606080838360005b8381101561043e578181015183820152602001610426565b5050505090500191505060405180910390f35b34801561045d57600080fd5b50610466611216565b6040805163ffffffff9092168252519081900360200190f35b34801561048b57600080fd5b506103d461121b565b3480156104a057600080fd5b506104a9611221565b604080516001600160a01b039092168252519081900360200190f35b3480156104d157600080fd5b5061054a600480360360408110156104e857600080fd5b60ff8235169190810190604081016020820135600160201b81111561050c57600080fd5b82018360208201111561051e57600080fd5b803590602001918460018302840111600160201b8311171561053f57600080fd5b509092509050611227565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561058457818101518382015260200161056c565b50505050905090810190601f1680156105b15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156105cb57600080fd5b506103d4600480360360208110156105e257600080fd5b50356001600160a01b03166113e3565b3480156105fe57600080fd5b506106076113fe565b6040805160ff9092168252519081900360200190f35b34801561062957600080fd5b50610607611403565b34801561063e57600080fd5b506103d4611408565b34801561065357600080fd5b5061046661140e565b34801561066857600080fd5b506103d4611413565b34801561067d57600080fd5b5061060761141e565b34801561069257600080fd5b506103d4611423565b3480156106a757600080fd5b506104a961142a565b3480156106bc57600080fd5b506106c5611430565b6040805161ffff9092168252519081900360200190f35b3480156106e857600080fd5b50610607611435565b6103bd6004803603604081101561070757600080fd5b506001600160a01b03813516906020013561143a565b34801561072957600080fd5b506104a9611a62565b34801561073e57600080fd5b50610607611a68565b34801561075357600080fd5b506103d4611a6d565b34801561076857600080fd5b506103d4611a73565b34801561077d57600080fd5b506103d4611a7c565b34801561079257600080fd5b506103d4611c1c565b6103bd600480360360608110156107b157600080fd5b506001600160a01b03813581169160208101359091169060400135611c22565b3480156107dd57600080fd5b506104a961230b565b3480156107f257600080fd5b506103d46004803603602081101561080957600080fd5b50356001600160a01b0316612311565b34801561082557600080fd5b5061060761232c565b34801561083a57600080fd5b50610607612331565b34801561084f57600080fd5b506103d46004803603602081101561086657600080fd5b50356001600160a01b0316612336565b34801561088257600080fd5b506104a9612351565b34801561089757600080fd5b50610607612357565b3480156108ac57600080fd5b506103bd600480360360408110156108c357600080fd5b60ff8235169190810190604081016020820135600160201b8111156108e757600080fd5b8201836020820111156108f957600080fd5b803590602001918460018302840111600160201b8311171561091a57600080fd5b50909250905061235c565b34801561093157600080fd5b50610607612624565b34801561094657600080fd5b506104a9612629565b34801561095b57600080fd5b506104a961262f565b34801561097057600080fd5b50610979612635565b604080519115158252519081900360200190f35b34801561099957600080fd5b50610466611a68565b3480156109ae57600080fd5b506103bd600480360360408110156109c557600080fd5b810190602081018135600160201b8111156109df57600080fd5b8201836020820111156109f157600080fd5b803590602001918460018302840111600160201b83111715610a1257600080fd5b919390929091602081019035600160201b811115610a2f57600080fd5b820183602082011115610a4157600080fd5b803590602001918460018302840111600160201b83111715610a6257600080fd5b50909250905061263e565b348015610a7957600080fd5b50610607612dd0565b348015610a8e57600080fd5b506103d4612dd5565b348015610aa357600080fd5b506103d4612f72565b348015610ab857600080fd5b506103d460048036036040811015610acf57600080fd5b506001600160a01b0381358116916020013516612f7d565b348015610af357600080fd5b506103d4612faa565b348015610b0857600080fd5b506104a9612fb0565b348015610b1d57600080fd5b506103bd60048036036040811015610b3457600080fd5b60ff8235169190810190604081016020820135600160201b811115610b5857600080fd5b820183602082011115610b6a57600080fd5b803590602001918460018302840111600160201b83111715610b8b57600080fd5b509092509050612fb6565b348015610ba257600080fd5b506103d460048036036040811015610bb957600080fd5b506001600160a01b03813581169160200135166131d9565b348015610bdd57600080fd5b506104a9613204565b348015610bf257600080fd5b506103d461320a565b348015610c0757600080fd5b506103d460048036036060811015610c1e57600080fd5b506001600160a01b038135811691602081013582169160409091013516613217565b348015610c4c57600080fd5b506104a961324c565b348015610c6157600080fd5b506103d4613252565b348015610c7657600080fd5b506104a9613258565b60105460ff1660021415610ccb576040805162461bcd60e51b815260206004820152600e60248201526d4e6f2072652d656e7472616e637960901b604482015290519081900360640190fd5b6010805460ff19166002179055806402540be4003406158015610cf357506402540be4008106155b610d44576040805162461bcd60e51b815260206004820152601c60248201527f707265636973696f6e206c6f737320696e20636f6e76657273696f6e00000000604482015290519081900360640190fd5b60005460ff16610d87576638d7ea4c6800006001908155662386f26fc1000060025568056bc75e2d631000006003556108fc6011556000805460ff191690911790555b600354821015610dde576040805162461bcd60e51b815260206004820152601760248201527f696e76616c69642064656c656761746520616d6f756e74000000000000000000604482015290519081900360640190fd5b600154610df290839063ffffffff61325e16565b341015610e3d576040805162461bcd60e51b81526020600482015260146024820152736e6f7420656e6f756768206d73672076616c756560601b604482015290519081900360640190fd5b601154604051600091339183818181818787f1925050503d8060008114610e80576040519150601f19603f3d011682016040523d82523d6000602084013e610e85565b606091505b5050905080610ecf576040805162461bcd60e51b815260206004820152601160248201527034b73b30b634b2103232b632b3b0ba37b960791b604482015290519081900360640190fd5b6000610ee6846402540be40063ffffffff6132bf16565b90506000610efa348663ffffffff61330116565b90506000610f136002548361330190919063ffffffff16565b6040805160038082526080820190925291925060609190816020015b6060815260200190600190039081610f2f579050509050610f4f33613343565b81600081518110610f5c57fe5b6020026020010181905250610f79886001600160a01b0316613343565b81600181518110610f8657fe5b6020026020010181905250610f9a84613366565b81600281518110610fa757fe5b60200260200101819052506060610fc76001610fc284613379565b613403565b8051602080830191909120600f80546000908152600a845260408082209390935581546001908101909255338152600b909352912080549091019055905061200063f7a251d7601083611025876402540be40063ffffffff6132bf16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561108357818101518382015260200161106b565b50505050905090810190601f1680156110b05780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156110d157600080fd5b505af11580156110e5573d6000803e3d6000fd5b5061100492506108fc915061110290508a8663ffffffff61325e16565b6040518115909202916000818181858888f1935050505015801561112a573d6000803e3d6000fd5b506002546040516110029180156108fc02916000818181858888f1935050505015801561115b573d6000803e3d6000fd5b50604080518981526020810185905281516001600160a01b038c169233927f5f32ed2794e2e72d19e3cb2320e8820a499c4204887372beba51f5e61c040867929081900390910190a350506010805460ff1916600117905550505050505050565b60035481565b6111ca615193565b6111d2615193565b6001600160a01b0383166000818152600b60209081526040808320548552838352600c82528083205485830152928252600d9052819020549082015290505b919050565b606481565b6108fc81565b61200181565b606033612000146112695760405162461bcd60e51b815260040180806020018281038252602f81526020018061539b602f913960400191505060405180910390fd5b60005460ff166112ac576638d7ea4c6800006001908155662386f26fc1000060025568056bc75e2d631000006003556108fc6011556000805460ff191690911790555b6112b46151b1565b6112fb6112f685858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061348992505050565b6134ae565b9050600061131061130b836134f8565b613546565b90506000606060ff8316600414156113355761132b846135fd565b909250905061138c565b60ff83166005141561134a5761132b846137dd565b6040805162461bcd60e51b8152602060048201526012602482015271756e6b6e6f776e206576656e74207479706560701b604482015290519081900360640190fd5b63ffffffff8216156113d8576040805163ffffffff84168152905160ff8516917f391d6e5ea6ab6c49b9a0abb1782cae5def8d711f973b00c729658c0b2a80b31b919081900360200190a25b979650505050505050565b6001600160a01b031660009081526006602052604090205490565b600581565b600181565b60015481565b606581565b662386f26fc1000081565b600381565b620a8c0081565b61100181565b606181565b600881565b60105460ff1660021415611486576040805162461bcd60e51b815260206004820152600e60248201526d4e6f2072652d656e7472616e637960901b604482015290519081900360640190fd5b6010805460ff19166002179055806402540be40034061580156114ae57506402540be4008106155b6114ff576040805162461bcd60e51b815260206004820152601c60248201527f707265636973696f6e206c6f737320696e20636f6e76657273696f6e00000000604482015290519081900360640190fd5b60005460ff16611542576638d7ea4c6800006001908155662386f26fc1000060025568056bc75e2d631000006003556108fc6011556000805460ff191690911790555b600154341015611590576040805162461bcd60e51b81526020600482015260146024820152736e6f7420656e6f7567682072656c61792066656560601b604482015290519081900360640190fd5b60035482101561164b573360009081526005602090815260408083206001600160a01b03871684529091529020548214611602576040805162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b604482015290519081900360640190fd5b600254821161164b576040805162461bcd60e51b815260206004820152601060248201526f6e6f7420656e6f7567682066756e647360801b604482015290519081900360640190fd5b3360009081526007602090815260408083206001600160a01b03871684529091529020544210156116c3576040805162461bcd60e51b815260206004820152601a60248201527f70656e64696e6720756e64656c65676174696f6e206578697374000000000000604482015290519081900360640190fd5b604080518082018252601081526f6e6f7420656e6f7567682066756e647360801b602080830191909152336000908152600582528381206001600160a01b03881682529091529182205461171e91859063ffffffff6139f916565b905080156117665760025481116117665760405162461bcd60e51b81526004018080602001828103825260258152602001806153766025913960400191505060405180910390fd5b600061177d846402540be40063ffffffff6132bf16565b600254909150349060009061179990839063ffffffff61330116565b6040805160038082526080820190925291925060609190816020015b60608152602001906001900390816117b55790505090506117d533613343565b816000815181106117e257fe5b60200260200101819052506117ff886001600160a01b0316613343565b8160018151811061180c57fe5b602002602001018190525061182084613366565b8160028151811061182d57fe5b602002602001018190525060606118486002610fc284613379565b8051602080830191909120600f80546000908152600a845260408082209390935581546001908101909255338152600c909352912080549091019055905061189942620a8c0063ffffffff61325e16565b3360009081526007602090815260408083206001600160a01b038e16845290915290205561200063f7a251d76010836118dd876402540be40063ffffffff6132bf16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561193b578181015183820152602001611923565b50505050905090810190601f1680156119685780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561198957600080fd5b505af115801561199d573d6000803e3d6000fd5b5050604051611004925085156108fc02915085906000818181858888f193505050501580156119d0573d6000803e3d6000fd5b506002546040516110029180156108fc02916000818181858888f19350505050158015611a01573d6000803e3d6000fd5b50604080518981526020810185905281516001600160a01b038c169233927fdf0b6ac27f3f3bb31cee3dab0f4fe40cc19c6a3f8daaec52e06b261e58a12519929081900390910190a350506010805460ff1916600117905550505050505050565b61200081565b600081565b60025481565b6402540be40081565b60105460009060ff1660021415611acb576040805162461bcd60e51b815260206004820152600e60248201526d4e6f2072652d656e7472616e637960901b604482015290519081900360640190fd5b506010805460ff191660021790553360009081526008602052604090205480611b32576040805162461bcd60e51b81526020600482015260146024820152736e6f20756e64656c6567617465642066756e647360601b604482015290519081900360640190fd5b336000818152600860205260408082208290556011549051919291849084818181858888f193505050503d8060008114611b88576040519150601f19603f3d011682016040523d82523d6000602084013e611b8d565b606091505b5050905080611bd5576040805162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b604482015290519081900360640190fd5b60408051838152905133917fc712d133b8d448221aaed2198ed1f0db6dfc860fb01bc3a630916fe6cbef946f919081900360200190a2506010805460ff1916600117905590565b60035490565b60105460ff1660021415611c6e576040805162461bcd60e51b815260206004820152600e60248201526d4e6f2072652d656e7472616e637960901b604482015290519081900360640190fd5b6010805460ff19166002179055806402540be4003406158015611c9657506402540be4008106155b611ce7576040805162461bcd60e51b815260206004820152601c60248201527f707265636973696f6e206c6f737320696e20636f6e76657273696f6e00000000604482015290519081900360640190fd5b60005460ff16611d2a576638d7ea4c6800006001908155662386f26fc1000060025568056bc75e2d631000006003556108fc6011556000805460ff191690911790555b826001600160a01b0316846001600160a01b03161415611d88576040805162461bcd60e51b815260206004820152601460248201527334b73b30b634b2103932b232b632b3b0ba34b7b760611b604482015290519081900360640190fd5b600154341015611dd6576040805162461bcd60e51b81526020600482015260146024820152736e6f7420656e6f7567682072656c61792066656560601b604482015290519081900360640190fd5b600354821015611e1e576040805162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b604482015290519081900360640190fd5b3360009081526009602090815260408083206001600160a01b03888116855290835281842090871684529091529020544210801590611e8c57503360009081526009602090815260408083206001600160a01b03878116855290835281842090881684529091529020544210155b611edd576040805162461bcd60e51b815260206004820152601a60248201527f70656e64696e6720726564656c65676174696f6e206578697374000000000000604482015290519081900360640190fd5b604080518082018252601081526f6e6f7420656e6f7567682066756e647360801b602080830191909152336000908152600582528381206001600160a01b038916825290915291822054611f3891859063ffffffff6139f916565b90508015611f80576002548111611f805760405162461bcd60e51b815260040180806020018281038252602581526020018061527a6025913960400191505060405180910390fd5b6000611f97846402540be40063ffffffff6132bf16565b6002549091503490600090611fb390839063ffffffff61330116565b60408051600480825260a0820190925291925060609190816020015b6060815260200190600190039081611fcf579050509050611fef33613343565b81600081518110611ffc57fe5b6020026020010181905250612019896001600160a01b0316613343565b8160018151811061202657fe5b6020026020010181905250612043886001600160a01b0316613343565b8160028151811061205057fe5b602002602001018190525061206484613366565b8160038151811061207157fe5b6020026020010181905250606061208c6003610fc284613379565b8051602080830191909120600f80546000908152600a845260408082209390935581546001908101909255338152600d90935291208054909101905590506120dd42620a8c0063ffffffff61325e16565b3360009081526009602090815260408083206001600160a01b038e81168552908352818420908f16845290915290205561212042620a8c0063ffffffff61325e16565b3360009081526009602090815260408083206001600160a01b038f81168552908352818420908e16845290915290205561200063f7a251d7601083612170876402540be40063ffffffff6132bf16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156121ce5781810151838201526020016121b6565b50505050905090810190601f1680156121fb5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561221c57600080fd5b505af1158015612230573d6000803e3d6000fd5b5050604051611004925085156108fc02915085906000818181858888f19350505050158015612263573d6000803e3d6000fd5b506002546040516110029180156108fc02916000818181858888f19350505050158015612294573d6000803e3d6000fd5b50886001600160a01b03168a6001600160a01b0316336001600160a01b03167fdb0d03fdfcb145c486c442659e6a341a8828985505097cb5190afcf541e840158b87604051808381526020018281526020019250505060405180910390a450506010805460ff191660011790555050505050505050565b61100581565b6001600160a01b031660009081526004602052604090205490565b600281565b601081565b6001600160a01b031660009081526008602052604090205490565b61100881565b600b81565b336120001461239c5760405162461bcd60e51b815260040180806020018281038252602f81526020018061539b602f913960400191505060405180910390fd5b60005460ff166123df576638d7ea4c6800006001908155662386f26fc1000060025568056bc75e2d631000006003556108fc6011556000805460ff191690911790555b6123e76151b1565b6124296112f684848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061348992505050565b905060008060606000805b61243d86613a90565b156124a8578061245a5761245361130b876134f8565b94506124a0565b80600114156124765761246f61130b876134f8565b93506124a0565b806002141561249b5761249061248b876134f8565b613ab1565b9250600191506124a0565b6124a8565b600101612434565b816124ee576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b6124f783613b21565b61253a576040805162461bcd60e51b815260206004820152600f60248201526e0eee4dedcce40e0c2c6d640d0c2e6d608b1b604482015290519081900360640190fd5b6125466112f684613489565b9550600061255661130b886134f8565b90506125606151b1565b61256988613a90565b1561258c576125856112f661258061248b8b6134f8565b613489565b90506125cd565b6040805162461bcd60e51b8152602060048201526011602482015270656d7074792061636b207061636b61676560781b604482015290519081900360640190fd5b60ff8216600114156125e9576125e4818888613b75565b612617565b60ff821660021415612600576125e4818888613f2c565b60ff82166003141561134a576125e48188886141f9565b5050505050505050505050565b600981565b61100781565b61100681565b60005460ff1681565b60005460ff16612695576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604482015290519081900360640190fd5b33611007146126d55760405162461bcd60e51b815260040180806020018281038252602e8152602001806152ec602e913960400191505060405180910390fd5b61273684848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600a81526972656c6179657246656560b01b6020820152915061455e9050565b1561289c5760208114612790576040805162461bcd60e51b815260206004820152601d60248201527f6c656e677468206f662072656c61796572466565206d69736d61746368000000604482015290519081900360640190fd5b604080516020601f84018190048102820181019092528281526000916127ce9185858083850183828082843760009201919091525061464592505050565b905060035481106128105760405162461bcd60e51b815260040180806020018281038252602e81526020018061531a602e913960400191505060405180910390fd5b60025481116128505760405162461bcd60e51b815260040180806020018281038252602e815260200180615348602e913960400191505060405180910390fd5b6402540be4008106156128945760405162461bcd60e51b815260040180806020018281038252602c8152602001806152c0602c913960400191505060405180910390fd5b600155612d3e565b61290084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c62534352656c6179657246656560981b6020820152915061455e9050565b15612a62576020811461295a576040805162461bcd60e51b815260206004820181905260248201527f6c656e677468206f662062534352656c61796572466565206d69736d61746368604482015290519081900360640190fd5b604080516020601f84018190048102820181019092528281526000916129989185858083850183828082843760009201919091525061464592505050565b9050806129d65760405162461bcd60e51b81526004018080602001828103825260228152602001806153ca6022913960400191505060405180910390fd5b6001548110612a165760405162461bcd60e51b815260040180806020018281038252602e81526020018061521b602e913960400191505060405180910390fd5b6402540be400810615612a5a5760405162461bcd60e51b815260040180806020018281038252602f8152602001806151ec602f913960400191505060405180910390fd5b600255612d3e565b612ac684848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c36b4b72232b632b3b0ba34b7b760991b6020820152915061455e9050565b15612ba85760208114612b20576040805162461bcd60e51b815260206004820181905260248201527f6c656e677468206f66206d696e44656c65676174696f6e206d69736d61746368604482015290519081900360640190fd5b604080516020601f8401819004810282018101909252828152600091612b5e9185858083850183828082843760009201919091525061464592505050565b90506001548111612ba05760405162461bcd60e51b81526004018080602001828103825260318152602001806152496031913960400191505060405180910390fd5b600355612d3e565b612c0a84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600b81526a7472616e7366657247617360a81b6020820152915061455e9050565b15612d015760208114612c64576040805162461bcd60e51b815260206004820152601e60248201527f6c656e677468206f66207472616e73666572476173206d69736d617463680000604482015290519081900360640190fd5b604080516020601f8401819004810282018101909252828152600091612ca29185858083850183828082843760009201919091525061464592505050565b905060008111612cf9576040805162461bcd60e51b815260206004820152601e60248201527f746865207472616e736665724761732063616e6e6f74206265207a65726f0000604482015290519081900360640190fd5b601155612d3e565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b600481565b60105460009060ff1660021415612e24576040805162461bcd60e51b815260206004820152600e60248201526d4e6f2072652d656e7472616e637960901b604482015290519081900360640190fd5b506010805460ff191660021790553360009081526006602052604090205480612e88576040805162461bcd60e51b81526020600482015260116024820152701b9bc81c195b991a5b99c81c995dd85c99607a1b604482015290519081900360640190fd5b336000818152600660205260408082208290556011549051919291849084818181858888f193505050503d8060008114612ede576040519150601f19603f3d011682016040523d82523d6000602084013e612ee3565b606091505b5050905080612f2b576040805162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b604482015290519081900360640190fd5b60408051838152905133917f83b78188b13346b2ffb484da70d42ee27de7fbf9f2bd8045269e10ed643ccd76919081900360200190a2506010805460ff1916600117905590565b6638d7ea4c68000081565b6001600160a01b038083166000908152600760209081526040808320938516835292905220545b92915050565b60015490565b61100281565b3361200014612ff65760405162461bcd60e51b815260040180806020018281038252602f81526020018061539b602f913960400191505060405180910390fd5b60005460ff16613039576638d7ea4c6800006001908155662386f26fc1000060025568056bc75e2d631000006003556108fc6011556000805460ff191690911790555b61307882828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613b2192505050565b6130bb576040805162461bcd60e51b815260206004820152600f60248201526e0eee4dedcce40e0c2c6d640d0c2e6d608b1b604482015290519081900360640190fd5b6130c36151b1565b6131056112f684848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061348992505050565b9050600061311561130b836134f8565b905061311f6151b1565b61312883613a90565b156131465761313f6112f661258061248b866134f8565b905061318c565b6040805162461bcd60e51b8152602060048201526016602482015275656d707479206661696c2061636b207061636b61676560501b604482015290519081900360640190fd5b60ff8216600114156131a6576131a18161464a565b6131d0565b60ff8216600214156131bb576131a181614864565b60ff82166003141561134a576131a18161498e565b5050505b505050565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205490565b61100381565b68056bc75e2d6310000081565b6001600160a01b0392831660009081526009602090815260408083209486168352938152838220929094168152925290205490565b61100081565b60115481565b61100481565b6000828201838110156132b8576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b60006132b883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614af3565b60006132b883836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506139f9565b60408051600560a21b83186014820152603481019091526060906132b881614b58565b6060612fa461337483614bae565b614b58565b606081516000141561339a5750604080516000815260208101909152611211565b6060826000815181106133a957fe5b602002602001015190506000600190505b83518110156133ea576133e0828583815181106133d357fe5b6020026020010151614c94565b91506001016133ba565b506132b86133fd825160c060ff16614d11565b82614c94565b6040805160028082526060828101909352829190816020015b606081526020019060019003908161341c57905050905061343f8460ff16613366565b8160008151811061344c57fe5b602002602001018190525061346083614b58565b8160018151811061346d57fe5b602002602001018190525061348181613379565b949350505050565b6134916151d1565b506040805180820190915281518152602082810190820152919050565b6134b66151b1565b6134bf82614e09565b6134c857600080fd5b60006134d78360200151614e43565b60208085015160408051808201909152868152920190820152915050919050565b6135006151d1565b61350982613a90565b61351257600080fd5b6020820151600061352282614ea6565b80830160209586015260408051808201909152908152938401919091525090919050565b80516000901580159061355b57508151602110155b61356457600080fd5b60006135738360200151614e43565b905080836000015110156135ce576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b8251602080850151830180519284900392918310156135f457826020036101000a820491505b50949350505050565b600060606000806000805b61361187613a90565b1561366357826136335761362c613627886134f8565b614fd9565b9150613658565b82600114156136535761364861130b886134f8565b905060019350613658565b613663565b826001019250613608565b836136a9576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b60006110046001600160a01b031663727be1f8836040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b1580156136f357600080fd5b505af1158015613707573d6000803e3d6000fd5b505050506040513d602081101561371d57600080fd5b505190508061374257613734600484846065614ff3565b9650965050505050506137d8565b6001600160a01b03831660009081526006602052604090205461376b908363ffffffff61325e16565b6001600160a01b038416600081815260066020908152604091829020939093558051858152905191927f7cc266c7b444f808013fa187f7b904d470a051a6564e78f482aa496581ba4bf892918290030190a260408051600080825260208201909252909750955050505050505b915091565b6000606060008060008060005b6137f388613a90565b1561385c578361381057613809613627896134f8565b9250613851565b836001141561382c57613825613627896134f8565b9150613851565b836002141561384c5761384161130b896134f8565b905060019450613851565b61385c565b8360010193506137ea565b846138a2576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b60006110046001600160a01b031663727be1f8836040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b1580156138ec57600080fd5b505af1158015613900573d6000803e3d6000fd5b505050506040513d602081101561391657600080fd5b505190508061393c5761392d600585846065614ff3565b975097505050505050506137d8565b6001600160a01b038085166000818152600760209081526040808320948816835293815283822082905591815260089091522054613980908363ffffffff61325e16565b6001600160a01b0380861660008181526008602090815260409182902094909455805186815290519287169391927f35a799836f74fac7eccf5c73902823b970543d2274d3b93d8da3d37a255772a2929181900390910190a3604080516000808252602082019092529098509650505050505050915091565b60008184841115613a885760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613a4d578181015183820152602001613a35565b50505050905090810190601f168015613a7a5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000613a9a6151d1565b505080518051602091820151919092015191011190565b8051606090613abf57600080fd5b6000613ace8360200151614e43565b83516040805191839003808352601f19601f8201168301602001909152919250606090828015613b05576020820181803683370190505b50905060008160200190506135f48487602001510182856150ef565b8051602080830191909120600e546000908152600a9092526040822054808214613b5057600092505050611211565b5050600e80546000908152600a60205260408120558054600190810190915592915050565b60008060008060005b613b8788613a90565b15613bf05783613ba457613b9d613627896134f8565b9250613be5565b8360011415613bc057613bb9613627896134f8565b9150613be5565b8360021415613be057613bd561130b896134f8565b905060019450613be5565b613bf0565b836001019350613b7e565b84613c36576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b6000613c4d826402540be40063ffffffff61513a16565b6001600160a01b0385166000908152600b602052604090208054600019019055905060ff881660011415613d935760ff871615613cc0576040805162461bcd60e51b815260206004820152600c60248201526b77726f6e672073746174757360a01b604482015290519081900360640190fd5b6001600160a01b038416600090815260046020526040902054613ce9908263ffffffff61325e16565b6001600160a01b03808616600090815260046020908152604080832094909455600581528382209287168252919091522054613d2b908263ffffffff61325e16565b6001600160a01b038086166000818152600560209081526040808320948916808452948252918290209490945580518581529051929391927f9a57c81564ab02642f34fd87e41baa9b074c18342cec3b7268b62bf752018fd1929181900390910190a3613f21565b60ff8816613ee5576001600160a01b038416600090815260086020526040902054613dc4908263ffffffff61325e16565b6001600160a01b0385166000908152600860209081526040808320939093558251630e4f7c3f60e31b81526004810185905292516110049363727be1f89360248083019493928390030190829087803b158015613e2057600080fd5b505af1158015613e34573d6000803e3d6000fd5b505050506040513d6020811015613e4a57600080fd5b5051613e93576040805162461bcd60e51b81526020600482015260136024820152721dda5d1a191c985dc8189b988819985a5b1959606a1b604482015290519081900360640190fd5b6040805182815260ff8916602082015281516001600160a01b0380871693908816927fcbd481ae600289fad8c0484d07ce0ffe4f010d7c844ecfdeaf2a13fead52886e929081900390910190a3613f21565b6040805162461bcd60e51b815260206004820152600c60248201526b77726f6e672073746174757360a01b604482015290519081900360640190fd5b505050505050505050565b60008060008060005b613f3e88613a90565b15613fa75783613f5b57613f54613627896134f8565b9250613f9c565b8360011415613f7757613f70613627896134f8565b9150613f9c565b8360021415613f9757613f8c61130b896134f8565b905060019450613f9c565b613fa7565b836001019350613f35565b84613fed576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b6000614004826402540be40063ffffffff61513a16565b6001600160a01b0385166000908152600c602052604090208054600019019055905060ff8816600114156141835760ff871615614077576040805162461bcd60e51b815260206004820152600c60248201526b77726f6e672073746174757360a01b604482015290519081900360640190fd5b6001600160a01b0384166000908152600460205260409020546140a0908263ffffffff61330116565b6001600160a01b038086166000908152600460209081526040808320949094556005815283822092871682529190915220546140e2908263ffffffff61330116565b6001600160a01b0380861660009081526005602090815260408083209388168352929052205561411b42620a8c0063ffffffff61325e16565b6001600160a01b038086166000818152600760209081526040808320948916808452948252918290209490945580518581529051929391927fd6f878a5bcbbe79a64e6418bb0d56aaa20b9a60587d45749819df88dfc7c3c44929181900390910190a3613f21565b60ff8816613ee5576001600160a01b03808516600081815260076020908152604080832094881680845294825280832092909255815185815260ff8c169181019190915281517f4417d10c1e33efa83a770b8d4f47176e78c08c1298d534901ad3b16bb585fa2e929181900390910190a3613f21565b6000806000806000805b61420c89613a90565b156142915784614229576142226136278a6134f8565b9350614286565b84600114156142455761423e6136278a6134f8565b9250614286565b84600214156142615761425a6136278a6134f8565b9150614286565b84600314156142815761427661130b8a6134f8565b905060019550614286565b614291565b846001019450614203565b856142d7576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b60006142ee826402540be40063ffffffff61513a16565b6001600160a01b0386166000908152600d602052604090208054600019019055905060ff8916600114156144c15760ff881615614361576040805162461bcd60e51b815260206004820152600c60248201526b77726f6e672073746174757360a01b604482015290519081900360640190fd5b6001600160a01b03808616600090815260056020908152604080832093881683529290522054614397908263ffffffff61330116565b6001600160a01b038681166000908152600560209081526040808320898516845290915280822093909355908516815220546143d3908261325e565b6001600160a01b0380871660009081526005602090815260408083209388168352929052205561440c42620a8c0063ffffffff61325e16565b6001600160a01b038087166000908152600960209081526040808320898516845282528083209388168352929052205561444f42620a8c0063ffffffff61325e16565b6001600160a01b038087166000818152600960209081526040808320898616808552908352818420958b1680855295835292819020959095558451868152945191947f78bffae3f8c6691ac7fc1a3bff800cb2d612f5ad9ae5b0444cfe2eb15c189e18929081900390910190a4614552565b60ff8916613ee5576001600160a01b038581166000818152600960209081526040808320898616808552818452828520968a16808652968452828520859055908352818420818552835281842093909355805186815260ff8e169281019290925280519293927fb93bee5c59f85ede6b074a99f4ffcd3e3fc0d5c3d8156de331de89a49e0ce77c9281900390910190a45b50505050505050505050565b6000816040516020018082805190602001908083835b602083106145935780518252601f199092019160209182019101614574565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106146015780518252601f1990920191602091820191016145e2565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b60008060008060005b61465c86613a90565b156146c5578361467957614672613627876134f8565b92506146ba565b83600114156146955761468e613627876134f8565b91506146ba565b83600214156146b5576146aa61130b876134f8565b9050600194506146ba565b6146c5565b836001019350614653565b8461470b576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b6000614722826402540be40063ffffffff61513a16565b6001600160a01b0385166000908152600b6020908152604080832080546000190190556008909152902054909150614760908263ffffffff61325e16565b6001600160a01b0385166000908152600860209081526040808320939093558251630e4f7c3f60e31b81526004810185905292516110049363727be1f89360248083019493928390030190829087803b1580156147bc57600080fd5b505af11580156147d0573d6000803e3d6000fd5b505050506040513d60208110156147e657600080fd5b505161482f576040805162461bcd60e51b81526020600482015260136024820152721dda5d1a191c985dc8189b988819985a5b1959606a1b604482015290519081900360640190fd5b6040516001907ff83de021914a4585482db5ca47d520a5657165b443fa2c7ef8ed4635f054da9b90600090a250505050505050565b60008060008060005b61487686613a90565b156148df57836148935761488c613627876134f8565b92506148d4565b83600114156148af576148a8613627876134f8565b91506148d4565b83600214156148cf576148c461130b876134f8565b9050600194506148d4565b6148df565b83600101935061486d565b84614925576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b6001600160a01b038084166000908152600c60209081526040808320805460001901905560078252808320938616835292905281812081905590516002917ff83de021914a4585482db5ca47d520a5657165b443fa2c7ef8ed4635f054da9b91a2505050505050565b6000806000806000805b6149a187613a90565b15614a2657846149be576149b7613627886134f8565b9350614a1b565b84600114156149da576149d3613627886134f8565b9250614a1b565b84600214156149f6576149ef613627886134f8565b9150614a1b565b8460031415614a1657614a0b61130b886134f8565b905060019550614a1b565b614a26565b846001019450614998565b85614a6c576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b6001600160a01b038481166000908152600d602090815260408083208054600019019055600982528083208785168085528184528285209588168552948352818420849055825280832093835292905281812081905590516003917ff83de021914a4585482db5ca47d520a5657165b443fa2c7ef8ed4635f054da9b91a250505050505050565b60008183614b425760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613a4d578181015183820152602001613a35565b506000838581614b4e57fe5b0495945050505050565b606081516001148015614b8a5750607f60f81b82600081518110614b7857fe5b01602001516001600160f81b03191611155b15614b96575080611211565b612fa4614ba88351608060ff16614d11565b83614c94565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416614bf257506018614c16565b6fffffffffffffffffffffffffffffffff198416614c1257506010614c16565b5060005b6020811015614c4c57818181518110614c2b57fe5b01602001516001600160f81b03191615614c4457614c4c565b600101614c16565b60008160200390506060816040519080825280601f01601f191660200182016040528015614c81576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b81831015614cc5578051835260209283019201614cad565b50855184518101855292509050808201602086015b81831015614cf2578051835260209283019201614cda565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310614d61576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411614dbb5782840160f81b81600081518110614d9d57fe5b60200101906001600160f81b031916908160001a9053509050612fa4565b6060614dc685614bae565b90508381510160370160f81b82600081518110614ddf57fe5b60200101906001600160f81b031916908160001a905350614e008282614c94565b95945050505050565b8051600090614e1a57506000611211565b6020820151805160001a9060c0821015614e3957600092505050611211565b5060019392505050565b8051600090811a6080811015614e5d576000915050611211565b60b8811080614e78575060c08110801590614e78575060f881105b15614e87576001915050611211565b60c0811015614e9b5760b519019050611211565b60f519019050611211565b80516000908190811a6080811015614ec15760019150614fd2565b60b8811015614ed657607e1981019150614fd2565b60c0811015614f5057600060b78203600186019550806020036101000a865104915060018101820193505080831015614f4a576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b50614fd2565b60f8811015614f655760be1981019150614fd2565b600060f78203600186019550806020036101000a865104915060018101820193505080831015614fd0576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b8051600090601514614fea57600080fd5b612fa482613546565b6000606061500c846402540be40063ffffffff6132bf16565b60408051600480825260a0820190925291955060609190816020015b606081526020019060019003908161502857905050905061504b8760ff16613366565b8160008151811061505857fe5b6020026020010181905250615075866001600160a01b0316613343565b8160018151811061508257fe5b602002602001018190525061509685613366565b816002815181106150a357fe5b60200260200101819052506150bd8463ffffffff16613366565b816003815181106150ca57fe5b602002602001018190525060606150e082613379565b94989497509395505050505050565b806150f9576131d4565b5b60208110615119578251825260209283019290910190601f19016150fa565b915181516020939093036101000a6000190180199091169216919091179052565b60008261514957506000612fa4565b8282028284828161515657fe5b04146132b85760405162461bcd60e51b815260040180806020018281038252602181526020018061529f6021913960400191505060405180910390fd5b60405180606001604052806003906020820280368337509192915050565b60405180604001604052806151c46151d1565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe7468652042534352656c61796572466565206d6f642074656e20646563696d616c73206d757374206265207a65726f7468652042534352656c61796572466565206d757374206265206c657373207468616e2072656c61796572466565746865206d696e44656c65676174696f6e206d7573742062652067726561746572207468616e2072656c61796572466565696e73756666696369656e742062616c616e636520616674657220726564656c6567617465536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f777468652072656c61796572466565206d6f642074656e20646563696d616c73206d757374206265207a65726f746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163747468652072656c61796572466565206d757374206265206c657373207468616e206d696e44656c65676174696f6e7468652072656c61796572466565206d757374206265206d6f7265207468616e2042534352656c61796572466565696e73756666696369656e742062616c616e636520616674657220756e64656c6567617465746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e74726163747468652042534352656c61796572466565206d757374206e6f74206265207a65726fa2646970667358221220de1a90a99417952bd5d4f424161817780a15ff9f30026401fbf3cc2b00ccc44464736f6c63430006040033", + }, + }, + } + + PlanckUpgrade[networkname.RialtoChainName] = &Upgrade{ + UpgradeName: "planck", + Configs: []*UpgradeConfig{ + { + ContractAddr: SlashContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/78e13b1d3a5a1b08c9208af94a9b14fc1efda213", + Code: "608060405234801561001057600080fd5b50600436106102535760003560e01c80637942fd0511610146578063ac431751116100c3578063dc927faf11610087578063dc927faf1461073b578063e1c7392a14610743578063f9a2bbc71461074b578063fc3e590814610753578063fc4333cd1461075b578063fd6a68791461076357610253565b8063ac431751146105cf578063c80d4b8f1461068d578063c81b166214610695578063c8509d811461069d578063c96be4cb1461071557610253565b80639dc092621161010a5780639dc0926214610593578063a1a11bf51461059b578063a78abc16146105a3578063ab51bb96146105bf578063ac0af629146105c757610253565b80637942fd05146104fb5780638256ace614610503578063831d65d11461050b57806396713da9146105835780639bc8e4f21461058b57610253565b80634bf6c882116101d45780636e47b482116101985780636e47b482146104d357806370fd5bad146104db578063718a8aa8146104e357806375d47a0a146104eb5780637912a65d146104f357610253565b80634bf6c8821461048b57806351e8067214610493578063567a372d1461049b5780635bfb4990146104a357806362b72cf5146104cb57610253565b806337c8dab91161021b57806337c8dab9146103ed578063389f4f711461042c5780633dffc3871461044657806343756e5c14610464578063493279b11461046c57610253565b80630bee7a67146102585780630e2374a5146102795780631182b8751461029d57806323bac5a21461038a57806335aa2e44146103d0575b600080fd5b61026061076b565b6040805163ffffffff9092168252519081900360200190f35b610281610770565b604080516001600160a01b039092168252519081900360200190f35b610315600480360360408110156102b357600080fd5b60ff8235169190810190604081016020820135600160201b8111156102d757600080fd5b8201836020820111156102e957600080fd5b803590602001918460018302840111600160201b8311171561030a57600080fd5b509092509050610776565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561034f578181015183820152602001610337565b50505050905090810190601f16801561037c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103b0600480360360208110156103a057600080fd5b50356001600160a01b031661084a565b604080519384526020840192909252151582820152519081900360600190f35b610281600480360360208110156103e657600080fd5b503561086d565b6104136004803603602081101561040357600080fd5b50356001600160a01b0316610894565b6040805192835260208301919091528051918290030190f35b6104346108eb565b60408051918252519081900360200190f35b61044e6108f1565b6040805160ff9092168252519081900360200190f35b6102816108f6565b6104746108fc565b6040805161ffff9092168252519081900360200190f35b61044e610902565b610281610907565b61043461090d565b6104c9600480360360208110156104b957600080fd5b50356001600160a01b0316610913565b005b610434610a74565b610281610a7a565b61044e610a80565b61044e610a85565b610281610a8a565b610434610a90565b61044e610a95565b610413610a9a565b6104c96004803603604081101561052157600080fd5b60ff8235169190810190604081016020820135600160201b81111561054557600080fd5b82018360208201111561055757600080fd5b803590602001918460018302840111600160201b8311171561057857600080fd5b509092509050610aa4565b61044e610bfe565b610434610c03565b610281610c0e565b610281610c14565b6105ab610c1a565b604080519115158252519081900360200190f35b610260610c23565b610434610c28565b6104c9600480360360408110156105e557600080fd5b810190602081018135600160201b8111156105ff57600080fd5b82018360208201111561061157600080fd5b803590602001918460018302840111600160201b8311171561063257600080fd5b919390929091602081019035600160201b81111561064f57600080fd5b82018360208201111561066157600080fd5b803590602001918460018302840111600160201b8311171561068257600080fd5b509092509050610c2d565b61043461101b565b610281611020565b6104c9600480360360408110156106b357600080fd5b60ff8235169190810190604081016020820135600160201b8111156106d757600080fd5b8201836020820111156106e957600080fd5b803590602001918460018302840111600160201b8311171561070a57600080fd5b509092509050611026565b6104c96004803603602081101561072b57600080fd5b50356001600160a01b03166110d9565b61028161165a565b6104c9611660565b6102816116d1565b61044e6116d7565b6104c96116dc565b610281611b67565b606481565b61200181565b606033612000146107b85760405162461bcd60e51b815260040180806020018281038252602f8152602001806125bf602f913960400191505060405180910390fd5b60005460ff166107fd576040805162461bcd60e51b8152602060048201526019602482015260008051602061261b833981519152604482015290519081900360640190fd5b6040805162461bcd60e51b815260206004820152601e60248201527f7265636569766520756e65787065637465642073796e207061636b6167650000604482015290519081900360640190fd5b600260208190526000918252604090912080546001820154919092015460ff1683565b6001818154811061087a57fe5b6000918252602090912001546001600160a01b0316905081565b60008061089f612483565b5050506001600160a01b0316600090815260026020818152604092839020835160608101855281548082526001830154938201849052919093015460ff16151592909301919091529091565b60055481565b600181565b61100181565b6102ca81565b600881565b61200081565b60045481565b33611000146109535760405162461bcd60e51b815260040180806020018281038252603081526020018061251a6030913960400191505060405180910390fd5b60005460ff16610998576040805162461bcd60e51b8152602060048201526019602482015260008051602061261b833981519152604482015290519081900360640190fd5b61200063f7a251d7600b6109ab84611b6d565b60006040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015610a0b5781810151838201526020016109f3565b50505050905090810190601f168015610a385780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015610a5957600080fd5b505af1158015610a6d573d6000803e3d6000fd5b5050505050565b60035481565b61100581565b600281565b601081565b61100881565b603281565b600b81565b6004546005549091565b3361200014610ae45760405162461bcd60e51b815260040180806020018281038252602f8152602001806125bf602f913960400191505060405180910390fd5b60005460ff16610b29576040805162461bcd60e51b8152602060048201526019602482015260008051602061261b833981519152604482015290519081900360640190fd5b610b316124a6565b6000610b7284848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c4092505050565b915091508015610bbc5781516040805163ffffffff9092168252517f7f0956d47419b9525356e7111652b653b530ec6f5096dccc04589bc38e6299679181900360200190a1610a6d565b81516040805163ffffffff9092168252517f7d45f62d17443dd4547bca8a8112c60e2385669318dc300ec61a5d2492f262e79181900360200190a15050505050565b600981565b662386f26fc1000081565b61100781565b61100681565b60005460ff1681565b600081565b600481565b60005460ff16610c72576040805162461bcd60e51b8152602060048201526019602482015260008051602061261b833981519152604482015290519081900360640190fd5b3361100714610cb25760405162461bcd60e51b815260040180806020018281038252602e81526020018061254a602e913960400191505060405180910390fd5b610d1d84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260148152731b5a5cd9195b59585b9bdc951a1c995cda1bdb1960621b60208201529150611cc09050565b15610df65760208114610d615760405162461bcd60e51b81526004018080602001828103825260278152602001806124f36027913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610d9f91858580838501838280828437600092019190915250611da892505050565b905060018110158015610db3575060055481105b610dee5760405162461bcd60e51b815260040180806020018281038252602581526020018061259a6025913960400191505060405180910390fd5b600455610f89565b610e5c84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e19995b1bdb9e551a1c995cda1bdb19608a1b60208201529150611cc09050565b15610f4c5760208114610ea05760405162461bcd60e51b81526004018080602001828103825260228152602001806125786022913960400191505060405180910390fd5b604080516020601f8401819004810282018101909252828152600091610ede91858580838501838280828437600092019190915250611da892505050565b90506103e88111158015610ef3575060045481115b610f44576040805162461bcd60e51b815260206004820181905260248201527f7468652066656c6f6e795468726573686f6c64206f7574206f662072616e6765604482015290519081900360640190fd5b600555610f89565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b609681565b61100281565b33612000146110665760405162461bcd60e51b815260040180806020018281038252602f8152602001806125bf602f913960400191505060405180910390fd5b60005460ff166110ab576040805162461bcd60e51b8152602060048201526019602482015260008051602061261b833981519152604482015290519081900360640190fd5b6040517f07db600eebe2ac176be8dcebad61858c245a4961bb32ca2aa3d159b09aa0810e90600090a1505050565b3341146111175760405162461bcd60e51b815260040180806020018281038252602d8152602001806125ee602d913960400191505060405180910390fd5b60005460ff1661115c576040805162461bcd60e51b8152602060048201526019602482015260008051602061261b833981519152604482015290519081900360640190fd5b60035443116111b2576040805162461bcd60e51b815260206004820181905260248201527f63616e206e6f7420736c61736820747769636520696e206f6e6520626c6f636b604482015290519081900360640190fd5b3a156111fc576040805162461bcd60e51b81526020600482015260146024820152736761737072696365206973206e6f74207a65726f60601b604482015290519081900360640190fd5b6040805163155853f360e21b81526001600160a01b03831660048201529051611000916355614fcc916024808301926020929190829003018186803b15801561124457600080fd5b505afa158015611258573d6000803e3d6000fd5b505050506040513d602081101561126e57600080fd5b505161127957611653565b611281612483565b506001600160a01b0381166000908152600260208181526040928390208351606081018552815481526001820154928101929092529091015460ff1615801592820192909252906112dc576020810180516001019052611335565b60016040820181905260208201819052805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0384161790555b43815260055460208201518161134757fe5b0661157757600060208201819052604080516335409f7f60e01b81526001600160a01b03851660048201529051611000926335409f7f926024808201939182900301818387803b15801561139a57600080fd5b505af11580156113ae573d6000803e3d6000fd5b505050506120006001600160a01b031663f7a251d7600b6113ce85611b6d565b60006040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561142e578181015183820152602001611416565b50505050905090810190601f16801561145b5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561147c57600080fd5b505af192505050801561148d575060015b611572573d8080156114bb576040519150601f19603f3d011682016040523d82523d6000602084013e6114c0565b606091505b50826001600160a01b03167fd7bc86ff5d08c8ab043edec743302aba2520e6635172a428bc956721db9e2d1c8360200151836040518083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561153557818101518382015260200161151d565b50505050905090810190601f1680156115625780820380516001836020036101000a031916815260200191505b50935050505060405180910390a2505b6115ed565b60045481602001518161158657fe5b066115ed57604080516375abf10160e11b81526001600160a01b038416600482015290516110009163eb57e20291602480830192600092919082900301818387803b1580156115d457600080fd5b505af11580156115e8573d6000803e3d6000fd5b505050505b6001600160a01b0382166000818152600260208181526040808420865181559186015160018301558581015191909201805460ff1916911515919091179055517fddb6012116e51abf5436d956a4f0ebd927e92c576ff96d7918290c8782291e3e9190a2505b5043600355565b61100381565b60005460ff16156116b8576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b603260045560966005556000805460ff19166001179055565b61100081565b600381565b336110001461171c5760405162461bcd60e51b815260040180806020018281038252603081526020018061251a6030913960400191505060405180910390fd5b60005460ff16611761576040805162461bcd60e51b8152602060048201526019602482015260008051602061261b833981519152604482015290519081900360640190fd5b60015461176d57611b65565b600154600090600019015b808211611b39576000805b8284101561189c57611793612483565b60026000600187815481106117a457fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff1615159082015260055490915060049004816020015111156118865760046005548161181157fe5b0481602001510381602001818152505080600260006001888154811061183357fe5b6000918252602080832091909101546001600160a01b0316835282810193909352604091820190208351815591830151600183015591909101516002909101805460ff1916911515919091179055611890565b600192505061189c565b50600190930192611783565b828411611a33576118ab612483565b60026000600186815481106118bc57fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff1615159082015260055490915060049004816020015111156119a45760046005548161192957fe5b0481602001510381602001818152505080600260006001878154811061194b57fe5b6000918252602080832091909101546001600160a01b03168352828101939093526040918201902083518155918301516001808401919091559201516002909101805460ff19169115159190911790559150611a339050565b60026000600186815481106119b557fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff191690558054806119f957fe5b600082815260209020810160001990810180546001600160a01b031916905501905583611a265750611a33565b506000199092019161189c565b818015611a3d5750805b15611b1c576002600060018681548110611a5357fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff19169055805484908110611a9a57fe5b600091825260209091200154600180546001600160a01b039092169186908110611ac057fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506001805480611af957fe5b600082815260209020810160001990810180546001600160a01b03191690550190555b82611b28575050611b39565b505060019091019060001901611778565b6040517fcfdb3b6ccaeccbdc68be3c59c840e3b3c90f0a7c491f5fff1cf56cfda200dd9c90600090a150505b565b61100481565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081611b88579050509050611bb1836001600160a01b0316611dad565b81600081518110611bbe57fe5b6020026020010181905250611bd243611dd0565b81600181518110611bdf57fe5b6020908102919091010152611bf56102ca611dd0565b81600281518110611c0257fe5b6020026020010181905250611c1642611dd0565b81600381518110611c2357fe5b6020026020010181905250611c3781611de3565b9150505b919050565b611c486124a6565b6000611c526124a6565b611c5a6124b8565b611c6b611c6686611e6d565b611e92565b90506000805b611c7a83611edc565b15611cb35780611ca657611c95611c9084611efd565b611f4b565b63ffffffff16845260019150611cab565b611cb3565b600101611c71565b5091935090915050915091565b6000816040516020018082805190602001908083835b60208310611cf55780518252601f199092019160209182019101611cd6565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310611d635780518252601f199092019160209182019101611d44565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490505b92915050565b015190565b60408051600560a21b8318601482015260348101909152606090611c3781612002565b6060611da2611dde83612058565b612002565b6060815160001415611e045750604080516000815260208101909152611c3b565b606082600081518110611e1357fe5b602002602001015190506000600190505b8351811015611e5457611e4a82858381518110611e3d57fe5b602002602001015161213e565b9150600101611e24565b50611c37611e67825160c060ff166121bb565b8261213e565b611e756124d8565b506040805180820190915281518152602082810190820152919050565b611e9a6124b8565b611ea3826122b3565b611eac57600080fd5b6000611ebb83602001516122ed565b60208085015160408051808201909152868152920190820152915050919050565b6000611ee66124d8565b505080518051602091820151919092015191011190565b611f056124d8565b611f0e82611edc565b611f1757600080fd5b60208201516000611f2782612350565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590611f6057508151602110155b611f6957600080fd5b6000611f7883602001516122ed565b90508083600001511015611fd3576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b825160208085015183018051928490039291831015611ff957826020036101000a820491505b50949350505050565b6060815160011480156120345750607f60f81b8260008151811061202257fe5b01602001516001600160f81b03191611155b15612040575080611c3b565b611da26120528351608060ff166121bb565b8361213e565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff19841661209c575060186120c0565b6fffffffffffffffffffffffffffffffff1984166120bc575060106120c0565b5060005b60208110156120f6578181815181106120d557fe5b01602001516001600160f81b031916156120ee576120f6565b6001016120c0565b60008160200390506060816040519080825280601f01601f19166020018201604052801561212b576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b8183101561216f578051835260209283019201612157565b50855184518101855292509050808201602086015b8183101561219c578051835260209283019201612184565b508651929092011591909101601f01601f191660405250905092915050565b606068010000000000000000831061220b576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b604080516001808252818301909252606091602082018180368337019050509050603784116122655782840160f81b8160008151811061224757fe5b60200101906001600160f81b031916908160001a9053509050611da2565b606061227085612058565b90508381510160370160f81b8260008151811061228957fe5b60200101906001600160f81b031916908160001a9053506122aa828261213e565b95945050505050565b80516000906122c457506000611c3b565b6020820151805160001a9060c08210156122e357600092505050611c3b565b5060019392505050565b8051600090811a6080811015612307576000915050611c3b565b60b8811080612322575060c08110801590612322575060f881105b15612331576001915050611c3b565b60c08110156123455760b519019050611c3b565b60f519019050611c3b565b80516000908190811a608081101561236b576001915061247c565b60b881101561238057607e198101915061247c565b60c08110156123fa57600060b78203600186019550806020036101000a8651049150600181018201935050808310156123f4576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b5061247c565b60f881101561240f5760be198101915061247c565b600060f78203600186019550806020036101000a86510491506001810182019350508083101561247a576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b604051806060016040528060008152602001600081526020016000151581525090565b60408051602081019091526000815290565b60405180604001604052806124cb6124d8565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe6c656e677468206f66206d697364656d65616e6f725468726573686f6c64206d69736d61746368746865206d6573736167652073656e646572206d7573742062652076616c696461746f7253657420636f6e7472616374746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662066656c6f6e795468726573686f6c64206d69736d61746368746865206d697364656d65616e6f725468726573686f6c64206f7574206f662072616e6765746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d6573736167652073656e646572206d7573742062652074686520626c6f636b2070726f647563657274686520636f6e7472616374206e6f7420696e69742079657400000000000000a2646970667358221220cc9198ce38d8be4b5a181b087111399299cbd68d44ed3c4d165ee1288b79e17164736f6c63430006040033", + }, + { + ContractAddr: TokenHubContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/78e13b1d3a5a1b08c9208af94a9b14fc1efda213", + Code: "6080604052600436106103c75760003560e01c806396713da9116101f2578063c81b16621161010d578063f0148472116100a0578063fc1a598f1161006f578063fc1a598f14610f25578063fc3e590814610b85578063fd6a687914610f58578063ff9c0027146107fd5761040f565b8063f014847214610ed1578063f9a2bbc714610ee6578063fa9e915914610efb578063fb063e8f14610f105761040f565b8063dc927faf116100dc578063dc927faf14610e5f578063e1c7392a14610e74578063e8f35cea14610e89578063ebf71d5314610ebc5761040f565b8063c81b166214610d8a578063c8509d8114610d9f578063cf41984414610e24578063d9e6dae91461077f5761040f565b8063aa7415f511610185578063b9fd21e311610154578063b9fd21e314610cfa578063ba35ead614610d0f578063bbface1f14610d24578063bd46646114610d575761040f565b8063aa7415f514610b9a578063ab51bb9614610be1578063ac43175114610bf6578063b99328c514610cc15761040f565b8063a1a11bf5116101c1578063a1a11bf514610b46578063a496fba214610b5b578063a78abc1614610b70578063a7c9f02d14610b855761040f565b806396713da914610ace5780639a854bbd14610ae35780639a99b4f014610af85780639dc0926214610b315761040f565b806359b92789116102e257806371d3086311610275578063831d65d111610244578063831d65d1146109d15780638b87b21f146106d45780638eff336c14610a565780639509b98014610a955761040f565b806371d3086314610968578063727be1f81461097d57806375d47a0a146109a75780637942fd05146109bc5761040f565b80636e056520116102b15780636e056520146108125780636e47b4821461093e57806370fd5bad146107fd578063718a8aa8146109535761040f565b806359b92789146107be5780635d499b1b146107e8578063613684751461077f57806366dea52a146107fd5761040f565b80633fd8b02f1161035a5780634a3acdf4116103295780634a3acdf41461076a5780634bf6c8821461077f57806350432d321461079457806351e80672146107a95761040f565b80633fd8b02f146106ff57806343756e5c1461071457806343a368b914610729578063493279b11461073e5761040f565b8063149d14d911610396578063149d14d9146105a85780632ae45483146105cf5780633d713223146106235780633dffc387146106d45761040f565b80630bee7a67146104145780630e2374a5146104425780631182b87514610473578063122345821461056d5761040f565b3661040f57341561040d576040805133815234602082015281517f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db929181900390910190a15b005b600080fd5b34801561042057600080fd5b50610429610f6d565b6040805163ffffffff9092168252519081900360200190f35b34801561044e57600080fd5b50610457610f72565b604080516001600160a01b039092168252519081900360200190f35b34801561047f57600080fd5b506104f86004803603604081101561049657600080fd5b60ff8235169190810190604081016020820135600160201b8111156104ba57600080fd5b8201836020820111156104cc57600080fd5b803590602001918460018302840111600160201b831117156104ed57600080fd5b509092509050610f78565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561053257818101518382015260200161051a565b50505050905090810190601f16801561055f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561057957600080fd5b5061040d6004803603604081101561059057600080fd5b506001600160a01b03813581169160200135166110a6565b3480156105b457600080fd5b506105bd6111a0565b60408051918252519081900360200190f35b3480156105db57600080fd5b5061060a600480360360408110156105f257600080fd5b506001600160a01b03813581169160200135166111a6565b6040805192835260208301919091528051918290030190f35b34801561062f57600080fd5b506104576004803603602081101561064657600080fd5b810190602081018135600160201b81111561066057600080fd5b82018360208201111561067257600080fd5b803590602001918460018302840111600160201b8311171561069357600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506111ca945050505050565b3480156106e057600080fd5b506106e96111ee565b6040805160ff9092168252519081900360200190f35b34801561070b57600080fd5b506105bd6111f3565b34801561072057600080fd5b506104576111f9565b34801561073557600080fd5b506105bd6111ff565b34801561074a57600080fd5b5061075361120b565b6040805161ffff9092168252519081900360200190f35b34801561077657600080fd5b506105bd611211565b34801561078b57600080fd5b506106e9611217565b3480156107a057600080fd5b506105bd61121c565b3480156107b557600080fd5b50610457611227565b3480156107ca57600080fd5b50610457600480360360208110156107e157600080fd5b503561122d565b3480156107f457600080fd5b506105bd611248565b34801561080957600080fd5b506106e9611251565b61092a6004803603608081101561082857600080fd5b810190602081018135600160201b81111561084257600080fd5b82018360208201111561085457600080fd5b803590602001918460208302840111600160201b8311171561087557600080fd5b919390929091602081019035600160201b81111561089257600080fd5b8201836020820111156108a457600080fd5b803590602001918460208302840111600160201b831117156108c557600080fd5b919390929091602081019035600160201b8111156108e257600080fd5b8201836020820111156108f457600080fd5b803590602001918460208302840111600160201b8311171561091557600080fd5b91935091503567ffffffffffffffff16611256565b604080519115158252519081900360200190f35b34801561094a57600080fd5b5061045761172b565b34801561095f57600080fd5b506106e9611731565b34801561097457600080fd5b506105bd611736565b34801561098957600080fd5b5061092a600480360360208110156109a057600080fd5b503561173c565b3480156109b357600080fd5b506104576117bd565b3480156109c857600080fd5b506106e96117c3565b3480156109dd57600080fd5b5061040d600480360360408110156109f457600080fd5b60ff8235169190810190604081016020820135600160201b811115610a1857600080fd5b820183602082011115610a2a57600080fd5b803590602001918460018302840111600160201b83111715610a4b57600080fd5b5090925090506117c8565b348015610a6257600080fd5b5061040d60048036036060811015610a7957600080fd5b508035906001600160a01b036020820135169060400135611911565b348015610aa157600080fd5b5061040d60048036036040811015610ab857600080fd5b506001600160a01b038135169060200135611997565b348015610ada57600080fd5b506106e9611b54565b348015610aef57600080fd5b506105bd611b59565b348015610b0457600080fd5b506105bd60048036036040811015610b1b57600080fd5b506001600160a01b038135169060200135611b65565b348015610b3d57600080fd5b50610457611ca3565b348015610b5257600080fd5b50610457611ca9565b348015610b6757600080fd5b506106e9611caf565b348015610b7c57600080fd5b5061092a611cb4565b348015610b9157600080fd5b506106e9611cbd565b61092a60048036036080811015610bb057600080fd5b5080356001600160a01b03908116916020810135909116906040810135906060013567ffffffffffffffff16611cc2565b348015610bed57600080fd5b50610429611caf565b348015610c0257600080fd5b5061040d60048036036040811015610c1957600080fd5b810190602081018135600160201b811115610c3357600080fd5b820183602082011115610c4557600080fd5b803590602001918460018302840111600160201b83111715610c6657600080fd5b919390929091602081019035600160201b811115610c8357600080fd5b820183602082011115610c9557600080fd5b803590602001918460018302840111600160201b83111715610cb657600080fd5b509092509050612383565b348015610ccd57600080fd5b5061040d60048036036040811015610ce457600080fd5b50803590602001356001600160a01b031661282b565b348015610d0657600080fd5b506105bd6128a1565b348015610d1b57600080fd5b506105bd6128ab565b348015610d3057600080fd5b506105bd60048036036020811015610d4757600080fd5b50356001600160a01b03166128b1565b348015610d6357600080fd5b506105bd60048036036020811015610d7a57600080fd5b50356001600160a01b03166128c3565b348015610d9657600080fd5b506104576128de565b348015610dab57600080fd5b5061040d60048036036040811015610dc257600080fd5b60ff8235169190810190604081016020820135600160201b811115610de657600080fd5b820183602082011115610df857600080fd5b803590602001918460018302840111600160201b83111715610e1957600080fd5b5090925090506128e4565b348015610e3057600080fd5b5061040d60048036036040811015610e4757600080fd5b506001600160a01b03813581169160200135166129b4565b348015610e6b57600080fd5b50610457612c88565b348015610e8057600080fd5b5061040d612c8e565b348015610e9557600080fd5b506105bd60048036036020811015610eac57600080fd5b50356001600160a01b0316612d2e565b348015610ec857600080fd5b506106e9612d40565b348015610edd57600080fd5b506106e9612d45565b348015610ef257600080fd5b50610457612d4a565b348015610f0757600080fd5b506105bd612d50565b348015610f1c57600080fd5b506105bd612d56565b348015610f3157600080fd5b506104f860048036036020811015610f4857600080fd5b50356001600160a01b0316612d64565b348015610f6457600080fd5b50610457612e8b565b606481565b61200181565b60005460609060ff16610fc0576040805162461bcd60e51b81526020600482015260196024820152600080516020615583833981519152604482015290519081900360640190fd5b33612000146110005760405162461bcd60e51b815260040180806020018281038252602f815260200180615531602f913960400191505060405180910390fd5b60ff8416600214156110525761104b83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612e9192505050565b905061109f565b6040805162461bcd60e51b815260206004820152601860248201527f756e7265636f676e697a65642073796e207061636b6167650000000000000000604482015290519081900360640190fd5b9392505050565b33612000146110e65760405162461bcd60e51b815260040180806020018281038252602f815260200180615531602f913960400191505060405180910390fd5b6001600160a01b0380831660009081526007602090815260408083209385168352929052208054611151576040805162461bcd60e51b815260206004820152601060248201526f1b9bc81b1bd8dad95908185b5bdd5b9d60821b604482015290519081900360640190fd5b8054600082556040805182815290516001600160a01b0380861692908716917f152fb15aa5d80f843e1e4bd5f2fc9161714f169945024decec7e84fb910fdd519181900360200190a350505050565b60015490565b60076020908152600092835260408084209091529082529020805460019091015482565b6020818101516000908152600490915260409020546001600160a01b03165b919050565b600181565b60055481565b61100181565b670de0b6b3a764000081565b6102ca81565b61a8c081565b600881565b66071afd498d000081565b61200081565b6000908152600460205260409020546001600160a01b031690565b6402540be40081565b600281565b6000805460ff1661129c576040805162461bcd60e51b81526020600482015260196024820152600080516020615583833981519152604482015290519081900360640190fd5b8685146112da5760405162461bcd60e51b815260040180806020018281038252603b8152602001806154f6603b913960400191505060405180910390fd5b8683146113185760405162461bcd60e51b815260040180806020018281038252603f8152602001806153c9603f913960400191505060405180910390fd5b426078018267ffffffffffffffff1610156113645760405162461bcd60e51b81526004018080602001828103825260248152602001806152b96024913960400191505060405180910390fd5b6402540be4003406156113a85760405162461bcd60e51b81526004018080602001828103825260408152602001806155f96040913960400191505060405180910390fd5b604080518681526020808802820101909152859060009081906060908480156113db578160200160208202803683370190505b50905060005b848110156114b6576402540be4008b8b838181106113fb57fe5b905060200201358161140957fe5b06156114465760405162461bcd60e51b815260040180806020018281038252603c815260200180615408603c913960400191505060405180910390fd5b61146b8b8b8381811061145557fe5b9050602002013585612fb590919063ffffffff16565b93506114976402540be4008c8c8481811061148257fe5b9050602002013561300f90919063ffffffff16565b8282815181106114a357fe5b60209081029190910101526001016113e1565b506001546114db906114ce908663ffffffff61305116565b849063ffffffff612fb516565b3410156115195760405162461bcd60e51b81526004018080602001828103825260568152602001806155a36056913960600191505060405180910390fd5b611529348463ffffffff6130aa16565b91506115336150bd565b6040518060c001604052806221272160e91b60001b815260200160006001600160a01b031681526020018381526020018e8e808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050908252506040805160208c810282810182019093528c82529283019290918d918d91829185019084908082843760009201919091525050509082525067ffffffffffffffff8916602090910152905061200063f7a251d760036115f7846130ec565b61160c876402540be40063ffffffff61300f16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561166a578181015183820152602001611652565b50505050905090810190601f1680156116975780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156116b857600080fd5b505af11580156116cc573d6000803e3d6000fd5b505060408051600081523360208201528082018890526060810187905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9350908190036080019150a15060019c9b505050505050505050505050565b61100581565b601081565b60015481565b6000336120011461177e5760405162461bcd60e51b81526004018080602001828103825260338152602001806151d76033913960400191505060405180910390fd5b81156117b5576040516120019083156108fc029084906000818181858888f193505050501580156117b3573d6000803e3d6000fd5b505b506001919050565b61100881565b600b81565b60005460ff1661180d576040805162461bcd60e51b81526020600482015260196024820152600080516020615583833981519152604482015290519081900360640190fd5b336120001461184d5760405162461bcd60e51b815260040180806020018281038252602f815260200180615531602f913960400191505060405180910390fd5b60ff83166003141561189d5761189882828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506133a792505050565b61190c565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a15b505050565b33611008146119515760405162461bcd60e51b81526004018080602001828103825260238152602001806155606023913960400191505060405180910390fd5b600083815260046020908152604080832080546001600160a01b039096166001600160a01b03199096168617905593825260038152838220949094556002909352912055565b81806001600160a01b031663893d20e86040518163ffffffff1660e01b815260040160206040518083038186803b1580156119d157600080fd5b505afa1580156119e5573d6000803e3d6000fd5b505050506040513d60208110156119fb57600080fd5b50516001600160a01b03163314611a59576040805162461bcd60e51b815260206004820152601860248201527f6e6f74206f776e6572206f6620424550323020746f6b656e0000000000000000604482015290519081900360640190fd5b60008211611aa7576040805162461bcd60e51b81526020600482015260166024820152751e995c9bc81b1a5b5a5d081b9bdd08185b1b1bddd95960521b604482015290519081900360640190fd5b6001600160a01b038316600090815260036020526040902054611afd576040805162461bcd60e51b81526020600482015260096024820152681b9bdd08189bdd5b9960ba1b604482015290519081900360640190fd5b6001600160a01b038316600081815260066020908152604091829020859055815185815291513393927f9df3a90730dbf23b5cc18dbbd5f4af3fa94a0dffb6ff6841f98a9a9a6ac626a892908290030190a3505050565b600981565b677ce66c50e284000081565b6000805460ff16611bab576040805162461bcd60e51b81526020600482015260196024820152600080516020615583833981519152604482015290519081900360640190fd5b3361100514611beb5760405162461bcd60e51b815260040180806020018281038252602f81526020018061520a602f913960400191505060405180910390fd5b6000478310611bfa5747611bfc565b825b9050670de0b6b3a7640000811115611c18576000915050611c9d565b8015611c9a576040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015611c54573d6000803e3d6000fd5b50604080516001600160a01b03861681526020810183905281517ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0929181900390910190a15b90505b92915050565b61100781565b61100681565b600081565b60005460ff1681565b600381565b6000805460ff16611d08576040805162461bcd60e51b81526020600482015260196024820152600080516020615583833981519152604482015290519081900360640190fd5b426078018267ffffffffffffffff161015611d545760405162461bcd60e51b81526004018080602001828103825260248152602001806152b96024913960400191505060405180910390fd5b6402540be400340615611d985760405162461bcd60e51b81526004018080602001828103825260408152602001806155f96040913960400191505060405180910390fd5b600080806001600160a01b038816611e7757600154611dbe90879063ffffffff612fb516565b341015611dfc5760405162461bcd60e51b81526004018080602001828103825260618152602001806153436061913960800191505060405180910390fd5b6402540be400860615611e405760405162461bcd60e51b815260040180806020018281038252603c815260200180615408603c913960400191505060405180910390fd5b611e50348763ffffffff6130aa16565b9050611e67866402540be40063ffffffff61300f16565b6221272160e91b9350915061211a565b6001600160a01b038816600090815260036020526040902054925082611ece5760405162461bcd60e51b81526004018080602001828103825260318152602001806153126031913960400191505060405180910390fd5b600154341015611f0f5760405162461bcd60e51b815260040180806020018281038252603f815260200180615465603f913960400191505060405180910390fd5b506001600160a01b0387166000908152600260205260409020543490600881111580611f5a5750600881118015611f5a5750611f58876007198301600a0a63ffffffff61340316565b155b611f955760405162461bcd60e51b815260040180806020018281038252603c815260200180615408603c913960400191505060405180910390fd5b611f9f8782613445565b9250611faa84613485565b15611ff2576305f5e100831015611ff25760405162461bcd60e51b815260040180806020018281038252603a81526020018061525b603a913960400191505060405180910390fd5b60088110158061200c575060088110801561200c57508683115b6120475760405162461bcd60e51b81526004018080602001828103825260258152602001806153a46025913960400191505060405180910390fd5b677ce66c50e284000083111561208e5760405162461bcd60e51b81526004018080602001828103825260358152602001806152dd6035913960400191505060405180910390fd5b604080516323b872dd60e01b81523360048201523060248201526044810189905290516001600160a01b038b16916323b872dd9160648083019260209291908290030181600087803b1580156120e357600080fd5b505af11580156120f7573d6000803e3d6000fd5b505050506040513d602081101561210d57600080fd5b505161211857600080fd5b505b6121226150bd565b6040805160c0810182528581526001600160a01b038b166020820152815160018082528184018452919283019181602001602082028036833750505081526040805160018082528183019092526020928301929091908083019080368337505050815260408051600180825281830190925260209283019290919080830190803683370190505081526020018767ffffffffffffffff1681525090508281604001516000815181106121d057fe5b6020026020010181815250508781606001516000815181106121ee57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505033816080015160008151811061222057fe5b6001600160a01b039092166020928302919091019091015261200063f7a251d7600361224b846130ec565b612260866402540be40063ffffffff61300f16565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b838110156122be5781810151838201526020016122a6565b50505050905090810190601f1680156122eb5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561230c57600080fd5b505af1158015612320573d6000803e3d6000fd5b5050604080516001600160a01b038d1681523360208201528082018b90526060810186905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9350908190036080019150a150600198975050505050505050565b33611007146123c35760405162461bcd60e51b815260040180806020018281038252602e8152602001806154a4602e913960400191505060405180910390fd5b60208114612418576040805162461bcd60e51b815260206004820152601b60248201527f65787065637465642076616c7565206c656e6774682069732033320000000000604482015290519081900360640190fd5b606084848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8801819004810282018101909252868152939450606093925086915085908190840183828082843760009201919091525050505060208301519091506772656c617946656560c01b811415612520576020820151670de0b6b3a764000081118015906124c757506402540be4008106155b612518576040805162461bcd60e51b815260206004820152601960248201527f7468652072656c6179466565206f7574206f662072616e676500000000000000604482015290519081900360640190fd5b600155612796565b61259487878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601781527f6c617267655472616e736665724c6f636b506572696f640000000000000000006020820152915061358b9050565b1561263057604080516020601f87018190048102820181019092528581526000916125d79188888083850183828082843760009201919091525061367292505050565b905062093a80811115612628576040805162461bcd60e51b81526020600482015260146024820152736c6f636b20706572696f6420746f6f206c6f6e6760601b604482015290519081900360640190fd5b600555612796565b61269c87878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526015815274189b9893185c99d9551c985b9cd9995c931a5b5a5d605a1b6020820152915061358b9050565b1561275957604080516020601f87018190048102820181019092528581526000916126df9188888083850183828082843760009201919091525061367292505050565b905068056bc75e2d631000008110156127295760405162461bcd60e51b81526004018080602001828103825260228152602001806152396022913960400191505060405180910390fd5b6000805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f855612796565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a878787876040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050505050565b336110081461286b5760405162461bcd60e51b81526004018080602001828103825260238152602001806155606023913960400191505060405180910390fd5b600091825260046020908152604080842080546001600160a01b03191690556001600160a01b0392909216835260039052812055565b6221272160e91b81565b61c35081565b60026020526000908152604090205481565b6001600160a01b031660009081526003602052604090205490565b61100281565b60005460ff16612929576040805162461bcd60e51b81526020600482015260196024820152600080516020615583833981519152604482015290519081900360640190fd5b33612000146129695760405162461bcd60e51b815260040180806020018281038252602f815260200180615531602f913960400191505060405180910390fd5b60ff83166003141561189d5761189882828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061367792505050565b60085460ff1660021415612a00576040805162461bcd60e51b815260206004820152600e60248201526d4e6f2072652d656e7472616e637960901b604482015290519081900360640190fd5b6008805460ff191660021790556001600160a01b0380831660009081526007602090815260408083209385168352929052208054612a78576040805162461bcd60e51b815260206004820152601060248201526f1b9bc81b1bd8dad95908185b5bdd5b9d60821b604482015290519081900360640190fd5b8060010154421015612ad1576040805162461bcd60e51b815260206004820152601760248201527f7374696c6c206f6e206c6f636b696e6720706572696f64000000000000000000604482015290519081900360640190fd5b805460008083556001600160a01b038516612b44576040516001600160a01b038516906127109084906000818181858888f193505050503d8060008114612b34576040519150601f19603f3d011682016040523d82523d6000602084013e612b39565b606091505b505080915050612bd7565b846001600160a01b031663a9059cbb61c35086856040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b158015612ba757600080fd5b5087f1158015612bbb573d6000803e3d6000fd5b50505050506040513d6020811015612bd257600080fd5b505190505b80612c29576040805162461bcd60e51b815260206004820152601e60248201527f776974686472617720756e6c6f636b656420746f6b656e206661696c65640000604482015290519081900360640190fd5b836001600160a01b0316856001600160a01b03167f832fc3e25f2b3e6fb0eb59419a73cba405f2a249fce75f7e31ea5a457a0323f1846040518082815260200191505060405180910390a350506008805460ff19166001179055505050565b61100381565b60005460ff1615612ce6576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b66071afd498d000060019081556000808052600260205260127fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b55805460ff19169091179055565b60066020526000908152604090205481565b600481565b600581565b61100081565b61271081565b69021e19e0c9bab240000081565b6001600160a01b03811660009081526003602090815260409182902054825182815280840190935260609290918391906020820181803683375050506020810183905290506000805b60208160ff161015612df457828160ff1681518110612dc857fe5b01602001516001600160f81b03191615612de757600190910190612dec565b612df4565b600101612dad565b5060608160ff166040519080825280601f01601f191660200182016040528015612e25576020820181803683370190505b50905060005b8260ff168160ff161015612e8157838160ff1681518110612e4857fe5b602001015160f81c60f81b828260ff1681518110612e6257fe5b60200101906001600160f81b031916908160001a905350600101612e2b565b5095945050505050565b61100481565b6060612e9b615109565b6000612ea684613775565b9150915080612efc576040805162461bcd60e51b815260206004820152601f60248201527f756e7265636f676e697a6564207472616e73666572496e207061636b61676500604482015290519081900360640190fd5b6000612f07836138b4565b905063ffffffff811615612f9b576040808401516020808601516001600160a01b03166000908152600290915291822054612f429190613445565b9050612f4c61513e565b60405180608001604052808660000151815260200183815260200186608001516001600160a01b031681526020018463ffffffff168152509050612f8f81613c1a565b955050505050506111e9565b505060408051600081526020810190915291506111e99050565b600082820183811015611c9a576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000611c9a83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613cf6565b60008261306057506000611c9d565b8282028284828161306d57fe5b0414611c9a5760405162461bcd60e51b81526004018080602001828103825260218152602001806154446021913960400191505060405180910390fd5b6000611c9a83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613d98565b60408051600680825260e08201909252606091829190816020015b6060815260200190600190039081613107575050835190915061312990613df2565b8160008151811061313657fe5b602002602001018190525061315783602001516001600160a01b0316613e05565b8160018151811061316457fe5b6020026020010181905250600083604001515190506060816040519080825280602002602001820160405280156131af57816020015b606081526020019060019003908161319a5790505b50905060005b828110156131fc576131dd866040015182815181106131d057fe5b6020026020010151613df2565b8282815181106131e957fe5b60209081029190910101526001016131b5565b5061320681613e28565b8360028151811061321357fe5b602002602001018190525060608260405190808252806020026020018201604052801561325457816020015b606081526020019060019003908161323f5790505b50905060005b838110156132aa5761328b8760600151828151811061327557fe5b60200260200101516001600160a01b0316613e05565b82828151811061329757fe5b602090810291909101015260010161325a565b506132b481613e28565b846003815181106132c157fe5b602002602001018190525060608360405190808252806020026020018201604052801561330257816020015b60608152602001906001900390816132ed5790505b50905060005b84811015613342576133238860800151828151811061327557fe5b82828151811061332f57fe5b6020908102919091010152600101613308565b5061334c81613e28565b8560048151811061335957fe5b602002602001018190525061337b8760a0015167ffffffffffffffff16613df2565b8560058151811061338857fe5b602002602001018190525061339c85613e28565b979650505050505050565b6133af615165565b60006133ba83613eb2565b91509150806133fa5760405162461bcd60e51b81526004018080602001828103825260248152602001806154d26024913960400191505060405180910390fd5b61190c8261407d565b6000611c9a83836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815250614501565b6000600882111561346e57613467836007198401600a0a63ffffffff61300f16565b9050611c9d565b611c9a836008849003600a0a63ffffffff61305116565b604080516020808252818301909252600091606091906020820181803683375050506020810184905290506000805b60208160ff1610156134fb57828160ff16815181106134cf57fe5b01602001516001600160f81b031916156134ee576001909101906134f3565b6134fb565b6001016134b4565b50600760ff82161015613513576000925050506111e9565b816005820360ff168151811061352557fe5b6020910101516001600160f81b031916602d60f81b1461354a576000925050506111e9565b816001820360ff168151811061355c57fe5b6020910101516001600160f81b031916604d60f81b14613581576000925050506111e9565b5060019392505050565b6000816040516020018082805190602001908083835b602083106135c05780518252601f1990920191602091820191016135a1565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b6020831061362e5780518252601f19909201916020918201910161360f565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b61367f6150bd565b600061368a83614563565b91509150806136ca5760405162461bcd60e51b81526004018080602001828103825260248152602001806152956024913960400191505060405180910390fd5b6136d2615165565b602080840180516001600160a01b0390811684526040808701518585015291511660009081526002909252812054905b846040015151811015613753576137308560400151828151811061372257fe5b6020026020010151836147c7565b8560400151828151811061374057fe5b6020908102919091010152600101613702565b50608084015160408301526005606083015261376e8261407d565b5050505050565b61377d615109565b6000613787615109565b61378f61519c565b6137a061379b86614800565b614825565b90506000805b6137af8361486f565b156138a757806137d1576137ca6137c584614890565b6148de565b845261389f565b80600114156137fe576137eb6137e684614890565b614995565b6001600160a01b0316602085015261389f565b806002141561381d576138136137c584614890565b604085015261389f565b8060031415613845576138326137e684614890565b6001600160a01b0316606085015261389f565b806004141561386d5761385a6137e684614890565b6001600160a01b0316608085015261389f565b806005141561389a576138826137c584614890565b67ffffffffffffffff1660a08501526001915061389f565b6138a7565b6001016137a6565b5091935090915050915091565b60208101516000906001600160a01b03166139f8578160a0015167ffffffffffffffff164211156138e7575060016111e9565b81604001514710156138fb575060036111e9565b613904826149af565b61397957606082015160408084015190516000926001600160a01b0316916127109184818181858888f193505050503d806000811461395f576040519150601f19603f3d011682016040523d82523d6000602084013e613964565b606091505b50509050806139775750600490506111e9565b505b7f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5982602001518360600151846040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a15060006111e9565b8160a0015167ffffffffffffffff16421115613a16575060016111e9565b81516020808401516001600160a01b031660009081526003909152604090205414613a43575060026111e9565b602080830151604080516370a0823160e01b815230600482015290516000936001600160a01b03909316926370a082319261c3509260248083019392829003018187803b158015613a9357600080fd5b5086fa158015613aa7573d6000803e3d6000fd5b50505050506040513d6020811015613abe57600080fd5b50516040840151909150811015613ad95750600390506111e9565b613ae2836149af565b613b9957600083602001516001600160a01b031663a9059cbb61c350866060015187604001516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b158015613b5757600080fd5b5087f1158015613b6b573d6000803e3d6000fd5b50505050506040513d6020811015613b8257600080fd5b5051905080613b975750600591506111e99050565b505b7f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5983602001518460600151856040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a150600090506111e9565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081613c355750508351909150613c5790613df2565b81600081518110613c6457fe5b6020026020010181905250613c7c8360200151613df2565b81600181518110613c8957fe5b6020026020010181905250613caa83604001516001600160a01b0316613e05565b81600281518110613cb757fe5b6020026020010181905250613cd5836060015163ffffffff16613df2565b81600381518110613ce257fe5b602002602001018190525061109f81613e28565b60008183613d825760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613d47578181015183820152602001613d2f565b50505050905090810190601f168015613d745780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581613d8e57fe5b0495945050505050565b60008184841115613dea5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613d47578181015183820152602001613d2f565b505050900390565b6060611c9d613e0083614b1d565b614c03565b60408051600560a21b831860148201526034810190915260609061109f81614c03565b6060815160001415613e4957506040805160008152602081019091526111e9565b606082600081518110613e5857fe5b602002602001015190506000600190505b8351811015613e9957613e8f82858381518110613e8257fe5b6020026020010151614c55565b9150600101613e69565b5061109f613eac825160c060ff16614cd2565b82614c55565b613eba615165565b6000613ec4615165565b613ecc61519c565b613ed861379b86614800565b90506000805b613ee78361486f565b156138a75780613f0d57613efd6137e684614890565b6001600160a01b03168452614075565b8060011415613fae576060613f29613f2485614890565b614dca565b90508051604051908082528060200260200182016040528015613f56578160200160208202803683370190505b50602086015260005b8151811015613fa757613f84828281518110613f7757fe5b60200260200101516148de565b86602001518281518110613f9457fe5b6020908102919091010152600101613f5f565b5050614075565b8060021415614050576060613fc5613f2485614890565b90508051604051908082528060200260200182016040528015613ff2578160200160208202803683370190505b50604086015260005b8151811015613fa75761402082828151811061401357fe5b6020026020010151614995565b8660400151828151811061403057fe5b6001600160a01b0390921660209283029190910190910152600101613ffb565b806003141561389a576140656137c584614890565b63ffffffff166060850152600191505b600101613ede565b80516001600160a01b03166142a75760005b8160200151518110156142a1576000826040015182815181106140ae57fe5b60200260200101516001600160a01b0316612710846020015184815181106140d257fe5b60209081029190910101516040516000818181858888f193505050503d806000811461411a576040519150601f19603f3d011682016040523d82523d6000602084013e61411f565b606091505b50509050806141e2577f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e83600001518460400151848151811061415e57fe5b60200260200101518560200151858151811061417657fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a1614298565b7fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a83600001518460400151848151811061421857fe5b60200260200101518560200151858151811061423057fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b5060010161408f565b506144fe565b60005b8160200151518110156144fc57600082600001516001600160a01b031663a9059cbb61c350856040015185815181106142df57fe5b6020026020010151866020015186815181106142f757fe5b60200260200101516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b15801561434e57600080fd5b5087f1158015614362573d6000803e3d6000fd5b50505050506040513d602081101561437957600080fd5b50519050801561443d577fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a8360000151846040015184815181106143b957fe5b6020026020010151856020015185815181106143d157fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a16144f3565b7f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e83600001518460400151848151811061447357fe5b60200260200101518560200151858151811061448b57fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b506001016142aa565b505b50565b600081836145505760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613d47578181015183820152602001613d2f565b5082848161455a57fe5b06949350505050565b61456b6150bd565b60006145756150bd565b61457d61519c565b61458961379b86614800565b90506000805b6145988361486f565b156138a757806145b5576145ae6137c584614890565b84526147bf565b80600114156145dd576145ca6137e684614890565b6001600160a01b031660208501526147bf565b806002141561466c5760606145f4613f2485614890565b90508051604051908082528060200260200182016040528015614621578160200160208202803683370190505b50604086015260005b815181101561466557614642828281518110613f7757fe5b8660400151828151811061465257fe5b602090810291909101015260010161462a565b50506147bf565b8060031415614701576060614683613f2485614890565b905080516040519080825280602002602001820160405280156146b0578160200160208202803683370190505b50606086015260005b8151811015614665576146d182828151811061401357fe5b866060015182815181106146e157fe5b6001600160a01b03909216602092830291909101909101526001016146b9565b8060041415614796576060614718613f2485614890565b90508051604051908082528060200260200182016040528015614745578160200160208202803683370190505b50608086015260005b81518110156146655761476682828151811061401357fe5b8660800151828151811061477657fe5b6001600160a01b039092166020928302919091019091015260010161474e565b806005141561389a576147ab6137c584614890565b67ffffffffffffffff1660a0850152600191505b60010161458f565b600060088211156147e957613467836007198401600a0a63ffffffff61305116565b611c9a836008849003600a0a63ffffffff61300f16565b6148086151bc565b506040805180820190915281518152602082810190820152919050565b61482d61519c565b61483682614e9b565b61483f57600080fd5b600061484e8360200151614ecb565b60208085015160408051808201909152868152920190820152915050919050565b60006148796151bc565b505080518051602091820151919092015191011190565b6148986151bc565b6148a18261486f565b6148aa57600080fd5b602082015160006148ba82614f2e565b80830160209586015260408051808201909152908152938401919091525090919050565b8051600090158015906148f357508151602110155b6148fc57600080fd5b600061490b8360200151614ecb565b90508083600001511015614966576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b82516020808501518301805192849003929183101561498c57826020036101000a820491505b50949350505050565b80516000906015146149a657600080fd5b611c9d826148de565b600080805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f8541580156149e85750600554155b15614a2a5760008052600660205269021e19e0c9bab24000007f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f85561a8c06005555b6020808301516001600160a01b0316600090815260069091526040902054801580614a585750808360400151105b15614a675760009150506111e9565b6020808401516001600160a01b039081166000908152600783526040808220606088015190931682529190925290819020908401518154614aad9163ffffffff612fb516565b8155600554420160018201819055606085015160208087015160408089015181519081529283019490945283516001600160a01b039384169493909116927f3fb83143cd331170da18fb1e8564d97e8ec39264b6ecb1ba248ea7596ab07258928290030190a35060019392505050565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416614b6157506018614b85565b6fffffffffffffffffffffffffffffffff198416614b8157506010614b85565b5060005b6020811015614bbb57818181518110614b9a57fe5b01602001516001600160f81b03191615614bb357614bbb565b600101614b85565b60008160200390506060816040519080825280601f01601f191660200182016040528015614bf0576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015614c355750607f60f81b82600081518110614c2357fe5b01602001516001600160f81b03191611155b15614c415750806111e9565b611c9d614c538351608060ff16614cd2565b835b6060806040519050835180825260208201818101602087015b81831015614c86578051835260209283019201614c6e565b50855184518101855292509050808201602086015b81831015614cb3578051835260209283019201614c9b565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310614d22576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411614d7c5782840160f81b81600081518110614d5e57fe5b60200101906001600160f81b031916908160001a9053509050611c9d565b6060614d8785614b1d565b90508381510160370160f81b82600081518110614da057fe5b60200101906001600160f81b031916908160001a905350614dc18282614c55565b95945050505050565b6060614dd582614e9b565b614dde57600080fd5b6000614de983615061565b9050606081604051908082528060200260200182016040528015614e2757816020015b614e146151bc565b815260200190600190039081614e0c5790505b5090506000614e398560200151614ecb565b60208601510190506000805b84811015614e9057614e5683614f2e565b9150604051806040016040528083815260200184815250848281518110614e7957fe5b602090810291909101015291810191600101614e45565b509195945050505050565b8051600090614eac575060006111e9565b6020820151805160001a9060c0821015613581576000925050506111e9565b8051600090811a6080811015614ee55760009150506111e9565b60b8811080614f00575060c08110801590614f00575060f881105b15614f0f5760019150506111e9565b60c0811015614f235760b5190190506111e9565b60f5190190506111e9565b80516000908190811a6080811015614f49576001915061505a565b60b8811015614f5e57607e198101915061505a565b60c0811015614fd857600060b78203600186019550806020036101000a865104915060018101820193505080831015614fd2576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b5061505a565b60f8811015614fed5760be198101915061505a565b600060f78203600186019550806020036101000a865104915060018101820193505080831015615058576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b8051600090615072575060006111e9565b600080905060006150868460200151614ecb565b602085015185519181019250015b808210156150b4576150a582614f2e565b60019093019290910190615094565b50909392505050565b6040518060c001604052806000801916815260200160006001600160a01b03168152602001606081526020016060815260200160608152602001600067ffffffffffffffff1681525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b60408051608081018252600080825260208201819052918101829052606081019190915290565b604051806080016040528060006001600160a01b031681526020016060815260200160608152602001600063ffffffff1681525090565b60405180604001604052806151af6151bc565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe6f6e6c79207374616b696e672073797374656d20636f6e74726163742063616e2063616c6c20746869732066756e6374696f6e746865206d6573736167652073656e646572206d75737420626520696e63656e746976697a6520636f6e7472616374626e62206c61726765207472616e73666572206c696d697420746f6f20736d616c6c466f72206d696e69546f6b656e2c20746865207472616e7366657220616d6f756e74206d757374206e6f74206265206c657373207468616e2031756e7265636f676e697a6564207472616e736665724f75742073796e207061636b61676565787069726554696d65206d7573742062652074776f206d696e75746573206c61746572616d6f756e7420697320746f6f206c617267652c20657863656564206d6178696d756d206265703220746f6b656e20616d6f756e7474686520636f6e747261637420686173206e6f74206265656e20626f756e6420746f20616e79206265703220746f6b656e726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e736665724f757420424e4220616d6f756e7420616e64206d696e696d756d2072656c6179466565616d6f756e7420697320746f6f206c617267652c2075696e74323536206f766572666c6f774c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620726566756e644164647273696e76616c6964207472616e7366657220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e20746865206d696e696d756d2072656c6179466565746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374756e7265636f676e697a6564207472616e736665724f75742061636b207061636b6167654c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620616d6f756e7473746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d73672073656e646572206d75737420626520746f6b656e4d616e6167657274686520636f6e7472616374206e6f7420696e69742079657400000000000000726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e7366657220424e4220616d6f756e7420616e642072656c6179466565696e76616c696420726563656976656420424e4220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6ea264697066735822122055e131816f7cd763bf5ca5ef344219b7a6ec4dab5c7d1c50f4bccc7f17fe5d4664736f6c63430006040033", + }, + { + ContractAddr: CrossChainContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/78e13b1d3a5a1b08c9208af94a9b14fc1efda213", + Code: "608060405234801561001057600080fd5b50600436106103995760003560e01c8063718a8aa8116101e9578063c27cdcfb1161010f578063dc927faf116100ad578063f7a251d71161007c578063f7a251d714610b2f578063f9a2bbc714610ba7578063fc3e590814610baf578063fd6a687914610bb757610399565b8063dc927faf14610af7578063e1c7392a14610aff578063e3b0480514610b07578063e6400bbe14610b2757610399565b8063ccc108d7116100e9578063ccc108d714610ab0578063d31f968d14610ab8578063d76a867514610ae7578063dc40433114610aef57610399565b8063c27cdcfb14610a80578063c780e9de14610aa0578063c81b166214610aa857610399565b80638cc8f56111610187578063a78abc1611610156578063a78abc16146109b2578063ab51bb96146109ba578063ac431751146109c2578063b0355f5b1461078157610399565b80638cc8f5611461088757806396713da91461099a5780639dc09262146109a2578063a1a11bf5146109aa57610399565b806375d47a0a116101c357806375d47a0a146108a75780637942fd05146108af57806384013b6a146108b7578063863fe4ab1461099257610399565b8063718a8aa81461088f578063719482d51461089757806374f079b81461089f57610399565b8063422f9050116102ce57806363e1394e1161026c5780636de380bd1161023b5780636de380bd146108575780636e47a51a1461085f5780636e47b4821461087f57806370fd5bad1461088757610399565b806363e1394e146107ff5780636a3cb34d146108075780636bacff2c1461080f5780636c46aa681461080757610399565b80634bf6c882116102a85780634bf6c882146107b957806351e80672146107c15780635692ddd3146107c95780635f832177146107d157610399565b8063422f90501461078957806343756e5c146107a9578063493279b1146107b157610399565b8063299b533d1161033b578063308325f411610315578063308325f4146106155780633a648b151461061d5780633bdc47a6146106595780633dffc3871461078157610399565b8063299b533d146105a35780632af6f399146105d75780632ff32aea146105f457610399565b806314b3023b1161037757806314b3023b146104015780631d1309351461041b5780631e275ae11461043757806322556cdc1461059b57610399565b806305e682581461039e5780630bee7a67146103bc5780630e2374a5146103dd575b600080fd5b6103a6610bbf565b6040805160ff9092168252519081900360200190f35b6103c4610bc4565b6040805163ffffffff9092168252519081900360200190f35b6103e5610bc9565b604080516001600160a01b039092168252519081900360200190f35b610409610bcf565b60408051918252519081900360200190f35b610423610bd5565b604080519115158252519081900360200190f35b610599600480360361010081101561044e57600080fd5b81018160a081016080820135600160201b81111561046b57600080fd5b82018360208201111561047d57600080fd5b803590602001918460018302840111600160201b8311171561049e57600080fd5b919390929091602081019035600160201b8111156104bb57600080fd5b8201836020820111156104cd57600080fd5b803590602001918460018302840111600160201b831117156104ee57600080fd5b919390929091602081019035600160201b81111561050b57600080fd5b82018360208201111561051d57600080fd5b803590602001918460018302840111600160201b8311171561053e57600080fd5b919390929091602081019035600160201b81111561055b57600080fd5b82018360208201111561056d57600080fd5b803590602001918460018302840111600160201b8311171561058e57600080fd5b509092509050610bde565b005b6104096112c2565b6105c0600480360360208110156105b957600080fd5b50356112c7565b6040805161ffff9092168252519081900360200190f35b610423600480360360208110156105ed57600080fd5b50356112dd565b6105fc6112f2565b60408051600792830b90920b8252519081900360200190f35b6104096112fb565b61063d6004803603602081101561063357600080fd5b503560ff16611301565b604080516001600160401b039092168252519081900360200190f35b61070c6004803603606081101561066f57600080fd5b60ff82351691602081013591810190606081016040820135600160201b81111561069857600080fd5b8201836020820111156106aa57600080fd5b803590602001918460018302840111600160201b831117156106cb57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061131c945050505050565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561074657818101518382015260200161072e565b50505050905090810190601f1680156107735780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103a6611392565b6104236004803603602081101561079f57600080fd5b503560ff16611397565b6103e56113ac565b6105c06113b2565b6103a66113b8565b6103e56113bd565b6104096113c3565b610599600480360360408110156107e757600080fd5b506001600160a01b03813581169160200135166113f3565b610409611653565b6105c061167b565b61082c6004803603602081101561082557600080fd5b5035611680565b6040805161ffff90941684526001600160801b03909216602084015282820152519081900360600190f35b6104096116af565b6103e56004803603602081101561087557600080fd5b503560ff166116d6565b6103e56116f1565b6103a661167b565b6103a66116f7565b6105c0611392565b6104096116fc565b6103e5611702565b6103a6611708565b610599600480360360a08110156108cd57600080fd5b810190602081018135600160201b8111156108e757600080fd5b8201836020820111156108f957600080fd5b803590602001918460018302840111600160201b8311171561091a57600080fd5b919390929091602081019035600160201b81111561093757600080fd5b82018360208201111561094957600080fd5b803590602001918460018302840111600160201b8311171561096a57600080fd5b919350915080356001600160401b03908116916020810135909116906040013560ff1661170d565b610409612a37565b6103a6612a3f565b6103e5612a44565b6103e5612a4a565b610423612a50565b6103c4610bbf565b610599600480360360408110156109d857600080fd5b810190602081018135600160201b8111156109f257600080fd5b820183602082011115610a0457600080fd5b803590602001918460018302840111600160201b83111715610a2557600080fd5b919390929091602081019035600160201b811115610a4257600080fd5b820183602082011115610a5457600080fd5b803590602001918460018302840111600160201b83111715610a7557600080fd5b509092509050612a59565b61063d60048036036020811015610a9657600080fd5b503560ff1661351d565b610409613538565b6103e561355c565b610599613562565b61042360048036036040811015610ace57600080fd5b5080356001600160a01b0316906020013560ff166137b6565b61070c6137d6565b6104096137f5565b6103e56137fb565b610599613801565b61063d60048036036020811015610b1d57600080fd5b503560ff16613bb8565b610599613bd3565b61059960048036036060811015610b4557600080fd5b60ff8235169190810190604081016020820135600160201b811115610b6957600080fd5b820183602082011115610b7b57600080fd5b803590602001918460018302840111600160201b83111715610b9c57600080fd5b919350915035613df2565b6103e5613f35565b6103a6613f3b565b6103e5613f40565b600081565b606481565b61200181565b60015481565b600b5460ff1681565b60005460ff16610c23576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4e833981519152604482015290519081900360640190fd5b604080516337d7f9c160e21b81526001600160401b038b35166004820181905291516110039163df5fe704916024808301926020929190829003018186803b158015610c6e57600080fd5b505afa158015610c82573d6000803e3d6000fd5b505050506040513d6020811015610c9857600080fd5b5051610cd55760405162461bcd60e51b8152600401808060200182810382526023815260200180614a6e6023913960400191505060405180910390fd5b604080516337d7f9c160e21b815260208c8101356001600160401b03166004830181905292516110039263df5fe704926024808301939192829003018186803b158015610d2157600080fd5b505afa158015610d35573d6000803e3d6000fd5b505050506040513d6020811015610d4b57600080fd5b5051610d885760405162461bcd60e51b8152600401808060200182810382526023815260200180614a6e6023913960400191505060405180910390fd5b60608b013560ff81166000908152600560205260409020546001600160401b03909116906001600160a01b0316610e01576040805162461bcd60e51b815260206004820152601860248201527718da185b9b995b081a5cc81b9bdd081cdd5c1c1bdc9d195960421b604482015290519081900360640190fd5b600b5460ff1615610e45576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b8888604051808383808284376040519201829003822094508f93508e9250819050838380828437808301925050509250505060405180910390201415610ec1576040805162461bcd60e51b815260206004820152600c60248201526b1cd85b59481c185e5b1bd85960a21b604482015290519081900360640190fd5b60606001600160401b0360408e01358116908e83013516610ee28282613f46565b80516020808301919091206000818152600e9092526040909120549194509060ff1615610f4b576040805162461bcd60e51b8152602060048201526012602482015271185b1c9958591e4818da185b1b195b99d95960721b604482015290519081900360640190fd5b6000908152600e60205260408120805460ff191660011790558f8160200201356001600160401b0316905060608f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040805163cba510a960e01b81526001600160401b038a16600482015290519596509094611003945063cba510a9935060248083019350602092829003018186803b15801561104157600080fd5b505afa158015611055573d6000803e3d6000fd5b505050506040513d602081101561106b57600080fd5b505160408051808201909152600381526269626360e81b6020820152909150611098908290898686613f8e565b6110e1576040805162461bcd60e51b81526020600482015260156024820152740696e76616c6964206d65726b6c652070726f6f663605c1b604482015290519081900360640190fd5b5050505060008f6001600481106110f457fe5b60200201356001600160401b0316905060608d8d8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8f018190048102820181019092528d815293945060609392508d91508c908190840183828082843760009201829052506040805163cba510a960e01b81526001600160401b038a16600482015290519596509094611003945063cba510a9935060248083019350602092829003018186803b1580156111c057600080fd5b505afa1580156111d4573d6000803e3d6000fd5b505050506040513d60208110156111ea57600080fd5b505160408051808201909152600381526269626360e81b6020820152909150611217908290898686613f8e565b611260576040805162461bcd60e51b8152602060048201526015602482015274696e76616c6964206d65726b6c652070726f6f663160581b604482015290519081900360640190fd5b5050505061126c61408b565b604080516001600160401b038416815260ff83166020820152815133927f039eb91179ffd7d3b6e97f8ea106e748e827f910b872375dbc9c14a362319c3c928290030190a2505050505050505050505050505050565b603281565b600d6020526000908152604090205461ffff1681565b600e6020526000908152604090205460ff1681565b60045460070b81565b60025481565b600a602052600090815260409020546001600160401b031681565b60606000825160210190506060816040519080825280601f01601f191660200182016040528015611354576020820181803683370190505b506021810186905260018101879052828152905060418101600061137786614109565b50905061138681838851614113565b50909695505050505050565b600181565b60096020526000908152604090205460ff1681565b61100181565b6102ca81565b600881565b61200081565b604080517710d05390d15317d514905394d1915497d41493d413d4d05360421b8152905190819003601801902081565b60005460ff16611438576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4e833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b15801561147b57600080fd5b505afa15801561148f573d6000803e3d6000fd5b505050506040513d60208110156114a557600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b1580156114e657600080fd5b505afa1580156114fa573d6000803e3d6000fd5b505050506040513d602081101561151057600080fd5b505190508061151d575060155b60008211801561152d5750808211155b61156c576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b604080516001600160a01b038087166020808401919091529086168284015282518083038401815260608301808552815191909201207710d05390d15317d514905394d1915497d41493d413d4d05360421b90915291519081900360780190206000906115d99083614154565b9050801561164b5760408051630911a2c160e11b81526001600160a01b03888116600483015287166024820152905161100491631223458291604480830192600092919082900301818387803b15801561163257600080fd5b505af1158015611646573d6000803e3d6000fd5b505050505b505050505050565b604080516f14d554d411539117d41493d413d4d05360821b8152905190819003601001902081565b600281565b600c602052600090815260409020805460019091015461ffff8216916201000090046001600160801b03169083565b604080516e149153d4115397d41493d413d4d053608a1b8152905190819003600f01902081565b6005602052600090815260409020546001600160a01b031681565b61100581565b601081565b60035481565b61100881565b600b81565b60005460ff16611752576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4e833981519152604482015290519081900360640190fd5b60408051630a83aaa960e31b815233600482015290516110069163541d5548916024808301926020929190829003018186803b15801561179157600080fd5b505afa1580156117a5573d6000803e3d6000fd5b505050506040513d60208110156117bb57600080fd5b505161180e576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b7388cb4d8f77742c24d647bef8049d3f3c56067cdd33148061184357507342d596440775c90db8d9187b47650986e106349333145b61187e5760405162461bcd60e51b815260040180806020018281038252602a8152602001806149f2602a913960400191505060405180910390fd5b60ff8116600090815260086020526040902054829082906001600160401b0390811690831681146118ee576040805162461bcd60e51b815260206004820152601560248201527439b2b8bab2b731b2903737ba1034b71037b93232b960591b604482015290519081900360640190fd5b60ff8216600090815260086020908152604091829020805467ffffffffffffffff1916600185016001600160401b039081169190911790915582516337d7f9c160e21b81529089166004820152915188926110039263df5fe70492602480840193829003018186803b15801561196357600080fd5b505afa158015611977573d6000803e3d6000fd5b505050506040513d602081101561198d57600080fd5b50516119ca5760405162461bcd60e51b8152600401808060200182810382526023815260200180614a6e6023913960400191505060405180910390fd5b60ff851660009081526005602052604090205485906001600160a01b0316611a34576040805162461bcd60e51b815260206004820152601860248201527718da185b9b995b081a5cc81b9bdd081cdd5c1c1bdc9d195960421b604482015290519081900360640190fd5b60ff86166000908152600a6020526040902054889087906001600160401b039081169083161015611a9d576040805162461bcd60e51b815260206004820152600e60248201526d3a37b79037b632103432b0b232b960911b604482015290519081900360640190fd5b60ff81166000908152600a60205260409020546001600160401b03838116911614611aef5760ff81166000908152600a60205260409020805467ffffffffffffffff19166001600160401b0384161790555b600b5460ff1615611b33576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b60608e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509050611c776110036001600160a01b031663cba510a98e6040518263ffffffff1660e01b815260040180826001600160401b03166001600160401b0316815260200191505060206040518083038186803b158015611c2057600080fd5b505afa158015611c34573d6000803e3d6000fd5b505050506040513d6020811015611c4a57600080fd5b505160408051808201909152600381526269626360e81b6020820152611c708e8e613f46565b8585613f8e565b611cbf576040805162461bcd60e51b815260206004820152601460248201527334b73b30b634b21036b2b935b63290383937b7b360611b604482015290519081900360640190fd5b60408051631bb5062960e31b81526001600160401b038e16600482015290516000916110039163dda8314891602480820192602092909190829003018186803b158015611d0b57600080fd5b505afa158015611d1f573d6000803e3d6000fd5b505050506040513d6020811015611d3557600080fd5b505190508b8b600080806060611d4a89614439565b935093509350935083611e0c578460ff16866001600160401b03167ff7b2e42d694eb1100184aae86d4245d9e46966100b1dc7e723275b98326854ac8b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611dc4578181015183820152602001611dac565b50505050905090810190601f168015611df15780820380516001836020036101000a031916815260200191505b509250505060405180910390a3505050505050505050612a27565b6040805160ff85811682529151918716916001600160401b038916917f36afdaf439a8f43fe72135135d804ae620b37a474f0943b5b85f6788312cad40919081900360200190a360ff83166123915760ff85166000818152600560209081526040808320548151631182b87560e01b815260048101958652602481019283528651604482015286516001600160a01b03909216958695631182b875958d958a9593949093606490910192918601918190849084905b83811015611ed9578181015183820152602001611ec1565b50505050905090810190601f168015611f065780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015611f2657600080fd5b505af192505050801561200a57506040513d6000823e601f3d908101601f191682016040526020811015611f5957600080fd5b8101908080516040519392919084600160201b821115611f7857600080fd5b908301906020820185811115611f8d57600080fd5b8251600160201b811182820188101715611fa657600080fd5b82525081516020918201929091019080838360005b83811015611fd3578181015183820152602001611fbb565b50505050905090810190601f1680156120005780820380516001836020036101000a031916815260200191505b5060405250505060015b61231c576040516000815260443d1015612026575060006120c1565b60046000803e60005160e01c6308c379a081146120475760009150506120c1565b60043d036004833e81513d60248201116001600160401b0382111715612072576000925050506120c1565b80830180516001600160401b038111156120935760009450505050506120c1565b8060208301013d86018111156120b1576000955050505050506120c1565b601f01601f191660405250925050505b806120cc57506121de565b60ff8716600090815260076020526040812054612103916001600160401b039091169089906120fe906002908861131c565b6144e9565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf948794849390840192918601918190849084905b8381101561219e578181015183820152602001612186565b50505050905090810190601f1680156121cb5780820380516001836020036101000a031916815260200191505b509250505060405180910390a250612317565b3d808015612208576040519150601f19603f3d011682016040523d82523d6000602084013e61220d565b606091505b5060ff8716600090815260076020526040812054612240916001600160401b039091169089906120fe906002908861131c565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351948794849390840192918601918190849084905b838110156122db5781810151838201526020016122c3565b50505050905090810190601f1680156123085780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b61238b565b8051156123895760ff8716600090815260076020526040812054612355916001600160401b039091169089906120fe906001908661131c565b60ff8716600090815260076020526040902080546001600160401b038082166001011667ffffffffffffffff199091161790555b505b5061295f565b60ff8316600114156126355760ff8516600081815260056020908152604080832054815163831d65d160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563831d65d1958d958a9593949093606490910192918601918190849084905b8381101561241b578181015183820152602001612403565b50505050905090810190601f1680156124485780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561246857600080fd5b505af1925050508015612479575060015b61238b576040516000815260443d101561249557506000612530565b60046000803e60005160e01c6308c379a081146124b6576000915050612530565b60043d036004833e81513d60248201116001600160401b03821117156124e157600092505050612530565b80830180516001600160401b03811115612502576000945050505050612530565b8060208301013d860181111561252057600095505050505050612530565b601f01601f191660405250925050505b8061253b57506125a0565b60408051602080825283518183015283516001600160a01b038616937ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf938693909283928301918501908083836000831561219e578181015183820152602001612186565b3d8080156125ca576040519150601f19603f3d011682016040523d82523d6000602084013e6125cf565b606091505b5060408051602080825283518183015283516001600160a01b038616937f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd297735193869390928392830191850190808383600083156122db5781810151838201526020016122c3565b60ff83166002141561295f5760ff8516600081815260056020908152604080832054815163c8509d8160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563c8509d81958d958a9593949093606490910192918601918190849084905b838110156126bf5781810151838201526020016126a7565b50505050905090810190601f1680156126ec5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561270c57600080fd5b505af192505050801561271d575060015b61295d576040516000815260443d1015612739575060006127d4565b60046000803e60005160e01c6308c379a0811461275a5760009150506127d4565b60043d036004833e81513d60248201116001600160401b0382111715612785576000925050506127d4565b80830180516001600160401b038111156127a65760009450505050506127d4565b8060208301013d86018111156127c4576000955050505050506127d4565b601f01601f191660405250925050505b806127df5750612888565b816001600160a01b03167ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf826040518080602001828103825283818151815260200191508051906020019080838360005b83811015612848578181015183820152602001612830565b50505050905090810190601f1680156128755780820380516001836020036101000a031916815260200191505b509250505060405180910390a25061295d565b3d8080156128b2576040519150601f19603f3d011682016040523d82523d6000602084013e6128b7565b606091505b50816001600160a01b03167f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351826040518080602001828103825283818151815260200191508051906020019080838360005b83811015612921578181015183820152602001612909565b50505050905090810190601f16801561294e5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b505b60ff80861660009081526009602052604090205461100591636f93d2e6918a91339187911680612991575060ff881615155b604080516001600160e01b031960e088901b1681526001600160a01b039586166004820152939094166024840152604483019190915215156064820152905160848083019260209291908290030181600087803b1580156129f157600080fd5b505af1158015612a05573d6000803e3d6000fd5b505050506040513d6020811015612a1b57600080fd5b50505050505050505050505b5050505050505050505050505050565b630102ca0081565b600981565b61100781565b61100681565b60005460ff1681565b3361100714612a995760405162461bcd60e51b815260040180806020018281038252602e81526020018061497a602e913960400191505060405180910390fd5b600b5460ff1615612add576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b612b4684848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526012815271626174636853697a65466f724f7261636c6560701b602082015291506146849050565b15612be157604080516020601f8401819004810282018101909252828152600091612b899185858083850183828082843760009201919091525061476b92505050565b90506127108111158015612b9e5750600a8110155b612bd95760405162461bcd60e51b8152600401808060200182810382526032815260200180614a1c6032913960400191505060405180910390fd5b60015561348b565b612c4a84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601281527118591913dc955c19185d1950da185b9b995b60721b602082015291506146849050565b15612dd257606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060169091149050612ccd5760405162461bcd60e51b815260040180806020018281038252605a815260200180614893605a913960600191505060405180910390fd5b60018101516002820151601683015160ff82161590612ceb81614770565b612d3c576040805162461bcd60e51b815260206004820152601960248201527f61646472657373206973206e6f74206120636f6e747261637400000000000000604482015290519081900360640190fd5b60ff8416600081815260056020908152604080832080546001600160a01b0319166001600160a01b038716908117909155808452600683528184208585528352818420805460ff199081166001179091556009909352818420805490931687151517909255519092917f7e3b6af43092577ee20e60eaa1d9b114a7031305c895ee7dd3ffe17196d2e1e091a3505050505061348b565b612e3f84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526016815275195b98589b1953dc911a5cd8589b1950da185b9b995b60521b602082015291506146849050565b15612f7057606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060029091149050612ec25760405162461bcd60e51b815260040180806020018281038252604a8152602001806149a8604a913960600191505060405180910390fd5b600181810151600283015160ff80831660009081526005602052604090205492939192908316909114906001600160a01b03168015612f66576001600160a01b038116600090815260066020908152604080832060ff881680855290835292819020805460ff1916861515908117909155815190815290517fa3132e3f9819fbddc7f0ed6d38d7feef59aa95112090b7c592f5cb5bc4aa4adc929181900390910190a25b505050505061348b565b612fd484848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c73757370656e6451756f72756d60981b602082015291506146849050565b1561310957600281146130185760405162461bcd60e51b815260040180806020018281038252602d815260200180614921602d913960400191505060405180910390fd5b600061305b600284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061476b92505050565b905060008161ffff16118015613075575060648161ffff16105b6130bf576040805162461bcd60e51b8152602060048201526016602482015275696e76616c69642073757370656e642071756f72756d60501b604482015290519081900360640190fd5b604080516f14d554d411539117d41493d413d4d05360821b815281519081900360100190206000908152600d60205220805461ffff90921661ffff1990921691909117905561348b565b61316c84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600c81526b72656f70656e51756f72756d60a01b602082015291506146849050565b1561329f57600281146131b05760405162461bcd60e51b815260040180806020018281038252602c81526020018061494e602c913960400191505060405180910390fd5b60006131f3600284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061476b92505050565b905060008161ffff1611801561320d575060648161ffff16105b613256576040805162461bcd60e51b8152602060048201526015602482015274696e76616c69642072656f70656e2071756f72756d60581b604482015290519081900360640190fd5b604080516e149153d4115397d41493d413d4d053608a1b8152815190819003600f0190206000908152600d60205220805461ffff90921661ffff1990921691909117905561348b565b61330a84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601481527363616e63656c5472616e7366657251756f72756d60601b602082015291506146849050565b1561344e576002811461334e5760405162461bcd60e51b81526004018080602001828103825260348152602001806148ed6034913960400191505060405180910390fd5b6000613391600284848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061476b92505050565b905060008161ffff161180156133ab575060648161ffff16105b6133fc576040805162461bcd60e51b815260206004820152601e60248201527f696e76616c69642063616e63656c207472616e736665722071756f72756d0000604482015290519081900360640190fd5b604080517710d05390d15317d514905394d1915497d41493d413d4d05360421b815281519081900360180190206000908152600d60205220805461ffff90921661ffff1990921691909117905561348b565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b6008602052600090815260409020546001600160401b031681565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081565b61100281565b60005460ff166135a7576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4e833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b1580156135ea57600080fd5b505afa1580156135fe573d6000803e3d6000fd5b505050506040513d602081101561361457600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b15801561365557600080fd5b505afa158015613669573d6000803e3d6000fd5b505050506040513d602081101561367f57600080fd5b505190508061368c575060155b60008211801561369c5750808211155b6136db576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b600b5460ff16613722576040805162461bcd60e51b815260206004820152600d60248201526c1b9bdd081cdd5cdc195b991959609a1b604482015290519081900360640190fd5b604080516e149153d4115397d41493d413d4d053608a1b8152905190819003600f019020600090613773907fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470614154565b905080156137b157600b805460ff1916905560405133907f899fe8c37dc61708a3aaa99c4bf143346c1d1da69af79be9e8920c0a6785b75290600090a25b505050565b600660209081526000928352604080842090915290825290205460ff1681565b6040518060400160405280600381526020016269626360e81b81525081565b610e1081565b61100381565b60005460ff1615613859576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b7f1471eb6eb2c5e789fc3de43f8ce62938c7d1836ec861730447e2ada8fd81017b80546001600160a01b0319908116611008179091557f92e85d02570a8092d09a6e3a57665bc3815a2699a4074001bf1ccabf660f5a36805460ff199081169091557fd8af288fc1c8680b4f4706064cf021e264efb6828fcaf7eb5ca36818eb365bcc8054821660019081179091557f89832631fb3c3307a103ba2c84ab569c64d6182a18893dcd163f0f1c2090733a805484166110049081179091557f6cde3cea4b3a3fb2488b2808bae7556f4a405e50f65e1794383bc026131b13c38054841690557f72e4efa1513b071517c6c74dba31b5934a81aa83cddd400e7081df5529c9943680548416831790557fa9bc9a3a348c357ba16b37005d7e6b3236198c0e939f4af8c5f19b8deeb8ebc08054851690911790557fc575c31fea594a6eb97c8e9d3f9caee4c16218c6ef37e923234c0fe9014a61e78054831690557f4e523af77f034e9810f1c94057f5e931fb3d16a51511a4c3add793617d18610580548316821790557ffb33122aa9f93cc639ebe80a7bc4784c11e6053dde89c6f4f7e268c6a623da1e805484166110001790557fc7694af312c4f286114180fd0ba6a52461fcee8a381636770b19a343af92538a80548316821790557f01112dd68e482ba8d68a7e828cff8b3abcea08eab88941953c180a7e650e9cd480548316821790557fc0a4a8be475dfebc377ebef2d7c4ff47656f572a08dd92b81017efcdba0febe1805484166110071790557f87e8a52529e8ece4ef759037313542a6429ff494a9fab9027fb79db90124eba680548316821790557f4c7666bbcb22d46469f7cc282f70764a7012dca2cce630ff8d83db9a9cdd48f080548316821790557f40f28f99a40bc9f6beea1013afdbc3cdcc689eb76b82c4de06c0acf1e1932ed58054909316611001179092557f0d9cf2cd531699eed8dd34e40ff2884a14a698c4898184fba85194e6f6772d248054821683179055600b60009081527f23f68c9bd22b8a93d06adabe17481c87c016bcbd20adc8bfd707a4d813a572176020527fdf0d5d05428057f5455c2dc8e810dd86d1e9350faa72f16bda8a45443c5b39328054831684179055603283556004805467ffffffffffffffff19166001600160401b031790556002819055600381905580549091169091179055565b6007602052600090815260409020546001600160401b031681565b60005460ff16613c18576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4e833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b158015613c5b57600080fd5b505afa158015613c6f573d6000803e3d6000fd5b505050506040513d6020811015613c8557600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b158015613cc657600080fd5b505afa158015613cda573d6000803e3d6000fd5b505050506040513d6020811015613cf057600080fd5b5051905080613cfd575060155b600082118015613d0d5750808211155b613d4c576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b600b5460ff1615613d90576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b604080516f14d554d411539117d41493d413d4d05360821b81529051908190036010019020600090613de2907fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470614154565b905080156137b1576137b161408b565b60005460ff16613e37576040805162461bcd60e51b81526020600482015260196024820152600080516020614a4e833981519152604482015290519081900360640190fd5b33600090815260066020908152604080832060ff8089168552925290912054859116613e945760405162461bcd60e51b81526004018080602001828103825260318152602001806148626031913960400191505060405180910390fd5b60ff85166000908152600760209081526040808320548151601f88018490048402810184019092528682526001600160401b031692613ef99284928a926120fe92909189918c908c908190840183828082843760009201919091525061131c92505050565b60ff959095166000908152600760205260409020805467ffffffffffffffff191660019096016001600160401b03169590951790945550505050565b61100081565b600381565b61100481565b60408051600e808252818301909252606091630102ca0060ff851617918391602082018180368337505050600e81810187905260068201939093529182525090505b92915050565b600085613f9d57506000614082565b606082518451865160800101016040519080825280601f01601f191660200182016040528015613fd4576020820181803683370190505b5090506000613fe282614776565b602080890151825201905086600080613ffa89614109565b8086526020909501949092509050614013828583614113565b9283019261402088614109565b8086526020909501949092509050614039828583614113565b9283018a81526020019261404c87614109565b909250905061405c828583614113565b50835160200161406a61477c565b60208183886065600019fa5051600114955050505050505b95945050505050565b600b5460ff16156140cf576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b600b805460ff1916600117905560405133907f6f123d3d54c84a7960a573b31c221dcd86e13fd849c5adb0c6ca851468cc1ae490600090a2565b8051602090910191565b5b60208110614133578251825260209283019290910190601f1901614114565b915181516020939093036101000a6000190180199091169216919091179052565b6000828152600d602052604081205461ffff1661421d57604080516f14d554d411539117d41493d413d4d05360821b815281519081900360100181206000908152600d6020818152848320805461ffff199081166001179091556e149153d4115397d41493d413d4d053608a1b8552855194859003600f01852084528282528584208054821660029081179091557710d05390d15317d514905394d1915497d41493d413d4d05360421b8652865195869003601801909520845291905292902080549092161790555b6000838152600c6020526040902080546201000090046001600160801b03164210158061424e575082816001015414155b15614321576000848152600d602090815260409182902054835461ffff90911661ffff199091161771ffffffffffffffffffffffffffffffff0000191662010000610e1042016001600160801b031602178355600180840186905582519182019092523381526142c39160028401919061479a565b5080546040805161ffff83168152620100009092046001600160801b0316602083015281810185905251339186917f9e109f0e55ef32e99e4880be2ec357f1ddb3469c79d0747ef4762da6e89fabe5916060908290030190a36143d5565b60005b60028201548110156143ac57336001600160a01b031682600201828154811061434957fe5b6000918252602090912001546001600160a01b031614156143a4576040805162461bcd60e51b815260206004820152601060248201526f185b1c9958591e48185c1c1c9bdd995960821b604482015290519081900360640190fd5b600101614324565b50600281018054600181018255600091825260209091200180546001600160a01b031916331790555b8054600282015461ffff9091161161442f576000848152600c60205260408120805471ffffffffffffffffffffffffffffffffffff19168155600181018290559061442360028301826147ff565b50506001915050613f88565b5060009392505050565b600080600060606021855110156144695750506040805160008082526020820190925290925082915081906144e2565b600185015160218601518651604080516020198301808252601f19600119909401939093168101602001909152604189019392916060919080156144b4576020820181803683370190505b50905060006144c282614109565b5090506144d4858260218d5103614113565b506001975091955093509150505b9193509193565b600b5460ff161561452d576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b60025443111561456c576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b1617909155600355436002556145ad565b600380546001908101918290555410156145ad576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003555b8160ff16836001600160401b0316600460009054906101000a900460070b6001600160401b03167f3a6e0fc61675aa2a100bcba0568368bb92bcec91c97673391074f11138f0cffe6102ca85604051808361ffff1661ffff16815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561464457818101518382015260200161462c565b50505050905090810190601f1680156146715780820380516001836020036101000a031916815260200191505b50935050505060405180910390a4505050565b6000816040516020018082805190602001908083835b602083106146b95780518252601f19909201916020918201910161469a565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106147275780518252601f199092019160209182019101614708565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b3b151590565b60200190565b60405180602001604052806001906020820280368337509192915050565b8280548282559060005260206000209081019282156147ef579160200282015b828111156147ef57825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906147ba565b506147fb929150614820565b5090565b508054600082559060005260206000209081019061481d9190614847565b50565b61484491905b808211156147fb5780546001600160a01b0319168155600101614826565b90565b61484491905b808211156147fb576000815560010161484d56fe74686520636f6e747261637420616e64206368616e6e656c2068617665206e6f74206265656e20726567697374657265646c656e677468206f662076616c756520666f72206164644f725570646174654368616e6e656c2073686f756c642062652032322c206368616e6e656c49643a697346726f6d53797374656d3a68616e646c6572416464726573736c656e677468206f662076616c756520666f722063616e63656c5472616e7366657251756f72756d2073686f756c6420626520326c656e677468206f662076616c756520666f722073757370656e6451756f72756d2073686f756c6420626520326c656e677468206f662076616c756520666f722072656f70656e51756f72756d2073686f756c642062652032746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f7220656e61626c654f7244697361626c654368616e6e656c2073686f756c6420626520322c206368616e6e656c49643a6973456e61626c65746865206d73672073656e646572206973206e6f7420612077686974656c6162656c2072656c61796572746865206e6577426174636853697a65466f724f7261636c652073686f756c6420626520696e205b31302c2031303030305d74686520636f6e7472616374206e6f7420696e697420796574000000000000006c6967687420636c69656e74206e6f742073796e632074686520626c6f636b20796574a2646970667358221220008ae508df631c7bfc8d3fe4ef823eddaef63a15d5e7aa54865ae501fe6fc38164736f6c63430006040033", + }, + }, + } + CalcuttaUpgrade[networkname.BorMainnetChainName] = &Upgrade{ UpgradeName: "calcutta", Configs: []*UpgradeConfig{ @@ -507,6 +579,99 @@ func init() { }, }, } + + LubanUpgrade[networkname.BSCChainName] = &Upgrade{ + UpgradeName: "luban", + Configs: []*UpgradeConfig{ + { + ContractAddr: ValidatorContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "60806040526004361061046c5760003560e01c8063862498821161024a578063c6d3394511610139578063e40716a1116100b6578063f9a2bbc71161007a578063f9a2bbc714610b6b578063fc3e590814610b80578063fccc281314610b95578063fd4ad81f14610baa578063fd6a687914610bd957610473565b8063e40716a114610af9578063eb57e20214610b0e578063eda5868c14610b2e578063f340fa0114610b43578063f92eb86b14610b5657610473565b8063d86222d5116100fd578063d86222d514610a90578063daacdb6614610aa5578063dc927faf14610aba578063e086c7b114610acf578063e1c7392a14610ae457610473565b8063c6d3394514610a3c578063c81b166214610a51578063c8509d811461085f578063d04aa99614610a66578063d68fb56a14610a7b57610473565b8063a5422d5c116101c7578063ad3c9da61161018b578063ad3c9da6146109d0578063aef198a9146109f0578063b7ab4db514610a05578063b8cf4ef114610a27578063bf9f49951461062f57610473565b8063a5422d5c1461095c578063a78abc1614610971578063aaf5eb6814610986578063ab51bb961461099b578063ac431751146109b057610473565b806396713da91161020e57806396713da9146108f35780639dc09262146109085780639fe0f8161461091d578063a0dc275814610932578063a1a11bf51461094757610473565b8063862498821461087f57806388b32f11146108945780638b5ad0c9146108a95780638d19a410146108be5780639369d7de146108de57610473565b80634df6e0c3116103665780636e47b482116102e35780637942fd05116102a75780637942fd05146108205780637a84ca2a1461083557806381650b621461084a578063831d65d11461085f578063853230aa1461080b57610473565b80636e47b482146107b757806370fd5bad146107cc578063718a8aa8146107e157806375d47a0a146107f657806378dfed4a1461080b57610473565b8063565c56b31161032a578063565c56b3146107265780635667515a146107465780635d77156c1461075b57806362b72cf5146107705780636969a25c1461078557610473565b80634df6e0c3146106b25780635192c82c146106c757806351e80672146106dc578063549b03f2146106f157806355614fcc1461070657610473565b8063321d398a116103f45780633dffc387116103b85780633dffc3871461062f57806343756e5c1461065157806345cf9daf14610666578063493279b11461067b5780634bf6c8821461069d57610473565b8063321d398a146105975780633365af3a146105b757806335409f7f146105d75780633b071dcc146105f75780633de0f0d81461061a57610473565b80631182b8751161043b5780631182b875146104fe578063152ad3b81461052b5780631ff180691461054d578063219f22d514610562578063300c35671461057757610473565b806304c4fec61461047857806307a568471461048f5780630bee7a67146104ba5780630e2374a5146104dc57610473565b3661047357005b600080fd5b34801561048457600080fd5b5061048d610bee565b005b34801561049b57600080fd5b506104a4610c60565b6040516104b19190616ef0565b60405180910390f35b3480156104c657600080fd5b506104cf610c66565b6040516104b19190616f1a565b3480156104e857600080fd5b506104f1610c6b565b6040516104b191906162f7565b34801561050a57600080fd5b5061051e6105193660046161dd565b610c71565b6040516104b1919061646e565b34801561053757600080fd5b50610540610ea9565b6040516104b19190616463565b34801561055957600080fd5b506104a4610eb2565b34801561056e57600080fd5b506104cf610eb8565b34801561058357600080fd5b5061048d6105923660046160a6565b610ebd565b3480156105a357600080fd5b506105406105b236600461618a565b611241565b3480156105c357600080fd5b506105406105d236600461618a565b611310565b3480156105e357600080fd5b5061048d6105f236600461607f565b6113c1565b34801561060357600080fd5b5061060c61151a565b6040516104b1929190616379565b34801561062657600080fd5b506104a46117f6565b34801561063b57600080fd5b506106446117fc565b6040516104b19190616f2b565b34801561065d57600080fd5b506104f1611801565b34801561067257600080fd5b506104a4611807565b34801561068757600080fd5b5061069061180d565b6040516104b19190616ee1565b3480156106a957600080fd5b50610644611812565b3480156106be57600080fd5b5061060c611817565b3480156106d357600080fd5b506104a4611995565b3480156106e857600080fd5b506104f161199b565b3480156106fd57600080fd5b506104a46119a1565b34801561071257600080fd5b5061054061072136600461607f565b6119a7565b34801561073257600080fd5b506104a461074136600461607f565b6119dc565b34801561075257600080fd5b50610644611a2d565b34801561076757600080fd5b506104cf611a32565b34801561077c57600080fd5b506104a4611a37565b34801561079157600080fd5b506107a56107a036600461618a565b611a3d565b6040516104b196959493929190616324565b3480156107c357600080fd5b506104f1611aa1565b3480156107d857600080fd5b50610644611aa7565b3480156107ed57600080fd5b50610644611aac565b34801561080257600080fd5b506104f1611ab1565b34801561081757600080fd5b506104a4611ab7565b34801561082c57600080fd5b50610644611abd565b34801561084157600080fd5b506104a4611ac2565b34801561085657600080fd5b506104cf611ac8565b34801561086b57600080fd5b5061048d61087a3660046161dd565b611acd565b34801561088b57600080fd5b506104a4611b2e565b3480156108a057600080fd5b506104a4611b34565b3480156108b557600080fd5b506104a4611b3a565b3480156108ca57600080fd5b506104a46108d936600461607f565b611b40565b3480156108ea57600080fd5b5061048d611b80565b3480156108ff57600080fd5b50610644611c94565b34801561091457600080fd5b506104f1611c99565b34801561092957600080fd5b506104a4611c9f565b34801561093e57600080fd5b506104a4611ca4565b34801561095357600080fd5b506104f1611ca9565b34801561096857600080fd5b5061051e611caf565b34801561097d57600080fd5b50610540611cce565b34801561099257600080fd5b506104a4611cd7565b3480156109a757600080fd5b506104cf611a2d565b3480156109bc57600080fd5b5061048d6109cb36600461612e565b611ce0565b3480156109dc57600080fd5b506104a46109eb36600461607f565b61258c565b3480156109fc57600080fd5b506104a461259e565b348015610a1157600080fd5b50610a1a6125ab565b6040516104b19190616366565b348015610a3357600080fd5b506104a4612697565b348015610a4857600080fd5b506104a4611aa7565b348015610a5d57600080fd5b506104f161269c565b348015610a7257600080fd5b506104a46126a2565b348015610a8757600080fd5b506104a46126a7565b348015610a9c57600080fd5b506104a46126e6565b348015610ab157600080fd5b506104a46126f2565b348015610ac657600080fd5b506104f16126f8565b348015610adb57600080fd5b506104a46126fe565b348015610af057600080fd5b5061048d612703565b348015610b0557600080fd5b506104a46128b2565b348015610b1a57600080fd5b5061048d610b2936600461607f565b6128b8565b348015610b3a57600080fd5b506104cf6129c0565b61048d610b5136600461607f565b6129c5565b348015610b6257600080fd5b506104a4612c4d565b348015610b7757600080fd5b506104f1612c53565b348015610b8c57600080fd5b50610644611c9f565b348015610ba157600080fd5b506104f1612c59565b348015610bb657600080fd5b50610bca610bc536600461618a565b612c5f565b6040516104b193929190616ef9565b348015610be557600080fd5b506104f1612d21565b6000610bf933611b40565b9050600b8181548110610c0857fe5b600091825260209091206001601690920201015460ff16610c445760405162461bcd60e51b8152600401610c3b90616b99565b60405180910390fd5b6000610c4e6126a7565b9050610c5b338383612d27565b505050565b60095481565b606481565b61200181565b60005460609060ff16610c965760405162461bcd60e51b8152600401610c3b9061662d565b3361200014610cb75760405162461bcd60e51b8152600401610c3b90616d78565b600b54610d7557610cc6615d6b565b60015460005b81811015610d7157600b80546001810182556000919091528351600080516020616fa383398151915260169092029182019081556020808601516000805160206175d28339815191528401805460ff1916911515919091179055604086015180518794610d4d93600080516020616fc3833981519152909101920190615d9a565b506060820151610d639060038301906013615e14565b505050806001019050610ccc565b5050505b610d7d615e41565b6000610dbe85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612f1392505050565b9150915080610dda57610dd160646130cf565b92505050610ea2565b815160009060ff16610dff57610df883602001518460400151613130565b9050610e6e565b825160ff1660011415610e6a57826020015151600114610e4457600080516020616f83833981519152604051610e3490616a80565b60405180910390a1506067610e65565b610df88360200151600081518110610e5857fe5b6020026020010151613d84565b610e6e565b5060655b63ffffffff8116610e935750506040805160008152602081019091529150610ea29050565b610e9c816130cf565b93505050505b9392505050565b60075460ff1681565b60035481565b606881565b334114610edc5760405162461bcd60e51b8152600401610c3b90616dc7565b6010544311610efd5760405162461bcd60e51b8152600401610c3b90616789565b60005460ff16610f1f5760405162461bcd60e51b8152600401610c3b9061662d565b600f54610f37576032600f5561100231601155611237565b60006110023168056bc75e2d63100000811115610f6657610f5f81606463ffffffff613efb16565b9150610faf565b601154811115610fa857610f5f6064610f9c600f54610f9060115486613f3d90919063ffffffff16565b9063ffffffff613f7f16565b9063ffffffff613efb16565b5050611237565b6040516309a99b4f60e41b815261100290639a99b4f090610fd6903090869060040161630b565b602060405180830381600087803b158015610ff057600080fd5b505af1158015611004573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061102891906161a2565b6110023160115591508161103d575050611237565b6000805b8481101561106b5785858281811061105557fe5b9050602002013582019150806001019050611041565b508061107957505050611237565b6000806000805b8981101561122f578489898381811061109557fe5b905060200201358802816110a557fe5b0493508a8a828181106110b457fe5b90506020020160208101906110c9919061607f565b6001600160a01b038116600090815260046020526040902054909350915081156111e55760006001808403815481106110fe57fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff161561116b57836001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d858660405161115e9190616ef0565b60405180910390a26111df565b60035461117e908663ffffffff613fb916565b6003908155810154611196908663ffffffff613fb916565b60038201556040516001600160a01b038516907fcb0aad6cf9cd03bdf6137e359f541c42f38b39f007cae8e89e88aa7d8c6617b2906111d6908890616ef0565b60405180910390a25b50611227565b826001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d858560405161121e9190616ef0565b60405180910390a25b600101611080565b505050505050505b5050436010555050565b60015460009082106112555750600061130b565b60006001600160a01b03166001838154811061126d57fe5b60009182526020909120600490910201546001600160a01b0316148061129d5750600854158061129d5750600a54155b806112ac575060085460095410155b806112bd57506112bb82611310565b155b806112e657506000600b83815481106112d257fe5b906000526020600020906016020160000154115b806112fa575060016112f66125ab565b5111155b156113075750600061130b565b5060015b919050565b60015460009082106113245750600061130b565b600b548210611361576001828154811061133a57fe5b9060005260206000209060040201600201601c9054906101000a900460ff1615905061130b565b6001828154811061136e57fe5b9060005260206000209060040201600201601c9054906101000a900460ff161580156113bb5750600b82815481106113a257fe5b600091825260209091206001601690920201015460ff16155b92915050565b33611001146113e25760405162461bcd60e51b8152600401610c3b90616e98565b600b546114a0576113f1615d6b565b60015460005b8181101561149c57600b80546001810182556000919091528351600080516020616fa383398151915260169092029182019081556020808601516000805160206175d28339815191528401805460ff191691151591909117905560408601518051879461147893600080516020616fc3833981519152909101920190615d9a565b50606082015161148e9060038301906013615e14565b5050508060010190506113f7565b5050505b6001600160a01b038116600090815260046020526040902054806114c45750611517565b6001810390506000600b82815481106114d957fe5b600091825260209091206001601690920201015460ff1690506114fc8383613fde565b80156115055750805b15610c5b576009805460001901905550505b50565b60015460609081906000805b8281101561156d576001818154811061153b57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611565576001909101905b600101611526565b5060608160405190808252806020026020018201604052801561159a578160200160208202803683370190505b5090506060826040519080825280602002602001820160405280156115d357816020015b60608152602001906001900390816115be5790505b50600b546000945090915084141561174e5760005b8481101561174857600181815481106115fd57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611740576001818154811061162d57fe5b600091825260209091206004909102015483516001600160a01b039091169084908690811061165857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600b818154811061168557fe5b600091825260209182902060026016909202018101805460408051601f60001961010060018616150201909316949094049182018590048502840185019052808352919290919083018282801561171d5780601f106116f25761010080835404028352916020019161171d565b820191906000526020600020905b81548152906001019060200180831161170057829003601f168201915b505050505082858151811061172e57fe5b60209081029190910101526001909301925b6001016115e8565b506117ea565b60005b848110156117e8576001818154811061176657fe5b9060005260206000209060040201600201601c9054906101000a900460ff166117e0576001818154811061179657fe5b600091825260209091206004909102015483516001600160a01b03909116908490869081106117c157fe5b6001600160a01b03909216602092830291909101909101526001909301925b600101611751565b505b909450925050505b9091565b61271081565b600181565b61100181565b60085481565b603881565b600881565b600e54600c5460609182918061182b575060155b60606118356125ab565b9050606061184282614391565b9050828251116118595790945092506117f2915050565b8383835103101561186b578282510393505b83156118a15760c8430461188783838388880360008a8a6144ff565b61189f8383838888038989038a8b8b8b5103016144ff565b505b6060836040519080825280602002602001820160405280156118cd578160200160208202803683370190505b50905060608460405190808252806020026020018201604052801561190657816020015b60608152602001906001900390816118f15790505b50905060005b858110156119875784818151811061192057fe5b602002602001015183828151811061193457fe5b60200260200101906001600160a01b031690816001600160a01b03168152505083818151811061196057fe5b602002602001015182828151811061197457fe5b602090810291909101015260010161190c565b509096509450505050509091565b60065481565b61200081565b600f5481565b6001600160a01b038116600090815260046020526040812054806119cf57600091505061130b565b60001901610ea281611310565b6001600160a01b03811660009081526004602052604081205480611a0457600091505061130b565b600180820381548110611a1357fe5b906000526020600020906004020160030154915050919050565b600081565b606781565b60105481565b60018181548110611a4a57fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b0392831694509082169291821691600160a01b81046001600160401b031691600160e01b90910460ff169086565b61100581565b600281565b601081565b61100881565b6103e881565b600b81565b600c5481565b606681565b3361200014611aee5760405162461bcd60e51b8152600401610c3b90616d78565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051611b2193929190616f39565b60405180910390a1505050565b60025481565b60115481565b600a5481565b6001600160a01b03811660009081526004602052604081205480611b765760405162461bcd60e51b8152600401610c3b90616d00565b6000190192915050565b600b54611c3e57611b8f615d6b565b60015460005b81811015611c3a57600b80546001810182556000919091528351600080516020616fa383398151915260169092029182019081556020808601516000805160206175d28339815191528401805460ff1916911515919091179055604086015180518794611c1693600080516020616fc3833981519152909101920190615d9a565b506060820151611c2c9060038301906013615e14565b505050806001019050611b95565b5050505b600854611c4b5760036008555b600a54611c58576002600a555b6000611c6333611b40565b9050611c6e81611241565b611c8a5760405162461bcd60e51b8152600401610c3b90616a3d565b6115173382614656565b600981565b61100781565b600381565b60c881565b61100681565b6040518061062001604052806105ef8152602001616fe36105ef913981565b60005460ff1681565b6402540be40081565b60005460ff16611d025760405162461bcd60e51b8152600401610c3b9061662d565b3361100714611d235760405162461bcd60e51b8152600401610c3b90616b06565b611d8d84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526013815272065787069726554696d655365636f6e6447617606c1b602082015291506146ee9050565b15611e2a5760208114611db25760405162461bcd60e51b8152600401610c3b90616cba565b604080516020601f8401819004810282018101909252828152600091611df09185858083850183828082843760009201919091525061474792505050565b905060648110158015611e065750620186a08111155b611e225760405162461bcd60e51b8152600401610c3b906168e6565b600255612549565b611e8a84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260098152686275726e526174696f60b81b602082015291506146ee9050565b15611f265760208114611eaf5760405162461bcd60e51b8152600401610c3b906164b3565b604080516020601f8401819004810282018101909252828152600091611eed9185858083850183828082843760009201919091525061474792505050565b9050612710811115611f115760405162461bcd60e51b8152600401610c3b906167cb565b6006556007805460ff19166001179055612549565b611f9084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260138152726d61784e756d4f664d61696e7461696e696e6760681b602082015291506146ee9050565b1561202a5760208114611fb55760405162461bcd60e51b8152600401610c3b906164ea565b604080516020601f8401819004810282018101909252828152600091611ff39185858083850183828082843760009201919091525061474792505050565b600c5490915080612002575060155b8082106120215760405162461bcd60e51b8152600401610c3b9061683e565b50600855612549565b61209384848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61696e7461696e536c6173685363616c6560701b602082015291506146ee9050565b1561212c57602081146120b85760405162461bcd60e51b8152600401610c3b906165b3565b604080516020601f84018190048102820181019092528281526000916120f69185858083850183828082843760009201919091525061474792505050565b90506000811180156121085750600a81105b6121245760405162461bcd60e51b8152600401610c3b90616e14565b600a55612549565b6121a084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601981527f6d61784e756d4f66576f726b696e6743616e6469646174657300000000000000602082015291506146ee9050565b1561222f57602081146121c55760405162461bcd60e51b8152600401610c3b90616567565b604080516020601f84018190048102820181019092528281526000916122039185858083850183828082843760009201919091525061474792505050565b9050600d548111156122275760405162461bcd60e51b8152600401610c3b9061695c565b600e55612549565b61229884848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61784e756d4f6643616e6469646174657360701b602082015291506146ee9050565b1561231a57602081146122bd5760405162461bcd60e51b8152600401610c3b90616b54565b604080516020601f84018190048102820181019092528281526000916122fb9185858083850183828082843760009201919091525061474792505050565b600d819055600e5490915081101561231457600d54600e555b50612549565b61237e84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c6e756d4f66436162696e65747360981b602082015291506146ee9050565b1561242c57602081146123a35760405162461bcd60e51b8152600401610c3b906165f8565b604080516020601f84018190048102820181019092528281526000916123e19185858083850183828082843760009201919091525061474792505050565b9050600081116124035760405162461bcd60e51b8152600401610c3b9061669b565b60298111156124245760405162461bcd60e51b8152600401610c3b906166e3565b600c55612549565b61249684848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601381527266696e616c697479526577617264526174696f60681b602082015291506146ee9050565b1561253157602081146124bb5760405162461bcd60e51b8152600401610c3b90616c3d565b604080516020601f84018190048102820181019092528281526000916124f99185858083850183828082843760009201919091525061474792505050565b90506001811015801561250d575060648111155b6125295760405162461bcd60e51b8152600401610c3b906169cb565b600f55612549565b60405162461bcd60e51b8152600401610c3b90616e71565b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a8484848460405161257e9493929190616481565b60405180910390a150505050565b60046020526000908152604090205481565b68056bc75e2d6310000081565b6001546060906000805b828110156125da576125c681611310565b156125d2578160010191505b6001016125b5565b50606081604051908082528060200260200182016040528015612607578160200160208202803683370190505b5090506000915060005b8381101561268e5761262281611310565b15612686576001818154811061263457fe5b600091825260209091206004909102015482516001600160a01b039091169083908590811061265f57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508260010192505b600101612611565b50925050505b90565b601581565b61100281565b603281565b60006126b16125ab565b519050600080600c54116126c65760156126ca565b600c545b9050808211156126d8578091505b816126e257600191505b5090565b67016345785d8a000081565b60055481565b61100381565b602981565b60005460ff16156127265760405162461bcd60e51b8152600401610c3b90616c06565b61272e615e41565b60006127546040518061062001604052806105ef8152602001616fe36105ef9139612f13565b91509150806127755760405162461bcd60e51b8152600401610c3b90616d37565b60005b82602001515181101561289a5760018360200151828151811061279757fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782558587015182850180549185169183169190911790556040860151600283018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590981692909516919091179290921694909417161790915560a09093015160039093019290925591860151805191850193918590811061286d57fe5b602090810291909101810151516001600160a01b0316825281019190915260400160002055600101612778565b50506103e8600255506000805460ff19166001179055565b600d5481565b33611001146128d95760405162461bcd60e51b8152600401610c3b90616e98565b600b54612997576128e8615d6b565b60015460005b8181101561299357600b80546001810182556000919091528351600080516020616fa383398151915260169092029182019081556020808601516000805160206175d28339815191528401805460ff191691151591909117905560408601518051879461296f93600080516020616fc3833981519152909101920190615d9a565b5060608201516129859060038301906013615e14565b5050508060010190506128ee565b5050505b60006129a28261474c565b90506129ad81611241565b156129bc576129bc8282614656565b5050565b606581565b3341146129e45760405162461bcd60e51b8152600401610c3b90616dc7565b60005460ff16612a065760405162461bcd60e51b8152600401610c3b9061662d565b60003411612a265760405162461bcd60e51b8152600401610c3b9061692d565b6001600160a01b0381166000908152600460205260409020546007543491906103e89060ff1615612a5657506006545b600083118015612a665750600081115b15612b07576000612a83612710610f9c868563ffffffff613f7f16565b90508015612b055760405161dead9082156108fc029083906000818181858888f19350505050158015612aba573d6000803e3d6000fd5b507f627059660ea01c4733a328effb2294d2f86905bf806da763a89cee254de8bee581604051612aea9190616ef0565b60405180910390a1612b02848263ffffffff613f3d16565b93505b505b8115612c05576000600180840381548110612b1e57fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff1615612b8b57846001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b485604051612b7e9190616ef0565b60405180910390a2612bff565b600354612b9e908563ffffffff613fb916565b6003908155810154612bb6908563ffffffff613fb916565b60038201556040516001600160a01b038616907f93a090ecc682c002995fad3c85b30c5651d7fd29b0be5da9d784a3302aedc05590612bf6908790616ef0565b60405180910390a25b50612c47565b836001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b484604051612c3e9190616ef0565b60405180910390a25b50505050565b600e5481565b61100081565b61dead81565b600b8181548110612c6c57fe5b6000918252602091829020601691909102018054600180830154600280850180546040805161010096831615969096026000190190911692909204601f810188900488028501880190925281845293965060ff90911694919291830182828015612d175780601f10612cec57610100808354040283529160200191612d17565b820191906000526020600020905b815481529060010190602001808311612cfa57829003601f168201915b5050505050905083565b61100481565b6000600a5460001480612d38575081155b80612d435750600954155b15612d5057506000610ea2565b60096000815460019003919050819055506000612d9b600a54610f9c85610f9c600b8981548110612d7d57fe5b6000918252602090912060169091020154439063ffffffff613f3d16565b90506000600b8581548110612dac57fe5b906000526020600020906016020160010160006101000a81548160ff0219169083151502179055506000806110016001600160a01b0316638256ace66040518163ffffffff1660e01b8152600401604080518083038186803b158015612e1157600080fd5b505afa158015612e25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e4991906161ba565b9150915060009350808310612ec357612e628787613fde565b506040516305bfb49960e41b815261100190635bfb499090612e88908a906004016162f7565b600060405180830381600087803b158015612ea257600080fd5b505af1158015612eb6573d6000803e3d6000fd5b5050505060019350612ed5565b818310612ed557612ed38761474c565b505b6040516001600160a01b038816907fb9d38178dc641ff1817967a63c9078cbcd955a9f1fcd75e0e3636de615d44d3b90600090a25050509392505050565b612f1b615e41565b6000612f25615e41565b612f2d615e65565b612f3e612f39866148ef565b614914565b90506000805b612f4d8361495e565b156130c15780612f7257612f68612f638461497f565b6149cd565b60ff1684526130b9565b80600114156130b4576060612f8e612f898561497f565b614a4d565b90508051604051908082528060200260200182016040528015612fcb57816020015b612fb8615e85565b815260200190600190039081612fb05790505b508560200181905250805160405190808252806020026020018201604052801561300957816020015b6060815260200190600190039081612ff45790505b50604086015260005b81518110156130a957613023615e85565b6060600061304385858151811061303657fe5b6020026020010151614b1e565b92509250925080613063578860009a509a505050505050505050506130ca565b828960200151858151811061307457fe5b6020026020010181905250818960400151858151811061309057fe5b6020026020010181905250505050806001019050613012565b5060019250506130b9565b6130c1565b600101612f44565b50919350909150505b915091565b604080516001808252818301909252606091829190816020015b60608152602001906001900390816130e957905050905061310f8363ffffffff16614c38565b8160008151811061311c57fe5b6020026020010181905250610ea281614c4b565b600060298351111561316757600080516020616f8383398151915260405161315790616740565b60405180910390a15060666113bb565b60005b83518110156132055760005b818110156131fc5784818151811061318a57fe5b6020026020010151600001516001600160a01b03168583815181106131ab57fe5b6020026020010151600001516001600160a01b031614156131f457600080516020616f838339815191526040516131e19061689b565b60405180910390a16066925050506113bb565b600101613176565b5060010161316a565b506060806132138585614cd5565b60015491935091506000908190815b818110156132985767016345785d8a00006001828154811061324057fe5b9060005260206000209060040201600301541061326257836001019350613290565b60006001828154811061327157fe5b9060005260206000209060040201600301541115613290578260010192505b600101613222565b506060836040519080825280602002602001820160405280156132c5578160200160208202803683370190505b5090506060846040519080825280602002602001820160405280156132f4578160200160208202803683370190505b509050606085604051908082528060200260200182016040528015613323578160200160208202803683370190505b509050606086604051908082528060200260200182016040528015613352578160200160208202803683370190505b5090506000606087604051908082528060200260200182016040528015613383578160200160208202803683370190505b5090506060886040519080825280602002602001820160405280156133b2578160200160208202803683370190505b509050600099506000985060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b1580156133fa57600080fd5b505afa15801561340e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061343291906161a2565b905067016345785d8a000081111561347d57600080516020616f8383398151915260405161345f90616bc5565b60405180910390a160689d50505050505050505050505050506113bb565b60005b898110156136ee5767016345785d8a00006001828154811061349e57fe5b9060005260206000209060040201600301541061362357600181815481106134c257fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316898d815181106134f357fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060006402540be4006001838154811061352857fe5b9060005260206000209060040201600301548161354157fe5b066001838154811061354f57fe5b9060005260206000209060040201600301540390506135778382613f3d90919063ffffffff16565b898e8151811061358357fe5b6020026020010181815250506001828154811061359c57fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316878e815181106135cd57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505081888e815181106135fa57fe5b6020908102919091010152613615868263ffffffff613fb916565b95508c6001019c50506136e6565b60006001828154811061363257fe5b90600052602060002090600402016003015411156136e6576001818154811061365757fe5b906000526020600020906004020160010160009054906101000a90046001600160a01b0316848c8151811061368857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600181815481106136b557fe5b906000526020600020906004020160030154838c815181106136d357fe5b6020026020010181815250508a6001019a505b600101613480565b5060008415613964576002546040516303702b2960e51b815261100491636e056520918891613728918e918e918d914201906004016163e9565b6020604051808303818588803b15801561374157600080fd5b505af193505050508015613772575060408051601f3d908101601f1916820190925261376f9181019061610e565b60015b6138e9576040516000815260443d101561378e57506000613829565b60046000803e60005160e01c6308c379a081146137af576000915050613829565b60043d036004833e81513d60248201116001600160401b03821117156137da57600092505050613829565b80830180516001600160401b038111156137fb576000945050505050613829565b8060208301013d860181111561381957600095505050505050613829565b601f01601f191660405250925050505b806138345750613876565b60019150857fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf28082604051613868919061646e565b60405180910390a2506138e4565b3d8080156138a0576040519150601f19603f3d011682016040523d82523d6000602084013e6138a5565b606091505b5060019150857fbfa884552dd8921b6ce90bfe906952ae5b3b29be0cc1a951d4f62697635a3a45826040516138da919061646e565b60405180910390a2505b613964565b801561392b577fa217d08e65f80c73121cd9db834d81652d544bfbf452f6d04922b16c90a37b708660405161391e9190616ef0565b60405180910390a1613962565b857fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf28060405161395990616530565b60405180910390a25b505b8015613b1a5760005b8751811015613b1857600088828151811061398457fe5b6020026020010151905060006001828154811061399d57fe5b60009182526020909120600160049092020181015481546001600160a01b03909116916108fc91859081106139ce57fe5b9060005260206000209060040201600301549081150290604051600060405180830381858888f1935050505090508015613a8a5760018281548110613a0f57fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d9185908110613a5e57fe5b906000526020600020906004020160030154604051613a7d9190616ef0565b60405180910390a2613b0e565b60018281548110613a9757fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d9185908110613ae657fe5b906000526020600020906004020160030154604051613b059190616ef0565b60405180910390a25b505060010161396d565b505b835115613c645760005b8451811015613c62576000858281518110613b3b57fe5b60200260200101516001600160a01b03166108fc868481518110613b5b57fe5b60200260200101519081150290604051600060405180830381858888f1935050505090508015613bf157858281518110613b9157fe5b60200260200101516001600160a01b03167f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d868481518110613bcf57fe5b6020026020010151604051613be49190616ef0565b60405180910390a2613c59565b858281518110613bfd57fe5b60200260200101516001600160a01b03167f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d868481518110613c3b57fe5b6020026020010151604051613c509190616ef0565b60405180910390a25b50600101613b24565b505b5050505050505050505050506000471115613ce0577f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d47604051613ca89190616ef0565b60405180910390a1604051611002904780156108fc02916000818181858888f19350505050158015613cde573d6000803e3d6000fd5b505b60006003819055600555815115613cfb57613cfb8282614f0e565b6110016001600160a01b031663fc4333cd6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015613d3857600080fd5b505af1158015613d4c573d6000803e3d6000fd5b50506040517fedd8d7296956dd970ab4de3f2fc03be2b0ffc615d20cd4c72c6e44f928630ebf925060009150a1506000949350505050565b80516001600160a01b0316600090815260046020526040812054801580613dd55750600180820381548110613db557fe5b9060005260206000209060040201600201601c9054906101000a900460ff165b15613e1b5782516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a2600091505061130b565b600154600554600019820111801590613e715784516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a26000935050505061130b565b600580546001908101909155805481906000198601908110613e8f57fe5b6000918252602082206002600490920201018054921515600160e01b0260ff60e01b199093169290921790915585516040516001600160a01b03909116917ff226e7d8f547ff903d9d419cf5f54e0d7d07efa9584135a53a057c5f1f27f49a91a2506000949350505050565b6000610ea283836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506156ed565b6000610ea283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250615724565b600082613f8e575060006113bb565b82820282848281613f9b57fe5b0414610ea25760405162461bcd60e51b8152600401610c3b90616ac5565b600082820183811015610ea25760405162461bcd60e51b8152600401610c3b90616664565b60008060018381548110613fee57fe5b906000526020600020906004020160030154905060006001808054905003905060016140186125ab565b511161404d5760006001858154811061402d57fe5b9060005260206000209060040201600301819055506000925050506113bb565b846001600160a01b03167f3b6f9ef90462b512a1293ecec018670bf7b7f1876fb727590a8a6d7643130a70836040516140869190616ef0565b60405180910390a26001600160a01b038516600090815260046020526040812055835b6001546000190181101561427357600181600101815481106140c757fe5b9060005260206000209060040201600182815481106140e257fe5b60009182526020909120825460049092020180546001600160a01b03199081166001600160a01b0393841617825560018085015481840180548416918616919091179055600280860180549185018054909416919095161780835584546001600160401b03600160a01b91829004160267ffffffffffffffff60a01b1990911617808355935460ff600160e01b918290041615150260ff60e01b19909416939093179055600392830154920191909155600b8054909183019081106141a357fe5b9060005260206000209060160201600b82815481106141be57fe5b600091825260209091208254601690920201908155600180830154818301805460ff909216151560ff1990921691909117905560028084018054614215938386019390821615610100026000190190911604615eba565b5061422860038281019084016013615f2f565b5090505080600101600460006001848154811061424157fe5b600091825260208083206004909202909101546001600160a01b031683528201929092526040019020556001016140a9565b50600180548061427f57fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b8054806142d257fe5b60008281526020812060166000199093019283020181815560018101805460ff19169055906143046002830182615f59565b614312600383016000615f9d565b50509055600081838161432157fe5b04905080156143855760015460005b8181101561438257826001828154811061434657fe5b906000526020600020906004020160030154016001828154811061436657fe5b6000918252602090912060036004909202010155600101614330565b50505b50600195945050505050565b6001548151604080518281526020808402820101909152606092919083908280156143d057816020015b60608152602001906001900390816143bb5790505b50600b5490915083146143e757925061130b915050565b60005b828110156144f657600b60016004600089858151811061440657fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002054038154811061443a57fe5b600091825260209182902060026016909202018101805460408051601f6000196101006001861615020190931694909404918201859004850284018501905280835291929091908301828280156144d25780601f106144a7576101008083540402835291602001916144d2565b820191906000526020600020905b8154815290600101906020018083116144b557829003601f168201915b50505050508282815181106144e357fe5b60209081029190910101526001016143ea565b50949350505050565b60005b8281101561464c57600082878388016040516020016145229291906162e9565b6040516020818303038152906040528051906020012060001c8161454257fe5b06905080850182870114614643576000898388018151811061456057fe5b602002602001015190506060898489018151811061457a57fe5b602002602001015190508a8388018151811061459257fe5b60200260200101518b858a01815181106145a857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050818b848901815181106145d757fe5b60200260200101906001600160a01b031690816001600160a01b031681525050898388018151811061460557fe5b60200260200101518a858a018151811061461b57fe5b6020026020010181905250808a8489018151811061463557fe5b602002602001018190525050505b50600101614502565b5050505050505050565b600980546001908101909155600b80548390811061467057fe5b906000526020600020906016020160010160006101000a81548160ff02191690831515021790555043600b82815481106146a657fe5b600091825260208220601690910201919091556040516001600160a01b038416917ff62981a567ec3cec866c6fa93c55bcdf841d6292d18b8d522ececa769375d82d91a25050565b60008160405160200161470191906162cd565b604051602081830303815290604052805190602001208360405160200161472891906162cd565b6040516020818303038152906040528051906020012014905092915050565b015190565b6001600160a01b038116600090815260046020526040812054806147755750600019905061130b565b60018103905060006001828154811061478a57fe5b90600052602060002090600402016003015490506000600183815481106147ad57fe5b6000918252602090912060036004909202010155600154604051600019909101906001600160a01b038616907f8cd4e147d8af98a9e3b6724021b8bf6aed2e5dac71c38f2dce8161b82585b25d90614806908590616ef0565b60405180910390a28061481e5782935050505061130b565b600081838161482957fe5b04905080156148e55760005b8481101561488757816001828154811061484b57fe5b906000526020600020906004020160030154016001828154811061486b57fe5b6000918252602090912060036004909202010155600101614835565b50600180549085015b818110156148e25782600182815481106148a657fe5b90600052602060002090600402016003015401600182815481106148c657fe5b6000918252602090912060036004909202010155600101614890565b50505b5091949350505050565b6148f7615fac565b506040805180820190915281518152602082810190820152919050565b61491c615e65565b61492582615750565b61492e57600080fd5b600061493d836020015161578a565b60208085015160408051808201909152868152920190820152915050919050565b6000614968615fac565b505080518051602091820151919092015191011190565b614987615fac565b6149908261495e565b61499957600080fd5b602082015160006149a9826157ed565b80830160209586015260408051808201909152908152938401919091525090919050565b8051600090158015906149e257508151602110155b6149eb57600080fd5b60006149fa836020015161578a565b90508083600001511015614a205760405162461bcd60e51b8152600401610c3b90616c83565b8251602080850151830180519284900392918310156144f657506020919091036101000a90049392505050565b6060614a5882615750565b614a6157600080fd5b6000614a6c836158ce565b9050606081604051908082528060200260200182016040528015614aaa57816020015b614a97615fac565b815260200190600190039081614a8f5790505b5090506000614abc856020015161578a565b60208601510190506000805b84811015614b1357614ad9836157ed565b9150604051806040016040528083815260200184815250848281518110614afc57fe5b602090810291909101015291810191600101614ac8565b509195945050505050565b614b26615e85565b60606000614b32615e85565b6060614b3c615e65565b614b4587614914565b90506000805b614b548361495e565b15614c295780614b7f57614b6f614b6a8461497f565b61592a565b6001600160a01b03168552614c21565b8060011415614ba757614b94614b6a8461497f565b6001600160a01b03166020860152614c21565b8060021415614bcf57614bbc614b6a8461497f565b6001600160a01b03166040860152614c21565b8060031415614bfb57614be4612f638461497f565b6001600160401b0316606086015260019150614c21565b8060041415614c1c57614c15614c108461497f565b615944565b9350614c21565b614c29565b600101614b4b565b50929791965091945092505050565b60606113bb614c46836159b4565b615a9a565b6060815160001415614c6c575060408051600081526020810190915261130b565b606082600081518110614c7b57fe5b602002602001015190506000600190505b8351811015614cbc57614cb282858381518110614ca557fe5b6020026020010151615aec565b9150600101614c8c565b50610ea2614ccf825160c060ff16615b69565b82615aec565b606080600080808080614ce66126a7565b6001549091505b8015614df457600181039250600b8381548110614d0657fe5b600091825260209091206001601690920201015460ff16614d2657614deb565b60018381548110614d3357fe5b60009182526020909120600490910201546001600160a01b03169450614d5a858484612d27565b9350831580614d6d575060018a51038610155b15614d7757614deb565b60005b8a51811015614de957856001600160a01b03168b8281518110614d9957fe5b6020026020010151600001516001600160a01b03161415614de15760018b8281518110614dc257fe5b6020908102919091010151901515608090910152600190960195614de9565b600101614d7a565b505b60001901614ced565b5084895103604051908082528060200260200182016040528015614e3257816020015b614e1f615e85565b815260200190600190039081614e175790505b50965084895103604051908082528060200260200182016040528015614e6c57816020015b6060815260200190600190039081614e575790505b5095506000915060005b8951811015614f0057898181518110614e8b57fe5b602002602001015160800151614ef857898181518110614ea757fe5b6020026020010151888481518110614ebb57fe5b6020026020010181905250888181518110614ed257fe5b6020026020010151878481518110614ee657fe5b60200260200101819052508260010192505b600101614e76565b5050505050505b9250929050565b600154825160005b8281101561502b576001614f28615e85565b60018381548110614f3557fe5b600091825260208083206040805160c08101825260049490940290910180546001600160a01b0390811685526001820154811693850193909352600281015492831691840191909152600160a01b82046001600160401b03166060840152600160e01b90910460ff16151560808301526003015460a082015291505b84811015614fff57878181518110614fc557fe5b6020026020010151600001516001600160a01b031682600001516001600160a01b03161415614ff75760009250614fff565b600101614fb1565b5081156150215780516001600160a01b03166000908152600460205260408120555b5050600101614f16565b50808211156150ea57805b828110156150e857600180548061504957fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b80548061509c57fe5b60008281526020812060166000199093019283020181815560018101805460ff19169055906150ce6002830182615f59565b6150dc600383016000615f9d565b50509055600101615036565b505b60008183106150f957816150fb565b825b905060005b8181101561549f576151ad86828151811061511757fe5b60200260200101516001838154811061512c57fe5b60009182526020918290206040805160c08101825260049390930290910180546001600160a01b0390811684526001820154811694840194909452600281015493841691830191909152600160a01b83046001600160401b03166060830152600160e01b90920460ff161515608082015260039091015460a0820152615c3b565b6153615780600101600460008884815181106151c557fe5b6020026020010151600001516001600160a01b03166001600160a01b031681526020019081526020016000208190555085818151811061520157fe5b60200260200101516001828154811061521657fe5b6000918252602091829020835160049092020180546001600160a01b039283166001600160a01b0319918216178255928401516001820180549184169185169190911790556040840151600282018054606087015160808801511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909716929097169190911792909216939093171692909217905560a09091015160039091015584518590829081106152d157fe5b6020026020010151600b82815481106152e657fe5b9060005260206000209060160201600201908051906020019061530a929190615d9a565b506000600b828154811061531a57fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b80548390811061534b57fe5b6000918252602090912060169091020155615497565b61542785828151811061537057fe5b6020026020010151600b838154811061538557fe5b600091825260209182902060026016909202018101805460408051601f60001961010060018616150201909316949094049182018590048502840185019052808352919290919083018282801561541d5780601f106153f25761010080835404028352916020019161541d565b820191906000526020600020905b81548152906001019060200180831161540057829003601f168201915b5050505050615cbc565b6154725784818151811061543757fe5b6020026020010151600b828154811061544c57fe5b90600052602060002090601602016002019080519060200190615470929190615d9a565b505b60006001828154811061548157fe5b9060005260206000209060040201600301819055505b600101615100565b5082821115615677576154b0615d6b565b835b83811015615674578581815181106154c657fe5b6020026020010151826040018190525060018782815181106154e457fe5b6020908102919091018101518254600181810185556000948552838520835160049093020180546001600160a01b039384166001600160a01b0319918216178255848601518284018054918616918316919091179055604080860151600284018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909a1692909616919091179290921696909617169190911790935560a090930151600390930192909255600b8054928301815590935284516016909102600080516020616fa38339815191528101918255858301516000805160206175d28339815191528201805491151560ff199092169190911790559285015180518694929361561a93600080516020616fc383398151915201920190615d9a565b5060608201516156309060038301906013615e14565b505050806001016004600089848151811061564757fe5b602090810291909101810151516001600160a01b03168252810191909152604001600020556001016154b2565b50505b6000600981905560015493505b838110156156e5576000600b828154811061569b57fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b8054839081106156cc57fe5b6000918252602090912060169091020155600101615684565b505050505050565b6000818361570e5760405162461bcd60e51b8152600401610c3b919061646e565b50600083858161571a57fe5b0495945050505050565b600081848411156157485760405162461bcd60e51b8152600401610c3b919061646e565b505050900390565b80516000906157615750600061130b565b6020820151805160001a9060c08210156157805760009250505061130b565b5060019392505050565b8051600090811a60808110156157a457600091505061130b565b60b88110806157bf575060c081108015906157bf575060f881105b156157ce57600191505061130b565b60c08110156157e25760b51901905061130b565b60f51901905061130b565b80516000908190811a608081101561580857600191506158c7565b60b881101561581d57607e19810191506158c7565b60c081101561586e57600060b78203600186019550806020036101000a8651049150600181018201935050808310156158685760405162461bcd60e51b8152600401610c3b90616a12565b506158c7565b60f88110156158835760be19810191506158c7565b600060f78203600186019550806020036101000a8651049150600181018201935050808310156158c55760405162461bcd60e51b8152600401610c3b90616a12565b505b5092915050565b80516000906158df5750600061130b565b600080905060006158f3846020015161578a565b602085015185519181019250015b8082101561592157615912826157ed565b82019150826001019250615901565b50909392505050565b805160009060151461593b57600080fd5b6113bb826149cd565b805160609061595257600080fd5b6000615961836020015161578a565b83516040805191839003808352601f19601f8201168301602001909152919250606090828015615998576020820181803683370190505b50905060008160200190506144f6848760200151018285615d20565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166159f857506018615a1c565b6fffffffffffffffffffffffffffffffff198416615a1857506010615a1c565b5060005b6020811015615a5257818181518110615a3157fe5b01602001516001600160f81b03191615615a4a57615a52565b600101615a1c565b60008160200390506060816040519080825280601f01601f191660200182016040528015615a87576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015615acc5750607f60f81b82600081518110615aba57fe5b01602001516001600160f81b03191611155b15615ad857508061130b565b6113bb615aea8351608060ff16615b69565b835b6060806040519050835180825260208201818101602087015b81831015615b1d578051835260209283019201615b05565b50855184518101855292509050808201602086015b81831015615b4a578051835260209283019201615b32565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310615b935760405162461bcd60e51b8152600401610c3b90616816565b60408051600180825281830190925260609160208201818036833701905050905060378411615bed5782840160f81b81600081518110615bcf57fe5b60200101906001600160f81b031916908160001a90535090506113bb565b6060615bf8856159b4565b90508381510160370160f81b82600081518110615c1157fe5b60200101906001600160f81b031916908160001a905350615c328282615aec565b95945050505050565b805182516000916001600160a01b039182169116148015615c75575081602001516001600160a01b031683602001516001600160a01b0316145b8015615c9a575081604001516001600160a01b031683604001516001600160a01b0316145b8015610ea25750506060908101519101516001600160401b0390811691161490565b815181516000916001918114808314615cd85760009250615d16565b600160208701838101602088015b600284838510011415615d11578051835114615d055760009650600093505b60209283019201615ce6565b505050505b5090949350505050565b80615d2a57610c5b565b5b60208110615d4a578251825260209283019290910190601f1901615d2b565b915181516020939093036101000a6000190180199091169216919091179052565b60405180608001604052806000815260200160001515815260200160608152602001615d95615fc6565b905290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615ddb57805160ff1916838001178555615e08565b82800160010185558215615e08579182015b82811115615e08578251825591602001919060010190615ded565b506126e2929150615fe5565b8260138101928215615e085791602002820182811115615e08578251825591602001919060010190615ded565b6040518060600160405280600060ff16815260200160608152602001606081525090565b6040518060400160405280615e78615fac565b8152602001600081525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615ef35780548555615e08565b82800160010185558215615e0857600052602060002091601f016020900482015b82811115615e08578254825591600101919060010190615f14565b8260138101928215615e085791820182811115615e08578254825591600101919060010190615f14565b50805460018160011615610100020316600290046000825580601f10615f7f5750611517565b601f0160209004906000526020600020908101906115179190615fe5565b50611517906013810190615fe5565b604051806040016040528060008152602001600081525090565b6040518061026001604052806013906020820280368337509192915050565b61269491905b808211156126e25760008155600101615feb565b60008083601f840112616010578182fd5b5081356001600160401b03811115616026578182fd5b6020830191508360208083028501011115614f0757600080fd5b60008083601f840112616051578182fd5b5081356001600160401b03811115616067578182fd5b602083019150836020828501011115614f0757600080fd5b600060208284031215616090578081fd5b81356001600160a01b0381168114610ea2578182fd5b600080600080604085870312156160bb578283fd5b84356001600160401b03808211156160d1578485fd5b6160dd88838901615fff565b909650945060208701359150808211156160f5578384fd5b5061610287828801615fff565b95989497509550505050565b60006020828403121561611f578081fd5b81518015158114610ea2578182fd5b60008060008060408587031215616143578384fd5b84356001600160401b0380821115616159578586fd5b61616588838901616040565b9096509450602087013591508082111561617d578384fd5b5061610287828801616040565b60006020828403121561619b578081fd5b5035919050565b6000602082840312156161b3578081fd5b5051919050565b600080604083850312156161cc578182fd5b505080516020909101519092909150565b6000806000604084860312156161f1578283fd5b833560ff81168114616201578384fd5b925060208401356001600160401b0381111561621b578283fd5b61622786828701616040565b9497909650939450505050565b6000815180845260208085019450808401835b8381101561626c5781516001600160a01b031687529582019590820190600101616247565b509495945050505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b600081518084526162b9816020860160208601616f56565b601f01601f19169290920160200192915050565b600082516162df818460208701616f56565b9190910192915050565b918252602082015260400190565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03968716815294861660208601529290941660408401526001600160401b03166060830152911515608082015260a081019190915260c00190565b600060208252610ea26020830184616234565b60006040825261638c6040830185616234565b602083820381850152818551808452828401915082838202850101838801865b838110156163da57601f198784030185526163c88383516162a1565b948601949250908501906001016163ac565b50909998505050505050505050565b6000608082526163fc6080830187616234565b828103602084810191909152865180835287820192820190845b8181101561643257845183529383019391830191600101616416565b505084810360408601526164468188616234565b93505050506001600160401b038316606083015295945050505050565b901515815260200190565b600060208252610ea260208301846162a1565b600060408252616495604083018688616277565b82810360208401526164a8818587616277565b979650505050505050565b6020808252601c908201527f6c656e677468206f66206275726e526174696f206d69736d6174636800000000604082015260600190565b60208082526026908201527f6c656e677468206f66206d61784e756d4f664d61696e7461696e696e67206d696040820152650e6dac2e8c6d60d31b606082015260800190565b6020808252601b908201527f6261746368207472616e736665722072657475726e2066616c73650000000000604082015260600190565b6020808252602c908201527f6c656e677468206f66206d61784e756d4f66576f726b696e6743616e6469646160408201526b0e8cae640dad2e6dac2e8c6d60a31b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61696e7461696e536c6173685363616c65206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252818101527f6c656e677468206f66206e756d4f66436162696e657473206d69736d61746368604082015260600190565b60208082526019908201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526028908201527f746865206e756d4f66436162696e657473206d75737420626520677265617465604082015267072207468616e20360c41b606082015260800190565b60208082526039908201527f746865206e756d4f66436162696e657473206d757374206265206c657373207460408201527f68616e204d41585f4e554d5f4f465f56414c494441544f525300000000000000606082015260800190565b60208082526029908201527f746865206e756d626572206f662076616c696461746f727320657863656564206040820152681d1a19481b1a5b5a5d60ba1b606082015260800190565b60208082526022908201527f63616e206e6f7420646f207468697320747769636520696e206f6e6520626c6f604082015261636b60f01b606082015260800190565b6020808252602b908201527f746865206275726e526174696f206d757374206265206e6f206772656174657260408201526a0207468616e2031303030360ac1b606082015260800190565b6020808252600e908201526d696e70757420746f6f206c6f6e6760901b604082015260600190565b60208082526037908201527f746865206d61784e756d4f664d61696e7461696e696e67206d7573742062652060408201527f6c657373207468616e206e756d4f66436162696e657473000000000000000000606082015260800190565b6020808252602b908201527f6475706c696361746520636f6e73656e7375732061646472657373206f66207660408201526a185b1a59185d1bdc94d95d60aa1b606082015260800190565b60208082526027908201527f7468652065787069726554696d655365636f6e64476170206973206f7574206f604082015266662072616e676560c81b606082015260800190565b6020808252601590820152746465706f7369742076616c7565206973207a65726f60581b604082015260600190565b60208082526049908201527f746865206d61784e756d4f66576f726b696e6743616e64696461746573206d7560408201527f7374206265206e6f742067726561746572207468616e206d61784e756d4f6643606082015268616e6469646174657360b81b608082015260a00190565b60208082526027908201527f7468652066696e616c697479526577617264526174696f206973206f7574206f604082015266662072616e676560c81b606082015260800190565b6020808252601190820152706164646974696f6e206f766572666c6f7760781b604082015260600190565b60208082526023908201527f63616e206e6f7420656e7465722054656d706f72617279204d61696e74656e616040820152626e636560e81b606082015260800190565b60208082526025908201527f6c656e677468206f66206a61696c2076616c696461746f7273206d757374206260408201526465206f6e6560d81b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252602e908201527f746865206d6573736167652073656e646572206d75737420626520676f76657260408201526d1b985b98d94818dbdb9d1c9858dd60921b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61784e756d4f6643616e64696461746573206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252601290820152716e6f7420696e206d61696e74656e616e636560701b604082015260600190565b60208082526021908201527f666565206973206c6172676572207468616e2044555354595f494e434f4d494e6040820152604760f81b606082015260800190565b60208082526019908201527f74686520636f6e747261637420616c726561647920696e697400000000000000604082015260600190565b60208082526026908201527f6c656e677468206f662066696e616c697479526577617264526174696f206d696040820152650e6dac2e8c6d60d31b606082015260800190565b6020808252601a908201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604082015260600190565b60208082526026908201527f6c656e677468206f662065787069726554696d655365636f6e64476170206d696040820152650e6dac2e8c6d60d31b606082015260800190565b60208082526017908201527f6f6e6c792063757272656e742076616c696461746f7273000000000000000000604082015260600190565b60208082526021908201527f6661696c656420746f20706172736520696e69742076616c696461746f7253656040820152601d60fa1b606082015260800190565b6020808252602f908201527f746865206d6573736167652073656e646572206d7573742062652063726f737360408201526e0818da185a5b8818dbdb9d1c9858dd608a1b606082015260800190565b6020808252602d908201527f746865206d6573736167652073656e646572206d75737420626520746865206260408201526c3637b1b590383937b23ab1b2b960991b606082015260800190565b6020808252603e908201527f746865206d61696e7461696e536c6173685363616c65206d757374206265206760408201527f726561746572207468616e203020616e64206c657373207468616e2031300000606082015260800190565b6020808252600d908201526c756e6b6e6f776e20706172616d60981b604082015260600190565b60208082526029908201527f746865206d6573736167652073656e646572206d75737420626520736c6173686040820152680818dbdb9d1c9858dd60ba1b606082015260800190565b61ffff91909116815260200190565b90815260200190565b6000848252831515602083015260606040830152615c3260608301846162a1565b63ffffffff91909116815260200190565b60ff91909116815260200190565b600060ff8516825260406020830152615c32604083018486616277565b60005b83811015616f71578181015183820152602001616f59565b83811115612c47575050600091015256fe70e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb20175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db90175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbbf905ec80f905e8f846942a7cdd959bfe8d9487b2a43b33565295a698f7e294b6a7edd747c0554875d3fc531d19ba1497992c5e941ff80f3f7f110ffd8920a3ac38fdef318fe94a3f86048c27395000f846946488aa4d1955ee33403f8ccb1d4de5fb97c7ade294220f003d8bdfaadf52aa1e55ae4cc485e6794875941a87e90e440a39c99aa9cb5cea0ad6a3f0b2407b86048c27395000f846949ef9f4360c606c7ab4db26b016007d3ad0ab86a0946103af86a874b705854033438383c82575f25bc29418e2db06cbff3e3c5f856410a1838649e760175786048c27395000f84694ee01c3b1283aa067c58eab4709f85e99d46de5fe94ee4b9bfb1871c64e2bcabb1dc382dc8b7c4218a29415904ab26ab0e99d70b51c220ccdcccabee6e29786048c27395000f84694685b1ded8013785d6623cc18d214320b6bb6475994a20ef4e5e4e7e36258dbf51f4d905114cb1b34bc9413e39085dc88704f4394d35209a02b1a9520320c86048c27395000f8469478f3adfc719c99674c072166708589033e2d9afe9448a30d5eaa7b64492a160f139e2da2800ec3834e94055838358c29edf4dcc1ba1985ad58aedbb6be2b86048c27395000f84694c2be4ec20253b8642161bc3f444f53679c1f3d479466f50c616d737e60d7ca6311ff0d9c434197898a94d1d678a2506eeaa365056fe565df8bc8659f28b086048c27395000f846942f7be8361c80a4c1e7e9aaf001d0877f1cfde218945f93992ac37f3e61db2ef8a587a436a161fd210b94ecbc4fb1a97861344dad0867ca3cba2b860411f086048c27395000f84694ce2fd7544e0b2cc94692d4a704debef7bcb613289444abc67b4b2fba283c582387f54c9cba7c34bafa948acc2ab395ded08bb75ce85bf0f95ad2abc51ad586048c27395000f84694b8f7166496996a7da21cf1f1b04d9b3e26a3d077946770572763289aac606e4f327c2f6cc1aa3b3e3b94882d745ed97d4422ca8da1c22ec49d880c4c097286048c27395000f846942d4c407bbe49438ed859fe965b140dcf1aab71a9943ad0939e120f33518fbba04631afe7a3ed6327b194b2bbb170ca4e499a2b0f3cc85ebfa6e8c4dfcbea86048c27395000f846946bbad7cf34b5fa511d8e963dbba288b1960e75d694853b0f6c324d1f4e76c8266942337ac1b0af1a229442498946a51ca5924552ead6fc2af08b94fcba648601d1a94a2000f846944430b3230294d12c6ab2aac5c2cd68e80b16b581947b107f4976a252a6939b771202c28e64e03f52d694795811a7f214084116949fc4f53cedbf189eeab28601d1a94a2000f84694ea0a6e3c511bbd10f4519ece37dc24887e11b55d946811ca77acfb221a49393c193f3a22db829fcc8e9464feb7c04830dd9ace164fc5c52b3f5a29e5018a8601d1a94a2000f846947ae2f5b9e386cd1b50a4550696d957cb4900f03a94e83bcc5077e6b873995c24bac871b5ad856047e19464e48d4057a90b233e026c1041e6012ada897fe88601d1a94a2000f8469482012708dafc9e1b880fd083b32182b869be8e09948e5adc73a2d233a1b496ed3115464dd6c7b887509428b383d324bc9a37f4e276190796ba5a8947f5ed8601d1a94a2000f8469422b81f8e175ffde54d797fe11eb03f9e3bf75f1d94a1c3ef7ca38d8ba80cce3bfc53ebd2903ed21658942767f7447f7b9b70313d4147b795414aecea54718601d1a94a2000f8469468bf0b8b6fb4e317a0f9d6f03eaf8ce6675bc60d94675cfe570b7902623f47e7f59c9664b5f5065dcf94d84f0d2e50bcf00f2fc476e1c57f5ca2d57f625b8601d1a94a2000f846948c4d90829ce8f72d0163c1d5cf348a862d5506309485c42a7b34309bee2ed6a235f86d16f059deec5894cc2cedc53f0fa6d376336efb67e43d167169f3b78601d1a94a2000f8469435e7a025f4da968de7e4d7e4004197917f4070f194b1182abaeeb3b4d8eba7e6a4162eac7ace23d57394c4fd0d870da52e73de2dd8ded19fe3d26f43a1138601d1a94a2000f84694d6caa02bbebaebb5d7e581e4b66559e635f805ff94c07335cf083c1c46a487f0325769d88e163b653694efaff03b42e41f953a925fc43720e45fb61a19938601d1a94a20000175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbaa26469706673582212206cf6e773ca0b0d999abe4e586cd00abd836c1f2e74f76626269d55c8fc09634364736f6c63430006040033", + }, + { + ContractAddr: SlashContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "608060405234801561001057600080fd5b506004361061027f5760003560e01c80637942fd051161015c578063c80d4b8f116100ce578063dc927faf11610087578063dc927faf146104ad578063e1c7392a146104b5578063f9a2bbc7146104bd578063fc3e5908146104c5578063fc4333cd146104cd578063fd6a6879146104d55761027f565b8063c80d4b8f1461045c578063c81b166214610464578063c8509d811461046c578063c96be4cb1461047f578063cc844b7314610492578063d2a42e4b146104a55761027f565b80639dc09262116101205780639dc0926214610421578063a1a11bf514610429578063a78abc1614610431578063ab51bb9614610439578063ac0af62914610441578063ac431751146104495761027f565b80637942fd05146103ee5780638256ace6146103f6578063831d65d1146103fe57806396713da9146104115780639bc8e4f2146104195761027f565b8063493279b1116101f557806362b72cf5116101b957806362b72cf5146103be5780636e47b482146103c657806370fd5bad146103ce578063718a8aa8146103d657806375d47a0a146103de5780637912a65d146103e65761027f565b8063493279b11461037c5780634bf6c8821461039157806351e8067214610399578063567a372d146103a15780635bfb4990146103a95761027f565b806335aa2e441161024757806335aa2e441461030e57806337c8dab914610321578063389f4f71146103425780633a63f4b1146103575780633dffc3871461035f57806343756e5c146103745761027f565b80630bee7a67146102845780630e2374a5146102a25780631182b875146102b757806322d1e80b146102d757806323bac5a2146102ec575b600080fd5b61028c6104dd565b60405161029991906132a4565b60405180910390f35b6102aa6104e2565b6040516102999190612b82565b6102ca6102c5366004612ab8565b6104e8565b6040516102999190612bba565b6102df61054e565b6040516102999190612baf565b6102ff6102fa366004612866565b610557565b6040516102999392919061328c565b6102aa61031c366004612a88565b61057a565b61033461032f366004612866565b6105a1565b60405161029992919061327e565b61034a6105f8565b6040516102999190613254565b61034a6105fe565b610367610604565b60405161029991906132b5565b6102aa610609565b61038461060f565b6040516102999190613245565b610367610614565b6102aa610619565b61034a61061f565b6103bc6103b7366004612866565b610625565b005b61034a6106d0565b6102aa6106d6565b6103676106dc565b6103676106e1565b6102aa6106e6565b61034a6106ec565b6103676106f1565b6103346106f6565b6103bc61040c366004612ab8565b610700565b610367610812565b61034a610817565b6102aa610822565b6102aa610828565b6102df61082e565b61028c610837565b61034a61083c565b6103bc61045736600461296c565b610841565b61034a610ce0565b6102aa610ce5565b6103bc61047a366004612ab8565b610ceb565b6103bc61048d366004612866565b610d5c565b6103bc6104a03660046129d5565b61114d565b61034a61169a565b6102aa61169f565b6103bc6116a5565b6102aa6116e1565b6103676116e7565b6103bc6116ec565b6102aa611b35565b606481565b61200181565b606033612000146105145760405162461bcd60e51b815260040161050b906130cb565b60405180910390fd5b60005460ff166105365760405162461bcd60e51b815260040161050b90612c9b565b60405162461bcd60e51b815260040161050b9061318e565b60075460ff1681565b600260208190526000918252604090912080546001820154919092015460ff1683565b6001818154811061058757fe5b6000918252602090912001546001600160a01b0316905081565b6000806105ac61264d565b5050506001600160a01b0316600090815260026020818152604092839020835160608101855281548082526001830154938201849052919093015460ff16151592909301919091529091565b60055481565b60065481565b600181565b61100181565b603881565b600881565b61200081565b60045481565b33611000146106465760405162461bcd60e51b815260040161050b90612edf565b60005460ff166106685760405162461bcd60e51b815260040161050b90612c9b565b61200063f7a251d7600b61067b84611b3b565b60006040518463ffffffff1660e01b815260040161069b939291906132c3565b600060405180830381600087803b1580156106b557600080fd5b505af11580156106c9573d6000803e3d6000fd5b5050505050565b60035481565b61100581565b600281565b601081565b61100881565b603281565b600b81565b6004546005549091565b33612000146107215760405162461bcd60e51b815260040161050b906130cb565b60005460ff166107435760405162461bcd60e51b815260040161050b90612c9b565b61074b612670565b600061078c84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c0d92505050565b9150915080156107d35781516040517f7f0956d47419b9525356e7111652b653b530ec6f5096dccc04589bc38e629967916107c6916132a4565b60405180910390a16106c9565b81516040517f7d45f62d17443dd4547bca8a8112c60e2385669318dc300ec61a5d2492f262e791610803916132a4565b60405180910390a15050505050565b600981565b662386f26fc1000081565b61100781565b61100681565b60005460ff1681565b600081565b600481565b60005460ff166108635760405162461bcd60e51b815260040161050b90612c9b565b33611007146108845760405162461bcd60e51b815260040161050b90612f88565b6108ef84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260148152731b5a5cd9195b59585b9bdc951a1c995cda1bdb1960621b60208201529150611c8d9050565b1561098a57602081146109145760405162461bcd60e51b815260040161050b90612e6b565b604080516020601f840181900481028201810190925282815260009161095291858580838501838280828437600092019190915250611ce792505050565b905060018110158015610966575060055481105b6109825760405162461bcd60e51b815260040161050b90613086565b600455610c9d565b6109f084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e19995b1bdb9e551a1c995cda1bdb19608a1b60208201529150611c8d9050565b15610a8c5760208114610a155760405162461bcd60e51b815260040161050b90612fd6565b604080516020601f8401819004810282018101909252828152600091610a5391858580838501838280828437600092019190915250611ce792505050565b90506103e88111158015610a68575060045481115b610a845760405162461bcd60e51b815260040161050b90612d09565b600555610c9d565b610b0084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601881527f66696e616c697479536c617368526577617264526174696f000000000000000060208201529150611c8d9050565b15610b9a5760208114610b255760405162461bcd60e51b815260040161050b906131c5565b604080516020601f8401819004810282018101909252828152600091610b6391858580838501838280828437600092019190915250611ce792505050565b9050600a8110158015610b765750606481105b610b925760405162461bcd60e51b815260040161050b90612e1f565b600655610c9d565b610c0e84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601881527f656e61626c654d616c6963696f7573566f7465536c617368000000000000000060208201529150611c8d9050565b15610c855760208114610c335760405162461bcd60e51b815260040161050b90612d3e565b604080516020601f8401819004810282018101909252828152610c6f9190848480838501838280828437600092019190915250611cec92505050565b6007805460ff1916911515919091179055610c9d565b60405162461bcd60e51b815260040161050b90613167565b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a84848484604051610cd29493929190612bcd565b60405180910390a150505050565b609681565b61100281565b3361200014610d0c5760405162461bcd60e51b815260040161050b906130cb565b60005460ff16610d2e5760405162461bcd60e51b815260040161050b90612c9b565b6040517f07db600eebe2ac176be8dcebad61858c245a4961bb32ca2aa3d159b09aa0810e90600090a1505050565b334114610d7b5760405162461bcd60e51b815260040161050b9061311a565b60005460ff16610d9d5760405162461bcd60e51b815260040161050b90612c9b565b6003544311610dbe5760405162461bcd60e51b815260040161050b90613210565b3a15610ddc5760405162461bcd60e51b815260040161050b90612f5a565b60405163155853f360e21b8152611000906355614fcc90610e01908490600401612b82565b60206040518083038186803b158015610e1957600080fd5b505afa158015610e2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e51919061294c565b610e5a57611146565b610e6261264d565b506001600160a01b0381166000908152600260208181526040928390208351606081018552815481526001820154928101929092529091015460ff161580159282019290925290610ebd576020810180516001019052610f16565b60016040820181905260208201819052805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0384161790555b438152600554602082015181610f2857fe5b0661107457600060208201526040516335409f7f60e01b8152611000906335409f7f90610f59908590600401612b82565b600060405180830381600087803b158015610f7357600080fd5b505af1158015610f87573d6000803e3d6000fd5b505050506120006001600160a01b031663f7a251d7600b610fa785611b3b565b60006040518463ffffffff1660e01b8152600401610fc7939291906132c3565b600060405180830381600087803b158015610fe157600080fd5b505af1925050508015610ff2575060015b61106f573d808015611020576040519150601f19603f3d011682016040523d82523d6000602084013e611025565b606091505b50826001600160a01b03167fd7bc86ff5d08c8ab043edec743302aba2520e6635172a428bc956721db9e2d1c83602001518360405161106592919061325d565b60405180910390a2505b6110e0565b60045481602001518161108357fe5b066110e0576040516375abf10160e11b81526110009063eb57e202906110ad908590600401612b82565b600060405180830381600087803b1580156110c757600080fd5b505af11580156110db573d6000803e3d6000fd5b505050505b6001600160a01b0382166000818152600260208181526040808420865181559186015160018301558581015191909201805460ff1916911515919091179055517fddb6012116e51abf5436d956a4f0ebd927e92c576ff96d7918290c8782291e3e9190a2505b5043600355565b60005460ff1661116f5760405162461bcd60e51b815260040161050b90612c9b565b604051630a83aaa960e31b81526110069063541d554890611194903390600401612b82565b60206040518083038186803b1580156111ac57600080fd5b505afa1580156111c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e4919061294c565b6112005760405162461bcd60e51b815260040161050b90612bff565b60075460ff166112225760405162461bcd60e51b815260040161050b90612c66565b60065461122f5760146006555b8051514361010090910111801561125157504381602001516000015161010001115b61126d5760405162461bcd60e51b815260040161050b90612c36565b80602001516020015181600001516020015114801561129b5750806020015160600151816000015160600151145b156112b85760405162461bcd60e51b815260040161050b90612eb2565b8051604081015190511080156112d75750602081015160408101519051105b6112f35760405162461bcd60e51b815260040161050b90612de8565b6020810151518151511080156113185750806000015160400151816020015160400151105b8061134357508051516020820151511080156113435750806020015160400151816000015160400151105b8061135d5750806020015160400151816000015160400151145b6113795760405162461bcd60e51b815260040161050b90612cd2565b61138b81600001518260400151611d14565b80156113a457506113a481602001518260400151611d14565b6113c05760405162461bcd60e51b815260040161050b90612d89565b6060806110006001600160a01b0316633b071dcc6040518163ffffffff1660e01b815260040160006040518083038186803b1580156113fe57600080fd5b505afa158015611412573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261143a9190810190612889565b9150915060005b81518110156115775761146b82828151811061145957fe5b60200260200101518560400151611eec565b1561156f576006546040516309a99b4f60e41b815260646110028031909302049190639a99b4f0906114a39033908590600401612b96565b602060405180830381600087803b1580156114bd57600080fd5b505af11580156114d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f59190612aa0565b506110006001600160a01b03166335409f7f85848151811061151357fe5b60200260200101516040518263ffffffff1660e01b81526004016115379190612b82565b600060405180830381600087803b15801561155157600080fd5b505af1158015611565573d6000803e3d6000fd5b5050505050611577565b600101611441565b50600061158984604001516000611f50565b90506120006001600160a01b031663f7a251d7600b6115ab8760400151611f6c565b60006040518463ffffffff1660e01b81526004016115cb939291906132c3565b600060405180830381600087803b1580156115e557600080fd5b505af19250505080156115f6575060015b611668573d808015611624576040519150601f19603f3d011682016040523d82523d6000602084013e611629565b606091505b50817fd58d1183100bd0932c0588f31c4205d6bc6168909765a96c41adbed3115f36288260405161165a9190612bba565b60405180910390a250611694565b60405181907f7b78aadacff901d8b63d0dba4f86283d4db8aef27f9ed70413dd860f1c9532b690600090a25b50505050565b601481565b61100381565b60005460ff16156116c85760405162461bcd60e51b815260040161050b90613018565b603260045560966005556000805460ff19166001179055565b61100081565b600381565b336110001461170d5760405162461bcd60e51b815260040161050b90612edf565b60005460ff1661172f5760405162461bcd60e51b815260040161050b90612c9b565b60015461173b57611b33565b600154600090600019015b808211611b07576000805b8284101561186a5761176161264d565b600260006001878154811061177257fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff161515908201526005549091506004900481602001511115611854576004600554816117df57fe5b0481602001510381602001818152505080600260006001888154811061180157fe5b6000918252602080832091909101546001600160a01b0316835282810193909352604091820190208351815591830151600183015591909101516002909101805460ff191691151591909117905561185e565b600192505061186a565b50836001019350611751565b828411611a015761187961264d565b600260006001868154811061188a57fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff161515908201526005549091506004900481602001511115611972576004600554816118f757fe5b0481602001510381602001818152505080600260006001878154811061191957fe5b6000918252602080832091909101546001600160a01b03168352828101939093526040918201902083518155918301516001808401919091559201516002909101805460ff19169115159190911790559150611a019050565b600260006001868154811061198357fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff191690558054806119c757fe5b600082815260209020810160001990810180546001600160a01b0319169055019055836119f45750611a01565b506000199092019161186a565b818015611a0b5750805b15611aea576002600060018681548110611a2157fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff19169055805484908110611a6857fe5b600091825260209091200154600180546001600160a01b039092169186908110611a8e57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506001805480611ac757fe5b600082815260209020810160001990810180546001600160a01b03191690550190555b82611af6575050611b07565b505060019091019060001901611746565b6040517fcfdb3b6ccaeccbdc68be3c59c840e3b3c90f0a7c491f5fff1cf56cfda200dd9c90600090a150505b565b61100481565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081611b56579050509050611b7f836001600160a01b0316611fa7565b81600081518110611b8c57fe5b6020026020010181905250611ba043611fca565b81600181518110611bad57fe5b6020908102919091010152611bc26038611fca565b81600281518110611bcf57fe5b6020026020010181905250611be342611fca565b81600381518110611bf057fe5b6020026020010181905250611c0481611fdd565b9150505b919050565b611c15612670565b6000611c1f612670565b611c27612682565b611c38611c3386612067565b61208c565b90506000805b611c47836120d6565b15611c805780611c7357611c62611c5d846120f7565b612145565b63ffffffff16845260019150611c78565b611c80565b600101611c3e565b5091935090915050915091565b600081604051602001611ca09190612b66565b6040516020818303038152906040528051906020012083604051602001611cc79190612b66565b604051602081830303815290604052805190602001201490505b92915050565b015190565b8082015160009060ff811615611d06576001915081611d0c565b60009150815b505092915050565b60408051600480825260a0820190925260009160609190816020015b6060815260200190600190039081611d30575050604080516020808252818301909252919250606091908082018180368337019050509050611d758560000151611fca565b82600081518110611d8257fe5b6020026020010181905250611d9d60208660200151836121c7565b611da6816121d7565b82600181518110611db357fe5b6020026020010181905250611dcb8560400151611fca565b82600281518110611dd857fe5b6020026020010181905250611df360208660600151836121c7565b611dfc816121d7565b82600381518110611e0957fe5b6020026020010181905250611e2f6020611e2284611fdd565b80519060200120836121c7565b6040805160b080825260e08201909252606091602082018180368337019050509050611e5f81836000602061222d565b611e718187608001516020606061222d565b611e7f81866080603061222d565b604080516001808252818301909252606091602082018180368337019050509050815160016020830182602086016066600019fa611ebc57600080fd5b506001611eca826000612280565b60ff1614611edf576000945050505050611ce1565b5060019695505050505050565b815181516000916001918114808314611f085760009250611f46565b600160208701838101602088015b600284838510011415611f41578051835114611f355760009650600093505b60209283019201611f16565b505050505b5090949350505050565b60008160200183511015611f6357600080fd5b50016020015190565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081611f87579050509050611b7f836121d7565b60408051600560a21b8318601482015260348101909152606090611c04816121d7565b6060611ce1611fd88361229c565b6121d7565b6060815160001415611ffe5750604080516000815260208101909152611c08565b60608260008151811061200d57fe5b602002602001015190506000600190505b835181101561204e576120448285838151811061203757fe5b6020026020010151612382565b915060010161201e565b50611c04612061825160c060ff166123ff565b82612382565b61206f6126a2565b506040805180820190915281518152602082810190820152919050565b612094612682565b61209d826124d1565b6120a657600080fd5b60006120b5836020015161250b565b60208085015160408051808201909152868152920190820152915050919050565b60006120e06126a2565b505080518051602091820151919092015191011190565b6120ff6126a2565b612108826120d6565b61211157600080fd5b602082015160006121218261256e565b80830160209586015260408051808201909152908152938401919091525090919050565b80516000901580159061215a57508151602110155b61216357600080fd5b6000612172836020015161250b565b905080836000015110156121985760405162461bcd60e51b815260040161050b9061304f565b8251602080850151830180519284900392918310156121be57826020036101000a820491505b50949350505050565b9091018181526020918201910152565b6060815160011480156122095750607f60f81b826000815181106121f757fe5b01602001516001600160f81b03191611155b15612215575080611c08565b611ce16122278351608060ff166123ff565b83612382565b60005b818110156106c95783818151811061224457fe5b602001015160f81c60f81b85848060010195508151811061226157fe5b60200101906001600160f81b031916908160001a905350600101612230565b6000816001018351101561229357600080fd5b50016001015190565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166122e057506018612304565b6fffffffffffffffffffffffffffffffff19841661230057506010612304565b5060005b602081101561233a5781818151811061231957fe5b01602001516001600160f81b031916156123325761233a565b600101612304565b60008160200390506060816040519080825280601f01601f19166020018201604052801561236f576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b818310156123b357805183526020928301920161239b565b50855184518101855292509050808201602086015b818310156123e05780518352602092830192016123c8565b508651929092011591909101601f01601f191660405250905092915050565b60606801000000000000000083106124295760405162461bcd60e51b815260040161050b90612dc0565b604080516001808252818301909252606091602082018180368337019050509050603784116124835782840160f81b8160008151811061246557fe5b60200101906001600160f81b031916908160001a9053509050611ce1565b606061248e8561229c565b90508381510160370160f81b826000815181106124a757fe5b60200101906001600160f81b031916908160001a9053506124c88282612382565b95945050505050565b80516000906124e257506000611c08565b6020820151805160001a9060c082101561250157600092505050611c08565b5060019392505050565b8051600090811a6080811015612525576000915050611c08565b60b8811080612540575060c08110801590612540575060f881105b1561254f576001915050611c08565b60c08110156125635760b519019050611c08565b60f519019050611c08565b80516000908190811a60808110156125895760019150612646565b60b881101561259e57607e1981019150612646565b60c08110156125ef57600060b78203600186019550806020036101000a8651049150600181018201935050808310156125e95760405162461bcd60e51b815260040161050b90612f2f565b50612646565b60f88110156126045760be1981019150612646565b600060f78203600186019550806020036101000a865104915060018101820193505080831015611d0c5760405162461bcd60e51b815260040161050b90612f2f565b5092915050565b604051806060016040528060008152602001600081526020016000151581525090565b60408051602081019091526000815290565b60405180604001604052806126956126a2565b8152602001600081525090565b604051806040016040528060008152602001600081525090565b600082601f8301126126cc578081fd5b81516126df6126da82613316565b6132ef565b818152915060208083019084810160005b84811015612755578151870188603f82011261270b57600080fd5b8381015161271b6126da82613336565b81815260408b8184860101111561273157600080fd5b6127408388840183870161335a565b508652505092820192908201906001016126f0565b505050505092915050565b60008083601f840112612771578182fd5b50813567ffffffffffffffff811115612788578182fd5b6020830191508360208285010111156127a057600080fd5b9250929050565b600082601f8301126127b7578081fd5b81356127c56126da82613336565b91508082528360208285010111156127dc57600080fd5b8060208401602084013760009082016020015292915050565b600060a08284031215612806578081fd5b61281060a06132ef565b905081358152602082013560208201526040820135604082015260608201356060820152608082013567ffffffffffffffff81111561284e57600080fd5b61285a848285016127a7565b60808301525092915050565b600060208284031215612877578081fd5b813561288281613386565b9392505050565b6000806040838503121561289b578081fd5b825167ffffffffffffffff808211156128b2578283fd5b81850186601f8201126128c3578384fd5b805192506128d36126da84613316565b80848252602080830192508084018a8283890287010111156128f3578788fd5b8794505b8685101561291e57805161290a81613386565b8452600194909401939281019281016128f7565b508801519096509350505080821115612935578283fd5b50612942858286016126bc565b9150509250929050565b60006020828403121561295d578081fd5b81518015158114612882578182fd5b60008060008060408587031215612981578182fd5b843567ffffffffffffffff80821115612998578384fd5b6129a488838901612760565b909650945060208701359150808211156129bc578384fd5b506129c987828801612760565b95989497509550505050565b6000602082840312156129e6578081fd5b813567ffffffffffffffff808211156129fd578283fd5b81840160608187031215612a0f578384fd5b612a1960606132ef565b9250803582811115612a29578485fd5b612a35878284016127f5565b845250602081013582811115612a49578485fd5b612a55878284016127f5565b602085015250604081013582811115612a6c578485fd5b612a78878284016127a7565b6040850152509195945050505050565b600060208284031215612a99578081fd5b5035919050565b600060208284031215612ab1578081fd5b5051919050565b600080600060408486031215612acc578283fd5b833560ff81168114612adc578384fd5b9250602084013567ffffffffffffffff811115612af7578283fd5b612b0386828701612760565b9497909650939450505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452612b5281602086016020860161335a565b601f01601f19169290920160200192915050565b60008251612b7881846020870161335a565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b6000602082526128826020830184612b3a565b600060408252612be1604083018688612b10565b8281036020840152612bf4818587612b10565b979650505050505050565b6020808252601f908201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604082015260600190565b6020808252601690820152751d1bdbc81bdb1908189b1bd8dac81a5b9d9bdb1d995960521b604082015260600190565b6020808252818101527f6d616c6963696f757320766f746520736c617368206e6f7420656e61626c6564604082015260600190565b60208082526019908201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604082015260600190565b6020808252601a908201527f6e6f2076696f6c6174696f6e206f6620766f74652072756c6573000000000000604082015260600190565b6020808252818101527f7468652066656c6f6e795468726573686f6c64206f7574206f662072616e6765604082015260600190565b6020808252602b908201527f6c656e677468206f6620656e61626c654d616c6963696f7573566f7465536c6160408201526a0e6d040dad2e6dac2e8c6d60ab1b606082015260800190565b60208082526017908201527f766572696679207369676e6174757265206661696c6564000000000000000000604082015260600190565b6020808252600e908201526d696e70757420746f6f206c6f6e6760901b604082015260600190565b60208082526019908201527f7372634e756d20626967676572207468616e207461724e756d00000000000000604082015260600190565b6020808252602c908201527f7468652066696e616c69747920736c6173682072657761726420726174696f2060408201526b6f7574206f662072616e676560a01b606082015260800190565b60208082526027908201527f6c656e677468206f66206d697364656d65616e6f725468726573686f6c64206d6040820152660d2e6dac2e8c6d60cb1b606082015260800190565b60208082526013908201527274776f206964656e746963616c20766f74657360681b604082015260600190565b60208082526030908201527f746865206d6573736167652073656e646572206d7573742062652076616c696460408201526f185d1bdc94d95d0818dbdb9d1c9858dd60821b606082015260800190565b6020808252601190820152706164646974696f6e206f766572666c6f7760781b604082015260600190565b6020808252601490820152736761737072696365206973206e6f74207a65726f60601b604082015260600190565b6020808252602e908201527f746865206d6573736167652073656e646572206d75737420626520676f76657260408201526d1b985b98d94818dbdb9d1c9858dd60921b606082015260800190565b60208082526022908201527f6c656e677468206f662066656c6f6e795468726573686f6c64206d69736d61746040820152610c6d60f31b606082015260800190565b60208082526019908201527f74686520636f6e747261637420616c726561647920696e697400000000000000604082015260600190565b6020808252601a908201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604082015260600190565b60208082526025908201527f746865206d697364656d65616e6f725468726573686f6c64206f7574206f662060408201526472616e676560d81b606082015260800190565b6020808252602f908201527f746865206d6573736167652073656e646572206d7573742062652063726f737360408201526e0818da185a5b8818dbdb9d1c9858dd608a1b606082015260800190565b6020808252602d908201527f746865206d6573736167652073656e646572206d75737420626520746865206260408201526c3637b1b590383937b23ab1b2b960991b606082015260800190565b6020808252600d908201526c756e6b6e6f776e20706172616d60981b604082015260600190565b6020808252601e908201527f7265636569766520756e65787065637465642073796e207061636b6167650000604082015260600190565b6020808252602b908201527f6c656e677468206f662066696e616c697479536c61736852657761726452617460408201526a0d2de40dad2e6dac2e8c6d60ab1b606082015260800190565b6020808252818101527f63616e206e6f7420736c61736820747769636520696e206f6e6520626c6f636b604082015260600190565b61ffff91909116815260200190565b90815260200190565b6000838252604060208301526132766040830184612b3a565b949350505050565b918252602082015260400190565b92835260208301919091521515604082015260600190565b63ffffffff91909116815260200190565b60ff91909116815260200190565b600060ff85168252606060208301526132df6060830185612b3a565b9050826040830152949350505050565b60405181810167ffffffffffffffff8111828210171561330e57600080fd5b604052919050565b600067ffffffffffffffff82111561332c578081fd5b5060209081020190565b600067ffffffffffffffff82111561334c578081fd5b50601f01601f191660200190565b60005b8381101561337557818101518382015260200161335d565b838111156116945750506000910152565b6001600160a01b038116811461339b57600080fd5b5056fea26469706673582212207e6be46f5e0281709e9788d33be4928c51610752d8a32e78d1c8c64bea3df55764736f6c63430006040033", + }, + { + ContractAddr: SystemRewardContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "6080604052600436106101a05760003560e01c80637942fd05116100ec578063ac4317511161008a578063f9a2bbc711610064578063f9a2bbc714610550578063fb5478b314610565578063fc3e59081461057a578063fd6a68791461058f576101e4565b8063ac43175114610457578063c81b166214610526578063dc927faf1461053b576101e4565b80639dc09262116100c65780639dc0926214610403578063a1a11bf514610418578063a78abc161461042d578063ab51bb9614610442576101e4565b80637942fd05146103a057806396713da9146103b55780639a99b4f0146103ca576101e4565b80634bf6c882116101595780636e47b482116101335780636e47b4821461034c57806370fd5bad14610361578063718a8aa81461037657806375d47a0a1461038b576101e4565b80634bf6c882146102db57806351e80672146102f05780636d70f7ae14610305576101e4565b80630bee7a67146101e95780630e2374a5146102175780633a0b0eff146102485780633dffc3871461026f57806343756e5c1461029a578063493279b1146102af576101e4565b366101e45734156101e25760408051348152905133917f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db919081900360200190a25b005b600080fd5b3480156101f557600080fd5b506101fe6105a4565b6040805163ffffffff9092168252519081900360200190f35b34801561022357600080fd5b5061022c6105a9565b604080516001600160a01b039092168252519081900360200190f35b34801561025457600080fd5b5061025d6105af565b60408051918252519081900360200190f35b34801561027b57600080fd5b506102846105b5565b6040805160ff9092168252519081900360200190f35b3480156102a657600080fd5b5061022c6105ba565b3480156102bb57600080fd5b506102c46105c0565b6040805161ffff9092168252519081900360200190f35b3480156102e757600080fd5b506102846105c5565b3480156102fc57600080fd5b5061022c6105ca565b34801561031157600080fd5b506103386004803603602081101561032857600080fd5b50356001600160a01b03166105d0565b604080519115158252519081900360200190f35b34801561035857600080fd5b5061022c6105ee565b34801561036d57600080fd5b506102846105f4565b34801561038257600080fd5b506102846105f9565b34801561039757600080fd5b5061022c6105fe565b3480156103ac57600080fd5b50610284610604565b3480156103c157600080fd5b50610284610609565b3480156103d657600080fd5b5061025d600480360360408110156103ed57600080fd5b506001600160a01b03813516906020013561060e565b34801561040f57600080fd5b5061022c6107b9565b34801561042457600080fd5b5061022c6107bf565b34801561043957600080fd5b506103386107c5565b34801561044e57600080fd5b506101fe6107ce565b34801561046357600080fd5b506101e26004803603604081101561047a57600080fd5b81019060208101813564010000000081111561049557600080fd5b8201836020820111156104a757600080fd5b803590602001918460018302840111640100000000831117156104c957600080fd5b9193909290916020810190356401000000008111156104e757600080fd5b8201836020820111156104f957600080fd5b8035906020019184600183028401116401000000008311171561051b57600080fd5b5090925090506107d3565b34801561053257600080fd5b5061022c610b56565b34801561054757600080fd5b5061022c610b5c565b34801561055c57600080fd5b5061022c610b62565b34801561057157600080fd5b5061025d610b68565b34801561058657600080fd5b50610284610b74565b34801561059b57600080fd5b5061022c610b79565b606481565b61200181565b60015481565b600181565b61100181565b603881565b600881565b61200081565b6001600160a01b031660009081526002602052604090205460ff1690565b61100581565b600281565b601081565b61100881565b600b81565b600981565b6000805460ff1661068b57600260208190527fe57bda0a954a7c7381b17b2c763e646ba2c60f67292d287ba583603e2c1c41668054600160ff19918216811790925561100560009081527fe25235fc0de9d7165652bef0846fefda506174abb9a190f03d0f7bcc6146dbce80548316841790559282558254161790555b3360009081526002602052604090205460ff166106d95760405162461bcd60e51b815260040180806020018281038252602b815260200180610c67602b913960400191505060405180910390fd5b60004783106106e857476106ea565b825b9050670de0b6b3a76400008111156107075750670de0b6b3a76400005b8015610788576040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015610743573d6000803e3d6000fd5b506040805182815290516001600160a01b038616917ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0919081900360200190a26107b2565b6040517fe589651933c2457488cc0d8e0941518abf748e799435e4e396d9c4d0b2db2d4d90600090a15b9392505050565b61100781565b61100681565b60005460ff1681565b600081565b33611007146108135760405162461bcd60e51b815260040180806020018281038252602e815260200180610cc1602e913960400191505060405180910390fd5b61087584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600b81526a30b23227b832b930ba37b960a91b60208201529150610b7f9050565b1561094d57606082828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050825192935050601490911490506108f85760405162461bcd60e51b815260040180806020018281038252602c815260200180610cef602c913960400191505060405180910390fd5b60148101516001600160a01b038116600081815260026020526040808220805460ff19166001179055517f9870d7fe5d112134c55844951dedf365363006d9c588db07c4c85af6322a06199190a25050610ac4565b6109b284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600e81526d3232b632ba32a7b832b930ba37b960911b60208201529150610b7f9050565b15610a8757606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060149091149050610a355760405162461bcd60e51b815260040180806020018281038252602f815260200180610c92602f913960400191505060405180910390fd5b60148101516001600160a01b038116600081815260026020526040808220805460ff19169055517fb40992a19dba61ea600e87fce607102bf5908dc89076217b6ca6ae195224f7029190a25050610ac4565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b61100081565b670de0b6b3a764000081565b600381565b61100481565b6000816040516020018082805190602001908083835b60208310610bb45780518252601f199092019160209182019101610b95565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310610c225780518252601f199092019160209182019101610c03565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490509291505056fe6f6e6c79206f70657261746f7220697320616c6c6f77656420746f2063616c6c20746865206d6574686f646c656e677468206f662076616c756520666f722064656c6574654f70657261746f722073686f756c64206265203230746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f72206164644f70657261746f722073686f756c64206265203230a264697066735822122078be72e2672a87e28d3e6849bea141a139b304a089fceb003c016dabd5f556fb64736f6c63430006040033", + }, + { + ContractAddr: RelayerHubContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "608060405234801561001057600080fd5b50600436106102275760003560e01c80638f83ab1311610130578063c81b1662116100b8578063f3ae24151161007c578063f3ae2415146104e8578063f9a2bbc71461050e578063fc3e590814610516578063fd30d9b81461051e578063fd6a68791461052657610227565b8063c81b1662146104c0578063dc927faf146104c8578063dd91d1c5146104d0578063e1c7392a146104d8578063e79a198f146104e057610227565b8063a1a11bf5116100ff578063a1a11bf5146103de578063a74b83ca146103e6578063a78abc16146103ee578063ab51bb96146103f6578063ac431751146103fe57610227565b80638f83ab13146103a057806395468d26146103c657806396713da9146103ce5780639dc09262146103d657610227565b8063541d5548116101b3578063718a8aa811610182578063718a8aa81461034857806375d47a0a1461035057806378beee67146103585780637942fd051461037e5780637ae230881461038657610227565b8063541d5548146102d85780636a6a419e146103125780636e47b4821461033857806370fd5bad1461034057610227565b80633dffc387116101fa5780633dffc3871461028357806343756e5c146102a1578063493279b1146102a95780634bf6c882146102c857806351e80672146102d057610227565b806303aff02b1461022c578063049a5716146102365780630bee7a671461025a5780630e2374a51461027b575b600080fd5b61023461052e565b005b61023e610539565b604080516001600160a01b039092168252519081900360200190f35b610262610551565b6040805163ffffffff9092168252519081900360200190f35b61023e610556565b61028b61055c565b6040805160ff9092168252519081900360200190f35b61023e610561565b6102b1610567565b6040805161ffff9092168252519081900360200190f35b61028b61056c565b61023e610571565b6102fe600480360360208110156102ee57600080fd5b50356001600160a01b0316610577565b604080519115158252519081900360200190f35b6102fe6004803603602081101561032857600080fd5b50356001600160a01b0316610595565b61023e6105b3565b61028b6105b9565b61028b6105be565b61023e6105c3565b6102346004803603602081101561036e57600080fd5b50356001600160a01b03166105c9565b61028b6107b1565b61038e6107b6565b60408051918252519081900360200190f35b610234600480360360208110156103b657600080fd5b50356001600160a01b03166107c3565b61038e610a02565b61028b610a0e565b61023e610a13565b61023e610a19565b61023e610a1f565b6102fe610a37565b610262610a40565b6102346004803603604081101561041457600080fd5b81019060208101813564010000000081111561042f57600080fd5b82018360208201111561044157600080fd5b8035906020019184600183028401116401000000008311171561046357600080fd5b91939092909160208101903564010000000081111561048157600080fd5b82018360208201111561049357600080fd5b803590602001918460018302840111640100000000831117156104b557600080fd5b509092509050610a45565b61023e610d96565b61023e610d9c565b610234610da2565b610234610e43565b610234610ec5565b6102fe600480360360208110156104fe57600080fd5b50356001600160a01b031661107e565b61023e61109c565b61028b6110a2565b6102fe6110a7565b61023e6110b0565b610537336110b6565b565b73b005741528b86f5952469d80a8614591e3c5b63281565b606481565b61200181565b600181565b61100181565b603881565b600881565b61200081565b6001600160a01b031660009081526007602052604090205460ff1690565b6001600160a01b031660009081526008602052604090205460ff1690565b61100581565b600281565b601081565b61100881565b3360009081526008602052604090205460ff166106175760405162461bcd60e51b81526004018080602001828103825260248152602001806115c26024913960400191505060405180910390fd5b61062033611218565b1561065c5760405162461bcd60e51b815260040180806020018281038252602181526020018061157f6021913960400191505060405180910390fd5b3233146106b0576040805162461bcd60e51b815260206004820152601e60248201527f70726f766973696f6e616c2072656c6179657220697320612070726f78790000604482015290519081900360640190fd5b6001600160a01b038181166000908152600960205260409020541633146107085760405162461bcd60e51b815260040180806020018281038252602781526020018061163b6027913960400191505060405180910390fd5b6001600160a01b03818116600081815260066020908152604080832080543380865260078086528487208054600160ff199182161790915584546001600160a01b031990811684179095556008875285882080548216905597875260098652848720805490941690935596168085529083529281902080549094169093558251828152908101939093528151909260008051602061166283398151915292908290030190a15050565b600b81565b68056bc75e2d6310000081565b3360009081526005602052604090205460ff16610820576040805162461bcd60e51b81526020600482015260166024820152751b585b9859d95c88191bd95cc81b9bdd08195e1a5cdd60521b604482015290519081900360640190fd5b61082981611218565b156108655760405162461bcd60e51b81526004018080602001828103825260278152602001806115e66027913960400191505060405180910390fd5b6001600160a01b03811615610921576001600160a01b03811660009081526007602052604090205460ff16156108db576040805162461bcd60e51b815260206004820152601660248201527572656c6179657220616c72656164792065786973747360501b604482015290519081900360640190fd5b6001600160a01b0381166000818152600860209081526040808320805460ff191660011790553383526009909152902080546001600160a01b03191690911790556109c2565b3360008181526006602090815260408083208054600980855283862080546001600160a01b03198085169095556001600160a01b0393841680895260078852868920805460ff19908116909155918516808a5260088952878a20805490931690925598909752908552805490921690915581518581529086169281019290925280516000805160206116628339815191529281900390910190a150506109ff565b604080516001600160a01b038316815290517ffba56633276570c7d3120d4535bf3bce26523da53958e40734210b9fd99b36939181900360200190a15b50565b67016345785d8a000081565b600981565b61100781565b61100681565b73446aa6e0dc65690403df3f127750da1322941f3e81565b60005460ff1681565b600081565b60005460ff16610a98576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b3361100714610ad85760405162461bcd60e51b815260040180806020018281038252602e81526020018061160d602e913960400191505060405180910390fd5b610b3984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600a81526930b23226b0b730b3b2b960b11b6020820152915061121e9050565b15610bd15760148114610b7d5760405162461bcd60e51b81526004018080602001828103825260228152602001806115a06022913960400191505060405180910390fd5b6000610bc0601484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061130592505050565b9050610bcb8161130a565b50610d04565b610c3584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c3932b6b7bb32a6b0b730b3b2b960991b6020820152915061121e9050565b15610cc75760148114610c795760405162461bcd60e51b81526004018080602001828103825260228152602001806115a06022913960400191505060405180910390fd5b6000610cbc601484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061130592505050565b9050610bcb816110b6565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b600a5460ff1615610dfa576040805162461bcd60e51b815260206004820152601e60248201527f7468652077686974656c6973747320616c726561647920757064617465640000604482015290519081900360640190fd5b610e1773b005741528b86f5952469d80a8614591e3c5b6326113cc565b610e3473446aa6e0dc65690403df3f127750da1322941f3e6113cc565b600a805460ff19166001179055565b60005460ff1615610e9b576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b68056bc75e2d63100000600190815567016345785d8a00006002556000805460ff19169091179055565b3360009081526004602052604090205460ff16610f20576040805162461bcd60e51b81526020600482015260146024820152731c995b185e595c88191bc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b60005460ff16610f73576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b610f7b611564565b5033600081815260036020908152604091829020825180840190935280548084526001909101549183018290529192916108fc91610fbf919063ffffffff61148416565b6040518115909202916000818181858888f19350505050158015610fe7573d6000803e3d6000fd5b50602081015160405161100291829181156108fc0291906000818181858888f1935050505015801561101d573d6000803e3d6000fd5b50336000818152600460209081526040808320805460ff191690556003825280832083815560010192909255815192835290517fd17202129b83db7880d6b9f25df81c58ad46f7e0e2c92236b1aa10663a4876679281900390910190a15050565b6001600160a01b031660009081526005602052604090205460ff1690565b61100081565b600381565b600a5460ff1681565b61100481565b6001600160a01b03811660009081526005602052604090205460ff1661111b576040805162461bcd60e51b81526020600482015260156024820152741b585b9859d95c88191bd95cdb89dd08195e1a5cdd605a1b604482015290519081900360640190fd5b6001600160a01b038082166000818152600660209081526040808320805460058452828520805460ff1990811690915582546001600160a01b0319908116909355600980865284872080548a16885260088752858820805490931690925595879052948452845490911690935580519384525191909316927f2002866d443ac6c241fecaaa2af4895828c7de2cc423b9d01f7969650f557c76928290030190a16001600160a01b03811615611214576001600160a01b0381166000818152600760209081526040808320805460ff1916905580519384529083019190915280516000805160206116628339815191529281900390910190a15b5050565b3b151590565b6000816040516020018082805190602001908083835b602083106112535780518252601f199092019160209182019101611234565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106112c15780518252601f1990920191602091820191016112a2565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b6001600160a01b03811660009081526005602052604090205460ff1615611371576040805162461bcd60e51b81526020600482015260166024820152756d616e6167657220616c72656164792065786973747360501b604482015290519081900360640190fd5b6001600160a01b038116600081815260056020908152604091829020805460ff19166001179055815192835290517fe0de8e71a22c046647f4ef744348fa126ad6d052d4ce070999481f69d45575179281900390910190a150565b6001600160a01b03811660008181526005602090815260408083208054600160ff1991821681179092556006845282852080546001600160a01b031916871790556007845293829020805490941617909255815192835290517fe0de8e71a22c046647f4ef744348fa126ad6d052d4ce070999481f69d45575179281900390910190a160408051600081526001600160a01b03831660208201528151600080516020611662833981519152929181900390910190a150565b60006114c683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506114cd565b9392505050565b6000818484111561155c5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611521578181015183820152602001611509565b50505050905090810190601f16801561154e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60405180604001604052806000815260200160008152509056fe70726f766973696f6e616c2072656c61796572206973206120636f6e74726163746c656e677468206f66206d616e616765722061646472657373206d69736d6174636872656c61796572206973206e6f7420612070726f766973696f6e616c2072656c61796572636f6e7472616374206973206e6f7420616c6c6f77656420746f20626520612072656c61796572746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e747261637470726f766973696f6e616c206973206e6f742073657420666f722074686973206d616e61676572a5a19d7e9dab30a215022382d7abe782b579986fcbedec9942ecd0db9510a148a2646970667358221220ca640b19c40787a49d8b8b52c563d76e0125386bfdf94825087004f989e9989d64736f6c63430006040033", + }, + { + ContractAddr: CrossChainContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "608060405234801561001057600080fd5b50600436106103995760003560e01c8063718a8aa8116101e9578063c27cdcfb1161010f578063dc927faf116100ad578063f7a251d71161007c578063f7a251d714610b2f578063f9a2bbc714610ba7578063fc3e590814610baf578063fd6a687914610bb757610399565b8063dc927faf14610af7578063e1c7392a14610aff578063e3b0480514610b07578063e6400bbe14610b2757610399565b8063ccc108d7116100e9578063ccc108d714610ab0578063d31f968d14610ab8578063d76a867514610ae7578063dc40433114610aef57610399565b8063c27cdcfb14610a80578063c780e9de14610aa0578063c81b166214610aa857610399565b80638cc8f56111610187578063a78abc1611610156578063a78abc16146109b2578063ab51bb96146109ba578063ac431751146109c2578063b0355f5b1461078157610399565b80638cc8f5611461088757806396713da91461099a5780639dc09262146109a2578063a1a11bf5146109aa57610399565b806375d47a0a116101c357806375d47a0a146108a75780637942fd05146108af57806384013b6a146108b7578063863fe4ab1461099257610399565b8063718a8aa81461088f578063719482d51461089757806374f079b81461089f57610399565b8063422f9050116102ce57806363e1394e1161026c5780636de380bd1161023b5780636de380bd146108575780636e47a51a1461085f5780636e47b4821461087f57806370fd5bad1461088757610399565b806363e1394e146107ff5780636a3cb34d146108075780636bacff2c1461080f5780636c46aa681461080757610399565b80634bf6c882116102a85780634bf6c882146107b957806351e80672146107c15780635692ddd3146107c95780635f832177146107d157610399565b8063422f90501461078957806343756e5c146107a9578063493279b1146107b157610399565b8063299b533d1161033b578063308325f411610315578063308325f4146106155780633a648b151461061d5780633bdc47a6146106595780633dffc3871461078157610399565b8063299b533d146105a35780632af6f399146105d75780632ff32aea146105f457610399565b806314b3023b1161037757806314b3023b146104015780631d1309351461041b5780631e275ae11461043757806322556cdc1461059b57610399565b806305e682581461039e5780630bee7a67146103bc5780630e2374a5146103dd575b600080fd5b6103a6610bbf565b6040805160ff9092168252519081900360200190f35b6103c4610bc4565b6040805163ffffffff9092168252519081900360200190f35b6103e5610bc9565b604080516001600160a01b039092168252519081900360200190f35b610409610bcf565b60408051918252519081900360200190f35b610423610bd5565b604080519115158252519081900360200190f35b610599600480360361010081101561044e57600080fd5b81018160a081016080820135600160201b81111561046b57600080fd5b82018360208201111561047d57600080fd5b803590602001918460018302840111600160201b8311171561049e57600080fd5b919390929091602081019035600160201b8111156104bb57600080fd5b8201836020820111156104cd57600080fd5b803590602001918460018302840111600160201b831117156104ee57600080fd5b919390929091602081019035600160201b81111561050b57600080fd5b82018360208201111561051d57600080fd5b803590602001918460018302840111600160201b8311171561053e57600080fd5b919390929091602081019035600160201b81111561055b57600080fd5b82018360208201111561056d57600080fd5b803590602001918460018302840111600160201b8311171561058e57600080fd5b509092509050610bde565b005b6104096112c2565b6105c0600480360360208110156105b957600080fd5b50356112c7565b6040805161ffff9092168252519081900360200190f35b610423600480360360208110156105ed57600080fd5b50356112dd565b6105fc6112f2565b60408051600792830b90920b8252519081900360200190f35b6104096112fb565b61063d6004803603602081101561063357600080fd5b503560ff16611301565b604080516001600160401b039092168252519081900360200190f35b61070c6004803603606081101561066f57600080fd5b60ff82351691602081013591810190606081016040820135600160201b81111561069857600080fd5b8201836020820111156106aa57600080fd5b803590602001918460018302840111600160201b831117156106cb57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061131c945050505050565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561074657818101518382015260200161072e565b50505050905090810190601f1680156107735780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103a6611392565b6104236004803603602081101561079f57600080fd5b503560ff16611397565b6103e56113ac565b6105c06113b2565b6103a66113b7565b6103e56113bc565b6104096113c2565b610599600480360360408110156107e757600080fd5b506001600160a01b03813581169160200135166113f2565b610409611652565b6105c061167a565b61082c6004803603602081101561082557600080fd5b503561167f565b6040805161ffff90941684526001600160801b03909216602084015282820152519081900360600190f35b6104096116ae565b6103e56004803603602081101561087557600080fd5b503560ff166116d5565b6103e56116f0565b6103a661167a565b6103a66116f6565b6105c0611392565b6104096116fb565b6103e5611701565b6103a6611707565b610599600480360360a08110156108cd57600080fd5b810190602081018135600160201b8111156108e757600080fd5b8201836020820111156108f957600080fd5b803590602001918460018302840111600160201b8311171561091a57600080fd5b919390929091602081019035600160201b81111561093757600080fd5b82018360208201111561094957600080fd5b803590602001918460018302840111600160201b8311171561096a57600080fd5b919350915080356001600160401b03908116916020810135909116906040013560ff1661170c565b6104096129c6565b6103a66129ce565b6103e56129d3565b6103e56129d9565b6104236129df565b6103c4610bbf565b610599600480360360408110156109d857600080fd5b810190602081018135600160201b8111156109f257600080fd5b820183602082011115610a0457600080fd5b803590602001918460018302840111600160201b83111715610a2557600080fd5b919390929091602081019035600160201b811115610a4257600080fd5b820183602082011115610a5457600080fd5b803590602001918460018302840111600160201b83111715610a7557600080fd5b5090925090506129e8565b61063d60048036036020811015610a9657600080fd5b503560ff166134ac565b6104096134c7565b6103e56134eb565b6105996134f1565b61042360048036036040811015610ace57600080fd5b5080356001600160a01b0316906020013560ff16613745565b61070c613765565b610409613784565b6103e561378a565b610599613790565b61063d60048036036020811015610b1d57600080fd5b503560ff16613b47565b610599613b62565b61059960048036036060811015610b4557600080fd5b60ff8235169190810190604081016020820135600160201b811115610b6957600080fd5b820183602082011115610b7b57600080fd5b803590602001918460018302840111600160201b83111715610b9c57600080fd5b919350915035613d81565b6103e5613ec4565b6103a6613eca565b6103e5613ecf565b600081565b606481565b61200181565b60015481565b600b5460ff1681565b60005460ff16610c23576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b604080516337d7f9c160e21b81526001600160401b038b35166004820181905291516110039163df5fe704916024808301926020929190829003018186803b158015610c6e57600080fd5b505afa158015610c82573d6000803e3d6000fd5b505050506040513d6020811015610c9857600080fd5b5051610cd55760405162461bcd60e51b81526004018080602001828103825260238152602001806149d26023913960400191505060405180910390fd5b604080516337d7f9c160e21b815260208c8101356001600160401b03166004830181905292516110039263df5fe704926024808301939192829003018186803b158015610d2157600080fd5b505afa158015610d35573d6000803e3d6000fd5b505050506040513d6020811015610d4b57600080fd5b5051610d885760405162461bcd60e51b81526004018080602001828103825260238152602001806149d26023913960400191505060405180910390fd5b60608b013560ff81166000908152600560205260409020546001600160401b03909116906001600160a01b0316610e01576040805162461bcd60e51b815260206004820152601860248201527718da185b9b995b081a5cc81b9bdd081cdd5c1c1bdc9d195960421b604482015290519081900360640190fd5b600b5460ff1615610e45576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b8888604051808383808284376040519201829003822094508f93508e9250819050838380828437808301925050509250505060405180910390201415610ec1576040805162461bcd60e51b815260206004820152600c60248201526b1cd85b59481c185e5b1bd85960a21b604482015290519081900360640190fd5b60606001600160401b0360408e01358116908e83013516610ee28282613ed5565b80516020808301919091206000818152600e9092526040909120549194509060ff1615610f4b576040805162461bcd60e51b8152602060048201526012602482015271185b1c9958591e4818da185b1b195b99d95960721b604482015290519081900360640190fd5b6000908152600e60205260408120805460ff191660011790558f8160200201356001600160401b0316905060608f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040805163cba510a960e01b81526001600160401b038a16600482015290519596509094611003945063cba510a9935060248083019350602092829003018186803b15801561104157600080fd5b505afa158015611055573d6000803e3d6000fd5b505050506040513d602081101561106b57600080fd5b505160408051808201909152600381526269626360e81b6020820152909150611098908290898686613f1d565b6110e1576040805162461bcd60e51b81526020600482015260156024820152740696e76616c6964206d65726b6c652070726f6f663605c1b604482015290519081900360640190fd5b5050505060008f6001600481106110f457fe5b60200201356001600160401b0316905060608d8d8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8f018190048102820181019092528d815293945060609392508d91508c908190840183828082843760009201829052506040805163cba510a960e01b81526001600160401b038a16600482015290519596509094611003945063cba510a9935060248083019350602092829003018186803b1580156111c057600080fd5b505afa1580156111d4573d6000803e3d6000fd5b505050506040513d60208110156111ea57600080fd5b505160408051808201909152600381526269626360e81b6020820152909150611217908290898686613f1d565b611260576040805162461bcd60e51b8152602060048201526015602482015274696e76616c6964206d65726b6c652070726f6f663160581b604482015290519081900360640190fd5b5050505061126c61401a565b604080516001600160401b038416815260ff83166020820152815133927f039eb91179ffd7d3b6e97f8ea106e748e827f910b872375dbc9c14a362319c3c928290030190a2505050505050505050505050505050565b603281565b600d6020526000908152604090205461ffff1681565b600e6020526000908152604090205460ff1681565b60045460070b81565b60025481565b600a602052600090815260409020546001600160401b031681565b60606000825160210190506060816040519080825280601f01601f191660200182016040528015611354576020820181803683370190505b506021810186905260018101879052828152905060418101600061137786614098565b509050611386818388516140a2565b50909695505050505050565b600181565b60096020526000908152604090205460ff1681565b61100181565b603881565b600881565b61200081565b604080517710d05390d15317d514905394d1915497d41493d413d4d05360421b8152905190819003601801902081565b60005460ff16611437576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b15801561147a57600080fd5b505afa15801561148e573d6000803e3d6000fd5b505050506040513d60208110156114a457600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b1580156114e557600080fd5b505afa1580156114f9573d6000803e3d6000fd5b505050506040513d602081101561150f57600080fd5b505190508061151c575060155b60008211801561152c5750808211155b61156b576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b604080516001600160a01b038087166020808401919091529086168284015282518083038401815260608301808552815191909201207710d05390d15317d514905394d1915497d41493d413d4d05360421b90915291519081900360780190206000906115d890836140e3565b9050801561164a5760408051630911a2c160e11b81526001600160a01b03888116600483015287166024820152905161100491631223458291604480830192600092919082900301818387803b15801561163157600080fd5b505af1158015611645573d6000803e3d6000fd5b505050505b505050505050565b604080516f14d554d411539117d41493d413d4d05360821b8152905190819003601001902081565b600281565b600c602052600090815260409020805460019091015461ffff8216916201000090046001600160801b03169083565b604080516e149153d4115397d41493d413d4d053608a1b8152905190819003600f01902081565b6005602052600090815260409020546001600160a01b031681565b61100581565b601081565b60035481565b61100881565b600b81565b60005460ff16611751576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b60408051630a83aaa960e31b815233600482015290516110069163541d5548916024808301926020929190829003018186803b15801561179057600080fd5b505afa1580156117a4573d6000803e3d6000fd5b505050506040513d60208110156117ba57600080fd5b505161180d576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b60ff8116600090815260086020526040902054829082906001600160401b03908116908316811461187d576040805162461bcd60e51b815260206004820152601560248201527439b2b8bab2b731b2903737ba1034b71037b93232b960591b604482015290519081900360640190fd5b60ff8216600090815260086020908152604091829020805467ffffffffffffffff1916600185016001600160401b039081169190911790915582516337d7f9c160e21b81529089166004820152915188926110039263df5fe70492602480840193829003018186803b1580156118f257600080fd5b505afa158015611906573d6000803e3d6000fd5b505050506040513d602081101561191c57600080fd5b50516119595760405162461bcd60e51b81526004018080602001828103825260238152602001806149d26023913960400191505060405180910390fd5b60ff851660009081526005602052604090205485906001600160a01b03166119c3576040805162461bcd60e51b815260206004820152601860248201527718da185b9b995b081a5cc81b9bdd081cdd5c1c1bdc9d195960421b604482015290519081900360640190fd5b60ff86166000908152600a6020526040902054889087906001600160401b039081169083161015611a2c576040805162461bcd60e51b815260206004820152600e60248201526d3a37b79037b632103432b0b232b960911b604482015290519081900360640190fd5b60ff81166000908152600a60205260409020546001600160401b03838116911614611a7e5760ff81166000908152600a60205260409020805467ffffffffffffffff19166001600160401b0384161790555b600b5460ff1615611ac2576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b60608e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509050611c066110036001600160a01b031663cba510a98e6040518263ffffffff1660e01b815260040180826001600160401b03166001600160401b0316815260200191505060206040518083038186803b158015611baf57600080fd5b505afa158015611bc3573d6000803e3d6000fd5b505050506040513d6020811015611bd957600080fd5b505160408051808201909152600381526269626360e81b6020820152611bff8e8e613ed5565b8585613f1d565b611c4e576040805162461bcd60e51b815260206004820152601460248201527334b73b30b634b21036b2b935b63290383937b7b360611b604482015290519081900360640190fd5b60408051631bb5062960e31b81526001600160401b038e16600482015290516000916110039163dda8314891602480820192602092909190829003018186803b158015611c9a57600080fd5b505afa158015611cae573d6000803e3d6000fd5b505050506040513d6020811015611cc457600080fd5b505190508b8b600080806060611cd9896143c8565b935093509350935083611d9b578460ff16866001600160401b03167ff7b2e42d694eb1100184aae86d4245d9e46966100b1dc7e723275b98326854ac8b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611d53578181015183820152602001611d3b565b50505050905090810190601f168015611d805780820380516001836020036101000a031916815260200191505b509250505060405180910390a35050505050505050506129b6565b6040805160ff85811682529151918716916001600160401b038916917f36afdaf439a8f43fe72135135d804ae620b37a474f0943b5b85f6788312cad40919081900360200190a360ff83166123205760ff85166000818152600560209081526040808320548151631182b87560e01b815260048101958652602481019283528651604482015286516001600160a01b03909216958695631182b875958d958a9593949093606490910192918601918190849084905b83811015611e68578181015183820152602001611e50565b50505050905090810190601f168015611e955780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015611eb557600080fd5b505af1925050508015611f9957506040513d6000823e601f3d908101601f191682016040526020811015611ee857600080fd5b8101908080516040519392919084600160201b821115611f0757600080fd5b908301906020820185811115611f1c57600080fd5b8251600160201b811182820188101715611f3557600080fd5b82525081516020918201929091019080838360005b83811015611f62578181015183820152602001611f4a565b50505050905090810190601f168015611f8f5780820380516001836020036101000a031916815260200191505b5060405250505060015b6122ab576040516000815260443d1015611fb557506000612050565b60046000803e60005160e01c6308c379a08114611fd6576000915050612050565b60043d036004833e81513d60248201116001600160401b038211171561200157600092505050612050565b80830180516001600160401b03811115612022576000945050505050612050565b8060208301013d860181111561204057600095505050505050612050565b601f01601f191660405250925050505b8061205b575061216d565b60ff8716600090815260076020526040812054612092916001600160401b0390911690899061208d906002908861131c565b614478565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf948794849390840192918601918190849084905b8381101561212d578181015183820152602001612115565b50505050905090810190601f16801561215a5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2506122a6565b3d808015612197576040519150601f19603f3d011682016040523d82523d6000602084013e61219c565b606091505b5060ff87166000908152600760205260408120546121cf916001600160401b0390911690899061208d906002908861131c565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351948794849390840192918601918190849084905b8381101561226a578181015183820152602001612252565b50505050905090810190601f1680156122975780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b61231a565b8051156123185760ff87166000908152600760205260408120546122e4916001600160401b0390911690899061208d906001908661131c565b60ff8716600090815260076020526040902080546001600160401b038082166001011667ffffffffffffffff199091161790555b505b506128ee565b60ff8316600114156125c45760ff8516600081815260056020908152604080832054815163831d65d160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563831d65d1958d958a9593949093606490910192918601918190849084905b838110156123aa578181015183820152602001612392565b50505050905090810190601f1680156123d75780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156123f757600080fd5b505af1925050508015612408575060015b61231a576040516000815260443d1015612424575060006124bf565b60046000803e60005160e01c6308c379a081146124455760009150506124bf565b60043d036004833e81513d60248201116001600160401b0382111715612470576000925050506124bf565b80830180516001600160401b038111156124915760009450505050506124bf565b8060208301013d86018111156124af576000955050505050506124bf565b601f01601f191660405250925050505b806124ca575061252f565b60408051602080825283518183015283516001600160a01b038616937ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf938693909283928301918501908083836000831561212d578181015183820152602001612115565b3d808015612559576040519150601f19603f3d011682016040523d82523d6000602084013e61255e565b606091505b5060408051602080825283518183015283516001600160a01b038616937f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351938693909283928301918501908083836000831561226a578181015183820152602001612252565b60ff8316600214156128ee5760ff8516600081815260056020908152604080832054815163c8509d8160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563c8509d81958d958a9593949093606490910192918601918190849084905b8381101561264e578181015183820152602001612636565b50505050905090810190601f16801561267b5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561269b57600080fd5b505af19250505080156126ac575060015b6128ec576040516000815260443d10156126c857506000612763565b60046000803e60005160e01c6308c379a081146126e9576000915050612763565b60043d036004833e81513d60248201116001600160401b038211171561271457600092505050612763565b80830180516001600160401b03811115612735576000945050505050612763565b8060208301013d860181111561275357600095505050505050612763565b601f01601f191660405250925050505b8061276e5750612817565b816001600160a01b03167ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf826040518080602001828103825283818151815260200191508051906020019080838360005b838110156127d75781810151838201526020016127bf565b50505050905090810190601f1680156128045780820380516001836020036101000a031916815260200191505b509250505060405180910390a2506128ec565b3d808015612841576040519150601f19603f3d011682016040523d82523d6000602084013e612846565b606091505b50816001600160a01b03167f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351826040518080602001828103825283818151815260200191508051906020019080838360005b838110156128b0578181015183820152602001612898565b50505050905090810190601f1680156128dd5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b505b60ff80861660009081526009602052604090205461100591636f93d2e6918a91339187911680612920575060ff881615155b604080516001600160e01b031960e088901b1681526001600160a01b039586166004820152939094166024840152604483019190915215156064820152905160848083019260209291908290030181600087803b15801561298057600080fd5b505af1158015612994573d6000803e3d6000fd5b505050506040513d60208110156129aa57600080fd5b50505050505050505050505b5050505050505050505050505050565b630100380081565b600981565b61100781565b61100681565b60005460ff1681565b3361100714612a285760405162461bcd60e51b815260040180806020018281038252602e815260200180614908602e913960400191505060405180910390fd5b600b5460ff1615612a6c576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b612ad584848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526012815271626174636853697a65466f724f7261636c6560701b602082015291506146129050565b15612b7057604080516020601f8401819004810282018101909252828152600091612b18918585808385018382808284376000920191909152506146f992505050565b90506127108111158015612b2d5750600a8110155b612b685760405162461bcd60e51b81526004018080602001828103825260328152602001806149806032913960400191505060405180910390fd5b60015561341a565b612bd984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601281527118591913dc955c19185d1950da185b9b995b60721b602082015291506146129050565b15612d6157606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060169091149050612c5c5760405162461bcd60e51b815260040180806020018281038252605a815260200180614821605a913960600191505060405180910390fd5b60018101516002820151601683015160ff82161590612c7a816146fe565b612ccb576040805162461bcd60e51b815260206004820152601960248201527f61646472657373206973206e6f74206120636f6e747261637400000000000000604482015290519081900360640190fd5b60ff8416600081815260056020908152604080832080546001600160a01b0319166001600160a01b038716908117909155808452600683528184208585528352818420805460ff199081166001179091556009909352818420805490931687151517909255519092917f7e3b6af43092577ee20e60eaa1d9b114a7031305c895ee7dd3ffe17196d2e1e091a3505050505061341a565b612dce84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526016815275195b98589b1953dc911a5cd8589b1950da185b9b995b60521b602082015291506146129050565b15612eff57606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060029091149050612e515760405162461bcd60e51b815260040180806020018281038252604a815260200180614936604a913960600191505060405180910390fd5b600181810151600283015160ff80831660009081526005602052604090205492939192908316909114906001600160a01b03168015612ef5576001600160a01b038116600090815260066020908152604080832060ff881680855290835292819020805460ff1916861515908117909155815190815290517fa3132e3f9819fbddc7f0ed6d38d7feef59aa95112090b7c592f5cb5bc4aa4adc929181900390910190a25b505050505061341a565b612f6384848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c73757370656e6451756f72756d60981b602082015291506146129050565b156130985760028114612fa75760405162461bcd60e51b815260040180806020018281038252602d8152602001806148af602d913960400191505060405180910390fd5b6000612fea600284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506146f992505050565b905060008161ffff16118015613004575060648161ffff16105b61304e576040805162461bcd60e51b8152602060048201526016602482015275696e76616c69642073757370656e642071756f72756d60501b604482015290519081900360640190fd5b604080516f14d554d411539117d41493d413d4d05360821b815281519081900360100190206000908152600d60205220805461ffff90921661ffff1990921691909117905561341a565b6130fb84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600c81526b72656f70656e51756f72756d60a01b602082015291506146129050565b1561322e576002811461313f5760405162461bcd60e51b815260040180806020018281038252602c8152602001806148dc602c913960400191505060405180910390fd5b6000613182600284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506146f992505050565b905060008161ffff1611801561319c575060648161ffff16105b6131e5576040805162461bcd60e51b8152602060048201526015602482015274696e76616c69642072656f70656e2071756f72756d60581b604482015290519081900360640190fd5b604080516e149153d4115397d41493d413d4d053608a1b8152815190819003600f0190206000908152600d60205220805461ffff90921661ffff1990921691909117905561341a565b61329984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601481527363616e63656c5472616e7366657251756f72756d60601b602082015291506146129050565b156133dd57600281146132dd5760405162461bcd60e51b815260040180806020018281038252603481526020018061487b6034913960400191505060405180910390fd5b6000613320600284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506146f992505050565b905060008161ffff1611801561333a575060648161ffff16105b61338b576040805162461bcd60e51b815260206004820152601e60248201527f696e76616c69642063616e63656c207472616e736665722071756f72756d0000604482015290519081900360640190fd5b604080517710d05390d15317d514905394d1915497d41493d413d4d05360421b815281519081900360180190206000908152600d60205220805461ffff90921661ffff1990921691909117905561341a565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b6008602052600090815260409020546001600160401b031681565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081565b61100281565b60005460ff16613536576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b15801561357957600080fd5b505afa15801561358d573d6000803e3d6000fd5b505050506040513d60208110156135a357600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b1580156135e457600080fd5b505afa1580156135f8573d6000803e3d6000fd5b505050506040513d602081101561360e57600080fd5b505190508061361b575060155b60008211801561362b5750808211155b61366a576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b600b5460ff166136b1576040805162461bcd60e51b815260206004820152600d60248201526c1b9bdd081cdd5cdc195b991959609a1b604482015290519081900360640190fd5b604080516e149153d4115397d41493d413d4d053608a1b8152905190819003600f019020600090613702907fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4706140e3565b9050801561374057600b805460ff1916905560405133907f899fe8c37dc61708a3aaa99c4bf143346c1d1da69af79be9e8920c0a6785b75290600090a25b505050565b600660209081526000928352604080842090915290825290205460ff1681565b6040518060400160405280600381526020016269626360e81b81525081565b610e1081565b61100381565b60005460ff16156137e8576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b7f1471eb6eb2c5e789fc3de43f8ce62938c7d1836ec861730447e2ada8fd81017b80546001600160a01b0319908116611008179091557f92e85d02570a8092d09a6e3a57665bc3815a2699a4074001bf1ccabf660f5a36805460ff199081169091557fd8af288fc1c8680b4f4706064cf021e264efb6828fcaf7eb5ca36818eb365bcc8054821660019081179091557f89832631fb3c3307a103ba2c84ab569c64d6182a18893dcd163f0f1c2090733a805484166110049081179091557f6cde3cea4b3a3fb2488b2808bae7556f4a405e50f65e1794383bc026131b13c38054841690557f72e4efa1513b071517c6c74dba31b5934a81aa83cddd400e7081df5529c9943680548416831790557fa9bc9a3a348c357ba16b37005d7e6b3236198c0e939f4af8c5f19b8deeb8ebc08054851690911790557fc575c31fea594a6eb97c8e9d3f9caee4c16218c6ef37e923234c0fe9014a61e78054831690557f4e523af77f034e9810f1c94057f5e931fb3d16a51511a4c3add793617d18610580548316821790557ffb33122aa9f93cc639ebe80a7bc4784c11e6053dde89c6f4f7e268c6a623da1e805484166110001790557fc7694af312c4f286114180fd0ba6a52461fcee8a381636770b19a343af92538a80548316821790557f01112dd68e482ba8d68a7e828cff8b3abcea08eab88941953c180a7e650e9cd480548316821790557fc0a4a8be475dfebc377ebef2d7c4ff47656f572a08dd92b81017efcdba0febe1805484166110071790557f87e8a52529e8ece4ef759037313542a6429ff494a9fab9027fb79db90124eba680548316821790557f4c7666bbcb22d46469f7cc282f70764a7012dca2cce630ff8d83db9a9cdd48f080548316821790557f40f28f99a40bc9f6beea1013afdbc3cdcc689eb76b82c4de06c0acf1e1932ed58054909316611001179092557f0d9cf2cd531699eed8dd34e40ff2884a14a698c4898184fba85194e6f6772d248054821683179055600b60009081527f23f68c9bd22b8a93d06adabe17481c87c016bcbd20adc8bfd707a4d813a572176020527fdf0d5d05428057f5455c2dc8e810dd86d1e9350faa72f16bda8a45443c5b39328054831684179055603283556004805467ffffffffffffffff19166001600160401b031790556002819055600381905580549091169091179055565b6007602052600090815260409020546001600160401b031681565b60005460ff16613ba7576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b158015613bea57600080fd5b505afa158015613bfe573d6000803e3d6000fd5b505050506040513d6020811015613c1457600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b158015613c5557600080fd5b505afa158015613c69573d6000803e3d6000fd5b505050506040513d6020811015613c7f57600080fd5b5051905080613c8c575060155b600082118015613c9c5750808211155b613cdb576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b600b5460ff1615613d1f576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b604080516f14d554d411539117d41493d413d4d05360821b81529051908190036010019020600090613d71907fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4706140e3565b905080156137405761374061401a565b60005460ff16613dc6576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b33600090815260066020908152604080832060ff8089168552925290912054859116613e235760405162461bcd60e51b81526004018080602001828103825260318152602001806147f06031913960400191505060405180910390fd5b60ff85166000908152600760209081526040808320548151601f88018490048402810184019092528682526001600160401b031692613e889284928a9261208d92909189918c908c908190840183828082843760009201919091525061131c92505050565b60ff959095166000908152600760205260409020805467ffffffffffffffff191660019096016001600160401b03169590951790945550505050565b61100081565b600381565b61100481565b60408051600e808252818301909252606091630100380060ff851617918391602082018180368337505050600e81810187905260068201939093529182525090505b92915050565b600085613f2c57506000614011565b606082518451865160800101016040519080825280601f01601f191660200182016040528015613f63576020820181803683370190505b5090506000613f7182614704565b602080890151825201905086600080613f8989614098565b8086526020909501949092509050613fa28285836140a2565b92830192613faf88614098565b8086526020909501949092509050613fc88285836140a2565b9283018a815260200192613fdb87614098565b9092509050613feb8285836140a2565b508351602001613ff961470a565b60208183886065600019fa5051600114955050505050505b95945050505050565b600b5460ff161561405e576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b600b805460ff1916600117905560405133907f6f123d3d54c84a7960a573b31c221dcd86e13fd849c5adb0c6ca851468cc1ae490600090a2565b8051602090910191565b5b602081106140c2578251825260209283019290910190601f19016140a3565b915181516020939093036101000a6000190180199091169216919091179052565b6000828152600d602052604081205461ffff166141ac57604080516f14d554d411539117d41493d413d4d05360821b815281519081900360100181206000908152600d6020818152848320805461ffff199081166001179091556e149153d4115397d41493d413d4d053608a1b8552855194859003600f01852084528282528584208054821660029081179091557710d05390d15317d514905394d1915497d41493d413d4d05360421b8652865195869003601801909520845291905292902080549092161790555b6000838152600c6020526040902080546201000090046001600160801b0316421015806141dd575082816001015414155b156142b0576000848152600d602090815260409182902054835461ffff90911661ffff199091161771ffffffffffffffffffffffffffffffff0000191662010000610e1042016001600160801b0316021783556001808401869055825191820190925233815261425291600284019190614728565b5080546040805161ffff83168152620100009092046001600160801b0316602083015281810185905251339186917f9e109f0e55ef32e99e4880be2ec357f1ddb3469c79d0747ef4762da6e89fabe5916060908290030190a3614364565b60005b600282015481101561433b57336001600160a01b03168260020182815481106142d857fe5b6000918252602090912001546001600160a01b03161415614333576040805162461bcd60e51b815260206004820152601060248201526f185b1c9958591e48185c1c1c9bdd995960821b604482015290519081900360640190fd5b6001016142b3565b50600281018054600181018255600091825260209091200180546001600160a01b031916331790555b8054600282015461ffff909116116143be576000848152600c60205260408120805471ffffffffffffffffffffffffffffffffffff1916815560018101829055906143b2600283018261478d565b50506001915050613f17565b5060009392505050565b600080600060606021855110156143f8575050604080516000808252602082019092529092508291508190614471565b600185015160218601518651604080516020198301808252601f1960011990940193909316810160200190915260418901939291606091908015614443576020820181803683370190505b509050600061445182614098565b509050614463858260218d51036140a2565b506001975091955093509150505b9193509193565b600b5460ff16156144bc576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b6002544311156144fb576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003554360025561453c565b6003805460019081019182905554101561453c576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003555b8160ff16836001600160401b0316600460009054906101000a900460070b6001600160401b03167f3a6e0fc61675aa2a100bcba0568368bb92bcec91c97673391074f11138f0cffe603885604051808361ffff1661ffff16815260200180602001828103825283818151815260200191508051906020019080838360005b838110156145d25781810151838201526020016145ba565b50505050905090810190601f1680156145ff5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a4505050565b6000816040516020018082805190602001908083835b602083106146475780518252601f199092019160209182019101614628565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106146b55780518252601f199092019160209182019101614696565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b3b151590565b60200190565b60405180602001604052806001906020820280368337509192915050565b82805482825590600052602060002090810192821561477d579160200282015b8281111561477d57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614748565b506147899291506147ae565b5090565b50805460008255906000526020600020908101906147ab91906147d5565b50565b6147d291905b808211156147895780546001600160a01b03191681556001016147b4565b90565b6147d291905b8082111561478957600081556001016147db56fe74686520636f6e747261637420616e64206368616e6e656c2068617665206e6f74206265656e20726567697374657265646c656e677468206f662076616c756520666f72206164644f725570646174654368616e6e656c2073686f756c642062652032322c206368616e6e656c49643a697346726f6d53797374656d3a68616e646c6572416464726573736c656e677468206f662076616c756520666f722063616e63656c5472616e7366657251756f72756d2073686f756c6420626520326c656e677468206f662076616c756520666f722073757370656e6451756f72756d2073686f756c6420626520326c656e677468206f662076616c756520666f722072656f70656e51756f72756d2073686f756c642062652032746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f7220656e61626c654f7244697361626c654368616e6e656c2073686f756c6420626520322c206368616e6e656c49643a6973456e61626c65746865206e6577426174636853697a65466f724f7261636c652073686f756c6420626520696e205b31302c2031303030305d74686520636f6e7472616374206e6f7420696e697420796574000000000000006c6967687420636c69656e74206e6f742073796e632074686520626c6f636b20796574a2646970667358221220622dd2ff8c5505e7bf8251c7cfe63da6bfa7891c3682ca46b6d6bf796895609f64736f6c63430006040033", + }, + }, + } + + LubanUpgrade[networkname.ChapelChainName] = &Upgrade{ + UpgradeName: "luban", + Configs: []*UpgradeConfig{ + { + ContractAddr: ValidatorContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "60806040526004361061046c5760003560e01c8063862498821161024a578063c6d3394511610139578063e40716a1116100b6578063f9a2bbc71161007a578063f9a2bbc714610b6b578063fc3e590814610b80578063fccc281314610b95578063fd4ad81f14610baa578063fd6a687914610bd957610473565b8063e40716a114610af9578063eb57e20214610b0e578063eda5868c14610b2e578063f340fa0114610b43578063f92eb86b14610b5657610473565b8063d86222d5116100fd578063d86222d514610a90578063daacdb6614610aa5578063dc927faf14610aba578063e086c7b114610acf578063e1c7392a14610ae457610473565b8063c6d3394514610a3c578063c81b166214610a51578063c8509d811461085f578063d04aa99614610a66578063d68fb56a14610a7b57610473565b8063a5422d5c116101c7578063ad3c9da61161018b578063ad3c9da6146109d0578063aef198a9146109f0578063b7ab4db514610a05578063b8cf4ef114610a27578063bf9f49951461062f57610473565b8063a5422d5c1461095c578063a78abc1614610971578063aaf5eb6814610986578063ab51bb961461099b578063ac431751146109b057610473565b806396713da91161020e57806396713da9146108f35780639dc09262146109085780639fe0f8161461091d578063a0dc275814610932578063a1a11bf51461094757610473565b8063862498821461087f57806388b32f11146108945780638b5ad0c9146108a95780638d19a410146108be5780639369d7de146108de57610473565b80634df6e0c3116103665780636e47b482116102e35780637942fd05116102a75780637942fd05146108205780637a84ca2a1461083557806381650b621461084a578063831d65d11461085f578063853230aa1461080b57610473565b80636e47b482146107b757806370fd5bad146107cc578063718a8aa8146107e157806375d47a0a146107f657806378dfed4a1461080b57610473565b8063565c56b31161032a578063565c56b3146107265780635667515a146107465780635d77156c1461075b57806362b72cf5146107705780636969a25c1461078557610473565b80634df6e0c3146106b25780635192c82c146106c757806351e80672146106dc578063549b03f2146106f157806355614fcc1461070657610473565b8063321d398a116103f45780633dffc387116103b85780633dffc3871461062f57806343756e5c1461065157806345cf9daf14610666578063493279b11461067b5780634bf6c8821461069d57610473565b8063321d398a146105975780633365af3a146105b757806335409f7f146105d75780633b071dcc146105f75780633de0f0d81461061a57610473565b80631182b8751161043b5780631182b875146104fe578063152ad3b81461052b5780631ff180691461054d578063219f22d514610562578063300c35671461057757610473565b806304c4fec61461047857806307a568471461048f5780630bee7a67146104ba5780630e2374a5146104dc57610473565b3661047357005b600080fd5b34801561048457600080fd5b5061048d610bee565b005b34801561049b57600080fd5b506104a4610c60565b6040516104b19190616ef0565b60405180910390f35b3480156104c657600080fd5b506104cf610c66565b6040516104b19190616f1a565b3480156104e857600080fd5b506104f1610c6b565b6040516104b191906162f7565b34801561050a57600080fd5b5061051e6105193660046161dd565b610c71565b6040516104b1919061646e565b34801561053757600080fd5b50610540610ea9565b6040516104b19190616463565b34801561055957600080fd5b506104a4610eb2565b34801561056e57600080fd5b506104cf610eb8565b34801561058357600080fd5b5061048d6105923660046160a6565b610ebd565b3480156105a357600080fd5b506105406105b236600461618a565b611241565b3480156105c357600080fd5b506105406105d236600461618a565b611310565b3480156105e357600080fd5b5061048d6105f236600461607f565b6113c1565b34801561060357600080fd5b5061060c61151a565b6040516104b1929190616379565b34801561062657600080fd5b506104a46117f6565b34801561063b57600080fd5b506106446117fc565b6040516104b19190616f2b565b34801561065d57600080fd5b506104f1611801565b34801561067257600080fd5b506104a4611807565b34801561068757600080fd5b5061069061180d565b6040516104b19190616ee1565b3480156106a957600080fd5b50610644611812565b3480156106be57600080fd5b5061060c611817565b3480156106d357600080fd5b506104a4611995565b3480156106e857600080fd5b506104f161199b565b3480156106fd57600080fd5b506104a46119a1565b34801561071257600080fd5b5061054061072136600461607f565b6119a7565b34801561073257600080fd5b506104a461074136600461607f565b6119dc565b34801561075257600080fd5b50610644611a2d565b34801561076757600080fd5b506104cf611a32565b34801561077c57600080fd5b506104a4611a37565b34801561079157600080fd5b506107a56107a036600461618a565b611a3d565b6040516104b196959493929190616324565b3480156107c357600080fd5b506104f1611aa1565b3480156107d857600080fd5b50610644611aa7565b3480156107ed57600080fd5b50610644611aac565b34801561080257600080fd5b506104f1611ab1565b34801561081757600080fd5b506104a4611ab7565b34801561082c57600080fd5b50610644611abd565b34801561084157600080fd5b506104a4611ac2565b34801561085657600080fd5b506104cf611ac8565b34801561086b57600080fd5b5061048d61087a3660046161dd565b611acd565b34801561088b57600080fd5b506104a4611b2e565b3480156108a057600080fd5b506104a4611b34565b3480156108b557600080fd5b506104a4611b3a565b3480156108ca57600080fd5b506104a46108d936600461607f565b611b40565b3480156108ea57600080fd5b5061048d611b80565b3480156108ff57600080fd5b50610644611c94565b34801561091457600080fd5b506104f1611c99565b34801561092957600080fd5b506104a4611c9f565b34801561093e57600080fd5b506104a4611ca4565b34801561095357600080fd5b506104f1611ca9565b34801561096857600080fd5b5061051e611caf565b34801561097d57600080fd5b50610540611cce565b34801561099257600080fd5b506104a4611cd7565b3480156109a757600080fd5b506104cf611a2d565b3480156109bc57600080fd5b5061048d6109cb36600461612e565b611ce0565b3480156109dc57600080fd5b506104a46109eb36600461607f565b61258c565b3480156109fc57600080fd5b506104a461259e565b348015610a1157600080fd5b50610a1a6125ab565b6040516104b19190616366565b348015610a3357600080fd5b506104a4612697565b348015610a4857600080fd5b506104a4611aa7565b348015610a5d57600080fd5b506104f161269c565b348015610a7257600080fd5b506104a46126a2565b348015610a8757600080fd5b506104a46126a7565b348015610a9c57600080fd5b506104a46126e6565b348015610ab157600080fd5b506104a46126f2565b348015610ac657600080fd5b506104f16126f8565b348015610adb57600080fd5b506104a46126fe565b348015610af057600080fd5b5061048d612703565b348015610b0557600080fd5b506104a46128b2565b348015610b1a57600080fd5b5061048d610b2936600461607f565b6128b8565b348015610b3a57600080fd5b506104cf6129c0565b61048d610b5136600461607f565b6129c5565b348015610b6257600080fd5b506104a4612c4d565b348015610b7757600080fd5b506104f1612c53565b348015610b8c57600080fd5b50610644611c9f565b348015610ba157600080fd5b506104f1612c59565b348015610bb657600080fd5b50610bca610bc536600461618a565b612c5f565b6040516104b193929190616ef9565b348015610be557600080fd5b506104f1612d21565b6000610bf933611b40565b9050600b8181548110610c0857fe5b600091825260209091206001601690920201015460ff16610c445760405162461bcd60e51b8152600401610c3b90616b99565b60405180910390fd5b6000610c4e6126a7565b9050610c5b338383612d27565b505050565b60095481565b606481565b61200181565b60005460609060ff16610c965760405162461bcd60e51b8152600401610c3b9061662d565b3361200014610cb75760405162461bcd60e51b8152600401610c3b90616d78565b600b54610d7557610cc6615d6b565b60015460005b81811015610d7157600b8054600181018255600091909152835160008051602061714e833981519152601690920291820190815560208086015160008051602061718e8339815191528401805460ff1916911515919091179055604086015180518794610d4d9360008051602061716e833981519152909101920190615d9a565b506060820151610d639060038301906013615e14565b505050806001019050610ccc565b5050505b610d7d615e41565b6000610dbe85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612f1392505050565b9150915080610dda57610dd160646130cf565b92505050610ea2565b815160009060ff16610dff57610df883602001518460400151613130565b9050610e6e565b825160ff1660011415610e6a57826020015151600114610e445760008051602061712e833981519152604051610e3490616a80565b60405180910390a1506067610e65565b610df88360200151600081518110610e5857fe5b6020026020010151613d84565b610e6e565b5060655b63ffffffff8116610e935750506040805160008152602081019091529150610ea29050565b610e9c816130cf565b93505050505b9392505050565b60075460ff1681565b60035481565b606881565b334114610edc5760405162461bcd60e51b8152600401610c3b90616dc7565b6010544311610efd5760405162461bcd60e51b8152600401610c3b90616789565b60005460ff16610f1f5760405162461bcd60e51b8152600401610c3b9061662d565b600f54610f37576032600f5561100231601155611237565b60006110023168056bc75e2d63100000811115610f6657610f5f81606463ffffffff613efb16565b9150610faf565b601154811115610fa857610f5f6064610f9c600f54610f9060115486613f3d90919063ffffffff16565b9063ffffffff613f7f16565b9063ffffffff613efb16565b5050611237565b6040516309a99b4f60e41b815261100290639a99b4f090610fd6903090869060040161630b565b602060405180830381600087803b158015610ff057600080fd5b505af1158015611004573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061102891906161a2565b6110023160115591508161103d575050611237565b6000805b8481101561106b5785858281811061105557fe5b9050602002013582019150806001019050611041565b508061107957505050611237565b6000806000805b8981101561122f578489898381811061109557fe5b905060200201358802816110a557fe5b0493508a8a828181106110b457fe5b90506020020160208101906110c9919061607f565b6001600160a01b038116600090815260046020526040902054909350915081156111e55760006001808403815481106110fe57fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff161561116b57836001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d858660405161115e9190616ef0565b60405180910390a26111df565b60035461117e908663ffffffff613fb916565b6003908155810154611196908663ffffffff613fb916565b60038201556040516001600160a01b038516907fcb0aad6cf9cd03bdf6137e359f541c42f38b39f007cae8e89e88aa7d8c6617b2906111d6908890616ef0565b60405180910390a25b50611227565b826001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d858560405161121e9190616ef0565b60405180910390a25b600101611080565b505050505050505b5050436010555050565b60015460009082106112555750600061130b565b60006001600160a01b03166001838154811061126d57fe5b60009182526020909120600490910201546001600160a01b0316148061129d5750600854158061129d5750600a54155b806112ac575060085460095410155b806112bd57506112bb82611310565b155b806112e657506000600b83815481106112d257fe5b906000526020600020906016020160000154115b806112fa575060016112f66125ab565b5111155b156113075750600061130b565b5060015b919050565b60015460009082106113245750600061130b565b600b548210611361576001828154811061133a57fe5b9060005260206000209060040201600201601c9054906101000a900460ff1615905061130b565b6001828154811061136e57fe5b9060005260206000209060040201600201601c9054906101000a900460ff161580156113bb5750600b82815481106113a257fe5b600091825260209091206001601690920201015460ff16155b92915050565b33611001146113e25760405162461bcd60e51b8152600401610c3b90616e98565b600b546114a0576113f1615d6b565b60015460005b8181101561149c57600b8054600181018255600091909152835160008051602061714e833981519152601690920291820190815560208086015160008051602061718e8339815191528401805460ff19169115159190911790556040860151805187946114789360008051602061716e833981519152909101920190615d9a565b50606082015161148e9060038301906013615e14565b5050508060010190506113f7565b5050505b6001600160a01b038116600090815260046020526040902054806114c45750611517565b6001810390506000600b82815481106114d957fe5b600091825260209091206001601690920201015460ff1690506114fc8383613fde565b80156115055750805b15610c5b576009805460001901905550505b50565b60015460609081906000805b8281101561156d576001818154811061153b57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611565576001909101905b600101611526565b5060608160405190808252806020026020018201604052801561159a578160200160208202803683370190505b5090506060826040519080825280602002602001820160405280156115d357816020015b60608152602001906001900390816115be5790505b50600b546000945090915084141561174e5760005b8481101561174857600181815481106115fd57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611740576001818154811061162d57fe5b600091825260209091206004909102015483516001600160a01b039091169084908690811061165857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600b818154811061168557fe5b600091825260209182902060026016909202018101805460408051601f60001961010060018616150201909316949094049182018590048502840185019052808352919290919083018282801561171d5780601f106116f25761010080835404028352916020019161171d565b820191906000526020600020905b81548152906001019060200180831161170057829003601f168201915b505050505082858151811061172e57fe5b60209081029190910101526001909301925b6001016115e8565b506117ea565b60005b848110156117e8576001818154811061176657fe5b9060005260206000209060040201600201601c9054906101000a900460ff166117e0576001818154811061179657fe5b600091825260209091206004909102015483516001600160a01b03909116908490869081106117c157fe5b6001600160a01b03909216602092830291909101909101526001909301925b600101611751565b505b909450925050505b9091565b61271081565b600181565b61100181565b60085481565b606181565b600881565b600e54600c5460609182918061182b575060155b60606118356125ab565b9050606061184282614391565b9050828251116118595790945092506117f2915050565b8383835103101561186b578282510393505b83156118a15760c8430461188783838388880360008a8a6144ff565b61189f8383838888038989038a8b8b8b5103016144ff565b505b6060836040519080825280602002602001820160405280156118cd578160200160208202803683370190505b50905060608460405190808252806020026020018201604052801561190657816020015b60608152602001906001900390816118f15790505b50905060005b858110156119875784818151811061192057fe5b602002602001015183828151811061193457fe5b60200260200101906001600160a01b031690816001600160a01b03168152505083818151811061196057fe5b602002602001015182828151811061197457fe5b602090810291909101015260010161190c565b509096509450505050509091565b60065481565b61200081565b600f5481565b6001600160a01b038116600090815260046020526040812054806119cf57600091505061130b565b60001901610ea281611310565b6001600160a01b03811660009081526004602052604081205480611a0457600091505061130b565b600180820381548110611a1357fe5b906000526020600020906004020160030154915050919050565b600081565b606781565b60105481565b60018181548110611a4a57fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b0392831694509082169291821691600160a01b81046001600160401b031691600160e01b90910460ff169086565b61100581565b600281565b601081565b61100881565b6103e881565b600b81565b600c5481565b606681565b3361200014611aee5760405162461bcd60e51b8152600401610c3b90616d78565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051611b2193929190616f39565b60405180910390a1505050565b60025481565b60115481565b600a5481565b6001600160a01b03811660009081526004602052604081205480611b765760405162461bcd60e51b8152600401610c3b90616d00565b6000190192915050565b600b54611c3e57611b8f615d6b565b60015460005b81811015611c3a57600b8054600181018255600091909152835160008051602061714e833981519152601690920291820190815560208086015160008051602061718e8339815191528401805460ff1916911515919091179055604086015180518794611c169360008051602061716e833981519152909101920190615d9a565b506060820151611c2c9060038301906013615e14565b505050806001019050611b95565b5050505b600854611c4b5760036008555b600a54611c58576002600a555b6000611c6333611b40565b9050611c6e81611241565b611c8a5760405162461bcd60e51b8152600401610c3b90616a3d565b6115173382614656565b600981565b61100781565b600381565b60c881565b61100681565b604051806101e001604052806101ab8152602001616f836101ab913981565b60005460ff1681565b6402540be40081565b60005460ff16611d025760405162461bcd60e51b8152600401610c3b9061662d565b3361100714611d235760405162461bcd60e51b8152600401610c3b90616b06565b611d8d84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526013815272065787069726554696d655365636f6e6447617606c1b602082015291506146ee9050565b15611e2a5760208114611db25760405162461bcd60e51b8152600401610c3b90616cba565b604080516020601f8401819004810282018101909252828152600091611df09185858083850183828082843760009201919091525061474792505050565b905060648110158015611e065750620186a08111155b611e225760405162461bcd60e51b8152600401610c3b906168e6565b600255612549565b611e8a84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260098152686275726e526174696f60b81b602082015291506146ee9050565b15611f265760208114611eaf5760405162461bcd60e51b8152600401610c3b906164b3565b604080516020601f8401819004810282018101909252828152600091611eed9185858083850183828082843760009201919091525061474792505050565b9050612710811115611f115760405162461bcd60e51b8152600401610c3b906167cb565b6006556007805460ff19166001179055612549565b611f9084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260138152726d61784e756d4f664d61696e7461696e696e6760681b602082015291506146ee9050565b1561202a5760208114611fb55760405162461bcd60e51b8152600401610c3b906164ea565b604080516020601f8401819004810282018101909252828152600091611ff39185858083850183828082843760009201919091525061474792505050565b600c5490915080612002575060155b8082106120215760405162461bcd60e51b8152600401610c3b9061683e565b50600855612549565b61209384848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61696e7461696e536c6173685363616c6560701b602082015291506146ee9050565b1561212c57602081146120b85760405162461bcd60e51b8152600401610c3b906165b3565b604080516020601f84018190048102820181019092528281526000916120f69185858083850183828082843760009201919091525061474792505050565b90506000811180156121085750600a81105b6121245760405162461bcd60e51b8152600401610c3b90616e14565b600a55612549565b6121a084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601981527f6d61784e756d4f66576f726b696e6743616e6469646174657300000000000000602082015291506146ee9050565b1561222f57602081146121c55760405162461bcd60e51b8152600401610c3b90616567565b604080516020601f84018190048102820181019092528281526000916122039185858083850183828082843760009201919091525061474792505050565b9050600d548111156122275760405162461bcd60e51b8152600401610c3b9061695c565b600e55612549565b61229884848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61784e756d4f6643616e6469646174657360701b602082015291506146ee9050565b1561231a57602081146122bd5760405162461bcd60e51b8152600401610c3b90616b54565b604080516020601f84018190048102820181019092528281526000916122fb9185858083850183828082843760009201919091525061474792505050565b600d819055600e5490915081101561231457600d54600e555b50612549565b61237e84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c6e756d4f66436162696e65747360981b602082015291506146ee9050565b1561242c57602081146123a35760405162461bcd60e51b8152600401610c3b906165f8565b604080516020601f84018190048102820181019092528281526000916123e19185858083850183828082843760009201919091525061474792505050565b9050600081116124035760405162461bcd60e51b8152600401610c3b9061669b565b60298111156124245760405162461bcd60e51b8152600401610c3b906166e3565b600c55612549565b61249684848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601381527266696e616c697479526577617264526174696f60681b602082015291506146ee9050565b1561253157602081146124bb5760405162461bcd60e51b8152600401610c3b90616c3d565b604080516020601f84018190048102820181019092528281526000916124f99185858083850183828082843760009201919091525061474792505050565b90506001811015801561250d575060648111155b6125295760405162461bcd60e51b8152600401610c3b906169cb565b600f55612549565b60405162461bcd60e51b8152600401610c3b90616e71565b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a8484848460405161257e9493929190616481565b60405180910390a150505050565b60046020526000908152604090205481565b68056bc75e2d6310000081565b6001546060906000805b828110156125da576125c681611310565b156125d2578160010191505b6001016125b5565b50606081604051908082528060200260200182016040528015612607578160200160208202803683370190505b5090506000915060005b8381101561268e5761262281611310565b15612686576001818154811061263457fe5b600091825260209091206004909102015482516001600160a01b039091169083908590811061265f57fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508260010192505b600101612611565b50925050505b90565b601581565b61100281565b603281565b60006126b16125ab565b519050600080600c54116126c65760156126ca565b600c545b9050808211156126d8578091505b816126e257600191505b5090565b67016345785d8a000081565b60055481565b61100381565b602981565b60005460ff16156127265760405162461bcd60e51b8152600401610c3b90616c06565b61272e615e41565b6000612754604051806101e001604052806101ab8152602001616f836101ab9139612f13565b91509150806127755760405162461bcd60e51b8152600401610c3b90616d37565b60005b82602001515181101561289a5760018360200151828151811061279757fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782558587015182850180549185169183169190911790556040860151600283018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590981692909516919091179290921694909417161790915560a09093015160039093019290925591860151805191850193918590811061286d57fe5b602090810291909101810151516001600160a01b0316825281019190915260400160002055600101612778565b50506103e8600255506000805460ff19166001179055565b600d5481565b33611001146128d95760405162461bcd60e51b8152600401610c3b90616e98565b600b54612997576128e8615d6b565b60015460005b8181101561299357600b8054600181018255600091909152835160008051602061714e833981519152601690920291820190815560208086015160008051602061718e8339815191528401805460ff191691151591909117905560408601518051879461296f9360008051602061716e833981519152909101920190615d9a565b5060608201516129859060038301906013615e14565b5050508060010190506128ee565b5050505b60006129a28261474c565b90506129ad81611241565b156129bc576129bc8282614656565b5050565b606581565b3341146129e45760405162461bcd60e51b8152600401610c3b90616dc7565b60005460ff16612a065760405162461bcd60e51b8152600401610c3b9061662d565b60003411612a265760405162461bcd60e51b8152600401610c3b9061692d565b6001600160a01b0381166000908152600460205260409020546007543491906103e89060ff1615612a5657506006545b600083118015612a665750600081115b15612b07576000612a83612710610f9c868563ffffffff613f7f16565b90508015612b055760405161dead9082156108fc029083906000818181858888f19350505050158015612aba573d6000803e3d6000fd5b507f627059660ea01c4733a328effb2294d2f86905bf806da763a89cee254de8bee581604051612aea9190616ef0565b60405180910390a1612b02848263ffffffff613f3d16565b93505b505b8115612c05576000600180840381548110612b1e57fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff1615612b8b57846001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b485604051612b7e9190616ef0565b60405180910390a2612bff565b600354612b9e908563ffffffff613fb916565b6003908155810154612bb6908563ffffffff613fb916565b60038201556040516001600160a01b038616907f93a090ecc682c002995fad3c85b30c5651d7fd29b0be5da9d784a3302aedc05590612bf6908790616ef0565b60405180910390a25b50612c47565b836001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b484604051612c3e9190616ef0565b60405180910390a25b50505050565b600e5481565b61100081565b61dead81565b600b8181548110612c6c57fe5b6000918252602091829020601691909102018054600180830154600280850180546040805161010096831615969096026000190190911692909204601f810188900488028501880190925281845293965060ff90911694919291830182828015612d175780601f10612cec57610100808354040283529160200191612d17565b820191906000526020600020905b815481529060010190602001808311612cfa57829003601f168201915b5050505050905083565b61100481565b6000600a5460001480612d38575081155b80612d435750600954155b15612d5057506000610ea2565b60096000815460019003919050819055506000612d9b600a54610f9c85610f9c600b8981548110612d7d57fe5b6000918252602090912060169091020154439063ffffffff613f3d16565b90506000600b8581548110612dac57fe5b906000526020600020906016020160010160006101000a81548160ff0219169083151502179055506000806110016001600160a01b0316638256ace66040518163ffffffff1660e01b8152600401604080518083038186803b158015612e1157600080fd5b505afa158015612e25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e4991906161ba565b9150915060009350808310612ec357612e628787613fde565b506040516305bfb49960e41b815261100190635bfb499090612e88908a906004016162f7565b600060405180830381600087803b158015612ea257600080fd5b505af1158015612eb6573d6000803e3d6000fd5b5050505060019350612ed5565b818310612ed557612ed38761474c565b505b6040516001600160a01b038816907fb9d38178dc641ff1817967a63c9078cbcd955a9f1fcd75e0e3636de615d44d3b90600090a25050509392505050565b612f1b615e41565b6000612f25615e41565b612f2d615e65565b612f3e612f39866148ef565b614914565b90506000805b612f4d8361495e565b156130c15780612f7257612f68612f638461497f565b6149cd565b60ff1684526130b9565b80600114156130b4576060612f8e612f898561497f565b614a4d565b90508051604051908082528060200260200182016040528015612fcb57816020015b612fb8615e85565b815260200190600190039081612fb05790505b508560200181905250805160405190808252806020026020018201604052801561300957816020015b6060815260200190600190039081612ff45790505b50604086015260005b81518110156130a957613023615e85565b6060600061304385858151811061303657fe5b6020026020010151614b1e565b92509250925080613063578860009a509a505050505050505050506130ca565b828960200151858151811061307457fe5b6020026020010181905250818960400151858151811061309057fe5b6020026020010181905250505050806001019050613012565b5060019250506130b9565b6130c1565b600101612f44565b50919350909150505b915091565b604080516001808252818301909252606091829190816020015b60608152602001906001900390816130e957905050905061310f8363ffffffff16614c38565b8160008151811061311c57fe5b6020026020010181905250610ea281614c4b565b60006029835111156131675760008051602061712e83398151915260405161315790616740565b60405180910390a15060666113bb565b60005b83518110156132055760005b818110156131fc5784818151811061318a57fe5b6020026020010151600001516001600160a01b03168583815181106131ab57fe5b6020026020010151600001516001600160a01b031614156131f45760008051602061712e8339815191526040516131e19061689b565b60405180910390a16066925050506113bb565b600101613176565b5060010161316a565b506060806132138585614cd5565b60015491935091506000908190815b818110156132985767016345785d8a00006001828154811061324057fe5b9060005260206000209060040201600301541061326257836001019350613290565b60006001828154811061327157fe5b9060005260206000209060040201600301541115613290578260010192505b600101613222565b506060836040519080825280602002602001820160405280156132c5578160200160208202803683370190505b5090506060846040519080825280602002602001820160405280156132f4578160200160208202803683370190505b509050606085604051908082528060200260200182016040528015613323578160200160208202803683370190505b509050606086604051908082528060200260200182016040528015613352578160200160208202803683370190505b5090506000606087604051908082528060200260200182016040528015613383578160200160208202803683370190505b5090506060886040519080825280602002602001820160405280156133b2578160200160208202803683370190505b509050600099506000985060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b1580156133fa57600080fd5b505afa15801561340e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061343291906161a2565b905067016345785d8a000081111561347d5760008051602061712e83398151915260405161345f90616bc5565b60405180910390a160689d50505050505050505050505050506113bb565b60005b898110156136ee5767016345785d8a00006001828154811061349e57fe5b9060005260206000209060040201600301541061362357600181815481106134c257fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316898d815181106134f357fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060006402540be4006001838154811061352857fe5b9060005260206000209060040201600301548161354157fe5b066001838154811061354f57fe5b9060005260206000209060040201600301540390506135778382613f3d90919063ffffffff16565b898e8151811061358357fe5b6020026020010181815250506001828154811061359c57fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316878e815181106135cd57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505081888e815181106135fa57fe5b6020908102919091010152613615868263ffffffff613fb916565b95508c6001019c50506136e6565b60006001828154811061363257fe5b90600052602060002090600402016003015411156136e6576001818154811061365757fe5b906000526020600020906004020160010160009054906101000a90046001600160a01b0316848c8151811061368857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600181815481106136b557fe5b906000526020600020906004020160030154838c815181106136d357fe5b6020026020010181815250508a6001019a505b600101613480565b5060008415613964576002546040516303702b2960e51b815261100491636e056520918891613728918e918e918d914201906004016163e9565b6020604051808303818588803b15801561374157600080fd5b505af193505050508015613772575060408051601f3d908101601f1916820190925261376f9181019061610e565b60015b6138e9576040516000815260443d101561378e57506000613829565b60046000803e60005160e01c6308c379a081146137af576000915050613829565b60043d036004833e81513d60248201116001600160401b03821117156137da57600092505050613829565b80830180516001600160401b038111156137fb576000945050505050613829565b8060208301013d860181111561381957600095505050505050613829565b601f01601f191660405250925050505b806138345750613876565b60019150857fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf28082604051613868919061646e565b60405180910390a2506138e4565b3d8080156138a0576040519150601f19603f3d011682016040523d82523d6000602084013e6138a5565b606091505b5060019150857fbfa884552dd8921b6ce90bfe906952ae5b3b29be0cc1a951d4f62697635a3a45826040516138da919061646e565b60405180910390a2505b613964565b801561392b577fa217d08e65f80c73121cd9db834d81652d544bfbf452f6d04922b16c90a37b708660405161391e9190616ef0565b60405180910390a1613962565b857fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf28060405161395990616530565b60405180910390a25b505b8015613b1a5760005b8751811015613b1857600088828151811061398457fe5b6020026020010151905060006001828154811061399d57fe5b60009182526020909120600160049092020181015481546001600160a01b03909116916108fc91859081106139ce57fe5b9060005260206000209060040201600301549081150290604051600060405180830381858888f1935050505090508015613a8a5760018281548110613a0f57fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d9185908110613a5e57fe5b906000526020600020906004020160030154604051613a7d9190616ef0565b60405180910390a2613b0e565b60018281548110613a9757fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d9185908110613ae657fe5b906000526020600020906004020160030154604051613b059190616ef0565b60405180910390a25b505060010161396d565b505b835115613c645760005b8451811015613c62576000858281518110613b3b57fe5b60200260200101516001600160a01b03166108fc868481518110613b5b57fe5b60200260200101519081150290604051600060405180830381858888f1935050505090508015613bf157858281518110613b9157fe5b60200260200101516001600160a01b03167f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d868481518110613bcf57fe5b6020026020010151604051613be49190616ef0565b60405180910390a2613c59565b858281518110613bfd57fe5b60200260200101516001600160a01b03167f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d868481518110613c3b57fe5b6020026020010151604051613c509190616ef0565b60405180910390a25b50600101613b24565b505b5050505050505050505050506000471115613ce0577f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d47604051613ca89190616ef0565b60405180910390a1604051611002904780156108fc02916000818181858888f19350505050158015613cde573d6000803e3d6000fd5b505b60006003819055600555815115613cfb57613cfb8282614f0e565b6110016001600160a01b031663fc4333cd6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015613d3857600080fd5b505af1158015613d4c573d6000803e3d6000fd5b50506040517fedd8d7296956dd970ab4de3f2fc03be2b0ffc615d20cd4c72c6e44f928630ebf925060009150a1506000949350505050565b80516001600160a01b0316600090815260046020526040812054801580613dd55750600180820381548110613db557fe5b9060005260206000209060040201600201601c9054906101000a900460ff165b15613e1b5782516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a2600091505061130b565b600154600554600019820111801590613e715784516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a26000935050505061130b565b600580546001908101909155805481906000198601908110613e8f57fe5b6000918252602082206002600490920201018054921515600160e01b0260ff60e01b199093169290921790915585516040516001600160a01b03909116917ff226e7d8f547ff903d9d419cf5f54e0d7d07efa9584135a53a057c5f1f27f49a91a2506000949350505050565b6000610ea283836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506156ed565b6000610ea283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250615724565b600082613f8e575060006113bb565b82820282848281613f9b57fe5b0414610ea25760405162461bcd60e51b8152600401610c3b90616ac5565b600082820183811015610ea25760405162461bcd60e51b8152600401610c3b90616664565b60008060018381548110613fee57fe5b906000526020600020906004020160030154905060006001808054905003905060016140186125ab565b511161404d5760006001858154811061402d57fe5b9060005260206000209060040201600301819055506000925050506113bb565b846001600160a01b03167f3b6f9ef90462b512a1293ecec018670bf7b7f1876fb727590a8a6d7643130a70836040516140869190616ef0565b60405180910390a26001600160a01b038516600090815260046020526040812055835b6001546000190181101561427357600181600101815481106140c757fe5b9060005260206000209060040201600182815481106140e257fe5b60009182526020909120825460049092020180546001600160a01b03199081166001600160a01b0393841617825560018085015481840180548416918616919091179055600280860180549185018054909416919095161780835584546001600160401b03600160a01b91829004160267ffffffffffffffff60a01b1990911617808355935460ff600160e01b918290041615150260ff60e01b19909416939093179055600392830154920191909155600b8054909183019081106141a357fe5b9060005260206000209060160201600b82815481106141be57fe5b600091825260209091208254601690920201908155600180830154818301805460ff909216151560ff1990921691909117905560028084018054614215938386019390821615610100026000190190911604615eba565b5061422860038281019084016013615f2f565b5090505080600101600460006001848154811061424157fe5b600091825260208083206004909202909101546001600160a01b031683528201929092526040019020556001016140a9565b50600180548061427f57fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b8054806142d257fe5b60008281526020812060166000199093019283020181815560018101805460ff19169055906143046002830182615f59565b614312600383016000615f9d565b50509055600081838161432157fe5b04905080156143855760015460005b8181101561438257826001828154811061434657fe5b906000526020600020906004020160030154016001828154811061436657fe5b6000918252602090912060036004909202010155600101614330565b50505b50600195945050505050565b6001548151604080518281526020808402820101909152606092919083908280156143d057816020015b60608152602001906001900390816143bb5790505b50600b5490915083146143e757925061130b915050565b60005b828110156144f657600b60016004600089858151811061440657fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002054038154811061443a57fe5b600091825260209182902060026016909202018101805460408051601f6000196101006001861615020190931694909404918201859004850284018501905280835291929091908301828280156144d25780601f106144a7576101008083540402835291602001916144d2565b820191906000526020600020905b8154815290600101906020018083116144b557829003601f168201915b50505050508282815181106144e357fe5b60209081029190910101526001016143ea565b50949350505050565b60005b8281101561464c57600082878388016040516020016145229291906162e9565b6040516020818303038152906040528051906020012060001c8161454257fe5b06905080850182870114614643576000898388018151811061456057fe5b602002602001015190506060898489018151811061457a57fe5b602002602001015190508a8388018151811061459257fe5b60200260200101518b858a01815181106145a857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050818b848901815181106145d757fe5b60200260200101906001600160a01b031690816001600160a01b031681525050898388018151811061460557fe5b60200260200101518a858a018151811061461b57fe5b6020026020010181905250808a8489018151811061463557fe5b602002602001018190525050505b50600101614502565b5050505050505050565b600980546001908101909155600b80548390811061467057fe5b906000526020600020906016020160010160006101000a81548160ff02191690831515021790555043600b82815481106146a657fe5b600091825260208220601690910201919091556040516001600160a01b038416917ff62981a567ec3cec866c6fa93c55bcdf841d6292d18b8d522ececa769375d82d91a25050565b60008160405160200161470191906162cd565b604051602081830303815290604052805190602001208360405160200161472891906162cd565b6040516020818303038152906040528051906020012014905092915050565b015190565b6001600160a01b038116600090815260046020526040812054806147755750600019905061130b565b60018103905060006001828154811061478a57fe5b90600052602060002090600402016003015490506000600183815481106147ad57fe5b6000918252602090912060036004909202010155600154604051600019909101906001600160a01b038616907f8cd4e147d8af98a9e3b6724021b8bf6aed2e5dac71c38f2dce8161b82585b25d90614806908590616ef0565b60405180910390a28061481e5782935050505061130b565b600081838161482957fe5b04905080156148e55760005b8481101561488757816001828154811061484b57fe5b906000526020600020906004020160030154016001828154811061486b57fe5b6000918252602090912060036004909202010155600101614835565b50600180549085015b818110156148e25782600182815481106148a657fe5b90600052602060002090600402016003015401600182815481106148c657fe5b6000918252602090912060036004909202010155600101614890565b50505b5091949350505050565b6148f7615fac565b506040805180820190915281518152602082810190820152919050565b61491c615e65565b61492582615750565b61492e57600080fd5b600061493d836020015161578a565b60208085015160408051808201909152868152920190820152915050919050565b6000614968615fac565b505080518051602091820151919092015191011190565b614987615fac565b6149908261495e565b61499957600080fd5b602082015160006149a9826157ed565b80830160209586015260408051808201909152908152938401919091525090919050565b8051600090158015906149e257508151602110155b6149eb57600080fd5b60006149fa836020015161578a565b90508083600001511015614a205760405162461bcd60e51b8152600401610c3b90616c83565b8251602080850151830180519284900392918310156144f657506020919091036101000a90049392505050565b6060614a5882615750565b614a6157600080fd5b6000614a6c836158ce565b9050606081604051908082528060200260200182016040528015614aaa57816020015b614a97615fac565b815260200190600190039081614a8f5790505b5090506000614abc856020015161578a565b60208601510190506000805b84811015614b1357614ad9836157ed565b9150604051806040016040528083815260200184815250848281518110614afc57fe5b602090810291909101015291810191600101614ac8565b509195945050505050565b614b26615e85565b60606000614b32615e85565b6060614b3c615e65565b614b4587614914565b90506000805b614b548361495e565b15614c295780614b7f57614b6f614b6a8461497f565b61592a565b6001600160a01b03168552614c21565b8060011415614ba757614b94614b6a8461497f565b6001600160a01b03166020860152614c21565b8060021415614bcf57614bbc614b6a8461497f565b6001600160a01b03166040860152614c21565b8060031415614bfb57614be4612f638461497f565b6001600160401b0316606086015260019150614c21565b8060041415614c1c57614c15614c108461497f565b615944565b9350614c21565b614c29565b600101614b4b565b50929791965091945092505050565b60606113bb614c46836159b4565b615a9a565b6060815160001415614c6c575060408051600081526020810190915261130b565b606082600081518110614c7b57fe5b602002602001015190506000600190505b8351811015614cbc57614cb282858381518110614ca557fe5b6020026020010151615aec565b9150600101614c8c565b50610ea2614ccf825160c060ff16615b69565b82615aec565b606080600080808080614ce66126a7565b6001549091505b8015614df457600181039250600b8381548110614d0657fe5b600091825260209091206001601690920201015460ff16614d2657614deb565b60018381548110614d3357fe5b60009182526020909120600490910201546001600160a01b03169450614d5a858484612d27565b9350831580614d6d575060018a51038610155b15614d7757614deb565b60005b8a51811015614de957856001600160a01b03168b8281518110614d9957fe5b6020026020010151600001516001600160a01b03161415614de15760018b8281518110614dc257fe5b6020908102919091010151901515608090910152600190960195614de9565b600101614d7a565b505b60001901614ced565b5084895103604051908082528060200260200182016040528015614e3257816020015b614e1f615e85565b815260200190600190039081614e175790505b50965084895103604051908082528060200260200182016040528015614e6c57816020015b6060815260200190600190039081614e575790505b5095506000915060005b8951811015614f0057898181518110614e8b57fe5b602002602001015160800151614ef857898181518110614ea757fe5b6020026020010151888481518110614ebb57fe5b6020026020010181905250888181518110614ed257fe5b6020026020010151878481518110614ee657fe5b60200260200101819052508260010192505b600101614e76565b5050505050505b9250929050565b600154825160005b8281101561502b576001614f28615e85565b60018381548110614f3557fe5b600091825260208083206040805160c08101825260049490940290910180546001600160a01b0390811685526001820154811693850193909352600281015492831691840191909152600160a01b82046001600160401b03166060840152600160e01b90910460ff16151560808301526003015460a082015291505b84811015614fff57878181518110614fc557fe5b6020026020010151600001516001600160a01b031682600001516001600160a01b03161415614ff75760009250614fff565b600101614fb1565b5081156150215780516001600160a01b03166000908152600460205260408120555b5050600101614f16565b50808211156150ea57805b828110156150e857600180548061504957fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b80548061509c57fe5b60008281526020812060166000199093019283020181815560018101805460ff19169055906150ce6002830182615f59565b6150dc600383016000615f9d565b50509055600101615036565b505b60008183106150f957816150fb565b825b905060005b8181101561549f576151ad86828151811061511757fe5b60200260200101516001838154811061512c57fe5b60009182526020918290206040805160c08101825260049390930290910180546001600160a01b0390811684526001820154811694840194909452600281015493841691830191909152600160a01b83046001600160401b03166060830152600160e01b90920460ff161515608082015260039091015460a0820152615c3b565b6153615780600101600460008884815181106151c557fe5b6020026020010151600001516001600160a01b03166001600160a01b031681526020019081526020016000208190555085818151811061520157fe5b60200260200101516001828154811061521657fe5b6000918252602091829020835160049092020180546001600160a01b039283166001600160a01b0319918216178255928401516001820180549184169185169190911790556040840151600282018054606087015160808801511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909716929097169190911792909216939093171692909217905560a09091015160039091015584518590829081106152d157fe5b6020026020010151600b82815481106152e657fe5b9060005260206000209060160201600201908051906020019061530a929190615d9a565b506000600b828154811061531a57fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b80548390811061534b57fe5b6000918252602090912060169091020155615497565b61542785828151811061537057fe5b6020026020010151600b838154811061538557fe5b600091825260209182902060026016909202018101805460408051601f60001961010060018616150201909316949094049182018590048502840185019052808352919290919083018282801561541d5780601f106153f25761010080835404028352916020019161541d565b820191906000526020600020905b81548152906001019060200180831161540057829003601f168201915b5050505050615cbc565b6154725784818151811061543757fe5b6020026020010151600b828154811061544c57fe5b90600052602060002090601602016002019080519060200190615470929190615d9a565b505b60006001828154811061548157fe5b9060005260206000209060040201600301819055505b600101615100565b5082821115615677576154b0615d6b565b835b83811015615674578581815181106154c657fe5b6020026020010151826040018190525060018782815181106154e457fe5b6020908102919091018101518254600181810185556000948552838520835160049093020180546001600160a01b039384166001600160a01b0319918216178255848601518284018054918616918316919091179055604080860151600284018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909a1692909616919091179290921696909617169190911790935560a090930151600390930192909255600b805492830181559093528451601690910260008051602061714e83398151915281019182558583015160008051602061718e8339815191528201805491151560ff199092169190911790559285015180518694929361561a9360008051602061716e83398151915201920190615d9a565b5060608201516156309060038301906013615e14565b505050806001016004600089848151811061564757fe5b602090810291909101810151516001600160a01b03168252810191909152604001600020556001016154b2565b50505b6000600981905560015493505b838110156156e5576000600b828154811061569b57fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b8054839081106156cc57fe5b6000918252602090912060169091020155600101615684565b505050505050565b6000818361570e5760405162461bcd60e51b8152600401610c3b919061646e565b50600083858161571a57fe5b0495945050505050565b600081848411156157485760405162461bcd60e51b8152600401610c3b919061646e565b505050900390565b80516000906157615750600061130b565b6020820151805160001a9060c08210156157805760009250505061130b565b5060019392505050565b8051600090811a60808110156157a457600091505061130b565b60b88110806157bf575060c081108015906157bf575060f881105b156157ce57600191505061130b565b60c08110156157e25760b51901905061130b565b60f51901905061130b565b80516000908190811a608081101561580857600191506158c7565b60b881101561581d57607e19810191506158c7565b60c081101561586e57600060b78203600186019550806020036101000a8651049150600181018201935050808310156158685760405162461bcd60e51b8152600401610c3b90616a12565b506158c7565b60f88110156158835760be19810191506158c7565b600060f78203600186019550806020036101000a8651049150600181018201935050808310156158c55760405162461bcd60e51b8152600401610c3b90616a12565b505b5092915050565b80516000906158df5750600061130b565b600080905060006158f3846020015161578a565b602085015185519181019250015b8082101561592157615912826157ed565b82019150826001019250615901565b50909392505050565b805160009060151461593b57600080fd5b6113bb826149cd565b805160609061595257600080fd5b6000615961836020015161578a565b83516040805191839003808352601f19601f8201168301602001909152919250606090828015615998576020820181803683370190505b50905060008160200190506144f6848760200151018285615d20565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166159f857506018615a1c565b6fffffffffffffffffffffffffffffffff198416615a1857506010615a1c565b5060005b6020811015615a5257818181518110615a3157fe5b01602001516001600160f81b03191615615a4a57615a52565b600101615a1c565b60008160200390506060816040519080825280601f01601f191660200182016040528015615a87576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015615acc5750607f60f81b82600081518110615aba57fe5b01602001516001600160f81b03191611155b15615ad857508061130b565b6113bb615aea8351608060ff16615b69565b835b6060806040519050835180825260208201818101602087015b81831015615b1d578051835260209283019201615b05565b50855184518101855292509050808201602086015b81831015615b4a578051835260209283019201615b32565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310615b935760405162461bcd60e51b8152600401610c3b90616816565b60408051600180825281830190925260609160208201818036833701905050905060378411615bed5782840160f81b81600081518110615bcf57fe5b60200101906001600160f81b031916908160001a90535090506113bb565b6060615bf8856159b4565b90508381510160370160f81b82600081518110615c1157fe5b60200101906001600160f81b031916908160001a905350615c328282615aec565b95945050505050565b805182516000916001600160a01b039182169116148015615c75575081602001516001600160a01b031683602001516001600160a01b0316145b8015615c9a575081604001516001600160a01b031683604001516001600160a01b0316145b8015610ea25750506060908101519101516001600160401b0390811691161490565b815181516000916001918114808314615cd85760009250615d16565b600160208701838101602088015b600284838510011415615d11578051835114615d055760009650600093505b60209283019201615ce6565b505050505b5090949350505050565b80615d2a57610c5b565b5b60208110615d4a578251825260209283019290910190601f1901615d2b565b915181516020939093036101000a6000190180199091169216919091179052565b60405180608001604052806000815260200160001515815260200160608152602001615d95615fc6565b905290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615ddb57805160ff1916838001178555615e08565b82800160010185558215615e08579182015b82811115615e08578251825591602001919060010190615ded565b506126e2929150615fe5565b8260138101928215615e085791602002820182811115615e08578251825591602001919060010190615ded565b6040518060600160405280600060ff16815260200160608152602001606081525090565b6040518060400160405280615e78615fac565b8152602001600081525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615ef35780548555615e08565b82800160010185558215615e0857600052602060002091601f016020900482015b82811115615e08578254825591600101919060010190615f14565b8260138101928215615e085791820182811115615e08578254825591600101919060010190615f14565b50805460018160011615610100020316600290046000825580601f10615f7f5750611517565b601f0160209004906000526020600020908101906115179190615fe5565b50611517906013810190615fe5565b604051806040016040528060008152602001600081525090565b6040518061026001604052806013906020820280368337509192915050565b61269491905b808211156126e25760008155600101615feb565b60008083601f840112616010578182fd5b5081356001600160401b03811115616026578182fd5b6020830191508360208083028501011115614f0757600080fd5b60008083601f840112616051578182fd5b5081356001600160401b03811115616067578182fd5b602083019150836020828501011115614f0757600080fd5b600060208284031215616090578081fd5b81356001600160a01b0381168114610ea2578182fd5b600080600080604085870312156160bb578283fd5b84356001600160401b03808211156160d1578485fd5b6160dd88838901615fff565b909650945060208701359150808211156160f5578384fd5b5061610287828801615fff565b95989497509550505050565b60006020828403121561611f578081fd5b81518015158114610ea2578182fd5b60008060008060408587031215616143578384fd5b84356001600160401b0380821115616159578586fd5b61616588838901616040565b9096509450602087013591508082111561617d578384fd5b5061610287828801616040565b60006020828403121561619b578081fd5b5035919050565b6000602082840312156161b3578081fd5b5051919050565b600080604083850312156161cc578182fd5b505080516020909101519092909150565b6000806000604084860312156161f1578283fd5b833560ff81168114616201578384fd5b925060208401356001600160401b0381111561621b578283fd5b61622786828701616040565b9497909650939450505050565b6000815180845260208085019450808401835b8381101561626c5781516001600160a01b031687529582019590820190600101616247565b509495945050505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b600081518084526162b9816020860160208601616f56565b601f01601f19169290920160200192915050565b600082516162df818460208701616f56565b9190910192915050565b918252602082015260400190565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03968716815294861660208601529290941660408401526001600160401b03166060830152911515608082015260a081019190915260c00190565b600060208252610ea26020830184616234565b60006040825261638c6040830185616234565b602083820381850152818551808452828401915082838202850101838801865b838110156163da57601f198784030185526163c88383516162a1565b948601949250908501906001016163ac565b50909998505050505050505050565b6000608082526163fc6080830187616234565b828103602084810191909152865180835287820192820190845b8181101561643257845183529383019391830191600101616416565b505084810360408601526164468188616234565b93505050506001600160401b038316606083015295945050505050565b901515815260200190565b600060208252610ea260208301846162a1565b600060408252616495604083018688616277565b82810360208401526164a8818587616277565b979650505050505050565b6020808252601c908201527f6c656e677468206f66206275726e526174696f206d69736d6174636800000000604082015260600190565b60208082526026908201527f6c656e677468206f66206d61784e756d4f664d61696e7461696e696e67206d696040820152650e6dac2e8c6d60d31b606082015260800190565b6020808252601b908201527f6261746368207472616e736665722072657475726e2066616c73650000000000604082015260600190565b6020808252602c908201527f6c656e677468206f66206d61784e756d4f66576f726b696e6743616e6469646160408201526b0e8cae640dad2e6dac2e8c6d60a31b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61696e7461696e536c6173685363616c65206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252818101527f6c656e677468206f66206e756d4f66436162696e657473206d69736d61746368604082015260600190565b60208082526019908201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526028908201527f746865206e756d4f66436162696e657473206d75737420626520677265617465604082015267072207468616e20360c41b606082015260800190565b60208082526039908201527f746865206e756d4f66436162696e657473206d757374206265206c657373207460408201527f68616e204d41585f4e554d5f4f465f56414c494441544f525300000000000000606082015260800190565b60208082526029908201527f746865206e756d626572206f662076616c696461746f727320657863656564206040820152681d1a19481b1a5b5a5d60ba1b606082015260800190565b60208082526022908201527f63616e206e6f7420646f207468697320747769636520696e206f6e6520626c6f604082015261636b60f01b606082015260800190565b6020808252602b908201527f746865206275726e526174696f206d757374206265206e6f206772656174657260408201526a0207468616e2031303030360ac1b606082015260800190565b6020808252600e908201526d696e70757420746f6f206c6f6e6760901b604082015260600190565b60208082526037908201527f746865206d61784e756d4f664d61696e7461696e696e67206d7573742062652060408201527f6c657373207468616e206e756d4f66436162696e657473000000000000000000606082015260800190565b6020808252602b908201527f6475706c696361746520636f6e73656e7375732061646472657373206f66207660408201526a185b1a59185d1bdc94d95d60aa1b606082015260800190565b60208082526027908201527f7468652065787069726554696d655365636f6e64476170206973206f7574206f604082015266662072616e676560c81b606082015260800190565b6020808252601590820152746465706f7369742076616c7565206973207a65726f60581b604082015260600190565b60208082526049908201527f746865206d61784e756d4f66576f726b696e6743616e64696461746573206d7560408201527f7374206265206e6f742067726561746572207468616e206d61784e756d4f6643606082015268616e6469646174657360b81b608082015260a00190565b60208082526027908201527f7468652066696e616c697479526577617264526174696f206973206f7574206f604082015266662072616e676560c81b606082015260800190565b6020808252601190820152706164646974696f6e206f766572666c6f7760781b604082015260600190565b60208082526023908201527f63616e206e6f7420656e7465722054656d706f72617279204d61696e74656e616040820152626e636560e81b606082015260800190565b60208082526025908201527f6c656e677468206f66206a61696c2076616c696461746f7273206d757374206260408201526465206f6e6560d81b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252602e908201527f746865206d6573736167652073656e646572206d75737420626520676f76657260408201526d1b985b98d94818dbdb9d1c9858dd60921b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61784e756d4f6643616e64696461746573206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252601290820152716e6f7420696e206d61696e74656e616e636560701b604082015260600190565b60208082526021908201527f666565206973206c6172676572207468616e2044555354595f494e434f4d494e6040820152604760f81b606082015260800190565b60208082526019908201527f74686520636f6e747261637420616c726561647920696e697400000000000000604082015260600190565b60208082526026908201527f6c656e677468206f662066696e616c697479526577617264526174696f206d696040820152650e6dac2e8c6d60d31b606082015260800190565b6020808252601a908201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604082015260600190565b60208082526026908201527f6c656e677468206f662065787069726554696d655365636f6e64476170206d696040820152650e6dac2e8c6d60d31b606082015260800190565b60208082526017908201527f6f6e6c792063757272656e742076616c696461746f7273000000000000000000604082015260600190565b60208082526021908201527f6661696c656420746f20706172736520696e69742076616c696461746f7253656040820152601d60fa1b606082015260800190565b6020808252602f908201527f746865206d6573736167652073656e646572206d7573742062652063726f737360408201526e0818da185a5b8818dbdb9d1c9858dd608a1b606082015260800190565b6020808252602d908201527f746865206d6573736167652073656e646572206d75737420626520746865206260408201526c3637b1b590383937b23ab1b2b960991b606082015260800190565b6020808252603e908201527f746865206d61696e7461696e536c6173685363616c65206d757374206265206760408201527f726561746572207468616e203020616e64206c657373207468616e2031300000606082015260800190565b6020808252600d908201526c756e6b6e6f776e20706172616d60981b604082015260600190565b60208082526029908201527f746865206d6573736167652073656e646572206d75737420626520736c6173686040820152680818dbdb9d1c9858dd60ba1b606082015260800190565b61ffff91909116815260200190565b90815260200190565b6000848252831515602083015260606040830152615c3260608301846162a1565b63ffffffff91909116815260200190565b60ff91909116815260200190565b600060ff8516825260406020830152615c32604083018486616277565b60005b83811015616f71578181015183820152602001616f59565b83811115612c47575050600091015256fef901a880f901a4f844941284214b9b9c85549ab3d2b972df0deef66ac2c9946ddf42a51534fc98d0c0a3b42c963cace8441ddf946ddf42a51534fc98d0c0a3b42c963cace8441ddf8410000000f84494a2959d3f95eae5dc7d70144ce1b73b403b7eb6e0948081ef03f1d9e0bb4a5bf38f16285c879299f07f948081ef03f1d9e0bb4a5bf38f16285c879299f07f8410000000f8449435552c16704d214347f29fa77f77da6d75d7c75294dc4973e838e3949c77aced16ac2315dc2d7ab11194dc4973e838e3949c77aced16ac2315dc2d7ab1118410000000f84494980a75ecd1309ea12fa2ed87a8744fbfc9b863d594cc6ac05c95a99c1f7b5f88de0e3486c82293b27094cc6ac05c95a99c1f7b5f88de0e3486c82293b2708410000000f84494f474cf03cceff28abc65c9cbae594f725c80e12d94e61a183325a18a173319dd8e19c8d069459e217594e61a183325a18a173319dd8e19c8d069459e21758410000000f84494b71b214cb885500844365e95cd9942c7276e7fd894d22ca3ba2141d23adab65ce4940eb7665ea2b6a794d22ca3ba2141d23adab65ce4940eb7665ea2b6a7841000000070e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb20175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db90175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbb0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbaa2646970667358221220df3b2f2afc524f6a9eb81529e8bd736333e37b7197419580d4e42bd858b6b14264736f6c63430006040033", + }, + { + ContractAddr: SlashContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "608060405234801561001057600080fd5b506004361061027f5760003560e01c80637942fd051161015c578063c80d4b8f116100ce578063dc927faf11610087578063dc927faf146104ad578063e1c7392a146104b5578063f9a2bbc7146104bd578063fc3e5908146104c5578063fc4333cd146104cd578063fd6a6879146104d55761027f565b8063c80d4b8f1461045c578063c81b166214610464578063c8509d811461046c578063c96be4cb1461047f578063cc844b7314610492578063d2a42e4b146104a55761027f565b80639dc09262116101205780639dc0926214610421578063a1a11bf514610429578063a78abc1614610431578063ab51bb9614610439578063ac0af62914610441578063ac431751146104495761027f565b80637942fd05146103ee5780638256ace6146103f6578063831d65d1146103fe57806396713da9146104115780639bc8e4f2146104195761027f565b8063493279b1116101f557806362b72cf5116101b957806362b72cf5146103be5780636e47b482146103c657806370fd5bad146103ce578063718a8aa8146103d657806375d47a0a146103de5780637912a65d146103e65761027f565b8063493279b11461037c5780634bf6c8821461039157806351e8067214610399578063567a372d146103a15780635bfb4990146103a95761027f565b806335aa2e441161024757806335aa2e441461030e57806337c8dab914610321578063389f4f71146103425780633a63f4b1146103575780633dffc3871461035f57806343756e5c146103745761027f565b80630bee7a67146102845780630e2374a5146102a25780631182b875146102b757806322d1e80b146102d757806323bac5a2146102ec575b600080fd5b61028c6104dd565b60405161029991906132a4565b60405180910390f35b6102aa6104e2565b6040516102999190612b82565b6102ca6102c5366004612ab8565b6104e8565b6040516102999190612bba565b6102df61054e565b6040516102999190612baf565b6102ff6102fa366004612866565b610557565b6040516102999392919061328c565b6102aa61031c366004612a88565b61057a565b61033461032f366004612866565b6105a1565b60405161029992919061327e565b61034a6105f8565b6040516102999190613254565b61034a6105fe565b610367610604565b60405161029991906132b5565b6102aa610609565b61038461060f565b6040516102999190613245565b610367610614565b6102aa610619565b61034a61061f565b6103bc6103b7366004612866565b610625565b005b61034a6106d0565b6102aa6106d6565b6103676106dc565b6103676106e1565b6102aa6106e6565b61034a6106ec565b6103676106f1565b6103346106f6565b6103bc61040c366004612ab8565b610700565b610367610812565b61034a610817565b6102aa610822565b6102aa610828565b6102df61082e565b61028c610837565b61034a61083c565b6103bc61045736600461296c565b610841565b61034a610ce0565b6102aa610ce5565b6103bc61047a366004612ab8565b610ceb565b6103bc61048d366004612866565b610d5c565b6103bc6104a03660046129d5565b61114d565b61034a61169a565b6102aa61169f565b6103bc6116a5565b6102aa6116e1565b6103676116e7565b6103bc6116ec565b6102aa611b35565b606481565b61200181565b606033612000146105145760405162461bcd60e51b815260040161050b906130cb565b60405180910390fd5b60005460ff166105365760405162461bcd60e51b815260040161050b90612c9b565b60405162461bcd60e51b815260040161050b9061318e565b60075460ff1681565b600260208190526000918252604090912080546001820154919092015460ff1683565b6001818154811061058757fe5b6000918252602090912001546001600160a01b0316905081565b6000806105ac61264d565b5050506001600160a01b0316600090815260026020818152604092839020835160608101855281548082526001830154938201849052919093015460ff16151592909301919091529091565b60055481565b60065481565b600181565b61100181565b606181565b600881565b61200081565b60045481565b33611000146106465760405162461bcd60e51b815260040161050b90612edf565b60005460ff166106685760405162461bcd60e51b815260040161050b90612c9b565b61200063f7a251d7600b61067b84611b3b565b60006040518463ffffffff1660e01b815260040161069b939291906132c3565b600060405180830381600087803b1580156106b557600080fd5b505af11580156106c9573d6000803e3d6000fd5b5050505050565b60035481565b61100581565b600281565b601081565b61100881565b603281565b600b81565b6004546005549091565b33612000146107215760405162461bcd60e51b815260040161050b906130cb565b60005460ff166107435760405162461bcd60e51b815260040161050b90612c9b565b61074b612670565b600061078c84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c0d92505050565b9150915080156107d35781516040517f7f0956d47419b9525356e7111652b653b530ec6f5096dccc04589bc38e629967916107c6916132a4565b60405180910390a16106c9565b81516040517f7d45f62d17443dd4547bca8a8112c60e2385669318dc300ec61a5d2492f262e791610803916132a4565b60405180910390a15050505050565b600981565b662386f26fc1000081565b61100781565b61100681565b60005460ff1681565b600081565b600481565b60005460ff166108635760405162461bcd60e51b815260040161050b90612c9b565b33611007146108845760405162461bcd60e51b815260040161050b90612f88565b6108ef84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260148152731b5a5cd9195b59585b9bdc951a1c995cda1bdb1960621b60208201529150611c8d9050565b1561098a57602081146109145760405162461bcd60e51b815260040161050b90612e6b565b604080516020601f840181900481028201810190925282815260009161095291858580838501838280828437600092019190915250611ce792505050565b905060018110158015610966575060055481105b6109825760405162461bcd60e51b815260040161050b90613086565b600455610c9d565b6109f084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e19995b1bdb9e551a1c995cda1bdb19608a1b60208201529150611c8d9050565b15610a8c5760208114610a155760405162461bcd60e51b815260040161050b90612fd6565b604080516020601f8401819004810282018101909252828152600091610a5391858580838501838280828437600092019190915250611ce792505050565b90506103e88111158015610a68575060045481115b610a845760405162461bcd60e51b815260040161050b90612d09565b600555610c9d565b610b0084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601881527f66696e616c697479536c617368526577617264526174696f000000000000000060208201529150611c8d9050565b15610b9a5760208114610b255760405162461bcd60e51b815260040161050b906131c5565b604080516020601f8401819004810282018101909252828152600091610b6391858580838501838280828437600092019190915250611ce792505050565b9050600a8110158015610b765750606481105b610b925760405162461bcd60e51b815260040161050b90612e1f565b600655610c9d565b610c0e84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601881527f656e61626c654d616c6963696f7573566f7465536c617368000000000000000060208201529150611c8d9050565b15610c855760208114610c335760405162461bcd60e51b815260040161050b90612d3e565b604080516020601f8401819004810282018101909252828152610c6f9190848480838501838280828437600092019190915250611cec92505050565b6007805460ff1916911515919091179055610c9d565b60405162461bcd60e51b815260040161050b90613167565b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a84848484604051610cd29493929190612bcd565b60405180910390a150505050565b609681565b61100281565b3361200014610d0c5760405162461bcd60e51b815260040161050b906130cb565b60005460ff16610d2e5760405162461bcd60e51b815260040161050b90612c9b565b6040517f07db600eebe2ac176be8dcebad61858c245a4961bb32ca2aa3d159b09aa0810e90600090a1505050565b334114610d7b5760405162461bcd60e51b815260040161050b9061311a565b60005460ff16610d9d5760405162461bcd60e51b815260040161050b90612c9b565b6003544311610dbe5760405162461bcd60e51b815260040161050b90613210565b3a15610ddc5760405162461bcd60e51b815260040161050b90612f5a565b60405163155853f360e21b8152611000906355614fcc90610e01908490600401612b82565b60206040518083038186803b158015610e1957600080fd5b505afa158015610e2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e51919061294c565b610e5a57611146565b610e6261264d565b506001600160a01b0381166000908152600260208181526040928390208351606081018552815481526001820154928101929092529091015460ff161580159282019290925290610ebd576020810180516001019052610f16565b60016040820181905260208201819052805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0384161790555b438152600554602082015181610f2857fe5b0661107457600060208201526040516335409f7f60e01b8152611000906335409f7f90610f59908590600401612b82565b600060405180830381600087803b158015610f7357600080fd5b505af1158015610f87573d6000803e3d6000fd5b505050506120006001600160a01b031663f7a251d7600b610fa785611b3b565b60006040518463ffffffff1660e01b8152600401610fc7939291906132c3565b600060405180830381600087803b158015610fe157600080fd5b505af1925050508015610ff2575060015b61106f573d808015611020576040519150601f19603f3d011682016040523d82523d6000602084013e611025565b606091505b50826001600160a01b03167fd7bc86ff5d08c8ab043edec743302aba2520e6635172a428bc956721db9e2d1c83602001518360405161106592919061325d565b60405180910390a2505b6110e0565b60045481602001518161108357fe5b066110e0576040516375abf10160e11b81526110009063eb57e202906110ad908590600401612b82565b600060405180830381600087803b1580156110c757600080fd5b505af11580156110db573d6000803e3d6000fd5b505050505b6001600160a01b0382166000818152600260208181526040808420865181559186015160018301558581015191909201805460ff1916911515919091179055517fddb6012116e51abf5436d956a4f0ebd927e92c576ff96d7918290c8782291e3e9190a2505b5043600355565b60005460ff1661116f5760405162461bcd60e51b815260040161050b90612c9b565b604051630a83aaa960e31b81526110069063541d554890611194903390600401612b82565b60206040518083038186803b1580156111ac57600080fd5b505afa1580156111c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e4919061294c565b6112005760405162461bcd60e51b815260040161050b90612bff565b60075460ff166112225760405162461bcd60e51b815260040161050b90612c66565b60065461122f5760146006555b8051514361010090910111801561125157504381602001516000015161010001115b61126d5760405162461bcd60e51b815260040161050b90612c36565b80602001516020015181600001516020015114801561129b5750806020015160600151816000015160600151145b156112b85760405162461bcd60e51b815260040161050b90612eb2565b8051604081015190511080156112d75750602081015160408101519051105b6112f35760405162461bcd60e51b815260040161050b90612de8565b6020810151518151511080156113185750806000015160400151816020015160400151105b8061134357508051516020820151511080156113435750806020015160400151816000015160400151105b8061135d5750806020015160400151816000015160400151145b6113795760405162461bcd60e51b815260040161050b90612cd2565b61138b81600001518260400151611d14565b80156113a457506113a481602001518260400151611d14565b6113c05760405162461bcd60e51b815260040161050b90612d89565b6060806110006001600160a01b0316633b071dcc6040518163ffffffff1660e01b815260040160006040518083038186803b1580156113fe57600080fd5b505afa158015611412573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261143a9190810190612889565b9150915060005b81518110156115775761146b82828151811061145957fe5b60200260200101518560400151611eec565b1561156f576006546040516309a99b4f60e41b815260646110028031909302049190639a99b4f0906114a39033908590600401612b96565b602060405180830381600087803b1580156114bd57600080fd5b505af11580156114d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f59190612aa0565b506110006001600160a01b03166335409f7f85848151811061151357fe5b60200260200101516040518263ffffffff1660e01b81526004016115379190612b82565b600060405180830381600087803b15801561155157600080fd5b505af1158015611565573d6000803e3d6000fd5b5050505050611577565b600101611441565b50600061158984604001516000611f50565b90506120006001600160a01b031663f7a251d7600b6115ab8760400151611f6c565b60006040518463ffffffff1660e01b81526004016115cb939291906132c3565b600060405180830381600087803b1580156115e557600080fd5b505af19250505080156115f6575060015b611668573d808015611624576040519150601f19603f3d011682016040523d82523d6000602084013e611629565b606091505b50817fd58d1183100bd0932c0588f31c4205d6bc6168909765a96c41adbed3115f36288260405161165a9190612bba565b60405180910390a250611694565b60405181907f7b78aadacff901d8b63d0dba4f86283d4db8aef27f9ed70413dd860f1c9532b690600090a25b50505050565b601481565b61100381565b60005460ff16156116c85760405162461bcd60e51b815260040161050b90613018565b603260045560966005556000805460ff19166001179055565b61100081565b600381565b336110001461170d5760405162461bcd60e51b815260040161050b90612edf565b60005460ff1661172f5760405162461bcd60e51b815260040161050b90612c9b565b60015461173b57611b33565b600154600090600019015b808211611b07576000805b8284101561186a5761176161264d565b600260006001878154811061177257fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff161515908201526005549091506004900481602001511115611854576004600554816117df57fe5b0481602001510381602001818152505080600260006001888154811061180157fe5b6000918252602080832091909101546001600160a01b0316835282810193909352604091820190208351815591830151600183015591909101516002909101805460ff191691151591909117905561185e565b600192505061186a565b50836001019350611751565b828411611a015761187961264d565b600260006001868154811061188a57fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff161515908201526005549091506004900481602001511115611972576004600554816118f757fe5b0481602001510381602001818152505080600260006001878154811061191957fe5b6000918252602080832091909101546001600160a01b03168352828101939093526040918201902083518155918301516001808401919091559201516002909101805460ff19169115159190911790559150611a019050565b600260006001868154811061198357fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff191690558054806119c757fe5b600082815260209020810160001990810180546001600160a01b0319169055019055836119f45750611a01565b506000199092019161186a565b818015611a0b5750805b15611aea576002600060018681548110611a2157fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff19169055805484908110611a6857fe5b600091825260209091200154600180546001600160a01b039092169186908110611a8e57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506001805480611ac757fe5b600082815260209020810160001990810180546001600160a01b03191690550190555b82611af6575050611b07565b505060019091019060001901611746565b6040517fcfdb3b6ccaeccbdc68be3c59c840e3b3c90f0a7c491f5fff1cf56cfda200dd9c90600090a150505b565b61100481565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081611b56579050509050611b7f836001600160a01b0316611fa7565b81600081518110611b8c57fe5b6020026020010181905250611ba043611fca565b81600181518110611bad57fe5b6020908102919091010152611bc26061611fca565b81600281518110611bcf57fe5b6020026020010181905250611be342611fca565b81600381518110611bf057fe5b6020026020010181905250611c0481611fdd565b9150505b919050565b611c15612670565b6000611c1f612670565b611c27612682565b611c38611c3386612067565b61208c565b90506000805b611c47836120d6565b15611c805780611c7357611c62611c5d846120f7565b612145565b63ffffffff16845260019150611c78565b611c80565b600101611c3e565b5091935090915050915091565b600081604051602001611ca09190612b66565b6040516020818303038152906040528051906020012083604051602001611cc79190612b66565b604051602081830303815290604052805190602001201490505b92915050565b015190565b8082015160009060ff811615611d06576001915081611d0c565b60009150815b505092915050565b60408051600480825260a0820190925260009160609190816020015b6060815260200190600190039081611d30575050604080516020808252818301909252919250606091908082018180368337019050509050611d758560000151611fca565b82600081518110611d8257fe5b6020026020010181905250611d9d60208660200151836121c7565b611da6816121d7565b82600181518110611db357fe5b6020026020010181905250611dcb8560400151611fca565b82600281518110611dd857fe5b6020026020010181905250611df360208660600151836121c7565b611dfc816121d7565b82600381518110611e0957fe5b6020026020010181905250611e2f6020611e2284611fdd565b80519060200120836121c7565b6040805160b080825260e08201909252606091602082018180368337019050509050611e5f81836000602061222d565b611e718187608001516020606061222d565b611e7f81866080603061222d565b604080516001808252818301909252606091602082018180368337019050509050815160016020830182602086016066600019fa611ebc57600080fd5b506001611eca826000612280565b60ff1614611edf576000945050505050611ce1565b5060019695505050505050565b815181516000916001918114808314611f085760009250611f46565b600160208701838101602088015b600284838510011415611f41578051835114611f355760009650600093505b60209283019201611f16565b505050505b5090949350505050565b60008160200183511015611f6357600080fd5b50016020015190565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081611f87579050509050611b7f836121d7565b60408051600560a21b8318601482015260348101909152606090611c04816121d7565b6060611ce1611fd88361229c565b6121d7565b6060815160001415611ffe5750604080516000815260208101909152611c08565b60608260008151811061200d57fe5b602002602001015190506000600190505b835181101561204e576120448285838151811061203757fe5b6020026020010151612382565b915060010161201e565b50611c04612061825160c060ff166123ff565b82612382565b61206f6126a2565b506040805180820190915281518152602082810190820152919050565b612094612682565b61209d826124d1565b6120a657600080fd5b60006120b5836020015161250b565b60208085015160408051808201909152868152920190820152915050919050565b60006120e06126a2565b505080518051602091820151919092015191011190565b6120ff6126a2565b612108826120d6565b61211157600080fd5b602082015160006121218261256e565b80830160209586015260408051808201909152908152938401919091525090919050565b80516000901580159061215a57508151602110155b61216357600080fd5b6000612172836020015161250b565b905080836000015110156121985760405162461bcd60e51b815260040161050b9061304f565b8251602080850151830180519284900392918310156121be57826020036101000a820491505b50949350505050565b9091018181526020918201910152565b6060815160011480156122095750607f60f81b826000815181106121f757fe5b01602001516001600160f81b03191611155b15612215575080611c08565b611ce16122278351608060ff166123ff565b83612382565b60005b818110156106c95783818151811061224457fe5b602001015160f81c60f81b85848060010195508151811061226157fe5b60200101906001600160f81b031916908160001a905350600101612230565b6000816001018351101561229357600080fd5b50016001015190565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166122e057506018612304565b6fffffffffffffffffffffffffffffffff19841661230057506010612304565b5060005b602081101561233a5781818151811061231957fe5b01602001516001600160f81b031916156123325761233a565b600101612304565b60008160200390506060816040519080825280601f01601f19166020018201604052801561236f576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b818310156123b357805183526020928301920161239b565b50855184518101855292509050808201602086015b818310156123e05780518352602092830192016123c8565b508651929092011591909101601f01601f191660405250905092915050565b60606801000000000000000083106124295760405162461bcd60e51b815260040161050b90612dc0565b604080516001808252818301909252606091602082018180368337019050509050603784116124835782840160f81b8160008151811061246557fe5b60200101906001600160f81b031916908160001a9053509050611ce1565b606061248e8561229c565b90508381510160370160f81b826000815181106124a757fe5b60200101906001600160f81b031916908160001a9053506124c88282612382565b95945050505050565b80516000906124e257506000611c08565b6020820151805160001a9060c082101561250157600092505050611c08565b5060019392505050565b8051600090811a6080811015612525576000915050611c08565b60b8811080612540575060c08110801590612540575060f881105b1561254f576001915050611c08565b60c08110156125635760b519019050611c08565b60f519019050611c08565b80516000908190811a60808110156125895760019150612646565b60b881101561259e57607e1981019150612646565b60c08110156125ef57600060b78203600186019550806020036101000a8651049150600181018201935050808310156125e95760405162461bcd60e51b815260040161050b90612f2f565b50612646565b60f88110156126045760be1981019150612646565b600060f78203600186019550806020036101000a865104915060018101820193505080831015611d0c5760405162461bcd60e51b815260040161050b90612f2f565b5092915050565b604051806060016040528060008152602001600081526020016000151581525090565b60408051602081019091526000815290565b60405180604001604052806126956126a2565b8152602001600081525090565b604051806040016040528060008152602001600081525090565b600082601f8301126126cc578081fd5b81516126df6126da82613316565b6132ef565b818152915060208083019084810160005b84811015612755578151870188603f82011261270b57600080fd5b8381015161271b6126da82613336565b81815260408b8184860101111561273157600080fd5b6127408388840183870161335a565b508652505092820192908201906001016126f0565b505050505092915050565b60008083601f840112612771578182fd5b50813567ffffffffffffffff811115612788578182fd5b6020830191508360208285010111156127a057600080fd5b9250929050565b600082601f8301126127b7578081fd5b81356127c56126da82613336565b91508082528360208285010111156127dc57600080fd5b8060208401602084013760009082016020015292915050565b600060a08284031215612806578081fd5b61281060a06132ef565b905081358152602082013560208201526040820135604082015260608201356060820152608082013567ffffffffffffffff81111561284e57600080fd5b61285a848285016127a7565b60808301525092915050565b600060208284031215612877578081fd5b813561288281613386565b9392505050565b6000806040838503121561289b578081fd5b825167ffffffffffffffff808211156128b2578283fd5b81850186601f8201126128c3578384fd5b805192506128d36126da84613316565b80848252602080830192508084018a8283890287010111156128f3578788fd5b8794505b8685101561291e57805161290a81613386565b8452600194909401939281019281016128f7565b508801519096509350505080821115612935578283fd5b50612942858286016126bc565b9150509250929050565b60006020828403121561295d578081fd5b81518015158114612882578182fd5b60008060008060408587031215612981578182fd5b843567ffffffffffffffff80821115612998578384fd5b6129a488838901612760565b909650945060208701359150808211156129bc578384fd5b506129c987828801612760565b95989497509550505050565b6000602082840312156129e6578081fd5b813567ffffffffffffffff808211156129fd578283fd5b81840160608187031215612a0f578384fd5b612a1960606132ef565b9250803582811115612a29578485fd5b612a35878284016127f5565b845250602081013582811115612a49578485fd5b612a55878284016127f5565b602085015250604081013582811115612a6c578485fd5b612a78878284016127a7565b6040850152509195945050505050565b600060208284031215612a99578081fd5b5035919050565b600060208284031215612ab1578081fd5b5051919050565b600080600060408486031215612acc578283fd5b833560ff81168114612adc578384fd5b9250602084013567ffffffffffffffff811115612af7578283fd5b612b0386828701612760565b9497909650939450505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452612b5281602086016020860161335a565b601f01601f19169290920160200192915050565b60008251612b7881846020870161335a565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b6000602082526128826020830184612b3a565b600060408252612be1604083018688612b10565b8281036020840152612bf4818587612b10565b979650505050505050565b6020808252601f908201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604082015260600190565b6020808252601690820152751d1bdbc81bdb1908189b1bd8dac81a5b9d9bdb1d995960521b604082015260600190565b6020808252818101527f6d616c6963696f757320766f746520736c617368206e6f7420656e61626c6564604082015260600190565b60208082526019908201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604082015260600190565b6020808252601a908201527f6e6f2076696f6c6174696f6e206f6620766f74652072756c6573000000000000604082015260600190565b6020808252818101527f7468652066656c6f6e795468726573686f6c64206f7574206f662072616e6765604082015260600190565b6020808252602b908201527f6c656e677468206f6620656e61626c654d616c6963696f7573566f7465536c6160408201526a0e6d040dad2e6dac2e8c6d60ab1b606082015260800190565b60208082526017908201527f766572696679207369676e6174757265206661696c6564000000000000000000604082015260600190565b6020808252600e908201526d696e70757420746f6f206c6f6e6760901b604082015260600190565b60208082526019908201527f7372634e756d20626967676572207468616e207461724e756d00000000000000604082015260600190565b6020808252602c908201527f7468652066696e616c69747920736c6173682072657761726420726174696f2060408201526b6f7574206f662072616e676560a01b606082015260800190565b60208082526027908201527f6c656e677468206f66206d697364656d65616e6f725468726573686f6c64206d6040820152660d2e6dac2e8c6d60cb1b606082015260800190565b60208082526013908201527274776f206964656e746963616c20766f74657360681b604082015260600190565b60208082526030908201527f746865206d6573736167652073656e646572206d7573742062652076616c696460408201526f185d1bdc94d95d0818dbdb9d1c9858dd60821b606082015260800190565b6020808252601190820152706164646974696f6e206f766572666c6f7760781b604082015260600190565b6020808252601490820152736761737072696365206973206e6f74207a65726f60601b604082015260600190565b6020808252602e908201527f746865206d6573736167652073656e646572206d75737420626520676f76657260408201526d1b985b98d94818dbdb9d1c9858dd60921b606082015260800190565b60208082526022908201527f6c656e677468206f662066656c6f6e795468726573686f6c64206d69736d61746040820152610c6d60f31b606082015260800190565b60208082526019908201527f74686520636f6e747261637420616c726561647920696e697400000000000000604082015260600190565b6020808252601a908201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604082015260600190565b60208082526025908201527f746865206d697364656d65616e6f725468726573686f6c64206f7574206f662060408201526472616e676560d81b606082015260800190565b6020808252602f908201527f746865206d6573736167652073656e646572206d7573742062652063726f737360408201526e0818da185a5b8818dbdb9d1c9858dd608a1b606082015260800190565b6020808252602d908201527f746865206d6573736167652073656e646572206d75737420626520746865206260408201526c3637b1b590383937b23ab1b2b960991b606082015260800190565b6020808252600d908201526c756e6b6e6f776e20706172616d60981b604082015260600190565b6020808252601e908201527f7265636569766520756e65787065637465642073796e207061636b6167650000604082015260600190565b6020808252602b908201527f6c656e677468206f662066696e616c697479536c61736852657761726452617460408201526a0d2de40dad2e6dac2e8c6d60ab1b606082015260800190565b6020808252818101527f63616e206e6f7420736c61736820747769636520696e206f6e6520626c6f636b604082015260600190565b61ffff91909116815260200190565b90815260200190565b6000838252604060208301526132766040830184612b3a565b949350505050565b918252602082015260400190565b92835260208301919091521515604082015260600190565b63ffffffff91909116815260200190565b60ff91909116815260200190565b600060ff85168252606060208301526132df6060830185612b3a565b9050826040830152949350505050565b60405181810167ffffffffffffffff8111828210171561330e57600080fd5b604052919050565b600067ffffffffffffffff82111561332c578081fd5b5060209081020190565b600067ffffffffffffffff82111561334c578081fd5b50601f01601f191660200190565b60005b8381101561337557818101518382015260200161335d565b838111156116945750506000910152565b6001600160a01b038116811461339b57600080fd5b5056fea2646970667358221220f826c2f80c6807c5df53c6cfe5be2e59ad7e87dad138f63f83dd1caf79118d6064736f6c63430006040033", + }, + { + ContractAddr: SystemRewardContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "6080604052600436106101a05760003560e01c80637942fd05116100ec578063ac4317511161008a578063f9a2bbc711610064578063f9a2bbc714610550578063fb5478b314610565578063fc3e59081461057a578063fd6a68791461058f576101e4565b8063ac43175114610457578063c81b166214610526578063dc927faf1461053b576101e4565b80639dc09262116100c65780639dc0926214610403578063a1a11bf514610418578063a78abc161461042d578063ab51bb9614610442576101e4565b80637942fd05146103a057806396713da9146103b55780639a99b4f0146103ca576101e4565b80634bf6c882116101595780636e47b482116101335780636e47b4821461034c57806370fd5bad14610361578063718a8aa81461037657806375d47a0a1461038b576101e4565b80634bf6c882146102db57806351e80672146102f05780636d70f7ae14610305576101e4565b80630bee7a67146101e95780630e2374a5146102175780633a0b0eff146102485780633dffc3871461026f57806343756e5c1461029a578063493279b1146102af576101e4565b366101e45734156101e25760408051348152905133917f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db919081900360200190a25b005b600080fd5b3480156101f557600080fd5b506101fe6105a4565b6040805163ffffffff9092168252519081900360200190f35b34801561022357600080fd5b5061022c6105a9565b604080516001600160a01b039092168252519081900360200190f35b34801561025457600080fd5b5061025d6105af565b60408051918252519081900360200190f35b34801561027b57600080fd5b506102846105b5565b6040805160ff9092168252519081900360200190f35b3480156102a657600080fd5b5061022c6105ba565b3480156102bb57600080fd5b506102c46105c0565b6040805161ffff9092168252519081900360200190f35b3480156102e757600080fd5b506102846105c5565b3480156102fc57600080fd5b5061022c6105ca565b34801561031157600080fd5b506103386004803603602081101561032857600080fd5b50356001600160a01b03166105d0565b604080519115158252519081900360200190f35b34801561035857600080fd5b5061022c6105ee565b34801561036d57600080fd5b506102846105f4565b34801561038257600080fd5b506102846105f9565b34801561039757600080fd5b5061022c6105fe565b3480156103ac57600080fd5b50610284610604565b3480156103c157600080fd5b50610284610609565b3480156103d657600080fd5b5061025d600480360360408110156103ed57600080fd5b506001600160a01b03813516906020013561060e565b34801561040f57600080fd5b5061022c6107b9565b34801561042457600080fd5b5061022c6107bf565b34801561043957600080fd5b506103386107c5565b34801561044e57600080fd5b506101fe6107ce565b34801561046357600080fd5b506101e26004803603604081101561047a57600080fd5b81019060208101813564010000000081111561049557600080fd5b8201836020820111156104a757600080fd5b803590602001918460018302840111640100000000831117156104c957600080fd5b9193909290916020810190356401000000008111156104e757600080fd5b8201836020820111156104f957600080fd5b8035906020019184600183028401116401000000008311171561051b57600080fd5b5090925090506107d3565b34801561053257600080fd5b5061022c610b56565b34801561054757600080fd5b5061022c610b5c565b34801561055c57600080fd5b5061022c610b62565b34801561057157600080fd5b5061025d610b68565b34801561058657600080fd5b50610284610b74565b34801561059b57600080fd5b5061022c610b79565b606481565b61200181565b60015481565b600181565b61100181565b606181565b600881565b61200081565b6001600160a01b031660009081526002602052604090205460ff1690565b61100581565b600281565b601081565b61100881565b600b81565b600981565b6000805460ff1661068b57600260208190527fe57bda0a954a7c7381b17b2c763e646ba2c60f67292d287ba583603e2c1c41668054600160ff19918216811790925561100560009081527fe25235fc0de9d7165652bef0846fefda506174abb9a190f03d0f7bcc6146dbce80548316841790559282558254161790555b3360009081526002602052604090205460ff166106d95760405162461bcd60e51b815260040180806020018281038252602b815260200180610c67602b913960400191505060405180910390fd5b60004783106106e857476106ea565b825b9050670de0b6b3a76400008111156107075750670de0b6b3a76400005b8015610788576040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015610743573d6000803e3d6000fd5b506040805182815290516001600160a01b038616917ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0919081900360200190a26107b2565b6040517fe589651933c2457488cc0d8e0941518abf748e799435e4e396d9c4d0b2db2d4d90600090a15b9392505050565b61100781565b61100681565b60005460ff1681565b600081565b33611007146108135760405162461bcd60e51b815260040180806020018281038252602e815260200180610cc1602e913960400191505060405180910390fd5b61087584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600b81526a30b23227b832b930ba37b960a91b60208201529150610b7f9050565b1561094d57606082828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050825192935050601490911490506108f85760405162461bcd60e51b815260040180806020018281038252602c815260200180610cef602c913960400191505060405180910390fd5b60148101516001600160a01b038116600081815260026020526040808220805460ff19166001179055517f9870d7fe5d112134c55844951dedf365363006d9c588db07c4c85af6322a06199190a25050610ac4565b6109b284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600e81526d3232b632ba32a7b832b930ba37b960911b60208201529150610b7f9050565b15610a8757606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060149091149050610a355760405162461bcd60e51b815260040180806020018281038252602f815260200180610c92602f913960400191505060405180910390fd5b60148101516001600160a01b038116600081815260026020526040808220805460ff19169055517fb40992a19dba61ea600e87fce607102bf5908dc89076217b6ca6ae195224f7029190a25050610ac4565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b61100081565b670de0b6b3a764000081565b600381565b61100481565b6000816040516020018082805190602001908083835b60208310610bb45780518252601f199092019160209182019101610b95565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310610c225780518252601f199092019160209182019101610c03565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490509291505056fe6f6e6c79206f70657261746f7220697320616c6c6f77656420746f2063616c6c20746865206d6574686f646c656e677468206f662076616c756520666f722064656c6574654f70657261746f722073686f756c64206265203230746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f72206164644f70657261746f722073686f756c64206265203230a26469706673582212205c998ac20925f17d8af20803f32be2cf1698c9a844de45001ca5ed8c879cc93f64736f6c63430006040033", + }, + { + ContractAddr: RelayerHubContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "608060405234801561001057600080fd5b50600436106102275760003560e01c80638f83ab1311610130578063c81b1662116100b8578063f3ae24151161007c578063f3ae2415146104e8578063f9a2bbc71461050e578063fc3e590814610516578063fd30d9b81461051e578063fd6a68791461052657610227565b8063c81b1662146104c0578063dc927faf146104c8578063dd91d1c5146104d0578063e1c7392a146104d8578063e79a198f146104e057610227565b8063a1a11bf5116100ff578063a1a11bf5146103de578063a74b83ca146103e6578063a78abc16146103ee578063ab51bb96146103f6578063ac431751146103fe57610227565b80638f83ab13146103a057806395468d26146103c657806396713da9146103ce5780639dc09262146103d657610227565b8063541d5548116101b3578063718a8aa811610182578063718a8aa81461034857806375d47a0a1461035057806378beee67146103585780637942fd051461037e5780637ae230881461038657610227565b8063541d5548146102d85780636a6a419e146103125780636e47b4821461033857806370fd5bad1461034057610227565b80633dffc387116101fa5780633dffc3871461028357806343756e5c146102a1578063493279b1146102a95780634bf6c882146102c857806351e80672146102d057610227565b806303aff02b1461022c578063049a5716146102365780630bee7a671461025a5780630e2374a51461027b575b600080fd5b61023461052e565b005b61023e610539565b604080516001600160a01b039092168252519081900360200190f35b610262610551565b6040805163ffffffff9092168252519081900360200190f35b61023e610556565b61028b61055c565b6040805160ff9092168252519081900360200190f35b61023e610561565b6102b1610567565b6040805161ffff9092168252519081900360200190f35b61028b61056c565b61023e610571565b6102fe600480360360208110156102ee57600080fd5b50356001600160a01b0316610577565b604080519115158252519081900360200190f35b6102fe6004803603602081101561032857600080fd5b50356001600160a01b0316610595565b61023e6105b3565b61028b6105b9565b61028b6105be565b61023e6105c3565b6102346004803603602081101561036e57600080fd5b50356001600160a01b03166105c9565b61028b6107b1565b61038e6107b6565b60408051918252519081900360200190f35b610234600480360360208110156103b657600080fd5b50356001600160a01b03166107c3565b61038e610a02565b61028b610a0e565b61023e610a13565b61023e610a19565b61023e610a1f565b6102fe610a37565b610262610a40565b6102346004803603604081101561041457600080fd5b81019060208101813564010000000081111561042f57600080fd5b82018360208201111561044157600080fd5b8035906020019184600183028401116401000000008311171561046357600080fd5b91939092909160208101903564010000000081111561048157600080fd5b82018360208201111561049357600080fd5b803590602001918460018302840111640100000000831117156104b557600080fd5b509092509050610a45565b61023e610d96565b61023e610d9c565b610234610da2565b610234610e43565b610234610ec5565b6102fe600480360360208110156104fe57600080fd5b50356001600160a01b031661107e565b61023e61109c565b61028b6110a2565b6102fe6110a7565b61023e6110b0565b610537336110b6565b565b739fb29aac15b9a4b7f17c3385939b007540f4d79181565b606481565b61200181565b600181565b61100181565b606181565b600881565b61200081565b6001600160a01b031660009081526007602052604090205460ff1690565b6001600160a01b031660009081526008602052604090205460ff1690565b61100581565b600281565b601081565b61100881565b3360009081526008602052604090205460ff166106175760405162461bcd60e51b81526004018080602001828103825260248152602001806115c26024913960400191505060405180910390fd5b61062033611218565b1561065c5760405162461bcd60e51b815260040180806020018281038252602181526020018061157f6021913960400191505060405180910390fd5b3233146106b0576040805162461bcd60e51b815260206004820152601e60248201527f70726f766973696f6e616c2072656c6179657220697320612070726f78790000604482015290519081900360640190fd5b6001600160a01b038181166000908152600960205260409020541633146107085760405162461bcd60e51b815260040180806020018281038252602781526020018061163b6027913960400191505060405180910390fd5b6001600160a01b03818116600081815260066020908152604080832080543380865260078086528487208054600160ff199182161790915584546001600160a01b031990811684179095556008875285882080548216905597875260098652848720805490941690935596168085529083529281902080549094169093558251828152908101939093528151909260008051602061166283398151915292908290030190a15050565b600b81565b68056bc75e2d6310000081565b3360009081526005602052604090205460ff16610820576040805162461bcd60e51b81526020600482015260166024820152751b585b9859d95c88191bd95cc81b9bdd08195e1a5cdd60521b604482015290519081900360640190fd5b61082981611218565b156108655760405162461bcd60e51b81526004018080602001828103825260278152602001806115e66027913960400191505060405180910390fd5b6001600160a01b03811615610921576001600160a01b03811660009081526007602052604090205460ff16156108db576040805162461bcd60e51b815260206004820152601660248201527572656c6179657220616c72656164792065786973747360501b604482015290519081900360640190fd5b6001600160a01b0381166000818152600860209081526040808320805460ff191660011790553383526009909152902080546001600160a01b03191690911790556109c2565b3360008181526006602090815260408083208054600980855283862080546001600160a01b03198085169095556001600160a01b0393841680895260078852868920805460ff19908116909155918516808a5260088952878a20805490931690925598909752908552805490921690915581518581529086169281019290925280516000805160206116628339815191529281900390910190a150506109ff565b604080516001600160a01b038316815290517ffba56633276570c7d3120d4535bf3bce26523da53958e40734210b9fd99b36939181900360200190a15b50565b67016345785d8a000081565b600981565b61100781565b61100681565b7337b8516a0f88e65d677229b402ec6c1e0e33300481565b60005460ff1681565b600081565b60005460ff16610a98576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b3361100714610ad85760405162461bcd60e51b815260040180806020018281038252602e81526020018061160d602e913960400191505060405180910390fd5b610b3984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600a81526930b23226b0b730b3b2b960b11b6020820152915061121e9050565b15610bd15760148114610b7d5760405162461bcd60e51b81526004018080602001828103825260228152602001806115a06022913960400191505060405180910390fd5b6000610bc0601484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061130592505050565b9050610bcb8161130a565b50610d04565b610c3584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c3932b6b7bb32a6b0b730b3b2b960991b6020820152915061121e9050565b15610cc75760148114610c795760405162461bcd60e51b81526004018080602001828103825260228152602001806115a06022913960400191505060405180910390fd5b6000610cbc601484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061130592505050565b9050610bcb816110b6565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b600a5460ff1615610dfa576040805162461bcd60e51b815260206004820152601e60248201527f7468652077686974656c6973747320616c726561647920757064617465640000604482015290519081900360640190fd5b610e17739fb29aac15b9a4b7f17c3385939b007540f4d7916113cc565b610e347337b8516a0f88e65d677229b402ec6c1e0e3330046113cc565b600a805460ff19166001179055565b60005460ff1615610e9b576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b68056bc75e2d63100000600190815567016345785d8a00006002556000805460ff19169091179055565b3360009081526004602052604090205460ff16610f20576040805162461bcd60e51b81526020600482015260146024820152731c995b185e595c88191bc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b60005460ff16610f73576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b610f7b611564565b5033600081815260036020908152604091829020825180840190935280548084526001909101549183018290529192916108fc91610fbf919063ffffffff61148416565b6040518115909202916000818181858888f19350505050158015610fe7573d6000803e3d6000fd5b50602081015160405161100291829181156108fc0291906000818181858888f1935050505015801561101d573d6000803e3d6000fd5b50336000818152600460209081526040808320805460ff191690556003825280832083815560010192909255815192835290517fd17202129b83db7880d6b9f25df81c58ad46f7e0e2c92236b1aa10663a4876679281900390910190a15050565b6001600160a01b031660009081526005602052604090205460ff1690565b61100081565b600381565b600a5460ff1681565b61100481565b6001600160a01b03811660009081526005602052604090205460ff1661111b576040805162461bcd60e51b81526020600482015260156024820152741b585b9859d95c88191bd95cdb89dd08195e1a5cdd605a1b604482015290519081900360640190fd5b6001600160a01b038082166000818152600660209081526040808320805460058452828520805460ff1990811690915582546001600160a01b0319908116909355600980865284872080548a16885260088752858820805490931690925595879052948452845490911690935580519384525191909316927f2002866d443ac6c241fecaaa2af4895828c7de2cc423b9d01f7969650f557c76928290030190a16001600160a01b03811615611214576001600160a01b0381166000818152600760209081526040808320805460ff1916905580519384529083019190915280516000805160206116628339815191529281900390910190a15b5050565b3b151590565b6000816040516020018082805190602001908083835b602083106112535780518252601f199092019160209182019101611234565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106112c15780518252601f1990920191602091820191016112a2565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b6001600160a01b03811660009081526005602052604090205460ff1615611371576040805162461bcd60e51b81526020600482015260166024820152756d616e6167657220616c72656164792065786973747360501b604482015290519081900360640190fd5b6001600160a01b038116600081815260056020908152604091829020805460ff19166001179055815192835290517fe0de8e71a22c046647f4ef744348fa126ad6d052d4ce070999481f69d45575179281900390910190a150565b6001600160a01b03811660008181526005602090815260408083208054600160ff1991821681179092556006845282852080546001600160a01b031916871790556007845293829020805490941617909255815192835290517fe0de8e71a22c046647f4ef744348fa126ad6d052d4ce070999481f69d45575179281900390910190a160408051600081526001600160a01b03831660208201528151600080516020611662833981519152929181900390910190a150565b60006114c683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506114cd565b9392505050565b6000818484111561155c5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611521578181015183820152602001611509565b50505050905090810190601f16801561154e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60405180604001604052806000815260200160008152509056fe70726f766973696f6e616c2072656c61796572206973206120636f6e74726163746c656e677468206f66206d616e616765722061646472657373206d69736d6174636872656c61796572206973206e6f7420612070726f766973696f6e616c2072656c61796572636f6e7472616374206973206e6f7420616c6c6f77656420746f20626520612072656c61796572746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e747261637470726f766973696f6e616c206973206e6f742073657420666f722074686973206d616e61676572a5a19d7e9dab30a215022382d7abe782b579986fcbedec9942ecd0db9510a148a2646970667358221220e87e5b6ca8388e14d2ec9c2453581b5e2346a0aaa8fa61707f4d522357ac45d464736f6c63430006040033", + }, + { + ContractAddr: CrossChainContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "608060405234801561001057600080fd5b50600436106103995760003560e01c8063718a8aa8116101e9578063c27cdcfb1161010f578063dc927faf116100ad578063f7a251d71161007c578063f7a251d714610b2f578063f9a2bbc714610ba7578063fc3e590814610baf578063fd6a687914610bb757610399565b8063dc927faf14610af7578063e1c7392a14610aff578063e3b0480514610b07578063e6400bbe14610b2757610399565b8063ccc108d7116100e9578063ccc108d714610ab0578063d31f968d14610ab8578063d76a867514610ae7578063dc40433114610aef57610399565b8063c27cdcfb14610a80578063c780e9de14610aa0578063c81b166214610aa857610399565b80638cc8f56111610187578063a78abc1611610156578063a78abc16146109b2578063ab51bb96146109ba578063ac431751146109c2578063b0355f5b1461078157610399565b80638cc8f5611461088757806396713da91461099a5780639dc09262146109a2578063a1a11bf5146109aa57610399565b806375d47a0a116101c357806375d47a0a146108a75780637942fd05146108af57806384013b6a146108b7578063863fe4ab1461099257610399565b8063718a8aa81461088f578063719482d51461089757806374f079b81461089f57610399565b8063422f9050116102ce57806363e1394e1161026c5780636de380bd1161023b5780636de380bd146108575780636e47a51a1461085f5780636e47b4821461087f57806370fd5bad1461088757610399565b806363e1394e146107ff5780636a3cb34d146108075780636bacff2c1461080f5780636c46aa681461080757610399565b80634bf6c882116102a85780634bf6c882146107b957806351e80672146107c15780635692ddd3146107c95780635f832177146107d157610399565b8063422f90501461078957806343756e5c146107a9578063493279b1146107b157610399565b8063299b533d1161033b578063308325f411610315578063308325f4146106155780633a648b151461061d5780633bdc47a6146106595780633dffc3871461078157610399565b8063299b533d146105a35780632af6f399146105d75780632ff32aea146105f457610399565b806314b3023b1161037757806314b3023b146104015780631d1309351461041b5780631e275ae11461043757806322556cdc1461059b57610399565b806305e682581461039e5780630bee7a67146103bc5780630e2374a5146103dd575b600080fd5b6103a6610bbf565b6040805160ff9092168252519081900360200190f35b6103c4610bc4565b6040805163ffffffff9092168252519081900360200190f35b6103e5610bc9565b604080516001600160a01b039092168252519081900360200190f35b610409610bcf565b60408051918252519081900360200190f35b610423610bd5565b604080519115158252519081900360200190f35b610599600480360361010081101561044e57600080fd5b81018160a081016080820135600160201b81111561046b57600080fd5b82018360208201111561047d57600080fd5b803590602001918460018302840111600160201b8311171561049e57600080fd5b919390929091602081019035600160201b8111156104bb57600080fd5b8201836020820111156104cd57600080fd5b803590602001918460018302840111600160201b831117156104ee57600080fd5b919390929091602081019035600160201b81111561050b57600080fd5b82018360208201111561051d57600080fd5b803590602001918460018302840111600160201b8311171561053e57600080fd5b919390929091602081019035600160201b81111561055b57600080fd5b82018360208201111561056d57600080fd5b803590602001918460018302840111600160201b8311171561058e57600080fd5b509092509050610bde565b005b6104096112c2565b6105c0600480360360208110156105b957600080fd5b50356112c7565b6040805161ffff9092168252519081900360200190f35b610423600480360360208110156105ed57600080fd5b50356112dd565b6105fc6112f2565b60408051600792830b90920b8252519081900360200190f35b6104096112fb565b61063d6004803603602081101561063357600080fd5b503560ff16611301565b604080516001600160401b039092168252519081900360200190f35b61070c6004803603606081101561066f57600080fd5b60ff82351691602081013591810190606081016040820135600160201b81111561069857600080fd5b8201836020820111156106aa57600080fd5b803590602001918460018302840111600160201b831117156106cb57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061131c945050505050565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561074657818101518382015260200161072e565b50505050905090810190601f1680156107735780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103a6611392565b6104236004803603602081101561079f57600080fd5b503560ff16611397565b6103e56113ac565b6105c06113b2565b6103a66113b7565b6103e56113bc565b6104096113c2565b610599600480360360408110156107e757600080fd5b506001600160a01b03813581169160200135166113f2565b610409611652565b6105c061167a565b61082c6004803603602081101561082557600080fd5b503561167f565b6040805161ffff90941684526001600160801b03909216602084015282820152519081900360600190f35b6104096116ae565b6103e56004803603602081101561087557600080fd5b503560ff166116d5565b6103e56116f0565b6103a661167a565b6103a66116f6565b6105c0611392565b6104096116fb565b6103e5611701565b6103a6611707565b610599600480360360a08110156108cd57600080fd5b810190602081018135600160201b8111156108e757600080fd5b8201836020820111156108f957600080fd5b803590602001918460018302840111600160201b8311171561091a57600080fd5b919390929091602081019035600160201b81111561093757600080fd5b82018360208201111561094957600080fd5b803590602001918460018302840111600160201b8311171561096a57600080fd5b919350915080356001600160401b03908116916020810135909116906040013560ff1661170c565b6104096129c6565b6103a66129ce565b6103e56129d3565b6103e56129d9565b6104236129df565b6103c4610bbf565b610599600480360360408110156109d857600080fd5b810190602081018135600160201b8111156109f257600080fd5b820183602082011115610a0457600080fd5b803590602001918460018302840111600160201b83111715610a2557600080fd5b919390929091602081019035600160201b811115610a4257600080fd5b820183602082011115610a5457600080fd5b803590602001918460018302840111600160201b83111715610a7557600080fd5b5090925090506129e8565b61063d60048036036020811015610a9657600080fd5b503560ff166134ac565b6104096134c7565b6103e56134eb565b6105996134f1565b61042360048036036040811015610ace57600080fd5b5080356001600160a01b0316906020013560ff16613745565b61070c613765565b610409613784565b6103e561378a565b610599613790565b61063d60048036036020811015610b1d57600080fd5b503560ff16613b47565b610599613b62565b61059960048036036060811015610b4557600080fd5b60ff8235169190810190604081016020820135600160201b811115610b6957600080fd5b820183602082011115610b7b57600080fd5b803590602001918460018302840111600160201b83111715610b9c57600080fd5b919350915035613d81565b6103e5613ec4565b6103a6613eca565b6103e5613ecf565b600081565b606481565b61200181565b60015481565b600b5460ff1681565b60005460ff16610c23576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b604080516337d7f9c160e21b81526001600160401b038b35166004820181905291516110039163df5fe704916024808301926020929190829003018186803b158015610c6e57600080fd5b505afa158015610c82573d6000803e3d6000fd5b505050506040513d6020811015610c9857600080fd5b5051610cd55760405162461bcd60e51b81526004018080602001828103825260238152602001806149d26023913960400191505060405180910390fd5b604080516337d7f9c160e21b815260208c8101356001600160401b03166004830181905292516110039263df5fe704926024808301939192829003018186803b158015610d2157600080fd5b505afa158015610d35573d6000803e3d6000fd5b505050506040513d6020811015610d4b57600080fd5b5051610d885760405162461bcd60e51b81526004018080602001828103825260238152602001806149d26023913960400191505060405180910390fd5b60608b013560ff81166000908152600560205260409020546001600160401b03909116906001600160a01b0316610e01576040805162461bcd60e51b815260206004820152601860248201527718da185b9b995b081a5cc81b9bdd081cdd5c1c1bdc9d195960421b604482015290519081900360640190fd5b600b5460ff1615610e45576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b8888604051808383808284376040519201829003822094508f93508e9250819050838380828437808301925050509250505060405180910390201415610ec1576040805162461bcd60e51b815260206004820152600c60248201526b1cd85b59481c185e5b1bd85960a21b604482015290519081900360640190fd5b60606001600160401b0360408e01358116908e83013516610ee28282613ed5565b80516020808301919091206000818152600e9092526040909120549194509060ff1615610f4b576040805162461bcd60e51b8152602060048201526012602482015271185b1c9958591e4818da185b1b195b99d95960721b604482015290519081900360640190fd5b6000908152600e60205260408120805460ff191660011790558f8160200201356001600160401b0316905060608f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040805163cba510a960e01b81526001600160401b038a16600482015290519596509094611003945063cba510a9935060248083019350602092829003018186803b15801561104157600080fd5b505afa158015611055573d6000803e3d6000fd5b505050506040513d602081101561106b57600080fd5b505160408051808201909152600381526269626360e81b6020820152909150611098908290898686613f1d565b6110e1576040805162461bcd60e51b81526020600482015260156024820152740696e76616c6964206d65726b6c652070726f6f663605c1b604482015290519081900360640190fd5b5050505060008f6001600481106110f457fe5b60200201356001600160401b0316905060608d8d8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8f018190048102820181019092528d815293945060609392508d91508c908190840183828082843760009201829052506040805163cba510a960e01b81526001600160401b038a16600482015290519596509094611003945063cba510a9935060248083019350602092829003018186803b1580156111c057600080fd5b505afa1580156111d4573d6000803e3d6000fd5b505050506040513d60208110156111ea57600080fd5b505160408051808201909152600381526269626360e81b6020820152909150611217908290898686613f1d565b611260576040805162461bcd60e51b8152602060048201526015602482015274696e76616c6964206d65726b6c652070726f6f663160581b604482015290519081900360640190fd5b5050505061126c61401a565b604080516001600160401b038416815260ff83166020820152815133927f039eb91179ffd7d3b6e97f8ea106e748e827f910b872375dbc9c14a362319c3c928290030190a2505050505050505050505050505050565b603281565b600d6020526000908152604090205461ffff1681565b600e6020526000908152604090205460ff1681565b60045460070b81565b60025481565b600a602052600090815260409020546001600160401b031681565b60606000825160210190506060816040519080825280601f01601f191660200182016040528015611354576020820181803683370190505b506021810186905260018101879052828152905060418101600061137786614098565b509050611386818388516140a2565b50909695505050505050565b600181565b60096020526000908152604090205460ff1681565b61100181565b606181565b600881565b61200081565b604080517710d05390d15317d514905394d1915497d41493d413d4d05360421b8152905190819003601801902081565b60005460ff16611437576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b15801561147a57600080fd5b505afa15801561148e573d6000803e3d6000fd5b505050506040513d60208110156114a457600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b1580156114e557600080fd5b505afa1580156114f9573d6000803e3d6000fd5b505050506040513d602081101561150f57600080fd5b505190508061151c575060155b60008211801561152c5750808211155b61156b576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b604080516001600160a01b038087166020808401919091529086168284015282518083038401815260608301808552815191909201207710d05390d15317d514905394d1915497d41493d413d4d05360421b90915291519081900360780190206000906115d890836140e3565b9050801561164a5760408051630911a2c160e11b81526001600160a01b03888116600483015287166024820152905161100491631223458291604480830192600092919082900301818387803b15801561163157600080fd5b505af1158015611645573d6000803e3d6000fd5b505050505b505050505050565b604080516f14d554d411539117d41493d413d4d05360821b8152905190819003601001902081565b600281565b600c602052600090815260409020805460019091015461ffff8216916201000090046001600160801b03169083565b604080516e149153d4115397d41493d413d4d053608a1b8152905190819003600f01902081565b6005602052600090815260409020546001600160a01b031681565b61100581565b601081565b60035481565b61100881565b600b81565b60005460ff16611751576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b60408051630a83aaa960e31b815233600482015290516110069163541d5548916024808301926020929190829003018186803b15801561179057600080fd5b505afa1580156117a4573d6000803e3d6000fd5b505050506040513d60208110156117ba57600080fd5b505161180d576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b60ff8116600090815260086020526040902054829082906001600160401b03908116908316811461187d576040805162461bcd60e51b815260206004820152601560248201527439b2b8bab2b731b2903737ba1034b71037b93232b960591b604482015290519081900360640190fd5b60ff8216600090815260086020908152604091829020805467ffffffffffffffff1916600185016001600160401b039081169190911790915582516337d7f9c160e21b81529089166004820152915188926110039263df5fe70492602480840193829003018186803b1580156118f257600080fd5b505afa158015611906573d6000803e3d6000fd5b505050506040513d602081101561191c57600080fd5b50516119595760405162461bcd60e51b81526004018080602001828103825260238152602001806149d26023913960400191505060405180910390fd5b60ff851660009081526005602052604090205485906001600160a01b03166119c3576040805162461bcd60e51b815260206004820152601860248201527718da185b9b995b081a5cc81b9bdd081cdd5c1c1bdc9d195960421b604482015290519081900360640190fd5b60ff86166000908152600a6020526040902054889087906001600160401b039081169083161015611a2c576040805162461bcd60e51b815260206004820152600e60248201526d3a37b79037b632103432b0b232b960911b604482015290519081900360640190fd5b60ff81166000908152600a60205260409020546001600160401b03838116911614611a7e5760ff81166000908152600a60205260409020805467ffffffffffffffff19166001600160401b0384161790555b600b5460ff1615611ac2576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b60608e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509050611c066110036001600160a01b031663cba510a98e6040518263ffffffff1660e01b815260040180826001600160401b03166001600160401b0316815260200191505060206040518083038186803b158015611baf57600080fd5b505afa158015611bc3573d6000803e3d6000fd5b505050506040513d6020811015611bd957600080fd5b505160408051808201909152600381526269626360e81b6020820152611bff8e8e613ed5565b8585613f1d565b611c4e576040805162461bcd60e51b815260206004820152601460248201527334b73b30b634b21036b2b935b63290383937b7b360611b604482015290519081900360640190fd5b60408051631bb5062960e31b81526001600160401b038e16600482015290516000916110039163dda8314891602480820192602092909190829003018186803b158015611c9a57600080fd5b505afa158015611cae573d6000803e3d6000fd5b505050506040513d6020811015611cc457600080fd5b505190508b8b600080806060611cd9896143c8565b935093509350935083611d9b578460ff16866001600160401b03167ff7b2e42d694eb1100184aae86d4245d9e46966100b1dc7e723275b98326854ac8b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611d53578181015183820152602001611d3b565b50505050905090810190601f168015611d805780820380516001836020036101000a031916815260200191505b509250505060405180910390a35050505050505050506129b6565b6040805160ff85811682529151918716916001600160401b038916917f36afdaf439a8f43fe72135135d804ae620b37a474f0943b5b85f6788312cad40919081900360200190a360ff83166123205760ff85166000818152600560209081526040808320548151631182b87560e01b815260048101958652602481019283528651604482015286516001600160a01b03909216958695631182b875958d958a9593949093606490910192918601918190849084905b83811015611e68578181015183820152602001611e50565b50505050905090810190601f168015611e955780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015611eb557600080fd5b505af1925050508015611f9957506040513d6000823e601f3d908101601f191682016040526020811015611ee857600080fd5b8101908080516040519392919084600160201b821115611f0757600080fd5b908301906020820185811115611f1c57600080fd5b8251600160201b811182820188101715611f3557600080fd5b82525081516020918201929091019080838360005b83811015611f62578181015183820152602001611f4a565b50505050905090810190601f168015611f8f5780820380516001836020036101000a031916815260200191505b5060405250505060015b6122ab576040516000815260443d1015611fb557506000612050565b60046000803e60005160e01c6308c379a08114611fd6576000915050612050565b60043d036004833e81513d60248201116001600160401b038211171561200157600092505050612050565b80830180516001600160401b03811115612022576000945050505050612050565b8060208301013d860181111561204057600095505050505050612050565b601f01601f191660405250925050505b8061205b575061216d565b60ff8716600090815260076020526040812054612092916001600160401b0390911690899061208d906002908861131c565b614478565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf948794849390840192918601918190849084905b8381101561212d578181015183820152602001612115565b50505050905090810190601f16801561215a5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2506122a6565b3d808015612197576040519150601f19603f3d011682016040523d82523d6000602084013e61219c565b606091505b5060ff87166000908152600760205260408120546121cf916001600160401b0390911690899061208d906002908861131c565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351948794849390840192918601918190849084905b8381101561226a578181015183820152602001612252565b50505050905090810190601f1680156122975780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b61231a565b8051156123185760ff87166000908152600760205260408120546122e4916001600160401b0390911690899061208d906001908661131c565b60ff8716600090815260076020526040902080546001600160401b038082166001011667ffffffffffffffff199091161790555b505b506128ee565b60ff8316600114156125c45760ff8516600081815260056020908152604080832054815163831d65d160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563831d65d1958d958a9593949093606490910192918601918190849084905b838110156123aa578181015183820152602001612392565b50505050905090810190601f1680156123d75780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156123f757600080fd5b505af1925050508015612408575060015b61231a576040516000815260443d1015612424575060006124bf565b60046000803e60005160e01c6308c379a081146124455760009150506124bf565b60043d036004833e81513d60248201116001600160401b0382111715612470576000925050506124bf565b80830180516001600160401b038111156124915760009450505050506124bf565b8060208301013d86018111156124af576000955050505050506124bf565b601f01601f191660405250925050505b806124ca575061252f565b60408051602080825283518183015283516001600160a01b038616937ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf938693909283928301918501908083836000831561212d578181015183820152602001612115565b3d808015612559576040519150601f19603f3d011682016040523d82523d6000602084013e61255e565b606091505b5060408051602080825283518183015283516001600160a01b038616937f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351938693909283928301918501908083836000831561226a578181015183820152602001612252565b60ff8316600214156128ee5760ff8516600081815260056020908152604080832054815163c8509d8160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563c8509d81958d958a9593949093606490910192918601918190849084905b8381101561264e578181015183820152602001612636565b50505050905090810190601f16801561267b5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561269b57600080fd5b505af19250505080156126ac575060015b6128ec576040516000815260443d10156126c857506000612763565b60046000803e60005160e01c6308c379a081146126e9576000915050612763565b60043d036004833e81513d60248201116001600160401b038211171561271457600092505050612763565b80830180516001600160401b03811115612735576000945050505050612763565b8060208301013d860181111561275357600095505050505050612763565b601f01601f191660405250925050505b8061276e5750612817565b816001600160a01b03167ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf826040518080602001828103825283818151815260200191508051906020019080838360005b838110156127d75781810151838201526020016127bf565b50505050905090810190601f1680156128045780820380516001836020036101000a031916815260200191505b509250505060405180910390a2506128ec565b3d808015612841576040519150601f19603f3d011682016040523d82523d6000602084013e612846565b606091505b50816001600160a01b03167f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351826040518080602001828103825283818151815260200191508051906020019080838360005b838110156128b0578181015183820152602001612898565b50505050905090810190601f1680156128dd5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b505b60ff80861660009081526009602052604090205461100591636f93d2e6918a91339187911680612920575060ff881615155b604080516001600160e01b031960e088901b1681526001600160a01b039586166004820152939094166024840152604483019190915215156064820152905160848083019260209291908290030181600087803b15801561298057600080fd5b505af1158015612994573d6000803e3d6000fd5b505050506040513d60208110156129aa57600080fd5b50505050505050505050505b5050505050505050505050505050565b630100610081565b600981565b61100781565b61100681565b60005460ff1681565b3361100714612a285760405162461bcd60e51b815260040180806020018281038252602e815260200180614908602e913960400191505060405180910390fd5b600b5460ff1615612a6c576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b612ad584848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526012815271626174636853697a65466f724f7261636c6560701b602082015291506146129050565b15612b7057604080516020601f8401819004810282018101909252828152600091612b18918585808385018382808284376000920191909152506146f992505050565b90506127108111158015612b2d5750600a8110155b612b685760405162461bcd60e51b81526004018080602001828103825260328152602001806149806032913960400191505060405180910390fd5b60015561341a565b612bd984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601281527118591913dc955c19185d1950da185b9b995b60721b602082015291506146129050565b15612d6157606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060169091149050612c5c5760405162461bcd60e51b815260040180806020018281038252605a815260200180614821605a913960600191505060405180910390fd5b60018101516002820151601683015160ff82161590612c7a816146fe565b612ccb576040805162461bcd60e51b815260206004820152601960248201527f61646472657373206973206e6f74206120636f6e747261637400000000000000604482015290519081900360640190fd5b60ff8416600081815260056020908152604080832080546001600160a01b0319166001600160a01b038716908117909155808452600683528184208585528352818420805460ff199081166001179091556009909352818420805490931687151517909255519092917f7e3b6af43092577ee20e60eaa1d9b114a7031305c895ee7dd3ffe17196d2e1e091a3505050505061341a565b612dce84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526016815275195b98589b1953dc911a5cd8589b1950da185b9b995b60521b602082015291506146129050565b15612eff57606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060029091149050612e515760405162461bcd60e51b815260040180806020018281038252604a815260200180614936604a913960600191505060405180910390fd5b600181810151600283015160ff80831660009081526005602052604090205492939192908316909114906001600160a01b03168015612ef5576001600160a01b038116600090815260066020908152604080832060ff881680855290835292819020805460ff1916861515908117909155815190815290517fa3132e3f9819fbddc7f0ed6d38d7feef59aa95112090b7c592f5cb5bc4aa4adc929181900390910190a25b505050505061341a565b612f6384848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c73757370656e6451756f72756d60981b602082015291506146129050565b156130985760028114612fa75760405162461bcd60e51b815260040180806020018281038252602d8152602001806148af602d913960400191505060405180910390fd5b6000612fea600284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506146f992505050565b905060008161ffff16118015613004575060648161ffff16105b61304e576040805162461bcd60e51b8152602060048201526016602482015275696e76616c69642073757370656e642071756f72756d60501b604482015290519081900360640190fd5b604080516f14d554d411539117d41493d413d4d05360821b815281519081900360100190206000908152600d60205220805461ffff90921661ffff1990921691909117905561341a565b6130fb84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600c81526b72656f70656e51756f72756d60a01b602082015291506146129050565b1561322e576002811461313f5760405162461bcd60e51b815260040180806020018281038252602c8152602001806148dc602c913960400191505060405180910390fd5b6000613182600284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506146f992505050565b905060008161ffff1611801561319c575060648161ffff16105b6131e5576040805162461bcd60e51b8152602060048201526015602482015274696e76616c69642072656f70656e2071756f72756d60581b604482015290519081900360640190fd5b604080516e149153d4115397d41493d413d4d053608a1b8152815190819003600f0190206000908152600d60205220805461ffff90921661ffff1990921691909117905561341a565b61329984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601481527363616e63656c5472616e7366657251756f72756d60601b602082015291506146129050565b156133dd57600281146132dd5760405162461bcd60e51b815260040180806020018281038252603481526020018061487b6034913960400191505060405180910390fd5b6000613320600284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506146f992505050565b905060008161ffff1611801561333a575060648161ffff16105b61338b576040805162461bcd60e51b815260206004820152601e60248201527f696e76616c69642063616e63656c207472616e736665722071756f72756d0000604482015290519081900360640190fd5b604080517710d05390d15317d514905394d1915497d41493d413d4d05360421b815281519081900360180190206000908152600d60205220805461ffff90921661ffff1990921691909117905561341a565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b6008602052600090815260409020546001600160401b031681565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081565b61100281565b60005460ff16613536576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b15801561357957600080fd5b505afa15801561358d573d6000803e3d6000fd5b505050506040513d60208110156135a357600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b1580156135e457600080fd5b505afa1580156135f8573d6000803e3d6000fd5b505050506040513d602081101561360e57600080fd5b505190508061361b575060155b60008211801561362b5750808211155b61366a576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b600b5460ff166136b1576040805162461bcd60e51b815260206004820152600d60248201526c1b9bdd081cdd5cdc195b991959609a1b604482015290519081900360640190fd5b604080516e149153d4115397d41493d413d4d053608a1b8152905190819003600f019020600090613702907fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4706140e3565b9050801561374057600b805460ff1916905560405133907f899fe8c37dc61708a3aaa99c4bf143346c1d1da69af79be9e8920c0a6785b75290600090a25b505050565b600660209081526000928352604080842090915290825290205460ff1681565b6040518060400160405280600381526020016269626360e81b81525081565b610e1081565b61100381565b60005460ff16156137e8576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b7f1471eb6eb2c5e789fc3de43f8ce62938c7d1836ec861730447e2ada8fd81017b80546001600160a01b0319908116611008179091557f92e85d02570a8092d09a6e3a57665bc3815a2699a4074001bf1ccabf660f5a36805460ff199081169091557fd8af288fc1c8680b4f4706064cf021e264efb6828fcaf7eb5ca36818eb365bcc8054821660019081179091557f89832631fb3c3307a103ba2c84ab569c64d6182a18893dcd163f0f1c2090733a805484166110049081179091557f6cde3cea4b3a3fb2488b2808bae7556f4a405e50f65e1794383bc026131b13c38054841690557f72e4efa1513b071517c6c74dba31b5934a81aa83cddd400e7081df5529c9943680548416831790557fa9bc9a3a348c357ba16b37005d7e6b3236198c0e939f4af8c5f19b8deeb8ebc08054851690911790557fc575c31fea594a6eb97c8e9d3f9caee4c16218c6ef37e923234c0fe9014a61e78054831690557f4e523af77f034e9810f1c94057f5e931fb3d16a51511a4c3add793617d18610580548316821790557ffb33122aa9f93cc639ebe80a7bc4784c11e6053dde89c6f4f7e268c6a623da1e805484166110001790557fc7694af312c4f286114180fd0ba6a52461fcee8a381636770b19a343af92538a80548316821790557f01112dd68e482ba8d68a7e828cff8b3abcea08eab88941953c180a7e650e9cd480548316821790557fc0a4a8be475dfebc377ebef2d7c4ff47656f572a08dd92b81017efcdba0febe1805484166110071790557f87e8a52529e8ece4ef759037313542a6429ff494a9fab9027fb79db90124eba680548316821790557f4c7666bbcb22d46469f7cc282f70764a7012dca2cce630ff8d83db9a9cdd48f080548316821790557f40f28f99a40bc9f6beea1013afdbc3cdcc689eb76b82c4de06c0acf1e1932ed58054909316611001179092557f0d9cf2cd531699eed8dd34e40ff2884a14a698c4898184fba85194e6f6772d248054821683179055600b60009081527f23f68c9bd22b8a93d06adabe17481c87c016bcbd20adc8bfd707a4d813a572176020527fdf0d5d05428057f5455c2dc8e810dd86d1e9350faa72f16bda8a45443c5b39328054831684179055603283556004805467ffffffffffffffff19166001600160401b031790556002819055600381905580549091169091179055565b6007602052600090815260409020546001600160401b031681565b60005460ff16613ba7576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b158015613bea57600080fd5b505afa158015613bfe573d6000803e3d6000fd5b505050506040513d6020811015613c1457600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b158015613c5557600080fd5b505afa158015613c69573d6000803e3d6000fd5b505050506040513d6020811015613c7f57600080fd5b5051905080613c8c575060155b600082118015613c9c5750808211155b613cdb576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b600b5460ff1615613d1f576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b604080516f14d554d411539117d41493d413d4d05360821b81529051908190036010019020600090613d71907fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4706140e3565b905080156137405761374061401a565b60005460ff16613dc6576040805162461bcd60e51b815260206004820152601960248201526000805160206149b2833981519152604482015290519081900360640190fd5b33600090815260066020908152604080832060ff8089168552925290912054859116613e235760405162461bcd60e51b81526004018080602001828103825260318152602001806147f06031913960400191505060405180910390fd5b60ff85166000908152600760209081526040808320548151601f88018490048402810184019092528682526001600160401b031692613e889284928a9261208d92909189918c908c908190840183828082843760009201919091525061131c92505050565b60ff959095166000908152600760205260409020805467ffffffffffffffff191660019096016001600160401b03169590951790945550505050565b61100081565b600381565b61100481565b60408051600e808252818301909252606091630100610060ff851617918391602082018180368337505050600e81810187905260068201939093529182525090505b92915050565b600085613f2c57506000614011565b606082518451865160800101016040519080825280601f01601f191660200182016040528015613f63576020820181803683370190505b5090506000613f7182614704565b602080890151825201905086600080613f8989614098565b8086526020909501949092509050613fa28285836140a2565b92830192613faf88614098565b8086526020909501949092509050613fc88285836140a2565b9283018a815260200192613fdb87614098565b9092509050613feb8285836140a2565b508351602001613ff961470a565b60208183886065600019fa5051600114955050505050505b95945050505050565b600b5460ff161561405e576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b600b805460ff1916600117905560405133907f6f123d3d54c84a7960a573b31c221dcd86e13fd849c5adb0c6ca851468cc1ae490600090a2565b8051602090910191565b5b602081106140c2578251825260209283019290910190601f19016140a3565b915181516020939093036101000a6000190180199091169216919091179052565b6000828152600d602052604081205461ffff166141ac57604080516f14d554d411539117d41493d413d4d05360821b815281519081900360100181206000908152600d6020818152848320805461ffff199081166001179091556e149153d4115397d41493d413d4d053608a1b8552855194859003600f01852084528282528584208054821660029081179091557710d05390d15317d514905394d1915497d41493d413d4d05360421b8652865195869003601801909520845291905292902080549092161790555b6000838152600c6020526040902080546201000090046001600160801b0316421015806141dd575082816001015414155b156142b0576000848152600d602090815260409182902054835461ffff90911661ffff199091161771ffffffffffffffffffffffffffffffff0000191662010000610e1042016001600160801b0316021783556001808401869055825191820190925233815261425291600284019190614728565b5080546040805161ffff83168152620100009092046001600160801b0316602083015281810185905251339186917f9e109f0e55ef32e99e4880be2ec357f1ddb3469c79d0747ef4762da6e89fabe5916060908290030190a3614364565b60005b600282015481101561433b57336001600160a01b03168260020182815481106142d857fe5b6000918252602090912001546001600160a01b03161415614333576040805162461bcd60e51b815260206004820152601060248201526f185b1c9958591e48185c1c1c9bdd995960821b604482015290519081900360640190fd5b6001016142b3565b50600281018054600181018255600091825260209091200180546001600160a01b031916331790555b8054600282015461ffff909116116143be576000848152600c60205260408120805471ffffffffffffffffffffffffffffffffffff1916815560018101829055906143b2600283018261478d565b50506001915050613f17565b5060009392505050565b600080600060606021855110156143f8575050604080516000808252602082019092529092508291508190614471565b600185015160218601518651604080516020198301808252601f1960011990940193909316810160200190915260418901939291606091908015614443576020820181803683370190505b509050600061445182614098565b509050614463858260218d51036140a2565b506001975091955093509150505b9193509193565b600b5460ff16156144bc576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b6002544311156144fb576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003554360025561453c565b6003805460019081019182905554101561453c576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003555b8160ff16836001600160401b0316600460009054906101000a900460070b6001600160401b03167f3a6e0fc61675aa2a100bcba0568368bb92bcec91c97673391074f11138f0cffe606185604051808361ffff1661ffff16815260200180602001828103825283818151815260200191508051906020019080838360005b838110156145d25781810151838201526020016145ba565b50505050905090810190601f1680156145ff5780820380516001836020036101000a031916815260200191505b50935050505060405180910390a4505050565b6000816040516020018082805190602001908083835b602083106146475780518252601f199092019160209182019101614628565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106146b55780518252601f199092019160209182019101614696565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b3b151590565b60200190565b60405180602001604052806001906020820280368337509192915050565b82805482825590600052602060002090810192821561477d579160200282015b8281111561477d57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614748565b506147899291506147ae565b5090565b50805460008255906000526020600020908101906147ab91906147d5565b50565b6147d291905b808211156147895780546001600160a01b03191681556001016147b4565b90565b6147d291905b8082111561478957600081556001016147db56fe74686520636f6e747261637420616e64206368616e6e656c2068617665206e6f74206265656e20726567697374657265646c656e677468206f662076616c756520666f72206164644f725570646174654368616e6e656c2073686f756c642062652032322c206368616e6e656c49643a697346726f6d53797374656d3a68616e646c6572416464726573736c656e677468206f662076616c756520666f722063616e63656c5472616e7366657251756f72756d2073686f756c6420626520326c656e677468206f662076616c756520666f722073757370656e6451756f72756d2073686f756c6420626520326c656e677468206f662076616c756520666f722072656f70656e51756f72756d2073686f756c642062652032746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f7220656e61626c654f7244697361626c654368616e6e656c2073686f756c6420626520322c206368616e6e656c49643a6973456e61626c65746865206e6577426174636853697a65466f724f7261636c652073686f756c6420626520696e205b31302c2031303030305d74686520636f6e7472616374206e6f7420696e697420796574000000000000006c6967687420636c69656e74206e6f742073796e632074686520626c6f636b20796574a26469706673582212200822a3bd79df610f758cc9702e0be636463b002fc0089f5e09cf86383a7f79fc64736f6c63430006040033", + }, + }, + } + + LubanUpgrade[networkname.RialtoChainName] = &Upgrade{ + UpgradeName: "luban", + Configs: []*UpgradeConfig{ + { + ContractAddr: ValidatorContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "60806040526004361061046c5760003560e01c8063862498821161024a578063c6d3394511610139578063e40716a1116100b6578063f9a2bbc71161007a578063f9a2bbc714610b6b578063fc3e590814610b80578063fccc281314610b95578063fd4ad81f14610baa578063fd6a687914610bd957610473565b8063e40716a114610af9578063eb57e20214610b0e578063eda5868c14610b2e578063f340fa0114610b43578063f92eb86b14610b5657610473565b8063d86222d5116100fd578063d86222d514610a90578063daacdb6614610aa5578063dc927faf14610aba578063e086c7b114610acf578063e1c7392a14610ae457610473565b8063c6d3394514610a3c578063c81b166214610a51578063c8509d811461085f578063d04aa99614610a66578063d68fb56a14610a7b57610473565b8063a5422d5c116101c7578063ad3c9da61161018b578063ad3c9da6146109d0578063aef198a9146109f0578063b7ab4db514610a05578063b8cf4ef114610a27578063bf9f49951461062f57610473565b8063a5422d5c1461095c578063a78abc1614610971578063aaf5eb6814610986578063ab51bb961461099b578063ac431751146109b057610473565b806396713da91161020e57806396713da9146108f35780639dc09262146109085780639fe0f8161461091d578063a0dc275814610932578063a1a11bf51461094757610473565b8063862498821461087f57806388b32f11146108945780638b5ad0c9146108a95780638d19a410146108be5780639369d7de146108de57610473565b80634df6e0c3116103665780636e47b482116102e35780637942fd05116102a75780637942fd05146108205780637a84ca2a1461083557806381650b621461084a578063831d65d11461085f578063853230aa1461080b57610473565b80636e47b482146107b757806370fd5bad146107cc578063718a8aa8146107e157806375d47a0a146107f657806378dfed4a1461080b57610473565b8063565c56b31161032a578063565c56b3146107265780635667515a146107465780635d77156c1461075b57806362b72cf5146107705780636969a25c1461078557610473565b80634df6e0c3146106b25780635192c82c146106c757806351e80672146106dc578063549b03f2146106f157806355614fcc1461070657610473565b8063321d398a116103f45780633dffc387116103b85780633dffc3871461062f57806343756e5c1461065157806345cf9daf14610666578063493279b11461067b5780634bf6c8821461069d57610473565b8063321d398a146105975780633365af3a146105b757806335409f7f146105d75780633b071dcc146105f75780633de0f0d81461061a57610473565b80631182b8751161043b5780631182b875146104fe578063152ad3b81461052b5780631ff180691461054d578063219f22d514610562578063300c35671461057757610473565b806304c4fec61461047857806307a568471461048f5780630bee7a67146104ba5780630e2374a5146104dc57610473565b3661047357005b600080fd5b34801561048457600080fd5b5061048d610bee565b005b34801561049b57600080fd5b506104a4610c60565b6040516104b19190616ef1565b60405180910390f35b3480156104c657600080fd5b506104cf610c66565b6040516104b19190616f1b565b3480156104e857600080fd5b506104f1610c6b565b6040516104b191906162f8565b34801561050a57600080fd5b5061051e6105193660046161de565b610c71565b6040516104b1919061646f565b34801561053757600080fd5b50610540610ea9565b6040516104b19190616464565b34801561055957600080fd5b506104a4610eb2565b34801561056e57600080fd5b506104cf610eb8565b34801561058357600080fd5b5061048d6105923660046160a7565b610ebd565b3480156105a357600080fd5b506105406105b236600461618b565b611241565b3480156105c357600080fd5b506105406105d236600461618b565b611310565b3480156105e357600080fd5b5061048d6105f2366004616080565b6113c1565b34801561060357600080fd5b5061060c61151a565b6040516104b192919061637a565b34801561062657600080fd5b506104a46117f6565b34801561063b57600080fd5b506106446117fc565b6040516104b19190616f2c565b34801561065d57600080fd5b506104f1611801565b34801561067257600080fd5b506104a4611807565b34801561068757600080fd5b5061069061180d565b6040516104b19190616ee2565b3480156106a957600080fd5b50610644611813565b3480156106be57600080fd5b5061060c611818565b3480156106d357600080fd5b506104a4611996565b3480156106e857600080fd5b506104f161199c565b3480156106fd57600080fd5b506104a46119a2565b34801561071257600080fd5b50610540610721366004616080565b6119a8565b34801561073257600080fd5b506104a4610741366004616080565b6119dd565b34801561075257600080fd5b50610644611a2e565b34801561076757600080fd5b506104cf611a33565b34801561077c57600080fd5b506104a4611a38565b34801561079157600080fd5b506107a56107a036600461618b565b611a3e565b6040516104b196959493929190616325565b3480156107c357600080fd5b506104f1611aa2565b3480156107d857600080fd5b50610644611aa8565b3480156107ed57600080fd5b50610644611aad565b34801561080257600080fd5b506104f1611ab2565b34801561081757600080fd5b506104a4611ab8565b34801561082c57600080fd5b50610644611abe565b34801561084157600080fd5b506104a4611ac3565b34801561085657600080fd5b506104cf611ac9565b34801561086b57600080fd5b5061048d61087a3660046161de565b611ace565b34801561088b57600080fd5b506104a4611b2f565b3480156108a057600080fd5b506104a4611b35565b3480156108b557600080fd5b506104a4611b3b565b3480156108ca57600080fd5b506104a46108d9366004616080565b611b41565b3480156108ea57600080fd5b5061048d611b81565b3480156108ff57600080fd5b50610644611c95565b34801561091457600080fd5b506104f1611c9a565b34801561092957600080fd5b506104a4611ca0565b34801561093e57600080fd5b506104a4611ca5565b34801561095357600080fd5b506104f1611caa565b34801561096857600080fd5b5061051e611cb0565b34801561097d57600080fd5b50610540611ccf565b34801561099257600080fd5b506104a4611cd8565b3480156109a757600080fd5b506104cf611a2e565b3480156109bc57600080fd5b5061048d6109cb36600461612f565b611ce1565b3480156109dc57600080fd5b506104a46109eb366004616080565b61258d565b3480156109fc57600080fd5b506104a461259f565b348015610a1157600080fd5b50610a1a6125ac565b6040516104b19190616367565b348015610a3357600080fd5b506104a4612698565b348015610a4857600080fd5b506104a4611aa8565b348015610a5d57600080fd5b506104f161269d565b348015610a7257600080fd5b506104a46126a3565b348015610a8757600080fd5b506104a46126a8565b348015610a9c57600080fd5b506104a46126e7565b348015610ab157600080fd5b506104a46126f3565b348015610ac657600080fd5b506104f16126f9565b348015610adb57600080fd5b506104a46126ff565b348015610af057600080fd5b5061048d612704565b348015610b0557600080fd5b506104a46128b3565b348015610b1a57600080fd5b5061048d610b29366004616080565b6128b9565b348015610b3a57600080fd5b506104cf6129c1565b61048d610b51366004616080565b6129c6565b348015610b6257600080fd5b506104a4612c4e565b348015610b7757600080fd5b506104f1612c54565b348015610b8c57600080fd5b50610644611ca0565b348015610ba157600080fd5b506104f1612c5a565b348015610bb657600080fd5b50610bca610bc536600461618b565b612c60565b6040516104b193929190616efa565b348015610be557600080fd5b506104f1612d22565b6000610bf933611b41565b9050600b8181548110610c0857fe5b600091825260209091206001601690920201015460ff16610c445760405162461bcd60e51b8152600401610c3b90616b9a565b60405180910390fd5b6000610c4e6126a8565b9050610c5b338383612d28565b505050565b60095481565b606481565b61200181565b60005460609060ff16610c965760405162461bcd60e51b8152600401610c3b9061662e565b3361200014610cb75760405162461bcd60e51b8152600401610c3b90616d79565b600b54610d7557610cc6615d6c565b60015460005b81811015610d7157600b8054600181018255600091909152835160008051602061714f833981519152601690920291820190815560208086015160008051602061718f8339815191528401805460ff1916911515919091179055604086015180518794610d4d9360008051602061716f833981519152909101920190615d9b565b506060820151610d639060038301906013615e15565b505050806001019050610ccc565b5050505b610d7d615e42565b6000610dbe85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612f1492505050565b9150915080610dda57610dd160646130d0565b92505050610ea2565b815160009060ff16610dff57610df883602001518460400151613131565b9050610e6e565b825160ff1660011415610e6a57826020015151600114610e445760008051602061712f833981519152604051610e3490616a81565b60405180910390a1506067610e65565b610df88360200151600081518110610e5857fe5b6020026020010151613d85565b610e6e565b5060655b63ffffffff8116610e935750506040805160008152602081019091529150610ea29050565b610e9c816130d0565b93505050505b9392505050565b60075460ff1681565b60035481565b606881565b334114610edc5760405162461bcd60e51b8152600401610c3b90616dc8565b6010544311610efd5760405162461bcd60e51b8152600401610c3b9061678a565b60005460ff16610f1f5760405162461bcd60e51b8152600401610c3b9061662e565b600f54610f37576032600f5561100231601155611237565b60006110023168056bc75e2d63100000811115610f6657610f5f81606463ffffffff613efc16565b9150610faf565b601154811115610fa857610f5f6064610f9c600f54610f9060115486613f3e90919063ffffffff16565b9063ffffffff613f8016565b9063ffffffff613efc16565b5050611237565b6040516309a99b4f60e41b815261100290639a99b4f090610fd6903090869060040161630c565b602060405180830381600087803b158015610ff057600080fd5b505af1158015611004573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061102891906161a3565b6110023160115591508161103d575050611237565b6000805b8481101561106b5785858281811061105557fe5b9050602002013582019150806001019050611041565b508061107957505050611237565b6000806000805b8981101561122f578489898381811061109557fe5b905060200201358802816110a557fe5b0493508a8a828181106110b457fe5b90506020020160208101906110c99190616080565b6001600160a01b038116600090815260046020526040902054909350915081156111e55760006001808403815481106110fe57fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff161561116b57836001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d858660405161115e9190616ef1565b60405180910390a26111df565b60035461117e908663ffffffff613fba16565b6003908155810154611196908663ffffffff613fba16565b60038201556040516001600160a01b038516907fcb0aad6cf9cd03bdf6137e359f541c42f38b39f007cae8e89e88aa7d8c6617b2906111d6908890616ef1565b60405180910390a25b50611227565b826001600160a01b03167fb9c75cbbfde137c4281689580799ef5f52144e78858f776a5979b2b212137d858560405161121e9190616ef1565b60405180910390a25b600101611080565b505050505050505b5050436010555050565b60015460009082106112555750600061130b565b60006001600160a01b03166001838154811061126d57fe5b60009182526020909120600490910201546001600160a01b0316148061129d5750600854158061129d5750600a54155b806112ac575060085460095410155b806112bd57506112bb82611310565b155b806112e657506000600b83815481106112d257fe5b906000526020600020906016020160000154115b806112fa575060016112f66125ac565b5111155b156113075750600061130b565b5060015b919050565b60015460009082106113245750600061130b565b600b548210611361576001828154811061133a57fe5b9060005260206000209060040201600201601c9054906101000a900460ff1615905061130b565b6001828154811061136e57fe5b9060005260206000209060040201600201601c9054906101000a900460ff161580156113bb5750600b82815481106113a257fe5b600091825260209091206001601690920201015460ff16155b92915050565b33611001146113e25760405162461bcd60e51b8152600401610c3b90616e99565b600b546114a0576113f1615d6c565b60015460005b8181101561149c57600b8054600181018255600091909152835160008051602061714f833981519152601690920291820190815560208086015160008051602061718f8339815191528401805460ff19169115159190911790556040860151805187946114789360008051602061716f833981519152909101920190615d9b565b50606082015161148e9060038301906013615e15565b5050508060010190506113f7565b5050505b6001600160a01b038116600090815260046020526040902054806114c45750611517565b6001810390506000600b82815481106114d957fe5b600091825260209091206001601690920201015460ff1690506114fc8383613fdf565b80156115055750805b15610c5b576009805460001901905550505b50565b60015460609081906000805b8281101561156d576001818154811061153b57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611565576001909101905b600101611526565b5060608160405190808252806020026020018201604052801561159a578160200160208202803683370190505b5090506060826040519080825280602002602001820160405280156115d357816020015b60608152602001906001900390816115be5790505b50600b546000945090915084141561174e5760005b8481101561174857600181815481106115fd57fe5b9060005260206000209060040201600201601c9054906101000a900460ff16611740576001818154811061162d57fe5b600091825260209091206004909102015483516001600160a01b039091169084908690811061165857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600b818154811061168557fe5b600091825260209182902060026016909202018101805460408051601f60001961010060018616150201909316949094049182018590048502840185019052808352919290919083018282801561171d5780601f106116f25761010080835404028352916020019161171d565b820191906000526020600020905b81548152906001019060200180831161170057829003601f168201915b505050505082858151811061172e57fe5b60209081029190910101526001909301925b6001016115e8565b506117ea565b60005b848110156117e8576001818154811061176657fe5b9060005260206000209060040201600201601c9054906101000a900460ff166117e0576001818154811061179657fe5b600091825260209091206004909102015483516001600160a01b03909116908490869081106117c157fe5b6001600160a01b03909216602092830291909101909101526001909301925b600101611751565b505b909450925050505b9091565b61271081565b600181565b61100181565b60085481565b6102ca81565b600881565b600e54600c5460609182918061182c575060155b60606118366125ac565b9050606061184382614392565b90508282511161185a5790945092506117f2915050565b8383835103101561186c578282510393505b83156118a25760c8430461188883838388880360008a8a614500565b6118a08383838888038989038a8b8b8b510301614500565b505b6060836040519080825280602002602001820160405280156118ce578160200160208202803683370190505b50905060608460405190808252806020026020018201604052801561190757816020015b60608152602001906001900390816118f25790505b50905060005b858110156119885784818151811061192157fe5b602002602001015183828151811061193557fe5b60200260200101906001600160a01b031690816001600160a01b03168152505083818151811061196157fe5b602002602001015182828151811061197557fe5b602090810291909101015260010161190d565b509096509450505050509091565b60065481565b61200081565b600f5481565b6001600160a01b038116600090815260046020526040812054806119d057600091505061130b565b60001901610ea281611310565b6001600160a01b03811660009081526004602052604081205480611a0557600091505061130b565b600180820381548110611a1457fe5b906000526020600020906004020160030154915050919050565b600081565b606781565b60105481565b60018181548110611a4b57fe5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b0392831694509082169291821691600160a01b81046001600160401b031691600160e01b90910460ff169086565b61100581565b600281565b601081565b61100881565b6103e881565b600b81565b600c5481565b606681565b3361200014611aef5760405162461bcd60e51b8152600401610c3b90616d79565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051611b2293929190616f3a565b60405180910390a1505050565b60025481565b60115481565b600a5481565b6001600160a01b03811660009081526004602052604081205480611b775760405162461bcd60e51b8152600401610c3b90616d01565b6000190192915050565b600b54611c3f57611b90615d6c565b60015460005b81811015611c3b57600b8054600181018255600091909152835160008051602061714f833981519152601690920291820190815560208086015160008051602061718f8339815191528401805460ff1916911515919091179055604086015180518794611c179360008051602061716f833981519152909101920190615d9b565b506060820151611c2d9060038301906013615e15565b505050806001019050611b96565b5050505b600854611c4c5760036008555b600a54611c59576002600a555b6000611c6433611b41565b9050611c6f81611241565b611c8b5760405162461bcd60e51b8152600401610c3b90616a3e565b6115173382614657565b600981565b61100781565b600381565b60c881565b61100681565b604051806101e001604052806101ab8152602001616f846101ab913981565b60005460ff1681565b6402540be40081565b60005460ff16611d035760405162461bcd60e51b8152600401610c3b9061662e565b3361100714611d245760405162461bcd60e51b8152600401610c3b90616b07565b611d8e84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526013815272065787069726554696d655365636f6e6447617606c1b602082015291506146ef9050565b15611e2b5760208114611db35760405162461bcd60e51b8152600401610c3b90616cbb565b604080516020601f8401819004810282018101909252828152600091611df19185858083850183828082843760009201919091525061474892505050565b905060648110158015611e075750620186a08111155b611e235760405162461bcd60e51b8152600401610c3b906168e7565b60025561254a565b611e8b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260098152686275726e526174696f60b81b602082015291506146ef9050565b15611f275760208114611eb05760405162461bcd60e51b8152600401610c3b906164b4565b604080516020601f8401819004810282018101909252828152600091611eee9185858083850183828082843760009201919091525061474892505050565b9050612710811115611f125760405162461bcd60e51b8152600401610c3b906167cc565b6006556007805460ff1916600117905561254a565b611f9184848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260138152726d61784e756d4f664d61696e7461696e696e6760681b602082015291506146ef9050565b1561202b5760208114611fb65760405162461bcd60e51b8152600401610c3b906164eb565b604080516020601f8401819004810282018101909252828152600091611ff49185858083850183828082843760009201919091525061474892505050565b600c5490915080612003575060155b8082106120225760405162461bcd60e51b8152600401610c3b9061683f565b5060085561254a565b61209484848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61696e7461696e536c6173685363616c6560701b602082015291506146ef9050565b1561212d57602081146120b95760405162461bcd60e51b8152600401610c3b906165b4565b604080516020601f84018190048102820181019092528281526000916120f79185858083850183828082843760009201919091525061474892505050565b90506000811180156121095750600a81105b6121255760405162461bcd60e51b8152600401610c3b90616e15565b600a5561254a565b6121a184848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601981527f6d61784e756d4f66576f726b696e6743616e6469646174657300000000000000602082015291506146ef9050565b1561223057602081146121c65760405162461bcd60e51b8152600401610c3b90616568565b604080516020601f84018190048102820181019092528281526000916122049185858083850183828082843760009201919091525061474892505050565b9050600d548111156122285760405162461bcd60e51b8152600401610c3b9061695d565b600e5561254a565b61229984848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260128152716d61784e756d4f6643616e6469646174657360701b602082015291506146ef9050565b1561231b57602081146122be5760405162461bcd60e51b8152600401610c3b90616b55565b604080516020601f84018190048102820181019092528281526000916122fc9185858083850183828082843760009201919091525061474892505050565b600d819055600e5490915081101561231557600d54600e555b5061254a565b61237f84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c6e756d4f66436162696e65747360981b602082015291506146ef9050565b1561242d57602081146123a45760405162461bcd60e51b8152600401610c3b906165f9565b604080516020601f84018190048102820181019092528281526000916123e29185858083850183828082843760009201919091525061474892505050565b9050600081116124045760405162461bcd60e51b8152600401610c3b9061669c565b60298111156124255760405162461bcd60e51b8152600401610c3b906166e4565b600c5561254a565b61249784848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601381527266696e616c697479526577617264526174696f60681b602082015291506146ef9050565b1561253257602081146124bc5760405162461bcd60e51b8152600401610c3b90616c3e565b604080516020601f84018190048102820181019092528281526000916124fa9185858083850183828082843760009201919091525061474892505050565b90506001811015801561250e575060648111155b61252a5760405162461bcd60e51b8152600401610c3b906169cc565b600f5561254a565b60405162461bcd60e51b8152600401610c3b90616e72565b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a8484848460405161257f9493929190616482565b60405180910390a150505050565b60046020526000908152604090205481565b68056bc75e2d6310000081565b6001546060906000805b828110156125db576125c781611310565b156125d3578160010191505b6001016125b6565b50606081604051908082528060200260200182016040528015612608578160200160208202803683370190505b5090506000915060005b8381101561268f5761262381611310565b15612687576001818154811061263557fe5b600091825260209091206004909102015482516001600160a01b039091169083908590811061266057fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508260010192505b600101612612565b50925050505b90565b601581565b61100281565b603281565b60006126b26125ac565b519050600080600c54116126c75760156126cb565b600c545b9050808211156126d9578091505b816126e357600191505b5090565b67016345785d8a000081565b60055481565b61100381565b602981565b60005460ff16156127275760405162461bcd60e51b8152600401610c3b90616c07565b61272f615e42565b6000612755604051806101e001604052806101ab8152602001616f846101ab9139612f14565b91509150806127765760405162461bcd60e51b8152600401610c3b90616d38565b60005b82602001515181101561289b5760018360200151828151811061279857fe5b60209081029190910181015182546001818101855560009485528385208351600493840290910180546001600160a01b039283166001600160a01b03199182161782558587015182850180549185169183169190911790556040860151600283018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b199590981692909516919091179290921694909417161790915560a09093015160039093019290925591860151805191850193918590811061286e57fe5b602090810291909101810151516001600160a01b0316825281019190915260400160002055600101612779565b50506103e8600255506000805460ff19166001179055565b600d5481565b33611001146128da5760405162461bcd60e51b8152600401610c3b90616e99565b600b54612998576128e9615d6c565b60015460005b8181101561299457600b8054600181018255600091909152835160008051602061714f833981519152601690920291820190815560208086015160008051602061718f8339815191528401805460ff19169115159190911790556040860151805187946129709360008051602061716f833981519152909101920190615d9b565b5060608201516129869060038301906013615e15565b5050508060010190506128ef565b5050505b60006129a38261474d565b90506129ae81611241565b156129bd576129bd8282614657565b5050565b606581565b3341146129e55760405162461bcd60e51b8152600401610c3b90616dc8565b60005460ff16612a075760405162461bcd60e51b8152600401610c3b9061662e565b60003411612a275760405162461bcd60e51b8152600401610c3b9061692e565b6001600160a01b0381166000908152600460205260409020546007543491906103e89060ff1615612a5757506006545b600083118015612a675750600081115b15612b08576000612a84612710610f9c868563ffffffff613f8016565b90508015612b065760405161dead9082156108fc029083906000818181858888f19350505050158015612abb573d6000803e3d6000fd5b507f627059660ea01c4733a328effb2294d2f86905bf806da763a89cee254de8bee581604051612aeb9190616ef1565b60405180910390a1612b03848263ffffffff613f3e16565b93505b505b8115612c06576000600180840381548110612b1f57fe5b9060005260206000209060040201905080600201601c9054906101000a900460ff1615612b8c57846001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b485604051612b7f9190616ef1565b60405180910390a2612c00565b600354612b9f908563ffffffff613fba16565b6003908155810154612bb7908563ffffffff613fba16565b60038201556040516001600160a01b038616907f93a090ecc682c002995fad3c85b30c5651d7fd29b0be5da9d784a3302aedc05590612bf7908790616ef1565b60405180910390a25b50612c48565b836001600160a01b03167ff177e5d6c5764d79c32883ed824111d9b13f5668cf6ab1cc12dd36791dd955b484604051612c3f9190616ef1565b60405180910390a25b50505050565b600e5481565b61100081565b61dead81565b600b8181548110612c6d57fe5b6000918252602091829020601691909102018054600180830154600280850180546040805161010096831615969096026000190190911692909204601f810188900488028501880190925281845293965060ff90911694919291830182828015612d185780601f10612ced57610100808354040283529160200191612d18565b820191906000526020600020905b815481529060010190602001808311612cfb57829003601f168201915b5050505050905083565b61100481565b6000600a5460001480612d39575081155b80612d445750600954155b15612d5157506000610ea2565b60096000815460019003919050819055506000612d9c600a54610f9c85610f9c600b8981548110612d7e57fe5b6000918252602090912060169091020154439063ffffffff613f3e16565b90506000600b8581548110612dad57fe5b906000526020600020906016020160010160006101000a81548160ff0219169083151502179055506000806110016001600160a01b0316638256ace66040518163ffffffff1660e01b8152600401604080518083038186803b158015612e1257600080fd5b505afa158015612e26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e4a91906161bb565b9150915060009350808310612ec457612e638787613fdf565b506040516305bfb49960e41b815261100190635bfb499090612e89908a906004016162f8565b600060405180830381600087803b158015612ea357600080fd5b505af1158015612eb7573d6000803e3d6000fd5b5050505060019350612ed6565b818310612ed657612ed48761474d565b505b6040516001600160a01b038816907fb9d38178dc641ff1817967a63c9078cbcd955a9f1fcd75e0e3636de615d44d3b90600090a25050509392505050565b612f1c615e42565b6000612f26615e42565b612f2e615e66565b612f3f612f3a866148f0565b614915565b90506000805b612f4e8361495f565b156130c25780612f7357612f69612f6484614980565b6149ce565b60ff1684526130ba565b80600114156130b5576060612f8f612f8a85614980565b614a4e565b90508051604051908082528060200260200182016040528015612fcc57816020015b612fb9615e86565b815260200190600190039081612fb15790505b508560200181905250805160405190808252806020026020018201604052801561300a57816020015b6060815260200190600190039081612ff55790505b50604086015260005b81518110156130aa57613024615e86565b6060600061304485858151811061303757fe5b6020026020010151614b1f565b92509250925080613064578860009a509a505050505050505050506130cb565b828960200151858151811061307557fe5b6020026020010181905250818960400151858151811061309157fe5b6020026020010181905250505050806001019050613013565b5060019250506130ba565b6130c2565b600101612f45565b50919350909150505b915091565b604080516001808252818301909252606091829190816020015b60608152602001906001900390816130ea5790505090506131108363ffffffff16614c39565b8160008151811061311d57fe5b6020026020010181905250610ea281614c4c565b60006029835111156131685760008051602061712f83398151915260405161315890616741565b60405180910390a15060666113bb565b60005b83518110156132065760005b818110156131fd5784818151811061318b57fe5b6020026020010151600001516001600160a01b03168583815181106131ac57fe5b6020026020010151600001516001600160a01b031614156131f55760008051602061712f8339815191526040516131e29061689c565b60405180910390a16066925050506113bb565b600101613177565b5060010161316b565b506060806132148585614cd6565b60015491935091506000908190815b818110156132995767016345785d8a00006001828154811061324157fe5b9060005260206000209060040201600301541061326357836001019350613291565b60006001828154811061327257fe5b9060005260206000209060040201600301541115613291578260010192505b600101613223565b506060836040519080825280602002602001820160405280156132c6578160200160208202803683370190505b5090506060846040519080825280602002602001820160405280156132f5578160200160208202803683370190505b509050606085604051908082528060200260200182016040528015613324578160200160208202803683370190505b509050606086604051908082528060200260200182016040528015613353578160200160208202803683370190505b5090506000606087604051908082528060200260200182016040528015613384578160200160208202803683370190505b5090506060886040519080825280602002602001820160405280156133b3578160200160208202803683370190505b509050600099506000985060006110046001600160a01b031663149d14d96040518163ffffffff1660e01b815260040160206040518083038186803b1580156133fb57600080fd5b505afa15801561340f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061343391906161a3565b905067016345785d8a000081111561347e5760008051602061712f83398151915260405161346090616bc6565b60405180910390a160689d50505050505050505050505050506113bb565b60005b898110156136ef5767016345785d8a00006001828154811061349f57fe5b9060005260206000209060040201600301541061362457600181815481106134c357fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316898d815181106134f457fe5b60200260200101906001600160a01b031690816001600160a01b03168152505060006402540be4006001838154811061352957fe5b9060005260206000209060040201600301548161354257fe5b066001838154811061355057fe5b9060005260206000209060040201600301540390506135788382613f3e90919063ffffffff16565b898e8151811061358457fe5b6020026020010181815250506001828154811061359d57fe5b906000526020600020906004020160020160009054906101000a90046001600160a01b0316878e815181106135ce57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505081888e815181106135fb57fe5b6020908102919091010152613616868263ffffffff613fba16565b95508c6001019c50506136e7565b60006001828154811061363357fe5b90600052602060002090600402016003015411156136e7576001818154811061365857fe5b906000526020600020906004020160010160009054906101000a90046001600160a01b0316848c8151811061368957fe5b60200260200101906001600160a01b031690816001600160a01b031681525050600181815481106136b657fe5b906000526020600020906004020160030154838c815181106136d457fe5b6020026020010181815250508a6001019a505b600101613481565b5060008415613965576002546040516303702b2960e51b815261100491636e056520918891613729918e918e918d914201906004016163ea565b6020604051808303818588803b15801561374257600080fd5b505af193505050508015613773575060408051601f3d908101601f191682019092526137709181019061610f565b60015b6138ea576040516000815260443d101561378f5750600061382a565b60046000803e60005160e01c6308c379a081146137b057600091505061382a565b60043d036004833e81513d60248201116001600160401b03821117156137db5760009250505061382a565b80830180516001600160401b038111156137fc57600094505050505061382a565b8060208301013d860181111561381a5760009550505050505061382a565b601f01601f191660405250925050505b806138355750613877565b60019150857fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf28082604051613869919061646f565b60405180910390a2506138e5565b3d8080156138a1576040519150601f19603f3d011682016040523d82523d6000602084013e6138a6565b606091505b5060019150857fbfa884552dd8921b6ce90bfe906952ae5b3b29be0cc1a951d4f62697635a3a45826040516138db919061646f565b60405180910390a2505b613965565b801561392c577fa217d08e65f80c73121cd9db834d81652d544bfbf452f6d04922b16c90a37b708660405161391f9190616ef1565b60405180910390a1613963565b857fa7cdeed7d0db45e3219a6e5d60838824c16f1d39991fcfe3f963029c844bf28060405161395a90616531565b60405180910390a25b505b8015613b1b5760005b8751811015613b1957600088828151811061398557fe5b6020026020010151905060006001828154811061399e57fe5b60009182526020909120600160049092020181015481546001600160a01b03909116916108fc91859081106139cf57fe5b9060005260206000209060040201600301549081150290604051600060405180830381858888f1935050505090508015613a8b5760018281548110613a1057fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d9185908110613a5f57fe5b906000526020600020906004020160030154604051613a7e9190616ef1565b60405180910390a2613b0f565b60018281548110613a9857fe5b60009182526020909120600160049092020181015481546001600160a01b03909116917f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d9185908110613ae757fe5b906000526020600020906004020160030154604051613b069190616ef1565b60405180910390a25b505060010161396e565b505b835115613c655760005b8451811015613c63576000858281518110613b3c57fe5b60200260200101516001600160a01b03166108fc868481518110613b5c57fe5b60200260200101519081150290604051600060405180830381858888f1935050505090508015613bf257858281518110613b9257fe5b60200260200101516001600160a01b03167f6c61d60f69a7beb3e1c80db7f39f37b208537cbb19da3174511b477812b2fc7d868481518110613bd057fe5b6020026020010151604051613be59190616ef1565b60405180910390a2613c5a565b858281518110613bfe57fe5b60200260200101516001600160a01b03167f25d0ce7d2f0cec669a8c17efe49d195c13455bb8872b65fa610ac7f53fe4ca7d868481518110613c3c57fe5b6020026020010151604051613c519190616ef1565b60405180910390a25b50600101613b25565b505b5050505050505050505050506000471115613ce1577f6ecc855f9440a9282c90913bbc91619fd44f5ec0b462af28d127b116f130aa4d47604051613ca99190616ef1565b60405180910390a1604051611002904780156108fc02916000818181858888f19350505050158015613cdf573d6000803e3d6000fd5b505b60006003819055600555815115613cfc57613cfc8282614f0f565b6110016001600160a01b031663fc4333cd6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015613d3957600080fd5b505af1158015613d4d573d6000803e3d6000fd5b50506040517fedd8d7296956dd970ab4de3f2fc03be2b0ffc615d20cd4c72c6e44f928630ebf925060009150a1506000949350505050565b80516001600160a01b0316600090815260046020526040812054801580613dd65750600180820381548110613db657fe5b9060005260206000209060040201600201601c9054906101000a900460ff165b15613e1c5782516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a2600091505061130b565b600154600554600019820111801590613e725784516040516001600160a01b03909116907fe209c46bebf57cf265d5d9009a00870e256d9150f3ed5281ab9d9eb3cec6e4be90600090a26000935050505061130b565b600580546001908101909155805481906000198601908110613e9057fe5b6000918252602082206002600490920201018054921515600160e01b0260ff60e01b199093169290921790915585516040516001600160a01b03909116917ff226e7d8f547ff903d9d419cf5f54e0d7d07efa9584135a53a057c5f1f27f49a91a2506000949350505050565b6000610ea283836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506156ee565b6000610ea283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250615725565b600082613f8f575060006113bb565b82820282848281613f9c57fe5b0414610ea25760405162461bcd60e51b8152600401610c3b90616ac6565b600082820183811015610ea25760405162461bcd60e51b8152600401610c3b90616665565b60008060018381548110613fef57fe5b906000526020600020906004020160030154905060006001808054905003905060016140196125ac565b511161404e5760006001858154811061402e57fe5b9060005260206000209060040201600301819055506000925050506113bb565b846001600160a01b03167f3b6f9ef90462b512a1293ecec018670bf7b7f1876fb727590a8a6d7643130a70836040516140879190616ef1565b60405180910390a26001600160a01b038516600090815260046020526040812055835b6001546000190181101561427457600181600101815481106140c857fe5b9060005260206000209060040201600182815481106140e357fe5b60009182526020909120825460049092020180546001600160a01b03199081166001600160a01b0393841617825560018085015481840180548416918616919091179055600280860180549185018054909416919095161780835584546001600160401b03600160a01b91829004160267ffffffffffffffff60a01b1990911617808355935460ff600160e01b918290041615150260ff60e01b19909416939093179055600392830154920191909155600b8054909183019081106141a457fe5b9060005260206000209060160201600b82815481106141bf57fe5b600091825260209091208254601690920201908155600180830154818301805460ff909216151560ff1990921691909117905560028084018054614216938386019390821615610100026000190190911604615ebb565b5061422960038281019084016013615f30565b5090505080600101600460006001848154811061424257fe5b600091825260208083206004909202909101546001600160a01b031683528201929092526040019020556001016140aa565b50600180548061428057fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b8054806142d357fe5b60008281526020812060166000199093019283020181815560018101805460ff19169055906143056002830182615f5a565b614313600383016000615f9e565b50509055600081838161432257fe5b04905080156143865760015460005b8181101561438357826001828154811061434757fe5b906000526020600020906004020160030154016001828154811061436757fe5b6000918252602090912060036004909202010155600101614331565b50505b50600195945050505050565b6001548151604080518281526020808402820101909152606092919083908280156143d157816020015b60608152602001906001900390816143bc5790505b50600b5490915083146143e857925061130b915050565b60005b828110156144f757600b60016004600089858151811061440757fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002054038154811061443b57fe5b600091825260209182902060026016909202018101805460408051601f6000196101006001861615020190931694909404918201859004850284018501905280835291929091908301828280156144d35780601f106144a8576101008083540402835291602001916144d3565b820191906000526020600020905b8154815290600101906020018083116144b657829003601f168201915b50505050508282815181106144e457fe5b60209081029190910101526001016143eb565b50949350505050565b60005b8281101561464d57600082878388016040516020016145239291906162ea565b6040516020818303038152906040528051906020012060001c8161454357fe5b06905080850182870114614644576000898388018151811061456157fe5b602002602001015190506060898489018151811061457b57fe5b602002602001015190508a8388018151811061459357fe5b60200260200101518b858a01815181106145a957fe5b60200260200101906001600160a01b031690816001600160a01b031681525050818b848901815181106145d857fe5b60200260200101906001600160a01b031690816001600160a01b031681525050898388018151811061460657fe5b60200260200101518a858a018151811061461c57fe5b6020026020010181905250808a8489018151811061463657fe5b602002602001018190525050505b50600101614503565b5050505050505050565b600980546001908101909155600b80548390811061467157fe5b906000526020600020906016020160010160006101000a81548160ff02191690831515021790555043600b82815481106146a757fe5b600091825260208220601690910201919091556040516001600160a01b038416917ff62981a567ec3cec866c6fa93c55bcdf841d6292d18b8d522ececa769375d82d91a25050565b60008160405160200161470291906162ce565b604051602081830303815290604052805190602001208360405160200161472991906162ce565b6040516020818303038152906040528051906020012014905092915050565b015190565b6001600160a01b038116600090815260046020526040812054806147765750600019905061130b565b60018103905060006001828154811061478b57fe5b90600052602060002090600402016003015490506000600183815481106147ae57fe5b6000918252602090912060036004909202010155600154604051600019909101906001600160a01b038616907f8cd4e147d8af98a9e3b6724021b8bf6aed2e5dac71c38f2dce8161b82585b25d90614807908590616ef1565b60405180910390a28061481f5782935050505061130b565b600081838161482a57fe5b04905080156148e65760005b8481101561488857816001828154811061484c57fe5b906000526020600020906004020160030154016001828154811061486c57fe5b6000918252602090912060036004909202010155600101614836565b50600180549085015b818110156148e35782600182815481106148a757fe5b90600052602060002090600402016003015401600182815481106148c757fe5b6000918252602090912060036004909202010155600101614891565b50505b5091949350505050565b6148f8615fad565b506040805180820190915281518152602082810190820152919050565b61491d615e66565b61492682615751565b61492f57600080fd5b600061493e836020015161578b565b60208085015160408051808201909152868152920190820152915050919050565b6000614969615fad565b505080518051602091820151919092015191011190565b614988615fad565b6149918261495f565b61499a57600080fd5b602082015160006149aa826157ee565b80830160209586015260408051808201909152908152938401919091525090919050565b8051600090158015906149e357508151602110155b6149ec57600080fd5b60006149fb836020015161578b565b90508083600001511015614a215760405162461bcd60e51b8152600401610c3b90616c84565b8251602080850151830180519284900392918310156144f757506020919091036101000a90049392505050565b6060614a5982615751565b614a6257600080fd5b6000614a6d836158cf565b9050606081604051908082528060200260200182016040528015614aab57816020015b614a98615fad565b815260200190600190039081614a905790505b5090506000614abd856020015161578b565b60208601510190506000805b84811015614b1457614ada836157ee565b9150604051806040016040528083815260200184815250848281518110614afd57fe5b602090810291909101015291810191600101614ac9565b509195945050505050565b614b27615e86565b60606000614b33615e86565b6060614b3d615e66565b614b4687614915565b90506000805b614b558361495f565b15614c2a5780614b8057614b70614b6b84614980565b61592b565b6001600160a01b03168552614c22565b8060011415614ba857614b95614b6b84614980565b6001600160a01b03166020860152614c22565b8060021415614bd057614bbd614b6b84614980565b6001600160a01b03166040860152614c22565b8060031415614bfc57614be5612f6484614980565b6001600160401b0316606086015260019150614c22565b8060041415614c1d57614c16614c1184614980565b615945565b9350614c22565b614c2a565b600101614b4c565b50929791965091945092505050565b60606113bb614c47836159b5565b615a9b565b6060815160001415614c6d575060408051600081526020810190915261130b565b606082600081518110614c7c57fe5b602002602001015190506000600190505b8351811015614cbd57614cb382858381518110614ca657fe5b6020026020010151615aed565b9150600101614c8d565b50610ea2614cd0825160c060ff16615b6a565b82615aed565b606080600080808080614ce76126a8565b6001549091505b8015614df557600181039250600b8381548110614d0757fe5b600091825260209091206001601690920201015460ff16614d2757614dec565b60018381548110614d3457fe5b60009182526020909120600490910201546001600160a01b03169450614d5b858484612d28565b9350831580614d6e575060018a51038610155b15614d7857614dec565b60005b8a51811015614dea57856001600160a01b03168b8281518110614d9a57fe5b6020026020010151600001516001600160a01b03161415614de25760018b8281518110614dc357fe5b6020908102919091010151901515608090910152600190960195614dea565b600101614d7b565b505b60001901614cee565b5084895103604051908082528060200260200182016040528015614e3357816020015b614e20615e86565b815260200190600190039081614e185790505b50965084895103604051908082528060200260200182016040528015614e6d57816020015b6060815260200190600190039081614e585790505b5095506000915060005b8951811015614f0157898181518110614e8c57fe5b602002602001015160800151614ef957898181518110614ea857fe5b6020026020010151888481518110614ebc57fe5b6020026020010181905250888181518110614ed357fe5b6020026020010151878481518110614ee757fe5b60200260200101819052508260010192505b600101614e77565b5050505050505b9250929050565b600154825160005b8281101561502c576001614f29615e86565b60018381548110614f3657fe5b600091825260208083206040805160c08101825260049490940290910180546001600160a01b0390811685526001820154811693850193909352600281015492831691840191909152600160a01b82046001600160401b03166060840152600160e01b90910460ff16151560808301526003015460a082015291505b8481101561500057878181518110614fc657fe5b6020026020010151600001516001600160a01b031682600001516001600160a01b03161415614ff85760009250615000565b600101614fb2565b5081156150225780516001600160a01b03166000908152600460205260408120555b5050600101614f17565b50808211156150eb57805b828110156150e957600180548061504a57fe5b60008281526020812060046000199093019283020180546001600160a01b0319908116825560018201805490911690556002810180546001600160e81b0319169055600301559055600b80548061509d57fe5b60008281526020812060166000199093019283020181815560018101805460ff19169055906150cf6002830182615f5a565b6150dd600383016000615f9e565b50509055600101615037565b505b60008183106150fa57816150fc565b825b905060005b818110156154a0576151ae86828151811061511857fe5b60200260200101516001838154811061512d57fe5b60009182526020918290206040805160c08101825260049390930290910180546001600160a01b0390811684526001820154811694840194909452600281015493841691830191909152600160a01b83046001600160401b03166060830152600160e01b90920460ff161515608082015260039091015460a0820152615c3c565b6153625780600101600460008884815181106151c657fe5b6020026020010151600001516001600160a01b03166001600160a01b031681526020019081526020016000208190555085818151811061520257fe5b60200260200101516001828154811061521757fe5b6000918252602091829020835160049092020180546001600160a01b039283166001600160a01b0319918216178255928401516001820180549184169185169190911790556040840151600282018054606087015160808801511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909716929097169190911792909216939093171692909217905560a09091015160039091015584518590829081106152d257fe5b6020026020010151600b82815481106152e757fe5b9060005260206000209060160201600201908051906020019061530b929190615d9b565b506000600b828154811061531b57fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b80548390811061534c57fe5b6000918252602090912060169091020155615498565b61542885828151811061537157fe5b6020026020010151600b838154811061538657fe5b600091825260209182902060026016909202018101805460408051601f60001961010060018616150201909316949094049182018590048502840185019052808352919290919083018282801561541e5780601f106153f35761010080835404028352916020019161541e565b820191906000526020600020905b81548152906001019060200180831161540157829003601f168201915b5050505050615cbd565b6154735784818151811061543857fe5b6020026020010151600b828154811061544d57fe5b90600052602060002090601602016002019080519060200190615471929190615d9b565b505b60006001828154811061548257fe5b9060005260206000209060040201600301819055505b600101615101565b5082821115615678576154b1615d6c565b835b83811015615675578581815181106154c757fe5b6020026020010151826040018190525060018782815181106154e557fe5b6020908102919091018101518254600181810185556000948552838520835160049093020180546001600160a01b039384166001600160a01b0319918216178255848601518284018054918616918316919091179055604080860151600284018054606089015160808a01511515600160e01b0260ff60e01b196001600160401b03909216600160a01b0267ffffffffffffffff60a01b1995909a1692909616919091179290921696909617169190911790935560a090930151600390930192909255600b805492830181559093528451601690910260008051602061714f83398151915281019182558583015160008051602061718f8339815191528201805491151560ff199092169190911790559285015180518694929361561b9360008051602061716f83398151915201920190615d9b565b5060608201516156319060038301906013615e15565b505050806001016004600089848151811061564857fe5b602090810291909101810151516001600160a01b03168252810191909152604001600020556001016154b3565b50505b6000600981905560015493505b838110156156e6576000600b828154811061569c57fe5b60009182526020822060169190910201600101805460ff191692151592909217909155600b8054839081106156cd57fe5b6000918252602090912060169091020155600101615685565b505050505050565b6000818361570f5760405162461bcd60e51b8152600401610c3b919061646f565b50600083858161571b57fe5b0495945050505050565b600081848411156157495760405162461bcd60e51b8152600401610c3b919061646f565b505050900390565b80516000906157625750600061130b565b6020820151805160001a9060c08210156157815760009250505061130b565b5060019392505050565b8051600090811a60808110156157a557600091505061130b565b60b88110806157c0575060c081108015906157c0575060f881105b156157cf57600191505061130b565b60c08110156157e35760b51901905061130b565b60f51901905061130b565b80516000908190811a608081101561580957600191506158c8565b60b881101561581e57607e19810191506158c8565b60c081101561586f57600060b78203600186019550806020036101000a8651049150600181018201935050808310156158695760405162461bcd60e51b8152600401610c3b90616a13565b506158c8565b60f88110156158845760be19810191506158c8565b600060f78203600186019550806020036101000a8651049150600181018201935050808310156158c65760405162461bcd60e51b8152600401610c3b90616a13565b505b5092915050565b80516000906158e05750600061130b565b600080905060006158f4846020015161578b565b602085015185519181019250015b8082101561592257615913826157ee565b82019150826001019250615902565b50909392505050565b805160009060151461593c57600080fd5b6113bb826149ce565b805160609061595357600080fd5b6000615962836020015161578b565b83516040805191839003808352601f19601f8201168301602001909152919250606090828015615999576020820181803683370190505b50905060008160200190506144f7848760200151018285615d21565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166159f957506018615a1d565b6fffffffffffffffffffffffffffffffff198416615a1957506010615a1d565b5060005b6020811015615a5357818181518110615a3257fe5b01602001516001600160f81b03191615615a4b57615a53565b600101615a1d565b60008160200390506060816040519080825280601f01601f191660200182016040528015615a88576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015615acd5750607f60f81b82600081518110615abb57fe5b01602001516001600160f81b03191611155b15615ad957508061130b565b6113bb615aeb8351608060ff16615b6a565b835b6060806040519050835180825260208201818101602087015b81831015615b1e578051835260209283019201615b06565b50855184518101855292509050808201602086015b81831015615b4b578051835260209283019201615b33565b508651929092011591909101601f01601f191660405250905092915050565b6060680100000000000000008310615b945760405162461bcd60e51b8152600401610c3b90616817565b60408051600180825281830190925260609160208201818036833701905050905060378411615bee5782840160f81b81600081518110615bd057fe5b60200101906001600160f81b031916908160001a90535090506113bb565b6060615bf9856159b5565b90508381510160370160f81b82600081518110615c1257fe5b60200101906001600160f81b031916908160001a905350615c338282615aed565b95945050505050565b805182516000916001600160a01b039182169116148015615c76575081602001516001600160a01b031683602001516001600160a01b0316145b8015615c9b575081604001516001600160a01b031683604001516001600160a01b0316145b8015610ea25750506060908101519101516001600160401b0390811691161490565b815181516000916001918114808314615cd95760009250615d17565b600160208701838101602088015b600284838510011415615d12578051835114615d065760009650600093505b60209283019201615ce7565b505050505b5090949350505050565b80615d2b57610c5b565b5b60208110615d4b578251825260209283019290910190601f1901615d2c565b915181516020939093036101000a6000190180199091169216919091179052565b60405180608001604052806000815260200160001515815260200160608152602001615d96615fc7565b905290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615ddc57805160ff1916838001178555615e09565b82800160010185558215615e09579182015b82811115615e09578251825591602001919060010190615dee565b506126e3929150615fe6565b8260138101928215615e095791602002820182811115615e09578251825591602001919060010190615dee565b6040518060600160405280600060ff16815260200160608152602001606081525090565b6040518060400160405280615e79615fad565b8152602001600081525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615ef45780548555615e09565b82800160010185558215615e0957600052602060002091601f016020900482015b82811115615e09578254825591600101919060010190615f15565b8260138101928215615e095791820182811115615e09578254825591600101919060010190615f15565b50805460018160011615610100020316600290046000825580601f10615f805750611517565b601f0160209004906000526020600020908101906115179190615fe6565b50611517906013810190615fe6565b604051806040016040528060008152602001600081525090565b6040518061026001604052806013906020820280368337509192915050565b61269591905b808211156126e35760008155600101615fec565b60008083601f840112616011578182fd5b5081356001600160401b03811115616027578182fd5b6020830191508360208083028501011115614f0857600080fd5b60008083601f840112616052578182fd5b5081356001600160401b03811115616068578182fd5b602083019150836020828501011115614f0857600080fd5b600060208284031215616091578081fd5b81356001600160a01b0381168114610ea2578182fd5b600080600080604085870312156160bc578283fd5b84356001600160401b03808211156160d2578485fd5b6160de88838901616000565b909650945060208701359150808211156160f6578384fd5b5061610387828801616000565b95989497509550505050565b600060208284031215616120578081fd5b81518015158114610ea2578182fd5b60008060008060408587031215616144578384fd5b84356001600160401b038082111561615a578586fd5b61616688838901616041565b9096509450602087013591508082111561617e578384fd5b5061610387828801616041565b60006020828403121561619c578081fd5b5035919050565b6000602082840312156161b4578081fd5b5051919050565b600080604083850312156161cd578182fd5b505080516020909101519092909150565b6000806000604084860312156161f2578283fd5b833560ff81168114616202578384fd5b925060208401356001600160401b0381111561621c578283fd5b61622886828701616041565b9497909650939450505050565b6000815180845260208085019450808401835b8381101561626d5781516001600160a01b031687529582019590820190600101616248565b509495945050505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b600081518084526162ba816020860160208601616f57565b601f01601f19169290920160200192915050565b600082516162e0818460208701616f57565b9190910192915050565b918252602082015260400190565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b03968716815294861660208601529290941660408401526001600160401b03166060830152911515608082015260a081019190915260c00190565b600060208252610ea26020830184616235565b60006040825261638d6040830185616235565b602083820381850152818551808452828401915082838202850101838801865b838110156163db57601f198784030185526163c98383516162a2565b948601949250908501906001016163ad565b50909998505050505050505050565b6000608082526163fd6080830187616235565b828103602084810191909152865180835287820192820190845b8181101561643357845183529383019391830191600101616417565b505084810360408601526164478188616235565b93505050506001600160401b038316606083015295945050505050565b901515815260200190565b600060208252610ea260208301846162a2565b600060408252616496604083018688616278565b82810360208401526164a9818587616278565b979650505050505050565b6020808252601c908201527f6c656e677468206f66206275726e526174696f206d69736d6174636800000000604082015260600190565b60208082526026908201527f6c656e677468206f66206d61784e756d4f664d61696e7461696e696e67206d696040820152650e6dac2e8c6d60d31b606082015260800190565b6020808252601b908201527f6261746368207472616e736665722072657475726e2066616c73650000000000604082015260600190565b6020808252602c908201527f6c656e677468206f66206d61784e756d4f66576f726b696e6743616e6469646160408201526b0e8cae640dad2e6dac2e8c6d60a31b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61696e7461696e536c6173685363616c65206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252818101527f6c656e677468206f66206e756d4f66436162696e657473206d69736d61746368604082015260600190565b60208082526019908201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604082015260600190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526028908201527f746865206e756d4f66436162696e657473206d75737420626520677265617465604082015267072207468616e20360c41b606082015260800190565b60208082526039908201527f746865206e756d4f66436162696e657473206d757374206265206c657373207460408201527f68616e204d41585f4e554d5f4f465f56414c494441544f525300000000000000606082015260800190565b60208082526029908201527f746865206e756d626572206f662076616c696461746f727320657863656564206040820152681d1a19481b1a5b5a5d60ba1b606082015260800190565b60208082526022908201527f63616e206e6f7420646f207468697320747769636520696e206f6e6520626c6f604082015261636b60f01b606082015260800190565b6020808252602b908201527f746865206275726e526174696f206d757374206265206e6f206772656174657260408201526a0207468616e2031303030360ac1b606082015260800190565b6020808252600e908201526d696e70757420746f6f206c6f6e6760901b604082015260600190565b60208082526037908201527f746865206d61784e756d4f664d61696e7461696e696e67206d7573742062652060408201527f6c657373207468616e206e756d4f66436162696e657473000000000000000000606082015260800190565b6020808252602b908201527f6475706c696361746520636f6e73656e7375732061646472657373206f66207660408201526a185b1a59185d1bdc94d95d60aa1b606082015260800190565b60208082526027908201527f7468652065787069726554696d655365636f6e64476170206973206f7574206f604082015266662072616e676560c81b606082015260800190565b6020808252601590820152746465706f7369742076616c7565206973207a65726f60581b604082015260600190565b60208082526049908201527f746865206d61784e756d4f66576f726b696e6743616e64696461746573206d7560408201527f7374206265206e6f742067726561746572207468616e206d61784e756d4f6643606082015268616e6469646174657360b81b608082015260a00190565b60208082526027908201527f7468652066696e616c697479526577617264526174696f206973206f7574206f604082015266662072616e676560c81b606082015260800190565b6020808252601190820152706164646974696f6e206f766572666c6f7760781b604082015260600190565b60208082526023908201527f63616e206e6f7420656e7465722054656d706f72617279204d61696e74656e616040820152626e636560e81b606082015260800190565b60208082526025908201527f6c656e677468206f66206a61696c2076616c696461746f7273206d757374206260408201526465206f6e6560d81b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252602e908201527f746865206d6573736167652073656e646572206d75737420626520676f76657260408201526d1b985b98d94818dbdb9d1c9858dd60921b606082015260800190565b60208082526025908201527f6c656e677468206f66206d61784e756d4f6643616e64696461746573206d69736040820152640dac2e8c6d60db1b606082015260800190565b6020808252601290820152716e6f7420696e206d61696e74656e616e636560701b604082015260600190565b60208082526021908201527f666565206973206c6172676572207468616e2044555354595f494e434f4d494e6040820152604760f81b606082015260800190565b60208082526019908201527f74686520636f6e747261637420616c726561647920696e697400000000000000604082015260600190565b60208082526026908201527f6c656e677468206f662066696e616c697479526577617264526174696f206d696040820152650e6dac2e8c6d60d31b606082015260800190565b6020808252601a908201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604082015260600190565b60208082526026908201527f6c656e677468206f662065787069726554696d655365636f6e64476170206d696040820152650e6dac2e8c6d60d31b606082015260800190565b60208082526017908201527f6f6e6c792063757272656e742076616c696461746f7273000000000000000000604082015260600190565b60208082526021908201527f6661696c656420746f20706172736520696e69742076616c696461746f7253656040820152601d60fa1b606082015260800190565b6020808252602f908201527f746865206d6573736167652073656e646572206d7573742062652063726f737360408201526e0818da185a5b8818dbdb9d1c9858dd608a1b606082015260800190565b6020808252602d908201527f746865206d6573736167652073656e646572206d75737420626520746865206260408201526c3637b1b590383937b23ab1b2b960991b606082015260800190565b6020808252603e908201527f746865206d61696e7461696e536c6173685363616c65206d757374206265206760408201527f726561746572207468616e203020616e64206c657373207468616e2031300000606082015260800190565b6020808252600d908201526c756e6b6e6f776e20706172616d60981b604082015260600190565b60208082526029908201527f746865206d6573736167652073656e646572206d75737420626520736c6173686040820152680818dbdb9d1c9858dd60ba1b606082015260800190565b61ffff91909116815260200190565b90815260200190565b6000848252831515602083015260606040830152615c3360608301846162a2565b63ffffffff91909116815260200190565b60ff91909116815260200190565b600060ff8516825260406020830152615c33604083018486616278565b60005b83811015616f72578181015183820152602001616f5a565b83811115612c48575050600091015256fef901a880f901a4f844941284214b9b9c85549ab3d2b972df0deef66ac2c9946ddf42a51534fc98d0c0a3b42c963cace8441ddf946ddf42a51534fc98d0c0a3b42c963cace8441ddf8410000000f84494a2959d3f95eae5dc7d70144ce1b73b403b7eb6e0948081ef03f1d9e0bb4a5bf38f16285c879299f07f948081ef03f1d9e0bb4a5bf38f16285c879299f07f8410000000f8449435552c16704d214347f29fa77f77da6d75d7c75294dc4973e838e3949c77aced16ac2315dc2d7ab11194dc4973e838e3949c77aced16ac2315dc2d7ab1118410000000f84494980a75ecd1309ea12fa2ed87a8744fbfc9b863d594cc6ac05c95a99c1f7b5f88de0e3486c82293b27094cc6ac05c95a99c1f7b5f88de0e3486c82293b2708410000000f84494f474cf03cceff28abc65c9cbae594f725c80e12d94e61a183325a18a173319dd8e19c8d069459e217594e61a183325a18a173319dd8e19c8d069459e21758410000000f84494b71b214cb885500844365e95cd9942c7276e7fd894d22ca3ba2141d23adab65ce4940eb7665ea2b6a794d22ca3ba2141d23adab65ce4940eb7665ea2b6a7841000000070e72399380dcfb0338abc03dc8d47f9f470ada8e769c9a78d644ea97385ecb20175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db90175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbb0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01dbaa2646970667358221220bc53b84b66ec5288714012f6e0e7cdc85eb3fd6718cf69ef36b3579924bc204664736f6c63430006040033", + }, + { + ContractAddr: SlashContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "608060405234801561001057600080fd5b506004361061027f5760003560e01c80637942fd051161015c578063c80d4b8f116100ce578063dc927faf11610087578063dc927faf146104ad578063e1c7392a146104b5578063f9a2bbc7146104bd578063fc3e5908146104c5578063fc4333cd146104cd578063fd6a6879146104d55761027f565b8063c80d4b8f1461045c578063c81b166214610464578063c8509d811461046c578063c96be4cb1461047f578063cc844b7314610492578063d2a42e4b146104a55761027f565b80639dc09262116101205780639dc0926214610421578063a1a11bf514610429578063a78abc1614610431578063ab51bb9614610439578063ac0af62914610441578063ac431751146104495761027f565b80637942fd05146103ee5780638256ace6146103f6578063831d65d1146103fe57806396713da9146104115780639bc8e4f2146104195761027f565b8063493279b1116101f557806362b72cf5116101b957806362b72cf5146103be5780636e47b482146103c657806370fd5bad146103ce578063718a8aa8146103d657806375d47a0a146103de5780637912a65d146103e65761027f565b8063493279b11461037c5780634bf6c8821461039157806351e8067214610399578063567a372d146103a15780635bfb4990146103a95761027f565b806335aa2e441161024757806335aa2e441461030e57806337c8dab914610321578063389f4f71146103425780633a63f4b1146103575780633dffc3871461035f57806343756e5c146103745761027f565b80630bee7a67146102845780630e2374a5146102a25780631182b875146102b757806322d1e80b146102d757806323bac5a2146102ec575b600080fd5b61028c6104dd565b60405161029991906132a6565b60405180910390f35b6102aa6104e2565b6040516102999190612b84565b6102ca6102c5366004612aba565b6104e8565b6040516102999190612bbc565b6102df61054e565b6040516102999190612bb1565b6102ff6102fa366004612868565b610557565b6040516102999392919061328e565b6102aa61031c366004612a8a565b61057a565b61033461032f366004612868565b6105a1565b604051610299929190613280565b61034a6105f8565b6040516102999190613256565b61034a6105fe565b610367610604565b60405161029991906132b7565b6102aa610609565b61038461060f565b6040516102999190613247565b610367610615565b6102aa61061a565b61034a610620565b6103bc6103b7366004612868565b610626565b005b61034a6106d1565b6102aa6106d7565b6103676106dd565b6103676106e2565b6102aa6106e7565b61034a6106ed565b6103676106f2565b6103346106f7565b6103bc61040c366004612aba565b610701565b610367610813565b61034a610818565b6102aa610823565b6102aa610829565b6102df61082f565b61028c610838565b61034a61083d565b6103bc61045736600461296e565b610842565b61034a610ce1565b6102aa610ce6565b6103bc61047a366004612aba565b610cec565b6103bc61048d366004612868565b610d5d565b6103bc6104a03660046129d7565b61114e565b61034a61169b565b6102aa6116a0565b6103bc6116a6565b6102aa6116e2565b6103676116e8565b6103bc6116ed565b6102aa611b36565b606481565b61200181565b606033612000146105145760405162461bcd60e51b815260040161050b906130cd565b60405180910390fd5b60005460ff166105365760405162461bcd60e51b815260040161050b90612c9d565b60405162461bcd60e51b815260040161050b90613190565b60075460ff1681565b600260208190526000918252604090912080546001820154919092015460ff1683565b6001818154811061058757fe5b6000918252602090912001546001600160a01b0316905081565b6000806105ac61264f565b5050506001600160a01b0316600090815260026020818152604092839020835160608101855281548082526001830154938201849052919093015460ff16151592909301919091529091565b60055481565b60065481565b600181565b61100181565b6102ca81565b600881565b61200081565b60045481565b33611000146106475760405162461bcd60e51b815260040161050b90612ee1565b60005460ff166106695760405162461bcd60e51b815260040161050b90612c9d565b61200063f7a251d7600b61067c84611b3c565b60006040518463ffffffff1660e01b815260040161069c939291906132c5565b600060405180830381600087803b1580156106b657600080fd5b505af11580156106ca573d6000803e3d6000fd5b5050505050565b60035481565b61100581565b600281565b601081565b61100881565b603281565b600b81565b6004546005549091565b33612000146107225760405162461bcd60e51b815260040161050b906130cd565b60005460ff166107445760405162461bcd60e51b815260040161050b90612c9d565b61074c612672565b600061078d84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611c0f92505050565b9150915080156107d45781516040517f7f0956d47419b9525356e7111652b653b530ec6f5096dccc04589bc38e629967916107c7916132a6565b60405180910390a16106ca565b81516040517f7d45f62d17443dd4547bca8a8112c60e2385669318dc300ec61a5d2492f262e791610804916132a6565b60405180910390a15050505050565b600981565b662386f26fc1000081565b61100781565b61100681565b60005460ff1681565b600081565b600481565b60005460ff166108645760405162461bcd60e51b815260040161050b90612c9d565b33611007146108855760405162461bcd60e51b815260040161050b90612f8a565b6108f084848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805180820190915260148152731b5a5cd9195b59585b9bdc951a1c995cda1bdb1960621b60208201529150611c8f9050565b1561098b57602081146109155760405162461bcd60e51b815260040161050b90612e6d565b604080516020601f840181900481028201810190925282815260009161095391858580838501838280828437600092019190915250611ce992505050565b905060018110158015610967575060055481105b6109835760405162461bcd60e51b815260040161050b90613088565b600455610c9e565b6109f184848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600f81526e19995b1bdb9e551a1c995cda1bdb19608a1b60208201529150611c8f9050565b15610a8d5760208114610a165760405162461bcd60e51b815260040161050b90612fd8565b604080516020601f8401819004810282018101909252828152600091610a5491858580838501838280828437600092019190915250611ce992505050565b90506103e88111158015610a69575060045481115b610a855760405162461bcd60e51b815260040161050b90612d0b565b600555610c9e565b610b0184848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601881527f66696e616c697479536c617368526577617264526174696f000000000000000060208201529150611c8f9050565b15610b9b5760208114610b265760405162461bcd60e51b815260040161050b906131c7565b604080516020601f8401819004810282018101909252828152600091610b6491858580838501838280828437600092019190915250611ce992505050565b9050600a8110158015610b775750606481105b610b935760405162461bcd60e51b815260040161050b90612e21565b600655610c9e565b610c0f84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601881527f656e61626c654d616c6963696f7573566f7465536c617368000000000000000060208201529150611c8f9050565b15610c865760208114610c345760405162461bcd60e51b815260040161050b90612d40565b604080516020601f8401819004810282018101909252828152610c709190848480838501838280828437600092019190915250611cee92505050565b6007805460ff1916911515919091179055610c9e565b60405162461bcd60e51b815260040161050b90613169565b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a84848484604051610cd39493929190612bcf565b60405180910390a150505050565b609681565b61100281565b3361200014610d0d5760405162461bcd60e51b815260040161050b906130cd565b60005460ff16610d2f5760405162461bcd60e51b815260040161050b90612c9d565b6040517f07db600eebe2ac176be8dcebad61858c245a4961bb32ca2aa3d159b09aa0810e90600090a1505050565b334114610d7c5760405162461bcd60e51b815260040161050b9061311c565b60005460ff16610d9e5760405162461bcd60e51b815260040161050b90612c9d565b6003544311610dbf5760405162461bcd60e51b815260040161050b90613212565b3a15610ddd5760405162461bcd60e51b815260040161050b90612f5c565b60405163155853f360e21b8152611000906355614fcc90610e02908490600401612b84565b60206040518083038186803b158015610e1a57600080fd5b505afa158015610e2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e52919061294e565b610e5b57611147565b610e6361264f565b506001600160a01b0381166000908152600260208181526040928390208351606081018552815481526001820154928101929092529091015460ff161580159282019290925290610ebe576020810180516001019052610f17565b60016040820181905260208201819052805480820182556000919091527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b0384161790555b438152600554602082015181610f2957fe5b0661107557600060208201526040516335409f7f60e01b8152611000906335409f7f90610f5a908590600401612b84565b600060405180830381600087803b158015610f7457600080fd5b505af1158015610f88573d6000803e3d6000fd5b505050506120006001600160a01b031663f7a251d7600b610fa885611b3c565b60006040518463ffffffff1660e01b8152600401610fc8939291906132c5565b600060405180830381600087803b158015610fe257600080fd5b505af1925050508015610ff3575060015b611070573d808015611021576040519150601f19603f3d011682016040523d82523d6000602084013e611026565b606091505b50826001600160a01b03167fd7bc86ff5d08c8ab043edec743302aba2520e6635172a428bc956721db9e2d1c83602001518360405161106692919061325f565b60405180910390a2505b6110e1565b60045481602001518161108457fe5b066110e1576040516375abf10160e11b81526110009063eb57e202906110ae908590600401612b84565b600060405180830381600087803b1580156110c857600080fd5b505af11580156110dc573d6000803e3d6000fd5b505050505b6001600160a01b0382166000818152600260208181526040808420865181559186015160018301558581015191909201805460ff1916911515919091179055517fddb6012116e51abf5436d956a4f0ebd927e92c576ff96d7918290c8782291e3e9190a2505b5043600355565b60005460ff166111705760405162461bcd60e51b815260040161050b90612c9d565b604051630a83aaa960e31b81526110069063541d554890611195903390600401612b84565b60206040518083038186803b1580156111ad57600080fd5b505afa1580156111c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e5919061294e565b6112015760405162461bcd60e51b815260040161050b90612c01565b60075460ff166112235760405162461bcd60e51b815260040161050b90612c68565b6006546112305760146006555b8051514361010090910111801561125257504381602001516000015161010001115b61126e5760405162461bcd60e51b815260040161050b90612c38565b80602001516020015181600001516020015114801561129c5750806020015160600151816000015160600151145b156112b95760405162461bcd60e51b815260040161050b90612eb4565b8051604081015190511080156112d85750602081015160408101519051105b6112f45760405162461bcd60e51b815260040161050b90612dea565b6020810151518151511080156113195750806000015160400151816020015160400151105b8061134457508051516020820151511080156113445750806020015160400151816000015160400151105b8061135e5750806020015160400151816000015160400151145b61137a5760405162461bcd60e51b815260040161050b90612cd4565b61138c81600001518260400151611d16565b80156113a557506113a581602001518260400151611d16565b6113c15760405162461bcd60e51b815260040161050b90612d8b565b6060806110006001600160a01b0316633b071dcc6040518163ffffffff1660e01b815260040160006040518083038186803b1580156113ff57600080fd5b505afa158015611413573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261143b919081019061288b565b9150915060005b81518110156115785761146c82828151811061145a57fe5b60200260200101518560400151611eee565b15611570576006546040516309a99b4f60e41b815260646110028031909302049190639a99b4f0906114a49033908590600401612b98565b602060405180830381600087803b1580156114be57600080fd5b505af11580156114d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f69190612aa2565b506110006001600160a01b03166335409f7f85848151811061151457fe5b60200260200101516040518263ffffffff1660e01b81526004016115389190612b84565b600060405180830381600087803b15801561155257600080fd5b505af1158015611566573d6000803e3d6000fd5b5050505050611578565b600101611442565b50600061158a84604001516000611f52565b90506120006001600160a01b031663f7a251d7600b6115ac8760400151611f6e565b60006040518463ffffffff1660e01b81526004016115cc939291906132c5565b600060405180830381600087803b1580156115e657600080fd5b505af19250505080156115f7575060015b611669573d808015611625576040519150601f19603f3d011682016040523d82523d6000602084013e61162a565b606091505b50817fd58d1183100bd0932c0588f31c4205d6bc6168909765a96c41adbed3115f36288260405161165b9190612bbc565b60405180910390a250611695565b60405181907f7b78aadacff901d8b63d0dba4f86283d4db8aef27f9ed70413dd860f1c9532b690600090a25b50505050565b601481565b61100381565b60005460ff16156116c95760405162461bcd60e51b815260040161050b9061301a565b603260045560966005556000805460ff19166001179055565b61100081565b600381565b336110001461170e5760405162461bcd60e51b815260040161050b90612ee1565b60005460ff166117305760405162461bcd60e51b815260040161050b90612c9d565b60015461173c57611b34565b600154600090600019015b808211611b08576000805b8284101561186b5761176261264f565b600260006001878154811061177357fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff161515908201526005549091506004900481602001511115611855576004600554816117e057fe5b0481602001510381602001818152505080600260006001888154811061180257fe5b6000918252602080832091909101546001600160a01b0316835282810193909352604091820190208351815591830151600183015591909101516002909101805460ff191691151591909117905561185f565b600192505061186b565b50836001019350611752565b828411611a025761187a61264f565b600260006001868154811061188b57fe5b60009182526020808320909101546001600160a01b0316835282810193909352604091820190208151606081018352815481526001820154938101939093526002015460ff161515908201526005549091506004900481602001511115611973576004600554816118f857fe5b0481602001510381602001818152505080600260006001878154811061191a57fe5b6000918252602080832091909101546001600160a01b03168352828101939093526040918201902083518155918301516001808401919091559201516002909101805460ff19169115159190911790559150611a029050565b600260006001868154811061198457fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff191690558054806119c857fe5b600082815260209020810160001990810180546001600160a01b0319169055019055836119f55750611a02565b506000199092019161186b565b818015611a0c5750805b15611aeb576002600060018681548110611a2257fe5b60009182526020808320909101546001600160a01b031683528201929092526040018120818155600181810192909255600201805460ff19169055805484908110611a6957fe5b600091825260209091200154600180546001600160a01b039092169186908110611a8f57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506001805480611ac857fe5b600082815260209020810160001990810180546001600160a01b03191690550190555b82611af7575050611b08565b505060019091019060001901611747565b6040517fcfdb3b6ccaeccbdc68be3c59c840e3b3c90f0a7c491f5fff1cf56cfda200dd9c90600090a150505b565b61100481565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081611b57579050509050611b80836001600160a01b0316611fa9565b81600081518110611b8d57fe5b6020026020010181905250611ba143611fcc565b81600181518110611bae57fe5b6020908102919091010152611bc46102ca611fcc565b81600281518110611bd157fe5b6020026020010181905250611be542611fcc565b81600381518110611bf257fe5b6020026020010181905250611c0681611fdf565b9150505b919050565b611c17612672565b6000611c21612672565b611c29612684565b611c3a611c3586612069565b61208e565b90506000805b611c49836120d8565b15611c825780611c7557611c64611c5f846120f9565b612147565b63ffffffff16845260019150611c7a565b611c82565b600101611c40565b5091935090915050915091565b600081604051602001611ca29190612b68565b6040516020818303038152906040528051906020012083604051602001611cc99190612b68565b604051602081830303815290604052805190602001201490505b92915050565b015190565b8082015160009060ff811615611d08576001915081611d0e565b60009150815b505092915050565b60408051600480825260a0820190925260009160609190816020015b6060815260200190600190039081611d32575050604080516020808252818301909252919250606091908082018180368337019050509050611d778560000151611fcc565b82600081518110611d8457fe5b6020026020010181905250611d9f60208660200151836121c9565b611da8816121d9565b82600181518110611db557fe5b6020026020010181905250611dcd8560400151611fcc565b82600281518110611dda57fe5b6020026020010181905250611df560208660600151836121c9565b611dfe816121d9565b82600381518110611e0b57fe5b6020026020010181905250611e316020611e2484611fdf565b80519060200120836121c9565b6040805160b080825260e08201909252606091602082018180368337019050509050611e6181836000602061222f565b611e738187608001516020606061222f565b611e8181866080603061222f565b604080516001808252818301909252606091602082018180368337019050509050815160016020830182602086016066600019fa611ebe57600080fd5b506001611ecc826000612282565b60ff1614611ee1576000945050505050611ce3565b5060019695505050505050565b815181516000916001918114808314611f0a5760009250611f48565b600160208701838101602088015b600284838510011415611f43578051835114611f375760009650600093505b60209283019201611f18565b505050505b5090949350505050565b60008160200183511015611f6557600080fd5b50016020015190565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081611f89579050509050611b80836121d9565b60408051600560a21b8318601482015260348101909152606090611c06816121d9565b6060611ce3611fda8361229e565b6121d9565b60608151600014156120005750604080516000815260208101909152611c0a565b60608260008151811061200f57fe5b602002602001015190506000600190505b8351811015612050576120468285838151811061203957fe5b6020026020010151612384565b9150600101612020565b50611c06612063825160c060ff16612401565b82612384565b6120716126a4565b506040805180820190915281518152602082810190820152919050565b612096612684565b61209f826124d3565b6120a857600080fd5b60006120b7836020015161250d565b60208085015160408051808201909152868152920190820152915050919050565b60006120e26126a4565b505080518051602091820151919092015191011190565b6121016126a4565b61210a826120d8565b61211357600080fd5b6020820151600061212382612570565b80830160209586015260408051808201909152908152938401919091525090919050565b80516000901580159061215c57508151602110155b61216557600080fd5b6000612174836020015161250d565b9050808360000151101561219a5760405162461bcd60e51b815260040161050b90613051565b8251602080850151830180519284900392918310156121c057826020036101000a820491505b50949350505050565b9091018181526020918201910152565b60608151600114801561220b5750607f60f81b826000815181106121f957fe5b01602001516001600160f81b03191611155b15612217575080611c0a565b611ce36122298351608060ff16612401565b83612384565b60005b818110156106ca5783818151811061224657fe5b602001015160f81c60f81b85848060010195508151811061226357fe5b60200101906001600160f81b031916908160001a905350600101612232565b6000816001018351101561229557600080fd5b50016001015190565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166122e257506018612306565b6fffffffffffffffffffffffffffffffff19841661230257506010612306565b5060005b602081101561233c5781818151811061231b57fe5b01602001516001600160f81b031916156123345761233c565b600101612306565b60008160200390506060816040519080825280601f01601f191660200182016040528015612371576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b818310156123b557805183526020928301920161239d565b50855184518101855292509050808201602086015b818310156123e25780518352602092830192016123ca565b508651929092011591909101601f01601f191660405250905092915050565b606068010000000000000000831061242b5760405162461bcd60e51b815260040161050b90612dc2565b604080516001808252818301909252606091602082018180368337019050509050603784116124855782840160f81b8160008151811061246757fe5b60200101906001600160f81b031916908160001a9053509050611ce3565b60606124908561229e565b90508381510160370160f81b826000815181106124a957fe5b60200101906001600160f81b031916908160001a9053506124ca8282612384565b95945050505050565b80516000906124e457506000611c0a565b6020820151805160001a9060c082101561250357600092505050611c0a565b5060019392505050565b8051600090811a6080811015612527576000915050611c0a565b60b8811080612542575060c08110801590612542575060f881105b15612551576001915050611c0a565b60c08110156125655760b519019050611c0a565b60f519019050611c0a565b80516000908190811a608081101561258b5760019150612648565b60b88110156125a057607e1981019150612648565b60c08110156125f157600060b78203600186019550806020036101000a8651049150600181018201935050808310156125eb5760405162461bcd60e51b815260040161050b90612f31565b50612648565b60f88110156126065760be1981019150612648565b600060f78203600186019550806020036101000a865104915060018101820193505080831015611d0e5760405162461bcd60e51b815260040161050b90612f31565b5092915050565b604051806060016040528060008152602001600081526020016000151581525090565b60408051602081019091526000815290565b60405180604001604052806126976126a4565b8152602001600081525090565b604051806040016040528060008152602001600081525090565b600082601f8301126126ce578081fd5b81516126e16126dc82613318565b6132f1565b818152915060208083019084810160005b84811015612757578151870188603f82011261270d57600080fd5b8381015161271d6126dc82613338565b81815260408b8184860101111561273357600080fd5b6127428388840183870161335c565b508652505092820192908201906001016126f2565b505050505092915050565b60008083601f840112612773578182fd5b50813567ffffffffffffffff81111561278a578182fd5b6020830191508360208285010111156127a257600080fd5b9250929050565b600082601f8301126127b9578081fd5b81356127c76126dc82613338565b91508082528360208285010111156127de57600080fd5b8060208401602084013760009082016020015292915050565b600060a08284031215612808578081fd5b61281260a06132f1565b905081358152602082013560208201526040820135604082015260608201356060820152608082013567ffffffffffffffff81111561285057600080fd5b61285c848285016127a9565b60808301525092915050565b600060208284031215612879578081fd5b813561288481613388565b9392505050565b6000806040838503121561289d578081fd5b825167ffffffffffffffff808211156128b4578283fd5b81850186601f8201126128c5578384fd5b805192506128d56126dc84613318565b80848252602080830192508084018a8283890287010111156128f5578788fd5b8794505b8685101561292057805161290c81613388565b8452600194909401939281019281016128f9565b508801519096509350505080821115612937578283fd5b50612944858286016126be565b9150509250929050565b60006020828403121561295f578081fd5b81518015158114612884578182fd5b60008060008060408587031215612983578182fd5b843567ffffffffffffffff8082111561299a578384fd5b6129a688838901612762565b909650945060208701359150808211156129be578384fd5b506129cb87828801612762565b95989497509550505050565b6000602082840312156129e8578081fd5b813567ffffffffffffffff808211156129ff578283fd5b81840160608187031215612a11578384fd5b612a1b60606132f1565b9250803582811115612a2b578485fd5b612a37878284016127f7565b845250602081013582811115612a4b578485fd5b612a57878284016127f7565b602085015250604081013582811115612a6e578485fd5b612a7a878284016127a9565b6040850152509195945050505050565b600060208284031215612a9b578081fd5b5035919050565b600060208284031215612ab3578081fd5b5051919050565b600080600060408486031215612ace578283fd5b833560ff81168114612ade578384fd5b9250602084013567ffffffffffffffff811115612af9578283fd5b612b0586828701612762565b9497909650939450505050565b60008284528282602086013780602084860101526020601f19601f85011685010190509392505050565b60008151808452612b5481602086016020860161335c565b601f01601f19169290920160200192915050565b60008251612b7a81846020870161335c565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b901515815260200190565b6000602082526128846020830184612b3c565b600060408252612be3604083018688612b12565b8281036020840152612bf6818587612b12565b979650505050505050565b6020808252601f908201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604082015260600190565b6020808252601690820152751d1bdbc81bdb1908189b1bd8dac81a5b9d9bdb1d995960521b604082015260600190565b6020808252818101527f6d616c6963696f757320766f746520736c617368206e6f7420656e61626c6564604082015260600190565b60208082526019908201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604082015260600190565b6020808252601a908201527f6e6f2076696f6c6174696f6e206f6620766f74652072756c6573000000000000604082015260600190565b6020808252818101527f7468652066656c6f6e795468726573686f6c64206f7574206f662072616e6765604082015260600190565b6020808252602b908201527f6c656e677468206f6620656e61626c654d616c6963696f7573566f7465536c6160408201526a0e6d040dad2e6dac2e8c6d60ab1b606082015260800190565b60208082526017908201527f766572696679207369676e6174757265206661696c6564000000000000000000604082015260600190565b6020808252600e908201526d696e70757420746f6f206c6f6e6760901b604082015260600190565b60208082526019908201527f7372634e756d20626967676572207468616e207461724e756d00000000000000604082015260600190565b6020808252602c908201527f7468652066696e616c69747920736c6173682072657761726420726174696f2060408201526b6f7574206f662072616e676560a01b606082015260800190565b60208082526027908201527f6c656e677468206f66206d697364656d65616e6f725468726573686f6c64206d6040820152660d2e6dac2e8c6d60cb1b606082015260800190565b60208082526013908201527274776f206964656e746963616c20766f74657360681b604082015260600190565b60208082526030908201527f746865206d6573736167652073656e646572206d7573742062652076616c696460408201526f185d1bdc94d95d0818dbdb9d1c9858dd60821b606082015260800190565b6020808252601190820152706164646974696f6e206f766572666c6f7760781b604082015260600190565b6020808252601490820152736761737072696365206973206e6f74207a65726f60601b604082015260600190565b6020808252602e908201527f746865206d6573736167652073656e646572206d75737420626520676f76657260408201526d1b985b98d94818dbdb9d1c9858dd60921b606082015260800190565b60208082526022908201527f6c656e677468206f662066656c6f6e795468726573686f6c64206d69736d61746040820152610c6d60f31b606082015260800190565b60208082526019908201527f74686520636f6e747261637420616c726561647920696e697400000000000000604082015260600190565b6020808252601a908201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604082015260600190565b60208082526025908201527f746865206d697364656d65616e6f725468726573686f6c64206f7574206f662060408201526472616e676560d81b606082015260800190565b6020808252602f908201527f746865206d6573736167652073656e646572206d7573742062652063726f737360408201526e0818da185a5b8818dbdb9d1c9858dd608a1b606082015260800190565b6020808252602d908201527f746865206d6573736167652073656e646572206d75737420626520746865206260408201526c3637b1b590383937b23ab1b2b960991b606082015260800190565b6020808252600d908201526c756e6b6e6f776e20706172616d60981b604082015260600190565b6020808252601e908201527f7265636569766520756e65787065637465642073796e207061636b6167650000604082015260600190565b6020808252602b908201527f6c656e677468206f662066696e616c697479536c61736852657761726452617460408201526a0d2de40dad2e6dac2e8c6d60ab1b606082015260800190565b6020808252818101527f63616e206e6f7420736c61736820747769636520696e206f6e6520626c6f636b604082015260600190565b61ffff91909116815260200190565b90815260200190565b6000838252604060208301526132786040830184612b3c565b949350505050565b918252602082015260400190565b92835260208301919091521515604082015260600190565b63ffffffff91909116815260200190565b60ff91909116815260200190565b600060ff85168252606060208301526132e16060830185612b3c565b9050826040830152949350505050565b60405181810167ffffffffffffffff8111828210171561331057600080fd5b604052919050565b600067ffffffffffffffff82111561332e578081fd5b5060209081020190565b600067ffffffffffffffff82111561334e578081fd5b50601f01601f191660200190565b60005b8381101561337757818101518382015260200161335f565b838111156116955750506000910152565b6001600160a01b038116811461339d57600080fd5b5056fea2646970667358221220425f90ada15339392881582f35a21b784186e12ed634c463af0e608e49de659064736f6c63430006040033", + }, + { + ContractAddr: SystemRewardContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "6080604052600436106101a05760003560e01c80637942fd05116100ec578063ac4317511161008a578063f9a2bbc711610064578063f9a2bbc714610550578063fb5478b314610565578063fc3e59081461057a578063fd6a68791461058f576101e4565b8063ac43175114610457578063c81b166214610526578063dc927faf1461053b576101e4565b80639dc09262116100c65780639dc0926214610403578063a1a11bf514610418578063a78abc161461042d578063ab51bb9614610442576101e4565b80637942fd05146103a057806396713da9146103b55780639a99b4f0146103ca576101e4565b80634bf6c882116101595780636e47b482116101335780636e47b4821461034c57806370fd5bad14610361578063718a8aa81461037657806375d47a0a1461038b576101e4565b80634bf6c882146102db57806351e80672146102f05780636d70f7ae14610305576101e4565b80630bee7a67146101e95780630e2374a5146102175780633a0b0eff146102485780633dffc3871461026f57806343756e5c1461029a578063493279b1146102af576101e4565b366101e45734156101e25760408051348152905133917f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db919081900360200190a25b005b600080fd5b3480156101f557600080fd5b506101fe6105a4565b6040805163ffffffff9092168252519081900360200190f35b34801561022357600080fd5b5061022c6105a9565b604080516001600160a01b039092168252519081900360200190f35b34801561025457600080fd5b5061025d6105af565b60408051918252519081900360200190f35b34801561027b57600080fd5b506102846105b5565b6040805160ff9092168252519081900360200190f35b3480156102a657600080fd5b5061022c6105ba565b3480156102bb57600080fd5b506102c46105c0565b6040805161ffff9092168252519081900360200190f35b3480156102e757600080fd5b506102846105c6565b3480156102fc57600080fd5b5061022c6105cb565b34801561031157600080fd5b506103386004803603602081101561032857600080fd5b50356001600160a01b03166105d1565b604080519115158252519081900360200190f35b34801561035857600080fd5b5061022c6105ef565b34801561036d57600080fd5b506102846105f5565b34801561038257600080fd5b506102846105fa565b34801561039757600080fd5b5061022c6105ff565b3480156103ac57600080fd5b50610284610605565b3480156103c157600080fd5b5061028461060a565b3480156103d657600080fd5b5061025d600480360360408110156103ed57600080fd5b506001600160a01b03813516906020013561060f565b34801561040f57600080fd5b5061022c6107ba565b34801561042457600080fd5b5061022c6107c0565b34801561043957600080fd5b506103386107c6565b34801561044e57600080fd5b506101fe6107cf565b34801561046357600080fd5b506101e26004803603604081101561047a57600080fd5b81019060208101813564010000000081111561049557600080fd5b8201836020820111156104a757600080fd5b803590602001918460018302840111640100000000831117156104c957600080fd5b9193909290916020810190356401000000008111156104e757600080fd5b8201836020820111156104f957600080fd5b8035906020019184600183028401116401000000008311171561051b57600080fd5b5090925090506107d4565b34801561053257600080fd5b5061022c610b57565b34801561054757600080fd5b5061022c610b5d565b34801561055c57600080fd5b5061022c610b63565b34801561057157600080fd5b5061025d610b69565b34801561058657600080fd5b50610284610b75565b34801561059b57600080fd5b5061022c610b7a565b606481565b61200181565b60015481565b600181565b61100181565b6102ca81565b600881565b61200081565b6001600160a01b031660009081526002602052604090205460ff1690565b61100581565b600281565b601081565b61100881565b600b81565b600981565b6000805460ff1661068c57600260208190527fe57bda0a954a7c7381b17b2c763e646ba2c60f67292d287ba583603e2c1c41668054600160ff19918216811790925561100560009081527fe25235fc0de9d7165652bef0846fefda506174abb9a190f03d0f7bcc6146dbce80548316841790559282558254161790555b3360009081526002602052604090205460ff166106da5760405162461bcd60e51b815260040180806020018281038252602b815260200180610c68602b913960400191505060405180910390fd5b60004783106106e957476106eb565b825b9050670de0b6b3a76400008111156107085750670de0b6b3a76400005b8015610789576040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015610744573d6000803e3d6000fd5b506040805182815290516001600160a01b038616917ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0919081900360200190a26107b3565b6040517fe589651933c2457488cc0d8e0941518abf748e799435e4e396d9c4d0b2db2d4d90600090a15b9392505050565b61100781565b61100681565b60005460ff1681565b600081565b33611007146108145760405162461bcd60e51b815260040180806020018281038252602e815260200180610cc2602e913960400191505060405180910390fd5b61087684848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600b81526a30b23227b832b930ba37b960a91b60208201529150610b809050565b1561094e57606082828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050825192935050601490911490506108f95760405162461bcd60e51b815260040180806020018281038252602c815260200180610cf0602c913960400191505060405180910390fd5b60148101516001600160a01b038116600081815260026020526040808220805460ff19166001179055517f9870d7fe5d112134c55844951dedf365363006d9c588db07c4c85af6322a06199190a25050610ac5565b6109b384848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600e81526d3232b632ba32a7b832b930ba37b960911b60208201529150610b809050565b15610a8857606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060149091149050610a365760405162461bcd60e51b815260040180806020018281038252602f815260200180610c93602f913960400191505060405180910390fd5b60148101516001600160a01b038116600081815260026020526040808220805460ff19169055517fb40992a19dba61ea600e87fce607102bf5908dc89076217b6ca6ae195224f7029190a25050610ac5565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b61100081565b670de0b6b3a764000081565b600381565b61100481565b6000816040516020018082805190602001908083835b60208310610bb55780518252601f199092019160209182019101610b96565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b60208310610c235780518252601f199092019160209182019101610c04565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001201490509291505056fe6f6e6c79206f70657261746f7220697320616c6c6f77656420746f2063616c6c20746865206d6574686f646c656e677468206f662076616c756520666f722064656c6574654f70657261746f722073686f756c64206265203230746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f72206164644f70657261746f722073686f756c64206265203230a2646970667358221220dfab8b447e80ff45b4921032d6fc749c076c81bafdd35dc3adbf21cb41cdac7964736f6c63430006040033", + }, + { + ContractAddr: RelayerHubContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "608060405234801561001057600080fd5b50600436106102275760003560e01c80638f83ab1311610130578063c81b1662116100b8578063f3ae24151161007c578063f3ae2415146104e8578063f9a2bbc71461050e578063fc3e590814610516578063fd30d9b81461051e578063fd6a68791461052657610227565b8063c81b1662146104c0578063dc927faf146104c8578063dd91d1c5146104d0578063e1c7392a146104d8578063e79a198f146104e057610227565b8063a1a11bf5116100ff578063a1a11bf5146103de578063a74b83ca146103e6578063a78abc16146103ee578063ab51bb96146103f6578063ac431751146103fe57610227565b80638f83ab13146103a057806395468d26146103c657806396713da9146103ce5780639dc09262146103d657610227565b8063541d5548116101b3578063718a8aa811610182578063718a8aa81461034857806375d47a0a1461035057806378beee67146103585780637942fd051461037e5780637ae230881461038657610227565b8063541d5548146102d85780636a6a419e146103125780636e47b4821461033857806370fd5bad1461034057610227565b80633dffc387116101fa5780633dffc3871461028357806343756e5c146102a1578063493279b1146102a95780634bf6c882146102c857806351e80672146102d057610227565b806303aff02b1461022c578063049a5716146102365780630bee7a671461025a5780630e2374a51461027b575b600080fd5b61023461052e565b005b61023e610539565b604080516001600160a01b039092168252519081900360200190f35b610262610551565b6040805163ffffffff9092168252519081900360200190f35b61023e610556565b61028b61055c565b6040805160ff9092168252519081900360200190f35b61023e610561565b6102b1610567565b6040805161ffff9092168252519081900360200190f35b61028b61056d565b61023e610572565b6102fe600480360360208110156102ee57600080fd5b50356001600160a01b0316610578565b604080519115158252519081900360200190f35b6102fe6004803603602081101561032857600080fd5b50356001600160a01b0316610596565b61023e6105b4565b61028b6105ba565b61028b6105bf565b61023e6105c4565b6102346004803603602081101561036e57600080fd5b50356001600160a01b03166105ca565b61028b6107b2565b61038e6107b7565b60408051918252519081900360200190f35b610234600480360360208110156103b657600080fd5b50356001600160a01b03166107c4565b61038e610a03565b61028b610a0f565b61023e610a14565b61023e610a1a565b61023e610a20565b6102fe610a38565b610262610a41565b6102346004803603604081101561041457600080fd5b81019060208101813564010000000081111561042f57600080fd5b82018360208201111561044157600080fd5b8035906020019184600183028401116401000000008311171561046357600080fd5b91939092909160208101903564010000000081111561048157600080fd5b82018360208201111561049357600080fd5b803590602001918460018302840111640100000000831117156104b557600080fd5b509092509050610a46565b61023e610d97565b61023e610d9d565b610234610da3565b610234610e44565b610234610ec6565b6102fe600480360360208110156104fe57600080fd5b50356001600160a01b031661107f565b61023e61109d565b61028b6110a3565b6102fe6110a8565b61023e6110b1565b610537336110b7565b565b7388cb4d8f77742c24d647bef8049d3f3c56067cdd81565b606481565b61200181565b600181565b61100181565b6102ca81565b600881565b61200081565b6001600160a01b031660009081526007602052604090205460ff1690565b6001600160a01b031660009081526008602052604090205460ff1690565b61100581565b600281565b601081565b61100881565b3360009081526008602052604090205460ff166106185760405162461bcd60e51b81526004018080602001828103825260248152602001806115c36024913960400191505060405180910390fd5b61062133611219565b1561065d5760405162461bcd60e51b81526004018080602001828103825260218152602001806115806021913960400191505060405180910390fd5b3233146106b1576040805162461bcd60e51b815260206004820152601e60248201527f70726f766973696f6e616c2072656c6179657220697320612070726f78790000604482015290519081900360640190fd5b6001600160a01b038181166000908152600960205260409020541633146107095760405162461bcd60e51b815260040180806020018281038252602781526020018061163c6027913960400191505060405180910390fd5b6001600160a01b03818116600081815260066020908152604080832080543380865260078086528487208054600160ff199182161790915584546001600160a01b031990811684179095556008875285882080548216905597875260098652848720805490941690935596168085529083529281902080549094169093558251828152908101939093528151909260008051602061166383398151915292908290030190a15050565b600b81565b68056bc75e2d6310000081565b3360009081526005602052604090205460ff16610821576040805162461bcd60e51b81526020600482015260166024820152751b585b9859d95c88191bd95cc81b9bdd08195e1a5cdd60521b604482015290519081900360640190fd5b61082a81611219565b156108665760405162461bcd60e51b81526004018080602001828103825260278152602001806115e76027913960400191505060405180910390fd5b6001600160a01b03811615610922576001600160a01b03811660009081526007602052604090205460ff16156108dc576040805162461bcd60e51b815260206004820152601660248201527572656c6179657220616c72656164792065786973747360501b604482015290519081900360640190fd5b6001600160a01b0381166000818152600860209081526040808320805460ff191660011790553383526009909152902080546001600160a01b03191690911790556109c3565b3360008181526006602090815260408083208054600980855283862080546001600160a01b03198085169095556001600160a01b0393841680895260078852868920805460ff19908116909155918516808a5260088952878a20805490931690925598909752908552805490921690915581518581529086169281019290925280516000805160206116638339815191529281900390910190a15050610a00565b604080516001600160a01b038316815290517ffba56633276570c7d3120d4535bf3bce26523da53958e40734210b9fd99b36939181900360200190a15b50565b67016345785d8a000081565b600981565b61100781565b61100681565b7342d596440775c90db8d9187b47650986e106349381565b60005460ff1681565b600081565b60005460ff16610a99576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b3361100714610ad95760405162461bcd60e51b815260040180806020018281038252602e81526020018061160e602e913960400191505060405180910390fd5b610b3a84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600a81526930b23226b0b730b3b2b960b11b6020820152915061121f9050565b15610bd25760148114610b7e5760405162461bcd60e51b81526004018080602001828103825260228152602001806115a16022913960400191505060405180910390fd5b6000610bc1601484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061130692505050565b9050610bcc8161130b565b50610d05565b610c3684848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c3932b6b7bb32a6b0b730b3b2b960991b6020820152915061121f9050565b15610cc85760148114610c7a5760405162461bcd60e51b81526004018080602001828103825260228152602001806115a16022913960400191505060405180910390fd5b6000610cbd601484848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061130692505050565b9050610bcc816110b7565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b61100281565b61100381565b600a5460ff1615610dfb576040805162461bcd60e51b815260206004820152601e60248201527f7468652077686974656c6973747320616c726561647920757064617465640000604482015290519081900360640190fd5b610e187388cb4d8f77742c24d647bef8049d3f3c56067cdd6113cd565b610e357342d596440775c90db8d9187b47650986e10634936113cd565b600a805460ff19166001179055565b60005460ff1615610e9c576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b68056bc75e2d63100000600190815567016345785d8a00006002556000805460ff19169091179055565b3360009081526004602052604090205460ff16610f21576040805162461bcd60e51b81526020600482015260146024820152731c995b185e595c88191bc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b60005460ff16610f74576040805162461bcd60e51b81526020600482015260196024820152781d1a194818dbdb9d1c9858dd081b9bdd081a5b9a5d081e595d603a1b604482015290519081900360640190fd5b610f7c611565565b5033600081815260036020908152604091829020825180840190935280548084526001909101549183018290529192916108fc91610fc0919063ffffffff61148516565b6040518115909202916000818181858888f19350505050158015610fe8573d6000803e3d6000fd5b50602081015160405161100291829181156108fc0291906000818181858888f1935050505015801561101e573d6000803e3d6000fd5b50336000818152600460209081526040808320805460ff191690556003825280832083815560010192909255815192835290517fd17202129b83db7880d6b9f25df81c58ad46f7e0e2c92236b1aa10663a4876679281900390910190a15050565b6001600160a01b031660009081526005602052604090205460ff1690565b61100081565b600381565b600a5460ff1681565b61100481565b6001600160a01b03811660009081526005602052604090205460ff1661111c576040805162461bcd60e51b81526020600482015260156024820152741b585b9859d95c88191bd95cdb89dd08195e1a5cdd605a1b604482015290519081900360640190fd5b6001600160a01b038082166000818152600660209081526040808320805460058452828520805460ff1990811690915582546001600160a01b0319908116909355600980865284872080548a16885260088752858820805490931690925595879052948452845490911690935580519384525191909316927f2002866d443ac6c241fecaaa2af4895828c7de2cc423b9d01f7969650f557c76928290030190a16001600160a01b03811615611215576001600160a01b0381166000818152600760209081526040808320805460ff1916905580519384529083019190915280516000805160206116638339815191529281900390910190a15b5050565b3b151590565b6000816040516020018082805190602001908083835b602083106112545780518252601f199092019160209182019101611235565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106112c25780518252601f1990920191602091820191016112a3565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b6001600160a01b03811660009081526005602052604090205460ff1615611372576040805162461bcd60e51b81526020600482015260166024820152756d616e6167657220616c72656164792065786973747360501b604482015290519081900360640190fd5b6001600160a01b038116600081815260056020908152604091829020805460ff19166001179055815192835290517fe0de8e71a22c046647f4ef744348fa126ad6d052d4ce070999481f69d45575179281900390910190a150565b6001600160a01b03811660008181526005602090815260408083208054600160ff1991821681179092556006845282852080546001600160a01b031916871790556007845293829020805490941617909255815192835290517fe0de8e71a22c046647f4ef744348fa126ad6d052d4ce070999481f69d45575179281900390910190a160408051600081526001600160a01b03831660208201528151600080516020611663833981519152929181900390910190a150565b60006114c783836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506114ce565b9392505050565b6000818484111561155d5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561152257818101518382015260200161150a565b50505050905090810190601f16801561154f5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60405180604001604052806000815260200160008152509056fe70726f766973696f6e616c2072656c61796572206973206120636f6e74726163746c656e677468206f66206d616e616765722061646472657373206d69736d6174636872656c61796572206973206e6f7420612070726f766973696f6e616c2072656c61796572636f6e7472616374206973206e6f7420616c6c6f77656420746f20626520612072656c61796572746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e747261637470726f766973696f6e616c206973206e6f742073657420666f722074686973206d616e61676572a5a19d7e9dab30a215022382d7abe782b579986fcbedec9942ecd0db9510a148a2646970667358221220243ef96c0e2d17d4e167cfcbcb6a51b4b92c1ac27fcb61400a87275f5128b4ab64736f6c63430006040033", + }, + { + ContractAddr: CrossChainContract, + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/b144718e94d7a1ebb24a7103202300f08826f369", + Code: "608060405234801561001057600080fd5b50600436106103995760003560e01c8063718a8aa8116101e9578063c27cdcfb1161010f578063dc927faf116100ad578063f7a251d71161007c578063f7a251d714610b2f578063f9a2bbc714610ba7578063fc3e590814610baf578063fd6a687914610bb757610399565b8063dc927faf14610af7578063e1c7392a14610aff578063e3b0480514610b07578063e6400bbe14610b2757610399565b8063ccc108d7116100e9578063ccc108d714610ab0578063d31f968d14610ab8578063d76a867514610ae7578063dc40433114610aef57610399565b8063c27cdcfb14610a80578063c780e9de14610aa0578063c81b166214610aa857610399565b80638cc8f56111610187578063a78abc1611610156578063a78abc16146109b2578063ab51bb96146109ba578063ac431751146109c2578063b0355f5b1461078157610399565b80638cc8f5611461088757806396713da91461099a5780639dc09262146109a2578063a1a11bf5146109aa57610399565b806375d47a0a116101c357806375d47a0a146108a75780637942fd05146108af57806384013b6a146108b7578063863fe4ab1461099257610399565b8063718a8aa81461088f578063719482d51461089757806374f079b81461089f57610399565b8063422f9050116102ce57806363e1394e1161026c5780636de380bd1161023b5780636de380bd146108575780636e47a51a1461085f5780636e47b4821461087f57806370fd5bad1461088757610399565b806363e1394e146107ff5780636a3cb34d146108075780636bacff2c1461080f5780636c46aa681461080757610399565b80634bf6c882116102a85780634bf6c882146107b957806351e80672146107c15780635692ddd3146107c95780635f832177146107d157610399565b8063422f90501461078957806343756e5c146107a9578063493279b1146107b157610399565b8063299b533d1161033b578063308325f411610315578063308325f4146106155780633a648b151461061d5780633bdc47a6146106595780633dffc3871461078157610399565b8063299b533d146105a35780632af6f399146105d75780632ff32aea146105f457610399565b806314b3023b1161037757806314b3023b146104015780631d1309351461041b5780631e275ae11461043757806322556cdc1461059b57610399565b806305e682581461039e5780630bee7a67146103bc5780630e2374a5146103dd575b600080fd5b6103a6610bbf565b6040805160ff9092168252519081900360200190f35b6103c4610bc4565b6040805163ffffffff9092168252519081900360200190f35b6103e5610bc9565b604080516001600160a01b039092168252519081900360200190f35b610409610bcf565b60408051918252519081900360200190f35b610423610bd5565b604080519115158252519081900360200190f35b610599600480360361010081101561044e57600080fd5b81018160a081016080820135600160201b81111561046b57600080fd5b82018360208201111561047d57600080fd5b803590602001918460018302840111600160201b8311171561049e57600080fd5b919390929091602081019035600160201b8111156104bb57600080fd5b8201836020820111156104cd57600080fd5b803590602001918460018302840111600160201b831117156104ee57600080fd5b919390929091602081019035600160201b81111561050b57600080fd5b82018360208201111561051d57600080fd5b803590602001918460018302840111600160201b8311171561053e57600080fd5b919390929091602081019035600160201b81111561055b57600080fd5b82018360208201111561056d57600080fd5b803590602001918460018302840111600160201b8311171561058e57600080fd5b509092509050610bde565b005b6104096112c2565b6105c0600480360360208110156105b957600080fd5b50356112c7565b6040805161ffff9092168252519081900360200190f35b610423600480360360208110156105ed57600080fd5b50356112dd565b6105fc6112f2565b60408051600792830b90920b8252519081900360200190f35b6104096112fb565b61063d6004803603602081101561063357600080fd5b503560ff16611301565b604080516001600160401b039092168252519081900360200190f35b61070c6004803603606081101561066f57600080fd5b60ff82351691602081013591810190606081016040820135600160201b81111561069857600080fd5b8201836020820111156106aa57600080fd5b803590602001918460018302840111600160201b831117156106cb57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061131c945050505050565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561074657818101518382015260200161072e565b50505050905090810190601f1680156107735780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103a6611392565b6104236004803603602081101561079f57600080fd5b503560ff16611397565b6103e56113ac565b6105c06113b2565b6103a66113b8565b6103e56113bd565b6104096113c3565b610599600480360360408110156107e757600080fd5b506001600160a01b03813581169160200135166113f3565b610409611653565b6105c061167b565b61082c6004803603602081101561082557600080fd5b5035611680565b6040805161ffff90941684526001600160801b03909216602084015282820152519081900360600190f35b6104096116af565b6103e56004803603602081101561087557600080fd5b503560ff166116d6565b6103e56116f1565b6103a661167b565b6103a66116f7565b6105c0611392565b6104096116fc565b6103e5611702565b6103a6611708565b610599600480360360a08110156108cd57600080fd5b810190602081018135600160201b8111156108e757600080fd5b8201836020820111156108f957600080fd5b803590602001918460018302840111600160201b8311171561091a57600080fd5b919390929091602081019035600160201b81111561093757600080fd5b82018360208201111561094957600080fd5b803590602001918460018302840111600160201b8311171561096a57600080fd5b919350915080356001600160401b03908116916020810135909116906040013560ff1661170d565b6104096129c7565b6103a66129cf565b6103e56129d4565b6103e56129da565b6104236129e0565b6103c4610bbf565b610599600480360360408110156109d857600080fd5b810190602081018135600160201b8111156109f257600080fd5b820183602082011115610a0457600080fd5b803590602001918460018302840111600160201b83111715610a2557600080fd5b919390929091602081019035600160201b811115610a4257600080fd5b820183602082011115610a5457600080fd5b803590602001918460018302840111600160201b83111715610a7557600080fd5b5090925090506129e9565b61063d60048036036020811015610a9657600080fd5b503560ff166134ad565b6104096134c8565b6103e56134ec565b6105996134f2565b61042360048036036040811015610ace57600080fd5b5080356001600160a01b0316906020013560ff16613746565b61070c613766565b610409613785565b6103e561378b565b610599613791565b61063d60048036036020811015610b1d57600080fd5b503560ff16613b48565b610599613b63565b61059960048036036060811015610b4557600080fd5b60ff8235169190810190604081016020820135600160201b811115610b6957600080fd5b820183602082011115610b7b57600080fd5b803590602001918460018302840111600160201b83111715610b9c57600080fd5b919350915035613d82565b6103e5613ec5565b6103a6613ecb565b6103e5613ed0565b600081565b606481565b61200181565b60015481565b600b5460ff1681565b60005460ff16610c23576040805162461bcd60e51b815260206004820152601960248201526000805160206149b4833981519152604482015290519081900360640190fd5b604080516337d7f9c160e21b81526001600160401b038b35166004820181905291516110039163df5fe704916024808301926020929190829003018186803b158015610c6e57600080fd5b505afa158015610c82573d6000803e3d6000fd5b505050506040513d6020811015610c9857600080fd5b5051610cd55760405162461bcd60e51b81526004018080602001828103825260238152602001806149d46023913960400191505060405180910390fd5b604080516337d7f9c160e21b815260208c8101356001600160401b03166004830181905292516110039263df5fe704926024808301939192829003018186803b158015610d2157600080fd5b505afa158015610d35573d6000803e3d6000fd5b505050506040513d6020811015610d4b57600080fd5b5051610d885760405162461bcd60e51b81526004018080602001828103825260238152602001806149d46023913960400191505060405180910390fd5b60608b013560ff81166000908152600560205260409020546001600160401b03909116906001600160a01b0316610e01576040805162461bcd60e51b815260206004820152601860248201527718da185b9b995b081a5cc81b9bdd081cdd5c1c1bdc9d195960421b604482015290519081900360640190fd5b600b5460ff1615610e45576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b8888604051808383808284376040519201829003822094508f93508e9250819050838380828437808301925050509250505060405180910390201415610ec1576040805162461bcd60e51b815260206004820152600c60248201526b1cd85b59481c185e5b1bd85960a21b604482015290519081900360640190fd5b60606001600160401b0360408e01358116908e83013516610ee28282613ed6565b80516020808301919091206000818152600e9092526040909120549194509060ff1615610f4b576040805162461bcd60e51b8152602060048201526012602482015271185b1c9958591e4818da185b1b195b99d95960721b604482015290519081900360640190fd5b6000908152600e60205260408120805460ff191660011790558f8160200201356001600160401b0316905060608f8f8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052506040805163cba510a960e01b81526001600160401b038a16600482015290519596509094611003945063cba510a9935060248083019350602092829003018186803b15801561104157600080fd5b505afa158015611055573d6000803e3d6000fd5b505050506040513d602081101561106b57600080fd5b505160408051808201909152600381526269626360e81b6020820152909150611098908290898686613f1e565b6110e1576040805162461bcd60e51b81526020600482015260156024820152740696e76616c6964206d65726b6c652070726f6f663605c1b604482015290519081900360640190fd5b5050505060008f6001600481106110f457fe5b60200201356001600160401b0316905060608d8d8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8f018190048102820181019092528d815293945060609392508d91508c908190840183828082843760009201829052506040805163cba510a960e01b81526001600160401b038a16600482015290519596509094611003945063cba510a9935060248083019350602092829003018186803b1580156111c057600080fd5b505afa1580156111d4573d6000803e3d6000fd5b505050506040513d60208110156111ea57600080fd5b505160408051808201909152600381526269626360e81b6020820152909150611217908290898686613f1e565b611260576040805162461bcd60e51b8152602060048201526015602482015274696e76616c6964206d65726b6c652070726f6f663160581b604482015290519081900360640190fd5b5050505061126c61401b565b604080516001600160401b038416815260ff83166020820152815133927f039eb91179ffd7d3b6e97f8ea106e748e827f910b872375dbc9c14a362319c3c928290030190a2505050505050505050505050505050565b603281565b600d6020526000908152604090205461ffff1681565b600e6020526000908152604090205460ff1681565b60045460070b81565b60025481565b600a602052600090815260409020546001600160401b031681565b60606000825160210190506060816040519080825280601f01601f191660200182016040528015611354576020820181803683370190505b506021810186905260018101879052828152905060418101600061137786614099565b509050611386818388516140a3565b50909695505050505050565b600181565b60096020526000908152604090205460ff1681565b61100181565b6102ca81565b600881565b61200081565b604080517710d05390d15317d514905394d1915497d41493d413d4d05360421b8152905190819003601801902081565b60005460ff16611438576040805162461bcd60e51b815260206004820152601960248201526000805160206149b4833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b15801561147b57600080fd5b505afa15801561148f573d6000803e3d6000fd5b505050506040513d60208110156114a557600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b1580156114e657600080fd5b505afa1580156114fa573d6000803e3d6000fd5b505050506040513d602081101561151057600080fd5b505190508061151d575060155b60008211801561152d5750808211155b61156c576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b604080516001600160a01b038087166020808401919091529086168284015282518083038401815260608301808552815191909201207710d05390d15317d514905394d1915497d41493d413d4d05360421b90915291519081900360780190206000906115d990836140e4565b9050801561164b5760408051630911a2c160e11b81526001600160a01b03888116600483015287166024820152905161100491631223458291604480830192600092919082900301818387803b15801561163257600080fd5b505af1158015611646573d6000803e3d6000fd5b505050505b505050505050565b604080516f14d554d411539117d41493d413d4d05360821b8152905190819003601001902081565b600281565b600c602052600090815260409020805460019091015461ffff8216916201000090046001600160801b03169083565b604080516e149153d4115397d41493d413d4d053608a1b8152905190819003600f01902081565b6005602052600090815260409020546001600160a01b031681565b61100581565b601081565b60035481565b61100881565b600b81565b60005460ff16611752576040805162461bcd60e51b815260206004820152601960248201526000805160206149b4833981519152604482015290519081900360640190fd5b60408051630a83aaa960e31b815233600482015290516110069163541d5548916024808301926020929190829003018186803b15801561179157600080fd5b505afa1580156117a5573d6000803e3d6000fd5b505050506040513d60208110156117bb57600080fd5b505161180e576040805162461bcd60e51b815260206004820152601f60248201527f746865206d73672073656e646572206973206e6f7420612072656c6179657200604482015290519081900360640190fd5b60ff8116600090815260086020526040902054829082906001600160401b03908116908316811461187e576040805162461bcd60e51b815260206004820152601560248201527439b2b8bab2b731b2903737ba1034b71037b93232b960591b604482015290519081900360640190fd5b60ff8216600090815260086020908152604091829020805467ffffffffffffffff1916600185016001600160401b039081169190911790915582516337d7f9c160e21b81529089166004820152915188926110039263df5fe70492602480840193829003018186803b1580156118f357600080fd5b505afa158015611907573d6000803e3d6000fd5b505050506040513d602081101561191d57600080fd5b505161195a5760405162461bcd60e51b81526004018080602001828103825260238152602001806149d46023913960400191505060405180910390fd5b60ff851660009081526005602052604090205485906001600160a01b03166119c4576040805162461bcd60e51b815260206004820152601860248201527718da185b9b995b081a5cc81b9bdd081cdd5c1c1bdc9d195960421b604482015290519081900360640190fd5b60ff86166000908152600a6020526040902054889087906001600160401b039081169083161015611a2d576040805162461bcd60e51b815260206004820152600e60248201526d3a37b79037b632103432b0b232b960911b604482015290519081900360640190fd5b60ff81166000908152600a60205260409020546001600160401b03838116911614611a7f5760ff81166000908152600a60205260409020805467ffffffffffffffff19166001600160401b0384161790555b600b5460ff1615611ac3576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b60608e8e8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905060608d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509050611c076110036001600160a01b031663cba510a98e6040518263ffffffff1660e01b815260040180826001600160401b03166001600160401b0316815260200191505060206040518083038186803b158015611bb057600080fd5b505afa158015611bc4573d6000803e3d6000fd5b505050506040513d6020811015611bda57600080fd5b505160408051808201909152600381526269626360e81b6020820152611c008e8e613ed6565b8585613f1e565b611c4f576040805162461bcd60e51b815260206004820152601460248201527334b73b30b634b21036b2b935b63290383937b7b360611b604482015290519081900360640190fd5b60408051631bb5062960e31b81526001600160401b038e16600482015290516000916110039163dda8314891602480820192602092909190829003018186803b158015611c9b57600080fd5b505afa158015611caf573d6000803e3d6000fd5b505050506040513d6020811015611cc557600080fd5b505190508b8b600080806060611cda896143c9565b935093509350935083611d9c578460ff16866001600160401b03167ff7b2e42d694eb1100184aae86d4245d9e46966100b1dc7e723275b98326854ac8b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611d54578181015183820152602001611d3c565b50505050905090810190601f168015611d815780820380516001836020036101000a031916815260200191505b509250505060405180910390a35050505050505050506129b7565b6040805160ff85811682529151918716916001600160401b038916917f36afdaf439a8f43fe72135135d804ae620b37a474f0943b5b85f6788312cad40919081900360200190a360ff83166123215760ff85166000818152600560209081526040808320548151631182b87560e01b815260048101958652602481019283528651604482015286516001600160a01b03909216958695631182b875958d958a9593949093606490910192918601918190849084905b83811015611e69578181015183820152602001611e51565b50505050905090810190601f168015611e965780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b158015611eb657600080fd5b505af1925050508015611f9a57506040513d6000823e601f3d908101601f191682016040526020811015611ee957600080fd5b8101908080516040519392919084600160201b821115611f0857600080fd5b908301906020820185811115611f1d57600080fd5b8251600160201b811182820188101715611f3657600080fd5b82525081516020918201929091019080838360005b83811015611f63578181015183820152602001611f4b565b50505050905090810190601f168015611f905780820380516001836020036101000a031916815260200191505b5060405250505060015b6122ac576040516000815260443d1015611fb657506000612051565b60046000803e60005160e01c6308c379a08114611fd7576000915050612051565b60043d036004833e81513d60248201116001600160401b038211171561200257600092505050612051565b80830180516001600160401b03811115612023576000945050505050612051565b8060208301013d860181111561204157600095505050505050612051565b601f01601f191660405250925050505b8061205c575061216e565b60ff8716600090815260076020526040812054612093916001600160401b0390911690899061208e906002908861131c565b614479565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf948794849390840192918601918190849084905b8381101561212e578181015183820152602001612116565b50505050905090810190601f16801561215b5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2506122a7565b3d808015612198576040519150601f19603f3d011682016040523d82523d6000602084013e61219d565b606091505b5060ff87166000908152600760205260408120546121d0916001600160401b0390911690899061208e906002908861131c565b60ff8716600090815260076020908152604080832080546001600160401b038082166001011667ffffffffffffffff19909116179055805182815284518184015284516001600160a01b038716947f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351948794849390840192918601918190849084905b8381101561226b578181015183820152602001612253565b50505050905090810190601f1680156122985780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b61231b565b8051156123195760ff87166000908152600760205260408120546122e5916001600160401b0390911690899061208e906001908661131c565b60ff8716600090815260076020526040902080546001600160401b038082166001011667ffffffffffffffff199091161790555b505b506128ef565b60ff8316600114156125c55760ff8516600081815260056020908152604080832054815163831d65d160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563831d65d1958d958a9593949093606490910192918601918190849084905b838110156123ab578181015183820152602001612393565b50505050905090810190601f1680156123d85780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156123f857600080fd5b505af1925050508015612409575060015b61231b576040516000815260443d1015612425575060006124c0565b60046000803e60005160e01c6308c379a081146124465760009150506124c0565b60043d036004833e81513d60248201116001600160401b0382111715612471576000925050506124c0565b80830180516001600160401b038111156124925760009450505050506124c0565b8060208301013d86018111156124b0576000955050505050506124c0565b601f01601f191660405250925050505b806124cb5750612530565b60408051602080825283518183015283516001600160a01b038616937ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf938693909283928301918501908083836000831561212e578181015183820152602001612116565b3d80801561255a576040519150601f19603f3d011682016040523d82523d6000602084013e61255f565b606091505b5060408051602080825283518183015283516001600160a01b038616937f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351938693909283928301918501908083836000831561226b578181015183820152602001612253565b60ff8316600214156128ef5760ff8516600081815260056020908152604080832054815163c8509d8160e01b815260048101958652602481019283528651604482015286516001600160a01b0390921695869563c8509d81958d958a9593949093606490910192918601918190849084905b8381101561264f578181015183820152602001612637565b50505050905090810190601f16801561267c5780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b15801561269c57600080fd5b505af19250505080156126ad575060015b6128ed576040516000815260443d10156126c957506000612764565b60046000803e60005160e01c6308c379a081146126ea576000915050612764565b60043d036004833e81513d60248201116001600160401b038211171561271557600092505050612764565b80830180516001600160401b03811115612736576000945050505050612764565b8060208301013d860181111561275457600095505050505050612764565b601f01601f191660405250925050505b8061276f5750612818565b816001600160a01b03167ff91a8f63e5b3e0e89e5f93e1915a7805f3c52d9a73b3c09769785c2c7bf87acf826040518080602001828103825283818151815260200191508051906020019080838360005b838110156127d85781810151838201526020016127c0565b50505050905090810190601f1680156128055780820380516001836020036101000a031916815260200191505b509250505060405180910390a2506128ed565b3d808015612842576040519150601f19603f3d011682016040523d82523d6000602084013e612847565b606091505b50816001600160a01b03167f63ac299d6332d1cc4e61b81e59bc00c0ac7c798addadf33840f1307cd2977351826040518080602001828103825283818151815260200191508051906020019080838360005b838110156128b1578181015183820152602001612899565b50505050905090810190601f1680156128de5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505b505b60ff80861660009081526009602052604090205461100591636f93d2e6918a91339187911680612921575060ff881615155b604080516001600160e01b031960e088901b1681526001600160a01b039586166004820152939094166024840152604483019190915215156064820152905160848083019260209291908290030181600087803b15801561298157600080fd5b505af1158015612995573d6000803e3d6000fd5b505050506040513d60208110156129ab57600080fd5b50505050505050505050505b5050505050505050505050505050565b630102ca0081565b600981565b61100781565b61100681565b60005460ff1681565b3361100714612a295760405162461bcd60e51b815260040180806020018281038252602e81526020018061490a602e913960400191505060405180910390fd5b600b5460ff1615612a6d576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b612ad684848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526012815271626174636853697a65466f724f7261636c6560701b602082015291506146149050565b15612b7157604080516020601f8401819004810282018101909252828152600091612b19918585808385018382808284376000920191909152506146fb92505050565b90506127108111158015612b2e5750600a8110155b612b695760405162461bcd60e51b81526004018080602001828103825260328152602001806149826032913960400191505060405180910390fd5b60015561341b565b612bda84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601281527118591913dc955c19185d1950da185b9b995b60721b602082015291506146149050565b15612d6257606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060169091149050612c5d5760405162461bcd60e51b815260040180806020018281038252605a815260200180614823605a913960600191505060405180910390fd5b60018101516002820151601683015160ff82161590612c7b81614700565b612ccc576040805162461bcd60e51b815260206004820152601960248201527f61646472657373206973206e6f74206120636f6e747261637400000000000000604482015290519081900360640190fd5b60ff8416600081815260056020908152604080832080546001600160a01b0319166001600160a01b038716908117909155808452600683528184208585528352818420805460ff199081166001179091556009909352818420805490931687151517909255519092917f7e3b6af43092577ee20e60eaa1d9b114a7031305c895ee7dd3ffe17196d2e1e091a3505050505061341b565b612dcf84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080518082019091526016815275195b98589b1953dc911a5cd8589b1950da185b9b995b60521b602082015291506146149050565b15612f0057606082828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505082519293505060029091149050612e525760405162461bcd60e51b815260040180806020018281038252604a815260200180614938604a913960600191505060405180910390fd5b600181810151600283015160ff80831660009081526005602052604090205492939192908316909114906001600160a01b03168015612ef6576001600160a01b038116600090815260066020908152604080832060ff881680855290835292819020805460ff1916861515908117909155815190815290517fa3132e3f9819fbddc7f0ed6d38d7feef59aa95112090b7c592f5cb5bc4aa4adc929181900390910190a25b505050505061341b565b612f6484848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c73757370656e6451756f72756d60981b602082015291506146149050565b156130995760028114612fa85760405162461bcd60e51b815260040180806020018281038252602d8152602001806148b1602d913960400191505060405180910390fd5b6000612feb600284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506146fb92505050565b905060008161ffff16118015613005575060648161ffff16105b61304f576040805162461bcd60e51b8152602060048201526016602482015275696e76616c69642073757370656e642071756f72756d60501b604482015290519081900360640190fd5b604080516f14d554d411539117d41493d413d4d05360821b815281519081900360100190206000908152600d60205220805461ffff90921661ffff1990921691909117905561341b565b6130fc84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600c81526b72656f70656e51756f72756d60a01b602082015291506146149050565b1561322f57600281146131405760405162461bcd60e51b815260040180806020018281038252602c8152602001806148de602c913960400191505060405180910390fd5b6000613183600284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506146fb92505050565b905060008161ffff1611801561319d575060648161ffff16105b6131e6576040805162461bcd60e51b8152602060048201526015602482015274696e76616c69642072656f70656e2071756f72756d60581b604482015290519081900360640190fd5b604080516e149153d4115397d41493d413d4d053608a1b8152815190819003600f0190206000908152600d60205220805461ffff90921661ffff1990921691909117905561341b565b61329a84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152601481527363616e63656c5472616e7366657251756f72756d60601b602082015291506146149050565b156133de57600281146132de5760405162461bcd60e51b815260040180806020018281038252603481526020018061487d6034913960400191505060405180910390fd5b6000613321600284848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506146fb92505050565b905060008161ffff1611801561333b575060648161ffff16105b61338c576040805162461bcd60e51b815260206004820152601e60248201527f696e76616c69642063616e63656c207472616e736665722071756f72756d0000604482015290519081900360640190fd5b604080517710d05390d15317d514905394d1915497d41493d413d4d05360421b815281519081900360180190206000908152600d60205220805461ffff90921661ffff1990921691909117905561341b565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b6008602052600090815260409020546001600160401b031681565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081565b61100281565b60005460ff16613537576040805162461bcd60e51b815260206004820152601960248201526000805160206149b4833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b15801561357a57600080fd5b505afa15801561358e573d6000803e3d6000fd5b505050506040513d60208110156135a457600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b1580156135e557600080fd5b505afa1580156135f9573d6000803e3d6000fd5b505050506040513d602081101561360f57600080fd5b505190508061361c575060155b60008211801561362c5750808211155b61366b576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b600b5460ff166136b2576040805162461bcd60e51b815260206004820152600d60248201526c1b9bdd081cdd5cdc195b991959609a1b604482015290519081900360640190fd5b604080516e149153d4115397d41493d413d4d053608a1b8152905190819003600f019020600090613703907fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4706140e4565b9050801561374157600b805460ff1916905560405133907f899fe8c37dc61708a3aaa99c4bf143346c1d1da69af79be9e8920c0a6785b75290600090a25b505050565b600660209081526000928352604080842090915290825290205460ff1681565b6040518060400160405280600381526020016269626360e81b81525081565b610e1081565b61100381565b60005460ff16156137e9576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b7f1471eb6eb2c5e789fc3de43f8ce62938c7d1836ec861730447e2ada8fd81017b80546001600160a01b0319908116611008179091557f92e85d02570a8092d09a6e3a57665bc3815a2699a4074001bf1ccabf660f5a36805460ff199081169091557fd8af288fc1c8680b4f4706064cf021e264efb6828fcaf7eb5ca36818eb365bcc8054821660019081179091557f89832631fb3c3307a103ba2c84ab569c64d6182a18893dcd163f0f1c2090733a805484166110049081179091557f6cde3cea4b3a3fb2488b2808bae7556f4a405e50f65e1794383bc026131b13c38054841690557f72e4efa1513b071517c6c74dba31b5934a81aa83cddd400e7081df5529c9943680548416831790557fa9bc9a3a348c357ba16b37005d7e6b3236198c0e939f4af8c5f19b8deeb8ebc08054851690911790557fc575c31fea594a6eb97c8e9d3f9caee4c16218c6ef37e923234c0fe9014a61e78054831690557f4e523af77f034e9810f1c94057f5e931fb3d16a51511a4c3add793617d18610580548316821790557ffb33122aa9f93cc639ebe80a7bc4784c11e6053dde89c6f4f7e268c6a623da1e805484166110001790557fc7694af312c4f286114180fd0ba6a52461fcee8a381636770b19a343af92538a80548316821790557f01112dd68e482ba8d68a7e828cff8b3abcea08eab88941953c180a7e650e9cd480548316821790557fc0a4a8be475dfebc377ebef2d7c4ff47656f572a08dd92b81017efcdba0febe1805484166110071790557f87e8a52529e8ece4ef759037313542a6429ff494a9fab9027fb79db90124eba680548316821790557f4c7666bbcb22d46469f7cc282f70764a7012dca2cce630ff8d83db9a9cdd48f080548316821790557f40f28f99a40bc9f6beea1013afdbc3cdcc689eb76b82c4de06c0acf1e1932ed58054909316611001179092557f0d9cf2cd531699eed8dd34e40ff2884a14a698c4898184fba85194e6f6772d248054821683179055600b60009081527f23f68c9bd22b8a93d06adabe17481c87c016bcbd20adc8bfd707a4d813a572176020527fdf0d5d05428057f5455c2dc8e810dd86d1e9350faa72f16bda8a45443c5b39328054831684179055603283556004805467ffffffffffffffff19166001600160401b031790556002819055600381905580549091169091179055565b6007602052600090815260409020546001600160401b031681565b60005460ff16613ba8576040805162461bcd60e51b815260206004820152601960248201526000805160206149b4833981519152604482015290519081900360640190fd5b6040805163569e4ed360e11b815233600482015290516000916110009163ad3c9da691602480820192602092909190829003018186803b158015613beb57600080fd5b505afa158015613bff573d6000803e3d6000fd5b505050506040513d6020811015613c1557600080fd5b505160408051633d42651560e11b8152905191925060009161100091637a84ca2a916004808301926020929190829003018186803b158015613c5657600080fd5b505afa158015613c6a573d6000803e3d6000fd5b505050506040513d6020811015613c8057600080fd5b5051905080613c8d575060155b600082118015613c9d5750808211155b613cdc576040805162461bcd60e51b815260206004820152600b60248201526a1b9bdd0818d8589a5b995d60aa1b604482015290519081900360640190fd5b600b5460ff1615613d20576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b604080516f14d554d411539117d41493d413d4d05360821b81529051908190036010019020600090613d72907fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4706140e4565b905080156137415761374161401b565b60005460ff16613dc7576040805162461bcd60e51b815260206004820152601960248201526000805160206149b4833981519152604482015290519081900360640190fd5b33600090815260066020908152604080832060ff8089168552925290912054859116613e245760405162461bcd60e51b81526004018080602001828103825260318152602001806147f26031913960400191505060405180910390fd5b60ff85166000908152600760209081526040808320548151601f88018490048402810184019092528682526001600160401b031692613e899284928a9261208e92909189918c908c908190840183828082843760009201919091525061131c92505050565b60ff959095166000908152600760205260409020805467ffffffffffffffff191660019096016001600160401b03169590951790945550505050565b61100081565b600381565b61100481565b60408051600e808252818301909252606091630102ca0060ff851617918391602082018180368337505050600e81810187905260068201939093529182525090505b92915050565b600085613f2d57506000614012565b606082518451865160800101016040519080825280601f01601f191660200182016040528015613f64576020820181803683370190505b5090506000613f7282614706565b602080890151825201905086600080613f8a89614099565b8086526020909501949092509050613fa38285836140a3565b92830192613fb088614099565b8086526020909501949092509050613fc98285836140a3565b9283018a815260200192613fdc87614099565b9092509050613fec8285836140a3565b508351602001613ffa61470c565b60208183886065600019fa5051600114955050505050505b95945050505050565b600b5460ff161561405f576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b600b805460ff1916600117905560405133907f6f123d3d54c84a7960a573b31c221dcd86e13fd849c5adb0c6ca851468cc1ae490600090a2565b8051602090910191565b5b602081106140c3578251825260209283019290910190601f19016140a4565b915181516020939093036101000a6000190180199091169216919091179052565b6000828152600d602052604081205461ffff166141ad57604080516f14d554d411539117d41493d413d4d05360821b815281519081900360100181206000908152600d6020818152848320805461ffff199081166001179091556e149153d4115397d41493d413d4d053608a1b8552855194859003600f01852084528282528584208054821660029081179091557710d05390d15317d514905394d1915497d41493d413d4d05360421b8652865195869003601801909520845291905292902080549092161790555b6000838152600c6020526040902080546201000090046001600160801b0316421015806141de575082816001015414155b156142b1576000848152600d602090815260409182902054835461ffff90911661ffff199091161771ffffffffffffffffffffffffffffffff0000191662010000610e1042016001600160801b031602178355600180840186905582519182019092523381526142539160028401919061472a565b5080546040805161ffff83168152620100009092046001600160801b0316602083015281810185905251339186917f9e109f0e55ef32e99e4880be2ec357f1ddb3469c79d0747ef4762da6e89fabe5916060908290030190a3614365565b60005b600282015481101561433c57336001600160a01b03168260020182815481106142d957fe5b6000918252602090912001546001600160a01b03161415614334576040805162461bcd60e51b815260206004820152601060248201526f185b1c9958591e48185c1c1c9bdd995960821b604482015290519081900360640190fd5b6001016142b4565b50600281018054600181018255600091825260209091200180546001600160a01b031916331790555b8054600282015461ffff909116116143bf576000848152600c60205260408120805471ffffffffffffffffffffffffffffffffffff1916815560018101829055906143b3600283018261478f565b50506001915050613f18565b5060009392505050565b600080600060606021855110156143f9575050604080516000808252602082019092529092508291508190614472565b600185015160218601518651604080516020198301808252601f1960011990940193909316810160200190915260418901939291606091908015614444576020820181803683370190505b509050600061445282614099565b509050614464858260218d51036140a3565b506001975091955093509150505b9193509193565b600b5460ff16156144bd576040805162461bcd60e51b81526020600482015260096024820152681cdd5cdc195b99195960ba1b604482015290519081900360640190fd5b6002544311156144fc576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003554360025561453d565b6003805460019081019182905554101561453d576004805467ffffffffffffffff1981166001600160401b036001600793840b810190930b16179091556003555b8160ff16836001600160401b0316600460009054906101000a900460070b6001600160401b03167f3a6e0fc61675aa2a100bcba0568368bb92bcec91c97673391074f11138f0cffe6102ca85604051808361ffff1661ffff16815260200180602001828103825283818151815260200191508051906020019080838360005b838110156145d45781810151838201526020016145bc565b50505050905090810190601f1680156146015780820380516001836020036101000a031916815260200191505b50935050505060405180910390a4505050565b6000816040516020018082805190602001908083835b602083106146495780518252601f19909201916020918201910161462a565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106146b75780518252601f199092019160209182019101614698565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b3b151590565b60200190565b60405180602001604052806001906020820280368337509192915050565b82805482825590600052602060002090810192821561477f579160200282015b8281111561477f57825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019061474a565b5061478b9291506147b0565b5090565b50805460008255906000526020600020908101906147ad91906147d7565b50565b6147d491905b8082111561478b5780546001600160a01b03191681556001016147b6565b90565b6147d491905b8082111561478b57600081556001016147dd56fe74686520636f6e747261637420616e64206368616e6e656c2068617665206e6f74206265656e20726567697374657265646c656e677468206f662076616c756520666f72206164644f725570646174654368616e6e656c2073686f756c642062652032322c206368616e6e656c49643a697346726f6d53797374656d3a68616e646c6572416464726573736c656e677468206f662076616c756520666f722063616e63656c5472616e7366657251756f72756d2073686f756c6420626520326c656e677468206f662076616c756520666f722073757370656e6451756f72756d2073686f756c6420626520326c656e677468206f662076616c756520666f722072656f70656e51756f72756d2073686f756c642062652032746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163746c656e677468206f662076616c756520666f7220656e61626c654f7244697361626c654368616e6e656c2073686f756c6420626520322c206368616e6e656c49643a6973456e61626c65746865206e6577426174636853697a65466f724f7261636c652073686f756c6420626520696e205b31302c2031303030305d74686520636f6e7472616374206e6f7420696e697420796574000000000000006c6967687420636c69656e74206e6f742073796e632074686520626c6f636b20796574a264697066735822122020f10a3f6af250b9c5c16c5020f1b83db8bc64ed4363d8712e2b85f20f56251164736f6c63430006040033", + }, + }, + } } func UpgradeBuildInSystemContract(config *chain.Config, blockNumber *big.Int, statedb *state.IntraBlockState) { @@ -539,6 +704,10 @@ func UpgradeBuildInSystemContract(config *chain.Config, blockNumber *big.Int, st applySystemContractUpgrade(MoranUpgrade[config.ChainName], blockNumber, statedb, logger) } + if config.IsOnPlanck(blockNumber) { + applySystemContractUpgrade(PlanckUpgrade[config.ChainName], blockNumber, statedb, logger) + } + if config.IsOnGibbs(blockNumber) { applySystemContractUpgrade(GibbsUpgrade[config.ChainName], blockNumber, statedb, logger) } @@ -547,6 +716,10 @@ func UpgradeBuildInSystemContract(config *chain.Config, blockNumber *big.Int, st applySystemContractUpgrade(CalcuttaUpgrade[config.ChainName], blockNumber, statedb, logger) } + if config.IsOnLuban(blockNumber) { + applySystemContractUpgrade(LubanUpgrade[config.ChainName], blockNumber, statedb, logger) + } + /* apply other upgrades */ diff --git a/core/types/accounts/account_proof.go b/core/types/accounts/account_proof.go new file mode 100644 index 00000000000..7653445d1d1 --- /dev/null +++ b/core/types/accounts/account_proof.go @@ -0,0 +1,24 @@ +package accounts + +import ( + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" + + "github.com/ledgerwatch/erigon/common/hexutil" +) + +// Result structs for GetProof +type AccProofResult struct { + Address libcommon.Address `json:"address"` + AccountProof []hexutility.Bytes `json:"accountProof"` + Balance *hexutil.Big `json:"balance"` + CodeHash libcommon.Hash `json:"codeHash"` + Nonce hexutil.Uint64 `json:"nonce"` + StorageHash libcommon.Hash `json:"storageHash"` + StorageProof []StorProofResult `json:"storageProof"` +} +type StorProofResult struct { + Key libcommon.Hash `json:"key"` + Value *hexutil.Big `json:"value"` + Proof []hexutility.Bytes `json:"proof"` +} diff --git a/core/types/blob_tx_wrapper.go b/core/types/blob_tx_wrapper.go new file mode 100644 index 00000000000..fe036c683b3 --- /dev/null +++ b/core/types/blob_tx_wrapper.go @@ -0,0 +1,439 @@ +package types + +import ( + "bytes" + "encoding/hex" + "errors" + "fmt" + "io" + "math/big" + "time" + + "github.com/holiman/uint256" + "github.com/ledgerwatch/erigon-lib/chain" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" + types2 "github.com/ledgerwatch/erigon-lib/types" + + gokzg4844 "github.com/crate-crypto/go-kzg-4844" + "github.com/protolambda/ztyp/codec" + + "github.com/ledgerwatch/erigon/crypto/kzg" + "github.com/ledgerwatch/erigon/params" + "github.com/ledgerwatch/erigon/rlp" +) + +// Compressed BLS12-381 G1 element +type KZGCommitment [48]byte + +func (p *KZGCommitment) Deserialize(dr *codec.DecodingReader) error { + if p == nil { + return errors.New("nil pubkey") + } + _, err := dr.Read(p[:]) + return err +} + +func (p *KZGCommitment) Serialize(w *codec.EncodingWriter) error { + return w.Write(p[:]) +} + +func (KZGCommitment) ByteLength() uint64 { + return 48 +} + +func (KZGCommitment) FixedLength() uint64 { + return 48 +} + +func (p KZGCommitment) MarshalText() ([]byte, error) { + return []byte("0x" + hex.EncodeToString(p[:])), nil +} + +func (p KZGCommitment) String() string { + return "0x" + hex.EncodeToString(p[:]) +} + +func (p *KZGCommitment) UnmarshalText(text []byte) error { + return hexutility.UnmarshalFixedText("KZGCommitment", text, p[:]) +} + +func (c KZGCommitment) ComputeVersionedHash() libcommon.Hash { + return libcommon.Hash(kzg.KZGToVersionedHash(gokzg4844.KZGCommitment(c))) +} + +// Compressed BLS12-381 G1 element +type KZGProof [48]byte + +func (p *KZGProof) Deserialize(dr *codec.DecodingReader) error { + if p == nil { + return errors.New("nil pubkey") + } + _, err := dr.Read(p[:]) + return err +} + +func (p *KZGProof) Serialize(w *codec.EncodingWriter) error { + return w.Write(p[:]) +} + +func (KZGProof) ByteLength() uint64 { + return 48 +} + +func (KZGProof) FixedLength() uint64 { + return 48 +} + +func (p KZGProof) MarshalText() ([]byte, error) { + return []byte("0x" + hex.EncodeToString(p[:])), nil +} + +func (p KZGProof) String() string { + return "0x" + hex.EncodeToString(p[:]) +} + +func (p *KZGProof) UnmarshalText(text []byte) error { + return hexutility.UnmarshalFixedText("KZGProof", text, p[:]) +} + +// BLSFieldElement is the raw bytes representation of a field element +type BLSFieldElement [32]byte + +func (p BLSFieldElement) MarshalText() ([]byte, error) { + return []byte("0x" + hex.EncodeToString(p[:])), nil +} + +func (p BLSFieldElement) String() string { + return "0x" + hex.EncodeToString(p[:]) +} + +func (p *BLSFieldElement) UnmarshalText(text []byte) error { + return hexutility.UnmarshalFixedText("BLSFieldElement", text, p[:]) +} + +// Blob data +type Blob [params.FieldElementsPerBlob * 32]byte + +func (blob *Blob) Deserialize(dr *codec.DecodingReader) error { + if blob == nil { + return errors.New("cannot decode ssz into nil Blob") + } + + // We treat the blob as an opaque sequence of bytes + // and therefore we do not do any validation related to field + // elements + if _, err := dr.Read(blob[:]); err != nil { + return err + } + + return nil +} + +func (blob *Blob) Serialize(w *codec.EncodingWriter) error { + return w.Write(blob[:]) +} + +func (blob *Blob) ByteLength() (out uint64) { + return params.FieldElementsPerBlob * 32 +} + +func (blob *Blob) FixedLength() uint64 { + return params.FieldElementsPerBlob * 32 +} + +func (blob *Blob) MarshalText() ([]byte, error) { + out := make([]byte, 2+params.FieldElementsPerBlob*32*2) + copy(out[:2], "0x") + hex.Encode(out[2:], blob[:]) + + return out, nil +} + +func (blob *Blob) String() string { + v, err := blob.MarshalText() + if err != nil { + return "" + } + return string(v) +} + +func (blob *Blob) UnmarshalText(text []byte) error { + if blob == nil { + return errors.New("cannot decode text into nil Blob") + } + l := 2 + params.FieldElementsPerBlob*32*2 + if len(text) != l { + return fmt.Errorf("expected %d characters but got %d", l, len(text)) + } + if !(text[0] == '0' && text[1] == 'x') { + return fmt.Errorf("expected '0x' prefix in Blob string") + } + if _, err := hex.Decode(blob[:], text[2:]); err != nil { + return fmt.Errorf("blob is not formatted correctly: %v", err) + } + + return nil +} + +type BlobKzgs []KZGCommitment + +func (li *BlobKzgs) Deserialize(dr *codec.DecodingReader) error { + return dr.List(func() codec.Deserializable { + i := len(*li) + *li = append(*li, KZGCommitment{}) + return &(*li)[i] + }, 48, params.MaxBlobsPerBlock) +} + +func (li BlobKzgs) Serialize(w *codec.EncodingWriter) error { + return w.List(func(i uint64) codec.Serializable { + return &li[i] + }, 48, uint64(len(li))) +} + +func (li BlobKzgs) ByteLength() uint64 { + return uint64(len(li)) * 48 +} + +func (li BlobKzgs) FixedLength() uint64 { + return 0 +} + +func (li BlobKzgs) copy() BlobKzgs { + cpy := make(BlobKzgs, len(li)) + copy(cpy, li) + return cpy +} + +type KZGProofs []KZGProof + +func (li *KZGProofs) Deserialize(dr *codec.DecodingReader) error { + return dr.List(func() codec.Deserializable { + i := len(*li) + *li = append(*li, KZGProof{}) + return &(*li)[i] + }, 48, params.MaxBlobsPerBlock) +} + +func (li KZGProofs) Serialize(w *codec.EncodingWriter) error { + return w.List(func(i uint64) codec.Serializable { + return &li[i] + }, 48, uint64(len(li))) +} + +func (li KZGProofs) ByteLength() uint64 { + return uint64(len(li)) * 48 +} + +func (li KZGProofs) FixedLength() uint64 { + return 0 +} + +func (li KZGProofs) copy() KZGProofs { + cpy := make(KZGProofs, len(li)) + copy(cpy, li) + return cpy +} + +type Blobs []Blob + +func (a *Blobs) Deserialize(dr *codec.DecodingReader) error { + return dr.List(func() codec.Deserializable { + i := len(*a) + *a = append(*a, Blob{}) + return &(*a)[i] + }, params.FieldElementsPerBlob*32, params.FieldElementsPerBlob) +} + +func (a Blobs) Serialize(w *codec.EncodingWriter) error { + return w.List(func(i uint64) codec.Serializable { + return &a[i] + }, params.FieldElementsPerBlob*32, uint64(len(a))) +} + +func (a Blobs) ByteLength() (out uint64) { + return uint64(len(a)) * params.FieldElementsPerBlob * 32 +} + +func (a *Blobs) FixedLength() uint64 { + return 0 // it's a list, no fixed length +} + +func (blobs Blobs) copy() Blobs { + cpy := make(Blobs, len(blobs)) + copy(cpy, blobs) // each blob element is an array and gets deep-copied + return cpy +} + +// Return KZG commitments, versioned hashes and the proofs that correspond to these blobs +func (blobs Blobs) ComputeCommitmentsAndProofs() (commitments []KZGCommitment, versionedHashes []libcommon.Hash, proofs []KZGProof, err error) { + commitments = make([]KZGCommitment, len(blobs)) + proofs = make([]KZGProof, len(blobs)) + versionedHashes = make([]libcommon.Hash, len(blobs)) + + cryptoCtx := kzg.CrpytoCtx() + for i, blob := range blobs { + commitment, err := cryptoCtx.BlobToKZGCommitment(gokzg4844.Blob(blob)) + if err != nil { + return nil, nil, nil, fmt.Errorf("could not convert blob to commitment: %v", err) + } + + proof, err := cryptoCtx.ComputeBlobKZGProof(gokzg4844.Blob(blob), commitment) + if err != nil { + return nil, nil, nil, fmt.Errorf("could not compute proof for blob: %v", err) + } + commitments[i] = KZGCommitment(commitment) + proofs[i] = KZGProof(proof) + versionedHashes[i] = libcommon.Hash(kzg.KZGToVersionedHash(commitment)) + } + + return commitments, versionedHashes, proofs, nil +} + +func toBlobs(_blobs Blobs) []gokzg4844.Blob { + blobs := make([]gokzg4844.Blob, len(_blobs)) + for i, _blob := range _blobs { + blobs[i] = gokzg4844.Blob(_blob) + } + return blobs +} +func toComms(_comms BlobKzgs) []gokzg4844.KZGCommitment { + comms := make([]gokzg4844.KZGCommitment, len(_comms)) + for i, _comm := range _comms { + comms[i] = gokzg4844.KZGCommitment(_comm) + } + return comms +} +func toProofs(_proofs KZGProofs) []gokzg4844.KZGProof { + proofs := make([]gokzg4844.KZGProof, len(_proofs)) + for i, _proof := range _proofs { + proofs[i] = gokzg4844.KZGProof(_proof) + } + return proofs +} + +// BlobTxWrapper is the "network representation" of a Blob transaction, that is it includes not +// only the SignedBlobTx but also all the associated blob data. +type BlobTxWrapper struct { + Tx SignedBlobTx + BlobKzgs BlobKzgs + Blobs Blobs + Proofs KZGProofs +} + +func (txw *BlobTxWrapper) Deserialize(dr *codec.DecodingReader) error { + return dr.Container(&txw.Tx, &txw.BlobKzgs, &txw.Blobs, &txw.Proofs) +} + +func (txw *BlobTxWrapper) Serialize(w *codec.EncodingWriter) error { + return w.Container(&txw.Tx, &txw.BlobKzgs, &txw.Blobs, &txw.Proofs) +} + +func (txw *BlobTxWrapper) ByteLength() uint64 { + return codec.ContainerLength(&txw.Tx, &txw.BlobKzgs, &txw.Blobs, &txw.Proofs) +} + +func (txw *BlobTxWrapper) FixedLength() uint64 { + return 0 +} + +// validateBlobTransactionWrapper implements validate_blob_transaction_wrapper from EIP-4844 +func (txw *BlobTxWrapper) ValidateBlobTransactionWrapper() error { + blobTx := txw.Tx.Message + l1 := len(blobTx.BlobVersionedHashes) + if l1 == 0 { + return fmt.Errorf("a blob tx must contain at least one blob") + } + l2 := len(txw.BlobKzgs) + l3 := len(txw.Blobs) + l4 := len(txw.Proofs) + if l1 != l2 || l2 != l3 || l1 != l4 { + return fmt.Errorf("lengths don't match %v %v %v %v", l1, l2, l3, l4) + } + // the following check isn't strictly necessary as it would be caught by data gas processing + // (and hence it is not explicitly in the spec for this function), but it doesn't hurt to fail + // early in case we are getting spammed with too many blobs or there is a bug somewhere: + if l1 > params.MaxBlobsPerBlock { + return fmt.Errorf("number of blobs exceeds max: %v", l1) + } + cryptoCtx := kzg.CrpytoCtx() + err := cryptoCtx.VerifyBlobKZGProofBatch(toBlobs(txw.Blobs), toComms(txw.BlobKzgs), toProofs(txw.Proofs)) + if err != nil { + return fmt.Errorf("error during proof verification: %v", err) + } + for i, h := range blobTx.BlobVersionedHashes { + if computed := txw.BlobKzgs[i].ComputeVersionedHash(); computed != h { + return fmt.Errorf("versioned hash %d supposedly %s but does not match computed %s", i, h, computed) + } + } + return nil +} + +// Implement transaction interface +func (txw *BlobTxWrapper) Type() byte { return txw.Tx.Type() } +func (txw *BlobTxWrapper) GetChainID() *uint256.Int { return txw.Tx.GetChainID() } +func (txw *BlobTxWrapper) GetNonce() uint64 { return txw.Tx.GetNonce() } +func (txw *BlobTxWrapper) GetPrice() *uint256.Int { return txw.Tx.GetPrice() } +func (txw *BlobTxWrapper) GetTip() *uint256.Int { return txw.Tx.GetTip() } +func (txw *BlobTxWrapper) GetEffectiveGasTip(baseFee *uint256.Int) *uint256.Int { + return txw.Tx.GetEffectiveGasTip(baseFee) +} +func (txw *BlobTxWrapper) GetFeeCap() *uint256.Int { return txw.Tx.GetFeeCap() } +func (txw *BlobTxWrapper) Cost() *uint256.Int { return txw.Tx.GetFeeCap() } +func (txw *BlobTxWrapper) GetDataHashes() []libcommon.Hash { return txw.Tx.GetDataHashes() } +func (txw *BlobTxWrapper) GetGas() uint64 { return txw.Tx.GetGas() } +func (txw *BlobTxWrapper) GetDataGas() uint64 { return txw.Tx.GetDataGas() } +func (txw *BlobTxWrapper) GetValue() *uint256.Int { return txw.Tx.GetValue() } +func (txw *BlobTxWrapper) Time() time.Time { return txw.Tx.Time() } +func (txw *BlobTxWrapper) GetTo() *libcommon.Address { return txw.Tx.GetTo() } +func (txw *BlobTxWrapper) AsMessage(s Signer, baseFee *big.Int, rules *chain.Rules) (Message, error) { + return txw.Tx.AsMessage(s, baseFee, rules) +} +func (txw *BlobTxWrapper) WithSignature(signer Signer, sig []byte) (Transaction, error) { + return txw.Tx.WithSignature(signer, sig) +} +func (txw *BlobTxWrapper) FakeSign(address libcommon.Address) (Transaction, error) { + return txw.Tx.FakeSign(address) +} +func (txw *BlobTxWrapper) Hash() libcommon.Hash { return txw.Tx.Hash() } +func (txw *BlobTxWrapper) SigningHash(chainID *big.Int) libcommon.Hash { + return txw.Tx.SigningHash(chainID) +} +func (txw *BlobTxWrapper) GetData() []byte { return txw.Tx.GetData() } +func (txw *BlobTxWrapper) GetAccessList() types2.AccessList { return txw.Tx.GetAccessList() } +func (txw *BlobTxWrapper) Protected() bool { return txw.Tx.Protected() } +func (txw *BlobTxWrapper) RawSignatureValues() (*uint256.Int, *uint256.Int, *uint256.Int) { + return txw.Tx.RawSignatureValues() +} +func (txw *BlobTxWrapper) Sender(s Signer) (libcommon.Address, error) { return txw.Tx.Sender(s) } +func (txw *BlobTxWrapper) GetSender() (libcommon.Address, bool) { return txw.Tx.GetSender() } +func (txw *BlobTxWrapper) SetSender(address libcommon.Address) { txw.Tx.SetSender(address) } +func (txw *BlobTxWrapper) IsContractDeploy() bool { return txw.Tx.IsContractDeploy() } +func (txw *BlobTxWrapper) Unwrap() Transaction { return &txw.Tx } + +func (txw BlobTxWrapper) EncodingSize() int { + envelopeSize := int(codec.ContainerLength(&txw.Tx, &txw.BlobKzgs, &txw.Blobs, &txw.Proofs)) + // Add type byte + envelopeSize++ + return envelopeSize +} + +func (txw *BlobTxWrapper) MarshalBinary(w io.Writer) error { + var b [33]byte + // encode TxType + b[0] = BlobTxType + if _, err := w.Write(b[:1]); err != nil { + return err + } + wcodec := codec.NewEncodingWriter(w) + return txw.Serialize(wcodec) +} + +func (txw BlobTxWrapper) EncodeRLP(w io.Writer) error { + var buf bytes.Buffer + if err := txw.MarshalBinary(&buf); err != nil { + return err + } + return rlp.Encode(w, buf.Bytes()) +} diff --git a/core/types/block.go b/core/types/block.go index 64c61a909b6..aea6a42ed3d 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -33,9 +33,6 @@ import ( "github.com/ledgerwatch/erigon-lib/common/hexutility" rlp2 "github.com/ledgerwatch/erigon-lib/rlp" - "github.com/ledgerwatch/erigon/cl/clparams" - "github.com/ledgerwatch/erigon/cl/cltypes/ssz_utils" - "github.com/ledgerwatch/erigon/cl/merkle_tree" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/rlp" @@ -65,7 +62,7 @@ func (n BlockNonce) Uint64() uint64 { // MarshalText encodes n as a hex string with 0x prefix. func (n BlockNonce) MarshalText() ([]byte, error) { - return hexutil.Bytes(n[:]).MarshalText() + return hexutility.Bytes(n[:]).MarshalText() } // UnmarshalText implements encoding.TextUnmarshaler. @@ -99,15 +96,24 @@ type Header struct { BaseFee *big.Int `json:"baseFeePerGas"` // EIP-1559 WithdrawalsHash *libcommon.Hash `json:"withdrawalsRoot"` // EIP-4895 + // ExcessDataGas was added by EIP-4844 and is ignored in legacy headers. + ExcessDataGas *big.Int `json:"excessDataGas"` // The verkle proof is ignored in legacy headers Verkle bool VerkleProof []byte VerkleKeyVals []verkle.KeyValuePair - // ETH2 fields - // This is the block hash given by the CL,we cannot validate in the context of the state. - BlockHashCL libcommon.Hash - TxHashSSZ libcommon.Hash // They decided to hash txs differently than EL :( +} + +// ParentExcessDataGas is a helper that returns the excess data gas value of the parent block. It +// returns nil if the parent header could not be fetched, or if the parent block's excess data gas +// is nil. +func (h *Header) ParentExcessDataGas(getHeader func(hash libcommon.Hash, number uint64) *Header) *big.Int { + p := getHeader(h.ParentHash, h.Number.Uint64()) + if p != nil { + return p.ExcessDataGas + } + return nil } func bitsToBytes(bitLen int) (byteLen int) { @@ -165,6 +171,11 @@ func (h *Header) EncodingSize() int { encodingSize += 33 } + if h.ExcessDataGas != nil { + encodingSize++ + encodingSize += rlp.BigIntLenExcludingHead(h.ExcessDataGas) + } + if h.Verkle { // Encoding of Verkle Proof encodingSize++ @@ -307,6 +318,12 @@ func (h *Header) EncodeRLP(w io.Writer) error { } } + if h.ExcessDataGas != nil { + if err := rlp.EncodeBigInt(h.ExcessDataGas, w, b[:]); err != nil { + return err + } + } + if h.Verkle { if err := rlp.EncodeString(h.VerkleProof, w, b[:]); err != nil { return err @@ -452,6 +469,19 @@ func (h *Header) DecodeRLP(s *rlp.Stream) error { h.WithdrawalsHash = new(libcommon.Hash) h.WithdrawalsHash.SetBytes(b) + // ExcessDataGas + if b, err = s.Uint256Bytes(); err != nil { + if errors.Is(err, rlp.EOL) { + h.ExcessDataGas = nil + if err := s.ListEnd(); err != nil { + return fmt.Errorf("close header struct (no ExcessDataGas): %w", err) + } + return nil + } + return fmt.Errorf("read ExcessDataGas: %w", err) + } + h.ExcessDataGas = new(big.Int).SetBytes(b) + if h.Verkle { if h.VerkleProof, err = s.Bytes(); err != nil { return fmt.Errorf("read VerkleProof: %w", err) @@ -471,14 +501,27 @@ func (h *Header) DecodeRLP(s *rlp.Stream) error { // field type overrides for gencodec type headerMarshaling struct { - Difficulty *hexutil.Big - Number *hexutil.Big - GasLimit hexutil.Uint64 - GasUsed hexutil.Uint64 - Time hexutil.Uint64 - Extra hexutil.Bytes - BaseFee *hexutil.Big - Hash libcommon.Hash `json:"hash"` // adds call to Hash() in MarshalJSON + Difficulty *hexutil.Big + Number *hexutil.Big + GasLimit hexutil.Uint64 + GasUsed hexutil.Uint64 + Time hexutil.Uint64 + Extra hexutility.Bytes + BaseFee *hexutil.Big + ExcessDataGas *hexutil.Big + Hash libcommon.Hash `json:"hash"` // adds call to Hash() in MarshalJSON +} + +// SetExcessDataGas sets the excess_data_gas field in the header +func (h *Header) SetExcessDataGas(v *big.Int) { + h.ExcessDataGas = new(big.Int) + if v != nil { + h.ExcessDataGas.Set(v) + } + if h.WithdrawalsHash == nil { + // leaving this nil would result in a buggy encoding + h.WithdrawalsHash = &EmptyRootHash + } } // Hash returns the block hash of the header, which is simply the keccak256 hash of its @@ -499,6 +542,9 @@ func (h *Header) Size() common.StorageSize { if h.WithdrawalsHash != nil { s += common.StorageSize(32) } + if h.ExcessDataGas != nil { + s += common.StorageSize(bitsToBytes(h.ExcessDataGas.BitLen())) + } return s } @@ -523,189 +569,15 @@ func (h *Header) SanityCheck() error { return fmt.Errorf("too large base fee: bitlen %d", bfLen) } } - return nil -} - -func (h *Header) EncodeHeaderMetadataForSSZ(dst []byte, extraDataOffset int) ([]byte, error) { - buf := dst - buf = append(buf, h.ParentHash[:]...) - buf = append(buf, h.Coinbase[:]...) - buf = append(buf, h.Root[:]...) - buf = append(buf, h.ReceiptHash[:]...) - buf = append(buf, h.Bloom[:]...) - buf = append(buf, h.MixDigest[:]...) - buf = append(buf, ssz_utils.Uint64SSZ(h.Number.Uint64())...) - buf = append(buf, ssz_utils.Uint64SSZ(h.GasLimit)...) - buf = append(buf, ssz_utils.Uint64SSZ(h.GasUsed)...) - buf = append(buf, ssz_utils.Uint64SSZ(h.Time)...) - buf = append(buf, ssz_utils.OffsetSSZ(uint32(extraDataOffset))...) - - // Add Base Fee - var baseFeeBytes32 [32]byte // Base fee is padded. - baseFeeBytes := h.BaseFee.Bytes() - for i, j := 0, len(baseFeeBytes)-1; i < j; i, j = i+1, j-1 { - baseFeeBytes[i], baseFeeBytes[j] = baseFeeBytes[j], baseFeeBytes[i] - } - copy(baseFeeBytes32[:], baseFeeBytes) - buf = append(buf, baseFeeBytes32[:]...) - buf = append(buf, h.BlockHashCL[:]...) - return buf, nil -} - -func (h *Header) EncodeSSZ(dst []byte) (buf []byte, err error) { - buf = dst - offset := ssz_utils.BaseExtraDataSSZOffsetHeader - - if h.WithdrawalsHash != nil { - offset += 32 - } - - buf, err = h.EncodeHeaderMetadataForSSZ(buf, offset) - if err != nil { - return nil, err - } - buf = append(buf, h.TxHashSSZ[:]...) - - if h.WithdrawalsHash != nil { - buf = append(buf, h.WithdrawalsHash[:]...) - } - - buf = append(buf, h.Extra...) - return -} - -// NOTE: it is skipping extra data -func (h *Header) DecodeHeaderMetadataForSSZ(buf []byte) (pos int, extraDataOffset int) { - h.UncleHash = EmptyUncleHash - h.Difficulty = libcommon.Big0 - - copy(h.ParentHash[:], buf) - pos = len(h.ParentHash) - - copy(h.Coinbase[:], buf[pos:]) - pos += len(h.Coinbase) - - copy(h.Root[:], buf[pos:]) - pos += len(h.Root) - - copy(h.ReceiptHash[:], buf[pos:]) - pos += len(h.ReceiptHash) - - h.Bloom.SetBytes(buf[pos : pos+BloomByteLength]) - pos += BloomByteLength - - copy(h.MixDigest[:], buf[pos:]) - pos += len(h.MixDigest) - - h.Number = new(big.Int).SetUint64(ssz_utils.UnmarshalUint64SSZ(buf[pos:])) - h.GasLimit = ssz_utils.UnmarshalUint64SSZ(buf[pos+8:]) - h.GasUsed = ssz_utils.UnmarshalUint64SSZ(buf[pos+16:]) - h.Time = ssz_utils.UnmarshalUint64SSZ(buf[pos+24:]) - pos += 32 - extraDataOffset = int(ssz_utils.DecodeOffset(buf[pos:])) - pos += 4 - // Add Base Fee - baseFeeBytes := common.CopyBytes(buf[pos : pos+32]) - for i, j := 0, len(baseFeeBytes)-1; i < j; i, j = i+1, j-1 { - baseFeeBytes[i], baseFeeBytes[j] = baseFeeBytes[j], baseFeeBytes[i] - } - h.BaseFee = new(big.Int).SetBytes(baseFeeBytes) - pos += 32 - copy(h.BlockHashCL[:], buf[pos:pos+32]) - pos += 32 - return -} - -func (h *Header) DecodeSSZ(buf []byte, version clparams.StateVersion) error { - if len(buf) < h.EncodingSizeSSZ(version) { - return ssz_utils.ErrLowBufferSize + if h.ExcessDataGas != nil { + if bfLen := h.ExcessDataGas.BitLen(); bfLen > 256 { + return fmt.Errorf("too large excess data gas: bitlen %d", bfLen) + } } - pos, _ := h.DecodeHeaderMetadataForSSZ(buf) - copy(h.TxHashSSZ[:], buf[pos:pos+32]) - pos += len(h.TxHashSSZ) - if version >= clparams.CapellaVersion { - h.WithdrawalsHash = new(libcommon.Hash) - copy((*h.WithdrawalsHash)[:], buf[pos:]) - pos += len(h.WithdrawalsHash) - } else { - h.WithdrawalsHash = nil - } - h.Extra = common.CopyBytes(buf[pos:]) return nil } -// EncodingSizeSSZ returns the ssz encoded size in bytes for the Header object -func (h *Header) EncodingSizeSSZ(version clparams.StateVersion) int { - size := 536 - - if h.WithdrawalsHash != nil || version >= clparams.CapellaVersion { - size += 32 - } - - return size + len(h.Extra) -} - -func (h *Header) HashSSZ() ([32]byte, error) { - // Compute coinbase leaf - var coinbase32 [32]byte - copy(coinbase32[:], h.Coinbase[:]) - // Compute Bloom leaf - bloomLeaf, err := merkle_tree.ArraysRoot([][32]byte{ - libcommon.BytesToHash(h.Bloom[:32]), - libcommon.BytesToHash(h.Bloom[32:64]), - libcommon.BytesToHash(h.Bloom[64:96]), - libcommon.BytesToHash(h.Bloom[96:128]), - libcommon.BytesToHash(h.Bloom[128:160]), - libcommon.BytesToHash(h.Bloom[160:192]), - libcommon.BytesToHash(h.Bloom[192:224]), - libcommon.BytesToHash(h.Bloom[224:]), - }, 8) - if err != nil { - return [32]byte{}, err - } - // Compute baseFee leaf - baseFeeBytes := h.BaseFee.Bytes() - for i, j := 0, len(baseFeeBytes)-1; i < j; i, j = i+1, j-1 { - baseFeeBytes[i], baseFeeBytes[j] = baseFeeBytes[j], baseFeeBytes[i] - } - var baseFeeLeaf libcommon.Hash - copy(baseFeeLeaf[:], baseFeeBytes) - // Compute extra data leaf - var extraLeaf libcommon.Hash - - var baseExtraLeaf [32]byte - copy(baseExtraLeaf[:], h.Extra) - - extraLeaf, err = merkle_tree.ArraysRoot([][32]byte{ - baseExtraLeaf, - merkle_tree.Uint64Root(uint64(len(h.Extra)))}, 2) - if err != nil { - return [32]byte{}, err - } - - leaves := [][32]byte{ - h.ParentHash, - coinbase32, - h.Root, - h.ReceiptHash, - bloomLeaf, - h.MixDigest, - merkle_tree.Uint64Root(h.Number.Uint64()), - merkle_tree.Uint64Root(h.GasLimit), - merkle_tree.Uint64Root(h.GasUsed), - merkle_tree.Uint64Root(h.Time), - extraLeaf, - baseFeeLeaf, - h.BlockHashCL, - h.TxHashSSZ, - } - if h.WithdrawalsHash != nil { - leaves = append(leaves, *h.WithdrawalsHash) - } - return merkle_tree.ArraysRoot(leaves, 16) -} - // Body is a simple (mutable, non-safe) data container for storing and moving // a block's data contents (transactions and uncles) together. type Body struct { @@ -1360,6 +1232,10 @@ func CopyHeader(h *Header) *Header { cpy.WithdrawalsHash = new(libcommon.Hash) cpy.WithdrawalsHash.SetBytes(h.WithdrawalsHash.Bytes()) } + if h.ExcessDataGas != nil { + cpy.ExcessDataGas = new(big.Int) + cpy.ExcessDataGas.Set(h.ExcessDataGas) + } return &cpy } @@ -1587,6 +1463,13 @@ func (b *Block) BaseFee() *big.Int { func (b *Block) WithdrawalsHash() *libcommon.Hash { return b.header.WithdrawalsHash } func (b *Block) Withdrawals() Withdrawals { return b.withdrawals } +func (b *Block) ExcessDataGas() *big.Int { + if b.header.ExcessDataGas == nil { + return nil + } + return new(big.Int).Set(b.header.ExcessDataGas) +} + // Header returns a deep-copy of the entire block header using CopyHeader() func (b *Block) Header() *Header { return CopyHeader(b.header) } func (b *Block) HeaderNoCopy() *Header { return b.header } diff --git a/core/types/bloom9.go b/core/types/bloom9.go index b0e499ad9dc..07ba1f9583b 100644 --- a/core/types/bloom9.go +++ b/core/types/bloom9.go @@ -23,7 +23,6 @@ import ( "github.com/ledgerwatch/erigon-lib/common/hexutility" - "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/crypto/cryptopool" ) @@ -95,7 +94,7 @@ func (b Bloom) Test(topic []byte) bool { // MarshalText encodes b as a hex string with 0x prefix. func (b Bloom) MarshalText() ([]byte, error) { - return hexutil.Bytes(b[:]).MarshalText() + return hexutility.Bytes(b[:]).MarshalText() } // UnmarshalText b as a hex string with 0x prefix. diff --git a/core/types/gen_erigon_log_json.go b/core/types/gen_erigon_log_json.go index 5b800456c18..2360e2fdba0 100644 --- a/core/types/gen_erigon_log_json.go +++ b/core/types/gen_erigon_log_json.go @@ -7,6 +7,7 @@ import ( "errors" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common/hexutil" ) @@ -18,7 +19,7 @@ func (l ErigonLog) MarshalJSON() ([]byte, error) { type ErigonLog struct { Address libcommon.Address `json:"address" gencodec:"required"` Topics []libcommon.Hash `json:"topics" gencodec:"required"` - Data hexutil.Bytes `json:"data" gencodec:"required"` + Data hexutility.Bytes `json:"data" gencodec:"required"` BlockNumber hexutil.Uint64 `json:"blockNumber"` TxHash libcommon.Hash `json:"transactionHash" gencodec:"required"` TxIndex hexutil.Uint `json:"transactionIndex"` @@ -48,7 +49,7 @@ func (l *ErigonLog) UnmarshalJSON(input []byte) error { type ErigonLog struct { Address *libcommon.Address `json:"address" gencodec:"required"` Topics []libcommon.Hash `json:"topics" gencodec:"required"` - Data *hexutil.Bytes `json:"data" gencodec:"required"` + Data *hexutility.Bytes `json:"data" gencodec:"required"` BlockNumber *hexutil.Uint64 `json:"blockNumber"` TxHash *libcommon.Hash `json:"transactionHash" gencodec:"required"` TxIndex *hexutil.Uint `json:"transactionIndex"` diff --git a/core/types/gen_header_json.go b/core/types/gen_header_json.go index fb8194348e6..17b70798b48 100644 --- a/core/types/gen_header_json.go +++ b/core/types/gen_header_json.go @@ -8,6 +8,7 @@ import ( "math/big" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common/hexutil" ) @@ -29,7 +30,7 @@ func (h Header) MarshalJSON() ([]byte, error) { GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"` GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` Time hexutil.Uint64 `json:"timestamp" gencodec:"required"` - Extra hexutil.Bytes `json:"extraData" gencodec:"required"` + Extra hexutility.Bytes `json:"extraData" gencodec:"required"` MixDigest libcommon.Hash `json:"mixHash"` Nonce BlockNonce `json:"nonce"` BaseFee *hexutil.Big `json:"baseFeePerGas"` @@ -73,7 +74,7 @@ func (h *Header) UnmarshalJSON(input []byte) error { GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"` GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"` Time *hexutil.Uint64 `json:"timestamp" gencodec:"required"` - Extra *hexutil.Bytes `json:"extraData" gencodec:"required"` + Extra *hexutility.Bytes `json:"extraData" gencodec:"required"` MixDigest *libcommon.Hash `json:"mixHash"` Nonce *BlockNonce `json:"nonce"` BaseFee *hexutil.Big `json:"baseFeePerGas"` diff --git a/core/types/gen_log_json.go b/core/types/gen_log_json.go index 6b61925936e..e3db5873dc4 100644 --- a/core/types/gen_log_json.go +++ b/core/types/gen_log_json.go @@ -7,6 +7,7 @@ import ( "errors" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common/hexutil" ) @@ -18,7 +19,7 @@ func (l Log) MarshalJSON() ([]byte, error) { type Log struct { Address libcommon.Address `json:"address" gencodec:"required"` Topics []libcommon.Hash `json:"topics" gencodec:"required"` - Data hexutil.Bytes `json:"data" gencodec:"required"` + Data hexutility.Bytes `json:"data" gencodec:"required"` BlockNumber hexutil.Uint64 `json:"blockNumber"` TxHash libcommon.Hash `json:"transactionHash" gencodec:"required"` TxIndex hexutil.Uint `json:"transactionIndex"` @@ -44,7 +45,7 @@ func (l *Log) UnmarshalJSON(input []byte) error { type Log struct { Address *libcommon.Address `json:"address" gencodec:"required"` Topics []libcommon.Hash `json:"topics" gencodec:"required"` - Data *hexutil.Bytes `json:"data" gencodec:"required"` + Data *hexutility.Bytes `json:"data" gencodec:"required"` BlockNumber *hexutil.Uint64 `json:"blockNumber"` TxHash *libcommon.Hash `json:"transactionHash" gencodec:"required"` TxIndex *hexutil.Uint `json:"transactionIndex"` diff --git a/core/types/gen_receipt_json.go b/core/types/gen_receipt_json.go index aae54fecc3b..8a898648386 100644 --- a/core/types/gen_receipt_json.go +++ b/core/types/gen_receipt_json.go @@ -8,6 +8,7 @@ import ( "math/big" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common/hexutil" ) @@ -18,7 +19,7 @@ var _ = (*receiptMarshaling)(nil) func (r Receipt) MarshalJSON() ([]byte, error) { type Receipt struct { Type hexutil.Uint64 `json:"type,omitempty"` - PostState hexutil.Bytes `json:"root"` + PostState hexutility.Bytes `json:"root"` Status hexutil.Uint64 `json:"status"` CumulativeGasUsed hexutil.Uint64 `json:"cumulativeGasUsed" gencodec:"required"` Bloom Bloom `json:"logsBloom" gencodec:"required"` @@ -50,7 +51,7 @@ func (r Receipt) MarshalJSON() ([]byte, error) { func (r *Receipt) UnmarshalJSON(input []byte) error { type Receipt struct { Type *hexutil.Uint64 `json:"type,omitempty"` - PostState *hexutil.Bytes `json:"root"` + PostState *hexutility.Bytes `json:"root"` Status *hexutil.Uint64 `json:"status"` CumulativeGasUsed *hexutil.Uint64 `json:"cumulativeGasUsed" gencodec:"required"` Bloom *Bloom `json:"logsBloom" gencodec:"required"` diff --git a/core/types/genesis.go b/core/types/genesis.go new file mode 100644 index 00000000000..8c2d800ae83 --- /dev/null +++ b/core/types/genesis.go @@ -0,0 +1,165 @@ +// 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 types + +import ( + "bytes" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "math/big" + + "github.com/ledgerwatch/erigon-lib/chain" + "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" + + common2 "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/common/math" + "github.com/ledgerwatch/erigon/params" +) + +//go:generate gencodec -type Genesis -field-override genesisSpecMarshaling -out gen_genesis.go +//go:generate gencodec -type GenesisAccount -field-override genesisAccountMarshaling -out gen_genesis_account.go + +var ErrGenesisNoConfig = errors.New("genesis has no chain configuration") + +// Genesis specifies the header fields, state of a genesis block. It also defines hard +// fork switch-over blocks through the chain configuration. +type Genesis struct { + Config *chain.Config `json:"config"` + Nonce uint64 `json:"nonce"` + Timestamp uint64 `json:"timestamp"` + ExtraData []byte `json:"extraData"` + GasLimit uint64 `json:"gasLimit" gencodec:"required"` + Difficulty *big.Int `json:"difficulty" gencodec:"required"` + Mixhash common.Hash `json:"mixHash"` + Coinbase common.Address `json:"coinbase"` + BaseFee *big.Int `json:"baseFeePerGas"` + ExcessDataGas *big.Int `json:"excessDataGas"` + Alloc GenesisAlloc `json:"alloc" gencodec:"required"` + AuRaStep uint64 `json:"auRaStep"` + AuRaSeal []byte `json:"auRaSeal"` + + // These fields are used for consensus tests. Please don't use them + // in actual genesis blocks. + Number uint64 `json:"number"` + GasUsed uint64 `json:"gasUsed"` + ParentHash common.Hash `json:"parentHash"` +} + +// GenesisAlloc specifies the initial state that is part of the genesis block. +type GenesisAlloc map[common.Address]GenesisAccount + +type AuthorityRoundSeal struct { + /// Seal step. + Step uint64 `json:"step"` + /// Seal signature. + Signature common.Hash `json:"signature"` +} + +func (ga *GenesisAlloc) UnmarshalJSON(data []byte) error { + m := make(map[common2.UnprefixedAddress]GenesisAccount) + if err := json.Unmarshal(data, &m); err != nil { + return err + } + *ga = make(GenesisAlloc) + for addr, a := range m { + (*ga)[common.Address(addr)] = a + } + return nil +} + +// GenesisAccount is an account in the state of the genesis block. +// Either use "constructor" for deployment code or "code" directly for the final code. +type GenesisAccount struct { + Constructor []byte `json:"constructor,omitempty"` // deployment code + Code []byte `json:"code,omitempty"` // final contract code + Storage map[common.Hash]common.Hash `json:"storage,omitempty"` + Balance *big.Int `json:"balance" gencodec:"required"` + Nonce uint64 `json:"nonce,omitempty"` + PrivateKey []byte `json:"secretKey,omitempty"` // for tests +} + +// field type overrides for gencodec +type genesisSpecMarshaling struct { + Nonce math.HexOrDecimal64 + Timestamp math.HexOrDecimal64 + ExtraData hexutility.Bytes + GasLimit math.HexOrDecimal64 + GasUsed math.HexOrDecimal64 + Number math.HexOrDecimal64 + Difficulty *math.HexOrDecimal256 + BaseFee *math.HexOrDecimal256 + ExcessDataGas *math.HexOrDecimal256 + Alloc map[common2.UnprefixedAddress]GenesisAccount +} + +type genesisAccountMarshaling struct { + Constructor hexutility.Bytes + Code hexutility.Bytes + Balance *math.HexOrDecimal256 + Nonce math.HexOrDecimal64 + Storage map[storageJSON]storageJSON + PrivateKey hexutility.Bytes +} + +// storageJSON represents a 256 bit byte array, but allows less than 256 bits when +// unmarshaling from hex. +type storageJSON common.Hash + +func (h *storageJSON) UnmarshalText(text []byte) error { + text = bytes.TrimPrefix(text, []byte("0x")) + if len(text) > 64 { + return fmt.Errorf("too many hex characters in storage key/value %q", text) + } + offset := len(h) - len(text)/2 // pad on the left + if _, err := hex.Decode(h[offset:], text); err != nil { + return fmt.Errorf("invalid hex storage key/value %q", text) + } + return nil +} + +func (h storageJSON) MarshalText() ([]byte, error) { + return hexutility.Bytes(h[:]).MarshalText() +} + +// GenesisMismatchError is raised when trying to overwrite an existing +// genesis block with an incompatible one. +type GenesisMismatchError struct { + Stored, New common.Hash +} + +func (e *GenesisMismatchError) Error() string { + config := params.ChainConfigByGenesisHash(e.Stored) + if config == nil { + return fmt.Sprintf("database contains incompatible genesis (have %x, new %x)", e.Stored, e.New) + } + return fmt.Sprintf("database contains incompatible genesis (try with --chain=%s)", config.ChainName) +} +func (g *Genesis) ConfigOrDefault(genesisHash common.Hash) *chain.Config { + if g != nil { + return g.Config + } + + config := params.ChainConfigByGenesisHash(genesisHash) + if config != nil { + return config + } else { + return params.AllProtocolChanges + } +} diff --git a/core/types/hashing.go b/core/types/hashing.go index d473c3c5f51..eb363872531 100644 --- a/core/types/hashing.go +++ b/core/types/hashing.go @@ -22,6 +22,7 @@ import ( "io" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/protolambda/ztyp/codec" "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/crypto/cryptopool" @@ -190,3 +191,13 @@ func prefixedRlpHash(prefix byte, x interface{}) (h libcommon.Hash) { cryptopool.ReturnToPoolKeccak256(sha) return h } + +// prefixedSSZHash writes the prefix into the hasher before SSZ encoding x. It's used for +// computing the tx id & signing hashes of signed blob transactions. +func prefixedSSZHash(prefix byte, obj codec.Serializable) (h libcommon.Hash) { + sha := crypto.NewKeccakState() + sha.Write([]byte{prefix}) + EncodeSSZ(sha, obj) + sha.Read(h[:]) + return h +} diff --git a/core/types/log.go b/core/types/log.go index 892b8cf34a6..552300f49a6 100644 --- a/core/types/log.go +++ b/core/types/log.go @@ -20,6 +20,7 @@ import ( "io" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/rlp" @@ -189,7 +190,7 @@ Logs: } type logMarshaling struct { - Data hexutil.Bytes + Data hexutility.Bytes BlockNumber hexutil.Uint64 TxIndex hexutil.Uint Index hexutil.Uint diff --git a/core/types/receipt.go b/core/types/receipt.go index 32092fbe236..a8605e5676e 100644 --- a/core/types/receipt.go +++ b/core/types/receipt.go @@ -24,6 +24,7 @@ import ( "math/big" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/crypto" @@ -72,7 +73,7 @@ type Receipt struct { type receiptMarshaling struct { Type hexutil.Uint64 - PostState hexutil.Bytes + PostState hexutility.Bytes Status hexutil.Uint64 CumulativeGasUsed hexutil.Uint64 GasUsed hexutil.Uint64 diff --git a/core/types/signed_blob_tx.go b/core/types/signed_blob_tx.go new file mode 100644 index 00000000000..ca8354ecef9 --- /dev/null +++ b/core/types/signed_blob_tx.go @@ -0,0 +1,596 @@ +package types + +import ( + "bytes" + "encoding/hex" + "errors" + "fmt" + "io" + "math/big" + + "github.com/holiman/uint256" + "github.com/protolambda/ztyp/codec" + "github.com/protolambda/ztyp/conv" + . "github.com/protolambda/ztyp/view" + + "github.com/ledgerwatch/erigon-lib/chain" + libcommon "github.com/ledgerwatch/erigon-lib/common" + types2 "github.com/ledgerwatch/erigon-lib/types" + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/common/u256" + "github.com/ledgerwatch/erigon/params" + "github.com/ledgerwatch/erigon/rlp" +) + +type ECDSASignature struct { + V Uint8View + R Uint256View + S Uint256View +} + +func (sig *ECDSASignature) GetV() *uint256.Int { + bytes := uint256.Int([4]uint64{uint64(sig.V), 0, 0, 0}) + return &bytes +} + +func (sig *ECDSASignature) GetR() *uint256.Int { + r := uint256.Int(sig.R) + return &r +} + +func (sig *ECDSASignature) GetS() *uint256.Int { + s := uint256.Int(sig.S) + return &s +} + +func (sig *ECDSASignature) Deserialize(dr *codec.DecodingReader) error { + return dr.FixedLenContainer(&sig.V, &sig.R, &sig.S) +} + +func (sig *ECDSASignature) Serialize(w *codec.EncodingWriter) error { + return w.FixedLenContainer(&sig.V, &sig.R, &sig.S) +} + +func (*ECDSASignature) ByteLength() uint64 { + return 1 + 32 + 32 +} + +func (*ECDSASignature) FixedLength() uint64 { + return 1 + 32 + 32 +} + +type AddressSSZ libcommon.Address + +func (addr *AddressSSZ) Deserialize(dr *codec.DecodingReader) error { + if addr == nil { + return errors.New("cannot deserialize into nil Address") + } + _, err := dr.Read(addr[:]) + return err +} + +func (addr *AddressSSZ) Serialize(w *codec.EncodingWriter) error { + return w.Write(addr[:]) +} + +func (*AddressSSZ) ByteLength() uint64 { + return 20 +} + +func (*AddressSSZ) FixedLength() uint64 { + return 20 +} + +// AddressOptionalSSZ implements Union[None, Address] +type AddressOptionalSSZ struct { + Address *AddressSSZ +} + +func (ao *AddressOptionalSSZ) Deserialize(dr *codec.DecodingReader) error { + if ao == nil { + return errors.New("cannot deserialize into nil Address") + } + if v, err := dr.ReadByte(); err != nil { + return err + } else if v == 0 { + ao.Address = nil + return nil + } else if v == 1 { + ao.Address = new(AddressSSZ) + if err := ao.Address.Deserialize(dr); err != nil { + return err + } + return nil + } else { + return fmt.Errorf("invalid union selector for Union[None, Address]: %d", v) + } +} + +func (ao *AddressOptionalSSZ) Serialize(w *codec.EncodingWriter) error { + if ao.Address == nil { + return w.WriteByte(0) + } else { + if err := w.WriteByte(1); err != nil { + return err + } + return ao.Address.Serialize(w) + } +} + +func (ao *AddressOptionalSSZ) ByteLength() uint64 { + if ao.Address == nil { + return 1 + } else { + return 1 + 20 + } +} + +func (*AddressOptionalSSZ) FixedLength() uint64 { + return 0 +} + +type TxDataView []byte + +func (tdv *TxDataView) Deserialize(dr *codec.DecodingReader) error { + return dr.ByteList((*[]byte)(tdv), MAX_CALLDATA_SIZE) +} + +func (tdv TxDataView) Serialize(w *codec.EncodingWriter) error { + return w.Write(tdv) +} + +func (tdv TxDataView) ByteLength() (out uint64) { + return uint64(len(tdv)) +} + +func (tdv *TxDataView) FixedLength() uint64 { + return 0 +} + +func (tdv TxDataView) MarshalText() ([]byte, error) { + return conv.BytesMarshalText(tdv[:]) +} + +func (tdv TxDataView) String() string { + return "0x" + hex.EncodeToString(tdv[:]) +} + +func (tdv *TxDataView) UnmarshalText(text []byte) error { + if tdv == nil { + return errors.New("cannot decode into nil blob data") + } + return conv.DynamicBytesUnmarshalText((*[]byte)(tdv), text) +} + +func ReadHashes(dr *codec.DecodingReader, hashes *[]libcommon.Hash, length uint64) error { + if uint64(len(*hashes)) != length { + // re-use space if available (for recycling old state objects) + if uint64(cap(*hashes)) >= length { + *hashes = (*hashes)[:length] + } else { + *hashes = make([]libcommon.Hash, length) + } + } else if *hashes == nil { + // make sure the output is never nil + *hashes = []libcommon.Hash{} + } + dst := *hashes + for i := uint64(0); i < length; i++ { + if _, err := dr.Read(dst[i][:]); err != nil { + return err + } + } + return nil +} + +func ReadHashesLimited(dr *codec.DecodingReader, hashes *[]libcommon.Hash, limit uint64) error { + scope := dr.Scope() + if scope%32 != 0 { + return fmt.Errorf("bad deserialization scope, cannot decode hashes list") + } + length := scope / 32 + if length > limit { + return fmt.Errorf("too many hashes: %d > %d", length, limit) + } + return ReadHashes(dr, hashes, length) +} + +func WriteHashes(ew *codec.EncodingWriter, hashes []libcommon.Hash) error { + for i := range hashes { + if err := ew.Write(hashes[i][:]); err != nil { + return err + } + } + return nil +} + +type VersionedHashesView []libcommon.Hash + +func (vhv *VersionedHashesView) Deserialize(dr *codec.DecodingReader) error { + return ReadHashesLimited(dr, (*[]libcommon.Hash)(vhv), MAX_VERSIONED_HASHES_LIST_SIZE) +} + +func (vhv VersionedHashesView) Serialize(w *codec.EncodingWriter) error { + return WriteHashes(w, vhv) +} + +func (vhv VersionedHashesView) ByteLength() (out uint64) { + return uint64(len(vhv)) * 32 +} + +func (vhv *VersionedHashesView) FixedLength() uint64 { + return 0 // it's a list, no fixed length +} + +type StorageKeysView []libcommon.Hash + +func (skv *StorageKeysView) Deserialize(dr *codec.DecodingReader) error { + return ReadHashesLimited(dr, (*[]libcommon.Hash)(skv), MAX_ACCESS_LIST_STORAGE_KEYS) +} + +func (skv StorageKeysView) Serialize(w *codec.EncodingWriter) error { + return WriteHashes(w, skv) +} + +func (skv StorageKeysView) ByteLength() (out uint64) { + return uint64(len(skv)) * 32 +} + +func (skv *StorageKeysView) FixedLength() uint64 { + return 0 // it's a list, no fixed length +} + +type AccessTupleView types2.AccessTuple + +func (atv *AccessTupleView) Deserialize(dr *codec.DecodingReader) error { + return dr.Container((*AddressSSZ)(&atv.Address), (*StorageKeysView)(&atv.StorageKeys)) +} + +func (atv *AccessTupleView) Serialize(w *codec.EncodingWriter) error { + return w.Container((*AddressSSZ)(&atv.Address), (*StorageKeysView)(&atv.StorageKeys)) +} + +func (atv *AccessTupleView) ByteLength() uint64 { + return codec.ContainerLength((*AddressSSZ)(&atv.Address), (*StorageKeysView)(&atv.StorageKeys)) +} + +func (atv *AccessTupleView) FixedLength() uint64 { + return 0 +} + +type AccessListView types2.AccessList + +func (alv *AccessListView) Deserialize(dr *codec.DecodingReader) error { + *alv = AccessListView([]types2.AccessTuple{}) + return dr.List(func() codec.Deserializable { + i := len(*alv) + *alv = append(*alv, types2.AccessTuple{}) + return (*AccessTupleView)(&((*alv)[i])) + }, 0, MAX_ACCESS_LIST_SIZE) +} + +func (alv AccessListView) Serialize(w *codec.EncodingWriter) error { + return w.List(func(i uint64) codec.Serializable { + return (*AccessTupleView)(&alv[i]) + }, 0, uint64(len(alv))) +} + +func (alv AccessListView) ByteLength() (out uint64) { + for idx := range alv { + out += (*AccessTupleView)(&alv[idx]).ByteLength() + codec.OFFSET_SIZE + } + return +} + +func (alv *AccessListView) FixedLength() uint64 { + return 0 +} + +type BlobTxMessage struct { + ChainID Uint256View + Nonce Uint64View + GasTipCap Uint256View // a.k.a. maxPriorityFeePerGas + GasFeeCap Uint256View // a.k.a. maxFeePerGas + Gas Uint64View + To AddressOptionalSSZ // nil means contract creation + Value Uint256View + Data TxDataView + AccessList AccessListView + MaxFeePerDataGas Uint256View + + BlobVersionedHashes VersionedHashesView +} + +func (tx *BlobTxMessage) Deserialize(dr *codec.DecodingReader) error { + err := dr.Container(&tx.ChainID, &tx.Nonce, &tx.GasTipCap, &tx.GasFeeCap, &tx.Gas, &tx.To, &tx.Value, &tx.Data, &tx.AccessList, &tx.MaxFeePerDataGas, &tx.BlobVersionedHashes) + return err +} + +func (tx *BlobTxMessage) Serialize(w *codec.EncodingWriter) error { + return w.Container(&tx.ChainID, &tx.Nonce, &tx.GasTipCap, &tx.GasFeeCap, &tx.Gas, &tx.To, &tx.Value, &tx.Data, &tx.AccessList, &tx.MaxFeePerDataGas, &tx.BlobVersionedHashes) +} + +func (tx *BlobTxMessage) ByteLength() uint64 { + return codec.ContainerLength(&tx.ChainID, &tx.Nonce, &tx.GasTipCap, &tx.GasFeeCap, &tx.Gas, &tx.To, &tx.Value, &tx.Data, &tx.AccessList, &tx.MaxFeePerDataGas, &tx.BlobVersionedHashes) +} + +func (tx *BlobTxMessage) FixedLength() uint64 { + return 0 +} + +// copy creates a deep copy of the transaction data and initializes all fields. +func (tx *BlobTxMessage) copy() *BlobTxMessage { + cpy := &BlobTxMessage{ + ChainID: tx.ChainID, + Nonce: tx.Nonce, + GasTipCap: tx.GasTipCap, + GasFeeCap: tx.GasFeeCap, + Gas: tx.Gas, + To: AddressOptionalSSZ{Address: (*AddressSSZ)(copyAddressPtr((*libcommon.Address)(tx.To.Address)))}, + Value: tx.Value, + Data: common.CopyBytes(tx.Data), + AccessList: make([]types2.AccessTuple, len(tx.AccessList)), + MaxFeePerDataGas: tx.MaxFeePerDataGas, + BlobVersionedHashes: make([]libcommon.Hash, len(tx.BlobVersionedHashes)), + } + copy(cpy.AccessList, tx.AccessList) + copy(cpy.BlobVersionedHashes, tx.BlobVersionedHashes) + + return cpy +} + +type SignedBlobTx struct { + TransactionMisc + + Message BlobTxMessage + Signature ECDSASignature +} + +var _ Transaction = &SignedBlobTx{} + +const ( + MAX_CALLDATA_SIZE = 1 << 24 + MAX_ACCESS_LIST_SIZE = 1 << 24 + MAX_ACCESS_LIST_STORAGE_KEYS = 1 << 24 + MAX_VERSIONED_HASHES_LIST_SIZE = 1 << 24 +) + +// copy creates a deep copy of the transaction data and initializes all fields. +func (stx SignedBlobTx) copy() *SignedBlobTx { + cpy := &SignedBlobTx{ + Message: *stx.Message.copy(), + Signature: stx.Signature, + } + + return cpy +} + +func (stx SignedBlobTx) Type() byte { return BlobTxType } + +func (stx SignedBlobTx) GetChainID() *uint256.Int { + chainID := uint256.Int(stx.Message.ChainID) + return &chainID +} + +func (stx SignedBlobTx) GetNonce() uint64 { return uint64(stx.Message.Nonce) } +func (stx SignedBlobTx) GetGas() uint64 { return uint64(stx.Message.Gas) } +func (stx SignedBlobTx) GetDataGas() uint64 { + return params.DataGasPerBlob * uint64(len(stx.Message.BlobVersionedHashes)) +} +func (stx SignedBlobTx) GetTo() *libcommon.Address { + return (*libcommon.Address)(stx.Message.To.Address) +} +func (stx SignedBlobTx) GetAmount() uint256.Int { return uint256.Int(stx.Message.Value) } +func (stx SignedBlobTx) GetData() []byte { return stx.Message.Data } +func (stx SignedBlobTx) GetValue() *uint256.Int { + value := uint256.Int(stx.Message.Value) + return &value +} + +func (stx SignedBlobTx) GetPrice() *uint256.Int { + tip := (uint256.Int)(stx.Message.GasTipCap) + return &tip +} +func (stx SignedBlobTx) GetFeeCap() *uint256.Int { + feeCap := (uint256.Int)(stx.Message.GasFeeCap) + return &feeCap +} + +func (stx *SignedBlobTx) GetTip() *uint256.Int { + tip := (uint256.Int)(stx.Message.GasTipCap) + return &tip +} + +func (stx *SignedBlobTx) GetEffectiveGasTip(baseFee *uint256.Int) *uint256.Int { + if baseFee == nil { + return stx.GetTip() + } + gasFeeCap := stx.GetFeeCap() + // return 0 because effectiveFee cant be < 0 + if gasFeeCap.Lt(baseFee) { + return uint256.NewInt(0) + } + effectiveFee := new(uint256.Int).Sub(gasFeeCap, baseFee) + if stx.GetTip().Lt(effectiveFee) { + return stx.GetTip() + } else { + return effectiveFee + } +} + +func (stx *SignedBlobTx) Cost() *uint256.Int { + total := new(uint256.Int).SetUint64(uint64(stx.Message.Gas)) + tip := uint256.Int(stx.Message.GasTipCap) + total.Mul(total, &tip) + + value := uint256.Int(stx.Message.Value) + total.Add(total, &value) + return total +} + +func (stx *SignedBlobTx) GetMaxFeePerDataGas() *uint256.Int { + fee := (uint256.Int)(stx.Message.MaxFeePerDataGas) + return &fee +} + +func (stx *SignedBlobTx) GetDataHashes() []libcommon.Hash { + return []libcommon.Hash(stx.Message.BlobVersionedHashes) +} + +// TODO +func (stx *SignedBlobTx) Sender(signer Signer) (libcommon.Address, error) { + if sc := stx.from.Load(); sc != nil { + return sc.(libcommon.Address), nil + } + + addr, err := signer.Sender(stx) + if err != nil { + return libcommon.Address{}, err + } + + stx.from.Store(addr) + return addr, nil +} + +func (stx *SignedBlobTx) GetSender() (libcommon.Address, bool) { + if sc := stx.from.Load(); sc != nil { + return sc.(libcommon.Address), true + } + return libcommon.Address{}, false +} + +func (stx *SignedBlobTx) SetSender(addr libcommon.Address) { + stx.from.Store(addr) +} + +func (stx *SignedBlobTx) IsContractDeploy() bool { + return stx.GetTo() == nil +} + +func (stx *SignedBlobTx) Unwrap() Transaction { + return stx +} + +func (stx SignedBlobTx) Protected() bool { + return true +} + +func (stx *SignedBlobTx) WithSignature(signer Signer, sig []byte) (Transaction, error) { + cpy := stx.copy() + r, s, v, err := signer.SignatureValues(stx, sig) + if err != nil { + return nil, err + } + + cpy.Signature.R = Uint256View(*r) + cpy.Signature.V = Uint8View([4]uint64(*v)[0]) + cpy.Signature.S = Uint256View(*s) + cpy.Message.ChainID = Uint256View(*signer.ChainID()) + return cpy, nil +} + +func (tx *SignedBlobTx) FakeSign(address libcommon.Address) (Transaction, error) { + cpy := tx.copy() + cpy.Signature.R = Uint256View(*u256.Num1) + cpy.Signature.S = Uint256View(*u256.Num1) + cpy.Signature.V = Uint8View([4]uint64(*u256.Num4)[0]) + + cpy.from.Store(address) + return cpy, nil +} + +func (tx *SignedBlobTx) GetAccessList() types2.AccessList { + return types2.AccessList(tx.Message.AccessList) +} + +func (stx SignedBlobTx) AsMessage(s Signer, baseFee *big.Int, rules *chain.Rules) (Message, error) { + msg := Message{ + nonce: stx.GetNonce(), + gasLimit: stx.GetGas(), + tip: *stx.GetTip(), + feeCap: *stx.GetFeeCap(), + to: stx.GetTo(), + amount: stx.GetAmount(), + data: stx.Message.Data, + accessList: stx.GetAccessList(), + maxFeePerDataGas: *stx.GetMaxFeePerDataGas(), + dataHashes: stx.GetDataHashes(), + checkNonce: true, + } + + if baseFee != nil { + overflow := msg.gasPrice.SetFromBig(baseFee) + if overflow { + return msg, fmt.Errorf("gasPrice higher than 2^256-1") + } + } + msg.gasPrice.Add(&msg.gasPrice, stx.GetTip()) + if msg.gasPrice.Gt(stx.GetFeeCap()) { + msg.gasPrice.Set(stx.GetFeeCap()) + } + + var err error + msg.from, err = stx.Sender(s) + return msg, err +} + +// Hash computes the hash (but not for signatures!) +func (stx *SignedBlobTx) Hash() libcommon.Hash { + return prefixedSSZHash(BlobTxType, stx) +} + +// MarshalBinary returns the canonical encoding of the transaction. +// For legacy transactions, it returns the RLP encoding. For EIP-2718 typed +// transactions, it returns the type and payload. +func (tx SignedBlobTx) MarshalBinary(w io.Writer) error { + var b [33]byte + // encode TxType + b[0] = BlobTxType + if _, err := w.Write(b[:1]); err != nil { + return err + } + wcodec := codec.NewEncodingWriter(w) + return tx.Serialize(wcodec) +} + +func (stx SignedBlobTx) EncodeRLP(w io.Writer) error { + var buf bytes.Buffer + if err := stx.MarshalBinary(&buf); err != nil { + return err + } + return rlp.Encode(w, buf.Bytes()) +} + +func (tx SignedBlobTx) RawSignatureValues() (v *uint256.Int, r *uint256.Int, s *uint256.Int) { + return tx.Signature.GetV(), tx.Signature.GetR(), tx.Signature.GetS() +} + +func (stx SignedBlobTx) SigningHash(chainID *big.Int) libcommon.Hash { + // stx is a shallow copy of the tx so we can modify ChainID without mutating the input + stx.Message.ChainID.SetFromBig(chainID) + return prefixedSSZHash(BlobTxType, &stx.Message) +} + +func (tx SignedBlobTx) EncodingSize() int { + envelopeSize := int(codec.ContainerLength(&tx.Message, &tx.Signature)) + // Add type byte + envelopeSize++ + return envelopeSize +} + +func (stx *SignedBlobTx) Deserialize(dr *codec.DecodingReader) error { + err := dr.Container(&stx.Message, &stx.Signature) + return err +} + +func (stx *SignedBlobTx) Serialize(w *codec.EncodingWriter) error { + return w.Container(&stx.Message, &stx.Signature) +} + +func (stx *SignedBlobTx) ByteLength() uint64 { + return codec.ContainerLength(&stx.Message, &stx.Signature) +} + +func (stx *SignedBlobTx) FixedLength() uint64 { + return 0 +} diff --git a/core/types/transaction.go b/core/types/transaction.go index 8df16bf4526..a556964d032 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -31,10 +31,12 @@ import ( libcommon "github.com/ledgerwatch/erigon-lib/common" types2 "github.com/ledgerwatch/erigon-lib/types" "github.com/ledgerwatch/log/v3" + "github.com/protolambda/ztyp/codec" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/math" "github.com/ledgerwatch/erigon/crypto" + "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/rlp" ) @@ -50,6 +52,7 @@ const ( LegacyTxType = iota AccessListTxType DynamicFeeTxType + BlobTxType ) // Transaction is an Ethereum transaction. @@ -62,6 +65,7 @@ type Transaction interface { GetEffectiveGasTip(baseFee *uint256.Int) *uint256.Int GetFeeCap() *uint256.Int Cost() *uint256.Int + GetDataHashes() []libcommon.Hash GetGas() uint64 GetValue() *uint256.Int Time() time.Time @@ -453,21 +457,23 @@ func (t *TransactionsFixedOrder) Pop() { // Message is a fully derived transaction and implements core.Message type Message struct { - to *libcommon.Address - from libcommon.Address - nonce uint64 - amount uint256.Int - gasLimit uint64 - gasPrice uint256.Int - feeCap uint256.Int - tip uint256.Int - data []byte - accessList types2.AccessList - checkNonce bool - isFree bool -} - -func NewMessage(from libcommon.Address, to *libcommon.Address, nonce uint64, amount *uint256.Int, gasLimit uint64, gasPrice *uint256.Int, feeCap, tip *uint256.Int, data []byte, accessList types2.AccessList, checkNonce bool, isFree bool) Message { + to *libcommon.Address + from libcommon.Address + nonce uint64 + amount uint256.Int + gasLimit uint64 + gasPrice uint256.Int + feeCap uint256.Int + tip uint256.Int + maxFeePerDataGas uint256.Int + data []byte + accessList types2.AccessList + checkNonce bool + isFree bool + dataHashes []libcommon.Hash +} + +func NewMessage(from libcommon.Address, to *libcommon.Address, nonce uint64, amount *uint256.Int, gasLimit uint64, gasPrice *uint256.Int, feeCap, tip *uint256.Int, data []byte, accessList types2.AccessList, checkNonce bool, isFree bool, maxFeePerDataGas *uint256.Int) Message { m := Message{ from: from, to: to, @@ -488,6 +494,9 @@ func NewMessage(from libcommon.Address, to *libcommon.Address, nonce uint64, amo if feeCap != nil { m.feeCap.Set(feeCap) } + if maxFeePerDataGas != nil { + m.maxFeePerDataGas.Set(maxFeePerDataGas) + } return m } @@ -525,3 +534,28 @@ func (m *Message) ChangeGas(globalGasCap, desiredGas uint64) { m.gasLimit = gas } + +func (m Message) DataGas() uint64 { return params.DataGasPerBlob * uint64(len(m.dataHashes)) } +func (m Message) MaxFeePerDataGas() *uint256.Int { + return &m.maxFeePerDataGas +} + +func (m Message) DataHashes() []libcommon.Hash { return m.dataHashes } + +func DecodeSSZ(data []byte, dest codec.Deserializable) error { + err := dest.Deserialize(codec.NewDecodingReader(bytes.NewReader(data), uint64(len(data)))) + return err +} + +func EncodeSSZ(w io.Writer, obj codec.Serializable) error { + return obj.Serialize(codec.NewEncodingWriter(w)) +} + +// copyAddressPtr copies an address. +func copyAddressPtr(a *libcommon.Address) *libcommon.Address { + if a == nil { + return nil + } + cpy := *a + return &cpy +} diff --git a/core/types/transaction_marshalling.go b/core/types/transaction_marshalling.go index b1188293458..f66134f6fd4 100644 --- a/core/types/transaction_marshalling.go +++ b/core/types/transaction_marshalling.go @@ -6,9 +6,11 @@ import ( "fmt" "github.com/holiman/uint256" + "github.com/valyala/fastjson" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" types2 "github.com/ledgerwatch/erigon-lib/types" - "github.com/valyala/fastjson" "github.com/ledgerwatch/erigon/common/hexutil" ) @@ -24,7 +26,7 @@ type txJSON struct { Tip *hexutil.Big `json:"maxPriorityFeePerGas"` Gas *hexutil.Uint64 `json:"gas"` Value *hexutil.Big `json:"value"` - Data *hexutil.Bytes `json:"input"` + Data *hexutility.Bytes `json:"input"` V *hexutil.Big `json:"v"` R *hexutil.Big `json:"r"` S *hexutil.Big `json:"s"` @@ -47,7 +49,7 @@ func (tx LegacyTx) MarshalJSON() ([]byte, error) { enc.Gas = (*hexutil.Uint64)(&tx.Gas) enc.GasPrice = (*hexutil.Big)(tx.GasPrice.ToBig()) enc.Value = (*hexutil.Big)(tx.Value.ToBig()) - enc.Data = (*hexutil.Bytes)(&tx.Data) + enc.Data = (*hexutility.Bytes)(&tx.Data) enc.To = tx.To enc.V = (*hexutil.Big)(tx.V.ToBig()) enc.R = (*hexutil.Big)(tx.R.ToBig()) @@ -66,7 +68,7 @@ func (tx AccessListTx) MarshalJSON() ([]byte, error) { enc.Gas = (*hexutil.Uint64)(&tx.Gas) enc.GasPrice = (*hexutil.Big)(tx.GasPrice.ToBig()) enc.Value = (*hexutil.Big)(tx.Value.ToBig()) - enc.Data = (*hexutil.Bytes)(&tx.Data) + enc.Data = (*hexutility.Bytes)(&tx.Data) enc.To = tx.To enc.V = (*hexutil.Big)(tx.V.ToBig()) enc.R = (*hexutil.Big)(tx.R.ToBig()) @@ -86,7 +88,7 @@ func (tx DynamicFeeTransaction) MarshalJSON() ([]byte, error) { enc.FeeCap = (*hexutil.Big)(tx.FeeCap.ToBig()) enc.Tip = (*hexutil.Big)(tx.Tip.ToBig()) enc.Value = (*hexutil.Big)(tx.Value.ToBig()) - enc.Data = (*hexutil.Bytes)(&tx.Data) + enc.Data = (*hexutility.Bytes)(&tx.Data) enc.To = tx.To enc.V = (*hexutil.Big)(tx.V.ToBig()) enc.R = (*hexutil.Big)(tx.R.ToBig()) diff --git a/core/types/vote.go b/core/types/vote.go new file mode 100644 index 00000000000..8c4882243ce --- /dev/null +++ b/core/types/vote.go @@ -0,0 +1,91 @@ +package types + +import ( + "sync/atomic" + + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/pkg/errors" + "github.com/prysmaticlabs/prysm/v4/crypto/bls" +) + +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 libcommon.Hash // The block hash of the source block. + TargetNumber uint64 // The target block number which validator wants to vote for. + TargetHash libcommon.Hash // The block hash of the target block. +} + +// Hash returns the hash of the vote data. +func (d *VoteData) Hash() libcommon.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() libcommon.Hash { + if hash := v.hash.Load(); hash != nil { + return hash.(libcommon.Hash) + } + + h := v.calcVoteHash() + v.hash.Store(h) + return h +} + +func (v *VoteEnvelope) calcVoteHash() libcommon.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 c3a4beb2327..2485f41381c 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -17,11 +17,14 @@ package vm import ( - "crypto/sha256" "encoding/binary" "errors" "math/big" + "github.com/ledgerwatch/log/v3" + "github.com/minio/sha256-simd" + "github.com/prysmaticlabs/prysm/v4/crypto/bls" + "github.com/holiman/uint256" "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" @@ -155,7 +158,43 @@ var PrecompiledContractsBLS = map[libcommon.Address]PrecompiledContract{ libcommon.BytesToAddress([]byte{18}): &bls12381MapG2{}, } +var PrecompiledContractsPlanck = map[libcommon.Address]PrecompiledContract{ + libcommon.BytesToAddress([]byte{1}): &ecrecover{}, + libcommon.BytesToAddress([]byte{2}): &sha256hash{}, + libcommon.BytesToAddress([]byte{3}): &ripemd160hash{}, + libcommon.BytesToAddress([]byte{4}): &dataCopy{}, + libcommon.BytesToAddress([]byte{5}): &bigModExp{}, + libcommon.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, + libcommon.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, + libcommon.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, + libcommon.BytesToAddress([]byte{9}): &blake2F{}, + + libcommon.BytesToAddress([]byte{100}): &tmHeaderValidate{}, + libcommon.BytesToAddress([]byte{101}): &iavlMerkleProofValidatePlanck{}, +} + +// PrecompiledContractsLuban contains the default set of pre-compiled Ethereum +// contracts used in the Luban release. +var PrecompiledContractsLuban = map[libcommon.Address]PrecompiledContract{ + libcommon.BytesToAddress([]byte{1}): &ecrecover{}, + libcommon.BytesToAddress([]byte{2}): &sha256hash{}, + libcommon.BytesToAddress([]byte{3}): &ripemd160hash{}, + libcommon.BytesToAddress([]byte{4}): &dataCopy{}, + libcommon.BytesToAddress([]byte{5}): &bigModExp{}, + libcommon.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, + libcommon.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, + libcommon.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, + libcommon.BytesToAddress([]byte{9}): &blake2F{}, + + libcommon.BytesToAddress([]byte{100}): &tmHeaderValidate{}, + libcommon.BytesToAddress([]byte{101}): &iavlMerkleProofValidatePlanck{}, + libcommon.BytesToAddress([]byte{102}): &blsSignatureVerify{}, + libcommon.BytesToAddress([]byte{103}): &cometBFTLightBlockValidate{}, +} + var ( + PrecompiledAddressesLuban []libcommon.Address + PrecompiledAddressesPlanck []libcommon.Address PrecompiledAddressesMoran []libcommon.Address PrecompiledAddressesNano []libcommon.Address PrecompiledAddressesBerlin []libcommon.Address @@ -187,11 +226,22 @@ func init() { for k := range PrecompiledContractsIsMoran { PrecompiledAddressesMoran = append(PrecompiledAddressesMoran, k) } + for k := range PrecompiledContractsPlanck { + PrecompiledAddressesPlanck = append(PrecompiledAddressesPlanck, k) + } + + for k := range PrecompiledContractsLuban { + PrecompiledAddressesLuban = append(PrecompiledAddressesLuban, k) + } } // ActivePrecompiles returns the precompiles enabled with the current configuration. func ActivePrecompiles(rules *chain.Rules) []libcommon.Address { switch { + case rules.IsLuban: + return PrecompiledAddressesLuban + case rules.IsPlanck: + return PrecompiledAddressesPlanck case rules.IsMoran: return PrecompiledAddressesMoran case rules.IsNano: @@ -314,6 +364,7 @@ type bigModExp struct { } var ( + big0 = big.NewInt(0) big1 = big.NewInt(1) big3 = big.NewInt(3) big4 = big.NewInt(4) @@ -1126,3 +1177,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_lightclient.go b/core/vm/contracts_lightclient.go index e6b11d5e7b0..f914f7ce48f 100644 --- a/core/vm/contracts_lightclient.go +++ b/core/vm/contracts_lightclient.go @@ -3,10 +3,14 @@ package vm import ( "encoding/binary" "fmt" + "net/url" + "strings" + "github.com/ledgerwatch/erigon/core/vm/lightclient/iavl" cmn "github.com/tendermint/tendermint/libs/common" - "github.com/ledgerwatch/erigon/core/vm/lightclient" + v1 "github.com/ledgerwatch/erigon/core/vm/lightclient/v1" + v2 "github.com/ledgerwatch/erigon/core/vm/lightclient/v2" "github.com/ledgerwatch/erigon/params" "github.com/tendermint/tendermint/crypto/merkle" ) @@ -23,17 +27,22 @@ const ( // input: // consensus state length | consensus state | tendermint header | // 32 bytes | | | -func decodeTendermintHeaderValidationInput(input []byte) (*lightclient.ConsensusState, *lightclient.Header, error) { +func decodeTendermintHeaderValidationInput(input []byte) (*v1.ConsensusState, *v1.Header, error) { csLen := binary.BigEndian.Uint64(input[consensusStateLengthBytesLength-uint64TypeLength : consensusStateLengthBytesLength]) + + if consensusStateLengthBytesLength+csLen < consensusStateLengthBytesLength { + return nil, nil, fmt.Errorf("integer overflow, csLen: %d", csLen) + } + if uint64(len(input)) <= consensusStateLengthBytesLength+csLen { return nil, nil, fmt.Errorf("expected payload size %d, actual size: %d", consensusStateLengthBytesLength+csLen, len(input)) } - cs, err := lightclient.DecodeConsensusState(input[consensusStateLengthBytesLength : consensusStateLengthBytesLength+csLen]) + cs, err := v1.DecodeConsensusState(input[consensusStateLengthBytesLength : consensusStateLengthBytesLength+csLen]) if err != nil { return nil, nil, err } - header, err := lightclient.DecodeHeader(input[consensusStateLengthBytesLength+csLen:]) + header, err := v1.DecodeHeader(input[consensusStateLengthBytesLength+csLen:]) if err != nil { return nil, nil, err } @@ -41,7 +50,8 @@ func decodeTendermintHeaderValidationInput(input []byte) (*lightclient.Consensus return &cs, header, nil } -// tmHeaderValidate implemented as a native contract. +// tmHeaderValidate implemented as a native contract. Used to validate the light +// client's new header for tendermint v0.31.12 and its compatible version.type tmHeaderValidate struct{} type tmHeaderValidate struct{} func (c *tmHeaderValidate) RequiredGas(input []byte) uint64 { @@ -152,8 +162,38 @@ func (c *iavlMerkleProofValidateMoran) Run(input []byte) (result []byte, err err return c.basicIavlMerkleProofValidate.Run(input) } +type iavlMerkleProofValidatePlanck struct { + basicIavlMerkleProofValidate +} + +func (c *iavlMerkleProofValidatePlanck) RequiredGas(_ []byte) uint64 { + return params.IAVLMerkleProofValidateGas +} + +func (c *iavlMerkleProofValidatePlanck) Run(input []byte) (result []byte, err error) { + c.basicIavlMerkleProofValidate.proofRuntime = v1.Ics23CompatibleProofRuntime() + c.basicIavlMerkleProofValidate.verifiers = []merkle.ProofOpVerifier{ + forbiddenAbsenceOpVerifier, + singleValueOpVerifier, + multiStoreOpVerifier, + forbiddenSimpleValueOpVerifier, + } + c.basicIavlMerkleProofValidate.keyVerifier = keyVerifier + c.basicIavlMerkleProofValidate.opsVerifier = proofOpsVerifier + return c.basicIavlMerkleProofValidate.Run(input) +} + +func successfulMerkleResult() []byte { + result := make([]byte, merkleProofValidateResultLength) + binary.BigEndian.PutUint64(result[merkleProofValidateResultLength-uint64TypeLength:], 0x01) + return result +} + type basicIavlMerkleProofValidate struct { - verifiers []merkle.ProofOpVerifier + keyVerifier v1.KeyVerifier + opsVerifier merkle.ProofOpsVerifier + verifiers []merkle.ProofOpVerifier + proofRuntime *merkle.ProofRuntime } func (c *basicIavlMerkleProofValidate) Run(input []byte) (result []byte, err error) { @@ -172,20 +212,26 @@ func (c *basicIavlMerkleProofValidate) Run(input []byte) (result []byte, err err return nil, fmt.Errorf("invalid input: input size should be %d, actual the size is %d", payloadLength+precompileContractInputMetaDataLength, len(input)) } - kvmp, err := lightclient.DecodeKeyValueMerkleProof(input[precompileContractInputMetaDataLength:]) + kvmp, err := v1.DecodeKeyValueMerkleProof(input[precompileContractInputMetaDataLength:]) if err != nil { return nil, err } + if c.proofRuntime == nil { + kvmp.SetProofRuntime(v1.DefaultProofRuntime()) + } else { + kvmp.SetProofRuntime(c.proofRuntime) + } kvmp.SetVerifiers(c.verifiers) + kvmp.SetOpsVerifier(c.opsVerifier) + kvmp.SetKeyVerifier(c.keyVerifier) + valid := kvmp.Validate() if !valid { return nil, fmt.Errorf("invalid merkle proof") } - result = make([]byte, merkleProofValidateResultLength) - binary.BigEndian.PutUint64(result[merkleProofValidateResultLength-uint64TypeLength:], 0x01) - return result, nil + return successfulMerkleResult(), nil } func forbiddenAbsenceOpVerifier(op merkle.ProofOperator) error { if op == nil { @@ -211,7 +257,7 @@ func multiStoreOpVerifier(op merkle.ProofOperator) error { if op == nil { return nil } - if mop, ok := op.(lightclient.MultiStoreProofOp); ok { + if mop, ok := op.(v1.MultiStoreProofOp); ok { storeNames := make(map[string]bool, len(mop.Proof.StoreInfos)) for _, store := range mop.Proof.StoreInfos { if exist := storeNames[store.Name]; exist { @@ -240,3 +286,81 @@ func singleValueOpVerifier(op merkle.ProofOperator) error { } return nil } + +func proofOpsVerifier(poz merkle.ProofOperators) error { + if len(poz) != 2 { + return cmn.NewError("proof ops should be 2") + } + + // for legacy proof type + if _, ok := poz[1].(v1.MultiStoreProofOp); ok { + if _, ok := poz[0].(iavl.IAVLValueOp); !ok { + return cmn.NewError("invalid proof op") + } + return nil + } + + // for ics23 proof type + if op2, ok := poz[1].(v1.CommitmentOp); ok { + if op2.Type != v1.ProofOpSimpleMerkleCommitment { + return cmn.NewError("invalid proof op") + } + + op1, ok := poz[0].(v1.CommitmentOp) + if !ok { + return cmn.NewError("invalid proof op") + } + + if op1.Type != v1.ProofOpIAVLCommitment { + return cmn.NewError("invalid proof op") + } + return nil + } + + return cmn.NewError("invalid proof type") +} + +func keyVerifier(key string) error { + // https://github.com/bnb-chain/tendermint/blob/72375a6f3d4a72831cc65e73363db89a0073db38/crypto/merkle/proof_key_path.go#L88 + // since the upper function is ambiguous, `x:00` can be decoded to both kind of key type + // we check the key here to make sure the key will not start from `x:` + if strings.HasPrefix(url.PathEscape(key), "x:") { + return cmn.NewError("key should not start with x:") + } + return nil +} + +// cometBFTLightBlockValidate implemented as a native contract. Used to validate the light blocks for CometBFT v0.37.0 +// and its compatible version. Besides, in order to support the BLS cross-chain infrastructure, the SetRelayerAddress +// and SetBlsKey methods should be implemented for the validator. +type cometBFTLightBlockValidate struct{} + +func (c *cometBFTLightBlockValidate) RequiredGas(input []byte) uint64 { + return params.CometBFTLightBlockValidateGas +} + +func (c *cometBFTLightBlockValidate) Run(input []byte) (result []byte, err error) { + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("internal error: %v\n", r) + } + }() + + cs, block, err := v2.DecodeLightBlockValidationInput(input) + if err != nil { + return nil, err + } + + validatorSetChanged, err := cs.ApplyLightBlock(block) + if err != nil { + return nil, err + } + + consensusStateBytes, err := cs.EncodeConsensusState() + if err != nil { + return nil, err + } + + result = v2.EncodeLightBlockValidationResult(validatorSetChanged, consensusStateBytes) + return result, nil +} diff --git a/core/vm/contracts_lightclient_test.go b/core/vm/contracts_lightclient_test.go index ef58579041d..2327c831614 100644 --- a/core/vm/contracts_lightclient_test.go +++ b/core/vm/contracts_lightclient_test.go @@ -3,12 +3,16 @@ package vm import ( "encoding/binary" "encoding/hex" - "github.com/stretchr/testify/assert" + "github.com/ledgerwatch/erigon/core/vm/lightclient/v1" "testing" + "github.com/stretchr/testify/assert" + "github.com/tendermint/tendermint/crypto/merkle" + cmn "github.com/tendermint/tendermint/libs/common" + "github.com/stretchr/testify/require" - "github.com/ledgerwatch/erigon/core/vm/lightclient" + "github.com/ledgerwatch/erigon/core/vm/lightclient/iavl" ) const ( @@ -28,7 +32,7 @@ func TestTmHeaderValidateAndMerkleProofValidate(t *testing.T) { "da8a0bf13b1abaeee7a8f9383542099a554d219b93d0ce69e3970e8000000174876e800") require.NoError(t, err) - cs, err := lightclient.DecodeConsensusState(consensusStateBytes) + cs, err := v1.DecodeConsensusState(consensusStateBytes) require.NoError(t, err) headerBytes, err := hex.DecodeString("e3210a92130abb020a02080a121242696e616e63652d436861696e2d4e696c6518e38bf01f220c08e191aef20510f5f4e4c70230dae0c7173a480a20102b54820dd8fb5bc2c4e875ee573fa294d9b7b7ceb362aa8fd21b33dee41b1c12240801122082f341511f3e6b89d6177fd31f8a106013ba09d6e12ef40a7dec885d81b687634220b1b77e6977e0cd0177e3102a78833c9e152aa646ed4fb5a77e8af58c9867eec0522080d9ab0fc10d18ca0e0832d5f4c063c5489ec1443dfb738252d038a82131b27a5a2080d9ab0fc10d18ca0e0832d5f4c063c5489ec1443dfb738252d038a82131b27a6220294d8fbd0b94b767a7eba9840f299a3586da7fe6b5dead3b7eecba193c400f936a20a3e248bc209955054d880e4d89ff3c0419c0cd77681f4b4c6649ead5545054b982011462633d9db7ed78e951f79913fdc8231aa77ec12b12d1100a480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be212b601080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510cebfe23e321406fd60078eb4c2356137dd50036597db267cf61642409276f20ad4b152f91c344bd63ac691bad66e04e228a8b58dca293ff0bd10f8aef6dfbcecae49e32b09d89e10b771a6c01628628596a95e126b04763560c66c0f12b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510a4caa532321418e69cc672973992bb5f76d049a5b2c5ddf77436380142409ed2b74fa835296d552e68c439dd4ee3fa94fb197282edcc1cc815c863ca42a2c9a73475ff6be9064371a61655a3c31d2f0acc89c3a4489ad4c2671aef52360512b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510a69eca2f3214344c39bb8f4512d6cab1f6aafac1811ef9d8afdf38024240de2768ead90011bcbb1914abc1572749ab7b81382eb81cff3b41c56edc12470a7b8a4d61f8b4ca7b2cb7e24706edd219455796b4db74cd36965859f91dc8910312b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510dcdd833b321437ef19af29679b368d2b9e9de3f8769b357866763803424072ddfe0aeb13616b3f17eb60b19a923ec51fcc726625094aa069255c829c8cdd9e242080a1e559b0030fe9a0db19fd34e392bd78df12a9caff9f2b811bc1ac0a12b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510e9f2f859321462633d9db7ed78e951f79913fdc8231aa77ec12b38044240f5f61c640ab2402b44936de0d24e7b439df78bc3ef15467ecb29b92ece4aa0550790d5ce80761f2ac4b0e3283969725c42343749d9b44b179b2d4fced66c5d0412b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510ff90f55532147b343e041ca130000a8bc00c35152bd7e774003738054240df6e298b3efd42eb536e68a0210bc921e8b5dc145fe965f63f4d3490064f239f2a54a6db16c96086e4ae52280c04ad8b32b44f5ff3d41f0c364949ccb628c50312b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510cad7c931321491844d296bd8e591448efc65fd6ad51a888d58fa3806424030298627da1afd28229aac150f553724b594989e59136d6a175d84e45a4dee344ff9e0eeb69fdf29abb6d833adc3e1ccdc87b2a65019ef5fb627c44d9d132c0012b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510c8c296323214b3727172ce6473bc780298a2d66c12f1a14f5b2a38074240918491100730b4523f0c85409f6d1cca9ebc4b8ca6df8d55fe3d85158fa43286608693c50332953e1d3b93e3e78b24e158d6a2275ce8c6c7c07a7a646a19200312b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef2051086f1a2403214b6f20c7faa2b2f6f24518fa02b71cb5f4a09fba338084240ca59c9fc7f6ab660e9970fc03e5ed588ccb8be43fe5a3e8450287b726f29d039e53fe888438f178ac63c3d2ca969cd8c2fbc8606f067634339b6a94a7382960212b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef2051080efbb543214e0dd72609cc106210d1aa13936cb67b93a0aee2138094240e787a21f5cb7052624160759a9d379dd9db144f2b498bca026375c9ce8ecdc2a0936af1c309b3a0f686c92bf5578b595a4ca99036a19c9fc50d3718fd454b30012b801080210e38bf01f22480a207eaabf7df1081377e06e08efe7ad17974049380bdd65a9b053c099ef80ff6e6f122408011220d153cc308d9cb96ca43ffeceaae1ee85794c83d17408ff76cfee92f5e91d0be22a0b08e291aef20510ddf8d85a3214fc3108dc3814888f4187452182bc1baf83b71bc9380a4240d51ea31f6449eed71de22339722af1edbb0b21401037d85882b32a2ed8ae9127f2df4d1da2092729e582812856227ed6cdf98a3f60203d1ff80bd635fb03bb0912a4070a4f0a1406fd60078eb4c2356137dd50036597db267cf61612251624de6420e17cbe9c20cdcfdf876b3b12978d3264a007fcaaa71c4cdb701d9ebc0323f44f1880d0dbc3f4022080e0ebdaf2e2ffffff010a4b0a1418e69cc672973992bb5f76d049a5b2c5ddf7743612251624de6420184e7b103d34c41003f9b864d5f8c1adda9bd0436b253bb3c844bc739c1e77c91880d0dbc3f4022080d0dbc3f4020a4b0a14344c39bb8f4512d6cab1f6aafac1811ef9d8afdf12251624de64204d420aea843e92a0cfe69d89696dff6827769f9cb52a249af537ce89bf2a4b741880d0dbc3f4022080d0dbc3f4020a4b0a1437ef19af29679b368d2b9e9de3f8769b3578667612251624de6420bd03de9f8ab29e2800094e153fac6f696cfa512536c9c2f804dcb2c2c4e4aed61880d0dbc3f4022080d0dbc3f4020a4b0a1462633d9db7ed78e951f79913fdc8231aa77ec12b12251624de64208f4a74a07351895ddf373057b98fae6dfaf2cd21f37a063e19601078fe470d531880d0dbc3f4022080d0dbc3f4020a4b0a147b343e041ca130000a8bc00c35152bd7e774003712251624de64204a5d4753eb79f92e80efe22df7aca4f666a4f44bf81c536c4a09d4b9c5b654b51880d0dbc3f4022080d0dbc3f4020a4b0a1491844d296bd8e591448efc65fd6ad51a888d58fa12251624de6420c80e9abef7ff439c10c68fe8f1303deddfc527718c3b37d8ba6807446e3c827a1880d0dbc3f4022080d0dbc3f4020a4b0a14b3727172ce6473bc780298a2d66c12f1a14f5b2a12251624de64209142afcc691b7cc05d26c7b0be0c8b46418294171730e079f384fde2fa50bafc1880d0dbc3f4022080d0dbc3f4020a4b0a14b6f20c7faa2b2f6f24518fa02b71cb5f4a09fba312251624de642049b288e4ebbb3a281c2d546fc30253d5baf08993b6e5d295fb787a5b314a298e1880d0dbc3f4022080d0dbc3f4020a4b0a14e0dd72609cc106210d1aa13936cb67b93a0aee2112251624de642004224339688f012e649de48e241880092eaa8f6aa0f4f14bfcf9e0c76917c0b61880d0dbc3f4022080d0dbc3f4020a4b0a14fc3108dc3814888f4187452182bc1baf83b71bc912251624de64204034b37ceda8a0bf13b1abaeee7a8f9383542099a554d219b93d0ce69e3970e81880d0dbc3f4022080d0dbc3f402124f0a1406fd60078eb4c2356137dd50036597db267cf61612251624de6420e17cbe9c20cdcfdf876b3b12978d3264a007fcaaa71c4cdb701d9ebc0323f44f1880d0dbc3f4022080e0ebdaf2e2ffffff011aa4070a4f0a1406fd60078eb4c2356137dd50036597db267cf61612251624de6420e17cbe9c20cdcfdf876b3b12978d3264a007fcaaa71c4cdb701d9ebc0323f44f1880d0dbc3f4022080e0ebdaf2e2ffffff010a4b0a1418e69cc672973992bb5f76d049a5b2c5ddf7743612251624de6420184e7b103d34c41003f9b864d5f8c1adda9bd0436b253bb3c844bc739c1e77c91880d0dbc3f4022080d0dbc3f4020a4b0a14344c39bb8f4512d6cab1f6aafac1811ef9d8afdf12251624de64204d420aea843e92a0cfe69d89696dff6827769f9cb52a249af537ce89bf2a4b741880d0dbc3f4022080d0dbc3f4020a4b0a1437ef19af29679b368d2b9e9de3f8769b3578667612251624de6420bd03de9f8ab29e2800094e153fac6f696cfa512536c9c2f804dcb2c2c4e4aed61880d0dbc3f4022080d0dbc3f4020a4b0a1462633d9db7ed78e951f79913fdc8231aa77ec12b12251624de64208f4a74a07351895ddf373057b98fae6dfaf2cd21f37a063e19601078fe470d531880d0dbc3f4022080d0dbc3f4020a4b0a147b343e041ca130000a8bc00c35152bd7e774003712251624de64204a5d4753eb79f92e80efe22df7aca4f666a4f44bf81c536c4a09d4b9c5b654b51880d0dbc3f4022080d0dbc3f4020a4b0a1491844d296bd8e591448efc65fd6ad51a888d58fa12251624de6420c80e9abef7ff439c10c68fe8f1303deddfc527718c3b37d8ba6807446e3c827a1880d0dbc3f4022080d0dbc3f4020a4b0a14b3727172ce6473bc780298a2d66c12f1a14f5b2a12251624de64209142afcc691b7cc05d26c7b0be0c8b46418294171730e079f384fde2fa50bafc1880d0dbc3f4022080d0dbc3f4020a4b0a14b6f20c7faa2b2f6f24518fa02b71cb5f4a09fba312251624de642049b288e4ebbb3a281c2d546fc30253d5baf08993b6e5d295fb787a5b314a298e1880d0dbc3f4022080d0dbc3f4020a4b0a14e0dd72609cc106210d1aa13936cb67b93a0aee2112251624de642004224339688f012e649de48e241880092eaa8f6aa0f4f14bfcf9e0c76917c0b61880d0dbc3f4022080d0dbc3f4020a4b0a14fc3108dc3814888f4187452182bc1baf83b71bc912251624de64204034b37ceda8a0bf13b1abaeee7a8f9383542099a554d219b93d0ce69e3970e81880d0dbc3f4022080d0dbc3f402124f0a1406fd60078eb4c2356137dd50036597db267cf61612251624de6420e17cbe9c20cdcfdf876b3b12978d3264a007fcaaa71c4cdb701d9ebc0323f44f1880d0dbc3f4022080e0ebdaf2e2ffffff01") @@ -49,7 +53,7 @@ func TestTmHeaderValidateAndMerkleProofValidate(t *testing.T) { var tmHeaderValidateContract tmHeaderValidate syncedConsensusStateBytes, err := tmHeaderValidateContract.Run(input) require.NoError(t, err) - syncedConsensusState, err := lightclient.DecodeConsensusState(syncedConsensusStateBytes[32:]) + syncedConsensusState, err := v1.DecodeConsensusState(syncedConsensusStateBytes[32:]) require.NoError(t, err) require.Equal(t, testHeight+1, syncedConsensusState.Height) require.Equal(t, cs.ChainID, syncedConsensusState.ChainID) @@ -69,7 +73,7 @@ func TestTmHeaderValidateAndMerkleProofValidate(t *testing.T) { syncedAgainConsensusStateBytes, err := tmHeaderValidateContract.Run(input) require.NoError(t, err) - syncedAgainConsensusState, err := lightclient.DecodeConsensusState(syncedAgainConsensusStateBytes[32:]) + syncedAgainConsensusState, err := v1.DecodeConsensusState(syncedAgainConsensusStateBytes[32:]) require.NoError(t, err) newAppHash := syncedAgainConsensusState.AppHash @@ -113,6 +117,43 @@ func TestTmHeaderValidateAndMerkleProofValidate(t *testing.T) { require.Equal(t, expectedResult, success) } +func TestIcs23Proof(t *testing.T) { + appHash, err := hex.DecodeString("ae6d1123fc362b3297bfb19c9f9fabbcbd1e2555b923dead261905b8a2ff6db6") + require.NoError(t, err) + key, err := hex.DecodeString("77696e64") + require.NoError(t, err) + value, err := hex.DecodeString("626c6f7773") + require.NoError(t, err) + proofBytes, err := hex.DecodeString("0a300a0a69637332333a6961766c120477696e641a1c0a1a0a0477696e641205626c6f77731a0b0801180120012a030002040a9d010a0c69637332333a73696d706c6512036962631a87010a84010a036962631220141acb8632cfb808f293f2649cb9aabaca74fc18640900ffd0d48e2994b2a1521a090801180120012a0100222708011201011a205f0ba08283de309300409486e978a3ea59d82bccc838b07c7d39bd87c16a5034222708011201011a20455b81ef5591150bd24d3e57a769f65518b16de93487f0fab02271b3d69e2852") + require.NoError(t, err) + + merkleProofInput := make([]byte, 32+32+len(key)+32+len(value)+32+len(proofBytes)) + copy(merkleProofInput[:32], "ibc") + binary.BigEndian.PutUint64(merkleProofInput[32+24:32+32], uint64(len(key))) + copy(merkleProofInput[32+32:32+32+len(key)], key) + + binary.BigEndian.PutUint64(merkleProofInput[32+32+len(key)+24:32+32+len(key)+32], uint64(len(value))) + copy(merkleProofInput[32+32+len(key)+32:32+32+len(key)+32+len(value)], value) + + copy(merkleProofInput[32+32+len(key)+32+len(value):32+32+len(key)+32+len(value)+32], appHash) + copy(merkleProofInput[32+32+len(key)+32+len(value)+32:], proofBytes) + + totalLengthPrefix := make([]byte, 32) + binary.BigEndian.PutUint64(totalLengthPrefix[0:8], 0) + binary.BigEndian.PutUint64(totalLengthPrefix[8:16], 0) + binary.BigEndian.PutUint64(totalLengthPrefix[16:24], 0) + binary.BigEndian.PutUint64(totalLengthPrefix[24:], uint64(len(merkleProofInput))) + + input := append(totalLengthPrefix, merkleProofInput...) + + validator := iavlMerkleProofValidatePlanck{} + success, err := validator.Run(input) + require.NoError(t, err) + expectedResult := make([]byte, 32) + binary.BigEndian.PutUint64(expectedResult[24:], 0x01) + require.Equal(t, expectedResult, success) +} + func TestMerkleProofValidateMoran(t *testing.T) { // Bytest1 is the inputs of exploit tx 0x05356fd06ce56a9ec5b4eaf9c075abd740cae4c21eab1676440ab5cd2fe5c57a bytest1, _ := hex.DecodeString("00000000000000000000000000000000000000000000000000000000000005086962630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e00000100380200000000010dd9ac0000000000000000000000000000000000000000000000000000000000000093000000000000000000000000000000000000000000000000000000000000000000f870a0424e4200000000000000000000000000000000000000000000000000000000009400000000000000000000000000000000000000008ad3c21bcecceda100000094489a8756c18c0b8b24ec2a2b9ff3d4d447f79bec94489a8756c18c0b8b24ec2a2b9ff3d4d447f79bec846553f10072cda827a83531ca0fd7ac917a6b65649719aab0836722caafe0603147a523180a8d020a066961766c3a76120e00000100380200000000010dd9ac1af201f0010aed010a2b0802100318b091c73422200c10f902d266c238a4ca9e26fa9bc36483cd3ebee4e263012f5e7f40c22ee4d20a4d0801100218b091c7342220e4fd47bffd1c06e67edad92b2bf9ca63631978676288a2aa99f95c459436ef632a20121a1f9c4eca726c725796c5375fc4158986ced08e498dc8268ef94d8ed1891612001a370a0e0000010038020000000000000002122011056c6919f02d966991c10721684a8d1542e44003f9ffb47032c18995d4ac7f18b091c7341a340a0e00000100380200000000010dd9ac12202c3a561458f8527b002b5ec3cab2d308662798d6245d4588a4e6a80ebdfe30ac18010ad4050a0a6d756c746973746f726512036962631ac005be050abb050a110a066f7261636c6512070a0508b891c7340a0f0a046d61696e12070a0508b891c7340a350a08736c617368696e6712290a2708b891c7341220c8ccf341e6e695e7e1cb0ce4bf347eea0cc16947d8b4e934ec400b57c59d6f860a380a0b61746f6d69635f7377617012290a2708b891c734122042d4ecc9468f71a70288a95d46564bfcaf2c9f811051dcc5593dbef152976b010a110a0662726964676512070a0508b891c7340a300a0364657812290a2708b891c73412201773be443c27f61075cecdc050ce22eb4990c54679089e90afdc4e0e88182a230a2f0a02736312290a2708b891c7341220df7a0484b7244f76861b1642cfb7a61d923794bd2e076c8dbd05fc4ee29f3a670a330a06746f6b656e7312290a2708b891c734122064958c2f76fec1fa5d1828296e51264c259fa264f499724795a740f48fc4731b0a320a057374616b6512290a2708b891c734122015d2c302143bdf029d58fe381cc3b54cedf77ecb8834dfc5dc3e1555d68f19ab0a330a06706172616d7312290a2708b891c734122050abddcb7c115123a5a4247613ab39e6ba935a3d4f4b9123c4fedfa0895c040a0a300a0361636312290a2708b891c734122079fb5aecc4a9b87e56231103affa5e515a1bdf3d0366490a73e087980b7f1f260a0e0a0376616c12070a0508b891c7340a300a0369626312290a2708b891c7341220e09159530585455058cf1785f411ea44230f39334e6e0f6a3c54dbf069df2b620a300a03676f7612290a2708b891c7341220db85ddd37470983b14186e975a175dfb0bf301b43de685ced0aef18d28b4e0420a320a05706169727312290a2708b891c7341220a78b556bc9e73d86b4c63ceaf146db71b12ac80e4c10dd0ce6eb09c99b0c7cfe0a360a0974696d655f6c6f636b12290a2708b891c73412204775dbe01d41cab018c21ba5c2af94720e4d7119baf693670e70a40ba2a52143") @@ -142,12 +183,12 @@ func TestAbsenceMerkleProofValidateMoran(t *testing.T) { } func TestMultiStore(t *testing.T) { - goodProof := lightclient.NewMultiStoreProofOp([]byte("legit"), &lightclient.MultiStoreProof{ - StoreInfos: []lightclient.StoreInfo{ + goodProof := v1.NewMultiStoreProofOp([]byte("legit"), &v1.MultiStoreProof{ + StoreInfos: []v1.StoreInfo{ { Name: "legit", - Core: lightclient.StoreCore{ - CommitID: lightclient.CommitID{ + Core: v1.StoreCore{ + CommitID: v1.CommitID{ Version: 1, Hash: []byte("legithash"), }, @@ -162,12 +203,12 @@ func TestMultiStore(t *testing.T) { _, err = goodProof.Run([][]byte{[]byte("evilhash")}) assert.Error(t, err, "hash mismatch for substore") - badProof := lightclient.NewMultiStoreProofOp([]byte("legit"), &lightclient.MultiStoreProof{ - StoreInfos: []lightclient.StoreInfo{ + badProof := v1.NewMultiStoreProofOp([]byte("legit"), &v1.MultiStoreProof{ + StoreInfos: []v1.StoreInfo{ { Name: "legit", - Core: lightclient.StoreCore{ - CommitID: lightclient.CommitID{ + Core: v1.StoreCore{ + CommitID: v1.CommitID{ Version: 1, Hash: []byte("evilhash"), }, @@ -175,8 +216,8 @@ func TestMultiStore(t *testing.T) { }, { Name: "legit", - Core: lightclient.StoreCore{ - CommitID: lightclient.CommitID{ + Core: v1.StoreCore{ + CommitID: v1.CommitID{ Version: 1, Hash: []byte("legithash"), }, @@ -195,3 +236,91 @@ func TestMultiStore(t *testing.T) { err = multiStoreOpVerifier(badProof) assert.Error(t, err, "duplicated store") } + +func TestProofOpsVerifier(t *testing.T) { + tests := []struct { + ops merkle.ProofOperators + err error + }{ + { + merkle.ProofOperators{ + iavl.IAVLValueOp{}, + }, + cmn.NewError("proof ops should be 2"), + }, + { + merkle.ProofOperators{ + v1.MultiStoreProofOp{}, + v1.MultiStoreProofOp{}, + }, + cmn.NewError("invalid proof op"), + }, + { + merkle.ProofOperators{ + iavl.IAVLValueOp{}, + v1.MultiStoreProofOp{}, + }, + nil, + }, + { + merkle.ProofOperators{ + v1.CommitmentOp{Type: v1.ProofOpIAVLCommitment}, + v1.CommitmentOp{Type: v1.ProofOpSimpleMerkleCommitment}, + }, + nil, + }, + { + merkle.ProofOperators{ + v1.CommitmentOp{Type: v1.ProofOpSimpleMerkleCommitment}, + v1.CommitmentOp{Type: v1.ProofOpSimpleMerkleCommitment}, + }, + cmn.NewError("invalid proof op"), + }, + { + merkle.ProofOperators{ + v1.MultiStoreProofOp{}, + iavl.IAVLValueOp{}, + }, + cmn.NewError("invalid proof type"), + }, + } + + for _, testCase := range tests { + err := proofOpsVerifier(testCase.ops) + assert.Equal(t, err, testCase.err) + } +} + +func TestKeyVerifier(t *testing.T) { + tests := []struct { + key string + err error + }{ + { + "x:sdfdfdsd", + cmn.NewError("key should not start with x:"), + }, + { + "sdfxdfxs", + nil, + }, + } + + for _, testCase := range tests { + err := keyVerifier(testCase.key) + assert.Equal(t, err, testCase.err) + } +} + +func TestCometBFTLightBlockValidate(t *testing.T) { + inputStr := "000000000000000000000000000000000000000000000000000000000000018c677265656e6669656c645f393030302d3132310000000000000000000000000000000000000000013c350cd55b99dc6c2b7da9bef5410fbfb869fede858e7b95bf7ca294e228bb40e33f6e876d63791ebd05ff617a1b4f4ad1aa2ce65e3c3a9cdfb33e0ffa7e8423000000000098968015154514f68ce65a0d9eecc578c0ab12da0a2a28a0805521b5b7ae56eb3fb24555efbfe59e1622bfe9f7be8c9022e9b3f2442739c1ce870b9adee169afe60f674edd7c86451c5363d89052fde8351895eeea166ce5373c36e31b518ed191d0c599aa0f5b0000000000989680432f6c4908a9aa5f3444421f466b11645235c99b831b2a2de9e504d7ea299e52a202ce529808618eb3bfc0addf13d8c5f2df821d81e18f9bc61583510b322d067d46323b0a572635c06a049c0a2a929e3c8184a50cf6a8b95708c25834ade456f399015a0000000000989680864cb9828254d712f8e59b164fc6a9402dc4e6c59065e38cff24f5323c8c5da888a0f97e5ee4ba1e11b0674b0a0d06204c1dfa247c370cd4be3e799fc4f6f48d977ac7ca0aeb060adb030a02080b1213677265656e6669656c645f393030302d3132311802220c08b2d7f3a10610e8d2adb3032a480a20ec6ecb5db4ffb17fabe40c60ca7b8441e9c5d77585d0831186f3c37aa16e9c15122408011220a2ab9e1eb9ea52812f413526e424b326aff2f258a56e00d690db9f805b60fe7e32200f40aeff672e8309b7b0aefbb9a1ae3d4299b5c445b7d54e8ff398488467f0053a20e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b85542203c350cd55b99dc6c2b7da9bef5410fbfb869fede858e7b95bf7ca294e228bb404a203c350cd55b99dc6c2b7da9bef5410fbfb869fede858e7b95bf7ca294e228bb405220294d8fbd0b94b767a7eba9840f299a3586da7fe6b5dead3b7eecba193c400f935a20bc50557c12d7392b0d07d75df0b61232d48f86a74fdea6d1485d9be6317d268c6220e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8556a20e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b85572146699336aa109d1beab3946198c8e59f3b2cbd92f7a4065e3cd89e315ca39d87dee92835b98f8b8ec0861d6d9bb2c60156df5d375b3ceb1fbe71af6a244907d62548a694165caa660fec7a9b4e7b9198191361c71be0b128a0308021a480a20726abd0fdbfb6f779b0483e6e4b4b6f12241f6ea2bf374233ab1a316692b6415122408011220159f10ff15a8b58fc67a92ffd7f33c8cd407d4ce81b04ca79177dfd00ca19a67226808021214050cff76cc632760ba9db796c046004c900967361a0c08b3d7f3a10610808cadba03224080713027ffb776a702d78fd0406205c629ba473e1f8d6af646190f6eb9262cd67d69be90d10e597b91e06d7298eb6fa4b8f1eb7752ebf352a1f51560294548042268080212146699336aa109d1beab3946198c8e59f3b2cbd92f1a0c08b3d7f3a10610b087c1c00322405e2ddb70acfe4904438be3d9f4206c0ace905ac4fc306a42cfc9e86268950a0fbfd6ec5f526d3e41a3ef52bf9f9f358e3cb4c3feac76c762fa3651c1244fe004226808021214c55765fd2d0570e869f6ac22e7f2916a35ea300d1a0c08b3d7f3a10610f0b3d492032240ca17898bd22232fc9374e1188636ee321a396444a5b1a79f7628e4a11f265734b2ab50caf21e8092c55d701248e82b2f011426cb35ba22043b497a6b4661930612a0050aa8010a14050cff76cc632760ba9db796c046004c9009673612220a20e33f6e876d63791ebd05ff617a1b4f4ad1aa2ce65e3c3a9cdfb33e0ffa7e84231880ade2042080a6bbf6ffffffffff012a30a0805521b5b7ae56eb3fb24555efbfe59e1622bfe9f7be8c9022e9b3f2442739c1ce870b9adee169afe60f674edd7c86321415154514f68ce65a0d9eecc578c0ab12da0a2a283a14ee7a2a6a44d427f6949eeb8f12ea9fbb2501da880aa2010a146699336aa109d1beab3946198c8e59f3b2cbd92f12220a20451c5363d89052fde8351895eeea166ce5373c36e31b518ed191d0c599aa0f5b1880ade2042080ade2042a30831b2a2de9e504d7ea299e52a202ce529808618eb3bfc0addf13d8c5f2df821d81e18f9bc61583510b322d067d46323b3214432f6c4908a9aa5f3444421f466b11645235c99b3a14a0a7769429468054e19059af4867da0a495567e50aa2010a14c55765fd2d0570e869f6ac22e7f2916a35ea300d12220a200a572635c06a049c0a2a929e3c8184a50cf6a8b95708c25834ade456f399015a1880ade2042080ade2042a309065e38cff24f5323c8c5da888a0f97e5ee4ba1e11b0674b0a0d06204c1dfa247c370cd4be3e799fc4f6f48d977ac7ca3214864cb9828254d712f8e59b164fc6a9402dc4e6c53a143139916d97df0c589312b89950b6ab9795f34d1a12a8010a14050cff76cc632760ba9db796c046004c9009673612220a20e33f6e876d63791ebd05ff617a1b4f4ad1aa2ce65e3c3a9cdfb33e0ffa7e84231880ade2042080a6bbf6ffffffffff012a30a0805521b5b7ae56eb3fb24555efbfe59e1622bfe9f7be8c9022e9b3f2442739c1ce870b9adee169afe60f674edd7c86321415154514f68ce65a0d9eecc578c0ab12da0a2a283a14ee7a2a6a44d427f6949eeb8f12ea9fbb2501da88" + expectOutputStr := "000000000000000000000000000000000000000000000000000000000000018c677265656e6669656c645f393030302d3132310000000000000000000000000000000000000000023c350cd55b99dc6c2b7da9bef5410fbfb869fede858e7b95bf7ca294e228bb40e33f6e876d63791ebd05ff617a1b4f4ad1aa2ce65e3c3a9cdfb33e0ffa7e8423000000000098968015154514f68ce65a0d9eecc578c0ab12da0a2a28a0805521b5b7ae56eb3fb24555efbfe59e1622bfe9f7be8c9022e9b3f2442739c1ce870b9adee169afe60f674edd7c86451c5363d89052fde8351895eeea166ce5373c36e31b518ed191d0c599aa0f5b0000000000989680432f6c4908a9aa5f3444421f466b11645235c99b831b2a2de9e504d7ea299e52a202ce529808618eb3bfc0addf13d8c5f2df821d81e18f9bc61583510b322d067d46323b0a572635c06a049c0a2a929e3c8184a50cf6a8b95708c25834ade456f399015a0000000000989680864cb9828254d712f8e59b164fc6a9402dc4e6c59065e38cff24f5323c8c5da888a0f97e5ee4ba1e11b0674b0a0d06204c1dfa247c370cd4be3e799fc4f6f48d977ac7ca" + + input, err := hex.DecodeString(inputStr) + require.NoError(t, err) + + contract := &cometBFTLightBlockValidate{} + res, err := contract.Run(input) + require.NoError(t, err) + require.Equal(t, expectOutputStr, hex.EncodeToString(res)) +} diff --git a/core/vm/eips.go b/core/vm/eips.go index 292f5c7d07a..1109aa5148a 100644 --- a/core/vm/eips.go +++ b/core/vm/eips.go @@ -198,3 +198,26 @@ func enable3860(jt *JumpTable) { jt[CREATE].dynamicGas = gasCreateEip3860 jt[CREATE2].dynamicGas = gasCreate2Eip3860 } + +// enableSharding applies mini-danksharding (DATAHASH Opcode) +// - Adds an opcode that returns the versioned data hash of the tx at a index. +func enableSharding(jt *JumpTable) { + jt[DATAHASH] = &operation{ + execute: opDataHash, + constantGas: GasFastestStep, + numPop: 0, + numPush: 1, + } +} + +// opDataHash implements DATAHASH opcode +func opDataHash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { + idx := scope.Stack.Peek() + if idx.LtUint64(uint64(len(interpreter.evm.TxContext().DataHashes))) { + hash := interpreter.evm.TxContext().DataHashes[idx.Uint64()] + idx.SetBytes(hash.Bytes()) + } else { + idx.Clear() + } + return nil, nil +} diff --git a/core/vm/evm.go b/core/vm/evm.go index 8d6cdd736e3..9ddd4909d33 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -37,6 +37,10 @@ var emptyCodeHash = crypto.Keccak256Hash(nil) func (evm *EVM) precompile(addr libcommon.Address) (PrecompiledContract, bool) { var precompiles map[libcommon.Address]PrecompiledContract switch { + case evm.chainRules.IsLuban: + precompiles = PrecompiledContractsLuban + case evm.chainRules.IsPlanck: + precompiles = PrecompiledContractsPlanck case evm.chainRules.IsMoran: precompiles = PrecompiledContractsIsMoran case evm.chainRules.IsNano: @@ -165,11 +169,13 @@ func (evm *EVM) Interpreter() Interpreter { } func (evm *EVM) call(typ OpCode, caller ContractRef, addr libcommon.Address, input []byte, gas uint64, value *uint256.Int, bailout bool) (ret []byte, leftOverGas uint64, err error) { - if evm.config.NoRecursion && evm.interpreter.Depth() > 0 { + depth := evm.interpreter.Depth() + + if evm.config.NoRecursion && depth > 0 { return nil, gas, nil } // Fail if we're trying to execute above the call depth limit - if evm.interpreter.Depth() > int(params.CallCreateDepth) { + if depth > int(params.CallCreateDepth) { return nil, gas, ErrDepth } if typ == CALL || typ == CALLCODE { @@ -197,16 +203,12 @@ func (evm *EVM) call(typ OpCode, caller ContractRef, addr libcommon.Address, inp v = nil } // Calling a non existing account, don't do anything, but ping the tracer - if evm.interpreter.Depth() == 0 { + if depth == 0 { evm.config.Tracer.CaptureStart(evm, caller.Address(), addr, isPrecompile, false /* create */, input, gas, v, code) - defer func(startGas uint64) { // Lazy evaluation of the parameters - evm.config.Tracer.CaptureEnd(ret, 0, err) - }(gas) + evm.config.Tracer.CaptureEnd(ret, 0, nil) } else { evm.config.Tracer.CaptureEnter(typ, caller.Address(), addr, isPrecompile, false /* create */, input, gas, v, code) - defer func(startGas uint64) { // Lazy evaluation of the parameters - evm.config.Tracer.CaptureExit(ret, 0, err) - }(gas) + evm.config.Tracer.CaptureExit(ret, 0, nil) } } return nil, gas, nil @@ -226,7 +228,7 @@ func (evm *EVM) call(typ OpCode, caller ContractRef, addr libcommon.Address, inp if typ == STATICCALL { v = nil } - if evm.interpreter.Depth() == 0 { + if depth == 0 { evm.config.Tracer.CaptureStart(evm, caller.Address(), addr, isPrecompile, false /* create */, input, gas, v, code) defer func(startGas uint64) { // Lazy evaluation of the parameters evm.config.Tracer.CaptureEnd(ret, startGas-gas, err) @@ -338,9 +340,10 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, var ret []byte var err error var gasConsumption uint64 + depth := evm.interpreter.Depth() if evm.config.Debug { - if evm.interpreter.Depth() == 0 { + if depth == 0 { evm.config.Tracer.CaptureStart(evm, caller.Address(), address, false /* precompile */, true /* create */, codeAndHash.code, gas, value, nil) defer func() { evm.config.Tracer.CaptureEnd(ret, gasConsumption, err) @@ -355,7 +358,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, // Depth check execution. Fail if we're trying to execute above the // limit. - if evm.interpreter.Depth() > int(params.CallCreateDepth) { + if depth > int(params.CallCreateDepth) { err = ErrDepth return nil, libcommon.Address{}, gas, err } @@ -395,7 +398,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, contract := NewContract(caller, AccountRef(address), value, gas, evm.config.SkipAnalysis) contract.SetCodeOptionalHash(&address, codeAndHash) - if evm.config.NoRecursion && evm.interpreter.Depth() > 0 { + if evm.config.NoRecursion && depth > 0 { return nil, address, gas, nil } diff --git a/core/vm/lightclient/v1/ics23_proof.go b/core/vm/lightclient/v1/ics23_proof.go new file mode 100644 index 00000000000..cd4f340fbe5 --- /dev/null +++ b/core/vm/lightclient/v1/ics23_proof.go @@ -0,0 +1,107 @@ +package v1 + +import ( + "fmt" + + "github.com/bnb-chain/ics23" + "github.com/tendermint/tendermint/crypto/merkle" +) + +const ( + ProofOpIAVLCommitment = "ics23:iavl" + ProofOpSimpleMerkleCommitment = "ics23:simple" +) + +// CommitmentOp implements merkle.ProofOperator by wrapping an ics23 CommitmentProof +// It also contains a Key field to determine which key the proof is proving. +// NOTE: CommitmentProof currently can either be ExistenceProof or NonexistenceProof +// +// Type and Spec are classified by the kind of merkle proof it represents allowing +// the code to be reused by more types. Spec is never on the wire, but mapped from type in the code. +type CommitmentOp struct { + Type string + Spec *ics23.ProofSpec + Key []byte + Proof *ics23.CommitmentProof +} + +var _ merkle.ProofOperator = CommitmentOp{} + +// CommitmentOpDecoder takes a merkle.ProofOp and attempts to decode it into a CommitmentOp ProofOperator +// The proofOp.Data is just a marshalled CommitmentProof. The Key of the CommitmentOp is extracted +// from the unmarshalled proof. +func CommitmentOpDecoder(pop merkle.ProofOp) (merkle.ProofOperator, error) { + var spec *ics23.ProofSpec + switch pop.Type { + case ProofOpIAVLCommitment: + spec = ics23.IavlSpec + case ProofOpSimpleMerkleCommitment: + spec = ics23.TendermintSpec + default: + return nil, fmt.Errorf("unexpected ProofOp.Type; got %s, want supported ics23 subtypes 'ProofOpIAVLCommitment' or 'ProofOpSimpleMerkleCommitment'", pop.Type) + } + + proof := &ics23.CommitmentProof{} + err := proof.Unmarshal(pop.Data) + if err != nil { + return nil, err + } + + op := CommitmentOp{ + Type: pop.Type, + Key: pop.Key, + Spec: spec, + Proof: proof, + } + return op, nil +} + +func (op CommitmentOp) GetKey() []byte { + return op.Key +} + +// Run takes in a list of arguments and attempts to run the proof op against these arguments. +// Returns the root wrapped in [][]byte if the proof op succeeds with given args. If not, +// it will return an error. +// +// CommitmentOp will accept args of length 1 or length 0 +// If length 1 args is passed in, then CommitmentOp will attempt to prove the existence of the key +// with the value provided by args[0] using the embedded CommitmentProof and return the CommitmentRoot of the proof. +// If length 0 args is passed in, then CommitmentOp will attempt to prove the absence of the key +// in the CommitmentOp and return the CommitmentRoot of the proof. +func (op CommitmentOp) Run(args [][]byte) ([][]byte, error) { + if _, ok := op.Proof.Proof.(*ics23.CommitmentProof_Exist); !ok { + return nil, fmt.Errorf("only exist proof supported") + } + + // calculate root from proof + root, err := op.Proof.Calculate() + if err != nil { + return nil, fmt.Errorf("could not calculate root for proof: %v", err) + } + if len(args) != 1 { + return nil, fmt.Errorf("args must be length 1, got: %d", len(args)) + } + + // Args is length 1, verify existence of key with value args[0] + if !ics23.VerifyMembership(op.Spec, root, op.Proof, op.Key, args[0]) { + return nil, fmt.Errorf("proof did not verify existence of key %s with given value %x", op.Key, args[0]) + } + + return [][]byte{root}, nil +} + +// ProofOp implements ProofOperator interface and converts a CommitmentOp +// into a merkle.ProofOp format that can later be decoded by CommitmentOpDecoder +// back into a CommitmentOp for proof verification +func (op CommitmentOp) ProofOp() merkle.ProofOp { + bz, err := op.Proof.Marshal() + if err != nil { + panic(err.Error()) + } + return merkle.ProofOp{ + Type: op.Type, + Key: op.Key, + Data: bz, + } +} diff --git a/core/vm/lightclient/multistoreproof.go b/core/vm/lightclient/v1/multistoreproof.go similarity index 87% rename from core/vm/lightclient/multistoreproof.go rename to core/vm/lightclient/v1/multistoreproof.go index fd00c2f1401..a55b6838da5 100644 --- a/core/vm/lightclient/multistoreproof.go +++ b/core/vm/lightclient/v1/multistoreproof.go @@ -1,9 +1,9 @@ -package lightclient +package v1 import ( "bytes" "fmt" - + "github.com/ledgerwatch/erigon/core/vm/lightclient/iavl" iavl2 "github.com/ledgerwatch/erigon/core/vm/lightclient/iavl" "github.com/tendermint/tendermint/crypto/merkle" cmn "github.com/tendermint/tendermint/libs/common" @@ -136,3 +136,14 @@ func DefaultProofRuntime() (prt *merkle.ProofRuntime) { prt.RegisterOpDecoder(ProofOpMultiStore, MultiStoreProofOpDecoder) return } + +func Ics23CompatibleProofRuntime() (prt *merkle.ProofRuntime) { + prt = merkle.NewProofRuntime() + prt.RegisterOpDecoder(merkle.ProofOpSimpleValue, merkle.SimpleValueOpDecoder) + prt.RegisterOpDecoder(iavl.ProofOpIAVLValue, iavl.IAVLValueOpDecoder) + prt.RegisterOpDecoder(iavl.ProofOpIAVLAbsence, iavl.IAVLAbsenceOpDecoder) + prt.RegisterOpDecoder(ProofOpMultiStore, MultiStoreProofOpDecoder) + prt.RegisterOpDecoder(ProofOpIAVLCommitment, CommitmentOpDecoder) + prt.RegisterOpDecoder(ProofOpSimpleMerkleCommitment, CommitmentOpDecoder) + return +} diff --git a/core/vm/lightclient/rootmultistore.go b/core/vm/lightclient/v1/rootmultistore.go similarity index 98% rename from core/vm/lightclient/rootmultistore.go rename to core/vm/lightclient/v1/rootmultistore.go index d0e016c0e7b..c0f32f1b9f7 100644 --- a/core/vm/lightclient/rootmultistore.go +++ b/core/vm/lightclient/v1/rootmultistore.go @@ -1,8 +1,7 @@ -package lightclient +package v1 import ( "fmt" - "github.com/tendermint/tendermint/crypto/merkle" "github.com/tendermint/tendermint/crypto/tmhash" ) diff --git a/core/vm/lightclient/types.go b/core/vm/lightclient/v1/types.go similarity index 85% rename from core/vm/lightclient/types.go rename to core/vm/lightclient/v1/types.go index cd5c5944b82..afa478c85f5 100644 --- a/core/vm/lightclient/types.go +++ b/core/vm/lightclient/v1/types.go @@ -1,10 +1,9 @@ -package lightclient +package v1 import ( "bytes" "encoding/binary" "fmt" - "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/crypto/merkle" lerr "github.com/tendermint/tendermint/lite/errors" @@ -130,7 +129,7 @@ func (cs ConsensusState) EncodeConsensusState() ([]byte, error) { } func (cs *ConsensusState) ApplyHeader(header *Header) (bool, error) { - if uint64(header.Height) < cs.Height { + if uint64(header.Height) <= cs.Height { return false, fmt.Errorf("header height < consensus height (%d < %d)", header.Height, cs.Height) } @@ -209,32 +208,57 @@ func DecodeHeader(input []byte) (*Header, error) { return &header, nil } +type KeyVerifier func(string) error + type KeyValueMerkleProof struct { Key []byte Value []byte StoreName string AppHash []byte Proof *merkle.Proof - verifiers []merkle.ProofOpVerifier + + keyVerifier KeyVerifier + proofOpsVerifier merkle.ProofOpsVerifier + verifiers []merkle.ProofOpVerifier + proofRuntime *merkle.ProofRuntime +} + +func (kvmp *KeyValueMerkleProof) SetProofRuntime(prt *merkle.ProofRuntime) { + kvmp.proofRuntime = prt } func (kvmp *KeyValueMerkleProof) SetVerifiers(verifiers []merkle.ProofOpVerifier) { kvmp.verifiers = verifiers } +func (kvmp *KeyValueMerkleProof) SetOpsVerifier(verifier merkle.ProofOpsVerifier) { + kvmp.proofOpsVerifier = verifier +} + +func (kvmp *KeyValueMerkleProof) SetKeyVerifier(keyChecker KeyVerifier) { + kvmp.keyVerifier = keyChecker +} + func (kvmp *KeyValueMerkleProof) Validate() bool { - prt := DefaultProofRuntime() + if kvmp.keyVerifier != nil { + if err := kvmp.keyVerifier(kvmp.StoreName); err != nil { + return false + } + if err := kvmp.keyVerifier(string(kvmp.Key)); err != nil { + return false + } + } kp := merkle.KeyPath{} kp = kp.AppendKey([]byte(kvmp.StoreName), merkle.KeyEncodingURL) kp = kp.AppendKey(kvmp.Key, merkle.KeyEncodingURL) if len(kvmp.Value) == 0 { - err := prt.VerifyAbsence(kvmp.Proof, kvmp.AppHash, kp.String(), kvmp.verifiers...) + err := kvmp.proofRuntime.VerifyAbsence(kvmp.Proof, kvmp.AppHash, kp.String(), kvmp.verifiers...) return err == nil } - err := prt.VerifyValue(kvmp.Proof, kvmp.AppHash, kp.String(), kvmp.Value, kvmp.verifiers...) + err := kvmp.proofRuntime.VerifyValue(kvmp.Proof, kvmp.AppHash, kp.String(), kvmp.Value, kvmp.proofOpsVerifier, kvmp.verifiers...) return err == nil } @@ -245,8 +269,9 @@ func DecodeKeyValueMerkleProof(input []byte) (*KeyValueMerkleProof, error) { inputLength := uint64(len(input)) pos := uint64(0) - if inputLength <= storeNameLengthBytesLength+keyLengthBytesLength+valueLengthBytesLength+appHashLength { - return nil, fmt.Errorf("input length should be no less than %d", storeNameLengthBytesLength+keyLengthBytesLength+valueLengthBytesLength+appHashLength) + fixedSize := storeNameLengthBytesLength + keyLengthBytesLength + valueLengthBytesLength + appHashLength + if inputLength <= fixedSize { + return nil, fmt.Errorf("input length should be no less than %d", fixedSize) } storeName := string(bytes.Trim(input[pos:pos+storeNameLengthBytesLength], "\x00")) pos += storeNameLengthBytesLength @@ -254,7 +279,8 @@ func DecodeKeyValueMerkleProof(input []byte) (*KeyValueMerkleProof, error) { keyLength := binary.BigEndian.Uint64(input[pos+keyLengthBytesLength-8 : pos+keyLengthBytesLength]) pos += keyLengthBytesLength - if inputLength <= storeNameLengthBytesLength+keyLengthBytesLength+keyLength+valueLengthBytesLength { + fixedSize = storeNameLengthBytesLength + keyLengthBytesLength + valueLengthBytesLength + if inputLength <= fixedSize+keyLength || fixedSize+keyLength < fixedSize { return nil, fmt.Errorf("invalid input, keyLength %d is too long", keyLength) } key := input[pos : pos+keyLength] @@ -263,7 +289,10 @@ func DecodeKeyValueMerkleProof(input []byte) (*KeyValueMerkleProof, error) { valueLength := binary.BigEndian.Uint64(input[pos+valueLengthBytesLength-8 : pos+valueLengthBytesLength]) pos += valueLengthBytesLength - if inputLength <= storeNameLengthBytesLength+keyLengthBytesLength+keyLength+valueLengthBytesLength+valueLength+appHashLength { + fixedSize = storeNameLengthBytesLength + keyLengthBytesLength + valueLengthBytesLength + appHashLength + if inputLength <= fixedSize+keyLength+valueLength || + fixedSize+keyLength < fixedSize || + fixedSize+keyLength+valueLength < valueLength { return nil, fmt.Errorf("invalid input, valueLength %d is too long", valueLength) } value := input[pos : pos+valueLength] diff --git a/core/vm/lightclient/utils.go b/core/vm/lightclient/v1/utils.go similarity index 99% rename from core/vm/lightclient/utils.go rename to core/vm/lightclient/v1/utils.go index 20da6a1347b..685b6a12809 100644 --- a/core/vm/lightclient/utils.go +++ b/core/vm/lightclient/v1/utils.go @@ -1,4 +1,4 @@ -package lightclient +package v1 /* import ( diff --git a/core/vm/lightclient/wire.go b/core/vm/lightclient/v1/wire.go similarity index 92% rename from core/vm/lightclient/wire.go rename to core/vm/lightclient/v1/wire.go index 460dfce1de7..3570ae9351f 100644 --- a/core/vm/lightclient/wire.go +++ b/core/vm/lightclient/v1/wire.go @@ -1,4 +1,4 @@ -package lightclient +package v1 import ( "github.com/tendermint/go-amino" diff --git a/core/vm/lightclient/v2/lightclient.go b/core/vm/lightclient/v2/lightclient.go new file mode 100644 index 00000000000..888bff4a9d1 --- /dev/null +++ b/core/vm/lightclient/v2/lightclient.go @@ -0,0 +1,233 @@ +// Package v2 is used for tendermint v0.34.22 and its compatible version. +package v2 + +import ( + "bytes" + "encoding/binary" + "fmt" + + "github.com/cometbft/cometbft/crypto/ed25519" + "github.com/cometbft/cometbft/light" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + "github.com/cometbft/cometbft/types" +) + +const ( + uint64TypeLength uint64 = 8 + consensusStateLengthBytesLength uint64 = 32 + validateResultMetaDataLength uint64 = 32 + + chainIDLength uint64 = 32 + heightLength uint64 = 8 + validatorSetHashLength uint64 = 32 + validatorPubkeyLength uint64 = 32 + validatorVotingPowerLength uint64 = 8 + relayerAddressLength uint64 = 20 + relayerBlsKeyLength uint64 = 48 + singleValidatorBytesLength uint64 = validatorPubkeyLength + validatorVotingPowerLength + relayerAddressLength + relayerBlsKeyLength + maxConsensusStateLength uint64 = chainIDLength + heightLength + validatorSetHashLength + 99*singleValidatorBytesLength // Maximum validator quantity 99 +) + +type ConsensusState struct { + ChainID string + Height uint64 + NextValidatorSetHash []byte + ValidatorSet *types.ValidatorSet +} + +// output: +// | chainID | height | nextValidatorSetHash | [{validator pubkey, voting power, relayer address, relayer bls pubkey}] | +// | 32 bytes | 8 bytes | 32 bytes | [{32 bytes, 8 bytes, 20 bytes, 48 bytes}] | +func (cs ConsensusState) EncodeConsensusState() ([]byte, error) { + validatorSetLength := uint64(len(cs.ValidatorSet.Validators)) + serializeLength := chainIDLength + heightLength + validatorSetHashLength + validatorSetLength*singleValidatorBytesLength + if serializeLength > maxConsensusStateLength { + return nil, fmt.Errorf("too many validators %d, consensus state bytes should not exceed %d", len(cs.ValidatorSet.Validators), maxConsensusStateLength) + } + + encodingBytes := make([]byte, serializeLength) + + pos := uint64(0) + if uint64(len(cs.ChainID)) > chainIDLength { + return nil, fmt.Errorf("chainID length should be no more than 32") + } + copy(encodingBytes[pos:pos+chainIDLength], cs.ChainID) + pos += chainIDLength + + binary.BigEndian.PutUint64(encodingBytes[pos:pos+heightLength], cs.Height) + pos += heightLength + + copy(encodingBytes[pos:pos+validatorSetHashLength], cs.NextValidatorSetHash) + pos += validatorSetHashLength + + for index := uint64(0); index < validatorSetLength; index++ { + validator := cs.ValidatorSet.Validators[index] + pubkey, ok := validator.PubKey.(ed25519.PubKey) + if !ok { + return nil, fmt.Errorf("invalid pubkey type") + } + + copy(encodingBytes[pos:pos+validatorPubkeyLength], pubkey[:]) + pos += validatorPubkeyLength + + binary.BigEndian.PutUint64(encodingBytes[pos:pos+validatorVotingPowerLength], uint64(validator.VotingPower)) + pos += validatorVotingPowerLength + + copy(encodingBytes[pos:pos+relayerAddressLength], validator.RelayerAddress) + pos += relayerAddressLength + + copy(encodingBytes[pos:pos+relayerBlsKeyLength], validator.BlsKey) + pos += relayerBlsKeyLength + } + + return encodingBytes, nil +} + +func (cs *ConsensusState) ApplyLightBlock(block *types.LightBlock) (bool, error) { + if uint64(block.Height) <= cs.Height { + return false, fmt.Errorf("block height <= consensus height (%d < %d)", block.Height, cs.Height) + } + + if err := block.ValidateBasic(cs.ChainID); err != nil { + return false, err + } + + if cs.Height == uint64(block.Height-1) { + if !bytes.Equal(cs.NextValidatorSetHash, block.ValidatorsHash) { + return false, fmt.Errorf("validators hash mismatch, expected: %s, real: %s", cs.NextValidatorSetHash, block.ValidatorsHash) + } + err := block.ValidatorSet.VerifyCommitLight(cs.ChainID, block.Commit.BlockID, block.Height, block.Commit) + if err != nil { + return false, err + } + } else { + // Ensure that +`trustLevel` (default 1/3) or more of last trusted validators signed correctly. + err := cs.ValidatorSet.VerifyCommitLightTrusting(cs.ChainID, block.Commit, light.DefaultTrustLevel) + if err != nil { + return false, err + } + + // Ensure that +2/3 of new validators signed correctly. + // + // NOTE: this should always be the last check because untrustedVals can be + // intentionally made very large to DOS the light client. not the case for + // VerifyAdjacent, where validator set is known in advance. + err = block.ValidatorSet.VerifyCommitLight(cs.ChainID, block.Commit.BlockID, block.Height, block.Commit) + if err != nil { + return false, err + } + } + + // update consensus state + cs.Height = uint64(block.Height) + cs.NextValidatorSetHash = block.NextValidatorsHash + cs.ValidatorSet = block.ValidatorSet + + return !(bytes.Equal(cs.ValidatorSet.Hash(), block.ValidatorsHash)), nil +} + +// input: +// | chainID | height | nextValidatorSetHash | [{validator pubkey, voting power, relayer address, relayer bls pubkey}] | +// | 32 bytes | 8 bytes | 32 bytes | [{32 bytes, 8 bytes, 20 bytes, 48 bytes}] | +func DecodeConsensusState(input []byte) (ConsensusState, error) { + minimumLength := chainIDLength + heightLength + validatorSetHashLength + inputLen := uint64(len(input)) + if inputLen <= minimumLength || (inputLen-minimumLength)%singleValidatorBytesLength != 0 { + return ConsensusState{}, fmt.Errorf("expected input size %d+%d*N, actual input size: %d", minimumLength, singleValidatorBytesLength, inputLen) + } + + pos := uint64(0) + chainID := string(bytes.Trim(input[pos:pos+chainIDLength], "\x00")) + pos += chainIDLength + + height := binary.BigEndian.Uint64(input[pos : pos+heightLength]) + pos += heightLength + + nextValidatorSetHash := input[pos : pos+validatorSetHashLength] + pos += validatorSetHashLength + + validatorSetLength := (inputLen - minimumLength) / singleValidatorBytesLength + validatorSetBytes := input[pos:] + validatorSet := make([]*types.Validator, 0, validatorSetLength) + for index := uint64(0); index < validatorSetLength; index++ { + validatorBytes := validatorSetBytes[singleValidatorBytesLength*index : singleValidatorBytesLength*(index+1)] + + pos = 0 + pubkey := ed25519.PubKey(make([]byte, ed25519.PubKeySize)) + copy(pubkey[:], validatorBytes[:validatorPubkeyLength]) + pos += validatorPubkeyLength + + votingPower := int64(binary.BigEndian.Uint64(validatorBytes[pos : pos+validatorVotingPowerLength])) + pos += validatorVotingPowerLength + + relayerAddress := make([]byte, relayerAddressLength) + copy(relayerAddress, validatorBytes[pos:pos+relayerAddressLength]) + pos += relayerAddressLength + + relayerBlsKey := make([]byte, relayerBlsKeyLength) + copy(relayerBlsKey, validatorBytes[pos:]) + + validator := types.NewValidator(pubkey, votingPower) + validator.SetRelayerAddress(relayerAddress) + validator.SetBlsKey(relayerBlsKey) + validatorSet = append(validatorSet, validator) + } + + consensusState := ConsensusState{ + ChainID: chainID, + Height: height, + NextValidatorSetHash: nextValidatorSetHash, + ValidatorSet: &types.ValidatorSet{ + Validators: validatorSet, + }, + } + + return consensusState, nil +} + +// input: +// consensus state length | consensus state | light block | +// 32 bytes | | | +func DecodeLightBlockValidationInput(input []byte) (*ConsensusState, *types.LightBlock, error) { + if uint64(len(input)) <= consensusStateLengthBytesLength { + return nil, nil, fmt.Errorf("invalid input") + } + + csLen := binary.BigEndian.Uint64(input[consensusStateLengthBytesLength-uint64TypeLength : consensusStateLengthBytesLength]) + if uint64(len(input)) <= consensusStateLengthBytesLength+csLen { + return nil, nil, fmt.Errorf("expected payload size %d, actual size: %d", consensusStateLengthBytesLength+csLen, len(input)) + } + + cs, err := DecodeConsensusState(input[consensusStateLengthBytesLength : consensusStateLengthBytesLength+csLen]) + if err != nil { + return nil, nil, err + } + + var lbpb tmproto.LightBlock + err = lbpb.Unmarshal(input[consensusStateLengthBytesLength+csLen:]) + if err != nil { + return nil, nil, err + } + block, err := types.LightBlockFromProto(&lbpb) + if err != nil { + return nil, nil, err + } + + return &cs, block, nil +} + +// output: +// | validatorSetChanged | empty | consensusStateBytesLength | new consensusState | +// | 1 byte | 23 bytes | 8 bytes | | +func EncodeLightBlockValidationResult(validatorSetChanged bool, consensusStateBytes []byte) []byte { + lengthBytes := make([]byte, validateResultMetaDataLength) + if validatorSetChanged { + copy(lengthBytes[:1], []byte{0x01}) + } + + consensusStateBytesLength := uint64(len(consensusStateBytes)) + binary.BigEndian.PutUint64(lengthBytes[validateResultMetaDataLength-uint64TypeLength:], consensusStateBytesLength) + + result := append(lengthBytes, consensusStateBytes...) + return result +} diff --git a/core/vm/lightclient/v2/lightclient_test.go b/core/vm/lightclient/v2/lightclient_test.go new file mode 100644 index 00000000000..7519ad2a19a --- /dev/null +++ b/core/vm/lightclient/v2/lightclient_test.go @@ -0,0 +1,174 @@ +// Package v2 is used for tendermint v0.34.22 and its compatible version. +package v2 + +import ( + "bytes" + "encoding/hex" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/cometbft/cometbft/crypto/ed25519" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" + "github.com/cometbft/cometbft/types" +) + +type validatorInfo struct { + pubKey string + votingPower int64 + relayerAddress string + relayerBlsKey string +} + +var testcases = []struct { + chainID string + height uint64 + nextValidatorSetHash string + vals []validatorInfo + consensusStateBytes string +}{ + { + chainID: "chain_9000-121", + height: 1, + nextValidatorSetHash: "0CE856B1DC9CDCF3BF2478291CF02C62AEEB3679889E9866931BF1FB05A10EDA", + vals: []validatorInfo{ + { + pubKey: "c3d9a1082f42ca161402f8668f8e39ec9e30092affd8d3262267ac7e248a959e", + votingPower: int64(10000), + relayerAddress: "B32d0723583040F3A16D1380D1e6AA874cD1bdF7", + relayerBlsKey: "a60afe627fd78b19e07e07e19d446009dd53a18c6c8744176a5d851a762bbb51198e7e006f2a6ea7225661a61ecd832d", + }, + }, + consensusStateBytes: "636861696e5f393030302d31323100000000000000000000000000000000000000000000000000010ce856b1dc9cdcf3bf2478291cf02c62aeeb3679889e9866931bf1fb05a10edac3d9a1082f42ca161402f8668f8e39ec9e30092affd8d3262267ac7e248a959e0000000000002710b32d0723583040f3a16d1380d1e6aa874cd1bdf7a60afe627fd78b19e07e07e19d446009dd53a18c6c8744176a5d851a762bbb51198e7e006f2a6ea7225661a61ecd832d", + }, + { + chainID: "chain_9000-121", + height: 1, + nextValidatorSetHash: "A5F1AF4874227F1CDBE5240259A365AD86484A4255BFD65E2A0222D733FCDBC3", + vals: []validatorInfo{ + { + pubKey: "20cc466ee9412ddd49e0fff04cdb41bade2b7622f08b6bdacac94d4de03bdb97", + votingPower: int64(10000), + relayerAddress: "d5e63aeee6e6fa122a6a23a6e0fca87701ba1541", + relayerBlsKey: "aa2d28cbcd1ea3a63479f6fb260a3d755853e6a78cfa6252584fee97b2ec84a9d572ee4a5d3bc1558bb98a4b370fb861", + }, + { + pubKey: "6b0b523ee91ad18a63d63f21e0c40a83ef15963f4260574ca5159fd90a1c5270", + votingPower: int64(10000), + relayerAddress: "6fd1ceb5a48579f322605220d4325bd9ff90d5fa", + relayerBlsKey: "b31e74a881fc78681e3dfa440978d2b8be0708a1cbbca2c660866216975fdaf0e9038d9b7ccbf9731f43956dba7f2451", + }, + { + pubKey: "919606ae20bf5d248ee353821754bcdb456fd3950618fda3e32d3d0fb990eeda", + votingPower: int64(10000), + relayerAddress: "97376a436bbf54e0f6949b57aa821a90a749920a", + relayerBlsKey: "b32979580ea04984a2be033599c20c7a0c9a8d121b57f94ee05f5eda5b36c38f6e354c89328b92cdd1de33b64d3a0867", + }, + }, + consensusStateBytes: "636861696e5f393030302d3132310000000000000000000000000000000000000000000000000001a5f1af4874227f1cdbe5240259a365ad86484a4255bfd65e2a0222d733fcdbc320cc466ee9412ddd49e0fff04cdb41bade2b7622f08b6bdacac94d4de03bdb970000000000002710d5e63aeee6e6fa122a6a23a6e0fca87701ba1541aa2d28cbcd1ea3a63479f6fb260a3d755853e6a78cfa6252584fee97b2ec84a9d572ee4a5d3bc1558bb98a4b370fb8616b0b523ee91ad18a63d63f21e0c40a83ef15963f4260574ca5159fd90a1c527000000000000027106fd1ceb5a48579f322605220d4325bd9ff90d5fab31e74a881fc78681e3dfa440978d2b8be0708a1cbbca2c660866216975fdaf0e9038d9b7ccbf9731f43956dba7f2451919606ae20bf5d248ee353821754bcdb456fd3950618fda3e32d3d0fb990eeda000000000000271097376a436bbf54e0f6949b57aa821a90a749920ab32979580ea04984a2be033599c20c7a0c9a8d121b57f94ee05f5eda5b36c38f6e354c89328b92cdd1de33b64d3a0867", + }, +} + +func TestEncodeConsensusState(t *testing.T) { + for i := 0; i < len(testcases); i++ { + testcase := testcases[i] + + var validatorSet []*types.Validator + + for j := 0; j < len(testcase.vals); j++ { + valInfo := testcase.vals[j] + + pubKeyBytes, err := hex.DecodeString(valInfo.pubKey) + require.NoError(t, err) + relayerAddress, err := hex.DecodeString(valInfo.relayerAddress) + require.NoError(t, err) + relayerBlsKey, err := hex.DecodeString(valInfo.relayerBlsKey) + require.NoError(t, err) + + pubkey := ed25519.PubKey(make([]byte, ed25519.PubKeySize)) + copy(pubkey[:], pubKeyBytes) + validator := types.NewValidator(pubkey, valInfo.votingPower) + validator.SetRelayerAddress(relayerAddress) + validator.SetBlsKey(relayerBlsKey) + validatorSet = append(validatorSet, validator) + } + + nextValidatorHash, err := hex.DecodeString(testcase.nextValidatorSetHash) + require.NoError(t, err) + + consensusState := ConsensusState{ + ChainID: testcase.chainID, + Height: testcase.height, + NextValidatorSetHash: nextValidatorHash, + ValidatorSet: &types.ValidatorSet{ + Validators: validatorSet, + }, + } + + csBytes, err := consensusState.EncodeConsensusState() + require.NoError(t, err) + + expectCsBytes, err := hex.DecodeString(testcase.consensusStateBytes) + require.NoError(t, err) + + if !bytes.Equal(csBytes, expectCsBytes) { + t.Fatalf("Consensus state mimatch, expect: %s, real:%s\n", testcase.consensusStateBytes, hex.EncodeToString(csBytes)) + } + } +} + +func TestDecodeConsensusState(t *testing.T) { + for i := 0; i < len(testcases); i++ { + testcase := testcases[i] + + csBytes, err := hex.DecodeString(testcase.consensusStateBytes) + require.NoError(t, err) + + cs, err := DecodeConsensusState(csBytes) + require.NoError(t, err) + + if cs.ChainID != testcase.chainID { + t.Fatalf("Chain ID mimatch, expect: %s, real:%s\n", testcase.chainID, cs.ChainID) + } + + if cs.Height != testcase.height { + t.Fatalf("Height mimatch, expect: %d, real:%d\n", testcase.height, cs.Height) + } + + nextValidatorSetHashBytes, err := hex.DecodeString(testcase.nextValidatorSetHash) + if err != nil { + t.Fatalf("Decode next validator set hash failed: %v\n", err) + } + + if !bytes.Equal(cs.NextValidatorSetHash, nextValidatorSetHashBytes) { + t.Fatalf("Next validator set hash mimatch, expect: %s, real:%s\n", testcase.nextValidatorSetHash, hex.EncodeToString(cs.NextValidatorSetHash)) + } + } +} + +func TestConsensusStateApplyLightBlock(t *testing.T) { + csBytes, err := hex.DecodeString("677265656e6669656c645f393030302d3132310000000000000000000000000000000000000000013c350cd55b99dc6c2b7da9bef5410fbfb869fede858e7b95bf7ca294e228bb40e33f6e876d63791ebd05ff617a1b4f4ad1aa2ce65e3c3a9cdfb33e0ffa7e8423000000000098968015154514f68ce65a0d9eecc578c0ab12da0a2a28a0805521b5b7ae56eb3fb24555efbfe59e1622bfe9f7be8c9022e9b3f2442739c1ce870b9adee169afe60f674edd7c86451c5363d89052fde8351895eeea166ce5373c36e31b518ed191d0c599aa0f5b0000000000989680432f6c4908a9aa5f3444421f466b11645235c99b831b2a2de9e504d7ea299e52a202ce529808618eb3bfc0addf13d8c5f2df821d81e18f9bc61583510b322d067d46323b0a572635c06a049c0a2a929e3c8184a50cf6a8b95708c25834ade456f399015a0000000000989680864cb9828254d712f8e59b164fc6a9402dc4e6c59065e38cff24f5323c8c5da888a0f97e5ee4ba1e11b0674b0a0d06204c1dfa247c370cd4be3e799fc4f6f48d977ac7ca") + require.NoError(t, err) + t.Logf("cs length: %d\n", len(csBytes)) + blockBytes, err := hex.DecodeString("0aeb060adb030a02080b1213677265656e6669656c645f393030302d3132311802220c08b2d7f3a10610e8d2adb3032a480a20ec6ecb5db4ffb17fabe40c60ca7b8441e9c5d77585d0831186f3c37aa16e9c15122408011220a2ab9e1eb9ea52812f413526e424b326aff2f258a56e00d690db9f805b60fe7e32200f40aeff672e8309b7b0aefbb9a1ae3d4299b5c445b7d54e8ff398488467f0053a20e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b85542203c350cd55b99dc6c2b7da9bef5410fbfb869fede858e7b95bf7ca294e228bb404a203c350cd55b99dc6c2b7da9bef5410fbfb869fede858e7b95bf7ca294e228bb405220294d8fbd0b94b767a7eba9840f299a3586da7fe6b5dead3b7eecba193c400f935a20bc50557c12d7392b0d07d75df0b61232d48f86a74fdea6d1485d9be6317d268c6220e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b8556a20e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b85572146699336aa109d1beab3946198c8e59f3b2cbd92f7a4065e3cd89e315ca39d87dee92835b98f8b8ec0861d6d9bb2c60156df5d375b3ceb1fbe71af6a244907d62548a694165caa660fec7a9b4e7b9198191361c71be0b128a0308021a480a20726abd0fdbfb6f779b0483e6e4b4b6f12241f6ea2bf374233ab1a316692b6415122408011220159f10ff15a8b58fc67a92ffd7f33c8cd407d4ce81b04ca79177dfd00ca19a67226808021214050cff76cc632760ba9db796c046004c900967361a0c08b3d7f3a10610808cadba03224080713027ffb776a702d78fd0406205c629ba473e1f8d6af646190f6eb9262cd67d69be90d10e597b91e06d7298eb6fa4b8f1eb7752ebf352a1f51560294548042268080212146699336aa109d1beab3946198c8e59f3b2cbd92f1a0c08b3d7f3a10610b087c1c00322405e2ddb70acfe4904438be3d9f4206c0ace905ac4fc306a42cfc9e86268950a0fbfd6ec5f526d3e41a3ef52bf9f9f358e3cb4c3feac76c762fa3651c1244fe004226808021214c55765fd2d0570e869f6ac22e7f2916a35ea300d1a0c08b3d7f3a10610f0b3d492032240ca17898bd22232fc9374e1188636ee321a396444a5b1a79f7628e4a11f265734b2ab50caf21e8092c55d701248e82b2f011426cb35ba22043b497a6b4661930612a0050aa8010a14050cff76cc632760ba9db796c046004c9009673612220a20e33f6e876d63791ebd05ff617a1b4f4ad1aa2ce65e3c3a9cdfb33e0ffa7e84231880ade2042080a6bbf6ffffffffff012a30a0805521b5b7ae56eb3fb24555efbfe59e1622bfe9f7be8c9022e9b3f2442739c1ce870b9adee169afe60f674edd7c86321415154514f68ce65a0d9eecc578c0ab12da0a2a283a14ee7a2a6a44d427f6949eeb8f12ea9fbb2501da880aa2010a146699336aa109d1beab3946198c8e59f3b2cbd92f12220a20451c5363d89052fde8351895eeea166ce5373c36e31b518ed191d0c599aa0f5b1880ade2042080ade2042a30831b2a2de9e504d7ea299e52a202ce529808618eb3bfc0addf13d8c5f2df821d81e18f9bc61583510b322d067d46323b3214432f6c4908a9aa5f3444421f466b11645235c99b3a14a0a7769429468054e19059af4867da0a495567e50aa2010a14c55765fd2d0570e869f6ac22e7f2916a35ea300d12220a200a572635c06a049c0a2a929e3c8184a50cf6a8b95708c25834ade456f399015a1880ade2042080ade2042a309065e38cff24f5323c8c5da888a0f97e5ee4ba1e11b0674b0a0d06204c1dfa247c370cd4be3e799fc4f6f48d977ac7ca3214864cb9828254d712f8e59b164fc6a9402dc4e6c53a143139916d97df0c589312b89950b6ab9795f34d1a12a8010a14050cff76cc632760ba9db796c046004c9009673612220a20e33f6e876d63791ebd05ff617a1b4f4ad1aa2ce65e3c3a9cdfb33e0ffa7e84231880ade2042080a6bbf6ffffffffff012a30a0805521b5b7ae56eb3fb24555efbfe59e1622bfe9f7be8c9022e9b3f2442739c1ce870b9adee169afe60f674edd7c86321415154514f68ce65a0d9eecc578c0ab12da0a2a283a14ee7a2a6a44d427f6949eeb8f12ea9fbb2501da88") + require.NoError(t, err) + + var lbpb tmproto.LightBlock + err = lbpb.Unmarshal(blockBytes) + require.NoError(t, err) + block, err := types.LightBlockFromProto(&lbpb) + require.NoError(t, err) + + cs, err := DecodeConsensusState(csBytes) + require.NoError(t, err) + validatorSetChanged, err := cs.ApplyLightBlock(block) + require.NoError(t, err) + + if cs.Height != 2 { + t.Fatalf("Height is unexpected, expected: 2, actual: %d\n", cs.Height) + } + + if validatorSetChanged { + t.Fatalf("Validator set has exchanaged which is not expected.\n") + } +} diff --git a/crypto/kzg/kzg.go b/crypto/kzg/kzg.go new file mode 100644 index 00000000000..b90e60052d6 --- /dev/null +++ b/crypto/kzg/kzg.go @@ -0,0 +1,113 @@ +package kzg + +import ( + "crypto/sha256" + "errors" + "fmt" + "math/big" + "sync" + + gokzg4844 "github.com/crate-crypto/go-kzg-4844" +) + +const ( + BlobCommitmentVersionKZG uint8 = 0x01 + FieldElementsPerBlob int = 4096 +) + +type VersionedHash [32]byte +type Root [32]byte +type Slot uint64 + +type BlobsSidecar struct { + BeaconBlockRoot Root + BeaconBlockSlot Slot + Blobs []gokzg4844.Blob + Proofs []gokzg4844.KZGProof +} + +const ( + BlobTxType = 5 + PrecompileInputLength = 192 + BlobVersionedHashesOffset = 258 // position of blob_versioned_hashes offset in a serialized blob tx, see TxPeekBlobVersionedHashes +) + +var ( + errInvalidInputLength = errors.New("invalid input length") +) + +// The value that gets returned when the `verify_kzg_proof“ precompile is called +var precompileReturnValue [64]byte + +var gCryptoCtx gokzg4844.Context +var initCryptoCtx sync.Once + +// InitializeCrypytoCtx initializes the global context object returned via CryptoCtx +func InitializeCrypytoCtx() { + initCryptoCtx.Do(func() { + // Initialize context to match the configurations that the + // specs are using. + ctx, err := gokzg4844.NewContext4096Insecure1337() + if err != nil { + panic(fmt.Sprintf("could not create context, err : %v", err)) + } + gCryptoCtx = *ctx + // Initialize the precompile return value + new(big.Int).SetUint64(gokzg4844.ScalarsPerBlob).FillBytes(precompileReturnValue[:32]) + copy(precompileReturnValue[32:], gokzg4844.BlsModulus[:]) + }) +} + +// CryptoCtx returns a context object stores all of the necessary configurations +// to allow one to create and verify blob proofs. +// This function is expensive to run if the crypto context isn't initialized, so it is recommended to +// pre-initialize by calling InitializeCryptoCtx +func CrpytoCtx() gokzg4844.Context { + InitializeCrypytoCtx() + return gCryptoCtx +} + +// PointEvaluationPrecompile implements point_evaluation_precompile from EIP-4844 +func PointEvaluationPrecompile(input []byte) ([]byte, error) { + if len(input) != PrecompileInputLength { + return nil, errInvalidInputLength + } + // versioned hash: first 32 bytes + var versionedHash [32]byte + copy(versionedHash[:], input[:32]) + + var x, y [32]byte + // Evaluation point: next 32 bytes + copy(x[:], input[32:64]) + // Expected output: next 32 bytes + copy(y[:], input[64:96]) + + // input kzg point: next 48 bytes + var dataKZG [48]byte + copy(dataKZG[:], input[96:144]) + if KZGToVersionedHash(gokzg4844.KZGCommitment(dataKZG)) != VersionedHash(versionedHash) { + return nil, errors.New("mismatched versioned hash") + } + + // Quotient kzg: next 48 bytes + var quotientKZG [48]byte + copy(quotientKZG[:], input[144:PrecompileInputLength]) + + cryptoCtx := CrpytoCtx() + err := cryptoCtx.VerifyKZGProof(dataKZG, x, y, quotientKZG) + if err != nil { + return nil, fmt.Errorf("verify_kzg_proof error: %v", err) + } + + result := precompileReturnValue // copy the value + + return result[:], nil +} + +// KZGToVersionedHash implements kzg_to_versioned_hash from EIP-4844 +func KZGToVersionedHash(kzg gokzg4844.KZGCommitment) VersionedHash { + h := sha256.Sum256(kzg[:]) + h[0] = BlobCommitmentVersionKZG + + return VersionedHash(h) +} diff --git a/crypto/signature_nocgo.go b/crypto/signature_nocgo.go index 338ee4b2482..0edc7afd68e 100644 --- a/crypto/signature_nocgo.go +++ b/crypto/signature_nocgo.go @@ -23,37 +23,48 @@ import ( "crypto/elliptic" "errors" "fmt" - "math/big" "github.com/btcsuite/btcd/btcec" + btc_ecdsa "github.com/btcsuite/btcd/btcec/v2/ecdsa" ) // Ecrecover returns the uncompressed public key that created the given signature. func Ecrecover(hash, sig []byte) ([]byte, error) { - pub, err := SigToPub(hash, sig) + pub, err := sigToPub(hash, sig) if err != nil { return nil, err } - bytes := (*btcec.PublicKey)(pub).SerializeUncompressed() + bytes := pub.SerializeUncompressed() return bytes, err } -// SigToPub returns the public key that created the given signature. -func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) { +func sigToPub(hash, sig []byte) (*btcec.PublicKey, error) { + if len(sig) != SignatureLength { + return nil, errors.New("invalid signature") + } // Convert to btcec input format with 'recovery id' v at the beginning. btcsig := make([]byte, SignatureLength) - btcsig[0] = sig[64] + 27 + btcsig[0] = sig[RecoveryIDOffset] + 27 copy(btcsig[1:], sig) - pub, _, err := btcec.RecoverCompact(btcec.S256(), btcsig, hash) - return (*ecdsa.PublicKey)(pub), err + pub, _, err := btc_ecdsa.RecoverCompact(btcsig, hash) + return pub, err +} + +// SigToPub returns the public key that created the given signature. +func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) { + pub, err := sigToPub(hash, sig) + if err != nil { + return nil, err + } + return pub.ToECDSA(), nil } // Sign calculates an ECDSA signature. // // This function is susceptible to chosen plaintext attacks that can leak // information about the private key that is used for signing. Callers must -// be aware that the given hash cannot be chosen by an adversery. Common +// be aware that the given hash cannot be chosen by an adversary. Common // solution is to hash any input before calculating the signature. // // The produced signature is in the [R || S || V] format where V is 0 or 1. @@ -64,14 +75,20 @@ func Sign(hash []byte, prv *ecdsa.PrivateKey) ([]byte, error) { if prv.Curve != btcec.S256() { return nil, fmt.Errorf("private key curve is not secp256k1") } - sig, err := btcec.SignCompact(btcec.S256(), (*btcec.PrivateKey)(prv), hash, false) + // ecdsa.PrivateKey -> btcec.PrivateKey + var priv btcec.PrivateKey + if overflow := priv.Key.SetByteSlice(prv.D.Bytes()); overflow || priv.Key.IsZero() { + return nil, fmt.Errorf("invalid private key") + } + defer priv.Zero() + sig, err := btc_ecdsa.SignCompact(&priv, hash, false) // ref uncompressed pubkey if err != nil { return nil, err } // Convert to Ethereum signature format with 'recovery id' v at the end. v := sig[0] - 27 copy(sig, sig[1:]) - sig[64] = v + sig[RecoveryIDOffset] = v return sig, nil } @@ -82,13 +99,20 @@ func VerifySignature(pubkey, hash, signature []byte) bool { if len(signature) != 64 { return false } - sig := &btcec.Signature{R: new(big.Int).SetBytes(signature[:32]), S: new(big.Int).SetBytes(signature[32:])} - key, err := btcec.ParsePubKey(pubkey, btcec.S256()) + var r, s btcec.ModNScalar + if r.SetByteSlice(signature[:32]) { + return false // overflow + } + if s.SetByteSlice(signature[32:]) { + return false + } + sig := btc_ecdsa.NewSignature(&r, &s) + key, err := btcec.ParsePubKey(pubkey) if err != nil { return false } // Reject malleable signatures. libsecp256k1 does this check but btcec doesn't. - if sig.S.Cmp(secp256k1halfN.ToBig()) > 0 { + if s.IsOverHalfOrder() { return false } return sig.Verify(hash, key) @@ -99,16 +123,26 @@ func DecompressPubkey(pubkey []byte) (*ecdsa.PublicKey, error) { if len(pubkey) != 33 { return nil, errors.New("invalid compressed public key length") } - key, err := btcec.ParsePubKey(pubkey, btcec.S256()) + key, err := btcec.ParsePubKey(pubkey) if err != nil { return nil, err } return key.ToECDSA(), nil } -// CompressPubkey encodes a public key to the 33-byte compressed format. +// CompressPubkey encodes a public key to the 33-byte compressed format. The +// provided PublicKey must be valid. Namely, the coordinates must not be larger +// than 32 bytes each, they must be less than the field prime, and it must be a +// point on the secp256k1 curve. This is the case for a PublicKey constructed by +// elliptic.Unmarshal (see UnmarshalPubkey), or by ToECDSA and ecdsa.GenerateKey +// when constructing a PrivateKey. func CompressPubkey(pubkey *ecdsa.PublicKey) []byte { - return (*btcec.PublicKey)(pubkey).SerializeCompressed() + // NOTE: the coordinates may be validated with + // btcec.ParsePubKey(FromECDSAPub(pubkey)) + var x, y btcec.FieldVal + x.SetByteSlice(pubkey.X.Bytes()) + y.SetByteSlice(pubkey.Y.Bytes()) + return btcec.NewPublicKey(&x, &y).SerializeCompressed() } // S256 returns an instance of the secp256k1 curve. diff --git a/dataflow/states.go b/dataflow/states.go new file mode 100644 index 00000000000..8eab162c6a3 --- /dev/null +++ b/dataflow/states.go @@ -0,0 +1,106 @@ +package dataflow + +import ( + "fmt" + "io" + "sync" + + "github.com/google/btree" +) + +var BlockBodyDownloadStates *States = NewStates(64 * 1024) + +const ( + BlockBodyCleared byte = iota + BlockBodyExpired + BlockBodyRequested + BlockBodyReceived + BlockBodyEvicted + BlockBodySkipped // Delivery requested but was skipped due to limitation on the size of the response + BlockBodyEmpty // Identified as empty and no need to be requested + BlockBodyPrefetched + BlockBodyInDb +) + +type SnapshotItem struct { + id uint64 + state byte +} + +type States struct { + lock sync.Mutex + window int + ids []uint64 + states []byte + snapshot *btree.BTreeG[SnapshotItem] + snapshotTick int + idx int +} + +func NewStates(window int) *States { + s := &States{ + window: window, + ids: make([]uint64, window), + states: make([]byte, window), + snapshot: btree.NewG[SnapshotItem](16, func(a, b SnapshotItem) bool { + return a.id < b.id + }), + idx: 0, + } + return s +} + +func (s *States) AddChange(id uint64, state byte) { + s.lock.Lock() + defer s.lock.Unlock() + if s.idx >= s.window { + s.makeSnapshot() + } + i := s.idx + s.idx++ + s.ids[i] = id + s.states[i] = state +} + +func (s *States) makeSnapshot() { + newSnapshot := map[uint64]byte{} + // snapshotTime is now time of the latest change + s.snapshotTick += s.idx + // Proceed backwards + for i := s.idx - 1; i >= 0; i-- { + if _, ok := newSnapshot[s.ids[i]]; !ok { + newSnapshot[s.ids[i]] = s.states[i] + } + } + for id, state := range newSnapshot { + if state == 0 { + s.snapshot.Delete(SnapshotItem{id: id}) + } else { + s.snapshot.ReplaceOrInsert(SnapshotItem{id: id, state: state}) + } + } + s.idx = 0 +} + +func (s *States) ChangesSince(startTick int, w io.Writer) { + s.lock.Lock() + defer s.lock.Unlock() + var startI int + var tick int + if startTick <= s.snapshotTick { + // Include snapshot + fmt.Fprintf(w, "snapshot %d\n", s.snapshotTick) + s.snapshot.Ascend(func(a SnapshotItem) bool { + fmt.Fprintf(w, "%d,%d\n", a.id, a.state) + return true + }) + tick = s.snapshotTick + 1 + } else { + startI = startTick - s.snapshotTick + tick = startTick + } + fmt.Fprintf(w, "changes %d\n", tick) + for i := startI; i < s.idx; i++ { + fmt.Fprintf(w, "%d,%d\n", s.ids[i], s.states[i]) + } +} diff --git a/diagnostics/block_body_download.go b/diagnostics/block_body_download.go new file mode 100644 index 00000000000..c60fa1b9bab --- /dev/null +++ b/diagnostics/block_body_download.go @@ -0,0 +1,34 @@ +package diagnostics + +import ( + "fmt" + "io" + "net/http" + "strconv" + + "github.com/ledgerwatch/erigon/dataflow" +) + +func SetupBlockBodyDownload() { + http.HandleFunc("/debug/metrics/block_body_download", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Access-Control-Allow-Origin", "*") + writeBlockBodyDownload(w, r) + }) +} + +func writeBlockBodyDownload(w io.Writer, r *http.Request) { + if err := r.ParseForm(); err != nil { + fmt.Fprintf(w, "ERROR: parsing arguments: %v\n", err) + return + } + sinceTickStr := r.Form.Get("sincetick") + var tick int64 + if sinceTickStr != "" { + var err error + if tick, err = strconv.ParseInt(sinceTickStr, 10, 64); err != nil { + fmt.Fprintf(w, "ERROR: parsing sincemilli: %v\n", err) + } + } + fmt.Fprintf(w, "SUCCESS\n") + dataflow.BlockBodyDownloadStates.ChangesSince(int(tick), w) +} diff --git a/diagnostics/cmd_line.go b/diagnostics/cmd_line.go new file mode 100644 index 00000000000..067861d7ba7 --- /dev/null +++ b/diagnostics/cmd_line.go @@ -0,0 +1,22 @@ +package diagnostics + +import ( + "fmt" + "io" + "net/http" + "os" +) + +func SetupCmdLineAccess() { + http.HandleFunc("/debug/metrics/cmdline", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Access-Control-Allow-Origin", "*") + writeCmdLine(w) + }) +} + +func writeCmdLine(w io.Writer) { + fmt.Fprintf(w, "SUCCESS\n") + for _, arg := range os.Args { + fmt.Fprintf(w, "%s\n", arg) + } +} diff --git a/diagnostics/logs_access.go b/diagnostics/logs_access.go index 7c988b83124..58bfe69b15b 100644 --- a/diagnostics/logs_access.go +++ b/diagnostics/logs_access.go @@ -17,6 +17,12 @@ import ( func SetupLogsAccess(ctx *cli.Context) { dirPath := ctx.String(logging.LogDirPathFlag.Name) + if dirPath == "" { + datadir := ctx.String("datadir") + if datadir != "" { + dirPath = filepath.Join(datadir, "logs") + } + } if dirPath == "" { return } diff --git a/diagnostics/version.go b/diagnostics/version.go new file mode 100644 index 00000000000..a8b97e73d2e --- /dev/null +++ b/diagnostics/version.go @@ -0,0 +1,25 @@ +package diagnostics + +import ( + "fmt" + "io" + "net/http" + + "github.com/ledgerwatch/erigon/params" +) + +const Version = 1 + +func SetupVersionAccess() { + http.HandleFunc("/debug/metrics/version", func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Access-Control-Allow-Origin", "*") + writeVersion(w) + }) +} + +func writeVersion(w io.Writer) { + fmt.Fprintf(w, "SUCCESS\n") + fmt.Fprintf(w, "%d\n", Version) + fmt.Fprintf(w, "%s\n", params.VersionWithMeta) + fmt.Fprintf(w, "%s\n", params.GitCommit) +} diff --git a/docker-compose.yml b/docker-compose.yml index a7ea8b9eeea..bf5982c9b4a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -71,7 +71,7 @@ services: prometheus: - image: prom/prometheus:v2.42.0 + image: prom/prometheus:v2.43.0 user: ${DOCKER_UID:-1000}:${DOCKER_GID:-1000} # Uses erigon user from Dockerfile command: --log.level=warn --config.file=/etc/prometheus/prometheus.yml --storage.tsdb.path=/prometheus --storage.tsdb.retention.time=150d --web.console.libraries=/usr/share/prometheus/console_libraries --web.console.templates=/usr/share/prometheus/consoles ports: [ "9090:9090" ] @@ -81,7 +81,7 @@ services: restart: unless-stopped grafana: - image: grafana/grafana:9.3.6 + image: grafana/grafana:9.4.7 user: "472:0" # required for grafana version >= 7.3 ports: [ "3000:3000" ] volumes: diff --git a/eth/backend.go b/eth/backend.go index e97975e9ca6..562beb8ad58 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -32,6 +32,12 @@ import ( "time" "github.com/holiman/uint256" + "github.com/ledgerwatch/log/v3" + "golang.org/x/exp/slices" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + "google.golang.org/protobuf/types/known/emptypb" + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/datadir" @@ -49,32 +55,19 @@ import ( "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv/kvcache" "github.com/ledgerwatch/erigon-lib/kv/kvcfg" - "github.com/ledgerwatch/erigon-lib/kv/memdb" "github.com/ledgerwatch/erigon-lib/kv/remotedbserver" libstate "github.com/ledgerwatch/erigon-lib/state" txpool2 "github.com/ledgerwatch/erigon-lib/txpool" "github.com/ledgerwatch/erigon-lib/txpool/txpooluitl" types2 "github.com/ledgerwatch/erigon-lib/types" - "github.com/ledgerwatch/log/v3" - "golang.org/x/exp/slices" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials" - "google.golang.org/protobuf/types/known/emptypb" - - "github.com/ledgerwatch/erigon/core/systemcontracts" - "github.com/ledgerwatch/erigon/p2p/enode" - - "github.com/ledgerwatch/erigon/core/state/historyv2read" - "github.com/ledgerwatch/erigon/core/state/temporal" - "github.com/ledgerwatch/erigon/core/types/accounts" "github.com/ledgerwatch/erigon/cl/clparams" + "github.com/ledgerwatch/erigon/cmd/caplin-phase1/caplin1" clcore "github.com/ledgerwatch/erigon/cmd/erigon-cl/core" - "github.com/ledgerwatch/erigon/cmd/lightclient/lightclient" + "github.com/ledgerwatch/erigon/cmd/erigon-cl/execution_client" "github.com/ledgerwatch/erigon/cmd/rpcdaemon/cli" "github.com/ledgerwatch/erigon/cmd/rpcdaemon/commands" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel" - "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/handshake" "github.com/ledgerwatch/erigon/cmd/sentinel/sentinel/service" "github.com/ledgerwatch/erigon/cmd/sentry/sentry" "github.com/ledgerwatch/erigon/common/debug" @@ -86,7 +79,11 @@ import ( "github.com/ledgerwatch/erigon/consensus/serenity" "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/core/rawdb" + "github.com/ledgerwatch/erigon/core/state/historyv2read" + "github.com/ledgerwatch/erigon/core/state/temporal" + "github.com/ledgerwatch/erigon/core/systemcontracts" "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/core/types/accounts" "github.com/ledgerwatch/erigon/core/vm" "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/eth/ethconfig" @@ -100,6 +97,7 @@ import ( "github.com/ledgerwatch/erigon/ethstats" "github.com/ledgerwatch/erigon/node" "github.com/ledgerwatch/erigon/p2p" + "github.com/ledgerwatch/erigon/p2p/enode" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/engineapi" @@ -118,7 +116,6 @@ type Config = ethconfig.Config // Ethereum implements the Ethereum full node service. type Ethereum struct { config *ethconfig.Config - log log.Logger // DB interfaces chainDB kv.RwDB @@ -191,7 +188,7 @@ func splitAddrIntoHostAndPort(addr string) (host string, port int, err error) { // New creates a new Ethereum object (including the // initialisation of the common Ethereum object) -func New(stack *node.Node, config *ethconfig.Config, logger log.Logger) (*Ethereum, error) { +func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { if config.Miner.GasPrice == nil || config.Miner.GasPrice.Cmp(libcommon.Big0) <= 0 { log.Warn("Sanitizing invalid miner gas price", "provided", config.Miner.GasPrice, "updated", ethconfig.Defaults.Miner.GasPrice) config.Miner.GasPrice = new(big.Int).Set(ethconfig.Defaults.Miner.GasPrice) @@ -204,7 +201,7 @@ func New(stack *node.Node, config *ethconfig.Config, logger log.Logger) (*Ethere } // Assemble the Ethereum object - chainKv, err := node.OpenDatabase(stack.Config(), logger, kv.ChainDB) + chainKv, err := node.OpenDatabase(stack.Config(), kv.ChainDB) if err != nil { return nil, err } @@ -289,7 +286,6 @@ func New(stack *node.Node, config *ethconfig.Config, logger log.Logger) (*Ethere sentryCtx: ctx, sentryCancel: ctxCancel, config: config, - log: logger, chainDB: chainKv, networkID: config.NetworkID, etherbase: config.Miner.Etherbase, @@ -448,7 +444,6 @@ func New(stack *node.Node, config *ethconfig.Config, logger log.Logger) (*Ethere if chainConfig.Clique != nil { consensusConfig = &config.Clique } else if chainConfig.Aura != nil { - config.Aura.Etherbase = config.Miner.Etherbase consensusConfig = &config.Aura } else if chainConfig.Parlia != nil { consensusConfig = &config.Parlia @@ -457,7 +452,7 @@ func New(stack *node.Node, config *ethconfig.Config, logger log.Logger) (*Ethere } else { consensusConfig = &config.Ethash } - backend.engine = ethconsensusconfig.CreateConsensusEngine(chainConfig, logger, consensusConfig, config.Miner.Notify, config.Miner.Noverify, config.HeimdallgRPCAddress, config.HeimdallURL, config.WithoutHeimdall, stack.DataDir(), allSnapshots, false /* readonly */, backend.chainDB) + backend.engine = ethconsensusconfig.CreateConsensusEngine(chainConfig, consensusConfig, config.Miner.Notify, config.Miner.Noverify, config.HeimdallgRPCAddress, config.HeimdallURL, config.WithoutHeimdall, stack.DataDir(), allSnapshots, false /* readonly */, backend.chainDB) backend.forkValidator = engineapi.NewForkValidator(currentBlockNumber, inMemoryExecution, tmpdir) backend.sentriesClient, err = sentry.NewMultiClient( @@ -568,7 +563,7 @@ func New(stack *node.Node, config *ethconfig.Config, logger log.Logger) (*Ethere } // If we choose not to run a consensus layer, run our embedded. - if !config.ExternalCL && clparams.EmbeddedSupported(config.NetworkID) { + if config.InternalCL && clparams.EmbeddedSupported(config.NetworkID) { genesisCfg, networkCfg, beaconCfg := clparams.GetConfigsByNetwork(clparams.NetworkType(config.NetworkID)) if err != nil { return nil, err @@ -581,27 +576,19 @@ func New(stack *node.Node, config *ethconfig.Config, logger log.Logger) (*Ethere NetworkConfig: networkCfg, BeaconConfig: beaconCfg, TmpDir: tmpdir, - }, chainKv, &service.ServerConfig{Network: "tcp", Addr: fmt.Sprintf("%s:%d", config.SentinelAddr, config.SentinelPort)}, creds, nil, handshake.LightClientRule) + }, chainKv, &service.ServerConfig{Network: "tcp", Addr: fmt.Sprintf("%s:%d", config.SentinelAddr, config.SentinelPort)}, creds, nil) if err != nil { return nil, err } - - lc, err := lightclient.NewLightClient(ctx, memdb.New(tmpdir), genesisCfg, beaconCfg, ethBackendRPC, nil, client, currentBlockNumber, false) - if err != nil { - return nil, err - } - bs, err := clcore.RetrieveBeaconState(ctx, beaconCfg, genesisCfg, + engine := execution_client.NewExecutionEnginePhase1FromServer(ctx, ethBackendRPC) + state, err := clcore.RetrieveBeaconState(ctx, beaconCfg, genesisCfg, clparams.GetCheckpointSyncEndpoint(clparams.NetworkType(config.NetworkID))) if err != nil { return nil, err } - if err := lc.BootstrapCheckpoint(ctx, bs.FinalizedCheckpoint().Root); err != nil { - return nil, err - } - - go lc.Start() + go caplin1.RunCaplinPhase1(ctx, client, beaconCfg, genesisCfg, engine, state) } if currentBlock == nil { @@ -994,7 +981,7 @@ func (s *Ethereum) setUpBlockReader(ctx context.Context, dirs datadir.Dirs, snCo if err != nil { return nil, nil, nil, err } - go downloader3.MainLoop(ctx, s.downloader, true) + s.downloader.MainLoopInBackground(ctx, true) bittorrentServer, err := downloader3.NewGrpcServer(s.downloader) if err != nil { return nil, nil, nil, fmt.Errorf("new server: %w", err) diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index 4b753242ed1..87c4a40fd11 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -242,7 +242,7 @@ type Config struct { // Ethstats service Ethstats string // Consensus layer - ExternalCL bool + InternalCL bool LightClientDiscoveryAddr string LightClientDiscoveryPort uint64 LightClientDiscoveryTCPPort uint64 diff --git a/eth/ethconfig/estimate/esitmated_ram.go b/eth/ethconfig/estimate/esitmated_ram.go index 2798d3cb1b2..7487fcc2fb9 100644 --- a/eth/ethconfig/estimate/esitmated_ram.go +++ b/eth/ethconfig/estimate/esitmated_ram.go @@ -1,11 +1,13 @@ package estimate import ( + "os" "runtime" "github.com/c2h5oh/datasize" "github.com/ledgerwatch/erigon-lib/common/cmp" "github.com/pbnjay/memory" + "github.com/shirou/gopsutil/v3/docker" ) type estimatedRamPerWorker datasize.ByteSize @@ -13,7 +15,7 @@ type estimatedRamPerWorker datasize.ByteSize // Workers - return max workers amount based on total Memory/CPU's and estimated RAM per worker func (r estimatedRamPerWorker) Workers() int { // 50% of TotalMemory. Better don't count on 100% because OOM Killer may have aggressive defaults and other software may need RAM - maxWorkersForGivenMemory := (memory.TotalMemory() / 2) / uint64(r) + maxWorkersForGivenMemory := (totalMemory() / 2) / uint64(r) return cmp.Min(AlmostAllCPUs(), int(maxWorkersForGivenMemory)) } func (r estimatedRamPerWorker) WorkersHalf() int { return cmp.Max(1, r.Workers()/2) } @@ -30,3 +32,29 @@ const ( func AlmostAllCPUs() int { return cmp.Max(1, runtime.GOMAXPROCS(-1)-1) } +func totalMemory() uint64 { + mem := memory.TotalMemory() + + if cgroupsMemLimit, ok := cgroupsMemoryLimit(); ok { + mem = cmp.Min(mem, cgroupsMemLimit) + } + + return mem +} + +// apply limit from docker if can, treat errors as "not available or maybe non-docker environment +// supports only cgroups v1, for v2 see: https://github.com/shirou/gopsutil/issues/1416 +func cgroupsMemoryLimit() (mem uint64, ok bool) { + hostname, err := os.Hostname() + if err != nil { + return 0, false + } + cgmem, err := docker.CgroupMemDocker(hostname) + if err != nil { + return 0, false + } + if cgmem == nil || cgmem.MemLimitInBytes <= 0 { + return 0, false + } + return cgmem.MemLimitInBytes, true +} diff --git a/eth/ethconfig/gen_config.go b/eth/ethconfig/gen_config.go index 502603d1dba..ff557ae08d7 100644 --- a/eth/ethconfig/gen_config.go +++ b/eth/ethconfig/gen_config.go @@ -8,10 +8,10 @@ import ( "github.com/c2h5oh/datasize" "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon/consensus/ethash/ethashcfg" + "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/eth/gasprice/gaspricecfg" - "github.com/ledgerwatch/erigon/consensus/ethash" - "github.com/ledgerwatch/erigon/core" - "github.com/ledgerwatch/erigon/eth/gasprice" "github.com/ledgerwatch/erigon/ethdb/prune" "github.com/ledgerwatch/erigon/params" ) @@ -19,7 +19,7 @@ import ( // MarshalTOML marshals as TOML. func (c Config) MarshalTOML() (interface{}, error) { type Config struct { - Genesis *core.Genesis `toml:",omitempty"` + Genesis *types.Genesis `toml:",omitempty"` NetworkID uint64 EthDiscoveryURLs []string P2PEnabled bool @@ -32,12 +32,11 @@ func (c Config) MarshalTOML() (interface{}, error) { ExternalSnapshotDownloaderAddr string Whitelist map[uint64]libcommon.Hash `toml:"-"` Miner params.MiningConfig - Ethash ethash.Config + Ethash ethashcfg.Config Clique params.ConsensusSnapshotConfig Aura chain.AuRaConfig - Parlia chain.ParliaConfig - TxPool core.TxPoolConfig - GPO gasprice.Config + TxPool DeprecatedTxPoolConfig + GPO gaspricecfg.Config RPCGasCap uint64 `toml:",omitempty"` RPCTxFeeCap float64 `toml:",omitempty"` StateStream bool @@ -60,7 +59,6 @@ func (c Config) MarshalTOML() (interface{}, error) { enc.Ethash = c.Ethash enc.Clique = c.Clique enc.Aura = c.Aura - enc.Parlia = c.Parlia enc.TxPool = c.DeprecatedTxPool enc.GPO = c.GPO enc.RPCGasCap = c.RPCGasCap @@ -72,7 +70,7 @@ 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"` + Genesis *types.Genesis `toml:",omitempty"` NetworkID *uint64 EthDiscoveryURLs []string P2PEnabled *bool @@ -85,12 +83,11 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { ExternalSnapshotDownloaderAddr *string Whitelist map[uint64]libcommon.Hash `toml:"-"` Miner *params.MiningConfig - Ethash *ethash.Config + Ethash *ethashcfg.Config Clique *params.ConsensusSnapshotConfig Aura *chain.AuRaConfig - Parlia *chain.ParliaConfig - TxPool *core.TxPoolConfig - GPO *gasprice.Config + TxPool *DeprecatedTxPoolConfig + GPO *gaspricecfg.Config RPCGasCap *uint64 `toml:",omitempty"` RPCTxFeeCap *float64 `toml:",omitempty"` StateStream *bool @@ -146,9 +143,6 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.Aura != nil { c.Aura = *dec.Aura } - if dec.Parlia != nil { - c.Parlia = *dec.Parlia - } if dec.TxPool != nil { c.DeprecatedTxPool = *dec.TxPool } diff --git a/eth/ethconsensusconfig/config.go b/eth/ethconsensusconfig/config.go index 1ae814745ea..11c95f8feec 100644 --- a/eth/ethconsensusconfig/config.go +++ b/eth/ethconsensusconfig/config.go @@ -3,15 +3,14 @@ package ethconsensusconfig import ( "path/filepath" - "github.com/ledgerwatch/erigon-lib/chain" - "github.com/ledgerwatch/erigon-lib/kv" - "github.com/davecgh/go-spew/spew" "github.com/ledgerwatch/log/v3" + "github.com/ledgerwatch/erigon-lib/chain" + "github.com/ledgerwatch/erigon-lib/kv" + "github.com/ledgerwatch/erigon/consensus" "github.com/ledgerwatch/erigon/consensus/aura" - "github.com/ledgerwatch/erigon/consensus/aura/consensusconfig" "github.com/ledgerwatch/erigon/consensus/bor" "github.com/ledgerwatch/erigon/consensus/bor/contract" "github.com/ledgerwatch/erigon/consensus/bor/heimdall" @@ -20,29 +19,30 @@ import ( "github.com/ledgerwatch/erigon/consensus/clique" "github.com/ledgerwatch/erigon/consensus/db" "github.com/ledgerwatch/erigon/consensus/ethash" + "github.com/ledgerwatch/erigon/consensus/ethash/ethashcfg" "github.com/ledgerwatch/erigon/consensus/parlia" "github.com/ledgerwatch/erigon/consensus/serenity" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/turbo/snapshotsync" ) -func CreateConsensusEngine(chainConfig *chain.Config, logger log.Logger, config interface{}, notify []string, noverify bool, HeimdallgRPCAddress string, HeimdallURL string, WithoutHeimdall bool, datadir string, snapshots *snapshotsync.RoSnapshots, readonly bool, chainDb ...kv.RwDB) consensus.Engine { +func CreateConsensusEngine(chainConfig *chain.Config, config interface{}, notify []string, noverify bool, HeimdallgRPCAddress string, HeimdallURL string, WithoutHeimdall bool, datadir string, snapshots *snapshotsync.RoSnapshots, readonly bool, chainDb ...kv.RwDB) consensus.Engine { var eng consensus.Engine switch consensusCfg := config.(type) { - case *ethash.Config: + case *ethashcfg.Config: switch consensusCfg.PowMode { - case ethash.ModeFake: + case ethashcfg.ModeFake: log.Warn("Ethash used in fake mode") eng = ethash.NewFaker() - case ethash.ModeTest: + case ethashcfg.ModeTest: log.Warn("Ethash used in test mode") eng = ethash.NewTester(nil, noverify) - case ethash.ModeShared: + case ethashcfg.ModeShared: log.Warn("Ethash used in shared mode") eng = ethash.NewShared() default: - eng = ethash.New(ethash.Config{ + eng = ethash.New(ethashcfg.Config{ CachesInMem: consensusCfg.CachesInMem, CachesLockMmap: consensusCfg.CachesLockMmap, DatasetDir: consensusCfg.DatasetDir, @@ -56,15 +56,13 @@ func CreateConsensusEngine(chainConfig *chain.Config, logger log.Logger, config if consensusCfg.DBPath == "" { consensusCfg.DBPath = filepath.Join(datadir, "clique", "db") } - eng = clique.New(chainConfig, consensusCfg, db.OpenDatabase(consensusCfg.DBPath, logger, consensusCfg.InMemory, readonly)) + eng = clique.New(chainConfig, consensusCfg, db.OpenDatabase(consensusCfg.DBPath, consensusCfg.InMemory, readonly)) } case *chain.AuRaConfig: if chainConfig.Aura != nil { - if consensusCfg.DBPath == "" { - consensusCfg.DBPath = filepath.Join(datadir, "aura") - } + dbPath := filepath.Join(datadir, "aura") var err error - eng, err = aura.NewAuRa(chainConfig.Aura, db.OpenDatabase(consensusCfg.DBPath, logger, consensusCfg.InMemory, readonly), chainConfig.Aura.Etherbase, consensusconfig.GetConfigByChain(chainConfig.ChainName)) + eng, err = aura.NewAuRa(chainConfig.Aura, db.OpenDatabase(dbPath, false, readonly)) if err != nil { panic(err) } @@ -74,7 +72,7 @@ func CreateConsensusEngine(chainConfig *chain.Config, logger log.Logger, config if consensusCfg.DBPath == "" { consensusCfg.DBPath = filepath.Join(datadir, "parlia") } - eng = parlia.New(chainConfig, db.OpenDatabase(consensusCfg.DBPath, logger, consensusCfg.InMemory, readonly), snapshots, chainDb[0]) + eng = parlia.New(chainConfig, db.OpenDatabase(consensusCfg.DBPath, consensusCfg.InMemory, readonly), snapshots, chainDb[0]) } case *chain.BorConfig: // If Matic bor consensus is requested, set it up @@ -84,7 +82,7 @@ func CreateConsensusEngine(chainConfig *chain.Config, logger log.Logger, config genesisContractsClient := contract.NewGenesisContractsClient(chainConfig, chainConfig.Bor.ValidatorContract, chainConfig.Bor.StateReceiverContract) spanner := span.NewChainSpanner(contract.ValidatorSet(), chainConfig) borDbPath := filepath.Join(datadir, "bor") // bor consensus path: datadir/bor - db := db.OpenDatabase(borDbPath, logger, false, readonly) + db := db.OpenDatabase(borDbPath, false, readonly) var heimdallClient bor.IHeimdallClient if WithoutHeimdall { diff --git a/eth/gasprice/feehistory.go b/eth/gasprice/feehistory.go index 246f00a0440..c2a31cf86aa 100644 --- a/eth/gasprice/feehistory.go +++ b/eth/gasprice/feehistory.go @@ -135,42 +135,66 @@ 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, maxHistory int) (*types.Block, []*types.Receipt, uint64, int, error) { +func (oracle *Oracle) resolveBlockRange(ctx context.Context, reqEnd rpc.BlockNumber, blocks, maxHistory 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 { - 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 } + if maxHistory != 0 { // limit retrieval to the given number of latest blocks - if tooOldCount := int64(headBlock) - int64(maxHistory) - int64(lastBlock) + int64(blocks); tooOldCount > 0 { + if tooOldCount := int64(headBlock.Number.Uint64()) - int64(maxHistory) - int64(reqEnd) + int64(blocks); tooOldCount > 0 { // tooOldCount is the number of requested blocks that are too old to be served if int64(blocks) > tooOldCount { blocks -= int(tooOldCount) @@ -180,10 +204,10 @@ func (oracle *Oracle) resolveBlockRange(ctx context.Context, lastBlock rpc.Block } } // ensure not trying to retrieve before genesis - if rpc.BlockNumber(blocks) > lastBlock+1 { - blocks = int(lastBlock + 1) + if rpc.BlockNumber(blocks) > reqEnd+1 { + 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/stagedsync/README.md b/eth/stagedsync/README.md index c0ff154ed5b..e2c0ba436a2 100644 --- a/eth/stagedsync/README.md +++ b/eth/stagedsync/README.md @@ -71,7 +71,11 @@ Most of the stages can work offline though it isn't implemented in the current v We can add/remove stages, so exact stage numbers may change - but order and names stay the same. -### Stage 1: [Download Headers Stage](/eth/stagedsync/stage_headers.go) +### Stage 1: [Snapshots](/eth/stagedsync/stage_snapshots.go) + +Download Snapshots + +### Stage 2: [Download Headers Stage](/eth/stagedsync/stage_headers.go) During this stage we download all the headers between the local HEAD and our peer's head. @@ -81,17 +85,21 @@ Most of the unwinds are initiated on this stage due to the chain reorgs. This stage promotes local HEAD pointer. -### Stage 2: [Block Hashes](/eth/stagedsync/stage_blockhashes.go) +### Stage 3: [Cumulative Index](/eth/stagedsync/stage_cumulative_index.go) + +Calculate how much gas has been used up to each block. + +### Stage 4: [Block Hashes](/eth/stagedsync/stage_blockhashes.go) Creates an index of blockHash -> blockNumber extracted from the headers for faster lookups and making the sync friendlier for HDDs. -### Stage 4: [Download Block Bodies Stage](/eth/stagedsync/stage_bodies.go) +### Stage 5: [Download Block Bodies Stage](/eth/stagedsync/stage_bodies.go) At that stage, we download bodies for block headers that we already downloaded. That is the most intensive stage for the network connection, the vast majority of data is downloaded here. -### Stage 5: [Recover Senders Stage](/eth/stagedsync/stage_senders.go) +### Stage 6: [Recover Senders Stage](/eth/stagedsync/stage_senders.go) This stage recovers and stores senders for each transaction in each downloaded block. @@ -99,7 +107,7 @@ This is also a CPU intensive stage and also benefits from multi-core CPUs. This stage doesn't use any network connection. -### Stage 6: [Execute Blocks Stage](/eth/stagedsync/stage_execute.go) +### Stage 7: [Execute Blocks Stage](/eth/stagedsync/stage_execute.go) During this stage, we execute block-by-block everything that we downloaded before. @@ -113,23 +121,16 @@ This stage is disk intensive. This stage can spawn unwinds if the block execution fails. -### Stage 7: [Transpile marked VM contracts to TEVM](/eth/stagedsync/stage_tevm.go) - -[TODO] - -### Stage 8: [Generate Hashed State Stage](/eth/stagedsync/stage_hashstate.go) +### Stage 8: [Transpile marked VM contracts to TEVM](/eth/stagedsync/stage_tevm.go) -Erigon during execution uses Plain state storage. +Translation each marked for translation contract (from EVM to TEVM) -> Plain State: Instead of the normal (we call it "Hashed State") where accounts and storage items are addressed as `keccak256(address)`, in the plain state them are addressed by the `address` itself. -Though, to make sure that some APIs work and keep the compatibility with the other clients, we generate Hashed state as well. +### Stage 9: [VerkleTrie](/eth/stagedsync/stage_verkle_trie.go) -If the hashed state is not empty, then we are looking at the History ChangeSets and update only the items that were changed. - -This stage doesn't use a network connection. +[TODO] -### Stage 9: [Compute State Root Stage](/eth/stagedsync/stage_interhashes.go) +### Stage 10: [Compute State Root Stage](/eth/stagedsync/stage_interhashes.go) This stage build the Merkle trie and checks the root hash for the current state. @@ -143,13 +144,22 @@ If the root hash doesn't match, it initiates an unwind one block backwards. This stage doesn't use a network connection. -### Stage 10: [Generate call traces index](/eth/stagedsync/stage_call_traces.go) +### Stage 11: [Generate Hashed State Stage](/eth/stagedsync/stage_hashstate.go) + +Erigon during execution uses Plain state storage. + +> Plain State: Instead of the normal (we call it "Hashed State") where accounts and storage items are addressed as `keccak256(address)`, in the plain state them are addressed by the `address` itself. + +Though, to make sure that some APIs work and keep the compatibility with the other clients, we generate Hashed state as well. + +If the hashed state is not empty, then we are looking at the History ChangeSets and update only the items that were changed. + +This stage doesn't use a network connection. -[TODO] -### Stages [11, 12](/eth/stagedsync/stage_indexes.go), [13](/eth/stagedsync/stage_log_index.go), and [14](/eth/stagedsync/stage_txlookup.go): Generate Indexes +### Stages [12, 13](/eth/stagedsync/stage_indexes.go), [14](/eth/stagedsync/stage_log_index.go), [15](/eth/stagedsync/stage_call_traces.go) and [16](/eth/stagedsync/stage_txlookup.go): Generate Indexes -There are 4 indexes that are generated during sync. +There are 5 indexes that are generated during sync. They might be disabled because they aren't used for all the APIs. @@ -167,11 +177,15 @@ This index stores the mapping from the storage item address to the list of block This index sets up a link from the [TODO] to [TODO]. +**Call traces index** + +[TODO] + **Tx Lookup Index** This index sets up a link from the transaction hash to the block number. -### Stage 15: [Transaction Pool Stage](/eth/stagedsync/stage_txpool.go) +### Stage 16: [Transaction Pool Stage](/eth/stagedsync/stage_txpool.go) During this stage we start the transaction pool or update its state. For instance, we remove the transactions from the blocks we have downloaded from the pool. @@ -179,6 +193,6 @@ On unwinds, we add the transactions from the blocks we unwind, back to the pool. This stage doesn't use a network connection. -### Stage 16: Finish +### Stage 17: Finish This stage sets the current block number that is then used by [RPC calls](../../cmd/rpcdaemon/README.md), such as [`eth_blockNumber`](../../README.md). diff --git a/eth/stagedsync/exec3.go b/eth/stagedsync/exec3.go index c9c96745b4a..93ec7604a7a 100644 --- a/eth/stagedsync/exec3.go +++ b/eth/stagedsync/exec3.go @@ -2,7 +2,6 @@ package stagedsync import ( "bytes" - "container/heap" "context" "encoding/binary" "errors" @@ -11,6 +10,7 @@ import ( "path/filepath" "runtime" "sync" + "sync/atomic" "time" "github.com/VictoriaMetrics/metrics" @@ -26,13 +26,14 @@ import ( "github.com/ledgerwatch/erigon-lib/kv/rawdbv3" libstate "github.com/ledgerwatch/erigon-lib/state" state2 "github.com/ledgerwatch/erigon-lib/state" + "github.com/ledgerwatch/erigon/common/math" + "github.com/ledgerwatch/erigon/core/state/temporal" "github.com/ledgerwatch/log/v3" "github.com/torquem-ch/mdbx-go/mdbx" - atomic2 "go.uber.org/atomic" + "golang.org/x/sync/errgroup" "github.com/ledgerwatch/erigon/cmd/state/exec22" "github.com/ledgerwatch/erigon/cmd/state/exec3" - "github.com/ledgerwatch/erigon/common/math" "github.com/ledgerwatch/erigon/consensus" "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/core/rawdb" @@ -46,6 +47,8 @@ import ( ) var ExecStepsInDB = metrics.NewCounter(`exec_steps_in_db`) //nolint +var ExecRepeats = metrics.NewCounter(`exec_repeats`) //nolint +var ExecTriggers = metrics.NewCounter(`exec_triggers`) //nolint func NewProgress(prevOutputBlockNum, commitThreshold uint64, workersCount int, logPrefix string) *Progress { return &Progress{prevTime: time.Now(), prevOutputBlockNum: prevOutputBlockNum, commitThreshold: commitThreshold, workersCount: workersCount, logPrefix: logPrefix} @@ -62,12 +65,11 @@ type Progress struct { logPrefix string } -func (p *Progress) Log(rs *state.StateV3, rwsLen int, queueSize, doneCount, inputBlockNum, outputBlockNum, outTxNum, repeatCount uint64, resultsSize uint64, resultCh chan *exec22.TxTask, idxStepsAmountInDB float64) { +func (p *Progress) Log(rs *state.StateV3, in *exec22.QueueWithRetry, rws *exec22.ResultsQueue, doneCount, inputBlockNum, outputBlockNum, outTxNum, repeatCount uint64, idxStepsAmountInDB float64) { ExecStepsInDB.Set(uint64(idxStepsAmountInDB * 100)) var m runtime.MemStats dbg.ReadMemStats(&m) sizeEstimate := rs.SizeEstimate() - queueLen := rs.QueueLen() currentTime := time.Now() interval := currentTime.Sub(p.prevTime) speedTx := float64(doneCount-p.prevCount) / (float64(interval) / float64(time.Second)) @@ -81,13 +83,12 @@ func (p *Progress) Log(rs *state.StateV3, rwsLen int, queueSize, doneCount, inpu "blk", outputBlockNum, //"blk/s", fmt.Sprintf("%.1f", speedBlock), "tx/s", fmt.Sprintf("%.1f", speedTx), - "pipe", fmt.Sprintf("%d/%d->%d/%d->%d/%d", queueLen, queueSize, rwsLen, queueSize, len(resultCh), cap(resultCh)), - "resultsSize", common.ByteCount(resultsSize), + "pipe", fmt.Sprintf("(%d+%d)->%d/%d->%d/%d", in.NewTasksLen(), in.RetriesLen(), rws.ResultChLen(), rws.ResultChCap(), rws.Len(), rws.Limit()), "repeatRatio", fmt.Sprintf("%.2f%%", repeatRatio), "workers", p.workersCount, "buffer", fmt.Sprintf("%s/%s", common.ByteCount(sizeEstimate), common.ByteCount(p.commitThreshold)), "idxStepsInDB", fmt.Sprintf("%.2f", idxStepsAmountInDB), - "inBlk", inputBlockNum, + //"inBlk", inputBlockNum, "step", fmt.Sprintf("%.1f", float64(outTxNum)/float64(ethconfig.HistoryV3AggregationStep)), "alloc", common.ByteCount(m.Alloc), "sys", common.ByteCount(m.Sys), ) @@ -106,11 +107,16 @@ func (p *Progress) Log(rs *state.StateV3, rwsLen int, queueSize, doneCount, inpu func ExecV3(ctx context.Context, execStage *StageState, u Unwinder, workerCount int, cfg ExecuteBlockCfg, applyTx kv.RwTx, - parallel bool, rs *state.StateV3, logPrefix string, - logger log.Logger, + parallel bool, logPrefix string, maxBlockNum uint64, ) error { - batchSize, chainDb := cfg.batchSize, cfg.db + batchSize := cfg.batchSize + chainDb := cfg.db + //TODO: re-think - how it must work + if casted, ok := chainDb.(*temporal.DB); ok { + chainDb = casted.InternalDB() + } + blockReader := cfg.blockReader agg, engine := cfg.agg, cfg.engine chainConfig, genesis := cfg.chainConfig, cfg.genesis @@ -132,7 +138,10 @@ func ExecV3(ctx context.Context, var block, stageProgress uint64 var maxTxNum uint64 - var outputTxNum = atomic2.NewUint64(0) + outputTxNum := atomic.Uint64{} + blockComplete := atomic.Bool{} + blockComplete.Store(true) + var inputTxNum uint64 if execStage.BlockNumber > 0 { stageProgress = execStage.BlockNumber @@ -157,7 +166,7 @@ func ExecV3(ctx context.Context, return err } outputTxNum.Store(_outputTxNum) - outputTxNum.Inc() + outputTxNum.Add(1) inputTxNum = outputTxNum.Load() } } else { @@ -173,7 +182,7 @@ func ExecV3(ctx context.Context, return err } outputTxNum.Store(_outputTxNum) - outputTxNum.Inc() + outputTxNum.Add(1) inputTxNum = outputTxNum.Load() } return nil @@ -184,24 +193,28 @@ func ExecV3(ctx context.Context, agg.SetTxNum(inputTxNum) var outputBlockNum = syncMetrics[stages.Execution] - var inputBlockNum = atomic2.NewUint64(0) + inputBlockNum := &atomic.Uint64{} var count uint64 - var repeatCount, triggerCount = atomic2.NewUint64(0), atomic2.NewUint64(0) - var resultsSize = atomic2.NewInt64(0) var lock sync.RWMutex - queueSize := workerCount // workerCount * 4 // when wait cond can be moved inside txs loop - execWorkers, applyWorker, resultCh, stopWorkers, waitWorkers := exec3.NewWorkersPool(lock.RLocker(), ctx, parallel, chainDb, rs, blockReader, chainConfig, logger, genesis, engine, workerCount+1) + rs := state.NewStateV3(cfg.dirs.Tmp) + + //TODO: owner of `resultCh` is main goroutine, but owner of `retryQueue` is applyLoop. + // Now rwLoop closing both (because applyLoop we completely restart) + // Maybe need split channels? Maybe don't exit from ApplyLoop? Maybe current way is also ok? + + // input queue + in := exec22.NewQueueWithRetry(100_000) + defer in.Close() + + rwsConsumed := make(chan struct{}, 1) + defer close(rwsConsumed) + + execWorkers, applyWorker, rws, stopWorkers, waitWorkers := exec3.NewWorkersPool(lock.RLocker(), ctx, parallel, chainDb, rs, in, blockReader, chainConfig, genesis, engine, workerCount+1) defer stopWorkers() applyWorker.DiscardReadList() - rws := &exec22.TxTaskQueue{} - heap.Init(rws) - var rwsLock sync.Mutex - rwsReceiveCond := sync.NewCond(&rwsLock) - commitThreshold := batchSize.Bytes() - resultsThreshold := int64(batchSize.Bytes()) progress := NewProgress(block, commitThreshold, workerCount, execStage.LogPrefix()) logEvery := time.NewTicker(20 * time.Second) defer logEvery.Stop() @@ -220,61 +233,31 @@ func ExecV3(ctx context.Context, applyWorker.ResetTx(tx) - notifyReceived := func() { rwsReceiveCond.Signal() } - var t time.Time var lastBlockNum uint64 - drainF := func(txTask *exec22.TxTask) (added int64) { - rwsLock.Lock() - defer rwsLock.Unlock() - added += txTask.ResultsSize - heap.Push(rws, txTask) - - for { - select { - case txTask, ok := <-resultCh: - if !ok { - return added - } - added += txTask.ResultsSize - heap.Push(rws, txTask) - default: // we are inside mutex section, can't block here - return added - } - } - } for outputTxNum.Load() <= maxTxNum { - select { - case <-ctx.Done(): - return ctx.Err() - case txTask, ok := <-resultCh: - if !ok { - return nil - } - added := drainF(txTask) - resultsSize.Add(added) + if err := rws.Drain(ctx); err != nil { + return err } - processedResultSize, processedTxNum, conflicts, processedBlockNum, err := func() (processedResultSize int64, processedTxNum, conflicts, processedBlockNum uint64, err error) { - rwsLock.Lock() - defer rwsLock.Unlock() - return processResultQueue(rws, outputTxNum.Load(), rs, agg, tx, triggerCount, notifyReceived, applyWorker) + processedTxNum, conflicts, triggers, processedBlockNum, stoppedAtBlockEnd, err := func() (processedTxNum uint64, conflicts, triggers int, processedBlockNum uint64, stopedAtBlockEnd bool, err error) { + it := rws.Iter() + defer it.Close() + return processResultQueue(in, it, outputTxNum.Load(), rs, agg, tx, rwsConsumed, applyWorker, true, false) }() if err != nil { return err } - resultsSize.Add(-processedResultSize) - repeatCount.Add(conflicts) + + ExecRepeats.Add(conflicts) + ExecTriggers.Add(triggers) if processedBlockNum > lastBlockNum { outputBlockNum.Set(processedBlockNum) - if lastBlockNum > 0 { - core.BlockExecutionTimer.UpdateDuration(t) - } lastBlockNum = processedBlockNum - t = time.Now() } if processedTxNum > 0 { outputTxNum.Store(processedTxNum) + blockComplete.Store(stoppedAtBlockEnd) } } @@ -291,7 +274,7 @@ func ExecV3(ctx context.Context, var rwLoopErrCh chan error - var rwLoopWg sync.WaitGroup + var rwLoopG *errgroup.Group if parallel { // `rwLoop` lives longer than `applyLoop` rwLoop := func(ctx context.Context) error { @@ -319,29 +302,25 @@ func ExecV3(ctx context.Context, return ctx.Err() case <-logEvery.C: - rwsLock.Lock() - rwsLen := rws.Len() - rwsLock.Unlock() + if list := agg.SlowContextsList(); len(list) > 0 { + log.Info("[dbg] Active agg ctx", "list", list) + } stepsInDB := rawdbhelpers.IdxStepsCountV3(tx) - progress.Log(rs, rwsLen, uint64(queueSize), rs.DoneCount(), inputBlockNum.Load(), outputBlockNum.Get(), outputTxNum.Load(), repeatCount.Load(), uint64(resultsSize.Load()), resultCh, stepsInDB) + progress.Log(rs, in, rws, rs.DoneCount(), inputBlockNum.Load(), outputBlockNum.Get(), outputTxNum.Load(), ExecRepeats.Get(), stepsInDB) + if agg.HasBackgroundFilesBuild() { + log.Info(fmt.Sprintf("[%s] Background files build", logPrefix), "progress", agg.BackgroundProgress()) + } case <-pruneEvery.C: if rs.SizeEstimate() < commitThreshold { - // too much steps in db will slow-down everything: flush and prune - // it means better spend time for pruning, before flushing more data to db - // also better do it now - instead of before Commit() - because Commit does block execution - stepsInDB := rawdbhelpers.IdxStepsCountV3(tx) - if stepsInDB > 5 && rs.SizeEstimate() < uint64(float64(commitThreshold)*0.2) { - if err = agg.Prune(ctx, ethconfig.HistoryV3AggregationStep*2); err != nil { // prune part of retired data, before commit - panic(err) + if agg.CanPrune(tx) { + if err = agg.Prune(ctx, ethconfig.HistoryV3AggregationStep*10); err != nil { // prune part of retired data, before commit + return err + } + } else { + if err = agg.Flush(ctx, tx); err != nil { + return err } - } - - if err = agg.Flush(ctx, tx); err != nil { - return err - } - if err = agg.PruneWithTiemout(ctx, 1*time.Second); err != nil { - return err } break } @@ -349,68 +328,51 @@ func ExecV3(ctx context.Context, cancelApplyCtx() applyLoopWg.Wait() - var t1, t2, t3, t4 time.Duration + var t0, t1, t2, t3, t4 time.Duration commitStart := time.Now() - log.Info("Committing...") + log.Info("Committing...", "blockComplete.Load()", blockComplete.Load()) if err := func() error { - rwsLock.Lock() - defer rwsLock.Unlock() - // Drain results (and process) channel because read sets do not carry over - for { - var drained bool - for !drained { - select { - case txTask, ok := <-resultCh: - if !ok { - return nil - } - resultsSize.Add(txTask.ResultsSize) - heap.Push(rws, txTask) - default: - drained = true - } - } + //Drain results (and process) channel because read sets do not carry over + for !blockComplete.Load() { + rws.DrainNonBlocking() applyWorker.ResetTx(tx) - processedResultSize, processedTxNum, conflicts, processedBlockNum, err := processResultQueue(rws, outputTxNum.Load(), rs, agg, tx, triggerCount, func() {}, applyWorker) + + resIt := rws.Iter() + processedTxNum, conflicts, triggers, processedBlockNum, stoppedAtBlockEnd, err := processResultQueue(in, resIt, outputTxNum.Load(), rs, agg, tx, nil, applyWorker, false, true) if err != nil { return err } - resultsSize.Add(-processedResultSize) - repeatCount.Add(conflicts) + resIt.Close() //TODO: in defer + + ExecRepeats.Add(conflicts) + ExecTriggers.Add(triggers) if processedBlockNum > 0 { outputBlockNum.Set(processedBlockNum) } if processedTxNum > 0 { outputTxNum.Store(processedTxNum) - } - - if rws.Len() == 0 { - break + blockComplete.Store(stoppedAtBlockEnd) } } - rwsReceiveCond.Signal() + t0 = time.Since(commitStart) lock.Lock() // This is to prevent workers from starting work on any new txTask defer lock.Unlock() - DrainLoop: // Drain results channel because read sets do not carry over - for { - select { - case txTask, ok := <-resultCh: - if !ok { - return nil - } - rs.AddWork(txTask) - default: - break DrainLoop - } + select { + case rwsConsumed <- struct{}{}: + default: } - // Drain results queue as well - for rws.Len() > 0 { - txTask := heap.Pop(rws).(*exec22.TxTask) - resultsSize.Add(-txTask.ResultsSize) - rs.AddWork(txTask) - } + // Drain results channel because read sets do not carry over + rws.DropResults(func(txTask *exec22.TxTask) { + rs.ReTry(txTask, in) + }) + + //lastTxNumInDb, _ := rawdbv3.TxNums.Max(tx, outputBlockNum.Get()) + //if lastTxNumInDb != outputTxNum.Load()-1 { + // panic(fmt.Sprintf("assert: %d != %d", lastTxNumInDb, outputTxNum.Load())) + //} + t1 = time.Since(commitStart) tt := time.Now() if err := rs.Flush(ctx, tx, logPrefix, logEvery); err != nil { @@ -453,7 +415,7 @@ func ExecV3(ctx context.Context, applyLoopWg.Add(1) go applyLoop(applyCtx, rwLoopErrCh) - log.Info("Committed", "time", time.Since(commitStart), "drain", t1, "rs.flush", t2, "agg.flush", t3, "tx.commit", t4) + log.Info("Committed", "time", time.Since(commitStart), "drain", t0, "drain_and_lock", t1, "rs.flush", t2, "agg.flush", t3, "tx.commit", t4) } } if err = rs.Flush(ctx, tx, logPrefix, logEvery); err != nil { @@ -465,32 +427,22 @@ func ExecV3(ctx context.Context, if err = execStage.Update(tx, outputBlockNum.Get()); err != nil { return err } - //if err = execStage.Update(tx, stageProgress); err != nil { - // panic(err) - //} if err = tx.Commit(); err != nil { return err } return nil } - rwLoopErrCh = make(chan error, 1) - - defer rwLoopWg.Wait() - rwLoopCtx, rwLoopCancel := context.WithCancel(ctx) - defer rwLoopCancel() - rwLoopWg.Add(1) - go func() { - defer close(rwLoopErrCh) - defer rwLoopWg.Done() - + rwLoopCtx, rwLoopCtxCancel := context.WithCancel(ctx) + defer rwLoopCtxCancel() + rwLoopG, rwLoopCtx = errgroup.WithContext(rwLoopCtx) + defer rwLoopG.Wait() + rwLoopG.Go(func() error { + defer rws.Close() + defer in.Close() defer applyLoopWg.Wait() - defer rs.Finish() - - if err := rwLoop(rwLoopCtx); err != nil { - rwLoopErrCh <- err - } - }() + return rwLoop(rwLoopCtx) + }) } if block < blockSnapshots.BlocksAvailable() { @@ -526,6 +478,9 @@ func ExecV3(ctx context.Context, _, isPoSa := cfg.engine.(consensus.PoSA) //isBor := cfg.chainConfig.Bor != nil + slowDownLimit := time.NewTicker(time.Second) + defer slowDownLimit.Stop() + var b *types.Block var blockNum uint64 var err error @@ -537,7 +492,7 @@ Loop: return err } if b == nil { - // TODO: panic here and see that overall prodcess deadlock + // TODO: panic here and see that overall process deadlock return fmt.Errorf("nil block %d", blockNum) } txs := b.Transactions() @@ -552,7 +507,7 @@ Loop: defer getHashFnMute.Unlock() return f(n) } - blockContext := core.NewEVMBlockContext(header, getHashFn, engine, nil /* author */) + blockContext := core.NewEVMBlockContext(header, getHashFn, engine, nil /* author */, nil /*excessDataGas*/) if parallel { select { @@ -560,23 +515,27 @@ Loop: if err != nil { return err } + case <-ctx.Done(): + return ctx.Err() default: } func() { - needWait := rs.QueueLen() > queueSize - if !needWait { - return - } - rwsLock.Lock() - defer rwsLock.Unlock() - for rs.QueueLen() > queueSize || rws.Len() > queueSize || resultsSize.Load() >= resultsThreshold || rs.SizeEstimate() >= commitThreshold { + for rws.Len() > rws.Limit() || rs.SizeEstimate() >= commitThreshold { select { case <-ctx.Done(): return - default: + case _, ok := <-rwsConsumed: + if !ok { + return + } + case <-slowDownLimit.C: + //log.Warn("skip", "rws.Len()", rws.Len(), "rws.Limit()", rws.Limit(), "rws.ResultChLen()", rws.ResultChLen()) + //if tt := rws.Dbg(); tt != nil { + // log.Warn("fst", "n", tt.TxNum, "in.len()", in.Len(), "out", outputTxNum.Load(), "in.NewTasksLen", in.NewTasksLen()) + //} + return } - rwsReceiveCond.Wait() } }() } @@ -606,7 +565,7 @@ Loop: txTask.Tx = txs[txIndex] txTask.TxAsMessage, err = txTask.Tx.AsMessage(signer, header.BaseFee, txTask.Rules) if err != nil { - panic(err) + return err } if sender, ok := txs[txIndex].GetSender(); ok { @@ -624,10 +583,10 @@ Loop: if parallel { if txTask.TxIndex >= 0 && txTask.TxIndex < len(txs) { if ok := rs.RegisterSender(txTask); ok { - rs.AddWork(txTask) + rs.AddWork(ctx, txTask, in) } } else { - rs.AddWork(txTask) + rs.AddWork(ctx, txTask, in) } } else { count++ @@ -664,8 +623,8 @@ Loop: if err := rs.ApplyState(applyTx, txTask, agg); err != nil { return fmt.Errorf("StateV3.Apply: %w", err) } - triggerCount.Add(rs.CommitTxNum(txTask.Sender, txTask.TxNum)) - outputTxNum.Inc() + ExecTriggers.Add(rs.CommitTxNum(txTask.Sender, txTask.TxNum, in)) + outputTxNum.Add(1) if err := rs.ApplyHistory(txTask, agg); err != nil { return fmt.Errorf("StateV3.Apply: %w", err) @@ -681,7 +640,7 @@ Loop: select { case <-logEvery.C: stepsInDB := rawdbhelpers.IdxStepsCountV3(applyTx) - progress.Log(rs, rws.Len(), uint64(queueSize), count, inputBlockNum.Load(), outputBlockNum.Get(), outputTxNum.Load(), repeatCount.Load(), uint64(resultsSize.Load()), resultCh, stepsInDB) + progress.Log(rs, in, rws, count, inputBlockNum.Load(), outputBlockNum.Get(), outputTxNum.Load(), ExecRepeats.Get(), stepsInDB) if rs.SizeEstimate() < commitThreshold { break } @@ -718,7 +677,7 @@ Loop: } if blockSnapshots.Cfg().Produce { - agg.BuildFilesInBackground() + agg.BuildFilesInBackground(outputTxNum.Load()) } select { case <-ctx.Done(): @@ -728,10 +687,9 @@ Loop: } if parallel { - if err := <-rwLoopErrCh; err != nil { + if err := rwLoopG.Wait(); err != nil { return err } - rwLoopWg.Wait() waitWorkers() } else { if err = rs.Flush(ctx, applyTx, logPrefix, logEvery); err != nil { @@ -746,7 +704,7 @@ Loop: } if blockSnapshots.Cfg().Produce { - agg.BuildFilesInBackground() + agg.BuildFilesInBackground(outputTxNum.Load()) } if !useExternalTx && applyTx != nil { @@ -775,48 +733,56 @@ func blockWithSenders(db kv.RoDB, tx kv.Tx, blockReader services.BlockReader, bl return b, nil } -func processResultQueue(rws *exec22.TxTaskQueue, outputTxNumIn uint64, rs *state.StateV3, agg *state2.AggregatorV3, applyTx kv.Tx, triggerCount *atomic2.Uint64, onSuccess func(), applyWorker *exec3.Worker) (resultSize int64, outputTxNum, conflicts, processedBlockNum uint64, err error) { +func processResultQueue(in *exec22.QueueWithRetry, rws *exec22.ResultsQueueIter, outputTxNumIn uint64, rs *state.StateV3, agg *state2.AggregatorV3, applyTx kv.Tx, backPressure chan struct{}, applyWorker *exec3.Worker, canRetry, forceStopAtBlockEnd bool) (outputTxNum uint64, conflicts, triggers int, processedBlockNum uint64, stopedAtBlockEnd bool, err error) { var i int outputTxNum = outputTxNumIn - for rws.Len() > 0 && (*rws)[0].TxNum == outputTxNum { - txTask := heap.Pop(rws).(*exec22.TxTask) - resultSize += txTask.ResultsSize + for rws.HasNext(outputTxNum) { + txTask := rws.PopNext() if txTask.Error != nil || !rs.ReadsValid(txTask.ReadLists) { conflicts++ - if i > 0 { + if i > 0 && canRetry { //send to re-exex - rs.AddWork(txTask) + rs.ReTry(txTask, in) continue } // resolve first conflict right here: it's faster and conflict-free applyWorker.RunTxTask(txTask) if txTask.Error != nil { - return resultSize, outputTxNum, conflicts, processedBlockNum, txTask.Error + return outputTxNum, conflicts, triggers, processedBlockNum, false, txTask.Error } i++ } if err := rs.ApplyState(applyTx, txTask, agg); err != nil { - return resultSize, outputTxNum, conflicts, processedBlockNum, fmt.Errorf("StateV3.Apply: %w", err) + return outputTxNum, conflicts, triggers, processedBlockNum, false, fmt.Errorf("StateV3.Apply: %w", err) } - triggerCount.Add(rs.CommitTxNum(txTask.Sender, txTask.TxNum)) + triggers += rs.CommitTxNum(txTask.Sender, txTask.TxNum, in) outputTxNum++ - onSuccess() + if backPressure != nil { + select { + case backPressure <- struct{}{}: + default: + } + } if err := rs.ApplyHistory(txTask, agg); err != nil { - return resultSize, outputTxNum, conflicts, processedBlockNum, fmt.Errorf("StateV3.Apply: %w", err) + return outputTxNum, conflicts, triggers, processedBlockNum, false, fmt.Errorf("StateV3.Apply: %w", err) } //fmt.Printf("Applied %d block %d txIndex %d\n", txTask.TxNum, txTask.BlockNum, txTask.TxIndex) processedBlockNum = txTask.BlockNum + stopedAtBlockEnd = txTask.Final + if forceStopAtBlockEnd && txTask.Final { + break + } } - return resultSize, outputTxNum, conflicts, processedBlockNum, nil + return } func reconstituteStep(last bool, workerCount int, ctx context.Context, db kv.RwDB, txNum uint64, dirs datadir.Dirs, as *libstate.AggregatorStep, chainDb kv.RwDB, blockReader services.FullBlockReader, - chainConfig *chain.Config, logger log.Logger, genesis *core.Genesis, engine consensus.Engine, + chainConfig *chain.Config, logger log.Logger, genesis *types.Genesis, engine consensus.Engine, batchSize datasize.ByteSize, s *StageState, blockNum uint64, total uint64, ) error { var startOk, endOk bool @@ -856,8 +822,6 @@ func reconstituteStep(last bool, var maxTxNum = startTxNum - workCh := make(chan *exec22.TxTask, workerCount*4) - rs := state.NewReconState(workCh) scanWorker := exec3.NewScanWorker(txNum, as) t := time.Now() @@ -885,7 +849,6 @@ func reconstituteStep(last bool, } bitmap := scanWorker.Bitmap() - var wg sync.WaitGroup logEvery := time.NewTicker(logInterval) defer logEvery.Stop() @@ -913,6 +876,16 @@ func reconstituteStep(last bool, return err } } + g, reconstWorkersCtx := errgroup.WithContext(ctx) + defer g.Wait() + workCh := make(chan *exec22.TxTask, workerCount*4) + defer func() { + fmt.Printf("close1\n") + safeCloseTxTaskCh(workCh) + }() + + rs := state.NewReconState(workCh) + prevCount := rs.DoneCount() for i := 0; i < workerCount; i++ { var localAs *libstate.AggregatorStep if i == 0 { @@ -920,27 +893,56 @@ func reconstituteStep(last bool, } else { localAs = as.Clone() } - reconWorkers[i] = exec3.NewReconWorker(lock.RLocker(), &wg, rs, localAs, blockReader, chainConfig, logger, genesis, engine, chainTxs[i]) + reconWorkers[i] = exec3.NewReconWorker(lock.RLocker(), reconstWorkersCtx, rs, localAs, blockReader, chainConfig, logger, genesis, engine, chainTxs[i]) reconWorkers[i].SetTx(roTxs[i]) reconWorkers[i].SetChainTx(chainTxs[i]) } - wg.Add(workerCount) rollbackCount := uint64(0) - prevCount := rs.DoneCount() + for i := 0; i < workerCount; i++ { - go reconWorkers[i].Run() + i := i + g.Go(func() error { return reconWorkers[i].Run() }) } commitThreshold := batchSize.Bytes() prevRollbackCount := uint64(0) prevTime := time.Now() - reconDone := make(chan struct{}) - //var bn uint64 - go func() { + reconDone := make(chan struct{}, 1) + + defer close(reconDone) + + commit := func(ctx context.Context) error { + t := time.Now() + lock.Lock() + defer lock.Unlock() + for i := 0; i < workerCount; i++ { + roTxs[i].Rollback() + } + if err := db.Update(ctx, func(tx kv.RwTx) error { + if err := rs.Flush(tx); err != nil { + return err + } + return nil + }); err != nil { + return err + } + for i := 0; i < workerCount; i++ { + var err error + if roTxs[i], err = db.BeginRo(ctx); err != nil { + return err + } + reconWorkers[i].SetTx(roTxs[i]) + } + log.Info(fmt.Sprintf("[%s] State reconstitution, commit", s.LogPrefix()), "took", time.Since(t)) + return nil + } + g.Go(func() error { for { select { - case <-reconDone: - return + case <-reconDone: // success finish path + return nil + case <-reconstWorkersCtx.Done(): // force-stop path + return reconstWorkersCtx.Err() case <-logEvery.C: var m runtime.MemStats dbg.ReadMemStats(&m) @@ -967,37 +969,13 @@ func reconstituteStep(last bool, "buffer", fmt.Sprintf("%s/%s", common.ByteCount(sizeEstimate), common.ByteCount(commitThreshold)), "alloc", common.ByteCount(m.Alloc), "sys", common.ByteCount(m.Sys)) if sizeEstimate >= commitThreshold { - t := time.Now() - if err := func() error { - lock.Lock() - defer lock.Unlock() - for i := 0; i < workerCount; i++ { - roTxs[i].Rollback() - } - if err := db.Update(ctx, func(tx kv.RwTx) error { - if err := rs.Flush(tx); err != nil { - return err - } - return nil - }); err != nil { - return err - } - for i := 0; i < workerCount; i++ { - var err error - if roTxs[i], err = db.BeginRo(ctx); err != nil { - return err - } - reconWorkers[i].SetTx(roTxs[i]) - } - return nil - }(); err != nil { - panic(err) + if err := commit(reconstWorkersCtx); err != nil { + return err } - log.Info(fmt.Sprintf("[%s] State reconstitution, commit", s.LogPrefix()), "took", time.Since(t)) } } } - }() + }) var inputTxNum = startTxNum var b *types.Block @@ -1017,84 +995,99 @@ func reconstituteStep(last bool, return h } - var err error // avoid declare global mutable variable - for bn := startBlockNum; bn <= endBlockNum; bn++ { - t = time.Now() - b, err = blockWithSenders(chainDb, nil, blockReader, bn) - if err != nil { - return err - } - if b == nil { - fmt.Printf("could not find block %d\n", bn) - panic("") - } - txs := b.Transactions() - header := b.HeaderNoCopy() - skipAnalysis := core.SkipAnalysis(chainConfig, bn) - signer := *types.MakeSigner(chainConfig, bn) - - f := core.GetHashFn(header, getHeaderFunc) - getHashFnMute := &sync.Mutex{} - getHashFn := func(n uint64) common.Hash { - getHashFnMute.Lock() - defer getHashFnMute.Unlock() - return f(n) - } - blockContext := core.NewEVMBlockContext(header, getHashFn, engine, nil /* author */) - rules := chainConfig.Rules(bn, b.Time()) - - for txIndex := -1; txIndex <= len(txs); txIndex++ { - if bitmap.Contains(inputTxNum) { - binary.BigEndian.PutUint64(txKey[:], inputTxNum) - txTask := &exec22.TxTask{ - BlockNum: bn, - Header: header, - Coinbase: b.Coinbase(), - Uncles: b.Uncles(), - Rules: rules, - TxNum: inputTxNum, - Txs: txs, - TxIndex: txIndex, - BlockHash: b.Hash(), - SkipAnalysis: skipAnalysis, - Final: txIndex == len(txs), - GetHashFn: getHashFn, - EvmBlockContext: blockContext, - Withdrawals: b.Withdrawals(), + if err := func() (err error) { + defer func() { + close(workCh) + reconDone <- struct{}{} // Complete logging and committing go-routine + if waitErr := g.Wait(); waitErr != nil { + if err == nil { + err = waitErr } - if txIndex >= 0 && txIndex < len(txs) { - txTask.Tx = txs[txIndex] - txTask.TxAsMessage, err = txTask.Tx.AsMessage(signer, header.BaseFee, txTask.Rules) - if err != nil { - return err + return + } + }() + + for bn := startBlockNum; bn <= endBlockNum; bn++ { + t = time.Now() + b, err = blockWithSenders(chainDb, nil, blockReader, bn) + if err != nil { + return err + } + if b == nil { + return fmt.Errorf("could not find block %d\n", bn) + } + txs := b.Transactions() + header := b.HeaderNoCopy() + skipAnalysis := core.SkipAnalysis(chainConfig, bn) + signer := *types.MakeSigner(chainConfig, bn) + + f := core.GetHashFn(header, getHeaderFunc) + getHashFnMute := &sync.Mutex{} + getHashFn := func(n uint64) common.Hash { + getHashFnMute.Lock() + defer getHashFnMute.Unlock() + return f(n) + } + blockContext := core.NewEVMBlockContext(header, getHashFn, engine, nil /* author */, nil /*excessDataGas*/) + rules := chainConfig.Rules(bn, b.Time()) + + for txIndex := -1; txIndex <= len(txs); txIndex++ { + if bitmap.Contains(inputTxNum) { + binary.BigEndian.PutUint64(txKey[:], inputTxNum) + txTask := &exec22.TxTask{ + BlockNum: bn, + Header: header, + Coinbase: b.Coinbase(), + Uncles: b.Uncles(), + Rules: rules, + TxNum: inputTxNum, + Txs: txs, + TxIndex: txIndex, + BlockHash: b.Hash(), + SkipAnalysis: skipAnalysis, + Final: txIndex == len(txs), + GetHashFn: getHashFn, + EvmBlockContext: blockContext, + Withdrawals: b.Withdrawals(), } - if sender, ok := txs[txIndex].GetSender(); ok { - txTask.Sender = &sender + if txIndex >= 0 && txIndex < len(txs) { + txTask.Tx = txs[txIndex] + txTask.TxAsMessage, err = txTask.Tx.AsMessage(signer, header.BaseFee, txTask.Rules) + if err != nil { + return err + } + if sender, ok := txs[txIndex].GetSender(); ok { + txTask.Sender = &sender + } + } else { + txTask.Txs = txs + } + + select { + case workCh <- txTask: + case <-reconstWorkersCtx.Done(): + // if ctx canceled, then maybe it's because of error in errgroup + // + // errgroup doesn't play with pattern where some 1 goroutine-producer is outside of errgroup + // but RwTx doesn't allow move between goroutines + return g.Wait() } - } else { - txTask.Txs = txs } - workCh <- txTask + inputTxNum++ } - inputTxNum++ - } - core.BlockExecutionTimer.UpdateDuration(t) - syncMetrics[stages.Execution].Set(bn) - select { - case <-ctx.Done(): - return ctx.Err() - default: + syncMetrics[stages.Execution].Set(bn) } + return err + }(); err != nil { + return err } - close(workCh) - wg.Wait() - reconDone <- struct{}{} // Complete logging and committing go-routine + for i := 0; i < workerCount; i++ { roTxs[i].Rollback() } if err := db.Update(ctx, func(tx kv.RwTx) error { - if err = rs.Flush(tx); err != nil { + if err := rs.Flush(tx); err != nil { return err } return nil @@ -1109,49 +1102,56 @@ func reconstituteStep(last bool, plainContractCollector := etl.NewCollector(fmt.Sprintf("%s recon plainContract", s.LogPrefix()), dirs.Tmp, etl.NewSortableBuffer(etl.BufferOptimalSize)) defer plainContractCollector.Close() var transposedKey []byte - if err = db.View(ctx, func(roTx kv.Tx) error { - kv.ReadAhead(ctx, db, atomic2.NewBool(false), kv.PlainStateR, nil, math.MaxUint32) - if err = roTx.ForEach(kv.PlainStateR, nil, func(k, v []byte) error { + + if err := db.View(ctx, func(roTx kv.Tx) error { + clear := kv.ReadAhead(ctx, db, &atomic.Bool{}, kv.PlainStateR, nil, math.MaxUint32) + defer clear() + if err := roTx.ForEach(kv.PlainStateR, nil, func(k, v []byte) error { transposedKey = append(transposedKey[:0], k[8:]...) transposedKey = append(transposedKey, k[:8]...) return plainStateCollector.Collect(transposedKey, v) }); err != nil { return err } - kv.ReadAhead(ctx, db, atomic2.NewBool(false), kv.PlainStateD, nil, math.MaxUint32) - if err = roTx.ForEach(kv.PlainStateD, nil, func(k, v []byte) error { + clear2 := kv.ReadAhead(ctx, db, &atomic.Bool{}, kv.PlainStateD, nil, math.MaxUint32) + defer clear2() + if err := roTx.ForEach(kv.PlainStateD, nil, func(k, v []byte) error { transposedKey = append(transposedKey[:0], v...) transposedKey = append(transposedKey, k...) return plainStateCollector.Collect(transposedKey, nil) }); err != nil { return err } - kv.ReadAhead(ctx, db, atomic2.NewBool(false), kv.CodeR, nil, math.MaxUint32) - if err = roTx.ForEach(kv.CodeR, nil, func(k, v []byte) error { + clear3 := kv.ReadAhead(ctx, db, &atomic.Bool{}, kv.CodeR, nil, math.MaxUint32) + defer clear3() + if err := roTx.ForEach(kv.CodeR, nil, func(k, v []byte) error { transposedKey = append(transposedKey[:0], k[8:]...) transposedKey = append(transposedKey, k[:8]...) return codeCollector.Collect(transposedKey, v) }); err != nil { return err } - kv.ReadAhead(ctx, db, atomic2.NewBool(false), kv.CodeD, nil, math.MaxUint32) - if err = roTx.ForEach(kv.CodeD, nil, func(k, v []byte) error { + clear4 := kv.ReadAhead(ctx, db, &atomic.Bool{}, kv.CodeD, nil, math.MaxUint32) + defer clear4() + if err := roTx.ForEach(kv.CodeD, nil, func(k, v []byte) error { transposedKey = append(transposedKey[:0], v...) transposedKey = append(transposedKey, k...) return codeCollector.Collect(transposedKey, nil) }); err != nil { return err } - kv.ReadAhead(ctx, db, atomic2.NewBool(false), kv.PlainContractR, nil, math.MaxUint32) - if err = roTx.ForEach(kv.PlainContractR, nil, func(k, v []byte) error { + clear5 := kv.ReadAhead(ctx, db, &atomic.Bool{}, kv.PlainContractR, nil, math.MaxUint32) + defer clear5() + if err := roTx.ForEach(kv.PlainContractR, nil, func(k, v []byte) error { transposedKey = append(transposedKey[:0], k[8:]...) transposedKey = append(transposedKey, k[:8]...) return plainContractCollector.Collect(transposedKey, v) }); err != nil { return err } - kv.ReadAhead(ctx, db, atomic2.NewBool(false), kv.PlainContractD, nil, math.MaxUint32) - if err = roTx.ForEach(kv.PlainContractD, nil, func(k, v []byte) error { + clear6 := kv.ReadAhead(ctx, db, &atomic.Bool{}, kv.PlainContractD, nil, math.MaxUint32) + defer clear6() + if err := roTx.ForEach(kv.PlainContractD, nil, func(k, v []byte) error { transposedKey = append(transposedKey[:0], v...) transposedKey = append(transposedKey, k...) return plainContractCollector.Collect(transposedKey, nil) @@ -1162,33 +1162,33 @@ func reconstituteStep(last bool, }); err != nil { return err } - if err = db.Update(ctx, func(tx kv.RwTx) error { - if err = tx.ClearBucket(kv.PlainStateR); err != nil { + if err := db.Update(ctx, func(tx kv.RwTx) error { + if err := tx.ClearBucket(kv.PlainStateR); err != nil { return err } - if err = tx.ClearBucket(kv.PlainStateD); err != nil { + if err := tx.ClearBucket(kv.PlainStateD); err != nil { return err } - if err = tx.ClearBucket(kv.CodeR); err != nil { + if err := tx.ClearBucket(kv.CodeR); err != nil { return err } - if err = tx.ClearBucket(kv.CodeD); err != nil { + if err := tx.ClearBucket(kv.CodeD); err != nil { return err } - if err = tx.ClearBucket(kv.PlainContractR); err != nil { + if err := tx.ClearBucket(kv.PlainContractR); err != nil { return err } - if err = tx.ClearBucket(kv.PlainContractD); err != nil { + if err := tx.ClearBucket(kv.PlainContractD); err != nil { return err } return nil }); err != nil { return err } - if err = chainDb.Update(ctx, func(tx kv.RwTx) error { + if err := chainDb.Update(ctx, func(tx kv.RwTx) error { var lastKey []byte var lastVal []byte - if err = plainStateCollector.Load(tx, kv.PlainState, func(k, v []byte, table etl.CurrentTableReader, next etl.LoadNextFunc) error { + if err := plainStateCollector.Load(tx, kv.PlainState, func(k, v []byte, table etl.CurrentTableReader, next etl.LoadNextFunc) error { if !bytes.Equal(k[:len(k)-8], lastKey) { if lastKey != nil { if e := next(lastKey, lastKey, lastVal); e != nil { @@ -1197,7 +1197,11 @@ func reconstituteStep(last bool, } lastKey = append(lastKey[:0], k[:len(k)-8]...) } - lastVal = append(lastVal[:0], v...) + if v == nil { // `nil` value means delete, `empty value []byte{}` means empty value + lastVal = nil + } else { + lastVal = append(lastVal[:0], v...) + } return nil }, etl.TransformArgs{}); err != nil { return err @@ -1216,7 +1220,7 @@ func reconstituteStep(last bool, } lastKey = nil lastVal = nil - if err = codeCollector.Load(tx, kv.Code, func(k, v []byte, table etl.CurrentTableReader, next etl.LoadNextFunc) error { + if err := codeCollector.Load(tx, kv.Code, func(k, v []byte, table etl.CurrentTableReader, next etl.LoadNextFunc) error { if !bytes.Equal(k[:len(k)-8], lastKey) { if lastKey != nil { if e := next(lastKey, lastKey, lastVal); e != nil { @@ -1225,7 +1229,11 @@ func reconstituteStep(last bool, } lastKey = append(lastKey[:0], k[:len(k)-8]...) } - lastVal = append(lastVal[:0], v...) + if v == nil { + lastVal = nil + } else { + lastVal = append(lastVal[:0], v...) + } return nil }, etl.TransformArgs{}); err != nil { return err @@ -1244,7 +1252,7 @@ func reconstituteStep(last bool, } lastKey = nil lastVal = nil - if err = plainContractCollector.Load(tx, kv.PlainContractCode, func(k, v []byte, table etl.CurrentTableReader, next etl.LoadNextFunc) error { + if err := plainContractCollector.Load(tx, kv.PlainContractCode, func(k, v []byte, table etl.CurrentTableReader, next etl.LoadNextFunc) error { if !bytes.Equal(k[:len(k)-8], lastKey) { if lastKey != nil { if e := next(lastKey, lastKey, lastVal); e != nil { @@ -1253,7 +1261,11 @@ func reconstituteStep(last bool, } lastKey = append(lastKey[:0], k[:len(k)-8]...) } - lastVal = append(lastVal[:0], v...) + if v == nil { + lastVal = nil + } else { + lastVal = append(lastVal[:0], v...) + } return nil }, etl.TransformArgs{}); err != nil { return err @@ -1278,10 +1290,22 @@ func reconstituteStep(last bool, return nil } +func safeCloseTxTaskCh(ch chan *exec22.TxTask) { + if ch == nil { + return + } + select { + case <-ch: + // Channel was already closed + default: + close(ch) + } +} + func ReconstituteState(ctx context.Context, s *StageState, dirs datadir.Dirs, workerCount int, batchSize datasize.ByteSize, chainDb kv.RwDB, blockReader services.FullBlockReader, logger log.Logger, agg *state2.AggregatorV3, engine consensus.Engine, - chainConfig *chain.Config, genesis *core.Genesis) (err error) { + chainConfig *chain.Config, genesis *types.Genesis) (err error) { startTime := time.Now() defer agg.EnableMadvNormal().DisableReadAhead() blockSnapshots := blockReader.(WithSnapshots).Snapshots() @@ -1313,7 +1337,8 @@ func ReconstituteState(ctx context.Context, s *StageState, dirs datadir.Dirs, wo return err } if !ok { - return fmt.Errorf("blockNum for mininmaxTxNum=%d not found", toTxNum) + lastBn, lastTn, _ := rawdbv3.TxNums.Last(tx) + return fmt.Errorf("blockNum for mininmaxTxNum=%d not found. See lastBlockNum=%d,lastTxNum=%d", toTxNum, lastBn, lastTn) } if blockNum == 0 { return fmt.Errorf("not enough transactions in the history data") @@ -1365,17 +1390,23 @@ func ReconstituteState(ctx context.Context, s *StageState, dirs datadir.Dirs, wo fillWorker := exec3.NewFillWorker(txNum, aggSteps[len(aggSteps)-1]) t := time.Now() - fillWorker.FillAccounts(plainStateCollector) + if err := fillWorker.FillAccounts(plainStateCollector); err != nil { + return err + } if time.Since(t) > 5*time.Second { log.Info(fmt.Sprintf("[%s] Filled accounts", s.LogPrefix()), "took", time.Since(t)) } t = time.Now() - fillWorker.FillStorage(plainStateCollector) + if err := fillWorker.FillStorage(plainStateCollector); err != nil { + return err + } if time.Since(t) > 5*time.Second { log.Info(fmt.Sprintf("[%s] Filled storage", s.LogPrefix()), "took", time.Since(t)) } t = time.Now() - fillWorker.FillCode(codeCollector, plainContractCollector) + if err := fillWorker.FillCode(codeCollector, plainContractCollector); err != nil { + return err + } if time.Since(t) > 5*time.Second { log.Info(fmt.Sprintf("[%s] Filled code", s.LogPrefix()), "took", time.Since(t)) } diff --git a/eth/stagedsync/stage_bodies.go b/eth/stagedsync/stage_bodies.go index 24914bc67da..34fd58c1dfb 100644 --- a/eth/stagedsync/stage_bodies.go +++ b/eth/stagedsync/stage_bodies.go @@ -14,6 +14,7 @@ import ( "github.com/ledgerwatch/log/v3" "github.com/ledgerwatch/erigon/core/rawdb" + "github.com/ledgerwatch/erigon/dataflow" "github.com/ledgerwatch/erigon/eth/stagedsync/stages" "github.com/ledgerwatch/erigon/turbo/adapter" "github.com/ledgerwatch/erigon/turbo/services" @@ -129,39 +130,14 @@ func BodiesForward( prevProgress := bodyProgress var noProgressCount uint = 0 // How many time the progress was printed without actual progress var totalDelivered uint64 = 0 + cr := ChainReader{Cfg: cfg.chanConfig, Db: tx} loopBody := func() (bool, error) { - // always check if a new request is needed at the start of the loop - // this will check for timed out old requests and attempt to send them again - start := time.Now() - currentTime := uint64(time.Now().Unix()) - req, err = cfg.bd.RequestMoreBodies(tx, cfg.blockReader, currentTime, cfg.blockPropagator) - if err != nil { - return false, fmt.Errorf("request more bodies: %w", err) - } - d1 += time.Since(start) - - peer = [64]byte{} - sentToPeer = false - - if req != nil { - start := time.Now() - peer, sentToPeer = cfg.bodyReqSend(ctx, req) - d2 += time.Since(start) - } - if req != nil && sentToPeer { - start := time.Now() - currentTime := uint64(time.Now().Unix()) - cfg.bd.RequestSent(req, currentTime+uint64(timeout), peer) - d3 += time.Since(start) - } - // loopCount is used here to ensure we don't get caught in a constant loop of making requests // having some time out so requesting again and cycling like that forever. We'll cap it // and break the loop so we can see if there are any records to actually process further down // then come back here again in the next cycle - loopCount := 0 - for req != nil && sentToPeer { + for loopCount := 0; loopCount == 0 || (req != nil && sentToPeer && loopCount < requestLoopCutOff); loopCount++ { start := time.Now() currentTime := uint64(time.Now().Unix()) req, err = cfg.bd.RequestMoreBodies(tx, cfg.blockReader, currentTime, cfg.blockPropagator) @@ -181,14 +157,9 @@ func BodiesForward( cfg.bd.RequestSent(req, currentTime+uint64(timeout), peer) d3 += time.Since(start) } - - loopCount++ - if loopCount >= requestLoopCutOff { - break - } } - start = time.Now() + start := time.Now() requestedLow, delivered, err := cfg.bd.GetDeliveries(tx) if err != nil { return false, err @@ -196,7 +167,6 @@ func BodiesForward( totalDelivered += delivered d4 += time.Since(start) start = time.Now() - cr := ChainReader{Cfg: cfg.chanConfig, Db: tx} toProcess := cfg.bd.NextProcessingCount() @@ -246,6 +216,9 @@ func BodiesForward( return false, err } } + if ok { + dataflow.BlockBodyDownloadStates.AddChange(blockHeight, dataflow.BlockBodyCleared) + } if blockHeight > bodyProgress { bodyProgress = blockHeight @@ -296,14 +269,11 @@ func BodiesForward( } // kick off the loop and check for any reason to stop and break early - for !stopped { - shouldBreak, err := loopBody() - if err != nil { + var shouldBreak bool + for !stopped && !shouldBreak { + if shouldBreak, err = loopBody(); err != nil { return err } - if shouldBreak { - break - } } // remove the temporary bucket for bodies stage diff --git a/eth/stagedsync/stage_cumulative_index.go b/eth/stagedsync/stage_cumulative_index.go index c9f9f01941d..23fbc6aa7e6 100644 --- a/eth/stagedsync/stage_cumulative_index.go +++ b/eth/stagedsync/stage_cumulative_index.go @@ -34,7 +34,7 @@ func SpawnStageCumulativeIndex(cfg CumulativeIndexCfg, s *StageState, tx kv.RwTx if !useExternalTx { var err error - tx, err = cfg.db.BeginRw(context.Background()) + tx, err = cfg.db.BeginRw(ctx) if err != nil { return err } @@ -102,6 +102,8 @@ func SpawnStageCumulativeIndex(cfg CumulativeIndexCfg, s *StageState, tx kv.RwTx // Check for logs select { + case <-ctx.Done(): + return ctx.Err() case <-logEvery.C: log.Info(fmt.Sprintf("[%s] Wrote Cumulative Index", s.LogPrefix()), "gasUsed", cumulativeGasUsed.String(), "now", currentBlockNumber, "blk/sec", float64(currentBlockNumber-prevProgress)/float64(logInterval/time.Second)) diff --git a/eth/stagedsync/stage_execute.go b/eth/stagedsync/stage_execute.go index f5998b7aa76..2eca369fd16 100644 --- a/eth/stagedsync/stage_execute.go +++ b/eth/stagedsync/stage_execute.go @@ -85,7 +85,7 @@ type ExecuteBlockCfg struct { dirs datadir.Dirs historyV3 bool syncCfg ethconfig.Sync - genesis *core.Genesis + genesis *types.Genesis agg *libstate.AggregatorV3 } @@ -105,7 +105,7 @@ func StageExecuteBlocksCfg( dirs datadir.Dirs, blockReader services.FullBlockReader, hd headerDownloader, - genesis *core.Genesis, + genesis *types.Genesis, syncCfg ethconfig.Sync, agg *libstate.AggregatorV3, ) ExecuteBlockCfg { @@ -170,11 +170,11 @@ func executeBlock( getHashFn := core.GetHashFn(block.Header(), getHeader) if isPoSa { - execRs, err = core.ExecuteBlockEphemerallyForBSC(cfg.chainConfig, &vmConfig, getHashFn, cfg.engine, block, stateReader, stateWriter, EpochReaderImpl{tx: tx}, ChainReaderImpl{config: cfg.chainConfig, tx: tx, blockReader: cfg.blockReader}, getTracer) + execRs, err = core.ExecuteBlockEphemerallyForBSC(cfg.chainConfig, &vmConfig, getHashFn, cfg.engine, block, stateReader, stateWriter, ChainReaderImpl{config: cfg.chainConfig, tx: tx, blockReader: cfg.blockReader}, getTracer) } else if isBor { - execRs, err = core.ExecuteBlockEphemerallyBor(cfg.chainConfig, &vmConfig, getHashFn, cfg.engine, block, stateReader, stateWriter, EpochReaderImpl{tx: tx}, ChainReaderImpl{config: cfg.chainConfig, tx: tx, blockReader: cfg.blockReader}, getTracer) + execRs, err = core.ExecuteBlockEphemerallyBor(cfg.chainConfig, &vmConfig, getHashFn, cfg.engine, block, stateReader, stateWriter, ChainReaderImpl{config: cfg.chainConfig, tx: tx, blockReader: cfg.blockReader}, getTracer) } else { - execRs, err = core.ExecuteBlockEphemerally(cfg.chainConfig, &vmConfig, getHashFn, cfg.engine, block, stateReader, stateWriter, EpochReaderImpl{tx: tx}, ChainReaderImpl{config: cfg.chainConfig, tx: tx, blockReader: cfg.blockReader}, getTracer) + execRs, err = core.ExecuteBlockEphemerally(cfg.chainConfig, &vmConfig, getHashFn, cfg.engine, block, stateReader, stateWriter, ChainReaderImpl{config: cfg.chainConfig, tx: tx, blockReader: cfg.blockReader}, getTracer) } if err != nil { return err @@ -281,10 +281,9 @@ func ExecBlockV3(s *StageState, u Unwinder, tx kv.RwTx, toBlock uint64, ctx cont if to > s.BlockNumber+16 { log.Info(fmt.Sprintf("[%s] Blocks execution", logPrefix), "from", s.BlockNumber, "to", to) } - rs := state.NewStateV3() parallel := initialCycle && tx == nil - if err := ExecV3(ctx, s, u, workersCount, cfg, tx, parallel, rs, logPrefix, - log.New(), to); err != nil { + if err := ExecV3(ctx, s, u, workersCount, cfg, tx, parallel, logPrefix, + to); err != nil { return fmt.Errorf("ExecV3: %w", err) } return nil @@ -312,7 +311,7 @@ func reconstituteBlock(agg *libstate.AggregatorV3, db kv.RoDB, tx kv.Tx) (n uint func unwindExec3(u *UnwindState, s *StageState, tx kv.RwTx, ctx context.Context, cfg ExecuteBlockCfg, accumulator *shards.Accumulator) (err error) { cfg.agg.SetLogPrefix(s.LogPrefix()) - rs := state.NewStateV3() + rs := state.NewStateV3(cfg.dirs.Tmp) // unwind all txs of u.UnwindPoint block. 1 txn in begin/end of block - system txs txNum, err := rawdbv3.TxNums.Min(tx, u.UnwindPoint+1) if err != nil { diff --git a/eth/stagedsync/stage_headers.go b/eth/stagedsync/stage_headers.go index 2747058d052..b2087efa73c 100644 --- a/eth/stagedsync/stage_headers.go +++ b/eth/stagedsync/stage_headers.go @@ -859,7 +859,7 @@ Loop: } // Load headers into the database var inSync bool - if inSync, err = cfg.hd.InsertHeaders(headerInserter.NewFeedHeaderFunc(tx, cfg.blockReader), cfg.chainConfig.TerminalTotalDifficulty, logPrefix, logEvery.C, uint64(currentTime.Unix())); err != nil { + if inSync, err = cfg.hd.InsertHeaders(headerInserter.NewFeedHeaderFunc(tx, cfg.blockReader, cfg.hd.Engine, cfg.chainConfig, cfg.hd.ConsensusHeaderReader), cfg.chainConfig.TerminalTotalDifficulty, logPrefix, logEvery.C, uint64(currentTime.Unix())); err != nil { return err } @@ -1149,26 +1149,6 @@ func (cr ChainReaderImpl) GetTd(hash libcommon.Hash, number uint64) *big.Int { return td } -type EpochReaderImpl struct { - tx kv.RwTx -} - -func (cr EpochReaderImpl) GetEpoch(hash libcommon.Hash, number uint64) ([]byte, error) { - return rawdb.ReadEpoch(cr.tx, number, hash) -} -func (cr EpochReaderImpl) PutEpoch(hash libcommon.Hash, number uint64, proof []byte) error { - return rawdb.WriteEpoch(cr.tx, number, hash, proof) -} -func (cr EpochReaderImpl) GetPendingEpoch(hash libcommon.Hash, number uint64) ([]byte, error) { - return rawdb.ReadPendingEpoch(cr.tx, number, hash) -} -func (cr EpochReaderImpl) PutPendingEpoch(hash libcommon.Hash, number uint64, proof []byte) error { - return rawdb.WritePendingEpoch(cr.tx, number, hash, proof) -} -func (cr EpochReaderImpl) FindBeforeOrEqualNumber(number uint64) (blockNum uint64, blockHash libcommon.Hash, transitionProof []byte, err error) { - return rawdb.FindEpochBeforeOrEqualNumber(cr.tx, number) -} - func HeadersPrune(p *PruneState, tx kv.RwTx, cfg HeadersCfg, ctx context.Context) (err error) { useExternalTx := tx != nil if !useExternalTx { diff --git a/eth/stagedsync/stage_mining_exec.go b/eth/stagedsync/stage_mining_exec.go index 98bacc2c16a..d1b160bf818 100644 --- a/eth/stagedsync/stage_mining_exec.go +++ b/eth/stagedsync/stage_mining_exec.go @@ -172,8 +172,12 @@ func SpawnMiningExecStage(s *StageState, tx kv.RwTx, cfg MiningExecCfg, quit <-c } var err error - _, current.Txs, current.Receipts, err = core.FinalizeBlockExecution(cfg.engine, stateReader, current.Header, current.Txs, current.Uncles, stateWriter, - &cfg.chainConfig, ibs, current.Receipts, current.Withdrawals, EpochReaderImpl{tx: tx}, ChainReaderImpl{config: &cfg.chainConfig, tx: tx, blockReader: cfg.blockReader}, true) + parentHeader := getHeader(current.Header.ParentHash, current.Header.Number.Uint64()-1) + var excessDataGas *big.Int + if parentHeader != nil { + excessDataGas = parentHeader.ExcessDataGas + } + _, current.Txs, current.Receipts, err = core.FinalizeBlockExecution(cfg.engine, stateReader, current.Header, current.Txs, current.Uncles, stateWriter, &cfg.chainConfig, ibs, current.Receipts, current.Withdrawals, ChainReaderImpl{config: &cfg.chainConfig, tx: tx, blockReader: cfg.blockReader}, true, excessDataGas) if err != nil { return err } @@ -376,12 +380,14 @@ func addTransactionsToMiningBlock(logPrefix string, current *MiningBlock, chainC var coalescedLogs types.Logs noop := state.NewNoopWriter() + parentHeader := getHeader(header.ParentHash, header.Number.Uint64()-1) + var miningCommitTx = func(txn types.Transaction, coinbase libcommon.Address, vmConfig *vm.Config, chainConfig chain.Config, ibs *state.IntraBlockState, current *MiningBlock) ([]*types.Log, error) { ibs.Prepare(txn.Hash(), libcommon.Hash{}, tcount) gasSnap := gasPool.Gas() snap := ibs.Snapshot() log.Debug("addTransactionsToMiningBlock", "txn hash", txn.Hash()) - receipt, _, err := core.ApplyTransaction(&chainConfig, core.GetHashFn(header, getHeader), engine, &coinbase, gasPool, ibs, noop, header, txn, &header.GasUsed, *vmConfig) + receipt, _, err := core.ApplyTransaction(&chainConfig, core.GetHashFn(header, getHeader), engine, &coinbase, gasPool, ibs, noop, header, txn, &header.GasUsed, *vmConfig, parentHeader.ExcessDataGas) if err != nil { ibs.RevertToSnapshot(snap) gasPool = new(core.GasPool).AddGas(gasSnap) // restore gasPool as well as ibs diff --git a/eth/stagedsync/stage_snapshots.go b/eth/stagedsync/stage_snapshots.go index 2117844804d..afa31e7dd19 100644 --- a/eth/stagedsync/stage_snapshots.go +++ b/eth/stagedsync/stage_snapshots.go @@ -10,6 +10,8 @@ import ( "time" "github.com/holiman/uint256" + "github.com/ledgerwatch/log/v3" + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/cmp" @@ -22,6 +24,7 @@ import ( "github.com/ledgerwatch/erigon-lib/kv/kvcfg" "github.com/ledgerwatch/erigon-lib/kv/rawdbv3" "github.com/ledgerwatch/erigon-lib/state" + "github.com/ledgerwatch/erigon/consensus" "github.com/ledgerwatch/erigon/consensus/parlia" "github.com/ledgerwatch/erigon/core/rawdb" @@ -31,7 +34,6 @@ import ( "github.com/ledgerwatch/erigon/turbo/services" "github.com/ledgerwatch/erigon/turbo/snapshotsync" "github.com/ledgerwatch/erigon/turbo/snapshotsync/snapcfg" - "github.com/ledgerwatch/log/v3" ) type SnapshotsCfg struct { @@ -164,6 +166,8 @@ func DownloadAndIndexSnapshotsIfNeed(s *StageState, ctx context.Context, tx kv.R } if cfg.historyV3 { + cfg.agg.CleanDir() + indexWorkers := estimate.IndexSnapshot.Workers() if err := cfg.agg.BuildMissedIndices(ctx, indexWorkers); err != nil { return err @@ -534,7 +538,7 @@ func SnapshotsPrune(s *PruneState, cfg SnapshotsCfg, ctx context.Context, tx kv. } br.RetireBlocksInBackground(ctx, s.ForwardProgress, log.LvlDebug) - cfg.agg.BuildFilesInBackground() + //cfg.agg.BuildFilesInBackground() } if !useExternalTx { diff --git a/eth/tracers/internal/tracetest/calltrace_test.go b/eth/tracers/internal/tracetest/calltrace_test.go index 26009ae8c25..9c3c5ab005d 100644 --- a/eth/tracers/internal/tracetest/calltrace_test.go +++ b/eth/tracers/internal/tracetest/calltrace_test.go @@ -28,7 +28,9 @@ import ( "github.com/holiman/uint256" "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" - "github.com/ledgerwatch/erigon-lib/kv/memdb" + "github.com/ledgerwatch/erigon-lib/common/hexutility" + "github.com/ledgerwatch/erigon/turbo/stages" + "github.com/stretchr/testify/require" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/common/hexutil" @@ -60,7 +62,7 @@ type callContext struct { type callLog struct { Address libcommon.Address `json:"address"` Topics []libcommon.Hash `json:"topics"` - Data hexutil.Bytes `json:"data"` + Data hexutility.Bytes `json:"data"` } // callTrace is the result of a callTracer run. @@ -69,8 +71,8 @@ type callTrace struct { Gas *hexutil.Uint64 `json:"gas"` GasUsed *hexutil.Uint64 `json:"gasUsed"` To libcommon.Address `json:"to,omitempty"` - Input hexutil.Bytes `json:"input"` - Output hexutil.Bytes `json:"output,omitempty"` + Input hexutility.Bytes `json:"input"` + Output hexutility.Bytes `json:"output,omitempty"` Error string `json:"error,omitempty"` Revertal string `json:"revertReason,omitempty"` Calls []callTrace `json:"calls,omitempty"` @@ -82,7 +84,7 @@ type callTrace struct { // callTracerTest defines a single test to check the call tracer against. type callTracerTest struct { - Genesis *core.Genesis `json:"genesis"` + Genesis *types.Genesis `json:"genesis"` Context *callContext `json:"context"` Input string `json:"input"` TracerConfig json.RawMessage `json:"tracerConfig"` @@ -147,10 +149,13 @@ func testCallTracer(tracerName string, dirPath string, t *testing.T) { Difficulty: (*big.Int)(test.Context.Difficulty), GasLimit: uint64(test.Context.GasLimit), } - _, dbTx = memdb.NewTestTx(t) - rules = test.Genesis.Config.Rules(context.BlockNumber, context.Time) - statedb, _ = tests.MakePreState(rules, dbTx, test.Genesis.Alloc, uint64(test.Context.Number)) + rules = test.Genesis.Config.Rules(context.BlockNumber, context.Time) ) + m := stages.Mock(t) + dbTx, err := m.DB.BeginRw(m.Ctx) + require.NoError(t, err) + defer dbTx.Rollback() + statedb, _ := tests.MakePreState(rules, dbTx, test.Genesis.Alloc, uint64(test.Context.Number)) if test.Genesis.BaseFee != nil { context.BaseFee, _ = uint256.FromBig(test.Genesis.BaseFee) } @@ -222,12 +227,12 @@ func BenchmarkTracers(b *testing.B) { if err := json.Unmarshal(blob, test); err != nil { b.Fatalf("failed to parse testcase: %v", err) } - benchTracer("callTracer", test, b) + benchTracer(b, "callTracer", test) }) } } -func benchTracer(tracerName string, test *callTracerTest, b *testing.B) { +func benchTracer(b *testing.B, tracerName string, test *callTracerTest) { // Configure a blockchain with the given prestate tx, err := types.DecodeTransaction(rlp.NewStream(bytes.NewReader(common.FromHex(test.Input)), 0)) if err != nil { @@ -253,7 +258,10 @@ func benchTracer(tracerName string, test *callTracerTest, b *testing.B) { Difficulty: (*big.Int)(test.Context.Difficulty), GasLimit: uint64(test.Context.GasLimit), } - _, dbTx := memdb.NewTestTx(b) + m := stages.Mock(b) + dbTx, err := m.DB.BeginRw(m.Ctx) + require.NoError(b, err) + defer dbTx.Rollback() statedb, _ := tests.MakePreState(rules, dbTx, test.Genesis.Alloc, uint64(test.Context.Number)) b.ReportAllocs() @@ -315,18 +323,22 @@ func TestZeroValueToNotExitCall(t *testing.T) { byte(vm.DUP1), byte(vm.PUSH1), 0xff, byte(vm.GAS), // value=0,address=0xff, gas=GAS byte(vm.CALL), } - var alloc = core.GenesisAlloc{ - to: core.GenesisAccount{ + var alloc = types.GenesisAlloc{ + to: types.GenesisAccount{ Nonce: 1, Code: code, }, - origin: core.GenesisAccount{ + origin: types.GenesisAccount{ Nonce: 0, Balance: big.NewInt(500000000000000), }, } rules := params.MainnetChainConfig.Rules(context.BlockNumber, context.Time) - _, dbTx := memdb.NewTestTx(t) + m := stages.Mock(t) + dbTx, err := m.DB.BeginRw(m.Ctx) + require.NoError(t, err) + defer dbTx.Rollback() + statedb, _ := tests.MakePreState(rules, dbTx, alloc, context.BlockNumber) // Create the tracer, the EVM environment and run it tracer, err := tracers.New("callTracer", nil, nil) diff --git a/eth/tracers/internal/tracetest/prestate_test.go b/eth/tracers/internal/tracetest/prestate_test.go index 987aee88d75..f6bd6ebb1e6 100644 --- a/eth/tracers/internal/tracetest/prestate_test.go +++ b/eth/tracers/internal/tracetest/prestate_test.go @@ -27,7 +27,8 @@ import ( "github.com/holiman/uint256" libcommon "github.com/ledgerwatch/erigon-lib/common" - "github.com/ledgerwatch/erigon-lib/kv/memdb" + "github.com/ledgerwatch/erigon/turbo/stages" + "github.com/stretchr/testify/require" "github.com/ledgerwatch/erigon/common" "github.com/ledgerwatch/erigon/core" @@ -112,10 +113,13 @@ func testPrestateDiffTracer(tracerName string, dirPath string, t *testing.T) { Difficulty: (*big.Int)(test.Context.Difficulty), GasLimit: uint64(test.Context.GasLimit), } - _, dbTx = memdb.NewTestTx(t) - rules = test.Genesis.Config.Rules(context.BlockNumber, context.Time) - statedb, _ = tests.MakePreState(rules, dbTx, test.Genesis.Alloc, context.BlockNumber) + rules = test.Genesis.Config.Rules(context.BlockNumber, context.Time) ) + m := stages.Mock(t) + dbTx, err := m.DB.BeginRw(m.Ctx) + require.NoError(t, err) + defer dbTx.Rollback() + statedb, _ := tests.MakePreState(rules, dbTx, test.Genesis.Alloc, context.BlockNumber) if test.Genesis.BaseFee != nil { context.BaseFee, _ = uint256.FromBig(test.Genesis.BaseFee) } diff --git a/eth/tracers/logger/gen_structlog.go b/eth/tracers/logger/gen_structlog.go index 15d82751044..fa9de16a7b4 100644 --- a/eth/tracers/logger/gen_structlog.go +++ b/eth/tracers/logger/gen_structlog.go @@ -5,8 +5,8 @@ import ( "math/big" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" - "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/common/math" "github.com/ledgerwatch/erigon/core/vm" ) @@ -20,11 +20,11 @@ func (s StructLog) MarshalJSON() ([]byte, error) { Op vm.OpCode `json:"op"` Gas math.HexOrDecimal64 `json:"gas"` GasCost math.HexOrDecimal64 `json:"gasCost"` - Memory hexutil.Bytes `json:"memory"` + Memory hexutility.Bytes `json:"memory"` MemorySize int `json:"memSize"` Stack []*math.HexOrDecimal256 `json:"stack"` ReturnStack []math.HexOrDecimal64 `json:"returnStack"` - ReturnData hexutil.Bytes `json:"returnData"` + ReturnData hexutility.Bytes `json:"returnData"` Storage map[libcommon.Hash]libcommon.Hash `json:"-"` Depth int `json:"depth"` RefundCounter uint64 `json:"refund"` @@ -62,10 +62,10 @@ func (s *StructLog) UnmarshalJSON(input []byte) error { Op *vm.OpCode `json:"op"` Gas *math.HexOrDecimal64 `json:"gas"` GasCost *math.HexOrDecimal64 `json:"gasCost"` - Memory *hexutil.Bytes `json:"memory"` + Memory *hexutility.Bytes `json:"memory"` MemorySize *int `json:"memSize"` Stack []*math.HexOrDecimal256 `json:"stack"` - ReturnData *hexutil.Bytes `json:"returnData"` + ReturnData *hexutility.Bytes `json:"returnData"` Storage map[libcommon.Hash]libcommon.Hash `json:"-"` Depth *int `json:"depth"` RefundCounter *uint64 `json:"refund"` diff --git a/eth/tracers/logger/logger.go b/eth/tracers/logger/logger.go index 97934e51cc0..3beb7e7d96c 100644 --- a/eth/tracers/logger/logger.go +++ b/eth/tracers/logger/logger.go @@ -11,10 +11,11 @@ import ( "strings" "github.com/holiman/uint256" + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" - "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/common/math" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/core/vm" @@ -70,8 +71,8 @@ type structLogMarshaling struct { Stack []*math.HexOrDecimal256 Gas math.HexOrDecimal64 GasCost math.HexOrDecimal64 - Memory hexutil.Bytes - ReturnData hexutil.Bytes + Memory hexutility.Bytes + ReturnData hexutility.Bytes OpName string `json:"opName"` // adds call to OpName() in MarshalJSON ErrorString string `json:"error"` // adds call to ErrorString() in MarshalJSON } diff --git a/eth/tracers/native/call.go b/eth/tracers/native/call.go index 59982d23ec5..4a70838bd00 100644 --- a/eth/tracers/native/call.go +++ b/eth/tracers/native/call.go @@ -23,7 +23,9 @@ import ( "sync/atomic" "github.com/holiman/uint256" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/accounts/abi" "github.com/ledgerwatch/erigon/common" @@ -41,7 +43,7 @@ func init() { type callLog struct { Address libcommon.Address `json:"address"` Topics []libcommon.Hash `json:"topics"` - Data hexutil.Bytes `json:"data"` + Data hexutility.Bytes `json:"data"` } type callFrame struct { @@ -96,8 +98,8 @@ type callFrameMarshaling struct { Gas hexutil.Uint64 GasUsed hexutil.Uint64 Value *hexutil.Big - Input hexutil.Bytes - Output hexutil.Bytes + Input hexutility.Bytes + Output hexutility.Bytes } type callTracer struct { @@ -181,7 +183,7 @@ func (t *callTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, sco } data := scope.Memory.GetCopy(int64(mStart.Uint64()), int64(mSize.Uint64())) - log := callLog{Address: scope.Contract.Address(), Topics: topics, Data: hexutil.Bytes(data)} + log := callLog{Address: scope.Contract.Address(), Topics: topics, Data: hexutility.Bytes(data)} t.callstack[len(t.callstack)-1].Logs = append(t.callstack[len(t.callstack)-1].Logs, log) } } diff --git a/eth/tracers/native/gen_account_json.go b/eth/tracers/native/gen_account_json.go index ec2f40728b1..d4f00b2a4e2 100644 --- a/eth/tracers/native/gen_account_json.go +++ b/eth/tracers/native/gen_account_json.go @@ -7,6 +7,7 @@ import ( "math/big" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common/hexutil" ) @@ -17,7 +18,7 @@ var _ = (*accountMarshaling)(nil) func (a account) MarshalJSON() ([]byte, error) { type account struct { Balance *hexutil.Big `json:"balance,omitempty"` - Code hexutil.Bytes `json:"code,omitempty"` + Code hexutility.Bytes `json:"code,omitempty"` Nonce uint64 `json:"nonce,omitempty"` Storage map[libcommon.Hash]libcommon.Hash `json:"storage,omitempty"` } @@ -33,7 +34,7 @@ func (a account) MarshalJSON() ([]byte, error) { func (a *account) UnmarshalJSON(input []byte) error { type account struct { Balance *hexutil.Big `json:"balance,omitempty"` - Code *hexutil.Bytes `json:"code,omitempty"` + Code *hexutility.Bytes `json:"code,omitempty"` Nonce *uint64 `json:"nonce,omitempty"` Storage map[libcommon.Hash]libcommon.Hash `json:"storage,omitempty"` } diff --git a/eth/tracers/native/gen_callframe_json.go b/eth/tracers/native/gen_callframe_json.go index ac3cfc9386c..9a49f0f7cc5 100644 --- a/eth/tracers/native/gen_callframe_json.go +++ b/eth/tracers/native/gen_callframe_json.go @@ -7,6 +7,7 @@ import ( "math/big" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/core/vm" @@ -22,8 +23,8 @@ func (c callFrame) MarshalJSON() ([]byte, error) { Gas hexutil.Uint64 `json:"gas"` GasUsed hexutil.Uint64 `json:"gasUsed"` To libcommon.Address `json:"to,omitempty" rlp:"optional"` - Input hexutil.Bytes `json:"input" rlp:"optional"` - Output hexutil.Bytes `json:"output,omitempty" rlp:"optional"` + Input hexutility.Bytes `json:"input" rlp:"optional"` + Output hexutility.Bytes `json:"output,omitempty" rlp:"optional"` Error string `json:"error,omitempty" rlp:"optional"` Revertal string `json:"revertReason,omitempty"` Calls []callFrame `json:"calls,omitempty" rlp:"optional"` @@ -56,8 +57,8 @@ func (c *callFrame) UnmarshalJSON(input []byte) error { Gas *hexutil.Uint64 `json:"gas"` GasUsed *hexutil.Uint64 `json:"gasUsed"` To *libcommon.Address `json:"to,omitempty" rlp:"optional"` - Input *hexutil.Bytes `json:"input" rlp:"optional"` - Output *hexutil.Bytes `json:"output,omitempty" rlp:"optional"` + Input *hexutility.Bytes `json:"input" rlp:"optional"` + Output *hexutility.Bytes `json:"output,omitempty" rlp:"optional"` Error *string `json:"error,omitempty" rlp:"optional"` Revertal *string `json:"revertReason,omitempty"` Calls []callFrame `json:"calls,omitempty" rlp:"optional"` diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go index 89c497d50a8..3bce65a17d0 100644 --- a/eth/tracers/native/prestate.go +++ b/eth/tracers/native/prestate.go @@ -23,7 +23,9 @@ import ( "sync/atomic" "github.com/holiman/uint256" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/core/vm" @@ -52,7 +54,7 @@ func (a *account) exists() bool { type accountMarshaling struct { Balance *hexutil.Big - Code hexutil.Bytes + Code hexutility.Bytes } type prestateTracer struct { diff --git a/eth/tracers/tracers_test.go b/eth/tracers/tracers_test.go index 6e4deaa2f35..3ec95a9152a 100644 --- a/eth/tracers/tracers_test.go +++ b/eth/tracers/tracers_test.go @@ -24,8 +24,6 @@ import ( "testing" libcommon "github.com/ledgerwatch/erigon-lib/common" - "github.com/ledgerwatch/erigon-lib/kv/memdb" - "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/core/types" @@ -34,6 +32,8 @@ import ( "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/params" "github.com/ledgerwatch/erigon/tests" + "github.com/ledgerwatch/erigon/turbo/stages" + "github.com/stretchr/testify/require" "github.com/holiman/uint256" @@ -80,22 +80,25 @@ func TestPrestateTracerCreate2(t *testing.T) { GasLimit: uint64(6000000), } context.BaseFee = uint256.NewInt(0) - alloc := core.GenesisAlloc{} + alloc := types.GenesisAlloc{} // The code pushes 'deadbeef' into memory, then the other params, and calls CREATE2, then returns // the address - alloc[libcommon.HexToAddress("0x00000000000000000000000000000000deadbeef")] = core.GenesisAccount{ + alloc[libcommon.HexToAddress("0x00000000000000000000000000000000deadbeef")] = types.GenesisAccount{ Nonce: 1, Code: hexutil.MustDecode("0x63deadbeef60005263cafebabe6004601c6000F560005260206000F3"), Balance: big.NewInt(1), } - alloc[origin] = core.GenesisAccount{ + alloc[origin] = types.GenesisAccount{ Nonce: 1, Code: []byte{}, Balance: big.NewInt(500000000000000), } - _, tx := memdb.NewTestTx(t) + m := stages.Mock(t) + tx, err := m.DB.BeginRw(m.Ctx) + require.NoError(t, err) + defer tx.Rollback() rules := params.AllProtocolChanges.Rules(context.BlockNumber, context.Time) statedb, _ := tests.MakePreState(rules, tx, alloc, context.BlockNumber) diff --git a/ethdb/privateapi/ethbackend.go b/ethdb/privateapi/ethbackend.go index ded53ba96b2..7fad85f3f53 100644 --- a/ethdb/privateapi/ethbackend.go +++ b/ethdb/privateapi/ethbackend.go @@ -296,8 +296,57 @@ func (s *EthBackendServer) checkWithdrawalsPresence(time uint64, withdrawals []* return nil } -func (s *EthBackendServer) EngineGetBlobsBundleV1(ctx context.Context, in *remote.EngineGetBlobsBundleRequest) (*types2.BlobsBundleV1, error) { - return nil, fmt.Errorf("EngineGetBlobsBundleV1: not implemented yet") +func (s *EthBackendServer) EngineGetBlobsBundleV1(ctx context.Context, req *remote.EngineGetBlobsBundleRequest) (*types2.BlobsBundleV1, error) { + if !s.proposing { + return nil, fmt.Errorf("execution layer not running as a proposer. enable proposer by taking out the --proposer.disable flag on startup") + } + + if s.config.TerminalTotalDifficulty == nil { + return nil, fmt.Errorf("not a proof-of-stake chain") + } + + log.Debug("[GetBlobsBundleV1] acquiring lock") + s.lock.Lock() + defer s.lock.Unlock() + log.Debug("[GetBlobsBundleV1] lock acquired") + + builder, ok := s.builders[req.PayloadId] + if !ok { + log.Warn("Payload not stored", "payloadId", req.PayloadId) + return nil, &UnknownPayloadErr + } + + block, err := builder.Stop() + if err != nil { + log.Error("Failed to build PoS block", "err", err) + return nil, err + } + + blobsBundle := &types2.BlobsBundleV1{ + BlockHash: gointerfaces.ConvertHashToH256(block.Block.Header().Hash()), + } + for i, tx := range block.Block.Transactions() { + if tx.Type() != types.BlobTxType { + continue + } + blobtx, ok := tx.(*types.BlobTxWrapper) + if !ok { + return nil, fmt.Errorf("expected blob transaction to be type BlobTxWrapper, got: %T", blobtx) + } + versionedHashes, kzgs, blobs, proofs := blobtx.GetDataHashes(), blobtx.BlobKzgs, blobtx.Blobs, blobtx.Proofs + lenCheck := len(versionedHashes) + if lenCheck != len(kzgs) || lenCheck != len(blobs) || lenCheck != len(blobtx.Proofs) { + return nil, fmt.Errorf("tx %d in block %s has inconsistent blobs (%d) / kzgs (%d) / proofs (%d)"+ + " / versioned hashes (%d)", i, block.Block.Hash(), len(blobs), len(kzgs), len(proofs), lenCheck) + } + for _, blob := range blobs { + blobsBundle.Blobs = append(blobsBundle.Blobs, blob[:]) + } + for _, kzg := range kzgs { + blobsBundle.Kzgs = append(blobsBundle.Kzgs, kzg[:]) + } + } + return blobsBundle, nil } // EngineNewPayload validates and possibly executes payload @@ -680,6 +729,7 @@ func (s *EthBackendServer) EngineForkChoiceUpdated(ctx context.Context, req *rem // First check if we're already building a block with the requested parameters if reflect.DeepEqual(s.lastParameters, ¶m) { + log.Info("[ForkChoiceUpdated] duplicate build request") return &remote.EngineForkChoiceUpdatedResponse{ PayloadStatus: &remote.EnginePayloadStatus{ Status: remote.EngineStatus_VALID, @@ -697,7 +747,7 @@ func (s *EthBackendServer) EngineForkChoiceUpdated(ctx context.Context, req *rem s.lastParameters = ¶m s.builders[s.payloadId] = builder.NewBlockBuilder(s.builderFunc, ¶m) - log.Debug("BlockBuilder added", "payload", s.payloadId) + log.Info("[ForkChoiceUpdated] BlockBuilder added", "payload", s.payloadId) return &remote.EngineForkChoiceUpdatedResponse{ PayloadStatus: &remote.EnginePayloadStatus{ diff --git a/go.mod b/go.mod index 4269870df8e..ad80b8b4191 100644 --- a/go.mod +++ b/go.mod @@ -1,18 +1,18 @@ module github.com/ledgerwatch/erigon -go 1.18 +go 1.19 require ( - github.com/ledgerwatch/erigon-lib v0.0.0-20230328191829-416af23d9dcd + github.com/ledgerwatch/erigon-lib v0.0.0-20230330024812-ae99e29d013b github.com/ledgerwatch/erigon-snapshot v1.1.1-0.20230306083105-1391330d62a3 github.com/ledgerwatch/log/v3 v3.7.0 github.com/ledgerwatch/secp256k1 v1.0.0 github.com/ledgerwatch/trackerslist v1.1.0 // indirect - github.com/torquem-ch/mdbx-go v0.27.8 + github.com/torquem-ch/mdbx-go v0.27.10 ) require ( - github.com/99designs/gqlgen v0.17.25 + github.com/99designs/gqlgen v0.17.27 github.com/Giulio2002/bls v0.0.0-20230217173148-c87a29266b6c github.com/RoaringBitmap/roaring v1.2.3 github.com/VictoriaMetrics/fastcache v1.12.1 @@ -20,55 +20,63 @@ require ( github.com/anacrolix/sync v0.4.0 github.com/anacrolix/torrent v1.48.1-0.20230219022425-e8971ea0f1bf github.com/benesch/cgosymbolizer v0.0.0-20190515212042-bec6fe6e597b + github.com/bnb-chain/ics23 v0.1.0 github.com/btcsuite/btcd v0.22.0-beta - github.com/btcsuite/btcd/btcec/v2 v2.2.1 + github.com/btcsuite/btcd/btcec/v2 v2.3.2 github.com/c2h5oh/datasize v0.0.0-20220606134207-859f65c6625b - github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f + github.com/cometbft/cometbft v0.37.1 + github.com/consensys/gnark-crypto v0.10.0 github.com/crate-crypto/go-ipa v0.0.0-20221111143132-9aa5d42120bc + github.com/crate-crypto/go-kzg-4844 v0.0.0-20230405223534-4364e2f9d209 github.com/davecgh/go-spew v1.1.1 github.com/deckarep/golang-set v1.8.0 - github.com/deckarep/golang-set/v2 v2.1.0 - github.com/docker/docker v20.10.17+incompatible - github.com/dop251/goja v0.0.0-20220405120441-9037c2b61cbf + github.com/deckarep/golang-set/v2 v2.3.0 + github.com/docker/docker v20.10.19+incompatible + github.com/dop251/goja v0.0.0-20230122112309-96b1610dd4f7 github.com/edsrzf/mmap-go v1.1.0 github.com/emicklei/dot v1.0.0 github.com/emirpasic/gods v1.18.1 github.com/fjl/gencodec v0.0.0-20220412091415-8bb9e558978c github.com/gballet/go-verkle v0.0.0-20221121182333-31427a1f2d35 - github.com/goccy/go-json v0.9.7 + github.com/goccy/go-json v0.9.11 github.com/gofrs/flock v0.8.1 github.com/golang-jwt/jwt/v4 v4.5.0 github.com/golang/mock v1.6.0 github.com/golang/snappy v0.0.4 github.com/google/btree v1.1.2 - github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa + github.com/google/gofuzz v1.2.0 github.com/gorilla/websocket v1.5.0 - github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 + github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d - github.com/hashicorp/golang-lru/v2 v2.0.1 - github.com/holiman/uint256 v1.2.1 + github.com/hashicorp/golang-lru/v2 v2.0.2 + github.com/holiman/uint256 v1.2.2 github.com/huandu/xstrings v1.4.0 github.com/huin/goupnp v1.1.0 github.com/jackpal/go-nat-pmp v1.0.2 github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/kevinburke/go-bindata v3.21.0+incompatible - github.com/libp2p/go-libp2p v0.25.1 - github.com/libp2p/go-libp2p-pubsub v0.9.1-0.20230221111042-3dbc2fd5baca + github.com/libp2p/go-libp2p v0.26.2 + github.com/libp2p/go-libp2p-pubsub v0.9.3 github.com/maticnetwork/crand v1.0.2 github.com/maticnetwork/polyproto v0.0.2 + github.com/minio/sha256-simd v1.0.0 github.com/multiformats/go-multiaddr v0.8.0 github.com/nxadm/tail v1.4.9-0.20211216163028-4472660a31a6 github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 github.com/pelletier/go-toml v1.9.5 github.com/pelletier/go-toml/v2 v2.0.7 github.com/pion/stun v0.4.0 + github.com/pkg/errors v0.9.1 + github.com/prometheus/client_golang v1.14.0 github.com/protolambda/eth2-shuffle v1.1.0 - github.com/prysmaticlabs/fastssz v0.0.0-20220628121656-93dfe28febab + github.com/protolambda/ztyp v0.2.2 github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7 github.com/prysmaticlabs/gohashtree v0.0.2-alpha + github.com/prysmaticlabs/prysm/v4 v4.0.3 github.com/quasilyte/go-ruleguard/dsl v0.3.22 github.com/rs/cors v1.8.3 + github.com/shirou/gopsutil/v3 v3.23.3 github.com/spf13/cobra v1.6.1 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.8.2 @@ -78,24 +86,25 @@ require ( github.com/tidwall/btree v1.6.0 github.com/ugorji/go/codec v1.1.13 github.com/ugorji/go/codec/codecgen v1.1.13 - github.com/urfave/cli/v2 v2.24.4 + github.com/urfave/cli/v2 v2.25.0 github.com/valyala/fastjson v1.6.4 github.com/vektah/gqlparser/v2 v2.5.1 + github.com/willf/bitset v1.1.10 github.com/xsleonard/go-merkle v1.1.0 - go.uber.org/atomic v1.10.0 go.uber.org/zap v1.24.0 - golang.org/x/crypto v0.6.0 - golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 - golang.org/x/net v0.7.0 + golang.org/x/crypto v0.8.0 + golang.org/x/exp v0.0.0-20230321023759-10a507213a29 + golang.org/x/net v0.9.0 golang.org/x/sync v0.1.0 - golang.org/x/sys v0.5.0 + golang.org/x/sys v0.7.0 golang.org/x/time v0.3.0 - google.golang.org/grpc v1.53.0 - google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0 - google.golang.org/protobuf v1.28.1 + google.golang.org/grpc v1.54.0 + google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 + google.golang.org/protobuf v1.30.0 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c + gopkg.in/natefinch/lumberjack.v2 v2.2.1 gopkg.in/yaml.v2 v2.4.0 - modernc.org/sqlite v1.21.0 + modernc.org/sqlite v1.21.1 pgregory.net/rapid v0.5.5 ) @@ -112,7 +121,7 @@ require ( github.com/anacrolix/log v0.13.2-0.20221123232138-02e2764801c3 // indirect github.com/anacrolix/missinggo v1.3.0 // indirect github.com/anacrolix/missinggo/perf v1.0.0 // indirect - github.com/anacrolix/missinggo/v2 v2.7.0 // indirect + github.com/anacrolix/missinggo/v2 v2.7.1 // indirect github.com/anacrolix/mmsg v1.0.0 // indirect github.com/anacrolix/multiless v0.3.0 // indirect github.com/anacrolix/stm v0.4.0 // indirect @@ -122,35 +131,45 @@ require ( github.com/benbjohnson/clock v1.3.0 // indirect github.com/benbjohnson/immutable v0.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bits-and-blooms/bitset v1.2.2 // indirect + github.com/bits-and-blooms/bitset v1.5.0 // indirect github.com/bradfitz/iter v0.0.0-20191230175014-e8f45d346db8 // indirect + github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/consensys/bavard v0.1.13 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect + github.com/cosmos/gogoproto v1.4.1 // 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/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 // 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.1 // indirect github.com/elastic/gosigar v0.14.2 // indirect + github.com/ethereum/go-ethereum v1.11.3 // 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.5.4 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/garslo/gogen v0.0.0-20170307003452-d6ebae628c7c // indirect - github.com/go-kit/kit v0.10.0 // indirect + github.com/go-kit/kit v0.12.0 // indirect + github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect github.com/go-stack/stack v1.8.1 // 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/protobuf v1.5.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/google/gopacket v1.1.19 // indirect github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect github.com/google/uuid v1.3.0 // indirect + github.com/gtank/merlin v0.1.1 // indirect + github.com/herumi/bls-eth-go-binary v0.0.0-20210917013441-d37c07cfda4e // indirect github.com/ianlancetaylor/cgosymbolizer v0.0.0-20220405231054-a1ae3e4bba26 // indirect github.com/inconshreveable/mousetrap v1.0.1 // indirect github.com/ipfs/go-cid v0.3.2 // indirect @@ -173,7 +192,7 @@ require ( github.com/libp2p/go-reuseport v0.2.0 // indirect github.com/libp2p/go-yamux/v4 v4.0.0 // indirect github.com/lispad/go-generics-tools v1.1.0 // indirect - github.com/magiconair/properties v1.8.6 // indirect + github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.17 // indirect @@ -181,10 +200,12 @@ require ( 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/sha256-simd v1.0.0 // indirect + github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mmcloughlin/addchain v0.4.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/mschoch/smat v0.2.0 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect @@ -198,6 +219,7 @@ require ( github.com/multiformats/go-varint v0.0.7 // indirect github.com/onsi/ginkgo/v2 v2.8.0 // indirect github.com/opencontainers/runtime-spec v1.0.2 // indirect + github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect github.com/pion/datachannel v1.5.2 // indirect github.com/pion/dtls/v2 v2.2.4 // indirect github.com/pion/ice/v2 v2.2.6 // indirect @@ -215,38 +237,47 @@ require ( github.com/pion/turn/v2 v2.0.8 // indirect github.com/pion/udp v0.1.4 // indirect github.com/pion/webrtc/v3 v3.1.42 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_golang v1.14.0 // indirect + github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.39.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect + github.com/prysmaticlabs/eth2-types v0.0.0-20210303084904-c9735a06829d // indirect + github.com/prysmaticlabs/fastssz v0.0.0-20220628121656-93dfe28febab // indirect + github.com/prysmaticlabs/prysm v0.0.0-20220124113610-e26cde5e091b // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/qtls-go1-18 v0.2.0 // indirect - github.com/quic-go/qtls-go1-19 v0.2.0 // indirect - github.com/quic-go/qtls-go1-20 v0.1.0 // indirect - github.com/quic-go/quic-go v0.32.0 // indirect - github.com/quic-go/webtransport-go v0.5.1 // indirect + github.com/quic-go/qtls-go1-19 v0.2.1 // indirect + github.com/quic-go/qtls-go1-20 v0.1.1 // indirect + github.com/quic-go/quic-go v0.33.0 // indirect + github.com/quic-go/webtransport-go v0.5.2 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect + github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/rogpeppe/go-internal v1.9.0 // indirect github.com/rs/dnscache v0.0.0-20211102005908-e0241e321417 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/sasha-s/go-deadlock v0.3.1 // indirect + github.com/shoenig/go-m1cpu v0.1.4 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/supranational/blst v0.3.10 // indirect + github.com/tklauser/go-sysconf v0.3.11 // indirect + github.com/tklauser/numcpus v0.6.0 // indirect github.com/valyala/fastrand v1.1.0 // indirect github.com/valyala/histogram v1.2.0 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect + github.com/yusufpapurcu/wmi v1.2.2 // indirect go.etcd.io/bbolt v1.3.6 // indirect - go.opentelemetry.io/otel v1.8.0 // indirect - go.opentelemetry.io/otel/trace v1.8.0 // indirect + go.opentelemetry.io/otel v1.11.0 // indirect + go.opentelemetry.io/otel/trace v1.11.0 // indirect + go.uber.org/atomic v1.10.0 // indirect go.uber.org/dig v1.16.1 // indirect go.uber.org/fx v1.19.1 // indirect go.uber.org/multierr v1.9.0 // indirect - golang.org/x/mod v0.8.0 // indirect - golang.org/x/text v0.7.0 // indirect - golang.org/x/tools v0.6.0 // indirect - google.golang.org/genproto v0.0.0-20230202175211-008b39050e57 // indirect + golang.org/x/mod v0.9.0 // indirect + golang.org/x/text v0.9.0 // indirect + golang.org/x/tools v0.7.0 // indirect + google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.3.0 // indirect @@ -261,6 +292,11 @@ require ( modernc.org/strutil v1.1.3 // indirect modernc.org/token v1.1.0 // indirect nhooyr.io/websocket v1.8.7 // indirect + rsc.io/tmplfunc v0.0.3 // indirect ) -replace github.com/tendermint/tendermint => github.com/bnb-chain/tendermint v0.31.12 +replace ( + github.com/cometbft/cometbft => github.com/bnb-chain/greenfield-tendermint v0.0.0-20230417032003-4cda1f296fb2 + github.com/ledgerwatch/erigon-lib => github.com/chainstack/erigon-lib v0.0.0-20230426134128-a2ae5fb02bbb + github.com/tendermint/tendermint => github.com/bnb-chain/tendermint v0.31.15 +) diff --git a/go.sum b/go.sum index 24662fefc07..704fa191da5 100644 --- a/go.sum +++ b/go.sum @@ -1,41 +1,107 @@ +cloud.google.com/go v0.16.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 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= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/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/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= +contrib.go.opencensus.io/exporter/jaeger v0.2.1/go.mod h1:Y8IsLgdxqh1QxYxPC5IgXVmBaeLUeQFfBeBi9PbeZd0= crawshaw.io/iox v0.0.0-20181124134642-c51c3df30797 h1:yDf7ARQc637HoxDho7xjqdvO5ZA2Yb+xzv/fOnnvZzw= crawshaw.io/iox v0.0.0-20181124134642-c51c3df30797/go.mod h1:sXBiorCo8c46JlQV3oXPKINnZ8mcqnye1EkVkqsectk= crawshaw.io/sqlite v0.3.2/go.mod h1:igAO5JulrQ1DbdZdtVq48mnZUBAPOeFzer7VhDWNtW4= crawshaw.io/sqlite v0.3.3-0.20220618202545-d1964889ea3c h1:wvzox0eLO6CKQAMcOqz7oH3UFqMpMmK7kwmwV+22HIs= crawshaw.io/sqlite v0.3.3-0.20220618202545-d1964889ea3c/go.mod h1:igAO5JulrQ1DbdZdtVq48mnZUBAPOeFzer7VhDWNtW4= 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= filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU= git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= -github.com/99designs/gqlgen v0.17.25 h1:5CAocr5i+dqY0lUR+Xu0InU81Ax/g+xsxKwOU8Glqy0= -github.com/99designs/gqlgen v0.17.25/go.mod h1:i4rEatMrzzu6RXaHydq1nmEPZkb3bKQsnxNRHS4DQB4= +github.com/99designs/gqlgen v0.17.27 h1:XPsaZiWY1lL2qqVYtBt37GzkyX7bBiVvda7k1buC/Ao= +github.com/99designs/gqlgen v0.17.27/go.mod h1:i4rEatMrzzu6RXaHydq1nmEPZkb3bKQsnxNRHS4DQB4= +github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= +github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc= +github.com/Azure/azure-storage-blob-go v0.7.0/go.mod h1:f9YQKtsG1nMisotuTPpO0tjNuEjKRYAcJU8/ydDI++4= +github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= +github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= +github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= +github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= +github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= +github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +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/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d h1:nalkkPQcITbvhmL4+C4cKA87NW0tfm3Kl9VXRoPywFg= +github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/Giulio2002/bls v0.0.0-20230217173148-c87a29266b6c h1:Die1JC9Eiec1trMccXTTVgdE11KYHPec1Z76AP3bSlE= github.com/Giulio2002/bls v0.0.0-20230217173148-c87a29266b6c/go.mod h1:o6qWofeW8A1XImbo3eHbC/wXnw/dasu0YuHEtdrjYzw= 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/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/RoaringBitmap/roaring v0.4.7/go.mod h1:8khRDP4HmeXns4xIj9oGrKSz7XTQiJx2zgh7AcNke4w= github.com/RoaringBitmap/roaring v0.4.17/go.mod h1:D3qVegWTmfCaX4Bl5CrBE9hfrSrrXIr8KVNvRsDi1NI= github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo= github.com/RoaringBitmap/roaring v1.2.3 h1:yqreLINqIrX22ErkKI0vY47/ivtJr6n+kMhVOVmhWBY= github.com/RoaringBitmap/roaring v1.2.3/go.mod h1:plvDsJQpxOC5bw8LRteu/MLWHsHez/3y6cubLI4/1yE= 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/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw= github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= github.com/VictoriaMetrics/metrics v1.23.1 h1:/j8DzeJBxSpL2qSIdqnRFLvQQhbJyJbbEi22yMm7oL0= github.com/VictoriaMetrics/metrics v1.23.1/go.mod h1:rAr/llLpEnAdTehiNlUxKgnjcOuROSzpw0GvjpEbvFc= +github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= +github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/ajwerner/btree v0.0.0-20211221152037-f427b3e689c0 h1:byYvvbfSo3+9efR4IeReh77gVs4PnNDR3AMOE9NJ7a0= github.com/ajwerner/btree v0.0.0-20211221152037-f427b3e689c0/go.mod h1:q37NoqncT41qKc048STsifIt69LfUJ8SrWWcz/yam5k= github.com/alecthomas/assert/v2 v2.0.0-alpha3 h1:pcHeMvQ3OMstAWgaeaXIAL8uzB9xMm2zlxt+/4ml8lk= @@ -46,8 +112,10 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= 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/anacrolix/chansync v0.3.0 h1:lRu9tbeuw3wl+PhMu/r+JJCRu5ArFXIluOgdF0ao6/U= github.com/anacrolix/chansync v0.3.0/go.mod h1:DZsatdsdXxD0WiwcGl0nJVwyjCKMDv+knl1q2iBjA2k= github.com/anacrolix/dht/v2 v2.19.2-0.20221121215055-066ad8494444 h1:8V0K09lrGoeT2KRJNOtspA7q+OMxGwQqK/Ug0IiaaRE= @@ -80,8 +148,8 @@ github.com/anacrolix/missinggo/perf v1.0.0/go.mod h1:ljAFWkBuzkO12MQclXzZrosP5ur github.com/anacrolix/missinggo/v2 v2.2.0/go.mod h1:o0jgJoYOyaoYQ4E2ZMISVa9c88BbUBVQQW4QeRkNCGY= github.com/anacrolix/missinggo/v2 v2.5.1/go.mod h1:WEjqh2rmKECd0t1VhQkLGTdIWXO6f6NLjp5GlMZ+6FA= github.com/anacrolix/missinggo/v2 v2.5.2/go.mod h1:yNvsLrtZYRYCOI+KRH/JM8TodHjtIE/bjOGhQaLOWIE= -github.com/anacrolix/missinggo/v2 v2.7.0 h1:4fzOAAn/VCvfWGviLmh64MPMttrlYew81JdPO7nSHvI= -github.com/anacrolix/missinggo/v2 v2.7.0/go.mod h1:2IZIvmRTizALNYFYXsPR7ofXPzJgyBpKZ4kMqMEICkI= +github.com/anacrolix/missinggo/v2 v2.7.1 h1:Y+wL0JC6D2icpwhDpcrRM4THQB/uFcPNYUtZMbYvQgI= +github.com/anacrolix/missinggo/v2 v2.7.1/go.mod h1:2IZIvmRTizALNYFYXsPR7ofXPzJgyBpKZ4kMqMEICkI= github.com/anacrolix/mmsg v0.0.0-20180515031531-a4a3ba1fc8bb/go.mod h1:x2/ErsYUmT77kezS63+wzZp8E3byYB0gzirM/WMBLfw= github.com/anacrolix/mmsg v1.0.0 h1:btC7YLjOn29aTUAExJiVUhQOuf/8rhm+/nWCMAnL3Hg= github.com/anacrolix/mmsg v1.0.0/go.mod h1:x8kRaJY/dCrY9Al0PEcj1mb/uFHwP6GCJ9fLl4thEPc= @@ -106,19 +174,39 @@ github.com/anacrolix/utp v0.1.0/go.mod h1:MDwc+vsGEq7RMw6lr2GKOEqjWny5hO5OZXRVNa github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= 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/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= +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-20200521140103-6c3304613b30/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/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= 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/go.mod h1:zEQs02YRBw1DjK0PoJv3ygDYOFTre1ejlJWl8FwAuQo= +github.com/aws/aws-sdk-go-v2/config v1.1.1/go.mod h1:0XsVy9lBI/BCXm+2Tuvt39YmdHwS5unDQmxZOYe8F5Y= +github.com/aws/aws-sdk-go-v2/credentials v1.1.1/go.mod h1:mM2iIjwl7LULWtS6JCACyInboHirisUUdkBPoTHMOUo= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.0.2/go.mod h1:3hGg3PpiEjHnrkrlasTfxFqUsZ2GCk/fMUn4CbKgSkM= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.0.2/go.mod h1:45MfaXZ0cNbeuT0KQ1XJylq8A6+OpVV2E5kvY/Kq+u8= +github.com/aws/aws-sdk-go-v2/service/route53 v1.1.1/go.mod h1:rLiOUrPLW/Er5kRcQ7NkwbjlijluLsrIbu/iyl35RO4= +github.com/aws/aws-sdk-go-v2/service/sso v1.1.1/go.mod h1:SuZJxklHxLAXgLTc1iFXbEWkXs7QRTQpCLGaKIprQW0= +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/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= +github.com/bazelbuild/rules_go v0.23.2 h1:Wxu7JjqnF78cKZbsBsARLSXx/jlGaSLCnUV3mTlyHvM= +github.com/bazelbuild/rules_go v0.23.2/go.mod h1:MC23Dc/wkXEyk3Wpq6lCqz0ZAYOZDw2DR5y3N1q2i7M= +github.com/benbjohnson/clock v1.0.2/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= +github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= 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= @@ -133,23 +221,35 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= -github.com/bits-and-blooms/bitset v1.2.2 h1:J5gbX05GpMdBjCvQ9MteIg2KKDExr7DrgK+Yc15FvIk= -github.com/bits-and-blooms/bitset v1.2.2/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= -github.com/bnb-chain/tendermint v0.31.12 h1:g+blWaXkRw6iHa56lcRfRzPXHgURCWPmgIvaGBSV7Zc= -github.com/bnb-chain/tendermint v0.31.12/go.mod h1:j6XU7CArrhQ+9XBMRwdIz63iUxdVwSrZ8f7vP7gcCqg= +github.com/bits-and-blooms/bitset v1.5.0 h1:NpE8frKRLGHIcEzkR+gZhiioW1+WbYV6fKwD6ZIpQT8= +github.com/bits-and-blooms/bitset v1.5.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= +github.com/bnb-chain/greenfield-tendermint v0.0.0-20230417032003-4cda1f296fb2 h1:jubavYCs/mCFj/g6Utl+l4SfpykdBdWJFPsvb9FcEXU= +github.com/bnb-chain/greenfield-tendermint v0.0.0-20230417032003-4cda1f296fb2/go.mod h1:9q11eHNRY9FDwFH+4pompzPNGv//Z3VcfvkELaHJPMs= +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/bradfitz/gomemcache v0.0.0-20170208213004-1952afaa557d/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60= github.com/bradfitz/iter v0.0.0-20140124041915-454541ec3da2/go.mod h1:PyRFw1Lt2wKX4ZVSQ2mk+PeDa1rxyObEDlApuIsUKuo= github.com/bradfitz/iter v0.0.0-20190303215204-33e6a9893b0c/go.mod h1:PyRFw1Lt2wKX4ZVSQ2mk+PeDa1rxyObEDlApuIsUKuo= github.com/bradfitz/iter v0.0.0-20191230175014-e8f45d346db8 h1:GKTyiRCL6zVf5wWaqKnf+7Qs6GbEPfd4iMOitWzXJx8= github.com/bradfitz/iter v0.0.0-20191230175014-e8f45d346db8/go.mod h1:spo1JLcs67NmW1aVLEgtA8Yy1elc+X8y5SRW1sFW4Og= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= +github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94= github.com/btcsuite/btcd v0.22.0-beta h1:LTDpDKUM5EeOFBPM8IXpinEcmZ6FWfNZbE3lfrfdnWo= github.com/btcsuite/btcd v0.22.0-beta/go.mod h1:9n5ntfhhHQBIhUvlhDvD3Qg6fRUj4jkN0VB8L8svzOA= -github.com/btcsuite/btcd/btcec/v2 v2.2.1 h1:xP60mv8fvp+0khmrN0zTdPC3cNm24rfeE6lh2R/Yv3E= -github.com/btcsuite/btcd/btcec/v2 v2.2.1/go.mod h1:9/CSmJxmuvqzX9Wh2fXMWToLOHhPd11lSPuIupwTkI8= +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/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= +github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= @@ -159,114 +259,197 @@ github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= 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/c2h5oh/datasize v0.0.0-20220606134207-859f65c6625b h1:6+ZFm0flnudZzdSE0JxlhR2hKnGPcNB35BjQf4RYQDY= github.com/c2h5oh/datasize v0.0.0-20220606134207-859f65c6625b/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M= 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/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= +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.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chainstack/erigon-lib v0.0.0-20230426134128-a2ae5fb02bbb h1:xOy4O4wUIxgjpgmt06nQ/OKGKzvVxzMSls2Gys5ssaQ= +github.com/chainstack/erigon-lib v0.0.0-20230426134128-a2ae5fb02bbb/go.mod h1:D05f9OXc/2cnYxCyBexlu5HeIeQW9GKXynyWYzJ1F5I= +github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/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/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/cometbft/cometbft-db v0.7.0 h1:uBjbrBx4QzU0zOEnU8KxoDl18dMNgDh+zZRUE0ucsbo= 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/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= +github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q= +github.com/consensys/gnark-crypto v0.10.0 h1:zRh22SR7o4K35SoNqouS9J/TKHTyU2QWaj5ldehyXtA= +github.com/consensys/gnark-crypto v0.10.0/go.mod h1:Iq/P3HHl0ElSjsg2E1gsMwhAyxnxoKK5nVyZKd+/KhU= github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= 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-20191104093116-d3cd4ed1dbcf/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/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d h1:49RLWk1j44Xu4fjHb6JFYmeUnDORVwHNkDxaQ0ctCVU= +github.com/cosmos/gogoproto v1.4.1 h1:WoyH+0/jbCTzpKNvyav5FL1ZTWsp1im1MxEpJEzKUB8= +github.com/cosmos/gogoproto v1.4.1/go.mod h1:Ac9lzL4vFpBMcptJROQ6dQ4M3pOEK5Z/l0Q9p+LoCr4= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= 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/crate-crypto/go-ipa v0.0.0-20221111143132-9aa5d42120bc h1:mtR7MuscVeP/s0/ERWA2uSr5QOrRYy1pdvZqG1USfXI= github.com/crate-crypto/go-ipa v0.0.0-20221111143132-9aa5d42120bc/go.mod h1:gFnFS95y8HstDP6P9pPwzrxOOC5TRDkwbM+ao15ChAI= +github.com/crate-crypto/go-kzg-4844 v0.0.0-20230405223534-4364e2f9d209 h1:OnTdosxWDRxchZa7uOT8zz1sm3TZQdCiqtj69wYGnH8= +github.com/crate-crypto/go-kzg-4844 v0.0.0-20230405223534-4364e2f9d209/go.mod h1:bsF9NlLDLBdRmnU0hiImPGjwoDSrjLRXKAP9vVT6IsI= +github.com/creachadair/taskgroup v0.3.2 h1:zlfutDS+5XG40AOxcHDSThxKzns8Tnr9jnr6VqkYlkM= 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/d4l3k/messagediff v1.2.1/go.mod h1:Oozbb1TVXFac9FtSIxHBMnBCq2qeH/2KkEQxENCrlLo= +github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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-20170701192655-dcfb0a7ac018/go.mod h1:rQYf4tfk5sSwFsnDg3qYaBxSjsD9S8+59vW0dKUgme4= 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 v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= +github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4= github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= -github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= -github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/deckarep/golang-set/v2 v2.3.0 h1:qs18EKUfHm2X9fA50Mr/M5hccg2tNnVqsiBImnyDs0g= +github.com/deckarep/golang-set/v2 v2.3.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= 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/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= +github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= +github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= +github.com/dgraph-io/badger v1.6.1/go.mod h1:FRmFw3uxvcpa8zG3Rxs0th+hCLIuaQg8HlNV5bjgnuU= +github.com/dgraph-io/badger v1.6.2 h1:mNw0qs90GVgGGWylh0umH5iag1j6n/PeJtNvL6KY/x8= +github.com/dgraph-io/badger v1.6.2/go.mod h1:JW2yswe3V058sS0kZ2h/AXeDSqFjxnZcRrVH//y2UQE= +github.com/dgraph-io/badger/v2 v2.2007.4 h1:TRWBQg8UrlUhaFdco01nO2uXwzKS7zd+HVdwV/GHc4o= +github.com/dgraph-io/ristretto v0.0.2/go.mod h1:KPxhHT9ZxKefz+PCeOGsrHpl1qZ7i70dGTu2u+Ahh6E= +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/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/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g= github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= -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/docker/docker v20.10.17+incompatible h1:JYCuMrWaVNophQTOrMMoSwudOVEfcegoZZrleKc1xwE= -github.com/docker/docker v20.10.17+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +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.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.19+incompatible h1:lzEmjivyNHFHMNAFLXORMBXyGIhw/UP4DvJwvyKYq64= +github.com/docker/docker v20.10.19+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= 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/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -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/dop251/goja v0.0.0-20211011172007-d99e4b8cbf48/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= +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 v0.0.0-20180421182945-02af3965c54e/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= 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/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/dot v0.11.0/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s= github.com/emicklei/dot v1.0.0 h1:yyObALINBOuI1GdCRwVea2IPtGtVgh0NQgJDrE03Tqc= github.com/emicklei/dot v1.0.0/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s= +github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 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.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/ethereum/go-ethereum v1.10.13/go.mod h1:W3yfrFyL9C1pHcwY5hmRHVDaorTiQxhYBkKyu5mEDHw= +github.com/ethereum/go-ethereum v1.11.3 h1:uuBkYUJW9aY5JYi3+sqLHz+XWyo5fmn/ab9XcbtVDTU= +github.com/ethereum/go-ethereum v1.11.3/go.mod h1:rBUvAl5cdVrAei9q5lgOU7RSEuPJk1nlBDnS/YSoKQE= +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/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +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/gencodec v0.0.0-20220412091415-8bb9e558978c h1:CndMRAH4JIwxbW8KYq6Q+cGWcGHz0FjGR3QqcInWcW0= github.com/fjl/gencodec v0.0.0-20220412091415-8bb9e558978c/go.mod h1:AzA8Lj6YtixmJWL+wkKoBGsLWy9gFrAzi4g+5bCKwpY= +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/frankban/quicktest v1.9.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.4.3-0.20170329110642-4da3e2cfbabc/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= -github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= -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/garslo/gogen v0.0.0-20170307003452-d6ebae628c7c h1:uYNKzPntb8c6DKvP9EfrBjkLkU7pM4lM+uuHSIa8UtU= github.com/garslo/gogen v0.0.0-20170307003452-d6ebae628c7c/go.mod h1:Q0X6pkwTILDlzrGEckF6HKjXe48EgsY/l7K7vhY4MW8= +github.com/garyburd/redigo v1.1.1-0.20170914051019-70e1b1943d4f/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= +github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= +github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= +github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/gballet/go-verkle v0.0.0-20221121182333-31427a1f2d35 h1:I8QswD9gf3VEpr7bpepKKOm7ChxFITIG+oc1I5/S0no= github.com/gballet/go-verkle v0.0.0-20221121182333-31427a1f2d35/go.mod h1:DMDd04jjQgdynaAwbEgiRERIGpC8fDjx0+y06an7Psg= +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/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= @@ -279,50 +462,75 @@ github.com/glycerine/go-unsnap-stream v0.0.0-20190901134440-81cf024a9e0a/go.mod github.com/glycerine/goconvey v0.0.0-20180728074245-46e3a41ad493/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= github.com/glycerine/goconvey v0.0.0-20190315024820-982ee783a72e/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= +github.com/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/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= +github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4= +github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= +github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= 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 v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/logr v0.2.1/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.2.2/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-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= +github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +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/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= +github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= 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.6.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 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/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM= -github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk= +github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= 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.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gofrs/uuid v3.3.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= @@ -330,66 +538,113 @@ github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zV 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 v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/golang/gddo v0.0.0-20200528160355-8d077c1d8f4c/go.mod h1:sam69Hju0uq+5uvLJUMDlsKlQ21Vrs1Kd/1YFPNYdOU= +github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/lint v0.0.0-20170918230701-e5d664eb928e/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= 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= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/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= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 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= +github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= github.com/google/btree v0.0.0-20180124185431-e89373fe6b4a/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/go-cmp v0.1.1-0.20171103154506-982329095285/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.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.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 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.1-0.20200604201612-c04b05f3adfa h1:Q75Upo5UN4JbPFURXZ8nLKYUvF85dyFRop/vQ0Rv+64= +github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/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/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U= github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +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.1.5/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/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190309154008-847fc94819f9/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= @@ -397,20 +652,35 @@ github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99/go.mod h1:wJfORR 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/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +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 v0.0.0-20201113091052-beb923fada29/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= +github.com/gregjones/httpcache v0.0.0-20170920190843-316c5e0ff04e/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= 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.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= +github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= +github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= +github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.0.1/go.mod h1:oVMjMN64nzEcepv1kdZKgx1qNYt4Ro0Gqefiq2JWdis= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 h1:BZHcxBETFHIdVyhyEfOvn/RdU/QGdLI4y34qQGjGWO0= +github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is= +github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s= +github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= 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/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= @@ -420,21 +690,30 @@ github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerX 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.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/golang-lru/v2 v2.0.1 h1:5pv5N1lT1fjLg2VQ5KWc7kmucp2x/kvFOnxuVTqZ6x4= -github.com/hashicorp/golang-lru/v2 v2.0.1/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/hashicorp/golang-lru/v2 v2.0.2 h1:Dwmkdr5Nc/oBiXgJS3CDHNhJtIHkuZ3DZF5twqnfBdU= +github.com/hashicorp/golang-lru/v2 v2.0.2/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/hashicorp/hcl v0.0.0-20170914154624-68e816d1c783/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= +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/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= -github.com/holiman/uint256 v1.2.1 h1:XRtyuda/zw2l+Bq/38n5XUoEF72aSOu/77Thd9pPp2o= -github.com/holiman/uint256 v1.2.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= +github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= +github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= +github.com/holiman/uint256 v1.2.2 h1:TXKcSGc2WaxPD2+bmzAsVthL4+pEN0YwXcL5qED83vk= +github.com/holiman/uint256 v1.2.2/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo= github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= @@ -445,61 +724,140 @@ github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= 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.2/go.mod h1:0dxJBVBHqTMjIUMkESDTNgOOx/Mw5wYIfyFmdzSamkM= github.com/huin/goupnp v1.1.0 h1:gEe0Dp/lZmPZiDFzJJaOfUpOvv2MKUkoBX8lDrn9vKU= github.com/huin/goupnp v1.1.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/ianlancetaylor/cgosymbolizer v0.0.0-20200424224625-be1b05b0b279/go.mod h1:a5aratAVTWyz+nJMmDsN8O4XTfaLfdAsB1ysCmZX5Bw= github.com/ianlancetaylor/cgosymbolizer v0.0.0-20220405231054-a1ae3e4bba26 h1:UT3hQ6+5hwqUT83cKhKlY5I0W/kqsl6lpn3iFb3Gtqs= github.com/ianlancetaylor/cgosymbolizer v0.0.0-20220405231054-a1ae3e4bba26/go.mod h1:DvXTE/K/RtHehxU8/GtDs4vFtfw64jJ3PaCnFri8CRg= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/inconshreveable/log15 v0.0.0-20170622235902-74a0988b5f80/go.mod h1:cOaXtrgN4ScfRrD9Bre7U1thNq5RtJ8ZoP4iXVGRj6o= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY= +github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI= +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= +github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= +github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19ybifQhZoQNF5D8= +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.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= +github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= +github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= 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-datastore v0.4.1/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= +github.com/ipfs/go-datastore v0.4.4/go.mod h1:SX/xMIKoCszPqp+z9JhPYCmoOoXTvaa13XEbGtsFUhA= +github.com/ipfs/go-datastore v0.5.0/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk= 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-ds-badger v0.2.3/go.mod h1:pEYw0rgg3FIrywKKnL+Snr+w/LjJZVMTBRn4FS6UHUk= +github.com/ipfs/go-ds-badger v0.3.0/go.mod h1:1ke6mXNqeV8K3y5Ak2bAA0osoTfmxUdupVCGm4QUIek= +github.com/ipfs/go-ds-leveldb v0.4.2/go.mod h1:jpbku/YqBSsBc1qgME8BkWS4AxzF2cEu1Ii2r79Hh9s= +github.com/ipfs/go-ds-leveldb v0.5.0/go.mod h1:d3XG9RUDzQ6V4SHi8+Xgj9j1XuEk1z82lquxrVbml/Q= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk= +github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A= +github.com/ipfs/go-log v1.0.4/go.mod h1:oDCg2FkjogeFOhqqb+N39l2RpTNPL6F/StPkB3kPgcs= +github.com/ipfs/go-log v1.0.5/go.mod h1:j0b8ZoR+7+R99LD9jZ6+AJsrzkPbSXbZfGakb5JPtIo= +github.com/ipfs/go-log/v2 v2.0.2/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= +github.com/ipfs/go-log/v2 v2.0.3/go.mod h1:O7P1lJt27vWHhOwQmcFEvlmo49ry2VY2+JfBWFaa9+0= +github.com/ipfs/go-log/v2 v2.0.5/go.mod h1:eZs4Xt4ZUJQFM3DlanGhy7TkwwawCZcSByscwkWG+dw= +github.com/ipfs/go-log/v2 v2.1.1/go.mod h1:2v2nsGfZsvvAJz13SyFzf9ObaqwHiHxsPLEHntrv9KM= +github.com/ipfs/go-log/v2 v2.1.3/go.mod h1:/8d0SH3Su5Ooc31QlL1WysJhvyOTDCjcCZ9Axpmri6g= +github.com/ipfs/go-log/v2 v2.3.0/go.mod h1:QqGoj30OTpnKaG/LKTGTxoP2mmQtjVMEnK72gynbe/g= +github.com/ipfs/go-log/v2 v2.4.0/go.mod h1:nPZnh7Cj7lwS3LpRU5Mwr2ol1c2gXIEXuF6aywqrtmo= 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-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= 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-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= 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/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +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/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/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/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/joonix/log v0.0.0-20200409080653-9c1d2ceb5f1d/go.mod h1:fS54ONkjDV71zS9CDx3V9K21gJg7byKSvI4ajuWFNJw= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/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/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw= +github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0= +github.com/karalabe/usb v0.0.0-20211005121534-4c5740d64559/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kevinburke/go-bindata v3.21.0+incompatible h1:baK7hwFJDlAHrOqmE9U3u8tow1Uc5ihN9E/b7djcK2g= github.com/kevinburke/go-bindata v3.21.0+incompatible/go.mod h1:/pEEZ72flUW2p0yi30bslSp9YqD9pysLxunQDdb2CPM= +github.com/kevinms/leakybucket-go v0.0.0-20200115003610-082473db97ca/go.mod h1:ph+C5vpnCcQvKBwJwKLTK3JLNGnBXYlG7m7JjoC/zYA= 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/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +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.10.3/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.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y70BU= github.com/klauspost/cpuid/v2 v2.2.3/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/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.2/go.mod h1:XoLfkAiA2KeZsYh4DbHxD7h3nR2AZNqVQOa+LJuqPYs= 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= @@ -514,11 +872,12 @@ 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= -github.com/kylelemons/godebug v0.0.0-20170224010052-a616ab194758 h1:0D5M2HQSGD3PYPwICLl+/9oulQauOuETfgFvhBDffs0= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= +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/ledgerwatch/erigon-lib v0.0.0-20230328191829-416af23d9dcd h1:VUp9woJj6sVoZO6lIwOOm4qA5Qe0LRiOpUn84cy3ohw= -github.com/ledgerwatch/erigon-lib v0.0.0-20230328191829-416af23d9dcd/go.mod h1:nyJqfX9uPm1P/poZB1211DFe5DnAKOhYqvkEPyW7dXM= github.com/ledgerwatch/erigon-snapshot v1.1.1-0.20230306083105-1391330d62a3 h1:tfzawK1gIIgRjVZeANXOr0Ziu+kqCIBuKMe0TXfl5Aw= github.com/ledgerwatch/erigon-snapshot v1.1.1-0.20230306083105-1391330d62a3/go.mod h1:3AuPxZc85jkehh/HA9h8gabv5MSi3kb/ddtzBsTVJFo= github.com/ledgerwatch/log/v3 v3.7.0 h1:aFPEZdwZx4jzA3+/Pf8wNDN5tCI0cIolq/kfvgcM+og= @@ -527,68 +886,207 @@ github.com/ledgerwatch/secp256k1 v1.0.0 h1:Usvz87YoTG0uePIV8woOof5cQnLXGYa162rFf github.com/ledgerwatch/secp256k1 v1.0.0/go.mod h1:SPmqJFciiF/Q0mPt2jVs2dTr/1TZBTIA+kPMmKgBAak= github.com/ledgerwatch/trackerslist v1.1.0 h1:eKhgeURD9x/J3qzMnL6C0e0cLy6Ld7Ck/VR/yF+7cZQ= github.com/ledgerwatch/trackerslist v1.1.0/go.mod h1:wWU/V810cpsEl//o49ebwAWf0BL0WOJiu/577L4IVok= -github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= +github.com/libp2p/go-addr-util v0.0.2/go.mod h1:Ecd6Fb3yIuLzq4bD7VcywcVSBtefcAwnUISBM3WG15E= +github.com/libp2p/go-addr-util v0.1.0/go.mod h1:6I3ZYuFr2O/9D+SoyM0zEw0EF3YkldtTX406BpdQMqw= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= 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-conn-security-multistream v0.2.0/go.mod h1:hZN4MjlNetKD3Rq5Jb/P5ohUnFLNzEAR4DLSzpn2QLU= +github.com/libp2p/go-conn-security-multistream v0.2.1/go.mod h1:cR1d8gA0Hr59Fj6NhaTpFhJZrjSYuNmhpT2r25zYR70= +github.com/libp2p/go-conn-security-multistream v0.3.0/go.mod h1:EEP47t4fw/bTelVmEzIDqSe69hO/ip52xBEhZMLWAHM= +github.com/libp2p/go-eventbus v0.2.1/go.mod h1:jc2S4SoEVPP48H9Wpzm5aiGwUCBMfGhVhhBjyhhCJs8= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= 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.25.1 h1:YK+YDCHpYyTvitKWVxa5PfElgIpOONU01X5UcLEwJGA= -github.com/libp2p/go-libp2p v0.25.1/go.mod h1:xnK9/1d9+jeQCVvi/f1g12KqtVi/jP/SijtKV1hML3g= +github.com/libp2p/go-libp2p v0.17.0/go.mod h1:Fkin50rsGdv5mm5BshBUtPRZknt9esfmYXBOYcwOTgw= +github.com/libp2p/go-libp2p v0.26.2 h1:eHEoW/696FP7/6DxOvcrKfTD6Bi0DExxiMSZUJxswA0= +github.com/libp2p/go-libp2p v0.26.2/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= +github.com/libp2p/go-libp2p-asn-util v0.1.0/go.mod h1:wu+AnM9Ii2KgO5jMmS1rz9dvzTdj8BXqsPR9HR0XB7I= 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.9.1-0.20230221111042-3dbc2fd5baca h1:oZfjXSBxZqteGMAcyaX+3wVQqM8k0f5r/Pi9BDU8058= -github.com/libp2p/go-libp2p-pubsub v0.9.1-0.20230221111042-3dbc2fd5baca/go.mod h1:RYA7aM9jIic5VV47WXu4GkcRxRhrdElWf8xtyli+Dzc= +github.com/libp2p/go-libp2p-autonat v0.7.0/go.mod h1:uPvPn6J7cN+LCfFwW5tpOYvAz5NvPTc4iBamTV/WDMg= +github.com/libp2p/go-libp2p-blankhost v0.2.0/go.mod h1:eduNKXGTioTuQAUcZ5epXi9vMl+t4d8ugUBRQ4SqaNQ= +github.com/libp2p/go-libp2p-blankhost v0.3.0/go.mod h1:urPC+7U01nCGgJ3ZsV8jdwTp6Ji9ID0dMTvq+aJ+nZU= +github.com/libp2p/go-libp2p-circuit v0.4.0/go.mod h1:t/ktoFIUzM6uLQ+o1G6NuBl2ANhBKN9Bc8jRIk31MoA= +github.com/libp2p/go-libp2p-connmgr v0.2.4/go.mod h1:YV0b/RIm8NGPnnNWM7hG9Q38OeQiQfKhHCCs1++ufn0= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-core v0.2.0/go.mod h1:X0eyB0Gy93v0DZtSYbEM7RnMChm9Uv3j7yRXjO77xSI= +github.com/libp2p/go-libp2p-core v0.3.0/go.mod h1:ACp3DmS3/N64c2jDzcV429ukDpicbL6+TrrxANBjPGw= +github.com/libp2p/go-libp2p-core v0.3.1/go.mod h1:thvWy0hvaSBhnVBaW37BvzgVV68OUhgJJLAa6almrII= +github.com/libp2p/go-libp2p-core v0.5.0/go.mod h1:49XGI+kc38oGVwqSBhDEwytaAxgZasHhFfQKibzTls0= +github.com/libp2p/go-libp2p-core v0.5.1/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= +github.com/libp2p/go-libp2p-core v0.5.4/go.mod h1:uN7L2D4EvPCvzSH5SrhR72UWbnSGpt5/a35Sm4upn4Y= +github.com/libp2p/go-libp2p-core v0.5.5/go.mod h1:vj3awlOr9+GMZJFH9s4mpt9RHHgGqeHCopzbYKZdRjM= +github.com/libp2p/go-libp2p-core v0.5.7/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= +github.com/libp2p/go-libp2p-core v0.6.0/go.mod h1:txwbVEhHEXikXn9gfC7/UDDw7rkxuX0bJvM49Ykaswo= +github.com/libp2p/go-libp2p-core v0.7.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.0/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.1/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.2/go.mod h1:FfewUH/YpvWbEB+ZY9AQRQ4TAD8sJBt/G1rVvhz5XT8= +github.com/libp2p/go-libp2p-core v0.8.6/go.mod h1:dgHr0l0hIKfWpGpqAMbpo19pen9wJfdCGv51mTmdpmM= +github.com/libp2p/go-libp2p-core v0.9.0/go.mod h1:ESsbz31oC3C1AvMJoGx26RTuCkNhmkSRCqZ0kQtJ2/8= +github.com/libp2p/go-libp2p-core v0.10.0/go.mod h1:ECdxehoYosLYHgDDFa2N4yE8Y7aQRAMf0sX9mf2sbGg= +github.com/libp2p/go-libp2p-core v0.11.0/go.mod h1:ECdxehoYosLYHgDDFa2N4yE8Y7aQRAMf0sX9mf2sbGg= +github.com/libp2p/go-libp2p-core v0.12.0/go.mod h1:ECdxehoYosLYHgDDFa2N4yE8Y7aQRAMf0sX9mf2sbGg= +github.com/libp2p/go-libp2p-core v0.13.0/go.mod h1:ECdxehoYosLYHgDDFa2N4yE8Y7aQRAMf0sX9mf2sbGg= +github.com/libp2p/go-libp2p-discovery v0.6.0/go.mod h1:/u1voHt0tKIe5oIA1RHBKQLVCWPna2dXmPNHc2zR9S8= +github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= +github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= +github.com/libp2p/go-libp2p-mplex v0.2.3/go.mod h1:CK3p2+9qH9x+7ER/gWWDYJ3QW5ZxWDkm+dVvjfuG3ek= +github.com/libp2p/go-libp2p-mplex v0.4.1/go.mod h1:cmy+3GfqfM1PceHTLL7zQzAAYaryDu6iPSC+CIb094g= +github.com/libp2p/go-libp2p-nat v0.1.0/go.mod h1:DQzAG+QbDYjN1/C3B6vXucLtz3u9rEonLVPtZVzQqks= +github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU= +github.com/libp2p/go-libp2p-noise v0.3.0/go.mod h1:JNjHbociDJKHD64KTkzGnzqJ0FEV5gHJa6AB00kbCNQ= +github.com/libp2p/go-libp2p-peerstore v0.2.6/go.mod h1:ss/TWTgHZTMpsU/oKVVPQCGuDHItOpf2W8RxAi50P2s= +github.com/libp2p/go-libp2p-peerstore v0.4.0/go.mod h1:rDJUFyzEWPpXpEwywkcTYYzDHlwza8riYMaUzaN6hX0= +github.com/libp2p/go-libp2p-peerstore v0.6.0/go.mod h1:DGEmKdXrcYpK9Jha3sS7MhqYdInxJy84bIPtSu65bKc= +github.com/libp2p/go-libp2p-pnet v0.2.0/go.mod h1:Qqvq6JH/oMZGwqs3N1Fqhv8NVhrdYcO0BW4wssv21LA= +github.com/libp2p/go-libp2p-pubsub v0.6.1/go.mod h1:nJv87QM2cU0w45KPR1rZicq+FmFIOD16zmT+ep1nOmg= +github.com/libp2p/go-libp2p-pubsub v0.9.3 h1:ihcz9oIBMaCK9kcx+yHWm3mLAFBMAUsM4ux42aikDxo= +github.com/libp2p/go-libp2p-pubsub v0.9.3/go.mod h1:RYA7aM9jIic5VV47WXu4GkcRxRhrdElWf8xtyli+Dzc= +github.com/libp2p/go-libp2p-quic-transport v0.13.0/go.mod h1:39/ZWJ1TW/jx1iFkKzzUg00W6tDJh73FC0xYudjr7Hc= +github.com/libp2p/go-libp2p-quic-transport v0.15.2/go.mod h1:wv4uGwjcqe8Mhjj7N/Ic0aKjA+/10UnMlSzLO0yRpYQ= +github.com/libp2p/go-libp2p-swarm v0.3.0/go.mod h1:hdv95GWCTmzkgeJpP+GK/9D9puJegb7H57B5hWQR5Kk= +github.com/libp2p/go-libp2p-swarm v0.8.0/go.mod h1:sOMp6dPuqco0r0GHTzfVheVBh6UEL0L1lXUZ5ot2Fvc= +github.com/libp2p/go-libp2p-swarm v0.9.0/go.mod h1:2f8d8uxTJmpeqHF/1ujjdXZp+98nNIbujVOMEZxCbZ8= +github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.1.1/go.mod h1:xaZWMJrPUM5GlDBxCeGUi7kI4eqnjVyavGroI2nxEM0= +github.com/libp2p/go-libp2p-testing v0.1.2-0.20200422005655-8775583591d8/go.mod h1:Qy8sAncLKpwXtS2dSnDOP8ktexIAHKu+J+pnZOFZLTc= +github.com/libp2p/go-libp2p-testing v0.3.0/go.mod h1:efZkql4UZ7OVsEfaxNHZPzIehtsBXMrXnCfJIgDti5g= +github.com/libp2p/go-libp2p-testing v0.4.0/go.mod h1:Q+PFXYoiYFN5CAEG2w3gLPEzotlKsNSbKQ/lImlOWF0= +github.com/libp2p/go-libp2p-testing v0.4.2/go.mod h1:Q+PFXYoiYFN5CAEG2w3gLPEzotlKsNSbKQ/lImlOWF0= +github.com/libp2p/go-libp2p-testing v0.5.0/go.mod h1:QBk8fqIL1XNcno/l3/hhaIEn4aLRijpYOR+zVjjlh+A= +github.com/libp2p/go-libp2p-testing v0.6.0/go.mod h1:QBk8fqIL1XNcno/l3/hhaIEn4aLRijpYOR+zVjjlh+A= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= +github.com/libp2p/go-libp2p-tls v0.3.0/go.mod h1:fwF5X6PWGxm6IDRwF3V8AVCCj/hOd5oFlg+wo2FxJDY= +github.com/libp2p/go-libp2p-tls v0.3.1/go.mod h1:fwF5X6PWGxm6IDRwF3V8AVCCj/hOd5oFlg+wo2FxJDY= +github.com/libp2p/go-libp2p-transport-upgrader v0.2.0/go.mod h1:mQcrHj4asu6ArfSoMuyojOdjx73Q47cYD7s5+gZOlns= +github.com/libp2p/go-libp2p-transport-upgrader v0.3.0/go.mod h1:i+SKzbRnvXdVbU3D1dwydnTmKRPXiAR/fyvi1dXuL4o= +github.com/libp2p/go-libp2p-transport-upgrader v0.4.3/go.mod h1:bpkldbOWXMrXhpZbSV1mQxTrefOg2Fi+k1ClDSA4ppw= +github.com/libp2p/go-libp2p-transport-upgrader v0.5.0/go.mod h1:Rc+XODlB3yce7dvFV4q/RmyJGsFcCZRkeZMu/Zdg0mo= +github.com/libp2p/go-libp2p-transport-upgrader v0.6.0/go.mod h1:1e07y1ZSZdHo9HPbuU8IztM1Cj+DR5twgycb4pnRzRo= +github.com/libp2p/go-libp2p-yamux v0.4.0/go.mod h1:+DWDjtFMzoAwYLVkNZftoucn7PelNoy5nm3tZ3/Zw30= +github.com/libp2p/go-libp2p-yamux v0.5.0/go.mod h1:AyR8k5EzyM2QN9Bbdg6X1SkVVuqLwTGf0L4DFq9g6po= +github.com/libp2p/go-libp2p-yamux v0.7.0/go.mod h1:fMyA0CsPfHkIuBU0wjRGrCjTBFiXTXxG0k5M4ETv+08= +github.com/libp2p/go-maddr-filter v0.0.5/go.mod h1:Jk+36PMfIqCJhAnaASRH83bdAvfDRp/w6ENFaC9bG+M= +github.com/libp2p/go-maddr-filter v0.1.0/go.mod h1:VzZhTXkMucEGGEOSKddrwGiOv0tUhgnKqNEmIAz/bPU= +github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= +github.com/libp2p/go-mplex v0.1.2/go.mod h1:Xgz2RDCi3co0LeZfgjm4OgUF15+sVR8SRcu3SFXI1lk= +github.com/libp2p/go-mplex v0.3.0/go.mod h1:0Oy/A9PQlwBytDRp4wSkFnzHYDKcpLot35JQ6msjvYQ= 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.0.4/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-msgio v0.0.6/go.mod h1:4ecVB6d9f4BDSL5fqvPiC4A3KivjWn+Venn/1ALLMWA= +github.com/libp2p/go-msgio v0.1.0/go.mod h1:eNlv2vy9V2X/kNldcZ+SShFE++o2Yjxwx6RAYsmgJnE= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= github.com/libp2p/go-nat v0.1.0 h1:MfVsH6DLcpa04Xr+p8hmVRG4juse0s3J8HyNWYHffXg= github.com/libp2p/go-nat v0.1.0/go.mod h1:X7teVkwRHNInVNWQiO/tAiAVRwSr5zoRz4YSTC3uRBM= github.com/libp2p/go-netroute v0.1.2/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= +github.com/libp2p/go-netroute v0.1.3/go.mod h1:jZLDV+1PE8y5XxBySEBgbuVAXbhtuHSdmLPL2n9MKbk= +github.com/libp2p/go-netroute v0.1.5/go.mod h1:V1SR3AaECRkEQCoFFzYwVYWvYIEtlxx89+O3qcpCl4A= +github.com/libp2p/go-netroute v0.1.6/go.mod h1:AqhkMh0VuWmfgtxKPp3Oc1LdU5QSWS7wl0QLhSZqXxQ= 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.0.4/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= +github.com/libp2p/go-openssl v0.0.5/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= +github.com/libp2p/go-openssl v0.0.7/go.mod h1:unDrJpgy3oFr+rqXsarWifmJuNnJR4chtO1HmaZjggc= +github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= +github.com/libp2p/go-reuseport v0.1.0/go.mod h1:bQVn9hmfcTaoo0c9v5pBhOarsU1eNOBZdaAd2hzXRKU= 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-reuseport-transport v0.0.3/go.mod h1:Spv+MPft1exxARzP2Sruj2Wb5JSyHNncjf1Oi2dEbzM= +github.com/libp2p/go-reuseport-transport v0.1.0/go.mod h1:vev0C0uMkzriDY59yFHD9v+ujJvYmDQVLowvAjEOmfw= github.com/libp2p/go-sockaddr v0.0.2/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= +github.com/libp2p/go-sockaddr v0.1.0/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= +github.com/libp2p/go-sockaddr v0.1.1/go.mod h1:syPvOmNs24S3dFVGJA1/mrqdeijPxLV2Le3BRLKd68k= +github.com/libp2p/go-stream-muxer-multistream v0.3.0/go.mod h1:yDh8abSIzmZtqtOt64gFJUXEryejzNb0lisTt+fAMJA= +github.com/libp2p/go-tcp-transport v0.2.0/go.mod h1:vX2U0CnWimU4h0SGSEsg++AzvBcroCGYw28kh94oLe0= +github.com/libp2p/go-tcp-transport v0.4.0/go.mod h1:0y52Rwrn4076xdJYu/51/qJIdxz+EWDAOG2S45sV3VI= +github.com/libp2p/go-ws-transport v0.5.0/go.mod h1:I2juo1dNTbl8BKSBYo98XY85kU2xds1iamArLvl8kNg= +github.com/libp2p/go-yamux v1.4.0/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= +github.com/libp2p/go-yamux v1.4.1/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/hkmpooHE= +github.com/libp2p/go-yamux/v2 v2.3.0/go.mod h1:iTU+lOIn/2h0AgKcL49clNTwfEw+WSfDYrXe05EyKIs= 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/libp2p/zeroconf/v2 v2.1.1/go.mod h1:fuJqLnUwZTshS3U/bMRJ3+ow/v9oid1n0DmyYyNO1Xs= 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/lispad/go-generics-tools v1.1.0 h1:mbSgcxdFVmpoyso1X/MJHXbSbSL3dD+qhRryyxk+/XY= github.com/lispad/go-generics-tools v1.1.0/go.mod h1:2csd1EJljo/gy5qG4khXol7ivCPptNjG5Uv2X8MgK84= +github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/lucas-clemente/quic-go v0.23.0/go.mod h1:paZuzjXCE5mj6sikVLMvqXk8lJV2AsqtJ6bDhjEfxx0= +github.com/lucas-clemente/quic-go v0.24.0/go.mod h1:paZuzjXCE5mj6sikVLMvqXk8lJV2AsqtJ6bDhjEfxx0= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= 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.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= -github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/magiconair/properties v1.7.4-0.20170902060319-8d7837e64d3c/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.0/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-20180823135443-60711f1a8329/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/go.mod h1:n4zTdgP0vr0S3w7/O/g98U+e0gwLScEXGwov2nIKuGQ= +github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= +github.com/marten-seemann/qtls-go1-15 v0.1.4/go.mod h1:GyFwywLKkRt+6mfU99csTEY1joMZz5vmB1WNZH3P81I= +github.com/marten-seemann/qtls-go1-16 v0.1.4/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk= +github.com/marten-seemann/qtls-go1-17 v0.1.0/go.mod h1:fz4HIxByo+LlWcreM4CZOYNuz3taBQ8rN2X6FqvaWo8= 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/maticnetwork/crand v1.0.2 h1:Af0tAivC8zrxXDpGWNWVT/0s1fOz8w0eRbahZgURS8I= github.com/maticnetwork/crand v1.0.2/go.mod h1:/NRNL3bj2eYdqpWmoIP5puxndTpi0XRxpj5ZKxfHjyg= github.com/maticnetwork/polyproto v0.0.2 h1:cPxuxbIDItdwGnucc3lZB58U8Zfe1mH73PWTGd15554= github.com/maticnetwork/polyproto v0.0.2/go.mod h1:e1mU2EXSwEpn5jM7GfNwu3AupsV6WAGoPFFfswXOF0o= +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.0.10-0.20170816031813-ad5389df28cd/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +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/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/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= +github.com/mattn/go-isatty v0.0.2/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= 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.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +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.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.13/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/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-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/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= +github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= 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/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= 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.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= 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= @@ -597,19 +1095,37 @@ github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUM 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/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= +github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 h1:QRUSJEgZn2Snx0EmT/QLXibWjSUDjKWvXIT19NBVp94= +github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/highwayhash v1.0.1/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= +github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= 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/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 v0.0.0-20170523030023-d0303fe80992/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/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= +github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= +github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= +github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= 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= @@ -617,37 +1133,77 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN 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.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/mr-tron/base58 v1.1.3/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/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM= github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= 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.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= 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.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= 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.2.1/go.mod h1:s/Apk6IyxfvMjDafnhJgJ3/46z7tZ04iMk5wP4QMGGE= +github.com/multiformats/go-multiaddr v0.2.2/go.mod h1:NtfXiOtHvghW9KojvtySjH5y0u0xW5UouOmQQrn6a3Y= +github.com/multiformats/go-multiaddr v0.3.0/go.mod h1:dF9kph9wfJ+3VLAaeBqo9Of8x4fJxp6ggJGteB8HQTI= +github.com/multiformats/go-multiaddr v0.3.1/go.mod h1:uPbspcUPd5AfaP6ql3ujFY+QWzmBD8uLLL4bXW0XfGc= +github.com/multiformats/go-multiaddr v0.3.3/go.mod h1:lCKNGP1EQ1eZ35Za2wlqnabm9xQkib3fyB+nZXHLag0= +github.com/multiformats/go-multiaddr v0.4.0/go.mod h1:YcpyLH8ZPudLxQlemYBPhSm0/oCXAT8Z4mzFpyoPyRc= 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-multiaddr-net v0.1.2/go.mod h1:QsWt3XK/3hwvNxZJp92iMQKME1qHfpYmyIjFVsSOY6Y= +github.com/multiformats/go-multiaddr-net v0.1.3/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= +github.com/multiformats/go-multiaddr-net v0.1.4/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= +github.com/multiformats/go-multiaddr-net v0.1.5/go.mod h1:ilNnaM9HbmVFqsb/qcNysjCu4PVONlrBZpHIrw/qQuA= +github.com/multiformats/go-multiaddr-net v0.2.0/go.mod h1:gGdH3UXny6U3cKKYCvpXI5rnK7YaOIEOPVDI9tsJbEA= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= 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.8.0 h1:evBmgkbSQux+Ds2IgfhkO38Dl2GDtRW8/Rp6YiSHX/Q= github.com/multiformats/go-multicodec v0.8.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= +github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= +github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= +github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= +github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg= 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.1.1/go.mod h1:KmHZ40hzVxiaiwlj3MEbYgK9JFk2/9UktWZAF54Du38= +github.com/multiformats/go-multistream v0.2.1/go.mod h1:5GZPQZbkWOLOn3J2y4Y99vVW7vOfsAflxARk3x14o6k= +github.com/multiformats/go-multistream v0.2.2/go.mod h1:UIcnm7Zuo8HKG+HkWgfQsGL+/MIEhyTqbODbIUwSXKs= github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/multiformats/go-varint v0.0.2/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/multiformats/go-varint v0.0.6/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/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= +github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= 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= @@ -663,28 +1219,44 @@ github.com/nxadm/tail v1.4.9-0.20211216163028-4472660a31a6 h1:iZ5rEHU561k2tdi/at github.com/nxadm/tail v1.4.9-0.20211216163028-4472660a31a6/go.mod h1:A+9rV4WFp4DKg1Ym1v6YtCrJ2vvlt1ZA/iml0CNuu2A= 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/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.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= 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.8.0 h1:pAM+oBNPrpXRs+E/8spkeGx9QgekbRVyr74EUvRVOUI= github.com/onsi/ginkgo/v2 v2.8.0/go.mod h1:6JsQiECmxCa3V5st74AL/AmsV482EDdVrGaVW6z3oYU= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.25.0 h1:Vw7br2PCDYijJHSfBOWhov+8cAnUf8MfMaIOV323l6Y= 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/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +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= @@ -692,17 +1264,29 @@ github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh 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/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +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/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-toml v1.0.1-0.20170904195809-1d6b12b7cb29/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.0.7 h1:muncTPStnKRos5dpVKULv2FVd4bMOhNePj9CjgDb8Us= github.com/pelletier/go-toml/v2 v2.0.7/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= 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/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= +github.com/peterh/liner v1.2.0/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= +github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ= +github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= 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/pion/datachannel v1.5.2 h1:piB93s8LGmbECrpO84DnkIVWasRMk3IimbcXkTQLE6E= github.com/pion/datachannel v1.5.2/go.mod h1:FTGQWaHrdCwIJ1rw6xBIfZVkslikjShim5yr05XFuCQ= github.com/pion/dtls/v2 v2.1.3/go.mod h1:o6+WvyLDAlXF7YiPB/RlskRoeK+/JtuaZa5emwQcWus= @@ -753,15 +1337,23 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE 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/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/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= 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.5.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU= +github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= 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= @@ -773,10 +1365,17 @@ github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T 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.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.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= 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= @@ -784,43 +1383,68 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.0.10/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.2.0/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.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/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/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4= github.com/protolambda/eth2-shuffle v1.1.0 h1:gixIBI84IeugTwwHXm8vej1bSSEhueBCSryA4lAKRLU= github.com/protolambda/eth2-shuffle v1.1.0/go.mod h1:FhA2c0tN15LTC+4T9DNVm+55S7uXTTjQ8TQnBuXlkF8= +github.com/protolambda/ztyp v0.2.2 h1:rVcL3vBu9W/aV646zF6caLS/dyn9BN8NYiuJzicLNyY= +github.com/protolambda/ztyp v0.2.2/go.mod h1:9bYgKGqg3wJqT9ac1gI2hnVb0STQq7p/1lapqrqY1dU= +github.com/prysmaticlabs/eth2-types v0.0.0-20210303084904-c9735a06829d h1:1dN7YAqMN3oAJ0LceWcyv/U4jHLh+5urnSnr4br6zg4= +github.com/prysmaticlabs/eth2-types v0.0.0-20210303084904-c9735a06829d/go.mod h1:kOmQ/zdobQf7HUohDTifDNFEZfNaSCIY5fkONPL+dWU= 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-20210108222456-8e92c3709aa0/go.mod h1:hCwmef+4qXWjv0jLDbQdWnL0Ol7cS7/lCSS26WR+u6s= 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/prombbolt v0.0.0-20210126082820-9b7adba6db7c/go.mod h1:ZRws458tYHS/Zs936OQ6oCrL+Ict5O4Xpwve1UQ6C9M= +github.com/prysmaticlabs/protoc-gen-go-cast v0.0.0-20211014160335-757fae4f38c6/go.mod h1:ZVEbRdnMkGhp/pu35zq4SXxtvUwWK0J1MATtekZpH2Y= +github.com/prysmaticlabs/prysm v0.0.0-20220124113610-e26cde5e091b h1:XULhE6PdzCYSe5OEVFhuixNqL3mYVOq/3M+SUGnKr1Y= +github.com/prysmaticlabs/prysm v0.0.0-20220124113610-e26cde5e091b/go.mod h1:bFzDfaj4xtisRey9RPkMJOhOJVwmtH3FChV7NPKV1Nk= +github.com/prysmaticlabs/prysm/v4 v4.0.3 h1:w4jkMQjgI4NyIdxny2GBDH1UMVS3tcnlh6obQewkKDM= +github.com/prysmaticlabs/prysm/v4 v4.0.3/go.mod h1:WkVcqMkQQtKcxL+yho4jzkXaKQW93+60tnuLj1vNrXU= github.com/quasilyte/go-ruleguard/dsl v0.3.22 h1:wd8zkOhSNr+I+8Qeciml08ivDt1pSXe60+5DqOpCjPE= github.com/quasilyte/go-ruleguard/dsl v0.3.22/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/qtls-go1-18 v0.2.0 h1:5ViXqBZ90wpUcZS0ge79rf029yx0dYB0McyPJwqqj7U= -github.com/quic-go/qtls-go1-18 v0.2.0/go.mod h1:moGulGHK7o6O8lSPSZNoOwcLvJKJ85vVNc7oJFD65bc= -github.com/quic-go/qtls-go1-19 v0.2.0 h1:Cvn2WdhyViFUHoOqK52i51k4nDX8EwIh5VJiVM4nttk= -github.com/quic-go/qtls-go1-19 v0.2.0/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= -github.com/quic-go/qtls-go1-20 v0.1.0 h1:d1PK3ErFy9t7zxKsG3NXBJXZjp/kMLoIb3y/kV54oAI= -github.com/quic-go/qtls-go1-20 v0.1.0/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= -github.com/quic-go/quic-go v0.32.0 h1:lY02md31s1JgPiiyfqJijpu/UX/Iun304FI3yUqX7tA= -github.com/quic-go/quic-go v0.32.0/go.mod h1:/fCsKANhQIeD5l76c2JFU+07gVE3KaA0FP+0zMWwfwo= -github.com/quic-go/webtransport-go v0.5.1 h1:1eVb7WDWCRoaeTtFHpFBJ6WDN1bSrPrRoW6tZgSw0Ow= -github.com/quic-go/webtransport-go v0.5.1/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= +github.com/quic-go/qtls-go1-19 v0.2.1 h1:aJcKNMkH5ASEJB9FXNeZCyTEIHU1J7MmHyz1Q1TSG1A= +github.com/quic-go/qtls-go1-19 v0.2.1/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= +github.com/quic-go/qtls-go1-20 v0.1.1 h1:KbChDlg82d3IHqaj2bn6GfKRj84Per2VGf5XV3wSwQk= +github.com/quic-go/qtls-go1-20 v0.1.1/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= +github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= +github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= +github.com/quic-go/webtransport-go v0.5.2 h1:GA6Bl6oZY+g/flt00Pnu0XtivSD8vukOu3lYhJjnGEk= +github.com/quic-go/webtransport-go v0.5.2/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU= +github.com/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/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= +github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= +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/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo= github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/dnscache v0.0.0-20211102005908-e0241e321417 h1:Lt9DzQALzHoDwMBGJ6v8ObDPR0dzr2a6sXTB1Fq7IHs= @@ -833,11 +1457,24 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46 h1:GHRpF1pTW19a8tTFrMLUcfWwyC0pnifVo2ClaLq+hP8= github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46/go.mod h1:uAQ5PCi+MFsC7HjREoAz1BU+Mq60+05gifQSsHSDG/8= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= +github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/schollz/progressbar/v3 v3.3.4/go.mod h1:Rp5lZwpgtYmlvmGo1FyDwXMqagyRBQYSDwzlP9QDu84= github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/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/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shirou/gopsutil/v3 v3.23.3 h1:Syt5vVZXUDXPEXpIBt5ziWsJ4LdSAAxF4l/xZeQgSEE= +github.com/shirou/gopsutil/v3 v3.23.3/go.mod h1:lSBNN6t3+D6W5e5nXTxc8KIMMVxAcS+6IJlffjRRlMU= +github.com/shoenig/go-m1cpu v0.1.4 h1:SZPIgRM2sEF9NJy50mRHu9PKGwxyyTTJIWvCtgVbozs= +github.com/shoenig/go-m1cpu v0.1.4/go.mod h1:Wwvst4LR89UxjeFtLRMrpgRiyY4xPsejnVZym39dbAQ= +github.com/shoenig/test v0.6.3 h1:GVXWJFk9PiOjN0KoJ7VrJGH6uLPnqxR7/fe3HUPfE0c= +github.com/shoenig/test v0.6.3/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= 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= @@ -863,25 +1500,47 @@ github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYED 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/assertions v0.0.0-20190215210624-980c5ac6f3ac/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= github.com/smartystreets/goconvey v0.0.0-20190306220146-200a235640ff/go.mod h1:KSQcGKpxUMHk3nbYzs/tIBAM2iDooCn0BmttHOJEbLs= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smola/gocompat v0.2.0/go.mod h1:1B0MlxbmoZNo3h8guHp8HztB3BSYR5itql9qtVc0ypY= 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/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +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 v0.0.0-20170901052352-ee1bd8ee15a1/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +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.1.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= +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 v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= +github.com/spf13/jwalterweatherman v0.0.0-20170901151539-12bd96e66386/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +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-0.20170901120850-7aff26db30c1/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/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.0.0/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/R4aaNBc= +github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= +github.com/status-im/keycard-go v0.0.0-20200402102358-957c09536969/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= 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= @@ -889,6 +1548,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ 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= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -901,9 +1561,16 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/supranational/blst v0.3.5/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/supranational/blst v0.3.10 h1:CMciDZ/h4pXDDXQASe8ZGTNKUiVNxVVA5hpci2Uuhuk= github.com/supranational/blst v0.3.10/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= +github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c h1:g+WoO5jjkqGAzHWCjJB1zZfXPIAaDpzXIEJ0eS6B5Ok= +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/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e h1:cR8/SYRgyQCt5cNCMniB/ZScMkhI9nk8U5C7SbISXjo= @@ -913,11 +1580,23 @@ github.com/tidwall/btree v1.6.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EU github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tinylib/msgp v1.1.0/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= +github.com/tjfoc/gmsm v1.3.0/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w= +github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= +github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM= +github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= +github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= +github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms= +github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/torquem-ch/mdbx-go v0.27.8 h1:rqGmgT2g4S/nKlfmFhLcQUKGQYV6OSog1tT+HHi7LME= -github.com/torquem-ch/mdbx-go v0.27.8/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= +github.com/torquem-ch/mdbx-go v0.27.10 h1:iwb8Wn9gse4MEYIltAna+pxMPCY7hA1/5LLN/Qrcsx0= +github.com/torquem-ch/mdbx-go v0.27.10/go.mod h1:T2fsoJDVppxfAPTLd1svUgH1kpPmeXdPESmroSHcL1E= +github.com/trailofbits/go-mutexasserts v0.0.0-20200708152505-19999e7d3cef/go.mod h1:+SV/613m53DNAmlXPTWGZhIyt4E/qDvn9g/lOPRiy0A= +github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= +github.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go v1.1.13/go.mod h1:jxau1n+/wyTGLQoCkjok9r5zFa/FxT6eI5HiHKQszjc= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.1.13 h1:013LbFhocBoIqgHeIHKlV4JWYhqogATYWZhIcH0WHn4= github.com/ugorji/go/codec v1.1.13/go.mod h1:oNVt3Dq+FO91WNQ/9JnHKQP2QJxTzoN7wCBFCq1OeuU= @@ -926,62 +1605,110 @@ github.com/ugorji/go/codec/codecgen v1.1.13/go.mod h1:EhCxlc7Crov+HLygD4+hBCitXN 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.24.4 h1:0gyJJEBYtCV87zI/x2nZCPyDxD51K6xM8SkwjHFCNEU= -github.com/urfave/cli/v2 v2.24.4/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= +github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +github.com/urfave/cli/v2 v2.25.0 h1:ykdZKuQey2zq0yin/l7JOm9Mh+pg72ngYMeB0ABn6q8= +github.com/urfave/cli/v2 v2.25.0/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXVQ= github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= github.com/valyala/fastrand v1.1.0 h1:f+5HkLW4rsgzdNoleUOB69hyT9IlD2ZQh9GyDMfb5G8= github.com/valyala/fastrand v1.1.0/go.mod h1:HWqCzkrkg6QXT8V2EXWvXCoow7vLwOFN002oeRzjapQ= +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/valyala/histogram v1.2.0 h1:wyYGAZZt3CpwUiIb9AU/Zbllg1llXyrtApRS815OLoQ= github.com/valyala/histogram v1.2.0/go.mod h1:Hb4kBwb4UxsaNbbbh+RRz8ZR6pdodR57tzWUS3BUzXY= github.com/vektah/gqlparser/v2 v2.5.1 h1:ZGu+bquAY23jsxDRcYpWjttRZrUz07LbiY77gUOHcr4= github.com/vektah/gqlparser/v2 v2.5.1/go.mod h1:mPgqFBu/woKTVYWyNk8cO3kh4S/f4aRFZrvOnp3hmCs= 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/go.mod h1:jENeMqeTEU8FNZyDFRVc7KqBdRKSnJ9CCh26TcuNb9s= +github.com/wealdtech/go-eth2-types/v2 v2.5.2/go.mod h1:8lkNUbgklSQ4LZ2oMSuxSdR7WwJW3L9ge1dcoCVyzws= +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/go.mod h1:qiIimacW5NhVRy8o+YxWo9YrecXqDAKKbL0+sOa0SJ4= +github.com/wealdtech/go-eth2-wallet-types/v2 v2.8.2/go.mod h1:k6kmiKWSWBTd4OxFifTEkPaBLhZspnO2KFD5XJY9nqg= +github.com/wercker/journalhook v0.0.0-20180428041537-5d0a5ae867b3/go.mod h1:XCsSkdKK4gwBMNrOCZWww0pX6AOt+2gYc5Z6jBRrNVg= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= +github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee/go.mod h1:m2aV4LZI4Aez7dP5PMyVKEHhUyEJ/RjmPEDOpDvudHg= +github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.9/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= +github.com/willf/bitset v1.1.10 h1:NotGKqX0KwQ72NUzqrjZq5ipPNDQex9lo3WpaS8L2sc= github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= +github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= +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/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= 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/xsleonard/go-merkle v1.1.0 h1:fHe1fuhJjGH22ZzVTAH0jqHLhTGhOq3wQjJN+8P0jQg= github.com/xsleonard/go-merkle v1.1.0/go.mod h1:cW4z+UZ/4f2n9IJgIiyDCdYguchoDyDAPmpuOWGxdGg= +github.com/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/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= +github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.opencensus.io v0.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.opentelemetry.io/otel v1.8.0 h1:zcvBFizPbpa1q7FehvFiHbQwGzmPILebO0tyqIR5Djg= -go.opentelemetry.io/otel v1.8.0/go.mod h1:2pkj+iMj0o03Y+cW6/m8Y4WkRdYN3AvCXCnzRMp9yvM= -go.opentelemetry.io/otel/trace v1.8.0 h1:cSy0DF9eGI5WIfNwZ1q2iUyGj00tGzP24dE1lOlHrfY= -go.opentelemetry.io/otel/trace v1.8.0/go.mod h1:0Bt3PXY8w+3pheS3hQUt+wow8b1ojPaTBoTCh2zIFI4= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/otel v1.11.0 h1:kfToEGMDq6TrVrJ9Vht84Y8y9enykSZzDDZglV0kIEk= +go.opentelemetry.io/otel v1.11.0/go.mod h1:H2KtuEphyMvlhZ+F7tg9GRhAOe60moNx61Ex+WmiKkk= +go.opentelemetry.io/otel/trace v1.11.0 h1:20U/Vj42SX+mASlXLmSGBg6jpI1jQtv682lZtTAOVFI= +go.opentelemetry.io/otel/trace v1.11.0/go.mod h1:nyYjis9jy0gytE9LXGU+/m1sHTKbRY0fX0hulNNDP1U= +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.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/automaxprocs v1.3.0/go.mod h1:9CWT6lKIep8U41DDaPiH6eFscnTyjfTANNQNx6LrIcA= go.uber.org/dig v1.16.1 h1:+alNIBsl0qfY0j6epRubp/9obgtrObRAc5aD+6jbWY8= go.uber.org/dig v1.16.1/go.mod h1:557JTAUZT5bUK0SvCwikmLPPtdQhfvLYtO5tJgQSbnk= go.uber.org/fx v1.19.1 h1:JwYIYAQzXBuBBwSZ1/tn/95pnQO/Sp3yE8lWj9eSAzI= go.uber.org/fx v1.19.1/go.mod h1:bGK+AEy7XUwTBkqCsK/vDyFF0JJOA6X5KWpNC0e6qTA= +go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.1.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.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= 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.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= +go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= +go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= +go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= +go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= 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= @@ -991,42 +1718,87 @@ golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnf 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-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/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-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 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-20190618222545-ea8f1a30c443/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-20200115085410-6d4e4cb37c7d/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-20200510223506-06a226fb4e37/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-20210220033148-5ea612d1eb83/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-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= +golang.org/x/crypto v0.0.0-20210813211128-0a44fdfbc16e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220516162934-403b01795ae8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= -golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= -golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ= +golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= +golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 h1:Jvc7gsqn21cJHCmAWx0LiimpP18LZmUxkT5Mp7EZ1mI= -golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= +golang.org/x/exp v0.0.0-20200513190911-00229845015e/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29/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= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= 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/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= +golang.org/x/mod v0.9.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-20180524181706-dfa909b99c79/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1042,22 +1814,53 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r 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-20190227160552-c95aed5357e7/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= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-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= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-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= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-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-20200904194848-62affa334b73/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-20201201195509-5d6afe98e0b7/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-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-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-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211201190559-0a0e4e1bb54c/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= @@ -1067,24 +1870,35 @@ golang.org/x/net v0.0.0-20220531201128-c960675eff93/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/oauth2 v0.0.0-20170912212905-13449ad91cb2/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 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-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= +golang.org/x/sync v0.0.0-20170517211232-f52d1811a629/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/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= @@ -1095,123 +1909,292 @@ golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5h 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-20181205085412-a5c9d58dba9a/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-20190219092855-153ac476189d/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= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/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-20191206220618-eeba5f6aabab/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-20200413165638-669c56c373c4/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-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/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-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210317225723-c4fcb01b228e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210324051608-47abb6519492/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-20210426080607-c94f62235c83/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210511113859-b0526f3d8744/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211020174200-9d6173849985/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/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-20220412211240-33da011f77ad/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-20220608164250-635b8c9b7f68/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-20220722155257-8c9f86f7a55f/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.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= +golang.org/x/sys v0.7.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.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +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= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.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.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 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/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/time v0.0.0-20170424234030-8be79e1e0910/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +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-20181130052023-1c3d964395ce/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= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-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= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-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= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-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.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -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/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= 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/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +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-20170921000349-586095a6e407/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= 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= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/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/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20170918111702-1e559d0a00ee/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 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-20190522204451-c2c4e71fbf69/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= 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= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-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-20230202175211-008b39050e57 h1:vArvWooPH749rNHpBGgVl+U9B9dATjiEhJzcWGlovNs= -google.golang.org/genproto v0.0.0-20230202175211-008b39050e57/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +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/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-20201019141844-1ed22bb0c154/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-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= +google.golang.org/grpc v1.2.1-0.20170921194603-d4b75ebd4f9f/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= 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= @@ -1219,46 +2202,80 @@ google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc= -google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0 h1:TLkBREm4nIsEcexnCjgQd5GQWaHcqMzwQV0TX9pq8S0= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0/go.mod h1:DNq5QpG7LJqD2AamLZ7zvKE0DEpVl2BSEVjFycAAjRY= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.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.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.54.0 h1:EhTqbhiYeixwWQtAEZAxmV9MGqcjEU2mFx52xCzNyag= +google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.0.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 h1:rNBFJjBCOgVr9pWD7rs/knKL4FRTKgpZmsRfV214zcA= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0/go.mod h1:Dk1tviKTvMCz5tvh7t+fh94dhmQVHuCt2OzJB3CTW9Y= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +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.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.27.1/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= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 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/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/go.mod h1:EUzikiKadqXWcD1AzJLagx0j/BeeWGtn++04Xniyg44= 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/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +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/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= +gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= +gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= +gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= +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/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8= +gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE= 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/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= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1269,15 +2286,31 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C 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= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.3.0 h1:MfDY1b1/0xN1CyMlQDac0ziEy9zJQd9CXBRRDHw2jJo= gotest.tools/v3 v3.3.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A= 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= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= +k8s.io/api v0.18.3/go.mod h1:UOaMwERbqJMfeeeHc8XJKawj4P9TgDRnViIqqBeH2QA= +k8s.io/apimachinery v0.18.3/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko= +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/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= +k8s.io/klog/v2 v2.3.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +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/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= lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI= @@ -1296,8 +2329,8 @@ modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds= modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= -modernc.org/sqlite v1.21.0 h1:4aP4MdUf15i3R3M2mx6Q90WHKz3nZLoz96zlB6tNdow= -modernc.org/sqlite v1.21.0/go.mod h1:XwQ0wZPIh1iKb5mkvCJ3szzbhk+tykC8ZWqTRTgYRwI= +modernc.org/sqlite v1.21.1 h1:GyDFqNnESLOhwwDRaHGdp2jKLDzpyT/rNLglX3ZkMSU= +modernc.org/sqlite v1.21.1/go.mod h1:XwQ0wZPIh1iKb5mkvCJ3szzbhk+tykC8ZWqTRTgYRwI= modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY= modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= modernc.org/tcl v1.15.1 h1:mOQwiEK4p7HruMZcwKTZPw/aqtGM4aY00uzWhlKKYws= @@ -1308,7 +2341,16 @@ nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= pgregory.net/rapid v0.5.5 h1:jkgx1TjbQPD/feRoK+S/mXw9e1uj6WilpHrXJowi6oA= pgregory.net/rapid v0.5.5/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= +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= +rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= +rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= +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/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +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/interfaces.go b/interfaces.go index 9c46a3b763c..1f6126f33a7 100644 --- a/interfaces.go +++ b/interfaces.go @@ -116,16 +116,18 @@ type ChainSyncReader interface { // CallMsg contains parameters for contract calls. type CallMsg struct { - From libcommon.Address // the sender of the 'transaction' - To *libcommon.Address // the destination contract (nil for contract creation) - Gas uint64 // if 0, the call executes with near-infinite gas - GasPrice *uint256.Int // wei <-> gas exchange ratio - Value *uint256.Int // amount of wei sent along with the call - Data []byte // input data, usually an ABI-encoded contract method invocation + From libcommon.Address // the sender of the 'transaction' + To *libcommon.Address // the destination contract (nil for contract creation) + Gas uint64 // if 0, the call executes with near-infinite gas + MaxFeePerDataGas *uint256.Int // EIP-4844 max_fee_per_data_gas + GasPrice *uint256.Int // wei <-> gas exchange ratio + Value *uint256.Int // amount of wei sent along with the call + Data []byte // input data, usually an ABI-encoded contract method invocation FeeCap *uint256.Int // EIP-1559 fee cap per gas. Tip *uint256.Int // EIP-1559 tip per gas. AccessList types2.AccessList // EIP-2930 access list. + DataHashes []libcommon.Hash // EIP-4844 versioned data hashes. } // A ContractCaller provides contract calls, essentially transactions that are executed by diff --git a/node/node.go b/node/node.go index 5647a02fdd7..722298ee665 100644 --- a/node/node.go +++ b/node/node.go @@ -284,7 +284,7 @@ func (n *Node) DataDir() string { return n.config.Dirs.DataDir } -func OpenDatabase(config *nodecfg.Config, logger log.Logger, label kv.Label) (kv.RwDB, error) { +func OpenDatabase(config *nodecfg.Config, label kv.Label) (kv.RwDB, error) { var name string switch label { case kv.ChainDB: @@ -309,14 +309,14 @@ func OpenDatabase(config *nodecfg.Config, logger log.Logger, label kv.Label) (kv roTxLimit = int64(config.Http.DBReadConcurrency) } roTxsLimiter := semaphore.NewWeighted(roTxLimit) // 1 less than max to allow unlocking to happen - opts := mdbx.NewMDBX(logger). + opts := mdbx.NewMDBX(log.Root()). Path(dbPath).Label(label). DBVerbosity(config.DatabaseVerbosity).RoTxsLimiter(roTxsLimiter) if exclusive { opts = opts.Exclusive() } if label == kv.ChainDB { - opts = opts.PageSize(config.MdbxPageSize.Bytes()).MapSize(8 * datasize.TB) + opts = opts.PageSize(config.MdbxPageSize.Bytes()).MapSize(config.MdbxDBSizeLimit) } else { opts = opts.GrowthStep(16 * datasize.MB) } diff --git a/node/node_test.go b/node/node_test.go index 3be75b5a4a7..1cb528474fe 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -28,7 +28,6 @@ import ( "github.com/ledgerwatch/erigon/crypto" "github.com/ledgerwatch/erigon/node/nodecfg" "github.com/ledgerwatch/erigon/p2p" - "github.com/ledgerwatch/log/v3" "github.com/stretchr/testify/require" ) @@ -146,7 +145,7 @@ func TestNodeCloseClosesDB(t *testing.T) { stack, _ := New(testNodeConfig(t)) defer stack.Close() - db, err := OpenDatabase(stack.Config(), log.New(), kv.SentryDB) + db, err := OpenDatabase(stack.Config(), kv.SentryDB) if err != nil { t.Fatal("can't open DB:", err) } @@ -177,7 +176,7 @@ func TestNodeOpenDatabaseFromLifecycleStart(t *testing.T) { var db kv.RwDB stack.RegisterLifecycle(&InstrumentedService{ startHook: func() { - db, err = OpenDatabase(stack.Config(), log.New(), kv.SentryDB) + db, err = OpenDatabase(stack.Config(), kv.SentryDB) if err != nil { t.Fatal("can't open DB:", err) } @@ -202,7 +201,7 @@ func TestNodeOpenDatabaseFromLifecycleStop(t *testing.T) { stack.RegisterLifecycle(&InstrumentedService{ stopHook: func() { - db, err := OpenDatabase(stack.Config(), log.New(), kv.ChainDB) + db, err := OpenDatabase(stack.Config(), kv.ChainDB) if err != nil { t.Fatal("can't open DB:", err) } diff --git a/node/nodecfg/config.go b/node/nodecfg/config.go index 96d52302146..cdb353e6acd 100644 --- a/node/nodecfg/config.go +++ b/node/nodecfg/config.go @@ -163,7 +163,8 @@ type Config struct { TLSKeyFile string TLSCACert string - MdbxPageSize datasize.ByteSize + MdbxPageSize datasize.ByteSize + MdbxDBSizeLimit datasize.ByteSize // HealthCheck enables standard grpc health check HealthCheck bool diff --git a/p2p/enode/nodedb.go b/p2p/enode/nodedb.go index cde82c9dac1..e3d5d1b9368 100644 --- a/p2p/enode/nodedb.go +++ b/p2p/enode/nodedb.go @@ -102,7 +102,7 @@ func bucketsConfig(_ kv.TableCfg) kv.TableCfg { func newMemoryDB(logger log.Logger, tmpDir string) (*DB, error) { db := &DB{quit: make(chan struct{})} var err error - db.kv, err = mdbx.NewMDBX(logger).InMem(tmpDir).Label(kv.SentryDB).WithTableCfg(bucketsConfig).Open() + db.kv, err = mdbx.NewMDBX(logger).InMem(tmpDir).Label(kv.SentryDB).WithTableCfg(bucketsConfig).MapSize(1 * datasize.GB).Open() if err != nil { return nil, err } diff --git a/params/bootnodes.go b/params/bootnodes.go index f9060eb4dee..b2bad918af4 100644 --- a/params/bootnodes.go +++ b/params/bootnodes.go @@ -73,6 +73,7 @@ var BscBootnodes = []string{ "enode://28b1d16562dac280dacaaf45d54516b85bc6c994252a9825c5cc4e080d3e53446d05f63ba495ea7d44d6c316b54cd92b245c5c328c37da24605c4a93a0d099c4@34.246.65.14:30311", "enode://5a7b996048d1b0a07683a949662c87c09b55247ce774aeee10bb886892e586e3c604564393292e38ef43c023ee9981e1f8b335766ec4f0f256e57f8640b079d5@35.73.137.11:30311", } + var SepoliaStaticPeers = []string{ // from https://github.com/ledgerwatch/erigon/issues/6134#issuecomment-1354923418 "enode://8ae4559db1b1e160be8cc46018d7db123ed6d03fbbfe481da5ec05f71f0aa4d5f4b02ad059127096aa994568706a0d02933984083b87c5e1e3de2b7692444d37@35.161.233.158:46855", @@ -90,6 +91,11 @@ var SepoliaStaticPeers = []string{ "enode://66158b31eecff939f220b291d2b448edbfe94f1d4c992d9395b5d476e55e54b5abd11d3ee44daf1e18ee27b910ef99cdf6f19775eb4820ebe4f77d7aa948e3b6@51.195.63.10:55198", "enode://bf94acbd51170bf075cacb9f149b21ff46354d659ab434a0d40688f776e1e1556bc62be2dc2867ba513844268c0dc8240099a6b60efe1713fbc25da7fdeb6ff1@3.82.105.139:30303", "enode://41329e5ceb51cdddbe6a475db00b682505768b71ff8ee37d2d3500ca1b78918f9fad57d6006dd9f79cd418437dbcf87ec2fd58d60710f925cb17da05a51197cf@65.21.34.60:30303", + "enode://4e5e92199ee224a01932a377160aa432f31d0b351f84ab413a8e0a42f4f36476f8fb1cbe914af0d9aef0d51665c214cf653c651c4bbd9d5550a934f241f1682b@138.197.51.181:30303", + "enode://143e11fb766781d22d92a2e33f8f104cddae4411a122295ed1fdb6638de96a6ce65f5b7c964ba3763bba27961738fef7d3ecc739268f3e5e771fb4c87b6234ba@146.190.1.103:30303", + "enode://8b61dc2d06c3f96fddcbebb0efb29d60d3598650275dc469c22229d3e5620369b0d3dedafd929835fe7f489618f19f456fe7c0df572bf2d914a9f4e006f783a9@170.64.250.88:30303", + "enode://10d62eff032205fcef19497f35ca8477bea0eadfff6d769a147e895d8b2b8f8ae6341630c645c30f5df6e67547c03494ced3d9c5764e8622a26587b083b028e8@139.59.49.206:30303", + "enode://9e9492e2e8836114cc75f5b929784f4f46c324ad01daf87d956f98b3b6c5fcba95524d6e5cf9861dc96a2c8a171ea7105bb554a197455058de185fa870970c7c@138.68.123.152:30303", } var BscStaticPeers = []string{ @@ -186,13 +192,6 @@ var ChapelStaticPeers = []string{ var RialtoBootnodes = []string{} var RialtoStaticPeers = ChapelStaticPeers -var SokolBootnodes = []string{ - "enode://f11a0f80939b49a28bf99581da9b351a592ec1504b9d32a7dfda79b36510a891e96631239c4166e5c73368c21e9bb3241e7fd6929b899772e5a8fe9a7b7c3af6@45.77.52.149:30303", - "enode://e08adce358fc26dfbe1f24ee578dceaa29575ca44a39d9041203131db5135aceba6241840a9b57b1540eeaf7b4eff1aead28a74641be43342c35af454abb31b3@199.247.18.10:30313", - "enode://f1a5100a81cb73163ae450c584d06b1f644aa4fad4486c6aeb4c384b343c54bb66c744aa5f133af66ea1b25f0f4a454f04878f3e96ee4cd2390c047396d6357b@209.97.158.4:30303", - "enode://f11a0f80939b49a28bf99581da9b351a592ec1504b9d32a7dfda79b36510a891e96631239c4166e5c73368c21e9bb3241e7fd6929b899772e5a8fe9a7b7c3af6@45.77.52.149:30303", -} - var V5Bootnodes = []string{ // Teku team's bootnode "enr:-KG4QOtcP9X1FbIMOe17QNMKqDxCpm14jcX5tiOE4_TyMrFqbmhPZHK_ZPG2Gxb1GE2xdtodOfx9-cgvNtxnRyHEmC0ghGV0aDKQ9aX9QgAAAAD__________4JpZIJ2NIJpcIQDE8KdiXNlY3AyNTZrMaEDhpehBDbZjM_L9ek699Y7vhUJ-eAdMyQW_Fil522Y0fODdGNwgiMog3VkcIIjKA", @@ -278,8 +277,6 @@ func BootnodeURLsOfChain(chain string) []string { return ChapelBootnodes case networkname.RialtoChainName: return RialtoBootnodes - case networkname.SokolChainName: - return SokolBootnodes case networkname.MumbaiChainName: return MumbaiBootnodes case networkname.BorMainnetChainName: diff --git a/params/chainspecs/bsc.json b/params/chainspecs/bsc.json index da944f274c0..254388101d1 100644 --- a/params/chainspecs/bsc.json +++ b/params/chainspecs/bsc.json @@ -1,28 +1,28 @@ { - "ChainName": "bsc", - "chainId": 56, - "consensus": "parlia", - "homesteadBlock": 0, - "eip150Block": 0, - "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "eip155Block": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 0, - "petersburgBlock": 0, - "istanbulBlock": 0, - "muirGlacierBlock": 0, - "ramanujanBlock": 0, - "nielsBlock": 0, - "mirrorSyncBlock": 5184000, - "brunoBlock": 13082000, - "eulerBlock": 18907621, - "nanoBlock": 21962149, - "moranBlock": 22107423, - "gibbsBlock": 23846001, - "parlia": { - "DBPath": "", - "InMemory": false, - "period": 3, - "epoch": 200 - } + "ChainName": "bsc", + "chainId": 56, + "consensus": "parlia", + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "muirGlacierBlock": 0, + "ramanujanBlock": 0, + "nielsBlock": 0, + "mirrorSyncBlock": 5184000, + "brunoBlock": 13082000, + "eulerBlock": 18907621, + "nanoBlock": 21962149, + "moranBlock": 22107423, + "gibbsBlock": 23846001, + "planckBlock": 27281024, + "parlia": { + "DBPath": "", + "InMemory": false, + "period": 3, + "epoch": 200 + } } \ No newline at end of file diff --git a/params/chainspecs/chapel.json b/params/chainspecs/chapel.json index 78cd5f30775..bdf76d5cd41 100644 --- a/params/chainspecs/chapel.json +++ b/params/chainspecs/chapel.json @@ -4,7 +4,6 @@ "consensus": "parlia", "homesteadBlock": 0, "eip150Block": 0, - "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", "eip155Block": 0, "byzantiumBlock": 0, "constantinopleBlock": 0, @@ -19,10 +18,12 @@ "gibbsBlock": 22800220, "nanoBlock": 23482428, "moranBlock": 23603940, + "planckBlock": 28196022, + "lubanBlock": 29295050, "parlia": { "DBPath": "", "InMemory": false, "period": 3, "epoch": 200 } -} +} \ No newline at end of file diff --git a/params/chainspecs/chiado.json b/params/chainspecs/chiado.json index e1c6ab4d57b..de2e2f64f58 100644 --- a/params/chainspecs/chiado.json +++ b/params/chainspecs/chiado.json @@ -10,7 +10,6 @@ "constantinopleBlock": 0, "petersburgBlock": 0, "istanbulBlock": 0, - "posdaoBlock": 0, "berlinBlock": 0, "londonBlock": 0, "eip1559FeeCollectorTransition": 0, @@ -18,8 +17,37 @@ "terminalTotalDifficulty": 231707791542740786049188744689299064356246512, "terminalTotalDifficultyPassed": true, "aura": { - "DBPath": "", - "InMemory": false, - "Etherbase": "0x0000000000000000000000000000000000000000" + "stepDuration": 5, + "blockReward": 0, + "maximumUncleCountTransition": 0, + "maximumUncleCount": 0, + "validators": { + "multi": { + "0": { + "list": ["0x14747a698Ec1227e6753026C08B29b4d5D3bC484"] + }, + "67334": { + "list": [ + "0x14747a698Ec1227e6753026C08B29b4d5D3bC484", + "0x56D421c0AC39976E89fa400d34ca6579417B84cA", + "0x5CD99ac2F0F8C25a1e670F6BaB19D52Aad69D875", + "0x60F1CF46B42Df059b98Acf67C1dD7771b100e124", + "0x655e97bA0f63A56c2b56EB3e84f7bf42b20Bae14", + "0x755B6259938D140626301c0B6026c1C00C9eD5d9", + "0xa8010da9Cb0AC018C86A06301963853CC371a18c" + ] + } + } + }, + "blockRewardContractAddress": "0x2000000000000000000000000000000000000001", + "blockRewardContractTransition": 0, + "randomnessContractAddress": { + "0": "0x3000000000000000000000000000000000000001" + }, + "posdaoTransition": 0, + "blockGasLimitContractTransitions": { + "0": "0x4000000000000000000000000000000000000001" + }, + "registrar": "0x6000000000000000000000000000000000000000" } } diff --git a/params/chainspecs/gnosis.json b/params/chainspecs/gnosis.json index 7f1d730684e..65568965b4b 100644 --- a/params/chainspecs/gnosis.json +++ b/params/chainspecs/gnosis.json @@ -10,7 +10,6 @@ "constantinopleBlock": 1604400, "petersburgBlock": 2508800, "istanbulBlock": 7298030, - "posdaoBlock": 9186425, "berlinBlock": 16101500, "londonBlock": 19040000, "eip1559FeeCollectorTransition": 19040000, @@ -18,8 +17,39 @@ "terminalTotalDifficulty": 8626000000000000000000058750000000000000000000, "terminalTotalDifficultyPassed": true, "aura": { - "DBPath": "", - "InMemory": false, - "Etherbase": "0x0000000000000000000000000000000000000000" + "stepDuration": 5, + "blockReward": 0, + "maximumUncleCountTransition": 0, + "maximumUncleCount": 0, + "validators": { + "multi": { + "0": { + "list": [ + "0xcace5b3c29211740e595850e80478416ee77ca21" + ] + }, + "1300": { + "safeContract": "0x22e1229a2c5b95a60983b5577f745a603284f535" + }, + "9186425": { + "contract": "0xB87BE9f7196F2AE084Ca1DE6af5264292976e013" + } + } + }, + "blockRewardContractAddress": "0x867305d19606aadba405ce534e303d0e225f9556", + "blockRewardContractTransition": 1310, + "blockRewardContractTransitions": { + "9186425": "0x481c034c6d9441db23ea48de68bcae812c5d39ba" + }, + "randomnessContractAddress": { + "9186425": "0x5870b0527DeDB1cFBD9534343Feda1a41Ce47766" + }, + "posdaoTransition": 9186425, + "registrar": "0x6B53721D4f2Fb9514B85f5C49b197D857e36Cf03", + "rewriteBytecode": { + "21735000": { + "0xf8D1677c8a0c961938bf2f9aDc3F3CFDA759A9d9": "0x6080604052600436106101b35763ffffffff60e060020a60003504166305d2035b81146101b857806306fdde03146101e1578063095ea7b31461026b5780630b26cf661461028f57806318160ddd146102b257806323b872dd146102d957806330adf81f14610303578063313ce567146103185780633644e5151461034357806339509351146103585780634000aea01461037c57806340c10f19146103ad57806342966c68146103d157806354fd4d50146103e957806366188463146103fe57806369ffa08a1461042257806370a0823114610449578063715018a61461046a578063726600ce1461047f5780637d64bcb4146104a05780637ecebe00146104b5578063859ba28c146104d65780638da5cb5b146105175780638fcbaf0c1461054857806395d89b4114610586578063a457c2d71461059b578063a9059cbb146105bf578063b753a98c146105e3578063bb35783b14610607578063c6a1dedf14610631578063cd59658314610646578063d505accf1461065b578063d73dd62314610694578063dd62ed3e146106b8578063f2d5d56b146106df578063f2fde38b14610703578063ff9e884d14610724575b600080fd5b3480156101c457600080fd5b506101cd61074b565b604080519115158252519081900360200190f35b3480156101ed57600080fd5b506101f661076c565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610230578181015183820152602001610218565b50505050905090810190601f16801561025d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561027757600080fd5b506101cd600160a060020a03600435166024356107fa565b34801561029b57600080fd5b506102b0600160a060020a0360043516610810565b005b3480156102be57600080fd5b506102c761086a565b60408051918252519081900360200190f35b3480156102e557600080fd5b506101cd600160a060020a0360043581169060243516604435610870565b34801561030f57600080fd5b506102c7610a38565b34801561032457600080fd5b5061032d610a5c565b6040805160ff9092168252519081900360200190f35b34801561034f57600080fd5b506102c7610a65565b34801561036457600080fd5b506101cd600160a060020a0360043516602435610a6b565b34801561038857600080fd5b506101cd60048035600160a060020a0316906024803591604435918201910135610aac565b3480156103b957600080fd5b506101cd600160a060020a0360043516602435610bbd565b3480156103dd57600080fd5b506102b0600435610cc8565b3480156103f557600080fd5b506101f6610cd5565b34801561040a57600080fd5b506101cd600160a060020a0360043516602435610d0c565b34801561042e57600080fd5b506102b0600160a060020a0360043581169060243516610de9565b34801561045557600080fd5b506102c7600160a060020a0360043516610e0e565b34801561047657600080fd5b506102b0610e29565b34801561048b57600080fd5b506101cd600160a060020a0360043516610e40565b3480156104ac57600080fd5b506101cd610e54565b3480156104c157600080fd5b506102c7600160a060020a0360043516610e5b565b3480156104e257600080fd5b506104eb610e6d565b6040805167ffffffffffffffff9485168152928416602084015292168183015290519081900360600190f35b34801561052357600080fd5b5061052c610e78565b60408051600160a060020a039092168252519081900360200190f35b34801561055457600080fd5b506102b0600160a060020a0360043581169060243516604435606435608435151560ff60a4351660c43560e435610e87565b34801561059257600080fd5b506101f6610fc5565b3480156105a757600080fd5b506101cd600160a060020a036004351660243561101f565b3480156105cb57600080fd5b506101cd600160a060020a0360043516602435611032565b3480156105ef57600080fd5b506102b0600160a060020a0360043516602435611054565b34801561061357600080fd5b506102b0600160a060020a0360043581169060243516604435611064565b34801561063d57600080fd5b506102c7611075565b34801561065257600080fd5b5061052c611099565b34801561066757600080fd5b506102b0600160a060020a036004358116906024351660443560643560ff6084351660a43560c4356110a8565b3480156106a057600080fd5b506101cd600160a060020a0360043516602435611184565b3480156106c457600080fd5b506102c7600160a060020a036004358116906024351661120b565b3480156106eb57600080fd5b506102b0600160a060020a0360043516602435611236565b34801561070f57600080fd5b506102b0600160a060020a0360043516611241565b34801561073057600080fd5b506102c7600160a060020a0360043581169060243516611261565b60065474010000000000000000000000000000000000000000900460ff1681565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156107f25780601f106107c7576101008083540402835291602001916107f2565b820191906000526020600020905b8154815290600101906020018083116107d557829003601f168201915b505050505081565b600061080733848461127e565b50600192915050565b600654600160a060020a0316331461082757600080fd5b610830816112c0565b151561083b57600080fd5b6007805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b60045490565b600080600160a060020a038516151561088857600080fd5b600160a060020a038416151561089d57600080fd5b600160a060020a0385166000908152600360205260409020546108c6908463ffffffff6112c816565b600160a060020a0380871660009081526003602052604080822093909355908616815220546108fb908463ffffffff6112da16565b600160a060020a038086166000818152600360209081526040918290209490945580518781529051919392891692600080516020611d7283398151915292918290030190a3600160a060020a0385163314610a225761095a853361120b565b905060001981146109c457610975818463ffffffff6112c816565b600160a060020a038616600081815260056020908152604080832033808552908352928190208590558051948552519193600080516020611d92833981519152929081900390910190a3610a22565b600160a060020a0385166000908152600a602090815260408083203384529091529020541580610a175750600160a060020a0385166000908152600a602090815260408083203384529091529020544211155b1515610a2257600080fd5b610a2d8585856112ed565b506001949350505050565b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60025460ff1681565b60085481565b336000818152600560209081526040808320600160a060020a03871684529091528120549091610807918590610aa7908663ffffffff6112da16565b61127e565b600084600160a060020a03811615801590610ad05750600160a060020a0381163014155b1515610adb57600080fd5b610ae58686611324565b1515610af057600080fd5b85600160a060020a031633600160a060020a03167fe19260aff97b920c7df27010903aeb9c8d2be5d310a2c67824cf3f15396e4c16878787604051808481526020018060200182810382528484828181526020019250808284376040519201829003965090945050505050a3610b65866112c0565b15610bb157610ba633878787878080601f01602080910402602001604051908101604052809392919081815260200183838082843750611330945050505050565b1515610bb157600080fd5b50600195945050505050565b600654600090600160a060020a03163314610bd757600080fd5b60065474010000000000000000000000000000000000000000900460ff1615610bff57600080fd5b600454610c12908363ffffffff6112da16565b600455600160a060020a038316600090815260036020526040902054610c3e908363ffffffff6112da16565b600160a060020a038416600081815260036020908152604091829020939093558051858152905191927f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688592918290030190a2604080518381529051600160a060020a03851691600091600080516020611d728339815191529181900360200190a350600192915050565b610cd233826114ad565b50565b60408051808201909152600181527f3100000000000000000000000000000000000000000000000000000000000000602082015281565b336000908152600560209081526040808320600160a060020a0386168452909152812054808310610d6057336000908152600560209081526040808320600160a060020a0388168452909152812055610d95565b610d70818463ffffffff6112c816565b336000908152600560209081526040808320600160a060020a03891684529091529020555b336000818152600560209081526040808320600160a060020a038916808552908352928190205481519081529051929392600080516020611d92833981519152929181900390910190a35060019392505050565b600654600160a060020a03163314610e0057600080fd5b610e0a828261159c565b5050565b600160a060020a031660009081526003602052604090205490565b600654600160a060020a031633146101b357600080fd5b600754600160a060020a0390811691161490565b6000806000fd5b60096020526000908152604090205481565b600260056000909192565b600654600160a060020a031681565b600080861580610e975750864211155b1515610ea257600080fd5b604080517fea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb6020820152600160a060020a03808d16828401528b166060820152608081018a905260a0810189905287151560c0808301919091528251808303909101815260e0909101909152610f17906115da565b9150610f25828686866116e1565b600160a060020a038b8116911614610f3c57600080fd5b600160a060020a038a1660009081526009602052604090208054600181019091558814610f6857600080fd5b85610f74576000610f78565b6000195b905085610f86576000610f88565b865b600160a060020a03808c166000908152600a60209081526040808320938e1683529290522055610fb98a8a836118e3565b50505050505050505050565b60018054604080516020600284861615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156107f25780601f106107c7576101008083540402835291602001916107f2565b600061102b8383610d0c565b9392505050565b600061103e8383611324565b151561104957600080fd5b6108073384846112ed565b61105f338383610870565b505050565b61106f838383610870565b50505050565b7fea2aa0a1be11a07ed86d755c93467f4f82362b452371d1ba94d1715123511acb81565b600754600160a060020a031690565b600080428610156110b857600080fd5b600160a060020a03808a1660008181526009602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c99281019290925281830193909352928b166060840152608083018a905260a0830182905260c08084018a90528151808503909101815260e090930190529250611149906115da565b9050611157818686866116e1565b600160a060020a038a811691161461116e57600080fd5b61117989898961127e565b505050505050505050565b336000908152600560209081526040808320600160a060020a03861684529091528120546111b8908363ffffffff6112da16565b336000818152600560209081526040808320600160a060020a038916808552908352928190208590558051948552519193600080516020611d92833981519152929081900390910190a350600192915050565b600160a060020a03918216600090815260056020908152604080832093909416825291909152205490565b61105f823383610870565b600654600160a060020a0316331461125857600080fd5b610cd281611a3e565b600a60209081526000928352604080842090915290825290205481565b6112898383836118e3565b60001981141561105f57600160a060020a038084166000908152600a60209081526040808320938616835292905290812055505050565b6000903b1190565b6000828211156112d457fe5b50900390565b818101828110156112e757fe5b92915050565b6112f682610e40565b1561105f5760408051600081526020810190915261131990849084908490611330565b151561105f57600080fd5b600061102b8383611abc565b600083600160a060020a031663a4c0ed3660e060020a028685856040516024018084600160a060020a0316600160a060020a0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b838110156113a8578181015183820152602001611390565b50505050905090810190601f1680156113d55780820380516001836020036101000a031916815260200191505b5060408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909916989098178852518151919790965086955093509150819050838360005b8381101561146357818101518382015260200161144b565b50505050905090810190601f1680156114905780820380516001836020036101000a031916815260200191505b509150506000604051808303816000865af1979650505050505050565b600160a060020a0382166000908152600360205260409020548111156114d257600080fd5b600160a060020a0382166000908152600360205260409020546114fb908263ffffffff6112c816565b600160a060020a038316600090815260036020526040902055600454611527908263ffffffff6112c816565b600455604080518281529051600160a060020a038416917fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5919081900360200190a2604080518281529051600091600160a060020a03851691600080516020611d728339815191529181900360200190a35050565b80600160a060020a03811615156115b257600080fd5b600160a060020a03831615156115d0576115cb82611b8b565b61105f565b61105f8383611b97565b6000600854826040518082805190602001908083835b6020831061160f5780518252601f1990920191602091820191016115f0565b51815160209384036101000a6000190180199092169116179052604080519290940182900382207f190100000000000000000000000000000000000000000000000000000000000083830152602283019790975260428083019790975283518083039097018752606290910192839052855192945084935085019190508083835b602083106116af5780518252601f199092019160209182019101611690565b5181516020939093036101000a6000190180199091169216919091179052604051920182900390912095945050505050565b6000808460ff16601b14806116f957508460ff16601c145b1515611775576040805160e560020a62461bcd02815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611813576040805160e560020a62461bcd02815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f7565000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60408051600080825260208083018085528a905260ff8916838501526060830188905260808301879052925160019360a0808501949193601f19840193928390039091019190865af115801561186d573d6000803e3d6000fd5b5050604051601f190151915050600160a060020a03811615156118da576040805160e560020a62461bcd02815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015290519081900360640190fd5b95945050505050565b600160a060020a0383161515611968576040805160e560020a62461bcd028152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a03821615156119ee576040805160e560020a62461bcd02815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a0380841660008181526005602090815260408083209487168084529482529182902085905581518581529151600080516020611d928339815191529281900390910190a3505050565b600160a060020a0381161515611a5357600080fd5b600654604051600160a060020a038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a36006805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b33600090815260036020526040812054821115611ad857600080fd5b600160a060020a0383161515611aed57600080fd5b33600090815260036020526040902054611b0d908363ffffffff6112c816565b3360009081526003602052604080822092909255600160a060020a03851681522054611b3f908363ffffffff6112da16565b600160a060020a038416600081815260036020908152604091829020939093558051858152905191923392600080516020611d728339815191529281900390910190a350600192915050565b3031610e0a8282611c44565b604080517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290518391600091600160a060020a038416916370a0823191602480830192602092919082900301818787803b158015611bfc57600080fd5b505af1158015611c10573d6000803e3d6000fd5b505050506040513d6020811015611c2657600080fd5b5051905061106f600160a060020a038516848363ffffffff611cac16565b604051600160a060020a0383169082156108fc029083906000818181858888f193505050501515610e0a578082611c79611d41565b600160a060020a039091168152604051908190036020019082f080158015611ca5573d6000803e3d6000fd5b5050505050565b82600160a060020a031663a9059cbb83836040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a0316815260200182815260200192505050600060405180830381600087803b158015611d0f57600080fd5b505af1158015611d23573d6000803e3d6000fd5b505050503d1561105f5760206000803e600051151561105f57600080fd5b604051602180611d51833901905600608060405260405160208060218339810160405251600160a060020a038116ff00ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925a165627a7a72305820b96bb0733a3e45fdddafa592f51114d0cf16cad047ad60b9b91ae91eb772c6940029" + } + } } } diff --git a/params/chainspecs/rialto.json b/params/chainspecs/rialto.json index 9f5b7936cb1..9a9396077b8 100644 --- a/params/chainspecs/rialto.json +++ b/params/chainspecs/rialto.json @@ -1,26 +1,25 @@ { - "ChainName": "rialto", - "chainId": 1417, - "consensus": "parlia", - "homesteadBlock": 0, - "eip150Block": 0, - "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "eip155Block": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 0, - "petersburgBlock": 0, - "istanbulBlock": 0, - "muirGlacierBlock": 0, - "ramanujanBlock": 400, - "nielsBlock": 0, - "mirrorSyncBlock": 400, - "brunoBlock": 400, - "eulerBlock": 400, - "gibbsBlock": 400, - "parlia": { - "DBPath": "", - "InMemory": false, - "period": 3, - "epoch": 200 - } -} + "ChainName": "rialto", + "chainId": 1417, + "consensus": "parlia", + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "muirGlacierBlock": 0, + "ramanujanBlock": 400, + "nielsBlock": 0, + "mirrorSyncBlock": 400, + "brunoBlock": 400, + "eulerBlock": 400, + "gibbsBlock": 400, + "parlia": { + "DBPath": "", + "InMemory": false, + "period": 3, + "epoch": 200 + } +} \ No newline at end of file diff --git a/params/chainspecs/ropsten.json b/params/chainspecs/ropsten.json new file mode 100644 index 00000000000..17172dd40f4 --- /dev/null +++ b/params/chainspecs/ropsten.json @@ -0,0 +1,17 @@ +{ + "ChainName": "ropsten", + "chainId": 3, + "consensus": "ethash", + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 10, + "byzantiumBlock": 1700000, + "constantinopleBlock": 4230000, + "petersburgBlock": 4939394, + "istanbulBlock": 6485846, + "muirGlacierBlock": 7117117, + "berlinBlock": 9812189, + "londonBlock": 10499401, + "terminalTotalDifficulty": 50000000000000000, + "ethash": {} +} \ No newline at end of file diff --git a/params/chainspecs/sokol.json b/params/chainspecs/sokol.json deleted file mode 100644 index a69ecba07e3..00000000000 --- a/params/chainspecs/sokol.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "ChainName": "sokol", - "chainId": 77, - "consensus": "aura", - "homesteadBlock": 0, - "eip150Block": 0, - "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "eip155Block": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 6464300, - "petersburgBlock": 7026400, - "istanbulBlock": 12095200, - "berlinBlock": 21050600, - "aura": { - "DBPath": "", - "InMemory": false, - "Etherbase": "0x0000000000000000000000000000000000000000" - } -} diff --git a/params/config.go b/params/config.go index 083f6101ab4..762581e0dd4 100644 --- a/params/config.go +++ b/params/config.go @@ -25,7 +25,6 @@ import ( "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" - "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon/common/paths" "github.com/ledgerwatch/erigon/params/networkname" @@ -55,7 +54,6 @@ var ( SepoliaGenesisHash = libcommon.HexToHash("0x25a5cc106eea7138acab33231d7160d69cb777ee0c2c553fcddf5138993e6dd9") RinkebyGenesisHash = libcommon.HexToHash("0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177") GoerliGenesisHash = libcommon.HexToHash("0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a") - SokolGenesisHash = libcommon.HexToHash("0x5b28c1bfd3a15230c9a46b399cd0f9a6920d432e85381cc6a140b06e8410112f") BSCGenesisHash = libcommon.HexToHash("0x0d21840abff46b96c84b2ac9e10e4f5cdaeb5693cb665db62a2f3b02d2d57b5b") ChapelGenesisHash = libcommon.HexToHash("0x6d3c66c5357ec91d5c43af47e234a939b22557cbb552dc45bebbceeed90fbe34") RialtoGenesisHash = libcommon.HexToHash("0xee835a629f9cf5510b48b6ba41d69e0ff7d6ef10f977166ef939db41f59f5501") @@ -67,11 +65,6 @@ var ( ) var ( - SokolGenesisEpochProof = hexutility.FromHex("0xf91a8c80b91a87f91a84f9020da00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0fad4af258fd11939fae0c6c6eec9d340b1caac0b0196fd9a1bc3f489c5bf00b3a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200008083663be080808080b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f91871b914c26060604052600436106100fc576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806303aca79214610101578063108552691461016457806340a141ff1461019d57806340c9cdeb146101d65780634110a489146101ff57806345199e0a1461025757806349285b58146102c15780634d238c8e14610316578063752862111461034f578063900eb5a8146103645780639a573786146103c7578063a26a47d21461041c578063ae4b1b5b14610449578063b3f05b971461049e578063b7ab4db5146104cb578063d3e848f114610535578063fa81b2001461058a578063facd743b146105df575b600080fd5b341561010c57600080fd5b6101226004808035906020019091905050610630565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561016f57600080fd5b61019b600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061066f565b005b34156101a857600080fd5b6101d4600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610807565b005b34156101e157600080fd5b6101e9610bb7565b6040518082815260200191505060405180910390f35b341561020a57600080fd5b610236600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610bbd565b60405180831515151581526020018281526020019250505060405180910390f35b341561026257600080fd5b61026a610bee565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156102ad578082015181840152602081019050610292565b505050509050019250505060405180910390f35b34156102cc57600080fd5b6102d4610c82565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561032157600080fd5b61034d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610d32565b005b341561035a57600080fd5b610362610fcc565b005b341561036f57600080fd5b61038560048080359060200190919050506110fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156103d257600080fd5b6103da61113b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561042757600080fd5b61042f6111eb565b604051808215151515815260200191505060405180910390f35b341561045457600080fd5b61045c6111fe565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156104a957600080fd5b6104b1611224565b604051808215151515815260200191505060405180910390f35b34156104d657600080fd5b6104de611237565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610521578082015181840152602081019050610506565b505050509050019250505060405180910390f35b341561054057600080fd5b6105486112cb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561059557600080fd5b61059d6112f1565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156105ea57600080fd5b610616600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611317565b604051808215151515815260200191505060405180910390f35b60078181548110151561063f57fe5b90600052602060002090016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156106cb57600080fd5b600460019054906101000a900460ff161515156106e757600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561072357600080fd5b80600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600460016101000a81548160ff0219169083151502179055507f600bcf04a13e752d1e3670a5a9f1c21177ca2a93c6f5391d4f1298d098097c22600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b600080600061081461113b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561084d57600080fd5b83600960008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff1615156108a957600080fd5b600960008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101549350600160078054905003925060078381548110151561090857fe5b906000526020600020900160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691508160078581548110151561094657fe5b906000526020600020900160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506007838154811015156109e557fe5b906000526020600020900160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556000600780549050111515610a2757600080fd5b6007805480919060019003610a3c9190611370565b506000600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506000600960008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160006101000a81548160ff0219169083151502179055506000600460006101000a81548160ff0219169083151502179055506001430340600019167f55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89600760405180806020018281038252838181548152602001915080548015610ba257602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610b58575b50509250505060405180910390a25050505050565b60085481565b60096020528060005260406000206000915090508060000160009054906101000a900460ff16908060010154905082565b610bf661139c565b6007805480602002602001604051908101604052809291908181526020018280548015610c7857602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610c2e575b5050505050905090565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166349285b586000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1515610d1257600080fd5b6102c65a03f11515610d2357600080fd5b50505060405180519050905090565b610d3a61113b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610d7357600080fd5b80600960008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff16151515610dd057600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614151515610e0c57600080fd5b6040805190810160405280600115158152602001600780549050815250600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff0219169083151502179055506020820151816001015590505060078054806001018281610ea991906113b0565b9160005260206000209001600084909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506000600460006101000a81548160ff0219169083151502179055506001430340600019167f55252fa6eee4741b4e24a74a70e9c11fd2c2281df8d6ea13126ff845f7825c89600760405180806020018281038252838181548152602001915080548015610fba57602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311610f70575b50509250505060405180910390a25050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480156110365750600460009054906101000a900460ff16155b151561104157600080fd5b6001600460006101000a81548160ff0219169083151502179055506007600690805461106e9291906113dc565b506006805490506008819055507f8564cd629b15f47dc310d45bcbfc9bcf5420b0d51bf0659a16c67f91d27632536110a4611237565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156110e75780820151818401526020810190506110cc565b505050509050019250505060405180910390a1565b60068181548110151561110b57fe5b90600052602060002090016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639a5737866000604051602001526040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15156111cb57600080fd5b6102c65a03f115156111dc57600080fd5b50505060405180519050905090565b600460019054906101000a900460ff1681565b600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900460ff1681565b61123f61139c565b60068054806020026020016040519081016040528092919081815260200182805480156112c157602002820191906000526020600020905b8160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019060010190808311611277575b5050505050905090565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460029054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600960008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff169050919050565b81548183558181151161139757818360005260206000209182019101611396919061142e565b5b505050565b602060405190810160405280600081525090565b8154818355818115116113d7578183600052602060002091820191016113d6919061142e565b5b505050565b82805482825590600052602060002090810192821561141d5760005260206000209182015b8281111561141c578254825591600101919060010190611401565b5b50905061142a9190611453565b5090565b61145091905b8082111561144c576000816000905550600101611434565b5090565b90565b61149391905b8082111561148f57600081816101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550600101611459565b5090565b905600a165627a7a7230582036ea35935c8246b68074adece2eab70c40e69a0193c08a6277ce06e5b25188510029b86bf869a033aa5d69545785694b808840be50c182dad2ec3636dfccbe6572fb69828742c0b846f8440101a0663ce0d171e545a26aa67e4ca66f72ba96bb48287dbcc03beea282867f80d44ba01f0e7726926cb43c03a0abf48197dba78522ec8ba1b158e2aa30da7d2a2c6f9eb8f3f8f1a08023c0d95fc2364e0bf7593f5ff32e1db8ef9f4b41c0bd474eae62d1af896e99808080a0b47b4f0b3e73b5edc8f9a9da1cbcfed562eb06bf54619b6aefeadebf5b3604c280a0da6ec08940a924cb08c947dd56cdb40076b29a6f0ea4dba4e2d02d9a9a72431b80a030cc4138c9e74b6cf79d624b4b5612c0fd888e91f55316cfee7d1694e1a90c0b80a0c5d54b915b56a888eee4e6eeb3141e778f9b674d1d322962eed900f02c29990aa017256b36ef47f907c6b1378a2636942ce894c17075e56fc054d4283f6846659e808080a03340bbaeafcda3a8672eb83099231dbbfab8dae02a1e8ec2f7180538fac207e080b838f7a03868bdfa8727775661e4ccf117824a175a33f8703d728c04488fbfffcafda9f99594e8ddc5c7a2d2f0d7a9798459c0104fdf5e987acab853f851808080a07bb75cabebdcbd1dbb4331054636d0c6d7a2b08483b9e04df057395a7434c9e080808080808080a0e61e567237b49c44d8f906ceea49027260b4010c10a547b38d8b131b9d3b6f848080808080b853f851808080a0a87d9bb950836582673aa0eecc0ff64aac607870637a2dd2012b8b1b31981f698080a08da6d5c36a404670c553a2c9052df7cd604f04e3863c4c7b9e0027bfd54206d680808080808080808080b86bf869a02080c7b7ae81a58eb98d9c78de4a1fd7fd9535fc953ed2be602daaa41767312ab846f8448080a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470b8d3f8d1a0dc277c93a9f9dcee99aac9b8ba3cfa4c51821998522469c37715644e8fbac0bfa0ab8cdb808c8303bb61fb48e276217be9770fa83ecf3f90f2234d558885f5abf1808080a0fe137c3a474fbde41d89a59dd76da4c55bf696b86d3af64a55632f76cf30786780808080a06301b39b2ea8a44df8b0356120db64b788e71f52e1d7a6309d0d2e5b86fee7cb80a0da5d8b08dea0c5a4799c0f44d8a24d7cdf209f9b7a5588c1ecafb5361f6b9f07a01b7779e149cadf24d4ffb77ca7e11314b8db7097e4d70b2a173493153ca2e5a0808080a3e2a02052222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0180") -) - -var ( - SokolGenesisStateRoot = libcommon.HexToHash("0xfad4af258fd11939fae0c6c6eec9d340b1caac0b0196fd9a1bc3f489c5bf00b3") GnosisGenesisStateRoot = libcommon.HexToHash("0x40cf4430ecaa733787d1a65154a3b9efb560c95d9e324a23b97f0609b539133b") ChiadoGenesisStateRoot = libcommon.HexToHash("0x9ec3eaf4e6188dfbdd6ade76eaa88289b57c63c9a2cde8d35291d5a29e143d31") ) @@ -95,8 +88,6 @@ var ( RialtoChainConfig = readChainSpec("chainspecs/rialto.json") - SokolChainConfig = readChainSpec("chainspecs/sokol.json") - // AllProtocolChanges contains every protocol change (EIPs) introduced // and accepted by the Ethereum core developers into the main net protocol. AllProtocolChanges = &chain.Config{ @@ -222,8 +213,6 @@ func ChainConfigByChainName(chain string) *chain.Config { return RinkebyChainConfig case networkname.GoerliChainName: return GoerliChainConfig - case networkname.SokolChainName: - return SokolChainConfig case networkname.BSCChainName: return BSCChainConfig case networkname.ChapelChainName: @@ -255,8 +244,6 @@ func GenesisHashByChainName(chain string) *libcommon.Hash { return &RinkebyGenesisHash case networkname.GoerliChainName: return &GoerliGenesisHash - case networkname.SokolChainName: - return &SokolGenesisHash case networkname.BSCChainName: return &BSCGenesisHash case networkname.ChapelChainName: @@ -288,8 +275,6 @@ func ChainConfigByGenesisHash(genesisHash libcommon.Hash) *chain.Config { return RinkebyChainConfig case genesisHash == GoerliGenesisHash: return GoerliChainConfig - case genesisHash == SokolGenesisHash: - return SokolChainConfig case genesisHash == BSCGenesisHash: return BSCChainConfig case genesisHash == ChapelGenesisHash: diff --git a/params/mining.go b/params/mining.go index 34d47d38c37..d5e0d8cc868 100644 --- a/params/mining.go +++ b/params/mining.go @@ -6,8 +6,7 @@ import ( "time" libcommon "github.com/ledgerwatch/erigon-lib/common" - - "github.com/ledgerwatch/erigon/common/hexutil" + "github.com/ledgerwatch/erigon-lib/common/hexutility" ) // MiningConfig is the configuration parameters of mining. @@ -18,7 +17,7 @@ type MiningConfig struct { Etherbase libcommon.Address `toml:",omitempty"` // Public address for block mining rewards SigKey *ecdsa.PrivateKey // ECDSA private key for signing blocks Notify []string `toml:",omitempty"` // HTTP URL list to be notified of new work packages(only useful in ethash). - ExtraData hexutil.Bytes `toml:",omitempty"` // Block extra data set by the miner + ExtraData hexutility.Bytes `toml:",omitempty"` // Block extra data set by the miner GasLimit uint64 // Target gas limit for mined blocks. GasPrice *big.Int // Minimum gas price for mining a transaction Recommit time.Duration // The time interval for miner to re-create mining work. diff --git a/params/networkname/network_name.go b/params/networkname/network_name.go index 49aa02866aa..2e3b381d5f2 100644 --- a/params/networkname/network_name.go +++ b/params/networkname/network_name.go @@ -6,7 +6,6 @@ const ( RinkebyChainName = "rinkeby" GoerliChainName = "goerli" DevChainName = "dev" - SokolChainName = "sokol" BSCChainName = "bsc" ChapelChainName = "chapel" RialtoChainName = "rialto" @@ -22,7 +21,6 @@ var All = []string{ SepoliaChainName, RinkebyChainName, GoerliChainName, - SokolChainName, BSCChainName, ChapelChainName, //RialtoChainName, diff --git a/params/protocol_params.go b/params/protocol_params.go index a09f2a69bb3..87cbf978776 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -132,8 +132,9 @@ const ( // Precompiled contract gas prices - TendermintHeaderValidateGas uint64 = 3000 // Gas for validate tendermiint consensus state - IAVLMerkleProofValidateGas uint64 = 3000 // Gas for validate merkle proof + TendermintHeaderValidateGas uint64 = 3000 // Gas for validate tendermiint consensus state + IAVLMerkleProofValidateGas uint64 = 3000 // Gas for validate merkle proof + CometBFTLightBlockValidateGas uint64 = 3000 // Gas for validate cometBFT light block EcrecoverGas uint64 = 3000 // Elliptic curve sender recovery gas price Sha256BaseGas uint64 = 60 // Base price for a SHA256 operation @@ -143,6 +144,9 @@ const ( 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 Bn256ScalarMulGasByzantium uint64 = 40000 // Byzantium gas needed for an elliptic curve scalar multiplication diff --git a/params/version.go b/params/version.go index fc23d0af7d9..927c488281e 100644 --- a/params/version.go +++ b/params/version.go @@ -31,10 +31,10 @@ var ( // see https://calver.org const ( - VersionMajor = 2 // Major version component of the current release - VersionMinor = 42 // Minor version component of the current release - VersionMicro = 0 // Patch version component of the current release - VersionModifier = "stable" // Modifier component of the current release + VersionMajor = 2 // Major version component of the current release + VersionMinor = 43 // Minor version component of the current release + VersionMicro = 0 // Patch version component of the current release + VersionModifier = "dev" // Modifier component of the current release VersionKeyCreated = "ErigonVersionCreated" VersionKeyFinished = "ErigonVersionFinished" ) diff --git a/tests/block_test_util.go b/tests/block_test_util.go index 2a96086bd6c..bb10d47b38c 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -27,8 +27,10 @@ import ( "testing" "github.com/holiman/uint256" + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon/common" @@ -95,7 +97,7 @@ type btHeader struct { } type btHeaderMarshaling struct { - ExtraData hexutil.Bytes + ExtraData hexutility.Bytes Number *math.HexOrDecimal256 Difficulty *math.HexOrDecimal256 GasLimit math.HexOrDecimal64 diff --git a/tests/fuzzers/secp256k1/secp_fuzzer.go b/tests/fuzzers/secp256k1/secp_fuzzer.go index a6c7be0ec00..efc84f5d81d 100644 --- a/tests/fuzzers/secp256k1/secp_fuzzer.go +++ b/tests/fuzzers/secp256k1/secp_fuzzer.go @@ -16,6 +16,8 @@ // build +gofuzz +// build +gofuzz + package secp256k1 import ( @@ -44,7 +46,7 @@ func Fuzz(input []byte) int { resBX, resBY := curveB.Add(x1, y1, x2, y2) if resAX.Cmp(resBX) != 0 || resAY.Cmp(resBY) != 0 { fmt.Printf("%s %s %s %s\n", x1, y1, x2, y2) - panic(fmt.Sprintf("Addition failed: erigon: %s %s btcd: %s %s", resAX, resAY, resBX, resBY)) + panic(fmt.Sprintf("Addition failed: geth: %s %s btcd: %s %s", resAX, resAY, resBX, resBY)) } return 0 } diff --git a/tests/gen_btheader.go b/tests/gen_btheader.go index 41722bf16e1..b6187760f75 100644 --- a/tests/gen_btheader.go +++ b/tests/gen_btheader.go @@ -7,8 +7,8 @@ import ( "math/big" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" - "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/common/math" "github.com/ledgerwatch/erigon/core/types" ) @@ -29,7 +29,7 @@ func (b btHeader) MarshalJSON() ([]byte, error) { StateRoot libcommon.Hash TransactionsTrie libcommon.Hash UncleHash libcommon.Hash - ExtraData hexutil.Bytes + ExtraData hexutility.Bytes Difficulty *math.HexOrDecimal256 GasLimit math.HexOrDecimal64 GasUsed math.HexOrDecimal64 @@ -71,7 +71,7 @@ func (b *btHeader) UnmarshalJSON(input []byte) error { StateRoot *libcommon.Hash TransactionsTrie *libcommon.Hash UncleHash *libcommon.Hash - ExtraData *hexutil.Bytes + ExtraData *hexutility.Bytes Difficulty *math.HexOrDecimal256 GasLimit *math.HexOrDecimal64 GasUsed *math.HexOrDecimal64 diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 65c247edd9c..0644db0a496 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -26,15 +26,16 @@ import ( "strings" "github.com/holiman/uint256" + "golang.org/x/crypto/sha3" + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/common/length" "github.com/ledgerwatch/erigon-lib/kv" types2 "github.com/ledgerwatch/erigon-lib/types" - "golang.org/x/crypto/sha3" "github.com/ledgerwatch/erigon/common" - "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/common/math" "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/core/state" @@ -65,14 +66,14 @@ type stJSON struct { Env stEnv `json:"env"` Pre core.GenesisAlloc `json:"pre"` Tx stTransactionMarshaling `json:"transaction"` - Out hexutil.Bytes `json:"out"` + Out hexutility.Bytes `json:"out"` Post map[string][]stPostState `json:"post"` } type stPostState struct { Root common.UnprefixedHash `json:"hash"` Logs common.UnprefixedHash `json:"logs"` - Tx hexutil.Bytes `json:"txbytes"` + Tx hexutility.Bytes `json:"txbytes"` ExpectException string `json:"expectException"` Indexes struct { Data int `json:"data"` @@ -100,7 +101,7 @@ type stTransactionMarshaling struct { MaxPriorityFeePerGas *math.HexOrDecimal256 `json:"maxPriorityFeePerGas"` Nonce math.HexOrDecimal64 `json:"nonce"` GasLimit []math.HexOrDecimal64 `json:"gasLimit"` - PrivateKey hexutil.Bytes `json:"secretKey"` + PrivateKey hexutility.Bytes `json:"secretKey"` To string `json:"to"` Data []string `json:"data"` Value []string `json:"value"` @@ -467,7 +468,9 @@ func toMessage(tx stTransactionMarshaling, ps stPostState, baseFee *big.Int) (co data, accessList, false, /* checkNonce */ - false /* isFree */) + false, /* isFree */ + uint256.NewInt(tipCap.Uint64()), + ) return msg, nil } diff --git a/tests/statedb_chain_test.go b/tests/statedb_chain_test.go index a10e348a9ce..feb4439c987 100644 --- a/tests/statedb_chain_test.go +++ b/tests/statedb_chain_test.go @@ -17,6 +17,7 @@ package tests import ( + "context" "math/big" "testing" @@ -25,8 +26,6 @@ import ( libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/stretchr/testify/require" - "github.com/ledgerwatch/erigon/ethdb/olddb" - "github.com/ledgerwatch/erigon/accounts/abi/bind" "github.com/ledgerwatch/erigon/accounts/abi/bind/backends" "github.com/ledgerwatch/erigon/core" @@ -43,7 +42,7 @@ func TestSelfDestructReceive(t *testing.T) { key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") address = crypto.PubkeyToAddress(key.PublicKey) funds = big.NewInt(1000000000) - gspec = &core.Genesis{ + gspec = &types.Genesis{ Config: &chain.Config{ ChainID: big.NewInt(1), HomesteadBlock: new(big.Int), @@ -52,7 +51,7 @@ func TestSelfDestructReceive(t *testing.T) { TangerineWhistleBlock: new(big.Int), SpuriousDragonBlock: new(big.Int), }, - Alloc: core.GenesisAlloc{ + Alloc: types.GenesisAlloc{ address: {Balance: funds}, }, } @@ -61,8 +60,6 @@ func TestSelfDestructReceive(t *testing.T) { ) m := stages.MockWithGenesis(t, gspec, key, false) - db := olddb.NewObjectDatabase(m.DB) - defer db.Close() contractBackend := backends.NewTestSimulatedBackendWithConfig(t, gspec.Alloc, gspec.Config, gspec.GasLimit) transactOpts, err := bind.NewKeyedTransactorWithChainID(key, m.ChainConfig.ChainID) @@ -77,23 +74,23 @@ func TestSelfDestructReceive(t *testing.T) { // The second block is empty and is only used to force the newly created blockchain object to reload the trie // from the database. chain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 2, func(i int, block *core.BlockGen) { - var tx types.Transaction + var txn types.Transaction switch i { case 0: - contractAddress, tx, selfDestructorContract, err = contracts.DeploySelfDestructor(transactOpts, contractBackend) + contractAddress, txn, selfDestructorContract, err = contracts.DeploySelfDestructor(transactOpts, contractBackend) if err != nil { t.Fatal(err) } - block.AddTx(tx) - tx, err = selfDestructorContract.SelfDestruct(transactOpts) + block.AddTx(txn) + txn, err = selfDestructorContract.SelfDestruct(transactOpts) if err != nil { t.Fatal(err) } - block.AddTx(tx) + block.AddTx(txn) // Send 1 wei to contract after self-destruction - tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), contractAddress, uint256.NewInt(1000), 21000, uint256.NewInt(1), nil), *signer, key) - block.AddTx(tx) + txn, err = types.SignTx(types.NewTransaction(block.TxNonce(address), contractAddress, uint256.NewInt(1000), 21000, uint256.NewInt(1), nil), *signer, key) + block.AddTx(txn) } contractBackend.Commit() }, false /* intermediateHashes */) @@ -101,7 +98,13 @@ func TestSelfDestructReceive(t *testing.T) { t.Fatalf("generate blocks: %v", err) } - st := state.New(state.NewPlainStateReader(db)) + tx, err := m.DB.BeginRo(context.Background()) + if err != nil { + panic(err) + } + defer tx.Rollback() + + st := state.New(m.NewStateReader(tx)) if !st.Exist(address) { t.Error("expected account to exist") } @@ -122,7 +125,12 @@ func TestSelfDestructReceive(t *testing.T) { // and that means that the state of the accounts written in the first block was correct. // This test checks that the storage root of the account is properly set to the root of the empty tree - st = state.New(state.NewPlainStateReader(db)) + tx, err = m.DB.BeginRo(context.Background()) + if err != nil { + panic(err) + } + defer tx.Rollback() + st = state.New(m.NewStateReader(tx)) if !st.Exist(address) { t.Error("expected account to exist") } diff --git a/tests/statedb_insert_chain_transaction_test.go b/tests/statedb_insert_chain_transaction_test.go index e50d28bd8e1..85370133169 100644 --- a/tests/statedb_insert_chain_transaction_test.go +++ b/tests/statedb_insert_chain_transaction_test.go @@ -77,7 +77,7 @@ func TestInsertIncorrectStateRootDifferentAccounts(t *testing.T) { require.NoError(t, err) defer tx.Rollback() - st := state.New(state.NewPlainStateReader(tx)) + st := state.New(m.NewStateReader(tx)) if !st.Exist(to) { t.Error("expected account to exist") } @@ -145,7 +145,7 @@ func TestInsertIncorrectStateRootSameAccount(t *testing.T) { require.NoError(t, err) defer tx.Rollback() - st := state.New(state.NewPlainStateReader(tx)) + st := state.New(m.NewStateReader(tx)) if !st.Exist(to) { t.Error("expected account to exist") } @@ -207,7 +207,7 @@ func TestInsertIncorrectStateRootSameAccountSameAmount(t *testing.T) { require.NoError(t, err) defer tx.Rollback() - st := state.New(state.NewPlainStateReader(tx)) + st := state.New(m.NewStateReader(tx)) if !st.Exist(to) { t.Error("expected account to exist") } @@ -269,7 +269,7 @@ func TestInsertIncorrectStateRootAllFundsRoot(t *testing.T) { require.NoError(t, err) defer tx.Rollback() - st := state.New(state.NewPlainStateReader(tx)) + st := state.New(m.NewStateReader(tx)) if !st.Exist(to) { t.Error("expected account to exist") } @@ -331,7 +331,7 @@ func TestInsertIncorrectStateRootAllFunds(t *testing.T) { require.NoError(t, err) defer tx.Rollback() - st := state.New(state.NewPlainStateReader(tx)) + st := state.New(m.NewStateReader(tx)) if !st.Exist(to) { t.Error("expected account to exist") } @@ -372,7 +372,7 @@ func TestAccountDeployIncorrectRoot(t *testing.T) { t.Fatal(err) } err = m.DB.View(context.Background(), func(tx kv.Tx) error { - st := state.New(state.NewPlainStateReader(tx)) + st := state.New(m.NewStateReader(tx)) if !st.Exist(from) { t.Error("expected account to exist") } @@ -395,7 +395,7 @@ func TestAccountDeployIncorrectRoot(t *testing.T) { } err = m.DB.View(context.Background(), func(tx kv.Tx) error { - st := state.New(state.NewPlainStateReader(tx)) + st := state.New(m.NewStateReader(tx)) if !st.Exist(from) { t.Error("expected account to exist") } @@ -413,7 +413,7 @@ func TestAccountDeployIncorrectRoot(t *testing.T) { } err = m.DB.View(context.Background(), func(tx kv.Tx) error { - st := state.New(state.NewPlainStateReader(tx)) + st := state.New(m.NewStateReader(tx)) if !st.Exist(from) { t.Error("expected account to exist") } @@ -459,7 +459,7 @@ func TestAccountCreateIncorrectRoot(t *testing.T) { } err = m.DB.View(context.Background(), func(tx kv.Tx) error { - st := state.New(state.NewPlainStateReader(tx)) + st := state.New(m.NewStateReader(tx)) if !st.Exist(from) { t.Error("expected account to exist") } @@ -477,7 +477,7 @@ func TestAccountCreateIncorrectRoot(t *testing.T) { t.Fatal(err) } err = m.DB.View(context.Background(), func(tx kv.Tx) error { - st := state.New(state.NewPlainStateReader(tx)) + st := state.New(m.NewStateReader(tx)) if !st.Exist(from) { t.Error("expected account to exist") } @@ -543,7 +543,7 @@ func TestAccountUpdateIncorrectRoot(t *testing.T) { } err = m.DB.View(context.Background(), func(tx kv.Tx) error { - st := state.New(state.NewPlainStateReader(tx)) + st := state.New(m.NewStateReader(tx)) if !st.Exist(from) { t.Error("expected account to exist") } @@ -562,7 +562,7 @@ func TestAccountUpdateIncorrectRoot(t *testing.T) { } err = m.DB.View(context.Background(), func(tx kv.Tx) error { - st := state.New(state.NewPlainStateReader(tx)) + st := state.New(m.NewStateReader(tx)) if !st.Exist(from) { t.Error("expected account to exist") } @@ -632,7 +632,7 @@ func TestAccountDeleteIncorrectRoot(t *testing.T) { } err = m.DB.View(context.Background(), func(tx kv.Tx) error { - st := state.New(state.NewPlainStateReader(tx)) + st := state.New(m.NewStateReader(tx)) if !st.Exist(from) { t.Error("expected account to exist") } @@ -650,7 +650,7 @@ func TestAccountDeleteIncorrectRoot(t *testing.T) { } err = m.DB.View(context.Background(), func(tx kv.Tx) error { - st := state.New(state.NewPlainStateReader(tx)) + st := state.New(m.NewStateReader(tx)) if !st.Exist(from) { t.Error("expected account to exist") } diff --git a/tests/testdata b/tests/testdata deleted file mode 160000 index b6247b008e9..00000000000 --- a/tests/testdata +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b6247b008e934adf981a9d0d5f903477004f9d7d diff --git a/tests/transaction_test_util.go b/tests/transaction_test_util.go index 5eee06e75cc..f2d063650b8 100644 --- a/tests/transaction_test_util.go +++ b/tests/transaction_test_util.go @@ -23,10 +23,11 @@ import ( "math/big" "github.com/holiman/uint256" + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/hexutility" - "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/common/math" "github.com/ledgerwatch/erigon/core" "github.com/ledgerwatch/erigon/core/types" @@ -35,8 +36,8 @@ import ( // TransactionTest checks RLP decoding and sender derivation of transactions. type TransactionTest struct { - RLP hexutil.Bytes `json:"txbytes"` - Forks ttForks `json:"result"` + RLP hexutility.Bytes `json:"txbytes"` + Forks ttForks `json:"result"` } type ttForks struct { @@ -60,7 +61,7 @@ type ttFork struct { } func (tt *TransactionTest) Run(chainID *big.Int) error { - validateTx := func(rlpData hexutil.Bytes, signer types.Signer, rules *chain.Rules) (*libcommon.Address, *libcommon.Hash, uint64, error) { + validateTx := func(rlpData hexutility.Bytes, signer types.Signer, rules *chain.Rules) (*libcommon.Address, *libcommon.Hash, uint64, error) { tx, err := types.DecodeTransaction(rlp.NewStream(bytes.NewReader(rlpData), 0)) if err != nil { return nil, nil, 0, err diff --git a/turbo/adapter/ethapi/api.go b/turbo/adapter/ethapi/api.go index 43c36e4343b..863309d46e7 100644 --- a/turbo/adapter/ethapi/api.go +++ b/turbo/adapter/ethapi/api.go @@ -43,9 +43,10 @@ type CallArgs struct { GasPrice *hexutil.Big `json:"gasPrice"` MaxPriorityFeePerGas *hexutil.Big `json:"maxPriorityFeePerGas"` MaxFeePerGas *hexutil.Big `json:"maxFeePerGas"` + MaxFeePerDataGas *hexutil.Big `json:"maxFeePerDataGas"` Value *hexutil.Big `json:"value"` Nonce *hexutil.Uint64 `json:"nonce"` - Data *hexutil.Bytes `json:"data"` + Data *hexutility.Bytes `json:"data"` AccessList *types2.AccessList `json:"accessList"` ChainID *hexutil.Big `json:"chainId,omitempty"` } @@ -81,9 +82,10 @@ func (args *CallArgs) ToMessage(globalGasCap uint64, baseFee *uint256.Int) (type } var ( - gasPrice *uint256.Int - gasFeeCap *uint256.Int - gasTipCap *uint256.Int + gasPrice *uint256.Int + gasFeeCap *uint256.Int + gasTipCap *uint256.Int + maxFeePerDataGas *uint256.Int ) if baseFee == nil { // If there's no basefee, then it must be a non-1559 execution @@ -127,6 +129,9 @@ func (args *CallArgs) ToMessage(globalGasCap uint64, baseFee *uint256.Int) (type gasPrice = math.U256Min(new(uint256.Int).Add(gasTipCap, baseFee), gasFeeCap) } } + if args.MaxFeePerDataGas != nil { + maxFeePerDataGas.SetFromBig(args.MaxFeePerDataGas.ToInt()) + } } value := new(uint256.Int) @@ -145,7 +150,7 @@ func (args *CallArgs) ToMessage(globalGasCap uint64, baseFee *uint256.Int) (type accessList = *args.AccessList } - msg := types.NewMessage(addr, args.To, 0, value, gas, gasPrice, gasFeeCap, gasTipCap, data, accessList, false /* checkNonce */, false /* isFree */) + msg := types.NewMessage(addr, args.To, 0, value, gas, gasPrice, gasFeeCap, gasTipCap, data, accessList, false /* checkNonce */, false /* isFree */, maxFeePerDataGas) return msg, nil } @@ -157,7 +162,7 @@ func (args *CallArgs) ToMessage(globalGasCap uint64, baseFee *uint256.Int) (type // message. type Account struct { Nonce *hexutil.Uint64 `json:"nonce"` - Code *hexutil.Bytes `json:"code"` + Code *hexutility.Bytes `json:"code"` Balance **hexutil.Big `json:"balance"` State *map[libcommon.Hash]uint256.Int `json:"state"` StateDiff *map[libcommon.Hash]uint256.Int `json:"stateDiff"` @@ -267,7 +272,7 @@ func RPCMarshalHeader(head *types.Header) map[string]interface{} { "stateRoot": head.Root, "miner": head.Coinbase, "difficulty": (*hexutil.Big)(head.Difficulty), - "extraData": hexutil.Bytes(head.Extra), + "extraData": hexutility.Bytes(head.Extra), "size": hexutil.Uint64(head.Size()), "gasLimit": hexutil.Uint64(head.GasLimit), "gasUsed": hexutil.Uint64(head.GasUsed), @@ -374,8 +379,9 @@ type RPCTransaction struct { GasPrice *hexutil.Big `json:"gasPrice,omitempty"` Tip *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"` FeeCap *hexutil.Big `json:"maxFeePerGas,omitempty"` + MaxFeePerDataGas *hexutil.Big `json:"maxFeePerDataGas,omitempty"` Hash libcommon.Hash `json:"hash"` - Input hexutil.Bytes `json:"input"` + Input hexutility.Bytes `json:"input"` Nonce hexutil.Uint64 `json:"nonce"` To *libcommon.Address `json:"to"` TransactionIndex *hexutil.Uint64 `json:"transactionIndex"` @@ -400,7 +406,7 @@ func newRPCTransaction(tx types.Transaction, blockHash libcommon.Hash, blockNumb Type: hexutil.Uint64(tx.Type()), Gas: hexutil.Uint64(tx.GetGas()), Hash: tx.Hash(), - Input: hexutil.Bytes(tx.GetData()), + Input: hexutility.Bytes(tx.GetData()), Nonce: hexutil.Uint64(tx.GetNonce()), To: tx.GetTo(), Value: (*hexutil.Big)(tx.GetValue().ToBig()), @@ -441,6 +447,7 @@ func newRPCTransaction(tx types.Transaction, blockHash libcommon.Hash, blockNumb } else { result.GasPrice = nil } + // case *types.SignedBlobTx: // TODO } signer := types.LatestSignerForChainID(chainId.ToBig()) var err error @@ -466,7 +473,7 @@ func newRPCBorTransaction(opaqueTx types.Transaction, txHash libcommon.Hash, blo GasPrice: (*hexutil.Big)(tx.GasPrice.ToBig()), Gas: hexutil.Uint64(tx.GetGas()), Hash: txHash, - Input: hexutil.Bytes(tx.GetData()), + Input: hexutility.Bytes(tx.GetData()), Nonce: hexutil.Uint64(tx.GetNonce()), From: libcommon.Address{}, To: tx.GetTo(), diff --git a/turbo/app/import.go b/turbo/app/import.go index 9838af1a2e7..379d922c6f3 100644 --- a/turbo/app/import.go +++ b/turbo/app/import.go @@ -52,15 +52,13 @@ func importChain(ctx *cli.Context) error { utils.Fatalf("This command requires an argument.") } - logger := log.New(ctx) - nodeCfg := turboNode.NewNodConfigUrfave(ctx) ethCfg := turboNode.NewEthConfigUrfave(ctx, nodeCfg) stack := makeConfigNode(nodeCfg) defer stack.Close() - ethereum, err := eth.New(stack, ethCfg, logger) + ethereum, err := eth.New(stack, ethCfg) if err != nil { return err } diff --git a/turbo/app/init.go b/turbo/app/init.go index 9c7f516d51e..6327b75870a 100644 --- a/turbo/app/init.go +++ b/turbo/app/init.go @@ -54,7 +54,7 @@ func initGenesis(ctx *cli.Context) error { stack := MakeConfigNodeDefault(ctx) defer stack.Close() - chaindb, err := node.OpenDatabase(stack.Config(), log.New(ctx), kv.ChainDB) + chaindb, err := node.OpenDatabase(stack.Config(), kv.ChainDB) if err != nil { utils.Fatalf("Failed to open database: %v", err) } diff --git a/turbo/app/snapshots.go b/turbo/app/snapshots.go index 03bcff9db8f..2bd3879805f 100644 --- a/turbo/app/snapshots.go +++ b/turbo/app/snapshots.go @@ -355,6 +355,7 @@ func doRetireCommand(cliCtx *cli.Context) error { return err } agg.SetWorkers(estimate.CompressSnapshot.Workers()) + agg.CleanDir() if to == 0 { var forwardProgress uint64 @@ -373,7 +374,7 @@ func doRetireCommand(cliCtx *cli.Context) error { if err := br.RetireBlocks(ctx, i, i+every, log.LvlInfo); err != nil { panic(err) } - if err := db.Update(ctx, func(tx kv.RwTx) error { + if err := db.UpdateNosync(ctx, func(tx kv.RwTx) error { if err := rawdb.WriteSnapshots(tx, br.Snapshots().Files(), agg.Files()); err != nil { return err } @@ -394,7 +395,7 @@ func doRetireCommand(cliCtx *cli.Context) error { log.Info("Prune state history") for i := 0; i < 1024; i++ { - if err := db.Update(ctx, func(tx kv.RwTx) error { + if err := db.UpdateNosync(ctx, func(tx kv.RwTx) error { agg.SetTx(tx) if err = agg.Prune(ctx, ethconfig.HistoryV3AggregationStep/10); err != nil { return err @@ -411,9 +412,10 @@ func doRetireCommand(cliCtx *cli.Context) error { return err } + var lastTxNum uint64 if err := db.View(ctx, func(tx kv.Tx) error { execProgress, _ := stages.GetStageProgress(tx, stages.Execution) - lastTxNum, err := rawdbv3.TxNums.Max(tx, execProgress) + lastTxNum, err = rawdbv3.TxNums.Max(tx, execProgress) if err != nil { return err } @@ -424,14 +426,14 @@ func doRetireCommand(cliCtx *cli.Context) error { } log.Info("Build state history snapshots") - if err = agg.BuildFiles(ctx, db); err != nil { + if err = agg.BuildFiles(lastTxNum); err != nil { return err } + if err = agg.MergeLoop(ctx, estimate.CompressSnapshot.Workers()); err != nil { return err } - - if err := db.Update(ctx, func(tx kv.RwTx) error { + if err := db.UpdateNosync(ctx, func(tx kv.RwTx) error { return rawdb.WriteSnapshots(tx, snapshots.Files(), agg.Files()) }); err != nil { return err @@ -439,7 +441,7 @@ func doRetireCommand(cliCtx *cli.Context) error { log.Info("Prune state history") for i := 0; i < 1024; i++ { - if err := db.Update(ctx, func(tx kv.RwTx) error { + if err := db.UpdateNosync(ctx, func(tx kv.RwTx) error { agg.SetTx(tx) if err = agg.Prune(ctx, ethconfig.HistoryV3AggregationStep/10); err != nil { return err @@ -449,6 +451,11 @@ func doRetireCommand(cliCtx *cli.Context) error { return err } } + if err := db.Update(ctx, func(tx kv.RwTx) error { + return rawdb.WriteSnapshots(tx, snapshots.Files(), agg.Files()) + }); err != nil { + return err + } return nil } diff --git a/turbo/app/support.go b/turbo/app/support.go index 02473457f30..ef0faa613c8 100644 --- a/turbo/app/support.go +++ b/turbo/app/support.go @@ -1,17 +1,38 @@ package app import ( + "bufio" + "bytes" + "context" + "crypto/tls" + "crypto/x509" + "encoding/binary" + "fmt" "io" "net/http" "os" "os/signal" - "path" "syscall" "time" - "github.com/ledgerwatch/erigon/cmd/utils" "github.com/ledgerwatch/log/v3" "github.com/urfave/cli/v2" + "golang.org/x/net/http2" +) + +var ( + diagnosticsURLFlag = cli.StringFlag{ + Name: "diagnostics.url", + Usage: "URL of the diagnostics system provided by the support team, include unique session PIN", + } + metricsURLsFlag = cli.StringSliceFlag{ + Name: "metrics.urls", + Usage: "Comma separated list of URLs to the metrics endpoints thats are being diagnosed", + } + insecureFlag = cli.BoolFlag{ + Name: "insecure", + Usage: "Allows communication with diagnostics system using self-signed TLS certificates", + } ) var supportCommand = cli.Command{ @@ -20,8 +41,9 @@ var supportCommand = cli.Command{ Usage: "Connect Erigon instance to a diagnostics system for support", ArgsUsage: "--diagnostics.url --metrics.url ", Flags: []cli.Flag{ - &utils.MetricsURLsFlag, - &utils.DiagnosticsURLFlag, + &metricsURLsFlag, + &diagnosticsURLFlag, + &insecureFlag, }, Category: "SUPPORT COMMANDS", Description: ` @@ -29,42 +51,138 @@ The support command connects a running Erigon instances to a diagnostics system by the URL.`, } -func connectDiagnostics(ctx *cli.Context) error { +const Version = 1 + +func connectDiagnostics(cliCtx *cli.Context) error { sigs := make(chan os.Signal, 1) - interruptCh := make(chan bool, 1) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + metricsURLs := cliCtx.StringSlice(metricsURLsFlag.Name) + metricsURL := metricsURLs[0] // TODO: Generalise + + diagnosticsUrl := cliCtx.String(diagnosticsURLFlag.Name) + + // Create a pool with the server certificate since it is not signed + // by a known CA + certPool := x509.NewCertPool() + + // Create TLS configuration with the certificate of the server + insecure := cliCtx.Bool(insecureFlag.Name) + tlsConfig := &tls.Config{ + RootCAs: certPool, + InsecureSkipVerify: insecure, //nolint:gosec + } + + // Perform the requests in a loop (reconnect) + for { + if err := tunnel(ctx, cancel, sigs, tlsConfig, diagnosticsUrl, metricsURL); err != nil { + return err + } + select { + case <-ctx.Done(): + // Quit immediately if the context was cancelled (by Ctrl-C or TERM signal) + return nil + default: + } + log.Info("Reconnecting in 1 second...") + timer := time.NewTimer(1 * time.Second) + <-timer.C + } +} + +var successLine = []byte("SUCCESS") + +// tunnel operates the tunnel from diagnostics system to the metrics URL for one http/2 request +// needs to be called repeatedly to implement re-connect logic +func tunnel(ctx context.Context, cancel context.CancelFunc, sigs chan os.Signal, tlsConfig *tls.Config, diagnosticsUrl string, metricsURL string) error { + diagnosticsClient := &http.Client{Transport: &http2.Transport{TLSClientConfig: tlsConfig}} + defer diagnosticsClient.CloseIdleConnections() + metricsClient := &http.Client{} + defer metricsClient.CloseIdleConnections() + // Create a request object to send to the server + reader, writer := io.Pipe() + ctx1, cancel1 := context.WithCancel(ctx) + defer cancel1() go func() { - <-sigs - interruptCh <- true - }() - interrupt := false - pollInterval := 500 * time.Millisecond - pollEvery := time.NewTicker(pollInterval) - defer pollEvery.Stop() - client := &http.Client{} - defer client.CloseIdleConnections() - diagnosticsUrl := ctx.String(utils.DiagnosticsURLFlag.Name) - giveRequestsUrl := path.Join(diagnosticsUrl, "giveRequests") - for !interrupt { select { - case interrupt = <-interruptCh: - log.Info("interrupted, please wait for cleanup") - case <-pollEvery.C: - pollResponse, err := client.Get(giveRequestsUrl) - if err != nil { - log.Error("Polling problem", "err", err) - } else if pollResponse.StatusCode != http.StatusOK { - log.Error("Polling problem", "status", pollResponse.Status) - } else { - buf := make([]byte, pollResponse.ContentLength) - if _, err = io.ReadFull(pollResponse.Body, buf); err != nil { - log.Error("Reading polling response", "err", err) - } - log.Info("Polling response", "resp", string(buf)) + case <-sigs: + cancel() + case <-ctx1.Done(): + } + reader.Close() + writer.Close() + }() + req, err := http.NewRequestWithContext(ctx1, http.MethodPost, diagnosticsUrl, reader) + if err != nil { + return err + } + + // Create a connection + // Apply given context to the sent request + resp, err := diagnosticsClient.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + defer writer.Close() + + // Apply the connection context on the request context + var metricsBuf bytes.Buffer + r := bufio.NewReaderSize(resp.Body, 4096) + line, isPrefix, err := r.ReadLine() + if err != nil { + return fmt.Errorf("reading first line: %v", err) + } + if isPrefix { + return fmt.Errorf("request too long") + } + if !bytes.Equal(line, successLine) { + return fmt.Errorf("connecting to diagnostics system, first line [%s]", line) + } + var versionBytes [8]byte + binary.BigEndian.PutUint64(versionBytes[:], Version) + if _, err = writer.Write(versionBytes[:]); err != nil { + return fmt.Errorf("sending version: %v", err) + } + + log.Info("Connected") + + for line, isPrefix, err = r.ReadLine(); err == nil && !isPrefix; line, isPrefix, err = r.ReadLine() { + metricsBuf.Reset() + metricsResponse, err := metricsClient.Get(metricsURL + string(line)) + if err != nil { + fmt.Fprintf(&metricsBuf, "ERROR: Requesting metrics url [%s], query [%s], err: %v", metricsURL, line, err) + } else { + // Buffer the metrics response, and relay it back to the diagnostics system, prepending with the size + if _, err := io.Copy(&metricsBuf, metricsResponse.Body); err != nil { + metricsBuf.Reset() + fmt.Fprintf(&metricsBuf, "ERROR: Extracting metrics url [%s], query [%s], err: %v", metricsURL, line, err) } - pollResponse.Body.Close() + metricsResponse.Body.Close() + } + var sizeBuf [4]byte + binary.BigEndian.PutUint32(sizeBuf[:], uint32(metricsBuf.Len())) + if _, err = writer.Write(sizeBuf[:]); err != nil { + log.Error("Problem relaying metrics prefix len", "url", metricsURL, "query", line, "err", err) + break + } + if _, err = writer.Write(metricsBuf.Bytes()); err != nil { + log.Error("Problem relaying", "url", metricsURL, "query", line, "err", err) + break } } + if err != nil { + select { + case <-ctx.Done(): + default: + log.Error("Breaking connection", "err", err) + } + } + if isPrefix { + log.Error("Request too long, circuit breaker") + } return nil } diff --git a/turbo/cli/default_flags.go b/turbo/cli/default_flags.go index c31aa481f71..58570bbda9e 100644 --- a/turbo/cli/default_flags.go +++ b/turbo/cli/default_flags.go @@ -12,7 +12,7 @@ var DefaultFlags = []cli.Flag{ &utils.DataDirFlag, &utils.EthashDatasetDirFlag, &utils.SnapshotFlag, - &utils.ExternalConsensusFlag, + &utils.InternalConsensusFlag, &utils.TxPoolDisableFlag, &utils.TxPoolLocalsFlag, &utils.TxPoolNoLocalsFlag, @@ -85,6 +85,7 @@ var DefaultFlags = []cli.Flag{ &utils.SnapKeepBlocksFlag, &utils.SnapStopFlag, &utils.DbPageSizeFlag, + &utils.DbSizeLimitFlag, &utils.TorrentPortFlag, &utils.TorrentMaxPeersFlag, &utils.TorrentConnsPerFileFlag, diff --git a/turbo/cli/flags.go b/turbo/cli/flags.go index d8a944aa401..3489aadb9a7 100644 --- a/turbo/cli/flags.go +++ b/turbo/cli/flags.go @@ -2,7 +2,6 @@ package cli import ( "fmt" - "strings" "time" libcommon "github.com/ledgerwatch/erigon-lib/common" @@ -208,7 +207,7 @@ func ApplyFlagsForEthConfig(ctx *cli.Context, cfg *ethconfig.Config) { ctx.Uint64(PruneReceiptBeforeFlag.Name), ctx.Uint64(PruneTxIndexBeforeFlag.Name), ctx.Uint64(PruneCallTracesBeforeFlag.Name), - strings.Split(ctx.String(ExperimentsFlag.Name), ","), + utils.SplitAndTrim(ctx.String(ExperimentsFlag.Name)), ) if err != nil { utils.Fatalf(fmt.Sprintf("error while parsing mode: %v", err)) @@ -363,10 +362,10 @@ func setEmbeddedRpcDaemon(ctx *cli.Context, cfg *nodecfg.Config) { AuthRpcPort: ctx.Int(utils.AuthRpcPort.Name), JWTSecretPath: jwtSecretPath, TraceRequests: ctx.Bool(utils.HTTPTraceFlag.Name), - HttpCORSDomain: strings.Split(ctx.String(utils.HTTPCORSDomainFlag.Name), ","), - HttpVirtualHost: strings.Split(ctx.String(utils.HTTPVirtualHostsFlag.Name), ","), - AuthRpcVirtualHost: strings.Split(ctx.String(utils.AuthRpcVirtualHostsFlag.Name), ","), - API: strings.Split(apis, ","), + HttpCORSDomain: utils.SplitAndTrim(ctx.String(utils.HTTPCORSDomainFlag.Name)), + HttpVirtualHost: utils.SplitAndTrim(ctx.String(utils.HTTPVirtualHostsFlag.Name)), + AuthRpcVirtualHost: utils.SplitAndTrim(ctx.String(utils.AuthRpcVirtualHostsFlag.Name)), + API: utils.SplitAndTrim(apis), HTTPTimeouts: rpccfg.HTTPTimeouts{ ReadTimeout: ctx.Duration(HTTPReadTimeoutFlag.Name), WriteTimeout: ctx.Duration(HTTPWriteTimeoutFlag.Name), diff --git a/turbo/debug/flags.go b/turbo/debug/flags.go index 19bbdbe4dd4..fcafe071da6 100644 --- a/turbo/debug/flags.go +++ b/turbo/debug/flags.go @@ -80,7 +80,7 @@ func SetupCobra(cmd *cobra.Command) error { RaiseFdLimit() flags := cmd.Flags() - _ = logging.GetLoggerCmd("debug", cmd) + logging.SetupLoggerCmd("erigon", cmd) traceFile, err := flags.GetString(traceFlag.Name) if err != nil { @@ -144,7 +144,7 @@ func SetupCobra(cmd *cobra.Command) error { func Setup(ctx *cli.Context) error { RaiseFdLimit() - _ = logging.GetLoggerCtx("debug", ctx) + logging.SetupLoggerCtx("erigon", ctx) if traceFile := ctx.String(traceFlag.Name); traceFile != "" { if err := Handler.StartGoTrace(traceFile); err != nil { @@ -166,6 +166,9 @@ func Setup(ctx *cli.Context) error { exp.Setup(address) diagnostics.SetupLogsAccess(ctx) diagnostics.SetupDbAccess(ctx) + diagnostics.SetupCmdLineAccess() + diagnostics.SetupVersionAccess() + diagnostics.SetupBlockBodyDownload() } // pprof server diff --git a/turbo/logging/flags.go b/turbo/logging/flags.go index a5ce6658118..bf070e2fe1e 100644 --- a/turbo/logging/flags.go +++ b/turbo/logging/flags.go @@ -41,7 +41,7 @@ var ( LogDirVerbosityFlag = cli.StringFlag{ Name: "log.dir.verbosity", Usage: "Set the log verbosity for logs stored to disk", - Value: log.LvlDebug.String(), + Value: log.LvlInfo.String(), } ) diff --git a/turbo/logging/logging.go b/turbo/logging/logging.go index 597a1263610..09b03863d7f 100644 --- a/turbo/logging/logging.go +++ b/turbo/logging/logging.go @@ -4,14 +4,16 @@ import ( "flag" "os" "path" + "path/filepath" "strconv" "github.com/ledgerwatch/log/v3" "github.com/spf13/cobra" "github.com/urfave/cli/v2" + "gopkg.in/natefinch/lumberjack.v2" ) -func GetLoggerCtx(filePrefix string, ctx *cli.Context) log.Logger { +func SetupLoggerCtx(filePrefix string, ctx *cli.Context) { var consoleJson = ctx.Bool(LogJsonFlag.Name) || ctx.Bool(LogConsoleJsonFlag.Name) var dirJson = ctx.Bool(LogDirJsonFlag.Name) @@ -26,14 +28,20 @@ func GetLoggerCtx(filePrefix string, ctx *cli.Context) log.Logger { dirLevel, dErr := tryGetLogLevel(ctx.String(LogDirVerbosityFlag.Name)) if dErr != nil { - dirLevel = log.LvlDebug + dirLevel = log.LvlInfo } dirPath := ctx.String(LogDirPathFlag.Name) - return initSeparatedLogging(filePrefix, dirPath, consoleLevel, dirLevel, consoleJson, dirJson) + if dirPath == "" { + datadir := ctx.String("datadir") + if datadir != "" { + dirPath = filepath.Join(datadir, "logs") + } + } + initSeparatedLogging(filePrefix, dirPath, consoleLevel, dirLevel, consoleJson, dirJson) } -func GetLoggerCmd(filePrefix string, cmd *cobra.Command) log.Logger { +func SetupLoggerCmd(filePrefix string, cmd *cobra.Command) { logJsonVal, ljerr := cmd.Flags().GetBool(LogJsonFlag.Name) if ljerr != nil { @@ -62,14 +70,20 @@ func GetLoggerCmd(filePrefix string, cmd *cobra.Command) log.Logger { dirLevel, dErr := tryGetLogLevel(cmd.Flags().Lookup(LogDirVerbosityFlag.Name).Value.String()) if dErr != nil { - dirLevel = log.LvlDebug + dirLevel = log.LvlInfo } dirPath := cmd.Flags().Lookup(LogDirPathFlag.Name).Value.String() - return initSeparatedLogging(filePrefix, dirPath, consoleLevel, dirLevel, consoleJson, dirJson) + if dirPath == "" { + datadir := cmd.Flags().Lookup("datadir").Value.String() + if datadir != "" { + dirPath = filepath.Join(datadir, "logs") + } + } + initSeparatedLogging(filePrefix, dirPath, consoleLevel, dirLevel, consoleJson, dirJson) } -func GetLogger(filePrefix string) log.Logger { +func SetupLogger(filePrefix string) { var logConsoleVerbosity = flag.String(LogConsoleVerbosityFlag.Name, "", LogConsoleVerbosityFlag.Usage) var logDirVerbosity = flag.String(LogDirVerbosityFlag.Name, "", LogDirVerbosityFlag.Usage) var logDirPath = flag.String(LogDirPathFlag.Name, "", LogDirPathFlag.Usage) @@ -93,10 +107,10 @@ func GetLogger(filePrefix string) log.Logger { dirLevel, dErr := tryGetLogLevel(*logDirVerbosity) if dErr != nil { - dirLevel = log.LvlDebug + dirLevel = log.LvlInfo } - return initSeparatedLogging(filePrefix, *logDirPath, consoleLevel, dirLevel, consoleJson, *dirJson) + initSeparatedLogging(filePrefix, *logDirPath, consoleLevel, dirLevel, consoleJson, *dirJson) } func initSeparatedLogging( @@ -105,7 +119,7 @@ func initSeparatedLogging( consoleLevel log.Lvl, dirLevel log.Lvl, consoleJson bool, - dirJson bool) log.Logger { + dirJson bool) { logger := log.Root() @@ -117,36 +131,31 @@ func initSeparatedLogging( if len(dirPath) == 0 { logger.Warn("no log dir set, console logging only") - return logger + return } err := os.MkdirAll(dirPath, 0764) if err != nil { logger.Warn("failed to create log dir, console logging only") - return logger + return } - dirFormat := log.LogfmtFormat() + dirFormat := log.TerminalFormatNoColor() if dirJson { dirFormat = log.JsonFormat() } - userLog, err := log.FileHandler(path.Join(dirPath, filePrefix+"-user.log"), dirFormat, 1<<27) // 128Mb - if err != nil { - logger.Warn("failed to open user log, console logging only") - return logger - } - errLog, err := log.FileHandler(path.Join(dirPath, filePrefix+"-error.log"), dirFormat, 1<<27) // 128Mb - if err != nil { - logger.Warn("failed to open error log, console logging only") - return logger + lumberjack := &lumberjack.Logger{ + Filename: path.Join(dirPath, filePrefix+".log"), + MaxSize: 100, // megabytes + MaxBackups: 3, + MaxAge: 28, //days } + userLog := log.StreamHandler(lumberjack, dirFormat) - mux := log.MultiHandler(logger.GetHandler(), log.LvlFilterHandler(dirLevel, userLog), log.LvlFilterHandler(log.LvlError, errLog)) + mux := log.MultiHandler(logger.GetHandler(), log.LvlFilterHandler(dirLevel, userLog)) log.Root().SetHandler(mux) - logger.SetHandler(mux) logger.Info("logging to file system", "log dir", dirPath, "file prefix", filePrefix, "log level", dirLevel, "json", dirJson) - return logger } func tryGetLogLevel(s string) (log.Lvl, error) { diff --git a/turbo/node/node.go b/turbo/node/node.go index b74d6c48557..d89f6c71b19 100644 --- a/turbo/node/node.go +++ b/turbo/node/node.go @@ -102,7 +102,6 @@ func NewEthConfigUrfave(ctx *cli.Context, nodeConfig *nodecfg.Config) *ethconfig func New( nodeConfig *nodecfg.Config, ethConfig *ethconfig.Config, - logger log.Logger, ) (*ErigonNode, error) { //prepareBuckets(optionalParams.CustomBuckets) node, err := node.New(nodeConfig) @@ -110,7 +109,7 @@ func New( utils.Fatalf("Failed to create Erigon node: %v", err) } - ethereum, err := eth.New(node, ethConfig, logger) + ethereum, err := eth.New(node, ethConfig) if err != nil { return nil, err } diff --git a/turbo/rpchelper/interface.go b/turbo/rpchelper/interface.go index 9daee67c168..80583eae7b7 100644 --- a/turbo/rpchelper/interface.go +++ b/turbo/rpchelper/interface.go @@ -28,6 +28,7 @@ type ApiBackend interface { EngineNewPayload(ctx context.Context, payload *types2.ExecutionPayload) (*remote.EnginePayloadStatus, error) EngineForkchoiceUpdated(ctx context.Context, request *remote.EngineForkChoiceUpdatedRequest) (*remote.EngineForkChoiceUpdatedResponse, error) EngineGetPayload(ctx context.Context, payloadId uint64) (*remote.EngineGetPayloadResponse, error) + EngineGetBlobsBundleV1(ctx context.Context, payloadId uint64) (*types2.BlobsBundleV1, error) NodeInfo(ctx context.Context, limit uint32) ([]p2p.NodeInfo, error) Peers(ctx context.Context) ([]*p2p.PeerInfo, error) PendingBlock(ctx context.Context) (*types.Block, error) diff --git a/turbo/shards/state_change_accumulator.go b/turbo/shards/state_change_accumulator.go index 7d698b8760b..321337f722b 100644 --- a/turbo/shards/state_change_accumulator.go +++ b/turbo/shards/state_change_accumulator.go @@ -36,7 +36,7 @@ func (a *Accumulator) SendAndReset(ctx context.Context, c StateChangeConsumer, p if a == nil || c == nil || len(a.changes) == 0 { return } - sc := &remote.StateChangeBatch{StateVersionID: a.plainStateID, ChangeBatch: a.changes, PendingBlockBaseFee: pendingBaseFee, BlockGasLimit: blockGasLimit} + sc := &remote.StateChangeBatch{StateVersionId: a.plainStateID, ChangeBatch: a.changes, PendingBlockBaseFee: pendingBaseFee, BlockGasLimit: blockGasLimit} c.SendStateChanges(ctx, sc) a.Reset(0) // reset here for GC, but there will be another Reset with correct viewID } diff --git a/turbo/snapshotsync/block_reader.go b/turbo/snapshotsync/block_reader.go index e49823a0cf9..ccd820952bd 100644 --- a/turbo/snapshotsync/block_reader.go +++ b/turbo/snapshotsync/block_reader.go @@ -465,6 +465,7 @@ func (back *BlockReaderWithSnapshots) bodyFromSnapshot(blockHeight uint64, sn *B body := new(types.Body) body.Uncles = b.Uncles + body.Withdrawals = b.Withdrawals var txsAmount uint32 if b.TxAmount >= 2 { txsAmount = b.TxAmount - 2 diff --git a/turbo/snapshotsync/block_snapshots.go b/turbo/snapshotsync/block_snapshots.go index c7a4c119c1b..20ca42a4ef2 100644 --- a/turbo/snapshotsync/block_snapshots.go +++ b/turbo/snapshotsync/block_snapshots.go @@ -862,8 +862,8 @@ func (s *RoSnapshots) ViewTxs(blockNum uint64, f func(sn *TxnSegment) error) (fo } func buildIdx(ctx context.Context, sn snaptype.FileInfo, chainID uint256.Int, tmpDir string, p *background.Progress, lvl log.Lvl) error { - _, fName := filepath.Split(sn.Path) - log.Debug("[snapshots] build idx", "file", fName) + //_, fName := filepath.Split(sn.Path) + //log.Debug("[snapshots] build idx", "file", fName) switch sn.T { case snaptype.Headers: if err := HeadersIdx(ctx, sn.Path, sn.From, tmpDir, p, lvl); err != nil { @@ -885,8 +885,7 @@ func buildIdx(ctx context.Context, sn snaptype.FileInfo, chainID uint256.Int, tm func BuildMissedIndices(logPrefix string, ctx context.Context, dirs datadir.Dirs, chainID uint256.Int, workers int) error { dir, tmpDir := dirs.Snap, dirs.Tmp //log.Log(lvl, "[snapshots] Build indices", "from", min) - logEvery := time.NewTicker(20 * time.Second) - defer logEvery.Stop() + segments, _, err := Segments(dir) if err != nil { return err @@ -920,6 +919,8 @@ func BuildMissedIndices(logPrefix string, ctx context.Context, dirs datadir.Dirs g.Wait() }() + logEvery := time.NewTicker(20 * time.Second) + defer logEvery.Stop() for { select { case <-finish: @@ -1793,8 +1794,6 @@ RETRY: return fmt.Errorf("txnHash2BlockNumIdx: %w", err) } - p.Processed.Store(p.Total.Load()) - return nil } @@ -2027,7 +2026,6 @@ func (m *Merger) Merge(ctx context.Context, snapshots *RoSnapshots, mergeRanges } logEvery := time.NewTicker(30 * time.Second) defer logEvery.Stop() - log.Log(m.lvl, "[snapshots] Merge segments", "ranges", fmt.Sprintf("%v", mergeRanges)) for _, r := range mergeRanges { toMerge, err := m.filesByRange(snapshots, r.from, r.to) if err != nil { @@ -2090,14 +2088,6 @@ func (m *Merger) merge(ctx context.Context, toMerge []string, targetFile string, if err := f.AddWord(word); err != nil { return err } - select { - case <-ctx.Done(): - return ctx.Err() - case <-logEvery.C: - _, fName := filepath.Split(targetFile) - log.Info("[snapshots] Merge", "progress", fmt.Sprintf("%.2f%%", 100*float64(f.Count())/float64(expectedTotal)), "to", fName) - default: - } } return nil }); err != nil { diff --git a/turbo/stages/blockchain_test.go b/turbo/stages/blockchain_test.go index e349fd9f4a5..dbc654b3ef4 100644 --- a/turbo/stages/blockchain_test.go +++ b/turbo/stages/blockchain_test.go @@ -928,7 +928,7 @@ func TestEIP161AccountRemoval(t *testing.T) { t.Fatal(err) } err = m.DB.View(context.Background(), func(tx kv.Tx) error { - if st := state.New(state.NewPlainStateReader(tx)); !st.Exist(theAddr) { + if st := state.New(m.NewStateReader(tx)); !st.Exist(theAddr) { t.Error("expected account to exist") } return nil @@ -939,8 +939,8 @@ func TestEIP161AccountRemoval(t *testing.T) { if err = m.InsertChain(chain.Slice(1, 2)); err != nil { t.Fatal(err) } - err = m.DB.View(context.Background(), func(tx kv.Tx) error { - if st := state.New(state.NewPlainStateReader(tx)); st.Exist(theAddr) { + err = m.DB.View(m.Ctx, func(tx kv.Tx) error { + if st := state.New(m.NewStateReader(tx)); st.Exist(theAddr) { t.Error("account should not exist") } return nil @@ -951,8 +951,8 @@ func TestEIP161AccountRemoval(t *testing.T) { if err = m.InsertChain(chain.Slice(2, 3)); err != nil { t.Fatal(err) } - err = m.DB.View(context.Background(), func(tx kv.Tx) error { - if st := state.New(state.NewPlainStateReader(tx)); st.Exist(theAddr) { + err = m.DB.View(m.Ctx, func(tx kv.Tx) error { + if st := state.New(m.NewStateReader(tx)); st.Exist(theAddr) { t.Error("account should not exist") } return nil @@ -1017,7 +1017,7 @@ func TestDoubleAccountRemoval(t *testing.T) { }) assert.NoError(t, err) - tx, err := m.DB.BeginRo(context.Background()) + tx, err := m.DB.BeginRo(m.Ctx) if err != nil { t.Fatalf("read only db tx to read state: %v", err) } @@ -1074,7 +1074,7 @@ func TestBlockchainHeaderchainReorgConsistency(t *testing.T) { t.Fatalf("block %d: failed to insert into chain: %v", i, err) } - if err := m2.DB.View(context.Background(), func(tx kv.Tx) error { + if err := m2.DB.View(m2.Ctx, func(tx kv.Tx) error { b, h := rawdb.ReadCurrentBlock(tx), rawdb.ReadCurrentHeader(tx) if b.Hash() != h.Hash() { t.Errorf("block %d: current block/header mismatch: block #%d [%x…], header #%d [%x…]", i, b.Number(), b.Hash().Bytes()[:4], h.Number, h.Hash().Bytes()[:4]) @@ -1385,7 +1385,7 @@ func TestDeleteRecreateSlots(t *testing.T) { if err := m.InsertChain(chain); err != nil { t.Fatalf("failed to insert into chain: %v", err) } - err = m.DB.View(context.Background(), func(tx kv.Tx) error { + err = m.DB.View(m.Ctx, func(tx kv.Tx) error { statedb := state.New(m.NewHistoryStateReader(2, tx)) // If all is correct, then slot 1 and 2 are zero @@ -1503,7 +1503,7 @@ func TestCVE2020_26265(t *testing.T) { if err := m.InsertChain(chain); err != nil { t.Fatalf("failed to insert into chain: %v", err) } - err = m.DB.View(context.Background(), func(tx kv.Tx) error { + err = m.DB.View(m.Ctx, func(tx kv.Tx) error { reader := m.NewHistoryStateReader(2, tx) statedb := state.New(reader) @@ -1570,7 +1570,7 @@ func TestDeleteRecreateAccount(t *testing.T) { if err := m.InsertChain(chain); err != nil { t.Fatalf("failed to insert into chain: %v", err) } - err = m.DB.View(context.Background(), func(tx kv.Tx) error { + err = m.DB.View(m.Ctx, func(tx kv.Tx) error { statedb := state.New(m.NewHistoryStateReader(2, tx)) // If all is correct, then both slots are zero @@ -1880,7 +1880,7 @@ func TestInitThenFailCreateContract(t *testing.T) { t.Fatalf("generate blocks: %v", err) } - err = m.DB.View(context.Background(), func(tx kv.Tx) error { + err = m.DB.View(m.Ctx, func(tx kv.Tx) error { // Import the canonical chain statedb := state.New(m.NewHistoryStateReader(2, tx)) @@ -1978,7 +1978,7 @@ func TestEIP2718Transition(t *testing.T) { t.Fatalf("failed to insert into chain: %v", err) } - tx, err := m.DB.BeginRo(context.Background()) + tx, err := m.DB.BeginRo(m.Ctx) if err != nil { t.Fatal(err) } @@ -2088,7 +2088,7 @@ func TestEIP1559Transition(t *testing.T) { t.Fatalf("incorrect amount of gas spent: expected %d, got %d", expectedGas, block.GasUsed()) } - err = m.DB.View(context.Background(), func(tx kv.Tx) error { + err = m.DB.View(m.Ctx, func(tx kv.Tx) error { statedb := state.New(m.NewHistoryStateReader(1, tx)) // 3: Ensure that miner received only the tx's tip. @@ -2129,7 +2129,7 @@ func TestEIP1559Transition(t *testing.T) { } block = chain.Blocks[0] - err = m.DB.View(context.Background(), func(tx kv.Tx) error { + err = m.DB.View(m.Ctx, func(tx kv.Tx) error { statedb := state.New(m.NewHistoryStateReader(1, tx)) effectiveTip := block.Transactions()[0].GetPrice().Uint64() - block.BaseFee().Uint64() diff --git a/turbo/stages/bodydownload/body_algos.go b/turbo/stages/bodydownload/body_algos.go index 3f055c24912..b80f83ce6cd 100644 --- a/turbo/stages/bodydownload/body_algos.go +++ b/turbo/stages/bodydownload/body_algos.go @@ -16,6 +16,7 @@ import ( "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/types" + "github.com/ledgerwatch/erigon/dataflow" "github.com/ledgerwatch/erigon/eth/stagedsync/stages" "github.com/ledgerwatch/erigon/turbo/adapter" "github.com/ledgerwatch/erigon/turbo/services" @@ -88,6 +89,7 @@ func (bd *BodyDownload) RequestMoreBodies(tx kv.RwTx, blockReader services.FullB continue } bd.peerMap[req.peerID]++ + dataflow.BlockBodyDownloadStates.AddChange(blockNum, dataflow.BlockBodyExpired) delete(bd.requests, blockNum) } @@ -147,12 +149,14 @@ func (bd *BodyDownload) RequestMoreBodies(tx kv.RwTx, blockReader services.FullB body.Withdrawals = make([]*types.Withdrawal, 0) } bd.addBodyToCache(blockNum, body) + dataflow.BlockBodyDownloadStates.AddChange(blockNum, dataflow.BlockBodyEmpty) request = false } else { // Perhaps we already have this block block := rawdb.ReadBlock(tx, hash, blockNum) if block != nil { bd.addBodyToCache(blockNum, block.RawBody()) + dataflow.BlockBodyDownloadStates.AddChange(blockNum, dataflow.BlockBodyInDb) request = false } } @@ -192,6 +196,7 @@ func (bd *BodyDownload) checkPrefetchedBlock(hash libcommon.Hash, tx kv.RwTx, bl bd.deliveriesH[blockNum] = header // make sure we have the body in the bucket for later use + dataflow.BlockBodyDownloadStates.AddChange(blockNum, dataflow.BlockBodyPrefetched) bd.addBodyToCache(blockNum, body) // Calculate the TD of the block (it's not imported yet, so block.Td is not valid) @@ -215,6 +220,7 @@ func (bd *BodyDownload) RequestSent(bodyReq *BodyRequest, timeWithTimeout uint64 //} for _, num := range bodyReq.BlockNums { bd.requests[num] = bodyReq + dataflow.BlockBodyDownloadStates.AddChange(num, dataflow.BlockBodyRequested) } bodyReq.waitUntil = timeWithTimeout bodyReq.peerID = peer @@ -317,11 +323,16 @@ Loop: bd.addBodyToCache(blockNum, &types.RawBody{Transactions: txs[i], Uncles: uncles[i], Withdrawals: withdrawals[i]}) bd.delivered.Add(blockNum) delivered++ + dataflow.BlockBodyDownloadStates.AddChange(blockNum, dataflow.BlockBodyReceived) } // Clean up the requests //var clearedNums []uint64 for blockNum := range toClean { delete(bd.requests, blockNum) + if !bd.delivered.Contains(blockNum) { + // Delivery was requested but was skipped due to the limitation on the size of the response + dataflow.BlockBodyDownloadStates.AddChange(blockNum, dataflow.BlockBodySkipped) + } //clearedNums = append(clearedNums, blockNum) } //sort.Slice(deliveredNums, func(i, j int) bool { return deliveredNums[i] < deliveredNums[j] }) @@ -417,6 +428,7 @@ func (bd *BodyDownload) addBodyToCache(key uint64, body *types.RawBody) { item, _ := bd.bodyCache.DeleteMax() bd.bodyCacheSize -= item.payloadSize delete(bd.requests, item.blockNum) + dataflow.BlockBodyDownloadStates.AddChange(item.blockNum, dataflow.BlockBodyEvicted) } } diff --git a/turbo/stages/chain_makers_test.go b/turbo/stages/chain_makers_test.go index 98658800212..825669fb99d 100644 --- a/turbo/stages/chain_makers_test.go +++ b/turbo/stages/chain_makers_test.go @@ -106,7 +106,7 @@ func TestGenerateChain(t *testing.T) { } defer tx.Rollback() - st := state.New(state.NewPlainStateReader(tx)) + st := state.New(m.NewStateReader(tx)) if big.NewInt(5).Cmp(current(m.DB).Number()) != 0 { t.Errorf("wrong block number: %d", current(m.DB).Number()) } diff --git a/turbo/stages/headerdownload/header_algo_test.go b/turbo/stages/headerdownload/header_algo_test.go index 8b168bbd709..ea6b3d95980 100644 --- a/turbo/stages/headerdownload/header_algo_test.go +++ b/turbo/stages/headerdownload/header_algo_test.go @@ -54,11 +54,11 @@ func TestInserter1(t *testing.T) { } h2Hash := h2.Hash() data1, _ := rlp.EncodeToBytes(&h1) - if _, err = hi.FeedHeaderPoW(tx, snapshotsync.NewBlockReaderWithSnapshots(m.BlockSnapshots, m.TransactionsV3), &h1, data1, h1Hash, 1); err != nil { + if _, err = hi.FeedHeaderPoW(tx, snapshotsync.NewBlockReaderWithSnapshots(m.BlockSnapshots, m.TransactionsV3), &h1, data1, h1Hash, 1, nil, *chainConfig, nil); err != nil { t.Errorf("feed empty header 1: %v", err) } data2, _ := rlp.EncodeToBytes(&h2) - if _, err = hi.FeedHeaderPoW(tx, snapshotsync.NewBlockReaderWithSnapshots(m.BlockSnapshots, m.TransactionsV3), &h2, data2, h2Hash, 2); err != nil { + if _, err = hi.FeedHeaderPoW(tx, snapshotsync.NewBlockReaderWithSnapshots(m.BlockSnapshots, m.TransactionsV3), &h2, data2, h2Hash, 2, nil, *chainConfig, nil); err != nil { t.Errorf("feed empty header 2: %v", err) } } diff --git a/turbo/stages/headerdownload/header_algos.go b/turbo/stages/headerdownload/header_algos.go index 07aec41d2c3..a6c2adf533c 100644 --- a/turbo/stages/headerdownload/header_algos.go +++ b/turbo/stages/headerdownload/header_algos.go @@ -14,6 +14,7 @@ import ( "strings" "time" + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/etl" "github.com/ledgerwatch/erigon-lib/kv" @@ -497,7 +498,7 @@ func (hd *HeaderDownload) RequestSkeleton() *HeaderRequest { } func (hd *HeaderDownload) VerifyHeader(header *types.Header) error { - return hd.engine.VerifyHeader(hd.consensusHeaderReader, header, true /* seal */) + return hd.Engine.VerifyHeader(hd.ConsensusHeaderReader, header, true /* seal */) } type FeedHeaderFunc = func(header *types.Header, headerRaw []byte, hash libcommon.Hash, blockHeight uint64) (td *big.Int, err error) @@ -785,9 +786,9 @@ func (hd *HeaderDownload) addHeaderAsLink(h ChainSegmentHeader, persisted bool) return link } -func (hi *HeaderInserter) NewFeedHeaderFunc(db kv.StatelessRwTx, headerReader services.HeaderReader) FeedHeaderFunc { +func (hi *HeaderInserter) NewFeedHeaderFunc(db kv.StatelessRwTx, headerReader services.HeaderReader, engine consensus.Engine, config chain.Config, consensusHeaderReader consensus.ChainHeaderReader) FeedHeaderFunc { return func(header *types.Header, headerRaw []byte, hash libcommon.Hash, blockHeight uint64) (*big.Int, error) { - return hi.FeedHeaderPoW(db, headerReader, header, headerRaw, hash, blockHeight) + return hi.FeedHeaderPoW(db, headerReader, header, headerRaw, hash, blockHeight, engine, config, consensusHeaderReader) } } @@ -844,7 +845,7 @@ func (hi *HeaderInserter) ForkingPoint(db kv.StatelessRwTx, header, parent *type return } -func (hi *HeaderInserter) FeedHeaderPoW(db kv.StatelessRwTx, headerReader services.HeaderReader, header *types.Header, headerRaw []byte, hash libcommon.Hash, blockHeight uint64) (td *big.Int, err error) { +func (hi *HeaderInserter) FeedHeaderPoW(db kv.StatelessRwTx, headerReader services.HeaderReader, header *types.Header, headerRaw []byte, hash libcommon.Hash, blockHeight uint64, engine consensus.Engine, config chain.Config, consensusHeaderReader consensus.ChainHeaderReader) (td *big.Int, err error) { if hash == hi.prevHash { // Skip duplicates return nil, nil @@ -857,6 +858,7 @@ func (hi *HeaderInserter) FeedHeaderPoW(db kv.StatelessRwTx, headerReader servic // Already inserted, skip return nil, nil } + // Load parent header parent, err := headerReader.Header(context.Background(), db, header.ParentHash, blockHeight-1) if err != nil { @@ -866,15 +868,38 @@ func (hi *HeaderInserter) FeedHeaderPoW(db kv.StatelessRwTx, headerReader servic // Fail on headers without parent return nil, fmt.Errorf("could not find parent with hash %x and height %d for header %x %d", header.ParentHash, blockHeight-1, hash, blockHeight) } - // Parent's total difficulty - parentTd, err := rawdb.ReadTd(db, header.ParentHash, blockHeight-1) - if err != nil || parentTd == nil { - return nil, fmt.Errorf("[%s] parent's total difficulty not found with hash %x and height %d for header %x %d: %v", hi.logPrefix, header.ParentHash, blockHeight-1, hash, blockHeight, err) + + isWithFastFinality := true + reorgFunc := func() (bool, error) { + if p, ok := engine.(consensus.PoSA); ok { + justifiedNumber, curJustifiedNumber := uint64(0), uint64(0) + if config.IsPlato(header.Number.Uint64()) { + if justifiedNumberGot, _, err := p.GetJustifiedNumberAndHash(consensusHeaderReader, header); err == nil { + justifiedNumber = justifiedNumberGot + } + } + if config.IsPlato(hi.highest) { + if justifiedNumberGot, _, err := p.GetJustifiedNumberAndHash(consensusHeaderReader, header); err == nil { + curJustifiedNumber = justifiedNumberGot + } + } + if justifiedNumber == curJustifiedNumber { + // Parent's total difficulty + parentTd, err := rawdb.ReadTd(db, header.ParentHash, blockHeight-1) + if err != nil || parentTd == nil { + return false, fmt.Errorf("[%s] parent's total difficulty not found with hash %x and height %d for header %x %d: %v", hi.logPrefix, header.ParentHash, blockHeight-1, hash, blockHeight, err) + } + // Calculate total difficulty of this header using parent's total difficulty + td = new(big.Int).Add(parentTd, header.Difficulty) + isWithFastFinality = false + return td.Cmp(hi.localTd) > 0, nil + } + return justifiedNumber > curJustifiedNumber, nil + } + return false, nil } - // Calculate total difficulty of this header using parent's total difficulty - td = new(big.Int).Add(parentTd, header.Difficulty) // Now we can decide wether this header will create a change in the canonical head - if td.Cmp(hi.localTd) > 0 { + if reorg, err := reorgFunc(); err == nil && reorg { hi.newCanonical = true forkingPoint, err := hi.ForkingPoint(db, header, parent) if err != nil { @@ -890,8 +915,11 @@ func (hi *HeaderInserter) FeedHeaderPoW(db kv.StatelessRwTx, headerReader servic hi.unwind = true } // This makes sure we end up choosing the chain with the max total difficulty - hi.localTd.Set(td) + if !isWithFastFinality { + hi.localTd.Set(td) + } } + if err = rawdb.WriteTd(db, hash, blockHeight, td); err != nil { return nil, fmt.Errorf("[%s] failed to WriteTd: %w", hi.logPrefix, err) } @@ -1066,7 +1094,7 @@ func (hd *HeaderDownload) SetFirstPoSHeight(blockHeight uint64) { func (hd *HeaderDownload) SetHeaderReader(headerReader consensus.ChainHeaderReader) { hd.lock.Lock() defer hd.lock.Unlock() - hd.consensusHeaderReader = headerReader + hd.ConsensusHeaderReader = headerReader } func (hd *HeaderDownload) AfterInitialCycle() { diff --git a/turbo/stages/headerdownload/header_data_struct.go b/turbo/stages/headerdownload/header_data_struct.go index a1266990ee0..7b11b3bc311 100644 --- a/turbo/stages/headerdownload/header_data_struct.go +++ b/turbo/stages/headerdownload/header_data_struct.go @@ -8,8 +8,8 @@ import ( "time" "github.com/google/btree" - lru "github.com/hashicorp/golang-lru" - libcommon "github.com/ledgerwatch/erigon-lib/common" + lru "github.com/hashicorp/golang-lru/v2" + "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/etl" "github.com/ledgerwatch/erigon/consensus" @@ -36,9 +36,9 @@ const ( type Link struct { header *types.Header headerRaw []byte - fChild *Link // Pointer to the first child, further children can be found by following `next` pointers to the siblings - next *Link // Pointer to the next sibling, or nil if there are no siblings - hash libcommon.Hash // Hash of the header + fChild *Link // Pointer to the first child, further children can be found by following `next` pointers to the siblings + next *Link // Pointer to the next sibling, or nil if there are no siblings + hash common.Hash // Hash of the header blockHeight uint64 persisted bool // Whether this link comes from the database record verified bool // Ancestor of pre-verified header or verified by consensus engine @@ -105,8 +105,8 @@ func (lq *LinkQueue) Pop() interface{} { // more than one pointer. type Anchor struct { peerID [64]byte - fLink *Link // Links attached immediately to this anchor (pointer to the first one, the rest can be found by following `next` fields) - parentHash libcommon.Hash // Hash of the header this anchor can be connected to (to disappear) + fLink *Link // Links attached immediately to this anchor (pointer to the first one, the rest can be found by following `next` fields) + parentHash common.Hash // Hash of the header this anchor can be connected to (to disappear) blockHeight uint64 nextRetryTime time.Time // Zero when anchor has just been created, otherwise time when anchor needs to be check to see if retry is needed timeouts int // Number of timeout that this anchor has experiences - after certain threshold, it gets invalidated @@ -115,7 +115,7 @@ type Anchor struct { type ChainSegmentHeader struct { HeaderRaw rlp.RawValue Header *types.Header - Hash libcommon.Hash + Hash common.Hash Number uint64 } @@ -149,7 +149,7 @@ type PeerPenalty struct { // Request for chain segment starting with hash and going to its parent, etc, with length headers in total type HeaderRequest struct { - Hash libcommon.Hash + Hash common.Hash Number uint64 Length uint64 Skip uint64 @@ -162,12 +162,12 @@ type PenaltyItem struct { Penalty Penalty } type Announce struct { - Hash libcommon.Hash + Hash common.Hash Number uint64 } type VerifySealFunc func(header *types.Header) error -type CalcDifficultyFunc func(childTimestamp uint64, parentTime uint64, parentDifficulty, parentNumber *big.Int, parentHash, parentUncleHash libcommon.Hash) *big.Int +type CalcDifficultyFunc func(childTimestamp uint64, parentTime uint64, parentDifficulty, parentNumber *big.Int, parentHash, parentUncleHash common.Hash) *big.Int // InsertQueue keeps the links before they are inserted in the database // It priorities them by block height (the lowest block height on the top), @@ -227,10 +227,10 @@ type Stats struct { } type HeaderDownload struct { - badHeaders map[libcommon.Hash]struct{} - anchors map[libcommon.Hash]*Anchor // Mapping from parentHash to collection of anchors - links map[libcommon.Hash]*Link // Links by header hash - engine consensus.Engine + badHeaders map[common.Hash]struct{} + anchors map[common.Hash]*Anchor // Mapping from parentHash to collection of anchors + links map[common.Hash]*Link // Links by header hash + Engine consensus.Engine insertQueue InsertQueue // Priority queue of non-persisted links that need to be verified and can be inserted seenAnnounces *SeenAnnounces // External announcement hashes, after header verification if hash is in this set - will broadcast it further persistedLinkQueue LinkQueue // Priority queue of persisted links used to limit their number @@ -251,7 +251,7 @@ type HeaderDownload struct { trace bool stats Stats - consensusHeaderReader consensus.ChainHeaderReader + ConsensusHeaderReader consensus.ChainHeaderReader headerReader services.HeaderReader // Proof of Stake (PoS) @@ -259,17 +259,17 @@ type HeaderDownload struct { requestId int posAnchor *Anchor posStatus SyncStatus - posSync bool // Whether the chain is syncing in the PoS mode - headersCollector *etl.Collector // ETL collector for headers - BeaconRequestList *engineapi.RequestList // Requests from ethbackend to staged sync - PayloadStatusCh chan engineapi.PayloadStatus // Responses (validation/execution status) - ShutdownCh chan struct{} // Channel to signal shutdown - pendingPayloadHash libcommon.Hash // Header whose status we still should send to PayloadStatusCh - pendingPayloadStatus *engineapi.PayloadStatus // Alternatively, there can be an already prepared response to send to PayloadStatusCh - unsettledForkChoice *engineapi.ForkChoiceMessage // Forkchoice to process after unwind - unsettledHeadHeight uint64 // Height of unsettledForkChoice.headBlockHash - posDownloaderTip libcommon.Hash // See https://hackmd.io/GDc0maGsQeKfP8o2C7L52w - badPoSHeaders map[libcommon.Hash]libcommon.Hash // Invalid Tip -> Last Valid Ancestor + posSync bool // Whether the chain is syncing in the PoS mode + headersCollector *etl.Collector // ETL collector for headers + BeaconRequestList *engineapi.RequestList // Requests from ethbackend to staged sync + PayloadStatusCh chan engineapi.PayloadStatus // Responses (validation/execution status) + ShutdownCh chan struct{} // Channel to signal shutdown + pendingPayloadHash common.Hash // Header whose status we still should send to PayloadStatusCh + pendingPayloadStatus *engineapi.PayloadStatus // Alternatively, there can be an already prepared response to send to PayloadStatusCh + unsettledForkChoice *engineapi.ForkChoiceMessage // Forkchoice to process after unwind + unsettledHeadHeight uint64 // Height of unsettledForkChoice.headBlockHash + posDownloaderTip common.Hash // See https://hackmd.io/GDc0maGsQeKfP8o2C7L52w + badPoSHeaders map[common.Hash]common.Hash // Invalid Tip -> Last Valid Ancestor } // HeaderRecord encapsulates two forms of the same header - raw RLP encoding (to avoid duplicated decodings and encodings), and parsed value types.Header @@ -287,13 +287,13 @@ func NewHeaderDownload( persistentLinkLimit := linkLimit / 16 hd := &HeaderDownload{ initialCycle: true, - badHeaders: make(map[libcommon.Hash]struct{}), - anchors: make(map[libcommon.Hash]*Anchor), + badHeaders: make(map[common.Hash]struct{}), + anchors: make(map[common.Hash]*Anchor), persistedLinkLimit: persistentLinkLimit, linkLimit: linkLimit - persistentLinkLimit, anchorLimit: anchorLimit, - engine: engine, - links: make(map[libcommon.Hash]*Link), + Engine: engine, + links: make(map[common.Hash]*Link), anchorTree: btree.NewG[*Anchor](32, func(a, b *Anchor) bool { return a.blockHeight < b.blockHeight }), seenAnnounces: NewSeenAnnounces(), DeliveryNotify: make(chan struct{}, 1), @@ -302,7 +302,7 @@ func NewHeaderDownload( PayloadStatusCh: make(chan engineapi.PayloadStatus, 1), ShutdownCh: make(chan struct{}), headerReader: headerReader, - badPoSHeaders: make(map[libcommon.Hash]libcommon.Hash), + badPoSHeaders: make(map[common.Hash]common.Hash), } heap.Init(&hd.persistedLinkQueue) heap.Init(&hd.linkQueue) @@ -371,14 +371,14 @@ func (hd *HeaderDownload) moveLinkToQueue(link *Link, queueId QueueID) { type HeaderInserter struct { localTd *big.Int logPrefix string - prevHash libcommon.Hash // Hash of previously seen header - to filter out potential duplicates - highestHash libcommon.Hash + prevHash common.Hash // Hash of previously seen header - to filter out potential duplicates + highestHash common.Hash newCanonical bool unwind bool unwindPoint uint64 highest uint64 highestTimestamp uint64 - canonicalCache *lru.Cache + canonicalCache *lru.Cache[uint64, common.Hash] headerReader services.HeaderAndCanonicalReader } @@ -389,24 +389,24 @@ func NewHeaderInserter(logPrefix string, localTd *big.Int, headerProgress uint64 unwindPoint: headerProgress, headerReader: headerReader, } - hi.canonicalCache, _ = lru.New(1000) + hi.canonicalCache, _ = lru.New[uint64, common.Hash](1000) return hi } // SeenAnnounces - external announcement hashes, after header verification if hash is in this set - will broadcast it further type SeenAnnounces struct { - hashes *lru.Cache + hashes *lru.Cache[common.Hash, struct{}] } func NewSeenAnnounces() *SeenAnnounces { - cache, err := lru.New(1000) + cache, err := lru.New[common.Hash, struct{}](1000) if err != nil { panic("error creating prefetching cache for blocks") } return &SeenAnnounces{hashes: cache} } -func (s *SeenAnnounces) Pop(hash libcommon.Hash) bool { +func (s *SeenAnnounces) Pop(hash common.Hash) bool { _, ok := s.hashes.Get(hash) if ok { s.hashes.Remove(hash) @@ -414,11 +414,11 @@ func (s *SeenAnnounces) Pop(hash libcommon.Hash) bool { return ok } -func (s SeenAnnounces) Seen(hash libcommon.Hash) bool { +func (s SeenAnnounces) Seen(hash common.Hash) bool { _, ok := s.hashes.Get(hash) return ok } -func (s *SeenAnnounces) Add(b libcommon.Hash) { +func (s *SeenAnnounces) Add(b common.Hash) { s.hashes.ContainsOrAdd(b, struct{}{}) } diff --git a/turbo/stages/mock_sentry.go b/turbo/stages/mock_sentry.go index 6a980bbd426..535f611063b 100644 --- a/turbo/stages/mock_sentry.go +++ b/turbo/stages/mock_sentry.go @@ -27,7 +27,9 @@ import ( "github.com/ledgerwatch/erigon-lib/kv/remotedbserver" libstate "github.com/ledgerwatch/erigon-lib/state" "github.com/ledgerwatch/erigon-lib/txpool" + "github.com/ledgerwatch/erigon-lib/txpool/txpoolcfg" types2 "github.com/ledgerwatch/erigon-lib/types" + "github.com/ledgerwatch/erigon/turbo/trie" "github.com/ledgerwatch/log/v3" "google.golang.org/protobuf/types/known/emptypb" @@ -66,12 +68,12 @@ type MockSentry struct { proto_sentry.UnimplementedSentryServer Ctx context.Context Log log.Logger - t *testing.T + tb testing.TB cancel context.CancelFunc DB kv.RwDB Dirs datadir.Dirs Engine consensus.Engine - gspec *core.Genesis + gspec *types.Genesis ChainConfig *chain.Config Sync *stagedsync.Sync MiningSync *stagedsync.Sync @@ -202,23 +204,23 @@ func (ms *MockSentry) NodeInfo(context.Context, *emptypb.Empty) (*ptypes.NodeInf return nil, nil } -func MockWithGenesis(t *testing.T, gspec *core.Genesis, key *ecdsa.PrivateKey, withPosDownloader bool) *MockSentry { - return MockWithGenesisPruneMode(t, gspec, key, prune.DefaultMode, withPosDownloader) +func MockWithGenesis(tb testing.TB, gspec *types.Genesis, key *ecdsa.PrivateKey, withPosDownloader bool) *MockSentry { + return MockWithGenesisPruneMode(tb, gspec, key, prune.DefaultMode, withPosDownloader) } -func MockWithGenesisEngine(t *testing.T, gspec *core.Genesis, engine consensus.Engine, withPosDownloader bool) *MockSentry { +func MockWithGenesisEngine(tb testing.TB, gspec *types.Genesis, engine consensus.Engine, withPosDownloader bool) *MockSentry { key, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - return MockWithEverything(t, gspec, key, prune.DefaultMode, engine, false, withPosDownloader) + return MockWithEverything(tb, gspec, key, prune.DefaultMode, engine, false, withPosDownloader) } -func MockWithGenesisPruneMode(t *testing.T, gspec *core.Genesis, key *ecdsa.PrivateKey, prune prune.Mode, withPosDownloader bool) *MockSentry { - return MockWithEverything(t, gspec, key, prune, ethash.NewFaker(), false, withPosDownloader) +func MockWithGenesisPruneMode(tb testing.TB, gspec *types.Genesis, key *ecdsa.PrivateKey, prune prune.Mode, withPosDownloader bool) *MockSentry { + return MockWithEverything(tb, gspec, key, prune, ethash.NewFaker(), false, withPosDownloader) } -func MockWithEverything(t *testing.T, gspec *core.Genesis, key *ecdsa.PrivateKey, prune prune.Mode, engine consensus.Engine, withTxPool bool, withPosDownloader bool) *MockSentry { +func MockWithEverything(tb testing.TB, gspec *types.Genesis, key *ecdsa.PrivateKey, prune prune.Mode, engine consensus.Engine, withTxPool bool, withPosDownloader bool) *MockSentry { var tmpdir string - if t != nil { - tmpdir = t.TempDir() + if tb != nil { + tmpdir = tb.TempDir() } else { tmpdir = os.TempDir() } @@ -234,8 +236,8 @@ func MockWithEverything(t *testing.T, gspec *core.Genesis, key *ecdsa.PrivateKey cfg.DeprecatedTxPool.StartOnInit = true var db kv.RwDB - if t != nil { - db = memdb.NewTestDB(t) + if tb != nil { + db = memdb.NewTestDB(tb) } else { db = memdb.New(tmpdir) } @@ -268,7 +270,7 @@ func MockWithEverything(t *testing.T, gspec *core.Genesis, key *ecdsa.PrivateKey allSnapshots := snapshotsync.NewRoSnapshots(ethconfig.Defaults.Snapshot, dirs.Snap) mock := &MockSentry{ Ctx: ctx, cancel: ctxCancel, DB: db, agg: agg, - t: t, + tb: tb, Log: log.New(), Dirs: dirs, Engine: engine, @@ -287,8 +289,8 @@ func MockWithEverything(t *testing.T, gspec *core.Genesis, key *ecdsa.PrivateKey HistoryV3: cfg.HistoryV3, TransactionsV3: cfg.TransactionsV3, } - if t != nil { - t.Cleanup(mock.Close) + if tb != nil { + tb.Cleanup(mock.Close) } blockReader := snapshotsync.NewBlockReaderWithSnapshots(mock.BlockSnapshots, mock.TransactionsV3) @@ -305,10 +307,10 @@ func MockWithEverything(t *testing.T, gspec *core.Genesis, key *ecdsa.PrivateKey blockPropagator := func(Ctx context.Context, header *types.Header, body *types.RawBody, td *big.Int) {} if !cfg.DeprecatedTxPool.Disable { - poolCfg := txpool.DefaultConfig + poolCfg := txpoolcfg.DefaultConfig newTxs := make(chan types2.Announcements, 1024) - if t != nil { - t.Cleanup(func() { + if tb != nil { + tb.Cleanup(func() { close(newTxs) }) } @@ -316,7 +318,7 @@ func MockWithEverything(t *testing.T, gspec *core.Genesis, key *ecdsa.PrivateKey shanghaiTime := mock.ChainConfig.ShanghaiTime mock.TxPool, err = txpool.New(newTxs, mock.DB, poolCfg, kvcache.NewDummy(), *chainID, shanghaiTime) if err != nil { - t.Fatal(err) + tb.Fatal(err) } mock.txPoolDB = memdb.NewPoolDB(tmpdir) @@ -338,8 +340,8 @@ func MockWithEverything(t *testing.T, gspec *core.Genesis, key *ecdsa.PrivateKey // Committed genesis will be shared between download and mock sentry _, mock.Genesis, err = core.CommitGenesisBlock(mock.DB, gspec, "") if _, ok := err.(*chain.ConfigCompatError); err != nil && !ok { - if t != nil { - t.Fatal(err) + if tb != nil { + tb.Fatal(err) } else { panic(err) } @@ -385,8 +387,8 @@ func MockWithEverything(t *testing.T, gspec *core.Genesis, key *ecdsa.PrivateKey mock.sentriesClient.IsMock = true if err != nil { - if t != nil { - t.Fatal(err) + if tb != nil { + tb.Fatal(err) } else { panic(err) } @@ -514,18 +516,18 @@ func MockWithEverything(t *testing.T, gspec *core.Genesis, key *ecdsa.PrivateKey } // Mock is convenience function to create a mock with some pre-set values -func Mock(t *testing.T) *MockSentry { +func Mock(tb testing.TB) *MockSentry { funds := big.NewInt(1 * params.Ether) key, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") address := crypto.PubkeyToAddress(key.PublicKey) chainConfig := params.TestChainConfig - gspec := &core.Genesis{ + gspec := &types.Genesis{ Config: chainConfig, - Alloc: core.GenesisAlloc{ + Alloc: types.GenesisAlloc{ address: {Balance: funds}, }, } - return MockWithGenesis(t, gspec, key, false) + return MockWithGenesis(tb, gspec, key, false) } func MockWithTxPool(t *testing.T) *MockSentry { @@ -533,9 +535,9 @@ func MockWithTxPool(t *testing.T) *MockSentry { key, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") address := crypto.PubkeyToAddress(key.PublicKey) chainConfig := params.TestChainConfig - gspec := &core.Genesis{ + gspec := &types.Genesis{ Config: chainConfig, - Alloc: core.GenesisAlloc{ + Alloc: types.GenesisAlloc{ address: {Balance: funds}, }, } @@ -549,9 +551,9 @@ func MockWithZeroTTD(t *testing.T, withPosDownloader bool) *MockSentry { address := crypto.PubkeyToAddress(key.PublicKey) chainConfig := params.AllProtocolChanges chainConfig.TerminalTotalDifficulty = libcommon.Big0 - gspec := &core.Genesis{ + gspec := &types.Genesis{ Config: chainConfig, - Alloc: core.GenesisAlloc{ + Alloc: types.GenesisAlloc{ address: {Balance: funds}, }, } @@ -565,19 +567,19 @@ func MockWithZeroTTDGnosis(t *testing.T, withPosDownloader bool) *MockSentry { chainConfig := params.TestChainAuraConfig chainConfig.TerminalTotalDifficulty = libcommon.Big0 chainConfig.TerminalTotalDifficultyPassed = true - gspec := &core.Genesis{ + gspec := &types.Genesis{ Config: chainConfig, - Alloc: core.GenesisAlloc{ + Alloc: types.GenesisAlloc{ address: {Balance: funds}, }, } - engine := ethconsensusconfig.CreateConsensusEngine(chainConfig, log.New(), chainConfig.Aura, nil, true, "", "", true, "", nil, false /* readonly */, nil) + engine := ethconsensusconfig.CreateConsensusEngine(chainConfig, chainConfig.Aura, nil, true, "", "", true, "", nil, false /* readonly */, nil) return MockWithGenesisEngine(t, gspec, engine, withPosDownloader) } func (ms *MockSentry) EnableLogs() { log.Root().SetHandler(log.LvlFilterHandler(log.LvlInfo, log.StderrHandler)) - ms.t.Cleanup(func() { + ms.tb.Cleanup(func() { log.Root().SetHandler(log.Root().GetHandler()) }) } @@ -767,6 +769,17 @@ func (ms *MockSentry) NewStateReader(tx kv.Tx) state.StateReader { return state.NewPlainStateReader(tx) } +func (ms *MockSentry) NewStateWriter(tx kv.RwTx, blockNum uint64) state.StateWriter { + return state.NewPlainStateWriter(tx, tx, blockNum) +} + +func (ms *MockSentry) CalcStateRoot(tx kv.Tx) libcommon.Hash { + h, err := trie.CalcRoot("test", tx) + if err != nil { + panic(err) + } + return h +} func (ms *MockSentry) HistoryV3Components() *libstate.AggregatorV3 { return ms.agg } diff --git a/turbo/transactions/call.go b/turbo/transactions/call.go index d1ceaeadcad..f2399e8c5d8 100644 --- a/turbo/transactions/call.go +++ b/turbo/transactions/call.go @@ -3,6 +3,7 @@ package transactions import ( "context" "fmt" + "math/big" "time" "github.com/holiman/uint256" @@ -107,7 +108,15 @@ func DoCall( } func NewEVMBlockContext(engine consensus.EngineReader, header *types.Header, requireCanonical bool, tx kv.Tx, headerReader services.HeaderReader) evmtypes.BlockContext { - return core.NewEVMBlockContext(header, MakeHeaderGetter(requireCanonical, tx, headerReader), engine, nil /* author */) + var excessDataGas *big.Int + parentHeader, err := headerReader.HeaderByHash(context.Background(), tx, header.ParentHash) + if err != nil { + // TODO(eip-4844): Do we need to propagate this error? + log.Error("Can't get parent block's header:", err) + } else if parentHeader != nil { + excessDataGas = parentHeader.ExcessDataGas + } + return core.NewEVMBlockContext(header, MakeHeaderGetter(requireCanonical, tx, headerReader), engine, nil /* author */, excessDataGas) } func MakeHeaderGetter(requireCanonical bool, tx kv.Tx, headerReader services.HeaderReader) func(uint64) libcommon.Hash { diff --git a/turbo/transactions/tracing.go b/turbo/transactions/tracing.go index 9ec1844a18f..a1ac24d56a6 100644 --- a/turbo/transactions/tracing.go +++ b/turbo/transactions/tracing.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "math/big" "time" jsoniter "github.com/json-iterator/go" @@ -25,6 +26,7 @@ import ( "github.com/ledgerwatch/erigon/eth/tracers/logger" "github.com/ledgerwatch/erigon/turbo/rpchelper" "github.com/ledgerwatch/erigon/turbo/services" + "github.com/ledgerwatch/log/v3" ) type BlockGetter interface { @@ -53,7 +55,16 @@ func ComputeTxEnv(ctx context.Context, engine consensus.EngineReader, block *typ return h } header := block.HeaderNoCopy() - BlockContext := core.NewEVMBlockContext(header, core.GetHashFn(header, getHeader), engine, nil) + parentHeader, err := headerReader.HeaderByHash(ctx, dbtx, header.ParentHash) + if err != nil { + // TODO(eip-4844): Do we need to propagate this error? + log.Error("Can't get parent block's header:", err) + } + var excessDataGas *big.Int + if parentHeader != nil { + excessDataGas = parentHeader.ExcessDataGas + } + BlockContext := core.NewEVMBlockContext(header, core.GetHashFn(header, getHeader), engine, nil, excessDataGas) // Recompute transactions up to the target index. signer := types.MakeSigner(cfg, block.NumberU64()) @@ -64,7 +75,7 @@ func ComputeTxEnv(ctx context.Context, engine consensus.EngineReader, block *typ msg, _ := txn.AsMessage(*signer, block.BaseFee(), rules) if msg.FeeCap().IsZero() && engine != nil { syscall := func(contract libcommon.Address, data []byte) ([]byte, error) { - return core.SysCallContract(contract, data, *cfg, statedb, header, engine, true /* constCall */) + return core.SysCallContract(contract, data, *cfg, statedb, header, engine, true /* constCall */, excessDataGas) } msg.SetIsFree(engine.IsServiceTransaction(msg.From(), syscall)) } @@ -77,7 +88,7 @@ func ComputeTxEnv(ctx context.Context, engine consensus.EngineReader, block *typ consensusHeaderReader := stagedsync.NewChainReaderImpl(cfg, dbtx, nil) - core.InitializeBlockExecution(engine.(consensus.Engine), consensusHeaderReader, nil, header, block.Transactions(), block.Uncles(), cfg, statedb) + core.InitializeBlockExecution(engine.(consensus.Engine), consensusHeaderReader, header, block.Transactions(), block.Uncles(), cfg, statedb, excessDataGas) for idx, txn := range block.Transactions() { select { @@ -91,7 +102,7 @@ func ComputeTxEnv(ctx context.Context, engine consensus.EngineReader, block *typ msg, _ := txn.AsMessage(*signer, block.BaseFee(), rules) if msg.FeeCap().IsZero() && engine != nil { syscall := func(contract libcommon.Address, data []byte) ([]byte, error) { - return core.SysCallContract(contract, data, *cfg, statedb, header, engine, true /* constCall */) + return core.SysCallContract(contract, data, *cfg, statedb, header, engine, true /* constCall */, excessDataGas) } msg.SetIsFree(engine.IsServiceTransaction(msg.From(), syscall)) } diff --git a/turbo/trie/gen_struct_step.go b/turbo/trie/gen_struct_step.go index 0ae491b0ca2..856726cdd83 100644 --- a/turbo/trie/gen_struct_step.go +++ b/turbo/trie/gen_struct_step.go @@ -41,6 +41,7 @@ type structInfoReceiver interface { topHash() []byte topHashes(prefix []byte, branches, children uint16) []byte printTopHashes(prefix []byte, branches, children uint16) + setProofElement(pe *proofElement) } // hashCollector gets called whenever there might be a need to create intermediate hash record @@ -99,7 +100,10 @@ func (GenStructStepHashData) GenStructStepData() {} // Whenever a `BRANCH` or `BRANCHHASH` opcode is emitted, the set of digits is taken from the corresponding `groups` item, which is // then removed from the slice. This signifies the usage of the number of the stack items by the `BRANCH` or `BRANCHHASH` opcode. // DESCRIBED: docs/programmers_guide/guide.md#separation-of-keys-and-the-structure -func GenStructStep( + +// GenStructStepEx is extended to support optional generation of an Account Proof during trie_root.go CalcTrieRoot(). +// The wrapper below calls it with nil/false defaults so that other callers do not need to be modified. +func GenStructStepEx( retain func(prefix []byte) bool, curr, succ []byte, e structInfoReceiver, @@ -109,6 +113,8 @@ func GenStructStep( hasTree []uint16, hasHash []uint16, trace bool, + retainProof func(prefix []byte) *proofElement, + cutoff bool, ) ([]uint16, []uint16, []uint16, error) { for precLen, buildExtensions := calcPrecLen(groups), false; precLen >= 0; precLen, buildExtensions = calcPrecLen(groups), true { var precExists = len(groups) > 0 @@ -145,6 +151,20 @@ func GenStructStep( } //fmt.Printf("groups is now %x,%d,%b\n", extraDigit, maxLen, groups) + // retainIfProving will call setProofElement to a new proof element + // it is the caller's responsibility set the proof element to nil after the + // next element invocation. This function returns whether a proof is needed + // for this node. + retainIfProving := func(key []byte) bool { + if retainProof != nil { + if pe := retainProof(key); pe != nil { + e.setProofElement(pe) + return true + } + } + return false + } + if !buildExtensions { switch v := data.(type) { case *GenStructStepHashData: @@ -164,10 +184,14 @@ func GenStructStep( } buildExtensions = true case *GenStructStepAccountData: - if retain(curr[:maxLen]) { + proving := retainIfProving(curr[:len(curr)-1]) + if proving || retain(curr[:maxLen]) { if err := e.accountLeaf(remainderLen, curr, &v.Balance, v.Nonce, v.Incarnation, v.FieldSet, codeSizeUncached); err != nil { return nil, nil, nil, err } + if proving { + e.setProofElement(nil) + } } else { if err := e.accountLeafHash(remainderLen, curr, &v.Balance, v.Nonce, v.Incarnation, v.FieldSet); err != nil { return nil, nil, nil, err @@ -175,10 +199,14 @@ func GenStructStep( } case *GenStructStepLeafData: /* building leafs */ - if retain(curr[:maxLen]) { + proving := retainIfProving(curr[:len(curr)-1]) + if proving || retain(curr[:maxLen]) { if err := e.leaf(remainderLen, curr, v.Value); err != nil { return nil, nil, nil, err } + if proving { + e.setProofElement(nil) + } } else { if err := e.leafHash(remainderLen, curr, v.Value); err != nil { return nil, nil, nil, err @@ -218,10 +246,14 @@ func GenStructStep( fmt.Printf("Extension: %x, %b, %b, %b\n", curr[remainderStart:remainderStart+remainderLen], hasHash, hasTree, groups) } /* building extensions */ - if retain(curr[:maxLen]) { + proving := retainIfProving(curr[:remainderStart]) + if proving || retain(curr[:maxLen]) { if err := e.extension(curr[remainderStart : remainderStart+remainderLen]); err != nil { return nil, nil, nil, err } + if proving { + e.setProofElement(nil) + } } else { if err := e.extensionHash(curr[remainderStart : remainderStart+remainderLen]); err != nil { return nil, nil, nil, err @@ -270,10 +302,14 @@ func GenStructStep( if trace { e.printTopHashes(curr[:maxLen], 0, groups[maxLen]) } - if retain(curr[:maxLen]) { + proving := retainIfProving(curr[:maxLen]) + if proving || retain(curr[:maxLen]) { if err := e.branch(groups[maxLen]); err != nil { return nil, nil, nil, err } + if proving { + e.setProofElement(nil) + } } else { if err := e.branchHash(groups[maxLen]); err != nil { return nil, nil, nil, err @@ -305,6 +341,19 @@ func GenStructStep( } return nil, nil, nil, nil } +func GenStructStep( + retain func(prefix []byte) bool, + curr, succ []byte, + e structInfoReceiver, + h HashCollector2, + data GenStructStepData, + groups []uint16, + hasTree []uint16, + hasHash []uint16, + trace bool, +) ([]uint16, []uint16, []uint16, error) { + return GenStructStepEx(retain, curr, succ, e, h, data, groups, hasTree, hasHash, trace, nil, false) +} func GenStructStepOld( retain func(prefix []byte) bool, diff --git a/turbo/trie/hashbuilder.go b/turbo/trie/hashbuilder.go index 32659a80ee5..5a38ffde99c 100644 --- a/turbo/trie/hashbuilder.go +++ b/turbo/trie/hashbuilder.go @@ -41,6 +41,11 @@ type HashBuilder struct { trace bool // Set to true when HashBuilder is required to print trace information for diagnostics topHashesCopy []byte + + // proofElement is set when the next element computation should have its RLP + // encoding retained. Additionally, the account root storage hash and storage + // values are stored into this field when set and in the relavent codepath. + proofElement *proofElement } // NewHashBuilder creates a new HashBuilder @@ -61,6 +66,13 @@ func (hb *HashBuilder) Reset() { hb.nodeStack = hb.nodeStack[:0] } hb.topHashesCopy = hb.topHashesCopy[:0] + hb.proofElement = nil +} + +// setProofElement sets the proofElement field in which the relevant methods +// will check and additionally write the proof bytes to during trie computation. +func (hb *HashBuilder) setProofElement(pe *proofElement) { + hb.proofElement = pe } func (hb *HashBuilder) leaf(length int, keyHex []byte, val rlphacks.RlpSerializable) error { @@ -72,6 +84,9 @@ func (hb *HashBuilder) leaf(length int, keyHex []byte, val rlphacks.RlpSerializa } key := keyHex[len(keyHex)-length:] s := &shortNode{Key: common.CopyBytes(key), Val: valueNode(common.CopyBytes(val.RawBytes()))} + if hb.proofElement != nil { + hb.proofElement.storageValue = new(uint256.Int).SetBytes(val.RawBytes()) + } hb.nodeStack = append(hb.nodeStack, s) if err := hb.leafHashWithKeyVal(key, val); err != nil { return err @@ -148,6 +163,10 @@ func (hb *HashBuilder) completeLeafHash(kp, kl, compactLen int, key []byte, comp writer = hb.sha reader = hb.sha } + // Collect a copy of the hash input if needed for an eth_getProof + if hb.proofElement != nil { + writer = io.MultiWriter(writer, &hb.proofElement.proof) + } if _, err := writer.Write(hb.lenPrefix[:pt]); err != nil { return err @@ -220,7 +239,7 @@ func (hb *HashBuilder) accountLeaf(length int, keyHex []byte, balance *uint256.I var accountCode codeNode if fieldSet&uint32(8) != 0 { copy(hb.acc.CodeHash[:], hb.hashStack[len(hb.hashStack)-popped*hashStackStride-length2.Hash:len(hb.hashStack)-popped*hashStackStride]) - ok := false + var ok bool if !bytes.Equal(hb.acc.CodeHash[:], EmptyCodeHash[:]) { stackTop := hb.nodeStack[len(hb.nodeStack)-popped-1] if stackTop != nil { // if we don't have any stack top it might be okay because we didn't resolve the code yet (stateful resolver) @@ -233,6 +252,12 @@ func (hb *HashBuilder) accountLeaf(length int, keyHex []byte, balance *uint256.I } popped++ } + + if hb.proofElement != nil { + // The storageRoot is not stored with the account info, therefore + // we capture it with the account proof element + hb.proofElement.storageRoot = hb.acc.Root + } var accCopy accounts.Account accCopy.Copy(&hb.acc) @@ -363,6 +388,11 @@ func (hb *HashBuilder) extension(key []byte) error { } func (hb *HashBuilder) extensionHash(key []byte) error { + writer := io.Writer(hb.sha) + if hb.proofElement != nil { + writer = io.MultiWriter(hb.sha, &hb.proofElement.proof) + } + if hb.trace { fmt.Printf("EXTENSIONHASH %x\n", key) } @@ -399,31 +429,32 @@ func (hb *HashBuilder) extensionHash(key []byte) error { totalLen := kp + kl + 33 pt := rlphacks.GenerateStructLen(hb.lenPrefix[:], totalLen) hb.sha.Reset() - if _, err := hb.sha.Write(hb.lenPrefix[:pt]); err != nil { + if _, err := writer.Write(hb.lenPrefix[:pt]); err != nil { return err } - if _, err := hb.sha.Write(hb.keyPrefix[:kp]); err != nil { + if _, err := writer.Write(hb.keyPrefix[:kp]); err != nil { return err } hb.b[0] = compact0 - if _, err := hb.sha.Write(hb.b[:]); err != nil { + if _, err := writer.Write(hb.b[:]); err != nil { return err } for i := 1; i < compactLen; i++ { hb.b[0] = key[ni]*16 + key[ni+1] - if _, err := hb.sha.Write(hb.b[:]); err != nil { + if _, err := writer.Write(hb.b[:]); err != nil { return err } ni += 2 } //capture := common.CopyBytes(branchHash[:length2.Hash+1]) - if _, err := hb.sha.Write(branchHash[:length2.Hash+1]); err != nil { + if _, err := writer.Write(branchHash[:length2.Hash+1]); err != nil { return err } // Replace previous hash with the new one if _, err := hb.sha.Read(hb.hashStack[len(hb.hashStack)-length2.Hash:]); err != nil { return err } + hb.hashStack[len(hb.hashStack)-hashStackStride] = 0x80 + length2.Hash //fmt.Printf("extensionHash [%x]=>[%x]\nHash [%x]\n", key, capture, hb.hashStack[len(hb.hashStack)-hashStackStride:len(hb.hashStack)]) if _, ok := hb.nodeStack[len(hb.nodeStack)-1].(*fullNode); ok { @@ -472,6 +503,11 @@ func (hb *HashBuilder) branch(set uint16) error { } func (hb *HashBuilder) branchHash(set uint16) error { + writer := io.Writer(hb.sha) + if hb.proofElement != nil { + writer = io.MultiWriter(hb.sha, &hb.proofElement.proof) + } + if hb.trace { fmt.Printf("BRANCHHASH (%b)\n", set) } @@ -496,7 +532,7 @@ func (hb *HashBuilder) branchHash(set uint16) error { } hb.sha.Reset() pt := rlphacks.GenerateStructLen(hb.lenPrefix[:], totalSize) - if _, err := hb.sha.Write(hb.lenPrefix[:pt]); err != nil { + if _, err := writer.Write(hb.lenPrefix[:pt]); err != nil { return err } // Output hasState hashes or embedded RLPs @@ -506,21 +542,21 @@ func (hb *HashBuilder) branchHash(set uint16) error { for digit := uint(0); digit < 17; digit++ { if ((1 << digit) & set) != 0 { if hashes[hashStackStride*i] == byte(0x80+length2.Hash) { - if _, err := hb.sha.Write(hashes[hashStackStride*i : hashStackStride*i+hashStackStride]); err != nil { + if _, err := writer.Write(hashes[hashStackStride*i : hashStackStride*i+hashStackStride]); err != nil { return err } //fmt.Printf("%x: [%x]\n", digit, hashes[hashStackStride*i:hashStackStride*i+hashStackStride]) } else { // Embedded node size := int(hashes[hashStackStride*i]) - rlp.EmptyListCode - if _, err := hb.sha.Write(hashes[hashStackStride*i : hashStackStride*i+size+1]); err != nil { + if _, err := writer.Write(hashes[hashStackStride*i : hashStackStride*i+size+1]); err != nil { return err } //fmt.Printf("%x: embedded [%x]\n", digit, hashes[hashStackStride*i:hashStackStride*i+size+1]) } i++ } else { - if _, err := hb.sha.Write(hb.b[:]); err != nil { + if _, err := writer.Write(hb.b[:]); err != nil { return err } //fmt.Printf("%x: empty\n", digit) @@ -531,6 +567,7 @@ func (hb *HashBuilder) branchHash(set uint16) error { if _, err := hb.sha.Read(hb.hashStack[len(hb.hashStack)-length2.Hash:]); err != nil { return err } + //fmt.Printf("} [%x]\n", hb.hashStack[len(hb.hashStack)-hashStackStride:]) if hashStackStride*len(hb.nodeStack) > len(hb.hashStack) { diff --git a/turbo/trie/retain_list.go b/turbo/trie/retain_list.go index 959fdd52bcb..7f9c7a4c1c9 100644 --- a/turbo/trie/retain_list.go +++ b/turbo/trie/retain_list.go @@ -18,10 +18,15 @@ package trie import ( "bytes" + "encoding/binary" "fmt" "sort" + "github.com/holiman/uint256" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon/common" + "github.com/ledgerwatch/erigon/common/hexutil" + "github.com/ledgerwatch/erigon/core/types/accounts" ) type RetainDecider interface { @@ -31,10 +36,167 @@ type RetainDecider interface { type RetainDeciderWithMarker interface { RetainDecider - AddKeyWithMarker(key []byte, marker bool) + // AddKeyWithMarker adds a key in KEY encoding with marker and returns the + // nibble encoded key. + AddKeyWithMarker(key []byte, marker bool) []byte RetainWithMarker(prefix []byte) (retain bool, nextMarkedKey []byte) } +// ProofRetainer is a wrapper around the RetainList passed to the trie builder. +// It is responsible for aggregating proof values from the trie computation and +// will return a valid accounts.AccProofresult after the trie root hash +// calculation has completed. +type ProofRetainer struct { + rl *RetainList + addr libcommon.Address + acc *accounts.Account + accHexKey []byte + storageKeys []libcommon.Hash + storageHexKeys [][]byte + proofs []*proofElement +} + +// NewProofRetainer creates a new ProofRetainer instance for a given account and +// set of storage keys. The trie keys corresponding to the account key, and its +// storage keys are added to the given RetainList. The ProofRetainer should be +// set onto the FlatDBTrieLoader via SetProofRetainer before performing its Load +// operation in order to appropriately collect the proof elements. +func NewProofRetainer(addr libcommon.Address, a *accounts.Account, storageKeys []libcommon.Hash, rl *RetainList) (*ProofRetainer, error) { + addrHash, err := common.HashData(addr[:]) + if err != nil { + return nil, err + } + accHexKey := rl.AddKey(addrHash[:]) + + storageHexKeys := make([][]byte, len(storageKeys)) + for i, sk := range storageKeys { + storageHash, err := common.HashData(sk[:]) + if err != nil { + return nil, err + } + + var compactEncoded [72]byte + copy(compactEncoded[:32], addrHash[:]) + binary.BigEndian.PutUint64(compactEncoded[32:40], a.Incarnation) + copy(compactEncoded[40:], storageHash[:]) + storageHexKeys[i] = rl.AddKey(compactEncoded[:]) + } + + return &ProofRetainer{ + rl: rl, + addr: addr, + acc: a, + accHexKey: accHexKey, + storageKeys: storageKeys, + storageHexKeys: storageHexKeys, + }, nil +} + +// ProofElement requests a new proof element for a given prefix. This proof +// element is retained by the ProofRetainer, and will be utilized to compute the +// proof after the trie computation has completed. The prefix is the standard +// nibble encoded prefix used in the rest of the trie computations. +func (pr *ProofRetainer) ProofElement(prefix []byte) *proofElement { + if !pr.rl.Retain(prefix) { + return nil + } + + switch { + case bytes.HasPrefix(pr.accHexKey, prefix): + // This prefix is a node between the account and the root + case bytes.HasPrefix(prefix, pr.accHexKey): + // This prefix is the account or one of its storage nodes + default: + // we do not need a proof element for this prefix + return nil + } + + pe := &proofElement{ + hexKey: append([]byte{}, prefix...), + } + // Since we do a depth-first traversal, reverse the proof elements so that + // they are ordered correctly root -> node -> ... -> leaf as dictated by + // EIP-1186 + pr.proofs = append([]*proofElement{pe}, pr.proofs...) + return pe +} + +// ProofResult may be invoked only after the Load function of the +// FlatDBTrieLoader has successfully executed. It will populate the Address, +// Balance, Nonce, and CodeHash from the account data supplied in the +// constructor, the StorageHash, storageKey values, and proof elements are +// supplied by the Load operation of the trie construction. +func (pr *ProofRetainer) ProofResult() (*accounts.AccProofResult, error) { + result := &accounts.AccProofResult{ + Address: pr.addr, + Balance: (*hexutil.Big)(pr.acc.Balance.ToBig()), + Nonce: hexutil.Uint64(pr.acc.Nonce), + CodeHash: pr.acc.CodeHash, + } + + for _, pe := range pr.proofs { + if !bytes.HasPrefix(pr.accHexKey, pe.hexKey) { + continue + } + result.AccountProof = append(result.AccountProof, pe.proof.Bytes()) + if pe.storageRoot != (libcommon.Hash{}) { + result.StorageHash = pe.storageRoot + } + } + + if result.StorageHash == (libcommon.Hash{}) { + return nil, fmt.Errorf("did not find storage root in proof elements") + } + + result.StorageProof = make([]accounts.StorProofResult, len(pr.storageKeys)) + for i, sk := range pr.storageKeys { + result.StorageProof[i].Key = sk + hexKey := pr.storageHexKeys[i] + for _, pe := range pr.proofs { + if len(pe.hexKey) <= 2*32 { + // Ignore the proof elements above the storage tree (64 bytes, as nibble + // encoded) + continue + } + if !bytes.HasPrefix(hexKey, pe.hexKey) { + continue + } + if pe.storageValue != nil { + result.StorageProof[i].Value = (*hexutil.Big)(pe.storageValue.ToBig()) + } + + result.StorageProof[i].Proof = append(result.StorageProof[i].Proof, pe.proof.Bytes()) + } + + if result.StorageProof[i].Value == nil { + return nil, fmt.Errorf("no storage value for storage key 0x%x set", sk) + } + } + + return result, nil +} + +// proofElement represent a node or leaf in the trie and its +// corresponding RLP encoding. We store the elements individually when +// aggregating as multiple keys (in particular storage keys) may need to +// reference the same proof elements in their Merkle proof. +type proofElement struct { + // key is the hex encoded key indicating the path of the + // element in the proof. + hexKey []byte + + // buf is used to store the proof bytes + proof bytes.Buffer + + // storageRoot stores the storage root if this is writing + // an account leaf + storageRoot libcommon.Hash + + // storageValue stores the value of the particular storage + // key if this writer is for a storage key + storageValue *uint256.Int +} + // RetainList encapsulates the list of keys that are required to be fully available, or loaded // (by using `BRANCH` opcode instead of `HASHER`) after processing of the sequence of key-value // pairs @@ -65,11 +227,11 @@ func (rl *RetainList) Swap(i, j int) { } // AddKey adds a new key (in KEY encoding) to the list -func (rl *RetainList) AddKey(key []byte) { - rl.AddKeyWithMarker(key, false) +func (rl *RetainList) AddKey(key []byte) []byte { + return rl.AddKeyWithMarker(key, false) } -func (rl *RetainList) AddKeyWithMarker(key []byte, marker bool) { +func (rl *RetainList) AddKeyWithMarker(key []byte, marker bool) []byte { var nibbles = make([]byte, 2*len(key)) for i, b := range key { nibbles[i*2] = b / 16 @@ -77,6 +239,7 @@ func (rl *RetainList) AddKeyWithMarker(key []byte, marker bool) { } rl.AddHex(nibbles) rl.markers = append(rl.markers, marker) + return nibbles } // AddHex adds a new key (in HEX encoding) to the list diff --git a/turbo/trie/retain_list_test.go b/turbo/trie/retain_list_test.go new file mode 100644 index 00000000000..2bfa948e673 --- /dev/null +++ b/turbo/trie/retain_list_test.go @@ -0,0 +1,106 @@ +package trie + +import ( + "testing" + + "github.com/holiman/uint256" + libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon/core/types/accounts" + "github.com/stretchr/testify/require" +) + +func TestProofRetainerConstruction(t *testing.T) { + rl := NewRetainList(0) + pr, err := NewProofRetainer( + libcommon.Address{0x1}, + &accounts.Account{ + Initialised: true, + Nonce: 2, + Balance: *uint256.NewInt(6e9), + CodeHash: libcommon.Hash{3}, + Incarnation: 3, + }, + []libcommon.Hash{{1}, {2}, {3}}, + rl, + ) + require.NoError(t, err) + require.Len(t, rl.hexes, 4) + + validKeys := [][]byte{ + pr.storageHexKeys[2][:], + pr.storageHexKeys[2][:98], + pr.storageHexKeys[2][:95], + pr.storageHexKeys[1][:], + pr.storageHexKeys[1][:90], + pr.storageHexKeys[0][:], + pr.storageHexKeys[0][:85], + pr.accHexKey[:], + pr.accHexKey[:15], + {}, + } + + invalidKeys := [][]byte{ + pr.accHexKey[1:16], + pr.storageHexKeys[0][12:80], + pr.storageHexKeys[2][19:90], + } + + for _, key := range validKeys { + pe := pr.ProofElement(key) + require.NotNil(t, pe) + require.Equal(t, pe.hexKey, key) + switch len(key) { + case 64: // Account leaf key + pe.storageRoot = libcommon.Hash{3} + case 144: // Storage leaf key + pe.storageValue = uint256.NewInt(5) + } + pe.proof.Write(key) + } + for _, key := range invalidKeys { + pe := pr.ProofElement(key) + require.Nil(t, pe) + } + require.Equal(t, len(validKeys), len(pr.proofs)) + + accProof, err := pr.ProofResult() + require.NoError(t, err) + + require.Len(t, accProof.AccountProof, 3) + require.Equal(t, []byte(nil), []byte(accProof.AccountProof[0])) + require.Equal(t, validKeys[8], []byte(accProof.AccountProof[1])) + require.Equal(t, validKeys[7], []byte(accProof.AccountProof[2])) + + require.Len(t, accProof.StorageProof, 3) + require.Equal(t, accProof.StorageProof[0].Key, libcommon.Hash{1}) + require.Len(t, accProof.StorageProof[0].Proof, 2) + require.Equal(t, validKeys[6], []byte(accProof.StorageProof[0].Proof[0])) + require.Equal(t, validKeys[5], []byte(accProof.StorageProof[0].Proof[1])) + + require.Equal(t, accProof.StorageProof[1].Key, libcommon.Hash{2}) + require.Len(t, accProof.StorageProof[1].Proof, 2) + require.Equal(t, validKeys[4], []byte(accProof.StorageProof[1].Proof[0])) + require.Equal(t, validKeys[3], []byte(accProof.StorageProof[1].Proof[1])) + + require.Equal(t, accProof.StorageProof[2].Key, libcommon.Hash{3}) + require.Len(t, accProof.StorageProof[2].Proof, 3) + require.Equal(t, validKeys[2], []byte(accProof.StorageProof[2].Proof[0])) + require.Equal(t, validKeys[1], []byte(accProof.StorageProof[2].Proof[1])) + require.Equal(t, validKeys[0], []byte(accProof.StorageProof[2].Proof[2])) + + t.Run("missingStorageRoot", func(t *testing.T) { + oldStorageHash := pr.proofs[2].storageRoot + pr.proofs[2].storageRoot = libcommon.Hash{} + defer func() { pr.proofs[2].storageRoot = oldStorageHash }() + _, err := pr.ProofResult() + require.Error(t, err, "did not find storage root in proof elements") + }) + + t.Run("missingStorageValue", func(t *testing.T) { + oldKey := pr.proofs[4].storageValue + pr.proofs[4].storageValue = nil + defer func() { pr.proofs[4].storageValue = oldKey }() + _, err := pr.ProofResult() + require.Error(t, err, "no storage value for storage key 0x%x", validKeys[4]) + }) +} diff --git a/turbo/trie/trie_root.go b/turbo/trie/trie_root.go index a155031ffdd..8f513e154d4 100644 --- a/turbo/trie/trie_root.go +++ b/turbo/trie/trie_root.go @@ -9,6 +9,7 @@ import ( "time" libcommon "github.com/ledgerwatch/erigon-lib/common" + "github.com/ledgerwatch/erigon-lib/common/length" length2 "github.com/ledgerwatch/erigon-lib/common/length" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/log/v3" @@ -73,7 +74,7 @@ Then delete this account (SELFDESTRUCT). // FlatDBTrieLoader reads state and intermediate trie hashes in order equal to "Preorder trie traversal" // (Preorder - visit Root, visit Left, visit Right) // -// It produces stream of values and send this stream to `defaultReceiver` +// It produces stream of values and send this stream to `receiver` // It skips storage with incorrect incarnations // // Each intermediate hash key firstly pass to RetainDecider, only if it returns "false" - such AccTrie can be used. @@ -89,10 +90,9 @@ type FlatDBTrieLoader struct { // Account item buffer accountValue accounts.Account - receiver StreamReceiver - defaultReceiver *RootHashAggregator - hc HashCollector2 - shc StorageHashCollector2 + receiver *RootHashAggregator + hc HashCollector2 + shc StorageHashCollector2 } // RootHashAggregator - calculates Merkle trie root hash from incoming data stream @@ -125,22 +125,10 @@ type RootHashAggregator struct { a accounts.Account leafData GenStructStepLeafData accData GenStructStepAccountData -} -type StreamReceiver interface { - Receive( - itemType StreamItem, - accountKey []byte, - storageKey []byte, - accountValue *accounts.Account, - storageValue []byte, - hash []byte, - hasTree bool, - cutoff int, - ) error - - Result() SubTries - Root() libcommon.Hash + // Used to construct an Account proof while calculating the tree root. + proofRetainer *ProofRetainer + cutoff bool } func NewRootHashAggregator() *RootHashAggregator { @@ -149,31 +137,32 @@ func NewRootHashAggregator() *RootHashAggregator { } } -func NewFlatDBTrieLoader(logPrefix string) *FlatDBTrieLoader { - return &FlatDBTrieLoader{ - logPrefix: logPrefix, - defaultReceiver: NewRootHashAggregator(), - } -} - -// Reset prepares the loader for reuse -func (l *FlatDBTrieLoader) Reset(rd RetainDeciderWithMarker, hc HashCollector2, shc StorageHashCollector2, trace bool) error { - l.defaultReceiver.Reset(hc, shc, trace) - l.hc = hc - l.shc = shc - l.receiver = l.defaultReceiver - l.trace = trace - l.ihSeek, l.accSeek, l.storageSeek, l.kHex, l.kHexS = make([]byte, 0, 128), make([]byte, 0, 128), make([]byte, 0, 128), make([]byte, 0, 128), make([]byte, 0, 128) - l.rd = rd - if l.trace { +func NewFlatDBTrieLoader(logPrefix string, rd RetainDeciderWithMarker, hc HashCollector2, shc StorageHashCollector2, trace bool) *FlatDBTrieLoader { + if trace { fmt.Printf("----------\n") fmt.Printf("CalcTrieRoot\n") } - return nil + return &FlatDBTrieLoader{ + logPrefix: logPrefix, + receiver: &RootHashAggregator{ + hb: NewHashBuilder(false), + hc: hc, + shc: shc, + trace: trace, + }, + ihSeek: make([]byte, 0, 128), + accSeek: make([]byte, 0, 128), + storageSeek: make([]byte, 0, 128), + kHex: make([]byte, 0, 128), + kHexS: make([]byte, 0, 128), + rd: rd, + hc: hc, + shc: shc, + } } -func (l *FlatDBTrieLoader) SetStreamReceiver(receiver StreamReceiver) { - l.receiver = receiver +func (l *FlatDBTrieLoader) SetProofRetainer(pr *ProofRetainer) { + l.receiver.proofRetainer = pr } // CalcTrieRoot algo: @@ -198,7 +187,7 @@ func (l *FlatDBTrieLoader) SetStreamReceiver(receiver StreamReceiver) { // SkipAccounts: // use(AccTrie) // } -func (l *FlatDBTrieLoader) CalcTrieRoot(tx kv.Tx, prefix []byte, quit <-chan struct{}) (libcommon.Hash, error) { +func (l *FlatDBTrieLoader) CalcTrieRoot(tx kv.Tx, quit <-chan struct{}) (libcommon.Hash, error) { accC, err := tx.Cursor(kv.HashedAccounts) if err != nil { @@ -231,7 +220,7 @@ func (l *FlatDBTrieLoader) CalcTrieRoot(tx kv.Tx, prefix []byte, quit <-chan str defer ss.Close() logEvery := time.NewTicker(30 * time.Second) defer logEvery.Stop() - for ihK, ihV, hasTree, err := accTrie.AtPrefix(prefix); ; ihK, ihV, hasTree, err = accTrie.Next() { // no loop termination is at he end of loop + for ihK, ihV, hasTree, err := accTrie.AtPrefix(nil); ; ihK, ihV, hasTree, err = accTrie.Next() { // no loop termination is at he end of loop if err != nil { return EmptyRoot, err } @@ -243,7 +232,7 @@ func (l *FlatDBTrieLoader) CalcTrieRoot(tx kv.Tx, prefix []byte, quit <-chan str if err1 != nil { return EmptyRoot, err1 } - if keyIsBefore(ihK, kHex) || !bytes.HasPrefix(kHex, prefix) { // read all accounts until next AccTrie + if keyIsBefore(ihK, kHex) || !bytes.HasPrefix(kHex, nil) { // read all accounts until next AccTrie break } if err = l.accountValue.DecodeForStorage(v); err != nil { @@ -310,7 +299,7 @@ func (l *FlatDBTrieLoader) CalcTrieRoot(tx kv.Tx, prefix []byte, quit <-chan str } } - if err := l.receiver.Receive(CutoffStreamItem, nil, nil, nil, nil, nil, false, len(prefix)); err != nil { + if err := l.receiver.Receive(CutoffStreamItem, nil, nil, nil, nil, nil, false, 0); err != nil { return EmptyRoot, err } return l.receiver.Root(), nil @@ -330,27 +319,6 @@ func (r *RootHashAggregator) RetainNothing(_ []byte) bool { return false } -func (r *RootHashAggregator) Reset(hc HashCollector2, shc StorageHashCollector2, trace bool) { - r.hc = hc - r.shc = shc - r.curr.Reset() - r.succ.Reset() - r.value = nil - r.groups = r.groups[:0] - r.hasTree = r.hasTree[:0] - r.hasHash = r.hasHash[:0] - r.a.Reset() - r.hb.Reset() - r.wasIH = false - r.currStorage.Reset() - r.succStorage.Reset() - r.valueStorage = nil - r.wasIHStorage = false - r.root = libcommon.Hash{} - r.trace = trace - r.hb.trace = trace -} - func (r *RootHashAggregator) Receive(itemType StreamItem, accountKey []byte, storageKey []byte, @@ -371,6 +339,7 @@ func (r *RootHashAggregator) Receive(itemType StreamItem, // fmt.Printf("1: %d, %x, %x, %x\n", itemType, accountKey, storageKey, hash) // //} //} + // switch itemType { case StorageStreamItem: @@ -482,6 +451,10 @@ func (r *RootHashAggregator) Receive(itemType StreamItem, r.accData.FieldSet |= AccountFieldStorageOnly } } + + // Used for optional GetProof calculation to trigger inclusion of the top-level node + r.cutoff = true + if r.curr.Len() > 0 { if err := r.genStructAccount(); err != nil { return err @@ -525,10 +498,6 @@ func (r *RootHashAggregator) Receive(itemType StreamItem, // } // } -func (r *RootHashAggregator) Result() SubTries { - panic("don't call me") -} - func (r *RootHashAggregator) Root() libcommon.Hash { return r.root } @@ -566,13 +535,32 @@ func (r *RootHashAggregator) genStructStorage() error { r.leafData.Value = rlphacks.RlpSerializableBytes(r.valueStorage) data = &r.leafData } - r.groupsStorage, r.hasTreeStorage, r.hasHashStorage, err = GenStructStep(r.RetainNothing, r.currStorage.Bytes(), r.succStorage.Bytes(), r.hb, func(keyHex []byte, hasState, hasTree, hasHash uint16, hashes, rootHash []byte) error { + var wantProof func(_ []byte) *proofElement + if r.proofRetainer != nil { + var fullKey [2 * (length.Hash + length.Incarnation + length.Hash)]byte + for i, b := range r.currAccK { + fullKey[i*2] = b / 16 + fullKey[i*2+1] = b % 16 + } + for i, b := range binary.BigEndian.AppendUint64(nil, r.a.Incarnation) { + fullKey[2*length.Hash+i*2] = b / 16 + fullKey[2*length.Hash+i*2+1] = b % 16 + } + baseKeyLen := 2 * (length.Hash + length.Incarnation) + wantProof = func(prefix []byte) *proofElement { + copy(fullKey[baseKeyLen:], prefix) + return r.proofRetainer.ProofElement(fullKey[:baseKeyLen+len(prefix)]) + } + } + r.groupsStorage, r.hasTreeStorage, r.hasHashStorage, err = GenStructStepEx(r.RetainNothing, r.currStorage.Bytes(), r.succStorage.Bytes(), r.hb, func(keyHex []byte, hasState, hasTree, hasHash uint16, hashes, rootHash []byte) error { if r.shc == nil { return nil } return r.shc(r.currAccK, keyHex, hasState, hasTree, hasHash, hashes, rootHash) }, data, r.groupsStorage, r.hasTreeStorage, r.hasHashStorage, r.trace, + wantProof, + r.cutoff, ) if err != nil { return err @@ -634,14 +622,21 @@ func (r *RootHashAggregator) genStructAccount() error { r.currStorage.Reset() r.succStorage.Reset() var err error - if r.groups, r.hasTree, r.hasHash, err = GenStructStep(r.RetainNothing, r.curr.Bytes(), r.succ.Bytes(), r.hb, func(keyHex []byte, hasState, hasTree, hasHash uint16, hashes, rootHash []byte) error { + + var wantProof func(_ []byte) *proofElement + if r.proofRetainer != nil { + wantProof = r.proofRetainer.ProofElement + } + if r.groups, r.hasTree, r.hasHash, err = GenStructStepEx(r.RetainNothing, r.curr.Bytes(), r.succ.Bytes(), r.hb, func(keyHex []byte, hasState, hasTree, hasHash uint16, hashes, rootHash []byte) error { if r.hc == nil { return nil } return r.hc(keyHex, hasState, hasTree, hasHash, hashes, rootHash) }, data, r.groups, r.hasTree, r.hasHash, - false, - //r.trace, + //false, + r.trace, + wantProof, + r.cutoff, ); err != nil { return err } @@ -1488,12 +1483,9 @@ func CastTrieNodeValue(hashes, rootHash []byte) []libcommon.Hash { // CalcRoot is a combination of `ResolveStateTrie` and `UpdateStateTrie` // DESCRIBED: docs/programmers_guide/guide.md#organising-ethereum-state-into-a-merkle-tree func CalcRoot(logPrefix string, tx kv.Tx) (libcommon.Hash, error) { - loader := NewFlatDBTrieLoader(logPrefix) - if err := loader.Reset(NewRetainList(0), nil, nil, false); err != nil { - return EmptyRoot, err - } + loader := NewFlatDBTrieLoader(logPrefix, NewRetainList(0), nil, nil, false) - h, err := loader.CalcTrieRoot(tx, nil, nil) + h, err := loader.CalcTrieRoot(tx, nil) if err != nil { return EmptyRoot, err } From eb45000a2b6e567b4b0b7db5cd976ab939abf1a8 Mon Sep 17 00:00:00 2001 From: Daniil Date: Thu, 27 Apr 2023 22:03:29 +0200 Subject: [PATCH 16/18] starter with errortrack flag --- Makefile | 1 + cmd/starter/README.md | 32 ++++++++ cmd/starter/main.go | 176 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 209 insertions(+) create mode 100644 cmd/starter/README.md create mode 100644 cmd/starter/main.go diff --git a/Makefile b/Makefile index 68e1c7ddcc4..98a212dbfba 100644 --- a/Makefile +++ b/Makefile @@ -105,6 +105,7 @@ geth: erigon erigon: go-version erigon.cmd @rm -f $(GOBIN)/tg # Remove old binary to prevent confusion where users still use it because of the scripts +COMMANDS += starter COMMANDS += devnet COMMANDS += erigon-el-mock COMMANDS += downloader diff --git a/cmd/starter/README.md b/cmd/starter/README.md new file mode 100644 index 00000000000..11c25d09141 --- /dev/null +++ b/cmd/starter/README.md @@ -0,0 +1,32 @@ +# Starter + +Starter is an additional utility for tracking errors in the logs of the main process. If the given substring is found in the logs more than N times in the given period of time, then the starter will restart the process. + +If starter receives a signal to stop, it will stop the main process and exit. + +## Build + +```go build -o /build/bin/starter cmd/starter/main.go``` + +or + +```make starter``` + +## Usage +Each `--errortrack` flag requires 3 arguments after it, the rest of arguments is a command for child process. + +```starter [--errortrack error_substring error_limit time_window] [args...]``` + +- `error_substring` - substring to search in the logs +- `error_limit` - maximum number of occurrences of the substring in the given period +- `time_window` - time window for error searching (e.g. 60s, 1m, 1h, 1d) +- `command` - command to run +- `[args...]` - arguments for the command +## Example +This command will restart erigon if the substring 'No block bodies' is found in the logs more than 50 times in 5 minutes: + +```starter --errortrack 'No block bodies' 50 5m erigon --datadir /data --private.api.addr``` + +It is possible to track multiple errors by using `--errortrack` flag multiple times. + +```starter --errortrack 'No block bodies' 50 5m --errortrack 'No peers' 10 60s erigon --datadir /data --private.api.addr``` diff --git a/cmd/starter/main.go b/cmd/starter/main.go new file mode 100644 index 00000000000..35bfab4df2d --- /dev/null +++ b/cmd/starter/main.go @@ -0,0 +1,176 @@ +package main + +import ( + "bufio" + "fmt" + "io" + "os" + "os/exec" + "os/signal" + "strconv" + "strings" + "sync" + "syscall" + "time" +) + +type ErrorTracker struct { + Substring string + Limit int + Window time.Duration + Errors []time.Time +} + +func (et *ErrorTracker) AddError(t time.Time) { + et.Errors = append(et.Errors, t) + if len(et.Errors) > et.Limit { + et.Errors = et.Errors[1:] + } +} + +func (et *ErrorTracker) ShouldRestartProcess() bool { + if len(et.Errors) < et.Limit { + return false + } + + firstError := et.Errors[0] + lastError := et.Errors[len(et.Errors)-1] + return lastError.Sub(firstError) <= et.Window +} + +func parseErrorTrackers() ([]ErrorTracker, []string) { + trackers := make([]ErrorTracker, 0) + args := os.Args[1:] + maxArg := -1 + + for i, arg := range args { + if arg == "--errortrack" { + if i+3 >= len(args) { + log("Invalid --errortrack parameters") + os.Exit(1) + } + + substring := args[i+1] + limit, err := strconv.Atoi(args[i+2]) + if err != nil { + log("Error parsing limit: %v", err) + os.Exit(1) + } + + window, err := time.ParseDuration(args[i+3]) + if err != nil { + log("Error parsing time window: %v", err) + os.Exit(1) + } + + trackers = append(trackers, ErrorTracker{Substring: substring, Limit: limit, Window: window}) + if i+3 > maxArg { + maxArg = i + 3 + } + } + } + + if maxArg >= len(args)-1 { + log("No command provided") + os.Exit(1) + } + + cmdArgs := args[maxArg+1:] + return trackers, cmdArgs +} + +func log(format string, a ...interface{}) { + fmt.Printf(fmt.Sprintf("[starter] %s ", time.Now().Format("[01-02|15:04:05.000]"))+format+"\n", a...) +} + +func main() { + trackers, cmdArgs := parseErrorTrackers() + if len(cmdArgs) == 0 { + log("No command provided") + os.Exit(1) + } + + cmdName := cmdArgs[0] + cmdArgs = cmdArgs[1:] + + // Set up signal handling + sigChan := make(chan os.Signal, 1) + signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) + restartChan := make(chan struct{}, 2) + var cmd *exec.Cmd + var stdoutPipe, stderrPipe io.ReadCloser + var wg sync.WaitGroup + + scanAndTrackErrors := func(scanner *bufio.Scanner, trackers []ErrorTracker, lasrwriter io.Writer, restartChan chan struct{}) { + restartInit := false + for scanner.Scan() { + + line := scanner.Text() + + fmt.Fprintln(lasrwriter, line) + + if restartInit { + continue + } + + for i := range trackers { + if strings.Contains(line, trackers[i].Substring) { + trackers[i].AddError(time.Now()) + log("Find error substring %q, %d errors in %s", trackers[i].Substring, len(trackers[i].Errors), trackers[i].Window) + + if trackers[i].ShouldRestartProcess() { + log("Restarting process due to error limit for substring %q", trackers[i].Substring) + restartChan <- struct{}{} + restartInit = true + } + } + } + } + } + + runCmd := func() { + cmd = exec.Command(cmdName, cmdArgs...) + stdoutPipe, _ = cmd.StdoutPipe() + stderrPipe, _ = cmd.StderrPipe() + + wg.Add(2) + go func() { + defer wg.Done() + scanner := bufio.NewScanner(stdoutPipe) + scanAndTrackErrors(scanner, trackers, os.Stdout, restartChan) + }() + + go func() { + defer wg.Done() + scanner := bufio.NewScanner(stderrPipe) + scanAndTrackErrors(scanner, trackers, os.Stderr, restartChan) + }() + cmd.Start() + } + + runCmd() + + for { + select { + case sig := <-sigChan: + switch sig { + case syscall.SIGINT, syscall.SIGTERM: + cmd.Process.Signal(sig) + cmd.Process.Wait() + wg.Wait() + os.Exit(0) + } + case <-restartChan: + if err := cmd.Process.Signal(syscall.SIGINT); err != nil { + log("Error sending signal to process: %v", err) + } + cmd.Process.Wait() + wg.Wait() + log("Restarting process due to error limits") + for i := range trackers { + trackers[i].Errors = []time.Time{} + } + runCmd() + } + } +} From 2132de9af8f739cf0dc9519d710bbe83e03fbef2 Mon Sep 17 00:00:00 2001 From: Avinash Bodapati Date: Mon, 8 May 2023 18:39:25 +0530 Subject: [PATCH 17/18] Fix chapel sync issues --- consensus/parlia/parlia.go | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/consensus/parlia/parlia.go b/consensus/parlia/parlia.go index d936830bf11..7edf7be34d9 100644 --- a/consensus/parlia/parlia.go +++ b/consensus/parlia/parlia.go @@ -256,6 +256,8 @@ type Parlia struct { fakeDiff bool // Skip difficulty verifications heightForks, timeForks []uint64 // Forks extracted from the chainConfig snapshots *snapshotsync.RoSnapshots + newValidators []libcommon.Address + voteAddressMapmap map[libcommon.Address]*types.BLSPublicKey } // New creates a Parlia consensus engine. @@ -876,18 +878,27 @@ func (p *Parlia) Prepare(chain consensus.ChainHeaderReader, header *types.Header } func (p *Parlia) verifyValidators(header, parentHeader *types.Header, state *state.IntraBlockState) error { - if header.Number.Uint64()%p.config.Epoch != 0 { - return nil - } + if (header.Number.Uint64()+1)%p.config.Epoch == 0 { + newValidators, voteAddressMap, err := p.getCurrentValidators(header, state) + if err != nil { + return err + } + p.newValidators = newValidators + p.voteAddressMapmap = voteAddressMap + return nil + } - newValidators, voteAddressMap, err := p.getCurrentValidators(parentHeader, state) - if err != nil { - return err - } + if header.Number.Uint64()%p.config.Epoch != 0 { + return nil + } + + + newValidators, voteAddressMap := p.newValidators, p.voteAddressMapmap // sort validator by address sort.Sort(validatorsAscending(newValidators)) var validatorsBytes []byte validatorsNumber := len(newValidators) + if !p.chainConfig.IsLuban(header.Number.Uint64()) { validatorsBytes = make([]byte, validatorsNumber*validatorBytesLengthBeforeLuban) for i, validator := range newValidators { From f7912be2c723494881cfd15bb58f7941ef670b7e Mon Sep 17 00:00:00 2001 From: sonicWhale Date: Wed, 10 May 2023 22:38:18 +0100 Subject: [PATCH 18/18] Filter method with changed sequence of arguments --- cmd/rpcdaemon/commands/trace_api.go | 4 ++-- cmd/rpcdaemon/commands/trace_filtering.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/rpcdaemon/commands/trace_api.go b/cmd/rpcdaemon/commands/trace_api.go index a75daa6105e..fce0cb9877d 100644 --- a/cmd/rpcdaemon/commands/trace_api.go +++ b/cmd/rpcdaemon/commands/trace_api.go @@ -3,8 +3,8 @@ package commands import ( "context" "encoding/json" - jsoniter "github.com/json-iterator/go" + libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/kv" @@ -26,7 +26,7 @@ type TraceAPI interface { Transaction(ctx context.Context, txHash libcommon.Hash, gasBailOut *bool) (ParityTraces, error) Get(ctx context.Context, txHash libcommon.Hash, txIndicies []hexutil.Uint64, gasBailOut *bool) (*ParityTrace, error) Block(ctx context.Context, blockNr rpc.BlockNumber, gasBailOut *bool) (ParityTraces, error) - Filter(ctx context.Context, req TraceFilterRequest, stream *jsoniter.Stream, gasBailOut *bool) error + Filter(ctx context.Context, req TraceFilterRequest, gasBailOut *bool, stream *jsoniter.Stream) error } // TraceAPIImpl is implementation of the TraceAPI interface based on remote Db access diff --git a/cmd/rpcdaemon/commands/trace_filtering.go b/cmd/rpcdaemon/commands/trace_filtering.go index c96d3c0eeaa..2b362dd242a 100644 --- a/cmd/rpcdaemon/commands/trace_filtering.go +++ b/cmd/rpcdaemon/commands/trace_filtering.go @@ -338,7 +338,7 @@ func traceFilterBitmapsV3(tx kv.TemporalTx, req TraceFilterRequest, from, to uin // Filter implements trace_filter // NOTE: We do not store full traces - we just store index for each address // Pull blocks which have txs with matching address -func (api *TraceAPIImpl) Filter(ctx context.Context, req TraceFilterRequest, stream *jsoniter.Stream, gasBailOut *bool) error { +func (api *TraceAPIImpl) Filter(ctx context.Context, req TraceFilterRequest, gasBailOut *bool, stream *jsoniter.Stream) error { if gasBailOut == nil { gasBailOut = new(bool) // false by default }