fix error get signer when fork chain

This commit is contained in:
Nguyen Ba Tam 2019-01-15 17:44:01 +07:00
parent fe448f6a50
commit d6e910e268
2 changed files with 69 additions and 70 deletions

View file

@ -307,90 +307,88 @@ func DecryptRandomizeFromSecretsAndOpening(secrets [][32]byte, opening [32]byte)
} }
// Calculate reward for reward checkpoint. // Calculate reward for reward checkpoint.
func GetRewardForCheckpoint(c *posv.Posv, chain consensus.ChainReader, number uint64, rCheckpoint uint64, totalSigner *uint64) (map[common.Address]*rewardLog, error) { func GetRewardForCheckpoint(c *posv.Posv, chain consensus.ChainReader, header *types.Header, rCheckpoint uint64, totalSigner *uint64) (map[common.Address]*rewardLog, error) {
// Not reward for singer of genesis block and only calculate reward at checkpoint block. // Not reward for singer of genesis block and only calculate reward at checkpoint block.
number := header.Number.Uint64()
prevCheckpoint := number - (rCheckpoint * 2) prevCheckpoint := number - (rCheckpoint * 2)
startBlockNumber := prevCheckpoint + 1 startBlockNumber := prevCheckpoint + 1
endBlockNumber := startBlockNumber + rCheckpoint - 1 endBlockNumber := startBlockNumber + rCheckpoint - 1
signers := make(map[common.Address]*rewardLog) signers := make(map[common.Address]*rewardLog)
prevHeaderCheckpoint := chain.GetHeaderByNumber(prevCheckpoint) mapBlkHash := map[uint64]common.Hash{}
masternodes := posv.GetMasternodesFromCheckpointHeader(prevHeaderCheckpoint)
if len(masternodes) > 0 { data := make(map[common.Hash][]common.Address)
for i := prevCheckpoint + (rCheckpoint * 2) - 1; i >= startBlockNumber; i-- {
header = chain.GetHeader(header.ParentHash, i)
mapBlkHash[i] = header.Hash()
if signData, ok := c.BlockSigners.Get(header.Hash()); ok {
txs := signData.([]*types.Transaction)
for _, tx := range txs {
blkHash := common.BytesToHash(tx.Data()[len(tx.Data())-32:])
from := *tx.From()
data[blkHash] = append(data[blkHash], from)
}
} else {
log.Debug("Failed get from cached", "hash", header.Hash().String(), "number", i)
block := chain.GetBlock(header.Hash(), i)
txs := block.Transactions()
receipts := core.GetBlockReceipts(c.GetDb(), header.Hash(), i)
data := make(map[common.Hash][]common.Address) var signTxs []*types.Transaction
for i := startBlockNumber; i <= prevCheckpoint+(rCheckpoint*2)-1; i++ { for _, tx := range txs {
header := chain.GetHeaderByNumber(i) if tx.IsSigningTransaction() {
if signData, ok := c.BlockSigners.Get(header.Hash()); ok { var b uint
txs := signData.([]*types.Transaction) for _, r := range receipts {
for _, tx := range txs { if r.TxHash == tx.Hash() {
if len(r.PostState) > 0 {
b = types.ReceiptStatusSuccessful
} else {
b = r.Status
}
break
}
}
if b == types.ReceiptStatusFailed {
continue
}
signTxs = append(signTxs, tx)
blkHash := common.BytesToHash(tx.Data()[len(tx.Data())-32:]) blkHash := common.BytesToHash(tx.Data()[len(tx.Data())-32:])
from := *tx.From() from := *tx.From()
data[blkHash] = append(data[blkHash], from) data[blkHash] = append(data[blkHash], from)
} }
} else { }
log.Debug("Failed get from cached", "hash", header.Hash().String(), "number", i) c.BlockSigners.Add(header.Hash(), signTxs)
block := chain.GetBlock(header.Hash(), i) }
txs := block.Transactions() }
receipts := core.GetBlockReceipts(c.GetDb(), header.Hash(), i) header = chain.GetHeader(header.ParentHash, prevCheckpoint)
masternodes := posv.GetMasternodesFromCheckpointHeader(header)
var signTxs []*types.Transaction for i := startBlockNumber; i <= endBlockNumber; i++ {
for _, tx := range txs { if i%common.MergeSignRange == 0 || !chain.Config().IsTIP2019(big.NewInt(int64(i))) {
if tx.IsSigningTransaction() { addrs := data[mapBlkHash[i]]
var b uint // Filter duplicate address.
for _, r := range receipts { if len(addrs) > 0 {
if r.TxHash == tx.Hash() { addrSigners := make(map[common.Address]bool)
if len(r.PostState) > 0 { for _, masternode := range masternodes {
b = types.ReceiptStatusSuccessful for _, addr := range addrs {
} else { if addr == masternode {
b = r.Status if _, ok := addrSigners[addr]; !ok {
} addrSigners[addr] = true
break
} }
break
} }
if b == types.ReceiptStatusFailed {
continue
}
signTxs = append(signTxs, tx)
blkHash := common.BytesToHash(tx.Data()[len(tx.Data())-32:])
from := *tx.From()
data[blkHash] = append(data[blkHash], from)
} }
} }
c.BlockSigners.Add(header.Hash(), signTxs)
} for addr := range addrSigners {
} _, exist := signers[addr]
if exist {
for i := startBlockNumber; i <= endBlockNumber; i++ { signers[addr].Sign++
if i%common.MergeSignRange == 0 || !chain.Config().IsTIP2019(big.NewInt(int64(i))) { } else {
block := chain.GetHeaderByNumber(i) signers[addr] = &rewardLog{1, new(big.Int)}
addrs := data[block.Hash()]
// Filter duplicate address.
if len(addrs) > 0 {
addrSigners := make(map[common.Address]bool)
for _, masternode := range masternodes {
for _, addr := range addrs {
if addr == masternode {
if _, ok := addrSigners[addr]; !ok {
addrSigners[addr] = true
}
break
}
}
}
for addr := range addrSigners {
_, exist := signers[addr]
if exist {
signers[addr].Sign++
} else {
signers[addr] = &rewardLog{1, new(big.Int)}
}
*totalSigner++
} }
*totalSigner++
} }
} }
} }

View file

@ -291,8 +291,9 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
} }
// Hook calculates reward for masternodes // Hook calculates reward for masternodes
c.HookReward = func(chain consensus.ChainReader, state *state.StateDB, header *types.Header) (error, map[string]interface{}) { c.HookReward = func(chain consensus.ChainReader, stateBlock *state.StateDB, header *types.Header) (error, map[string]interface{}) {
canonicalState, err := eth.blockchain.State() parentHeader := eth.blockchain.GetHeader(header.ParentHash, header.Number.Uint64()-1)
canonicalState, err := eth.blockchain.StateAt(parentHeader.Root)
if canonicalState == nil || err != nil { if canonicalState == nil || err != nil {
log.Crit("Can't get state at head of canonical chain", "head number", header.Number.Uint64(), "err", err) log.Crit("Can't get state at head of canonical chain", "head number", header.Number.Uint64(), "err", err)
} }
@ -312,7 +313,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
chainReward = rewardInflation(chainReward, number, common.BlocksPerYear) chainReward = rewardInflation(chainReward, number, common.BlocksPerYear)
totalSigner := new(uint64) totalSigner := new(uint64)
signers, err := contracts.GetRewardForCheckpoint(c, chain, number, rCheckpoint, totalSigner) signers, err := contracts.GetRewardForCheckpoint(c, chain, header, rCheckpoint, totalSigner)
log.Debug("Time Get Signers", "block", header.Number.Uint64(), "time", common.PrettyDuration(time.Since(start))) log.Debug("Time Get Signers", "block", header.Number.Uint64(), "time", common.PrettyDuration(time.Since(start)))
if err != nil { if err != nil {
@ -333,7 +334,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
} }
if len(rewards) > 0 { if len(rewards) > 0 {
for holder, reward := range rewards { for holder, reward := range rewards {
state.AddBalance(holder, reward) stateBlock.AddBalance(holder, reward)
} }
} }
voterResults[signer] = rewards voterResults[signer] = rewards