func TestSendPermission(t *testing.T) { stateDB := dbm.GetDB("state") genDoc := newBaseGenDoc(PermsAllFalse, PermsAllFalse) genDoc.Accounts[0].Permissions.Base.Set(ptypes.Send, true) // give the 0 account permission st := MakeGenesisState(stateDB, &genDoc) blockCache := NewBlockCache(st) // A single input, having the permission, should succeed tx := types.NewSendTx() if err := tx.AddInput(blockCache, user[0].PubKey, 5); err != nil { t.Fatal(err) } tx.AddOutput(user[1].Address, 5) tx.SignInput(chainID, 0, user[0]) if err := ExecTx(blockCache, tx, true, nil); err != nil { t.Fatal("Transaction failed", err) } // Two inputs, one with permission, one without, should fail tx = types.NewSendTx() if err := tx.AddInput(blockCache, user[0].PubKey, 5); err != nil { t.Fatal(err) } if err := tx.AddInput(blockCache, user[1].PubKey, 5); err != nil { t.Fatal(err) } tx.AddOutput(user[2].Address, 10) tx.SignInput(chainID, 0, user[0]) tx.SignInput(chainID, 1, user[1]) if err := ExecTx(blockCache, tx, true, nil); err == nil { t.Fatal("Expected error") } else { fmt.Println(err) } }
func makeDefaultSendTx(t *testing.T, typ string, addr []byte, amt int64) *types.SendTx { nonce := getNonce(t, typ, user[0].Address) tx := types.NewSendTx() tx.AddInputWithNonce(user[0].PubKey, amt, nonce+1) tx.AddOutput(addr, amt) return tx }
func newSendTx(t *testing.T, mempool *Mempool, from *acm.PrivAccount, to []byte, amt int64) types.Tx { tx := types.NewSendTx() tx.AddInput(mempool.GetCache(), from.PubKey, amt) tx.AddOutput(to, amt) tx.SignInput(config.GetString("chain_id"), 0, from) if err := mempool.AddTx(tx); err != nil { t.Fatal(err) } return tx }
func (this *transactor) Send(privKey, toAddress []byte, amount int64) (*Receipt, error) { var toAddr []byte if len(toAddress) == 0 { toAddr = nil } else if len(toAddress) != 20 { return nil, fmt.Errorf("To-address is not of the right length: %d\n", len(toAddress)) } else { toAddr = toAddress } if len(privKey) != 64 { return nil, fmt.Errorf("Private key is not of the right length: %d\n", len(privKey)) } pk := &[64]byte{} copy(pk[:], privKey) this.txMtx.Lock() defer this.txMtx.Unlock() pa := account.GenPrivAccountFromPrivKeyBytes(privKey) cache := this.mempoolReactor.Mempool.GetCache() acc := cache.GetAccount(pa.Address) var sequence int if acc == nil { sequence = 1 } else { sequence = acc.Sequence + 1 } tx := types.NewSendTx() txInput := &types.TxInput{ Address: pa.Address, Amount: amount, Sequence: sequence, PubKey: pa.PubKey, } tx.Inputs = append(tx.Inputs, txInput) txOutput := &types.TxOutput{toAddr, amount} tx.Outputs = append(tx.Outputs, txOutput) // Got ourselves a tx. txS, errS := this.SignTx(tx, []*account.PrivAccount{pa}) if errS != nil { return nil, errS } return this.BroadcastTx(txS) }
func TestTxSequence(t *testing.T) { state, privAccounts, _ := RandGenesisState(3, true, 1000, 1, true, 1000) acc0 := state.GetAccount(privAccounts[0].PubKey.Address()) acc0PubKey := privAccounts[0].PubKey acc1 := state.GetAccount(privAccounts[1].PubKey.Address()) // Test a variety of sequence numbers for the tx. // The tx should only pass when i == 1. for i := -1; i < 3; i++ { sequence := acc0.Sequence + i tx := types.NewSendTx() tx.AddInputWithNonce(acc0PubKey, 1, sequence) tx.AddOutput(acc1.Address, 1) tx.Inputs[0].Signature = privAccounts[0].Sign(state.ChainID, tx) stateCopy := state.Copy() err := execTxWithState(stateCopy, tx, true) if i == 1 { // Sequence is good. if err != nil { t.Errorf("Expected good sequence to pass: %v", err) } // Check acc.Sequence. newAcc0 := stateCopy.GetAccount(acc0.Address) if newAcc0.Sequence != sequence { t.Errorf("Expected account sequence to change to %v, got %v", sequence, newAcc0.Sequence) } } else { // Sequence is bad. if err == nil { t.Errorf("Expected bad sequence to fail") } // Check acc.Sequence. (shouldn't have changed) newAcc0 := stateCopy.GetAccount(acc0.Address) if newAcc0.Sequence != acc0.Sequence { t.Errorf("Expected account sequence to not change from %v, got %v", acc0.Sequence, newAcc0.Sequence) } } } }
func Send(nodeAddr, signAddr, pubkey, addr, toAddr, amtS, nonceS string) (*types.SendTx, error) { pub, amt, nonce, err := checkCommon(nodeAddr, signAddr, pubkey, addr, amtS, nonceS) if err != nil { return nil, err } if toAddr == "" { return nil, fmt.Errorf("destination address must be given with --to flag") } toAddrBytes, err := hex.DecodeString(toAddr) if err != nil { return nil, fmt.Errorf("toAddr is bad hex: %v", err) } tx := types.NewSendTx() tx.AddInputWithNonce(pub, amt, int(nonce)) tx.AddOutput(toAddrBytes, amt) return tx, nil }
func TestCreateAccountPermission(t *testing.T) { stateDB := dbm.GetDB("state") genDoc := newBaseGenDoc(PermsAllFalse, PermsAllFalse) genDoc.Accounts[0].Permissions.Base.Set(ptypes.Send, true) // give the 0 account permission genDoc.Accounts[1].Permissions.Base.Set(ptypes.Send, true) // give the 0 account permission genDoc.Accounts[0].Permissions.Base.Set(ptypes.CreateAccount, true) // give the 0 account permission st := MakeGenesisState(stateDB, &genDoc) blockCache := NewBlockCache(st) //---------------------------------------------------------- // SendTx to unknown account // A single input, having the permission, should succeed tx := types.NewSendTx() if err := tx.AddInput(blockCache, user[0].PubKey, 5); err != nil { t.Fatal(err) } tx.AddOutput(user[6].Address, 5) tx.SignInput(chainID, 0, user[0]) if err := ExecTx(blockCache, tx, true, nil); err != nil { t.Fatal("Transaction failed", err) } // Two inputs, both with send, one with create, one without, should fail tx = types.NewSendTx() if err := tx.AddInput(blockCache, user[0].PubKey, 5); err != nil { t.Fatal(err) } if err := tx.AddInput(blockCache, user[1].PubKey, 5); err != nil { t.Fatal(err) } tx.AddOutput(user[7].Address, 10) tx.SignInput(chainID, 0, user[0]) tx.SignInput(chainID, 1, user[1]) if err := ExecTx(blockCache, tx, true, nil); err == nil { t.Fatal("Expected error") } else { fmt.Println(err) } // Two inputs, both with send, one with create, one without, two ouputs (one known, one unknown) should fail tx = types.NewSendTx() if err := tx.AddInput(blockCache, user[0].PubKey, 5); err != nil { t.Fatal(err) } if err := tx.AddInput(blockCache, user[1].PubKey, 5); err != nil { t.Fatal(err) } tx.AddOutput(user[7].Address, 4) tx.AddOutput(user[4].Address, 6) tx.SignInput(chainID, 0, user[0]) tx.SignInput(chainID, 1, user[1]) if err := ExecTx(blockCache, tx, true, nil); err == nil { t.Fatal("Expected error") } else { fmt.Println(err) } // Two inputs, both with send, both with create, should pass acc := blockCache.GetAccount(user[1].Address) acc.Permissions.Base.Set(ptypes.CreateAccount, true) blockCache.UpdateAccount(acc) tx = types.NewSendTx() if err := tx.AddInput(blockCache, user[0].PubKey, 5); err != nil { t.Fatal(err) } if err := tx.AddInput(blockCache, user[1].PubKey, 5); err != nil { t.Fatal(err) } tx.AddOutput(user[7].Address, 10) tx.SignInput(chainID, 0, user[0]) tx.SignInput(chainID, 1, user[1]) if err := ExecTx(blockCache, tx, true, nil); err != nil { t.Fatal("Unexpected error", err) } // Two inputs, both with send, both with create, two outputs (one known, one unknown) should pass tx = types.NewSendTx() if err := tx.AddInput(blockCache, user[0].PubKey, 5); err != nil { t.Fatal(err) } if err := tx.AddInput(blockCache, user[1].PubKey, 5); err != nil { t.Fatal(err) } tx.AddOutput(user[7].Address, 7) tx.AddOutput(user[4].Address, 3) tx.SignInput(chainID, 0, user[0]) tx.SignInput(chainID, 1, user[1]) if err := ExecTx(blockCache, tx, true, nil); err != nil { t.Fatal("Unexpected error", err) } //---------------------------------------------------------- // CALL to unknown account acc = blockCache.GetAccount(user[0].Address) acc.Permissions.Base.Set(ptypes.Call, true) blockCache.UpdateAccount(acc) // call to contract that calls unknown account - without create_account perm // create contract that calls the simple contract contractCode := callContractCode(user[9].Address) caller1ContractAddr := NewContractAddress(user[4].Address, 101) caller1Acc := &acm.Account{ Address: caller1ContractAddr, Balance: 0, Code: contractCode, Sequence: 0, StorageRoot: Zero256.Bytes(), Permissions: ptypes.ZeroAccountPermissions, } blockCache.UpdateAccount(caller1Acc) // A single input, having the permission, but the contract doesn't have permission txCall, _ := types.NewCallTx(blockCache, user[0].PubKey, caller1ContractAddr, nil, 100, 10000, 100) txCall.Sign(chainID, user[0]) // we need to subscribe to the Call event to detect the exception _, exception := execTxWaitEvent(t, blockCache, txCall, types.EventStringAccCall(caller1ContractAddr)) // if exception == "" { t.Fatal("Expected exception") } // NOTE: for a contract to be able to CreateAccount, it must be able to call // NOTE: for a user to be able to CreateAccount, it must be able to send! caller1Acc.Permissions.Base.Set(ptypes.CreateAccount, true) caller1Acc.Permissions.Base.Set(ptypes.Call, true) blockCache.UpdateAccount(caller1Acc) // A single input, having the permission, but the contract doesn't have permission txCall, _ = types.NewCallTx(blockCache, user[0].PubKey, caller1ContractAddr, nil, 100, 10000, 100) txCall.Sign(chainID, user[0]) // we need to subscribe to the Call event to detect the exception _, exception = execTxWaitEvent(t, blockCache, txCall, types.EventStringAccCall(caller1ContractAddr)) // if exception != "" { t.Fatal("Unexpected exception", exception) } }
func TestSendFails(t *testing.T) { stateDB := dbm.GetDB("state") genDoc := newBaseGenDoc(PermsAllFalse, PermsAllFalse) genDoc.Accounts[1].Permissions.Base.Set(ptypes.Send, true) genDoc.Accounts[2].Permissions.Base.Set(ptypes.Call, true) genDoc.Accounts[3].Permissions.Base.Set(ptypes.CreateContract, true) st := MakeGenesisState(stateDB, &genDoc) blockCache := NewBlockCache(st) //------------------- // send txs // simple send tx should fail tx := types.NewSendTx() if err := tx.AddInput(blockCache, user[0].PubKey, 5); err != nil { t.Fatal(err) } tx.AddOutput(user[1].Address, 5) tx.SignInput(chainID, 0, user[0]) if err := ExecTx(blockCache, tx, true, nil); err == nil { t.Fatal("Expected error") } else { fmt.Println(err) } // simple send tx with call perm should fail tx = types.NewSendTx() if err := tx.AddInput(blockCache, user[2].PubKey, 5); err != nil { t.Fatal(err) } tx.AddOutput(user[4].Address, 5) tx.SignInput(chainID, 0, user[2]) if err := ExecTx(blockCache, tx, true, nil); err == nil { t.Fatal("Expected error") } else { fmt.Println(err) } // simple send tx with create perm should fail tx = types.NewSendTx() if err := tx.AddInput(blockCache, user[3].PubKey, 5); err != nil { t.Fatal(err) } tx.AddOutput(user[4].Address, 5) tx.SignInput(chainID, 0, user[3]) if err := ExecTx(blockCache, tx, true, nil); err == nil { t.Fatal("Expected error") } else { fmt.Println(err) } // simple send tx to unknown account without create_account perm should fail acc := blockCache.GetAccount(user[3].Address) acc.Permissions.Base.Set(ptypes.Send, true) blockCache.UpdateAccount(acc) tx = types.NewSendTx() if err := tx.AddInput(blockCache, user[3].PubKey, 5); err != nil { t.Fatal(err) } tx.AddOutput(user[6].Address, 5) tx.SignInput(chainID, 0, user[3]) if err := ExecTx(blockCache, tx, true, nil); err == nil { t.Fatal("Expected error") } else { fmt.Println(err) } }