Search Apps Documentation Source Content File Folder Download Copy Actions Download

poa.gno

2.46 Kb ยท 105 lines
  1package poa
  2
  3import (
  4	"errors"
  5
  6	"gno.land/p/nt/avl"
  7	"gno.land/p/sys/validators"
  8)
  9
 10var ErrInvalidVotingPower = errors.New("invalid voting power")
 11
 12// 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 already
 16// - proposed validator voting power must be > 0
 17//
 18// To remove:
 19// - proposed validator must be part of the set already
 20type PoA struct {
 21	validators *avl.Tree // address -> validators.Validator
 22}
 23
 24// NewPoA creates a new empty Proof of Authority validator set
 25func NewPoA(opts ...Option) *PoA {
 26	// Create the empty set
 27	p := &PoA{
 28		validators: avl.NewTree(),
 29	}
 30
 31	// Apply the options
 32	for _, opt := range opts {
 33		opt(p)
 34	}
 35
 36	return p
 37}
 38
 39func (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 set
 42	if p.IsValidator(address_XXX) {
 43		return validators.Validator{}, validators.ErrValidatorExists
 44	}
 45
 46	// Make sure the voting power > 0
 47	if power == 0 {
 48		return validators.Validator{}, ErrInvalidVotingPower
 49	}
 50
 51	v := validators.Validator{
 52		Address:     address_XXX,
 53		PubKey:      pubKey, // TODO: in the future, verify the public key
 54		VotingPower: power,
 55	}
 56
 57	// Add the validator to the set
 58	p.validators.Set(address_XXX.String(), v)
 59
 60	return v, nil
 61}
 62
 63func (p *PoA) RemoveValidator(address_XXX address) (validators.Validator, error) {
 64	// Validate that the operation is a valid call
 65	// Fetch the validator
 66	validator, err := p.GetValidator(address_XXX)
 67	if err != nil {
 68		return validators.Validator{}, err
 69	}
 70
 71	// Remove the validator from the set
 72	p.validators.Remove(address_XXX.String())
 73
 74	return validator, nil
 75}
 76
 77func (p *PoA) IsValidator(address_XXX address) bool {
 78	_, exists := p.validators.Get(address_XXX.String())
 79
 80	return exists
 81}
 82
 83func (p *PoA) GetValidator(address_XXX address) (validators.Validator, error) {
 84	validatorRaw, exists := p.validators.Get(address_XXX.String())
 85	if !exists {
 86		return validators.Validator{}, validators.ErrValidatorMissing
 87	}
 88
 89	validator := validatorRaw.(validators.Validator)
 90
 91	return validator, nil
 92}
 93
 94func (p *PoA) GetValidators() []validators.Validator {
 95	vals := make([]validators.Validator, 0, p.validators.Size())
 96
 97	p.validators.Iterate("", "", func(_ string, value any) bool {
 98		validator := value.(validators.Validator)
 99		vals = append(vals, validator)
100
101		return false
102	})
103
104	return vals
105}