Fixed check penalty using block creator instead of using block signer transaction.

This commit is contained in:
DinhLN 2019-01-29 14:53:53 +07:00 committed by Nguyen Ba Tam
parent e639f0f46e
commit 8747342373
3 changed files with 98 additions and 49 deletions

View file

@ -18,6 +18,7 @@ const (
LimitThresholdNonceInQueue = 10 LimitThresholdNonceInQueue = 10
DefaultMinGasPrice = 2500 DefaultMinGasPrice = 2500
MergeSignRange = 15 MergeSignRange = 15
RangeReturnSigner = 90
) )
var TIP2019Block = big.NewInt(1050000) var TIP2019Block = big.NewInt(1050000)

View file

@ -306,20 +306,8 @@ func DecryptRandomizeFromSecretsAndOpening(secrets [][32]byte, opening [32]byte)
return random, nil return random, nil
} }
// Calculate reward for reward checkpoint. // Get txw signed for block using cache or block body inside.
func GetRewardForCheckpoint(c *posv.Posv, chain consensus.ChainReader, header *types.Header, rCheckpoint uint64, totalSigner *uint64) (map[common.Address]*rewardLog, error) { func GetSignersSignedAtBlockHash(c *posv.Posv, chain consensus.ChainReader, data map[common.Hash][]common.Address, header *types.Header, curNumber uint64) map[common.Hash][]common.Address {
// Not reward for singer of genesis block and only calculate reward at checkpoint block.
number := header.Number.Uint64()
prevCheckpoint := number - (rCheckpoint * 2)
startBlockNumber := prevCheckpoint + 1
endBlockNumber := startBlockNumber + rCheckpoint - 1
signers := make(map[common.Address]*rewardLog)
mapBlkHash := map[uint64]common.Hash{}
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 { if signData, ok := c.BlockSigners.Get(header.Hash()); ok {
txs := signData.([]*types.Transaction) txs := signData.([]*types.Transaction)
for _, tx := range txs { for _, tx := range txs {
@ -328,10 +316,10 @@ func GetRewardForCheckpoint(c *posv.Posv, chain consensus.ChainReader, header *t
data[blkHash] = append(data[blkHash], from) data[blkHash] = append(data[blkHash], from)
} }
} else { } else {
log.Debug("Failed get from cached", "hash", header.Hash().String(), "number", i) log.Debug("Failed get from cached", "hash", header.Hash().String(), "number", curNumber)
block := chain.GetBlock(header.Hash(), i) block := chain.GetBlock(header.Hash(), curNumber)
txs := block.Transactions() txs := block.Transactions()
receipts := core.GetBlockReceipts(c.GetDb(), header.Hash(), i) receipts := core.GetBlockReceipts(c.GetDb(), header.Hash(), curNumber)
var signTxs []*types.Transaction var signTxs []*types.Transaction
for _, tx := range txs { for _, tx := range txs {
@ -360,6 +348,35 @@ func GetRewardForCheckpoint(c *posv.Posv, chain consensus.ChainReader, header *t
} }
c.BlockSigners.Add(header.Hash(), signTxs) c.BlockSigners.Add(header.Hash(), signTxs)
} }
return data
}
// Get signers list from bytes.
func GetSignersFromBytes(byteHeader []byte) []common.Address {
signers := make([]common.Address, len(byteHeader)/common.AddressLength)
for i := 0; i < len(masternodes); i++ {
copy(signers[i][:], byteHeader[i*common.AddressLength:])
}
return signers
}
// Calculate reward for reward checkpoint.
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.
number := header.Number.Uint64()
prevCheckpoint := number - (rCheckpoint * 2)
startBlockNumber := prevCheckpoint + 1
endBlockNumber := startBlockNumber + rCheckpoint - 1
signers := make(map[common.Address]*rewardLog)
mapBlkHash := map[uint64]common.Hash{}
data := make(map[common.Hash][]common.Address)
for curNumber := prevCheckpoint + (rCheckpoint * 2) - 1; curNumber >= startBlockNumber; curNumber-- {
header = chain.GetHeader(header.ParentHash, curNumber)
mapBlkHash[curNumber] = header.Hash()
data = GetSignersSignedAtBlockHash(c, chain, data, header, curNumber)
} }
header = chain.GetHeader(header.ParentHash, prevCheckpoint) header = chain.GetHeader(header.ParentHash, prevCheckpoint)
masternodes := posv.GetMasternodesFromCheckpointHeader(header) masternodes := posv.GetMasternodesFromCheckpointHeader(header)

View file

@ -274,7 +274,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
start := time.Now() start := time.Now()
prevHeader := chain.GetHeaderByNumber(prevEpoc) prevHeader := chain.GetHeaderByNumber(prevEpoc)
penSigners := c.GetMasternodes(chain, prevHeader) penSigners := c.GetMasternodes(chain, prevHeader)
goodSigners := make(map[common.Address]*big.Int) signedSigners := make(map[common.Address]*big.Int)
if len(penSigners) > 0 { if len(penSigners) > 0 {
// Loop for each block to check missing sign. // Loop for each block to check missing sign.
for i := prevEpoc; i < blockNumberEpoc; i++ { for i := prevEpoc; i < blockNumberEpoc; i++ {
@ -289,8 +289,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
} }
for _, addr := range penSigners { for _, addr := range penSigners {
if signer == addr { if signer == addr {
// Remove it from dupSigners. signedSigners[signer] = signedSigners[signer].Add(signedSigners[signer], big.NewInt(1))
goodSigners[signer] = goodSigners[signer].Add(goodSigners[signer], big.NewInt(1))
} }
} }
} else { } else {
@ -298,12 +297,12 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
} }
} }
if len(goodSigners) > 0 { if len(signedSigners) > 0 {
for signer, totalSign := range goodSigners { for signer, totalSign := range signedSigners {
if totalSign.Cmp(big.NewInt(4)) >= 0 { if totalSign.Cmp(big.NewInt(4)) >= 0 {
for j, addr := range penSigners { for j, addr := range penSigners {
if signer == addr { if signer == addr {
// Remove it from dupSigners. // If create block above 4 times then remove it from penSigners.
penSigners = append(penSigners[:j], penSigners[j+1:]...) penSigners = append(penSigners[:j], penSigners[j+1:]...)
} }
} }
@ -312,6 +311,38 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
} }
} }
} }
// Check penalty signer return chain.
prevSigners := contracts.GetSignersFromBytes(prevHeader.Penalties)
if len(prevSigners) > 0 {
startCheck := blockNumberEpoc - common.RangeReturnSigner
data := make(map[common.Hash][]common.Address)
mapBlkHash := map[uint64]common.Hash{}
for curNumber := startCheck; curNumber < blockNumberEpoc; curNumber++ {
signers := make(map[common.Hash][]common.Address)
header := chain.GetHeaderByNumber(curNumber)
mapBlkHash[curNumber] = header.Hash()
data = contracts.GetSignersSignedAtBlockHash(c, chain, signers, header, curNumber)
}
for _, blkHash := range mapBlkHash {
signers := data[blkHash]
for j, addr := range prevSigners {
for _, signer := range signers {
if signer == addr {
// If create block above 4 times then remove it from penSigners.
prevSigners = append(prevSigners[:j], prevSigners[j+1:]...)
}
}
}
}
if len(prevSigners) > 0 {
for _, signer := range prevSigners {
penSigners = append(penSigners, signer)
}
}
}
log.Debug("Time Calculated HookPenalty ", "block", blockNumberEpoc, "time", common.PrettyDuration(time.Since(start))) log.Debug("Time Calculated HookPenalty ", "block", blockNumberEpoc, "time", common.PrettyDuration(time.Since(start)))
return penSigners, nil return penSigners, nil
} }