From b0200cd90f328067a2c535b5449fdd2a839c263c Mon Sep 17 00:00:00 2001 From: Tuna Date: Sat, 29 Dec 2018 16:14:27 +0700 Subject: [PATCH 01/11] return err properly, apply retry at GetSignersFromContract --- contracts/utils.go | 10 +++++++++- internal/ethapi/api.go | 17 ++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/contracts/utils.go b/contracts/utils.go index 42643b4571..faf86b1c55 100644 --- a/contracts/utils.go +++ b/contracts/utils.go @@ -85,7 +85,8 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m // Add tx signed to local tx pool. err = pool.AddLocal(txSigned) if err != nil { - log.Warn("Fail to add tx sign to local pool.", "error", err, "number", block.NumberU64(), "hash", block.Hash().Hex(), "from", account.Address, "nonce", nonce) + log.Error("Fail to add tx sign to local pool.", "error", err, "number", block.NumberU64(), "hash", block.Hash().Hex(), "from", account.Address, "nonce", nonce) + return err } // Create secret tx. @@ -114,6 +115,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m err = pool.AddLocal(txSigned) if err != nil { log.Error("Fail to add tx secret to local pool.", "error", err, "number", block.NumberU64(), "hash", block.Hash().Hex(), "from", account.Address, "nonce", nonce) + return err } // Put randomize key into chainDb. @@ -125,6 +127,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m randomizeKeyValue, err := chainDb.Get(randomizeKeyName) if err != nil { log.Error("Fail to get randomize key from state db.", "error", err) + return err } tx, err := BuildTxOpeningRandomize(nonce+1, common.HexToAddress(common.RandomizeSMC), randomizeKeyValue) @@ -141,6 +144,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m err = pool.AddLocal(txSigned) if err != nil { log.Error("Fail to add tx opening to local pool.", "error", err, "number", block.NumberU64(), "hash", block.Hash().Hex(), "from", account.Address, "nonce", nonce) + return err } // Clear randomize key in state db. @@ -216,15 +220,18 @@ func GetRandomizeFromContract(client bind.ContractBackend, addrMasternode common randomize, err := randomizeContract.NewTomoRandomize(common.HexToAddress(common.RandomizeSMC), client) if err != nil { log.Error("Fail to get instance of randomize", "error", err) + return -1, err } opts := new(bind.CallOpts) secrets, err := randomize.GetSecret(opts, addrMasternode) if err != nil { log.Error("Fail get secrets from randomize", "error", err) + return -1, err } opening, err := randomize.GetOpening(opts, addrMasternode) if err != nil { log.Error("Fail get opening from randomize", "error", err) + return -1, err } return DecryptRandomizeFromSecretsAndOpening(secrets, opening) @@ -289,6 +296,7 @@ func DecryptRandomizeFromSecretsAndOpening(secrets [][32]byte, opening [32]byte) intNumber, err := strconv.Atoi(decryptSecret) if err != nil { log.Error("Can not convert string to integer", "error", err) + return -1, err } random = int64(intNumber) } diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 4a6f1f5583..cc83bd3d6c 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -865,15 +865,26 @@ func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx client, err := s.b.GetIPCClient() if err != nil { log.Error("Fail to connect IPC client for block status", "error", err) + return nil, err } var signers []common.Address var filterSigners []common.Address finality := int32(0) if b.Number().Int64() > 0 { addrBlockSigner := common.HexToAddress(common.BlockSigners) - signers, err = contracts.GetSignersFromContract(addrBlockSigner, client, b.Hash()) - if err != nil { - log.Error("Fail to get signers from block signer SC.", "error", err) + retries := 3 + for { + signers, err = contracts.GetSignersFromContract(addrBlockSigner, client, b.Hash()) + if err != nil { + log.Error("Fail to get signers from block signer SC.", "error", err, "retries", retries) + if retries == 0 { + return nil, err + } + } else { + break + } + retries-- + time.Sleep(100 * time.Millisecond) } // Get block epoc latest. if s.b.ChainConfig().Posv != nil { From 1ddd1b514bd33a8eeaee13dd4d62ae33f7889a37 Mon Sep 17 00:00:00 2001 From: Nguyen Sy Thanh Son Date: Sun, 30 Dec 2018 22:02:59 +0700 Subject: [PATCH 02/11] Update blockchain.go --- core/blockchain.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index b7985a8999..a01275da5d 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -1218,8 +1218,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty if (chain[i].NumberU64() % bc.chainConfig.Posv.Epoch) == (bc.chainConfig.Posv.Epoch - bc.chainConfig.Posv.Gap) { err := bc.UpdateM1() if err != nil { - log.Error("Error when update masternodes set. Stopping node", "err", err) - os.Exit(1) + log.Crit("Error when update masternodes set. Stopping node", "err", err) } } } From bfa11f2bced8943336ccbd30ececf44c96e0b6a0 Mon Sep 17 00:00:00 2001 From: Nguyen Sy Thanh Son Date: Wed, 2 Jan 2019 03:15:43 +0000 Subject: [PATCH 03/11] Critical log if failed count signers --- contracts/utils.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/contracts/utils.go b/contracts/utils.go index 42643b4571..427a2c2ac0 100644 --- a/contracts/utils.go +++ b/contracts/utils.go @@ -313,8 +313,7 @@ func GetRewardForCheckpoint(chain consensus.ChainReader, blockSignerAddr common. block := chain.GetHeaderByNumber(i) addrs, err := GetSignersFromContract(blockSignerAddr, client, block.Hash()) if err != nil { - log.Error("Fail to get signers from smartcontract.", "error", err, "blockNumber", i) - return nil, err + log.Crit("Fail to get signers from smartcontract.", "error", err, "blockNumber", i) } // Filter duplicate address. if len(addrs) > 0 { From 8909b21925a29158c34b9347252123c1dc8b0421 Mon Sep 17 00:00:00 2001 From: Nguyen Sy Thanh Son Date: Wed, 2 Jan 2019 03:25:24 +0000 Subject: [PATCH 04/11] crit when get voters, voter capacity --- contracts/utils.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/contracts/utils.go b/contracts/utils.go index 427a2c2ac0..03a1b656bf 100644 --- a/contracts/utils.go +++ b/contracts/utils.go @@ -410,8 +410,7 @@ func GetRewardBalancesRate(foudationWalletAddr common.Address, masterAddr common opts := new(bind.CallOpts) voters, err := validator.GetVoters(opts, masterAddr) if err != nil { - log.Error("Fail to get voters", "error", err) - return nil, err + log.Crit("Fail to get voters", "error", err) } if len(voters) > 0 { @@ -423,8 +422,7 @@ func GetRewardBalancesRate(foudationWalletAddr common.Address, masterAddr common for _, voteAddr := range voters { voterCap, err := validator.GetVoterCap(opts, masterAddr, voteAddr) if err != nil { - log.Error("Fail to get vote capacity", "error", err) - return nil, err + log.Crit("Fail to get vote capacity", "error", err) } totalCap.Add(totalCap, voterCap) From 63d646772428a8cb857c383ef458cb94183d49e1 Mon Sep 17 00:00:00 2001 From: Nguyen Ba Tam Date: Wed, 2 Jan 2019 10:34:01 +0700 Subject: [PATCH 05/11] fix duplicate hook rewards with --announceTxs --- core/blockchain.go | 4 ++-- eth/api_backend.go | 15 +++++++++++++++ miner/worker.go | 10 +++++----- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index a01275da5d..5521ff617b 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -57,8 +57,8 @@ var ( ) const ( - bodyCacheLimit = 256 - blockCacheLimit = 256 + bodyCacheLimit = 2560 + blockCacheLimit = 2560 maxFutureBlocks = 256 maxTimeFutureBlocks = 30 badBlockLimit = 10 diff --git a/eth/api_backend.go b/eth/api_backend.go index 3b34e843ef..7f2b9b7944 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -18,8 +18,11 @@ package eth import ( "context" + "encoding/json" "github.com/ethereum/go-ethereum/consensus/posv" + "io/ioutil" "math/big" + "path/filepath" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" @@ -241,6 +244,18 @@ func (s *EthApiBackend) GetRewardByHash(hash common.Hash) map[string]interface{} if rewards != nil { return rewards } + } else { + header := s.eth.blockchain.GetHeaderByHash(hash) + if header != nil { + data, err := ioutil.ReadFile(filepath.Join(s.eth.config.StoreRewardFolder, header.Number.String()+"."+header.Hash().Hex())) + if err == nil { + rewards := make(map[string]interface{}) + err = json.Unmarshal(data, &rewards) + if err == nil { + return rewards + } + } + } } return make(map[string]interface{}) } diff --git a/miner/worker.go b/miner/worker.go index 9baefbce40..a5d5167fb4 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -612,12 +612,12 @@ func (self *worker) commitNewWork() { delete(self.possibleUncles, hash) } } - // Create the new block to seal with the consensus engine - if work.Block, err = self.engine.Finalize(self.chain, header, work.state, work.txs, uncles, work.receipts); err != nil { - log.Error("Failed to finalize block for sealing", "err", err) - return - } if atomic.LoadInt32(&self.mining) == 1 { + // Create the new block to seal with the consensus engine + if work.Block, err = self.engine.Finalize(self.chain, header, work.state, work.txs, uncles, work.receipts); err != nil { + log.Error("Failed to finalize block for sealing", "err", err) + return + } log.Info("Committing new block", "number", work.Block.Number(), "txs", work.tcount, "special txs", len(specialTxs), "uncles", len(uncles), "elapsed", common.PrettyDuration(time.Since(tstart))) self.unconfirmed.Shift(work.Block.NumberU64() - 1) self.lastParentBlockCommit = parent.Hash().Hex() From e5082863de247bc6ccc70a3bf0650c3e34225fe4 Mon Sep 17 00:00:00 2001 From: Nguyen Sy Thanh Son Date: Wed, 2 Jan 2019 03:34:49 +0000 Subject: [PATCH 06/11] should handle crit error in backend file --- contracts/utils.go | 9 ++++++--- eth/backend.go | 15 +++++---------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/contracts/utils.go b/contracts/utils.go index 03a1b656bf..42643b4571 100644 --- a/contracts/utils.go +++ b/contracts/utils.go @@ -313,7 +313,8 @@ func GetRewardForCheckpoint(chain consensus.ChainReader, blockSignerAddr common. block := chain.GetHeaderByNumber(i) addrs, err := GetSignersFromContract(blockSignerAddr, client, block.Hash()) if err != nil { - log.Crit("Fail to get signers from smartcontract.", "error", err, "blockNumber", i) + log.Error("Fail to get signers from smartcontract.", "error", err, "blockNumber", i) + return nil, err } // Filter duplicate address. if len(addrs) > 0 { @@ -410,7 +411,8 @@ func GetRewardBalancesRate(foudationWalletAddr common.Address, masterAddr common opts := new(bind.CallOpts) voters, err := validator.GetVoters(opts, masterAddr) if err != nil { - log.Crit("Fail to get voters", "error", err) + log.Error("Fail to get voters", "error", err) + return nil, err } if len(voters) > 0 { @@ -422,7 +424,8 @@ func GetRewardBalancesRate(foudationWalletAddr common.Address, masterAddr common for _, voteAddr := range voters { voterCap, err := validator.GetVoterCap(opts, masterAddr, voteAddr) if err != nil { - log.Crit("Fail to get vote capacity", "error", err) + log.Error("Fail to get vote capacity", "error", err) + return nil, err } totalCap.Add(totalCap, voterCap) diff --git a/eth/backend.go b/eth/backend.go index c05909bfd6..64f102dcb8 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -292,8 +292,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { c.HookReward = func(chain consensus.ChainReader, state *state.StateDB, header *types.Header) (error, map[string]interface{}) { client, err := eth.blockchain.GetClient() if err != nil { - log.Error("Fail to connect IPC client for blockSigner", "error", err) - return err, nil + log.Crit("Fail to connect IPC client for blockSigner", "error", err) } number := header.Number.Uint64() rCheckpoint := chain.Config().Posv.RewardCheckpoint @@ -313,20 +312,17 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { totalSigner := new(uint64) signers, err := contracts.GetRewardForCheckpoint(chain, addr, number, rCheckpoint, client, totalSigner) if err != nil { - log.Error("Fail to get signers for reward checkpoint", "error", err) - return err, nil + log.Crit("Fail to get signers for reward checkpoint", "error", err) } rewards["signers"] = signers rewardSigners, err := contracts.CalculateRewardForSigner(chainReward, signers, *totalSigner) if err != nil { - log.Error("Fail to calculate reward for signers", "error", err) - return err, nil + log.Crit("Fail to calculate reward for signers", "error", err) } // Get validator. validator, err := contract.NewTomoValidator(common.HexToAddress(common.MasternodeVotingSMC), client) if err != nil { - log.Error("Fail get instance of Tomo Validator", "error", err) - return err, nil + log.Crit("Fail get instance of Tomo Validator", "error", err) } // Add reward for coin holders. voterResults := make(map[common.Address]interface{}) @@ -334,8 +330,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { for signer, calcReward := range rewardSigners { err, rewards := contracts.CalculateRewardForHolders(foudationWalletAddr, validator, state, signer, calcReward) if err != nil { - log.Error("Fail to calculate reward for holders.", "error", err) - return err, nil + log.Crit("Fail to calculate reward for holders.", "error", err) } voterResults[signer] = rewards } From c2caf4bcc5a7af78a4536f63d2df25ce8822515e Mon Sep 17 00:00:00 2001 From: Nguyen Sy Thanh Son Date: Wed, 2 Jan 2019 03:47:53 +0000 Subject: [PATCH 07/11] fix empty log error --- rpc/server.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rpc/server.go b/rpc/server.go index 478310196a..0e7142a183 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -133,7 +133,7 @@ func (s *Server) serveRequest(codec ServerCodec, singleShot bool, options CodecO const size = 64 << 10 buf := make([]byte, size) buf = buf[:runtime.Stack(buf, false)] - log.Error(string(buf)) + log.Error(fmt.Sprintf("RPC serveRequest %s\n", string(buf))) } s.codecsMu.Lock() s.codecs.Remove(codec) @@ -344,7 +344,7 @@ func (s *Server) exec(ctx context.Context, codec ServerCodec, req *serverRequest } if err := codec.Write(response); err != nil { - log.Error(fmt.Sprintf("%v\n", err)) + log.Error(fmt.Sprintf("RPC exec %v\n", err)) codec.Close() } @@ -371,7 +371,7 @@ func (s *Server) execBatch(ctx context.Context, codec ServerCodec, requests []*s } if err := codec.Write(responses); err != nil { - log.Error(fmt.Sprintf("%v\n", err)) + log.Error(fmt.Sprintf("RPC execBacth %v\n", err)) codec.Close() } From 7ea485deeed4cc3357b0726aea964e127f32d0b5 Mon Sep 17 00:00:00 2001 From: Nick Yeates <213291+nyeates@users.noreply.github.com> Date: Wed, 2 Jan 2019 02:14:50 -0500 Subject: [PATCH 08/11] Corrections to grammar and sentences Fixed many grammatical and sentence-structure elements that would be noticed by English-first speakers. Removed one small section that was lacking its explanatory image (bad link). This was the Tomo vs Giants explanation. --- README.md | 47 ++++++++++++++++++++--------------------------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 9feb1ca4ac..323b98e306 100644 --- a/README.md +++ b/README.md @@ -7,35 +7,28 @@ TomoChain is an innovative solution to the scalability problem with the Ethereum blockchain. Our mission is to be a leading force in building the Internet of Value, and its infrastructure. -We are working to create an alternative, scalable financial system which is more secure, transparent, efficient, inclusive and equitable for everyone. +We are working to create an alternative, scalable financial system which is more secure, transparent, efficient, inclusive, and equitable for everyone. -TomoChain relies on a system of 150 Masternodes with Proof of Stake Voting consensus that can support near-zero fee, and 2-second transaction confirmation time. -Security, stability and chain finality are guaranteed via novel techniques such as double validation, staking via smart-contracts and "true" randomization processes. +TomoChain relies on a system of 150 Masternodes with a Proof of Stake Voting consensus that can support near-zero fee, and 2-second transaction confirmation times. +Security, stability, and chain finality are guaranteed via novel techniques such as double validation, staking via smart-contracts, and "true" randomization processes. Tomochain supports all EVM-compatible smart-contracts, protocols, and atomic cross-chain token transfers. -New scaling techniques such as sharding, private-chain generation, hardware integration will be continuously researched and incorporated into Tomochain's masternode architecture which will be an ideal scalable smart-contract public blockchain for decentralized apps, token issuances and token integrations for small and big businesses. +New scaling techniques such as sharding, private-chain generation, and hardware integration will be continuously researched and incorporated into Tomochain's masternode architecture. This architecture will be an ideal scalable smart-contract public blockchain for decentralized apps, token issuances, and token integrations for small and big businesses. More details can be found at our [technical white paper](https://tomochain.com/docs/technical-whitepaper---1.0.pdf) -Reading more about us on: +Read more about us on: - our website: http://tomochain.com - our blogs and announcements: https://medium.com/tomochain -- our documentation site: https://docs.tomochain.com - -## Tomochain vs Giants - -Tomochain is built by the mindset of standing on the giants shoulder. -We have learned from all advanced technical design concept of many well-known public blockchains on the market and shaped up the platform with our own ingredients. -See below the overall technical comparison table that we try to make clear the position of Tomochain comparing to some popular blockchains at the top-tier. - -![Tomochain](https://s3-ap-southeast-1.amazonaws.com/tomochain/tomochainvsgiants.png) +- our documentation portal: https://docs.tomochain.com ## Building the source -Tomochain provides client binary called `tomo` for both running a masternode and running a full-node. -Building `tomo` requires both a Go (1.7+) and a C compiler. -Install them by your own way. Once the dependencies are installed, just run below commands: +Tomochain provides a client binary called `tomo` for both running a masternode and running a full-node. +Building `tomo` requires both a Go (1.7+) and C compiler; install both of these. + +Once the dependencies are installed, just run the below commands: ```bash $ git clone https://github.com/tomochain/tomochain tomochain @@ -43,19 +36,19 @@ $ cd tomochain $ make tomo ``` -Alternatively, you could quickly download pre-complied binary on our [github release page](https://github.com/tomochain/tomochain/releases) +Alternatively, you could quickly download our pre-complied binary from our [github release page](https://github.com/tomochain/tomochain/releases) ## Running tomo ### Running a tomo masternode -Please refer to the [official documentation](https://docs.tomochain.com/get-started/run-node/) on how to run a node if you goal is to run a masternode. +Please refer to the [official documentation](https://docs.tomochain.com/get-started/run-node/) on how to run a node if your goal is to run a masternode. The recommanded ways of running a node and applying to become a masternode are explained in detail there. ### Attaching to the Tomochain test network We published our test network 2.0 with full implementation of PoSV consensus at https://stats.testnet.tomochain.com. -If you'd like to experiment with smart contracts creation and DApps, you might be interested in giving it a try on our Testnet. +If you'd like to experiment with smart contract creation and DApps, you might be interested to give these a try on our Testnet. In order to connect to one of the masternodes on the Testnet, just run the command below: @@ -154,22 +147,22 @@ The implementation of the following features is being studied by our research te - Layer 2 scalability with state sharding - DEX integration - Spam filtering -- Multi-chains interoperabilty +- Multi-chain interoperabilty -## Contribution and technical discuss +## Contributing and technical discussion Thank you for considering to try out our network and/or help out with the source code. -We would love to get your help, feel free to lend a hand. -Even the smallest bit of code, bug reporting or just discussing ideas are highly appreciated. +We would love to get your help; feel free to lend a hand. +Even the smallest bit of code, bug reporting, or just discussing ideas are highly appreciated. If you would like to contribute to the tomochain source code, please refer to our Developer Guide for details on configuring development environment, managing dependencies, compiling, testing and submitting your code changes to our repo. Please also make sure your contributions adhere to the base coding guidelines: -- Code must adhere the official Go [formatting](https://golang.org/doc/effective_go.html#formatting) guidelines (i.e uses [gofmt](https://golang.org/cmd/gofmt/)). -- Code must be documented adhering to the official Go [commentary](https://golang.org/doc/effective_go.html#commentary) guidelines. +- Code must adhere to official Go [formatting](https://golang.org/doc/effective_go.html#formatting) guidelines (i.e uses [gofmt](https://golang.org/cmd/gofmt/)). +- Code comments must adhere to the official Go [commentary](https://golang.org/doc/effective_go.html#commentary) guidelines. - Pull requests need to be based on and opened against the `master` branch. -- Problem you are trying to contribute must be well-explained as an issue on our [github issue page](https://github.com/tomochain/tomochain/issues) +- Any code you are trying to contribute must be well-explained as an issue on our [github issue page](https://github.com/tomochain/tomochain/issues) - Commit messages should be short but clear enough and should refer to the corresponding pre-logged issue mentioned above. For technical discussion, feel free to join our chat at [Gitter](https://gitter.im/tomochain/tomochain). From 0eecfd8fad2e1a9079ceecbaa60b418efd313831 Mon Sep 17 00:00:00 2001 From: Nguyen Ba Tam Date: Wed, 2 Jan 2019 13:41:31 +0700 Subject: [PATCH 09/11] fix error read reward --- cmd/utils/flags.go | 6 +++--- common/constants.go | 1 + consensus/posv/posv.go | 32 ++++++++++++++------------------ core/blockchain.go | 11 ++--------- eth/api_backend.go | 21 +++++++++++---------- eth/backend.go | 24 ------------------------ eth/config.go | 2 -- internal/ethapi/api.go | 8 +------- les/api_backend.go | 26 +++++++++++++++++++++----- 9 files changed, 53 insertions(+), 78 deletions(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 6144dd57fc..fbeecee31a 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -1087,9 +1087,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) { cfg.EnablePreimageRecording = ctx.GlobalBool(VMEnableDebugFlag.Name) } if ctx.GlobalIsSet(StoreRewardFlag.Name) { - cfg.StoreRewardFolder = filepath.Join(stack.DataDir(), "tomo", "rewards") - if _, err := os.Stat(cfg.StoreRewardFolder); os.IsNotExist(err) { - os.Mkdir(cfg.StoreRewardFolder, os.ModePerm) + common.StoreRewardFolder = filepath.Join(stack.DataDir(), "tomo", "rewards") + if _, err := os.Stat(common.StoreRewardFolder); os.IsNotExist(err) { + os.Mkdir(common.StoreRewardFolder, os.ModePerm) } } // Override any default configs for hard coded networks. diff --git a/common/constants.go b/common/constants.go index 89ded09a84..1cad593c9e 100644 --- a/common/constants.go +++ b/common/constants.go @@ -18,3 +18,4 @@ const ( ) var IsTestnet bool = false +var StoreRewardFolder string diff --git a/consensus/posv/posv.go b/consensus/posv/posv.go index 4b50a589c8..8be0762cb9 100644 --- a/consensus/posv/posv.go +++ b/consensus/posv/posv.go @@ -18,10 +18,13 @@ package posv import ( "bytes" + "encoding/json" "errors" "fmt" + "io/ioutil" "math/big" "math/rand" + "path/filepath" "strconv" "sync" "time" @@ -215,14 +218,13 @@ type Posv struct { signatures *lru.ARCCache // Signatures of recent blocks to speed up mining validatorSignatures *lru.ARCCache // Signatures of recent blocks to speed up mining verifiedHeaders *lru.ARCCache - rewards *lru.ARCCache proposals map[common.Address]bool // Current list of proposals we are pushing signer common.Address // Ethereum address of the signing key signFn clique.SignerFn // Signer function to authorize hashes with lock sync.RWMutex // Protects the signer fields - HookReward func(chain consensus.ChainReader, state *state.StateDB, header *types.Header) (error, map[string]interface{}) + HookReward func(chain consensus.ChainReader, state *state.StateDB, header *types.Header) (error, map[string]interface{}) HookPenalty func(chain consensus.ChainReader, blockNumberEpoc uint64) ([]common.Address, error) HookValidator func(header *types.Header, signers []common.Address) ([]byte, error) HookVerifyMNs func(header *types.Header, signers []common.Address) error @@ -241,7 +243,6 @@ func New(config *params.PosvConfig, db ethdb.Database) *Posv { signatures, _ := lru.NewARC(inmemorySnapshots) validatorSignatures, _ := lru.NewARC(inmemorySnapshots) verifiedHeaders, _ := lru.NewARC(inmemorySnapshots) - rewards, _ := lru.NewARC(inmemorySnapshots) return &Posv{ config: &conf, db: db, @@ -249,7 +250,6 @@ func New(config *params.PosvConfig, db ethdb.Database) *Posv { signatures: signatures, verifiedHeaders: verifiedHeaders, validatorSignatures: validatorSignatures, - rewards: rewards, proposals: make(map[common.Address]bool), } } @@ -850,11 +850,19 @@ func (c *Posv) Finalize(chain consensus.ChainReader, header *types.Header, state rCheckpoint := chain.Config().Posv.RewardCheckpoint if c.HookReward != nil && number%rCheckpoint == 0 { - err, rewardResults := c.HookReward(chain, state, header) + err, rewards := c.HookReward(chain, state, header) if err != nil { return nil, err } - c.rewards.Add(header.Hash(), rewardResults) + if len(common.StoreRewardFolder) > 0 { + data, err := json.Marshal(rewards) + if err == nil { + err = ioutil.WriteFile(filepath.Join(common.StoreRewardFolder, header.Number.String()+"."+header.Hash().Hex()), data, 0644) + } + if err != nil { + log.Error("Error when save reward info ", "number", header.Number, "hash", header.Hash().Hex(), "err", err) + } + } } // the state remains as is and uncles are dropped @@ -1084,15 +1092,3 @@ func Hop(len, pre, cur int) int { return len - 1 } } - -func (c *Posv) GetRewards(hash common.Hash) map[string]interface{} { - rewards, ok := c.rewards.Get(hash) - if !ok { - return nil - } - return rewards.(map[string]interface{}) -} - -func (c *Posv) InsertRewards(hash common.Hash, rewards map[string]interface{}) { - c.rewards.Add(hash, rewards) -} diff --git a/core/blockchain.go b/core/blockchain.go index 5521ff617b..0795ce0b38 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -57,8 +57,8 @@ var ( ) const ( - bodyCacheLimit = 2560 - blockCacheLimit = 2560 + bodyCacheLimit = 256 + blockCacheLimit = 256 maxFutureBlocks = 256 maxTimeFutureBlocks = 30 badBlockLimit = 10 @@ -144,7 +144,6 @@ type BlockChain struct { badBlocks *lru.Cache // Bad block cache IPCEndpoint string Client *ethclient.Client // Global ipc client instance. - HookWriteRewards func(header *types.Header) } // NewBlockChain returns a fully initialised block chain using information @@ -1222,9 +1221,6 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty } } } - if bc.HookWriteRewards != nil { - bc.HookWriteRewards(block.Header()) - } } // Append a single chain head event if we've progressed the chain if lastCanon != nil && bc.CurrentBlock().Hash() == lastCanon.Hash() { @@ -1431,9 +1427,6 @@ func (bc *BlockChain) insertBlock(block *types.Block) ([]interface{}, []*types.L events = append(events, ChainHeadEvent{block}) log.Debug("New ChainHeadEvent from fetcher ", "number", block.NumberU64(), "hash", block.Hash()) } - if bc.HookWriteRewards != nil { - bc.HookWriteRewards(block.Header()) - } return events, coalescedLogs, nil } diff --git a/eth/api_backend.go b/eth/api_backend.go index 7f2b9b7944..97dfea2873 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -19,7 +19,6 @@ package eth import ( "context" "encoding/json" - "github.com/ethereum/go-ethereum/consensus/posv" "io/ioutil" "math/big" "path/filepath" @@ -239,15 +238,17 @@ func (b *EthApiBackend) GetEngine() consensus.Engine { } func (s *EthApiBackend) GetRewardByHash(hash common.Hash) map[string]interface{} { - if c, ok := s.eth.Engine().(*posv.Posv); ok { - rewards := c.GetRewards(hash) - if rewards != nil { - return rewards - } - } else { - header := s.eth.blockchain.GetHeaderByHash(hash) - if header != nil { - data, err := ioutil.ReadFile(filepath.Join(s.eth.config.StoreRewardFolder, header.Number.String()+"."+header.Hash().Hex())) + header := s.eth.blockchain.GetHeaderByHash(hash) + if header != nil { + data, err := ioutil.ReadFile(filepath.Join(common.StoreRewardFolder, header.Number.String()+"."+header.Hash().Hex())) + if err == nil { + rewards := make(map[string]interface{}) + err = json.Unmarshal(data, &rewards) + if err == nil { + return rewards + } + } else { + data, err = ioutil.ReadFile(filepath.Join(common.StoreRewardFolder, header.Number.String()+"."+header.HashNoValidator().Hex())) if err == nil { rewards := make(map[string]interface{}) err = json.Unmarshal(data, &rewards) diff --git a/eth/backend.go b/eth/backend.go index c05909bfd6..527327d0cf 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -18,12 +18,9 @@ package eth import ( - "encoding/json" "errors" "fmt" - "io/ioutil" "math/big" - "path/filepath" "runtime" "sync" "sync/atomic" @@ -374,27 +371,6 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) { } return false } - eth.blockchain.HookWriteRewards = func(header *types.Header) { - if len(config.StoreRewardFolder) > 0 { - rewards := c.GetRewards(header.Hash()) - if rewards == nil { - rewards = c.GetRewards(header.HashNoValidator()) - if rewards != nil { - c.InsertRewards(header.Hash(), rewards) - } - } - if rewards == nil { - return - } - data, err := json.Marshal(rewards) - if err == nil { - err = ioutil.WriteFile(filepath.Join(config.StoreRewardFolder, header.Number.String()+"."+header.Hash().Hex()), data, 0644) - } - if err != nil { - log.Error("Error when save reward info ", "number", header.Number, "hash", header.Hash().Hex(), "err", err) - } - } - } } return eth, nil } diff --git a/eth/config.go b/eth/config.go index 6f0d58955e..dbfe973913 100644 --- a/eth/config.go +++ b/eth/config.go @@ -114,8 +114,6 @@ type Config struct { // Miscellaneous options DocRoot string `toml:"-"` - - StoreRewardFolder string } type configMarshaling struct { diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 4a6f1f5583..dca62b86a0 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -494,13 +494,7 @@ func (s *PublicBlockChainAPI) BlockNumber() *big.Int { // BlockNumber returns the block number of the chain head. func (s *PublicBlockChainAPI) GetRewardByHash(hash common.Hash) map[string]interface{} { - if c, ok := s.b.GetEngine().(*posv.Posv); ok { - rewards := c.GetRewards(hash) - if rewards != nil { - return rewards - } - } - return make(map[string]interface{}) + return s.b.GetRewardByHash(hash) } // GetBalance returns the amount of wei for the given address in the state of the diff --git a/les/api_backend.go b/les/api_backend.go index 152aab79ee..36afa39717 100644 --- a/les/api_backend.go +++ b/les/api_backend.go @@ -18,8 +18,10 @@ package les import ( "context" - "github.com/ethereum/go-ethereum/consensus/posv" + "encoding/json" + "io/ioutil" "math/big" + "path/filepath" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" @@ -202,10 +204,24 @@ func (b *LesApiBackend) GetEngine() consensus.Engine { return b.eth.engine } func (s *LesApiBackend) GetRewardByHash(hash common.Hash) map[string]interface{} { - if c, ok := s.eth.Engine().(*posv.Posv); ok { - rewards := c.GetRewards(hash) - if rewards != nil { - return rewards + header := s.eth.blockchain.GetHeaderByHash(hash) + if header != nil { + data, err := ioutil.ReadFile(filepath.Join(common.StoreRewardFolder, header.Number.String()+"."+header.Hash().Hex())) + if err == nil { + rewards := make(map[string]interface{}) + err = json.Unmarshal(data, &rewards) + if err == nil { + return rewards + } + } else { + data, err = ioutil.ReadFile(filepath.Join(common.StoreRewardFolder, header.Number.String()+"."+header.HashNoValidator().Hex())) + if err == nil { + rewards := make(map[string]interface{}) + err = json.Unmarshal(data, &rewards) + if err == nil { + return rewards + } + } } } return make(map[string]interface{}) From e178e8723e0ab6057f0eb658bb5d40c4688d850f Mon Sep 17 00:00:00 2001 From: Tuna Date: Wed, 2 Jan 2019 15:52:39 +0700 Subject: [PATCH 10/11] remove retry --- internal/ethapi/api.go | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index cc83bd3d6c..edfb14fc21 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -872,19 +872,10 @@ func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx finality := int32(0) if b.Number().Int64() > 0 { addrBlockSigner := common.HexToAddress(common.BlockSigners) - retries := 3 - for { - signers, err = contracts.GetSignersFromContract(addrBlockSigner, client, b.Hash()) - if err != nil { - log.Error("Fail to get signers from block signer SC.", "error", err, "retries", retries) - if retries == 0 { - return nil, err - } - } else { - break - } - retries-- - time.Sleep(100 * time.Millisecond) + signers, err = contracts.GetSignersFromContract(addrBlockSigner, client, b.Hash()) + if err != nil { + log.Error("Fail to get signers from block signer SC.", "error", err) + return nil, err } // Get block epoc latest. if s.b.ChainConfig().Posv != nil { From 47af8deec1f474e5ca2d111a8aa8158502f04ef5 Mon Sep 17 00:00:00 2001 From: Tuna Date: Wed, 2 Jan 2019 17:52:56 +0700 Subject: [PATCH 11/11] make gofmt --- consensus/posv/posv.go | 2 +- core/blockchain.go | 6 +++--- core/genesis.go | 2 +- eth/downloader/api.go | 4 ++-- eth/handler_test.go | 8 ++++---- swarm/api/http/error.go | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/consensus/posv/posv.go b/consensus/posv/posv.go index 8be0762cb9..a6f0613954 100644 --- a/consensus/posv/posv.go +++ b/consensus/posv/posv.go @@ -224,7 +224,7 @@ type Posv struct { signFn clique.SignerFn // Signer function to authorize hashes with lock sync.RWMutex // Protects the signer fields - HookReward func(chain consensus.ChainReader, state *state.StateDB, header *types.Header) (error, map[string]interface{}) + HookReward func(chain consensus.ChainReader, state *state.StateDB, header *types.Header) (error, map[string]interface{}) HookPenalty func(chain consensus.ChainReader, blockNumberEpoc uint64) ([]common.Address, error) HookValidator func(header *types.Header, signers []common.Address) ([]byte, error) HookVerifyMNs func(header *types.Header, signers []common.Address) error diff --git a/core/blockchain.go b/core/blockchain.go index 0795ce0b38..4d6c2cc011 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -141,9 +141,9 @@ type BlockChain struct { validator Validator // block and state validator interface vmConfig vm.Config - badBlocks *lru.Cache // Bad block cache - IPCEndpoint string - Client *ethclient.Client // Global ipc client instance. + badBlocks *lru.Cache // Bad block cache + IPCEndpoint string + Client *ethclient.Client // Global ipc client instance. } // NewBlockChain returns a fully initialised block chain using information diff --git a/core/genesis.go b/core/genesis.go index c87460b908..9d8eb27953 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -366,7 +366,7 @@ func DeveloperGenesisBlock(period uint64, faucet common.Address) *Genesis { common.BytesToAddress([]byte{6}): {Balance: big.NewInt(1)}, // ECAdd common.BytesToAddress([]byte{7}): {Balance: big.NewInt(1)}, // ECScalarMul common.BytesToAddress([]byte{8}): {Balance: big.NewInt(1)}, // ECPairing - faucet: {Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(9))}, + faucet: {Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(9))}, }, } } diff --git a/eth/downloader/api.go b/eth/downloader/api.go index 581e9aed24..d496fa6a4d 100644 --- a/eth/downloader/api.go +++ b/eth/downloader/api.go @@ -40,8 +40,8 @@ type PublicDownloaderAPI struct { // installSyncSubscription channel. func NewPublicDownloaderAPI(d *Downloader, m *event.TypeMux) *PublicDownloaderAPI { api := &PublicDownloaderAPI{ - d: d, - mux: m, + d: d, + mux: m, installSyncSubscription: make(chan chan interface{}), uninstallSyncSubscription: make(chan *uninstallSyncSubscriptionRequest), } diff --git a/eth/handler_test.go b/eth/handler_test.go index 923df129a0..e336dfa285 100644 --- a/eth/handler_test.go +++ b/eth/handler_test.go @@ -242,10 +242,10 @@ func testGetBlockBodies(t *testing.T, protocol int) { available []bool // Availability of explicitly requested blocks expected int // Total number of existing blocks to expect }{ - {1, nil, nil, 1}, // A single random block should be retrievable - {10, nil, nil, 10}, // Multiple random blocks should be retrievable - {limit, nil, nil, limit}, // The maximum possible blocks should be retrievable - {limit + 1, nil, nil, limit}, // No more than the possible block count should be returned + {1, nil, nil, 1}, // A single random block should be retrievable + {10, nil, nil, 10}, // Multiple random blocks should be retrievable + {limit, nil, nil, limit}, // The maximum possible blocks should be retrievable + {limit + 1, nil, nil, limit}, // No more than the possible block count should be returned {0, []common.Hash{pm.blockchain.Genesis().Hash()}, []bool{true}, 1}, // The genesis block should be retrievable {0, []common.Hash{pm.blockchain.CurrentBlock().Hash()}, []bool{true}, 1}, // The chains head block should be retrievable {0, []common.Hash{{}}, []bool{false}, 0}, // A non existent block should not be returned diff --git a/swarm/api/http/error.go b/swarm/api/http/error.go index 2f77f2784a..9a65412cf9 100644 --- a/swarm/api/http/error.go +++ b/swarm/api/http/error.go @@ -71,7 +71,7 @@ func initErrHandling() { multipleChoicesPage := GetMultipleChoicesErrorPage() //map the codes to the available pages tnames := map[int]string{ - 0: genErrPage, //default + 0: genErrPage, //default http.StatusBadRequest: genErrPage, http.StatusNotFound: notFoundPage, http.StatusMultipleChoices: multipleChoicesPage,