func Bond(nodeAddr, signAddr, pubkey, unbondAddr, amtS, nonceS string) (*types.BondTx, error) { pub, amt, nonce, err := checkCommon(nodeAddr, signAddr, pubkey, "", amtS, nonceS) if err != nil { return nil, err } var pubKey account.PubKeyEd25519 var unbondAddrBytes []byte if unbondAddr == "" { pkb, _ := hex.DecodeString(pubkey) copy(pubKey[:], pkb) unbondAddrBytes = pubKey.Address() } else { unbondAddrBytes, err = hex.DecodeString(unbondAddr) if err != nil { return nil, fmt.Errorf("unbondAddr is bad hex: %v", err) } } tx, err := types.NewBondTx(pub) if err != nil { return nil, err } tx.AddInputWithNonce(pub, amt, int(nonce)) tx.AddOutput(unbondAddrBytes, amt) return tx, nil }
func TestBondPermission(t *testing.T) { stateDB := dbm.GetDB("state") genDoc := newBaseGenDoc(PermsAllFalse, PermsAllFalse) st := MakeGenesisState(stateDB, &genDoc) blockCache := NewBlockCache(st) var bondAcc *acm.Account //------------------------------ // one bonder without permission should fail tx, _ := types.NewBondTx(user[1].PubKey) if err := tx.AddInput(blockCache, user[1].PubKey, 5); err != nil { t.Fatal(err) } tx.AddOutput(user[1].Address, 5) tx.SignInput(chainID, 0, user[1]) tx.SignBond(chainID, user[1]) if err := ExecTx(blockCache, tx, true, nil); err == nil { t.Fatal("Expected error") } else { fmt.Println(err) } //------------------------------ // one bonder with permission should pass bondAcc = blockCache.GetAccount(user[1].Address) bondAcc.Permissions.Base.Set(ptypes.Bond, true) blockCache.UpdateAccount(bondAcc) if err := ExecTx(blockCache, tx, true, nil); err != nil { t.Fatal("Unexpected error", err) } // reset state (we can only bond with an account once ..) genDoc = newBaseGenDoc(PermsAllFalse, PermsAllFalse) st = MakeGenesisState(stateDB, &genDoc) blockCache = NewBlockCache(st) bondAcc = blockCache.GetAccount(user[1].Address) bondAcc.Permissions.Base.Set(ptypes.Bond, true) blockCache.UpdateAccount(bondAcc) //------------------------------ // one bonder with permission and an input without send should fail tx, _ = types.NewBondTx(user[1].PubKey) if err := tx.AddInput(blockCache, user[2].PubKey, 5); err != nil { t.Fatal(err) } tx.AddOutput(user[1].Address, 5) tx.SignInput(chainID, 0, user[2]) tx.SignBond(chainID, user[1]) if err := ExecTx(blockCache, tx, true, nil); err == nil { t.Fatal("Expected error") } else { fmt.Println(err) } // reset state (we can only bond with an account once ..) genDoc = newBaseGenDoc(PermsAllFalse, PermsAllFalse) st = MakeGenesisState(stateDB, &genDoc) blockCache = NewBlockCache(st) bondAcc = blockCache.GetAccount(user[1].Address) bondAcc.Permissions.Base.Set(ptypes.Bond, true) blockCache.UpdateAccount(bondAcc) //------------------------------ // one bonder with permission and an input with send should pass sendAcc := blockCache.GetAccount(user[2].Address) sendAcc.Permissions.Base.Set(ptypes.Send, true) blockCache.UpdateAccount(sendAcc) tx, _ = types.NewBondTx(user[1].PubKey) if err := tx.AddInput(blockCache, user[2].PubKey, 5); err != nil { t.Fatal(err) } tx.AddOutput(user[1].Address, 5) tx.SignInput(chainID, 0, user[2]) tx.SignBond(chainID, user[1]) if err := ExecTx(blockCache, tx, true, nil); err != nil { t.Fatal("Unexpected error", err) } // reset state (we can only bond with an account once ..) genDoc = newBaseGenDoc(PermsAllFalse, PermsAllFalse) st = MakeGenesisState(stateDB, &genDoc) blockCache = NewBlockCache(st) bondAcc = blockCache.GetAccount(user[1].Address) bondAcc.Permissions.Base.Set(ptypes.Bond, true) blockCache.UpdateAccount(bondAcc) //------------------------------ // one bonder with permission and an input with bond should pass sendAcc.Permissions.Base.Set(ptypes.Bond, true) blockCache.UpdateAccount(sendAcc) tx, _ = types.NewBondTx(user[1].PubKey) if err := tx.AddInput(blockCache, user[2].PubKey, 5); err != nil { t.Fatal(err) } tx.AddOutput(user[1].Address, 5) tx.SignInput(chainID, 0, user[2]) tx.SignBond(chainID, user[1]) if err := ExecTx(blockCache, tx, true, nil); err != nil { t.Fatal("Unexpected error", err) } // reset state (we can only bond with an account once ..) genDoc = newBaseGenDoc(PermsAllFalse, PermsAllFalse) st = MakeGenesisState(stateDB, &genDoc) blockCache = NewBlockCache(st) bondAcc = blockCache.GetAccount(user[1].Address) bondAcc.Permissions.Base.Set(ptypes.Bond, true) blockCache.UpdateAccount(bondAcc) //------------------------------ // one bonder with permission and an input from that bonder and an input without send or bond should fail tx, _ = types.NewBondTx(user[1].PubKey) if err := tx.AddInput(blockCache, user[1].PubKey, 5); err != nil { t.Fatal(err) } if err := tx.AddInput(blockCache, user[2].PubKey, 5); err != nil { t.Fatal(err) } tx.AddOutput(user[1].Address, 5) tx.SignInput(chainID, 0, user[1]) tx.SignInput(chainID, 1, user[2]) tx.SignBond(chainID, user[1]) if err := ExecTx(blockCache, tx, true, nil); err == nil { t.Fatal("Expected error") } }