From 27fc66ef249994b07aebfa7c8bc5a7b4d31a2eea Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Thu, 27 Feb 2020 16:54:01 +0530 Subject: [PATCH 01/12] Add bor.isValidatorAction and call it while validating underpriced tx --- consensus/bor/bor.go | 18 ++++++++++++++++++ core/tx_pool.go | 15 +++++++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 0daf9353b041..1bdf00d81123 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -1218,6 +1218,24 @@ func (c *Bor) CommitStates( return nil } +func (c *Bor) isValidatorAction(chain consensus.ChainReader, from common.Address, tx *types.Transaction) bool { + header := chain.CurrentHeader() + snap, err := c.snapshot(chain, header.Number.Uint64(), header.Hash(), nil) + if err != nil { + log.Error("Failed fetching snapshot", err) + } + + _isValidatorAction := false + for _, validator := range snap.ValidatorSet.Validators { + if bytes.Compare(validator.Address.Bytes(), from.Bytes()) == 0 { + _isValidatorAction = true + break + } + } + // @todo only either of proposeState and proposeSpan should pass this check + return _isValidatorAction +} + // // Private methods // diff --git a/core/tx_pool.go b/core/tx_pool.go index a089394a18fd..39d66b5286eb 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -27,6 +27,7 @@ import ( "github.com/maticnetwork/bor/common" "github.com/maticnetwork/bor/common/prque" + "github.com/maticnetwork/bor/consensus" "github.com/maticnetwork/bor/core/state" "github.com/maticnetwork/bor/core/types" "github.com/maticnetwork/bor/event" @@ -116,14 +117,22 @@ 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 { CurrentBlock() *types.Block GetBlock(hash common.Hash, number uint64) *types.Block StateAt(root common.Hash) (*state.StateDB, error) - SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription + + Engine() consensus.Engine + CurrentHeader() *types.Header } // TxPoolConfig are the configuration parameters of the transaction pool. @@ -527,7 +536,9 @@ 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.gasPrice.Cmp(tx.GasPrice()) > 0 { + if !local && + !pool.chain.Engine().(bor).isValidatorAction(pool.chain.(consensus.ChainReader), from, tx) && + pool.gasPrice.Cmp(tx.GasPrice()) > 0 { return ErrUnderpriced } // Ensure the transaction adheres to nonce ordering From a3e01638a47473d23f509d09fde65ef917135a2f Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Tue, 3 Mar 2020 11:44:45 +0530 Subject: [PATCH 02/12] Test isValidatorAction :construction: --- consensus/bor/bor.go | 1 + consensus/bor/bor_test.go | 57 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 consensus/bor/bor_test.go diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 1bdf00d81123..00ef59f537af 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -1233,6 +1233,7 @@ func (c *Bor) isValidatorAction(chain consensus.ChainReader, from common.Address } } // @todo only either of proposeState and proposeSpan should pass this check + fmt.Println("tx.Data", tx.Data()) return _isValidatorAction } diff --git a/consensus/bor/bor_test.go b/consensus/bor/bor_test.go new file mode 100644 index 000000000000..e55d49c1f501 --- /dev/null +++ b/consensus/bor/bor_test.go @@ -0,0 +1,57 @@ +package bor + +import ( + "math/big" + "testing" + + "github.com/maticnetwork/bor/common" + "github.com/maticnetwork/bor/core" + "github.com/maticnetwork/bor/core/rawdb" + "github.com/maticnetwork/bor/core/types" + "github.com/maticnetwork/bor/core/vm" + "github.com/maticnetwork/bor/crypto" + "github.com/maticnetwork/bor/internal/ethapi" + "github.com/maticnetwork/bor/params" +) + +type MockEthAPI struct{} + +// func (ethapi *MockEthAPI) call() + +func TestIsValidatorAction(t *testing.T) { + var ( + db = rawdb.NewMemoryDatabase() + key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + addr = crypto.PubkeyToAddress(key.PublicKey) + // bor = New(¶ms.ChainConfig{}, db, ðapi.PublicBlockChainAPI{}) + // signer = new(types.HomesteadSigner) + ) + genspec := &core.Genesis{ + ExtraData: make([]byte, extraVanity+common.AddressLength+extraSeal), + Alloc: map[common.Address]core.GenesisAccount{ + addr: {Balance: big.NewInt(1)}, + }, + } + copy(genspec.ExtraData[extraVanity:], addr[:]) + genspec.MustCommit(db) + // genesis := genspec.MustCommit(db) + config := ¶ms.ChainConfig{ + Bor: ¶ms.BorConfig{ + ValidatorContract: "0x0000000000000000000000000000000000001000", + StateReceiverContract: "0x0000000000000000000000000000000000001001", + }, + } + bor := New(config, db, ðapi.PublicBlockChainAPI{}) + chain, err := core.NewBlockChain(db, nil, config, bor, vm.Config{}, nil) + if err != nil { + t.Fatalf("%s", err) + } + + tx := types.NewTransaction( + 0, + addr, // to - Just a place holder + big.NewInt(0), 0 /* fix gas limit */, big.NewInt(0), + nil, // data + ) + bor.isValidatorAction(chain, addr, tx) +} From 1d5b263362cb2c8820fca524fbac643139f1c35c Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Wed, 4 Mar 2020 15:43:29 +0530 Subject: [PATCH 03/12] WIP --- consensus/bor/bor.go | 8 ++-- consensus/bor/bor_test.go | 57 ----------------------- consensus/bor_test/bor_test.go | 82 +++++++++++++++++++++++++++++++++ consensus/bor_test/genesis.json | 47 +++++++++++++++++++ core/tx_pool.go | 4 +- 5 files changed, 135 insertions(+), 63 deletions(-) delete mode 100644 consensus/bor/bor_test.go create mode 100644 consensus/bor_test/bor_test.go create mode 100644 consensus/bor_test/genesis.json diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 00ef59f537af..5ff495cc9aaa 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -1218,23 +1218,23 @@ func (c *Bor) CommitStates( return nil } -func (c *Bor) isValidatorAction(chain consensus.ChainReader, from common.Address, tx *types.Transaction) bool { +func (c *Bor) IsValidatorAction(chain consensus.ChainReader, from common.Address, tx *types.Transaction) bool { header := chain.CurrentHeader() snap, err := c.snapshot(chain, header.Number.Uint64(), header.Hash(), nil) if err != nil { log.Error("Failed fetching snapshot", err) } - _isValidatorAction := false + _IsValidatorAction := false for _, validator := range snap.ValidatorSet.Validators { if bytes.Compare(validator.Address.Bytes(), from.Bytes()) == 0 { - _isValidatorAction = true + _IsValidatorAction = true break } } // @todo only either of proposeState and proposeSpan should pass this check fmt.Println("tx.Data", tx.Data()) - return _isValidatorAction + return _IsValidatorAction } // diff --git a/consensus/bor/bor_test.go b/consensus/bor/bor_test.go deleted file mode 100644 index e55d49c1f501..000000000000 --- a/consensus/bor/bor_test.go +++ /dev/null @@ -1,57 +0,0 @@ -package bor - -import ( - "math/big" - "testing" - - "github.com/maticnetwork/bor/common" - "github.com/maticnetwork/bor/core" - "github.com/maticnetwork/bor/core/rawdb" - "github.com/maticnetwork/bor/core/types" - "github.com/maticnetwork/bor/core/vm" - "github.com/maticnetwork/bor/crypto" - "github.com/maticnetwork/bor/internal/ethapi" - "github.com/maticnetwork/bor/params" -) - -type MockEthAPI struct{} - -// func (ethapi *MockEthAPI) call() - -func TestIsValidatorAction(t *testing.T) { - var ( - db = rawdb.NewMemoryDatabase() - key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - addr = crypto.PubkeyToAddress(key.PublicKey) - // bor = New(¶ms.ChainConfig{}, db, ðapi.PublicBlockChainAPI{}) - // signer = new(types.HomesteadSigner) - ) - genspec := &core.Genesis{ - ExtraData: make([]byte, extraVanity+common.AddressLength+extraSeal), - Alloc: map[common.Address]core.GenesisAccount{ - addr: {Balance: big.NewInt(1)}, - }, - } - copy(genspec.ExtraData[extraVanity:], addr[:]) - genspec.MustCommit(db) - // genesis := genspec.MustCommit(db) - config := ¶ms.ChainConfig{ - Bor: ¶ms.BorConfig{ - ValidatorContract: "0x0000000000000000000000000000000000001000", - StateReceiverContract: "0x0000000000000000000000000000000000001001", - }, - } - bor := New(config, db, ðapi.PublicBlockChainAPI{}) - chain, err := core.NewBlockChain(db, nil, config, bor, vm.Config{}, nil) - if err != nil { - t.Fatalf("%s", err) - } - - tx := types.NewTransaction( - 0, - addr, // to - Just a place holder - big.NewInt(0), 0 /* fix gas limit */, big.NewInt(0), - nil, // data - ) - bor.isValidatorAction(chain, addr, tx) -} diff --git a/consensus/bor_test/bor_test.go b/consensus/bor_test/bor_test.go new file mode 100644 index 000000000000..1750e4ac3b60 --- /dev/null +++ b/consensus/bor_test/bor_test.go @@ -0,0 +1,82 @@ +package bor_test + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "math/big" + "testing" + + "github.com/maticnetwork/bor/consensus/bor" + "github.com/maticnetwork/bor/core" + "github.com/maticnetwork/bor/core/rawdb" + "github.com/maticnetwork/bor/core/types" + "github.com/maticnetwork/bor/core/vm" + "github.com/maticnetwork/bor/crypto" + "github.com/maticnetwork/bor/eth" + "github.com/maticnetwork/bor/internal/ethapi" + // "github.com/maticnetwork/bor/node" + // "github.com/maticnetwork/bor/params" +) + +func TestIsValidatorAction(t *testing.T) { + var ( + db = rawdb.NewMemoryDatabase() + key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + addr = crypto.PubkeyToAddress(key.PublicKey) + // signer = new(types.HomesteadSigner) + ) + data, err := ioutil.ReadFile("genesis.json") + if err != nil { + t.Fatalf("%s", err) + } + config := eth.Config + Genesis: &core.Genesis{}, + } + // var genesis core.Genesis + if err := json.Unmarshal(data, config.Genesis); err != nil { + t.Fatalf("%s", err) + } + // fmt.Println(genesis) + chainConfig, _, err := core.SetupGenesisBlock(db, config.Genesis) + fmt.Printf("Chain config: %v\n", chainConfig) + + // copy(genspec.ExtraData[extraVanity:], addr[:]) + config.Genesis.MustCommit(db) + + _eth := ð.Ethereum{ + // config: config, + // chainDb: chainDb, + // eventMux: ctx.EventMux, + // accountManager: ctx.AccountManager, + // engine: nil, + // shutdownChan: make(chan bool), + // networkID: config.NetworkId, + // gasPrice: config.Miner.GasPrice, + // etherbase: config.Miner.Etherbase, + // bloomRequests: make(chan chan *bloombits.Retrieval), + // bloomIndexer: NewBloomIndexer(chainDb, params.BloomBitsBlocks, params.BloomConfirms), + } + + _eth.APIBackend = ð.EthAPIBackend{false, _eth, nil} + ethAPI := ethapi.NewPublicBlockChainAPI(_eth.APIBackend) + // ctx := &node.ServiceContext{ + // config: &node.Config{}, + // // services: make(map[reflect.Type]Service), + // // EventMux: n.eventmux, + // // AccountManager: n.accman, + // } + engine := bor.New(chainConfig, db, ðapi.PublicBlockChainAPI{}) + chain, err := core.NewBlockChain(db, nil, chainConfig, engine, vm.Config{}, nil) + if err != nil { + t.Fatalf("%s", err) + } + + tx := types.NewTransaction( + 0, + addr, // to - Just a place holder + big.NewInt(0), 0 /* fix gas limit */, big.NewInt(0), + nil, // data + ) + engine.IsValidatorAction(chain, addr, tx) +} diff --git a/consensus/bor_test/genesis.json b/consensus/bor_test/genesis.json new file mode 100644 index 000000000000..3adbd205a73f --- /dev/null +++ b/consensus/bor_test/genesis.json @@ -0,0 +1,47 @@ +{ + "config": { + "chainId": 15001, + "homesteadBlock": 1, + "eip150Block": 0, + "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "bor": { + "period": 1, + "producerDelay": 4, + "sprint": 64, + "validatorContract": "0x0000000000000000000000000000000000001000", + "stateReceiverContract": "0x0000000000000000000000000000000000001001", + "heimdall": "http://localhost:1317" + } + }, + "nonce": "0x0", + "timestamp": "0x5ce28211", + "extraData": "", + "gasLimit": "0x989680", + "difficulty": "0x1", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "coinbase": "0x0000000000000000000000000000000000000000", + "alloc": { + "0000000000000000000000000000000000001000": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106102115760003560e01c806365b3a1e211610125578063b2472431116100ad578063d0504f891161007c578063d0504f89146106af578063d5b844eb146106cb578063dcf2793a146106e9578063e3b7c9241461071b578063f59cf5651461073957610211565b8063b247243114610612578063b71d7a6914610630578063b7ab4db514610660578063c1b3c9191461067f57610211565b806370ba5707116100f457806370ba57071461055657806398ab2b62146105865780639d11b807146105a4578063ae756451146105d4578063af26aa96146105f257610211565b806365b3a1e2146104c957806366332354146104e8578063687a9bd61461050657806369c49fac1461053857610211565b806335ddfeea116101a85780634b0e4d17116101775780634b0e4d17146104215780634dbc959f1461042b57806355614fcc14610449578063582a8d081461047957806360c8614d146104a957610211565b806335ddfeea1461037357806343ee8213146103a357806344c15cb1146103c157806344d6528f146103f157610211565b806323f2a73f116101e457806323f2a73f146102c55780632de3a180146102f55780632eddf352146103255780633434735f1461035557610211565b8063047a6c5b146102165780630c35b1cb146102485780631270b5741461027957806323c2a2b4146102a9575b600080fd5b610230600480360361022b9190810190612e7e565b61076b565b60405161023f93929190613903565b60405180910390f35b610262600480360361025d9190810190612e7e565b6107c2565b6040516102709291906136c4565b60405180910390f35b610293600480360361028e9190810190612ea7565b61099e565b6040516102a091906136fb565b60405180910390f35b6102c360048036036102be9190810190612f86565b610af6565b005b6102df60048036036102da9190810190612ea7565b611177565b6040516102ec91906136fb565b60405180910390f35b61030f600480360361030a9190810190612d18565b6112cf565b60405161031c9190613716565b60405180910390f35b61033f600480360361033a9190810190612e7e565b611350565b60405161034c91906138b1565b60405180910390f35b61035d611481565b60405161036a91906136a9565b60405180910390f35b61038d60048036036103889190810190612d54565b611499565b60405161039a91906136fb565b60405180910390f35b6103ab611564565b6040516103b89190613716565b60405180910390f35b6103db60048036036103d69190810190612ee3565b61157b565b6040516103e891906138b1565b60405180910390f35b61040b60048036036104069190810190612ea7565b611663565b6040516104189190613896565b60405180910390f35b6104296117cc565b005b610433611828565b60405161044091906138b1565b60405180910390f35b610463600480360361045e9190810190612c9d565b611838565b60405161047091906136fb565b60405180910390f35b610493600480360361048e9190810190612cc6565b611852565b6040516104a09190613716565b60405180910390f35b6104b16118d0565b6040516104c093929190613903565b60405180910390f35b6104d1611944565b6040516104df9291906136c4565b60405180910390f35b6104f0611a34565b6040516104fd91906138b1565b60405180910390f35b610520600480360361051b9190810190612f4a565b611a39565b60405161052f939291906138cc565b60405180910390f35b610540611a9d565b60405161054d91906136fb565b60405180910390f35b610570600480360361056b9190810190612c9d565b611ab4565b60405161057d91906136fb565b60405180910390f35b61058e611ace565b60405161059b9190613716565b60405180910390f35b6105be60048036036105b99190810190612e7e565b611ae5565b6040516105cb91906138b1565b60405180910390f35b6105dc611c16565b6040516105e99190613716565b60405180910390f35b6105fa611c2d565b60405161060993929190613903565b60405180910390f35b61061a611c8e565b60405161062791906138b1565b60405180910390f35b61064a60048036036106459190810190612e7e565b611c94565b60405161065791906138b1565b60405180910390f35b610668611d94565b6040516106769291906136c4565b60405180910390f35b61069960048036036106949190810190612e7e565b611da8565b6040516106a691906138b1565b60405180910390f35b6106c960048036036106c49190810190612dbb565b611dc9565b005b6106d361201f565b6040516106e0919061393a565b60405180910390f35b61070360048036036106fe9190810190612f4a565b612024565b604051610712939291906138cc565b60405180910390f35b610723612088565b60405161073091906138b1565b60405180910390f35b610753600480360361074e9190810190612e7e565b61209a565b60405161076293929190613903565b60405180910390f35b60008060006004600085815260200190815260200160002060000154600460008681526020019081526020016000206001015460046000878152602001908152602001600020600201549250925092509193909250565b60608060ff83116107de576107d5611944565b91509150610999565b60006107e984611c94565b9050606060036000838152602001908152602001600020805490506040519080825280602002602001820160405280156108325781602001602082028038833980820191505090505b5090506060600360008481526020019081526020016000208054905060405190808252806020026020018201604052801561087c5781602001602082028038833980820191505090505b50905060008090505b600360008581526020019081526020016000208054905081101561098e576003600085815260200190815260200160002081815481106108c157fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168382815181106108ff57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060036000858152602001908152602001600020818154811061095757fe5b90600052602060002090600302016001015482828151811061097557fe5b6020026020010181815250508080600101915050610885565b508181945094505050505b915091565b6000606060036000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015610a71578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050815260200190600101906109d5565b50505050905060008090505b8151811015610ae9578373ffffffffffffffffffffffffffffffffffffffff16828281518110610aa957fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff161415610adc57600192505050610af0565b8080600101915050610a7d565b5060009150505b92915050565b73fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b4257600080fd5b6000610b4c611828565b90506000811415610b6057610b5f6120c4565b5b610b746001826123f090919063ffffffff16565b8814610bb5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bac906137b6565b60405180910390fd5b868611610bf7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bee90613816565b60405180910390fd5b6000805460018989030181610c0857fe5b0614610c49576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c40906137f6565b60405180910390fd5b8660046000838152602001908152602001600020600101541115610ca2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c9990613776565b60405180910390fd5b6000600460008a81526020019081526020016000206000015414610cfb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cf2906137d6565b60405180910390fd5b604051806060016040528089815260200188815260200187815250600460008a815260200190815260200160002060008201518160000155602082015181600101556040820151816002015590505060058890806001815401808255809150509060018203906000526020600020016000909192909190915055506000600260008a815260200190815260200160002081610d969190612a97565b506000600360008a815260200190815260200160002081610db79190612a97565b506060610e0f610e0a87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061240f565b61243d565b905060008090505b8151811015610f83576060610e3e838381518110610e3157fe5b602002602001015161243d565b9050600260008c81526020019081526020016000208054809190600101610e659190612a97565b506040518060600160405280610e8e83600081518110610e8157fe5b602002602001015161251a565b8152602001610eb083600181518110610ea357fe5b602002602001015161251a565b8152602001610ed283600281518110610ec557fe5b602002602001015161258b565b73ffffffffffffffffffffffffffffffffffffffff16815250600260008d81526020019081526020016000208381548110610f0957fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050508080600101915050610e17565b506060610fdb610fd686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061240f565b61243d565b905060008090505b815181101561114f57606061100a838381518110610ffd57fe5b602002602001015161243d565b9050600360008d815260200190815260200160002080548091906001016110319190612a97565b50604051806060016040528061105a8360008151811061104d57fe5b602002602001015161251a565b815260200161107c8360018151811061106f57fe5b602002602001015161251a565b815260200161109e8360028151811061109157fe5b602002602001015161258b565b73ffffffffffffffffffffffffffffffffffffffff16815250600360008e815260200190815260200160002083815481106110d557fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050508080600101915050610fe3565b506000600160006101000a81548160ff02191690831515021790555050505050505050505050565b6000606060026000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561124a578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050815260200190600101906111ae565b50505050905060008090505b81518110156112c2578373ffffffffffffffffffffffffffffffffffffffff1682828151811061128257fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff1614156112b5576001925050506112c9565b8080600101915050611256565b5060009150505b92915050565b60006002600160f81b84846040516020016112ec93929190613616565b6040516020818303038152906040526040516113089190613653565b602060405180830381855afa158015611325573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506113489190810190612cef565b905092915050565b6000606060026000848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015611423578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611387565b505050509050600080905060008090505b82518110156114765761146783828151811061144c57fe5b602002602001015160200151836123f090919063ffffffff16565b91508080600101915050611434565b508092505050919050565b73fffffffffffffffffffffffffffffffffffffffe81565b60008060008085905060006021808751816114b057fe5b0402905060008111156114c9576114c687611852565b91505b6000602190505b818111611553576000600182038801519050818801519550806000602081106114f557fe5b1a60f81b9450600060f81b857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561153a5761153386856112cf565b9350611547565b61154484876112cf565b93505b506021810190506114d0565b508782149450505050509392505050565b6040516115709061367f565b604051809103902081565b60008060009050600080905060008090505b84518167ffffffffffffffff1610156116565760606115b8868367ffffffffffffffff1660416125ae565b905060006115cf828961263a90919063ffffffff16565b90506115d9612ac9565b6115e38a83611663565b90506115ef8a83611177565b801561162657508473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16115b15611648578194506116458160200151876123f090919063ffffffff16565b95505b50505060418101905061158d565b5081925050509392505050565b61166b612ac9565b606060026000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561173c578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050815260200190600101906116a0565b50505050905060008090505b81518110156117c4578373ffffffffffffffffffffffffffffffffffffffff1682828151811061177457fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff1614156117b7578181815181106117a857fe5b602002602001015192506117c4565b8080600101915050611748565b505092915050565b60006117d6611828565b90506117e28133611177565b6117eb57600080fd5b60001515600160009054906101000a900460ff1615151461180b57600080fd5b60018060006101000a81548160ff02191690831515021790555050565b600061183343611c94565b905090565b600061184b611845611828565b83611177565b9050919050565b60006002600060f81b8360405160200161186d9291906135ea565b6040516020818303038152906040526040516118899190613653565b602060405180830381855afa1580156118a6573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506118c99190810190612cef565b9050919050565b6000806000806118f160016118e3611828565b6123f090919063ffffffff16565b905060046000828152602001908152602001600020600001546004600083815260200190815260200160002060010154600460008481526020019081526020016000206002015493509350935050909192565b606080606060016040519080825280602002602001820160405280156119795781602001602082028038833980820191505090505b509050736c468cf8c9879006e22ec4029696e005c2319c9d8160008151811061199e57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060606001604051908082528060200260200182016040528015611a0a5781602001602082028038833980820191505090505b509050600a81600081518110611a1c57fe5b60200260200101818152505081819350935050509091565b60ff81565b60036020528160005260406000208181548110611a5257fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b6000600160009054906101000a900460ff16905090565b6000611ac7611ac1611828565b8361099e565b9050919050565b604051611ada9061366a565b604051809103902081565b6000606060036000848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015611bb8578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611b1c565b505050509050600080905060008090505b8251811015611c0b57611bfc838281518110611be157fe5b602002602001015160200151836123f090919063ffffffff16565b91508080600101915050611bc9565b508092505050919050565b604051611c2290613694565b604051809103902081565b600080600080611c3b611828565b905060046000828152602001908152602001600020600001546004600083815260200190815260200160002060010154600460008481526020019081526020016000206002015493509350935050909192565b60005481565b60008060058054905090505b6000811115611d5457611cb1612b00565b6004600060056001850381548110611cc557fe5b906000526020600020015481526020019081526020016000206040518060600160405290816000820154815260200160018201548152602001600282015481525050905083816020015111158015611d2257506000816040015114155b8015611d32575080604001518411155b15611d4557806000015192505050611d8f565b50808060019003915050611ca0565b5060006005805490501115611d8a57600560016005805490500381548110611d7857fe5b90600052602060002001549050611d8f565b600090505b919050565b606080611da0436107c2565b915091509091565b60058181548110611db557fe5b906000526020600020016000915090505481565b6060611ddc611dd78661240f565b61243d565b9050604051611dea9061367f565b6040518091039020611e0f82600081518110611e0257fe5b6020026020010151612744565b8051906020012014611e56576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e4d90613796565b60405180910390fd5b600260ff16611e7882600181518110611e6b57fe5b602002602001015161251a565b14611eb8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eaf90613836565b60405180910390fd5b611f31611ed882600481518110611ecb57fe5b602002602001015161251a565b60001b600285604051611eeb9190613653565b602060405180830381855afa158015611f08573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250611f2b9190810190612cef565b84611499565b611f70576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6790613856565b60405180910390fd5b6000611f7a611828565b90506000611f908288805190602001208861157b565b9050611fd46001611fc66003611fb86002611faa88611350565b6127d090919063ffffffff16565b61280a90919063ffffffff16565b6123f090919063ffffffff16565b811015612016576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161200d90613876565b60405180910390fd5b50505050505050565b600281565b6002602052816000526040600020818154811061203d57fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b60006040438161209457fe5b04905090565b60046020528060005260406000206000915090508060000154908060010154908060020154905083565b60406000819055506060806120d7611944565b8092508193505050600080905060405180606001604052808281526020016000815260200160ff815250600460008381526020019081526020016000206000820151816000015560208201518160010155604082015181600201559050506005819080600181540180825580915050906001820390600052602060002001600090919290919091505550600060026000838152602001908152602001600020816121819190612a97565b50600060036000838152602001908152602001600020816121a29190612a97565b5060008090505b83518110156122c6576002600083815260200190815260200160002080548091906001016121d79190612a97565b5060405180606001604052808281526020018483815181106121f557fe5b6020026020010151815260200185838151811061220e57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681525060026000848152602001908152602001600020828154811061224d57fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505080806001019150506121a9565b5060008090505b83518110156123ea576003600083815260200190815260200160002080548091906001016122fb9190612a97565b50604051806060016040528082815260200184838151811061231957fe5b6020026020010151815260200185838151811061233257fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681525060036000848152602001908152602001600020828154811061237157fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505080806001019150506122cd565b50505050565b60008082840190508381101561240557600080fd5b8091505092915050565b612417612b21565b600060208301905060405180604001604052808451815260200182815250915050919050565b606061244882612830565b61245157600080fd5b600061245c8361287e565b905060608160405190808252806020026020018201604052801561249a57816020015b612487612b3b565b81526020019060019003908161247f5790505b50905060006124ac85602001516128ef565b8560200151019050600080600090505b8481101561250d576124cd83612978565b91506040518060400160405280838152602001848152508482815181106124f057fe5b6020026020010181905250818301925080806001019150506124bc565b5082945050505050919050565b600080826000015111801561253457506021826000015111155b61253d57600080fd5b600061254c83602001516128ef565b9050600081846000015103905060008083866020015101905080519150602083101561257f57826020036101000a820491505b81945050505050919050565b6000601582600001511461259e57600080fd5b6125a78261251a565b9050919050565b6060818301845110156125c057600080fd5b60608215600081146125dd5760405191506020820160405261262e565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561261b57805183526020830192506020810190506125fe565b50868552601f19601f8301166040525050505b50809150509392505050565b6000806000806041855114612655576000935050505061273e565b602085015192506040850151915060ff6041860151169050601b8160ff16101561268057601b810190505b601b8160ff16141580156126985750601c8160ff1614155b156126a9576000935050505061273e565b6000600187838686604051600081526020016040526040516126ce9493929190613731565b6020604051602081039080840390855afa1580156126f0573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561273657600080fd5b809450505050505b92915050565b6060600082600001511161275757600080fd5b600061276683602001516128ef565b905060008184600001510390506060816040519080825280601f01601f1916602001820160405280156127a85781602001600182028038833980820191505090505b50905060008160200190506127c4848760200151018285612a30565b81945050505050919050565b6000808314156127e35760009050612804565b60008284029050828482816127f457fe5b04146127ff57600080fd5b809150505b92915050565b600080821161281857600080fd5b600082848161282357fe5b0490508091505092915050565b600080826000015114156128475760009050612879565b60008083602001519050805160001a915060c060ff168260ff16101561287257600092505050612879565b6001925050505b919050565b6000808260000151141561289557600090506128ea565b600080905060006128a984602001516128ef565b84602001510190506000846000015185602001510190505b808210156128e3576128d282612978565b8201915082806001019350506128c1565b8293505050505b919050565b600080825160001a9050608060ff1681101561290f576000915050612973565b60b860ff16811080612934575060c060ff168110158015612933575060f860ff1681105b5b15612943576001915050612973565b60c060ff168110156129635760018060b80360ff16820301915050612973565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff168110156129995760019150612a26565b60b860ff168110156129b6576001608060ff168203019150612a25565b60c060ff168110156129e65760b78103600185019450806020036101000a85510460018201810193505050612a24565b60f860ff16811015612a0357600160c060ff168203019150612a23565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b6000811415612a3e57612a92565b5b602060ff168110612a6e5782518252602060ff1683019250602060ff1682019150602060ff1681039050612a3f565b6000600182602060ff16036101000a03905080198451168184511681811785525050505b505050565b815481835581811115612ac457600302816003028360005260206000209182019101612ac39190612b55565b5b505050565b60405180606001604052806000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b60405180606001604052806000815260200160008152602001600081525090565b604051806040016040528060008152602001600081525090565b604051806040016040528060008152602001600081525090565b612ba891905b80821115612ba45760008082016000905560018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550600301612b5b565b5090565b90565b600081359050612bba81613b33565b92915050565b600081359050612bcf81613b4a565b92915050565b600081519050612be481613b4a565b92915050565b60008083601f840112612bfc57600080fd5b8235905067ffffffffffffffff811115612c1557600080fd5b602083019150836001820283011115612c2d57600080fd5b9250929050565b600082601f830112612c4557600080fd5b8135612c58612c5382613982565b613955565b91508082526020830160208301858383011115612c7457600080fd5b612c7f838284613add565b50505092915050565b600081359050612c9781613b61565b92915050565b600060208284031215612caf57600080fd5b6000612cbd84828501612bab565b91505092915050565b600060208284031215612cd857600080fd5b6000612ce684828501612bc0565b91505092915050565b600060208284031215612d0157600080fd5b6000612d0f84828501612bd5565b91505092915050565b60008060408385031215612d2b57600080fd5b6000612d3985828601612bc0565b9250506020612d4a85828601612bc0565b9150509250929050565b600080600060608486031215612d6957600080fd5b6000612d7786828701612bc0565b9350506020612d8886828701612bc0565b925050604084013567ffffffffffffffff811115612da557600080fd5b612db186828701612c34565b9150509250925092565b60008060008060808587031215612dd157600080fd5b600085013567ffffffffffffffff811115612deb57600080fd5b612df787828801612c34565b945050602085013567ffffffffffffffff811115612e1457600080fd5b612e2087828801612c34565b935050604085013567ffffffffffffffff811115612e3d57600080fd5b612e4987828801612c34565b925050606085013567ffffffffffffffff811115612e6657600080fd5b612e7287828801612c34565b91505092959194509250565b600060208284031215612e9057600080fd5b6000612e9e84828501612c88565b91505092915050565b60008060408385031215612eba57600080fd5b6000612ec885828601612c88565b9250506020612ed985828601612bab565b9150509250929050565b600080600060608486031215612ef857600080fd5b6000612f0686828701612c88565b9350506020612f1786828701612bc0565b925050604084013567ffffffffffffffff811115612f3457600080fd5b612f4086828701612c34565b9150509250925092565b60008060408385031215612f5d57600080fd5b6000612f6b85828601612c88565b9250506020612f7c85828601612c88565b9150509250929050565b600080600080600080600060a0888a031215612fa157600080fd5b6000612faf8a828b01612c88565b9750506020612fc08a828b01612c88565b9650506040612fd18a828b01612c88565b955050606088013567ffffffffffffffff811115612fee57600080fd5b612ffa8a828b01612bea565b9450945050608088013567ffffffffffffffff81111561301957600080fd5b6130258a828b01612bea565b925092505092959891949750929550565b60006130428383613066565b60208301905092915050565b600061305a83836135bd565b60208301905092915050565b61306f81613a52565b82525050565b61307e81613a52565b82525050565b600061308f826139ce565b6130998185613a09565b93506130a4836139ae565b8060005b838110156130d55781516130bc8882613036565b97506130c7836139ef565b9250506001810190506130a8565b5085935050505092915050565b60006130ed826139d9565b6130f78185613a1a565b9350613102836139be565b8060005b8381101561313357815161311a888261304e565b9750613125836139fc565b925050600181019050613106565b5085935050505092915050565b61314981613a64565b82525050565b61316061315b82613a70565b613b1f565b82525050565b61316f81613a9c565b82525050565b61318661318182613a9c565b613b29565b82525050565b6000613197826139e4565b6131a18185613a2b565b93506131b1818560208601613aec565b80840191505092915050565b60006131ca600483613a47565b91507f766f7465000000000000000000000000000000000000000000000000000000006000830152600482019050919050565b600061320a602d83613a36565b91507f537461727420626c6f636b206d7573742062652067726561746572207468616e60008301527f2063757272656e74207370616e000000000000000000000000000000000000006020830152604082019050919050565b6000613270600f83613a47565b91507f6865696d64616c6c2d50357258776700000000000000000000000000000000006000830152600f82019050919050565b60006132b0601383613a36565b91507f436861696e20494420697320696e76616c6964000000000000000000000000006000830152602082019050919050565b60006132f0600f83613a36565b91507f496e76616c6964207370616e20696400000000000000000000000000000000006000830152602082019050919050565b6000613330601383613a36565b91507f5370616e20616c726561647920657869737473000000000000000000000000006000830152602082019050919050565b6000613370604583613a36565b91507f446966666572656e6365206265747765656e20737461727420616e6420656e6460008301527f20626c6f636b206d75737420626520696e206d756c7469706c6573206f66207360208301527f7072696e740000000000000000000000000000000000000000000000000000006040830152606082019050919050565b60006133fc602a83613a36565b91507f456e6420626c6f636b206d7573742062652067726561746572207468616e207360008301527f7461727420626c6f636b000000000000000000000000000000000000000000006020830152604082019050919050565b6000613462601483613a36565b91507f566f7465207479706520697320696e76616c69640000000000000000000000006000830152602082019050919050565b60006134a2601683613a36565b91507f5472616e73616374696f6e20697320696e76616c6964000000000000000000006000830152602082019050919050565b60006134e2600583613a47565b91507f31353030310000000000000000000000000000000000000000000000000000006000830152600582019050919050565b6000613522602483613a36565b91507f4e6f7420656e6f7567687420706f77657220746f206368616e6765207468652060008301527f7370616e000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60608201600082015161359160008501826135bd565b5060208201516135a460208501826135bd565b5060408201516135b76040850182613066565b50505050565b6135c681613ac6565b82525050565b6135d581613ac6565b82525050565b6135e481613ad0565b82525050565b60006135f6828561314f565b6001820191506136068284613175565b6020820191508190509392505050565b6000613622828661314f565b6001820191506136328285613175565b6020820191506136428284613175565b602082019150819050949350505050565b600061365f828461318c565b915081905092915050565b6000613675826131bd565b9150819050919050565b600061368a82613263565b9150819050919050565b600061369f826134d5565b9150819050919050565b60006020820190506136be6000830184613075565b92915050565b600060408201905081810360008301526136de8185613084565b905081810360208301526136f281846130e2565b90509392505050565b60006020820190506137106000830184613140565b92915050565b600060208201905061372b6000830184613166565b92915050565b60006080820190506137466000830187613166565b61375360208301866135db565b6137606040830185613166565b61376d6060830184613166565b95945050505050565b6000602082019050818103600083015261378f816131fd565b9050919050565b600060208201905081810360008301526137af816132a3565b9050919050565b600060208201905081810360008301526137cf816132e3565b9050919050565b600060208201905081810360008301526137ef81613323565b9050919050565b6000602082019050818103600083015261380f81613363565b9050919050565b6000602082019050818103600083015261382f816133ef565b9050919050565b6000602082019050818103600083015261384f81613455565b9050919050565b6000602082019050818103600083015261386f81613495565b9050919050565b6000602082019050818103600083015261388f81613515565b9050919050565b60006060820190506138ab600083018461357b565b92915050565b60006020820190506138c660008301846135cc565b92915050565b60006060820190506138e160008301866135cc565b6138ee60208301856135cc565b6138fb6040830184613075565b949350505050565b600060608201905061391860008301866135cc565b61392560208301856135cc565b61393260408301846135cc565b949350505050565b600060208201905061394f60008301846135db565b92915050565b6000604051905081810181811067ffffffffffffffff8211171561397857600080fd5b8060405250919050565b600067ffffffffffffffff82111561399957600080fd5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000613a5d82613aa6565b9050919050565b60008115159050919050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b82818337600083830152505050565b60005b83811015613b0a578082015181840152602081019050613aef565b83811115613b19576000848401525b50505050565b6000819050919050565b6000819050919050565b613b3c81613a52565b8114613b4757600080fd5b50565b613b5381613a9c565b8114613b5e57600080fd5b50565b613b6a81613ac6565b8114613b7557600080fd5b5056fea365627a7a72315820234efaeec44cd697e3b3da6f1185de12a990609aeccd9385ae0e67cf398056796c6578706572696d656e74616cf564736f6c634300050b0040" + }, + "0000000000000000000000000000000000001001": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b506004361061009e5760003560e01c8063d0504f8911610066578063d0504f8914610255578063d79e60b7146104d5578063ede01f17146104f7578063f552102214610525578063facd743b146105815761009e565b8063017a9105146100a3578063080356b7146100e957806321ec23b6146101625780633434735f146101c15780639426e2261461020b575b600080fd5b6100cf600480360360208110156100b957600080fd5b81019080803590602001909291905050506105dd565b604051808215151515815260200191505060405180910390f35b610160600480360360208110156100ff57600080fd5b810190808035906020019064010000000081111561011c57600080fd5b82018360208201111561012e57600080fd5b8035906020019184600183028401116401000000008311171561015057600080fd5b90919293919293905050506105fd565b005b61016a61094a565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156101ad578082015181840152602081019050610192565b505050509050019250505060405180910390f35b6101c96109fb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610213610a13565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6104d36004803603608081101561026b57600080fd5b810190808035906020019064010000000081111561028857600080fd5b82018360208201111561029a57600080fd5b803590602001918460018302840111640100000000831117156102bc57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561031f57600080fd5b82018360208201111561033157600080fd5b8035906020019184600183028401116401000000008311171561035357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156103b657600080fd5b8201836020820111156103c857600080fd5b803590602001918460018302840111640100000000831117156103ea57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561044d57600080fd5b82018360208201111561045f57600080fd5b8035906020019184600183028401116401000000008311171561048157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610a19565b005b6104dd610c38565b604051808215151515815260200191505060405180910390f35b6105236004803603602081101561050d57600080fd5b8101908080359060200190929190505050610c70565b005b6105676004803603602081101561053b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610e1a565b604051808215151515815260200191505060405180910390f35b6105c36004803603602081101561059757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610edd565b604051808215151515815260200191505060405180910390f35b60036020528060005260406000206000915054906101000a900460ff1681565b73fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461064957600080fd5b60606106a061069b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610fa0565b610fce565b905060006106c1826000815181106106b457fe5b60200260200101516110ab565b905060006106e2836001815181106106d557fe5b602002602001015161111c565b90506060610703846002815181106106f657fe5b602002602001015161113f565b9050600115156107146000856111cb565b151514610789576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f496e76616c69642070726f706f7365642073746174652069640000000000000081525060200191505060405180910390fd5b600015156003600085815260200190815260200160002060009054906101000a900460ff16151514610823576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f496e76616c69642073746174652069640000000000000000000000000000000081525060200191505060405180910390fd5b61082c826111f0565b1561090a578173ffffffffffffffffffffffffffffffffffffffff166326c53bea84836040518363ffffffff1660e01b81526004018083815260200180602001828103825283818151815260200191508051906020019080838360005b838110156108a4578082015181840152602081019050610889565b50505050905090810190601f1680156108d15780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156108f157600080fd5b505af1158015610905573d6000803e3d6000fd5b505050505b60016003600085815260200190815260200160002060006101000a81548160ff021916908315150217905550610941600084611209565b50505050505050565b6060600080905060606000600201546040519080825280602002602001820160405280156109875781602001602082028038833980820191505090505b509050600061099660006112c7565b90505b6109a46000826112fa565b156109f2576000806109b760008461130e565b8092508193505050818486815181106109cc57fe5b60200260200101818152505060018501945050506109eb600082611363565b9050610999565b50809250505090565b73fffffffffffffffffffffffffffffffffffffffe81565b61100081565b61100073ffffffffffffffffffffffffffffffffffffffff1663d0504f89858585856040518563ffffffff1660e01b81526004018080602001806020018060200180602001858103855289818151815260200191508051906020019080838360005b83811015610a96578082015181840152602081019050610a7b565b50505050905090810190601f168015610ac35780820380516001836020036101000a031916815260200191505b50858103845288818151815260200191508051906020019080838360005b83811015610afc578082015181840152602081019050610ae1565b50505050905090810190601f168015610b295780820380516001836020036101000a031916815260200191505b50858103835287818151815260200191508051906020019080838360005b83811015610b62578082015181840152602081019050610b47565b50505050905090810190601f168015610b8f5780820380516001836020036101000a031916815260200191505b50858103825286818151815260200191508051906020019080838360005b83811015610bc8578082015181840152602081019050610bad565b50505050905090810190601f168015610bf55780820380516001836020036101000a031916815260200191505b5098505050505050505050600060405180830381600087803b158015610c1a57600080fd5b505af1158015610c2e573d6000803e3d6000fd5b5050505050505050565b600061100073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b610c7933610edd565b610ceb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f496e76616c69642076616c696461746f7200000000000000000000000000000081525060200191505060405180910390fd5b60001515610cfa6000836111cb565b151514610d6f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f537461746520616c72656164792070726f706f7365640000000000000000000081525060200191505060405180910390fd5b600015156003600083815260200190815260200160002060009054906101000a900460ff16151514610e09576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f537461746520616c726561647920636f6d6d697474656400000000000000000081525060200191505060405180910390fd5b610e1660008260016113c9565b5050565b600061100073ffffffffffffffffffffffffffffffffffffffff166370ba5707836040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015610e9b57600080fd5b505afa158015610eaf573d6000803e3d6000fd5b505050506040513d6020811015610ec557600080fd5b81019080805190602001909291905050509050919050565b600061100073ffffffffffffffffffffffffffffffffffffffff166355614fcc836040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015610f5e57600080fd5b505afa158015610f72573d6000803e3d6000fd5b505050506040513d6020811015610f8857600080fd5b81019080805190602001909291905050509050919050565b610fa861170f565b600060208301905060405180604001604052808451815260200182815250915050919050565b6060610fd9826114a8565b610fe257600080fd5b6000610fed836114f6565b905060608160405190808252806020026020018201604052801561102b57816020015b611018611729565b8152602001906001900390816110105790505b509050600061103d8560200151611567565b8560200151019050600080600090505b8481101561109e5761105e836115f0565b915060405180604001604052808381526020018481525084828151811061108157fe5b60200260200101819052508183019250808060010191505061104d565b5082945050505050919050565b60008082600001511180156110c557506021826000015111155b6110ce57600080fd5b60006110dd8360200151611567565b9050600081846000015103905060008083866020015101905080519150602083101561111057826020036101000a820491505b81945050505050919050565b6000601582600001511461112f57600080fd5b611138826110ab565b9050919050565b6060600082600001511161115257600080fd5b60006111618360200151611567565b905060008184600001510390506060816040519080825280601f01601f1916602001820160405280156111a35781602001600182028038833980820191505090505b50905060008160200190506111bf8487602001510182856116a8565b81945050505050919050565b6000808360000160008481526020019081526020016000206000015411905092915050565b600080823b905060008163ffffffff1611915050919050565b600080836000016000848152602001908152602001600020600001549050600081141561123a5760009150506112c1565b8360000160008481526020019081526020016000206000808201600090556001820160006101000a81549060ff02191690555050600184600101600183038154811061128257fe5b906000526020600020906002020160010160006101000a81548160ff021916908315150217905550836002016000815480929190600190039190505550505b92915050565b60006112f3827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611363565b9050919050565b600082600101805490508210905092915050565b60008083600101838154811061132057fe5b906000526020600020906002020160000154915083600001600083815260200190815260200160002060010160009054906101000a900460ff1690509250929050565b600081806001019250505b8260010180549050821080156113ae575082600101828154811061138e57fe5b906000526020600020906002020160010160009054906101000a900460ff165b156113c057818060010192505061136e565b81905092915050565b6000808460000160008581526020019081526020016000206000015490508285600001600086815260200190815260200160002060010160006101000a81548160ff021916908315150217905550600081111561142a5760019150506114a1565b8460010180548091906001016114409190611743565b905060018101856000016000868152602001908152602001600020600001819055508385600101828154811061147257fe5b906000526020600020906002020160000181905550846002016000815480929190600101919050555060009150505b9392505050565b600080826000015114156114bf57600090506114f1565b60008083602001519050805160001a915060c060ff168260ff1610156114ea576000925050506114f1565b6001925050505b919050565b6000808260000151141561150d5760009050611562565b600080905060006115218460200151611567565b84602001510190506000846000015185602001510190505b8082101561155b5761154a826115f0565b820191508280600101935050611539565b8293505050505b919050565b600080825160001a9050608060ff168110156115875760009150506115eb565b60b860ff168110806115ac575060c060ff1681101580156115ab575060f860ff1681105b5b156115bb5760019150506115eb565b60c060ff168110156115db5760018060b80360ff168203019150506115eb565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff16811015611611576001915061169e565b60b860ff1681101561162e576001608060ff16820301915061169d565b60c060ff1681101561165e5760b78103600185019450806020036101000a8551046001820181019350505061169c565b60f860ff1681101561167b57600160c060ff16820301915061169b565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b60008114156116b65761170a565b5b602060ff1681106116e65782518252602060ff1683019250602060ff1682019150602060ff16810390506116b7565b6000600182602060ff16036101000a03905080198451168184511681811785525050505b505050565b604051806040016040528060008152602001600081525090565b604051806040016040528060008152602001600081525090565b8154818355818111156117705760020281600202836000526020600020918201910161176f9190611775565b5b505050565b6117ad91905b808211156117a9576000808201600090556001820160006101000a81549060ff02191690555060020161177b565b5090565b9056fea265627a7a723158209019c704cf8a199f003a390a902db2323e1adac1a6e87371012f3319ba0b4c4b64736f6c634300050b0032" + }, + "0000000000000000000000000000000000001010": { + "balance": "0x204fce28085b549b31600000", + "code": "0x60806040526004361061019c5760003560e01c806377d32e94116100ec578063acd06cb31161008a578063e306f77911610064578063e306f77914610a7b578063e614d0d614610aa6578063f2fde38b14610ad1578063fc0c546a14610b225761019c565b8063acd06cb31461097a578063b789543c146109cd578063cc79f97b14610a505761019c565b80639025e64c116100c65780639025e64c146107c957806395d89b4114610859578063a9059cbb146108e9578063abceeba21461094f5761019c565b806377d32e94146106315780638da5cb5b146107435780638f32d59b1461079a5761019c565b806347e7ef24116101595780637019d41a116101335780637019d41a1461053357806370a082311461058a578063715018a6146105ef578063771282f6146106065761019c565b806347e7ef2414610410578063485cc9551461046b57806360f96a8f146104dc5761019c565b806306fdde03146101a15780631499c5921461023157806318160ddd1461028257806319d27d9c146102ad5780632e1a7d4d146103b1578063313ce567146103df575b600080fd5b3480156101ad57600080fd5b506101b6610b79565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101f65780820151818401526020810190506101db565b50505050905090810190601f1680156102235780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561023d57600080fd5b506102806004803603602081101561025457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610bb6565b005b34801561028e57600080fd5b50610297610c24565b6040518082815260200191505060405180910390f35b3480156102b957600080fd5b5061036f600480360360a08110156102d057600080fd5b81019080803590602001906401000000008111156102ed57600080fd5b8201836020820111156102ff57600080fd5b8035906020019184600183028401116401000000008311171561032157600080fd5b9091929391929390803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610c3a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103dd600480360360208110156103c757600080fd5b8101908080359060200190929190505050610e06565b005b3480156103eb57600080fd5b506103f4610f64565b604051808260ff1660ff16815260200191505060405180910390f35b34801561041c57600080fd5b506104696004803603604081101561043357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610f6d565b005b34801561047757600080fd5b506104da6004803603604081101561048e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611129565b005b3480156104e857600080fd5b506104f16111f8565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561053f57600080fd5b5061054861121e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561059657600080fd5b506105d9600480360360208110156105ad57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611244565b6040518082815260200191505060405180910390f35b3480156105fb57600080fd5b50610604611265565b005b34801561061257600080fd5b5061061b611335565b6040518082815260200191505060405180910390f35b34801561063d57600080fd5b506107016004803603604081101561065457600080fd5b81019080803590602001909291908035906020019064010000000081111561067b57600080fd5b82018360208201111561068d57600080fd5b803590602001918460018302840111640100000000831117156106af57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061133b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561074f57600080fd5b506107586114c0565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156107a657600080fd5b506107af6114e9565b604051808215151515815260200191505060405180910390f35b3480156107d557600080fd5b506107de611540565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561081e578082015181840152602081019050610803565b50505050905090810190601f16801561084b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561086557600080fd5b5061086e611579565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156108ae578082015181840152602081019050610893565b50505050905090810190601f1680156108db5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610935600480360360408110156108ff57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506115b6565b604051808215151515815260200191505060405180910390f35b34801561095b57600080fd5b506109646115dc565b6040518082815260200191505060405180910390f35b34801561098657600080fd5b506109b36004803603602081101561099d57600080fd5b8101908080359060200190929190505050611669565b604051808215151515815260200191505060405180910390f35b3480156109d957600080fd5b50610a3a600480360360808110156109f057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019092919080359060200190929190505050611689565b6040518082815260200191505060405180910390f35b348015610a5c57600080fd5b50610a656116a9565b6040518082815260200191505060405180910390f35b348015610a8757600080fd5b50610a906116af565b6040518082815260200191505060405180910390f35b348015610ab257600080fd5b50610abb6116b5565b6040518082815260200191505060405180910390f35b348015610add57600080fd5b50610b2060048036036020811015610af457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611742565b005b348015610b2e57600080fd5b50610b3761175f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60606040518060400160405280600b81526020017f4d6174696320546f6b656e000000000000000000000000000000000000000000815250905090565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f44697361626c656420666561747572650000000000000000000000000000000081525060200191505060405180910390fd5b6000601260ff16600a0a6402540be40002905090565b6000808511610c4857600080fd5b6000831480610c575750824311155b610cc9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5369676e6174757265206973206578706972656400000000000000000000000081525060200191505060405180910390fd5b6000610cd733878787611689565b9050600015156005600083815260200190815260200160002060009054906101000a900460ff16151514610d73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f536967206465616374697661746564000000000000000000000000000000000081525060200191505060405180910390fd5b60016005600083815260200190815260200160002060006101000a81548160ff021916908315150217905550610ded8189898080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061133b565b9150610dfa828488611785565b50509695505050505050565b60003390506000610e1682611244565b9050610e2d83600654611b4290919063ffffffff16565b600681905550600083118015610e435750828110155b8015610e4e57508234145b610ec0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f496e73756666696369656e7420616d6f756e740000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167febff2602b3f468259e1e99f613fed6691f3a6526effe6ef3e768ba7ae7a36c4f8584610f3c87611244565b60405180848152602001838152602001828152602001935050505060405180910390a3505050565b60006012905090565b610f756114e9565b610f7e57600080fd5b600081118015610fbb5750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b611010576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611e6e6023913960400191505060405180910390fd5b600061101b83611244565b905060008390508073ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f19350505050158015611068573d6000803e3d6000fd5b5061107e83600654611b6290919063ffffffff16565b6006819055508373ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f4e2ca0515ed1aef1395f66b5303bb5d6f1bf9d61a353fa53f73f8ac9973fa9f6858561110089611244565b60405180848152602001838152602001828152602001935050505060405180910390a350505050565b600760009054906101000a900460ff161561118f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611e4b6023913960400191505060405180910390fd5b6001600760006101000a81548160ff02191690831515021790555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506111f482611b81565b5050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b61126d6114e9565b61127657600080fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60065481565b600080600080604185511461135657600093505050506114ba565b602085015192506040850151915060ff6041860151169050601b8160ff16101561138157601b810190505b601b8160ff16141580156113995750601c8160ff1614155b156113aa57600093505050506114ba565b60018682858560405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015611407573d6000803e3d6000fd5b505050602060405103519350600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156114b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4572726f7220696e2065637265636f766572000000000000000000000000000081525060200191505060405180910390fd5b5050505b92915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b6040518060400160405280600281526020017f3a9900000000000000000000000000000000000000000000000000000000000081525081565b60606040518060400160405280600581526020017f4d41544943000000000000000000000000000000000000000000000000000000815250905090565b60008134146115c857600090506115d6565b6115d3338484611785565b90505b92915050565b6040518060800160405280605b8152602001611e91605b91396040516020018082805190602001908083835b6020831061162b5780518252602082019150602081019050602083039250611608565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b60056020528060005260406000206000915054906101000a900460ff1681565b600061169f61169a86868686611c79565b611d4f565b9050949350505050565b613a9981565b60015481565b604051806080016040528060498152602001611eec604991396040516020018082805190602001908083835b6020831061170457805182526020820191506020810190506020830392506116e1565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b61174a6114e9565b61175357600080fd5b61175c81611b81565b50565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000803073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561180557600080fd5b505afa158015611819573d6000803e3d6000fd5b505050506040513d602081101561182f57600080fd5b8101908080519060200190929190505050905060003073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156118c157600080fd5b505afa1580156118d5573d6000803e3d6000fd5b505050506040513d60208110156118eb57600080fd5b81019080805190602001909291905050509050611909868686611d99565b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fe6497e3ee548a3372136af2fcb0696db31fc6cf20260707645068bd3fe97f3c48786863073ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611a1157600080fd5b505afa158015611a25573d6000803e3d6000fd5b505050506040513d6020811015611a3b57600080fd5b81019080805190602001909291905050503073ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611ac957600080fd5b505afa158015611add573d6000803e3d6000fd5b505050506040513d6020811015611af357600080fd5b8101908080519060200190929190505050604051808681526020018581526020018481526020018381526020018281526020019550505050505060405180910390a46001925050509392505050565b600082821115611b5157600080fd5b600082840390508091505092915050565b600080828401905083811015611b7757600080fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611bbb57600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000806040518060800160405280605b8152602001611e91605b91396040516020018082805190602001908083835b60208310611ccb5780518252602082019150602081019050602083039250611ca8565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120905060405181815273ffffffffffffffffffffffffffffffffffffffff8716602082015285604082015284606082015283608082015260a0812092505081915050949350505050565b60008060015490506040517f190100000000000000000000000000000000000000000000000000000000000081528160028201528360228201526042812092505081915050919050565b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611ddf573d6000803e3d6000fd5b508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a350505056fe54686520636f6e747261637420697320616c726561647920696e697469616c697a6564496e73756666696369656e7420616d6f756e74206f7220696e76616c69642075736572546f6b656e5472616e736665724f726465722861646472657373207370656e6465722c75696e7432353620746f6b656e49644f72416d6f756e742c6279746573333220646174612c75696e743235362065787069726174696f6e29454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320636f6e747261637429a265627a7a72315820f61fab49705fc0473e56e179e67d714e15b540d31ecea57818c062e41902d06c64736f6c634300050b0032" + }, + "6c468CF8c9879006E22EC4029696E005C2319C9D": { + "balance": "0x3635c9adc5dea00000" + } + }, + "number": "0x0", + "gasUsed": "0x0", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" +} diff --git a/core/tx_pool.go b/core/tx_pool.go index 39d66b5286eb..02011586c344 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -120,7 +120,7 @@ const ( // 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 + IsValidatorAction(chain consensus.ChainReader, from common.Address, tx *types.Transaction) bool } // blockChain provides the state of blockchain and current gas limit to do @@ -537,7 +537,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().(bor).IsValidatorAction(pool.chain.(consensus.ChainReader), from, tx) && pool.gasPrice.Cmp(tx.GasPrice()) > 0 { return ErrUnderpriced } From f7e58d6030a1010548fd4c1640084f6f8d92970b Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Thu, 5 Mar 2020 11:35:43 +0530 Subject: [PATCH 04/12] Test for IsValidatorAction --- README.md | 5 ++ consensus/bor/bor.go | 30 +++++++-- consensus/bor_test/bor_test.go | 114 +++++++++++++++++++------------- consensus/bor_test/genesis.json | 8 +-- 4 files changed, 99 insertions(+), 58 deletions(-) diff --git a/README.md b/README.md index 3ee31b5d3fd8..cb7aff2a22c9 100644 --- a/README.md +++ b/README.md @@ -163,6 +163,11 @@ Ethereum nodes with exposed APIs! Further, all browser tabs can access locally running web servers, so malicious web pages could try to subvert locally available APIs!** +### Tests +``` +go test github.com/maticnetwork/bor/consensus/bor_test +``` + ## License The bor library (i.e. all code outside of the `cmd` directory) is licensed under the diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 5ff495cc9aaa..cda2840144bb 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -40,8 +40,10 @@ 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 ( + 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"}]` + 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 @@ -1225,16 +1227,30 @@ func (c *Bor) IsValidatorAction(chain consensus.ChainReader, from common.Address log.Error("Failed fetching snapshot", err) } - _IsValidatorAction := false + isValidator := false for _, validator := range snap.ValidatorSet.Validators { if bytes.Compare(validator.Address.Bytes(), from.Bytes()) == 0 { - _IsValidatorAction = true + isValidator = true break } } - // @todo only either of proposeState and proposeSpan should pass this check - fmt.Println("tx.Data", tx.Data()) - return _IsValidatorAction + 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") + 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") + fmt.Println(bytes.Compare(proposeStateSig, tx.Data()[:4]) == 0, tx.To().String(), stateReceiverContract) + return bytes.Compare(proposeStateSig, tx.Data()[:4]) == 0 && + tx.To().String() == stateReceiverContract } // diff --git a/consensus/bor_test/bor_test.go b/consensus/bor_test/bor_test.go index 1750e4ac3b60..80163bc91eca 100644 --- a/consensus/bor_test/bor_test.go +++ b/consensus/bor_test/bor_test.go @@ -1,22 +1,24 @@ package bor_test import ( + "encoding/hex" "encoding/json" - "fmt" "io/ioutil" "math/big" "testing" + "github.com/stretchr/testify/assert" + + "github.com/maticnetwork/bor/common" "github.com/maticnetwork/bor/consensus/bor" "github.com/maticnetwork/bor/core" "github.com/maticnetwork/bor/core/rawdb" "github.com/maticnetwork/bor/core/types" - "github.com/maticnetwork/bor/core/vm" "github.com/maticnetwork/bor/crypto" "github.com/maticnetwork/bor/eth" - "github.com/maticnetwork/bor/internal/ethapi" - // "github.com/maticnetwork/bor/node" - // "github.com/maticnetwork/bor/params" + + "github.com/maticnetwork/bor/ethdb" + "github.com/maticnetwork/bor/node" ) func TestIsValidatorAction(t *testing.T) { @@ -24,59 +26,77 @@ func TestIsValidatorAction(t *testing.T) { db = rawdb.NewMemoryDatabase() key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") addr = crypto.PubkeyToAddress(key.PublicKey) - // signer = new(types.HomesteadSigner) ) - data, err := ioutil.ReadFile("genesis.json") + ethereum := buildEthereumInstance(t, db) + chain := ethereum.BlockChain() + engine := ethereum.Engine() + bor := engine.(*bor.Bor) + + // proposeState + data, _ := hex.DecodeString("ede01f170000000000000000000000000000000000000000000000000000000000000000") + tx := types.NewTransaction( + 0, + common.HexToAddress(chain.Config().Bor.StateReceiverContract), + big.NewInt(0), 0, big.NewInt(0), + data, + ) + assert.True(t, bor.IsValidatorAction(chain, addr, tx)) + + // proposeSpan + data, _ = hex.DecodeString("4b0e4d17") + tx = types.NewTransaction( + 0, + common.HexToAddress(chain.Config().Bor.ValidatorContract), + big.NewInt(0), 0, big.NewInt(0), + data, + ) + assert.True(t, bor.IsValidatorAction(chain, addr, tx)) +} + +func buildEthereumInstance(t *testing.T, db ethdb.Database) *eth.Ethereum { + genesisData, err := ioutil.ReadFile("genesis.json") if err != nil { t.Fatalf("%s", err) } - config := eth.Config - Genesis: &core.Genesis{}, - } - // var genesis core.Genesis - if err := json.Unmarshal(data, config.Genesis); err != nil { + gen := &core.Genesis{} + if err := json.Unmarshal(genesisData, gen); err != nil { t.Fatalf("%s", err) } - // fmt.Println(genesis) - chainConfig, _, err := core.SetupGenesisBlock(db, config.Genesis) - fmt.Printf("Chain config: %v\n", chainConfig) + // chainConfig, _, err := core.SetupGenesisBlock(db, gen) + ethConf := ð.Config{ + Genesis: gen, + } + ethConf.Genesis.MustCommit(db) - // copy(genspec.ExtraData[extraVanity:], addr[:]) - config.Genesis.MustCommit(db) + // Create a temporary storage for the node keys and initialize it + workspace, err := ioutil.TempDir("", "console-tester-") + if err != nil { + t.Fatalf("failed to create temporary keystore: %v", err) + } - _eth := ð.Ethereum{ - // config: config, - // chainDb: chainDb, - // eventMux: ctx.EventMux, - // accountManager: ctx.AccountManager, - // engine: nil, - // shutdownChan: make(chan bool), - // networkID: config.NetworkId, - // gasPrice: config.Miner.GasPrice, - // etherbase: config.Miner.Etherbase, - // bloomRequests: make(chan chan *bloombits.Retrieval), - // bloomIndexer: NewBloomIndexer(chainDb, params.BloomBitsBlocks, params.BloomConfirms), + // Create a networkless protocol stack and start an Ethereum service within + stack, err := node.New(&node.Config{DataDir: workspace, UseLightweightKDF: true, Name: "console-tester"}) + if err != nil { + t.Fatalf("failed to create node: %v", err) + } + err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { + s, err := eth.New(ctx, ethConf) + return s, err + }) + if err != nil { + t.Fatalf("failed to register Ethereum protocol: %v", err) } - _eth.APIBackend = ð.EthAPIBackend{false, _eth, nil} - ethAPI := ethapi.NewPublicBlockChainAPI(_eth.APIBackend) - // ctx := &node.ServiceContext{ - // config: &node.Config{}, - // // services: make(map[reflect.Type]Service), - // // EventMux: n.eventmux, - // // AccountManager: n.accman, - // } - engine := bor.New(chainConfig, db, ðapi.PublicBlockChainAPI{}) - chain, err := core.NewBlockChain(db, nil, chainConfig, engine, vm.Config{}, nil) + // Start the node and assemble the JavaScript console around it + if err = stack.Start(); err != nil { + t.Fatalf("failed to start test stack: %v", err) + } + _, err = stack.Attach() if err != nil { - t.Fatalf("%s", err) + t.Fatalf("failed to attach to node: %v", err) } - tx := types.NewTransaction( - 0, - addr, // to - Just a place holder - big.NewInt(0), 0 /* fix gas limit */, big.NewInt(0), - nil, // data - ) - engine.IsValidatorAction(chain, addr, tx) + var ethereum *eth.Ethereum + stack.Service(ðereum) + return ethereum } diff --git a/consensus/bor_test/genesis.json b/consensus/bor_test/genesis.json index 3adbd205a73f..84a293ff05a7 100644 --- a/consensus/bor_test/genesis.json +++ b/consensus/bor_test/genesis.json @@ -27,17 +27,17 @@ "alloc": { "0000000000000000000000000000000000001000": { "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b50600436106102115760003560e01c806365b3a1e211610125578063b2472431116100ad578063d0504f891161007c578063d0504f89146106af578063d5b844eb146106cb578063dcf2793a146106e9578063e3b7c9241461071b578063f59cf5651461073957610211565b8063b247243114610612578063b71d7a6914610630578063b7ab4db514610660578063c1b3c9191461067f57610211565b806370ba5707116100f457806370ba57071461055657806398ab2b62146105865780639d11b807146105a4578063ae756451146105d4578063af26aa96146105f257610211565b806365b3a1e2146104c957806366332354146104e8578063687a9bd61461050657806369c49fac1461053857610211565b806335ddfeea116101a85780634b0e4d17116101775780634b0e4d17146104215780634dbc959f1461042b57806355614fcc14610449578063582a8d081461047957806360c8614d146104a957610211565b806335ddfeea1461037357806343ee8213146103a357806344c15cb1146103c157806344d6528f146103f157610211565b806323f2a73f116101e457806323f2a73f146102c55780632de3a180146102f55780632eddf352146103255780633434735f1461035557610211565b8063047a6c5b146102165780630c35b1cb146102485780631270b5741461027957806323c2a2b4146102a9575b600080fd5b610230600480360361022b9190810190612e7e565b61076b565b60405161023f93929190613903565b60405180910390f35b610262600480360361025d9190810190612e7e565b6107c2565b6040516102709291906136c4565b60405180910390f35b610293600480360361028e9190810190612ea7565b61099e565b6040516102a091906136fb565b60405180910390f35b6102c360048036036102be9190810190612f86565b610af6565b005b6102df60048036036102da9190810190612ea7565b611177565b6040516102ec91906136fb565b60405180910390f35b61030f600480360361030a9190810190612d18565b6112cf565b60405161031c9190613716565b60405180910390f35b61033f600480360361033a9190810190612e7e565b611350565b60405161034c91906138b1565b60405180910390f35b61035d611481565b60405161036a91906136a9565b60405180910390f35b61038d60048036036103889190810190612d54565b611499565b60405161039a91906136fb565b60405180910390f35b6103ab611564565b6040516103b89190613716565b60405180910390f35b6103db60048036036103d69190810190612ee3565b61157b565b6040516103e891906138b1565b60405180910390f35b61040b60048036036104069190810190612ea7565b611663565b6040516104189190613896565b60405180910390f35b6104296117cc565b005b610433611828565b60405161044091906138b1565b60405180910390f35b610463600480360361045e9190810190612c9d565b611838565b60405161047091906136fb565b60405180910390f35b610493600480360361048e9190810190612cc6565b611852565b6040516104a09190613716565b60405180910390f35b6104b16118d0565b6040516104c093929190613903565b60405180910390f35b6104d1611944565b6040516104df9291906136c4565b60405180910390f35b6104f0611a34565b6040516104fd91906138b1565b60405180910390f35b610520600480360361051b9190810190612f4a565b611a39565b60405161052f939291906138cc565b60405180910390f35b610540611a9d565b60405161054d91906136fb565b60405180910390f35b610570600480360361056b9190810190612c9d565b611ab4565b60405161057d91906136fb565b60405180910390f35b61058e611ace565b60405161059b9190613716565b60405180910390f35b6105be60048036036105b99190810190612e7e565b611ae5565b6040516105cb91906138b1565b60405180910390f35b6105dc611c16565b6040516105e99190613716565b60405180910390f35b6105fa611c2d565b60405161060993929190613903565b60405180910390f35b61061a611c8e565b60405161062791906138b1565b60405180910390f35b61064a60048036036106459190810190612e7e565b611c94565b60405161065791906138b1565b60405180910390f35b610668611d94565b6040516106769291906136c4565b60405180910390f35b61069960048036036106949190810190612e7e565b611da8565b6040516106a691906138b1565b60405180910390f35b6106c960048036036106c49190810190612dbb565b611dc9565b005b6106d361201f565b6040516106e0919061393a565b60405180910390f35b61070360048036036106fe9190810190612f4a565b612024565b604051610712939291906138cc565b60405180910390f35b610723612088565b60405161073091906138b1565b60405180910390f35b610753600480360361074e9190810190612e7e565b61209a565b60405161076293929190613903565b60405180910390f35b60008060006004600085815260200190815260200160002060000154600460008681526020019081526020016000206001015460046000878152602001908152602001600020600201549250925092509193909250565b60608060ff83116107de576107d5611944565b91509150610999565b60006107e984611c94565b9050606060036000838152602001908152602001600020805490506040519080825280602002602001820160405280156108325781602001602082028038833980820191505090505b5090506060600360008481526020019081526020016000208054905060405190808252806020026020018201604052801561087c5781602001602082028038833980820191505090505b50905060008090505b600360008581526020019081526020016000208054905081101561098e576003600085815260200190815260200160002081815481106108c157fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168382815181106108ff57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060036000858152602001908152602001600020818154811061095757fe5b90600052602060002090600302016001015482828151811061097557fe5b6020026020010181815250508080600101915050610885565b508181945094505050505b915091565b6000606060036000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015610a71578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050815260200190600101906109d5565b50505050905060008090505b8151811015610ae9578373ffffffffffffffffffffffffffffffffffffffff16828281518110610aa957fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff161415610adc57600192505050610af0565b8080600101915050610a7d565b5060009150505b92915050565b73fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b4257600080fd5b6000610b4c611828565b90506000811415610b6057610b5f6120c4565b5b610b746001826123f090919063ffffffff16565b8814610bb5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bac906137b6565b60405180910390fd5b868611610bf7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bee90613816565b60405180910390fd5b6000805460018989030181610c0857fe5b0614610c49576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c40906137f6565b60405180910390fd5b8660046000838152602001908152602001600020600101541115610ca2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c9990613776565b60405180910390fd5b6000600460008a81526020019081526020016000206000015414610cfb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cf2906137d6565b60405180910390fd5b604051806060016040528089815260200188815260200187815250600460008a815260200190815260200160002060008201518160000155602082015181600101556040820151816002015590505060058890806001815401808255809150509060018203906000526020600020016000909192909190915055506000600260008a815260200190815260200160002081610d969190612a97565b506000600360008a815260200190815260200160002081610db79190612a97565b506060610e0f610e0a87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061240f565b61243d565b905060008090505b8151811015610f83576060610e3e838381518110610e3157fe5b602002602001015161243d565b9050600260008c81526020019081526020016000208054809190600101610e659190612a97565b506040518060600160405280610e8e83600081518110610e8157fe5b602002602001015161251a565b8152602001610eb083600181518110610ea357fe5b602002602001015161251a565b8152602001610ed283600281518110610ec557fe5b602002602001015161258b565b73ffffffffffffffffffffffffffffffffffffffff16815250600260008d81526020019081526020016000208381548110610f0957fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050508080600101915050610e17565b506060610fdb610fd686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061240f565b61243d565b905060008090505b815181101561114f57606061100a838381518110610ffd57fe5b602002602001015161243d565b9050600360008d815260200190815260200160002080548091906001016110319190612a97565b50604051806060016040528061105a8360008151811061104d57fe5b602002602001015161251a565b815260200161107c8360018151811061106f57fe5b602002602001015161251a565b815260200161109e8360028151811061109157fe5b602002602001015161258b565b73ffffffffffffffffffffffffffffffffffffffff16815250600360008e815260200190815260200160002083815481106110d557fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050508080600101915050610fe3565b506000600160006101000a81548160ff02191690831515021790555050505050505050505050565b6000606060026000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561124a578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050815260200190600101906111ae565b50505050905060008090505b81518110156112c2578373ffffffffffffffffffffffffffffffffffffffff1682828151811061128257fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff1614156112b5576001925050506112c9565b8080600101915050611256565b5060009150505b92915050565b60006002600160f81b84846040516020016112ec93929190613616565b6040516020818303038152906040526040516113089190613653565b602060405180830381855afa158015611325573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506113489190810190612cef565b905092915050565b6000606060026000848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015611423578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611387565b505050509050600080905060008090505b82518110156114765761146783828151811061144c57fe5b602002602001015160200151836123f090919063ffffffff16565b91508080600101915050611434565b508092505050919050565b73fffffffffffffffffffffffffffffffffffffffe81565b60008060008085905060006021808751816114b057fe5b0402905060008111156114c9576114c687611852565b91505b6000602190505b818111611553576000600182038801519050818801519550806000602081106114f557fe5b1a60f81b9450600060f81b857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561153a5761153386856112cf565b9350611547565b61154484876112cf565b93505b506021810190506114d0565b508782149450505050509392505050565b6040516115709061367f565b604051809103902081565b60008060009050600080905060008090505b84518167ffffffffffffffff1610156116565760606115b8868367ffffffffffffffff1660416125ae565b905060006115cf828961263a90919063ffffffff16565b90506115d9612ac9565b6115e38a83611663565b90506115ef8a83611177565b801561162657508473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16115b15611648578194506116458160200151876123f090919063ffffffff16565b95505b50505060418101905061158d565b5081925050509392505050565b61166b612ac9565b606060026000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561173c578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050815260200190600101906116a0565b50505050905060008090505b81518110156117c4578373ffffffffffffffffffffffffffffffffffffffff1682828151811061177457fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff1614156117b7578181815181106117a857fe5b602002602001015192506117c4565b8080600101915050611748565b505092915050565b60006117d6611828565b90506117e28133611177565b6117eb57600080fd5b60001515600160009054906101000a900460ff1615151461180b57600080fd5b60018060006101000a81548160ff02191690831515021790555050565b600061183343611c94565b905090565b600061184b611845611828565b83611177565b9050919050565b60006002600060f81b8360405160200161186d9291906135ea565b6040516020818303038152906040526040516118899190613653565b602060405180830381855afa1580156118a6573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506118c99190810190612cef565b9050919050565b6000806000806118f160016118e3611828565b6123f090919063ffffffff16565b905060046000828152602001908152602001600020600001546004600083815260200190815260200160002060010154600460008481526020019081526020016000206002015493509350935050909192565b606080606060016040519080825280602002602001820160405280156119795781602001602082028038833980820191505090505b509050736c468cf8c9879006e22ec4029696e005c2319c9d8160008151811061199e57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060606001604051908082528060200260200182016040528015611a0a5781602001602082028038833980820191505090505b509050600a81600081518110611a1c57fe5b60200260200101818152505081819350935050509091565b60ff81565b60036020528160005260406000208181548110611a5257fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b6000600160009054906101000a900460ff16905090565b6000611ac7611ac1611828565b8361099e565b9050919050565b604051611ada9061366a565b604051809103902081565b6000606060036000848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015611bb8578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611b1c565b505050509050600080905060008090505b8251811015611c0b57611bfc838281518110611be157fe5b602002602001015160200151836123f090919063ffffffff16565b91508080600101915050611bc9565b508092505050919050565b604051611c2290613694565b604051809103902081565b600080600080611c3b611828565b905060046000828152602001908152602001600020600001546004600083815260200190815260200160002060010154600460008481526020019081526020016000206002015493509350935050909192565b60005481565b60008060058054905090505b6000811115611d5457611cb1612b00565b6004600060056001850381548110611cc557fe5b906000526020600020015481526020019081526020016000206040518060600160405290816000820154815260200160018201548152602001600282015481525050905083816020015111158015611d2257506000816040015114155b8015611d32575080604001518411155b15611d4557806000015192505050611d8f565b50808060019003915050611ca0565b5060006005805490501115611d8a57600560016005805490500381548110611d7857fe5b90600052602060002001549050611d8f565b600090505b919050565b606080611da0436107c2565b915091509091565b60058181548110611db557fe5b906000526020600020016000915090505481565b6060611ddc611dd78661240f565b61243d565b9050604051611dea9061367f565b6040518091039020611e0f82600081518110611e0257fe5b6020026020010151612744565b8051906020012014611e56576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e4d90613796565b60405180910390fd5b600260ff16611e7882600181518110611e6b57fe5b602002602001015161251a565b14611eb8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eaf90613836565b60405180910390fd5b611f31611ed882600481518110611ecb57fe5b602002602001015161251a565b60001b600285604051611eeb9190613653565b602060405180830381855afa158015611f08573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250611f2b9190810190612cef565b84611499565b611f70576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6790613856565b60405180910390fd5b6000611f7a611828565b90506000611f908288805190602001208861157b565b9050611fd46001611fc66003611fb86002611faa88611350565b6127d090919063ffffffff16565b61280a90919063ffffffff16565b6123f090919063ffffffff16565b811015612016576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161200d90613876565b60405180910390fd5b50505050505050565b600281565b6002602052816000526040600020818154811061203d57fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b60006040438161209457fe5b04905090565b60046020528060005260406000206000915090508060000154908060010154908060020154905083565b60406000819055506060806120d7611944565b8092508193505050600080905060405180606001604052808281526020016000815260200160ff815250600460008381526020019081526020016000206000820151816000015560208201518160010155604082015181600201559050506005819080600181540180825580915050906001820390600052602060002001600090919290919091505550600060026000838152602001908152602001600020816121819190612a97565b50600060036000838152602001908152602001600020816121a29190612a97565b5060008090505b83518110156122c6576002600083815260200190815260200160002080548091906001016121d79190612a97565b5060405180606001604052808281526020018483815181106121f557fe5b6020026020010151815260200185838151811061220e57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681525060026000848152602001908152602001600020828154811061224d57fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505080806001019150506121a9565b5060008090505b83518110156123ea576003600083815260200190815260200160002080548091906001016122fb9190612a97565b50604051806060016040528082815260200184838151811061231957fe5b6020026020010151815260200185838151811061233257fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681525060036000848152602001908152602001600020828154811061237157fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505080806001019150506122cd565b50505050565b60008082840190508381101561240557600080fd5b8091505092915050565b612417612b21565b600060208301905060405180604001604052808451815260200182815250915050919050565b606061244882612830565b61245157600080fd5b600061245c8361287e565b905060608160405190808252806020026020018201604052801561249a57816020015b612487612b3b565b81526020019060019003908161247f5790505b50905060006124ac85602001516128ef565b8560200151019050600080600090505b8481101561250d576124cd83612978565b91506040518060400160405280838152602001848152508482815181106124f057fe5b6020026020010181905250818301925080806001019150506124bc565b5082945050505050919050565b600080826000015111801561253457506021826000015111155b61253d57600080fd5b600061254c83602001516128ef565b9050600081846000015103905060008083866020015101905080519150602083101561257f57826020036101000a820491505b81945050505050919050565b6000601582600001511461259e57600080fd5b6125a78261251a565b9050919050565b6060818301845110156125c057600080fd5b60608215600081146125dd5760405191506020820160405261262e565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561261b57805183526020830192506020810190506125fe565b50868552601f19601f8301166040525050505b50809150509392505050565b6000806000806041855114612655576000935050505061273e565b602085015192506040850151915060ff6041860151169050601b8160ff16101561268057601b810190505b601b8160ff16141580156126985750601c8160ff1614155b156126a9576000935050505061273e565b6000600187838686604051600081526020016040526040516126ce9493929190613731565b6020604051602081039080840390855afa1580156126f0573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561273657600080fd5b809450505050505b92915050565b6060600082600001511161275757600080fd5b600061276683602001516128ef565b905060008184600001510390506060816040519080825280601f01601f1916602001820160405280156127a85781602001600182028038833980820191505090505b50905060008160200190506127c4848760200151018285612a30565b81945050505050919050565b6000808314156127e35760009050612804565b60008284029050828482816127f457fe5b04146127ff57600080fd5b809150505b92915050565b600080821161281857600080fd5b600082848161282357fe5b0490508091505092915050565b600080826000015114156128475760009050612879565b60008083602001519050805160001a915060c060ff168260ff16101561287257600092505050612879565b6001925050505b919050565b6000808260000151141561289557600090506128ea565b600080905060006128a984602001516128ef565b84602001510190506000846000015185602001510190505b808210156128e3576128d282612978565b8201915082806001019350506128c1565b8293505050505b919050565b600080825160001a9050608060ff1681101561290f576000915050612973565b60b860ff16811080612934575060c060ff168110158015612933575060f860ff1681105b5b15612943576001915050612973565b60c060ff168110156129635760018060b80360ff16820301915050612973565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff168110156129995760019150612a26565b60b860ff168110156129b6576001608060ff168203019150612a25565b60c060ff168110156129e65760b78103600185019450806020036101000a85510460018201810193505050612a24565b60f860ff16811015612a0357600160c060ff168203019150612a23565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b6000811415612a3e57612a92565b5b602060ff168110612a6e5782518252602060ff1683019250602060ff1682019150602060ff1681039050612a3f565b6000600182602060ff16036101000a03905080198451168184511681811785525050505b505050565b815481835581811115612ac457600302816003028360005260206000209182019101612ac39190612b55565b5b505050565b60405180606001604052806000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b60405180606001604052806000815260200160008152602001600081525090565b604051806040016040528060008152602001600081525090565b604051806040016040528060008152602001600081525090565b612ba891905b80821115612ba45760008082016000905560018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550600301612b5b565b5090565b90565b600081359050612bba81613b33565b92915050565b600081359050612bcf81613b4a565b92915050565b600081519050612be481613b4a565b92915050565b60008083601f840112612bfc57600080fd5b8235905067ffffffffffffffff811115612c1557600080fd5b602083019150836001820283011115612c2d57600080fd5b9250929050565b600082601f830112612c4557600080fd5b8135612c58612c5382613982565b613955565b91508082526020830160208301858383011115612c7457600080fd5b612c7f838284613add565b50505092915050565b600081359050612c9781613b61565b92915050565b600060208284031215612caf57600080fd5b6000612cbd84828501612bab565b91505092915050565b600060208284031215612cd857600080fd5b6000612ce684828501612bc0565b91505092915050565b600060208284031215612d0157600080fd5b6000612d0f84828501612bd5565b91505092915050565b60008060408385031215612d2b57600080fd5b6000612d3985828601612bc0565b9250506020612d4a85828601612bc0565b9150509250929050565b600080600060608486031215612d6957600080fd5b6000612d7786828701612bc0565b9350506020612d8886828701612bc0565b925050604084013567ffffffffffffffff811115612da557600080fd5b612db186828701612c34565b9150509250925092565b60008060008060808587031215612dd157600080fd5b600085013567ffffffffffffffff811115612deb57600080fd5b612df787828801612c34565b945050602085013567ffffffffffffffff811115612e1457600080fd5b612e2087828801612c34565b935050604085013567ffffffffffffffff811115612e3d57600080fd5b612e4987828801612c34565b925050606085013567ffffffffffffffff811115612e6657600080fd5b612e7287828801612c34565b91505092959194509250565b600060208284031215612e9057600080fd5b6000612e9e84828501612c88565b91505092915050565b60008060408385031215612eba57600080fd5b6000612ec885828601612c88565b9250506020612ed985828601612bab565b9150509250929050565b600080600060608486031215612ef857600080fd5b6000612f0686828701612c88565b9350506020612f1786828701612bc0565b925050604084013567ffffffffffffffff811115612f3457600080fd5b612f4086828701612c34565b9150509250925092565b60008060408385031215612f5d57600080fd5b6000612f6b85828601612c88565b9250506020612f7c85828601612c88565b9150509250929050565b600080600080600080600060a0888a031215612fa157600080fd5b6000612faf8a828b01612c88565b9750506020612fc08a828b01612c88565b9650506040612fd18a828b01612c88565b955050606088013567ffffffffffffffff811115612fee57600080fd5b612ffa8a828b01612bea565b9450945050608088013567ffffffffffffffff81111561301957600080fd5b6130258a828b01612bea565b925092505092959891949750929550565b60006130428383613066565b60208301905092915050565b600061305a83836135bd565b60208301905092915050565b61306f81613a52565b82525050565b61307e81613a52565b82525050565b600061308f826139ce565b6130998185613a09565b93506130a4836139ae565b8060005b838110156130d55781516130bc8882613036565b97506130c7836139ef565b9250506001810190506130a8565b5085935050505092915050565b60006130ed826139d9565b6130f78185613a1a565b9350613102836139be565b8060005b8381101561313357815161311a888261304e565b9750613125836139fc565b925050600181019050613106565b5085935050505092915050565b61314981613a64565b82525050565b61316061315b82613a70565b613b1f565b82525050565b61316f81613a9c565b82525050565b61318661318182613a9c565b613b29565b82525050565b6000613197826139e4565b6131a18185613a2b565b93506131b1818560208601613aec565b80840191505092915050565b60006131ca600483613a47565b91507f766f7465000000000000000000000000000000000000000000000000000000006000830152600482019050919050565b600061320a602d83613a36565b91507f537461727420626c6f636b206d7573742062652067726561746572207468616e60008301527f2063757272656e74207370616e000000000000000000000000000000000000006020830152604082019050919050565b6000613270600f83613a47565b91507f6865696d64616c6c2d50357258776700000000000000000000000000000000006000830152600f82019050919050565b60006132b0601383613a36565b91507f436861696e20494420697320696e76616c6964000000000000000000000000006000830152602082019050919050565b60006132f0600f83613a36565b91507f496e76616c6964207370616e20696400000000000000000000000000000000006000830152602082019050919050565b6000613330601383613a36565b91507f5370616e20616c726561647920657869737473000000000000000000000000006000830152602082019050919050565b6000613370604583613a36565b91507f446966666572656e6365206265747765656e20737461727420616e6420656e6460008301527f20626c6f636b206d75737420626520696e206d756c7469706c6573206f66207360208301527f7072696e740000000000000000000000000000000000000000000000000000006040830152606082019050919050565b60006133fc602a83613a36565b91507f456e6420626c6f636b206d7573742062652067726561746572207468616e207360008301527f7461727420626c6f636b000000000000000000000000000000000000000000006020830152604082019050919050565b6000613462601483613a36565b91507f566f7465207479706520697320696e76616c69640000000000000000000000006000830152602082019050919050565b60006134a2601683613a36565b91507f5472616e73616374696f6e20697320696e76616c6964000000000000000000006000830152602082019050919050565b60006134e2600583613a47565b91507f31353030310000000000000000000000000000000000000000000000000000006000830152600582019050919050565b6000613522602483613a36565b91507f4e6f7420656e6f7567687420706f77657220746f206368616e6765207468652060008301527f7370616e000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60608201600082015161359160008501826135bd565b5060208201516135a460208501826135bd565b5060408201516135b76040850182613066565b50505050565b6135c681613ac6565b82525050565b6135d581613ac6565b82525050565b6135e481613ad0565b82525050565b60006135f6828561314f565b6001820191506136068284613175565b6020820191508190509392505050565b6000613622828661314f565b6001820191506136328285613175565b6020820191506136428284613175565b602082019150819050949350505050565b600061365f828461318c565b915081905092915050565b6000613675826131bd565b9150819050919050565b600061368a82613263565b9150819050919050565b600061369f826134d5565b9150819050919050565b60006020820190506136be6000830184613075565b92915050565b600060408201905081810360008301526136de8185613084565b905081810360208301526136f281846130e2565b90509392505050565b60006020820190506137106000830184613140565b92915050565b600060208201905061372b6000830184613166565b92915050565b60006080820190506137466000830187613166565b61375360208301866135db565b6137606040830185613166565b61376d6060830184613166565b95945050505050565b6000602082019050818103600083015261378f816131fd565b9050919050565b600060208201905081810360008301526137af816132a3565b9050919050565b600060208201905081810360008301526137cf816132e3565b9050919050565b600060208201905081810360008301526137ef81613323565b9050919050565b6000602082019050818103600083015261380f81613363565b9050919050565b6000602082019050818103600083015261382f816133ef565b9050919050565b6000602082019050818103600083015261384f81613455565b9050919050565b6000602082019050818103600083015261386f81613495565b9050919050565b6000602082019050818103600083015261388f81613515565b9050919050565b60006060820190506138ab600083018461357b565b92915050565b60006020820190506138c660008301846135cc565b92915050565b60006060820190506138e160008301866135cc565b6138ee60208301856135cc565b6138fb6040830184613075565b949350505050565b600060608201905061391860008301866135cc565b61392560208301856135cc565b61393260408301846135cc565b949350505050565b600060208201905061394f60008301846135db565b92915050565b6000604051905081810181811067ffffffffffffffff8211171561397857600080fd5b8060405250919050565b600067ffffffffffffffff82111561399957600080fd5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000613a5d82613aa6565b9050919050565b60008115159050919050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b82818337600083830152505050565b60005b83811015613b0a578082015181840152602081019050613aef565b83811115613b19576000848401525b50505050565b6000819050919050565b6000819050919050565b613b3c81613a52565b8114613b4757600080fd5b50565b613b5381613a9c565b8114613b5e57600080fd5b50565b613b6a81613ac6565b8114613b7557600080fd5b5056fea365627a7a72315820234efaeec44cd697e3b3da6f1185de12a990609aeccd9385ae0e67cf398056796c6578706572696d656e74616cf564736f6c634300050b0040" + "code": "0x608060405234801561001057600080fd5b50600436106102115760003560e01c806365b3a1e211610125578063b2472431116100ad578063d0504f891161007c578063d0504f89146106af578063d5b844eb146106cb578063dcf2793a146106e9578063e3b7c9241461071b578063f59cf5651461073957610211565b8063b247243114610612578063b71d7a6914610630578063b7ab4db514610660578063c1b3c9191461067f57610211565b806370ba5707116100f457806370ba57071461055657806398ab2b62146105865780639d11b807146105a4578063ae756451146105d4578063af26aa96146105f257610211565b806365b3a1e2146104c957806366332354146104e8578063687a9bd61461050657806369c49fac1461053857610211565b806335ddfeea116101a85780634b0e4d17116101775780634b0e4d17146104215780634dbc959f1461042b57806355614fcc14610449578063582a8d081461047957806360c8614d146104a957610211565b806335ddfeea1461037357806343ee8213146103a357806344c15cb1146103c157806344d6528f146103f157610211565b806323f2a73f116101e457806323f2a73f146102c55780632de3a180146102f55780632eddf352146103255780633434735f1461035557610211565b8063047a6c5b146102165780630c35b1cb146102485780631270b5741461027957806323c2a2b4146102a9575b600080fd5b610230600480360361022b9190810190612e7e565b61076b565b60405161023f93929190613903565b60405180910390f35b610262600480360361025d9190810190612e7e565b6107c2565b6040516102709291906136c4565b60405180910390f35b610293600480360361028e9190810190612ea7565b61099e565b6040516102a091906136fb565b60405180910390f35b6102c360048036036102be9190810190612f86565b610af6565b005b6102df60048036036102da9190810190612ea7565b611177565b6040516102ec91906136fb565b60405180910390f35b61030f600480360361030a9190810190612d18565b6112cf565b60405161031c9190613716565b60405180910390f35b61033f600480360361033a9190810190612e7e565b611350565b60405161034c91906138b1565b60405180910390f35b61035d611481565b60405161036a91906136a9565b60405180910390f35b61038d60048036036103889190810190612d54565b611499565b60405161039a91906136fb565b60405180910390f35b6103ab611564565b6040516103b89190613716565b60405180910390f35b6103db60048036036103d69190810190612ee3565b61157b565b6040516103e891906138b1565b60405180910390f35b61040b60048036036104069190810190612ea7565b611663565b6040516104189190613896565b60405180910390f35b6104296117cc565b005b610433611828565b60405161044091906138b1565b60405180910390f35b610463600480360361045e9190810190612c9d565b611838565b60405161047091906136fb565b60405180910390f35b610493600480360361048e9190810190612cc6565b611852565b6040516104a09190613716565b60405180910390f35b6104b16118d0565b6040516104c093929190613903565b60405180910390f35b6104d1611944565b6040516104df9291906136c4565b60405180910390f35b6104f0611a34565b6040516104fd91906138b1565b60405180910390f35b610520600480360361051b9190810190612f4a565b611a39565b60405161052f939291906138cc565b60405180910390f35b610540611a9d565b60405161054d91906136fb565b60405180910390f35b610570600480360361056b9190810190612c9d565b611ab4565b60405161057d91906136fb565b60405180910390f35b61058e611ace565b60405161059b9190613716565b60405180910390f35b6105be60048036036105b99190810190612e7e565b611ae5565b6040516105cb91906138b1565b60405180910390f35b6105dc611c16565b6040516105e99190613716565b60405180910390f35b6105fa611c2d565b60405161060993929190613903565b60405180910390f35b61061a611c8e565b60405161062791906138b1565b60405180910390f35b61064a60048036036106459190810190612e7e565b611c94565b60405161065791906138b1565b60405180910390f35b610668611d94565b6040516106769291906136c4565b60405180910390f35b61069960048036036106949190810190612e7e565b611da8565b6040516106a691906138b1565b60405180910390f35b6106c960048036036106c49190810190612dbb565b611dc9565b005b6106d361201f565b6040516106e0919061393a565b60405180910390f35b61070360048036036106fe9190810190612f4a565b612024565b604051610712939291906138cc565b60405180910390f35b610723612088565b60405161073091906138b1565b60405180910390f35b610753600480360361074e9190810190612e7e565b61209a565b60405161076293929190613903565b60405180910390f35b60008060006004600085815260200190815260200160002060000154600460008681526020019081526020016000206001015460046000878152602001908152602001600020600201549250925092509193909250565b60608060ff83116107de576107d5611944565b91509150610999565b60006107e984611c94565b9050606060036000838152602001908152602001600020805490506040519080825280602002602001820160405280156108325781602001602082028038833980820191505090505b5090506060600360008481526020019081526020016000208054905060405190808252806020026020018201604052801561087c5781602001602082028038833980820191505090505b50905060008090505b600360008581526020019081526020016000208054905081101561098e576003600085815260200190815260200160002081815481106108c157fe5b906000526020600020906003020160020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168382815181106108ff57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060036000858152602001908152602001600020818154811061095757fe5b90600052602060002090600302016001015482828151811061097557fe5b6020026020010181815250508080600101915050610885565b508181945094505050505b915091565b6000606060036000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015610a71578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050815260200190600101906109d5565b50505050905060008090505b8151811015610ae9578373ffffffffffffffffffffffffffffffffffffffff16828281518110610aa957fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff161415610adc57600192505050610af0565b8080600101915050610a7d565b5060009150505b92915050565b73fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b4257600080fd5b6000610b4c611828565b90506000811415610b6057610b5f6120c4565b5b610b746001826123f090919063ffffffff16565b8814610bb5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bac906137b6565b60405180910390fd5b868611610bf7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bee90613816565b60405180910390fd5b6000805460018989030181610c0857fe5b0614610c49576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c40906137f6565b60405180910390fd5b8660046000838152602001908152602001600020600101541115610ca2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c9990613776565b60405180910390fd5b6000600460008a81526020019081526020016000206000015414610cfb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cf2906137d6565b60405180910390fd5b604051806060016040528089815260200188815260200187815250600460008a815260200190815260200160002060008201518160000155602082015181600101556040820151816002015590505060058890806001815401808255809150509060018203906000526020600020016000909192909190915055506000600260008a815260200190815260200160002081610d969190612a97565b506000600360008a815260200190815260200160002081610db79190612a97565b506060610e0f610e0a87878080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061240f565b61243d565b905060008090505b8151811015610f83576060610e3e838381518110610e3157fe5b602002602001015161243d565b9050600260008c81526020019081526020016000208054809190600101610e659190612a97565b506040518060600160405280610e8e83600081518110610e8157fe5b602002602001015161251a565b8152602001610eb083600181518110610ea357fe5b602002602001015161251a565b8152602001610ed283600281518110610ec557fe5b602002602001015161258b565b73ffffffffffffffffffffffffffffffffffffffff16815250600260008d81526020019081526020016000208381548110610f0957fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050508080600101915050610e17565b506060610fdb610fd686868080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061240f565b61243d565b905060008090505b815181101561114f57606061100a838381518110610ffd57fe5b602002602001015161243d565b9050600360008d815260200190815260200160002080548091906001016110319190612a97565b50604051806060016040528061105a8360008151811061104d57fe5b602002602001015161251a565b815260200161107c8360018151811061106f57fe5b602002602001015161251a565b815260200161109e8360028151811061109157fe5b602002602001015161258b565b73ffffffffffffffffffffffffffffffffffffffff16815250600360008e815260200190815260200160002083815481106110d557fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550905050508080600101915050610fe3565b506000600160006101000a81548160ff02191690831515021790555050505050505050505050565b6000606060026000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561124a578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050815260200190600101906111ae565b50505050905060008090505b81518110156112c2578373ffffffffffffffffffffffffffffffffffffffff1682828151811061128257fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff1614156112b5576001925050506112c9565b8080600101915050611256565b5060009150505b92915050565b60006002600160f81b84846040516020016112ec93929190613616565b6040516020818303038152906040526040516113089190613653565b602060405180830381855afa158015611325573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506113489190810190612cef565b905092915050565b6000606060026000848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015611423578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611387565b505050509050600080905060008090505b82518110156114765761146783828151811061144c57fe5b602002602001015160200151836123f090919063ffffffff16565b91508080600101915050611434565b508092505050919050565b73fffffffffffffffffffffffffffffffffffffffe81565b60008060008085905060006021808751816114b057fe5b0402905060008111156114c9576114c687611852565b91505b6000602190505b818111611553576000600182038801519050818801519550806000602081106114f557fe5b1a60f81b9450600060f81b857effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141561153a5761153386856112cf565b9350611547565b61154484876112cf565b93505b506021810190506114d0565b508782149450505050509392505050565b6040516115709061367f565b604051809103902081565b60008060009050600080905060008090505b84518167ffffffffffffffff1610156116565760606115b8868367ffffffffffffffff1660416125ae565b905060006115cf828961263a90919063ffffffff16565b90506115d9612ac9565b6115e38a83611663565b90506115ef8a83611177565b801561162657508473ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16115b15611648578194506116458160200151876123f090919063ffffffff16565b95505b50505060418101905061158d565b5081925050509392505050565b61166b612ac9565b606060026000858152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b8282101561173c578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681525050815260200190600101906116a0565b50505050905060008090505b81518110156117c4578373ffffffffffffffffffffffffffffffffffffffff1682828151811061177457fe5b60200260200101516040015173ffffffffffffffffffffffffffffffffffffffff1614156117b7578181815181106117a857fe5b602002602001015192506117c4565b8080600101915050611748565b505092915050565b60006117d6611828565b90506117e28133611177565b6117eb57600080fd5b60001515600160009054906101000a900460ff1615151461180b57600080fd5b60018060006101000a81548160ff02191690831515021790555050565b600061183343611c94565b905090565b600061184b611845611828565b83611177565b9050919050565b60006002600060f81b8360405160200161186d9291906135ea565b6040516020818303038152906040526040516118899190613653565b602060405180830381855afa1580156118a6573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052506118c99190810190612cef565b9050919050565b6000806000806118f160016118e3611828565b6123f090919063ffffffff16565b905060046000828152602001908152602001600020600001546004600083815260200190815260200160002060010154600460008481526020019081526020016000206002015493509350935050909192565b606080606060016040519080825280602002602001820160405280156119795781602001602082028038833980820191505090505b5090507371562b71999873db5b286df957af199ec94617f78160008151811061199e57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060606001604051908082528060200260200182016040528015611a0a5781602001602082028038833980820191505090505b509050600a81600081518110611a1c57fe5b60200260200101818152505081819350935050509091565b60ff81565b60036020528160005260406000208181548110611a5257fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b6000600160009054906101000a900460ff16905090565b6000611ac7611ac1611828565b8361099e565b9050919050565b604051611ada9061366a565b604051809103902081565b6000606060036000848152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b82821015611bb8578382906000526020600020906003020160405180606001604052908160008201548152602001600182015481526020016002820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152505081526020019060010190611b1c565b505050509050600080905060008090505b8251811015611c0b57611bfc838281518110611be157fe5b602002602001015160200151836123f090919063ffffffff16565b91508080600101915050611bc9565b508092505050919050565b604051611c2290613694565b604051809103902081565b600080600080611c3b611828565b905060046000828152602001908152602001600020600001546004600083815260200190815260200160002060010154600460008481526020019081526020016000206002015493509350935050909192565b60005481565b60008060058054905090505b6000811115611d5457611cb1612b00565b6004600060056001850381548110611cc557fe5b906000526020600020015481526020019081526020016000206040518060600160405290816000820154815260200160018201548152602001600282015481525050905083816020015111158015611d2257506000816040015114155b8015611d32575080604001518411155b15611d4557806000015192505050611d8f565b50808060019003915050611ca0565b5060006005805490501115611d8a57600560016005805490500381548110611d7857fe5b90600052602060002001549050611d8f565b600090505b919050565b606080611da0436107c2565b915091509091565b60058181548110611db557fe5b906000526020600020016000915090505481565b6060611ddc611dd78661240f565b61243d565b9050604051611dea9061367f565b6040518091039020611e0f82600081518110611e0257fe5b6020026020010151612744565b8051906020012014611e56576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e4d90613796565b60405180910390fd5b600260ff16611e7882600181518110611e6b57fe5b602002602001015161251a565b14611eb8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eaf90613836565b60405180910390fd5b611f31611ed882600481518110611ecb57fe5b602002602001015161251a565b60001b600285604051611eeb9190613653565b602060405180830381855afa158015611f08573d6000803e3d6000fd5b5050506040513d601f19601f82011682018060405250611f2b9190810190612cef565b84611499565b611f70576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6790613856565b60405180910390fd5b6000611f7a611828565b90506000611f908288805190602001208861157b565b9050611fd46001611fc66003611fb86002611faa88611350565b6127d090919063ffffffff16565b61280a90919063ffffffff16565b6123f090919063ffffffff16565b811015612016576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161200d90613876565b60405180910390fd5b50505050505050565b600281565b6002602052816000526040600020818154811061203d57fe5b9060005260206000209060030201600091509150508060000154908060010154908060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905083565b60006040438161209457fe5b04905090565b60046020528060005260406000206000915090508060000154908060010154908060020154905083565b60406000819055506060806120d7611944565b8092508193505050600080905060405180606001604052808281526020016000815260200160ff815250600460008381526020019081526020016000206000820151816000015560208201518160010155604082015181600201559050506005819080600181540180825580915050906001820390600052602060002001600090919290919091505550600060026000838152602001908152602001600020816121819190612a97565b50600060036000838152602001908152602001600020816121a29190612a97565b5060008090505b83518110156122c6576002600083815260200190815260200160002080548091906001016121d79190612a97565b5060405180606001604052808281526020018483815181106121f557fe5b6020026020010151815260200185838151811061220e57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681525060026000848152602001908152602001600020828154811061224d57fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505080806001019150506121a9565b5060008090505b83518110156123ea576003600083815260200190815260200160002080548091906001016122fb9190612a97565b50604051806060016040528082815260200184838151811061231957fe5b6020026020010151815260200185838151811061233257fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1681525060036000848152602001908152602001600020828154811061237157fe5b9060005260206000209060030201600082015181600001556020820151816001015560408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555090505080806001019150506122cd565b50505050565b60008082840190508381101561240557600080fd5b8091505092915050565b612417612b21565b600060208301905060405180604001604052808451815260200182815250915050919050565b606061244882612830565b61245157600080fd5b600061245c8361287e565b905060608160405190808252806020026020018201604052801561249a57816020015b612487612b3b565b81526020019060019003908161247f5790505b50905060006124ac85602001516128ef565b8560200151019050600080600090505b8481101561250d576124cd83612978565b91506040518060400160405280838152602001848152508482815181106124f057fe5b6020026020010181905250818301925080806001019150506124bc565b5082945050505050919050565b600080826000015111801561253457506021826000015111155b61253d57600080fd5b600061254c83602001516128ef565b9050600081846000015103905060008083866020015101905080519150602083101561257f57826020036101000a820491505b81945050505050919050565b6000601582600001511461259e57600080fd5b6125a78261251a565b9050919050565b6060818301845110156125c057600080fd5b60608215600081146125dd5760405191506020820160405261262e565b6040519150601f8416801560200281840101858101878315602002848b0101015b8183101561261b57805183526020830192506020810190506125fe565b50868552601f19601f8301166040525050505b50809150509392505050565b6000806000806041855114612655576000935050505061273e565b602085015192506040850151915060ff6041860151169050601b8160ff16101561268057601b810190505b601b8160ff16141580156126985750601c8160ff1614155b156126a9576000935050505061273e565b6000600187838686604051600081526020016040526040516126ce9493929190613731565b6020604051602081039080840390855afa1580156126f0573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561273657600080fd5b809450505050505b92915050565b6060600082600001511161275757600080fd5b600061276683602001516128ef565b905060008184600001510390506060816040519080825280601f01601f1916602001820160405280156127a85781602001600182028038833980820191505090505b50905060008160200190506127c4848760200151018285612a30565b81945050505050919050565b6000808314156127e35760009050612804565b60008284029050828482816127f457fe5b04146127ff57600080fd5b809150505b92915050565b600080821161281857600080fd5b600082848161282357fe5b0490508091505092915050565b600080826000015114156128475760009050612879565b60008083602001519050805160001a915060c060ff168260ff16101561287257600092505050612879565b6001925050505b919050565b6000808260000151141561289557600090506128ea565b600080905060006128a984602001516128ef565b84602001510190506000846000015185602001510190505b808210156128e3576128d282612978565b8201915082806001019350506128c1565b8293505050505b919050565b600080825160001a9050608060ff1681101561290f576000915050612973565b60b860ff16811080612934575060c060ff168110158015612933575060f860ff1681105b5b15612943576001915050612973565b60c060ff168110156129635760018060b80360ff16820301915050612973565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff168110156129995760019150612a26565b60b860ff168110156129b6576001608060ff168203019150612a25565b60c060ff168110156129e65760b78103600185019450806020036101000a85510460018201810193505050612a24565b60f860ff16811015612a0357600160c060ff168203019150612a23565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b6000811415612a3e57612a92565b5b602060ff168110612a6e5782518252602060ff1683019250602060ff1682019150602060ff1681039050612a3f565b6000600182602060ff16036101000a03905080198451168184511681811785525050505b505050565b815481835581811115612ac457600302816003028360005260206000209182019101612ac39190612b55565b5b505050565b60405180606001604052806000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b60405180606001604052806000815260200160008152602001600081525090565b604051806040016040528060008152602001600081525090565b604051806040016040528060008152602001600081525090565b612ba891905b80821115612ba45760008082016000905560018201600090556002820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905550600301612b5b565b5090565b90565b600081359050612bba81613b33565b92915050565b600081359050612bcf81613b4a565b92915050565b600081519050612be481613b4a565b92915050565b60008083601f840112612bfc57600080fd5b8235905067ffffffffffffffff811115612c1557600080fd5b602083019150836001820283011115612c2d57600080fd5b9250929050565b600082601f830112612c4557600080fd5b8135612c58612c5382613982565b613955565b91508082526020830160208301858383011115612c7457600080fd5b612c7f838284613add565b50505092915050565b600081359050612c9781613b61565b92915050565b600060208284031215612caf57600080fd5b6000612cbd84828501612bab565b91505092915050565b600060208284031215612cd857600080fd5b6000612ce684828501612bc0565b91505092915050565b600060208284031215612d0157600080fd5b6000612d0f84828501612bd5565b91505092915050565b60008060408385031215612d2b57600080fd5b6000612d3985828601612bc0565b9250506020612d4a85828601612bc0565b9150509250929050565b600080600060608486031215612d6957600080fd5b6000612d7786828701612bc0565b9350506020612d8886828701612bc0565b925050604084013567ffffffffffffffff811115612da557600080fd5b612db186828701612c34565b9150509250925092565b60008060008060808587031215612dd157600080fd5b600085013567ffffffffffffffff811115612deb57600080fd5b612df787828801612c34565b945050602085013567ffffffffffffffff811115612e1457600080fd5b612e2087828801612c34565b935050604085013567ffffffffffffffff811115612e3d57600080fd5b612e4987828801612c34565b925050606085013567ffffffffffffffff811115612e6657600080fd5b612e7287828801612c34565b91505092959194509250565b600060208284031215612e9057600080fd5b6000612e9e84828501612c88565b91505092915050565b60008060408385031215612eba57600080fd5b6000612ec885828601612c88565b9250506020612ed985828601612bab565b9150509250929050565b600080600060608486031215612ef857600080fd5b6000612f0686828701612c88565b9350506020612f1786828701612bc0565b925050604084013567ffffffffffffffff811115612f3457600080fd5b612f4086828701612c34565b9150509250925092565b60008060408385031215612f5d57600080fd5b6000612f6b85828601612c88565b9250506020612f7c85828601612c88565b9150509250929050565b600080600080600080600060a0888a031215612fa157600080fd5b6000612faf8a828b01612c88565b9750506020612fc08a828b01612c88565b9650506040612fd18a828b01612c88565b955050606088013567ffffffffffffffff811115612fee57600080fd5b612ffa8a828b01612bea565b9450945050608088013567ffffffffffffffff81111561301957600080fd5b6130258a828b01612bea565b925092505092959891949750929550565b60006130428383613066565b60208301905092915050565b600061305a83836135bd565b60208301905092915050565b61306f81613a52565b82525050565b61307e81613a52565b82525050565b600061308f826139ce565b6130998185613a09565b93506130a4836139ae565b8060005b838110156130d55781516130bc8882613036565b97506130c7836139ef565b9250506001810190506130a8565b5085935050505092915050565b60006130ed826139d9565b6130f78185613a1a565b9350613102836139be565b8060005b8381101561313357815161311a888261304e565b9750613125836139fc565b925050600181019050613106565b5085935050505092915050565b61314981613a64565b82525050565b61316061315b82613a70565b613b1f565b82525050565b61316f81613a9c565b82525050565b61318661318182613a9c565b613b29565b82525050565b6000613197826139e4565b6131a18185613a2b565b93506131b1818560208601613aec565b80840191505092915050565b60006131ca600483613a47565b91507f766f7465000000000000000000000000000000000000000000000000000000006000830152600482019050919050565b600061320a602d83613a36565b91507f537461727420626c6f636b206d7573742062652067726561746572207468616e60008301527f2063757272656e74207370616e000000000000000000000000000000000000006020830152604082019050919050565b6000613270600f83613a47565b91507f6865696d64616c6c2d50357258776700000000000000000000000000000000006000830152600f82019050919050565b60006132b0601383613a36565b91507f436861696e20494420697320696e76616c6964000000000000000000000000006000830152602082019050919050565b60006132f0600f83613a36565b91507f496e76616c6964207370616e20696400000000000000000000000000000000006000830152602082019050919050565b6000613330601383613a36565b91507f5370616e20616c726561647920657869737473000000000000000000000000006000830152602082019050919050565b6000613370604583613a36565b91507f446966666572656e6365206265747765656e20737461727420616e6420656e6460008301527f20626c6f636b206d75737420626520696e206d756c7469706c6573206f66207360208301527f7072696e740000000000000000000000000000000000000000000000000000006040830152606082019050919050565b60006133fc602a83613a36565b91507f456e6420626c6f636b206d7573742062652067726561746572207468616e207360008301527f7461727420626c6f636b000000000000000000000000000000000000000000006020830152604082019050919050565b6000613462601483613a36565b91507f566f7465207479706520697320696e76616c69640000000000000000000000006000830152602082019050919050565b60006134a2601683613a36565b91507f5472616e73616374696f6e20697320696e76616c6964000000000000000000006000830152602082019050919050565b60006134e2600583613a47565b91507f31353030310000000000000000000000000000000000000000000000000000006000830152600582019050919050565b6000613522602483613a36565b91507f4e6f7420656e6f7567687420706f77657220746f206368616e6765207468652060008301527f7370616e000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60608201600082015161359160008501826135bd565b5060208201516135a460208501826135bd565b5060408201516135b76040850182613066565b50505050565b6135c681613ac6565b82525050565b6135d581613ac6565b82525050565b6135e481613ad0565b82525050565b60006135f6828561314f565b6001820191506136068284613175565b6020820191508190509392505050565b6000613622828661314f565b6001820191506136328285613175565b6020820191506136428284613175565b602082019150819050949350505050565b600061365f828461318c565b915081905092915050565b6000613675826131bd565b9150819050919050565b600061368a82613263565b9150819050919050565b600061369f826134d5565b9150819050919050565b60006020820190506136be6000830184613075565b92915050565b600060408201905081810360008301526136de8185613084565b905081810360208301526136f281846130e2565b90509392505050565b60006020820190506137106000830184613140565b92915050565b600060208201905061372b6000830184613166565b92915050565b60006080820190506137466000830187613166565b61375360208301866135db565b6137606040830185613166565b61376d6060830184613166565b95945050505050565b6000602082019050818103600083015261378f816131fd565b9050919050565b600060208201905081810360008301526137af816132a3565b9050919050565b600060208201905081810360008301526137cf816132e3565b9050919050565b600060208201905081810360008301526137ef81613323565b9050919050565b6000602082019050818103600083015261380f81613363565b9050919050565b6000602082019050818103600083015261382f816133ef565b9050919050565b6000602082019050818103600083015261384f81613455565b9050919050565b6000602082019050818103600083015261386f81613495565b9050919050565b6000602082019050818103600083015261388f81613515565b9050919050565b60006060820190506138ab600083018461357b565b92915050565b60006020820190506138c660008301846135cc565b92915050565b60006060820190506138e160008301866135cc565b6138ee60208301856135cc565b6138fb6040830184613075565b949350505050565b600060608201905061391860008301866135cc565b61392560208301856135cc565b61393260408301846135cc565b949350505050565b600060208201905061394f60008301846135db565b92915050565b6000604051905081810181811067ffffffffffffffff8211171561397857600080fd5b8060405250919050565b600067ffffffffffffffff82111561399957600080fd5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000613a5d82613aa6565b9050919050565b60008115159050919050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b82818337600083830152505050565b60005b83811015613b0a578082015181840152602081019050613aef565b83811115613b19576000848401525b50505050565b6000819050919050565b6000819050919050565b613b3c81613a52565b8114613b4757600080fd5b50565b613b5381613a9c565b8114613b5e57600080fd5b50565b613b6a81613ac6565b8114613b7557600080fd5b5056fea365627a7a7231582041043c020490417f03b23833da19152e2e105982aaa0228db2459085c981a3f16c6578706572696d656e74616cf564736f6c63430005100040" }, "0000000000000000000000000000000000001001": { "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b506004361061009e5760003560e01c8063d0504f8911610066578063d0504f8914610255578063d79e60b7146104d5578063ede01f17146104f7578063f552102214610525578063facd743b146105815761009e565b8063017a9105146100a3578063080356b7146100e957806321ec23b6146101625780633434735f146101c15780639426e2261461020b575b600080fd5b6100cf600480360360208110156100b957600080fd5b81019080803590602001909291905050506105dd565b604051808215151515815260200191505060405180910390f35b610160600480360360208110156100ff57600080fd5b810190808035906020019064010000000081111561011c57600080fd5b82018360208201111561012e57600080fd5b8035906020019184600183028401116401000000008311171561015057600080fd5b90919293919293905050506105fd565b005b61016a61094a565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b838110156101ad578082015181840152602081019050610192565b505050509050019250505060405180910390f35b6101c96109fb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610213610a13565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6104d36004803603608081101561026b57600080fd5b810190808035906020019064010000000081111561028857600080fd5b82018360208201111561029a57600080fd5b803590602001918460018302840111640100000000831117156102bc57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561031f57600080fd5b82018360208201111561033157600080fd5b8035906020019184600183028401116401000000008311171561035357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156103b657600080fd5b8201836020820111156103c857600080fd5b803590602001918460018302840111640100000000831117156103ea57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561044d57600080fd5b82018360208201111561045f57600080fd5b8035906020019184600183028401116401000000008311171561048157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050610a19565b005b6104dd610c38565b604051808215151515815260200191505060405180910390f35b6105236004803603602081101561050d57600080fd5b8101908080359060200190929190505050610c70565b005b6105676004803603602081101561053b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610e1a565b604051808215151515815260200191505060405180910390f35b6105c36004803603602081101561059757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610edd565b604051808215151515815260200191505060405180910390f35b60036020528060005260406000206000915054906101000a900460ff1681565b73fffffffffffffffffffffffffffffffffffffffe73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461064957600080fd5b60606106a061069b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050610fa0565b610fce565b905060006106c1826000815181106106b457fe5b60200260200101516110ab565b905060006106e2836001815181106106d557fe5b602002602001015161111c565b90506060610703846002815181106106f657fe5b602002602001015161113f565b9050600115156107146000856111cb565b151514610789576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f496e76616c69642070726f706f7365642073746174652069640000000000000081525060200191505060405180910390fd5b600015156003600085815260200190815260200160002060009054906101000a900460ff16151514610823576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f496e76616c69642073746174652069640000000000000000000000000000000081525060200191505060405180910390fd5b61082c826111f0565b1561090a578173ffffffffffffffffffffffffffffffffffffffff166326c53bea84836040518363ffffffff1660e01b81526004018083815260200180602001828103825283818151815260200191508051906020019080838360005b838110156108a4578082015181840152602081019050610889565b50505050905090810190601f1680156108d15780820380516001836020036101000a031916815260200191505b509350505050600060405180830381600087803b1580156108f157600080fd5b505af1158015610905573d6000803e3d6000fd5b505050505b60016003600085815260200190815260200160002060006101000a81548160ff021916908315150217905550610941600084611209565b50505050505050565b6060600080905060606000600201546040519080825280602002602001820160405280156109875781602001602082028038833980820191505090505b509050600061099660006112c7565b90505b6109a46000826112fa565b156109f2576000806109b760008461130e565b8092508193505050818486815181106109cc57fe5b60200260200101818152505060018501945050506109eb600082611363565b9050610999565b50809250505090565b73fffffffffffffffffffffffffffffffffffffffe81565b61100081565b61100073ffffffffffffffffffffffffffffffffffffffff1663d0504f89858585856040518563ffffffff1660e01b81526004018080602001806020018060200180602001858103855289818151815260200191508051906020019080838360005b83811015610a96578082015181840152602081019050610a7b565b50505050905090810190601f168015610ac35780820380516001836020036101000a031916815260200191505b50858103845288818151815260200191508051906020019080838360005b83811015610afc578082015181840152602081019050610ae1565b50505050905090810190601f168015610b295780820380516001836020036101000a031916815260200191505b50858103835287818151815260200191508051906020019080838360005b83811015610b62578082015181840152602081019050610b47565b50505050905090810190601f168015610b8f5780820380516001836020036101000a031916815260200191505b50858103825286818151815260200191508051906020019080838360005b83811015610bc8578082015181840152602081019050610bad565b50505050905090810190601f168015610bf55780820380516001836020036101000a031916815260200191505b5098505050505050505050600060405180830381600087803b158015610c1a57600080fd5b505af1158015610c2e573d6000803e3d6000fd5b5050505050505050565b600061100073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b610c7933610edd565b610ceb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f496e76616c69642076616c696461746f7200000000000000000000000000000081525060200191505060405180910390fd5b60001515610cfa6000836111cb565b151514610d6f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f537461746520616c72656164792070726f706f7365640000000000000000000081525060200191505060405180910390fd5b600015156003600083815260200190815260200160002060009054906101000a900460ff16151514610e09576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f537461746520616c726561647920636f6d6d697474656400000000000000000081525060200191505060405180910390fd5b610e1660008260016113c9565b5050565b600061100073ffffffffffffffffffffffffffffffffffffffff166370ba5707836040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015610e9b57600080fd5b505afa158015610eaf573d6000803e3d6000fd5b505050506040513d6020811015610ec557600080fd5b81019080805190602001909291905050509050919050565b600061100073ffffffffffffffffffffffffffffffffffffffff166355614fcc836040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015610f5e57600080fd5b505afa158015610f72573d6000803e3d6000fd5b505050506040513d6020811015610f8857600080fd5b81019080805190602001909291905050509050919050565b610fa861170f565b600060208301905060405180604001604052808451815260200182815250915050919050565b6060610fd9826114a8565b610fe257600080fd5b6000610fed836114f6565b905060608160405190808252806020026020018201604052801561102b57816020015b611018611729565b8152602001906001900390816110105790505b509050600061103d8560200151611567565b8560200151019050600080600090505b8481101561109e5761105e836115f0565b915060405180604001604052808381526020018481525084828151811061108157fe5b60200260200101819052508183019250808060010191505061104d565b5082945050505050919050565b60008082600001511180156110c557506021826000015111155b6110ce57600080fd5b60006110dd8360200151611567565b9050600081846000015103905060008083866020015101905080519150602083101561111057826020036101000a820491505b81945050505050919050565b6000601582600001511461112f57600080fd5b611138826110ab565b9050919050565b6060600082600001511161115257600080fd5b60006111618360200151611567565b905060008184600001510390506060816040519080825280601f01601f1916602001820160405280156111a35781602001600182028038833980820191505090505b50905060008160200190506111bf8487602001510182856116a8565b81945050505050919050565b6000808360000160008481526020019081526020016000206000015411905092915050565b600080823b905060008163ffffffff1611915050919050565b600080836000016000848152602001908152602001600020600001549050600081141561123a5760009150506112c1565b8360000160008481526020019081526020016000206000808201600090556001820160006101000a81549060ff02191690555050600184600101600183038154811061128257fe5b906000526020600020906002020160010160006101000a81548160ff021916908315150217905550836002016000815480929190600190039190505550505b92915050565b60006112f3827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611363565b9050919050565b600082600101805490508210905092915050565b60008083600101838154811061132057fe5b906000526020600020906002020160000154915083600001600083815260200190815260200160002060010160009054906101000a900460ff1690509250929050565b600081806001019250505b8260010180549050821080156113ae575082600101828154811061138e57fe5b906000526020600020906002020160010160009054906101000a900460ff165b156113c057818060010192505061136e565b81905092915050565b6000808460000160008581526020019081526020016000206000015490508285600001600086815260200190815260200160002060010160006101000a81548160ff021916908315150217905550600081111561142a5760019150506114a1565b8460010180548091906001016114409190611743565b905060018101856000016000868152602001908152602001600020600001819055508385600101828154811061147257fe5b906000526020600020906002020160000181905550846002016000815480929190600101919050555060009150505b9392505050565b600080826000015114156114bf57600090506114f1565b60008083602001519050805160001a915060c060ff168260ff1610156114ea576000925050506114f1565b6001925050505b919050565b6000808260000151141561150d5760009050611562565b600080905060006115218460200151611567565b84602001510190506000846000015185602001510190505b8082101561155b5761154a826115f0565b820191508280600101935050611539565b8293505050505b919050565b600080825160001a9050608060ff168110156115875760009150506115eb565b60b860ff168110806115ac575060c060ff1681101580156115ab575060f860ff1681105b5b156115bb5760019150506115eb565b60c060ff168110156115db5760018060b80360ff168203019150506115eb565b60018060f80360ff168203019150505b919050565b6000806000835160001a9050608060ff16811015611611576001915061169e565b60b860ff1681101561162e576001608060ff16820301915061169d565b60c060ff1681101561165e5760b78103600185019450806020036101000a8551046001820181019350505061169c565b60f860ff1681101561167b57600160c060ff16820301915061169b565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b60008114156116b65761170a565b5b602060ff1681106116e65782518252602060ff1683019250602060ff1682019150602060ff16810390506116b7565b6000600182602060ff16036101000a03905080198451168184511681811785525050505b505050565b604051806040016040528060008152602001600081525090565b604051806040016040528060008152602001600081525090565b8154818355818111156117705760020281600202836000526020600020918201910161176f9190611775565b5b505050565b6117ad91905b808211156117a9576000808201600090556001820160006101000a81549060ff02191690555060020161177b565b5090565b9056fea265627a7a723158209019c704cf8a199f003a390a902db2323e1adac1a6e87371012f3319ba0b4c4b64736f6c634300050b0032" + "code": "0x" }, "0000000000000000000000000000000000001010": { "balance": "0x204fce28085b549b31600000", - "code": "0x60806040526004361061019c5760003560e01c806377d32e94116100ec578063acd06cb31161008a578063e306f77911610064578063e306f77914610a7b578063e614d0d614610aa6578063f2fde38b14610ad1578063fc0c546a14610b225761019c565b8063acd06cb31461097a578063b789543c146109cd578063cc79f97b14610a505761019c565b80639025e64c116100c65780639025e64c146107c957806395d89b4114610859578063a9059cbb146108e9578063abceeba21461094f5761019c565b806377d32e94146106315780638da5cb5b146107435780638f32d59b1461079a5761019c565b806347e7ef24116101595780637019d41a116101335780637019d41a1461053357806370a082311461058a578063715018a6146105ef578063771282f6146106065761019c565b806347e7ef2414610410578063485cc9551461046b57806360f96a8f146104dc5761019c565b806306fdde03146101a15780631499c5921461023157806318160ddd1461028257806319d27d9c146102ad5780632e1a7d4d146103b1578063313ce567146103df575b600080fd5b3480156101ad57600080fd5b506101b6610b79565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101f65780820151818401526020810190506101db565b50505050905090810190601f1680156102235780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561023d57600080fd5b506102806004803603602081101561025457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610bb6565b005b34801561028e57600080fd5b50610297610c24565b6040518082815260200191505060405180910390f35b3480156102b957600080fd5b5061036f600480360360a08110156102d057600080fd5b81019080803590602001906401000000008111156102ed57600080fd5b8201836020820111156102ff57600080fd5b8035906020019184600183028401116401000000008311171561032157600080fd5b9091929391929390803590602001909291908035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610c3a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103dd600480360360208110156103c757600080fd5b8101908080359060200190929190505050610e06565b005b3480156103eb57600080fd5b506103f4610f64565b604051808260ff1660ff16815260200191505060405180910390f35b34801561041c57600080fd5b506104696004803603604081101561043357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610f6d565b005b34801561047757600080fd5b506104da6004803603604081101561048e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611129565b005b3480156104e857600080fd5b506104f16111f8565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561053f57600080fd5b5061054861121e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561059657600080fd5b506105d9600480360360208110156105ad57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611244565b6040518082815260200191505060405180910390f35b3480156105fb57600080fd5b50610604611265565b005b34801561061257600080fd5b5061061b611335565b6040518082815260200191505060405180910390f35b34801561063d57600080fd5b506107016004803603604081101561065457600080fd5b81019080803590602001909291908035906020019064010000000081111561067b57600080fd5b82018360208201111561068d57600080fd5b803590602001918460018302840111640100000000831117156106af57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050919291929050505061133b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561074f57600080fd5b506107586114c0565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156107a657600080fd5b506107af6114e9565b604051808215151515815260200191505060405180910390f35b3480156107d557600080fd5b506107de611540565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561081e578082015181840152602081019050610803565b50505050905090810190601f16801561084b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561086557600080fd5b5061086e611579565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156108ae578082015181840152602081019050610893565b50505050905090810190601f1680156108db5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610935600480360360408110156108ff57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506115b6565b604051808215151515815260200191505060405180910390f35b34801561095b57600080fd5b506109646115dc565b6040518082815260200191505060405180910390f35b34801561098657600080fd5b506109b36004803603602081101561099d57600080fd5b8101908080359060200190929190505050611669565b604051808215151515815260200191505060405180910390f35b3480156109d957600080fd5b50610a3a600480360360808110156109f057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019092919080359060200190929190505050611689565b6040518082815260200191505060405180910390f35b348015610a5c57600080fd5b50610a656116a9565b6040518082815260200191505060405180910390f35b348015610a8757600080fd5b50610a906116af565b6040518082815260200191505060405180910390f35b348015610ab257600080fd5b50610abb6116b5565b6040518082815260200191505060405180910390f35b348015610add57600080fd5b50610b2060048036036020811015610af457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611742565b005b348015610b2e57600080fd5b50610b3761175f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60606040518060400160405280600b81526020017f4d6174696320546f6b656e000000000000000000000000000000000000000000815250905090565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260108152602001807f44697361626c656420666561747572650000000000000000000000000000000081525060200191505060405180910390fd5b6000601260ff16600a0a6402540be40002905090565b6000808511610c4857600080fd5b6000831480610c575750824311155b610cc9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f5369676e6174757265206973206578706972656400000000000000000000000081525060200191505060405180910390fd5b6000610cd733878787611689565b9050600015156005600083815260200190815260200160002060009054906101000a900460ff16151514610d73576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f536967206465616374697661746564000000000000000000000000000000000081525060200191505060405180910390fd5b60016005600083815260200190815260200160002060006101000a81548160ff021916908315150217905550610ded8189898080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505061133b565b9150610dfa828488611785565b50509695505050505050565b60003390506000610e1682611244565b9050610e2d83600654611b4290919063ffffffff16565b600681905550600083118015610e435750828110155b8015610e4e57508234145b610ec0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f496e73756666696369656e7420616d6f756e740000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167febff2602b3f468259e1e99f613fed6691f3a6526effe6ef3e768ba7ae7a36c4f8584610f3c87611244565b60405180848152602001838152602001828152602001935050505060405180910390a3505050565b60006012905090565b610f756114e9565b610f7e57600080fd5b600081118015610fbb5750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b611010576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611e6e6023913960400191505060405180910390fd5b600061101b83611244565b905060008390508073ffffffffffffffffffffffffffffffffffffffff166108fc849081150290604051600060405180830381858888f19350505050158015611068573d6000803e3d6000fd5b5061107e83600654611b6290919063ffffffff16565b6006819055508373ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f4e2ca0515ed1aef1395f66b5303bb5d6f1bf9d61a353fa53f73f8ac9973fa9f6858561110089611244565b60405180848152602001838152602001828152602001935050505060405180910390a350505050565b600760009054906101000a900460ff161561118f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180611e4b6023913960400191505060405180910390fd5b6001600760006101000a81548160ff02191690831515021790555080600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506111f482611b81565b5050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008173ffffffffffffffffffffffffffffffffffffffff16319050919050565b61126d6114e9565b61127657600080fd5b600073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60065481565b600080600080604185511461135657600093505050506114ba565b602085015192506040850151915060ff6041860151169050601b8160ff16101561138157601b810190505b601b8160ff16141580156113995750601c8160ff1614155b156113aa57600093505050506114ba565b60018682858560405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015611407573d6000803e3d6000fd5b505050602060405103519350600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156114b6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f4572726f7220696e2065637265636f766572000000000000000000000000000081525060200191505060405180910390fd5b5050505b92915050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614905090565b6040518060400160405280600281526020017f3a9900000000000000000000000000000000000000000000000000000000000081525081565b60606040518060400160405280600581526020017f4d41544943000000000000000000000000000000000000000000000000000000815250905090565b60008134146115c857600090506115d6565b6115d3338484611785565b90505b92915050565b6040518060800160405280605b8152602001611e91605b91396040516020018082805190602001908083835b6020831061162b5780518252602082019150602081019050602083039250611608565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b60056020528060005260406000206000915054906101000a900460ff1681565b600061169f61169a86868686611c79565b611d4f565b9050949350505050565b613a9981565b60015481565b604051806080016040528060498152602001611eec604991396040516020018082805190602001908083835b6020831061170457805182526020820191506020810190506020830392506116e1565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012081565b61174a6114e9565b61175357600080fd5b61175c81611b81565b50565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000803073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561180557600080fd5b505afa158015611819573d6000803e3d6000fd5b505050506040513d602081101561182f57600080fd5b8101908080519060200190929190505050905060003073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156118c157600080fd5b505afa1580156118d5573d6000803e3d6000fd5b505050506040513d60208110156118eb57600080fd5b81019080805190602001909291905050509050611909868686611d99565b8473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fe6497e3ee548a3372136af2fcb0696db31fc6cf20260707645068bd3fe97f3c48786863073ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611a1157600080fd5b505afa158015611a25573d6000803e3d6000fd5b505050506040513d6020811015611a3b57600080fd5b81019080805190602001909291905050503073ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015611ac957600080fd5b505afa158015611add573d6000803e3d6000fd5b505050506040513d6020811015611af357600080fd5b8101908080519060200190929190505050604051808681526020018581526020018481526020018381526020018281526020019550505050505060405180910390a46001925050509392505050565b600082821115611b5157600080fd5b600082840390508091505092915050565b600080828401905083811015611b7757600080fd5b8091505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611bbb57600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000806040518060800160405280605b8152602001611e91605b91396040516020018082805190602001908083835b60208310611ccb5780518252602082019150602081019050602083039250611ca8565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120905060405181815273ffffffffffffffffffffffffffffffffffffffff8716602082015285604082015284606082015283608082015260a0812092505081915050949350505050565b60008060015490506040517f190100000000000000000000000000000000000000000000000000000000000081528160028201528360228201526042812092505081915050919050565b8173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611ddf573d6000803e3d6000fd5b508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a350505056fe54686520636f6e747261637420697320616c726561647920696e697469616c697a6564496e73756666696369656e7420616d6f756e74206f7220696e76616c69642075736572546f6b656e5472616e736665724f726465722861646472657373207370656e6465722c75696e7432353620746f6b656e49644f72416d6f756e742c6279746573333220646174612c75696e743235362065787069726174696f6e29454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c75696e7432353620636861696e49642c6164647265737320636f6e747261637429a265627a7a72315820f61fab49705fc0473e56e179e67d714e15b540d31ecea57818c062e41902d06c64736f6c634300050b0032" + "code": "0x" }, - "6c468CF8c9879006E22EC4029696E005C2319C9D": { + "71562b71999873DB5b286dF957af199Ec94617F7": { "balance": "0x3635c9adc5dea00000" } }, From 57ccdb54826798c0a97bff366ad31766acc5e36e Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Thu, 5 Mar 2020 11:38:44 +0530 Subject: [PATCH 05/12] Revert unintended changes --- consensus/bor/bor.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index cda2840144bb..f4223be70266 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -40,10 +40,8 @@ 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"}]` - 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 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 From 9dd4e4b0f98f0af56ab9309d55519153f31b0b97 Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Wed, 11 Mar 2020 15:31:38 +0530 Subject: [PATCH 06/12] Refactor HeimdallClient + commitSpan test :construction: --- consensus/bor/api.go | 4 ++ consensus/bor/bor.go | 109 ++++++++++++++++++++----------- consensus/bor/rest.go | 83 ++++++++++++++---------- consensus/bor_test/bor_test.go | 111 ++++++++++++++++++++++++++++++-- consensus/bor_test/genesis.json | 2 +- consensus/bor_test/span.json | 95 +++++++++++++++++++++++++++ mocks/IHeimdallClient.go | 71 ++++++++++++++++++++ 7 files changed, 396 insertions(+), 79 deletions(-) create mode 100644 consensus/bor_test/span.json create mode 100644 mocks/IHeimdallClient.go diff --git a/consensus/bor/api.go b/consensus/bor/api.go index 98f7c46b6e61..d1d151c216a5 100644 --- a/consensus/bor/api.go +++ b/consensus/bor/api.go @@ -30,6 +30,10 @@ type API struct { bor *Bor } +func NewBorApi(chain consensus.ChainReader, bor *Bor) API { + return API{chain: chain, bor: bor} +} + // GetSnapshot retrieves the state snapshot at a given block. func (api *API) GetSnapshot(number *rpc.BlockNumber) (*Snapshot, error) { // Retrieve the requested block number (or current if none requested) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index f4223be70266..68ecb362119d 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -10,7 +10,8 @@ import ( "io" "math" "math/big" - "net/http" + + // "net/http" "sort" "strconv" "strings" @@ -243,7 +244,7 @@ type Bor struct { ethAPI *ethapi.PublicBlockChainAPI validatorSetABI abi.ABI stateReceiverABI abi.ABI - httpClient http.Client + HeimdallClient IHeimdallClient // The fields below are for testing only fakeDiff bool // Skip difficulty verifications @@ -268,6 +269,8 @@ func New( signatures, _ := lru.NewARC(inmemorySignatures) vABI, _ := abi.JSON(strings.NewReader(validatorsetABI)) sABI, _ := abi.JSON(strings.NewReader(stateReceiverABI)) + heimdallClient, _ := NewHeimdallClient(chainConfig.Bor.Heimdall) + c := &Bor{ chainConfig: chainConfig, config: borConfig, @@ -277,9 +280,7 @@ func New( signatures: signatures, validatorSetABI: vABI, stateReceiverABI: sABI, - httpClient: http.Client{ - Timeout: time.Duration(5 * time.Second), - }, + HeimdallClient: heimdallClient, } return c @@ -662,20 +663,26 @@ func (c *Bor) Prepare(chain consensus.ChainReader, header *types.Header) error { // rewards given. func (c *Bor) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header) { // commit span - if header.Number.Uint64()%c.config.Sprint == 0 { + headerNumber := header.Number.Uint64() + fmt.Println(header.Number, headerNumber % c.config.Sprint) + if headerNumber > 0 && + headerNumber % c.config.Sprint == 0 { cx := chainContext{Chain: chain, Bor: c} - + fmt.Println("here 0.1") // check and commit span if err := c.checkAndCommitSpan(state, header, cx); err != nil { + fmt.Println("Error while committing span", err) log.Error("Error while committing span", "error", err) return } - + fmt.Println("here 11") // commit statees - if err := c.CommitStates(state, header, cx); err != nil { - log.Error("Error while committing states", "error", err) - return - } + // if err := c.CommitStates(state, header, cx); err != nil { + // log.Error("Error while committing states", "error", err) + // fmt.Println("here 12", err) + // return + // } + fmt.Println("here 12") } // No block rewards in PoA, so the state remains as is and uncles are dropped @@ -986,33 +993,53 @@ func (c *Bor) checkAndCommitSpan( header *types.Header, chain core.ChainContext, ) error { + headerNumber := header.Number.Uint64() pending := false var span *Span = nil - var wg sync.WaitGroup - wg.Add(1) + errors := make(chan error) + // var wg sync.WaitGroup + // wg.Add(1) go func() { - pending, _ = c.isSpanPending(header.Number.Uint64()) - wg.Done() + var err error + pending, err = c.isSpanPending(headerNumber - 1) + errors <- err + // wg.Done() }() - wg.Add(1) + // wg.Add(1) go func() { - span, _ = c.GetCurrentSpan(header.Number.Uint64() - 1) - wg.Done() + var err error + span, err = c.GetCurrentSpan(headerNumber - 1) + errors <- err + // wg.Done() }() - wg.Wait() + var err error + for i := 0; i < 2; i++ { + err = <- errors + if err != nil { + // fmt.Println(i, err) + return err + } + } + + fmt.Println("here 1") // commit span if there is new span pending or span is ending or end block is not set - if pending || c.needToCommitSpan(span, header) { - err := c.commitSpan(span, state, header, chain) + if pending || c.needToCommitSpan(span, headerNumber) { + fmt.Println("here 2", span) + err := c.fetchAndCommitSpan(span.ID + 1, state, header, chain) + // err := c.commitSpan(span, state, header, chain) + fmt.Println("here 10", err) return err } return nil } -func (c *Bor) needToCommitSpan(span *Span, header *types.Header) bool { +func (c *Bor) needToCommitSpan(span *Span, headerNumber uint64) bool { + fmt.Println("span", span) + // if span is nil if span == nil { return false @@ -1024,21 +1051,21 @@ func (c *Bor) needToCommitSpan(span *Span, header *types.Header) bool { } // if current block is first block of last sprint in current span - h := header.Number.Uint64() - if span.EndBlock > c.config.Sprint && span.EndBlock-c.config.Sprint+1 == h { + if span.EndBlock > c.config.Sprint && span.EndBlock-c.config.Sprint+1 == headerNumber { return true } return false } -func (c *Bor) commitSpan( - span *Span, +func (c *Bor) fetchAndCommitSpan( + newSpanID uint64, state *state.StateDB, header *types.Header, chain core.ChainContext, ) error { - response, err := FetchFromHeimdallWithRetry(c.httpClient, c.chainConfig.Bor.Heimdall, "bor", "span", strconv.FormatUint(span.ID+1, 10)) + response, err := c.HeimdallClient.FetchWithRetry("bor", "span", strconv.FormatUint(newSpanID, 10)) + fmt.Println("here 3") if err != nil { return err } @@ -1047,7 +1074,7 @@ func (c *Bor) commitSpan( if err := json.Unmarshal(response.Result, &heimdallSpan); err != nil { return err } - + fmt.Println("here 4", heimdallSpan) // check if chain id matches with heimdall span if heimdallSpan.ChainID != c.chainConfig.ChainID.String() { return fmt.Errorf( @@ -1056,7 +1083,7 @@ func (c *Bor) commitSpan( c.chainConfig.ChainID, ) } - + fmt.Println("here 5") // get validators bytes var validators []MinimalVal for _, val := range heimdallSpan.ValidatorSet.Validators { @@ -1066,7 +1093,7 @@ func (c *Bor) commitSpan( if err != nil { return err } - + fmt.Println("here 6") // get producers bytes var producers []MinimalVal for _, val := range heimdallSpan.SelectedProducers { @@ -1086,7 +1113,7 @@ func (c *Bor) commitSpan( "validatorBytes", hex.EncodeToString(validatorBytes), "producerBytes", hex.EncodeToString(producerBytes), ) - + fmt.Println("here 7") // get packed data data, err := c.validatorSetABI.Pack(method, big.NewInt(0).SetUint64(heimdallSpan.ID), @@ -1099,10 +1126,10 @@ func (c *Bor) commitSpan( log.Error("Unable to pack tx for commitSpan", "error", err) return err } - + fmt.Println("here 8") // get system message msg := getSystemMessage(common.HexToAddress(c.config.ValidatorContract), data) - + fmt.Println("here 9") // apply message return applyMessage(msg, state, header, c.chainConfig, chain) } @@ -1166,7 +1193,7 @@ func (c *Bor) CommitStates( // itereate through state ids for _, stateID := range stateIds { // fetch from heimdall - response, err := FetchFromHeimdallWithRetry(c.httpClient, c.chainConfig.Bor.Heimdall, "clerk", "event-record", strconv.FormatUint(stateID.Uint64(), 10)) + response, err := c.HeimdallClient.FetchWithRetry("clerk", "event-record", strconv.FormatUint(stateID.Uint64(), 10)) if err != nil { return err } @@ -1218,6 +1245,10 @@ func (c *Bor) CommitStates( return nil } +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() snap, err := c.snapshot(chain, header.Number.Uint64(), header.Hash(), nil) @@ -1246,7 +1277,6 @@ func isProposeSpanAction(tx *types.Transaction, validatorContract string) bool { func isProposeStateAction(tx *types.Transaction, stateReceiverContract string) bool { // keccak256('proposeState(uint256)').slice(0, 4) proposeStateSig, _ := hex.DecodeString("ede01f17") - fmt.Println(bytes.Compare(proposeStateSig, tx.Data()[:4]) == 0, tx.To().String(), stateReceiverContract) return bytes.Compare(proposeStateSig, tx.Data()[:4]) == 0 && tx.To().String() == stateReceiverContract } @@ -1265,6 +1295,10 @@ type chainContext struct { Bor consensus.Engine } +// func NewChainContext(chain consensus.ChainReader, bor consensus.Engine) (chainContext) { +// return {Chain: chain, Bor: bor} +// } + func (c chainContext) Engine() consensus.Engine { return c.Bor } @@ -1322,11 +1356,12 @@ func applyMessage( msg.Gas(), msg.Value(), ) + fmt.Println("here 9.1", err) // Update the state with pending changes if err != nil { + fmt.Println("here 9.2", err) state.Finalise(true) } - return nil } diff --git a/consensus/bor/rest.go b/consensus/bor/rest.go index a31295913286..6129037fc38d 100644 --- a/consensus/bor/rest.go +++ b/consensus/bor/rest.go @@ -19,69 +19,82 @@ type ResponseWithHeight struct { Result json.RawMessage `json:"result"` } -// internal fetch method -func internalFetch(client http.Client, u *url.URL) (*ResponseWithHeight, error) { - res, err := client.Get(u.String()) - if err != nil { - return nil, err - } - defer res.Body.Close() +type IHeimdallClient interface { + Fetch(paths ...string) (*ResponseWithHeight, error) + FetchWithRetry(paths ...string) (*ResponseWithHeight, error) +} - // check status code - if res.StatusCode != 200 { - return nil, fmt.Errorf("Error while fetching data from Heimdall") - } +type HeimdallClient struct { + u *url.URL + client http.Client +} - // get response - body, err := ioutil.ReadAll(res.Body) +func NewHeimdallClient(urlString string) (*HeimdallClient, error) { + u, err := url.Parse(urlString) if err != nil { return nil, err } - // unmarshall data from buffer - var response ResponseWithHeight - if err := json.Unmarshal(body, &response); err != nil { - return nil, err + h := &HeimdallClient{ + u: u, + client: http.Client{ + Timeout: time.Duration(5 * time.Second), + }, } - - return &response, nil + return h, nil } -// FetchFromHeimdallWithRetry returns data from heimdall with retry -func FetchFromHeimdallWithRetry(client http.Client, urlString string, paths ...string) (*ResponseWithHeight, error) { - u, err := url.Parse(urlString) - if err != nil { - return nil, err +func (h *HeimdallClient) Fetch(paths ...string) (*ResponseWithHeight, error) { + for _, e := range paths { + if e != "" { + h.u.Path = path.Join(h.u.Path, e) + } } + return h.internalFetch() +} +// FetchWithRetry returns data from heimdall with retry +func (h *HeimdallClient) FetchWithRetry(paths ...string) (*ResponseWithHeight, error) { for _, e := range paths { if e != "" { - u.Path = path.Join(u.Path, e) + h.u.Path = path.Join(h.u.Path, e) } } for { - res, err := internalFetch(client, u) + res, err := h.internalFetch() if err == nil && res != nil { return res, nil } - log.Info("Retrying again in 5 seconds for next Heimdall span", "path", u.Path) + log.Info("Retrying again in 5 seconds for next Heimdall span", "path", h.u.Path) time.Sleep(5 * time.Second) } } -// FetchFromHeimdall returns data from heimdall -func FetchFromHeimdall(client http.Client, urlString string, paths ...string) (*ResponseWithHeight, error) { - u, err := url.Parse(urlString) +// internal fetch method +func (h *HeimdallClient) internalFetch() (*ResponseWithHeight, error) { + res, err := h.client.Get(h.u.String()) if err != nil { return nil, err } + defer res.Body.Close() - for _, e := range paths { - if e != "" { - u.Path = path.Join(u.Path, e) - } + // check status code + if res.StatusCode != 200 { + return nil, fmt.Errorf("Error while fetching data from Heimdall") + } + + // 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 } - return internalFetch(client, u) + return &response, nil } diff --git a/consensus/bor_test/bor_test.go b/consensus/bor_test/bor_test.go index 80163bc91eca..f959f07cb0ab 100644 --- a/consensus/bor_test/bor_test.go +++ b/consensus/bor_test/bor_test.go @@ -3,34 +3,129 @@ package bor_test import ( "encoding/hex" "encoding/json" + "fmt" + + // "fmt" "io/ioutil" "math/big" "testing" "github.com/stretchr/testify/assert" + // "github.com/stretchr/testify/mock" "github.com/maticnetwork/bor/common" "github.com/maticnetwork/bor/consensus/bor" "github.com/maticnetwork/bor/core" "github.com/maticnetwork/bor/core/rawdb" + "github.com/maticnetwork/bor/core/state" "github.com/maticnetwork/bor/core/types" + // "github.com/maticnetwork/bor/core/vm" "github.com/maticnetwork/bor/crypto" "github.com/maticnetwork/bor/eth" "github.com/maticnetwork/bor/ethdb" + "github.com/maticnetwork/bor/mocks" "github.com/maticnetwork/bor/node" ) +type initializeData struct { + genesis *core.Genesis + ethereum *eth.Ethereum +} + +func TestCommitSpan(t *testing.T) { + var ( + db = rawdb.NewMemoryDatabase() + // key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + // addr = crypto.PubkeyToAddress(key.PublicKey) + ) + init := buildEthereumInstance(t, db) + chain := init.ethereum.BlockChain() + engine := init.ethereum.Engine() + _bor := engine.(*bor.Bor) + + spanData, err := ioutil.ReadFile("span.json") + if err != nil { + t.Fatalf("%s", err) + } + res := &bor.ResponseWithHeight{} + if err := json.Unmarshal(spanData, res); err != nil { + t.Fatalf("%s", err) + } + + h := &mocks.IHeimdallClient{} + h.On("FetchWithRetry", "bor", "span", "1").Return(res, nil) + _bor.SetHeimdallClient(h) + block := init.genesis.ToBlock(db) + statedb, _ := state.New(block.Root(), state.NewDatabase(db)) + // _, _, _, err = chain.Processor().Process(block, statedb, vm.Config{}) + // fmt.Println(err) + // _bor.Finalize(chain, block.Header(), statedb, nil, nil) + + api := bor.NewBorApi(chain, _bor) + validators, _ := api.GetCurrentValidators() + fmt.Println(1, validators) + + header := block.Header() + header.Number = big.NewInt(1) + header.ParentHash = block.Hash() + block = types.NewBlockWithHeader(header) + _bor.Finalize(chain, block.Header(), statedb, nil, nil) + // _, _, _, err = chain.Processor().Process(block, statedb, vm.Config{}) + if err != nil { + t.Fatalf("%s", err) + } + // fmt.Println(header.Number) + // _bor.Finalize(chain, header, statedb, nil, nil) + + // status, err := chain.writeBlockWithState(block, receipts, statedb) + + // chain.chainmu.Lock() + k := big.NewInt(0) + k.Add(block.Difficulty(), chain.GetTdByHash(block.ParentHash())) + fmt.Println("k", k) + + rawdb.WriteTd(db, + block.Hash(), + block.NumberU64(), + k, + ) + rawdb.WriteBlock(db, block) + root, err := statedb.Commit(true /* false ??*/) + fmt.Println("root", root) + if err != nil { + t.Fatalf("%s", err) + } + if err := statedb.Reset(root); err != nil { + t.Fatalf("state reset after block %d failed: %v", block.NumberU64(), err) + } + // blockchain.chainmu.Unlock() + + assert.True(t, h.AssertNumberOfCalls(t, "FetchWithRetry", 1)) + validators, _ = api.GetCurrentValidators() + fmt.Println(2, validators) + + validators, _ = _bor.GetCurrentValidators(0, 255) + fmt.Println(3, validators) + + validators, _ = _bor.GetCurrentValidators(0, 256) + fmt.Println(4, validators) + + // validators, _ = _bor.GetCurrentValidators(1, 256) + // fmt.Println(4, validators) + // engine +} + func TestIsValidatorAction(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") addr = crypto.PubkeyToAddress(key.PublicKey) ) - ethereum := buildEthereumInstance(t, db) + init := buildEthereumInstance(t, db) + ethereum := init.ethereum chain := ethereum.BlockChain() engine := ethereum.Engine() - bor := engine.(*bor.Bor) // proposeState data, _ := hex.DecodeString("ede01f170000000000000000000000000000000000000000000000000000000000000000") @@ -40,7 +135,7 @@ func TestIsValidatorAction(t *testing.T) { big.NewInt(0), 0, big.NewInt(0), data, ) - assert.True(t, bor.IsValidatorAction(chain, addr, tx)) + assert.True(t, engine.(*bor.Bor).IsValidatorAction(chain, addr, tx)) // proposeSpan data, _ = hex.DecodeString("4b0e4d17") @@ -50,10 +145,10 @@ func TestIsValidatorAction(t *testing.T) { big.NewInt(0), 0, big.NewInt(0), data, ) - assert.True(t, bor.IsValidatorAction(chain, addr, tx)) + assert.True(t, engine.(*bor.Bor).IsValidatorAction(chain, addr, tx)) } -func buildEthereumInstance(t *testing.T, db ethdb.Database) *eth.Ethereum { +func buildEthereumInstance(t *testing.T, db ethdb.Database) (*initializeData) { genesisData, err := ioutil.ReadFile("genesis.json") if err != nil { t.Fatalf("%s", err) @@ -98,5 +193,9 @@ func buildEthereumInstance(t *testing.T, db ethdb.Database) *eth.Ethereum { var ethereum *eth.Ethereum stack.Service(ðereum) - return ethereum + + return &initializeData{ + genesis: gen, + ethereum: ethereum, + } } diff --git a/consensus/bor_test/genesis.json b/consensus/bor_test/genesis.json index 84a293ff05a7..737cb600dd80 100644 --- a/consensus/bor_test/genesis.json +++ b/consensus/bor_test/genesis.json @@ -11,7 +11,7 @@ "bor": { "period": 1, "producerDelay": 4, - "sprint": 64, + "sprint": 1, "validatorContract": "0x0000000000000000000000000000000000001000", "stateReceiverContract": "0x0000000000000000000000000000000000001001", "heimdall": "http://localhost:1317" diff --git a/consensus/bor_test/span.json b/consensus/bor_test/span.json new file mode 100644 index 000000000000..01e9427c47d5 --- /dev/null +++ b/consensus/bor_test/span.json @@ -0,0 +1,95 @@ +{ + "height": "42841", + "result": { + "span_id": 1, + "start_block": 256, + "end_block": 6655, + "validator_set": { + "validators": [{ + "ID": 3, + "startEpoch": 0, + "endEpoch": 0, + "power": 10000, + "pubKey": "0x046434e10a34ade13c4fea917346a9fd1473eac2138a0b4e2a36426871918be63188fde4edbf598457592c9a49fe3b0036dd5497079495d132e5045bf499c4bdb1", + "signer": "0x1c4f0f054a0d6a1415382dc0fd83c6535188b220", + "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, + "pubKey": "0x04a36f6ed1f93acb0a38f4cacbe2467c72458ac41ce3b12b34d758205b2bc5d930a4e059462da7a0976c32fce766e1f7e8d73933ae72ac2af231fe161187743932", + "signer": "0x836fe3e3dd0a5f77d9d5b0f67e48048aaafcd5a0", + "last_updated": 0, + "accum": 10000 + }, { + "ID": 1, + "startEpoch": 0, + "endEpoch": 0, + "power": 10000, + "pubKey": "0x04a312814042a6655c8e5ecf0c52cba0b6a6f3291c87cc42260a3c0222410c0d0d59b9139d1c56542e5df0ce2fce3a86ce13e93bd9bde0dc8ff664f8dd5294dead", + "signer": "0x925a91f8003aaeabea6037103123b93c50b86ca3", + "last_updated": 0, + "accum": 10000 + }, { + "ID": 2, + "startEpoch": 0, + "endEpoch": 0, + "power": 10000, + "pubKey": "0x0469536ae98030a7e83ec5ef3baffed2d05a32e31d978e58486f6bdb0fbbf240293838325116090190c0639db03f9cbd8b9aecfd269d016f46e3a2287fbf9ad232", + "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 + } + }, + "selected_producers": [{ + "ID": 5, + "startEpoch": 0, + "endEpoch": 0, + "power": 1, + "pubKey": "0x04a36f6ed1f93acb0a38f4cacbe2467c72458ac41ce3b12b34d758205b2bc5d930a4e059462da7a0976c32fce766e1f7e8d73933ae72ac2af231fe161187743932", + "signer": "0x836fe3e3dd0a5f77d9d5b0f67e48048aaafcd5a0", + "last_updated": 0, + "accum": 10000 + }, { + "ID": 1, + "startEpoch": 0, + "endEpoch": 0, + "power": 1, + "pubKey": "0x04a312814042a6655c8e5ecf0c52cba0b6a6f3291c87cc42260a3c0222410c0d0d59b9139d1c56542e5df0ce2fce3a86ce13e93bd9bde0dc8ff664f8dd5294dead", + "signer": "0x925a91f8003aaeabea6037103123b93c50b86ca3", + "last_updated": 0, + "accum": 10000 + }, { + "ID": 2, + "startEpoch": 0, + "endEpoch": 0, + "power": 2, + "pubKey": "0x0469536ae98030a7e83ec5ef3baffed2d05a32e31d978e58486f6bdb0fbbf240293838325116090190c0639db03f9cbd8b9aecfd269d016f46e3a2287fbf9ad232", + "signer": "0xc787af4624cb3e80ee23ae7faac0f2acea2be34c", + "last_updated": 0, + "accum": 10000 + }], + "bor_chain_id": "15001" + } +} diff --git a/mocks/IHeimdallClient.go b/mocks/IHeimdallClient.go new file mode 100644 index 000000000000..cb09800c746d --- /dev/null +++ b/mocks/IHeimdallClient.go @@ -0,0 +1,71 @@ +// Code generated by mockery v1.0.0. DO NOT EDIT. + +package mocks + +import ( + bor "github.com/maticnetwork/bor/consensus/bor" + mock "github.com/stretchr/testify/mock" +) + +// IHeimdallClient is an autogenerated mock type for the IHeimdallClient type +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...) + + var r0 *bor.ResponseWithHeight + if rf, ok := ret.Get(0).(func(...string) *bor.ResponseWithHeight); ok { + r0 = rf(paths...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*bor.ResponseWithHeight) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(...string) error); ok { + r1 = rf(paths...) + } else { + r1 = ret.Error(1) + } + + 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...) + + var r0 *bor.ResponseWithHeight + if rf, ok := ret.Get(0).(func(...string) *bor.ResponseWithHeight); ok { + r0 = rf(paths...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*bor.ResponseWithHeight) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(...string) error); ok { + r1 = rf(paths...) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} From 2d0b9ea63deeb33158b3b55f41b9fe7a813f7b88 Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Wed, 11 Mar 2020 21:25:25 +0530 Subject: [PATCH 07/12] try to use same statedb --- consensus/bor/bor.go | 5 +++-- consensus/bor_test/bor_test.go | 40 +++++++++++++++++++++------------- eth/api_backend.go | 2 ++ internal/ethapi/api.go | 1 + 4 files changed, 31 insertions(+), 17 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 68ecb362119d..3809edb17a11 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -665,7 +665,7 @@ func (c *Bor) Finalize(chain consensus.ChainReader, header *types.Header, state // commit span headerNumber := header.Number.Uint64() fmt.Println(header.Number, headerNumber % c.config.Sprint) - if headerNumber > 0 && + if /* headerNumber > 0 && */ headerNumber % c.config.Sprint == 0 { cx := chainContext{Chain: chain, Bor: c} fmt.Println("here 0.1") @@ -1002,6 +1002,7 @@ func (c *Bor) checkAndCommitSpan( go func() { var err error pending, err = c.isSpanPending(headerNumber - 1) + // pending, err = c.isSpanPending(headerNumber) errors <- err // wg.Done() }() @@ -1074,7 +1075,7 @@ func (c *Bor) fetchAndCommitSpan( if err := json.Unmarshal(response.Result, &heimdallSpan); err != nil { return err } - fmt.Println("here 4", heimdallSpan) + // fmt.Println("here 4", heimdallSpan) // check if chain id matches with heimdall span if heimdallSpan.ChainID != c.chainConfig.ChainID.String() { return fmt.Errorf( diff --git a/consensus/bor_test/bor_test.go b/consensus/bor_test/bor_test.go index f959f07cb0ab..6517e7b126a6 100644 --- a/consensus/bor_test/bor_test.go +++ b/consensus/bor_test/bor_test.go @@ -17,7 +17,7 @@ import ( "github.com/maticnetwork/bor/consensus/bor" "github.com/maticnetwork/bor/core" "github.com/maticnetwork/bor/core/rawdb" - "github.com/maticnetwork/bor/core/state" + // "github.com/maticnetwork/bor/core/state" "github.com/maticnetwork/bor/core/types" // "github.com/maticnetwork/bor/core/vm" "github.com/maticnetwork/bor/crypto" @@ -35,11 +35,11 @@ type initializeData struct { func TestCommitSpan(t *testing.T) { var ( - db = rawdb.NewMemoryDatabase() + // db = rawdb.NewMemoryDatabase() // key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") // addr = crypto.PubkeyToAddress(key.PublicKey) ) - init := buildEthereumInstance(t, db) + init := buildEthereumInstance(t, rawdb.NewMemoryDatabase()) chain := init.ethereum.BlockChain() engine := init.ethereum.Engine() _bor := engine.(*bor.Bor) @@ -56,8 +56,10 @@ func TestCommitSpan(t *testing.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) - statedb, _ := state.New(block.Root(), state.NewDatabase(db)) + statedb, err := chain.StateAt(block.Root()) + // statedb, _ := state.New(block.Root(), state.NewDatabase(db)) // _, _, _, err = chain.Processor().Process(block, statedb, vm.Config{}) // fmt.Println(err) // _bor.Finalize(chain, block.Header(), statedb, nil, nil) @@ -69,9 +71,17 @@ func TestCommitSpan(t *testing.T) { header := block.Header() header.Number = big.NewInt(1) header.ParentHash = block.Hash() + fmt.Println(block.Hash()) + // header.Hash = block = types.NewBlockWithHeader(header) + + fmt.Println("statedb.IntermediateRoot", statedb.IntermediateRoot(true)) _bor.Finalize(chain, block.Header(), statedb, nil, nil) // _, _, _, err = chain.Processor().Process(block, statedb, vm.Config{}) + fmt.Println("statedb.IntermediateRoot 2", statedb.IntermediateRoot(true)) + statedb, err = chain.StateAt(block.Root()) + fmt.Println("statedb.IntermediateRoot 3", statedb.IntermediateRoot(true)) + if err != nil { t.Fatalf("%s", err) } @@ -81,24 +91,24 @@ func TestCommitSpan(t *testing.T) { // status, err := chain.writeBlockWithState(block, receipts, statedb) // chain.chainmu.Lock() - k := big.NewInt(0) - k.Add(block.Difficulty(), chain.GetTdByHash(block.ParentHash())) - fmt.Println("k", k) + td := big.NewInt(0) + td.Add(block.Difficulty(), chain.GetTdByHash(block.ParentHash())) + fmt.Println("td", td) rawdb.WriteTd(db, block.Hash(), block.NumberU64(), - k, + td, ) rawdb.WriteBlock(db, block) - root, err := statedb.Commit(true /* false ??*/) + root, err := statedb.Commit(false) fmt.Println("root", root) if err != nil { t.Fatalf("%s", err) } - if err := statedb.Reset(root); err != nil { - t.Fatalf("state reset after block %d failed: %v", block.NumberU64(), err) - } + // if err := statedb.Reset(root); err != nil { + // t.Fatalf("state reset after block %d failed: %v", block.NumberU64(), err) + // } // blockchain.chainmu.Unlock() assert.True(t, h.AssertNumberOfCalls(t, "FetchWithRetry", 1)) @@ -111,8 +121,8 @@ func TestCommitSpan(t *testing.T) { validators, _ = _bor.GetCurrentValidators(0, 256) fmt.Println(4, validators) - // validators, _ = _bor.GetCurrentValidators(1, 256) - // fmt.Println(4, validators) + validators, _ = _bor.GetCurrentValidators(1, 256) + fmt.Println(4, validators) // engine } @@ -193,7 +203,7 @@ func buildEthereumInstance(t *testing.T, db ethdb.Database) (*initializeData) { var ethereum *eth.Ethereum stack.Service(ðereum) - + ethConf.Genesis.MustCommit(ethereum.ChainDb()) return &initializeData{ genesis: gen, ethereum: ethereum, diff --git a/eth/api_backend.go b/eth/api_backend.go index dbb57207d6b7..6034f98f396a 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -19,6 +19,7 @@ package eth import ( "context" "errors" + "fmt" "math/big" "github.com/maticnetwork/bor/accounts" @@ -101,6 +102,7 @@ func (b *EthAPIBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc. return nil, nil, err } if header == nil { + fmt.Println("yoyo") return nil, nil, errors.New("header not found") } stateDb, err := b.eth.BlockChain().StateAt(header.Root) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 2a939ed2c463..58eb78bb5a52 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -730,6 +730,7 @@ func DoCall(ctx context.Context, b Backend, args CallArgs, blockNr rpc.BlockNumb defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now()) state, header, err := b.StateAndHeaderByNumber(ctx, blockNr) + fmt.Println("statedb.IntermediateRoot in DoCall", state.IntermediateRoot(true)) if state == nil || err != nil { return nil, 0, false, err } From e6de60b80ee74540a9440e9f7c011f6df678cb41 Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Mon, 16 Mar 2020 20:17:48 +0530 Subject: [PATCH 08/12] TestCommitSpan finally works --- consensus/bor/bor.go | 44 ++++---------- consensus/bor_test/bor_test.go | 108 ++++++++++++--------------------- consensus/bor_test/span.json | 6 +- crypto/secp256k1/secp256.go | 1 + eth/api_backend.go | 2 - internal/ethapi/api.go | 2 +- les/api_backend.go | 3 + 7 files changed, 59 insertions(+), 107 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 3809edb17a11..590d19c9d426 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -327,7 +327,6 @@ func (c *Bor) verifyHeader(chain consensus.ChainReader, header *types.Header, pa return errUnknownBlock } number := header.Number.Uint64() - // Don't waste time checking blocks from the future if header.Time > uint64(time.Now().Unix()) { return consensus.ErrFutureBlock @@ -339,10 +338,8 @@ func (c *Bor) verifyHeader(chain consensus.ChainReader, header *types.Header, pa if len(header.Extra) < extraVanity+extraSeal { return errMissingSignature } - // check extr adata isSprintEnd := (number+1)%c.config.Sprint == 0 - // Ensure that the extra-data contains a signer list on checkpoint, but none otherwise signersBytes := len(header.Extra) - extraVanity - extraSeal if !isSprintEnd && signersBytes != 0 { @@ -428,6 +425,7 @@ func (c *Bor) verifyCascadingFields(chain consensus.ChainReader, header *types.H } // All basic checks passed, verify the seal and return + // return nil return c.verifySeal(chain, header, parents) } @@ -564,7 +562,6 @@ func (c *Bor) verifySeal(chain consensus.ChainReader, header *types.Header, pare if err != nil { return err } - if !snap.ValidatorSet.HasAddress(signer.Bytes()) { return errUnauthorizedSigner } @@ -664,25 +661,22 @@ func (c *Bor) Prepare(chain consensus.ChainReader, header *types.Header) error { 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() - fmt.Println(header.Number, headerNumber % c.config.Sprint) + + // @todo check if this is required if /* headerNumber > 0 && */ - headerNumber % c.config.Sprint == 0 { + headerNumber%c.config.Sprint == 0 { cx := chainContext{Chain: chain, Bor: c} - fmt.Println("here 0.1") // check and commit span if err := c.checkAndCommitSpan(state, header, cx); err != nil { fmt.Println("Error while committing span", err) log.Error("Error while committing span", "error", err) return } - fmt.Println("here 11") // commit statees - // if err := c.CommitStates(state, header, cx); err != nil { - // log.Error("Error while committing states", "error", err) - // fmt.Println("here 12", err) - // return - // } - fmt.Println("here 12") + if err := c.CommitStates(state, header, cx); err != nil { + log.Error("Error while committing states", "error", err) + return + } } // No block rewards in PoA, so the state remains as is and uncles are dropped @@ -1017,21 +1011,15 @@ func (c *Bor) checkAndCommitSpan( var err error for i := 0; i < 2; i++ { - err = <- errors + err = <-errors if err != nil { - // fmt.Println(i, err) return err } } - fmt.Println("here 1") - // commit span if there is new span pending or span is ending or end block is not set if pending || c.needToCommitSpan(span, headerNumber) { - fmt.Println("here 2", span) - err := c.fetchAndCommitSpan(span.ID + 1, state, header, chain) - // err := c.commitSpan(span, state, header, chain) - fmt.Println("here 10", err) + err := c.fetchAndCommitSpan(span.ID+1, state, header, chain) return err } @@ -1039,8 +1027,6 @@ func (c *Bor) checkAndCommitSpan( } func (c *Bor) needToCommitSpan(span *Span, headerNumber uint64) bool { - fmt.Println("span", span) - // if span is nil if span == nil { return false @@ -1066,7 +1052,7 @@ func (c *Bor) fetchAndCommitSpan( chain core.ChainContext, ) error { response, err := c.HeimdallClient.FetchWithRetry("bor", "span", strconv.FormatUint(newSpanID, 10)) - fmt.Println("here 3") + if err != nil { return err } @@ -1075,7 +1061,6 @@ func (c *Bor) fetchAndCommitSpan( if err := json.Unmarshal(response.Result, &heimdallSpan); err != nil { return err } - // fmt.Println("here 4", heimdallSpan) // check if chain id matches with heimdall span if heimdallSpan.ChainID != c.chainConfig.ChainID.String() { return fmt.Errorf( @@ -1084,7 +1069,6 @@ func (c *Bor) fetchAndCommitSpan( c.chainConfig.ChainID, ) } - fmt.Println("here 5") // get validators bytes var validators []MinimalVal for _, val := range heimdallSpan.ValidatorSet.Validators { @@ -1094,7 +1078,6 @@ func (c *Bor) fetchAndCommitSpan( if err != nil { return err } - fmt.Println("here 6") // get producers bytes var producers []MinimalVal for _, val := range heimdallSpan.SelectedProducers { @@ -1114,7 +1097,6 @@ func (c *Bor) fetchAndCommitSpan( "validatorBytes", hex.EncodeToString(validatorBytes), "producerBytes", hex.EncodeToString(producerBytes), ) - fmt.Println("here 7") // get packed data data, err := c.validatorSetABI.Pack(method, big.NewInt(0).SetUint64(heimdallSpan.ID), @@ -1127,10 +1109,8 @@ func (c *Bor) fetchAndCommitSpan( log.Error("Unable to pack tx for commitSpan", "error", err) return err } - fmt.Println("here 8") // get system message msg := getSystemMessage(common.HexToAddress(c.config.ValidatorContract), data) - fmt.Println("here 9") // apply message return applyMessage(msg, state, header, c.chainConfig, chain) } @@ -1357,10 +1337,8 @@ func applyMessage( msg.Gas(), msg.Value(), ) - fmt.Println("here 9.1", err) // Update the state with pending changes if err != nil { - fmt.Println("here 9.2", err) state.Finalise(true) } return nil diff --git a/consensus/bor_test/bor_test.go b/consensus/bor_test/bor_test.go index 6517e7b126a6..afb88ca54c9b 100644 --- a/consensus/bor_test/bor_test.go +++ b/consensus/bor_test/bor_test.go @@ -3,23 +3,18 @@ package bor_test import ( "encoding/hex" "encoding/json" - "fmt" - - // "fmt" "io/ioutil" "math/big" "testing" "github.com/stretchr/testify/assert" - // "github.com/stretchr/testify/mock" - "github.com/maticnetwork/bor/common" "github.com/maticnetwork/bor/consensus/bor" "github.com/maticnetwork/bor/core" "github.com/maticnetwork/bor/core/rawdb" - // "github.com/maticnetwork/bor/core/state" + "github.com/maticnetwork/bor/crypto/secp256k1" + "github.com/maticnetwork/bor/core/types" - // "github.com/maticnetwork/bor/core/vm" "github.com/maticnetwork/bor/crypto" "github.com/maticnetwork/bor/eth" @@ -28,22 +23,22 @@ import ( "github.com/maticnetwork/bor/node" ) +const ( + extraSeal = 65 // Fixed number of extra-data suffix bytes reserved for signer seal +) + type initializeData struct { - genesis *core.Genesis + genesis *core.Genesis ethereum *eth.Ethereum } func TestCommitSpan(t *testing.T) { - var ( - // db = rawdb.NewMemoryDatabase() - // key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - // addr = crypto.PubkeyToAddress(key.PublicKey) - ) init := buildEthereumInstance(t, rawdb.NewMemoryDatabase()) chain := init.ethereum.BlockChain() engine := init.ethereum.Engine() _bor := engine.(*bor.Bor) + // Mock HeimdallClient.FetchWithRetry to return span data from span.json spanData, err := ioutil.ReadFile("span.json") if err != nil { t.Fatalf("%s", err) @@ -52,78 +47,55 @@ func TestCommitSpan(t *testing.T) { if err := json.Unmarshal(spanData, res); err != nil { t.Fatalf("%s", err) } - h := &mocks.IHeimdallClient{} h.On("FetchWithRetry", "bor", "span", "1").Return(res, nil) _bor.SetHeimdallClient(h) + + // Build 1st blocks header db := init.ethereum.ChainDb() block := init.genesis.ToBlock(db) - statedb, err := chain.StateAt(block.Root()) - // statedb, _ := state.New(block.Root(), state.NewDatabase(db)) - // _, _, _, err = chain.Processor().Process(block, statedb, vm.Config{}) - // fmt.Println(err) - // _bor.Finalize(chain, block.Header(), statedb, nil, nil) - - api := bor.NewBorApi(chain, _bor) - validators, _ := api.GetCurrentValidators() - fmt.Println(1, validators) - - header := block.Header() + header := block.Header() // get 0th block header and mutate it as required header.Number = big.NewInt(1) header.ParentHash = block.Hash() - fmt.Println(block.Hash()) - // header.Hash = - block = types.NewBlockWithHeader(header) - - fmt.Println("statedb.IntermediateRoot", statedb.IntermediateRoot(true)) - _bor.Finalize(chain, block.Header(), statedb, nil, nil) - // _, _, _, err = chain.Processor().Process(block, statedb, vm.Config{}) - fmt.Println("statedb.IntermediateRoot 2", statedb.IntermediateRoot(true)) - statedb, err = chain.StateAt(block.Root()) - fmt.Println("statedb.IntermediateRoot 3", statedb.IntermediateRoot(true)) + header.Time += (init.genesis.Config.Bor.Period + 1) + header.Extra = make([]byte, 97) // vanity (32) + extraSeal (65) + privKey, _ := hex.DecodeString("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + statedb, err := chain.State() if err != nil { t.Fatalf("%s", err) } - // fmt.Println(header.Number) - // _bor.Finalize(chain, header, statedb, nil, nil) - - // status, err := chain.writeBlockWithState(block, receipts, statedb) - // chain.chainmu.Lock() - td := big.NewInt(0) - td.Add(block.Difficulty(), chain.GetTdByHash(block.ParentHash())) - fmt.Println("td", td) - - rawdb.WriteTd(db, - block.Hash(), - block.NumberU64(), - td, - ) - rawdb.WriteBlock(db, block) - root, err := statedb.Commit(false) - fmt.Println("root", root) + block, err = _bor.FinalizeAndAssemble(chain, header, statedb, nil, nil, nil) if err != nil { t.Fatalf("%s", err) } - // if err := statedb.Reset(root); err != nil { - // t.Fatalf("state reset after block %d failed: %v", block.NumberU64(), err) - // } - // blockchain.chainmu.Unlock() - assert.True(t, h.AssertNumberOfCalls(t, "FetchWithRetry", 1)) - validators, _ = api.GetCurrentValidators() - fmt.Println(2, validators) + 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) - validators, _ = _bor.GetCurrentValidators(0, 255) - fmt.Println(3, validators) + block = types.NewBlockWithHeader(header) + if _, err := chain.InsertChain([]*types.Block{block}); err != nil { + t.Fatalf("%s", err) + } - validators, _ = _bor.GetCurrentValidators(0, 256) - fmt.Println(4, validators) + assert.True(t, h.AssertNumberOfCalls(t, "FetchWithRetry", 2)) + validators, err := _bor.GetCurrentValidators(1, 256) // new span starts at 256 + if err != nil { + t.Fatalf("%s", err) + } - validators, _ = _bor.GetCurrentValidators(1, 256) - fmt.Println(4, validators) - // engine + var heimdallSpan bor.HeimdallSpan + if err := json.Unmarshal(res.Result, &heimdallSpan); err != nil { + t.Fatalf("%s", err) + } + 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) + } } func TestIsValidatorAction(t *testing.T) { @@ -158,7 +130,7 @@ func TestIsValidatorAction(t *testing.T) { assert.True(t, engine.(*bor.Bor).IsValidatorAction(chain, addr, tx)) } -func buildEthereumInstance(t *testing.T, db ethdb.Database) (*initializeData) { +func buildEthereumInstance(t *testing.T, db ethdb.Database) *initializeData { genesisData, err := ioutil.ReadFile("genesis.json") if err != nil { t.Fatalf("%s", err) @@ -205,7 +177,7 @@ func buildEthereumInstance(t *testing.T, db ethdb.Database) (*initializeData) { stack.Service(ðereum) ethConf.Genesis.MustCommit(ethereum.ChainDb()) return &initializeData{ - genesis: gen, + genesis: gen, ethereum: ethereum, } } diff --git a/consensus/bor_test/span.json b/consensus/bor_test/span.json index 01e9427c47d5..f4be94eeb8bb 100644 --- a/consensus/bor_test/span.json +++ b/consensus/bor_test/span.json @@ -11,7 +11,7 @@ "endEpoch": 0, "power": 10000, "pubKey": "0x046434e10a34ade13c4fea917346a9fd1473eac2138a0b4e2a36426871918be63188fde4edbf598457592c9a49fe3b0036dd5497079495d132e5045bf499c4bdb1", - "signer": "0x1c4f0f054a0d6a1415382dc0fd83c6535188b220", + "signer": "0xc787af4624cb3e80ee23ae7faac0f2acea2be34c", "last_updated": 0, "accum": -40000 }, { @@ -47,7 +47,7 @@ "endEpoch": 0, "power": 10000, "pubKey": "0x0469536ae98030a7e83ec5ef3baffed2d05a32e31d978e58486f6bdb0fbbf240293838325116090190c0639db03f9cbd8b9aecfd269d016f46e3a2287fbf9ad232", - "signer": "0xc787af4624cb3e80ee23ae7faac0f2acea2be34c", + "signer": "0x1c4f0f054a0d6a1415382dc0fd83c6535188b220", "last_updated": 0, "accum": 10000 }], @@ -88,7 +88,7 @@ "pubKey": "0x0469536ae98030a7e83ec5ef3baffed2d05a32e31d978e58486f6bdb0fbbf240293838325116090190c0639db03f9cbd8b9aecfd269d016f46e3a2287fbf9ad232", "signer": "0xc787af4624cb3e80ee23ae7faac0f2acea2be34c", "last_updated": 0, - "accum": 10000 + "accum": 5000 }], "bor_chain_id": "15001" } diff --git a/crypto/secp256k1/secp256.go b/crypto/secp256k1/secp256.go index 35d0eef34ace..191e158f0596 100644 --- a/crypto/secp256k1/secp256.go +++ b/crypto/secp256k1/secp256.go @@ -59,6 +59,7 @@ func Sign(msg []byte, seckey []byte) ([]byte, error) { if len(msg) != 32 { return nil, ErrInvalidMsgLen } + if len(seckey) != 32 { return nil, ErrInvalidKey } diff --git a/eth/api_backend.go b/eth/api_backend.go index 6034f98f396a..dbb57207d6b7 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -19,7 +19,6 @@ package eth import ( "context" "errors" - "fmt" "math/big" "github.com/maticnetwork/bor/accounts" @@ -102,7 +101,6 @@ func (b *EthAPIBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc. return nil, nil, err } if header == nil { - fmt.Println("yoyo") return nil, nil, errors.New("header not found") } stateDb, err := b.eth.BlockChain().StateAt(header.Root) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 58eb78bb5a52..7b56ba612e2d 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -730,7 +730,7 @@ func DoCall(ctx context.Context, b Backend, args CallArgs, blockNr rpc.BlockNumb defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now()) state, header, err := b.StateAndHeaderByNumber(ctx, blockNr) - fmt.Println("statedb.IntermediateRoot in DoCall", state.IntermediateRoot(true)) + // fmt.Println("statedb.IntermediateRoot in DoCall", state.IntermediateRoot(false).Hex()) if state == nil || err != nil { return nil, 0, false, err } diff --git a/les/api_backend.go b/les/api_backend.go index 8333fdd8c37f..4c6ee1f7a7f4 100644 --- a/les/api_backend.go +++ b/les/api_backend.go @@ -19,6 +19,7 @@ package les import ( "context" "errors" + "fmt" "math/big" "github.com/maticnetwork/bor/accounts" @@ -60,8 +61,10 @@ func (b *LesApiBackend) SetHead(number uint64) { func (b *LesApiBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) { if blockNr == rpc.LatestBlockNumber || blockNr == rpc.PendingBlockNumber { + fmt.Println("20") return b.eth.blockchain.CurrentHeader(), nil } + fmt.Println("21") return b.eth.blockchain.GetHeaderByNumberOdr(ctx, uint64(blockNr)) } From 2ea69833dd2e5300dccdde5bd5c60a2d8e59d20c Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Mon, 16 Mar 2020 20:52:09 +0530 Subject: [PATCH 09/12] Cleanup debug statements --- consensus/bor/api.go | 4 ---- consensus/bor/bor.go | 29 +++++++++++++---------------- crypto/secp256k1/secp256.go | 1 - internal/ethapi/api.go | 1 - les/api_backend.go | 3 --- 5 files changed, 13 insertions(+), 25 deletions(-) diff --git a/consensus/bor/api.go b/consensus/bor/api.go index d1d151c216a5..98f7c46b6e61 100644 --- a/consensus/bor/api.go +++ b/consensus/bor/api.go @@ -30,10 +30,6 @@ type API struct { bor *Bor } -func NewBorApi(chain consensus.ChainReader, bor *Bor) API { - return API{chain: chain, bor: bor} -} - // GetSnapshot retrieves the state snapshot at a given block. func (api *API) GetSnapshot(number *rpc.BlockNumber) (*Snapshot, error) { // Retrieve the requested block number (or current if none requested) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 590d19c9d426..127a396854c8 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -11,7 +11,6 @@ import ( "math" "math/big" - // "net/http" "sort" "strconv" "strings" @@ -327,6 +326,7 @@ func (c *Bor) verifyHeader(chain consensus.ChainReader, header *types.Header, pa return errUnknownBlock } number := header.Number.Uint64() + // Don't waste time checking blocks from the future if header.Time > uint64(time.Now().Unix()) { return consensus.ErrFutureBlock @@ -338,8 +338,10 @@ func (c *Bor) verifyHeader(chain consensus.ChainReader, header *types.Header, pa if len(header.Extra) < extraVanity+extraSeal { return errMissingSignature } + // check extr adata isSprintEnd := (number+1)%c.config.Sprint == 0 + // Ensure that the extra-data contains a signer list on checkpoint, but none otherwise signersBytes := len(header.Extra) - extraVanity - extraSeal if !isSprintEnd && signersBytes != 0 { @@ -425,7 +427,6 @@ func (c *Bor) verifyCascadingFields(chain consensus.ChainReader, header *types.H } // All basic checks passed, verify the seal and return - // return nil return c.verifySeal(chain, header, parents) } @@ -562,6 +563,7 @@ func (c *Bor) verifySeal(chain consensus.ChainReader, header *types.Header, pare if err != nil { return err } + if !snap.ValidatorSet.HasAddress(signer.Bytes()) { return errUnauthorizedSigner } @@ -662,13 +664,10 @@ func (c *Bor) Finalize(chain consensus.ChainReader, header *types.Header, state // commit span headerNumber := header.Number.Uint64() - // @todo check if this is required - if /* headerNumber > 0 && */ - headerNumber%c.config.Sprint == 0 { + if headerNumber%c.config.Sprint == 0 { cx := chainContext{Chain: chain, Bor: c} // check and commit span if err := c.checkAndCommitSpan(state, header, cx); err != nil { - fmt.Println("Error while committing span", err) log.Error("Error while committing span", "error", err) return } @@ -991,22 +990,16 @@ func (c *Bor) checkAndCommitSpan( pending := false var span *Span = nil errors := make(chan error) - // var wg sync.WaitGroup - // wg.Add(1) go func() { var err error pending, err = c.isSpanPending(headerNumber - 1) - // pending, err = c.isSpanPending(headerNumber) errors <- err - // wg.Done() }() - // wg.Add(1) go func() { var err error span, err = c.GetCurrentSpan(headerNumber - 1) errors <- err - // wg.Done() }() var err error @@ -1061,6 +1054,7 @@ func (c *Bor) fetchAndCommitSpan( if err := json.Unmarshal(response.Result, &heimdallSpan); err != nil { return err } + // check if chain id matches with heimdall span if heimdallSpan.ChainID != c.chainConfig.ChainID.String() { return fmt.Errorf( @@ -1069,6 +1063,7 @@ func (c *Bor) fetchAndCommitSpan( c.chainConfig.ChainID, ) } + // get validators bytes var validators []MinimalVal for _, val := range heimdallSpan.ValidatorSet.Validators { @@ -1078,6 +1073,7 @@ func (c *Bor) fetchAndCommitSpan( if err != nil { return err } + // get producers bytes var producers []MinimalVal for _, val := range heimdallSpan.SelectedProducers { @@ -1097,6 +1093,7 @@ func (c *Bor) fetchAndCommitSpan( "validatorBytes", hex.EncodeToString(validatorBytes), "producerBytes", hex.EncodeToString(producerBytes), ) + // get packed data data, err := c.validatorSetABI.Pack(method, big.NewInt(0).SetUint64(heimdallSpan.ID), @@ -1109,8 +1106,10 @@ func (c *Bor) fetchAndCommitSpan( log.Error("Unable to pack tx for commitSpan", "error", err) return err } + // get system message msg := getSystemMessage(common.HexToAddress(c.config.ValidatorContract), data) + // apply message return applyMessage(msg, state, header, c.chainConfig, chain) } @@ -1235,6 +1234,7 @@ func (c *Bor) IsValidatorAction(chain consensus.ChainReader, from common.Address snap, err := c.snapshot(chain, header.Number.Uint64(), header.Hash(), nil) if err != nil { log.Error("Failed fetching snapshot", err) + return false } isValidator := false @@ -1276,10 +1276,6 @@ type chainContext struct { Bor consensus.Engine } -// func NewChainContext(chain consensus.ChainReader, bor consensus.Engine) (chainContext) { -// return {Chain: chain, Bor: bor} -// } - func (c chainContext) Engine() consensus.Engine { return c.Bor } @@ -1341,6 +1337,7 @@ func applyMessage( if err != nil { state.Finalise(true) } + return nil } diff --git a/crypto/secp256k1/secp256.go b/crypto/secp256k1/secp256.go index 191e158f0596..35d0eef34ace 100644 --- a/crypto/secp256k1/secp256.go +++ b/crypto/secp256k1/secp256.go @@ -59,7 +59,6 @@ func Sign(msg []byte, seckey []byte) ([]byte, error) { if len(msg) != 32 { return nil, ErrInvalidMsgLen } - if len(seckey) != 32 { return nil, ErrInvalidKey } diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 7b56ba612e2d..2a939ed2c463 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -730,7 +730,6 @@ func DoCall(ctx context.Context, b Backend, args CallArgs, blockNr rpc.BlockNumb defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now()) state, header, err := b.StateAndHeaderByNumber(ctx, blockNr) - // fmt.Println("statedb.IntermediateRoot in DoCall", state.IntermediateRoot(false).Hex()) if state == nil || err != nil { return nil, 0, false, err } diff --git a/les/api_backend.go b/les/api_backend.go index 4c6ee1f7a7f4..8333fdd8c37f 100644 --- a/les/api_backend.go +++ b/les/api_backend.go @@ -19,7 +19,6 @@ package les import ( "context" "errors" - "fmt" "math/big" "github.com/maticnetwork/bor/accounts" @@ -61,10 +60,8 @@ func (b *LesApiBackend) SetHead(number uint64) { func (b *LesApiBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) { if blockNr == rpc.LatestBlockNumber || blockNr == rpc.PendingBlockNumber { - fmt.Println("20") return b.eth.blockchain.CurrentHeader(), nil } - fmt.Println("21") return b.eth.blockchain.GetHeaderByNumberOdr(ctx, uint64(blockNr)) } From d56c75d90a7c845c2b1fefdd381db2f037eff418 Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Tue, 17 Mar 2020 16:58:47 +0530 Subject: [PATCH 10/12] Test isValidatorAction after span changes --- consensus/bor/bor.go | 10 +- consensus/bor_test/bor_test.go | 184 +++++++++++++++++++++++---------- 2 files changed, 133 insertions(+), 61 deletions(-) diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go index 127a396854c8..d84288d42900 100644 --- a/consensus/bor/bor.go +++ b/consensus/bor/bor.go @@ -563,7 +563,6 @@ func (c *Bor) verifySeal(chain consensus.ChainReader, header *types.Header, pare if err != nil { return err } - if !snap.ValidatorSet.HasAddress(signer.Bytes()) { return errUnauthorizedSigner } @@ -1006,9 +1005,11 @@ func (c *Bor) checkAndCommitSpan( for i := 0; i < 2; i++ { err = <-errors if err != nil { + close(errors) 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) { @@ -1231,19 +1232,20 @@ func (c *Bor) SetHeimdallClient(h IHeimdallClient) { func (c *Bor) IsValidatorAction(chain consensus.ChainReader, from common.Address, tx *types.Transaction) bool { header := chain.CurrentHeader() - snap, err := c.snapshot(chain, header.Number.Uint64(), header.Hash(), nil) + 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 snap.ValidatorSet.Validators { + 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)) } @@ -1337,7 +1339,7 @@ func applyMessage( if err != nil { state.Finalise(true) } - + return nil } diff --git a/consensus/bor_test/bor_test.go b/consensus/bor_test/bor_test.go index afb88ca54c9b..88eb9245b556 100644 --- a/consensus/bor_test/bor_test.go +++ b/consensus/bor_test/bor_test.go @@ -7,12 +7,13 @@ import ( "math/big" "testing" - "github.com/stretchr/testify/assert" "github.com/maticnetwork/bor/common" "github.com/maticnetwork/bor/consensus/bor" "github.com/maticnetwork/bor/core" "github.com/maticnetwork/bor/core/rawdb" + "github.com/maticnetwork/bor/core/state" "github.com/maticnetwork/bor/crypto/secp256k1" + "github.com/stretchr/testify/assert" "github.com/maticnetwork/bor/core/types" "github.com/maticnetwork/bor/crypto" @@ -23,8 +24,11 @@ import ( "github.com/maticnetwork/bor/node" ) -const ( +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 ) type initializeData struct { @@ -39,48 +43,25 @@ func TestCommitSpan(t *testing.T) { _bor := engine.(*bor.Bor) // Mock HeimdallClient.FetchWithRetry to return span data from span.json - spanData, err := ioutil.ReadFile("span.json") - if err != nil { - t.Fatalf("%s", err) - } - res := &bor.ResponseWithHeight{} - if err := json.Unmarshal(spanData, res); err != nil { - t.Fatalf("%s", err) - } + res, heimdallSpan := loadSpanFromFile(t) h := &mocks.IHeimdallClient{} - h.On("FetchWithRetry", "bor", "span", "1").Return(res, nil) + h.On("FetchWithRetry", "bor", "span", "1"). + Return(res, nil). + Times(2) // both FinalizeAndAssemble and chain.InsertChain call HeimdallClient.FetchWithRetry. @todo Investigate this in depth _bor.SetHeimdallClient(h) - // Build 1st blocks header db := init.ethereum.ChainDb() block := init.genesis.ToBlock(db) - header := block.Header() // get 0th block header and mutate it as required - header.Number = big.NewInt(1) - header.ParentHash = block.Hash() - header.Time += (init.genesis.Config.Bor.Period + 1) - header.Extra = make([]byte, 97) // vanity (32) + extraSeal (65) - privKey, _ := hex.DecodeString("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + // Build 1st block's header + header := buildMinimalNextHeader(t, block, init.genesis.Config.Bor.Period) statedb, err := chain.State() if err != nil { t.Fatalf("%s", err) } - 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) - if _, err := chain.InsertChain([]*types.Block{block}); 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 @@ -88,10 +69,7 @@ func TestCommitSpan(t *testing.T) { t.Fatalf("%s", err) } - var heimdallSpan bor.HeimdallSpan - if err := json.Unmarshal(res.Result, &heimdallSpan); err != nil { - t.Fatalf("%s", err) - } + assert.Equal(t, len(validators), 3) 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) @@ -99,35 +77,78 @@ func TestCommitSpan(t *testing.T) { } func TestIsValidatorAction(t *testing.T) { - var ( - db = rawdb.NewMemoryDatabase() - key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - addr = crypto.PubkeyToAddress(key.PublicKey) - ) - init := buildEthereumInstance(t, db) - ethereum := init.ethereum - chain := ethereum.BlockChain() - engine := ethereum.Engine() - - // proposeState - data, _ := hex.DecodeString("ede01f170000000000000000000000000000000000000000000000000000000000000000") - tx := types.NewTransaction( + init := buildEthereumInstance(t, rawdb.NewMemoryDatabase()) + chain := init.ethereum.BlockChain() + engine := init.ethereum.Engine() + _bor := engine.(*bor.Bor) + + 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), - data, + proposeStateData, ) - assert.True(t, engine.(*bor.Bor).IsValidatorAction(chain, addr, tx)) + assert.True(t, _bor.IsValidatorAction(chain, addr, tx)) - // proposeSpan - data, _ = hex.DecodeString("4b0e4d17") tx = types.NewTransaction( 0, common.HexToAddress(chain.Config().Bor.ValidatorContract), big.NewInt(0), 0, big.NewInt(0), - data, + proposeSpanData, ) - assert.True(t, engine.(*bor.Bor).IsValidatorAction(chain, addr, tx)) + 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) + + // Build 1st block's header + db := init.ethereum.ChainDb() + block := init.genesis.ToBlock(db) + + header := buildMinimalNextHeader(t, block, init.genesis.Config.Bor.Period) + 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++ { + header := buildMinimalNextHeader(t, block, init.genesis.Config.Bor.Period) + 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) + } + + 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 buildEthereumInstance(t *testing.T, db ethdb.Database) *initializeData { @@ -139,7 +160,6 @@ func buildEthereumInstance(t *testing.T, db ethdb.Database) *initializeData { if err := json.Unmarshal(genesisData, gen); err != nil { t.Fatalf("%s", err) } - // chainConfig, _, err := core.SetupGenesisBlock(db, gen) ethConf := ð.Config{ Genesis: gen, } @@ -181,3 +201,53 @@ func buildEthereumInstance(t *testing.T, db ethdb.Database) *initializeData { ethereum: ethereum, } } + +func insertNewBlock(t *testing.T, _bor *bor.Bor, chain *core.BlockChain, header *types.Header, statedb *state.StateDB, privKey []byte) { + _, 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) + if _, err := chain.InsertChain([]*types.Block{block}); err != nil { + t.Fatalf("%s", err) + } +} + +func buildMinimalNextHeader(t *testing.T, block *types.Block, period uint64) *types.Header { + header := block.Header() + header.Number.Add(header.Number, big.NewInt(1)) + header.ParentHash = block.Hash() + header.Time += (period + 1) + header.Extra = make([]byte, 97) // vanity (32) + extraSeal (65) + _key, _ := hex.DecodeString(privKey) + sig, err := secp256k1.Sign(crypto.Keccak256(bor.BorRLP(header)), _key) + 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) { + spanData, err := ioutil.ReadFile("span.json") + if err != nil { + t.Fatalf("%s", err) + } + res := &bor.ResponseWithHeight{} + if err := json.Unmarshal(spanData, res); err != nil { + t.Fatalf("%s", err) + } + + heimdallSpan := &bor.HeimdallSpan{} + if err := json.Unmarshal(res.Result, heimdallSpan); err != nil { + t.Fatalf("%s", err) + } + return res, heimdallSpan +} From de889c13ed013d9c3c32396c5e7e5603b833f45b Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Wed, 18 Mar 2020 14:55:00 +0530 Subject: [PATCH 11/12] Add testify/mock modules and Add make test to circle config --- .circleci/config.yml | 2 ++ Makefile | 4 ++-- go.mod | 3 ++- go.sum | 6 ++++++ 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 331aa6d07256..39242f496cf4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -16,3 +16,5 @@ jobs: - checkout # check out source code to working directory - run: command: make bor + - run: + command: make test diff --git a/Makefile b/Makefile index 9f863193ea98..93a7a3ee2a11 100644 --- a/Makefile +++ b/Makefile @@ -29,8 +29,8 @@ ios: @echo "Done building." @echo "Import \"$(GOBIN)/bor.framework\" to use the library." -test: all - build/env.sh go run build/ci.go test +test: bor + go test github.com/maticnetwork/bor/consensus/bor_test lint: ## Run linters. build/env.sh go run build/ci.go lint diff --git a/go.mod b/go.mod index b305c65352e8..b9b765a52cea 100644 --- a/go.mod +++ b/go.mod @@ -51,7 +51,8 @@ require ( github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4 github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 // indirect - github.com/stretchr/testify v1.2.2 + github.com/stretchr/objx v0.2.0 // indirect + github.com/stretchr/testify v1.3.0 github.com/syndtr/goleveldb v1.0.1-0.20190318030020-c3a204f8e965 github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 diff --git a/go.sum b/go.sum index 4c4267f25fc2..c946c411bc40 100644 --- a/go.sum +++ b/go.sum @@ -19,6 +19,7 @@ github.com/btcsuite/btcd v0.0.0-20171128150713-2e60448ffcc6/go.mod h1:Dmm/EzmjnC github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea h1:j4317fAZh7X6GqbFowYdYdI0L9bwxL07jyPZIdepyZ0= @@ -131,8 +132,13 @@ github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 h1:gIlAHnH1 github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw= github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 h1:njlZPzLwU639dk2kqnCPPv+wNjq7Xb6EfUxe/oX0/NM= github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3/go.mod h1:hpGUWaI9xL8pRQCTXQgocU38Qw1g0Us7n5PxxTwTCYU= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/syndtr/goleveldb v1.0.1-0.20190318030020-c3a204f8e965 h1:1oFLiOyVl+W7bnBzGhf7BbIv9loSFQcieWWYIjLqcAw= github.com/syndtr/goleveldb v1.0.1-0.20190318030020-c3a204f8e965/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA= github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef h1:wHSqTBrZW24CsNJDfeh9Ex6Pm0Rcpc7qrgKBiL44vF4= From bd951981688d6c5012d19ebf3a1af3d099eb26e4 Mon Sep 17 00:00:00 2001 From: atvanguard <93arpit@gmail.com> Date: Wed, 18 Mar 2020 14:56:30 +0530 Subject: [PATCH 12/12] Remove Test section from README --- README.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/README.md b/README.md index cb7aff2a22c9..3ee31b5d3fd8 100644 --- a/README.md +++ b/README.md @@ -163,11 +163,6 @@ Ethereum nodes with exposed APIs! Further, all browser tabs can access locally running web servers, so malicious web pages could try to subvert locally available APIs!** -### Tests -``` -go test github.com/maticnetwork/bor/consensus/bor_test -``` - ## License The bor library (i.e. all code outside of the `cmd` directory) is licensed under the