mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-19 13:21:37 +00:00
feat(consensus): add RPC endpoint to query signing tx count by epoch
This commit is contained in:
parent
9579593438
commit
99bbb60b9b
3 changed files with 80 additions and 2 deletions
|
|
@ -769,3 +769,75 @@ func (api *API) GetBlockInfoByEpochNum(epochNumber uint64) (*utils.EpochNumInfo,
|
||||||
}
|
}
|
||||||
return api.GetBlockInfoByV2EpochNum(epochNumber)
|
return api.GetBlockInfoByV2EpochNum(epochNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetSigningTxCountByEpoch returns the signing transaction count for ALL masternodes
|
||||||
|
// (including non-active ones) in the epoch that ends at epochBlockNum.
|
||||||
|
// epochBlockNum must be an epoch-switch block number.
|
||||||
|
func (api *API) GetSigningTxCountByEpoch(epochBlockNum rpc.BlockNumber) (map[common.Address]uint64, error) {
|
||||||
|
header := api.chain.GetHeaderByNumber(uint64(epochBlockNum.Int64()))
|
||||||
|
if header == nil {
|
||||||
|
return nil, fmt.Errorf("block %d not found", epochBlockNum)
|
||||||
|
}
|
||||||
|
|
||||||
|
isEpochSwitch, _, err := api.XDPoS.IsEpochSwitch(header)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !isEpochSwitch {
|
||||||
|
return nil, fmt.Errorf("block %d is not an epoch switch block", epochBlockNum)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Walk backwards from epochBlockNum-1 to the previous epoch switch block,
|
||||||
|
// collecting signing txs from every block.
|
||||||
|
mapBlkHash := map[uint64]common.Hash{}
|
||||||
|
// sigData maps blockHash -> list of signers who signed for that block
|
||||||
|
sigData := make(map[common.Hash][]common.Address)
|
||||||
|
|
||||||
|
h := header
|
||||||
|
for i := header.Number.Uint64() - 1; ; i-- {
|
||||||
|
parentHash := h.ParentHash
|
||||||
|
h = api.chain.GetHeader(parentHash, i)
|
||||||
|
if h == nil {
|
||||||
|
return nil, fmt.Errorf("failed to get header at number %d hash %s", i, parentHash.Hex())
|
||||||
|
}
|
||||||
|
|
||||||
|
mapBlkHash[i] = h.Hash()
|
||||||
|
|
||||||
|
signingTxs, ok := api.XDPoS.GetCachedSigningTxs(h.Hash())
|
||||||
|
if !ok {
|
||||||
|
block := api.chain.GetBlock(h.Hash(), i)
|
||||||
|
if block != nil {
|
||||||
|
signingTxs = api.XDPoS.CacheSigningTxs(h.Hash(), block.Transactions())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, tx := range signingTxs {
|
||||||
|
blkHash := common.BytesToHash(tx.Data()[len(tx.Data())-32:])
|
||||||
|
from := *tx.From()
|
||||||
|
sigData[blkHash] = append(sigData[blkHash], from)
|
||||||
|
}
|
||||||
|
|
||||||
|
prevIsEpochSwitch, _, err := api.XDPoS.IsEpochSwitch(h)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if prevIsEpochSwitch || i == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count signings: for each block at MergeSignRange boundary, tally unique signers.
|
||||||
|
result := make(map[common.Address]uint64)
|
||||||
|
for blockNum, blkHash := range mapBlkHash {
|
||||||
|
if blockNum%common.MergeSignRange != 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
seen := make(map[common.Address]bool)
|
||||||
|
for _, addr := range sigData[blkHash] {
|
||||||
|
if !seen[addr] {
|
||||||
|
seen[addr] = true
|
||||||
|
result[addr]++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -124,7 +124,7 @@ func (x *XDPoS_v2) getTCEpochInfo(chain consensus.ChainReader, timeoutRound type
|
||||||
Round: epochRound,
|
Round: epochRound,
|
||||||
Number: epochSwitchInfo.EpochSwitchBlockInfo.Number,
|
Number: epochSwitchInfo.EpochSwitchBlockInfo.Number,
|
||||||
}
|
}
|
||||||
log.Info("[getTCEpochInfo] Init epochInfo", "number", epochBlockInfo.Number, "round", epochRound, "tcRound", timeoutRound, "tcEpoch", tempTCEpoch)
|
log.Debug("[getTCEpochInfo] Init epochInfo", "number", epochBlockInfo.Number, "round", epochRound, "tcRound", timeoutRound, "tcEpoch", tempTCEpoch)
|
||||||
for epochBlockInfo.Round > timeoutRound && tempTCEpoch > 0 {
|
for epochBlockInfo.Round > timeoutRound && tempTCEpoch > 0 {
|
||||||
tempTCEpoch--
|
tempTCEpoch--
|
||||||
epochBlockInfo, err = x.GetBlockByEpochNumber(chain, tempTCEpoch)
|
epochBlockInfo, err = x.GetBlockByEpochNumber(chain, tempTCEpoch)
|
||||||
|
|
@ -135,7 +135,7 @@ func (x *XDPoS_v2) getTCEpochInfo(chain consensus.ChainReader, timeoutRound type
|
||||||
log.Debug("[getTCEpochInfo] Loop to get right epochInfo", "number", epochBlockInfo.Number, "round", epochBlockInfo.Round, "tcRound", timeoutRound, "tcEpoch", tempTCEpoch)
|
log.Debug("[getTCEpochInfo] Loop to get right epochInfo", "number", epochBlockInfo.Number, "round", epochBlockInfo.Round, "tcRound", timeoutRound, "tcEpoch", tempTCEpoch)
|
||||||
}
|
}
|
||||||
tcEpoch := tempTCEpoch
|
tcEpoch := tempTCEpoch
|
||||||
log.Info("[getTCEpochInfo] Final TC epochInfo", "number", epochBlockInfo.Number, "round", epochBlockInfo.Round, "tcRound", timeoutRound, "tcEpoch", tcEpoch)
|
log.Debug("[getTCEpochInfo] Final TC epochInfo", "number", epochBlockInfo.Number, "round", epochBlockInfo.Round, "tcRound", timeoutRound, "tcEpoch", tcEpoch)
|
||||||
|
|
||||||
epochInfo, err := x.getEpochSwitchInfo(chain, nil, epochBlockInfo.Hash)
|
epochInfo, err := x.getEpochSwitchInfo(chain, nil, epochBlockInfo.Hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,12 @@ web3._extend({
|
||||||
params: 3,
|
params: 3,
|
||||||
inputFormatter: [null, web3._extend.formatters.inputBlockNumberFormatter, web3._extend.formatters.inputBlockNumberFormatter]
|
inputFormatter: [null, web3._extend.formatters.inputBlockNumberFormatter, web3._extend.formatters.inputBlockNumberFormatter]
|
||||||
}),
|
}),
|
||||||
|
new web3._extend.Method({
|
||||||
|
name: 'getSigningTxCountByEpoch',
|
||||||
|
call: 'XDPoS_getSigningTxCountByEpoch',
|
||||||
|
params: 1,
|
||||||
|
inputFormatter: [web3._extend.formatters.inputBlockNumberFormatter]
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
properties: [
|
properties: [
|
||||||
new web3._extend.Property({
|
new web3._extend.Property({
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue