1package poa23import (4 "errors"56 "gno.land/p/nt/bptree/v0"7 "gno.land/p/sys/validators/v0"8)910var ErrInvalidVotingPower = errors.New("invalid voting power")1112// PoA specifies the Proof of Authority validator set, with simple add / remove constraints.13//14// To add:15// - proposed validator must not be part of the set already16// - proposed validator voting power must be > 017//18// To remove:19// - proposed validator must be part of the set already20type PoA struct {21 validators *bptree.BPTree // address -> validators.Validator22}2324// NewPoA creates a new empty Proof of Authority validator set25func NewPoA(opts ...Option) *PoA {26 // Create the empty set27 p := &PoA{28 validators: bptree.NewBPTree32(),29 }3031 // Apply the options32 for _, opt := range opts {33 opt(p)34 }3536 return p37}3839func (p *PoA) AddValidator(address_XXX address, pubKey string, power uint64) (validators.Validator, error) {40 // Validate that the operation is a valid call.41 // Check if the validator is already in the set42 if p.IsValidator(address_XXX) {43 return validators.Validator{}, validators.ErrValidatorExists44 }4546 // Make sure the voting power > 047 if power == 0 {48 return validators.Validator{}, ErrInvalidVotingPower49 }5051 v := validators.Validator{52 Address: address_XXX,53 PubKey: pubKey, // TODO: in the future, verify the public key54 VotingPower: power,55 }5657 // Add the validator to the set58 p.validators.Set(address_XXX.String(), v)5960 return v, nil61}6263func (p *PoA) RemoveValidator(address_XXX address) (validators.Validator, error) {64 // Validate that the operation is a valid call65 // Fetch the validator66 validator, err := p.GetValidator(address_XXX)67 if err != nil {68 return validators.Validator{}, err69 }7071 // Remove the validator from the set72 p.validators.Remove(address_XXX.String())7374 return validator, nil75}7677func (p *PoA) IsValidator(address_XXX address) bool {78 return p.validators.Has(address_XXX.String())79}8081func (p *PoA) GetValidator(address_XXX address) (validators.Validator, error) {82 validatorRaw := p.validators.Get(address_XXX.String())83 if validatorRaw == nil {84 return validators.Validator{}, validators.ErrValidatorMissing85 }8687 validator := validatorRaw.(validators.Validator)8889 return validator, nil90}9192func (p *PoA) GetValidators() []validators.Validator {93 vals := make([]validators.Validator, 0, p.validators.Size())9495 p.validators.Iterate("", "", func(_ string, value any) bool {96 validator := value.(validators.Validator)97 vals = append(vals, validator)9899 return false100 })101102 return vals103}104Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.