From d9140f284196db67a4ea5a528c81a20c387d9211 Mon Sep 17 00:00:00 2001 From: pingke Date: Thu, 4 May 2023 18:47:56 +0800 Subject: [PATCH 1/5] eth storage miner part 0 changes --- cmd/sstorage/main.go | 50 ++++++- core/blockchain.go | 53 +++++-- core/genesis.go | 16 +- core/vm/contracts.go | 20 ++- core/vm/contracts_test.go | 6 +- eth/backend.go | 3 +- eth/downloader/downloader.go | 9 +- eth/protocols/sstorage/sync.go | 220 ++++++++++++++++++++++------ eth/protocols/sstorage/sync_test.go | 138 +++++++++-------- params/config.go | 2 +- sstorage/data_file.go | 31 +++- sstorage/data_shard.go | 54 +++++-- sstorage/merklelib.go | 129 ++++++++++++++++ sstorage/shard_config.go | 26 +--- sstorage/shard_manager.go | 74 ++++++++-- 15 files changed, 640 insertions(+), 191 deletions(-) create mode 100644 sstorage/merklelib.go diff --git a/cmd/sstorage/main.go b/cmd/sstorage/main.go index 998d00004a80..58e8652f8f1a 100644 --- a/cmd/sstorage/main.go +++ b/cmd/sstorage/main.go @@ -2,6 +2,7 @@ package main import ( "bufio" + "bytes" "fmt" "io" "os" @@ -15,7 +16,7 @@ import ( ) var ( - chunkLen *uint64 + kvLen *uint64 miner *string filenames *[]string @@ -62,8 +63,14 @@ var ShardWriteCmd = &cobra.Command{ Run: runShardWrite, } +var CheckEmtpyKVsCmd = &cobra.Command{ + Use: "check_empty_kvs", + Short: "check empty Kvs have been filled", + Run: runCheckEmtpyKVs, +} + func init() { - chunkLen = CreateCmd.Flags().Uint64("len", 0, "Chunk idx len to create") + kvLen = CreateCmd.Flags().Uint64("kv_len", 0, "kv idx len to create") filenames = rootCmd.PersistentFlags().StringArray("filename", []string{}, "Data filename") miner = rootCmd.PersistentFlags().String("miner", "", "miner address") @@ -110,9 +117,9 @@ func runCreate(cmd *cobra.Command, args []string) { } minerAddr := common.HexToAddress(*miner) - log.Info("Creating data file", "chunkIdx", *chunkIdx, "chunkLen", *chunkLen, "miner", minerAddr, "encodeType", *encodeType) + log.Info("Creating data file", "kvIdx", *kvIdx, "kvLen", *kvLen, "miner", minerAddr, "encodeType", *encodeType) - _, err := sstorage.Create((*filenames)[0], *chunkIdx, *chunkLen, 0, *kvSize, *encodeType, minerAddr) + _, err := sstorage.Create((*filenames)[0], *kvIdx, *kvLen, 0, *kvSize, *encodeType, minerAddr) if err != nil { log.Crit("create failed", "error", err) } @@ -231,6 +238,40 @@ func runShardWrite(cmd *cobra.Command, args []string) { log.Info("Write value", "kvIdx", *kvIdx, "bytes", len(bs)) } +func runCheckEmtpyKVs(cmd *cobra.Command, args []string) { + setupLogger() + + if len(*filenames) != 1 { + log.Crit("must provide a filename") + } + + var err error + var df *sstorage.DataFile + df, err = sstorage.OpenDataFile((*filenames)[0]) + if err != nil { + log.Crit("open failed", "error", err) + } + + commit := common.Hash{} + chunkPerKv := df.KVSize() / sstorage.CHUNK_SIZE + startChunkIdx := (*kvIdx) * chunkPerKv + log.Info("start to verify", "kvidx", *kvIdx, "startChunkIdx", startChunkIdx, "EndChunkIdx", df.EndChunkIdx()) + for chunkIdx := startChunkIdx; chunkIdx < df.EndChunkIdx(); chunkIdx++ { + maskedChunkData, err := df.Read(chunkIdx, int(sstorage.CHUNK_SIZE)) + if err != nil { + log.Warn("read sstorage file failed", "chunkidx", chunkIdx, "error", err) + } + encodeKey := sstorage.CalcEncodeKey(commit, chunkIdx, df.Miner()) + unmaskedChunk := sstorage.DecodeChunk(maskedChunkData, 2, encodeKey) + if bytes.Compare(unmaskedChunk, make([]byte, sstorage.CHUNK_SIZE)) != 0 { + log.Warn("verify empty chunk", "chunkidx", chunkIdx) + } + if chunkIdx%(chunkPerKv*100) == 0 { + log.Info("verify verify state", "chunkidx", chunkIdx) + } + } +} + // rootCmd represents the base command when called without any subcommands var rootCmd = &cobra.Command{ Use: "sstorage", @@ -243,6 +284,7 @@ func init() { rootCmd.AddCommand(ChunkWriteCmd) rootCmd.AddCommand(ShardReadCmd) rootCmd.AddCommand(ShardWriteCmd) + rootCmd.AddCommand(CheckEmtpyKVsCmd) } func main() { diff --git a/core/blockchain.go b/core/blockchain.go index 515cc27478d8..5d6f49d52d60 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -50,7 +50,6 @@ import ( "github.com/ethereum/go-ethereum/trie" lru "github.com/hashicorp/golang-lru" "github.com/holiman/uint256" - "golang.org/x/crypto/sha3" ) var ( @@ -2410,13 +2409,7 @@ func getSlotHash(slotIdx uint64, key common.Hash) common.Hash { slotdata := slot[:] data := append(keydata, slotdata...) - hasher := sha3.NewLegacyKeccak256().(crypto.KeccakState) - hasher.Write(data) - - hashRes := common.Hash{} - hasher.Read(hashRes[:]) - - return hashRes + return crypto.Keccak256Hash(data) } // GetSstorageMetadata get sstorage metadata for a given kv (specified by contract address and index) @@ -2465,20 +2458,48 @@ func VerifyKV(sm *sstorage.ShardManager, idx uint64, val []byte, meta *SstorageM } if meta.KVSize != uint64(len(data)) { - return nil, fmt.Errorf("verifyKV fail: size error; Data size: %d; MetaHash KVSize: %d", len(val), meta.KVSize) + return nil, fmt.Errorf("verifyKV fail: size error; Data size: %d; MetaHash kvSize: %d", len(val), meta.KVSize) } data = d } - hash := crypto.Keccak256Hash(data) - if !bytes.Equal(hash[:24], meta.HashInMeta) { - return nil, fmt.Errorf("verifyKV fail: size error; Data hash: %s; MetaHash hash (24): %s", - common.Bytes2Hex(hash[:24]), common.Bytes2Hex(meta.HashInMeta)) + root := sstorage.MerkleRootWithMinTree(data) + if !bytes.Equal(root[:24], meta.HashInMeta) { + return nil, fmt.Errorf("verifyKV fail: Data hash: %s; MetaHash hash (24): %s, providerAddr %s, data %s", + common.Bytes2Hex(root[:24]), common.Bytes2Hex(meta.HashInMeta), providerAddr.Hex(), common.Bytes2Hex(data)) } return data, nil } +func (bc *BlockChain) FillSstorWithEmptyKV(contract common.Address, start, limit uint64) (uint64, error) { + sm := sstorage.ContractToShardManager[contract] + if sm == nil { + return start, fmt.Errorf("kv verify fail: contract not support, contract: %s", contract.Hex()) + } + + // bc.chainmu.TryLock() + // defer bc.chainmu.Unlock() + + empty := make([]byte, 0) + lastKvIdx, err := bc.GetSstorageLastKvIdx(contract) + if err != nil { + return start, fmt.Errorf("get lastKvIdx for FillEmptyKV fail, err: %s", err.Error()) + } + for idx := start; idx <= limit; idx++ { + if lastKvIdx > idx { + continue + } + _, err = sm.TryWrite(idx, empty, common.Hash{}) + if err != nil { + err = fmt.Errorf("write empty to kv file fail, index: %d; error: %s", idx, err.Error()) + return idx, err + } + } + + return limit + 1, nil +} + // VerifyAndWriteKV verify a list of raw KV data using the metadata saved in the local level DB and write successfully verified // KVs to the sstorage file. And return the inserted KV index list. func (bc *BlockChain) VerifyAndWriteKV(contract common.Address, data map[uint64][]byte, providerAddr common.Address) (uint64, uint64, []uint64, error) { @@ -2535,13 +2556,13 @@ func (bc *BlockChain) VerifyAndWriteKV(contract common.Address, data map[uint64] if metaHash != vkv.MetaHash { // TODO: verify the storage data again before returning error - log.Warn("verify vkv fail", "error", err) + log.Warn("verify vkv fail", "kvIdx", vkv.Idx, "kvHash", common.Bytes2Hex(meta.HashInMeta), "error", err) continue } - success, err := sm.TryWrite(vkv.Idx, vkv.Data, vkv.MetaHash) + success, err := sm.TryWrite(vkv.Idx, vkv.Data, common.BytesToHash(meta.HashInMeta)) if err != nil { - log.Warn("write kv fail", "error", err) + log.Warn("write kv fail", "kvIdx", vkv.Idx, "kvHash", common.Bytes2Hex(meta.HashInMeta), "error", err) } if success { inserted = append(inserted, vkv.Idx) diff --git a/core/genesis.go b/core/genesis.go index 8b1893a1766a..1f38121385ff 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -146,10 +146,10 @@ func (e *GenesisMismatchError) Error() string { // SetupGenesisBlock writes or updates the genesis block in db. // The block that will be used is: // -// genesis == nil genesis != nil -// +------------------------------------------ -// db has no genesis | main-net default | genesis -// db has genesis | from DB | genesis (if compatible) +// genesis == nil genesis != nil +// +------------------------------------------ +// db has no genesis | main-net default | genesis +// db has genesis | from DB | genesis (if compatible) // // The stored chain configuration will be updated if it is compatible (i.e. does not // specify a fork block below the local head block). In case of a conflict, the @@ -441,10 +441,10 @@ func DefaultWeb3QTestnetGenesisBlock() *Genesis { common.HexToAddress("0x5C935469C5592Aeeac3372e922d9bCEabDF8830d"): {Balance: new(big.Int).Mul(big.NewInt(1000000000000000000), big.NewInt(1000000000))}, // 1e9 Ether }, NextValidators: []common.Address{ - common.HexToAddress("0x2cff0b8e36522eba76f6f5c328d58581243882e4"), - common.HexToAddress("0x959994471dee37411f579dd2820a8743cba20f46"), - common.HexToAddress("0x977cfc676bb06daed7ddfa7711bcfe8d50c93081"), - common.HexToAddress("0xcd21538af6e33ff6fcf1e2ca20f771413004cfd3"), + common.HexToAddress("0xf3025bac5d2e9a179f78e0295a0dd0cd74003e16"), + common.HexToAddress("0x9b30603c22474755c0917254b3e86e78646c87de"), + common.HexToAddress("0x6562837cbadff8ccdfad90a5e40d44bdab561dad"), + common.HexToAddress("0x46a1a4832a046cf7a6d9fc862c155b2c90196dde"), }, NextValidatorPowers: []uint64{1, 1, 1, 1}, } diff --git a/core/vm/contracts.go b/core/vm/contracts.go index d7a34788df68..ea219822027f 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -17,6 +17,7 @@ package vm import ( + "bytes" "context" "crypto/sha256" "encoding/binary" @@ -678,7 +679,7 @@ var ( systemContracts = map[common.Address][]byte{ // Get the url of PrecompileManager: https://github.com/ethstorage/storage-contracts/blob/developing/contracts/DecentralizedKVDaggerHashimoto.sol // contract at 0x0000000000000000000000000000000003330001 is complied DecentralizedKVDaggerHashimoto() + 0.8.16 solc (enable optimized) - common.HexToAddress("0x0000000000000000000000000000000003330001"): common.Hex2Bytes("6080604052600436106102675760003560e01c806378e9792511610144578063b2aebe88116100b6578063d32897131161007a578063d328971314610962578063d4044b3314610996578063dca00511146109ca578063dd7e57d4146109ed578063df80ca5514610a04578063e7a84c4614610a1957600080fd5b8063b2aebe881461087f578063bf8b887c1461089f578063c4a942cb146108da578063c5d3490c1461090e578063ca2af6231461094257600080fd5b8063919c6eae11610108578063919c6eae1461074157806395bc267314610775578063a097365f14610795578063a4a8435e146107c9578063afd5644d146107fd578063b1e1a3441461085f57600080fd5b806378e9792514610675578063812d2e72146106a95780638612af34146106dd5780638891ce9c1461070a578063896b49911461072a57600080fd5b806349bdd6f5116101dd5780636d951bc5116101a15780636d951bc5146105295780636da6d51e1461055d57806372f2b9dc1461058c578063739b482f146105a657806373e8b3d4146105da578063749cf2821461064857600080fd5b806349bdd6f51461044d5780634e86235e1461046d57806354b02ba4146104a15780636620dfc5146104d55780636cece5f81461050957600080fd5b806327c845dc1161022f57806327c845dc146102d357806328de3c9b1461033a578063390df0b61461039e5780633cb2fecc146103d2578063429dd7ad1461040657806344e77d991461043a57600080fd5b80630fce307b1461026c57806315853983146102b35780631aff59e2146102d55780631ccbc6da146102f5578063258ae5821461030a575b600080fd5b34801561027857600080fd5b506102a07fa8bae11751799de4dbe638406c5c9642c0e791f2a65e852a05ba4fdf0d88e3e681565b6040519081526020015b60405180910390f35b3480156102bf57600080fd5b506102d36102ce3660046129c1565b610a30565b005b3480156102e157600080fd5b506102d36102f0366004612acf565b610a49565b34801561030157600080fd5b506102a0610b3f565b34801561031657600080fd5b5061032a610325366004612af1565b610b4f565b60405190151581526020016102aa565b34801561034657600080fd5b5061037e610355366004612b37565b600360208190526000918252604090912080546001820154600283015492909301549092919084565b6040805194855260208501939093529183015260608201526080016102aa565b3480156103aa57600080fd5b506102a07fa8bae11751799de4dbe638406c5c9642c0e791f2a65e852a05ba4fdf0d88e3e681565b3480156103de57600080fd5b506102a07f000000000000000000000000000000000000000000000000000000000000000081565b34801561041257600080fd5b506000546104249064ffffffffff1681565b60405164ffffffffff90911681526020016102aa565b6102d3610448366004612af1565b610c7b565b34801561045957600080fd5b506102d3610468366004612b50565b610eab565b34801561047957600080fd5b506102a07f000000000000000000000000000000000000000000000000000000000000000c81565b3480156104ad57600080fd5b506102a07f000000000000000000000000000000000000000000000000000000000000002881565b3480156104e157600080fd5b506102a07f000000000000000000000000000000000000000000000000000000000000000081565b34801561051557600080fd5b506102d3610524366004612b95565b6110d9565b34801561053557600080fd5b506102a07f000000000000000000000000000000000000000000000000000000000000006481565b34801561056957600080fd5b506105746203330281565b6040516001600160a01b0390911681526020016102aa565b34801561059857600080fd5b5060045461032a9060ff1681565b3480156105b257600080fd5b506102a07f000000000000000000000000000000000000000000000000000000000000040081565b3480156105e657600080fd5b5061032a6105f5366004612b37565b60408051336020808301919091528183019390935281518082038301815260609091018252805190830120600090815260019092529081902054600160401b9004901b67ffffffffffffffff1916151590565b34801561065457600080fd5b50610668610663366004612beb565b6111a3565b6040516102aa9190612c67565b34801561068157600080fd5b506102a07f000000000000000000000000000000000000000000000000000000000000000181565b3480156106b557600080fd5b506102a07f000000000000000000000000000000000000000000000000000000000000012c81565b3480156106e957600080fd5b506106f2600281565b6040516001600160401b0390911681526020016102aa565b34801561071657600080fd5b50610668610725366004612c7a565b6112b4565b34801561073657600080fd5b506105746203330581565b34801561074d57600080fd5b506102a07f00000000000000000000000000000000000000000000000000000000000003e881565b34801561078157600080fd5b506102d3610790366004612b37565b6113ad565b3480156107a157600080fd5b506102a07f000000000000000000000000000000000000000000000000000000000000100081565b3480156107d557600080fd5b506102a07f000000000000000000000000000000000000000000000000000000000000000081565b34801561080957600080fd5b506102a0610818366004612b37565b6040805133602080830191909152818301939093528151808203830181526060909101825280519083012060009081526001909252902054600160281b900462ffffff1690565b34801561086b57600080fd5b5061032a61087a366004612cb3565b6113ba565b34801561088b57600080fd5b506102d361089a366004612acf565b6115dc565b3480156108ab57600080fd5b506108cc6108ba366004612af1565b80519181526020820181209181529091565b6040516102aa929190612d86565b3480156108e657600080fd5b506102a07f000000000000000000000000000000000000000000000000000000000000100081565b34801561091a57600080fd5b506102a07f000000000000000000000000000000000000000000000000000000000000000681565b34801561094e57600080fd5b5061066861095d366004612d9f565b6116a3565b34801561096e57600080fd5b506102a07f000000000000000000000000000000000000000000000000000000000000001081565b3480156109a257600080fd5b506102a07f000000000000000000000000000000000000000000000000000000000000001281565b3480156109d657600080fd5b506106686109e5366004612af1565b606092915050565b3480156109f957600080fd5b506105746203330381565b348015610a1057600080fd5b506102a0611789565b348015610a2557600080fd5b506105746203330481565b610a4042888888888888886117cd565b50505050505050565b60045460ff1615610a965760405162461bcd60e51b8152602060048201526012602482015271185b1c9958591e481a5b9a5d081cda185c9960721b60448201526064015b60405180910390fd5b6004805460ff1916600190811790915560036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92f008390557f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff8290556000527fa15bc60c955c405d20d9149c709e2460f1c2d9a497496a7f46004d1772c3054d919091557fa15bc60c955c405d20d9149c709e2460f1c2d9a497496a7f46004d1772c3054c55565b6000610b4a426118ea565b905090565b60408051336020820152908101839052600090819060600160408051808303601f1901815282825280516020918201206000818152600183528381206060860185525464ffffffffff81168652600160281b810462ffffff1693860193909352600160401b909204831b67ffffffffffffffff1916928401839052935003610c085760405162461bcd60e51b815260206004820152600c60248201526b1add881b9bdd08195e1a5cdd60a21b6044820152606401610a8d565b8351816020015162ffffff1614610c2457600092505050610c73565b6000610c50857f000000000000000000000000000000000000000000000000000000000000100061193f565b9050806001600160401b03191682604001516001600160401b0319161493505050505b92915050565b565b7f000000000000000000000000000000000000000000000000000000000000100081511115610cdd5760405162461bcd60e51b815260206004820152600e60248201526d6461746120746f6f206c6172676560901b6044820152606401610a8d565b610ce5611b70565b6040805133602082015290810183905260009060600160408051808303601f1901815282825280516020918201206000818152600183528381206060860185525464ffffffffff81168652600160281b810462ffffff1693860193909352600160401b909204831b67ffffffffffffffff1916928401839052935003610dfa57610d6d610b3f565b341015610db15760405162461bcd60e51b81526020600482015260126024820152711b9bdd08195b9bdd59da081c185e5b595b9d60721b6044820152606401610a8d565b6000805464ffffffffff90811680845282526002602052604082208490559054610ddd91166001612e16565b6000805464ffffffffff191664ffffffffff929092169190911790555b825162ffffff166020820152610e30837f000000000000000000000000000000000000000000000000000000000000100061193f565b67ffffffffffffffff19908116604080840191825260008581526001602090815290829020855181549287015194519384901c600160401b0262ffffff909516600160281b029290951664ffffffffff909516948517919091176001600160401b031692909217909155610ea59190856110d9565b50505050565b6040805133602082015290810183905260009060600160408051808303601f1901815282825280516020918201206000818152600183528381206060860185525464ffffffffff8116808752600160281b820462ffffff1694870194909452600160401b9004841b67ffffffffffffffff191693850184905290945090919003610f665760405162461bcd60e51b815260206004820152600c60248201526b1add881b9bdd08195e1a5cdd60a21b6044820152606401610a8d565b6040805160608101825260008082526020808301828152838501838152888452600192839052858420945185549251915190961c600160401b0262ffffff91909116600160281b0267ffffffffffffffff199290921664ffffffffff96871617919091176001600160401b031617909255805490926002928492610fea9216612e3b565b64ffffffffff908116825260208083019390935260409182016000908120548683168083526002808752858420839055828452600196879052948320805464ffffffffff191690911790558154909550909384926110489216612e3b565b64ffffffffff9081168252602082019290925260400160009081209290925590546110769160019116612e3b565b6000805464ffffffffff191664ffffffffff92831690811790915561109c9184166115dc565b846001600160a01b03166108fc6110b1610b3f565b6040518115909202916000818181858888f19350505050158015610a40573d6000803e3d6000fd5b604080519083901c9060009062033302906110fc90879085908790602001612e59565b60408051601f198184030181529082905261111691612e81565b6000604051808303816000865af19150503d8060008114611153576040519150601f19603f3d011682016040523d82523d6000602084013e611158565b606091505b505090508061119c5760405162461bcd60e51b815260206004820152601060248201526f6661696c656420746f2070757452617760801b6044820152606401610a8d565b5050505050565b6060816000036111c257506040805160008152602081019091526112ad565b6040805133602082015290810185905260009060600160408051808303601f1901815282825280516020918201206000818152600183528390206060850184525464ffffffffff81168552600160281b810462ffffff16928501839052600160401b9004831b67ffffffffffffffff191692840192909252909250851061125b57505060408051600081526020810190915290506112ad565b602081015162ffffff1661126f8686612e9d565b111561128d5784816020015162ffffff1661128a9190612eb0565b93505b6112a88160400151826000015164ffffffffff1687876112b4565b925050505b9392505050565b6040805185821c6020820181905291810185905260608082018590526080820184905291906000908190620333039060a00160408051601f198184030181529082905261130091612e81565b600060405180830381855afa9150503d806000811461133b576040519150601f19603f3d011682016040523d82523d6000602084013e611340565b606091505b50915091508161138b5760405162461bcd60e51b81526020600482015260166024820152756661696c656420746f2073797374656d47657452617760501b6044820152606401610a8d565b8080602001905181019061139f9190612ec3565b93505050505b949350505050565b6113b78133610eab565b50565b600060017f00000000000000000000000000000000000000000000000000000000000000001b816113eb8288612f46565b90506000866020015162ffffff167f0000000000000000000000000000000000000000000000000000000000001000836114259190612f5a565b1061145e577fa8bae11751799de4dbe638406c5c9642c0e791f2a65e852a05ba4fdf0d88e3e685805190602001201493505050506113a5565b817f0000000000000000000000000000000000000000000000000000000000001000600189602001516114919190612f79565b62ffffff166114a09190612f95565b036115a35760006114d17f000000000000000000000000000000000000000000000000000000000000100084612f5a565b886020015162ffffff166114e59190612eb0565b6020870181902092509050600061151c827f0000000000000000000000000000000000000000000000000000000000001000612eb0565b9050801561159c576000816001600160401b0381111561153e5761153e6127ce565b6040519080825280601f01601f191660200182016040528015611568576020820181803683370190505b5090506000808360208401209150838560208c0101209050808214611598576000985050505050505050506113a5565b5050505b50506115ac565b50835160208501205b60006115b9828489611b79565b604089015167ffffffffffffffff19918216911614945050505050949350505050565b6040805160208101849052908101829052600090620333059060600160408051601f198184030181529082905261161291612e81565b6000604051808303816000865af19150503d806000811461164f576040519150601f19603f3d011682016040523d82523d6000602084013e611654565b606091505b505090508061169e5760405162461bcd60e51b81526020600482015260166024820152756661696c656420746f2073797374656d50757452617760501b6044820152606401610a8d565b505050565b6040805160609185901c90600090819062033304906116cf906002908b9087908b908b90602001612fa9565b60408051601f19818403018152908290526116e991612e81565b600060405180830381855afa9150503d8060008114611724576040519150601f19603f3d011682016040523d82523d6000602084013e611729565b606091505b50915091508161138b5760405162461bcd60e51b815260206004820152602560248201527f6661696c656420746f2073797374656d556e6d61736b4368756e6b57697468456044820152640e8d0c2e6d60db1b6064820152608401610a8d565b600080546117c19064ffffffffff167f00000000000000000000000000000000000000000000000000000000000000061c6001612e16565b64ffffffffff16905090565b878411156118115760405162461bcd60e51b81526020600482015260116024820152706d696e6564547320746f6f206c6172676560781b6044820152606401610a8d565b6001861b600080806118248b858a611cad565b604080516020808201939093526001600160a01b038e1681830152606081018d905260808082018d90528251808303909101815260a090910190915280519101209194509250905061187a8b8b838c8a8a611e97565b9050600061188a84600019612f95565b9050808211156118cd5760405162461bcd60e51b815260206004820152600e60248201526d0c8d2cccc40dcdee840dac2e8c6d60931b6044820152606401610a8d565b506118dc8b858b8b8686612280565b505050505050505050505050565b6000610c737f000000000000000000000000000000000000000000000000000000000000000061193a7f000000000000000000000000000000000000000000000000000000000000000185612eb0565b612422565b6000825160000361195257506000610c73565b60008260018486516119649190612e9d565b61196e9190612eb0565b6119789190612f95565b9050600060018211156119935761198e82612463565b611996565b60015b90506000816001600160401b038111156119b2576119b26127ce565b6040519080825280602002602001820160405280156119db578160200160208202803683370190505b50905060005b82811015611a61576000806119f68884612f5a565b905088518110611a07575050611a61565b6000818a51611a169190612eb0565b9050888110611a225750875b808260208c010120925082858581518110611a3f57611a3f612ff6565b6020026020010181815250505050508080611a599061300c565b9150506119e1565b508192505b82600114611b4a5760005b611a7c600285612f95565b811015611b375781611a8f826002612f5a565b81518110611a9f57611a9f612ff6565b602002602001015182826002611ab59190612f5a565b611ac0906001612e9d565b81518110611ad057611ad0612ff6565b6020026020010151604051602001611af2929190918252602082015260400190565b60405160208183030381529060405280519060200120828281518110611b1a57611b1a612ff6565b602090810291909101015280611b2f8161300c565b915050611a71565b50611b43600284612f95565b9250611a66565b80600081518110611b5d57611b5d612ff6565b6020026020010151935050505092915050565b610c79426124a0565b805160009084906001811b8510611bc65760405162461bcd60e51b81526020600482015260116024820152706368756e6b4964206f766572666c6f777360781b6044820152606401610a8d565b60005b81811015611ca257611bdc600287612f46565b600003611c355782858281518110611bf657611bf6612ff6565b6020026020010151604051602001611c18929190918252602082015260400190565b604051602081830303815290604052805190602001209250611c83565b848181518110611c4757611c47612ff6565b602002602001015183604051602001611c6a929190918252602082015260400190565b6040516020818303038152906040528051906020012092505b611c8e600287612f95565b955080611c9a8161300c565b915050611bc9565b509095945050505050565b600060606000846001600160401b03811115611ccb57611ccb6127ce565b604051908082528060200260200182016040528015611cf4578160200160208202803683370190505b50600093509150829050805b85811015611e8d576000611d148289612e9d565b6000818152600360205260409020600181015491925090871015611d6e5760405162461bcd60e51b81526020600482015260116024820152701b5a5b9959151cc81d1bdbc81cdb585b1b607a1b6044820152606401610a8d565b611dfc81887f000000000000000000000000000000000000000000000000000000000000012c7f00000000000000000000000000000000000000000000000000000000000000287f00000000000000000000000000000000000000000000000000000000000004007f0000000000000000000000000000000000000000000000000000000000000064612593565b858481518110611e0e57611e0e612ff6565b602002602001018181525050848381518110611e2c57611e2c612ff6565b602002602001015186611e3f9190612e9d565b81546040805160208101889052908101859052606081019190915290965060800160405160208183030381529060405280519060200120935050508080611e859061300c565b915050611d00565b5093509350939050565b60007f0000000000000000000000000000000000000000000000000000000000000010825114611f095760405162461bcd60e51b815260206004820152601f60248201527f6461746120767320636865636b733a206c656e677468206d69736d61746368006044820152606401610a8d565b7f0000000000000000000000000000000000000000000000000000000000000010835114611f835760405162461bcd60e51b815260206004820152602160248201527f70726f6f667320767320636865636b733a206c656e677468206d69736d6174636044820152600d60fb1b6064820152608401610a8d565b60007f0000000000000000000000000000000000000000000000000000000000000000611fd0887f0000000000000000000000000000000000000000000000000000000000000006612e9d565b611fda9190612e9d565b6001901b905060005b7f0000000000000000000000000000000000000000000000000000000000000010811015612273577f000000000000000000000000000000000000000000000000000000000000100084828151811061203e5761203e612ff6565b602002602001015151146120895760405162461bcd60e51b8152602060048201526012602482015271696e76616c69642070726f6f662073697a6560701b6044820152606401610a8d565b60006120958389612f46565b905060006120e37f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000006612e9d565b6120f0908c901b83612e9d565b7f000000000000000000000000000000000000000000000000000000000000000081901c6000818152600260209081526040808320548352600182528083208151606081018352905464ffffffffff81168252600160281b810462ffffff1693820193909352600160401b909204811b67ffffffffffffffff19169082018190528a51949550929390926121a2918691908e908d908b90811061219557612195612ff6565b60200260200101516116a3565b90506121c984838c89815181106121bb576121bb612ff6565b6020026020010151846113ba565b61220c5760405162461bcd60e51b815260206004820152601460248201527334b73b30b634b21030b1b1b2b9b990383937b7b360611b6044820152606401610a8d565b600089878151811061222057612220612ff6565b6020908102919091018101519d8e527f00000000000000000000000000000000000000000000000000000000000010009081018e209d525085945061226b935084925061300c915050565b915050611fe3565b5094979650505050505050565b60008061228b611789565b905060005b878110156123665760006122a4828b612e9d565b9050828111612353576000818152600360205260409020600181015461230e907f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000061b908a612661565b6123189086612e9d565b9450612351600360008481526020019081526020016000208989868151811061234357612343612ff6565b6020026020010151896126c0565b505b508061235e8161300c565b915050612290565b5060006127106123967f00000000000000000000000000000000000000000000000000000000000003e885612f5a565b6123a09190612f95565b905060006123ae8285612eb0565b604051909150419083156108fc029084906000818181858888f193505050501580156123de573d6000803e3d6000fd5b506040516001600160a01b0389169082156108fc029083906000818181858888f19350505050158015612415573d6000803e3d6000fd5b5050505050505050505050565b600060806124507f0000000000000000000000000000000000000000000000000000000000000000846126e4565b61245a9085612f5a565b901c9392505050565b6000612470600183612eb0565b91505b61247e600183612eb0565b82161561249957612490600183612eb0565b82169150612473565b5060011b90565b60005460017f000000000000000000000000000000000000000000000000000000000000000681901b916124dd9164ffffffffff90911690612e16565b64ffffffffff166124ee9190612f46565b6000036113b757600080547f00000000000000000000000000000000000000000000000000000000000000069061252d9064ffffffffff166001612e16565b64ffffffffff16901c60016125429190612e16565b64ffffffffff166000818152600360208190526040822060019081018690559293509161256f9084612eb0565b81526020808201929092526040908101600090812054938152600390925290205550565b6000808760010154876125a69190612eb0565b6002890154909150868210156125fd5784816125c28885612f95565b6125cd906001612eb0565b6125d79190612f5a565b6125e19190612f95565b6125eb9082612e9d565b9050838110156125f85750825b612655565b60008582600161260d8a87612f95565b6126179190612eb0565b6126219190612f5a565b61262b9190612f95565b9050816126388683612e9d565b111561264657849150612653565b6126508183612eb0565b91505b505b98975050505050505050565b60006113a5846126917f000000000000000000000000000000000000000000000000000000000000000186612eb0565b6126bb7f000000000000000000000000000000000000000000000000000000000000000186612eb0565b6126f0565b60038401546126d0906001612e9d565b600385015583556002830155600190910155565b60006112ad8383612766565b6000608061271e7f0000000000000000000000000000000000000000000000000000000000000000846126e4565b6127487f0000000000000000000000000000000000000000000000000000000000000000866126e4565b6127529190612eb0565b61275c9086612f5a565b901c949350505050565b6000600160801b5b82156112ad578260011660010361279057608061278b8583612f5a565b901c90505b608061279c8580612f5a565b901c93506127ab600284612f95565b925061276e565b80356001600160a01b03811681146127c957600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b0381118282101715612806576128066127ce565b60405290565b604051601f8201601f191681016001600160401b0381118282101715612834576128346127ce565b604052919050565b60006001600160401b03821115612855576128556127ce565b5060051b60200190565b600082601f83011261287057600080fd5b813560206128856128808361283c565b61280c565b82815260059290921b840181019181810190868411156128a457600080fd5b8286015b848110156128bf57803583529183019183016128a8565b509695505050505050565b60006001600160401b038211156128e3576128e36127ce565b50601f01601f191660200190565b600082601f83011261290257600080fd5b8135612910612880826128ca565b81815284602083860101111561292557600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261295357600080fd5b813560206129636128808361283c565b82815260059290921b8401810191818101908684111561298257600080fd5b8286015b848110156128bf5780356001600160401b038111156129a55760008081fd5b6129b38986838b01016128f1565b845250918301918301612986565b600080600080600080600060e0888a0312156129dc57600080fd5b87359650602088013595506129f3604089016127b2565b9450606088013593506080880135925060a08801356001600160401b0380821115612a1d57600080fd5b818a0191508a601f830112612a3157600080fd5b8135612a3f6128808261283c565b8082825260208201915060208360051b86010192508d831115612a6157600080fd5b602085015b83811015612a9a578481351115612a7c57600080fd5b612a8c8f6020833589010161285f565b835260209283019201612a66565b509550505060c08a0135915080821115612ab357600080fd5b50612ac08a828b01612942565b91505092959891949750929550565b60008060408385031215612ae257600080fd5b50508035926020909101359150565b60008060408385031215612b0457600080fd5b8235915060208301356001600160401b03811115612b2157600080fd5b612b2d858286016128f1565b9150509250929050565b600060208284031215612b4957600080fd5b5035919050565b60008060408385031215612b6357600080fd5b82359150612b73602084016127b2565b90509250929050565b803567ffffffffffffffff19811681146127c957600080fd5b600080600060608486031215612baa57600080fd5b83359250612bba60208501612b7c565b915060408401356001600160401b03811115612bd557600080fd5b612be1868287016128f1565b9150509250925092565b600080600060608486031215612c0057600080fd5b505081359360208301359350604090920135919050565b60005b83811015612c32578181015183820152602001612c1a565b50506000910152565b60008151808452612c53816020860160208601612c17565b601f01601f19169290920160200192915050565b6020815260006112ad6020830184612c3b565b60008060008060808587031215612c9057600080fd5b612c9985612b7c565b966020860135965060408601359560600135945092505050565b60008060008084860360c0811215612cca57600080fd5b853594506060601f1982011215612ce057600080fd5b50612ce96127e4565b602086013564ffffffffff81168114612d0157600080fd5b8152604086013562ffffff81168114612d1957600080fd5b6020820152612d2a60608701612b7c565b6040820152925060808501356001600160401b0380821115612d4b57600080fd5b612d578883890161285f565b935060a0870135915080821115612d6d57600080fd5b50612d7a878288016128f1565b91505092959194509250565b8281526040602082015260006113a56040830184612c3b565b60008060008060808587031215612db557600080fd5b84356001600160401b038082168214612dcd57600080fd5b819550612ddc60208801612b7c565b9450612dea604088016127b2565b93506060870135915080821115612d6d57600080fd5b634e487b7160e01b600052601160045260246000fd5b64ffffffffff818116838216019080821115612e3457612e34612e00565b5092915050565b64ffffffffff828116828216039080821115612e3457612e34612e00565b838152826020820152606060408201526000612e786060830184612c3b565b95945050505050565b60008251612e93818460208701612c17565b9190910192915050565b80820180821115610c7357610c73612e00565b81810381811115610c7357610c73612e00565b600060208284031215612ed557600080fd5b81516001600160401b03811115612eeb57600080fd5b8201601f81018413612efc57600080fd5b8051612f0a612880826128ca565b818152856020838501011115612f1f57600080fd5b612e78826020830160208601612c17565b634e487b7160e01b600052601260045260246000fd5b600082612f5557612f55612f30565b500690565b6000816000190483118215151615612f7457612f74612e00565b500290565b62ffffff828116828216039080821115612e3457612e34612e00565b600082612fa457612fa4612f30565b500490565b6001600160401b03868116825285166020820152604081018490526001600160a01b038316606082015260a060808201819052600090612feb90830184612c3b565b979650505050505050565b634e487b7160e01b600052603260045260246000fd5b60006001820161301e5761301e612e00565b506001019056fea2646970667358221220818e32029f91fbabb52182f57c50b99971de6a63ca4b85bf469137b3d7523f7264736f6c63430008100033"), + common.HexToAddress("0x0000000000000000000000000000000003330001"): common.Hex2Bytes("60806040526004361061025c5760003560e01c8063749cf28211610144578063b1e1a344116100b6578063d32897131161007a578063d32897131461091c578063d4044b3314610950578063dca0051114610984578063dd7e57d4146109a7578063df80ca55146109be578063e7a84c46146109d357600080fd5b8063b1e1a34414610854578063b2aebe8814610874578063c4a942cb14610894578063c5d3490c146108c8578063ca2af623146108fc57600080fd5b8063896b499111610108578063896b49911461071f578063919c6eae1461073657806395bc26731461076a578063a097365f1461078a578063a4a8435e146107be578063afd5644d146107f257600080fd5b8063749cf2821461063d57806378e979251461066a578063812d2e721461069e5780638612af34146106d25780638891ce9c146106ff57600080fd5b8063429dd7ad116101dd5780636620dfc5116101a15780636620dfc5146104e45780636cece5f8146105185780636d951bc5146105385780636da6d51e1461056c578063739b482f1461059b57806373e8b3d4146105cf57600080fd5b8063429dd7ad1461041557806344e77d991461044957806349bdd6f51461045c5780634e86235e1461047c57806354b02ba4146104b057600080fd5b8063258ae58211610224578063258ae5821461032957806327c845dc146102f257806328de3c9b14610349578063390df0b6146103ad5780633cb2fecc146103e157600080fd5b806304cbaa51146102615780630fce307b1461029057806315853983146102d25780631aff59e2146102f45780631ccbc6da14610314575b600080fd5b34801561026d57600080fd5b5060045461027b9060ff1681565b60405190151581526020015b60405180910390f35b34801561029c57600080fd5b506102c47f6387d10d3fe6d4fcb51c9f9caf0c34f88526afc3d0c6a2b80adfceeea2b4a70181565b604051908152602001610287565b3480156102de57600080fd5b506102f26102ed366004612b7d565b6109ea565b005b34801561030057600080fd5b506102f261030f366004612c8b565b610a03565b34801561032057600080fd5b506102c4610b04565b34801561033557600080fd5b5061027b610344366004612cad565b610b14565b34801561035557600080fd5b5061038d610364366004612cf3565b600360208190526000918252604090912080546001820154600283015492909301549092919084565b604080519485526020850193909352918301526060820152608001610287565b3480156103b957600080fd5b506102c47fa8bae11751799de4dbe638406c5c9642c0e791f2a65e852a05ba4fdf0d88e3e681565b3480156103ed57600080fd5b506102c47f000000000000000000000000000000000000000000000000000000000000000081565b34801561042157600080fd5b506000546104339064ffffffffff1681565b60405164ffffffffff9091168152602001610287565b6102f2610457366004612cad565b610c40565b34801561046857600080fd5b506102f2610477366004612d0c565b610e70565b34801561048857600080fd5b506102c47f000000000000000000000000000000000000000000000000000000000000001181565b3480156104bc57600080fd5b506102c47f000000000000000000000000000000000000000000000000000000000000012c81565b3480156104f057600080fd5b506102c47f000000000000000000000000000000000000000000000000000000000000000581565b34801561052457600080fd5b506102f2610533366004612d51565b61109e565b34801561054457600080fd5b506102c47f000000000000000000000000000000000000000000000000000000000000271081565b34801561057857600080fd5b506105836203330281565b6040516001600160a01b039091168152602001610287565b3480156105a757600080fd5b506102c47f000000000000000000000000000000000000000000000000000000000000040081565b3480156105db57600080fd5b5061027b6105ea366004612cf3565b60408051336020808301919091528183019390935281518082038301815260609091018252805190830120600090815260019092529081902054600160401b9004901b67ffffffffffffffff1916151590565b34801561064957600080fd5b5061065d610658366004612da7565b611168565b6040516102879190612e23565b34801561067657600080fd5b506102c47f000000000000000000000000000000000000000000000000000000000000000181565b3480156106aa57600080fd5b506102c47f000000000000000000000000000000000000000000000000000000000000012c81565b3480156106de57600080fd5b506106e7600281565b6040516001600160401b039091168152602001610287565b34801561070b57600080fd5b5061065d61071a366004612e36565b611279565b34801561072b57600080fd5b506105836203330581565b34801561074257600080fd5b506102c47f00000000000000000000000000000000000000000000000000000000000003e881565b34801561077657600080fd5b506102f2610785366004612cf3565b611372565b34801561079657600080fd5b506102c47f000000000000000000000000000000000000000000000000000000000002000081565b3480156107ca57600080fd5b506102c47f000000000000000000000000000000000000000000000000000000000000000081565b3480156107fe57600080fd5b506102c461080d366004612cf3565b6040805133602080830191909152818301939093528151808203830181526060909101825280519083012060009081526001909252902054600160281b900462ffffff1690565b34801561086057600080fd5b5061027b61086f366004612e6f565b61137f565b34801561088057600080fd5b506102f261088f366004612c8b565b6115a1565b3480156108a057600080fd5b506102c47f000000000000000000000000000000000000000000000000000000000000100081565b3480156108d457600080fd5b506102c47f000000000000000000000000000000000000000000000000000000000000000a81565b34801561090857600080fd5b5061065d610917366004612f42565b61166f565b34801561092857600080fd5b506102c47f000000000000000000000000000000000000000000000000000000000000001081565b34801561095c57600080fd5b506102c47f000000000000000000000000000000000000000000000000000000000000001b81565b34801561099057600080fd5b5061065d61099f366004612cad565b606092915050565b3480156109b357600080fd5b506105836203330381565b3480156109ca57600080fd5b506102c4611755565b3480156109df57600080fd5b506105836203330481565b6109fa4288888888888888611799565b50505050505050565b60045460ff1615610a5b5760405162461bcd60e51b815260206004820152601960248201527f616c726561647920696e697469616c697a65642073686172640000000000000060448201526064015b60405180910390fd5b6004805460ff1916600190811790915560036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92f008390557f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff8290556000527fa15bc60c955c405d20d9149c709e2460f1c2d9a497496a7f46004d1772c3054d919091557fa15bc60c955c405d20d9149c709e2460f1c2d9a497496a7f46004d1772c3054c55565b6000610b0f426118d0565b905090565b60408051336020820152908101839052600090819060600160408051808303601f1901815282825280516020918201206000818152600183528381206060860185525464ffffffffff81168652600160281b810462ffffff1693860193909352600160401b909204831b67ffffffffffffffff1916928401839052935003610bcd5760405162461bcd60e51b815260206004820152600c60248201526b1add881b9bdd08195e1a5cdd60a21b6044820152606401610a52565b8351816020015162ffffff1614610be957600092505050610c38565b6000610c15857f0000000000000000000000000000000000000000000000000000000000001000611925565b9050806001600160401b03191682604001516001600160401b0319161493505050505b92915050565b565b7f000000000000000000000000000000000000000000000000000000000002000081511115610ca25760405162461bcd60e51b815260206004820152600e60248201526d6461746120746f6f206c6172676560901b6044820152606401610a52565b610caa611b56565b6040805133602082015290810183905260009060600160408051808303601f1901815282825280516020918201206000818152600183528381206060860185525464ffffffffff81168652600160281b810462ffffff1693860193909352600160401b909204831b67ffffffffffffffff1916928401839052935003610dbf57610d32610b04565b341015610d765760405162461bcd60e51b81526020600482015260126024820152711b9bdd08195b9bdd59da081c185e5b595b9d60721b6044820152606401610a52565b6000805464ffffffffff90811680845282526002602052604082208490559054610da291166001612fb9565b6000805464ffffffffff191664ffffffffff929092169190911790555b825162ffffff166020820152610df5837f0000000000000000000000000000000000000000000000000000000000001000611925565b67ffffffffffffffff19908116604080840191825260008581526001602090815290829020855181549287015194519384901c600160401b0262ffffff909516600160281b029290951664ffffffffff909516948517919091176001600160401b031692909217909155610e6a91908561109e565b50505050565b6040805133602082015290810183905260009060600160408051808303601f1901815282825280516020918201206000818152600183528381206060860185525464ffffffffff8116808752600160281b820462ffffff1694870194909452600160401b9004841b67ffffffffffffffff191693850184905290945090919003610f2b5760405162461bcd60e51b815260206004820152600c60248201526b1add881b9bdd08195e1a5cdd60a21b6044820152606401610a52565b6040805160608101825260008082526020808301828152838501838152888452600192839052858420945185549251915190961c600160401b0262ffffff91909116600160281b0267ffffffffffffffff199290921664ffffffffff96871617919091176001600160401b031617909255805490926002928492610faf9216612fde565b64ffffffffff908116825260208083019390935260409182016000908120548683168083526002808752858420839055828452600196879052948320805464ffffffffff1916909117905581549095509093849261100d9216612fde565b64ffffffffff90811682526020820192909252604001600090812092909255905461103b9160019116612fde565b6000805464ffffffffff191664ffffffffff9283169081179091556110619184166115a1565b846001600160a01b03166108fc611076610b04565b6040518115909202916000818181858888f193505050501580156109fa573d6000803e3d6000fd5b604080519083901c9060009062033302906110c190879085908790602001612ffc565b60408051601f19818403018152908290526110db91613024565b6000604051808303816000865af19150503d8060008114611118576040519150601f19603f3d011682016040523d82523d6000602084013e61111d565b606091505b50509050806111615760405162461bcd60e51b815260206004820152601060248201526f6661696c656420746f2070757452617760801b6044820152606401610a52565b5050505050565b6060816000036111875750604080516000815260208101909152611272565b6040805133602082015290810185905260009060600160408051808303601f1901815282825280516020918201206000818152600183528390206060850184525464ffffffffff81168552600160281b810462ffffff16928501839052600160401b9004831b67ffffffffffffffff19169284019290925290925085106112205750506040805160008152602081019091529050611272565b602081015162ffffff166112348686613040565b11156112525784816020015162ffffff1661124f9190613053565b93505b61126d8160400151826000015164ffffffffff168787611279565b925050505b9392505050565b6040805185821c6020820181905291810185905260608082018590526080820184905291906000908190620333039060a00160408051601f19818403018152908290526112c591613024565b600060405180830381855afa9150503d8060008114611300576040519150601f19603f3d011682016040523d82523d6000602084013e611305565b606091505b5091509150816113505760405162461bcd60e51b81526020600482015260166024820152756661696c656420746f2073797374656d47657452617760501b6044820152606401610a52565b808060200190518101906113649190613066565b93505050505b949350505050565b61137c8133610e70565b50565b600060017f00000000000000000000000000000000000000000000000000000000000000051b816113b082886130e9565b90506000866020015162ffffff167f0000000000000000000000000000000000000000000000000000000000001000836113ea91906130fd565b10611423577fa8bae11751799de4dbe638406c5c9642c0e791f2a65e852a05ba4fdf0d88e3e6858051906020012014935050505061136a565b817f000000000000000000000000000000000000000000000000000000000000100060018960200151611456919061311c565b62ffffff166114659190613138565b036115685760006114967f0000000000000000000000000000000000000000000000000000000000001000846130fd565b886020015162ffffff166114aa9190613053565b602087018190209250905060006114e1827f0000000000000000000000000000000000000000000000000000000000001000613053565b90508015611561576000816001600160401b038111156115035761150361298a565b6040519080825280601f01601f19166020018201604052801561152d576020820181803683370190505b5090506000808360208401209150838560208c010120905080821461155d5760009850505050505050505061136a565b5050505b5050611571565b50835160208501205b600061157e828489611b5f565b604089015167ffffffffffffffff19918216911614945050505050949350505050565b6040805160208101849052908101829052600090620333059060600160408051601f19818403018152908290526115d791613024565b6000604051808303816000865af19150503d8060008114611614576040519150601f19603f3d011682016040523d82523d6000602084013e611619565b606091505b505090508061166a5760405162461bcd60e51b815260206004820152601960248201527f6661696c656420746f2073797374656d52656d6f7665526177000000000000006044820152606401610a52565b505050565b6040805160609185901c906000908190620333049061169b906002908b9087908b908b9060200161314c565b60408051601f19818403018152908290526116b591613024565b600060405180830381855afa9150503d80600081146116f0576040519150601f19603f3d011682016040523d82523d6000602084013e6116f5565b606091505b5091509150816113505760405162461bcd60e51b815260206004820152602560248201527f6661696c656420746f2073797374656d556e6d61736b4368756e6b57697468456044820152640e8d0c2e6d60db1b6064820152608401610a52565b6000805461178d9064ffffffffff167f000000000000000000000000000000000000000000000000000000000000000a1c6001612fb9565b64ffffffffff16905090565b878411156117dd5760405162461bcd60e51b81526020600482015260116024820152706d696e6564547320746f6f206c6172676560781b6044820152606401610a52565b6001861b600080806117f08b858a611c93565b604080516020808201939093526001600160a01b038e1681830152606081018d905260808082018d90528251808303909101815260a09091019091528051910120919450925090506118468b8b838c8a8a611e7d565b9050600061185684600019613138565b905060006118638361224a565b61186c8361224a565b60405160200161187d929190613199565b60408051601f19818403018152919052905080828411156118b15760405162461bcd60e51b8152600401610a529190612e23565b5050506118c28b858b8b86866122a1565b505050505050505050505050565b6000610c387f00000000000000000000000000000000000000000000000000000000000000006119207f000000000000000000000000000000000000000000000000000000000000000185613053565b612443565b6000825160000361193857506000610c38565b600082600184865161194a9190613040565b6119549190613053565b61195e9190613138565b9050600060018211156119795761197482612484565b61197c565b60015b90506000816001600160401b038111156119985761199861298a565b6040519080825280602002602001820160405280156119c1578160200160208202803683370190505b50905060005b82811015611a47576000806119dc88846130fd565b9050885181106119ed575050611a47565b6000818a516119fc9190613053565b9050888110611a085750875b808260208c010120925082858581518110611a2557611a25613205565b6020026020010181815250505050508080611a3f9061321b565b9150506119c7565b508192505b82600114611b305760005b611a62600285613138565b811015611b1d5781611a758260026130fd565b81518110611a8557611a85613205565b602002602001015182826002611a9b91906130fd565b611aa6906001613040565b81518110611ab657611ab6613205565b6020026020010151604051602001611ad8929190918252602082015260400190565b60405160208183030381529060405280519060200120828281518110611b0057611b00613205565b602090810291909101015280611b158161321b565b915050611a57565b50611b29600284613138565b9250611a4c565b80600081518110611b4357611b43613205565b6020026020010151935050505092915050565b610c3e426124c1565b805160009084906001811b8510611bac5760405162461bcd60e51b81526020600482015260116024820152706368756e6b4964206f766572666c6f777360781b6044820152606401610a52565b60005b81811015611c8857611bc26002876130e9565b600003611c1b5782858281518110611bdc57611bdc613205565b6020026020010151604051602001611bfe929190918252602082015260400190565b604051602081830303815290604052805190602001209250611c69565b848181518110611c2d57611c2d613205565b602002602001015183604051602001611c50929190918252602082015260400190565b6040516020818303038152906040528051906020012092505b611c74600287613138565b955080611c808161321b565b915050611baf565b509095945050505050565b600060606000846001600160401b03811115611cb157611cb161298a565b604051908082528060200260200182016040528015611cda578160200160208202803683370190505b50600093509150829050805b85811015611e73576000611cfa8289613040565b6000818152600360205260409020600181015491925090871015611d545760405162461bcd60e51b81526020600482015260116024820152701b5a5b9959151cc81d1bdbc81cdb585b1b607a1b6044820152606401610a52565b611de281887f000000000000000000000000000000000000000000000000000000000000012c7f000000000000000000000000000000000000000000000000000000000000012c7f00000000000000000000000000000000000000000000000000000000000004007f00000000000000000000000000000000000000000000000000000000000027106125b4565b858481518110611df457611df4613205565b602002602001018181525050848381518110611e1257611e12613205565b602002602001015186611e259190613040565b81546040805160208101889052908101859052606081019190915290965060800160405160208183030381529060405280519060200120935050508080611e6b9061321b565b915050611ce6565b5093509350939050565b60007f0000000000000000000000000000000000000000000000000000000000000010825114611eef5760405162461bcd60e51b815260206004820152601f60248201527f6461746120767320636865636b733a206c656e677468206d69736d61746368006044820152606401610a52565b7f0000000000000000000000000000000000000000000000000000000000000010835114611f695760405162461bcd60e51b815260206004820152602160248201527f70726f6f667320767320636865636b733a206c656e677468206d69736d6174636044820152600d60fb1b6064820152608401610a52565b60007f0000000000000000000000000000000000000000000000000000000000000005611fb6887f000000000000000000000000000000000000000000000000000000000000000a613040565b611fc09190613040565b6001901b905060005b7f000000000000000000000000000000000000000000000000000000000000001081101561223d5760007f000000000000000000000000000000000000000000000000000000000000100090508085838151811061202957612029613205565b602002602001015151146120745760405162461bcd60e51b8152602060048201526012602482015271696e76616c69642070726f6f662073697a6560701b6044820152606401610a52565b6000612080848a6130e9565b905060006120ce7f00000000000000000000000000000000000000000000000000000000000000057f000000000000000000000000000000000000000000000000000000000000000a613040565b6120db908d901b83613040565b7f000000000000000000000000000000000000000000000000000000000000000581901c6000818152600260209081526040808320548352600182528083208151606081018352905464ffffffffff81168252600160281b810462ffffff1693820193909352600160401b909204811b67ffffffffffffffff19169082018190528b519495509293909261218d918691908f908e908c90811061218057612180613205565b602002602001015161166f565b90506121b484838d8a815181106121a6576121a6613205565b60200260200101518461137f565b6121f75760405162461bcd60e51b815260206004820152601460248201527334b73b30b634b21030b1b1b2b9b990383937b7b360611b6044820152606401610a52565b60008a888151811061220b5761220b613205565b602002602001015190508d81526020870181209d508681525050505050505080806122359061321b565b915050611fc9565b5094979650505050505050565b6060816000036122745750506040805180820190915260048152630307830360e41b602082015290565b8160005b811561229757806122888161321b565b915050600882901c9150612278565b61136a8482612682565b6000806122ac611755565b905060005b878110156123875760006122c5828b613040565b9050828111612374576000818152600360205260409020600181015461232f907f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000a1b908a61281d565b6123399086613040565b9450612372600360008481526020019081526020016000208989868151811061236457612364613205565b60200260200101518961287c565b505b508061237f8161321b565b9150506122b1565b5060006127106123b77f00000000000000000000000000000000000000000000000000000000000003e8856130fd565b6123c19190613138565b905060006123cf8285613053565b604051909150419083156108fc029084906000818181858888f193505050501580156123ff573d6000803e3d6000fd5b506040516001600160a01b0389169082156108fc029083906000818181858888f19350505050158015612436573d6000803e3d6000fd5b5050505050505050505050565b600060806124717f0000000000000000000000000000000000000000000000000000000000000000846128a0565b61247b90856130fd565b901c9392505050565b6000612491600183613053565b91505b61249f600183613053565b8216156124ba576124b1600183613053565b82169150612494565b5060011b90565b60005460017f000000000000000000000000000000000000000000000000000000000000000a81901b916124fe9164ffffffffff90911690612fb9565b64ffffffffff1661250f91906130e9565b60000361137c57600080547f000000000000000000000000000000000000000000000000000000000000000a9061254e9064ffffffffff166001612fb9565b64ffffffffff16901c60016125639190612fb9565b64ffffffffff16600081815260036020819052604082206001908101869055929350916125909084613053565b81526020808201929092526040908101600090812054938152600390925290205550565b6000808760010154876125c79190613053565b60028901549091508682101561261e5784816125e38885613138565b6125ee906001613053565b6125f891906130fd565b6126029190613138565b61260c9082613040565b9050838110156126195750825b612676565b60008582600161262e8a87613138565b6126389190613053565b61264291906130fd565b61264c9190613138565b9050816126598683613040565b111561266757849150612674565b6126718183613053565b91505b505b98975050505050505050565b606060006126918360026130fd565b61269c906002613040565b6001600160401b038111156126b3576126b361298a565b6040519080825280601f01601f1916602001820160405280156126dd576020820181803683370190505b509050600360fc1b816000815181106126f8576126f8613205565b60200101906001600160f81b031916908160001a905350600f60fb1b8160018151811061272757612727613205565b60200101906001600160f81b031916908160001a905350600061274b8460026130fd565b612756906001613040565b90505b60018111156127ce576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061278a5761278a613205565b1a60f81b8282815181106127a0576127a0613205565b60200101906001600160f81b031916908160001a90535060049490941c936127c781613234565b9050612759565b5083156112725760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610a52565b600061136a8461284d7f000000000000000000000000000000000000000000000000000000000000000186613053565b6128777f000000000000000000000000000000000000000000000000000000000000000186613053565b6128ac565b600384015461288c906001613040565b600385015583556002830155600190910155565b60006112728383612922565b600060806128da7f0000000000000000000000000000000000000000000000000000000000000000846128a0565b6129047f0000000000000000000000000000000000000000000000000000000000000000866128a0565b61290e9190613053565b61291890866130fd565b901c949350505050565b6000600160801b5b8215611272578260011660010361294c57608061294785836130fd565b901c90505b608061295885806130fd565b901c9350612967600284613138565b925061292a565b80356001600160a01b038116811461298557600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b604051606081016001600160401b03811182821017156129c2576129c261298a565b60405290565b604051601f8201601f191681016001600160401b03811182821017156129f0576129f061298a565b604052919050565b60006001600160401b03821115612a1157612a1161298a565b5060051b60200190565b600082601f830112612a2c57600080fd5b81356020612a41612a3c836129f8565b6129c8565b82815260059290921b84018101918181019086841115612a6057600080fd5b8286015b84811015612a7b5780358352918301918301612a64565b509695505050505050565b60006001600160401b03821115612a9f57612a9f61298a565b50601f01601f191660200190565b600082601f830112612abe57600080fd5b8135612acc612a3c82612a86565b818152846020838601011115612ae157600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f830112612b0f57600080fd5b81356020612b1f612a3c836129f8565b82815260059290921b84018101918181019086841115612b3e57600080fd5b8286015b84811015612a7b5780356001600160401b03811115612b615760008081fd5b612b6f8986838b0101612aad565b845250918301918301612b42565b600080600080600080600060e0888a031215612b9857600080fd5b8735965060208801359550612baf6040890161296e565b9450606088013593506080880135925060a08801356001600160401b0380821115612bd957600080fd5b818a0191508a601f830112612bed57600080fd5b8135612bfb612a3c826129f8565b8082825260208201915060208360051b86010192508d831115612c1d57600080fd5b602085015b83811015612c56578481351115612c3857600080fd5b612c488f60208335890101612a1b565b835260209283019201612c22565b509550505060c08a0135915080821115612c6f57600080fd5b50612c7c8a828b01612afe565b91505092959891949750929550565b60008060408385031215612c9e57600080fd5b50508035926020909101359150565b60008060408385031215612cc057600080fd5b8235915060208301356001600160401b03811115612cdd57600080fd5b612ce985828601612aad565b9150509250929050565b600060208284031215612d0557600080fd5b5035919050565b60008060408385031215612d1f57600080fd5b82359150612d2f6020840161296e565b90509250929050565b803567ffffffffffffffff198116811461298557600080fd5b600080600060608486031215612d6657600080fd5b83359250612d7660208501612d38565b915060408401356001600160401b03811115612d9157600080fd5b612d9d86828701612aad565b9150509250925092565b600080600060608486031215612dbc57600080fd5b505081359360208301359350604090920135919050565b60005b83811015612dee578181015183820152602001612dd6565b50506000910152565b60008151808452612e0f816020860160208601612dd3565b601f01601f19169290920160200192915050565b6020815260006112726020830184612df7565b60008060008060808587031215612e4c57600080fd5b612e5585612d38565b966020860135965060408601359560600135945092505050565b60008060008084860360c0811215612e8657600080fd5b853594506060601f1982011215612e9c57600080fd5b50612ea56129a0565b602086013564ffffffffff81168114612ebd57600080fd5b8152604086013562ffffff81168114612ed557600080fd5b6020820152612ee660608701612d38565b6040820152925060808501356001600160401b0380821115612f0757600080fd5b612f1388838901612a1b565b935060a0870135915080821115612f2957600080fd5b50612f3687828801612aad565b91505092959194509250565b60008060008060808587031215612f5857600080fd5b84356001600160401b038082168214612f7057600080fd5b819550612f7f60208801612d38565b9450612f8d6040880161296e565b93506060870135915080821115612f2957600080fd5b634e487b7160e01b600052601160045260246000fd5b64ffffffffff818116838216019080821115612fd757612fd7612fa3565b5092915050565b64ffffffffff828116828216039080821115612fd757612fd7612fa3565b83815282602082015260606040820152600061301b6060830184612df7565b95945050505050565b60008251613036818460208701612dd3565b9190910192915050565b80820180821115610c3857610c38612fa3565b81810381811115610c3857610c38612fa3565b60006020828403121561307857600080fd5b81516001600160401b0381111561308e57600080fd5b8201601f8101841361309f57600080fd5b80516130ad612a3c82612a86565b8181528560208385010111156130c257600080fd5b61301b826020830160208601612dd3565b634e487b7160e01b600052601260045260246000fd5b6000826130f8576130f86130d3565b500690565b600081600019048311821515161561311757613117612fa3565b500290565b62ffffff828116828216039080821115612fd757612fd7612fa3565b600082613147576131476130d3565b500490565b6001600160401b03868116825285166020820152604081018490526001600160a01b038316606082015260a06080820181905260009061318e90830184612df7565b979650505050505050565b753234b333103737ba1036b0ba31b41d903430b9b4181d60511b8152600083516131ca816016850160208801612dd3565b6e10103932b8bab4b932b22234b3331d60891b60169184019182015283516131f9816025840160208801612dd3565b01602501949350505050565b634e487b7160e01b600052603260045260246000fd5b60006001820161322d5761322d612fa3565b5060010190565b60008161324357613243612fa3565b50600019019056fea26469706673582212204fca2ca323dc60ce2f3d4311cf00f0f33ac3b656154fcd642a749218f334557164736f6c63430008100033"), // Get the url of Web3qBridge: https://github.com/QuarkChain/staking-contracts/blob/cross_chain_event/contracts/token/Web3qBridge.sol // contract at 0x0000000000000000000000000000000003330002 is complied Web3qBridge 0.8.9 solc (enable optimized) tokenManager: common.Hex2Bytes("60806040526004361061009c5760003560e01c8063885b012e11610064578063885b012e146101455780638929268814610184578063cde5f63b1461019b578063dbc11758146101a3578063ee271935146101d2578063ee9277b1146101f257600080fd5b80632362e53a146100a15780632996f972146100de5780632f6af8cc146100f55780633ffe450814610118578063474d6dea1461012f575b600080fd5b3480156100ad57600080fd5b506000546100c1906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156100ea57600080fd5b506100c16203332381565b34801561010157600080fd5b5061010a600a81565b6040519081526020016100d5565b34801561012457600080fd5b506100c16203332181565b34801561013b57600080fd5b5061010a60025481565b34801561015157600080fd5b506101826101603660046106b8565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b005b34801561019057600080fd5b506100c16203332281565b61018261023d565b3480156101af57600080fd5b506101c36101be3660046106dc565b610297565b6040516100d593929190610773565b3480156101de57600080fd5b506101826101ed3660046107dc565b61031f565b3480156101fe57600080fd5b5061022d61020d3660046107dc565b600160209081526000928352604080842090915290825290205460ff1681565b60405190151581526020016100d5565b61024733346104b3565b60028054906000610257836107fe565b90915550506002546040513481523391907fc838383de55ec352dbaa3387ea63cfc867d4bddf19389bce783dbde403459c769060200160405180910390a3565b60006060806000806102ac8a8a8a8a8a61055a565b91509150816102f0576000818060200190518101906102cb91906108bd565b90508060405162461bcd60e51b81526004016102e7919061090e565b60405180910390fd5b6000806000838060200190518101906103099190610941565b919f909e50909c509a5050505050505050505050565b600082815260016020908152604080832084845290915290205460ff16156103895760405162461bcd60e51b815260206004820152601a60248201527f746865206275726e206c6f6720686173206265656e207573656400000000000060448201526064016102e7565b600082815260016020818152604080842085855282528320805460ff1916909217909155819081906103c39060049087908790600a610297565b60005492955090935091506001600160a01b038085169116146104215760405162461bcd60e51b81526020600482015260166024820152750c6dedce8e4c2c6e840c2c8c8e440dcde40dac2e8c6d60531b60448201526064016102e7565b60008260018151811061043657610436610a20565b602002602001015160001c90506000828060200190518101906104599190610a36565b905061046582826105fe565b816001600160a01b031686887fea683109724089070580fcd9f3e5f4a7e585bd0eb900a9cdc15903d6e82445ec846040516104a291815260200190565b60405180910390a450505050505050565b604080516001600160a01b0384166020820152908101829052600090620333239060600160408051601f19818403018152908290526104f191610a4f565b6000604051808303816000865af19150503d806000811461052e576040519150601f19603f3d011682016040523d82523d6000602084013e610533565b606091505b50509050806105555760405163ac5ca12160e01b815260040160405180910390fd5b505050565b604080516020810187905290810185905260608181018590526080820184905260a08201839052600091829060c00160408051601f1981840301815290829052915062033321906105ac908390610a4f565b6000604051808303816000865af19150503d80600081146105e9576040519150601f19603f3d011682016040523d82523d6000602084013e6105ee565b606091505b5092509250509550959350505050565b604080516001600160a01b0384166020820152908101829052600090620333229060600160408051601f198184030181529082905261063c91610a4f565b6000604051808303816000865af19150503d8060008114610679576040519150601f19603f3d011682016040523d82523d6000602084013e61067e565b606091505b505090508061055557604051635caede6760e11b815260040160405180910390fd5b6001600160a01b03811681146106b557600080fd5b50565b6000602082840312156106ca57600080fd5b81356106d5816106a0565b9392505050565b600080600080600060a086880312156106f457600080fd5b505083359560208501359550604085013594606081013594506080013592509050565b60005b8381101561073257818101518382015260200161071a565b83811115610741576000848401525b50505050565b6000815180845261075f816020860160208601610717565b601f01601f19169290920160200192915050565b6001600160a01b038416815260606020808301829052845191830182905260009185820191906080850190845b818110156107bc578451835293830193918301916001016107a0565b505084810360408601526107d08187610747565b98975050505050505050565b600080604083850312156107ef57600080fd5b50508035926020909101359150565b600060001982141561082057634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561086657610866610827565b604052919050565b600067ffffffffffffffff83111561088857610888610827565b61089b601f8401601f191660200161083d565b90508281528383830111156108af57600080fd5b6106d5836020830184610717565b6000602082840312156108cf57600080fd5b815167ffffffffffffffff8111156108e657600080fd5b8201601f810184136108f757600080fd5b6109068482516020840161086e565b949350505050565b6020815260006106d56020830184610747565b600082601f83011261093257600080fd5b6106d58383516020850161086e565b60008060006060848603121561095657600080fd5b8351610961816106a0565b8093505060208085015167ffffffffffffffff8082111561098157600080fd5b818701915087601f83011261099557600080fd5b8151818111156109a7576109a7610827565b8060051b6109b685820161083d565b918252838101850191858101908b8411156109d057600080fd5b948601945b838610156109ee578551825294860194908601906109d5565b60408b0151909850955050505080831115610a0857600080fd5b5050610a1686828701610921565b9150509250925092565b634e487b7160e01b600052603260045260246000fd5b600060208284031215610a4857600080fd5b5051919050565b60008251610a61818460208701610717565b919091019291505056fea2646970667358221220b1003dd9a162c1405348aa2ed55f52d945e62f6e81f49565728124e95cce688564736f6c63430008090033"), @@ -776,7 +777,10 @@ func (l *sstoragePisaPutRaw) RunWith(env *PrecompiledContractCallEnv, input []by if putLen > maxKVSize { return nil, errors.New("put len too large") } - evm.StateDB.SstorageWrite(caller, kvIdx, kvHash, getData(input, dataPtr+32, putLen)) + err := evm.StateDB.SstorageWrite(caller, kvIdx, kvHash, getData(input, dataPtr+32, putLen)) + if err != nil { + return nil, err + } log.Info("sstoragePisaPutRaw() returns", "caller", caller, "kvidx", kvIdx, "dataPtr", dataPtr, "maxKVSize", maxKVSize) return nil, nil @@ -877,7 +881,11 @@ func (l *sstoragePisaUnmaskDaggerData) RunWith(env *PrecompiledContractCallEnv, pb := make([]byte, 64) binary.BigEndian.PutUint64(pb[32-8:32], 32) binary.BigEndian.PutUint64(pb[64-8:64], uint64(len(unmaskedChunk))) - log.Debug("sstoragePisaUnmaskDaggerData() returns", "encodeType", encodeType, "chunkIdx", chunkIdx, "kvHash", kvHash, "miner", miner, "datalen", datalen) + if bytes.Compare(unmaskedChunk[:20], make([]byte, 20)) != 0 { + log.Info("sstoragePisaUnmaskDaggerData() returns", "encodeType", encodeType, "chunkIdx", chunkIdx, + "kvHash", kvHash, "miner", miner, "datalen", datalen, "masked chunk data", maskedChunkData[:20], + "unmasked chunk data", unmaskedChunk[:20], "kvidx", chunkIdx/32, "chunkidx", chunkIdx%32) + } return append(pb, unmaskedChunk...), nil } @@ -1318,7 +1326,7 @@ func (c *tokenIssuer) RequiredGas(input []byte) uint64 { // who uses the chain for the first time and load the account leaf at cache until completing the `AddBalance` operation, // then commit the account-leaf to disk. // At the same time, if the user is not a new account, this previously charged gas can cover the gas cost for - //`AddBalance` operation and is similar to the gas cost of Transfer(21000) for users + // `AddBalance` operation and is similar to the gas cost of Transfer(21000) for users return params.CallNewAccountGas } @@ -1689,8 +1697,8 @@ func VerifyCrossChainCall(client MindReadingClient, externalCallInput string) ([ MinimumConfirms: 10, } evm := NewEVMWithMRC(BlockContext{BlockNumber: big.NewInt(0)}, TxContext{}, mrctx, nil, chainCfg, evmConfig) - //evmInterpreter := NewEVMInterpreter(evm, evm.Config) - //evm.interpreter = evmInterpreter + // evmInterpreter := NewEVMInterpreter(evm, evm.Config) + // evm.interpreter = evmInterpreter if res, _, err := RunPrecompiledContract(&PrecompiledContractCallEnv{evm: evm}, p, common.FromHex(externalCallInput), gas); err != nil { return nil, err diff --git a/core/vm/contracts_test.go b/core/vm/contracts_test.go index 0b2e5539cb13..5037bb4167dd 100644 --- a/core/vm/contracts_test.go +++ b/core/vm/contracts_test.go @@ -21,17 +21,17 @@ import ( "encoding/hex" "encoding/json" "fmt" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/sstorage" "io/ioutil" "math/big" "testing" "time" + "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/sstorage" ) // precompiledTest defines the input/output pairs for precompiled contract tests. @@ -186,7 +186,7 @@ func benchmarkPrecompiled(addr string, test precompiledTest, bench *testing.B) { // Keep it as uint64, multiply 100 to get two digit float later mgasps := (100 * 1000 * gasUsed) / elapsed bench.ReportMetric(float64(mgasps)/100, "mgas/s") - //Check if it is correct + // Check if it is correct if err != nil { bench.Error(err) return diff --git a/eth/backend.go b/eth/backend.go index 1f6e0e8b75ad..3cfd7e96e3ae 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -189,10 +189,9 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { if config.IsMiner && chainConfig.MindReading.EnableBlockNumber.Cmp(big.NewInt(0)) >= 0 && chainConfig.MindReading.CallRpc == "" { return nil, fmt.Errorf("Validator must enable MindReading with valid MindReadingCallRpc ") } + log.Info("Initialised mindReading configuration", "mindReading conf", *chainConfig.MindReading) } - log.Info("Initialised mindReading configuration", "mindReading conf", *chainConfig.MindReading) - if err = chainDb.StartFreeze(chainDb, chainConfig); err != nil { log.Crit("Failed to StartFreeze", "error", err) } diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index e48613435dac..6b33a1f16481 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -212,13 +212,16 @@ type BlockChain interface { // KVs to the sstorage file. And return the inserted KV index list. VerifyAndWriteKV(contract common.Address, data map[uint64][]byte, provderAddr common.Address) (uint64, uint64, []uint64, error) + // FillSstorWithEmptyKV get the lastKVIndex and if the kv index need to fill is larger than or equal to lastKVIndex + // fill up the kv with empty ([]byte{}), so the data in the file will be filled with encode empty data + FillSstorWithEmptyKV(contract common.Address, start, limit uint64) (uint64, error) + // ReadEncodedKVsByIndexList Read the encoded KVs by a list of KV index. ReadEncodedKVsByIndexList(contract common.Address, shardId uint64, indexes []uint64) (common.Address, []*core.KV, error) // ReadEncodedKVsByIndexRange Read encoded KVs sequentially starting from origin until the index exceeds the limit or // the amount of data read is greater than the bytes. - ReadEncodedKVsByIndexRange(contract common.Address, shardId uint64, origin uint64, - limit uint64, bytes uint64) (common.Address, []*core.KV, error) + ReadEncodedKVsByIndexRange(contract common.Address, shardId uint64, origin uint64, limit uint64, bytes uint64) (common.Address, []*core.KV, error) // GetSstorageLastKvIdx get LastKvIdx from a sstorage contract with latest stateDB. GetSstorageLastKvIdx(contract common.Address) (uint64, error) @@ -241,7 +244,7 @@ func New(checkpoint uint64, stateDb ethdb.Database, mux *event.TypeMux, chain Bl headerProcCh: make(chan *headerTask, 1), quitCh: make(chan struct{}), SnapSyncer: snap.NewSyncer(stateDb), - SstorSyncer: sstorage.NewSyncer(stateDb, chain, sstor.Shards()), + SstorSyncer: sstorage.NewSyncer(stateDb, chain, mux, sstor.Shards()), stateSyncStart: make(chan *stateSync), sstorSyncStart: make(chan *sstorSync), } diff --git a/eth/protocols/sstorage/sync.go b/eth/protocols/sstorage/sync.go index 95a62742f9ed..750e46a2a9e7 100644 --- a/eth/protocols/sstorage/sync.go +++ b/eth/protocols/sstorage/sync.go @@ -21,14 +21,14 @@ import ( "errors" "fmt" "math/rand" + "runtime" "sort" "sync" "time" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" - - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethdb" @@ -45,7 +45,7 @@ const ( maxConcurrency = 16 - minSubTaskSize = 512 + minSubTaskSize = 16 ) // ErrCancelled is returned from sstorage syncing if the operation was prematurely @@ -53,6 +53,8 @@ const ( var ErrCancelled = errors.New("sync cancelled") var ( + maxEmptyTaskTreads int + empty = make([]byte, 0) requestTimeoutInMillisecond = 1000 * time.Millisecond // Millisecond ) @@ -134,16 +136,29 @@ type kvHealResponse struct { // kvTask represents the sync task for a sstorage shard. type kvTask struct { // These fields get serialized to leveldb on shutdown - Contract common.Address // Contract address - ShardId uint64 // ShardId - KvSubTasks []*kvSubTask - HealTask *kvHealTask + Contract common.Address // Contract address + ShardId uint64 // ShardId + KvSubTasks []*kvSubTask + HealTask *kvHealTask + KvSubEmptyTasks []*kvSubEmptyTask statelessPeers map[string]struct{} // Peers that failed to deliver kv Data done bool // Flag whether the task can be removed } +// task which is used to write empty to sstorage file, so the files will fill up with encode data +type kvSubEmptyTask struct { + kvTask *kvTask + + next uint64 + First uint64 + Last uint64 + + isRunning bool + done bool // Flag whether the task can be removed +} + type kvSubTask struct { kvTask *kvTask @@ -172,7 +187,7 @@ type kvHealTask struct { func (h *kvHealTask) hasIndexInRange(first, last uint64) (bool, uint64) { min, exist := last, false for idx, _ := range h.Indexes { - if idx <= last && idx >= first { + if idx < last && idx >= first { exist = true if min > idx { min = idx @@ -207,8 +222,10 @@ type SyncProgress struct { Tasks []*kvTask // The suspended kv tasks // Status report during syncing phase - KVSynced uint64 // Number of kvs downloaded - KVBytes common.StorageSize // Number of kv bytes downloaded + KVSynced uint64 // Number of kvs downloaded + KVBytes common.StorageSize // Number of kv bytes downloaded + EmptyKVToFill uint64 + EmptyKVFilled uint64 } // SyncPeer abstracts out the methods required for a peer to be synced against @@ -246,13 +263,16 @@ type BlockChain interface { // KVs to the sstorage file. And return the inserted KV index list. VerifyAndWriteKV(contract common.Address, data map[uint64][]byte, providerAddress common.Address) (uint64, uint64, []uint64, error) + // FillSstorWithEmptyKV get the lastKVIndex and if the kv index need to fill is larger than or equal to lastKVIndex + // fill up the kv with empty ([]byte{}), so the data in the file will be filled with encode empty data + FillSstorWithEmptyKV(contract common.Address, start, limit uint64) (uint64, error) + // ReadEncodedKVsByIndexList Read the masked KVs by a list of KV index. ReadEncodedKVsByIndexList(contract common.Address, shardId uint64, indexes []uint64) (common.Address, []*core.KV, error) // ReadEncodedKVsByIndexRange Read masked KVs sequentially starting from origin until the index exceeds the limit or // the amount of data read is greater than the bytes. - ReadEncodedKVsByIndexRange(contract common.Address, shardId uint64, origin uint64, - limit uint64, bytes uint64) (common.Address, []*core.KV, error) + ReadEncodedKVsByIndexRange(contract common.Address, shardId uint64, origin uint64, limit uint64, bytes uint64) (common.Address, []*core.KV, error) // GetSstorageLastKvIdx get LastKvIdx from a sstorage contract with latest stateDB. GetSstorageLastKvIdx(contract common.Address) (uint64, error) @@ -270,6 +290,7 @@ type BlockChain interface { type Syncer struct { db ethdb.KeyValueStore // Database to store the sync state chain BlockChain + mux *event.TypeMux // Event multiplexer to announce sync operation events tasks []*kvTask sstorageInfo map[common.Address][]uint64 // Map for Contract address to support shardIds @@ -288,10 +309,15 @@ type Syncer struct { kvRangeReqs map[uint64]*kvRangeRequest // KV requests currently running kvHealReqs map[uint64]*kvHealRequest // KV heal requests currently running + runningEmptyTaskTreads int // Number of working threads for processing empty task + kvSynced uint64 // Number of kvs downloaded kvBytes common.StorageSize // Number of kv bytes downloaded kvSyncing uint64 // Number of kvs downloading + emptyKVToFill uint64 + emptyKVFilled uint64 + startTime time.Time // Time instance when sstorage sync started logTime time.Time // Time instance when status was Last reported @@ -301,10 +327,14 @@ type Syncer struct { } // NewSyncer creates a new sstorage syncer to download the sharded storage content over the sstorage protocol. -func NewSyncer(db ethdb.KeyValueStore, chain BlockChain, sstorageInfo map[common.Address][]uint64) *Syncer { +func NewSyncer(db ethdb.KeyValueStore, chain BlockChain, mux *event.TypeMux, sstorageInfo map[common.Address][]uint64) *Syncer { + maxEmptyTaskTreads = runtime.NumCPU() - 2 + if maxEmptyTaskTreads < 1 { + maxEmptyTaskTreads = 1 + } return &Syncer{ - db: db, - + db: db, + mux: mux, tasks: make([]*kvTask, 0), sstorageInfo: sstorageInfo, chain: chain, @@ -315,10 +345,11 @@ func NewSyncer(db ethdb.KeyValueStore, chain BlockChain, sstorageInfo map[common rates: msgrate.NewTrackers(log.New("proto", "sstorage")), update: make(chan struct{}, 1), - kvRangeIdlers: make(map[string]struct{}), - kvHealIdlers: make(map[string]struct{}), - kvRangeReqs: make(map[uint64]*kvRangeRequest), - kvHealReqs: make(map[uint64]*kvHealRequest), + kvRangeIdlers: make(map[string]struct{}), + kvHealIdlers: make(map[string]struct{}), + runningEmptyTaskTreads: 0, + kvRangeReqs: make(map[uint64]*kvRangeRequest), + kvHealReqs: make(map[uint64]*kvHealRequest), } } @@ -431,6 +462,8 @@ func (s *Syncer) Sync(cancel chan struct{}) error { // Assign all the Data retrieval tasks to any free peers s.assignKVHealTasks(kvHealResps, kvHealReqFails, cancel) + s.assignKVEmptyTasks() + // Wait for something to happen select { case <-time.After(requestTimeoutInMillisecond): @@ -465,6 +498,7 @@ func (s *Syncer) Sync(cancel chan struct{}) error { func (s *Syncer) loadSyncStatus() { // Start a fresh sync for retrieval. s.kvSynced, s.kvBytes = 0, 0 + s.emptyKVToFill, s.emptyKVFilled = 0, 0 var progress SyncProgress if status := rawdb.ReadSstorageSyncStatus(s.db); status != nil { @@ -475,12 +509,19 @@ func (s *Syncer) loadSyncStatus() { log.Debug("Scheduled sstorage sync task", "Contract", task.Contract.Hex(), "shard", task.ShardId, "count", len(task.KvSubTasks)) task.HealTask.kvTask = task + task.statelessPeers = make(map[string]struct{}) for _, kvSubTask := range task.KvSubTasks { kvSubTask.kvTask = task kvSubTask.next = kvSubTask.First } + for _, kvSubEmptyTask := range task.KvSubEmptyTasks { + kvSubEmptyTask.kvTask = task + kvSubEmptyTask.next = kvSubEmptyTask.First + s.emptyKVToFill += (kvSubEmptyTask.Last - kvSubEmptyTask.First) + } } s.kvSynced, s.kvBytes = progress.KVSynced, progress.KVBytes + s.emptyKVFilled = progress.EmptyKVFilled } } @@ -504,13 +545,7 @@ func (s *Syncer) loadSyncStatus() { if exist { continue } - first, limit := sm.KvEntries()*sid, sm.KvEntries()*(sid+1)-1 - if lastKvIndex > 0 && first >= lastKvIndex { - continue - } - if lastKvIndex > 0 && limit >= lastKvIndex { - limit = lastKvIndex - 1 - } + task := kvTask{ Contract: contract, ShardId: sid, @@ -522,6 +557,17 @@ func (s *Syncer) loadSyncStatus() { kvTask: &task, Indexes: make(map[uint64]int64), } + + first, limit := sm.KvEntries()*sid, sm.KvEntries()*(sid+1) + firstEmpty, limitForEmpty := uint64(0), uint64(0) + if first >= lastKvIndex { + firstEmpty, limitForEmpty = first, limit + limit = first + } else if limit >= lastKvIndex { + firstEmpty, limitForEmpty = lastKvIndex, limit + limit = lastKvIndex + } + subTasks := make([]*kvSubTask, 0) // split task for a shard to 16 subtasks and if one batch is too small // set to minSubTaskSize @@ -544,33 +590,68 @@ func (s *Syncer) loadSyncStatus() { } subTasks = append(subTasks, &subTask) - first = last + 1 + first = last + } + + subEmptyTasks := make([]*kvSubEmptyTask, 0) + if limitForEmpty > 0 { + s.emptyKVToFill += limitForEmpty - firstEmpty + maxEmptyTaskSize := (limitForEmpty - firstEmpty + uint64(maxEmptyTaskTreads)) / uint64(maxEmptyTaskTreads) + if maxEmptyTaskSize < minSubTaskSize { + maxEmptyTaskSize = minSubTaskSize + } + + for firstEmpty < limitForEmpty { + last := firstEmpty + maxEmptyTaskSize + if last > limitForEmpty { + last = limitForEmpty + } + subTask := kvSubEmptyTask{ + kvTask: &task, + next: firstEmpty, + First: firstEmpty, + Last: last, + done: false, + } + + subEmptyTasks = append(subEmptyTasks, &subTask) + firstEmpty = last + } } - task.HealTask, task.KvSubTasks = &healTask, subTasks + task.HealTask, task.KvSubTasks, task.KvSubEmptyTasks = &healTask, subTasks, subEmptyTasks s.tasks = append(s.tasks, &task) } } allDone := true for _, task := range s.tasks { - if len(task.KvSubTasks) > 0 || len(task.HealTask.Indexes) > 0 { + if len(task.KvSubTasks) > 0 || len(task.HealTask.Indexes) > 0 || len(task.KvSubEmptyTasks) > 0 { allDone = false break } } if allDone { - s.syncDone = true + s.setSyncDone() } } +type SstorSyncDone struct{} + +func (s *Syncer) setSyncDone() { + s.syncDone = true + s.mux.Post(SstorSyncDone{}) +} + // saveSyncStatus marshals the remaining sync tasks into leveldb. func (s *Syncer) saveSyncStatus() { // Store the actual progress markers progress := &SyncProgress{ - Tasks: s.tasks, - KVSynced: s.kvSynced, - KVBytes: s.kvBytes, + Tasks: s.tasks, + KVSynced: s.kvSynced, + KVBytes: s.kvBytes, + EmptyKVToFill: s.emptyKVToFill, + EmptyKVFilled: s.emptyKVFilled, } status, err := json.Marshal(progress) if err != nil { @@ -585,8 +666,10 @@ func (s *Syncer) Progress() (*SyncProgress, uint64) { defer s.lock.Unlock() progress := &SyncProgress{ - KVSynced: s.kvSynced, - KVBytes: s.kvBytes, + KVSynced: s.kvSynced, + KVBytes: s.kvBytes, + EmptyKVFilled: s.emptyKVFilled, + EmptyKVToFill: s.emptyKVToFill, } return progress, s.kvSyncing } @@ -606,7 +689,13 @@ func (s *Syncer) cleanKVTasks() { i-- } } - if len(task.KvSubTasks) > 0 { + for i := 0; i < len(task.KvSubEmptyTasks); i++ { + if task.KvSubEmptyTasks[i].done { + task.KvSubEmptyTasks = append(task.KvSubEmptyTasks[:i], task.KvSubEmptyTasks[i+1:]...) + i-- + } + } + if len(task.KvSubTasks) > 0 || len(task.KvSubEmptyTasks) > 0 { allDone = false } } @@ -614,7 +703,7 @@ func (s *Syncer) cleanKVTasks() { // If everything was just finalized, generate the account trie and start heal if allDone { s.lock.Lock() - s.syncDone = true + s.setSyncDone() s.lock.Unlock() log.Info("Sstorage sync done", "task count", len(s.tasks)) @@ -690,7 +779,7 @@ func (s *Syncer) assignKVRangeTasks(success chan *kvRangeResponse, fail chan *kv contract: task.Contract, shardId: task.ShardId, origin: subTask.next, - limit: subTask.Last, + limit: subTask.Last - 1, time: time.Now(), deliver: success, revert: fail, @@ -828,6 +917,50 @@ func (s *Syncer) assignKVHealTasks(success chan *kvHealResponse, fail chan *kvHe } } +// assignKVEmptyTasks attempts to match idle peers to heal kv requests to retrieval missing kv from the kv range request. +func (s *Syncer) assignKVEmptyTasks() { + s.lock.Lock() + defer s.lock.Unlock() + + // Iterate over all the tasks and try to find a pending one + for _, task := range s.tasks { + for _, subEmptyTask := range task.KvSubEmptyTasks { + if s.runningEmptyTaskTreads >= maxEmptyTaskTreads { + return + } + s.runningEmptyTaskTreads++ + if subEmptyTask.isRunning { + continue + } + subTask := subEmptyTask + subTask.isRunning = true + start, last := subTask.next, subTask.Last + if last > start+minSubTaskSize { + last = start + minSubTaskSize + } + go func(eTask *kvSubEmptyTask, contract common.Address, start, limit uint64) { + t := time.Now() + next, err := s.chain.FillSstorWithEmptyKV(contract, start, limit) + if err != nil { + log.Warn("fill in empty fail", "err", err.Error()) + } + log.Warn("FillSstorWithEmptyKV", "time", time.Now().Sub(t).Seconds()) + eTask.next = next + filled := next - start + s.emptyKVFilled += filled + if s.emptyKVToFill > filled { + s.emptyKVToFill -= filled + } + if eTask.next >= eTask.Last { + eTask.done = true + } + eTask.isRunning = false + s.runningEmptyTaskTreads-- + }(subTask, task.Contract, start, last-1) + } + } +} + // revertRequests locates all the currently pending reuqests from a particular // peer and reverts them, rescheduling for others to fulfill. func (s *Syncer) revertRequests(peer string) { @@ -981,7 +1114,7 @@ func (s *Syncer) processKVRangeResponse(res *kvRangeResponse) { res.task.kvTask.HealTask.Indexes[n] = 0 } } - if max == res.task.Last { + if max == res.task.Last-1 { res.task.done = true } else { res.task.next = max + 1 @@ -1079,7 +1212,7 @@ func (s *Syncer) OnKVs(peer SyncPeer, id uint64, providerAddr common.Address, kv // get id range and check range sm := sstorage.ContractToShardManager[req.contract] if sm == nil { - logger.Debug("Peer rejected kv request") + logger.Debug("Peer rejected kv request", "len", len(req.task.kvTask.HealTask.Indexes)) req.task.kvTask.statelessPeers[peer.ID()] = struct{}{} s.lock.Unlock() @@ -1174,7 +1307,7 @@ func (s *Syncer) OnKVRange(peer SyncPeer, id uint64, providerAddr common.Address // get id range and check range sm := sstorage.ContractToShardManager[req.contract] if sm == nil { - logger.Debug("Peer rejected kv request") + logger.Debug("Peer rejected kv request", "origin", req.origin, "limit", req.limit) req.task.kvTask.statelessPeers[peer.ID()] = struct{}{} s.lock.Unlock() @@ -1250,6 +1383,7 @@ func (s *Syncer) report(force bool) { progress = fmt.Sprintf("%.2f%%", float64(synced)*100/float64(kvsToSync+synced)) kv = fmt.Sprintf("%v@%v", log.FormatLogfmtUint64(s.kvSynced), s.kvBytes.TerminalString()) ) - log.Info("State sync in progress", "synced", progress, "state", synced, "kvsToSync", kvsToSync, - "sub task remain", subTaskRemain, "kv", kv, "eta", common.PrettyDuration(estTime-elapsed)) + log.Info("Sstorage sync in progress", "synced", progress, "state", synced, "kvsToSync", kvsToSync, + "sub task remain", subTaskRemain, "kv", kv, "eta", common.PrettyDuration(estTime-elapsed), + "empty KV filled", s.emptyKVFilled, "empty KV to fill", s.emptyKVToFill) } diff --git a/eth/protocols/sstorage/sync_test.go b/eth/protocols/sstorage/sync_test.go index 25a50c18c541..85ca67c33c5b 100644 --- a/eth/protocols/sstorage/sync_test.go +++ b/eth/protocols/sstorage/sync_test.go @@ -20,6 +20,7 @@ import ( "bytes" "encoding/binary" "fmt" + "github.com/ethereum/go-ethereum/event" "math/rand" "os" "sync" @@ -36,12 +37,12 @@ import ( "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/sstorage" "github.com/holiman/uint256" - "golang.org/x/crypto/sha3" ) var ( - contract = common.HexToAddress("0x0000000000000000000000000000000003330001") - kvEntries = uint64(512) + contract = common.HexToAddress("0x0000000000000000000000000000000003330001") + kvEntriesBits = uint64(9) + kvEntries = uint64(1) << 9 ) type ( @@ -62,6 +63,31 @@ func (c *blockChain) CurrentBlock() *types.Block { return c.block } +func (bc *blockChain) FillSstorWithEmptyKV(contract common.Address, start, limit uint64) (uint64, error) { + sm := sstorage.ContractToShardManager[contract] + if sm == nil { + return start, fmt.Errorf("kv verify fail: contract not support, contract: %s", contract.Hex()) + } + + empty := make([]byte, 0) + lastKvIdx, err := bc.GetSstorageLastKvIdx(contract) + if err != nil { + return start, fmt.Errorf("get lastKvIdx for FillEmptyKV fail, err: %s", err.Error()) + } + for idx := start; idx <= limit; idx++ { + if lastKvIdx > idx { + continue + } + _, err = sm.TryWrite(idx, empty, common.Hash{}) + if err != nil { + err = fmt.Errorf("write empty to kv file fail, index: %d; error: %s", idx, err.Error()) + return idx, err + } + } + + return limit + 1, nil +} + func (c *blockChain) VerifyAndWriteKV(contract common.Address, data map[uint64][]byte, providerAddr common.Address) (uint64, uint64, []uint64, error) { var ( synced uint64 @@ -77,7 +103,7 @@ func (c *blockChain) VerifyAndWriteKV(contract common.Address, data map[uint64][ synced++ syncedBytes += uint64(len(val)) - metaHash, meta, err := core.GetSstorageMetadata(c.stateDB, contract, idx) + _, meta, err := core.GetSstorageMetadata(c.stateDB, contract, idx) if err != nil || meta == nil { log.Warn("processKVResponse: get vkv MetaHash for verification fail", "error", err) continue @@ -89,7 +115,7 @@ func (c *blockChain) VerifyAndWriteKV(contract common.Address, data map[uint64][ continue } - success, err := sm.TryWrite(idx, rawData, metaHash) + success, err := sm.TryWrite(idx, rawData, common.BytesToHash(meta.HashInMeta)) if err != nil { log.Warn("write kv fail", "error", err) continue @@ -106,11 +132,11 @@ func (c *blockChain) ReadEncodedKVsByIndexList(contract common.Address, shardId if sm == nil { return common.Address{}, nil, fmt.Errorf("shard manager for contract %s is not support", contract.Hex()) } - miner, ok := sm.GetShardMiner(shardId) if !ok { return common.Address{}, nil, fmt.Errorf("shard %d do not support for contract %s", shardId, contract.Hex()) } + res := make([]*core.KV, 0) for _, idx := range indexes { _, meta, err := core.GetSstorageMetadata(c.stateDB, contract, idx) @@ -127,17 +153,17 @@ func (c *blockChain) ReadEncodedKVsByIndexList(contract common.Address, shardId return miner, res, nil } -func (c *blockChain) ReadEncodedKVsByIndexRange(contract common.Address, shardId uint64, origin uint64, - limit uint64, bytes uint64) (common.Address, []*core.KV, error) { +func (c *blockChain) ReadEncodedKVsByIndexRange(contract common.Address, shardId uint64, origin uint64, limit uint64, + bytes uint64) (common.Address, []*core.KV, error) { sm := sstorage.ContractToShardManager[contract] if sm == nil { return common.Address{}, nil, fmt.Errorf("shard manager for contract %s is not support", contract.Hex()) } - miner, ok := sm.GetShardMiner(shardId) if !ok { return common.Address{}, nil, fmt.Errorf("shard %d do not support for contract %s", shardId, contract.Hex()) } + res := make([]*core.KV, 0) read := uint64(0) for idx := origin; idx <= limit; idx++ { @@ -293,7 +319,6 @@ func createKVRequestResponse(t *testPeer, id uint64, stateDB *state.StateDB, con } else { values = append(values, &core.KV{Idx: idx, Data: bs}) } - } } @@ -317,7 +342,7 @@ func setupSyncer(shards map[common.Address][]uint64, stateDB *state.StateDB, las rlp.DecodeBytes(blockEnc, &block) chain := blockChain{block: &block, stateDB: stateDB} chain.lastKvIdx = lastKvIdx - syncer := NewSyncer(db, &chain, shards) + syncer := NewSyncer(db, &chain, new(event.TypeMux), shards) for _, peer := range peers { syncer.Register(peer) peer.remote = syncer @@ -333,17 +358,7 @@ func getSKey(contract common.Address, idx uint64) common.Hash { slotdata := slot[:] data := append(keydata, slotdata...) - return hash(data) -} - -func hash(data []byte) common.Hash { - hasher := sha3.NewLegacyKeccak256().(crypto.KeccakState) - hasher.Write(data) - - hashRes := common.Hash{} - hasher.Read(hashRes[:]) - - return hashRes + return crypto.Keccak256Hash(data) } func checkStall(t *testing.T, term func()) chan struct{} { @@ -383,13 +398,7 @@ func getSlotHash(slotIdx uint64, key common.Hash) common.Hash { slotdata := slot[:] data := append(keydata, slotdata...) - hasher := sha3.NewLegacyKeccak256().(crypto.KeccakState) - hasher.Write(data) - - hashRes := common.Hash{} - hasher.Read(hashRes[:]) - - return hashRes + return crypto.Keccak256Hash(data) } // makeKVStorage generate a range of storage Data and its metadata @@ -412,7 +421,7 @@ func makeKVStorage(stateDB *state.StateDB, contract common.Address, shards []uin key := getSlotHash(2, uint256.NewInt(i).Bytes32()) stateDB.SetState(contract, key, skey) - meta := generateMetadata(i, uint64(len(val)), hash(val)) + meta := generateMetadata(i, uint64(len(val)), sstorage.MerkleRootWithMinTree(val)) key = getSlotHash(1, skey) stateDB.SetState(contract, key, meta) } @@ -424,10 +433,12 @@ func makeKVStorage(stateDB *state.StateDB, contract common.Address, shards []uin return shardData, shardList } -func createSstorage(contract common.Address, shardIdxList []uint64, kvSize, - kvEntries, filePerShard uint64, miner common.Address) (map[common.Address][]uint64, []string) { - sm := sstorage.NewShardManager(contract, kvSize, kvEntries) +func createSstorage(contract common.Address, shardIdxList []uint64, kvSizeBits, + kvEntriesBits, filePerShard uint64, miner common.Address) (map[common.Address][]uint64, []string) { + sm := sstorage.NewShardManager(contract, kvSizeBits, kvEntriesBits) sstorage.ContractToShardManager[contract] = sm + kvSize := uint64(1) << kvSizeBits + kvEntries := uint64(1) << kvEntriesBits files := make([]string, 0) for _, shardIdx := range shardIdxList { @@ -436,10 +447,9 @@ func createSstorage(contract common.Address, shardIdxList []uint64, kvSize, fileId := shardIdx*filePerShard + i fileName := fmt.Sprintf(".\\ss%d.dat", fileId) files = append(files, fileName) - chunkPerfile := kvEntries * kvSize / sstorage.CHUNK_SIZE / filePerShard - startChunkId := fileId * chunkPerfile - endChunkId := (fileId + 1) * chunkPerfile - _, err := sstorage.Create(fileName, startChunkId, endChunkId, 0, kvSize, sstorage.ENCODE_KECCAK_256, miner) + kvPerfile := kvEntries / filePerShard + startKVId := fileId * kvPerfile + _, err := sstorage.Create(fileName, startKVId, kvPerfile, 0, kvSize, sstorage.ENCODE_KECCAK_256, miner) if err != nil { log.Crit("open failed", "error", err) } @@ -451,6 +461,9 @@ func createSstorage(contract common.Address, shardIdxList []uint64, kvSize, } sm.AddDataFile(df) } + for i := shardIdx * sm.KvEntries(); i < (shardIdx+1)*sm.KvEntries(); i++ { + sm.TryWrite(i, empty, common.Hash{}) + } } shards := make(map[common.Address][]uint64) @@ -467,20 +480,28 @@ func verifyKVs(stateDB *state.StateDB, data map[common.Address]map[uint64][]byte } for idx, val := range shards { _, meta, err := core.GetSstorageMetadata(stateDB, contract, idx) - if _, ok := destroyedList[idx]; ok { - val = make([]byte, shardData.MaxKvSize()) - } if err != nil { t.Fatalf("get MetaHash data fail with err: %s.", err.Error()) } + sval, ok, err := shardData.TryRead(idx, len(val), common.BytesToHash(meta.HashInMeta)) if err != nil { t.Fatalf("TryRead sstorage Data fail. err: %s", err.Error()) } if !ok { - t.Fatalf("TryRead sstroage Data fail. err: %s", "shard Idx not support") + t.Fatalf("TryRead sstroage Data fail. err: %s, index %d", "shard Idx not support", idx) } + if _, ok := destroyedList[idx]; ok { + val = make([]byte, sstorage.CHUNK_SIZE) + sval, ok, err = shardData.TryReadChunk(idx, common.BytesToHash(make([]byte, 24))) + if err != nil { + t.Fatalf("TryReadChunk fail. err: %s", err.Error()) + } + if !ok { + t.Fatalf("TryReadChunk fail. err: %s", "shard Idx not support") + } + } if !bytes.Equal(val, sval) { t.Fatalf("verify KV failed; index: %d; val: %s; sval: %s", idx, common.Bytes2Hex(val), common.Bytes2Hex(sval)) @@ -635,7 +656,7 @@ func checkTasksWithBaskTasks(baseTasks, tasks []*kvTask) error { // TestReadWrite tests a basic sstorage read/wrtie func TestReadWrite(t *testing.T) { - shards, files := createSstorage(contract, []uint64{0}, sstorage.CHUNK_SIZE, kvEntries, 1, common.Address{}) + shards, files := createSstorage(contract, []uint64{0}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1, common.Address{}) if shards == nil { t.Fatalf("createSstorage failed") } @@ -674,7 +695,7 @@ func TestSync(t *testing.T) { } ) - shards, files := createSstorage(contract, []uint64{0}, sstorage.CHUNK_SIZE, kvEntries, 1, common.Address{}) + shards, files := createSstorage(contract, []uint64{0}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1, common.Address{}) if shards == nil { t.Fatalf("createSstorage failed") } @@ -708,7 +729,8 @@ func TestMultiSubTasksSync(t *testing.T) { var ( once sync.Once cancel = make(chan struct{}) - entries = uint64(1024) + entriesBits = uint64(10) + entries = uint64(1) << 10 destroyedList = make(map[uint64]struct{}) stateDB, _ = state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) term = func() { @@ -718,7 +740,7 @@ func TestMultiSubTasksSync(t *testing.T) { } ) - shards, files := createSstorage(contract, []uint64{0}, sstorage.CHUNK_SIZE, entries, 1, common.Address{}) + shards, files := createSstorage(contract, []uint64{0}, sstorage.CHUNK_SIZE_BITS, entriesBits, 1, common.Address{}) if shards == nil { t.Fatalf("createSstorage failed") } @@ -761,7 +783,7 @@ func TestMultiSync(t *testing.T) { } ) - shards, files := createSstorage(contract, []uint64{0, 1, 2, 3, 4}, sstorage.CHUNK_SIZE, kvEntries, 1, common.Address{}) + shards, files := createSstorage(contract, []uint64{0, 1, 2, 3, 4}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1, common.Address{}) if shards == nil { t.Fatalf("createSstorage failed") } @@ -814,7 +836,7 @@ func TestSyncWithEmptyResponse(t *testing.T) { } ) - shards, files := createSstorage(contract, []uint64{0}, sstorage.CHUNK_SIZE, kvEntries, 1, common.Address{}) + shards, files := createSstorage(contract, []uint64{0}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1, common.Address{}) if shards == nil { t.Fatalf("createSstorage failed") } @@ -861,7 +883,7 @@ func TestSyncWithNoResponse(t *testing.T) { } ) - shards, files := createSstorage(contract, []uint64{0}, sstorage.CHUNK_SIZE, kvEntries, 1, common.Address{}) + shards, files := createSstorage(contract, []uint64{0}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1, common.Address{}) if shards == nil { t.Fatalf("createSstorage failed") } @@ -906,10 +928,10 @@ func TestSyncWithFewerResult(t *testing.T) { close(cancel) }) } - reduce = rand.Uint64()%(kvEntries/2) - 1 + reduce = rand.Uint64()%(kvEntriesBits/2) - 1 ) - shards, files := createSstorage(contract, []uint64{0}, sstorage.CHUNK_SIZE, kvEntries, 1, common.Address{}) + shards, files := createSstorage(contract, []uint64{0}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1, common.Address{}) if shards == nil { t.Fatalf("createSstorage failed") } @@ -951,7 +973,7 @@ func TestSyncMismatchWithMeta(t *testing.T) { } ) - shards, files := createSstorage(contract, []uint64{0}, sstorage.CHUNK_SIZE, kvEntries, 1, common.Address{}) + shards, files := createSstorage(contract, []uint64{0}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1, common.Address{}) if shards == nil { t.Fatalf("createSstorage failed") } @@ -995,7 +1017,7 @@ func TestMultiSyncWithDataOverlay(t *testing.T) { } ) - _, files := createSstorage(contract, []uint64{0, 1, 2, 3}, sstorage.CHUNK_SIZE, kvEntries, 1, common.Address{}) + _, files := createSstorage(contract, []uint64{0, 1, 2, 3}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1, common.Address{}) defer func(files []string) { for _, file := range files { @@ -1016,7 +1038,7 @@ func TestMultiSyncWithDataOverlay(t *testing.T) { peer0 := mkSource("source_0", shards, data) data, shards = makeKVStorage(nil, contract, []uint64{2, 3}, kvEntries) peer1 := mkSource("source_1", shards, data) - /* data, shards = makeKVStorage(nil, contract, []uint64{2, 3}, kvEntries) + /* data, shards = makeKVStorage(nil, contract, []uint64{2, 3}, kvEntriesBits) peer2 := mkSource("source_2", shards, data)*/ syncer := setupSyncer(localShards, stateDB, kvEntries*4, peer0, peer1) @@ -1042,7 +1064,7 @@ func TestMultiSyncWithDataOverlayWithDestroyed(t *testing.T) { ) requestTimeoutInMillisecond = 50 * time.Millisecond // Millisecond - _, files := createSstorage(contract, []uint64{0, 1, 2}, sstorage.CHUNK_SIZE, kvEntries, 1, common.Address{}) + _, files := createSstorage(contract, []uint64{0, 1, 2}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1, common.Address{}) defer func(files []string) { for _, file := range files { @@ -1089,7 +1111,7 @@ func TestAddPeerDuringSyncing(t *testing.T) { ) requestTimeoutInMillisecond = 50 * time.Millisecond // Millisecond - _, files := createSstorage(contract, []uint64{0, 1, 2}, sstorage.CHUNK_SIZE, kvEntries, 1, common.Address{}) + _, files := createSstorage(contract, []uint64{0, 1, 2}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1, common.Address{}) defer func(files []string) { for _, file := range files { @@ -1133,10 +1155,10 @@ func TestAddPeerDuringSyncing(t *testing.T) { func TestSaveAndLoadSyncStatus(t *testing.T) { var ( stateDB, _ = state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - entries = kvEntries * 10 - lastKvIndex = entries*3 - kvEntries - 9 + entries = kvEntriesBits * 10 + lastKvIndex = entries*3 - kvEntriesBits - 9 ) - shards, files := createSstorage(contract, []uint64{0, 1, 2}, sstorage.CHUNK_SIZE, kvEntries, 1, common.Address{}) + shards, files := createSstorage(contract, []uint64{0, 1, 2}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1, common.Address{}) if shards == nil { t.Fatalf("createSstorage failed") } diff --git a/params/config.go b/params/config.go index 73f88c9e3142..fa424d0ab773 100644 --- a/params/config.go +++ b/params/config.go @@ -34,7 +34,7 @@ var ( SepoliaGenesisHash = common.HexToHash("0x25a5cc106eea7138acab33231d7160d69cb777ee0c2c553fcddf5138993e6dd9") RinkebyGenesisHash = common.HexToHash("0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177") GoerliGenesisHash = common.HexToHash("0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a") - Web3QTestnetGenesisHash = common.HexToHash("0xe1b551a47236ea806a1a9f6a9082ab989cffd999a44caa6015edc27136e0aab5") + Web3QTestnetGenesisHash = common.HexToHash("0xaba50efdf3572a2d25dab20e08bb5d9f30aea360c74aff451e702cf749094d70") Web3QGalileoGenesisHash = common.HexToHash("0xa576a985390f3a643e2acdeaed074cc9866c99f6bdf3ca8c49ec959054703745") ) diff --git a/sstorage/data_file.go b/sstorage/data_file.go index 7a873926f192..b6f10e5c3cb5 100644 --- a/sstorage/data_file.go +++ b/sstorage/data_file.go @@ -21,7 +21,8 @@ const ( MAGIC = uint64(0xcf20bd770c22b2e1) VERSION = uint64(1) - CHUNK_SIZE = uint64(4096) + CHUNK_SIZE = uint64(4096) + CHUNK_SIZE_BITS = uint64(12) ) // A DataFile represents a local file for a consective chunks @@ -67,21 +68,25 @@ func UnmaskDataInPlace(userData []byte, maskData []byte) []byte { return userData } -func Create(filename string, chunkIdxStart uint64, chunkIdxLen uint64, epoch, maxKvSize uint64, encodeType uint64, miner common.Address) (*DataFile, error) { +func Create(filename string, kvIdxStart uint64, kvIdxLen uint64, epoch, maxKvSize uint64, encodeType uint64, miner common.Address) (*DataFile, error) { log.Info("Creating file", "filename", filename) file, err := os.Create(filename) if err != nil { return nil, err } + if maxKvSize%CHUNK_SIZE != 0 { + return nil, fmt.Errorf("max kv size %% CHUNK_SIZE should be 0") + } + chunkPerKV := maxKvSize / CHUNK_SIZE // actual initialization is done when synchronize - err = fallocate.Fallocate(file, int64(CHUNK_SIZE*chunkIdxLen), int64(CHUNK_SIZE)) + err = fallocate.Fallocate(file, int64(CHUNK_SIZE), int64(maxKvSize*kvIdxLen)) if err != nil { return nil, err } dataFile := &DataFile{ file: file, - chunkIdxStart: chunkIdxStart, - chunkIdxLen: chunkIdxLen, + chunkIdxStart: kvIdxStart * chunkPerKV, + chunkIdxLen: kvIdxLen * chunkPerKV, encodeType: encodeType, maxKvSize: maxKvSize, miner: miner, @@ -250,3 +255,19 @@ func (df *DataFile) readHeader() error { return nil } + +func (df *DataFile) Miner() common.Address { + return df.miner +} + +func (df *DataFile) KVSize() uint64 { + return df.maxKvSize +} + +func (df *DataFile) EndChunkIdx() uint64 { + return df.chunkIdxStart + df.chunkIdxLen - 1 +} + +func (df *DataFile) StartChunkIdx() uint64 { + return df.chunkIdxStart +} diff --git a/sstorage/data_shard.go b/sstorage/data_shard.go index 2daaeb38f109..e2ff23e86e57 100644 --- a/sstorage/data_shard.go +++ b/sstorage/data_shard.go @@ -99,7 +99,39 @@ func (ds *DataShard) GetStorageFile(chunkIdx uint64) *DataFile { return nil } -// Read the encoded data from storage and return it. +// ReadChunkEncoded read the encoded data from storage and return it. +func (ds *DataShard) ReadChunkEncoded(kvIdx uint64, chunkIdx uint64) ([]byte, error) { + return ds.readChunkWith(kvIdx, chunkIdx, func(cdata []byte, chunkIdx uint64) []byte { + return cdata + }) +} + +// ReadChunk read the encoded data from storage and decode it. +func (ds *DataShard) ReadChunk(kvIdx uint64, chunkIdx uint64, commit common.Hash) ([]byte, error) { + return ds.readChunkWith(kvIdx, chunkIdx, func(cdata []byte, chunkIdx uint64) []byte { + encodeKey := calcEncodeKey(commit, chunkIdx, ds.dataFiles[0].miner) + return decodeChunk(cdata, ds.dataFiles[0].encodeType, encodeKey) + }) +} + +// readChunkWith read the encoded chunk from storage with a decoder. +func (ds *DataShard) readChunkWith(kvIdx uint64, chunkIdx uint64, decoder func([]byte, uint64) []byte) ([]byte, error) { + if !ds.Contains(kvIdx) { + return nil, fmt.Errorf("kv not found") + } + if chunkIdx >= ds.chunksPerKv { + return nil, fmt.Errorf("chunkIdx out of range, chunkIdx: %d vs chunksPerKv %d", chunkIdx, ds.chunksPerKv) + } + idx := kvIdx*ds.chunksPerKv + chunkIdx + data, err := ds.readChunk(idx, int(CHUNK_SIZE)) + if err != nil { + return nil, err + } + data = decoder(data, idx) + return data, nil +} + +// ReadEncoded read the encoded data from storage and return it. func (ds *DataShard) ReadEncoded(kvIdx uint64, readLen int) ([]byte, error) { return ds.readWith(kvIdx, readLen, func(cdata []byte, chunkIdx uint64) []byte { return cdata @@ -114,7 +146,7 @@ func (ds *DataShard) Read(kvIdx uint64, readLen int, commit common.Hash) ([]byte }) } -// Read the encoded data from storage with a decoder. +// readWith read the encoded data from storage with a decoder. func (ds *DataShard) readWith(kvIdx uint64, readLen int, decoder func([]byte, uint64) []byte) ([]byte, error) { if !ds.Contains(kvIdx) { return nil, fmt.Errorf("kv not found") @@ -231,7 +263,7 @@ func decodeChunk(bs []byte, encodeType uint64, encodeKey common.Hash) []byte { } else if encodeType == NO_ENCODE { return bs } else if encodeType == ENCODE_ETHASH { - return MaskDataInPlace(pora.GetMaskData(0, encodeKey, len(bs), nil), bs) + return UnmaskDataInPlace(pora.GetMaskData(0, encodeKey, len(bs), nil), bs) } else { panic("unsupported encode type") } @@ -246,24 +278,16 @@ func (ds *DataShard) Write(kvIdx uint64, b []byte, commit common.Hash) error { if uint64(len(b)) > ds.kvSize { return fmt.Errorf("write data too large") } - + cb := make([]byte, ds.kvSize) + copy(cb, b) for i := uint64(0); i < ds.chunksPerKv; i++ { - off := int(i * CHUNK_SIZE) - if off >= len(b) { - break - } - writeLen := len(b) - off - if writeLen > int(CHUNK_SIZE) { - writeLen = int(CHUNK_SIZE) - } - chunkIdx := kvIdx*ds.chunksPerKv + i encodeKey := calcEncodeKey(commit, chunkIdx, ds.Miner()) - encodedChunk := encodeChunk(b[off:off+writeLen], ds.EncodeType(), encodeKey) + encodedChunk := encodeChunk(cb[int(i*CHUNK_SIZE):int((i+1)*CHUNK_SIZE)], ds.EncodeType(), encodeKey) err := ds.writeChunk(chunkIdx, encodedChunk) if err != nil { - return nil + return err } } return nil diff --git a/sstorage/merklelib.go b/sstorage/merklelib.go new file mode 100644 index 000000000000..f3d2c4982c34 --- /dev/null +++ b/sstorage/merklelib.go @@ -0,0 +1,129 @@ +package sstorage + +import ( + "fmt" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" +) + +func GetProof(data []byte, nChunkBits, chunkIdx uint64) ([]common.Hash, error) { + if len(data) == 0 { + return nil, nil + } + nChunks := uint64(1) << nChunkBits + if chunkIdx >= nChunks { + return []common.Hash{}, fmt.Errorf("index out of scope") + } + nodes := make([]common.Hash, nChunks) + for i := uint64(0); i < nChunks; i++ { + off := i * CHUNK_SIZE + if off > uint64(len(data)) { + break + } + l := uint64(len(data)) - off + if l >= CHUNK_SIZE { + l = CHUNK_SIZE + } + nodes[i] = crypto.Keccak256Hash(data[off : off+l]) + } + n, proofIdx := nChunks, uint64(0) + proofs := make([]common.Hash, nChunkBits) + for n != 1 { + proofs[proofIdx] = nodes[(chunkIdx/2)*2+1-chunkIdx%2] + for i := uint64(0); i < n/2; i++ { + nodes[i] = crypto.Keccak256Hash(nodes[i*2].Bytes(), nodes[i*2+1].Bytes()) + } + n = n / 2 + chunkIdx = chunkIdx / 2 + proofIdx = proofIdx + 1 + } + return proofs, nil +} + +func CalculateRootWithProof(dataHash common.Hash, chunkIdx uint64, proofs []common.Hash) (common.Hash, error) { + if len(proofs) == 0 { + return dataHash, nil + } + hash := dataHash + nChunkBits := uint64(len(proofs)) + if chunkIdx >= uint64(1)<= l { + // empty mean the leaf is zero + break + } + size := l - off + if size >= CHUNK_SIZE { + size = CHUNK_SIZE + } + hash := crypto.Keccak256Hash(data[off : off+size]) + nodes[i] = hash + } + n := chunkPerKV + for n != 1 { + for i := uint64(0); i < n/2; i++ { + nodes[i] = crypto.Keccak256Hash(nodes[i*2].Bytes(), nodes[i*2+1].Bytes()) + } + + n = n / 2 + } + return nodes[0] +} + +func findNChunk(dataLen uint64) (uint64, uint64) { + if dataLen == 0 { + return 0, 0 + } + n := (dataLen+CHUNK_SIZE-1)/CHUNK_SIZE - 1 + nChunkBits := uint64(0) + for n != 0 { + nChunkBits++ + n = n >> 1 + } + + return uint64(1) << nChunkBits, nChunkBits +} + +func GetProofWithMinTree(data []byte, nChunkBits, chunkIdx uint64) ([]common.Hash, error) { + if len(data) == 0 { + return []common.Hash{}, nil + } + nChunks := uint64(1) << nChunkBits + if chunkIdx >= nChunks { + return []common.Hash{}, fmt.Errorf("index out of scope") + } + nMinChunks, nMinChunkBits := findNChunk(uint64(len(data))) + if chunkIdx >= nMinChunks { + return []common.Hash{}, nil + } + return GetProof(data, nMinChunkBits, chunkIdx) +} + +func MerkleRootWithMinTree(data []byte) common.Hash { + l := uint64(len(data)) + if l == 0 { + return common.Hash{} + } + nChunk, _ := findNChunk(uint64(len(data))) + return MerkleRoot(data, nChunk) +} diff --git a/sstorage/shard_config.go b/sstorage/shard_config.go index 69480d0c5a2f..c1a53f2fb425 100644 --- a/sstorage/shard_config.go +++ b/sstorage/shard_config.go @@ -12,19 +12,19 @@ import ( var ContractToShardManager = make(map[common.Address]*ShardManager) type ShardInfo struct { - Contract common.Address - KVSize uint64 - KVEntries uint64 + Contract common.Address + KVSizeBits uint64 + KVEntrieBits uint64 } // TODO: move to chain specific config? var ShardInfos = []*ShardInfo{ - {common.HexToAddress("0x0000000000000000000000000000000003330001"), 4 * 1024, 256 * 1024}, + {common.HexToAddress("0x0000000000000000000000000000000003330001"), 17, 10}, } func InitializeConfig() { for _, sinfo := range ShardInfos { - ContractToShardManager[sinfo.Contract] = NewShardManager(sinfo.Contract, sinfo.KVSize, sinfo.KVEntries) + ContractToShardManager[sinfo.Contract] = NewShardManager(sinfo.Contract, sinfo.KVSizeBits, sinfo.KVEntrieBits) } } @@ -80,26 +80,16 @@ func AddDataShardFromConfig(cfg string) error { } func AddDataFileFromConfig(cfg string) error { - // Format is kvSize,dataFile - ss := strings.Split(cfg, ",") - if len(ss) != 2 || len(ss[0]) == 0 || len(ss[1]) == 0 { - return fmt.Errorf("incorrect data shard cfg") - } - - kvSize, err := parseKvSize(ss[0]) + df, err := OpenDataFile(cfg) if err != nil { return err } - sm := findShardManaager(kvSize) + sm := findShardManaager(df.maxKvSize) if sm == nil { - return fmt.Errorf("shard with kv size %d not found", kvSize) + return fmt.Errorf("shard with kv size %d not found", df.maxKvSize) } - df, err := OpenDataFile(ss[1]) - if err != nil { - return err - } return sm.AddDataFile(df) } diff --git a/sstorage/shard_manager.go b/sstorage/shard_manager.go index 0ad471114ddb..a8fd47e34676 100644 --- a/sstorage/shard_manager.go +++ b/sstorage/shard_manager.go @@ -9,29 +9,55 @@ import ( type ShardManager struct { shardMap map[uint64]*DataShard contractAddress common.Address + kvSizeBits uint64 kvSize uint64 + chunksPerKvBits uint64 chunksPerKv uint64 + kvEntriesBits uint64 kvEntries uint64 } -func NewShardManager(contractAddress common.Address, kvSize uint64, kvEntries uint64) *ShardManager { +func NewShardManager(contractAddress common.Address, kvSizeBits uint64, kvEntriesBits uint64) *ShardManager { return &ShardManager{ shardMap: make(map[uint64]*DataShard), contractAddress: contractAddress, - kvSize: kvSize, - chunksPerKv: kvSize / CHUNK_SIZE, - kvEntries: kvEntries, + kvSizeBits: kvSizeBits, + kvSize: 1 << kvSizeBits, + kvEntriesBits: kvEntriesBits, + kvEntries: 1 << kvEntriesBits, + chunksPerKvBits: kvSizeBits - CHUNK_SIZE_BITS, + chunksPerKv: (1 << kvSizeBits) / CHUNK_SIZE, } } +func (sm *ShardManager) ShardMap() map[uint64]*DataShard { + return sm.shardMap +} + +func (sm *ShardManager) ChunksPerKv() uint64 { + return sm.chunksPerKv +} + +func (sm *ShardManager) ChunksPerKvBits() uint64 { + return sm.chunksPerKvBits +} + func (sm *ShardManager) KvEntries() uint64 { return sm.kvEntries } +func (sm *ShardManager) KvEntriesBits() uint64 { + return sm.kvEntriesBits +} + func (sm *ShardManager) MaxKvSize() uint64 { return sm.kvSize } +func (sm *ShardManager) MaxKvSizeBits() uint64 { + return sm.kvSizeBits +} + func (sm *ShardManager) AddDataShard(shardIdx uint64) error { if _, ok := sm.shardMap[shardIdx]; !ok { ds := NewDataShard(shardIdx, sm.kvSize, sm.kvEntries) @@ -53,7 +79,7 @@ func (sm *ShardManager) AddDataFile(df *DataFile) error { return ds.AddDataFile(df) } -// Encode a raw KV data, and write it to the underly storage file. +// TryWrite Encode a raw KV data, and write it to the underly storage file. // Return error if the write IO fails. // Return false if the data is not managed by the ShardManager. func (sm *ShardManager) TryWrite(kvIdx uint64, b []byte, commit common.Hash) (bool, error) { @@ -65,7 +91,7 @@ func (sm *ShardManager) TryWrite(kvIdx uint64, b []byte, commit common.Hash) (bo } } -// Read the encoded KV data from storage file and decode it. +// TryRead Read the encoded KV data from storage file and decode it. // Return error if the read IO fails. // Return false if the data is not managed by the ShardManager. func (sm *ShardManager) TryRead(kvIdx uint64, readLen int, commit common.Hash) ([]byte, bool, error) { @@ -85,12 +111,12 @@ func (sm *ShardManager) GetShardMiner(shardIdx uint64) (common.Address, bool) { return common.Address{}, false } -// Decode the encoded KV data. +// DecodeKV Decode the encoded KV data. func (sm *ShardManager) DecodeKV(kvIdx uint64, b []byte, hash common.Hash, providerAddr common.Address) ([]byte, bool, error) { return sm.DecodeOrEncodeKV(kvIdx, b, hash, providerAddr, false) } -// Encode the raw KV data. +// EncodeKV Encode the raw KV data. func (sm *ShardManager) EncodeKV(kvIdx uint64, b []byte, hash common.Hash, providerAddr common.Address) ([]byte, bool, error) { return sm.DecodeOrEncodeKV(kvIdx, b, hash, providerAddr, true) } @@ -126,7 +152,7 @@ func (sm *ShardManager) DecodeOrEncodeKV(kvIdx uint64, b []byte, hash common.Has return nil, false, nil } -// Read the encoded KV data from storage file and return it. +// TryReadEncoded Read the encoded KV data from storage file and return it. // Return error if the read IO fails. // Return false if the data is not managed by the ShardManager. func (sm *ShardManager) TryReadEncoded(kvIdx uint64, readLen int) ([]byte, bool, error) { @@ -139,6 +165,36 @@ func (sm *ShardManager) TryReadEncoded(kvIdx uint64, readLen int) ([]byte, bool, } } +// TryReadChunk Read the encoded KV data using chunkIdx from storage file and decode it. +// Return error if the read IO fails. +// Return false if the data is not managed by the ShardManager. +func (sm *ShardManager) TryReadChunk(chunkIdx uint64, commit common.Hash) ([]byte, bool, error) { + kvIdx := chunkIdx / sm.chunksPerKv + cIdx := chunkIdx % sm.chunksPerKv + shardIdx := kvIdx / sm.kvEntries + if ds, ok := sm.shardMap[shardIdx]; ok { + b, err := ds.ReadChunk(kvIdx, cIdx, commit) // read all the data + return b, true, err + } else { + return nil, false, nil + } +} + +// TryReadChunkEncoded Read the encoded KV data using chunkIdx from storage file and return it. +// Return error if the read IO fails. +// Return false if the data is not managed by the ShardManager. +func (sm *ShardManager) TryReadChunkEncoded(chunkIdx uint64) ([]byte, bool, error) { + kvIdx := chunkIdx / sm.chunksPerKv + cIdx := chunkIdx % sm.chunksPerKv + shardIdx := kvIdx / sm.kvEntries + if ds, ok := sm.shardMap[shardIdx]; ok { + b, err := ds.ReadChunkEncoded(kvIdx, cIdx) // read all the data + return b, true, err + } else { + return nil, false, nil + } +} + func (sm *ShardManager) IsComplete() error { for _, ds := range sm.shardMap { if !ds.IsComplete() { From 5bf29eb4cf1b2233b99326628a6d26c9abf00027 Mon Sep 17 00:00:00 2001 From: pingke Date: Fri, 5 May 2023 17:34:45 +0800 Subject: [PATCH 2/5] resolve comments --- core/blockchain.go | 6 ++++-- core/vm/contracts.go | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index 5d6f49d52d60..0624383f4ec0 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -2472,14 +2472,16 @@ func VerifyKV(sm *sstorage.ShardManager, idx uint64, val []byte, meta *SstorageM return data, nil } +// FillSstorWithEmptyKV this func is used to fill empty KVs to storage file to make the whole file data encoded. +// file in the KVs between start and limit(include limit). if the lastKvIdx larger than kv idx to fill, ignore it. func (bc *BlockChain) FillSstorWithEmptyKV(contract common.Address, start, limit uint64) (uint64, error) { sm := sstorage.ContractToShardManager[contract] if sm == nil { return start, fmt.Errorf("kv verify fail: contract not support, contract: %s", contract.Hex()) } - // bc.chainmu.TryLock() - // defer bc.chainmu.Unlock() + bc.chainmu.TryLock() + defer bc.chainmu.Unlock() empty := make([]byte, 0) lastKvIdx, err := bc.GetSstorageLastKvIdx(contract) diff --git a/core/vm/contracts.go b/core/vm/contracts.go index ea219822027f..e673289a7aaf 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -882,7 +882,7 @@ func (l *sstoragePisaUnmaskDaggerData) RunWith(env *PrecompiledContractCallEnv, binary.BigEndian.PutUint64(pb[32-8:32], 32) binary.BigEndian.PutUint64(pb[64-8:64], uint64(len(unmaskedChunk))) if bytes.Compare(unmaskedChunk[:20], make([]byte, 20)) != 0 { - log.Info("sstoragePisaUnmaskDaggerData() returns", "encodeType", encodeType, "chunkIdx", chunkIdx, + log.Debug("sstoragePisaUnmaskDaggerData() returns", "encodeType", encodeType, "chunkIdx", chunkIdx, "kvHash", kvHash, "miner", miner, "datalen", datalen, "masked chunk data", maskedChunkData[:20], "unmasked chunk data", unmaskedChunk[:20], "kvidx", chunkIdx/32, "chunkidx", chunkIdx%32) } From b548fa7ad036e72afd897712b774640a439ca54b Mon Sep 17 00:00:00 2001 From: pingke Date: Sat, 6 May 2023 10:26:54 +0800 Subject: [PATCH 3/5] change back validators list --- core/genesis.go | 8 ++++---- params/config.go | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/core/genesis.go b/core/genesis.go index 1f38121385ff..d46d3fded82b 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -441,10 +441,10 @@ func DefaultWeb3QTestnetGenesisBlock() *Genesis { common.HexToAddress("0x5C935469C5592Aeeac3372e922d9bCEabDF8830d"): {Balance: new(big.Int).Mul(big.NewInt(1000000000000000000), big.NewInt(1000000000))}, // 1e9 Ether }, NextValidators: []common.Address{ - common.HexToAddress("0xf3025bac5d2e9a179f78e0295a0dd0cd74003e16"), - common.HexToAddress("0x9b30603c22474755c0917254b3e86e78646c87de"), - common.HexToAddress("0x6562837cbadff8ccdfad90a5e40d44bdab561dad"), - common.HexToAddress("0x46a1a4832a046cf7a6d9fc862c155b2c90196dde"), + common.HexToAddress("0x2cff0b8e36522eba76f6f5c328d58581243882e4"), + common.HexToAddress("0x959994471dee37411f579dd2820a8743cba20f46"), + common.HexToAddress("0x977cfc676bb06daed7ddfa7711bcfe8d50c93081"), + common.HexToAddress("0xcd21538af6e33ff6fcf1e2ca20f771413004cfd3"), }, NextValidatorPowers: []uint64{1, 1, 1, 1}, } diff --git a/params/config.go b/params/config.go index fa424d0ab773..73f88c9e3142 100644 --- a/params/config.go +++ b/params/config.go @@ -34,7 +34,7 @@ var ( SepoliaGenesisHash = common.HexToHash("0x25a5cc106eea7138acab33231d7160d69cb777ee0c2c553fcddf5138993e6dd9") RinkebyGenesisHash = common.HexToHash("0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177") GoerliGenesisHash = common.HexToHash("0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a") - Web3QTestnetGenesisHash = common.HexToHash("0xaba50efdf3572a2d25dab20e08bb5d9f30aea360c74aff451e702cf749094d70") + Web3QTestnetGenesisHash = common.HexToHash("0xe1b551a47236ea806a1a9f6a9082ab989cffd999a44caa6015edc27136e0aab5") Web3QGalileoGenesisHash = common.HexToHash("0xa576a985390f3a643e2acdeaed074cc9866c99f6bdf3ca8c49ec959054703745") ) From ca865c7aed627af63c10a414a87a17efc1aab0bc Mon Sep 17 00:00:00 2001 From: pingke Date: Sat, 6 May 2023 16:11:16 +0800 Subject: [PATCH 4/5] small change --- eth/protocols/sstorage/sync_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eth/protocols/sstorage/sync_test.go b/eth/protocols/sstorage/sync_test.go index 85ca67c33c5b..b9f98eafb97e 100644 --- a/eth/protocols/sstorage/sync_test.go +++ b/eth/protocols/sstorage/sync_test.go @@ -20,7 +20,6 @@ import ( "bytes" "encoding/binary" "fmt" - "github.com/ethereum/go-ethereum/event" "math/rand" "os" "sync" @@ -33,6 +32,7 @@ import ( "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/sstorage" From 43ac8d691a65cb2a13c700964b8e0505879247b1 Mon Sep 17 00:00:00 2001 From: pingke Date: Tue, 9 May 2023 22:28:26 +0800 Subject: [PATCH 5/5] fix test case --- eth/protocols/sstorage/sync_test.go | 65 ++++++++++++++--------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/eth/protocols/sstorage/sync_test.go b/eth/protocols/sstorage/sync_test.go index eb2bb5ae64cd..9a7c30899c7e 100644 --- a/eth/protocols/sstorage/sync_test.go +++ b/eth/protocols/sstorage/sync_test.go @@ -40,9 +40,10 @@ import ( ) var ( + miner = common.HexToAddress("0x0000000000000000000000000000000000000001") contract = common.HexToAddress("0x0000000000000000000000000000000003330001") - kvEntriesBits = uint64(9) - kvEntries = uint64(1) << 9 + kvEntriesBits = uint64(4) + kvEntries = uint64(1) << 4 ) type ( @@ -271,7 +272,7 @@ func defaultKVRangeRequestHandler(t *testPeer, id uint64, contract common.Addres if vals == nil { t.test.Error("CreateKVRequestResponse fail: vals is nul.") } - if err := t.remote.OnKVRange(t, id, common.Address{}, vals); err != nil { + if err := t.remote.OnKVRange(t, id, miner, vals); err != nil { t.test.Errorf("Remote side rejected our delivery: %v", err) t.term() return err @@ -286,7 +287,7 @@ func defaultKVHealRequestHandler(t *testPeer, id uint64, contract common.Address if vals == nil { t.test.Error("CreateKVRequestResponse fail: vals is nul.") } - if err := t.remote.OnKVs(t, id, common.Address{}, vals); err != nil { + if err := t.remote.OnKVs(t, id, miner, vals); err != nil { t.test.Errorf("Remote side rejected our delivery: %v", err) t.term() return err @@ -313,7 +314,7 @@ func createKVRequestResponse(t *testPeer, id uint64, stateDB *state.StateDB, con if err != nil { return nil } - bs, _, _ := sm.EncodeKV(idx, data, common.BytesToHash(meta.HashInMeta), common.Address{}) + bs, _, _ := sm.EncodeKV(idx, data, common.BytesToHash(meta.HashInMeta), miner) if uint64(len(bs)) > meta.KVSize { values = append(values, &core.KV{Idx: idx, Data: bs[:meta.KVSize]}) } else { @@ -327,7 +328,7 @@ func createKVRequestResponse(t *testPeer, id uint64, stateDB *state.StateDB, con // emptyRequestKVRangeFn is a rejects AccountRangeRequests func emptyRequestKVRangeFn(t *testPeer, id uint64, contract common.Address, shardId uint64, kvList []uint64) error { - t.remote.OnKVRange(t, id, common.Address{}, nil) + t.remote.OnKVRange(t, id, miner, nil) return nil } @@ -365,7 +366,7 @@ func checkStall(t *testing.T, term func()) chan struct{} { testDone := make(chan struct{}) go func() { select { - case <-time.After(2 * time.Second): + case <-time.After(20 * time.Second): t.Log("Sync stalled") term() case <-testDone: @@ -433,7 +434,7 @@ func makeKVStorage(stateDB *state.StateDB, contract common.Address, shards []uin } func createSstorage(contract common.Address, shardIdxList []uint64, kvSizeBits, - kvEntriesBits, filePerShard uint64, miner common.Address) (map[common.Address][]uint64, []string) { + kvEntriesBits, filePerShard uint64) (map[common.Address][]uint64, []string) { sm := sstorage.NewShardManager(contract, kvSizeBits, kvEntriesBits) sstorage.ContractToShardManager[contract] = sm kvSize := uint64(1) << kvSizeBits @@ -446,9 +447,9 @@ func createSstorage(contract common.Address, shardIdxList []uint64, kvSizeBits, fileId := shardIdx*filePerShard + i fileName := fmt.Sprintf(".\\ss%d.dat", fileId) files = append(files, fileName) - kvPerfile := kvEntries / filePerShard - startKVId := fileId * kvPerfile - _, err := sstorage.Create(fileName, startKVId, kvPerfile, 0, kvSize, sstorage.ENCODE_KECCAK_256, miner) + chunkPerfile := kvEntries * kvSize / sstorage.CHUNK_SIZE / filePerShard + startChunkId := fileId * chunkPerfile + _, err := sstorage.Create(fileName, startChunkId, chunkPerfile, 0, kvSize, sstorage.ENCODE_ETHASH, miner) if err != nil { log.Crit("open failed", "error", err) } @@ -655,7 +656,7 @@ func checkTasksWithBaskTasks(baseTasks, tasks []*kvTask) error { // TestReadWrite tests a basic sstorage read/wrtie func TestReadWrite(t *testing.T) { - shards, files := createSstorage(contract, []uint64{0}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1, common.Address{}) + shards, files := createSstorage(contract, []uint64{0}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1) if shards == nil { t.Fatalf("createSstorage failed") } @@ -694,7 +695,7 @@ func TestSync(t *testing.T) { } ) - shards, files := createSstorage(contract, []uint64{0}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1, common.Address{}) + shards, files := createSstorage(contract, []uint64{0}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1) if shards == nil { t.Fatalf("createSstorage failed") } @@ -728,8 +729,6 @@ func TestMultiSubTasksSync(t *testing.T) { var ( once sync.Once cancel = make(chan struct{}) - entriesBits = uint64(10) - entries = uint64(1) << 10 destroyedList = make(map[uint64]struct{}) stateDB, _ = state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) term = func() { @@ -739,7 +738,7 @@ func TestMultiSubTasksSync(t *testing.T) { } ) - shards, files := createSstorage(contract, []uint64{0}, sstorage.CHUNK_SIZE_BITS, entriesBits, 1, common.Address{}) + shards, files := createSstorage(contract, []uint64{0}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1) if shards == nil { t.Fatalf("createSstorage failed") } @@ -758,8 +757,8 @@ func TestMultiSubTasksSync(t *testing.T) { return source } - data, _ := makeKVStorage(stateDB, contract, []uint64{0}, entries) - syncer := setupSyncer(shards, stateDB, entries, mkSource("source", shards, data)) + data, _ := makeKVStorage(stateDB, contract, []uint64{0}, kvEntries) + syncer := setupSyncer(shards, stateDB, kvEntries, mkSource("source", shards, data)) done := checkStall(t, term) if err := syncer.Sync(cancel); err != nil { t.Fatalf("sync failed: %v", err) @@ -782,7 +781,7 @@ func TestMultiSync(t *testing.T) { } ) - shards, files := createSstorage(contract, []uint64{0, 1, 2, 3, 4}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1, common.Address{}) + shards, files := createSstorage(contract, []uint64{0, 1, 2}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1) if shards == nil { t.Fatalf("createSstorage failed") } @@ -803,14 +802,14 @@ func TestMultiSync(t *testing.T) { peers := make([]*testPeer, 0) dataList := make([]map[common.Address]map[uint64][]byte, 0) - for i := 0; i < 5; i++ { + for i := 0; i < 3; i++ { data, shards := makeKVStorage(stateDB, contract, []uint64{uint64(i)}, kvEntries) dataList = append(dataList, data) peer := mkSource(fmt.Sprintf("source_%d", i), shards, data) peers = append(peers, peer) } - syncer := setupSyncer(shards, stateDB, kvEntries*5, peers...) + syncer := setupSyncer(shards, stateDB, kvEntries*3, peers...) done := checkStall(t, term) if err := syncer.Sync(cancel); err != nil { t.Fatalf("sync failed: %v", err) @@ -835,7 +834,7 @@ func TestSyncWithEmptyResponse(t *testing.T) { } ) - shards, files := createSstorage(contract, []uint64{0}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1, common.Address{}) + shards, files := createSstorage(contract, []uint64{0}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1) if shards == nil { t.Fatalf("createSstorage failed") } @@ -882,7 +881,7 @@ func TestSyncWithNoResponse(t *testing.T) { } ) - shards, files := createSstorage(contract, []uint64{0}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1, common.Address{}) + shards, files := createSstorage(contract, []uint64{0}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1) if shards == nil { t.Fatalf("createSstorage failed") } @@ -927,10 +926,10 @@ func TestSyncWithFewerResult(t *testing.T) { close(cancel) }) } - reduce = rand.Uint64()%(kvEntriesBits/2) - 1 + reduce = rand.Uint64() % (kvEntries / 2) ) - shards, files := createSstorage(contract, []uint64{0}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1, common.Address{}) + shards, files := createSstorage(contract, []uint64{0}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1) if shards == nil { t.Fatalf("createSstorage failed") } @@ -972,7 +971,7 @@ func TestSyncMismatchWithMeta(t *testing.T) { } ) - shards, files := createSstorage(contract, []uint64{0}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1, common.Address{}) + shards, files := createSstorage(contract, []uint64{0}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1) if shards == nil { t.Fatalf("createSstorage failed") } @@ -1016,7 +1015,7 @@ func TestMultiSyncWithDataOverlay(t *testing.T) { } ) - _, files := createSstorage(contract, []uint64{0, 1, 2, 3}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1, common.Address{}) + _, files := createSstorage(contract, []uint64{0, 1, 2, 3}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1) defer func(files []string) { for _, file := range files { @@ -1063,7 +1062,7 @@ func TestMultiSyncWithDataOverlayWithDestroyed(t *testing.T) { ) requestTimeoutInMillisecond = 50 * time.Millisecond // Millisecond - _, files := createSstorage(contract, []uint64{0, 1, 2}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1, common.Address{}) + _, files := createSstorage(contract, []uint64{0, 1, 2}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1) defer func(files []string) { for _, file := range files { @@ -1110,7 +1109,7 @@ func TestAddPeerDuringSyncing(t *testing.T) { ) requestTimeoutInMillisecond = 50 * time.Millisecond // Millisecond - _, files := createSstorage(contract, []uint64{0, 1, 2}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1, common.Address{}) + _, files := createSstorage(contract, []uint64{0, 1, 2}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1) defer func(files []string) { for _, file := range files { @@ -1154,10 +1153,10 @@ func TestAddPeerDuringSyncing(t *testing.T) { func TestSaveAndLoadSyncStatus(t *testing.T) { var ( stateDB, _ = state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - entries = kvEntriesBits * 10 - lastKvIndex = entries*3 - kvEntriesBits - 9 + entries = uint64(1) << kvEntriesBits + lastKvIndex = entries*3 - kvEntriesBits - 1 ) - shards, files := createSstorage(contract, []uint64{0, 1, 2}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1, common.Address{}) + shards, files := createSstorage(contract, []uint64{0, 1, 2}, sstorage.CHUNK_SIZE_BITS, kvEntriesBits, 1) if shards == nil { t.Fatalf("createSstorage failed") } @@ -1169,7 +1168,7 @@ func TestSaveAndLoadSyncStatus(t *testing.T) { }(files) syncer := setupSyncer(shards, stateDB, kvEntries) - task0 := createKvTask(contract, entries, 0, lastKvIndex, 20) + task0 := createKvTask(contract, entries, 0, lastKvIndex, 8) task0.KvSubTasks = make([]*kvSubTask, 0) task1 := createKvTask(contract, entries, 1, lastKvIndex, 4) task2 := createKvTask(contract, entries, 2, lastKvIndex, 0)