HandleMessageStake() is the proper handler for a `Stake` message (Validator does not yet exist in the state)
(msg *MessageStake)
| 64 | |
| 65 | // HandleMessageStake() is the proper handler for a `Stake` message (Validator does not yet exist in the state) |
| 66 | func (s *StateMachine) HandleMessageStake(msg *MessageStake) lib.ErrorI { |
| 67 | // convert the message public key bytes into a public key object |
| 68 | publicKey, e := crypto.NewPublicKeyFromBytes(msg.PublicKey) |
| 69 | if e != nil { |
| 70 | return ErrInvalidPublicKey(e) |
| 71 | } |
| 72 | // the public key must be a BLS public key to be a validator in order to participate in consensus for efficient signature aggregation |
| 73 | if !msg.Delegate { |
| 74 | if _, ok := publicKey.(*crypto.BLS12381PublicKey); !ok { |
| 75 | return ErrInvalidPublicKey(e) |
| 76 | } |
| 77 | } |
| 78 | // check the net address of the message |
| 79 | if err := CheckNetAddress(msg.NetAddress, msg.Delegate); err != nil { |
| 80 | return err |
| 81 | } |
| 82 | // extract the address from the BLS public key |
| 83 | address := publicKey.Address() |
| 84 | // check if validator exists in state |
| 85 | exists, err := s.GetValidatorExists(address) |
| 86 | if err != nil { |
| 87 | return err |
| 88 | } |
| 89 | // fail if validator already exists |
| 90 | if exists { |
| 91 | return ErrValidatorExists() |
| 92 | } |
| 93 | // get val params for validation |
| 94 | params, err := s.GetParamsVal() |
| 95 | if err != nil { |
| 96 | return err |
| 97 | } |
| 98 | // validate stake is above minimums |
| 99 | if msg.Delegate { |
| 100 | if msg.Amount < params.MinimumStakeForDelegates { |
| 101 | return ErrStakeBelowMininum() |
| 102 | } |
| 103 | } else { |
| 104 | if msg.Amount < params.MinimumStakeForValidators { |
| 105 | return ErrStakeBelowMininum() |
| 106 | } |
| 107 | } |
| 108 | // subtract the tokens being locked from the signer account |
| 109 | if err = s.AccountSub(crypto.NewAddress(msg.Signer), msg.Amount); err != nil { |
| 110 | return err |
| 111 | } |
| 112 | // add to the 'total staked' tokens count in the state's supply tracker |
| 113 | if err = s.AddToStakedSupply(msg.Amount); err != nil { |
| 114 | return err |
| 115 | } |
| 116 | // if the validator is not 'actively participating' it is a delegate |
| 117 | if msg.Delegate { |
| 118 | // add to the 'delegate only' staked tokens count in the state's supply tracker |
| 119 | if err = s.AddToDelegateSupply(msg.Amount); err != nil { |
| 120 | return err |
| 121 | } |
| 122 | // set delegated validator in each committee in state |
| 123 | if err = s.SetDelegations(address, msg.Amount, msg.Committees); err != nil { |