summaryrefslogtreecommitdiff
path: root/cmd/tealdbg/local_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/tealdbg/local_test.go')
-rw-r--r--cmd/tealdbg/local_test.go332
1 files changed, 322 insertions, 10 deletions
diff --git a/cmd/tealdbg/local_test.go b/cmd/tealdbg/local_test.go
index d4d917a40..d78c402e8 100644
--- a/cmd/tealdbg/local_test.go
+++ b/cmd/tealdbg/local_test.go
@@ -18,6 +18,7 @@ package main
import (
"encoding/json"
+ "fmt"
"net/http"
"net/http/httptest"
"reflect"
@@ -226,14 +227,6 @@ func makeSampleBalanceRecord(addr basics.Address, assetIdx basics.AssetIndex, ap
return br
}
-func makeSampleSerializedBalanceRecord(addr basics.Address, toJSON bool) []byte {
- br := makeSampleBalanceRecord(addr, 50, 100)
- if toJSON {
- return protocol.EncodeJSON(&br)
- }
- return protocol.EncodeMsgp(&br)
-}
-
func TestBalanceJSONInput(t *testing.T) {
partitiontest.PartitionTest(t)
a := require.New(t)
@@ -325,7 +318,7 @@ func TestDebugEnvironment(t *testing.T) {
Txn: transactions.Transaction{
Header: transactions.Header{
Sender: sender,
- Fee: basics.MicroAlgos{Raw: 100},
+ Fee: basics.MicroAlgos{Raw: 1000},
Note: []byte{1, 2, 3},
},
ApplicationCallTxnFields: transactions.ApplicationCallTxnFields{
@@ -1087,7 +1080,7 @@ func TestDebugTxSubmit(t *testing.T) {
Type: protocol.ApplicationCallTx,
Header: transactions.Header{
Sender: sender,
- Fee: basics.MicroAlgos{Raw: 100},
+ Fee: basics.MicroAlgos{Raw: 1000},
Note: []byte{1, 2, 3},
},
ApplicationCallTxnFields: transactions.ApplicationCallTxnFields{
@@ -1138,3 +1131,322 @@ int 1`
a.NoError(err)
a.True(pass)
}
+
+func TestDebugFeePooling(t *testing.T) {
+ partitiontest.PartitionTest(t)
+ a := require.New(t)
+
+ sender, err := basics.UnmarshalChecksumAddress("47YPQTIGQEO7T4Y4RWDYWEKV6RTR2UNBQXBABEEGM72ESWDQNCQ52OPASU")
+ a.NoError(err)
+
+ source := `#pragma version 5
+itxn_begin
+int pay
+itxn_field TypeEnum
+int 0
+itxn_field Amount
+txn Sender
+itxn_field Receiver
+itxn_submit
+int 1`
+
+ ops, err := logic.AssembleString(source)
+ a.NoError(err)
+ prog := ops.Program
+
+ stxn := transactions.SignedTxn{
+ Txn: transactions.Transaction{
+ Type: protocol.ApplicationCallTx,
+ Header: transactions.Header{
+ Sender: sender,
+ Note: []byte{1, 2, 3},
+ },
+ ApplicationCallTxnFields: transactions.ApplicationCallTxnFields{
+ ApplicationID: 0,
+ ApprovalProgram: prog,
+ ClearStateProgram: prog,
+ },
+ },
+ }
+
+ appIdx := basics.AppIndex(1)
+ br := basics.BalanceRecord{
+ Addr: sender,
+ AccountData: basics.AccountData{
+ MicroAlgos: basics.MicroAlgos{Raw: 5000000},
+ AppParams: map[basics.AppIndex]basics.AppParams{
+ appIdx: {
+ ApprovalProgram: prog,
+ ClearStateProgram: prog,
+ },
+ },
+ },
+ }
+ balanceBlob := protocol.EncodeMsgp(&br)
+
+ // two testcase: success with enough fees and fail otherwise
+ var tests = []struct {
+ pass bool
+ fee uint64
+ }{
+ {true, 2000},
+ {false, 1500},
+ }
+ for _, test := range tests {
+ t.Run(fmt.Sprintf("fee=%d", test.fee), func(t *testing.T) {
+
+ stxn.Txn.Fee = basics.MicroAlgos{Raw: test.fee}
+ encoded := protocol.EncodeJSON(&stxn)
+
+ ds := DebugParams{
+ ProgramNames: []string{"test"},
+ BalanceBlob: balanceBlob,
+ TxnBlob: encoded,
+ Proto: string(protocol.ConsensusCurrentVersion),
+ Round: 222,
+ LatestTimestamp: 333,
+ GroupIndex: 0,
+ RunMode: "application",
+ AppID: uint64(appIdx),
+ }
+
+ local := MakeLocalRunner(nil)
+ err = local.Setup(&ds)
+ a.NoError(err)
+
+ pass, err := local.Run()
+ if test.pass {
+ a.NoError(err)
+ a.True(pass)
+ } else {
+ a.Error(err)
+ a.False(pass)
+ }
+ })
+ }
+}
+
+func TestDebugCostPooling(t *testing.T) {
+ partitiontest.PartitionTest(t)
+ a := require.New(t)
+
+ sender, err := basics.UnmarshalChecksumAddress("47YPQTIGQEO7T4Y4RWDYWEKV6RTR2UNBQXBABEEGM72ESWDQNCQ52OPASU")
+ a.NoError(err)
+
+ // cost is 2000 (ecdsa_pk_recover) + 130 (keccak256) + 8 (rest opcodes)
+ // needs 4 app calls to pool together
+ source := `#pragma version 5
+byte "hello from ethereum" // msg
+keccak256
+int 0 // v
+byte 0x745e8f55ac6189ee89ed707c36694868e3903988fbf776c8096c45da2e60c638 // r
+byte 0x30c8e4a9b5d2eb53ddc6294587dd00bed8afe2c45dd72f6b4cf752e46d5ba681 // s
+ecdsa_pk_recover Secp256k1
+concat // convert public key X and Y to ethereum addr
+keccak256
+substring 12 32
+byte 0x5ce9454909639d2d17a3f753ce7d93fa0b9ab12e // addr
+==
+`
+ ops, err := logic.AssembleString(source)
+ a.NoError(err)
+ prog := ops.Program
+
+ ops, err = logic.AssembleString("#pragma version 2\nint 1")
+ a.NoError(err)
+ trivial := ops.Program
+
+ stxn := transactions.SignedTxn{
+ Txn: transactions.Transaction{
+ Type: protocol.ApplicationCallTx,
+ Header: transactions.Header{
+ Sender: sender,
+ Fee: basics.MicroAlgos{Raw: 1000},
+ Note: []byte{1, 2, 3},
+ },
+ ApplicationCallTxnFields: transactions.ApplicationCallTxnFields{
+ ApplicationID: 0,
+ ApprovalProgram: prog,
+ ClearStateProgram: trivial,
+ },
+ },
+ }
+
+ appIdx := basics.AppIndex(1)
+ trivialAppIdx := basics.AppIndex(2)
+ trivialStxn := transactions.SignedTxn{
+ Txn: transactions.Transaction{
+ Type: protocol.ApplicationCallTx,
+ Header: transactions.Header{
+ Sender: sender,
+ Fee: basics.MicroAlgos{Raw: 1000},
+ },
+ ApplicationCallTxnFields: transactions.ApplicationCallTxnFields{
+ ApplicationID: trivialAppIdx,
+ },
+ },
+ }
+
+ br := basics.BalanceRecord{
+ Addr: sender,
+ AccountData: basics.AccountData{
+ MicroAlgos: basics.MicroAlgos{Raw: 5000000},
+ AppParams: map[basics.AppIndex]basics.AppParams{
+ appIdx: {
+ ApprovalProgram: prog,
+ ClearStateProgram: trivial,
+ },
+ trivialAppIdx: {
+ ApprovalProgram: trivial,
+ ClearStateProgram: trivial,
+ },
+ },
+ },
+ }
+ balanceBlob := protocol.EncodeMsgp(&br)
+
+ var tests = []struct {
+ pass bool
+ additionalApps int
+ }{
+ {false, 2},
+ {true, 3},
+ }
+ for _, test := range tests {
+ t.Run(fmt.Sprintf("txn-count=%d", test.additionalApps+1), func(t *testing.T) {
+ txnBlob := protocol.EncodeMsgp(&stxn)
+ for i := 0; i < test.additionalApps; i++ {
+ val, err := getRandomAddress()
+ a.NoError(err)
+ trivialStxn.Txn.Note = val[:]
+ txnBlob = append(txnBlob, protocol.EncodeMsgp(&trivialStxn)...)
+ }
+
+ ds := DebugParams{
+ ProgramNames: []string{"test"},
+ BalanceBlob: balanceBlob,
+ TxnBlob: txnBlob,
+ Proto: string(protocol.ConsensusCurrentVersion),
+ Round: 222,
+ LatestTimestamp: 333,
+ GroupIndex: 0,
+ RunMode: "application",
+ AppID: uint64(appIdx),
+ }
+
+ local := MakeLocalRunner(nil)
+ err = local.Setup(&ds)
+ a.NoError(err)
+
+ pass, err := local.Run()
+ if test.pass {
+ a.NoError(err)
+ a.True(pass)
+ } else {
+ a.Error(err)
+ a.Contains(err.Error(), "dynamic cost budget exceeded")
+ a.False(pass)
+ }
+ })
+ }
+}
+
+func TestGroupTxnIdx(t *testing.T) {
+
+ partitiontest.PartitionTest(t)
+ a := require.New(t)
+
+ ddrBlob := `{
+ "accounts": [
+ {
+ "address": "FPVVJ7N42QRVP2OWBGZ3XPTQAZFQNBYHJGZ2CJFOATAQNWFA5NWB4MPWBQ",
+ "amount": 3999999999497000,
+ "amount-without-pending-rewards": 3999999999497000,
+ "created-apps": [
+ {
+ "id": 1,
+ "params": {
+ "approval-program": "BSABATEQIhJAABExEIEGEkAAByJAAAEAIkMiQ4EAQw==",
+ "clear-state-program": "BYEBQw==",
+ "creator": "FPVVJ7N42QRVP2OWBGZ3XPTQAZFQNBYHJGZ2CJFOATAQNWFA5NWB4MPWBQ"
+ }
+ }
+ ],
+ "pending-rewards": 0,
+ "rewards": 0,
+ "round": 2,
+ "status": "Online"
+ },
+ {
+ "address": "WCS6TVPJRBSARHLN2326LRU5BYVJZUKI2VJ53CAWKYYHDE455ZGKANWMGM",
+ "amount": 500000,
+ "amount-without-pending-rewards": 500000,
+ "pending-rewards": 0,
+ "rewards": 0,
+ "round": 2,
+ "status": "Offline"
+ }
+ ],
+ "apps": [
+ {
+ "id": 1,
+ "params": {
+ "approval-program": "BSABATEQIhJAABExEIEGEkAAByJAAAEAIkMiQ4EAQw==",
+ "clear-state-program": "BYEBQw==",
+ "creator": "FPVVJ7N42QRVP2OWBGZ3XPTQAZFQNBYHJGZ2CJFOATAQNWFA5NWB4MPWBQ"
+ }
+ }
+ ],
+ "latest-timestamp": 1634765269,
+ "protocol-version": "future",
+ "round": 2,
+ "sources": null,
+ "txns": [
+ {
+ "sig": "8Z/ECart3vFBSKp5sFuNRN4coliea4TE+xttZNn9E15DJ8GZ++kgtZKhG4Tiopv7r61Lqh8VBuyuTf9AC3uQBQ==",
+ "txn": {
+ "amt": 5000,
+ "fee": 1000,
+ "fv": 3,
+ "gen": "sandnet-v1",
+ "gh": "pjM5GFR9MpNkWIibcfqtu/a2OIZTBy/mSQc++sF1r0Q=",
+ "grp": "2ca4sSb5aGab0k065qIT3J3AcB5YWYezrRh6bLB0ve8=",
+ "lv": 1003,
+ "note": "V+GSPgDmLQo=",
+ "rcv": "WCS6TVPJRBSARHLN2326LRU5BYVJZUKI2VJ53CAWKYYHDE455ZGKANWMGM",
+ "snd": "FPVVJ7N42QRVP2OWBGZ3XPTQAZFQNBYHJGZ2CJFOATAQNWFA5NWB4MPWBQ",
+ "type": "pay"
+ }
+ },
+ {
+ "sig": "4/gj+6rllN/Uc55kAJ0BOKTzoUJKJ7gExE3vp7cr5vC9XVStx0QNZq1DFXLhpTZnTQAl3zOrGzIxfS5HOpSyCg==",
+ "txn": {
+ "apid": 1,
+ "fee": 1000,
+ "fv": 3,
+ "gh": "pjM5GFR9MpNkWIibcfqtu/a2OIZTBy/mSQc++sF1r0Q=",
+ "grp": "2ca4sSb5aGab0k065qIT3J3AcB5YWYezrRh6bLB0ve8=",
+ "lv": 1003,
+ "note": "+fl8jkXqyFc=",
+ "snd": "FPVVJ7N42QRVP2OWBGZ3XPTQAZFQNBYHJGZ2CJFOATAQNWFA5NWB4MPWBQ",
+ "type": "appl"
+ }
+ }
+ ]
+ }`
+
+ ds := DebugParams{
+ Proto: string(protocol.ConsensusCurrentVersion),
+ DdrBlob: []byte(ddrBlob),
+ GroupIndex: 0,
+ RunMode: "application",
+ }
+
+ local := MakeLocalRunner(nil)
+ err := local.Setup(&ds)
+ a.NoError(err)
+
+ pass, err := local.Run()
+ a.NoError(err)
+ a.True(pass)
+}