This commit is contained in:
Nguyen Sy Thanh Son 2019-01-02 15:36:11 +00:00
commit 628fc119ef
17 changed files with 116 additions and 129 deletions

View file

@ -7,35 +7,28 @@
TomoChain is an innovative solution to the scalability problem with the Ethereum blockchain. 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. 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. 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. 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. 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) 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 website: http://tomochain.com
- our blogs and announcements: https://medium.com/tomochain - our blogs and announcements: https://medium.com/tomochain
- our documentation site: https://docs.tomochain.com - our documentation portal: 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)
## Building the source ## Building the source
Tomochain provides client binary called `tomo` for both running a masternode and running a full-node. 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 a C compiler. Building `tomo` requires both a Go (1.7+) and C compiler; install both of these.
Install them by your own way. Once the dependencies are installed, just run below commands:
Once the dependencies are installed, just run the below commands:
```bash ```bash
$ git clone https://github.com/tomochain/tomochain tomochain $ git clone https://github.com/tomochain/tomochain tomochain
@ -43,19 +36,19 @@ $ cd tomochain
$ make tomo $ 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 tomo
### Running a tomo masternode ### 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. The recommanded ways of running a node and applying to become a masternode are explained in detail there.
### Attaching to the Tomochain test network ### 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. 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: 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 - Layer 2 scalability with state sharding
- DEX integration - DEX integration
- Spam filtering - 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. 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. 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. 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. 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: 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 adhere to 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 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. - 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. - 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). For technical discussion, feel free to join our chat at [Gitter](https://gitter.im/tomochain/tomochain).

View file

@ -1087,9 +1087,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
cfg.EnablePreimageRecording = ctx.GlobalBool(VMEnableDebugFlag.Name) cfg.EnablePreimageRecording = ctx.GlobalBool(VMEnableDebugFlag.Name)
} }
if ctx.GlobalIsSet(StoreRewardFlag.Name) { if ctx.GlobalIsSet(StoreRewardFlag.Name) {
cfg.StoreRewardFolder = filepath.Join(stack.DataDir(), "tomo", "rewards") common.StoreRewardFolder = filepath.Join(stack.DataDir(), "tomo", "rewards")
if _, err := os.Stat(cfg.StoreRewardFolder); os.IsNotExist(err) { if _, err := os.Stat(common.StoreRewardFolder); os.IsNotExist(err) {
os.Mkdir(cfg.StoreRewardFolder, os.ModePerm) os.Mkdir(common.StoreRewardFolder, os.ModePerm)
} }
} }
// Override any default configs for hard coded networks. // Override any default configs for hard coded networks.

View file

@ -18,3 +18,4 @@ const (
) )
var IsTestnet bool = false var IsTestnet bool = false
var StoreRewardFolder string

View file

@ -18,10 +18,13 @@ package posv
import ( import (
"bytes" "bytes"
"encoding/json"
"errors" "errors"
"fmt" "fmt"
"io/ioutil"
"math/big" "math/big"
"math/rand" "math/rand"
"path/filepath"
"strconv" "strconv"
"sync" "sync"
"time" "time"
@ -215,7 +218,6 @@ type Posv struct {
signatures *lru.ARCCache // Signatures of recent blocks to speed up mining signatures *lru.ARCCache // Signatures of recent blocks to speed up mining
validatorSignatures *lru.ARCCache // Signatures of recent blocks to speed up mining validatorSignatures *lru.ARCCache // Signatures of recent blocks to speed up mining
verifiedHeaders *lru.ARCCache verifiedHeaders *lru.ARCCache
rewards *lru.ARCCache
proposals map[common.Address]bool // Current list of proposals we are pushing proposals map[common.Address]bool // Current list of proposals we are pushing
signer common.Address // Ethereum address of the signing key signer common.Address // Ethereum address of the signing key
@ -241,7 +243,6 @@ func New(config *params.PosvConfig, db ethdb.Database) *Posv {
signatures, _ := lru.NewARC(inmemorySnapshots) signatures, _ := lru.NewARC(inmemorySnapshots)
validatorSignatures, _ := lru.NewARC(inmemorySnapshots) validatorSignatures, _ := lru.NewARC(inmemorySnapshots)
verifiedHeaders, _ := lru.NewARC(inmemorySnapshots) verifiedHeaders, _ := lru.NewARC(inmemorySnapshots)
rewards, _ := lru.NewARC(inmemorySnapshots)
return &Posv{ return &Posv{
config: &conf, config: &conf,
db: db, db: db,
@ -249,7 +250,6 @@ func New(config *params.PosvConfig, db ethdb.Database) *Posv {
signatures: signatures, signatures: signatures,
verifiedHeaders: verifiedHeaders, verifiedHeaders: verifiedHeaders,
validatorSignatures: validatorSignatures, validatorSignatures: validatorSignatures,
rewards: rewards,
proposals: make(map[common.Address]bool), 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 rCheckpoint := chain.Config().Posv.RewardCheckpoint
if c.HookReward != nil && number%rCheckpoint == 0 { if c.HookReward != nil && number%rCheckpoint == 0 {
err, rewardResults := c.HookReward(chain, state, header) err, rewards := c.HookReward(chain, state, header)
if err != nil { if err != nil {
return nil, err 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 // the state remains as is and uncles are dropped
@ -1084,15 +1092,3 @@ func Hop(len, pre, cur int) int {
return len - 1 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)
}

View file

@ -86,7 +86,8 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
// Add tx signed to local tx pool. // Add tx signed to local tx pool.
err = pool.AddLocal(txSigned) err = pool.AddLocal(txSigned)
if err != nil { 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. // Create secret tx.
@ -115,6 +116,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
err = pool.AddLocal(txSigned) err = pool.AddLocal(txSigned)
if err != nil { 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) 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. // Put randomize key into chainDb.
@ -126,6 +128,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
randomizeKeyValue, err := chainDb.Get(randomizeKeyName) randomizeKeyValue, err := chainDb.Get(randomizeKeyName)
if err != nil { if err != nil {
log.Error("Fail to get randomize key from state db.", "error", err) log.Error("Fail to get randomize key from state db.", "error", err)
return err
} }
tx, err := BuildTxOpeningRandomize(nonce+1, common.HexToAddress(common.RandomizeSMC), randomizeKeyValue) tx, err := BuildTxOpeningRandomize(nonce+1, common.HexToAddress(common.RandomizeSMC), randomizeKeyValue)
@ -142,6 +145,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
err = pool.AddLocal(txSigned) err = pool.AddLocal(txSigned)
if err != nil { 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) 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. // Clear randomize key in state db.
@ -217,15 +221,18 @@ func GetRandomizeFromContract(client bind.ContractBackend, addrMasternode common
randomize, err := randomizeContract.NewTomoRandomize(common.HexToAddress(common.RandomizeSMC), client) randomize, err := randomizeContract.NewTomoRandomize(common.HexToAddress(common.RandomizeSMC), client)
if err != nil { if err != nil {
log.Error("Fail to get instance of randomize", "error", err) log.Error("Fail to get instance of randomize", "error", err)
return -1, err
} }
opts := new(bind.CallOpts) opts := new(bind.CallOpts)
secrets, err := randomize.GetSecret(opts, addrMasternode) secrets, err := randomize.GetSecret(opts, addrMasternode)
if err != nil { if err != nil {
log.Error("Fail get secrets from randomize", "error", err) log.Error("Fail get secrets from randomize", "error", err)
return -1, err
} }
opening, err := randomize.GetOpening(opts, addrMasternode) opening, err := randomize.GetOpening(opts, addrMasternode)
if err != nil { if err != nil {
log.Error("Fail get opening from randomize", "error", err) log.Error("Fail get opening from randomize", "error", err)
return -1, err
} }
return DecryptRandomizeFromSecretsAndOpening(secrets, opening) return DecryptRandomizeFromSecretsAndOpening(secrets, opening)
@ -290,6 +297,7 @@ func DecryptRandomizeFromSecretsAndOpening(secrets [][32]byte, opening [32]byte)
intNumber, err := strconv.Atoi(decryptSecret) intNumber, err := strconv.Atoi(decryptSecret)
if err != nil { if err != nil {
log.Error("Can not convert string to integer", "error", err) log.Error("Can not convert string to integer", "error", err)
return -1, err
} }
random = int64(intNumber) random = int64(intNumber)
} }

View file

@ -144,7 +144,6 @@ type BlockChain struct {
badBlocks *lru.Cache // Bad block cache badBlocks *lru.Cache // Bad block cache
IPCEndpoint string IPCEndpoint string
Client *ethclient.Client // Global ipc client instance. Client *ethclient.Client // Global ipc client instance.
HookWriteRewards func(header *types.Header)
} }
// NewBlockChain returns a fully initialised block chain using information // NewBlockChain returns a fully initialised block chain using information
@ -1218,14 +1217,10 @@ 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) { if (chain[i].NumberU64() % bc.chainConfig.Posv.Epoch) == (bc.chainConfig.Posv.Epoch - bc.chainConfig.Posv.Gap) {
err := bc.UpdateM1() err := bc.UpdateM1()
if err != nil { if err != nil {
log.Error("Error when update masternodes set. Stopping node", "err", err) log.Crit("Error when update masternodes set. Stopping node", "err", err)
os.Exit(1)
} }
} }
} }
if bc.HookWriteRewards != nil {
bc.HookWriteRewards(block.Header())
}
} }
// Append a single chain head event if we've progressed the chain // Append a single chain head event if we've progressed the chain
if lastCanon != nil && bc.CurrentBlock().Hash() == lastCanon.Hash() { if lastCanon != nil && bc.CurrentBlock().Hash() == lastCanon.Hash() {
@ -1432,9 +1427,6 @@ func (bc *BlockChain) insertBlock(block *types.Block) ([]interface{}, []*types.L
events = append(events, ChainHeadEvent{block}) events = append(events, ChainHeadEvent{block})
log.Debug("New ChainHeadEvent from fetcher ", "number", block.NumberU64(), "hash", block.Hash()) log.Debug("New ChainHeadEvent from fetcher ", "number", block.NumberU64(), "hash", block.Hash())
} }
if bc.HookWriteRewards != nil {
bc.HookWriteRewards(block.Header())
}
return events, coalescedLogs, nil return events, coalescedLogs, nil
} }

View file

@ -18,8 +18,10 @@ package eth
import ( import (
"context" "context"
"github.com/ethereum/go-ethereum/consensus/posv" "encoding/json"
"io/ioutil"
"math/big" "math/big"
"path/filepath"
"github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
@ -236,11 +238,25 @@ func (b *EthApiBackend) GetEngine() consensus.Engine {
} }
func (s *EthApiBackend) GetRewardByHash(hash common.Hash) map[string]interface{} { func (s *EthApiBackend) GetRewardByHash(hash common.Hash) map[string]interface{} {
if c, ok := s.eth.Engine().(*posv.Posv); ok { header := s.eth.blockchain.GetHeaderByHash(hash)
rewards := c.GetRewards(hash) if header != nil {
if rewards != 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 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{}) return make(map[string]interface{})
} }

View file

@ -18,12 +18,9 @@
package eth package eth
import ( import (
"encoding/json"
"errors" "errors"
"fmt" "fmt"
"io/ioutil"
"math/big" "math/big"
"path/filepath"
"runtime" "runtime"
"sync" "sync"
"sync/atomic" "sync/atomic"
@ -292,8 +289,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{}) { c.HookReward = func(chain consensus.ChainReader, state *state.StateDB, header *types.Header) (error, map[string]interface{}) {
client, err := eth.blockchain.GetClient() client, err := eth.blockchain.GetClient()
if err != nil { if err != nil {
log.Error("Fail to connect IPC client for blockSigner", "error", err) log.Crit("Fail to connect IPC client for blockSigner", "error", err)
return err, nil
} }
number := header.Number.Uint64() number := header.Number.Uint64()
rCheckpoint := chain.Config().Posv.RewardCheckpoint rCheckpoint := chain.Config().Posv.RewardCheckpoint
@ -314,20 +310,17 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
signers, err := contracts.GetRewardForCheckpoint(chain, addr, number, rCheckpoint, client, totalSigner) signers, err := contracts.GetRewardForCheckpoint(chain, addr, number, rCheckpoint, client, totalSigner)
fmt.Println("Time Get Signers", "block", header.Number.Uint64(), "time", common.PrettyDuration(time.Since(start))) fmt.Println("Time Get Signers", "block", header.Number.Uint64(), "time", common.PrettyDuration(time.Since(start)))
if err != nil { if err != nil {
log.Error("Fail to get signers for reward checkpoint", "error", err) log.Crit("Fail to get signers for reward checkpoint", "error", err)
return err, nil
} }
rewards["signers"] = signers rewards["signers"] = signers
rewardSigners, err := contracts.CalculateRewardForSigner(chainReward, signers, *totalSigner) rewardSigners, err := contracts.CalculateRewardForSigner(chainReward, signers, *totalSigner)
if err != nil { if err != nil {
log.Error("Fail to calculate reward for signers", "error", err) log.Crit("Fail to calculate reward for signers", "error", err)
return err, nil
} }
// Get validator. // Get validator.
validator, err := contract.NewTomoValidator(common.HexToAddress(common.MasternodeVotingSMC), client) validator, err := contract.NewTomoValidator(common.HexToAddress(common.MasternodeVotingSMC), client)
if err != nil { if err != nil {
log.Error("Fail get instance of Tomo Validator", "error", err) log.Crit("Fail get instance of Tomo Validator", "error", err)
return err, nil
} }
// Add reward for coin holders. // Add reward for coin holders.
voterResults := make(map[common.Address]interface{}) voterResults := make(map[common.Address]interface{})
@ -337,8 +330,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
err, rewards := contracts.CalculateRewardForHolders(foudationWalletAddr, validator, state, signer, calcReward) err, rewards := contracts.CalculateRewardForHolders(foudationWalletAddr, validator, state, signer, calcReward)
// err, rewards := contracts.CalculateRewardForHolders2(foudationWalletAddr, vmenv, state, signer, calcReward) // err, rewards := contracts.CalculateRewardForHolders2(foudationWalletAddr, vmenv, state, signer, calcReward)
if err != nil { if err != nil {
log.Error("Fail to calculate reward for holders.", "error", err) log.Crit("Fail to calculate reward for holders.", "error", err)
return err, nil
} }
voterResults[signer] = rewards voterResults[signer] = rewards
} }
@ -378,27 +370,6 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
} }
return false 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 return eth, nil
} }

View file

@ -114,8 +114,6 @@ type Config struct {
// Miscellaneous options // Miscellaneous options
DocRoot string `toml:"-"` DocRoot string `toml:"-"`
StoreRewardFolder string
} }
type configMarshaling struct { type configMarshaling struct {

View file

@ -494,13 +494,7 @@ func (s *PublicBlockChainAPI) BlockNumber() *big.Int {
// BlockNumber returns the block number of the chain head. // BlockNumber returns the block number of the chain head.
func (s *PublicBlockChainAPI) GetRewardByHash(hash common.Hash) map[string]interface{} { func (s *PublicBlockChainAPI) GetRewardByHash(hash common.Hash) map[string]interface{} {
if c, ok := s.b.GetEngine().(*posv.Posv); ok { return s.b.GetRewardByHash(hash)
rewards := c.GetRewards(hash)
if rewards != nil {
return rewards
}
}
return make(map[string]interface{})
} }
// GetBalance returns the amount of wei for the given address in the state of the // GetBalance returns the amount of wei for the given address in the state of the
@ -865,6 +859,7 @@ func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx
client, err := s.b.GetIPCClient() client, err := s.b.GetIPCClient()
if err != nil { if err != nil {
log.Error("Fail to connect IPC client for block status", "error", err) log.Error("Fail to connect IPC client for block status", "error", err)
return nil, err
} }
var signers []common.Address var signers []common.Address
var filterSigners []common.Address var filterSigners []common.Address
@ -874,6 +869,7 @@ func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx
signers, err = contracts.GetSignersFromContract(addrBlockSigner, client, b.Hash()) signers, err = contracts.GetSignersFromContract(addrBlockSigner, client, b.Hash())
if err != nil { if err != nil {
log.Error("Fail to get signers from block signer SC.", "error", err) log.Error("Fail to get signers from block signer SC.", "error", err)
return nil, err
} }
// Get block epoc latest. // Get block epoc latest.
if s.b.ChainConfig().Posv != nil { if s.b.ChainConfig().Posv != nil {

View file

@ -18,8 +18,10 @@ package les
import ( import (
"context" "context"
"github.com/ethereum/go-ethereum/consensus/posv" "encoding/json"
"io/ioutil"
"math/big" "math/big"
"path/filepath"
"github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
@ -202,11 +204,25 @@ func (b *LesApiBackend) GetEngine() consensus.Engine {
return b.eth.engine return b.eth.engine
} }
func (s *LesApiBackend) GetRewardByHash(hash common.Hash) map[string]interface{} { func (s *LesApiBackend) GetRewardByHash(hash common.Hash) map[string]interface{} {
if c, ok := s.eth.Engine().(*posv.Posv); ok { header := s.eth.blockchain.GetHeaderByHash(hash)
rewards := c.GetRewards(hash) if header != nil {
if rewards != 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 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{}) return make(map[string]interface{})
} }

View file

@ -612,12 +612,12 @@ func (self *worker) commitNewWork() {
delete(self.possibleUncles, hash) delete(self.possibleUncles, hash)
} }
} }
if atomic.LoadInt32(&self.mining) == 1 {
// Create the new block to seal with the consensus engine // 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 { 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) log.Error("Failed to finalize block for sealing", "err", err)
return return
} }
if atomic.LoadInt32(&self.mining) == 1 {
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))) 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.unconfirmed.Shift(work.Block.NumberU64() - 1)
self.lastParentBlockCommit = parent.Hash().Hex() self.lastParentBlockCommit = parent.Hash().Hex()

View file

@ -133,7 +133,7 @@ func (s *Server) serveRequest(codec ServerCodec, singleShot bool, options CodecO
const size = 64 << 10 const size = 64 << 10
buf := make([]byte, size) buf := make([]byte, size)
buf = buf[:runtime.Stack(buf, false)] buf = buf[:runtime.Stack(buf, false)]
log.Error(string(buf)) log.Error(fmt.Sprintf("RPC serveRequest %s\n", string(buf)))
} }
s.codecsMu.Lock() s.codecsMu.Lock()
s.codecs.Remove(codec) 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 { 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() codec.Close()
} }
@ -371,7 +371,7 @@ func (s *Server) execBatch(ctx context.Context, codec ServerCodec, requests []*s
} }
if err := codec.Write(responses); err != nil { 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() codec.Close()
} }