From 501411ec4ba69cf864992c0892dc235f0a8196fe Mon Sep 17 00:00:00 2001 From: Joel Bjornson Date: Mon, 4 Apr 2022 18:16:50 +0100 Subject: [PATCH 1/4] Proto: expose used/paid contract storage for tests --- src/proto_alpha/lib_protocol/alpha_context.ml | 5 ++++- src/proto_alpha/lib_protocol/alpha_context.mli | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/proto_alpha/lib_protocol/alpha_context.ml b/src/proto_alpha/lib_protocol/alpha_context.ml index bc04e36c363a..94e9f9492402 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.ml +++ b/src/proto_alpha/lib_protocol/alpha_context.ml @@ -222,7 +222,10 @@ module Contract = struct let get_manager_key = Contract_manager_storage.get_manager_key - module Internal_for_tests = Contract_repr + module Internal_for_tests = struct + include Contract_repr + include Contract_storage + end end module Tx_rollup_level = Tx_rollup_level_repr diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index ae57df3823b1..a1976eaacf42 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -1574,6 +1574,8 @@ module Contract : sig module Internal_for_tests : sig (** see [Contract_repr.originated_contract] for documentation *) val originated_contract : Origination_nonce.Internal_for_tests.t -> contract + + val paid_storage_space : context -> t -> Z.t tzresult Lwt.t end end -- GitLab From 10fa032f05d38422da70e3de0110d1899e629278 Mon Sep 17 00:00:00 2001 From: Joel Bjornson Date: Tue, 5 Apr 2022 10:51:56 +0100 Subject: [PATCH 2/4] Proto: expose paid/used ticket storage functions for tests --- src/proto_alpha/lib_protocol/alpha_context.mli | 6 ++++++ src/proto_alpha/lib_protocol/ticket_storage.ml | 10 ++++++++++ src/proto_alpha/lib_protocol/ticket_storage.mli | 8 ++++++++ 3 files changed, 24 insertions(+) diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index a1976eaacf42..8c6ab9988f3d 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -3408,6 +3408,12 @@ module Ticket_balance : sig val get_balance : context -> Ticket_hash.t -> (Z.t option * context) tzresult Lwt.t + + module Internal_for_tests : sig + val used_storage_space : context -> Z.t tzresult Lwt.t + + val paid_storage_space : context -> Z.t tzresult Lwt.t + end end module First_level_of_protocol : sig diff --git a/src/proto_alpha/lib_protocol/ticket_storage.ml b/src/proto_alpha/lib_protocol/ticket_storage.ml index aeba2b4bdd8b..f008125c8bd5 100644 --- a/src/proto_alpha/lib_protocol/ticket_storage.ml +++ b/src/proto_alpha/lib_protocol/ticket_storage.ml @@ -109,3 +109,13 @@ let adjust_storage_space ctxt ~storage_diff = Storage.Ticket_balance.Paid_storage_space.add ctxt new_used_storage >>= fun ctxt -> return (diff, ctxt) else return (Z.zero, ctxt) + +module Internal_for_tests = struct + let used_storage_space c = + Storage.Ticket_balance.Used_storage_space.find c + >|=? Option.value ~default:Z.zero + + let paid_storage_space c = + Storage.Ticket_balance.Paid_storage_space.find c + >|=? Option.value ~default:Z.zero +end diff --git a/src/proto_alpha/lib_protocol/ticket_storage.mli b/src/proto_alpha/lib_protocol/ticket_storage.mli index 9e02e4037574..3aa3cc35a00f 100644 --- a/src/proto_alpha/lib_protocol/ticket_storage.mli +++ b/src/proto_alpha/lib_protocol/ticket_storage.mli @@ -65,3 +65,11 @@ val adjust_balance : than the given (positive) [storage_diff]. *) val adjust_storage_space : Raw_context.t -> storage_diff:Z.t -> (Z.t * Raw_context.t) tzresult Lwt.t + +module Internal_for_tests : sig + (** [used_storage_space ctxt] returns the used ticket storage space. *) + val used_storage_space : Raw_context.t -> (Z.t, error trace) result Lwt.t + + (** [paid_storage_space ctxt] returns the paid ticket storage space. *) + val paid_storage_space : Raw_context.t -> (Z.t, error trace) result Lwt.t +end -- GitLab From 6248e770b5887b77b55d6d9252e1e3d20ff1952b Mon Sep 17 00:00:00 2001 From: Joel Bjornson Date: Sun, 3 Apr 2022 19:50:33 +0100 Subject: [PATCH 3/4] Tests: ticket used and paid storage tests --- .../michelson/test_ticket_balance.ml | 397 ++++++++++++++++++ 1 file changed, 397 insertions(+) diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_balance.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_balance.ml index cbf5418e4ac4..ceed895495d9 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_balance.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_balance.ml @@ -74,6 +74,71 @@ let get_balance ctxt ~token ~owner = in wrap (Ticket_balance.get_balance ctxt key_hash) +let get_used_ticket_storage block = + let* incr = Incremental.begin_construction block in + wrap + @@ Ticket_balance.Internal_for_tests.used_storage_space + (Incremental.alpha_ctxt incr) + +let get_paid_ticket_storage block = + let* incr = Incremental.begin_construction block in + wrap + @@ Ticket_balance.Internal_for_tests.paid_storage_space + (Incremental.alpha_ctxt incr) + +let get_used_contract_storage block contract = + let* incr = Incremental.begin_construction block in + let alpha_ctxt = Incremental.alpha_ctxt incr in + wrap @@ Alpha_context.Contract.used_storage_space alpha_ctxt contract + +let get_paid_contract_storage block contract = + let* incr = Incremental.begin_construction block in + let alpha_ctxt = Incremental.alpha_ctxt incr in + wrap + @@ Alpha_context.Contract.Internal_for_tests.paid_storage_space + alpha_ctxt + contract + +let assert_paid_contract_storage ~loc block contract expected = + let* storage = get_paid_contract_storage block contract in + Assert.equal + ~loc + Z.equal + "Paid contract storage " + Z.pp_print + (Z.of_int expected) + storage + +let assert_used_contract_storage ~loc block contract expected = + let* storage = get_used_contract_storage block contract in + Assert.equal + ~loc + Z.equal + "Used contract storage " + Z.pp_print + (Z.of_int expected) + storage + +let assert_paid_ticket_storage ~loc block expected = + let* storage = get_paid_ticket_storage block in + Assert.equal + ~loc + Z.equal + "Paid ticket storage " + Z.pp_print + (Z.of_int expected) + storage + +let assert_used_ticket_storage ~loc block expected = + let* storage = get_used_ticket_storage block in + Assert.equal + ~loc + Z.equal + "Used ticket storage " + Z.pp_print + (Z.of_int expected) + storage + let assert_token_balance ~loc block token owner expected = let* incr = Incremental.begin_construction block in let ctxt = Incremental.alpha_ctxt incr in @@ -1059,6 +1124,333 @@ let test_ticket_wallet () = let* block = send_to_burn block in assert_balance block None +(* Test used ticket storage and paid storage. *) +let test_ticket_storage () = + let* {block; baker; contract = source_contract} = init_env () in + (* A contract that can receive a ticket and store it. Each new ticket it + receives is added to a list. *) + let* (ticket_keeper, _script, block) = + originate + ~baker + ~source_contract + ~script: + {| + { parameter (ticket string) ; + storage (list (ticket string)) ; + code { UNPAIR ; CONS ; NIL operation ; PAIR } } + |} + ~storage:"{}" + block + in + (* A contract that receives a pair of ticket and address and forwards the + ticket to the given address. The contract does not store any tickets. *) + let* (ticket_forwarder, _script, block) = + originate + ~baker + ~source_contract + ~script: + {| + { parameter (pair (ticket string) address) ; + storage unit ; + code { CAR ; + UNPAIR ; + SWAP ; + CONTRACT (ticket string) ; + IF_NONE + { DROP ; + PUSH string "Contract of type `ticket(string)` not found" ; + FAILWITH } + { PUSH mutez 0 ; + DIG 2 ; + TRANSFER_TOKENS ; + PUSH unit Unit ; + NIL operation ; + DIG 2 ; + CONS ; + PAIR } } } + |} + ~storage:"Unit" + block + in + (* A contract that takes two addresses: one to a ticket-forward contract and + one to a ticket-receiver contract, mints and sends the ticket to a + ticket-forward address along with the address of the ticket-receiver. + + Altogether we have: + + [ticket_minter] ----> [ticket_forwarder] ----> [ticket_receiver] + *) + let* (ticket_minter, _script, block) = + originate + ~baker + ~source_contract + ~script: + {| + { parameter (pair address address) ; storage unit ; + code { CAR ; + UNPAIR ; + CONTRACT (pair (ticket string) address) ; + IF_NONE + { DROP ; + PUSH string "Contract of type `ticket(string)` not found" ; + FAILWITH } + { PUSH mutez 0 ; + DIG 2 ; + PUSH nat 1 ; + PUSH string "Red" ; + TICKET ; + PAIR ; + TRANSFER_TOKENS ; + PUSH unit Unit ; + NIL operation ; + DIG 2 ; + CONS ; + PAIR } } } |} + ~storage:"Unit" + block + in + let mint_and_send block = + transaction + ~entrypoint:Entrypoint.default + ~baker + ~sender:source_contract + block + ~recipient:ticket_minter + ~parameters: + (Printf.sprintf + {|Pair %S %S|} + (Contract.to_b58check ticket_forwarder) + (Contract.to_b58check ticket_keeper)) + in + let* block = mint_and_send block in + let token_red = string_token ~ticketer:ticket_minter "Red" in + (* Verify that the ticket is accredited to the ticket keeper and no one else. + The ticket table now looks like: + *) + let* () = + assert_token_balance ~loc:__LOC__ block token_red ticket_minter None + in + let* () = + assert_token_balance ~loc:__LOC__ block token_red ticket_forwarder None + in + let* () = + assert_token_balance ~loc:__LOC__ block token_red ticket_keeper (Some 1) + in + (* Both ticket paid and used storage should now be 65 bytes for the key and + one for the value. Ticket table looks like: + + | Owner x Ticket-token | Amount | + |--------------------------|--------| + | ticket_keeper x Red | 1 | + + Used storage: 65 + 1 = 66 + + Paid storage: 66 + *) + let* () = assert_used_ticket_storage ~loc:__LOC__ block 66 in + let* () = assert_paid_ticket_storage ~loc:__LOC__ block 66 in + (* Send another ticket that uses the same slot. That does not increase used + storage. The first call from [ticket_minter] to ticket-forwarder results in + a table: + + | Owner x Ticket-token | Amount | + |--------------------------|--------| + | ticket_forwarder x Red | 1 | + | ticket_keeper x Red | 1 | + + Used storage: 132 + + The call from ticket-forwarder to [ticket_keeper] results in: + + | Owner x Ticket-token | Amount | + |--------------------------|--------| + | ticket_keeper x Red | 2 | + + Used storage: 66 + + Noted that the paid-storage "water-marker" was pushed up to 132. + *) + let* block = mint_and_send block in + let* () = + assert_token_balance ~loc:__LOC__ block token_red ticket_keeper (Some 2) + in + let* () = assert_used_ticket_storage ~loc:__LOC__ block 66 in + let* () = assert_paid_ticket_storage ~loc:__LOC__ block 132 in + (* Send yet another ticket that uses the same slot. That does not increase used + storage and it's using already paid storage. The first call from + [ticket_minter] to ticket-forwarder results in a table: + + | Owner x Ticket-token | Amount | + |--------------------------|--------| + | ticket_forwarder x Red | 1 | + | ticket_keeper x Red | 2 | + + Used storage: 132 + + The call from ticket-forwarder to [ticket_keeper] results in: + + | Owner x Ticket-token | Amount | + |--------------------------|--------| + | ticket_keeper x Red | 3 | + + Used storage: 66 + + Here, the paid_storage "water-mark" is not pushed up. + *) + let* block = mint_and_send block in + let* () = + assert_token_balance ~loc:__LOC__ block token_red ticket_keeper (Some 3) + in + let* () = assert_used_ticket_storage ~loc:__LOC__ block 66 in + let* () = assert_paid_ticket_storage ~loc:__LOC__ block 132 in + return () + +(* Test used ticket storage and paid storage. *) +let test_storage_for_create_and_remove_tickets () = + let* {block; baker; contract = source_contract} = init_env () in + (* A contract with two endpoints: + - Create n tickets and add to its storage + - Remove all tickets + *) + let* (ticket_manager, _script, block) = + originate + ~baker + ~source_contract + ~script: + {| + { parameter (or (pair %add nat string) (unit %clear)) ; + storage (list (ticket string)) ; + code { UNPAIR ; + IF_LEFT + { UNPAIR ; DIG 2 ; SWAP ; DIG 2 ; TICKET ; CONS ; NIL operation ; PAIR } + { DROP 2 ; NIL (ticket string) ; NIL operation ; PAIR } } } + |} + ~storage:"{}" + block + in + let add block n content = + transaction + ~entrypoint:(Entrypoint.of_string_strict_exn "add") + ~baker + ~sender:source_contract + block + ~recipient:ticket_manager + ~parameters:(Printf.sprintf "Pair %d %S" n content) + in + let clear block = + transaction + ~entrypoint:(Entrypoint.of_string_strict_exn "clear") + ~baker + ~sender:source_contract + block + ~recipient:ticket_manager + ~parameters:"Unit" + in + (* Initially the used and paid contract storage size is 115. *) + let* () = + assert_used_contract_storage ~loc:__LOC__ block ticket_manager 115 + in + let* () = + assert_paid_contract_storage ~loc:__LOC__ block ticket_manager 115 + in + (* Add 1000 units of "A" tickets. *) + let* block = add block 1000 "A" in + (* After adding one block the new used and paid storage grows to accommodate + for the new ticket. The size is 115 + 40 (size of ticket) = 155. *) + let* () = + assert_used_contract_storage ~loc:__LOC__ block ticket_manager 155 + in + let* () = + assert_paid_contract_storage ~loc:__LOC__ block ticket_manager 155 + in + (* The size of used and paid-for ticket storage is 67 bytes. (65 for hash + and 2 for amount). *) + let* () = assert_used_ticket_storage ~loc:__LOC__ block 67 in + let* () = assert_paid_ticket_storage ~loc:__LOC__ block 67 in + (* Add 1000 units of "B" tickets. *) + let* block = add block 1000 "B" in + (* The new used and paid for contract storage grow to 155 + 40 = 195. *) + let* () = + assert_used_contract_storage ~loc:__LOC__ block ticket_manager 195 + in + let* () = + assert_paid_contract_storage ~loc:__LOC__ block ticket_manager 195 + in + (* The new used and paid for ticket storage doubles (2 * 67 = 134). *) + let* () = assert_used_ticket_storage ~loc:__LOC__ block 134 in + let* () = assert_paid_ticket_storage ~loc:__LOC__ block 134 in + (* Clear all tickets. *) + let* block = clear block in + (* We're back to 115 base-line for the used contract storage and keep 195 for + paid. *) + let* () = + assert_used_contract_storage ~loc:__LOC__ block ticket_manager 115 + in + let* () = + assert_paid_contract_storage ~loc:__LOC__ block ticket_manager 195 + in + (* Since the ticket-table is empty it does not take up any space. However, + we've already paid for 134 bytes. *) + let* () = assert_used_ticket_storage ~loc:__LOC__ block 0 in + let* () = assert_paid_ticket_storage ~loc:__LOC__ block 134 in + (* Add one unit of "C" tickets. *) + let* block = add block 1 "C" in + (* The new used storage is 115 + 39 (size of ticket) = 154. The size is 39 + rather than 40 because it carries a smaller amount payload. *) + let* () = + assert_used_contract_storage ~loc:__LOC__ block ticket_manager 154 + in + (* We still have paid for 195 contract storage. *) + let* () = + assert_paid_contract_storage ~loc:__LOC__ block ticket_manager 195 + in + (* There is one row in the ticket table with size 65 (for the hash) + 1 + (for the amount) = 65 bytes. *) + let* () = assert_used_ticket_storage ~loc:__LOC__ block 66 in + (* We've still paid for 134 bytes however. *) + let* () = assert_paid_ticket_storage ~loc:__LOC__ block 134 in + (* Add yet another "C" ticket. *) + let* block = add block 1 "C" in + (* The new used storage is 154 + 39 (size of ticket) = 193. *) + let* () = + assert_used_contract_storage ~loc:__LOC__ block ticket_manager 193 + in + (* We still have paid for 195 contract storage. *) + let* () = + assert_paid_contract_storage ~loc:__LOC__ block ticket_manager 195 + in + (* There is still only one row in the ticket table with size 66. *) + let* () = assert_used_ticket_storage ~loc:__LOC__ block 66 in + (* And we've still paid for 134 bytes. *) + let* () = assert_paid_ticket_storage ~loc:__LOC__ block 134 in + (* Add a "D" ticket. *) + let* block = add block 1 "D" in + (* The new used storage is 193 + 39 (size of ticket) = 193. *) + let* () = + assert_used_contract_storage ~loc:__LOC__ block ticket_manager 232 + in + (* The paid storage also increases to 232. *) + let* () = + assert_paid_contract_storage ~loc:__LOC__ block ticket_manager 232 + in + (* There are now two rows in the ticket table: 2 x 66 = 132 *) + let* () = assert_used_ticket_storage ~loc:__LOC__ block 132 in + (* And we've still paid for 134 bytes. *) + let* () = assert_paid_ticket_storage ~loc:__LOC__ block 134 in + let* block = add block 1 "E" in + (* The new used storage is 232 + 39 (size of ticket) = 193. *) + let* () = + assert_used_contract_storage ~loc:__LOC__ block ticket_manager 271 + in + (* The paid storage also increases to 271. *) + let* () = + assert_paid_contract_storage ~loc:__LOC__ block ticket_manager 271 + in + (* There are now three rows in the ticket table: 3 x 66 = 198. *) + let* () = assert_used_ticket_storage ~loc:__LOC__ block 198 in + (* And the paid storage has increased. *) + assert_paid_ticket_storage ~loc:__LOC__ block 198 + let tests = [ Tztest.tztest "Test add strict" `Quick test_add_strict; @@ -1075,4 +1467,9 @@ let tests = Tztest.tztest "Test send drop" `Quick test_create_contract_with_ticket; Tztest.tztest "Test join" `Quick test_join_tickets; Tztest.tztest "Test wallet" `Quick test_ticket_wallet; + Tztest.tztest "Test ticket storage" `Quick test_ticket_storage; + Tztest.tztest + "Test storage for create and remove tickets" + `Quick + test_storage_for_create_and_remove_tickets; ] -- GitLab From df1ac95af00fbd17bd29f7836ac1c0172af4703b Mon Sep 17 00:00:00 2001 From: Joel Bjornson Date: Mon, 4 Apr 2022 15:42:08 +0100 Subject: [PATCH 4/4] Tests: ticket storage regressions --- .../mini_scenarios/add_clear_tickets.tz | 6 ++ ...t_add_clear_tickets_add_first_transfer.out | 38 ++++++++++++ ..._add_clear_tickets_add_second_transfer.out | 34 +++++++++++ ...t_add_clear_tickets_add_third_transfer.out | 39 ++++++++++++ ...:test_add_clear_tickets_clear_transfer.out | 32 ++++++++++ ...ts::test_add_clear_tickets_origination.out | 51 ++++++++++++++++ ..._hash[client_regtest_custom_scrubber0].out | 1 + ...[mini_scenarios--add_clear_tickets.tz].out | 33 ++++++++++ tests_python/tests_alpha/test_contract.py | 60 +++++++++++++++++++ 9 files changed, 294 insertions(+) create mode 100644 tests_python/contracts_alpha/mini_scenarios/add_clear_tickets.tz create mode 100644 tests_python/tests_alpha/_regtest_outputs/test_contract.TestCreateRemoveTickets::test_add_clear_tickets_add_first_transfer.out create mode 100644 tests_python/tests_alpha/_regtest_outputs/test_contract.TestCreateRemoveTickets::test_add_clear_tickets_add_second_transfer.out create mode 100644 tests_python/tests_alpha/_regtest_outputs/test_contract.TestCreateRemoveTickets::test_add_clear_tickets_add_third_transfer.out create mode 100644 tests_python/tests_alpha/_regtest_outputs/test_contract.TestCreateRemoveTickets::test_add_clear_tickets_clear_transfer.out create mode 100644 tests_python/tests_alpha/_regtest_outputs/test_contract.TestCreateRemoveTickets::test_add_clear_tickets_origination.out create mode 100644 tests_python/tests_alpha/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--add_clear_tickets.tz].out diff --git a/tests_python/contracts_alpha/mini_scenarios/add_clear_tickets.tz b/tests_python/contracts_alpha/mini_scenarios/add_clear_tickets.tz new file mode 100644 index 000000000000..9275b38a2c39 --- /dev/null +++ b/tests_python/contracts_alpha/mini_scenarios/add_clear_tickets.tz @@ -0,0 +1,6 @@ +parameter (or (pair %add nat string) (unit %clear)) ; +storage (list (ticket string)) ; +code { UNPAIR ; + IF_LEFT + { UNPAIR ; DIG 2 ; SWAP ; DIG 2 ; TICKET ; CONS ; NIL operation ; PAIR } + { DROP 2 ; NIL (ticket string) ; NIL operation ; PAIR } } diff --git a/tests_python/tests_alpha/_regtest_outputs/test_contract.TestCreateRemoveTickets::test_add_clear_tickets_add_first_transfer.out b/tests_python/tests_alpha/_regtest_outputs/test_contract.TestCreateRemoveTickets::test_add_clear_tickets_add_first_transfer.out new file mode 100644 index 000000000000..4283f5efad9f --- /dev/null +++ b/tests_python/tests_alpha/_regtest_outputs/test_contract.TestCreateRemoveTickets::test_add_clear_tickets_add_first_transfer.out @@ -0,0 +1,38 @@ +tests_alpha/test_contract.py::TestCreateRemoveTickets::test_add_clear_tickets_add_first_transfer + +Node is bootstrapped. +Estimated gas: 2576.017 units (will add 100 for safety) +Estimated storage: 105 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000535 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 2677 + Storage limit: 125 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000535 + payload fees(the block proposer) ....... +ꜩ0.000535 + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Entrypoint: add + Parameter: (Pair 1 "A") + This transaction was successfully applied + Updated storage: + { Pair 0x0134d794a355dbb7027075d278a68494e91c6709ed00 (Pair "A" 1) } + Storage size: 154 bytes + Paid storage size diff: 105 bytes + Consumed gas: 2576.017 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.02625 + storage fees ........................... +ꜩ0.02625 + +Injected block at minimal timestamp diff --git a/tests_python/tests_alpha/_regtest_outputs/test_contract.TestCreateRemoveTickets::test_add_clear_tickets_add_second_transfer.out b/tests_python/tests_alpha/_regtest_outputs/test_contract.TestCreateRemoveTickets::test_add_clear_tickets_add_second_transfer.out new file mode 100644 index 000000000000..149eac7ee6b4 --- /dev/null +++ b/tests_python/tests_alpha/_regtest_outputs/test_contract.TestCreateRemoveTickets::test_add_clear_tickets_add_second_transfer.out @@ -0,0 +1,34 @@ +tests_alpha/test_contract.py::TestCreateRemoveTickets::test_add_clear_tickets_add_second_transfer + +Node is bootstrapped. +Estimated gas: 1657.442 units (will add 100 for safety) +Estimated storage: no bytes added +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000443 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1758 + Storage limit: 0 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000443 + payload fees(the block proposer) ....... +ꜩ0.000443 + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Entrypoint: add + Parameter: (Pair 1 "B") + This transaction was successfully applied + Updated storage: + { Pair 0x0134d794a355dbb7027075d278a68494e91c6709ed00 (Pair "B" 1) } + Storage size: 154 bytes + Consumed gas: 1657.442 + +Injected block at minimal timestamp diff --git a/tests_python/tests_alpha/_regtest_outputs/test_contract.TestCreateRemoveTickets::test_add_clear_tickets_add_third_transfer.out b/tests_python/tests_alpha/_regtest_outputs/test_contract.TestCreateRemoveTickets::test_add_clear_tickets_add_third_transfer.out new file mode 100644 index 000000000000..d924a3fc4e93 --- /dev/null +++ b/tests_python/tests_alpha/_regtest_outputs/test_contract.TestCreateRemoveTickets::test_add_clear_tickets_add_third_transfer.out @@ -0,0 +1,39 @@ +tests_alpha/test_contract.py::TestCreateRemoveTickets::test_add_clear_tickets_add_third_transfer + +Node is bootstrapped. +Estimated gas: 2333.061 units (will add 100 for safety) +Estimated storage: 105 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000511 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 2434 + Storage limit: 125 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000511 + payload fees(the block proposer) ....... +ꜩ0.000511 + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Entrypoint: add + Parameter: (Pair 1 "C") + This transaction was successfully applied + Updated storage: + { Pair 0x0134d794a355dbb7027075d278a68494e91c6709ed00 (Pair "C" 1) ; + Pair 0x0134d794a355dbb7027075d278a68494e91c6709ed00 (Pair "B" 1) } + Storage size: 193 bytes + Paid storage size diff: 105 bytes + Consumed gas: 2333.061 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.02625 + storage fees ........................... +ꜩ0.02625 + +Injected block at minimal timestamp diff --git a/tests_python/tests_alpha/_regtest_outputs/test_contract.TestCreateRemoveTickets::test_add_clear_tickets_clear_transfer.out b/tests_python/tests_alpha/_regtest_outputs/test_contract.TestCreateRemoveTickets::test_add_clear_tickets_clear_transfer.out new file mode 100644 index 000000000000..a0acc70c165d --- /dev/null +++ b/tests_python/tests_alpha/_regtest_outputs/test_contract.TestCreateRemoveTickets::test_add_clear_tickets_clear_transfer.out @@ -0,0 +1,32 @@ +tests_alpha/test_contract.py::TestCreateRemoveTickets::test_add_clear_tickets_clear_transfer + +Node is bootstrapped. +Estimated gas: 1845.821 units (will add 100 for safety) +Estimated storage: no bytes added +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000456 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1946 + Storage limit: 0 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000456 + payload fees(the block proposer) ....... +ꜩ0.000456 + Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Entrypoint: clear + This transaction was successfully applied + Updated storage: {} + Storage size: 115 bytes + Consumed gas: 1845.821 + +Injected block at minimal timestamp diff --git a/tests_python/tests_alpha/_regtest_outputs/test_contract.TestCreateRemoveTickets::test_add_clear_tickets_origination.out b/tests_python/tests_alpha/_regtest_outputs/test_contract.TestCreateRemoveTickets::test_add_clear_tickets_origination.out new file mode 100644 index 000000000000..62185cd8f13c --- /dev/null +++ b/tests_python/tests_alpha/_regtest_outputs/test_contract.TestCreateRemoveTickets::test_add_clear_tickets_origination.out @@ -0,0 +1,51 @@ +tests_alpha/test_contract.py::TestCreateRemoveTickets::test_add_clear_tickets_origination + +Node is bootstrapped. +Estimated gas: 1427.302 units (will add 100 for safety) +Estimated storage: 372 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[BLOCK_HASH]' +NOT waiting for the operation to be included. +Use command + tezos-client wait for [BLOCK_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [CONTRACT_HASH] + Fee to the baker: ꜩ0.000498 + Expected counter: [EXPECTED_COUNTER] + Gas limit: 1528 + Storage limit: 392 bytes + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000498 + payload fees(the block proposer) ....... +ꜩ0.000498 + Origination: + From: [CONTRACT_HASH] + Credit: ꜩ200 + Script: + { parameter (or (pair %add nat string) (unit %clear)) ; + storage (list (ticket string)) ; + code { UNPAIR ; + IF_LEFT + { UNPAIR ; DIG 2 ; SWAP ; DIG 2 ; TICKET ; CONS ; NIL operation ; PAIR } + { DROP 2 ; NIL (ticket string) ; NIL operation ; PAIR } } } + Initial storage: {} + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 115 bytes + Paid storage size diff: 115 bytes + Consumed gas: 1427.302 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.02875 + storage fees ........................... +ꜩ0.02875 + [CONTRACT_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + [CONTRACT_HASH] ... -ꜩ200 + [CONTRACT_HASH] ... +ꜩ200 + +New contract [CONTRACT_HASH] originated. +Contract memorized as add_clear_tickets. +Injected block at minimal timestamp +[ [], [], [], [ "[BLOCK_HASH]" ] ] diff --git a/tests_python/tests_alpha/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[client_regtest_custom_scrubber0].out b/tests_python/tests_alpha/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[client_regtest_custom_scrubber0].out index ce7d7b6b640c..4b6d78f0ba4e 100644 --- a/tests_python/tests_alpha/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[client_regtest_custom_scrubber0].out +++ b/tests_python/tests_alpha/_regtest_outputs/test_contract.TestScriptHashRegression::test_contract_hash[client_regtest_custom_scrubber0].out @@ -63,6 +63,7 @@ exprtw4kigYCiREgky6KBKryS7JkaGih6ju8jkjaXtpdcWYrYukRKX [CONTRACT_PATH]/macros/pa exprtxutG1Nu8d198ebiCraNuQ8a6iYYqJYfGXq19aykNPB1uECc8w [CONTRACT_PATH]/macros/set_caddaadr.tz exprvCE6JDXrzEfZuxTQzSgxWXtxX5GoNxvidL84CN2TAm6Hk3kuK6 [CONTRACT_PATH]/macros/take_my_money.tz exprunGqZLZZwm9mY31NFGbBemCgXGevYqLRKdeRKQArPf824Npnni [CONTRACT_PATH]/macros/unpair_macro.tz +expru9ZhqLGykU3yRksBDWe4uDwxavSM19B8WfKukQA3fkgok4hGTE [CONTRACT_PATH]/mini_scenarios/add_clear_tickets.tz exprufRUAYF6r5QHQvK8CzWkKQcdvYkPx5fjEYzWPXc35Dry77KDT1 [CONTRACT_PATH]/mini_scenarios/authentication.tz exprtjdvZr5J7WfN4SyNgKueLnxX4fALUYJ4cmi675EHJdUu5yyg2n [CONTRACT_PATH]/mini_scenarios/big_map_entrypoints.tz exprtfWRfK4RoY8CF9VXvcHeBxizfjMMPAkLojfUTuoZkMSyiPKoyK [CONTRACT_PATH]/mini_scenarios/big_map_magic.tz diff --git a/tests_python/tests_alpha/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--add_clear_tickets.tz].out b/tests_python/tests_alpha/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--add_clear_tickets.tz].out new file mode 100644 index 000000000000..e4d7ef6dd70b --- /dev/null +++ b/tests_python/tests_alpha/_regtest_outputs/test_contract.TestTypecheck::test_typecheck[mini_scenarios--add_clear_tickets.tz].out @@ -0,0 +1,33 @@ +tests_alpha/test_contract.py::TestTypecheck::test_typecheck[mini_scenarios/add_clear_tickets.tz] + +Well typed +Gas remaining: 1039990.715 units remaining +{ parameter (or (pair %add nat string) (unit %clear)) ; + storage (list (ticket string)) ; + code { UNPAIR + /* [ or (pair nat string) unit : list (ticket string) ] */ ; + IF_LEFT + { UNPAIR + /* [ nat : string : list (ticket string) ] */ ; + DIG 2 + /* [ list (ticket string) : nat : string ] */ ; + SWAP + /* [ nat : list (ticket string) : string ] */ ; + DIG 2 + /* [ string : nat : list (ticket string) ] */ ; + TICKET + /* [ ticket string : list (ticket string) ] */ ; + CONS + /* [ list (ticket string) ] */ ; + NIL operation + /* [ list operation : list (ticket string) ] */ ; + PAIR + /* [ pair (list operation) (list (ticket string)) ] */ } + { DROP 2 + /* [] */ ; + NIL (ticket string) + /* [ list (ticket string) ] */ ; + NIL operation + /* [ list operation : list (ticket string) ] */ ; + PAIR + /* [ pair (list operation) (list (ticket string)) ] */ } } } diff --git a/tests_python/tests_alpha/test_contract.py b/tests_python/tests_alpha/test_contract.py index a004f160c78d..953ceb6fe1c1 100644 --- a/tests_python/tests_alpha/test_contract.py +++ b/tests_python/tests_alpha/test_contract.py @@ -2347,3 +2347,63 @@ class TestOriginateContractFromContract: ['--arg', 'Unit', '--burn-cap', '2'], ) utils.bake(client, 'bootstrap5') + + +@pytest.mark.incremental +@pytest.mark.contract +@pytest.mark.regression +class TestCreateRemoveTickets: + def test_add_clear_tickets_origination( + self, client_regtest_scrubbed, session + ): + client = client_regtest_scrubbed + path = os.path.join( + CONTRACT_PATH, 'mini_scenarios', 'add_clear_tickets.tz' + ) + originate(client, session, path, '{}', 200) + + def test_add_clear_tickets_add_first_transfer( + self, client_regtest_scrubbed + ): + client = client_regtest_scrubbed + client.transfer( + 0, + 'bootstrap2', + 'add_clear_tickets', + ['--entrypoint', 'add', '--arg', 'Pair 1 "A"', '--burn-cap', '2'], + ) + utils.bake(client, 'bootstrap5') + + def test_add_clear_tickets_clear_transfer(self, client_regtest_scrubbed): + client = client_regtest_scrubbed + client.transfer( + 0, + 'bootstrap2', + 'add_clear_tickets', + ['--entrypoint', 'clear', '--arg', 'Unit', '--burn-cap', '2'], + ) + utils.bake(client, 'bootstrap5') + + def test_add_clear_tickets_add_second_transfer( + self, client_regtest_scrubbed + ): + client = client_regtest_scrubbed + client.transfer( + 0, + 'bootstrap2', + 'add_clear_tickets', + ['--entrypoint', 'add', '--arg', 'Pair 1 "B"', '--burn-cap', '2'], + ) + utils.bake(client, 'bootstrap5') + + def test_add_clear_tickets_add_third_transfer( + self, client_regtest_scrubbed + ): + client = client_regtest_scrubbed + client.transfer( + 0, + 'bootstrap2', + 'add_clear_tickets', + ['--entrypoint', 'add', '--arg', 'Pair 1 "C"', '--burn-cap', '2'], + ) + utils.bake(client, 'bootstrap5') -- GitLab