From a959bea0921b6b7067185f01b2ce620258df0ac0 Mon Sep 17 00:00:00 2001 From: Wanwiset Peerapatanapokin Date: Fri, 21 Jul 2023 10:07:05 +0400 Subject: [PATCH] add standbynodes in GetMasternodesByNumber similar way to subnet --- consensus/XDPoS/api.go | 31 +++++++++++-------- consensus/XDPoS/engines/engine_v2/engine.go | 11 ++++++- .../XDPoS/engines/engine_v2/epochSwitch.go | 19 ++++++++++-- core/types/consensus_v2.go | 1 + 4 files changed, 46 insertions(+), 16 deletions(-) diff --git a/consensus/XDPoS/api.go b/consensus/XDPoS/api.go index a13f3c2f9636..0228c5ce1410 100644 --- a/consensus/XDPoS/api.go +++ b/consensus/XDPoS/api.go @@ -62,13 +62,15 @@ type SignerTypes struct { } type MasternodesStatus struct { - Number uint64 - Round types.Round - MasternodesLen int - Masternodes []common.Address - PenaltyLen int - Penalty []common.Address - Error error + Number uint64 + Round types.Round + MasternodesLen int + Masternodes []common.Address + PenaltyLen int + Penalty []common.Address + StandbynodesLen int + Standbynodes []common.Address + Error error } type MessageStatus map[string]map[string]SignerTypes @@ -144,14 +146,17 @@ func (api *API) GetMasternodesByNumber(number *rpc.BlockNumber) MasternodesStatu masterNodes := api.XDPoS.EngineV2.GetMasternodes(api.chain, header) penalties := api.XDPoS.EngineV2.GetPenalties(api.chain, header) + standbynodes := api.XDPoS.EngineV2.GetStandbynodes(api.chain, header) info := MasternodesStatus{ - Number: header.Number.Uint64(), - Round: round, - MasternodesLen: len(masterNodes), - Masternodes: masterNodes, - PenaltyLen: len(penalties), - Penalty: penalties, + Number: header.Number.Uint64(), + Round: round, + MasternodesLen: len(masterNodes), + Masternodes: masterNodes, + PenaltyLen: len(penalties), + Penalty: penalties, + StandbynodesLen: len(standbynodes), + Standbynodes: standbynodes, } return info } diff --git a/consensus/XDPoS/engines/engine_v2/engine.go b/consensus/XDPoS/engines/engine_v2/engine.go index 8366e9a89995..cff0c57b9e5b 100644 --- a/consensus/XDPoS/engines/engine_v2/engine.go +++ b/consensus/XDPoS/engines/engine_v2/engine.go @@ -987,12 +987,21 @@ func (x *XDPoS_v2) GetMasternodes(chain consensus.ChainReader, header *types.Hea func (x *XDPoS_v2) GetPenalties(chain consensus.ChainReader, header *types.Header) []common.Address { epochSwitchInfo, err := x.getEpochSwitchInfo(chain, header, header.Hash()) if err != nil { - log.Error("[GetMasternodes] Adaptor v2 getEpochSwitchInfo has error", "err", err) + log.Error("[GetPenalties] Adaptor v2 getEpochSwitchInfo has error", "err", err) return []common.Address{} } return epochSwitchInfo.Penalties } +func (x *XDPoS_v2) GetStandbynodes(chain consensus.ChainReader, header *types.Header) []common.Address { + epochSwitchInfo, err := x.getEpochSwitchInfo(chain, header, header.Hash()) + if err != nil { + log.Error("[GetStandbynodes] Adaptor v2 getEpochSwitchInfo has error", "err", err) + return []common.Address{} + } + return epochSwitchInfo.Standbynodes +} + // Calculate masternodes for a block number and parent hash. In V2, truncating candidates[:MaxMasternodes] is done in this function. func (x *XDPoS_v2) calcMasternodes(chain consensus.ChainReader, blockNum *big.Int, parentHash common.Hash) ([]common.Address, []common.Address, error) { // using new max masterndoes diff --git a/consensus/XDPoS/engines/engine_v2/epochSwitch.go b/consensus/XDPoS/engines/engine_v2/epochSwitch.go index 3660c15f9b8e..7b6e50b94b71 100644 --- a/consensus/XDPoS/engines/engine_v2/epochSwitch.go +++ b/consensus/XDPoS/engines/engine_v2/epochSwitch.go @@ -56,10 +56,25 @@ func (x *XDPoS_v2) getEpochSwitchInfo(chain consensus.ChainReader, header *types log.Error("[getEpochSwitchInfo] get extra field", "err", err, "number", h.Number.Uint64()) return nil, err } + + snap, err := x.getSnapshot(chain, header.Number.Uint64(), false) + if err != nil { + log.Error("[getEpochSwitchInfo] Adaptor v2 getSnapshot has error", "err", err) + return nil, err + } penalties := common.ExtractAddressFromBytes(h.Penalties) + candidates := snap.NextEpochMasterNodes + standbynodes := []common.Address{} + if len(masternodes) != len(candidates) { + standbynodes = candidates + standbynodes = common.RemoveItemFromArray(standbynodes, masternodes) + standbynodes = common.RemoveItemFromArray(standbynodes, penalties) + } + epochSwitchInfo := &types.EpochSwitchInfo{ - Penalties: penalties, - Masternodes: masternodes, + Penalties: penalties, + Standbynodes: standbynodes, + Masternodes: masternodes, EpochSwitchBlockInfo: &types.BlockInfo{ Hash: hash, Number: h.Number, diff --git a/core/types/consensus_v2.go b/core/types/consensus_v2.go index ce3090487caf..3f4c7cec8c9b 100644 --- a/core/types/consensus_v2.go +++ b/core/types/consensus_v2.go @@ -112,6 +112,7 @@ func (e *ExtraFields_v2) EncodeToBytes() ([]byte, error) { type EpochSwitchInfo struct { Penalties []common.Address + Standbynodes []common.Address Masternodes []common.Address EpochSwitchBlockInfo *BlockInfo EpochSwitchParentBlockInfo *BlockInfo