diff --git a/.github/commitlint.config.js b/.github/commitlint.config.js new file mode 100644 index 0000000000..ee22a331bc --- /dev/null +++ b/.github/commitlint.config.js @@ -0,0 +1,44 @@ +const validateTypeNums = (parsedCommit) => { + const mergePrefix = "Merge pull request" + if (parsedCommit.raw.startsWith(mergePrefix)) { + console.log('this is a merge commit:' + parsedCommit.raw) + return [true,''] + } + + if (!parsedCommit.type) { + return [false, 'invalid commit message, should be like "name: descriptions.", yours: "' + parsedCommit.raw + '"'] + } + + const types = parsedCommit.type.split(' ') + for (var i=0;i 0 { packages = flag.CommandLine.Args() } @@ -342,12 +342,17 @@ func downloadLinter(cachedir string) string { csdb := build.MustLoadChecksums("build/checksums.txt") arch := runtime.GOARCH - if arch == "arm" { + ext := ".tar.gz" + + if runtime.GOOS == "windows" { + ext = ".zip" + } + if arch == "arm" { arch += "v" + os.Getenv("GOARM") } base := fmt.Sprintf("golangci-lint-%s-%s-%s", version, runtime.GOOS, arch) - url := fmt.Sprintf("https://github.com/golangci/golangci-lint/releases/download/v%s/%s.tar.gz", version, base) - archivePath := filepath.Join(cachedir, base+".tar.gz") + url := fmt.Sprintf("https://github.com/golangci/golangci-lint/releases/download/v%s/%s%s", version, base, ext) + archivePath := filepath.Join(cachedir, base+ext) if err := csdb.DownloadFile(url, archivePath); err != nil { log.Fatal(err) } diff --git a/cmd/geth/pruneblock_test.go b/cmd/geth/pruneblock_test.go index 78b1d343b5..6182c37b28 100644 --- a/cmd/geth/pruneblock_test.go +++ b/cmd/geth/pruneblock_test.go @@ -49,8 +49,8 @@ var ( blockPruneBackUpBlockNumber = 128 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") address = crypto.PubkeyToAddress(key.PublicKey) - balance = big.NewInt(10000000) - gspec = &core.Genesis{Config: params.TestChainConfig, Alloc: core.GenesisAlloc{address: {Balance: balance}}} + balance = big.NewInt(100000000000000000) + gspec = &core.Genesis{Config: params.TestChainConfig, Alloc: core.GenesisAlloc{address: {Balance: balance}}, BaseFee: big.NewInt(params.InitialBaseFee)} signer = types.LatestSigner(gspec.Config) config = &core.CacheConfig{ TrieCleanLimit: 256, @@ -93,7 +93,7 @@ func testOfflineBlockPruneWithAmountReserved(t *testing.T, amountReserved uint64 t.Fatalf("Failed to back up block: %v", err) } - dbBack, err := rawdb.NewLevelDBDatabaseWithFreezer(chaindbPath, 0, 0, newAncientPath, "", false, true, false, false) + dbBack, err := rawdb.NewLevelDBDatabaseWithFreezer(chaindbPath, 0, 0, newAncientPath, "", false, true, false, false, true) if err != nil { t.Fatalf("failed to create database with ancient backend") } @@ -139,7 +139,7 @@ func testOfflineBlockPruneWithAmountReserved(t *testing.T, amountReserved uint64 func BlockchainCreator(t *testing.T, chaindbPath, AncientPath string, blockRemain uint64) (ethdb.Database, []*types.Block, []*types.Block, []types.Receipts, []*big.Int, uint64, *core.BlockChain) { //create a database with ancient freezer - db, err := rawdb.NewLevelDBDatabaseWithFreezer(chaindbPath, 0, 0, AncientPath, "", false, false, false, false) + db, err := rawdb.NewLevelDBDatabaseWithFreezer(chaindbPath, 0, 0, AncientPath, "", false, false, false, false, true) if err != nil { t.Fatalf("failed to create database with ancient backend") } @@ -154,7 +154,7 @@ func BlockchainCreator(t *testing.T, chaindbPath, AncientPath string, blockRemai // Make chain starting from genesis blocks, _ := core.GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 500, func(i int, block *core.BlockGen) { block.SetCoinbase(common.Address{0: byte(canonicalSeed), 19: byte(i)}) - tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, nil, nil), signer, key) + tx, err := types.SignTx(types.NewTransaction(block.TxNonce(address), common.Address{0x00}, big.NewInt(1000), params.TxGas, big.NewInt(params.InitialBaseFee), nil), signer, key) if err != nil { panic(err) } diff --git a/cmd/geth/snapshot.go b/cmd/geth/snapshot.go index dd5d6e34fc..20d4f75fbd 100644 --- a/cmd/geth/snapshot.go +++ b/cmd/geth/snapshot.go @@ -601,8 +601,7 @@ func traverseState(ctx *cli.Context) error { } } if !bytes.Equal(acc.CodeHash, emptyCode) { - code := rawdb.ReadCode(chaindb, common.BytesToHash(acc.CodeHash)) - if len(code) == 0 { + if !rawdb.HasCode(chaindb, common.BytesToHash(acc.CodeHash)) { log.Error("Code is missing", "hash", common.BytesToHash(acc.CodeHash)) return errors.New("missing code") } @@ -673,11 +672,10 @@ func traverseRawState(ctx *cli.Context) error { nodes += 1 node := accIter.Hash() + // Check the present for non-empty hash node(embedded node doesn't + // have their own hash). if node != (common.Hash{}) { - // Check the present for non-empty hash node(embedded node doesn't - // have their own hash). - blob := rawdb.ReadTrieNode(chaindb, node) - if len(blob) == 0 { + if !rawdb.HasTrieNode(chaindb, node) { log.Error("Missing trie node(account)", "hash", node) return errors.New("missing account") } @@ -721,8 +719,7 @@ func traverseRawState(ctx *cli.Context) error { } } if !bytes.Equal(acc.CodeHash, emptyCode) { - code := rawdb.ReadCode(chaindb, common.BytesToHash(acc.CodeHash)) - if len(code) == 0 { + if !rawdb.HasCode(chaindb, common.BytesToHash(acc.CodeHash)) { log.Error("Code is missing", "account", common.BytesToHash(accIter.LeafKey())) return errors.New("missing code") } diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 5c58c542e7..41582d1fde 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -2020,7 +2020,7 @@ func MakeChainDatabase(ctx *cli.Context, stack *node.Node, readonly, disableFree chainDb, err = stack.OpenDatabase(name, cache, handles, "", readonly) } else { name := "chaindata" - chainDb, err = stack.OpenDatabaseWithFreezer(name, cache, handles, ctx.GlobalString(AncientFlag.Name), "", readonly, disableFreeze, false, false) + chainDb, err = stack.OpenDatabaseWithFreezer(name, cache, handles, ctx.GlobalString(AncientFlag.Name), "", readonly, disableFreeze, false, false, true) } if err != nil { Fatalf("Could not open database: %v", err) diff --git a/consensus/misc/eip1559_test.go b/consensus/misc/eip1559_test.go index 23cd9023de..aaa09da9b9 100644 --- a/consensus/misc/eip1559_test.go +++ b/consensus/misc/eip1559_test.go @@ -58,53 +58,53 @@ func config() *params.ChainConfig { // TestBlockGasLimits tests the gasLimit checks for blocks both across // the EIP-1559 boundary and post-1559 blocks -func TestBlockGasLimits(t *testing.T) { - initial := new(big.Int).SetUint64(params.InitialBaseFee) +// func TestBlockGasLimits(t *testing.T) { +// initial := new(big.Int).SetUint64(params.InitialBaseFee) - for i, tc := range []struct { - pGasLimit uint64 - pNum int64 - gasLimit uint64 - ok bool - }{ - // Transitions from non-london to london - {10000000, 4, 20000000, true}, // No change - {10000000, 4, 20019530, true}, // Upper limit - {10000000, 4, 20019531, false}, // Upper +1 - {10000000, 4, 19980470, true}, // Lower limit - {10000000, 4, 19980469, false}, // Lower limit -1 - // London to London - {20000000, 5, 20000000, true}, - {20000000, 5, 20019530, true}, // Upper limit - {20000000, 5, 20019531, false}, // Upper limit +1 - {20000000, 5, 19980470, true}, // Lower limit - {20000000, 5, 19980469, false}, // Lower limit -1 - {40000000, 5, 40039061, true}, // Upper limit - {40000000, 5, 40039062, false}, // Upper limit +1 - {40000000, 5, 39960939, true}, // lower limit - {40000000, 5, 39960938, false}, // Lower limit -1 - } { - parent := &types.Header{ - GasUsed: tc.pGasLimit / 2, - GasLimit: tc.pGasLimit, - BaseFee: initial, - Number: big.NewInt(tc.pNum), - } - header := &types.Header{ - GasUsed: tc.gasLimit / 2, - GasLimit: tc.gasLimit, - BaseFee: initial, - Number: big.NewInt(tc.pNum + 1), - } - err := VerifyEip1559Header(config(), parent, header) - if tc.ok && err != nil { - t.Errorf("test %d: Expected valid header: %s", i, err) - } - if !tc.ok && err == nil { - t.Errorf("test %d: Expected invalid header", i) - } - } -} +// for i, tc := range []struct { +// pGasLimit uint64 +// pNum int64 +// gasLimit uint64 +// ok bool +// }{ +// // Transitions from non-london to london +// {10000000, 4, 20000000, true}, // No change +// {10000000, 4, 20019530, true}, // Upper limit +// {10000000, 4, 20019531, false}, // Upper +1 +// {10000000, 4, 19980470, true}, // Lower limit +// {10000000, 4, 19980469, false}, // Lower limit -1 +// // London to London +// {20000000, 5, 20000000, true}, +// {20000000, 5, 20019530, true}, // Upper limit +// {20000000, 5, 20019531, false}, // Upper limit +1 +// {20000000, 5, 19980470, true}, // Lower limit +// {20000000, 5, 19980469, false}, // Lower limit -1 +// {40000000, 5, 40039061, true}, // Upper limit +// {40000000, 5, 40039062, false}, // Upper limit +1 +// {40000000, 5, 39960939, true}, // lower limit +// {40000000, 5, 39960938, false}, // Lower limit -1 +// } { +// parent := &types.Header{ +// GasUsed: tc.pGasLimit / 2, +// GasLimit: tc.pGasLimit, +// BaseFee: initial, +// Number: big.NewInt(tc.pNum), +// } +// header := &types.Header{ +// GasUsed: tc.gasLimit / 2, +// GasLimit: tc.gasLimit, +// BaseFee: initial, +// Number: big.NewInt(tc.pNum + 1), +// } +// err := VerifyEip1559Header(config(), parent, header) +// if tc.ok && err != nil { +// t.Errorf("test %d: Expected valid header: %s", i, err) +// } +// if !tc.ok && err == nil { +// t.Errorf("test %d: Expected invalid header", i) +// } +// } +// } // TestCalcBaseFee assumes all blocks are 1559-blocks func TestCalcBaseFee(t *testing.T) { diff --git a/consensus/parlia/parlia.go b/consensus/parlia/parlia.go index ab8a355774..33ed15a627 100644 --- a/consensus/parlia/parlia.go +++ b/consensus/parlia/parlia.go @@ -420,7 +420,7 @@ func (p *Parlia) verifyCascadingFields(chain consensus.ChainHeaderReader, header if diff < 0 { diff *= -1 } - limit := parent.GasLimit / params.ParliaGasLimitBoundDivisor + limit := parent.GasLimit / params.GasLimitBoundDivisor if uint64(diff) >= limit || header.GasLimit < params.MinGasLimit { return fmt.Errorf("invalid gas limit: have %d, want %d += %d", header.GasLimit, parent.GasLimit, limit) diff --git a/core/block_validator_test.go b/core/block_validator_test.go index 0f183ba527..6ea0e10cfc 100644 --- a/core/block_validator_test.go +++ b/core/block_validator_test.go @@ -377,8 +377,8 @@ func TestCalcGasLimit(t *testing.T) { max uint64 min uint64 }{ - {20000000, 20019530, 19980470}, - {40000000, 40039061, 39960939}, + {20000000, 20078124, 19921876}, + {40000000, 40156249, 39843751}, } { // Increase if have, want := CalcGasLimit(tc.pGasLimit, 2*tc.pGasLimit), tc.max; have != want { diff --git a/core/blockchain.go b/core/blockchain.go index 89059792f0..832eba973b 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1451,6 +1451,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types. // Calculate the total difficulty of the block ptd := bc.GetTd(block.ParentHash(), block.NumberU64()-1) if ptd == nil { + state.StopPrefetcher() return consensus.ErrUnknownAncestor } // Make sure no inconsistent state is leaked during insertion @@ -1809,17 +1810,6 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals, setHead bool) bc.reportBlock(block, nil, err) return it.index, err } - // No validation errors for the first block (or chain prefix skipped) - var activeState *state.StateDB - defer func() { - // The chain importer is starting and stopping trie prefetchers. If a bad - // block or other error is hit however, an early return may not properly - // terminate the background threads. This defer ensures that we clean up - // and dangling prefetcher, without defering each and holding on live refs. - if activeState != nil { - activeState.StopPrefetcher() - } - }() for ; block != nil && err == nil || errors.Is(err, ErrKnownBlock); block, err = it.next() { // If the chain is terminating, stop processing blocks @@ -1889,10 +1879,18 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals, setHead bool) interruptCh := make(chan struct{}) // For diff sync, it may fallback to full sync, so we still do prefetch if len(block.Transactions()) >= prefetchTxNumber { - throwaway := statedb.Copy() // do Prefetch in a separate goroutine to avoid blocking the critical path + + // 1.do state prefetch for snapshot cache + throwaway := statedb.CopyDoPrefetch() go bc.prefetcher.Prefetch(block, throwaway, &bc.vmConfig, interruptCh) + + // 2.do trie prefetch for MPT trie node cache + // it is for the big state trie tree, prefetch based on transaction's From/To address. + // trie prefetcher is thread safe now, ok to prefetch in a separate routine + go throwaway.TriePrefetchInAdvance(block, signer) } + //Process block using the parent state as reference point substart := time.Now() if bc.pipeCommit { @@ -1901,9 +1899,9 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals, setHead bool) statedb.SetExpectedStateRoot(block.Root()) statedb, receipts, logs, usedGas, err := bc.processor.Process(block, statedb, bc.vmConfig) close(interruptCh) // state prefetch can be stopped - activeState = statedb if err != nil { bc.reportBlock(block, receipts, err) + statedb.StopPrefetcher() return it.index, err } // Update the metrics touched during block processing @@ -1922,6 +1920,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, verifySeals, setHead bool) if err := bc.validator.ValidateState(block, statedb, receipts, usedGas); err != nil { log.Error("validate state failed", "error", err) bc.reportBlock(block, receipts, err) + statedb.StopPrefetcher() return it.index, err } } @@ -2911,6 +2910,9 @@ Error: %v // of the header retrieval mechanisms already need to verify nonces, as well as // because nonces can be verified sparsely, not needing to check each. func (bc *BlockChain) InsertHeaderChain(chain []*types.Header, checkFreq int) (int, error) { + if len(chain) == 0 { + return 0, nil + } start := time.Now() if i, err := bc.hc.ValidateHeaderChain(chain, checkFreq); err != nil { return i, err diff --git a/core/blockchain_repair_test.go b/core/blockchain_repair_test.go index 658c9a9d09..f56ed9fcdc 100644 --- a/core/blockchain_repair_test.go +++ b/core/blockchain_repair_test.go @@ -1762,7 +1762,7 @@ func testRepair(t *testing.T, tt *rewindTest, snapshots bool) { } os.RemoveAll(datadir) - db, err := rawdb.NewLevelDBDatabaseWithFreezer(datadir, 0, 0, datadir, "", false, false, false, false) + db, err := rawdb.NewLevelDBDatabaseWithFreezer(datadir, 0, 0, datadir, "", false, false, false, false, true) if err != nil { t.Fatalf("Failed to create persistent database: %v", err) } @@ -1833,7 +1833,7 @@ func testRepair(t *testing.T, tt *rewindTest, snapshots bool) { db.Close() // Start a new blockchain back up and see where the repait leads us - db, err = rawdb.NewLevelDBDatabaseWithFreezer(datadir, 0, 0, datadir, "", false, false, false, false) + db, err = rawdb.NewLevelDBDatabaseWithFreezer(datadir, 0, 0, datadir, "", false, false, false, false, true) if err != nil { t.Fatalf("Failed to reopen persistent database: %v", err) } @@ -1892,7 +1892,7 @@ func TestIssue23496(t *testing.T) { } os.RemoveAll(datadir) - db, err := rawdb.NewLevelDBDatabaseWithFreezer(datadir, 0, 0, datadir, "", false, false, false, false) + db, err := rawdb.NewLevelDBDatabaseWithFreezer(datadir, 0, 0, datadir, "", false, false, false, false, true) if err != nil { t.Fatalf("Failed to create persistent database: %v", err) } @@ -1949,7 +1949,7 @@ func TestIssue23496(t *testing.T) { db.Close() // Start a new blockchain back up and see where the repair leads us - db, err = rawdb.NewLevelDBDatabaseWithFreezer(datadir, 0, 0, datadir, "", false, false, false, false) + db, err = rawdb.NewLevelDBDatabaseWithFreezer(datadir, 0, 0, datadir, "", false, false, false, false, true) if err != nil { t.Fatalf("Failed to reopen persistent database: %v", err) } diff --git a/core/blockchain_sethead_test.go b/core/blockchain_sethead_test.go index 8cd87fd6db..7ee213b726 100644 --- a/core/blockchain_sethead_test.go +++ b/core/blockchain_sethead_test.go @@ -1961,7 +1961,7 @@ func testSetHead(t *testing.T, tt *rewindTest, snapshots bool) { } os.RemoveAll(datadir) - db, err := rawdb.NewLevelDBDatabaseWithFreezer(datadir, 0, 0, datadir, "", false, false, false, false) + db, err := rawdb.NewLevelDBDatabaseWithFreezer(datadir, 0, 0, datadir, "", false, false, false, false, true) if err != nil { t.Fatalf("Failed to create persistent database: %v", err) } diff --git a/core/blockchain_snapshot_test.go b/core/blockchain_snapshot_test.go index 23f4ff9af6..bc217fd80d 100644 --- a/core/blockchain_snapshot_test.go +++ b/core/blockchain_snapshot_test.go @@ -65,7 +65,7 @@ func (basic *snapshotTestBasic) prepare(t *testing.T) (*BlockChain, []*types.Blo } os.RemoveAll(datadir) - db, err := rawdb.NewLevelDBDatabaseWithFreezer(datadir, 0, 0, datadir, "", false, false, false, false) + db, err := rawdb.NewLevelDBDatabaseWithFreezer(datadir, 0, 0, datadir, "", false, false, false, false, true) if err != nil { t.Fatalf("Failed to create persistent database: %v", err) } @@ -249,7 +249,7 @@ func (snaptest *crashSnapshotTest) test(t *testing.T) { db.Close() // Start a new blockchain back up and see where the repair leads us - newdb, err := rawdb.NewLevelDBDatabaseWithFreezer(snaptest.datadir, 0, 0, snaptest.datadir, "", false, false, false, false) + newdb, err := rawdb.NewLevelDBDatabaseWithFreezer(snaptest.datadir, 0, 0, snaptest.datadir, "", false, false, false, false, true) if err != nil { t.Fatalf("Failed to reopen persistent database: %v", err) } diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 83aae79390..e0e6f9e03c 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -903,7 +903,7 @@ func TestFastVsFullChains(t *testing.T) { t.Fatalf("failed to create temp freezer dir: %v", err) } defer os.Remove(frdir) - ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false, false, false, false) + ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false, false, false, false, true) if err != nil { t.Fatalf("failed to create temp freezer db: %v", err) } @@ -999,7 +999,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) { t.Fatalf("failed to create temp freezer dir: %v", err) } defer os.Remove(dir) - db, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), dir, "", false, false, false, false) + db, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), dir, "", false, false, false, false, true) if err != nil { t.Fatalf("failed to create temp freezer db: %v", err) } @@ -1866,7 +1866,7 @@ func TestBlockchainRecovery(t *testing.T) { } defer os.Remove(frdir) - ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false, false, false, false) + ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false, false, false, false, true) if err != nil { t.Fatalf("failed to create temp freezer db: %v", err) } @@ -1937,7 +1937,7 @@ func TestInsertReceiptChainRollback(t *testing.T) { t.Fatalf("failed to create temp freezer dir: %v", err) } defer os.Remove(frdir) - ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false, false, false, false) + ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false, false, false, false, true) if err != nil { t.Fatalf("failed to create temp freezer db: %v", err) } @@ -2203,7 +2203,7 @@ func testInsertKnownChainData(t *testing.T, typ string) { t.Fatalf("failed to create temp freezer dir: %v", err) } defer os.Remove(dir) - chaindb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), dir, "", false, false, false, false) + chaindb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), dir, "", false, false, false, false, true) if err != nil { t.Fatalf("failed to create temp freezer db: %v", err) } @@ -2367,7 +2367,7 @@ func testInsertKnownChainDataWithMerging(t *testing.T, typ string, mergeHeight i t.Fatalf("failed to create temp freezer dir: %v", err) } defer os.Remove(dir) - chaindb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), dir, "", false, false, false, false) + chaindb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), dir, "", false, false, false, false, true) if err != nil { t.Fatalf("failed to create temp freezer db: %v", err) } @@ -2677,7 +2677,7 @@ func TestTransactionIndices(t *testing.T) { t.Fatalf("failed to create temp freezer dir: %v", err) } defer os.Remove(frdir) - ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false, false, false, false) + ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false, false, false, false, true) if err != nil { t.Fatalf("failed to create temp freezer db: %v", err) } @@ -2705,7 +2705,7 @@ func TestTransactionIndices(t *testing.T) { // Init block chain with external ancients, check all needed indices has been indexed. limit := []uint64{0, 32, 64, 128} for _, l := range limit { - ancientDb, err = rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false, false, false, false) + ancientDb, err = rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false, false, false, false, true) if err != nil { t.Fatalf("failed to create temp freezer db: %v", err) } @@ -2725,7 +2725,7 @@ func TestTransactionIndices(t *testing.T) { } // Reconstruct a block chain which only reserves HEAD-64 tx indices - ancientDb, err = rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false, false, false, false) + ancientDb, err = rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false, false, false, false, true) if err != nil { t.Fatalf("failed to create temp freezer db: %v", err) } @@ -2804,7 +2804,7 @@ func TestSkipStaleTxIndicesInSnapSync(t *testing.T) { t.Fatalf("failed to create temp freezer dir: %v", err) } defer os.Remove(frdir) - ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false, false, false, false) + ancientDb, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), frdir, "", false, false, false, false, true) if err != nil { t.Fatalf("failed to create temp freezer db: %v", err) } diff --git a/core/rawdb/accessors_chain_test.go b/core/rawdb/accessors_chain_test.go index 7b6b5dca29..877dccfebb 100644 --- a/core/rawdb/accessors_chain_test.go +++ b/core/rawdb/accessors_chain_test.go @@ -441,7 +441,7 @@ func TestAncientStorage(t *testing.T) { } defer os.RemoveAll(frdir) - db, err := NewDatabaseWithFreezer(NewMemoryDatabase(), frdir, "", false, false, false, false) + db, err := NewDatabaseWithFreezer(NewMemoryDatabase(), frdir, "", false, false, false, false, true) if err != nil { t.Fatalf("failed to create database with ancient backend") } @@ -582,7 +582,7 @@ func BenchmarkWriteAncientBlocks(b *testing.B) { b.Fatalf("failed to create temp freezer dir: %v", err) } defer os.RemoveAll(frdir) - db, err := NewDatabaseWithFreezer(NewMemoryDatabase(), frdir, "", false, false, false, false) + db, err := NewDatabaseWithFreezer(NewMemoryDatabase(), frdir, "", false, false, false, false, true) if err != nil { b.Fatalf("failed to create database with ancient backend") } @@ -892,7 +892,7 @@ func TestHeadersRLPStorage(t *testing.T) { } defer os.Remove(frdir) - db, err := NewDatabaseWithFreezer(NewMemoryDatabase(), frdir, "", false, false, false, false) + db, err := NewDatabaseWithFreezer(NewMemoryDatabase(), frdir, "", false, false, false, false, true) if err != nil { t.Fatalf("failed to create database with ancient backend") } diff --git a/core/rawdb/accessors_state.go b/core/rawdb/accessors_state.go index a239d07667..41e21b6ca4 100644 --- a/core/rawdb/accessors_state.go +++ b/core/rawdb/accessors_state.go @@ -28,17 +28,6 @@ func ReadPreimage(db ethdb.KeyValueReader, hash common.Hash) []byte { return data } -// WritePreimages writes the provided set of preimages to the database. -func WritePreimages(db ethdb.KeyValueWriter, preimages map[common.Hash][]byte) { - for hash, preimage := range preimages { - if err := db.Put(preimageKey(hash), preimage); err != nil { - log.Crit("Failed to store trie preimage", "err", err) - } - } - preimageCounter.Inc(int64(len(preimages))) - preimageHitCounter.Inc(int64(len(preimages))) -} - // ReadCode retrieves the contract code of the provided code hash. func ReadCode(db ethdb.KeyValueReader, hash common.Hash) []byte { // Try with the prefixed code scheme first, if not then try with legacy @@ -47,7 +36,7 @@ func ReadCode(db ethdb.KeyValueReader, hash common.Hash) []byte { if len(data) != 0 { return data } - data, _ = db.Get(hash[:]) + data, _ = db.Get(hash.Bytes()) return data } @@ -59,6 +48,24 @@ func ReadCodeWithPrefix(db ethdb.KeyValueReader, hash common.Hash) []byte { return data } +// ReadTrieNode retrieves the trie node of the provided hash. +func ReadTrieNode(db ethdb.KeyValueReader, hash common.Hash) []byte { + data, _ := db.Get(hash.Bytes()) + return data +} + +// HasCode checks if the contract code corresponding to the +// provided code hash is present in the db. +func HasCode(db ethdb.KeyValueReader, hash common.Hash) bool { + // Try with the prefixed code scheme first, if not then try with legacy + // scheme. + if ok := HasCodeWithPrefix(db, hash); ok { + return true + } + ok, _ := db.Has(hash.Bytes()) + return ok +} + // HasCodeWithPrefix checks if the contract code corresponding to the // provided code hash is present in the db. This function will only check // presence using the prefix-scheme. @@ -67,30 +74,28 @@ func HasCodeWithPrefix(db ethdb.KeyValueReader, hash common.Hash) bool { return ok } -// WriteCode writes the provided contract code database. -func WriteCode(db ethdb.KeyValueWriter, hash common.Hash, code []byte) { - if err := db.Put(codeKey(hash), code); err != nil { - log.Crit("Failed to store contract code", "err", err) - } +// HasTrieNode checks if the trie node with the provided hash is present in db. +func HasTrieNode(db ethdb.KeyValueReader, hash common.Hash) bool { + ok, _ := db.Has(hash.Bytes()) + return ok } -// DeleteCode deletes the specified contract code from the database. -func DeleteCode(db ethdb.KeyValueWriter, hash common.Hash) { - if err := db.Delete(codeKey(hash)); err != nil { - log.Crit("Failed to delete contract code", "err", err) +// WritePreimages writes the provided set of preimages to the database. +func WritePreimages(db ethdb.KeyValueWriter, preimages map[common.Hash][]byte) { + for hash, preimage := range preimages { + if err := db.Put(preimageKey(hash), preimage); err != nil { + log.Crit("Failed to store trie preimage", "err", err) + } } + preimageCounter.Inc(int64(len(preimages))) + preimageHitCounter.Inc(int64(len(preimages))) } -// ReadTrieNode retrieves the trie node of the provided hash. -func ReadTrieNode(db ethdb.KeyValueReader, hash common.Hash) []byte { - data, _ := db.Get(hash.Bytes()) - return data -} - -// HasTrieNode checks if the trie node with the provided hash is present in db. -func HasTrieNode(db ethdb.KeyValueReader, hash common.Hash) bool { - ok, _ := db.Has(hash.Bytes()) - return ok +// WriteCode writes the provided contract code database. +func WriteCode(db ethdb.KeyValueWriter, hash common.Hash, code []byte) { + if err := db.Put(codeKey(hash), code); err != nil { + log.Crit("Failed to store contract code", "err", err) + } } // WriteTrieNode writes the provided trie node database. @@ -100,6 +105,13 @@ func WriteTrieNode(db ethdb.KeyValueWriter, hash common.Hash, node []byte) { } } +// DeleteCode deletes the specified contract code from the database. +func DeleteCode(db ethdb.KeyValueWriter, hash common.Hash) { + if err := db.Delete(codeKey(hash)); err != nil { + log.Crit("Failed to delete contract code", "err", err) + } +} + // DeleteTrieNode deletes the specified trie node from the database. func DeleteTrieNode(db ethdb.KeyValueWriter, hash common.Hash) { if err := db.Delete(hash.Bytes()); err != nil { diff --git a/core/rawdb/database.go b/core/rawdb/database.go index aef68d5750..da37aeee48 100644 --- a/core/rawdb/database.go +++ b/core/rawdb/database.go @@ -190,7 +190,7 @@ func NewFreezerDb(db ethdb.KeyValueStore, frz, namespace string, readonly bool, // NewDatabaseWithFreezer creates a high level database on top of a given key- // value data store with a freezer moving immutable chain segments into cold // storage. -func NewDatabaseWithFreezer(db ethdb.KeyValueStore, freezer string, namespace string, readonly, disableFreeze, isLastOffset, pruneAncientData bool) (ethdb.Database, error) { +func NewDatabaseWithFreezer(db ethdb.KeyValueStore, freezer string, namespace string, readonly, disableFreeze, isLastOffset, pruneAncientData, skipCheckFreezerType bool) (ethdb.Database, error) { if pruneAncientData && !disableFreeze && !readonly { frdb, err := newPrunedFreezer(freezer, db) if err != nil { @@ -211,7 +211,7 @@ func NewDatabaseWithFreezer(db ethdb.KeyValueStore, freezer string, namespace st log.Error("pruneancient not take effect, disableFreezer or readonly be set") } - if ReadAncientType(db) == PruneFreezerType { + if !skipCheckFreezerType && ReadAncientType(db) == PruneFreezerType { log.Warn("prune ancinet flag is set, may start fail, can add pruneancient parameter resolve") return nil, errors.New("pruneancient was set, please add pruneancient parameter") } @@ -340,12 +340,12 @@ func NewLevelDBDatabase(file string, cache int, handles int, namespace string, r // NewLevelDBDatabaseWithFreezer creates a persistent key-value database with a // freezer moving immutable chain segments into cold storage. -func NewLevelDBDatabaseWithFreezer(file string, cache int, handles int, freezer string, namespace string, readonly, disableFreeze, isLastOffset, pruneAncientData bool) (ethdb.Database, error) { +func NewLevelDBDatabaseWithFreezer(file string, cache int, handles int, freezer string, namespace string, readonly, disableFreeze, isLastOffset, pruneAncientData, skipCheckFreezerType bool) (ethdb.Database, error) { kvdb, err := leveldb.New(file, cache, handles, namespace, readonly) if err != nil { return nil, err } - frdb, err := NewDatabaseWithFreezer(kvdb, freezer, namespace, readonly, disableFreeze, isLastOffset, pruneAncientData) + frdb, err := NewDatabaseWithFreezer(kvdb, freezer, namespace, readonly, disableFreeze, isLastOffset, pruneAncientData, skipCheckFreezerType) if err != nil { kvdb.Close() return nil, err diff --git a/core/state/pruner/pruner.go b/core/state/pruner/pruner.go index 30703fa04c..703893574a 100644 --- a/core/state/pruner/pruner.go +++ b/core/state/pruner/pruner.go @@ -358,7 +358,7 @@ func prune(snaptree *snapshot.Tree, root common.Hash, maindb ethdb.Database, sta func (p *BlockPruner) backUpOldDb(name string, cache, handles int, namespace string, readonly, interrupt bool) error { // Open old db wrapper. - chainDb, err := p.node.OpenDatabaseWithFreezer(name, cache, handles, p.oldAncientPath, namespace, readonly, true, interrupt, false) + chainDb, err := p.node.OpenDatabaseWithFreezer(name, cache, handles, p.oldAncientPath, namespace, readonly, true, interrupt, false, true) if err != nil { log.Error("Failed to open ancient database", "err=", err) return err @@ -584,7 +584,7 @@ func (p *Pruner) Prune(root common.Hash) error { // Ensure the root is really present. The weak assumption // is the presence of root can indicate the presence of the // entire trie. - if blob := rawdb.ReadTrieNode(p.db, root); len(blob) == 0 { + if !rawdb.HasTrieNode(p.db, root) { // The special case is for clique based networks(rinkeby, goerli // and some other private networks), it's possible that two // consecutive blocks will have same root. In this case snapshot @@ -598,7 +598,7 @@ func (p *Pruner) Prune(root common.Hash) error { // as the pruning target. var found bool for i := len(layers) - 2; i >= 1; i-- { - if blob := rawdb.ReadTrieNode(p.db, layers[i].Root()); len(blob) != 0 { + if rawdb.HasTrieNode(p.db, layers[i].Root()) { root = layers[i].Root() found = true log.Info("Selecting middle-layer as the pruning target", "root", root, "depth", i) @@ -815,7 +815,7 @@ const warningLog = ` WARNING! -The clean trie cache is not found. Please delete it by yourself after the +The clean trie cache is not found. Please delete it by yourself after the pruning. Remember don't start the Geth without deleting the clean trie cache otherwise the entire database may be damaged! diff --git a/core/state/snapshot/difflayer.go b/core/state/snapshot/difflayer.go index d2b1b2778b..ca20b3ea4b 100644 --- a/core/state/snapshot/difflayer.go +++ b/core/state/snapshot/difflayer.go @@ -118,9 +118,8 @@ type diffLayer struct { storageList map[common.Hash][]common.Hash // List of storage slots for iterated retrievals, one per account. Any existing lists are sorted if non-nil storageData map[common.Hash]map[common.Hash][]byte // Keyed storage slots for direct retrieval. one per account (nil means deleted) - verifiedCh chan struct{} // the difflayer is verified when verifiedCh is nil or closed - valid bool // mark the difflayer is valid or not. - accountCorrected bool // mark the accountData has been corrected ort not + verifiedCh chan struct{} // the difflayer is verified when verifiedCh is nil or closed + valid bool // mark the difflayer is valid or not. diffed *bloomfilter.Filter // Bloom filter tracking all the diffed items up to the disk layer @@ -294,14 +293,6 @@ func (dl *diffLayer) CorrectAccounts(accounts map[common.Hash][]byte) { defer dl.lock.Unlock() dl.accountData = accounts - dl.accountCorrected = true -} - -func (dl *diffLayer) AccountsCorrected() bool { - dl.lock.RLock() - defer dl.lock.RUnlock() - - return dl.accountCorrected } // Parent returns the subsequent layer of a diff layer. diff --git a/core/state/snapshot/disklayer.go b/core/state/snapshot/disklayer.go index 6d46496a71..ca4a1051aa 100644 --- a/core/state/snapshot/disklayer.go +++ b/core/state/snapshot/disklayer.go @@ -62,10 +62,6 @@ func (dl *diskLayer) Verified() bool { func (dl *diskLayer) CorrectAccounts(map[common.Hash][]byte) { } -func (dl *diskLayer) AccountsCorrected() bool { - return true -} - // Parent always returns nil as there's no layer below the disk. func (dl *diskLayer) Parent() snapshot { return nil diff --git a/core/state/snapshot/snapshot.go b/core/state/snapshot/snapshot.go index 967fc0c68c..2f13631607 100644 --- a/core/state/snapshot/snapshot.go +++ b/core/state/snapshot/snapshot.go @@ -113,9 +113,6 @@ type Snapshot interface { // CorrectAccounts updates account data for storing the correct data during pipecommit CorrectAccounts(map[common.Hash][]byte) - // AccountsCorrected checks whether the account data has been corrected during pipecommit - AccountsCorrected() bool - // Account directly retrieves the account associated with a particular hash in // the snapshot slim data format. Account(hash common.Hash) (*Account, error) @@ -131,6 +128,10 @@ type Snapshot interface { // Storage directly retrieves the storage data associated with a particular hash, // within a particular account. Storage(accountHash, storageHash common.Hash) ([]byte, error) + + // Parent returns the subsequent layer of a snapshot, or nil if the base was + // reached. + Parent() snapshot } // snapshot is the internal version of the snapshot data layer that supports some @@ -138,13 +139,6 @@ type Snapshot interface { type snapshot interface { Snapshot - // Parent returns the subsequent layer of a snapshot, or nil if the base was - // reached. - // - // Note, the method is an internal helper to avoid type switching between the - // disk and diff layers. There is no locking involved. - Parent() snapshot - // Update creates a new layer on top of the existing snapshot diff tree with // the specified data items. // diff --git a/core/state/state_object.go b/core/state/state_object.go index bd6192c964..fc89a4f904 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -238,25 +238,10 @@ func (s *StateObject) GetCommittedState(db Database, key common.Hash) common.Has } // If no live objects are available, attempt to use snapshots var ( - enc []byte - err error - meter *time.Duration + enc []byte + err error ) - readStart := time.Now() - if metrics.EnabledExpensive { - // If the snap is 'under construction', the first lookup may fail. If that - // happens, we don't want to double-count the time elapsed. Thus this - // dance with the metering. - defer func() { - if meter != nil { - *meter += time.Since(readStart) - } - }() - } if s.db.snap != nil { - if metrics.EnabledExpensive { - meter = &s.db.SnapshotStorageReads - } // If the object was destructed in *this* block (and potentially resurrected), // the storage has been cleared out, and we should *not* consult the previous // snapshot about any storage values. The only possible alternatives are: @@ -266,21 +251,24 @@ func (s *StateObject) GetCommittedState(db Database, key common.Hash) common.Has if _, destructed := s.db.snapDestructs[s.address]; destructed { return common.Hash{} } + start := time.Now() enc, err = s.db.snap.Storage(s.addrHash, crypto.Keccak256Hash(key.Bytes())) + if metrics.EnabledExpensive { + s.db.SnapshotStorageReads += time.Since(start) + } } // If snapshot unavailable or reading from it failed, load from the database if s.db.snap == nil || err != nil { - if meter != nil { - // If we already spent time checking the snapshot, account for it - // and reset the readStart - *meter += time.Since(readStart) - readStart = time.Now() - } + start := time.Now() + // if metrics.EnabledExpensive { + // meter = &s.db.StorageReads + // } + enc, err = s.getTrie(db).TryGet(key.Bytes()) if metrics.EnabledExpensive { - meter = &s.db.StorageReads + s.db.StorageReads += time.Since(start) } - if enc, err = s.getTrie(db).TryGet(key.Bytes()); err != nil { + if err != nil { s.setError(err) return common.Hash{} } @@ -351,18 +339,8 @@ func (s *StateObject) finalise(prefetch bool) { } } - // The account root need to be updated before prefetch, otherwise the account root is empty - if s.db.pipeCommit && s.data.Root == dummyRoot && !s.rootCorrected && s.db.snap.AccountsCorrected() { - if acc, err := s.db.snap.Account(crypto.HashData(s.db.hasher, s.address.Bytes())); err == nil { - if acc != nil && len(acc.Root) != 0 { - s.data.Root = common.BytesToHash(acc.Root) - s.rootCorrected = true - } - } - } - prefetcher := s.db.prefetcher - if prefetcher != nil && prefetch && len(slotsToPrefetch) > 0 && s.data.Root != emptyRoot && s.data.Root != dummyRoot { + if prefetcher != nil && prefetch && len(slotsToPrefetch) > 0 && s.data.Root != emptyRoot { prefetcher.prefetch(s.data.Root, slotsToPrefetch, s.addrHash) } if len(s.dirtyStorage) > 0 { diff --git a/core/state/statedb.go b/core/state/statedb.go index 0fefa5d81c..e7bf3c9491 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -50,10 +50,6 @@ var ( // emptyRoot is the known root hash of an empty trie. emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") - // dummyRoot is the dummy account root before corrected in pipecommit sync mode, - // the value is 542e5fc2709de84248e9bce43a9c0c8943a608029001360f8ab55bf113b23d28 - dummyRoot = crypto.Keccak256Hash([]byte("dummy_account_root")) - emptyAddr = crypto.Keccak256Hash(common.Address{}.Bytes()) ) @@ -218,7 +214,12 @@ func (s *StateDB) StartPrefetcher(namespace string) { s.prefetcher = nil } if s.snap != nil { - s.prefetcher = newTriePrefetcher(s.db, s.originalRoot, namespace) + parent := s.snap.Parent() + if parent != nil { + s.prefetcher = newTriePrefetcher(s.db, s.originalRoot, parent.Root(), namespace) + } else { + s.prefetcher = newTriePrefetcher(s.db, s.originalRoot, common.Hash{}, namespace) + } } } @@ -229,10 +230,38 @@ func (s *StateDB) StopPrefetcher() { return } s.prefetcherLock.Lock() - defer s.prefetcherLock.Unlock() if s.prefetcher != nil { s.prefetcher.close() - s.prefetcher = nil + } + s.prefetcherLock.Unlock() +} + +func (s *StateDB) TriePrefetchInAdvance(block *types.Block, signer types.Signer) { + // s is a temporary throw away StateDB, s.prefetcher won't be resetted to nil + // so no need to add lock for s.prefetcher + prefetcher := s.prefetcher + if prefetcher == nil { + return + } + accounts := make(map[common.Address]struct{}, block.Transactions().Len()<<1) + for _, tx := range block.Transactions() { + from, err := types.Sender(signer, tx) + if err != nil { + // invalid block, skip prefetch + return + } + accounts[from] = struct{}{} + if tx.To() != nil { + accounts[*tx.To()] = struct{}{} + } + } + addressesToPrefetch := make([][]byte, 0, len(accounts)) + for addr := range accounts { + addressesToPrefetch = append(addressesToPrefetch, common.CopyBytes(addr[:])) // Copy needed for closure + } + + if len(addressesToPrefetch) > 0 { + prefetcher.prefetch(s.originalRoot, addressesToPrefetch, emptyAddr) } } @@ -627,16 +656,14 @@ func (s *StateDB) getDeletedStateObject(addr common.Address) *StateObject { return obj } // If no live objects are available, attempt to use snapshots - var ( - data *types.StateAccount - err error - ) + var data *types.StateAccount if s.snap != nil { + start := time.Now() + acc, err := s.snap.Account(crypto.HashData(s.hasher, addr.Bytes())) if metrics.EnabledExpensive { - defer func(start time.Time) { s.SnapshotAccountReads += time.Since(start) }(time.Now()) + s.SnapshotAccountReads += time.Since(start) } - var acc *snapshot.Account - if acc, err = s.snap.Account(crypto.HashData(s.hasher, addr.Bytes())); err == nil { + if err == nil { if acc == nil { return nil } @@ -656,7 +683,7 @@ func (s *StateDB) getDeletedStateObject(addr common.Address) *StateObject { } // If snapshot unavailable or reading from it failed, load from the database - if s.snap == nil || err != nil { + if data == nil { if s.trie == nil { tr, err := s.db.OpenTrie(s.originalRoot) if err != nil { @@ -665,10 +692,11 @@ func (s *StateDB) getDeletedStateObject(addr common.Address) *StateObject { } s.trie = tr } + start := time.Now() + enc, err := s.trie.TryGet(addr.Bytes()) if metrics.EnabledExpensive { - defer func(start time.Time) { s.AccountReads += time.Since(start) }(time.Now()) + s.AccountReads += time.Since(start) } - enc, err := s.trie.TryGet(addr.Bytes()) if err != nil { s.setError(fmt.Errorf("getDeleteStateObject (%x) error: %v", addr.Bytes(), err)) return nil @@ -775,6 +803,17 @@ func (db *StateDB) ForEachStorage(addr common.Address, cb func(key, value common // Copy creates a deep, independent copy of the state. // Snapshots of the copied state cannot be applied to the copy. func (s *StateDB) Copy() *StateDB { + return s.copyInternal(false) +} + +// It is mainly for state prefetcher to do trie prefetch right now. +func (s *StateDB) CopyDoPrefetch() *StateDB { + return s.copyInternal(true) +} + +// If doPrefetch is true, it tries to reuse the prefetcher, the copied StateDB will do active trie prefetch. +// otherwise, just do inactive copy trie prefetcher. +func (s *StateDB) copyInternal(doPrefetch bool) *StateDB { // Copy all the basic fields, initialize the memory ones state := &StateDB{ db: s.db, @@ -841,12 +880,12 @@ func (s *StateDB) Copy() *StateDB { state.accessList = s.accessList.Copy() } - // If there's a prefetcher running, make an inactive copy of it that can - // only access data but does not actively preload (since the user will not - // know that they need to explicitly terminate an active copy). - prefetcher := s.prefetcher - if prefetcher != nil { - state.prefetcher = prefetcher.copy() + state.prefetcher = s.prefetcher + if s.prefetcher != nil && !doPrefetch { + // If there's a prefetcher running, make an inactive copy of it that can + // only access data but does not actively preload (since the user will not + // know that they need to explicitly terminate an active copy). + state.prefetcher = state.prefetcher.copy() } if s.snaps != nil { // In order for the miner to be able to use and make additions @@ -960,7 +999,11 @@ func (s *StateDB) Finalise(deleteEmptyObjects bool) { } prefetcher := s.prefetcher if prefetcher != nil && len(addressesToPrefetch) > 0 { - prefetcher.prefetch(s.originalRoot, addressesToPrefetch, emptyAddr) + if s.snap.Verified() { + prefetcher.prefetch(s.originalRoot, addressesToPrefetch, emptyAddr) + } else if prefetcher.rootParent != (common.Hash{}) { + prefetcher.prefetch(prefetcher.rootParent, addressesToPrefetch, emptyAddr) + } } // Invalidate journal because reverting across transactions is not allowed. s.clearJournalAndRefund() @@ -995,11 +1038,12 @@ func (s *StateDB) CorrectAccountsRoot(blockRoot common.Hash) { } if accounts, err := snapshot.Accounts(); err == nil && accounts != nil { for _, obj := range s.stateObjects { - if !obj.deleted && !obj.rootCorrected && obj.data.Root == dummyRoot { + if !obj.deleted { if account, exist := accounts[crypto.Keccak256Hash(obj.address[:])]; exist { - obj.data.Root = common.BytesToHash(account.Root) - if obj.data.Root == (common.Hash{}) { + if len(account.Root) == 0 { obj.data.Root = emptyRoot + } else { + obj.data.Root = common.BytesToHash(account.Root) } obj.rootCorrected = true } @@ -1013,12 +1057,8 @@ func (s *StateDB) PopulateSnapAccountAndStorage() { for addr := range s.stateObjectsPending { if obj := s.stateObjects[addr]; !obj.deleted { if s.snap != nil { - root := obj.data.Root - storageChanged := s.populateSnapStorage(obj) - if storageChanged { - root = dummyRoot - } - s.snapAccounts[obj.address] = snapshot.SlimAccountRLP(obj.data.Nonce, obj.data.Balance, root, obj.data.CodeHash) + s.populateSnapStorage(obj) + s.snapAccounts[obj.address] = snapshot.SlimAccountRLP(obj.data.Nonce, obj.data.Balance, obj.data.Root, obj.data.CodeHash) } } } @@ -1114,15 +1154,7 @@ func (s *StateDB) StateIntermediateRoot() common.Hash { // the remainder without, but pre-byzantium even the initial prefetcher is // useless, so no sleep lost. prefetcher := s.prefetcher - defer func() { - s.prefetcherLock.Lock() - if s.prefetcher != nil { - s.prefetcher.close() - s.prefetcher = nil - } - // try not use defer inside defer - s.prefetcherLock.Unlock() - }() + defer s.StopPrefetcher() // Now we're about to start to write changes to the trie. The trie is so far // _untouched_. We can check with the prefetcher, if it can give us a trie @@ -1315,10 +1347,12 @@ func (s *StateDB) LightCommit() (common.Hash, *types.DiffLayer, error) { // Commit writes the state to the underlying in-memory trie database. func (s *StateDB) Commit(failPostCommitFunc func(), postCommitFuncs ...func() error) (common.Hash, *types.DiffLayer, error) { if s.dbErr != nil { + s.StopPrefetcher() return common.Hash{}, nil, fmt.Errorf("commit aborted due to earlier error: %v", s.dbErr) } // Finalize any pending changes and merge everything into the tries if s.lightProcessed { + defer s.StopPrefetcher() root, diff, err := s.LightCommit() if err != nil { return root, diff, err @@ -1527,6 +1561,7 @@ func (s *StateDB) Commit(failPostCommitFunc func(), postCommitFuncs ...func() er if s.pipeCommit { go commmitTrie() } else { + defer s.StopPrefetcher() commitFuncs = append(commitFuncs, commmitTrie) } commitRes := make(chan error, len(commitFuncs)) diff --git a/core/state/trie_prefetcher.go b/core/state/trie_prefetcher.go index e42628dc67..cd51820e9e 100644 --- a/core/state/trie_prefetcher.go +++ b/core/state/trie_prefetcher.go @@ -26,8 +26,10 @@ import ( ) const ( - abortChanSize = 64 - concurrentChanSize = 10 + abortChanSize = 64 + concurrentChanSize = 10 + parallelTriePrefetchThreshold = 10 + parallelTriePrefetchCapacity = 20 ) var ( @@ -47,20 +49,19 @@ type prefetchMsg struct { // // Note, the prefetcher's API is not thread safe. type triePrefetcher struct { - db Database // Database to fetch trie nodes through - root common.Hash // Root hash of theaccount trie for metrics - fetches map[common.Hash]Trie // Partially or fully fetcher tries - fetchers map[common.Hash]*subfetcher // Subfetchers for each trie + db Database // Database to fetch trie nodes through + root common.Hash // Root hash of theaccount trie for metrics + rootParent common.Hash //Root has of the account trie from block before the prvious one, designed for pipecommit mode + fetches map[common.Hash]Trie // Partially or fully fetcher tries + fetchers map[common.Hash]*subfetcher // Subfetchers for each trie + abortChan chan *subfetcher // to abort a single subfetcher and its children closed int32 closeMainChan chan struct{} // it is to inform the mainLoop closeMainDoneChan chan struct{} fetchersMutex sync.RWMutex prefetchChan chan *prefetchMsg // no need to wait for return - abortChan chan *subfetcher - closeAbortChan chan struct{} // it is used to inform abortLoop - deliveryMissMeter metrics.Meter accountLoadMeter metrics.Meter accountDupMeter metrics.Meter @@ -70,17 +71,22 @@ type triePrefetcher struct { storageDupMeter metrics.Meter storageSkipMeter metrics.Meter storageWasteMeter metrics.Meter + + accountStaleLoadMeter metrics.Meter + accountStaleDupMeter metrics.Meter + accountStaleSkipMeter metrics.Meter + accountStaleWasteMeter metrics.Meter } // newTriePrefetcher -func newTriePrefetcher(db Database, root common.Hash, namespace string) *triePrefetcher { +func newTriePrefetcher(db Database, root, rootParent common.Hash, namespace string) *triePrefetcher { prefix := triePrefetchMetricsPrefix + namespace p := &triePrefetcher{ - db: db, - root: root, - fetchers: make(map[common.Hash]*subfetcher), // Active prefetchers use the fetchers map - abortChan: make(chan *subfetcher, abortChanSize), - closeAbortChan: make(chan struct{}), + db: db, + root: root, + rootParent: rootParent, + fetchers: make(map[common.Hash]*subfetcher), // Active prefetchers use the fetchers map + abortChan: make(chan *subfetcher, abortChanSize), closeMainChan: make(chan struct{}), closeMainDoneChan: make(chan struct{}), @@ -95,12 +101,19 @@ func newTriePrefetcher(db Database, root common.Hash, namespace string) *triePre storageDupMeter: metrics.GetOrRegisterMeter(prefix+"/storage/dup", nil), storageSkipMeter: metrics.GetOrRegisterMeter(prefix+"/storage/skip", nil), storageWasteMeter: metrics.GetOrRegisterMeter(prefix+"/storage/waste", nil), + + accountStaleLoadMeter: metrics.GetOrRegisterMeter(prefix+"/accountst/load", nil), + accountStaleDupMeter: metrics.GetOrRegisterMeter(prefix+"/accountst/dup", nil), + accountStaleSkipMeter: metrics.GetOrRegisterMeter(prefix+"/accountst/skip", nil), + accountStaleWasteMeter: metrics.GetOrRegisterMeter(prefix+"/accountst/waste", nil), } - go p.abortLoop() go p.mainLoop() return p } +// the subfetcher's lifecycle will only be updated in this loop, +// include: subfetcher's creation & abort, child subfetcher's creation & abort. +// since the mainLoop will handle all the requests, each message handle should be lightweight func (p *triePrefetcher) mainLoop() { for { select { @@ -112,14 +125,39 @@ func (p *triePrefetcher) mainLoop() { p.fetchers[pMsg.root] = fetcher p.fetchersMutex.Unlock() } - fetcher.schedule(pMsg.keys) + select { + case <-fetcher.stop: + default: + fetcher.schedule(pMsg.keys) + // no need to run parallel trie prefetch if threshold is not reached. + if atomic.LoadUint32(&fetcher.pendingSize) > parallelTriePrefetchThreshold { + fetcher.scheduleParallel(pMsg.keys) + } + } + + case fetcher := <-p.abortChan: + fetcher.abort() + for _, child := range fetcher.paraChildren { + child.abort() + } case <-p.closeMainChan: for _, fetcher := range p.fetchers { - p.abortChan <- fetcher // safe to do multiple times + fetcher.abort() // safe to do multiple times + for _, child := range fetcher.paraChildren { + child.abort() + } + } + // make sure all subfetchers and child subfetchers are stopped + for _, fetcher := range p.fetchers { <-fetcher.term + for _, child := range fetcher.paraChildren { + <-child.term + } + if metrics.EnabledExpensive { - if fetcher.root == p.root { + switch fetcher.root { + case p.root: p.accountLoadMeter.Mark(int64(len(fetcher.seen))) p.accountDupMeter.Mark(int64(fetcher.dups)) p.accountSkipMeter.Mark(int64(len(fetcher.tasks))) @@ -129,7 +167,19 @@ func (p *triePrefetcher) mainLoop() { } fetcher.lock.Unlock() p.accountWasteMeter.Mark(int64(len(fetcher.seen))) - } else { + + case p.rootParent: + p.accountStaleLoadMeter.Mark(int64(len(fetcher.seen))) + p.accountStaleDupMeter.Mark(int64(fetcher.dups)) + p.accountStaleSkipMeter.Mark(int64(len(fetcher.tasks))) + fetcher.lock.Lock() + for _, key := range fetcher.used { + delete(fetcher.seen, string(key)) + } + fetcher.lock.Unlock() + p.accountStaleWasteMeter.Mark(int64(len(fetcher.seen))) + + default: p.storageLoadMeter.Mark(int64(len(fetcher.seen))) p.storageDupMeter.Mark(int64(fetcher.dups)) p.storageSkipMeter.Mark(int64(len(fetcher.tasks))) @@ -140,33 +190,14 @@ func (p *triePrefetcher) mainLoop() { } fetcher.lock.Unlock() p.storageWasteMeter.Mark(int64(len(fetcher.seen))) + } } } - close(p.closeAbortChan) close(p.closeMainDoneChan) p.fetchersMutex.Lock() p.fetchers = nil p.fetchersMutex.Unlock() - - // drain all the channels before quit the loop - for { - select { - case <-p.prefetchChan: - default: - return - } - } - } - } -} - -func (p *triePrefetcher) abortLoop() { - for { - select { - case fetcher := <-p.abortChan: - fetcher.abort() - case <-p.closeAbortChan: return } } @@ -208,7 +239,8 @@ func (p *triePrefetcher) copy() *triePrefetcher { select { case <-p.closeMainChan: - // for closed trie prefetcher, the fetches should not be nil + // for closed trie prefetcher, fetchers is empty + // but the fetches should not be nil, since fetches is used to check if it is a copied inactive one. fetcherCopied := &triePrefetcher{ db: p.db, root: p.root, @@ -255,6 +287,7 @@ func (p *triePrefetcher) trie(root common.Hash) Trie { return p.db.CopyTrie(trie) } + // use lock instead of request to mainLoop by chan to get the fetcher for performance concern. p.fetchersMutex.RLock() fetcher := p.fetchers[root] p.fetchersMutex.RUnlock() @@ -266,8 +299,8 @@ func (p *triePrefetcher) trie(root common.Hash) Trie { // Interrupt the prefetcher if it's by any chance still running and return // a copy of any pre-loaded trie. select { - case <-p.closeAbortChan: - case p.abortChan <- fetcher: // safe to do multiple times + case <-p.closeMainChan: + case p.abortChan <- fetcher: // safe to abort a fecther multiple times } trie := fetcher.peek() @@ -323,6 +356,9 @@ type subfetcher struct { used [][]byte // Tracks the entries used in the end accountHash common.Hash + + pendingSize uint32 + paraChildren []*subfetcher // Parallel trie prefetch for address of massive change } // newSubfetcher creates a goroutine to prefetch state items belonging to a @@ -344,11 +380,11 @@ func newSubfetcher(db Database, root common.Hash, accountHash common.Hash) *subf // schedule adds a batch of trie keys to the queue to prefetch. func (sf *subfetcher) schedule(keys [][]byte) { + atomic.AddUint32(&sf.pendingSize, uint32(len(keys))) // Append the tasks to the current queue sf.lock.Lock() sf.tasks = append(sf.tasks, keys...) sf.lock.Unlock() - // Notify the prefetcher, it's fine if it's already terminated select { case sf.wake <- struct{}{}: @@ -356,6 +392,45 @@ func (sf *subfetcher) schedule(keys [][]byte) { } } +func (sf *subfetcher) scheduleParallel(keys [][]byte) { + var keyIndex uint32 = 0 + childrenNum := len(sf.paraChildren) + if childrenNum > 0 { + // To feed the children first, if they are hungry. + // A child can handle keys with capacity of parallelTriePrefetchCapacity. + childIndex := len(keys) % childrenNum // randomly select the start child to avoid always feed the first one + for i := 0; i < childrenNum; i++ { + child := sf.paraChildren[childIndex] + childIndex = (childIndex + 1) % childrenNum + if atomic.LoadUint32(&child.pendingSize) >= parallelTriePrefetchCapacity { + // the child is already full, skip it + continue + } + feedNum := parallelTriePrefetchCapacity - atomic.LoadUint32(&child.pendingSize) + if keyIndex+feedNum >= uint32(len(keys)) { + // the new arrived keys are all consumed by children. + child.schedule(keys[keyIndex:]) + return + } + child.schedule(keys[keyIndex : keyIndex+feedNum]) + keyIndex += feedNum + } + } + // Children did not consume all the keys, to create new subfetch to handle left keys. + keysLeft := keys[keyIndex:] + keysLeftSize := len(keysLeft) + for i := 0; i*parallelTriePrefetchCapacity < keysLeftSize; i++ { + child := newSubfetcher(sf.db, sf.root, sf.accountHash) + sf.paraChildren = append(sf.paraChildren, child) + endIndex := (i + 1) * parallelTriePrefetchCapacity + if endIndex >= keysLeftSize { + child.schedule(keysLeft[i*parallelTriePrefetchCapacity:]) + return + } + child.schedule(keysLeft[i*parallelTriePrefetchCapacity : endIndex]) + } +} + // peek tries to retrieve a deep copy of the fetcher's trie in whatever form it // is currently. func (sf *subfetcher) peek() Trie { @@ -382,7 +457,7 @@ func (sf *subfetcher) abort() { default: close(sf.stop) } - <-sf.term + // no need to wait <-sf.term here, will check sf.term later } // loop waits for new tasks to be scheduled and keeps loading them until it runs @@ -450,6 +525,7 @@ func (sf *subfetcher) loop() { sf.trie.TryGet(task) sf.seen[string(task)] = struct{}{} } + atomic.AddUint32(&sf.pendingSize, ^uint32(0)) // decrease } } diff --git a/core/state/trie_prefetcher_test.go b/core/state/trie_prefetcher_test.go index aa178dc9d0..8d8888fb24 100644 --- a/core/state/trie_prefetcher_test.go +++ b/core/state/trie_prefetcher_test.go @@ -55,7 +55,7 @@ func prefetchGuaranteed(prefetcher *triePrefetcher, root common.Hash, keys [][]b func TestCopyAndClose(t *testing.T) { db := filledStateDB() - prefetcher := newTriePrefetcher(db.db, db.originalRoot, "") + prefetcher := newTriePrefetcher(db.db, db.originalRoot, common.Hash{}, "") skey := common.HexToHash("aaa") prefetchGuaranteed(prefetcher, db.originalRoot, [][]byte{skey.Bytes()}, common.Hash{}) prefetchGuaranteed(prefetcher, db.originalRoot, [][]byte{skey.Bytes()}, common.Hash{}) @@ -80,7 +80,7 @@ func TestCopyAndClose(t *testing.T) { func TestUseAfterClose(t *testing.T) { db := filledStateDB() - prefetcher := newTriePrefetcher(db.db, db.originalRoot, "") + prefetcher := newTriePrefetcher(db.db, db.originalRoot, common.Hash{}, "") skey := common.HexToHash("aaa") prefetchGuaranteed(prefetcher, db.originalRoot, [][]byte{skey.Bytes()}, common.Hash{}) a := prefetcher.trie(db.originalRoot) @@ -96,7 +96,7 @@ func TestUseAfterClose(t *testing.T) { func TestCopyClose(t *testing.T) { db := filledStateDB() - prefetcher := newTriePrefetcher(db.db, db.originalRoot, "") + prefetcher := newTriePrefetcher(db.db, db.originalRoot, common.Hash{}, "") skey := common.HexToHash("aaa") prefetchGuaranteed(prefetcher, db.originalRoot, [][]byte{skey.Bytes()}, common.Hash{}) cpy := prefetcher.copy() diff --git a/core/state_prefetcher.go b/core/state_prefetcher.go index d39f3e4e25..fdc141c474 100644 --- a/core/state_prefetcher.go +++ b/core/state_prefetcher.go @@ -58,7 +58,7 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c // No need to execute the first batch, since the main processor will do it. for i := 0; i < prefetchThread; i++ { go func() { - newStatedb := statedb.Copy() + newStatedb := statedb.CopyDoPrefetch() newStatedb.EnableWriteOnSharedStorage() gaspool := new(GasPool).AddGas(block.GasLimit()) blockContext := NewEVMBlockContext(header, p.bc, nil) @@ -100,7 +100,7 @@ func (p *statePrefetcher) PrefetchMining(txs *types.TransactionsByPriceAndNonce, for i := 0; i < prefetchThread; i++ { go func(startCh <-chan *types.Transaction, stopCh <-chan struct{}) { idx := 0 - newStatedb := statedb.Copy() + newStatedb := statedb.CopyDoPrefetch() newStatedb.EnableWriteOnSharedStorage() gaspool := new(GasPool).AddGas(gasLimit) blockContext := NewEVMBlockContext(header, p.bc, nil) @@ -138,9 +138,14 @@ func (p *statePrefetcher) PrefetchMining(txs *types.TransactionsByPriceAndNonce, if tx == nil { return } - txCh <- tx - txset.Shift() + select { + case <-interruptCh: + return + case txCh <- tx: + } + + txset.Shift() } } }(txs) @@ -153,5 +158,8 @@ func precacheTransaction(msg types.Message, config *params.ChainConfig, gaspool // Update the evm with the new transaction context. evm.Reset(NewEVMTxContext(msg), statedb) // Add addresses to access list if applicable - ApplyMessage(evm, msg, gaspool) + if _, err := ApplyMessage(evm, msg, gaspool); err == nil { + statedb.Finalise(true) + } + } diff --git a/core/state_processor.go b/core/state_processor.go index 97025fb9eb..b42938adf9 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -403,9 +403,10 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg posa, isPoSA := p.engine.(consensus.PoSA) commonTxs := make([]*types.Transaction, 0, txNum) - // initilise bloom processors + // initialise bloom processors bloomProcessors := NewAsyncReceiptBloomGenerator(txNum) statedb.MarkFullProcessed() + signer := types.MakeSigner(p.config, header.Number) // usually do have two tx, one for validator set contract, another for system reward contract. systemTxs := make([]*types.Transaction, 0, 2) @@ -421,7 +422,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg } } - msg, err := tx.AsMessage(types.MakeSigner(p.config, header.Number), header.BaseFee) + msg, err := tx.AsMessage(signer, header.BaseFee) if err != nil { bloomProcessors.Close() return statedb, nil, nil, 0, err diff --git a/core/state_processor_test.go b/core/state_processor_test.go index 7ef8747806..964c08947c 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -58,6 +58,7 @@ func TestStateProcessorErrors(t *testing.T) { EulerBlock: big.NewInt(0), BerlinBlock: big.NewInt(0), LondonBlock: big.NewInt(0), + GibbsBlock: big.NewInt(0), Ethash: new(params.EthashConfig), } signer = types.LatestSigner(config) diff --git a/core/systemcontracts/const.go b/core/systemcontracts/const.go index 15c1987e96..a5a74905e0 100644 --- a/core/systemcontracts/const.go +++ b/core/systemcontracts/const.go @@ -12,4 +12,5 @@ const ( GovHubContract = "0x0000000000000000000000000000000000001007" TokenManagerContract = "0x0000000000000000000000000000000000001008" CrossChainContract = "0x0000000000000000000000000000000000002000" + StakingContract = "0x0000000000000000000000000000000000002001" ) diff --git a/core/systemcontracts/upgrade.go b/core/systemcontracts/upgrade.go index b5e6c7e781..4f020d02fb 100644 --- a/core/systemcontracts/upgrade.go +++ b/core/systemcontracts/upgrade.go @@ -45,6 +45,8 @@ var ( brunoUpgrade = make(map[string]*Upgrade) eulerUpgrade = make(map[string]*Upgrade) + + gibbsUpgrade = make(map[string]*Upgrade) ) func init() { @@ -360,6 +362,37 @@ func init() { }, } + gibbsUpgrade[chapelNet] = &Upgrade{ + UpgradeName: "gibbs", + Configs: []*UpgradeConfig{ + { + ContractAddr: common.HexToAddress(TokenHubContract), + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/9d45b31c12b2c04757284717f4351cb44e81a3a7", + Code: "60806040526004361061036f5760003560e01c80639a854bbd116101c6578063bd466461116100f7578063f014847211610095578063fc1a598f1161006f578063fc1a598f14610d58578063fc3e590814610a3b578063fd6a687914610d8b578063ff9c0027146106ec576103b7565b8063f014847214610d19578063f9a2bbc714610d2e578063fa9e915914610d43576103b7565b8063d9e6dae9116100d1578063d9e6dae91461066e578063dc927faf14610cda578063e1c7392a14610cef578063ebf71d5314610d04576103b7565b8063bd46646114610c0d578063c81b166214610c40578063c8509d8114610c55576103b7565b8063aa7415f511610164578063b99328c51161013e578063b99328c514610b77578063b9fd21e314610bb0578063ba35ead614610bc5578063bbface1f14610bda576103b7565b8063aa7415f514610a50578063ab51bb9614610a97578063ac43175114610aac576103b7565b8063a1a11bf5116101a0578063a1a11bf5146109fc578063a496fba214610a11578063a78abc1614610a26578063a7c9f02d14610a3b576103b7565b80639a854bbd146109995780639a99b4f0146109ae5780639dc09262146109e7576103b7565b806361368475116102a0578063727be1f81161023e578063831d65d111610218578063831d65d1146108c05780638b87b21f146105ed5780638eff336c1461094557806396713da914610984576103b7565b8063727be1f81461086c57806375d47a0a146108965780637942fd05146108ab576103b7565b80636e47b4821161027a5780636e47b4821461082d57806370fd5bad146106ec578063718a8aa81461084257806371d3086314610857576103b7565b8063613684751461066e57806366dea52a146106ec5780636e05652014610701576103b7565b806343a368b91161030d57806350432d32116102e757806350432d321461068357806351e806721461069857806359b92789146106ad5780635d499b1b146106d7576103b7565b806343a368b91461062d578063493279b1146106425780634bf6c8821461066e576103b7565b8063149d14d911610349578063149d14d9146105155780633d7132231461053c5780633dffc387146105ed57806343756e5c14610618576103b7565b80630bee7a67146103bc5780630e2374a5146103ea5780631182b8751461041b576103b7565b366103b75734156103b5576040805133815234602082015281517f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db929181900390910190a15b005b600080fd5b3480156103c857600080fd5b506103d1610da0565b6040805163ffffffff9092168252519081900360200190f35b3480156103f657600080fd5b506103ff610da5565b604080516001600160a01b039092168252519081900360200190f35b34801561042757600080fd5b506104a06004803603604081101561043e57600080fd5b60ff8235169190810190604081016020820135600160201b81111561046257600080fd5b82018360208201111561047457600080fd5b803590602001918460018302840111600160201b8311171561049557600080fd5b509092509050610dab565b6040805160208082528351818301528351919283929083019185019080838360005b838110156104da5781810151838201526020016104c2565b50505050905090810190601f1680156105075780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561052157600080fd5b5061052a610ed9565b60408051918252519081900360200190f35b34801561054857600080fd5b506103ff6004803603602081101561055f57600080fd5b810190602081018135600160201b81111561057957600080fd5b82018360208201111561058b57600080fd5b803590602001918460018302840111600160201b831117156105ac57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610edf945050505050565b3480156105f957600080fd5b50610602610f03565b6040805160ff9092168252519081900360200190f35b34801561062457600080fd5b506103ff610f08565b34801561063957600080fd5b5061052a610f0e565b34801561064e57600080fd5b50610657610f1a565b6040805161ffff9092168252519081900360200190f35b34801561067a57600080fd5b50610602610f1f565b34801561068f57600080fd5b5061052a610f24565b3480156106a457600080fd5b506103ff610f2f565b3480156106b957600080fd5b506103ff600480360360208110156106d057600080fd5b5035610f35565b3480156106e357600080fd5b5061052a610f50565b3480156106f857600080fd5b50610602610f59565b6108196004803603608081101561071757600080fd5b810190602081018135600160201b81111561073157600080fd5b82018360208201111561074357600080fd5b803590602001918460208302840111600160201b8311171561076457600080fd5b919390929091602081019035600160201b81111561078157600080fd5b82018360208201111561079357600080fd5b803590602001918460208302840111600160201b831117156107b457600080fd5b919390929091602081019035600160201b8111156107d157600080fd5b8201836020820111156107e357600080fd5b803590602001918460208302840111600160201b8311171561080457600080fd5b91935091503567ffffffffffffffff16610f5e565b604080519115158252519081900360200190f35b34801561083957600080fd5b506103ff611433565b34801561084e57600080fd5b50610602611439565b34801561086357600080fd5b5061052a61143e565b34801561087857600080fd5b506108196004803603602081101561088f57600080fd5b5035611444565b3480156108a257600080fd5b506103ff6114be565b3480156108b757600080fd5b506106026114c4565b3480156108cc57600080fd5b506103b5600480360360408110156108e357600080fd5b60ff8235169190810190604081016020820135600160201b81111561090757600080fd5b82018360208201111561091957600080fd5b803590602001918460018302840111600160201b8311171561093a57600080fd5b5090925090506114c9565b34801561095157600080fd5b506103b56004803603606081101561096857600080fd5b508035906001600160a01b036020820135169060400135611612565b34801561099057600080fd5b50610602611698565b3480156109a557600080fd5b5061052a61169d565b3480156109ba57600080fd5b5061052a600480360360408110156109d157600080fd5b506001600160a01b0381351690602001356116a9565b3480156109f357600080fd5b506103ff6117e7565b348015610a0857600080fd5b506103ff6117ed565b348015610a1d57600080fd5b506106026117f3565b348015610a3257600080fd5b506108196117f8565b348015610a4757600080fd5b50610602611801565b61081960048036036080811015610a6657600080fd5b5080356001600160a01b03908116916020810135909116906040810135906060013567ffffffffffffffff16611806565b348015610aa357600080fd5b506103d16117f3565b348015610ab857600080fd5b506103b560048036036040811015610acf57600080fd5b810190602081018135600160201b811115610ae957600080fd5b820183602082011115610afb57600080fd5b803590602001918460018302840111600160201b83111715610b1c57600080fd5b919390929091602081019035600160201b811115610b3957600080fd5b820183602082011115610b4b57600080fd5b803590602001918460018302840111600160201b83111715610b6c57600080fd5b509092509050611ec7565b348015610b8357600080fd5b506103b560048036036040811015610b9a57600080fd5b50803590602001356001600160a01b0316612136565b348015610bbc57600080fd5b5061052a6121ac565b348015610bd157600080fd5b5061052a6121b6565b348015610be657600080fd5b5061052a60048036036020811015610bfd57600080fd5b50356001600160a01b03166121bc565b348015610c1957600080fd5b5061052a60048036036020811015610c3057600080fd5b50356001600160a01b03166121ce565b348015610c4c57600080fd5b506103ff6121e9565b348015610c6157600080fd5b506103b560048036036040811015610c7857600080fd5b60ff8235169190810190604081016020820135600160201b811115610c9c57600080fd5b820183602082011115610cae57600080fd5b803590602001918460018302840111600160201b83111715610ccf57600080fd5b5090925090506121ef565b348015610ce657600080fd5b506103ff6122bf565b348015610cfb57600080fd5b506103b56122c5565b348015610d1057600080fd5b50610602612365565b348015610d2557600080fd5b5061060261236a565b348015610d3a57600080fd5b506103ff61236f565b348015610d4f57600080fd5b5061052a612375565b348015610d6457600080fd5b506104a060048036036020811015610d7b57600080fd5b50356001600160a01b031661237b565b348015610d9757600080fd5b506103ff6124a2565b606481565b61200181565b60005460609060ff16610df3576040805162461bcd60e51b81526020600482015260196024820152600080516020614905833981519152604482015290519081900360640190fd5b3361200014610e335760405162461bcd60e51b815260040180806020018281038252602f8152602001806148b3602f913960400191505060405180910390fd5b60ff841660021415610e8557610e7e83838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506124a892505050565b9050610ed2565b6040805162461bcd60e51b815260206004820152601860248201527f756e7265636f676e697a65642073796e207061636b6167650000000000000000604482015290519081900360640190fd5b9392505050565b60015490565b6020818101516000908152600490915260409020546001600160a01b03165b919050565b600181565b61100181565b670de0b6b3a764000081565b606181565b600881565b66071afd498d000081565b61200081565b6000908152600460205260409020546001600160a01b031690565b6402540be40081565b600281565b6000805460ff16610fa4576040805162461bcd60e51b81526020600482015260196024820152600080516020614905833981519152604482015290519081900360640190fd5b868514610fe25760405162461bcd60e51b815260040180806020018281038252603b815260200180614878603b913960400191505060405180910390fd5b8683146110205760405162461bcd60e51b815260040180806020018281038252603f81526020018061474b603f913960400191505060405180910390fd5b426078018267ffffffffffffffff16101561106c5760405162461bcd60e51b815260040180806020018281038252602481526020018061463b6024913960400191505060405180910390fd5b6402540be4003406156110b05760405162461bcd60e51b815260040180806020018281038252604081526020018061497b6040913960400191505060405180910390fd5b604080518681526020808802820101909152859060009081906060908480156110e3578160200160208202803683370190505b50905060005b848110156111be576402540be4008b8b8381811061110357fe5b905060200201358161111157fe5b061561114e5760405162461bcd60e51b815260040180806020018281038252603c81526020018061478a603c913960400191505060405180910390fd5b6111738b8b8381811061115d57fe5b90506020020135856125cc90919063ffffffff16565b935061119f6402540be4008c8c8481811061118a57fe5b9050602002013561262690919063ffffffff16565b8282815181106111ab57fe5b60209081029190910101526001016110e9565b506001546111e3906111d6908663ffffffff61266816565b849063ffffffff6125cc16565b3410156112215760405162461bcd60e51b81526004018080602001828103825260568152602001806149256056913960600191505060405180910390fd5b611231348463ffffffff6126c116565b915061123b614461565b6040518060c001604052806221272160e91b60001b815260200160006001600160a01b031681526020018381526020018e8e808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050908252506040805160208c810282810182019093528c82529283019290918d918d91829185019084908082843760009201919091525050509082525067ffffffffffffffff8916602090910152905061200063f7a251d760036112ff84612703565b611314876402540be40063ffffffff61262616565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561137257818101518382015260200161135a565b50505050905090810190601f16801561139f5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156113c057600080fd5b505af11580156113d4573d6000803e3d6000fd5b505060408051600081523360208201528082018890526060810187905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9350908190036080019150a15060019c9b505050505050505050505050565b61100581565b601081565b60015481565b600033612001146114865760405162461bcd60e51b815260040180806020018281038252603381526020018061457b6033913960400191505060405180910390fd5b6040516120019083156108fc029084906000818181858888f193505050501580156114b5573d6000803e3d6000fd5b50600192915050565b61100881565b600b81565b60005460ff1661150e576040805162461bcd60e51b81526020600482015260196024820152600080516020614905833981519152604482015290519081900360640190fd5b336120001461154e5760405162461bcd60e51b815260040180806020018281038252602f8152602001806148b3602f913960400191505060405180910390fd5b60ff83166003141561159e5761159982828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506129be92505050565b61160d565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a15b505050565b33611008146116525760405162461bcd60e51b81526004018080602001828103825260238152602001806148e26023913960400191505060405180910390fd5b600083815260046020908152604080832080546001600160a01b039096166001600160a01b03199096168617905593825260038152838220949094556002909352912055565b600981565b677ce66c50e284000081565b6000805460ff166116ef576040805162461bcd60e51b81526020600482015260196024820152600080516020614905833981519152604482015290519081900360640190fd5b336110051461172f5760405162461bcd60e51b815260040180806020018281038252602f8152602001806145ae602f913960400191505060405180910390fd5b600047831061173e5747611740565b825b9050670de0b6b3a764000081111561175c5760009150506117e1565b80156117de576040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015611798573d6000803e3d6000fd5b50604080516001600160a01b03861681526020810183905281517ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0929181900390910190a15b90505b92915050565b61100781565b61100681565b600081565b60005460ff1681565b600381565b6000805460ff1661184c576040805162461bcd60e51b81526020600482015260196024820152600080516020614905833981519152604482015290519081900360640190fd5b426078018267ffffffffffffffff1610156118985760405162461bcd60e51b815260040180806020018281038252602481526020018061463b6024913960400191505060405180910390fd5b6402540be4003406156118dc5760405162461bcd60e51b815260040180806020018281038252604081526020018061497b6040913960400191505060405180910390fd5b600080806001600160a01b0388166119bb5760015461190290879063ffffffff6125cc16565b3410156119405760405162461bcd60e51b81526004018080602001828103825260618152602001806146c56061913960800191505060405180910390fd5b6402540be4008606156119845760405162461bcd60e51b815260040180806020018281038252603c81526020018061478a603c913960400191505060405180910390fd5b611994348763ffffffff6126c116565b90506119ab866402540be40063ffffffff61262616565b6221272160e91b93509150611c5e565b6001600160a01b038816600090815260036020526040902054925082611a125760405162461bcd60e51b81526004018080602001828103825260318152602001806146946031913960400191505060405180910390fd5b600154341015611a535760405162461bcd60e51b815260040180806020018281038252603f8152602001806147e7603f913960400191505060405180910390fd5b506001600160a01b0387166000908152600260205260409020543490600881111580611a9e5750600881118015611a9e5750611a9c876007198301600a0a63ffffffff612a1a16565b155b611ad95760405162461bcd60e51b815260040180806020018281038252603c81526020018061478a603c913960400191505060405180910390fd5b611ae38782612a5c565b9250611aee84612a9c565b15611b36576305f5e100831015611b365760405162461bcd60e51b815260040180806020018281038252603a8152602001806145dd603a913960400191505060405180910390fd5b600881101580611b505750600881108015611b5057508683115b611b8b5760405162461bcd60e51b81526004018080602001828103825260258152602001806147266025913960400191505060405180910390fd5b677ce66c50e2840000831115611bd25760405162461bcd60e51b815260040180806020018281038252603581526020018061465f6035913960400191505060405180910390fd5b604080516323b872dd60e01b81523360048201523060248201526044810189905290516001600160a01b038b16916323b872dd9160648083019260209291908290030181600087803b158015611c2757600080fd5b505af1158015611c3b573d6000803e3d6000fd5b505050506040513d6020811015611c5157600080fd5b5051611c5c57600080fd5b505b611c66614461565b6040805160c0810182528581526001600160a01b038b166020820152815160018082528184018452919283019181602001602082028036833750505081526040805160018082528183019092526020928301929091908083019080368337505050815260408051600180825281830190925260209283019290919080830190803683370190505081526020018767ffffffffffffffff168152509050828160400151600081518110611d1457fe5b602002602001018181525050878160600151600081518110611d3257fe5b60200260200101906001600160a01b031690816001600160a01b031681525050338160800151600081518110611d6457fe5b6001600160a01b039092166020928302919091019091015261200063f7a251d76003611d8f84612703565b611da4866402540be40063ffffffff61262616565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611e02578181015183820152602001611dea565b50505050905090810190601f168015611e2f5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015611e5057600080fd5b505af1158015611e64573d6000803e3d6000fd5b5050604080516001600160a01b038d1681523360208201528082018b90526060810186905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9350908190036080019150a150600198975050505050505050565b3361100714611f075760405162461bcd60e51b815260040180806020018281038252602e815260200180614826602e913960400191505060405180910390fd5b60208114611f5c576040805162461bcd60e51b815260206004820152601b60248201527f65787065637465642076616c7565206c656e6774682069732033320000000000604482015290519081900360640190fd5b606084848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8801819004810282018101909252868152939450606093925086915085908190840183828082843760009201919091525050505060208301519091506772656c617946656560c01b811415612064576020820151670de0b6b3a7640000811180159061200b57506402540be4008106155b61205c576040805162461bcd60e51b815260206004820152601960248201527f7468652072656c6179466565206f7574206f662072616e676500000000000000604482015290519081900360640190fd5b6001556120a1565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a878787876040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050505050565b33611008146121765760405162461bcd60e51b81526004018080602001828103825260238152602001806148e26023913960400191505060405180910390fd5b600091825260046020908152604080842080546001600160a01b03191690556001600160a01b0392909216835260039052812055565b6221272160e91b81565b61c35081565b60026020526000908152604090205481565b6001600160a01b031660009081526003602052604090205490565b61100281565b60005460ff16612234576040805162461bcd60e51b81526020600482015260196024820152600080516020614905833981519152604482015290519081900360640190fd5b33612000146122745760405162461bcd60e51b815260040180806020018281038252602f8152602001806148b3602f913960400191505060405180910390fd5b60ff83166003141561159e5761159982828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612ba292505050565b61100381565b60005460ff161561231d576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b66071afd498d000060019081556000808052600260205260127fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b55805460ff19169091179055565b600481565b600581565b61100081565b61271081565b6001600160a01b03811660009081526003602090815260409182902054825182815280840190935260609290918391906020820181803683375050506020810183905290506000805b60208160ff16101561240b57828160ff16815181106123df57fe5b01602001516001600160f81b031916156123fe57600190910190612403565b61240b565b6001016123c4565b5060608160ff166040519080825280601f01601f19166020018201604052801561243c576020820181803683370190505b50905060005b8260ff168160ff16101561249857838160ff168151811061245f57fe5b602001015160f81c60f81b828260ff168151811061247957fe5b60200101906001600160f81b031916908160001a905350600101612442565b5095945050505050565b61100481565b60606124b26144ad565b60006124bd84612ca0565b9150915080612513576040805162461bcd60e51b815260206004820152601f60248201527f756e7265636f676e697a6564207472616e73666572496e207061636b61676500604482015290519081900360640190fd5b600061251e83612ddf565b905063ffffffff8116156125b2576040808401516020808601516001600160a01b031660009081526002909152918220546125599190612a5c565b90506125636144e2565b60405180608001604052808660000151815260200183815260200186608001516001600160a01b031681526020018463ffffffff1681525090506125a68161312c565b95505050505050610efe565b50506040805160008152602081019091529150610efe9050565b6000828201838110156117de576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60006117de83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613208565b600082612677575060006117e1565b8282028284828161268457fe5b04146117de5760405162461bcd60e51b81526004018080602001828103825260218152602001806147c66021913960400191505060405180910390fd5b60006117de83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506132aa565b60408051600680825260e08201909252606091829190816020015b606081526020019060019003908161271e575050835190915061274090613304565b8160008151811061274d57fe5b602002602001018190525061276e83602001516001600160a01b0316613317565b8160018151811061277b57fe5b6020026020010181905250600083604001515190506060816040519080825280602002602001820160405280156127c657816020015b60608152602001906001900390816127b15790505b50905060005b82811015612813576127f4866040015182815181106127e757fe5b6020026020010151613304565b82828151811061280057fe5b60209081029190910101526001016127cc565b5061281d8161333a565b8360028151811061282a57fe5b602002602001018190525060608260405190808252806020026020018201604052801561286b57816020015b60608152602001906001900390816128565790505b50905060005b838110156128c1576128a28760600151828151811061288c57fe5b60200260200101516001600160a01b0316613317565b8282815181106128ae57fe5b6020908102919091010152600101612871565b506128cb8161333a565b846003815181106128d857fe5b602002602001018190525060608360405190808252806020026020018201604052801561291957816020015b60608152602001906001900390816129045790505b50905060005b848110156129595761293a8860800151828151811061288c57fe5b82828151811061294657fe5b602090810291909101015260010161291f565b506129638161333a565b8560048151811061297057fe5b60200260200101819052506129928760a0015167ffffffffffffffff16613304565b8560058151811061299f57fe5b60200260200101819052506129b38561333a565b979650505050505050565b6129c6614509565b60006129d1836133c4565b9150915080612a115760405162461bcd60e51b81526004018080602001828103825260248152602001806148546024913960400191505060405180910390fd5b61160d8261358f565b60006117de83836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815250613a13565b60006008821115612a8557612a7e836007198401600a0a63ffffffff61262616565b90506117e1565b6117de836008849003600a0a63ffffffff61266816565b604080516020808252818301909252600091606091906020820181803683375050506020810184905290506000805b60208160ff161015612b1257828160ff1681518110612ae657fe5b01602001516001600160f81b03191615612b0557600190910190612b0a565b612b12565b600101612acb565b50600760ff82161015612b2a57600092505050610efe565b816005820360ff1681518110612b3c57fe5b6020910101516001600160f81b031916602d60f81b14612b6157600092505050610efe565b816001820360ff1681518110612b7357fe5b6020910101516001600160f81b031916604d60f81b14612b9857600092505050610efe565b5060019392505050565b612baa614461565b6000612bb583613a75565b9150915080612bf55760405162461bcd60e51b81526004018080602001828103825260248152602001806146176024913960400191505060405180910390fd5b612bfd614509565b602080840180516001600160a01b0390811684526040808701518585015291511660009081526002909252812054905b846040015151811015612c7e57612c5b85604001518281518110612c4d57fe5b602002602001015183613cd9565b85604001518281518110612c6b57fe5b6020908102919091010152600101612c2d565b506080840151604083015260056060830152612c998261358f565b5050505050565b612ca86144ad565b6000612cb26144ad565b612cba614540565b612ccb612cc686613d12565b613d37565b90506000805b612cda83613d81565b15612dd25780612cfc57612cf5612cf084613da2565b613df0565b8452612dca565b8060011415612d2957612d16612d1184613da2565b613ea7565b6001600160a01b03166020850152612dca565b8060021415612d4857612d3e612cf084613da2565b6040850152612dca565b8060031415612d7057612d5d612d1184613da2565b6001600160a01b03166060850152612dca565b8060041415612d9857612d85612d1184613da2565b6001600160a01b03166080850152612dca565b8060051415612dc557612dad612cf084613da2565b67ffffffffffffffff1660a085015260019150612dca565b612dd2565b600101612cd1565b5091935090915050915091565b60208101516000906001600160a01b0316612f16578160a0015167ffffffffffffffff16421115612e1257506001610efe565b8160400151471015612e2657506003610efe565b606082015160408084015190516000926001600160a01b0316916127109184818181858888f193505050503d8060008114612e7d576040519150601f19603f3d011682016040523d82523d6000602084013e612e82565b606091505b5050905080612e95575060049050610efe565b7f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5983602001518460600151856040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a15060009050610efe565b8160a0015167ffffffffffffffff16421115612f3457506001610efe565b81516020808401516001600160a01b031660009081526003909152604090205414612f6157506002610efe565b602080830151604080516370a0823160e01b815230600482015290516000936001600160a01b03909316926370a082319261c3509260248083019392829003018187803b158015612fb157600080fd5b5086fa158015612fc5573d6000803e3d6000fd5b50505050506040513d6020811015612fdc57600080fd5b50516040840151909150811015612ff7575060039050610efe565b600083602001516001600160a01b031663a9059cbb61c350866060015187604001516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b15801561306857600080fd5b5087f115801561307c573d6000803e3d6000fd5b50505050506040513d602081101561309357600080fd5b505190508015613120577f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5984602001518560600151866040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a15060009150610efe9050565b5060059150610efe9050565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081613147575050835190915061316990613304565b8160008151811061317657fe5b602002602001018190525061318e8360200151613304565b8160018151811061319b57fe5b60200260200101819052506131bc83604001516001600160a01b0316613317565b816002815181106131c957fe5b60200260200101819052506131e7836060015163ffffffff16613304565b816003815181106131f457fe5b6020026020010181905250610ed28161333a565b600081836132945760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613259578181015183820152602001613241565b50505050905090810190601f1680156132865780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816132a057fe5b0495945050505050565b600081848411156132fc5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613259578181015183820152602001613241565b505050900390565b60606117e161331283613ec1565b613fa7565b60408051600560a21b8318601482015260348101909152606090610ed281613fa7565b606081516000141561335b5750604080516000815260208101909152610efe565b60608260008151811061336a57fe5b602002602001015190506000600190505b83518110156133ab576133a18285838151811061339457fe5b6020026020010151613ff9565b915060010161337b565b50610ed26133be825160c060ff16614076565b82613ff9565b6133cc614509565b60006133d6614509565b6133de614540565b6133ea612cc686613d12565b90506000805b6133f983613d81565b15612dd2578061341f5761340f612d1184613da2565b6001600160a01b03168452613587565b80600114156134c057606061343b61343685613da2565b61416e565b90508051604051908082528060200260200182016040528015613468578160200160208202803683370190505b50602086015260005b81518110156134b95761349682828151811061348957fe5b6020026020010151613df0565b866020015182815181106134a657fe5b6020908102919091010152600101613471565b5050613587565b80600214156135625760606134d761343685613da2565b90508051604051908082528060200260200182016040528015613504578160200160208202803683370190505b50604086015260005b81518110156134b95761353282828151811061352557fe5b6020026020010151613ea7565b8660400151828151811061354257fe5b6001600160a01b039092166020928302919091019091015260010161350d565b8060031415612dc557613577612cf084613da2565b63ffffffff166060850152600191505b6001016133f0565b80516001600160a01b03166137b95760005b8160200151518110156137b3576000826040015182815181106135c057fe5b60200260200101516001600160a01b0316612710846020015184815181106135e457fe5b60209081029190910101516040516000818181858888f193505050503d806000811461362c576040519150601f19603f3d011682016040523d82523d6000602084013e613631565b606091505b50509050806136f4577f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e83600001518460400151848151811061367057fe5b60200260200101518560200151858151811061368857fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a16137aa565b7fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a83600001518460400151848151811061372a57fe5b60200260200101518560200151858151811061374257fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b506001016135a1565b50613a10565b60005b816020015151811015613a0e57600082600001516001600160a01b031663a9059cbb61c350856040015185815181106137f157fe5b60200260200101518660200151868151811061380957fe5b60200260200101516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b15801561386057600080fd5b5087f1158015613874573d6000803e3d6000fd5b50505050506040513d602081101561388b57600080fd5b50519050801561394f577fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a8360000151846040015184815181106138cb57fe5b6020026020010151856020015185815181106138e357fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a1613a05565b7f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e83600001518460400151848151811061398557fe5b60200260200101518560200151858151811061399d57fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b506001016137bc565b505b50565b60008183613a625760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315613259578181015183820152602001613241565b50828481613a6c57fe5b06949350505050565b613a7d614461565b6000613a87614461565b613a8f614540565b613a9b612cc686613d12565b90506000805b613aaa83613d81565b15612dd25780613ac757613ac0612cf084613da2565b8452613cd1565b8060011415613aef57613adc612d1184613da2565b6001600160a01b03166020850152613cd1565b8060021415613b7e576060613b0661343685613da2565b90508051604051908082528060200260200182016040528015613b33578160200160208202803683370190505b50604086015260005b8151811015613b7757613b5482828151811061348957fe5b86604001518281518110613b6457fe5b6020908102919091010152600101613b3c565b5050613cd1565b8060031415613c13576060613b9561343685613da2565b90508051604051908082528060200260200182016040528015613bc2578160200160208202803683370190505b50606086015260005b8151811015613b7757613be382828151811061352557fe5b86606001518281518110613bf357fe5b6001600160a01b0390921660209283029190910190910152600101613bcb565b8060041415613ca8576060613c2a61343685613da2565b90508051604051908082528060200260200182016040528015613c57578160200160208202803683370190505b50608086015260005b8151811015613b7757613c7882828151811061352557fe5b86608001518281518110613c8857fe5b6001600160a01b0390921660209283029190910190910152600101613c60565b8060051415612dc557613cbd612cf084613da2565b67ffffffffffffffff1660a0850152600191505b600101613aa1565b60006008821115613cfb57612a7e836007198401600a0a63ffffffff61266816565b6117de836008849003600a0a63ffffffff61262616565b613d1a614560565b506040805180820190915281518152602082810190820152919050565b613d3f614540565b613d488261423f565b613d5157600080fd5b6000613d60836020015161426f565b60208085015160408051808201909152868152920190820152915050919050565b6000613d8b614560565b505080518051602091820151919092015191011190565b613daa614560565b613db382613d81565b613dbc57600080fd5b60208201516000613dcc826142d2565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590613e0557508151602110155b613e0e57600080fd5b6000613e1d836020015161426f565b90508083600001511015613e78576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b825160208085015183018051928490039291831015613e9e57826020036101000a820491505b50949350505050565b8051600090601514613eb857600080fd5b6117e182613df0565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416613f0557506018613f29565b6fffffffffffffffffffffffffffffffff198416613f2557506010613f29565b5060005b6020811015613f5f57818181518110613f3e57fe5b01602001516001600160f81b03191615613f5757613f5f565b600101613f29565b60008160200390506060816040519080825280601f01601f191660200182016040528015613f94576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015613fd95750607f60f81b82600081518110613fc757fe5b01602001516001600160f81b03191611155b15613fe5575080610efe565b6117e1613ff78351608060ff16614076565b835b6060806040519050835180825260208201818101602087015b8183101561402a578051835260209283019201614012565b50855184518101855292509050808201602086015b8183101561405757805183526020928301920161403f565b508651929092011591909101601f01601f191660405250905092915050565b60606801000000000000000083106140c6576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b604080516001808252818301909252606091602082018180368337019050509050603784116141205782840160f81b8160008151811061410257fe5b60200101906001600160f81b031916908160001a90535090506117e1565b606061412b85613ec1565b90508381510160370160f81b8260008151811061414457fe5b60200101906001600160f81b031916908160001a9053506141658282613ff9565b95945050505050565b60606141798261423f565b61418257600080fd5b600061418d83614405565b90506060816040519080825280602002602001820160405280156141cb57816020015b6141b8614560565b8152602001906001900390816141b05790505b50905060006141dd856020015161426f565b60208601510190506000805b84811015614234576141fa836142d2565b915060405180604001604052808381526020018481525084828151811061421d57fe5b6020908102919091010152918101916001016141e9565b509195945050505050565b805160009061425057506000610efe565b6020820151805160001a9060c0821015612b9857600092505050610efe565b8051600090811a6080811015614289576000915050610efe565b60b88110806142a4575060c081108015906142a4575060f881105b156142b3576001915050610efe565b60c08110156142c75760b519019050610efe565b60f519019050610efe565b80516000908190811a60808110156142ed57600191506143fe565b60b881101561430257607e19810191506143fe565b60c081101561437c57600060b78203600186019550806020036101000a865104915060018101820193505080831015614376576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b506143fe565b60f88110156143915760be19810191506143fe565b600060f78203600186019550806020036101000a8651049150600181018201935050808310156143fc576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b805160009061441657506000610efe565b6000809050600061442a846020015161426f565b602085015185519181019250015b8082101561445857614449826142d2565b60019093019290910190614438565b50909392505050565b6040518060c001604052806000801916815260200160006001600160a01b03168152602001606081526020016060815260200160608152602001600067ffffffffffffffff1681525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b60408051608081018252600080825260208201819052918101829052606081019190915290565b604051806080016040528060006001600160a01b031681526020016060815260200160608152602001600063ffffffff1681525090565b6040518060400160405280614553614560565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe6f6e6c79207374616b696e672073797374656d20636f6e74726163742063616e2063616c6c20746869732066756e6374696f6e746865206d6573736167652073656e646572206d75737420626520696e63656e746976697a6520636f6e7472616374466f72206d696e69546f6b656e2c20746865207472616e7366657220616d6f756e74206d757374206e6f74206265206c657373207468616e2031756e7265636f676e697a6564207472616e736665724f75742073796e207061636b61676565787069726554696d65206d7573742062652074776f206d696e75746573206c61746572616d6f756e7420697320746f6f206c617267652c20657863656564206d6178696d756d206265703220746f6b656e20616d6f756e7474686520636f6e747261637420686173206e6f74206265656e20626f756e6420746f20616e79206265703220746f6b656e726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e736665724f757420424e4220616d6f756e7420616e64206d696e696d756d2072656c6179466565616d6f756e7420697320746f6f206c617267652c2075696e74323536206f766572666c6f774c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620726566756e644164647273696e76616c6964207472616e7366657220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e20746865206d696e696d756d2072656c6179466565746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374756e7265636f676e697a6564207472616e736665724f75742061636b207061636b6167654c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620616d6f756e7473746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d73672073656e646572206d75737420626520746f6b656e4d616e6167657274686520636f6e7472616374206e6f7420696e69742079657400000000000000726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e7366657220424e4220616d6f756e7420616e642072656c6179466565696e76616c696420726563656976656420424e4220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6ea2646970667358221220caf56ff249aa6ca806ce69d2892ae51c7530b6d135624d7e27646a2095f0b01964736f6c63430006040033", + }, + { + ContractAddr: common.HexToAddress(StakingContract), + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/9d45b31c12b2c04757284717f4351cb44e81a3a7", + Code: "60806040526004361061036f5760003560e01c806370fd5bad116101c6578063b88a802f116100f7578063d7ecfcb611610095578063f45fd80b1161006f578063f45fd80b14610bd0578063f9a2bbc714610c15578063fc3e590814610646578063fd6a687914610c2a57610376565b8063d7ecfcb6146107ee578063dc927faf14610ba6578063edc1a5b014610bbb57610376565b8063c2117d82116100d1578063c2117d8214610abc578063c81b166214610ad1578063c8509d8114610ae6578063d61b9b9314610b6b57610376565b8063b88a802f14610a57578063baaafd3b14610a6c578063bf8546ca14610a8157610376565b806396713da911610164578063a78abc161161013e578063a78abc1614610939578063ab51bb9614610962578063ac43175114610977578063b14315df14610a4257610376565b806396713da9146108fa5780639dc092621461090f578063a1a11bf51461092457610376565b806375d47a0a116101a057806375d47a0a1461084b5780637942fd0514610860578063831d65d11461087557806392b888a4146105f257610376565b806370fd5bad146107ee578063718a8aa81461080357806375aca5931461081857610376565b8063413d9c3a116102a05780635d17c8bd1161023e57806369b635b61161021857806369b635b61461075b5780636bd8f804146107705780636e47b482146107a65780636fb7f7eb146107bb57610376565b80635d17c8bd1461071c5780635d499b1b1461073157806362b171d21461074657610376565b80634bf6c8821161027a5780634bf6c882146106b15780634d99dd16146106c657806351e80672146106f2578063552aaf931461070757610376565b8063413d9c3a1461065b57806343756e5c14610670578063493279b11461068557610376565b8063151817e31161030d578063333ad3e7116102e7578063333ad3e71461061c57806334c43354146106315780633dffc387146105f25780633fdfa7e41461064657610376565b8063151817e3146105c757806317c9efb0146105f25780632fdeb1111461060757610376565b80630bee7a67116103495780630bee7a671461043b5780630e2374a5146104695780631182b8751461049a57806311fe9ec61461059457610376565b8063026e402b1461037b57806302985992146103a9578063047636d1146103d057610376565b3661037657005b600080fd5b6103a76004803603604081101561039157600080fd5b506001600160a01b038135169060200135610c3f565b005b3480156103b557600080fd5b506103be611141565b60408051918252519081900360200190f35b3480156103dc57600080fd5b50610403600480360360208110156103f357600080fd5b50356001600160a01b0316611147565b6040518082606080838360005b83811015610428578181015183820152602001610410565b5050505090500191505060405180910390f35b34801561044757600080fd5b5061045061119b565b6040805163ffffffff9092168252519081900360200190f35b34801561047557600080fd5b5061047e6111a0565b604080516001600160a01b039092168252519081900360200190f35b3480156104a657600080fd5b5061051f600480360360408110156104bd57600080fd5b60ff8235169190810190604081016020820135600160201b8111156104e157600080fd5b8201836020820111156104f357600080fd5b803590602001918460018302840111600160201b8311171561051457600080fd5b5090925090506111a6565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610559578181015183820152602001610541565b50505050905090810190601f1680156105865780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156105a057600080fd5b506103be600480360360208110156105b757600080fd5b50356001600160a01b031661135c565b3480156105d357600080fd5b506105dc611377565b6040805160ff9092168252519081900360200190f35b3480156105fe57600080fd5b506105dc61137c565b34801561061357600080fd5b506103be611381565b34801561062857600080fd5b50610450611387565b34801561063d57600080fd5b506103be61138c565b34801561065257600080fd5b506105dc611397565b34801561066757600080fd5b506103be61139c565b34801561067c57600080fd5b5061047e6113a3565b34801561069157600080fd5b5061069a6113a9565b6040805161ffff9092168252519081900360200190f35b3480156106bd57600080fd5b506105dc6113ae565b6103a7600480360360408110156106dc57600080fd5b506001600160a01b0381351690602001356113b3565b3480156106fe57600080fd5b5061047e61199a565b34801561071357600080fd5b506105dc6119a0565b34801561072857600080fd5b506103be6119a5565b34801561073d57600080fd5b506103be6119ab565b34801561075257600080fd5b506103be6119b4565b34801561076757600080fd5b506103be611aec565b6103a76004803603606081101561078657600080fd5b506001600160a01b03813581169160208101359091169060400135611af2565b3480156107b257600080fd5b5061047e612160565b3480156107c757600080fd5b506103be600480360360208110156107de57600080fd5b50356001600160a01b0316612166565b3480156107fa57600080fd5b506105dc612181565b34801561080f57600080fd5b506105dc612186565b34801561082457600080fd5b506103be6004803603602081101561083b57600080fd5b50356001600160a01b031661218b565b34801561085757600080fd5b5061047e6121a6565b34801561086c57600080fd5b506105dc6121ac565b34801561088157600080fd5b506103a76004803603604081101561089857600080fd5b60ff8235169190810190604081016020820135600160201b8111156108bc57600080fd5b8201836020820111156108ce57600080fd5b803590602001918460018302840111600160201b831117156108ef57600080fd5b5090925090506121b1565b34801561090657600080fd5b506105dc612473565b34801561091b57600080fd5b5061047e612478565b34801561093057600080fd5b5061047e61247e565b34801561094557600080fd5b5061094e612484565b604080519115158252519081900360200190f35b34801561096e57600080fd5b506104506119a0565b34801561098357600080fd5b506103a76004803603604081101561099a57600080fd5b810190602081018135600160201b8111156109b457600080fd5b8201836020820111156109c657600080fd5b803590602001918460018302840111600160201b831117156109e757600080fd5b919390929091602081019035600160201b811115610a0457600080fd5b820183602082011115610a1657600080fd5b803590602001918460018302840111600160201b83111715610a3757600080fd5b50909250905061248d565b348015610a4e57600080fd5b506105dc612a8a565b348015610a6357600080fd5b506103be612a8f565b348015610a7857600080fd5b506103be612bc4565b348015610a8d57600080fd5b506103be60048036036040811015610aa457600080fd5b506001600160a01b0381358116916020013516612bcf565b348015610ac857600080fd5b506103be612bfc565b348015610add57600080fd5b5061047e612c02565b348015610af257600080fd5b506103a760048036036040811015610b0957600080fd5b60ff8235169190810190604081016020820135600160201b811115610b2d57600080fd5b820183602082011115610b3f57600080fd5b803590602001918460018302840111600160201b83111715610b6057600080fd5b509092509050612c08565b348015610b7757600080fd5b506103be60048036036040811015610b8e57600080fd5b506001600160a01b0381358116916020013516612e25565b348015610bb257600080fd5b5061047e612e50565b348015610bc757600080fd5b506103be612e56565b348015610bdc57600080fd5b506103be60048036036060811015610bf357600080fd5b506001600160a01b038135811691602081013582169160409091013516612e63565b348015610c2157600080fd5b5061047e612e98565b348015610c3657600080fd5b5061047e612e9e565b60105460ff1660021415610c8b576040805162461bcd60e51b815260206004820152600e60248201526d4e6f2072652d656e7472616e637960901b604482015290519081900360640190fd5b6010805460ff19166002179055806402540be4003406158015610cb357506402540be4008106155b610d04576040805162461bcd60e51b815260206004820152601c60248201527f707265636973696f6e206c6f737320696e20636f6e76657273696f6e00000000604482015290519081900360640190fd5b60005460ff16610d41576638d7ea4c6800006001908155662386f26fc1000060025568056bc75e2d631000006003556000805460ff191690911790555b600354821015610d98576040805162461bcd60e51b815260206004820152601760248201527f696e76616c69642064656c656761746520616d6f756e74000000000000000000604482015290519081900360640190fd5b600154610dac90839063ffffffff612ea416565b341015610df7576040805162461bcd60e51b81526020600482015260146024820152736e6f7420656e6f756768206d73672076616c756560601b604482015290519081900360640190fd5b60405133906108fc9060009081818181818888f19350505050610e55576040805162461bcd60e51b815260206004820152601160248201527034b73b30b634b2103232b632b3b0ba37b960791b604482015290519081900360640190fd5b6000610e6c836402540be40063ffffffff612f0516565b90506000610e80348563ffffffff612f4716565b90506000610e9960025483612f4790919063ffffffff16565b6040805160038082526080820190925291925060609190816020015b6060815260200190600190039081610eb5579050509050610ed533612f89565b81600081518110610ee257fe5b6020026020010181905250610eff876001600160a01b0316612f89565b81600181518110610f0c57fe5b6020026020010181905250610f2084612fac565b81600281518110610f2d57fe5b60200260200101819052506060610f4d6001610f4884612fbf565b613049565b8051602080830191909120600f80546000908152600a845260408082209390935581546001908101909255338152600b909352912080549091019055905061200063f7a251d7601083610fab876402540be40063ffffffff612f0516565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611009578181015183820152602001610ff1565b50505050905090810190601f1680156110365780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561105757600080fd5b505af115801561106b573d6000803e3d6000fd5b5061100492506108fc91506110889050898663ffffffff612ea416565b6040518115909202916000818181858888f193505050501580156110b0573d6000803e3d6000fd5b506002546040516110029180156108fc02916000818181858888f193505050501580156110e1573d6000803e3d6000fd5b50604080518881526020810185905281516001600160a01b038b169233927f5f32ed2794e2e72d19e3cb2320e8820a499c4204887372beba51f5e61c040867929081900390910190a350506010805460ff19166001179055505050505050565b60035481565b61114f614dd9565b611157614dd9565b6001600160a01b0383166000818152600b60209081526040808320548552838352600c82528083205485830152928252600d9052819020549082015290505b919050565b606481565b61200181565b606033612000146111e85760405162461bcd60e51b815260040180806020018281038252602f815260200180614f97602f913960400191505060405180910390fd5b60005460ff16611225576638d7ea4c6800006001908155662386f26fc1000060025568056bc75e2d631000006003556000805460ff191690911790555b61122d614df7565b61127461126f85858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506130cf92505050565b6130f4565b905060006112896112848361313e565b61318c565b90506000606060ff8316600414156112ae576112a484613243565b9092509050611305565b60ff8316600514156112c3576112a484613423565b6040805162461bcd60e51b8152602060048201526012602482015271756e6b6e6f776e206576656e74207479706560701b604482015290519081900360640190fd5b63ffffffff821615611351576040805163ffffffff84168152905160ff8516917f391d6e5ea6ab6c49b9a0abb1782cae5def8d711f973b00c729658c0b2a80b31b919081900360200190a25b979650505050505050565b6001600160a01b031660009081526006602052604090205490565b600581565b600181565b60015481565b606581565b662386f26fc1000081565b600381565b620a8c0081565b61100181565b606181565b600881565b60105460ff16600214156113ff576040805162461bcd60e51b815260206004820152600e60248201526d4e6f2072652d656e7472616e637960901b604482015290519081900360640190fd5b6010805460ff19166002179055806402540be400340615801561142757506402540be4008106155b611478576040805162461bcd60e51b815260206004820152601c60248201527f707265636973696f6e206c6f737320696e20636f6e76657273696f6e00000000604482015290519081900360640190fd5b60005460ff166114b5576638d7ea4c6800006001908155662386f26fc1000060025568056bc75e2d631000006003556000805460ff191690911790555b600154341015611503576040805162461bcd60e51b81526020600482015260146024820152736e6f7420656e6f7567682072656c61792066656560601b604482015290519081900360640190fd5b6003548210156115be576002548211611556576040805162461bcd60e51b815260206004820152601060248201526f6e6f7420656e6f7567682066756e647360801b604482015290519081900360640190fd5b3360009081526005602090815260408083206001600160a01b038716845290915290205482146115be576040805162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b604482015290519081900360640190fd5b3360009081526005602090815260408083206001600160a01b0387168452909152902054821115611627576040805162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b604482015290519081900360640190fd5b3360009081526007602090815260408083206001600160a01b038716845290915290205442101561169f576040805162461bcd60e51b815260206004820152601a60248201527f70656e64696e6720756e64656c65676174696f6e206578697374000000000000604482015290519081900360640190fd5b60006116b6836402540be40063ffffffff612f0516565b60025490915034906000906116d290839063ffffffff612f4716565b6040805160038082526080820190925291925060609190816020015b60608152602001906001900390816116ee57905050905061170e33612f89565b8160008151811061171b57fe5b6020026020010181905250611738876001600160a01b0316612f89565b8160018151811061174557fe5b602002602001018190525061175984612fac565b8160028151811061176657fe5b602002602001018190525060606117816002610f4884612fbf565b8051602080830191909120600f80546000908152600a845260408082209390935581546001908101909255338152600c90935291208054909101905590506117d242620a8c0063ffffffff612ea416565b3360009081526007602090815260408083206001600160a01b038d16845290915290205561200063f7a251d7601083611816876402540be40063ffffffff612f0516565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561187457818101518382015260200161185c565b50505050905090810190601f1680156118a15780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156118c257600080fd5b505af11580156118d6573d6000803e3d6000fd5b5050604051611004925085156108fc02915085906000818181858888f19350505050158015611909573d6000803e3d6000fd5b506002546040516110029180156108fc02916000818181858888f1935050505015801561193a573d6000803e3d6000fd5b50604080518881526020810185905281516001600160a01b038b169233927fdf0b6ac27f3f3bb31cee3dab0f4fe40cc19c6a3f8daaec52e06b261e58a12519929081900390910190a350506010805460ff19166001179055505050505050565b61200081565b600081565b60025481565b6402540be40081565b60105460009060ff1660021415611a03576040805162461bcd60e51b815260206004820152600e60248201526d4e6f2072652d656e7472616e637960901b604482015290519081900360640190fd5b506010805460ff191660021790553360009081526008602052604090205480611a6a576040805162461bcd60e51b81526020600482015260146024820152736e6f20756e64656c6567617465642066756e647360601b604482015290519081900360640190fd5b336000818152600860205260408082208290555183156108fc0291849190818181858888f19350505050158015611aa5573d6000803e3d6000fd5b5060408051828152905133917fc712d133b8d448221aaed2198ed1f0db6dfc860fb01bc3a630916fe6cbef946f919081900360200190a26010805460ff1916600117905590565b60035490565b60105460ff1660021415611b3e576040805162461bcd60e51b815260206004820152600e60248201526d4e6f2072652d656e7472616e637960901b604482015290519081900360640190fd5b6010805460ff19166002179055806402540be4003406158015611b6657506402540be4008106155b611bb7576040805162461bcd60e51b815260206004820152601c60248201527f707265636973696f6e206c6f737320696e20636f6e76657273696f6e00000000604482015290519081900360640190fd5b60005460ff16611bf4576638d7ea4c6800006001908155662386f26fc1000060025568056bc75e2d631000006003556000805460ff191690911790555b826001600160a01b0316846001600160a01b03161415611c52576040805162461bcd60e51b815260206004820152601460248201527334b73b30b634b2103932b232b632b3b0ba34b7b760611b604482015290519081900360640190fd5b600154341015611ca0576040805162461bcd60e51b81526020600482015260146024820152736e6f7420656e6f7567682072656c61792066656560601b604482015290519081900360640190fd5b6003548210158015611cd557503360009081526005602090815260408083206001600160a01b03881684529091529020548211155b611d17576040805162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b604482015290519081900360640190fd5b3360009081526009602090815260408083206001600160a01b03888116855290835281842090871684529091529020544210801590611d8557503360009081526009602090815260408083206001600160a01b03878116855290835281842090881684529091529020544210155b611dd6576040805162461bcd60e51b815260206004820152601a60248201527f70656e64696e6720726564656c65676174696f6e206578697374000000000000604482015290519081900360640190fd5b6000611ded836402540be40063ffffffff612f0516565b6002549091503490600090611e0990839063ffffffff612f4716565b60408051600480825260a0820190925291925060609190816020015b6060815260200190600190039081611e25579050509050611e4533612f89565b81600081518110611e5257fe5b6020026020010181905250611e6f886001600160a01b0316612f89565b81600181518110611e7c57fe5b6020026020010181905250611e99876001600160a01b0316612f89565b81600281518110611ea657fe5b6020026020010181905250611eba84612fac565b81600381518110611ec757fe5b60200260200101819052506060611ee26003610f4884612fbf565b8051602080830191909120600f80546000908152600a845260408082209390935581546001908101909255338152600d9093529120805490910190559050611f3342620a8c0063ffffffff612ea416565b3360009081526009602090815260408083206001600160a01b038d81168552908352818420908e168452909152902055611f7642620a8c0063ffffffff612ea416565b3360009081526009602090815260408083206001600160a01b038e81168552908352818420908d16845290915290205561200063f7a251d7601083611fc6876402540be40063ffffffff612f0516565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561202457818101518382015260200161200c565b50505050905090810190601f1680156120515780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561207257600080fd5b505af1158015612086573d6000803e3d6000fd5b5050604051611004925085156108fc02915085906000818181858888f193505050501580156120b9573d6000803e3d6000fd5b506002546040516110029180156108fc02916000818181858888f193505050501580156120ea573d6000803e3d6000fd5b50876001600160a01b0316896001600160a01b0316336001600160a01b03167fdb0d03fdfcb145c486c442659e6a341a8828985505097cb5190afcf541e840158a87604051808381526020018281526020019250505060405180910390a450506010805460ff1916600117905550505050505050565b61100581565b6001600160a01b031660009081526004602052604090205490565b600281565b601081565b6001600160a01b031660009081526008602052604090205490565b61100881565b600b81565b33612000146121f15760405162461bcd60e51b815260040180806020018281038252602f815260200180614f97602f913960400191505060405180910390fd5b60005460ff1661222e576638d7ea4c6800006001908155662386f26fc1000060025568056bc75e2d631000006003556000805460ff191690911790555b612236614df7565b61227861126f84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506130cf92505050565b905060008060606000805b61228c8661363f565b156122f757806122a9576122a26112848761313e565b94506122ef565b80600114156122c5576122be6112848761313e565b93506122ef565b80600214156122ea576122df6122da8761313e565b613660565b9250600191506122ef565b6122f7565b600101612283565b8161233d576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b612346836136d0565b612389576040805162461bcd60e51b815260206004820152600f60248201526e0eee4dedcce40e0c2c6d640d0c2e6d608b1b604482015290519081900360640190fd5b61239561126f846130cf565b955060006123a56112848861313e565b90506123af614df7565b6123b88861363f565b156123db576123d461126f6123cf6122da8b61313e565b6130cf565b905061241c565b6040805162461bcd60e51b8152602060048201526011602482015270656d7074792061636b207061636b61676560781b604482015290519081900360640190fd5b60ff82166001141561243857612433818888613724565b612466565b60ff82166002141561244f57612433818888613adb565b60ff8216600314156112c357612433818888613da8565b5050505050505050505050565b600981565b61100781565b61100681565b60005460ff1681565b60005460ff166124e4576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604482015290519081900360640190fd5b33611007146125245760405162461bcd60e51b815260040180806020018281038252602e815260200180614f0d602e913960400191505060405180910390fd5b61258584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600a81526972656c6179657246656560b01b6020820152915061410d9050565b156126eb57602081146125df576040805162461bcd60e51b815260206004820152601d60248201527f6c656e677468206f662072656c61796572466565206d69736d61746368000000604482015290519081900360640190fd5b604080516020601f840181900481028201810190925282815260009161261d918585808385018382808284376000920191909152506141f492505050565b9050600354811061265f5760405162461bcd60e51b815260040180806020018281038252602e815260200180614f3b602e913960400191505060405180910390fd5b600254811161269f5760405162461bcd60e51b815260040180806020018281038252602e815260200180614f69602e913960400191505060405180910390fd5b6402540be4008106156126e35760405162461bcd60e51b815260040180806020018281038252602c815260200180614ee1602c913960400191505060405180910390fd5b6001556129f8565b61274f84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c62534352656c6179657246656560981b6020820152915061410d9050565b1561287557602081146127a9576040805162461bcd60e51b815260206004820181905260248201527f6c656e677468206f662062534352656c61796572466565206d69736d61746368604482015290519081900360640190fd5b604080516020601f84018190048102820181019092528281526000916127e7918585808385018382808284376000920191909152506141f492505050565b905060015481106128295760405162461bcd60e51b815260040180806020018281038252602e815260200180614e61602e913960400191505060405180910390fd5b6402540be40081061561286d5760405162461bcd60e51b815260040180806020018281038252602f815260200180614e32602f913960400191505060405180910390fd5b6002556129f8565b6128d984848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c36b4b72232b632b3b0ba34b7b760991b6020820152915061410d9050565b156129bb5760208114612933576040805162461bcd60e51b815260206004820181905260248201527f6c656e677468206f66206d696e44656c65676174696f6e206d69736d61746368604482015290519081900360640190fd5b604080516020601f8401819004810282018101909252828152600091612971918585808385018382808284376000920191909152506141f492505050565b905060015481116129b35760405162461bcd60e51b8152600401808060200182810382526031815260200180614e8f6031913960400191505060405180910390fd5b6003556129f8565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b600481565b60105460009060ff1660021415612ade576040805162461bcd60e51b815260206004820152600e60248201526d4e6f2072652d656e7472616e637960901b604482015290519081900360640190fd5b506010805460ff191660021790553360009081526006602052604090205480612b42576040805162461bcd60e51b81526020600482015260116024820152701b9bc81c195b991a5b99c81c995dd85c99607a1b604482015290519081900360640190fd5b336000818152600660205260408082208290555183156108fc0291849190818181858888f19350505050158015612b7d573d6000803e3d6000fd5b5060408051828152905133917f83b78188b13346b2ffb484da70d42ee27de7fbf9f2bd8045269e10ed643ccd76919081900360200190a26010805460ff1916600117905590565b6638d7ea4c68000081565b6001600160a01b038083166000908152600760209081526040808320938516835292905220545b92915050565b60015490565b61100281565b3361200014612c485760405162461bcd60e51b815260040180806020018281038252602f815260200180614f97602f913960400191505060405180910390fd5b60005460ff16612c85576638d7ea4c6800006001908155662386f26fc1000060025568056bc75e2d631000006003556000805460ff191690911790555b612cc482828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506136d092505050565b612d07576040805162461bcd60e51b815260206004820152600f60248201526e0eee4dedcce40e0c2c6d640d0c2e6d608b1b604482015290519081900360640190fd5b612d0f614df7565b612d5161126f84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506130cf92505050565b90506000612d616112848361313e565b9050612d6b614df7565b612d748361363f565b15612d9257612d8b61126f6123cf6122da8661313e565b9050612dd8565b6040805162461bcd60e51b8152602060048201526016602482015275656d707479206661696c2061636b207061636b61676560501b604482015290519081900360640190fd5b60ff821660011415612df257612ded816141f9565b612e1c565b60ff821660021415612e0757612ded81614413565b60ff8216600314156112c357612ded8161453d565b5050505b505050565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205490565b61100381565b68056bc75e2d6310000081565b6001600160a01b0392831660009081526009602090815260408083209486168352938152838220929094168152925290205490565b61100081565b61100481565b600082820183811015612efe576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6000612efe83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506146a2565b6000612efe83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614744565b60408051600560a21b8318601482015260348101909152606090612efe8161479e565b6060612bf6612fba836147f4565b61479e565b6060815160001415612fe05750604080516000815260208101909152611196565b606082600081518110612fef57fe5b602002602001015190506000600190505b8351811015613030576130268285838151811061301957fe5b60200260200101516148da565b9150600101613000565b50612efe613043825160c060ff16614957565b826148da565b6040805160028082526060828101909352829190816020015b60608152602001906001900390816130625790505090506130858460ff16612fac565b8160008151811061309257fe5b60200260200101819052506130a68361479e565b816001815181106130b357fe5b60200260200101819052506130c781612fbf565b949350505050565b6130d7614e17565b506040805180820190915281518152602082810190820152919050565b6130fc614df7565b61310582614a4f565b61310e57600080fd5b600061311d8360200151614a89565b60208085015160408051808201909152868152920190820152915050919050565b613146614e17565b61314f8261363f565b61315857600080fd5b6020820151600061316882614aec565b80830160209586015260408051808201909152908152938401919091525090919050565b8051600090158015906131a157508151602110155b6131aa57600080fd5b60006131b98360200151614a89565b90508083600001511015613214576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b82516020808501518301805192849003929183101561323a57826020036101000a820491505b50949350505050565b600060606000806000805b6132578761363f565b156132a957826132795761327261326d8861313e565b614c1f565b915061329e565b82600114156132995761328e6112848861313e565b90506001935061329e565b6132a9565b82600101925061324e565b836132ef576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b60006110046001600160a01b031663727be1f8836040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b15801561333957600080fd5b505af115801561334d573d6000803e3d6000fd5b505050506040513d602081101561336357600080fd5b50519050806133885761337a600484846065614c39565b96509650505050505061341e565b6001600160a01b0383166000908152600660205260409020546133b1908363ffffffff612ea416565b6001600160a01b038416600081815260066020908152604091829020939093558051858152905191927f7cc266c7b444f808013fa187f7b904d470a051a6564e78f482aa496581ba4bf892918290030190a260408051600080825260208201909252909750955050505050505b915091565b6000606060008060008060005b6134398861363f565b156134a257836134565761344f61326d8961313e565b9250613497565b83600114156134725761346b61326d8961313e565b9150613497565b8360021415613492576134876112848961313e565b905060019450613497565b6134a2565b836001019350613430565b846134e8576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b60006110046001600160a01b031663727be1f8836040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b15801561353257600080fd5b505af1158015613546573d6000803e3d6000fd5b505050506040513d602081101561355c57600080fd5b505190508061358257613573600585846065614c39565b9750975050505050505061341e565b6001600160a01b0380851660008181526007602090815260408083209488168352938152838220829055918152600890915220546135c6908363ffffffff612ea416565b6001600160a01b0380861660008181526008602090815260409182902094909455805186815290519287169391927f35a799836f74fac7eccf5c73902823b970543d2274d3b93d8da3d37a255772a2929181900390910190a3604080516000808252602082019092529098509650505050505050915091565b6000613649614e17565b505080518051602091820151919092015191011190565b805160609061366e57600080fd5b600061367d8360200151614a89565b83516040805191839003808352601f19601f82011683016020019091529192506060908280156136b4576020820181803683370190505b509050600081602001905061323a848760200151018285614d35565b8051602080830191909120600e546000908152600a90925260408220548082146136ff57600092505050611196565b5050600e80546000908152600a60205260408120558054600190810190915592915050565b60008060008060005b6137368861363f565b1561379f57836137535761374c61326d8961313e565b9250613794565b836001141561376f5761376861326d8961313e565b9150613794565b836002141561378f576137846112848961313e565b905060019450613794565b61379f565b83600101935061372d565b846137e5576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b60006137fc826402540be40063ffffffff614d8016565b6001600160a01b0385166000908152600b602052604090208054600019019055905060ff8816600114156139425760ff87161561386f576040805162461bcd60e51b815260206004820152600c60248201526b77726f6e672073746174757360a01b604482015290519081900360640190fd5b6001600160a01b038416600090815260046020526040902054613898908263ffffffff612ea416565b6001600160a01b038086166000908152600460209081526040808320949094556005815283822092871682529190915220546138da908263ffffffff612ea416565b6001600160a01b038086166000818152600560209081526040808320948916808452948252918290209490945580518581529051929391927f9a57c81564ab02642f34fd87e41baa9b074c18342cec3b7268b62bf752018fd1929181900390910190a3613ad0565b60ff8816613a94576001600160a01b038416600090815260086020526040902054613973908263ffffffff612ea416565b6001600160a01b0385166000908152600860209081526040808320939093558251630e4f7c3f60e31b81526004810185905292516110049363727be1f89360248083019493928390030190829087803b1580156139cf57600080fd5b505af11580156139e3573d6000803e3d6000fd5b505050506040513d60208110156139f957600080fd5b5051613a42576040805162461bcd60e51b81526020600482015260136024820152721dda5d1a191c985dc8189b988819985a5b1959606a1b604482015290519081900360640190fd5b6040805182815260ff8916602082015281516001600160a01b0380871693908816927fcbd481ae600289fad8c0484d07ce0ffe4f010d7c844ecfdeaf2a13fead52886e929081900390910190a3613ad0565b6040805162461bcd60e51b815260206004820152600c60248201526b77726f6e672073746174757360a01b604482015290519081900360640190fd5b505050505050505050565b60008060008060005b613aed8861363f565b15613b565783613b0a57613b0361326d8961313e565b9250613b4b565b8360011415613b2657613b1f61326d8961313e565b9150613b4b565b8360021415613b4657613b3b6112848961313e565b905060019450613b4b565b613b56565b836001019350613ae4565b84613b9c576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b6000613bb3826402540be40063ffffffff614d8016565b6001600160a01b0385166000908152600c602052604090208054600019019055905060ff881660011415613d325760ff871615613c26576040805162461bcd60e51b815260206004820152600c60248201526b77726f6e672073746174757360a01b604482015290519081900360640190fd5b6001600160a01b038416600090815260046020526040902054613c4f908263ffffffff612f4716565b6001600160a01b03808616600090815260046020908152604080832094909455600581528382209287168252919091522054613c91908263ffffffff612f4716565b6001600160a01b03808616600090815260056020908152604080832093881683529290522055613cca42620a8c0063ffffffff612ea416565b6001600160a01b038086166000818152600760209081526040808320948916808452948252918290209490945580518581529051929391927fd6f878a5bcbbe79a64e6418bb0d56aaa20b9a60587d45749819df88dfc7c3c44929181900390910190a3613ad0565b60ff8816613a94576001600160a01b03808516600081815260076020908152604080832094881680845294825280832092909255815185815260ff8c169181019190915281517f4417d10c1e33efa83a770b8d4f47176e78c08c1298d534901ad3b16bb585fa2e929181900390910190a3613ad0565b6000806000806000805b613dbb8961363f565b15613e405784613dd857613dd161326d8a61313e565b9350613e35565b8460011415613df457613ded61326d8a61313e565b9250613e35565b8460021415613e1057613e0961326d8a61313e565b9150613e35565b8460031415613e3057613e256112848a61313e565b905060019550613e35565b613e40565b846001019450613db2565b85613e86576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b6000613e9d826402540be40063ffffffff614d8016565b6001600160a01b0386166000908152600d602052604090208054600019019055905060ff8916600114156140705760ff881615613f10576040805162461bcd60e51b815260206004820152600c60248201526b77726f6e672073746174757360a01b604482015290519081900360640190fd5b6001600160a01b03808616600090815260056020908152604080832093881683529290522054613f46908263ffffffff612f4716565b6001600160a01b03868116600090815260056020908152604080832089851684529091528082209390935590851681522054613f829082612ea4565b6001600160a01b03808716600090815260056020908152604080832093881683529290522055613fbb42620a8c0063ffffffff612ea416565b6001600160a01b0380871660009081526009602090815260408083208985168452825280832093881683529290522055613ffe42620a8c0063ffffffff612ea416565b6001600160a01b038087166000818152600960209081526040808320898616808552908352818420958b1680855295835292819020959095558451868152945191947f78bffae3f8c6691ac7fc1a3bff800cb2d612f5ad9ae5b0444cfe2eb15c189e18929081900390910190a4614101565b60ff8916613a94576001600160a01b038581166000818152600960209081526040808320898616808552818452828520968a16808652968452828520859055908352818420818552835281842093909355805186815260ff8e169281019290925280519293927fb93bee5c59f85ede6b074a99f4ffcd3e3fc0d5c3d8156de331de89a49e0ce77c9281900390910190a45b50505050505050505050565b6000816040516020018082805190602001908083835b602083106141425780518252601f199092019160209182019101614123565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106141b05780518252601f199092019160209182019101614191565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b60008060008060005b61420b8661363f565b1561427457836142285761422161326d8761313e565b9250614269565b83600114156142445761423d61326d8761313e565b9150614269565b8360021415614264576142596112848761313e565b905060019450614269565b614274565b836001019350614202565b846142ba576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b60006142d1826402540be40063ffffffff614d8016565b6001600160a01b0385166000908152600b602090815260408083208054600019019055600890915290205490915061430f908263ffffffff612ea416565b6001600160a01b0385166000908152600860209081526040808320939093558251630e4f7c3f60e31b81526004810185905292516110049363727be1f89360248083019493928390030190829087803b15801561436b57600080fd5b505af115801561437f573d6000803e3d6000fd5b505050506040513d602081101561439557600080fd5b50516143de576040805162461bcd60e51b81526020600482015260136024820152721dda5d1a191c985dc8189b988819985a5b1959606a1b604482015290519081900360640190fd5b6040516001907ff83de021914a4585482db5ca47d520a5657165b443fa2c7ef8ed4635f054da9b90600090a250505050505050565b60008060008060005b6144258661363f565b1561448e57836144425761443b61326d8761313e565b9250614483565b836001141561445e5761445761326d8761313e565b9150614483565b836002141561447e576144736112848761313e565b905060019450614483565b61448e565b83600101935061441c565b846144d4576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b6001600160a01b038084166000908152600c60209081526040808320805460001901905560078252808320938616835292905281812081905590516002917ff83de021914a4585482db5ca47d520a5657165b443fa2c7ef8ed4635f054da9b91a2505050505050565b6000806000806000805b6145508761363f565b156145d5578461456d5761456661326d8861313e565b93506145ca565b84600114156145895761458261326d8861313e565b92506145ca565b84600214156145a55761459e61326d8861313e565b91506145ca565b84600314156145c5576145ba6112848861313e565b9050600195506145ca565b6145d5565b846001019450614547565b8561461b576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b6001600160a01b038481166000908152600d602090815260408083208054600019019055600982528083208785168085528184528285209588168552948352818420849055825280832093835292905281812081905590516003917ff83de021914a4585482db5ca47d520a5657165b443fa2c7ef8ed4635f054da9b91a250505050505050565b6000818361472e5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156146f35781810151838201526020016146db565b50505050905090810190601f1680156147205780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161473a57fe5b0495945050505050565b600081848411156147965760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156146f35781810151838201526020016146db565b505050900390565b6060815160011480156147d05750607f60f81b826000815181106147be57fe5b01602001516001600160f81b03191611155b156147dc575080611196565b612bf66147ee8351608060ff16614957565b836148da565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166148385750601861485c565b6fffffffffffffffffffffffffffffffff1984166148585750601061485c565b5060005b60208110156148925781818151811061487157fe5b01602001516001600160f81b0319161561488a57614892565b60010161485c565b60008160200390506060816040519080825280601f01601f1916602001820160405280156148c7576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b8183101561490b5780518352602092830192016148f3565b50855184518101855292509050808201602086015b81831015614938578051835260209283019201614920565b508651929092011591909101601f01601f191660405250905092915050565b60606801000000000000000083106149a7576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411614a015782840160f81b816000815181106149e357fe5b60200101906001600160f81b031916908160001a9053509050612bf6565b6060614a0c856147f4565b90508381510160370160f81b82600081518110614a2557fe5b60200101906001600160f81b031916908160001a905350614a4682826148da565b95945050505050565b8051600090614a6057506000611196565b6020820151805160001a9060c0821015614a7f57600092505050611196565b5060019392505050565b8051600090811a6080811015614aa3576000915050611196565b60b8811080614abe575060c08110801590614abe575060f881105b15614acd576001915050611196565b60c0811015614ae15760b519019050611196565b60f519019050611196565b80516000908190811a6080811015614b075760019150614c18565b60b8811015614b1c57607e1981019150614c18565b60c0811015614b9657600060b78203600186019550806020036101000a865104915060018101820193505080831015614b90576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b50614c18565b60f8811015614bab5760be1981019150614c18565b600060f78203600186019550806020036101000a865104915060018101820193505080831015614c16576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b8051600090601514614c3057600080fd5b612bf68261318c565b60006060614c52846402540be40063ffffffff612f0516565b60408051600480825260a0820190925291955060609190816020015b6060815260200190600190039081614c6e579050509050614c918760ff16612fac565b81600081518110614c9e57fe5b6020026020010181905250614cbb866001600160a01b0316612f89565b81600181518110614cc857fe5b6020026020010181905250614cdc85612fac565b81600281518110614ce957fe5b6020026020010181905250614d038463ffffffff16612fac565b81600381518110614d1057fe5b60200260200101819052506060614d2682612fbf565b94989497509395505050505050565b80614d3f57612e20565b5b60208110614d5f578251825260209283019290910190601f1901614d40565b915181516020939093036101000a6000190180199091169216919091179052565b600082614d8f57506000612bf6565b82820282848281614d9c57fe5b0414612efe5760405162461bcd60e51b8152600401808060200182810382526021815260200180614ec06021913960400191505060405180910390fd5b60405180606001604052806003906020820280368337509192915050565b6040518060400160405280614e0a614e17565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe7468652042534352656c61796572466565206d6f642074656e20646563696d616c73206d757374206265207a65726f7468652042534352656c61796572466565206d757374206265206c657373207468616e2072656c61796572466565746865206d696e44656c65676174696f6e206d7573742062652067726561746572207468616e2072656c61796572466565536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f777468652072656c61796572466565206d6f642074656e20646563696d616c73206d757374206265207a65726f746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163747468652072656c61796572466565206d757374206265206c657373207468616e206d696e44656c65676174696f6e7468652072656c61796572466565206d757374206265206d6f7265207468616e2042534352656c61796572466565746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374a2646970667358221220066cc7c05d87e3cd20ecf3649deba7ac4ce8b389992969b6006793cbf330c73564736f6c63430006040033", + }, + }, + } + + gibbsUpgrade[rialtoNet] = &Upgrade{ + UpgradeName: "gibbs", + Configs: []*UpgradeConfig{ + { + ContractAddr: common.HexToAddress(TokenHubContract), + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/9d45b31c12b2c04757284717f4351cb44e81a3a7", + Code: "60806040526004361061036f5760003560e01c80639a854bbd116101c6578063bd466461116100f7578063f014847211610095578063fc1a598f1161006f578063fc1a598f14610d58578063fc3e590814610a3b578063fd6a687914610d8b578063ff9c0027146106ec576103b7565b8063f014847214610d19578063f9a2bbc714610d2e578063fa9e915914610d43576103b7565b8063d9e6dae9116100d1578063d9e6dae91461066e578063dc927faf14610cda578063e1c7392a14610cef578063ebf71d5314610d04576103b7565b8063bd46646114610c0d578063c81b166214610c40578063c8509d8114610c55576103b7565b8063aa7415f511610164578063b99328c51161013e578063b99328c514610b77578063b9fd21e314610bb0578063ba35ead614610bc5578063bbface1f14610bda576103b7565b8063aa7415f514610a50578063ab51bb9614610a97578063ac43175114610aac576103b7565b8063a1a11bf5116101a0578063a1a11bf5146109fc578063a496fba214610a11578063a78abc1614610a26578063a7c9f02d14610a3b576103b7565b80639a854bbd146109995780639a99b4f0146109ae5780639dc09262146109e7576103b7565b806361368475116102a0578063727be1f81161023e578063831d65d111610218578063831d65d1146108c05780638b87b21f146105ed5780638eff336c1461094557806396713da914610984576103b7565b8063727be1f81461086c57806375d47a0a146108965780637942fd05146108ab576103b7565b80636e47b4821161027a5780636e47b4821461082d57806370fd5bad146106ec578063718a8aa81461084257806371d3086314610857576103b7565b8063613684751461066e57806366dea52a146106ec5780636e05652014610701576103b7565b806343a368b91161030d57806350432d32116102e757806350432d321461068357806351e806721461069857806359b92789146106ad5780635d499b1b146106d7576103b7565b806343a368b91461062d578063493279b1146106425780634bf6c8821461066e576103b7565b8063149d14d911610349578063149d14d9146105155780633d7132231461053c5780633dffc387146105ed57806343756e5c14610618576103b7565b80630bee7a67146103bc5780630e2374a5146103ea5780631182b8751461041b576103b7565b366103b75734156103b5576040805133815234602082015281517f6c98249d85d88c3753a04a22230f595e4dc8d3dc86c34af35deeeedc861b89db929181900390910190a15b005b600080fd5b3480156103c857600080fd5b506103d1610da0565b6040805163ffffffff9092168252519081900360200190f35b3480156103f657600080fd5b506103ff610da5565b604080516001600160a01b039092168252519081900360200190f35b34801561042757600080fd5b506104a06004803603604081101561043e57600080fd5b60ff8235169190810190604081016020820135600160201b81111561046257600080fd5b82018360208201111561047457600080fd5b803590602001918460018302840111600160201b8311171561049557600080fd5b509092509050610dab565b6040805160208082528351818301528351919283929083019185019080838360005b838110156104da5781810151838201526020016104c2565b50505050905090810190601f1680156105075780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561052157600080fd5b5061052a610ed9565b60408051918252519081900360200190f35b34801561054857600080fd5b506103ff6004803603602081101561055f57600080fd5b810190602081018135600160201b81111561057957600080fd5b82018360208201111561058b57600080fd5b803590602001918460018302840111600160201b831117156105ac57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610edf945050505050565b3480156105f957600080fd5b50610602610f03565b6040805160ff9092168252519081900360200190f35b34801561062457600080fd5b506103ff610f08565b34801561063957600080fd5b5061052a610f0e565b34801561064e57600080fd5b50610657610f1a565b6040805161ffff9092168252519081900360200190f35b34801561067a57600080fd5b50610602610f20565b34801561068f57600080fd5b5061052a610f25565b3480156106a457600080fd5b506103ff610f30565b3480156106b957600080fd5b506103ff600480360360208110156106d057600080fd5b5035610f36565b3480156106e357600080fd5b5061052a610f51565b3480156106f857600080fd5b50610602610f5a565b6108196004803603608081101561071757600080fd5b810190602081018135600160201b81111561073157600080fd5b82018360208201111561074357600080fd5b803590602001918460208302840111600160201b8311171561076457600080fd5b919390929091602081019035600160201b81111561078157600080fd5b82018360208201111561079357600080fd5b803590602001918460208302840111600160201b831117156107b457600080fd5b919390929091602081019035600160201b8111156107d157600080fd5b8201836020820111156107e357600080fd5b803590602001918460208302840111600160201b8311171561080457600080fd5b91935091503567ffffffffffffffff16610f5f565b604080519115158252519081900360200190f35b34801561083957600080fd5b506103ff611434565b34801561084e57600080fd5b5061060261143a565b34801561086357600080fd5b5061052a61143f565b34801561087857600080fd5b506108196004803603602081101561088f57600080fd5b5035611445565b3480156108a257600080fd5b506103ff6114bf565b3480156108b757600080fd5b506106026114c5565b3480156108cc57600080fd5b506103b5600480360360408110156108e357600080fd5b60ff8235169190810190604081016020820135600160201b81111561090757600080fd5b82018360208201111561091957600080fd5b803590602001918460018302840111600160201b8311171561093a57600080fd5b5090925090506114ca565b34801561095157600080fd5b506103b56004803603606081101561096857600080fd5b508035906001600160a01b036020820135169060400135611613565b34801561099057600080fd5b50610602611699565b3480156109a557600080fd5b5061052a61169e565b3480156109ba57600080fd5b5061052a600480360360408110156109d157600080fd5b506001600160a01b0381351690602001356116aa565b3480156109f357600080fd5b506103ff6117e8565b348015610a0857600080fd5b506103ff6117ee565b348015610a1d57600080fd5b506106026117f4565b348015610a3257600080fd5b506108196117f9565b348015610a4757600080fd5b50610602611802565b61081960048036036080811015610a6657600080fd5b5080356001600160a01b03908116916020810135909116906040810135906060013567ffffffffffffffff16611807565b348015610aa357600080fd5b506103d16117f4565b348015610ab857600080fd5b506103b560048036036040811015610acf57600080fd5b810190602081018135600160201b811115610ae957600080fd5b820183602082011115610afb57600080fd5b803590602001918460018302840111600160201b83111715610b1c57600080fd5b919390929091602081019035600160201b811115610b3957600080fd5b820183602082011115610b4b57600080fd5b803590602001918460018302840111600160201b83111715610b6c57600080fd5b509092509050611ec8565b348015610b8357600080fd5b506103b560048036036040811015610b9a57600080fd5b50803590602001356001600160a01b0316612137565b348015610bbc57600080fd5b5061052a6121ad565b348015610bd157600080fd5b5061052a6121b7565b348015610be657600080fd5b5061052a60048036036020811015610bfd57600080fd5b50356001600160a01b03166121bd565b348015610c1957600080fd5b5061052a60048036036020811015610c3057600080fd5b50356001600160a01b03166121cf565b348015610c4c57600080fd5b506103ff6121ea565b348015610c6157600080fd5b506103b560048036036040811015610c7857600080fd5b60ff8235169190810190604081016020820135600160201b811115610c9c57600080fd5b820183602082011115610cae57600080fd5b803590602001918460018302840111600160201b83111715610ccf57600080fd5b5090925090506121f0565b348015610ce657600080fd5b506103ff6122c0565b348015610cfb57600080fd5b506103b56122c6565b348015610d1057600080fd5b50610602612366565b348015610d2557600080fd5b5061060261236b565b348015610d3a57600080fd5b506103ff612370565b348015610d4f57600080fd5b5061052a612376565b348015610d6457600080fd5b506104a060048036036020811015610d7b57600080fd5b50356001600160a01b031661237c565b348015610d9757600080fd5b506103ff6124a3565b606481565b61200181565b60005460609060ff16610df3576040805162461bcd60e51b81526020600482015260196024820152600080516020614906833981519152604482015290519081900360640190fd5b3361200014610e335760405162461bcd60e51b815260040180806020018281038252602f8152602001806148b4602f913960400191505060405180910390fd5b60ff841660021415610e8557610e7e83838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506124a992505050565b9050610ed2565b6040805162461bcd60e51b815260206004820152601860248201527f756e7265636f676e697a65642073796e207061636b6167650000000000000000604482015290519081900360640190fd5b9392505050565b60015490565b6020818101516000908152600490915260409020546001600160a01b03165b919050565b600181565b61100181565b670de0b6b3a764000081565b6102ca81565b600881565b66071afd498d000081565b61200081565b6000908152600460205260409020546001600160a01b031690565b6402540be40081565b600281565b6000805460ff16610fa5576040805162461bcd60e51b81526020600482015260196024820152600080516020614906833981519152604482015290519081900360640190fd5b868514610fe35760405162461bcd60e51b815260040180806020018281038252603b815260200180614879603b913960400191505060405180910390fd5b8683146110215760405162461bcd60e51b815260040180806020018281038252603f81526020018061474c603f913960400191505060405180910390fd5b426078018267ffffffffffffffff16101561106d5760405162461bcd60e51b815260040180806020018281038252602481526020018061463c6024913960400191505060405180910390fd5b6402540be4003406156110b15760405162461bcd60e51b815260040180806020018281038252604081526020018061497c6040913960400191505060405180910390fd5b604080518681526020808802820101909152859060009081906060908480156110e4578160200160208202803683370190505b50905060005b848110156111bf576402540be4008b8b8381811061110457fe5b905060200201358161111257fe5b061561114f5760405162461bcd60e51b815260040180806020018281038252603c81526020018061478b603c913960400191505060405180910390fd5b6111748b8b8381811061115e57fe5b90506020020135856125cd90919063ffffffff16565b93506111a06402540be4008c8c8481811061118b57fe5b9050602002013561262790919063ffffffff16565b8282815181106111ac57fe5b60209081029190910101526001016110ea565b506001546111e4906111d7908663ffffffff61266916565b849063ffffffff6125cd16565b3410156112225760405162461bcd60e51b81526004018080602001828103825260568152602001806149266056913960600191505060405180910390fd5b611232348463ffffffff6126c216565b915061123c614462565b6040518060c001604052806221272160e91b60001b815260200160006001600160a01b031681526020018381526020018e8e808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050908252506040805160208c810282810182019093528c82529283019290918d918d91829185019084908082843760009201919091525050509082525067ffffffffffffffff8916602090910152905061200063f7a251d7600361130084612704565b611315876402540be40063ffffffff61262716565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561137357818101518382015260200161135b565b50505050905090810190601f1680156113a05780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156113c157600080fd5b505af11580156113d5573d6000803e3d6000fd5b505060408051600081523360208201528082018890526060810187905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9350908190036080019150a15060019c9b505050505050505050505050565b61100581565b601081565b60015481565b600033612001146114875760405162461bcd60e51b815260040180806020018281038252603381526020018061457c6033913960400191505060405180910390fd5b6040516120019083156108fc029084906000818181858888f193505050501580156114b6573d6000803e3d6000fd5b50600192915050565b61100881565b600b81565b60005460ff1661150f576040805162461bcd60e51b81526020600482015260196024820152600080516020614906833981519152604482015290519081900360640190fd5b336120001461154f5760405162461bcd60e51b815260040180806020018281038252602f8152602001806148b4602f913960400191505060405180910390fd5b60ff83166003141561159f5761159a82828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506129bf92505050565b61160e565b7f41ce201247b6ceb957dcdb217d0b8acb50b9ea0e12af9af4f5e7f38902101605838383604051808460ff1660ff168152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f1916909201829003965090945050505050a15b505050565b33611008146116535760405162461bcd60e51b81526004018080602001828103825260238152602001806148e36023913960400191505060405180910390fd5b600083815260046020908152604080832080546001600160a01b039096166001600160a01b03199096168617905593825260038152838220949094556002909352912055565b600981565b677ce66c50e284000081565b6000805460ff166116f0576040805162461bcd60e51b81526020600482015260196024820152600080516020614906833981519152604482015290519081900360640190fd5b33611005146117305760405162461bcd60e51b815260040180806020018281038252602f8152602001806145af602f913960400191505060405180910390fd5b600047831061173f5747611741565b825b9050670de0b6b3a764000081111561175d5760009150506117e2565b80156117df576040516001600160a01b0385169082156108fc029083906000818181858888f19350505050158015611799573d6000803e3d6000fd5b50604080516001600160a01b03861681526020810183905281517ff8b71c64315fc33b2ead2adfa487955065152a8ac33d9d5193aafd7f45dc15a0929181900390910190a15b90505b92915050565b61100781565b61100681565b600081565b60005460ff1681565b600381565b6000805460ff1661184d576040805162461bcd60e51b81526020600482015260196024820152600080516020614906833981519152604482015290519081900360640190fd5b426078018267ffffffffffffffff1610156118995760405162461bcd60e51b815260040180806020018281038252602481526020018061463c6024913960400191505060405180910390fd5b6402540be4003406156118dd5760405162461bcd60e51b815260040180806020018281038252604081526020018061497c6040913960400191505060405180910390fd5b600080806001600160a01b0388166119bc5760015461190390879063ffffffff6125cd16565b3410156119415760405162461bcd60e51b81526004018080602001828103825260618152602001806146c66061913960800191505060405180910390fd5b6402540be4008606156119855760405162461bcd60e51b815260040180806020018281038252603c81526020018061478b603c913960400191505060405180910390fd5b611995348763ffffffff6126c216565b90506119ac866402540be40063ffffffff61262716565b6221272160e91b93509150611c5f565b6001600160a01b038816600090815260036020526040902054925082611a135760405162461bcd60e51b81526004018080602001828103825260318152602001806146956031913960400191505060405180910390fd5b600154341015611a545760405162461bcd60e51b815260040180806020018281038252603f8152602001806147e8603f913960400191505060405180910390fd5b506001600160a01b0387166000908152600260205260409020543490600881111580611a9f5750600881118015611a9f5750611a9d876007198301600a0a63ffffffff612a1b16565b155b611ada5760405162461bcd60e51b815260040180806020018281038252603c81526020018061478b603c913960400191505060405180910390fd5b611ae48782612a5d565b9250611aef84612a9d565b15611b37576305f5e100831015611b375760405162461bcd60e51b815260040180806020018281038252603a8152602001806145de603a913960400191505060405180910390fd5b600881101580611b515750600881108015611b5157508683115b611b8c5760405162461bcd60e51b81526004018080602001828103825260258152602001806147276025913960400191505060405180910390fd5b677ce66c50e2840000831115611bd35760405162461bcd60e51b81526004018080602001828103825260358152602001806146606035913960400191505060405180910390fd5b604080516323b872dd60e01b81523360048201523060248201526044810189905290516001600160a01b038b16916323b872dd9160648083019260209291908290030181600087803b158015611c2857600080fd5b505af1158015611c3c573d6000803e3d6000fd5b505050506040513d6020811015611c5257600080fd5b5051611c5d57600080fd5b505b611c67614462565b6040805160c0810182528581526001600160a01b038b166020820152815160018082528184018452919283019181602001602082028036833750505081526040805160018082528183019092526020928301929091908083019080368337505050815260408051600180825281830190925260209283019290919080830190803683370190505081526020018767ffffffffffffffff168152509050828160400151600081518110611d1557fe5b602002602001018181525050878160600151600081518110611d3357fe5b60200260200101906001600160a01b031690816001600160a01b031681525050338160800151600081518110611d6557fe5b6001600160a01b039092166020928302919091019091015261200063f7a251d76003611d9084612704565b611da5866402540be40063ffffffff61262716565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611e03578181015183820152602001611deb565b50505050905090810190601f168015611e305780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015611e5157600080fd5b505af1158015611e65573d6000803e3d6000fd5b5050604080516001600160a01b038d1681523360208201528082018b90526060810186905290517f74eab09b0e53aefc23f2e1b16da593f95c2dd49c6f5a23720463d10d9c330b2a9350908190036080019150a150600198975050505050505050565b3361100714611f085760405162461bcd60e51b815260040180806020018281038252602e815260200180614827602e913960400191505060405180910390fd5b60208114611f5d576040805162461bcd60e51b815260206004820152601b60248201527f65787065637465642076616c7565206c656e6774682069732033320000000000604482015290519081900360640190fd5b606084848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8801819004810282018101909252868152939450606093925086915085908190840183828082843760009201919091525050505060208301519091506772656c617946656560c01b811415612065576020820151670de0b6b3a7640000811180159061200c57506402540be4008106155b61205d576040805162461bcd60e51b815260206004820152601960248201527f7468652072656c6179466565206f7574206f662072616e676500000000000000604482015290519081900360640190fd5b6001556120a2565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a878787876040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050505050565b33611008146121775760405162461bcd60e51b81526004018080602001828103825260238152602001806148e36023913960400191505060405180910390fd5b600091825260046020908152604080842080546001600160a01b03191690556001600160a01b0392909216835260039052812055565b6221272160e91b81565b61c35081565b60026020526000908152604090205481565b6001600160a01b031660009081526003602052604090205490565b61100281565b60005460ff16612235576040805162461bcd60e51b81526020600482015260196024820152600080516020614906833981519152604482015290519081900360640190fd5b33612000146122755760405162461bcd60e51b815260040180806020018281038252602f8152602001806148b4602f913960400191505060405180910390fd5b60ff83166003141561159f5761159a82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612ba392505050565b61100381565b60005460ff161561231e576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e747261637420616c726561647920696e697400000000000000604482015290519081900360640190fd5b66071afd498d000060019081556000808052600260205260127fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b55805460ff19169091179055565b600481565b600581565b61100081565b61271081565b6001600160a01b03811660009081526003602090815260409182902054825182815280840190935260609290918391906020820181803683375050506020810183905290506000805b60208160ff16101561240c57828160ff16815181106123e057fe5b01602001516001600160f81b031916156123ff57600190910190612404565b61240c565b6001016123c5565b5060608160ff166040519080825280601f01601f19166020018201604052801561243d576020820181803683370190505b50905060005b8260ff168160ff16101561249957838160ff168151811061246057fe5b602001015160f81c60f81b828260ff168151811061247a57fe5b60200101906001600160f81b031916908160001a905350600101612443565b5095945050505050565b61100481565b60606124b36144ae565b60006124be84612ca1565b9150915080612514576040805162461bcd60e51b815260206004820152601f60248201527f756e7265636f676e697a6564207472616e73666572496e207061636b61676500604482015290519081900360640190fd5b600061251f83612de0565b905063ffffffff8116156125b3576040808401516020808601516001600160a01b0316600090815260029091529182205461255a9190612a5d565b90506125646144e3565b60405180608001604052808660000151815260200183815260200186608001516001600160a01b031681526020018463ffffffff1681525090506125a78161312d565b95505050505050610efe565b50506040805160008152602081019091529150610efe9050565b6000828201838110156117df576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60006117df83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613209565b600082612678575060006117e2565b8282028284828161268557fe5b04146117df5760405162461bcd60e51b81526004018080602001828103825260218152602001806147c76021913960400191505060405180910390fd5b60006117df83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506132ab565b60408051600680825260e08201909252606091829190816020015b606081526020019060019003908161271f575050835190915061274190613305565b8160008151811061274e57fe5b602002602001018190525061276f83602001516001600160a01b0316613318565b8160018151811061277c57fe5b6020026020010181905250600083604001515190506060816040519080825280602002602001820160405280156127c757816020015b60608152602001906001900390816127b25790505b50905060005b82811015612814576127f5866040015182815181106127e857fe5b6020026020010151613305565b82828151811061280157fe5b60209081029190910101526001016127cd565b5061281e8161333b565b8360028151811061282b57fe5b602002602001018190525060608260405190808252806020026020018201604052801561286c57816020015b60608152602001906001900390816128575790505b50905060005b838110156128c2576128a38760600151828151811061288d57fe5b60200260200101516001600160a01b0316613318565b8282815181106128af57fe5b6020908102919091010152600101612872565b506128cc8161333b565b846003815181106128d957fe5b602002602001018190525060608360405190808252806020026020018201604052801561291a57816020015b60608152602001906001900390816129055790505b50905060005b8481101561295a5761293b8860800151828151811061288d57fe5b82828151811061294757fe5b6020908102919091010152600101612920565b506129648161333b565b8560048151811061297157fe5b60200260200101819052506129938760a0015167ffffffffffffffff16613305565b856005815181106129a057fe5b60200260200101819052506129b48561333b565b979650505050505050565b6129c761450a565b60006129d2836133c5565b9150915080612a125760405162461bcd60e51b81526004018080602001828103825260248152602001806148556024913960400191505060405180910390fd5b61160e82613590565b60006117df83836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815250613a14565b60006008821115612a8657612a7f836007198401600a0a63ffffffff61262716565b90506117e2565b6117df836008849003600a0a63ffffffff61266916565b604080516020808252818301909252600091606091906020820181803683375050506020810184905290506000805b60208160ff161015612b1357828160ff1681518110612ae757fe5b01602001516001600160f81b03191615612b0657600190910190612b0b565b612b13565b600101612acc565b50600760ff82161015612b2b57600092505050610efe565b816005820360ff1681518110612b3d57fe5b6020910101516001600160f81b031916602d60f81b14612b6257600092505050610efe565b816001820360ff1681518110612b7457fe5b6020910101516001600160f81b031916604d60f81b14612b9957600092505050610efe565b5060019392505050565b612bab614462565b6000612bb683613a76565b9150915080612bf65760405162461bcd60e51b81526004018080602001828103825260248152602001806146186024913960400191505060405180910390fd5b612bfe61450a565b602080840180516001600160a01b0390811684526040808701518585015291511660009081526002909252812054905b846040015151811015612c7f57612c5c85604001518281518110612c4e57fe5b602002602001015183613cda565b85604001518281518110612c6c57fe5b6020908102919091010152600101612c2e565b506080840151604083015260056060830152612c9a82613590565b5050505050565b612ca96144ae565b6000612cb36144ae565b612cbb614541565b612ccc612cc786613d13565b613d38565b90506000805b612cdb83613d82565b15612dd35780612cfd57612cf6612cf184613da3565b613df1565b8452612dcb565b8060011415612d2a57612d17612d1284613da3565b613ea8565b6001600160a01b03166020850152612dcb565b8060021415612d4957612d3f612cf184613da3565b6040850152612dcb565b8060031415612d7157612d5e612d1284613da3565b6001600160a01b03166060850152612dcb565b8060041415612d9957612d86612d1284613da3565b6001600160a01b03166080850152612dcb565b8060051415612dc657612dae612cf184613da3565b67ffffffffffffffff1660a085015260019150612dcb565b612dd3565b600101612cd2565b5091935090915050915091565b60208101516000906001600160a01b0316612f17578160a0015167ffffffffffffffff16421115612e1357506001610efe565b8160400151471015612e2757506003610efe565b606082015160408084015190516000926001600160a01b0316916127109184818181858888f193505050503d8060008114612e7e576040519150601f19603f3d011682016040523d82523d6000602084013e612e83565b606091505b5050905080612e96575060049050610efe565b7f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5983602001518460600151856040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a15060009050610efe565b8160a0015167ffffffffffffffff16421115612f3557506001610efe565b81516020808401516001600160a01b031660009081526003909152604090205414612f6257506002610efe565b602080830151604080516370a0823160e01b815230600482015290516000936001600160a01b03909316926370a082319261c3509260248083019392829003018187803b158015612fb257600080fd5b5086fa158015612fc6573d6000803e3d6000fd5b50505050506040513d6020811015612fdd57600080fd5b50516040840151909150811015612ff8575060039050610efe565b600083602001516001600160a01b031663a9059cbb61c350866060015187604001516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b15801561306957600080fd5b5087f115801561307d573d6000803e3d6000fd5b50505050506040513d602081101561309457600080fd5b505190508015613121577f471eb9cc1ffe55ffadf15b32595415eb9d80f22e761d24bd6dffc607e1284d5984602001518560600151866040015160405180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060405180910390a15060009150610efe9050565b5060059150610efe9050565b60408051600480825260a08201909252606091829190816020015b6060815260200190600190039081613148575050835190915061316a90613305565b8160008151811061317757fe5b602002602001018190525061318f8360200151613305565b8160018151811061319c57fe5b60200260200101819052506131bd83604001516001600160a01b0316613318565b816002815181106131ca57fe5b60200260200101819052506131e8836060015163ffffffff16613305565b816003815181106131f557fe5b6020026020010181905250610ed28161333b565b600081836132955760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561325a578181015183820152602001613242565b50505050905090810190601f1680156132875780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816132a157fe5b0495945050505050565b600081848411156132fd5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561325a578181015183820152602001613242565b505050900390565b60606117e261331383613ec2565b613fa8565b60408051600560a21b8318601482015260348101909152606090610ed281613fa8565b606081516000141561335c5750604080516000815260208101909152610efe565b60608260008151811061336b57fe5b602002602001015190506000600190505b83518110156133ac576133a28285838151811061339557fe5b6020026020010151613ffa565b915060010161337c565b50610ed26133bf825160c060ff16614077565b82613ffa565b6133cd61450a565b60006133d761450a565b6133df614541565b6133eb612cc786613d13565b90506000805b6133fa83613d82565b15612dd3578061342057613410612d1284613da3565b6001600160a01b03168452613588565b80600114156134c157606061343c61343785613da3565b61416f565b90508051604051908082528060200260200182016040528015613469578160200160208202803683370190505b50602086015260005b81518110156134ba5761349782828151811061348a57fe5b6020026020010151613df1565b866020015182815181106134a757fe5b6020908102919091010152600101613472565b5050613588565b80600214156135635760606134d861343785613da3565b90508051604051908082528060200260200182016040528015613505578160200160208202803683370190505b50604086015260005b81518110156134ba5761353382828151811061352657fe5b6020026020010151613ea8565b8660400151828151811061354357fe5b6001600160a01b039092166020928302919091019091015260010161350e565b8060031415612dc657613578612cf184613da3565b63ffffffff166060850152600191505b6001016133f1565b80516001600160a01b03166137ba5760005b8160200151518110156137b4576000826040015182815181106135c157fe5b60200260200101516001600160a01b0316612710846020015184815181106135e557fe5b60209081029190910101516040516000818181858888f193505050503d806000811461362d576040519150601f19603f3d011682016040523d82523d6000602084013e613632565b606091505b50509050806136f5577f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e83600001518460400151848151811061367157fe5b60200260200101518560200151858151811061368957fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a16137ab565b7fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a83600001518460400151848151811061372b57fe5b60200260200101518560200151858151811061374357fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b506001016135a2565b50613a11565b60005b816020015151811015613a0f57600082600001516001600160a01b031663a9059cbb61c350856040015185815181106137f257fe5b60200260200101518660200151868151811061380a57fe5b60200260200101516040518463ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600088803b15801561386157600080fd5b5087f1158015613875573d6000803e3d6000fd5b50505050506040513d602081101561388c57600080fd5b505190508015613950577fd468d4fa5e8fb4adc119b29a983fd0785e04af5cb8b7a3a69a47270c54b6901a8360000151846040015184815181106138cc57fe5b6020026020010151856020015185815181106138e457fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a1613a06565b7f203f9f67a785f4f81be4d48b109aa0c498d1bc8097ecc2627063f480cc5fe73e83600001518460400151848151811061398657fe5b60200260200101518560200151858151811061399e57fe5b6020026020010151866060015160405180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b031681526020018381526020018263ffffffff1663ffffffff16815260200194505050505060405180910390a15b506001016137bd565b505b50565b60008183613a635760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561325a578181015183820152602001613242565b50828481613a6d57fe5b06949350505050565b613a7e614462565b6000613a88614462565b613a90614541565b613a9c612cc786613d13565b90506000805b613aab83613d82565b15612dd35780613ac857613ac1612cf184613da3565b8452613cd2565b8060011415613af057613add612d1284613da3565b6001600160a01b03166020850152613cd2565b8060021415613b7f576060613b0761343785613da3565b90508051604051908082528060200260200182016040528015613b34578160200160208202803683370190505b50604086015260005b8151811015613b7857613b5582828151811061348a57fe5b86604001518281518110613b6557fe5b6020908102919091010152600101613b3d565b5050613cd2565b8060031415613c14576060613b9661343785613da3565b90508051604051908082528060200260200182016040528015613bc3578160200160208202803683370190505b50606086015260005b8151811015613b7857613be482828151811061352657fe5b86606001518281518110613bf457fe5b6001600160a01b0390921660209283029190910190910152600101613bcc565b8060041415613ca9576060613c2b61343785613da3565b90508051604051908082528060200260200182016040528015613c58578160200160208202803683370190505b50608086015260005b8151811015613b7857613c7982828151811061352657fe5b86608001518281518110613c8957fe5b6001600160a01b0390921660209283029190910190910152600101613c61565b8060051415612dc657613cbe612cf184613da3565b67ffffffffffffffff1660a0850152600191505b600101613aa2565b60006008821115613cfc57612a7f836007198401600a0a63ffffffff61266916565b6117df836008849003600a0a63ffffffff61262716565b613d1b614561565b506040805180820190915281518152602082810190820152919050565b613d40614541565b613d4982614240565b613d5257600080fd5b6000613d618360200151614270565b60208085015160408051808201909152868152920190820152915050919050565b6000613d8c614561565b505080518051602091820151919092015191011190565b613dab614561565b613db482613d82565b613dbd57600080fd5b60208201516000613dcd826142d3565b80830160209586015260408051808201909152908152938401919091525090919050565b805160009015801590613e0657508151602110155b613e0f57600080fd5b6000613e1e8360200151614270565b90508083600001511015613e79576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b825160208085015183018051928490039291831015613e9f57826020036101000a820491505b50949350505050565b8051600090601514613eb957600080fd5b6117e282613df1565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff198416613f0657506018613f2a565b6fffffffffffffffffffffffffffffffff198416613f2657506010613f2a565b5060005b6020811015613f6057818181518110613f3f57fe5b01602001516001600160f81b03191615613f5857613f60565b600101613f2a565b60008160200390506060816040519080825280601f01601f191660200182016040528015613f95576020820181803683370190505b5080830196909652508452509192915050565b606081516001148015613fda5750607f60f81b82600081518110613fc857fe5b01602001516001600160f81b03191611155b15613fe6575080610efe565b6117e2613ff88351608060ff16614077565b835b6060806040519050835180825260208201818101602087015b8183101561402b578051835260209283019201614013565b50855184518101855292509050808201602086015b81831015614058578051835260209283019201614040565b508651929092011591909101601f01601f191660405250905092915050565b60606801000000000000000083106140c7576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b604080516001808252818301909252606091602082018180368337019050509050603784116141215782840160f81b8160008151811061410357fe5b60200101906001600160f81b031916908160001a90535090506117e2565b606061412c85613ec2565b90508381510160370160f81b8260008151811061414557fe5b60200101906001600160f81b031916908160001a9053506141668282613ffa565b95945050505050565b606061417a82614240565b61418357600080fd5b600061418e83614406565b90506060816040519080825280602002602001820160405280156141cc57816020015b6141b9614561565b8152602001906001900390816141b15790505b50905060006141de8560200151614270565b60208601510190506000805b84811015614235576141fb836142d3565b915060405180604001604052808381526020018481525084828151811061421e57fe5b6020908102919091010152918101916001016141ea565b509195945050505050565b805160009061425157506000610efe565b6020820151805160001a9060c0821015612b9957600092505050610efe565b8051600090811a608081101561428a576000915050610efe565b60b88110806142a5575060c081108015906142a5575060f881105b156142b4576001915050610efe565b60c08110156142c85760b519019050610efe565b60f519019050610efe565b80516000908190811a60808110156142ee57600191506143ff565b60b881101561430357607e19810191506143ff565b60c081101561437d57600060b78203600186019550806020036101000a865104915060018101820193505080831015614377576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b506143ff565b60f88110156143925760be19810191506143ff565b600060f78203600186019550806020036101000a8651049150600181018201935050808310156143fd576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b805160009061441757506000610efe565b6000809050600061442b8460200151614270565b602085015185519181019250015b808210156144595761444a826142d3565b60019093019290910190614439565b50909392505050565b6040518060c001604052806000801916815260200160006001600160a01b03168152602001606081526020016060815260200160608152602001600067ffffffffffffffff1681525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b60408051608081018252600080825260208201819052918101829052606081019190915290565b604051806080016040528060006001600160a01b031681526020016060815260200160608152602001600063ffffffff1681525090565b6040518060400160405280614554614561565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe6f6e6c79207374616b696e672073797374656d20636f6e74726163742063616e2063616c6c20746869732066756e6374696f6e746865206d6573736167652073656e646572206d75737420626520696e63656e746976697a6520636f6e7472616374466f72206d696e69546f6b656e2c20746865207472616e7366657220616d6f756e74206d757374206e6f74206265206c657373207468616e2031756e7265636f676e697a6564207472616e736665724f75742073796e207061636b61676565787069726554696d65206d7573742062652074776f206d696e75746573206c61746572616d6f756e7420697320746f6f206c617267652c20657863656564206d6178696d756d206265703220746f6b656e20616d6f756e7474686520636f6e747261637420686173206e6f74206265656e20626f756e6420746f20616e79206265703220746f6b656e726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e736665724f757420424e4220616d6f756e7420616e64206d696e696d756d2072656c6179466565616d6f756e7420697320746f6f206c617267652c2075696e74323536206f766572666c6f774c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620726566756e644164647273696e76616c6964207472616e7366657220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e20746865206d696e696d756d2072656c6179466565746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e7472616374756e7265636f676e697a6564207472616e736665724f75742061636b207061636b6167654c656e677468206f6620726563697069656e74416464727320646f65736e277420657175616c20746f206c656e677468206f6620616d6f756e7473746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374746865206d73672073656e646572206d75737420626520746f6b656e4d616e6167657274686520636f6e7472616374206e6f7420696e69742079657400000000000000726563656976656420424e4220616d6f756e742073686f756c64206265206e6f206c657373207468616e207468652073756d206f66207472616e7366657220424e4220616d6f756e7420616e642072656c6179466565696e76616c696420726563656976656420424e4220616d6f756e743a20707265636973696f6e206c6f737320696e20616d6f756e7420636f6e76657273696f6ea26469706673582212208f0455128650f210f452673f65fe656f790624ecf0bc6bbea21225e02413b67564736f6c63430006040033", + }, + { + ContractAddr: common.HexToAddress(StakingContract), + CommitUrl: "https://github.com/bnb-chain/bsc-genesis-contract/commit/9d45b31c12b2c04757284717f4351cb44e81a3a7", + Code: "60806040526004361061036f5760003560e01c806370fd5bad116101c6578063b88a802f116100f7578063d7ecfcb611610095578063f45fd80b1161006f578063f45fd80b14610bd0578063f9a2bbc714610c15578063fc3e590814610646578063fd6a687914610c2a57610376565b8063d7ecfcb6146107ee578063dc927faf14610ba6578063edc1a5b014610bbb57610376565b8063c2117d82116100d1578063c2117d8214610abc578063c81b166214610ad1578063c8509d8114610ae6578063d61b9b9314610b6b57610376565b8063b88a802f14610a57578063baaafd3b14610a6c578063bf8546ca14610a8157610376565b806396713da911610164578063a78abc161161013e578063a78abc1614610939578063ab51bb9614610962578063ac43175114610977578063b14315df14610a4257610376565b806396713da9146108fa5780639dc092621461090f578063a1a11bf51461092457610376565b806375d47a0a116101a057806375d47a0a1461084b5780637942fd0514610860578063831d65d11461087557806392b888a4146105f257610376565b806370fd5bad146107ee578063718a8aa81461080357806375aca5931461081857610376565b8063413d9c3a116102a05780635d17c8bd1161023e57806369b635b61161021857806369b635b61461075b5780636bd8f804146107705780636e47b482146107a65780636fb7f7eb146107bb57610376565b80635d17c8bd1461071c5780635d499b1b1461073157806362b171d21461074657610376565b80634bf6c8821161027a5780634bf6c882146106b15780634d99dd16146106c657806351e80672146106f2578063552aaf931461070757610376565b8063413d9c3a1461065b57806343756e5c14610670578063493279b11461068557610376565b8063151817e31161030d578063333ad3e7116102e7578063333ad3e71461061c57806334c43354146106315780633dffc387146105f25780633fdfa7e41461064657610376565b8063151817e3146105c757806317c9efb0146105f25780632fdeb1111461060757610376565b80630bee7a67116103495780630bee7a671461043b5780630e2374a5146104695780631182b8751461049a57806311fe9ec61461059457610376565b8063026e402b1461037b57806302985992146103a9578063047636d1146103d057610376565b3661037657005b600080fd5b6103a76004803603604081101561039157600080fd5b506001600160a01b038135169060200135610c3f565b005b3480156103b557600080fd5b506103be611141565b60408051918252519081900360200190f35b3480156103dc57600080fd5b50610403600480360360208110156103f357600080fd5b50356001600160a01b0316611147565b6040518082606080838360005b83811015610428578181015183820152602001610410565b5050505090500191505060405180910390f35b34801561044757600080fd5b5061045061119b565b6040805163ffffffff9092168252519081900360200190f35b34801561047557600080fd5b5061047e6111a0565b604080516001600160a01b039092168252519081900360200190f35b3480156104a657600080fd5b5061051f600480360360408110156104bd57600080fd5b60ff8235169190810190604081016020820135600160201b8111156104e157600080fd5b8201836020820111156104f357600080fd5b803590602001918460018302840111600160201b8311171561051457600080fd5b5090925090506111a6565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610559578181015183820152602001610541565b50505050905090810190601f1680156105865780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156105a057600080fd5b506103be600480360360208110156105b757600080fd5b50356001600160a01b031661135c565b3480156105d357600080fd5b506105dc611377565b6040805160ff9092168252519081900360200190f35b3480156105fe57600080fd5b506105dc61137c565b34801561061357600080fd5b506103be611381565b34801561062857600080fd5b50610450611387565b34801561063d57600080fd5b506103be61138c565b34801561065257600080fd5b506105dc611397565b34801561066757600080fd5b506103be61139c565b34801561067c57600080fd5b5061047e6113a3565b34801561069157600080fd5b5061069a6113a9565b6040805161ffff9092168252519081900360200190f35b3480156106bd57600080fd5b506105dc6113af565b6103a7600480360360408110156106dc57600080fd5b506001600160a01b0381351690602001356113b4565b3480156106fe57600080fd5b5061047e61199b565b34801561071357600080fd5b506105dc6119a1565b34801561072857600080fd5b506103be6119a6565b34801561073d57600080fd5b506103be6119ac565b34801561075257600080fd5b506103be6119b5565b34801561076757600080fd5b506103be611aed565b6103a76004803603606081101561078657600080fd5b506001600160a01b03813581169160208101359091169060400135611af3565b3480156107b257600080fd5b5061047e612161565b3480156107c757600080fd5b506103be600480360360208110156107de57600080fd5b50356001600160a01b0316612167565b3480156107fa57600080fd5b506105dc612182565b34801561080f57600080fd5b506105dc612187565b34801561082457600080fd5b506103be6004803603602081101561083b57600080fd5b50356001600160a01b031661218c565b34801561085757600080fd5b5061047e6121a7565b34801561086c57600080fd5b506105dc6121ad565b34801561088157600080fd5b506103a76004803603604081101561089857600080fd5b60ff8235169190810190604081016020820135600160201b8111156108bc57600080fd5b8201836020820111156108ce57600080fd5b803590602001918460018302840111600160201b831117156108ef57600080fd5b5090925090506121b2565b34801561090657600080fd5b506105dc612474565b34801561091b57600080fd5b5061047e612479565b34801561093057600080fd5b5061047e61247f565b34801561094557600080fd5b5061094e612485565b604080519115158252519081900360200190f35b34801561096e57600080fd5b506104506119a1565b34801561098357600080fd5b506103a76004803603604081101561099a57600080fd5b810190602081018135600160201b8111156109b457600080fd5b8201836020820111156109c657600080fd5b803590602001918460018302840111600160201b831117156109e757600080fd5b919390929091602081019035600160201b811115610a0457600080fd5b820183602082011115610a1657600080fd5b803590602001918460018302840111600160201b83111715610a3757600080fd5b50909250905061248e565b348015610a4e57600080fd5b506105dc612a8b565b348015610a6357600080fd5b506103be612a90565b348015610a7857600080fd5b506103be612bc5565b348015610a8d57600080fd5b506103be60048036036040811015610aa457600080fd5b506001600160a01b0381358116916020013516612bd0565b348015610ac857600080fd5b506103be612bfd565b348015610add57600080fd5b5061047e612c03565b348015610af257600080fd5b506103a760048036036040811015610b0957600080fd5b60ff8235169190810190604081016020820135600160201b811115610b2d57600080fd5b820183602082011115610b3f57600080fd5b803590602001918460018302840111600160201b83111715610b6057600080fd5b509092509050612c09565b348015610b7757600080fd5b506103be60048036036040811015610b8e57600080fd5b506001600160a01b0381358116916020013516612e26565b348015610bb257600080fd5b5061047e612e51565b348015610bc757600080fd5b506103be612e57565b348015610bdc57600080fd5b506103be60048036036060811015610bf357600080fd5b506001600160a01b038135811691602081013582169160409091013516612e64565b348015610c2157600080fd5b5061047e612e99565b348015610c3657600080fd5b5061047e612e9f565b60105460ff1660021415610c8b576040805162461bcd60e51b815260206004820152600e60248201526d4e6f2072652d656e7472616e637960901b604482015290519081900360640190fd5b6010805460ff19166002179055806402540be4003406158015610cb357506402540be4008106155b610d04576040805162461bcd60e51b815260206004820152601c60248201527f707265636973696f6e206c6f737320696e20636f6e76657273696f6e00000000604482015290519081900360640190fd5b60005460ff16610d41576638d7ea4c6800006001908155662386f26fc1000060025568056bc75e2d631000006003556000805460ff191690911790555b600354821015610d98576040805162461bcd60e51b815260206004820152601760248201527f696e76616c69642064656c656761746520616d6f756e74000000000000000000604482015290519081900360640190fd5b600154610dac90839063ffffffff612ea516565b341015610df7576040805162461bcd60e51b81526020600482015260146024820152736e6f7420656e6f756768206d73672076616c756560601b604482015290519081900360640190fd5b60405133906108fc9060009081818181818888f19350505050610e55576040805162461bcd60e51b815260206004820152601160248201527034b73b30b634b2103232b632b3b0ba37b960791b604482015290519081900360640190fd5b6000610e6c836402540be40063ffffffff612f0616565b90506000610e80348563ffffffff612f4816565b90506000610e9960025483612f4890919063ffffffff16565b6040805160038082526080820190925291925060609190816020015b6060815260200190600190039081610eb5579050509050610ed533612f8a565b81600081518110610ee257fe5b6020026020010181905250610eff876001600160a01b0316612f8a565b81600181518110610f0c57fe5b6020026020010181905250610f2084612fad565b81600281518110610f2d57fe5b60200260200101819052506060610f4d6001610f4884612fc0565b61304a565b8051602080830191909120600f80546000908152600a845260408082209390935581546001908101909255338152600b909352912080549091019055905061200063f7a251d7601083610fab876402540be40063ffffffff612f0616565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b83811015611009578181015183820152602001610ff1565b50505050905090810190601f1680156110365780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561105757600080fd5b505af115801561106b573d6000803e3d6000fd5b5061100492506108fc91506110889050898663ffffffff612ea516565b6040518115909202916000818181858888f193505050501580156110b0573d6000803e3d6000fd5b506002546040516110029180156108fc02916000818181858888f193505050501580156110e1573d6000803e3d6000fd5b50604080518881526020810185905281516001600160a01b038b169233927f5f32ed2794e2e72d19e3cb2320e8820a499c4204887372beba51f5e61c040867929081900390910190a350506010805460ff19166001179055505050505050565b60035481565b61114f614dda565b611157614dda565b6001600160a01b0383166000818152600b60209081526040808320548552838352600c82528083205485830152928252600d9052819020549082015290505b919050565b606481565b61200181565b606033612000146111e85760405162461bcd60e51b815260040180806020018281038252602f815260200180614f98602f913960400191505060405180910390fd5b60005460ff16611225576638d7ea4c6800006001908155662386f26fc1000060025568056bc75e2d631000006003556000805460ff191690911790555b61122d614df8565b61127461126f85858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506130d092505050565b6130f5565b905060006112896112848361313f565b61318d565b90506000606060ff8316600414156112ae576112a484613244565b9092509050611305565b60ff8316600514156112c3576112a484613424565b6040805162461bcd60e51b8152602060048201526012602482015271756e6b6e6f776e206576656e74207479706560701b604482015290519081900360640190fd5b63ffffffff821615611351576040805163ffffffff84168152905160ff8516917f391d6e5ea6ab6c49b9a0abb1782cae5def8d711f973b00c729658c0b2a80b31b919081900360200190a25b979650505050505050565b6001600160a01b031660009081526006602052604090205490565b600581565b600181565b60015481565b606581565b662386f26fc1000081565b600381565b620a8c0081565b61100181565b6102ca81565b600881565b60105460ff1660021415611400576040805162461bcd60e51b815260206004820152600e60248201526d4e6f2072652d656e7472616e637960901b604482015290519081900360640190fd5b6010805460ff19166002179055806402540be400340615801561142857506402540be4008106155b611479576040805162461bcd60e51b815260206004820152601c60248201527f707265636973696f6e206c6f737320696e20636f6e76657273696f6e00000000604482015290519081900360640190fd5b60005460ff166114b6576638d7ea4c6800006001908155662386f26fc1000060025568056bc75e2d631000006003556000805460ff191690911790555b600154341015611504576040805162461bcd60e51b81526020600482015260146024820152736e6f7420656e6f7567682072656c61792066656560601b604482015290519081900360640190fd5b6003548210156115bf576002548211611557576040805162461bcd60e51b815260206004820152601060248201526f6e6f7420656e6f7567682066756e647360801b604482015290519081900360640190fd5b3360009081526005602090815260408083206001600160a01b038716845290915290205482146115bf576040805162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b604482015290519081900360640190fd5b3360009081526005602090815260408083206001600160a01b0387168452909152902054821115611628576040805162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b604482015290519081900360640190fd5b3360009081526007602090815260408083206001600160a01b03871684529091529020544210156116a0576040805162461bcd60e51b815260206004820152601a60248201527f70656e64696e6720756e64656c65676174696f6e206578697374000000000000604482015290519081900360640190fd5b60006116b7836402540be40063ffffffff612f0616565b60025490915034906000906116d390839063ffffffff612f4816565b6040805160038082526080820190925291925060609190816020015b60608152602001906001900390816116ef57905050905061170f33612f8a565b8160008151811061171c57fe5b6020026020010181905250611739876001600160a01b0316612f8a565b8160018151811061174657fe5b602002602001018190525061175a84612fad565b8160028151811061176757fe5b602002602001018190525060606117826002610f4884612fc0565b8051602080830191909120600f80546000908152600a845260408082209390935581546001908101909255338152600c90935291208054909101905590506117d342620a8c0063ffffffff612ea516565b3360009081526007602090815260408083206001600160a01b038d16845290915290205561200063f7a251d7601083611817876402540be40063ffffffff612f0616565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561187557818101518382015260200161185d565b50505050905090810190601f1680156118a25780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156118c357600080fd5b505af11580156118d7573d6000803e3d6000fd5b5050604051611004925085156108fc02915085906000818181858888f1935050505015801561190a573d6000803e3d6000fd5b506002546040516110029180156108fc02916000818181858888f1935050505015801561193b573d6000803e3d6000fd5b50604080518881526020810185905281516001600160a01b038b169233927fdf0b6ac27f3f3bb31cee3dab0f4fe40cc19c6a3f8daaec52e06b261e58a12519929081900390910190a350506010805460ff19166001179055505050505050565b61200081565b600081565b60025481565b6402540be40081565b60105460009060ff1660021415611a04576040805162461bcd60e51b815260206004820152600e60248201526d4e6f2072652d656e7472616e637960901b604482015290519081900360640190fd5b506010805460ff191660021790553360009081526008602052604090205480611a6b576040805162461bcd60e51b81526020600482015260146024820152736e6f20756e64656c6567617465642066756e647360601b604482015290519081900360640190fd5b336000818152600860205260408082208290555183156108fc0291849190818181858888f19350505050158015611aa6573d6000803e3d6000fd5b5060408051828152905133917fc712d133b8d448221aaed2198ed1f0db6dfc860fb01bc3a630916fe6cbef946f919081900360200190a26010805460ff1916600117905590565b60035490565b60105460ff1660021415611b3f576040805162461bcd60e51b815260206004820152600e60248201526d4e6f2072652d656e7472616e637960901b604482015290519081900360640190fd5b6010805460ff19166002179055806402540be4003406158015611b6757506402540be4008106155b611bb8576040805162461bcd60e51b815260206004820152601c60248201527f707265636973696f6e206c6f737320696e20636f6e76657273696f6e00000000604482015290519081900360640190fd5b60005460ff16611bf5576638d7ea4c6800006001908155662386f26fc1000060025568056bc75e2d631000006003556000805460ff191690911790555b826001600160a01b0316846001600160a01b03161415611c53576040805162461bcd60e51b815260206004820152601460248201527334b73b30b634b2103932b232b632b3b0ba34b7b760611b604482015290519081900360640190fd5b600154341015611ca1576040805162461bcd60e51b81526020600482015260146024820152736e6f7420656e6f7567682072656c61792066656560601b604482015290519081900360640190fd5b6003548210158015611cd657503360009081526005602090815260408083206001600160a01b03881684529091529020548211155b611d18576040805162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b604482015290519081900360640190fd5b3360009081526009602090815260408083206001600160a01b03888116855290835281842090871684529091529020544210801590611d8657503360009081526009602090815260408083206001600160a01b03878116855290835281842090881684529091529020544210155b611dd7576040805162461bcd60e51b815260206004820152601a60248201527f70656e64696e6720726564656c65676174696f6e206578697374000000000000604482015290519081900360640190fd5b6000611dee836402540be40063ffffffff612f0616565b6002549091503490600090611e0a90839063ffffffff612f4816565b60408051600480825260a0820190925291925060609190816020015b6060815260200190600190039081611e26579050509050611e4633612f8a565b81600081518110611e5357fe5b6020026020010181905250611e70886001600160a01b0316612f8a565b81600181518110611e7d57fe5b6020026020010181905250611e9a876001600160a01b0316612f8a565b81600281518110611ea757fe5b6020026020010181905250611ebb84612fad565b81600381518110611ec857fe5b60200260200101819052506060611ee36003610f4884612fc0565b8051602080830191909120600f80546000908152600a845260408082209390935581546001908101909255338152600d9093529120805490910190559050611f3442620a8c0063ffffffff612ea516565b3360009081526009602090815260408083206001600160a01b038d81168552908352818420908e168452909152902055611f7742620a8c0063ffffffff612ea516565b3360009081526009602090815260408083206001600160a01b038e81168552908352818420908d16845290915290205561200063f7a251d7601083611fc7876402540be40063ffffffff612f0616565b6040518463ffffffff1660e01b8152600401808460ff1660ff16815260200180602001838152602001828103825284818151815260200191508051906020019080838360005b8381101561202557818101518382015260200161200d565b50505050905090810190601f1680156120525780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561207357600080fd5b505af1158015612087573d6000803e3d6000fd5b5050604051611004925085156108fc02915085906000818181858888f193505050501580156120ba573d6000803e3d6000fd5b506002546040516110029180156108fc02916000818181858888f193505050501580156120eb573d6000803e3d6000fd5b50876001600160a01b0316896001600160a01b0316336001600160a01b03167fdb0d03fdfcb145c486c442659e6a341a8828985505097cb5190afcf541e840158a87604051808381526020018281526020019250505060405180910390a450506010805460ff1916600117905550505050505050565b61100581565b6001600160a01b031660009081526004602052604090205490565b600281565b601081565b6001600160a01b031660009081526008602052604090205490565b61100881565b600b81565b33612000146121f25760405162461bcd60e51b815260040180806020018281038252602f815260200180614f98602f913960400191505060405180910390fd5b60005460ff1661222f576638d7ea4c6800006001908155662386f26fc1000060025568056bc75e2d631000006003556000805460ff191690911790555b612237614df8565b61227961126f84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506130d092505050565b905060008060606000805b61228d86613640565b156122f857806122aa576122a36112848761313f565b94506122f0565b80600114156122c6576122bf6112848761313f565b93506122f0565b80600214156122eb576122e06122db8761313f565b613661565b9250600191506122f0565b6122f8565b600101612284565b8161233e576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b612347836136d1565b61238a576040805162461bcd60e51b815260206004820152600f60248201526e0eee4dedcce40e0c2c6d640d0c2e6d608b1b604482015290519081900360640190fd5b61239661126f846130d0565b955060006123a66112848861313f565b90506123b0614df8565b6123b988613640565b156123dc576123d561126f6123d06122db8b61313f565b6130d0565b905061241d565b6040805162461bcd60e51b8152602060048201526011602482015270656d7074792061636b207061636b61676560781b604482015290519081900360640190fd5b60ff82166001141561243957612434818888613725565b612467565b60ff82166002141561245057612434818888613adc565b60ff8216600314156112c357612434818888613da9565b5050505050505050505050565b600981565b61100781565b61100681565b60005460ff1681565b60005460ff166124e5576040805162461bcd60e51b815260206004820152601960248201527f74686520636f6e7472616374206e6f7420696e69742079657400000000000000604482015290519081900360640190fd5b33611007146125255760405162461bcd60e51b815260040180806020018281038252602e815260200180614f0e602e913960400191505060405180910390fd5b61258684848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600a81526972656c6179657246656560b01b6020820152915061410e9050565b156126ec57602081146125e0576040805162461bcd60e51b815260206004820152601d60248201527f6c656e677468206f662072656c61796572466565206d69736d61746368000000604482015290519081900360640190fd5b604080516020601f840181900481028201810190925282815260009161261e918585808385018382808284376000920191909152506141f592505050565b905060035481106126605760405162461bcd60e51b815260040180806020018281038252602e815260200180614f3c602e913960400191505060405180910390fd5b60025481116126a05760405162461bcd60e51b815260040180806020018281038252602e815260200180614f6a602e913960400191505060405180910390fd5b6402540be4008106156126e45760405162461bcd60e51b815260040180806020018281038252602c815260200180614ee2602c913960400191505060405180910390fd5b6001556129f9565b61275084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c62534352656c6179657246656560981b6020820152915061410e9050565b1561287657602081146127aa576040805162461bcd60e51b815260206004820181905260248201527f6c656e677468206f662062534352656c61796572466565206d69736d61746368604482015290519081900360640190fd5b604080516020601f84018190048102820181019092528281526000916127e8918585808385018382808284376000920191909152506141f592505050565b9050600154811061282a5760405162461bcd60e51b815260040180806020018281038252602e815260200180614e62602e913960400191505060405180910390fd5b6402540be40081061561286e5760405162461bcd60e51b815260040180806020018281038252602f815260200180614e33602f913960400191505060405180910390fd5b6002556129f9565b6128da84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505060408051808201909152600d81526c36b4b72232b632b3b0ba34b7b760991b6020820152915061410e9050565b156129bc5760208114612934576040805162461bcd60e51b815260206004820181905260248201527f6c656e677468206f66206d696e44656c65676174696f6e206d69736d61746368604482015290519081900360640190fd5b604080516020601f8401819004810282018101909252828152600091612972918585808385018382808284376000920191909152506141f592505050565b905060015481116129b45760405162461bcd60e51b8152600401808060200182810382526031815260200180614e906031913960400191505060405180910390fd5b6003556129f9565b6040805162461bcd60e51b815260206004820152600d60248201526c756e6b6e6f776e20706172616d60981b604482015290519081900360640190fd5b7f6cdb0ac70ab7f2e2d035cca5be60d89906f2dede7648ddbd7402189c1eeed17a848484846040518080602001806020018381038352878782818152602001925080828437600083820152601f01601f191690910184810383528581526020019050858580828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b600481565b60105460009060ff1660021415612adf576040805162461bcd60e51b815260206004820152600e60248201526d4e6f2072652d656e7472616e637960901b604482015290519081900360640190fd5b506010805460ff191660021790553360009081526006602052604090205480612b43576040805162461bcd60e51b81526020600482015260116024820152701b9bc81c195b991a5b99c81c995dd85c99607a1b604482015290519081900360640190fd5b336000818152600660205260408082208290555183156108fc0291849190818181858888f19350505050158015612b7e573d6000803e3d6000fd5b5060408051828152905133917f83b78188b13346b2ffb484da70d42ee27de7fbf9f2bd8045269e10ed643ccd76919081900360200190a26010805460ff1916600117905590565b6638d7ea4c68000081565b6001600160a01b038083166000908152600760209081526040808320938516835292905220545b92915050565b60015490565b61100281565b3361200014612c495760405162461bcd60e51b815260040180806020018281038252602f815260200180614f98602f913960400191505060405180910390fd5b60005460ff16612c86576638d7ea4c6800006001908155662386f26fc1000060025568056bc75e2d631000006003556000805460ff191690911790555b612cc582828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506136d192505050565b612d08576040805162461bcd60e51b815260206004820152600f60248201526e0eee4dedcce40e0c2c6d640d0c2e6d608b1b604482015290519081900360640190fd5b612d10614df8565b612d5261126f84848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506130d092505050565b90506000612d626112848361313f565b9050612d6c614df8565b612d7583613640565b15612d9357612d8c61126f6123d06122db8661313f565b9050612dd9565b6040805162461bcd60e51b8152602060048201526016602482015275656d707479206661696c2061636b207061636b61676560501b604482015290519081900360640190fd5b60ff821660011415612df357612dee816141fa565b612e1d565b60ff821660021415612e0857612dee81614414565b60ff8216600314156112c357612dee8161453e565b5050505b505050565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205490565b61100381565b68056bc75e2d6310000081565b6001600160a01b0392831660009081526009602090815260408083209486168352938152838220929094168152925290205490565b61100081565b61100481565b600082820183811015612eff576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6000612eff83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506146a3565b6000612eff83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614745565b60408051600560a21b8318601482015260348101909152606090612eff8161479f565b6060612bf7612fbb836147f5565b61479f565b6060815160001415612fe15750604080516000815260208101909152611196565b606082600081518110612ff057fe5b602002602001015190506000600190505b8351811015613031576130278285838151811061301a57fe5b60200260200101516148db565b9150600101613001565b50612eff613044825160c060ff16614958565b826148db565b6040805160028082526060828101909352829190816020015b60608152602001906001900390816130635790505090506130868460ff16612fad565b8160008151811061309357fe5b60200260200101819052506130a78361479f565b816001815181106130b457fe5b60200260200101819052506130c881612fc0565b949350505050565b6130d8614e18565b506040805180820190915281518152602082810190820152919050565b6130fd614df8565b61310682614a50565b61310f57600080fd5b600061311e8360200151614a8a565b60208085015160408051808201909152868152920190820152915050919050565b613147614e18565b61315082613640565b61315957600080fd5b6020820151600061316982614aed565b80830160209586015260408051808201909152908152938401919091525090919050565b8051600090158015906131a257508151602110155b6131ab57600080fd5b60006131ba8360200151614a8a565b90508083600001511015613215576040805162461bcd60e51b815260206004820152601a60248201527f6c656e677468206973206c657373207468616e206f6666736574000000000000604482015290519081900360640190fd5b82516020808501518301805192849003929183101561323b57826020036101000a820491505b50949350505050565b600060606000806000805b61325887613640565b156132aa578261327a5761327361326e8861313f565b614c20565b915061329f565b826001141561329a5761328f6112848861313f565b90506001935061329f565b6132aa565b82600101925061324f565b836132f0576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b60006110046001600160a01b031663727be1f8836040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b15801561333a57600080fd5b505af115801561334e573d6000803e3d6000fd5b505050506040513d602081101561336457600080fd5b50519050806133895761337b600484846065614c3a565b96509650505050505061341f565b6001600160a01b0383166000908152600660205260409020546133b2908363ffffffff612ea516565b6001600160a01b038416600081815260066020908152604091829020939093558051858152905191927f7cc266c7b444f808013fa187f7b904d470a051a6564e78f482aa496581ba4bf892918290030190a260408051600080825260208201909252909750955050505050505b915091565b6000606060008060008060005b61343a88613640565b156134a357836134575761345061326e8961313f565b9250613498565b83600114156134735761346c61326e8961313f565b9150613498565b8360021415613493576134886112848961313f565b905060019450613498565b6134a3565b836001019350613431565b846134e9576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b60006110046001600160a01b031663727be1f8836040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b15801561353357600080fd5b505af1158015613547573d6000803e3d6000fd5b505050506040513d602081101561355d57600080fd5b505190508061358357613574600585846065614c3a565b9750975050505050505061341f565b6001600160a01b0380851660008181526007602090815260408083209488168352938152838220829055918152600890915220546135c7908363ffffffff612ea516565b6001600160a01b0380861660008181526008602090815260409182902094909455805186815290519287169391927f35a799836f74fac7eccf5c73902823b970543d2274d3b93d8da3d37a255772a2929181900390910190a3604080516000808252602082019092529098509650505050505050915091565b600061364a614e18565b505080518051602091820151919092015191011190565b805160609061366f57600080fd5b600061367e8360200151614a8a565b83516040805191839003808352601f19601f82011683016020019091529192506060908280156136b5576020820181803683370190505b509050600081602001905061323b848760200151018285614d36565b8051602080830191909120600e546000908152600a909252604082205480821461370057600092505050611196565b5050600e80546000908152600a60205260408120558054600190810190915592915050565b60008060008060005b61373788613640565b156137a057836137545761374d61326e8961313f565b9250613795565b83600114156137705761376961326e8961313f565b9150613795565b8360021415613790576137856112848961313f565b905060019450613795565b6137a0565b83600101935061372e565b846137e6576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b60006137fd826402540be40063ffffffff614d8116565b6001600160a01b0385166000908152600b602052604090208054600019019055905060ff8816600114156139435760ff871615613870576040805162461bcd60e51b815260206004820152600c60248201526b77726f6e672073746174757360a01b604482015290519081900360640190fd5b6001600160a01b038416600090815260046020526040902054613899908263ffffffff612ea516565b6001600160a01b038086166000908152600460209081526040808320949094556005815283822092871682529190915220546138db908263ffffffff612ea516565b6001600160a01b038086166000818152600560209081526040808320948916808452948252918290209490945580518581529051929391927f9a57c81564ab02642f34fd87e41baa9b074c18342cec3b7268b62bf752018fd1929181900390910190a3613ad1565b60ff8816613a95576001600160a01b038416600090815260086020526040902054613974908263ffffffff612ea516565b6001600160a01b0385166000908152600860209081526040808320939093558251630e4f7c3f60e31b81526004810185905292516110049363727be1f89360248083019493928390030190829087803b1580156139d057600080fd5b505af11580156139e4573d6000803e3d6000fd5b505050506040513d60208110156139fa57600080fd5b5051613a43576040805162461bcd60e51b81526020600482015260136024820152721dda5d1a191c985dc8189b988819985a5b1959606a1b604482015290519081900360640190fd5b6040805182815260ff8916602082015281516001600160a01b0380871693908816927fcbd481ae600289fad8c0484d07ce0ffe4f010d7c844ecfdeaf2a13fead52886e929081900390910190a3613ad1565b6040805162461bcd60e51b815260206004820152600c60248201526b77726f6e672073746174757360a01b604482015290519081900360640190fd5b505050505050505050565b60008060008060005b613aee88613640565b15613b575783613b0b57613b0461326e8961313f565b9250613b4c565b8360011415613b2757613b2061326e8961313f565b9150613b4c565b8360021415613b4757613b3c6112848961313f565b905060019450613b4c565b613b57565b836001019350613ae5565b84613b9d576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b6000613bb4826402540be40063ffffffff614d8116565b6001600160a01b0385166000908152600c602052604090208054600019019055905060ff881660011415613d335760ff871615613c27576040805162461bcd60e51b815260206004820152600c60248201526b77726f6e672073746174757360a01b604482015290519081900360640190fd5b6001600160a01b038416600090815260046020526040902054613c50908263ffffffff612f4816565b6001600160a01b03808616600090815260046020908152604080832094909455600581528382209287168252919091522054613c92908263ffffffff612f4816565b6001600160a01b03808616600090815260056020908152604080832093881683529290522055613ccb42620a8c0063ffffffff612ea516565b6001600160a01b038086166000818152600760209081526040808320948916808452948252918290209490945580518581529051929391927fd6f878a5bcbbe79a64e6418bb0d56aaa20b9a60587d45749819df88dfc7c3c44929181900390910190a3613ad1565b60ff8816613a95576001600160a01b03808516600081815260076020908152604080832094881680845294825280832092909255815185815260ff8c169181019190915281517f4417d10c1e33efa83a770b8d4f47176e78c08c1298d534901ad3b16bb585fa2e929181900390910190a3613ad1565b6000806000806000805b613dbc89613640565b15613e415784613dd957613dd261326e8a61313f565b9350613e36565b8460011415613df557613dee61326e8a61313f565b9250613e36565b8460021415613e1157613e0a61326e8a61313f565b9150613e36565b8460031415613e3157613e266112848a61313f565b905060019550613e36565b613e41565b846001019450613db3565b85613e87576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b6000613e9e826402540be40063ffffffff614d8116565b6001600160a01b0386166000908152600d602052604090208054600019019055905060ff8916600114156140715760ff881615613f11576040805162461bcd60e51b815260206004820152600c60248201526b77726f6e672073746174757360a01b604482015290519081900360640190fd5b6001600160a01b03808616600090815260056020908152604080832093881683529290522054613f47908263ffffffff612f4816565b6001600160a01b03868116600090815260056020908152604080832089851684529091528082209390935590851681522054613f839082612ea5565b6001600160a01b03808716600090815260056020908152604080832093881683529290522055613fbc42620a8c0063ffffffff612ea516565b6001600160a01b0380871660009081526009602090815260408083208985168452825280832093881683529290522055613fff42620a8c0063ffffffff612ea516565b6001600160a01b038087166000818152600960209081526040808320898616808552908352818420958b1680855295835292819020959095558451868152945191947f78bffae3f8c6691ac7fc1a3bff800cb2d612f5ad9ae5b0444cfe2eb15c189e18929081900390910190a4614102565b60ff8916613a95576001600160a01b038581166000818152600960209081526040808320898616808552818452828520968a16808652968452828520859055908352818420818552835281842093909355805186815260ff8e169281019290925280519293927fb93bee5c59f85ede6b074a99f4ffcd3e3fc0d5c3d8156de331de89a49e0ce77c9281900390910190a45b50505050505050505050565b6000816040516020018082805190602001908083835b602083106141435780518252601f199092019160209182019101614124565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120836040516020018082805190602001908083835b602083106141b15780518252601f199092019160209182019101614192565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012014905092915050565b015190565b60008060008060005b61420c86613640565b1561427557836142295761422261326e8761313f565b925061426a565b83600114156142455761423e61326e8761313f565b915061426a565b83600214156142655761425a6112848761313f565b90506001945061426a565b614275565b836001019350614203565b846142bb576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b60006142d2826402540be40063ffffffff614d8116565b6001600160a01b0385166000908152600b6020908152604080832080546000190190556008909152902054909150614310908263ffffffff612ea516565b6001600160a01b0385166000908152600860209081526040808320939093558251630e4f7c3f60e31b81526004810185905292516110049363727be1f89360248083019493928390030190829087803b15801561436c57600080fd5b505af1158015614380573d6000803e3d6000fd5b505050506040513d602081101561439657600080fd5b50516143df576040805162461bcd60e51b81526020600482015260136024820152721dda5d1a191c985dc8189b988819985a5b1959606a1b604482015290519081900360640190fd5b6040516001907ff83de021914a4585482db5ca47d520a5657165b443fa2c7ef8ed4635f054da9b90600090a250505050505050565b60008060008060005b61442686613640565b1561448f57836144435761443c61326e8761313f565b9250614484565b836001141561445f5761445861326e8761313f565b9150614484565b836002141561447f576144746112848761313f565b905060019450614484565b61448f565b83600101935061441d565b846144d5576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b6001600160a01b038084166000908152600c60209081526040808320805460001901905560078252808320938616835292905281812081905590516002917ff83de021914a4585482db5ca47d520a5657165b443fa2c7ef8ed4635f054da9b91a2505050505050565b6000806000806000805b61455187613640565b156145d6578461456e5761456761326e8861313f565b93506145cb565b846001141561458a5761458361326e8861313f565b92506145cb565b84600214156145a65761459f61326e8861313f565b91506145cb565b84600314156145c6576145bb6112848861313f565b9050600195506145cb565b6145d6565b846001019450614548565b8561461c576040805162461bcd60e51b81526020600482015260116024820152701c9b1c08191958dbd9194819985a5b1959607a1b604482015290519081900360640190fd5b6001600160a01b038481166000908152600d602090815260408083208054600019019055600982528083208785168085528184528285209588168552948352818420849055825280832093835292905281812081905590516003917ff83de021914a4585482db5ca47d520a5657165b443fa2c7ef8ed4635f054da9b91a250505050505050565b6000818361472f5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156146f45781810151838201526020016146dc565b50505050905090810190601f1680156147215780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161473b57fe5b0495945050505050565b600081848411156147975760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156146f45781810151838201526020016146dc565b505050900390565b6060815160011480156147d15750607f60f81b826000815181106147bf57fe5b01602001516001600160f81b03191611155b156147dd575080611196565b612bf76147ef8351608060ff16614958565b836148db565b604080516020808252818301909252606091829190602082018180368337505050602081018490529050600067ffffffffffffffff1984166148395750601861485d565b6fffffffffffffffffffffffffffffffff1984166148595750601061485d565b5060005b60208110156148935781818151811061487257fe5b01602001516001600160f81b0319161561488b57614893565b60010161485d565b60008160200390506060816040519080825280601f01601f1916602001820160405280156148c8576020820181803683370190505b5080830196909652508452509192915050565b6060806040519050835180825260208201818101602087015b8183101561490c5780518352602092830192016148f4565b50855184518101855292509050808201602086015b81831015614939578051835260209283019201614921565b508651929092011591909101601f01601f191660405250905092915050565b60606801000000000000000083106149a8576040805162461bcd60e51b815260206004820152600e60248201526d696e70757420746f6f206c6f6e6760901b604482015290519081900360640190fd5b60408051600180825281830190925260609160208201818036833701905050905060378411614a025782840160f81b816000815181106149e457fe5b60200101906001600160f81b031916908160001a9053509050612bf7565b6060614a0d856147f5565b90508381510160370160f81b82600081518110614a2657fe5b60200101906001600160f81b031916908160001a905350614a4782826148db565b95945050505050565b8051600090614a6157506000611196565b6020820151805160001a9060c0821015614a8057600092505050611196565b5060019392505050565b8051600090811a6080811015614aa4576000915050611196565b60b8811080614abf575060c08110801590614abf575060f881105b15614ace576001915050611196565b60c0811015614ae25760b519019050611196565b60f519019050611196565b80516000908190811a6080811015614b085760019150614c19565b60b8811015614b1d57607e1981019150614c19565b60c0811015614b9757600060b78203600186019550806020036101000a865104915060018101820193505080831015614b91576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b50614c19565b60f8811015614bac5760be1981019150614c19565b600060f78203600186019550806020036101000a865104915060018101820193505080831015614c17576040805162461bcd60e51b81526020600482015260116024820152706164646974696f6e206f766572666c6f7760781b604482015290519081900360640190fd5b505b5092915050565b8051600090601514614c3157600080fd5b612bf78261318d565b60006060614c53846402540be40063ffffffff612f0616565b60408051600480825260a0820190925291955060609190816020015b6060815260200190600190039081614c6f579050509050614c928760ff16612fad565b81600081518110614c9f57fe5b6020026020010181905250614cbc866001600160a01b0316612f8a565b81600181518110614cc957fe5b6020026020010181905250614cdd85612fad565b81600281518110614cea57fe5b6020026020010181905250614d048463ffffffff16612fad565b81600381518110614d1157fe5b60200260200101819052506060614d2782612fc0565b94989497509395505050505050565b80614d4057612e21565b5b60208110614d60578251825260209283019290910190601f1901614d41565b915181516020939093036101000a6000190180199091169216919091179052565b600082614d9057506000612bf7565b82820282848281614d9d57fe5b0414612eff5760405162461bcd60e51b8152600401808060200182810382526021815260200180614ec16021913960400191505060405180910390fd5b60405180606001604052806003906020820280368337509192915050565b6040518060400160405280614e0b614e18565b8152602001600081525090565b60405180604001604052806000815260200160008152509056fe7468652042534352656c61796572466565206d6f642074656e20646563696d616c73206d757374206265207a65726f7468652042534352656c61796572466565206d757374206265206c657373207468616e2072656c61796572466565746865206d696e44656c65676174696f6e206d7573742062652067726561746572207468616e2072656c61796572466565536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f777468652072656c61796572466565206d6f642074656e20646563696d616c73206d757374206265207a65726f746865206d6573736167652073656e646572206d75737420626520676f7665726e616e636520636f6e74726163747468652072656c61796572466565206d757374206265206c657373207468616e206d696e44656c65676174696f6e7468652072656c61796572466565206d757374206265206d6f7265207468616e2042534352656c61796572466565746865206d6573736167652073656e646572206d7573742062652063726f737320636861696e20636f6e7472616374a26469706673582212202d43db3e2ebde4487e0172cc743868769dac674a6b5ac4e5b38d932f5fe77d2964736f6c63430006040033", + }, + }, + } } func UpgradeBuildInSystemContract(config *params.ChainConfig, blockNumber *big.Int, statedb *state.StateDB) { @@ -400,6 +433,10 @@ func UpgradeBuildInSystemContract(config *params.ChainConfig, blockNumber *big.I applySystemContractUpgrade(eulerUpgrade[network], blockNumber, statedb, logger) } + if config.IsOnGibbs(blockNumber) { + applySystemContractUpgrade(gibbsUpgrade[network], blockNumber, statedb, logger) + } + /* apply other upgrades */ diff --git a/core/tx_pool.go b/core/tx_pool.go index 21fb5e5d0c..31b0690739 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -1224,10 +1224,17 @@ func (pool *TxPool) runReorg(done chan struct{}, reset *txpoolResetRequest, dirt // because of another transaction (e.g. higher gas price). if reset != nil { pool.demoteUnexecutables() - if reset.newHead != nil && pool.chainconfig.IsLondon(new(big.Int).Add(reset.newHead.Number, big.NewInt(1))) { - pendingBaseFee := misc.CalcBaseFee(pool.chainconfig, reset.newHead) - pool.priced.SetBaseFee(pendingBaseFee) + if reset.newHead != nil { + if pool.chainconfig.IsLondon(new(big.Int).Add(reset.newHead.Number, big.NewInt(1))) { + // london fork enabled, reset given the base fee + pendingBaseFee := misc.CalcBaseFee(pool.chainconfig, reset.newHead) + pool.priced.SetBaseFee(pendingBaseFee) + } else { + // london fork not enabled, reheap to "reset" the priced list + pool.priced.Reheap() + } } + // Update all accounts to the latest known pending nonce nonces := make(map[common.Address]uint64, len(pool.pending)) for addr, list := range pool.pending { diff --git a/core/types/access_list_tx.go b/core/types/access_list_tx.go index ee5f194b77..8ad5e739e9 100644 --- a/core/types/access_list_tx.go +++ b/core/types/access_list_tx.go @@ -22,7 +22,7 @@ import ( "github.com/ethereum/go-ethereum/common" ) -//go:generate gencodec -type AccessTuple -out gen_access_tuple.go +//go:generate go run github.com/fjl/gencodec@latest -type AccessTuple -out gen_access_tuple.go // AccessList is an EIP-2930 access list. type AccessList []AccessTuple diff --git a/core/types/block.go b/core/types/block.go index 59c6adf2a9..634ac219e3 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -93,7 +93,8 @@ func (n *BlockNonce) UnmarshalText(input []byte) error { return hexutil.UnmarshalFixedText("BlockNonce", input, n[:]) } -//go:generate gencodec -type Header -field-override headerMarshaling -out gen_header_json.go +//go:generate go run github.com/fjl/gencodec@latest -type Header -field-override headerMarshaling -out gen_header_json.go +//go:generate go run ../../rlp/rlpgen -type Header -out gen_header_rlp.go // Header represents a block header in the Ethereum blockchain. type Header struct { diff --git a/core/types/block_test.go b/core/types/block_test.go index 5cdea3fc06..aa1db2f4fa 100644 --- a/core/types/block_test.go +++ b/core/types/block_test.go @@ -285,7 +285,7 @@ func makeBenchBlock() *Block { func TestRlpDecodeParentHash(t *testing.T) { // A minimum one want := common.HexToHash("0x112233445566778899001122334455667788990011223344556677889900aabb") - if rlpData, err := rlp.EncodeToBytes(Header{ParentHash: want}); err != nil { + if rlpData, err := rlp.EncodeToBytes(&Header{ParentHash: want}); err != nil { t.Fatal(err) } else { if have := HeaderParentHashFromRLP(rlpData); have != want { @@ -299,7 +299,7 @@ func TestRlpDecodeParentHash(t *testing.T) { // | BaseFee | dynamic| *big.Int | 64 bits | mainnetTd := new(big.Int) mainnetTd.SetString("5ad3c2c71bbff854908", 16) - if rlpData, err := rlp.EncodeToBytes(Header{ + if rlpData, err := rlp.EncodeToBytes(&Header{ ParentHash: want, Difficulty: mainnetTd, Number: new(big.Int).SetUint64(math.MaxUint64), @@ -316,7 +316,7 @@ func TestRlpDecodeParentHash(t *testing.T) { { // The rlp-encoding of the heder belowCauses _total_ length of 65540, // which is the first to blow the fast-path. - h := Header{ + h := &Header{ ParentHash: want, Extra: make([]byte, 65041), } diff --git a/core/types/gen_account_rlp.go b/core/types/gen_account_rlp.go new file mode 100644 index 0000000000..5181d88411 --- /dev/null +++ b/core/types/gen_account_rlp.go @@ -0,0 +1,27 @@ +// Code generated by rlpgen. DO NOT EDIT. + +//go:build !norlpgen +// +build !norlpgen + +package types + +import "github.com/ethereum/go-ethereum/rlp" +import "io" + +func (obj *StateAccount) EncodeRLP(_w io.Writer) error { + w := rlp.NewEncoderBuffer(_w) + _tmp0 := w.List() + w.WriteUint64(obj.Nonce) + if obj.Balance == nil { + w.Write(rlp.EmptyString) + } else { + if obj.Balance.Sign() == -1 { + return rlp.ErrNegativeBigInt + } + w.WriteBigInt(obj.Balance) + } + w.WriteBytes(obj.Root[:]) + w.WriteBytes(obj.CodeHash) + w.ListEnd(_tmp0) + return w.Flush() +} diff --git a/core/types/gen_header_rlp.go b/core/types/gen_header_rlp.go new file mode 100644 index 0000000000..e1a6873318 --- /dev/null +++ b/core/types/gen_header_rlp.go @@ -0,0 +1,56 @@ +// Code generated by rlpgen. DO NOT EDIT. + +//go:build !norlpgen +// +build !norlpgen + +package types + +import "github.com/ethereum/go-ethereum/rlp" +import "io" + +func (obj *Header) EncodeRLP(_w io.Writer) error { + w := rlp.NewEncoderBuffer(_w) + _tmp0 := w.List() + w.WriteBytes(obj.ParentHash[:]) + w.WriteBytes(obj.UncleHash[:]) + w.WriteBytes(obj.Coinbase[:]) + w.WriteBytes(obj.Root[:]) + w.WriteBytes(obj.TxHash[:]) + w.WriteBytes(obj.ReceiptHash[:]) + w.WriteBytes(obj.Bloom[:]) + if obj.Difficulty == nil { + w.Write(rlp.EmptyString) + } else { + if obj.Difficulty.Sign() == -1 { + return rlp.ErrNegativeBigInt + } + w.WriteBigInt(obj.Difficulty) + } + if obj.Number == nil { + w.Write(rlp.EmptyString) + } else { + if obj.Number.Sign() == -1 { + return rlp.ErrNegativeBigInt + } + w.WriteBigInt(obj.Number) + } + w.WriteUint64(obj.GasLimit) + w.WriteUint64(obj.GasUsed) + w.WriteUint64(obj.Time) + w.WriteBytes(obj.Extra) + w.WriteBytes(obj.MixDigest[:]) + w.WriteBytes(obj.Nonce[:]) + _tmp1 := obj.BaseFee != nil + if _tmp1 { + if obj.BaseFee == nil { + w.Write(rlp.EmptyString) + } else { + if obj.BaseFee.Sign() == -1 { + return rlp.ErrNegativeBigInt + } + w.WriteBigInt(obj.BaseFee) + } + } + w.ListEnd(_tmp0) + return w.Flush() +} diff --git a/core/types/gen_log_rlp.go b/core/types/gen_log_rlp.go new file mode 100644 index 0000000000..4a6c6b0094 --- /dev/null +++ b/core/types/gen_log_rlp.go @@ -0,0 +1,23 @@ +// Code generated by rlpgen. DO NOT EDIT. + +//go:build !norlpgen +// +build !norlpgen + +package types + +import "github.com/ethereum/go-ethereum/rlp" +import "io" + +func (obj *rlpLog) EncodeRLP(_w io.Writer) error { + w := rlp.NewEncoderBuffer(_w) + _tmp0 := w.List() + w.WriteBytes(obj.Address[:]) + _tmp1 := w.List() + for _, _tmp2 := range obj.Topics { + w.WriteBytes(_tmp2[:]) + } + w.ListEnd(_tmp1) + w.WriteBytes(obj.Data) + w.ListEnd(_tmp0) + return w.Flush() +} diff --git a/core/types/log.go b/core/types/log.go index 88274e39da..b27c7ccbd3 100644 --- a/core/types/log.go +++ b/core/types/log.go @@ -24,7 +24,7 @@ import ( "github.com/ethereum/go-ethereum/rlp" ) -//go:generate gencodec -type Log -field-override logMarshaling -out gen_log_json.go +//go:generate go run github.com/fjl/gencodec@latest -type Log -field-override logMarshaling -out gen_log_json.go // Log represents a contract log event. These events are generated by the LOG opcode and // stored/indexed by the node. @@ -62,15 +62,14 @@ type logMarshaling struct { Index hexutil.Uint } +//go:generate go run ../../rlp/rlpgen -type rlpLog -out gen_log_rlp.go + type rlpLog struct { Address common.Address Topics []common.Hash Data []byte } -// rlpStorageLog is the storage encoding of a log. -type rlpStorageLog rlpLog - // legacyRlpStorageLog is the previous storage encoding of a log including some redundant fields. type legacyRlpStorageLog struct { Address common.Address @@ -85,7 +84,8 @@ type legacyRlpStorageLog struct { // EncodeRLP implements rlp.Encoder. func (l *Log) EncodeRLP(w io.Writer) error { - return rlp.Encode(w, rlpLog{Address: l.Address, Topics: l.Topics, Data: l.Data}) + rl := rlpLog{Address: l.Address, Topics: l.Topics, Data: l.Data} + return rlp.Encode(w, &rl) } // DecodeRLP implements rlp.Decoder. @@ -104,11 +104,8 @@ type LogForStorage Log // EncodeRLP implements rlp.Encoder. func (l *LogForStorage) EncodeRLP(w io.Writer) error { - return rlp.Encode(w, rlpStorageLog{ - Address: l.Address, - Topics: l.Topics, - Data: l.Data, - }) + rl := rlpLog{Address: l.Address, Topics: l.Topics, Data: l.Data} + return rlp.Encode(w, &rl) } // DecodeRLP implements rlp.Decoder. @@ -119,7 +116,7 @@ func (l *LogForStorage) DecodeRLP(s *rlp.Stream) error { if err != nil { return err } - var dec rlpStorageLog + var dec rlpLog err = rlp.DecodeBytes(blob, &dec) if err == nil { *l = LogForStorage{ diff --git a/core/types/receipt.go b/core/types/receipt.go index 28b82f26f5..90c9dbcd02 100644 --- a/core/types/receipt.go +++ b/core/types/receipt.go @@ -31,7 +31,7 @@ import ( "github.com/ethereum/go-ethereum/rlp" ) -//go:generate gencodec -type Receipt -field-override receiptMarshaling -out gen_receipt_json.go +//go:generate go run github.com/fjl/gencodec@latest -type Receipt -field-override receiptMarshaling -out gen_receipt_json.go var ( receiptStatusFailedRLP = []byte{} @@ -293,16 +293,20 @@ type ReceiptForStorage Receipt // EncodeRLP implements rlp.Encoder, and flattens all content fields of a receipt // into an RLP stream. -func (r *ReceiptForStorage) EncodeRLP(w io.Writer) error { - enc := &storedReceiptRLP{ - PostStateOrStatus: (*Receipt)(r).statusEncoding(), - CumulativeGasUsed: r.CumulativeGasUsed, - Logs: make([]*LogForStorage, len(r.Logs)), - } - for i, log := range r.Logs { - enc.Logs[i] = (*LogForStorage)(log) +func (r *ReceiptForStorage) EncodeRLP(_w io.Writer) error { + w := rlp.NewEncoderBuffer(_w) + outerList := w.List() + w.WriteBytes((*Receipt)(r).statusEncoding()) + w.WriteUint64(r.CumulativeGasUsed) + logList := w.List() + for _, log := range r.Logs { + if err := rlp.Encode(w, log); err != nil { + return err + } } - return rlp.Encode(w, enc) + w.ListEnd(logList) + w.ListEnd(outerList) + return w.Flush() } // DecodeRLP implements rlp.Decoder, and loads both consensus and implementation diff --git a/core/types/state_account.go b/core/types/state_account.go index 68804bf311..3b01be4519 100644 --- a/core/types/state_account.go +++ b/core/types/state_account.go @@ -22,6 +22,8 @@ import ( "github.com/ethereum/go-ethereum/common" ) +//go:generate go run ../../rlp/rlpgen -type StateAccount -out gen_account_rlp.go + // StateAccount is the Ethereum consensus representation of accounts. // These objects are stored in the main account trie. type StateAccount struct { diff --git a/core/vm/operations_acl.go b/core/vm/operations_acl.go index 483226eefa..551e1f5f11 100644 --- a/core/vm/operations_acl.go +++ b/core/vm/operations_acl.go @@ -214,7 +214,7 @@ var ( // see gasSStoreEIP2200(...) in core/vm/gas_table.go for more info about how EIP 2200 is specified gasSStoreEIP2929 = makeGasSStoreFunc(params.SstoreClearsScheduleRefundEIP2200) - // gasSStoreEIP2539 implements gas cost for SSTORE according to EPI-2539 + // gasSStoreEIP2539 implements gas cost for SSTORE according to EIP-2539 // Replace `SSTORE_CLEARS_SCHEDULE` with `SSTORE_RESET_GAS + ACCESS_LIST_STORAGE_KEY_COST` (4,800) gasSStoreEIP3529 = makeGasSStoreFunc(params.SstoreClearsScheduleRefundEIP3529) ) diff --git a/docs/lint/commit.md b/docs/lint/commit.md new file mode 100644 index 0000000000..1e76e4dc9d --- /dev/null +++ b/docs/lint/commit.md @@ -0,0 +1,26 @@ +## Commit Format Requirements +1. The head line should contain no more than 72 characters +2. head line is composed by scope : subject +3. multi-scope is supported, separated by a space, such as scope1 scope2 scope3: subject + it is better that scope number =<3 , scope length <= 20 char , but not mandatory +4. keyword, such as R4R or WIP is not acceptable in the scope, no matter upper case or lower case. + +#### Example: Single Scope +``` +evm: optimize opcode mload +``` + +#### Example: Multi Scope +``` +rpc core db: refactor the interface of trie access +``` + +#### Example: Big Scope +if the change is too big, impact several scopes, the scope name can be bep, feat or fix +``` +bep130: implement parallel evm + +feat: implement parallel trie prefetch + +fix: stack overflow on GetCommitState +``` diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index 207ed39915..9ac5a7fd43 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -1340,23 +1340,25 @@ func (d *Downloader) processHeaders(origin uint64, td *big.Int) error { if chunkHeaders[len(chunkHeaders)-1].Number.Uint64()+uint64(fsHeaderForceVerify) > pivot { frequency = 1 } - if n, err := d.lightchain.InsertHeaderChain(chunkHeaders, frequency); err != nil { - rollbackErr = err + if len(chunkHeaders) > 0 { + if n, err := d.lightchain.InsertHeaderChain(chunkHeaders, frequency); err != nil { + rollbackErr = err - // If some headers were inserted, track them as uncertain - if (mode == SnapSync || frequency > 1) && n > 0 && rollback == 0 { - rollback = chunkHeaders[0].Number.Uint64() + // If some headers were inserted, track them as uncertain + if (mode == SnapSync || frequency > 1) && n > 0 && rollback == 0 { + rollback = chunkHeaders[0].Number.Uint64() + } + log.Warn("Invalid header encountered", "number", chunkHeaders[n].Number, "hash", chunkHashes[n], "parent", chunkHeaders[n].ParentHash, "err", err) + return fmt.Errorf("%w: %v", errInvalidChain, err) } - log.Warn("Invalid header encountered", "number", chunkHeaders[n].Number, "hash", chunkHashes[n], "parent", chunkHeaders[n].ParentHash, "err", err) - return fmt.Errorf("%w: %v", errInvalidChain, err) - } - // All verifications passed, track all headers within the alloted limits - if mode == SnapSync { - head := chunkHeaders[len(chunkHeaders)-1].Number.Uint64() - if head-rollback > uint64(fsHeaderSafetyNet) { - rollback = head - uint64(fsHeaderSafetyNet) - } else { - rollback = 1 + // All verifications passed, track all headers within the alloted limits + if mode == SnapSync { + head := chunkHeaders[len(chunkHeaders)-1].Number.Uint64() + if head-rollback > uint64(fsHeaderSafetyNet) { + rollback = head - uint64(fsHeaderSafetyNet) + } else { + rollback = 1 + } } } } diff --git a/eth/downloader/downloader_test.go b/eth/downloader/downloader_test.go index a2e0e2e34d..88951fba11 100644 --- a/eth/downloader/downloader_test.go +++ b/eth/downloader/downloader_test.go @@ -60,7 +60,7 @@ func newTester() *downloadTester { if err != nil { panic(err) } - db, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), freezer, "", false, false, false, false) + db, err := rawdb.NewDatabaseWithFreezer(rawdb.NewMemoryDatabase(), freezer, "", false, false, false, false, true) if err != nil { panic(err) } diff --git a/eth/gasprice/gasprice_test.go b/eth/gasprice/gasprice_test.go index bcb3e23e4d..01edde38ce 100644 --- a/eth/gasprice/gasprice_test.go +++ b/eth/gasprice/gasprice_test.go @@ -108,6 +108,7 @@ func newTestBackend(t *testing.T, londonBlock *big.Int, pending bool) *testBacke ) config.LondonBlock = londonBlock config.ArrowGlacierBlock = londonBlock + config.GibbsBlock = nil engine := ethash.NewFaker() db := rawdb.NewMemoryDatabase() genesis, err := gspec.Commit(db) diff --git a/eth/handler_eth_test.go b/eth/handler_eth_test.go index 02f12010fc..74db6668c3 100644 --- a/eth/handler_eth_test.go +++ b/eth/handler_eth_test.go @@ -693,7 +693,7 @@ func testCheckpointChallenge(t *testing.T, syncmode downloader.SyncMode, checkpo t.Fatalf("failed to answer challenge: %v", err) } } else { - responseRlp, _ := rlp.EncodeToBytes(types.Header{Number: response.Number}) + responseRlp, _ := rlp.EncodeToBytes(&types.Header{Number: response.Number}) if err := remote.ReplyBlockHeadersRLP(request.RequestId, []rlp.RawValue{responseRlp}); err != nil { t.Fatalf("failed to answer challenge: %v", err) } diff --git a/eth/protocols/eth/handler_test.go b/eth/protocols/eth/handler_test.go index 7d9b378839..55e612b801 100644 --- a/eth/protocols/eth/handler_test.go +++ b/eth/protocols/eth/handler_test.go @@ -264,11 +264,11 @@ func testGetBlockHeaders(t *testing.T, protocol uint) { headers = append(headers, backend.chain.GetBlockByHash(hash).Header()) } // Send the hash request and verify the response - p2p.Send(peer.app, GetBlockHeadersMsg, GetBlockHeadersPacket66{ + p2p.Send(peer.app, GetBlockHeadersMsg, &GetBlockHeadersPacket66{ RequestId: 123, GetBlockHeadersPacket: tt.query, }) - if err := p2p.ExpectMsg(peer.app, BlockHeadersMsg, BlockHeadersPacket66{ + if err := p2p.ExpectMsg(peer.app, BlockHeadersMsg, &BlockHeadersPacket66{ RequestId: 123, BlockHeadersPacket: headers, }); err != nil { @@ -279,14 +279,12 @@ func testGetBlockHeaders(t *testing.T, protocol uint) { if origin := backend.chain.GetBlockByNumber(tt.query.Origin.Number); origin != nil { tt.query.Origin.Hash, tt.query.Origin.Number = origin.Hash(), 0 - p2p.Send(peer.app, GetBlockHeadersMsg, GetBlockHeadersPacket66{ + p2p.Send(peer.app, GetBlockHeadersMsg, &GetBlockHeadersPacket66{ RequestId: 456, GetBlockHeadersPacket: tt.query, }) - if err := p2p.ExpectMsg(peer.app, BlockHeadersMsg, BlockHeadersPacket66{ - RequestId: 456, - BlockHeadersPacket: headers, - }); err != nil { + expected := &BlockHeadersPacket66{RequestId: 456, BlockHeadersPacket: headers} + if err := p2p.ExpectMsg(peer.app, BlockHeadersMsg, expected); err != nil { t.Errorf("test %d by hash: headers mismatch: %v", i, err) } } @@ -364,11 +362,11 @@ func testGetBlockBodies(t *testing.T, protocol uint) { } } // Send the hash request and verify the response - p2p.Send(peer.app, GetBlockBodiesMsg, GetBlockBodiesPacket66{ + p2p.Send(peer.app, GetBlockBodiesMsg, &GetBlockBodiesPacket66{ RequestId: 123, GetBlockBodiesPacket: hashes, }) - if err := p2p.ExpectMsg(peer.app, BlockBodiesMsg, BlockBodiesPacket66{ + if err := p2p.ExpectMsg(peer.app, BlockBodiesMsg, &BlockBodiesPacket66{ RequestId: 123, BlockBodiesPacket: bodies, }); err != nil { @@ -436,7 +434,7 @@ func testGetNodeData(t *testing.T, protocol uint) { it.Release() // Request all hashes. - p2p.Send(peer.app, GetNodeDataMsg, GetNodeDataPacket66{ + p2p.Send(peer.app, GetNodeDataMsg, &GetNodeDataPacket66{ RequestId: 123, GetNodeDataPacket: hashes, }) @@ -546,11 +544,11 @@ func testGetBlockReceipts(t *testing.T, protocol uint) { receipts = append(receipts, backend.chain.GetReceiptsByHash(block.Hash())) } // Send the hash request and verify the response - p2p.Send(peer.app, GetReceiptsMsg, GetReceiptsPacket66{ + p2p.Send(peer.app, GetReceiptsMsg, &GetReceiptsPacket66{ RequestId: 123, GetReceiptsPacket: hashes, }) - if err := p2p.ExpectMsg(peer.app, ReceiptsMsg, ReceiptsPacket66{ + if err := p2p.ExpectMsg(peer.app, ReceiptsMsg, &ReceiptsPacket66{ RequestId: 123, ReceiptsPacket: receipts, }); err != nil { diff --git a/eth/protocols/eth/peer.go b/eth/protocols/eth/peer.go index dd02b03b5b..2f6b0293f6 100644 --- a/eth/protocols/eth/peer.go +++ b/eth/protocols/eth/peer.go @@ -260,7 +260,7 @@ func (p *Peer) ReplyPooledTransactionsRLP(id uint64, hashes []common.Hash, txs [ p.knownTxs.Add(hashes...) // Not packed into PooledTransactionsPacket to avoid RLP decoding - return p2p.Send(p.rw, PooledTransactionsMsg, PooledTransactionsRLPPacket66{ + return p2p.Send(p.rw, PooledTransactionsMsg, &PooledTransactionsRLPPacket66{ RequestId: id, PooledTransactionsRLPPacket: txs, }) @@ -317,7 +317,7 @@ func (p *Peer) AsyncSendNewBlock(block *types.Block, td *big.Int) { // ReplyBlockHeaders is the eth/66 version of SendBlockHeaders. func (p *Peer) ReplyBlockHeadersRLP(id uint64, headers []rlp.RawValue) error { - return p2p.Send(p.rw, BlockHeadersMsg, BlockHeadersRLPPacket66{ + return p2p.Send(p.rw, BlockHeadersMsg, &BlockHeadersRLPPacket66{ RequestId: id, BlockHeadersRLPPacket: headers, }) @@ -326,7 +326,7 @@ func (p *Peer) ReplyBlockHeadersRLP(id uint64, headers []rlp.RawValue) error { // ReplyBlockBodiesRLP is the eth/66 version of SendBlockBodiesRLP. func (p *Peer) ReplyBlockBodiesRLP(id uint64, bodies []rlp.RawValue) error { // Not packed into BlockBodiesPacket to avoid RLP decoding - return p2p.Send(p.rw, BlockBodiesMsg, BlockBodiesRLPPacket66{ + return p2p.Send(p.rw, BlockBodiesMsg, &BlockBodiesRLPPacket66{ RequestId: id, BlockBodiesRLPPacket: bodies, }) @@ -334,7 +334,7 @@ func (p *Peer) ReplyBlockBodiesRLP(id uint64, bodies []rlp.RawValue) error { // ReplyNodeData is the eth/66 response to GetNodeData. func (p *Peer) ReplyNodeData(id uint64, data [][]byte) error { - return p2p.Send(p.rw, NodeDataMsg, NodeDataPacket66{ + return p2p.Send(p.rw, NodeDataMsg, &NodeDataPacket66{ RequestId: id, NodeDataPacket: data, }) @@ -342,7 +342,7 @@ func (p *Peer) ReplyNodeData(id uint64, data [][]byte) error { // ReplyReceiptsRLP is the eth/66 response to GetReceipts. func (p *Peer) ReplyReceiptsRLP(id uint64, receipts []rlp.RawValue) error { - return p2p.Send(p.rw, ReceiptsMsg, ReceiptsRLPPacket66{ + return p2p.Send(p.rw, ReceiptsMsg, &ReceiptsRLPPacket66{ RequestId: id, ReceiptsRLPPacket: receipts, }) diff --git a/eth/protocols/snap/sync.go b/eth/protocols/snap/sync.go index 51ac8bd420..9a1af86cd4 100644 --- a/eth/protocols/snap/sync.go +++ b/eth/protocols/snap/sync.go @@ -2830,7 +2830,10 @@ func (s *Syncer) reportSyncProgress(force bool) { new(big.Int).Mul(new(big.Int).SetUint64(uint64(synced)), hashSpace), accountFills, ).Uint64()) - + // Don't report anything until we have a meaningful progress + if estBytes < 1.0 { + return + } elapsed := time.Since(s.startTime) estTime := elapsed / time.Duration(synced) * time.Duration(estBytes) diff --git a/eth/protocols/snap/sync_test.go b/eth/protocols/snap/sync_test.go index 47ab1f026d..879ce8b6b2 100644 --- a/eth/protocols/snap/sync_test.go +++ b/eth/protocols/snap/sync_test.go @@ -1349,7 +1349,7 @@ func makeAccountTrieNoStorage(n int) (*trie.Trie, entrySlice) { accTrie, _ := trie.New(common.Hash{}, db) var entries entrySlice for i := uint64(1); i <= uint64(n); i++ { - value, _ := rlp.EncodeToBytes(types.StateAccount{ + value, _ := rlp.EncodeToBytes(&types.StateAccount{ Nonce: i, Balance: big.NewInt(int64(i)), Root: emptyRoot, @@ -1394,7 +1394,7 @@ func makeBoundaryAccountTrie(n int) (*trie.Trie, entrySlice) { } // Fill boundary accounts for i := 0; i < len(boundaries); i++ { - value, _ := rlp.EncodeToBytes(types.StateAccount{ + value, _ := rlp.EncodeToBytes(&types.StateAccount{ Nonce: uint64(0), Balance: big.NewInt(int64(i)), Root: emptyRoot, @@ -1406,7 +1406,7 @@ func makeBoundaryAccountTrie(n int) (*trie.Trie, entrySlice) { } // Fill other accounts if required for i := uint64(1); i <= uint64(n); i++ { - value, _ := rlp.EncodeToBytes(types.StateAccount{ + value, _ := rlp.EncodeToBytes(&types.StateAccount{ Nonce: i, Balance: big.NewInt(int64(i)), Root: emptyRoot, @@ -1442,7 +1442,7 @@ func makeAccountTrieWithStorageWithUniqueStorage(accounts, slots int, code bool) stTrie, stEntries := makeStorageTrieWithSeed(uint64(slots), i, db) stRoot := stTrie.Hash() stTrie.Commit(nil) - value, _ := rlp.EncodeToBytes(types.StateAccount{ + value, _ := rlp.EncodeToBytes(&types.StateAccount{ Nonce: i, Balance: big.NewInt(int64(i)), Root: stRoot, @@ -1489,7 +1489,7 @@ func makeAccountTrieWithStorage(accounts, slots int, code, boundary bool) (*trie if code { codehash = getCodeHash(i) } - value, _ := rlp.EncodeToBytes(types.StateAccount{ + value, _ := rlp.EncodeToBytes(&types.StateAccount{ Nonce: i, Balance: big.NewInt(int64(i)), Root: stRoot, diff --git a/eth/tracers/api.go b/eth/tracers/api.go index 693c5435da..9c1fdfbd59 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -454,7 +454,7 @@ func (api *API) TraceBlockByHash(ctx context.Context, hash common.Hash, config * // TraceBlock returns the structured logs created during the execution of EVM // and returns them as a JSON object. -func (api *API) TraceBlock(ctx context.Context, blob []byte, config *TraceConfig) ([]*txTraceResult, error) { +func (api *API) TraceBlock(ctx context.Context, blob hexutil.Bytes, config *TraceConfig) ([]*txTraceResult, error) { block := new(types.Block) if err := rlp.Decode(bytes.NewReader(blob), block); err != nil { return nil, fmt.Errorf("could not decode block: %v", err) diff --git a/go.mod b/go.mod index a6a3acb727..0e357fb564 100644 --- a/go.mod +++ b/go.mod @@ -80,6 +80,7 @@ require ( golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912 golang.org/x/text v0.3.6 golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba + golang.org/x/tools v0.1.0 gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 gopkg.in/urfave/cli.v1 v1.20.0 diff --git a/go.sum b/go.sum index 5ef6be435d..e47c562f49 100644 --- a/go.sum +++ b/go.sum @@ -488,6 +488,7 @@ golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -611,6 +612,7 @@ golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/graphql/graphql.go b/graphql/graphql.go index 9f1e251970..68ac63b5dc 100644 --- a/graphql/graphql.go +++ b/graphql/graphql.go @@ -100,6 +100,14 @@ func (a *Account) Balance(ctx context.Context) (hexutil.Big, error) { } func (a *Account) TransactionCount(ctx context.Context) (hexutil.Uint64, error) { + // Ask transaction pool for the nonce which includes pending transactions + if blockNr, ok := a.blockNrOrHash.Number(); ok && blockNr == rpc.PendingBlockNumber { + nonce, err := a.backend.GetPoolNonce(ctx, a.address) + if err != nil { + return 0, err + } + return hexutil.Uint64(nonce), nil + } state, err := a.getState(ctx) if err != nil { return 0, err diff --git a/internal/build/download.go b/internal/build/download.go index 0ed0b5e130..efb223b327 100644 --- a/internal/build/download.go +++ b/internal/build/download.go @@ -58,7 +58,7 @@ func (db *ChecksumDB) Verify(path string) error { } fileHash := hex.EncodeToString(h.Sum(nil)) if !db.findHash(filepath.Base(path), fileHash) { - return fmt.Errorf("invalid file hash %s", fileHash) + return fmt.Errorf("invalid file hash %s for %s", fileHash, filepath.Base(path)) } return nil } diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 58fa326344..cf2108fcd9 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -293,7 +293,7 @@ func NewPrivateAccountAPI(b Backend, nonceLock *AddrLocker) *PrivateAccountAPI { } } -// listAccounts will return a list of addresses for accounts this node manages. +// ListAccounts will return a list of addresses for accounts this node manages. func (s *PrivateAccountAPI) ListAccounts() []common.Address { return s.am.Accounts() } @@ -1967,7 +1967,7 @@ func (s *PublicTransactionPoolAPI) GetTransactionDataAndReceipt(ctx context.Cont fields["status"] = hexutil.Uint(receipt.Status) } if receipt.Logs == nil { - fields["logs"] = [][]*types.Log{} + fields["logs"] = []*types.Log{} } // If the ContractAddress is 20 0x0 bytes, assume it is not a contract creation if receipt.ContractAddress != (common.Address{}) { diff --git a/les/peer.go b/les/peer.go index e09b3bc130..a1d932649a 100644 --- a/les/peer.go +++ b/les/peer.go @@ -212,7 +212,7 @@ func (p *peerCommons) sendReceiveHandshake(sendList keyValueList) (keyValueList, ) // Send out own handshake in a new thread go func() { - errc <- p2p.Send(p.rw, StatusMsg, sendList) + errc <- p2p.Send(p.rw, StatusMsg, &sendList) }() go func() { // In the mean time retrieve the remote status message @@ -420,7 +420,7 @@ func sendRequest(w p2p.MsgWriter, msgcode, reqID uint64, data interface{}) error ReqID uint64 Data interface{} } - return p2p.Send(w, msgcode, req{reqID, data}) + return p2p.Send(w, msgcode, &req{reqID, data}) } func (p *serverPeer) sendRequest(msgcode, reqID uint64, data interface{}, amount int) error { @@ -870,7 +870,7 @@ func (r *reply) send(bv uint64) error { ReqID, BV uint64 Data rlp.RawValue } - return p2p.Send(r.w, r.msgcode, resp{r.reqID, bv, r.data}) + return p2p.Send(r.w, r.msgcode, &resp{r.reqID, bv, r.data}) } // size returns the RLP encoded size of the message data diff --git a/les/test_helper.go b/les/test_helper.go index a5829fa882..9394e6c8c8 100644 --- a/les/test_helper.go +++ b/les/test_helper.go @@ -356,7 +356,7 @@ func (p *testPeer) handshakeWithServer(t *testing.T, td *big.Int, head common.Ha if err := p2p.ExpectMsg(p.app, StatusMsg, nil); err != nil { t.Fatalf("status recv: %v", err) } - if err := p2p.Send(p.app, StatusMsg, sendList); err != nil { + if err := p2p.Send(p.app, StatusMsg, &sendList); err != nil { t.Fatalf("status send: %v", err) } } @@ -389,7 +389,7 @@ func (p *testPeer) handshakeWithClient(t *testing.T, td *big.Int, head common.Ha if err := p2p.ExpectMsg(p.app, StatusMsg, nil); err != nil { t.Fatalf("status recv: %v", err) } - if err := p2p.Send(p.app, StatusMsg, sendList); err != nil { + if err := p2p.Send(p.app, StatusMsg, &sendList); err != nil { t.Fatalf("status send: %v", err) } } diff --git a/les/vflux/client/fillset_test.go b/les/vflux/client/fillset_test.go index 58240682c6..ca5af8f07e 100644 --- a/les/vflux/client/fillset_test.go +++ b/les/vflux/client/fillset_test.go @@ -34,16 +34,20 @@ type testIter struct { } func (i *testIter) Next() bool { - i.waitCh <- struct{}{} + if _, ok := <-i.waitCh; !ok { + return false + } i.node = <-i.nodeCh - return i.node != nil + return true } func (i *testIter) Node() *enode.Node { return i.node } -func (i *testIter) Close() {} +func (i *testIter) Close() { + close(i.waitCh) +} func (i *testIter) push() { var id enode.ID @@ -53,7 +57,7 @@ func (i *testIter) push() { func (i *testIter) waiting(timeout time.Duration) bool { select { - case <-i.waitCh: + case i.waitCh <- struct{}{}: return true case <-time.After(timeout): return false diff --git a/les/vflux/server/clientpool.go b/les/vflux/server/clientpool.go index 87d783ebab..805de2d41b 100644 --- a/les/vflux/server/clientpool.go +++ b/les/vflux/server/clientpool.go @@ -34,7 +34,7 @@ import ( var ( ErrNotConnected = errors.New("client not connected") ErrNoPriority = errors.New("priority too low to raise capacity") - ErrCantFindMaximum = errors.New("Unable to find maximum allowed capacity") + ErrCantFindMaximum = errors.New("unable to find maximum allowed capacity") ) // ClientPool implements a client database that assigns a priority to each client @@ -177,7 +177,7 @@ func (cp *ClientPool) Unregister(peer clientPeer) { cp.ns.SetField(peer.Node(), cp.setup.clientField, nil) } -// setConnectedBias sets the connection bias, which is applied to already connected clients +// SetConnectedBias sets the connection bias, which is applied to already connected clients // So that already connected client won't be kicked out very soon and we can ensure all // connected clients can have enough time to request or sync some data. func (cp *ClientPool) SetConnectedBias(bias time.Duration) { diff --git a/light/lightchain.go b/light/lightchain.go index 78a436085e..7ce0b2698d 100644 --- a/light/lightchain.go +++ b/light/lightchain.go @@ -424,6 +424,9 @@ func (lc *LightChain) SetChainHead(header *types.Header) error { // In the case of a light chain, InsertHeaderChain also creates and posts light // chain events when necessary. func (lc *LightChain) InsertHeaderChain(chain []*types.Header, checkFreq int) (int, error) { + if len(chain) == 0 { + return 0, nil + } if atomic.LoadInt32(&lc.disableCheckFreq) == 1 { checkFreq = 0 } diff --git a/miner/worker.go b/miner/worker.go index 7eb1b69103..7a7eaf14c5 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -34,6 +34,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/trie" ) @@ -78,6 +79,12 @@ const ( staleThreshold = 11 ) +var ( + commitTxsTimer = metrics.NewRegisteredTimer("worker/committxs", nil) + writeBlockTimer = metrics.NewRegisteredTimer("worker/writeblock", nil) + finalizeBlockTimer = metrics.NewRegisteredTimer("worker/finalizeblock", nil) +) + // environment is the worker's current environment and holds all // information of the sealing block generation. type environment struct { @@ -602,6 +609,7 @@ func (w *worker) mainLoop() { // already included in the current sealing block. These transactions will // be automatically eliminated. if !w.isRunning() && w.current != nil { + start := time.Now() // If block is already full, abort if gp := w.current.gasPool; gp != nil && gp.Gas() < params.TxGas { continue @@ -614,6 +622,7 @@ func (w *worker) mainLoop() { txset := types.NewTransactionsByPriceAndNonce(w.current.signer, txs, w.current.header.BaseFee) tcount := w.current.tcount w.commitTransactions(w.current, txset, nil) + commitTxsTimer.UpdateSince(start) // Only update the snapshot if any new transactions were added // to the pending block @@ -747,19 +756,22 @@ func (w *worker) resultLoop() { } logs = append(logs, receipt.Logs...) } + + // Broadcast the block and announce chain insertion event + w.mux.Post(core.NewMinedBlockEvent{Block: block}) + // Commit block and state to database. task.state.SetExpectedStateRoot(block.Root()) + start := time.Now() _, err := w.chain.WriteBlockAndSetHead(block, receipts, logs, task.state, true) if err != nil { log.Error("Failed writing block to chain", "err", err) continue } + writeBlockTimer.UpdateSince(start) log.Info("Successfully sealed new block", "number", block.Number(), "sealhash", sealhash, "hash", hash, "elapsed", common.PrettyDuration(time.Since(task.createdAt))) - // Broadcast the block and announce chain insertion event - w.mux.Post(core.NewMinedBlockEvent{Block: block}) - // Insert the block into the set of pending ones to resultLoop for confirmations w.unconfirmed.Insert(block.NumberU64(), block.Hash()) @@ -888,7 +900,7 @@ func (w *worker) commitTransactions(env *environment, txs *types.TransactionsByP txsPrefetch := txs.Copy() tx := txsPrefetch.Peek() txCurr := &tx - w.prefetcher.PrefetchMining(txsPrefetch, env.header, env.gasPool.Gas(), env.state.Copy(), *w.chain.GetVMConfig(), interruptCh, txCurr) + w.prefetcher.PrefetchMining(txsPrefetch, env.header, env.gasPool.Gas(), env.state.CopyDoPrefetch(), *w.chain.GetVMConfig(), interruptCh, txCurr) LOOP: for { @@ -1197,10 +1209,12 @@ func (w *worker) commit(env *environment, interval func(), update bool, start ti } env.state.CorrectAccountsRoot(w.chain.CurrentBlock().Root()) + finalizeStart := time.Now() block, receipts, err := w.engine.FinalizeAndAssemble(w.chain, types.CopyHeader(env.header), env.state, env.txs, env.unclelist(), env.receipts) if err != nil { return err } + finalizeBlockTimer.UpdateSince(finalizeStart) // Create a local environment copy, avoid the data race with snapshot state. // https://github.com/ethereum/go-ethereum/issues/24299 diff --git a/mobile/geth.go b/mobile/geth.go index bad9e0589f..709b68cbde 100644 --- a/mobile/geth.go +++ b/mobile/geth.go @@ -220,14 +220,6 @@ func (n *Node) Start() error { return n.node.Start() } -// Stop terminates a running node along with all its services. If the node was not started, -// an error is returned. It is not possible to restart a stopped node. -// -// Deprecated: use Close() -func (n *Node) Stop() error { - return n.node.Close() -} - // GetEthereumClient retrieves a client to access the Ethereum subsystem. func (n *Node) GetEthereumClient() (client *EthereumClient, _ error) { rpc, err := n.node.Attach() diff --git a/node/node.go b/node/node.go index d9bba741a7..48f7b4c4be 100644 --- a/node/node.go +++ b/node/node.go @@ -594,7 +594,7 @@ func (n *Node) OpenAndMergeDatabase(name string, cache, handles int, freezer, di if persistDiff { chainDataHandles = handles * chainDataHandlesPercentage / 100 } - chainDB, err := n.OpenDatabaseWithFreezer(name, cache, chainDataHandles, freezer, namespace, readonly, false, false, pruneAncientData) + chainDB, err := n.OpenDatabaseWithFreezer(name, cache, chainDataHandles, freezer, namespace, readonly, false, false, pruneAncientData, false) if err != nil { return nil, err } @@ -614,7 +614,7 @@ func (n *Node) OpenAndMergeDatabase(name string, cache, handles int, freezer, di // also attaching a chain freezer to it that moves ancient chain data from the // database to immutable append-only files. If the node is an ephemeral one, a // memory database is returned. -func (n *Node) OpenDatabaseWithFreezer(name string, cache, handles int, freezer, namespace string, readonly, disableFreeze, isLastOffset, pruneAncientData bool) (ethdb.Database, error) { +func (n *Node) OpenDatabaseWithFreezer(name string, cache, handles int, freezer, namespace string, readonly, disableFreeze, isLastOffset, pruneAncientData, skipCheckFreezerType bool) (ethdb.Database, error) { n.lock.Lock() defer n.lock.Unlock() if n.state == closedState { @@ -633,7 +633,7 @@ func (n *Node) OpenDatabaseWithFreezer(name string, cache, handles int, freezer, case !filepath.IsAbs(freezer): freezer = n.ResolvePath(freezer) } - db, err = rawdb.NewLevelDBDatabaseWithFreezer(root, cache, handles, freezer, namespace, readonly, disableFreeze, isLastOffset, pruneAncientData) + db, err = rawdb.NewLevelDBDatabaseWithFreezer(root, cache, handles, freezer, namespace, readonly, disableFreeze, isLastOffset, pruneAncientData, skipCheckFreezerType) } if err == nil { diff --git a/p2p/server.go b/p2p/server.go index 6d2b6b1c15..38c2d73a0e 100644 --- a/p2p/server.go +++ b/p2p/server.go @@ -976,9 +976,8 @@ func (srv *Server) setupConn(c *conn, flags connFlag, dialDest *enode.Node) erro } // If dialing, figure out the remote public key. - var dialPubkey *ecdsa.PublicKey if dialDest != nil { - dialPubkey = new(ecdsa.PublicKey) + dialPubkey := new(ecdsa.PublicKey) if err := dialDest.Load((*enode.Secp256k1)(dialPubkey)); err != nil { err = errors.New("dial destination doesn't have a secp256k1 public key") srv.log.Trace("Setting up connection failed", "addr", c.fd.RemoteAddr(), "conn", c.flags, "err", err) diff --git a/p2p/simulations/http_test.go b/p2p/simulations/http_test.go index 6d7f0b6d7a..f5172f3f23 100644 --- a/p2p/simulations/http_test.go +++ b/p2p/simulations/http_test.go @@ -141,7 +141,7 @@ func (t *testService) Stop() error { // message with the given code func (t *testService) handshake(rw p2p.MsgReadWriter, code uint64) error { errc := make(chan error, 2) - go func() { errc <- p2p.Send(rw, code, struct{}{}) }() + go func() { errc <- p2p.SendItems(rw, code) }() go func() { errc <- p2p.ExpectMsg(rw, code, struct{}{}) }() for i := 0; i < 2; i++ { if err := <-errc; err != nil { diff --git a/params/config.go b/params/config.go index 2681da63df..8cc6a2182d 100644 --- a/params/config.go +++ b/params/config.go @@ -279,6 +279,7 @@ var ( }, Threshold: 2, } + BSCChainConfig = &ChainConfig{ ChainID: big.NewInt(56), HomesteadBlock: big.NewInt(0), @@ -296,6 +297,9 @@ var ( BrunoBlock: big.NewInt(13082000), EulerBlock: big.NewInt(18907621), + //TODO + GibbsBlock: nil, + Parlia: &ParliaConfig{ Period: 3, Epoch: 200, @@ -318,6 +322,7 @@ var ( MirrorSyncBlock: big.NewInt(5582500), BrunoBlock: big.NewInt(13837000), EulerBlock: big.NewInt(19203503), + GibbsBlock: big.NewInt(22800220), Parlia: &ParliaConfig{ Period: 3, @@ -340,7 +345,8 @@ var ( NielsBlock: big.NewInt(0), MirrorSyncBlock: big.NewInt(400), BrunoBlock: big.NewInt(400), - EulerBlock: nil, + EulerBlock: big.NewInt(400), + GibbsBlock: big.NewInt(400), Parlia: &ParliaConfig{ Period: 3, @@ -366,6 +372,7 @@ var ( MirrorSyncBlock: big.NewInt(0), BrunoBlock: big.NewInt(0), EulerBlock: big.NewInt(0), + GibbsBlock: big.NewInt(0), MuirGlacierBlock: nil, BerlinBlock: nil, // Don't enable Berlin directly, we're YOLOing it YoloV3Block: big.NewInt(0), @@ -380,16 +387,16 @@ var ( // // This configuration is intentionally not using keyed fields to force anyone // adding flags to the config to also have to set these fields. - AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), new(EthashConfig), nil, nil} + AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), new(EthashConfig), nil, nil} // AllCliqueProtocolChanges contains every protocol change (EIPs) introduced // and accepted by the Ethereum core developers into the Clique consensus. // // This configuration is intentionally not using keyed fields to force anyone // adding flags to the config to also have to set these fields. - AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), nil, nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil} + AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), nil, nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil} - TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), new(EthashConfig), nil, nil} + TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), new(EthashConfig), nil, nil} TestRules = TestChainConfig.Rules(new(big.Int), false) ) @@ -482,6 +489,7 @@ type ChainConfig struct { MirrorSyncBlock *big.Int `json:"mirrorSyncBlock,omitempty" toml:",omitempty"` // mirrorSyncBlock switch block (nil = no fork, 0 = already activated) BrunoBlock *big.Int `json:"brunoBlock,omitempty" toml:",omitempty"` // brunoBlock switch block (nil = no fork, 0 = already activated) EulerBlock *big.Int `json:"eulerBlock,omitempty" toml:",omitempty"` // eulerBlock switch block (nil = no fork, 0 = already activated) + GibbsBlock *big.Int `json:"gibbsBlock,omitempty" toml:",omitempty"` // gibbsBlock switch block (nil = no fork, 0 = already activated) // Various consensus engines Ethash *EthashConfig `json:"ethash,omitempty" toml:",omitempty"` @@ -532,7 +540,7 @@ func (c *ChainConfig) String() string { default: engine = "unknown" } - return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Ramanujan: %v, Niels: %v, MirrorSync: %v, Bruno: %v, Berlin: %v, YOLO v3: %v, CatalystBlock: %v, London: %v, ArrowGlacier: %v, MergeFork:%v, Euler: %v, Engine: %v}", + return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Ramanujan: %v, Niels: %v, MirrorSync: %v, Bruno: %v, Berlin: %v, YOLO v3: %v, CatalystBlock: %v, London: %v, ArrowGlacier: %v, MergeFork:%v, Euler: %v, Gibbs: %v, Engine: %v}", c.ChainID, c.HomesteadBlock, c.DAOForkBlock, @@ -556,6 +564,7 @@ func (c *ChainConfig) String() string { c.ArrowGlacierBlock, c.MergeForkBlock, c.EulerBlock, + c.GibbsBlock, engine, ) } @@ -685,6 +694,16 @@ func (c *ChainConfig) IsTerminalPoWBlock(parentTotalDiff *big.Int, totalDiff *bi return parentTotalDiff.Cmp(c.TerminalTotalDifficulty) < 0 && totalDiff.Cmp(c.TerminalTotalDifficulty) >= 0 } +// IsGibbs returns whether num is either equal to the gibbs fork block or greater. +func (c *ChainConfig) IsGibbs(num *big.Int) bool { + return isForked(c.GibbsBlock, num) +} + +// IsOnGibbs returns whether num is equal to the gibbs fork block +func (c *ChainConfig) IsOnGibbs(num *big.Int) bool { + return configNumEqual(c.GibbsBlock, num) +} + // CheckCompatible checks whether scheduled fork transitions have been imported // with a mismatching chain configuration. func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError { @@ -716,10 +735,7 @@ func (c *ChainConfig) CheckConfigForkOrder() error { {name: "mirrorSyncBlock", block: c.MirrorSyncBlock}, {name: "brunoBlock", block: c.BrunoBlock}, {name: "eulerBlock", block: c.EulerBlock}, - {name: "berlinBlock", block: c.BerlinBlock}, - {name: "londonBlock", block: c.LondonBlock}, - {name: "arrowGlacierBlock", block: c.ArrowGlacierBlock, optional: true}, - {name: "mergeStartBlock", block: c.MergeForkBlock, optional: true}, + {name: "gibbsBlock", block: c.GibbsBlock}, } { if lastFork.name != "" { // Next one must be higher number @@ -807,6 +823,9 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *Confi if isForkIncompatible(c.EulerBlock, newcfg.EulerBlock, head) { return newCompatError("euler fork block", c.EulerBlock, newcfg.EulerBlock) } + if isForkIncompatible(c.GibbsBlock, newcfg.GibbsBlock, head) { + return newCompatError("gibbs fork block", c.GibbsBlock, newcfg.GibbsBlock) + } return nil } diff --git a/params/protocol_params.go b/params/protocol_params.go index 30b5309982..e244c24231 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -19,11 +19,10 @@ package params import "math/big" const ( - GasLimitBoundDivisor uint64 = 1024 // The bound divisor of the gas limit, used in update calculations. - ParliaGasLimitBoundDivisor uint64 = 256 // The bound divisor of the gas limit, used in update calculations. - MinGasLimit uint64 = 5000 // Minimum the gas limit may ever be. - MaxGasLimit uint64 = 0x7fffffffffffffff // Maximum the gas limit (2^63-1). - GenesisGasLimit uint64 = 4712388 // Gas limit of the Genesis block. + GasLimitBoundDivisor uint64 = 256 // The bound divisor of the gas limit, used in update calculations. + MinGasLimit uint64 = 5000 // Minimum the gas limit may ever be. + MaxGasLimit uint64 = 0x7fffffffffffffff // Maximum the gas limit (2^63-1). + GenesisGasLimit uint64 = 4712388 // Gas limit of the Genesis block. MaximumExtraDataSize uint64 = 32 // Maximum size extra data may be after Genesis. ForkIDSize uint64 = 4 // The length of fork id diff --git a/params/version.go b/params/version.go index c0a9a4509f..9cffddc7d2 100644 --- a/params/version.go +++ b/params/version.go @@ -23,7 +23,7 @@ import ( const ( VersionMajor = 1 // Major version component of the current release VersionMinor = 1 // Minor version component of the current release - VersionPatch = 12 // Patch version component of the current release + VersionPatch = 13 // Patch version component of the current release VersionMeta = "" // Version metadata to append to the version string ) diff --git a/rlp/decode.go b/rlp/decode.go index 5f2e5ad5fe..9214dbfb37 100644 --- a/rlp/decode.go +++ b/rlp/decode.go @@ -27,6 +27,8 @@ import ( "reflect" "strings" "sync" + + "github.com/ethereum/go-ethereum/rlp/internal/rlpstruct" ) //lint:ignore ST1012 EOL is not an error. @@ -148,7 +150,7 @@ var ( bigInt = reflect.TypeOf(big.Int{}) ) -func makeDecoder(typ reflect.Type, tags tags) (dec decoder, err error) { +func makeDecoder(typ reflect.Type, tags rlpstruct.Tags) (dec decoder, err error) { kind := typ.Kind() switch { case typ == rawValueType: @@ -220,55 +222,20 @@ func decodeBigIntNoPtr(s *Stream, val reflect.Value) error { } func decodeBigInt(s *Stream, val reflect.Value) error { - var buffer []byte - kind, size, err := s.Kind() - switch { - case err != nil: - return wrapStreamError(err, val.Type()) - case kind == List: - return wrapStreamError(ErrExpectedString, val.Type()) - case kind == Byte: - buffer = s.uintbuf[:1] - buffer[0] = s.byteval - s.kind = -1 // re-arm Kind - case size == 0: - // Avoid zero-length read. - s.kind = -1 - case size <= uint64(len(s.uintbuf)): - // For integers smaller than s.uintbuf, allocating a buffer - // can be avoided. - buffer = s.uintbuf[:size] - if err := s.readFull(buffer); err != nil { - return wrapStreamError(err, val.Type()) - } - // Reject inputs where single byte encoding should have been used. - if size == 1 && buffer[0] < 128 { - return wrapStreamError(ErrCanonSize, val.Type()) - } - default: - // For large integers, a temporary buffer is needed. - buffer = make([]byte, size) - if err := s.readFull(buffer); err != nil { - return wrapStreamError(err, val.Type()) - } - } - - // Reject leading zero bytes. - if len(buffer) > 0 && buffer[0] == 0 { - return wrapStreamError(ErrCanonInt, val.Type()) - } - - // Set the integer bytes. i := val.Interface().(*big.Int) if i == nil { i = new(big.Int) val.Set(reflect.ValueOf(i)) } - i.SetBytes(buffer) + + err := s.decodeBigInt(i) + if err != nil { + return wrapStreamError(err, val.Type()) + } return nil } -func makeListDecoder(typ reflect.Type, tag tags) (decoder, error) { +func makeListDecoder(typ reflect.Type, tag rlpstruct.Tags) (decoder, error) { etype := typ.Elem() if etype.Kind() == reflect.Uint8 && !reflect.PtrTo(etype).Implements(decoderInterface) { if typ.Kind() == reflect.Array { @@ -276,7 +243,7 @@ func makeListDecoder(typ reflect.Type, tag tags) (decoder, error) { } return decodeByteSlice, nil } - etypeinfo := theTC.infoWhileGenerating(etype, tags{}) + etypeinfo := theTC.infoWhileGenerating(etype, rlpstruct.Tags{}) if etypeinfo.decoderErr != nil { return nil, etypeinfo.decoderErr } @@ -286,7 +253,7 @@ func makeListDecoder(typ reflect.Type, tag tags) (decoder, error) { dec = func(s *Stream, val reflect.Value) error { return decodeListArray(s, val, etypeinfo.decoder) } - case tag.tail: + case tag.Tail: // A slice with "tail" tag can occur as the last field // of a struct and is supposed to swallow all remaining // list elements. The struct decoder already called s.List, @@ -451,16 +418,16 @@ func zeroFields(structval reflect.Value, fields []field) { } // makePtrDecoder creates a decoder that decodes into the pointer's element type. -func makePtrDecoder(typ reflect.Type, tag tags) (decoder, error) { +func makePtrDecoder(typ reflect.Type, tag rlpstruct.Tags) (decoder, error) { etype := typ.Elem() - etypeinfo := theTC.infoWhileGenerating(etype, tags{}) + etypeinfo := theTC.infoWhileGenerating(etype, rlpstruct.Tags{}) switch { case etypeinfo.decoderErr != nil: return nil, etypeinfo.decoderErr - case !tag.nilOK: + case !tag.NilOK: return makeSimplePtrDecoder(etype, etypeinfo), nil default: - return makeNilPtrDecoder(etype, etypeinfo, tag.nilKind), nil + return makeNilPtrDecoder(etype, etypeinfo, tag), nil } } @@ -481,9 +448,13 @@ func makeSimplePtrDecoder(etype reflect.Type, etypeinfo *typeinfo) decoder { // values are decoded into a value of the element type, just like makePtrDecoder does. // // This decoder is used for pointer-typed struct fields with struct tag "nil". -func makeNilPtrDecoder(etype reflect.Type, etypeinfo *typeinfo, nilKind Kind) decoder { +func makeNilPtrDecoder(etype reflect.Type, etypeinfo *typeinfo, ts rlpstruct.Tags) decoder { typ := reflect.PtrTo(etype) nilPtr := reflect.Zero(typ) + + // Determine the value kind that results in nil pointer. + nilKind := typeNilKind(etype, ts) + return func(s *Stream, val reflect.Value) (err error) { kind, size, err := s.Kind() if err != nil { @@ -659,6 +630,37 @@ func (s *Stream) Bytes() ([]byte, error) { } } +// ReadBytes decodes the next RLP value and stores the result in b. +// The value size must match len(b) exactly. +func (s *Stream) ReadBytes(b []byte) error { + kind, size, err := s.Kind() + if err != nil { + return err + } + switch kind { + case Byte: + if len(b) != 1 { + return fmt.Errorf("input value has wrong size 1, want %d", len(b)) + } + b[0] = s.byteval + s.kind = -1 // rearm Kind + return nil + case String: + if uint64(len(b)) != size { + return fmt.Errorf("input value has wrong size %d, want %d", size, len(b)) + } + if err = s.readFull(b); err != nil { + return err + } + if size == 1 && b[0] < 128 { + return ErrCanonSize + } + return nil + default: + return ErrExpectedString + } +} + // Raw reads a raw encoded value including RLP type information. func (s *Stream) Raw() ([]byte, error) { kind, size, err := s.Kind() @@ -687,10 +689,31 @@ func (s *Stream) Raw() ([]byte, error) { // Uint reads an RLP string of up to 8 bytes and returns its contents // as an unsigned integer. If the input does not contain an RLP string, the // returned error will be ErrExpectedString. +// +// Deprecated: use s.Uint64 instead. func (s *Stream) Uint() (uint64, error) { return s.uint(64) } +func (s *Stream) Uint64() (uint64, error) { + return s.uint(64) +} + +func (s *Stream) Uint32() (uint32, error) { + i, err := s.uint(32) + return uint32(i), err +} + +func (s *Stream) Uint16() (uint16, error) { + i, err := s.uint(16) + return uint16(i), err +} + +func (s *Stream) Uint8() (uint8, error) { + i, err := s.uint(8) + return uint8(i), err +} + func (s *Stream) uint(maxbits int) (uint64, error) { kind, size, err := s.Kind() if err != nil { @@ -781,6 +804,65 @@ func (s *Stream) ListEnd() error { return nil } +// MoreDataInList reports whether the current list context contains +// more data to be read. +func (s *Stream) MoreDataInList() bool { + _, listLimit := s.listLimit() + return listLimit > 0 +} + +// BigInt decodes an arbitrary-size integer value. +func (s *Stream) BigInt() (*big.Int, error) { + i := new(big.Int) + if err := s.decodeBigInt(i); err != nil { + return nil, err + } + return i, nil +} + +func (s *Stream) decodeBigInt(dst *big.Int) error { + var buffer []byte + kind, size, err := s.Kind() + switch { + case err != nil: + return err + case kind == List: + return ErrExpectedString + case kind == Byte: + buffer = s.uintbuf[:1] + buffer[0] = s.byteval + s.kind = -1 // re-arm Kind + case size == 0: + // Avoid zero-length read. + s.kind = -1 + case size <= uint64(len(s.uintbuf)): + // For integers smaller than s.uintbuf, allocating a buffer + // can be avoided. + buffer = s.uintbuf[:size] + if err := s.readFull(buffer); err != nil { + return err + } + // Reject inputs where single byte encoding should have been used. + if size == 1 && buffer[0] < 128 { + return ErrCanonSize + } + default: + // For large integers, a temporary buffer is needed. + buffer = make([]byte, size) + if err := s.readFull(buffer); err != nil { + return err + } + } + + // Reject leading zero bytes. + if len(buffer) > 0 && buffer[0] == 0 { + return ErrCanonInt + } + // Set the integer bytes. + dst.SetBytes(buffer) + return nil +} + // Decode decodes a value and stores the result in the value pointed // to by val. Please see the documentation for the Decode function // to learn about the decoding rules. diff --git a/rlp/decode_test.go b/rlp/decode_test.go index 7c3dafeac4..babdf3891b 100644 --- a/rlp/decode_test.go +++ b/rlp/decode_test.go @@ -286,6 +286,47 @@ func TestStreamRaw(t *testing.T) { } } +func TestStreamReadBytes(t *testing.T) { + tests := []struct { + input string + size int + err string + }{ + // kind List + {input: "C0", size: 1, err: "rlp: expected String or Byte"}, + // kind Byte + {input: "04", size: 0, err: "input value has wrong size 1, want 0"}, + {input: "04", size: 1}, + {input: "04", size: 2, err: "input value has wrong size 1, want 2"}, + // kind String + {input: "820102", size: 0, err: "input value has wrong size 2, want 0"}, + {input: "820102", size: 1, err: "input value has wrong size 2, want 1"}, + {input: "820102", size: 2}, + {input: "820102", size: 3, err: "input value has wrong size 2, want 3"}, + } + + for _, test := range tests { + test := test + name := fmt.Sprintf("input_%s/size_%d", test.input, test.size) + t.Run(name, func(t *testing.T) { + s := NewStream(bytes.NewReader(unhex(test.input)), 0) + b := make([]byte, test.size) + err := s.ReadBytes(b) + if test.err == "" { + if err != nil { + t.Errorf("unexpected error %q", err) + } + } else { + if err == nil { + t.Errorf("expected error, got nil") + } else if err.Error() != test.err { + t.Errorf("wrong error %q", err) + } + } + }) + } +} + func TestDecodeErrors(t *testing.T) { r := bytes.NewReader(nil) @@ -990,7 +1031,7 @@ func TestInvalidOptionalField(t *testing.T) { v interface{} err string }{ - {v: new(invalid1), err: `rlp: struct field rlp.invalid1.B needs "optional" tag`}, + {v: new(invalid1), err: `rlp: invalid struct tag "" for rlp.invalid1.B (must be optional because preceding field "A" is optional)`}, {v: new(invalid2), err: `rlp: invalid struct tag "optional" for rlp.invalid2.T (also has "tail" tag)`}, {v: new(invalid3), err: `rlp: invalid struct tag "tail" for rlp.invalid3.T (also has "optional" tag)`}, } diff --git a/rlp/encbuffer.go b/rlp/encbuffer.go new file mode 100644 index 0000000000..1a4edc742f --- /dev/null +++ b/rlp/encbuffer.go @@ -0,0 +1,373 @@ +package rlp + +import ( + "io" + "math/big" + "reflect" + "sync" +) + +type encBuffer struct { + str []byte // string data, contains everything except list headers + lheads []listhead // all list headers + lhsize int // sum of sizes of all encoded list headers + sizebuf [9]byte // auxiliary buffer for uint encoding +} + +// The global encBuffer pool. +var encBufferPool = sync.Pool{ + New: func() interface{} { return new(encBuffer) }, +} + +func getEncBuffer() *encBuffer { + buf := encBufferPool.Get().(*encBuffer) + buf.reset() + return buf +} + +func (buf *encBuffer) reset() { + buf.lhsize = 0 + buf.str = buf.str[:0] + buf.lheads = buf.lheads[:0] +} + +// size returns the length of the encoded data. +func (buf *encBuffer) size() int { + return len(buf.str) + buf.lhsize +} + +// makeBytes creates the encoder output. +func (w *encBuffer) makeBytes() []byte { + out := make([]byte, w.size()) + w.copyTo(out) + return out +} + +func (w *encBuffer) copyTo(dst []byte) { + strpos := 0 + pos := 0 + for _, head := range w.lheads { + // write string data before header + n := copy(dst[pos:], w.str[strpos:head.offset]) + pos += n + strpos += n + // write the header + enc := head.encode(dst[pos:]) + pos += len(enc) + } + // copy string data after the last list header + copy(dst[pos:], w.str[strpos:]) +} + +// writeTo writes the encoder output to w. +func (buf *encBuffer) writeTo(w io.Writer) (err error) { + strpos := 0 + for _, head := range buf.lheads { + // write string data before header + if head.offset-strpos > 0 { + n, err := w.Write(buf.str[strpos:head.offset]) + strpos += n + if err != nil { + return err + } + } + // write the header + enc := head.encode(buf.sizebuf[:]) + if _, err = w.Write(enc); err != nil { + return err + } + } + if strpos < len(buf.str) { + // write string data after the last list header + _, err = w.Write(buf.str[strpos:]) + } + return err +} + +// Write implements io.Writer and appends b directly to the output. +func (buf *encBuffer) Write(b []byte) (int, error) { + buf.str = append(buf.str, b...) + return len(b), nil +} + +// writeBool writes b as the integer 0 (false) or 1 (true). +func (buf *encBuffer) writeBool(b bool) { + if b { + buf.str = append(buf.str, 0x01) + } else { + buf.str = append(buf.str, 0x80) + } +} + +func (buf *encBuffer) writeUint64(i uint64) { + if i == 0 { + buf.str = append(buf.str, 0x80) + } else if i < 128 { + // fits single byte + buf.str = append(buf.str, byte(i)) + } else { + s := putint(buf.sizebuf[1:], i) + buf.sizebuf[0] = 0x80 + byte(s) + buf.str = append(buf.str, buf.sizebuf[:s+1]...) + } +} + +func (buf *encBuffer) writeBytes(b []byte) { + if len(b) == 1 && b[0] <= 0x7F { + // fits single byte, no string header + buf.str = append(buf.str, b[0]) + } else { + buf.encodeStringHeader(len(b)) + buf.str = append(buf.str, b...) + } +} + +// wordBytes is the number of bytes in a big.Word +const wordBytes = (32 << (uint64(^big.Word(0)) >> 63)) / 8 + +// writeBigInt writes i as an integer. +func (w *encBuffer) writeBigInt(i *big.Int) { + bitlen := i.BitLen() + if bitlen <= 64 { + w.writeUint64(i.Uint64()) + return + } + // Integer is larger than 64 bits, encode from i.Bits(). + // The minimal byte length is bitlen rounded up to the next + // multiple of 8, divided by 8. + length := ((bitlen + 7) & -8) >> 3 + w.encodeStringHeader(length) + w.str = append(w.str, make([]byte, length)...) + index := length + buf := w.str[len(w.str)-length:] + for _, d := range i.Bits() { + for j := 0; j < wordBytes && index > 0; j++ { + index-- + buf[index] = byte(d) + d >>= 8 + } + } +} + +// list adds a new list header to the header stack. It returns the index of the header. +// Call listEnd with this index after encoding the content of the list. +func (buf *encBuffer) list() int { + buf.lheads = append(buf.lheads, listhead{offset: len(buf.str), size: buf.lhsize}) + return len(buf.lheads) - 1 +} + +func (buf *encBuffer) listEnd(index int) { + lh := &buf.lheads[index] + lh.size = buf.size() - lh.offset - lh.size + if lh.size < 56 { + buf.lhsize++ // length encoded into kind tag + } else { + buf.lhsize += 1 + intsize(uint64(lh.size)) + } +} + +func (buf *encBuffer) encode(val interface{}) error { + rval := reflect.ValueOf(val) + writer, err := cachedWriter(rval.Type()) + if err != nil { + return err + } + return writer(rval, buf) +} + +func (buf *encBuffer) encodeStringHeader(size int) { + if size < 56 { + buf.str = append(buf.str, 0x80+byte(size)) + } else { + sizesize := putint(buf.sizebuf[1:], uint64(size)) + buf.sizebuf[0] = 0xB7 + byte(sizesize) + buf.str = append(buf.str, buf.sizebuf[:sizesize+1]...) + } +} + +// encReader is the io.Reader returned by EncodeToReader. +// It releases its encbuf at EOF. +type encReader struct { + buf *encBuffer // the buffer we're reading from. this is nil when we're at EOF. + lhpos int // index of list header that we're reading + strpos int // current position in string buffer + piece []byte // next piece to be read +} + +func (r *encReader) Read(b []byte) (n int, err error) { + for { + if r.piece = r.next(); r.piece == nil { + // Put the encode buffer back into the pool at EOF when it + // is first encountered. Subsequent calls still return EOF + // as the error but the buffer is no longer valid. + if r.buf != nil { + encBufferPool.Put(r.buf) + r.buf = nil + } + return n, io.EOF + } + nn := copy(b[n:], r.piece) + n += nn + if nn < len(r.piece) { + // piece didn't fit, see you next time. + r.piece = r.piece[nn:] + return n, nil + } + r.piece = nil + } +} + +// next returns the next piece of data to be read. +// it returns nil at EOF. +func (r *encReader) next() []byte { + switch { + case r.buf == nil: + return nil + + case r.piece != nil: + // There is still data available for reading. + return r.piece + + case r.lhpos < len(r.buf.lheads): + // We're before the last list header. + head := r.buf.lheads[r.lhpos] + sizebefore := head.offset - r.strpos + if sizebefore > 0 { + // String data before header. + p := r.buf.str[r.strpos:head.offset] + r.strpos += sizebefore + return p + } + r.lhpos++ + return head.encode(r.buf.sizebuf[:]) + + case r.strpos < len(r.buf.str): + // String data at the end, after all list headers. + p := r.buf.str[r.strpos:] + r.strpos = len(r.buf.str) + return p + + default: + return nil + } +} + +func encBufferFromWriter(w io.Writer) *encBuffer { + switch w := w.(type) { + case EncoderBuffer: + return w.buf + case *EncoderBuffer: + return w.buf + case *encBuffer: + return w + default: + return nil + } +} + +// EncoderBuffer is a buffer for incremental encoding. +// +// The zero value is NOT ready for use. To get a usable buffer, +// create it using NewEncoderBuffer or call Reset. +type EncoderBuffer struct { + buf *encBuffer + dst io.Writer + + ownBuffer bool +} + +// NewEncoderBuffer creates an encoder buffer. +func NewEncoderBuffer(dst io.Writer) EncoderBuffer { + var w EncoderBuffer + w.Reset(dst) + return w +} + +// Reset truncates the buffer and sets the output destination. +func (w *EncoderBuffer) Reset(dst io.Writer) { + if w.buf != nil && !w.ownBuffer { + panic("can't Reset derived EncoderBuffer") + } + + // If the destination writer has an *encBuffer, use it. + // Note that w.ownBuffer is left false here. + if dst != nil { + if outer := encBufferFromWriter(dst); outer != nil { + *w = EncoderBuffer{outer, nil, false} + return + } + } + + // Get a fresh buffer. + if w.buf == nil { + w.buf = encBufferPool.Get().(*encBuffer) + w.ownBuffer = true + } + w.buf.reset() + w.dst = dst +} + +// Flush writes encoded RLP data to the output writer. This can only be called once. +// If you want to re-use the buffer after Flush, you must call Reset. +func (w *EncoderBuffer) Flush() error { + var err error + if w.dst != nil { + err = w.buf.writeTo(w.dst) + } + // Release the internal buffer. + if w.ownBuffer { + encBufferPool.Put(w.buf) + } + *w = EncoderBuffer{} + return err +} + +// ToBytes returns the encoded bytes. +func (w *EncoderBuffer) ToBytes() []byte { + return w.buf.makeBytes() +} + +// AppendToBytes appends the encoded bytes to dst. +func (w *EncoderBuffer) AppendToBytes(dst []byte) []byte { + size := w.buf.size() + out := append(dst, make([]byte, size)...) + w.buf.copyTo(out[len(dst):]) + return out +} + +// Write appends b directly to the encoder output. +func (w EncoderBuffer) Write(b []byte) (int, error) { + return w.buf.Write(b) +} + +// WriteBool writes b as the integer 0 (false) or 1 (true). +func (w EncoderBuffer) WriteBool(b bool) { + w.buf.writeBool(b) +} + +// WriteUint64 encodes an unsigned integer. +func (w EncoderBuffer) WriteUint64(i uint64) { + w.buf.writeUint64(i) +} + +// WriteBigInt encodes a big.Int as an RLP string. +// Note: Unlike with Encode, the sign of i is ignored. +func (w EncoderBuffer) WriteBigInt(i *big.Int) { + w.buf.writeBigInt(i) +} + +// WriteBytes encodes b as an RLP string. +func (w EncoderBuffer) WriteBytes(b []byte) { + w.buf.writeBytes(b) +} + +// List starts a list. It returns an internal index. Call EndList with +// this index after encoding the content to finish the list. +func (w EncoderBuffer) List() int { + return w.buf.list() +} + +// ListEnd finishes the given list. +func (w EncoderBuffer) ListEnd(index int) { + w.buf.listEnd(index) +} diff --git a/rlp/encbuffer_example_test.go b/rlp/encbuffer_example_test.go new file mode 100644 index 0000000000..ee15d82a77 --- /dev/null +++ b/rlp/encbuffer_example_test.go @@ -0,0 +1,45 @@ +// Copyright 2022 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package rlp_test + +import ( + "bytes" + "fmt" + + "github.com/ethereum/go-ethereum/rlp" +) + +func ExampleEncoderBuffer() { + var w bytes.Buffer + + // Encode [4, [5, 6]] to w. + buf := rlp.NewEncoderBuffer(&w) + l1 := buf.List() + buf.WriteUint64(4) + l2 := buf.List() + buf.WriteUint64(5) + buf.WriteUint64(6) + buf.ListEnd(l2) + buf.ListEnd(l1) + + if err := buf.Flush(); err != nil { + panic(err) + } + fmt.Printf("%X\n", w.Bytes()) + // Output: + // C404C20506 +} diff --git a/rlp/encode.go b/rlp/encode.go index 1623e97a3e..b96505f56d 100644 --- a/rlp/encode.go +++ b/rlp/encode.go @@ -17,11 +17,13 @@ package rlp import ( + "errors" "fmt" "io" "math/big" "reflect" - "sync" + + "github.com/ethereum/go-ethereum/rlp/internal/rlpstruct" ) var ( @@ -31,6 +33,8 @@ var ( EmptyList = []byte{0xC0} ) +var ErrNegativeBigInt = errors.New("rlp: cannot encode negative big.Int") + // Encoder is implemented by types that require custom // encoding rules or want to encode private fields. type Encoder interface { @@ -51,30 +55,29 @@ type Encoder interface { // // Please see package-level documentation of encoding rules. func Encode(w io.Writer, val interface{}) error { - if outer, ok := w.(*encbuf); ok { - // Encode was called by some type's EncodeRLP. - // Avoid copying by writing to the outer encbuf directly. - return outer.encode(val) + // Optimization: reuse *encBuffer when called by EncodeRLP. + if buf := encBufferFromWriter(w); buf != nil { + return buf.encode(val) } - eb := encbufPool.Get().(*encbuf) - defer encbufPool.Put(eb) - eb.reset() - if err := eb.encode(val); err != nil { + + buf := getEncBuffer() + defer encBufferPool.Put(buf) + if err := buf.encode(val); err != nil { return err } - return eb.toWriter(w) + return buf.writeTo(w) } // EncodeToBytes returns the RLP encoding of val. // Please see package-level documentation for the encoding rules. func EncodeToBytes(val interface{}) ([]byte, error) { - eb := encbufPool.Get().(*encbuf) - defer encbufPool.Put(eb) - eb.reset() - if err := eb.encode(val); err != nil { + buf := getEncBuffer() + defer encBufferPool.Put(buf) + + if err := buf.encode(val); err != nil { return nil, err } - return eb.toBytes(), nil + return buf.makeBytes(), nil } // EncodeToReader returns a reader from which the RLP encoding of val @@ -83,12 +86,15 @@ func EncodeToBytes(val interface{}) ([]byte, error) { // // Please see the documentation of Encode for the encoding rules. func EncodeToReader(val interface{}) (size int, r io.Reader, err error) { - eb := encbufPool.Get().(*encbuf) - eb.reset() - if err := eb.encode(val); err != nil { + buf := getEncBuffer() + if err := buf.encode(val); err != nil { + encBufferPool.Put(buf) return 0, nil, err } - return eb.size(), &encReader{buf: eb}, nil + // Note: can't put the reader back into the pool here + // because it is held by encReader. The reader puts it + // back when it has been fully consumed. + return buf.size(), &encReader{buf: buf}, nil } type listhead struct { @@ -123,207 +129,10 @@ func puthead(buf []byte, smalltag, largetag byte, size uint64) int { return sizesize + 1 } -type encbuf struct { - str []byte // string data, contains everything except list headers - lheads []listhead // all list headers - lhsize int // sum of sizes of all encoded list headers - sizebuf [9]byte // auxiliary buffer for uint encoding -} - -// encbufs are pooled. -var encbufPool = sync.Pool{ - New: func() interface{} { return new(encbuf) }, -} - -func (w *encbuf) reset() { - w.lhsize = 0 - w.str = w.str[:0] - w.lheads = w.lheads[:0] -} - -// encbuf implements io.Writer so it can be passed it into EncodeRLP. -func (w *encbuf) Write(b []byte) (int, error) { - w.str = append(w.str, b...) - return len(b), nil -} - -func (w *encbuf) encode(val interface{}) error { - rval := reflect.ValueOf(val) - writer, err := cachedWriter(rval.Type()) - if err != nil { - return err - } - return writer(rval, w) -} - -func (w *encbuf) encodeStringHeader(size int) { - if size < 56 { - w.str = append(w.str, 0x80+byte(size)) - } else { - sizesize := putint(w.sizebuf[1:], uint64(size)) - w.sizebuf[0] = 0xB7 + byte(sizesize) - w.str = append(w.str, w.sizebuf[:sizesize+1]...) - } -} - -func (w *encbuf) encodeString(b []byte) { - if len(b) == 1 && b[0] <= 0x7F { - // fits single byte, no string header - w.str = append(w.str, b[0]) - } else { - w.encodeStringHeader(len(b)) - w.str = append(w.str, b...) - } -} - -func (w *encbuf) encodeUint(i uint64) { - if i == 0 { - w.str = append(w.str, 0x80) - } else if i < 128 { - // fits single byte - w.str = append(w.str, byte(i)) - } else { - s := putint(w.sizebuf[1:], i) - w.sizebuf[0] = 0x80 + byte(s) - w.str = append(w.str, w.sizebuf[:s+1]...) - } -} - -// list adds a new list header to the header stack. It returns the index -// of the header. The caller must call listEnd with this index after encoding -// the content of the list. -func (w *encbuf) list() int { - w.lheads = append(w.lheads, listhead{offset: len(w.str), size: w.lhsize}) - return len(w.lheads) - 1 -} - -func (w *encbuf) listEnd(index int) { - lh := &w.lheads[index] - lh.size = w.size() - lh.offset - lh.size - if lh.size < 56 { - w.lhsize++ // length encoded into kind tag - } else { - w.lhsize += 1 + intsize(uint64(lh.size)) - } -} - -func (w *encbuf) size() int { - return len(w.str) + w.lhsize -} - -func (w *encbuf) toBytes() []byte { - out := make([]byte, w.size()) - strpos := 0 - pos := 0 - for _, head := range w.lheads { - // write string data before header - n := copy(out[pos:], w.str[strpos:head.offset]) - pos += n - strpos += n - // write the header - enc := head.encode(out[pos:]) - pos += len(enc) - } - // copy string data after the last list header - copy(out[pos:], w.str[strpos:]) - return out -} - -func (w *encbuf) toWriter(out io.Writer) (err error) { - strpos := 0 - for _, head := range w.lheads { - // write string data before header - if head.offset-strpos > 0 { - n, err := out.Write(w.str[strpos:head.offset]) - strpos += n - if err != nil { - return err - } - } - // write the header - enc := head.encode(w.sizebuf[:]) - if _, err = out.Write(enc); err != nil { - return err - } - } - if strpos < len(w.str) { - // write string data after the last list header - _, err = out.Write(w.str[strpos:]) - } - return err -} - -// encReader is the io.Reader returned by EncodeToReader. -// It releases its encbuf at EOF. -type encReader struct { - buf *encbuf // the buffer we're reading from. this is nil when we're at EOF. - lhpos int // index of list header that we're reading - strpos int // current position in string buffer - piece []byte // next piece to be read -} - -func (r *encReader) Read(b []byte) (n int, err error) { - for { - if r.piece = r.next(); r.piece == nil { - // Put the encode buffer back into the pool at EOF when it - // is first encountered. Subsequent calls still return EOF - // as the error but the buffer is no longer valid. - if r.buf != nil { - encbufPool.Put(r.buf) - r.buf = nil - } - return n, io.EOF - } - nn := copy(b[n:], r.piece) - n += nn - if nn < len(r.piece) { - // piece didn't fit, see you next time. - r.piece = r.piece[nn:] - return n, nil - } - r.piece = nil - } -} - -// next returns the next piece of data to be read. -// it returns nil at EOF. -func (r *encReader) next() []byte { - switch { - case r.buf == nil: - return nil - - case r.piece != nil: - // There is still data available for reading. - return r.piece - - case r.lhpos < len(r.buf.lheads): - // We're before the last list header. - head := r.buf.lheads[r.lhpos] - sizebefore := head.offset - r.strpos - if sizebefore > 0 { - // String data before header. - p := r.buf.str[r.strpos:head.offset] - r.strpos += sizebefore - return p - } - r.lhpos++ - return head.encode(r.buf.sizebuf[:]) - - case r.strpos < len(r.buf.str): - // String data at the end, after all list headers. - p := r.buf.str[r.strpos:] - r.strpos = len(r.buf.str) - return p - - default: - return nil - } -} - var encoderInterface = reflect.TypeOf(new(Encoder)).Elem() // makeWriter creates a writer function for the given type. -func makeWriter(typ reflect.Type, ts tags) (writer, error) { +func makeWriter(typ reflect.Type, ts rlpstruct.Tags) (writer, error) { kind := typ.Kind() switch { case typ == rawValueType: @@ -357,71 +166,45 @@ func makeWriter(typ reflect.Type, ts tags) (writer, error) { } } -func writeRawValue(val reflect.Value, w *encbuf) error { +func writeRawValue(val reflect.Value, w *encBuffer) error { w.str = append(w.str, val.Bytes()...) return nil } -func writeUint(val reflect.Value, w *encbuf) error { - w.encodeUint(val.Uint()) +func writeUint(val reflect.Value, w *encBuffer) error { + w.writeUint64(val.Uint()) return nil } -func writeBool(val reflect.Value, w *encbuf) error { - if val.Bool() { - w.str = append(w.str, 0x01) - } else { - w.str = append(w.str, 0x80) - } +func writeBool(val reflect.Value, w *encBuffer) error { + w.writeBool(val.Bool()) return nil } -func writeBigIntPtr(val reflect.Value, w *encbuf) error { +func writeBigIntPtr(val reflect.Value, w *encBuffer) error { ptr := val.Interface().(*big.Int) if ptr == nil { w.str = append(w.str, 0x80) return nil } - return writeBigInt(ptr, w) + if ptr.Sign() == -1 { + return ErrNegativeBigInt + } + w.writeBigInt(ptr) + return nil } -func writeBigIntNoPtr(val reflect.Value, w *encbuf) error { +func writeBigIntNoPtr(val reflect.Value, w *encBuffer) error { i := val.Interface().(big.Int) - return writeBigInt(&i, w) -} - -// wordBytes is the number of bytes in a big.Word -const wordBytes = (32 << (uint64(^big.Word(0)) >> 63)) / 8 - -func writeBigInt(i *big.Int, w *encbuf) error { if i.Sign() == -1 { - return fmt.Errorf("rlp: cannot encode negative *big.Int") - } - bitlen := i.BitLen() - if bitlen <= 64 { - w.encodeUint(i.Uint64()) - return nil - } - // Integer is larger than 64 bits, encode from i.Bits(). - // The minimal byte length is bitlen rounded up to the next - // multiple of 8, divided by 8. - length := ((bitlen + 7) & -8) >> 3 - w.encodeStringHeader(length) - w.str = append(w.str, make([]byte, length)...) - index := length - buf := w.str[len(w.str)-length:] - for _, d := range i.Bits() { - for j := 0; j < wordBytes && index > 0; j++ { - index-- - buf[index] = byte(d) - d >>= 8 - } + return ErrNegativeBigInt } + w.writeBigInt(&i) return nil } -func writeBytes(val reflect.Value, w *encbuf) error { - w.encodeString(val.Bytes()) +func writeBytes(val reflect.Value, w *encBuffer) error { + w.writeBytes(val.Bytes()) return nil } @@ -433,7 +216,7 @@ func makeByteArrayWriter(typ reflect.Type) writer { return writeLengthOneByteArray default: length := typ.Len() - return func(val reflect.Value, w *encbuf) error { + return func(val reflect.Value, w *encBuffer) error { if !val.CanAddr() { // Getting the byte slice of val requires it to be addressable. Make it // addressable by copying. @@ -449,12 +232,12 @@ func makeByteArrayWriter(typ reflect.Type) writer { } } -func writeLengthZeroByteArray(val reflect.Value, w *encbuf) error { +func writeLengthZeroByteArray(val reflect.Value, w *encBuffer) error { w.str = append(w.str, 0x80) return nil } -func writeLengthOneByteArray(val reflect.Value, w *encbuf) error { +func writeLengthOneByteArray(val reflect.Value, w *encBuffer) error { b := byte(val.Index(0).Uint()) if b <= 0x7f { w.str = append(w.str, b) @@ -464,7 +247,7 @@ func writeLengthOneByteArray(val reflect.Value, w *encbuf) error { return nil } -func writeString(val reflect.Value, w *encbuf) error { +func writeString(val reflect.Value, w *encBuffer) error { s := val.String() if len(s) == 1 && s[0] <= 0x7f { // fits single byte, no string header @@ -476,7 +259,7 @@ func writeString(val reflect.Value, w *encbuf) error { return nil } -func writeInterface(val reflect.Value, w *encbuf) error { +func writeInterface(val reflect.Value, w *encBuffer) error { if val.IsNil() { // Write empty list. This is consistent with the previous RLP // encoder that we had and should therefore avoid any @@ -492,17 +275,17 @@ func writeInterface(val reflect.Value, w *encbuf) error { return writer(eval, w) } -func makeSliceWriter(typ reflect.Type, ts tags) (writer, error) { - etypeinfo := theTC.infoWhileGenerating(typ.Elem(), tags{}) +func makeSliceWriter(typ reflect.Type, ts rlpstruct.Tags) (writer, error) { + etypeinfo := theTC.infoWhileGenerating(typ.Elem(), rlpstruct.Tags{}) if etypeinfo.writerErr != nil { return nil, etypeinfo.writerErr } var wfn writer - if ts.tail { + if ts.Tail { // This is for struct tail slices. // w.list is not called for them. - wfn = func(val reflect.Value, w *encbuf) error { + wfn = func(val reflect.Value, w *encBuffer) error { vlen := val.Len() for i := 0; i < vlen; i++ { if err := etypeinfo.writer(val.Index(i), w); err != nil { @@ -513,7 +296,7 @@ func makeSliceWriter(typ reflect.Type, ts tags) (writer, error) { } } else { // This is for regular slices and arrays. - wfn = func(val reflect.Value, w *encbuf) error { + wfn = func(val reflect.Value, w *encBuffer) error { vlen := val.Len() if vlen == 0 { w.str = append(w.str, 0xC0) @@ -547,7 +330,7 @@ func makeStructWriter(typ reflect.Type) (writer, error) { firstOptionalField := firstOptionalField(fields) if firstOptionalField == len(fields) { // This is the writer function for structs without any optional fields. - writer = func(val reflect.Value, w *encbuf) error { + writer = func(val reflect.Value, w *encBuffer) error { lh := w.list() for _, f := range fields { if err := f.info.writer(val.Field(f.index), w); err != nil { @@ -560,7 +343,7 @@ func makeStructWriter(typ reflect.Type) (writer, error) { } else { // If there are any "optional" fields, the writer needs to perform additional // checks to determine the output list length. - writer = func(val reflect.Value, w *encbuf) error { + writer = func(val reflect.Value, w *encBuffer) error { lastField := len(fields) - 1 for ; lastField >= firstOptionalField; lastField-- { if !val.Field(fields[lastField].index).IsZero() { @@ -580,33 +363,18 @@ func makeStructWriter(typ reflect.Type) (writer, error) { return writer, nil } -// nilEncoding returns the encoded value of a nil pointer. -func nilEncoding(typ reflect.Type, ts tags) uint8 { - var nilKind Kind - if ts.nilOK { - nilKind = ts.nilKind // use struct tag if provided - } else { - nilKind = defaultNilKind(typ.Elem()) +func makePtrWriter(typ reflect.Type, ts rlpstruct.Tags) (writer, error) { + nilEncoding := byte(0xC0) + if typeNilKind(typ.Elem(), ts) == String { + nilEncoding = 0x80 } - switch nilKind { - case String: - return 0x80 - case List: - return 0xC0 - default: - panic(fmt.Errorf("rlp: invalid nil kind %d", nilKind)) - } -} - -func makePtrWriter(typ reflect.Type, ts tags) (writer, error) { - etypeinfo := theTC.infoWhileGenerating(typ.Elem(), tags{}) + etypeinfo := theTC.infoWhileGenerating(typ.Elem(), rlpstruct.Tags{}) if etypeinfo.writerErr != nil { return nil, etypeinfo.writerErr } - nilEncoding := nilEncoding(typ, ts) - writer := func(val reflect.Value, w *encbuf) error { + writer := func(val reflect.Value, w *encBuffer) error { if ev := val.Elem(); ev.IsValid() { return etypeinfo.writer(ev, w) } @@ -618,11 +386,11 @@ func makePtrWriter(typ reflect.Type, ts tags) (writer, error) { func makeEncoderWriter(typ reflect.Type) writer { if typ.Implements(encoderInterface) { - return func(val reflect.Value, w *encbuf) error { + return func(val reflect.Value, w *encBuffer) error { return val.Interface().(Encoder).EncodeRLP(w) } } - w := func(val reflect.Value, w *encbuf) error { + w := func(val reflect.Value, w *encBuffer) error { if !val.CanAddr() { // package json simply doesn't call MarshalJSON for this case, but encodes the // value as if it didn't implement the interface. We don't want to handle it that diff --git a/rlp/encode_test.go b/rlp/encode_test.go index a63743440d..1d715e3776 100644 --- a/rlp/encode_test.go +++ b/rlp/encode_test.go @@ -145,7 +145,8 @@ var encTests = []encTest{ {val: *big.NewInt(0xFFFFFF), output: "83FFFFFF"}, // negative ints are not supported - {val: big.NewInt(-1), error: "rlp: cannot encode negative *big.Int"}, + {val: big.NewInt(-1), error: "rlp: cannot encode negative big.Int"}, + {val: *big.NewInt(-1), error: "rlp: cannot encode negative big.Int"}, // byte arrays {val: [0]byte{}, output: "80"}, @@ -398,6 +399,21 @@ func TestEncodeToBytes(t *testing.T) { runEncTests(t, EncodeToBytes) } +func TestEncodeAppendToBytes(t *testing.T) { + buffer := make([]byte, 20) + runEncTests(t, func(val interface{}) ([]byte, error) { + w := NewEncoderBuffer(nil) + defer w.Flush() + + err := Encode(w, val) + if err != nil { + return nil, err + } + output := w.AppendToBytes(buffer[:0]) + return output, nil + }) +} + func TestEncodeToReader(t *testing.T) { runEncTests(t, func(val interface{}) ([]byte, error) { _, r, err := EncodeToReader(val) diff --git a/rlp/encoder_example_test.go b/rlp/encoder_example_test.go index 42c1c5c890..4cd3cb8673 100644 --- a/rlp/encoder_example_test.go +++ b/rlp/encoder_example_test.go @@ -14,11 +14,13 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package rlp +package rlp_test import ( "fmt" "io" + + "github.com/ethereum/go-ethereum/rlp" ) type MyCoolType struct { @@ -28,16 +30,16 @@ type MyCoolType struct { // EncodeRLP writes x as RLP list [a, b] that omits the Name field. func (x *MyCoolType) EncodeRLP(w io.Writer) (err error) { - return Encode(w, []uint{x.a, x.b}) + return rlp.Encode(w, []uint{x.a, x.b}) } func ExampleEncoder() { var t *MyCoolType // t is nil pointer to MyCoolType - bytes, _ := EncodeToBytes(t) + bytes, _ := rlp.EncodeToBytes(t) fmt.Printf("%v → %X\n", t, bytes) t = &MyCoolType{Name: "foobar", a: 5, b: 6} - bytes, _ = EncodeToBytes(t) + bytes, _ = rlp.EncodeToBytes(t) fmt.Printf("%v → %X\n", t, bytes) // Output: diff --git a/rlp/internal/rlpstruct/rlpstruct.go b/rlp/internal/rlpstruct/rlpstruct.go new file mode 100644 index 0000000000..1ebaa960e3 --- /dev/null +++ b/rlp/internal/rlpstruct/rlpstruct.go @@ -0,0 +1,213 @@ +// Copyright 2021 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Package rlpstruct implements struct processing for RLP encoding/decoding. +// +// In particular, this package handles all rules around field filtering, +// struct tags and nil value determination. +package rlpstruct + +import ( + "fmt" + "reflect" + "strings" +) + +// Field represents a struct field. +type Field struct { + Name string + Index int + Exported bool + Type Type + Tag string +} + +// Type represents the attributes of a Go type. +type Type struct { + Name string + Kind reflect.Kind + IsEncoder bool // whether type implements rlp.Encoder + IsDecoder bool // whether type implements rlp.Decoder + Elem *Type // non-nil for Kind values of Ptr, Slice, Array +} + +// defaultNilValue determines whether a nil pointer to t encodes/decodes +// as an empty string or empty list. +func (t Type) DefaultNilValue() NilKind { + k := t.Kind + if isUint(k) || k == reflect.String || k == reflect.Bool || isByteArray(t) { + return NilKindString + } + return NilKindList +} + +// NilKind is the RLP value encoded in place of nil pointers. +type NilKind uint8 + +const ( + NilKindString NilKind = 0x80 + NilKindList NilKind = 0xC0 +) + +// Tags represents struct tags. +type Tags struct { + // rlp:"nil" controls whether empty input results in a nil pointer. + // nilKind is the kind of empty value allowed for the field. + NilKind NilKind + NilOK bool + + // rlp:"optional" allows for a field to be missing in the input list. + // If this is set, all subsequent fields must also be optional. + Optional bool + + // rlp:"tail" controls whether this field swallows additional list elements. It can + // only be set for the last field, which must be of slice type. + Tail bool + + // rlp:"-" ignores fields. + Ignored bool +} + +// TagError is raised for invalid struct tags. +type TagError struct { + StructType string + + // These are set by this package. + Field string + Tag string + Err string +} + +func (e TagError) Error() string { + field := "field " + e.Field + if e.StructType != "" { + field = e.StructType + "." + e.Field + } + return fmt.Sprintf("rlp: invalid struct tag %q for %s (%s)", e.Tag, field, e.Err) +} + +// ProcessFields filters the given struct fields, returning only fields +// that should be considered for encoding/decoding. +func ProcessFields(allFields []Field) ([]Field, []Tags, error) { + lastPublic := lastPublicField(allFields) + + // Gather all exported fields and their tags. + var fields []Field + var tags []Tags + for _, field := range allFields { + if !field.Exported { + continue + } + ts, err := parseTag(field, lastPublic) + if err != nil { + return nil, nil, err + } + if ts.Ignored { + continue + } + fields = append(fields, field) + tags = append(tags, ts) + } + + // Verify optional field consistency. If any optional field exists, + // all fields after it must also be optional. Note: optional + tail + // is supported. + var anyOptional bool + var firstOptionalName string + for i, ts := range tags { + name := fields[i].Name + if ts.Optional || ts.Tail { + if !anyOptional { + firstOptionalName = name + } + anyOptional = true + } else { + if anyOptional { + msg := fmt.Sprintf("must be optional because preceding field %q is optional", firstOptionalName) + return nil, nil, TagError{Field: name, Err: msg} + } + } + } + return fields, tags, nil +} + +func parseTag(field Field, lastPublic int) (Tags, error) { + name := field.Name + tag := reflect.StructTag(field.Tag) + var ts Tags + for _, t := range strings.Split(tag.Get("rlp"), ",") { + switch t = strings.TrimSpace(t); t { + case "": + // empty tag is allowed for some reason + case "-": + ts.Ignored = true + case "nil", "nilString", "nilList": + ts.NilOK = true + if field.Type.Kind != reflect.Ptr { + return ts, TagError{Field: name, Tag: t, Err: "field is not a pointer"} + } + switch t { + case "nil": + ts.NilKind = field.Type.Elem.DefaultNilValue() + case "nilString": + ts.NilKind = NilKindString + case "nilList": + ts.NilKind = NilKindList + } + case "optional": + ts.Optional = true + if ts.Tail { + return ts, TagError{Field: name, Tag: t, Err: `also has "tail" tag`} + } + case "tail": + ts.Tail = true + if field.Index != lastPublic { + return ts, TagError{Field: name, Tag: t, Err: "must be on last field"} + } + if ts.Optional { + return ts, TagError{Field: name, Tag: t, Err: `also has "optional" tag`} + } + if field.Type.Kind != reflect.Slice { + return ts, TagError{Field: name, Tag: t, Err: "field type is not slice"} + } + default: + return ts, TagError{Field: name, Tag: t, Err: "unknown tag"} + } + } + return ts, nil +} + +func lastPublicField(fields []Field) int { + last := 0 + for _, f := range fields { + if f.Exported { + last = f.Index + } + } + return last +} + +func isUint(k reflect.Kind) bool { + return k >= reflect.Uint && k <= reflect.Uintptr +} + +func isByte(typ Type) bool { + return typ.Kind == reflect.Uint8 && !typ.IsEncoder +} + +func isByteArray(typ Type) bool { + return (typ.Kind == reflect.Slice || typ.Kind == reflect.Array) && isByte(*typ.Elem) +} diff --git a/rlp/rlpgen/gen.go b/rlp/rlpgen/gen.go new file mode 100644 index 0000000000..b36b269478 --- /dev/null +++ b/rlp/rlpgen/gen.go @@ -0,0 +1,735 @@ +package main + +import ( + "bytes" + "fmt" + "go/format" + "go/types" + "sort" + + "github.com/ethereum/go-ethereum/rlp/internal/rlpstruct" +) + +// buildContext keeps the data needed for make*Op. +type buildContext struct { + topType *types.Named // the type we're creating methods for + + encoderIface *types.Interface + decoderIface *types.Interface + rawValueType *types.Named + + typeToStructCache map[types.Type]*rlpstruct.Type +} + +func newBuildContext(packageRLP *types.Package) *buildContext { + enc := packageRLP.Scope().Lookup("Encoder").Type().Underlying() + dec := packageRLP.Scope().Lookup("Decoder").Type().Underlying() + rawv := packageRLP.Scope().Lookup("RawValue").Type() + return &buildContext{ + typeToStructCache: make(map[types.Type]*rlpstruct.Type), + encoderIface: enc.(*types.Interface), + decoderIface: dec.(*types.Interface), + rawValueType: rawv.(*types.Named), + } +} + +func (bctx *buildContext) isEncoder(typ types.Type) bool { + return types.Implements(typ, bctx.encoderIface) +} + +func (bctx *buildContext) isDecoder(typ types.Type) bool { + return types.Implements(typ, bctx.decoderIface) +} + +// typeToStructType converts typ to rlpstruct.Type. +func (bctx *buildContext) typeToStructType(typ types.Type) *rlpstruct.Type { + if prev := bctx.typeToStructCache[typ]; prev != nil { + return prev // short-circuit for recursive types. + } + + // Resolve named types to their underlying type, but keep the name. + name := types.TypeString(typ, nil) + for { + utype := typ.Underlying() + if utype == typ { + break + } + typ = utype + } + + // Create the type and store it in cache. + t := &rlpstruct.Type{ + Name: name, + Kind: typeReflectKind(typ), + IsEncoder: bctx.isEncoder(typ), + IsDecoder: bctx.isDecoder(typ), + } + bctx.typeToStructCache[typ] = t + + // Assign element type. + switch typ.(type) { + case *types.Array, *types.Slice, *types.Pointer: + etype := typ.(interface{ Elem() types.Type }).Elem() + t.Elem = bctx.typeToStructType(etype) + } + return t +} + +// genContext is passed to the gen* methods of op when generating +// the output code. It tracks packages to be imported by the output +// file and assigns unique names of temporary variables. +type genContext struct { + inPackage *types.Package + imports map[string]struct{} + tempCounter int +} + +func newGenContext(inPackage *types.Package) *genContext { + return &genContext{ + inPackage: inPackage, + imports: make(map[string]struct{}), + } +} + +func (ctx *genContext) temp() string { + v := fmt.Sprintf("_tmp%d", ctx.tempCounter) + ctx.tempCounter++ + return v +} + +func (ctx *genContext) resetTemp() { + ctx.tempCounter = 0 +} + +func (ctx *genContext) addImport(path string) { + if path == ctx.inPackage.Path() { + return // avoid importing the package that we're generating in. + } + // TODO: renaming? + ctx.imports[path] = struct{}{} +} + +// importsList returns all packages that need to be imported. +func (ctx *genContext) importsList() []string { + imp := make([]string, 0, len(ctx.imports)) + for k := range ctx.imports { + imp = append(imp, k) + } + sort.Strings(imp) + return imp +} + +// qualify is the types.Qualifier used for printing types. +func (ctx *genContext) qualify(pkg *types.Package) string { + if pkg.Path() == ctx.inPackage.Path() { + return "" + } + ctx.addImport(pkg.Path()) + // TODO: renaming? + return pkg.Name() +} + +type op interface { + // genWrite creates the encoder. The generated code should write v, + // which is any Go expression, to the rlp.EncoderBuffer 'w'. + genWrite(ctx *genContext, v string) string + + // genDecode creates the decoder. The generated code should read + // a value from the rlp.Stream 'dec' and store it to dst. + genDecode(ctx *genContext) (string, string) +} + +// basicOp handles basic types bool, uint*, string. +type basicOp struct { + typ types.Type + writeMethod string // calle write the value + writeArgType types.Type // parameter type of writeMethod + decMethod string + decResultType types.Type // return type of decMethod + decUseBitSize bool // if true, result bit size is appended to decMethod +} + +func (*buildContext) makeBasicOp(typ *types.Basic) (op, error) { + op := basicOp{typ: typ} + kind := typ.Kind() + switch { + case kind == types.Bool: + op.writeMethod = "WriteBool" + op.writeArgType = types.Typ[types.Bool] + op.decMethod = "Bool" + op.decResultType = types.Typ[types.Bool] + case kind >= types.Uint8 && kind <= types.Uint64: + op.writeMethod = "WriteUint64" + op.writeArgType = types.Typ[types.Uint64] + op.decMethod = "Uint" + op.decResultType = typ + op.decUseBitSize = true + case kind == types.String: + op.writeMethod = "WriteString" + op.writeArgType = types.Typ[types.String] + op.decMethod = "String" + op.decResultType = types.Typ[types.String] + default: + return nil, fmt.Errorf("unhandled basic type: %v", typ) + } + return op, nil +} + +func (*buildContext) makeByteSliceOp(typ *types.Slice) op { + if !isByte(typ.Elem()) { + panic("non-byte slice type in makeByteSliceOp") + } + bslice := types.NewSlice(types.Typ[types.Uint8]) + return basicOp{ + typ: typ, + writeMethod: "WriteBytes", + writeArgType: bslice, + decMethod: "Bytes", + decResultType: bslice, + } +} + +func (bctx *buildContext) makeRawValueOp() op { + bslice := types.NewSlice(types.Typ[types.Uint8]) + return basicOp{ + typ: bctx.rawValueType, + writeMethod: "Write", + writeArgType: bslice, + decMethod: "Raw", + decResultType: bslice, + } +} + +func (op basicOp) writeNeedsConversion() bool { + return !types.AssignableTo(op.typ, op.writeArgType) +} + +func (op basicOp) decodeNeedsConversion() bool { + return !types.AssignableTo(op.decResultType, op.typ) +} + +func (op basicOp) genWrite(ctx *genContext, v string) string { + if op.writeNeedsConversion() { + v = fmt.Sprintf("%s(%s)", op.writeArgType, v) + } + return fmt.Sprintf("w.%s(%s)\n", op.writeMethod, v) +} + +func (op basicOp) genDecode(ctx *genContext) (string, string) { + var ( + resultV = ctx.temp() + result = resultV + method = op.decMethod + ) + if op.decUseBitSize { + // Note: For now, this only works for platform-independent integer + // sizes. makeBasicOp forbids the platform-dependent types. + var sizes types.StdSizes + method = fmt.Sprintf("%s%d", op.decMethod, sizes.Sizeof(op.typ)*8) + } + + // Call the decoder method. + var b bytes.Buffer + fmt.Fprintf(&b, "%s, err := dec.%s()\n", resultV, method) + fmt.Fprintf(&b, "if err != nil { return err }\n") + if op.decodeNeedsConversion() { + conv := ctx.temp() + fmt.Fprintf(&b, "%s := %s(%s)\n", conv, types.TypeString(op.typ, ctx.qualify), resultV) + result = conv + } + return result, b.String() +} + +// byteArrayOp handles [...]byte. +type byteArrayOp struct { + typ types.Type + name types.Type // name != typ for named byte array types (e.g. common.Address) +} + +func (bctx *buildContext) makeByteArrayOp(name *types.Named, typ *types.Array) byteArrayOp { + nt := types.Type(name) + if name == nil { + nt = typ + } + return byteArrayOp{typ, nt} +} + +func (op byteArrayOp) genWrite(ctx *genContext, v string) string { + return fmt.Sprintf("w.WriteBytes(%s[:])\n", v) +} + +func (op byteArrayOp) genDecode(ctx *genContext) (string, string) { + var resultV = ctx.temp() + + var b bytes.Buffer + fmt.Fprintf(&b, "var %s %s\n", resultV, types.TypeString(op.name, ctx.qualify)) + fmt.Fprintf(&b, "if err := dec.ReadBytes(%s[:]); err != nil { return err }\n", resultV) + return resultV, b.String() +} + +// bigIntNoPtrOp handles non-pointer big.Int. +// This exists because big.Int has it's own decoder operation on rlp.Stream, +// but the decode method returns *big.Int, so it needs to be dereferenced. +type bigIntOp struct { + pointer bool +} + +func (op bigIntOp) genWrite(ctx *genContext, v string) string { + var b bytes.Buffer + + fmt.Fprintf(&b, "if %s.Sign() == -1 {\n", v) + fmt.Fprintf(&b, " return rlp.ErrNegativeBigInt\n") + fmt.Fprintf(&b, "}\n") + dst := v + if !op.pointer { + dst = "&" + v + } + fmt.Fprintf(&b, "w.WriteBigInt(%s)\n", dst) + + // Wrap with nil check. + if op.pointer { + code := b.String() + b.Reset() + fmt.Fprintf(&b, "if %s == nil {\n", v) + fmt.Fprintf(&b, " w.Write(rlp.EmptyString)") + fmt.Fprintf(&b, "} else {\n") + fmt.Fprint(&b, code) + fmt.Fprintf(&b, "}\n") + } + + return b.String() +} + +func (op bigIntOp) genDecode(ctx *genContext) (string, string) { + var resultV = ctx.temp() + + var b bytes.Buffer + fmt.Fprintf(&b, "%s, err := dec.BigInt()\n", resultV) + fmt.Fprintf(&b, "if err != nil { return err }\n") + + result := resultV + if !op.pointer { + result = "(*" + resultV + ")" + } + return result, b.String() +} + +// encoderDecoderOp handles rlp.Encoder and rlp.Decoder. +// In order to be used with this, the type must implement both interfaces. +// This restriction may be lifted in the future by creating separate ops for +// encoding and decoding. +type encoderDecoderOp struct { + typ types.Type +} + +func (op encoderDecoderOp) genWrite(ctx *genContext, v string) string { + return fmt.Sprintf("if err := %s.EncodeRLP(w); err != nil { return err }\n", v) +} + +func (op encoderDecoderOp) genDecode(ctx *genContext) (string, string) { + // DecodeRLP must have pointer receiver, and this is verified in makeOp. + etyp := op.typ.(*types.Pointer).Elem() + var resultV = ctx.temp() + + var b bytes.Buffer + fmt.Fprintf(&b, "%s := new(%s)\n", resultV, types.TypeString(etyp, ctx.qualify)) + fmt.Fprintf(&b, "if err := %s.DecodeRLP(dec); err != nil { return err }\n", resultV) + return resultV, b.String() +} + +// ptrOp handles pointer types. +type ptrOp struct { + elemTyp types.Type + elem op + nilOK bool + nilValue rlpstruct.NilKind +} + +func (bctx *buildContext) makePtrOp(elemTyp types.Type, tags rlpstruct.Tags) (op, error) { + elemOp, err := bctx.makeOp(nil, elemTyp, rlpstruct.Tags{}) + if err != nil { + return nil, err + } + op := ptrOp{elemTyp: elemTyp, elem: elemOp} + + // Determine nil value. + if tags.NilOK { + op.nilOK = true + op.nilValue = tags.NilKind + } else { + styp := bctx.typeToStructType(elemTyp) + op.nilValue = styp.DefaultNilValue() + } + return op, nil +} + +func (op ptrOp) genWrite(ctx *genContext, v string) string { + // Note: in writer functions, accesses to v are read-only, i.e. v is any Go + // expression. To make all accesses work through the pointer, we substitute + // v with (*v). This is required for most accesses including `v`, `call(v)`, + // and `v[index]` on slices. + // + // For `v.field` and `v[:]` on arrays, the dereference operation is not required. + var vv string + _, isStruct := op.elem.(structOp) + _, isByteArray := op.elem.(byteArrayOp) + if isStruct || isByteArray { + vv = v + } else { + vv = fmt.Sprintf("(*%s)", v) + } + + var b bytes.Buffer + fmt.Fprintf(&b, "if %s == nil {\n", v) + fmt.Fprintf(&b, " w.Write([]byte{0x%X})\n", op.nilValue) + fmt.Fprintf(&b, "} else {\n") + fmt.Fprintf(&b, " %s", op.elem.genWrite(ctx, vv)) + fmt.Fprintf(&b, "}\n") + return b.String() +} + +func (op ptrOp) genDecode(ctx *genContext) (string, string) { + result, code := op.elem.genDecode(ctx) + if !op.nilOK { + // If nil pointers are not allowed, we can just decode the element. + return "&" + result, code + } + + // nil is allowed, so check the kind and size first. + // If size is zero and kind matches the nilKind of the type, + // the value decodes as a nil pointer. + var ( + resultV = ctx.temp() + kindV = ctx.temp() + sizeV = ctx.temp() + wantKind string + ) + if op.nilValue == rlpstruct.NilKindList { + wantKind = "rlp.List" + } else { + wantKind = "rlp.String" + } + var b bytes.Buffer + fmt.Fprintf(&b, "var %s %s\n", resultV, types.TypeString(types.NewPointer(op.elemTyp), ctx.qualify)) + fmt.Fprintf(&b, "if %s, %s, err := dec.Kind(); err != nil {\n", kindV, sizeV) + fmt.Fprintf(&b, " return err\n") + fmt.Fprintf(&b, "} else if %s != 0 || %s != %s {\n", sizeV, kindV, wantKind) + fmt.Fprint(&b, code) + fmt.Fprintf(&b, " %s = &%s\n", resultV, result) + fmt.Fprintf(&b, "}\n") + return resultV, b.String() +} + +// structOp handles struct types. +type structOp struct { + named *types.Named + typ *types.Struct + fields []*structField + optionalFields []*structField +} + +type structField struct { + name string + typ types.Type + elem op +} + +func (bctx *buildContext) makeStructOp(named *types.Named, typ *types.Struct) (op, error) { + // Convert fields to []rlpstruct.Field. + var allStructFields []rlpstruct.Field + for i := 0; i < typ.NumFields(); i++ { + f := typ.Field(i) + allStructFields = append(allStructFields, rlpstruct.Field{ + Name: f.Name(), + Exported: f.Exported(), + Index: i, + Tag: typ.Tag(i), + Type: *bctx.typeToStructType(f.Type()), + }) + } + + // Filter/validate fields. + fields, tags, err := rlpstruct.ProcessFields(allStructFields) + if err != nil { + return nil, err + } + + // Create field ops. + var op = structOp{named: named, typ: typ} + for i, field := range fields { + // Advanced struct tags are not supported yet. + tag := tags[i] + if err := checkUnsupportedTags(field.Name, tag); err != nil { + return nil, err + } + typ := typ.Field(field.Index).Type() + elem, err := bctx.makeOp(nil, typ, tags[i]) + if err != nil { + return nil, fmt.Errorf("field %s: %v", field.Name, err) + } + f := &structField{name: field.Name, typ: typ, elem: elem} + if tag.Optional { + op.optionalFields = append(op.optionalFields, f) + } else { + op.fields = append(op.fields, f) + } + } + return op, nil +} + +func checkUnsupportedTags(field string, tag rlpstruct.Tags) error { + if tag.Tail { + return fmt.Errorf(`field %s has unsupported struct tag "tail"`, field) + } + return nil +} + +func (op structOp) genWrite(ctx *genContext, v string) string { + var b bytes.Buffer + var listMarker = ctx.temp() + fmt.Fprintf(&b, "%s := w.List()\n", listMarker) + for _, field := range op.fields { + selector := v + "." + field.name + fmt.Fprint(&b, field.elem.genWrite(ctx, selector)) + } + op.writeOptionalFields(&b, ctx, v) + fmt.Fprintf(&b, "w.ListEnd(%s)\n", listMarker) + return b.String() +} + +func (op structOp) writeOptionalFields(b *bytes.Buffer, ctx *genContext, v string) { + if len(op.optionalFields) == 0 { + return + } + // First check zero-ness of all optional fields. + var zeroV = make([]string, len(op.optionalFields)) + for i, field := range op.optionalFields { + selector := v + "." + field.name + zeroV[i] = ctx.temp() + fmt.Fprintf(b, "%s := %s\n", zeroV[i], nonZeroCheck(selector, field.typ, ctx.qualify)) + } + // Now write the fields. + for i, field := range op.optionalFields { + selector := v + "." + field.name + cond := "" + for j := i; j < len(op.optionalFields); j++ { + if j > i { + cond += " || " + } + cond += zeroV[j] + } + fmt.Fprintf(b, "if %s {\n", cond) + fmt.Fprint(b, field.elem.genWrite(ctx, selector)) + fmt.Fprintf(b, "}\n") + } +} + +func (op structOp) genDecode(ctx *genContext) (string, string) { + // Get the string representation of the type. + // Here, named types are handled separately because the output + // would contain a copy of the struct definition otherwise. + var typeName string + if op.named != nil { + typeName = types.TypeString(op.named, ctx.qualify) + } else { + typeName = types.TypeString(op.typ, ctx.qualify) + } + + // Create struct object. + var resultV = ctx.temp() + var b bytes.Buffer + fmt.Fprintf(&b, "var %s %s\n", resultV, typeName) + + // Decode fields. + fmt.Fprintf(&b, "{\n") + fmt.Fprintf(&b, "if _, err := dec.List(); err != nil { return err }\n") + for _, field := range op.fields { + result, code := field.elem.genDecode(ctx) + fmt.Fprintf(&b, "// %s:\n", field.name) + fmt.Fprint(&b, code) + fmt.Fprintf(&b, "%s.%s = %s\n", resultV, field.name, result) + } + op.decodeOptionalFields(&b, ctx, resultV) + fmt.Fprintf(&b, "if err := dec.ListEnd(); err != nil { return err }\n") + fmt.Fprintf(&b, "}\n") + return resultV, b.String() +} + +func (op structOp) decodeOptionalFields(b *bytes.Buffer, ctx *genContext, resultV string) { + var suffix bytes.Buffer + for _, field := range op.optionalFields { + result, code := field.elem.genDecode(ctx) + fmt.Fprintf(b, "// %s:\n", field.name) + fmt.Fprintf(b, "if dec.MoreDataInList() {\n") + fmt.Fprint(b, code) + fmt.Fprintf(b, "%s.%s = %s\n", resultV, field.name, result) + fmt.Fprintf(&suffix, "}\n") + } + suffix.WriteTo(b) +} + +// sliceOp handles slice types. +type sliceOp struct { + typ *types.Slice + elemOp op +} + +func (bctx *buildContext) makeSliceOp(typ *types.Slice) (op, error) { + elemOp, err := bctx.makeOp(nil, typ.Elem(), rlpstruct.Tags{}) + if err != nil { + return nil, err + } + return sliceOp{typ: typ, elemOp: elemOp}, nil +} + +func (op sliceOp) genWrite(ctx *genContext, v string) string { + var ( + listMarker = ctx.temp() // holds return value of w.List() + iterElemV = ctx.temp() // iteration variable + elemCode = op.elemOp.genWrite(ctx, iterElemV) + ) + + var b bytes.Buffer + fmt.Fprintf(&b, "%s := w.List()\n", listMarker) + fmt.Fprintf(&b, "for _, %s := range %s {\n", iterElemV, v) + fmt.Fprint(&b, elemCode) + fmt.Fprintf(&b, "}\n") + fmt.Fprintf(&b, "w.ListEnd(%s)\n", listMarker) + return b.String() +} + +func (op sliceOp) genDecode(ctx *genContext) (string, string) { + var sliceV = ctx.temp() // holds the output slice + elemResult, elemCode := op.elemOp.genDecode(ctx) + + var b bytes.Buffer + fmt.Fprintf(&b, "var %s %s\n", sliceV, types.TypeString(op.typ, ctx.qualify)) + fmt.Fprintf(&b, "if _, err := dec.List(); err != nil { return err }\n") + fmt.Fprintf(&b, "for dec.MoreDataInList() {\n") + fmt.Fprintf(&b, " %s", elemCode) + fmt.Fprintf(&b, " %s = append(%s, %s)\n", sliceV, sliceV, elemResult) + fmt.Fprintf(&b, "}\n") + fmt.Fprintf(&b, "if err := dec.ListEnd(); err != nil { return err }\n") + return sliceV, b.String() +} + +func (bctx *buildContext) makeOp(name *types.Named, typ types.Type, tags rlpstruct.Tags) (op, error) { + switch typ := typ.(type) { + case *types.Named: + if isBigInt(typ) { + return bigIntOp{}, nil + } + if typ == bctx.rawValueType { + return bctx.makeRawValueOp(), nil + } + if bctx.isDecoder(typ) { + return nil, fmt.Errorf("type %v implements rlp.Decoder with non-pointer receiver", typ) + } + // TODO: same check for encoder? + return bctx.makeOp(typ, typ.Underlying(), tags) + case *types.Pointer: + if isBigInt(typ.Elem()) { + return bigIntOp{pointer: true}, nil + } + // Encoder/Decoder interfaces. + if bctx.isEncoder(typ) { + if bctx.isDecoder(typ) { + return encoderDecoderOp{typ}, nil + } + return nil, fmt.Errorf("type %v implements rlp.Encoder but not rlp.Decoder", typ) + } + if bctx.isDecoder(typ) { + return nil, fmt.Errorf("type %v implements rlp.Decoder but not rlp.Encoder", typ) + } + // Default pointer handling. + return bctx.makePtrOp(typ.Elem(), tags) + case *types.Basic: + return bctx.makeBasicOp(typ) + case *types.Struct: + return bctx.makeStructOp(name, typ) + case *types.Slice: + etyp := typ.Elem() + if isByte(etyp) && !bctx.isEncoder(etyp) { + return bctx.makeByteSliceOp(typ), nil + } + return bctx.makeSliceOp(typ) + case *types.Array: + etyp := typ.Elem() + if isByte(etyp) && !bctx.isEncoder(etyp) { + return bctx.makeByteArrayOp(name, typ), nil + } + return nil, fmt.Errorf("unhandled array type: %v", typ) + default: + return nil, fmt.Errorf("unhandled type: %v", typ) + } +} + +// generateDecoder generates the DecodeRLP method on 'typ'. +func generateDecoder(ctx *genContext, typ string, op op) []byte { + ctx.resetTemp() + ctx.addImport(pathOfPackageRLP) + + result, code := op.genDecode(ctx) + var b bytes.Buffer + fmt.Fprintf(&b, "func (obj *%s) DecodeRLP(dec *rlp.Stream) error {\n", typ) + fmt.Fprint(&b, code) + fmt.Fprintf(&b, " *obj = %s\n", result) + fmt.Fprintf(&b, " return nil\n") + fmt.Fprintf(&b, "}\n") + return b.Bytes() +} + +// generateEncoder generates the EncodeRLP method on 'typ'. +func generateEncoder(ctx *genContext, typ string, op op) []byte { + ctx.resetTemp() + ctx.addImport("io") + ctx.addImport(pathOfPackageRLP) + + var b bytes.Buffer + fmt.Fprintf(&b, "func (obj *%s) EncodeRLP(_w io.Writer) error {\n", typ) + fmt.Fprintf(&b, " w := rlp.NewEncoderBuffer(_w)\n") + fmt.Fprint(&b, op.genWrite(ctx, "obj")) + fmt.Fprintf(&b, " return w.Flush()\n") + fmt.Fprintf(&b, "}\n") + return b.Bytes() +} + +func (bctx *buildContext) generate(typ *types.Named, encoder, decoder bool) ([]byte, error) { + bctx.topType = typ + + pkg := typ.Obj().Pkg() + op, err := bctx.makeOp(nil, typ, rlpstruct.Tags{}) + if err != nil { + return nil, err + } + + var ( + ctx = newGenContext(pkg) + encSource []byte + decSource []byte + ) + if encoder { + encSource = generateEncoder(ctx, typ.Obj().Name(), op) + } + if decoder { + decSource = generateDecoder(ctx, typ.Obj().Name(), op) + } + + var b bytes.Buffer + fmt.Fprintf(&b, "package %s\n\n", pkg.Name()) + for _, imp := range ctx.importsList() { + fmt.Fprintf(&b, "import %q\n", imp) + } + if encoder { + fmt.Fprintln(&b) + b.Write(encSource) + } + if decoder { + fmt.Fprintln(&b) + b.Write(decSource) + } + + source := b.Bytes() + // fmt.Println(string(source)) + return format.Source(source) +} diff --git a/rlp/rlpgen/gen_test.go b/rlp/rlpgen/gen_test.go new file mode 100644 index 0000000000..9940db188d --- /dev/null +++ b/rlp/rlpgen/gen_test.go @@ -0,0 +1,92 @@ +package main + +import ( + "bytes" + "fmt" + "go/ast" + "go/importer" + "go/parser" + "go/token" + "go/types" + "io/ioutil" + "os" + "path/filepath" + "testing" +) + +// Package RLP is loaded only once and reused for all tests. +var ( + testFset = token.NewFileSet() + testImporter = importer.ForCompiler(testFset, "source", nil).(types.ImporterFrom) + testPackageRLP *types.Package +) + +func init() { + cwd, err := os.Getwd() + if err != nil { + panic(err) + } + testPackageRLP, err = testImporter.ImportFrom(pathOfPackageRLP, cwd, 0) + if err != nil { + panic(fmt.Errorf("can't load package RLP: %v", err)) + } +} + +var tests = []string{"uints", "nil", "rawvalue", "optional", "bigint"} + +func TestOutput(t *testing.T) { + for _, test := range tests { + test := test + t.Run(test, func(t *testing.T) { + inputFile := filepath.Join("testdata", test+".in.txt") + outputFile := filepath.Join("testdata", test+".out.txt") + bctx, typ, err := loadTestSource(inputFile, "Test") + if err != nil { + t.Fatal("error loading test source:", err) + } + output, err := bctx.generate(typ, true, true) + if err != nil { + t.Fatal("error in generate:", err) + } + + // Set this environment variable to regenerate the test outputs. + if os.Getenv("WRITE_TEST_FILES") != "" { + ioutil.WriteFile(outputFile, output, 0644) + } + + // Check if output matches. + wantOutput, err := ioutil.ReadFile(outputFile) + if err != nil { + t.Fatal("error loading expected test output:", err) + } + if !bytes.Equal(output, wantOutput) { + t.Fatal("output mismatch:\n", string(output)) + } + }) + } +} + +func loadTestSource(file string, typeName string) (*buildContext, *types.Named, error) { + // Load the test input. + content, err := ioutil.ReadFile(file) + if err != nil { + return nil, nil, err + } + f, err := parser.ParseFile(testFset, file, content, 0) + if err != nil { + return nil, nil, err + } + conf := types.Config{Importer: testImporter} + pkg, err := conf.Check("test", testFset, []*ast.File{f}, nil) + if err != nil { + return nil, nil, err + } + + // Find the test struct. + bctx := newBuildContext(testPackageRLP) + typ, err := lookupStructType(pkg.Scope(), typeName) + if err != nil { + return nil, nil, fmt.Errorf("can't find type %s: %v", typeName, err) + } + return bctx, typ, nil +} diff --git a/rlp/rlpgen/main.go b/rlp/rlpgen/main.go new file mode 100644 index 0000000000..5b240bfd85 --- /dev/null +++ b/rlp/rlpgen/main.go @@ -0,0 +1,148 @@ +// Copyright 2021 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package main + +import ( + "bytes" + "errors" + "flag" + "fmt" + "go/types" + "io/ioutil" + "os" + + "golang.org/x/tools/go/packages" +) + +const pathOfPackageRLP = "github.com/ethereum/go-ethereum/rlp" + +func main() { + var ( + pkgdir = flag.String("dir", ".", "input package") + output = flag.String("out", "-", "output file (default is stdout)") + genEncoder = flag.Bool("encoder", true, "generate EncodeRLP?") + genDecoder = flag.Bool("decoder", false, "generate DecodeRLP?") + typename = flag.String("type", "", "type to generate methods for") + ) + flag.Parse() + + cfg := Config{ + Dir: *pkgdir, + Type: *typename, + GenerateEncoder: *genEncoder, + GenerateDecoder: *genDecoder, + } + code, err := cfg.process() + if err != nil { + fatal(err) + } + if *output == "-" { + os.Stdout.Write(code) + } else if err := ioutil.WriteFile(*output, code, 0644); err != nil { + fatal(err) + } +} + +func fatal(args ...interface{}) { + fmt.Fprintln(os.Stderr, args...) + os.Exit(1) +} + +type Config struct { + Dir string // input package directory + Type string + + GenerateEncoder bool + GenerateDecoder bool +} + +// process generates the Go code. +func (cfg *Config) process() (code []byte, err error) { + // Load packages. + pcfg := &packages.Config{ + Mode: packages.NeedName | packages.NeedTypes | packages.NeedImports | packages.NeedDeps, + Dir: cfg.Dir, + BuildFlags: []string{"-tags", "norlpgen"}, + } + ps, err := packages.Load(pcfg, pathOfPackageRLP, ".") + if err != nil { + return nil, err + } + if len(ps) == 0 { + return nil, fmt.Errorf("no Go package found in %s", cfg.Dir) + } + packages.PrintErrors(ps) + + // Find the packages that were loaded. + var ( + pkg *types.Package + packageRLP *types.Package + ) + for _, p := range ps { + if len(p.Errors) > 0 { + return nil, fmt.Errorf("package %s has errors", p.PkgPath) + } + if p.PkgPath == pathOfPackageRLP { + packageRLP = p.Types + } else { + pkg = p.Types + } + } + bctx := newBuildContext(packageRLP) + + // Find the type and generate. + typ, err := lookupStructType(pkg.Scope(), cfg.Type) + if err != nil { + return nil, fmt.Errorf("can't find %s in %s: %v", typ, pkg, err) + } + code, err = bctx.generate(typ, cfg.GenerateEncoder, cfg.GenerateDecoder) + if err != nil { + return nil, err + } + + // Add build comments. + // This is done here to avoid processing these lines with gofmt. + var header bytes.Buffer + fmt.Fprint(&header, "// Code generated by rlpgen. DO NOT EDIT.\n\n") + fmt.Fprint(&header, "//go:build !norlpgen\n") + fmt.Fprint(&header, "// +build !norlpgen\n\n") + return append(header.Bytes(), code...), nil +} + +func lookupStructType(scope *types.Scope, name string) (*types.Named, error) { + typ, err := lookupType(scope, name) + if err != nil { + return nil, err + } + _, ok := typ.Underlying().(*types.Struct) + if !ok { + return nil, errors.New("not a struct type") + } + return typ, nil +} + +func lookupType(scope *types.Scope, name string) (*types.Named, error) { + obj := scope.Lookup(name) + if obj == nil { + return nil, errors.New("no such identifier") + } + typ, ok := obj.(*types.TypeName) + if !ok { + return nil, errors.New("not a type") + } + return typ.Type().(*types.Named), nil +} diff --git a/rlp/rlpgen/testdata/bigint.in.txt b/rlp/rlpgen/testdata/bigint.in.txt new file mode 100644 index 0000000000..d23d84a287 --- /dev/null +++ b/rlp/rlpgen/testdata/bigint.in.txt @@ -0,0 +1,10 @@ +// -*- mode: go -*- + +package test + +import "math/big" + +type Test struct { + Int *big.Int + IntNoPtr big.Int +} diff --git a/rlp/rlpgen/testdata/bigint.out.txt b/rlp/rlpgen/testdata/bigint.out.txt new file mode 100644 index 0000000000..f54d1faa15 --- /dev/null +++ b/rlp/rlpgen/testdata/bigint.out.txt @@ -0,0 +1,49 @@ +package test + +import "github.com/ethereum/go-ethereum/rlp" +import "io" + +func (obj *Test) EncodeRLP(_w io.Writer) error { + w := rlp.NewEncoderBuffer(_w) + _tmp0 := w.List() + if obj.Int == nil { + w.Write(rlp.EmptyString) + } else { + if obj.Int.Sign() == -1 { + return rlp.ErrNegativeBigInt + } + w.WriteBigInt(obj.Int) + } + if obj.IntNoPtr.Sign() == -1 { + return rlp.ErrNegativeBigInt + } + w.WriteBigInt(&obj.IntNoPtr) + w.ListEnd(_tmp0) + return w.Flush() +} + +func (obj *Test) DecodeRLP(dec *rlp.Stream) error { + var _tmp0 Test + { + if _, err := dec.List(); err != nil { + return err + } + // Int: + _tmp1, err := dec.BigInt() + if err != nil { + return err + } + _tmp0.Int = _tmp1 + // IntNoPtr: + _tmp2, err := dec.BigInt() + if err != nil { + return err + } + _tmp0.IntNoPtr = (*_tmp2) + if err := dec.ListEnd(); err != nil { + return err + } + } + *obj = _tmp0 + return nil +} diff --git a/rlp/rlpgen/testdata/nil.in.txt b/rlp/rlpgen/testdata/nil.in.txt new file mode 100644 index 0000000000..a28ff34487 --- /dev/null +++ b/rlp/rlpgen/testdata/nil.in.txt @@ -0,0 +1,30 @@ +// -*- mode: go -*- + +package test + +type Aux struct{ + A uint32 +} + +type Test struct{ + Uint8 *byte `rlp:"nil"` + Uint8List *byte `rlp:"nilList"` + + Uint32 *uint32 `rlp:"nil"` + Uint32List *uint32 `rlp:"nilList"` + + Uint64 *uint64 `rlp:"nil"` + Uint64List *uint64 `rlp:"nilList"` + + String *string `rlp:"nil"` + StringList *string `rlp:"nilList"` + + ByteArray *[3]byte `rlp:"nil"` + ByteArrayList *[3]byte `rlp:"nilList"` + + ByteSlice *[]byte `rlp:"nil"` + ByteSliceList *[]byte `rlp:"nilList"` + + Struct *Aux `rlp:"nil"` + StructString *Aux `rlp:"nilString"` +} diff --git a/rlp/rlpgen/testdata/nil.out.txt b/rlp/rlpgen/testdata/nil.out.txt new file mode 100644 index 0000000000..e0d5dcebad --- /dev/null +++ b/rlp/rlpgen/testdata/nil.out.txt @@ -0,0 +1,289 @@ +package test + +import "github.com/ethereum/go-ethereum/rlp" +import "io" + +func (obj *Test) EncodeRLP(_w io.Writer) error { + w := rlp.NewEncoderBuffer(_w) + _tmp0 := w.List() + if obj.Uint8 == nil { + w.Write([]byte{0x80}) + } else { + w.WriteUint64(uint64((*obj.Uint8))) + } + if obj.Uint8List == nil { + w.Write([]byte{0xC0}) + } else { + w.WriteUint64(uint64((*obj.Uint8List))) + } + if obj.Uint32 == nil { + w.Write([]byte{0x80}) + } else { + w.WriteUint64(uint64((*obj.Uint32))) + } + if obj.Uint32List == nil { + w.Write([]byte{0xC0}) + } else { + w.WriteUint64(uint64((*obj.Uint32List))) + } + if obj.Uint64 == nil { + w.Write([]byte{0x80}) + } else { + w.WriteUint64((*obj.Uint64)) + } + if obj.Uint64List == nil { + w.Write([]byte{0xC0}) + } else { + w.WriteUint64((*obj.Uint64List)) + } + if obj.String == nil { + w.Write([]byte{0x80}) + } else { + w.WriteString((*obj.String)) + } + if obj.StringList == nil { + w.Write([]byte{0xC0}) + } else { + w.WriteString((*obj.StringList)) + } + if obj.ByteArray == nil { + w.Write([]byte{0x80}) + } else { + w.WriteBytes(obj.ByteArray[:]) + } + if obj.ByteArrayList == nil { + w.Write([]byte{0xC0}) + } else { + w.WriteBytes(obj.ByteArrayList[:]) + } + if obj.ByteSlice == nil { + w.Write([]byte{0x80}) + } else { + w.WriteBytes((*obj.ByteSlice)) + } + if obj.ByteSliceList == nil { + w.Write([]byte{0xC0}) + } else { + w.WriteBytes((*obj.ByteSliceList)) + } + if obj.Struct == nil { + w.Write([]byte{0xC0}) + } else { + _tmp1 := w.List() + w.WriteUint64(uint64(obj.Struct.A)) + w.ListEnd(_tmp1) + } + if obj.StructString == nil { + w.Write([]byte{0x80}) + } else { + _tmp2 := w.List() + w.WriteUint64(uint64(obj.StructString.A)) + w.ListEnd(_tmp2) + } + w.ListEnd(_tmp0) + return w.Flush() +} + +func (obj *Test) DecodeRLP(dec *rlp.Stream) error { + var _tmp0 Test + { + if _, err := dec.List(); err != nil { + return err + } + // Uint8: + var _tmp2 *byte + if _tmp3, _tmp4, err := dec.Kind(); err != nil { + return err + } else if _tmp4 != 0 || _tmp3 != rlp.String { + _tmp1, err := dec.Uint8() + if err != nil { + return err + } + _tmp2 = &_tmp1 + } + _tmp0.Uint8 = _tmp2 + // Uint8List: + var _tmp6 *byte + if _tmp7, _tmp8, err := dec.Kind(); err != nil { + return err + } else if _tmp8 != 0 || _tmp7 != rlp.List { + _tmp5, err := dec.Uint8() + if err != nil { + return err + } + _tmp6 = &_tmp5 + } + _tmp0.Uint8List = _tmp6 + // Uint32: + var _tmp10 *uint32 + if _tmp11, _tmp12, err := dec.Kind(); err != nil { + return err + } else if _tmp12 != 0 || _tmp11 != rlp.String { + _tmp9, err := dec.Uint32() + if err != nil { + return err + } + _tmp10 = &_tmp9 + } + _tmp0.Uint32 = _tmp10 + // Uint32List: + var _tmp14 *uint32 + if _tmp15, _tmp16, err := dec.Kind(); err != nil { + return err + } else if _tmp16 != 0 || _tmp15 != rlp.List { + _tmp13, err := dec.Uint32() + if err != nil { + return err + } + _tmp14 = &_tmp13 + } + _tmp0.Uint32List = _tmp14 + // Uint64: + var _tmp18 *uint64 + if _tmp19, _tmp20, err := dec.Kind(); err != nil { + return err + } else if _tmp20 != 0 || _tmp19 != rlp.String { + _tmp17, err := dec.Uint64() + if err != nil { + return err + } + _tmp18 = &_tmp17 + } + _tmp0.Uint64 = _tmp18 + // Uint64List: + var _tmp22 *uint64 + if _tmp23, _tmp24, err := dec.Kind(); err != nil { + return err + } else if _tmp24 != 0 || _tmp23 != rlp.List { + _tmp21, err := dec.Uint64() + if err != nil { + return err + } + _tmp22 = &_tmp21 + } + _tmp0.Uint64List = _tmp22 + // String: + var _tmp26 *string + if _tmp27, _tmp28, err := dec.Kind(); err != nil { + return err + } else if _tmp28 != 0 || _tmp27 != rlp.String { + _tmp25, err := dec.String() + if err != nil { + return err + } + _tmp26 = &_tmp25 + } + _tmp0.String = _tmp26 + // StringList: + var _tmp30 *string + if _tmp31, _tmp32, err := dec.Kind(); err != nil { + return err + } else if _tmp32 != 0 || _tmp31 != rlp.List { + _tmp29, err := dec.String() + if err != nil { + return err + } + _tmp30 = &_tmp29 + } + _tmp0.StringList = _tmp30 + // ByteArray: + var _tmp34 *[3]byte + if _tmp35, _tmp36, err := dec.Kind(); err != nil { + return err + } else if _tmp36 != 0 || _tmp35 != rlp.String { + var _tmp33 [3]byte + if err := dec.ReadBytes(_tmp33[:]); err != nil { + return err + } + _tmp34 = &_tmp33 + } + _tmp0.ByteArray = _tmp34 + // ByteArrayList: + var _tmp38 *[3]byte + if _tmp39, _tmp40, err := dec.Kind(); err != nil { + return err + } else if _tmp40 != 0 || _tmp39 != rlp.List { + var _tmp37 [3]byte + if err := dec.ReadBytes(_tmp37[:]); err != nil { + return err + } + _tmp38 = &_tmp37 + } + _tmp0.ByteArrayList = _tmp38 + // ByteSlice: + var _tmp42 *[]byte + if _tmp43, _tmp44, err := dec.Kind(); err != nil { + return err + } else if _tmp44 != 0 || _tmp43 != rlp.String { + _tmp41, err := dec.Bytes() + if err != nil { + return err + } + _tmp42 = &_tmp41 + } + _tmp0.ByteSlice = _tmp42 + // ByteSliceList: + var _tmp46 *[]byte + if _tmp47, _tmp48, err := dec.Kind(); err != nil { + return err + } else if _tmp48 != 0 || _tmp47 != rlp.List { + _tmp45, err := dec.Bytes() + if err != nil { + return err + } + _tmp46 = &_tmp45 + } + _tmp0.ByteSliceList = _tmp46 + // Struct: + var _tmp51 *Aux + if _tmp52, _tmp53, err := dec.Kind(); err != nil { + return err + } else if _tmp53 != 0 || _tmp52 != rlp.List { + var _tmp49 Aux + { + if _, err := dec.List(); err != nil { + return err + } + // A: + _tmp50, err := dec.Uint32() + if err != nil { + return err + } + _tmp49.A = _tmp50 + if err := dec.ListEnd(); err != nil { + return err + } + } + _tmp51 = &_tmp49 + } + _tmp0.Struct = _tmp51 + // StructString: + var _tmp56 *Aux + if _tmp57, _tmp58, err := dec.Kind(); err != nil { + return err + } else if _tmp58 != 0 || _tmp57 != rlp.String { + var _tmp54 Aux + { + if _, err := dec.List(); err != nil { + return err + } + // A: + _tmp55, err := dec.Uint32() + if err != nil { + return err + } + _tmp54.A = _tmp55 + if err := dec.ListEnd(); err != nil { + return err + } + } + _tmp56 = &_tmp54 + } + _tmp0.StructString = _tmp56 + if err := dec.ListEnd(); err != nil { + return err + } + } + *obj = _tmp0 + return nil +} diff --git a/rlp/rlpgen/testdata/optional.in.txt b/rlp/rlpgen/testdata/optional.in.txt new file mode 100644 index 0000000000..f1ac9f7899 --- /dev/null +++ b/rlp/rlpgen/testdata/optional.in.txt @@ -0,0 +1,17 @@ +// -*- mode: go -*- + +package test + +type Aux struct { + A uint64 +} + +type Test struct { + Uint64 uint64 `rlp:"optional"` + Pointer *uint64 `rlp:"optional"` + String string `rlp:"optional"` + Slice []uint64 `rlp:"optional"` + Array [3]byte `rlp:"optional"` + NamedStruct Aux `rlp:"optional"` + AnonStruct struct{ A string } `rlp:"optional"` +} diff --git a/rlp/rlpgen/testdata/optional.out.txt b/rlp/rlpgen/testdata/optional.out.txt new file mode 100644 index 0000000000..02df8e457f --- /dev/null +++ b/rlp/rlpgen/testdata/optional.out.txt @@ -0,0 +1,153 @@ +package test + +import "github.com/ethereum/go-ethereum/rlp" +import "io" + +func (obj *Test) EncodeRLP(_w io.Writer) error { + w := rlp.NewEncoderBuffer(_w) + _tmp0 := w.List() + _tmp1 := obj.Uint64 != 0 + _tmp2 := obj.Pointer != nil + _tmp3 := obj.String != "" + _tmp4 := len(obj.Slice) > 0 + _tmp5 := obj.Array != ([3]byte{}) + _tmp6 := obj.NamedStruct != (Aux{}) + _tmp7 := obj.AnonStruct != (struct{ A string }{}) + if _tmp1 || _tmp2 || _tmp3 || _tmp4 || _tmp5 || _tmp6 || _tmp7 { + w.WriteUint64(obj.Uint64) + } + if _tmp2 || _tmp3 || _tmp4 || _tmp5 || _tmp6 || _tmp7 { + if obj.Pointer == nil { + w.Write([]byte{0x80}) + } else { + w.WriteUint64((*obj.Pointer)) + } + } + if _tmp3 || _tmp4 || _tmp5 || _tmp6 || _tmp7 { + w.WriteString(obj.String) + } + if _tmp4 || _tmp5 || _tmp6 || _tmp7 { + _tmp8 := w.List() + for _, _tmp9 := range obj.Slice { + w.WriteUint64(_tmp9) + } + w.ListEnd(_tmp8) + } + if _tmp5 || _tmp6 || _tmp7 { + w.WriteBytes(obj.Array[:]) + } + if _tmp6 || _tmp7 { + _tmp10 := w.List() + w.WriteUint64(obj.NamedStruct.A) + w.ListEnd(_tmp10) + } + if _tmp7 { + _tmp11 := w.List() + w.WriteString(obj.AnonStruct.A) + w.ListEnd(_tmp11) + } + w.ListEnd(_tmp0) + return w.Flush() +} + +func (obj *Test) DecodeRLP(dec *rlp.Stream) error { + var _tmp0 Test + { + if _, err := dec.List(); err != nil { + return err + } + // Uint64: + if dec.MoreDataInList() { + _tmp1, err := dec.Uint64() + if err != nil { + return err + } + _tmp0.Uint64 = _tmp1 + // Pointer: + if dec.MoreDataInList() { + _tmp2, err := dec.Uint64() + if err != nil { + return err + } + _tmp0.Pointer = &_tmp2 + // String: + if dec.MoreDataInList() { + _tmp3, err := dec.String() + if err != nil { + return err + } + _tmp0.String = _tmp3 + // Slice: + if dec.MoreDataInList() { + var _tmp4 []uint64 + if _, err := dec.List(); err != nil { + return err + } + for dec.MoreDataInList() { + _tmp5, err := dec.Uint64() + if err != nil { + return err + } + _tmp4 = append(_tmp4, _tmp5) + } + if err := dec.ListEnd(); err != nil { + return err + } + _tmp0.Slice = _tmp4 + // Array: + if dec.MoreDataInList() { + var _tmp6 [3]byte + if err := dec.ReadBytes(_tmp6[:]); err != nil { + return err + } + _tmp0.Array = _tmp6 + // NamedStruct: + if dec.MoreDataInList() { + var _tmp7 Aux + { + if _, err := dec.List(); err != nil { + return err + } + // A: + _tmp8, err := dec.Uint64() + if err != nil { + return err + } + _tmp7.A = _tmp8 + if err := dec.ListEnd(); err != nil { + return err + } + } + _tmp0.NamedStruct = _tmp7 + // AnonStruct: + if dec.MoreDataInList() { + var _tmp9 struct{ A string } + { + if _, err := dec.List(); err != nil { + return err + } + // A: + _tmp10, err := dec.String() + if err != nil { + return err + } + _tmp9.A = _tmp10 + if err := dec.ListEnd(); err != nil { + return err + } + } + _tmp0.AnonStruct = _tmp9 + } + } + } + } + } + } + } + if err := dec.ListEnd(); err != nil { + return err + } + } + *obj = _tmp0 + return nil +} diff --git a/rlp/rlpgen/testdata/rawvalue.in.txt b/rlp/rlpgen/testdata/rawvalue.in.txt new file mode 100644 index 0000000000..3a657bc907 --- /dev/null +++ b/rlp/rlpgen/testdata/rawvalue.in.txt @@ -0,0 +1,11 @@ +// -*- mode: go -*- + +package test + +import "github.com/ethereum/go-ethereum/rlp" + +type Test struct { + RawValue rlp.RawValue + PointerToRawValue *rlp.RawValue + SliceOfRawValue []rlp.RawValue +} diff --git a/rlp/rlpgen/testdata/rawvalue.out.txt b/rlp/rlpgen/testdata/rawvalue.out.txt new file mode 100644 index 0000000000..3607c98636 --- /dev/null +++ b/rlp/rlpgen/testdata/rawvalue.out.txt @@ -0,0 +1,64 @@ +package test + +import "github.com/ethereum/go-ethereum/rlp" +import "io" + +func (obj *Test) EncodeRLP(_w io.Writer) error { + w := rlp.NewEncoderBuffer(_w) + _tmp0 := w.List() + w.Write(obj.RawValue) + if obj.PointerToRawValue == nil { + w.Write([]byte{0x80}) + } else { + w.Write((*obj.PointerToRawValue)) + } + _tmp1 := w.List() + for _, _tmp2 := range obj.SliceOfRawValue { + w.Write(_tmp2) + } + w.ListEnd(_tmp1) + w.ListEnd(_tmp0) + return w.Flush() +} + +func (obj *Test) DecodeRLP(dec *rlp.Stream) error { + var _tmp0 Test + { + if _, err := dec.List(); err != nil { + return err + } + // RawValue: + _tmp1, err := dec.Raw() + if err != nil { + return err + } + _tmp0.RawValue = _tmp1 + // PointerToRawValue: + _tmp2, err := dec.Raw() + if err != nil { + return err + } + _tmp0.PointerToRawValue = &_tmp2 + // SliceOfRawValue: + var _tmp3 []rlp.RawValue + if _, err := dec.List(); err != nil { + return err + } + for dec.MoreDataInList() { + _tmp4, err := dec.Raw() + if err != nil { + return err + } + _tmp3 = append(_tmp3, _tmp4) + } + if err := dec.ListEnd(); err != nil { + return err + } + _tmp0.SliceOfRawValue = _tmp3 + if err := dec.ListEnd(); err != nil { + return err + } + } + *obj = _tmp0 + return nil +} diff --git a/rlp/rlpgen/testdata/uints.in.txt b/rlp/rlpgen/testdata/uints.in.txt new file mode 100644 index 0000000000..8095da997d --- /dev/null +++ b/rlp/rlpgen/testdata/uints.in.txt @@ -0,0 +1,10 @@ +// -*- mode: go -*- + +package test + +type Test struct{ + A uint8 + B uint16 + C uint32 + D uint64 +} diff --git a/rlp/rlpgen/testdata/uints.out.txt b/rlp/rlpgen/testdata/uints.out.txt new file mode 100644 index 0000000000..1a354956a4 --- /dev/null +++ b/rlp/rlpgen/testdata/uints.out.txt @@ -0,0 +1,53 @@ +package test + +import "github.com/ethereum/go-ethereum/rlp" +import "io" + +func (obj *Test) EncodeRLP(_w io.Writer) error { + w := rlp.NewEncoderBuffer(_w) + _tmp0 := w.List() + w.WriteUint64(uint64(obj.A)) + w.WriteUint64(uint64(obj.B)) + w.WriteUint64(uint64(obj.C)) + w.WriteUint64(obj.D) + w.ListEnd(_tmp0) + return w.Flush() +} + +func (obj *Test) DecodeRLP(dec *rlp.Stream) error { + var _tmp0 Test + { + if _, err := dec.List(); err != nil { + return err + } + // A: + _tmp1, err := dec.Uint8() + if err != nil { + return err + } + _tmp0.A = _tmp1 + // B: + _tmp2, err := dec.Uint16() + if err != nil { + return err + } + _tmp0.B = _tmp2 + // C: + _tmp3, err := dec.Uint32() + if err != nil { + return err + } + _tmp0.C = _tmp3 + // D: + _tmp4, err := dec.Uint64() + if err != nil { + return err + } + _tmp0.D = _tmp4 + if err := dec.ListEnd(); err != nil { + return err + } + } + *obj = _tmp0 + return nil +} diff --git a/rlp/rlpgen/types.go b/rlp/rlpgen/types.go new file mode 100644 index 0000000000..5926a801ee --- /dev/null +++ b/rlp/rlpgen/types.go @@ -0,0 +1,98 @@ +package main + +import ( + "fmt" + "go/types" + "reflect" +) + +// typeReflectKind gives the reflect.Kind that represents typ. +func typeReflectKind(typ types.Type) reflect.Kind { + switch typ := typ.(type) { + case *types.Basic: + k := typ.Kind() + if k >= types.Bool && k <= types.Complex128 { + // value order matches for Bool..Complex128 + return reflect.Bool + reflect.Kind(k-types.Bool) + } + if k == types.String { + return reflect.String + } + if k == types.UnsafePointer { + return reflect.UnsafePointer + } + panic(fmt.Errorf("unhandled BasicKind %v", k)) + case *types.Array: + return reflect.Array + case *types.Chan: + return reflect.Chan + case *types.Interface: + return reflect.Interface + case *types.Map: + return reflect.Map + case *types.Pointer: + return reflect.Ptr + case *types.Signature: + return reflect.Func + case *types.Slice: + return reflect.Slice + case *types.Struct: + return reflect.Struct + default: + panic(fmt.Errorf("unhandled type %T", typ)) + } +} + +// nonZeroCheck returns the expression that checks whether 'v' is a non-zero value of type 'vtyp'. +func nonZeroCheck(v string, vtyp types.Type, qualify types.Qualifier) string { + // Resolve type name. + typ := resolveUnderlying(vtyp) + switch typ := typ.(type) { + case *types.Basic: + k := typ.Kind() + switch { + case k == types.Bool: + return v + case k >= types.Uint && k <= types.Complex128: + return fmt.Sprintf("%s != 0", v) + case k == types.String: + return fmt.Sprintf(`%s != ""`, v) + default: + panic(fmt.Errorf("unhandled BasicKind %v", k)) + } + case *types.Array, *types.Struct: + return fmt.Sprintf("%s != (%s{})", v, types.TypeString(vtyp, qualify)) + case *types.Interface, *types.Pointer, *types.Signature: + return fmt.Sprintf("%s != nil", v) + case *types.Slice, *types.Map: + return fmt.Sprintf("len(%s) > 0", v) + default: + panic(fmt.Errorf("unhandled type %T", typ)) + } +} + +// isBigInt checks whether 'typ' is "math/big".Int. +func isBigInt(typ types.Type) bool { + named, ok := typ.(*types.Named) + if !ok { + return false + } + name := named.Obj() + return name.Pkg().Path() == "math/big" && name.Name() == "Int" +} + +// isByte checks whether the underlying type of 'typ' is uint8. +func isByte(typ types.Type) bool { + basic, ok := resolveUnderlying(typ).(*types.Basic) + return ok && basic.Kind() == types.Uint8 +} + +func resolveUnderlying(typ types.Type) types.Type { + for { + t := typ.Underlying() + if t == typ { + return t + } + typ = t + } +} diff --git a/rlp/typecache.go b/rlp/typecache.go index 62553d3b55..3e37c9d2fc 100644 --- a/rlp/typecache.go +++ b/rlp/typecache.go @@ -19,9 +19,10 @@ package rlp import ( "fmt" "reflect" - "strings" "sync" "sync/atomic" + + "github.com/ethereum/go-ethereum/rlp/internal/rlpstruct" ) // typeinfo is an entry in the type cache. @@ -32,35 +33,16 @@ type typeinfo struct { writerErr error // error from makeWriter } -// tags represents struct tags. -type tags struct { - // rlp:"nil" controls whether empty input results in a nil pointer. - // nilKind is the kind of empty value allowed for the field. - nilKind Kind - nilOK bool - - // rlp:"optional" allows for a field to be missing in the input list. - // If this is set, all subsequent fields must also be optional. - optional bool - - // rlp:"tail" controls whether this field swallows additional list elements. It can - // only be set for the last field, which must be of slice type. - tail bool - - // rlp:"-" ignores fields. - ignored bool -} - // typekey is the key of a type in typeCache. It includes the struct tags because // they might generate a different decoder. type typekey struct { reflect.Type - tags + rlpstruct.Tags } type decoder func(*Stream, reflect.Value) error -type writer func(reflect.Value, *encbuf) error +type writer func(reflect.Value, *encBuffer) error var theTC = newTypeCache() @@ -95,10 +77,10 @@ func (c *typeCache) info(typ reflect.Type) *typeinfo { } // Not in the cache, need to generate info for this type. - return c.generate(typ, tags{}) + return c.generate(typ, rlpstruct.Tags{}) } -func (c *typeCache) generate(typ reflect.Type, tags tags) *typeinfo { +func (c *typeCache) generate(typ reflect.Type, tags rlpstruct.Tags) *typeinfo { c.mu.Lock() defer c.mu.Unlock() @@ -122,7 +104,7 @@ func (c *typeCache) generate(typ reflect.Type, tags tags) *typeinfo { return info } -func (c *typeCache) infoWhileGenerating(typ reflect.Type, tags tags) *typeinfo { +func (c *typeCache) infoWhileGenerating(typ reflect.Type, tags rlpstruct.Tags) *typeinfo { key := typekey{typ, tags} if info := c.next[key]; info != nil { return info @@ -144,35 +126,40 @@ type field struct { // structFields resolves the typeinfo of all public fields in a struct type. func structFields(typ reflect.Type) (fields []field, err error) { - var ( - lastPublic = lastPublicField(typ) - anyOptional = false - ) + // Convert fields to rlpstruct.Field. + var allStructFields []rlpstruct.Field for i := 0; i < typ.NumField(); i++ { - if f := typ.Field(i); f.PkgPath == "" { // exported - tags, err := parseStructTag(typ, i, lastPublic) - if err != nil { - return nil, err - } - - // Skip rlp:"-" fields. - if tags.ignored { - continue - } - // If any field has the "optional" tag, subsequent fields must also have it. - if tags.optional || tags.tail { - anyOptional = true - } else if anyOptional { - return nil, fmt.Errorf(`rlp: struct field %v.%s needs "optional" tag`, typ, f.Name) - } - info := theTC.infoWhileGenerating(f.Type, tags) - fields = append(fields, field{i, info, tags.optional}) + rf := typ.Field(i) + allStructFields = append(allStructFields, rlpstruct.Field{ + Name: rf.Name, + Index: i, + Exported: rf.PkgPath == "", + Tag: string(rf.Tag), + Type: *rtypeToStructType(rf.Type, nil), + }) + } + + // Filter/validate fields. + structFields, structTags, err := rlpstruct.ProcessFields(allStructFields) + if err != nil { + if tagErr, ok := err.(rlpstruct.TagError); ok { + tagErr.StructType = typ.String() + return nil, tagErr } + return nil, err + } + + // Resolve typeinfo. + for i, sf := range structFields { + typ := typ.Field(sf.Index).Type + tags := structTags[i] + info := theTC.infoWhileGenerating(typ, tags) + fields = append(fields, field{sf.Index, info, tags.Optional}) } return fields, nil } -// anyOptionalFields returns the index of the first field with "optional" tag. +// firstOptionalField returns the index of the first field with "optional" tag. func firstOptionalField(fields []field) int { for i, f := range fields { if f.optional { @@ -192,82 +179,56 @@ func (e structFieldError) Error() string { return fmt.Sprintf("%v (struct field %v.%s)", e.err, e.typ, e.typ.Field(e.field).Name) } -type structTagError struct { - typ reflect.Type - field, tag, err string +func (i *typeinfo) generate(typ reflect.Type, tags rlpstruct.Tags) { + i.decoder, i.decoderErr = makeDecoder(typ, tags) + i.writer, i.writerErr = makeWriter(typ, tags) } -func (e structTagError) Error() string { - return fmt.Sprintf("rlp: invalid struct tag %q for %v.%s (%s)", e.tag, e.typ, e.field, e.err) -} +// rtypeToStructType converts typ to rlpstruct.Type. +func rtypeToStructType(typ reflect.Type, rec map[reflect.Type]*rlpstruct.Type) *rlpstruct.Type { + k := typ.Kind() + if k == reflect.Invalid { + panic("invalid kind") + } -func parseStructTag(typ reflect.Type, fi, lastPublic int) (tags, error) { - f := typ.Field(fi) - var ts tags - for _, t := range strings.Split(f.Tag.Get("rlp"), ",") { - switch t = strings.TrimSpace(t); t { - case "": - case "-": - ts.ignored = true - case "nil", "nilString", "nilList": - ts.nilOK = true - if f.Type.Kind() != reflect.Ptr { - return ts, structTagError{typ, f.Name, t, "field is not a pointer"} - } - switch t { - case "nil": - ts.nilKind = defaultNilKind(f.Type.Elem()) - case "nilString": - ts.nilKind = String - case "nilList": - ts.nilKind = List - } - case "optional": - ts.optional = true - if ts.tail { - return ts, structTagError{typ, f.Name, t, `also has "tail" tag`} - } - case "tail": - ts.tail = true - if fi != lastPublic { - return ts, structTagError{typ, f.Name, t, "must be on last field"} - } - if ts.optional { - return ts, structTagError{typ, f.Name, t, `also has "optional" tag`} - } - if f.Type.Kind() != reflect.Slice { - return ts, structTagError{typ, f.Name, t, "field type is not slice"} - } - default: - return ts, fmt.Errorf("rlp: unknown struct tag %q on %v.%s", t, typ, f.Name) - } + if prev := rec[typ]; prev != nil { + return prev // short-circuit for recursive types + } + if rec == nil { + rec = make(map[reflect.Type]*rlpstruct.Type) } - return ts, nil -} -func lastPublicField(typ reflect.Type) int { - last := 0 - for i := 0; i < typ.NumField(); i++ { - if typ.Field(i).PkgPath == "" { - last = i - } + t := &rlpstruct.Type{ + Name: typ.String(), + Kind: k, + IsEncoder: typ.Implements(encoderInterface), + IsDecoder: typ.Implements(decoderInterface), + } + rec[typ] = t + if k == reflect.Array || k == reflect.Slice || k == reflect.Ptr { + t.Elem = rtypeToStructType(typ.Elem(), rec) } - return last + return t } -func (i *typeinfo) generate(typ reflect.Type, tags tags) { - i.decoder, i.decoderErr = makeDecoder(typ, tags) - i.writer, i.writerErr = makeWriter(typ, tags) -} +// typeNilKind gives the RLP value kind for nil pointers to 'typ'. +func typeNilKind(typ reflect.Type, tags rlpstruct.Tags) Kind { + styp := rtypeToStructType(typ, nil) -// defaultNilKind determines whether a nil pointer to typ encodes/decodes -// as an empty string or empty list. -func defaultNilKind(typ reflect.Type) Kind { - k := typ.Kind() - if isUint(k) || k == reflect.String || k == reflect.Bool || isByteArray(typ) { + var nk rlpstruct.NilKind + if tags.NilOK { + nk = tags.NilKind + } else { + nk = styp.DefaultNilValue() + } + switch nk { + case rlpstruct.NilKindString: return String + case rlpstruct.NilKindList: + return List + default: + panic("invalid nil kind value") } - return List } func isUint(k reflect.Kind) bool { @@ -277,7 +238,3 @@ func isUint(k reflect.Kind) bool { func isByte(typ reflect.Type) bool { return typ.Kind() == reflect.Uint8 && !typ.Implements(encoderInterface) } - -func isByteArray(typ reflect.Type) bool { - return (typ.Kind() == reflect.Slice || typ.Kind() == reflect.Array) && isByte(typ.Elem()) -} diff --git a/rpc/server_test.go b/rpc/server_test.go index c692a071cf..e67893710d 100644 --- a/rpc/server_test.go +++ b/rpc/server_test.go @@ -134,7 +134,7 @@ func TestServerShortLivedConn(t *testing.T) { if err != nil { t.Fatal("can't dial:", err) } - defer conn.Close() + conn.SetDeadline(deadline) // Write the request, then half-close the connection so the server stops reading. conn.Write([]byte(request)) @@ -142,6 +142,8 @@ func TestServerShortLivedConn(t *testing.T) { // Now try to get the response. buf := make([]byte, 2000) n, err := conn.Read(buf) + conn.Close() + if err != nil { t.Fatal("read error:", err) } diff --git a/tests/fuzzers/vflux/clientpool-fuzzer.go b/tests/fuzzers/vflux/clientpool-fuzzer.go index 0414c001ec..b3b523cc82 100644 --- a/tests/fuzzers/vflux/clientpool-fuzzer.go +++ b/tests/fuzzers/vflux/clientpool-fuzzer.go @@ -267,9 +267,7 @@ func FuzzClientPool(input []byte) int { bias = f.randomDelay() requested = f.randomBool() ) - if _, err := pool.SetCapacity(f.peers[index].node, reqCap, bias, requested); err == vfs.ErrCantFindMaximum { - panic(nil) - } + pool.SetCapacity(f.peers[index].node, reqCap, bias, requested) doLog("Set capacity", "id", f.peers[index].node.ID(), "reqcap", reqCap, "bias", bias, "requested", requested) case 7: index := f.randomByte() diff --git a/trie/committer.go b/trie/committer.go index 0721990a21..db753e2fa0 100644 --- a/trie/committer.go +++ b/trie/committer.go @@ -44,7 +44,6 @@ type leaf struct { // By 'some level' of parallelism, it's still the case that all leaves will be // processed sequentially - onleaf will never be called in parallel or out of order. type committer struct { - tmp sliceBuffer sha crypto.KeccakState onleaf LeafCallback @@ -55,7 +54,6 @@ type committer struct { var committerPool = sync.Pool{ New: func() interface{} { return &committer{ - tmp: make(sliceBuffer, 0, 550), // cap is as large as a full fullNode. sha: sha3.NewLegacyKeccak256().(crypto.KeccakState), } }, diff --git a/trie/database.go b/trie/database.go index b8d1aa6eea..7504eb2c91 100644 --- a/trie/database.go +++ b/trie/database.go @@ -118,16 +118,9 @@ func (n rawFullNode) cache() (hashNode, bool) { panic("this should never end u func (n rawFullNode) fstring(ind string) string { panic("this should never end up in a live trie") } func (n rawFullNode) EncodeRLP(w io.Writer) error { - var nodes [17]node - - for i, child := range n { - if child != nil { - nodes[i] = child - } else { - nodes[i] = nilValueNode - } - } - return rlp.Encode(w, nodes) + eb := rlp.NewEncoderBuffer(w) + n.encode(eb) + return eb.Flush() } // rawShortNode represents only the useful data content of a short node, with the @@ -169,11 +162,7 @@ func (n *cachedNode) rlp() []byte { if node, ok := n.node.(rawNode); ok { return node } - blob, err := rlp.EncodeToBytes(n.node) - if err != nil { - panic(err) - } - return blob + return nodeToBytes(n.node) } // obj returns the decoded and expanded trie node, either directly from the cache, diff --git a/trie/hasher.go b/trie/hasher.go index 3a62a2f119..7f0748c13d 100644 --- a/trie/hasher.go +++ b/trie/hasher.go @@ -24,22 +24,12 @@ import ( "golang.org/x/crypto/sha3" ) -type sliceBuffer []byte - -func (b *sliceBuffer) Write(data []byte) (n int, err error) { - *b = append(*b, data...) - return len(data), nil -} - -func (b *sliceBuffer) Reset() { - *b = (*b)[:0] -} - // hasher is a type used for the trie Hash operation. A hasher has some // internal preallocated temp space type hasher struct { sha crypto.KeccakState - tmp sliceBuffer + tmp []byte + encbuf rlp.EncoderBuffer parallel bool // Whether to use paralallel threads when hashing } @@ -47,8 +37,9 @@ type hasher struct { var hasherPool = sync.Pool{ New: func() interface{} { return &hasher{ - tmp: make(sliceBuffer, 0, 550), // cap is as large as a full fullNode. - sha: sha3.NewLegacyKeccak256().(crypto.KeccakState), + tmp: make([]byte, 0, 550), // cap is as large as a full fullNode. + sha: sha3.NewLegacyKeccak256().(crypto.KeccakState), + encbuf: rlp.NewEncoderBuffer(nil), } }, } @@ -153,30 +144,41 @@ func (h *hasher) hashFullNodeChildren(n *fullNode) (collapsed *fullNode, cached // into compact form for RLP encoding. // If the rlp data is smaller than 32 bytes, `nil` is returned. func (h *hasher) shortnodeToHash(n *shortNode, force bool) node { - h.tmp.Reset() - if err := rlp.Encode(&h.tmp, n); err != nil { - panic("encode error: " + err.Error()) - } + n.encode(h.encbuf) + enc := h.encodedBytes() - if len(h.tmp) < 32 && !force { + if len(enc) < 32 && !force { return n // Nodes smaller than 32 bytes are stored inside their parent } - return h.hashData(h.tmp) + return h.hashData(enc) } // shortnodeToHash is used to creates a hashNode from a set of hashNodes, (which // may contain nil values) func (h *hasher) fullnodeToHash(n *fullNode, force bool) node { - h.tmp.Reset() - // Generate the RLP encoding of the node - if err := n.EncodeRLP(&h.tmp); err != nil { - panic("encode error: " + err.Error()) - } + n.encode(h.encbuf) + enc := h.encodedBytes() - if len(h.tmp) < 32 && !force { + if len(enc) < 32 && !force { return n // Nodes smaller than 32 bytes are stored inside their parent } - return h.hashData(h.tmp) + return h.hashData(enc) +} + +// encodedBytes returns the result of the last encoding operation on h.encbuf. +// This also resets the encoder buffer. +// +// All node encoding must be done like this: +// +// node.encode(h.encbuf) +// enc := h.encodedBytes() +// +// This convention exists because node.encode can only be inlined/escape-analyzed when +// called on a concrete receiver type. +func (h *hasher) encodedBytes() []byte { + h.tmp = h.encbuf.AppendToBytes(h.tmp[:0]) + h.encbuf.Reset(nil) + return h.tmp } // hashData hashes the provided data diff --git a/trie/iterator.go b/trie/iterator.go index 9f6dc3af7f..c7899b9735 100644 --- a/trie/iterator.go +++ b/trie/iterator.go @@ -23,7 +23,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/rlp" ) // Iterator is a key-value trie iterator that traverses a Trie. @@ -151,8 +150,11 @@ func (e seekError) Error() string { } func newNodeIterator(trie *Trie, start []byte) NodeIterator { - if trie.Hash() == emptyState { - return new(nodeIterator) + if trie.Hash() == emptyRoot { + return &nodeIterator{ + trie: trie, + err: errIteratorEnd, + } } it := &nodeIterator{trie: trie} it.err = it.seek(start) @@ -210,8 +212,7 @@ func (it *nodeIterator) LeafProof() [][]byte { // Gather nodes that end up as hash nodes (or the root) node, hashed := hasher.proofHash(item.node) if _, ok := hashed.(hashNode); ok || i == 0 { - enc, _ := rlp.EncodeToBytes(node) - proofs = append(proofs, enc) + proofs = append(proofs, nodeToBytes(node)) } } return proofs @@ -402,7 +403,7 @@ func findChild(n *fullNode, index int, path []byte, ancestor common.Hash) (node, func (it *nodeIterator) nextChild(parent *nodeIteratorState, ancestor common.Hash) (*nodeIteratorState, []byte, bool) { switch node := parent.node.(type) { case *fullNode: - //Full node, move to the first non-nil child. + // Full node, move to the first non-nil child. if child, state, path, index := findChild(node, parent.index+1, it.path, ancestor); child != nil { parent.index = index - 1 return state, path, true @@ -480,8 +481,9 @@ func (it *nodeIterator) push(state *nodeIteratorState, parentIndex *int, path [] } func (it *nodeIterator) pop() { - parent := it.stack[len(it.stack)-1] - it.path = it.path[:parent.pathlen] + last := it.stack[len(it.stack)-1] + it.path = it.path[:last.pathlen] + it.stack[len(it.stack)-1] = nil it.stack = it.stack[:len(it.stack)-1] } diff --git a/trie/iterator_test.go b/trie/iterator_test.go index 95cafdd3bd..1ebd6a1131 100644 --- a/trie/iterator_test.go +++ b/trie/iterator_test.go @@ -29,6 +29,19 @@ import ( "github.com/ethereum/go-ethereum/ethdb/memorydb" ) +func TestEmptyIterator(t *testing.T) { + trie := newEmpty() + iter := trie.NodeIterator(nil) + + seen := make(map[string]struct{}) + for iter.Next(true) { + seen[string(iter.Path())] = struct{}{} + } + if len(seen) != 0 { + t.Fatal("Unexpected trie node iterated") + } +} + func TestIterator(t *testing.T) { trie := newEmpty() vals := []struct{ k, v string }{ diff --git a/trie/node.go b/trie/node.go index f4055e779a..bf3f024bb8 100644 --- a/trie/node.go +++ b/trie/node.go @@ -28,8 +28,9 @@ import ( var indices = []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "[17]"} type node interface { - fstring(string) string cache() (hashNode, bool) + encode(w rlp.EncoderBuffer) + fstring(string) string } type ( @@ -52,16 +53,9 @@ var nilValueNode = valueNode(nil) // EncodeRLP encodes a full node into the consensus RLP format. func (n *fullNode) EncodeRLP(w io.Writer) error { - var nodes [17]node - - for i, child := range &n.Children { - if child != nil { - nodes[i] = child - } else { - nodes[i] = nilValueNode - } - } - return rlp.Encode(w, nodes) + eb := rlp.NewEncoderBuffer(w) + n.encode(eb) + return eb.Flush() } func (n *fullNode) copy() *fullNode { copy := *n; return © } diff --git a/trie/node_enc.go b/trie/node_enc.go new file mode 100644 index 0000000000..cade35b707 --- /dev/null +++ b/trie/node_enc.go @@ -0,0 +1,87 @@ +// Copyright 2022 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package trie + +import ( + "github.com/ethereum/go-ethereum/rlp" +) + +func nodeToBytes(n node) []byte { + w := rlp.NewEncoderBuffer(nil) + n.encode(w) + result := w.ToBytes() + w.Flush() + return result +} + +func (n *fullNode) encode(w rlp.EncoderBuffer) { + offset := w.List() + for _, c := range n.Children { + if c != nil { + c.encode(w) + } else { + w.Write(rlp.EmptyString) + } + } + w.ListEnd(offset) +} + +func (n *shortNode) encode(w rlp.EncoderBuffer) { + offset := w.List() + w.WriteBytes(n.Key) + if n.Val != nil { + n.Val.encode(w) + } else { + w.Write(rlp.EmptyString) + } + w.ListEnd(offset) +} + +func (n hashNode) encode(w rlp.EncoderBuffer) { + w.WriteBytes(n) +} + +func (n valueNode) encode(w rlp.EncoderBuffer) { + w.WriteBytes(n) +} + +func (n rawFullNode) encode(w rlp.EncoderBuffer) { + offset := w.List() + for _, c := range n { + if c != nil { + c.encode(w) + } else { + w.Write(rlp.EmptyString) + } + } + w.ListEnd(offset) +} + +func (n *rawShortNode) encode(w rlp.EncoderBuffer) { + offset := w.List() + w.WriteBytes(n.Key) + if n.Val != nil { + n.Val.encode(w) + } else { + w.Write(rlp.EmptyString) + } + w.ListEnd(offset) +} + +func (n rawNode) encode(w rlp.EncoderBuffer) { + w.Write(n) +} diff --git a/trie/proof.go b/trie/proof.go index 9be3b62216..88ca80b0e7 100644 --- a/trie/proof.go +++ b/trie/proof.go @@ -25,7 +25,6 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb/memorydb" "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" ) // Prove constructs a merkle proof for key. The result contains all encoded nodes @@ -79,7 +78,7 @@ func (t *Trie) Prove(key []byte, fromLevel uint, proofDb ethdb.KeyValueWriter) e if hash, ok := hn.(hashNode); ok || i == 0 { // If the node's database encoding is a hash (or is the // root node), it becomes a proof element. - enc, _ := rlp.EncodeToBytes(n) + enc := nodeToBytes(n) if !ok { hash = hasher.hashData(enc) } diff --git a/trie/stacktrie.go b/trie/stacktrie.go index 76258c3112..b38bb01b0f 100644 --- a/trie/stacktrie.go +++ b/trie/stacktrie.go @@ -28,7 +28,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" ) var ErrCommitDisabled = errors.New("no database for committing") @@ -224,6 +223,7 @@ func (st *StackTrie) insert(key, value []byte) { switch st.nodeType { case branchNode: /* Branch */ idx := int(key[0]) + // Unresolve elder siblings for i := idx - 1; i >= 0; i-- { if st.children[i] != nil { @@ -233,12 +233,14 @@ func (st *StackTrie) insert(key, value []byte) { break } } + // Add new child if st.children[idx] == nil { st.children[idx] = newLeaf(key[1:], value, st.db) } else { st.children[idx].insert(key[1:], value) } + case extNode: /* Ext */ // Compare both key chunks and see where they differ diffidx := st.getDiffIndex(key) @@ -326,10 +328,9 @@ func (st *StackTrie) insert(key, value []byte) { p = st.children[0] } - // Create the two child leaves: the one containing the - // original value and the one containing the new value - // The child leave will be hashed directly in order to - // free up some memory. + // Create the two child leaves: one containing the original + // value and another containing the new value. The child leaf + // is hashed directly in order to free up some memory. origIdx := st.key[diffidx] p.children[origIdx] = newLeaf(st.key[diffidx+1:], st.val, st.db) p.children[origIdx].hash() @@ -341,19 +342,22 @@ func (st *StackTrie) insert(key, value []byte) { // over to the children. st.key = st.key[:diffidx] st.val = nil + case emptyNode: /* Empty */ st.nodeType = leafNode st.key = key st.val = value + case hashedNode: panic("trying to insert into hash") + default: panic("invalid type") } } -// hash() hashes the node 'st' and converts it into 'hashedNode', if possible. -// Possible outcomes: +// hash converts st into a 'hashedNode', if possible. Possible outcomes: +// // 1. The rlp-encoded value was >= 32 bytes: // - Then the 32-byte `hash` will be accessible in `st.val`. // - And the 'st.type' will be 'hashedNode' @@ -361,119 +365,116 @@ func (st *StackTrie) insert(key, value []byte) { // - Then the <32 byte rlp-encoded value will be accessible in 'st.val'. // - And the 'st.type' will be 'hashedNode' AGAIN // -// This method will also: -// set 'st.type' to hashedNode -// clear 'st.key' +// This method also sets 'st.type' to hashedNode, and clears 'st.key'. func (st *StackTrie) hash() { - /* Shortcut if node is already hashed */ - if st.nodeType == hashedNode { - return - } - // The 'hasher' is taken from a pool, but we don't actually - // claim an instance until all children are done with their hashing, - // and we actually need one - var h *hasher + h := newHasher(false) + defer returnHasherToPool(h) + + st.hashRec(h) +} + +func (st *StackTrie) hashRec(hasher *hasher) { + // The switch below sets this to the RLP-encoding of this node. + var encodedNode []byte switch st.nodeType { + case hashedNode: + return + + case emptyNode: + st.val = emptyRoot.Bytes() + st.key = st.key[:0] + st.nodeType = hashedNode + return + case branchNode: - var nodes [17]node + var nodes rawFullNode for i, child := range st.children { if child == nil { nodes[i] = nilValueNode continue } - child.hash() + + child.hashRec(hasher) if len(child.val) < 32 { nodes[i] = rawNode(child.val) } else { nodes[i] = hashNode(child.val) } - st.children[i] = nil // Reclaim mem from subtree + + // Release child back to pool. + st.children[i] = nil returnToPool(child) } - nodes[16] = nilValueNode - h = newHasher(false) - defer returnHasherToPool(h) - h.tmp.Reset() - if err := rlp.Encode(&h.tmp, nodes); err != nil { - panic(err) - } + + nodes.encode(hasher.encbuf) + encodedNode = hasher.encodedBytes() + case extNode: - st.children[0].hash() - h = newHasher(false) - defer returnHasherToPool(h) - h.tmp.Reset() - var valuenode node + st.children[0].hashRec(hasher) + + sz := hexToCompactInPlace(st.key) + n := rawShortNode{Key: st.key[:sz]} if len(st.children[0].val) < 32 { - valuenode = rawNode(st.children[0].val) + n.Val = rawNode(st.children[0].val) } else { - valuenode = hashNode(st.children[0].val) - } - n := struct { - Key []byte - Val node - }{ - Key: hexToCompact(st.key), - Val: valuenode, - } - if err := rlp.Encode(&h.tmp, n); err != nil { - panic(err) + n.Val = hashNode(st.children[0].val) } + + n.encode(hasher.encbuf) + encodedNode = hasher.encodedBytes() + + // Release child back to pool. returnToPool(st.children[0]) - st.children[0] = nil // Reclaim mem from subtree + st.children[0] = nil + case leafNode: - h = newHasher(false) - defer returnHasherToPool(h) - h.tmp.Reset() st.key = append(st.key, byte(16)) sz := hexToCompactInPlace(st.key) - n := [][]byte{st.key[:sz], st.val} - if err := rlp.Encode(&h.tmp, n); err != nil { - panic(err) - } - case emptyNode: - st.val = emptyRoot.Bytes() - st.key = st.key[:0] - st.nodeType = hashedNode - return + n := rawShortNode{Key: st.key[:sz], Val: valueNode(st.val)} + + n.encode(hasher.encbuf) + encodedNode = hasher.encodedBytes() + default: - panic("Invalid node type") + panic("invalid node type") } - st.key = st.key[:0] + st.nodeType = hashedNode - if len(h.tmp) < 32 { - st.val = common.CopyBytes(h.tmp) + st.key = st.key[:0] + if len(encodedNode) < 32 { + st.val = common.CopyBytes(encodedNode) return } + // Write the hash to the 'val'. We allocate a new val here to not mutate // input values - st.val = make([]byte, 32) - h.sha.Reset() - h.sha.Write(h.tmp) - h.sha.Read(st.val) + st.val = hasher.hashData(encodedNode) if st.db != nil { // TODO! Is it safe to Put the slice here? // Do all db implementations copy the value provided? - st.db.Put(st.val, h.tmp) + st.db.Put(st.val, encodedNode) } } -// Hash returns the hash of the current node +// Hash returns the hash of the current node. func (st *StackTrie) Hash() (h common.Hash) { - st.hash() - if len(st.val) != 32 { - // If the node's RLP isn't 32 bytes long, the node will not - // be hashed, and instead contain the rlp-encoding of the - // node. For the top level node, we need to force the hashing. - ret := make([]byte, 32) - h := newHasher(false) - defer returnHasherToPool(h) - h.sha.Reset() - h.sha.Write(st.val) - h.sha.Read(ret) - return common.BytesToHash(ret) + hasher := newHasher(false) + defer returnHasherToPool(hasher) + + st.hashRec(hasher) + if len(st.val) == 32 { + copy(h[:], st.val) + return h } - return common.BytesToHash(st.val) + + // If the node's RLP isn't 32 bytes long, the node will not + // be hashed, and instead contain the rlp-encoding of the + // node. For the top level node, we need to force the hashing. + hasher.sha.Reset() + hasher.sha.Write(st.val) + hasher.sha.Read(h[:]) + return h } // Commit will firstly hash the entrie trie if it's still not hashed @@ -483,23 +484,26 @@ func (st *StackTrie) Hash() (h common.Hash) { // // The associated database is expected, otherwise the whole commit // functionality should be disabled. -func (st *StackTrie) Commit() (common.Hash, error) { +func (st *StackTrie) Commit() (h common.Hash, err error) { if st.db == nil { return common.Hash{}, ErrCommitDisabled } - st.hash() - if len(st.val) != 32 { - // If the node's RLP isn't 32 bytes long, the node will not - // be hashed (and committed), and instead contain the rlp-encoding of the - // node. For the top level node, we need to force the hashing+commit. - ret := make([]byte, 32) - h := newHasher(false) - defer returnHasherToPool(h) - h.sha.Reset() - h.sha.Write(st.val) - h.sha.Read(ret) - st.db.Put(ret, st.val) - return common.BytesToHash(ret), nil + + hasher := newHasher(false) + defer returnHasherToPool(hasher) + + st.hashRec(hasher) + if len(st.val) == 32 { + copy(h[:], st.val) + return h, nil } - return common.BytesToHash(st.val), nil + + // If the node's RLP isn't 32 bytes long, the node will not + // be hashed (and committed), and instead contain the rlp-encoding of the + // node. For the top level node, we need to force the hashing+commit. + hasher.sha.Reset() + hasher.sha.Write(st.val) + hasher.sha.Read(h[:]) + st.db.Put(h[:], st.val) + return h, nil } diff --git a/trie/trie_test.go b/trie/trie_test.go index be0df8a544..20944bf8f5 100644 --- a/trie/trie_test.go +++ b/trie/trie_test.go @@ -414,8 +414,9 @@ func runRandTest(rt randTest) bool { values := make(map[string]string) // tracks content of the trie for i, step := range rt { - fmt.Printf("{op: %d, key: common.Hex2Bytes(\"%x\"), value: common.Hex2Bytes(\"%x\")}, // step %d\n", - step.op, step.key, step.value, i) + // fmt.Printf("{op: %d, key: common.Hex2Bytes(\"%x\"), value: common.Hex2Bytes(\"%x\")}, // step %d\n", + // step.op, step.key, step.value, i) + switch step.op { case opUpdate: tr.Update(step.key, step.value) @@ -884,7 +885,8 @@ func TestCommitSequenceSmallRoot(t *testing.T) { if stRoot != root { t.Fatalf("root wrong, got %x exp %x", stRoot, root) } - fmt.Printf("root: %x\n", stRoot) + + t.Logf("root: %x\n", stRoot) if got, exp := stackTrieSponge.sponge.Sum(nil), s.sponge.Sum(nil); !bytes.Equal(got, exp) { t.Fatalf("test, disk write sequence wrong:\ngot %x exp %x\n", got, exp) }