Skip to content

Commit

Permalink
consortium/v2: add RPC API for querying finality vote easily (axieinf…
Browse files Browse the repository at this point in the history
…inity#318)

This commit adds 2 APIs in consortiumv2 namespace:
consortiumv2_getValidatorAtHash, consortiumv2_getFinalityVoteAtHash.
consortiumv2_getValidatorAtHash returns the authorized validators that can seal
block hash with BLS public key. consortiumv2_getFinalityVoteAtHash returns the
finality vote information in the block header at block hash.
  • Loading branch information
minh-bq committed Sep 7, 2023
1 parent 6f2bf3a commit 555a252
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 1 deletion.
80 changes: 80 additions & 0 deletions consensus/consortium/v2/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package v2

import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus"
consortiumCommon "github.com/ethereum/go-ethereum/consensus/consortium/common"
"github.com/ethereum/go-ethereum/consensus/consortium/v2/finality"
)

type consortiumV2Api struct {
chain consensus.ChainHeaderReader
consortium *Consortium
}

// GetValidatorAtHash returns the authorized validators that can seal block hash with
// their BLS public key if available
func (api *consortiumV2Api) GetValidatorAtHash(hash common.Hash) ([]finality.ValidatorWithBlsPub, error) {
header := api.chain.GetHeaderByHash(hash)
if header == nil {
return nil, consortiumCommon.ErrUnknownBlock
}

snap, err := api.consortium.snapshot(api.chain, header.Number.Uint64()-1, header.ParentHash, nil)
if err != nil {
return nil, err
}

if snap.ValidatorsWithBlsPub != nil {
return snap.ValidatorsWithBlsPub, nil
}

var validators []finality.ValidatorWithBlsPub
for validator := range snap.Validators {
validators = append(validators, finality.ValidatorWithBlsPub{
Address: validator,
})
}

return validators, nil
}

type finalityVote struct {
Signature string
VoterPublicKey []string
VoterAddress []string
}

// GetFinalityVoteAtHash returns the finality vote at block hash
func (api *consortiumV2Api) GetFinalityVoteAtHash(hash common.Hash) (*finalityVote, error) {
header := api.chain.GetHeaderByHash(hash)
if header == nil {
return nil, consortiumCommon.ErrUnknownBlock
}

isShillin := api.consortium.chainConfig.IsShillin(header.Number)
extraData, err := finality.DecodeExtra(header.Extra, isShillin)
if err != nil {
return nil, err
}

if extraData.HasFinalityVote == 0 {
return nil, nil
}

var vote finalityVote
vote.Signature = common.Bytes2Hex(extraData.AggregatedFinalityVotes.Marshal())

snap, err := api.consortium.snapshot(api.chain, header.Number.Uint64()-1, header.ParentHash, nil)
if err != nil {
return nil, err
}
position := extraData.FinalityVotedValidators.Indices()
for _, pos := range position {
validator := snap.ValidatorsWithBlsPub[pos]
vote.VoterAddress = append(vote.VoterAddress, validator.Address.Hex())
vote.VoterPublicKey = append(vote.VoterPublicKey, common.Bytes2Hex(validator.BlsPublicKey.Marshal()))
}

return &vote, nil
}
9 changes: 8 additions & 1 deletion consensus/consortium/v2/consortium.go
Original file line number Diff line number Diff line change
Expand Up @@ -1021,7 +1021,14 @@ func (c *Consortium) Close() error {

// APIs are backward compatible with the v1, so we do not to implement it again
func (c *Consortium) APIs(chain consensus.ChainHeaderReader) []rpc.API {
return []rpc.API{}
return []rpc.API{
{
Namespace: "consortiumv2",
Version: "1.0",
Service: &consortiumV2Api{chain: chain, consortium: c},
Public: false,
},
}
}

// CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty
Expand Down

0 comments on commit 555a252

Please sign in to comment.