Last active
February 8, 2025 23:03
-
-
Save franciscoaguirre/4b00b23cb08f1e1f44b9c0c3edf3fc14 to your computer and use it in GitHub Desktop.
JAM Test Service
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| %stack_size = 4096 | |
| // Can't test the "designate" host function because | |
| // we'd need 336 * 1023 zeroes here for correct decoding. | |
| %rw_data_size = 12 | |
| %rw_data = 00 00 00 00 00 00 00 00 00 00 00 00 | |
| // ===== JAM entrypoints ===== | |
| jump @is_authorized | |
| fallthrough | |
| fallthrough | |
| fallthrough | |
| jump @refine | |
| fallthrough | |
| fallthrough | |
| fallthrough | |
| jump @accumulate | |
| fallthrough | |
| fallthrough | |
| fallthrough | |
| jump @on_transfer | |
| fallthrough | |
| fallthrough | |
| fallthrough | |
| // ===== For testing host functions ===== | |
| jump @gas_host_fn | |
| jump @lookup_host_fn | |
| jump @read_host_fn | |
| jump @write_host_fn | |
| jump @info_host_fn | |
| jump @bless_host_fn | |
| jump @assign_host_fn | |
| jump @designate_host_fn | |
| jump @checkpoint_host_fn | |
| jump @new_host_fn | |
| jump @upgrade_host_fn | |
| jump @transfer_host_fn | |
| jump @eject_host_fn | |
| jump @query_host_fn | |
| jump @solicit_host_fn | |
| jump @forget_host_fn | |
| jump @yield_host_fn | |
| jump @historical_lookup_host_fn | |
| jump @fetch_host_fn | |
| jump @export_host_fn | |
| jump @machine_host_fn | |
| jump @peek_host_fn | |
| jump @poke_host_fn | |
| jump @zero_host_fn | |
| jump @void_host_fn | |
| jump @invoke_host_fn | |
| pub @is_authorized: | |
| a1 = 0 | |
| trap | |
| pub @refine: | |
| a1 = 0 | |
| trap | |
| pub @accumulate: | |
| // Counter | |
| a1 = 0 | |
| // Accumulator | |
| a2 = 0 | |
| @target: | |
| // Fetch | |
| a3 = u8 [a1 + 0xfeff0003] | |
| // Accumulate | |
| a2 = a2 + a3 | |
| // Increase counter | |
| a1 = a1 + 1 | |
| // Condition | |
| jump @target if a1 <u 4 | |
| // Change state | |
| u8 [0xfeff0010] = 3 | |
| a1 = 1224 | |
| a2 = 2335 | |
| a3 = 3446 | |
| a4 = 4557 | |
| // 'write' host function | |
| ecalli 3 | |
| // Return | |
| a0 = a2 | |
| trap | |
| pub @on_transfer: | |
| a1 = 0 | |
| trap | |
| // Tests the "gas" host function. | |
| pub @gas_host_fn: | |
| // Call "gas" host function. | |
| ecalli 0 | |
| trap | |
| // Tests the "lookup" host function. | |
| pub @lookup_host_fn: | |
| // Call "lookup" host function. | |
| ecalli 1 | |
| trap | |
| // Tests the "read" host function. | |
| pub @read_host_fn: | |
| // Call "read" host function. | |
| ecalli 2 | |
| trap | |
| // Tests the "write" host function. | |
| pub @write_host_fn: | |
| // Write "key" in read-write memory. | |
| u8 [0x00020000] = 107 | |
| u8 [0x00020001] = 101 | |
| u8 [0x00020002] = 121 | |
| // Pointer and length to "key". | |
| a0 = 0x00020000 | |
| a1 = 3 | |
| // Write value in read-write memory. Just some number. | |
| u32 [0x00020003] = 1224 | |
| a2 = 0x00020003 | |
| a3 = 4 | |
| // Call "write" host function. | |
| ecalli 3 | |
| trap | |
| // Tests the "info" host function. | |
| pub @info_host_fn: | |
| // Set service index in w7. | |
| a0 = 0 | |
| // Set the memory address. | |
| a1 = 0x00020004 | |
| // Call "info" host function. | |
| ecalli 4 | |
| // Now we can get the data from memory and put it in storage. | |
| // Key for the data | |
| u8 [0x00020000] = 105 | |
| u8 [0x00020001] = 110 | |
| u8 [0x00020002] = 102 | |
| u8 [0x00020003] = 111 | |
| // Pointer and length to the key | |
| a0 = 0x00020000 | |
| a1 = 4 | |
| // Pointer and length to the data. | |
| a2 = 0x00020004 | |
| a3 = 76 | |
| // Call "write" host function. | |
| ecalli 3 | |
| trap | |
| // Tests the "bless" host function. | |
| pub @bless_host_fn: | |
| // Manager | |
| a0 = 1 | |
| // Authorizers | |
| a1 = 2 | |
| // Validators | |
| a2 = 3 | |
| // Load service id 10 in memory. | |
| u32 [0x00020000] = 10 | |
| // Give it some free amount of gas. | |
| u32 [0x00020004] = 1000 | |
| u32 [0x00020008] = 0 | |
| // Address for extra services | |
| a3 = 0x00020000 | |
| // Number of extra services | |
| a4 = 1 | |
| // Call the "bless" host function. | |
| ecalli 5 | |
| trap | |
| // Tests the "assign" host function. | |
| pub @assign_host_fn: | |
| // Change the first authorizer hash. | |
| u8 [0x00020000] = 128 | |
| // Core index. | |
| a0 = 0 | |
| // Memory address where assignments start. | |
| a1 = 0x00020000 | |
| // Call "assign" host function. | |
| ecalli 6 | |
| trap | |
| // Tests the "designate" host function. | |
| pub @designate_host_fn: | |
| // Simple loop for putting 128 336 times. | |
| s0 = 0 | |
| @designate_host_fn_loop: | |
| u8 [s0 + 0x00020000] = 128 | |
| s0 = s0 + 1 | |
| jump @designate_host_fn_loop if s0 <u 336 | |
| // Address in memory of new validators. | |
| a0 = 0x00020000 | |
| // Call "designate" host function. | |
| ecalli 7 | |
| trap | |
| // Tests the "checkpoint" host function. | |
| // It's meant to run out of gas in the middle of execution. | |
| pub @checkpoint_host_fn: | |
| // We first write something to storage. | |
| // Key. | |
| u8 [0x00020000] = 107 | |
| u8 [0x00020001] = 101 | |
| u8 [0x00020002] = 121 | |
| // Value. | |
| u32 [0x00020003] = 1224 | |
| // Set parameters for "write" host function. | |
| // Pointer and length to key. | |
| a0 = 0x00020000 | |
| a1 = 3 | |
| // Pointer and length to value. | |
| a2 = 0x00020003 | |
| a3 = 4 | |
| // Call "write" host function. | |
| ecalli 3 | |
| // Call "checkpoint" host function. | |
| ecalli 8 | |
| // We are adding the code for overriding the key in | |
| // storage but it's not meant to execute because of | |
| // lack of gas. | |
| // Override value. | |
| u32 [0x00020003] = 1337 | |
| // Set parameters. | |
| a0 = 0x00020000 | |
| a1 = 3 | |
| a2 = 0x00020003 | |
| a3 = 4 | |
| // Call "write". | |
| ecalli 3 | |
| trap | |
| // Tests the "new" host function. | |
| pub @new_host_fn: | |
| // Address of code hash. | |
| a0 = 0x00020000 | |
| // Code length. | |
| a1 = 1 | |
| // Min gas accumulate. | |
| a2 = 1000 | |
| a3 = 0 | |
| // Min gas on transfer. | |
| a4 = 500 | |
| a5 = 0 | |
| // Call "new" host function. | |
| ecalli 9 | |
| trap | |
| // Tests the "upgrade" host function. | |
| pub @upgrade_host_fn: | |
| // Address of code hash. | |
| a0 = 0x00020000 | |
| // Simple loop for putting 128 32 times. | |
| s0 = 0 | |
| @upgrade_host_fn_loop: | |
| u8 [s0 + 0x00020000] = 128 | |
| s0 = s0 + 1 | |
| jump @upgrade_host_fn_loop if s0 <u 32 | |
| // Min gas accumulate. | |
| a1 = 0 | |
| a2 = 1000 | |
| // Min gas on transfer. | |
| a3 = 0 | |
| a4 = 500 | |
| // Call "upgrade" host function. | |
| ecalli 10 | |
| trap | |
| // Tests the "transfer" host function. | |
| pub @transfer_host_fn: | |
| // Destination service. | |
| a0 = 0 | |
| // Amount. | |
| a1 = 1000 | |
| a2 = 0 | |
| // Gas limit. | |
| a3 = 10 | |
| a4 = 0 | |
| // Memo. | |
| a5 = 0x00020000 | |
| u8 [0x00020000] = 65 | |
| u8 [0x00020001] = 105 | |
| u8 [0x00020002] = 114 | |
| u8 [0x00020003] = 100 | |
| u8 [0x00020004] = 114 | |
| u8 [0x00020005] = 111 | |
| u8 [0x00020006] = 112 | |
| // Call "transfer" host function. | |
| ecalli 11 | |
| trap | |
| // Tests the "eject" host function. | |
| pub @eject_host_fn: | |
| // Destination service. | |
| a0 = 0 | |
| // Memo. | |
| a1 = 0x00020000 | |
| u8 [0x00020000] = 84 | |
| u8 [0x00020001] = 101 | |
| u8 [0x00020002] = 115 | |
| u8 [0x00020003] = 116 | |
| // Call "eject" host function. | |
| ecalli 12 | |
| trap | |
| // Tests the "query" host function. | |
| pub @query_host_fn: | |
| // TODO | |
| trap | |
| // Tests the "solicit" host function. | |
| pub @solicit_host_fn: | |
| // Hash. | |
| a0 = 0x00020000 | |
| // Simple loop for putting 128 32 times. | |
| s0 = 0 | |
| @solicit_host_fn_loop: | |
| u8 [s0 + 0x00020000] = 128 | |
| s0 = s0 + 1 | |
| jump @solicit_host_fn_loop if s0 <u 32 | |
| // Preimage length. | |
| a1 = 1 | |
| // Call "solicit" host function. | |
| ecalli 14 | |
| trap | |
| // Tests the "forget" host function. | |
| pub @forget_host_fn: | |
| // Hash. | |
| a0 = 0x00020000 | |
| // Simple loop for putting 128 32 times. | |
| s0 = 0 | |
| @forget_host_fn_loop: | |
| u8 [s0 + 0x00020000] = 128 | |
| s0 = s0 + 1 | |
| jump @forget_host_fn_loop if s0 <u 32 | |
| // Preimage length. | |
| a1 = 1 | |
| // Call "forget" host function. | |
| ecalli 15 | |
| trap | |
| // Tests the "yield" host function. | |
| pub @yield_host_fn: | |
| // TODO | |
| trap | |
| // Tests the "historical lookup" host function. | |
| pub @historical_lookup_host_fn: | |
| // Target service 0. | |
| a0 = 0 | |
| // Preimage hash. | |
| a1 = 0x00020000 | |
| u8 [0x00020000] = 128 | |
| // Preimage destination. | |
| a2 = 0x00020100 | |
| // Call "historical lookup" host function. | |
| ecalli 17 | |
| // Return preimage. | |
| // From. | |
| a3 = 0x00020100 | |
| // To. | |
| a4 = 0x00020104 | |
| // Halt. | |
| a0 = 4294901760 | |
| jump [a0] | |
| trap | |
| // Tests the "fetch" host function. | |
| pub @fetch_host_fn: | |
| // We want the first fetch. | |
| a0 = 0 | |
| // Then we put it in the following address. | |
| a1 = 0x00020000 | |
| // Some length | |
| a2 = 10 | |
| // Call "fetch" host function. | |
| ecalli 18 | |
| // Return preimage. | |
| // From. | |
| a3 = 0x00020000 | |
| // To. | |
| a4 = 0x00020010 | |
| // Halt. | |
| a0 = 4294901760 | |
| jump [a0] | |
| trap | |
| // Tests the "export" host function. | |
| pub @export_host_fn: | |
| // Export address. | |
| a0 = 0x00020000 | |
| // Export length. | |
| a1 = 6 | |
| // "export" | |
| u8 [0x00020000] = 101 | |
| u8 [0x00020001] = 120 | |
| u8 [0x00020002] = 112 | |
| u8 [0x00020003] = 111 | |
| u8 [0x00020004] = 114 | |
| u8 [0x00020005] = 116 | |
| // Call "export" host function. | |
| ecalli 19 | |
| // Halt. | |
| a0 = 4294901760 | |
| jump [a0] | |
| trap | |
| pub @machine_host_fn: | |
| // Code address. | |
| a0 = 0x00020000 | |
| // Code length. | |
| a1 = 10 | |
| // Program counter. | |
| a2 = 0 | |
| // Call "machine" host function. | |
| // This creates the machine and puts its id in register a0. | |
| ecalli 20 | |
| a0 = 0x00020000 | |
| ecalli 20 | |
| a0 = 0x00020000 | |
| ecalli 20 | |
| // Let's return it. | |
| u32 [0x00020000] = a0 | |
| // From. | |
| a3 = 0x00020000 | |
| // To. | |
| a4 = 0x00020003 | |
| // Halt. | |
| a0 = 4294901760 | |
| jump [a0] | |
| trap | |
| // Tests the "peek" host function. | |
| pub @peek_host_fn: | |
| // First we create the machine. | |
| a0 = 0x00020000 | |
| a1 = 10 | |
| a2 = 0 | |
| ecalli 20 | |
| // Then we add something to its memory. | |
| // But first we have to initialize a memory page to write to. | |
| // Machine id. | |
| a0 = 0 | |
| // From page. | |
| a1 = 32 | |
| // To page. | |
| a2 = 33 | |
| // Call the "zero" host function. | |
| ecalli 23 | |
| // Machine id. | |
| a0 = 0 | |
| // Address to read from main memory. | |
| a1 = 0x00020000 | |
| u32 [0x00020000] = 1224 | |
| // Address to write to submachine memory. | |
| a2 = 0x00020000 | |
| // Length. | |
| a3 = 4 | |
| // We write to memory with the "poke" host function. | |
| ecalli 22 | |
| // Now we can peek into its memory. | |
| // Machine id. | |
| a0 = 0 | |
| // Address to write the peeked value. | |
| a1 = 0x00020010 | |
| // Address to read from submachine memory. | |
| a2 = 0x00020000 | |
| // Length. | |
| a3 = 4 | |
| // Call "peek" host function. | |
| ecalli 21 | |
| // Now we return the peeked value from memory. | |
| a3 = 0x00020010 | |
| a4 = 0x00020013 | |
| // Halt. | |
| a0 = 4294901760 | |
| jump [a0] | |
| trap | |
| // Tests the "poke" host function. | |
| pub @poke_host_fn: | |
| // Already tested alongside "peek". | |
| trap | |
| // Tests the "zero" host function. | |
| pub @zero_host_fn: | |
| // TODO | |
| trap | |
| // Tests the "void" host function. | |
| pub @void_host_fn: | |
| // TODO | |
| trap | |
| // Tests the "invoke" host function. | |
| pub @invoke_host_fn: | |
| // We first need to create a machine. | |
| // Code. | |
| a0 = 0x00020000 | |
| // Code length. | |
| a1 = 41 | |
| // Load fibonacci program to memory starting at 0x00020000. | |
| jump @load_fibonacci | |
| @after_load_fibonacci: | |
| // Program counter. | |
| a2 = 0 | |
| // Create. | |
| ecalli 20 | |
| // Now we invoke it. | |
| // Machine id. | |
| a0 = 0 | |
| // Address of gas and registers. | |
| a1 = 0x00020100 | |
| // Loads gas and registers starting at 0x00020100 | |
| jump @load_gas_and_registers | |
| @after_gas_and_registers: | |
| // Call "invoke" host function. | |
| ecalli 25 | |
| // Result is in w_7 of the submachine. | |
| // We return it. | |
| a3 = 0x00020100 | |
| a4 = 0x0002016f | |
| // Halt. | |
| a0 = 4294901760 | |
| jump [a0] | |
| trap | |
| // Loads a fibonacci program in memory. | |
| // From 0x00020000 to 0x00020028 | |
| @load_fibonacci: | |
| // Preface. | |
| u8 [0x00020000] = 0 | |
| u8 [0x00020001] = 0 | |
| u8 [0x00020002] = 33 | |
| // load_imm 8 1 | |
| u8 [0x00020003] = 51 | |
| u8 [0x00020004] = 8 | |
| u8 [0x00020005] = 1 | |
| // load_imm 9 1 | |
| u8 [0x00020006] = 51 | |
| u8 [0x00020007] = 9 | |
| u8 [0x00020008] = 1 | |
| // jump 3 | |
| u8 [0x00020009] = 40 | |
| u8 [0x0002000a] = 3 | |
| // trap | |
| u8 [0x0002000b] = 0 | |
| // add_imm_64 7 7 8 | |
| u8 [0x0002000c] = 149 | |
| u8 [0x0002000d] = 119 | |
| u8 [0x0002000e] = 255 | |
| // branch_eq_imm 7 0 12 | |
| u8 [0x0002000f] = 81 | |
| u8 [0x00020010] = 7 | |
| u8 [0x00020011] = 12 | |
| // move_reg 8 10 | |
| u8 [0x00020012] = 100 | |
| u8 [0x00020013] = 138 | |
| // add_64 9 8 8 | |
| u8 [0x00020014] = 200 | |
| u8 [0x00020015] = 152 | |
| u8 [0x00020016] = 8 | |
| // move_reg 10 9 | |
| u8 [0x00020017] = 100 | |
| u8 [0x00020018] = 169 | |
| // jump -13 | |
| u8 [0x00020019] = 40 | |
| u8 [0x0002001a] = 243 | |
| // move_reg 8 7 | |
| u8 [0x0002001b] = 100 | |
| u8 [0x0002001c] = 135 | |
| // load_imm 8 0 | |
| u8 [0x0002001d] = 51 | |
| u8 [0x0002001e] = 8 | |
| // load_imm 9 0 | |
| u8 [0x0002001f] = 51 | |
| u8 [0x00020020] = 9 | |
| // fallthrough | |
| u8 [0x00020021] = 1 | |
| // jump_ind 0 0 | |
| u8 [0x00020022] = 50 | |
| u8 [0x00020023] = 0 | |
| // Opcode bitmask. | |
| u8 [0x00020024] = 73 | |
| u8 [0x00020025] = 147 | |
| u8 [0x00020026] = 82 | |
| u8 [0x00020027] = 213 | |
| u8 [0x00020028] = 0 | |
| jump @after_load_fibonacci | |
| @load_gas_and_registers: | |
| // Gas | |
| u32 [0x00020100] = 10000 | |
| u32 [0x00020104] = 0 | |
| // w_0 | |
| u32 [0x00020108] = 4294901760 | |
| u32 [0x0002010c] = 0 | |
| // w_1 | |
| u32 [0x00020110] = 0 | |
| u32 [0x00020114] = 0 | |
| // w_2 | |
| u32 [0x00020118] = 0 | |
| u32 [0x0002011c] = 0 | |
| // w_3 | |
| u32 [0x00020120] = 0 | |
| u32 [0x00020124] = 0 | |
| // w_4 | |
| u32 [0x00020128] = 0 | |
| u32 [0x0002012c] = 0 | |
| // w_5 | |
| u32 [0x00020130] = 0 | |
| u32 [0x00020134] = 0 | |
| // w_6 | |
| u32 [0x00020138] = 0 | |
| u32 [0x0002013c] = 0 | |
| // w_7 | |
| u32 [0x00020140] = 9 | |
| u32 [0x00020144] = 0 | |
| // w_8 | |
| u32 [0x00020148] = 0 | |
| u32 [0x0002014c] = 0 | |
| // w_9 | |
| u32 [0x00020150] = 0 | |
| u32 [0x00020154] = 0 | |
| // w_10 | |
| u32 [0x00020158] = 0 | |
| u32 [0x0002015c] = 0 | |
| // w_11 | |
| u32 [0x00020160] = 0 | |
| u32 [0x00020164] = 0 | |
| // w_12 | |
| u32 [0x00020168] = 0 | |
| u32 [0x0002016c] = 0 | |
| jump @after_gas_and_registers |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment