summaryrefslogtreecommitdiff
path: root/data/transactions/logic/evalAppTxn_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'data/transactions/logic/evalAppTxn_test.go')
-rw-r--r--data/transactions/logic/evalAppTxn_test.go162
1 files changed, 154 insertions, 8 deletions
diff --git a/data/transactions/logic/evalAppTxn_test.go b/data/transactions/logic/evalAppTxn_test.go
index 693e1e82e..b24e10fc2 100644
--- a/data/transactions/logic/evalAppTxn_test.go
+++ b/data/transactions/logic/evalAppTxn_test.go
@@ -25,11 +25,18 @@ import (
"github.com/stretchr/testify/require"
)
-func TestActionTypes(t *testing.T) {
+func TestInnerTypesV5(t *testing.T) {
+ v5, _ := makeSampleEnvWithVersion(5)
+ // not alllowed in v5
+ testApp(t, "itxn_begin; byte \"keyreg\"; itxn_field Type; itxn_submit; int 1;", v5, "keyreg is not a valid Type for itxn_field")
+ testApp(t, "itxn_begin; int keyreg; itxn_field TypeEnum; itxn_submit; int 1;", v5, "keyreg is not a valid Type for itxn_field")
+}
+
+func TestCurrentInnerTypes(t *testing.T) {
ep, ledger := makeSampleEnv()
testApp(t, "itxn_submit; int 1;", ep, "itxn_submit without itxn_begin")
testApp(t, "int pay; itxn_field TypeEnum; itxn_submit; int 1;", ep, "itxn_field without itxn_begin")
- testApp(t, "itxn_begin; itxn_submit; int 1;", ep, "Invalid inner transaction type")
+ testApp(t, "itxn_begin; itxn_submit; int 1;", ep, "unknown tx type")
// bad type
testApp(t, "itxn_begin; byte \"pya\"; itxn_field Type; itxn_submit; int 1;", ep, "pya is not a valid Type")
// mixed up the int form for the byte form
@@ -37,11 +44,9 @@ func TestActionTypes(t *testing.T) {
// or vice versa
testApp(t, obfuscate("itxn_begin; byte \"pay\"; itxn_field TypeEnum; itxn_submit; int 1;"), ep, "not a uint64")
- // good types, not alllowed yet
- testApp(t, "itxn_begin; byte \"keyreg\"; itxn_field Type; itxn_submit; int 1;", ep, "keyreg is not a valid Type for itxn_field")
+ // good types, not allowed yet
testApp(t, "itxn_begin; byte \"appl\"; itxn_field Type; itxn_submit; int 1;", ep, "appl is not a valid Type for itxn_field")
// same, as enums
- testApp(t, "itxn_begin; int keyreg; itxn_field TypeEnum; itxn_submit; int 1;", ep, "keyreg is not a valid Type for itxn_field")
testApp(t, "itxn_begin; int appl; itxn_field TypeEnum; itxn_submit; int 1;", ep, "appl is not a valid Type for itxn_field")
testApp(t, "itxn_begin; int 42; itxn_field TypeEnum; itxn_submit; int 1;", ep, "42 is not a valid TypeEnum")
testApp(t, "itxn_begin; int 0; itxn_field TypeEnum; itxn_submit; int 1;", ep, "0 is not a valid TypeEnum")
@@ -58,6 +63,10 @@ func TestActionTypes(t *testing.T) {
testApp(t, "itxn_begin; int acfg; itxn_field TypeEnum; itxn_submit; int 1;", ep, "insufficient balance")
testApp(t, "itxn_begin; int afrz; itxn_field TypeEnum; itxn_submit; int 1;", ep, "insufficient balance")
+ // alllowed since v6
+ testApp(t, "itxn_begin; byte \"keyreg\"; itxn_field Type; itxn_submit; int 1;", ep, "insufficient balance")
+ testApp(t, "itxn_begin; int keyreg; itxn_field TypeEnum; itxn_submit; int 1;", ep, "insufficient balance")
+
// Establish 888 as the app id, and fund it.
ledger.NewApp(ep.Txn.Txn.Receiver, 888, basics.AppParams{})
ledger.NewAccount(basics.AppIndex(888).Address(), 200000)
@@ -220,6 +229,30 @@ func TestRekeyPay(t *testing.T) {
// See explanation in logicLedger's Perform()
}
+func TestRekeyBack(t *testing.T) {
+ payAndUnkey := `
+ itxn_begin
+ itxn_field Amount
+ itxn_field Receiver
+ itxn_field Sender
+ int pay
+ itxn_field TypeEnum
+ txn Sender
+ itxn_field RekeyTo
+ itxn_submit
+`
+
+ ep, ledger := makeSampleEnv()
+ ledger.NewApp(ep.Txn.Txn.Receiver, 888, basics.AppParams{})
+ testApp(t, "txn Sender; balance; int 0; ==;", ep)
+ testApp(t, "txn Sender; txn Accounts 1; int 100"+payAndUnkey, ep, "unauthorized")
+ ledger.NewAccount(ep.Txn.Txn.Sender, 120+3*ep.Proto.MinTxnFee)
+ ledger.Rekey(ep.Txn.Txn.Sender, basics.AppIndex(888).Address())
+ testApp(t, "txn Sender; txn Accounts 1; int 100"+payAndUnkey+"; int 1", ep)
+ // now rekeyed back to original
+ testApp(t, "txn Sender; txn Accounts 1; int 100"+payAndUnkey, ep, "unauthorized")
+}
+
func TestDefaultSender(t *testing.T) {
pay := `
itxn_begin
@@ -320,7 +353,7 @@ func TestExtraFields(t *testing.T) {
"non-zero fields for type axfer")
}
-func TestBadField(t *testing.T) {
+func TestBadFieldV5(t *testing.T) {
pay := `
itxn_begin
int 7; itxn_field AssetAmount;
@@ -334,12 +367,34 @@ func TestBadField(t *testing.T) {
itxn_submit
`
- ep, ledger := makeSampleEnv()
+ ep, ledger := makeSampleEnvWithVersion(5)
ledger.NewApp(ep.Txn.Txn.Receiver, 888, basics.AppParams{})
testApp(t, "global CurrentApplicationAddress; txn Accounts 1; int 100"+pay, ep,
"invalid itxn_field RekeyTo")
}
+func TestBadField(t *testing.T) {
+ pay := `
+ itxn_begin
+ int 7; itxn_field AssetAmount;
+ itxn_field Amount
+ itxn_field Receiver
+ itxn_field Sender
+ int pay
+ itxn_field TypeEnum
+ txn Receiver
+ itxn_field RekeyTo // ALLOWED, since v6
+ int 10
+ itxn_field FirstValid // NOT ALLOWED
+ itxn_submit
+`
+
+ ep, ledger := makeSampleEnv()
+ ledger.NewApp(ep.Txn.Txn.Receiver, 888, basics.AppParams{})
+ testApp(t, "global CurrentApplicationAddress; txn Accounts 1; int 100"+pay, ep,
+ "invalid itxn_field FirstValid")
+}
+
func TestNumInner(t *testing.T) {
pay := `
itxn_begin
@@ -360,7 +415,7 @@ func TestNumInner(t *testing.T) {
testApp(t, pay+pay+pay+";int 1", ep)
testApp(t, pay+pay+pay+pay+";int 1", ep)
// In the sample proto, MaxInnerTransactions = 4
- testApp(t, pay+pay+pay+pay+pay+";int 1", ep, "itxn_submit with MaxInnerTransactions")
+ testApp(t, pay+pay+pay+pay+pay+";int 1", ep, "too many inner transactions")
}
func TestAssetCreate(t *testing.T) {
@@ -434,3 +489,94 @@ func TestAssetFreeze(t *testing.T) {
require.NoError(t, err)
require.Equal(t, false, holding.Frozen)
}
+
+func TestFieldSetting(t *testing.T) {
+ ep, ledger := makeSampleEnv()
+ ledger.NewApp(ep.Txn.Txn.Receiver, 888, basics.AppParams{})
+ ledger.NewAccount(ledger.ApplicationID().Address(), 10*defaultEvalProto().MinTxnFee)
+ testApp(t, "itxn_begin; int 500; bzero; itxn_field Note; int 1", ep)
+ testApp(t, "itxn_begin; int 501; bzero; itxn_field Note; int 1", ep,
+ "Note may not exceed")
+
+ testApp(t, "itxn_begin; int 32; bzero; itxn_field VotePK; int 1", ep)
+ testApp(t, "itxn_begin; int 31; bzero; itxn_field VotePK; int 1", ep,
+ "VotePK must be 32")
+
+ testApp(t, "itxn_begin; int 32; bzero; itxn_field SelectionPK; int 1", ep)
+ testApp(t, "itxn_begin; int 33; bzero; itxn_field SelectionPK; int 1", ep,
+ "SelectionPK must be 32")
+
+ testApp(t, "itxn_begin; int 32; bzero; itxn_field RekeyTo; int 1", ep)
+ testApp(t, "itxn_begin; int 31; bzero; itxn_field RekeyTo; int 1", ep,
+ "not an address")
+
+ testApp(t, "itxn_begin; int 6; bzero; itxn_field ConfigAssetUnitName; int 1", ep)
+ testApp(t, "itxn_begin; int 7; bzero; itxn_field ConfigAssetUnitName; int 1", ep,
+ "value is too long")
+
+ testApp(t, "itxn_begin; int 12; bzero; itxn_field ConfigAssetName; int 1", ep)
+ testApp(t, "itxn_begin; int 13; bzero; itxn_field ConfigAssetName; int 1", ep,
+ "value is too long")
+}
+
+func TestInnerGroup(t *testing.T) {
+ ep, ledger := makeSampleEnv()
+ ledger.NewApp(ep.Txn.Txn.Receiver, 888, basics.AppParams{})
+ // Need both fees and both payments
+ ledger.NewAccount(ledger.ApplicationID().Address(), 999+2*defaultEvalProto().MinTxnFee)
+ pay := `
+int pay; itxn_field TypeEnum;
+int 500; itxn_field Amount;
+txn Sender; itxn_field Receiver;
+`
+ testApp(t, "itxn_begin"+pay+"itxn_next"+pay+"itxn_submit; int 1", ep,
+ "insufficient balance")
+
+ // NewAccount overwrites the existing balance
+ ledger.NewAccount(ledger.ApplicationID().Address(), 1000+2*defaultEvalProto().MinTxnFee)
+ testApp(t, "itxn_begin"+pay+"itxn_next"+pay+"itxn_submit; int 1", ep)
+}
+
+func TestInnerFeePooling(t *testing.T) {
+ ep, ledger := makeSampleEnv()
+ ledger.NewApp(ep.Txn.Txn.Receiver, 888, basics.AppParams{})
+ ledger.NewAccount(ledger.ApplicationID().Address(), 50_000)
+ pay := `
+int pay; itxn_field TypeEnum;
+int 500; itxn_field Amount;
+txn Sender; itxn_field Receiver;
+`
+ // Force the first fee to 3, but the second will default to 2*fee-3 = 2002-3
+ testApp(t, "itxn_begin"+
+ pay+
+ "int 3; itxn_field Fee;"+
+ "itxn_next"+
+ pay+
+ "itxn_submit; itxn Fee; int 1999; ==", ep)
+
+ // Same first, but force the second too low
+ testApp(t, "itxn_begin"+
+ pay+
+ "int 3; itxn_field Fee;"+
+ "itxn_next"+
+ pay+
+ "int 1998; itxn_field Fee;"+
+ "itxn_submit; int 1", ep, "fee too small")
+
+ // Overpay in first itxn, the second will default to less
+ testApp(t, "itxn_begin"+
+ pay+
+ "int 2000; itxn_field Fee;"+
+ "itxn_next"+
+ pay+
+ "itxn_submit; itxn Fee; int 2; ==", ep)
+
+ // Same first, but force the second too low
+ testApp(t, "itxn_begin"+
+ pay+
+ "int 2000; itxn_field Fee;"+
+ "itxn_next"+
+ pay+
+ "int 1; itxn_field Fee;"+
+ "itxn_submit; itxn Fee; int 1", ep, "fee too small")
+}