github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/execution/contexts/bond_context.go (about) 1 package contexts 2 3 import ( 4 "fmt" 5 "math/big" 6 7 "github.com/hyperledger/burrow/acm/acmstate" 8 "github.com/hyperledger/burrow/acm/validator" 9 "github.com/hyperledger/burrow/crypto" 10 "github.com/hyperledger/burrow/execution/exec" 11 "github.com/hyperledger/burrow/logging" 12 "github.com/hyperledger/burrow/txs/payload" 13 ) 14 15 type BondContext struct { 16 State acmstate.ReaderWriter 17 ValidatorSet validator.ReaderWriter 18 Logger *logging.Logger 19 tx *payload.BondTx 20 } 21 22 // Execute a BondTx to add or remove a new validator 23 func (ctx *BondContext) Execute(txe *exec.TxExecution, p payload.Payload) error { 24 var ok bool 25 ctx.tx, ok = p.(*payload.BondTx) 26 if !ok { 27 return fmt.Errorf("payload must be BondTx, but is: %v", txe.Envelope.Tx.Payload) 28 } 29 30 // the account initiating the bond 31 power := new(big.Int).SetUint64(ctx.tx.Input.GetAmount()) 32 account, err := ctx.State.GetAccount(ctx.tx.Input.Address) 33 if err != nil { 34 return err 35 } 36 37 ct := account.PublicKey.GetCurveType() 38 if ct == crypto.CurveTypeSecp256k1 { 39 return fmt.Errorf("secp256k1 not supported") 40 } 41 42 // can the account bond? 43 if !hasBondPermission(ctx.State, account, ctx.Logger) { 44 return fmt.Errorf("account '%s' lacks bond permission", account.Address) 45 } 46 47 // check account has enough to bond 48 amount := ctx.tx.Input.GetAmount() 49 if amount == 0 { 50 return fmt.Errorf("nothing to bond") 51 } else if account.Balance < amount { 52 return fmt.Errorf("insufficient funds, account %s only has balance %v and "+ 53 "we are deducting %v", account.Address, account.Balance, amount) 54 } 55 56 // we're good to go 57 err = account.SubtractFromBalance(amount) 58 if err != nil { 59 return err 60 } 61 62 // assume public key is know as we update account from signatures 63 err = validator.AddPower(ctx.ValidatorSet, account.PublicKey, power) 64 if err != nil { 65 return err 66 } 67 68 return ctx.State.UpdateAccount(account) 69 }