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 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) } }