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 }