From d8c07f302ac44585fd3586231236b405f3cf618e Mon Sep 17 00:00:00 2001 From: Arpit Agarwal <93arpit@gmail.com> Date: Mon, 20 Apr 2020 11:53:05 +0530 Subject: [PATCH 01/46] fix: Check block delay in verifyHeaders / remove empty chainId check (MAT-1080, MAT-1089) (#49) * fix: Check block delay in verifyHeaders * Pull block time check out of if condition * fix: Always check chainId equality in heimdall response --- consensus/bor/bor.go | 25 ++++++++++++++++++------- consensus/bor/bor_test/bor_test.go | 6 +++--- consensus/bor/bor_test/helper.go | 5 +++-- consensus/errors.go | 3 +++ 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index a59fecd2e8..a33681c1d8 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -205,13 +205,13 @@ func CalcDifficulty(snap *Snapshot, signer common.Address, epoch uint64) *big.In return big.NewInt(0).SetUint64(snap.inturn(snap.Number+1, signer, epoch)) } -// CalcProducerDelay is the producer delay algorithm based on block time. -func CalcProducerDelay(snap *Snapshot, signer common.Address, period uint64, epoch uint64, producerDelay uint64) uint64 { - // if block is epoch start block, proposer will be inturn signer - if (snap.Number+1)%epoch == 0 { +// CalcProducerDelay is the block delay algorithm based on block time and period / producerDelay values in genesis +func CalcProducerDelay(number uint64, period uint64, sprint uint64, producerDelay uint64) uint64 { + // When the block is the first block of the sprint, it is expected to be delayed by `producerDelay`. + // That is to allow time for block propagation in the last sprint + if number%sprint == 0 { return producerDelay } - return period } @@ -331,6 +331,17 @@ func (c *Bor) verifyHeader(chain consensus.ChainReader, header *types.Header, pa } number := header.Number.Uint64() + var parent *types.Header + if len(parents) > 0 { // if parents is nil, len(parents) is zero + parent = parents[len(parents)-1] + } else if number > 0 { + parent = chain.GetHeader(header.ParentHash, number-1) + } + + if parent != nil && header.Time < parent.Time+CalcProducerDelay(number, c.config.Period, c.config.Sprint, c.config.ProducerDelay) { + return consensus.ErrBlockTooSoon + } + // Don't waste time checking blocks from the future if header.Time > uint64(time.Now().Unix()) { return consensus.ErrFutureBlock @@ -654,7 +665,7 @@ func (c *Bor) Prepare(chain consensus.ChainReader, header *types.Header) error { return consensus.ErrUnknownAncestor } - header.Time = parent.Time + CalcProducerDelay(snap, c.signer, c.config.Period, c.config.Sprint, c.config.ProducerDelay) + header.Time = parent.Time + CalcProducerDelay(number, c.config.Period, c.config.Sprint, c.config.ProducerDelay) if header.Time < uint64(time.Now().Unix()) { header.Time = uint64(time.Now().Unix()) } @@ -1190,7 +1201,7 @@ func (c *Bor) CommitStates( } // check if chain id matches with event record - if eventRecord.ChainID != "" && eventRecord.ChainID != c.chainConfig.ChainID.String() { + if eventRecord.ChainID != c.chainConfig.ChainID.String() { return fmt.Errorf( "Chain id proposed state in span, %s, and bor chain id, %s, doesn't match", eventRecord.ChainID, diff --git a/consensus/bor/bor_test/bor_test.go b/consensus/bor/bor_test/bor_test.go index ce1585f6f2..13fb4f2e6b 100644 --- a/consensus/bor/bor_test/bor_test.go +++ b/consensus/bor/bor_test/bor_test.go @@ -32,7 +32,7 @@ func TestCommitSpan(t *testing.T) { db := init.ethereum.ChainDb() block := init.genesis.ToBlock(db) // Build 1st block's header - header := buildMinimalNextHeader(t, block, init.genesis.Config.Bor.Period) + header := buildMinimalNextHeader(t, block, init.genesis.Config.Bor) statedb, err := chain.State() if err != nil { @@ -89,7 +89,7 @@ func TestIsValidatorAction(t *testing.T) { db := init.ethereum.ChainDb() block := init.genesis.ToBlock(db) - header := buildMinimalNextHeader(t, block, init.genesis.Config.Bor.Period) + header := buildMinimalNextHeader(t, block, init.genesis.Config.Bor) statedb, err := chain.State() if err != nil { t.Fatalf("%s", err) @@ -101,7 +101,7 @@ func TestIsValidatorAction(t *testing.T) { var headers []*types.Header for i := int64(2); i <= 255; i++ { - header := buildMinimalNextHeader(t, block, init.genesis.Config.Bor.Period) + header := buildMinimalNextHeader(t, block, init.genesis.Config.Bor) headers = append(headers, header) block = types.NewBlockWithHeader(header) } diff --git a/consensus/bor/bor_test/helper.go b/consensus/bor/bor_test/helper.go index 54ab949983..9a5c0facc5 100644 --- a/consensus/bor/bor_test/helper.go +++ b/consensus/bor/bor_test/helper.go @@ -16,6 +16,7 @@ import ( "github.com/maticnetwork/bor/eth" "github.com/maticnetwork/bor/ethdb" "github.com/maticnetwork/bor/node" + "github.com/maticnetwork/bor/params" ) var ( @@ -99,11 +100,11 @@ func insertNewBlock(t *testing.T, _bor *bor.Bor, chain *core.BlockChain, header } } -func buildMinimalNextHeader(t *testing.T, block *types.Block, period uint64) *types.Header { +func buildMinimalNextHeader(t *testing.T, block *types.Block, borConfig *params.BorConfig) *types.Header { header := block.Header() header.Number.Add(header.Number, big.NewInt(1)) header.ParentHash = block.Hash() - header.Time += (period + 1) + header.Time += bor.CalcProducerDelay(header.Number.Uint64(), borConfig.Period, borConfig.Sprint, borConfig.ProducerDelay) header.Extra = make([]byte, 97) // vanity (32) + extraSeal (65) _key, _ := hex.DecodeString(privKey) sig, err := secp256k1.Sign(crypto.Keccak256(bor.BorRLP(header)), _key) diff --git a/consensus/errors.go b/consensus/errors.go index a005c5f63d..04342bea8a 100644 --- a/consensus/errors.go +++ b/consensus/errors.go @@ -31,6 +31,9 @@ var ( // to the current node. ErrFutureBlock = errors.New("block in the future") + // ErrBlockTooSoon is returned when the period / producerDelay values in the genesis were not respected + ErrBlockTooSoon = errors.New("block was produced sooner than expected") + // ErrInvalidNumber is returned if a block's number doesn't equal it's parent's // plus one. ErrInvalidNumber = errors.New("invalid block number") From 122a2304db245df38f9f102f4190f038e67b3412 Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Mon, 20 Apr 2020 20:34:58 +0530 Subject: [PATCH 02/46] minor: Run gofmt -w . --- accounts/scwallet/hub.go | 2 +- accounts/scwallet/securechannel.go | 2 +- accounts/scwallet/wallet.go | 2 +- accounts/usbwallet/hub.go | 2 +- accounts/usbwallet/trezor.go | 2 +- accounts/usbwallet/wallet.go | 2 +- consensus/clique/clique.go | 2 +- consensus/clique/snapshot.go | 2 +- consensus/ethash/ethash.go | 2 +- core/headerchain.go | 2 +- core/rawdb/freezer_table.go | 2 +- core/state/database.go | 2 +- graphql/service.go | 4 ++-- internal/debug/flags.go | 2 +- light/lightchain.go | 2 +- metrics/influxdb/influxdb.go | 2 +- p2p/nat/nat.go | 2 +- p2p/rlpx.go | 2 +- p2p/simulations/http.go | 2 +- 19 files changed, 20 insertions(+), 20 deletions(-) diff --git a/accounts/scwallet/hub.go b/accounts/scwallet/hub.go index dfcc5ac4bf..66005b04e9 100644 --- a/accounts/scwallet/hub.go +++ b/accounts/scwallet/hub.go @@ -41,11 +41,11 @@ import ( "sync" "time" + pcsc "github.com/gballet/go-libpcsclite" "github.com/maticnetwork/bor/accounts" "github.com/maticnetwork/bor/common" "github.com/maticnetwork/bor/event" "github.com/maticnetwork/bor/log" - pcsc "github.com/gballet/go-libpcsclite" ) // Scheme is the URI prefix for smartcard wallets. diff --git a/accounts/scwallet/securechannel.go b/accounts/scwallet/securechannel.go index 3d0be4728e..7f0a8df4ac 100644 --- a/accounts/scwallet/securechannel.go +++ b/accounts/scwallet/securechannel.go @@ -25,8 +25,8 @@ import ( "crypto/sha512" "fmt" - "github.com/maticnetwork/bor/crypto" pcsc "github.com/gballet/go-libpcsclite" + "github.com/maticnetwork/bor/crypto" "github.com/wsddn/go-ecdh" "golang.org/x/crypto/pbkdf2" "golang.org/x/text/unicode/norm" diff --git a/accounts/scwallet/wallet.go b/accounts/scwallet/wallet.go index 540bcc1a60..6b986ff946 100644 --- a/accounts/scwallet/wallet.go +++ b/accounts/scwallet/wallet.go @@ -33,13 +33,13 @@ import ( "sync" "time" + pcsc "github.com/gballet/go-libpcsclite" ethereum "github.com/maticnetwork/bor" "github.com/maticnetwork/bor/accounts" "github.com/maticnetwork/bor/common" "github.com/maticnetwork/bor/core/types" "github.com/maticnetwork/bor/crypto" "github.com/maticnetwork/bor/log" - pcsc "github.com/gballet/go-libpcsclite" "github.com/status-im/keycard-go/derivationpath" ) diff --git a/accounts/usbwallet/hub.go b/accounts/usbwallet/hub.go index a80eff5a93..e742e49fe0 100644 --- a/accounts/usbwallet/hub.go +++ b/accounts/usbwallet/hub.go @@ -23,10 +23,10 @@ import ( "sync/atomic" "time" + "github.com/karalabe/usb" "github.com/maticnetwork/bor/accounts" "github.com/maticnetwork/bor/event" "github.com/maticnetwork/bor/log" - "github.com/karalabe/usb" ) // LedgerScheme is the protocol scheme prefixing account and wallet URLs. diff --git a/accounts/usbwallet/trezor.go b/accounts/usbwallet/trezor.go index f88501e32f..49c71cb028 100644 --- a/accounts/usbwallet/trezor.go +++ b/accounts/usbwallet/trezor.go @@ -27,13 +27,13 @@ import ( "io" "math/big" + "github.com/golang/protobuf/proto" "github.com/maticnetwork/bor/accounts" "github.com/maticnetwork/bor/accounts/usbwallet/trezor" "github.com/maticnetwork/bor/common" "github.com/maticnetwork/bor/common/hexutil" "github.com/maticnetwork/bor/core/types" "github.com/maticnetwork/bor/log" - "github.com/golang/protobuf/proto" ) // ErrTrezorPINNeeded is returned if opening the trezor requires a PIN code. In diff --git a/accounts/usbwallet/wallet.go b/accounts/usbwallet/wallet.go index 09a140a756..29f7cf661e 100644 --- a/accounts/usbwallet/wallet.go +++ b/accounts/usbwallet/wallet.go @@ -25,13 +25,13 @@ import ( "sync" "time" + "github.com/karalabe/usb" ethereum "github.com/maticnetwork/bor" "github.com/maticnetwork/bor/accounts" "github.com/maticnetwork/bor/common" "github.com/maticnetwork/bor/core/types" "github.com/maticnetwork/bor/crypto" "github.com/maticnetwork/bor/log" - "github.com/karalabe/usb" ) // Maximum time between wallet health checks to detect USB unplugs. diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index b90f611766..799ee16b2d 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -26,6 +26,7 @@ import ( "sync" "time" + lru "github.com/hashicorp/golang-lru" "github.com/maticnetwork/bor/accounts" "github.com/maticnetwork/bor/common" "github.com/maticnetwork/bor/common/hexutil" @@ -39,7 +40,6 @@ import ( "github.com/maticnetwork/bor/params" "github.com/maticnetwork/bor/rlp" "github.com/maticnetwork/bor/rpc" - lru "github.com/hashicorp/golang-lru" "golang.org/x/crypto/sha3" ) diff --git a/consensus/clique/snapshot.go b/consensus/clique/snapshot.go index 593dfe8b99..a4063e3516 100644 --- a/consensus/clique/snapshot.go +++ b/consensus/clique/snapshot.go @@ -22,12 +22,12 @@ import ( "sort" "time" + lru "github.com/hashicorp/golang-lru" "github.com/maticnetwork/bor/common" "github.com/maticnetwork/bor/core/types" "github.com/maticnetwork/bor/ethdb" "github.com/maticnetwork/bor/log" "github.com/maticnetwork/bor/params" - lru "github.com/hashicorp/golang-lru" ) // Vote represents a single vote that an authorized signer made to modify the diff --git a/consensus/ethash/ethash.go b/consensus/ethash/ethash.go index 999d92012a..08a80ae819 100644 --- a/consensus/ethash/ethash.go +++ b/consensus/ethash/ethash.go @@ -34,13 +34,13 @@ import ( "unsafe" mmap "github.com/edsrzf/mmap-go" + "github.com/hashicorp/golang-lru/simplelru" "github.com/maticnetwork/bor/common" "github.com/maticnetwork/bor/consensus" "github.com/maticnetwork/bor/core/types" "github.com/maticnetwork/bor/log" "github.com/maticnetwork/bor/metrics" "github.com/maticnetwork/bor/rpc" - "github.com/hashicorp/golang-lru/simplelru" ) var ErrInvalidDumpMagic = errors.New("invalid dump magic") diff --git a/core/headerchain.go b/core/headerchain.go index 95634891fe..07775a228a 100644 --- a/core/headerchain.go +++ b/core/headerchain.go @@ -26,6 +26,7 @@ import ( "sync/atomic" "time" + lru "github.com/hashicorp/golang-lru" "github.com/maticnetwork/bor/common" "github.com/maticnetwork/bor/consensus" "github.com/maticnetwork/bor/core/rawdb" @@ -33,7 +34,6 @@ import ( "github.com/maticnetwork/bor/ethdb" "github.com/maticnetwork/bor/log" "github.com/maticnetwork/bor/params" - lru "github.com/hashicorp/golang-lru" ) const ( diff --git a/core/rawdb/freezer_table.go b/core/rawdb/freezer_table.go index 868d81f6a5..33c1ca8b34 100644 --- a/core/rawdb/freezer_table.go +++ b/core/rawdb/freezer_table.go @@ -26,10 +26,10 @@ import ( "sync" "sync/atomic" + "github.com/golang/snappy" "github.com/maticnetwork/bor/common" "github.com/maticnetwork/bor/log" "github.com/maticnetwork/bor/metrics" - "github.com/golang/snappy" ) var ( diff --git a/core/state/database.go b/core/state/database.go index 834e8ad96b..33ab998c61 100644 --- a/core/state/database.go +++ b/core/state/database.go @@ -19,10 +19,10 @@ package state import ( "fmt" + lru "github.com/hashicorp/golang-lru" "github.com/maticnetwork/bor/common" "github.com/maticnetwork/bor/ethdb" "github.com/maticnetwork/bor/trie" - lru "github.com/hashicorp/golang-lru" ) const ( diff --git a/graphql/service.go b/graphql/service.go index 473e01b250..6b2626d927 100644 --- a/graphql/service.go +++ b/graphql/service.go @@ -21,12 +21,12 @@ import ( "net" "net/http" + "github.com/graph-gophers/graphql-go" + "github.com/graph-gophers/graphql-go/relay" "github.com/maticnetwork/bor/internal/ethapi" "github.com/maticnetwork/bor/log" "github.com/maticnetwork/bor/p2p" "github.com/maticnetwork/bor/rpc" - "github.com/graph-gophers/graphql-go" - "github.com/graph-gophers/graphql-go/relay" ) // Service encapsulates a GraphQL service. diff --git a/internal/debug/flags.go b/internal/debug/flags.go index 8bd64b9bb9..469dd8dff2 100644 --- a/internal/debug/flags.go +++ b/internal/debug/flags.go @@ -24,10 +24,10 @@ import ( "os" "runtime" + "github.com/fjl/memsize/memsizeui" "github.com/maticnetwork/bor/log" "github.com/maticnetwork/bor/metrics" "github.com/maticnetwork/bor/metrics/exp" - "github.com/fjl/memsize/memsizeui" colorable "github.com/mattn/go-colorable" "github.com/mattn/go-isatty" "gopkg.in/urfave/cli.v1" diff --git a/light/lightchain.go b/light/lightchain.go index cfa684e846..99f14ee3ca 100644 --- a/light/lightchain.go +++ b/light/lightchain.go @@ -26,6 +26,7 @@ import ( "sync/atomic" "time" + lru "github.com/hashicorp/golang-lru" "github.com/maticnetwork/bor/common" "github.com/maticnetwork/bor/consensus" "github.com/maticnetwork/bor/core" @@ -37,7 +38,6 @@ import ( "github.com/maticnetwork/bor/log" "github.com/maticnetwork/bor/params" "github.com/maticnetwork/bor/rlp" - lru "github.com/hashicorp/golang-lru" ) var ( diff --git a/metrics/influxdb/influxdb.go b/metrics/influxdb/influxdb.go index 5971c50aa3..d4452bc6d3 100644 --- a/metrics/influxdb/influxdb.go +++ b/metrics/influxdb/influxdb.go @@ -5,9 +5,9 @@ import ( uurl "net/url" "time" + "github.com/influxdata/influxdb/client" "github.com/maticnetwork/bor/log" "github.com/maticnetwork/bor/metrics" - "github.com/influxdata/influxdb/client" ) type reporter struct { diff --git a/p2p/nat/nat.go b/p2p/nat/nat.go index 08b7a39dda..0f5cd07c05 100644 --- a/p2p/nat/nat.go +++ b/p2p/nat/nat.go @@ -25,8 +25,8 @@ import ( "sync" "time" - "github.com/maticnetwork/bor/log" "github.com/jackpal/go-nat-pmp" + "github.com/maticnetwork/bor/log" ) // An implementation of nat.Interface can map local ports to ports diff --git a/p2p/rlpx.go b/p2p/rlpx.go index 1513ed9d09..36f845332f 100644 --- a/p2p/rlpx.go +++ b/p2p/rlpx.go @@ -35,11 +35,11 @@ import ( "sync" "time" + "github.com/golang/snappy" "github.com/maticnetwork/bor/common/bitutil" "github.com/maticnetwork/bor/crypto" "github.com/maticnetwork/bor/crypto/ecies" "github.com/maticnetwork/bor/rlp" - "github.com/golang/snappy" "golang.org/x/crypto/sha3" ) diff --git a/p2p/simulations/http.go b/p2p/simulations/http.go index c42f2e8a0c..55119851f2 100644 --- a/p2p/simulations/http.go +++ b/p2p/simulations/http.go @@ -29,12 +29,12 @@ import ( "strings" "sync" + "github.com/julienschmidt/httprouter" "github.com/maticnetwork/bor/event" "github.com/maticnetwork/bor/p2p" "github.com/maticnetwork/bor/p2p/enode" "github.com/maticnetwork/bor/p2p/simulations/adapters" "github.com/maticnetwork/bor/rpc" - "github.com/julienschmidt/httprouter" "golang.org/x/net/websocket" ) From b00299ca13882cc65fe1c36408b5e57a654ac437 Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Tue, 21 Apr 2020 09:50:44 +0530 Subject: [PATCH 03/46] fix: Validator list could be invalid making the node crash (2.13) --- consensus/bor/bor.go | 21 +++++++++++++++------ consensus/bor/snapshot.go | 3 +++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index a33681c1d8..58754c5941 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -346,12 +346,9 @@ func (c *Bor) verifyHeader(chain consensus.ChainReader, header *types.Header, pa if header.Time > uint64(time.Now().Unix()) { return consensus.ErrFutureBlock } - // Check that the extra-data contains both the vanity and signature - if len(header.Extra) < extraVanity { - return errMissingVanity - } - if len(header.Extra) < extraVanity+extraSeal { - return errMissingSignature + + if err := validateHeaderExtraField(header.Extra); err != nil { + return err } // check extr adata @@ -387,6 +384,18 @@ func (c *Bor) verifyHeader(chain consensus.ChainReader, header *types.Header, pa return c.verifyCascadingFields(chain, header, parents) } +// validateHeaderExtraField validates that the extra-data contains both the vanity and signature. +// header.Extra = header.Vanity + header.ProducerBytes (optional) + header.Seal +func validateHeaderExtraField(extraBytes []byte) error { + if len(extraBytes) < extraVanity { + return errMissingVanity + } + if len(extraBytes) < extraVanity+extraSeal { + return errMissingSignature + } + return nil +} + // verifyCascadingFields verifies all the header fields that are not standalone, // rather depend on a batch of previous headers. The caller may optionally pass // in a batch of parents (ascending order) to avoid looking those up from the diff --git a/consensus/bor/snapshot.go b/consensus/bor/snapshot.go index d2f0e82ff4..8f197f335b 100644 --- a/consensus/bor/snapshot.go +++ b/consensus/bor/snapshot.go @@ -185,6 +185,9 @@ func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) { // change validator set and change proposer if number > 0 && (number+1)%s.config.Sprint == 0 { + if err := validateHeaderExtraField(header.Extra); err != nil { + return nil, err + } validatorBytes := header.Extra[extraVanity : len(header.Extra)-extraSeal] // get validators from headers and use that for new validator set From 48d6d76d180011d2f1a06fbb03b2d8aa2a53c0c2 Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Tue, 21 Apr 2020 10:29:59 +0530 Subject: [PATCH 04/46] minor: Remove the redundant validator.Bytes() func, fix comments (2.26) --- consensus/bor/validator.go | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/consensus/bor/validator.go b/consensus/bor/validator.go index 0592ab3b13..1d12666138 100644 --- a/consensus/bor/validator.go +++ b/consensus/bor/validator.go @@ -2,7 +2,7 @@ package bor import ( "bytes" - "encoding/json" + // "encoding/json" "errors" "fmt" "math/big" @@ -13,8 +13,6 @@ import ( ) // Validator represets Volatile state for each Validator -// NOTE: The ProposerPriority is not included in Validator.Hash(); -// make sure to update that method if changes are made here type Validator struct { ID uint64 `json:"ID"` Address common.Address `json:"signer"` @@ -80,18 +78,6 @@ func ValidatorListString(vals []*Validator) string { return strings.Join(chunks, ",") } -// Bytes computes the unique encoding of a validator with a given voting power. -// These are the bytes that gets hashed in consensus. It excludes address -// as its redundant with the pubkey. This also excludes ProposerPriority -// which changes every round. -func (v *Validator) Bytes() []byte { - b, err := json.Marshal(v) - if err != nil { - return b - } - return nil -} - // HeaderBytes return header bytes func (v *Validator) HeaderBytes() []byte { result := make([]byte, 40) From bfab1d932dd7ce2bf596a26b5e1b99a25a24f1ee Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Tue, 21 Apr 2020 11:31:45 +0530 Subject: [PATCH 05/46] dev: rename CompareProposerPriority to Cmp, add nil check (2.27) --- consensus/bor/validator.go | 12 ++++++++---- consensus/bor/validator_set.go | 4 ++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/consensus/bor/validator.go b/consensus/bor/validator.go index 1d12666138..dab50e7b2c 100644 --- a/consensus/bor/validator.go +++ b/consensus/bor/validator.go @@ -29,18 +29,23 @@ func NewValidator(address common.Address, votingPower int64) *Validator { } } -// Creates a new copy of the validator so we can mutate ProposerPriority. +// Copy creates a new copy of the validator so we can mutate ProposerPriority. // Panics if the validator is nil. func (v *Validator) Copy() *Validator { vCopy := *v return &vCopy } -// Returns the one with higher ProposerPriority. -func (v *Validator) CompareProposerPriority(other *Validator) *Validator { +// Cmp returns the one validator with a higher ProposerPriority. +// If ProposerPriority is same, it returns the validator with lexicographically smaller address +func (v *Validator) Cmp(other *Validator) *Validator { + // if both of v and other are nil, nil will be returned and that could possibly lead to nil pointer dereference bubbling up the stack if v == nil { return other } + if other == nil { + return v + } if v.ProposerPriority > other.ProposerPriority { return v } else if v.ProposerPriority < other.ProposerPriority { @@ -53,7 +58,6 @@ func (v *Validator) CompareProposerPriority(other *Validator) *Validator { return other } else { panic("Cannot compare identical validators") - return nil } } } diff --git a/consensus/bor/validator_set.go b/consensus/bor/validator_set.go index 2f22d5b59f..89e0c16b13 100644 --- a/consensus/bor/validator_set.go +++ b/consensus/bor/validator_set.go @@ -182,7 +182,7 @@ func computeMaxMinPriorityDiff(vals *ValidatorSet) int64 { func (vals *ValidatorSet) getValWithMostPriority() *Validator { var res *Validator for _, val := range vals.Validators { - res = res.CompareProposerPriority(val) + res = res.Cmp(val) } return res } @@ -298,7 +298,7 @@ func (vals *ValidatorSet) findProposer() *Validator { var proposer *Validator for _, val := range vals.Validators { if proposer == nil || !bytes.Equal(val.Address.Bytes(), proposer.Address.Bytes()) { - proposer = proposer.CompareProposerPriority(val) + proposer = proposer.Cmp(val) } } return proposer From 18266b0d7a303276f771d40d35ccaf1aab9e44bc Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Wed, 22 Apr 2020 12:42:03 +0530 Subject: [PATCH 06/46] minor: Throw error if proposer/signer are not in the validator set (2.28) --- consensus/bor/errors.go | 27 +++++++++++++++++++++++++++ consensus/bor/snapshot.go | 6 ++++++ 2 files changed, 33 insertions(+) create mode 100644 consensus/bor/errors.go diff --git a/consensus/bor/errors.go b/consensus/bor/errors.go new file mode 100644 index 0000000000..29b879ebe3 --- /dev/null +++ b/consensus/bor/errors.go @@ -0,0 +1,27 @@ +package bor + +import ( + "fmt" + + "github.com/maticnetwork/bor/common" +) + +// Will include any new bor consensus errors here in an attempt to make error messages more descriptive + +// ProposerNotFoundError is returned if the given proposer address is not present in the validator set +type ProposerNotFoundError struct { + Address common.Address +} + +func (e *ProposerNotFoundError) Error() string { + return fmt.Sprintf("Proposer: %s not found", e.Address.Hex()) +} + +// SignerNotFoundError is returned when the signer address is not present in the validator set +type SignerNotFoundError struct { + Address common.Address +} + +func (e *SignerNotFoundError) Error() string { + return fmt.Sprintf("Signer: %s not found", e.Address.Hex()) +} diff --git a/consensus/bor/snapshot.go b/consensus/bor/snapshot.go index 8f197f335b..97ba2fa0a8 100644 --- a/consensus/bor/snapshot.go +++ b/consensus/bor/snapshot.go @@ -164,7 +164,13 @@ func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) { // proposer will be the last signer if block is not epoch block proposer := snap.ValidatorSet.GetProposer().Address proposerIndex, _ := snap.ValidatorSet.GetByAddress(proposer) + if proposerIndex == -1 { + return nil, &ProposerNotFoundError{proposer} + } signerIndex, _ := snap.ValidatorSet.GetByAddress(signer) + if signerIndex == -1 { + return nil, &SignerNotFoundError{signer} + } limit := len(validators)/2 + 1 // temp index From 54609b616839442cdf60b4a0094b2fb99f86c09f Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Wed, 22 Apr 2020 13:48:59 +0530 Subject: [PATCH 07/46] refactor: Bubble up error in updateTotalVotingPower instead of panic (2.29) --- consensus/bor/errors.go | 15 +++++++++++++++ consensus/bor/snapshot.go | 4 +++- consensus/bor/validator_set.go | 20 ++++++++++++-------- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/consensus/bor/errors.go b/consensus/bor/errors.go index 29b879ebe3..a3b0dc656d 100644 --- a/consensus/bor/errors.go +++ b/consensus/bor/errors.go @@ -25,3 +25,18 @@ type SignerNotFoundError struct { func (e *SignerNotFoundError) Error() string { return fmt.Sprintf("Signer: %s not found", e.Address.Hex()) } + +// TotalVotingPowerExceededError is returned when the maximum allowed total voting power is exceeded +type TotalVotingPowerExceededError struct { + Sum int64 + Validators []*Validator +} + +func (e *TotalVotingPowerExceededError) Error() string { + return fmt.Sprintf( + "Total voting power should be guarded to not exceed %v; got: %v; for validator set: %v", + MaxTotalVotingPower, + e.Sum, + e.Validators, + ) +} diff --git a/consensus/bor/snapshot.go b/consensus/bor/snapshot.go index 97ba2fa0a8..7707719462 100644 --- a/consensus/bor/snapshot.go +++ b/consensus/bor/snapshot.go @@ -87,7 +87,9 @@ func loadSnapshot(config *params.BorConfig, sigcache *lru.ARCCache, db ethdb.Dat snap.ethAPI = ethAPI // update total voting power - snap.ValidatorSet.updateTotalVotingPower() + if err := snap.ValidatorSet.updateTotalVotingPower(); err != nil { + return nil, err + } return snap, nil } diff --git a/consensus/bor/validator_set.go b/consensus/bor/validator_set.go index 89e0c16b13..dbe987ce78 100644 --- a/consensus/bor/validator_set.go +++ b/consensus/bor/validator_set.go @@ -11,6 +11,7 @@ import ( "strings" "github.com/maticnetwork/bor/common" + "github.com/maticnetwork/bor/log" ) // MaxTotalVotingPower - the maximum allowed total voting power. @@ -256,28 +257,29 @@ func (vals *ValidatorSet) Size() int { } // Force recalculation of the set's total voting power. -func (vals *ValidatorSet) updateTotalVotingPower() { +func (vals *ValidatorSet) updateTotalVotingPower() error { sum := int64(0) for _, val := range vals.Validators { // mind overflow sum = safeAddClip(sum, val.VotingPower) if sum > MaxTotalVotingPower { - panic(fmt.Sprintf( - "Total voting power should be guarded to not exceed %v; got: %v", - MaxTotalVotingPower, - sum)) + return &TotalVotingPowerExceededError{sum, vals.Validators} } } - vals.totalVotingPower = sum + return nil } // TotalVotingPower returns the sum of the voting powers of all validators. // It recomputes the total voting power if required. func (vals *ValidatorSet) TotalVotingPower() int64 { if vals.totalVotingPower == 0 { - vals.updateTotalVotingPower() + log.Info("invoking updateTotalVotingPower before returning it") + if err := vals.updateTotalVotingPower(); err != nil { + // Can/should we do better? + panic(err) + } } return vals.totalVotingPower } @@ -562,7 +564,9 @@ func (vals *ValidatorSet) updateWithChangeSet(changes []*Validator, allowDeletes vals.applyUpdates(updates) vals.applyRemovals(deletes) - vals.updateTotalVotingPower() + if err := vals.updateTotalVotingPower(); err != nil { + return err + } // Scale and center. vals.RescalePriorities(PriorityWindowSizeFactor * vals.TotalVotingPower()) From 52dbf54808c4e6ec08b46b3049faf4d48077f752 Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Sun, 26 Apr 2020 23:25:50 +0530 Subject: [PATCH 08/46] refactor: Fix minor issues from audit (2.36/37/40/41) --- consensus/bor/bor.go | 83 ++++++--------------------------------- consensus/bor/snapshot.go | 63 ++++++++++++++++------------- 2 files changed, 49 insertions(+), 97 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 58754c5941..a32543f087 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -201,8 +201,8 @@ func encodeSigHeader(w io.Writer, header *types.Header) { // CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty // that a new block should have based on the previous blocks in the chain and the // current signer. -func CalcDifficulty(snap *Snapshot, signer common.Address, epoch uint64) *big.Int { - return big.NewInt(0).SetUint64(snap.inturn(snap.Number+1, signer, epoch)) +func CalcDifficulty(snap *Snapshot, signer common.Address, sprint uint64) *big.Int { + return big.NewInt(0).SetUint64(snap.inturn(snap.Number+1, signer, sprint)) } // CalcProducerDelay is the block delay algorithm based on block time and period / producerDelay values in genesis @@ -439,15 +439,6 @@ func (c *Bor) verifyCascadingFields(chain consensus.ChainReader, header *types.H for i, validator := range currentValidators { copy(validatorsBytes[i*validatorHeaderBytesLength:], validator.HeaderBytes()) } - - extraSuffix := len(header.Extra) - extraSeal - - // fmt.Println("validatorsBytes ==> verify seal ==> ", hex.EncodeToString(validatorsBytes)) - // fmt.Println("header.Extra ==> verify seal ==> ", hex.EncodeToString(header.Extra[extraVanity:extraSuffix])) - - if !bytes.Equal(header.Extra[extraVanity:extraSuffix], validatorsBytes) { - // return errMismatchingSprintValidators - } } // All basic checks passed, verify the seal and return @@ -591,27 +582,9 @@ func (c *Bor) verifySeal(chain consensus.ChainReader, header *types.Header, pare return errUnauthorizedSigner } - // check if signer is correct - validators := snap.ValidatorSet.Validators - // proposer will be the last signer if block is not epoch block proposer := snap.ValidatorSet.GetProposer().Address - if number%c.config.Sprint != 0 { - // proposer = snap.Recents[number-1] - } - proposerIndex, _ := snap.ValidatorSet.GetByAddress(proposer) - signerIndex, _ := snap.ValidatorSet.GetByAddress(signer) - limit := len(validators)/2 + 1 - - // temp index - tempIndex := signerIndex - if proposerIndex != tempIndex && limit > 0 { - if tempIndex < proposerIndex { - tempIndex = tempIndex + len(validators) - } - - if tempIndex-proposerIndex > limit { - return errRecentlySigned - } + if _, err = snap.getSignerSuccessionNumber(signer, proposer); err != nil { + return err } // Ensure that the difficulty corresponds to the turn-ness of the signer @@ -775,31 +748,15 @@ func (c *Bor) Seal(chain consensus.ChainReader, block *types.Block, results chan return errUnauthorizedSigner } - validators := snap.ValidatorSet.Validators - // proposer will be the last signer if block is not epoch block proposer := snap.ValidatorSet.GetProposer().Address - if number%c.config.Sprint != 0 { - // proposer = snap.Recents[number-1] - } - - proposerIndex, _ := snap.ValidatorSet.GetByAddress(proposer) - signerIndex, _ := snap.ValidatorSet.GetByAddress(signer) - limit := len(validators)/2 + 1 - - // temp index - tempIndex := signerIndex - if tempIndex < proposerIndex { - tempIndex = tempIndex + len(validators) - } - - if limit > 0 && tempIndex-proposerIndex > limit { - log.Info("Signed recently, must wait for others") - return nil + successionNumber, err := snap.getSignerSuccessionNumber(signer, proposer) + if err != nil { + return err } // Sweet, the protocol permits us to sign the block, wait for our time delay := time.Unix(int64(header.Time), 0).Sub(time.Now()) // nolint: gosimple - wiggle := time.Duration(2*c.config.Period) * time.Second * time.Duration(tempIndex-proposerIndex) + wiggle := time.Duration(2*c.config.Period) * time.Second * time.Duration(successionNumber) delay += wiggle log.Info("Out-of-turn signing requested", "wiggle", common.PrettyDuration(wiggle)) @@ -863,7 +820,7 @@ func (c *Bor) Close() error { return nil } -// Checks if new span is pending +// Checks if "force" proposeSpan has been set func (c *Bor) isSpanPending(snapshotNumber uint64) (bool, error) { blockNr := rpc.BlockNumber(snapshotNumber) method := "spanProposalPending" @@ -875,14 +832,10 @@ func (c *Bor) isSpanPending(snapshotNumber uint64) (bool, error) { return false, err } - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() // cancel when we are finished consuming integers - - // call msgData := (hexutil.Bytes)(data) toAddress := common.HexToAddress(c.config.ValidatorContract) gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2)) - result, err := c.ethAPI.Call(ctx, ethapi.CallArgs{ + result, err := c.ethAPI.Call(context.Background(), ethapi.CallArgs{ Gas: &gas, To: &toAddress, Data: &msgData, @@ -913,14 +866,10 @@ func (c *Bor) GetCurrentSpan(snapshotNumber uint64) (*Span, error) { return nil, err } - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() // cancel when we are finished consuming integers - - // call msgData := (hexutil.Bytes)(data) toAddress := common.HexToAddress(c.config.ValidatorContract) gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2)) - result, err := c.ethAPI.Call(ctx, ethapi.CallArgs{ + result, err := c.ethAPI.Call(context.Background(), ethapi.CallArgs{ Gas: &gas, To: &toAddress, Data: &msgData, @@ -963,14 +912,11 @@ func (c *Bor) GetCurrentValidators(snapshotNumber uint64, blockNumber uint64) ([ return nil, err } - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() // cancel when we are finished consuming integers - // call msgData := (hexutil.Bytes)(data) toAddress := common.HexToAddress(c.config.ValidatorContract) gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2)) - result, err := c.ethAPI.Call(ctx, ethapi.CallArgs{ + result, err := c.ethAPI.Call(context.Background(), ethapi.CallArgs{ Gas: &gas, To: &toAddress, Data: &msgData, @@ -1153,13 +1099,10 @@ func (c *Bor) GetPendingStateProposals(snapshotNumber uint64) ([]*big.Int, error return nil, err } - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() // cancel when we are finished consuming integers - msgData := (hexutil.Bytes)(data) toAddress := common.HexToAddress(c.config.StateReceiverContract) gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2)) - result, err := c.ethAPI.Call(ctx, ethapi.CallArgs{ + result, err := c.ethAPI.Call(context.Background(), ethapi.CallArgs{ Gas: &gas, To: &toAddress, Data: &msgData, diff --git a/consensus/bor/snapshot.go b/consensus/bor/snapshot.go index 7707719462..f0bd723ef5 100644 --- a/consensus/bor/snapshot.go +++ b/consensus/bor/snapshot.go @@ -158,34 +158,9 @@ func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) { return nil, errUnauthorizedSigner } - // - // Check validator - // - - validators := snap.ValidatorSet.Validators - // proposer will be the last signer if block is not epoch block proposer := snap.ValidatorSet.GetProposer().Address - proposerIndex, _ := snap.ValidatorSet.GetByAddress(proposer) - if proposerIndex == -1 { - return nil, &ProposerNotFoundError{proposer} - } - signerIndex, _ := snap.ValidatorSet.GetByAddress(signer) - if signerIndex == -1 { - return nil, &SignerNotFoundError{signer} - } - limit := len(validators)/2 + 1 - - // temp index - tempIndex := signerIndex - if proposerIndex != tempIndex && limit > 0 { - if tempIndex < proposerIndex { - tempIndex = tempIndex + len(validators) - } - - if tempIndex-proposerIndex > limit { - log.Info("Invalid signer: error while applying headers", "proposerIndex", validators[proposerIndex].Address.Hex(), "signerIndex", validators[signerIndex].Address.Hex()) - return nil, errRecentlySigned - } + if _, err = snap.getSignerSuccessionNumber(signer, proposer); err != nil { + return nil, err } // add recents @@ -211,6 +186,40 @@ func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) { return snap, nil } +// getSignerSuccessionNumber returns the relative position of signer in terms of the in-turn proposer +func (s *Snapshot) getSignerSuccessionNumber(signer common.Address, proposer common.Address) (int, error) { + validators := s.ValidatorSet.Validators + // bor.verifySeal and bor.Seal has the following commented out. + // TODO DISCUSS WITH JD if this is required + // If it is, we will also need to send in header.Number as parameter + // if number%c.config.Sprint != 0 { + // proposer = snap.Recents[number-1] + // } + + proposerIndex, _ := s.ValidatorSet.GetByAddress(proposer) + if proposerIndex == -1 { + return -1, &ProposerNotFoundError{proposer} + } + signerIndex, _ := s.ValidatorSet.GetByAddress(signer) + if signerIndex == -1 { + return -1, &SignerNotFoundError{signer} + } + limit := len(validators)/2 + 1 + + tempIndex := signerIndex + if proposerIndex != tempIndex && limit > 0 { + if tempIndex < proposerIndex { + tempIndex = tempIndex + len(validators) + } + + if tempIndex-proposerIndex > limit { + log.Info("errRecentlySigned", "proposerIndex", validators[proposerIndex].Address.Hex(), "signerIndex", validators[signerIndex].Address.Hex()) + return -1, errRecentlySigned + } + } + return tempIndex - proposerIndex, nil +} + // signers retrieves the list of authorized signers in ascending order. func (s *Snapshot) signers() []common.Address { sigs := make([]common.Address, 0, len(s.ValidatorSet.Validators)) From 7e4e2b722c8dcc62942b71bdba11a2684d9a2ad5 Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Tue, 28 Apr 2020 11:01:37 +0530 Subject: [PATCH 09/46] test: Add tests for GetSignerSuccessionNumber --- consensus/bor/bor.go | 8 +- consensus/bor/bor_test/snapshot_test.go | 125 ++++++++++++++++++++++++ consensus/bor/snapshot.go | 15 +-- 3 files changed, 132 insertions(+), 16 deletions(-) create mode 100644 consensus/bor/bor_test/snapshot_test.go diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index a32543f087..994465155e 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -582,8 +582,7 @@ func (c *Bor) verifySeal(chain consensus.ChainReader, header *types.Header, pare return errUnauthorizedSigner } - proposer := snap.ValidatorSet.GetProposer().Address - if _, err = snap.getSignerSuccessionNumber(signer, proposer); err != nil { + if _, err = snap.GetSignerSuccessionNumber(signer); err != nil { return err } @@ -748,8 +747,7 @@ func (c *Bor) Seal(chain consensus.ChainReader, block *types.Block, results chan return errUnauthorizedSigner } - proposer := snap.ValidatorSet.GetProposer().Address - successionNumber, err := snap.getSignerSuccessionNumber(signer, proposer) + successionNumber, err := snap.GetSignerSuccessionNumber(signer) if err != nil { return err } @@ -760,7 +758,7 @@ func (c *Bor) Seal(chain consensus.ChainReader, block *types.Block, results chan delay += wiggle log.Info("Out-of-turn signing requested", "wiggle", common.PrettyDuration(wiggle)) - log.Info("Sealing block with", "number", number, "delay", delay, "headerDifficulty", header.Difficulty, "signer", signer.Hex(), "proposer", proposer.Hex()) + log.Info("Sealing block with", "number", number, "delay", delay, "headerDifficulty", header.Difficulty, "signer", signer.Hex(), "proposer", snap.ValidatorSet.GetProposer().Address.Hex()) // Sign all the things! sighash, err := signFn(accounts.Account{Address: signer}, accounts.MimetypeBor, BorRLP(header)) diff --git a/consensus/bor/bor_test/snapshot_test.go b/consensus/bor/bor_test/snapshot_test.go new file mode 100644 index 0000000000..264c632952 --- /dev/null +++ b/consensus/bor/bor_test/snapshot_test.go @@ -0,0 +1,125 @@ +package bortest + +import ( + "math/rand" + "sort" + "testing" + "time" + + "github.com/stretchr/testify/assert" + + "github.com/maticnetwork/bor/common" + "github.com/maticnetwork/bor/consensus/bor" +) + +const ( + numVals = 100 +) + +func TestGetSignerSuccessionNumber_ProposerIsSigner(t *testing.T) { + validators := buildRandomValidatorSet(numVals) + validatorSet := bor.NewValidatorSet(validators) + snap := bor.Snapshot{ + ValidatorSet: validatorSet, + } + + // proposer is signer + signer := validatorSet.Proposer.Address + successionNumber, err := snap.GetSignerSuccessionNumber(signer) + if err != nil { + t.Fatalf("%s", err) + } + assert.Equal(t, 0, successionNumber) +} + +func TestGetSignerSuccessionNumber_SignerIndexIsLarger(t *testing.T) { + validators := buildRandomValidatorSet(numVals) + + // sort validators by address, which is what bor.NewValidatorSet also does + sort.Sort(bor.ValidatorsByAddress(validators)) + proposerIndex := 32 + signerIndex := 56 + // give highest ProposerPriority to a particular val, so that they become the proposer + validators[proposerIndex].VotingPower = 200 + snap := bor.Snapshot{ + ValidatorSet: bor.NewValidatorSet(validators), + } + + // choose a signer at an index greater than proposer index + signer := snap.ValidatorSet.Validators[signerIndex].Address + successionNumber, err := snap.GetSignerSuccessionNumber(signer) + if err != nil { + t.Fatalf("%s", err) + } + assert.Equal(t, signerIndex-proposerIndex, successionNumber) +} + +func TestGetSignerSuccessionNumber_SignerIndexIsSmaller(t *testing.T) { + validators := buildRandomValidatorSet(numVals) + proposerIndex := 98 + signerIndex := 11 + // give highest ProposerPriority to a particular val, so that they become the proposer + validators[proposerIndex].VotingPower = 200 + snap := bor.Snapshot{ + ValidatorSet: bor.NewValidatorSet(validators), + } + + // choose a signer at an index greater than proposer index + signer := snap.ValidatorSet.Validators[signerIndex].Address + successionNumber, err := snap.GetSignerSuccessionNumber(signer) + if err != nil { + t.Fatalf("%s", err) + } + assert.Equal(t, signerIndex+numVals-proposerIndex, successionNumber) +} + +func TestGetSignerSuccessionNumber_ProposerNotFound(t *testing.T) { + validators := buildRandomValidatorSet(numVals) + snap := bor.Snapshot{ + ValidatorSet: bor.NewValidatorSet(validators), + } + dummyProposerAddress := randomAddress() + snap.ValidatorSet.Proposer = &bor.Validator{Address: dummyProposerAddress} + // choose any signer + signer := snap.ValidatorSet.Validators[3].Address + _, err := snap.GetSignerSuccessionNumber(signer) + assert.NotNil(t, err) + e, ok := err.(*bor.ProposerNotFoundError) + assert.True(t, ok) + assert.Equal(t, dummyProposerAddress, e.Address) +} + +func TestGetSignerSuccessionNumber_SignerNotFound(t *testing.T) { + validators := buildRandomValidatorSet(numVals) + snap := bor.Snapshot{ + ValidatorSet: bor.NewValidatorSet(validators), + } + dummySignerAddress := randomAddress() + _, err := snap.GetSignerSuccessionNumber(dummySignerAddress) + assert.NotNil(t, err) + e, ok := err.(*bor.SignerNotFoundError) + assert.True(t, ok) + assert.Equal(t, dummySignerAddress, e.Address) +} + +func buildRandomValidatorSet(numVals int) []*bor.Validator { + rand.Seed(time.Now().Unix()) + validators := make([]*bor.Validator, numVals) + for i := 0; i < numVals; i++ { + validators[i] = &bor.Validator{ + Address: randomAddress(), + // cannot process validators with voting power 0, hence +1 + VotingPower: int64(rand.Intn(99) + 1), + } + } + + // sort validators by address, which is what bor.NewValidatorSet also does + sort.Sort(bor.ValidatorsByAddress(validators)) + return validators +} + +func randomAddress() common.Address { + bytes := make([]byte, 32) + rand.Read(bytes) + return common.BytesToAddress(bytes) +} diff --git a/consensus/bor/snapshot.go b/consensus/bor/snapshot.go index f0bd723ef5..08088d7911 100644 --- a/consensus/bor/snapshot.go +++ b/consensus/bor/snapshot.go @@ -158,8 +158,7 @@ func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) { return nil, errUnauthorizedSigner } - proposer := snap.ValidatorSet.GetProposer().Address - if _, err = snap.getSignerSuccessionNumber(signer, proposer); err != nil { + if _, err = snap.GetSignerSuccessionNumber(signer); err != nil { return nil, err } @@ -186,16 +185,10 @@ func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) { return snap, nil } -// getSignerSuccessionNumber returns the relative position of signer in terms of the in-turn proposer -func (s *Snapshot) getSignerSuccessionNumber(signer common.Address, proposer common.Address) (int, error) { +// GetSignerSuccessionNumber returns the relative position of signer in terms of the in-turn proposer +func (s *Snapshot) GetSignerSuccessionNumber(signer common.Address) (int, error) { validators := s.ValidatorSet.Validators - // bor.verifySeal and bor.Seal has the following commented out. - // TODO DISCUSS WITH JD if this is required - // If it is, we will also need to send in header.Number as parameter - // if number%c.config.Sprint != 0 { - // proposer = snap.Recents[number-1] - // } - + proposer := s.ValidatorSet.GetProposer().Address proposerIndex, _ := s.ValidatorSet.GetByAddress(proposer) if proposerIndex == -1 { return -1, &ProposerNotFoundError{proposer} From f02da00855b558680c71c7654eb0982b26861f23 Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Wed, 29 Apr 2020 10:55:27 +0530 Subject: [PATCH 10/46] chg: dev: errMismatchingSprintValidators --- consensus/bor/bor.go | 11 ++++++++--- consensus/bor/bor_test/helper.go | 11 ++++++++++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 994465155e..84fabf3336 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -429,8 +429,9 @@ func (c *Bor) verifyCascadingFields(chain consensus.ChainReader, header *types.H return err } - // If the block is a sprint end block, verify the validator list - if number%c.config.Sprint == 0 { + isSprintEnd := (number+1)%c.config.Sprint == 0 + // verify the validator list in the last sprint block + if isSprintEnd { validatorsBytes := make([]byte, len(snap.ValidatorSet.Validators)*validatorHeaderBytesLength) currentValidators := snap.ValidatorSet.Copy().Validators @@ -439,6 +440,10 @@ func (c *Bor) verifyCascadingFields(chain consensus.ChainReader, header *types.H for i, validator := range currentValidators { copy(validatorsBytes[i*validatorHeaderBytesLength:], validator.HeaderBytes()) } + // len(header.Extra) >= extraVanity+extraSeal has already been validated in validateHeaderExtraField, so this won't result in a panic + if !bytes.Equal(header.Extra[extraVanity : len(header.Extra)-extraSeal], validatorsBytes) { + return errMismatchingSprintValidators + } } // All basic checks passed, verify the seal and return @@ -474,7 +479,7 @@ func (c *Bor) snapshot(chain consensus.ChainReader, number uint64, hash common.H // up more headers than allowed to be reorged (chain reinit from a freezer), // consider the checkpoint trusted and snapshot it. // TODO fix this - if number == 0 /* || (number%c.config.Sprint == 0 && (len(headers) > params.ImmutabilityThreshold || chain.GetHeaderByNumber(number-1) == nil)) */ { + if number == 0 { checkpoint := chain.GetHeaderByNumber(number) if checkpoint != nil { // get checkpoint data diff --git a/consensus/bor/bor_test/helper.go b/consensus/bor/bor_test/helper.go index 9a5c0facc5..1ead54ed88 100644 --- a/consensus/bor/bor_test/helper.go +++ b/consensus/bor/bor_test/helper.go @@ -105,7 +105,16 @@ func buildMinimalNextHeader(t *testing.T, block *types.Block, borConfig *params. header.Number.Add(header.Number, big.NewInt(1)) header.ParentHash = block.Hash() header.Time += bor.CalcProducerDelay(header.Number.Uint64(), borConfig.Period, borConfig.Sprint, borConfig.ProducerDelay) - header.Extra = make([]byte, 97) // vanity (32) + extraSeal (65) + isSprintEnd := (header.Number.Uint64()+1)%borConfig.Sprint == 0 + if isSprintEnd { + header.Extra = make([]byte, 32 + 40 + 65) // vanity + validatorBytes + extraSeal + // the genesis file was initialized with a validator 0x71562b71999873db5b286df957af199ec94617f7 with power 10 + // So, if you change ./genesis.json, do change the following as well + validatorBytes, _ := hex.DecodeString("71562b71999873db5b286df957af199ec94617f7000000000000000000000000000000000000000a") + copy(header.Extra[32:72], validatorBytes) + } else { + header.Extra = make([]byte, 32 + 65) // vanity + extraSeal + } _key, _ := hex.DecodeString(privKey) sig, err := secp256k1.Sign(crypto.Keccak256(bor.BorRLP(header)), _key) if err != nil { From 5bd72779d5a5cacbae7af37faf8efb9f312dcf34 Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Tue, 5 May 2020 09:45:57 +0530 Subject: [PATCH 11/46] new: Add GetRootHash bor api method --- consensus/bor/api.go | 44 +++++++++++++++++++++++++++++ consensus/bor/bor.go | 2 +- consensus/bor/bor_test/helper.go | 4 +-- consensus/bor/merkle.go | 48 ++++++++++++++++++++++++++++++++ go.mod | 1 + go.sum | 2 ++ internal/web3ext/web3ext.go | 5 ++++ 7 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 consensus/bor/merkle.go diff --git a/consensus/bor/api.go b/consensus/bor/api.go index 98f7c46b6e..7ef9cdcd47 100644 --- a/consensus/bor/api.go +++ b/consensus/bor/api.go @@ -17,10 +17,16 @@ package bor import ( + "math/big" + "sync" + "github.com/maticnetwork/bor/common" "github.com/maticnetwork/bor/consensus" "github.com/maticnetwork/bor/core/types" + "github.com/maticnetwork/bor/crypto" "github.com/maticnetwork/bor/rpc" + "github.com/xsleonard/go-merkle" + "golang.org/x/crypto/sha3" ) // API is a user facing RPC API to allow controlling the signer and voting @@ -105,3 +111,41 @@ func (api *API) GetCurrentValidators() ([]*Validator, error) { } return snap.ValidatorSet.Validators, nil } + +// GetRootHash gets the current validators +func (api *API) GetRootHash(start uint64, end uint64) ([]byte, error) { + blockHeaders := make([]*types.Header, end-start+1) + wg := new(sync.WaitGroup) + // do we want to limit the # of concurrent go routines? + for i := start; i <= end; i++ { + wg.Add(1) + go func(number uint64) { + blockHeaders[number-start] = api.chain.GetHeaderByNumber(number) + wg.Done() + }(i) + } + wg.Wait() + + expectedLength := nextPowerOfTwo(end - start + 1) + headers := make([][32]byte, expectedLength) + for i := 0; i < len(blockHeaders); i++ { + blockHeader := blockHeaders[i] + header := crypto.Keccak256(appendBytes32( + blockHeader.Number.Bytes(), + new(big.Int).SetUint64(blockHeader.Time).Bytes(), + blockHeader.TxHash.Bytes(), + blockHeader.ReceiptHash.Bytes(), + )) + + var arr [32]byte + copy(arr[:], header) + headers[i] = arr + } + + tree := merkle.NewTreeWithOpts(merkle.TreeOptions{EnableHashSorting: false, DisableHashLeaves: true}) + if err := tree.Generate(convert(headers), sha3.NewLegacyKeccak256()); err != nil { + return nil, err + } + + return tree.Root().Hash, nil +} diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 84fabf3336..945395dd6b 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -441,7 +441,7 @@ func (c *Bor) verifyCascadingFields(chain consensus.ChainReader, header *types.H copy(validatorsBytes[i*validatorHeaderBytesLength:], validator.HeaderBytes()) } // len(header.Extra) >= extraVanity+extraSeal has already been validated in validateHeaderExtraField, so this won't result in a panic - if !bytes.Equal(header.Extra[extraVanity : len(header.Extra)-extraSeal], validatorsBytes) { + if !bytes.Equal(header.Extra[extraVanity:len(header.Extra)-extraSeal], validatorsBytes) { return errMismatchingSprintValidators } } diff --git a/consensus/bor/bor_test/helper.go b/consensus/bor/bor_test/helper.go index 1ead54ed88..48735a7c5f 100644 --- a/consensus/bor/bor_test/helper.go +++ b/consensus/bor/bor_test/helper.go @@ -107,13 +107,13 @@ func buildMinimalNextHeader(t *testing.T, block *types.Block, borConfig *params. header.Time += bor.CalcProducerDelay(header.Number.Uint64(), borConfig.Period, borConfig.Sprint, borConfig.ProducerDelay) isSprintEnd := (header.Number.Uint64()+1)%borConfig.Sprint == 0 if isSprintEnd { - header.Extra = make([]byte, 32 + 40 + 65) // vanity + validatorBytes + extraSeal + header.Extra = make([]byte, 32+40+65) // vanity + validatorBytes + extraSeal // the genesis file was initialized with a validator 0x71562b71999873db5b286df957af199ec94617f7 with power 10 // So, if you change ./genesis.json, do change the following as well validatorBytes, _ := hex.DecodeString("71562b71999873db5b286df957af199ec94617f7000000000000000000000000000000000000000a") copy(header.Extra[32:72], validatorBytes) } else { - header.Extra = make([]byte, 32 + 65) // vanity + extraSeal + header.Extra = make([]byte, 32+65) // vanity + extraSeal } _key, _ := hex.DecodeString(privKey) sig, err := secp256k1.Sign(crypto.Keccak256(bor.BorRLP(header)), _key) diff --git a/consensus/bor/merkle.go b/consensus/bor/merkle.go new file mode 100644 index 0000000000..bdfbaba983 --- /dev/null +++ b/consensus/bor/merkle.go @@ -0,0 +1,48 @@ +package bor + +func appendBytes32(data ...[]byte) []byte { + var result []byte + for _, v := range data { + paddedV, err := convertTo32(v) + if err == nil { + result = append(result, paddedV[:]...) + } + } + return result +} + +func nextPowerOfTwo(n uint64) uint64 { + if n == 0 { + return 1 + } + // http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 + n-- + n |= n >> 1 + n |= n >> 2 + n |= n >> 4 + n |= n >> 8 + n |= n >> 16 + n |= n >> 32 + n++ + return n +} + +func convertTo32(input []byte) (output [32]byte, err error) { + l := len(input) + if l > 32 || l == 0 { + return + } + copy(output[32-l:], input[:]) + return +} + +func convert(input []([32]byte)) [][]byte { + var output [][]byte + for _, in := range input { + newInput := make([]byte, len(in[:])) + copy(newInput, in[:]) + output = append(output, newInput) + + } + return output +} diff --git a/go.mod b/go.mod index ca433a71c6..efce11a0bf 100644 --- a/go.mod +++ b/go.mod @@ -60,6 +60,7 @@ require ( github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 + github.com/xsleonard/go-merkle v1.1.0 golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4 golang.org/x/net v0.0.0-20200301022130-244492dfa37a golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e diff --git a/go.sum b/go.sum index c51ed2d8e9..c15b30bb97 100644 --- a/go.sum +++ b/go.sum @@ -176,6 +176,8 @@ github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef h1:wHSqTBrZ github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 h1:1cngl9mPEoITZG8s8cVcUy5CeIBYhEESkOB7m6Gmkrk= github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees= +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= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4 h1:QmwruyY+bKbDDL0BaglrbZABEali68eoMFhTZpCjYVA= diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index d3fea7b50c..9ee4b4f3a7 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -149,6 +149,11 @@ web3._extend({ call: 'bor_getCurrentValidators', params: 0 }), + new web3._extend.Method({ + name: 'getRootHash', + call: 'bor_getRootHash', + params: 2, + }), ] }); ` From bbe6522f3575e7f3df65ccdd2cd03110e008920f Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Tue, 5 May 2020 14:45:56 +0530 Subject: [PATCH 12/46] new: Add GetRootHash to api backend --- consensus/bor/api.go | 65 +++++++++++++++++++++++++++++++------- consensus/bor/errors.go | 28 ++++++++++++++++ eth/api_backend.go | 14 ++++++++ internal/ethapi/api.go | 8 +++++ internal/ethapi/backend.go | 1 + les/api_backend.go | 4 +++ 6 files changed, 109 insertions(+), 11 deletions(-) diff --git a/consensus/bor/api.go b/consensus/bor/api.go index 7ef9cdcd47..ca64cd5521 100644 --- a/consensus/bor/api.go +++ b/consensus/bor/api.go @@ -17,9 +17,12 @@ package bor import ( + "math" "math/big" + "strconv" "sync" + lru "github.com/hashicorp/golang-lru" "github.com/maticnetwork/bor/common" "github.com/maticnetwork/bor/consensus" "github.com/maticnetwork/bor/core/types" @@ -29,11 +32,17 @@ import ( "golang.org/x/crypto/sha3" ) +var ( + // MaxCheckpointLength is the maximum number of blocks that can be requested for constructing a checkpoint root hash + MaxCheckpointLength = uint64(math.Pow(2, 15)) +) + // API is a user facing RPC API to allow controlling the signer and voting // mechanisms of the proof-of-authority scheme. type API struct { - chain consensus.ChainReader - bor *Bor + chain consensus.ChainReader + bor *Bor + rootHashCache *lru.ARCCache } // GetSnapshot retrieves the state snapshot at a given block. @@ -112,22 +121,38 @@ func (api *API) GetCurrentValidators() ([]*Validator, error) { return snap.ValidatorSet.Validators, nil } -// GetRootHash gets the current validators -func (api *API) GetRootHash(start uint64, end uint64) ([]byte, error) { +// GetRootHash returns the merkle root of the start to end block headers +func (api *API) GetRootHash(start int64, end int64) ([]byte, error) { + key := getKey(start, end) + if root, err := api.lookupCache(key); err != nil { + return nil, err + } else if root != nil { + return root, nil + } + length := uint64(end - start + 1) + if length > MaxCheckpointLength { + return nil, &MaxCheckpointLengthExceededError{start, end} + } + currentHeaderNumber := api.chain.CurrentHeader().Number.Int64() + if start > end || end > currentHeaderNumber { + return nil, &InvalidStartEndBlockError{start, end, currentHeaderNumber} + } blockHeaders := make([]*types.Header, end-start+1) wg := new(sync.WaitGroup) - // do we want to limit the # of concurrent go routines? + concurrent := make(chan bool, 20) for i := start; i <= end; i++ { wg.Add(1) - go func(number uint64) { - blockHeaders[number-start] = api.chain.GetHeaderByNumber(number) + concurrent <- true + go func(number int64) { + blockHeaders[number-start] = api.chain.GetHeaderByNumber(uint64(number)) + <-concurrent wg.Done() }(i) } wg.Wait() + close(concurrent) - expectedLength := nextPowerOfTwo(end - start + 1) - headers := make([][32]byte, expectedLength) + headers := make([][32]byte, nextPowerOfTwo(length)) for i := 0; i < len(blockHeaders); i++ { blockHeader := blockHeaders[i] header := crypto.Keccak256(appendBytes32( @@ -146,6 +171,24 @@ func (api *API) GetRootHash(start uint64, end uint64) ([]byte, error) { if err := tree.Generate(convert(headers), sha3.NewLegacyKeccak256()); err != nil { return nil, err } - - return tree.Root().Hash, nil + root := tree.Root().Hash + api.rootHashCache.Add(key, root) + return root, nil +} + +func (api *API) lookupCache(key string) ([]byte, error) { + var err error + if api.rootHashCache == nil { + if api.rootHashCache, err = lru.NewARC(10); err != nil { + return nil, err + } + } + if root, known := api.rootHashCache.Get(key); known { + return root.([]byte), nil + } + return nil, nil +} + +func getKey(start int64, end int64) string { + return strconv.FormatInt(start, 10) + "-" + strconv.FormatInt(end, 10) } diff --git a/consensus/bor/errors.go b/consensus/bor/errors.go index a3b0dc656d..ae7da982a7 100644 --- a/consensus/bor/errors.go +++ b/consensus/bor/errors.go @@ -40,3 +40,31 @@ func (e *TotalVotingPowerExceededError) Error() string { e.Validators, ) } + +type InvalidStartEndBlockError struct { + Start int64 + End int64 + CurrentHeader int64 +} + +func (e *InvalidStartEndBlockError) Error() string { + return fmt.Sprintf( + "Invalid parameters start: %d and end block: %d params", + e.Start, + e.End, + ) +} + +type MaxCheckpointLengthExceededError struct { + Start int64 + End int64 +} + +func (e *MaxCheckpointLengthExceededError) Error() string { + return fmt.Sprintf( + "Start: %d and end block: %d exceed max allowed checkpoint length: %d", + e.Start, + e.End, + MaxCheckpointLength, + ) +} diff --git a/eth/api_backend.go b/eth/api_backend.go index ff03d1a91e..7958f86b37 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -248,3 +248,17 @@ func (b *EthAPIBackend) ServiceFilter(ctx context.Context, session *bloombits.Ma go session.Multiplex(bloomRetrievalBatch, bloomRetrievalWait, b.eth.bloomRequests) } } + +func (b *EthAPIBackend) GetRootHash(ctx context.Context, starBlockNr rpc.BlockNumber, endBlockNr rpc.BlockNumber) ([]byte, error) { + var api *bor.API + for _, _api := range b.eth.Engine().APIs(b.eth.BlockChain()) { + if _api.Namespace == "bor" { + api = _api.Service.(*bor.API) + } + } + root, err := api.GetRootHash(starBlockNr.Int64(), endBlockNr.Int64()) + if err != nil { + return nil, err + } + return root, nil +} diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 2a939ed2c4..0ad624e7ed 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -716,6 +716,14 @@ func (s *PublicBlockChainAPI) GetStorageAt(ctx context.Context, address common.A return res[:], state.Error() } +func (s *PublicBlockChainAPI) GetRootHash(ctx context.Context, starBlockNr rpc.BlockNumber, endBlockNr rpc.BlockNumber) ([]byte, error) { + root, err := s.b.GetRootHash(ctx, starBlockNr, endBlockNr) + if err != nil { + return nil, err + } + return root, nil +} + // CallArgs represents the arguments for a call. type CallArgs struct { From *common.Address `json:"from"` diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go index e0deeab81f..21cef13f44 100644 --- a/internal/ethapi/backend.go +++ b/internal/ethapi/backend.go @@ -62,6 +62,7 @@ type Backend interface { SubscribeStateEvent(ch chan<- core.NewStateChangeEvent) event.Subscription SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription + GetRootHash(ctx context.Context, starBlockNr rpc.BlockNumber, endBlockNr rpc.BlockNumber) ([]byte, error) // Transaction pool API SendTx(ctx context.Context, signedTx *types.Transaction) error diff --git a/les/api_backend.go b/les/api_backend.go index 5c8ec82d88..4739abcdeb 100644 --- a/les/api_backend.go +++ b/les/api_backend.go @@ -223,3 +223,7 @@ func (b *LesApiBackend) ServiceFilter(ctx context.Context, session *bloombits.Ma go session.Multiplex(bloomRetrievalBatch, bloomRetrievalWait, b.eth.bloomRequests) } } + +func (b *LesApiBackend) GetRootHash(ctx context.Context, starBlockNr rpc.BlockNumber, endBlockNr rpc.BlockNumber) ([]byte, error) { + return nil, errors.New("Not implemented") +} From 54bbdff1e4a26ae65760cbddfa9cd886e8e03613 Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Wed, 6 May 2020 16:35:12 +0530 Subject: [PATCH 13/46] Initialize apiCache in once.do --- consensus/bor/api.go | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/consensus/bor/api.go b/consensus/bor/api.go index ca64cd5521..d5de0a61cb 100644 --- a/consensus/bor/api.go +++ b/consensus/bor/api.go @@ -35,6 +35,7 @@ import ( var ( // MaxCheckpointLength is the maximum number of blocks that can be requested for constructing a checkpoint root hash MaxCheckpointLength = uint64(math.Pow(2, 15)) + once sync.Once ) // API is a user facing RPC API to allow controlling the signer and voting @@ -123,11 +124,18 @@ func (api *API) GetCurrentValidators() ([]*Validator, error) { // GetRootHash returns the merkle root of the start to end block headers func (api *API) GetRootHash(start int64, end int64) ([]byte, error) { - key := getKey(start, end) - if root, err := api.lookupCache(key); err != nil { + var err error + once.Do(func() { + if api.rootHashCache == nil { + api.rootHashCache, err = lru.NewARC(10) + } + }) + if err != nil { return nil, err - } else if root != nil { - return root, nil + } + key := getRootHashKey(start, end) + if root, known := api.rootHashCache.Get(key); known { + return root.([]byte), nil } length := uint64(end - start + 1) if length > MaxCheckpointLength { @@ -176,19 +184,6 @@ func (api *API) GetRootHash(start int64, end int64) ([]byte, error) { return root, nil } -func (api *API) lookupCache(key string) ([]byte, error) { - var err error - if api.rootHashCache == nil { - if api.rootHashCache, err = lru.NewARC(10); err != nil { - return nil, err - } - } - if root, known := api.rootHashCache.Get(key); known { - return root.([]byte), nil - } - return nil, nil -} - -func getKey(start int64, end int64) string { +func getRootHashKey(start int64, end int64) string { return strconv.FormatInt(start, 10) + "-" + strconv.FormatInt(end, 10) } From 50c0b662cfeeee8b8f14ff8131429bfd1e8eaf16 Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Wed, 6 May 2020 17:14:53 +0530 Subject: [PATCH 14/46] Remove once.do --- consensus/bor/api.go | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/consensus/bor/api.go b/consensus/bor/api.go index d5de0a61cb..672d378215 100644 --- a/consensus/bor/api.go +++ b/consensus/bor/api.go @@ -35,7 +35,6 @@ import ( var ( // MaxCheckpointLength is the maximum number of blocks that can be requested for constructing a checkpoint root hash MaxCheckpointLength = uint64(math.Pow(2, 15)) - once sync.Once ) // API is a user facing RPC API to allow controlling the signer and voting @@ -124,13 +123,7 @@ func (api *API) GetCurrentValidators() ([]*Validator, error) { // GetRootHash returns the merkle root of the start to end block headers func (api *API) GetRootHash(start int64, end int64) ([]byte, error) { - var err error - once.Do(func() { - if api.rootHashCache == nil { - api.rootHashCache, err = lru.NewARC(10) - } - }) - if err != nil { + if err := api.initializeRootHashCache(); err != nil { return nil, err } key := getRootHashKey(start, end) @@ -184,6 +177,14 @@ func (api *API) GetRootHash(start int64, end int64) ([]byte, error) { return root, nil } +func (api *API) initializeRootHashCache() error { + var err error + if api.rootHashCache == nil { + api.rootHashCache, err = lru.NewARC(10) + } + return err +} + func getRootHashKey(start int64, end int64) string { return strconv.FormatInt(start, 10) + "-" + strconv.FormatInt(end, 10) } From 67c29d7ce30d1719556e08c6f0c1f9416c45f2bb Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Thu, 7 May 2020 20:17:15 +0530 Subject: [PATCH 15/46] chg: Add GetRootHash to ethClient / use uint64 --- consensus/bor/api.go | 23 ++++++++++++----------- consensus/bor/errors.go | 10 +++++----- eth/api_backend.go | 6 +++--- ethclient/ethclient.go | 9 +++++++++ internal/ethapi/api.go | 4 ++-- internal/ethapi/backend.go | 2 +- les/api_backend.go | 4 ++-- 7 files changed, 34 insertions(+), 24 deletions(-) diff --git a/consensus/bor/api.go b/consensus/bor/api.go index 672d378215..5af1ddbc39 100644 --- a/consensus/bor/api.go +++ b/consensus/bor/api.go @@ -17,6 +17,7 @@ package bor import ( + "encoding/hex" "math" "math/big" "strconv" @@ -122,21 +123,21 @@ func (api *API) GetCurrentValidators() ([]*Validator, error) { } // GetRootHash returns the merkle root of the start to end block headers -func (api *API) GetRootHash(start int64, end int64) ([]byte, error) { +func (api *API) GetRootHash(start uint64, end uint64) (string, error) { if err := api.initializeRootHashCache(); err != nil { - return nil, err + return "", err } key := getRootHashKey(start, end) if root, known := api.rootHashCache.Get(key); known { - return root.([]byte), nil + return root.(string), nil } length := uint64(end - start + 1) if length > MaxCheckpointLength { - return nil, &MaxCheckpointLengthExceededError{start, end} + return "", &MaxCheckpointLengthExceededError{start, end} } - currentHeaderNumber := api.chain.CurrentHeader().Number.Int64() + currentHeaderNumber := api.chain.CurrentHeader().Number.Uint64() if start > end || end > currentHeaderNumber { - return nil, &InvalidStartEndBlockError{start, end, currentHeaderNumber} + return "", &InvalidStartEndBlockError{start, end, currentHeaderNumber} } blockHeaders := make([]*types.Header, end-start+1) wg := new(sync.WaitGroup) @@ -144,7 +145,7 @@ func (api *API) GetRootHash(start int64, end int64) ([]byte, error) { for i := start; i <= end; i++ { wg.Add(1) concurrent <- true - go func(number int64) { + go func(number uint64) { blockHeaders[number-start] = api.chain.GetHeaderByNumber(uint64(number)) <-concurrent wg.Done() @@ -170,9 +171,9 @@ func (api *API) GetRootHash(start int64, end int64) ([]byte, error) { tree := merkle.NewTreeWithOpts(merkle.TreeOptions{EnableHashSorting: false, DisableHashLeaves: true}) if err := tree.Generate(convert(headers), sha3.NewLegacyKeccak256()); err != nil { - return nil, err + return "", err } - root := tree.Root().Hash + root := hex.EncodeToString(tree.Root().Hash) api.rootHashCache.Add(key, root) return root, nil } @@ -185,6 +186,6 @@ func (api *API) initializeRootHashCache() error { return err } -func getRootHashKey(start int64, end int64) string { - return strconv.FormatInt(start, 10) + "-" + strconv.FormatInt(end, 10) +func getRootHashKey(start uint64, end uint64) string { + return strconv.FormatUint(start, 10) + "-" + strconv.FormatUint(end, 10) } diff --git a/consensus/bor/errors.go b/consensus/bor/errors.go index ae7da982a7..f9f99e2b64 100644 --- a/consensus/bor/errors.go +++ b/consensus/bor/errors.go @@ -42,9 +42,9 @@ func (e *TotalVotingPowerExceededError) Error() string { } type InvalidStartEndBlockError struct { - Start int64 - End int64 - CurrentHeader int64 + Start uint64 + End uint64 + CurrentHeader uint64 } func (e *InvalidStartEndBlockError) Error() string { @@ -56,8 +56,8 @@ func (e *InvalidStartEndBlockError) Error() string { } type MaxCheckpointLengthExceededError struct { - Start int64 - End int64 + Start uint64 + End uint64 } func (e *MaxCheckpointLengthExceededError) Error() string { diff --git a/eth/api_backend.go b/eth/api_backend.go index 7958f86b37..0be0376cf5 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -249,16 +249,16 @@ func (b *EthAPIBackend) ServiceFilter(ctx context.Context, session *bloombits.Ma } } -func (b *EthAPIBackend) GetRootHash(ctx context.Context, starBlockNr rpc.BlockNumber, endBlockNr rpc.BlockNumber) ([]byte, error) { +func (b *EthAPIBackend) GetRootHash(ctx context.Context, starBlockNr uint64, endBlockNr uint64) (string, error) { var api *bor.API for _, _api := range b.eth.Engine().APIs(b.eth.BlockChain()) { if _api.Namespace == "bor" { api = _api.Service.(*bor.API) } } - root, err := api.GetRootHash(starBlockNr.Int64(), endBlockNr.Int64()) + root, err := api.GetRootHash(starBlockNr, endBlockNr) if err != nil { - return nil, err + return "", err } return root, nil } diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go index 5d349a289b..7d44b0da03 100644 --- a/ethclient/ethclient.go +++ b/ethclient/ethclient.go @@ -522,6 +522,15 @@ func (ec *Client) SendTransaction(ctx context.Context, tx *types.Transaction) er return ec.c.CallContext(ctx, nil, "eth_sendRawTransaction", common.ToHex(data)) } +// GetRootHash returns the merkle root of the block headers +func (ec *Client) GetRootHash(ctx context.Context, startBlockNumber uint64, endBlockNumber uint64) (string, error) { + var rootHash string + if err := ec.c.CallContext(ctx, &rootHash, "eth_getRootHash", startBlockNumber, endBlockNumber); err != nil { + return "", err + } + return rootHash, nil +} + func toCallArg(msg ethereum.CallMsg) interface{} { arg := map[string]interface{}{ "from": msg.From, diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 0ad624e7ed..cee5a575fb 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -716,10 +716,10 @@ func (s *PublicBlockChainAPI) GetStorageAt(ctx context.Context, address common.A return res[:], state.Error() } -func (s *PublicBlockChainAPI) GetRootHash(ctx context.Context, starBlockNr rpc.BlockNumber, endBlockNr rpc.BlockNumber) ([]byte, error) { +func (s *PublicBlockChainAPI) GetRootHash(ctx context.Context, starBlockNr uint64, endBlockNr uint64) (string, error) { root, err := s.b.GetRootHash(ctx, starBlockNr, endBlockNr) if err != nil { - return nil, err + return "", err } return root, nil } diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go index 21cef13f44..595a69b0cc 100644 --- a/internal/ethapi/backend.go +++ b/internal/ethapi/backend.go @@ -62,7 +62,7 @@ type Backend interface { SubscribeStateEvent(ch chan<- core.NewStateChangeEvent) event.Subscription SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription - GetRootHash(ctx context.Context, starBlockNr rpc.BlockNumber, endBlockNr rpc.BlockNumber) ([]byte, error) + GetRootHash(ctx context.Context, starBlockNr uint64, endBlockNr uint64) (string, error) // Transaction pool API SendTx(ctx context.Context, signedTx *types.Transaction) error diff --git a/les/api_backend.go b/les/api_backend.go index 4739abcdeb..3b228e7374 100644 --- a/les/api_backend.go +++ b/les/api_backend.go @@ -224,6 +224,6 @@ func (b *LesApiBackend) ServiceFilter(ctx context.Context, session *bloombits.Ma } } -func (b *LesApiBackend) GetRootHash(ctx context.Context, starBlockNr rpc.BlockNumber, endBlockNr rpc.BlockNumber) ([]byte, error) { - return nil, errors.New("Not implemented") +func (b *LesApiBackend) GetRootHash(ctx context.Context, starBlockNr uint64, endBlockNr uint64) (string, error) { + return "", errors.New("Not implemented") } From d1ea515af1bb1420bdd3103d48e448c5f7f7ec5e Mon Sep 17 00:00:00 2001 From: Arpit Agarwal <93arpit@gmail.com> Date: Mon, 11 May 2020 17:00:33 +0530 Subject: [PATCH 16/46] chg: Cancel active sealing op when a new chain segment is received (MAT-1116) (#54) * dev: Fix out-of-turn signing log statement * dev: Cancel active sealing op when a new chain segment is received * remove debug statement and return value * minor: no need to use a channel * Fix race condition in shouldSeal channel * Info -> Debug statement --- consensus/bor/bor.go | 68 +++++++++++++++++++++++++++++++++++------ consensus/bor/errors.go | 11 +++++++ consensus/consensus.go | 7 +++++ core/blockchain.go | 1 + core/tx_pool.go | 8 +---- 5 files changed, 78 insertions(+), 17 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 945395dd6b..c8e8b7b91c 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -138,6 +138,12 @@ var ( errRecentlySigned = errors.New("recently signed") ) +// ActiveSealingOp keeps the context of the active sealing operation +type ActiveSealingOp struct { + number uint64 + cancel context.CancelFunc +} + // SignerFn is a signer callback function to request a header to be signed by a // backing account. type SignerFn func(accounts.Account, string, []byte) ([]byte, error) @@ -246,8 +252,9 @@ type Bor struct { stateReceiverABI abi.ABI HeimdallClient IHeimdallClient - stateDataFeed event.Feed - scope event.SubscriptionScope + stateDataFeed event.Feed + scope event.SubscriptionScope + activeSealingOp *ActiveSealingOp // The fields below are for testing only fakeDiff bool // Skip difficulty verifications } @@ -725,6 +732,9 @@ func (c *Bor) Authorize(signer common.Address, signFn SignerFn) { // Seal implements consensus.Engine, attempting to create a sealed block using // the local signing credentials. func (c *Bor) Seal(chain consensus.ChainReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error { + if c.activeSealingOp != nil { + return &SealingInFlightError{c.activeSealingOp.number} + } header := block.Header() // Sealing the genesis block is not supported @@ -762,9 +772,6 @@ func (c *Bor) Seal(chain consensus.ChainReader, block *types.Block, results chan wiggle := time.Duration(2*c.config.Period) * time.Second * time.Duration(successionNumber) delay += wiggle - log.Info("Out-of-turn signing requested", "wiggle", common.PrettyDuration(wiggle)) - log.Info("Sealing block with", "number", number, "delay", delay, "headerDifficulty", header.Difficulty, "signer", signer.Hex(), "proposer", snap.ValidatorSet.GetProposer().Address.Hex()) - // Sign all the things! sighash, err := signFn(accounts.Account{Address: signer}, accounts.MimetypeBor, BorRLP(header)) if err != nil { @@ -774,23 +781,64 @@ func (c *Bor) Seal(chain consensus.ChainReader, block *types.Block, results chan // Wait until sealing is terminated or delay timeout. log.Trace("Waiting for slot to sign and propagate", "delay", common.PrettyDuration(delay)) + shouldSeal := make(chan bool) + go c.WaitForSealingOp(number, shouldSeal, delay, stop) go func() { - select { - case <-stop: + defer func() { + close(shouldSeal) + c.activeSealingOp = nil + }() + switch <-shouldSeal { + case false: return - case <-time.After(delay): + case true: + if wiggle > 0 { + log.Info( + "Sealing out-of-turn", + "number", number, + "wiggle", common.PrettyDuration(wiggle), + "in-turn-signer", snap.ValidatorSet.GetProposer().Address.Hex(), + ) + } + log.Info( + "Sealing successful", + "number", number, + "delay", delay, + "headerDifficulty", header.Difficulty, + ) } select { case results <- block.WithSeal(header): default: - log.Warn("Sealing result is not read by miner", "sealhash", SealHash(header)) + log.Warn("Sealing result was not read by miner", "sealhash", SealHash(header)) } }() - return nil } +// WaitForSealingOp blocks until delay elapses or stop signal is received +func (c *Bor) WaitForSealingOp(number uint64, shouldSeal chan bool, delay time.Duration, stop <-chan struct{}) { + ctx, cancel := context.WithCancel(context.Background()) + c.activeSealingOp = &ActiveSealingOp{number, cancel} + select { + case <-stop: + shouldSeal <- false + case <-ctx.Done(): + shouldSeal <- false + case <-time.After(delay): + shouldSeal <- true + } +} + +// CancelActiveSealingOp cancels in-flight sealing process +func (c *Bor) CancelActiveSealingOp() { + if c.activeSealingOp != nil { + log.Debug("Discarding active sealing operation", "number", c.activeSealingOp.number) + c.activeSealingOp.cancel() + } +} + // CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty // that a new block should have based on the previous blocks in the chain and the // current signer. diff --git a/consensus/bor/errors.go b/consensus/bor/errors.go index f9f99e2b64..8b09bdfe9f 100644 --- a/consensus/bor/errors.go +++ b/consensus/bor/errors.go @@ -68,3 +68,14 @@ func (e *MaxCheckpointLengthExceededError) Error() string { MaxCheckpointLength, ) } + +type SealingInFlightError struct { + Number uint64 +} + +func (e *SealingInFlightError) Error() string { + return fmt.Sprintf( + "Requested concurrent block sealing. Sealing for block %d is already in progress", + e.Number, + ) +} diff --git a/consensus/consensus.go b/consensus/consensus.go index e86583f394..0620cff059 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -116,6 +116,13 @@ type Engine interface { Close() error } +// Bor is a consensus engine developed by folks at Matic Network +type Bor interface { + Engine + IsValidatorAction(chain ChainReader, from common.Address, tx *types.Transaction) bool + CancelActiveSealingOp() +} + // PoW is a consensus engine based on proof-of-work. type PoW interface { Engine diff --git a/core/blockchain.go b/core/blockchain.go index e90ffbb30e..3ce4356929 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1718,6 +1718,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, [] if lastCanon != nil && bc.CurrentBlock().Hash() == lastCanon.Hash() { events = append(events, ChainHeadEvent{lastCanon}) } + bc.engine.(consensus.Bor).CancelActiveSealingOp() return it.index, events, coalescedLogs, err } diff --git a/core/tx_pool.go b/core/tx_pool.go index 02011586c3..1462c2324e 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -117,12 +117,6 @@ const ( TxStatusIncluded ) -// bor acts as a way to be able to type cast consensus.Engine; -// since importing "github.com/maticnetwork/bor/consensus/bor" results in a cyclic dependency -type bor interface { - IsValidatorAction(chain consensus.ChainReader, from common.Address, tx *types.Transaction) bool -} - // blockChain provides the state of blockchain and current gas limit to do // some pre checks in tx pool and event subscribers. type blockChain interface { @@ -537,7 +531,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { // Drop non-local transactions under our own minimal accepted gas price local = local || pool.locals.contains(from) // account may be local even if the transaction arrived from the network if !local && - !pool.chain.Engine().(bor).IsValidatorAction(pool.chain.(consensus.ChainReader), from, tx) && + !pool.chain.Engine().(consensus.Bor).IsValidatorAction(pool.chain.(consensus.ChainReader), from, tx) && pool.gasPrice.Cmp(tx.GasPrice()) > 0 { return ErrUnderpriced } From 0f8d3b1006bba659502c0781fc31ef4753e745e8 Mon Sep 17 00:00:00 2001 From: Arpit Agarwal <93arpit@gmail.com> Date: Wed, 13 May 2020 14:08:21 +0530 Subject: [PATCH 17/46] fix: Check validator bytes at first block of sprint (MAT-1311) (#56) * Check validator bytes at first block of sprint * not required to get parent again * fix tests * fix build error --- consensus/bor/bor.go | 16 +++++----- consensus/bor/bor_test/bor_test.go | 45 ++++++++++++----------------- consensus/bor/bor_test/genesis.json | 8 ++--- consensus/bor/bor_test/helper.go | 43 ++++++++++++++++++--------- consensus/bor/bor_test/span.json | 2 +- consensus/bor/errors.go | 17 +++++++++++ 6 files changed, 78 insertions(+), 53 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index c8e8b7b91c..700bc879e9 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -105,10 +105,6 @@ var ( // invalid list of validators (i.e. non divisible by 40 bytes). errInvalidSpanValidators = errors.New("invalid validator list on sprint end block") - // errMismatchingSprintValidators is returned if a sprint block contains a - // list of validators different than the one the local node calculated. - errMismatchingSprintValidators = errors.New("mismatching validator list on sprint block") - // errInvalidMixDigest is returned if a block's mix digest is non-zero. errInvalidMixDigest = errors.New("non-zero mix digest") @@ -436,9 +432,9 @@ func (c *Bor) verifyCascadingFields(chain consensus.ChainReader, header *types.H return err } - isSprintEnd := (number+1)%c.config.Sprint == 0 // verify the validator list in the last sprint block - if isSprintEnd { + if isSprintStart(number, c.config.Sprint) { + parentValidatorBytes := parent.Extra[extraVanity : len(parent.Extra)-extraSeal] validatorsBytes := make([]byte, len(snap.ValidatorSet.Validators)*validatorHeaderBytesLength) currentValidators := snap.ValidatorSet.Copy().Validators @@ -448,8 +444,8 @@ func (c *Bor) verifyCascadingFields(chain consensus.ChainReader, header *types.H copy(validatorsBytes[i*validatorHeaderBytesLength:], validator.HeaderBytes()) } // len(header.Extra) >= extraVanity+extraSeal has already been validated in validateHeaderExtraField, so this won't result in a panic - if !bytes.Equal(header.Extra[extraVanity:len(header.Extra)-extraSeal], validatorsBytes) { - return errMismatchingSprintValidators + if !bytes.Equal(parentValidatorBytes, validatorsBytes) { + return &MismatchingValidatorsError{number - 1, validatorsBytes, parentValidatorBytes} } } @@ -1417,3 +1413,7 @@ func getUpdatedValidatorSet(oldValidatorSet *ValidatorSet, newVals []*Validator) v.UpdateWithChangeSet(changes) return v } + +func isSprintStart(number, sprint uint64) bool { + return number%sprint == 0 +} diff --git a/consensus/bor/bor_test/bor_test.go b/consensus/bor/bor_test/bor_test.go index 13fb4f2e6b..b7cf4659bd 100644 --- a/consensus/bor/bor_test/bor_test.go +++ b/consensus/bor/bor_test/bor_test.go @@ -24,31 +24,34 @@ func TestCommitSpan(t *testing.T) { // Mock HeimdallClient.FetchWithRetry to return span data from span.json res, heimdallSpan := loadSpanFromFile(t) h := &mocks.IHeimdallClient{} - h.On("FetchWithRetry", "bor", "span", "1"). - Return(res, nil). - Times(2) // both FinalizeAndAssemble and chain.InsertChain call HeimdallClient.FetchWithRetry. @todo Investigate this in depth + // FetchWithRetry is invoked 3 times + // 1. bor.FinalizeAndAssemble to prepare a new block when calling insertNewBlock + // 2. bor.Finalize via(bc.insertChain => bc.processor.Process) + // 3. bor.FinalizeAndAssemble via worker.commit + h.On("FetchWithRetry", "bor", "span", "1").Return(res, nil).Times(3) _bor.SetHeimdallClient(h) db := init.ethereum.ChainDb() - block := init.genesis.ToBlock(db) - // Build 1st block's header - header := buildMinimalNextHeader(t, block, init.genesis.Config.Bor) - statedb, err := chain.State() if err != nil { t.Fatalf("%s", err) } - _key, _ := hex.DecodeString(privKey) - insertNewBlock(t, _bor, chain, header, statedb, _key) - assert.True(t, h.AssertNumberOfCalls(t, "FetchWithRetry", 2)) - validators, err := _bor.GetCurrentValidators(1, 256) // new span starts at 256 + block := init.genesis.ToBlock(db) + // Insert sprintSize # of blocks so that span is fetched at the start of a new sprint + for i := uint64(1); i <= sprintSize; i++ { + header := buildMinimalNextHeader(t, block, init.genesis.Config.Bor) + block = insertNewBlock(t, _bor, chain, header, statedb, _key) + } + + assert.True(t, h.AssertNumberOfCalls(t, "FetchWithRetry", 3)) + validators, err := _bor.GetCurrentValidators(sprintSize, 256) // new span starts at 256 if err != nil { t.Fatalf("%s", err) } - assert.Equal(t, len(validators), 3) + assert.Equal(t, 3, len(validators)) for i, validator := range validators { assert.Equal(t, validator.Address.Bytes(), heimdallSpan.SelectedProducers[i].Address.Bytes()) assert.Equal(t, validator.VotingPower, heimdallSpan.SelectedProducers[i].VotingPower) @@ -85,29 +88,17 @@ func TestIsValidatorAction(t *testing.T) { h.On("FetchWithRetry", "bor", "span", "1").Return(res, nil) _bor.SetHeimdallClient(h) - // Build 1st block's header db := init.ethereum.ChainDb() - block := init.genesis.ToBlock(db) - - header := buildMinimalNextHeader(t, block, init.genesis.Config.Bor) statedb, err := chain.State() if err != nil { t.Fatalf("%s", err) } - _key, _ := hex.DecodeString(privKey) - insertNewBlock(t, _bor, chain, header, statedb, _key) - block = types.NewBlockWithHeader(header) - var headers []*types.Header - for i := int64(2); i <= 255; i++ { + block := init.genesis.ToBlock(db) + for i := uint64(1); i <= spanSize; i++ { header := buildMinimalNextHeader(t, block, init.genesis.Config.Bor) - headers = append(headers, header) - block = types.NewBlockWithHeader(header) - } - t.Logf("inserting %v headers", len(headers)) - if _, err := chain.InsertHeaderChain(headers, 0); err != nil { - t.Fatalf("%s", err) + block = insertNewBlock(t, _bor, chain, header, statedb, _key) } for _, validator := range heimdallSpan.SelectedProducers { diff --git a/consensus/bor/bor_test/genesis.json b/consensus/bor/bor_test/genesis.json index 32b9cd5b2a..5525732b9d 100644 --- a/consensus/bor/bor_test/genesis.json +++ b/consensus/bor/bor_test/genesis.json @@ -11,7 +11,7 @@ "bor": { "period": 1, "producerDelay": 4, - "sprint": 1, + "sprint": 4, "validatorContract": "0x0000000000000000000000000000000000001000", "stateReceiverContract": "0x0000000000000000000000000000000000001001" } @@ -26,15 +26,15 @@ "alloc": { "0000000000000000000000000000000000001000": { "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b50600436106102115760003560e01c806365b3a1e211610125578063b2472431116100ad578063d0504f891161007c578063d0504f89146106af578063d5b844eb146106cb578063dcf2793a146106e9578063e3b7c9241461071b578063f59cf5651461073957610211565b8063b247243114610612578063b71d7a6914610630578063b7ab4db514610660578063c1b3c9191461067f57610211565b806370ba5707116100f457806370ba57071461055657806398ab2b62146105865780639d11b807146105a4578063ae756451146105d4578063af26aa96146105f257610211565b806365b3a1e2146104c957806366332354146104e8578063687a9bd61461050657806369c49fac1461053857610211565b806335ddfeea116101a85780634b0e4d17116101775780634b0e4d17146104215780634dbc959f1461042b57806355614fcc14610449578063582a8d081461047957806360c8614d146104a957610211565b806335ddfeea1461037357806343ee8213146103a357806344c15cb1146103c157806344d6528f146103f157610211565b806323f2a73f116101e457806323f2a73f146102c55780632de3a180146102f55780632eddf352146103255780633434735f1461035557610211565b8063047a6c5b146102165780630c35b1cb146102485780631270b5741461027957806323c2a2b4146102a9575b600080fd5b610230600480360361022b9190810190612e7e565b61076b565b60405161023f93929190613903565b60405180910390f35b610262600480360361025d9190810190612e7e565b6107c2565b6040516102709291906136c4565b60405180910390f35b610293600480360361028e9190810190612ea7565b61099e565b6040516102a091906136fb565b60405180910390f35b6102c360048036036102be9190810190612f86565b610af6565b005b6102df60048036036102da9190810190612ea7565b611177565b6040516102ec91906136fb565b60405180910390f35b61030f600480360361030a9190810190612d18565b6112cf565b60405161031c9190613716565b60405180910390f35b61033f600480360361033a9190810190612e7e565b611350565b60405161034c91906138b1565b60405180910390f35b61035d611481565b60405161036a91906136a9565b60405180910390f35b61038d60048036036103889190810190612d54565b611499565b60405161039a91906136fb565b60405180910390f35b6103ab611564565b6040516103b89190613716565b60405180910390f35b6103db60048036036103d69190810190612ee3565b61157b565b6040516103e891906138b1565b60405180910390f35b61040b60048036036104069190810190612ea7565b611663565b6040516104189190613896565b60405180910390f35b6104296117cc565b005b610433611828565b60405161044091906138b1565b60405180910390f35b610463600480360361045e9190810190612c9d565b611838565b60405161047091906136fb565b60405180910390f35b610493600480360361048e9190810190612cc6565b611852565b6040516104a09190613716565b60405180910390f35b6104b16118d0565b6040516104c093929190613903565b60405180910390f35b6104d1611944565b6040516104df9291906136c4565b60405180910390f35b6104f0611a34565b6040516104fd91906138b1565b60405180910390f35b610520600480360361051b9190810190612f4a565b611a39565b60405161052f939291906138cc565b60405180910390f35b610540611a9d565b60405161054d91906136fb565b60405180910390f35b610570600480360361056b9190810190612c9d565b611ab4565b60405161057d91906136fb565b60405180910390f35b61058e611ace565b60405161059b9190613716565b60405180910390f35b6105be60048036036105b99190810190612e7e565b611ae5565b6040516105cb91906138b1565b60405180910390f35b6105dc611c16565b6040516105e99190613716565b60405180910390f35b6105fa611c2d565b60405161060993929190613903565b60405180910390f35b61061a611c8e565b60405161062791906138b1565b60405180910390f35b61064a60048036036106459190810190612e7e565b611c94565b60405161065791906138b1565b60405180910390f35b610668611d94565b6040516106769291906136c4565b60405180910390f35b61069960048036036106949190810190612e7e565b611da8565b6040516106a691906138b1565b60405180910390f35b6106c960048036036106c49190810190612dbb565b611dc9565b005b6106d361201f565b6040516106e0919061393a565b60405180910390f35b61070360048036036106fe9190810190612f4a565b612024565b604051610712939291906138cc565b60405180910390f35b610723612088565b60405161073091906138b1565b60405180910390f35b610753600480360361074e9190810190612e7e565b61209a565b60405161076293929190613903565b60405180910390f35b60008060006004600085815260200190815260200160002060000154600460008681526020019081526020016000206001015460046000878152602001908152602001600020600201549250925092509193909250565b60608060ff83116107de576107d5611944565b91509150610999565b60006107e984611c94565b9050606060036000838152602001908152602001600020805490506040519080825280602002602001820160405280156108325781602001602082028038833980820191505090505b5090506060600360008481526020019081526020016000208054905060405190808252806020026020018201604052801561087c5781602001602082028038833980820191505090505b50905060008090505b600360008581526020019081526020016000208054905081101561098e576003600085815260200190815260200160002081815481106108c157fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168382815181106108ff57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060036000858152602001908152602001600020818154811061095757fe5b90600052602060002090600302016001015482828151811061097557fe5b6020026020010181815250508080600101915050610885565b508181945094505050505b915091565b6000606060036000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015610a71578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050815260200190600101906109d5565b50505050905060008090505b8151811015610ae9578373ffffffffffffffffffffffffffffffffffffffff16828281518110610aa957fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff161415610adc57600192505050610af0565b8080600101915050610a7d565b5060009150505b92915050565b73fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b4257600080fd5b6000610b4c611828565b90506000811415610b6057610b5f6120c4565b5b610b746001826123f090919063ffffffff16565b8814610bb5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bac906137b6565b60405180910390fd5b868611610bf7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bee90613816565b60405180910390fd5b6000805460018989030181610c0857fe5b0614610c49576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c40906137f6565b60405180910390fd5b8660046000838152602001908152602001600020600101541115610ca2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c9990613776565b60405180910390fd5b6000600460008a81526020019081526020016000206000015414610cfb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cf2906137d6565b60405180910390fd5b604051806060016040528089815260200188815260200187815250600460008a815260200190815260200160002060008201518160000155602082015181600101556040820151816002015590505060058890806001815401808255809150509060018203906000526020600020016000909192909190915055506000600260008a815260200190815260200160002081610d969190612a97565b506000600360008a815260200190815260200160002081610db79190612a97565b506060610e0f610e0a87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061240f565b61243d565b905060008090505b8151811015610f83576060610e3e838381518110610e3157fe5b602002602001015161243d565b9050600260008c81526020019081526020016000208054809190600101610e659190612a97565b506040518060600160405280610e8e83600081518110610e8157fe5b602002602001015161251a565b8152602001610eb083600181518110610ea357fe5b602002602001015161251a565b8152602001610ed283600281518110610ec557fe5b602002602001015161258b565b73ffffffffffffffffffffffffffffffffffffffff16815250600260008d81526020019081526020016000208381548110610f0957fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050508080600101915050610e17565b506060610fdb610fd686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061240f565b61243d565b905060008090505b815181101561114f57606061100a838381518110610ffd57fe5b602002602001015161243d565b9050600360008d815260200190815260200160002080548091906001016110319190612a97565b50604051806060016040528061105a8360008151811061104d57fe5b602002602001015161251a565b815260200161107c8360018151811061106f57fe5b602002602001015161251a565b815260200161109e8360028151811061109157fe5b602002602001015161258b565b73ffffffffffffffffffffffffffffffffffffffff16815250600360008e815260200190815260200160002083815481106110d557fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050508080600101915050610fe3565b506000600160006101000a81548160ff02191690831515021790555050505050505050505050565b6000606060026000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561124a578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050815260200190600101906111ae565b50505050905060008090505b81518110156112c2578373ffffffffffffffffffffffffffffffffffffffff1682828151811061128257fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff1614156112b5576001925050506112c9565b8080600101915050611256565b5060009150505b92915050565b60006002600160f81b84846040516020016112ec93929190613616565b6040516020818303038152906040526040516113089190613653565b602060405180830381855afa158015611325573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506113489190810190612cef565b905092915050565b6000606060026000848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015611423578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611387565b505050509050600080905060008090505b82518110156114765761146783828151811061144c57fe5b602002602001015160200151836123f090919063ffffffff16565b91508080600101915050611434565b508092505050919050565b73fffffffffffffffffffffffffffffffffffffffe81565b60008060008085905060006021808751816114b057fe5b0402905060008111156114c9576114c687611852565b91505b6000602190505b818111611553576000600182038801519050818801519550806000602081106114f557fe5b1a60f81b9450600060f81b857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561153a5761153386856112cf565b9350611547565b61154484876112cf565b93505b506021810190506114d0565b508782149450505050509392505050565b6040516115709061367f565b604051809103902081565b60008060009050600080905060008090505b84518167ffffffffffffffff1610156116565760606115b8868367ffffffffffffffff1660416125ae565b905060006115cf828961263a90919063ffffffff16565b90506115d9612ac9565b6115e38a83611663565b90506115ef8a83611177565b801561162657508473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16115b15611648578194506116458160200151876123f090919063ffffffff16565b95505b50505060418101905061158d565b5081925050509392505050565b61166b612ac9565b606060026000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561173c578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050815260200190600101906116a0565b50505050905060008090505b81518110156117c4578373ffffffffffffffffffffffffffffffffffffffff1682828151811061177457fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff1614156117b7578181815181106117a857fe5b602002602001015192506117c4565b8080600101915050611748565b505092915050565b60006117d6611828565b90506117e28133611177565b6117eb57600080fd5b60001515600160009054906101000a900460ff1615151461180b57600080fd5b60018060006101000a81548160ff02191690831515021790555050565b600061183343611c94565b905090565b600061184b611845611828565b83611177565b9050919050565b60006002600060f81b8360405160200161186d9291906135ea565b6040516020818303038152906040526040516118899190613653565b602060405180830381855afa1580156118a6573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506118c99190810190612cef565b9050919050565b6000806000806118f160016118e3611828565b6123f090919063ffffffff16565b905060046000828152602001908152602001600020600001546004600083815260200190815260200160002060010154600460008481526020019081526020016000206002015493509350935050909192565b606080606060016040519080825280602002602001820160405280156119795781602001602082028038833980820191505090505b5090507371562b71999873db5b286df957af199ec94617f78160008151811061199e57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060606001604051908082528060200260200182016040528015611a0a5781602001602082028038833980820191505090505b509050600a81600081518110611a1c57fe5b60200260200101818152505081819350935050509091565b60ff81565b60036020528160005260406000208181548110611a5257fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b6000600160009054906101000a900460ff16905090565b6000611ac7611ac1611828565b8361099e565b9050919050565b604051611ada9061366a565b604051809103902081565b6000606060036000848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015611bb8578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611b1c565b505050509050600080905060008090505b8251811015611c0b57611bfc838281518110611be157fe5b602002602001015160200151836123f090919063ffffffff16565b91508080600101915050611bc9565b508092505050919050565b604051611c2290613694565b604051809103902081565b600080600080611c3b611828565b905060046000828152602001908152602001600020600001546004600083815260200190815260200160002060010154600460008481526020019081526020016000206002015493509350935050909192565b60005481565b60008060058054905090505b6000811115611d5457611cb1612b00565b6004600060056001850381548110611cc557fe5b906000526020600020015481526020019081526020016000206040518060600160405290816000820154815260200160018201548152602001600282015481525050905083816020015111158015611d2257506000816040015114155b8015611d32575080604001518411155b15611d4557806000015192505050611d8f565b50808060019003915050611ca0565b5060006005805490501115611d8a57600560016005805490500381548110611d7857fe5b90600052602060002001549050611d8f565b600090505b919050565b606080611da0436107c2565b915091509091565b60058181548110611db557fe5b906000526020600020016000915090505481565b6060611ddc611dd78661240f565b61243d565b9050604051611dea9061367f565b6040518091039020611e0f82600081518110611e0257fe5b6020026020010151612744565b8051906020012014611e56576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e4d90613796565b60405180910390fd5b600260ff16611e7882600181518110611e6b57fe5b602002602001015161251a565b14611eb8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eaf90613836565b60405180910390fd5b611f31611ed882600481518110611ecb57fe5b602002602001015161251a565b60001b600285604051611eeb9190613653565b602060405180830381855afa158015611f08573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250611f2b9190810190612cef565b84611499565b611f70576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6790613856565b60405180910390fd5b6000611f7a611828565b90506000611f908288805190602001208861157b565b9050611fd46001611fc66003611fb86002611faa88611350565b6127d090919063ffffffff16565b61280a90919063ffffffff16565b6123f090919063ffffffff16565b811015612016576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161200d90613876565b60405180910390fd5b50505050505050565b600281565b6002602052816000526040600020818154811061203d57fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b60006040438161209457fe5b04905090565b60046020528060005260406000206000915090508060000154908060010154908060020154905083565b60406000819055506060806120d7611944565b8092508193505050600080905060405180606001604052808281526020016000815260200160ff815250600460008381526020019081526020016000206000820151816000015560208201518160010155604082015181600201559050506005819080600181540180825580915050906001820390600052602060002001600090919290919091505550600060026000838152602001908152602001600020816121819190612a97565b50600060036000838152602001908152602001600020816121a29190612a97565b5060008090505b83518110156122c6576002600083815260200190815260200160002080548091906001016121d79190612a97565b5060405180606001604052808281526020018483815181106121f557fe5b6020026020010151815260200185838151811061220e57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681525060026000848152602001908152602001600020828154811061224d57fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505080806001019150506121a9565b5060008090505b83518110156123ea576003600083815260200190815260200160002080548091906001016122fb9190612a97565b50604051806060016040528082815260200184838151811061231957fe5b6020026020010151815260200185838151811061233257fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681525060036000848152602001908152602001600020828154811061237157fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505080806001019150506122cd565b50505050565b60008082840190508381101561240557600080fd5b8091505092915050565b612417612b21565b600060208301905060405180604001604052808451815260200182815250915050919050565b606061244882612830565b61245157600080fd5b600061245c8361287e565b905060608160405190808252806020026020018201604052801561249a57816020015b612487612b3b565b81526020019060019003908161247f5790505b50905060006124ac85602001516128ef565b8560200151019050600080600090505b8481101561250d576124cd83612978565b91506040518060400160405280838152602001848152508482815181106124f057fe5b6020026020010181905250818301925080806001019150506124bc565b5082945050505050919050565b600080826000015111801561253457506021826000015111155b61253d57600080fd5b600061254c83602001516128ef565b9050600081846000015103905060008083866020015101905080519150602083101561257f57826020036101000a820491505b81945050505050919050565b6000601582600001511461259e57600080fd5b6125a78261251a565b9050919050565b6060818301845110156125c057600080fd5b60608215600081146125dd5760405191506020820160405261262e565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561261b57805183526020830192506020810190506125fe565b50868552601f19601f8301166040525050505b50809150509392505050565b6000806000806041855114612655576000935050505061273e565b602085015192506040850151915060ff6041860151169050601b8160ff16101561268057601b810190505b601b8160ff16141580156126985750601c8160ff1614155b156126a9576000935050505061273e565b6000600187838686604051600081526020016040526040516126ce9493929190613731565b6020604051602081039080840390855afa1580156126f0573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561273657600080fd5b809450505050505b92915050565b6060600082600001511161275757600080fd5b600061276683602001516128ef565b905060008184600001510390506060816040519080825280601f01601f1916602001820160405280156127a85781602001600182028038833980820191505090505b50905060008160200190506127c4848760200151018285612a30565b81945050505050919050565b6000808314156127e35760009050612804565b60008284029050828482816127f457fe5b04146127ff57600080fd5b809150505b92915050565b600080821161281857600080fd5b600082848161282357fe5b0490508091505092915050565b600080826000015114156128475760009050612879565b60008083602001519050805160001a915060c060ff168260ff16101561287257600092505050612879565b6001925050505b919050565b6000808260000151141561289557600090506128ea565b600080905060006128a984602001516128ef565b84602001510190506000846000015185602001510190505b808210156128e3576128d282612978565b8201915082806001019350506128c1565b8293505050505b919050565b600080825160001a9050608060ff1681101561290f576000915050612973565b60b860ff16811080612934575060c060ff168110158015612933575060f860ff1681105b5b15612943576001915050612973565b60c060ff168110156129635760018060b80360ff16820301915050612973565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff168110156129995760019150612a26565b60b860ff168110156129b6576001608060ff168203019150612a25565b60c060ff168110156129e65760b78103600185019450806020036101000a85510460018201810193505050612a24565b60f860ff16811015612a0357600160c060ff168203019150612a23565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b6000811415612a3e57612a92565b5b602060ff168110612a6e5782518252602060ff1683019250602060ff1682019150602060ff1681039050612a3f565b6000600182602060ff16036101000a03905080198451168184511681811785525050505b505050565b815481835581811115612ac457600302816003028360005260206000209182019101612ac39190612b55565b5b505050565b60405180606001604052806000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b60405180606001604052806000815260200160008152602001600081525090565b604051806040016040528060008152602001600081525090565b604051806040016040528060008152602001600081525090565b612ba891905b80821115612ba45760008082016000905560018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550600301612b5b565b5090565b90565b600081359050612bba81613b33565b92915050565b600081359050612bcf81613b4a565b92915050565b600081519050612be481613b4a565b92915050565b60008083601f840112612bfc57600080fd5b8235905067ffffffffffffffff811115612c1557600080fd5b602083019150836001820283011115612c2d57600080fd5b9250929050565b600082601f830112612c4557600080fd5b8135612c58612c5382613982565b613955565b91508082526020830160208301858383011115612c7457600080fd5b612c7f838284613add565b50505092915050565b600081359050612c9781613b61565b92915050565b600060208284031215612caf57600080fd5b6000612cbd84828501612bab565b91505092915050565b600060208284031215612cd857600080fd5b6000612ce684828501612bc0565b91505092915050565b600060208284031215612d0157600080fd5b6000612d0f84828501612bd5565b91505092915050565b60008060408385031215612d2b57600080fd5b6000612d3985828601612bc0565b9250506020612d4a85828601612bc0565b9150509250929050565b600080600060608486031215612d6957600080fd5b6000612d7786828701612bc0565b9350506020612d8886828701612bc0565b925050604084013567ffffffffffffffff811115612da557600080fd5b612db186828701612c34565b9150509250925092565b60008060008060808587031215612dd157600080fd5b600085013567ffffffffffffffff811115612deb57600080fd5b612df787828801612c34565b945050602085013567ffffffffffffffff811115612e1457600080fd5b612e2087828801612c34565b935050604085013567ffffffffffffffff811115612e3d57600080fd5b612e4987828801612c34565b925050606085013567ffffffffffffffff811115612e6657600080fd5b612e7287828801612c34565b91505092959194509250565b600060208284031215612e9057600080fd5b6000612e9e84828501612c88565b91505092915050565b60008060408385031215612eba57600080fd5b6000612ec885828601612c88565b9250506020612ed985828601612bab565b9150509250929050565b600080600060608486031215612ef857600080fd5b6000612f0686828701612c88565b9350506020612f1786828701612bc0565b925050604084013567ffffffffffffffff811115612f3457600080fd5b612f4086828701612c34565b9150509250925092565b60008060408385031215612f5d57600080fd5b6000612f6b85828601612c88565b9250506020612f7c85828601612c88565b9150509250929050565b600080600080600080600060a0888a031215612fa157600080fd5b6000612faf8a828b01612c88565b9750506020612fc08a828b01612c88565b9650506040612fd18a828b01612c88565b955050606088013567ffffffffffffffff811115612fee57600080fd5b612ffa8a828b01612bea565b9450945050608088013567ffffffffffffffff81111561301957600080fd5b6130258a828b01612bea565b925092505092959891949750929550565b60006130428383613066565b60208301905092915050565b600061305a83836135bd565b60208301905092915050565b61306f81613a52565b82525050565b61307e81613a52565b82525050565b600061308f826139ce565b6130998185613a09565b93506130a4836139ae565b8060005b838110156130d55781516130bc8882613036565b97506130c7836139ef565b9250506001810190506130a8565b5085935050505092915050565b60006130ed826139d9565b6130f78185613a1a565b9350613102836139be565b8060005b8381101561313357815161311a888261304e565b9750613125836139fc565b925050600181019050613106565b5085935050505092915050565b61314981613a64565b82525050565b61316061315b82613a70565b613b1f565b82525050565b61316f81613a9c565b82525050565b61318661318182613a9c565b613b29565b82525050565b6000613197826139e4565b6131a18185613a2b565b93506131b1818560208601613aec565b80840191505092915050565b60006131ca600483613a47565b91507f766f7465000000000000000000000000000000000000000000000000000000006000830152600482019050919050565b600061320a602d83613a36565b91507f537461727420626c6f636b206d7573742062652067726561746572207468616e60008301527f2063757272656e74207370616e000000000000000000000000000000000000006020830152604082019050919050565b6000613270600f83613a47565b91507f6865696d64616c6c2d50357258776700000000000000000000000000000000006000830152600f82019050919050565b60006132b0601383613a36565b91507f436861696e20494420697320696e76616c6964000000000000000000000000006000830152602082019050919050565b60006132f0600f83613a36565b91507f496e76616c6964207370616e20696400000000000000000000000000000000006000830152602082019050919050565b6000613330601383613a36565b91507f5370616e20616c726561647920657869737473000000000000000000000000006000830152602082019050919050565b6000613370604583613a36565b91507f446966666572656e6365206265747765656e20737461727420616e6420656e6460008301527f20626c6f636b206d75737420626520696e206d756c7469706c6573206f66207360208301527f7072696e740000000000000000000000000000000000000000000000000000006040830152606082019050919050565b60006133fc602a83613a36565b91507f456e6420626c6f636b206d7573742062652067726561746572207468616e207360008301527f7461727420626c6f636b000000000000000000000000000000000000000000006020830152604082019050919050565b6000613462601483613a36565b91507f566f7465207479706520697320696e76616c69640000000000000000000000006000830152602082019050919050565b60006134a2601683613a36565b91507f5472616e73616374696f6e20697320696e76616c6964000000000000000000006000830152602082019050919050565b60006134e2600583613a47565b91507f31353030310000000000000000000000000000000000000000000000000000006000830152600582019050919050565b6000613522602483613a36565b91507f4e6f7420656e6f7567687420706f77657220746f206368616e6765207468652060008301527f7370616e000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60608201600082015161359160008501826135bd565b5060208201516135a460208501826135bd565b5060408201516135b76040850182613066565b50505050565b6135c681613ac6565b82525050565b6135d581613ac6565b82525050565b6135e481613ad0565b82525050565b60006135f6828561314f565b6001820191506136068284613175565b6020820191508190509392505050565b6000613622828661314f565b6001820191506136328285613175565b6020820191506136428284613175565b602082019150819050949350505050565b600061365f828461318c565b915081905092915050565b6000613675826131bd565b9150819050919050565b600061368a82613263565b9150819050919050565b600061369f826134d5565b9150819050919050565b60006020820190506136be6000830184613075565b92915050565b600060408201905081810360008301526136de8185613084565b905081810360208301526136f281846130e2565b90509392505050565b60006020820190506137106000830184613140565b92915050565b600060208201905061372b6000830184613166565b92915050565b60006080820190506137466000830187613166565b61375360208301866135db565b6137606040830185613166565b61376d6060830184613166565b95945050505050565b6000602082019050818103600083015261378f816131fd565b9050919050565b600060208201905081810360008301526137af816132a3565b9050919050565b600060208201905081810360008301526137cf816132e3565b9050919050565b600060208201905081810360008301526137ef81613323565b9050919050565b6000602082019050818103600083015261380f81613363565b9050919050565b6000602082019050818103600083015261382f816133ef565b9050919050565b6000602082019050818103600083015261384f81613455565b9050919050565b6000602082019050818103600083015261386f81613495565b9050919050565b6000602082019050818103600083015261388f81613515565b9050919050565b60006060820190506138ab600083018461357b565b92915050565b60006020820190506138c660008301846135cc565b92915050565b60006060820190506138e160008301866135cc565b6138ee60208301856135cc565b6138fb6040830184613075565b949350505050565b600060608201905061391860008301866135cc565b61392560208301856135cc565b61393260408301846135cc565b949350505050565b600060208201905061394f60008301846135db565b92915050565b6000604051905081810181811067ffffffffffffffff8211171561397857600080fd5b8060405250919050565b600067ffffffffffffffff82111561399957600080fd5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000613a5d82613aa6565b9050919050565b60008115159050919050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b82818337600083830152505050565b60005b83811015613b0a578082015181840152602081019050613aef565b83811115613b19576000848401525b50505050565b6000819050919050565b6000819050919050565b613b3c81613a52565b8114613b4757600080fd5b50565b613b5381613a9c565b8114613b5e57600080fd5b50565b613b6a81613ac6565b8114613b7557600080fd5b5056fea365627a7a7231582041043c020490417f03b23833da19152e2e105982aaa0228db2459085c981a3f16c6578706572696d656e74616cf564736f6c63430005100040" + "code": "0x608060405234801561001057600080fd5b50600436106102115760003560e01c806365b3a1e211610125578063b2472431116100ad578063d0504f891161007c578063d0504f89146106af578063d5b844eb146106cb578063dcf2793a146106e9578063e3b7c9241461071b578063f59cf5651461073957610211565b8063b247243114610612578063b71d7a6914610630578063b7ab4db514610660578063c1b3c9191461067f57610211565b806370ba5707116100f457806370ba57071461055657806398ab2b62146105865780639d11b807146105a4578063ae756451146105d4578063af26aa96146105f257610211565b806365b3a1e2146104c957806366332354146104e8578063687a9bd61461050657806369c49fac1461053857610211565b806335ddfeea116101a85780634b0e4d17116101775780634b0e4d17146104215780634dbc959f1461042b57806355614fcc14610449578063582a8d081461047957806360c8614d146104a957610211565b806335ddfeea1461037357806343ee8213146103a357806344c15cb1146103c157806344d6528f146103f157610211565b806323f2a73f116101e457806323f2a73f146102c55780632de3a180146102f55780632eddf352146103255780633434735f1461035557610211565b8063047a6c5b146102165780630c35b1cb146102485780631270b5741461027957806323c2a2b4146102a9575b600080fd5b610230600480360361022b9190810190612e7e565b61076b565b60405161023f93929190613903565b60405180910390f35b610262600480360361025d9190810190612e7e565b6107c2565b6040516102709291906136c4565b60405180910390f35b610293600480360361028e9190810190612ea7565b61099e565b6040516102a091906136fb565b60405180910390f35b6102c360048036036102be9190810190612f86565b610af6565b005b6102df60048036036102da9190810190612ea7565b611177565b6040516102ec91906136fb565b60405180910390f35b61030f600480360361030a9190810190612d18565b6112cf565b60405161031c9190613716565b60405180910390f35b61033f600480360361033a9190810190612e7e565b611350565b60405161034c91906138b1565b60405180910390f35b61035d611481565b60405161036a91906136a9565b60405180910390f35b61038d60048036036103889190810190612d54565b611499565b60405161039a91906136fb565b60405180910390f35b6103ab611564565b6040516103b89190613716565b60405180910390f35b6103db60048036036103d69190810190612ee3565b61157b565b6040516103e891906138b1565b60405180910390f35b61040b60048036036104069190810190612ea7565b611663565b6040516104189190613896565b60405180910390f35b6104296117cc565b005b610433611828565b60405161044091906138b1565b60405180910390f35b610463600480360361045e9190810190612c9d565b611838565b60405161047091906136fb565b60405180910390f35b610493600480360361048e9190810190612cc6565b611852565b6040516104a09190613716565b60405180910390f35b6104b16118d0565b6040516104c093929190613903565b60405180910390f35b6104d1611944565b6040516104df9291906136c4565b60405180910390f35b6104f0611a34565b6040516104fd91906138b1565b60405180910390f35b610520600480360361051b9190810190612f4a565b611a39565b60405161052f939291906138cc565b60405180910390f35b610540611a9d565b60405161054d91906136fb565b60405180910390f35b610570600480360361056b9190810190612c9d565b611ab4565b60405161057d91906136fb565b60405180910390f35b61058e611ace565b60405161059b9190613716565b60405180910390f35b6105be60048036036105b99190810190612e7e565b611ae5565b6040516105cb91906138b1565b60405180910390f35b6105dc611c16565b6040516105e99190613716565b60405180910390f35b6105fa611c2d565b60405161060993929190613903565b60405180910390f35b61061a611c8e565b60405161062791906138b1565b60405180910390f35b61064a60048036036106459190810190612e7e565b611c94565b60405161065791906138b1565b60405180910390f35b610668611d94565b6040516106769291906136c4565b60405180910390f35b61069960048036036106949190810190612e7e565b611da8565b6040516106a691906138b1565b60405180910390f35b6106c960048036036106c49190810190612dbb565b611dc9565b005b6106d361201f565b6040516106e0919061393a565b60405180910390f35b61070360048036036106fe9190810190612f4a565b612024565b604051610712939291906138cc565b60405180910390f35b610723612088565b60405161073091906138b1565b60405180910390f35b610753600480360361074e9190810190612e7e565b61209a565b60405161076293929190613903565b60405180910390f35b60008060006004600085815260200190815260200160002060000154600460008681526020019081526020016000206001015460046000878152602001908152602001600020600201549250925092509193909250565b606080600883116107de576107d5611944565b91509150610999565b60006107e984611c94565b9050606060036000838152602001908152602001600020805490506040519080825280602002602001820160405280156108325781602001602082028038833980820191505090505b5090506060600360008481526020019081526020016000208054905060405190808252806020026020018201604052801561087c5781602001602082028038833980820191505090505b50905060008090505b600360008581526020019081526020016000208054905081101561098e576003600085815260200190815260200160002081815481106108c157fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168382815181106108ff57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060036000858152602001908152602001600020818154811061095757fe5b90600052602060002090600302016001015482828151811061097557fe5b6020026020010181815250508080600101915050610885565b508181945094505050505b915091565b6000606060036000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015610a71578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050815260200190600101906109d5565b50505050905060008090505b8151811015610ae9578373ffffffffffffffffffffffffffffffffffffffff16828281518110610aa957fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff161415610adc57600192505050610af0565b8080600101915050610a7d565b5060009150505b92915050565b73fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b4257600080fd5b6000610b4c611828565b90506000811415610b6057610b5f6120c4565b5b610b746001826123f090919063ffffffff16565b8814610bb5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bac906137b6565b60405180910390fd5b868611610bf7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bee90613816565b60405180910390fd5b6000805460018989030181610c0857fe5b0614610c49576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c40906137f6565b60405180910390fd5b8660046000838152602001908152602001600020600101541115610ca2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c9990613776565b60405180910390fd5b6000600460008a81526020019081526020016000206000015414610cfb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cf2906137d6565b60405180910390fd5b604051806060016040528089815260200188815260200187815250600460008a815260200190815260200160002060008201518160000155602082015181600101556040820151816002015590505060058890806001815401808255809150509060018203906000526020600020016000909192909190915055506000600260008a815260200190815260200160002081610d969190612a97565b506000600360008a815260200190815260200160002081610db79190612a97565b506060610e0f610e0a87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061240f565b61243d565b905060008090505b8151811015610f83576060610e3e838381518110610e3157fe5b602002602001015161243d565b9050600260008c81526020019081526020016000208054809190600101610e659190612a97565b506040518060600160405280610e8e83600081518110610e8157fe5b602002602001015161251a565b8152602001610eb083600181518110610ea357fe5b602002602001015161251a565b8152602001610ed283600281518110610ec557fe5b602002602001015161258b565b73ffffffffffffffffffffffffffffffffffffffff16815250600260008d81526020019081526020016000208381548110610f0957fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050508080600101915050610e17565b506060610fdb610fd686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061240f565b61243d565b905060008090505b815181101561114f57606061100a838381518110610ffd57fe5b602002602001015161243d565b9050600360008d815260200190815260200160002080548091906001016110319190612a97565b50604051806060016040528061105a8360008151811061104d57fe5b602002602001015161251a565b815260200161107c8360018151811061106f57fe5b602002602001015161251a565b815260200161109e8360028151811061109157fe5b602002602001015161258b565b73ffffffffffffffffffffffffffffffffffffffff16815250600360008e815260200190815260200160002083815481106110d557fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050508080600101915050610fe3565b506000600160006101000a81548160ff02191690831515021790555050505050505050505050565b6000606060026000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561124a578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050815260200190600101906111ae565b50505050905060008090505b81518110156112c2578373ffffffffffffffffffffffffffffffffffffffff1682828151811061128257fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff1614156112b5576001925050506112c9565b8080600101915050611256565b5060009150505b92915050565b60006002600160f81b84846040516020016112ec93929190613616565b6040516020818303038152906040526040516113089190613653565b602060405180830381855afa158015611325573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506113489190810190612cef565b905092915050565b6000606060026000848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015611423578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611387565b505050509050600080905060008090505b82518110156114765761146783828151811061144c57fe5b602002602001015160200151836123f090919063ffffffff16565b91508080600101915050611434565b508092505050919050565b73fffffffffffffffffffffffffffffffffffffffe81565b60008060008085905060006021808751816114b057fe5b0402905060008111156114c9576114c687611852565b91505b6000602190505b818111611553576000600182038801519050818801519550806000602081106114f557fe5b1a60f81b9450600060f81b857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561153a5761153386856112cf565b9350611547565b61154484876112cf565b93505b506021810190506114d0565b508782149450505050509392505050565b6040516115709061367f565b604051809103902081565b60008060009050600080905060008090505b84518167ffffffffffffffff1610156116565760606115b8868367ffffffffffffffff1660416125ae565b905060006115cf828961263a90919063ffffffff16565b90506115d9612ac9565b6115e38a83611663565b90506115ef8a83611177565b801561162657508473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16115b15611648578194506116458160200151876123f090919063ffffffff16565b95505b50505060418101905061158d565b5081925050509392505050565b61166b612ac9565b606060026000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561173c578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050815260200190600101906116a0565b50505050905060008090505b81518110156117c4578373ffffffffffffffffffffffffffffffffffffffff1682828151811061177457fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff1614156117b7578181815181106117a857fe5b602002602001015192506117c4565b8080600101915050611748565b505092915050565b60006117d6611828565b90506117e28133611177565b6117eb57600080fd5b60001515600160009054906101000a900460ff1615151461180b57600080fd5b60018060006101000a81548160ff02191690831515021790555050565b600061183343611c94565b905090565b600061184b611845611828565b83611177565b9050919050565b60006002600060f81b8360405160200161186d9291906135ea565b6040516020818303038152906040526040516118899190613653565b602060405180830381855afa1580156118a6573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506118c99190810190612cef565b9050919050565b6000806000806118f160016118e3611828565b6123f090919063ffffffff16565b905060046000828152602001908152602001600020600001546004600083815260200190815260200160002060010154600460008481526020019081526020016000206002015493509350935050909192565b606080606060016040519080825280602002602001820160405280156119795781602001602082028038833980820191505090505b5090507371562b71999873db5b286df957af199ec94617f78160008151811061199e57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060606001604051908082528060200260200182016040528015611a0a5781602001602082028038833980820191505090505b509050600a81600081518110611a1c57fe5b60200260200101818152505081819350935050509091565b600881565b60036020528160005260406000208181548110611a5257fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b6000600160009054906101000a900460ff16905090565b6000611ac7611ac1611828565b8361099e565b9050919050565b604051611ada9061366a565b604051809103902081565b6000606060036000848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015611bb8578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611b1c565b505050509050600080905060008090505b8251811015611c0b57611bfc838281518110611be157fe5b602002602001015160200151836123f090919063ffffffff16565b91508080600101915050611bc9565b508092505050919050565b604051611c2290613694565b604051809103902081565b600080600080611c3b611828565b905060046000828152602001908152602001600020600001546004600083815260200190815260200160002060010154600460008481526020019081526020016000206002015493509350935050909192565b60005481565b60008060058054905090505b6000811115611d5457611cb1612b00565b6004600060056001850381548110611cc557fe5b906000526020600020015481526020019081526020016000206040518060600160405290816000820154815260200160018201548152602001600282015481525050905083816020015111158015611d2257506000816040015114155b8015611d32575080604001518411155b15611d4557806000015192505050611d8f565b50808060019003915050611ca0565b5060006005805490501115611d8a57600560016005805490500381548110611d7857fe5b90600052602060002001549050611d8f565b600090505b919050565b606080611da0436107c2565b915091509091565b60058181548110611db557fe5b906000526020600020016000915090505481565b6060611ddc611dd78661240f565b61243d565b9050604051611dea9061367f565b6040518091039020611e0f82600081518110611e0257fe5b6020026020010151612744565b8051906020012014611e56576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e4d90613796565b60405180910390fd5b600260ff16611e7882600181518110611e6b57fe5b602002602001015161251a565b14611eb8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eaf90613836565b60405180910390fd5b611f31611ed882600481518110611ecb57fe5b602002602001015161251a565b60001b600285604051611eeb9190613653565b602060405180830381855afa158015611f08573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250611f2b9190810190612cef565b84611499565b611f70576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6790613856565b60405180910390fd5b6000611f7a611828565b90506000611f908288805190602001208861157b565b9050611fd46001611fc66003611fb86002611faa88611350565b6127d090919063ffffffff16565b61280a90919063ffffffff16565b6123f090919063ffffffff16565b811015612016576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161200d90613876565b60405180910390fd5b50505050505050565b600281565b6002602052816000526040600020818154811061203d57fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b60006040438161209457fe5b04905090565b60046020528060005260406000206000915090508060000154908060010154908060020154905083565b60406000819055506060806120d7611944565b809250819350505060008090506040518060600160405280828152602001600081526020016008815250600460008381526020019081526020016000206000820151816000015560208201518160010155604082015181600201559050506005819080600181540180825580915050906001820390600052602060002001600090919290919091505550600060026000838152602001908152602001600020816121819190612a97565b50600060036000838152602001908152602001600020816121a29190612a97565b5060008090505b83518110156122c6576002600083815260200190815260200160002080548091906001016121d79190612a97565b5060405180606001604052808281526020018483815181106121f557fe5b6020026020010151815260200185838151811061220e57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681525060026000848152602001908152602001600020828154811061224d57fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505080806001019150506121a9565b5060008090505b83518110156123ea576003600083815260200190815260200160002080548091906001016122fb9190612a97565b50604051806060016040528082815260200184838151811061231957fe5b6020026020010151815260200185838151811061233257fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681525060036000848152602001908152602001600020828154811061237157fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505080806001019150506122cd565b50505050565b60008082840190508381101561240557600080fd5b8091505092915050565b612417612b21565b600060208301905060405180604001604052808451815260200182815250915050919050565b606061244882612830565b61245157600080fd5b600061245c8361287e565b905060608160405190808252806020026020018201604052801561249a57816020015b612487612b3b565b81526020019060019003908161247f5790505b50905060006124ac85602001516128ef565b8560200151019050600080600090505b8481101561250d576124cd83612978565b91506040518060400160405280838152602001848152508482815181106124f057fe5b6020026020010181905250818301925080806001019150506124bc565b5082945050505050919050565b600080826000015111801561253457506021826000015111155b61253d57600080fd5b600061254c83602001516128ef565b9050600081846000015103905060008083866020015101905080519150602083101561257f57826020036101000a820491505b81945050505050919050565b6000601582600001511461259e57600080fd5b6125a78261251a565b9050919050565b6060818301845110156125c057600080fd5b60608215600081146125dd5760405191506020820160405261262e565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561261b57805183526020830192506020810190506125fe565b50868552601f19601f8301166040525050505b50809150509392505050565b6000806000806041855114612655576000935050505061273e565b602085015192506040850151915060ff6041860151169050601b8160ff16101561268057601b810190505b601b8160ff16141580156126985750601c8160ff1614155b156126a9576000935050505061273e565b6000600187838686604051600081526020016040526040516126ce9493929190613731565b6020604051602081039080840390855afa1580156126f0573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561273657600080fd5b809450505050505b92915050565b6060600082600001511161275757600080fd5b600061276683602001516128ef565b905060008184600001510390506060816040519080825280601f01601f1916602001820160405280156127a85781602001600182028038833980820191505090505b50905060008160200190506127c4848760200151018285612a30565b81945050505050919050565b6000808314156127e35760009050612804565b60008284029050828482816127f457fe5b04146127ff57600080fd5b809150505b92915050565b600080821161281857600080fd5b600082848161282357fe5b0490508091505092915050565b600080826000015114156128475760009050612879565b60008083602001519050805160001a915060c060ff168260ff16101561287257600092505050612879565b6001925050505b919050565b6000808260000151141561289557600090506128ea565b600080905060006128a984602001516128ef565b84602001510190506000846000015185602001510190505b808210156128e3576128d282612978565b8201915082806001019350506128c1565b8293505050505b919050565b600080825160001a9050608060ff1681101561290f576000915050612973565b60b860ff16811080612934575060c060ff168110158015612933575060f860ff1681105b5b15612943576001915050612973565b60c060ff168110156129635760018060b80360ff16820301915050612973565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff168110156129995760019150612a26565b60b860ff168110156129b6576001608060ff168203019150612a25565b60c060ff168110156129e65760b78103600185019450806020036101000a85510460018201810193505050612a24565b60f860ff16811015612a0357600160c060ff168203019150612a23565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b6000811415612a3e57612a92565b5b602060ff168110612a6e5782518252602060ff1683019250602060ff1682019150602060ff1681039050612a3f565b6000600182602060ff16036101000a03905080198451168184511681811785525050505b505050565b815481835581811115612ac457600302816003028360005260206000209182019101612ac39190612b55565b5b505050565b60405180606001604052806000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b60405180606001604052806000815260200160008152602001600081525090565b604051806040016040528060008152602001600081525090565b604051806040016040528060008152602001600081525090565b612ba891905b80821115612ba45760008082016000905560018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550600301612b5b565b5090565b90565b600081359050612bba81613b33565b92915050565b600081359050612bcf81613b4a565b92915050565b600081519050612be481613b4a565b92915050565b60008083601f840112612bfc57600080fd5b8235905067ffffffffffffffff811115612c1557600080fd5b602083019150836001820283011115612c2d57600080fd5b9250929050565b600082601f830112612c4557600080fd5b8135612c58612c5382613982565b613955565b91508082526020830160208301858383011115612c7457600080fd5b612c7f838284613add565b50505092915050565b600081359050612c9781613b61565b92915050565b600060208284031215612caf57600080fd5b6000612cbd84828501612bab565b91505092915050565b600060208284031215612cd857600080fd5b6000612ce684828501612bc0565b91505092915050565b600060208284031215612d0157600080fd5b6000612d0f84828501612bd5565b91505092915050565b60008060408385031215612d2b57600080fd5b6000612d3985828601612bc0565b9250506020612d4a85828601612bc0565b9150509250929050565b600080600060608486031215612d6957600080fd5b6000612d7786828701612bc0565b9350506020612d8886828701612bc0565b925050604084013567ffffffffffffffff811115612da557600080fd5b612db186828701612c34565b9150509250925092565b60008060008060808587031215612dd157600080fd5b600085013567ffffffffffffffff811115612deb57600080fd5b612df787828801612c34565b945050602085013567ffffffffffffffff811115612e1457600080fd5b612e2087828801612c34565b935050604085013567ffffffffffffffff811115612e3d57600080fd5b612e4987828801612c34565b925050606085013567ffffffffffffffff811115612e6657600080fd5b612e7287828801612c34565b91505092959194509250565b600060208284031215612e9057600080fd5b6000612e9e84828501612c88565b91505092915050565b60008060408385031215612eba57600080fd5b6000612ec885828601612c88565b9250506020612ed985828601612bab565b9150509250929050565b600080600060608486031215612ef857600080fd5b6000612f0686828701612c88565b9350506020612f1786828701612bc0565b925050604084013567ffffffffffffffff811115612f3457600080fd5b612f4086828701612c34565b9150509250925092565b60008060408385031215612f5d57600080fd5b6000612f6b85828601612c88565b9250506020612f7c85828601612c88565b9150509250929050565b600080600080600080600060a0888a031215612fa157600080fd5b6000612faf8a828b01612c88565b9750506020612fc08a828b01612c88565b9650506040612fd18a828b01612c88565b955050606088013567ffffffffffffffff811115612fee57600080fd5b612ffa8a828b01612bea565b9450945050608088013567ffffffffffffffff81111561301957600080fd5b6130258a828b01612bea565b925092505092959891949750929550565b60006130428383613066565b60208301905092915050565b600061305a83836135bd565b60208301905092915050565b61306f81613a52565b82525050565b61307e81613a52565b82525050565b600061308f826139ce565b6130998185613a09565b93506130a4836139ae565b8060005b838110156130d55781516130bc8882613036565b97506130c7836139ef565b9250506001810190506130a8565b5085935050505092915050565b60006130ed826139d9565b6130f78185613a1a565b9350613102836139be565b8060005b8381101561313357815161311a888261304e565b9750613125836139fc565b925050600181019050613106565b5085935050505092915050565b61314981613a64565b82525050565b61316061315b82613a70565b613b1f565b82525050565b61316f81613a9c565b82525050565b61318661318182613a9c565b613b29565b82525050565b6000613197826139e4565b6131a18185613a2b565b93506131b1818560208601613aec565b80840191505092915050565b60006131ca600483613a47565b91507f766f7465000000000000000000000000000000000000000000000000000000006000830152600482019050919050565b600061320a602d83613a36565b91507f537461727420626c6f636b206d7573742062652067726561746572207468616e60008301527f2063757272656e74207370616e000000000000000000000000000000000000006020830152604082019050919050565b6000613270601383613a36565b91507f436861696e20494420697320696e76616c6964000000000000000000000000006000830152602082019050919050565b60006132b0600f83613a36565b91507f496e76616c6964207370616e20696400000000000000000000000000000000006000830152602082019050919050565b60006132f0601383613a36565b91507f5370616e20616c726561647920657869737473000000000000000000000000006000830152602082019050919050565b6000613330604583613a36565b91507f446966666572656e6365206265747765656e20737461727420616e6420656e6460008301527f20626c6f636b206d75737420626520696e206d756c7469706c6573206f66207360208301527f7072696e740000000000000000000000000000000000000000000000000000006040830152606082019050919050565b60006133bc602a83613a36565b91507f456e6420626c6f636b206d7573742062652067726561746572207468616e207360008301527f7461727420626c6f636b000000000000000000000000000000000000000000006020830152604082019050919050565b6000613422601483613a36565b91507f566f7465207479706520697320696e76616c69640000000000000000000000006000830152602082019050919050565b6000613462601683613a36565b91507f5472616e73616374696f6e20697320696e76616c6964000000000000000000006000830152602082019050919050565b60006134a2600e83613a47565b91507f6865696d64616c6c2d31353030310000000000000000000000000000000000006000830152600e82019050919050565b60006134e2600583613a47565b91507f31353030310000000000000000000000000000000000000000000000000000006000830152600582019050919050565b6000613522602483613a36565b91507f4e6f7420656e6f7567687420706f77657220746f206368616e6765207468652060008301527f7370616e000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60608201600082015161359160008501826135bd565b5060208201516135a460208501826135bd565b5060408201516135b76040850182613066565b50505050565b6135c681613ac6565b82525050565b6135d581613ac6565b82525050565b6135e481613ad0565b82525050565b60006135f6828561314f565b6001820191506136068284613175565b6020820191508190509392505050565b6000613622828661314f565b6001820191506136328285613175565b6020820191506136428284613175565b602082019150819050949350505050565b600061365f828461318c565b915081905092915050565b6000613675826131bd565b9150819050919050565b600061368a82613495565b9150819050919050565b600061369f826134d5565b9150819050919050565b60006020820190506136be6000830184613075565b92915050565b600060408201905081810360008301526136de8185613084565b905081810360208301526136f281846130e2565b90509392505050565b60006020820190506137106000830184613140565b92915050565b600060208201905061372b6000830184613166565b92915050565b60006080820190506137466000830187613166565b61375360208301866135db565b6137606040830185613166565b61376d6060830184613166565b95945050505050565b6000602082019050818103600083015261378f816131fd565b9050919050565b600060208201905081810360008301526137af81613263565b9050919050565b600060208201905081810360008301526137cf816132a3565b9050919050565b600060208201905081810360008301526137ef816132e3565b9050919050565b6000602082019050818103600083015261380f81613323565b9050919050565b6000602082019050818103600083015261382f816133af565b9050919050565b6000602082019050818103600083015261384f81613415565b9050919050565b6000602082019050818103600083015261386f81613455565b9050919050565b6000602082019050818103600083015261388f81613515565b9050919050565b60006060820190506138ab600083018461357b565b92915050565b60006020820190506138c660008301846135cc565b92915050565b60006060820190506138e160008301866135cc565b6138ee60208301856135cc565b6138fb6040830184613075565b949350505050565b600060608201905061391860008301866135cc565b61392560208301856135cc565b61393260408301846135cc565b949350505050565b600060208201905061394f60008301846135db565b92915050565b6000604051905081810181811067ffffffffffffffff8211171561397857600080fd5b8060405250919050565b600067ffffffffffffffff82111561399957600080fd5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000613a5d82613aa6565b9050919050565b60008115159050919050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b82818337600083830152505050565b60005b83811015613b0a578082015181840152602081019050613aef565b83811115613b19576000848401525b50505050565b6000819050919050565b6000819050919050565b613b3c81613a52565b8114613b4757600080fd5b50565b613b5381613a9c565b8114613b5e57600080fd5b50565b613b6a81613ac6565b8114613b7557600080fd5b5056fea365627a7a72315820974ebeb3f99a1975cbb5176c18039d5281de5c0dd7622c82358480b017dede8d6c6578706572696d656e74616cf564736f6c63430005100040" }, "0000000000000000000000000000000000001001": { "balance": "0x0", - "code": "0x" + "code": "0x608060405234801561001057600080fd5b506004361061009e5760003560e01c8063d0504f8911610066578063d0504f8914610255578063d79e60b7146104d5578063ede01f17146104f7578063f552102214610525578063facd743b146105815761009e565b8063017a9105146100a3578063080356b7146100e957806321ec23b6146101625780633434735f146101c15780639426e2261461020b575b600080fd5b6100cf600480360360208110156100b957600080fd5b81019080803590602001909291905050506105dd565b604051808215151515815260200191505060405180910390f35b610160600480360360208110156100ff57600080fd5b810190808035906020019064010000000081111561011c57600080fd5b82018360208201111561012e57600080fd5b8035906020019184600183028401116401000000008311171561015057600080fd5b90919293919293905050506105fd565b005b61016a610a21565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156101ad578082015181840152602081019050610192565b505050509050019250505060405180910390f35b6101c9610ad2565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610213610aea565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6104d36004803603608081101561026b57600080fd5b810190808035906020019064010000000081111561028857600080fd5b82018360208201111561029a57600080fd5b803590602001918460018302840111640100000000831117156102bc57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561031f57600080fd5b82018360208201111561033157600080fd5b8035906020019184600183028401116401000000008311171561035357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156103b657600080fd5b8201836020820111156103c857600080fd5b803590602001918460018302840111640100000000831117156103ea57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561044d57600080fd5b82018360208201111561045f57600080fd5b8035906020019184600183028401116401000000008311171561048157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610af0565b005b6104dd610d0f565b604051808215151515815260200191505060405180910390f35b6105236004803603602081101561050d57600080fd5b8101908080359060200190929190505050610d47565b005b6105676004803603602081101561053b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610ef1565b604051808215151515815260200191505060405180910390f35b6105c36004803603602081101561059757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610fb4565b604051808215151515815260200191505060405180910390f35b60036020528060005260406000206000915054906101000a900460ff1681565b73fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461064957600080fd5b60606106a061069b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611077565b6110a5565b905060006106c1826000815181106106b457fe5b6020026020010151611182565b905060006106e2836001815181106106d557fe5b60200260200101516111f3565b90506060610703846002815181106106f657fe5b6020026020010151611216565b9050600115156107146000856112a2565b151514610789576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f496e76616c69642070726f706f7365642073746174652069640000000000000081525060200191505060405180910390fd5b600015156003600085815260200190815260200160002060009054906101000a900460ff16151514610823576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f53746174652077617320616c72656164792070726f636573736564000000000081525060200191505060405180910390fd5b60016003600085815260200190815260200160002060006101000a81548160ff02191690831515021790555061085a6000846112c7565b5061086482611385565b15610a19578173ffffffffffffffffffffffffffffffffffffffff1683826040516024018083815260200180602001828103825283818151815260200191508051906020019080838360005b838110156108cb5780820151818401526020810190506108b0565b50505050905090810190601f1680156108f85780820380516001836020036101000a031916815260200191505b5093505050506040516020818303038152906040527f26c53bea000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b602083106109ae578051825260208201915060208101905060208303925061098b565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610a10576040519150601f19603f3d011682016040523d82523d6000602084013e610a15565b606091505b5050505b505050505050565b606060008090506060600060020154604051908082528060200260200182016040528015610a5e5781602001602082028038833980820191505090505b5090506000610a6d600061139e565b90505b610a7b6000826113d1565b15610ac957600080610a8e6000846113e5565b809250819350505081848681518110610aa357fe5b6020026020010181815250506001850194505050610ac260008261143a565b9050610a70565b50809250505090565b73fffffffffffffffffffffffffffffffffffffffe81565b61100081565b61100073ffffffffffffffffffffffffffffffffffffffff1663d0504f89858585856040518563ffffffff1660e01b81526004018080602001806020018060200180602001858103855289818151815260200191508051906020019080838360005b83811015610b6d578082015181840152602081019050610b52565b50505050905090810190601f168015610b9a5780820380516001836020036101000a031916815260200191505b50858103845288818151815260200191508051906020019080838360005b83811015610bd3578082015181840152602081019050610bb8565b50505050905090810190601f168015610c005780820380516001836020036101000a031916815260200191505b50858103835287818151815260200191508051906020019080838360005b83811015610c39578082015181840152602081019050610c1e565b50505050905090810190601f168015610c665780820380516001836020036101000a031916815260200191505b50858103825286818151815260200191508051906020019080838360005b83811015610c9f578082015181840152602081019050610c84565b50505050905090810190601f168015610ccc5780820380516001836020036101000a031916815260200191505b5098505050505050505050600060405180830381600087803b158015610cf157600080fd5b505af1158015610d05573d6000803e3d6000fd5b5050505050505050565b600061100073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b610d5033610fb4565b610dc2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f496e76616c69642076616c696461746f7200000000000000000000000000000081525060200191505060405180910390fd5b60001515610dd16000836112a2565b151514610e46576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f537461746520616c72656164792070726f706f7365640000000000000000000081525060200191505060405180910390fd5b600015156003600083815260200190815260200160002060009054906101000a900460ff16151514610ee0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f537461746520616c726561647920636f6d6d697474656400000000000000000081525060200191505060405180910390fd5b610eed60008260016114a0565b5050565b600061100073ffffffffffffffffffffffffffffffffffffffff166370ba5707836040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015610f7257600080fd5b505afa158015610f86573d6000803e3d6000fd5b505050506040513d6020811015610f9c57600080fd5b81019080805190602001909291905050509050919050565b600061100073ffffffffffffffffffffffffffffffffffffffff166355614fcc836040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561103557600080fd5b505afa158015611049573d6000803e3d6000fd5b505050506040513d602081101561105f57600080fd5b81019080805190602001909291905050509050919050565b61107f6117e6565b600060208301905060405180604001604052808451815260200182815250915050919050565b60606110b08261157f565b6110b957600080fd5b60006110c4836115cd565b905060608160405190808252806020026020018201604052801561110257816020015b6110ef611800565b8152602001906001900390816110e75790505b5090506000611114856020015161163e565b8560200151019050600080600090505b8481101561117557611135836116c7565b915060405180604001604052808381526020018481525084828151811061115857fe5b602002602001018190525081830192508080600101915050611124565b5082945050505050919050565b600080826000015111801561119c57506021826000015111155b6111a557600080fd5b60006111b4836020015161163e565b905060008184600001510390506000808386602001510190508051915060208310156111e757826020036101000a820491505b81945050505050919050565b6000601582600001511461120657600080fd5b61120f82611182565b9050919050565b6060600082600001511161122957600080fd5b6000611238836020015161163e565b905060008184600001510390506060816040519080825280601f01601f19166020018201604052801561127a5781602001600182028038833980820191505090505b509050600081602001905061129684876020015101828561177f565b81945050505050919050565b6000808360000160008481526020019081526020016000206000015411905092915050565b60008083600001600084815260200190815260200160002060000154905060008114156112f857600091505061137f565b8360000160008481526020019081526020016000206000808201600090556001820160006101000a81549060ff02191690555050600184600101600183038154811061134057fe5b906000526020600020906002020160010160006101000a81548160ff021916908315150217905550836002016000815480929190600190039190505550505b92915050565b600080823b905060008163ffffffff1611915050919050565b60006113ca827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61143a565b9050919050565b600082600101805490508210905092915050565b6000808360010183815481106113f757fe5b906000526020600020906002020160000154915083600001600083815260200190815260200160002060010160009054906101000a900460ff1690509250929050565b600081806001019250505b826001018054905082108015611485575082600101828154811061146557fe5b906000526020600020906002020160010160009054906101000a900460ff165b15611497578180600101925050611445565b81905092915050565b6000808460000160008581526020019081526020016000206000015490508285600001600086815260200190815260200160002060010160006101000a81548160ff0219169083151502179055506000811115611501576001915050611578565b846001018054809190600101611517919061181a565b905060018101856000016000868152602001908152602001600020600001819055508385600101828154811061154957fe5b906000526020600020906002020160000181905550846002016000815480929190600101919050555060009150505b9392505050565b6000808260000151141561159657600090506115c8565b60008083602001519050805160001a915060c060ff168260ff1610156115c1576000925050506115c8565b6001925050505b919050565b600080826000015114156115e45760009050611639565b600080905060006115f8846020015161163e565b84602001510190506000846000015185602001510190505b8082101561163257611621826116c7565b820191508280600101935050611610565b8293505050505b919050565b600080825160001a9050608060ff1681101561165e5760009150506116c2565b60b860ff16811080611683575060c060ff168110158015611682575060f860ff1681105b5b156116925760019150506116c2565b60c060ff168110156116b25760018060b80360ff168203019150506116c2565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff168110156116e85760019150611775565b60b860ff16811015611705576001608060ff168203019150611774565b60c060ff168110156117355760b78103600185019450806020036101000a85510460018201810193505050611773565b60f860ff1681101561175257600160c060ff168203019150611772565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b600081141561178d576117e1565b5b602060ff1681106117bd5782518252602060ff1683019250602060ff1682019150602060ff168103905061178e565b6000600182602060ff16036101000a03905080198451168184511681811785525050505b505050565b604051806040016040528060008152602001600081525090565b604051806040016040528060008152602001600081525090565b81548183558181111561184757600202816002028360005260206000209182019101611846919061184c565b5b505050565b61188491905b80821115611880576000808201600090556001820160006101000a81549060ff021916905550600201611852565b5090565b9056fea265627a7a723158207ab014ef9c036daf74874e7574845504838ad6772ad1e6e62607a4791965d6a964736f6c63430005100032" }, "0000000000000000000000000000000000001010": { "balance": "0x204fce28085b549b31600000", - "code": "0x" + "code": "0x60806040526004361061019c5760003560e01c806377d32e94116100ec578063acd06cb31161008a578063e306f77911610064578063e306f77914610a7b578063e614d0d614610aa6578063f2fde38b14610ad1578063fc0c546a14610b225761019c565b8063acd06cb31461097a578063b789543c146109cd578063cc79f97b14610a505761019c565b80639025e64c116100c65780639025e64c146107c957806395d89b4114610859578063a9059cbb146108e9578063abceeba21461094f5761019c565b806377d32e94146106315780638da5cb5b146107435780638f32d59b1461079a5761019c565b806347e7ef24116101595780637019d41a116101335780637019d41a1461053357806370a082311461058a578063715018a6146105ef578063771282f6146106065761019c565b806347e7ef2414610410578063485cc9551461046b57806360f96a8f146104dc5761019c565b806306fdde03146101a15780631499c5921461023157806318160ddd1461028257806319d27d9c146102ad5780632e1a7d4d146103b1578063313ce567146103df575b600080fd5b3480156101ad57600080fd5b506101b6610b79565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101f65780820151818401526020810190506101db565b50505050905090810190601f1680156102235780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561023d57600080fd5b506102806004803603602081101561025457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610bb6565b005b34801561028e57600080fd5b50610297610c24565b6040518082815260200191505060405180910390f35b3480156102b957600080fd5b5061036f600480360360a08110156102d057600080fd5b81019080803590602001906401000000008111156102ed57600080fd5b8201836020820111156102ff57600080fd5b8035906020019184600183028401116401000000008311171561032157600080fd5b9091929391929390803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610c3a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103dd600480360360208110156103c757600080fd5b8101908080359060200190929190505050610e06565b005b3480156103eb57600080fd5b506103f4610f58565b604051808260ff1660ff16815260200191505060405180910390f35b34801561041c57600080fd5b506104696004803603604081101561043357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610f61565b005b34801561047757600080fd5b506104da6004803603604081101561048e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061111d565b005b3480156104e857600080fd5b506104f16111ec565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561053f57600080fd5b50610548611212565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561059657600080fd5b506105d9600480360360208110156105ad57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611238565b6040518082815260200191505060405180910390f35b3480156105fb57600080fd5b50610604611259565b005b34801561061257600080fd5b5061061b611329565b6040518082815260200191505060405180910390f35b34801561063d57600080fd5b506107016004803603604081101561065457600080fd5b81019080803590602001909291908035906020019064010000000081111561067b57600080fd5b82018360208201111561068d57600080fd5b803590602001918460018302840111640100000000831117156106af57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061132f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561074f57600080fd5b506107586114b4565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156107a657600080fd5b506107af6114dd565b604051808215151515815260200191505060405180910390f35b3480156107d557600080fd5b506107de611534565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561081e578082015181840152602081019050610803565b50505050905090810190601f16801561084b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561086557600080fd5b5061086e61156d565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156108ae578082015181840152602081019050610893565b50505050905090810190601f1680156108db5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610935600480360360408110156108ff57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506115aa565b604051808215151515815260200191505060405180910390f35b34801561095b57600080fd5b506109646115d0565b6040518082815260200191505060405180910390f35b34801561098657600080fd5b506109b36004803603602081101561099d57600080fd5b810190808035906020019092919050505061165d565b604051808215151515815260200191505060405180910390f35b3480156109d957600080fd5b50610a3a600480360360808110156109f057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001909291908035906020019092919050505061167d565b6040518082815260200191505060405180910390f35b348015610a5c57600080fd5b50610a6561169d565b6040518082815260200191505060405180910390f35b348015610a8757600080fd5b50610a906116a3565b6040518082815260200191505060405180910390f35b348015610ab257600080fd5b50610abb6116a9565b6040518082815260200191505060405180910390f35b348015610add57600080fd5b50610b2060048036036020811015610af457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611736565b005b348015610b2e57600080fd5b50610b37611753565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60606040518060400160405280600b81526020017f4d6174696320546f6b656e000000000000000000000000000000000000000000815250905090565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f44697361626c656420666561747572650000000000000000000000000000000081525060200191505060405180910390fd5b6000601260ff16600a0a6402540be40002905090565b6000808511610c4857600080fd5b6000831480610c575750824311155b610cc9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5369676e6174757265206973206578706972656400000000000000000000000081525060200191505060405180910390fd5b6000610cd73387878761167d565b9050600015156005600083815260200190815260200160002060009054906101000a900460ff16151514610d73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f536967206465616374697661746564000000000000000000000000000000000081525060200191505060405180910390fd5b60016005600083815260200190815260200160002060006101000a81548160ff021916908315150217905550610ded8189898080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061132f565b9150610dfa828488611779565b50509695505050505050565b60003390506000610e1682611238565b9050610e2d83600654611b3690919063ffffffff16565b600681905550600083118015610e4257508234145b610eb4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f496e73756666696369656e7420616d6f756e740000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167febff2602b3f468259e1e99f613fed6691f3a6526effe6ef3e768ba7ae7a36c4f8584610f3087611238565b60405180848152602001838152602001828152602001935050505060405180910390a3505050565b60006012905090565b610f696114dd565b610f7257600080fd5b600081118015610faf5750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b611004576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611e626023913960400191505060405180910390fd5b600061100f83611238565b905060008390508073ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f1935050505015801561105c573d6000803e3d6000fd5b5061107283600654611b5690919063ffffffff16565b6006819055508373ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f4e2ca0515ed1aef1395f66b5303bb5d6f1bf9d61a353fa53f73f8ac9973fa9f685856110f489611238565b60405180848152602001838152602001828152602001935050505060405180910390a350505050565b600760009054906101000a900460ff1615611183576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611e3f6023913960400191505060405180910390fd5b6001600760006101000a81548160ff02191690831515021790555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506111e882611b75565b5050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b6112616114dd565b61126a57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60065481565b600080600080604185511461134a57600093505050506114ae565b602085015192506040850151915060ff6041860151169050601b8160ff16101561137557601b810190505b601b8160ff161415801561138d5750601c8160ff1614155b1561139e57600093505050506114ae565b60018682858560405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156113fb573d6000803e3d6000fd5b505050602060405103519350600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156114aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4572726f7220696e2065637265636f766572000000000000000000000000000081525060200191505060405180910390fd5b5050505b92915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b6040518060400160405280600281526020017f3a9900000000000000000000000000000000000000000000000000000000000081525081565b60606040518060400160405280600581526020017f4d41544943000000000000000000000000000000000000000000000000000000815250905090565b60008134146115bc57600090506115ca565b6115c7338484611779565b90505b92915050565b6040518060800160405280605b8152602001611ed7605b91396040516020018082805190602001908083835b6020831061161f57805182526020820191506020810190506020830392506115fc565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b60056020528060005260406000206000915054906101000a900460ff1681565b600061169361168e86868686611c6d565b611d43565b9050949350505050565b613a9981565b60015481565b604051806080016040528060528152602001611e85605291396040516020018082805190602001908083835b602083106116f857805182526020820191506020810190506020830392506116d5565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b61173e6114dd565b61174757600080fd5b61175081611b75565b50565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000803073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156117f957600080fd5b505afa15801561180d573d6000803e3d6000fd5b505050506040513d602081101561182357600080fd5b8101908080519060200190929190505050905060003073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156118b557600080fd5b505afa1580156118c9573d6000803e3d6000fd5b505050506040513d60208110156118df57600080fd5b810190808051906020019092919050505090506118fd868686611d8d565b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fe6497e3ee548a3372136af2fcb0696db31fc6cf20260707645068bd3fe97f3c48786863073ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611a0557600080fd5b505afa158015611a19573d6000803e3d6000fd5b505050506040513d6020811015611a2f57600080fd5b81019080805190602001909291905050503073ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611abd57600080fd5b505afa158015611ad1573d6000803e3d6000fd5b505050506040513d6020811015611ae757600080fd5b8101908080519060200190929190505050604051808681526020018581526020018481526020018381526020018281526020019550505050505060405180910390a46001925050509392505050565b600082821115611b4557600080fd5b600082840390508091505092915050565b600080828401905083811015611b6b57600080fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611baf57600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000806040518060800160405280605b8152602001611ed7605b91396040516020018082805190602001908083835b60208310611cbf5780518252602082019150602081019050602083039250611c9c565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120905060405181815273ffffffffffffffffffffffffffffffffffffffff8716602082015285604082015284606082015283608082015260a0812092505081915050949350505050565b60008060015490506040517f190100000000000000000000000000000000000000000000000000000000000081528160028201528360228201526042812092505081915050919050565b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611dd3573d6000803e3d6000fd5b508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a350505056fe54686520636f6e747261637420697320616c726561647920696e697469616c697a6564496e73756666696369656e7420616d6f756e74206f7220696e76616c69642075736572454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429546f6b656e5472616e736665724f726465722861646472657373207370656e6465722c75696e7432353620746f6b656e49644f72416d6f756e742c6279746573333220646174612c75696e743235362065787069726174696f6e29a265627a7a723158204d7efcb673053866d78e69673fa7583d77880fd0f002e7e8c82d7c2f0e571d6764736f6c63430005100032" }, "71562b71999873DB5b286dF957af199Ec94617F7": { "balance": "0x3635c9adc5dea00000" diff --git a/consensus/bor/bor_test/helper.go b/consensus/bor/bor_test/helper.go index 48735a7c5f..f812599dc9 100644 --- a/consensus/bor/bor_test/helper.go +++ b/consensus/bor/bor_test/helper.go @@ -5,8 +5,10 @@ import ( "encoding/json" "io/ioutil" "math/big" + "sort" "testing" + "github.com/maticnetwork/bor/common" "github.com/maticnetwork/bor/consensus/bor" "github.com/maticnetwork/bor/core" "github.com/maticnetwork/bor/core/state" @@ -20,10 +22,14 @@ import ( ) var ( - extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal - privKey = "b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291" - key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - addr = crypto.PubkeyToAddress(key.PublicKey) // 0x71562b71999873DB5b286dF957af199Ec94617F7 + // The genesis for tests was generated with following parameters + extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal + privKey = "b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291" + key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + addr = crypto.PubkeyToAddress(key.PublicKey) // 0x71562b71999873DB5b286dF957af199Ec94617F7 + validatorHeaderBytesLength = common.AddressLength + 20 // address + power + sprintSize uint64 = 4 + spanSize uint64 = 8 ) type initializeData struct { @@ -82,7 +88,7 @@ func buildEthereumInstance(t *testing.T, db ethdb.Database) *initializeData { } } -func insertNewBlock(t *testing.T, _bor *bor.Bor, chain *core.BlockChain, header *types.Header, statedb *state.StateDB, privKey []byte) { +func insertNewBlock(t *testing.T, _bor *bor.Bor, chain *core.BlockChain, header *types.Header, statedb *state.StateDB, privKey []byte) *types.Block { _, err := _bor.FinalizeAndAssemble(chain, header, statedb, nil, nil, nil) if err != nil { t.Fatalf("%s", err) @@ -98,6 +104,7 @@ func insertNewBlock(t *testing.T, _bor *bor.Bor, chain *core.BlockChain, header if _, err := chain.InsertChain([]*types.Block{block}); err != nil { t.Fatalf("%s", err) } + return block } func buildMinimalNextHeader(t *testing.T, block *types.Block, borConfig *params.BorConfig) *types.Header { @@ -105,15 +112,25 @@ func buildMinimalNextHeader(t *testing.T, block *types.Block, borConfig *params. header.Number.Add(header.Number, big.NewInt(1)) header.ParentHash = block.Hash() header.Time += bor.CalcProducerDelay(header.Number.Uint64(), borConfig.Period, borConfig.Sprint, borConfig.ProducerDelay) - isSprintEnd := (header.Number.Uint64()+1)%borConfig.Sprint == 0 + header.Extra = make([]byte, 32+65) // vanity + extraSeal + + currentValidators := []*bor.Validator{bor.NewValidator(addr, 10)} + isSpanEnd := (header.Number.Uint64()+1)%spanSize == 0 + isSprintEnd := (header.Number.Uint64()+1)%sprintSize == 0 + if isSpanEnd { + _, heimdallSpan := loadSpanFromFile(t) + currentValidators = heimdallSpan.ValidatorSet.Validators + } else if header.Number.Uint64()%spanSize == 0 { + header.Difficulty = new(big.Int).SetInt64(5) + } if isSprintEnd { - header.Extra = make([]byte, 32+40+65) // vanity + validatorBytes + extraSeal - // the genesis file was initialized with a validator 0x71562b71999873db5b286df957af199ec94617f7 with power 10 - // So, if you change ./genesis.json, do change the following as well - validatorBytes, _ := hex.DecodeString("71562b71999873db5b286df957af199ec94617f7000000000000000000000000000000000000000a") - copy(header.Extra[32:72], validatorBytes) - } else { - header.Extra = make([]byte, 32+65) // vanity + extraSeal + sort.Sort(bor.ValidatorsByAddress(currentValidators)) + validatorBytes := make([]byte, len(currentValidators)*validatorHeaderBytesLength) + header.Extra = make([]byte, 32+len(validatorBytes)+65) // vanity + validatorBytes + extraSeal + for i, val := range currentValidators { + copy(validatorBytes[i*validatorHeaderBytesLength:], val.HeaderBytes()) + } + copy(header.Extra[32:], validatorBytes) } _key, _ := hex.DecodeString(privKey) sig, err := secp256k1.Sign(crypto.Keccak256(bor.BorRLP(header)), _key) diff --git a/consensus/bor/bor_test/span.json b/consensus/bor/bor_test/span.json index f4be94eeb8..1f2679523a 100644 --- a/consensus/bor/bor_test/span.json +++ b/consensus/bor/bor_test/span.json @@ -47,7 +47,7 @@ "endEpoch": 0, "power": 10000, "pubKey": "0x0469536ae98030a7e83ec5ef3baffed2d05a32e31d978e58486f6bdb0fbbf240293838325116090190c0639db03f9cbd8b9aecfd269d016f46e3a2287fbf9ad232", - "signer": "0x1c4f0f054a0d6a1415382dc0fd83c6535188b220", + "signer": "0x71562b71999873DB5b286dF957af199Ec94617F7", "last_updated": 0, "accum": 10000 }], diff --git a/consensus/bor/errors.go b/consensus/bor/errors.go index 8b09bdfe9f..b058adc7f4 100644 --- a/consensus/bor/errors.go +++ b/consensus/bor/errors.go @@ -79,3 +79,20 @@ func (e *SealingInFlightError) Error() string { e.Number, ) } + +// MismatchingValidatorsError is returned if a last block in sprint contains a +// list of validators different from the one that local node calculated +type MismatchingValidatorsError struct { + Number uint64 + ValidatorSetSnap []byte + ValidatorSetHeader []byte +} + +func (e *MismatchingValidatorsError) Error() string { + return fmt.Sprintf( + "Mismatching validators at block %d\nValidatorBytes from snapshot: %x\nValidatorBytes in Header: %x\n", + e.Number, + e.ValidatorSetSnap, + e.ValidatorSetHeader, + ) +} From 9f6df9ade0c8d4362a5ade422c2ab4587165711d Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Wed, 13 May 2020 20:11:13 +0530 Subject: [PATCH 18/46] dev: Remove concurrent seal check --- consensus/bor/bor.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 700bc879e9..204c560eba 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -728,9 +728,9 @@ func (c *Bor) Authorize(signer common.Address, signFn SignerFn) { // Seal implements consensus.Engine, attempting to create a sealed block using // the local signing credentials. func (c *Bor) Seal(chain consensus.ChainReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error { - if c.activeSealingOp != nil { - return &SealingInFlightError{c.activeSealingOp.number} - } + // if c.activeSealingOp != nil { + // return &SealingInFlightError{c.activeSealingOp.number} + // } header := block.Header() // Sealing the genesis block is not supported From f76491d53b8cd5923215fe7ffd69b194a1437cfe Mon Sep 17 00:00:00 2001 From: Jaynti Kanani Date: Thu, 14 May 2020 12:03:33 +0530 Subject: [PATCH 19/46] new: add new flags for bor service file --- .github/workflows/linuxpackage.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/linuxpackage.yml b/.github/workflows/linuxpackage.yml index 71c2ff477e..938a1968f2 100644 --- a/.github/workflows/linuxpackage.yml +++ b/.github/workflows/linuxpackage.yml @@ -3,7 +3,7 @@ name: Linux package on: push: tags: - - 'v*.*.*' + - "v*.*.*" jobs: build: runs-on: ubuntu-latest @@ -30,7 +30,7 @@ jobs: sudo apt-get -yqq install libpq-dev build-essential gem install --no-document fpm fpm --version - + make bor cat > bor.service <<- "EOF" @@ -40,7 +40,7 @@ jobs: WorkingDirectory=/etc/bor/ EnvironmentFile=/etc/bor/metadata ExecStartPre=/bin/mkdir -p /var/log/matic-logs/ - ExecStart=/bin/bash -c "/usr/bin/bor --datadir /etc/bor/dataDir --port '30303' --rpc --rpcaddr '0.0.0.0' --rpcvhosts '*' --rpccorsdomain '*' --rpcport '8545' --ipcpath /etc/bor/geth.ipc --rpcapi 'bor,db,eth,net,web3,txpool' --networkid ${NETWORK_ID} --gasprice '0' --keystore /etc/bor/dataDir/keystore --unlock ${VALIDATOR_ADDRESS} --password /etc/bor/dataDir/password.txt --allow-insecure-unlock --maxpeers 150 --mine > /var/log/matic-logs/bor.log 2>&1" + ExecStart=/bin/bash -c "/usr/bin/bor --datadir /etc/bor/dataDir --port '30303' --rpc --rpcaddr '0.0.0.0' --rpcvhosts '*' --rpccorsdomain '*' --rpcport '8545' --ipcpath /etc/bor/geth.ipc --rpcapi 'bor,db,eth,net,web3,txpool,bor' --networkid ${NETWORK_ID} --miner.gasprice '1000000000' --miner.gaslimit '24000000' --txpool.nolocals --txpool.accountslots '128' --txpool.globalslots '16384' --txpool.accountqueue '128' --txpool.globalqueue '20000' --txpool.lifetime '0h16m0s' --keystore /etc/bor/dataDir/keystore --unlock ${VALIDATOR_ADDRESS} --password /etc/bor/dataDir/password.txt --allow-insecure-unlock --maxpeers 150 --mine > /var/log/matic-logs/bor.log 2>&1" Type=simple User=root EOF @@ -60,7 +60,7 @@ jobs: bor.service=/etc/systemd/system/ \ build/bin/bor=/usr/bin/ \ metadata=/etc/bor/ - + mkdir packages-v${{ env.RELEASE_VERSION }} mv matic-bor_${{ env.RELEASE_VERSION }}_amd64.deb packages-v${{ env.RELEASE_VERSION }}/ @@ -75,14 +75,14 @@ jobs: AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - AWS_REGION: 'us-east-1' # optional: defaults to us-east-1 - SOURCE_DIR: 'packages-v${{ env.RELEASE_VERSION }}' - DEST_DIR: 'v${{ env.RELEASE_VERSION }}' + AWS_REGION: "us-east-1" # optional: defaults to us-east-1 + SOURCE_DIR: "packages-v${{ env.RELEASE_VERSION }}" + DEST_DIR: "v${{ env.RELEASE_VERSION }}" - name: Slack Notification uses: rtCamp/action-slack-notify@v2.0.0 env: SLACK_CHANNEL: code-releases SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} - SLACK_TITLE: 'New linux package for Bor v${{ env.RELEASE_VERSION }} just got released' - SLACK_MESSAGE: 'Package has been uploaded to S3 bucket for public use and available at https://matic-public.s3.amazonaws.com/v${{ env.RELEASE_VERSION }}/matic-bor_${{ env.RELEASE_VERSION }}_amd64.deb' + SLACK_TITLE: "New linux package for Bor v${{ env.RELEASE_VERSION }} just got released" + SLACK_MESSAGE: "Package has been uploaded to S3 bucket for public use and available at https://matic-public.s3.amazonaws.com/v${{ env.RELEASE_VERSION }}/matic-bor_${{ env.RELEASE_VERSION }}_amd64.deb" From a2983189a947f3efa4275b5bcb453e4ca8787bca Mon Sep 17 00:00:00 2001 From: Jaynti Kanani Date: Thu, 14 May 2020 13:10:39 +0530 Subject: [PATCH 20/46] chg: change tx pool params and gaslimit --- .github/workflows/linuxpackage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linuxpackage.yml b/.github/workflows/linuxpackage.yml index 938a1968f2..306cf00ffb 100644 --- a/.github/workflows/linuxpackage.yml +++ b/.github/workflows/linuxpackage.yml @@ -40,7 +40,7 @@ jobs: WorkingDirectory=/etc/bor/ EnvironmentFile=/etc/bor/metadata ExecStartPre=/bin/mkdir -p /var/log/matic-logs/ - ExecStart=/bin/bash -c "/usr/bin/bor --datadir /etc/bor/dataDir --port '30303' --rpc --rpcaddr '0.0.0.0' --rpcvhosts '*' --rpccorsdomain '*' --rpcport '8545' --ipcpath /etc/bor/geth.ipc --rpcapi 'bor,db,eth,net,web3,txpool,bor' --networkid ${NETWORK_ID} --miner.gasprice '1000000000' --miner.gaslimit '24000000' --txpool.nolocals --txpool.accountslots '128' --txpool.globalslots '16384' --txpool.accountqueue '128' --txpool.globalqueue '20000' --txpool.lifetime '0h16m0s' --keystore /etc/bor/dataDir/keystore --unlock ${VALIDATOR_ADDRESS} --password /etc/bor/dataDir/password.txt --allow-insecure-unlock --maxpeers 150 --mine > /var/log/matic-logs/bor.log 2>&1" + ExecStart=/bin/bash -c "/usr/bin/bor --datadir /etc/bor/dataDir --port '30303' --rpc --rpcaddr '0.0.0.0' --rpcvhosts '*' --rpccorsdomain '*' --rpcport '8545' --ipcpath /etc/bor/geth.ipc --rpcapi 'bor,db,eth,net,web3,txpool,bor' --networkid ${NETWORK_ID} --miner.gaslimit '2000000000' --txpool.nolocals --txpool.accountslots '128' --txpool.globalslots '20000' --txpool.lifetime '0h16m0s' --keystore /etc/bor/dataDir/keystore --unlock ${VALIDATOR_ADDRESS} --password /etc/bor/dataDir/password.txt --allow-insecure-unlock --maxpeers 150 --mine > /var/log/matic-logs/bor.log 2>&1" Type=simple User=root EOF From c27b8b78012f64723e730b6e98b3eb1298a41543 Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Thu, 14 May 2020 12:19:47 +0530 Subject: [PATCH 21/46] new: Add wiggle to block time --- cmd/puppeth/wizard_genesis.go | 1 + consensus/bor/bor.go | 49 +++++++++++++++++------------ consensus/bor/bor_test/bor_test.go | 11 +++---- consensus/bor/bor_test/genesis.json | 1 + consensus/bor/bor_test/helper.go | 2 +- consensus/bor/errors.go | 13 ++++++++ params/config.go | 1 + 7 files changed, 51 insertions(+), 27 deletions(-) diff --git a/cmd/puppeth/wizard_genesis.go b/cmd/puppeth/wizard_genesis.go index 695005f090..e431c17dd5 100644 --- a/cmd/puppeth/wizard_genesis.go +++ b/cmd/puppeth/wizard_genesis.go @@ -111,6 +111,7 @@ func (w *wizard) makeGenesis() { Period: 1, ProducerDelay: 5, Sprint: 60, + BackupMultiplier: 1, ValidatorContract: "0x0000000000000000000000000000000000001000", StateReceiverContract: "0x0000000000000000000000000000000000001001", } diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 204c560eba..3151e6e549 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -207,14 +207,18 @@ func CalcDifficulty(snap *Snapshot, signer common.Address, sprint uint64) *big.I return big.NewInt(0).SetUint64(snap.inturn(snap.Number+1, signer, sprint)) } -// CalcProducerDelay is the block delay algorithm based on block time and period / producerDelay values in genesis -func CalcProducerDelay(number uint64, period uint64, sprint uint64, producerDelay uint64) uint64 { +// CalcProducerDelay is the block delay algorithm based on block time, period, producerDelay and turn-ness of a signer +func CalcProducerDelay(number uint64, succession int, c *params.BorConfig) uint64 { // When the block is the first block of the sprint, it is expected to be delayed by `producerDelay`. // That is to allow time for block propagation in the last sprint - if number%sprint == 0 { - return producerDelay + delay := c.Period + if number%c.Sprint == 0 { + delay = c.ProducerDelay } - return period + if succession > 0 { + delay += uint64(succession) * c.BackupMultiplier + } + return delay } // BorRLP returns the rlp bytes which needs to be signed for the bor @@ -334,17 +338,6 @@ func (c *Bor) verifyHeader(chain consensus.ChainReader, header *types.Header, pa } number := header.Number.Uint64() - var parent *types.Header - if len(parents) > 0 { // if parents is nil, len(parents) is zero - parent = parents[len(parents)-1] - } else if number > 0 { - parent = chain.GetHeader(header.ParentHash, number-1) - } - - if parent != nil && header.Time < parent.Time+CalcProducerDelay(number, c.config.Period, c.config.Sprint, c.config.ProducerDelay) { - return consensus.ErrBlockTooSoon - } - // Don't waste time checking blocks from the future if header.Time > uint64(time.Now().Unix()) { return consensus.ErrFutureBlock @@ -590,10 +583,22 @@ func (c *Bor) verifySeal(chain consensus.ChainReader, header *types.Header, pare return errUnauthorizedSigner } - if _, err = snap.GetSignerSuccessionNumber(signer); err != nil { + succession, err := snap.GetSignerSuccessionNumber(signer) + if err != nil { return err } + var parent *types.Header + if len(parents) > 0 { // if parents is nil, len(parents) is zero + parent = parents[len(parents)-1] + } else if number > 0 { + parent = chain.GetHeader(header.ParentHash, number-1) + } + + if parent != nil && header.Time < parent.Time+CalcProducerDelay(number, succession, c.config) { + return &BlockTooSoonError{number, succession} + } + // Ensure that the difficulty corresponds to the turn-ness of the signer if !c.fakeDiff { difficulty := snap.inturn(header.Number.Uint64(), signer, c.config.Sprint) @@ -654,7 +659,11 @@ func (c *Bor) Prepare(chain consensus.ChainReader, header *types.Header) error { return consensus.ErrUnknownAncestor } - header.Time = parent.Time + CalcProducerDelay(number, c.config.Period, c.config.Sprint, c.config.ProducerDelay) + succession, err := snap.GetSignerSuccessionNumber(c.signer) + if err != nil { + return err + } + header.Time = parent.Time + CalcProducerDelay(number, succession, c.config) if header.Time < uint64(time.Now().Unix()) { header.Time = uint64(time.Now().Unix()) } @@ -765,8 +774,8 @@ func (c *Bor) Seal(chain consensus.ChainReader, block *types.Block, results chan // Sweet, the protocol permits us to sign the block, wait for our time delay := time.Unix(int64(header.Time), 0).Sub(time.Now()) // nolint: gosimple - wiggle := time.Duration(2*c.config.Period) * time.Second * time.Duration(successionNumber) - delay += wiggle + // wiggle was already accounted for in header.Time, this is just for logging + wiggle := time.Duration(successionNumber) * time.Duration(c.config.BackupMultiplier) * time.Second // Sign all the things! sighash, err := signFn(accounts.Account{Address: signer}, accounts.MimetypeBor, BorRLP(header)) diff --git a/consensus/bor/bor_test/bor_test.go b/consensus/bor/bor_test/bor_test.go index b7cf4659bd..f478175b28 100644 --- a/consensus/bor/bor_test/bor_test.go +++ b/consensus/bor/bor_test/bor_test.go @@ -24,11 +24,7 @@ func TestCommitSpan(t *testing.T) { // Mock HeimdallClient.FetchWithRetry to return span data from span.json res, heimdallSpan := loadSpanFromFile(t) h := &mocks.IHeimdallClient{} - // FetchWithRetry is invoked 3 times - // 1. bor.FinalizeAndAssemble to prepare a new block when calling insertNewBlock - // 2. bor.Finalize via(bc.insertChain => bc.processor.Process) - // 3. bor.FinalizeAndAssemble via worker.commit - h.On("FetchWithRetry", "bor", "span", "1").Return(res, nil).Times(3) + h.On("FetchWithRetry", "bor", "span", "1").Return(res, nil) _bor.SetHeimdallClient(h) db := init.ethereum.ChainDb() @@ -45,7 +41,10 @@ func TestCommitSpan(t *testing.T) { block = insertNewBlock(t, _bor, chain, header, statedb, _key) } - assert.True(t, h.AssertNumberOfCalls(t, "FetchWithRetry", 3)) + // FetchWithRetry is invoked 2 times + // 1. bor.FinalizeAndAssemble to prepare a new block when calling insertNewBlock + // 2. bor.Finalize via(bc.insertChain => bc.processor.Process) + assert.True(t, h.AssertNumberOfCalls(t, "FetchWithRetry", 2)) validators, err := _bor.GetCurrentValidators(sprintSize, 256) // new span starts at 256 if err != nil { t.Fatalf("%s", err) diff --git a/consensus/bor/bor_test/genesis.json b/consensus/bor/bor_test/genesis.json index 5525732b9d..5113190b18 100644 --- a/consensus/bor/bor_test/genesis.json +++ b/consensus/bor/bor_test/genesis.json @@ -11,6 +11,7 @@ "bor": { "period": 1, "producerDelay": 4, + "backupMultiplier": 1, "sprint": 4, "validatorContract": "0x0000000000000000000000000000000000001000", "stateReceiverContract": "0x0000000000000000000000000000000000001001" diff --git a/consensus/bor/bor_test/helper.go b/consensus/bor/bor_test/helper.go index f812599dc9..2a050eff8e 100644 --- a/consensus/bor/bor_test/helper.go +++ b/consensus/bor/bor_test/helper.go @@ -111,7 +111,7 @@ func buildMinimalNextHeader(t *testing.T, block *types.Block, borConfig *params. header := block.Header() header.Number.Add(header.Number, big.NewInt(1)) header.ParentHash = block.Hash() - header.Time += bor.CalcProducerDelay(header.Number.Uint64(), borConfig.Period, borConfig.Sprint, borConfig.ProducerDelay) + header.Time += bor.CalcProducerDelay(header.Number.Uint64(), 0, borConfig) header.Extra = make([]byte, 32+65) // vanity + extraSeal currentValidators := []*bor.Validator{bor.NewValidator(addr, 10)} diff --git a/consensus/bor/errors.go b/consensus/bor/errors.go index b058adc7f4..7e7ee17915 100644 --- a/consensus/bor/errors.go +++ b/consensus/bor/errors.go @@ -96,3 +96,16 @@ func (e *MismatchingValidatorsError) Error() string { e.ValidatorSetHeader, ) } + +type BlockTooSoonError struct { + Number uint64 + Succession int +} + +func (e *BlockTooSoonError) Error() string { + return fmt.Sprintf( + "Block %d was created too soon. Signer turn-ness number is %d\n", + e.Number, + e.Succession, + ) +} diff --git a/params/config.go b/params/config.go index e56336fe2d..3af6bb064b 100644 --- a/params/config.go +++ b/params/config.go @@ -319,6 +319,7 @@ type BorConfig struct { Period uint64 `json:"period"` // Number of seconds between blocks to enforce ProducerDelay uint64 `json:"producerDelay"` // Number of seconds delay between two producer interval Sprint uint64 `json:"sprint"` // Epoch length to proposer + BackupMultiplier uint64 `json:"backupMultiplier"` // Backup multiplier to determine the wiggle time ValidatorContract string `json:"validatorContract"` // Validator set contract StateReceiverContract string `json:"stateReceiverContract"` // State receiver contract } From 71c3bf757c154b021a6b067a88e95cef96d99044 Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Thu, 14 May 2020 14:48:02 +0530 Subject: [PATCH 22/46] refactor: Tests + add test for OutOfTurnSign --- consensus/bor/bor.go | 37 ++++++-------- consensus/bor/bor_test/bor_test.go | 77 +++++++++++++++++++++------- consensus/bor/bor_test/helper.go | 80 ++++++++++++++++++++---------- consensus/bor/bor_test/span.json | 54 +++++--------------- consensus/bor/errors.go | 35 ++++++++++++- consensus/bor/snapshot.go | 6 +-- 6 files changed, 176 insertions(+), 113 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 3151e6e549..7ee2f52be1 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -114,10 +114,6 @@ var ( // errInvalidDifficulty is returned if the difficulty of a block neither 1 or 2. errInvalidDifficulty = errors.New("invalid difficulty") - // errWrongDifficulty is returned if the difficulty of a block doesn't match the - // turn of the signer. - errWrongDifficulty = errors.New("wrong difficulty") - // ErrInvalidTimestamp is returned if the timestamp of a block is lower than // the previous block's timestamp + the minimum block period. ErrInvalidTimestamp = errors.New("invalid timestamp") @@ -126,9 +122,6 @@ var ( // be modified via out-of-range or non-contiguous headers. errOutOfRangeChain = errors.New("out of range or non-contiguous chain") - // errUnauthorizedSigner is returned if a header is signed by a non-authorized entity. - errUnauthorizedSigner = errors.New("unauthorized signer") - // errRecentlySigned is returned if a header is signed by an authorized entity // that already signed a header recently, thus is temporarily not allowed to. errRecentlySigned = errors.New("recently signed") @@ -200,13 +193,6 @@ func encodeSigHeader(w io.Writer, header *types.Header) { } } -// CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty -// that a new block should have based on the previous blocks in the chain and the -// current signer. -func CalcDifficulty(snap *Snapshot, signer common.Address, sprint uint64) *big.Int { - return big.NewInt(0).SetUint64(snap.inturn(snap.Number+1, signer, sprint)) -} - // CalcProducerDelay is the block delay algorithm based on block time, period, producerDelay and turn-ness of a signer func CalcProducerDelay(number uint64, succession int, c *params.BorConfig) uint64 { // When the block is the first block of the sprint, it is expected to be delayed by `producerDelay`. @@ -580,7 +566,7 @@ func (c *Bor) verifySeal(chain consensus.ChainReader, header *types.Header, pare return err } if !snap.ValidatorSet.HasAddress(signer.Bytes()) { - return errUnauthorizedSigner + return &UnauthorizedSignerError{number, signer.Bytes()} } succession, err := snap.GetSignerSuccessionNumber(signer) @@ -601,9 +587,9 @@ func (c *Bor) verifySeal(chain consensus.ChainReader, header *types.Header, pare // Ensure that the difficulty corresponds to the turn-ness of the signer if !c.fakeDiff { - difficulty := snap.inturn(header.Number.Uint64(), signer, c.config.Sprint) + difficulty := snap.Difficulty(signer) if header.Difficulty.Uint64() != difficulty { - return errWrongDifficulty + return &WrongDifficultyError{number, difficulty, header.Difficulty.Uint64(), signer.Bytes()} } } @@ -625,7 +611,7 @@ func (c *Bor) Prepare(chain consensus.ChainReader, header *types.Header) error { } // Set the correct difficulty - header.Difficulty = CalcDifficulty(snap, c.signer, c.config.Sprint) + header.Difficulty = new(big.Int).SetUint64(snap.Difficulty(c.signer)) // Ensure the extra data has all it's components if len(header.Extra) < extraVanity { @@ -659,10 +645,15 @@ func (c *Bor) Prepare(chain consensus.ChainReader, header *types.Header) error { return consensus.ErrUnknownAncestor } - succession, err := snap.GetSignerSuccessionNumber(c.signer) - if err != nil { - return err + var succession int + // if signer is not empty + if bytes.Compare(c.signer.Bytes(), common.Address{}.Bytes()) != 0 { + succession, err = snap.GetSignerSuccessionNumber(c.signer) + if err != nil { + return err + } } + header.Time = parent.Time + CalcProducerDelay(number, succession, c.config) if header.Time < uint64(time.Now().Unix()) { header.Time = uint64(time.Now().Unix()) @@ -764,7 +755,7 @@ func (c *Bor) Seal(chain consensus.ChainReader, block *types.Block, results chan // Bail out if we're unauthorized to sign a block if !snap.ValidatorSet.HasAddress(signer.Bytes()) { - return errUnauthorizedSigner + return &UnauthorizedSignerError{number, signer.Bytes()} } successionNumber, err := snap.GetSignerSuccessionNumber(signer) @@ -852,7 +843,7 @@ func (c *Bor) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *t if err != nil { return nil } - return CalcDifficulty(snap, c.signer, c.config.Sprint) + return new(big.Int).SetUint64(snap.Difficulty(c.signer)) } // SealHash returns the hash of a block prior to it being sealed. diff --git a/consensus/bor/bor_test/bor_test.go b/consensus/bor/bor_test/bor_test.go index f478175b28..62d929220a 100644 --- a/consensus/bor/bor_test/bor_test.go +++ b/consensus/bor/bor_test/bor_test.go @@ -8,6 +8,7 @@ import ( "github.com/maticnetwork/bor/common" "github.com/maticnetwork/bor/consensus/bor" "github.com/maticnetwork/bor/core/rawdb" + "github.com/maticnetwork/bor/crypto" "github.com/stretchr/testify/assert" "github.com/maticnetwork/bor/core/types" @@ -28,23 +29,17 @@ func TestCommitSpan(t *testing.T) { _bor.SetHeimdallClient(h) db := init.ethereum.ChainDb() - statedb, err := chain.State() - if err != nil { - t.Fatalf("%s", err) - } - _key, _ := hex.DecodeString(privKey) - block := init.genesis.ToBlock(db) // Insert sprintSize # of blocks so that span is fetched at the start of a new sprint for i := uint64(1); i <= sprintSize; i++ { - header := buildMinimalNextHeader(t, block, init.genesis.Config.Bor) - block = insertNewBlock(t, _bor, chain, header, statedb, _key) + block = buildNextBlock(t, _bor, chain, block, nil, init.genesis.Config.Bor) + insertNewBlock(t, chain, block) } // FetchWithRetry is invoked 2 times - // 1. bor.FinalizeAndAssemble to prepare a new block when calling insertNewBlock + // 1. bor.FinalizeAndAssemble to prepare a new block when calling buildNextBlock // 2. bor.Finalize via(bc.insertChain => bc.processor.Process) - assert.True(t, h.AssertNumberOfCalls(t, "FetchWithRetry", 2)) + assert.True(t, h.AssertCalled(t, "FetchWithRetry", "bor", "span", "1")) validators, err := _bor.GetCurrentValidators(sprintSize, 256) // new span starts at 256 if err != nil { t.Fatalf("%s", err) @@ -88,16 +83,11 @@ func TestIsValidatorAction(t *testing.T) { _bor.SetHeimdallClient(h) db := init.ethereum.ChainDb() - statedb, err := chain.State() - if err != nil { - t.Fatalf("%s", err) - } - _key, _ := hex.DecodeString(privKey) - block := init.genesis.ToBlock(db) + for i := uint64(1); i <= spanSize; i++ { - header := buildMinimalNextHeader(t, block, init.genesis.Config.Bor) - block = insertNewBlock(t, _bor, chain, header, statedb, _key) + block = buildNextBlock(t, _bor, chain, block, nil, init.genesis.Config.Bor) + insertNewBlock(t, chain, block) } for _, validator := range heimdallSpan.SelectedProducers { @@ -119,3 +109,54 @@ func TestIsValidatorAction(t *testing.T) { assert.True(t, _bor.IsValidatorAction(chain, _addr, tx)) } } + +func TestOutOfTurnSigning(t *testing.T) { + init := buildEthereumInstance(t, rawdb.NewMemoryDatabase()) + chain := init.ethereum.BlockChain() + engine := init.ethereum.Engine() + _bor := engine.(*bor.Bor) + + res, _ := loadSpanFromFile(t) + h := &mocks.IHeimdallClient{} + h.On("FetchWithRetry", "bor", "span", "1").Return(res, nil) + _bor.SetHeimdallClient(h) + + db := init.ethereum.ChainDb() + block := init.genesis.ToBlock(db) + + for i := uint64(1); i < spanSize; i++ { + block = buildNextBlock(t, _bor, chain, block, nil, init.genesis.Config.Bor) + insertNewBlock(t, chain, block) + } + + // insert spanSize-th block + // This account is one the out-of-turn validators for 1st (0-indexed) span + signer := "c8deb0bea5c41afe8e37b4d1bd84e31adff11b09c8c96ff4b605003cce067cd9" + signerKey, _ := hex.DecodeString(signer) + key, _ = crypto.HexToECDSA(signer) + addr = crypto.PubkeyToAddress(key.PublicKey) + expectedSuccessionNumber := 2 + + block = buildNextBlock(t, _bor, chain, block, signerKey, init.genesis.Config.Bor) + _, err := chain.InsertChain([]*types.Block{block}) + assert.Equal(t, + *err.(*bor.BlockTooSoonError), + bor.BlockTooSoonError{Number: spanSize, Succession: expectedSuccessionNumber}) + + expectedDifficulty := uint64(3 - expectedSuccessionNumber) // len(validators) - succession + header := block.Header() + header.Time += (bor.CalcProducerDelay(header.Number.Uint64(), expectedSuccessionNumber, init.genesis.Config.Bor) - + bor.CalcProducerDelay(header.Number.Uint64(), 0, init.genesis.Config.Bor)) + sign(t, header, signerKey) + block = types.NewBlockWithHeader(header) + _, err = chain.InsertChain([]*types.Block{block}) + assert.Equal(t, + *err.(*bor.WrongDifficultyError), + bor.WrongDifficultyError{Number: spanSize, Expected: expectedDifficulty, Actual: 3, Signer: addr.Bytes()}) + + header.Difficulty = new(big.Int).SetUint64(expectedDifficulty) + sign(t, header, signerKey) + block = types.NewBlockWithHeader(header) + _, err = chain.InsertChain([]*types.Block{block}) + assert.Nil(t, err) +} diff --git a/consensus/bor/bor_test/helper.go b/consensus/bor/bor_test/helper.go index 2a050eff8e..b59c3731fc 100644 --- a/consensus/bor/bor_test/helper.go +++ b/consensus/bor/bor_test/helper.go @@ -11,7 +11,6 @@ import ( "github.com/maticnetwork/bor/common" "github.com/maticnetwork/bor/consensus/bor" "github.com/maticnetwork/bor/core" - "github.com/maticnetwork/bor/core/state" "github.com/maticnetwork/bor/core/types" "github.com/maticnetwork/bor/crypto" "github.com/maticnetwork/bor/crypto/secp256k1" @@ -23,11 +22,19 @@ import ( var ( // The genesis for tests was generated with following parameters - extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal - privKey = "b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291" - key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - addr = crypto.PubkeyToAddress(key.PublicKey) // 0x71562b71999873DB5b286dF957af199Ec94617F7 - validatorHeaderBytesLength = common.AddressLength + 20 // address + power + extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal + + // Only this account is a validator for the 0th span + privKey = "b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291" + key, _ = crypto.HexToECDSA(privKey) + addr = crypto.PubkeyToAddress(key.PublicKey) // 0x71562b71999873DB5b286dF957af199Ec94617F7 + + // This account is one the validators for 1st span (0-indexed) + privKey2 = "9b28f36fbd67381120752d6172ecdcf10e06ab2d9a1367aac00cdcd6ac7855d3" + key2, _ = crypto.HexToECDSA(privKey2) + addr2 = crypto.PubkeyToAddress(key2.PublicKey) // 0x9fB29AAc15b9A4B7F17c3385939b007540f4d791 + + validatorHeaderBytesLength = common.AddressLength + 20 // address + power sprintSize uint64 = 4 spanSize uint64 = 8 ) @@ -88,40 +95,36 @@ func buildEthereumInstance(t *testing.T, db ethdb.Database) *initializeData { } } -func insertNewBlock(t *testing.T, _bor *bor.Bor, chain *core.BlockChain, header *types.Header, statedb *state.StateDB, privKey []byte) *types.Block { - _, err := _bor.FinalizeAndAssemble(chain, header, statedb, nil, nil, nil) - if err != nil { - t.Fatalf("%s", err) - } - - sig, err := secp256k1.Sign(crypto.Keccak256(bor.BorRLP(header)), privKey) - if err != nil { - t.Fatalf("%s", err) - } - copy(header.Extra[len(header.Extra)-extraSeal:], sig) - - block := types.NewBlockWithHeader(header) +func insertNewBlock(t *testing.T, chain *core.BlockChain, block *types.Block) { if _, err := chain.InsertChain([]*types.Block{block}); err != nil { t.Fatalf("%s", err) } - return block } -func buildMinimalNextHeader(t *testing.T, block *types.Block, borConfig *params.BorConfig) *types.Header { +func buildNextBlock(t *testing.T, _bor *bor.Bor, chain *core.BlockChain, block *types.Block, signer []byte, borConfig *params.BorConfig) *types.Block { header := block.Header() header.Number.Add(header.Number, big.NewInt(1)) + number := header.Number.Uint64() + + if signer == nil { + signer = getSignerKey(header.Number.Uint64()) + } + header.ParentHash = block.Hash() header.Time += bor.CalcProducerDelay(header.Number.Uint64(), 0, borConfig) header.Extra = make([]byte, 32+65) // vanity + extraSeal currentValidators := []*bor.Validator{bor.NewValidator(addr, 10)} - isSpanEnd := (header.Number.Uint64()+1)%spanSize == 0 + + isSpanEnd := (number+1)%spanSize == 0 + isSpanStart := number%spanSize == 0 isSprintEnd := (header.Number.Uint64()+1)%sprintSize == 0 if isSpanEnd { _, heimdallSpan := loadSpanFromFile(t) + // this is to stash the validator bytes in the header currentValidators = heimdallSpan.ValidatorSet.Validators - } else if header.Number.Uint64()%spanSize == 0 { - header.Difficulty = new(big.Int).SetInt64(5) + } else if isSpanStart { + header.Difficulty = new(big.Int).SetInt64(3) } if isSprintEnd { sort.Sort(bor.ValidatorsByAddress(currentValidators)) @@ -132,13 +135,25 @@ func buildMinimalNextHeader(t *testing.T, block *types.Block, borConfig *params. } copy(header.Extra[32:], validatorBytes) } - _key, _ := hex.DecodeString(privKey) - sig, err := secp256k1.Sign(crypto.Keccak256(bor.BorRLP(header)), _key) + + state, err := chain.State() + if err != nil { + t.Fatalf("%s", err) + } + _, err = _bor.FinalizeAndAssemble(chain, header, state, nil, nil, nil) + if err != nil { + t.Fatalf("%s", err) + } + sign(t, header, signer) + return types.NewBlockWithHeader(header) +} + +func sign(t *testing.T, header *types.Header, signer []byte) { + sig, err := secp256k1.Sign(crypto.Keccak256(bor.BorRLP(header)), signer) if err != nil { t.Fatalf("%s", err) } copy(header.Extra[len(header.Extra)-extraSeal:], sig) - return header } func loadSpanFromFile(t *testing.T) (*bor.ResponseWithHeight, *bor.HeimdallSpan) { @@ -157,3 +172,14 @@ func loadSpanFromFile(t *testing.T) (*bor.ResponseWithHeight, *bor.HeimdallSpan) } return res, heimdallSpan } + +func getSignerKey(number uint64) []byte { + signerKey := privKey + isSpanStart := number%spanSize == 0 + if isSpanStart { + // validator set in the new span has changed + signerKey = privKey2 + } + _key, _ := hex.DecodeString(signerKey) + return _key +} diff --git a/consensus/bor/bor_test/span.json b/consensus/bor/bor_test/span.json index 1f2679523a..893d3db4a6 100644 --- a/consensus/bor/bor_test/span.json +++ b/consensus/bor/bor_test/span.json @@ -6,85 +6,57 @@ "end_block": 6655, "validator_set": { "validators": [{ - "ID": 3, - "startEpoch": 0, - "endEpoch": 0, - "power": 10000, - "pubKey": "0x046434e10a34ade13c4fea917346a9fd1473eac2138a0b4e2a36426871918be63188fde4edbf598457592c9a49fe3b0036dd5497079495d132e5045bf499c4bdb1", - "signer": "0xc787af4624cb3e80ee23ae7faac0f2acea2be34c", - "last_updated": 0, - "accum": -40000 - }, { - "ID": 4, - "startEpoch": 0, - "endEpoch": 0, - "power": 10000, - "pubKey": "0x04d9d09f2afc9da3cccc164e8112eb6911a63f5ede10169768f800df83cf99c73f944411e9d4fac3543b11c5f84a82e56b36cfcd34f1d065855c1e2b27af8b5247", - "signer": "0x461295d3d9249215e758e939a150ab180950720b", - "last_updated": 0, - "accum": 10000 - }, { "ID": 5, "startEpoch": 0, "endEpoch": 0, - "power": 10000, + "power": 30, "pubKey": "0x04a36f6ed1f93acb0a38f4cacbe2467c72458ac41ce3b12b34d758205b2bc5d930a4e059462da7a0976c32fce766e1f7e8d73933ae72ac2af231fe161187743932", - "signer": "0x836fe3e3dd0a5f77d9d5b0f67e48048aaafcd5a0", + "signer": "0x9fB29AAc15b9A4B7F17c3385939b007540f4d791", "last_updated": 0, "accum": 10000 }, { "ID": 1, "startEpoch": 0, "endEpoch": 0, - "power": 10000, + "power": 20, "pubKey": "0x04a312814042a6655c8e5ecf0c52cba0b6a6f3291c87cc42260a3c0222410c0d0d59b9139d1c56542e5df0ce2fce3a86ce13e93bd9bde0dc8ff664f8dd5294dead", - "signer": "0x925a91f8003aaeabea6037103123b93c50b86ca3", + "signer": "0x96C42C56fdb78294F96B0cFa33c92bed7D75F96a", "last_updated": 0, "accum": 10000 }, { "ID": 2, "startEpoch": 0, "endEpoch": 0, - "power": 10000, + "power": 10, "pubKey": "0x0469536ae98030a7e83ec5ef3baffed2d05a32e31d978e58486f6bdb0fbbf240293838325116090190c0639db03f9cbd8b9aecfd269d016f46e3a2287fbf9ad232", - "signer": "0x71562b71999873DB5b286dF957af199Ec94617F7", + "signer": "0xc787af4624cb3e80ee23ae7faac0f2acea2be34c", "last_updated": 0, - "accum": 10000 - }], - "proposer": { - "ID": 3, - "startEpoch": 0, - "endEpoch": 0, - "power": 10000, - "pubKey": "0x046434e10a34ade13c4fea917346a9fd1473eac2138a0b4e2a36426871918be63188fde4edbf598457592c9a49fe3b0036dd5497079495d132e5045bf499c4bdb1", - "signer": "0x1c4f0f054a0d6a1415382dc0fd83c6535188b220", - "last_updated": 0, - "accum": -40000 - } + "accum": 5000 + }] }, "selected_producers": [{ "ID": 5, "startEpoch": 0, "endEpoch": 0, - "power": 1, + "power": 30, "pubKey": "0x04a36f6ed1f93acb0a38f4cacbe2467c72458ac41ce3b12b34d758205b2bc5d930a4e059462da7a0976c32fce766e1f7e8d73933ae72ac2af231fe161187743932", - "signer": "0x836fe3e3dd0a5f77d9d5b0f67e48048aaafcd5a0", + "signer": "0x9fB29AAc15b9A4B7F17c3385939b007540f4d791", "last_updated": 0, "accum": 10000 }, { "ID": 1, "startEpoch": 0, "endEpoch": 0, - "power": 1, + "power": 20, "pubKey": "0x04a312814042a6655c8e5ecf0c52cba0b6a6f3291c87cc42260a3c0222410c0d0d59b9139d1c56542e5df0ce2fce3a86ce13e93bd9bde0dc8ff664f8dd5294dead", - "signer": "0x925a91f8003aaeabea6037103123b93c50b86ca3", + "signer": "0x96C42C56fdb78294F96B0cFa33c92bed7D75F96a", "last_updated": 0, "accum": 10000 }, { "ID": 2, "startEpoch": 0, "endEpoch": 0, - "power": 2, + "power": 10, "pubKey": "0x0469536ae98030a7e83ec5ef3baffed2d05a32e31d978e58486f6bdb0fbbf240293838325116090190c0639db03f9cbd8b9aecfd269d016f46e3a2287fbf9ad232", "signer": "0xc787af4624cb3e80ee23ae7faac0f2acea2be34c", "last_updated": 0, diff --git a/consensus/bor/errors.go b/consensus/bor/errors.go index 7e7ee17915..f357705db4 100644 --- a/consensus/bor/errors.go +++ b/consensus/bor/errors.go @@ -90,7 +90,7 @@ type MismatchingValidatorsError struct { func (e *MismatchingValidatorsError) Error() string { return fmt.Sprintf( - "Mismatching validators at block %d\nValidatorBytes from snapshot: %x\nValidatorBytes in Header: %x\n", + "Mismatching validators at block %d\nValidatorBytes from snapshot: 0x%x\nValidatorBytes in Header: 0x%x\n", e.Number, e.ValidatorSetSnap, e.ValidatorSetHeader, @@ -109,3 +109,36 @@ func (e *BlockTooSoonError) Error() string { e.Succession, ) } + +// UnauthorizedSignerError is returned if a header is signed by a non-authorized entity. +type UnauthorizedSignerError struct { + Number uint64 + Signer []byte +} + +func (e *UnauthorizedSignerError) Error() string { + return fmt.Sprintf( + "Validator set for block %d doesn't contain the signer 0x%x\n", + e.Number, + e.Signer, + ) +} + +// WrongDifficultyError is returned if the difficulty of a block doesn't match the +// turn of the signer. +type WrongDifficultyError struct { + Number uint64 + Expected uint64 + Actual uint64 + Signer []byte +} + +func (e *WrongDifficultyError) Error() string { + return fmt.Sprintf( + "Wrong difficulty at block %d, expected: %d, actual %d. Signer was %x\n", + e.Number, + e.Expected, + e.Actual, + e.Signer, + ) +} diff --git a/consensus/bor/snapshot.go b/consensus/bor/snapshot.go index 08088d7911..a62c2014b9 100644 --- a/consensus/bor/snapshot.go +++ b/consensus/bor/snapshot.go @@ -155,7 +155,7 @@ func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) { // check if signer is in validator set if !snap.ValidatorSet.HasAddress(signer.Bytes()) { - return nil, errUnauthorizedSigner + return nil, &UnauthorizedSignerError{number, signer.Bytes()} } if _, err = snap.GetSignerSuccessionNumber(signer); err != nil { @@ -222,8 +222,8 @@ func (s *Snapshot) signers() []common.Address { return sigs } -// inturn returns if a signer at a given block height is in-turn or not. -func (s *Snapshot) inturn(number uint64, signer common.Address, epoch uint64) uint64 { +// Difficulty returns the difficulty for a particular signer at the current snapshot number +func (s *Snapshot) Difficulty(signer common.Address) uint64 { // if signer is empty if bytes.Compare(signer.Bytes(), common.Address{}.Bytes()) == 0 { return 1 From 0f9e189a258247ed1c1a40b39000727d79b6aea1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Apr 2020 22:37:34 +0000 Subject: [PATCH 23/46] Bump https-proxy-agent from 2.2.1 to 2.2.4 in /dashboard/assets Bumps [https-proxy-agent](https://github.com/TooTallNate/node-https-proxy-agent) from 2.2.1 to 2.2.4. - [Release notes](https://github.com/TooTallNate/node-https-proxy-agent/releases) - [Commits](https://github.com/TooTallNate/node-https-proxy-agent/compare/2.2.1...2.2.4) Signed-off-by: dependabot[bot] --- dashboard/assets/yarn.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dashboard/assets/yarn.lock b/dashboard/assets/yarn.lock index 0fdf5593cd..a1b03f483b 100644 --- a/dashboard/assets/yarn.lock +++ b/dashboard/assets/yarn.lock @@ -1075,7 +1075,7 @@ after@0.8.2: resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= -agent-base@4, agent-base@^4.1.0: +agent-base@4, agent-base@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== @@ -3650,11 +3650,11 @@ https-browserify@^1.0.0: integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= https-proxy-agent@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0" - integrity sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ== + version "2.2.4" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b" + integrity sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg== dependencies: - agent-base "^4.1.0" + agent-base "^4.3.0" debug "^3.1.0" humps@^2.0.1: From 9ad02c9a577d0932fc285c78da7d4c600926c42a Mon Sep 17 00:00:00 2001 From: Jaynti Kanani Date: Fri, 15 May 2020 23:09:44 +0530 Subject: [PATCH 24/46] fix: heimdall url flag --- cmd/bor/chaincmd.go | 1 + cmd/bor/config.go | 2 +- cmd/utils/flags.go | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/cmd/bor/chaincmd.go b/cmd/bor/chaincmd.go index bbb8792a16..83d3261566 100644 --- a/cmd/bor/chaincmd.go +++ b/cmd/bor/chaincmd.go @@ -64,6 +64,7 @@ It expects the genesis file as argument.`, ArgsUsage: " ( ... ) ", Flags: []cli.Flag{ utils.DataDirFlag, + utils.HeimdallURLFlag, utils.CacheFlag, utils.SyncModeFlag, utils.GCModeFlag, diff --git a/cmd/bor/config.go b/cmd/bor/config.go index 4929d826eb..9202fec7c4 100644 --- a/cmd/bor/config.go +++ b/cmd/bor/config.go @@ -151,7 +151,7 @@ func enableWhisper(ctx *cli.Context) bool { func makeFullNode(ctx *cli.Context) *node.Node { stack, cfg := makeConfigNode(ctx) - cfg.Eth.HeimdallURL = ctx.String(utils.HeimdallURLFlag.Name) + cfg.Eth.HeimdallURL = ctx.GlobalString(utils.HeimdallURLFlag.Name) log.Info("Connecting to heimdall service on...", "heimdallURL", cfg.Eth.HeimdallURL) utils.RegisterEthService(stack, &cfg.Eth) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index fa0aa9bf16..78a70beabe 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -1694,7 +1694,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai if config.Clique != nil { engine = clique.New(config.Clique, chainDb) } else if config.Bor != nil { - cfg := ð.Config{Genesis: genesis} + cfg := ð.Config{Genesis: genesis, HeimdallURL: ctx.GlobalString(HeimdallURLFlag.Name)} workspace, err := ioutil.TempDir("", "console-tester-") if err != nil { Fatalf("failed to create temporary keystore: %v", err) From 868dc81c8ae37dd8dd06dbb7335f00cdc6d75ecc Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Sun, 17 May 2020 17:24:09 +0530 Subject: [PATCH 25/46] new: New fetch State sync logic --- consensus/bor/bor.go | 203 ++++++++-------------- consensus/bor/bor_test/bor_test.go | 46 +++-- consensus/bor/bor_test/genesis.json | 8 +- consensus/bor/bor_test/helper.go | 12 ++ consensus/bor/bor_test/states.json | 23 +++ consensus/bor/clerk.go | 33 ++++ consensus/bor/errors.go | 18 ++ consensus/bor/genesis_contracts_client.go | 108 ++++++++++++ 8 files changed, 302 insertions(+), 149 deletions(-) create mode 100644 consensus/bor/bor_test/states.json create mode 100644 consensus/bor/genesis_contracts_client.go diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 7ee2f52be1..4b2b9b59f3 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -41,9 +41,6 @@ import ( "golang.org/x/crypto/sha3" ) -const validatorsetABI = `[{"constant":true,"inputs":[{"name":"span","type":"uint256"}],"name":"getSpan","outputs":[{"name":"number","type":"uint256"},{"name":"startBlock","type":"uint256"},{"name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"number","type":"uint256"}],"name":"getBorValidators","outputs":[{"name":"","type":"address[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"span","type":"uint256"},{"name":"signer","type":"address"}],"name":"isProducer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newSpan","type":"uint256"},{"name":"startBlock","type":"uint256"},{"name":"endBlock","type":"uint256"},{"name":"validatorBytes","type":"bytes"},{"name":"producerBytes","type":"bytes"}],"name":"commitSpan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"span","type":"uint256"},{"name":"signer","type":"address"}],"name":"isValidator","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"proposeSpan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"currentSpanNumber","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNextSpan","outputs":[{"name":"number","type":"uint256"},{"name":"startBlock","type":"uint256"},{"name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitialValidators","outputs":[{"name":"","type":"address[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"spanProposalPending","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCurrentSpan","outputs":[{"name":"number","type":"uint256"},{"name":"startBlock","type":"uint256"},{"name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"number","type":"uint256"}],"name":"getSpanByBlock","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getValidators","outputs":[{"name":"","type":"address[]"},{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"vote","type":"bytes"},{"name":"sigs","type":"bytes"},{"name":"txBytes","type":"bytes"},{"name":"proof","type":"bytes"}],"name":"validateValidatorSet","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]` -const stateReceiverABI = `[{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"states","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"recordBytes","type":"bytes"}],"name":"commitState","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getPendingStates","outputs":[{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SYSTEM_ADDRESS","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"validatorSet","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"vote","type":"bytes"},{"name":"sigs","type":"bytes"},{"name":"txBytes","type":"bytes"},{"name":"proof","type":"bytes"}],"name":"validateValidatorSet","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"isValidatorSetContract","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"stateId","type":"uint256"}],"name":"proposeState","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"signer","type":"address"}],"name":"isProducer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"signer","type":"address"}],"name":"isValidator","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"}]` - const ( checkpointInterval = 1024 // Number of blocks after which to save the vote snapshot to the database inmemorySnapshots = 128 // Number of recent vote snapshots to keep in memory @@ -66,6 +63,7 @@ var ( validatorHeaderBytesLength = common.AddressLength + 20 // address + power systemAddress = common.HexToAddress("0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE") + stateFetchLimit = 50 ) // Various error messages to mark blocks invalid. These should be private to @@ -233,10 +231,11 @@ type Bor struct { signFn SignerFn // Signer function to authorize hashes with lock sync.RWMutex // Protects the signer fields - ethAPI *ethapi.PublicBlockChainAPI - validatorSetABI abi.ABI - stateReceiverABI abi.ABI - HeimdallClient IHeimdallClient + ethAPI *ethapi.PublicBlockChainAPI + genesisContractsClient *GenesisContractsClient + validatorSetABI abi.ABI + stateReceiverABI abi.ABI + HeimdallClient IHeimdallClient stateDataFeed event.Feed scope event.SubscriptionScope @@ -266,17 +265,18 @@ func New( vABI, _ := abi.JSON(strings.NewReader(validatorsetABI)) sABI, _ := abi.JSON(strings.NewReader(stateReceiverABI)) heimdallClient, _ := NewHeimdallClient(heimdallURL) - + genesisContractsClient := NewGenesisContractsClient(chainConfig, borConfig.ValidatorContract, borConfig.StateReceiverContract, ethAPI) c := &Bor{ - chainConfig: chainConfig, - config: borConfig, - db: db, - ethAPI: ethAPI, - recents: recents, - signatures: signatures, - validatorSetABI: vABI, - stateReceiverABI: sABI, - HeimdallClient: heimdallClient, + chainConfig: chainConfig, + config: borConfig, + db: db, + ethAPI: ethAPI, + recents: recents, + signatures: signatures, + validatorSetABI: vABI, + stateReceiverABI: sABI, + genesisContractsClient: genesisContractsClient, + HeimdallClient: heimdallClient, } return c @@ -703,7 +703,7 @@ func (c *Bor) FinalizeAndAssemble(chain consensus.ChainReader, header *types.Hea // commit statees if err := c.CommitStates(state, header, cx); err != nil { log.Error("Error while committing states", "error", err) - // return nil, err + return nil, err } } @@ -867,38 +867,6 @@ func (c *Bor) Close() error { return nil } -// Checks if "force" proposeSpan has been set -func (c *Bor) isSpanPending(snapshotNumber uint64) (bool, error) { - blockNr := rpc.BlockNumber(snapshotNumber) - method := "spanProposalPending" - - // get packed data - data, err := c.validatorSetABI.Pack(method) - if err != nil { - log.Error("Unable to pack tx for spanProposalPending", "error", err) - return false, err - } - - msgData := (hexutil.Bytes)(data) - toAddress := common.HexToAddress(c.config.ValidatorContract) - gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2)) - result, err := c.ethAPI.Call(context.Background(), ethapi.CallArgs{ - Gas: &gas, - To: &toAddress, - Data: &msgData, - }, blockNr) - if err != nil { - return false, err - } - - var ret0 = new(bool) - if err := c.validatorSetABI.Unpack(ret0, method, result); err != nil { - return false, err - } - - return *ret0, nil -} - // GetCurrentSpan get current span from contract func (c *Bor) GetCurrentSpan(snapshotNumber uint64) (*Span, error) { // block @@ -1003,37 +971,14 @@ func (c *Bor) checkAndCommitSpan( chain core.ChainContext, ) error { headerNumber := header.Number.Uint64() - pending := false - var span *Span = nil - errors := make(chan error) - go func() { - var err error - pending, err = c.isSpanPending(headerNumber - 1) - errors <- err - }() - - go func() { - var err error - span, err = c.GetCurrentSpan(headerNumber - 1) - errors <- err - }() - - var err error - for i := 0; i < 2; i++ { - err = <-errors - if err != nil { - close(errors) - return err - } + span, err := c.GetCurrentSpan(headerNumber - 1) + if err != nil { + return err } - close(errors) - - // commit span if there is new span pending or span is ending or end block is not set - if pending || c.needToCommitSpan(span, headerNumber) { + if c.needToCommitSpan(span, headerNumber) { err := c.fetchAndCommitSpan(span.ID+1, state, header, chain) return err } - return nil } @@ -1170,83 +1115,87 @@ func (c *Bor) GetPendingStateProposals(snapshotNumber uint64) ([]*big.Int, error func (c *Bor) CommitStates( state *state.StateDB, header *types.Header, - chain core.ChainContext, + chain chainContext, ) error { - // get pending state proposals - stateIds, err := c.GetPendingStateProposals(header.Number.Uint64() - 1) + number := header.Number.Uint64() + if number < c.config.Sprint { + return errors.New("Requested to commit states too soon") + } + + lastSync, err := c.genesisContractsClient.LastStateSyncTime(number - 1) if err != nil { return err } + from := lastSync.Add(time.Second * 1) // querying the interval [from, to) + to := time.Unix(int64(chain.Chain.GetHeaderByNumber(number-1).Time), 0) + log.Info( + "Fetching state updates from Heimdall", + "from", from.Format(time.RFC3339), + "to", to.Format(time.RFC3339)) - // state ids - if len(stateIds) > 0 { - log.Debug("Found new proposed states", "numberOfStates", len(stateIds)) - } - - method := "commitState" - - // itereate through state ids - for _, stateID := range stateIds { - // fetch from heimdall - response, err := c.HeimdallClient.FetchWithRetry("clerk", "event-record", strconv.FormatUint(stateID.Uint64(), 10)) + page := 1 + eventRecords := make([]*EventRecordWithTime, 0) + for { + query := fmt.Sprintf("clerk/event-record/list?from-time=%d&to-time=%d&page=%d&limit=%d", from.Unix(), to.Unix(), page, stateFetchLimit) + log.Info("Fetching state events", "query", query) + response, err := c.HeimdallClient.FetchWithRetry(query) if err != nil { return err } - - // get event record - var eventRecord EventRecord - if err := json.Unmarshal(response.Result, &eventRecord); err != nil { + var _eventRecords []*EventRecordWithTime + if err := json.Unmarshal(response.Result, &_eventRecords); err != nil { return err } + eventRecords = append(eventRecords, _eventRecords...) + if len(_eventRecords) < stateFetchLimit { + break + } + page++ + } + sort.SliceStable(eventRecords, func(i, j int) bool { + return eventRecords[i].Time.Before(eventRecords[j].Time) + }) - // check if chain id matches with event record - if eventRecord.ChainID != c.chainConfig.ChainID.String() { - return fmt.Errorf( - "Chain id proposed state in span, %s, and bor chain id, %s, doesn't match", - eventRecord.ChainID, - c.chainConfig.ChainID, - ) + chainID := c.chainConfig.ChainID.String() + for _, eventRecord := range eventRecords { + // if chanId doesn't match with the record, simply ignore it + if eventRecord.ChainID != chainID { + log.Error(fmt.Sprintln("Chain Id in received event %s and bor chain Id %s, don't match", eventRecord, chainID)) + continue + } + // validateEventRecord checks whether an event lies in the specified time range + // since the events are sorted by time and if it turns out that event i lies outside the time range, + // it would mean all subsequent events lie outside of the time range. Hence we don't probe any further and break the loop + if err := validateEventRecord(eventRecord, number, from, to); err != nil { + log.Error( + fmt.Sprintf( + "Received event %s does not lie in the time range, from %s, to %s", + eventRecord, from.Format(time.RFC3339), to.Format(time.RFC3339))) + break } - log.Info("→ committing new state", - "id", eventRecord.ID, - "contract", eventRecord.Contract, - "data", hex.EncodeToString(eventRecord.Data), - "txHash", eventRecord.TxHash, - "chainID", eventRecord.ChainID, - ) stateData := types.StateData{ Did: eventRecord.ID, Contract: eventRecord.Contract, Data: hex.EncodeToString(eventRecord.Data), TxHash: eventRecord.TxHash, } - go func() { c.stateDataFeed.Send(core.NewStateChangeEvent{StateData: &stateData}) }() - recordBytes, err := rlp.EncodeToBytes(eventRecord) - if err != nil { - return err - } - - // get packed data for commit state - data, err := c.stateReceiverABI.Pack(method, recordBytes) - if err != nil { - log.Error("Unable to pack tx for commitState", "error", err) - return err - } - - // get system message - msg := getSystemMessage(common.HexToAddress(c.config.StateReceiverContract), data) - - // apply message - if err := applyMessage(msg, state, header, c.chainConfig, chain); err != nil { + if err := c.genesisContractsClient.CommitState(eventRecord, state, header, chain); err != nil { return err } } + return nil +} +func validateEventRecord(eventRecord *EventRecordWithTime, number uint64, from, to time.Time) error { + inRange := (eventRecord.Time.Equal(from) || eventRecord.Time.After(from)) && eventRecord.Time.Before(to) + if !inRange { + return &InvalidStateReceivedError{number, &from, &to, eventRecord} + } return nil } diff --git a/consensus/bor/bor_test/bor_test.go b/consensus/bor/bor_test/bor_test.go index 62d929220a..9502812622 100644 --- a/consensus/bor/bor_test/bor_test.go +++ b/consensus/bor/bor_test/bor_test.go @@ -2,6 +2,9 @@ package bortest import ( "encoding/hex" + "fmt" + // "encoding/json" + // "fmt" "math/big" "testing" @@ -10,6 +13,7 @@ import ( "github.com/maticnetwork/bor/core/rawdb" "github.com/maticnetwork/bor/crypto" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" "github.com/maticnetwork/bor/core/types" @@ -21,26 +25,27 @@ func TestCommitSpan(t *testing.T) { chain := init.ethereum.BlockChain() engine := init.ethereum.Engine() _bor := engine.(*bor.Bor) - - // Mock HeimdallClient.FetchWithRetry to return span data from span.json - res, heimdallSpan := loadSpanFromFile(t) - h := &mocks.IHeimdallClient{} - h.On("FetchWithRetry", "bor", "span", "1").Return(res, nil) + h, heimdallSpan := getMockedHeimdallClient(t) _bor.SetHeimdallClient(h) db := init.ethereum.ChainDb() block := init.genesis.ToBlock(db) + var to int64 + // Insert sprintSize # of blocks so that span is fetched at the start of a new sprint for i := uint64(1); i <= sprintSize; i++ { block = buildNextBlock(t, _bor, chain, block, nil, init.genesis.Config.Bor) insertNewBlock(t, chain, block) + if i == sprintSize-1 { + // at # sprintSize, events are fetched for the internal [from, (block-1).Time) + to = int64(block.Header().Time) + } } - // FetchWithRetry is invoked 2 times - // 1. bor.FinalizeAndAssemble to prepare a new block when calling buildNextBlock - // 2. bor.Finalize via(bc.insertChain => bc.processor.Process) assert.True(t, h.AssertCalled(t, "FetchWithRetry", "bor", "span", "1")) - validators, err := _bor.GetCurrentValidators(sprintSize, 256) // new span starts at 256 + query := fmt.Sprintf("clerk/event-record/list?from-time=%d&to-time=%d&page=1&limit=50", 1, to) + assert.True(t, h.AssertCalled(t, "FetchWithRetry", query)) + validators, err := _bor.GetCurrentValidators(sprintSize, spanSize) // new span starts at 256 if err != nil { t.Fatalf("%s", err) } @@ -57,6 +62,8 @@ func TestIsValidatorAction(t *testing.T) { chain := init.ethereum.BlockChain() engine := init.ethereum.Engine() _bor := engine.(*bor.Bor) + h, heimdallSpan := getMockedHeimdallClient(t) + _bor.SetHeimdallClient(h) proposeStateData, _ := hex.DecodeString("ede01f170000000000000000000000000000000000000000000000000000000000000000") proposeSpanData, _ := hex.DecodeString("4b0e4d17") @@ -77,11 +84,6 @@ func TestIsValidatorAction(t *testing.T) { ) assert.True(t, _bor.IsValidatorAction(chain, addr, tx)) - res, heimdallSpan := loadSpanFromFile(t) - h := &mocks.IHeimdallClient{} - h.On("FetchWithRetry", "bor", "span", "1").Return(res, nil) - _bor.SetHeimdallClient(h) - db := init.ethereum.ChainDb() block := init.genesis.ToBlock(db) @@ -115,10 +117,7 @@ func TestOutOfTurnSigning(t *testing.T) { chain := init.ethereum.BlockChain() engine := init.ethereum.Engine() _bor := engine.(*bor.Bor) - - res, _ := loadSpanFromFile(t) - h := &mocks.IHeimdallClient{} - h.On("FetchWithRetry", "bor", "span", "1").Return(res, nil) + h, _ := getMockedHeimdallClient(t) _bor.SetHeimdallClient(h) db := init.ethereum.ChainDb() @@ -160,3 +159,14 @@ func TestOutOfTurnSigning(t *testing.T) { _, err = chain.InsertChain([]*types.Block{block}) assert.Nil(t, err) } + +func getMockedHeimdallClient(t *testing.T) (*mocks.IHeimdallClient, *bor.HeimdallSpan) { + res, heimdallSpan := loadSpanFromFile(t) + h := &mocks.IHeimdallClient{} + h.On("FetchWithRetry", "bor", "span", "1").Return(res, nil) + + res = zeroResultPayload(t) + // query := fmt.Sprintf("clerk/event-record/list?from-time=%d&to-time=%d&page=1&limit=50", 1, 1589709047) + h.On("FetchWithRetry", mock.AnythingOfType("string")).Return(res, nil) + return h, heimdallSpan +} diff --git a/consensus/bor/bor_test/genesis.json b/consensus/bor/bor_test/genesis.json index 5113190b18..7c70393591 100644 --- a/consensus/bor/bor_test/genesis.json +++ b/consensus/bor/bor_test/genesis.json @@ -10,9 +10,9 @@ "constantinopleBlock": 0, "bor": { "period": 1, - "producerDelay": 4, - "backupMultiplier": 1, + "producerDelay": 1, "sprint": 4, + "backupMultiplier": 1, "validatorContract": "0x0000000000000000000000000000000000001000", "stateReceiverContract": "0x0000000000000000000000000000000000001001" } @@ -27,11 +27,11 @@ "alloc": { "0000000000000000000000000000000000001000": { "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b50600436106102115760003560e01c806365b3a1e211610125578063b2472431116100ad578063d0504f891161007c578063d0504f89146106af578063d5b844eb146106cb578063dcf2793a146106e9578063e3b7c9241461071b578063f59cf5651461073957610211565b8063b247243114610612578063b71d7a6914610630578063b7ab4db514610660578063c1b3c9191461067f57610211565b806370ba5707116100f457806370ba57071461055657806398ab2b62146105865780639d11b807146105a4578063ae756451146105d4578063af26aa96146105f257610211565b806365b3a1e2146104c957806366332354146104e8578063687a9bd61461050657806369c49fac1461053857610211565b806335ddfeea116101a85780634b0e4d17116101775780634b0e4d17146104215780634dbc959f1461042b57806355614fcc14610449578063582a8d081461047957806360c8614d146104a957610211565b806335ddfeea1461037357806343ee8213146103a357806344c15cb1146103c157806344d6528f146103f157610211565b806323f2a73f116101e457806323f2a73f146102c55780632de3a180146102f55780632eddf352146103255780633434735f1461035557610211565b8063047a6c5b146102165780630c35b1cb146102485780631270b5741461027957806323c2a2b4146102a9575b600080fd5b610230600480360361022b9190810190612e7e565b61076b565b60405161023f93929190613903565b60405180910390f35b610262600480360361025d9190810190612e7e565b6107c2565b6040516102709291906136c4565b60405180910390f35b610293600480360361028e9190810190612ea7565b61099e565b6040516102a091906136fb565b60405180910390f35b6102c360048036036102be9190810190612f86565b610af6565b005b6102df60048036036102da9190810190612ea7565b611177565b6040516102ec91906136fb565b60405180910390f35b61030f600480360361030a9190810190612d18565b6112cf565b60405161031c9190613716565b60405180910390f35b61033f600480360361033a9190810190612e7e565b611350565b60405161034c91906138b1565b60405180910390f35b61035d611481565b60405161036a91906136a9565b60405180910390f35b61038d60048036036103889190810190612d54565b611499565b60405161039a91906136fb565b60405180910390f35b6103ab611564565b6040516103b89190613716565b60405180910390f35b6103db60048036036103d69190810190612ee3565b61157b565b6040516103e891906138b1565b60405180910390f35b61040b60048036036104069190810190612ea7565b611663565b6040516104189190613896565b60405180910390f35b6104296117cc565b005b610433611828565b60405161044091906138b1565b60405180910390f35b610463600480360361045e9190810190612c9d565b611838565b60405161047091906136fb565b60405180910390f35b610493600480360361048e9190810190612cc6565b611852565b6040516104a09190613716565b60405180910390f35b6104b16118d0565b6040516104c093929190613903565b60405180910390f35b6104d1611944565b6040516104df9291906136c4565b60405180910390f35b6104f0611a34565b6040516104fd91906138b1565b60405180910390f35b610520600480360361051b9190810190612f4a565b611a39565b60405161052f939291906138cc565b60405180910390f35b610540611a9d565b60405161054d91906136fb565b60405180910390f35b610570600480360361056b9190810190612c9d565b611ab4565b60405161057d91906136fb565b60405180910390f35b61058e611ace565b60405161059b9190613716565b60405180910390f35b6105be60048036036105b99190810190612e7e565b611ae5565b6040516105cb91906138b1565b60405180910390f35b6105dc611c16565b6040516105e99190613716565b60405180910390f35b6105fa611c2d565b60405161060993929190613903565b60405180910390f35b61061a611c8e565b60405161062791906138b1565b60405180910390f35b61064a60048036036106459190810190612e7e565b611c94565b60405161065791906138b1565b60405180910390f35b610668611d94565b6040516106769291906136c4565b60405180910390f35b61069960048036036106949190810190612e7e565b611da8565b6040516106a691906138b1565b60405180910390f35b6106c960048036036106c49190810190612dbb565b611dc9565b005b6106d361201f565b6040516106e0919061393a565b60405180910390f35b61070360048036036106fe9190810190612f4a565b612024565b604051610712939291906138cc565b60405180910390f35b610723612088565b60405161073091906138b1565b60405180910390f35b610753600480360361074e9190810190612e7e565b61209a565b60405161076293929190613903565b60405180910390f35b60008060006004600085815260200190815260200160002060000154600460008681526020019081526020016000206001015460046000878152602001908152602001600020600201549250925092509193909250565b606080600883116107de576107d5611944565b91509150610999565b60006107e984611c94565b9050606060036000838152602001908152602001600020805490506040519080825280602002602001820160405280156108325781602001602082028038833980820191505090505b5090506060600360008481526020019081526020016000208054905060405190808252806020026020018201604052801561087c5781602001602082028038833980820191505090505b50905060008090505b600360008581526020019081526020016000208054905081101561098e576003600085815260200190815260200160002081815481106108c157fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168382815181106108ff57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060036000858152602001908152602001600020818154811061095757fe5b90600052602060002090600302016001015482828151811061097557fe5b6020026020010181815250508080600101915050610885565b508181945094505050505b915091565b6000606060036000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015610a71578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050815260200190600101906109d5565b50505050905060008090505b8151811015610ae9578373ffffffffffffffffffffffffffffffffffffffff16828281518110610aa957fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff161415610adc57600192505050610af0565b8080600101915050610a7d565b5060009150505b92915050565b73fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b4257600080fd5b6000610b4c611828565b90506000811415610b6057610b5f6120c4565b5b610b746001826123f090919063ffffffff16565b8814610bb5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bac906137b6565b60405180910390fd5b868611610bf7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bee90613816565b60405180910390fd5b6000805460018989030181610c0857fe5b0614610c49576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c40906137f6565b60405180910390fd5b8660046000838152602001908152602001600020600101541115610ca2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c9990613776565b60405180910390fd5b6000600460008a81526020019081526020016000206000015414610cfb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cf2906137d6565b60405180910390fd5b604051806060016040528089815260200188815260200187815250600460008a815260200190815260200160002060008201518160000155602082015181600101556040820151816002015590505060058890806001815401808255809150509060018203906000526020600020016000909192909190915055506000600260008a815260200190815260200160002081610d969190612a97565b506000600360008a815260200190815260200160002081610db79190612a97565b506060610e0f610e0a87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061240f565b61243d565b905060008090505b8151811015610f83576060610e3e838381518110610e3157fe5b602002602001015161243d565b9050600260008c81526020019081526020016000208054809190600101610e659190612a97565b506040518060600160405280610e8e83600081518110610e8157fe5b602002602001015161251a565b8152602001610eb083600181518110610ea357fe5b602002602001015161251a565b8152602001610ed283600281518110610ec557fe5b602002602001015161258b565b73ffffffffffffffffffffffffffffffffffffffff16815250600260008d81526020019081526020016000208381548110610f0957fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050508080600101915050610e17565b506060610fdb610fd686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061240f565b61243d565b905060008090505b815181101561114f57606061100a838381518110610ffd57fe5b602002602001015161243d565b9050600360008d815260200190815260200160002080548091906001016110319190612a97565b50604051806060016040528061105a8360008151811061104d57fe5b602002602001015161251a565b815260200161107c8360018151811061106f57fe5b602002602001015161251a565b815260200161109e8360028151811061109157fe5b602002602001015161258b565b73ffffffffffffffffffffffffffffffffffffffff16815250600360008e815260200190815260200160002083815481106110d557fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050508080600101915050610fe3565b506000600160006101000a81548160ff02191690831515021790555050505050505050505050565b6000606060026000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561124a578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050815260200190600101906111ae565b50505050905060008090505b81518110156112c2578373ffffffffffffffffffffffffffffffffffffffff1682828151811061128257fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff1614156112b5576001925050506112c9565b8080600101915050611256565b5060009150505b92915050565b60006002600160f81b84846040516020016112ec93929190613616565b6040516020818303038152906040526040516113089190613653565b602060405180830381855afa158015611325573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506113489190810190612cef565b905092915050565b6000606060026000848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015611423578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611387565b505050509050600080905060008090505b82518110156114765761146783828151811061144c57fe5b602002602001015160200151836123f090919063ffffffff16565b91508080600101915050611434565b508092505050919050565b73fffffffffffffffffffffffffffffffffffffffe81565b60008060008085905060006021808751816114b057fe5b0402905060008111156114c9576114c687611852565b91505b6000602190505b818111611553576000600182038801519050818801519550806000602081106114f557fe5b1a60f81b9450600060f81b857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561153a5761153386856112cf565b9350611547565b61154484876112cf565b93505b506021810190506114d0565b508782149450505050509392505050565b6040516115709061367f565b604051809103902081565b60008060009050600080905060008090505b84518167ffffffffffffffff1610156116565760606115b8868367ffffffffffffffff1660416125ae565b905060006115cf828961263a90919063ffffffff16565b90506115d9612ac9565b6115e38a83611663565b90506115ef8a83611177565b801561162657508473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16115b15611648578194506116458160200151876123f090919063ffffffff16565b95505b50505060418101905061158d565b5081925050509392505050565b61166b612ac9565b606060026000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561173c578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050815260200190600101906116a0565b50505050905060008090505b81518110156117c4578373ffffffffffffffffffffffffffffffffffffffff1682828151811061177457fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff1614156117b7578181815181106117a857fe5b602002602001015192506117c4565b8080600101915050611748565b505092915050565b60006117d6611828565b90506117e28133611177565b6117eb57600080fd5b60001515600160009054906101000a900460ff1615151461180b57600080fd5b60018060006101000a81548160ff02191690831515021790555050565b600061183343611c94565b905090565b600061184b611845611828565b83611177565b9050919050565b60006002600060f81b8360405160200161186d9291906135ea565b6040516020818303038152906040526040516118899190613653565b602060405180830381855afa1580156118a6573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506118c99190810190612cef565b9050919050565b6000806000806118f160016118e3611828565b6123f090919063ffffffff16565b905060046000828152602001908152602001600020600001546004600083815260200190815260200160002060010154600460008481526020019081526020016000206002015493509350935050909192565b606080606060016040519080825280602002602001820160405280156119795781602001602082028038833980820191505090505b5090507371562b71999873db5b286df957af199ec94617f78160008151811061199e57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060606001604051908082528060200260200182016040528015611a0a5781602001602082028038833980820191505090505b509050600a81600081518110611a1c57fe5b60200260200101818152505081819350935050509091565b600881565b60036020528160005260406000208181548110611a5257fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b6000600160009054906101000a900460ff16905090565b6000611ac7611ac1611828565b8361099e565b9050919050565b604051611ada9061366a565b604051809103902081565b6000606060036000848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015611bb8578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611b1c565b505050509050600080905060008090505b8251811015611c0b57611bfc838281518110611be157fe5b602002602001015160200151836123f090919063ffffffff16565b91508080600101915050611bc9565b508092505050919050565b604051611c2290613694565b604051809103902081565b600080600080611c3b611828565b905060046000828152602001908152602001600020600001546004600083815260200190815260200160002060010154600460008481526020019081526020016000206002015493509350935050909192565b60005481565b60008060058054905090505b6000811115611d5457611cb1612b00565b6004600060056001850381548110611cc557fe5b906000526020600020015481526020019081526020016000206040518060600160405290816000820154815260200160018201548152602001600282015481525050905083816020015111158015611d2257506000816040015114155b8015611d32575080604001518411155b15611d4557806000015192505050611d8f565b50808060019003915050611ca0565b5060006005805490501115611d8a57600560016005805490500381548110611d7857fe5b90600052602060002001549050611d8f565b600090505b919050565b606080611da0436107c2565b915091509091565b60058181548110611db557fe5b906000526020600020016000915090505481565b6060611ddc611dd78661240f565b61243d565b9050604051611dea9061367f565b6040518091039020611e0f82600081518110611e0257fe5b6020026020010151612744565b8051906020012014611e56576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e4d90613796565b60405180910390fd5b600260ff16611e7882600181518110611e6b57fe5b602002602001015161251a565b14611eb8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eaf90613836565b60405180910390fd5b611f31611ed882600481518110611ecb57fe5b602002602001015161251a565b60001b600285604051611eeb9190613653565b602060405180830381855afa158015611f08573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250611f2b9190810190612cef565b84611499565b611f70576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6790613856565b60405180910390fd5b6000611f7a611828565b90506000611f908288805190602001208861157b565b9050611fd46001611fc66003611fb86002611faa88611350565b6127d090919063ffffffff16565b61280a90919063ffffffff16565b6123f090919063ffffffff16565b811015612016576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161200d90613876565b60405180910390fd5b50505050505050565b600281565b6002602052816000526040600020818154811061203d57fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b60006040438161209457fe5b04905090565b60046020528060005260406000206000915090508060000154908060010154908060020154905083565b60406000819055506060806120d7611944565b809250819350505060008090506040518060600160405280828152602001600081526020016008815250600460008381526020019081526020016000206000820151816000015560208201518160010155604082015181600201559050506005819080600181540180825580915050906001820390600052602060002001600090919290919091505550600060026000838152602001908152602001600020816121819190612a97565b50600060036000838152602001908152602001600020816121a29190612a97565b5060008090505b83518110156122c6576002600083815260200190815260200160002080548091906001016121d79190612a97565b5060405180606001604052808281526020018483815181106121f557fe5b6020026020010151815260200185838151811061220e57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681525060026000848152602001908152602001600020828154811061224d57fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505080806001019150506121a9565b5060008090505b83518110156123ea576003600083815260200190815260200160002080548091906001016122fb9190612a97565b50604051806060016040528082815260200184838151811061231957fe5b6020026020010151815260200185838151811061233257fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681525060036000848152602001908152602001600020828154811061237157fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505080806001019150506122cd565b50505050565b60008082840190508381101561240557600080fd5b8091505092915050565b612417612b21565b600060208301905060405180604001604052808451815260200182815250915050919050565b606061244882612830565b61245157600080fd5b600061245c8361287e565b905060608160405190808252806020026020018201604052801561249a57816020015b612487612b3b565b81526020019060019003908161247f5790505b50905060006124ac85602001516128ef565b8560200151019050600080600090505b8481101561250d576124cd83612978565b91506040518060400160405280838152602001848152508482815181106124f057fe5b6020026020010181905250818301925080806001019150506124bc565b5082945050505050919050565b600080826000015111801561253457506021826000015111155b61253d57600080fd5b600061254c83602001516128ef565b9050600081846000015103905060008083866020015101905080519150602083101561257f57826020036101000a820491505b81945050505050919050565b6000601582600001511461259e57600080fd5b6125a78261251a565b9050919050565b6060818301845110156125c057600080fd5b60608215600081146125dd5760405191506020820160405261262e565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561261b57805183526020830192506020810190506125fe565b50868552601f19601f8301166040525050505b50809150509392505050565b6000806000806041855114612655576000935050505061273e565b602085015192506040850151915060ff6041860151169050601b8160ff16101561268057601b810190505b601b8160ff16141580156126985750601c8160ff1614155b156126a9576000935050505061273e565b6000600187838686604051600081526020016040526040516126ce9493929190613731565b6020604051602081039080840390855afa1580156126f0573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561273657600080fd5b809450505050505b92915050565b6060600082600001511161275757600080fd5b600061276683602001516128ef565b905060008184600001510390506060816040519080825280601f01601f1916602001820160405280156127a85781602001600182028038833980820191505090505b50905060008160200190506127c4848760200151018285612a30565b81945050505050919050565b6000808314156127e35760009050612804565b60008284029050828482816127f457fe5b04146127ff57600080fd5b809150505b92915050565b600080821161281857600080fd5b600082848161282357fe5b0490508091505092915050565b600080826000015114156128475760009050612879565b60008083602001519050805160001a915060c060ff168260ff16101561287257600092505050612879565b6001925050505b919050565b6000808260000151141561289557600090506128ea565b600080905060006128a984602001516128ef565b84602001510190506000846000015185602001510190505b808210156128e3576128d282612978565b8201915082806001019350506128c1565b8293505050505b919050565b600080825160001a9050608060ff1681101561290f576000915050612973565b60b860ff16811080612934575060c060ff168110158015612933575060f860ff1681105b5b15612943576001915050612973565b60c060ff168110156129635760018060b80360ff16820301915050612973565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff168110156129995760019150612a26565b60b860ff168110156129b6576001608060ff168203019150612a25565b60c060ff168110156129e65760b78103600185019450806020036101000a85510460018201810193505050612a24565b60f860ff16811015612a0357600160c060ff168203019150612a23565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b6000811415612a3e57612a92565b5b602060ff168110612a6e5782518252602060ff1683019250602060ff1682019150602060ff1681039050612a3f565b6000600182602060ff16036101000a03905080198451168184511681811785525050505b505050565b815481835581811115612ac457600302816003028360005260206000209182019101612ac39190612b55565b5b505050565b60405180606001604052806000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b60405180606001604052806000815260200160008152602001600081525090565b604051806040016040528060008152602001600081525090565b604051806040016040528060008152602001600081525090565b612ba891905b80821115612ba45760008082016000905560018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550600301612b5b565b5090565b90565b600081359050612bba81613b33565b92915050565b600081359050612bcf81613b4a565b92915050565b600081519050612be481613b4a565b92915050565b60008083601f840112612bfc57600080fd5b8235905067ffffffffffffffff811115612c1557600080fd5b602083019150836001820283011115612c2d57600080fd5b9250929050565b600082601f830112612c4557600080fd5b8135612c58612c5382613982565b613955565b91508082526020830160208301858383011115612c7457600080fd5b612c7f838284613add565b50505092915050565b600081359050612c9781613b61565b92915050565b600060208284031215612caf57600080fd5b6000612cbd84828501612bab565b91505092915050565b600060208284031215612cd857600080fd5b6000612ce684828501612bc0565b91505092915050565b600060208284031215612d0157600080fd5b6000612d0f84828501612bd5565b91505092915050565b60008060408385031215612d2b57600080fd5b6000612d3985828601612bc0565b9250506020612d4a85828601612bc0565b9150509250929050565b600080600060608486031215612d6957600080fd5b6000612d7786828701612bc0565b9350506020612d8886828701612bc0565b925050604084013567ffffffffffffffff811115612da557600080fd5b612db186828701612c34565b9150509250925092565b60008060008060808587031215612dd157600080fd5b600085013567ffffffffffffffff811115612deb57600080fd5b612df787828801612c34565b945050602085013567ffffffffffffffff811115612e1457600080fd5b612e2087828801612c34565b935050604085013567ffffffffffffffff811115612e3d57600080fd5b612e4987828801612c34565b925050606085013567ffffffffffffffff811115612e6657600080fd5b612e7287828801612c34565b91505092959194509250565b600060208284031215612e9057600080fd5b6000612e9e84828501612c88565b91505092915050565b60008060408385031215612eba57600080fd5b6000612ec885828601612c88565b9250506020612ed985828601612bab565b9150509250929050565b600080600060608486031215612ef857600080fd5b6000612f0686828701612c88565b9350506020612f1786828701612bc0565b925050604084013567ffffffffffffffff811115612f3457600080fd5b612f4086828701612c34565b9150509250925092565b60008060408385031215612f5d57600080fd5b6000612f6b85828601612c88565b9250506020612f7c85828601612c88565b9150509250929050565b600080600080600080600060a0888a031215612fa157600080fd5b6000612faf8a828b01612c88565b9750506020612fc08a828b01612c88565b9650506040612fd18a828b01612c88565b955050606088013567ffffffffffffffff811115612fee57600080fd5b612ffa8a828b01612bea565b9450945050608088013567ffffffffffffffff81111561301957600080fd5b6130258a828b01612bea565b925092505092959891949750929550565b60006130428383613066565b60208301905092915050565b600061305a83836135bd565b60208301905092915050565b61306f81613a52565b82525050565b61307e81613a52565b82525050565b600061308f826139ce565b6130998185613a09565b93506130a4836139ae565b8060005b838110156130d55781516130bc8882613036565b97506130c7836139ef565b9250506001810190506130a8565b5085935050505092915050565b60006130ed826139d9565b6130f78185613a1a565b9350613102836139be565b8060005b8381101561313357815161311a888261304e565b9750613125836139fc565b925050600181019050613106565b5085935050505092915050565b61314981613a64565b82525050565b61316061315b82613a70565b613b1f565b82525050565b61316f81613a9c565b82525050565b61318661318182613a9c565b613b29565b82525050565b6000613197826139e4565b6131a18185613a2b565b93506131b1818560208601613aec565b80840191505092915050565b60006131ca600483613a47565b91507f766f7465000000000000000000000000000000000000000000000000000000006000830152600482019050919050565b600061320a602d83613a36565b91507f537461727420626c6f636b206d7573742062652067726561746572207468616e60008301527f2063757272656e74207370616e000000000000000000000000000000000000006020830152604082019050919050565b6000613270601383613a36565b91507f436861696e20494420697320696e76616c6964000000000000000000000000006000830152602082019050919050565b60006132b0600f83613a36565b91507f496e76616c6964207370616e20696400000000000000000000000000000000006000830152602082019050919050565b60006132f0601383613a36565b91507f5370616e20616c726561647920657869737473000000000000000000000000006000830152602082019050919050565b6000613330604583613a36565b91507f446966666572656e6365206265747765656e20737461727420616e6420656e6460008301527f20626c6f636b206d75737420626520696e206d756c7469706c6573206f66207360208301527f7072696e740000000000000000000000000000000000000000000000000000006040830152606082019050919050565b60006133bc602a83613a36565b91507f456e6420626c6f636b206d7573742062652067726561746572207468616e207360008301527f7461727420626c6f636b000000000000000000000000000000000000000000006020830152604082019050919050565b6000613422601483613a36565b91507f566f7465207479706520697320696e76616c69640000000000000000000000006000830152602082019050919050565b6000613462601683613a36565b91507f5472616e73616374696f6e20697320696e76616c6964000000000000000000006000830152602082019050919050565b60006134a2600e83613a47565b91507f6865696d64616c6c2d31353030310000000000000000000000000000000000006000830152600e82019050919050565b60006134e2600583613a47565b91507f31353030310000000000000000000000000000000000000000000000000000006000830152600582019050919050565b6000613522602483613a36565b91507f4e6f7420656e6f7567687420706f77657220746f206368616e6765207468652060008301527f7370616e000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60608201600082015161359160008501826135bd565b5060208201516135a460208501826135bd565b5060408201516135b76040850182613066565b50505050565b6135c681613ac6565b82525050565b6135d581613ac6565b82525050565b6135e481613ad0565b82525050565b60006135f6828561314f565b6001820191506136068284613175565b6020820191508190509392505050565b6000613622828661314f565b6001820191506136328285613175565b6020820191506136428284613175565b602082019150819050949350505050565b600061365f828461318c565b915081905092915050565b6000613675826131bd565b9150819050919050565b600061368a82613495565b9150819050919050565b600061369f826134d5565b9150819050919050565b60006020820190506136be6000830184613075565b92915050565b600060408201905081810360008301526136de8185613084565b905081810360208301526136f281846130e2565b90509392505050565b60006020820190506137106000830184613140565b92915050565b600060208201905061372b6000830184613166565b92915050565b60006080820190506137466000830187613166565b61375360208301866135db565b6137606040830185613166565b61376d6060830184613166565b95945050505050565b6000602082019050818103600083015261378f816131fd565b9050919050565b600060208201905081810360008301526137af81613263565b9050919050565b600060208201905081810360008301526137cf816132a3565b9050919050565b600060208201905081810360008301526137ef816132e3565b9050919050565b6000602082019050818103600083015261380f81613323565b9050919050565b6000602082019050818103600083015261382f816133af565b9050919050565b6000602082019050818103600083015261384f81613415565b9050919050565b6000602082019050818103600083015261386f81613455565b9050919050565b6000602082019050818103600083015261388f81613515565b9050919050565b60006060820190506138ab600083018461357b565b92915050565b60006020820190506138c660008301846135cc565b92915050565b60006060820190506138e160008301866135cc565b6138ee60208301856135cc565b6138fb6040830184613075565b949350505050565b600060608201905061391860008301866135cc565b61392560208301856135cc565b61393260408301846135cc565b949350505050565b600060208201905061394f60008301846135db565b92915050565b6000604051905081810181811067ffffffffffffffff8211171561397857600080fd5b8060405250919050565b600067ffffffffffffffff82111561399957600080fd5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000613a5d82613aa6565b9050919050565b60008115159050919050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b82818337600083830152505050565b60005b83811015613b0a578082015181840152602081019050613aef565b83811115613b19576000848401525b50505050565b6000819050919050565b6000819050919050565b613b3c81613a52565b8114613b4757600080fd5b50565b613b5381613a9c565b8114613b5e57600080fd5b50565b613b6a81613ac6565b8114613b7557600080fd5b5056fea365627a7a72315820974ebeb3f99a1975cbb5176c18039d5281de5c0dd7622c82358480b017dede8d6c6578706572696d656e74616cf564736f6c63430005100040" + "code": "0x608060405234801561001057600080fd5b50600436106101f05760003560e01c806365b3a1e21161010f578063b2472431116100a2578063d5b844eb11610071578063d5b844eb14610666578063dcf2793a14610684578063e3b7c924146106b6578063f59cf565146106d4576101f0565b8063b2472431146105c9578063b71d7a69146105e7578063b7ab4db514610617578063c1b3c91914610636576101f0565b806398ab2b62116100de57806398ab2b621461053d5780639d11b8071461055b578063ae7564511461058b578063af26aa96146105a9576101f0565b806365b3a1e21461049e57806366332354146104bd578063687a9bd6146104db57806370ba57071461050d576101f0565b806335ddfeea116101875780634dbc959f116101565780634dbc959f1461040057806355614fcc1461041e578063582a8d081461044e57806360c8614d1461047e576101f0565b806335ddfeea1461035257806343ee82131461038257806344c15cb1146103a057806344d6528f146103d0576101f0565b806323f2a73f116101c357806323f2a73f146102a45780632de3a180146102d45780632eddf352146103045780633434735f14610334576101f0565b8063047a6c5b146101f55780630c35b1cb146102275780631270b5741461025857806323c2a2b414610288575b600080fd5b61020f600480360361020a919081019061290d565b610706565b60405161021e939291906131ec565b60405180910390f35b610241600480360361023c919081019061290d565b61075d565b60405161024f92919061302d565b60405180910390f35b610272600480360361026d9190810190612936565b610939565b60405161027f9190613064565b60405180910390f35b6102a2600480360361029d9190810190612a15565b610a91565b005b6102be60048036036102b99190810190612936565b6110f4565b6040516102cb9190613064565b60405180910390f35b6102ee60048036036102e9919081019061286a565b61124b565b6040516102fb919061307f565b60405180910390f35b61031e6004803603610319919081019061290d565b6112cc565b60405161032b919061319a565b60405180910390f35b61033c6113fc565b6040516103499190613012565b60405180910390f35b61036c600480360361036791908101906128a6565b611414565b6040516103799190613064565b60405180910390f35b61038a6114df565b604051610397919061307f565b60405180910390f35b6103ba60048036036103b59190810190612972565b6114f6565b6040516103c7919061319a565b60405180910390f35b6103ea60048036036103e59190810190612936565b6115de565b6040516103f7919061317f565b60405180910390f35b610408611746565b604051610415919061319a565b60405180910390f35b610438600480360361043391908101906127ef565b611756565b6040516104459190613064565b60405180910390f35b61046860048036036104639190810190612818565b611770565b604051610475919061307f565b60405180910390f35b6104866117ee565b604051610495939291906131ec565b60405180910390f35b6104a6611862565b6040516104b492919061302d565b60405180910390f35b6104c5611952565b6040516104d2919061319a565b60405180910390f35b6104f560048036036104f091908101906129d9565b611957565b604051610504939291906131b5565b60405180910390f35b610527600480360361052291908101906127ef565b6119bb565b6040516105349190613064565b60405180910390f35b6105456119d5565b604051610552919061307f565b60405180910390f35b6105756004803603610570919081019061290d565b6119ec565b604051610582919061319a565b60405180910390f35b610593611b1d565b6040516105a0919061307f565b60405180910390f35b6105b1611b34565b6040516105c0939291906131ec565b60405180910390f35b6105d1611b95565b6040516105de919061319a565b60405180910390f35b61060160048036036105fc919081019061290d565b611b9a565b60405161060e919061319a565b60405180910390f35b61061f611c9a565b60405161062d92919061302d565b60405180910390f35b610650600480360361064b919081019061290d565b611cae565b60405161065d919061319a565b60405180910390f35b61066e611ccf565b60405161067b9190613223565b60405180910390f35b61069e600480360361069991908101906129d9565b611cd4565b6040516106ad939291906131b5565b60405180910390f35b6106be611d38565b6040516106cb919061319a565b60405180910390f35b6106ee60048036036106e9919081019061290d565b611d4a565b6040516106fd939291906131ec565b60405180910390f35b60008060006002600085815260200190815260200160002060000154600260008681526020019081526020016000206001015460026000878152602001908152602001600020600201549250925092509193909250565b6060806007831161077957610770611862565b91509150610934565b600061078484611b9a565b9050606060016000838152602001908152602001600020805490506040519080825280602002602001820160405280156107cd5781602001602082028038833980820191505090505b509050606060016000848152602001908152602001600020805490506040519080825280602002602001820160405280156108175781602001602082028038833980820191505090505b50905060008090505b60016000858152602001908152602001600020805490508110156109295760016000858152602001908152602001600020818154811061085c57fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683828151811061089a57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506001600085815260200190815260200160002081815481106108f257fe5b90600052602060002090600302016001015482828151811061091057fe5b6020026020010181815250508080600101915050610820565b508181945094505050505b915091565b6000606060016000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015610a0c578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190610970565b50505050905060008090505b8151811015610a84578373ffffffffffffffffffffffffffffffffffffffff16828281518110610a4457fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff161415610a7757600192505050610a8b565b8080600101915050610a18565b5060009150505b92915050565b73fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610add57600080fd5b6000610ae7611746565b90506000811415610afb57610afa611d74565b5b610b0f60018261209590919063ffffffff16565b8814610b50576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b47906130ff565b60405180910390fd5b868611610b92576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b899061315f565b60405180910390fd5b6000600460018989030181610ba357fe5b0614610be4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bdb9061313f565b60405180910390fd5b8660026000838152602001908152602001600020600101541115610c3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c34906130df565b60405180910390fd5b6000600260008a81526020019081526020016000206000015414610c96576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c8d9061311f565b60405180910390fd5b604051806060016040528089815260200188815260200187815250600260008a8152602001908152602001600020600082015181600001556020820151816001015560408201518160020155905050600388908060018154018082558091505090600182039060005260206000200160009091929091909150555060008060008a815260200190815260200160002081610d3091906125e9565b506000600160008a815260200190815260200160002081610d5191906125e9565b506060610da9610da487878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506120b4565b6120e2565b905060008090505b8151811015610f1b576060610dd8838381518110610dcb57fe5b60200260200101516120e2565b90506000808c81526020019081526020016000208054809190600101610dfe91906125e9565b506040518060600160405280610e2783600081518110610e1a57fe5b60200260200101516121bf565b8152602001610e4983600181518110610e3c57fe5b60200260200101516121bf565b8152602001610e6b83600281518110610e5e57fe5b6020026020010151612230565b73ffffffffffffffffffffffffffffffffffffffff168152506000808d81526020019081526020016000208381548110610ea157fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050508080600101915050610db1565b506060610f73610f6e86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506120b4565b6120e2565b905060008090505b81518110156110e7576060610fa2838381518110610f9557fe5b60200260200101516120e2565b9050600160008d81526020019081526020016000208054809190600101610fc991906125e9565b506040518060600160405280610ff283600081518110610fe557fe5b60200260200101516121bf565b81526020016110148360018151811061100757fe5b60200260200101516121bf565b81526020016110368360028151811061102957fe5b6020026020010151612230565b73ffffffffffffffffffffffffffffffffffffffff16815250600160008e8152602001908152602001600020838154811061106d57fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050508080600101915050610f7b565b5050505050505050505050565b60006060600080858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156111c6578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250508152602001906001019061112a565b50505050905060008090505b815181101561123e578373ffffffffffffffffffffffffffffffffffffffff168282815181106111fe57fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff16141561123157600192505050611245565b80806001019150506111d2565b5060009150505b92915050565b60006002600160f81b848460405160200161126893929190612f7f565b6040516020818303038152906040526040516112849190612fbc565b602060405180830381855afa1580156112a1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506112c49190810190612841565b905092915050565b60006060600080848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561139e578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611302565b505050509050600080905060008090505b82518110156113f1576113e28382815181106113c757fe5b6020026020010151602001518361209590919063ffffffff16565b915080806001019150506113af565b508092505050919050565b73fffffffffffffffffffffffffffffffffffffffe81565b600080600080859050600060218087518161142b57fe5b0402905060008111156114445761144187611770565b91505b6000602190505b8181116114ce5760006001820388015190508188015195508060006020811061147057fe5b1a60f81b9450600060f81b857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156114b5576114ae868561124b565b93506114c2565b6114bf848761124b565b93505b5060218101905061144b565b508782149450505050509392505050565b6040516114eb90612fe8565b604051809103902081565b60008060009050600080905060008090505b84518167ffffffffffffffff1610156115d1576060611533868367ffffffffffffffff166041612253565b9050600061154a82896122df90919063ffffffff16565b905061155461261b565b61155e8a836115de565b905061156a8a836110f4565b80156115a157508473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16115b156115c3578194506115c081602001518761209590919063ffffffff16565b95505b505050604181019050611508565b5081925050509392505050565b6115e661261b565b6060600080858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156116b6578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250508152602001906001019061161a565b50505050905060008090505b815181101561173e578373ffffffffffffffffffffffffffffffffffffffff168282815181106116ee57fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff1614156117315781818151811061172257fe5b6020026020010151925061173e565b80806001019150506116c2565b505092915050565b600061175143611b9a565b905090565b6000611769611763611746565b836110f4565b9050919050565b60006002600060f81b8360405160200161178b929190612f53565b6040516020818303038152906040526040516117a79190612fbc565b602060405180830381855afa1580156117c4573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506117e79190810190612841565b9050919050565b60008060008061180f6001611801611746565b61209590919063ffffffff16565b905060026000828152602001908152602001600020600001546002600083815260200190815260200160002060010154600260008481526020019081526020016000206002015493509350935050909192565b606080606060016040519080825280602002602001820160405280156118975781602001602082028038833980820191505090505b5090507371562b71999873db5b286df957af199ec94617f7816000815181106118bc57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050606060016040519080825280602002602001820160405280156119285781602001602082028038833980820191505090505b509050600a8160008151811061193a57fe5b60200260200101818152505081819350935050509091565b600781565b6001602052816000526040600020818154811061197057fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b60006119ce6119c8611746565b83610939565b9050919050565b6040516119e190612fd3565b604051809103902081565b6000606060016000848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015611abf578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611a23565b505050509050600080905060008090505b8251811015611b1257611b03838281518110611ae857fe5b6020026020010151602001518361209590919063ffffffff16565b91508080600101915050611ad0565b508092505050919050565b604051611b2990612ffd565b604051809103902081565b600080600080611b42611746565b905060026000828152602001908152602001600020600001546002600083815260200190815260200160002060010154600260008481526020019081526020016000206002015493509350935050909192565b600481565b60008060038054905090505b6000811115611c5a57611bb7612652565b6002600060036001850381548110611bcb57fe5b906000526020600020015481526020019081526020016000206040518060600160405290816000820154815260200160018201548152602001600282015481525050905083816020015111158015611c2857506000816040015114155b8015611c38575080604001518411155b15611c4b57806000015192505050611c95565b50808060019003915050611ba6565b5060006003805490501115611c9057600360016003805490500381548110611c7e57fe5b90600052602060002001549050611c95565b600090505b919050565b606080611ca64361075d565b915091509091565b60038181548110611cbb57fe5b906000526020600020016000915090505481565b600281565b60006020528160005260406000208181548110611ced57fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b600060404381611d4457fe5b04905090565b60026020528060005260406000206000915090508060000154908060010154908060020154905083565b606080611d7f611862565b809250819350505060008090506040518060600160405280828152602001600081526020016007815250600260008381526020019081526020016000206000820151816000015560208201518160010155604082015181600201559050506003819080600181540180825580915050906001820390600052602060002001600090919290919091505550600080600083815260200190815260200160002081611e2891906125e9565b5060006001600083815260200190815260200160002081611e4991906125e9565b5060008090505b8351811015611f6b576000808381526020019081526020016000208054809190600101611e7d91906125e9565b506040518060600160405280828152602001848381518110611e9b57fe5b60200260200101518152602001858381518110611eb457fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff168152506000808481526020019081526020016000208281548110611ef257fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050508080600101915050611e50565b5060008090505b835181101561208f57600160008381526020019081526020016000208054809190600101611fa091906125e9565b506040518060600160405280828152602001848381518110611fbe57fe5b60200260200101518152602001858381518110611fd757fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681525060016000848152602001908152602001600020828154811061201657fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050508080600101915050611f72565b50505050565b6000808284019050838110156120aa57600080fd5b8091505092915050565b6120bc612673565b600060208301905060405180604001604052808451815260200182815250915050919050565b60606120ed826123e9565b6120f657600080fd5b600061210183612437565b905060608160405190808252806020026020018201604052801561213f57816020015b61212c61268d565b8152602001906001900390816121245790505b509050600061215185602001516124a8565b8560200151019050600080600090505b848110156121b25761217283612531565b915060405180604001604052808381526020018481525084828151811061219557fe5b602002602001018190525081830192508080600101915050612161565b5082945050505050919050565b60008082600001511180156121d957506021826000015111155b6121e257600080fd5b60006121f183602001516124a8565b9050600081846000015103905060008083866020015101905080519150602083101561222457826020036101000a820491505b81945050505050919050565b6000601582600001511461224357600080fd5b61224c826121bf565b9050919050565b60608183018451101561226557600080fd5b6060821560008114612282576040519150602082016040526122d3565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156122c057805183526020830192506020810190506122a3565b50868552601f19601f8301166040525050505b50809150509392505050565b60008060008060418551146122fa57600093505050506123e3565b602085015192506040850151915060ff6041860151169050601b8160ff16101561232557601b810190505b601b8160ff161415801561233d5750601c8160ff1614155b1561234e57600093505050506123e3565b600060018783868660405160008152602001604052604051612373949392919061309a565b6020604051602081039080840390855afa158015612395573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156123db57600080fd5b809450505050505b92915050565b600080826000015114156124005760009050612432565b60008083602001519050805160001a915060c060ff168260ff16101561242b57600092505050612432565b6001925050505b919050565b6000808260000151141561244e57600090506124a3565b6000809050600061246284602001516124a8565b84602001510190506000846000015185602001510190505b8082101561249c5761248b82612531565b82019150828060010193505061247a565b8293505050505b919050565b600080825160001a9050608060ff168110156124c857600091505061252c565b60b860ff168110806124ed575060c060ff1681101580156124ec575060f860ff1681105b5b156124fc57600191505061252c565b60c060ff1681101561251c5760018060b80360ff1682030191505061252c565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff1681101561255257600191506125df565b60b860ff1681101561256f576001608060ff1682030191506125de565b60c060ff1681101561259f5760b78103600185019450806020036101000a855104600182018101935050506125dd565b60f860ff168110156125bc57600160c060ff1682030191506125dc565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b8154818355818111156126165760030281600302836000526020600020918201910161261591906126a7565b5b505050565b60405180606001604052806000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b60405180606001604052806000815260200160008152602001600081525090565b604051806040016040528060008152602001600081525090565b604051806040016040528060008152602001600081525090565b6126fa91905b808211156126f65760008082016000905560018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055506003016126ad565b5090565b90565b60008135905061270c8161341c565b92915050565b60008135905061272181613433565b92915050565b60008151905061273681613433565b92915050565b60008083601f84011261274e57600080fd5b8235905067ffffffffffffffff81111561276757600080fd5b60208301915083600182028301111561277f57600080fd5b9250929050565b600082601f83011261279757600080fd5b81356127aa6127a58261326b565b61323e565b915080825260208301602083018583830111156127c657600080fd5b6127d18382846133c6565b50505092915050565b6000813590506127e98161344a565b92915050565b60006020828403121561280157600080fd5b600061280f848285016126fd565b91505092915050565b60006020828403121561282a57600080fd5b600061283884828501612712565b91505092915050565b60006020828403121561285357600080fd5b600061286184828501612727565b91505092915050565b6000806040838503121561287d57600080fd5b600061288b85828601612712565b925050602061289c85828601612712565b9150509250929050565b6000806000606084860312156128bb57600080fd5b60006128c986828701612712565b93505060206128da86828701612712565b925050604084013567ffffffffffffffff8111156128f757600080fd5b61290386828701612786565b9150509250925092565b60006020828403121561291f57600080fd5b600061292d848285016127da565b91505092915050565b6000806040838503121561294957600080fd5b6000612957858286016127da565b9250506020612968858286016126fd565b9150509250929050565b60008060006060848603121561298757600080fd5b6000612995868287016127da565b93505060206129a686828701612712565b925050604084013567ffffffffffffffff8111156129c357600080fd5b6129cf86828701612786565b9150509250925092565b600080604083850312156129ec57600080fd5b60006129fa858286016127da565b9250506020612a0b858286016127da565b9150509250929050565b600080600080600080600060a0888a031215612a3057600080fd5b6000612a3e8a828b016127da565b9750506020612a4f8a828b016127da565b9650506040612a608a828b016127da565b955050606088013567ffffffffffffffff811115612a7d57600080fd5b612a898a828b0161273c565b9450945050608088013567ffffffffffffffff811115612aa857600080fd5b612ab48a828b0161273c565b925092505092959891949750929550565b6000612ad18383612af5565b60208301905092915050565b6000612ae98383612f26565b60208301905092915050565b612afe8161333b565b82525050565b612b0d8161333b565b82525050565b6000612b1e826132b7565b612b2881856132f2565b9350612b3383613297565b8060005b83811015612b64578151612b4b8882612ac5565b9750612b56836132d8565b925050600181019050612b37565b5085935050505092915050565b6000612b7c826132c2565b612b868185613303565b9350612b91836132a7565b8060005b83811015612bc2578151612ba98882612add565b9750612bb4836132e5565b925050600181019050612b95565b5085935050505092915050565b612bd88161334d565b82525050565b612bef612bea82613359565b613408565b82525050565b612bfe81613385565b82525050565b612c15612c1082613385565b613412565b82525050565b6000612c26826132cd565b612c308185613314565b9350612c408185602086016133d5565b80840191505092915050565b6000612c59600483613330565b91507f766f7465000000000000000000000000000000000000000000000000000000006000830152600482019050919050565b6000612c99602d8361331f565b91507f537461727420626c6f636b206d7573742062652067726561746572207468616e60008301527f2063757272656e74207370616e000000000000000000000000000000000000006020830152604082019050919050565b6000612cff600f8361331f565b91507f496e76616c6964207370616e20696400000000000000000000000000000000006000830152602082019050919050565b6000612d3f60138361331f565b91507f5370616e20616c726561647920657869737473000000000000000000000000006000830152602082019050919050565b6000612d7f60458361331f565b91507f446966666572656e6365206265747765656e20737461727420616e6420656e6460008301527f20626c6f636b206d75737420626520696e206d756c7469706c6573206f66207360208301527f7072696e740000000000000000000000000000000000000000000000000000006040830152606082019050919050565b6000612e0b602a8361331f565b91507f456e6420626c6f636b206d7573742062652067726561746572207468616e207360008301527f7461727420626c6f636b000000000000000000000000000000000000000000006020830152604082019050919050565b6000612e71600e83613330565b91507f6865696d64616c6c2d31353030310000000000000000000000000000000000006000830152600e82019050919050565b6000612eb1600583613330565b91507f31353030310000000000000000000000000000000000000000000000000000006000830152600582019050919050565b606082016000820151612efa6000850182612f26565b506020820151612f0d6020850182612f26565b506040820151612f206040850182612af5565b50505050565b612f2f816133af565b82525050565b612f3e816133af565b82525050565b612f4d816133b9565b82525050565b6000612f5f8285612bde565b600182019150612f6f8284612c04565b6020820191508190509392505050565b6000612f8b8286612bde565b600182019150612f9b8285612c04565b602082019150612fab8284612c04565b602082019150819050949350505050565b6000612fc88284612c1b565b915081905092915050565b6000612fde82612c4c565b9150819050919050565b6000612ff382612e64565b9150819050919050565b600061300882612ea4565b9150819050919050565b60006020820190506130276000830184612b04565b92915050565b600060408201905081810360008301526130478185612b13565b9050818103602083015261305b8184612b71565b90509392505050565b60006020820190506130796000830184612bcf565b92915050565b60006020820190506130946000830184612bf5565b92915050565b60006080820190506130af6000830187612bf5565b6130bc6020830186612f44565b6130c96040830185612bf5565b6130d66060830184612bf5565b95945050505050565b600060208201905081810360008301526130f881612c8c565b9050919050565b6000602082019050818103600083015261311881612cf2565b9050919050565b6000602082019050818103600083015261313881612d32565b9050919050565b6000602082019050818103600083015261315881612d72565b9050919050565b6000602082019050818103600083015261317881612dfe565b9050919050565b60006060820190506131946000830184612ee4565b92915050565b60006020820190506131af6000830184612f35565b92915050565b60006060820190506131ca6000830186612f35565b6131d76020830185612f35565b6131e46040830184612b04565b949350505050565b60006060820190506132016000830186612f35565b61320e6020830185612f35565b61321b6040830184612f35565b949350505050565b60006020820190506132386000830184612f44565b92915050565b6000604051905081810181811067ffffffffffffffff8211171561326157600080fd5b8060405250919050565b600067ffffffffffffffff82111561328257600080fd5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b60006133468261338f565b9050919050565b60008115159050919050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b82818337600083830152505050565b60005b838110156133f35780820151818401526020810190506133d8565b83811115613402576000848401525b50505050565b6000819050919050565b6000819050919050565b6134258161333b565b811461343057600080fd5b50565b61343c81613385565b811461344757600080fd5b50565b613453816133af565b811461345e57600080fd5b5056fea365627a7a72315820aa6f542f997439d335795efc14d8a210d40bbd537d8b923d22efa48a1f756b6d6c6578706572696d656e74616cf564736f6c63430005100040" }, "0000000000000000000000000000000000001001": { "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b506004361061009e5760003560e01c8063d0504f8911610066578063d0504f8914610255578063d79e60b7146104d5578063ede01f17146104f7578063f552102214610525578063facd743b146105815761009e565b8063017a9105146100a3578063080356b7146100e957806321ec23b6146101625780633434735f146101c15780639426e2261461020b575b600080fd5b6100cf600480360360208110156100b957600080fd5b81019080803590602001909291905050506105dd565b604051808215151515815260200191505060405180910390f35b610160600480360360208110156100ff57600080fd5b810190808035906020019064010000000081111561011c57600080fd5b82018360208201111561012e57600080fd5b8035906020019184600183028401116401000000008311171561015057600080fd5b90919293919293905050506105fd565b005b61016a610a21565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156101ad578082015181840152602081019050610192565b505050509050019250505060405180910390f35b6101c9610ad2565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610213610aea565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6104d36004803603608081101561026b57600080fd5b810190808035906020019064010000000081111561028857600080fd5b82018360208201111561029a57600080fd5b803590602001918460018302840111640100000000831117156102bc57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561031f57600080fd5b82018360208201111561033157600080fd5b8035906020019184600183028401116401000000008311171561035357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156103b657600080fd5b8201836020820111156103c857600080fd5b803590602001918460018302840111640100000000831117156103ea57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561044d57600080fd5b82018360208201111561045f57600080fd5b8035906020019184600183028401116401000000008311171561048157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610af0565b005b6104dd610d0f565b604051808215151515815260200191505060405180910390f35b6105236004803603602081101561050d57600080fd5b8101908080359060200190929190505050610d47565b005b6105676004803603602081101561053b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610ef1565b604051808215151515815260200191505060405180910390f35b6105c36004803603602081101561059757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610fb4565b604051808215151515815260200191505060405180910390f35b60036020528060005260406000206000915054906101000a900460ff1681565b73fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461064957600080fd5b60606106a061069b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050611077565b6110a5565b905060006106c1826000815181106106b457fe5b6020026020010151611182565b905060006106e2836001815181106106d557fe5b60200260200101516111f3565b90506060610703846002815181106106f657fe5b6020026020010151611216565b9050600115156107146000856112a2565b151514610789576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f496e76616c69642070726f706f7365642073746174652069640000000000000081525060200191505060405180910390fd5b600015156003600085815260200190815260200160002060009054906101000a900460ff16151514610823576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f53746174652077617320616c72656164792070726f636573736564000000000081525060200191505060405180910390fd5b60016003600085815260200190815260200160002060006101000a81548160ff02191690831515021790555061085a6000846112c7565b5061086482611385565b15610a19578173ffffffffffffffffffffffffffffffffffffffff1683826040516024018083815260200180602001828103825283818151815260200191508051906020019080838360005b838110156108cb5780820151818401526020810190506108b0565b50505050905090810190601f1680156108f85780820380516001836020036101000a031916815260200191505b5093505050506040516020818303038152906040527f26c53bea000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b602083106109ae578051825260208201915060208101905060208303925061098b565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610a10576040519150601f19603f3d011682016040523d82523d6000602084013e610a15565b606091505b5050505b505050505050565b606060008090506060600060020154604051908082528060200260200182016040528015610a5e5781602001602082028038833980820191505090505b5090506000610a6d600061139e565b90505b610a7b6000826113d1565b15610ac957600080610a8e6000846113e5565b809250819350505081848681518110610aa357fe5b6020026020010181815250506001850194505050610ac260008261143a565b9050610a70565b50809250505090565b73fffffffffffffffffffffffffffffffffffffffe81565b61100081565b61100073ffffffffffffffffffffffffffffffffffffffff1663d0504f89858585856040518563ffffffff1660e01b81526004018080602001806020018060200180602001858103855289818151815260200191508051906020019080838360005b83811015610b6d578082015181840152602081019050610b52565b50505050905090810190601f168015610b9a5780820380516001836020036101000a031916815260200191505b50858103845288818151815260200191508051906020019080838360005b83811015610bd3578082015181840152602081019050610bb8565b50505050905090810190601f168015610c005780820380516001836020036101000a031916815260200191505b50858103835287818151815260200191508051906020019080838360005b83811015610c39578082015181840152602081019050610c1e565b50505050905090810190601f168015610c665780820380516001836020036101000a031916815260200191505b50858103825286818151815260200191508051906020019080838360005b83811015610c9f578082015181840152602081019050610c84565b50505050905090810190601f168015610ccc5780820380516001836020036101000a031916815260200191505b5098505050505050505050600060405180830381600087803b158015610cf157600080fd5b505af1158015610d05573d6000803e3d6000fd5b5050505050505050565b600061100073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b610d5033610fb4565b610dc2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f496e76616c69642076616c696461746f7200000000000000000000000000000081525060200191505060405180910390fd5b60001515610dd16000836112a2565b151514610e46576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f537461746520616c72656164792070726f706f7365640000000000000000000081525060200191505060405180910390fd5b600015156003600083815260200190815260200160002060009054906101000a900460ff16151514610ee0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f537461746520616c726561647920636f6d6d697474656400000000000000000081525060200191505060405180910390fd5b610eed60008260016114a0565b5050565b600061100073ffffffffffffffffffffffffffffffffffffffff166370ba5707836040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015610f7257600080fd5b505afa158015610f86573d6000803e3d6000fd5b505050506040513d6020811015610f9c57600080fd5b81019080805190602001909291905050509050919050565b600061100073ffffffffffffffffffffffffffffffffffffffff166355614fcc836040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561103557600080fd5b505afa158015611049573d6000803e3d6000fd5b505050506040513d602081101561105f57600080fd5b81019080805190602001909291905050509050919050565b61107f6117e6565b600060208301905060405180604001604052808451815260200182815250915050919050565b60606110b08261157f565b6110b957600080fd5b60006110c4836115cd565b905060608160405190808252806020026020018201604052801561110257816020015b6110ef611800565b8152602001906001900390816110e75790505b5090506000611114856020015161163e565b8560200151019050600080600090505b8481101561117557611135836116c7565b915060405180604001604052808381526020018481525084828151811061115857fe5b602002602001018190525081830192508080600101915050611124565b5082945050505050919050565b600080826000015111801561119c57506021826000015111155b6111a557600080fd5b60006111b4836020015161163e565b905060008184600001510390506000808386602001510190508051915060208310156111e757826020036101000a820491505b81945050505050919050565b6000601582600001511461120657600080fd5b61120f82611182565b9050919050565b6060600082600001511161122957600080fd5b6000611238836020015161163e565b905060008184600001510390506060816040519080825280601f01601f19166020018201604052801561127a5781602001600182028038833980820191505090505b509050600081602001905061129684876020015101828561177f565b81945050505050919050565b6000808360000160008481526020019081526020016000206000015411905092915050565b60008083600001600084815260200190815260200160002060000154905060008114156112f857600091505061137f565b8360000160008481526020019081526020016000206000808201600090556001820160006101000a81549060ff02191690555050600184600101600183038154811061134057fe5b906000526020600020906002020160010160006101000a81548160ff021916908315150217905550836002016000815480929190600190039190505550505b92915050565b600080823b905060008163ffffffff1611915050919050565b60006113ca827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61143a565b9050919050565b600082600101805490508210905092915050565b6000808360010183815481106113f757fe5b906000526020600020906002020160000154915083600001600083815260200190815260200160002060010160009054906101000a900460ff1690509250929050565b600081806001019250505b826001018054905082108015611485575082600101828154811061146557fe5b906000526020600020906002020160010160009054906101000a900460ff165b15611497578180600101925050611445565b81905092915050565b6000808460000160008581526020019081526020016000206000015490508285600001600086815260200190815260200160002060010160006101000a81548160ff0219169083151502179055506000811115611501576001915050611578565b846001018054809190600101611517919061181a565b905060018101856000016000868152602001908152602001600020600001819055508385600101828154811061154957fe5b906000526020600020906002020160000181905550846002016000815480929190600101919050555060009150505b9392505050565b6000808260000151141561159657600090506115c8565b60008083602001519050805160001a915060c060ff168260ff1610156115c1576000925050506115c8565b6001925050505b919050565b600080826000015114156115e45760009050611639565b600080905060006115f8846020015161163e565b84602001510190506000846000015185602001510190505b8082101561163257611621826116c7565b820191508280600101935050611610565b8293505050505b919050565b600080825160001a9050608060ff1681101561165e5760009150506116c2565b60b860ff16811080611683575060c060ff168110158015611682575060f860ff1681105b5b156116925760019150506116c2565b60c060ff168110156116b25760018060b80360ff168203019150506116c2565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff168110156116e85760019150611775565b60b860ff16811015611705576001608060ff168203019150611774565b60c060ff168110156117355760b78103600185019450806020036101000a85510460018201810193505050611773565b60f860ff1681101561175257600160c060ff168203019150611772565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b600081141561178d576117e1565b5b602060ff1681106117bd5782518252602060ff1683019250602060ff1682019150602060ff168103905061178e565b6000600182602060ff16036101000a03905080198451168184511681811785525050505b505050565b604051806040016040528060008152602001600081525090565b604051806040016040528060008152602001600081525090565b81548183558181111561184757600202816002028360005260206000209182019101611846919061184c565b5b505050565b61188491905b80821115611880576000808201600090556001820160006101000a81549060ff021916905550600201611852565b5090565b9056fea265627a7a723158207ab014ef9c036daf74874e7574845504838ad6772ad1e6e62607a4791965d6a964736f6c63430005100032" + "code": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c8063017a9105146100515780633434735f1461009757806348a211d6146100e15780634c7af28e14610164575b600080fd5b61007d6004803603602081101561006757600080fd5b8101908080359060200190929190505050610182565b604051808215151515815260200191505060405180910390f35b61009f6101a2565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610162600480360360408110156100f757600080fd5b810190808035906020019064010000000081111561011457600080fd5b82018360208201111561012657600080fd5b8035906020019184600183028401116401000000008311171561014857600080fd5b9091929391929390803590602001909291905050506101ba565b005b61016c6105b0565b6040518082815260200191505060405180910390f35b60016020528060005260406000206000915054906101000a900460ff1681565b73fffffffffffffffffffffffffffffffffffffffe81565b73fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461020657600080fd5b600054811015610261576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180610a966027913960400191505060405180910390fd5b8060008190555060606102bf6102ba85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506105b6565b6105e4565b905060006102e0826000815181106102d357fe5b60200260200101516106c1565b90506000610301836001815181106102f457fe5b6020026020010151610732565b905060606103228460028151811061031557fe5b6020026020010151610755565b9050600015156001600085815260200190815260200160002060009054906101000a900460ff161515146103be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f53746174652077617320616c72656164792070726f636573736564000000000081525060200191505060405180910390fd5b600180600085815260200190815260200160002060006101000a81548160ff0219169083151502179055506103f2826107e1565b156105a7578173ffffffffffffffffffffffffffffffffffffffff1683826040516024018083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561045957808201518184015260208101905061043e565b50505050905090810190601f1680156104865780820380516001836020036101000a031916815260200191505b5093505050506040516020818303038152906040527f26c53bea000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b6020831061053c5780518252602082019150602081019050602083039250610519565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461059e576040519150601f19603f3d011682016040523d82523d6000602084013e6105a3565b606091505b5050505b50505050505050565b60005481565b6105be610a61565b600060208301905060405180604001604052808451815260200182815250915050919050565b60606105ef826107fa565b6105f857600080fd5b600061060383610848565b905060608160405190808252806020026020018201604052801561064157816020015b61062e610a7b565b8152602001906001900390816106265790505b509050600061065385602001516108b9565b8560200151019050600080600090505b848110156106b45761067483610942565b915060405180604001604052808381526020018481525084828151811061069757fe5b602002602001018190525081830192508080600101915050610663565b5082945050505050919050565b60008082600001511180156106db57506021826000015111155b6106e457600080fd5b60006106f383602001516108b9565b9050600081846000015103905060008083866020015101905080519150602083101561072657826020036101000a820491505b81945050505050919050565b6000601582600001511461074557600080fd5b61074e826106c1565b9050919050565b6060600082600001511161076857600080fd5b600061077783602001516108b9565b905060008184600001510390506060816040519080825280601f01601f1916602001820160405280156107b95781602001600182028038833980820191505090505b50905060008160200190506107d58487602001510182856109fa565b81945050505050919050565b600080823b905060008163ffffffff1611915050919050565b600080826000015114156108115760009050610843565b60008083602001519050805160001a915060c060ff168260ff16101561083c57600092505050610843565b6001925050505b919050565b6000808260000151141561085f57600090506108b4565b6000809050600061087384602001516108b9565b84602001510190506000846000015185602001510190505b808210156108ad5761089c82610942565b82019150828060010193505061088b565b8293505050505b919050565b600080825160001a9050608060ff168110156108d957600091505061093d565b60b860ff168110806108fe575060c060ff1681101580156108fd575060f860ff1681105b5b1561090d57600191505061093d565b60c060ff1681101561092d5760018060b80360ff1682030191505061093d565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff1681101561096357600191506109f0565b60b860ff16811015610980576001608060ff1682030191506109ef565b60c060ff168110156109b05760b78103600185019450806020036101000a855104600182018101935050506109ee565b60f860ff168110156109cd57600160c060ff1682030191506109ed565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b6000811415610a0857610a5c565b5b602060ff168110610a385782518252602060ff1683019250602060ff1682019150602060ff1681039050610a09565b6000600182602060ff16036101000a03905080198451168184511681811785525050505b505050565b604051806040016040528060008152602001600081525090565b60405180604001604052806000815260200160008152509056fe417474656d7074696e6720746f2073796e63207374617465732066726f6d207468652070617374a265627a7a72315820dba46dd2ffc6ab680135ba772c3c3520365da762079ac66a151d80ff2bbb5c6a64736f6c63430005100032" }, "0000000000000000000000000000000000001010": { "balance": "0x204fce28085b549b31600000", diff --git a/consensus/bor/bor_test/helper.go b/consensus/bor/bor_test/helper.go index b59c3731fc..f95bf6cb05 100644 --- a/consensus/bor/bor_test/helper.go +++ b/consensus/bor/bor_test/helper.go @@ -156,6 +156,18 @@ func sign(t *testing.T, header *types.Header, signer []byte) { copy(header.Extra[len(header.Extra)-extraSeal:], sig) } +func zeroResultPayload(t *testing.T) *bor.ResponseWithHeight { + stateData, err := ioutil.ReadFile("states.json") + if err != nil { + t.Fatalf("%s", err) + } + res := &bor.ResponseWithHeight{} + if err := json.Unmarshal(stateData, res); err != nil { + t.Fatalf("%s", err) + } + return res +} + func loadSpanFromFile(t *testing.T) (*bor.ResponseWithHeight, *bor.HeimdallSpan) { spanData, err := ioutil.ReadFile("span.json") if err != nil { diff --git a/consensus/bor/bor_test/states.json b/consensus/bor/bor_test/states.json new file mode 100644 index 0000000000..809998ad90 --- /dev/null +++ b/consensus/bor/bor_test/states.json @@ -0,0 +1,23 @@ +{ + "height": "0", + "result": [ + { + "id": 1, + "contract": "0xb55969a6d60413a63291a1de572269875df541e3", + "data": "0x00000000000000000000000048aa8d4af32551892fcf08ad63be7dd206d46f6500000000000000000000000048aa8d4af32551892fcf08ad63be7dd206d46f65000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000014", + "tx_hash": "0x7b113e09d98b6d4be1dedfbc0746e34876de767f2cb8b58ff00160a160811dd6", + "log_index": 0, + "bor_chain_id": "15001", + "record_time": "2020-05-15T13:36:38.580995Z" + }, + { + "id": 2, + "contract": "0xb55969a6d60413a63291a1de572269875df541e3", + "data": "0x00000000000000000000000048aa8d4af32551892fcf08ad63be7dd206d46f6500000000000000000000000048aa8d4af32551892fcf08ad63be7dd206d46f65000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000015", + "tx_hash": "0xb72358aff8e4d61f4de97a37a40ddda986c081e0de8036e0a78c4b61b067cba9", + "log_index": 0, + "bor_chain_id": "15001", + "record_time": "2020-05-15T13:42:37.319058Z" + } + ] +} diff --git a/consensus/bor/clerk.go b/consensus/bor/clerk.go index adcbfb78b4..1c78b5fdd4 100644 --- a/consensus/bor/clerk.go +++ b/consensus/bor/clerk.go @@ -1,6 +1,9 @@ package bor import ( + "fmt" + "time" + "github.com/maticnetwork/bor/common" "github.com/maticnetwork/bor/common/hexutil" ) @@ -14,3 +17,33 @@ type EventRecord struct { LogIndex uint64 `json:"log_index" yaml:"log_index"` ChainID string `json:"bor_chain_id" yaml:"bor_chain_id"` } + +type EventRecordWithTime struct { + EventRecord + Time time.Time `json:"record_time" yaml:"record_time"` +} + +// String returns the string representatin of span +func (e *EventRecordWithTime) String() string { + return fmt.Sprintf( + "id %v, contract %v, data: %v, txHash: %v, logIndex: %v, chainId: %v, time %s", + e.ID, + e.Contract.String(), + e.Data.String(), + e.TxHash.Hex(), + e.LogIndex, + e.ChainID, + e.Time.Format(time.RFC3339), + ) +} + +func (e *EventRecordWithTime) BuildEventRecord() *EventRecord { + return &EventRecord{ + ID: e.ID, + Contract: e.Contract, + Data: e.Data, + TxHash: e.TxHash, + LogIndex: e.LogIndex, + ChainID: e.ChainID, + } +} diff --git a/consensus/bor/errors.go b/consensus/bor/errors.go index f357705db4..76d9a3ee22 100644 --- a/consensus/bor/errors.go +++ b/consensus/bor/errors.go @@ -2,6 +2,7 @@ package bor import ( "fmt" + "time" "github.com/maticnetwork/bor/common" ) @@ -142,3 +143,20 @@ func (e *WrongDifficultyError) Error() string { e.Signer, ) } + +type InvalidStateReceivedError struct { + Number uint64 + From *time.Time + To *time.Time + Event *EventRecordWithTime +} + +func (e *InvalidStateReceivedError) Error() string { + return fmt.Sprintf( + "Received event with invalid timestamp at block %d. Requested events from %s to %s. Received %s\n", + e.Number, + e.From.Format(time.RFC3339), + e.To.Format(time.RFC3339), + e.Event, + ) +} diff --git a/consensus/bor/genesis_contracts_client.go b/consensus/bor/genesis_contracts_client.go new file mode 100644 index 0000000000..3e2606c079 --- /dev/null +++ b/consensus/bor/genesis_contracts_client.go @@ -0,0 +1,108 @@ +package bor + +import ( + "context" + "math" + "math/big" + + // "math/big" + "strings" + "time" + + "github.com/maticnetwork/bor/accounts/abi" + "github.com/maticnetwork/bor/common" + "github.com/maticnetwork/bor/common/hexutil" + "github.com/maticnetwork/bor/core/state" + "github.com/maticnetwork/bor/core/types" + "github.com/maticnetwork/bor/internal/ethapi" + "github.com/maticnetwork/bor/log" + "github.com/maticnetwork/bor/params" + "github.com/maticnetwork/bor/rlp" + "github.com/maticnetwork/bor/rpc" +) + +type GenesisContractsClient struct { + validatorSetABI abi.ABI + stateReceiverABI abi.ABI + ValidatorContract string + StateReceiverContract string + chainConfig *params.ChainConfig + ethAPI *ethapi.PublicBlockChainAPI +} + +const validatorsetABI = `[{"constant":true,"inputs":[],"name":"SYSTEM_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"CHAIN","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FIRST_END_BLOCK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"producers","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ROUND_TYPE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"BOR_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"sprint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"spanNumbers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"VOTE_TYPE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"validators","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"spans","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"startBlock","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"endBlock","type":"uint256"}],"name":"NewSpan","type":"event"},{"constant":true,"inputs":[],"name":"currentSprint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"}],"name":"getSpan","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCurrentSpan","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNextSpan","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"number","type":"uint256"}],"name":"getSpanByBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"currentSpanNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"}],"name":"getValidatorsTotalStakeBySpan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"}],"name":"getProducersTotalStakeBySpan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"name":"getValidatorBySigner","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"internalType":"struct BorValidatorSet.Validator","name":"result","type":"tuple"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"name":"isValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"name":"isProducer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"isCurrentValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"isCurrentProducer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"number","type":"uint256"}],"name":"getBorValidators","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitialValidators","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getValidators","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"newSpan","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"},{"internalType":"bytes","name":"validatorBytes","type":"bytes"},{"internalType":"bytes","name":"producerBytes","type":"bytes"}],"name":"commitSpan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"bytes32","name":"dataHash","type":"bytes32"},{"internalType":"bytes","name":"sigs","type":"bytes"}],"name":"getStakePowerBySigs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"internalType":"bytes32","name":"leaf","type":"bytes32"},{"internalType":"bytes","name":"proof","type":"bytes"}],"name":"checkMembership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"d","type":"bytes32"}],"name":"leafNode","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"left","type":"bytes32"},{"internalType":"bytes32","name":"right","type":"bytes32"}],"name":"innerNode","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"}]` +const stateReceiverABI = `[{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"states","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SYSTEM_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastStateSyncTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes","name":"recordBytes","type":"bytes"},{"internalType":"uint256","name":"syncTime","type":"uint256"}],"name":"commitState","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]` + +func NewGenesisContractsClient( + chainConfig *params.ChainConfig, + validatorContract, + stateReceiverContract string, + ethAPI *ethapi.PublicBlockChainAPI, +) *GenesisContractsClient { + vABI, _ := abi.JSON(strings.NewReader(validatorsetABI)) + sABI, _ := abi.JSON(strings.NewReader(stateReceiverABI)) + return &GenesisContractsClient{ + validatorSetABI: vABI, + stateReceiverABI: sABI, + ValidatorContract: validatorContract, + StateReceiverContract: stateReceiverContract, + chainConfig: chainConfig, + ethAPI: ethAPI, + } +} + +func (gc *GenesisContractsClient) CommitState( + event *EventRecordWithTime, + state *state.StateDB, + header *types.Header, + chCtx chainContext, +) error { + eventRecord := event.BuildEventRecord() + recordBytes, err := rlp.EncodeToBytes(eventRecord) + if err != nil { + return err + } + method := "commitState" + t := event.Time.Unix() + data, err := gc.stateReceiverABI.Pack(method, recordBytes, big.NewInt(0).SetInt64(t)) + // t, err := time.Parse(event.Time, time.RFC3339) + // data, err := gc.stateReceiverABI.Pack(method, recordBytes, t.Unix()) + if err != nil { + log.Error("Unable to pack tx for commitState", "error", err) + return err + } + log.Info("→ committing new state", "eventRecord", event.String()) + msg := getSystemMessage(common.HexToAddress(gc.StateReceiverContract), data) + if err := applyMessage(msg, state, header, gc.chainConfig, chCtx); err != nil { + return err + } + return nil +} + +func (gc *GenesisContractsClient) LastStateSyncTime(snapshotNumber uint64) (*time.Time, error) { + method := "lastStateSyncTime" + data, err := gc.stateReceiverABI.Pack(method) + if err != nil { + log.Error("Unable to pack tx for getLastSyncTime", "error", err) + return nil, err + } + + msgData := (hexutil.Bytes)(data) + toAddress := common.HexToAddress(gc.StateReceiverContract) + gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2)) + result, err := gc.ethAPI.Call(context.Background(), ethapi.CallArgs{ + Gas: &gas, + To: &toAddress, + Data: &msgData, + }, rpc.BlockNumber(snapshotNumber)) + if err != nil { + return nil, err + } + + var ret = new(*big.Int) + if err := gc.stateReceiverABI.Unpack(ret, method, result); err != nil { + return nil, err + } + _time := time.Unix((*ret).Int64(), 0) + return &_time, nil +} From 4be5477f642a17abefaa4da655e741f7663954ee Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Sun, 17 May 2020 17:28:55 +0530 Subject: [PATCH 26/46] dev: cleanup comments --- consensus/bor/bor.go | 4 ---- consensus/bor/bor_test/bor_test.go | 4 +--- consensus/bor/bor_test/helper.go | 2 +- consensus/bor/genesis_contracts_client.go | 3 --- 4 files changed, 2 insertions(+), 11 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 4b2b9b59f3..03fddbf5d5 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -1118,10 +1118,6 @@ func (c *Bor) CommitStates( chain chainContext, ) error { number := header.Number.Uint64() - if number < c.config.Sprint { - return errors.New("Requested to commit states too soon") - } - lastSync, err := c.genesisContractsClient.LastStateSyncTime(number - 1) if err != nil { return err diff --git a/consensus/bor/bor_test/bor_test.go b/consensus/bor/bor_test/bor_test.go index 9502812622..72b40d9560 100644 --- a/consensus/bor/bor_test/bor_test.go +++ b/consensus/bor/bor_test/bor_test.go @@ -3,8 +3,6 @@ package bortest import ( "encoding/hex" "fmt" - // "encoding/json" - // "fmt" "math/big" "testing" @@ -165,7 +163,7 @@ func getMockedHeimdallClient(t *testing.T) (*mocks.IHeimdallClient, *bor.Heimdal h := &mocks.IHeimdallClient{} h.On("FetchWithRetry", "bor", "span", "1").Return(res, nil) - res = zeroResultPayload(t) + res = stateSyncEventsPayload(t) // query := fmt.Sprintf("clerk/event-record/list?from-time=%d&to-time=%d&page=1&limit=50", 1, 1589709047) h.On("FetchWithRetry", mock.AnythingOfType("string")).Return(res, nil) return h, heimdallSpan diff --git a/consensus/bor/bor_test/helper.go b/consensus/bor/bor_test/helper.go index f95bf6cb05..d02c3463fc 100644 --- a/consensus/bor/bor_test/helper.go +++ b/consensus/bor/bor_test/helper.go @@ -156,7 +156,7 @@ func sign(t *testing.T, header *types.Header, signer []byte) { copy(header.Extra[len(header.Extra)-extraSeal:], sig) } -func zeroResultPayload(t *testing.T) *bor.ResponseWithHeight { +func stateSyncEventsPayload(t *testing.T) *bor.ResponseWithHeight { stateData, err := ioutil.ReadFile("states.json") if err != nil { t.Fatalf("%s", err) diff --git a/consensus/bor/genesis_contracts_client.go b/consensus/bor/genesis_contracts_client.go index 3e2606c079..d616c6f12e 100644 --- a/consensus/bor/genesis_contracts_client.go +++ b/consensus/bor/genesis_contracts_client.go @@ -5,7 +5,6 @@ import ( "math" "math/big" - // "math/big" "strings" "time" @@ -65,8 +64,6 @@ func (gc *GenesisContractsClient) CommitState( method := "commitState" t := event.Time.Unix() data, err := gc.stateReceiverABI.Pack(method, recordBytes, big.NewInt(0).SetInt64(t)) - // t, err := time.Parse(event.Time, time.RFC3339) - // data, err := gc.stateReceiverABI.Pack(method, recordBytes, t.Unix()) if err != nil { log.Error("Unable to pack tx for commitState", "error", err) return err From 9a56de6d84c7a28bb4c9e308622070058045901b Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Sun, 17 May 2020 17:33:59 +0530 Subject: [PATCH 27/46] dev: cleanup isValidatorAction logic --- consensus/bor/bor.go | 20 ---------- consensus/bor/bor_test/bor_test.go | 60 +----------------------------- consensus/consensus.go | 1 - core/tx_pool.go | 1 - 4 files changed, 2 insertions(+), 80 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 03fddbf5d5..43ebe93fd4 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -1204,26 +1204,6 @@ func (c *Bor) SetHeimdallClient(h IHeimdallClient) { c.HeimdallClient = h } -func (c *Bor) IsValidatorAction(chain consensus.ChainReader, from common.Address, tx *types.Transaction) bool { - header := chain.CurrentHeader() - validators, err := c.GetCurrentValidators(header.Number.Uint64(), header.Number.Uint64()+1) - if err != nil { - log.Error("Failed fetching snapshot", err) - return false - } - - isValidator := false - for _, validator := range validators { - if bytes.Compare(validator.Address.Bytes(), from.Bytes()) == 0 { - isValidator = true - break - } - } - - return isValidator && (isProposeSpanAction(tx, chain.Config().Bor.ValidatorContract) || - isProposeStateAction(tx, chain.Config().Bor.StateReceiverContract)) -} - func isProposeSpanAction(tx *types.Transaction, validatorContract string) bool { // keccak256('proposeSpan()').slice(0, 4) proposeSpanSig, _ := hex.DecodeString("4b0e4d17") diff --git a/consensus/bor/bor_test/bor_test.go b/consensus/bor/bor_test/bor_test.go index 72b40d9560..56b2e38f8a 100644 --- a/consensus/bor/bor_test/bor_test.go +++ b/consensus/bor/bor_test/bor_test.go @@ -6,7 +6,6 @@ import ( "math/big" "testing" - "github.com/maticnetwork/bor/common" "github.com/maticnetwork/bor/consensus/bor" "github.com/maticnetwork/bor/core/rawdb" "github.com/maticnetwork/bor/crypto" @@ -18,7 +17,7 @@ import ( "github.com/maticnetwork/bor/mocks" ) -func TestCommitSpan(t *testing.T) { +func TestInsertingSpanSizeBlocks(t *testing.T) { init := buildEthereumInstance(t, rawdb.NewMemoryDatabase()) chain := init.ethereum.BlockChain() engine := init.ethereum.Engine() @@ -31,7 +30,7 @@ func TestCommitSpan(t *testing.T) { var to int64 // Insert sprintSize # of blocks so that span is fetched at the start of a new sprint - for i := uint64(1); i <= sprintSize; i++ { + for i := uint64(1); i <= spanSize; i++ { block = buildNextBlock(t, _bor, chain, block, nil, init.genesis.Config.Bor) insertNewBlock(t, chain, block) if i == sprintSize-1 { @@ -55,61 +54,6 @@ func TestCommitSpan(t *testing.T) { } } -func TestIsValidatorAction(t *testing.T) { - init := buildEthereumInstance(t, rawdb.NewMemoryDatabase()) - chain := init.ethereum.BlockChain() - engine := init.ethereum.Engine() - _bor := engine.(*bor.Bor) - h, heimdallSpan := getMockedHeimdallClient(t) - _bor.SetHeimdallClient(h) - - proposeStateData, _ := hex.DecodeString("ede01f170000000000000000000000000000000000000000000000000000000000000000") - proposeSpanData, _ := hex.DecodeString("4b0e4d17") - var tx *types.Transaction - tx = types.NewTransaction( - 0, - common.HexToAddress(chain.Config().Bor.StateReceiverContract), - big.NewInt(0), 0, big.NewInt(0), - proposeStateData, - ) - assert.True(t, _bor.IsValidatorAction(chain, addr, tx)) - - tx = types.NewTransaction( - 0, - common.HexToAddress(chain.Config().Bor.ValidatorContract), - big.NewInt(0), 0, big.NewInt(0), - proposeSpanData, - ) - assert.True(t, _bor.IsValidatorAction(chain, addr, tx)) - - db := init.ethereum.ChainDb() - block := init.genesis.ToBlock(db) - - for i := uint64(1); i <= spanSize; i++ { - block = buildNextBlock(t, _bor, chain, block, nil, init.genesis.Config.Bor) - insertNewBlock(t, chain, block) - } - - for _, validator := range heimdallSpan.SelectedProducers { - _addr := validator.Address - tx = types.NewTransaction( - 0, - common.HexToAddress(chain.Config().Bor.StateReceiverContract), - big.NewInt(0), 0, big.NewInt(0), - proposeStateData, - ) - assert.True(t, _bor.IsValidatorAction(chain, _addr, tx)) - - tx = types.NewTransaction( - 0, - common.HexToAddress(chain.Config().Bor.ValidatorContract), - big.NewInt(0), 0, big.NewInt(0), - proposeSpanData, - ) - assert.True(t, _bor.IsValidatorAction(chain, _addr, tx)) - } -} - func TestOutOfTurnSigning(t *testing.T) { init := buildEthereumInstance(t, rawdb.NewMemoryDatabase()) chain := init.ethereum.BlockChain() diff --git a/consensus/consensus.go b/consensus/consensus.go index 0620cff059..689c840dae 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -119,7 +119,6 @@ type Engine interface { // Bor is a consensus engine developed by folks at Matic Network type Bor interface { Engine - IsValidatorAction(chain ChainReader, from common.Address, tx *types.Transaction) bool CancelActiveSealingOp() } diff --git a/core/tx_pool.go b/core/tx_pool.go index 1462c2324e..a1822ec54a 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -531,7 +531,6 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { // Drop non-local transactions under our own minimal accepted gas price local = local || pool.locals.contains(from) // account may be local even if the transaction arrived from the network if !local && - !pool.chain.Engine().(consensus.Bor).IsValidatorAction(pool.chain.(consensus.ChainReader), from, tx) && pool.gasPrice.Cmp(tx.GasPrice()) > 0 { return ErrUnderpriced } From 8dea9114e863c098d45a25cb75b107de75b5f94a Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Sun, 17 May 2020 17:44:44 +0530 Subject: [PATCH 28/46] dev: update changes in StateReceiver contract --- consensus/bor/bor_test/genesis.json | 4 ++-- consensus/bor/genesis_contracts_client.go | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/consensus/bor/bor_test/genesis.json b/consensus/bor/bor_test/genesis.json index 7c70393591..8842554c3e 100644 --- a/consensus/bor/bor_test/genesis.json +++ b/consensus/bor/bor_test/genesis.json @@ -27,11 +27,11 @@ "alloc": { "0000000000000000000000000000000000001000": { "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b50600436106101f05760003560e01c806365b3a1e21161010f578063b2472431116100a2578063d5b844eb11610071578063d5b844eb14610666578063dcf2793a14610684578063e3b7c924146106b6578063f59cf565146106d4576101f0565b8063b2472431146105c9578063b71d7a69146105e7578063b7ab4db514610617578063c1b3c91914610636576101f0565b806398ab2b62116100de57806398ab2b621461053d5780639d11b8071461055b578063ae7564511461058b578063af26aa96146105a9576101f0565b806365b3a1e21461049e57806366332354146104bd578063687a9bd6146104db57806370ba57071461050d576101f0565b806335ddfeea116101875780634dbc959f116101565780634dbc959f1461040057806355614fcc1461041e578063582a8d081461044e57806360c8614d1461047e576101f0565b806335ddfeea1461035257806343ee82131461038257806344c15cb1146103a057806344d6528f146103d0576101f0565b806323f2a73f116101c357806323f2a73f146102a45780632de3a180146102d45780632eddf352146103045780633434735f14610334576101f0565b8063047a6c5b146101f55780630c35b1cb146102275780631270b5741461025857806323c2a2b414610288575b600080fd5b61020f600480360361020a919081019061290d565b610706565b60405161021e939291906131ec565b60405180910390f35b610241600480360361023c919081019061290d565b61075d565b60405161024f92919061302d565b60405180910390f35b610272600480360361026d9190810190612936565b610939565b60405161027f9190613064565b60405180910390f35b6102a2600480360361029d9190810190612a15565b610a91565b005b6102be60048036036102b99190810190612936565b6110f4565b6040516102cb9190613064565b60405180910390f35b6102ee60048036036102e9919081019061286a565b61124b565b6040516102fb919061307f565b60405180910390f35b61031e6004803603610319919081019061290d565b6112cc565b60405161032b919061319a565b60405180910390f35b61033c6113fc565b6040516103499190613012565b60405180910390f35b61036c600480360361036791908101906128a6565b611414565b6040516103799190613064565b60405180910390f35b61038a6114df565b604051610397919061307f565b60405180910390f35b6103ba60048036036103b59190810190612972565b6114f6565b6040516103c7919061319a565b60405180910390f35b6103ea60048036036103e59190810190612936565b6115de565b6040516103f7919061317f565b60405180910390f35b610408611746565b604051610415919061319a565b60405180910390f35b610438600480360361043391908101906127ef565b611756565b6040516104459190613064565b60405180910390f35b61046860048036036104639190810190612818565b611770565b604051610475919061307f565b60405180910390f35b6104866117ee565b604051610495939291906131ec565b60405180910390f35b6104a6611862565b6040516104b492919061302d565b60405180910390f35b6104c5611952565b6040516104d2919061319a565b60405180910390f35b6104f560048036036104f091908101906129d9565b611957565b604051610504939291906131b5565b60405180910390f35b610527600480360361052291908101906127ef565b6119bb565b6040516105349190613064565b60405180910390f35b6105456119d5565b604051610552919061307f565b60405180910390f35b6105756004803603610570919081019061290d565b6119ec565b604051610582919061319a565b60405180910390f35b610593611b1d565b6040516105a0919061307f565b60405180910390f35b6105b1611b34565b6040516105c0939291906131ec565b60405180910390f35b6105d1611b95565b6040516105de919061319a565b60405180910390f35b61060160048036036105fc919081019061290d565b611b9a565b60405161060e919061319a565b60405180910390f35b61061f611c9a565b60405161062d92919061302d565b60405180910390f35b610650600480360361064b919081019061290d565b611cae565b60405161065d919061319a565b60405180910390f35b61066e611ccf565b60405161067b9190613223565b60405180910390f35b61069e600480360361069991908101906129d9565b611cd4565b6040516106ad939291906131b5565b60405180910390f35b6106be611d38565b6040516106cb919061319a565b60405180910390f35b6106ee60048036036106e9919081019061290d565b611d4a565b6040516106fd939291906131ec565b60405180910390f35b60008060006002600085815260200190815260200160002060000154600260008681526020019081526020016000206001015460026000878152602001908152602001600020600201549250925092509193909250565b6060806007831161077957610770611862565b91509150610934565b600061078484611b9a565b9050606060016000838152602001908152602001600020805490506040519080825280602002602001820160405280156107cd5781602001602082028038833980820191505090505b509050606060016000848152602001908152602001600020805490506040519080825280602002602001820160405280156108175781602001602082028038833980820191505090505b50905060008090505b60016000858152602001908152602001600020805490508110156109295760016000858152602001908152602001600020818154811061085c57fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683828151811061089a57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506001600085815260200190815260200160002081815481106108f257fe5b90600052602060002090600302016001015482828151811061091057fe5b6020026020010181815250508080600101915050610820565b508181945094505050505b915091565b6000606060016000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015610a0c578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190610970565b50505050905060008090505b8151811015610a84578373ffffffffffffffffffffffffffffffffffffffff16828281518110610a4457fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff161415610a7757600192505050610a8b565b8080600101915050610a18565b5060009150505b92915050565b73fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610add57600080fd5b6000610ae7611746565b90506000811415610afb57610afa611d74565b5b610b0f60018261209590919063ffffffff16565b8814610b50576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b47906130ff565b60405180910390fd5b868611610b92576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b899061315f565b60405180910390fd5b6000600460018989030181610ba357fe5b0614610be4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bdb9061313f565b60405180910390fd5b8660026000838152602001908152602001600020600101541115610c3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c34906130df565b60405180910390fd5b6000600260008a81526020019081526020016000206000015414610c96576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c8d9061311f565b60405180910390fd5b604051806060016040528089815260200188815260200187815250600260008a8152602001908152602001600020600082015181600001556020820151816001015560408201518160020155905050600388908060018154018082558091505090600182039060005260206000200160009091929091909150555060008060008a815260200190815260200160002081610d3091906125e9565b506000600160008a815260200190815260200160002081610d5191906125e9565b506060610da9610da487878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506120b4565b6120e2565b905060008090505b8151811015610f1b576060610dd8838381518110610dcb57fe5b60200260200101516120e2565b90506000808c81526020019081526020016000208054809190600101610dfe91906125e9565b506040518060600160405280610e2783600081518110610e1a57fe5b60200260200101516121bf565b8152602001610e4983600181518110610e3c57fe5b60200260200101516121bf565b8152602001610e6b83600281518110610e5e57fe5b6020026020010151612230565b73ffffffffffffffffffffffffffffffffffffffff168152506000808d81526020019081526020016000208381548110610ea157fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050508080600101915050610db1565b506060610f73610f6e86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506120b4565b6120e2565b905060008090505b81518110156110e7576060610fa2838381518110610f9557fe5b60200260200101516120e2565b9050600160008d81526020019081526020016000208054809190600101610fc991906125e9565b506040518060600160405280610ff283600081518110610fe557fe5b60200260200101516121bf565b81526020016110148360018151811061100757fe5b60200260200101516121bf565b81526020016110368360028151811061102957fe5b6020026020010151612230565b73ffffffffffffffffffffffffffffffffffffffff16815250600160008e8152602001908152602001600020838154811061106d57fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050508080600101915050610f7b565b5050505050505050505050565b60006060600080858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156111c6578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250508152602001906001019061112a565b50505050905060008090505b815181101561123e578373ffffffffffffffffffffffffffffffffffffffff168282815181106111fe57fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff16141561123157600192505050611245565b80806001019150506111d2565b5060009150505b92915050565b60006002600160f81b848460405160200161126893929190612f7f565b6040516020818303038152906040526040516112849190612fbc565b602060405180830381855afa1580156112a1573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506112c49190810190612841565b905092915050565b60006060600080848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561139e578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611302565b505050509050600080905060008090505b82518110156113f1576113e28382815181106113c757fe5b6020026020010151602001518361209590919063ffffffff16565b915080806001019150506113af565b508092505050919050565b73fffffffffffffffffffffffffffffffffffffffe81565b600080600080859050600060218087518161142b57fe5b0402905060008111156114445761144187611770565b91505b6000602190505b8181116114ce5760006001820388015190508188015195508060006020811061147057fe5b1a60f81b9450600060f81b857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156114b5576114ae868561124b565b93506114c2565b6114bf848761124b565b93505b5060218101905061144b565b508782149450505050509392505050565b6040516114eb90612fe8565b604051809103902081565b60008060009050600080905060008090505b84518167ffffffffffffffff1610156115d1576060611533868367ffffffffffffffff166041612253565b9050600061154a82896122df90919063ffffffff16565b905061155461261b565b61155e8a836115de565b905061156a8a836110f4565b80156115a157508473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16115b156115c3578194506115c081602001518761209590919063ffffffff16565b95505b505050604181019050611508565b5081925050509392505050565b6115e661261b565b6060600080858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156116b6578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250508152602001906001019061161a565b50505050905060008090505b815181101561173e578373ffffffffffffffffffffffffffffffffffffffff168282815181106116ee57fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff1614156117315781818151811061172257fe5b6020026020010151925061173e565b80806001019150506116c2565b505092915050565b600061175143611b9a565b905090565b6000611769611763611746565b836110f4565b9050919050565b60006002600060f81b8360405160200161178b929190612f53565b6040516020818303038152906040526040516117a79190612fbc565b602060405180830381855afa1580156117c4573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506117e79190810190612841565b9050919050565b60008060008061180f6001611801611746565b61209590919063ffffffff16565b905060026000828152602001908152602001600020600001546002600083815260200190815260200160002060010154600260008481526020019081526020016000206002015493509350935050909192565b606080606060016040519080825280602002602001820160405280156118975781602001602082028038833980820191505090505b5090507371562b71999873db5b286df957af199ec94617f7816000815181106118bc57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050606060016040519080825280602002602001820160405280156119285781602001602082028038833980820191505090505b509050600a8160008151811061193a57fe5b60200260200101818152505081819350935050509091565b600781565b6001602052816000526040600020818154811061197057fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b60006119ce6119c8611746565b83610939565b9050919050565b6040516119e190612fd3565b604051809103902081565b6000606060016000848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015611abf578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611a23565b505050509050600080905060008090505b8251811015611b1257611b03838281518110611ae857fe5b6020026020010151602001518361209590919063ffffffff16565b91508080600101915050611ad0565b508092505050919050565b604051611b2990612ffd565b604051809103902081565b600080600080611b42611746565b905060026000828152602001908152602001600020600001546002600083815260200190815260200160002060010154600260008481526020019081526020016000206002015493509350935050909192565b600481565b60008060038054905090505b6000811115611c5a57611bb7612652565b6002600060036001850381548110611bcb57fe5b906000526020600020015481526020019081526020016000206040518060600160405290816000820154815260200160018201548152602001600282015481525050905083816020015111158015611c2857506000816040015114155b8015611c38575080604001518411155b15611c4b57806000015192505050611c95565b50808060019003915050611ba6565b5060006003805490501115611c9057600360016003805490500381548110611c7e57fe5b90600052602060002001549050611c95565b600090505b919050565b606080611ca64361075d565b915091509091565b60038181548110611cbb57fe5b906000526020600020016000915090505481565b600281565b60006020528160005260406000208181548110611ced57fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b600060404381611d4457fe5b04905090565b60026020528060005260406000206000915090508060000154908060010154908060020154905083565b606080611d7f611862565b809250819350505060008090506040518060600160405280828152602001600081526020016007815250600260008381526020019081526020016000206000820151816000015560208201518160010155604082015181600201559050506003819080600181540180825580915050906001820390600052602060002001600090919290919091505550600080600083815260200190815260200160002081611e2891906125e9565b5060006001600083815260200190815260200160002081611e4991906125e9565b5060008090505b8351811015611f6b576000808381526020019081526020016000208054809190600101611e7d91906125e9565b506040518060600160405280828152602001848381518110611e9b57fe5b60200260200101518152602001858381518110611eb457fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff168152506000808481526020019081526020016000208281548110611ef257fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050508080600101915050611e50565b5060008090505b835181101561208f57600160008381526020019081526020016000208054809190600101611fa091906125e9565b506040518060600160405280828152602001848381518110611fbe57fe5b60200260200101518152602001858381518110611fd757fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681525060016000848152602001908152602001600020828154811061201657fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050508080600101915050611f72565b50505050565b6000808284019050838110156120aa57600080fd5b8091505092915050565b6120bc612673565b600060208301905060405180604001604052808451815260200182815250915050919050565b60606120ed826123e9565b6120f657600080fd5b600061210183612437565b905060608160405190808252806020026020018201604052801561213f57816020015b61212c61268d565b8152602001906001900390816121245790505b509050600061215185602001516124a8565b8560200151019050600080600090505b848110156121b25761217283612531565b915060405180604001604052808381526020018481525084828151811061219557fe5b602002602001018190525081830192508080600101915050612161565b5082945050505050919050565b60008082600001511180156121d957506021826000015111155b6121e257600080fd5b60006121f183602001516124a8565b9050600081846000015103905060008083866020015101905080519150602083101561222457826020036101000a820491505b81945050505050919050565b6000601582600001511461224357600080fd5b61224c826121bf565b9050919050565b60608183018451101561226557600080fd5b6060821560008114612282576040519150602082016040526122d3565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156122c057805183526020830192506020810190506122a3565b50868552601f19601f8301166040525050505b50809150509392505050565b60008060008060418551146122fa57600093505050506123e3565b602085015192506040850151915060ff6041860151169050601b8160ff16101561232557601b810190505b601b8160ff161415801561233d5750601c8160ff1614155b1561234e57600093505050506123e3565b600060018783868660405160008152602001604052604051612373949392919061309a565b6020604051602081039080840390855afa158015612395573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156123db57600080fd5b809450505050505b92915050565b600080826000015114156124005760009050612432565b60008083602001519050805160001a915060c060ff168260ff16101561242b57600092505050612432565b6001925050505b919050565b6000808260000151141561244e57600090506124a3565b6000809050600061246284602001516124a8565b84602001510190506000846000015185602001510190505b8082101561249c5761248b82612531565b82019150828060010193505061247a565b8293505050505b919050565b600080825160001a9050608060ff168110156124c857600091505061252c565b60b860ff168110806124ed575060c060ff1681101580156124ec575060f860ff1681105b5b156124fc57600191505061252c565b60c060ff1681101561251c5760018060b80360ff1682030191505061252c565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff1681101561255257600191506125df565b60b860ff1681101561256f576001608060ff1682030191506125de565b60c060ff1681101561259f5760b78103600185019450806020036101000a855104600182018101935050506125dd565b60f860ff168110156125bc57600160c060ff1682030191506125dc565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b8154818355818111156126165760030281600302836000526020600020918201910161261591906126a7565b5b505050565b60405180606001604052806000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b60405180606001604052806000815260200160008152602001600081525090565b604051806040016040528060008152602001600081525090565b604051806040016040528060008152602001600081525090565b6126fa91905b808211156126f65760008082016000905560018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055506003016126ad565b5090565b90565b60008135905061270c8161341c565b92915050565b60008135905061272181613433565b92915050565b60008151905061273681613433565b92915050565b60008083601f84011261274e57600080fd5b8235905067ffffffffffffffff81111561276757600080fd5b60208301915083600182028301111561277f57600080fd5b9250929050565b600082601f83011261279757600080fd5b81356127aa6127a58261326b565b61323e565b915080825260208301602083018583830111156127c657600080fd5b6127d18382846133c6565b50505092915050565b6000813590506127e98161344a565b92915050565b60006020828403121561280157600080fd5b600061280f848285016126fd565b91505092915050565b60006020828403121561282a57600080fd5b600061283884828501612712565b91505092915050565b60006020828403121561285357600080fd5b600061286184828501612727565b91505092915050565b6000806040838503121561287d57600080fd5b600061288b85828601612712565b925050602061289c85828601612712565b9150509250929050565b6000806000606084860312156128bb57600080fd5b60006128c986828701612712565b93505060206128da86828701612712565b925050604084013567ffffffffffffffff8111156128f757600080fd5b61290386828701612786565b9150509250925092565b60006020828403121561291f57600080fd5b600061292d848285016127da565b91505092915050565b6000806040838503121561294957600080fd5b6000612957858286016127da565b9250506020612968858286016126fd565b9150509250929050565b60008060006060848603121561298757600080fd5b6000612995868287016127da565b93505060206129a686828701612712565b925050604084013567ffffffffffffffff8111156129c357600080fd5b6129cf86828701612786565b9150509250925092565b600080604083850312156129ec57600080fd5b60006129fa858286016127da565b9250506020612a0b858286016127da565b9150509250929050565b600080600080600080600060a0888a031215612a3057600080fd5b6000612a3e8a828b016127da565b9750506020612a4f8a828b016127da565b9650506040612a608a828b016127da565b955050606088013567ffffffffffffffff811115612a7d57600080fd5b612a898a828b0161273c565b9450945050608088013567ffffffffffffffff811115612aa857600080fd5b612ab48a828b0161273c565b925092505092959891949750929550565b6000612ad18383612af5565b60208301905092915050565b6000612ae98383612f26565b60208301905092915050565b612afe8161333b565b82525050565b612b0d8161333b565b82525050565b6000612b1e826132b7565b612b2881856132f2565b9350612b3383613297565b8060005b83811015612b64578151612b4b8882612ac5565b9750612b56836132d8565b925050600181019050612b37565b5085935050505092915050565b6000612b7c826132c2565b612b868185613303565b9350612b91836132a7565b8060005b83811015612bc2578151612ba98882612add565b9750612bb4836132e5565b925050600181019050612b95565b5085935050505092915050565b612bd88161334d565b82525050565b612bef612bea82613359565b613408565b82525050565b612bfe81613385565b82525050565b612c15612c1082613385565b613412565b82525050565b6000612c26826132cd565b612c308185613314565b9350612c408185602086016133d5565b80840191505092915050565b6000612c59600483613330565b91507f766f7465000000000000000000000000000000000000000000000000000000006000830152600482019050919050565b6000612c99602d8361331f565b91507f537461727420626c6f636b206d7573742062652067726561746572207468616e60008301527f2063757272656e74207370616e000000000000000000000000000000000000006020830152604082019050919050565b6000612cff600f8361331f565b91507f496e76616c6964207370616e20696400000000000000000000000000000000006000830152602082019050919050565b6000612d3f60138361331f565b91507f5370616e20616c726561647920657869737473000000000000000000000000006000830152602082019050919050565b6000612d7f60458361331f565b91507f446966666572656e6365206265747765656e20737461727420616e6420656e6460008301527f20626c6f636b206d75737420626520696e206d756c7469706c6573206f66207360208301527f7072696e740000000000000000000000000000000000000000000000000000006040830152606082019050919050565b6000612e0b602a8361331f565b91507f456e6420626c6f636b206d7573742062652067726561746572207468616e207360008301527f7461727420626c6f636b000000000000000000000000000000000000000000006020830152604082019050919050565b6000612e71600e83613330565b91507f6865696d64616c6c2d31353030310000000000000000000000000000000000006000830152600e82019050919050565b6000612eb1600583613330565b91507f31353030310000000000000000000000000000000000000000000000000000006000830152600582019050919050565b606082016000820151612efa6000850182612f26565b506020820151612f0d6020850182612f26565b506040820151612f206040850182612af5565b50505050565b612f2f816133af565b82525050565b612f3e816133af565b82525050565b612f4d816133b9565b82525050565b6000612f5f8285612bde565b600182019150612f6f8284612c04565b6020820191508190509392505050565b6000612f8b8286612bde565b600182019150612f9b8285612c04565b602082019150612fab8284612c04565b602082019150819050949350505050565b6000612fc88284612c1b565b915081905092915050565b6000612fde82612c4c565b9150819050919050565b6000612ff382612e64565b9150819050919050565b600061300882612ea4565b9150819050919050565b60006020820190506130276000830184612b04565b92915050565b600060408201905081810360008301526130478185612b13565b9050818103602083015261305b8184612b71565b90509392505050565b60006020820190506130796000830184612bcf565b92915050565b60006020820190506130946000830184612bf5565b92915050565b60006080820190506130af6000830187612bf5565b6130bc6020830186612f44565b6130c96040830185612bf5565b6130d66060830184612bf5565b95945050505050565b600060208201905081810360008301526130f881612c8c565b9050919050565b6000602082019050818103600083015261311881612cf2565b9050919050565b6000602082019050818103600083015261313881612d32565b9050919050565b6000602082019050818103600083015261315881612d72565b9050919050565b6000602082019050818103600083015261317881612dfe565b9050919050565b60006060820190506131946000830184612ee4565b92915050565b60006020820190506131af6000830184612f35565b92915050565b60006060820190506131ca6000830186612f35565b6131d76020830185612f35565b6131e46040830184612b04565b949350505050565b60006060820190506132016000830186612f35565b61320e6020830185612f35565b61321b6040830184612f35565b949350505050565b60006020820190506132386000830184612f44565b92915050565b6000604051905081810181811067ffffffffffffffff8211171561326157600080fd5b8060405250919050565b600067ffffffffffffffff82111561328257600080fd5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b60006133468261338f565b9050919050565b60008115159050919050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b82818337600083830152505050565b60005b838110156133f35780820151818401526020810190506133d8565b83811115613402576000848401525b50505050565b6000819050919050565b6000819050919050565b6134258161333b565b811461343057600080fd5b50565b61343c81613385565b811461344757600080fd5b50565b613453816133af565b811461345e57600080fd5b5056fea365627a7a72315820aa6f542f997439d335795efc14d8a210d40bbd537d8b923d22efa48a1f756b6d6c6578706572696d656e74616cf564736f6c63430005100040" + "code": "0x608060405234801561001057600080fd5b50600436106101f05760003560e01c806360c8614d1161010f578063af26aa96116100a2578063d5b844eb11610071578063d5b844eb14610666578063dcf2793a14610684578063e3b7c924146106b6578063f59cf565146106d4576101f0565b8063af26aa96146105c7578063b71d7a69146105e7578063b7ab4db514610617578063c1b3c91914610636576101f0565b806370ba5707116100de57806370ba57071461052b57806398ab2b621461055b5780639d11b80714610579578063ae756451146105a9576101f0565b806360c8614d1461049c57806365b3a1e2146104bc57806366332354146104db578063687a9bd6146104f9576101f0565b80633434735f1161018757806344d6528f1161015657806344d6528f146103ee5780634dbc959f1461041e57806355614fcc1461043c578063582a8d081461046c576101f0565b80633434735f1461035257806335ddfeea1461037057806343ee8213146103a057806344c15cb1146103be576101f0565b806323f2a73f116101c357806323f2a73f146102a45780632bc06564146102d45780632de3a180146102f25780632eddf35214610322576101f0565b8063047a6c5b146101f55780630c35b1cb146102275780631270b5741461025857806323c2a2b414610288575b600080fd5b61020f600480360361020a919081019061290d565b610706565b60405161021e939291906131ec565b60405180910390f35b610241600480360361023c919081019061290d565b61075d565b60405161024f92919061302d565b60405180910390f35b610272600480360361026d9190810190612936565b610939565b60405161027f9190613064565b60405180910390f35b6102a2600480360361029d9190810190612a15565b610a91565b005b6102be60048036036102b99190810190612936565b6110f4565b6040516102cb9190613064565b60405180910390f35b6102dc61124b565b6040516102e9919061319a565b60405180910390f35b61030c6004803603610307919081019061286a565b611250565b604051610319919061307f565b60405180910390f35b61033c6004803603610337919081019061290d565b6112d1565b604051610349919061319a565b60405180910390f35b61035a611401565b6040516103679190613012565b60405180910390f35b61038a600480360361038591908101906128a6565b611419565b6040516103979190613064565b60405180910390f35b6103a86114e4565b6040516103b5919061307f565b60405180910390f35b6103d860048036036103d39190810190612972565b6114fb565b6040516103e5919061319a565b60405180910390f35b61040860048036036104039190810190612936565b6115e3565b604051610415919061317f565b60405180910390f35b61042661174b565b604051610433919061319a565b60405180910390f35b610456600480360361045191908101906127ef565b61175b565b6040516104639190613064565b60405180910390f35b61048660048036036104819190810190612818565b611775565b604051610493919061307f565b60405180910390f35b6104a46117f3565b6040516104b3939291906131ec565b60405180910390f35b6104c4611867565b6040516104d292919061302d565b60405180910390f35b6104e3611957565b6040516104f0919061319a565b60405180910390f35b610513600480360361050e91908101906129d9565b61195c565b604051610522939291906131b5565b60405180910390f35b610545600480360361054091908101906127ef565b6119c0565b6040516105529190613064565b60405180910390f35b6105636119da565b604051610570919061307f565b60405180910390f35b610593600480360361058e919081019061290d565b6119f1565b6040516105a0919061319a565b60405180910390f35b6105b1611b22565b6040516105be919061307f565b60405180910390f35b6105cf611b39565b6040516105de939291906131ec565b60405180910390f35b61060160048036036105fc919081019061290d565b611b9a565b60405161060e919061319a565b60405180910390f35b61061f611c9a565b60405161062d92919061302d565b60405180910390f35b610650600480360361064b919081019061290d565b611cae565b60405161065d919061319a565b60405180910390f35b61066e611ccf565b60405161067b9190613223565b60405180910390f35b61069e600480360361069991908101906129d9565b611cd4565b6040516106ad939291906131b5565b60405180910390f35b6106be611d38565b6040516106cb919061319a565b60405180910390f35b6106ee60048036036106e9919081019061290d565b611d4a565b6040516106fd939291906131ec565b60405180910390f35b60008060006002600085815260200190815260200160002060000154600260008681526020019081526020016000206001015460026000878152602001908152602001600020600201549250925092509193909250565b6060806007831161077957610770611867565b91509150610934565b600061078484611b9a565b9050606060016000838152602001908152602001600020805490506040519080825280602002602001820160405280156107cd5781602001602082028038833980820191505090505b509050606060016000848152602001908152602001600020805490506040519080825280602002602001820160405280156108175781602001602082028038833980820191505090505b50905060008090505b60016000858152602001908152602001600020805490508110156109295760016000858152602001908152602001600020818154811061085c57fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683828151811061089a57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506001600085815260200190815260200160002081815481106108f257fe5b90600052602060002090600302016001015482828151811061091057fe5b6020026020010181815250508080600101915050610820565b508181945094505050505b915091565b6000606060016000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015610a0c578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190610970565b50505050905060008090505b8151811015610a84578373ffffffffffffffffffffffffffffffffffffffff16828281518110610a4457fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff161415610a7757600192505050610a8b565b8080600101915050610a18565b5060009150505b92915050565b73fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610add57600080fd5b6000610ae761174b565b90506000811415610afb57610afa611d74565b5b610b0f60018261209590919063ffffffff16565b8814610b50576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b47906130ff565b60405180910390fd5b868611610b92576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b899061315f565b60405180910390fd5b6000600460018989030181610ba357fe5b0614610be4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bdb9061313f565b60405180910390fd5b8660026000838152602001908152602001600020600101541115610c3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c34906130df565b60405180910390fd5b6000600260008a81526020019081526020016000206000015414610c96576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c8d9061311f565b60405180910390fd5b604051806060016040528089815260200188815260200187815250600260008a8152602001908152602001600020600082015181600001556020820151816001015560408201518160020155905050600388908060018154018082558091505090600182039060005260206000200160009091929091909150555060008060008a815260200190815260200160002081610d3091906125e9565b506000600160008a815260200190815260200160002081610d5191906125e9565b506060610da9610da487878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506120b4565b6120e2565b905060008090505b8151811015610f1b576060610dd8838381518110610dcb57fe5b60200260200101516120e2565b90506000808c81526020019081526020016000208054809190600101610dfe91906125e9565b506040518060600160405280610e2783600081518110610e1a57fe5b60200260200101516121bf565b8152602001610e4983600181518110610e3c57fe5b60200260200101516121bf565b8152602001610e6b83600281518110610e5e57fe5b6020026020010151612230565b73ffffffffffffffffffffffffffffffffffffffff168152506000808d81526020019081526020016000208381548110610ea157fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050508080600101915050610db1565b506060610f73610f6e86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506120b4565b6120e2565b905060008090505b81518110156110e7576060610fa2838381518110610f9557fe5b60200260200101516120e2565b9050600160008d81526020019081526020016000208054809190600101610fc991906125e9565b506040518060600160405280610ff283600081518110610fe557fe5b60200260200101516121bf565b81526020016110148360018151811061100757fe5b60200260200101516121bf565b81526020016110368360028151811061102957fe5b6020026020010151612230565b73ffffffffffffffffffffffffffffffffffffffff16815250600160008e8152602001908152602001600020838154811061106d57fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050508080600101915050610f7b565b5050505050505050505050565b60006060600080858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156111c6578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250508152602001906001019061112a565b50505050905060008090505b815181101561123e578373ffffffffffffffffffffffffffffffffffffffff168282815181106111fe57fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff16141561123157600192505050611245565b80806001019150506111d2565b5060009150505b92915050565b600481565b60006002600160f81b848460405160200161126d93929190612f7f565b6040516020818303038152906040526040516112899190612fbc565b602060405180830381855afa1580156112a6573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506112c99190810190612841565b905092915050565b60006060600080848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156113a3578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611307565b505050509050600080905060008090505b82518110156113f6576113e78382815181106113cc57fe5b6020026020010151602001518361209590919063ffffffff16565b915080806001019150506113b4565b508092505050919050565b73fffffffffffffffffffffffffffffffffffffffe81565b600080600080859050600060218087518161143057fe5b0402905060008111156114495761144687611775565b91505b6000602190505b8181116114d35760006001820388015190508188015195508060006020811061147557fe5b1a60f81b9450600060f81b857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156114ba576114b38685611250565b93506114c7565b6114c48487611250565b93505b50602181019050611450565b508782149450505050509392505050565b6040516114f090612fe8565b604051809103902081565b60008060009050600080905060008090505b84518167ffffffffffffffff1610156115d6576060611538868367ffffffffffffffff166041612253565b9050600061154f82896122df90919063ffffffff16565b905061155961261b565b6115638a836115e3565b905061156f8a836110f4565b80156115a657508473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16115b156115c8578194506115c581602001518761209590919063ffffffff16565b95505b50505060418101905061150d565b5081925050509392505050565b6115eb61261b565b6060600080858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156116bb578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250508152602001906001019061161f565b50505050905060008090505b8151811015611743578373ffffffffffffffffffffffffffffffffffffffff168282815181106116f357fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff1614156117365781818151811061172757fe5b60200260200101519250611743565b80806001019150506116c7565b505092915050565b600061175643611b9a565b905090565b600061176e61176861174b565b836110f4565b9050919050565b60006002600060f81b83604051602001611790929190612f53565b6040516020818303038152906040526040516117ac9190612fbc565b602060405180830381855afa1580156117c9573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506117ec9190810190612841565b9050919050565b600080600080611814600161180661174b565b61209590919063ffffffff16565b905060026000828152602001908152602001600020600001546002600083815260200190815260200160002060010154600260008481526020019081526020016000206002015493509350935050909192565b6060806060600160405190808252806020026020018201604052801561189c5781602001602082028038833980820191505090505b5090507371562b71999873db5b286df957af199ec94617f7816000815181106118c157fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506060600160405190808252806020026020018201604052801561192d5781602001602082028038833980820191505090505b509050600a8160008151811061193f57fe5b60200260200101818152505081819350935050509091565b600781565b6001602052816000526040600020818154811061197557fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b60006119d36119cd61174b565b83610939565b9050919050565b6040516119e690612fd3565b604051809103902081565b6000606060016000848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015611ac4578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611a28565b505050509050600080905060008090505b8251811015611b1757611b08838281518110611aed57fe5b6020026020010151602001518361209590919063ffffffff16565b91508080600101915050611ad5565b508092505050919050565b604051611b2e90612ffd565b604051809103902081565b600080600080611b4761174b565b905060026000828152602001908152602001600020600001546002600083815260200190815260200160002060010154600260008481526020019081526020016000206002015493509350935050909192565b60008060038054905090505b6000811115611c5a57611bb7612652565b6002600060036001850381548110611bcb57fe5b906000526020600020015481526020019081526020016000206040518060600160405290816000820154815260200160018201548152602001600282015481525050905083816020015111158015611c2857506000816040015114155b8015611c38575080604001518411155b15611c4b57806000015192505050611c95565b50808060019003915050611ba6565b5060006003805490501115611c9057600360016003805490500381548110611c7e57fe5b90600052602060002001549050611c95565b600090505b919050565b606080611ca64361075d565b915091509091565b60038181548110611cbb57fe5b906000526020600020016000915090505481565b600281565b60006020528160005260406000208181548110611ced57fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b600060044381611d4457fe5b04905090565b60026020528060005260406000206000915090508060000154908060010154908060020154905083565b606080611d7f611867565b809250819350505060008090506040518060600160405280828152602001600081526020016007815250600260008381526020019081526020016000206000820151816000015560208201518160010155604082015181600201559050506003819080600181540180825580915050906001820390600052602060002001600090919290919091505550600080600083815260200190815260200160002081611e2891906125e9565b5060006001600083815260200190815260200160002081611e4991906125e9565b5060008090505b8351811015611f6b576000808381526020019081526020016000208054809190600101611e7d91906125e9565b506040518060600160405280828152602001848381518110611e9b57fe5b60200260200101518152602001858381518110611eb457fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff168152506000808481526020019081526020016000208281548110611ef257fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050508080600101915050611e50565b5060008090505b835181101561208f57600160008381526020019081526020016000208054809190600101611fa091906125e9565b506040518060600160405280828152602001848381518110611fbe57fe5b60200260200101518152602001858381518110611fd757fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681525060016000848152602001908152602001600020828154811061201657fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050508080600101915050611f72565b50505050565b6000808284019050838110156120aa57600080fd5b8091505092915050565b6120bc612673565b600060208301905060405180604001604052808451815260200182815250915050919050565b60606120ed826123e9565b6120f657600080fd5b600061210183612437565b905060608160405190808252806020026020018201604052801561213f57816020015b61212c61268d565b8152602001906001900390816121245790505b509050600061215185602001516124a8565b8560200151019050600080600090505b848110156121b25761217283612531565b915060405180604001604052808381526020018481525084828151811061219557fe5b602002602001018190525081830192508080600101915050612161565b5082945050505050919050565b60008082600001511180156121d957506021826000015111155b6121e257600080fd5b60006121f183602001516124a8565b9050600081846000015103905060008083866020015101905080519150602083101561222457826020036101000a820491505b81945050505050919050565b6000601582600001511461224357600080fd5b61224c826121bf565b9050919050565b60608183018451101561226557600080fd5b6060821560008114612282576040519150602082016040526122d3565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156122c057805183526020830192506020810190506122a3565b50868552601f19601f8301166040525050505b50809150509392505050565b60008060008060418551146122fa57600093505050506123e3565b602085015192506040850151915060ff6041860151169050601b8160ff16101561232557601b810190505b601b8160ff161415801561233d5750601c8160ff1614155b1561234e57600093505050506123e3565b600060018783868660405160008152602001604052604051612373949392919061309a565b6020604051602081039080840390855afa158015612395573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156123db57600080fd5b809450505050505b92915050565b600080826000015114156124005760009050612432565b60008083602001519050805160001a915060c060ff168260ff16101561242b57600092505050612432565b6001925050505b919050565b6000808260000151141561244e57600090506124a3565b6000809050600061246284602001516124a8565b84602001510190506000846000015185602001510190505b8082101561249c5761248b82612531565b82019150828060010193505061247a565b8293505050505b919050565b600080825160001a9050608060ff168110156124c857600091505061252c565b60b860ff168110806124ed575060c060ff1681101580156124ec575060f860ff1681105b5b156124fc57600191505061252c565b60c060ff1681101561251c5760018060b80360ff1682030191505061252c565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff1681101561255257600191506125df565b60b860ff1681101561256f576001608060ff1682030191506125de565b60c060ff1681101561259f5760b78103600185019450806020036101000a855104600182018101935050506125dd565b60f860ff168110156125bc57600160c060ff1682030191506125dc565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b8154818355818111156126165760030281600302836000526020600020918201910161261591906126a7565b5b505050565b60405180606001604052806000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b60405180606001604052806000815260200160008152602001600081525090565b604051806040016040528060008152602001600081525090565b604051806040016040528060008152602001600081525090565b6126fa91905b808211156126f65760008082016000905560018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055506003016126ad565b5090565b90565b60008135905061270c8161341c565b92915050565b60008135905061272181613433565b92915050565b60008151905061273681613433565b92915050565b60008083601f84011261274e57600080fd5b8235905067ffffffffffffffff81111561276757600080fd5b60208301915083600182028301111561277f57600080fd5b9250929050565b600082601f83011261279757600080fd5b81356127aa6127a58261326b565b61323e565b915080825260208301602083018583830111156127c657600080fd5b6127d18382846133c6565b50505092915050565b6000813590506127e98161344a565b92915050565b60006020828403121561280157600080fd5b600061280f848285016126fd565b91505092915050565b60006020828403121561282a57600080fd5b600061283884828501612712565b91505092915050565b60006020828403121561285357600080fd5b600061286184828501612727565b91505092915050565b6000806040838503121561287d57600080fd5b600061288b85828601612712565b925050602061289c85828601612712565b9150509250929050565b6000806000606084860312156128bb57600080fd5b60006128c986828701612712565b93505060206128da86828701612712565b925050604084013567ffffffffffffffff8111156128f757600080fd5b61290386828701612786565b9150509250925092565b60006020828403121561291f57600080fd5b600061292d848285016127da565b91505092915050565b6000806040838503121561294957600080fd5b6000612957858286016127da565b9250506020612968858286016126fd565b9150509250929050565b60008060006060848603121561298757600080fd5b6000612995868287016127da565b93505060206129a686828701612712565b925050604084013567ffffffffffffffff8111156129c357600080fd5b6129cf86828701612786565b9150509250925092565b600080604083850312156129ec57600080fd5b60006129fa858286016127da565b9250506020612a0b858286016127da565b9150509250929050565b600080600080600080600060a0888a031215612a3057600080fd5b6000612a3e8a828b016127da565b9750506020612a4f8a828b016127da565b9650506040612a608a828b016127da565b955050606088013567ffffffffffffffff811115612a7d57600080fd5b612a898a828b0161273c565b9450945050608088013567ffffffffffffffff811115612aa857600080fd5b612ab48a828b0161273c565b925092505092959891949750929550565b6000612ad18383612af5565b60208301905092915050565b6000612ae98383612f26565b60208301905092915050565b612afe8161333b565b82525050565b612b0d8161333b565b82525050565b6000612b1e826132b7565b612b2881856132f2565b9350612b3383613297565b8060005b83811015612b64578151612b4b8882612ac5565b9750612b56836132d8565b925050600181019050612b37565b5085935050505092915050565b6000612b7c826132c2565b612b868185613303565b9350612b91836132a7565b8060005b83811015612bc2578151612ba98882612add565b9750612bb4836132e5565b925050600181019050612b95565b5085935050505092915050565b612bd88161334d565b82525050565b612bef612bea82613359565b613408565b82525050565b612bfe81613385565b82525050565b612c15612c1082613385565b613412565b82525050565b6000612c26826132cd565b612c308185613314565b9350612c408185602086016133d5565b80840191505092915050565b6000612c59600483613330565b91507f766f7465000000000000000000000000000000000000000000000000000000006000830152600482019050919050565b6000612c99602d8361331f565b91507f537461727420626c6f636b206d7573742062652067726561746572207468616e60008301527f2063757272656e74207370616e000000000000000000000000000000000000006020830152604082019050919050565b6000612cff600f8361331f565b91507f496e76616c6964207370616e20696400000000000000000000000000000000006000830152602082019050919050565b6000612d3f60138361331f565b91507f5370616e20616c726561647920657869737473000000000000000000000000006000830152602082019050919050565b6000612d7f60458361331f565b91507f446966666572656e6365206265747765656e20737461727420616e6420656e6460008301527f20626c6f636b206d75737420626520696e206d756c7469706c6573206f66207360208301527f7072696e740000000000000000000000000000000000000000000000000000006040830152606082019050919050565b6000612e0b602a8361331f565b91507f456e6420626c6f636b206d7573742062652067726561746572207468616e207360008301527f7461727420626c6f636b000000000000000000000000000000000000000000006020830152604082019050919050565b6000612e71600e83613330565b91507f6865696d64616c6c2d31353030310000000000000000000000000000000000006000830152600e82019050919050565b6000612eb1600583613330565b91507f31353030310000000000000000000000000000000000000000000000000000006000830152600582019050919050565b606082016000820151612efa6000850182612f26565b506020820151612f0d6020850182612f26565b506040820151612f206040850182612af5565b50505050565b612f2f816133af565b82525050565b612f3e816133af565b82525050565b612f4d816133b9565b82525050565b6000612f5f8285612bde565b600182019150612f6f8284612c04565b6020820191508190509392505050565b6000612f8b8286612bde565b600182019150612f9b8285612c04565b602082019150612fab8284612c04565b602082019150819050949350505050565b6000612fc88284612c1b565b915081905092915050565b6000612fde82612c4c565b9150819050919050565b6000612ff382612e64565b9150819050919050565b600061300882612ea4565b9150819050919050565b60006020820190506130276000830184612b04565b92915050565b600060408201905081810360008301526130478185612b13565b9050818103602083015261305b8184612b71565b90509392505050565b60006020820190506130796000830184612bcf565b92915050565b60006020820190506130946000830184612bf5565b92915050565b60006080820190506130af6000830187612bf5565b6130bc6020830186612f44565b6130c96040830185612bf5565b6130d66060830184612bf5565b95945050505050565b600060208201905081810360008301526130f881612c8c565b9050919050565b6000602082019050818103600083015261311881612cf2565b9050919050565b6000602082019050818103600083015261313881612d32565b9050919050565b6000602082019050818103600083015261315881612d72565b9050919050565b6000602082019050818103600083015261317881612dfe565b9050919050565b60006060820190506131946000830184612ee4565b92915050565b60006020820190506131af6000830184612f35565b92915050565b60006060820190506131ca6000830186612f35565b6131d76020830185612f35565b6131e46040830184612b04565b949350505050565b60006060820190506132016000830186612f35565b61320e6020830185612f35565b61321b6040830184612f35565b949350505050565b60006020820190506132386000830184612f44565b92915050565b6000604051905081810181811067ffffffffffffffff8211171561326157600080fd5b8060405250919050565b600067ffffffffffffffff82111561328257600080fd5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b60006133468261338f565b9050919050565b60008115159050919050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b82818337600083830152505050565b60005b838110156133f35780820151818401526020810190506133d8565b83811115613402576000848401525b50505050565b6000819050919050565b6000819050919050565b6134258161333b565b811461343057600080fd5b50565b61343c81613385565b811461344757600080fd5b50565b613453816133af565b811461345e57600080fd5b5056fea365627a7a72315820705a7e2d8613a0b74be45107951c3d3839c8711982c0ee57a8b920f2f99e86036c6578706572696d656e74616cf564736f6c63430005100040" }, "0000000000000000000000000000000000001001": { "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c8063017a9105146100515780633434735f1461009757806348a211d6146100e15780634c7af28e14610164575b600080fd5b61007d6004803603602081101561006757600080fd5b8101908080359060200190929190505050610182565b604051808215151515815260200191505060405180910390f35b61009f6101a2565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610162600480360360408110156100f757600080fd5b810190808035906020019064010000000081111561011457600080fd5b82018360208201111561012657600080fd5b8035906020019184600183028401116401000000008311171561014857600080fd5b9091929391929390803590602001909291905050506101ba565b005b61016c6105b0565b6040518082815260200191505060405180910390f35b60016020528060005260406000206000915054906101000a900460ff1681565b73fffffffffffffffffffffffffffffffffffffffe81565b73fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461020657600080fd5b600054811015610261576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180610a966027913960400191505060405180910390fd5b8060008190555060606102bf6102ba85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506105b6565b6105e4565b905060006102e0826000815181106102d357fe5b60200260200101516106c1565b90506000610301836001815181106102f457fe5b6020026020010151610732565b905060606103228460028151811061031557fe5b6020026020010151610755565b9050600015156001600085815260200190815260200160002060009054906101000a900460ff161515146103be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f53746174652077617320616c72656164792070726f636573736564000000000081525060200191505060405180910390fd5b600180600085815260200190815260200160002060006101000a81548160ff0219169083151502179055506103f2826107e1565b156105a7578173ffffffffffffffffffffffffffffffffffffffff1683826040516024018083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561045957808201518184015260208101905061043e565b50505050905090810190601f1680156104865780820380516001836020036101000a031916815260200191505b5093505050506040516020818303038152906040527f26c53bea000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b6020831061053c5780518252602082019150602081019050602083039250610519565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461059e576040519150601f19603f3d011682016040523d82523d6000602084013e6105a3565b606091505b5050505b50505050505050565b60005481565b6105be610a61565b600060208301905060405180604001604052808451815260200182815250915050919050565b60606105ef826107fa565b6105f857600080fd5b600061060383610848565b905060608160405190808252806020026020018201604052801561064157816020015b61062e610a7b565b8152602001906001900390816106265790505b509050600061065385602001516108b9565b8560200151019050600080600090505b848110156106b45761067483610942565b915060405180604001604052808381526020018481525084828151811061069757fe5b602002602001018190525081830192508080600101915050610663565b5082945050505050919050565b60008082600001511180156106db57506021826000015111155b6106e457600080fd5b60006106f383602001516108b9565b9050600081846000015103905060008083866020015101905080519150602083101561072657826020036101000a820491505b81945050505050919050565b6000601582600001511461074557600080fd5b61074e826106c1565b9050919050565b6060600082600001511161076857600080fd5b600061077783602001516108b9565b905060008184600001510390506060816040519080825280601f01601f1916602001820160405280156107b95781602001600182028038833980820191505090505b50905060008160200190506107d58487602001510182856109fa565b81945050505050919050565b600080823b905060008163ffffffff1611915050919050565b600080826000015114156108115760009050610843565b60008083602001519050805160001a915060c060ff168260ff16101561083c57600092505050610843565b6001925050505b919050565b6000808260000151141561085f57600090506108b4565b6000809050600061087384602001516108b9565b84602001510190506000846000015185602001510190505b808210156108ad5761089c82610942565b82019150828060010193505061088b565b8293505050505b919050565b600080825160001a9050608060ff168110156108d957600091505061093d565b60b860ff168110806108fe575060c060ff1681101580156108fd575060f860ff1681105b5b1561090d57600191505061093d565b60c060ff1681101561092d5760018060b80360ff1682030191505061093d565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff1681101561096357600191506109f0565b60b860ff16811015610980576001608060ff1682030191506109ef565b60c060ff168110156109b05760b78103600185019450806020036101000a855104600182018101935050506109ee565b60f860ff168110156109cd57600160c060ff1682030191506109ed565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b6000811415610a0857610a5c565b5b602060ff168110610a385782518252602060ff1683019250602060ff1682019150602060ff1681039050610a09565b6000600182602060ff16036101000a03905080198451168184511681811785525050505b505050565b604051806040016040528060008152602001600081525090565b60405180604001604052806000815260200160008152509056fe417474656d7074696e6720746f2073796e63207374617465732066726f6d207468652070617374a265627a7a72315820dba46dd2ffc6ab680135ba772c3c3520365da762079ac66a151d80ff2bbb5c6a64736f6c63430005100032" + "code": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c8063017a91051461005157806319494a17146100975780633434735f1461011a5780634c7af28e14610164575b600080fd5b61007d6004803603602081101561006757600080fd5b8101908080359060200190929190505050610182565b604051808215151515815260200191505060405180910390f35b610118600480360360408110156100ad57600080fd5b8101908080359060200190929190803590602001906401000000008111156100d457600080fd5b8201836020820111156100e657600080fd5b8035906020019184600183028401116401000000008311171561010857600080fd5b90919293919293905050506101a2565b005b610122610598565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61016c6105b0565b6040518082815260200191505060405180910390f35b60016020528060005260406000206000915054906101000a900460ff1681565b73fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101ee57600080fd5b600054831015610249576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180610a966027913960400191505060405180910390fd5b8260008190555060606102a76102a284848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506105b6565b6105e4565b905060006102c8826000815181106102bb57fe5b60200260200101516106c1565b905060006102e9836001815181106102dc57fe5b6020026020010151610732565b9050606061030a846002815181106102fd57fe5b6020026020010151610755565b9050600015156001600085815260200190815260200160002060009054906101000a900460ff161515146103a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f53746174652077617320616c72656164792070726f636573736564000000000081525060200191505060405180910390fd5b600180600085815260200190815260200160002060006101000a81548160ff0219169083151502179055506103da826107e1565b1561058f578173ffffffffffffffffffffffffffffffffffffffff1683826040516024018083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610441578082015181840152602081019050610426565b50505050905090810190601f16801561046e5780820380516001836020036101000a031916815260200191505b5093505050506040516020818303038152906040527f26c53bea000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b602083106105245780518252602082019150602081019050602083039250610501565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610586576040519150601f19603f3d011682016040523d82523d6000602084013e61058b565b606091505b5050505b50505050505050565b73fffffffffffffffffffffffffffffffffffffffe81565b60005481565b6105be610a61565b600060208301905060405180604001604052808451815260200182815250915050919050565b60606105ef826107fa565b6105f857600080fd5b600061060383610848565b905060608160405190808252806020026020018201604052801561064157816020015b61062e610a7b565b8152602001906001900390816106265790505b509050600061065385602001516108b9565b8560200151019050600080600090505b848110156106b45761067483610942565b915060405180604001604052808381526020018481525084828151811061069757fe5b602002602001018190525081830192508080600101915050610663565b5082945050505050919050565b60008082600001511180156106db57506021826000015111155b6106e457600080fd5b60006106f383602001516108b9565b9050600081846000015103905060008083866020015101905080519150602083101561072657826020036101000a820491505b81945050505050919050565b6000601582600001511461074557600080fd5b61074e826106c1565b9050919050565b6060600082600001511161076857600080fd5b600061077783602001516108b9565b905060008184600001510390506060816040519080825280601f01601f1916602001820160405280156107b95781602001600182028038833980820191505090505b50905060008160200190506107d58487602001510182856109fa565b81945050505050919050565b600080823b905060008163ffffffff1611915050919050565b600080826000015114156108115760009050610843565b60008083602001519050805160001a915060c060ff168260ff16101561083c57600092505050610843565b6001925050505b919050565b6000808260000151141561085f57600090506108b4565b6000809050600061087384602001516108b9565b84602001510190506000846000015185602001510190505b808210156108ad5761089c82610942565b82019150828060010193505061088b565b8293505050505b919050565b600080825160001a9050608060ff168110156108d957600091505061093d565b60b860ff168110806108fe575060c060ff1681101580156108fd575060f860ff1681105b5b1561090d57600191505061093d565b60c060ff1681101561092d5760018060b80360ff1682030191505061093d565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff1681101561096357600191506109f0565b60b860ff16811015610980576001608060ff1682030191506109ef565b60c060ff168110156109b05760b78103600185019450806020036101000a855104600182018101935050506109ee565b60f860ff168110156109cd57600160c060ff1682030191506109ed565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b6000811415610a0857610a5c565b5b602060ff168110610a385782518252602060ff1683019250602060ff1682019150602060ff1681039050610a09565b6000600182602060ff16036101000a03905080198451168184511681811785525050505b505050565b604051806040016040528060008152602001600081525090565b60405180604001604052806000815260200160008152509056fe417474656d7074696e6720746f2073796e63207374617465732066726f6d207468652070617374a265627a7a723158200e44a9fc38049f8bea49a2b5a69ed071eb2bc0248bee71fd0222d1318c23b9e664736f6c63430005100032" }, "0000000000000000000000000000000000001010": { "balance": "0x204fce28085b549b31600000", diff --git a/consensus/bor/genesis_contracts_client.go b/consensus/bor/genesis_contracts_client.go index d616c6f12e..4afbdabbf6 100644 --- a/consensus/bor/genesis_contracts_client.go +++ b/consensus/bor/genesis_contracts_client.go @@ -29,8 +29,8 @@ type GenesisContractsClient struct { ethAPI *ethapi.PublicBlockChainAPI } -const validatorsetABI = `[{"constant":true,"inputs":[],"name":"SYSTEM_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"CHAIN","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FIRST_END_BLOCK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"producers","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ROUND_TYPE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"BOR_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"sprint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"spanNumbers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"VOTE_TYPE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"validators","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"spans","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"startBlock","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"endBlock","type":"uint256"}],"name":"NewSpan","type":"event"},{"constant":true,"inputs":[],"name":"currentSprint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"}],"name":"getSpan","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCurrentSpan","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNextSpan","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"number","type":"uint256"}],"name":"getSpanByBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"currentSpanNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"}],"name":"getValidatorsTotalStakeBySpan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"}],"name":"getProducersTotalStakeBySpan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"name":"getValidatorBySigner","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"internalType":"struct BorValidatorSet.Validator","name":"result","type":"tuple"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"name":"isValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"name":"isProducer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"isCurrentValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"isCurrentProducer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"number","type":"uint256"}],"name":"getBorValidators","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitialValidators","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getValidators","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"newSpan","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"},{"internalType":"bytes","name":"validatorBytes","type":"bytes"},{"internalType":"bytes","name":"producerBytes","type":"bytes"}],"name":"commitSpan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"bytes32","name":"dataHash","type":"bytes32"},{"internalType":"bytes","name":"sigs","type":"bytes"}],"name":"getStakePowerBySigs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"internalType":"bytes32","name":"leaf","type":"bytes32"},{"internalType":"bytes","name":"proof","type":"bytes"}],"name":"checkMembership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"d","type":"bytes32"}],"name":"leafNode","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"left","type":"bytes32"},{"internalType":"bytes32","name":"right","type":"bytes32"}],"name":"innerNode","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"}]` -const stateReceiverABI = `[{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"states","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SYSTEM_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastStateSyncTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes","name":"recordBytes","type":"bytes"},{"internalType":"uint256","name":"syncTime","type":"uint256"}],"name":"commitState","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]` +const validatorsetABI = `[{"constant":true,"inputs":[],"name":"SPRINT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SYSTEM_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"CHAIN","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FIRST_END_BLOCK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"producers","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ROUND_TYPE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"BOR_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"spanNumbers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"VOTE_TYPE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"validators","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"spans","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"startBlock","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"endBlock","type":"uint256"}],"name":"NewSpan","type":"event"},{"constant":true,"inputs":[],"name":"currentSprint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"}],"name":"getSpan","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCurrentSpan","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNextSpan","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"number","type":"uint256"}],"name":"getSpanByBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"currentSpanNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"}],"name":"getValidatorsTotalStakeBySpan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"}],"name":"getProducersTotalStakeBySpan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"name":"getValidatorBySigner","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"internalType":"struct BorValidatorSet.Validator","name":"result","type":"tuple"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"name":"isValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"name":"isProducer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"isCurrentValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"isCurrentProducer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"number","type":"uint256"}],"name":"getBorValidators","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitialValidators","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getValidators","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"newSpan","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"},{"internalType":"bytes","name":"validatorBytes","type":"bytes"},{"internalType":"bytes","name":"producerBytes","type":"bytes"}],"name":"commitSpan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"bytes32","name":"dataHash","type":"bytes32"},{"internalType":"bytes","name":"sigs","type":"bytes"}],"name":"getStakePowerBySigs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"internalType":"bytes32","name":"leaf","type":"bytes32"},{"internalType":"bytes","name":"proof","type":"bytes"}],"name":"checkMembership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"d","type":"bytes32"}],"name":"leafNode","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"left","type":"bytes32"},{"internalType":"bytes32","name":"right","type":"bytes32"}],"name":"innerNode","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"}]` +const stateReceiverABI = `[{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"states","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SYSTEM_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastStateSyncTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"syncTime","type":"uint256"},{"internalType":"bytes","name":"recordBytes","type":"bytes"}],"name":"commitState","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]` func NewGenesisContractsClient( chainConfig *params.ChainConfig, @@ -63,7 +63,7 @@ func (gc *GenesisContractsClient) CommitState( } method := "commitState" t := event.Time.Unix() - data, err := gc.stateReceiverABI.Pack(method, recordBytes, big.NewInt(0).SetInt64(t)) + data, err := gc.stateReceiverABI.Pack(method, big.NewInt(0).SetInt64(t), recordBytes) if err != nil { log.Error("Unable to pack tx for commitState", "error", err) return err From c5a015a8a4a5c5842ea15af2802899222e0afafc Mon Sep 17 00:00:00 2001 From: Jaynti Kanani Date: Sat, 16 May 2020 10:36:44 +0530 Subject: [PATCH 29/46] fix: make data fetch more robust --- consensus/bor/rest.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/consensus/bor/rest.go b/consensus/bor/rest.go index 9c525d6df6..91aae237a7 100644 --- a/consensus/bor/rest.go +++ b/consensus/bor/rest.go @@ -86,18 +86,22 @@ func (h *HeimdallClient) internalFetch(u *url.URL) (*ResponseWithHeight, error) defer res.Body.Close() // check status code - if res.StatusCode != 200 { + if res.StatusCode != 200 && res.StatusCode != 204 { return nil, fmt.Errorf("Error while fetching data from Heimdall") } + // unmarshall data from buffer + var response ResponseWithHeight + if res.StatusCode == 204 { + return &response, nil + } + // get response body, err := ioutil.ReadAll(res.Body) if err != nil { return nil, err } - // unmarshall data from buffer - var response ResponseWithHeight if err := json.Unmarshal(body, &response); err != nil { return nil, err } From 767fe584b596ce45117e51b0de6514840ff99a09 Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Mon, 18 May 2020 12:37:20 +0530 Subject: [PATCH 30/46] fix: revert cancel active seal logic --- consensus/bor/bor.go | 52 ++++++----------------------------------- consensus/bor/errors.go | 11 --------- consensus/consensus.go | 1 - core/blockchain.go | 1 - 4 files changed, 7 insertions(+), 58 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 7ee2f52be1..0d244548eb 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -127,12 +127,6 @@ var ( errRecentlySigned = errors.New("recently signed") ) -// ActiveSealingOp keeps the context of the active sealing operation -type ActiveSealingOp struct { - number uint64 - cancel context.CancelFunc -} - // SignerFn is a signer callback function to request a header to be signed by a // backing account. type SignerFn func(accounts.Account, string, []byte) ([]byte, error) @@ -238,9 +232,8 @@ type Bor struct { stateReceiverABI abi.ABI HeimdallClient IHeimdallClient - stateDataFeed event.Feed - scope event.SubscriptionScope - activeSealingOp *ActiveSealingOp + stateDataFeed event.Feed + scope event.SubscriptionScope // The fields below are for testing only fakeDiff bool // Skip difficulty verifications } @@ -728,9 +721,6 @@ func (c *Bor) Authorize(signer common.Address, signFn SignerFn) { // Seal implements consensus.Engine, attempting to create a sealed block using // the local signing credentials. func (c *Bor) Seal(chain consensus.ChainReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error { - // if c.activeSealingOp != nil { - // return &SealingInFlightError{c.activeSealingOp.number} - // } header := block.Header() // Sealing the genesis block is not supported @@ -777,17 +767,12 @@ func (c *Bor) Seal(chain consensus.ChainReader, block *types.Block, results chan // Wait until sealing is terminated or delay timeout. log.Trace("Waiting for slot to sign and propagate", "delay", common.PrettyDuration(delay)) - shouldSeal := make(chan bool) - go c.WaitForSealingOp(number, shouldSeal, delay, stop) go func() { - defer func() { - close(shouldSeal) - c.activeSealingOp = nil - }() - switch <-shouldSeal { - case false: + select { + case <-stop: + log.Debug("Discarding sealing operation for block", "number", number) return - case true: + case <-time.After(delay): if wiggle > 0 { log.Info( "Sealing out-of-turn", @@ -803,38 +788,15 @@ func (c *Bor) Seal(chain consensus.ChainReader, block *types.Block, results chan "headerDifficulty", header.Difficulty, ) } - select { case results <- block.WithSeal(header): default: - log.Warn("Sealing result was not read by miner", "sealhash", SealHash(header)) + log.Warn("Sealing result was not read by miner", "number", number, "sealhash", SealHash(header)) } }() return nil } -// WaitForSealingOp blocks until delay elapses or stop signal is received -func (c *Bor) WaitForSealingOp(number uint64, shouldSeal chan bool, delay time.Duration, stop <-chan struct{}) { - ctx, cancel := context.WithCancel(context.Background()) - c.activeSealingOp = &ActiveSealingOp{number, cancel} - select { - case <-stop: - shouldSeal <- false - case <-ctx.Done(): - shouldSeal <- false - case <-time.After(delay): - shouldSeal <- true - } -} - -// CancelActiveSealingOp cancels in-flight sealing process -func (c *Bor) CancelActiveSealingOp() { - if c.activeSealingOp != nil { - log.Debug("Discarding active sealing operation", "number", c.activeSealingOp.number) - c.activeSealingOp.cancel() - } -} - // CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty // that a new block should have based on the previous blocks in the chain and the // current signer. diff --git a/consensus/bor/errors.go b/consensus/bor/errors.go index f357705db4..7e0b90941c 100644 --- a/consensus/bor/errors.go +++ b/consensus/bor/errors.go @@ -69,17 +69,6 @@ func (e *MaxCheckpointLengthExceededError) Error() string { ) } -type SealingInFlightError struct { - Number uint64 -} - -func (e *SealingInFlightError) Error() string { - return fmt.Sprintf( - "Requested concurrent block sealing. Sealing for block %d is already in progress", - e.Number, - ) -} - // MismatchingValidatorsError is returned if a last block in sprint contains a // list of validators different from the one that local node calculated type MismatchingValidatorsError struct { diff --git a/consensus/consensus.go b/consensus/consensus.go index 0620cff059..0372391138 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -120,7 +120,6 @@ type Engine interface { type Bor interface { Engine IsValidatorAction(chain ChainReader, from common.Address, tx *types.Transaction) bool - CancelActiveSealingOp() } // PoW is a consensus engine based on proof-of-work. diff --git a/core/blockchain.go b/core/blockchain.go index 3ce4356929..e90ffbb30e 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1718,7 +1718,6 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, [] if lastCanon != nil && bc.CurrentBlock().Hash() == lastCanon.Hash() { events = append(events, ChainHeadEvent{lastCanon}) } - bc.engine.(consensus.Bor).CancelActiveSealingOp() return it.index, events, coalescedLogs, err } From c7ea09a019c1fc9eaff6ed6a35e42935e504acda Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Mon, 18 May 2020 13:33:27 +0530 Subject: [PATCH 31/46] dev: Change wording for UnauthorizedSignerError, remove errRecentlySigned --- consensus/bor/bor.go | 4 --- consensus/bor/bor_test/bor_test.go | 27 ++++++++++++++++ consensus/bor/bor_test/snapshot_test.go | 8 ++--- consensus/bor/errors.go | 42 ++++++++++--------------- consensus/bor/snapshot.go | 13 ++------ 5 files changed, 51 insertions(+), 43 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 0d244548eb..a8f90dfe66 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -121,10 +121,6 @@ var ( // errOutOfRangeChain is returned if an authorization list is attempted to // be modified via out-of-range or non-contiguous headers. errOutOfRangeChain = errors.New("out of range or non-contiguous chain") - - // errRecentlySigned is returned if a header is signed by an authorized entity - // that already signed a header recently, thus is temporarily not allowed to. - errRecentlySigned = errors.New("recently signed") ) // SignerFn is a signer callback function to request a header to be signed by a diff --git a/consensus/bor/bor_test/bor_test.go b/consensus/bor/bor_test/bor_test.go index 62d929220a..1c6c530e82 100644 --- a/consensus/bor/bor_test/bor_test.go +++ b/consensus/bor/bor_test/bor_test.go @@ -160,3 +160,30 @@ func TestOutOfTurnSigning(t *testing.T) { _, err = chain.InsertChain([]*types.Block{block}) assert.Nil(t, err) } + +func TestSignerNotFound(t *testing.T) { + init := buildEthereumInstance(t, rawdb.NewMemoryDatabase()) + chain := init.ethereum.BlockChain() + engine := init.ethereum.Engine() + _bor := engine.(*bor.Bor) + + res, _ := loadSpanFromFile(t) + h := &mocks.IHeimdallClient{} + h.On("FetchWithRetry", "bor", "span", "1").Return(res, nil) + _bor.SetHeimdallClient(h) + + db := init.ethereum.ChainDb() + block := init.genesis.ToBlock(db) + + // random signer account that is not a part of the validator set + signer := "3714d99058cd64541433d59c6b391555b2fd9b54629c2b717a6c9c00d1127b6b" + signerKey, _ := hex.DecodeString(signer) + key, _ = crypto.HexToECDSA(signer) + addr = crypto.PubkeyToAddress(key.PublicKey) + + block = buildNextBlock(t, _bor, chain, block, signerKey, init.genesis.Config.Bor) + _, err := chain.InsertChain([]*types.Block{block}) + assert.Equal(t, + *err.(*bor.UnauthorizedSignerError), + bor.UnauthorizedSignerError{Number: 1, Signer: addr.Bytes()}) +} diff --git a/consensus/bor/bor_test/snapshot_test.go b/consensus/bor/bor_test/snapshot_test.go index 264c632952..6eb43b3e60 100644 --- a/consensus/bor/bor_test/snapshot_test.go +++ b/consensus/bor/bor_test/snapshot_test.go @@ -84,9 +84,9 @@ func TestGetSignerSuccessionNumber_ProposerNotFound(t *testing.T) { signer := snap.ValidatorSet.Validators[3].Address _, err := snap.GetSignerSuccessionNumber(signer) assert.NotNil(t, err) - e, ok := err.(*bor.ProposerNotFoundError) + e, ok := err.(*bor.UnauthorizedProposerError) assert.True(t, ok) - assert.Equal(t, dummyProposerAddress, e.Address) + assert.Equal(t, dummyProposerAddress.Bytes(), e.Proposer) } func TestGetSignerSuccessionNumber_SignerNotFound(t *testing.T) { @@ -97,9 +97,9 @@ func TestGetSignerSuccessionNumber_SignerNotFound(t *testing.T) { dummySignerAddress := randomAddress() _, err := snap.GetSignerSuccessionNumber(dummySignerAddress) assert.NotNil(t, err) - e, ok := err.(*bor.SignerNotFoundError) + e, ok := err.(*bor.UnauthorizedSignerError) assert.True(t, ok) - assert.Equal(t, dummySignerAddress, e.Address) + assert.Equal(t, dummySignerAddress.Bytes(), e.Signer) } func buildRandomValidatorSet(numVals int) []*bor.Validator { diff --git a/consensus/bor/errors.go b/consensus/bor/errors.go index 7e0b90941c..2153c8c4a5 100644 --- a/consensus/bor/errors.go +++ b/consensus/bor/errors.go @@ -2,30 +2,8 @@ package bor import ( "fmt" - - "github.com/maticnetwork/bor/common" ) -// Will include any new bor consensus errors here in an attempt to make error messages more descriptive - -// ProposerNotFoundError is returned if the given proposer address is not present in the validator set -type ProposerNotFoundError struct { - Address common.Address -} - -func (e *ProposerNotFoundError) Error() string { - return fmt.Sprintf("Proposer: %s not found", e.Address.Hex()) -} - -// SignerNotFoundError is returned when the signer address is not present in the validator set -type SignerNotFoundError struct { - Address common.Address -} - -func (e *SignerNotFoundError) Error() string { - return fmt.Sprintf("Signer: %s not found", e.Address.Hex()) -} - // TotalVotingPowerExceededError is returned when the maximum allowed total voting power is exceeded type TotalVotingPowerExceededError struct { Sum int64 @@ -99,7 +77,21 @@ func (e *BlockTooSoonError) Error() string { ) } -// UnauthorizedSignerError is returned if a header is signed by a non-authorized entity. +// UnauthorizedProposerError is returned if a header is [being] signed by an unauthorized entity. +type UnauthorizedProposerError struct { + Number uint64 + Proposer []byte +} + +func (e *UnauthorizedProposerError) Error() string { + return fmt.Sprintf( + "Proposer 0x%x is not a part of the producer set at block %d", + e.Proposer, + e.Number, + ) +} + +// UnauthorizedSignerError is returned if a header is [being] signed by an unauthorized entity. type UnauthorizedSignerError struct { Number uint64 Signer []byte @@ -107,9 +99,9 @@ type UnauthorizedSignerError struct { func (e *UnauthorizedSignerError) Error() string { return fmt.Sprintf( - "Validator set for block %d doesn't contain the signer 0x%x\n", - e.Number, + "Signer 0x%x is not a part of the producer set at block %d", e.Signer, + e.Number, ) } diff --git a/consensus/bor/snapshot.go b/consensus/bor/snapshot.go index a62c2014b9..2ff7dec0ce 100644 --- a/consensus/bor/snapshot.go +++ b/consensus/bor/snapshot.go @@ -26,7 +26,6 @@ import ( "github.com/maticnetwork/bor/core/types" "github.com/maticnetwork/bor/ethdb" "github.com/maticnetwork/bor/internal/ethapi" - "github.com/maticnetwork/bor/log" "github.com/maticnetwork/bor/params" ) @@ -191,24 +190,18 @@ func (s *Snapshot) GetSignerSuccessionNumber(signer common.Address) (int, error) proposer := s.ValidatorSet.GetProposer().Address proposerIndex, _ := s.ValidatorSet.GetByAddress(proposer) if proposerIndex == -1 { - return -1, &ProposerNotFoundError{proposer} + return -1, &UnauthorizedProposerError{s.Number, proposer.Bytes()} } signerIndex, _ := s.ValidatorSet.GetByAddress(signer) if signerIndex == -1 { - return -1, &SignerNotFoundError{signer} + return -1, &UnauthorizedSignerError{s.Number, signer.Bytes()} } - limit := len(validators)/2 + 1 tempIndex := signerIndex - if proposerIndex != tempIndex && limit > 0 { + if proposerIndex != tempIndex { if tempIndex < proposerIndex { tempIndex = tempIndex + len(validators) } - - if tempIndex-proposerIndex > limit { - log.Info("errRecentlySigned", "proposerIndex", validators[proposerIndex].Address.Hex(), "signerIndex", validators[signerIndex].Address.Hex()) - return -1, errRecentlySigned - } } return tempIndex - proposerIndex, nil } From 1be0c4894afee14c7aae7ebab3074b47cdab9389 Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Mon, 18 May 2020 14:17:13 +0530 Subject: [PATCH 32/46] dev: provide previous block number to UnauthorizedSignerError --- consensus/bor/bor.go | 6 ++++-- consensus/bor/bor_test/bor_test.go | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index a8f90dfe66..fac5500b76 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -555,7 +555,8 @@ func (c *Bor) verifySeal(chain consensus.ChainReader, header *types.Header, pare return err } if !snap.ValidatorSet.HasAddress(signer.Bytes()) { - return &UnauthorizedSignerError{number, signer.Bytes()} + // Check the UnauthorizedSignerError.Error() msg to see why we pass number-1 + return &UnauthorizedSignerError{number - 1, signer.Bytes()} } succession, err := snap.GetSignerSuccessionNumber(signer) @@ -741,7 +742,8 @@ func (c *Bor) Seal(chain consensus.ChainReader, block *types.Block, results chan // Bail out if we're unauthorized to sign a block if !snap.ValidatorSet.HasAddress(signer.Bytes()) { - return &UnauthorizedSignerError{number, signer.Bytes()} + // Check the UnauthorizedSignerError.Error() msg to see why we pass number-1 + return &UnauthorizedSignerError{number - 1, signer.Bytes()} } successionNumber, err := snap.GetSignerSuccessionNumber(signer) diff --git a/consensus/bor/bor_test/bor_test.go b/consensus/bor/bor_test/bor_test.go index 1c6c530e82..98331996f9 100644 --- a/consensus/bor/bor_test/bor_test.go +++ b/consensus/bor/bor_test/bor_test.go @@ -185,5 +185,5 @@ func TestSignerNotFound(t *testing.T) { _, err := chain.InsertChain([]*types.Block{block}) assert.Equal(t, *err.(*bor.UnauthorizedSignerError), - bor.UnauthorizedSignerError{Number: 1, Signer: addr.Bytes()}) + bor.UnauthorizedSignerError{Number: 0, Signer: addr.Bytes()}) } From fa0266a347550348d069ecc96988507085da01d6 Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Mon, 18 May 2020 18:51:29 +0530 Subject: [PATCH 33/46] merge develop into mew-deposits --- cmd/bor/chaincmd.go | 1 + cmd/bor/config.go | 2 +- cmd/utils/flags.go | 2 +- consensus/bor/bor.go | 62 +++++-------------------- consensus/bor/bor_test/bor_test.go | 24 ++++++++++ consensus/bor/bor_test/snapshot_test.go | 8 ++-- consensus/bor/errors.go | 53 +++++++-------------- consensus/bor/snapshot.go | 13 ++---- consensus/consensus.go | 6 --- core/blockchain.go | 1 - 10 files changed, 62 insertions(+), 110 deletions(-) diff --git a/cmd/bor/chaincmd.go b/cmd/bor/chaincmd.go index bbb8792a16..83d3261566 100644 --- a/cmd/bor/chaincmd.go +++ b/cmd/bor/chaincmd.go @@ -64,6 +64,7 @@ It expects the genesis file as argument.`, ArgsUsage: " ( ... ) ", Flags: []cli.Flag{ utils.DataDirFlag, + utils.HeimdallURLFlag, utils.CacheFlag, utils.SyncModeFlag, utils.GCModeFlag, diff --git a/cmd/bor/config.go b/cmd/bor/config.go index 4929d826eb..9202fec7c4 100644 --- a/cmd/bor/config.go +++ b/cmd/bor/config.go @@ -151,7 +151,7 @@ func enableWhisper(ctx *cli.Context) bool { func makeFullNode(ctx *cli.Context) *node.Node { stack, cfg := makeConfigNode(ctx) - cfg.Eth.HeimdallURL = ctx.String(utils.HeimdallURLFlag.Name) + cfg.Eth.HeimdallURL = ctx.GlobalString(utils.HeimdallURLFlag.Name) log.Info("Connecting to heimdall service on...", "heimdallURL", cfg.Eth.HeimdallURL) utils.RegisterEthService(stack, &cfg.Eth) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index fa0aa9bf16..78a70beabe 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -1694,7 +1694,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai if config.Clique != nil { engine = clique.New(config.Clique, chainDb) } else if config.Bor != nil { - cfg := ð.Config{Genesis: genesis} + cfg := ð.Config{Genesis: genesis, HeimdallURL: ctx.GlobalString(HeimdallURLFlag.Name)} workspace, err := ioutil.TempDir("", "console-tester-") if err != nil { Fatalf("failed to create temporary keystore: %v", err) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 43ebe93fd4..d0d66403bf 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -119,18 +119,8 @@ var ( // errOutOfRangeChain is returned if an authorization list is attempted to // be modified via out-of-range or non-contiguous headers. errOutOfRangeChain = errors.New("out of range or non-contiguous chain") - - // errRecentlySigned is returned if a header is signed by an authorized entity - // that already signed a header recently, thus is temporarily not allowed to. - errRecentlySigned = errors.New("recently signed") ) -// ActiveSealingOp keeps the context of the active sealing operation -type ActiveSealingOp struct { - number uint64 - cancel context.CancelFunc -} - // SignerFn is a signer callback function to request a header to be signed by a // backing account. type SignerFn func(accounts.Account, string, []byte) ([]byte, error) @@ -237,9 +227,8 @@ type Bor struct { stateReceiverABI abi.ABI HeimdallClient IHeimdallClient - stateDataFeed event.Feed - scope event.SubscriptionScope - activeSealingOp *ActiveSealingOp + stateDataFeed event.Feed + scope event.SubscriptionScope // The fields below are for testing only fakeDiff bool // Skip difficulty verifications } @@ -566,7 +555,8 @@ func (c *Bor) verifySeal(chain consensus.ChainReader, header *types.Header, pare return err } if !snap.ValidatorSet.HasAddress(signer.Bytes()) { - return &UnauthorizedSignerError{number, signer.Bytes()} + // Check the UnauthorizedSignerError.Error() msg to see why we pass number-1 + return &UnauthorizedSignerError{number - 1, signer.Bytes()} } succession, err := snap.GetSignerSuccessionNumber(signer) @@ -728,9 +718,6 @@ func (c *Bor) Authorize(signer common.Address, signFn SignerFn) { // Seal implements consensus.Engine, attempting to create a sealed block using // the local signing credentials. func (c *Bor) Seal(chain consensus.ChainReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error { - // if c.activeSealingOp != nil { - // return &SealingInFlightError{c.activeSealingOp.number} - // } header := block.Header() // Sealing the genesis block is not supported @@ -755,7 +742,8 @@ func (c *Bor) Seal(chain consensus.ChainReader, block *types.Block, results chan // Bail out if we're unauthorized to sign a block if !snap.ValidatorSet.HasAddress(signer.Bytes()) { - return &UnauthorizedSignerError{number, signer.Bytes()} + // Check the UnauthorizedSignerError.Error() msg to see why we pass number-1 + return &UnauthorizedSignerError{number - 1, signer.Bytes()} } successionNumber, err := snap.GetSignerSuccessionNumber(signer) @@ -777,17 +765,12 @@ func (c *Bor) Seal(chain consensus.ChainReader, block *types.Block, results chan // Wait until sealing is terminated or delay timeout. log.Trace("Waiting for slot to sign and propagate", "delay", common.PrettyDuration(delay)) - shouldSeal := make(chan bool) - go c.WaitForSealingOp(number, shouldSeal, delay, stop) go func() { - defer func() { - close(shouldSeal) - c.activeSealingOp = nil - }() - switch <-shouldSeal { - case false: + select { + case <-stop: + log.Debug("Discarding sealing operation for block", "number", number) return - case true: + case <-time.After(delay): if wiggle > 0 { log.Info( "Sealing out-of-turn", @@ -803,38 +786,15 @@ func (c *Bor) Seal(chain consensus.ChainReader, block *types.Block, results chan "headerDifficulty", header.Difficulty, ) } - select { case results <- block.WithSeal(header): default: - log.Warn("Sealing result was not read by miner", "sealhash", SealHash(header)) + log.Warn("Sealing result was not read by miner", "number", number, "sealhash", SealHash(header)) } }() return nil } -// WaitForSealingOp blocks until delay elapses or stop signal is received -func (c *Bor) WaitForSealingOp(number uint64, shouldSeal chan bool, delay time.Duration, stop <-chan struct{}) { - ctx, cancel := context.WithCancel(context.Background()) - c.activeSealingOp = &ActiveSealingOp{number, cancel} - select { - case <-stop: - shouldSeal <- false - case <-ctx.Done(): - shouldSeal <- false - case <-time.After(delay): - shouldSeal <- true - } -} - -// CancelActiveSealingOp cancels in-flight sealing process -func (c *Bor) CancelActiveSealingOp() { - if c.activeSealingOp != nil { - log.Debug("Discarding active sealing operation", "number", c.activeSealingOp.number) - c.activeSealingOp.cancel() - } -} - // CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty // that a new block should have based on the previous blocks in the chain and the // current signer. diff --git a/consensus/bor/bor_test/bor_test.go b/consensus/bor/bor_test/bor_test.go index 56b2e38f8a..0bd4a50653 100644 --- a/consensus/bor/bor_test/bor_test.go +++ b/consensus/bor/bor_test/bor_test.go @@ -102,6 +102,30 @@ func TestOutOfTurnSigning(t *testing.T) { assert.Nil(t, err) } +func TestSignerNotFound(t *testing.T) { + init := buildEthereumInstance(t, rawdb.NewMemoryDatabase()) + chain := init.ethereum.BlockChain() + engine := init.ethereum.Engine() + _bor := engine.(*bor.Bor) + h, _ := getMockedHeimdallClient(t) + _bor.SetHeimdallClient(h) + + db := init.ethereum.ChainDb() + block := init.genesis.ToBlock(db) + + // random signer account that is not a part of the validator set + signer := "3714d99058cd64541433d59c6b391555b2fd9b54629c2b717a6c9c00d1127b6b" + signerKey, _ := hex.DecodeString(signer) + key, _ = crypto.HexToECDSA(signer) + addr = crypto.PubkeyToAddress(key.PublicKey) + + block = buildNextBlock(t, _bor, chain, block, signerKey, init.genesis.Config.Bor) + _, err := chain.InsertChain([]*types.Block{block}) + assert.Equal(t, + *err.(*bor.UnauthorizedSignerError), + bor.UnauthorizedSignerError{Number: 0, Signer: addr.Bytes()}) +} + func getMockedHeimdallClient(t *testing.T) (*mocks.IHeimdallClient, *bor.HeimdallSpan) { res, heimdallSpan := loadSpanFromFile(t) h := &mocks.IHeimdallClient{} diff --git a/consensus/bor/bor_test/snapshot_test.go b/consensus/bor/bor_test/snapshot_test.go index 264c632952..6eb43b3e60 100644 --- a/consensus/bor/bor_test/snapshot_test.go +++ b/consensus/bor/bor_test/snapshot_test.go @@ -84,9 +84,9 @@ func TestGetSignerSuccessionNumber_ProposerNotFound(t *testing.T) { signer := snap.ValidatorSet.Validators[3].Address _, err := snap.GetSignerSuccessionNumber(signer) assert.NotNil(t, err) - e, ok := err.(*bor.ProposerNotFoundError) + e, ok := err.(*bor.UnauthorizedProposerError) assert.True(t, ok) - assert.Equal(t, dummyProposerAddress, e.Address) + assert.Equal(t, dummyProposerAddress.Bytes(), e.Proposer) } func TestGetSignerSuccessionNumber_SignerNotFound(t *testing.T) { @@ -97,9 +97,9 @@ func TestGetSignerSuccessionNumber_SignerNotFound(t *testing.T) { dummySignerAddress := randomAddress() _, err := snap.GetSignerSuccessionNumber(dummySignerAddress) assert.NotNil(t, err) - e, ok := err.(*bor.SignerNotFoundError) + e, ok := err.(*bor.UnauthorizedSignerError) assert.True(t, ok) - assert.Equal(t, dummySignerAddress, e.Address) + assert.Equal(t, dummySignerAddress.Bytes(), e.Signer) } func buildRandomValidatorSet(numVals int) []*bor.Validator { diff --git a/consensus/bor/errors.go b/consensus/bor/errors.go index 76d9a3ee22..fce71cd6f2 100644 --- a/consensus/bor/errors.go +++ b/consensus/bor/errors.go @@ -3,30 +3,8 @@ package bor import ( "fmt" "time" - - "github.com/maticnetwork/bor/common" ) -// Will include any new bor consensus errors here in an attempt to make error messages more descriptive - -// ProposerNotFoundError is returned if the given proposer address is not present in the validator set -type ProposerNotFoundError struct { - Address common.Address -} - -func (e *ProposerNotFoundError) Error() string { - return fmt.Sprintf("Proposer: %s not found", e.Address.Hex()) -} - -// SignerNotFoundError is returned when the signer address is not present in the validator set -type SignerNotFoundError struct { - Address common.Address -} - -func (e *SignerNotFoundError) Error() string { - return fmt.Sprintf("Signer: %s not found", e.Address.Hex()) -} - // TotalVotingPowerExceededError is returned when the maximum allowed total voting power is exceeded type TotalVotingPowerExceededError struct { Sum int64 @@ -70,17 +48,6 @@ func (e *MaxCheckpointLengthExceededError) Error() string { ) } -type SealingInFlightError struct { - Number uint64 -} - -func (e *SealingInFlightError) Error() string { - return fmt.Sprintf( - "Requested concurrent block sealing. Sealing for block %d is already in progress", - e.Number, - ) -} - // MismatchingValidatorsError is returned if a last block in sprint contains a // list of validators different from the one that local node calculated type MismatchingValidatorsError struct { @@ -111,7 +78,21 @@ func (e *BlockTooSoonError) Error() string { ) } -// UnauthorizedSignerError is returned if a header is signed by a non-authorized entity. +// UnauthorizedProposerError is returned if a header is [being] signed by an unauthorized entity. +type UnauthorizedProposerError struct { + Number uint64 + Proposer []byte +} + +func (e *UnauthorizedProposerError) Error() string { + return fmt.Sprintf( + "Proposer 0x%x is not a part of the producer set at block %d", + e.Proposer, + e.Number, + ) +} + +// UnauthorizedSignerError is returned if a header is [being] signed by an unauthorized entity. type UnauthorizedSignerError struct { Number uint64 Signer []byte @@ -119,9 +100,9 @@ type UnauthorizedSignerError struct { func (e *UnauthorizedSignerError) Error() string { return fmt.Sprintf( - "Validator set for block %d doesn't contain the signer 0x%x\n", - e.Number, + "Signer 0x%x is not a part of the producer set at block %d", e.Signer, + e.Number, ) } diff --git a/consensus/bor/snapshot.go b/consensus/bor/snapshot.go index a62c2014b9..2ff7dec0ce 100644 --- a/consensus/bor/snapshot.go +++ b/consensus/bor/snapshot.go @@ -26,7 +26,6 @@ import ( "github.com/maticnetwork/bor/core/types" "github.com/maticnetwork/bor/ethdb" "github.com/maticnetwork/bor/internal/ethapi" - "github.com/maticnetwork/bor/log" "github.com/maticnetwork/bor/params" ) @@ -191,24 +190,18 @@ func (s *Snapshot) GetSignerSuccessionNumber(signer common.Address) (int, error) proposer := s.ValidatorSet.GetProposer().Address proposerIndex, _ := s.ValidatorSet.GetByAddress(proposer) if proposerIndex == -1 { - return -1, &ProposerNotFoundError{proposer} + return -1, &UnauthorizedProposerError{s.Number, proposer.Bytes()} } signerIndex, _ := s.ValidatorSet.GetByAddress(signer) if signerIndex == -1 { - return -1, &SignerNotFoundError{signer} + return -1, &UnauthorizedSignerError{s.Number, signer.Bytes()} } - limit := len(validators)/2 + 1 tempIndex := signerIndex - if proposerIndex != tempIndex && limit > 0 { + if proposerIndex != tempIndex { if tempIndex < proposerIndex { tempIndex = tempIndex + len(validators) } - - if tempIndex-proposerIndex > limit { - log.Info("errRecentlySigned", "proposerIndex", validators[proposerIndex].Address.Hex(), "signerIndex", validators[signerIndex].Address.Hex()) - return -1, errRecentlySigned - } } return tempIndex - proposerIndex, nil } diff --git a/consensus/consensus.go b/consensus/consensus.go index 689c840dae..e86583f394 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -116,12 +116,6 @@ type Engine interface { Close() error } -// Bor is a consensus engine developed by folks at Matic Network -type Bor interface { - Engine - CancelActiveSealingOp() -} - // PoW is a consensus engine based on proof-of-work. type PoW interface { Engine diff --git a/core/blockchain.go b/core/blockchain.go index 3ce4356929..e90ffbb30e 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1718,7 +1718,6 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals bool) (int, [] if lastCanon != nil && bc.CurrentBlock().Hash() == lastCanon.Hash() { events = append(events, ChainHeadEvent{lastCanon}) } - bc.engine.(consensus.Bor).CancelActiveSealingOp() return it.index, events, coalescedLogs, err } From 8f47b3945e6916eeac94591a170cad4409711c23 Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Mon, 18 May 2020 19:26:42 +0530 Subject: [PATCH 34/46] test: Handle 204 and add test for new deposit mechanism --- consensus/bor/bor.go | 3 ++ consensus/bor/bor_test/bor_test.go | 82 ++++++++++++++++++++++++++++-- 2 files changed, 81 insertions(+), 4 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index d0d66403bf..7adebb9e4c 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -1099,6 +1099,9 @@ func (c *Bor) CommitStates( return err } var _eventRecords []*EventRecordWithTime + if response.Result == nil { // status 204 + break + } if err := json.Unmarshal(response.Result, &_eventRecords); err != nil { return err } diff --git a/consensus/bor/bor_test/bor_test.go b/consensus/bor/bor_test/bor_test.go index 0bd4a50653..8b2fde3be4 100644 --- a/consensus/bor/bor_test/bor_test.go +++ b/consensus/bor/bor_test/bor_test.go @@ -2,12 +2,15 @@ package bortest import ( "encoding/hex" + "encoding/json" "fmt" "math/big" "testing" + "time" "github.com/maticnetwork/bor/consensus/bor" "github.com/maticnetwork/bor/core/rawdb" + "github.com/maticnetwork/bor/crypto" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -54,6 +57,64 @@ func TestInsertingSpanSizeBlocks(t *testing.T) { } } +func TestFetchStateSyncEvents(t *testing.T) { + init := buildEthereumInstance(t, rawdb.NewMemoryDatabase()) + chain := init.ethereum.BlockChain() + engine := init.ethereum.Engine() + _bor := engine.(*bor.Bor) + + // A. Insert blocks for 0th sprint + db := init.ethereum.ChainDb() + block := init.genesis.ToBlock(db) + + // Insert sprintSize # of blocks so that span is fetched at the start of a new sprint + for i := uint64(1); i < sprintSize; i++ { + block = buildNextBlock(t, _bor, chain, block, nil, init.genesis.Config.Bor) + insertNewBlock(t, chain, block) + } + + // B. Before inserting 1st block of the next sprint, mock heimdall deps + // B.1 Mock /bor/span/1 + res, _ := loadSpanFromFile(t) + h := &mocks.IHeimdallClient{} + h.On("FetchWithRetry", "bor", "span", "1").Return(res, nil) + + // B.2 Mock State Sync events + // read heimdall api response from file + res = stateSyncEventsPayload(t) + var _eventRecords []*bor.EventRecordWithTime + if err := json.Unmarshal(res.Result, &_eventRecords); err != nil { + t.Fatalf("%s", err) + } + + // use that as a sample to generate bor.stateFetchLimit events + eventRecords := generateFakeStateSyncEvents(_eventRecords[0], 50) + _res, _ := json.Marshal(eventRecords) + response := bor.ResponseWithHeight{Height: "0"} + if err := json.Unmarshal(_res, &response.Result); err != nil { + t.Fatalf("%s", err) + } + + // at # sprintSize, events are fetched for the internal [from, (block-1).Time) + from := 1 + to := int64(block.Header().Time) + page := 1 + query1 := fmt.Sprintf("clerk/event-record/list?from-time=%d&to-time=%d&page=%d&limit=50", from, to, page) + h.On("FetchWithRetry", query1).Return(&response, nil) + + page = 2 + query2 := fmt.Sprintf("clerk/event-record/list?from-time=%d&to-time=%d&page=%d&limit=50", from, to, page) + h.On("FetchWithRetry", query2).Return(&bor.ResponseWithHeight{}, nil) + _bor.SetHeimdallClient(h) + + block = buildNextBlock(t, _bor, chain, block, nil, init.genesis.Config.Bor) + insertNewBlock(t, chain, block) + + assert.True(t, h.AssertCalled(t, "FetchWithRetry", "bor", "span", "1")) + assert.True(t, h.AssertCalled(t, "FetchWithRetry", query1)) + assert.True(t, h.AssertCalled(t, "FetchWithRetry", query2)) +} + func TestOutOfTurnSigning(t *testing.T) { init := buildEthereumInstance(t, rawdb.NewMemoryDatabase()) chain := init.ethereum.BlockChain() @@ -130,9 +191,22 @@ func getMockedHeimdallClient(t *testing.T) (*mocks.IHeimdallClient, *bor.Heimdal res, heimdallSpan := loadSpanFromFile(t) h := &mocks.IHeimdallClient{} h.On("FetchWithRetry", "bor", "span", "1").Return(res, nil) - - res = stateSyncEventsPayload(t) - // query := fmt.Sprintf("clerk/event-record/list?from-time=%d&to-time=%d&page=1&limit=50", 1, 1589709047) - h.On("FetchWithRetry", mock.AnythingOfType("string")).Return(res, nil) + h.On("FetchWithRetry", mock.AnythingOfType("string")).Return(stateSyncEventsPayload(t), nil) return h, heimdallSpan } + +func generateFakeStateSyncEvents(sample *bor.EventRecordWithTime, count int) []*bor.EventRecordWithTime { + events := make([]*bor.EventRecordWithTime, count) + event := *sample + event.ID = 0 + event.Time = time.Now() + events[0] = &bor.EventRecordWithTime{} + *events[0] = event + for i := 1; i < count; i++ { + event.ID = uint64(i) + event.Time = event.Time.Add(1 * time.Second) + events[i] = &bor.EventRecordWithTime{} + *events[i] = event + } + return events +} From 0e8b5ca4b7dac0c003f37b51ea58a732e3ff0b8d Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Mon, 18 May 2020 23:36:16 +0530 Subject: [PATCH 35/46] minor: separate path, query params with FetchWithRetry --- consensus/bor/bor.go | 11 ++++---- consensus/bor/bor_test/bor_test.go | 33 +++++++++++++----------- consensus/bor/rest.go | 24 +++++++----------- mocks/IHeimdallClient.go | 40 +++++++++++------------------- 4 files changed, 47 insertions(+), 61 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 7adebb9e4c..d3fde78751 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -12,7 +12,6 @@ import ( "math/big" "sort" - "strconv" "strings" "sync" "time" @@ -967,7 +966,7 @@ func (c *Bor) fetchAndCommitSpan( header *types.Header, chain core.ChainContext, ) error { - response, err := c.HeimdallClient.FetchWithRetry("bor", "span", strconv.FormatUint(newSpanID, 10)) + response, err := c.HeimdallClient.FetchWithRetry(fmt.Sprintf("bor/span/%d", newSpanID), "") if err != nil { return err @@ -1092,9 +1091,9 @@ func (c *Bor) CommitStates( page := 1 eventRecords := make([]*EventRecordWithTime, 0) for { - query := fmt.Sprintf("clerk/event-record/list?from-time=%d&to-time=%d&page=%d&limit=%d", from.Unix(), to.Unix(), page, stateFetchLimit) - log.Info("Fetching state events", "query", query) - response, err := c.HeimdallClient.FetchWithRetry(query) + queryParams := fmt.Sprintf("from-time=%d&to-time=%d&page=%d&limit=%d", from.Unix(), to.Unix(), page, stateFetchLimit) + log.Info("Fetching state sync events", "queryParams", queryParams) + response, err := c.HeimdallClient.FetchWithRetry("clerk/event-record/list", queryParams) if err != nil { return err } @@ -1119,7 +1118,7 @@ func (c *Bor) CommitStates( for _, eventRecord := range eventRecords { // if chanId doesn't match with the record, simply ignore it if eventRecord.ChainID != chainID { - log.Error(fmt.Sprintln("Chain Id in received event %s and bor chain Id %s, don't match", eventRecord, chainID)) + log.Error(fmt.Sprintf("Chain Id in received event %s and bor chain Id %s, don't match", eventRecord, chainID)) continue } // validateEventRecord checks whether an event lies in the specified time range diff --git a/consensus/bor/bor_test/bor_test.go b/consensus/bor/bor_test/bor_test.go index 8b2fde3be4..d9391f1787 100644 --- a/consensus/bor/bor_test/bor_test.go +++ b/consensus/bor/bor_test/bor_test.go @@ -20,6 +20,12 @@ import ( "github.com/maticnetwork/bor/mocks" ) +var ( + spanPath = "bor/span/1" + clerkPath = "clerk/event-record/list" + clerkQueryParams = "from-time=%d&to-time=%d&page=%d&limit=50" +) + func TestInsertingSpanSizeBlocks(t *testing.T) { init := buildEthereumInstance(t, rawdb.NewMemoryDatabase()) chain := init.ethereum.BlockChain() @@ -42,10 +48,9 @@ func TestInsertingSpanSizeBlocks(t *testing.T) { } } - assert.True(t, h.AssertCalled(t, "FetchWithRetry", "bor", "span", "1")) - query := fmt.Sprintf("clerk/event-record/list?from-time=%d&to-time=%d&page=1&limit=50", 1, to) - assert.True(t, h.AssertCalled(t, "FetchWithRetry", query)) - validators, err := _bor.GetCurrentValidators(sprintSize, spanSize) // new span starts at 256 + assert.True(t, h.AssertCalled(t, "FetchWithRetry", spanPath, "")) + assert.True(t, h.AssertCalled(t, "FetchWithRetry", clerkPath, fmt.Sprintf(clerkQueryParams, 1, to, 1))) + validators, err := _bor.GetCurrentValidators(sprintSize, spanSize) // check validator set at the first block of new span if err != nil { t.Fatalf("%s", err) } @@ -77,7 +82,7 @@ func TestFetchStateSyncEvents(t *testing.T) { // B.1 Mock /bor/span/1 res, _ := loadSpanFromFile(t) h := &mocks.IHeimdallClient{} - h.On("FetchWithRetry", "bor", "span", "1").Return(res, nil) + h.On("FetchWithRetry", spanPath, "").Return(res, nil) // B.2 Mock State Sync events // read heimdall api response from file @@ -99,20 +104,20 @@ func TestFetchStateSyncEvents(t *testing.T) { from := 1 to := int64(block.Header().Time) page := 1 - query1 := fmt.Sprintf("clerk/event-record/list?from-time=%d&to-time=%d&page=%d&limit=50", from, to, page) - h.On("FetchWithRetry", query1).Return(&response, nil) + query1Params := fmt.Sprintf(clerkQueryParams, from, to, page) + h.On("FetchWithRetry", clerkPath, query1Params).Return(&response, nil) page = 2 - query2 := fmt.Sprintf("clerk/event-record/list?from-time=%d&to-time=%d&page=%d&limit=50", from, to, page) - h.On("FetchWithRetry", query2).Return(&bor.ResponseWithHeight{}, nil) + query2Params := fmt.Sprintf(clerkQueryParams, from, to, page) + h.On("FetchWithRetry", clerkPath, query2Params).Return(&bor.ResponseWithHeight{}, nil) _bor.SetHeimdallClient(h) block = buildNextBlock(t, _bor, chain, block, nil, init.genesis.Config.Bor) insertNewBlock(t, chain, block) - assert.True(t, h.AssertCalled(t, "FetchWithRetry", "bor", "span", "1")) - assert.True(t, h.AssertCalled(t, "FetchWithRetry", query1)) - assert.True(t, h.AssertCalled(t, "FetchWithRetry", query2)) + assert.True(t, h.AssertCalled(t, "FetchWithRetry", spanPath, "")) + assert.True(t, h.AssertCalled(t, "FetchWithRetry", clerkPath, query1Params)) + assert.True(t, h.AssertCalled(t, "FetchWithRetry", clerkPath, query2Params)) } func TestOutOfTurnSigning(t *testing.T) { @@ -190,8 +195,8 @@ func TestSignerNotFound(t *testing.T) { func getMockedHeimdallClient(t *testing.T) (*mocks.IHeimdallClient, *bor.HeimdallSpan) { res, heimdallSpan := loadSpanFromFile(t) h := &mocks.IHeimdallClient{} - h.On("FetchWithRetry", "bor", "span", "1").Return(res, nil) - h.On("FetchWithRetry", mock.AnythingOfType("string")).Return(stateSyncEventsPayload(t), nil) + h.On("FetchWithRetry", "bor/span/1", "").Return(res, nil) + h.On("FetchWithRetry", mock.AnythingOfType("string"), mock.AnythingOfType("string")).Return(stateSyncEventsPayload(t), nil) return h, heimdallSpan } diff --git a/consensus/bor/rest.go b/consensus/bor/rest.go index 91aae237a7..14bfb7853c 100644 --- a/consensus/bor/rest.go +++ b/consensus/bor/rest.go @@ -6,7 +6,6 @@ import ( "io/ioutil" "net/http" "net/url" - "path" "time" "github.com/maticnetwork/bor/log" @@ -20,8 +19,8 @@ type ResponseWithHeight struct { } type IHeimdallClient interface { - Fetch(paths ...string) (*ResponseWithHeight, error) - FetchWithRetry(paths ...string) (*ResponseWithHeight, error) + Fetch(path string, query string) (*ResponseWithHeight, error) + FetchWithRetry(path string, query string) (*ResponseWithHeight, error) } type HeimdallClient struct { @@ -39,33 +38,28 @@ func NewHeimdallClient(urlString string) (*HeimdallClient, error) { return h, nil } -func (h *HeimdallClient) Fetch(paths ...string) (*ResponseWithHeight, error) { +// Fetch fetches response from heimdall +func (h *HeimdallClient) Fetch(rawPath string, rawQuery string) (*ResponseWithHeight, error) { u, err := url.Parse(h.urlString) if err != nil { return nil, err } - for _, e := range paths { - if e != "" { - u.Path = path.Join(u.Path, e) - } - } + u.Path = rawPath + u.RawQuery = rawQuery return h.internalFetch(u) } // FetchWithRetry returns data from heimdall with retry -func (h *HeimdallClient) FetchWithRetry(paths ...string) (*ResponseWithHeight, error) { +func (h *HeimdallClient) FetchWithRetry(rawPath string, rawQuery string) (*ResponseWithHeight, error) { u, err := url.Parse(h.urlString) if err != nil { return nil, err } - for _, e := range paths { - if e != "" { - u.Path = path.Join(u.Path, e) - } - } + u.Path = rawPath + u.RawQuery = rawQuery for { res, err := h.internalFetch(u) diff --git a/mocks/IHeimdallClient.go b/mocks/IHeimdallClient.go index cb09800c74..5bc7cb6e62 100644 --- a/mocks/IHeimdallClient.go +++ b/mocks/IHeimdallClient.go @@ -12,19 +12,13 @@ type IHeimdallClient struct { mock.Mock } -// Fetch provides a mock function with given fields: paths -func (_m *IHeimdallClient) Fetch(paths ...string) (*bor.ResponseWithHeight, error) { - _va := make([]interface{}, len(paths)) - for _i := range paths { - _va[_i] = paths[_i] - } - var _ca []interface{} - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// Fetch provides a mock function with given fields: path, query +func (_m *IHeimdallClient) Fetch(path string, query string) (*bor.ResponseWithHeight, error) { + ret := _m.Called(path, query) var r0 *bor.ResponseWithHeight - if rf, ok := ret.Get(0).(func(...string) *bor.ResponseWithHeight); ok { - r0 = rf(paths...) + if rf, ok := ret.Get(0).(func(string, string) *bor.ResponseWithHeight); ok { + r0 = rf(path, query) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*bor.ResponseWithHeight) @@ -32,8 +26,8 @@ func (_m *IHeimdallClient) Fetch(paths ...string) (*bor.ResponseWithHeight, erro } var r1 error - if rf, ok := ret.Get(1).(func(...string) error); ok { - r1 = rf(paths...) + if rf, ok := ret.Get(1).(func(string, string) error); ok { + r1 = rf(path, query) } else { r1 = ret.Error(1) } @@ -41,19 +35,13 @@ func (_m *IHeimdallClient) Fetch(paths ...string) (*bor.ResponseWithHeight, erro return r0, r1 } -// FetchWithRetry provides a mock function with given fields: paths -func (_m *IHeimdallClient) FetchWithRetry(paths ...string) (*bor.ResponseWithHeight, error) { - _va := make([]interface{}, len(paths)) - for _i := range paths { - _va[_i] = paths[_i] - } - var _ca []interface{} - _ca = append(_ca, _va...) - ret := _m.Called(_ca...) +// FetchWithRetry provides a mock function with given fields: path, query +func (_m *IHeimdallClient) FetchWithRetry(path string, query string) (*bor.ResponseWithHeight, error) { + ret := _m.Called(path, query) var r0 *bor.ResponseWithHeight - if rf, ok := ret.Get(0).(func(...string) *bor.ResponseWithHeight); ok { - r0 = rf(paths...) + if rf, ok := ret.Get(0).(func(string, string) *bor.ResponseWithHeight); ok { + r0 = rf(path, query) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*bor.ResponseWithHeight) @@ -61,8 +49,8 @@ func (_m *IHeimdallClient) FetchWithRetry(paths ...string) (*bor.ResponseWithHei } var r1 error - if rf, ok := ret.Get(1).(func(...string) error); ok { - r1 = rf(paths...) + if rf, ok := ret.Get(1).(func(string, string) error); ok { + r1 = rf(path, query) } else { r1 = ret.Error(1) } From ba70b74fb7ee5ad7ab69ec3f2e52d5d61d4df6a5 Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Tue, 19 May 2020 09:47:54 +0530 Subject: [PATCH 36/46] fetch events from [lastSync, (block-sprint).Time) --- consensus/bor/bor.go | 16 +++++++++------- consensus/bor/bor_test/bor_test.go | 11 +++-------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index d3fde78751..66e04dbab6 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -653,9 +653,7 @@ func (c *Bor) Prepare(chain consensus.ChainReader, header *types.Header) error { // Finalize implements consensus.Engine, ensuring no uncles are set, nor block // rewards given. func (c *Bor) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) { - // commit span headerNumber := header.Number.Uint64() - if headerNumber%c.config.Sprint == 0 { cx := chainContext{Chain: chain, Bor: c} // check and commit span @@ -663,6 +661,7 @@ func (c *Bor) Finalize(chain consensus.ChainReader, header *types.Header, state log.Error("Error while committing span", "error", err) return } + // commit statees if err := c.CommitStates(state, header, cx); err != nil { log.Error("Error while committing states", "error", err) @@ -678,8 +677,8 @@ func (c *Bor) Finalize(chain consensus.ChainReader, header *types.Header, state // FinalizeAndAssemble implements consensus.Engine, ensuring no uncles are set, // nor block rewards given, and returns the final block. func (c *Bor) FinalizeAndAssemble(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) { - // commit span - if header.Number.Uint64()%c.config.Sprint == 0 { + headerNumber := header.Number.Uint64() + if headerNumber%c.config.Sprint == 0 { cx := chainContext{Chain: chain, Bor: c} // check and commit span @@ -1082,7 +1081,10 @@ func (c *Bor) CommitStates( return err } from := lastSync.Add(time.Second * 1) // querying the interval [from, to) - to := time.Unix(int64(chain.Chain.GetHeaderByNumber(number-1).Time), 0) + to := time.Unix(int64(chain.Chain.GetHeaderByNumber(number-c.config.Sprint).Time), 0) + if !from.Before(to) { + return nil + } log.Info( "Fetching state updates from Heimdall", "from", from.Format(time.RFC3339), @@ -1150,8 +1152,8 @@ func (c *Bor) CommitStates( } func validateEventRecord(eventRecord *EventRecordWithTime, number uint64, from, to time.Time) error { - inRange := (eventRecord.Time.Equal(from) || eventRecord.Time.After(from)) && eventRecord.Time.Before(to) - if !inRange { + // event should lie in the range [from, to) + if eventRecord.Time.Before(from) || !eventRecord.Time.Before(to) { return &InvalidStateReceivedError{number, &from, &to, eventRecord} } return nil diff --git a/consensus/bor/bor_test/bor_test.go b/consensus/bor/bor_test/bor_test.go index d9391f1787..8cbdbfa8a4 100644 --- a/consensus/bor/bor_test/bor_test.go +++ b/consensus/bor/bor_test/bor_test.go @@ -36,16 +36,12 @@ func TestInsertingSpanSizeBlocks(t *testing.T) { db := init.ethereum.ChainDb() block := init.genesis.ToBlock(db) - var to int64 + to := int64(block.Header().Time) // Insert sprintSize # of blocks so that span is fetched at the start of a new sprint for i := uint64(1); i <= spanSize; i++ { block = buildNextBlock(t, _bor, chain, block, nil, init.genesis.Config.Bor) insertNewBlock(t, chain, block) - if i == sprintSize-1 { - // at # sprintSize, events are fetched for the internal [from, (block-1).Time) - to = int64(block.Header().Time) - } } assert.True(t, h.AssertCalled(t, "FetchWithRetry", spanPath, "")) @@ -71,7 +67,6 @@ func TestFetchStateSyncEvents(t *testing.T) { // A. Insert blocks for 0th sprint db := init.ethereum.ChainDb() block := init.genesis.ToBlock(db) - // Insert sprintSize # of blocks so that span is fetched at the start of a new sprint for i := uint64(1); i < sprintSize; i++ { block = buildNextBlock(t, _bor, chain, block, nil, init.genesis.Config.Bor) @@ -100,9 +95,9 @@ func TestFetchStateSyncEvents(t *testing.T) { t.Fatalf("%s", err) } - // at # sprintSize, events are fetched for the internal [from, (block-1).Time) + // at # sprintSize, events are fetched for the interval [from, (block-sprint).Time) from := 1 - to := int64(block.Header().Time) + to := int64(chain.GetHeaderByNumber(0).Time) page := 1 query1Params := fmt.Sprintf(clerkQueryParams, from, to, page) h.On("FetchWithRetry", clerkPath, query1Params).Return(&response, nil) From fa52ce61f7f55d679fcc5856a9ea6aefe52522c7 Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Tue, 19 May 2020 12:05:29 +0530 Subject: [PATCH 37/46] sort state events acc to id --- consensus/bor/bor.go | 14 +++++--------- consensus/bor/genesis_contracts_client.go | 2 +- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 66e04dbab6..e34a604c68 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -1112,21 +1112,17 @@ func (c *Bor) CommitStates( } page++ } + sort.SliceStable(eventRecords, func(i, j int) bool { - return eventRecords[i].Time.Before(eventRecords[j].Time) + return eventRecords[i].ID < eventRecords[j].ID }) chainID := c.chainConfig.ChainID.String() for _, eventRecord := range eventRecords { - // if chanId doesn't match with the record, simply ignore it - if eventRecord.ChainID != chainID { - log.Error(fmt.Sprintf("Chain Id in received event %s and bor chain Id %s, don't match", eventRecord, chainID)) - continue - } // validateEventRecord checks whether an event lies in the specified time range // since the events are sorted by time and if it turns out that event i lies outside the time range, // it would mean all subsequent events lie outside of the time range. Hence we don't probe any further and break the loop - if err := validateEventRecord(eventRecord, number, from, to); err != nil { + if err := validateEventRecord(eventRecord, number, from, to, chainID); err != nil { log.Error( fmt.Sprintf( "Received event %s does not lie in the time range, from %s, to %s", @@ -1151,9 +1147,9 @@ func (c *Bor) CommitStates( return nil } -func validateEventRecord(eventRecord *EventRecordWithTime, number uint64, from, to time.Time) error { +func validateEventRecord(eventRecord *EventRecordWithTime, number uint64, from, to time.Time, chainID string) error { // event should lie in the range [from, to) - if eventRecord.Time.Before(from) || !eventRecord.Time.Before(to) { + if eventRecord.ChainID != chainID || eventRecord.Time.Before(from) || !eventRecord.Time.Before(to) { return &InvalidStateReceivedError{number, &from, &to, eventRecord} } return nil diff --git a/consensus/bor/genesis_contracts_client.go b/consensus/bor/genesis_contracts_client.go index 4afbdabbf6..bd679e2f70 100644 --- a/consensus/bor/genesis_contracts_client.go +++ b/consensus/bor/genesis_contracts_client.go @@ -30,7 +30,7 @@ type GenesisContractsClient struct { } const validatorsetABI = `[{"constant":true,"inputs":[],"name":"SPRINT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SYSTEM_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"CHAIN","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FIRST_END_BLOCK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"producers","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ROUND_TYPE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"BOR_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"spanNumbers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"VOTE_TYPE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"validators","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"spans","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"startBlock","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"endBlock","type":"uint256"}],"name":"NewSpan","type":"event"},{"constant":true,"inputs":[],"name":"currentSprint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"}],"name":"getSpan","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCurrentSpan","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNextSpan","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"number","type":"uint256"}],"name":"getSpanByBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"currentSpanNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"}],"name":"getValidatorsTotalStakeBySpan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"}],"name":"getProducersTotalStakeBySpan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"name":"getValidatorBySigner","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"internalType":"struct BorValidatorSet.Validator","name":"result","type":"tuple"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"name":"isValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"name":"isProducer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"isCurrentValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"isCurrentProducer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"number","type":"uint256"}],"name":"getBorValidators","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitialValidators","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getValidators","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"newSpan","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"},{"internalType":"bytes","name":"validatorBytes","type":"bytes"},{"internalType":"bytes","name":"producerBytes","type":"bytes"}],"name":"commitSpan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"bytes32","name":"dataHash","type":"bytes32"},{"internalType":"bytes","name":"sigs","type":"bytes"}],"name":"getStakePowerBySigs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"internalType":"bytes32","name":"leaf","type":"bytes32"},{"internalType":"bytes","name":"proof","type":"bytes"}],"name":"checkMembership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"d","type":"bytes32"}],"name":"leafNode","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"left","type":"bytes32"},{"internalType":"bytes32","name":"right","type":"bytes32"}],"name":"innerNode","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"}]` -const stateReceiverABI = `[{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"states","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SYSTEM_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastStateSyncTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"syncTime","type":"uint256"},{"internalType":"bytes","name":"recordBytes","type":"bytes"}],"name":"commitState","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]` +const stateReceiverABI = `[{"constant":true,"inputs":[],"name":"SYSTEM_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastStateSyncTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastStateId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"syncTime","type":"uint256"},{"internalType":"bytes","name":"recordBytes","type":"bytes"}],"name":"commitState","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]` func NewGenesisContractsClient( chainConfig *params.ChainConfig, From 742c2104afaba0712bff0790bae539dacb6fb55a Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Tue, 19 May 2020 21:16:37 +0530 Subject: [PATCH 38/46] alter the fetch logic a bit --- consensus/bor/bor.go | 32 +++++++++++++---------- consensus/bor/errors.go | 14 +++++----- consensus/bor/genesis_contracts_client.go | 27 +++++++++++++++++++ 3 files changed, 53 insertions(+), 20 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index e34a604c68..f2ba5cdb04 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -1080,8 +1080,14 @@ func (c *Bor) CommitStates( if err != nil { return err } - from := lastSync.Add(time.Second * 1) // querying the interval [from, to) - to := time.Unix(int64(chain.Chain.GetHeaderByNumber(number-c.config.Sprint).Time), 0) + _lastStateID, err := c.genesisContractsClient.LastStateId(number - 1) + if err != nil { + return err + } + + from := *lastSync + to := time.Unix(int64(chain.Chain.GetHeaderByNumber(number-1).Time), 0) + lastStateID := _lastStateID.Uint64() if !from.Before(to) { return nil } @@ -1119,14 +1125,11 @@ func (c *Bor) CommitStates( chainID := c.chainConfig.ChainID.String() for _, eventRecord := range eventRecords { - // validateEventRecord checks whether an event lies in the specified time range - // since the events are sorted by time and if it turns out that event i lies outside the time range, - // it would mean all subsequent events lie outside of the time range. Hence we don't probe any further and break the loop - if err := validateEventRecord(eventRecord, number, from, to, chainID); err != nil { - log.Error( - fmt.Sprintf( - "Received event %s does not lie in the time range, from %s, to %s", - eventRecord, from.Format(time.RFC3339), to.Format(time.RFC3339))) + if eventRecord.ID <= lastStateID { + continue + } + if err := validateEventRecord(eventRecord, number, from, to, lastStateID, chainID); err != nil { + log.Error(err.Error()) break } @@ -1144,13 +1147,14 @@ func (c *Bor) CommitStates( return err } } + lastStateID++ return nil } -func validateEventRecord(eventRecord *EventRecordWithTime, number uint64, from, to time.Time, chainID string) error { - // event should lie in the range [from, to) - if eventRecord.ChainID != chainID || eventRecord.Time.Before(from) || !eventRecord.Time.Before(to) { - return &InvalidStateReceivedError{number, &from, &to, eventRecord} +func validateEventRecord(eventRecord *EventRecordWithTime, number uint64, from, to time.Time, lastStateID uint64, chainID string) error { + // event id should be sequential and event.Time should lie in the range [from, to) + if lastStateID+1 != eventRecord.ID || eventRecord.ChainID != chainID || eventRecord.Time.Before(from) || !eventRecord.Time.Before(to) { + return &InvalidStateReceivedError{number, lastStateID, &from, &to, eventRecord} } return nil } diff --git a/consensus/bor/errors.go b/consensus/bor/errors.go index fce71cd6f2..778a2672b0 100644 --- a/consensus/bor/errors.go +++ b/consensus/bor/errors.go @@ -126,18 +126,20 @@ func (e *WrongDifficultyError) Error() string { } type InvalidStateReceivedError struct { - Number uint64 - From *time.Time - To *time.Time - Event *EventRecordWithTime + Number uint64 + LastStateID uint64 + From *time.Time + To *time.Time + Event *EventRecordWithTime } func (e *InvalidStateReceivedError) Error() string { return fmt.Sprintf( - "Received event with invalid timestamp at block %d. Requested events from %s to %s. Received %s\n", + "Received invalid event %s at block %d. Requested events from %s to %s. lastStateID was %d.\n", + e.Event, e.Number, e.From.Format(time.RFC3339), e.To.Format(time.RFC3339), - e.Event, + e.LastStateID, ) } diff --git a/consensus/bor/genesis_contracts_client.go b/consensus/bor/genesis_contracts_client.go index bd679e2f70..48c4bb5e63 100644 --- a/consensus/bor/genesis_contracts_client.go +++ b/consensus/bor/genesis_contracts_client.go @@ -103,3 +103,30 @@ func (gc *GenesisContractsClient) LastStateSyncTime(snapshotNumber uint64) (*tim _time := time.Unix((*ret).Int64(), 0) return &_time, nil } + +func (gc *GenesisContractsClient) LastStateId(snapshotNumber uint64) (*big.Int, error) { + method := "lastStateId" + data, err := gc.stateReceiverABI.Pack(method) + if err != nil { + log.Error("Unable to pack tx for getLastSyncTime", "error", err) + return nil, err + } + + msgData := (hexutil.Bytes)(data) + toAddress := common.HexToAddress(gc.StateReceiverContract) + gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2)) + result, err := gc.ethAPI.Call(context.Background(), ethapi.CallArgs{ + Gas: &gas, + To: &toAddress, + Data: &msgData, + }, rpc.BlockNumber(snapshotNumber)) + if err != nil { + return nil, err + } + + var ret = new(*big.Int) + if err := gc.stateReceiverABI.Unpack(ret, method, result); err != nil { + return nil, err + } + return *ret, nil +} From 89248d711670dd3ed1c6d692a1e125bbc00174d7 Mon Sep 17 00:00:00 2001 From: Arpit Agarwal <93arpit@gmail.com> Date: Tue, 19 May 2020 21:34:35 +0530 Subject: [PATCH 39/46] Update consensus/bor/bor.go Co-authored-by: Jaynti Kanani --- consensus/bor/bor.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index f2ba5cdb04..15c94e6d53 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -1086,7 +1086,7 @@ func (c *Bor) CommitStates( } from := *lastSync - to := time.Unix(int64(chain.Chain.GetHeaderByNumber(number-1).Time), 0) + to := time.Unix(int64(chain.Chain.GetHeaderByNumber(number-c.config.Sprint).Time), 0) lastStateID := _lastStateID.Uint64() if !from.Before(to) { return nil From 3236e423d2bad7883e6e1846df49be2a8e256efd Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Tue, 19 May 2020 21:42:32 +0530 Subject: [PATCH 40/46] dont return a pointer from LastStateSyncTime --- consensus/bor/bor.go | 2 +- consensus/bor/genesis_contracts_client.go | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 15c94e6d53..37ae73128f 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -1085,7 +1085,7 @@ func (c *Bor) CommitStates( return err } - from := *lastSync + from := lastSync to := time.Unix(int64(chain.Chain.GetHeaderByNumber(number-c.config.Sprint).Time), 0) lastStateID := _lastStateID.Uint64() if !from.Before(to) { diff --git a/consensus/bor/genesis_contracts_client.go b/consensus/bor/genesis_contracts_client.go index 48c4bb5e63..fe995dfbf7 100644 --- a/consensus/bor/genesis_contracts_client.go +++ b/consensus/bor/genesis_contracts_client.go @@ -76,12 +76,12 @@ func (gc *GenesisContractsClient) CommitState( return nil } -func (gc *GenesisContractsClient) LastStateSyncTime(snapshotNumber uint64) (*time.Time, error) { +func (gc *GenesisContractsClient) LastStateSyncTime(snapshotNumber uint64) (time.Time, error) { method := "lastStateSyncTime" data, err := gc.stateReceiverABI.Pack(method) if err != nil { log.Error("Unable to pack tx for getLastSyncTime", "error", err) - return nil, err + return time.Time{}, err } msgData := (hexutil.Bytes)(data) @@ -93,15 +93,14 @@ func (gc *GenesisContractsClient) LastStateSyncTime(snapshotNumber uint64) (*tim Data: &msgData, }, rpc.BlockNumber(snapshotNumber)) if err != nil { - return nil, err + return time.Time{}, err } var ret = new(*big.Int) if err := gc.stateReceiverABI.Unpack(ret, method, result); err != nil { - return nil, err + return time.Time{}, err } - _time := time.Unix((*ret).Int64(), 0) - return &_time, nil + return time.Unix((*ret).Int64(), 0), nil } func (gc *GenesisContractsClient) LastStateId(snapshotNumber uint64) (*big.Int, error) { From 200472dfdc2d20a3e95ef0c613b20b9539485263 Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Wed, 20 May 2020 08:54:46 +0530 Subject: [PATCH 41/46] update bytecode in genesis --- consensus/bor/bor_test/bor_test.go | 4 ++-- consensus/bor/bor_test/genesis.json | 8 ++++---- consensus/bor/genesis_contracts_client.go | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/consensus/bor/bor_test/bor_test.go b/consensus/bor/bor_test/bor_test.go index 8cbdbfa8a4..31db0d17d0 100644 --- a/consensus/bor/bor_test/bor_test.go +++ b/consensus/bor/bor_test/bor_test.go @@ -45,7 +45,7 @@ func TestInsertingSpanSizeBlocks(t *testing.T) { } assert.True(t, h.AssertCalled(t, "FetchWithRetry", spanPath, "")) - assert.True(t, h.AssertCalled(t, "FetchWithRetry", clerkPath, fmt.Sprintf(clerkQueryParams, 1, to, 1))) + assert.True(t, h.AssertCalled(t, "FetchWithRetry", clerkPath, fmt.Sprintf(clerkQueryParams, 0, to, 1))) validators, err := _bor.GetCurrentValidators(sprintSize, spanSize) // check validator set at the first block of new span if err != nil { t.Fatalf("%s", err) @@ -96,7 +96,7 @@ func TestFetchStateSyncEvents(t *testing.T) { } // at # sprintSize, events are fetched for the interval [from, (block-sprint).Time) - from := 1 + from := 0 to := int64(chain.GetHeaderByNumber(0).Time) page := 1 query1Params := fmt.Sprintf(clerkQueryParams, from, to, page) diff --git a/consensus/bor/bor_test/genesis.json b/consensus/bor/bor_test/genesis.json index 8842554c3e..a77b7b79ed 100644 --- a/consensus/bor/bor_test/genesis.json +++ b/consensus/bor/bor_test/genesis.json @@ -10,7 +10,7 @@ "constantinopleBlock": 0, "bor": { "period": 1, - "producerDelay": 1, + "producerDelay": 4, "sprint": 4, "backupMultiplier": 1, "validatorContract": "0x0000000000000000000000000000000000001000", @@ -27,15 +27,15 @@ "alloc": { "0000000000000000000000000000000000001000": { "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b50600436106101f05760003560e01c806360c8614d1161010f578063af26aa96116100a2578063d5b844eb11610071578063d5b844eb14610666578063dcf2793a14610684578063e3b7c924146106b6578063f59cf565146106d4576101f0565b8063af26aa96146105c7578063b71d7a69146105e7578063b7ab4db514610617578063c1b3c91914610636576101f0565b806370ba5707116100de57806370ba57071461052b57806398ab2b621461055b5780639d11b80714610579578063ae756451146105a9576101f0565b806360c8614d1461049c57806365b3a1e2146104bc57806366332354146104db578063687a9bd6146104f9576101f0565b80633434735f1161018757806344d6528f1161015657806344d6528f146103ee5780634dbc959f1461041e57806355614fcc1461043c578063582a8d081461046c576101f0565b80633434735f1461035257806335ddfeea1461037057806343ee8213146103a057806344c15cb1146103be576101f0565b806323f2a73f116101c357806323f2a73f146102a45780632bc06564146102d45780632de3a180146102f25780632eddf35214610322576101f0565b8063047a6c5b146101f55780630c35b1cb146102275780631270b5741461025857806323c2a2b414610288575b600080fd5b61020f600480360361020a919081019061290d565b610706565b60405161021e939291906131ec565b60405180910390f35b610241600480360361023c919081019061290d565b61075d565b60405161024f92919061302d565b60405180910390f35b610272600480360361026d9190810190612936565b610939565b60405161027f9190613064565b60405180910390f35b6102a2600480360361029d9190810190612a15565b610a91565b005b6102be60048036036102b99190810190612936565b6110f4565b6040516102cb9190613064565b60405180910390f35b6102dc61124b565b6040516102e9919061319a565b60405180910390f35b61030c6004803603610307919081019061286a565b611250565b604051610319919061307f565b60405180910390f35b61033c6004803603610337919081019061290d565b6112d1565b604051610349919061319a565b60405180910390f35b61035a611401565b6040516103679190613012565b60405180910390f35b61038a600480360361038591908101906128a6565b611419565b6040516103979190613064565b60405180910390f35b6103a86114e4565b6040516103b5919061307f565b60405180910390f35b6103d860048036036103d39190810190612972565b6114fb565b6040516103e5919061319a565b60405180910390f35b61040860048036036104039190810190612936565b6115e3565b604051610415919061317f565b60405180910390f35b61042661174b565b604051610433919061319a565b60405180910390f35b610456600480360361045191908101906127ef565b61175b565b6040516104639190613064565b60405180910390f35b61048660048036036104819190810190612818565b611775565b604051610493919061307f565b60405180910390f35b6104a46117f3565b6040516104b3939291906131ec565b60405180910390f35b6104c4611867565b6040516104d292919061302d565b60405180910390f35b6104e3611957565b6040516104f0919061319a565b60405180910390f35b610513600480360361050e91908101906129d9565b61195c565b604051610522939291906131b5565b60405180910390f35b610545600480360361054091908101906127ef565b6119c0565b6040516105529190613064565b60405180910390f35b6105636119da565b604051610570919061307f565b60405180910390f35b610593600480360361058e919081019061290d565b6119f1565b6040516105a0919061319a565b60405180910390f35b6105b1611b22565b6040516105be919061307f565b60405180910390f35b6105cf611b39565b6040516105de939291906131ec565b60405180910390f35b61060160048036036105fc919081019061290d565b611b9a565b60405161060e919061319a565b60405180910390f35b61061f611c9a565b60405161062d92919061302d565b60405180910390f35b610650600480360361064b919081019061290d565b611cae565b60405161065d919061319a565b60405180910390f35b61066e611ccf565b60405161067b9190613223565b60405180910390f35b61069e600480360361069991908101906129d9565b611cd4565b6040516106ad939291906131b5565b60405180910390f35b6106be611d38565b6040516106cb919061319a565b60405180910390f35b6106ee60048036036106e9919081019061290d565b611d4a565b6040516106fd939291906131ec565b60405180910390f35b60008060006002600085815260200190815260200160002060000154600260008681526020019081526020016000206001015460026000878152602001908152602001600020600201549250925092509193909250565b6060806007831161077957610770611867565b91509150610934565b600061078484611b9a565b9050606060016000838152602001908152602001600020805490506040519080825280602002602001820160405280156107cd5781602001602082028038833980820191505090505b509050606060016000848152602001908152602001600020805490506040519080825280602002602001820160405280156108175781602001602082028038833980820191505090505b50905060008090505b60016000858152602001908152602001600020805490508110156109295760016000858152602001908152602001600020818154811061085c57fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683828151811061089a57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506001600085815260200190815260200160002081815481106108f257fe5b90600052602060002090600302016001015482828151811061091057fe5b6020026020010181815250508080600101915050610820565b508181945094505050505b915091565b6000606060016000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015610a0c578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190610970565b50505050905060008090505b8151811015610a84578373ffffffffffffffffffffffffffffffffffffffff16828281518110610a4457fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff161415610a7757600192505050610a8b565b8080600101915050610a18565b5060009150505b92915050565b73fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610add57600080fd5b6000610ae761174b565b90506000811415610afb57610afa611d74565b5b610b0f60018261209590919063ffffffff16565b8814610b50576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b47906130ff565b60405180910390fd5b868611610b92576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b899061315f565b60405180910390fd5b6000600460018989030181610ba357fe5b0614610be4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bdb9061313f565b60405180910390fd5b8660026000838152602001908152602001600020600101541115610c3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c34906130df565b60405180910390fd5b6000600260008a81526020019081526020016000206000015414610c96576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c8d9061311f565b60405180910390fd5b604051806060016040528089815260200188815260200187815250600260008a8152602001908152602001600020600082015181600001556020820151816001015560408201518160020155905050600388908060018154018082558091505090600182039060005260206000200160009091929091909150555060008060008a815260200190815260200160002081610d3091906125e9565b506000600160008a815260200190815260200160002081610d5191906125e9565b506060610da9610da487878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506120b4565b6120e2565b905060008090505b8151811015610f1b576060610dd8838381518110610dcb57fe5b60200260200101516120e2565b90506000808c81526020019081526020016000208054809190600101610dfe91906125e9565b506040518060600160405280610e2783600081518110610e1a57fe5b60200260200101516121bf565b8152602001610e4983600181518110610e3c57fe5b60200260200101516121bf565b8152602001610e6b83600281518110610e5e57fe5b6020026020010151612230565b73ffffffffffffffffffffffffffffffffffffffff168152506000808d81526020019081526020016000208381548110610ea157fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050508080600101915050610db1565b506060610f73610f6e86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506120b4565b6120e2565b905060008090505b81518110156110e7576060610fa2838381518110610f9557fe5b60200260200101516120e2565b9050600160008d81526020019081526020016000208054809190600101610fc991906125e9565b506040518060600160405280610ff283600081518110610fe557fe5b60200260200101516121bf565b81526020016110148360018151811061100757fe5b60200260200101516121bf565b81526020016110368360028151811061102957fe5b6020026020010151612230565b73ffffffffffffffffffffffffffffffffffffffff16815250600160008e8152602001908152602001600020838154811061106d57fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050508080600101915050610f7b565b5050505050505050505050565b60006060600080858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156111c6578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250508152602001906001019061112a565b50505050905060008090505b815181101561123e578373ffffffffffffffffffffffffffffffffffffffff168282815181106111fe57fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff16141561123157600192505050611245565b80806001019150506111d2565b5060009150505b92915050565b600481565b60006002600160f81b848460405160200161126d93929190612f7f565b6040516020818303038152906040526040516112899190612fbc565b602060405180830381855afa1580156112a6573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506112c99190810190612841565b905092915050565b60006060600080848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156113a3578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611307565b505050509050600080905060008090505b82518110156113f6576113e78382815181106113cc57fe5b6020026020010151602001518361209590919063ffffffff16565b915080806001019150506113b4565b508092505050919050565b73fffffffffffffffffffffffffffffffffffffffe81565b600080600080859050600060218087518161143057fe5b0402905060008111156114495761144687611775565b91505b6000602190505b8181116114d35760006001820388015190508188015195508060006020811061147557fe5b1a60f81b9450600060f81b857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156114ba576114b38685611250565b93506114c7565b6114c48487611250565b93505b50602181019050611450565b508782149450505050509392505050565b6040516114f090612fe8565b604051809103902081565b60008060009050600080905060008090505b84518167ffffffffffffffff1610156115d6576060611538868367ffffffffffffffff166041612253565b9050600061154f82896122df90919063ffffffff16565b905061155961261b565b6115638a836115e3565b905061156f8a836110f4565b80156115a657508473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16115b156115c8578194506115c581602001518761209590919063ffffffff16565b95505b50505060418101905061150d565b5081925050509392505050565b6115eb61261b565b6060600080858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156116bb578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250508152602001906001019061161f565b50505050905060008090505b8151811015611743578373ffffffffffffffffffffffffffffffffffffffff168282815181106116f357fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff1614156117365781818151811061172757fe5b60200260200101519250611743565b80806001019150506116c7565b505092915050565b600061175643611b9a565b905090565b600061176e61176861174b565b836110f4565b9050919050565b60006002600060f81b83604051602001611790929190612f53565b6040516020818303038152906040526040516117ac9190612fbc565b602060405180830381855afa1580156117c9573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506117ec9190810190612841565b9050919050565b600080600080611814600161180661174b565b61209590919063ffffffff16565b905060026000828152602001908152602001600020600001546002600083815260200190815260200160002060010154600260008481526020019081526020016000206002015493509350935050909192565b6060806060600160405190808252806020026020018201604052801561189c5781602001602082028038833980820191505090505b5090507371562b71999873db5b286df957af199ec94617f7816000815181106118c157fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506060600160405190808252806020026020018201604052801561192d5781602001602082028038833980820191505090505b509050600a8160008151811061193f57fe5b60200260200101818152505081819350935050509091565b600781565b6001602052816000526040600020818154811061197557fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b60006119d36119cd61174b565b83610939565b9050919050565b6040516119e690612fd3565b604051809103902081565b6000606060016000848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015611ac4578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611a28565b505050509050600080905060008090505b8251811015611b1757611b08838281518110611aed57fe5b6020026020010151602001518361209590919063ffffffff16565b91508080600101915050611ad5565b508092505050919050565b604051611b2e90612ffd565b604051809103902081565b600080600080611b4761174b565b905060026000828152602001908152602001600020600001546002600083815260200190815260200160002060010154600260008481526020019081526020016000206002015493509350935050909192565b60008060038054905090505b6000811115611c5a57611bb7612652565b6002600060036001850381548110611bcb57fe5b906000526020600020015481526020019081526020016000206040518060600160405290816000820154815260200160018201548152602001600282015481525050905083816020015111158015611c2857506000816040015114155b8015611c38575080604001518411155b15611c4b57806000015192505050611c95565b50808060019003915050611ba6565b5060006003805490501115611c9057600360016003805490500381548110611c7e57fe5b90600052602060002001549050611c95565b600090505b919050565b606080611ca64361075d565b915091509091565b60038181548110611cbb57fe5b906000526020600020016000915090505481565b600281565b60006020528160005260406000208181548110611ced57fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b600060044381611d4457fe5b04905090565b60026020528060005260406000206000915090508060000154908060010154908060020154905083565b606080611d7f611867565b809250819350505060008090506040518060600160405280828152602001600081526020016007815250600260008381526020019081526020016000206000820151816000015560208201518160010155604082015181600201559050506003819080600181540180825580915050906001820390600052602060002001600090919290919091505550600080600083815260200190815260200160002081611e2891906125e9565b5060006001600083815260200190815260200160002081611e4991906125e9565b5060008090505b8351811015611f6b576000808381526020019081526020016000208054809190600101611e7d91906125e9565b506040518060600160405280828152602001848381518110611e9b57fe5b60200260200101518152602001858381518110611eb457fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff168152506000808481526020019081526020016000208281548110611ef257fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050508080600101915050611e50565b5060008090505b835181101561208f57600160008381526020019081526020016000208054809190600101611fa091906125e9565b506040518060600160405280828152602001848381518110611fbe57fe5b60200260200101518152602001858381518110611fd757fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681525060016000848152602001908152602001600020828154811061201657fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050508080600101915050611f72565b50505050565b6000808284019050838110156120aa57600080fd5b8091505092915050565b6120bc612673565b600060208301905060405180604001604052808451815260200182815250915050919050565b60606120ed826123e9565b6120f657600080fd5b600061210183612437565b905060608160405190808252806020026020018201604052801561213f57816020015b61212c61268d565b8152602001906001900390816121245790505b509050600061215185602001516124a8565b8560200151019050600080600090505b848110156121b25761217283612531565b915060405180604001604052808381526020018481525084828151811061219557fe5b602002602001018190525081830192508080600101915050612161565b5082945050505050919050565b60008082600001511180156121d957506021826000015111155b6121e257600080fd5b60006121f183602001516124a8565b9050600081846000015103905060008083866020015101905080519150602083101561222457826020036101000a820491505b81945050505050919050565b6000601582600001511461224357600080fd5b61224c826121bf565b9050919050565b60608183018451101561226557600080fd5b6060821560008114612282576040519150602082016040526122d3565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156122c057805183526020830192506020810190506122a3565b50868552601f19601f8301166040525050505b50809150509392505050565b60008060008060418551146122fa57600093505050506123e3565b602085015192506040850151915060ff6041860151169050601b8160ff16101561232557601b810190505b601b8160ff161415801561233d5750601c8160ff1614155b1561234e57600093505050506123e3565b600060018783868660405160008152602001604052604051612373949392919061309a565b6020604051602081039080840390855afa158015612395573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156123db57600080fd5b809450505050505b92915050565b600080826000015114156124005760009050612432565b60008083602001519050805160001a915060c060ff168260ff16101561242b57600092505050612432565b6001925050505b919050565b6000808260000151141561244e57600090506124a3565b6000809050600061246284602001516124a8565b84602001510190506000846000015185602001510190505b8082101561249c5761248b82612531565b82019150828060010193505061247a565b8293505050505b919050565b600080825160001a9050608060ff168110156124c857600091505061252c565b60b860ff168110806124ed575060c060ff1681101580156124ec575060f860ff1681105b5b156124fc57600191505061252c565b60c060ff1681101561251c5760018060b80360ff1682030191505061252c565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff1681101561255257600191506125df565b60b860ff1681101561256f576001608060ff1682030191506125de565b60c060ff1681101561259f5760b78103600185019450806020036101000a855104600182018101935050506125dd565b60f860ff168110156125bc57600160c060ff1682030191506125dc565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b8154818355818111156126165760030281600302836000526020600020918201910161261591906126a7565b5b505050565b60405180606001604052806000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b60405180606001604052806000815260200160008152602001600081525090565b604051806040016040528060008152602001600081525090565b604051806040016040528060008152602001600081525090565b6126fa91905b808211156126f65760008082016000905560018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055506003016126ad565b5090565b90565b60008135905061270c8161341c565b92915050565b60008135905061272181613433565b92915050565b60008151905061273681613433565b92915050565b60008083601f84011261274e57600080fd5b8235905067ffffffffffffffff81111561276757600080fd5b60208301915083600182028301111561277f57600080fd5b9250929050565b600082601f83011261279757600080fd5b81356127aa6127a58261326b565b61323e565b915080825260208301602083018583830111156127c657600080fd5b6127d18382846133c6565b50505092915050565b6000813590506127e98161344a565b92915050565b60006020828403121561280157600080fd5b600061280f848285016126fd565b91505092915050565b60006020828403121561282a57600080fd5b600061283884828501612712565b91505092915050565b60006020828403121561285357600080fd5b600061286184828501612727565b91505092915050565b6000806040838503121561287d57600080fd5b600061288b85828601612712565b925050602061289c85828601612712565b9150509250929050565b6000806000606084860312156128bb57600080fd5b60006128c986828701612712565b93505060206128da86828701612712565b925050604084013567ffffffffffffffff8111156128f757600080fd5b61290386828701612786565b9150509250925092565b60006020828403121561291f57600080fd5b600061292d848285016127da565b91505092915050565b6000806040838503121561294957600080fd5b6000612957858286016127da565b9250506020612968858286016126fd565b9150509250929050565b60008060006060848603121561298757600080fd5b6000612995868287016127da565b93505060206129a686828701612712565b925050604084013567ffffffffffffffff8111156129c357600080fd5b6129cf86828701612786565b9150509250925092565b600080604083850312156129ec57600080fd5b60006129fa858286016127da565b9250506020612a0b858286016127da565b9150509250929050565b600080600080600080600060a0888a031215612a3057600080fd5b6000612a3e8a828b016127da565b9750506020612a4f8a828b016127da565b9650506040612a608a828b016127da565b955050606088013567ffffffffffffffff811115612a7d57600080fd5b612a898a828b0161273c565b9450945050608088013567ffffffffffffffff811115612aa857600080fd5b612ab48a828b0161273c565b925092505092959891949750929550565b6000612ad18383612af5565b60208301905092915050565b6000612ae98383612f26565b60208301905092915050565b612afe8161333b565b82525050565b612b0d8161333b565b82525050565b6000612b1e826132b7565b612b2881856132f2565b9350612b3383613297565b8060005b83811015612b64578151612b4b8882612ac5565b9750612b56836132d8565b925050600181019050612b37565b5085935050505092915050565b6000612b7c826132c2565b612b868185613303565b9350612b91836132a7565b8060005b83811015612bc2578151612ba98882612add565b9750612bb4836132e5565b925050600181019050612b95565b5085935050505092915050565b612bd88161334d565b82525050565b612bef612bea82613359565b613408565b82525050565b612bfe81613385565b82525050565b612c15612c1082613385565b613412565b82525050565b6000612c26826132cd565b612c308185613314565b9350612c408185602086016133d5565b80840191505092915050565b6000612c59600483613330565b91507f766f7465000000000000000000000000000000000000000000000000000000006000830152600482019050919050565b6000612c99602d8361331f565b91507f537461727420626c6f636b206d7573742062652067726561746572207468616e60008301527f2063757272656e74207370616e000000000000000000000000000000000000006020830152604082019050919050565b6000612cff600f8361331f565b91507f496e76616c6964207370616e20696400000000000000000000000000000000006000830152602082019050919050565b6000612d3f60138361331f565b91507f5370616e20616c726561647920657869737473000000000000000000000000006000830152602082019050919050565b6000612d7f60458361331f565b91507f446966666572656e6365206265747765656e20737461727420616e6420656e6460008301527f20626c6f636b206d75737420626520696e206d756c7469706c6573206f66207360208301527f7072696e740000000000000000000000000000000000000000000000000000006040830152606082019050919050565b6000612e0b602a8361331f565b91507f456e6420626c6f636b206d7573742062652067726561746572207468616e207360008301527f7461727420626c6f636b000000000000000000000000000000000000000000006020830152604082019050919050565b6000612e71600e83613330565b91507f6865696d64616c6c2d31353030310000000000000000000000000000000000006000830152600e82019050919050565b6000612eb1600583613330565b91507f31353030310000000000000000000000000000000000000000000000000000006000830152600582019050919050565b606082016000820151612efa6000850182612f26565b506020820151612f0d6020850182612f26565b506040820151612f206040850182612af5565b50505050565b612f2f816133af565b82525050565b612f3e816133af565b82525050565b612f4d816133b9565b82525050565b6000612f5f8285612bde565b600182019150612f6f8284612c04565b6020820191508190509392505050565b6000612f8b8286612bde565b600182019150612f9b8285612c04565b602082019150612fab8284612c04565b602082019150819050949350505050565b6000612fc88284612c1b565b915081905092915050565b6000612fde82612c4c565b9150819050919050565b6000612ff382612e64565b9150819050919050565b600061300882612ea4565b9150819050919050565b60006020820190506130276000830184612b04565b92915050565b600060408201905081810360008301526130478185612b13565b9050818103602083015261305b8184612b71565b90509392505050565b60006020820190506130796000830184612bcf565b92915050565b60006020820190506130946000830184612bf5565b92915050565b60006080820190506130af6000830187612bf5565b6130bc6020830186612f44565b6130c96040830185612bf5565b6130d66060830184612bf5565b95945050505050565b600060208201905081810360008301526130f881612c8c565b9050919050565b6000602082019050818103600083015261311881612cf2565b9050919050565b6000602082019050818103600083015261313881612d32565b9050919050565b6000602082019050818103600083015261315881612d72565b9050919050565b6000602082019050818103600083015261317881612dfe565b9050919050565b60006060820190506131946000830184612ee4565b92915050565b60006020820190506131af6000830184612f35565b92915050565b60006060820190506131ca6000830186612f35565b6131d76020830185612f35565b6131e46040830184612b04565b949350505050565b60006060820190506132016000830186612f35565b61320e6020830185612f35565b61321b6040830184612f35565b949350505050565b60006020820190506132386000830184612f44565b92915050565b6000604051905081810181811067ffffffffffffffff8211171561326157600080fd5b8060405250919050565b600067ffffffffffffffff82111561328257600080fd5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b60006133468261338f565b9050919050565b60008115159050919050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b82818337600083830152505050565b60005b838110156133f35780820151818401526020810190506133d8565b83811115613402576000848401525b50505050565b6000819050919050565b6000819050919050565b6134258161333b565b811461343057600080fd5b50565b61343c81613385565b811461344757600080fd5b50565b613453816133af565b811461345e57600080fd5b5056fea365627a7a72315820705a7e2d8613a0b74be45107951c3d3839c8711982c0ee57a8b920f2f99e86036c6578706572696d656e74616cf564736f6c63430005100040" + "code": "0x608060405234801561001057600080fd5b50600436106101f05760003560e01c806360c8614d1161010f578063af26aa96116100a2578063d5b844eb11610071578063d5b844eb14610666578063dcf2793a14610684578063e3b7c924146106b6578063f59cf565146106d4576101f0565b8063af26aa96146105c7578063b71d7a69146105e7578063b7ab4db514610617578063c1b3c91914610636576101f0565b806370ba5707116100de57806370ba57071461052b57806398ab2b621461055b5780639d11b80714610579578063ae756451146105a9576101f0565b806360c8614d1461049c57806365b3a1e2146104bc57806366332354146104db578063687a9bd6146104f9576101f0565b80633434735f1161018757806344d6528f1161015657806344d6528f146103ee5780634dbc959f1461041e57806355614fcc1461043c578063582a8d081461046c576101f0565b80633434735f1461035257806335ddfeea1461037057806343ee8213146103a057806344c15cb1146103be576101f0565b806323f2a73f116101c357806323f2a73f146102a45780632bc06564146102d45780632de3a180146102f25780632eddf35214610322576101f0565b8063047a6c5b146101f55780630c35b1cb146102275780631270b5741461025857806323c2a2b414610288575b600080fd5b61020f600480360361020a919081019061290d565b610706565b60405161021e939291906131ec565b60405180910390f35b610241600480360361023c919081019061290d565b61075d565b60405161024f92919061302d565b60405180910390f35b610272600480360361026d9190810190612936565b610939565b60405161027f9190613064565b60405180910390f35b6102a2600480360361029d9190810190612a15565b610a91565b005b6102be60048036036102b99190810190612936565b6110f4565b6040516102cb9190613064565b60405180910390f35b6102dc61124b565b6040516102e9919061319a565b60405180910390f35b61030c6004803603610307919081019061286a565b611250565b604051610319919061307f565b60405180910390f35b61033c6004803603610337919081019061290d565b6112d1565b604051610349919061319a565b60405180910390f35b61035a611401565b6040516103679190613012565b60405180910390f35b61038a600480360361038591908101906128a6565b611419565b6040516103979190613064565b60405180910390f35b6103a86114e4565b6040516103b5919061307f565b60405180910390f35b6103d860048036036103d39190810190612972565b6114fb565b6040516103e5919061319a565b60405180910390f35b61040860048036036104039190810190612936565b6115e3565b604051610415919061317f565b60405180910390f35b61042661174b565b604051610433919061319a565b60405180910390f35b610456600480360361045191908101906127ef565b61175b565b6040516104639190613064565b60405180910390f35b61048660048036036104819190810190612818565b611775565b604051610493919061307f565b60405180910390f35b6104a46117f3565b6040516104b3939291906131ec565b60405180910390f35b6104c4611867565b6040516104d292919061302d565b60405180910390f35b6104e3611957565b6040516104f0919061319a565b60405180910390f35b610513600480360361050e91908101906129d9565b61195c565b604051610522939291906131b5565b60405180910390f35b610545600480360361054091908101906127ef565b6119c0565b6040516105529190613064565b60405180910390f35b6105636119da565b604051610570919061307f565b60405180910390f35b610593600480360361058e919081019061290d565b6119f1565b6040516105a0919061319a565b60405180910390f35b6105b1611b22565b6040516105be919061307f565b60405180910390f35b6105cf611b39565b6040516105de939291906131ec565b60405180910390f35b61060160048036036105fc919081019061290d565b611b9a565b60405161060e919061319a565b60405180910390f35b61061f611c9a565b60405161062d92919061302d565b60405180910390f35b610650600480360361064b919081019061290d565b611cae565b60405161065d919061319a565b60405180910390f35b61066e611ccf565b60405161067b9190613223565b60405180910390f35b61069e600480360361069991908101906129d9565b611cd4565b6040516106ad939291906131b5565b60405180910390f35b6106be611d38565b6040516106cb919061319a565b60405180910390f35b6106ee60048036036106e9919081019061290d565b611d4a565b6040516106fd939291906131ec565b60405180910390f35b60008060006002600085815260200190815260200160002060000154600260008681526020019081526020016000206001015460026000878152602001908152602001600020600201549250925092509193909250565b6060806007831161077957610770611867565b91509150610934565b600061078484611b9a565b9050606060016000838152602001908152602001600020805490506040519080825280602002602001820160405280156107cd5781602001602082028038833980820191505090505b509050606060016000848152602001908152602001600020805490506040519080825280602002602001820160405280156108175781602001602082028038833980820191505090505b50905060008090505b60016000858152602001908152602001600020805490508110156109295760016000858152602001908152602001600020818154811061085c57fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683828151811061089a57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506001600085815260200190815260200160002081815481106108f257fe5b90600052602060002090600302016001015482828151811061091057fe5b6020026020010181815250508080600101915050610820565b508181945094505050505b915091565b6000606060016000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015610a0c578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190610970565b50505050905060008090505b8151811015610a84578373ffffffffffffffffffffffffffffffffffffffff16828281518110610a4457fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff161415610a7757600192505050610a8b565b8080600101915050610a18565b5060009150505b92915050565b73fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610add57600080fd5b6000610ae761174b565b90506000811415610afb57610afa611d74565b5b610b0f60018261209590919063ffffffff16565b8814610b50576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b47906130ff565b60405180910390fd5b868611610b92576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b899061315f565b60405180910390fd5b6000600460018989030181610ba357fe5b0614610be4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bdb9061313f565b60405180910390fd5b8660026000838152602001908152602001600020600101541115610c3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c34906130df565b60405180910390fd5b6000600260008a81526020019081526020016000206000015414610c96576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c8d9061311f565b60405180910390fd5b604051806060016040528089815260200188815260200187815250600260008a8152602001908152602001600020600082015181600001556020820151816001015560408201518160020155905050600388908060018154018082558091505090600182039060005260206000200160009091929091909150555060008060008a815260200190815260200160002081610d3091906125e9565b506000600160008a815260200190815260200160002081610d5191906125e9565b506060610da9610da487878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506120b4565b6120e2565b905060008090505b8151811015610f1b576060610dd8838381518110610dcb57fe5b60200260200101516120e2565b90506000808c81526020019081526020016000208054809190600101610dfe91906125e9565b506040518060600160405280610e2783600081518110610e1a57fe5b60200260200101516121bf565b8152602001610e4983600181518110610e3c57fe5b60200260200101516121bf565b8152602001610e6b83600281518110610e5e57fe5b6020026020010151612230565b73ffffffffffffffffffffffffffffffffffffffff168152506000808d81526020019081526020016000208381548110610ea157fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050508080600101915050610db1565b506060610f73610f6e86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506120b4565b6120e2565b905060008090505b81518110156110e7576060610fa2838381518110610f9557fe5b60200260200101516120e2565b9050600160008d81526020019081526020016000208054809190600101610fc991906125e9565b506040518060600160405280610ff283600081518110610fe557fe5b60200260200101516121bf565b81526020016110148360018151811061100757fe5b60200260200101516121bf565b81526020016110368360028151811061102957fe5b6020026020010151612230565b73ffffffffffffffffffffffffffffffffffffffff16815250600160008e8152602001908152602001600020838154811061106d57fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050508080600101915050610f7b565b5050505050505050505050565b60006060600080858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156111c6578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250508152602001906001019061112a565b50505050905060008090505b815181101561123e578373ffffffffffffffffffffffffffffffffffffffff168282815181106111fe57fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff16141561123157600192505050611245565b80806001019150506111d2565b5060009150505b92915050565b600481565b60006002600160f81b848460405160200161126d93929190612f7f565b6040516020818303038152906040526040516112899190612fbc565b602060405180830381855afa1580156112a6573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506112c99190810190612841565b905092915050565b60006060600080848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156113a3578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611307565b505050509050600080905060008090505b82518110156113f6576113e78382815181106113cc57fe5b6020026020010151602001518361209590919063ffffffff16565b915080806001019150506113b4565b508092505050919050565b73fffffffffffffffffffffffffffffffffffffffe81565b600080600080859050600060218087518161143057fe5b0402905060008111156114495761144687611775565b91505b6000602190505b8181116114d35760006001820388015190508188015195508060006020811061147557fe5b1a60f81b9450600060f81b857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614156114ba576114b38685611250565b93506114c7565b6114c48487611250565b93505b50602181019050611450565b508782149450505050509392505050565b6040516114f090612fe8565b604051809103902081565b60008060009050600080905060008090505b84518167ffffffffffffffff1610156115d6576060611538868367ffffffffffffffff166041612253565b9050600061154f82896122df90919063ffffffff16565b905061155961261b565b6115638a836115e3565b905061156f8a836110f4565b80156115a657508473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16115b156115c8578194506115c581602001518761209590919063ffffffff16565b95505b50505060418101905061150d565b5081925050509392505050565b6115eb61261b565b6060600080858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156116bb578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250508152602001906001019061161f565b50505050905060008090505b8151811015611743578373ffffffffffffffffffffffffffffffffffffffff168282815181106116f357fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff1614156117365781818151811061172757fe5b60200260200101519250611743565b80806001019150506116c7565b505092915050565b600061175643611b9a565b905090565b600061176e61176861174b565b836110f4565b9050919050565b60006002600060f81b83604051602001611790929190612f53565b6040516020818303038152906040526040516117ac9190612fbc565b602060405180830381855afa1580156117c9573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506117ec9190810190612841565b9050919050565b600080600080611814600161180661174b565b61209590919063ffffffff16565b905060026000828152602001908152602001600020600001546002600083815260200190815260200160002060010154600260008481526020019081526020016000206002015493509350935050909192565b6060806060600160405190808252806020026020018201604052801561189c5781602001602082028038833980820191505090505b5090507371562b71999873db5b286df957af199ec94617f7816000815181106118c157fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250506060600160405190808252806020026020018201604052801561192d5781602001602082028038833980820191505090505b509050600a8160008151811061193f57fe5b60200260200101818152505081819350935050509091565b600781565b6001602052816000526040600020818154811061197557fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b60006119d36119cd61174b565b83610939565b9050919050565b6040516119e690612fd3565b604051809103902081565b6000606060016000848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015611ac4578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611a28565b505050509050600080905060008090505b8251811015611b1757611b08838281518110611aed57fe5b6020026020010151602001518361209590919063ffffffff16565b91508080600101915050611ad5565b508092505050919050565b604051611b2e90612ffd565b604051809103902081565b600080600080611b4761174b565b905060026000828152602001908152602001600020600001546002600083815260200190815260200160002060010154600260008481526020019081526020016000206002015493509350935050909192565b60008060038054905090505b6000811115611c5a57611bb7612652565b6002600060036001850381548110611bcb57fe5b906000526020600020015481526020019081526020016000206040518060600160405290816000820154815260200160018201548152602001600282015481525050905083816020015111158015611c2857506000816040015114155b8015611c38575080604001518411155b15611c4b57806000015192505050611c95565b50808060019003915050611ba6565b5060006003805490501115611c9057600360016003805490500381548110611c7e57fe5b90600052602060002001549050611c95565b600090505b919050565b606080611ca64361075d565b915091509091565b60038181548110611cbb57fe5b906000526020600020016000915090505481565b600281565b60006020528160005260406000208181548110611ced57fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b600060044381611d4457fe5b04905090565b60026020528060005260406000206000915090508060000154908060010154908060020154905083565b606080611d7f611867565b809250819350505060008090506040518060600160405280828152602001600081526020016007815250600260008381526020019081526020016000206000820151816000015560208201518160010155604082015181600201559050506003819080600181540180825580915050906001820390600052602060002001600090919290919091505550600080600083815260200190815260200160002081611e2891906125e9565b5060006001600083815260200190815260200160002081611e4991906125e9565b5060008090505b8351811015611f6b576000808381526020019081526020016000208054809190600101611e7d91906125e9565b506040518060600160405280828152602001848381518110611e9b57fe5b60200260200101518152602001858381518110611eb457fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff168152506000808481526020019081526020016000208281548110611ef257fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050508080600101915050611e50565b5060008090505b835181101561208f57600160008381526020019081526020016000208054809190600101611fa091906125e9565b506040518060600160405280828152602001848381518110611fbe57fe5b60200260200101518152602001858381518110611fd757fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681525060016000848152602001908152602001600020828154811061201657fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055509050508080600101915050611f72565b50505050565b6000808284019050838110156120aa57600080fd5b8091505092915050565b6120bc612673565b600060208301905060405180604001604052808451815260200182815250915050919050565b60606120ed826123e9565b6120f657600080fd5b600061210183612437565b905060608160405190808252806020026020018201604052801561213f57816020015b61212c61268d565b8152602001906001900390816121245790505b509050600061215185602001516124a8565b8560200151019050600080600090505b848110156121b25761217283612531565b915060405180604001604052808381526020018481525084828151811061219557fe5b602002602001018190525081830192508080600101915050612161565b5082945050505050919050565b60008082600001511180156121d957506021826000015111155b6121e257600080fd5b60006121f183602001516124a8565b9050600081846000015103905060008083866020015101905080519150602083101561222457826020036101000a820491505b81945050505050919050565b6000601582600001511461224357600080fd5b61224c826121bf565b9050919050565b60608183018451101561226557600080fd5b6060821560008114612282576040519150602082016040526122d3565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156122c057805183526020830192506020810190506122a3565b50868552601f19601f8301166040525050505b50809150509392505050565b60008060008060418551146122fa57600093505050506123e3565b602085015192506040850151915060ff6041860151169050601b8160ff16101561232557601b810190505b601b8160ff161415801561233d5750601c8160ff1614155b1561234e57600093505050506123e3565b600060018783868660405160008152602001604052604051612373949392919061309a565b6020604051602081039080840390855afa158015612395573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156123db57600080fd5b809450505050505b92915050565b600080826000015114156124005760009050612432565b60008083602001519050805160001a915060c060ff168260ff16101561242b57600092505050612432565b6001925050505b919050565b6000808260000151141561244e57600090506124a3565b6000809050600061246284602001516124a8565b84602001510190506000846000015185602001510190505b8082101561249c5761248b82612531565b82019150828060010193505061247a565b8293505050505b919050565b600080825160001a9050608060ff168110156124c857600091505061252c565b60b860ff168110806124ed575060c060ff1681101580156124ec575060f860ff1681105b5b156124fc57600191505061252c565b60c060ff1681101561251c5760018060b80360ff1682030191505061252c565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff1681101561255257600191506125df565b60b860ff1681101561256f576001608060ff1682030191506125de565b60c060ff1681101561259f5760b78103600185019450806020036101000a855104600182018101935050506125dd565b60f860ff168110156125bc57600160c060ff1682030191506125dc565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b8154818355818111156126165760030281600302836000526020600020918201910161261591906126a7565b5b505050565b60405180606001604052806000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b60405180606001604052806000815260200160008152602001600081525090565b604051806040016040528060008152602001600081525090565b604051806040016040528060008152602001600081525090565b6126fa91905b808211156126f65760008082016000905560018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055506003016126ad565b5090565b90565b60008135905061270c8161341c565b92915050565b60008135905061272181613433565b92915050565b60008151905061273681613433565b92915050565b60008083601f84011261274e57600080fd5b8235905067ffffffffffffffff81111561276757600080fd5b60208301915083600182028301111561277f57600080fd5b9250929050565b600082601f83011261279757600080fd5b81356127aa6127a58261326b565b61323e565b915080825260208301602083018583830111156127c657600080fd5b6127d18382846133c6565b50505092915050565b6000813590506127e98161344a565b92915050565b60006020828403121561280157600080fd5b600061280f848285016126fd565b91505092915050565b60006020828403121561282a57600080fd5b600061283884828501612712565b91505092915050565b60006020828403121561285357600080fd5b600061286184828501612727565b91505092915050565b6000806040838503121561287d57600080fd5b600061288b85828601612712565b925050602061289c85828601612712565b9150509250929050565b6000806000606084860312156128bb57600080fd5b60006128c986828701612712565b93505060206128da86828701612712565b925050604084013567ffffffffffffffff8111156128f757600080fd5b61290386828701612786565b9150509250925092565b60006020828403121561291f57600080fd5b600061292d848285016127da565b91505092915050565b6000806040838503121561294957600080fd5b6000612957858286016127da565b9250506020612968858286016126fd565b9150509250929050565b60008060006060848603121561298757600080fd5b6000612995868287016127da565b93505060206129a686828701612712565b925050604084013567ffffffffffffffff8111156129c357600080fd5b6129cf86828701612786565b9150509250925092565b600080604083850312156129ec57600080fd5b60006129fa858286016127da565b9250506020612a0b858286016127da565b9150509250929050565b600080600080600080600060a0888a031215612a3057600080fd5b6000612a3e8a828b016127da565b9750506020612a4f8a828b016127da565b9650506040612a608a828b016127da565b955050606088013567ffffffffffffffff811115612a7d57600080fd5b612a898a828b0161273c565b9450945050608088013567ffffffffffffffff811115612aa857600080fd5b612ab48a828b0161273c565b925092505092959891949750929550565b6000612ad18383612af5565b60208301905092915050565b6000612ae98383612f26565b60208301905092915050565b612afe8161333b565b82525050565b612b0d8161333b565b82525050565b6000612b1e826132b7565b612b2881856132f2565b9350612b3383613297565b8060005b83811015612b64578151612b4b8882612ac5565b9750612b56836132d8565b925050600181019050612b37565b5085935050505092915050565b6000612b7c826132c2565b612b868185613303565b9350612b91836132a7565b8060005b83811015612bc2578151612ba98882612add565b9750612bb4836132e5565b925050600181019050612b95565b5085935050505092915050565b612bd88161334d565b82525050565b612bef612bea82613359565b613408565b82525050565b612bfe81613385565b82525050565b612c15612c1082613385565b613412565b82525050565b6000612c26826132cd565b612c308185613314565b9350612c408185602086016133d5565b80840191505092915050565b6000612c59600483613330565b91507f766f7465000000000000000000000000000000000000000000000000000000006000830152600482019050919050565b6000612c99602d8361331f565b91507f537461727420626c6f636b206d7573742062652067726561746572207468616e60008301527f2063757272656e74207370616e000000000000000000000000000000000000006020830152604082019050919050565b6000612cff600f8361331f565b91507f496e76616c6964207370616e20696400000000000000000000000000000000006000830152602082019050919050565b6000612d3f60138361331f565b91507f5370616e20616c726561647920657869737473000000000000000000000000006000830152602082019050919050565b6000612d7f60458361331f565b91507f446966666572656e6365206265747765656e20737461727420616e6420656e6460008301527f20626c6f636b206d75737420626520696e206d756c7469706c6573206f66207360208301527f7072696e740000000000000000000000000000000000000000000000000000006040830152606082019050919050565b6000612e0b602a8361331f565b91507f456e6420626c6f636b206d7573742062652067726561746572207468616e207360008301527f7461727420626c6f636b000000000000000000000000000000000000000000006020830152604082019050919050565b6000612e71600e83613330565b91507f6865696d64616c6c2d31353030310000000000000000000000000000000000006000830152600e82019050919050565b6000612eb1600583613330565b91507f31353030310000000000000000000000000000000000000000000000000000006000830152600582019050919050565b606082016000820151612efa6000850182612f26565b506020820151612f0d6020850182612f26565b506040820151612f206040850182612af5565b50505050565b612f2f816133af565b82525050565b612f3e816133af565b82525050565b612f4d816133b9565b82525050565b6000612f5f8285612bde565b600182019150612f6f8284612c04565b6020820191508190509392505050565b6000612f8b8286612bde565b600182019150612f9b8285612c04565b602082019150612fab8284612c04565b602082019150819050949350505050565b6000612fc88284612c1b565b915081905092915050565b6000612fde82612c4c565b9150819050919050565b6000612ff382612e64565b9150819050919050565b600061300882612ea4565b9150819050919050565b60006020820190506130276000830184612b04565b92915050565b600060408201905081810360008301526130478185612b13565b9050818103602083015261305b8184612b71565b90509392505050565b60006020820190506130796000830184612bcf565b92915050565b60006020820190506130946000830184612bf5565b92915050565b60006080820190506130af6000830187612bf5565b6130bc6020830186612f44565b6130c96040830185612bf5565b6130d66060830184612bf5565b95945050505050565b600060208201905081810360008301526130f881612c8c565b9050919050565b6000602082019050818103600083015261311881612cf2565b9050919050565b6000602082019050818103600083015261313881612d32565b9050919050565b6000602082019050818103600083015261315881612d72565b9050919050565b6000602082019050818103600083015261317881612dfe565b9050919050565b60006060820190506131946000830184612ee4565b92915050565b60006020820190506131af6000830184612f35565b92915050565b60006060820190506131ca6000830186612f35565b6131d76020830185612f35565b6131e46040830184612b04565b949350505050565b60006060820190506132016000830186612f35565b61320e6020830185612f35565b61321b6040830184612f35565b949350505050565b60006020820190506132386000830184612f44565b92915050565b6000604051905081810181811067ffffffffffffffff8211171561326157600080fd5b8060405250919050565b600067ffffffffffffffff82111561328257600080fd5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b60006133468261338f565b9050919050565b60008115159050919050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b82818337600083830152505050565b60005b838110156133f35780820151818401526020810190506133d8565b83811115613402576000848401525b50505050565b6000819050919050565b6000819050919050565b6134258161333b565b811461343057600080fd5b50565b61343c81613385565b811461344757600080fd5b50565b613453816133af565b811461345e57600080fd5b5056fea365627a7a723158208af21d8e799fd1406e4b7808af903d8055606c3aa8d3ec80d8e21f0514e9bf676c6578706572696d656e74616cf564736f6c634300050c0040" }, "0000000000000000000000000000000000001001": { "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c8063017a91051461005157806319494a17146100975780633434735f1461011a5780634c7af28e14610164575b600080fd5b61007d6004803603602081101561006757600080fd5b8101908080359060200190929190505050610182565b604051808215151515815260200191505060405180910390f35b610118600480360360408110156100ad57600080fd5b8101908080359060200190929190803590602001906401000000008111156100d457600080fd5b8201836020820111156100e657600080fd5b8035906020019184600183028401116401000000008311171561010857600080fd5b90919293919293905050506101a2565b005b610122610598565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61016c6105b0565b6040518082815260200191505060405180910390f35b60016020528060005260406000206000915054906101000a900460ff1681565b73fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101ee57600080fd5b600054831015610249576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526027815260200180610a966027913960400191505060405180910390fd5b8260008190555060606102a76102a284848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506105b6565b6105e4565b905060006102c8826000815181106102bb57fe5b60200260200101516106c1565b905060006102e9836001815181106102dc57fe5b6020026020010151610732565b9050606061030a846002815181106102fd57fe5b6020026020010151610755565b9050600015156001600085815260200190815260200160002060009054906101000a900460ff161515146103a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f53746174652077617320616c72656164792070726f636573736564000000000081525060200191505060405180910390fd5b600180600085815260200190815260200160002060006101000a81548160ff0219169083151502179055506103da826107e1565b1561058f578173ffffffffffffffffffffffffffffffffffffffff1683826040516024018083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610441578082015181840152602081019050610426565b50505050905090810190601f16801561046e5780820380516001836020036101000a031916815260200191505b5093505050506040516020818303038152906040527f26c53bea000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b602083106105245780518252602082019150602081019050602083039250610501565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610586576040519150601f19603f3d011682016040523d82523d6000602084013e61058b565b606091505b5050505b50505050505050565b73fffffffffffffffffffffffffffffffffffffffe81565b60005481565b6105be610a61565b600060208301905060405180604001604052808451815260200182815250915050919050565b60606105ef826107fa565b6105f857600080fd5b600061060383610848565b905060608160405190808252806020026020018201604052801561064157816020015b61062e610a7b565b8152602001906001900390816106265790505b509050600061065385602001516108b9565b8560200151019050600080600090505b848110156106b45761067483610942565b915060405180604001604052808381526020018481525084828151811061069757fe5b602002602001018190525081830192508080600101915050610663565b5082945050505050919050565b60008082600001511180156106db57506021826000015111155b6106e457600080fd5b60006106f383602001516108b9565b9050600081846000015103905060008083866020015101905080519150602083101561072657826020036101000a820491505b81945050505050919050565b6000601582600001511461074557600080fd5b61074e826106c1565b9050919050565b6060600082600001511161076857600080fd5b600061077783602001516108b9565b905060008184600001510390506060816040519080825280601f01601f1916602001820160405280156107b95781602001600182028038833980820191505090505b50905060008160200190506107d58487602001510182856109fa565b81945050505050919050565b600080823b905060008163ffffffff1611915050919050565b600080826000015114156108115760009050610843565b60008083602001519050805160001a915060c060ff168260ff16101561083c57600092505050610843565b6001925050505b919050565b6000808260000151141561085f57600090506108b4565b6000809050600061087384602001516108b9565b84602001510190506000846000015185602001510190505b808210156108ad5761089c82610942565b82019150828060010193505061088b565b8293505050505b919050565b600080825160001a9050608060ff168110156108d957600091505061093d565b60b860ff168110806108fe575060c060ff1681101580156108fd575060f860ff1681105b5b1561090d57600191505061093d565b60c060ff1681101561092d5760018060b80360ff1682030191505061093d565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff1681101561096357600191506109f0565b60b860ff16811015610980576001608060ff1682030191506109ef565b60c060ff168110156109b05760b78103600185019450806020036101000a855104600182018101935050506109ee565b60f860ff168110156109cd57600160c060ff1682030191506109ed565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b6000811415610a0857610a5c565b5b602060ff168110610a385782518252602060ff1683019250602060ff1682019150602060ff1681039050610a09565b6000600182602060ff16036101000a03905080198451168184511681811785525050505b505050565b604051806040016040528060008152602001600081525090565b60405180604001604052806000815260200160008152509056fe417474656d7074696e6720746f2073796e63207374617465732066726f6d207468652070617374a265627a7a723158200e44a9fc38049f8bea49a2b5a69ed071eb2bc0248bee71fd0222d1318c23b9e664736f6c63430005100032" + "code": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806319494a17146100515780633434735f146100ec5780634c7af28e146101365780635407ca6714610154575b600080fd5b6100d26004803603604081101561006757600080fd5b81019080803590602001909291908035906020019064010000000081111561008e57600080fd5b8201836020820111156100a057600080fd5b803590602001918460018302840111640100000000831117156100c257600080fd5b9091929391929390505050610172565b604051808215151515815260200191505060405180910390f35b6100f461049c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61013e6104b4565b6040518082815260200191505060405180910390f35b61015c6104ba565b6040518082815260200191505060405180910390f35b600073fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101c057600080fd5b60005484101561021b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260278152602001806109a06027913960400191505060405180910390fd5b83600081905550606061027961027485858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104c0565b6104ee565b9050600061029a8260008151811061028d57fe5b60200260200101516105cb565b905080600180540114610315576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f537461746549647320617265206e6f742073657175656e7469616c000000000081525060200191505060405180910390fd5b60016000815480929190600101919050555060006103468360018151811061033957fe5b602002602001015161063c565b905060606103678460028151811061035a57fe5b602002602001015161065f565b9050610372826106eb565b15610491576000624c4b409050606084836040516024018083815260200180602001828103825283818151815260200191508051906020019080838360005b838110156103cc5780820151818401526020810190506103b1565b50505050905090810190601f1680156103f95780820380516001836020036101000a031916815260200191505b5093505050506040516020818303038152906040527f26c53bea000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050905060008082516020840160008887f1965050505b505050509392505050565b73fffffffffffffffffffffffffffffffffffffffe81565b60005481565b60015481565b6104c861096b565b600060208301905060405180604001604052808451815260200182815250915050919050565b60606104f982610704565b61050257600080fd5b600061050d83610752565b905060608160405190808252806020026020018201604052801561054b57816020015b610538610985565b8152602001906001900390816105305790505b509050600061055d85602001516107c3565b8560200151019050600080600090505b848110156105be5761057e8361084c565b91506040518060400160405280838152602001848152508482815181106105a157fe5b60200260200101819052508183019250808060010191505061056d565b5082945050505050919050565b60008082600001511180156105e557506021826000015111155b6105ee57600080fd5b60006105fd83602001516107c3565b9050600081846000015103905060008083866020015101905080519150602083101561063057826020036101000a820491505b81945050505050919050565b6000601582600001511461064f57600080fd5b610658826105cb565b9050919050565b6060600082600001511161067257600080fd5b600061068183602001516107c3565b905060008184600001510390506060816040519080825280601f01601f1916602001820160405280156106c35781602001600182028038833980820191505090505b50905060008160200190506106df848760200151018285610904565b81945050505050919050565b600080823b905060008163ffffffff1611915050919050565b6000808260000151141561071b576000905061074d565b60008083602001519050805160001a915060c060ff168260ff1610156107465760009250505061074d565b6001925050505b919050565b6000808260000151141561076957600090506107be565b6000809050600061077d84602001516107c3565b84602001510190506000846000015185602001510190505b808210156107b7576107a68261084c565b820191508280600101935050610795565b8293505050505b919050565b600080825160001a9050608060ff168110156107e3576000915050610847565b60b860ff16811080610808575060c060ff168110158015610807575060f860ff1681105b5b15610817576001915050610847565b60c060ff168110156108375760018060b80360ff16820301915050610847565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff1681101561086d57600191506108fa565b60b860ff1681101561088a576001608060ff1682030191506108f9565b60c060ff168110156108ba5760b78103600185019450806020036101000a855104600182018101935050506108f8565b60f860ff168110156108d757600160c060ff1682030191506108f7565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b600081141561091257610966565b5b602060ff1681106109425782518252602060ff1683019250602060ff1682019150602060ff1681039050610913565b6000600182602060ff16036101000a03905080198451168184511681811785525050505b505050565b604051806040016040528060008152602001600081525090565b60405180604001604052806000815260200160008152509056fe417474656d7074696e6720746f2073796e63207374617465732066726f6d207468652070617374a265627a7a72315820d74a9109f80ef82840d3b83791c2edb76ecd1948140aa0c31a0db7ce72393dac64736f6c634300050c0032" }, "0000000000000000000000000000000000001010": { "balance": "0x204fce28085b549b31600000", - "code": "0x60806040526004361061019c5760003560e01c806377d32e94116100ec578063acd06cb31161008a578063e306f77911610064578063e306f77914610a7b578063e614d0d614610aa6578063f2fde38b14610ad1578063fc0c546a14610b225761019c565b8063acd06cb31461097a578063b789543c146109cd578063cc79f97b14610a505761019c565b80639025e64c116100c65780639025e64c146107c957806395d89b4114610859578063a9059cbb146108e9578063abceeba21461094f5761019c565b806377d32e94146106315780638da5cb5b146107435780638f32d59b1461079a5761019c565b806347e7ef24116101595780637019d41a116101335780637019d41a1461053357806370a082311461058a578063715018a6146105ef578063771282f6146106065761019c565b806347e7ef2414610410578063485cc9551461046b57806360f96a8f146104dc5761019c565b806306fdde03146101a15780631499c5921461023157806318160ddd1461028257806319d27d9c146102ad5780632e1a7d4d146103b1578063313ce567146103df575b600080fd5b3480156101ad57600080fd5b506101b6610b79565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101f65780820151818401526020810190506101db565b50505050905090810190601f1680156102235780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561023d57600080fd5b506102806004803603602081101561025457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610bb6565b005b34801561028e57600080fd5b50610297610c24565b6040518082815260200191505060405180910390f35b3480156102b957600080fd5b5061036f600480360360a08110156102d057600080fd5b81019080803590602001906401000000008111156102ed57600080fd5b8201836020820111156102ff57600080fd5b8035906020019184600183028401116401000000008311171561032157600080fd5b9091929391929390803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610c3a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103dd600480360360208110156103c757600080fd5b8101908080359060200190929190505050610e06565b005b3480156103eb57600080fd5b506103f4610f58565b604051808260ff1660ff16815260200191505060405180910390f35b34801561041c57600080fd5b506104696004803603604081101561043357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610f61565b005b34801561047757600080fd5b506104da6004803603604081101561048e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061111d565b005b3480156104e857600080fd5b506104f16111ec565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561053f57600080fd5b50610548611212565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561059657600080fd5b506105d9600480360360208110156105ad57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611238565b6040518082815260200191505060405180910390f35b3480156105fb57600080fd5b50610604611259565b005b34801561061257600080fd5b5061061b611329565b6040518082815260200191505060405180910390f35b34801561063d57600080fd5b506107016004803603604081101561065457600080fd5b81019080803590602001909291908035906020019064010000000081111561067b57600080fd5b82018360208201111561068d57600080fd5b803590602001918460018302840111640100000000831117156106af57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061132f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561074f57600080fd5b506107586114b4565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156107a657600080fd5b506107af6114dd565b604051808215151515815260200191505060405180910390f35b3480156107d557600080fd5b506107de611534565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561081e578082015181840152602081019050610803565b50505050905090810190601f16801561084b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561086557600080fd5b5061086e61156d565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156108ae578082015181840152602081019050610893565b50505050905090810190601f1680156108db5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610935600480360360408110156108ff57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506115aa565b604051808215151515815260200191505060405180910390f35b34801561095b57600080fd5b506109646115d0565b6040518082815260200191505060405180910390f35b34801561098657600080fd5b506109b36004803603602081101561099d57600080fd5b810190808035906020019092919050505061165d565b604051808215151515815260200191505060405180910390f35b3480156109d957600080fd5b50610a3a600480360360808110156109f057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001909291908035906020019092919050505061167d565b6040518082815260200191505060405180910390f35b348015610a5c57600080fd5b50610a6561169d565b6040518082815260200191505060405180910390f35b348015610a8757600080fd5b50610a906116a3565b6040518082815260200191505060405180910390f35b348015610ab257600080fd5b50610abb6116a9565b6040518082815260200191505060405180910390f35b348015610add57600080fd5b50610b2060048036036020811015610af457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611736565b005b348015610b2e57600080fd5b50610b37611753565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60606040518060400160405280600b81526020017f4d6174696320546f6b656e000000000000000000000000000000000000000000815250905090565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f44697361626c656420666561747572650000000000000000000000000000000081525060200191505060405180910390fd5b6000601260ff16600a0a6402540be40002905090565b6000808511610c4857600080fd5b6000831480610c575750824311155b610cc9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5369676e6174757265206973206578706972656400000000000000000000000081525060200191505060405180910390fd5b6000610cd73387878761167d565b9050600015156005600083815260200190815260200160002060009054906101000a900460ff16151514610d73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f536967206465616374697661746564000000000000000000000000000000000081525060200191505060405180910390fd5b60016005600083815260200190815260200160002060006101000a81548160ff021916908315150217905550610ded8189898080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061132f565b9150610dfa828488611779565b50509695505050505050565b60003390506000610e1682611238565b9050610e2d83600654611b3690919063ffffffff16565b600681905550600083118015610e4257508234145b610eb4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f496e73756666696369656e7420616d6f756e740000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167febff2602b3f468259e1e99f613fed6691f3a6526effe6ef3e768ba7ae7a36c4f8584610f3087611238565b60405180848152602001838152602001828152602001935050505060405180910390a3505050565b60006012905090565b610f696114dd565b610f7257600080fd5b600081118015610faf5750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b611004576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611e626023913960400191505060405180910390fd5b600061100f83611238565b905060008390508073ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f1935050505015801561105c573d6000803e3d6000fd5b5061107283600654611b5690919063ffffffff16565b6006819055508373ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f4e2ca0515ed1aef1395f66b5303bb5d6f1bf9d61a353fa53f73f8ac9973fa9f685856110f489611238565b60405180848152602001838152602001828152602001935050505060405180910390a350505050565b600760009054906101000a900460ff1615611183576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611e3f6023913960400191505060405180910390fd5b6001600760006101000a81548160ff02191690831515021790555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506111e882611b75565b5050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b6112616114dd565b61126a57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60065481565b600080600080604185511461134a57600093505050506114ae565b602085015192506040850151915060ff6041860151169050601b8160ff16101561137557601b810190505b601b8160ff161415801561138d5750601c8160ff1614155b1561139e57600093505050506114ae565b60018682858560405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156113fb573d6000803e3d6000fd5b505050602060405103519350600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156114aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4572726f7220696e2065637265636f766572000000000000000000000000000081525060200191505060405180910390fd5b5050505b92915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b6040518060400160405280600281526020017f3a9900000000000000000000000000000000000000000000000000000000000081525081565b60606040518060400160405280600581526020017f4d41544943000000000000000000000000000000000000000000000000000000815250905090565b60008134146115bc57600090506115ca565b6115c7338484611779565b90505b92915050565b6040518060800160405280605b8152602001611ed7605b91396040516020018082805190602001908083835b6020831061161f57805182526020820191506020810190506020830392506115fc565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b60056020528060005260406000206000915054906101000a900460ff1681565b600061169361168e86868686611c6d565b611d43565b9050949350505050565b613a9981565b60015481565b604051806080016040528060528152602001611e85605291396040516020018082805190602001908083835b602083106116f857805182526020820191506020810190506020830392506116d5565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b61173e6114dd565b61174757600080fd5b61175081611b75565b50565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000803073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156117f957600080fd5b505afa15801561180d573d6000803e3d6000fd5b505050506040513d602081101561182357600080fd5b8101908080519060200190929190505050905060003073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156118b557600080fd5b505afa1580156118c9573d6000803e3d6000fd5b505050506040513d60208110156118df57600080fd5b810190808051906020019092919050505090506118fd868686611d8d565b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fe6497e3ee548a3372136af2fcb0696db31fc6cf20260707645068bd3fe97f3c48786863073ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611a0557600080fd5b505afa158015611a19573d6000803e3d6000fd5b505050506040513d6020811015611a2f57600080fd5b81019080805190602001909291905050503073ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611abd57600080fd5b505afa158015611ad1573d6000803e3d6000fd5b505050506040513d6020811015611ae757600080fd5b8101908080519060200190929190505050604051808681526020018581526020018481526020018381526020018281526020019550505050505060405180910390a46001925050509392505050565b600082821115611b4557600080fd5b600082840390508091505092915050565b600080828401905083811015611b6b57600080fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611baf57600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000806040518060800160405280605b8152602001611ed7605b91396040516020018082805190602001908083835b60208310611cbf5780518252602082019150602081019050602083039250611c9c565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120905060405181815273ffffffffffffffffffffffffffffffffffffffff8716602082015285604082015284606082015283608082015260a0812092505081915050949350505050565b60008060015490506040517f190100000000000000000000000000000000000000000000000000000000000081528160028201528360228201526042812092505081915050919050565b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611dd3573d6000803e3d6000fd5b508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a350505056fe54686520636f6e747261637420697320616c726561647920696e697469616c697a6564496e73756666696369656e7420616d6f756e74206f7220696e76616c69642075736572454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429546f6b656e5472616e736665724f726465722861646472657373207370656e6465722c75696e7432353620746f6b656e49644f72416d6f756e742c6279746573333220646174612c75696e743235362065787069726174696f6e29a265627a7a723158204d7efcb673053866d78e69673fa7583d77880fd0f002e7e8c82d7c2f0e571d6764736f6c63430005100032" + "code": "0x60806040526004361061019c5760003560e01c806377d32e94116100ec578063acd06cb31161008a578063e306f77911610064578063e306f77914610a7b578063e614d0d614610aa6578063f2fde38b14610ad1578063fc0c546a14610b225761019c565b8063acd06cb31461097a578063b789543c146109cd578063cc79f97b14610a505761019c565b80639025e64c116100c65780639025e64c146107c957806395d89b4114610859578063a9059cbb146108e9578063abceeba21461094f5761019c565b806377d32e94146106315780638da5cb5b146107435780638f32d59b1461079a5761019c565b806347e7ef24116101595780637019d41a116101335780637019d41a1461053357806370a082311461058a578063715018a6146105ef578063771282f6146106065761019c565b806347e7ef2414610410578063485cc9551461046b57806360f96a8f146104dc5761019c565b806306fdde03146101a15780631499c5921461023157806318160ddd1461028257806319d27d9c146102ad5780632e1a7d4d146103b1578063313ce567146103df575b600080fd5b3480156101ad57600080fd5b506101b6610b79565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101f65780820151818401526020810190506101db565b50505050905090810190601f1680156102235780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561023d57600080fd5b506102806004803603602081101561025457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610bb6565b005b34801561028e57600080fd5b50610297610c24565b6040518082815260200191505060405180910390f35b3480156102b957600080fd5b5061036f600480360360a08110156102d057600080fd5b81019080803590602001906401000000008111156102ed57600080fd5b8201836020820111156102ff57600080fd5b8035906020019184600183028401116401000000008311171561032157600080fd5b9091929391929390803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610c3a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103dd600480360360208110156103c757600080fd5b8101908080359060200190929190505050610e06565b005b3480156103eb57600080fd5b506103f4610f58565b604051808260ff1660ff16815260200191505060405180910390f35b34801561041c57600080fd5b506104696004803603604081101561043357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610f61565b005b34801561047757600080fd5b506104da6004803603604081101561048e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061111d565b005b3480156104e857600080fd5b506104f16111ec565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561053f57600080fd5b50610548611212565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561059657600080fd5b506105d9600480360360208110156105ad57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611238565b6040518082815260200191505060405180910390f35b3480156105fb57600080fd5b50610604611259565b005b34801561061257600080fd5b5061061b611329565b6040518082815260200191505060405180910390f35b34801561063d57600080fd5b506107016004803603604081101561065457600080fd5b81019080803590602001909291908035906020019064010000000081111561067b57600080fd5b82018360208201111561068d57600080fd5b803590602001918460018302840111640100000000831117156106af57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061132f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561074f57600080fd5b506107586114b4565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156107a657600080fd5b506107af6114dd565b604051808215151515815260200191505060405180910390f35b3480156107d557600080fd5b506107de611534565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561081e578082015181840152602081019050610803565b50505050905090810190601f16801561084b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561086557600080fd5b5061086e61156d565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156108ae578082015181840152602081019050610893565b50505050905090810190601f1680156108db5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610935600480360360408110156108ff57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506115aa565b604051808215151515815260200191505060405180910390f35b34801561095b57600080fd5b506109646115d0565b6040518082815260200191505060405180910390f35b34801561098657600080fd5b506109b36004803603602081101561099d57600080fd5b810190808035906020019092919050505061165d565b604051808215151515815260200191505060405180910390f35b3480156109d957600080fd5b50610a3a600480360360808110156109f057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001909291908035906020019092919050505061167d565b6040518082815260200191505060405180910390f35b348015610a5c57600080fd5b50610a6561169d565b6040518082815260200191505060405180910390f35b348015610a8757600080fd5b50610a906116a3565b6040518082815260200191505060405180910390f35b348015610ab257600080fd5b50610abb6116a9565b6040518082815260200191505060405180910390f35b348015610add57600080fd5b50610b2060048036036020811015610af457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611736565b005b348015610b2e57600080fd5b50610b37611753565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60606040518060400160405280600b81526020017f4d6174696320546f6b656e000000000000000000000000000000000000000000815250905090565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f44697361626c656420666561747572650000000000000000000000000000000081525060200191505060405180910390fd5b6000601260ff16600a0a6402540be40002905090565b6000808511610c4857600080fd5b6000831480610c575750824311155b610cc9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5369676e6174757265206973206578706972656400000000000000000000000081525060200191505060405180910390fd5b6000610cd73387878761167d565b9050600015156005600083815260200190815260200160002060009054906101000a900460ff16151514610d73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f536967206465616374697661746564000000000000000000000000000000000081525060200191505060405180910390fd5b60016005600083815260200190815260200160002060006101000a81548160ff021916908315150217905550610ded8189898080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061132f565b9150610dfa828488611779565b50509695505050505050565b60003390506000610e1682611238565b9050610e2d83600654611b3690919063ffffffff16565b600681905550600083118015610e4257508234145b610eb4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f496e73756666696369656e7420616d6f756e740000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167febff2602b3f468259e1e99f613fed6691f3a6526effe6ef3e768ba7ae7a36c4f8584610f3087611238565b60405180848152602001838152602001828152602001935050505060405180910390a3505050565b60006012905090565b610f696114dd565b610f7257600080fd5b600081118015610faf5750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b611004576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611e626023913960400191505060405180910390fd5b600061100f83611238565b905060008390508073ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f1935050505015801561105c573d6000803e3d6000fd5b5061107283600654611b5690919063ffffffff16565b6006819055508373ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f4e2ca0515ed1aef1395f66b5303bb5d6f1bf9d61a353fa53f73f8ac9973fa9f685856110f489611238565b60405180848152602001838152602001828152602001935050505060405180910390a350505050565b600760009054906101000a900460ff1615611183576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611e3f6023913960400191505060405180910390fd5b6001600760006101000a81548160ff02191690831515021790555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506111e882611b75565b5050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b6112616114dd565b61126a57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60065481565b600080600080604185511461134a57600093505050506114ae565b602085015192506040850151915060ff6041860151169050601b8160ff16101561137557601b810190505b601b8160ff161415801561138d5750601c8160ff1614155b1561139e57600093505050506114ae565b60018682858560405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156113fb573d6000803e3d6000fd5b505050602060405103519350600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156114aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4572726f7220696e2065637265636f766572000000000000000000000000000081525060200191505060405180910390fd5b5050505b92915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b6040518060400160405280600281526020017f3a9900000000000000000000000000000000000000000000000000000000000081525081565b60606040518060400160405280600581526020017f4d41544943000000000000000000000000000000000000000000000000000000815250905090565b60008134146115bc57600090506115ca565b6115c7338484611779565b90505b92915050565b6040518060800160405280605b8152602001611ed7605b91396040516020018082805190602001908083835b6020831061161f57805182526020820191506020810190506020830392506115fc565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b60056020528060005260406000206000915054906101000a900460ff1681565b600061169361168e86868686611c6d565b611d43565b9050949350505050565b613a9981565b60015481565b604051806080016040528060528152602001611e85605291396040516020018082805190602001908083835b602083106116f857805182526020820191506020810190506020830392506116d5565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b61173e6114dd565b61174757600080fd5b61175081611b75565b50565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000803073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156117f957600080fd5b505afa15801561180d573d6000803e3d6000fd5b505050506040513d602081101561182357600080fd5b8101908080519060200190929190505050905060003073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156118b557600080fd5b505afa1580156118c9573d6000803e3d6000fd5b505050506040513d60208110156118df57600080fd5b810190808051906020019092919050505090506118fd868686611d8d565b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fe6497e3ee548a3372136af2fcb0696db31fc6cf20260707645068bd3fe97f3c48786863073ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611a0557600080fd5b505afa158015611a19573d6000803e3d6000fd5b505050506040513d6020811015611a2f57600080fd5b81019080805190602001909291905050503073ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611abd57600080fd5b505afa158015611ad1573d6000803e3d6000fd5b505050506040513d6020811015611ae757600080fd5b8101908080519060200190929190505050604051808681526020018581526020018481526020018381526020018281526020019550505050505060405180910390a46001925050509392505050565b600082821115611b4557600080fd5b600082840390508091505092915050565b600080828401905083811015611b6b57600080fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611baf57600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000806040518060800160405280605b8152602001611ed7605b91396040516020018082805190602001908083835b60208310611cbf5780518252602082019150602081019050602083039250611c9c565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120905060405181815273ffffffffffffffffffffffffffffffffffffffff8716602082015285604082015284606082015283608082015260a0812092505081915050949350505050565b60008060015490506040517f190100000000000000000000000000000000000000000000000000000000000081528160028201528360228201526042812092505081915050919050565b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611dd3573d6000803e3d6000fd5b508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a350505056fe54686520636f6e747261637420697320616c726561647920696e697469616c697a6564496e73756666696369656e7420616d6f756e74206f7220696e76616c69642075736572454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320766572696679696e67436f6e747261637429546f6b656e5472616e736665724f726465722861646472657373207370656e6465722c75696e7432353620746f6b656e49644f72416d6f756e742c6279746573333220646174612c75696e743235362065787069726174696f6e29a265627a7a72315820539379fc818a23e69edb3d3a2323efa049847b7691be5bd708c0770ce4be296964736f6c634300050c0032" }, "71562b71999873DB5b286dF957af199Ec94617F7": { "balance": "0x3635c9adc5dea00000" diff --git a/consensus/bor/genesis_contracts_client.go b/consensus/bor/genesis_contracts_client.go index fe995dfbf7..cc65e9b1cb 100644 --- a/consensus/bor/genesis_contracts_client.go +++ b/consensus/bor/genesis_contracts_client.go @@ -107,7 +107,7 @@ func (gc *GenesisContractsClient) LastStateId(snapshotNumber uint64) (*big.Int, method := "lastStateId" data, err := gc.stateReceiverABI.Pack(method) if err != nil { - log.Error("Unable to pack tx for getLastSyncTime", "error", err) + log.Error("Unable to pack tx for LastStateId", "error", err) return nil, err } From 2526aa8530ca53decf9e0fd9ac85a9bab0502ee1 Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Wed, 20 May 2020 10:08:30 +0530 Subject: [PATCH 42/46] wip --- consensus/bor/bor.go | 22 ++++++--- consensus/bor/bor_test/bor_test.go | 73 +++++++++++++++++++++++++++++ consensus/bor/bor_test/genesis.json | 2 +- consensus/bor/errors.go | 2 +- 4 files changed, 91 insertions(+), 8 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 37ae73128f..4b1a7ad05c 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -221,7 +221,7 @@ type Bor struct { lock sync.RWMutex // Protects the signer fields ethAPI *ethapi.PublicBlockChainAPI - genesisContractsClient *GenesisContractsClient + GenesisContractsClient *GenesisContractsClient validatorSetABI abi.ABI stateReceiverABI abi.ABI HeimdallClient IHeimdallClient @@ -263,7 +263,7 @@ func New( signatures: signatures, validatorSetABI: vABI, stateReceiverABI: sABI, - genesisContractsClient: genesisContractsClient, + GenesisContractsClient: genesisContractsClient, HeimdallClient: heimdallClient, } @@ -1076,11 +1076,11 @@ func (c *Bor) CommitStates( chain chainContext, ) error { number := header.Number.Uint64() - lastSync, err := c.genesisContractsClient.LastStateSyncTime(number - 1) + lastSync, err := c.GenesisContractsClient.LastStateSyncTime(number - 1) if err != nil { return err } - _lastStateID, err := c.genesisContractsClient.LastStateId(number - 1) + _lastStateID, err := c.GenesisContractsClient.LastStateId(number - 1) if err != nil { return err } @@ -1088,6 +1088,7 @@ func (c *Bor) CommitStates( from := lastSync to := time.Unix(int64(chain.Chain.GetHeaderByNumber(number-c.config.Sprint).Time), 0) lastStateID := _lastStateID.Uint64() + fmt.Println("to Uint64", lastStateID) if !from.Before(to) { return nil } @@ -1123,12 +1124,19 @@ func (c *Bor) CommitStates( return eventRecords[i].ID < eventRecords[j].ID }) + for _, e := range eventRecords { + fmt.Println("here", e.ID) + } + chainID := c.chainConfig.ChainID.String() for _, eventRecord := range eventRecords { + fmt.Println(eventRecord.ID, lastStateID) if eventRecord.ID <= lastStateID { + fmt.Println("continuiing", lastStateID) continue } if err := validateEventRecord(eventRecord, number, from, to, lastStateID, chainID); err != nil { + fmt.Println("breaking", err.Error()) log.Error(err.Error()) break } @@ -1143,11 +1151,13 @@ func (c *Bor) CommitStates( c.stateDataFeed.Send(core.NewStateChangeEvent{StateData: &stateData}) }() - if err := c.genesisContractsClient.CommitState(eventRecord, state, header, chain); err != nil { + if err := c.GenesisContractsClient.CommitState(eventRecord, state, header, chain); err != nil { + fmt.Println("erred", err) return err } + lastStateID++ } - lastStateID++ + fmt.Println("lastStateID is", lastStateID) return nil } diff --git a/consensus/bor/bor_test/bor_test.go b/consensus/bor/bor_test/bor_test.go index 31db0d17d0..dd282c9e5f 100644 --- a/consensus/bor/bor_test/bor_test.go +++ b/consensus/bor/bor_test/bor_test.go @@ -115,6 +115,72 @@ func TestFetchStateSyncEvents(t *testing.T) { assert.True(t, h.AssertCalled(t, "FetchWithRetry", clerkPath, query2Params)) } +func TestFetchStateSyncEvents_2(t *testing.T) { + init := buildEthereumInstance(t, rawdb.NewMemoryDatabase()) + chain := init.ethereum.BlockChain() + engine := init.ethereum.Engine() + _bor := engine.(*bor.Bor) + + // A. Insert blocks for 0th sprint + db := init.ethereum.ChainDb() + block := init.genesis.ToBlock(db) + // Insert sprintSize # of blocks so that span is fetched at the start of a new sprint + for i := uint64(1); i < sprintSize; i++ { + block = buildNextBlock(t, _bor, chain, block, nil, init.genesis.Config.Bor) + insertNewBlock(t, chain, block) + } + + // B. Before inserting 1st block of the next sprint, mock heimdall deps + // B.1 Mock /bor/span/1 + res, _ := loadSpanFromFile(t) + h := &mocks.IHeimdallClient{} + h.On("FetchWithRetry", spanPath, "").Return(res, nil) + + // B.2 Mock State Sync events + // read heimdall api response from file + res = stateSyncEventsPayload(t) + var _eventRecords []*bor.EventRecordWithTime + if err := json.Unmarshal(res.Result, &_eventRecords); err != nil { + t.Fatalf("%s", err) + } + sample := _eventRecords[0] + + // First query will be from [0, (block-sprint).Time] + // Insert 4 events are in this time range + eventRecords := []*bor.EventRecordWithTime{ + buildStateEvent(sample, 2, 3), // id = 2, time = 3 + buildStateEvent(sample, 3, 2), // id = 3, time = 2 + buildStateEvent(sample, 1, 1), // id = 1, time = 1 + // event with id 4 is missing + buildStateEvent(sample, 5, 4), // id = 5, time = 4 + } + _res, _ := json.Marshal(eventRecords) + response := bor.ResponseWithHeight{Height: "0"} + if err := json.Unmarshal(_res, &response.Result); err != nil { + t.Fatalf("%s", err) + } + + from := 0 + to := int64(chain.GetHeaderByNumber(0).Time) + page := 1 + queryParams := fmt.Sprintf(clerkQueryParams, from, to, page) + h.On("FetchWithRetry", clerkPath, queryParams).Return(&response, nil) + + page = 2 + query2Params := fmt.Sprintf(clerkQueryParams, from, to, page) + h.On("FetchWithRetry", clerkPath, query2Params).Return(&bor.ResponseWithHeight{}, nil) + _bor.SetHeimdallClient(h) + + block = buildNextBlock(t, _bor, chain, block, nil, init.genesis.Config.Bor) + insertNewBlock(t, chain, block) + + assert.True(t, h.AssertCalled(t, "FetchWithRetry", spanPath, "")) + assert.True(t, h.AssertCalled(t, "FetchWithRetry", clerkPath, queryParams)) + lastStateID, _ := _bor.GenesisContractsClient.LastStateId(sprintSize) + assert.Equal(t, uint64(3), lastStateID.Uint64()) + fmt.Println("lastStateId after", lastStateID) +} + func TestOutOfTurnSigning(t *testing.T) { init := buildEthereumInstance(t, rawdb.NewMemoryDatabase()) chain := init.ethereum.BlockChain() @@ -210,3 +276,10 @@ func generateFakeStateSyncEvents(sample *bor.EventRecordWithTime, count int) []* } return events } + +func buildStateEvent(sample *bor.EventRecordWithTime, id uint64, timeStamp int64) *bor.EventRecordWithTime { + event := *sample + event.ID = id + event.Time = time.Unix(timeStamp, 0) + return &event +} diff --git a/consensus/bor/bor_test/genesis.json b/consensus/bor/bor_test/genesis.json index a77b7b79ed..93f3cdbd3d 100644 --- a/consensus/bor/bor_test/genesis.json +++ b/consensus/bor/bor_test/genesis.json @@ -31,7 +31,7 @@ }, "0000000000000000000000000000000000001001": { "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806319494a17146100515780633434735f146100ec5780634c7af28e146101365780635407ca6714610154575b600080fd5b6100d26004803603604081101561006757600080fd5b81019080803590602001909291908035906020019064010000000081111561008e57600080fd5b8201836020820111156100a057600080fd5b803590602001918460018302840111640100000000831117156100c257600080fd5b9091929391929390505050610172565b604051808215151515815260200191505060405180910390f35b6100f461049c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61013e6104b4565b6040518082815260200191505060405180910390f35b61015c6104ba565b6040518082815260200191505060405180910390f35b600073fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101c057600080fd5b60005484101561021b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260278152602001806109a06027913960400191505060405180910390fd5b83600081905550606061027961027485858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506104c0565b6104ee565b9050600061029a8260008151811061028d57fe5b60200260200101516105cb565b905080600180540114610315576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f537461746549647320617265206e6f742073657175656e7469616c000000000081525060200191505060405180910390fd5b60016000815480929190600101919050555060006103468360018151811061033957fe5b602002602001015161063c565b905060606103678460028151811061035a57fe5b602002602001015161065f565b9050610372826106eb565b15610491576000624c4b409050606084836040516024018083815260200180602001828103825283818151815260200191508051906020019080838360005b838110156103cc5780820151818401526020810190506103b1565b50505050905090810190601f1680156103f95780820380516001836020036101000a031916815260200191505b5093505050506040516020818303038152906040527f26c53bea000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050905060008082516020840160008887f1965050505b505050509392505050565b73fffffffffffffffffffffffffffffffffffffffe81565b60005481565b60015481565b6104c861096b565b600060208301905060405180604001604052808451815260200182815250915050919050565b60606104f982610704565b61050257600080fd5b600061050d83610752565b905060608160405190808252806020026020018201604052801561054b57816020015b610538610985565b8152602001906001900390816105305790505b509050600061055d85602001516107c3565b8560200151019050600080600090505b848110156105be5761057e8361084c565b91506040518060400160405280838152602001848152508482815181106105a157fe5b60200260200101819052508183019250808060010191505061056d565b5082945050505050919050565b60008082600001511180156105e557506021826000015111155b6105ee57600080fd5b60006105fd83602001516107c3565b9050600081846000015103905060008083866020015101905080519150602083101561063057826020036101000a820491505b81945050505050919050565b6000601582600001511461064f57600080fd5b610658826105cb565b9050919050565b6060600082600001511161067257600080fd5b600061068183602001516107c3565b905060008184600001510390506060816040519080825280601f01601f1916602001820160405280156106c35781602001600182028038833980820191505090505b50905060008160200190506106df848760200151018285610904565b81945050505050919050565b600080823b905060008163ffffffff1611915050919050565b6000808260000151141561071b576000905061074d565b60008083602001519050805160001a915060c060ff168260ff1610156107465760009250505061074d565b6001925050505b919050565b6000808260000151141561076957600090506107be565b6000809050600061077d84602001516107c3565b84602001510190506000846000015185602001510190505b808210156107b7576107a68261084c565b820191508280600101935050610795565b8293505050505b919050565b600080825160001a9050608060ff168110156107e3576000915050610847565b60b860ff16811080610808575060c060ff168110158015610807575060f860ff1681105b5b15610817576001915050610847565b60c060ff168110156108375760018060b80360ff16820301915050610847565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff1681101561086d57600191506108fa565b60b860ff1681101561088a576001608060ff1682030191506108f9565b60c060ff168110156108ba5760b78103600185019450806020036101000a855104600182018101935050506108f8565b60f860ff168110156108d757600160c060ff1682030191506108f7565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b600081141561091257610966565b5b602060ff1681106109425782518252602060ff1683019250602060ff1682019150602060ff1681039050610913565b6000600182602060ff16036101000a03905080198451168184511681811785525050505b505050565b604051806040016040528060008152602001600081525090565b60405180604001604052806000815260200160008152509056fe417474656d7074696e6720746f2073796e63207374617465732066726f6d207468652070617374a265627a7a72315820d74a9109f80ef82840d3b83791c2edb76ecd1948140aa0c31a0db7ce72393dac64736f6c634300050c0032" + "code": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806319494a17146100515780633434735f146100ec5780634c7af28e146101365780635407ca6714610154575b600080fd5b6100d26004803603604081101561006757600080fd5b81019080803590602001909291908035906020019064010000000081111561008e57600080fd5b8201836020820111156100a057600080fd5b803590602001918460018302840111640100000000831117156100c257600080fd5b9091929391929390505050610172565b604051808215151515815260200191505060405180910390f35b6100f4610441565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61013e610459565b6040518082815260200191505060405180910390f35b61015c61045f565b6040518082815260200191505060405180910390f35b600073fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101c057600080fd5b83600081905550606061021e61021985858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610465565b610493565b9050600061023f8260008151811061023257fe5b6020026020010151610570565b9050806001805401146102ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f537461746549647320617265206e6f742073657175656e7469616c000000000081525060200191505060405180910390fd5b60016000815480929190600101919050555060006102eb836001815181106102de57fe5b60200260200101516105e1565b9050606061030c846002815181106102ff57fe5b6020026020010151610604565b905061031782610690565b15610436576000624c4b409050606084836040516024018083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610371578082015181840152602081019050610356565b50505050905090810190601f16801561039e5780820380516001836020036101000a031916815260200191505b5093505050506040516020818303038152906040527f26c53bea000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050905060008082516020840160008887f1965050505b505050509392505050565b73fffffffffffffffffffffffffffffffffffffffe81565b60005481565b60015481565b61046d610910565b600060208301905060405180604001604052808451815260200182815250915050919050565b606061049e826106a9565b6104a757600080fd5b60006104b2836106f7565b90506060816040519080825280602002602001820160405280156104f057816020015b6104dd61092a565b8152602001906001900390816104d55790505b50905060006105028560200151610768565b8560200151019050600080600090505b8481101561056357610523836107f1565b915060405180604001604052808381526020018481525084828151811061054657fe5b602002602001018190525081830192508080600101915050610512565b5082945050505050919050565b600080826000015111801561058a57506021826000015111155b61059357600080fd5b60006105a28360200151610768565b905060008184600001510390506000808386602001510190508051915060208310156105d557826020036101000a820491505b81945050505050919050565b600060158260000151146105f457600080fd5b6105fd82610570565b9050919050565b6060600082600001511161061757600080fd5b60006106268360200151610768565b905060008184600001510390506060816040519080825280601f01601f1916602001820160405280156106685781602001600182028038833980820191505090505b50905060008160200190506106848487602001510182856108a9565b81945050505050919050565b600080823b905060008163ffffffff1611915050919050565b600080826000015114156106c057600090506106f2565b60008083602001519050805160001a915060c060ff168260ff1610156106eb576000925050506106f2565b6001925050505b919050565b6000808260000151141561070e5760009050610763565b600080905060006107228460200151610768565b84602001510190506000846000015185602001510190505b8082101561075c5761074b826107f1565b82019150828060010193505061073a565b8293505050505b919050565b600080825160001a9050608060ff168110156107885760009150506107ec565b60b860ff168110806107ad575060c060ff1681101580156107ac575060f860ff1681105b5b156107bc5760019150506107ec565b60c060ff168110156107dc5760018060b80360ff168203019150506107ec565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff16811015610812576001915061089f565b60b860ff1681101561082f576001608060ff16820301915061089e565b60c060ff1681101561085f5760b78103600185019450806020036101000a8551046001820181019350505061089d565b60f860ff1681101561087c57600160c060ff16820301915061089c565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b60008114156108b75761090b565b5b602060ff1681106108e75782518252602060ff1683019250602060ff1682019150602060ff16810390506108b8565b6000600182602060ff16036101000a03905080198451168184511681811785525050505b505050565b604051806040016040528060008152602001600081525090565b60405180604001604052806000815260200160008152509056fea265627a7a72315820517dba64036af56cf58779d5f7ff3abb8279cf161ce9a6ad2c3f7cb1a1f1090764736f6c634300050c0032" }, "0000000000000000000000000000000000001010": { "balance": "0x204fce28085b549b31600000", diff --git a/consensus/bor/errors.go b/consensus/bor/errors.go index 778a2672b0..1a72d42f29 100644 --- a/consensus/bor/errors.go +++ b/consensus/bor/errors.go @@ -135,7 +135,7 @@ type InvalidStateReceivedError struct { func (e *InvalidStateReceivedError) Error() string { return fmt.Sprintf( - "Received invalid event %s at block %d. Requested events from %s to %s. lastStateID was %d.\n", + "Received invalid event %s at block %d. Requested events from %s to %s. lastStateID was %d.", e.Event, e.Number, e.From.Format(time.RFC3339), From 2675dc59e97189c837f0741493c8ad799da08b0e Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Wed, 20 May 2020 13:43:40 +0530 Subject: [PATCH 43/46] fetch state events with from_id/to_time --- consensus/bor/bor.go | 83 ++---------- consensus/bor/bor_test/bor_test.go | 153 ++++++++++------------ consensus/bor/bor_test/genesis.json | 2 +- consensus/bor/errors.go | 4 +- consensus/bor/genesis_contracts_client.go | 31 +---- consensus/bor/rest.go | 36 +++++ mocks/IHeimdallClient.go | 23 ++++ 7 files changed, 141 insertions(+), 191 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 4b1a7ad05c..790fe86cf5 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -62,7 +62,6 @@ var ( validatorHeaderBytesLength = common.AddressLength + 20 // address + power systemAddress = common.HexToAddress("0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE") - stateFetchLimit = 50 ) // Various error messages to mark blocks invalid. These should be private to @@ -1076,67 +1075,29 @@ func (c *Bor) CommitStates( chain chainContext, ) error { number := header.Number.Uint64() - lastSync, err := c.GenesisContractsClient.LastStateSyncTime(number - 1) - if err != nil { - return err - } + // lastSync, err := c.GenesisContractsClient.LastStateSyncTime(number - 1) + // if err != nil { + // return err + // } _lastStateID, err := c.GenesisContractsClient.LastStateId(number - 1) if err != nil { return err } - from := lastSync to := time.Unix(int64(chain.Chain.GetHeaderByNumber(number-c.config.Sprint).Time), 0) lastStateID := _lastStateID.Uint64() - fmt.Println("to Uint64", lastStateID) - if !from.Before(to) { - return nil - } log.Info( "Fetching state updates from Heimdall", - "from", from.Format(time.RFC3339), + "fromID", lastStateID+1, "to", to.Format(time.RFC3339)) - - page := 1 - eventRecords := make([]*EventRecordWithTime, 0) - for { - queryParams := fmt.Sprintf("from-time=%d&to-time=%d&page=%d&limit=%d", from.Unix(), to.Unix(), page, stateFetchLimit) - log.Info("Fetching state sync events", "queryParams", queryParams) - response, err := c.HeimdallClient.FetchWithRetry("clerk/event-record/list", queryParams) - if err != nil { - return err - } - var _eventRecords []*EventRecordWithTime - if response.Result == nil { // status 204 - break - } - if err := json.Unmarshal(response.Result, &_eventRecords); err != nil { - return err - } - eventRecords = append(eventRecords, _eventRecords...) - if len(_eventRecords) < stateFetchLimit { - break - } - page++ - } - - sort.SliceStable(eventRecords, func(i, j int) bool { - return eventRecords[i].ID < eventRecords[j].ID - }) - - for _, e := range eventRecords { - fmt.Println("here", e.ID) - } + eventRecords, err := c.HeimdallClient.FetchStateSyncEvents(lastStateID+1, to.Unix()) chainID := c.chainConfig.ChainID.String() for _, eventRecord := range eventRecords { - fmt.Println(eventRecord.ID, lastStateID) if eventRecord.ID <= lastStateID { - fmt.Println("continuiing", lastStateID) continue } - if err := validateEventRecord(eventRecord, number, from, to, lastStateID, chainID); err != nil { - fmt.Println("breaking", err.Error()) + if err := validateEventRecord(eventRecord, number, to, lastStateID, chainID); err != nil { log.Error(err.Error()) break } @@ -1152,19 +1113,17 @@ func (c *Bor) CommitStates( }() if err := c.GenesisContractsClient.CommitState(eventRecord, state, header, chain); err != nil { - fmt.Println("erred", err) return err } lastStateID++ } - fmt.Println("lastStateID is", lastStateID) return nil } -func validateEventRecord(eventRecord *EventRecordWithTime, number uint64, from, to time.Time, lastStateID uint64, chainID string) error { +func validateEventRecord(eventRecord *EventRecordWithTime, number uint64, to time.Time, lastStateID uint64, chainID string) error { // event id should be sequential and event.Time should lie in the range [from, to) - if lastStateID+1 != eventRecord.ID || eventRecord.ChainID != chainID || eventRecord.Time.Before(from) || !eventRecord.Time.Before(to) { - return &InvalidStateReceivedError{number, lastStateID, &from, &to, eventRecord} + if lastStateID+1 != eventRecord.ID || eventRecord.ChainID != chainID || !eventRecord.Time.Before(to) { + return &InvalidStateReceivedError{number, lastStateID, &to, eventRecord} } return nil } @@ -1178,28 +1137,6 @@ func (c *Bor) SetHeimdallClient(h IHeimdallClient) { c.HeimdallClient = h } -func isProposeSpanAction(tx *types.Transaction, validatorContract string) bool { - // keccak256('proposeSpan()').slice(0, 4) - proposeSpanSig, _ := hex.DecodeString("4b0e4d17") - if tx.Data() == nil || len(tx.Data()) < 4 { - return false - } - - return bytes.Compare(proposeSpanSig, tx.Data()[:4]) == 0 && - tx.To().String() == validatorContract -} - -func isProposeStateAction(tx *types.Transaction, stateReceiverContract string) bool { - // keccak256('proposeState(uint256)').slice(0, 4) - proposeStateSig, _ := hex.DecodeString("ede01f17") - if tx.Data() == nil || len(tx.Data()) < 4 { - return false - } - - return bytes.Compare(proposeStateSig, tx.Data()[:4]) == 0 && - tx.To().String() == stateReceiverContract -} - // // Private methods // diff --git a/consensus/bor/bor_test/bor_test.go b/consensus/bor/bor_test/bor_test.go index dd282c9e5f..2994143d12 100644 --- a/consensus/bor/bor_test/bor_test.go +++ b/consensus/bor/bor_test/bor_test.go @@ -3,20 +3,17 @@ package bortest import ( "encoding/hex" "encoding/json" - "fmt" "math/big" "testing" "time" - "github.com/maticnetwork/bor/consensus/bor" - "github.com/maticnetwork/bor/core/rawdb" - - "github.com/maticnetwork/bor/crypto" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" + "github.com/maticnetwork/bor/consensus/bor" + "github.com/maticnetwork/bor/core/rawdb" "github.com/maticnetwork/bor/core/types" - + "github.com/maticnetwork/bor/crypto" "github.com/maticnetwork/bor/mocks" ) @@ -36,7 +33,7 @@ func TestInsertingSpanSizeBlocks(t *testing.T) { db := init.ethereum.ChainDb() block := init.genesis.ToBlock(db) - to := int64(block.Header().Time) + // to := int64(block.Header().Time) // Insert sprintSize # of blocks so that span is fetched at the start of a new sprint for i := uint64(1); i <= spanSize; i++ { @@ -45,7 +42,6 @@ func TestInsertingSpanSizeBlocks(t *testing.T) { } assert.True(t, h.AssertCalled(t, "FetchWithRetry", spanPath, "")) - assert.True(t, h.AssertCalled(t, "FetchWithRetry", clerkPath, fmt.Sprintf(clerkQueryParams, 0, to, 1))) validators, err := _bor.GetCurrentValidators(sprintSize, spanSize) // check validator set at the first block of new span if err != nil { t.Fatalf("%s", err) @@ -80,39 +76,22 @@ func TestFetchStateSyncEvents(t *testing.T) { h.On("FetchWithRetry", spanPath, "").Return(res, nil) // B.2 Mock State Sync events - // read heimdall api response from file - res = stateSyncEventsPayload(t) - var _eventRecords []*bor.EventRecordWithTime - if err := json.Unmarshal(res.Result, &_eventRecords); err != nil { - t.Fatalf("%s", err) - } - - // use that as a sample to generate bor.stateFetchLimit events - eventRecords := generateFakeStateSyncEvents(_eventRecords[0], 50) - _res, _ := json.Marshal(eventRecords) - response := bor.ResponseWithHeight{Height: "0"} - if err := json.Unmarshal(_res, &response.Result); err != nil { - t.Fatalf("%s", err) - } - - // at # sprintSize, events are fetched for the interval [from, (block-sprint).Time) - from := 0 + fromID := uint64(1) + // at # sprintSize, events are fetched for [fromID, (block-sprint).Time) to := int64(chain.GetHeaderByNumber(0).Time) - page := 1 - query1Params := fmt.Sprintf(clerkQueryParams, from, to, page) - h.On("FetchWithRetry", clerkPath, query1Params).Return(&response, nil) + eventCount := 50 - page = 2 - query2Params := fmt.Sprintf(clerkQueryParams, from, to, page) - h.On("FetchWithRetry", clerkPath, query2Params).Return(&bor.ResponseWithHeight{}, nil) + sample := getSampleEventRecord(t) + sample.Time = time.Unix(to-int64(eventCount+1), 0) // last event.Time will be just < to + eventRecords := generateFakeStateSyncEvents(sample, eventCount) + h.On("FetchStateSyncEvents", fromID, to).Return(eventRecords, nil) _bor.SetHeimdallClient(h) block = buildNextBlock(t, _bor, chain, block, nil, init.genesis.Config.Bor) insertNewBlock(t, chain, block) assert.True(t, h.AssertCalled(t, "FetchWithRetry", spanPath, "")) - assert.True(t, h.AssertCalled(t, "FetchWithRetry", clerkPath, query1Params)) - assert.True(t, h.AssertCalled(t, "FetchWithRetry", clerkPath, query2Params)) + assert.True(t, h.AssertCalled(t, "FetchStateSyncEvents", fromID, to)) } func TestFetchStateSyncEvents_2(t *testing.T) { @@ -121,64 +100,58 @@ func TestFetchStateSyncEvents_2(t *testing.T) { engine := init.ethereum.Engine() _bor := engine.(*bor.Bor) - // A. Insert blocks for 0th sprint - db := init.ethereum.ChainDb() - block := init.genesis.ToBlock(db) - // Insert sprintSize # of blocks so that span is fetched at the start of a new sprint - for i := uint64(1); i < sprintSize; i++ { - block = buildNextBlock(t, _bor, chain, block, nil, init.genesis.Config.Bor) - insertNewBlock(t, chain, block) - } - - // B. Before inserting 1st block of the next sprint, mock heimdall deps - // B.1 Mock /bor/span/1 + // Mock /bor/span/1 res, _ := loadSpanFromFile(t) h := &mocks.IHeimdallClient{} h.On("FetchWithRetry", spanPath, "").Return(res, nil) - // B.2 Mock State Sync events - // read heimdall api response from file - res = stateSyncEventsPayload(t) - var _eventRecords []*bor.EventRecordWithTime - if err := json.Unmarshal(res.Result, &_eventRecords); err != nil { - t.Fatalf("%s", err) - } - sample := _eventRecords[0] - - // First query will be from [0, (block-sprint).Time] - // Insert 4 events are in this time range - eventRecords := []*bor.EventRecordWithTime{ - buildStateEvent(sample, 2, 3), // id = 2, time = 3 - buildStateEvent(sample, 3, 2), // id = 3, time = 2 - buildStateEvent(sample, 1, 1), // id = 1, time = 1 - // event with id 4 is missing - buildStateEvent(sample, 5, 4), // id = 5, time = 4 - } - _res, _ := json.Marshal(eventRecords) - response := bor.ResponseWithHeight{Height: "0"} - if err := json.Unmarshal(_res, &response.Result); err != nil { - t.Fatalf("%s", err) - } - - from := 0 + // Mock State Sync events + // at # sprintSize, events are fetched for [fromID, (block-sprint).Time) + fromID := uint64(1) to := int64(chain.GetHeaderByNumber(0).Time) - page := 1 - queryParams := fmt.Sprintf(clerkQueryParams, from, to, page) - h.On("FetchWithRetry", clerkPath, queryParams).Return(&response, nil) + sample := getSampleEventRecord(t) - page = 2 - query2Params := fmt.Sprintf(clerkQueryParams, from, to, page) - h.On("FetchWithRetry", clerkPath, query2Params).Return(&bor.ResponseWithHeight{}, nil) + // First query will be from [id=1, (block-sprint).Time] + // Insert 5 events in this time range + eventRecords := []*bor.EventRecordWithTime{ + buildStateEvent(sample, 1, 3), // id = 1, time = 1 + buildStateEvent(sample, 2, 1), // id = 2, time = 3 + buildStateEvent(sample, 3, 2), // id = 3, time = 2 + // event with id 5 is missing + buildStateEvent(sample, 4, 5), // id = 4, time = 5 + buildStateEvent(sample, 6, 4), // id = 6, time = 4 + } + h.On("FetchStateSyncEvents", fromID, to).Return(eventRecords, nil) _bor.SetHeimdallClient(h) - block = buildNextBlock(t, _bor, chain, block, nil, init.genesis.Config.Bor) - insertNewBlock(t, chain, block) - + // Insert blocks for 0th sprint + db := init.ethereum.ChainDb() + block := init.genesis.ToBlock(db) + for i := uint64(1); i <= sprintSize; i++ { + block = buildNextBlock(t, _bor, chain, block, nil, init.genesis.Config.Bor) + insertNewBlock(t, chain, block) + } assert.True(t, h.AssertCalled(t, "FetchWithRetry", spanPath, "")) - assert.True(t, h.AssertCalled(t, "FetchWithRetry", clerkPath, queryParams)) + assert.True(t, h.AssertCalled(t, "FetchStateSyncEvents", fromID, to)) lastStateID, _ := _bor.GenesisContractsClient.LastStateId(sprintSize) - assert.Equal(t, uint64(3), lastStateID.Uint64()) - fmt.Println("lastStateId after", lastStateID) + // state 6 was not written + assert.Equal(t, uint64(4), lastStateID.Uint64()) + + // + fromID = uint64(5) + to = int64(chain.GetHeaderByNumber(sprintSize).Time) + eventRecords = []*bor.EventRecordWithTime{ + buildStateEvent(sample, 5, 7), + buildStateEvent(sample, 6, 4), + } + h.On("FetchStateSyncEvents", fromID, to).Return(eventRecords, nil) + for i := sprintSize + 1; i <= spanSize; i++ { + block = buildNextBlock(t, _bor, chain, block, nil, init.genesis.Config.Bor) + insertNewBlock(t, chain, block) + } + assert.True(t, h.AssertCalled(t, "FetchStateSyncEvents", fromID, to)) + lastStateID, _ = _bor.GenesisContractsClient.LastStateId(spanSize) + assert.Equal(t, uint64(6), lastStateID.Uint64()) } func TestOutOfTurnSigning(t *testing.T) { @@ -257,15 +230,17 @@ func getMockedHeimdallClient(t *testing.T) (*mocks.IHeimdallClient, *bor.Heimdal res, heimdallSpan := loadSpanFromFile(t) h := &mocks.IHeimdallClient{} h.On("FetchWithRetry", "bor/span/1", "").Return(res, nil) - h.On("FetchWithRetry", mock.AnythingOfType("string"), mock.AnythingOfType("string")).Return(stateSyncEventsPayload(t), nil) + h.On( + "FetchStateSyncEvents", + mock.AnythingOfType("uint64"), + mock.AnythingOfType("int64")).Return([]*bor.EventRecordWithTime{getSampleEventRecord(t)}, nil) return h, heimdallSpan } func generateFakeStateSyncEvents(sample *bor.EventRecordWithTime, count int) []*bor.EventRecordWithTime { events := make([]*bor.EventRecordWithTime, count) event := *sample - event.ID = 0 - event.Time = time.Now() + event.ID = 1 events[0] = &bor.EventRecordWithTime{} *events[0] = event for i := 1; i < count; i++ { @@ -283,3 +258,13 @@ func buildStateEvent(sample *bor.EventRecordWithTime, id uint64, timeStamp int64 event.Time = time.Unix(timeStamp, 0) return &event } + +func getSampleEventRecord(t *testing.T) *bor.EventRecordWithTime { + res := stateSyncEventsPayload(t) + var _eventRecords []*bor.EventRecordWithTime + if err := json.Unmarshal(res.Result, &_eventRecords); err != nil { + t.Fatalf("%s", err) + } + _eventRecords[0].Time = time.Unix(1, 0) + return _eventRecords[0] +} diff --git a/consensus/bor/bor_test/genesis.json b/consensus/bor/bor_test/genesis.json index 93f3cdbd3d..ca21f42e1a 100644 --- a/consensus/bor/bor_test/genesis.json +++ b/consensus/bor/bor_test/genesis.json @@ -31,7 +31,7 @@ }, "0000000000000000000000000000000000001001": { "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806319494a17146100515780633434735f146100ec5780634c7af28e146101365780635407ca6714610154575b600080fd5b6100d26004803603604081101561006757600080fd5b81019080803590602001909291908035906020019064010000000081111561008e57600080fd5b8201836020820111156100a057600080fd5b803590602001918460018302840111640100000000831117156100c257600080fd5b9091929391929390505050610172565b604051808215151515815260200191505060405180910390f35b6100f4610441565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61013e610459565b6040518082815260200191505060405180910390f35b61015c61045f565b6040518082815260200191505060405180910390f35b600073fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101c057600080fd5b83600081905550606061021e61021985858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610465565b610493565b9050600061023f8260008151811061023257fe5b6020026020010151610570565b9050806001805401146102ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f537461746549647320617265206e6f742073657175656e7469616c000000000081525060200191505060405180910390fd5b60016000815480929190600101919050555060006102eb836001815181106102de57fe5b60200260200101516105e1565b9050606061030c846002815181106102ff57fe5b6020026020010151610604565b905061031782610690565b15610436576000624c4b409050606084836040516024018083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610371578082015181840152602081019050610356565b50505050905090810190601f16801561039e5780820380516001836020036101000a031916815260200191505b5093505050506040516020818303038152906040527f26c53bea000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050905060008082516020840160008887f1965050505b505050509392505050565b73fffffffffffffffffffffffffffffffffffffffe81565b60005481565b60015481565b61046d610910565b600060208301905060405180604001604052808451815260200182815250915050919050565b606061049e826106a9565b6104a757600080fd5b60006104b2836106f7565b90506060816040519080825280602002602001820160405280156104f057816020015b6104dd61092a565b8152602001906001900390816104d55790505b50905060006105028560200151610768565b8560200151019050600080600090505b8481101561056357610523836107f1565b915060405180604001604052808381526020018481525084828151811061054657fe5b602002602001018190525081830192508080600101915050610512565b5082945050505050919050565b600080826000015111801561058a57506021826000015111155b61059357600080fd5b60006105a28360200151610768565b905060008184600001510390506000808386602001510190508051915060208310156105d557826020036101000a820491505b81945050505050919050565b600060158260000151146105f457600080fd5b6105fd82610570565b9050919050565b6060600082600001511161061757600080fd5b60006106268360200151610768565b905060008184600001510390506060816040519080825280601f01601f1916602001820160405280156106685781602001600182028038833980820191505090505b50905060008160200190506106848487602001510182856108a9565b81945050505050919050565b600080823b905060008163ffffffff1611915050919050565b600080826000015114156106c057600090506106f2565b60008083602001519050805160001a915060c060ff168260ff1610156106eb576000925050506106f2565b6001925050505b919050565b6000808260000151141561070e5760009050610763565b600080905060006107228460200151610768565b84602001510190506000846000015185602001510190505b8082101561075c5761074b826107f1565b82019150828060010193505061073a565b8293505050505b919050565b600080825160001a9050608060ff168110156107885760009150506107ec565b60b860ff168110806107ad575060c060ff1681101580156107ac575060f860ff1681105b5b156107bc5760019150506107ec565b60c060ff168110156107dc5760018060b80360ff168203019150506107ec565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff16811015610812576001915061089f565b60b860ff1681101561082f576001608060ff16820301915061089e565b60c060ff1681101561085f5760b78103600185019450806020036101000a8551046001820181019350505061089d565b60f860ff1681101561087c57600160c060ff16820301915061089c565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b60008114156108b75761090b565b5b602060ff1681106108e75782518252602060ff1683019250602060ff1682019150602060ff16810390506108b8565b6000600182602060ff16036101000a03905080198451168184511681811785525050505b505050565b604051806040016040528060008152602001600081525090565b60405180604001604052806000815260200160008152509056fea265627a7a72315820517dba64036af56cf58779d5f7ff3abb8279cf161ce9a6ad2c3f7cb1a1f1090764736f6c634300050c0032" + "code": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806319494a17146100465780633434735f146100e15780635407ca671461012b575b600080fd5b6100c76004803603604081101561005c57600080fd5b81019080803590602001909291908035906020019064010000000081111561008357600080fd5b82018360208201111561009557600080fd5b803590602001918460018302840111640100000000831117156100b757600080fd5b9091929391929390505050610149565b604051808215151515815260200191505060405180910390f35b6100e9610411565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610133610429565b6040518082815260200191505060405180910390f35b600073fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461019757600080fd5b60606101ee6101e985858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061042f565b61045d565b9050600061020f8260008151811061020257fe5b602002602001015161053a565b9050806001600054011461028b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f537461746549647320617265206e6f742073657175656e7469616c000000000081525060200191505060405180910390fd5b600080815480929190600101919050555060006102bb836001815181106102ae57fe5b60200260200101516105ab565b905060606102dc846002815181106102cf57fe5b60200260200101516105ce565b90506102e78261065a565b15610406576000624c4b409050606084836040516024018083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610341578082015181840152602081019050610326565b50505050905090810190601f16801561036e5780820380516001836020036101000a031916815260200191505b5093505050506040516020818303038152906040527f26c53bea000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050905060008082516020840160008887f1965050505b505050509392505050565b73fffffffffffffffffffffffffffffffffffffffe81565b60005481565b6104376108da565b600060208301905060405180604001604052808451815260200182815250915050919050565b606061046882610673565b61047157600080fd5b600061047c836106c1565b90506060816040519080825280602002602001820160405280156104ba57816020015b6104a76108f4565b81526020019060019003908161049f5790505b50905060006104cc8560200151610732565b8560200151019050600080600090505b8481101561052d576104ed836107bb565b915060405180604001604052808381526020018481525084828151811061051057fe5b6020026020010181905250818301925080806001019150506104dc565b5082945050505050919050565b600080826000015111801561055457506021826000015111155b61055d57600080fd5b600061056c8360200151610732565b9050600081846000015103905060008083866020015101905080519150602083101561059f57826020036101000a820491505b81945050505050919050565b600060158260000151146105be57600080fd5b6105c78261053a565b9050919050565b606060008260000151116105e157600080fd5b60006105f08360200151610732565b905060008184600001510390506060816040519080825280601f01601f1916602001820160405280156106325781602001600182028038833980820191505090505b509050600081602001905061064e848760200151018285610873565b81945050505050919050565b600080823b905060008163ffffffff1611915050919050565b6000808260000151141561068a57600090506106bc565b60008083602001519050805160001a915060c060ff168260ff1610156106b5576000925050506106bc565b6001925050505b919050565b600080826000015114156106d8576000905061072d565b600080905060006106ec8460200151610732565b84602001510190506000846000015185602001510190505b8082101561072657610715826107bb565b820191508280600101935050610704565b8293505050505b919050565b600080825160001a9050608060ff168110156107525760009150506107b6565b60b860ff16811080610777575060c060ff168110158015610776575060f860ff1681105b5b156107865760019150506107b6565b60c060ff168110156107a65760018060b80360ff168203019150506107b6565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff168110156107dc5760019150610869565b60b860ff168110156107f9576001608060ff168203019150610868565b60c060ff168110156108295760b78103600185019450806020036101000a85510460018201810193505050610867565b60f860ff1681101561084657600160c060ff168203019150610866565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b6000811415610881576108d5565b5b602060ff1681106108b15782518252602060ff1683019250602060ff1682019150602060ff1681039050610882565b6000600182602060ff16036101000a03905080198451168184511681811785525050505b505050565b604051806040016040528060008152602001600081525090565b60405180604001604052806000815260200160008152509056fea265627a7a723158206e562292874be6a994dcfabfea65957791c1491194eeb7dea6f7eaf1390c036e64736f6c634300050c0032" }, "0000000000000000000000000000000000001010": { "balance": "0x204fce28085b549b31600000", diff --git a/consensus/bor/errors.go b/consensus/bor/errors.go index 1a72d42f29..a1e60d1e21 100644 --- a/consensus/bor/errors.go +++ b/consensus/bor/errors.go @@ -128,17 +128,15 @@ func (e *WrongDifficultyError) Error() string { type InvalidStateReceivedError struct { Number uint64 LastStateID uint64 - From *time.Time To *time.Time Event *EventRecordWithTime } func (e *InvalidStateReceivedError) Error() string { return fmt.Sprintf( - "Received invalid event %s at block %d. Requested events from %s to %s. lastStateID was %d.", + "Received invalid event %s at block %d. Requested events until %s. Last state id was %d", e.Event, e.Number, - e.From.Format(time.RFC3339), e.To.Format(time.RFC3339), e.LastStateID, ) diff --git a/consensus/bor/genesis_contracts_client.go b/consensus/bor/genesis_contracts_client.go index cc65e9b1cb..17323f278d 100644 --- a/consensus/bor/genesis_contracts_client.go +++ b/consensus/bor/genesis_contracts_client.go @@ -4,9 +4,7 @@ import ( "context" "math" "math/big" - "strings" - "time" "github.com/maticnetwork/bor/accounts/abi" "github.com/maticnetwork/bor/common" @@ -30,7 +28,7 @@ type GenesisContractsClient struct { } const validatorsetABI = `[{"constant":true,"inputs":[],"name":"SPRINT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SYSTEM_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"CHAIN","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"FIRST_END_BLOCK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"producers","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ROUND_TYPE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"BOR_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"spanNumbers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"VOTE_TYPE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"validators","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"spans","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"startBlock","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"endBlock","type":"uint256"}],"name":"NewSpan","type":"event"},{"constant":true,"inputs":[],"name":"currentSprint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"}],"name":"getSpan","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getCurrentSpan","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getNextSpan","outputs":[{"internalType":"uint256","name":"number","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"number","type":"uint256"}],"name":"getSpanByBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"currentSpanNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"}],"name":"getValidatorsTotalStakeBySpan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"}],"name":"getProducersTotalStakeBySpan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"name":"getValidatorBySigner","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"power","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"internalType":"struct BorValidatorSet.Validator","name":"result","type":"tuple"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"name":"isValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"address","name":"signer","type":"address"}],"name":"isProducer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"isCurrentValidator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"isCurrentProducer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"number","type":"uint256"}],"name":"getBorValidators","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getInitialValidators","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getValidators","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"newSpan","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"},{"internalType":"bytes","name":"validatorBytes","type":"bytes"},{"internalType":"bytes","name":"producerBytes","type":"bytes"}],"name":"commitSpan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"span","type":"uint256"},{"internalType":"bytes32","name":"dataHash","type":"bytes32"},{"internalType":"bytes","name":"sigs","type":"bytes"}],"name":"getStakePowerBySigs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"rootHash","type":"bytes32"},{"internalType":"bytes32","name":"leaf","type":"bytes32"},{"internalType":"bytes","name":"proof","type":"bytes"}],"name":"checkMembership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"d","type":"bytes32"}],"name":"leafNode","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"left","type":"bytes32"},{"internalType":"bytes32","name":"right","type":"bytes32"}],"name":"innerNode","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"pure","type":"function"}]` -const stateReceiverABI = `[{"constant":true,"inputs":[],"name":"SYSTEM_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastStateSyncTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastStateId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"syncTime","type":"uint256"},{"internalType":"bytes","name":"recordBytes","type":"bytes"}],"name":"commitState","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]` +const stateReceiverABI = `[{"constant":true,"inputs":[],"name":"SYSTEM_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastStateId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"syncTime","type":"uint256"},{"internalType":"bytes","name":"recordBytes","type":"bytes"}],"name":"commitState","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]` func NewGenesisContractsClient( chainConfig *params.ChainConfig, @@ -76,33 +74,6 @@ func (gc *GenesisContractsClient) CommitState( return nil } -func (gc *GenesisContractsClient) LastStateSyncTime(snapshotNumber uint64) (time.Time, error) { - method := "lastStateSyncTime" - data, err := gc.stateReceiverABI.Pack(method) - if err != nil { - log.Error("Unable to pack tx for getLastSyncTime", "error", err) - return time.Time{}, err - } - - msgData := (hexutil.Bytes)(data) - toAddress := common.HexToAddress(gc.StateReceiverContract) - gas := (hexutil.Uint64)(uint64(math.MaxUint64 / 2)) - result, err := gc.ethAPI.Call(context.Background(), ethapi.CallArgs{ - Gas: &gas, - To: &toAddress, - Data: &msgData, - }, rpc.BlockNumber(snapshotNumber)) - if err != nil { - return time.Time{}, err - } - - var ret = new(*big.Int) - if err := gc.stateReceiverABI.Unpack(ret, method, result); err != nil { - return time.Time{}, err - } - return time.Unix((*ret).Int64(), 0), nil -} - func (gc *GenesisContractsClient) LastStateId(snapshotNumber uint64) (*big.Int, error) { method := "lastStateId" data, err := gc.stateReceiverABI.Pack(method) diff --git a/consensus/bor/rest.go b/consensus/bor/rest.go index 14bfb7853c..35ac91622f 100644 --- a/consensus/bor/rest.go +++ b/consensus/bor/rest.go @@ -6,11 +6,16 @@ import ( "io/ioutil" "net/http" "net/url" + "sort" "time" "github.com/maticnetwork/bor/log" ) +var ( + stateFetchLimit = 50 +) + // ResponseWithHeight defines a response object type that wraps an original // response with a height. type ResponseWithHeight struct { @@ -21,6 +26,7 @@ type ResponseWithHeight struct { type IHeimdallClient interface { Fetch(path string, query string) (*ResponseWithHeight, error) FetchWithRetry(path string, query string) (*ResponseWithHeight, error) + FetchStateSyncEvents(fromID uint64, to int64) ([]*EventRecordWithTime, error) } type HeimdallClient struct { @@ -38,6 +44,36 @@ func NewHeimdallClient(urlString string) (*HeimdallClient, error) { return h, nil } +func (h *HeimdallClient) FetchStateSyncEvents(fromID uint64, to int64) ([]*EventRecordWithTime, error) { + page := 1 + eventRecords := make([]*EventRecordWithTime, 0) + for { + queryParams := fmt.Sprintf("from-id=%d&to-time=%d&page=%d&limit=%d", fromID, to, page, stateFetchLimit) + log.Info("Fetching state sync events", "queryParams", queryParams) + response, err := h.FetchWithRetry("clerk/event-record/list", queryParams) + if err != nil { + return nil, err + } + var _eventRecords []*EventRecordWithTime + if response.Result == nil { // status 204 + break + } + if err := json.Unmarshal(response.Result, &_eventRecords); err != nil { + return nil, err + } + eventRecords = append(eventRecords, _eventRecords...) + if len(_eventRecords) < stateFetchLimit { + break + } + page++ + } + + sort.SliceStable(eventRecords, func(i, j int) bool { + return eventRecords[i].ID < eventRecords[j].ID + }) + return eventRecords, nil +} + // Fetch fetches response from heimdall func (h *HeimdallClient) Fetch(rawPath string, rawQuery string) (*ResponseWithHeight, error) { u, err := url.Parse(h.urlString) diff --git a/mocks/IHeimdallClient.go b/mocks/IHeimdallClient.go index 5bc7cb6e62..d6037d2162 100644 --- a/mocks/IHeimdallClient.go +++ b/mocks/IHeimdallClient.go @@ -35,6 +35,29 @@ func (_m *IHeimdallClient) Fetch(path string, query string) (*bor.ResponseWithHe return r0, r1 } +// FetchStateSyncEvents provides a mock function with given fields: fromID, to +func (_m *IHeimdallClient) FetchStateSyncEvents(fromID uint64, to int64) ([]*bor.EventRecordWithTime, error) { + ret := _m.Called(fromID, to) + + var r0 []*bor.EventRecordWithTime + if rf, ok := ret.Get(0).(func(uint64, int64) []*bor.EventRecordWithTime); ok { + r0 = rf(fromID, to) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*bor.EventRecordWithTime) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(uint64, int64) error); ok { + r1 = rf(fromID, to) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // FetchWithRetry provides a mock function with given fields: path, query func (_m *IHeimdallClient) FetchWithRetry(path string, query string) (*bor.ResponseWithHeight, error) { ret := _m.Called(path, query) From 165157580561a432667ac6dc0042deae2aefc9b1 Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Wed, 20 May 2020 14:15:41 +0530 Subject: [PATCH 44/46] remove page param --- consensus/bor/bor.go | 4 ---- consensus/bor/rest.go | 5 ++--- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 790fe86cf5..f456dc871c 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -1075,10 +1075,6 @@ func (c *Bor) CommitStates( chain chainContext, ) error { number := header.Number.Uint64() - // lastSync, err := c.GenesisContractsClient.LastStateSyncTime(number - 1) - // if err != nil { - // return err - // } _lastStateID, err := c.GenesisContractsClient.LastStateId(number - 1) if err != nil { return err diff --git a/consensus/bor/rest.go b/consensus/bor/rest.go index 35ac91622f..43a4439fde 100644 --- a/consensus/bor/rest.go +++ b/consensus/bor/rest.go @@ -45,10 +45,9 @@ func NewHeimdallClient(urlString string) (*HeimdallClient, error) { } func (h *HeimdallClient) FetchStateSyncEvents(fromID uint64, to int64) ([]*EventRecordWithTime, error) { - page := 1 eventRecords := make([]*EventRecordWithTime, 0) for { - queryParams := fmt.Sprintf("from-id=%d&to-time=%d&page=%d&limit=%d", fromID, to, page, stateFetchLimit) + queryParams := fmt.Sprintf("from-id=%d&to-time=%d&limit=%d", fromID, to, stateFetchLimit) log.Info("Fetching state sync events", "queryParams", queryParams) response, err := h.FetchWithRetry("clerk/event-record/list", queryParams) if err != nil { @@ -65,7 +64,7 @@ func (h *HeimdallClient) FetchStateSyncEvents(fromID uint64, to int64) ([]*Event if len(_eventRecords) < stateFetchLimit { break } - page++ + fromID += uint64(stateFetchLimit) } sort.SliceStable(eventRecords, func(i, j int) bool { From 1b50155c2ae825248d996228f8ba59453b73cdee Mon Sep 17 00:00:00 2001 From: Jaynti Kanani Date: Mon, 25 May 2020 12:27:09 +0530 Subject: [PATCH 45/46] chg: change gas limit 20m for linux packages --- .github/workflows/linuxpackage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linuxpackage.yml b/.github/workflows/linuxpackage.yml index 306cf00ffb..898bf19605 100644 --- a/.github/workflows/linuxpackage.yml +++ b/.github/workflows/linuxpackage.yml @@ -40,7 +40,7 @@ jobs: WorkingDirectory=/etc/bor/ EnvironmentFile=/etc/bor/metadata ExecStartPre=/bin/mkdir -p /var/log/matic-logs/ - ExecStart=/bin/bash -c "/usr/bin/bor --datadir /etc/bor/dataDir --port '30303' --rpc --rpcaddr '0.0.0.0' --rpcvhosts '*' --rpccorsdomain '*' --rpcport '8545' --ipcpath /etc/bor/geth.ipc --rpcapi 'bor,db,eth,net,web3,txpool,bor' --networkid ${NETWORK_ID} --miner.gaslimit '2000000000' --txpool.nolocals --txpool.accountslots '128' --txpool.globalslots '20000' --txpool.lifetime '0h16m0s' --keystore /etc/bor/dataDir/keystore --unlock ${VALIDATOR_ADDRESS} --password /etc/bor/dataDir/password.txt --allow-insecure-unlock --maxpeers 150 --mine > /var/log/matic-logs/bor.log 2>&1" + ExecStart=/bin/bash -c "/usr/bin/bor --datadir /etc/bor/dataDir --port '30303' --rpc --rpcaddr '0.0.0.0' --rpcvhosts '*' --rpccorsdomain '*' --rpcport '8545' --ipcpath /etc/bor/bor.ipc --rpcapi 'db,eth,net,web3,txpool,bor' --networkid ${NETWORK_ID} --miner.gaslimit '20000000' --txpool.nolocals --txpool.accountslots '128' --txpool.globalslots '20000' --txpool.lifetime '0h16m0s' --keystore /etc/bor/dataDir/keystore --unlock ${VALIDATOR_ADDRESS} --password /etc/bor/dataDir/password.txt --allow-insecure-unlock --maxpeers 150 --mine > /var/log/matic-logs/bor.log 2>&1" Type=simple User=root EOF From 2cafa99b182faa3e221a99185813b8193db35a4b Mon Sep 17 00:00:00 2001 From: Jaynti Kanani Date: Mon, 25 May 2020 16:12:51 +0530 Subject: [PATCH 46/46] chg: use default service logs instead of custom files --- .github/workflows/linuxpackage.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/linuxpackage.yml b/.github/workflows/linuxpackage.yml index 898bf19605..f41bc311ad 100644 --- a/.github/workflows/linuxpackage.yml +++ b/.github/workflows/linuxpackage.yml @@ -39,8 +39,7 @@ jobs: [Service] WorkingDirectory=/etc/bor/ EnvironmentFile=/etc/bor/metadata - ExecStartPre=/bin/mkdir -p /var/log/matic-logs/ - ExecStart=/bin/bash -c "/usr/bin/bor --datadir /etc/bor/dataDir --port '30303' --rpc --rpcaddr '0.0.0.0' --rpcvhosts '*' --rpccorsdomain '*' --rpcport '8545' --ipcpath /etc/bor/bor.ipc --rpcapi 'db,eth,net,web3,txpool,bor' --networkid ${NETWORK_ID} --miner.gaslimit '20000000' --txpool.nolocals --txpool.accountslots '128' --txpool.globalslots '20000' --txpool.lifetime '0h16m0s' --keystore /etc/bor/dataDir/keystore --unlock ${VALIDATOR_ADDRESS} --password /etc/bor/dataDir/password.txt --allow-insecure-unlock --maxpeers 150 --mine > /var/log/matic-logs/bor.log 2>&1" + ExecStart=/bin/bash -c "/usr/bin/bor --datadir /etc/bor/dataDir --port '30303' --rpc --rpcaddr '0.0.0.0' --rpcvhosts '*' --rpccorsdomain '*' --rpcport '8545' --ipcpath /etc/bor/bor.ipc --rpcapi 'db,eth,net,web3,txpool,bor' --networkid ${NETWORK_ID} --miner.gaslimit '20000000' --txpool.nolocals --txpool.accountslots '128' --txpool.globalslots '20000' --txpool.lifetime '0h16m0s' --keystore /etc/bor/dataDir/keystore --unlock ${VALIDATOR_ADDRESS} --password /etc/bor/dataDir/password.txt --allow-insecure-unlock --maxpeers 150 --mine" Type=simple User=root EOF