github.com/algorand/go-algorand-sdk@v1.24.0/logic/logic_test.go (about)

     1  package logic
     2  
     3  import (
     4  	"encoding/hex"
     5  	"strings"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/require"
     9  )
    10  
    11  func TestCheckProgram(t *testing.T) {
    12  	program := []byte{1, 32, 1, 1, 34} // int 1
    13  	var args [][]byte
    14  	err := CheckProgram(program, args)
    15  	require.NoError(t, err)
    16  
    17  	args = make([][]byte, 1)
    18  	args[0] = []byte(strings.Repeat("a", 10))
    19  	err = CheckProgram(program, args)
    20  	require.NoError(t, err)
    21  
    22  	// too long arg
    23  	args[0] = []byte(strings.Repeat("a", 1000))
    24  	err = CheckProgram(program, args)
    25  	require.Error(t, err)
    26  
    27  	program = append(program, []byte(strings.Repeat("\x22", 10))...)
    28  	args[0] = []byte(strings.Repeat("a", 10))
    29  	err = CheckProgram(program, args)
    30  	require.NoError(t, err)
    31  
    32  	// too long program
    33  	program = append(program, []byte(strings.Repeat("\x22", 1000))...)
    34  	args[0] = []byte(strings.Repeat("a", 10))
    35  	err = CheckProgram(program, args)
    36  	require.EqualError(t, err, "program too long")
    37  
    38  	// invalid opcode
    39  	program = []byte{1, 32, 1, 1, 34} // int 1
    40  	program[4] = 255
    41  	args[0] = []byte(strings.Repeat("a", 10))
    42  	err = CheckProgram(program, args)
    43  	require.EqualError(t, err, "invalid instruction")
    44  
    45  	// check single keccak256 and 10x keccak256 work
    46  	program = []byte{0x01, 0x26, 0x01, 0x01, 0x01, 0x28, 0x02} // byte 0x01 + keccak256
    47  	err = CheckProgram(program, args)
    48  	require.NoError(t, err)
    49  
    50  	program = append(program, []byte(strings.Repeat("\x02", 10))...) // append 10x keccak256
    51  	err = CheckProgram(program, args)
    52  	require.NoError(t, err)
    53  
    54  	// check 800x keccak256 fail for v3 and below
    55  	versions := []byte{0x1, 0x2, 0x3}
    56  	program = append(program, []byte(strings.Repeat("\x02", 800))...) // append 800x keccak256
    57  	for _, v := range versions {
    58  		program[0] = v
    59  		err = CheckProgram(program, args)
    60  		require.EqualError(t, err, "program too costly for version < 4. consider using v4.")
    61  	}
    62  
    63  	// check 800x keccak256 ok for v4 and above
    64  	versions = []byte{0x4}
    65  	for _, v := range versions {
    66  		program[0] = v
    67  		err = CheckProgram(program, args)
    68  		require.NoError(t, err)
    69  	}
    70  }
    71  
    72  func TestCheckProgramV2(t *testing.T) {
    73  	// check program v2 opcodes
    74  	require.True(t, spec.EvalMaxVersion >= 2)
    75  	require.True(t, spec.LogicSigVersion >= 2)
    76  
    77  	args := make([][]byte, 0)
    78  
    79  	// balance
    80  	program := []byte{0x02, 0x20, 0x01, 0x00, 0x22, 0x60} // int 0; balance
    81  	err := CheckProgram(program, args)
    82  	require.NoError(t, err)
    83  
    84  	// app_opted_in
    85  	program = []byte{0x02, 0x20, 0x01, 0x00, 0x22, 0x22, 0x61} // int 0; int 0; app_opted_in
    86  	err = CheckProgram(program, args)
    87  	require.NoError(t, err)
    88  
    89  	// asset_holding_get
    90  	program = []byte{0x02, 0x20, 0x01, 0x00, 0x22, 0x70, 0x00} // int 0; int 0; asset_holding_get Balance
    91  	err = CheckProgram(program, args)
    92  	require.NoError(t, err)
    93  }
    94  
    95  func TestCheckProgramV3(t *testing.T) {
    96  	// check program v3 opcodes
    97  	require.True(t, spec.EvalMaxVersion >= 3)
    98  	require.True(t, spec.LogicSigVersion >= 3)
    99  
   100  	args := make([][]byte, 0)
   101  
   102  	// min_balance
   103  	program := []byte{0x03, 0x20, 0x01, 0x00, 0x22, 0x78} // int 0; min_balance
   104  	err := CheckProgram(program, args)
   105  	require.NoError(t, err)
   106  
   107  	// pushbytes
   108  	program = []byte{0x03, 0x20, 0x01, 0x00, 0x22, 0x80, 0x02, 0x68, 0x69, 0x48} // int 0; pushbytes "hi"; pop
   109  	err = CheckProgram(program, args)
   110  	require.NoError(t, err)
   111  
   112  	// pushint
   113  	program = []byte{0x03, 0x20, 0x01, 0x00, 0x22, 0x81, 0x01, 0x48} // int 0; pushint 1; pop
   114  	err = CheckProgram(program, args)
   115  	require.NoError(t, err)
   116  
   117  	// swap
   118  	program = []byte{0x03, 0x20, 0x02, 0x00, 0x01, 0x22, 0x23, 0x4c, 0x48} // int 0; int 1; swap; pop
   119  	err = CheckProgram(program, args)
   120  	require.NoError(t, err)
   121  }
   122  
   123  func TestCheckProgramV4(t *testing.T) {
   124  	// check program v4 opcodes
   125  	require.True(t, spec.EvalMaxVersion >= 4)
   126  
   127  	args := make([][]byte, 0)
   128  
   129  	// divmodw
   130  	program := []byte{0x04, 0x20, 0x03, 0x01, 0x00, 0x02, 0x22, 0x81, 0xd0, 0x0f, 0x23, 0x24, 0x1f} // int 1; pushint 2000; int 0; int 2; divmodw
   131  	err := CheckProgram(program, args)
   132  	require.NoError(t, err)
   133  
   134  	// gloads i
   135  	program = []byte{0x04, 0x20, 0x01, 0x00, 0x22, 0x3b, 0x00} // int 0; gloads 0
   136  	err = CheckProgram(program, args)
   137  	require.NoError(t, err)
   138  
   139  	// callsub
   140  	program = []byte{0x04, 0x20, 0x02, 0x01, 0x02, 0x22, 0x88, 0x00, 0x02, 0x23, 0x12, 0x49} // int 1; callsub double; int 2; ==; double: dup;
   141  	err = CheckProgram(program, args)
   142  	require.NoError(t, err)
   143  
   144  	// b>=
   145  	program = []byte{0x04, 0x26, 0x02, 0x01, 0x11, 0x01, 0x10, 0x28, 0x29, 0xa7} // byte 0x11; byte 0x10; b>=
   146  	err = CheckProgram(program, args)
   147  	require.NoError(t, err)
   148  
   149  	// b^
   150  	program = []byte{0x04, 0x26, 0x03, 0x01, 0x11, 0x01, 0x10, 0x01, 0x01, 0x28, 0x29, 0xad, 0x2a, 0x12} // byte 0x11; byte 0x10; b^; byte 0x01; ==
   151  	err = CheckProgram(program, args)
   152  	require.NoError(t, err)
   153  
   154  	// callsub, retsub.
   155  	program = []byte{0x04, 0x20, 0x02, 0x01, 0x02, 0x22, 0x88, 0x00, 0x03, 0x23, 0x12, 0x43, 0x49, 0x08, 0x89} // int 1; callsub double; int 2; ==; return; double: dup; +; retsub;
   156  	err = CheckProgram(program, args)
   157  	require.NoError(t, err)
   158  
   159  	// loop
   160  	program = []byte{0x04, 0x20, 0x04, 0x01, 0x02, 0x0a, 0x10, 0x22, 0x23, 0x0b, 0x49, 0x24, 0x0c, 0x40, 0xff, 0xf8, 0x25, 0x12} // int 1; loop: int 2; *; dup; int 10; <; bnz loop; int 16; ==
   161  	err = CheckProgram(program, args)
   162  	require.NoError(t, err)
   163  }
   164  
   165  func TestCheckProgramV5(t *testing.T) {
   166  	// check program v5 opcodes
   167  	require.True(t, spec.EvalMaxVersion >= 5)
   168  
   169  	args := make([][]byte, 0)
   170  
   171  	// itxn ops
   172  	program, err := hex.DecodeString("052001c0843db18101b21022b2083100b207b3b4082212")
   173  	// itxn_begin; int pay; itxn_field TypeEnum; int 1000000; itxn_field Amount; txn Sender; itxn_field Receiver; itxn_submit; itxn Amount; int 1000000; ==
   174  	require.NoError(t, err)
   175  	err = CheckProgram(program, args)
   176  	require.NoError(t, err)
   177  
   178  	// ECDSA ops
   179  	program, err = hex.DecodeString("058008746573746461746103802079bfa8245aeac0e714b7bd2b3252d03979e5e7a43cb039715a5f8109a7dd9ba180200753d317e54350d1d102289afbde3002add4529f10b9f7d3d223843985de62e0802103abfb5e6e331fb871e423f354e2bd78a384ef7cb07ac8bbf27d2dd1eca00e73c106000500")
   180  	// byte "testdata"; sha512_256; byte 0x79bfa8245aeac0e714b7bd2b3252d03979e5e7a43cb039715a5f8109a7dd9ba1; byte 0x0753d317e54350d1d102289afbde3002add4529f10b9f7d3d223843985de62e0; byte 0x03abfb5e6e331fb871e423f354e2bd78a384ef7cb07ac8bbf27d2dd1eca00e73c1; ecdsa_pk_decompress Secp256k1; ecdsa_verify Secp256k1
   181  	require.NoError(t, err)
   182  	err = CheckProgram(program, args)
   183  	require.NoError(t, err)
   184  
   185  	// cover, uncover, log
   186  	program, err = hex.DecodeString("058001618001628001634e024f025050b08101")
   187  	// byte "a"; byte "b"; byte "c"; cover 2; uncover 2; concat; concat; log; int 1
   188  	require.NoError(t, err)
   189  	err = CheckProgram(program, args)
   190  	require.NoError(t, err)
   191  }
   192  
   193  func TestCheckProgramV6(t *testing.T) {
   194  	// check program v6 opcodes
   195  	require.True(t, spec.EvalMaxVersion >= 6)
   196  
   197  	args := make([][]byte, 0)
   198  
   199  	// bsqrt
   200  	program, err := hex.DecodeString("068001909680010ca8")
   201  	// byte 0x90; bsqrt; byte 0x0c; b==
   202  	require.NoError(t, err)
   203  	err = CheckProgram(program, args)
   204  	require.NoError(t, err)
   205  
   206  	// divw
   207  	program, err = hex.DecodeString("06810981ecffffffffffffffff01810a9781feffffffffffffffff0112")
   208  	// int 9; int 18446744073709551596; int 10; divw; int 18446744073709551614; ==
   209  	require.NoError(t, err)
   210  	err = CheckProgram(program, args)
   211  	require.NoError(t, err)
   212  
   213  	// txn fields
   214  	program, err = hex.DecodeString("06313f1581401233003e15810a1210")
   215  	// txn StateProofPK; len; int 64; ==; gtxn 0 LastLog; len; int 10; ==; &&
   216  	require.NoError(t, err)
   217  	err = CheckProgram(program, args)
   218  	require.NoError(t, err)
   219  }